|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 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; }
|