/*++ Copyright (c) 1998 Microsoft Corporation Module Name: cmmsprop.cpp Abstract: This module contains the implementation of the special property class Author: Keith Lau (keithlau@microsoft.com) Revision History: keithlau 04/19/98 created --*/ #include "windows.h" #include #include "dbgtrace.h" #include "cmmsprop.h" // ================================================================= // Implementation of CSpecialPropertyTable // int __cdecl CompareProperties(const void *pElem1, const void *pElem2) { return( (((LPSPECIAL_PROPERTY_ITEM)pElem1)->idProp == ((LPSPECIAL_PROPERTY_ITEM)pElem2)->idProp) ? 0 : ((((LPSPECIAL_PROPERTY_ITEM)pElem1)->idProp > ((LPSPECIAL_PROPERTY_ITEM)pElem2)->idProp) ? 1 : -1) ); } CSpecialPropertyTable::CSpecialPropertyTable( LPPTABLE pPropertyTable ) { _ASSERT(pPropertyTable); _ASSERT(pPropertyTable->pProperties); m_pProperties = pPropertyTable->pProperties; m_dwProperties = pPropertyTable->dwProperties; m_fIsSorted = pPropertyTable->fIsSorted; } CSpecialPropertyTable::~CSpecialPropertyTable() { } HRESULT CSpecialPropertyTable::GetProperty( PROP_ID idProp, LPVOID pContext, LPVOID pParam, DWORD ptBaseType, DWORD cbLength, DWORD *pcbLength, LPBYTE pbBuffer, BOOL fCheckAccess ) { HRESULT hrRes = S_OK; LPSPECIAL_PROPERTY_ITEM pItem; TraceFunctEnterEx((LPARAM)this, "CSpecialPropertyTable::GetProperty"); if (!pcbLength || !pbBuffer) return(E_POINTER); // Find the property pItem = SearchForProperty(idProp); // Found? if (pItem) { // Access check if applicable if (fCheckAccess && !(pItem->fAccess & PA_READ)) hrRes = E_ACCESSDENIED; else { // Check the type if ((ptBaseType != PT_NONE) && (ptBaseType != pItem->ptBaseType)) hrRes = TYPE_E_TYPEMISMATCH; else { // Call the special get accessor hrRes = pItem->pfnGetAccessor( idProp, pContext, pParam, cbLength, pcbLength, pbBuffer); } } } else hrRes = S_FALSE; TraceFunctLeave(); return(hrRes); } HRESULT CSpecialPropertyTable::PutProperty( PROP_ID idProp, LPVOID pContext, LPVOID pParam, DWORD ptBaseType, DWORD cbLength, LPBYTE pbBuffer, BOOL fCheckAccess ) { HRESULT hrRes = S_OK; LPSPECIAL_PROPERTY_ITEM pItem; TraceFunctEnterEx((LPARAM)this, "CSpecialPropertyTable::PutProperty"); if (!pbBuffer) return(E_POINTER); // Find the property pItem = SearchForProperty(idProp); // Found? if (pItem) { // Access check if applicable if (fCheckAccess && !(pItem->fAccess & PA_WRITE)) hrRes = E_ACCESSDENIED; else { // Check the type if ((ptBaseType != PT_NONE) && (ptBaseType != pItem->ptBaseType)) hrRes = TYPE_E_TYPEMISMATCH; else { // Call the special put accessor hrRes = pItem->pfnPutAccessor( idProp, pContext, pParam, cbLength, pbBuffer); } } } else hrRes = S_FALSE; TraceFunctLeave(); return(hrRes); } LPSPECIAL_PROPERTY_ITEM CSpecialPropertyTable::SearchForProperty( PROP_ID idProp ) { LPSPECIAL_PROPERTY_ITEM pItem = NULL; TraceFunctEnter("CSpecialPropertyTable::SearchForProperty"); // If the table is sorted, we do a bsearch, otherwise we do // a inear search if (m_fIsSorted) { SPECIAL_PROPERTY_ITEM KeyItem; DebugTrace(NULL, "Property table is sorted"); // Fill in the property name to look for KeyItem.idProp = idProp; // Bsearch pItem = (LPSPECIAL_PROPERTY_ITEM)bsearch( &KeyItem, m_pProperties, m_dwProperties, sizeof(SPECIAL_PROPERTY_ITEM), CompareProperties); } else { DWORD i; LPSPECIAL_PROPERTY_ITEM pCurrentItem; DebugTrace(NULL, "Property table is not sorted"); // Linear search pItem = NULL; for (i = 0, pCurrentItem = m_pProperties; i < m_dwProperties; i++, pCurrentItem++) if (pCurrentItem->idProp == idProp) { pItem = pCurrentItem; break; } } TraceFunctLeave(); return(pItem); }