|
|
///////////////////////////////////////////////////////////////////////////////////////////
//
// 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;
}
|