360 lines
7.7 KiB
C#
Raw Normal View History

/*
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;
}
}
}