Leaked source code of windows server 2003
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.

857 lines
27 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. (c) Copyright Schlumberger Technology Corp., unpublished work, created
  4. 1999. This computer program includes Confidential, Proprietary
  5. Information and is a Trade Secret of Schlumberger Technology Corp. All
  6. use, disclosure, and/or reproduction is prohibited unless authorized
  7. in writing. All Rights Reserved.
  8. Module Name:
  9. autoreg
  10. Abstract:
  11. This module provides autoregistration capabilities to a CSP. It allows
  12. regsvr32 to call the DLL directly to add and remove Registry settings.
  13. Author:
  14. Doug Barlow (dbarlow) 3/11/1998
  15. Environment:
  16. Win32
  17. Notes:
  18. Look for "?vendor?" tags and edit appropriately.
  19. --*/
  20. #if defined(_UNICODE)
  21. #if !defined(UNICODE)
  22. #define UNICODE
  23. #endif //!UNICODE
  24. #endif //_UNICODE
  25. #if defined(UNICODE)
  26. #if !defined(_UNICODE)
  27. #define _UNICODE
  28. #endif //!_UNICODE
  29. #endif //UNICODE
  30. #ifndef WIN32_LEAN_AND_MEAN
  31. #define WIN32_LEAN_AND_MEAN
  32. #endif
  33. #ifdef _AFXDLL
  34. #include "stdafx.h"
  35. #else
  36. #include <windows.h>
  37. #endif
  38. #include <string>
  39. #include <basetsd.h>
  40. #include <wincrypt.h>
  41. #include <cspdk.h> // CRYPT_SIG_RESOURCE_NUMBER
  42. #include <winscard.h>
  43. #include <tchar.h>
  44. #include "CspProfile.h"
  45. #include "Blob.h"
  46. #include "StResource.h"
  47. using namespace std;
  48. using namespace ProviderProfile;
  49. namespace
  50. {
  51. typedef DWORD
  52. (*LPSETCARDTYPEPROVIDERNAME)(IN SCARDCONTEXT hContext,
  53. IN LPCTSTR szCardName,
  54. IN DWORD dwProviderId,
  55. IN LPCTSTR szProvider);
  56. LPCTSTR szCardRegPath =
  57. TEXT("SOFTWARE\\Microsoft\\Cryptography\\Calais\\SmartCards");
  58. // Remove the legacy Cryptoflex card from the registry. This
  59. // will ease transition of W2K beta users to its commercial
  60. // release as well as Cryptoflex SDK 1.x users. The supported
  61. // cards are added by IntroduceVendorCard.
  62. LPCTSTR aCardsToForget[] =
  63. {
  64. TEXT("Schlumberger Cryptoflex"),
  65. TEXT("Schlumberger Cryptoflex 4k"),
  66. TEXT("Schlumberger Cryptoflex 8k"),
  67. TEXT("Schlumberger Cryptoflex 8k v2")
  68. };
  69. HRESULT
  70. ForgetVendorCard(LPCTSTR szCardToForget)
  71. {
  72. bool fCardIsForgotten = false;
  73. HRESULT hReturnStatus = NO_ERROR;
  74. #if !defined(UNICODE)
  75. string
  76. #else
  77. wstring
  78. #endif // !defined(UNICODE)
  79. sRegCardToForget(szCardRegPath);
  80. sRegCardToForget.append(TEXT("\\"));
  81. sRegCardToForget.append(szCardToForget);
  82. for (DWORD dwIndex = 0; !fCardIsForgotten; dwIndex += 1)
  83. {
  84. HKEY hCalais(0);
  85. SCARDCONTEXT hCtx(0);
  86. DWORD dwStatus;
  87. LONG nStatus;
  88. switch (dwIndex)
  89. {
  90. case 0:
  91. dwStatus = SCardEstablishContext(SCARD_SCOPE_SYSTEM, 0, 0, &hCtx);
  92. if (ERROR_SUCCESS != dwStatus)
  93. continue;
  94. dwStatus = SCardForgetCardType(hCtx,
  95. szCardToForget);
  96. if (ERROR_SUCCESS != dwStatus)
  97. continue;
  98. dwStatus = SCardReleaseContext(hCtx);
  99. hCtx = NULL;
  100. if (ERROR_SUCCESS != dwStatus)
  101. {
  102. if (0 == (dwStatus & 0xffff0000))
  103. hReturnStatus = HRESULT_FROM_WIN32(dwStatus);
  104. else
  105. hReturnStatus = (HRESULT)dwStatus;
  106. goto ErrorExit;
  107. }
  108. // Ignore the return code since the previous probably deleted it.
  109. nStatus = RegDeleteKey(HKEY_LOCAL_MACHINE,
  110. sRegCardToForget.c_str());
  111. fCardIsForgotten = true;
  112. break;
  113. case 1:
  114. // Last try, if not successful then it must not exist...
  115. nStatus = RegDeleteKey(HKEY_LOCAL_MACHINE,
  116. sRegCardToForget.c_str());
  117. fCardIsForgotten = true;
  118. break;
  119. default:
  120. hReturnStatus = ERROR_ACCESS_DENIED;
  121. goto ErrorExit;
  122. }
  123. ErrorExit:
  124. if (NULL != hCtx)
  125. SCardReleaseContext(hCtx);
  126. if (NULL != hCalais)
  127. RegCloseKey(hCalais);
  128. break;
  129. }
  130. return hReturnStatus;
  131. }
  132. HRESULT
  133. IntroduceVendorCard(CString const &rsCspName,
  134. CardProfile const &rcp)
  135. {
  136. // Try various techniques until one works.
  137. ATR const &ratr = rcp.ATR();
  138. bool fCardIntroduced = false;
  139. HRESULT hReturnStatus = NO_ERROR;
  140. for (DWORD dwIndex = 0; !fCardIntroduced; dwIndex += 1)
  141. {
  142. HKEY hCalais(0);
  143. SCARDCONTEXT hCtx(0);
  144. DWORD dwDisp;
  145. DWORD dwStatus;
  146. LONG nStatus;
  147. HKEY hVendor(0);
  148. switch (dwIndex)
  149. {
  150. case 0:
  151. {
  152. HMODULE hWinSCard = NULL;
  153. LPSETCARDTYPEPROVIDERNAME pfSetCardTypeProviderName = NULL;
  154. hWinSCard = GetModuleHandle(TEXT("WinSCard.DLL"));
  155. if (NULL == hWinSCard)
  156. continue;
  157. #if defined(UNICODE)
  158. pfSetCardTypeProviderName =
  159. reinterpret_cast<LPSETCARDTYPEPROVIDERNAME>(GetProcAddress(hWinSCard,
  160. AsCCharP(TEXT("SCardSetCardTypeProviderNameW"))));
  161. #else
  162. pfSetCardTypeProviderName =
  163. reinterpret_cast<LPSETCARDTYPEPROVIDERNAME>(GetProcAddress(hWinSCard,
  164. TEXT("SCardSetCardTypeProviderNameA")));
  165. #endif
  166. if (!pfSetCardTypeProviderName)
  167. continue;
  168. dwStatus = SCardIntroduceCardType(NULL,
  169. (LPCTSTR)rcp.csRegistryName(),
  170. NULL, NULL, 0,
  171. ratr.String(),
  172. ratr.Mask(),
  173. ratr.Size());
  174. if ((ERROR_SUCCESS != dwStatus) &&
  175. (ERROR_ALREADY_EXISTS != dwStatus))
  176. continue;
  177. dwStatus = (*pfSetCardTypeProviderName)(NULL,
  178. (LPCTSTR)rcp.csRegistryName(),
  179. SCARD_PROVIDER_CSP,
  180. (LPCTSTR)rsCspName);
  181. if (ERROR_SUCCESS != dwStatus)
  182. {
  183. if (0 == (dwStatus & 0xffff0000))
  184. hReturnStatus = HRESULT_FROM_WIN32(dwStatus);
  185. else
  186. hReturnStatus = (HRESULT)dwStatus;
  187. goto ErrorExit;
  188. }
  189. fCardIntroduced = TRUE;
  190. break;
  191. }
  192. case 1:
  193. dwStatus = SCardEstablishContext(SCARD_SCOPE_SYSTEM, 0, 0, &hCtx);
  194. if (ERROR_SUCCESS != dwStatus)
  195. continue;
  196. dwStatus = SCardIntroduceCardType(hCtx,
  197. (LPCTSTR)rcp.csRegistryName(),
  198. &rcp.PrimaryProvider(),
  199. NULL, 0, ratr.String(),
  200. ratr.Mask(),
  201. ratr.Size());
  202. if ((ERROR_SUCCESS != dwStatus)
  203. && (ERROR_ALREADY_EXISTS != dwStatus))
  204. {
  205. if (0 == (dwStatus & 0xffff0000))
  206. hReturnStatus = HRESULT_FROM_WIN32(dwStatus);
  207. else
  208. hReturnStatus = (HRESULT)dwStatus;
  209. goto ErrorExit;
  210. }
  211. dwStatus = SCardReleaseContext(hCtx);
  212. hCtx = NULL;
  213. if (ERROR_SUCCESS != dwStatus)
  214. {
  215. if (0 == (dwStatus & 0xffff0000))
  216. hReturnStatus = HRESULT_FROM_WIN32(dwStatus);
  217. else
  218. hReturnStatus = (HRESULT)dwStatus;
  219. goto ErrorExit;
  220. }
  221. nStatus = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  222. TEXT("SOFTWARE\\Microsoft\\Cryptography\\Calais\\SmartCards"),
  223. 0, TEXT(""),
  224. REG_OPTION_NON_VOLATILE,
  225. KEY_ALL_ACCESS, NULL, &hCalais,
  226. &dwDisp);
  227. if (ERROR_SUCCESS != nStatus)
  228. {
  229. hReturnStatus = HRESULT_FROM_WIN32(nStatus);
  230. goto ErrorExit;
  231. }
  232. nStatus = RegCreateKeyEx(hCalais, (LPCTSTR)rcp.csRegistryName(),
  233. 0, TEXT(""),
  234. REG_OPTION_NON_VOLATILE,
  235. KEY_ALL_ACCESS, NULL, &hVendor,
  236. &dwDisp);
  237. if (ERROR_SUCCESS != nStatus)
  238. {
  239. hReturnStatus = HRESULT_FROM_WIN32(nStatus);
  240. goto ErrorExit;
  241. }
  242. nStatus = RegCloseKey(hCalais);
  243. hCalais = NULL;
  244. if (ERROR_SUCCESS != nStatus)
  245. {
  246. hReturnStatus = HRESULT_FROM_WIN32(nStatus);
  247. goto ErrorExit;
  248. }
  249. nStatus = RegSetValueEx(hVendor, TEXT("Crypto Provider"),
  250. 0, REG_SZ,
  251. reinterpret_cast<LPCBYTE>((LPCTSTR)rsCspName),
  252. (_tcslen((LPCTSTR)rsCspName) +
  253. 1) * sizeof TCHAR);
  254. if (ERROR_SUCCESS != nStatus)
  255. {
  256. hReturnStatus = HRESULT_FROM_WIN32(nStatus);
  257. goto ErrorExit;
  258. }
  259. nStatus = RegCloseKey(hVendor);
  260. hVendor = NULL;
  261. if (ERROR_SUCCESS != nStatus)
  262. {
  263. hReturnStatus = HRESULT_FROM_WIN32(nStatus);
  264. goto ErrorExit;
  265. }
  266. fCardIntroduced = TRUE;
  267. break;
  268. case 2:
  269. nStatus = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  270. TEXT("SOFTWARE\\Microsoft\\Cryptography\\Calais\\SmartCards"),
  271. 0, TEXT(""),
  272. REG_OPTION_NON_VOLATILE,
  273. KEY_ALL_ACCESS, NULL, &hCalais,
  274. &dwDisp);
  275. if (ERROR_SUCCESS != nStatus)
  276. continue;
  277. nStatus = RegCreateKeyEx(hCalais,
  278. (LPCTSTR)rcp.csRegistryName(), 0,
  279. TEXT(""),
  280. REG_OPTION_NON_VOLATILE,
  281. KEY_ALL_ACCESS, NULL, &hVendor,
  282. &dwDisp);
  283. if (ERROR_SUCCESS != nStatus)
  284. {
  285. hReturnStatus = HRESULT_FROM_WIN32(nStatus);
  286. goto ErrorExit;
  287. }
  288. nStatus = RegCloseKey(hCalais);
  289. hCalais = NULL;
  290. if (ERROR_SUCCESS != nStatus)
  291. {
  292. hReturnStatus = HRESULT_FROM_WIN32(nStatus);
  293. goto ErrorExit;
  294. }
  295. nStatus = RegSetValueEx(hVendor, TEXT("Primary Provider"),
  296. 0, REG_BINARY,
  297. (LPCBYTE)&rcp.PrimaryProvider(),
  298. sizeof LPCBYTE);
  299. if (ERROR_SUCCESS != nStatus)
  300. {
  301. hReturnStatus = HRESULT_FROM_WIN32(nStatus);
  302. goto ErrorExit;
  303. }
  304. nStatus = RegSetValueEx(hVendor, TEXT("ATR"), 0,
  305. REG_BINARY, ratr.String(),
  306. ratr.Size());
  307. if (ERROR_SUCCESS != nStatus)
  308. {
  309. hReturnStatus = HRESULT_FROM_WIN32(nStatus);
  310. goto ErrorExit;
  311. }
  312. nStatus = RegSetValueEx(hVendor, TEXT("ATRMask"), 0,
  313. REG_BINARY, ratr.Mask(),
  314. ratr.Size());
  315. if (ERROR_SUCCESS != nStatus)
  316. {
  317. hReturnStatus = HRESULT_FROM_WIN32(nStatus);
  318. goto ErrorExit;
  319. }
  320. nStatus = RegSetValueEx(hVendor, TEXT("Crypto Provider"),
  321. 0, REG_SZ,
  322. reinterpret_cast<LPCBYTE>((LPCTSTR)rsCspName),
  323. (_tcslen((LPCTSTR)rsCspName) + 1) * sizeof TCHAR);
  324. if (ERROR_SUCCESS != nStatus)
  325. {
  326. hReturnStatus = HRESULT_FROM_WIN32(nStatus);
  327. goto ErrorExit;
  328. }
  329. nStatus = RegCloseKey(hVendor);
  330. hVendor = NULL;
  331. if (ERROR_SUCCESS != nStatus)
  332. {
  333. hReturnStatus = HRESULT_FROM_WIN32(nStatus);
  334. goto ErrorExit;
  335. }
  336. fCardIntroduced = TRUE;
  337. break;
  338. default:
  339. hReturnStatus = ERROR_ACCESS_DENIED;
  340. goto ErrorExit;
  341. }
  342. ErrorExit:
  343. if (NULL != hCtx)
  344. SCardReleaseContext(hCtx);
  345. if (NULL != hCalais)
  346. RegCloseKey(hCalais);
  347. if (NULL != hVendor)
  348. RegCloseKey(hVendor);
  349. break;
  350. }
  351. return hReturnStatus;
  352. }
  353. } // namespace
  354. /*++
  355. DllUnregisterServer:
  356. This service removes the registry entries associated with this CSP.
  357. Arguments:
  358. None
  359. Return Value:
  360. Status code as an HRESULT.
  361. Author:
  362. Doug Barlow (dbarlow) 3/11/1998
  363. --*/
  364. STDAPI
  365. DllUnregisterServer(void)
  366. {
  367. LONG nStatus;
  368. DWORD dwDisp;
  369. HRESULT hReturnStatus = NO_ERROR;
  370. HKEY hProviders = NULL;
  371. SCARDCONTEXT hCtx = NULL;
  372. CString sProvName;
  373. #ifdef _AFXDLL
  374. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  375. #endif
  376. CspProfile const &rProfile = CspProfile::Instance();
  377. sProvName = rProfile.Name();
  378. //
  379. // Delete the Registry key for this CSP.
  380. //
  381. nStatus = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  382. TEXT("SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider"),
  383. 0, TEXT(""), REG_OPTION_NON_VOLATILE,
  384. KEY_ALL_ACCESS, NULL, &hProviders, &dwDisp);
  385. if (ERROR_SUCCESS == nStatus)
  386. {
  387. RegDeleteKey(hProviders, (LPCTSTR)sProvName);
  388. RegCloseKey(hProviders);
  389. hProviders = NULL;
  390. }
  391. //
  392. // Remove the cards introduced.
  393. //
  394. {
  395. vector<CardProfile> const &rvcp = rProfile.Cards();
  396. for (vector<CardProfile>::const_iterator it = rvcp.begin();
  397. it != rvcp.end(); ++it)
  398. {
  399. hReturnStatus = ForgetVendorCard((LPCTSTR)(it->csRegistryName()));
  400. if (NO_ERROR != hReturnStatus)
  401. break;
  402. }
  403. if (NO_ERROR != hReturnStatus)
  404. goto ErrorExit;
  405. }
  406. //
  407. // Forget the card type.
  408. //
  409. hCtx = NULL;
  410. SCardEstablishContext(SCARD_SCOPE_SYSTEM, 0, 0, &hCtx);
  411. SCardForgetCardType(hCtx, (LPCTSTR)sProvName);
  412. if (NULL != hCtx)
  413. {
  414. SCardReleaseContext(hCtx);
  415. hCtx = NULL;
  416. }
  417. //
  418. // All done!
  419. //
  420. ErrorExit:
  421. return hReturnStatus;
  422. }
  423. /*++
  424. DllRegisterServer:
  425. This function installs the proper registry entries to enable this CSP.
  426. Arguments:
  427. None
  428. Return Value:
  429. Status code as an HRESULT.
  430. Author:
  431. Doug Barlow (dbarlow) 3/11/1998
  432. --*/
  433. STDAPI
  434. DllRegisterServer(void)
  435. {
  436. TCHAR szModulePath[MAX_PATH+1]; // Security: Leave room to zero
  437. // terminate the buffer for
  438. // subsequent operations.
  439. BYTE pbSignature[136]; // Room for a 1024 bit signature, with padding.
  440. OSVERSIONINFO osVer;
  441. LPTSTR szFileName, szFileExt;
  442. HINSTANCE hThisDll;
  443. HRSRC hSigResource;
  444. DWORD dwStatus;
  445. LONG nStatus;
  446. BOOL fStatus;
  447. DWORD dwDisp;
  448. DWORD dwIndex;
  449. DWORD dwSigLength = 0;
  450. HRESULT hReturnStatus = NO_ERROR;
  451. HKEY hProviders = NULL;
  452. HKEY hMyCsp = NULL;
  453. HKEY hCalais = NULL;
  454. HKEY hVendor = NULL;
  455. BOOL fSignatureFound = FALSE;
  456. HANDLE hSigFile = INVALID_HANDLE_VALUE;
  457. SCARDCONTEXT hCtx = NULL;
  458. CString sProvName;
  459. // TO DO: Card registration should be made by the CCI/IOP, not
  460. // the CSP.
  461. #ifdef _AFXDLL
  462. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  463. #endif
  464. CspProfile const &rProfile = CspProfile::Instance();
  465. //
  466. // Figure out the file name and path.
  467. //
  468. hThisDll = rProfile.DllInstance();
  469. if (NULL == hThisDll)
  470. {
  471. hReturnStatus = HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE);
  472. goto ErrorExit;
  473. }
  474. dwStatus = GetModuleFileName(hThisDll, szModulePath,
  475. sizeof(szModulePath)/sizeof(TCHAR));
  476. if (0 == dwStatus)
  477. {
  478. hReturnStatus = HRESULT_FROM_WIN32(GetLastError());
  479. goto ErrorExit;
  480. }
  481. // Zero terminate buffer.
  482. szModulePath[dwStatus] = 0;
  483. szFileName = _tcsrchr(szModulePath, TEXT('\\'));
  484. if (NULL == szFileName)
  485. szFileName = szModulePath;
  486. else
  487. szFileName += 1;
  488. szFileExt = _tcsrchr(szFileName, TEXT('.'));
  489. if (NULL == szFileExt)
  490. {
  491. hReturnStatus = HRESULT_FROM_WIN32(ERROR_INVALID_NAME);
  492. goto ErrorExit;
  493. }
  494. else
  495. szFileExt += 1;
  496. //
  497. // Create the Registry key for this CSP.
  498. //
  499. nStatus = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  500. TEXT("SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider"),
  501. 0, TEXT(""), REG_OPTION_NON_VOLATILE,
  502. KEY_ALL_ACCESS, NULL, &hProviders,
  503. &dwDisp);
  504. if (ERROR_SUCCESS != nStatus)
  505. {
  506. hReturnStatus = HRESULT_FROM_WIN32(nStatus);
  507. goto ErrorExit;
  508. }
  509. sProvName = rProfile.Name();
  510. nStatus = RegCreateKeyEx(hProviders, (LPCTSTR)sProvName, 0,
  511. TEXT(""), REG_OPTION_NON_VOLATILE,
  512. KEY_ALL_ACCESS, NULL, &hMyCsp, &dwDisp);
  513. if (ERROR_SUCCESS != nStatus)
  514. {
  515. hReturnStatus = HRESULT_FROM_WIN32(nStatus);
  516. goto ErrorExit;
  517. }
  518. nStatus = RegCloseKey(hProviders);
  519. hProviders = NULL;
  520. if (ERROR_SUCCESS != nStatus)
  521. {
  522. hReturnStatus = HRESULT_FROM_WIN32(nStatus);
  523. goto ErrorExit;
  524. }
  525. //
  526. // Install the trivial registry values.
  527. //
  528. // Security/sysprep requirement: the module path must be replaced
  529. // with just the dll name to faclilitate sysprep. Corresponding
  530. // changes to LoadLibrary imply that there are no security risks
  531. // for system processes. The security implications of such
  532. // installation for applications is an open question.
  533. nStatus = RegSetValueEx(hMyCsp, TEXT("Image Path"), 0, REG_SZ,
  534. (LPBYTE)szFileName,//szModulePath,
  535. (_tcslen(szFileName/*szModulePath*/) + 1) * sizeof(TCHAR));
  536. if (ERROR_SUCCESS != nStatus)
  537. {
  538. hReturnStatus = HRESULT_FROM_WIN32(nStatus);
  539. goto ErrorExit;
  540. }
  541. {
  542. DWORD ProviderType = rProfile.Type();
  543. nStatus = RegSetValueEx(hMyCsp, TEXT("Type"), 0, REG_DWORD,
  544. (LPBYTE)&ProviderType,
  545. sizeof ProviderType);
  546. if (ERROR_SUCCESS != nStatus)
  547. {
  548. hReturnStatus = HRESULT_FROM_WIN32(nStatus);
  549. goto ErrorExit;
  550. }
  551. }
  552. //
  553. // See if we're self-signed. On NT5, CSP images can carry their own
  554. // signatures.
  555. //
  556. hSigResource = FindResource(hThisDll,
  557. MAKEINTRESOURCE(CRYPT_SIG_RESOURCE_NUMBER),
  558. RT_RCDATA);
  559. //
  560. // Install the file signature.
  561. //
  562. ZeroMemory(&osVer, sizeof(OSVERSIONINFO));
  563. osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  564. fStatus = GetVersionEx(&osVer);
  565. if (fStatus &&
  566. (VER_PLATFORM_WIN32_NT == osVer.dwPlatformId) &&
  567. (5 <= osVer.dwMajorVersion) &&
  568. (NULL != hSigResource))
  569. {
  570. //
  571. // Signature in file flag is sufficient.
  572. //
  573. dwStatus = 0;
  574. nStatus = RegSetValueEx(hMyCsp, TEXT("SigInFile"), 0,
  575. REG_DWORD, (LPBYTE)&dwStatus,
  576. sizeof(DWORD));
  577. if (ERROR_SUCCESS != nStatus)
  578. {
  579. hReturnStatus = HRESULT_FROM_WIN32(nStatus);
  580. goto ErrorExit;
  581. }
  582. }
  583. else
  584. {
  585. //
  586. // We have to install a signature entry.
  587. // Try various techniques until one works.
  588. //
  589. for (dwIndex = 0; !fSignatureFound; dwIndex += 1)
  590. {
  591. switch (dwIndex)
  592. {
  593. //
  594. // Look for an external *.sig file and load that into the registry.
  595. //
  596. case 0:
  597. _tcscpy(szFileExt, TEXT("sig"));
  598. hSigFile = CreateFile(
  599. szModulePath,
  600. GENERIC_READ,
  601. FILE_SHARE_READ,
  602. NULL,
  603. OPEN_EXISTING,
  604. FILE_ATTRIBUTE_NORMAL,
  605. NULL);
  606. if (INVALID_HANDLE_VALUE == hSigFile)
  607. continue;
  608. dwSigLength = GetFileSize(hSigFile, NULL);
  609. if ((dwSigLength > sizeof(pbSignature))
  610. || (dwSigLength < 72)) // Accept a 512-bit signature
  611. {
  612. hReturnStatus = NTE_BAD_SIGNATURE;
  613. goto ErrorExit;
  614. }
  615. fStatus = ReadFile(
  616. hSigFile,
  617. pbSignature,
  618. sizeof(pbSignature),
  619. &dwSigLength,
  620. NULL);
  621. if (!fStatus)
  622. {
  623. hReturnStatus = HRESULT_FROM_WIN32(GetLastError());
  624. goto ErrorExit;
  625. }
  626. fStatus = CloseHandle(hSigFile);
  627. hSigFile = NULL;
  628. if (!fStatus)
  629. {
  630. hReturnStatus = HRESULT_FROM_WIN32(GetLastError());
  631. goto ErrorExit;
  632. }
  633. fSignatureFound = TRUE;
  634. break;
  635. //
  636. // Other cases may be added in the future.
  637. //
  638. default:
  639. hReturnStatus = NTE_BAD_SIGNATURE;
  640. goto ErrorExit;
  641. }
  642. if (fSignatureFound)
  643. {
  644. for (dwIndex = 0; dwIndex < dwSigLength; dwIndex += 1)
  645. {
  646. if (0 != pbSignature[dwIndex])
  647. break;
  648. }
  649. if (dwIndex >= dwSigLength)
  650. fSignatureFound = FALSE;
  651. }
  652. }
  653. //
  654. // We've found a signature somewhere! Install it.
  655. //
  656. nStatus = RegSetValueEx(
  657. hMyCsp,
  658. TEXT("Signature"),
  659. 0,
  660. REG_BINARY,
  661. pbSignature,
  662. dwSigLength);
  663. if (ERROR_SUCCESS != nStatus)
  664. {
  665. hReturnStatus = HRESULT_FROM_WIN32(nStatus);
  666. goto ErrorExit;
  667. }
  668. }
  669. nStatus = RegCloseKey(hMyCsp);
  670. hMyCsp = NULL;
  671. if (ERROR_SUCCESS != nStatus)
  672. {
  673. hReturnStatus = HRESULT_FROM_WIN32(nStatus);
  674. goto ErrorExit;
  675. }
  676. for (dwIndex = 0;
  677. dwIndex < (sizeof aCardsToForget / sizeof *aCardsToForget);
  678. dwIndex++)
  679. {
  680. hReturnStatus = ForgetVendorCard(aCardsToForget[dwIndex]);
  681. if (NO_ERROR != hReturnStatus)
  682. goto ErrorExit;
  683. }
  684. //
  685. // Introduce the vendor cards. Try various techniques until one works.
  686. //
  687. {
  688. vector<CardProfile> const &rvcp = rProfile.Cards();
  689. for (vector<CardProfile>::const_iterator it = rvcp.begin();
  690. it != rvcp.end(); ++it)
  691. {
  692. hReturnStatus = IntroduceVendorCard(rProfile.Name(), *it);
  693. if (NO_ERROR != hReturnStatus)
  694. break;
  695. }
  696. if (NO_ERROR != hReturnStatus)
  697. goto ErrorExit;
  698. }
  699. //
  700. // ?vendor?
  701. // Add any additional initialization required here.
  702. //
  703. //
  704. // All done!
  705. //
  706. return hReturnStatus;
  707. //
  708. // An error was detected. Clean up any outstanding resources and
  709. // return the error.
  710. //
  711. ErrorExit:
  712. if (NULL != hCtx)
  713. SCardReleaseContext(hCtx);
  714. if (NULL != hCalais)
  715. RegCloseKey(hCalais);
  716. if (NULL != hVendor)
  717. RegCloseKey(hVendor);
  718. if (INVALID_HANDLE_VALUE != hSigFile)
  719. CloseHandle(hSigFile);
  720. if (NULL != hMyCsp)
  721. RegCloseKey(hMyCsp);
  722. if (NULL != hProviders)
  723. RegCloseKey(hProviders);
  724. DllUnregisterServer();
  725. return hReturnStatus;
  726. }