windows-nt/Source/XPSP1/NT/shell/shlwapi/dll.c
2020-09-26 16:20:57 +08:00

212 lines
5.3 KiB
C

/***************************************************************************
* dll.c
*
* Standard DLL entry-point functions
*
***************************************************************************/
#include "priv.h"
#include <ntverp.h>
//
// Downlevel delay load support (need to link to dload.lib)
//
#include <delayimp.h>
EXTERN_C
FARPROC
WINAPI
Downlevel_DelayLoadFailureHook(
UINT unReason,
PDelayLoadInfo pDelayInfo
);
PfnDliHook __pfnDliFailureHook = Downlevel_DelayLoadFailureHook;
HANDLE BaseDllHandle;
#define MLUI_INIT
#include <mluisupp.h>
BOOL g_bRunningOnNT = FALSE;
BOOL g_bRunningOnNT5OrHigher = FALSE;
BOOL g_bRunningOnMemphis = FALSE;
HINSTANCE g_hinst = NULL;
CRITICAL_SECTION g_csDll = {0};
DWORD g_TpsTls = (UINT)-1;
DWORD g_tlsThreadRef = (UINT)-1;
DWORD g_tlsOtherThreadsRef = (UINT)-1;
BOOL g_bDllTerminating = FALSE;
#ifdef DEBUG
//#define PROOFREAD_PARSES
#endif
#ifdef PROOFREAD_PARSES
enum
{
PP_COMPARE,
PP_ORIGINAL_ONLY,
PP_NEW_ONLY
};
DWORD g_dwProofMode = PP_COMPARE;
#endif // PROOFREAD_PARSES
void TermPalette();
void DeinitPUI();
void FreeViewStatePropertyBagCache();
void FreeDynamicLibraries();
STDAPI_(void) FreeGlobalSecurityAttributes();
STDAPI_(void) InitTimerQueue();
//
// Table of all window classes we register so we can unregister them
// at DLL unload.
//
// Since we are single-binary, we have to play it safe and do
// this cleanup (needed only on NT, but harmless on Win95).
//
const LPCTSTR c_rgszClasses[] = {
TEXT("WorkerA"), // util.cpp
TEXT("WorkerW"), // util.cpp
TEXT("WorkerW"), // util.cpp
};
//
// Global DCs used during mirroring an Icon.
//
HDC g_hdc = NULL, g_hdcMask = NULL;
BOOL g_bMirroredOS = FALSE;
STDAPI_(void) InitShellKeys(BOOL fInit);
#ifndef NO_ETW_TRACING
ULONG UnRegisterTracing();
#endif
BOOL APIENTRY DllMain(IN HANDLE hDll, IN DWORD dwReason, IN LPVOID lpReserved)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hDll);
#ifdef DEBUG
CcshellGetDebugFlags();
#endif
InitializeCriticalSection(&g_csDll); // for later use
BaseDllHandle = hDll; // for delayload
g_hinst = hDll;
MLLoadResources(g_hinst, TEXT("shlwaplc.dll"));
g_bRunningOnNT = IsOS(OS_NT);
g_bRunningOnNT5OrHigher = IsOS(OS_WIN2000ORGREATER);
g_bRunningOnMemphis = IsOS(OS_WIN98ORGREATER);
InitStopWatchMode(); // See if perf mode is enabled
InitTimerQueue();
// Check if we are running on a system that supports the mirroring APIs
// i.e. (NT5 or Memphis/BiDi)
//
g_bMirroredOS = IS_MIRRORING_ENABLED();
g_TpsTls = TlsAlloc();
g_tlsThreadRef = TlsAlloc();
g_tlsOtherThreadsRef = TlsAlloc();
InitShellKeys(TRUE);
#ifdef PROOFREAD_PARSES
{
DWORD dwSize = sizeof(g_dwProofMode);
if (ERROR_SUCCESS != SHGetValue( HKEY_CURRENT_USER,
TEXT("Software\\Microsoft\\Internet Explorer\\Main"),
TEXT("Verify URLCombine"), NULL, &g_dwProofMode, &dwSize) ||
(g_dwProofMode > PP_NEW_ONLY))
{
g_dwProofMode = PP_COMPARE;
}
}
#endif
break;
case DLL_PROCESS_DETACH:
g_bDllTerminating = TRUE;
MLFreeResources(g_hinst);
if (lpReserved == NULL)
{
DeinitPUI(); // free up plug ui resource hinstance dpa table
FreeViewStatePropertyBagCache();
}
//
// Icon mirroring stuff (see mirror.c)
// Cleanup cached DCs. No need to synchronize the following section of
// code since it is only called in DLL_PROCESS_DETACH which is
// synchronized by the OS Loader.
//
if (g_bMirroredOS)
{
if (g_hdc)
DeleteDC(g_hdc);
if (g_hdcMask)
DeleteDC(g_hdcMask);
g_hdc = g_hdcMask = NULL;
}
FreeGlobalSecurityAttributes();
TermPalette();
if (StopWatchMode()) {
StopWatchFlush(); // Flush the performance timing data to disk
#ifndef NO_ETW_TRACING
// If any event tracing controls are enabled, this cleans them up.
UnRegisterTracing();
#endif
}
DeleteCriticalSection(&g_csDll);
if (lpReserved == NULL)
{
SHTerminateThreadPool();
SHUnregisterClasses(HINST_THISDLL, c_rgszClasses, ARRAYSIZE(c_rgszClasses));
#ifdef I_WANT_WIN95_TO_CRASH
// If you call FreeLibrary during PROCESS_ATTACH, Win95 will crash
FreeDynamicLibraries();
#endif
}
if (g_TpsTls != (UINT)-1)
TlsFree(g_TpsTls);
if (g_tlsThreadRef != (UINT)-1)
TlsFree(g_tlsThreadRef);
if (g_tlsOtherThreadsRef != (UINT)-1)
TlsFree(g_tlsOtherThreadsRef);
InitShellKeys(FALSE);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
ASSERT(0); // We shouldn't get these because we called DisableThreadLibraryCalls().
break;
default:
break;
}
return TRUE;
}
// DllGetVersion
//
// All we have to do is declare this puppy and CCDllGetVersion does the rest
//
DLLVER_SINGLEBINARY(VER_PRODUCTVERSION_DW, VER_PRODUCTBUILD_QFE);