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.

1147 lines
27 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1996 - 1999
  3. Module Name:
  4. QueryDB
  5. Abstract:
  6. This module provides simple access to the Calais Registry Database.
  7. Author:
  8. Doug Barlow (dbarlow) 11/25/1996
  9. Environment:
  10. Win32, C++ w/ Exceptions
  11. Notes:
  12. ?Notes?
  13. --*/
  14. #ifndef WIN32_LEAN_AND_MEAN
  15. #define WIN32_LEAN_AND_MEAN
  16. #endif
  17. #include <windows.h>
  18. #include <stdlib.h>
  19. #include <tchar.h>
  20. #include <winscard.h>
  21. #include <CalaisLb.h>
  22. // Keep this in sync with ChangeDB.cpp
  23. typedef struct {
  24. DWORD dwScope;
  25. HKEY hKey;
  26. } RegMap;
  27. #if SCARD_SCOPE_SYSTEM < SCARD_SCOPE_USER
  28. #error Invalid ordering to SCARD_SCOPE definitions
  29. #endif
  30. static const RegMap l_rgRegMap[]
  31. = {
  32. { SCARD_SCOPE_USER, HKEY_CURRENT_USER },
  33. // { SCARD_SCOPE_TERMINAL, Not implemented yet }, // ?Hydra?
  34. { SCARD_SCOPE_SYSTEM, HKEY_LOCAL_MACHINE }
  35. };
  36. static const DWORD l_dwRegMapMax = sizeof(l_rgRegMap) / sizeof(RegMap);
  37. static const LPCTSTR l_szrgProvMap[]
  38. = {
  39. NULL, // Zero value
  40. SCARD_REG_PPV,
  41. SCARD_REG_CSP
  42. };
  43. static const DWORD l_dwProvMapMax = sizeof(l_szrgProvMap) / sizeof(LPCTSTR);
  44. static BOOL
  45. ListKnownKeys(
  46. IN DWORD dwScope,
  47. OUT CBuffer &bfKeys,
  48. IN LPCTSTR szUserList,
  49. IN LPCTSTR szSystemList = NULL);
  50. static void
  51. FindKey(
  52. IN DWORD dwScope,
  53. IN LPCTSTR szKey,
  54. OUT CRegistry &regKey,
  55. IN LPCTSTR szUserList,
  56. IN LPCTSTR szSystemList = NULL);
  57. //
  58. ////////////////////////////////////////////////////////////////////////////////
  59. //
  60. // Calais Database Query Services
  61. //
  62. // These services all are oriented towards reading the Calais database.
  63. //
  64. /*++
  65. ListReaderGroups:
  66. This service provides the list of named card reader groups that have
  67. previously been defined to the system.
  68. Arguments:
  69. dwScope supplies an indicator of the scope of the operation. Possible
  70. values are:
  71. SCARD_SCOPE_USER - The current user's definitions are used.
  72. SCARD_SCOPE_TERMINAL - The terminal's definitions are used.
  73. SCARD_SCOPE_SYSTEM - The system's definitions are used.
  74. For V1, this value is ignored, and assumed to be SCARD_SCOPE_SYSTEM.
  75. bfGroups receives a multi-string listing the reader groups defined within
  76. the supplied scope.
  77. Return Value:
  78. None.
  79. Author:
  80. Doug Barlow (dbarlow) 10/23/1996
  81. --*/
  82. void
  83. ListReaderGroups(
  84. IN DWORD dwScope,
  85. OUT CBuffer &bfGroups)
  86. {
  87. CBuffer bfReaders;
  88. CRegistry regReader;
  89. LPCTSTR szReader, mszGroups;
  90. CBuffer bfTmp;
  91. DWORD cchGroups;
  92. ListKnownKeys(dwScope, bfReaders, SCARD_REG_READERS);
  93. for (szReader = FirstString(bfReaders);
  94. NULL != szReader;
  95. szReader = NextString(szReader))
  96. {
  97. try
  98. {
  99. FindKey(dwScope, szReader, regReader, SCARD_REG_READERS);
  100. mszGroups = regReader.GetMultiStringValue(SCARD_REG_GROUPS);
  101. cchGroups = regReader.GetValueLength() / sizeof(TCHAR);
  102. while (0 == mszGroups[cchGroups - 1])
  103. cchGroups -= 1;
  104. bfTmp.Append(
  105. (LPBYTE)mszGroups,
  106. cchGroups * sizeof(TCHAR));
  107. bfTmp.Append((LPBYTE)TEXT("\000"), sizeof(TCHAR));
  108. }
  109. catch (...) {}
  110. }
  111. //
  112. // Sort the list, and remove duplicates.
  113. //
  114. bfTmp.Append((LPCBYTE)TEXT("\000"), 2 * sizeof(TCHAR));
  115. MStringSort(bfTmp, bfGroups);
  116. }
  117. /*++
  118. ListReaders:
  119. This service provides the list of readers within a set of named reader
  120. groups, eliminating duplicates. The caller supplies a multistring listing
  121. the name of a set of pre-defined group of readers, and receives the list of
  122. smartcard readers within the named groups. Unrecognized group names are
  123. ignored.
  124. Arguments:
  125. dwScope supplies an indicator of the scope of the operation. Possible
  126. values are:
  127. SCARD_SCOPE_USER - The current user's definitions are used.
  128. SCARD_SCOPE_TERMINAL - The terminal's definitions are used.
  129. SCARD_SCOPE_SYSTEM - The system's definitions are used.
  130. mszGroups supplies the names of the reader groups defined to the system, as
  131. a multi-string. If this parameter is null, all readers are returned.
  132. bfReaders receives a multi-string listing the card readers within the
  133. supplied reader groups.
  134. Return Value:
  135. None.
  136. Author:
  137. Doug Barlow (dbarlow) 10/23/1996
  138. --*/
  139. void
  140. ListReaders(
  141. IN DWORD dwScope,
  142. IN LPCTSTR mszGroups,
  143. OUT CBuffer &bfReaders)
  144. {
  145. CRegistry regReader;
  146. LPCTSTR szReader, mszRdrGroups;
  147. CBuffer bfRdrs, bfCmn;
  148. DWORD dwCmnCount;
  149. dwCmnCount = MStringCommon(mszGroups, SCARD_ALL_READERS, bfCmn);
  150. if (0 == dwCmnCount)
  151. {
  152. if ((NULL == mszGroups) || (0 == *mszGroups))
  153. mszGroups = SCARD_DEFAULT_READERS;
  154. bfReaders.Reset();
  155. ListKnownKeys(dwScope, bfRdrs, SCARD_REG_READERS);
  156. for (szReader = FirstString(bfRdrs);
  157. NULL != szReader;
  158. szReader = NextString(szReader))
  159. {
  160. try
  161. {
  162. FindKey(dwScope, szReader, regReader, SCARD_REG_READERS);
  163. mszRdrGroups = regReader.GetMultiStringValue(SCARD_REG_GROUPS);
  164. dwCmnCount = MStringCommon(mszGroups, mszRdrGroups, bfCmn);
  165. if (0 < dwCmnCount)
  166. bfReaders.Append(
  167. (LPCBYTE)szReader,
  168. (lstrlen(szReader) + 1) * sizeof(TCHAR));
  169. }
  170. catch (...) {}
  171. }
  172. bfReaders.Append((LPBYTE)TEXT("\000"), 2 * sizeof(TCHAR));
  173. bfReaders.Resize(MStrLen((LPCTSTR)bfReaders.Access()), TRUE);
  174. }
  175. else
  176. ListKnownKeys(dwScope, bfReaders, SCARD_REG_READERS);
  177. }
  178. /*++
  179. ListReaderNames:
  180. This routine returns the list of names corresponding to a given reader
  181. device.
  182. Arguments:
  183. dwScope supplies an indicator of the scope of the operation. Possible
  184. values are:
  185. SCARD_SCOPE_USER - The current user's definitions are used.
  186. SCARD_SCOPE_TERMINAL - The terminal's definitions are used.
  187. SCARD_SCOPE_SYSTEM - The system's definitions are used.
  188. For V1, this value is ignored, and assumed to be SCARD_SCOPE_SYSTEM.
  189. szDevice supplies the reader device name.
  190. bfNames receives a multistring of the names given to that device, if any.
  191. Return Value:
  192. None
  193. Throws:
  194. Errors as DWORD status codes
  195. Author:
  196. Doug Barlow (dbarlow) 2/13/1997
  197. --*/
  198. void
  199. ListReaderNames(
  200. IN DWORD dwScope,
  201. IN LPCTSTR szDevice,
  202. OUT CBuffer &bfNames)
  203. {
  204. CRegistry regReader;
  205. LPCTSTR szReader, szDev;
  206. CBuffer bfRdrs;
  207. bfNames.Reset();
  208. ListKnownKeys(dwScope, bfRdrs, SCARD_REG_READERS);
  209. for (szReader = FirstString(bfRdrs);
  210. NULL != szReader;
  211. szReader = NextString(szReader))
  212. {
  213. try
  214. {
  215. FindKey(dwScope, szReader, regReader, SCARD_REG_READERS);
  216. szDev = regReader.GetStringValue(SCARD_REG_DEVICE);
  217. if (0 == lstrcmpi(szDev, szDevice))
  218. MStrAdd(bfNames, szReader);
  219. }
  220. catch (...) {}
  221. }
  222. }
  223. /*++
  224. ListCards:
  225. This service provides a list of named cards previously introduced to the
  226. system by this user which match an optionally supplied ATR string and/or
  227. supply a set of given interfaces.
  228. Arguments:
  229. dwScope supplies an indicator of the scope of the operation. Possible
  230. values are:
  231. SCARD_SCOPE_USER - The current user's definitions are used.
  232. SCARD_SCOPE_TERMINAL - The terminal's definitions are used.
  233. SCARD_SCOPE_SYSTEM - The system's definitions are used.
  234. pbAtr supplies the address of an ATR string to compare to known cards, or
  235. NULL if all card names are to be returned.
  236. rgguidInterfaces supplies an array of GUIDs, or the value NULL. When an
  237. array is supplied, a card name will be returned only if this set of
  238. GUIDs is a (possibly improper) subset of the set of GUIDs supported by
  239. the card.
  240. cguidInterfaceCount supplies the number of entries in the rgguidInterfaces
  241. array. If rgguidInterfaces is NULL, then this value is ignored.
  242. bfCards receives a multi-string listing the smartcards introduced to the
  243. system by this user which match the supplied ATR string.
  244. Return Value:
  245. None
  246. Author:
  247. Doug Barlow (dbarlow) 10/23/1996
  248. --*/
  249. void
  250. ListCards(
  251. DWORD dwScope,
  252. IN LPCBYTE pbAtr,
  253. IN LPCGUID rgquidInterfaces,
  254. IN DWORD cguidInterfaceCount,
  255. OUT CBuffer &bfCards)
  256. {
  257. CRegistry regCard;
  258. LPCTSTR szCard;
  259. CBuffer bfCardAtr;
  260. CBuffer bfCardList;
  261. bfCards.Reset();
  262. ListKnownKeys(dwScope, bfCardList, SCARD_REG_CARDS, SCARD_REG_TEMPLATES);
  263. for (szCard = FirstString(bfCardList);
  264. NULL != szCard;
  265. szCard = NextString(szCard))
  266. {
  267. try
  268. {
  269. FindKey(
  270. dwScope,
  271. szCard,
  272. regCard,
  273. SCARD_REG_CARDS,
  274. SCARD_REG_TEMPLATES);
  275. //
  276. // Does this card match the supplied ATR?
  277. //
  278. if ((NULL != pbAtr) && (0 != *pbAtr))
  279. {
  280. LPCBYTE pbCardAtr, pbCardMask;
  281. DWORD cbCardAtr, cbCardMask;
  282. pbCardAtr = regCard.GetBinaryValue(
  283. SCARD_REG_ATR,
  284. &cbCardAtr);
  285. bfCardAtr.Set(pbCardAtr, cbCardAtr);
  286. try
  287. {
  288. pbCardMask = regCard.GetBinaryValue(
  289. SCARD_REG_ATRMASK,
  290. &cbCardMask);
  291. if (cbCardAtr != cbCardMask)
  292. continue; // Invalid ATR/Mask combination.
  293. }
  294. catch (...)
  295. {
  296. pbCardMask = NULL; // No mask.
  297. }
  298. if (!AtrCompare(pbAtr, bfCardAtr, pbCardMask, cbCardAtr))
  299. continue; // ATRs invalid or don't match.
  300. }
  301. //
  302. // Does this card support the given interfaces?
  303. //
  304. if ((NULL != rgquidInterfaces) && (0 < cguidInterfaceCount))
  305. {
  306. DWORD cguidCrd;
  307. DWORD ix, jx;
  308. BOOL fAllInterfacesFound = TRUE;
  309. LPCGUID rgCrdInfs = (LPCGUID)regCard.GetBinaryValue(
  310. SCARD_REG_GUIDS,
  311. &cguidCrd);
  312. if ((0 != (cguidCrd % sizeof(GUID)))
  313. || (0 == cguidCrd))
  314. continue; // Invalid GUID list.
  315. cguidCrd /= sizeof(GUID);
  316. for (ix = 0; ix < cguidInterfaceCount; ix += 1)
  317. {
  318. for (jx = 0; jx < cguidCrd; jx += 1)
  319. {
  320. if (0 == MemCompare(
  321. (LPCBYTE)&rgCrdInfs[jx],
  322. (LPCBYTE)&rgquidInterfaces[ix],
  323. sizeof(GUID)))
  324. break;
  325. }
  326. if (jx == cguidCrd)
  327. {
  328. fAllInterfacesFound = FALSE; // Unsupported interface
  329. break;
  330. }
  331. }
  332. if (!fAllInterfacesFound)
  333. continue;
  334. }
  335. //
  336. // This card passes all the tests -- Include it.
  337. //
  338. MStrAdd(bfCards, szCard);
  339. }
  340. catch (...) {}
  341. }
  342. if (0 == bfCards.Length())
  343. bfCards.Set((LPCBYTE)TEXT("\000"), 2 * sizeof(TCHAR));
  344. }
  345. /*++
  346. GetCardTypeProviderName:
  347. This routine returns the value of a given Provider Name, by Id number, for
  348. the identified card type.
  349. Arguments:
  350. dwScope supplies an indicator of the scope of the operation. Possible
  351. values are:
  352. SCARD_SCOPE_USER - The current user's definitions are used.
  353. SCARD_SCOPE_TERMINAL - The terminal's definitions are used.
  354. SCARD_SCOPE_SYSTEM - The system's definitions are used.
  355. szCardName supplies the name of the card type with which this provider name
  356. is associated.
  357. dwProviderId supplies the identifier for the provider associated with this
  358. card type. Possible values are:
  359. SCARD_PROVIDER_SSP - The SSP identifier, as a GUID string.
  360. SCARD_PROVIDER_CSP - The CSP name.
  361. Other values < 0x80000000 are reserved for use by Microsoft. Values
  362. over 0x80000000 are available for use by the smart card vendors, and
  363. are card-specific.
  364. bfProvider receives the string identifying the provider.
  365. Return Value:
  366. None
  367. Throws:
  368. Errors as DWORD status codes
  369. Author:
  370. Doug Barlow (dbarlow) 1/19/1998
  371. --*/
  372. void
  373. GetCardTypeProviderName(
  374. IN DWORD dwScope,
  375. IN LPCTSTR szCardName,
  376. IN DWORD dwProviderId,
  377. OUT CBuffer &bfProvider)
  378. {
  379. LPCTSTR szProvValue;
  380. TCHAR szNumeric[36];
  381. CRegistry regCard;
  382. //
  383. // Find the Card definition closest to the caller.
  384. //
  385. FindKey(
  386. dwScope,
  387. szCardName,
  388. regCard,
  389. SCARD_REG_CARDS,
  390. SCARD_REG_TEMPLATES);
  391. //
  392. // Derive the Provider Value Name.
  393. //
  394. if (dwProviderId < l_dwProvMapMax)
  395. {
  396. szProvValue = l_szrgProvMap[dwProviderId];
  397. if (NULL == szProvValue)
  398. throw (DWORD)SCARD_E_INVALID_PARAMETER;
  399. }
  400. else if (0x80000000 <= dwProviderId)
  401. {
  402. _ultot(dwProviderId, szNumeric, 16);
  403. szProvValue = szNumeric;
  404. }
  405. else
  406. throw (DWORD)SCARD_E_INVALID_PARAMETER;
  407. //
  408. // Read the provider value.
  409. //
  410. switch (dwProviderId)
  411. {
  412. case 1: // SCARD_PROVIDER_SSP
  413. {
  414. CBuffer bfGuid(sizeof(GUID));
  415. bfProvider.Presize(40 * sizeof(TCHAR));
  416. regCard.GetValue(szProvValue, bfGuid);
  417. StringFromGuid(
  418. (LPCGUID)bfGuid.Access(),
  419. (LPTSTR)bfProvider.Access());
  420. bfProvider.Resize(
  421. (lstrlen((LPCTSTR)bfProvider.Access()) + 1) * sizeof(TCHAR),
  422. TRUE);
  423. break;
  424. }
  425. default:
  426. regCard.GetValue(szProvValue, bfProvider);
  427. }
  428. }
  429. /*++
  430. GetReaderInfo:
  431. This routine returns all stored information regarding a given reader.
  432. Arguments:
  433. dwScope supplies an indicator of the scope of the operation. Possible
  434. values are:
  435. SCARD_SCOPE_USER - The current user's definitions are used.
  436. SCARD_SCOPE_TERMINAL - The terminal's definitions are used.
  437. SCARD_SCOPE_SYSTEM - The system's definitions are used.
  438. szReader supplies the name of the reader of which info is to be extracted.
  439. pbfGroups receives the list of groups as a multistring.
  440. pbfDevice receives the device name.
  441. Return Value:
  442. TRUE - Reader found
  443. FALSE - Reader not found
  444. Author:
  445. Doug Barlow (dbarlow) 12/2/1996
  446. --*/
  447. BOOL
  448. GetReaderInfo(
  449. IN DWORD dwScope,
  450. IN LPCTSTR szReader,
  451. OUT CBuffer *pbfGroups,
  452. OUT CBuffer *pbfDevice)
  453. {
  454. CRegistry regReader;
  455. //
  456. // Find the reader definition closest to the caller.
  457. //
  458. try
  459. {
  460. FindKey(dwScope, szReader, regReader, SCARD_REG_READERS);
  461. }
  462. catch (...)
  463. {
  464. return FALSE;
  465. }
  466. //
  467. // Look up all it's values.
  468. //
  469. if (NULL != pbfDevice)
  470. {
  471. // Device name
  472. try
  473. {
  474. regReader.GetValue(SCARD_REG_DEVICE, *pbfDevice);
  475. }
  476. catch (...)
  477. {
  478. pbfDevice->Reset();
  479. }
  480. }
  481. if (NULL != pbfGroups)
  482. {
  483. // Group list
  484. try
  485. {
  486. regReader.GetValue(SCARD_REG_GROUPS, *pbfGroups);
  487. }
  488. catch (...)
  489. {
  490. pbfGroups->Reset();
  491. }
  492. }
  493. return TRUE;
  494. }
  495. /*++
  496. GetCardInfo:
  497. This routine finds the given card under the given scope, and returns all
  498. information associated with it.
  499. Arguments:
  500. dwScope supplies an indicator of the scope of the operation. Possible
  501. values are:
  502. SCARD_SCOPE_USER - The current user's definitions are used.
  503. SCARD_SCOPE_TERMINAL - The terminal's definitions are used.
  504. SCARD_SCOPE_SYSTEM - The system's definitions are used.
  505. szCard supplies the name of the card for which info is to be extracted.
  506. pbfAtr receives the ATR string of the given card. This parameter may be
  507. NULL if the ATR is not desired.
  508. pbfAtrMask receives the ATR mask of the given card, if any. This parameter
  509. may be NULL if the value is not desired.
  510. pbfInterfaces receives the list of interfaces as an array of GUIDs for the
  511. given card, if any. This parameter may be NULL if the value is not
  512. desired.
  513. pbfProvider receives the Primary Provider of the given card, if any. This
  514. parameter may be NULL if the value is not desired.
  515. Return Value:
  516. TRUE - The card was found, the returned data is valid.
  517. FALSE - The supplied card was not found.
  518. Throws:
  519. None
  520. Author:
  521. Doug Barlow (dbarlow) 12/3/1996
  522. --*/
  523. BOOL
  524. GetCardInfo(
  525. IN DWORD dwScope,
  526. IN LPCTSTR szCard,
  527. OUT CBuffer *pbfAtr,
  528. OUT CBuffer *pbfAtrMask,
  529. OUT CBuffer *pbfInterfaces,
  530. OUT CBuffer *pbfProvider)
  531. {
  532. CRegistry regCard;
  533. //
  534. // Find the Card definition closest to the caller.
  535. //
  536. try
  537. {
  538. FindKey(
  539. dwScope,
  540. szCard,
  541. regCard,
  542. SCARD_REG_CARDS,
  543. SCARD_REG_TEMPLATES);
  544. }
  545. catch (...)
  546. {
  547. return FALSE;
  548. }
  549. //
  550. // Look up all it's values.
  551. //
  552. if (NULL != pbfAtr)
  553. {
  554. // Card ATR String
  555. try
  556. {
  557. regCard.GetValue(SCARD_REG_ATR, *pbfAtr);
  558. }
  559. catch (...)
  560. {
  561. pbfAtr->Reset();
  562. }
  563. }
  564. if (NULL != pbfAtrMask)
  565. {
  566. // Card ATR Comparison Mask
  567. try
  568. {
  569. regCard.GetValue(SCARD_REG_ATRMASK, *pbfAtrMask);
  570. }
  571. catch (...)
  572. {
  573. pbfAtrMask->Reset();
  574. }
  575. }
  576. if (NULL != pbfInterfaces)
  577. {
  578. // Supported Interface List
  579. try
  580. {
  581. regCard.GetValue(SCARD_REG_GUIDS, *pbfInterfaces);
  582. }
  583. catch (...)
  584. {
  585. pbfInterfaces->Reset();
  586. }
  587. }
  588. if (NULL != pbfProvider)
  589. {
  590. // Card Primary Provider
  591. try
  592. {
  593. regCard.GetValue(SCARD_REG_PPV, *pbfProvider);
  594. }
  595. catch (...)
  596. {
  597. pbfProvider->Reset();
  598. }
  599. }
  600. return TRUE;
  601. }
  602. #ifdef ENABLE_SCARD_TEMPLATES
  603. /*++
  604. ListCardTypeTemplates:
  605. This routine searches the template database looking for previously defined
  606. smart card templates against which the given card ATR matches. If the ATR
  607. parameter is NULL, it returns a list of all templates.
  608. Arguments:
  609. dwScope supplies an indicator of the scope of the operation. Possible
  610. values are:
  611. SCARD_SCOPE_USER - The current user's definitions are used.
  612. SCARD_SCOPE_TERMINAL - The terminal's definitions are used.
  613. SCARD_SCOPE_SYSTEM - The system's definitions are used.
  614. pbAtr supplies the ATR of a card to be matched against the known templates.
  615. bfTemplates receives a list of matching template names, as a multistring.
  616. Return Value:
  617. TRUE - At least one template was found.
  618. FALSE - No matching templates were found.
  619. Throws:
  620. Errors
  621. Author:
  622. Doug Barlow (dbarlow) 1/16/1998
  623. --*/
  624. BOOL
  625. ListCardTypeTemplates(
  626. IN DWORD dwScope,
  627. IN LPCBYTE pbAtr,
  628. OUT CBuffer &bfTemplates)
  629. {
  630. CRegistry regCard;
  631. LPCTSTR szCard;
  632. CBuffer bfCardAtr;
  633. CBuffer bfCardList;
  634. bfTemplates.Reset();
  635. ListKnownKeys(dwScope, bfCardList, SCARD_REG_TEMPLATES);
  636. for (szCard = FirstString(bfCardList);
  637. NULL != szCard;
  638. szCard = NextString(szCard))
  639. {
  640. try
  641. {
  642. FindKey(dwScope, szCard, regCard, SCARD_REG_TEMPLATES);
  643. //
  644. // Does this card match the supplied ATR?
  645. //
  646. if ((NULL != pbAtr) && (0 != *pbAtr))
  647. {
  648. LPCBYTE pbCardAtr, pbCardMask;
  649. DWORD cbCardAtr, cbCardMask;
  650. pbCardAtr = regCard.GetBinaryValue(
  651. SCARD_REG_ATR,
  652. &cbCardAtr);
  653. bfCardAtr.Set(pbCardAtr, cbCardAtr);
  654. try
  655. {
  656. pbCardMask = regCard.GetBinaryValue(
  657. SCARD_REG_ATRMASK,
  658. &cbCardMask);
  659. if (cbCardAtr != cbCardMask)
  660. continue; // Invalid ATR/Mask combination.
  661. }
  662. catch (...)
  663. {
  664. pbCardMask = NULL; // No mask.
  665. }
  666. if (!AtrCompare(pbAtr, bfCardAtr, pbCardMask, cbCardAtr))
  667. continue; // ATRs invalid or don't match.
  668. }
  669. //
  670. // This card passes all the tests -- Include it.
  671. //
  672. MStrAdd(bfTemplates, szCard);
  673. }
  674. catch (...) {}
  675. }
  676. if (0 == bfTemplates.Length())
  677. {
  678. bfTemplates.Set((LPCBYTE)TEXT("\000"), 2 * sizeof(TCHAR));
  679. return FALSE;
  680. }
  681. else
  682. return TRUE;
  683. }
  684. #endif // ENABLE_SCARD_TEMPLATES
  685. //
  686. ////////////////////////////////////////////////////////////////////////////////
  687. //
  688. // Support Routines
  689. //
  690. /*++
  691. ListKnownKeys:
  692. This routine lists all known keys of a given type within the current
  693. caller's scope.
  694. Arguments:
  695. dwScope supplies an indicator of the scope of the operation. Possible
  696. values are:
  697. SCARD_SCOPE_USER - The current user's definitions are used.
  698. SCARD_SCOPE_TERMINAL - The terminal's definitions are used.
  699. SCARD_SCOPE_SYSTEM - The system's definitions are used.
  700. bfKeys receives a multistring of existing key names, sorted and stripped
  701. of duplicates.
  702. szUserList supplies the primary registry path from which key names are to
  703. be returned.
  704. szSystemList supplies an optional secondary path from which key names can
  705. be returned if the caller is running at system scope.
  706. Return Value:
  707. TRUE - At least one was found
  708. FALSE - None were found.
  709. Throws:
  710. Errors are thrown as DWORD status codes.
  711. Author:
  712. Doug Barlow (dbarlow) 1/22/1998
  713. --*/
  714. static BOOL
  715. ListKnownKeys(
  716. IN DWORD dwScope,
  717. OUT CBuffer &bfKeys,
  718. IN LPCTSTR szUserList,
  719. IN LPCTSTR szSystemList)
  720. {
  721. DWORD dwSpace, dwIndex, dwCount;
  722. CRegistry regScopeKey;
  723. CBuffer bfMyList;
  724. LPCTSTR rgszLists[2];
  725. //
  726. // Loop through introduced space, then if appropriate, template space.
  727. //
  728. rgszLists[0] = szUserList;
  729. rgszLists[1] = szSystemList;
  730. for (dwSpace = 0; 2 > dwSpace; dwSpace += 1)
  731. {
  732. if (NULL == rgszLists[dwSpace])
  733. continue;
  734. //
  735. // Loop through all the possible scopes, from highest to lowest.
  736. //
  737. for (dwIndex = 0; l_dwRegMapMax > dwIndex; dwIndex += 1)
  738. {
  739. if (l_rgRegMap[dwIndex].dwScope >= dwScope)
  740. {
  741. //
  742. // If the caller is under this scope, then look for existing
  743. // Keys.
  744. //
  745. regScopeKey.Open(
  746. l_rgRegMap[dwIndex].hKey,
  747. rgszLists[dwSpace],
  748. KEY_READ);
  749. if (SCARD_S_SUCCESS != regScopeKey.Status(TRUE))
  750. continue;
  751. //
  752. // Pull out all it's subkey names.
  753. //
  754. for (dwCount = 0;; dwCount += 1)
  755. {
  756. LPCTSTR szKey;
  757. szKey = regScopeKey.Subkey(dwCount);
  758. if (NULL == szKey)
  759. break;
  760. bfMyList.Append(
  761. (LPBYTE)szKey,
  762. (lstrlen(szKey) + 1) * sizeof(TCHAR));
  763. }
  764. }
  765. }
  766. //
  767. // Don't go on to the system list unless we're at system scope.
  768. //
  769. if (SCARD_SCOPE_SYSTEM != dwScope)
  770. break;
  771. }
  772. //
  773. // Sort the list, and remove duplicates.
  774. //
  775. bfMyList.Append((LPBYTE)TEXT("\000"), 2 * sizeof(TCHAR));
  776. MStringSort(bfMyList, bfKeys);
  777. return (2 * sizeof(TCHAR) < bfKeys.Length());
  778. }
  779. /*++
  780. FindKey:
  781. This routine finds the named key closest in scope to the caller.
  782. Arguments:
  783. dwScope supplies an indicator of the scope of the operation. Possible
  784. values are:
  785. SCARD_SCOPE_USER - The current user's definitions are used.
  786. SCARD_SCOPE_TERMINAL - The terminal's definitions are used.
  787. SCARD_SCOPE_SYSTEM - The system's definitions are used.
  788. szKey supplies the name of the key to be found.
  789. regKey receives initialization to reference the named key.
  790. szUserList supplies the primary registry path from which key names are to
  791. be returned.
  792. szSystemList supplies an optional secondary path from which key names can
  793. be returned if the caller is running at system scope.
  794. Return Value:
  795. TRUE - The key was found.
  796. FALSE - No such key was found.
  797. Throws:
  798. Errors are thrown as DWORD status codes.
  799. Author:
  800. Doug Barlow (dbarlow) 1/22/1998
  801. --*/
  802. static void
  803. FindKey(
  804. IN DWORD dwScope,
  805. IN LPCTSTR szKey,
  806. OUT CRegistry &regKey,
  807. IN LPCTSTR szUserList,
  808. IN LPCTSTR szSystemList)
  809. {
  810. DWORD dwSpace, dwIndex;
  811. CRegistry regScopeKey;
  812. LPCTSTR rgszLists[2];
  813. //
  814. // Loop through introduced space, then if appropriate, template space.
  815. //
  816. rgszLists[0] = szUserList;
  817. rgszLists[1] = szSystemList;
  818. for (dwSpace = 0; 2 > dwSpace; dwSpace += 1)
  819. {
  820. if (NULL == rgszLists[dwSpace])
  821. continue;
  822. //
  823. // Loop through all the possible scopes, from highest to lowest.
  824. //
  825. for (dwIndex = 0; l_dwRegMapMax > dwIndex; dwIndex += 1)
  826. {
  827. if (l_rgRegMap[dwIndex].dwScope >= dwScope)
  828. {
  829. //
  830. // If the caller is under this scope, then look for an
  831. // existing Key.
  832. //
  833. regScopeKey.Open(
  834. l_rgRegMap[dwIndex].hKey,
  835. rgszLists[dwSpace],
  836. KEY_READ);
  837. if (SCARD_S_SUCCESS != regScopeKey.Status(TRUE))
  838. continue;
  839. regKey.Open(regScopeKey, szKey, KEY_READ);
  840. if (SCARD_S_SUCCESS != regKey.Status(TRUE))
  841. continue;
  842. //
  843. // We've found such a key. Return immediately.
  844. //
  845. return;
  846. }
  847. }
  848. //
  849. // Don't go on to the system list unless we're at system scope.
  850. //
  851. if (SCARD_SCOPE_SYSTEM != dwScope)
  852. break;
  853. }
  854. //
  855. // We didn't find any such key.
  856. //
  857. throw (DWORD)ERROR_FILE_NOT_FOUND;
  858. }