/*************************************************************************** * dll.c * * Standard DLL entry-point functions * ***************************************************************************/ #include "priv.h" #include // // Downlevel delay load support (need to link to dload.lib) // #include EXTERN_C FARPROC WINAPI Downlevel_DelayLoadFailureHook( UINT unReason, PDelayLoadInfo pDelayInfo ); PfnDliHook __pfnDliFailureHook = Downlevel_DelayLoadFailureHook; HANDLE BaseDllHandle; #define MLUI_INIT #include 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);