windows-nt/Source/XPSP1/NT/admin/wmi/wbem/adapters/oledb/binderclassfac.cpp
2020-09-26 16:20:57 +08:00

297 lines
11 KiB
C++

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Microsoft WMI OLE DB Provider
// (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
//
// The module contains the DLL Entry and Exit points, plus the OLE ClassFactory class for RootBinder object.
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//#define DECLARE_GLOBALS
//===============================================================================
// Don't include everything from windows.h, but always bring in OLE 2 support
//===============================================================================
//#define WIN32_LEAN_AND_MEAN
#define INC_OLE2
//===============================================================================
// Make sure constants get initialized
//===============================================================================
#define INITGUID
#define DBINITCONSTANTS
//===============================================================================
// Basic Windows and OLE everything
//===============================================================================
#include <windows.h>
//===============================================================================
// OLE DB headers
//===============================================================================
#include "oledb.h"
#include "oledberr.h"
//===============================================================================
// Data conversion library header
//===============================================================================
#include "msdadc.h"
//===============================================================================
// Guids for data conversion library
//===============================================================================
#include "msdaguid.h"
//===============================================================================
// GUIDs
//===============================================================================
#include "guids.h"
//===============================================================================
// Common project stuff
//===============================================================================
#include "headers.h"
#include "binderclassfac.h"
//===============================================================================
// Globals
//===============================================================================
extern LONG g_cObj; // # of outstanding objects
extern LONG g_cLock; // # of explicit locks set
extern DWORD g_cAttachedProcesses; // # of attached processes
extern DWORD g_dwPageSize; // System page size
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Destructor for this class
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
CBinderClassFactory:: CBinderClassFactory( void )
{
m_cRef = 0;
//================================================================
// Decrement global object count
//================================================================
InterlockedIncrement(&g_cObj);
}
CBinderClassFactory:: ~CBinderClassFactory( void )
{
//================================================================
// Decrement global object count
//================================================================
InterlockedDecrement(&g_cObj);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Returns a pointer to a specified interface. Callers use QueryInterface to determine which interfaces
// the called object supports.
//
// HRESULT indicating the status of the method
// S_OK Interface is supported and ppvObject is set.
// E_NOINTERFACE Interface is not supported by the object
// E_INVALIDARG One or more arguments are invalid.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CBinderClassFactory::QueryInterface (
REFIID riid, // IN Interface ID of the interface being queried for.
LPVOID * ppvObj // OUT Pointer to interface that was instantiated
)
{
HRESULT hr = S_OK;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
//=================================================================
// Check for valid ppvObj pointer
//=================================================================
if (!ppvObj){
hr = E_INVALIDARG;
LogMessage("QueryInterface: Invalid argument pointer");
}
else{
//=================================================================
// In case we fail, we need to zero output arguments
//=================================================================
*ppvObj = NULL;
//=================================================================
// Do we support this interface?
//=================================================================
if (riid == IID_IUnknown || riid == IID_IClassFactory)
{
*ppvObj = (LPVOID) this;
}
//=================================================================
// If we're going to return an interface, AddRef it first
//=================================================================
if (*ppvObj){
((LPUNKNOWN) *ppvObj)->AddRef();
}
else{
hr = E_NOINTERFACE;
LogMessage("QueryInterface: No interface");
}
}
CATCH_BLOCK_HRESULT(hr,L"IClassFactory::QueryInterface for RootBinder");
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Increments a persistence count for the object
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_( ULONG ) CBinderClassFactory::AddRef( void )
{
HRESULT hr = S_OK;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
hr = InterlockedIncrement((long *)&m_cRef);
CATCH_BLOCK_HRESULT(hr,L"IClassFactory::AddRef for RootBinder");
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Decrements a persistence count for the object and if persistence count is 0,the object destroys itself.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_( ULONG ) CBinderClassFactory::Release( void )
{
HRESULT hr = S_OK;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
if (!InterlockedDecrement((long *)&m_cRef)){
delete this;
}
CATCH_BLOCK_HRESULT(hr,L"IClassFactory::Release for RootBinder");
return m_cRef;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Creates an uninitialized instance of an object class.Initialization is subsequently performed using
// another interface-specific method
//
// HRESULT indicating the status of the method
// S_OK Interface is supported and ppvObject is set.
// E_NOINTERFACE Interface is not supported by the object
// E_INVALIDARG One or more arguments are invalid.
// E_OUTOFMEMORY Memory could not be allocated
// OTHER Other HRESULTs returned by called functions
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CBinderClassFactory::CreateInstance (
LPUNKNOWN pUnkOuter, // IN Points to the controlling IUnknown interface
REFIID riid, // IN Interface ID of the interface being queried for.
LPVOID * ppvObj // OUT Pointer to interface that was instantiated
)
{
CBinder* pObj = NULL;
HRESULT hr = S_OK;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
//==============================================================
// Check for valid ppvObj pointer
//==============================================================
if (ppvObj == NULL){
LogMessage("CreateInstance: Invalid argument pointer");
hr = ( E_INVALIDARG );
}
else
{
//==============================================================
// In case we fail, we need to zero output arguments
//==============================================================
*ppvObj = NULL;
//==============================================================
// If we're given a controlling IUnknown, it must ask for
// IUnknown. Otherwise, caller will end up getting a pointer to
// their pUnkOuter instead of to the new object we create and
// will have no way of getting back to this new object, so they
// won't be able to free it. Bad!
//==============================================================
if (pUnkOuter && riid != IID_IUnknown){
hr = DB_E_NOAGGREGATION;
LogMessage("CreateInstance: No aggregation");
}
else{
//==========================================================
// Prepare for the possibility that there might be an error
//==========================================================
hr = E_OUTOFMEMORY;
try
{
//==========================================================
// Create a CBinder object
//==========================================================
pObj = new CBinder(pUnkOuter);
}
catch(...)
{
SAFE_DELETE_PTR(pObj);
throw;
}
if (pObj != NULL ){
//======================================================
// Initialize it
//======================================================
if (SUCCEEDED(hr = pObj->InitBinder())){
hr = pObj->QueryInterface( riid, ppvObj );
}
if (FAILED( hr )){
LogMessage("CreateInstance: Out of memory");
SAFE_DELETE_PTR( pObj );
}
}
}
}
CATCH_BLOCK_HRESULT(hr,L"IClassFactory::CreateInstance for RootBinder");
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Controls whether an object application is kept in memory. Keeping the application alive in memory
// allows instances of this class to be created more quickly.
//
// HRESULT indicating the status of the method
// S_OK Interface is supported and ppvObject is set.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CBinderClassFactory::LockServer ( BOOL fLock ) // IN TRUE or FALSE to lock or unlock
{
HRESULT hr = NOERROR;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
if (fLock)
{
InterlockedIncrement( &g_cLock );
}
else
{
InterlockedDecrement( &g_cLock );
}
CATCH_BLOCK_HRESULT(hr,L"IClassFactory::LockServer for RootBinder");
return hr;
}