RIDER-12147 Show elevation status in window title like Visual Studio does

This commit is contained in:
Leonid Shalupov
2018-05-26 15:01:10 +08:00
parent 0baeb6d3dd
commit d3dd15c747
3 changed files with 93 additions and 2 deletions
@@ -31,6 +31,7 @@ import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.io.win32.WindowsElevationUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.*;
import com.intellij.openapi.wm.ex.IdeFrameEx;
@@ -316,6 +317,10 @@ public class IdeFrameImpl extends JFrame implements IdeFrameEx, AccessibleContex
updateTitle(this, myTitle, myFileTitle, myCurrentFile);
}
public static String getElevationSuffix() {
return WindowsElevationUtil.isUnderElevation() ? " (Administrator)" : "";
}
public static void updateTitle(@NotNull JFrame frame, @Nullable String title, @Nullable String fileTitle, @Nullable File currentFile) {
if (ourUpdatingTitle) return;
@@ -326,10 +331,10 @@ public class IdeFrameImpl extends JFrame implements IdeFrameEx, AccessibleContex
Builder builder = new Builder().append(title).append(fileTitle);
if (Boolean.getBoolean("ide.ui.version.in.title")) {
builder = builder.append(ApplicationNamesInfo.getInstance().getFullProductName() + ' ' + ApplicationInfo.getInstance().getFullVersion());
builder = builder.append(ApplicationNamesInfo.getInstance().getFullProductName() + ' ' + ApplicationInfo.getInstance().getFullVersion() + getElevationSuffix());
}
else if (!SystemInfo.isMac || builder.isEmpty()) {
builder = builder.append(ApplicationNamesInfo.getInstance().getFullProductName());
builder = builder.append(ApplicationNamesInfo.getInstance().getFullProductName() + getElevationSuffix());
}
frame.setTitle(builder.toString());
}
@@ -24,6 +24,7 @@ import com.intellij.openapi.ui.popup.ListItemDescriptorAdapter;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.*;
import com.intellij.openapi.wm.impl.IdeFrameImpl;
import com.intellij.openapi.wm.impl.IdeGlassPaneImpl;
import com.intellij.ui.*;
import com.intellij.ui.border.CustomLineBorder;
@@ -191,6 +192,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame, Disposable, Ac
if (Boolean.getBoolean("ide.ui.version.in.title")) {
title += ' ' + ApplicationInfo.getInstance().getFullVersion();
}
title += IdeFrameImpl.getElevationSuffix();
return title;
}
@@ -0,0 +1,84 @@
package com.intellij.openapi.util.io.win32;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.AtomicNotNullLazyValue;
import com.intellij.openapi.util.SystemInfo;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.*;
import com.sun.jna.ptr.IntByReference;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class WindowsElevationUtil {
private static Logger LOG = Logger.getInstance(WindowsElevationUtil.class);
private WindowsElevationUtil() {
}
/**
* returns true if current user is having administrator privileges AND this code is running under elevation
*/
public static boolean isUnderElevation() {
return IS_UNDER_ELEVATION.getValue();
}
private static final AtomicNotNullLazyValue<Boolean> IS_UNDER_ELEVATION = new AtomicNotNullLazyValue<Boolean>() {
@NotNull
@Override
protected Boolean compute() {
if (!SystemInfo.isWindows) {
return false;
}
try {
return isElevated();
} catch (Throwable t) {
LOG.warn("Unexpected exception in WindowsElevationUtil.IS_UNDER_ELEVATION", t);
return false;
}
}
private boolean isElevated() {
WinNT.HANDLEByReference processTokenHandle = new WinNT.HANDLEByReference();
boolean openProcessRc = Advapi32.INSTANCE.OpenProcessToken(
Kernel32.INSTANCE.GetCurrentProcess(),
WinNT.TOKEN_ADJUST_PRIVILEGES | WinNT.TOKEN_QUERY, processTokenHandle);
if (!openProcessRc) {
int lastError = Kernel32.INSTANCE.GetLastError();
LOG.warn("Unable to OpenProcessToken: error " + lastError + ": " + Kernel32Util.formatMessageFromLastErrorCode(lastError));
return false;
}
try {
IntByReference cbNeeded = new IntByReference(0);
TOKEN_ELEVATION tokenElevation = new TOKEN_ELEVATION();
boolean getTokenInformationRc = Advapi32.INSTANCE.GetTokenInformation(
processTokenHandle.getValue(), WinNT.TOKEN_INFORMATION_CLASS.TokenElevation,
tokenElevation, tokenElevation.size(), cbNeeded);
if (!getTokenInformationRc) {
int lastError = Kernel32.INSTANCE.GetLastError();
LOG.warn("Unable to GetTokenInformation: error " + lastError + ": " + Kernel32Util.formatMessageFromLastErrorCode(lastError));
return false;
}
return tokenElevation.TokenIsElevated.intValue() != 0;
} finally {
Kernel32.INSTANCE.CloseHandle(processTokenHandle.getValue());
}
}
};
public static class TOKEN_ELEVATION extends Structure {
@SuppressWarnings("WeakerAccess")
public WinDef.DWORD TokenIsElevated = new WinDef.DWORD(0);
@Override
protected List<String> getFieldOrder() {
return FIELDS;
}
private static List<String> FIELDS = createFieldsOrder("TokenIsElevated");
}
}