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

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: cprops.cxx
  7. //
  8. // Contents: Class Cache functionality for the NDS Provider
  9. //
  10. // Functions:
  11. // CClassCache::addentry
  12. // CClassCache::findentry
  13. // CClassCache::getentry
  14. // CProperyCache::CClassCache
  15. // CClassCache::~CClassCache
  16. // CClassCache::CreateClassCache
  17. //
  18. // History: 25-Apr-96 KrishnaG Created.
  19. //
  20. //----------------------------------------------------------------------------
  21. #include "nds.hxx"
  22. //+------------------------------------------------------------------------
  23. //
  24. // Function: CClassCache::addentry
  25. //
  26. // Synopsis:
  27. //
  28. //
  29. //
  30. // Arguments: [pszTreeName] --
  31. // [pszClassName] --
  32. // [pClassEntry] --
  33. //
  34. //
  35. //-------------------------------------------------------------------------
  36. HRESULT
  37. CClassCache::
  38. addentry(
  39. LPWSTR pszTreeName,
  40. LPWSTR pszClassName,
  41. PPROPENTRY pPropList
  42. )
  43. {
  44. HRESULT hr = S_OK;
  45. DWORD i = 0;
  46. DWORD dwLRUEntry = 0;
  47. DWORD dwIndex = 0;
  48. PPROPENTRY pNewPropList = NULL;
  49. EnterCriticalSection(&_cs);
  50. hr = findentry(
  51. pszTreeName,
  52. pszClassName,
  53. &dwIndex
  54. );
  55. if (SUCCEEDED(hr)) {
  56. hr = E_FAIL;
  57. BAIL_ON_FAILURE(hr);
  58. }
  59. //
  60. // Restore yr error code
  61. //
  62. hr = S_OK;
  63. if (_dwMaxCacheSize == 0 ) {
  64. LeaveCriticalSection(&_cs);
  65. RRETURN(E_FAIL);
  66. }
  67. for (i = 0; i < _dwMaxCacheSize; i++ ) {
  68. if (!_ClassEntries[i].bInUse) {
  69. //
  70. // Found an available entry; use it
  71. // fill in the name of the printer and the providor
  72. // that supports this printer.
  73. //
  74. break;
  75. } else {
  76. if ((dwLRUEntry == -1) || (i == IsOlderThan(i, dwLRUEntry))){
  77. dwLRUEntry = i;
  78. }
  79. }
  80. }
  81. if (i == _dwMaxCacheSize){
  82. //
  83. // We have no available entries so we need to use
  84. // the LRUEntry which is busy
  85. //
  86. //
  87. // Free this entry
  88. //
  89. if (_ClassEntries[dwLRUEntry].pPropList) {
  90. FreePropertyList(_ClassEntries[dwLRUEntry].pPropList);
  91. _ClassEntries[dwLRUEntry].pPropList = NULL;
  92. }
  93. //
  94. // BugBug: KrishnaG - add the free code!
  95. //
  96. _ClassEntries[dwLRUEntry].bInUse = FALSE;
  97. i = dwLRUEntry;
  98. }
  99. //
  100. // Insert the new entry into the Cache
  101. //
  102. wcscpy(_ClassEntries[i].szTreeName, pszTreeName);
  103. wcscpy(_ClassEntries[i].szClassName, pszClassName);
  104. pNewPropList = CopyPropList(pPropList);
  105. if (pNewPropList) {
  106. _ClassEntries[i].pPropList = pNewPropList;
  107. }
  108. _ClassEntries[i].bInUse = TRUE;
  109. //
  110. // update the time stamp so that we know when this entry was made
  111. //
  112. GetSystemTime(&_ClassEntries[i].st);
  113. error:
  114. LeaveCriticalSection(&_cs);
  115. RRETURN(hr);
  116. }
  117. //+------------------------------------------------------------------------
  118. //
  119. // Function: CClassCache::findentry
  120. //
  121. // Synopsis:
  122. //
  123. //
  124. //
  125. // Arguments: [szPropertyName] --
  126. // [pdwIndex] --
  127. //
  128. //-------------------------------------------------------------------------
  129. HRESULT
  130. CClassCache::
  131. findentry(
  132. LPWSTR pszTreeName,
  133. LPWSTR pszClassName,
  134. PDWORD pdwIndex
  135. )
  136. {
  137. DWORD i = 0;
  138. EnterCriticalSection(&_cs);
  139. if (_dwMaxCacheSize == 0 ) {
  140. LeaveCriticalSection(&_cs);
  141. RRETURN(E_FAIL);
  142. }
  143. for (i = 0; i < _dwMaxCacheSize; i++ ) {
  144. if (_ClassEntries[i].bInUse) {
  145. if ((!_wcsicmp(_ClassEntries[i].szTreeName, pszTreeName)) &&
  146. (!_wcsicmp(_ClassEntries[i].szClassName, pszClassName))) {
  147. //
  148. // update the time stamp so that it is current and not old
  149. //
  150. GetSystemTime(&_ClassEntries[i].st);
  151. *pdwIndex = i;
  152. LeaveCriticalSection(&_cs);
  153. RRETURN(S_OK);
  154. }
  155. }
  156. }
  157. LeaveCriticalSection(&_cs);
  158. RRETURN(E_FAIL);
  159. }
  160. //+------------------------------------------------------------------------
  161. //
  162. // Function: CClassCache::findentry
  163. //
  164. // Synopsis:
  165. //
  166. //
  167. //
  168. // Arguments: [szPropertyName] --
  169. // [pdwIndex] --
  170. //
  171. //-------------------------------------------------------------------------
  172. HRESULT
  173. CClassCache::
  174. getentry(
  175. LPWSTR pszTreeName,
  176. LPWSTR pszClassName,
  177. PPROPENTRY * ppPropList
  178. )
  179. {
  180. DWORD dwIndex = 0;
  181. HRESULT hr = S_OK;
  182. PPROPENTRY pPropList = NULL;
  183. EnterCriticalSection(&_cs);
  184. hr = findentry(
  185. pszTreeName,
  186. pszClassName,
  187. &dwIndex
  188. );
  189. BAIL_ON_FAILURE(hr);
  190. pPropList = CopyPropList(
  191. _ClassEntries[dwIndex].pPropList
  192. );
  193. *ppPropList = pPropList;
  194. error:
  195. LeaveCriticalSection(&_cs);
  196. RRETURN(hr);
  197. }
  198. //+------------------------------------------------------------------------
  199. //
  200. // Function: CClassCache
  201. //
  202. // Synopsis:
  203. //
  204. //
  205. //
  206. // Arguments:
  207. //
  208. //
  209. //-------------------------------------------------------------------------
  210. CClassCache::
  211. CClassCache():
  212. _dwMaxCacheSize(2)
  213. {
  214. memset(_ClassEntries, 0, sizeof(CLASSENTRY));
  215. }
  216. //+------------------------------------------------------------------------
  217. //
  218. // Function: ~CClassCache
  219. //
  220. // Synopsis:
  221. //
  222. //
  223. //
  224. // Arguments:
  225. //
  226. //
  227. //-------------------------------------------------------------------------
  228. CClassCache::
  229. ~CClassCache()
  230. {
  231. //
  232. // BugBug: KrishnaG - free each one of the data items
  233. //
  234. DWORD i;
  235. for (i = 0; i < _dwMaxCacheSize; i++ ) {
  236. if (_ClassEntries[i].bInUse) {
  237. if (_ClassEntries[i].pPropList) {
  238. FreePropertyList(_ClassEntries[i].pPropList);
  239. _ClassEntries[i].pPropList = NULL;
  240. }
  241. _ClassEntries[i].bInUse = FALSE;
  242. }
  243. }
  244. }
  245. //+------------------------------------------------------------------------
  246. //
  247. // Function:
  248. //
  249. // Synopsis:
  250. //
  251. //
  252. //
  253. // Arguments:
  254. //
  255. //
  256. //-------------------------------------------------------------------------
  257. HRESULT
  258. CClassCache::
  259. CreateClassCache(
  260. CClassCache FAR *FAR * ppClassCache
  261. )
  262. {
  263. CClassCache FAR * pClassCache = NULL;
  264. pClassCache = new CClassCache();
  265. if (!pClassCache) {
  266. RRETURN(E_FAIL);
  267. }
  268. InitializeCriticalSection(&(pClassCache->_cs));
  269. *ppClassCache = pClassCache;
  270. RRETURN(S_OK);
  271. }
  272. DWORD
  273. CClassCache::
  274. IsOlderThan(
  275. DWORD i,
  276. DWORD j
  277. )
  278. {
  279. SYSTEMTIME *pi, *pj;
  280. DWORD iMs, jMs;
  281. // DBGMSG(DBG_TRACE, ("IsOlderThan entering with i %d j %d\n", i, j));
  282. pi = &(_ClassEntries[i].st);
  283. pj = &(_ClassEntries[j].st);
  284. if (pi->wYear < pj->wYear) {
  285. // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", i));
  286. return(i);
  287. } else if (pi->wYear > pj->wYear) {
  288. // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", j));
  289. return(j);
  290. } else if (pi->wMonth < pj->wMonth) {
  291. // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", i));
  292. return(i);
  293. } else if (pi->wMonth > pj->wMonth) {
  294. // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", j));
  295. return(j);
  296. } else if (pi->wDay < pj->wDay) {
  297. // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", i));
  298. return(i);
  299. } else if (pi->wDay > pj->wDay) {
  300. // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", j));
  301. return(j);
  302. } else {
  303. iMs = ((((pi->wHour * 60) + pi->wMinute)*60) + pi->wSecond)* 1000 + pi->wMilliseconds;
  304. jMs = ((((pj->wHour * 60) + pj->wMinute)*60) + pj->wSecond)* 1000 + pj->wMilliseconds;
  305. if (iMs <= jMs) {
  306. // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", i));
  307. return(i);
  308. } else {
  309. // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", j));
  310. return(j);
  311. }
  312. }
  313. }
  314. HRESULT
  315. ValidatePropertyinCache(
  316. LPWSTR pszTreeName,
  317. LPWSTR pszClassName,
  318. LPWSTR pszPropName,
  319. CCredentials& Credentials,
  320. PDWORD pdwSyntaxId
  321. )
  322. {
  323. HRESULT hr = S_OK;
  324. PPROPENTRY pPropList = NULL;
  325. hr = pgClassCache->getentry(
  326. pszTreeName,
  327. pszClassName,
  328. &pPropList
  329. );
  330. if (FAILED(hr)) {
  331. hr = NdsGetClassInformation(
  332. pszTreeName,
  333. pszClassName,
  334. Credentials,
  335. &pPropList
  336. );
  337. BAIL_ON_FAILURE(hr);
  338. hr = pgClassCache->addentry(
  339. pszTreeName,
  340. pszClassName,
  341. pPropList
  342. );
  343. BAIL_ON_FAILURE(hr);
  344. }
  345. hr = FindProperty(
  346. pPropList,
  347. pszPropName,
  348. pdwSyntaxId
  349. );
  350. BAIL_ON_FAILURE(hr);
  351. error:
  352. if (pPropList) {
  353. FreePropertyList(pPropList);
  354. }
  355. RRETURN(hr);
  356. }
  357. HRESULT
  358. NdsGetClassInformation(
  359. LPWSTR pszTreeName,
  360. LPWSTR pszClassName,
  361. CCredentials& Credentials,
  362. PPROPENTRY * ppPropList
  363. )
  364. {
  365. HRESULT hr = S_OK;
  366. LPNDS_CLASS_DEF lpClassDefs = NULL;
  367. DWORD dwStatus;
  368. DWORD dwObjectReturned = 0;
  369. DWORD dwInfoType = 0;
  370. NDS_CONTEXT_HANDLE hADsContext = NULL;
  371. NDS_BUFFER_HANDLE hOperationData = NULL;
  372. PPROPENTRY pPropList = NULL;
  373. hr = ADsNdsOpenContext(
  374. pszTreeName,
  375. Credentials,
  376. &hADsContext
  377. );
  378. BAIL_ON_FAILURE(hr);
  379. hr = ADsNdsReadClassDef(
  380. hADsContext,
  381. DS_EXPANDED_CLASS_DEFS,
  382. &pszClassName,
  383. 1,
  384. &hOperationData
  385. );
  386. BAIL_ON_FAILURE(hr);
  387. hr = ADsNdsGetClassDefListFromBuffer(
  388. hADsContext,
  389. hOperationData,
  390. &dwObjectReturned,
  391. &dwInfoType,
  392. &lpClassDefs
  393. );
  394. BAIL_ON_FAILURE(hr);
  395. pPropList = GenerateAttrIdList(
  396. hADsContext,
  397. lpClassDefs->lpMandatoryAttributes,
  398. lpClassDefs->lpOptionalAttributes
  399. );
  400. /*
  401. pPropList = GeneratePropertyAndIdList(
  402. pszTreeName,
  403. lpClassDefs->lpMandatoryAttributes,
  404. lpClassDefs->lpOptionalAttributes
  405. );*/
  406. if (!pPropList) {
  407. hr = HRESULT_FROM_WIN32(GetLastError());
  408. BAIL_ON_FAILURE(hr);
  409. }
  410. *ppPropList = pPropList;
  411. error:
  412. if (hADsContext) {
  413. ADsNdsCloseContext(hADsContext);
  414. }
  415. if (hOperationData) {
  416. ADsNdsFreeBuffer(hOperationData);
  417. }
  418. ADsNdsFreeClassDefList(lpClassDefs, dwObjectReturned);
  419. RRETURN(hr);
  420. }
  421. PPROPENTRY
  422. CreatePropertyEntry(
  423. LPWSTR pszPropertyName,
  424. DWORD dwSyntaxId
  425. )
  426. {
  427. LPWSTR pszTemp = NULL;
  428. PPROPENTRY pPropName = NULL;
  429. pszTemp = (LPWSTR)AllocADsStr(
  430. pszPropertyName
  431. );
  432. if (!pszTemp) {
  433. return(NULL);
  434. }
  435. pPropName = (PPROPENTRY)AllocADsMem(
  436. sizeof(PROPENTRY)
  437. );
  438. if (!pPropName) {
  439. FreeADsStr(pszTemp);
  440. return(NULL);
  441. }
  442. pPropName->pszPropName = pszTemp;
  443. pPropName->dwSyntaxId = dwSyntaxId;
  444. return(pPropName);
  445. }
  446. void
  447. FreePropertyEntry(
  448. PPROPENTRY pPropName
  449. )
  450. {
  451. if (pPropName->pszPropName) {
  452. FreeADsStr(pPropName->pszPropName);
  453. }
  454. FreeADsMem(pPropName);
  455. return;
  456. }
  457. void
  458. FreePropertyList(
  459. PPROPENTRY pPropList
  460. )
  461. {
  462. PPROPENTRY pTemp = NULL;
  463. while (pPropList) {
  464. pTemp = pPropList->pNext;
  465. FreePropertyEntry(pPropList);
  466. pPropList = pTemp;
  467. }
  468. return;
  469. }
  470. PPROPENTRY
  471. GeneratePropertyList(
  472. LPWSTR_LIST lpMandatoryProps,
  473. LPWSTR_LIST lpOptionalProps
  474. )
  475. {
  476. PPROPENTRY pStart = NULL;
  477. PPROPENTRY lpProperty = NULL;
  478. LPWSTR_LIST lpTempStrings = NULL;
  479. lpTempStrings = lpMandatoryProps;
  480. while (lpTempStrings) {
  481. lpProperty = CreatePropertyEntry(
  482. lpTempStrings->szString,
  483. 0
  484. );
  485. if (!lpProperty) {
  486. goto cleanup;
  487. }
  488. lpProperty->pNext = pStart;
  489. pStart = lpProperty;
  490. lpTempStrings = lpTempStrings->Next;
  491. }
  492. lpTempStrings = lpOptionalProps;
  493. while (lpTempStrings) {
  494. lpProperty = CreatePropertyEntry(
  495. lpTempStrings->szString,
  496. 0
  497. );
  498. if (!lpProperty) {
  499. goto cleanup;
  500. }
  501. lpProperty->pNext = pStart;
  502. pStart = lpProperty;
  503. lpTempStrings = lpTempStrings->Next;
  504. }
  505. cleanup:
  506. return(pStart);
  507. }
  508. HRESULT
  509. FindProperty(
  510. PPROPENTRY pPropList,
  511. LPWSTR pszPropName,
  512. PDWORD pdwSyntaxId
  513. )
  514. {
  515. while (pPropList) {
  516. if (!_wcsicmp(pPropList->pszPropName, pszPropName)) {
  517. *pdwSyntaxId = pPropList->dwSyntaxId;
  518. RRETURN(S_OK);
  519. }
  520. pPropList = pPropList->pNext;
  521. }
  522. RRETURN(E_ADS_PROPERTY_NOT_FOUND);
  523. }
  524. PPROPENTRY
  525. CopyPropList(
  526. PPROPENTRY pPropList
  527. )
  528. {
  529. PPROPENTRY pPropEntry = NULL;
  530. PPROPENTRY pStart = NULL;
  531. while (pPropList) {
  532. pPropEntry = CreatePropertyEntry(
  533. pPropList->pszPropName,
  534. pPropList->dwSyntaxId
  535. );
  536. if (!pPropEntry) {
  537. return(pStart);
  538. }
  539. pPropEntry->pNext = pStart;
  540. pStart = pPropEntry;
  541. pPropList = pPropList->pNext;
  542. }
  543. return(pStart);
  544. }
  545. PPROPENTRY
  546. GenerateAttrIdList(
  547. NDS_CONTEXT_HANDLE hADsContext,
  548. LPWSTR_LIST lpMandatoryProps,
  549. LPWSTR_LIST lpOptionalProps
  550. )
  551. {
  552. PPROPENTRY pStart = NULL;
  553. PPROPENTRY pPropEntry = NULL;
  554. LPWSTR_LIST lpTempStrings = NULL;
  555. HANDLE hOperationData = NULL;
  556. DWORD i = 0;
  557. WCHAR szTempBuffer[MAX_PATH];
  558. DWORD dwSyntaxId = 0;
  559. HRESULT hr = S_OK;
  560. lpTempStrings = lpMandatoryProps;
  561. while (lpTempStrings) {
  562. wcscpy(szTempBuffer, lpTempStrings->szString);
  563. hr = ADsNdsGetSyntaxID(
  564. hADsContext,
  565. szTempBuffer,
  566. &dwSyntaxId
  567. );
  568. BAIL_ON_FAILURE(hr);
  569. pPropEntry = CreatePropertyEntry(
  570. szTempBuffer,
  571. dwSyntaxId
  572. );
  573. if (!pPropEntry)
  574. goto error;
  575. pPropEntry->pNext = pStart;
  576. pStart = pPropEntry;
  577. lpTempStrings = lpTempStrings->Next;
  578. }
  579. lpTempStrings = lpOptionalProps;
  580. while (lpTempStrings) {
  581. wcscpy(szTempBuffer, lpTempStrings->szString);
  582. hr = ADsNdsGetSyntaxID(
  583. hADsContext,
  584. szTempBuffer,
  585. &dwSyntaxId
  586. );
  587. BAIL_ON_FAILURE(hr);
  588. pPropEntry = CreatePropertyEntry(
  589. szTempBuffer,
  590. dwSyntaxId
  591. );
  592. if (!pPropEntry)
  593. goto error;
  594. pPropEntry->pNext = pStart;
  595. pStart = pPropEntry;
  596. lpTempStrings = lpTempStrings->Next;
  597. }
  598. error:
  599. return(pStart);
  600. }