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.

762 lines
25 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 bOldCrypto8KMask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00 };
  314. BYTE bCMask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };
  315. BYTE bMaskLength = 9;
  316. BYTE bATRLength = 9;
  317. BYTE bProperties[512];
  318. memset(bProperties, 0, sizeof(bProperties));
  319. // Register Cryptoflex 16K
  320. BYTE b16KCryptoATR[] = { 0x3B, 0x95, 0x15, 0x40, 0xFF, 0x63,
  321. 0x01, 0x01, 0x00, 0x00 };
  322. BYTE b16KCryptoMask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  323. 0xFF, 0xFF, 0x00, 0x00 };
  324. RegisterCard(g_szCrypto16KName, b16KCryptoATR,
  325. sizeof b16KCryptoATR / sizeof *b16KCryptoATR, b16KCryptoMask,
  326. sizeof b16KCryptoMask / sizeof *b16KCryptoMask,
  327. bProperties, CRYPTO_CARD);
  328. // Register e-gate
  329. BYTE be_gateATR[] = { 0x3B, 0x95, 0x00, 0x40, 0xFF, 0x62,
  330. 0x01, 0x01, 0x00, 0x00 };
  331. BYTE be_gateMask[] = { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
  332. 0xFF, 0xFF, 0x00, 0x00 };
  333. RegisterCard(g_sze_gateName, be_gateATR,
  334. sizeof be_gateATR / sizeof *be_gateATR, be_gateMask,
  335. sizeof be_gateMask / sizeof *be_gateMask,
  336. bProperties, CRYPTO_CARD);
  337. // Register Cyberflex Access card
  338. BYTE bAccessATR[] = { 0x3B, 0x16, 0x94, 0x81, 0x10, 0x06, 0x01, 0x00, 0x00 };
  339. RegisterCard(g_szAccessName, bAccessATR, bATRLength, bAccessMask,
  340. bMaskLength, bProperties, ACCESS_CARD);
  341. // Register old Cryptoflex 8K card
  342. BYTE bOldCryptoATR[] = { 0x3B, 0x85, 0x40, 0x20, 0x68, 0x01, 0x01, 0x00, 0x00 };
  343. RegisterCard(g_szOldCrypto8KName, bOldCryptoATR, bATRLength, bOldCrypto8KMask,
  344. bMaskLength, bProperties, CRYPTO_CARD);
  345. // Register new Cryptoflex 8K card
  346. BYTE bNewCryptoATR[] = { 0x3B, 0x85, 0x40, 0x20, 0x68, 0x01, 0x01, 0x05, 0x01 };
  347. RegisterCard(g_szNewCrypto8KName, bNewCryptoATR, bATRLength, bMask,
  348. bMaskLength, bProperties, CRYPTO_CARD);
  349. // Register another new Cryptoflex 8K card
  350. BYTE bCrypto8KV2ATR[] = { 0x3B, 0x95, 0x15, 0x40, 0x00, 0x68, 0x01, 0x02, 0x00, 0x00 };
  351. BYTE bCrypto8KV2Mask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00 };
  352. RegisterCard(g_szCrypto8KV2Name, bCrypto8KV2ATR, sizeof(bCrypto8KV2ATR), bCrypto8KV2Mask,
  353. sizeof(bCrypto8KV2Mask), bProperties, CRYPTO_CARD);
  354. // Register Cryptoflex 4K card
  355. BYTE b4KCryptoATR[] = { 0x3B, 0xE2, 0x00, 0x00, 0x40, 0x20, 0x49, 0x00 };
  356. bATRLength = 8;
  357. bMaskLength = 8;
  358. RegisterCard(g_szCrypto4KName, b4KCryptoATR, bATRLength, bCMask,
  359. bMaskLength, bProperties, CRYPTO_CARD);
  360. // Register Cyberflex Access Campus
  361. BYTE be_AccessCampusATR[] = { 0x3B, 0x23, 0x00, 0x35, 0x13, 0x80 };
  362. BYTE be_AccessCampusMask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
  363. RegisterCard(g_szAccessCampus, be_AccessCampusATR,
  364. sizeof be_AccessCampusATR / sizeof *be_AccessCampusATR,
  365. be_AccessCampusMask,
  366. sizeof be_AccessCampusMask / sizeof *be_AccessCampusMask,
  367. bProperties, ACCESS_CARD);
  368. // Register Cryptoflex ActivCard
  369. BYTE bCryptoActivCardATR[] = { 0x3B, 0x05, 0x68, 0x01, 0x01,
  370. 0x02, 0x05 };
  371. BYTE bCryptoActivCardMask[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  372. 0xFF, 0xFF };
  373. RegisterCard(g_szCryptoActivCard, bCryptoActivCardATR,
  374. sizeof(bCryptoActivCardATR), bCryptoActivCardMask,
  375. sizeof(bCryptoActivCardMask), bProperties, CRYPTO_CARD);
  376. }
  377. #if defined(SLBIOP_USE_SECURITY_ATTRIBUTES)
  378. void
  379. CIOP::InitIOPSecurityAttrs(CSecurityAttributes *psa)
  380. {
  381. DWORD dwRes;
  382. PSID pEveryoneSID = NULL, pAdminSID = NULL;
  383. PACL pACL = NULL;
  384. PSECURITY_DESCRIPTOR pSD = NULL;
  385. EXPLICIT_ACCESS ea;
  386. SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
  387. SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
  388. bool fErrorFound = false;
  389. // Create a well-known SID for the Everyone group.
  390. if(!AllocateAndInitializeSid(&SIDAuthWorld, 1,
  391. SECURITY_WORLD_RID,
  392. 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID))
  393. throw scu::OsException(GetLastError());
  394. // Initialize an EXPLICIT_ACCESS structure for an ACE.
  395. // The ACE will allow Everyone read access to the key.
  396. ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
  397. ea.grfAccessPermissions = SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL;
  398. ea.grfAccessMode = SET_ACCESS;
  399. ea.grfInheritance= NO_INHERITANCE;
  400. ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
  401. ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
  402. ea.Trustee.ptstrName = (LPTSTR) pEveryoneSID;
  403. #if 0
  404. // Create a SID for the BUILTIN\Administrators group.
  405. if (!AllocateAndInitializeSid(&SIDAuthNT, 2,
  406. SECURITY_BUILTIN_DOMAIN_RID,
  407. DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0,
  408. 0, 0, &pAdminSID))
  409. throw scu::OsException(GetLastError());
  410. // Initialize an EXPLICIT_ACCESS structure for an ACE.
  411. // The ACE will allow the Administrators group full access to the key.
  412. ea.grfAccessPermissions = SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL;
  413. ea.grfAccessMode = SET_ACCESS;
  414. ea.grfInheritance= NO_INHERITANCE;
  415. ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
  416. ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
  417. ea.Trustee.ptstrName = (LPTSTR) pAdminSID;
  418. #endif // 0
  419. // Create a new ACL that contains the new ACEs.
  420. dwRes = SetEntriesInAcl(1, &ea, NULL, &pACL);
  421. if (ERROR_SUCCESS != dwRes)
  422. {
  423. fErrorFound = true;
  424. }
  425. else
  426. {
  427. // Initialize a security descriptor.
  428. pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
  429. if (pSD == NULL)
  430. {
  431. fErrorFound = true;
  432. }
  433. else if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
  434. {
  435. fErrorFound = true;
  436. }
  437. // Add the ACL to the security descriptor.
  438. else if (!SetSecurityDescriptorDacl(pSD,
  439. TRUE, // fDaclPresent flag
  440. pACL,
  441. FALSE)) // not a default DACL
  442. {
  443. fErrorFound = true;
  444. }
  445. else
  446. {
  447. if (!IsValidSecurityDescriptor(pSD))
  448. {
  449. fErrorFound = true;
  450. }
  451. else
  452. {
  453. // Initialize a security attributes structure.
  454. psa->sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  455. psa->sa.lpSecurityDescriptor = pSD;
  456. psa->sa.bInheritHandle = FALSE;
  457. psa->pEveryoneSID = pEveryoneSID;
  458. psa->pACL = pACL;
  459. }
  460. }
  461. }
  462. DWORD dwLastError = GetLastError();
  463. if (true == fErrorFound)
  464. {
  465. if (NULL != pACL)
  466. {
  467. LocalFree(pACL);
  468. pACL = NULL;
  469. }
  470. if (NULL != pSD)
  471. {
  472. LocalFree(pSD);
  473. pSD = NULL;
  474. }
  475. if (NULL != pEveryoneSID)
  476. {
  477. FreeSid(pEveryoneSID);
  478. pEveryoneSID = NULL;
  479. }
  480. throw scu::OsException(dwLastError);
  481. }
  482. #if 0
  483. // Create a new ACL that contains the new ACEs.
  484. dwRes = SetEntriesInAcl(1, &ea, NULL, &pACL);
  485. if (ERROR_SUCCESS != dwRes)
  486. throw scu::OsException(GetLastError());
  487. // Initialize a security descriptor.
  488. pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
  489. if (pSD == NULL)
  490. throw scu::OsException(GetLastError());
  491. if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
  492. throw scu::OsException(GetLastError());
  493. // Add the ACL to the security descriptor.
  494. if (!SetSecurityDescriptorDacl(pSD,
  495. TRUE, // fDaclPresent flag
  496. pACL,
  497. FALSE)) // not a default DACL
  498. throw scu::OsException(GetLastError());
  499. // Initialize a security attributes structure.
  500. psa->nLength = sizeof(SECURITY_ATTRIBUTES);
  501. psa->lpSecurityDescriptor = pSD;
  502. psa->bInheritHandle = FALSE;
  503. if (!IsValidSecurityDescriptor(pSD))
  504. throw scu::OsException(GetLastError());
  505. #endif
  506. }
  507. #endif // defined(SLBIOP_USE_SECURITY_ATTRIBUTES)
  508. bool CIOP::WaitForSCManager()
  509. {
  510. #if defined(SLBIOP_WAIT_FOR_RM_STARTUP)
  511. // Wait for the SCManager to start, time out at dwTimeout seconds.
  512. HANDLE hStarted = GetSCResourceManagerStartedEvent();
  513. if (hStarted)
  514. {
  515. if (WaitForSingleObject(hStarted, 60 * 1000) == WAIT_OBJECT_0)
  516. return true;
  517. }
  518. return false;
  519. #else // defined(SLBIOP_WAIT_FOR_RM_STARTUP)
  520. return true;
  521. #endif // defined(SLBIOP_WAIT_FOR_RM_STARTUP)
  522. }
  523. } // namespace iop
  524. STDAPI DllGetVersion(DLLVERSIONINFO *dvi)
  525. {
  526. dvi->dwBuildNumber = 0;
  527. dvi->dwMajorVersion = 0;
  528. dvi->dwMinorVersion = 9;
  529. return 0;
  530. }
  531. STDAPI DllRegisterServer()
  532. {
  533. // Ensure default cards are registered to the system
  534. HRESULT hResult = ERROR_SUCCESS;
  535. try
  536. {
  537. iop::CIOP::RegisterDefaultCards();
  538. }
  539. catch (scu::OsException const &rExc)
  540. {
  541. hResult = rExc.Cause();
  542. }
  543. return hResult;
  544. }
  545. STDAPI DllUnregisterServer()
  546. {
  547. HRESULT hResult = NOERROR;
  548. LONG rv;
  549. HKEY hkSLBKey;
  550. HKEY hkTerminalsKey;
  551. HKEY hkCardsKey;
  552. bool bSLBKey = false, bTerminalsKey = false, bCardsKey = false;
  553. try
  554. {
  555. rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, g_szSLBRegistryPath, NULL, KEY_ALL_ACCESS, &hkSLBKey);
  556. if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
  557. bSLBKey = true;
  558. RegOpenKeyEx(hkSLBKey, g_szTerminalsName, NULL, KEY_ALL_ACCESS, &hkTerminalsKey);
  559. if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
  560. bTerminalsKey = true;
  561. RegOpenKeyEx(hkTerminalsKey, g_szCardName, NULL, KEY_ALL_ACCESS, &hkCardsKey);
  562. if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
  563. bCardsKey = true;
  564. rv = RegDeleteKey(hkCardsKey, g_szCrypto4KName);
  565. if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
  566. rv = RegDeleteKey(hkCardsKey, g_szOldCrypto8KName);
  567. if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
  568. rv = RegDeleteKey(hkCardsKey, g_szNewCrypto8KName);
  569. if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
  570. rv = RegDeleteKey(hkCardsKey, g_szCrypto8KV2Name);
  571. if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
  572. rv = RegDeleteKey(hkCardsKey, g_szAccessName);
  573. if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
  574. rv = RegDeleteKey(hkCardsKey, g_sze_gateName);
  575. if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
  576. rv = RegDeleteKey(hkCardsKey, g_szCrypto16KName);
  577. if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
  578. rv = RegDeleteKey(hkCardsKey, g_szAccessCampus);
  579. if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
  580. rv = RegDeleteKey(hkCardsKey, g_szCryptoActivCard);
  581. if(rv!=ERROR_SUCCESS) hResult = E_UNEXPECTED;
  582. rv = RegCloseKey (hkCardsKey);
  583. if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
  584. bCardsKey = false;
  585. rv = RegDeleteKey(hkTerminalsKey, g_szCardName);
  586. if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
  587. bCardsKey = false;
  588. rv = RegCloseKey (hkTerminalsKey);
  589. if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
  590. bTerminalsKey = false;
  591. rv = RegDeleteKey(hkSLBKey, g_szTerminalsName);
  592. if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
  593. bCardsKey = false;
  594. rv = RegCloseKey(hkSLBKey);
  595. if(rv!=ERROR_SUCCESS) throw scu::OsException(rv);
  596. bSLBKey = false;
  597. }
  598. catch(...)
  599. {
  600. hResult = E_UNEXPECTED;
  601. }
  602. if(bCardsKey) RegCloseKey (hkCardsKey);
  603. if(bTerminalsKey) RegCloseKey (hkTerminalsKey);
  604. if(bSLBKey) RegCloseKey (hkSLBKey);
  605. return hResult;
  606. }