Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

211 lines
5.3 KiB

  1. /***************************************************************************
  2. * dll.c
  3. *
  4. * Standard DLL entry-point functions
  5. *
  6. ***************************************************************************/
  7. #include "priv.h"
  8. #include <ntverp.h>
  9. //
  10. // Downlevel delay load support (need to link to dload.lib)
  11. //
  12. #include <delayimp.h>
  13. EXTERN_C
  14. FARPROC
  15. WINAPI
  16. Downlevel_DelayLoadFailureHook(
  17. UINT unReason,
  18. PDelayLoadInfo pDelayInfo
  19. );
  20. PfnDliHook __pfnDliFailureHook = Downlevel_DelayLoadFailureHook;
  21. HANDLE BaseDllHandle;
  22. #define MLUI_INIT
  23. #include <mluisupp.h>
  24. BOOL g_bRunningOnNT = FALSE;
  25. BOOL g_bRunningOnNT5OrHigher = FALSE;
  26. BOOL g_bRunningOnMemphis = FALSE;
  27. HINSTANCE g_hinst = NULL;
  28. CRITICAL_SECTION g_csDll = {0};
  29. DWORD g_TpsTls = (UINT)-1;
  30. DWORD g_tlsThreadRef = (UINT)-1;
  31. DWORD g_tlsOtherThreadsRef = (UINT)-1;
  32. BOOL g_bDllTerminating = FALSE;
  33. #ifdef DEBUG
  34. //#define PROOFREAD_PARSES
  35. #endif
  36. #ifdef PROOFREAD_PARSES
  37. enum
  38. {
  39. PP_COMPARE,
  40. PP_ORIGINAL_ONLY,
  41. PP_NEW_ONLY
  42. };
  43. DWORD g_dwProofMode = PP_COMPARE;
  44. #endif // PROOFREAD_PARSES
  45. void TermPalette();
  46. void DeinitPUI();
  47. void FreeViewStatePropertyBagCache();
  48. void FreeDynamicLibraries();
  49. STDAPI_(void) FreeGlobalSecurityAttributes();
  50. STDAPI_(void) InitTimerQueue();
  51. //
  52. // Table of all window classes we register so we can unregister them
  53. // at DLL unload.
  54. //
  55. // Since we are single-binary, we have to play it safe and do
  56. // this cleanup (needed only on NT, but harmless on Win95).
  57. //
  58. const LPCTSTR c_rgszClasses[] = {
  59. TEXT("WorkerA"), // util.cpp
  60. TEXT("WorkerW"), // util.cpp
  61. TEXT("WorkerW"), // util.cpp
  62. };
  63. //
  64. // Global DCs used during mirroring an Icon.
  65. //
  66. HDC g_hdc = NULL, g_hdcMask = NULL;
  67. BOOL g_bMirroredOS = FALSE;
  68. STDAPI_(void) InitShellKeys(BOOL fInit);
  69. #ifndef NO_ETW_TRACING
  70. ULONG UnRegisterTracing();
  71. #endif
  72. BOOL APIENTRY DllMain(IN HANDLE hDll, IN DWORD dwReason, IN LPVOID lpReserved)
  73. {
  74. switch(dwReason)
  75. {
  76. case DLL_PROCESS_ATTACH:
  77. DisableThreadLibraryCalls(hDll);
  78. #ifdef DEBUG
  79. CcshellGetDebugFlags();
  80. #endif
  81. InitializeCriticalSection(&g_csDll); // for later use
  82. BaseDllHandle = hDll; // for delayload
  83. g_hinst = hDll;
  84. MLLoadResources(g_hinst, TEXT("shlwaplc.dll"));
  85. g_bRunningOnNT = IsOS(OS_NT);
  86. g_bRunningOnNT5OrHigher = IsOS(OS_WIN2000ORGREATER);
  87. g_bRunningOnMemphis = IsOS(OS_WIN98ORGREATER);
  88. InitStopWatchMode(); // See if perf mode is enabled
  89. InitTimerQueue();
  90. // Check if we are running on a system that supports the mirroring APIs
  91. // i.e. (NT5 or Memphis/BiDi)
  92. //
  93. g_bMirroredOS = IS_MIRRORING_ENABLED();
  94. g_TpsTls = TlsAlloc();
  95. g_tlsThreadRef = TlsAlloc();
  96. g_tlsOtherThreadsRef = TlsAlloc();
  97. InitShellKeys(TRUE);
  98. #ifdef PROOFREAD_PARSES
  99. {
  100. DWORD dwSize = sizeof(g_dwProofMode);
  101. if (ERROR_SUCCESS != SHGetValue( HKEY_CURRENT_USER,
  102. TEXT("Software\\Microsoft\\Internet Explorer\\Main"),
  103. TEXT("Verify URLCombine"), NULL, &g_dwProofMode, &dwSize) ||
  104. (g_dwProofMode > PP_NEW_ONLY))
  105. {
  106. g_dwProofMode = PP_COMPARE;
  107. }
  108. }
  109. #endif
  110. break;
  111. case DLL_PROCESS_DETACH:
  112. g_bDllTerminating = TRUE;
  113. MLFreeResources(g_hinst);
  114. if (lpReserved == NULL)
  115. {
  116. DeinitPUI(); // free up plug ui resource hinstance dpa table
  117. FreeViewStatePropertyBagCache();
  118. }
  119. //
  120. // Icon mirroring stuff (see mirror.c)
  121. // Cleanup cached DCs. No need to synchronize the following section of
  122. // code since it is only called in DLL_PROCESS_DETACH which is
  123. // synchronized by the OS Loader.
  124. //
  125. if (g_bMirroredOS)
  126. {
  127. if (g_hdc)
  128. DeleteDC(g_hdc);
  129. if (g_hdcMask)
  130. DeleteDC(g_hdcMask);
  131. g_hdc = g_hdcMask = NULL;
  132. }
  133. FreeGlobalSecurityAttributes();
  134. TermPalette();
  135. if (StopWatchMode()) {
  136. StopWatchFlush(); // Flush the performance timing data to disk
  137. #ifndef NO_ETW_TRACING
  138. // If any event tracing controls are enabled, this cleans them up.
  139. UnRegisterTracing();
  140. #endif
  141. }
  142. DeleteCriticalSection(&g_csDll);
  143. if (lpReserved == NULL)
  144. {
  145. SHTerminateThreadPool();
  146. SHUnregisterClasses(HINST_THISDLL, c_rgszClasses, ARRAYSIZE(c_rgszClasses));
  147. #ifdef I_WANT_WIN95_TO_CRASH
  148. // If you call FreeLibrary during PROCESS_ATTACH, Win95 will crash
  149. FreeDynamicLibraries();
  150. #endif
  151. }
  152. if (g_TpsTls != (UINT)-1)
  153. TlsFree(g_TpsTls);
  154. if (g_tlsThreadRef != (UINT)-1)
  155. TlsFree(g_tlsThreadRef);
  156. if (g_tlsOtherThreadsRef != (UINT)-1)
  157. TlsFree(g_tlsOtherThreadsRef);
  158. InitShellKeys(FALSE);
  159. break;
  160. case DLL_THREAD_ATTACH:
  161. case DLL_THREAD_DETACH:
  162. ASSERT(0); // We shouldn't get these because we called DisableThreadLibraryCalls().
  163. break;
  164. default:
  165. break;
  166. }
  167. return TRUE;
  168. }
  169. // DllGetVersion
  170. //
  171. // All we have to do is declare this puppy and CCDllGetVersion does the rest
  172. //
  173. DLLVER_SINGLEBINARY(VER_PRODUCTVERSION_DW, VER_PRODUCTBUILD_QFE);