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.

156 lines
3.9 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1993 - 1999.
  5. //
  6. // File: DllMain.cpp
  7. //
  8. // Contents: DllMain routines
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "priv.h"
  12. #define DECL_CRTFREE
  13. #include <crtfree.h>
  14. // dll refrence count;
  15. LONG g_cRef = 0;
  16. // global hinstance
  17. HINSTANCE g_hinst = 0;
  18. extern HMODULE g_hmodNTShrUI; // cuser.cpp
  19. //
  20. // DllAddRef increment dll refrence count
  21. //
  22. void DllAddRef(void)
  23. {
  24. InterlockedIncrement(&g_cRef);
  25. }
  26. //
  27. // DllRelease decrement dll refrence count
  28. //
  29. void DllRelease(void)
  30. {
  31. LONG lRet;
  32. lRet = InterlockedDecrement(&g_cRef);
  33. ASSERT(lRet >= 0);
  34. if (0 == lRet)
  35. {
  36. HMODULE hmod = (HMODULE)InterlockedExchangePointer((PVOID*)&g_hmodNTShrUI, NULL);
  37. if (NULL != hmod)
  38. {
  39. FreeLibrary(hmod);
  40. }
  41. }
  42. }
  43. //
  44. // DllGetClassObject
  45. //
  46. // OLE entry point. Produces an IClassFactory for the indicated GUID.
  47. //
  48. // The artificial refcount inside DllGetClassObject helps to
  49. // avoid the race condition described in DllCanUnloadNow. It's
  50. // not perfect, but it makes the race window much smaller.
  51. //
  52. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppvObj)
  53. {
  54. HRESULT hr;
  55. DllAddRef();
  56. if (IsEqualIID(rclsid, CLSID_ShellLogonEnumUsers) ||
  57. IsEqualIID(rclsid, CLSID_ShellLogonUser) ||
  58. IsEqualIID(rclsid, CLSID_ShellLocalMachine) ||
  59. IsEqualIID(rclsid, CLSID_ShellLogonStatusHost))
  60. //IsEqualIID(rclsid, CLSID_ShellLogonUserEnumNotifications) ||
  61. //IsEqualIID(rclsid, CLSID_ShellLogonUserNotification))
  62. {
  63. hr = CSHGinaFactory_Create(rclsid, riid, ppvObj);
  64. }
  65. else
  66. {
  67. *ppvObj = NULL;
  68. hr = CLASS_E_CLASSNOTAVAILABLE;
  69. }
  70. DllRelease();
  71. return hr;
  72. }
  73. //
  74. // DllCanUnloadNow
  75. //
  76. // OLE entry point. Fail iff there are outstanding refs.
  77. //
  78. // There is an unavoidable race condition between DllCanUnloadNow
  79. // and the creation of a new IClassFactory: Between the time we
  80. // return from DllCanUnloadNow() and the caller inspects the value,
  81. // another thread in the same process may decide to call
  82. // DllGetClassObject, thus suddenly creating an object in this DLL
  83. // when there previously was none.
  84. //
  85. // It is the caller's responsibility to prepare for this possibility;
  86. // there is nothing we can do about it.
  87. //
  88. STDMETHODIMP DllCanUnloadNow()
  89. {
  90. HRESULT hr;
  91. if (g_cRef == 0)
  92. {
  93. // refcount is zero, ok to unload
  94. hr = S_OK;
  95. }
  96. else
  97. {
  98. // still cocreated objects, dont unload
  99. hr = S_FALSE;
  100. }
  101. return hr;
  102. }
  103. #define OLD_USERS_AND_PASSWORD TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace\\{7A9D77BD-5403-11d2-8785-2E0420524153}")
  104. //
  105. // DllMain (attach/deatch) routine
  106. //
  107. STDAPI_(BOOL) DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID lpReserved)
  108. {
  109. UNREFERENCED_PARAMETER(lpReserved);
  110. switch (dwReason)
  111. {
  112. case DLL_PROCESS_ATTACH:
  113. // HACKHACK (phellyar) Delete this registry key everytime we're loaded
  114. // to prevent the old users and password cpl from appearing in the
  115. // control panel. Since we're loaded by the welcome screen, we'll
  116. // be able to delete this key before a user ever gets a chance to open
  117. // the control panel, thereby ensuring the old cpl doesn't appear.
  118. RegDeleteKey(HKEY_LOCAL_MACHINE, OLD_USERS_AND_PASSWORD);
  119. // Don't put it under #ifdef DEBUG
  120. CcshellGetDebugFlags();
  121. DisableThreadLibraryCalls(hinst);
  122. g_hinst = hinst;
  123. break;
  124. case DLL_PROCESS_DETACH:
  125. {
  126. ASSERTMSG(g_cRef == 0, "Dll ref count is not zero: g_cRef = %d", g_cRef);
  127. break;
  128. }
  129. }
  130. return TRUE;
  131. }