//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1995. // // File: cprops.cxx // // Contents: Class Cache functionality for the NDS Provider // // Functions: // CClassCache::addentry // CClassCache::findentry // CClassCache::getentry // CProperyCache::CClassCache // CClassCache::~CClassCache // CClassCache::CreateClassCache // // History: 25-Apr-96 KrishnaG Created. // //---------------------------------------------------------------------------- #include "nds.hxx" //+------------------------------------------------------------------------ // // Function: CClassCache::addentry // // Synopsis: // // // // Arguments: [pszTreeName] -- // [pszClassName] -- // [pClassEntry] -- // // //------------------------------------------------------------------------- HRESULT CClassCache:: addentry( LPWSTR pszTreeName, LPWSTR pszClassName, PPROPENTRY pPropList ) { HRESULT hr = S_OK; DWORD i = 0; DWORD dwLRUEntry = 0; DWORD dwIndex = 0; PPROPENTRY pNewPropList = NULL; EnterCriticalSection(&_cs); hr = findentry( pszTreeName, pszClassName, &dwIndex ); if (SUCCEEDED(hr)) { hr = E_FAIL; BAIL_ON_FAILURE(hr); } // // Restore yr error code // hr = S_OK; if (_dwMaxCacheSize == 0 ) { LeaveCriticalSection(&_cs); RRETURN(E_FAIL); } for (i = 0; i < _dwMaxCacheSize; i++ ) { if (!_ClassEntries[i].bInUse) { // // Found an available entry; use it // fill in the name of the printer and the providor // that supports this printer. // break; } else { if ((dwLRUEntry == -1) || (i == IsOlderThan(i, dwLRUEntry))){ dwLRUEntry = i; } } } if (i == _dwMaxCacheSize){ // // We have no available entries so we need to use // the LRUEntry which is busy // // // Free this entry // if (_ClassEntries[dwLRUEntry].pPropList) { FreePropertyList(_ClassEntries[dwLRUEntry].pPropList); _ClassEntries[dwLRUEntry].pPropList = NULL; } _ClassEntries[dwLRUEntry].bInUse = FALSE; i = dwLRUEntry; } // // Insert the new entry into the Cache // wcscpy(_ClassEntries[i].szTreeName, pszTreeName); wcscpy(_ClassEntries[i].szClassName, pszClassName); pNewPropList = CopyPropList(pPropList); if (pNewPropList) { _ClassEntries[i].pPropList = pNewPropList; } _ClassEntries[i].bInUse = TRUE; // // update the time stamp so that we know when this entry was made // GetSystemTime(&_ClassEntries[i].st); error: LeaveCriticalSection(&_cs); RRETURN(hr); } //+------------------------------------------------------------------------ // // Function: CClassCache::findentry // // Synopsis: // // // // Arguments: [szPropertyName] -- // [pdwIndex] -- // //------------------------------------------------------------------------- HRESULT CClassCache:: findentry( LPWSTR pszTreeName, LPWSTR pszClassName, PDWORD pdwIndex ) { DWORD i = 0; EnterCriticalSection(&_cs); if (_dwMaxCacheSize == 0 ) { LeaveCriticalSection(&_cs); RRETURN(E_FAIL); } for (i = 0; i < _dwMaxCacheSize; i++ ) { if (_ClassEntries[i].bInUse) { if ((!_wcsicmp(_ClassEntries[i].szTreeName, pszTreeName)) && (!_wcsicmp(_ClassEntries[i].szClassName, pszClassName))) { // // update the time stamp so that it is current and not old // GetSystemTime(&_ClassEntries[i].st); *pdwIndex = i; LeaveCriticalSection(&_cs); RRETURN(S_OK); } } } LeaveCriticalSection(&_cs); RRETURN(E_FAIL); } //+------------------------------------------------------------------------ // // Function: CClassCache::findentry // // Synopsis: // // // // Arguments: [szPropertyName] -- // [pdwIndex] -- // //------------------------------------------------------------------------- HRESULT CClassCache:: getentry( LPWSTR pszTreeName, LPWSTR pszClassName, PPROPENTRY * ppPropList ) { DWORD dwIndex = 0; HRESULT hr = S_OK; PPROPENTRY pPropList = NULL; EnterCriticalSection(&_cs); hr = findentry( pszTreeName, pszClassName, &dwIndex ); BAIL_ON_FAILURE(hr); pPropList = CopyPropList( _ClassEntries[dwIndex].pPropList ); *ppPropList = pPropList; error: LeaveCriticalSection(&_cs); RRETURN(hr); } //+------------------------------------------------------------------------ // // Function: CClassCache // // Synopsis: // // // // Arguments: // // //------------------------------------------------------------------------- CClassCache:: CClassCache(): _dwMaxCacheSize(2) { memset(_ClassEntries, 0, sizeof(CLASSENTRY)); } //+------------------------------------------------------------------------ // // Function: ~CClassCache // // Synopsis: // // // // Arguments: // // //------------------------------------------------------------------------- CClassCache:: ~CClassCache() { DWORD i; for (i = 0; i < _dwMaxCacheSize; i++ ) { if (_ClassEntries[i].bInUse) { if (_ClassEntries[i].pPropList) { FreePropertyList(_ClassEntries[i].pPropList); _ClassEntries[i].pPropList = NULL; } _ClassEntries[i].bInUse = FALSE; } } DeleteCriticalSection(&_cs); } //+------------------------------------------------------------------------ // // Function: // // Synopsis: // // // // Arguments: // // //------------------------------------------------------------------------- HRESULT CClassCache:: CreateClassCache( CClassCache FAR *FAR * ppClassCache ) { CClassCache FAR * pClassCache = NULL; pClassCache = new CClassCache(); if (!pClassCache) { RRETURN(E_FAIL); } InitializeCriticalSection(&(pClassCache->_cs)); *ppClassCache = pClassCache; RRETURN(S_OK); } DWORD CClassCache:: IsOlderThan( DWORD i, DWORD j ) { SYSTEMTIME *pi, *pj; DWORD iMs, jMs; // DBGMSG(DBG_TRACE, ("IsOlderThan entering with i %d j %d\n", i, j)); pi = &(_ClassEntries[i].st); pj = &(_ClassEntries[j].st); if (pi->wYear < pj->wYear) { // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", i)); return(i); } else if (pi->wYear > pj->wYear) { // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", j)); return(j); } else if (pi->wMonth < pj->wMonth) { // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", i)); return(i); } else if (pi->wMonth > pj->wMonth) { // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", j)); return(j); } else if (pi->wDay < pj->wDay) { // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", i)); return(i); } else if (pi->wDay > pj->wDay) { // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", j)); return(j); } else { iMs = ((((pi->wHour * 60) + pi->wMinute)*60) + pi->wSecond)* 1000 + pi->wMilliseconds; jMs = ((((pj->wHour * 60) + pj->wMinute)*60) + pj->wSecond)* 1000 + pj->wMilliseconds; if (iMs <= jMs) { // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", i)); return(i); } else { // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", j)); return(j); } } } HRESULT ValidatePropertyinCache( LPWSTR pszTreeName, LPWSTR pszClassName, LPWSTR pszPropName, CCredentials& Credentials, PDWORD pdwSyntaxId ) { HRESULT hr = S_OK; PPROPENTRY pPropList = NULL; hr = pgClassCache->getentry( pszTreeName, pszClassName, &pPropList ); if (FAILED(hr)) { hr = NdsGetClassInformation( pszTreeName, pszClassName, Credentials, &pPropList ); BAIL_ON_FAILURE(hr); hr = pgClassCache->addentry( pszTreeName, pszClassName, pPropList ); BAIL_ON_FAILURE(hr); } hr = FindProperty( pPropList, pszPropName, pdwSyntaxId ); BAIL_ON_FAILURE(hr); error: if (pPropList) { FreePropertyList(pPropList); } RRETURN(hr); } HRESULT NdsGetClassInformation( LPWSTR pszTreeName, LPWSTR pszClassName, CCredentials& Credentials, PPROPENTRY * ppPropList ) { HRESULT hr = S_OK; LPNDS_CLASS_DEF lpClassDefs = NULL; DWORD dwStatus; DWORD dwObjectReturned = 0; DWORD dwInfoType = 0; HANDLE hTree = NULL; HANDLE hOperationData = NULL; PPROPENTRY pPropList = NULL; dwStatus = ADsNwNdsOpenObject( pszTreeName, Credentials, &hTree, NULL, NULL, NULL, NULL ); CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr); dwStatus = NwNdsCreateBuffer( NDS_SCHEMA_READ_CLASS_DEF, &hOperationData ); CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr); dwStatus = NwNdsPutInBuffer( pszClassName, 0, NULL, 0, 0, hOperationData ); CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr); dwStatus = NwNdsReadClassDef( hTree, NDS_CLASS_INFO_EXPANDED_DEFS, &hOperationData ); CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr); dwStatus = NwNdsGetClassDefListFromBuffer( hOperationData, &dwObjectReturned, &dwInfoType, (LPVOID *) &lpClassDefs ); CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr); pPropList = GenerateAttrIdList( hTree, lpClassDefs->lpMandatoryAttributes, lpClassDefs->lpOptionalAttributes ); /* pPropList = GeneratePropertyAndIdList( pszTreeName, lpClassDefs->lpMandatoryAttributes, lpClassDefs->lpOptionalAttributes );*/ if (!pPropList) { hr = HRESULT_FROM_WIN32(GetLastError()); BAIL_ON_FAILURE(hr); } *ppPropList = pPropList; error: if (hOperationData) { NwNdsFreeBuffer(hOperationData); } if (hTree) { NwNdsCloseObject(hTree); } RRETURN(hr); } PPROPENTRY CreatePropertyEntry( LPWSTR pszPropertyName, DWORD dwSyntaxId ) { LPWSTR pszTemp = NULL; PPROPENTRY pPropName = NULL; pszTemp = (LPWSTR)AllocADsStr( pszPropertyName ); if (!pszTemp) { return(NULL); } pPropName = (PPROPENTRY)AllocADsMem( sizeof(PROPENTRY) ); if (!pPropName) { FreeADsStr(pszTemp); return(NULL); } pPropName->pszPropName = pszTemp; pPropName->dwSyntaxId = dwSyntaxId; return(pPropName); } void FreePropertyEntry( PPROPENTRY pPropName ) { if (pPropName->pszPropName) { FreeADsStr(pPropName->pszPropName); } FreeADsMem(pPropName); return; } void FreePropertyList( PPROPENTRY pPropList ) { PPROPENTRY pTemp = NULL; while (pPropList) { pTemp = pPropList->pNext; FreePropertyEntry(pPropList); pPropList = pTemp; } return; } PPROPENTRY GeneratePropertyList( LPWSTR_LIST lpMandatoryProps, LPWSTR_LIST lpOptionalProps ) { PPROPENTRY pStart = NULL; PPROPENTRY lpProperty = NULL; LPWSTR_LIST lpTempStrings = NULL; lpTempStrings = lpMandatoryProps; while (lpTempStrings) { lpProperty = CreatePropertyEntry( lpTempStrings->szString, 0 ); if (!lpProperty) { goto cleanup; } lpProperty->pNext = pStart; pStart = lpProperty; lpTempStrings = lpTempStrings->Next; } lpTempStrings = lpOptionalProps; while (lpTempStrings) { lpProperty = CreatePropertyEntry( lpTempStrings->szString, 0 ); if (!lpProperty) { goto cleanup; } lpProperty->pNext = pStart; pStart = lpProperty; lpTempStrings = lpTempStrings->Next; } cleanup: return(pStart); } HRESULT FindProperty( PPROPENTRY pPropList, LPWSTR pszPropName, PDWORD pdwSyntaxId ) { while (pPropList) { if (!_wcsicmp(pPropList->pszPropName, pszPropName)) { *pdwSyntaxId = pPropList->dwSyntaxId; RRETURN(S_OK); } pPropList = pPropList->pNext; } RRETURN(E_ADS_PROPERTY_NOT_FOUND); } PPROPENTRY CopyPropList( PPROPENTRY pPropList ) { PPROPENTRY pPropEntry = NULL; PPROPENTRY pStart = NULL; while (pPropList) { pPropEntry = CreatePropertyEntry( pPropList->pszPropName, pPropList->dwSyntaxId ); if (!pPropEntry) { return(pStart); } pPropEntry->pNext = pStart; pStart = pPropEntry; pPropList = pPropList->pNext; } return(pStart); } PPROPENTRY GeneratePropertyAndIdList( LPWSTR pszTreeName, CCredentials& Credentials, LPWSTR_LIST lpMandatoryProps, LPWSTR_LIST lpOptionalProps ) { HANDLE hTree = NULL; PPROPENTRY pStart = NULL; PPROPENTRY pPropEntry = NULL; LPWSTR_LIST lpTempStrings = NULL; HANDLE hOperationData = NULL; DWORD i = 0; WCHAR szTempBuffer[MAX_PATH]; LPNDS_ATTR_DEF lpAttrDefs = NULL; DWORD dwSyntaxId = 0; DWORD dwNumEntries = 0; DWORD dwInfoType = 0; DWORD dwStatus = 0; dwStatus = ADsNwNdsOpenObject( pszTreeName, Credentials, &hTree, NULL, NULL, NULL, NULL ); if (dwStatus) { goto error; } dwStatus = NwNdsCreateBuffer( NDS_SCHEMA_READ_ATTR_DEF, &hOperationData ); if (dwStatus) { goto error; } lpTempStrings = lpMandatoryProps; while (lpTempStrings) { wcscpy(szTempBuffer, lpTempStrings->szString); dwStatus = NwNdsPutInBuffer( szTempBuffer, 0, NULL, 0, 0, hOperationData ); if (dwStatus) { goto error; } lpTempStrings = lpTempStrings->Next; } lpTempStrings = lpOptionalProps; while (lpTempStrings) { wcscpy(szTempBuffer, lpTempStrings->szString); dwStatus = NwNdsPutInBuffer( szTempBuffer, 0, NULL, 0, 0, hOperationData ); if (dwStatus) { goto error; } lpTempStrings = lpTempStrings->Next; } dwStatus = NwNdsReadAttrDef( hTree, NDS_INFO_NAMES_DEFS, &hOperationData ); if (dwStatus) { goto error; } dwStatus = NwNdsGetAttrDefListFromBuffer( hOperationData, &dwNumEntries, &dwInfoType, (LPVOID *)&lpAttrDefs ); if (dwStatus) { goto error; } for (i = 0; i < dwNumEntries; i++){ pPropEntry = CreatePropertyEntry( lpAttrDefs[i].szAttributeName, lpAttrDefs[i].dwSyntaxID ); if (!pPropEntry) { goto error; } pPropEntry->pNext = pStart; pStart = pPropEntry; } error: if (hOperationData) { NwNdsFreeBuffer(hOperationData); } if (hTree) { NwNdsCloseObject(hTree); } return(pStart); } PPROPENTRY GenerateAttrIdList( HANDLE hTree, LPWSTR_LIST lpMandatoryProps, LPWSTR_LIST lpOptionalProps ) { PPROPENTRY pStart = NULL; PPROPENTRY pPropEntry = NULL; LPWSTR_LIST lpTempStrings = NULL; HANDLE hOperationData = NULL; DWORD i = 0; WCHAR szTempBuffer[MAX_PATH]; LPNDS_ATTR_DEF lpAttrDefs = NULL; DWORD dwSyntaxId = 0; DWORD dwNumEntries = 0; DWORD dwInfoType = 0; DWORD dwStatus = 0; lpTempStrings = lpMandatoryProps; while (lpTempStrings) { wcscpy(szTempBuffer, lpTempStrings->szString); dwStatus = NwNdsGetSyntaxID( hTree, szTempBuffer, &dwSyntaxId ); if (dwStatus) { lpTempStrings = lpTempStrings->Next; continue; } pPropEntry = CreatePropertyEntry( szTempBuffer, dwSyntaxId ); if (!pPropEntry) { lpTempStrings = lpTempStrings->Next; continue; } pPropEntry->pNext = pStart; pStart = pPropEntry; lpTempStrings = lpTempStrings->Next; } lpTempStrings = lpOptionalProps; while (lpTempStrings) { wcscpy(szTempBuffer, lpTempStrings->szString); dwStatus = NwNdsGetSyntaxID( hTree, szTempBuffer, &dwSyntaxId ); if (dwStatus) { lpTempStrings = lpTempStrings->Next; continue; } pPropEntry = CreatePropertyEntry( szTempBuffer, dwSyntaxId ); if (!pPropEntry) { lpTempStrings = lpTempStrings->Next; continue; } pPropEntry->pNext = pStart; pStart = pPropEntry; lpTempStrings = lpTempStrings->Next; } return(pStart); }