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:
parent
3e416abd5c
commit
726bf760cd
5 changed files with 53 additions and 33 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
/*************\
|
||||
|
|
|
@ -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
|
||||
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue