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.

761 lines
23 KiB

  1. // iop.cpp -- Definition of CIOP
  2. // (c) Copyright Schlumberger Technology Corp., unpublished work, created
  3. // 2000. This computer program includes Confidential, Proprietary
  4. // Information and is a Trade Secret of Schlumberger Technology Corp. All
  5. // use, disclosure, and/or reproduction is prohibited unless authorized
  6. // in writing. All Rights Reserved.
  7. #include <tchar.h>
  8. #include <string>
  9. #include <scuOsExc.h>
  10. #include <scuOsVersion.h>
  11. #include <scuArrayP.h>
  12. #include "iop.h"
  13. #include <aclapi.h>
  14. #include "LockWrap.h"
  15. using namespace std;
  16. namespace
  17. {
  18. char g_szSLBRegistryPath[] = "SOFTWARE\\Schlumberger";
  19. char g_szTerminalsName[] = "Smart Cards and Terminals";
  20. char g_szCardName[] = "Smart Cards";
  21. char g_szCrypto4KName[] = "Cryptoflex 4K";
  22. char g_szOldCrypto8KName[] = "Cryptoflex 8K (no RSA key generation)";
  23. char g_szNewCrypto8KName[] = "Cryptoflex 8K (with RSA key generation)";
  24. char g_szCrypto8KV2Name[] = "Cryptoflex 8K (V2)";
  25. char g_szAccessName[] = "Cyberflex Access 16K";
  26. char g_sze_gateName[] = "Schlumberger Cryptoflex e-gate";
  27. char g_szCrypto16KName[] = "Cryptoflex 16K";
  28. char g_szAccessCampus[] = "Schlumberger Cyberflex Access Campus";
  29. char g_szCryptoActivCard[] = "Schlumberger Cryptoflex ActivCard";
  30. string
  31. CardPath()
  32. {
  33. static string sPath = string(g_szSLBRegistryPath) +
  34. string("\\") + string(g_szTerminalsName) + string("\\") +
  35. string(g_szCardName);
  36. return sPath;
  37. }
  38. #if defined(SLBIOP_WAIT_FOR_RM_STARTUP)
  39. HANDLE GetSCResourceManagerStartedEvent(void)
  40. {
  41. typedef HANDLE (*LPCALAISACCESSEVENT)(void);
  42. HANDLE hReturn = NULL;
  43. try
  44. {
  45. HMODULE hWinScard = GetModuleHandle(TEXT("WINSCARD.DLL"));
  46. if (NULL != hWinScard)
  47. {
  48. LPCALAISACCESSEVENT pfCalais =
  49. (LPCALAISACCESSEVENT)GetProcAddress(hWinScard,
  50. "SCardAccessStartedEvent");
  51. if (NULL != pfCalais)
  52. {
  53. hReturn = (*pfCalais)();
  54. }
  55. }
  56. }
  57. catch (...)
  58. {
  59. hReturn = NULL;
  60. }
  61. return hReturn;
  62. }
  63. #endif // defined(SLBIOP_WAIT_FOR_RM_STARTUP)
  64. }
  65. namespace iop
  66. {
  67. CIOP::CIOP()
  68. : m_hContext(NULL)
  69. {
  70. // Ensure that resorce manager is running, then Establish context
  71. if (!CIOP::WaitForSCManager())
  72. throw Exception(ccResourceManagerDisabled);
  73. HRESULT hResult = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &m_hContext);
  74. if (SCARD_S_SUCCESS != hResult)
  75. throw scu::OsException(hResult);
  76. }
  77. CIOP::~CIOP()
  78. {
  79. SCardReleaseContext(m_hContext);
  80. }
  81. CSmartCard *
  82. CIOP::Connect(const char* szReaderName,
  83. bool fExclusiveMode)
  84. {
  85. HRESULT hResult = NOERROR;
  86. DWORD dwShare = (fExclusiveMode ? SCARD_SHARE_EXCLUSIVE : SCARD_SHARE_SHARED);
  87. DWORD dwProtocol;
  88. SCARDHANDLE hCard;
  89. // Grab our Mutex. This is a hack around an RM bug.
  90. CIOPLock TempLock(szReaderName); // This is ok as long as one do not try to do SCard locking
  91. CIOPMutex tempMutex(&TempLock);
  92. // Connect to the reader
  93. hResult = SCardConnect(m_hContext, szReaderName, dwShare,
  94. SCARD_PROTOCOL_T0, &hCard, &dwProtocol);
  95. if (hResult != SCARD_S_SUCCESS)
  96. throw scu::OsException(hResult);
  97. // Get the ATR and determine card type
  98. DWORD dwBufferLen = 0;
  99. DWORD dwState;
  100. BYTE bATR[CSmartCard::cMaxAtrLength];
  101. DWORD dwATRLen = sizeof bATR / sizeof *bATR;
  102. hResult = SCardStatus(hCard,NULL, &dwBufferLen, &dwState,
  103. &dwProtocol, bATR, &dwATRLen);
  104. if (hResult != SCARD_S_SUCCESS)
  105. throw scu::OsException(hResult);
  106. // Create a SmartCard of the right type.
  107. CSmartCard *psc = CreateCard(bATR, dwATRLen, hCard, szReaderName, dwShare);
  108. return psc;
  109. }
  110. // This function creates a smart card of the appropriate type
  111. CSmartCard * CIOP::CreateCard(const BYTE* bATR,
  112. const DWORD dwLength,
  113. const SCARDHANDLE hCard,
  114. const char* szReaderName,
  115. const DWORD dwShareMode)
  116. {
  117. ////////////////////////////////////
  118. // Open path to registered keys //
  119. ////////////////////////////////////
  120. HKEY hkCardKey;
  121. HKEY hkTestKey;
  122. RegOpenKeyEx(HKEY_LOCAL_MACHINE, CardPath().c_str(), NULL,
  123. KEY_READ, &hkCardKey);
  124. //////////////////////////////////////////////
  125. // Enumerate subkeys to find an ATR match //
  126. //////////////////////////////////////////////
  127. FILETIME fileTime;
  128. char szATR[] = "ATR";
  129. char szMask[] = "ATR Mask";
  130. char szCardType[] = "Card Type";
  131. char sBuffer[MAX_PATH + 1];
  132. BYTE bATRtest[CSmartCard::cMaxAtrLength];
  133. BYTE bMask[CSmartCard::cMaxAtrLength];
  134. BYTE type;
  135. char szCardName[MAX_PATH + 1];
  136. DWORD dwBufferSize = sizeof(sBuffer);
  137. DWORD dwATRSize = sizeof bATRtest / sizeof *bATRtest;
  138. DWORD dwMaskSize = sizeof bMask / sizeof *bMask;
  139. DWORD dwTypeSize = 1;
  140. DWORD index = 0;
  141. LONG iRetVal = RegEnumKeyEx(hkCardKey, index, sBuffer,
  142. &dwBufferSize, NULL, NULL, NULL,
  143. &fileTime);
  144. while (iRetVal == ERROR_SUCCESS)
  145. {
  146. strcpy(szCardName, sBuffer);
  147. RegOpenKeyEx(hkCardKey, sBuffer, NULL, KEY_READ, &hkTestKey);
  148. RegQueryValueEx(hkTestKey, szATR, NULL, NULL, bATRtest, &dwATRSize);
  149. RegQueryValueEx(hkTestKey, szMask, NULL, NULL, bMask, &dwMaskSize);
  150. RegQueryValueEx(hkTestKey, szCardType, NULL, NULL, &type, &dwTypeSize);
  151. if (dwATRSize == dwLength)
  152. {
  153. scu::AutoArrayPtr<BYTE> aabMaskedATR(new BYTE[dwATRSize]);
  154. for (DWORD count = 0; count < dwATRSize; count++)
  155. aabMaskedATR[count] = bATR[count] & bMask[count];
  156. if (!memcmp(aabMaskedATR.Get(), bATRtest, dwATRSize))
  157. break;
  158. }
  159. index++;
  160. dwBufferSize = sizeof(sBuffer);
  161. dwATRSize = sizeof bATRtest / sizeof *bATRtest;
  162. dwMaskSize = sizeof bMask / sizeof *bMask;
  163. RegCloseKey(hkTestKey);
  164. iRetVal = RegEnumKeyEx(hkCardKey, index, sBuffer, &dwBufferSize, NULL, NULL, NULL, &fileTime);
  165. }
  166. // if loop was broken, iRetVal is still ERROR_SUCCESS, and type holds correct card to use
  167. CSmartCard *retVal = NULL;
  168. if (iRetVal == ERROR_SUCCESS)
  169. {
  170. switch (type)
  171. {
  172. case CRYPTO_CARD: retVal = new CCryptoCard(hCard,
  173. szReaderName,
  174. m_hContext,
  175. dwShareMode);
  176. break;
  177. case ACCESS_CARD: retVal = new CAccessCard(hCard,
  178. szReaderName,
  179. m_hContext,
  180. dwShareMode);
  181. break;
  182. default: throw Exception(ccUnknownCard);
  183. break;
  184. }
  185. }
  186. // loop wasn't broken, i.e., ATR not found. Try to make an Access Card.
  187. else
  188. retVal = new CAccessCard(hCard, szReaderName, m_hContext,
  189. dwShareMode);
  190. retVal->setCardName(szCardName);
  191. return retVal;
  192. }
  193. void
  194. CIOP::ListReaders(char* szReadersList, int &iSizeOfList)
  195. {
  196. DWORD dwSize = static_cast<DWORD>(iSizeOfList);
  197. LONG lRet;
  198. lRet = SCardListReaders(m_hContext, NULL, szReadersList, &dwSize);
  199. iSizeOfList = static_cast<int>(dwSize);
  200. if (SCARD_S_SUCCESS != lRet)
  201. throw scu::OsException(lRet);
  202. }
  203. void
  204. CIOP::ListKnownCards(char* szCardList, int& iSizeOfList)
  205. {
  206. ////////////////////////////////////
  207. // Open path to registered keys //
  208. ////////////////////////////////////
  209. LONG rv;
  210. HKEY hkCardKey;
  211. rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, CardPath().c_str(), NULL,
  212. KEY_READ, &hkCardKey);
  213. if(ERROR_SUCCESS != rv)
  214. throw scu::OsException(rv);
  215. ///////////////////////////////////////////
  216. // Enumerate subkeys to get card names //
  217. ///////////////////////////////////////////
  218. FILETIME fileTime;
  219. char sBuffer[1024];
  220. DWORD dwBufferSize = sizeof sBuffer / sizeof *sBuffer;
  221. int iTotalSize = 0;
  222. int index = 0;
  223. memset(sBuffer, 0, dwBufferSize);
  224. scu::AutoArrayPtr<char> aaszCardListBuffer(new char[iSizeOfList]);
  225. memset(aaszCardListBuffer.Get(), 0, iSizeOfList);
  226. rv = RegEnumKeyEx(hkCardKey, index++, sBuffer, &dwBufferSize,
  227. NULL, NULL, NULL, &fileTime);
  228. while (rv == ERROR_SUCCESS)
  229. {
  230. if (iTotalSize + dwBufferSize <= iSizeOfList - 2) // spare two chars for trailing nulls
  231. {
  232. strcpy((aaszCardListBuffer.Get() + iTotalSize), sBuffer);
  233. iTotalSize += dwBufferSize;
  234. aaszCardListBuffer[iTotalSize++] = 0;
  235. }
  236. else
  237. {
  238. iTotalSize += dwBufferSize + 1;
  239. }
  240. dwBufferSize = sizeof sBuffer / sizeof *sBuffer;
  241. memset(sBuffer, 0, dwBufferSize);
  242. rv = RegEnumKeyEx(hkCardKey, index++, sBuffer, &dwBufferSize,
  243. NULL, NULL, NULL, &fileTime);
  244. }
  245. bool fRetVal = (iTotalSize <= iSizeOfList - 1); // spare byte for final null terminator
  246. if (fRetVal)
  247. {
  248. aaszCardListBuffer[iTotalSize++] = 0;
  249. memcpy(szCardList, aaszCardListBuffer.Get(), iTotalSize);
  250. }
  251. else
  252. iTotalSize++; // spare byte for final null terminator
  253. iSizeOfList = iTotalSize;
  254. rv = RegCloseKey(hkCardKey);
  255. if (ERROR_SUCCESS != rv)
  256. throw scu::OsException(rv);
  257. }
  258. void
  259. CIOP::RegisterCard(const char* szCardName,
  260. const BYTE* bATR,
  261. BYTE bATRLength,
  262. const BYTE* bATRMask,
  263. BYTE bATRMaskLength,
  264. const BYTE* bProperties,
  265. cardType type)
  266. {
  267. HKEY hkCardKey;
  268. DWORD dwCreateFlag;
  269. BYTE bCardType = (BYTE)type;
  270. char szATR[] = "ATR";
  271. char szATRMask[] = "ATR Mask";
  272. char szCardType[] = "Card Type";
  273. char szProperties[] = "Properties";
  274. string sCardRegPath(CardPath());
  275. sCardRegPath.append("\\");
  276. sCardRegPath.append(szCardName);
  277. LONG rv = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  278. sCardRegPath.c_str(), NULL, NULL, NULL,
  279. KEY_ALL_ACCESS, NULL, &hkCardKey, &dwCreateFlag);
  280. if(ERROR_SUCCESS!=rv)
  281. throw scu::OsException(rv);
  282. if (dwCreateFlag == REG_CREATED_NEW_KEY)
  283. {
  284. rv = RegSetValueEx(hkCardKey, szATR, NULL, REG_BINARY, bATR,
  285. bATRLength);
  286. if (ERROR_SUCCESS==rv)
  287. {
  288. rv = RegSetValueEx(hkCardKey, szATRMask, NULL,
  289. REG_BINARY, bATRMask,
  290. bATRMaskLength);
  291. if (ERROR_SUCCESS==rv)
  292. {
  293. rv = RegSetValueEx(hkCardKey, szCardType, NULL,
  294. REG_BINARY, &bCardType, 1);
  295. if (ERROR_SUCCESS==rv)
  296. rv = RegSetValueEx(hkCardKey, szProperties, NULL,
  297. REG_BINARY, bProperties, 512);
  298. }
  299. }
  300. }
  301. LONG rv2 = RegCloseKey(hkCardKey);
  302. if (ERROR_SUCCESS!=rv) // an error occured earlier
  303. throw scu::OsException(rv);
  304. if (ERROR_SUCCESS != rv2)
  305. throw scu::OsException(rv2);
  306. // return (dwCreateFlag == REG_CREATED_NEW_KEY);
  307. }
  308. void
  309. CIOP::RegisterDefaultCards()
  310. {
  311. BYTE bMask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
  312. BYTE bAccessMask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00 };
  313. BYTE bCMask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };
  314. BYTE bMaskLength = 9;
  315. BYTE bATRLength = 9;
  316. BYTE bProperties[512];
  317. memset(bProperties, 0, sizeof(bProperties));
  318. // Register Cryptoflex 16K
  319. BYTE b16KCryptoATR[] = { 0x3B, 0x95, 0x15, 0x40, 0xFF, 0x63,
  320. 0x01, 0x01, 0x00, 0x00 };
  321. BYTE b16KCryptoMask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  322. 0xFF, 0xFF, 0x00, 0x00 };
  323. RegisterCard(g_szCrypto16KName, b16KCryptoATR,
  324. sizeof b16KCryptoATR / sizeof *b16KCryptoATR, b16KCryptoMask,
  325. sizeof b16KCryptoMask / sizeof *b16KCryptoMask,
  326. bProperties, CRYPTO_CARD);
  327. // Register e-gate
  328. BYTE be_gateATR[] = { 0x3B, 0x95, 0x00, 0x40, 0xFF, 0x62,
  329. 0x01, 0x01, 0x00, 0x00 };
  330. BYTE be_gateMask[] = { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
  331. 0xFF, 0xFF, 0x00, 0x00 };
  332. RegisterCard(g_sze_gateName, be_gateATR,
  333. sizeof be_gateATR / sizeof *be_gateATR, be_gateMask,
  334. sizeof be_gateMask / sizeof *be_gateMask,
  335. bProperties, CRYPTO_CARD);
  336. // Register Cyberflex Access card
  337. BYTE bAccessATR[] = { 0x3B, 0x16, 0x94, 0x81, 0x10, 0x06, 0x01, 0x00, 0x00 };
  338. RegisterCard(g_szAccessName, bAccessATR, bATRLength, bAccessMask,
  339. bMaskLength, bProperties, ACCESS_CARD);
  340. // Register old Cryptoflex 8K card
  341. BYTE bOldCryptoATR[] = { 0x3B, 0x85, 0x40, 0x20, 0x68, 0x01, 0x01, 0x00, 0x00 };
  342. RegisterCard(g_szOldCrypto8KName, bOldCryptoATR, bATRLength, bMask,
  343. bMaskLength, bProperties, CRYPTO_CARD);
  344. // Register new Cryptoflex 8K card
  345. BYTE bNewCryptoATR[] = { 0x3B, 0x85, 0x40, 0x20, 0x68, 0x01, 0x01, 0x05, 0x01 };
  346. RegisterCard(g_szNewCrypto8KName, bNewCryptoATR, bATRLength, bMask,
  347. bMaskLength, bProperties, CRYPTO_CARD);
  348. // Register another new Cryptoflex 8K card
  349. BYTE bCrypto8KV2ATR[] = { 0x3B, 0x95, 0x15, 0x40, 0x00, 0x68, 0x01, 0x02, 0x00, 0x00 };
  350. BYTE bCrypto8KV2Mask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00 };
  351. RegisterCard(g_szCrypto8KV2Name, bCrypto8KV2ATR, sizeof(bCrypto8KV2ATR), bCrypto8KV2Mask,
  352. sizeof(bCrypto8KV2Mask), bProperties, CRYPTO_CARD);
  353. // Register Cryptoflex 4K card
  354. BYTE b4KCryptoATR[] = { 0x3B, 0xE2, 0x00, 0x00, 0x40, 0x20, 0x49, 0x00 };
  355. bATRLength = 8;
  356. bMaskLength = 8;
  357. RegisterCard(g_szCrypto4KName, b4KCryptoATR, bATRLength, bCMask,
  358. bMaskLength, bProperties, CRYPTO_CARD);
  359. // Register Cyberflex Access Campus
  360. BYTE be_AccessCampusATR[] = { 0x3B, 0x23, 0x00, 0x35, 0x13, 0x80 };
  361. BYTE be_AccessCampusMask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
  362. RegisterCard(g_szAccessCampus, be_AccessCampusATR,
  363. sizeof be_AccessCampusATR / sizeof *be_AccessCampusATR,
  364. be_AccessCampusMask,
  365. sizeof be_AccessCampusMask / sizeof *be_AccessCampusMask,
  366. bProperties, ACCESS_CARD);
  367. // Register Cryptoflex ActivCard
  368. BYTE bCryptoActivCardATR[] = { 0x3B, 0x05, 0x68, 0x01, 0x01,
  369. 0x02, 0x05 };
  370. BYTE bCryptoActivCardMask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  371. 0xFF, 0xFF };
  372. RegisterCard(g_szCryptoActivCard, bCryptoActivCardATR,
  373. sizeof(bCryptoActivCardATR), bCryptoActivCardMask,
  374. sizeof(bCryptoActivCardMask), bProperties, CRYPTO_CARD);
  375. }
  376. #if defined(SLBIOP_USE_SECURITY_ATTRIBUTES)
  377. void
  378. CIOP::InitIOPSecurityAttrs(CSecurityAttributes *psa)
  379. {
  380. DWORD dwRes;
  381. PSID pEveryoneSID = NULL, pAdminSID = NULL;
  382. PACL pACL = NULL;
  383. PSECURITY_DESCRIPTOR pSD = NULL;
  384. EXPLICIT_ACCESS ea;
  385. SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
  386. SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
  387. bool fErrorFound = false;
  388. // Create a well-known SID for the Everyone group.
  389. if(!AllocateAndInitializeSid(&SIDAuthWorld, 1,
  390. SECURITY_WORLD_RID,
  391. 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID))
  392. throw scu::OsException(GetLastError());
  393. // Initialize an EXPLICIT_ACCESS structure for an ACE.
  394. // The ACE will allow Everyone read access to the key.
  395. ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
  396. ea.grfAccessPermissions = SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL;
  397. ea.grfAccessMode = SET_ACCESS;
  398. ea.grfInheritance= NO_INHERITANCE;
  399. ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
  400. ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
  401. ea.Trustee.ptstrName = (LPTSTR) pEveryoneSID;
  402. #if 0
  403. // Create a SID for the BUILTIN\Administrators group.
  404. if (!AllocateAndInitializeSid(&SIDAuthNT, 2,
  405. SECURITY_BUILTIN_DOMAIN_RID,
  406. DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0,
  407. 0, 0, &pAdminSID))
  408. throw scu::OsException(GetLastError());
  409. // Initialize an EXPLICIT_ACCESS structure for an ACE.
  410. // The ACE will allow the Administrators group full access to the key.
  411. ea.grfAccessPermissions = SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL;
  412. ea.grfAccessMode = SET_ACCESS;
  413. ea.grfInheritance= NO_INHERITANCE;
  414. ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
  415. ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
  416. ea.Trustee.ptstrName = (LPTSTR) pAdminSID;
  417. #endif // 0
  418. // Create a new ACL that contains the new ACEs.
  419. dwRes = SetEntriesInAcl(1, &ea, NULL, &pACL);
  420. if (ERROR_SUCCESS != dwRes)
  421. {
  422. fErrorFound = true;
  423. }
  424. else
  425. {
  426. // Initialize a security descriptor.
  427. pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
  428. if (pSD == NULL)
  429. {
  430. fErrorFound = true;
  431. }
  432. else if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
  433. {
  434. fErrorFound = true;
  435. }
  436. // Add the ACL to the security descriptor.
  437. else if (!SetSecurityDescriptorDacl(pSD,
  438. TRUE, // fDaclPresent flag
  439. pACL,
  440. FALSE)) // not a default DACL
  441. {
  442. fErrorFound = true;
  443. }
  444. else
  445. {
  446. if (!IsValidSecurityDescriptor(pSD))
  447. {
  448. fErrorFound = true;
  449. }
  450. else
  451. {
  452. // Initialize a security attributes structure.
  453. psa->sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  454. psa->sa.lpSecurityDescriptor = pSD;
  455. psa->sa.bInheritHandle = FALSE;
  456. psa->pEveryoneSID = pEveryoneSID;
  457. psa->pACL = pACL;
  458. }
  459. }
  460. }
  461. DWORD dwLastError = GetLastError();
  462. if (true == fErrorFound)
  463. {
  464. if (NULL != pACL)
  465. {
  466. LocalFree(pACL);
  467. pACL = NULL;
  468. }
  469. if (NULL != pSD)
  470. {
  471. LocalFree(pSD);
  472. pSD = NULL;
  473. }
  474. if (NULL != pEveryoneSID)
  475. {
  476. FreeSid(pEveryoneSID);
  477. pEveryoneSID = NULL;
  478. }
  479. throw scu::OsException(dwLastError);
  480. }
  481. #if 0
  482. // Create a new ACL that contains the new ACEs.
  483. dwRes = SetEntriesInAcl(1, &ea, NULL, &pACL);
  484. if (ERROR_SUCCESS != dwRes)
  485. throw scu::OsException(GetLastError());
  486. // Initialize a security descriptor.
  487. pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
  488. if (pSD == NULL)
  489. throw scu::OsException(GetLastError());
  490. if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
  491. throw scu::OsException(GetLastError());
  492. // Add the ACL to the security descriptor.
  493. if (!SetSecurityDescriptorDacl(pSD,
  494. TRUE, // fDaclPresent flag
  495. pACL,
  496. FALSE)) // not a default DACL
  497. throw scu::OsException(GetLastError());
  498. // Initialize a security attributes structure.
  499. psa->nLength = sizeof(SECURITY_ATTRIBUTES);
  500. psa->lpSecurityDescriptor = pSD;
  501. psa->bInheritHandle = FALSE;
  502. if (!IsValidSecurityDescriptor(pSD))
  503. throw scu::OsException(GetLastError());
  504. #endif
  505. }
  506. #endif // defined(SLBIOP_USE_SECURITY_ATTRIBUTES)
  507. bool CIOP::WaitForSCManager()
  508. {
  509. #if defined(SLBIOP_WAIT_FOR_RM_STARTUP)
  510. // Wait for the SCManager to start, time out at dwTimeout seconds.
  511. HANDLE hStarted = GetSCResourceManagerStartedEvent();
  512. if (hStarted)
  513. {
  514. if (WaitForSingleObject(hStarted, 60 * 1000) == WAIT_OBJECT_0)
  515. return true;
  516. }
  517. return false;
  518. #else // defined(SLBIOP_WAIT_FOR_RM_STARTUP)
  519. return true;
  520. #endif // defined(SLBIOP_WAIT_FOR_RM_STARTUP)
  521. }
  522. } // namespace iop
  523. STDAPI DllGetVersion(DLLVERSIONINFO *dvi)
  524. {
  525. dvi->dwBuildNumber = 0;
  526. dvi->dwMajorVersion = 0;
  527. dvi->dwMinorVersion = 9;
  528. return 0;
  529. }
  530. STDAPI DllRegisterServer()
  531. {
  532. // Ensure default cards are registered to the system
  533. HRESULT hResult = ERROR_SUCCESS;
  534. try
  535. {
  536. iop::CIOP::RegisterDefaultCards();
  537. }
  538. catch (scu::OsException const &rExc)
  539. {
  540. hResult = rExc.Cause();
  541. }
  542. return hResult;
  543. }
  544. STDAPI DllUnregisterServer()
  545. {
  546. HRESULT hResult = NOERROR;
  547. LONG rv;
  548. HKEY hkSLBKey;
  549. HKEY hkTerminalsKey;
  550. HKEY hkCardsKey;
  551. bool bSLBKey = false, bTerminalsKey = false, bCardsKey = false;
  552. try
  553. {
  554. rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, g_szSLBRegistryPath, NULL, KEY_ALL_ACCESS, &hkSLBKey);
  555. if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
  556. bSLBKey = true;
  557. RegOpenKeyEx(hkSLBKey, g_szTerminalsName, NULL, KEY_ALL_ACCESS, &hkTerminalsKey);
  558. if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
  559. bTerminalsKey = true;
  560. RegOpenKeyEx(hkTerminalsKey, g_szCardName, NULL, KEY_ALL_ACCESS, &hkCardsKey);
  561. if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
  562. bCardsKey = true;
  563. rv = RegDeleteKey(hkCardsKey, g_szCrypto4KName);
  564. if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
  565. rv = RegDeleteKey(hkCardsKey, g_szOldCrypto8KName);
  566. if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
  567. rv = RegDeleteKey(hkCardsKey, g_szNewCrypto8KName);
  568. if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
  569. rv = RegDeleteKey(hkCardsKey, g_szCrypto8KV2Name);
  570. if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
  571. rv = RegDeleteKey(hkCardsKey, g_szAccessName);
  572. if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
  573. rv = RegDeleteKey(hkCardsKey, g_sze_gateName);
  574. if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
  575. rv = RegDeleteKey(hkCardsKey, g_szCrypto16KName);
  576. if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
  577. rv = RegDeleteKey(hkCardsKey, g_szAccessCampus);
  578. if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
  579. rv = RegDeleteKey(hkCardsKey, g_szCryptoActivCard);
  580. if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
  581. rv = RegCloseKey (hkCardsKey);
  582. if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
  583. bCardsKey = false;
  584. rv = RegDeleteKey(hkTerminalsKey, g_szCardName);
  585. if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
  586. bCardsKey = false;
  587. rv = RegCloseKey (hkTerminalsKey);
  588. if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
  589. bTerminalsKey = false;
  590. rv = RegDeleteKey(hkSLBKey, g_szTerminalsName);
  591. if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
  592. bCardsKey = false;
  593. rv = RegCloseKey(hkSLBKey);
  594. if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
  595. bSLBKey = false;
  596. }
  597. catch(...)
  598. {
  599. hResult = E_UNEXPECTED;
  600. }
  601. if(bCardsKey) RegCloseKey (hkCardsKey);
  602. if(bTerminalsKey) RegCloseKey (hkTerminalsKey);
  603. if(bSLBKey) RegCloseKey (hkSLBKey);
  604. return hResult;
  605. }