diff --git a/Contrib/Library/RegTool/RegTool.c b/Contrib/Library/RegTool/RegTool.c index 81e9ede3..d873d06d 100644 --- a/Contrib/Library/RegTool/RegTool.c +++ b/Contrib/Library/RegTool/RegTool.c @@ -2,7 +2,7 @@ #define STR_SIZE 1024 -void RunSelf(char cmd, char *file); +void RunSelf(char cmd, char *file, int x64); void RegDll(char *file); void RegTypeLib(char *file); void DeleteFileOnReboot(char *pszFile); @@ -47,7 +47,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine if (SUCCEEDED(RegQueryValueEx(key, "count", NULL, &t, (LPBYTE) &count, &l)) && t == REG_DWORD) { DWORD j; - char valname[128], mode[2], file[STR_SIZE]; + char valname[128], mode[3], file[STR_SIZE]; for (j = 1; j <= count; j++) { @@ -61,7 +61,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine if (FAILED(RegQueryValueEx(key, valname, NULL, &t, (LPBYTE) file, &l)) || t != REG_SZ) continue; - RunSelf(mode[0], file); + RunSelf(mode[0], file, mode[1] == 'X'); } } @@ -104,21 +104,57 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine return 0; } -void RunSelf(char cmd, char *file) +void SafeWow64EnableWow64FsRedirection(BOOL Wow64FsEnableRedirection) +{ + HMODULE kernel = GetModuleHandle("kernel32"); + if (kernel) + { + FARPROC proc = GetProcAddress(kernel, "Wow64EnableWow64FsRedirection"); + if (proc) + { + typedef BOOL (WINAPI *Wow64EnableWow64FsRedirectionPtr)(BOOL); + Wow64EnableWow64FsRedirectionPtr Wow64EnableWow64FsRedirectionFunc = + (Wow64EnableWow64FsRedirectionPtr) proc; + + Wow64EnableWow64FsRedirectionFunc(Wow64FsEnableRedirection); + } + } +} + +void RunSelf(char cmd, char *file, int x64) { char self[STR_SIZE]; char cmdline[STR_SIZE]; + int ready = 0; + if (!*file || (cmd != 'D' && cmd != 'T')) return; - if (GetModuleFileName(GetModuleHandle(NULL), self, STR_SIZE)) + if (!x64) + { + if (GetModuleFileName(GetModuleHandle(NULL), self, STR_SIZE)) + { + wsprintf(cmdline, "\"%s\" /%c%s", self, cmd, file); + ready++; + } + } + else + { + if (GetSystemDirectory(self, STR_SIZE)) + { + wsprintf(cmdline, "\"%s\\regsvr32.exe\" /s \"%s\"", self, file); + ready++; + + SafeWow64EnableWow64FsRedirection(FALSE); + } + } + + if (ready) { PROCESS_INFORMATION pi; STARTUPINFO si = { sizeof(STARTUPINFO) }; - wsprintf(cmdline, "\"%s\" /%c%s", self, cmd, file); - if (CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { CloseHandle(pi.hThread); @@ -128,6 +164,11 @@ void RunSelf(char cmd, char *file) CloseHandle(pi.hProcess); } } + + if (x64) + { + SafeWow64EnableWow64FsRedirection(TRUE); + } } void RegDll(char *file) diff --git a/Docs/src/library.but b/Docs/src/library.but index 2402644a..c53dcbab 100644 --- a/Docs/src/library.but +++ b/Docs/src/library.but @@ -102,6 +102,12 @@ The Windows temp directory could be located on any volume, so you cannot use thi \S1{} Options +LIBRARY_X64 + +\b Installs a DLL built for Windows x64. + +\b \\Warning:\\ this resets \R{setregview}{RegSetView} and file system redirection. + LIBRARY_SHELL_EXTENSION \b Define this before inserting InstallLib macro to call SHChangeNotify with SHCNE_ASSOCCHANGED after registration. @@ -213,6 +219,12 @@ Location of the library \S1{} Options +LIBRARY_X64 + +\b Uninstalls a DLL built for Windows x64. + +\b \\Warning:\\ this resets \R{setregview}{RegSetView} and file system redirection. + LIBRARY_SHELL_EXTENSION \b Define this before inserting UninstallLib macro to call SHChangeNotify with SHCNE_ASSOCCHANGED after unregistration. Use this to refresh the shell when uninstalling a shell extension or when changing file associations. diff --git a/Include/Library.nsh b/Include/Library.nsh index 103ef18a..213ea07e 100644 --- a/Include/Library.nsh +++ b/Include/Library.nsh @@ -32,6 +32,7 @@ !endif !include LogicLib.nsh +!include x64.nsh ### GetParent macro, don't pass $1 or $2 as INTPUT or OUTPUT !macro __InstallLib_Helper_GetParent INPUT OUTPUT @@ -207,6 +208,15 @@ !error "InstallLib: Incorrect setting for parameter: install" !endif + ;------------------------ + ;x64 settings + + !ifdef LIBRARY_X64 + + ${DisableX64FSRedirection} + + !endif + ;------------------------ ;Copy the parameters used on run-time to a variable ;This allows the usage of variables as parameter @@ -221,11 +231,23 @@ StrCmp ${shared} "" 0 "installlib.noshareddllincrease_${INSTALLLIB_UNIQUE}" + !ifdef LIBRARY_X64 + + SetRegView 64 + + !endif + ReadRegDword $R0 HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R4 ClearErrors IntOp $R0 $R0 + 1 WriteRegDWORD HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R4 $R0 + !ifdef LIBRARY_X64 + + SetRegView 32 + + !endif + "installlib.noshareddllincrease_${INSTALLLIB_UNIQUE}:" !endif @@ -456,7 +478,15 @@ !ifdef INSTALLLIB_LIBTYPE_REGDLL | INSTALLLIB_LIBTYPE_REGDLLTLB - RegDll $R4 + !ifndef LIBRARY_X64 + + RegDll $R4 + + !else + + ExecWait '"$SYSDIR\regsvr32.exe" /s "$R4"' + + !endif !endif @@ -531,16 +561,15 @@ "installlib.regonreboot_${INSTALLLIB_UNIQUE}:" - !ifdef INSTALLLIB_LIBTYPE_REGDLL - !insertmacro __InstallLib_Helper_AddRegToolEntry 'D' "$R4" "$R5" + !ifdef INSTALLLIB_LIBTYPE_REGDLL | INSTALLLIB_LIBTYPE_REGDLLTLB + !ifndef LIBRARY_X64 + !insertmacro __InstallLib_Helper_AddRegToolEntry 'D' "$R4" "$R5" + !else + !insertmacro __InstallLib_Helper_AddRegToolEntry 'DX' "$R4" "$R5" + !endif !endif - !ifdef INSTALLLIB_LIBTYPE_TLB - !insertmacro __InstallLib_Helper_AddRegToolEntry 'T' "$R4" "$R5" - !endif - - !ifdef INSTALLLIB_LIBTYPE_REGDLLTLB - !insertmacro __InstallLib_Helper_AddRegToolEntry 'D' "$R4" "$R5" + !ifdef INSTALLLIB_LIBTYPE_TLB | INSTALLLIB_LIBTYPE_REGDLLTLB !insertmacro __InstallLib_Helper_AddRegToolEntry 'T' "$R4" "$R5" !endif @@ -553,6 +582,12 @@ "installlib.end_${INSTALLLIB_UNIQUE}:" + !ifdef LIBRARY_X64 + + ${EnableX64FSRedirection} + + !endif + ;------------------------ ;Undefine @@ -608,6 +643,15 @@ !error "UnInstallLib: Incorrect setting for parameter: uninstall" !endif + ;------------------------ + ;x64 settings + + !ifdef LIBRARY_X64 + + ${DisableX64FSRedirection} + + !endif + ;------------------------ ;Copy the parameters used on run-time to a variable ;This allows the usage of variables as parameter @@ -621,6 +665,12 @@ !define UNINSTALLLIB_DONE_LABEL + !ifdef LIBRARY_X64 + + SetRegView 64 + + !endif + ReadRegDword $R0 HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R1 StrCmp $R0 "" "uninstalllib.shareddlldone_${UNINSTALLLIB_UNIQUE}" @@ -636,9 +686,22 @@ "uninstalllib.shareddllinuse_${UNINSTALLLIB_UNIQUE}:" WriteRegDWORD HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R1 $R0 + + !ifdef LIBRARY_X64 + + SetRegView 32 + + !endif + Goto "uninstalllib.done_${UNINSTALLLIB_UNIQUE}" - "uninstalllib.shareddlldone_${UNINSTALLLIB_UNIQUE}:" + "uninstalllib.shareddlldone_${UNINSTALLLIB_UNIQUE}:" + + !ifdef LIBRARY_X64 + + SetRegView 32 + + !endif !endif @@ -674,7 +737,15 @@ !ifdef UNINSTALLLIB_LIBTYPE_REGDLL | UNINSTALLLIB_LIBTYPE_REGDLLTLB - UnRegDLL $R1 + !ifndef LIBRARY_X64 + + UnRegDLL $R1 + + !else + + ExecWait '"$SYSDIR\regsvr32.exe" /s /u "$R1"' + + !endif !endif @@ -754,6 +825,12 @@ !endif + !ifdef LIBRARY_X64 + + ${EnableX64FSRedirection} + + !endif + Pop $R1 Pop $R0