738 lines
21 KiB
C++
738 lines
21 KiB
C++
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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;
|
|
}
|