Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

767 lines
15 KiB

//+---------------------------------------------------------------------------
//
// 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);
}