404 lines
11 KiB
C++
404 lines
11 KiB
C++
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/* File: dskquota.cpp
|
||
|
|
||
|
Description: Contains standard functions for an OLE component server DLL.
|
||
|
|
||
|
DllMain
|
||
|
DllGetClassObject
|
||
|
DllCanUnloadNow
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
Date Description Programmer
|
||
|
-------- --------------------------------------------------- ----------
|
||
|
05/22/96 Initial creation. BrianAu
|
||
|
12/10/96 Moved to free-threading OLE apartment model. BrianAu
|
||
|
*/
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
#include "pch.h" // PCH
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#define INITGUIDS // Define GUIDs.
|
||
|
#include "dskquota.h"
|
||
|
#include "guidsp.h" // Private GUIDs.
|
||
|
#include <gpedit.h> // For GUIDs.
|
||
|
|
||
|
#include "factory.h" // Class factory declarations.
|
||
|
#include "sidcache.h" // SID/Name cache.
|
||
|
#include "registry.h"
|
||
|
//
|
||
|
// Verify that build is UNICODE.
|
||
|
//
|
||
|
#if !defined(UNICODE)
|
||
|
# error This module must be compiled UNICODE.
|
||
|
#endif
|
||
|
|
||
|
|
||
|
HINSTANCE g_hInstDll = NULL; // DLL instance handle.
|
||
|
LONG g_cRefThisDll = 0; // DLL reference count.
|
||
|
LONG g_cLockThisDll = 0; // DLL lock count.
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/* Function: DllGetClassObject
|
||
|
|
||
|
Description: Creates instance of DiskQuotaControlClassFactory.
|
||
|
|
||
|
Arguments:
|
||
|
rclsid - Reference to class ID that identifies the type of object that the
|
||
|
class factory will be asked to create.
|
||
|
|
||
|
riid - Reference to interface ID on the class factory object.
|
||
|
|
||
|
ppvOut - Destination location for class factory object pointer after
|
||
|
instantiation.
|
||
|
|
||
|
Returns:
|
||
|
NOERROR - Success.
|
||
|
E_OUTOFMEMORY - Can't create class factory object.
|
||
|
E_NOINTERFACE - Interface not supported.
|
||
|
E_INVALIDARG - ppvOut arg is NULL.
|
||
|
CLASS_E_CLASSNOTAVAILABLE - Class factory not available.
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
Date Description Programmer
|
||
|
-------- --------------------------------------------------- ----------
|
||
|
05/22/96 Initial creation. BrianAu
|
||
|
*/
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
STDAPI
|
||
|
DllGetClassObject(
|
||
|
REFCLSID rclsid,
|
||
|
REFIID riid,
|
||
|
LPVOID *ppvOut
|
||
|
)
|
||
|
{
|
||
|
DBGTRACE((DM_COM, DL_HIGH, TEXT("DllGetClassObject")));
|
||
|
DBGPRINTIID(DM_COM, DL_HIGH, (REFIID)rclsid);
|
||
|
DBGPRINTIID(DM_COM, DL_HIGH, riid);
|
||
|
|
||
|
HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
|
||
|
|
||
|
if (NULL == ppvOut)
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
*ppvOut = NULL;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
if (IsEqualIID(rclsid, CLSID_DiskQuotaControl))
|
||
|
{
|
||
|
DiskQuotaControlClassFactory *pClassFactory = NULL;
|
||
|
|
||
|
pClassFactory = new DiskQuotaControlClassFactory;
|
||
|
hr = pClassFactory->QueryInterface(riid, ppvOut);
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
delete pClassFactory;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
catch(CAllocException& e)
|
||
|
{
|
||
|
DBGERROR((TEXT("Insufficient memory exception")));
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/* Function: DllCanUnloadNow
|
||
|
|
||
|
Description: Called by OLE to determine if DLL can be unloaded.
|
||
|
|
||
|
Arguments: None.
|
||
|
|
||
|
Returns:
|
||
|
S_FALSE - Can't unload. Ref count or lock count are > 0.
|
||
|
S_OK - OK to unload. Ref count and lock count are 0.
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
Date Description Programmer
|
||
|
-------- --------------------------------------------------- ----------
|
||
|
05/22/96 Initial creation. BrianAu
|
||
|
*/
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
STDAPI
|
||
|
DllCanUnloadNow(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
DBGTRACE((DM_COM, DL_HIGH, TEXT("DllCanUnloadNow")));
|
||
|
DBGPRINT((DM_COM, DL_HIGH, TEXT("\tRefCnt = %d LockCnt = %d"),
|
||
|
g_cRefThisDll, g_cLockThisDll));
|
||
|
|
||
|
#ifdef DEBUG_PROCESS_DETACH
|
||
|
//
|
||
|
// This code will force the DLL to be unloaded so that we can
|
||
|
// test OnProcessDetach(). Otherwise, OLE will wait 10 minutes
|
||
|
// after DllCanUnloadNow returns S_OK to call FreeLibrary.
|
||
|
// Note however that the process will AV when OLE finally gets
|
||
|
// around to freeing the library. Therefore, we don't leave
|
||
|
// this code active in free or check builds; only private debug
|
||
|
// builds. Must explicitly define DEBUG_PROCESS_DETACH.
|
||
|
//
|
||
|
if (0 == g_cRefThisDll && 0 == g_cLockThisDll)
|
||
|
{
|
||
|
HINSTANCE hMod;
|
||
|
static INT iExeThisPath = 0;
|
||
|
|
||
|
if (0 == iExeThisPath++)
|
||
|
{
|
||
|
hMod = LoadLibrary(TEXT("dskquota.dll"));
|
||
|
if (NULL != hMod)
|
||
|
{
|
||
|
DBGASSERT((g_hInstDll == hMod));
|
||
|
FreeLibrary(hMod);
|
||
|
FreeLibrary(hMod);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif // DEBUG_PROCESS_DETACH
|
||
|
|
||
|
return (0 == g_cRefThisDll && 0 == g_cLockThisDll) ? S_OK : S_FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/* Function: DllRegisterServer
|
||
|
|
||
|
Description: Create the necessary registry entries for dskquota.dll
|
||
|
to operate properly. This is called by REGSVR32.EXE.
|
||
|
|
||
|
Arguments: None.
|
||
|
|
||
|
Returns:
|
||
|
S_OK - Succeeded.
|
||
|
SELFREG_E_CLASS - Failed to create one of the registry entries.
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
Date Description Programmer
|
||
|
-------- --------------------------------------------------- ----------
|
||
|
08/18/97 Initial creation. BrianAu
|
||
|
*/
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
DllRegisterServer(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
DBGTRACE((DM_COM, DL_HIGH, TEXT("DllRegisterServer")));
|
||
|
HRESULT hr = CallRegInstall(g_hInstDll, "RegDll");
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
hr = SELFREG_E_CLASS;
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/* Function: DllUnregisterServer
|
||
|
|
||
|
Description: Remove the necessary registry entries for dskquota.dll.
|
||
|
This is called by REGSVR32.EXE.
|
||
|
|
||
|
Arguments: None.
|
||
|
|
||
|
Returns:
|
||
|
S_OK - Succeeded.
|
||
|
SELFREG_E_CLASS - Failed to remove the CLSID entry.
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
Date Description Programmer
|
||
|
-------- --------------------------------------------------- ----------
|
||
|
08/18/97 Initial creation. BrianAu
|
||
|
*/
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
DllUnregisterServer(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
DBGTRACE((DM_COM, DL_HIGH, TEXT("DllUnregisterServer")));
|
||
|
HRESULT hr = CallRegInstall(g_hInstDll, "UnregDll");
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
hr = SELFREG_E_CLASS;
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/* Function: OnProcessAttach
|
||
|
|
||
|
Description: Handles all tasks associated with a process attaching to
|
||
|
the DLL.
|
||
|
|
||
|
Try to keep processing time to a minimum.
|
||
|
|
||
|
Arguments:
|
||
|
hInstDll - The DLL instance handle passed to DllMain.
|
||
|
|
||
|
Returns:
|
||
|
NOERROR - Success.
|
||
|
E_FAIL - Something failed.
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
Date Description Programmer
|
||
|
-------- --------------------------------------------------- ----------
|
||
|
08/09/96 Initial creation. BrianAu
|
||
|
*/
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
OnProcessAttach(
|
||
|
HINSTANCE hInstDll
|
||
|
)
|
||
|
{
|
||
|
DBGTRACE((DM_COM, DL_HIGH, TEXT("OnProcessAttach")));
|
||
|
HRESULT hr = NOERROR;
|
||
|
|
||
|
//
|
||
|
// Start IceCAP profiling.
|
||
|
//
|
||
|
ICAP_START_ALL;
|
||
|
|
||
|
#if DBG
|
||
|
DBGMODULE(TEXT("DSKQUOTA")); // Name of module displayed with messages.
|
||
|
RegKey key(HKEY_LOCAL_MACHINE, REGSTR_KEY_DISKQUOTA);
|
||
|
if (SUCCEEDED(key.Open(KEY_READ)))
|
||
|
{
|
||
|
DebugRegParams dp;
|
||
|
if (SUCCEEDED(key.GetValue(REGSTR_VAL_DEBUGPARAMS, (LPBYTE)&dp, sizeof(dp))))
|
||
|
{
|
||
|
DBGPRINTMASK(dp.PrintMask);
|
||
|
DBGPRINTLEVEL(dp.PrintLevel);
|
||
|
DBGPRINTVERBOSE(dp.PrintVerbose);
|
||
|
DBGTRACEMASK(dp.TraceMask);
|
||
|
DBGTRACELEVEL(dp.TraceLevel);
|
||
|
DBGTRACEVERBOSE(dp.TraceVerbose);
|
||
|
DBGTRACEONEXIT(dp.TraceOnExit);
|
||
|
}
|
||
|
}
|
||
|
#endif // DBG
|
||
|
|
||
|
g_hInstDll = hInstDll;
|
||
|
DisableThreadLibraryCalls(hInstDll);
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/* Function: OnProcessDetach
|
||
|
|
||
|
Description: Handles all tasks associated with a process detaching from
|
||
|
the DLL.
|
||
|
|
||
|
Arguments: None.
|
||
|
|
||
|
Returns:
|
||
|
NOERROR - Success.
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
Date Description Programmer
|
||
|
-------- --------------------------------------------------- ----------
|
||
|
08/09/96 Initial creation. BrianAu
|
||
|
*/
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT
|
||
|
OnProcessDetach(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
DBGTRACE((DM_COM, DL_HIGH, TEXT("OnProcessAttach")));
|
||
|
|
||
|
HRESULT hr = NOERROR;
|
||
|
|
||
|
#ifdef DEBUG_PROCESS_DETACH
|
||
|
LoadLibrary(TEXT("dskquota.dll"));
|
||
|
#endif
|
||
|
|
||
|
SidNameCache_Destroy();
|
||
|
|
||
|
//
|
||
|
// Stop IceCAP profiling.
|
||
|
//
|
||
|
ICAP_STOP_ALL;
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/* Function: DllMain
|
||
|
|
||
|
Description: Main entry point for OLE component server.
|
||
|
|
||
|
Arguments:
|
||
|
hInstDll - Instance handle of DLL
|
||
|
|
||
|
fdwReason - Reason DllMain is being called. Can be at Process attach/
|
||
|
detach or Thread attach/detach.
|
||
|
|
||
|
lpdwReserved - Reserved.
|
||
|
|
||
|
Returns:
|
||
|
TRUE - Successful initialization.
|
||
|
FALSE - Failed initialization.
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
Date Description Programmer
|
||
|
-------- --------------------------------------------------- ----------
|
||
|
05/22/96 Initial creation. BrianAu
|
||
|
08/09/96 Moved code associated with process attach and BrianAu
|
||
|
detach out to separate functions.
|
||
|
*/
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL WINAPI
|
||
|
DllMain(
|
||
|
HINSTANCE hInstDll,
|
||
|
DWORD fdwReason,
|
||
|
LPVOID lpvReserved
|
||
|
)
|
||
|
{
|
||
|
DBGTRACE((DM_COM, DL_HIGH, TEXT("DllMain")));
|
||
|
BOOL bResult = FALSE;
|
||
|
|
||
|
switch(fdwReason)
|
||
|
{
|
||
|
case DLL_PROCESS_ATTACH:
|
||
|
DBGPRINT((DM_COM, DL_HIGH, TEXT("DLL_PROCESS_ATTACH")));
|
||
|
bResult = SUCCEEDED(OnProcessAttach(hInstDll));
|
||
|
break;
|
||
|
|
||
|
case DLL_THREAD_ATTACH:
|
||
|
case DLL_THREAD_DETACH:
|
||
|
bResult = TRUE;
|
||
|
break;
|
||
|
|
||
|
case DLL_PROCESS_DETACH:
|
||
|
DBGPRINT((DM_COM, DL_HIGH, TEXT("DLL_PROCESS_DETACH")));
|
||
|
bResult = SUCCEEDED(OnProcessDetach());
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return bResult;
|
||
|
}
|
||
|
|