//+--------------------------------------------------------------------------- // // 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; } // // BugBug: KrishnaG - add the free code! // _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() { // // BugBug: KrishnaG - free each one of the data items // 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; } } } //+------------------------------------------------------------------------ // // 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; NDS_CONTEXT_HANDLE hADsContext = NULL; NDS_BUFFER_HANDLE hOperationData = NULL; PPROPENTRY pPropList = NULL; hr = ADsNdsOpenContext( pszTreeName, Credentials, &hADsContext ); BAIL_ON_FAILURE(hr); hr = ADsNdsReadClassDef( hADsContext, DS_EXPANDED_CLASS_DEFS, &pszClassName, 1, &hOperationData ); BAIL_ON_FAILURE(hr); hr = ADsNdsGetClassDefListFromBuffer( hADsContext, hOperationData, &dwObjectReturned, &dwInfoType, &lpClassDefs ); BAIL_ON_FAILURE(hr); pPropList = GenerateAttrIdList( hADsContext, 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 (hADsContext) { ADsNdsCloseContext(hADsContext); } if (hOperationData) { ADsNdsFreeBuffer(hOperationData); } ADsNdsFreeClassDefList(lpClassDefs, dwObjectReturned); 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 GenerateAttrIdList( NDS_CONTEXT_HANDLE hADsContext, 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]; DWORD dwSyntaxId = 0; HRESULT hr = S_OK; lpTempStrings = lpMandatoryProps; while (lpTempStrings) { wcscpy(szTempBuffer, lpTempStrings->szString); hr = ADsNdsGetSyntaxID( hADsContext, szTempBuffer, &dwSyntaxId ); BAIL_ON_FAILURE(hr); pPropEntry = CreatePropertyEntry( szTempBuffer, dwSyntaxId ); if (!pPropEntry) goto error; pPropEntry->pNext = pStart; pStart = pPropEntry; lpTempStrings = lpTempStrings->Next; } lpTempStrings = lpOptionalProps; while (lpTempStrings) { wcscpy(szTempBuffer, lpTempStrings->szString); hr = ADsNdsGetSyntaxID( hADsContext, szTempBuffer, &dwSyntaxId ); BAIL_ON_FAILURE(hr); pPropEntry = CreatePropertyEntry( szTempBuffer, dwSyntaxId ); if (!pPropEntry) goto error; pPropEntry->pNext = pStart; pStart = pPropEntry; lpTempStrings = lpTempStrings->Next; } error: return(pStart); }