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.

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