CPROPS.CPP

/*++ 

Copyright (c) 1996 Microsoft Corporation

Module Name:

CProps.cpp

Abstract:

Property Cache functionality

Author:

Environment:

User mode

Revision History :

--*/
#include "adssmp.h"
#pragma hdrstop


//+------------------------------------------------------------------------
//
// Function: CPropertyCache::addproperty
//
// Synopsis:
//
//
//
// Arguments: [szPropertyName] --
// [vt] --
// [vaData] --
//
//
//-------------------------------------------------------------------------
HRESULT
CPropertyCache::
addproperty(
LPWSTR szPropertyName,
DWORD dwSyntaxId,
DWORD dwNumValues,
PSampleDSOBJECT pSampleDSObject
)
{
HRESULT hr = S_OK;
PPROPERTY pNewProperty = NULL;

//
// extend the property cache by adding a new property entry
//

_pProperties = (PPROPERTY)ReallocProvMem(
_pProperties,
_cb,
_cb + sizeof(PROPERTY)
);
if (!_pProperties) {
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}


pNewProperty = (PPROPERTY)((LPBYTE)_pProperties + _cb);

wcscpy(pNewProperty->szPropertyName, szPropertyName);

//
// Update the index
//

_dwMaxProperties++;
_cb += sizeof(PROPERTY);

error:
RRETURN(hr);
}


//+------------------------------------------------------------------------
//
// Function: CPropertyCache::updateproperty
//
// Synopsis:
//
//
//
// Arguments: [szPropertyName] --
// [vaData] --
//
//-------------------------------------------------------------------------
HRESULT
CPropertyCache::
updateproperty(
LPWSTR szPropertyName,
DWORD dwSyntaxId,
DWORD dwNumValues,
PSampleDSOBJECT pSampleDSObject,
BOOL fExplicit
)
{
HRESULT hr;
DWORD dwIndex;
PSampleDSOBJECT 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) {
hr = S_OK;
goto error;
}
}


if (PROPERTY_SampleDSOBJECT(pThisProperty)) {

SampleDSTypeFreeSampleDSObjects(
PROPERTY_SampleDSOBJECT(pThisProperty),
PROPERTY_NUMVALUES(pThisProperty)
);
PROPERTY_SampleDSOBJECT(pThisProperty) = NULL;
}
PROPERTY_SYNTAX(pThisProperty) = dwSyntaxId;
PROPERTY_NUMVALUES(pThisProperty) = dwNumValues;

hr = SampleDSTypeCopyConstruct(
pSampleDSObject,
dwNumValues,
&pNdsTempObject
);
BAIL_ON_FAILURE(hr);

PROPERTY_SampleDSOBJECT(pThisProperty) = pNdsTempObject;

PROPERTY_FLAGS(pThisProperty) &= ~CACHE_PROPERTY_MODIFIED;

error:

RRETURN(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(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,
PSampleDSOBJECT * ppSampleDSObject
)
{
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_SampleDSOBJECT(pThisProperty)) {

*pdwSyntaxId = (DWORD)PROPERTY_SYNTAX(pThisProperty);
*pdwNumValues = (DWORD)PROPERTY_NUMVALUES(pThisProperty);

hr = SampleDSTypeCopyConstruct(
PROPERTY_SampleDSOBJECT(pThisProperty),
PROPERTY_NUMVALUES(pThisProperty),
ppSampleDSObject
);
BAIL_ON_FAILURE(hr);

}else {

*ppSampleDSObject = NULL;
*pdwNumValues = 0;
*pdwSyntaxId = 0;
hr = E_FAIL;

}

error:

RRETURN(hr);
}

//+------------------------------------------------------------------------
//
// Function: CPropertyCache::putproperty
//
// Synopsis:
//
//
//
// Arguments: [szPropertyName] -- Clsid index
// [vaData] -- Matching clsid returned in *pclsid
//
//-------------------------------------------------------------------------
HRESULT
CPropertyCache::
putproperty(
LPWSTR szPropertyName,
DWORD dwSyntaxId,
DWORD dwNumValues,
PSampleDSOBJECT pSampleDSOBJECT
)
{
HRESULT hr;
DWORD dwIndex = 0L;
PSampleDSOBJECT pSampleDSTempObject = NULL;
PPROPERTY pThisProperty = NULL;

hr = findproperty(
szPropertyName,
&dwIndex
);
BAIL_ON_FAILURE(hr);

pThisProperty = _pProperties + dwIndex;

if (PROPERTY_SampleDSOBJECT(pThisProperty)) {

SampleDSTypeFreeSampleDSObjects(
PROPERTY_SampleDSOBJECT(pThisProperty),
PROPERTY_NUMVALUES(pThisProperty)
);
PROPERTY_SampleDSOBJECT(pThisProperty) = NULL;
}

PROPERTY_SYNTAX(pThisProperty) = dwSyntaxId;
PROPERTY_NUMVALUES(pThisProperty) = dwNumValues;

hr = SampleDSTypeCopyConstruct(
pSampleDSOBJECT,
dwNumValues,
&pSampleDSTempObject
);
BAIL_ON_FAILURE(hr);

PROPERTY_SampleDSOBJECT(pThisProperty) = pSampleDSTempObject;

PROPERTY_FLAGS(pThisProperty) |= CACHE_PROPERTY_MODIFIED;

error:
RRETURN(hr);
}



//+------------------------------------------------------------------------
//
// Function: CPropertyCache
//
// Synopsis:
//
//
//
// Arguments:
//
//
//-------------------------------------------------------------------------
CPropertyCache::
CPropertyCache():
_dwMaxProperties(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 (PROPERTY_SampleDSOBJECT(pThisProperty)) {

SampleDSTypeFreeSampleDSObjects(
PROPERTY_SampleDSOBJECT(pThisProperty),
PROPERTY_NUMVALUES(pThisProperty)
);
PROPERTY_SampleDSOBJECT(pThisProperty) = NULL;
}
}

FreeProvMem(_pProperties);
}
}

//+------------------------------------------------------------------------
//
// Function:
//
// Synopsis:
//
//
//
// Arguments:
//
//
//-------------------------------------------------------------------------
HRESULT
CPropertyCache::
createpropertycache(
CCoreADsObject FAR * pCoreADsObject,
CPropertyCache FAR *FAR * ppPropertyCache
)
{
CPropertyCache FAR * pPropertyCache = NULL;

pPropertyCache = new CPropertyCache();

if (!pPropertyCache) {
RRETURN(E_FAIL);
}

pPropertyCache->_pCoreADsObject = pCoreADsObject;

*ppPropertyCache = pPropertyCache;

RRETURN(S_OK);
}


//+------------------------------------------------------------------------
//
// 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,
PSampleDSOBJECT * ppSampleDSOBJECT
)
{
HRESULT hr;
DWORD dwIndex = 0L;
PPROPERTY pThisProperty = NULL;

hr = findproperty(
szPropertyName,
&dwIndex
);
BAIL_ON_FAILURE(hr);

pThisProperty = _pProperties + dwIndex;

if (PROPERTY_SampleDSOBJECT(pThisProperty)) {

*pdwSyntaxId = (DWORD)PROPERTY_SYNTAX(pThisProperty);
*pdwNumValues = (DWORD)PROPERTY_NUMVALUES(pThisProperty);

hr = SampleDSTypeCopyConstruct(
PROPERTY_SampleDSOBJECT(pThisProperty),
PROPERTY_NUMVALUES(pThisProperty),
ppSampleDSOBJECT
);
BAIL_ON_FAILURE(hr);

}else {

*ppSampleDSOBJECT = NULL;
*pdwNumValues = 0;
*pdwSyntaxId = 0;
hr = E_FAIL;

}

error:

RRETURN(hr);
}



HRESULT
CPropertyCache::
SampleDSMarshallProperties(
HANDLE hOperationData
)
{
LPSampleDS_ATTRS_INFO pAttrsInfo = (LPSampleDS_ATTRS_INFO)hOperationData;
HRESULT hr = S_OK;
DWORD i = 0;
PPROPERTY pThisProperty = NULL;
BYTE lpBuffer[2048];
DWORD cProperty = 0;
LPSampleDS_ATTR_INFO pAttrInfoMemStart = NULL;
LPSampleDS_ATTR_INFO pAttrInfoMem = NULL;
pAttrInfoMemStart = (LPSampleDS_ATTR_INFO)AllocProvMem(
sizeof(SampleDS_ATTR_INFO)*_dwMaxProperties);
if (!pAttrInfoMemStart)
goto Error;

pAttrInfoMem = pAttrInfoMemStart;

for (i = 0; i < _dwMaxProperties ; i++) {

pThisProperty = _pProperties + i;

//
// Bypass any property that has not been
// modified
//

if (PROPERTY_FLAGS(pThisProperty) == 0) {

continue;
}

hr = MarshallSampleDSSynIdToSampleDS(
PROPERTY_SYNTAX(pThisProperty),
PROPERTY_SampleDSOBJECT(pThisProperty),
PROPERTY_NUMVALUES(pThisProperty),
lpBuffer
);
CONTINUE_ON_FAILURE(hr);


hr = marshallproperty(
pAttrInfoMem,
PROPERTY_NAME(pThisProperty),
lpBuffer,
PROPERTY_NUMVALUES(pThisProperty),
PROPERTY_SYNTAX(pThisProperty)
);
CONTINUE_ON_FAILURE(hr);
cProperty++;
pAttrInfoMem++;
}

if (cProperty != _dwMaxProperties) {
LPSampleDS_ATTR_INFO pAttrInfoNew;
pAttrInfoNew = (LPSampleDS_ATTR_INFO)AllocProvMem(
sizeof(SampleDS_ATTR_INFO)*cProperty);
if (!pAttrInfoNew) {
hr = E_FAIL;
goto Error;
}
memcpy( (void*)pAttrInfoNew,
(void*)pAttrInfoMemStart,
sizeof(SampleDS_ATTR_INFO)*cProperty);
FreeProvMem(pAttrInfoMemStart);
pAttrInfoMemStart = pAttrInfoNew;
}
pAttrsInfo->pAttrInfo = pAttrInfoMemStart;
pAttrsInfo->dwAttr = cProperty;
RRETURN(hr);

Error:
if (pAttrInfoMem)
FreeProvMem(pAttrInfoMem);
RRETURN(hr);

}

HRESULT
CPropertyCache::
marshallproperty(
LPSampleDS_ATTR_INFO pAttrInfo,
LPWSTR szPropertyName,
LPBYTE lpValues,
DWORD dwNumValues,
DWORD dwSyntaxId
)
{
pAttrInfo->lpAttributeName = (LPWSTR)AllocProvStr(szPropertyName);
if (!pAttrInfo->lpAttributeName)
RRETURN(E_FAIL);

DWORD dwMemSize;
switch (dwSyntaxId) {
case SampleDS_DATATYPE_1:
dwMemSize = sizeof(SampleDS_TYPE_1);
break;
case SampleDS_DATATYPE_2:
dwMemSize = sizeof(SampleDS_TYPE_2);
break;
default:
goto Error;
}
pAttrInfo->lpValue = (BYTE*)AllocProvMem(dwMemSize);
if (!pAttrInfo->lpValue)
goto Error;
memcpy( (void*)pAttrInfo->lpValue,
(void*)lpValues,
dwMemSize);

pAttrInfo->dwSyntaxId = dwSyntaxId;
pAttrInfo->dwNumberOfValues = dwNumValues;
RRETURN(S_OK);
Error:
if (pAttrInfo->lpAttributeName)
FreeProvMem(pAttrInfo->lpAttributeName);
if (pAttrInfo->lpValue)
FreeProvMem(pAttrInfo->lpValue);
RRETURN(E_FAIL);
}

HRESULT
CPropertyCache::
SampleDSUnMarshallProperties(
HANDLE hOperationData,
BOOL fExplicit
)

{
LPSampleDS_ATTRS_INFO pAttrsInfo = (LPSampleDS_ATTRS_INFO)hOperationData;

DWORD dwNumberOfEntries = 0L;
LPSampleDS_ATTR_INFO lpEntries = pAttrsInfo->pAttrInfo;
DWORD dwEntry = pAttrsInfo->dwAttr;
HRESULT hr = S_OK;
DWORD i = 0;
DWORD dwStatus = 0L;

for (i = 0; i < dwEntry; i++) {

//
// unmarshall this property into the
// property cache
//

hr = unmarshallproperty(
lpEntries[i].lpAttributeName,
lpEntries[i].lpValue,
lpEntries[i].dwNumberOfValues,
lpEntries[i].dwSyntaxId,
fExplicit
);

CONTINUE_ON_FAILURE(hr);

}

RRETURN(hr);

}

//+------------------------------------------------------------------------
//
// Function:
//
// Synopsis:
//
//
//
// Arguments:
//
//
//-------------------------------------------------------------------------

HRESULT
CPropertyCache::
unmarshallproperty(
LPWSTR szPropertyName,
LPBYTE lpValue,
DWORD dwNumValues,
DWORD dwSyntaxId,
BOOL fExplicit
)
{

DWORD dwIndex = 0;
HRESULT hr = S_OK;
PSampleDSOBJECT pSampleDSObject = NULL;

hr = UnMarshallSampleDSToSampleDSSynId(
dwSyntaxId,
dwNumValues,
lpValue,
&pSampleDSObject
);
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,
dwNumValues,
pSampleDSObject
);

//
// 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,
pSampleDSObject,
fExplicit
);
BAIL_ON_FAILURE(hr);


if (pSampleDSObject) {
SampleDSTypeFreeSampleDSObjects(
pSampleDSObject,
dwNumValues
);

}


error:
RRETURN(hr);
}