2025-04-27 07:49:33 -04:00

859 lines
28 KiB
C++

////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Microsoft WMI OLE DB Provider
// (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
//
// CImpIAccessor object implementation
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "headers.h"
#define INITIAL_NUM_PARAM 256
const DBTYPE TYPE_MODIFIERS = (DBTYPE_BYREF | DBTYPE_VECTOR | DBTYPE_ARRAY);
static const MAX_BITS = 1008;
//////////////////////////////////////////////////////////////////////////////////////////////////
// Initialize the accessor
//////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CImpIAccessor::FInit( )
{
HRESULT hr = S_OK;
if( !m_prowbitsIBuffer ){
if( !CreateNewBitArray()){
hr = E_OUTOFMEMORY;
}
}
if( hr == S_OK ){
if( !m_pextbufferAccessor ){
if( !CreateNewAccessorBuffer() ){
hr = E_OUTOFMEMORY ;
}
}
}
return hr;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//
// Adds a reference count to an existing accessor
//
// HRESULT
// S_OK Method Succeeded
// E_FAIL Provider specific Error
//////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIAccessor::AddRefAccessor ( HACCESSOR hAccessor, // IN Accessor Handle
DBREFCOUNT* pcRefCounts // OUT Reference Count
)
{
//==============================================================================================
// Retrieve our accessor structure from the client's hAccessor, free it, then mark accessor
// ptr as unused. We do not re-use accessor handles. This way, we hope to catch more client
// errors. (Also, ExtBuffer doesn't maintain a free list, so it doesn't know how to.)
//==============================================================================================
// NTRaid : 111811
// 06/13/00
PACCESSOR pAccessor = NULL;
HRESULT hr = S_OK;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
if( pcRefCounts )
{
*pcRefCounts = 0;
}
// Start a critical section
CAutoBlock cab(((CBaseObj*)(m_pObj))->GetCriticalSection());
g_pCError->ClearErrorInfo();
hr = m_pextbufferAccessor->GetItemOfExtBuffer( hAccessor, &pAccessor );
if (FAILED( hr ) || pAccessor == NULL){
hr = DB_E_BADACCESSORHANDLE;
}
else
{
InterlockedIncrement(&(pAccessor->cRef));
if( pcRefCounts )
{
*pcRefCounts = (ULONG)(pAccessor->cRef);
}
}
hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IAccessor);
CATCH_BLOCK_HRESULT(hr,L"IAccessor::AddRefAccessor");
return hr;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//
// Creates a set of bindings that can be used to send data to or retrieve data from the data cache.
//
// HRESULT
// S_OK Method Succeeded
// E_FAIL Provider specific Error
// E_INVALIDARG pHAccessor was NULL, dwAccessorFlags was invalid, or cBindings
// was not 0 and rgBindings was NULL
// E_OUTOFMEMORY Out of Memory
// DB_E_ERRORSOCCURRED dwBindPart in an rgBindings element was invalid, OR
// Column number specified was out of range, OR
// Requested coercion is not supported.
// OTHER Other HRESULTs returned by called functions
//
// NTRaid:130142: changes for this bug and also channged the accessorflag = to accessoflag &
//////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIAccessor::CreateAccessor(
DBACCESSORFLAGS dwAccessorFlags,
DBCOUNTITEM cBindings, // IN Number of Bindings
const DBBINDING rgBindings[], // IN Array of DBBINDINGS
DBLENGTH cbRowSize, // IN Number of bytes in consumer's buffer
HACCESSOR* phAccessor, // OUT Accessor Handle
DBBINDSTATUS rgStatus[]) // OUT Binding status
{
PACCESSOR pAccessor = NULL;
ULONG hAccessor;
ULONG ibind;
DBORDINAL icol;
HRESULT hr = S_OK;
DBTYPE lType = 0;
DBTYPE lAccType = 0;
DBTYPE currType = 0;
DBTYPE currTypePtr = 0;
DBTYPE currTypeBase = 0;
ULONG cError = 0;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
//======================================
// Start a critical section
//======================================
CAutoBlock cab(((CBaseObj*)(m_pObj))->GetCriticalSection());
g_pCError->ClearErrorInfo();
/* if(m_pObj->IsZoombie())
{
hr = E_UNEXPECTED;
}
else
*/ //============================================================================
// Check Parameters
//============================================================================
if ( ( cBindings && !rgBindings ) || ( phAccessor == NULL ) )
{
hr = E_INVALIDARG;
//return g_pCError->PostHResult(E_INVALIDARG,&IID_IAccessor);
}
else
if(cBindings == 0)
{
if((dwAccessorFlags & DBACCESSOR_ROWDATA) && m_bRowset)
{
VARIANT varTemp;
VariantInit(&varTemp);
if(SUCCEEDED(hr = ROWSET->GetRowsetProperty(DBPROP_IRowsetChange,varTemp)))
{
if(V_BOOL(&varTemp) == VARIANT_FALSE)
{
hr = DB_E_NULLACCESSORNOTSUPPORTED;
}
else
if(SUCCEEDED(hr = ROWSET->GetRowsetProperty(DBPROP_UPDATABILITY,varTemp)))
{
if(!(DBPROPVAL_UP_INSERT & varTemp.lVal))
{
hr = DB_E_NULLACCESSORNOTSUPPORTED;
}
}
}
}
else
if(!(dwAccessorFlags & DBACCESSOR_PARAMETERDATA) && m_bRowset == FALSE)
{
hr = DB_E_NULLACCESSORNOTSUPPORTED;
}
}
else
{
//============================================================================
// init out params
//============================================================================
*phAccessor = NULL;
//============================================================================
// Check if we have a correct accessor type
//============================================================================
if ( dwAccessorFlags & DBACCESSOR_PASSBYREF )
{
hr = DB_E_BYREFACCESSORNOTSUPPORTED;
}
}
if( SUCCEEDED(hr))
{
//============================================================================
// Take DBACCESSOR_OPTIMIZED off since we do nothing with it
//============================================================================
dwAccessorFlags &= ~DBACCESSOR_OPTIMIZED;
// NTRaid:130142
if (!( (dwAccessorFlags & DBACCESSOR_ROWDATA) || (dwAccessorFlags & DBACCESSOR_PARAMETERDATA)))
{
hr = DB_E_BADACCESSORFLAGS;
//return g_pCError->PostHResult(DB_E_BADACCESSORFLAGS,&IID_IAccessor) ;
}
else
// If parameterdata accessor is to be created when the accessor
// is from Rowset object then throw error
if((dwAccessorFlags & DBACCESSOR_PARAMETERDATA) && m_bRowset)
{
hr = DB_E_BADACCESSORFLAGS;
}
}
// if the accessor is on command and if it is command text is not been
// set then throw an erro
if(SUCCEEDED(hr) && (dwAccessorFlags & DBACCESSOR_PARAMETERDATA) &&
!(COMMAND->m_pQuery->GetStatus() & CMD_TEXT_SET))
{
DB_E_NOCOMMAND;
}
if( SUCCEEDED(hr))
{
//============================================================================
// reset the parameter data
//============================================================================
if (dwAccessorFlags & DBACCESSOR_PARAMETERDATA)
{
m_prowbitsIBuffer->ResetAllSlots();
}
//============================================================================
// Initialize the status array to DBBINDSTATUS_OK.
//============================================================================
if ( rgStatus )
{
memset(rgStatus, 0x00, cBindings*sizeof(DBBINDSTATUS));
}
//============================================================================
// Check on the bindings the user gave us.
//============================================================================
hr = NOERROR;
for (ibind =0; ibind < cBindings && hr != E_OUTOFMEMORY; ibind++)
{
//========================================================================
// other binding problems forbidden by OLE-DB
//========================================================================
currType = rgBindings[ibind].wType;
currTypePtr = currType & (DBTYPE_BYREF|DBTYPE_ARRAY|DBTYPE_VECTOR);
currTypeBase = currType & ~(DBTYPE_BYREF|DBTYPE_ARRAY|DBTYPE_VECTOR);
icol = rgBindings[ibind].iOrdinal;
//========================================================================
// make sure column number is in range
//========================================================================
if( dwAccessorFlags & DBACCESSOR_ROWDATA)
{
if(((ROWSET->m_ulProps & BOOKMARKPROP) && (DB_LORDINAL)icol < 0) ||
(!(ROWSET->m_ulProps & BOOKMARKPROP) && (DB_LORDINAL)icol <= 0) ||
(icol > ROWSET->m_cTotalCols) )
{
//====================================================================
// Set Bind status to DBBINDSTATUS_BADORDINAL
//====================================================================
hr = DB_E_ERRORSOCCURRED;
if ( rgStatus )
{
rgStatus[ibind] = DBBINDSTATUS_BADORDINAL;
}
cError++;
}
}
else
{
if(icol > COMMAND->GetParamCount() )
{
//====================================================================
// Set Bind status to DBBINDSTATUS_BADORDINAL
//====================================================================
hr = DB_E_ERRORSOCCURRED;
if ( rgStatus )
{
rgStatus[ibind] = DBBINDSTATUS_BADORDINAL;
}
cError++;
}
}
//========================================================================
// At least one of these valid parts has to be set. In SetData I assume
// it is the case.
//========================================================================
if( SUCCEEDED(hr) && !(rgBindings[ibind].dwPart & (DBPART_VALUE|DBPART_LENGTH|DBPART_STATUS)) )
{
//====================================================================
// Set Bind status to DBBINDSTATUS_BADBINDINFO
//====================================================================
hr = DB_E_ERRORSOCCURRED;
if ( rgStatus )
{
rgStatus[ibind] = DBBINDSTATUS_BADBINDINFO;
}
cError++;
}
//========================================================================
// dwPart is something other than value, length, or status
//========================================================================
else if ( (rgBindings[ibind].dwPart & ~(DBPART_VALUE|DBPART_LENGTH|DBPART_STATUS)) )
{
//====================================================================
// Set Bind status to DBBINDSTATUS_BADBINDINFO
//====================================================================
hr = DB_E_ERRORSOCCURRED;
if ( rgStatus )
{
rgStatus[ibind] = DBBINDSTATUS_BADBINDINFO;
}
cError++;
}
//========================================================================
// wType was DBTYPE_EMPTY or DBTYPE_NULL
//========================================================================
else
if ( (currType==DBTYPE_EMPTY || currType==DBTYPE_NULL) )
{
//====================================================================
// Set Bind status to DBBINDSTATUS_BADBINDINFO
//====================================================================
hr = DB_E_ERRORSOCCURRED;
if ( rgStatus )
{
rgStatus[ibind] = DBBINDSTATUS_BADBINDINFO;
}
cError++;
}
//========================================================================
// wType was DBTYPE_BYREF or'ed with DBTYPE_EMPTY, NULL, or RESERVED
//========================================================================
else
if ( ((currType & DBTYPE_BYREF) &&
(currTypeBase == DBTYPE_EMPTY || currTypeBase == DBTYPE_NULL || currType & DBTYPE_RESERVED)) )
{
//====================================================================
// Set Bind status to DBBINDSTATUS_BADBINDINFO
//====================================================================
hr = DB_E_ERRORSOCCURRED;
if ( rgStatus )
{
rgStatus[ibind] = DBBINDSTATUS_BADBINDINFO;
}
cError++;
}
//========================================================================
// wType was used with more than one type indicators
//========================================================================
else
if ( !(currTypePtr == 0 || currTypePtr == DBTYPE_BYREF ||
currTypePtr == DBTYPE_ARRAY || currTypePtr == DBTYPE_VECTOR) )
{
//====================================================================
// Set Bind status to DBBINDSTATUS_BADBINDINFO
//====================================================================
hr = DB_E_ERRORSOCCURRED;
if ( rgStatus )
{
rgStatus[ibind] = DBBINDSTATUS_BADBINDINFO;
}
cError++;
}
//========================================================================
// wType was a non pointer type with provider owned memory
//========================================================================
else
if ( !currTypePtr && rgBindings[ibind].dwMemOwner==DBMEMOWNER_PROVIDEROWNED )
{
//========================================================================
// We are dealing with parameter data
//========================================================================
if ((dwAccessorFlags & DBACCESSOR_PARAMETERDATA)
&& ((rgBindings[ibind].eParamIO & DBPARAMIO_OUTPUT)
|| ((rgBindings[ibind].eParamIO & DBPARAMIO_INPUT)
&&(dwAccessorFlags & DBACCESSOR_PASSBYREF) == 0)))
{
hr = DB_E_ERRORSOCCURRED;
if ( rgStatus )
{
rgStatus[ibind] = DBBINDSTATUS_BADBINDINFO;
}
cError++;
}
//====================================================================
// Set Bind status to DBBINDSTATUS_BADBINDINFO
//====================================================================
else
{
hr = DB_E_ERRORSOCCURRED;
if ( rgStatus )
{
rgStatus[ibind] = DBBINDSTATUS_BADBINDINFO;
}
cError++;
}
}
//========================================================================
// we only support client owned memory
//========================================================================
else
if ( rgBindings[ibind].dwMemOwner != DBMEMOWNER_CLIENTOWNED )
{
//====================================================================
// Set Bind status to DBBINDSTATUS_BADBINDINFO
//====================================================================
hr = DB_E_ERRORSOCCURRED;
if ( rgStatus )
{
rgStatus[ibind] = DBBINDSTATUS_BADBINDINFO;
}
cError++;
}
//========================================================================
// Make sure we can do the coercion that is requested
//========================================================================
else
{
WORD wBaseType;
BOOL fInParam = FALSE, fOutParam = FALSE;
if( NOERROR == S_OK && (dwAccessorFlags & DBACCESSOR_PARAMETERDATA))
{
if (rgBindings[ibind].iOrdinal == 0)
{
if(rgStatus)
{
rgStatus[ibind] = DBBINDSTATUS_BADORDINAL;
}
}
else
if ((rgBindings[ibind].eParamIO & (DBPARAMIO_INPUT|DBPARAMIO_OUTPUT)) == 0 ||
(rgBindings[ibind].eParamIO & ~(DBPARAMIO_INPUT|DBPARAMIO_OUTPUT)) )
{
if(rgStatus)
{
rgStatus[ibind] = DBBINDSTATUS_BADBINDINFO;
}
}
else
if (rgBindings[ibind].eParamIO & DBPARAMIO_INPUT)
{
if (m_prowbitsIBuffer->IsSlotSet((ULONG)rgBindings[ibind].iOrdinal) == S_OK)
{
if(rgStatus)
{
rgStatus[ibind] = DBBINDSTATUS_BADBINDINFO;
}
}
else
if (SUCCEEDED(hr) && FAILED(m_prowbitsIBuffer->SetSlots((ULONG)rgBindings[ibind].iOrdinal,(ULONG)rgBindings[ibind].iOrdinal)))
{
hr = E_OUTOFMEMORY;
break;
}
}
if ((rgBindings[ibind].eParamIO & DBPARAMIO_OUTPUT)
&& (rgBindings[ibind].wType & DBTYPE_BYREF)
&& (wBaseType = (rgBindings[ibind].wType & ~TYPE_MODIFIERS)) != DBTYPE_BYTES
&& wBaseType != DBTYPE_STR && wBaseType != DBTYPE_WSTR)
{
if(rgStatus && (rgStatus[ibind] == DBBINDSTATUS_OK))
{
rgStatus[ibind] = DBBINDSTATUS_BADBINDINFO;
}
}
if (rgStatus && (rgStatus[ibind] == DBBINDSTATUS_OK) && (dwAccessorFlags & DBACCESSOR_PASSBYREF))
{
if (!fInParam && (rgBindings[ibind].eParamIO & DBPARAMIO_INPUT))
fInParam = TRUE;
if (!fOutParam && (rgBindings[ibind].eParamIO & DBPARAMIO_OUTPUT))
fOutParam = TRUE;
if (fInParam && fOutParam && rgStatus)
rgStatus[ibind] = DBBINDSTATUS_BADBINDINFO;
}
}
else
{
// If the type of the column is of type CHAPTER then consider \
// that as of type unsigned long
if((dwAccessorFlags & DBACCESSOR_ROWDATA) && (DBTYPE_HCHAPTER == ROWSET->m_Columns.ColumnType(icol)))
{
lType = DBTYPE_UI4;
}
else
{
if(dwAccessorFlags & DBACCESSOR_ROWDATA)
{
lType = ROWSET->m_Columns.ColumnType(icol);
}
}
if(rgBindings[ibind].wType == DBTYPE_HCHAPTER)
{
lAccType = DBTYPE_UI4;
}
else
{
lAccType = rgBindings[ibind].wType;
}
if(S_OK != (hr = g_pIDataConvert->CanConvert(lAccType, lType)) ||
S_OK != (hr = g_pIDataConvert->CanConvert( lType, lAccType)))
{
//================================================================
// Set Bind status to DBBINDSTATUS_UNSUPPORTEDCONVERSION
//================================================================
hr = DB_E_ERRORSOCCURRED;
if ( rgStatus )
rgStatus[ibind] = DBBINDSTATUS_UNSUPPORTEDCONVERSION;
cError++;
}
} // else for if( NOERROR == S_OK && (dwAccessorFlags & DBACCESSOR_PARAMETERDATA))
}
} // end of for loop
//============================================================================
// Any errors amongst those checks?
//============================================================================
if(cError)
{
hr = DB_E_ERRORSOCCURRED;
}
else
if ( NOERROR == hr)
{
try
{
//========================================================================
// Make a copy of the client's binding array, and the type of binding.
//========================================================================
pAccessor = (ACCESSOR *) new BYTE[sizeof( ACCESSOR ) + (cBindings - 1) *sizeof( DBBINDING )];
}
catch(...)
{
SAFE_DELETE_PTR(pAccessor);
throw;
}
if ( pAccessor == NULL )
{
hr = E_OUTOFMEMORY;
}
else
{
//====================================================================
// We store a ptr to the newly created variable-sized ACCESSOR.
// We have an array of ptrs (to ACCESSOR's).
// The handle is the index into the array of ptrs.
// The InsertIntoExtBuffer function appends to the end of the array.
//====================================================================
assert( m_pextbufferAccessor );
hr = m_pextbufferAccessor->InsertIntoExtBuffer( &pAccessor, hAccessor );
if ( FAILED( hr ) )
{
SAFE_DELETE_PTR( pAccessor );
hr = E_OUTOFMEMORY;
}
else
{
assert( hAccessor );
//=================================================================
// Copy the client's bindings into the ACCESSOR.
//=================================================================
pAccessor->dwAccessorFlags = dwAccessorFlags;
pAccessor->cBindings = cBindings;
//=================================================================
// Establish Reference count.
//=================================================================
pAccessor->cRef = 1;
memcpy( &(pAccessor->rgBindings[0]), &rgBindings[0], cBindings*sizeof( DBBINDING ));
//=================================================================
// fill out-param
//=================================================================
*phAccessor = (HACCESSOR) hAccessor;
hr = S_OK ;
} // else for Failed(hr) after call to InsertIntoExtBuffer()
} // Else for if(pAccessor == NULL)
} // if ( NOERROR == hr )
} // If succeeded(hr) after validating arguments
hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IAccessor);
CATCH_BLOCK_HRESULT(hr,L"IAccessor::CreateAccessor");
return hr;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Returns the bindings in an accessor
//
// HRESULT
// S_OK Method Succeeded
// E_INVALIDARG pdwAccessorFlags/pcBinding/prgBinding were NULL
// E_OUTOFMEMORY Out of Memory
// DB_E_BADACCESSORHANDLE Invalid Accessor given
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIAccessor::GetBindings( HACCESSOR hAccessor, // IN Accessor Handle
DBACCESSORFLAGS* pdwAccessorFlags, // OUT Binding Type flag
DBCOUNTITEM* pcBindings, // OUT Number of Bindings returned
DBBINDING** prgBindings // OUT Bindings
)
{
//========================================================================
// Retrieve our accessor structure from the client's hAccessor,
// make a copy of the bindings for the user, then done.
//========================================================================
// NTRaid:111810
// 06/067/00
PACCESSOR pAccessor = NULL;
ULONG cBindingSize;
HRESULT hr = S_OK;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
//========================================================================
// init out-params
//========================================================================
if( pdwAccessorFlags )
{
*pdwAccessorFlags = 0;
}
if( pcBindings )
{
*pcBindings = 0;
}
if ( prgBindings )
{
*prgBindings = NULL;
}
// Start a critical section
CAutoBlock cab(((CBaseObj*)(m_pObj))->GetCriticalSection());
g_pCError->ClearErrorInfo();
/* if(m_pObj->IsZoombie())
{
hr = E_UNEXPECTED;
}
else
*/ //========================================================================
// check parameters
//========================================================================
if (!pdwAccessorFlags || !pcBindings || !prgBindings)
{
hr = E_INVALIDARG;
}
else
{
//====================================================================
// Validate Accessor Handle
//====================================================================
hr = m_pextbufferAccessor->GetItemOfExtBuffer( hAccessor, &pAccessor );
if (FAILED( hr ) || pAccessor == NULL)
{
hr = DB_E_BADACCESSORHANDLE;
}
else
{
//================================================================
// Allocate and return Array of bindings
//================================================================
cBindingSize = (ULONG)(pAccessor->cBindings * sizeof( DBBINDING ));
if ( cBindingSize )
{
*prgBindings = (DBBINDING *) g_pIMalloc->Alloc( cBindingSize );
}
//================================================================
// Check the Allocation
//================================================================
if ( ( *prgBindings == NULL ) && ( cBindingSize ) )
{
hr = E_OUTOFMEMORY;
}
else
{
*pdwAccessorFlags = pAccessor->dwAccessorFlags;
*pcBindings = pAccessor->cBindings;
memcpy( *prgBindings, pAccessor->rgBindings, cBindingSize );
hr = S_OK ;
}
}
}
hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IAccessor);
CATCH_BLOCK_HRESULT(hr,L"IAccessor::GetBindings");
return hr;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Releases an Accessor
//
// HRESULT
// S_OK Method Succeeded
// DB_E_BADACCESSORHANDLE hAccessor was invalid
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIAccessor::ReleaseAccessor( HACCESSOR hAccessor, // IN Accessor handle to release
DBREFCOUNT* pcRefCounts // OUT Reference Count
)
{
//===============================================================================
// Retrieve our accessor structure from the client's hAccessor, free it, then
// mark accessor ptr as unused. We do not re-use accessor handles. This way,
// we hope to catch more client errors. (Also, ExtBuffer doesn't
// maintain a free list, so it doesn't know how to.)
//===============================================================================
// NTRaid:111809
// 06/13/00
PACCESSOR pAccessor = NULL;
HRESULT hr = S_OK;
CSetStructuredExceptionHandler seh;
TRY_BLOCK;
if( pcRefCounts )
{
*pcRefCounts = 0;
}
//========================================================
// Start a critical section
//========================================================
CAutoBlock cab(((CBaseObj*)(m_pObj))->GetCriticalSection());
g_pCError->ClearErrorInfo();
hr = m_pextbufferAccessor->GetItemOfExtBuffer( hAccessor, &pAccessor );
if (FAILED( hr ) || pAccessor == NULL)
{
hr = DB_E_BADACCESSORHANDLE;
}
else
{
//============================================================
// Free the actual structure.
//============================================================
InterlockedDecrement(&(pAccessor->cRef));
assert( pAccessor->cRef >= 0 );
if( pAccessor->cRef <= 0 )
{
SAFE_DELETE_PTR( pAccessor );
if( pcRefCounts )
{
*pcRefCounts = 0;
}
//========================================================
// Store a null in our array-of-ptrs, so we know next time
// that it is invalid. (operator[] returns a ptr to the
// space where the ptr is stored.)
//========================================================
*(PACCESSOR*) ((*m_pextbufferAccessor)[ (ULONG) hAccessor]) = NULL;
}
else
if( pcRefCounts )
{
*pcRefCounts = (ULONG)(pAccessor->cRef);
}
hr = S_OK ;
}
hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IAccessor);
CATCH_BLOCK_HRESULT(hr,L"IAccessor::ReleaseAccessor");
return hr;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Create helper objects
//
// Bit array to track presence/absense of rows.
//
///////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CImpIAccessor::CreateNewBitArray()
{
BOOL fRc = TRUE;
SAFE_DELETE_PTR(m_prowbitsIBuffer);
m_prowbitsIBuffer = new CBitArray;
if (m_prowbitsIBuffer == NULL || FAILED( m_prowbitsIBuffer->FInit( MAX_BITS, g_dwPageSize ))){
fRc = FALSE;
}
return fRc;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CImpIAccessor::CreateNewAccessorBuffer()
{
BOOL fRc = TRUE;
SAFE_DELETE_PTR( m_pextbufferAccessor );
m_pextbufferAccessor = (LPEXTBUFFER) new CExtBuffer;
if (m_pextbufferAccessor == NULL || FAILED( m_pextbufferAccessor->FInit( 1, sizeof( PACCESSOR ), g_dwPageSize ))){
fRc = FALSE;
}
return fRc;
}