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

347 lines
10 KiB
C++

///////////////////////////////////////////////////////////////////////////
//
// Microsoft WMIOLE DB Provider
//
// (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
//
// IBindResource.CPP CImplIBindResource interface implementation
//
///////////////////////////////////////////////////////////////////////////
#include "headers.h"
////////////////////////////////////////////////////////////////////////////////
// Method of the IBindResource which binds the requested URL
// Returns one of the following values:
// S_OK Bind succeeded
// DB_S_ERRORSOCCURRED Bind succeeded, but some bind flags
// or properties were not satisfied
// DB_E_NOAGGREGATION Aggregation not supported by the
// object requested
// DB_E_NOTFOUND Object requested as from URL not found
// DB_E_OBJECTMISMATCH The object requested and the URL passed
// does not match
// DB_SEC_E_PERMISSIONDENIED User does not have permission for the
// object requested
// E_FAIL Other error ( WMI specifice errors)
// E_INVALIDARG one or more arguments are not valid
// E_NOINTERFACE The interface requested is not supported
// E_UNEXPECTED unexpected error
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImplIBindResource::Bind( IUnknown * pUnkOuter,
LPCOLESTR pwszURL,
DBBINDURLFLAG dwBindURLFlags,
REFGUID rguid,
REFIID riid,
IAuthenticate * pAuthenticate,
DBIMPLICITSESSION * pImplSession,
DBBINDURLSTATUS * pdwBindStatus,
IUnknown ** ppUnk)
{
HRESULT hr = E_FAIL;
BSTR strUrl;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
// Serialize the object
CAutoBlock cab(BINDER->GetCriticalSection());
g_pCError->ClearErrorInfo();
// If URL is NULL return Invalid Argument
if(pwszURL == NULL)
{
hr = E_INVALIDARG;
}
else
{
// Allocate the string
strUrl = Wmioledb_SysAllocString(pwszURL);
// Check if the flags passed are valid for the object requested
if(!CheckBindURLFlags(dwBindURLFlags,rguid))
{
hr = E_INVALIDARG;
}
else
if(!CheckIfProperURL(strUrl,rguid,pdwBindStatus))
{
hr = DB_E_OBJECTMISMATCH;
}
else
if( pUnkOuter != NULL && riid != IID_IUnknown)
{
hr = DB_E_NOAGGREGATION;
}
else
{
// Calling this to bind the URL to the appropriate object
hr = BindURL(pUnkOuter,strUrl,dwBindURLFlags,rguid,riid,pImplSession,pdwBindStatus,ppUnk);
}
// Free the string
SysFreeString(strUrl);
}
hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IBindResource);
CATCH_BLOCK_HRESULT(hr,L"IBindResource::Bind");
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////
// Function which checks if the URL flags matches the requested object
// This is as per the OLEDB specs
///////////////////////////////////////////////////////////////////////////////////////////
BOOL CImplIBindResource::CheckBindURLFlags(DBBINDURLFLAG dwBindURLFlags , REFGUID rguid)
{
BOOL bFlag = FALSE;
LONG lTemp = 0;
if( DBGUID_DSO == rguid)
{
lTemp = DBBINDURLFLAG_ASYNCHRONOUS | DBBINDURLFLAG_READ | DBBINDURLFLAG_WAITFORINIT;
// Flags can have only these values
if((dwBindURLFlags & ~lTemp) == 0)
bFlag = TRUE;
}
if( DBGUID_SESSION == rguid)
{
if( dwBindURLFlags == DBBINDURLFLAG_READ) // Flags can have only these values
bFlag = TRUE;
}
if( DBGUID_COMMAND == rguid)
{
lTemp = DBBINDURLFLAG_READ | DBBINDURLFLAG_WAITFORINIT;
if((dwBindURLFlags & ~lTemp) == 0)
bFlag = TRUE;
}
if( DBGUID_ROW == rguid)
{
bFlag = TRUE;
}
if( DBGUID_ROWSET == rguid)
{
if(!((dwBindURLFlags & DBBINDURLFLAG_DELAYFETCHCOLUMNS) || // Flags cannot have any of these two values
(dwBindURLFlags & DBBINDURLFLAG_DELAYFETCHSTREAM)))
bFlag = TRUE;
}
if( DBGUID_STREAM == rguid)
{
}
return bFlag;
}
////////////////////////////////////////////////////////////////////////////////////////////
// Function which checks if the URL is valid for the requested object
///////////////////////////////////////////////////////////////////////////////////////////
BOOL CImplIBindResource::CheckIfProperURL(BSTR & strUrl,REFGUID rguid,DBBINDURLSTATUS * pdwBindStatus)
{
BOOL bRet = FALSE;
LONG lUrlType = -1;
m_pObj->m_pUrlParser->ClearParser();
//==================================================================
// Set the URL string of the URL parser utility class
//==================================================================
if(SUCCEEDED(m_pObj->m_pUrlParser->SetURL(strUrl)))
{
bRet = TRUE;
//==================================================================
// If the url is a valid URL
//==================================================================
if((lUrlType = m_pObj->m_pUrlParser->GetURLType()) != -1)
{
switch(lUrlType)
{
case URL_ROW:
case URL_EMBEDEDCLASS:
bRet = TRUE;
//==================================================================
// if the url is of type row or rowset and if the requested object is
// datasource or session or command , then set the status
//==================================================================
if(rguid == DBGUID_DSO || rguid == DBGUID_SESSION || rguid == DBGUID_COMMAND)
*pdwBindStatus = DBBINDURLSTATUS_S_REDIRECTED;
break;
case URL_DATASOURCE:
//==================================================================
// check if the url is of type datasource and the requested object is
// row or rowset or stream
//==================================================================
if(!(rguid == DBGUID_ROW || rguid == DBGUID_ROWSET || rguid == DBGUID_STREAM))
bRet = TRUE;
break;
case URL_ROWSET:
//==================================================================
// if the url is of type rowset and if the requested object is
// datasource or session or command , then set the status
//==================================================================
if(rguid == DBGUID_DSO || rguid == DBGUID_SESSION || rguid == DBGUID_COMMAND)
*pdwBindStatus = DBBINDURLSTATUS_S_REDIRECTED;
bRet = TRUE;
if(rguid == DBGUID_ROW)
bRet = FALSE;
break;
};
}
}
return bRet;
}
///////////////////////////////////////////////////////////////////////////
// Function to bind the requested URL
///////////////////////////////////////////////////////////////////////////
HRESULT CImplIBindResource::BindURL(IUnknown * pUnkOuter,
LPCOLESTR pwszURL,
DBBINDURLFLAG dwBindURLFlags,
REFGUID rguid,
REFIID riid,
DBIMPLICITSESSION * pImplSession,
DBBINDURLSTATUS * pdwBindStatus,
IUnknown ** ppUnk)
{
HRESULT hr = E_FAIL;
IUnknown *pTempUnk = NULL;
LONG lInitFlags = 0;
LONG lBindFlags = 0;
REFGUID guidTemp = GUID_NULL;
IUnknown* pReqestedPtr = NULL;
GetInitAndBindFlagsFromBindFlags(dwBindURLFlags,lInitFlags,lBindFlags);
//=========================================================================================
// If the requested object is DSO then create the object aggregating with the outer object
//=========================================================================================
if( rguid == DBGUID_DSO)
{
if(DBBINDURLFLAG_WAITFORINIT & dwBindURLFlags)
lInitFlags |= DBBINDURLFLAG_WAITFORINIT;
hr = m_pObj->CreateDSO(pUnkOuter,lInitFlags,riid,&pReqestedPtr);
}
else
{
hr = m_pObj->CreateDSO(NULL,lInitFlags,guidTemp,NULL);
}
if(SUCCEEDED(hr))
{
if(rguid != DBGUID_DSO)
{
//=========================================================================================
// If the requested object is DSO then create the object aggregating with the outer object
//=========================================================================================
pReqestedPtr = NULL;
pTempUnk = NULL;
if( rguid == DBGUID_SESSION)
{
hr = m_pObj->CreateSession(pUnkOuter,riid,&pReqestedPtr);
}
else
{
if(pImplSession != NULL)
{
pTempUnk = pImplSession->pUnkOuter;
// if the session is to be created with aggregation
// if the requested pointer is on IUnknown then throw error
if( pTempUnk != NULL && *pImplSession->piid != IID_IUnknown)
{
hr = DB_E_NOAGGREGATION;
}
}
if(SUCCEEDED(hr))
{
hr = m_pObj->CreateSession(pTempUnk,guidTemp,&pReqestedPtr);
}
}
}
if( SUCCEEDED(hr))
{
//=========================================================================================
// If requested object is command then call function to
// to create a command
//=========================================================================================
if(rguid == DBGUID_COMMAND)
{
pReqestedPtr = NULL;
hr = m_pObj->CreateCommand(pUnkOuter,riid,&pReqestedPtr);
}
//=========================================================================================
// If requested object is row then call function to
// to create a row
//=========================================================================================
if( rguid == DBGUID_ROW)
{
pReqestedPtr = NULL;
hr = m_pObj->CreateRow(pUnkOuter,riid,&pReqestedPtr);
}
//=========================================================================================
// If requested object is rowset then call function to
// to create a rowset
//=========================================================================================
if( rguid == DBGUID_ROWSET)
{
pReqestedPtr = NULL;
hr = m_pObj->CreateRowset(pUnkOuter,riid,&pReqestedPtr);
}
}
}
//=========================================================================================
// If failed due to some reason then release all the
// object created for binding
//=========================================================================================
if( hr != S_OK)
{
m_pObj->ReleaseAllObjects();
}
if( SUCCEEDED(hr))
{
*ppUnk = pReqestedPtr;
}
return hr ;
}