157 lines
3.9 KiB
C++
157 lines
3.9 KiB
C++
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// 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;
|
||
|
}
|