⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cenum.cpp

📁 用测试OLE DB提供者的一个程序。能够测试出OEL DB提供者到底实现了哪些接口?很灵的。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
// Microsoft OLE DB RowsetViewer
// Copyright (C) 1994 - 1998 By Microsoft Corporation.
//
// @doc
//
// @module CENUM.CPP
//
//-----------------------------------------------------------------------------------

/////////////////////////////////////////////////////////////////
// Includes
//
/////////////////////////////////////////////////////////////////
#include "Common.h"
#include "CEnum.h"
#include "CDialog.h"	//CListBox
#include "Main.h"
#include "msdaguid.h"	//CLSID_OLEDB_ENUMERATOR


/////////////////////////////////////////////////////////////////
// CEnum::CEnum
//
/////////////////////////////////////////////////////////////////
CEnum::CEnum(HWND hWnd, CMainWindow* pCMainWindow, CListBox* pCListBox)
{
	ASSERT(pCMainWindow);
	m_pCMainWindow = pCMainWindow;
	ASSERT(pCListBox);
	m_pCListBox = pCListBox;
	
	//Enumerator ProvierInfo
	m_cEnumInfo				= 0;	
	m_rgEnumInfo			= NULL;
	m_pIParseDisplayName	= NULL; //Enumerator
	m_hWnd					= NULL;
}

/////////////////////////////////////////////////////////////////
// CEnum::~CEnum
//
/////////////////////////////////////////////////////////////////
CEnum::~CEnum()
{
	//Enumerator ProviderInfo
	m_cEnumInfo			= 0;	
	SAFE_FREE(m_rgEnumInfo);
	SAFE_RELEASE(m_pIParseDisplayName);
}


/////////////////////////////////////////////////////////////////
// BOOL CEnum::GetEnumInfo
//
/////////////////////////////////////////////////////////////////
ENUMINFO* CEnum::GetEnumInfo()
{
	ASSERT(m_rgEnumInfo);
	return m_rgEnumInfo;
}


/////////////////////////////////////////////////////////////////
// BOOL CEnum::GetEnumInfo
//
/////////////////////////////////////////////////////////////////
ENUMINFO* CEnum::GetEnumInfo(ULONG iIndex)
{
	ASSERT(m_rgEnumInfo);
	ASSERT(iIndex < m_cEnumInfo);
	return &m_rgEnumInfo[iIndex];
}


/////////////////////////////////////////////////////////////////////////////
// HRESULT CEnum::CreateProvider
//
/////////////////////////////////////////////////////////////////////////////
HRESULT CEnum::CreateProvider(IParseDisplayName* pIParseDisplayName, WCHAR* pwszParseName, DWORD dwCLSCTX, REFIID riid, IUnknown** ppIUnknown, DWORD dwConnectOpts, WCHAR* pwszRemoteServer)
{
	ASSERT(pwszParseName);
	ASSERT(ppIUnknown);

	IMoniker* pIMoniker = NULL;
	IBindCtx* pIBindCtx = NULL;
	ULONG chEaten = 0;
	CLSID clsid;
	HRESULT hr = E_FAIL;

	//If the user passes in a ParseDisplayName object, use that,
	//Otherwise use the Root Enum ParseDisplayName object...
	if(pIParseDisplayName == NULL)
		pIParseDisplayName = m_pIParseDisplayName;

	//Try and use ParseDisplayName
	//Otherwise we may be forced to just try CoCreateInstance if not installed...
	//Also cannot use ParseDisplayName if trying to aggregate ServiceComponents
	if(pIParseDisplayName && !(dwConnectOpts & CONNECT_USESERVICECOMP))
	{
		if(dwCLSCTX)
		{
			//Setup BIND_OPTS
			BIND_OPTS2 BindOps2;
			BindOps2.cbStruct		= sizeof(BIND_OPTS2);
			BindOps2.grfFlags		= BIND_MAYBOTHERUSER;
			BindOps2.grfMode		= STGM_READWRITE;
			BindOps2.dwTickCountDeadline = 0;
			BindOps2.dwTrackFlags	= 1;
			BindOps2.dwClassContext = dwCLSCTX;
			BindOps2.locale			= GetSystemDefaultLCID();
			BindOps2.pServerInfo	= NULL; 
			
			//Setup ServerInfo just incase we need it...
			COSERVERINFO	ServerInfo	= { 0, pwszRemoteServer, NULL, 0};
			MULTI_QI		MultiQI		= { &riid, NULL, S_OK};

			//Setup RemoteServer is specified
			if(dwCLSCTX & CLSCTX_REMOTE_SERVER)
				BindOps2.pServerInfo = &ServerInfo;

			//If this fails for some reason, we can still continue...
			hr = CreateBindCtx(0, &pIBindCtx);
			if(SUCCEEDED(hr) && pIBindCtx)
				hr = pIBindCtx->SetBindOptions(&BindOps2);

			//If it does fail we will just release the Bind Context and pass
			//IParseDisplayName NULL and let it choose the CLXCTX...
			if(FAILED(hr))
				SAFE_RELEASE(pIBindCtx);
		}
		
		//ParseDisplayName
		//Don't display error, since we have our own retry logic...
		TESTC(m_pCListBox->OutputPreMethod("IParseDisplayName::ParseDisplayName(0x%08x, %S, &%d, &0x%08x)", pIBindCtx, pwszParseName, chEaten, pIMoniker));
		hr = pIParseDisplayName->ParseDisplayName(pIBindCtx, pwszParseName, &chEaten, &pIMoniker);
		m_pCListBox->OutputPostMethod(hr, "IParseDisplayName::ParseDisplayName(0x%08x, %S, &%d, &0x%08x)", pIBindCtx, pwszParseName, chEaten, pIMoniker);
		
		if(SUCCEEDED(hr))
		{
			TESTC(m_pCListBox->OutputPreMethod("BindMoniker(0x%08x, 0, %s, &0x%08x)", pIBindCtx, GetInterfaceName(riid), ppIUnknown ? *ppIUnknown : NULL));
			XTEST(m_hWnd, hr = BindMoniker(pIMoniker, 0, riid, (void**)ppIUnknown));
			TESTC(m_pCListBox->OutputPostMethod(hr, "BindMoniker(0x%08x, 0, %s, &0x%08x)", pIBindCtx, GetInterfaceName(riid), ppIUnknown ? *ppIUnknown : NULL));
		}
	}
	
	//If Not using RootEnum or for some reason the RootEnum failed, 
	if(pIParseDisplayName == NULL || FAILED(hr))
	{
		//Find the CLSID from the ParseName
		//The user may have entered a ProgID or a CLSID 
		//Since the ParseName is a CLSID, try the common cvase first...
		if(FAILED(hr = CLSIDFromString(pwszParseName, &clsid)))
			XTESTC(m_hWnd, hr = CLSIDFromProgID(pwszParseName, &clsid));
				
		//Delegate
		TESTC(hr = CreateProvider(NULL, clsid, dwCLSCTX, riid, (IUnknown**)ppIUnknown, dwConnectOpts, pwszRemoteServer));
	}
	
CLEANUP:
	m_pCListBox->OutputRelease((IUnknown**)&pIMoniker, "IMoniker");
	SAFE_RELEASE(pIBindCtx);
	return hr;
}


/////////////////////////////////////////////////////////////////////////////
// HRESULT CEnum::CreateProvider
//
/////////////////////////////////////////////////////////////////////////////
HRESULT CEnum::CreateProvider(IUnknown* pIUnkOuter, CLSID clsid, DWORD dwCLSCTX, REFIID riid, IUnknown** ppIUnknown, DWORD dwConnectOpts, WCHAR* pwszRemoteServer)
{
	ASSERT(ppIUnknown);
	HRESULT hr = S_OK;

	//CLSID to String (just for display purposes...)
	WCHAR* pwszProgID = GetProgID(clsid);
	IDataInitialize* pIDataInitialize = NULL;

	//If using Service Components
	if(dwConnectOpts & CONNECT_USESERVICECOMP)
	{
		//CoCreateInstance on the ServiceComponents
		//We do this again here, incase you want Remoted Providers...
		XTESTC(m_hWnd, hr = CreateInstance(NULL, CLSID_MSDAINITIALIZE, dwCLSCTX, IID_IDataInitialize, (IUnknown**)&pIDataInitialize, pwszRemoteServer));

		//The provider is always "inproc" to whereever the ServiceComponents are:
		dwCLSCTX = CLSCTX_INPROC_SERVER;

		//Now Obtain Instance of Aggregated Provider
		m_pCListBox->OutputPreMethod("IDataInitialize::CreateDBInstance(%S, 0x%08x, %d, \"pwszReserved\", %s, &0x%08x)", pwszProgID, pIUnkOuter, dwCLSCTX, GetInterfaceName(riid), ppIUnknown ? *ppIUnknown : NULL);
		XTEST(m_hWnd, hr = pIDataInitialize->CreateDBInstance(clsid, pIUnkOuter, dwCLSCTX, L"pwszReserved", riid, ppIUnknown));
		m_pCListBox->OutputPostMethod(hr, "IDataInitialize::CreateDBInstance(%S, 0x%08x, %d, \"pwszReserved\", %s, &0x%08x)", pwszProgID, pIUnkOuter, dwCLSCTX, GetInterfaceName(riid), ppIUnknown ? *ppIUnknown : NULL);
	}
	else
	{
		//Delegate
		TESTC(hr = CreateInstance(pIUnkOuter, clsid, dwCLSCTX, riid, ppIUnknown, pwszRemoteServer));
	}
	
CLEANUP:
	SAFE_RELEASE(pIDataInitialize);
	SAFE_FREE(pwszProgID);
	return hr;
}

WINOLEAPI CoCreateInstanceEx(REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
/////////////////////////////////////////////////////////////////////////////
// HRESULT CEnum::CreateInstance
//
/////////////////////////////////////////////////////////////////////////////
HRESULT CEnum::CreateInstance(IUnknown* pIUnkOuter, CLSID clsid, DWORD dwCLSCTX, REFIID riid, IUnknown** ppIUnknown, WCHAR* pwszRemoteServer)
{
	ASSERT(ppIUnknown);
	HRESULT hr = S_OK;

	//CLSID to String (just for display purposes...)
	WCHAR* pwszProgID = GetProgID(clsid);

	//Determine which method to use...
	if(dwCLSCTX & CLSCTX_REMOTE_SERVER)
	{
		//Setup ServerInfo...
		COSERVERINFO	ServerInfo	= { 0, pwszRemoteServer, NULL, 0};
		MULTI_QI		MultiQI		= { &riid, NULL, S_OK};

		//CoCreateInstanceEx
		TESTC(m_pCListBox->OutputPreMethod("CoCreateInstanceEx(%S, 0x%08x, %d, &0x%08x, 1, &0x%08x)", pwszProgID, pIUnkOuter, dwCLSCTX, &ServerInfo, &MultiQI));
		XTEST(m_hWnd, hr = CoCreateInstanceEx(clsid, pIUnkOuter, dwCLSCTX, &ServerInfo, 1, &MultiQI));
		TESTC(m_pCListBox->OutputPostMethod(hr, "CoCreateInstanceEx(%S, 0x%08x, %d, &0x%08x, 1, &0x%08x)", pwszProgID, pIUnkOuter, dwCLSCTX, &ServerInfo, &MultiQI));
		
		//Output pointer from the MultiQI
		*ppIUnknown = MultiQI.pItf;
	}
	else
	{
		//CoCreateInstance

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -