windows-nt/Source/XPSP1/NT/ds/security/services/scerpc/escprov/maindll.cpp
2020-09-26 16:20:57 +08:00

322 lines
6.9 KiB
C++

//***************************************************************************
//
// MAINDLL.CPP
//
// Module: SCE WMI provider code
//
// Purpose: Contains DLL entry points. Also has code that controls
// when the DLL can be unloaded by tracking the number of
// objects and locks as well as routines that support
// self registration.
//
// Copyright (c) 1999-2001 Microsoft Corporation
//
//***************************************************************************
#include <objbase.h>
#include <initguid.h>
#include "sceprov.h"
#include "scecore_i.c"
#include "sceparser.h"
#include "persistmgr.h"
#include "resource.h"
#ifdef _MERGE_PROXYSTUB
extern "C" HINSTANCE hProxyDll;
#endif
//
// this is the ATL wrapper for our module
//
CComModule _Module;
//
// this is the ATL object map. If you need to create another COM object that
// is externally createable, then you need to add an entry here. You don't need
// to mess with class factory stuff.
//
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_SceProv, CSceWmiProv)
OBJECT_ENTRY(CLSID_ScePathParser, CScePathParser)
OBJECT_ENTRY(CLSID_SceQueryParser, CSceQueryParser)
OBJECT_ENTRY(CLSID_ScePersistMgr, CScePersistMgr)
END_OBJECT_MAP()
LPCWSTR lpszSceProvMof = L"Wbem\\SceProv.mof";
/*
Routine Description:
Name:
DllMain
Functionality:
Entry point for DLL.
Arguments:
See DllMain on MSDN.
Return Value:
TRUE if OK.
Notes:
DllMain will be called for attach and detach. When other dlls are loaded, this function
will also get called. So, this is not necessary a good place for you to initialize some
globals unless you know precisely what you are doing. Please read MSDN for details before
you try to modify this function.
As a general design approach, we use gloal class instances to guarantee its creation and
destruction.
*/
extern "C"
BOOL WINAPI DllMain (
IN HINSTANCE hInstance,
IN ULONG ulReason,
LPVOID pvReserved
)
{
#ifdef _MERGE_PROXYSTUB
if (!PrxDllMain(hInstance, dwReason, lpReserved))
return FALSE;
#endif
if (ulReason == DLL_PROCESS_ATTACH)
{
OutputDebugString(L"SceProv.dll loaded.\n");
_Module.Init(ObjectMap, hInstance);
DisableThreadLibraryCalls(hInstance);
}
else if (ulReason == DLL_PROCESS_DETACH)
{
OutputDebugString(L"SceProv.dll unloaded.\n");
_Module.Term();
}
return TRUE;
}
/*
Routine Description:
Name:
DllGetClassObject
Functionality:
Retrieves the class object from a DLL object handler or object application.
DllGetClassObject is called from within the CoGetClassObject function when the
class context is a DLL.
As a benefit of using ATL, we just need to delegate this to our _Module object.
Arguments:
rclsid - Class ID (guid) for the class object being requested.
riid - Interface GUID that is being requested.
ppv - the interface pointer being returned if successful
Return Value:
Whatever GetClassObject returns for this class ID and its requested interface id.
Notes:
*/
STDAPI DllGetClassObject (
IN REFCLSID rclsid,
IN REFIID riid,
OUT PPVOID ppv
)
{
#ifdef _MERGE_PROXYSTUB
if (PrxDllGetClassObject(rclsid, riid, ppv) == S_OK)
return S_OK;
#endif
return _Module.GetClassObject(rclsid, riid, ppv);
}
/*
Routine Description:
Name:
DllCanUnloadNow
Functionality:
Called periodically by COM in order to determine if the DLL can be freed.
As a benefit of using ATL, we just need to delegate this to our _Module object.
Arguments:
None
Return Value:
S_OK if the dll can be unloaded. Otherwise, it returns S_FALSE;
Notes:
*/
STDAPI DllCanUnloadNow (void)
{
#ifdef _MERGE_PROXYSTUB
if (PrxDllCanUnloadNow() != S_OK)
return S_FALSE;
#endif
return (_Module.GetLockCount() == 0) ? S_OK : S_FALSE;
}
/*
Routine Description:
Name:
DllRegisterServer
Functionality:
(1) Called during dll registration.
As a benefit of using ATL, we just need to delegate this to our _Module object.
(2) Since we are a provider, we will also compile our MOF file(s).
Arguments:
None
Return Value:
Success: success code (use SUCCEEDED(hr) to test).
Failure: it returns various errors;
Notes:
*/
STDAPI DllRegisterServer(void)
{
#ifdef _MERGE_PROXYSTUB
HRESULT hRes = PrxDllRegisterServer();
if (FAILED(hRes))
return hRes;
#endif
HRESULT hr = _Module.RegisterServer(TRUE);
//
// now compile the MOF file. This is only our current approach. It is not
// required to compile the MOF file during DLL registration. Users can compile
// MOF file(s) indenpendently from dll registration
//
if (SUCCEEDED(hr))
{
const int WBEM_MOF_FILE_LEN = 30;
WCHAR szBuffer[MAX_PATH];
WCHAR szMofFile[MAX_PATH + WBEM_MOF_FILE_LEN];
szBuffer[0] = L'\0';
szMofFile[0] = L'\0';
if ( GetSystemDirectory( szBuffer, MAX_PATH ) ) {
LPWSTR sz = szBuffer + wcslen(szBuffer);
if ( sz != szBuffer && *(sz-1) != L'\\') {
*sz++ = L'\\';
*sz = L'\0';
}
hr = WBEM_NO_ERROR;
//
// this protects buffer overrun
//
if (wcslen(lpszSceProvMof) < WBEM_MOF_FILE_LEN)
{
wcscpy(szMofFile, szBuffer);
wcscat( szMofFile, lpszSceProvMof);
//
// we need COM to be ready
//
hr = ::CoInitialize (NULL);
if (SUCCEEDED(hr))
{
//
// Get the MOF compiler interface
//
CComPtr<IMofCompiler> srpMof;
hr = ::CoCreateInstance (CLSID_MofCompiler, NULL, CLSCTX_INPROC_SERVER, IID_IMofCompiler, (void **)&srpMof);
if (SUCCEEDED(hr))
{
WBEM_COMPILE_STATUS_INFO stat;
hr = srpMof->CompileFile( szMofFile,
NULL,NULL,NULL,NULL,
0,0,0, &stat);
}
::CoUninitialize();
}
}
}
}
return hr;
}
/*
Routine Description:
Name:
DllRegisterServer
Functionality:
(1) Called when it is time to remove the registry entries.
As a benefit of using ATL, we just need to delegate this to our _Module object.
Arguments:
None
Return Value:
Success: S_OK (same as NOERROR).
Failure: it returns various errors;
Notes:
There is no MOF unregistration. Otherwise, we should probably do a MOF unregistration
*/
STDAPI DllUnregisterServer(void)
{
#ifdef _MERGE_PROXYSTUB
PrxDllUnregisterServer();
#endif
_Module.UnregisterServer();
return S_OK;
}