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

429 lines
15 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.
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//===============================================================================
// Don't include everything from windows.h, but always bring in OLE 2 support
//===============================================================================
//#define WIN32_LEAN_AND_MEAN
#define INC_OLE2
//===============================================================================
// 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"
#include <cguid.h>
//===============================================================================
// Common project stuff
//===============================================================================
#include "headers.h"
#include "classfac.h"
#include "binderclassfac.h"
#include "binder.h"
#include "schema.h"
#include "enumerat.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Constructor for this class
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
CClassFactory::CClassFactory( void )
{
m_cRef = 0;
//================================================================
// Increment global object count
//================================================================
InterlockedIncrement(&g_cObj);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Destructor for this class
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
CClassFactory:: ~CClassFactory( 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 CClassFactory::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");
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Increments a persistence count for the object
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_( ULONG ) CClassFactory::AddRef( void )
{
HRESULT hr = S_OK;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
hr = InterlockedIncrement((long*)&m_cRef);
CATCH_BLOCK_HRESULT(hr,L"IClassFactory::AddRef");
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Decrements a persistence count for the object and if persistence count is 0,the object destroys itself.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_( ULONG ) CClassFactory::Release( void )
{
HRESULT hr = S_OK;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
if (!InterlockedDecrement((long*)&m_cRef)){
delete this;
return 0;
}
CATCH_BLOCK_HRESULT(hr,L"IClassFactory::Release");
return m_cRef;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 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 CClassFactory::LockServer ( BOOL fLock ) // IN TRUE or FALSE to lock or unlock
{
HRESULT hr = S_OK;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
if (fLock)
{
InterlockedIncrement( &g_cLock );
}
else
{
InterlockedDecrement( &g_cLock );
}
CATCH_BLOCK_HRESULT(hr,L"IClassFactory::LockServer");
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// CDataSourceClassFactory
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CDataSourceClassFactory::CreateInstance( LPUNKNOWN pUnkOuter, REFIID riid, LPVOID * ppvObj )
{
PCDATASOURCE 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
{
pObj = new CDataSource( pUnkOuter );
}
catch(...)
{
SAFE_DELETE_PTR(pObj);
throw;
}
//==========================================================
// Create a CDataSource object
//==========================================================
if ((pObj != NULL)){
//======================================================
// Initialize it
//======================================================
if (SUCCEEDED(hr = pObj->FInit())){
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 Datasource");
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// CEnumeratorClassFactory
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CEnumeratorClassFactory::CreateInstance( LPUNKNOWN pUnkOuter, REFIID riid, LPVOID * ppvObj )
{
CEnumeratorNameSpace* 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 CEnumeratorNameSpace(pUnkOuter);
}
catch(...)
{
SAFE_DELETE_PTR(pObj);
throw;
}
if (pObj != NULL ){
//======================================================
// Initialize it
//======================================================
hr = pObj->Initialize();
if( S_OK == hr ){
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 Enumerator");
return hr;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Creates an uninitialized instance of an object class.
//
///////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CErrorLookupClassFactory::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
{
PCERRORLOOKUP pObj = NULL;
HRESULT hr;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
//============================================================================
// Check for valid ppvObj pointer
//============================================================================
if (ppvObj == NULL){
ERRORTRACE((THISPROVIDER,"CErrorLookupClassFactory::CreateInstance invalid argument "));
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, the 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 ){
ERRORTRACE((THISPROVIDER,"CErrorLookupClassFactory::CreateInstance no aggregation "));
hr = CLASS_E_NOAGGREGATION;
}
else
{
hr = E_OUTOFMEMORY;
try
{
//============================================================================
// Create a CErrorLookup object
//============================================================================
pObj = new CErrorLookup(pUnkOuter);
}
catch(...)
{
SAFE_DELETE_PTR(pObj);
throw;
}
if( pObj != NULL)
{
hr = pObj->QueryInterface(riid, ppvObj);
if( FAILED(hr) ){
delete pObj;
ERRORTRACE((THISPROVIDER,"ClassFactory::CreateInstance failed in call to CError::QueryInterface."));
}
}
}
}
CATCH_BLOCK_HRESULT(hr,L"IClassFactory::CreateInstance for ErrorLookup");
return hr;
}