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