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 *
\*************/
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;
}
/*************\

View file

@ -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
{

View file

@ -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

View file

@ -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.
*/

View file

@ -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.
*/