|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1993 - 1999.
//
// File: DllMain.cpp
//
// Contents: DllMain routines
//
//----------------------------------------------------------------------------
#include "priv.h"
#define DECL_CRTFREE
#include <crtfree.h>
// dll refrence count;
LONG g_cRef = 0;
// global hinstance
HINSTANCE g_hinst = 0;
extern HMODULE g_hmodNTShrUI; // cuser.cpp
//
// DllAddRef increment dll refrence count
//
void DllAddRef(void) { InterlockedIncrement(&g_cRef); }
//
// DllRelease decrement dll refrence count
//
void DllRelease(void) { LONG lRet; lRet = InterlockedDecrement(&g_cRef); ASSERT(lRet >= 0);
if (0 == lRet) { HMODULE hmod = (HMODULE)InterlockedExchangePointer((PVOID*)&g_hmodNTShrUI, NULL); if (NULL != hmod) { FreeLibrary(hmod); } } }
//
// DllGetClassObject
//
// OLE entry point. Produces an IClassFactory for the indicated GUID.
//
// The artificial refcount inside DllGetClassObject helps to
// avoid the race condition described in DllCanUnloadNow. It's
// not perfect, but it makes the race window much smaller.
//
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppvObj) { HRESULT hr;
DllAddRef(); if (IsEqualIID(rclsid, CLSID_ShellLogonEnumUsers) || IsEqualIID(rclsid, CLSID_ShellLogonUser) || IsEqualIID(rclsid, CLSID_ShellLocalMachine) || IsEqualIID(rclsid, CLSID_ShellLogonStatusHost)) //IsEqualIID(rclsid, CLSID_ShellLogonUserEnumNotifications) ||
//IsEqualIID(rclsid, CLSID_ShellLogonUserNotification))
{ hr = CSHGinaFactory_Create(rclsid, riid, ppvObj); } else { *ppvObj = NULL; hr = CLASS_E_CLASSNOTAVAILABLE; }
DllRelease(); return hr; }
//
// DllCanUnloadNow
//
// OLE entry point. Fail iff there are outstanding refs.
//
// There is an unavoidable race condition between DllCanUnloadNow
// and the creation of a new IClassFactory: Between the time we
// return from DllCanUnloadNow() and the caller inspects the value,
// another thread in the same process may decide to call
// DllGetClassObject, thus suddenly creating an object in this DLL
// when there previously was none.
//
// It is the caller's responsibility to prepare for this possibility;
// there is nothing we can do about it.
//
STDMETHODIMP DllCanUnloadNow() { HRESULT hr;
if (g_cRef == 0) { // refcount is zero, ok to unload
hr = S_OK; } else { // still cocreated objects, dont unload
hr = S_FALSE; }
return hr; }
#define OLD_USERS_AND_PASSWORD TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace\\{7A9D77BD-5403-11d2-8785-2E0420524153}")
//
// DllMain (attach/deatch) routine
//
STDAPI_(BOOL) DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID lpReserved) { UNREFERENCED_PARAMETER(lpReserved);
switch (dwReason) { case DLL_PROCESS_ATTACH:
// HACKHACK (phellyar) Delete this registry key everytime we're loaded
// to prevent the old users and password cpl from appearing in the
// control panel. Since we're loaded by the welcome screen, we'll
// be able to delete this key before a user ever gets a chance to open
// the control panel, thereby ensuring the old cpl doesn't appear.
RegDeleteKey(HKEY_LOCAL_MACHINE, OLD_USERS_AND_PASSWORD); // Don't put it under #ifdef DEBUG
CcshellGetDebugFlags(); DisableThreadLibraryCalls(hinst); g_hinst = hinst; break;
case DLL_PROCESS_DETACH: { ASSERTMSG(g_cRef == 0, "Dll ref count is not zero: g_cRef = %d", g_cRef); break; } }
return TRUE; }
|