diff --git a/installer.nsi b/installer.nsi
index eb3575503..a1b266f22 100644
--- a/installer.nsi
+++ b/installer.nsi
@@ -16,17 +16,19 @@
+
+!define APP_SHORTVERNAME "JPEXS FFDec v. ${APP_VER}"
+
!define APP_VERNAME "${APP_NAME} v. ${APP_VER}"
!define MUI_WELCOMEFINISHPAGE_BITMAP "graphics\installer_164x314.bmp"
!define MUI_HEADERIMAGE
-!define MUI_HEADERIMAGE_BITMAP "graphics\installer_150x57.bmp"
+!define MUI_HEADERIMAGE_BITMAP "graphics\installer_150x57.bmp"
!define APP_UNINSTKEY "{E618D276-6596-41F4-8A98-447D442A77DB}_is1"
-
SetCompressor /SOLID lzma
;Name and file
- Name "${APP_VERNAME}"
+ Name "${APP_SHORTVERNAME}"
OutFile "${APP_SETUPFILE}"
@@ -44,8 +46,15 @@ SetCompressor /SOLID lzma
;Interface Settings
!define MUI_ABORTWARNING
+ !define MUI_LANGDLL_ALLLANGUAGES
+
+!define MUI_PAGE_CUSTOMFUNCTION_SHOW un.ModifyUnWelcome
+!define MUI_PAGE_CUSTOMFUNCTION_LEAVE un.LeaveUnWelcome
+!insertmacro MUI_UNPAGE_WELCOME
+!insertmacro MUI_UNPAGE_INSTFILES
+
!include LogicLib.nsh
@@ -76,6 +85,103 @@ Function GetInstalledSize
Push $GetInstalledSize.total
FunctionEnd
+
+
+Function IsFlashInstalled
+ Push $R0
+ ClearErrors
+ ReadRegStr $R0 HKCR "CLSID\{D27CDB6E-AE6D-11cf-96B8-444553540000}\InprocServer32" ""
+ IfErrors lbl_na
+ IfFileExists $R0 0 lbl_na
+ StrCpy $R0 1
+ Goto lbl_end
+ lbl_na:
+ StrCpy $R0 0
+ lbl_end:
+ Exch $R0
+ FunctionEnd
+
+!define IsFlashInstalled "!insertmacro IsFlashInstalled"
+
+!macro IsFlashInstalled ResultVar
+ Call IsFlashInstalled
+ Pop "${ResultVar}"
+!macroend
+
+
+!define StrLoc "!insertmacro StrLoc"
+
+!macro StrLoc ResultVar String SubString StartPoint
+ Push "${String}"
+ Push "${SubString}"
+ Push "${StartPoint}"
+ Call StrLoc
+ Pop "${ResultVar}"
+!macroend
+
+Function StrLoc
+/*After this point:
+ ------------------------------------------
+ $R0 = StartPoint (input)
+ $R1 = SubString (input)
+ $R2 = String (input)
+ $R3 = SubStringLen (temp)
+ $R4 = StrLen (temp)
+ $R5 = StartCharPos (temp)
+ $R6 = TempStr (temp)*/
+
+ ;Get input from user
+ Exch $R0
+ Exch
+ Exch $R1
+ Exch 2
+ Exch $R2
+ Push $R3
+ Push $R4
+ Push $R5
+ Push $R6
+
+ ;Get "String" and "SubString" length
+ StrLen $R3 $R1
+ StrLen $R4 $R2
+ ;Start "StartCharPos" counter
+ StrCpy $R5 0
+
+ ;Loop until "SubString" is found or "String" reaches its end
+ ${Do}
+ ;Remove everything before and after the searched part ("TempStr")
+ StrCpy $R6 $R2 $R3 $R5
+
+ ;Compare "TempStr" with "SubString"
+ ${If} $R6 == $R1
+ ${If} $R0 == `<`
+ IntOp $R6 $R3 + $R5
+ IntOp $R0 $R4 - $R6
+ ${Else}
+ StrCpy $R0 $R5
+ ${EndIf}
+ ${ExitDo}
+ ${EndIf}
+ ;If not "SubString", this could be "String"'s end
+ ${If} $R5 >= $R4
+ StrCpy $R0 ``
+ ${ExitDo}
+ ${EndIf}
+ ;If not, continue the loop
+ IntOp $R5 $R5 + 1
+ ${Loop}
+
+ ;Return output to user
+ Pop $R6
+ Pop $R5
+ Pop $R4
+ Pop $R3
+ Pop $R2
+ Exch
+ Pop $R1
+ Exch $R0
+FunctionEnd
+
Function GetTime
!define GetTime `!insertmacro GetTimeCall`
@@ -216,6 +322,40 @@ Function GetTime
Exch $0
FunctionEnd
+Function RIndexOf
+Exch $R0
+Exch
+Exch $R1
+Push $R2
+Push $R3
+
+ StrCpy $R3 $R0
+ StrCpy $R0 0
+ IntOp $R0 $R0 + 1
+ StrCpy $R2 $R3 1 -$R0
+ StrCmp $R2 "" +2
+ StrCmp $R2 $R1 +2 -3
+
+ StrCpy $R0 -1
+
+Pop $R3
+Pop $R2
+Pop $R1
+
+Exch $R0
+FunctionEnd
+
+!macro StrRPos Var Str Char
+Push "${Char}"
+Push "${Str}"
+Call RIndexOf
+Pop $1
+StrLen $0 ${Str}
+IntOp ${Var} $0 - $1
+!macroend
+
+
+!define StrRPos "!insertmacro StrRPos"
;--------------------------------
;Pages
@@ -245,6 +385,18 @@ var SMDir
!insertmacro MUI_LANGUAGE "English"
!insertmacro MUI_LANGUAGE "Czech"
+ !insertmacro MUI_LANGUAGE "SimpChinese"
+ !insertmacro MUI_LANGUAGE "Dutch"
+ !insertmacro MUI_LANGUAGE "French"
+ !insertmacro MUI_LANGUAGE "German"
+ !insertmacro MUI_LANGUAGE "Hungarian"
+ !insertmacro MUI_LANGUAGE "Polish"
+ !insertmacro MUI_LANGUAGE "Portuguese"
+ !insertmacro MUI_LANGUAGE "PortugueseBR"
+ !insertmacro MUI_LANGUAGE "Russian"
+ !insertmacro MUI_LANGUAGE "Spanish"
+ !insertmacro MUI_LANGUAGE "Swedish"
+ !insertmacro MUI_LANGUAGE "Ukrainian"
@@ -252,14 +404,13 @@ var SMDir
;Installer Sections
-LangString Sec1Name ${LANG_ENGLISH} "FFDec"
-LangString Sec1Name ${LANG_CZECH} "FFDec"
-LangString Sec2Desktop ${LANG_ENGLISH} "Desktop Shortcut"
-LangString Sec2Desktop ${LANG_CZECH} "Zástupce na Ploše"
+LangString Sec3PlayerGlobal ${LANG_ENGLISH} "PlayerGlobal.swc (download)"
+LangString Sec3PlayerGlobal ${LANG_CZECH} "PlayerGlobal.swc (stažení)"
-Section !$(Sec1Name) SecDummy
+
+Section "FFDec" SecDummy
SetShellVarContext all
@@ -284,10 +435,11 @@ Section !$(Sec1Name) SecDummy
;Store installation folder
- DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\${APP_UNINSTKEY}"
- WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_UNINSTKEY}" "DisplayName" "${APP_NAME} (remove only)"
+ DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_UNINSTKEY}"
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_UNINSTKEY}" "DisplayName" "${APP_NAME}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_UNINSTKEY}" "UninstallString" '"$INSTDIR\Uninstall.exe"'
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_UNINSTKEY}" "QuietUninstallString" '"$INSTDIR\Uninstall.exe" /S'
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_UNINSTKEY}" "DisplayIcon" '"$INSTDIR\ffdec.exe"'
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_UNINSTKEY}" "DisplayVersion" "${APP_VER}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_UNINSTKEY}" "URLInfoAbout" "${APP_URL}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_UNINSTKEY}" "URLUpdateInfo" "${APP_URL}"
@@ -295,6 +447,9 @@ Section !$(Sec1Name) SecDummy
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_UNINSTKEY}" "Publisher" "${APP_PUBLISHER}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_UNINSTKEY}" "InstallLocation" "$INSTDIR"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_UNINSTKEY}" "Inno Setup: Icon Group" "$SMDir"
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_UNINSTKEY}" "NSIS: Language" "$language"
+
+
Call GetInstalledSize
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_UNINSTKEY}" "EstimatedSize" $GetInstalledSize.total
@@ -311,29 +466,112 @@ Section !$(Sec1Name) SecDummy
SectionEnd
-Section !$(Sec2Desktop)
+
+
+
+var txt
+var pos
+var pgfound
+var f
+var pgname
+
+Section "PlayerGlobal.swc" SecPlayerGlobal
+
+!tempfile PGHTML
+inetc::get /SILENT /USERAGENT "${APP_NAME} Setup" https://www.adobe.com/support/flashplayer/downloads.html ${PGHTML}
+Pop $0
+StrCmp $0 "OK" dlok
+MessageBox MB_OK|MB_ICONEXCLAMATION "PlayerGlobal.SWC was not found on Adobe webpages. Click OK to abort installation" /SD IDOK
+Abort
+dlok:
+
+StrCpy $pgfound 0
+
+FileOpen $f ${PGHTML} r
+loop:
+ FileRead $f $txt
+ IfErrors done
+ StrCmp $pgfound 1 0 nolicheck
+ ${StrLoc} $pos $txt "
"
+ StrCmp $pos "" nolicheck
+ IntOp $pos $pos + 13
+ StrCpy $txt $txt "" $pos
+ ${StrLoc} $pos $txt "$\"" ">"
+ StrCpy $txt $txt $pos
+ StrCpy $pgfound 2
+ Goto done
+ nolicheck:
+ ${StrLoc} $pos $txt "PlayerGlobal" ">"
+ StrCmp $pos "" loop
+ StrCpy $pgfound 1
+ Goto loop
+done:
+ FileClose $f
+ StrCmp $pgfound 2 +3
+ MessageBox MB_OK|MB_ICONEXCLAMATION "PlayerGlobal.SWC not found on Adobe Webpages, click OK to abort installation" /SD IDOK
+ Abort
+
+ ${StrRPos} $pos $txt "/"
+ IntOp $pos $pos + 1
+ StrCpy $pgname $txt "" $pos
+ SetShellVarContext current
+
+ CreateDirectory "$APPDATA\JPEXS\FFDec\flashlib"
+ inetc::get /USERAGENT "${APP_NAME} Setup" $txt "$APPDATA\JPEXS\FFDec\flashlib\$pgname"
+SectionEnd
+
+Section "Desktop Shortcut"
SetShellVarContext all
CreateShortCut "$DESKTOP\${APP_NAME}.lnk" "$INSTDIR\ffdec.exe" ""
SectionEnd
Function .onInit
- # set section 'test' as selected and read-only
+ !insertmacro MUI_LANGDLL_DISPLAY
IntOp $0 ${SF_SELECTED} | ${SF_RO}
- SectionSetFlags ${SecDummy} $0
+ SectionSetFlags ${SecDummy} $0
FunctionEnd
;--------------------------------
;Descriptions
;Language strings
- LangString DESC_SecDummy ${LANG_ENGLISH} "Application GUI and Libraries"
- LangString DESC_SecDummy ${LANG_CZECH} "Aplikační rozhraní a knihovny"
+ ;LangString DESC_SecDummy ${LANG_ENGLISH} "Application GUI and Libraries"
+ ;LangString DESC_SecDummy ${LANG_CZECH} "Aplikační rozhraní a knihovny"
+
+ ;LangString DESC_PlayerGlobal ${LANG_ENGLISH} "Download FlashPlayer library from Adobe site - useful for ActionScript direct editation and other features"
+ ;LangString DESC_PlayerGlobal ${LANG_CZECH} "Stáhnout knihovnu FlashPlayeru ze stránek Adobe - užitečné pro přímou editaci ActionScriptu a další věci"
;Assign language strings to sections
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
- !insertmacro MUI_DESCRIPTION_TEXT ${SecDummy} $(DESC_SecDummy)
+ !insertmacro MUI_DESCRIPTION_TEXT ${SecDummy} "Application GUI and Libraries"
+ !insertmacro MUI_DESCRIPTION_TEXT ${SecPlayerGlobal} "Download FlashPlayer library from Adobe site - useful for ActionScript direct editation and other features"
!insertmacro MUI_FUNCTION_DESCRIPTION_END
+
+;LangString DESC_UninstLocal ${LANG_ENGLISH} "Remove user configuration"
+;LangString DESC_UninstLocal ${LANG_CZECH} "Odstranit uživatelskou konfiguraci"
+
+
+
+
+Var mycheckbox
+Var uninstlocal
+
+Function un.ModifyUnWelcome
+${NSD_CreateCheckbox} 120u -18u 50% 12u "Remove user configuration"
+Pop $mycheckbox
+SetCtlColors $mycheckbox "" ${MUI_BGCOLOR}
+;${NSD_Check} $mycheckbox ; Check it by default
+FunctionEnd
+
+Function un.LeaveUnWelcome
+StrCpy $uninstlocal 0
+${NSD_GetState} $mycheckbox $0
+${If} $0 <> 0
+ StrCpy $uninstlocal 1
+${EndIf}
+FunctionEnd
+
;--------------------------------
;Uninstaller Section
@@ -353,9 +591,17 @@ Section "Uninstall"
!insertmacro MUI_STARTMENU_GETFOLDER 0 $SMDir
RmDir /r "$SMPROGRAMS\$SMDir\*.*"
- RMDir "$SMPROGRAMS\$SMDir"
+ RmDir "$SMPROGRAMS\$SMDir"
+ StrCmp $uninstlocal 1 0 +5
+ SetShellVarContext current
+ RmDir /r "$APPDATA\JPEXS\FFDec\*.*"
+ RmDir "$APPDATA\JPEXS\FFDec"
+ RmDir "$APPDATA\JPEXS"
+
DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\${APP_UNINSTKEY}"
SectionEnd
+
+;TODO: FlashPlayer detection/install, Java detection/install
\ No newline at end of file
diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java
index 0d52256cf..7e5cfaa2d 100644
--- a/src/com/jpexs/decompiler/flash/gui/Main.java
+++ b/src/com/jpexs/decompiler/flash/gui/Main.java
@@ -32,6 +32,7 @@ import com.jpexs.decompiler.flash.abc.types.Namespace;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.console.CommandLineArgumentParser;
import com.jpexs.decompiler.flash.console.ContextMenuTools;
+import static com.jpexs.decompiler.flash.console.ContextMenuTools.getAppDir;
import com.jpexs.decompiler.flash.gui.debugger.Debugger;
import com.jpexs.decompiler.flash.gui.proxy.ProxyFrame;
import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin;
@@ -48,6 +49,9 @@ import com.jpexs.helpers.ProgressListener;
import com.jpexs.helpers.Stopwatch;
import com.jpexs.helpers.streams.SeekableInputStream;
import com.sun.jna.Platform;
+import com.sun.jna.platform.win32.Advapi32Util;
+import com.sun.jna.platform.win32.Kernel32;
+import com.sun.jna.platform.win32.WinReg;
import java.awt.AWTException;
import java.awt.Frame;
import java.awt.GraphicsEnvironment;
@@ -816,6 +820,45 @@ public class Main {
if (GraphicsEnvironment.isHeadless()) { //No GUI in OS
return;
}
+ if (!Configuration.locale.hasValue()){
+ if (Platform.isWindows()) {
+ //Load from Installer
+ String uninstKey = "{E618D276-6596-41F4-8A98-447D442A77DB}_is1";
+ uninstKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + uninstKey;
+ try {
+ if (Advapi32Util.registryKeyExists(WinReg.HKEY_LOCAL_MACHINE, uninstKey)) {
+ if (Advapi32Util.registryValueExists(WinReg.HKEY_LOCAL_MACHINE, uninstKey, "NSIS: Language")) {
+ String installedLoc = Advapi32Util.registryGetStringValue(WinReg.HKEY_LOCAL_MACHINE, uninstKey, "NSIS: Language");
+ int lcid = Integer.parseInt(installedLoc);
+ char buf[] = new char[9];
+ int cnt = Kernel32.INSTANCE.GetLocaleInfo(lcid, Kernel32.LOCALE_SISO639LANGNAME, buf, 9);
+ String langCode = new String(buf, 0, cnt).trim().toLowerCase();
+
+ cnt = Kernel32.INSTANCE.GetLocaleInfo(lcid, Kernel32.LOCALE_SISO3166CTRYNAME, buf, 9);
+ String countryCode = new String(buf, 0, cnt).trim().toLowerCase();
+
+ List langs=Arrays.asList(SelectLanguageDialog.getAvailableLanguages());
+ for(int i=0;i.
- */
-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, 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, 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, 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, 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, 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 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, 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, 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, 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, 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, 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, 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, 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, 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, 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 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, 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 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 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 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 registryGetValues(HKEY root, String keyPath) {
- HKEYByReference phkKey = new HKEYByReference();
- int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, keyPath, 0, WinNT.KEY_READ, 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 environment) {
- StringBuilder out = new StringBuilder();
- for (Entry 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 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()]);
- }
- }
- }
-}
+/*
+ * Copyright (C) 2010-2014 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 .
+ */
+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 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 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 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 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 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 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 environment) {
+ StringBuilder out = new StringBuilder();
+ for (Entry 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 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()]);
+ }
+ }
+ }
+}
diff --git a/src/com/sun/jna/platform/win32/Kernel32.java b/src/com/sun/jna/platform/win32/Kernel32.java
index 2730c4b2e..c0e7408cf 100644
--- a/src/com/sun/jna/platform/win32/Kernel32.java
+++ b/src/com/sun/jna/platform/win32/Kernel32.java
@@ -299,4 +299,9 @@ public interface Kernel32 extends WinNT {
DWORD QueryDosDevice(String lpDeviceName, char[] lpTargetPath, int lenght);
boolean VirtualProtectEx(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, int flNewProtect, IntByReference lpflOldProtect);
+
+
+ public static final int LOCALE_SISO3166CTRYNAME = 90;
+ public static final int LOCALE_SISO639LANGNAME = 89;
+ int GetLocaleInfo (int Locale, int LCType, char[] lpLCData, int cchData);
}