📄 cenum.cpp
字号:
//-----------------------------------------------------------------------------
// 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 + -