diff --git a/Contrib/Dialer/dialer.c b/Contrib/Dialer/dialer.c index 3744edeb..4d48bd52 100644 --- a/Contrib/Dialer/dialer.c +++ b/Contrib/Dialer/dialer.c @@ -16,20 +16,32 @@ BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved * LOADER * \*************/ -HMODULE hWinInet = NULL; +HMODULE g_hWinInet = NULL; -// GetProcAddress only takes ANSI. -FARPROC GetWinInetFunc(char *func) { - hWinInet = LoadLibrary(_T("wininet.dll")); - if (hWinInet) - return GetProcAddress(hWinInet, func); +HMODULE NSISCALL LoadSystemLibrary(LPCSTR name) { + LPCTSTR fmt = sizeof(*fmt) > 1 ? TEXT("%s%S.dll") : TEXT("%s%s.dll"); // The module name is always ANSI + BYTE bytebuf[(MAX_PATH+1+20+1+3+!0) * sizeof(*fmt)]; // 20+4 is more than enough for + LPTSTR path = (LPTSTR) bytebuf; // the dllnames we are using. + + UINT cch = GetSystemDirectory(path, MAX_PATH); + if (cch > MAX_PATH) // MAX_PATH was somehow not large enough and we don't support + cch = 0; // \\?\ paths so we have to settle for just the name. + wsprintf(path + cch, fmt, TEXT("\\") + (!cch || path[cch-1] == '\\'), name); + + return LoadLibrary(path); +} + +FARPROC GetWinInetFunc(LPCSTR funcname) { + g_hWinInet = LoadSystemLibrary("WININET"); + if (g_hWinInet) + return GetProcAddress(g_hWinInet, funcname); return NULL; } void FreeWinInet() { - if (hWinInet) - FreeLibrary(hWinInet); - hWinInet = NULL; + if (g_hWinInet) + FreeLibrary(g_hWinInet); + g_hWinInet = NULL; } /*************\ diff --git a/Source/exehead/Main.c b/Source/exehead/Main.c index bdcc1693..8e658dd4 100644 --- a/Source/exehead/Main.c +++ b/Source/exehead/Main.c @@ -125,7 +125,9 @@ EXTERN_C void NSISWinMainNOCRT() // are exempt from this requirement and SHELL32 imports from SHLWAPI on // WoW64 systems and it is also on the KnownDLLs list so // SHLWAPI also gets a pass and that just leaves +#ifdef NSIS_SUPPORT_GETDLLVERSION myGetProcAddress(MGA_GetFileVersionInfo); // VERSION +#endif g_SHGetFolderPath = myGetProcAddress(MGA_SHGetFolderPath); // and SHFOLDER { diff --git a/Source/exehead/Ui.c b/Source/exehead/Ui.c index 618c2558..ccdcdbdd 100644 --- a/Source/exehead/Ui.c +++ b/Source/exehead/Ui.c @@ -388,17 +388,17 @@ FORCE_INLINE int NSISCALL ui_doinstall(void) #ifdef NSIS_CONFIG_LICENSEPAGE { // load richedit DLL - static const TCHAR riched20[]=_T("RichEd20"); - static const TCHAR riched32[]=_T("RichEd32"); + static const CHAR riched20[]=("RichEd20"); + static const CHAR riched32[]=("RichEd32"); #ifdef UNICODE static const TCHAR richedit20t[]=_T("RichEdit20W"); #else static const TCHAR richedit20t[]=_T("RichEdit20A"); #endif static const TCHAR richedit[]=_T("RichEdit"); - if (!LoadLibrary(riched20)) + if (!LoadSystemLibrary(riched20)) { - LoadLibrary(riched32); // Win95 only ships with v1.0, NT4 has v2.0: web.archive.org/web/20030607222419/http://msdn.microsoft.com/library/en-us/shellcc/platform/commctls/richedit/richeditcontrols/aboutricheditcontrols.asp + LoadSystemLibrary(riched32); // Win95 only ships with v1.0, NT4 has v2.0: web.archive.org/web/20030607222419/http://msdn.microsoft.com/library/en-us/shellcc/platform/commctls/richedit/richeditcontrols/aboutricheditcontrols.asp } // make richedit20a/w point to RICHEDIT diff --git a/Source/exehead/util.c b/Source/exehead/util.c index c502ad0e..f5c2bfda 100644 --- a/Source/exehead/util.c +++ b/Source/exehead/util.c @@ -1090,6 +1090,20 @@ struct MGA_FUNC MGA_FUNCS[] = { }; #endif +HMODULE NSISCALL LoadSystemLibrary(LPCSTR name) +{ + LPCTSTR fmt = sizeof(*fmt) > 1 ? TEXT("%s%S.dll") : TEXT("%s%s.dll"); // The module name is always ANSI + BYTE bytebuf[(MAX_PATH+1+20+1+3+!0) * sizeof(*fmt)]; // 20+4 is more than enough for + LPTSTR path = (LPTSTR) bytebuf; // the dllnames we are using. + + UINT cch = GetSystemDirectory(path, MAX_PATH); + if (cch > MAX_PATH) // MAX_PATH was somehow not large enough and we don't support + cch = 0; // \\?\ paths so we have to settle for just the name. + wsprintf(path + cch, fmt, TEXT("\\") + (!cch || path[cch-1] == '\\'), name); + + return LoadLibrary(path); +} + /** * Given a function enum, it will load the appropriate DLL and get the * process address of the function and return the pointer. It's up to @@ -1100,27 +1114,16 @@ struct MGA_FUNC MGA_FUNCS[] = { */ void* NSISCALL myGetProcAddress(const enum myGetProcAddressFunctions func) { -#ifdef UNICODE - static const TCHAR dllpathfmt[] = _T("%s%hs.dll"); // Strings in MGA_FUNC are always ANSI -#else - static const TCHAR dllpathfmt[] = _T("%s%s.dll"); -#endif - HMODULE hModule; const char *dllname = MGA_FUNCS[func].dll; - TCHAR buf[MAX_PATH+1+20+4+!0]; // 20+4 is more than enough for the dllnames we are using + HMODULE hModule; - UINT cch = GetSystemDirectory(buf, MAX_PATH); - if (cch > MAX_PATH) // MAX_PATH was somehow not large enough and we don't support - cch = 0; // \\?\ paths so we have to settle for just the name. - wsprintf(buf + cch, dllpathfmt, _T("\\") + (!cch || buf[cch-1] == '\\'), dllname); + hModule = GetModuleHandleA(dllname); // Avoid LoadLibrary if possible because + if (!hModule) // it can crash on 64-bit dlls if + hModule = LoadSystemLibrary(dllname); // WoW64 FS redirection is off. - hModule = GetModuleHandleA(dllname); // Avoid LoadLibrary if possible because - if (!hModule) // it can crash on 64-bit dlls if - hModule = LoadLibrary(buf); // WoW64 FS redirection is off. - if (!hModule) - return (FARPROC) hModule; // Optimized "return NULL;" - - return GetProcAddress(hModule, MGA_FUNCS[func].func); + return hModule + ? GetProcAddress(hModule, MGA_FUNCS[func].func) + : (FARPROC) hModule; // Optimized "return NULL;" } void NSISCALL MessageLoop(UINT uCheckedMsg) @@ -1136,7 +1139,7 @@ void NSISCALL MessageLoop(UINT uCheckedMsg) * the windows call and does the appropriate translation when * appropriate. * - * @param dllHandle Handle to the DLL loaded by LoadLibraryEx. + * @param dllHandle Handle to the DLL loaded by LoadLibrary[Ex]. * @param funcName The name of the function to get the address of. * @return The pointer to the function. Null if failure. */ diff --git a/Source/exehead/util.h b/Source/exehead/util.h index 9acf0bc6..e3906723 100644 --- a/Source/exehead/util.h +++ b/Source/exehead/util.h @@ -128,11 +128,14 @@ enum myGetProcAddressFunctions { MGA_InitiateShutdown, MGA_SHAutoComplete, // x64 can link to shlwapi directly but as long as MGA_SHGetFolderPath is used we can stick with myGetProcAddress MGA_SHGetFolderPath, // TODO: This can probably call something else directly on x64 +#ifdef NSIS_SUPPORT_GETDLLVERSION MGA_GetFileVersionInfoSize, // Version.dll exists in all Windows versions, it is delay loaded to avoid DLL hijacking [bug #1125] MGA_GetFileVersionInfo, MGA_VerQueryValue +#endif }; +HMODULE NSISCALL LoadSystemLibrary(LPCSTR name); void*NSISCALL myGetProcAddress(const enum myGetProcAddressFunctions func); void NSISCALL MessageLoop(UINT uCheckedMsg); @@ -142,7 +145,7 @@ void NSISCALL MessageLoop(UINT uCheckedMsg); * the windows call and does the appropriate translation when * appropriate. * - * @param dllHandle Handle to the DLL loaded by LoadLibraryEx. + * @param dllHandle Handle to the DLL loaded by LoadLibrary[Ex]. * @param funcName The name of the function to get the address of. * @return The pointer to the function. Null if failure. */