mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-27 17:50:43 +00:00
983 lines
35 KiB
Java
983 lines
35 KiB
Java
/*
|
|
* Copyright (C) 2010-2015 JPEXS
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
package com.sun.jna.platform.win32;
|
|
|
|
/**
|
|
*
|
|
* @author JPEXS
|
|
*/
|
|
import com.sun.jna.Memory;
|
|
import com.sun.jna.Native;
|
|
import com.sun.jna.Pointer;
|
|
import com.sun.jna.platform.win32.WinNT.EVENTLOGRECORD;
|
|
import com.sun.jna.platform.win32.WinReg.HKEY;
|
|
import com.sun.jna.platform.win32.WinReg.HKEYByReference;
|
|
import com.sun.jna.ptr.IntByReference;
|
|
import java.util.ArrayList;
|
|
import java.util.Map;
|
|
import java.util.Map.Entry;
|
|
import java.util.TreeMap;
|
|
|
|
/**
|
|
* Advapi32 utility API.
|
|
*
|
|
* @author dblock[at]dblock.org
|
|
*/
|
|
public abstract class Advapi32Util {
|
|
|
|
/**
|
|
* An account.
|
|
*/
|
|
public static class Account {
|
|
|
|
/**
|
|
* Account name.
|
|
*/
|
|
public String name;
|
|
/**
|
|
* Account domain.
|
|
*/
|
|
public String domain;
|
|
/**
|
|
* Account SID.
|
|
*/
|
|
public byte[] sid;
|
|
/**
|
|
* String representation of the account SID.
|
|
*/
|
|
public String sidString;
|
|
/**
|
|
* Account type, one of SID_NAME_USE.
|
|
*/
|
|
public int accountType;
|
|
/**
|
|
* Fully qualified account name.
|
|
*/
|
|
public String fqn;
|
|
}
|
|
|
|
/**
|
|
* Checks whether a registry key exists.
|
|
*
|
|
* @param root HKEY_LOCAL_MACHINE, etc.
|
|
* @param key Path to the registry key.
|
|
* @return True if the key exists.
|
|
*/
|
|
public static boolean registryKeyExists(HKEY root, String key) {
|
|
HKEYByReference phkKey = new HKEYByReference();
|
|
int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, key, 0, WinNT.KEY_READ | WinNT.KEY_WOW64_32KEY, phkKey);
|
|
switch (rc) {
|
|
case W32Errors.ERROR_SUCCESS:
|
|
Advapi32.INSTANCE.RegCloseKey(phkKey.getValue());
|
|
return true;
|
|
case W32Errors.ERROR_FILE_NOT_FOUND:
|
|
return false;
|
|
default:
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks whether a registry value exists.
|
|
*
|
|
* @param root HKEY_LOCAL_MACHINE, etc.
|
|
* @param key Registry key path.
|
|
* @param value Value name.
|
|
* @return True if the value exists.
|
|
*/
|
|
public static boolean registryValueExists(HKEY root, String key, String value) {
|
|
HKEYByReference phkKey = new HKEYByReference();
|
|
int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, key, 0, WinNT.KEY_READ | WinNT.KEY_WOW64_32KEY, phkKey);
|
|
try {
|
|
switch (rc) {
|
|
case W32Errors.ERROR_SUCCESS:
|
|
break;
|
|
case W32Errors.ERROR_FILE_NOT_FOUND:
|
|
return false;
|
|
default:
|
|
throw new Win32Exception(rc);
|
|
}
|
|
IntByReference lpcbData = new IntByReference();
|
|
IntByReference lpType = new IntByReference();
|
|
rc = Advapi32.INSTANCE.RegQueryValueEx(
|
|
phkKey.getValue(), value, 0, lpType, (char[]) null, lpcbData);
|
|
switch (rc) {
|
|
case W32Errors.ERROR_SUCCESS:
|
|
case W32Errors.ERROR_INSUFFICIENT_BUFFER:
|
|
return true;
|
|
case W32Errors.ERROR_FILE_NOT_FOUND:
|
|
return false;
|
|
default:
|
|
throw new Win32Exception(rc);
|
|
}
|
|
} finally {
|
|
if (phkKey.getValue() != null && phkKey.getValue() != WinBase.INVALID_HANDLE_VALUE) {
|
|
rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue());
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get a registry REG_SZ value.
|
|
*
|
|
* @param root Root key.
|
|
* @param key Registry path.
|
|
* @param value Name of the value to retrieve.
|
|
* @return String value.
|
|
*/
|
|
public static String registryGetStringValue(HKEY root, String key, String value) {
|
|
HKEYByReference phkKey = new HKEYByReference();
|
|
int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, key, 0, WinNT.KEY_READ | WinNT.KEY_WOW64_32KEY, phkKey);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
try {
|
|
IntByReference lpcbData = new IntByReference();
|
|
IntByReference lpType = new IntByReference();
|
|
rc = Advapi32.INSTANCE.RegQueryValueEx(
|
|
phkKey.getValue(), value, 0, lpType, (char[]) null, lpcbData);
|
|
if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
if (lpType.getValue() != WinNT.REG_SZ) {
|
|
throw new RuntimeException("Unexpected registry type " + lpType.getValue() + ", expected REG_SZ");
|
|
}
|
|
char[] data = new char[lpcbData.getValue()];
|
|
rc = Advapi32.INSTANCE.RegQueryValueEx(
|
|
phkKey.getValue(), value, 0, lpType, data, lpcbData);
|
|
if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
return Native.toString(data);
|
|
} finally {
|
|
rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue());
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get a registry REG_EXPAND_SZ value.
|
|
*
|
|
* @param root Root key.
|
|
* @param key Registry path.
|
|
* @param value Name of the value to retrieve.
|
|
* @return String value.
|
|
*/
|
|
public static String registryGetExpandableStringValue(HKEY root, String key, String value) {
|
|
HKEYByReference phkKey = new HKEYByReference();
|
|
int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, key, 0, WinNT.KEY_READ | WinNT.KEY_WOW64_32KEY, phkKey);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
try {
|
|
IntByReference lpcbData = new IntByReference();
|
|
IntByReference lpType = new IntByReference();
|
|
rc = Advapi32.INSTANCE.RegQueryValueEx(
|
|
phkKey.getValue(), value, 0, lpType, (char[]) null, lpcbData);
|
|
if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
if (lpType.getValue() != WinNT.REG_EXPAND_SZ) {
|
|
throw new RuntimeException("Unexpected registry type " + lpType.getValue() + ", expected REG_SZ");
|
|
}
|
|
char[] data = new char[lpcbData.getValue()];
|
|
rc = Advapi32.INSTANCE.RegQueryValueEx(
|
|
phkKey.getValue(), value, 0, lpType, data, lpcbData);
|
|
if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
return Native.toString(data);
|
|
} finally {
|
|
rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue());
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get a registry REG_MULTI_SZ value.
|
|
*
|
|
* @param root Root key.
|
|
* @param key Registry path.
|
|
* @param value Name of the value to retrieve.
|
|
* @return String value.
|
|
*/
|
|
public static String[] registryGetStringArray(HKEY root, String key, String value) {
|
|
HKEYByReference phkKey = new HKEYByReference();
|
|
int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, key, 0, WinNT.KEY_READ | WinNT.KEY_WOW64_32KEY, phkKey);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
try {
|
|
IntByReference lpcbData = new IntByReference();
|
|
IntByReference lpType = new IntByReference();
|
|
rc = Advapi32.INSTANCE.RegQueryValueEx(
|
|
phkKey.getValue(), value, 0, lpType, (char[]) null, lpcbData);
|
|
if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
if (lpType.getValue() != WinNT.REG_MULTI_SZ) {
|
|
throw new RuntimeException("Unexpected registry type " + lpType.getValue() + ", expected REG_SZ");
|
|
}
|
|
Memory data = new Memory(lpcbData.getValue());
|
|
rc = Advapi32.INSTANCE.RegQueryValueEx(
|
|
phkKey.getValue(), value, 0, lpType, data, lpcbData);
|
|
if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
ArrayList<String> result = new ArrayList<>();
|
|
int offset = 0;
|
|
while (offset < data.size()) {
|
|
String s = data.getString(offset, true);
|
|
offset += s.length() * Native.WCHAR_SIZE;
|
|
offset += Native.WCHAR_SIZE;
|
|
result.add(s);
|
|
}
|
|
return result.toArray(new String[result.size()]);
|
|
} finally {
|
|
rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue());
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get a registry REG_BINARY value.
|
|
*
|
|
* @param root Root key.
|
|
* @param key Registry path.
|
|
* @param value Name of the value to retrieve.
|
|
* @return String value.
|
|
*/
|
|
public static byte[] registryGetBinaryValue(HKEY root, String key, String value) {
|
|
HKEYByReference phkKey = new HKEYByReference();
|
|
int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, key, 0, WinNT.KEY_READ | WinNT.KEY_WOW64_32KEY, phkKey);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
try {
|
|
IntByReference lpcbData = new IntByReference();
|
|
IntByReference lpType = new IntByReference();
|
|
rc = Advapi32.INSTANCE.RegQueryValueEx(
|
|
phkKey.getValue(), value, 0, lpType, (char[]) null, lpcbData);
|
|
if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
if (lpType.getValue() != WinNT.REG_BINARY) {
|
|
throw new RuntimeException("Unexpected registry type " + lpType.getValue() + ", expected REG_BINARY");
|
|
}
|
|
byte[] data = new byte[lpcbData.getValue()];
|
|
rc = Advapi32.INSTANCE.RegQueryValueEx(
|
|
phkKey.getValue(), value, 0, lpType, data, lpcbData);
|
|
if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
return data;
|
|
} finally {
|
|
rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue());
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get a registry DWORD value.
|
|
*
|
|
* @param root Root key.
|
|
* @param key Registry key path.
|
|
* @param value Name of the value to retrieve.
|
|
* @return Integer value.
|
|
*/
|
|
public static int registryGetIntValue(HKEY root, String key, String value) {
|
|
HKEYByReference phkKey = new HKEYByReference();
|
|
int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, key, 0, WinNT.KEY_READ | WinNT.KEY_WOW64_32KEY, phkKey);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
try {
|
|
IntByReference lpcbData = new IntByReference();
|
|
IntByReference lpType = new IntByReference();
|
|
rc = Advapi32.INSTANCE.RegQueryValueEx(
|
|
phkKey.getValue(), value, 0, lpType, (char[]) null, lpcbData);
|
|
if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
if (lpType.getValue() != WinNT.REG_DWORD) {
|
|
throw new RuntimeException("Unexpected registry type " + lpType.getValue() + ", expected REG_SZ");
|
|
}
|
|
IntByReference data = new IntByReference();
|
|
rc = Advapi32.INSTANCE.RegQueryValueEx(
|
|
phkKey.getValue(), value, 0, lpType, data, lpcbData);
|
|
if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
return data.getValue();
|
|
} finally {
|
|
rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue());
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create a registry key.
|
|
*
|
|
* @param hKey Parent key.
|
|
* @param keyName Key name.
|
|
* @return True if the key was created, false otherwise.
|
|
*/
|
|
public static boolean registryCreateKey(HKEY hKey, String keyName) {
|
|
HKEYByReference phkResult = new HKEYByReference();
|
|
IntByReference lpdwDisposition = new IntByReference();
|
|
int rc = Advapi32.INSTANCE.RegCreateKeyEx(hKey, keyName, 0, null, WinNT.REG_OPTION_NON_VOLATILE,
|
|
WinNT.KEY_READ, null, phkResult, lpdwDisposition);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
rc = Advapi32.INSTANCE.RegCloseKey(phkResult.getValue());
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
return WinNT.REG_CREATED_NEW_KEY == lpdwDisposition.getValue();
|
|
}
|
|
|
|
/**
|
|
* Create a registry key.
|
|
*
|
|
* @param root Root key.
|
|
* @param parentPath Path to an existing registry key.
|
|
* @param keyName Key name.
|
|
* @return True if the key was created, false otherwise.
|
|
*/
|
|
public static boolean registryCreateKey(HKEY root, String parentPath, String keyName) {
|
|
HKEYByReference phkKey = new HKEYByReference();
|
|
int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, parentPath, 0, WinNT.KEY_CREATE_SUB_KEY, phkKey);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
try {
|
|
return registryCreateKey(phkKey.getValue(), keyName);
|
|
} finally {
|
|
rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue());
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set an integer value in registry.
|
|
*
|
|
* @param hKey Parent key.
|
|
* @param name Value name.
|
|
* @param value Value to write to registry.
|
|
*/
|
|
public static void registrySetIntValue(HKEY hKey, String name, int value) {
|
|
byte[] data = new byte[4];
|
|
data[0] = (byte) (value & 0xff);
|
|
data[1] = (byte) ((value >> 8) & 0xff);
|
|
data[2] = (byte) ((value >> 16) & 0xff);
|
|
data[3] = (byte) ((value >> 24) & 0xff);
|
|
int rc = Advapi32.INSTANCE.RegSetValueEx(hKey, name, 0, WinNT.REG_DWORD, data, 4);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set an integer value in registry.
|
|
*
|
|
* @param root Root key.
|
|
* @param keyPath Path to an existing registry key.
|
|
* @param name Value name.
|
|
* @param value Value to write to registry.
|
|
*/
|
|
public static void registrySetIntValue(HKEY root, String keyPath, String name, int value) {
|
|
HKEYByReference phkKey = new HKEYByReference();
|
|
int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, keyPath, 0, WinNT.KEY_READ | WinNT.KEY_WRITE | WinNT.KEY_WOW64_32KEY, phkKey);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
try {
|
|
registrySetIntValue(phkKey.getValue(), name, value);
|
|
} finally {
|
|
rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue());
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set a string value in registry.
|
|
*
|
|
* @param hKey Parent key.
|
|
* @param name Value name.
|
|
* @param value Value to write to registry.
|
|
*/
|
|
public static void registrySetStringValue(HKEY hKey, String name, String value) {
|
|
char[] data = Native.toCharArray(value);
|
|
int rc = Advapi32.INSTANCE.RegSetValueEx(hKey, name, 0, WinNT.REG_SZ,
|
|
data, data.length * Native.WCHAR_SIZE);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set a string value in registry.
|
|
*
|
|
* @param root Root key.
|
|
* @param keyPath Path to an existing registry key.
|
|
* @param name Value name.
|
|
* @param value Value to write to registry.
|
|
*/
|
|
public static void registrySetStringValue(HKEY root, String keyPath, String name, String value) {
|
|
HKEYByReference phkKey = new HKEYByReference();
|
|
int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, keyPath, 0, WinNT.KEY_READ | WinNT.KEY_WRITE | WinNT.KEY_WOW64_32KEY, phkKey);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
try {
|
|
registrySetStringValue(phkKey.getValue(), name, value);
|
|
} finally {
|
|
rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue());
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set an expandable string value in registry.
|
|
*
|
|
* @param hKey Parent key.
|
|
* @param name Value name.
|
|
* @param value Value to write to registry.
|
|
*/
|
|
public static void registrySetExpandableStringValue(HKEY hKey, String name, String value) {
|
|
char[] data = Native.toCharArray(value);
|
|
int rc = Advapi32.INSTANCE.RegSetValueEx(hKey, name, 0, WinNT.REG_EXPAND_SZ,
|
|
data, data.length * Native.WCHAR_SIZE);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set a string value in registry.
|
|
*
|
|
* @param root Root key.
|
|
* @param keyPath Path to an existing registry key.
|
|
* @param name Value name.
|
|
* @param value Value to write to registry.
|
|
*/
|
|
public static void registrySetExpandableStringValue(HKEY root, String keyPath, String name, String value) {
|
|
HKEYByReference phkKey = new HKEYByReference();
|
|
int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, keyPath, 0, WinNT.KEY_READ | WinNT.KEY_WRITE | WinNT.KEY_WOW64_32KEY, phkKey);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
try {
|
|
registrySetExpandableStringValue(phkKey.getValue(), name, value);
|
|
} finally {
|
|
rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue());
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set a string array value in registry.
|
|
*
|
|
* @param hKey Parent key.
|
|
* @param name Name.
|
|
* @param arr Array of strings to write to registry.
|
|
*/
|
|
public static void registrySetStringArray(HKEY hKey, String name, String[] arr) {
|
|
int size = 0;
|
|
for (String s : arr) {
|
|
size += s.length() * Native.WCHAR_SIZE;
|
|
size += Native.WCHAR_SIZE;
|
|
}
|
|
|
|
int offset = 0;
|
|
Memory data = new Memory(size);
|
|
for (String s : arr) {
|
|
data.setString(offset, s, true);
|
|
offset += s.length() * Native.WCHAR_SIZE;
|
|
offset += Native.WCHAR_SIZE;
|
|
}
|
|
|
|
int rc = Advapi32.INSTANCE.RegSetValueEx(hKey, name, 0, WinNT.REG_MULTI_SZ,
|
|
data.getByteArray(0, size), size);
|
|
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set a string array value in registry.
|
|
*
|
|
* @param root Root key.
|
|
* @param keyPath Path to an existing registry key.
|
|
* @param name Value name.
|
|
* @param arr Array of strings to write to registry.
|
|
*/
|
|
public static void registrySetStringArray(HKEY root, String keyPath, String name, String[] arr) {
|
|
HKEYByReference phkKey = new HKEYByReference();
|
|
int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, keyPath, 0, WinNT.KEY_READ | WinNT.KEY_WRITE | WinNT.KEY_WOW64_32KEY, phkKey);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
try {
|
|
registrySetStringArray(phkKey.getValue(), name, arr);
|
|
} finally {
|
|
rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue());
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set a binary value in registry.
|
|
*
|
|
* @param hKey Parent key.
|
|
* @param name Value name.
|
|
* @param data Data to write to registry.
|
|
*/
|
|
public static void registrySetBinaryValue(HKEY hKey, String name, byte[] data) {
|
|
int rc = Advapi32.INSTANCE.RegSetValueEx(hKey, name, 0, WinNT.REG_BINARY, data, data.length);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set a binary value in registry.
|
|
*
|
|
* @param root Root key.
|
|
* @param keyPath Path to an existing registry key.
|
|
* @param name Value name.
|
|
* @param data Data to write to registry.
|
|
*/
|
|
public static void registrySetBinaryValue(HKEY root, String keyPath, String name, byte[] data) {
|
|
HKEYByReference phkKey = new HKEYByReference();
|
|
int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, keyPath, 0, WinNT.KEY_READ | WinNT.KEY_WRITE | WinNT.KEY_WOW64_32KEY, phkKey);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
try {
|
|
registrySetBinaryValue(phkKey.getValue(), name, data);
|
|
} finally {
|
|
rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue());
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete a registry key.
|
|
*
|
|
* @param hKey Parent key.
|
|
* @param keyName Name of the key to delete.
|
|
*/
|
|
public static void registryDeleteKey(HKEY hKey, String keyName) {
|
|
int rc = Advapi32.INSTANCE.RegDeleteKey(hKey, keyName);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete a registry key.
|
|
*
|
|
* @param root Root key.
|
|
* @param keyPath Path to an existing registry key.
|
|
* @param keyName Name of the key to delete.
|
|
*/
|
|
public static void registryDeleteKey(HKEY root, String keyPath, String keyName) {
|
|
HKEYByReference phkKey = new HKEYByReference();
|
|
int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, keyPath, 0, WinNT.KEY_READ | WinNT.KEY_WRITE | WinNT.KEY_WOW64_32KEY, phkKey);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
try {
|
|
registryDeleteKey(phkKey.getValue(), keyName);
|
|
} finally {
|
|
rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue());
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete a registry value.
|
|
*
|
|
* @param hKey Parent key.
|
|
* @param valueName Name of the value to delete.
|
|
*/
|
|
public static void registryDeleteValue(HKEY hKey, String valueName) {
|
|
int rc = Advapi32.INSTANCE.RegDeleteValue(hKey, valueName);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete a registry value.
|
|
*
|
|
* @param root Root key.
|
|
* @param keyPath Path to an existing registry key.
|
|
* @param valueName Name of the value to delete.
|
|
*/
|
|
public static void registryDeleteValue(HKEY root, String keyPath, String valueName) {
|
|
HKEYByReference phkKey = new HKEYByReference();
|
|
int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, keyPath, 0, WinNT.KEY_READ | WinNT.KEY_WRITE | WinNT.KEY_WOW64_32KEY, phkKey);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
try {
|
|
registryDeleteValue(phkKey.getValue(), valueName);
|
|
} finally {
|
|
rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue());
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get names of the registry key's sub-keys.
|
|
*
|
|
* @param hKey Registry key.
|
|
* @return Array of registry key names.
|
|
*/
|
|
public static String[] registryGetKeys(HKEY hKey) {
|
|
IntByReference lpcSubKeys = new IntByReference();
|
|
IntByReference lpcMaxSubKeyLen = new IntByReference();
|
|
int rc = Advapi32.INSTANCE.RegQueryInfoKey(hKey, null, null, null,
|
|
lpcSubKeys, lpcMaxSubKeyLen, null, null, null, null, null, null);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
ArrayList<String> keys = new ArrayList<>(lpcSubKeys.getValue());
|
|
char[] name = new char[lpcMaxSubKeyLen.getValue() + 1];
|
|
for (int i = 0; i < lpcSubKeys.getValue(); i++) {
|
|
IntByReference lpcchValueName = new IntByReference(lpcMaxSubKeyLen.getValue() + 1);
|
|
rc = Advapi32.INSTANCE.RegEnumKeyEx(hKey, i, name, lpcchValueName,
|
|
null, null, null, null);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
keys.add(Native.toString(name));
|
|
}
|
|
return keys.toArray(new String[keys.size()]);
|
|
}
|
|
|
|
/**
|
|
* Get names of the registry key's sub-keys.
|
|
*
|
|
* @param root Root key.
|
|
* @param keyPath Path to a registry key.
|
|
* @return Array of registry key names.
|
|
*/
|
|
public static String[] registryGetKeys(HKEY root, String keyPath) {
|
|
HKEYByReference phkKey = new HKEYByReference();
|
|
int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, keyPath, 0, WinNT.KEY_READ | WinNT.KEY_WOW64_32KEY, phkKey);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
try {
|
|
return registryGetKeys(phkKey.getValue());
|
|
} finally {
|
|
rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue());
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get a table of registry values.
|
|
*
|
|
* @param hKey Registry key.
|
|
* @return Table of values.
|
|
*/
|
|
public static TreeMap<String, Object> registryGetValues(HKEY hKey) {
|
|
IntByReference lpcValues = new IntByReference();
|
|
IntByReference lpcMaxValueNameLen = new IntByReference();
|
|
IntByReference lpcMaxValueLen = new IntByReference();
|
|
int rc = Advapi32.INSTANCE.RegQueryInfoKey(hKey, null, null, null, null,
|
|
null, null, lpcValues, lpcMaxValueNameLen, lpcMaxValueLen, null, null);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
TreeMap<String, Object> keyValues = new TreeMap<>();
|
|
char[] name = new char[lpcMaxValueNameLen.getValue() + 1];
|
|
byte[] data = new byte[lpcMaxValueLen.getValue()];
|
|
for (int i = 0; i < lpcValues.getValue(); i++) {
|
|
IntByReference lpcchValueName = new IntByReference(lpcMaxValueNameLen.getValue() + 1);
|
|
IntByReference lpcbData = new IntByReference(lpcMaxValueLen.getValue());
|
|
IntByReference lpType = new IntByReference();
|
|
rc = Advapi32.INSTANCE.RegEnumValue(hKey, i, name, lpcchValueName, null,
|
|
lpType, data, lpcbData);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
|
|
String nameString = Native.toString(name);
|
|
|
|
Memory byteData = new Memory(lpcbData.getValue());
|
|
byteData.write(0, data, 0, lpcbData.getValue());
|
|
|
|
switch (lpType.getValue()) {
|
|
case WinNT.REG_DWORD: {
|
|
keyValues.put(nameString, byteData.getInt(0));
|
|
break;
|
|
}
|
|
case WinNT.REG_SZ:
|
|
case WinNT.REG_EXPAND_SZ: {
|
|
keyValues.put(nameString, byteData.getString(0, true));
|
|
break;
|
|
}
|
|
case WinNT.REG_BINARY: {
|
|
keyValues.put(nameString, byteData.getByteArray(0, lpcbData.getValue()));
|
|
break;
|
|
}
|
|
case WinNT.REG_MULTI_SZ: {
|
|
Memory stringData = new Memory(lpcbData.getValue());
|
|
stringData.write(0, data, 0, lpcbData.getValue());
|
|
ArrayList<String> result = new ArrayList<>();
|
|
int offset = 0;
|
|
while (offset < stringData.size()) {
|
|
String s = stringData.getString(offset, true);
|
|
offset += s.length() * Native.WCHAR_SIZE;
|
|
offset += Native.WCHAR_SIZE;
|
|
result.add(s);
|
|
}
|
|
keyValues.put(nameString, result.toArray(new String[result.size()]));
|
|
break;
|
|
}
|
|
default:
|
|
throw new RuntimeException("Unsupported type: " + lpType.getValue());
|
|
}
|
|
}
|
|
return keyValues;
|
|
}
|
|
|
|
/**
|
|
* Get a table of registry values.
|
|
*
|
|
* @param root Registry root.
|
|
* @param keyPath Regitry key path.
|
|
* @return Table of values.
|
|
*/
|
|
public static TreeMap<String, Object> registryGetValues(HKEY root, String keyPath) {
|
|
HKEYByReference phkKey = new HKEYByReference();
|
|
int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, keyPath, 0, WinNT.KEY_READ | WinNT.KEY_WOW64_32KEY, phkKey);
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
try {
|
|
return registryGetValues(phkKey.getValue());
|
|
} finally {
|
|
rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue());
|
|
if (rc != W32Errors.ERROR_SUCCESS) {
|
|
throw new Win32Exception(rc);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Converts a map of environment variables to an environment block suitable
|
|
* for {@link Advapi32#CreateProcessAsUser}. This environment block consists
|
|
* of null-terminated blocks of null-terminated strings. Each string is in
|
|
* the following form: name=value\0
|
|
*
|
|
* @param environment Environment variables
|
|
* @return A environment block
|
|
*/
|
|
public static String getEnvironmentBlock(Map<String, String> environment) {
|
|
StringBuilder out = new StringBuilder();
|
|
for (Entry<String, String> entry : environment.entrySet()) {
|
|
if (entry.getValue() != null) {
|
|
out.append(entry.getKey()).append("=").append(entry.getValue()).append("\0");
|
|
}
|
|
}
|
|
return out.toString() + "\0";
|
|
}
|
|
|
|
/**
|
|
* Event log types.
|
|
*/
|
|
public static enum EventLogType {
|
|
|
|
Error,
|
|
Warning,
|
|
Informational,
|
|
AuditSuccess,
|
|
AuditFailure
|
|
}
|
|
|
|
/**
|
|
* An event log record.
|
|
*/
|
|
public static class EventLogRecord {
|
|
|
|
private EVENTLOGRECORD _record = null;
|
|
private final String _source;
|
|
private byte[] _data;
|
|
private String[] _strings;
|
|
|
|
/**
|
|
* Raw record data.
|
|
*
|
|
* @return EVENTLOGRECORD.
|
|
*/
|
|
public EVENTLOGRECORD getRecord() {
|
|
return _record;
|
|
}
|
|
|
|
/**
|
|
* Event Id.
|
|
*
|
|
* @return Integer.
|
|
*/
|
|
public int getEventId() {
|
|
return _record.EventID.intValue();
|
|
}
|
|
|
|
/**
|
|
* Event source.
|
|
*
|
|
* @return String.
|
|
*/
|
|
public String getSource() {
|
|
return _source;
|
|
}
|
|
|
|
/**
|
|
* Status code for the facility, part of the Event ID.
|
|
*
|
|
* @return Status code.
|
|
*/
|
|
public int getStatusCode() {
|
|
return _record.EventID.intValue() & 0xFFFF;
|
|
}
|
|
|
|
/**
|
|
* Record number of the record. This value can be used with the
|
|
* EVENTLOG_SEEK_READ flag in the ReadEventLog function to begin reading
|
|
* at a specified record.
|
|
*
|
|
* @return Integer.
|
|
*/
|
|
public int getRecordNumber() {
|
|
return _record.RecordNumber.intValue();
|
|
}
|
|
|
|
/**
|
|
* Record length, with data.
|
|
*
|
|
* @return Number of bytes in the record including data.
|
|
*/
|
|
public int getLength() {
|
|
return _record.Length.intValue();
|
|
}
|
|
|
|
/**
|
|
* Strings associated with this event.
|
|
*
|
|
* @return Array of strings or null.
|
|
*/
|
|
public String[] getStrings() {
|
|
return _strings;
|
|
}
|
|
|
|
/**
|
|
* Event log type.
|
|
*
|
|
* @return Event log type.
|
|
*/
|
|
public EventLogType getType() {
|
|
switch (_record.EventType.intValue()) {
|
|
case WinNT.EVENTLOG_SUCCESS:
|
|
case WinNT.EVENTLOG_INFORMATION_TYPE:
|
|
return EventLogType.Informational;
|
|
case WinNT.EVENTLOG_AUDIT_FAILURE:
|
|
return EventLogType.AuditFailure;
|
|
case WinNT.EVENTLOG_AUDIT_SUCCESS:
|
|
return EventLogType.AuditSuccess;
|
|
case WinNT.EVENTLOG_ERROR_TYPE:
|
|
return EventLogType.Error;
|
|
case WinNT.EVENTLOG_WARNING_TYPE:
|
|
return EventLogType.Warning;
|
|
default:
|
|
throw new RuntimeException("Invalid type: " + _record.EventType.intValue());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Raw data associated with the record.
|
|
*
|
|
* @return Array of bytes or null.
|
|
*/
|
|
public byte[] getData() {
|
|
return _data;
|
|
}
|
|
|
|
public EventLogRecord(Pointer pevlr) {
|
|
_record = new EVENTLOGRECORD(pevlr);
|
|
_source = pevlr.getString(_record.size(), true);
|
|
// data
|
|
if (_record.DataLength.intValue() > 0) {
|
|
_data = pevlr.getByteArray(_record.DataOffset.intValue(),
|
|
_record.DataLength.intValue());
|
|
}
|
|
// strings
|
|
if (_record.NumStrings.intValue() > 0) {
|
|
ArrayList<String> strings = new ArrayList<>();
|
|
int count = _record.NumStrings.intValue();
|
|
long offset = _record.StringOffset.intValue();
|
|
while (count > 0) {
|
|
String s = pevlr.getString(offset, true);
|
|
strings.add(s);
|
|
offset += s.length() * Native.WCHAR_SIZE;
|
|
offset += Native.WCHAR_SIZE;
|
|
count--;
|
|
}
|
|
_strings = strings.toArray(new String[strings.size()]);
|
|
}
|
|
}
|
|
}
|
|
}
|