diff options
author | jfrijters <jfrijters> | 2015-06-29 12:41:44 +0300 |
---|---|---|
committer | jfrijters <jfrijters> | 2015-06-29 12:41:44 +0300 |
commit | cde423eea0021d29aaed964bd2fc67b5f105efa4 (patch) | |
tree | 6b204b35a6c68cc458d4b1f61680b72e0f2275fb | |
parent | 8ec0c04c96153d2dcfee298d6e69d190fe2aa65b (diff) |
Minor clean up of UAC detection.
-rw-r--r-- | runtime/openjdk/java.util.prefs.cs | 359 |
1 files changed, 359 insertions, 0 deletions
diff --git a/runtime/openjdk/java.util.prefs.cs b/runtime/openjdk/java.util.prefs.cs new file mode 100644 index 00000000..0166e370 --- /dev/null +++ b/runtime/openjdk/java.util.prefs.cs @@ -0,0 +1,359 @@ +/* + Copyright (C) 2007-2013 Jeroen Frijters + Copyright (C) 2009 Volker Berlin (i-net software) + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jeroen Frijters + jeroen@frijters.net + +*/ +using System; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.Principal; +using System.Text; + +static class Java_java_util_prefs_FileSystemPreferences +{ + public static int chmod(string filename, int permission) + { + // TODO + return 0; + } + + public static int[] lockFile0(string filename, int permission, bool shared) + { + // TODO + return new int[] { 1, 0 }; + } + + public static int unlockFile0(int fd) + { + // TODO + return 0; + } +} + +static class Java_java_util_prefs_WindowsPreferences +{ + // HACK we currently support only 16 handles at a time + private static readonly Microsoft.Win32.RegistryKey[] keys = new Microsoft.Win32.RegistryKey[16]; + + private static Microsoft.Win32.RegistryKey MapKey(int hKey) + { + switch (hKey) + { + case unchecked((int)0x80000001): + return Microsoft.Win32.Registry.CurrentUser; + case unchecked((int)0x80000002): + return Microsoft.Win32.Registry.LocalMachine; + default: + return keys[hKey - 1]; + } + } + + private static int AllocHandle(Microsoft.Win32.RegistryKey key) + { + lock (keys) + { + if (key != null) + { + for (int i = 0; i < keys.Length; i++) + { + if (keys[i] == null) + { + keys[i] = key; + return i + 1; + } + } + } + return 0; + } + } + + private static string BytesToString(byte[] bytes) + { + int len = bytes.Length; + if (bytes[len - 1] == 0) + { + len--; + } + return Encoding.ASCII.GetString(bytes, 0, len); + } + + private static byte[] StringToBytes(string str) + { + if (str.Length == 0 || str[str.Length - 1] != 0) + { + str += '\u0000'; + } + return Encoding.ASCII.GetBytes(str); + } + + public static int[] WindowsRegOpenKey(int hKey, byte[] subKey, int securityMask) + { + // writeable = DELETE == 0x10000 || KEY_SET_VALUE == 2 || KEY_CREATE_SUB_KEY == 4 || KEY_WRITE = 0x20006; + // !writeable : KEY_ENUMERATE_SUB_KEYS == 8 || KEY_READ == 0x20019 || KEY_QUERY_VALUE == 1 + bool writable = (securityMask & 0x10006) != 0; + Microsoft.Win32.RegistryKey resultKey = null; + int error = 0; + try + { + Microsoft.Win32.RegistryKey parent = MapKey(hKey); + // HACK we check if we can write in the system preferences + // we want not user registry virtualization for compatibility + if (writable && parent.Name.StartsWith("HKEY_LOCAL_MACHINE", StringComparison.Ordinal) && UACVirtualization.Enabled) + { + resultKey = parent.OpenSubKey(BytesToString(subKey), false); + if (resultKey != null) + { + // error only if key exists + resultKey.Close(); + error = 5; + resultKey = null; + } + } + else + { + resultKey = parent.OpenSubKey(BytesToString(subKey), writable); + } + } + catch (SecurityException) + { + error = 5; + } + catch (UnauthorizedAccessException) + { + error = 5; + } + return new int[] { AllocHandle(resultKey), error }; + } + + public static int WindowsRegCloseKey(int hKey) + { + keys[hKey - 1].Close(); + lock (keys) + { + keys[hKey - 1] = null; + } + return 0; + } + + public static int[] WindowsRegCreateKeyEx(int hKey, byte[] subKey) + { + Microsoft.Win32.RegistryKey resultKey = null; + int error = 0; + int disposition = -1; + try + { + Microsoft.Win32.RegistryKey key = MapKey(hKey); + string name = BytesToString(subKey); + resultKey = key.OpenSubKey(name); + disposition = 2; + if (resultKey == null) + { + resultKey = key.CreateSubKey(name); + disposition = 1; + } + } + catch (SecurityException) + { + error = 5; + } + catch (UnauthorizedAccessException) + { + error = 5; + } + return new int[] { AllocHandle(resultKey), error, disposition }; + } + + public static int WindowsRegDeleteKey(int hKey, byte[] subKey) + { + try + { + MapKey(hKey).DeleteSubKey(BytesToString(subKey), false); + return 0; + } + catch (SecurityException) + { + return 5; + } + } + + public static int WindowsRegFlushKey(int hKey) + { + MapKey(hKey).Flush(); + return 0; + } + + public static byte[] WindowsRegQueryValueEx(int hKey, byte[] valueName) + { + try + { + string value = MapKey(hKey).GetValue(BytesToString(valueName)) as string; + if (value == null) + { + return null; + } + return StringToBytes(value); + } + catch (SecurityException) + { + return null; + } + catch (UnauthorizedAccessException) + { + return null; + } + } + + public static int WindowsRegSetValueEx(int hKey, byte[] valueName, byte[] data) + { + if (valueName == null || data == null) + { + return -1; + } + try + { + MapKey(hKey).SetValue(BytesToString(valueName), BytesToString(data)); + return 0; + } + catch (SecurityException) + { + return 5; + } + catch (UnauthorizedAccessException) + { + return 5; + } + } + + public static int WindowsRegDeleteValue(int hKey, byte[] valueName) + { + try + { + MapKey(hKey).DeleteValue(BytesToString(valueName)); + return 0; + } + catch (System.ArgumentException) + { + return 2; //ERROR_FILE_NOT_FOUND + } + catch (SecurityException) + { + return 5; //ERROR_ACCESS_DENIED + } + catch (UnauthorizedAccessException) + { + return 5; //ERROR_ACCESS_DENIED + } + } + + public static int[] WindowsRegQueryInfoKey(int hKey) + { + int[] result = new int[5] { -1, -1, -1, -1, -1 }; + try + { + Microsoft.Win32.RegistryKey key = MapKey(hKey); + result[0] = key.SubKeyCount; + result[1] = 0; + result[2] = key.ValueCount; + foreach (string s in key.GetSubKeyNames()) + { + result[3] = Math.Max(result[3], s.Length); + } + foreach (string s in key.GetValueNames()) + { + result[4] = Math.Max(result[4], s.Length); + } + } + catch (SecurityException) + { + result[1] = 5; + } + catch (UnauthorizedAccessException) + { + result[1] = 5; + } + return result; + } + + public static byte[] WindowsRegEnumKeyEx(int hKey, int subKeyIndex, int maxKeyLength) + { + try + { + return StringToBytes(MapKey(hKey).GetSubKeyNames()[subKeyIndex]); + } + catch (SecurityException) + { + return null; + } + catch (UnauthorizedAccessException) + { + return null; + } + } + + public static byte[] WindowsRegEnumValue(int hKey, int valueIndex, int maxValueNameLength) + { + try + { + return StringToBytes(MapKey(hKey).GetValueNames()[valueIndex]); + } + catch (SecurityException) + { + return null; + } + catch (UnauthorizedAccessException) + { + return null; + } + } +} + +static class UACVirtualization +{ + private enum TOKEN_INFORMATION_CLASS + { + TokenVirtualizationEnabled = 24 + } + + [DllImport("advapi32.dll")] + private static extern int GetTokenInformation( + IntPtr TokenHandle, + TOKEN_INFORMATION_CLASS TokenInformationClass, + out int TokenInformation, + int TokenInformationLength, + out int ReturnLength); + + internal static bool Enabled + { + [SecuritySafeCritical] + get + { + OperatingSystem os = Environment.OSVersion; + if (os.Platform != PlatformID.Win32NT || os.Version.Major < 6) + { + return false; + } + int enabled, length; + return GetTokenInformation(WindowsIdentity.GetCurrent().Token, TOKEN_INFORMATION_CLASS.TokenVirtualizationEnabled, out enabled, 4, out length) != 0 + && enabled != 0; + } + } +} |