1250 lines
26 KiB
C++
1250 lines
26 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1995.
|
|
//
|
|
// File: cprops.cxx
|
|
//
|
|
// Contents: Property Cache functionality for NDS
|
|
//
|
|
// Functions:
|
|
// CPropertyCache::addproperty
|
|
// CPropertyCache::updateproperty
|
|
// CPropertyCache::findproperty
|
|
// CPropertyCache::getproperty
|
|
// CPropertyCache::putproperty
|
|
// CProperyCache::CPropertyCache
|
|
// CPropertyCache::~CPropertyCache
|
|
// CPropertyCache::createpropertycache
|
|
//
|
|
// History: 25-Apr-96 KrishnaG Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
#include "nds.hxx"
|
|
|
|
|
|
#if DBG
|
|
DECLARE_INFOLEVEL(NDSMarshall);
|
|
DECLARE_DEBUG(NDSMarshall);
|
|
#define NDSMarshallDebugOut(x) NDSMarshallInlineDebugOut x
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------------
|
|
//
|
|
// Function: CPropertyCache::addproperty
|
|
//
|
|
// Synopsis: Adds a new empty property to the cache
|
|
//
|
|
//
|
|
//
|
|
// Arguments: [szPropertyName] --
|
|
// [vt] --
|
|
// [vaData] --
|
|
//
|
|
//
|
|
//-------------------------------------------------------------------------
|
|
HRESULT
|
|
CPropertyCache::
|
|
addproperty(
|
|
LPWSTR szPropertyName,
|
|
DWORD dwSyntaxId
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
PPROPERTY pNewProperty = NULL;
|
|
LPWSTR tempString = NULL;
|
|
|
|
PPROPERTY pNewProperties = NULL;
|
|
|
|
//
|
|
// Allocate the string first
|
|
//
|
|
tempString = AllocADsStr(szPropertyName);
|
|
|
|
if (!tempString)
|
|
BAIL_ON_FAILURE(hr=E_OUTOFMEMORY);
|
|
|
|
|
|
//
|
|
// extend the property cache by adding a new property entry
|
|
//
|
|
|
|
pNewProperties = (PPROPERTY)ReallocADsMem(
|
|
_pProperties,
|
|
_cb,
|
|
_cb + sizeof(PROPERTY)
|
|
);
|
|
if (!pNewProperties) {
|
|
hr = E_OUTOFMEMORY;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
_pProperties = pNewProperties;
|
|
|
|
pNewProperty = (PPROPERTY)((LPBYTE)_pProperties + _cb);
|
|
|
|
|
|
//
|
|
// Since the memory has already been allocated in tempString
|
|
// just set the value/pointer now.
|
|
//
|
|
pNewProperty->szPropertyName = tempString;
|
|
|
|
//
|
|
// Update the index
|
|
//
|
|
|
|
_dwMaxProperties++;
|
|
_cb += sizeof(PROPERTY);
|
|
|
|
RRETURN(hr);
|
|
|
|
error:
|
|
|
|
if (tempString)
|
|
FreeADsStr(tempString);
|
|
|
|
RRETURN_EXP_IF_ERR(hr);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------------
|
|
//
|
|
// Function: CPropertyCache::updateproperty
|
|
//
|
|
// Synopsis:
|
|
//
|
|
//
|
|
//
|
|
// Arguments: [szPropertyName] --
|
|
// [vaData] --
|
|
//
|
|
//-------------------------------------------------------------------------
|
|
HRESULT
|
|
CPropertyCache::
|
|
updateproperty(
|
|
LPWSTR szPropertyName,
|
|
DWORD dwSyntaxId,
|
|
DWORD dwNumValues,
|
|
PNDSOBJECT pNdsObject,
|
|
BOOL fExplicit
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
DWORD dwIndex;
|
|
PNDSOBJECT pNdsTempObject = NULL;
|
|
PPROPERTY pThisProperty = NULL;
|
|
|
|
hr = findproperty(
|
|
szPropertyName,
|
|
&dwIndex
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
pThisProperty = _pProperties + dwIndex;
|
|
|
|
if (!fExplicit) {
|
|
if ((PROPERTY_FLAGS(pThisProperty) == CACHE_PROPERTY_MODIFIED) ||
|
|
(PROPERTY_FLAGS(pThisProperty) == CACHE_PROPERTY_CLEARED)) {
|
|
|
|
hr = S_OK;
|
|
goto error;
|
|
}
|
|
}
|
|
|
|
|
|
if (PROPERTY_NDSOBJECT(pThisProperty)) {
|
|
|
|
NdsTypeFreeNdsObjects(
|
|
PROPERTY_NDSOBJECT(pThisProperty),
|
|
PROPERTY_NUMVALUES(pThisProperty)
|
|
);
|
|
PROPERTY_NDSOBJECT(pThisProperty) = NULL;
|
|
}
|
|
|
|
PROPERTY_SYNTAX(pThisProperty) = dwSyntaxId;
|
|
PROPERTY_NUMVALUES(pThisProperty) = dwNumValues;
|
|
|
|
hr = NdsTypeCopyConstruct(
|
|
pNdsObject,
|
|
dwNumValues,
|
|
&pNdsTempObject
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
PROPERTY_NDSOBJECT(pThisProperty) = pNdsTempObject;
|
|
|
|
PROPERTY_FLAGS(pThisProperty) = CACHE_PROPERTY_INITIALIZED;
|
|
|
|
error:
|
|
|
|
RRETURN_EXP_IF_ERR(hr);
|
|
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------------
|
|
//
|
|
// Function: CPropertyCache::findproperty
|
|
//
|
|
// Synopsis:
|
|
//
|
|
//
|
|
//
|
|
// Arguments: [szPropertyName] --
|
|
// [pdwIndex] --
|
|
//
|
|
//-------------------------------------------------------------------------
|
|
HRESULT
|
|
CPropertyCache::
|
|
findproperty(
|
|
LPWSTR szPropertyName,
|
|
PDWORD pdwIndex
|
|
)
|
|
|
|
{
|
|
DWORD i = 0;
|
|
PPROPERTY pThisProperty = NULL;
|
|
|
|
for (i = 0; i < _dwMaxProperties; i++) {
|
|
|
|
pThisProperty = _pProperties + i;
|
|
|
|
if (!_wcsicmp(pThisProperty->szPropertyName, szPropertyName)) {
|
|
*pdwIndex = i;
|
|
RRETURN(S_OK);
|
|
}
|
|
}
|
|
*pdwIndex = 0;
|
|
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_FOUND);
|
|
}
|
|
|
|
//+------------------------------------------------------------------------
|
|
//
|
|
// Function: CPropertyCache::getproperty
|
|
//
|
|
// Synopsis:
|
|
//
|
|
//
|
|
//
|
|
// Arguments: [szPropertyName] -- Property to retrieve from the cache
|
|
// [pvaData] -- Data returned in a variant
|
|
//
|
|
//-------------------------------------------------------------------------
|
|
HRESULT
|
|
CPropertyCache::
|
|
getproperty(
|
|
LPWSTR szPropertyName,
|
|
PDWORD pdwSyntaxId,
|
|
PDWORD pdwNumValues,
|
|
PNDSOBJECT * ppNdsObject
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
DWORD dwIndex = 0L;
|
|
PPROPERTY pThisProperty = NULL;
|
|
|
|
hr = findproperty(
|
|
szPropertyName,
|
|
&dwIndex
|
|
);
|
|
|
|
if (hr == E_ADS_PROPERTY_NOT_FOUND) {
|
|
|
|
//
|
|
// Now call the GetInfo function
|
|
//
|
|
|
|
hr = _pCoreADsObject->GetInfo(
|
|
FALSE
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = findproperty(
|
|
szPropertyName,
|
|
&dwIndex
|
|
);
|
|
|
|
}
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
pThisProperty = _pProperties + dwIndex;
|
|
|
|
if (PROPERTY_NDSOBJECT(pThisProperty)) {
|
|
|
|
*pdwSyntaxId = (DWORD)PROPERTY_SYNTAX(pThisProperty);
|
|
*pdwNumValues = (DWORD)PROPERTY_NUMVALUES(pThisProperty);
|
|
|
|
hr = NdsTypeCopyConstruct(
|
|
PROPERTY_NDSOBJECT(pThisProperty),
|
|
PROPERTY_NUMVALUES(pThisProperty),
|
|
ppNdsObject
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
}else {
|
|
|
|
*ppNdsObject = NULL;
|
|
*pdwNumValues = 0;
|
|
*pdwSyntaxId = 0;
|
|
hr = E_FAIL;
|
|
|
|
}
|
|
|
|
error:
|
|
|
|
RRETURN_EXP_IF_ERR(hr);
|
|
}
|
|
|
|
//+------------------------------------------------------------------------
|
|
//
|
|
// Function: CPropertyCache::putproperty
|
|
//
|
|
// Synopsis:
|
|
//
|
|
//
|
|
//
|
|
// Arguments: [szPropertyName] -- Clsid index
|
|
// [vaData] -- Matching clsid returned in *pclsid
|
|
//
|
|
//-------------------------------------------------------------------------
|
|
HRESULT
|
|
CPropertyCache::
|
|
putproperty(
|
|
LPWSTR szPropertyName,
|
|
DWORD dwFlags,
|
|
DWORD dwSyntaxId,
|
|
DWORD dwNumValues,
|
|
PNDSOBJECT pNdsObject
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
DWORD dwIndex = 0L;
|
|
PNDSOBJECT pNdsTempObject = NULL;
|
|
PPROPERTY pThisProperty = NULL;
|
|
|
|
hr = findproperty(
|
|
szPropertyName,
|
|
&dwIndex
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
pThisProperty = _pProperties + dwIndex;
|
|
|
|
if (PROPERTY_NDSOBJECT(pThisProperty)) {
|
|
|
|
NdsTypeFreeNdsObjects(
|
|
PROPERTY_NDSOBJECT(pThisProperty),
|
|
PROPERTY_NUMVALUES(pThisProperty)
|
|
);
|
|
PROPERTY_NDSOBJECT(pThisProperty) = NULL;
|
|
}
|
|
|
|
|
|
switch (dwFlags) {
|
|
|
|
case CACHE_PROPERTY_MODIFIED:
|
|
|
|
PROPERTY_SYNTAX(pThisProperty) = dwSyntaxId;
|
|
|
|
PROPERTY_NUMVALUES(pThisProperty) = dwNumValues;
|
|
|
|
hr = NdsTypeCopyConstruct(
|
|
pNdsObject,
|
|
dwNumValues,
|
|
&pNdsTempObject
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
PROPERTY_NDSOBJECT(pThisProperty) = pNdsTempObject;
|
|
|
|
PROPERTY_FLAGS(pThisProperty) = CACHE_PROPERTY_MODIFIED;
|
|
break;
|
|
|
|
case CACHE_PROPERTY_CLEARED:
|
|
|
|
PROPERTY_SYNTAX(pThisProperty) = dwSyntaxId;
|
|
|
|
PROPERTY_NUMVALUES(pThisProperty) = 0;
|
|
|
|
PROPERTY_NDSOBJECT(pThisProperty) = NULL;
|
|
|
|
PROPERTY_FLAGS(pThisProperty) = CACHE_PROPERTY_CLEARED;
|
|
|
|
break;
|
|
|
|
|
|
case CACHE_PROPERTY_APPENDED:
|
|
|
|
PROPERTY_SYNTAX(pThisProperty) = dwSyntaxId;
|
|
|
|
PROPERTY_NUMVALUES(pThisProperty) = dwNumValues;
|
|
|
|
hr = NdsTypeCopyConstruct(
|
|
pNdsObject,
|
|
dwNumValues,
|
|
&pNdsTempObject
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
PROPERTY_NDSOBJECT(pThisProperty) = pNdsTempObject;
|
|
|
|
PROPERTY_FLAGS(pThisProperty) = CACHE_PROPERTY_APPENDED;
|
|
break;
|
|
|
|
|
|
case CACHE_PROPERTY_DELETED:
|
|
|
|
PROPERTY_SYNTAX(pThisProperty) = dwSyntaxId;
|
|
|
|
PROPERTY_NUMVALUES(pThisProperty) = dwNumValues;
|
|
|
|
hr = NdsTypeCopyConstruct(
|
|
pNdsObject,
|
|
dwNumValues,
|
|
&pNdsTempObject
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
PROPERTY_NDSOBJECT(pThisProperty) = pNdsTempObject;
|
|
|
|
PROPERTY_FLAGS(pThisProperty) = CACHE_PROPERTY_DELETED;
|
|
break;
|
|
|
|
}
|
|
|
|
error:
|
|
RRETURN_EXP_IF_ERR(hr);
|
|
}
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------------
|
|
//
|
|
// Function: CPropertyCache
|
|
//
|
|
// Synopsis:
|
|
//
|
|
//
|
|
//
|
|
// Arguments:
|
|
//
|
|
//
|
|
//-------------------------------------------------------------------------
|
|
CPropertyCache::
|
|
CPropertyCache():
|
|
_dwMaxProperties(0),
|
|
_dwCurrentIndex(0),
|
|
_pProperties(NULL),
|
|
_cb(0),
|
|
_pCoreADsObject(NULL)
|
|
{
|
|
|
|
}
|
|
|
|
//+------------------------------------------------------------------------
|
|
//
|
|
// Function: ~CPropertyCache
|
|
//
|
|
// Synopsis:
|
|
//
|
|
//
|
|
//
|
|
// Arguments:
|
|
//
|
|
//
|
|
//-------------------------------------------------------------------------
|
|
CPropertyCache::
|
|
~CPropertyCache()
|
|
{
|
|
DWORD i = 0;
|
|
PPROPERTY pThisProperty = NULL;
|
|
|
|
if (_pProperties) {
|
|
|
|
for (i = 0; i < _dwMaxProperties; i++) {
|
|
|
|
pThisProperty = _pProperties + i;
|
|
|
|
if (pThisProperty->szPropertyName){
|
|
FreeADsStr(pThisProperty->szPropertyName);
|
|
pThisProperty->szPropertyName = NULL;
|
|
}
|
|
|
|
if (PROPERTY_NDSOBJECT(pThisProperty)) {
|
|
|
|
NdsTypeFreeNdsObjects(
|
|
PROPERTY_NDSOBJECT(pThisProperty),
|
|
PROPERTY_NUMVALUES(pThisProperty)
|
|
);
|
|
PROPERTY_NDSOBJECT(pThisProperty) = NULL;
|
|
}
|
|
}
|
|
|
|
FreeADsMem(_pProperties);
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------------
|
|
//
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
//
|
|
//
|
|
// Arguments:
|
|
//
|
|
//
|
|
//-------------------------------------------------------------------------
|
|
HRESULT
|
|
CPropertyCache::
|
|
createpropertycache(
|
|
CCoreADsObject FAR * pCoreADsObject,
|
|
CPropertyCache FAR *FAR * ppPropertyCache
|
|
)
|
|
{
|
|
CPropertyCache FAR * pPropertyCache = NULL;
|
|
|
|
pPropertyCache = new CPropertyCache();
|
|
|
|
if (!pPropertyCache) {
|
|
RRETURN_EXP_IF_ERR(E_OUTOFMEMORY);
|
|
}
|
|
|
|
pPropertyCache->_pCoreADsObject = pCoreADsObject;
|
|
|
|
*ppPropertyCache = pPropertyCache;
|
|
|
|
RRETURN(S_OK);
|
|
}
|
|
|
|
//+------------------------------------------------------------------------
|
|
//
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
//
|
|
//
|
|
// Arguments:
|
|
//
|
|
//
|
|
//-------------------------------------------------------------------------
|
|
|
|
HRESULT
|
|
CPropertyCache::
|
|
unmarshallproperty(
|
|
LPWSTR szPropertyName,
|
|
LPBYTE lpValue,
|
|
DWORD dwNumValues,
|
|
DWORD dwSyntaxId,
|
|
BOOL fExplicit
|
|
)
|
|
{
|
|
|
|
DWORD dwIndex = 0;
|
|
HRESULT hr = S_OK;
|
|
PNDSOBJECT pNdsObject = NULL;
|
|
|
|
hr = UnMarshallNDSToNDSSynId(
|
|
dwSyntaxId,
|
|
dwNumValues,
|
|
lpValue,
|
|
&pNdsObject
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
//
|
|
// Find this property in the cache
|
|
//
|
|
|
|
hr = findproperty(
|
|
szPropertyName,
|
|
&dwIndex
|
|
);
|
|
|
|
//
|
|
// If this property does not exist in the
|
|
// cache, add this property into the cache.
|
|
//
|
|
|
|
|
|
if (FAILED(hr)) {
|
|
hr = addproperty(
|
|
szPropertyName,
|
|
dwSyntaxId
|
|
);
|
|
|
|
//
|
|
// If the operation fails for some reason
|
|
// move on to the next property
|
|
//
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
}
|
|
|
|
//
|
|
// Now update the property in the cache
|
|
//
|
|
|
|
hr = updateproperty(
|
|
szPropertyName,
|
|
dwSyntaxId,
|
|
dwNumValues,
|
|
pNdsObject,
|
|
fExplicit
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
if (pNdsObject) {
|
|
NdsTypeFreeNdsObjects(
|
|
pNdsObject,
|
|
dwNumValues
|
|
);
|
|
|
|
}
|
|
|
|
RRETURN_EXP_IF_ERR(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CPropertyCache::
|
|
NDSUnMarshallProperties(
|
|
HANDLE hOperationData,
|
|
BOOL fExplicit
|
|
)
|
|
|
|
{
|
|
DWORD dwNumberOfEntries = 0L;
|
|
LPNDS_ATTR_INFO lpEntries = NULL;
|
|
HRESULT hr = S_OK;
|
|
DWORD i = 0;
|
|
DWORD dwStatus = 0L;
|
|
|
|
//
|
|
// Compute the number of attributes in the
|
|
// read buffer.
|
|
//
|
|
|
|
dwStatus = NwNdsGetAttrListFromBuffer(
|
|
hOperationData,
|
|
&dwNumberOfEntries,
|
|
&lpEntries
|
|
);
|
|
|
|
CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
|
|
|
|
for (i = 0; i < dwNumberOfEntries; i++) {
|
|
|
|
//
|
|
// unmarshall this property into the
|
|
// property cache
|
|
//
|
|
|
|
hr = unmarshallproperty(
|
|
lpEntries[i].szAttributeName,
|
|
lpEntries[i].lpValue,
|
|
lpEntries[i].dwNumberOfValues,
|
|
lpEntries[i].dwSyntaxId,
|
|
fExplicit
|
|
);
|
|
|
|
CONTINUE_ON_FAILURE(hr);
|
|
|
|
}
|
|
|
|
error:
|
|
|
|
RRETURN_EXP_IF_ERR(hr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HRESULT
|
|
CPropertyCache::
|
|
marshallproperty(
|
|
HANDLE hOperationData,
|
|
LPWSTR szPropertyName,
|
|
DWORD dwFlags,
|
|
LPBYTE lpValues,
|
|
DWORD dwNumValues,
|
|
DWORD dwSyntaxId
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD dwStatus;
|
|
|
|
|
|
switch (dwFlags) {
|
|
|
|
case CACHE_PROPERTY_MODIFIED:
|
|
dwStatus = NwNdsPutInBuffer(
|
|
szPropertyName,
|
|
dwSyntaxId,
|
|
NULL,
|
|
0,
|
|
NDS_ATTR_CLEAR,
|
|
hOperationData
|
|
);
|
|
|
|
CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
|
|
|
|
dwStatus = NwNdsPutInBuffer(
|
|
szPropertyName,
|
|
dwSyntaxId,
|
|
lpValues,
|
|
dwNumValues,
|
|
NDS_ATTR_ADD,
|
|
hOperationData
|
|
);
|
|
|
|
CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
|
|
break;
|
|
|
|
case CACHE_PROPERTY_CLEARED:
|
|
|
|
dwStatus = NwNdsPutInBuffer(
|
|
szPropertyName,
|
|
dwSyntaxId,
|
|
NULL,
|
|
0,
|
|
NDS_ATTR_CLEAR,
|
|
hOperationData
|
|
);
|
|
|
|
CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
|
|
break;
|
|
|
|
|
|
case CACHE_PROPERTY_APPENDED:
|
|
dwStatus = NwNdsPutInBuffer(
|
|
szPropertyName,
|
|
dwSyntaxId,
|
|
lpValues,
|
|
dwNumValues,
|
|
NDS_ATTR_ADD_VALUE,
|
|
hOperationData
|
|
);
|
|
|
|
CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
|
|
break;
|
|
|
|
|
|
case CACHE_PROPERTY_DELETED:
|
|
dwStatus = NwNdsPutInBuffer(
|
|
szPropertyName,
|
|
dwSyntaxId,
|
|
lpValues,
|
|
dwNumValues,
|
|
NDS_ATTR_REMOVE_VALUE,
|
|
hOperationData
|
|
);
|
|
|
|
CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
|
|
break;
|
|
|
|
|
|
default:
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
#if DBG
|
|
|
|
NDSMarshallDebugOut((
|
|
DEB_TRACE,
|
|
"dwSyntaxId: %ld \n", dwSyntaxId
|
|
));
|
|
#endif
|
|
|
|
|
|
error:
|
|
|
|
RRETURN_EXP_IF_ERR(hr);
|
|
|
|
}
|
|
|
|
HRESULT
|
|
CPropertyCache::
|
|
NDSMarshallProperties(
|
|
HANDLE hOperationData
|
|
)
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
DWORD i = 0;
|
|
PPROPERTY pThisProperty = NULL;
|
|
BYTE lpBuffer[2048];
|
|
|
|
for (i = 0; i < _dwMaxProperties ; i++) {
|
|
|
|
pThisProperty = _pProperties + i;
|
|
|
|
//
|
|
// Bypass any property that has not been
|
|
// modified
|
|
//
|
|
|
|
if (PROPERTY_FLAGS(pThisProperty) == 0) {
|
|
|
|
continue;
|
|
}
|
|
|
|
|
|
hr = MarshallNDSSynIdToNDS(
|
|
PROPERTY_SYNTAX(pThisProperty),
|
|
PROPERTY_NDSOBJECT(pThisProperty),
|
|
PROPERTY_NUMVALUES(pThisProperty),
|
|
lpBuffer
|
|
);
|
|
CONTINUE_ON_FAILURE(hr);
|
|
|
|
|
|
hr = marshallproperty(
|
|
hOperationData,
|
|
PROPERTY_NAME(pThisProperty),
|
|
PROPERTY_FLAGS(pThisProperty),
|
|
lpBuffer,
|
|
PROPERTY_NUMVALUES(pThisProperty),
|
|
PROPERTY_SYNTAX(pThisProperty)
|
|
);
|
|
CONTINUE_ON_FAILURE(hr);
|
|
|
|
if (PROPERTY_NDSOBJECT(pThisProperty)) {
|
|
FreeMarshallMemory(
|
|
PROPERTY_SYNTAX(pThisProperty),
|
|
PROPERTY_NUMVALUES(pThisProperty),
|
|
lpBuffer
|
|
);
|
|
|
|
NdsTypeFreeNdsObjects(
|
|
PROPERTY_NDSOBJECT(pThisProperty),
|
|
PROPERTY_NUMVALUES(pThisProperty)
|
|
);
|
|
PROPERTY_NDSOBJECT(pThisProperty) = NULL;
|
|
}
|
|
|
|
wcscpy(pThisProperty->szPropertyName, TEXT(""));
|
|
PROPERTY_SYNTAX(pThisProperty) = 0;
|
|
PROPERTY_NUMVALUES(pThisProperty) = 0;
|
|
PROPERTY_FLAGS(pThisProperty) = CACHE_PROPERTY_INITIALIZED;
|
|
|
|
}
|
|
|
|
RRETURN_EXP_IF_ERR(hr);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------------
|
|
//
|
|
// Function: CPropertyCache::getproperty
|
|
//
|
|
// Synopsis:
|
|
//
|
|
//
|
|
//
|
|
// Arguments: [szPropertyName] -- Property to retrieve from the cache
|
|
// [pvaData] -- Data returned in a variant
|
|
//
|
|
//-------------------------------------------------------------------------
|
|
HRESULT
|
|
CPropertyCache::
|
|
unboundgetproperty(
|
|
LPWSTR szPropertyName,
|
|
PDWORD pdwSyntaxId,
|
|
PDWORD pdwNumValues,
|
|
PNDSOBJECT * ppNdsObject
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
DWORD dwIndex = 0L;
|
|
PPROPERTY pThisProperty = NULL;
|
|
|
|
hr = findproperty(
|
|
szPropertyName,
|
|
&dwIndex
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
pThisProperty = _pProperties + dwIndex;
|
|
|
|
if (PROPERTY_NDSOBJECT(pThisProperty)) {
|
|
|
|
*pdwSyntaxId = (DWORD)PROPERTY_SYNTAX(pThisProperty);
|
|
*pdwNumValues = (DWORD)PROPERTY_NUMVALUES(pThisProperty);
|
|
|
|
hr = NdsTypeCopyConstruct(
|
|
PROPERTY_NDSOBJECT(pThisProperty),
|
|
PROPERTY_NUMVALUES(pThisProperty),
|
|
ppNdsObject
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
}else {
|
|
|
|
*ppNdsObject = NULL;
|
|
*pdwNumValues = 0;
|
|
*pdwSyntaxId = 0;
|
|
//hr = E_FAIL;
|
|
|
|
}
|
|
|
|
error:
|
|
|
|
RRETURN_EXP_IF_ERR(hr);
|
|
}
|
|
|
|
//+------------------------------------------------------------------------
|
|
//
|
|
// Function: ~CPropertyCache
|
|
//
|
|
// Synopsis:
|
|
//
|
|
//
|
|
//
|
|
// Arguments:
|
|
//
|
|
//
|
|
//-------------------------------------------------------------------------
|
|
void
|
|
CPropertyCache::
|
|
flushpropcache()
|
|
{
|
|
DWORD i = 0;
|
|
PPROPERTY pThisProperty = NULL;
|
|
|
|
if (_pProperties) {
|
|
|
|
for (i = 0; i < _dwMaxProperties; i++) {
|
|
|
|
pThisProperty = _pProperties + i;
|
|
|
|
if (pThisProperty->szPropertyName) {
|
|
FreeADsStr(pThisProperty->szPropertyName);
|
|
pThisProperty->szPropertyName = NULL;
|
|
}
|
|
|
|
if (PROPERTY_NDSOBJECT(pThisProperty)) {
|
|
|
|
NdsTypeFreeNdsObjects(
|
|
PROPERTY_NDSOBJECT(pThisProperty),
|
|
PROPERTY_NUMVALUES(pThisProperty)
|
|
);
|
|
PROPERTY_NDSOBJECT(pThisProperty) = NULL;
|
|
}
|
|
}
|
|
|
|
FreeADsMem(_pProperties);
|
|
}
|
|
|
|
//
|
|
// Reset the property cache
|
|
//
|
|
|
|
_pProperties = NULL;
|
|
_dwMaxProperties = 0;
|
|
_cb = 0;
|
|
_dwCurrentIndex = 0;
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------------
|
|
//
|
|
// Function: CPropertyCache::getproperty
|
|
//
|
|
// Synopsis:
|
|
//
|
|
//
|
|
//
|
|
// Arguments: [szPropertyName] -- Property to retrieve from the cache
|
|
// [pvaData] -- Data returned in a variant
|
|
//
|
|
//-------------------------------------------------------------------------
|
|
HRESULT
|
|
CPropertyCache::
|
|
unboundgetproperty(
|
|
DWORD dwIndex,
|
|
PDWORD pdwSyntaxId,
|
|
PDWORD pdwNumValues,
|
|
PNDSOBJECT * ppNdsObject
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
PPROPERTY pThisProperty = NULL;
|
|
|
|
if (!_pProperties) {
|
|
RRETURN_EXP_IF_ERR(E_FAIL);
|
|
}
|
|
|
|
|
|
if (((LONG)dwIndex < 0) || dwIndex > (_dwMaxProperties - 1) )
|
|
RRETURN_EXP_IF_ERR(E_FAIL);
|
|
|
|
pThisProperty = _pProperties + dwIndex;
|
|
|
|
if (PROPERTY_NDSOBJECT(pThisProperty)) {
|
|
|
|
*pdwSyntaxId = (DWORD)PROPERTY_SYNTAX(pThisProperty);
|
|
*pdwNumValues = (DWORD)PROPERTY_NUMVALUES(pThisProperty);
|
|
|
|
hr = NdsTypeCopyConstruct(
|
|
PROPERTY_NDSOBJECT(pThisProperty),
|
|
PROPERTY_NUMVALUES(pThisProperty),
|
|
ppNdsObject
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
}else {
|
|
|
|
*ppNdsObject = NULL;
|
|
*pdwNumValues = 0;
|
|
*pdwSyntaxId = 0;
|
|
//hr = E_FAIL;
|
|
|
|
}
|
|
|
|
error:
|
|
|
|
RRETURN_EXP_IF_ERR(hr);
|
|
}
|
|
|
|
BOOL
|
|
CPropertyCache::
|
|
index_valid(
|
|
)
|
|
{
|
|
//
|
|
// NOTE: - _dwCurrentIndex is of type DWORD which is unsigned long.
|
|
// - _dwMaxProperties -1 is also of type unsigned long (so
|
|
// if _dwMaxProperites = 0, _dwMaxproperties -1 = 0xffffff)
|
|
// - comparision checking must taken the above into account
|
|
// for proper checking
|
|
//
|
|
|
|
if ( (_dwMaxProperties==0) || (_dwCurrentIndex >_dwMaxProperties-1) )
|
|
return(FALSE);
|
|
else
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
BOOL
|
|
CPropertyCache::
|
|
index_valid(
|
|
DWORD dwIndex
|
|
)
|
|
{
|
|
//
|
|
// NOTE: - _dwIndex is of type DWORD which is unsigned long.
|
|
// - _dwMaxProperties -1 is also of type unsigned long (so
|
|
// if _dwMaxProperites = 0, _dwMaxproperties -1 = 0xffffff)
|
|
// - comparision checking must taken the above into account
|
|
// for proper checking
|
|
//
|
|
|
|
if ( (_dwMaxProperties==0) || (dwIndex >_dwMaxProperties-1) )
|
|
return(FALSE);
|
|
else
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
void
|
|
CPropertyCache::
|
|
reset_propindex(
|
|
)
|
|
{
|
|
_dwCurrentIndex = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT
|
|
CPropertyCache::
|
|
skip_propindex(
|
|
DWORD dwElements
|
|
)
|
|
{
|
|
DWORD newIndex = _dwCurrentIndex + dwElements;
|
|
|
|
if (!index_valid())
|
|
RRETURN_EXP_IF_ERR(E_FAIL);
|
|
|
|
//
|
|
// - allow current index to go from within range to out of range by 1
|
|
// - by 1 since initial state is out of range by 1
|
|
//
|
|
|
|
if ( newIndex > _dwMaxProperties )
|
|
RRETURN_EXP_IF_ERR(E_FAIL);
|
|
|
|
_dwCurrentIndex = newIndex;
|
|
RRETURN(S_OK);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CPropertyCache::
|
|
get_PropertyCount(
|
|
PDWORD pdwMaxProperties
|
|
)
|
|
{
|
|
*pdwMaxProperties = _dwMaxProperties;
|
|
|
|
RRETURN(S_OK);
|
|
}
|
|
|
|
|
|
DWORD
|
|
CPropertyCache::
|
|
get_CurrentIndex(
|
|
)
|
|
{
|
|
return(_dwCurrentIndex);
|
|
}
|
|
|
|
|
|
LPWSTR
|
|
CPropertyCache::
|
|
get_CurrentPropName(
|
|
)
|
|
|
|
{
|
|
PPROPERTY pThisProperty = NULL;
|
|
|
|
if (!index_valid())
|
|
return(NULL);
|
|
|
|
pThisProperty = _pProperties + _dwCurrentIndex;
|
|
|
|
return(PROPERTY_NAME(pThisProperty));
|
|
}
|
|
|
|
|
|
LPWSTR
|
|
CPropertyCache::
|
|
get_PropName(
|
|
DWORD dwIndex
|
|
)
|
|
|
|
{
|
|
PPROPERTY pThisProperty = NULL;
|
|
|
|
if (!index_valid(dwIndex))
|
|
return(NULL);
|
|
|
|
pThisProperty = _pProperties + dwIndex;
|
|
|
|
return(PROPERTY_NAME(pThisProperty));
|
|
}
|
|
|
|
|
|
|
|
HRESULT
|
|
CPropertyCache::
|
|
deleteproperty(
|
|
DWORD dwIndex
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
PPROPERTY pNewProperties = NULL;
|
|
PPROPERTY pThisProperty = _pProperties + dwIndex;
|
|
|
|
if (!index_valid(dwIndex)) {
|
|
hr = E_FAIL;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
if (_dwMaxProperties == 1) {
|
|
//
|
|
// Deleting everything
|
|
//
|
|
if (PROPERTY_NDSOBJECT(pThisProperty)) {
|
|
NdsTypeFreeNdsObjects(
|
|
PROPERTY_NDSOBJECT(pThisProperty),
|
|
PROPERTY_NUMVALUES(pThisProperty)
|
|
);
|
|
PROPERTY_NDSOBJECT(pThisProperty) = NULL;
|
|
}
|
|
|
|
FreeADsMem(_pProperties);
|
|
_pProperties = NULL;
|
|
_dwMaxProperties = 0;
|
|
_cb = 0;
|
|
//
|
|
// Reset the current index just in case
|
|
//
|
|
_dwCurrentIndex = 0;
|
|
RRETURN(hr);
|
|
}
|
|
|
|
pNewProperties = (PPROPERTY)AllocADsMem(
|
|
_cb - sizeof(PROPERTY)
|
|
);
|
|
if (!pNewProperties) {
|
|
hr = E_OUTOFMEMORY;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
//
|
|
// Copying the memory before the deleted item
|
|
//
|
|
if (dwIndex != 0) {
|
|
memcpy( pNewProperties,
|
|
_pProperties,
|
|
dwIndex * sizeof(PROPERTY));
|
|
}
|
|
|
|
//
|
|
// Copying the memory following the deleted item
|
|
//
|
|
if (dwIndex != (_dwMaxProperties-1)) {
|
|
memcpy( pNewProperties + dwIndex,
|
|
_pProperties + dwIndex + 1,
|
|
(_dwMaxProperties - dwIndex - 1) * sizeof(PROPERTY));
|
|
}
|
|
|
|
if (PROPERTY_NDSOBJECT(pThisProperty)) {
|
|
NdsTypeFreeNdsObjects(
|
|
PROPERTY_NDSOBJECT(pThisProperty),
|
|
PROPERTY_NUMVALUES(pThisProperty)
|
|
);
|
|
PROPERTY_NDSOBJECT(pThisProperty) = NULL;
|
|
}
|
|
FreeADsMem(_pProperties);
|
|
_pProperties = pNewProperties;
|
|
_dwMaxProperties--;
|
|
_cb -= sizeof(PROPERTY);
|
|
//
|
|
// Reset the current index if necesary so we do not skip a property.
|
|
//
|
|
if (_dwCurrentIndex > dwIndex) {
|
|
_dwCurrentIndex--;
|
|
}
|
|
error:
|
|
|
|
RRETURN_EXP_IF_ERR(hr);
|
|
}
|
|
|