WindowsXP-SP1/shell/ext/shgina/dllmain.cpp
2020-09-30 16:53:49 +02:00

157 lines
4.1 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;
}