357 lines
10 KiB
C++
357 lines
10 KiB
C++
///////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Microsoft WMIOLE DB Provider
|
|
// (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
|
|
//
|
|
// IRowsetIdentity interface implementation
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "headers.h"
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Compares two row handles to see if they refer to the same row instance.
|
|
//
|
|
// HRESULT
|
|
// S_FALSE Method Succeeded but did not refer to the same row
|
|
// S_OK Method Succeeded
|
|
// DB_E_BADROWHANDLE Invalid row handle given
|
|
// OTHER Other HRESULTs returned by called functions
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CImplIRowsetRefresh::GetLastVisibleData(HROW hRow,HACCESSOR hAccessor,void * pData)
|
|
{
|
|
//============================================================
|
|
// Call this function of RowFetch Object to fetch data
|
|
//============================================================
|
|
|
|
HRESULT hr = S_OK;
|
|
CSetStructuredExceptionHandler seh;
|
|
|
|
TRY_BLOCK;
|
|
|
|
// Seriliaze the object
|
|
CAutoBlock cab(ROWSET->GetCriticalSection());
|
|
|
|
// Clear Error information
|
|
g_pCError->ClearErrorInfo();
|
|
|
|
if(m_pObj->IsZoombie())
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
else
|
|
{
|
|
hr = m_pObj->m_pRowFetchObj->FetchData(m_pObj,hRow,hAccessor,pData);
|
|
}
|
|
|
|
hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IRowsetRefresh);
|
|
|
|
CATCH_BLOCK_HRESULT(hr,L"IRowsetRefresh::GetLastVisibleData");
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Compares two row handles to see if they refer to the same row instance.
|
|
//
|
|
// HRESULT
|
|
// S_FALSE Method Succeeded but did not refer to the same row
|
|
// S_OK Method Succeeded
|
|
// DB_E_BADROWHANDLE Invalid row handle given
|
|
// DB_E_BADCHAPTER Bad HCHAPTER
|
|
// E_INVALIDARG One of the parameters is invalid
|
|
// OTHER Other HRESULTs returned by called functions
|
|
//
|
|
// NTRaid 111830 (Raid about CRowset::GetData Found that this function is not returning
|
|
// the proper error while looking into this
|
|
// NTRaid 147095
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CImplIRowsetRefresh::RefreshVisibleData(HCHAPTER hChapter,
|
|
DBCOUNTITEM cRows,
|
|
const HROW rghRows[],
|
|
BOOL fOverwrite,
|
|
DBCOUNTITEM * pcRowsRefreshed,
|
|
HROW ** prghRowsRefreshed,
|
|
DBROWSTATUS ** prgRowStatus)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DBCOUNTITEM lRowsRefreshed = 0;
|
|
DBROWSTATUS * rgRowStatus;
|
|
HROW * prghRows = NULL;
|
|
BOOL bGetAllActiveRows = FALSE;
|
|
BSTR strBookMark = Wmioledb_SysAllocString(NULL);
|
|
|
|
CSetStructuredExceptionHandler seh;
|
|
|
|
TRY_BLOCK;
|
|
|
|
// Seriliaze the object
|
|
CAutoBlock cab(ROWSET->GetCriticalSection());
|
|
|
|
// Clear Error information
|
|
g_pCError->ClearErrorInfo();
|
|
|
|
*prgRowStatus = NULL;
|
|
|
|
if(m_pObj->IsZoombie())
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
else
|
|
//========================================================================
|
|
// Check the HChapter is of the current rowset if it is non zero
|
|
//========================================================================
|
|
if((LONG_PTR) cRows < 0 || ( cRows > 0 && rghRows == NULL) ||
|
|
(pcRowsRefreshed == NULL && prghRowsRefreshed != NULL) )
|
|
{
|
|
hr = E_INVALIDARG;
|
|
}
|
|
else
|
|
//========================================================================
|
|
// Check the HChapter is of the current rowset is valid
|
|
//========================================================================
|
|
if((m_pObj->m_bIsChildRs == TRUE && hChapter == DB_NULL_HCHAPTER) || (LONG_PTR)hChapter < 0 ||
|
|
m_pObj->m_bIsChildRs == FALSE && hChapter != 0)
|
|
{
|
|
hr = DB_E_BADCHAPTER;
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
if(prghRowsRefreshed)
|
|
{
|
|
*prghRowsRefreshed = NULL;
|
|
}
|
|
if(pcRowsRefreshed)
|
|
{
|
|
*pcRowsRefreshed = 0;
|
|
}
|
|
if(prgRowStatus)
|
|
{
|
|
*prgRowStatus = NULL;
|
|
}
|
|
|
|
// If cRows is zero get all the active rows
|
|
if(cRows == 0)
|
|
{
|
|
bGetAllActiveRows = TRUE;
|
|
//=================================================
|
|
// if the rowset is child rowset get the list
|
|
// open rowset from the chapter manager
|
|
//=================================================
|
|
if(m_pObj->m_bIsChildRs)
|
|
{
|
|
hr = m_pObj->m_pChapterMgr->GetAllHROWs(prghRows,cRows);
|
|
|
|
}
|
|
//=========================================
|
|
// else get it from the instance manager
|
|
//=========================================
|
|
else
|
|
{
|
|
hr = m_pObj->m_InstMgr->GetAllHROWs(prghRows,cRows);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
prghRows = (HROW *)&rghRows[0];
|
|
}
|
|
|
|
// allocate memory for the row status
|
|
rgRowStatus = (DBROWSTATUS *)g_pIMalloc->Alloc(sizeof(DBROWSTATUS) * cRows);
|
|
if(S_OK == CheckIfRowsExists(cRows,prghRows,rgRowStatus))
|
|
{
|
|
// Navigate thru each row
|
|
for( ULONG nIndex = 0 ; nIndex < cRows ; nIndex++)
|
|
{
|
|
// If the status of the row is ok then refresh the instance
|
|
if(rgRowStatus[nIndex] == DBROWSTATUS_S_OK)
|
|
{
|
|
// call this function to refresh the instance pointer
|
|
m_pObj->RefreshInstance(m_pObj->GetInstancePtr(prghRows[nIndex]));
|
|
|
|
if(m_pObj->m_uRsType == PROPERTYQUALIFIER ||
|
|
m_pObj->m_uRsType == CLASSQUALIFIER )
|
|
{
|
|
m_pObj->GetQualiferName(prghRows[nIndex],strBookMark);
|
|
}
|
|
|
|
// Release the previous row data
|
|
hr = m_pObj->ReleaseRowData(prghRows[nIndex],FALSE); // don't release the slots
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
rgRowStatus[nIndex] = DBROWSTATUS_E_FAIL;
|
|
}
|
|
//===================================================================
|
|
// if data otherupdatedelete property is false then get the data
|
|
// for the row,
|
|
// Get the data even if rowset is pointing to a qualifer rowset
|
|
//===================================================================
|
|
// Get the data for the current row
|
|
hr = m_pObj->GetData(prghRows[nIndex],strBookMark);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
rgRowStatus[nIndex] = DBROWSTATUS_E_FAIL;
|
|
}
|
|
else
|
|
{
|
|
m_pObj->m_ulLastFetchedRow = prghRows[nIndex];
|
|
lRowsRefreshed++;
|
|
rgRowStatus[nIndex] = DBROWSTATUS_S_OK;
|
|
}
|
|
}
|
|
if(strBookMark != NULL)
|
|
{
|
|
SysFreeString(strBookMark);
|
|
strBookMark = NULL;
|
|
}
|
|
hr = S_OK;
|
|
}
|
|
|
|
// Allocate memory for output HROW and ROWSTATUS
|
|
if(pcRowsRefreshed)
|
|
{
|
|
*prghRowsRefreshed = (HROW *)g_pIMalloc->Alloc(sizeof(HROW) * cRows);
|
|
if(*prghRowsRefreshed)
|
|
{
|
|
memcpy( *prghRowsRefreshed,prghRows,sizeof(HROW) * cRows);
|
|
*pcRowsRefreshed = lRowsRefreshed;
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
if(SUCCEEDED(hr) && prgRowStatus)
|
|
{
|
|
*prgRowStatus = (DBROWSTATUS *)g_pIMalloc->Alloc(sizeof(DBROWSTATUS) * cRows);
|
|
if(*prgRowStatus)
|
|
{
|
|
memcpy( *prgRowStatus,rgRowStatus,sizeof(DBROWSTATUS) * cRows);
|
|
}
|
|
else
|
|
{
|
|
if(*prghRowsRefreshed != NULL)
|
|
{
|
|
g_pIMalloc->Free(*prghRowsRefreshed);
|
|
}
|
|
|
|
*prghRowsRefreshed = NULL;
|
|
*pcRowsRefreshed = 0;
|
|
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
}
|
|
|
|
// free the temporarily allocated memory
|
|
g_pIMalloc->Free(rgRowStatus);
|
|
|
|
// free the memory if allocated by GetAllHROWs
|
|
// which is called when cRows is 0
|
|
if(prghRows != NULL && bGetAllActiveRows == TRUE)
|
|
{
|
|
SAFE_DELETE_ARRAY(prghRows);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
if(rgRowStatus != NULL)
|
|
g_pIMalloc->Free(rgRowStatus);
|
|
|
|
if(*prgRowStatus != NULL)
|
|
g_pIMalloc->Free(*prgRowStatus);
|
|
|
|
if(*prghRowsRefreshed != NULL)
|
|
g_pIMalloc->Free(*prghRowsRefreshed);
|
|
|
|
if(prghRows != NULL && rghRows == NULL)
|
|
{
|
|
SAFE_DELETE_ARRAY(prghRows);
|
|
}
|
|
|
|
throw;
|
|
}
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if(lRowsRefreshed == 0 && cRows)
|
|
{
|
|
hr = DB_E_ERRORSOCCURRED;
|
|
}
|
|
else
|
|
{
|
|
hr = cRows>lRowsRefreshed ? DB_S_ERRORSOCCURRED : S_OK;
|
|
}
|
|
}
|
|
|
|
hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IRowsetRefresh);
|
|
|
|
CATCH_BLOCK_HRESULT(hr,L"IRowsetRefresh::RefreshVisibleData");
|
|
return hr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Function to check the row handles and set the status of the row handles
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CImplIRowsetRefresh::CheckIfRowsExists(DBCOUNTITEM cRows,const HROW rghRows[],DBROWSTATUS * prgRowStatus)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DBSTATUS dwStatus = 0;
|
|
|
|
if (!m_pObj->BitArrayInitialized()){
|
|
|
|
//=================================================================================
|
|
// This is the case when the method was called even before the rowset got fully
|
|
// intialized, hence no rows could have been fetched yet, therefore there do not
|
|
// exist valid row handles, and all row handles provided must be invalid.
|
|
//=================================================================================
|
|
hr = DB_E_BADROWHANDLE;
|
|
}
|
|
else
|
|
{
|
|
for ( ULONG nIndex = 0 ; nIndex < cRows ; nIndex++)
|
|
{
|
|
//=================================================================================
|
|
// Check validity of input handles
|
|
//=================================================================================
|
|
if(TRUE == m_pObj->IsRowExists(rghRows[nIndex]) )
|
|
{
|
|
dwStatus = m_pObj->GetRowStatus(rghRows[nIndex]);
|
|
if( dwStatus != DBROWSTATUS_S_OK )
|
|
{
|
|
if(dwStatus == DBROWSTATUS_E_DELETED ||
|
|
dwStatus == DBROWSTATUS_E_DELETED)
|
|
hr = DB_E_DELETEDROW;
|
|
else
|
|
prgRowStatus[nIndex] = DBROWSTATUS_E_FAIL;
|
|
}
|
|
else
|
|
prgRowStatus[nIndex] = DBROWSTATUS_S_OK;
|
|
|
|
}
|
|
else
|
|
{
|
|
prgRowStatus[nIndex] = DBROWSTATUS_E_INVALID;
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|