|
|
///////////////////////////////////////////////////////////////////////////
//
// Microsoft WMIOLE DB Provider
//
// (C) Copyright 2000-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
// NOTE: This should be allowed for only Scopes as the path of the objects in
// scope have the path of the scope in which they are and make sense only for
// that. In case of objects in container, these objects can be in as many
// container as it wants and its path need not be dependent on the containee
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIScopedOperations::Bind(IUnknown * pUnkOuter, LPCOLESTR pwszURL, DBBINDURLFLAG dwBindURLFlags, REFGUID rguid, REFIID riid, IAuthenticate * pAuthenticate, DBIMPLICITSESSION * pImplSession, DBBINDURLSTATUS * pdwBindStatus, IUnknown ** ppUnk) { HRESULT hr = DB_E_NOTSUPPORTED; WCHAR * pstrUrl = NULL;
CSetStructuredExceptionHandler seh;
// Bind is allowed only for Scopes
if(!m_pObj->IsContainer()) { TRY_BLOCK;
// Serialize the object
CAutoBlock cab(m_pObj->GetCriticalSection()); g_pCError->ClearErrorInfo();
// If URL is NULL return Invalid Argument
if(pwszURL == NULL) { hr = E_INVALIDARG; } else { try { // Allocate the string
pstrUrl = new WCHAR[wcslen(pwszURL) + 1]; hr = S_OK; } catch(...) { SAFE_DELETE_PTR(pstrUrl); } wcscpy(pstrUrl,pwszURL);
if(SUCCEEDED(hr = CheckIfProperURL(pstrUrl,rguid))) { if( pUnkOuter != NULL && riid != IID_IUnknown) { hr = DB_E_NOAGGREGATION; } else { //========================================================================
// Calling this to bind the URL to the appropriate object
//========================================================================
hr = BindURL(pUnkOuter,pstrUrl,dwBindURLFlags,rguid,riid,pImplSession,pdwBindStatus,ppUnk); } } SAFE_DELETE_ARRAY(pstrUrl); } CATCH_BLOCK_HRESULT(hr,L"IScopedOperations::Bind");
} hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IBindResource);
return hr; }
////////////////////////////////////////////////////////////////////////////////
// Copy link from one container to another container
// Returns one of the following values:
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIScopedOperations::Copy(DBCOUNTITEM cRows, LPCOLESTR __RPC_FAR rgpwszSourceURLs[ ], LPCOLESTR __RPC_FAR rgpwszDestURLs[ ], DWORD dwCopyFlags, IAuthenticate __RPC_FAR *pAuthenticate, DBSTATUS __RPC_FAR rgdwStatus[ ], LPOLESTR __RPC_FAR rgpwszNewURLs[ ], OLECHAR __RPC_FAR *__RPC_FAR *ppStringsBuffer) { HRESULT hr = S_OK; CSetStructuredExceptionHandler seh;
TRY_BLOCK;
// Seriliaze the object
CAutoBlock cab(m_pObj->GetCriticalSection());
// Clear Error information
g_pCError->ClearErrorInfo(); if(!m_pObj->IsContainer() && !(dwCopyFlags & DBCOPY_NON_RECURSIVE)) { hr = DB_E_NOTSUPPORTED; LogMessage("Copy of the entire sub tree is not supported for Scopes"); } else if(cRows) { //======================================================================================================
// The last parameter specifies ManipulateObjects to Copy objects from one scope/contianer to another
//======================================================================================================
ManipulateObjects(cRows,rgpwszSourceURLs,rgpwszDestURLs,rgdwStatus,rgpwszNewURLs,ppStringsBuffer,FALSE); }
CATCH_BLOCK_HRESULT(hr,L"IScopedOperations::Copy");
return hr; }
////////////////////////////////////////////////////////////////////////////////
// Moving item from one container to another container
// Returns one of the following values:
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIScopedOperations::Move(DBCOUNTITEM cRows, LPCOLESTR __RPC_FAR rgpwszSourceURLs[ ], LPCOLESTR __RPC_FAR rgpwszDestURLs[ ], DWORD dwMoveFlags, IAuthenticate __RPC_FAR *pAuthenticate, DBSTATUS __RPC_FAR rgdwStatus[ ], LPOLESTR __RPC_FAR rgpwszNewURLs[ ], OLECHAR __RPC_FAR *__RPC_FAR *ppStringsBuffer) {
HRESULT hr = S_OK; CSetStructuredExceptionHandler seh;
// Seriliaze the object
CAutoBlock cab(m_pObj->GetCriticalSection());
// Clear Error information
g_pCError->ClearErrorInfo();
ppStringsBuffer = NULL; TRY_BLOCK
if(!m_pObj->IsContainer()) { hr = DB_E_NOTSUPPORTED; LogMessage("Move not supported on a scope object"); } else if(cRows) { //======================================================================================================
// The last parameter specifies ManipulateObjects to Move objects from one contianer to another
//======================================================================================================
hr = ManipulateObjects(cRows,rgpwszSourceURLs,rgpwszDestURLs,rgdwStatus,rgpwszNewURLs,ppStringsBuffer,TRUE); }
CATCH_BLOCK_HRESULT(hr,L"IScopedOperations::Move");
hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IBindResource); return hr; }
////////////////////////////////////////////////////////////////////////////////
// Deleting objects from container. This can also be used to delete
// items from scope
// Returns one of the following values:
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIScopedOperations::Delete(DBCOUNTITEM cRows, LPCOLESTR __RPC_FAR rgpwszURLs[ ], DWORD dwDeleteFlags, DBSTATUS __RPC_FAR rgdwStatus[ ]) { HRESULT hr = S_OK; BOOL bContainer = FALSE; DBSTATUS dbStatus; DBCOUNTITEM cError = 0; WCHAR * pstrUrl = NULL; CSetStructuredExceptionHandler seh;
// Seriliaze the object
CAutoBlock cab(m_pObj->GetCriticalSection());
// Clear Error information
g_pCError->ClearErrorInfo();
if(cRows > 0) { TRY_BLOCK
for ( DBCOUNTITEM item = 0 ; item < cRows ; item++) {
dbStatus = DBSTATUS_S_OK; try { // Allocate the string
pstrUrl = new WCHAR[wcslen(rgpwszURLs[item]) + 1]; } catch(...) { SAFE_DELETE_PTR(pstrUrl); }
if(pstrUrl) { memset(pstrUrl,0,(wcslen(rgpwszURLs[item]) + 1) * sizeof(WCHAR)); hr = S_OK; wcscpy(pstrUrl,rgpwszURLs[item]); } else { hr = E_OUTOFMEMORY; break; }
//=============================================
// check if the URL passed is valid
//=============================================
if(SUCCEEDED(hr = CheckIfProperURL(pstrUrl,DBGUID_ROW))) { //======================================================
// call this function to delete the object passed
// refered in the URL
//======================================================
if(FAILED(m_pObj->Delete(pstrUrl,dwDeleteFlags,dbStatus))) { cError++; } if(rgdwStatus) { rgdwStatus[item] = dbStatus; } } else { if(rgdwStatus) { rgdwStatus[item] = DBSTATUS_E_INVALIDURL; } cError++; hr = S_OK; } SAFE_DELETE_PTR(pstrUrl); } // for loop
if(SUCCEEDED(hr)) { hr = cError > 0 ? DB_S_ERRORSOCCURRED: S_OK; } hr = cError >= cRows ? DB_E_ERRORSOCCURRED: hr; hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IBindResource);
CATCH_BLOCK_HRESULT(hr,L"IScopedOperations::Delete"); } return hr; }
////////////////////////////////////////////////////////////////////////////////
// Opening a rowset contiang objects in scope/container
// Returns one of the following values:
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIScopedOperations::OpenRowset(IUnknown __RPC_FAR *pUnkOuter, DBID __RPC_FAR *pTableID, DBID __RPC_FAR *pIndexID, REFIID riid, ULONG cPropertySets, DBPROPSET __RPC_FAR rgPropertySets[ ], IUnknown __RPC_FAR *__RPC_FAR *ppRowset) { HRESULT hr = S_OK; WCHAR * pTempStr = NULL; WCHAR * pStrURL = NULL;
CSetStructuredExceptionHandler seh;
if( ppRowset ) { *ppRowset = NULL; }
TRY_BLOCK;
// Seriliaze the object
CAutoBlock cab(m_pObj->GetCriticalSection());
// Clear Error information
g_pCError->ClearErrorInfo();
//=====================================================================
// Check Arguments
//=====================================================================
if ( riid == IID_NULL) { hr = E_NOINTERFACE; // return g_pCError->PostHResult(E_NOINTERFACE,&IID_IOpenRowset) ;
} else //==========================================================
// We only accept NULL for pIndexID at this present time
//==========================================================
if( pIndexID ) { hr = DB_E_NOINDEX; // return g_pCError->PostHResult(DB_E_NOINDEX,&IID_IOpenRowset) ;
} else //===================================================================================
// We do not allow the riid to be anything other than IID_IUnknown for aggregation
//===================================================================================
if ( (pUnkOuter) && (riid != IID_IUnknown) ) { hr = DB_E_NOAGGREGATION; // return g_pCError->PostHResult(DB_E_NOAGGREGATION,&IID_IOpenRowset) ;
}
if (pTableID == NULL || (pTableID != NULL && pTableID->eKind == DBKIND_NAME && pTableID->uName.pwszName == NULL) || (pTableID != NULL && pTableID->eKind == DBKIND_NAME && !wcscmp(pTableID->uName.pwszName,L"") )) { pTempStr = NULL; } else { pTempStr = pTableID->uName.pwszName; }
if(SUCCEEDED(hr)) { if(pTempStr) { pStrURL = new WCHAR [ wcslen(pTempStr) + 1]; if(pStrURL) { wcscpy(pStrURL,pTempStr); } else { hr = E_OUTOFMEMORY; } } //====================================================
// Check if the URL passed is in the require format
//====================================================
if(SUCCEEDED(hr) && SUCCEEDED(hr =CheckIfProperURL(pStrURL,DBGUID_ROWSET))) { //==============================
// Open the rowset
//==============================
hr = m_pObj->OpenRowset(pStrURL,pUnkOuter,riid,TRUE,ppRowset,cPropertySets,rgPropertySets); } SAFE_DELETE_ARRAY(pStrURL); }
hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IScopedOperations);
CATCH_BLOCK_HRESULT(hr,L"IScopedOperations::OpenRowset"); return hr; }
////////////////////////////////////////////////////////////////////////////////////////////
// Function which checks if the URL flags matches the requested object
// This is as per the OLEDB specs
///////////////////////////////////////////////////////////////////////////////////////////
BOOL CImpIScopedOperations::CheckBindURLFlags(DBBINDURLFLAG dwBindURLFlags , REFGUID rguid) { BOOL bFlag = FALSE;
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;
}
return bFlag; }
////////////////////////////////////////////////////////////////////////////////////////////
// Function which checks if the URL is valid for the requested object
///////////////////////////////////////////////////////////////////////////////////////////
HRESULT CImpIScopedOperations::CheckIfProperURL(LPOLESTR & lpszURL,REFGUID rguid) { HRESULT hr = S_OK; LONG lUrlType = -1; CURLParser urlParser; BOOL bEmptyURL = FALSE;
// IScopedOperations::Bind supports binding of only
// to rowset and row objects
if(!(rguid == DBGUID_ROW || rguid == DBGUID_ROWSET)) { hr = DB_E_NOTSUPPORTED; } else // Empty URL can be passed only for OpenRowset call
if(!lpszURL && rguid != DBGUID_ROWSET) { hr = E_INVALIDARG; } else if(urlParser.IsValidURL(lpszURL) != RELATIVEURL) {
bEmptyURL = (lpszURL == NULL || (lpszURL != NULL && wcslen(lpszURL) == 0));
// if URL is null or empty string then the requested object has to be rowset or
// if URL of the current row object and the object requested is same and if the row object is
// requested then there is no meaning as the current row is reffering to the object
if( (bEmptyURL && rguid != DBGUID_ROWSET) ||( wbem_wcsicmp(lpszURL,m_pObj->m_strURL) == 0 && rguid == DBGUID_ROW)) { hr = E_INVALIDARG; } else { // If URL is passed then the URL should be in the scope of the current object
// otherwise there error should be returned
if(!bEmptyURL && SUCCEEDED(hr = urlParser.SetURL(lpszURL))) { if(wbem_wcsincmp(m_pObj->m_strURL,lpszURL,wcslen(m_pObj->m_strURL))) { hr = DB_E_RESOURCEOUTOFSCOPE; } }
} }
return hr; }
///////////////////////////////////////////////////////////////////////////
// Function to bind the requested URL
///////////////////////////////////////////////////////////////////////////
HRESULT CImpIScopedOperations::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; WCHAR * pStrTemp = NULL;
GetInitAndBindFlagsFromBindFlags(dwBindURLFlags,lInitFlags,lBindFlags); //=========================================================================================
// If requested object is row then call function to
// to create a row
//=========================================================================================
if( rguid == DBGUID_ROW) { pReqestedPtr = NULL; hr = m_pObj->OpenRow(pwszURL,pUnkOuter,riid,&pReqestedPtr); }
//=========================================================================================
// If requested object is rowset then call function to
// to create a rowset
//=========================================================================================
if( rguid == DBGUID_ROWSET) { pReqestedPtr = NULL; // This has to be changed to path . URL should not be sent
// if DBBINDURLFLAG_COLLECTION flag of bindflags is set then , it means that the rowset is to
// be opened as container
hr = m_pObj->OpenRowset(pStrTemp,pUnkOuter,riid,(dwBindURLFlags & DBBINDURLFLAG_COLLECTION),&pReqestedPtr); } if( SUCCEEDED(hr)) { *ppUnk = pReqestedPtr; }
return hr ; }
//////////////////////////////////////////////////////////////////////////////////////////////
// Function to Move/Copy objects from one container to another
//////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CImpIScopedOperations::ManipulateObjects(DBCOUNTITEM cRows, LPCOLESTR __RPC_FAR rgpwszSourceURLs[ ], LPCOLESTR __RPC_FAR rgpwszDestURLs[ ], DBSTATUS __RPC_FAR rgdwStatus[ ], LPOLESTR __RPC_FAR rgpwszNewURLs[ ], OLECHAR __RPC_FAR *__RPC_FAR *ppStringsBuffer, BOOL bMoveObjects) { HRESULT hr = S_OK; WCHAR * pstrSrcURL = NULL; WCHAR * pStrDstURL = NULL; WCHAR * pstrNewURL = NULL; DBCOUNTITEM item = 0; DBCOUNTITEM cError = 0; DBSTATUS dbStatus = DBSTATUS_S_OK; // NTRaid:111804
// 06/07/00
WCHAR ** prgURL = NULL;
if(cRows) { prgURL = new WCHAR*[cRows]; // NTRaid:111803
// 06/07/00
if(prgURL) { for(item = 0 ; item < cRows ; item++) { prgURL[item] = NULL; }
try { for ( item = 0 ; item < cRows ; item++) {
dbStatus = DBSTATUS_S_OK; // Allocate the string
pstrSrcURL = new WCHAR[wcslen(rgpwszSourceURLs[item]) + 1]; pStrDstURL = new WCHAR[wcslen(rgpwszDestURLs[item]) + 1]; // NTRaid:111805 & 111806
// 06/07/00
if(!pstrSrcURL || !pStrDstURL) { SAFE_DELETE_ARRAY(pstrSrcURL); SAFE_DELETE_ARRAY(pStrDstURL); SAFE_DELETE_ARRAY(prgURL); hr = E_OUTOFMEMORY; break; } else { memset(pstrSrcURL,0,(wcslen(rgpwszSourceURLs[item]) + 1) * sizeof(WCHAR)); memset(pStrDstURL,0,(wcslen(rgpwszDestURLs[item]) + 1) * sizeof(WCHAR)); hr = S_OK;
wcscpy(pstrSrcURL,rgpwszSourceURLs[item]); wcscpy(pStrDstURL,rgpwszDestURLs[item]);
if((SUCCEEDED(hr = CheckIfProperURL(pstrSrcURL,DBGUID_ROW))) && (SUCCEEDED(hr = CheckIfProperURL(pStrDstURL,DBGUID_ROW)))) { if(bMoveObjects) { hr = m_pObj->MoveObjects(pStrDstURL,pstrSrcURL,prgURL[item],dbStatus); } else { hr = m_pObj->CopyObjects(pStrDstURL,pstrSrcURL,prgURL[item],dbStatus); }
if(FAILED(hr)) { hr = S_OK; cError++; } else if(rgdwStatus) { rgdwStatus[item] = dbStatus; } } else { if(rgdwStatus) { rgdwStatus[item] = DBSTATUS_E_INVALIDURL; } cError++; hr = S_OK; } } SAFE_DELETE_ARRAY(pstrSrcURL); SAFE_DELETE_ARRAY(pStrDstURL); SAFE_DELETE_ARRAY(prgURL);
} // for loop
if(SUCCEEDED(hr)) { DBCOUNTITEM lNumberOfCharacters; for(item = 0 ; item < cRows ; item++) { if(rgpwszNewURLs) { rgpwszNewURLs[item] = prgURL[item]; } lNumberOfCharacters += wcslen(prgURL[item]); lNumberOfCharacters++; }
//==================================================================
// if the pointer is not NULL then allocate buffer for the
// URL strings and fill the data
//==================================================================
if(ppStringsBuffer) { WCHAR *pTemp; *ppStringsBuffer = (OLECHAR *)g_pIMalloc->Alloc(lNumberOfCharacters * sizeof(WCHAR)); pTemp = *ppStringsBuffer; DBLENGTH lBytesToCopy = 0;
for(item = 0 ; item < cRows ; item++) { lBytesToCopy = (wcslen(prgURL[item]) + 1) * sizeof(WCHAR); memcpy(pTemp,prgURL[item],lBytesToCopy); pTemp = (WCHAR *)(((BYTE *)pTemp) + lBytesToCopy); } } //==================================================================
// if the output parameter is NULL then delete all the memory
// allocated
//==================================================================
if(!rgpwszNewURLs) { for(item = 0 ; item < cRows ; item++) { SAFE_DELETE_ARRAY(prgURL[item]); } } } } catch(...) { //=====================================
// Release the memory allocated
//=====================================
for(item = 0 ; item < cRows ; item++) { SAFE_DELETE_ARRAY(prgURL[item]); } SAFE_DELETE_ARRAY(pstrSrcURL); SAFE_DELETE_ARRAY(pStrDstURL); SAFE_DELETE_ARRAY(prgURL); if(*ppStringsBuffer) { g_pIMalloc->Free(*ppStringsBuffer); } throw; }
if(SUCCEEDED(hr)) { hr = cError > 0 ? DB_S_ERRORSOCCURRED: S_OK; hr = (cError >= cRows) ? DB_E_ERRORSOCCURRED: hr; } else { if(ppStringsBuffer) { *ppStringsBuffer = NULL; } for(item = 0 ; item < cRows ; item++) { SAFE_DELETE_ARRAY(prgURL[item]); } SAFE_DELETE_ARRAY(pstrSrcURL); SAFE_DELETE_ARRAY(pStrDstURL); } SAFE_DELETE_ARRAY(prgURL); } else { hr = E_OUTOFMEMORY; } }
return hr; }
|