mirror of https://github.com/tongzx/nt5src
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
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);
|
|
}
|