Leaked source code of windows server 2003
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.

163 lines
4.1 KiB

  1. /*****************************************************************************\
  2. FILE: dllmain.cpp
  3. DESCRIPTION:
  4. This file will take care of the DLL lifetime.
  5. BryanSt 4/4/2000 (Bryan Starbuck)
  6. Copyright (C) Microsoft Corp 2000-2000. All rights reserved.
  7. \*****************************************************************************/
  8. #include "priv.h"
  9. extern HANDLE g_hLogFile;
  10. /*****************************************************************************
  11. *
  12. * Dynamic Globals. There should be as few of these as possible.
  13. *
  14. * All access to dynamic globals must be thread-safe.
  15. *
  16. *****************************************************************************/
  17. ULONG g_cRef = 0; // Global reference count
  18. CRITICAL_SECTION g_csDll; // The shared critical section
  19. #ifdef DEBUG
  20. DWORD g_TlsMem = 0xffffffff;
  21. #endif // DEBUG
  22. CComModule _Module;
  23. BEGIN_OBJECT_MAP(ObjectMap)
  24. END_OBJECT_MAP()
  25. /*****************************************************************************
  26. *
  27. * DllAddRef / DllRelease
  28. *
  29. * Maintain the DLL reference count.
  30. *
  31. *****************************************************************************/
  32. void DllAddRef(void)
  33. {
  34. InterlockedIncrement((LPLONG)&g_cRef);
  35. }
  36. void DllRelease(void)
  37. {
  38. ASSERT( 0 != g_cRef );
  39. InterlockedDecrement((LPLONG)&g_cRef);
  40. }
  41. /*****************************************************************************
  42. *
  43. * DllGetClassObject
  44. *
  45. * OLE entry point. Produces an IClassFactory for the indicated GUID.
  46. *
  47. * The artificial refcount inside DllGetClassObject helps to
  48. * avoid the race condition described in DllCanUnloadNow. It's
  49. * not perfect, but it makes the race window much smaller.
  50. *
  51. *****************************************************************************/
  52. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID * ppvObj)
  53. {
  54. HRESULT hres;
  55. DllAddRef();
  56. hres = CClassFactory_Create(rclsid, riid, ppvObj);
  57. DllRelease();
  58. return hres;
  59. }
  60. /*****************************************************************************
  61. *
  62. * DllCanUnloadNow
  63. *
  64. * OLE entry point. Fail iff there are outstanding refs.
  65. *
  66. * There is an unavoidable race condition between DllCanUnloadNow
  67. * and the creation of a new IClassFactory: Between the time we
  68. * return from DllCanUnloadNow() and the caller inspects the value,
  69. * another thread in the same process may decide to call
  70. * DllGetClassObject, thus suddenly creating an object in this DLL
  71. * when there previously was none.
  72. *
  73. * It is the caller's responsibility to prepare for this possibility;
  74. * there is nothing we can do about it.
  75. *
  76. *****************************************************************************/
  77. STDMETHODIMP DllCanUnloadNow(void)
  78. {
  79. HRESULT hres;
  80. ENTERCRITICAL;
  81. hres = g_cRef ? S_FALSE : S_OK;
  82. if (S_OK == hres)
  83. {
  84. hres = (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
  85. }
  86. TraceMsg(TF_WMTHEME, "DllCanUnloadNow() returning hres=%#08lx. (S_OK means yes)", hres);
  87. LEAVECRITICAL;
  88. return hres;
  89. }
  90. /*****************************************************************************
  91. *
  92. * Entry32
  93. *
  94. * DLL entry point.
  95. *
  96. *****************************************************************************/
  97. STDAPI_(BOOL) DllEntry(HINSTANCE hinst, DWORD dwReason, LPVOID lpReserved)
  98. {
  99. static s_hresOle = E_FAIL;
  100. switch (dwReason)
  101. {
  102. case DLL_PROCESS_ATTACH:
  103. {
  104. #ifdef DEBUG
  105. CcshellGetDebugFlags();
  106. #endif
  107. InitializeCriticalSection(&g_csDll);
  108. g_hinst = hinst;
  109. DisableThreadLibraryCalls(hinst);
  110. SHFusionInitializeFromModuleID(hinst, 124);
  111. break;
  112. }
  113. case DLL_PROCESS_DETACH:
  114. {
  115. DeleteCriticalSection(&g_csDll);
  116. if (INVALID_HANDLE_VALUE != g_hLogFile)
  117. {
  118. CloseHandle(g_hLogFile);
  119. }
  120. SHFusionUninitialize();
  121. break;
  122. }
  123. }
  124. return 1;
  125. }