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.

1647 lines
50 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1996 - 1999
  3. Module Name:
  4. SCardSvr
  5. Abstract:
  6. This module provides the startup logic to make the Calais Resource Manager
  7. act as a server application under Windows NT.
  8. Author:
  9. Doug Barlow (dbarlow) 1/16/1997
  10. Environment:
  11. Win32
  12. Notes:
  13. This file detects which operating system it's running on, and acts
  14. accordingly.
  15. --*/
  16. #if defined(_DEBUG)
  17. #define DEBUG_SERVICE
  18. #endif
  19. #define __SUBROUTINE__
  20. #ifndef WIN32_LEAN_AND_MEAN
  21. #define WIN32_LEAN_AND_MEAN
  22. #endif
  23. #include <nt.h>
  24. #include <ntdef.h>
  25. #include <ntrtl.h>
  26. #include <nturtl.h>
  27. #include <windows.h>
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include <tchar.h>
  31. #include <aclapi.h>
  32. #include <dbt.h>
  33. #include <CalServe.h>
  34. #include "resource.h" // Pick up resource string Ids.
  35. // Keep one global copy of the structure which contains common initialized
  36. // sids. This way we can control the creation and cleanup of the pointer
  37. // and allow the service worker threads to safely access it.
  38. static PSERVICE_THREAD_SECURITY_INFO g_pServiceThreadSecurityInfo = NULL;
  39. static const DWORD l_dwWaitHint = CALAIS_THREAD_TIMEOUT;
  40. static const GUID l_guidSmartcards
  41. = { // 50DD5230-BA8A-11D1-BF5D-0000F805F530
  42. 0x50DD5230,
  43. 0xBA8A,
  44. 0x11D1,
  45. { 0xBF, 0x5D, 0x00, 0x00, 0xF8, 0x05, 0xF5, 0x30}};
  46. static const DWORD l_dwInteractiveAccess
  47. = READ_CONTROL
  48. // | SYNCHRONIZE
  49. | SERVICE_QUERY_CONFIG
  50. // | SERVICE_CHANGE_CONFIG
  51. | SERVICE_QUERY_STATUS
  52. | SERVICE_ENUMERATE_DEPENDENTS
  53. | SERVICE_START
  54. // | SERVICE_STOP
  55. // | SERVICE_PAUSE_CONTINUE
  56. | SERVICE_INTERROGATE
  57. | SERVICE_USER_DEFINED_CONTROL
  58. | 0;
  59. static const DWORD l_dwSystemAccess
  60. = READ_CONTROL
  61. | SERVICE_USER_DEFINED_CONTROL
  62. | SERVICE_START
  63. | SERVICE_STOP
  64. | SERVICE_QUERY_CONFIG
  65. | SERVICE_QUERY_STATUS
  66. | SERVICE_PAUSE_CONTINUE
  67. | SERVICE_INTERROGATE
  68. | SERVICE_ENUMERATE_DEPENDENTS
  69. | 0;
  70. static CCriticalSectionObject *l_pcsStatusLock = NULL;
  71. static SERVICE_STATUS l_srvStatus, l_srvNonPnP;
  72. static SERVICE_STATUS_HANDLE l_hService = NULL, l_hNonPnP = NULL;
  73. static HANDLE l_hShutdownEvent = NULL;
  74. #ifdef DEBUG_SERVICE
  75. static SERVICE_STATUS l_srvDebug;
  76. static SERVICE_STATUS_HANDLE l_hDebug = NULL;
  77. static HANDLE l_hDebugDoneEvent = NULL;
  78. static void WINAPI
  79. DebugMain(
  80. IN DWORD dwArgc,
  81. IN LPTSTR *pszArgv);
  82. static void WINAPI
  83. DebugHandler(
  84. IN DWORD dwOpCode);
  85. #endif
  86. static void WINAPI
  87. CalaisMain(
  88. IN DWORD dwArgc,
  89. IN LPTSTR *pszArgv);
  90. static DWORD WINAPI
  91. CalaisHandlerEx(
  92. IN DWORD dwControl,
  93. IN DWORD dwEventType,
  94. IN PVOID EventData,
  95. IN PVOID pData);
  96. //
  97. // Retrieve the global pointer to the service thread security info
  98. // structure.
  99. //
  100. PSERVICE_THREAD_SECURITY_INFO
  101. GetServiceThreadSecurityInfo(void)
  102. {
  103. return g_pServiceThreadSecurityInfo;
  104. }
  105. //
  106. // Frees the SIDs contained in the passed struct, then frees
  107. // the struct itself. The service must ensure that all service threads
  108. // are shutdown and no longer referencing this structure before
  109. // calling this routine.
  110. //
  111. DWORD FreeServiceThreadSecurityInfo(
  112. PSERVICE_THREAD_SECURITY_INFO *ppInfo)
  113. {
  114. PSERVICE_THREAD_SECURITY_INFO pLocal = *ppInfo;
  115. if (pLocal->pServiceSid)
  116. {
  117. FreeSid(pLocal->pServiceSid);
  118. pLocal->pServiceSid = NULL;
  119. }
  120. if (pLocal->pSystemSid)
  121. {
  122. FreeSid(pLocal->pSystemSid);
  123. pLocal->pSystemSid = NULL;
  124. }
  125. HeapFree(GetProcessHeap(), 0, pLocal);
  126. *ppInfo = NULL;
  127. return SCARD_S_SUCCESS;
  128. }
  129. //
  130. // Builds the SIDs contained in the structure allocated by this function.
  131. //
  132. DWORD InitializeServiceThreadSecurityInfo(
  133. PSERVICE_THREAD_SECURITY_INFO *ppInfo)
  134. {
  135. DWORD dwSts = SCARD_S_SUCCESS;
  136. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  137. PSERVICE_THREAD_SECURITY_INFO pLocal = NULL;
  138. *ppInfo = NULL;
  139. pLocal = (PSERVICE_THREAD_SECURITY_INFO) HeapAlloc(
  140. GetProcessHeap(),
  141. HEAP_ZERO_MEMORY,
  142. sizeof(SERVICE_THREAD_SECURITY_INFO));
  143. if (NULL == pLocal)
  144. return SCARD_E_NO_MEMORY;
  145. if (! AllocateAndInitializeSid(
  146. &NtAuthority,
  147. 1,
  148. SECURITY_LOCAL_SYSTEM_RID,
  149. 0, 0, 0, 0, 0, 0, 0,
  150. &pLocal->pSystemSid))
  151. {
  152. dwSts = GetLastError();
  153. goto Ret;
  154. }
  155. if (! AllocateAndInitializeSid(
  156. &NtAuthority,
  157. 1,
  158. SECURITY_SERVICE_RID,
  159. 0, 0, 0, 0, 0, 0, 0,
  160. &pLocal->pServiceSid))
  161. {
  162. dwSts = GetLastError();
  163. goto Ret;
  164. }
  165. *ppInfo = pLocal;
  166. pLocal = NULL;
  167. Ret:
  168. if (pLocal)
  169. FreeServiceThreadSecurityInfo(&pLocal);
  170. return dwSts;
  171. }
  172. /*++
  173. Main:
  174. This routine is the entry point for the Resource Manager.
  175. Arguments:
  176. Per standard Windows applications
  177. Return Value:
  178. Per standard Windows applications
  179. Throws:
  180. None
  181. Author:
  182. Doug Barlow (dbarlow) 1/16/1997
  183. --*/
  184. #undef __SUBROUTINE__
  185. #define __SUBROUTINE__ DBGT("main")
  186. extern "C" int __cdecl
  187. main(
  188. int nArgCount,
  189. LPCTSTR *rgszArgs)
  190. {
  191. NEW_THREAD;
  192. SERVICE_TABLE_ENTRY rgsteDispatchTable[3];
  193. DWORD dwI = 0;
  194. DWORD dwSts = ERROR_SUCCESS;
  195. //
  196. // Command line options are no longer supported.
  197. //
  198. if (1 < nArgCount)
  199. {
  200. dwSts = ERROR_INVALID_PARAMETER;
  201. goto ErrorExit;
  202. }
  203. CalaisInfo(
  204. __SUBROUTINE__,
  205. DBGT("Initiating Smart Card Services Process"));
  206. try
  207. {
  208. #ifdef DEBUG_SERVICE
  209. rgsteDispatchTable[dwI].lpServiceName = (LPTSTR)CalaisString(CALSTR_DEBUGSERVICE);
  210. rgsteDispatchTable[dwI].lpServiceProc = DebugMain;
  211. dwI += 1;
  212. #endif
  213. rgsteDispatchTable[dwI].lpServiceName = (LPTSTR)CalaisString(CALSTR_PRIMARYSERVICE);
  214. rgsteDispatchTable[dwI].lpServiceProc = CalaisMain;
  215. dwI += 1;
  216. rgsteDispatchTable[dwI].lpServiceName = NULL;
  217. rgsteDispatchTable[dwI].lpServiceProc = NULL;
  218. if (!StartServiceCtrlDispatcher(rgsteDispatchTable))
  219. {
  220. dwSts = GetLastError();
  221. CalaisError(__SUBROUTINE__, 505, dwSts);
  222. goto ServiceExit;
  223. }
  224. }
  225. catch (DWORD dwErr)
  226. {
  227. CalaisWarning(
  228. __SUBROUTINE__,
  229. DBGT("Service Main Routine unhandled error: %1"),
  230. dwErr);
  231. }
  232. catch (...)
  233. {
  234. CalaisWarning(
  235. __SUBROUTINE__,
  236. DBGT("Service Main Routine received unexpected exception."));
  237. dwSts = SCARD_F_UNKNOWN_ERROR;
  238. }
  239. ServiceExit:
  240. CalaisInfo(
  241. __SUBROUTINE__,
  242. DBGT("Terminating Smart Card Services Process: %1"),
  243. dwSts);
  244. return dwSts;
  245. ErrorExit:
  246. if (ERROR_SUCCESS != dwSts)
  247. {
  248. LPCTSTR szErr = NULL;
  249. try
  250. {
  251. szErr = ErrorString(dwSts);
  252. }
  253. catch(...)
  254. {
  255. // Not enough memory to build the error message
  256. // Nothing else to do
  257. }
  258. if (NULL == szErr)
  259. _tprintf(_T("0x%08x"), dwSts); // Same form as in ErrorString
  260. // if message can't be found
  261. else
  262. _putts(szErr);
  263. }
  264. return dwSts;
  265. }
  266. #ifdef _DEBUG
  267. /*++
  268. RunNow:
  269. This routine kicks off the resource manager running as an application
  270. process. That makes the internals easier to debug.
  271. Arguments:
  272. None
  273. Return Value:
  274. S_OK
  275. Throws:
  276. None
  277. Remarks:
  278. For private debugging only.
  279. Author:
  280. Doug Barlow (dbarlow) 2/19/1999
  281. --*/
  282. #undef __SUBROUTINE__
  283. #define __SUBROUTINE__ DBGT("RunNow")
  284. static HRESULT
  285. RunNow(
  286. void)
  287. {
  288. DWORD dwStatus;
  289. CalaisInfo(
  290. __SUBROUTINE__,
  291. DBGT("Initiating Smart Card Services Application"));
  292. l_pcsStatusLock = new CCriticalSectionObject(CSID_SERVICE_STATUS);
  293. if (NULL == l_pcsStatusLock)
  294. {
  295. CalaisError(__SUBROUTINE__, 501);
  296. goto FinalExit;
  297. }
  298. if (l_pcsStatusLock->InitFailed())
  299. {
  300. delete l_pcsStatusLock;
  301. l_pcsStatusLock = NULL;
  302. return SCARD_E_NO_MEMORY;
  303. }
  304. CalaisMessageInit(TEXT("Calais Application"));
  305. try
  306. {
  307. l_hShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  308. if (NULL == l_hShutdownEvent)
  309. {
  310. CalaisError(__SUBROUTINE__, 504, GetLastError());
  311. goto FinalExit;
  312. }
  313. //
  314. // Start the Calais Service.
  315. //
  316. dwStatus = CalaisStart();
  317. if (SCARD_S_SUCCESS != dwStatus)
  318. goto ServiceExit;
  319. //
  320. // Tell interested parties that we've started.
  321. //
  322. ResetEvent(AccessStoppedEvent());
  323. SetEvent(AccessStartedEvent());
  324. //
  325. // Now just hang around until we're supposed to stop.
  326. //
  327. dwStatus = WaitForSingleObject(l_hShutdownEvent, INFINITE);
  328. switch (dwStatus)
  329. {
  330. case WAIT_FAILED:
  331. CalaisWarning(
  332. __SUBROUTINE__,
  333. DBGT("Smart Card Resource Manager cannot wait for shutdown: %1"),
  334. GetLastError());
  335. break;
  336. case WAIT_ABANDONED:
  337. CalaisWarning(
  338. __SUBROUTINE__,
  339. DBGT("Smart Card Resource Manager received shutdown wait abandoned"));
  340. // Fall through intentionally
  341. case WAIT_OBJECT_0:
  342. break;
  343. case WAIT_TIMEOUT:
  344. CalaisWarning(
  345. __SUBROUTINE__,
  346. DBGT("Smart Card Resource Manager received shutdown wait time out"));
  347. break;
  348. default:
  349. CalaisWarning(
  350. __SUBROUTINE__,
  351. DBGT("Smart Card Resource Manager received invalid wait return code"));
  352. }
  353. ResetEvent(AccessStartedEvent());
  354. SetEvent(AccessStoppedEvent());
  355. CalaisStop();
  356. ServiceExit:
  357. ResetEvent(AccessStartedEvent());
  358. SetEvent(AccessStoppedEvent());
  359. CalaisInfo(__SUBROUTINE__, DBGT("Calais Stopping"));
  360. FinalExit:
  361. ResetEvent(AccessStartedEvent());
  362. SetEvent(AccessStoppedEvent());
  363. if (NULL != l_hShutdownEvent)
  364. {
  365. if (!CloseHandle(l_hShutdownEvent))
  366. CalaisWarning(
  367. __SUBROUTINE__,
  368. DBGT("Failed to close Calais Shutdown Event: %1"),
  369. GetLastError());
  370. l_hShutdownEvent = NULL;
  371. }
  372. }
  373. catch (DWORD dwErr)
  374. {
  375. CalaisWarning(
  376. __SUBROUTINE__,
  377. DBGT("Calais RunNow Routine unhandled error: %1"),
  378. dwErr);
  379. }
  380. catch (...)
  381. {
  382. CalaisWarning(
  383. __SUBROUTINE__,
  384. DBGT("Calais RunNow Routine received unexpected exception."));
  385. }
  386. CalaisMessageClose();
  387. return S_OK;
  388. }
  389. #endif
  390. #ifdef DEBUG_SERVICE
  391. /*++
  392. DebugMain:
  393. This helper function supplies a simple debuggable process so that
  394. the resource manager can be debugged as a service.
  395. Arguments:
  396. dwArgc supplies the number of command line arguments
  397. pszArgv supplies pointers to each of the arguments.
  398. Return Value:
  399. None
  400. Throws:
  401. None
  402. Author:
  403. Doug Barlow (dbarlow) 8/25/1998
  404. --*/
  405. #undef __SUBROUTINE__
  406. #define __SUBROUTINE__ DBGT("DebugMain")
  407. static void WINAPI
  408. DebugMain(
  409. IN DWORD dwArgc,
  410. IN LPTSTR *pszArgv)
  411. {
  412. NEW_THREAD;
  413. BOOL fSts;
  414. CalaisInfo(
  415. __SUBROUTINE__,
  416. DBGT("Debug service Start"));
  417. try
  418. {
  419. l_hDebugDoneEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  420. ASSERT(NULL != l_hDebugDoneEvent);
  421. l_srvDebug.dwServiceType = SERVICE_INTERACTIVE_PROCESS |
  422. SERVICE_WIN32_SHARE_PROCESS;
  423. l_srvStatus.dwCurrentState = SERVICE_START_PENDING;
  424. l_srvDebug.dwControlsAccepted = SERVICE_ACCEPT_STOP |
  425. SERVICE_ACCEPT_SHUTDOWN;
  426. l_srvDebug.dwWin32ExitCode = NO_ERROR;
  427. l_srvDebug.dwServiceSpecificExitCode = 0;
  428. l_srvDebug.dwCheckPoint = 0;
  429. l_srvDebug.dwWaitHint = 0;
  430. l_hDebug = RegisterServiceCtrlHandler(
  431. CalaisString(CALSTR_DEBUGSERVICE),
  432. DebugHandler);
  433. ASSERT(l_hDebug != NULL);
  434. l_srvDebug.dwCurrentState = SERVICE_RUNNING;
  435. fSts = SetServiceStatus(l_hDebug, &l_srvDebug);
  436. ASSERT(fSts == TRUE);
  437. CalaisInfo(
  438. __SUBROUTINE__,
  439. DBGT("Ready for debugging"));
  440. WaitForSingleObject(l_hDebugDoneEvent, INFINITE);
  441. CalaisInfo(
  442. __SUBROUTINE__,
  443. DBGT("Debugger service Stopping"));
  444. l_srvDebug.dwCurrentState = SERVICE_STOPPED;
  445. fSts = SetServiceStatus(l_hDebug, &l_srvDebug);
  446. }
  447. catch (DWORD dwErr)
  448. {
  449. CalaisWarning(
  450. __SUBROUTINE__,
  451. DBGT("Debug Main Routine unhandled error: %1"),
  452. dwErr);
  453. }
  454. catch (...)
  455. {
  456. CalaisWarning(
  457. __SUBROUTINE__,
  458. DBGT("Debug Main Routine received unexpected exception."));
  459. }
  460. if (NULL != l_hDebugDoneEvent)
  461. {
  462. fSts = CloseHandle(l_hDebugDoneEvent);
  463. l_hDebugDoneEvent = NULL;
  464. if (!fSts)
  465. {
  466. CalaisWarning(
  467. __SUBROUTINE__,
  468. DBGT("Failed to close Debug Service Handle: %1"),
  469. GetLastError());
  470. }
  471. }
  472. CalaisInfo(__SUBROUTINE__, DBGT("Debug service Complete"));
  473. }
  474. /*++
  475. DebugHandler:
  476. This routine services Debug requests.
  477. Arguments:
  478. dwOpCode supplies the service request.
  479. Return Value:
  480. None
  481. Throws:
  482. None
  483. Remarks:
  484. Standard Service processing routine. In theory, this will never get
  485. called, but just in case...
  486. Author:
  487. Doug Barlow (dbarlow) 8/25/1998
  488. --*/
  489. #undef __SUBROUTINE__
  490. #define __SUBROUTINE__ DBGT("DebugHandler")
  491. static void WINAPI
  492. DebugHandler(
  493. IN DWORD dwOpCode)
  494. {
  495. NEW_THREAD;
  496. DWORD nRetVal = NO_ERROR;
  497. //
  498. // Process the command.
  499. //
  500. CalaisInfo(__SUBROUTINE__, DBGT("Debug Handler Entered"));
  501. try
  502. {
  503. switch (dwOpCode)
  504. {
  505. case SERVICE_CONTROL_PAUSE:
  506. l_srvDebug.dwCurrentState = SERVICE_PAUSED;
  507. break;
  508. case SERVICE_CONTROL_CONTINUE:
  509. l_srvDebug.dwCurrentState = SERVICE_RUNNING;
  510. break;
  511. case SERVICE_CONTROL_INTERROGATE:
  512. break;
  513. case SERVICE_CONTROL_STOP:
  514. case SERVICE_CONTROL_SHUTDOWN:
  515. l_srvDebug.dwCurrentState = SERVICE_STOP_PENDING;
  516. l_srvDebug.dwCheckPoint = 0;
  517. l_srvDebug.dwWaitHint = 0;
  518. SetEvent(l_hDebugDoneEvent);
  519. break;
  520. default: // No action
  521. break;
  522. }
  523. l_srvDebug.dwWin32ExitCode = nRetVal;
  524. if (!SetServiceStatus(l_hDebug, &l_srvDebug))
  525. CalaisWarning(
  526. __SUBROUTINE__,
  527. DBGT("Failed to register Debug service status: %1"),
  528. GetLastError());
  529. }
  530. catch (DWORD dwErr)
  531. {
  532. CalaisWarning(
  533. __SUBROUTINE__,
  534. DBGT("Debug Handler Routine unhandled error: %1"),
  535. dwErr);
  536. }
  537. catch (...)
  538. {
  539. CalaisWarning(
  540. __SUBROUTINE__,
  541. DBGT("Debug Handler Routine received unexpected exception."));
  542. }
  543. CalaisInfo(__SUBROUTINE__, DBGT("Debug Handler Returned"));
  544. }
  545. #endif
  546. //
  547. // Permanently removes unneeded privileges from the service.
  548. //
  549. DWORD DisableUnnecessaryPrivileges(void)
  550. {
  551. DWORD dwSts = ERROR_SUCCESS;
  552. HANDLE hToken = NULL;
  553. PTOKEN_PRIVILEGES pTokenPrivileges = NULL;
  554. DWORD cbTokenPrivileges = 0;
  555. LUID_AND_ATTRIBUTES rgAttributes [] = {
  556. { RtlConvertUlongToLuid(SE_SECURITY_PRIVILEGE), SE_PRIVILEGE_REMOVED },
  557. { RtlConvertUlongToLuid(SE_CREATE_TOKEN_PRIVILEGE), SE_PRIVILEGE_REMOVED },
  558. { RtlConvertUlongToLuid(SE_TAKE_OWNERSHIP_PRIVILEGE), SE_PRIVILEGE_REMOVED },
  559. { RtlConvertUlongToLuid(SE_CREATE_PAGEFILE_PRIVILEGE), SE_PRIVILEGE_REMOVED },
  560. { RtlConvertUlongToLuid(SE_LOCK_MEMORY_PRIVILEGE), SE_PRIVILEGE_REMOVED },
  561. { RtlConvertUlongToLuid(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE), SE_PRIVILEGE_REMOVED },
  562. { RtlConvertUlongToLuid(SE_INCREASE_QUOTA_PRIVILEGE), SE_PRIVILEGE_REMOVED },
  563. { RtlConvertUlongToLuid(SE_INC_BASE_PRIORITY_PRIVILEGE), SE_PRIVILEGE_REMOVED },
  564. { RtlConvertUlongToLuid(SE_CREATE_PERMANENT_PRIVILEGE), SE_PRIVILEGE_REMOVED },
  565. { RtlConvertUlongToLuid(SE_DEBUG_PRIVILEGE), SE_PRIVILEGE_REMOVED },
  566. { RtlConvertUlongToLuid(SE_AUDIT_PRIVILEGE), SE_PRIVILEGE_REMOVED },
  567. { RtlConvertUlongToLuid(SE_SYSTEM_ENVIRONMENT_PRIVILEGE), SE_PRIVILEGE_REMOVED },
  568. { RtlConvertUlongToLuid(SE_BACKUP_PRIVILEGE), SE_PRIVILEGE_REMOVED },
  569. { RtlConvertUlongToLuid(SE_RESTORE_PRIVILEGE), SE_PRIVILEGE_REMOVED },
  570. { RtlConvertUlongToLuid(SE_SHUTDOWN_PRIVILEGE), SE_PRIVILEGE_REMOVED },
  571. { RtlConvertUlongToLuid(SE_PROF_SINGLE_PROCESS_PRIVILEGE), SE_PRIVILEGE_REMOVED },
  572. { RtlConvertUlongToLuid(SE_SYSTEMTIME_PRIVILEGE), SE_PRIVILEGE_REMOVED },
  573. { RtlConvertUlongToLuid(SE_UNDOCK_PRIVILEGE), SE_PRIVILEGE_REMOVED }
  574. };
  575. // PTOKEN_PRIVILEGES is one ULONG count followed by the privileges
  576. // array.
  577. cbTokenPrivileges =
  578. sizeof(rgAttributes) + sizeof(ULONG);
  579. pTokenPrivileges = (PTOKEN_PRIVILEGES) HeapAlloc(
  580. GetProcessHeap(), HEAP_ZERO_MEMORY, cbTokenPrivileges);
  581. if (NULL == pTokenPrivileges)
  582. return ERROR_NOT_ENOUGH_MEMORY;
  583. pTokenPrivileges->PrivilegeCount =
  584. sizeof(rgAttributes) / sizeof(rgAttributes[0]);
  585. // Taking the hit of copying the array after it's been set up. This method
  586. // seems to generate a lot less code than setting up each array item
  587. // one by one, but not sure which way is faster.
  588. memcpy(
  589. pTokenPrivileges->Privileges,
  590. rgAttributes,
  591. sizeof(rgAttributes));
  592. // Get our token.
  593. if (! OpenThreadToken(
  594. GetCurrentThread(),
  595. TOKEN_ADJUST_PRIVILEGES,
  596. TRUE,
  597. &hToken))
  598. {
  599. if (! OpenProcessToken(
  600. GetCurrentProcess(),
  601. TOKEN_ADJUST_PRIVILEGES,
  602. &hToken))
  603. {
  604. dwSts = GetLastError();
  605. goto Ret;
  606. }
  607. }
  608. // Permenantly remove this set of privileges for this process.
  609. if (! AdjustTokenPrivileges(
  610. hToken,
  611. FALSE,
  612. pTokenPrivileges,
  613. cbTokenPrivileges,
  614. NULL,
  615. NULL))
  616. {
  617. dwSts = GetLastError();
  618. goto Ret;
  619. }
  620. Ret:
  621. if (hToken)
  622. CloseHandle(hToken);
  623. if (pTokenPrivileges)
  624. HeapFree(GetProcessHeap(), 0, pTokenPrivileges);
  625. return dwSts;
  626. }
  627. /*++
  628. CalaisMain:
  629. This is the ServiceMain service entry point. It is only called under the
  630. NT operating system, and makes that assumption.
  631. Arguments:
  632. argc supplies the number of command line arguments
  633. argv supplies pointers to each of the arguments.
  634. Return Value:
  635. None
  636. Throws:
  637. None
  638. Author:
  639. Doug Barlow (dbarlow) 1/16/1997
  640. --*/
  641. #undef __SUBROUTINE__
  642. #define __SUBROUTINE__ DBGT("CalaisMain")
  643. static void WINAPI
  644. CalaisMain(
  645. IN DWORD dwArgc,
  646. IN LPTSTR *pszArgv)
  647. {
  648. NEW_THREAD;
  649. CalaisMessageInit(CalaisString(CALSTR_PRIMARYSERVICE), NULL, TRUE);
  650. CalaisInfo(__SUBROUTINE__, DBGT("CalaisMain Entered"));
  651. l_pcsStatusLock = new CCriticalSectionObject(CSID_SERVICE_STATUS);
  652. if (NULL == l_pcsStatusLock)
  653. {
  654. CalaisError(__SUBROUTINE__, 507);
  655. return;
  656. }
  657. if (l_pcsStatusLock->InitFailed())
  658. {
  659. CalaisError(__SUBROUTINE__, 502);
  660. delete l_pcsStatusLock;
  661. l_pcsStatusLock = NULL;
  662. return;
  663. }
  664. try
  665. {
  666. DWORD dwStatus;
  667. BOOL fSts;
  668. l_srvStatus.dwServiceType =
  669. #ifdef DBG
  670. SERVICE_INTERACTIVE_PROCESS |
  671. #endif
  672. SERVICE_WIN32_SHARE_PROCESS;
  673. l_srvStatus.dwCurrentState = SERVICE_START_PENDING;
  674. l_srvStatus.dwControlsAccepted =
  675. #ifdef SERVICE_ACCEPT_POWER_EVENTS
  676. SERVICE_ACCEPT_POWER_EVENTS |
  677. #endif
  678. #ifdef SERVICE_ACCEPT_DEVICE_EVENTS
  679. SERVICE_ACCEPT_DEVICE_EVENTS |
  680. #endif
  681. SERVICE_ACCEPT_STOP |
  682. SERVICE_ACCEPT_SHUTDOWN;
  683. l_srvStatus.dwWin32ExitCode = NO_ERROR;
  684. l_srvStatus.dwServiceSpecificExitCode = 0;
  685. l_srvStatus.dwCheckPoint = 0;
  686. l_srvStatus.dwWaitHint = 0;
  687. l_hShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  688. if (NULL == l_hShutdownEvent)
  689. {
  690. CalaisError(__SUBROUTINE__, 504, GetLastError());
  691. goto FinalExit;
  692. }
  693. //
  694. // Initialize the service and the internal data structures.
  695. //
  696. l_hService = RegisterServiceCtrlHandlerEx(
  697. CalaisString(CALSTR_PRIMARYSERVICE),
  698. CalaisHandlerEx,
  699. NULL);
  700. if (NULL == l_hService)
  701. {
  702. CalaisError(__SUBROUTINE__, 506, GetLastError());
  703. goto FinalExit;
  704. }
  705. //
  706. // Tell the Service Manager that we're trying to start.
  707. //
  708. {
  709. LockSection(l_pcsStatusLock, DBGT("Service Start Pending"));
  710. l_srvStatus.dwCurrentState = SERVICE_START_PENDING;
  711. l_srvStatus.dwCheckPoint = 0;
  712. l_srvStatus.dwWaitHint = l_dwWaitHint;
  713. fSts = SetServiceStatus(l_hService, &l_srvStatus);
  714. dwStatus = fSts ? ERROR_SUCCESS : GetLastError();
  715. }
  716. if (ERROR_SUCCESS != dwStatus)
  717. {
  718. CalaisWarning(
  719. __SUBROUTINE__,
  720. DBGT("Failed to update Service Manager status: %1"),
  721. dwStatus);
  722. }
  723. //
  724. // Register for future Plug 'n Play events.
  725. //
  726. try
  727. {
  728. AppInitializeDeviceRegistration(
  729. l_hService,
  730. DEVICE_NOTIFY_SERVICE_HANDLE);
  731. }
  732. catch (...)
  733. {
  734. CalaisWarning(
  735. __SUBROUTINE__,
  736. DBGT("Smart Card Resource Manager failed to register PnP events"));
  737. }
  738. //
  739. // Setup the shared security data used by the service threads.
  740. //
  741. dwStatus = InitializeServiceThreadSecurityInfo(
  742. &g_pServiceThreadSecurityInfo);
  743. if (SCARD_S_SUCCESS != dwStatus)
  744. goto ServiceExit;
  745. dwStatus = DisableUnnecessaryPrivileges();
  746. if (ERROR_SUCCESS != dwStatus)
  747. goto ServiceExit;
  748. //
  749. // Start the Calais Service.
  750. //
  751. dwStatus = CalaisStart();
  752. if (SCARD_S_SUCCESS != dwStatus)
  753. goto ServiceExit;
  754. else
  755. {
  756. LockSection(l_pcsStatusLock, DBGT("Declare Service Running"));
  757. l_srvStatus.dwCurrentState = SERVICE_RUNNING;
  758. l_srvStatus.dwCheckPoint = 0;
  759. l_srvStatus.dwWaitHint = 0;
  760. fSts = SetServiceStatus(l_hService, &l_srvStatus);
  761. dwStatus = fSts ? ERROR_SUCCESS : GetLastError();
  762. }
  763. if (ERROR_SUCCESS != dwStatus)
  764. CalaisWarning(
  765. __SUBROUTINE__,
  766. DBGT("Failed to update Service Manager status: %1"),
  767. dwStatus);
  768. //
  769. // Tell interested parties that we've started.
  770. //
  771. ResetEvent(AccessStoppedEvent());
  772. SetEvent(AccessStartedEvent());
  773. //
  774. // Now just hang around until we're supposed to stop.
  775. //
  776. dwStatus = WaitForSingleObject(l_hShutdownEvent, INFINITE);
  777. switch (dwStatus)
  778. {
  779. case WAIT_FAILED:
  780. CalaisWarning(
  781. __SUBROUTINE__,
  782. DBGT("Smart Card Resource Manager cannot wait for shutdown: %1"),
  783. GetLastError());
  784. break;
  785. case WAIT_ABANDONED:
  786. CalaisWarning(
  787. __SUBROUTINE__,
  788. DBGT("Smart Card Resource Manager received shutdown wait abandoned"));
  789. // Fall through intentionally
  790. case WAIT_OBJECT_0:
  791. break;
  792. case WAIT_TIMEOUT:
  793. CalaisWarning(
  794. __SUBROUTINE__,
  795. DBGT("Smart Card Resource Manager received shutdown wait time out"));
  796. break;
  797. default:
  798. CalaisWarning(
  799. __SUBROUTINE__,
  800. DBGT("Smart Card Resource Manager received invalid wait return code"));
  801. }
  802. ResetEvent(AccessStartedEvent());
  803. SetEvent(AccessStoppedEvent());
  804. CalaisStop();
  805. ServiceExit:
  806. ResetEvent(AccessStartedEvent());
  807. SetEvent(AccessStoppedEvent());
  808. CalaisInfo(__SUBROUTINE__, DBGT("Calais Main Stopping"));
  809. AppTerminateDeviceRegistration();
  810. {
  811. LockSection(l_pcsStatusLock, DBGT("Declare service stopped"));
  812. l_srvStatus.dwCurrentState = SERVICE_STOPPED;
  813. l_srvStatus.dwWin32ExitCode = dwStatus;
  814. l_srvStatus.dwCheckPoint = 0;
  815. l_srvStatus.dwWaitHint = 0;
  816. fSts = SetServiceStatus(l_hService, &l_srvStatus);
  817. dwStatus = fSts ? ERROR_SUCCESS : GetLastError();
  818. }
  819. if (ERROR_SUCCESS != dwStatus)
  820. CalaisWarning(
  821. __SUBROUTINE__,
  822. DBGT("Failed to update Service Manager status: %1"),
  823. dwStatus);
  824. FinalExit:
  825. ResetEvent(AccessStartedEvent());
  826. SetEvent(AccessStoppedEvent());
  827. if (NULL != l_hShutdownEvent)
  828. {
  829. fSts = CloseHandle(l_hShutdownEvent);
  830. l_hShutdownEvent = NULL;
  831. if (!fSts)
  832. CalaisWarning(
  833. __SUBROUTINE__,
  834. DBGT("Failed to close Calais Shutdown Event: %1"),
  835. GetLastError());
  836. }
  837. ReleaseAllEvents();
  838. if (NULL != g_pServiceThreadSecurityInfo)
  839. FreeServiceThreadSecurityInfo(
  840. &g_pServiceThreadSecurityInfo);
  841. }
  842. catch (DWORD dwErr)
  843. {
  844. CalaisWarning(
  845. __SUBROUTINE__,
  846. DBGT("Calais Main Routine unhandled error: %1"),
  847. dwErr);
  848. }
  849. catch (...)
  850. {
  851. CalaisWarning(
  852. __SUBROUTINE__,
  853. DBGT("Calais Main Routine received unexpected exception."));
  854. }
  855. CalaisInfo(__SUBROUTINE__, DBGT("CalaisMain Ended"));
  856. CalaisMessageClose();
  857. if (NULL != l_pcsStatusLock)
  858. {
  859. delete l_pcsStatusLock;
  860. l_pcsStatusLock = NULL;
  861. }
  862. }
  863. /*++
  864. CalaisHandlerEx:
  865. The handler service function for Calais on NT5. This version gets PnP and
  866. Power Management notifications, too.
  867. Arguments:
  868. dwOpCode supplies the operation to perform.
  869. Return Value:
  870. None
  871. Throws:
  872. None
  873. Author:
  874. Doug Barlow (dbarlow) 1/16/1997
  875. --*/
  876. #undef __SUBROUTINE__
  877. #define __SUBROUTINE__ DBGT("CalaisHandlerEx")
  878. static DWORD WINAPI
  879. CalaisHandlerEx(
  880. IN DWORD dwControl,
  881. IN DWORD dwEventType,
  882. IN PVOID EventData,
  883. IN PVOID pData)
  884. {
  885. NEW_THREAD;
  886. DWORD nRetVal = NO_ERROR;
  887. LockSection(l_pcsStatusLock, DBGT("Responding to service event"));
  888. CalaisDebug((DBGT("SCARDSVR!CalaisHandlerEx: Enter\n")));
  889. try
  890. {
  891. //
  892. // Process the command.
  893. //
  894. switch (dwControl)
  895. {
  896. case SERVICE_CONTROL_PAUSE:
  897. // ?noSupport?
  898. l_srvStatus.dwCurrentState = SERVICE_PAUSED;
  899. break;
  900. case SERVICE_CONTROL_CONTINUE:
  901. l_srvStatus.dwCurrentState = SERVICE_RUNNING;
  902. // ?noSupport?
  903. break;
  904. case SERVICE_CONTROL_INTERROGATE:
  905. break;
  906. case SERVICE_CONTROL_STOP:
  907. case SERVICE_CONTROL_SHUTDOWN:
  908. l_srvStatus.dwCurrentState = SERVICE_STOP_PENDING;
  909. l_srvStatus.dwCheckPoint = 0;
  910. l_srvStatus.dwWaitHint = l_dwWaitHint;
  911. if (!SetEvent(l_hShutdownEvent))
  912. CalaisError(__SUBROUTINE__, 516, GetLastError());
  913. break;
  914. case SERVICE_CONTROL_DEVICEEVENT:
  915. {
  916. DWORD dwSts;
  917. CTextString tzReader;
  918. LPCTSTR szReader = NULL;
  919. DEV_BROADCAST_HDR *pDevHdr = (DEV_BROADCAST_HDR *)EventData;
  920. CalaisInfo(
  921. __SUBROUTINE__,
  922. DBGT("Processing Device Event"));
  923. switch (dwEventType)
  924. {
  925. //
  926. // A device has been inserted and is now available.
  927. case DBT_DEVICEARRIVAL:
  928. {
  929. DEV_BROADCAST_DEVICEINTERFACE *pDev
  930. = (DEV_BROADCAST_DEVICEINTERFACE *)EventData;
  931. try
  932. {
  933. CalaisInfo(
  934. __SUBROUTINE__,
  935. DBGT("Processing Device Arrival Event"));
  936. if (DBT_DEVTYP_DEVICEINTERFACE == pDev->dbcc_devicetype)
  937. {
  938. ASSERT(sizeof(DEV_BROADCAST_DEVICEINTERFACE)
  939. < pDev->dbcc_size);
  940. ASSERT(0 == memcmp(
  941. &pDev->dbcc_classguid,
  942. &l_guidSmartcards,
  943. sizeof(GUID)));
  944. ASSERT(0 != pDev->dbcc_name[0]);
  945. if (0 == pDev->dbcc_name[1])
  946. tzReader = (LPCWSTR)pDev->dbcc_name;
  947. else
  948. tzReader = (LPCTSTR)pDev->dbcc_name;
  949. szReader = tzReader;
  950. dwSts = CalaisAddReader(szReader, RDRFLAG_PNPMONITOR);
  951. if (ERROR_SUCCESS != dwSts)
  952. throw dwSts;
  953. CalaisWarning(
  954. __SUBROUTINE__,
  955. DBGT("New device '%1' added."),
  956. szReader);
  957. }
  958. else
  959. CalaisWarning(
  960. __SUBROUTINE__,
  961. DBGT("Spurious device arrival event."));
  962. }
  963. catch (DWORD dwError)
  964. {
  965. CalaisError(__SUBROUTINE__, 514, dwError, szReader);
  966. }
  967. catch (...)
  968. {
  969. CalaisError(__SUBROUTINE__, 517, szReader);
  970. }
  971. break;
  972. }
  973. //
  974. // Permission to remove a device is requested. Any application can
  975. // deny this request and cancel the removal.
  976. case DBT_DEVICEQUERYREMOVE:
  977. {
  978. DEV_BROADCAST_HANDLE *pDev = (DEV_BROADCAST_HANDLE *)EventData;
  979. try
  980. {
  981. CalaisInfo(
  982. __SUBROUTINE__,
  983. DBGT("Processing Device Query Remove Event"));
  984. if (DBT_DEVTYP_HANDLE == pDev->dbch_devicetype)
  985. {
  986. ASSERT(FIELD_OFFSET(
  987. DEV_BROADCAST_HANDLE,
  988. dbch_eventguid)
  989. <= pDev->dbch_size);
  990. ASSERT(NULL != pDev->dbch_handle);
  991. ASSERT(NULL != pDev->dbch_hdevnotify);
  992. if (NULL != pDev->dbch_handle)
  993. {
  994. if (!CalaisQueryReader(pDev->dbch_handle))
  995. {
  996. CalaisError(
  997. __SUBROUTINE__,
  998. 520,
  999. TEXT("DBT_DEVICEQUERYREMOVE/dbch_handle"));
  1000. nRetVal = ERROR_DEVICE_IN_USE; // BROADCAST_QUERY_DENY
  1001. }
  1002. else
  1003. {
  1004. szReader = CalaisDisableReader(
  1005. (LPVOID)pDev->dbch_handle);
  1006. CalaisWarning(
  1007. __SUBROUTINE__,
  1008. DBGT("Device '%1' removal pending."),
  1009. szReader);
  1010. }
  1011. }
  1012. else
  1013. {
  1014. CalaisError(
  1015. __SUBROUTINE__,
  1016. 523,
  1017. TEXT("DBT_DEVICEQUERYREMOVE/dbch_handle"));
  1018. nRetVal = ERROR_DEVICE_IN_USE; // BROADCAST_QUERY_DENY
  1019. }
  1020. }
  1021. else
  1022. {
  1023. CalaisWarning(
  1024. __SUBROUTINE__,
  1025. DBGT("Spurious device removal query event."));
  1026. nRetVal = TRUE;
  1027. }
  1028. }
  1029. catch (DWORD dwError)
  1030. {
  1031. CalaisWarning(
  1032. __SUBROUTINE__,
  1033. DBGT("Error querying device busy state on reader %2: %1"),
  1034. dwError,
  1035. szReader);
  1036. nRetVal = ERROR_DEVICE_IN_USE; // BROADCAST_QUERY_DENY
  1037. }
  1038. catch (...)
  1039. {
  1040. CalaisWarning(
  1041. __SUBROUTINE__,
  1042. DBGT("Exception querying device busy state on reader %1"),
  1043. szReader);
  1044. CalaisError(
  1045. __SUBROUTINE__,
  1046. 522,
  1047. TEXT("DBT_DEVICEQUERYREMOVE"));
  1048. nRetVal = ERROR_DEVICE_IN_USE; // BROADCAST_QUERY_DENY
  1049. }
  1050. break;
  1051. }
  1052. //
  1053. // Request to remove a device has been canceled.
  1054. case DBT_DEVICEQUERYREMOVEFAILED:
  1055. {
  1056. CBuffer bfDevice;
  1057. DEV_BROADCAST_HANDLE *pDev = (DEV_BROADCAST_HANDLE *)EventData;
  1058. try
  1059. {
  1060. CalaisInfo(
  1061. __SUBROUTINE__,
  1062. DBGT("Processing Device Query Remove Failed Event"));
  1063. if (DBT_DEVTYP_HANDLE == pDev->dbch_devicetype)
  1064. {
  1065. ASSERT(FIELD_OFFSET(
  1066. DEV_BROADCAST_HANDLE,
  1067. dbch_eventguid)
  1068. <= pDev->dbch_size);
  1069. ASSERT(NULL != pDev->dbch_handle);
  1070. ASSERT(NULL != pDev->dbch_hdevnotify);
  1071. if (NULL != pDev->dbch_handle)
  1072. {
  1073. szReader = CalaisConfirmClosingReader(
  1074. pDev->dbch_handle);
  1075. if (NULL != szReader)
  1076. {
  1077. bfDevice.Set(
  1078. (LPBYTE)szReader,
  1079. (lstrlen(szReader) + 1) * sizeof(TCHAR));
  1080. szReader = (LPCTSTR)bfDevice.Access();
  1081. CalaisWarning(
  1082. __SUBROUTINE__,
  1083. DBGT("Smart Card Resource Manager asked to cancel release of reader %1"),
  1084. szReader);
  1085. if (NULL != pDev->dbch_hdevnotify)
  1086. {
  1087. CalaisRemoveReader(
  1088. (LPVOID)pDev->dbch_hdevnotify);
  1089. if (NULL != szReader)
  1090. dwSts = CalaisAddReader(
  1091. szReader,
  1092. RDRFLAG_PNPMONITOR);
  1093. }
  1094. }
  1095. else
  1096. CalaisWarning(
  1097. __SUBROUTINE__,
  1098. DBGT("Smart Card Resource Manager asked to cancel release on unreleased reader"));
  1099. }
  1100. else
  1101. CalaisError(
  1102. __SUBROUTINE__,
  1103. 521,
  1104. TEXT("DBT_DEVICEQUERYREMOVEFAILED/dbch_handle"));
  1105. }
  1106. else
  1107. {
  1108. CalaisWarning(
  1109. __SUBROUTINE__,
  1110. DBGT("Spurious device removal query failure event."));
  1111. }
  1112. }
  1113. catch (DWORD dwError)
  1114. {
  1115. CalaisWarning(
  1116. __SUBROUTINE__,
  1117. DBGT("Error cancelling removal on reader %2: %1"),
  1118. dwError,
  1119. szReader);
  1120. }
  1121. catch (...)
  1122. {
  1123. CalaisWarning(
  1124. __SUBROUTINE__,
  1125. DBGT("Exception cancelling removal on reader %1"),
  1126. szReader);
  1127. CalaisError(
  1128. __SUBROUTINE__,
  1129. 513,
  1130. TEXT("DBT_DEVICEQUERYREMOVEFAILED"));
  1131. }
  1132. break;
  1133. }
  1134. //
  1135. // Device is about to be removed. Cannot be denied.
  1136. case DBT_DEVICEREMOVEPENDING:
  1137. {
  1138. DEV_BROADCAST_HANDLE *pDev = (DEV_BROADCAST_HANDLE *)EventData;
  1139. try
  1140. {
  1141. CalaisInfo(
  1142. __SUBROUTINE__,
  1143. DBGT("Processing Device Remove Pending Event"));
  1144. if (DBT_DEVTYP_HANDLE == pDev->dbch_devicetype)
  1145. {
  1146. ASSERT(FIELD_OFFSET(
  1147. DEV_BROADCAST_HANDLE,
  1148. dbch_eventguid)
  1149. <= pDev->dbch_size);
  1150. ASSERT(NULL != pDev->dbch_handle);
  1151. ASSERT(NULL != pDev->dbch_hdevnotify);
  1152. if (NULL != pDev->dbch_handle)
  1153. {
  1154. szReader = CalaisDisableReader(pDev->dbch_handle);
  1155. CalaisWarning(
  1156. __SUBROUTINE__,
  1157. DBGT("Device '%1' being removed."),
  1158. szReader);
  1159. }
  1160. else
  1161. CalaisError(
  1162. __SUBROUTINE__,
  1163. 512,
  1164. TEXT("DBT_DEVICEREMOVEPENDING/dbch_handle"));
  1165. }
  1166. else
  1167. {
  1168. CalaisWarning(
  1169. __SUBROUTINE__,
  1170. DBGT("Spurious device removal pending event."));
  1171. }
  1172. }
  1173. catch (DWORD dwError)
  1174. {
  1175. CalaisWarning(
  1176. __SUBROUTINE__,
  1177. DBGT("Error removing reader %2: %1"),
  1178. dwError,
  1179. szReader);
  1180. }
  1181. catch (...)
  1182. {
  1183. CalaisWarning(
  1184. __SUBROUTINE__,
  1185. DBGT("Exception removing reader %1"),
  1186. szReader);
  1187. CalaisError(
  1188. __SUBROUTINE__,
  1189. 511,
  1190. TEXT("DBT_DEVICEREMOVEPENDING"));
  1191. }
  1192. break;
  1193. }
  1194. //
  1195. // Device has been removed.
  1196. case DBT_DEVICEREMOVECOMPLETE:
  1197. {
  1198. try
  1199. {
  1200. switch (pDevHdr->dbch_devicetype)
  1201. {
  1202. case DBT_DEVTYP_HANDLE:
  1203. {
  1204. DEV_BROADCAST_HANDLE *pDev =
  1205. (DEV_BROADCAST_HANDLE *)EventData;
  1206. try
  1207. {
  1208. CalaisInfo(
  1209. __SUBROUTINE__,
  1210. DBGT("Processing Device Remove Complete by handle Event"));
  1211. ASSERT(FIELD_OFFSET(
  1212. DEV_BROADCAST_HANDLE,
  1213. dbch_eventguid)
  1214. <= pDev->dbch_size);
  1215. ASSERT(DBT_DEVTYP_HANDLE == pDev->dbch_devicetype);
  1216. ASSERT(NULL != pDev->dbch_handle);
  1217. ASSERT(NULL != pDev->dbch_hdevnotify);
  1218. if ((NULL != pDev->dbch_handle)
  1219. && (NULL != pDev->dbch_hdevnotify))
  1220. {
  1221. szReader = CalaisDisableReader(
  1222. pDev->dbch_handle);
  1223. CalaisRemoveReader(
  1224. (LPVOID)pDev->dbch_hdevnotify);
  1225. if (NULL != szReader)
  1226. CalaisWarning(
  1227. __SUBROUTINE__,
  1228. DBGT("Device '%1' removed."),
  1229. szReader);
  1230. }
  1231. else
  1232. {
  1233. if (NULL == pDev->dbch_handle)
  1234. CalaisError(
  1235. __SUBROUTINE__,
  1236. 510,
  1237. TEXT("DBT_DEVICEREMOVECOMPLETE/DBT_DEVTYP_HANDLE/dbch_handle"));
  1238. if (NULL == pDev->dbch_hdevnotify)
  1239. CalaisError(
  1240. __SUBROUTINE__,
  1241. 519,
  1242. TEXT("DBT_DEVICEREMOVECOMPLETE/DBT_DEVTYP_HANDLE/dbch_hdevnotify"));
  1243. }
  1244. }
  1245. catch (DWORD dwError)
  1246. {
  1247. CalaisWarning(
  1248. __SUBROUTINE__,
  1249. DBGT("Error completing removal of reader %2: %1"),
  1250. dwError,
  1251. szReader);
  1252. }
  1253. catch (...)
  1254. {
  1255. CalaisWarning(
  1256. __SUBROUTINE__,
  1257. DBGT("Exception completing removal of reader %1"),
  1258. szReader);
  1259. CalaisError(
  1260. __SUBROUTINE__,
  1261. 509,
  1262. TEXT("DBT_DEVICEREMOVECOMPLETE/DBT_DEVTYP_HANDLE"));
  1263. }
  1264. break;
  1265. }
  1266. case DBT_DEVTYP_DEVICEINTERFACE:
  1267. {
  1268. DEV_BROADCAST_DEVICEINTERFACE *pDev
  1269. = (DEV_BROADCAST_DEVICEINTERFACE *)EventData;
  1270. try
  1271. {
  1272. CalaisInfo(
  1273. __SUBROUTINE__,
  1274. DBGT("Processing Device Remove Complete by interface Event"));
  1275. ASSERT(sizeof(DEV_BROADCAST_DEVICEINTERFACE)
  1276. < pDev->dbcc_size);
  1277. ASSERT(DBT_DEVTYP_DEVICEINTERFACE
  1278. == pDev->dbcc_devicetype);
  1279. ASSERT(0 == memcmp(
  1280. &pDev->dbcc_classguid,
  1281. &l_guidSmartcards,
  1282. sizeof(GUID)));
  1283. ASSERT(0 != pDev->dbcc_name[0]);
  1284. if (0 == pDev->dbcc_name[1])
  1285. tzReader = (LPCWSTR)pDev->dbcc_name;
  1286. else
  1287. tzReader = (LPCTSTR)pDev->dbcc_name;
  1288. szReader = tzReader;
  1289. dwSts = CalaisRemoveDevice(szReader);
  1290. if (ERROR_SUCCESS == dwSts)
  1291. CalaisWarning(
  1292. __SUBROUTINE__,
  1293. DBGT("Device '%1' Removed."),
  1294. szReader);
  1295. else
  1296. CalaisWarning(
  1297. __SUBROUTINE__,
  1298. DBGT("Error removing device '%2': %1"),
  1299. dwSts,
  1300. szReader);
  1301. }
  1302. catch (DWORD dwError)
  1303. {
  1304. CalaisWarning(
  1305. __SUBROUTINE__,
  1306. DBGT("Error completing removal of reader %2: %1"),
  1307. dwError,
  1308. szReader);
  1309. }
  1310. catch (...)
  1311. {
  1312. CalaisWarning(
  1313. __SUBROUTINE__,
  1314. DBGT("Exception completing removal of reader %1"),
  1315. szReader);
  1316. CalaisError(
  1317. __SUBROUTINE__,
  1318. 508,
  1319. TEXT("DBT_DEVICEREMOVECOMPLETE/DBT_DEVTYP_DEVICEINTERFACE"));
  1320. }
  1321. break;
  1322. }
  1323. default:
  1324. CalaisWarning(
  1325. __SUBROUTINE__,
  1326. DBGT("Unrecognized PnP Device Removal Type"));
  1327. break;
  1328. }
  1329. }
  1330. catch (...)
  1331. {
  1332. CalaisError(
  1333. __SUBROUTINE__,
  1334. 518,
  1335. TEXT("DBT_DEVICEREMOVECOMPLETE"));
  1336. }
  1337. break;
  1338. }
  1339. default:
  1340. CalaisWarning(
  1341. __SUBROUTINE__,
  1342. DBGT("Unrecognized PnP Event"));
  1343. break;
  1344. }
  1345. break;
  1346. }
  1347. case SERVICE_CONTROL_POWEREVENT:
  1348. CalaisWarning(
  1349. __SUBROUTINE__,
  1350. DBGT("Smart Card Resource Manager received Power Event!"));
  1351. break;
  1352. default: // No action
  1353. break;
  1354. }
  1355. }
  1356. catch (DWORD dwError)
  1357. {
  1358. CalaisWarning(
  1359. __SUBROUTINE__,
  1360. DBGT("Smart Card Resource Manager received error on service action: %1"),
  1361. dwError);
  1362. }
  1363. catch (...)
  1364. {
  1365. CalaisWarning(
  1366. __SUBROUTINE__,
  1367. DBGT("Smart Card Resource Manager recieved exception on service action"));
  1368. }
  1369. l_srvStatus.dwWin32ExitCode = nRetVal;
  1370. if (!SetServiceStatus(l_hService, &l_srvStatus))
  1371. CalaisError(__SUBROUTINE__, 515, GetLastError());
  1372. CalaisDebug(
  1373. (DBGT("SCARDSVR!CalaisHandlerEx: Exit (%lx)\n"),
  1374. nRetVal));
  1375. return nRetVal;
  1376. }
  1377. /*++
  1378. CalaisTerminate:
  1379. This function is called if the C Run Time Library wants to declare a fault.
  1380. If we get here, we're not coming back.
  1381. Arguments:
  1382. None
  1383. Return Value:
  1384. None (program exits on return)
  1385. Remarks:
  1386. ?Remarks?
  1387. Author:
  1388. Doug Barlow (dbarlow) 12/2/1998
  1389. --*/
  1390. #undef __SUBROUTINE__
  1391. #define __SUBROUTINE__ DBGT("CalaisTerminate")
  1392. void __cdecl
  1393. CalaisTerminate(
  1394. void)
  1395. {
  1396. ResetEvent(AccessStartedEvent());
  1397. SetEvent(AccessStoppedEvent());
  1398. #ifdef DBG
  1399. TCHAR szTid[sizeof(DWORD) * 2 + 3];
  1400. _stprintf(szTid, TEXT("0x%p"), GetCurrentThreadId);
  1401. CalaisError(
  1402. __SUBROUTINE__,
  1403. DBGT("Fatal Unhandled Exception: TID=%1"),
  1404. szTid);
  1405. DebugBreak();
  1406. #endif
  1407. }