Load system modules with full paths

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6647 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2015-11-29 13:54:35 +00:00
parent 3e416abd5c
commit 726bf760cd
5 changed files with 53 additions and 33 deletions

View file

@ -16,20 +16,32 @@ BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved
* LOADER * * LOADER *
\*************/ \*************/
HMODULE hWinInet = NULL; HMODULE g_hWinInet = NULL;
// GetProcAddress only takes ANSI. HMODULE NSISCALL LoadSystemLibrary(LPCSTR name) {
FARPROC GetWinInetFunc(char *func) { LPCTSTR fmt = sizeof(*fmt) > 1 ? TEXT("%s%S.dll") : TEXT("%s%s.dll"); // The module name is always ANSI
hWinInet = LoadLibrary(_T("wininet.dll")); BYTE bytebuf[(MAX_PATH+1+20+1+3+!0) * sizeof(*fmt)]; // 20+4 is more than enough for
if (hWinInet) LPTSTR path = (LPTSTR) bytebuf; // the dllnames we are using.
return GetProcAddress(hWinInet, func);
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; return NULL;
} }
void FreeWinInet() { void FreeWinInet() {
if (hWinInet) if (g_hWinInet)
FreeLibrary(hWinInet); FreeLibrary(g_hWinInet);
hWinInet = NULL; g_hWinInet = NULL;
} }
/*************\ /*************\

View file

@ -125,7 +125,9 @@ EXTERN_C void NSISWinMainNOCRT()
// are exempt from this requirement and SHELL32 imports from SHLWAPI on // are exempt from this requirement and SHELL32 imports from SHLWAPI on
// WoW64 systems and it is also on the KnownDLLs list so // WoW64 systems and it is also on the KnownDLLs list so
// SHLWAPI also gets a pass and that just leaves // SHLWAPI also gets a pass and that just leaves
#ifdef NSIS_SUPPORT_GETDLLVERSION
myGetProcAddress(MGA_GetFileVersionInfo); // VERSION myGetProcAddress(MGA_GetFileVersionInfo); // VERSION
#endif
g_SHGetFolderPath = myGetProcAddress(MGA_SHGetFolderPath); // and SHFOLDER g_SHGetFolderPath = myGetProcAddress(MGA_SHGetFolderPath); // and SHFOLDER
{ {

View file

@ -388,17 +388,17 @@ FORCE_INLINE int NSISCALL ui_doinstall(void)
#ifdef NSIS_CONFIG_LICENSEPAGE #ifdef NSIS_CONFIG_LICENSEPAGE
{ // load richedit DLL { // load richedit DLL
static const TCHAR riched20[]=_T("RichEd20"); static const CHAR riched20[]=("RichEd20");
static const TCHAR riched32[]=_T("RichEd32"); static const CHAR riched32[]=("RichEd32");
#ifdef UNICODE #ifdef UNICODE
static const TCHAR richedit20t[]=_T("RichEdit20W"); static const TCHAR richedit20t[]=_T("RichEdit20W");
#else #else
static const TCHAR richedit20t[]=_T("RichEdit20A"); static const TCHAR richedit20t[]=_T("RichEdit20A");
#endif #endif
static const TCHAR richedit[]=_T("RichEdit"); 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 // make richedit20a/w point to RICHEDIT

View file

@ -1090,6 +1090,20 @@ struct MGA_FUNC MGA_FUNCS[] = {
}; };
#endif #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 * 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 * 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) 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; 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); hModule = GetModuleHandleA(dllname); // Avoid LoadLibrary if possible because
if (cch > MAX_PATH) // MAX_PATH was somehow not large enough and we don't support if (!hModule) // it can crash on 64-bit dlls if
cch = 0; // \\?\ paths so we have to settle for just the name. hModule = LoadSystemLibrary(dllname); // WoW64 FS redirection is off.
wsprintf(buf + cch, dllpathfmt, _T("\\") + (!cch || buf[cch-1] == '\\'), dllname);
hModule = GetModuleHandleA(dllname); // Avoid LoadLibrary if possible because return hModule
if (!hModule) // it can crash on 64-bit dlls if ? GetProcAddress(hModule, MGA_FUNCS[func].func)
hModule = LoadLibrary(buf); // WoW64 FS redirection is off. : (FARPROC) hModule; // Optimized "return NULL;"
if (!hModule)
return (FARPROC) hModule; // Optimized "return NULL;"
return GetProcAddress(hModule, MGA_FUNCS[func].func);
} }
void NSISCALL MessageLoop(UINT uCheckedMsg) void NSISCALL MessageLoop(UINT uCheckedMsg)
@ -1136,7 +1139,7 @@ void NSISCALL MessageLoop(UINT uCheckedMsg)
* the windows call and does the appropriate translation when * the windows call and does the appropriate translation when
* appropriate. * 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. * @param funcName The name of the function to get the address of.
* @return The pointer to the function. Null if failure. * @return The pointer to the function. Null if failure.
*/ */

View file

@ -128,11 +128,14 @@ enum myGetProcAddressFunctions {
MGA_InitiateShutdown, MGA_InitiateShutdown,
MGA_SHAutoComplete, // x64 can link to shlwapi directly but as long as MGA_SHGetFolderPath is used we can stick with myGetProcAddress 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 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_GetFileVersionInfoSize, // Version.dll exists in all Windows versions, it is delay loaded to avoid DLL hijacking [bug #1125]
MGA_GetFileVersionInfo, MGA_GetFileVersionInfo,
MGA_VerQueryValue MGA_VerQueryValue
#endif
}; };
HMODULE NSISCALL LoadSystemLibrary(LPCSTR name);
void*NSISCALL myGetProcAddress(const enum myGetProcAddressFunctions func); void*NSISCALL myGetProcAddress(const enum myGetProcAddressFunctions func);
void NSISCALL MessageLoop(UINT uCheckedMsg); void NSISCALL MessageLoop(UINT uCheckedMsg);
@ -142,7 +145,7 @@ void NSISCALL MessageLoop(UINT uCheckedMsg);
* the windows call and does the appropriate translation when * the windows call and does the appropriate translation when
* appropriate. * 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. * @param funcName The name of the function to get the address of.
* @return The pointer to the function. Null if failure. * @return The pointer to the function. Null if failure.
*/ */