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.

955 lines
19 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. _ClassEntries[dwLRUEntry].bInUse = FALSE;
  94. i = dwLRUEntry;
  95. }
  96. //
  97. // Insert the new entry into the Cache
  98. //
  99. wcscpy(_ClassEntries[i].szTreeName, pszTreeName);
  100. wcscpy(_ClassEntries[i].szClassName, pszClassName);
  101. pNewPropList = CopyPropList(pPropList);
  102. if (pNewPropList) {
  103. _ClassEntries[i].pPropList = pNewPropList;
  104. }
  105. _ClassEntries[i].bInUse = TRUE;
  106. //
  107. // update the time stamp so that we know when this entry was made
  108. //
  109. GetSystemTime(&_ClassEntries[i].st);
  110. error:
  111. LeaveCriticalSection(&_cs);
  112. RRETURN(hr);
  113. }
  114. //+------------------------------------------------------------------------
  115. //
  116. // Function: CClassCache::findentry
  117. //
  118. // Synopsis:
  119. //
  120. //
  121. //
  122. // Arguments: [szPropertyName] --
  123. // [pdwIndex] --
  124. //
  125. //-------------------------------------------------------------------------
  126. HRESULT
  127. CClassCache::
  128. findentry(
  129. LPWSTR pszTreeName,
  130. LPWSTR pszClassName,
  131. PDWORD pdwIndex
  132. )
  133. {
  134. DWORD i = 0;
  135. EnterCriticalSection(&_cs);
  136. if (_dwMaxCacheSize == 0 ) {
  137. LeaveCriticalSection(&_cs);
  138. RRETURN(E_FAIL);
  139. }
  140. for (i = 0; i < _dwMaxCacheSize; i++ ) {
  141. if (_ClassEntries[i].bInUse) {
  142. if ((!_wcsicmp(_ClassEntries[i].szTreeName, pszTreeName)) &&
  143. (!_wcsicmp(_ClassEntries[i].szClassName, pszClassName))) {
  144. //
  145. // update the time stamp so that it is current and not old
  146. //
  147. GetSystemTime(&_ClassEntries[i].st);
  148. *pdwIndex = i;
  149. LeaveCriticalSection(&_cs);
  150. RRETURN(S_OK);
  151. }
  152. }
  153. }
  154. LeaveCriticalSection(&_cs);
  155. RRETURN(E_FAIL);
  156. }
  157. //+------------------------------------------------------------------------
  158. //
  159. // Function: CClassCache::findentry
  160. //
  161. // Synopsis:
  162. //
  163. //
  164. //
  165. // Arguments: [szPropertyName] --
  166. // [pdwIndex] --
  167. //
  168. //-------------------------------------------------------------------------
  169. HRESULT
  170. CClassCache::
  171. getentry(
  172. LPWSTR pszTreeName,
  173. LPWSTR pszClassName,
  174. PPROPENTRY * ppPropList
  175. )
  176. {
  177. DWORD dwIndex = 0;
  178. HRESULT hr = S_OK;
  179. PPROPENTRY pPropList = NULL;
  180. EnterCriticalSection(&_cs);
  181. hr = findentry(
  182. pszTreeName,
  183. pszClassName,
  184. &dwIndex
  185. );
  186. BAIL_ON_FAILURE(hr);
  187. pPropList = CopyPropList(
  188. _ClassEntries[dwIndex].pPropList
  189. );
  190. *ppPropList = pPropList;
  191. error:
  192. LeaveCriticalSection(&_cs);
  193. RRETURN(hr);
  194. }
  195. //+------------------------------------------------------------------------
  196. //
  197. // Function: CClassCache
  198. //
  199. // Synopsis:
  200. //
  201. //
  202. //
  203. // Arguments:
  204. //
  205. //
  206. //-------------------------------------------------------------------------
  207. CClassCache::
  208. CClassCache():
  209. _dwMaxCacheSize(2)
  210. {
  211. memset(_ClassEntries, 0, sizeof(CLASSENTRY));
  212. }
  213. //+------------------------------------------------------------------------
  214. //
  215. // Function: ~CClassCache
  216. //
  217. // Synopsis:
  218. //
  219. //
  220. //
  221. // Arguments:
  222. //
  223. //
  224. //-------------------------------------------------------------------------
  225. CClassCache::
  226. ~CClassCache()
  227. {
  228. DWORD i;
  229. for (i = 0; i < _dwMaxCacheSize; i++ ) {
  230. if (_ClassEntries[i].bInUse) {
  231. if (_ClassEntries[i].pPropList) {
  232. FreePropertyList(_ClassEntries[i].pPropList);
  233. _ClassEntries[i].pPropList = NULL;
  234. }
  235. _ClassEntries[i].bInUse = FALSE;
  236. }
  237. }
  238. DeleteCriticalSection(&_cs);
  239. }
  240. //+------------------------------------------------------------------------
  241. //
  242. // Function:
  243. //
  244. // Synopsis:
  245. //
  246. //
  247. //
  248. // Arguments:
  249. //
  250. //
  251. //-------------------------------------------------------------------------
  252. HRESULT
  253. CClassCache::
  254. CreateClassCache(
  255. CClassCache FAR *FAR * ppClassCache
  256. )
  257. {
  258. CClassCache FAR * pClassCache = NULL;
  259. pClassCache = new CClassCache();
  260. if (!pClassCache) {
  261. RRETURN(E_FAIL);
  262. }
  263. InitializeCriticalSection(&(pClassCache->_cs));
  264. *ppClassCache = pClassCache;
  265. RRETURN(S_OK);
  266. }
  267. DWORD
  268. CClassCache::
  269. IsOlderThan(
  270. DWORD i,
  271. DWORD j
  272. )
  273. {
  274. SYSTEMTIME *pi, *pj;
  275. DWORD iMs, jMs;
  276. // DBGMSG(DBG_TRACE, ("IsOlderThan entering with i %d j %d\n", i, j));
  277. pi = &(_ClassEntries[i].st);
  278. pj = &(_ClassEntries[j].st);
  279. if (pi->wYear < pj->wYear) {
  280. // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", i));
  281. return(i);
  282. } else if (pi->wYear > pj->wYear) {
  283. // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", j));
  284. return(j);
  285. } else if (pi->wMonth < pj->wMonth) {
  286. // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", i));
  287. return(i);
  288. } else if (pi->wMonth > pj->wMonth) {
  289. // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", j));
  290. return(j);
  291. } else if (pi->wDay < pj->wDay) {
  292. // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", i));
  293. return(i);
  294. } else if (pi->wDay > pj->wDay) {
  295. // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", j));
  296. return(j);
  297. } else {
  298. iMs = ((((pi->wHour * 60) + pi->wMinute)*60) + pi->wSecond)* 1000 + pi->wMilliseconds;
  299. jMs = ((((pj->wHour * 60) + pj->wMinute)*60) + pj->wSecond)* 1000 + pj->wMilliseconds;
  300. if (iMs <= jMs) {
  301. // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", i));
  302. return(i);
  303. } else {
  304. // DBGMSG(DBG_TRACE, ("IsOlderThan returns %d\n", j));
  305. return(j);
  306. }
  307. }
  308. }
  309. HRESULT
  310. ValidatePropertyinCache(
  311. LPWSTR pszTreeName,
  312. LPWSTR pszClassName,
  313. LPWSTR pszPropName,
  314. CCredentials& Credentials,
  315. PDWORD pdwSyntaxId
  316. )
  317. {
  318. HRESULT hr = S_OK;
  319. PPROPENTRY pPropList = NULL;
  320. hr = pgClassCache->getentry(
  321. pszTreeName,
  322. pszClassName,
  323. &pPropList
  324. );
  325. if (FAILED(hr)) {
  326. hr = NdsGetClassInformation(
  327. pszTreeName,
  328. pszClassName,
  329. Credentials,
  330. &pPropList
  331. );
  332. BAIL_ON_FAILURE(hr);
  333. hr = pgClassCache->addentry(
  334. pszTreeName,
  335. pszClassName,
  336. pPropList
  337. );
  338. BAIL_ON_FAILURE(hr);
  339. }
  340. hr = FindProperty(
  341. pPropList,
  342. pszPropName,
  343. pdwSyntaxId
  344. );
  345. BAIL_ON_FAILURE(hr);
  346. error:
  347. if (pPropList) {
  348. FreePropertyList(pPropList);
  349. }
  350. RRETURN(hr);
  351. }
  352. HRESULT
  353. NdsGetClassInformation(
  354. LPWSTR pszTreeName,
  355. LPWSTR pszClassName,
  356. CCredentials& Credentials,
  357. PPROPENTRY * ppPropList
  358. )
  359. {
  360. HRESULT hr = S_OK;
  361. LPNDS_CLASS_DEF lpClassDefs = NULL;
  362. DWORD dwStatus;
  363. DWORD dwObjectReturned = 0;
  364. DWORD dwInfoType = 0;
  365. HANDLE hTree = NULL;
  366. HANDLE hOperationData = NULL;
  367. PPROPENTRY pPropList = NULL;
  368. dwStatus = ADsNwNdsOpenObject(
  369. pszTreeName,
  370. Credentials,
  371. &hTree,
  372. NULL,
  373. NULL,
  374. NULL,
  375. NULL
  376. );
  377. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  378. dwStatus = NwNdsCreateBuffer(
  379. NDS_SCHEMA_READ_CLASS_DEF,
  380. &hOperationData
  381. );
  382. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  383. dwStatus = NwNdsPutInBuffer(
  384. pszClassName,
  385. 0,
  386. NULL,
  387. 0,
  388. 0,
  389. hOperationData
  390. );
  391. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  392. dwStatus = NwNdsReadClassDef(
  393. hTree,
  394. NDS_CLASS_INFO_EXPANDED_DEFS,
  395. &hOperationData
  396. );
  397. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  398. dwStatus = NwNdsGetClassDefListFromBuffer(
  399. hOperationData,
  400. &dwObjectReturned,
  401. &dwInfoType,
  402. (LPVOID *) &lpClassDefs
  403. );
  404. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  405. pPropList = GenerateAttrIdList(
  406. hTree,
  407. lpClassDefs->lpMandatoryAttributes,
  408. lpClassDefs->lpOptionalAttributes
  409. );
  410. /*
  411. pPropList = GeneratePropertyAndIdList(
  412. pszTreeName,
  413. lpClassDefs->lpMandatoryAttributes,
  414. lpClassDefs->lpOptionalAttributes
  415. );*/
  416. if (!pPropList) {
  417. hr = HRESULT_FROM_WIN32(GetLastError());
  418. BAIL_ON_FAILURE(hr);
  419. }
  420. *ppPropList = pPropList;
  421. error:
  422. if (hOperationData) {
  423. NwNdsFreeBuffer(hOperationData);
  424. }
  425. if (hTree) {
  426. NwNdsCloseObject(hTree);
  427. }
  428. RRETURN(hr);
  429. }
  430. PPROPENTRY
  431. CreatePropertyEntry(
  432. LPWSTR pszPropertyName,
  433. DWORD dwSyntaxId
  434. )
  435. {
  436. LPWSTR pszTemp = NULL;
  437. PPROPENTRY pPropName = NULL;
  438. pszTemp = (LPWSTR)AllocADsStr(
  439. pszPropertyName
  440. );
  441. if (!pszTemp) {
  442. return(NULL);
  443. }
  444. pPropName = (PPROPENTRY)AllocADsMem(
  445. sizeof(PROPENTRY)
  446. );
  447. if (!pPropName) {
  448. FreeADsStr(pszTemp);
  449. return(NULL);
  450. }
  451. pPropName->pszPropName = pszTemp;
  452. pPropName->dwSyntaxId = dwSyntaxId;
  453. return(pPropName);
  454. }
  455. void
  456. FreePropertyEntry(
  457. PPROPENTRY pPropName
  458. )
  459. {
  460. if (pPropName->pszPropName) {
  461. FreeADsStr(pPropName->pszPropName);
  462. }
  463. FreeADsMem(pPropName);
  464. return;
  465. }
  466. void
  467. FreePropertyList(
  468. PPROPENTRY pPropList
  469. )
  470. {
  471. PPROPENTRY pTemp = NULL;
  472. while (pPropList) {
  473. pTemp = pPropList->pNext;
  474. FreePropertyEntry(pPropList);
  475. pPropList = pTemp;
  476. }
  477. return;
  478. }
  479. PPROPENTRY
  480. GeneratePropertyList(
  481. LPWSTR_LIST lpMandatoryProps,
  482. LPWSTR_LIST lpOptionalProps
  483. )
  484. {
  485. PPROPENTRY pStart = NULL;
  486. PPROPENTRY lpProperty = NULL;
  487. LPWSTR_LIST lpTempStrings = NULL;
  488. lpTempStrings = lpMandatoryProps;
  489. while (lpTempStrings) {
  490. lpProperty = CreatePropertyEntry(
  491. lpTempStrings->szString,
  492. 0
  493. );
  494. if (!lpProperty) {
  495. goto cleanup;
  496. }
  497. lpProperty->pNext = pStart;
  498. pStart = lpProperty;
  499. lpTempStrings = lpTempStrings->Next;
  500. }
  501. lpTempStrings = lpOptionalProps;
  502. while (lpTempStrings) {
  503. lpProperty = CreatePropertyEntry(
  504. lpTempStrings->szString,
  505. 0
  506. );
  507. if (!lpProperty) {
  508. goto cleanup;
  509. }
  510. lpProperty->pNext = pStart;
  511. pStart = lpProperty;
  512. lpTempStrings = lpTempStrings->Next;
  513. }
  514. cleanup:
  515. return(pStart);
  516. }
  517. HRESULT
  518. FindProperty(
  519. PPROPENTRY pPropList,
  520. LPWSTR pszPropName,
  521. PDWORD pdwSyntaxId
  522. )
  523. {
  524. while (pPropList) {
  525. if (!_wcsicmp(pPropList->pszPropName, pszPropName)) {
  526. *pdwSyntaxId = pPropList->dwSyntaxId;
  527. RRETURN(S_OK);
  528. }
  529. pPropList = pPropList->pNext;
  530. }
  531. RRETURN(E_ADS_PROPERTY_NOT_FOUND);
  532. }
  533. PPROPENTRY
  534. CopyPropList(
  535. PPROPENTRY pPropList
  536. )
  537. {
  538. PPROPENTRY pPropEntry = NULL;
  539. PPROPENTRY pStart = NULL;
  540. while (pPropList) {
  541. pPropEntry = CreatePropertyEntry(
  542. pPropList->pszPropName,
  543. pPropList->dwSyntaxId
  544. );
  545. if (!pPropEntry) {
  546. return(pStart);
  547. }
  548. pPropEntry->pNext = pStart;
  549. pStart = pPropEntry;
  550. pPropList = pPropList->pNext;
  551. }
  552. return(pStart);
  553. }
  554. PPROPENTRY
  555. GeneratePropertyAndIdList(
  556. LPWSTR pszTreeName,
  557. CCredentials& Credentials,
  558. LPWSTR_LIST lpMandatoryProps,
  559. LPWSTR_LIST lpOptionalProps
  560. )
  561. {
  562. HANDLE hTree = NULL;
  563. PPROPENTRY pStart = NULL;
  564. PPROPENTRY pPropEntry = NULL;
  565. LPWSTR_LIST lpTempStrings = NULL;
  566. HANDLE hOperationData = NULL;
  567. DWORD i = 0;
  568. WCHAR szTempBuffer[MAX_PATH];
  569. LPNDS_ATTR_DEF lpAttrDefs = NULL;
  570. DWORD dwSyntaxId = 0;
  571. DWORD dwNumEntries = 0;
  572. DWORD dwInfoType = 0;
  573. DWORD dwStatus = 0;
  574. dwStatus = ADsNwNdsOpenObject(
  575. pszTreeName,
  576. Credentials,
  577. &hTree,
  578. NULL,
  579. NULL,
  580. NULL,
  581. NULL
  582. );
  583. if (dwStatus) {
  584. goto error;
  585. }
  586. dwStatus = NwNdsCreateBuffer(
  587. NDS_SCHEMA_READ_ATTR_DEF,
  588. &hOperationData
  589. );
  590. if (dwStatus) {
  591. goto error;
  592. }
  593. lpTempStrings = lpMandatoryProps;
  594. while (lpTempStrings) {
  595. wcscpy(szTempBuffer, lpTempStrings->szString);
  596. dwStatus = NwNdsPutInBuffer(
  597. szTempBuffer,
  598. 0,
  599. NULL,
  600. 0,
  601. 0,
  602. hOperationData
  603. );
  604. if (dwStatus) {
  605. goto error;
  606. }
  607. lpTempStrings = lpTempStrings->Next;
  608. }
  609. lpTempStrings = lpOptionalProps;
  610. while (lpTempStrings) {
  611. wcscpy(szTempBuffer, lpTempStrings->szString);
  612. dwStatus = NwNdsPutInBuffer(
  613. szTempBuffer,
  614. 0,
  615. NULL,
  616. 0,
  617. 0,
  618. hOperationData
  619. );
  620. if (dwStatus) {
  621. goto error;
  622. }
  623. lpTempStrings = lpTempStrings->Next;
  624. }
  625. dwStatus = NwNdsReadAttrDef(
  626. hTree,
  627. NDS_INFO_NAMES_DEFS,
  628. &hOperationData
  629. );
  630. if (dwStatus) {
  631. goto error;
  632. }
  633. dwStatus = NwNdsGetAttrDefListFromBuffer(
  634. hOperationData,
  635. &dwNumEntries,
  636. &dwInfoType,
  637. (LPVOID *)&lpAttrDefs
  638. );
  639. if (dwStatus) {
  640. goto error;
  641. }
  642. for (i = 0; i < dwNumEntries; i++){
  643. pPropEntry = CreatePropertyEntry(
  644. lpAttrDefs[i].szAttributeName,
  645. lpAttrDefs[i].dwSyntaxID
  646. );
  647. if (!pPropEntry) {
  648. goto error;
  649. }
  650. pPropEntry->pNext = pStart;
  651. pStart = pPropEntry;
  652. }
  653. error:
  654. if (hOperationData) {
  655. NwNdsFreeBuffer(hOperationData);
  656. }
  657. if (hTree) {
  658. NwNdsCloseObject(hTree);
  659. }
  660. return(pStart);
  661. }
  662. PPROPENTRY
  663. GenerateAttrIdList(
  664. HANDLE hTree,
  665. LPWSTR_LIST lpMandatoryProps,
  666. LPWSTR_LIST lpOptionalProps
  667. )
  668. {
  669. PPROPENTRY pStart = NULL;
  670. PPROPENTRY pPropEntry = NULL;
  671. LPWSTR_LIST lpTempStrings = NULL;
  672. HANDLE hOperationData = NULL;
  673. DWORD i = 0;
  674. WCHAR szTempBuffer[MAX_PATH];
  675. LPNDS_ATTR_DEF lpAttrDefs = NULL;
  676. DWORD dwSyntaxId = 0;
  677. DWORD dwNumEntries = 0;
  678. DWORD dwInfoType = 0;
  679. DWORD dwStatus = 0;
  680. lpTempStrings = lpMandatoryProps;
  681. while (lpTempStrings) {
  682. wcscpy(szTempBuffer, lpTempStrings->szString);
  683. dwStatus = NwNdsGetSyntaxID(
  684. hTree,
  685. szTempBuffer,
  686. &dwSyntaxId
  687. );
  688. if (dwStatus) {
  689. lpTempStrings = lpTempStrings->Next;
  690. continue;
  691. }
  692. pPropEntry = CreatePropertyEntry(
  693. szTempBuffer,
  694. dwSyntaxId
  695. );
  696. if (!pPropEntry) {
  697. lpTempStrings = lpTempStrings->Next;
  698. continue;
  699. }
  700. pPropEntry->pNext = pStart;
  701. pStart = pPropEntry;
  702. lpTempStrings = lpTempStrings->Next;
  703. }
  704. lpTempStrings = lpOptionalProps;
  705. while (lpTempStrings) {
  706. wcscpy(szTempBuffer, lpTempStrings->szString);
  707. dwStatus = NwNdsGetSyntaxID(
  708. hTree,
  709. szTempBuffer,
  710. &dwSyntaxId
  711. );
  712. if (dwStatus) {
  713. lpTempStrings = lpTempStrings->Next;
  714. continue;
  715. }
  716. pPropEntry = CreatePropertyEntry(
  717. szTempBuffer,
  718. dwSyntaxId
  719. );
  720. if (!pPropEntry) {
  721. lpTempStrings = lpTempStrings->Next;
  722. continue;
  723. }
  724. pPropEntry->pNext = pStart;
  725. pStart = pPropEntry;
  726. lpTempStrings = lpTempStrings->Next;
  727. }
  728. return(pStart);
  729. }