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.

688 lines
23 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: svrappdlg.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. // SvrAppDlg.cpp : implementation file
  11. //
  12. #include "stdafx.h"
  13. #include <winsvc.h>
  14. #include <dbt.h>
  15. #include "SvrApp.h"
  16. #include "SvrAppDlg.h"
  17. #include <CalServe.h>
  18. #ifdef _DEBUG
  19. #define new DEBUG_NEW
  20. #undef THIS_FILE
  21. static char THIS_FILE[] = __FILE__;
  22. #endif
  23. #define RSP_SIMPLE_SERVICE 0x00000001 // Registers the process as a
  24. // simple service process.
  25. #define RSP_UNREGISTER_SERVICE 0x00000000 // Unregisters the process as a
  26. // service process.
  27. typedef BOOL (WINAPI *LPREGISTER_SERIVCE)(DWORD, int);
  28. static BOOL g_fStarted = FALSE;
  29. static SERVICE_STATUS_HANDLE l_hService = NULL;
  30. static const TCHAR l_szEventSource[] = TEXT("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\SCardApp");
  31. static const TCHAR l_szServiceName[] = TEXT("SCardApp");
  32. static const GUID l_guidSmartcards
  33. = { // 50DD5230-BA8A-11D1-BF5D-0000F805F530
  34. 0x50DD5230,
  35. 0xBA8A,
  36. 0x11D1,
  37. { 0xBF, 0x5D, 0x00, 0x00, 0xF8, 0x05, 0xF5, 0x30 } };
  38. /////////////////////////////////////////////////////////////////////////////
  39. // CAboutDlg dialog used for App About
  40. class CAboutDlg : public CDialog
  41. {
  42. public:
  43. CAboutDlg();
  44. // Dialog Data
  45. //{{AFX_DATA(CAboutDlg)
  46. enum { IDD = IDD_ABOUTBOX };
  47. //}}AFX_DATA
  48. // ClassWizard generated virtual function overrides
  49. //{{AFX_VIRTUAL(CAboutDlg)
  50. protected:
  51. virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
  52. //}}AFX_VIRTUAL
  53. // Implementation
  54. protected:
  55. //{{AFX_MSG(CAboutDlg)
  56. //}}AFX_MSG
  57. DECLARE_MESSAGE_MAP()
  58. };
  59. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  60. {
  61. //{{AFX_DATA_INIT(CAboutDlg)
  62. //}}AFX_DATA_INIT
  63. }
  64. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  65. {
  66. CDialog::DoDataExchange(pDX);
  67. //{{AFX_DATA_MAP(CAboutDlg)
  68. //}}AFX_DATA_MAP
  69. }
  70. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  71. //{{AFX_MSG_MAP(CAboutDlg)
  72. // No message handlers
  73. //}}AFX_MSG_MAP
  74. END_MESSAGE_MAP()
  75. /////////////////////////////////////////////////////////////////////////////
  76. // CSvrAppDlg dialog
  77. CSvrAppDlg::CSvrAppDlg(CWnd* pParent /*=NULL*/)
  78. : CDialog(CSvrAppDlg::IDD, pParent)
  79. {
  80. //{{AFX_DATA_INIT(CSvrAppDlg)
  81. // NOTE: the ClassWizard will add member initialization here
  82. //}}AFX_DATA_INIT
  83. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  84. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  85. m_hIfDev = NULL;
  86. }
  87. void CSvrAppDlg::DoDataExchange(CDataExchange* pDX)
  88. {
  89. CDialog::DoDataExchange(pDX);
  90. //{{AFX_DATA_MAP(CSvrAppDlg)
  91. // NOTE: the ClassWizard will add DDX and DDV calls here
  92. //}}AFX_DATA_MAP
  93. }
  94. BEGIN_MESSAGE_MAP(CSvrAppDlg, CDialog)
  95. //{{AFX_MSG_MAP(CSvrAppDlg)
  96. ON_WM_SYSCOMMAND()
  97. ON_WM_PAINT()
  98. ON_WM_QUERYDRAGICON()
  99. ON_BN_CLICKED(IDC_START, OnStart)
  100. ON_BN_CLICKED(IDC_STOP, OnStop)
  101. //}}AFX_MSG_MAP
  102. ON_WM_DEVICECHANGE()
  103. END_MESSAGE_MAP()
  104. /////////////////////////////////////////////////////////////////////////////
  105. // CSvrAppDlg message handlers
  106. BOOL CSvrAppDlg::OnInitDialog()
  107. {
  108. CDialog::OnInitDialog();
  109. // Add "About..." menu item to system menu.
  110. // IDM_ABOUTBOX must be in the system command range.
  111. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  112. ASSERT(IDM_ABOUTBOX < 0xF000);
  113. CMenu* pSysMenu = GetSystemMenu(FALSE);
  114. CString strAboutMenu;
  115. strAboutMenu.LoadString(IDS_ABOUTBOX);
  116. if (!strAboutMenu.IsEmpty())
  117. {
  118. pSysMenu->AppendMenu(MF_SEPARATOR);
  119. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  120. }
  121. // Set the icon for this dialog. The framework does this automatically
  122. // when the application's main window is not a dialog
  123. SetIcon(m_hIcon, TRUE); // Set big icon
  124. SetIcon(m_hIcon, FALSE); // Set small icon
  125. // TODO: Add extra initialization here
  126. InitializeCriticalSection(&m_csMessageLock);
  127. return TRUE; // return TRUE unless you set the focus to a control
  128. }
  129. void CSvrAppDlg::OnSysCommand(UINT nID, LPARAM lParam)
  130. {
  131. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  132. {
  133. CAboutDlg dlgAbout;
  134. dlgAbout.DoModal();
  135. }
  136. else
  137. {
  138. CDialog::OnSysCommand(nID, lParam);
  139. }
  140. }
  141. // If you add a minimize button to your dialog, you will need the code below
  142. // to draw the icon. For MFC applications using the document/view model,
  143. // this is automatically done for you by the framework.
  144. void CSvrAppDlg::OnPaint()
  145. {
  146. if (IsIconic())
  147. {
  148. CPaintDC dc(this); // device context for painting
  149. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  150. // Center icon in client rectangle
  151. int cxIcon = GetSystemMetrics(SM_CXICON);
  152. int cyIcon = GetSystemMetrics(SM_CYICON);
  153. CRect rect;
  154. GetClientRect(&rect);
  155. int x = (rect.Width() - cxIcon + 1) / 2;
  156. int y = (rect.Height() - cyIcon + 1) / 2;
  157. // Draw the icon
  158. dc.DrawIcon(x, y, m_hIcon);
  159. }
  160. else
  161. {
  162. CDialog::OnPaint();
  163. }
  164. }
  165. // The system calls this to obtain the cursor to display while the user drags
  166. // the minimized window.
  167. HCURSOR CSvrAppDlg::OnQueryDragIcon()
  168. {
  169. return (HCURSOR) m_hIcon;
  170. }
  171. void CSvrAppDlg::OnStart()
  172. {
  173. ASSERT(!g_fStarted);
  174. try
  175. {
  176. //
  177. // Initialize Event Logging.
  178. //
  179. DWORD dwStatus;
  180. TCHAR szModulePath[MAX_PATH];
  181. CRegistry
  182. rgSCardSvr(
  183. HKEY_LOCAL_MACHINE,
  184. l_szEventSource,
  185. KEY_ALL_ACCESS,
  186. REG_OPTION_NON_VOLATILE);
  187. //
  188. // Add our source name as a subkey under the Application
  189. // key in the EventLog service portion of the registry.
  190. //
  191. dwStatus = GetModuleFileName(
  192. NULL,
  193. szModulePath,
  194. sizeof(szModulePath));
  195. if (0 == dwStatus)
  196. {
  197. dwStatus = GetLastError();
  198. CalaisWarning(
  199. DBGT("Smart Card Resource Manager cannot determine its module name: %1"),
  200. dwStatus);
  201. lstrcpy(
  202. szModulePath,
  203. #ifdef DBG
  204. TEXT("D:\\NT\\ISPU\\Calais\\bin\\objd\\i386\\SvrApp.exe"));
  205. #else
  206. TEXT("D:\\NT\\ISPU\\Calais\\bin\\obj\\i386\\SvrApp.exe"));
  207. #endif
  208. }
  209. rgSCardSvr.SetValue(
  210. TEXT("EventMessageFile"),
  211. szModulePath,
  212. REG_EXPAND_SZ);
  213. rgSCardSvr.SetValue(
  214. TEXT("TypesSupported"),
  215. (DWORD)(EVENTLOG_ERROR_TYPE
  216. | EVENTLOG_WARNING_TYPE
  217. | EVENTLOG_INFORMATION_TYPE));
  218. CalaisMessageInit(
  219. l_szServiceName,
  220. RegisterEventSource(NULL, l_szServiceName));
  221. }
  222. catch (...)
  223. {
  224. // No error logging!
  225. }
  226. AppInitializeDeviceRegistration(
  227. GetSafeHwnd(),
  228. DEVICE_NOTIFY_WINDOW_HANDLE);
  229. g_fStarted = (ERROR_SUCCESS == CalaisStart());
  230. if (!g_fStarted)
  231. AppTerminateDeviceRegistration();
  232. GetDlgItem(IDC_START)->EnableWindow(!g_fStarted);
  233. GetDlgItem(IDC_STOP)->EnableWindow(g_fStarted);
  234. }
  235. void CSvrAppDlg::OnStop()
  236. {
  237. ASSERT(g_fStarted);
  238. CalaisStop();
  239. AppTerminateDeviceRegistration();
  240. CalaisMessageClose();
  241. g_fStarted = FALSE;
  242. GetDlgItem(IDC_START)->EnableWindow(!g_fStarted);
  243. GetDlgItem(IDC_STOP)->EnableWindow(g_fStarted);
  244. }
  245. void CSvrAppDlg::OnOK()
  246. {
  247. if (g_fStarted)
  248. OnStop();
  249. DeleteCriticalSection(&m_csMessageLock);
  250. CDialog::OnOK();
  251. }
  252. afx_msg CSvrAppDlg::OnDeviceChange(UINT nEventType, DWORD_PTR EventData)
  253. {
  254. int nRetVal = CDialog::OnDeviceChange(nEventType, EventData);
  255. try
  256. {
  257. CCritSect csLock(&m_csMessageLock);
  258. DWORD dwSts;
  259. LPCTSTR szReader = NULL;
  260. DEV_BROADCAST_HDR *pDevHdr = (DEV_BROADCAST_HDR *)EventData;
  261. switch (nEventType)
  262. {
  263. //
  264. // A device has been inserted and is now available.
  265. case DBT_DEVICEARRIVAL:
  266. {
  267. DEV_BROADCAST_DEVICEINTERFACE *pDev
  268. = (DEV_BROADCAST_DEVICEINTERFACE *)EventData;
  269. try
  270. {
  271. if (DBT_DEVTYP_DEVICEINTERFACE == pDev->dbcc_devicetype)
  272. {
  273. CTextString tzReader;
  274. ASSERT(sizeof(DEV_BROADCAST_DEVICEINTERFACE) < pDev->dbcc_size);
  275. ASSERT(0 == memcmp(
  276. &pDev->dbcc_classguid,
  277. &l_guidSmartcards,
  278. sizeof(GUID)));
  279. ASSERT(0 != pDev->dbcc_name[0]);
  280. if (0 == pDev->dbcc_name[1])
  281. tzReader = (LPCWSTR)pDev->dbcc_name;
  282. else
  283. tzReader = (LPCTSTR)pDev->dbcc_name;
  284. szReader = tzReader;
  285. dwSts = CalaisAddReader(szReader);
  286. if (ERROR_SUCCESS != dwSts)
  287. throw dwSts;
  288. CalaisWarning(
  289. DBGT("New device '%1' added."),
  290. szReader);
  291. }
  292. else
  293. CalaisWarning(
  294. DBGT("Spurious device arrival event."));
  295. }
  296. catch (DWORD dwError)
  297. {
  298. CalaisError(514, dwError, szReader);
  299. }
  300. catch (...)
  301. {
  302. CalaisError(517, szReader);
  303. }
  304. }
  305. //
  306. // Permission to remove a device is requested. Any application can deny
  307. // this request and cancel the removal.
  308. case DBT_DEVICEQUERYREMOVE:
  309. {
  310. DEV_BROADCAST_HANDLE *pDev = (DEV_BROADCAST_HANDLE *)EventData;
  311. try
  312. {
  313. if (DBT_DEVTYP_HANDLE == pDev->dbch_devicetype)
  314. {
  315. ASSERT(FIELD_OFFSET(DEV_BROADCAST_HANDLE, dbch_eventguid)
  316. <= pDev->dbch_size);
  317. ASSERT(NULL != pDev->dbch_handle);
  318. ASSERT(NULL != pDev->dbch_hdevnotify);
  319. if (NULL != pDev->dbch_handle)
  320. {
  321. if (!CalaisQueryReader(pDev->dbch_handle))
  322. {
  323. CalaisError(
  324. 520,
  325. TEXT("DBT_DEVICEQUERYREMOVE/dbch_handle"));
  326. nRetVal = BROADCAST_QUERY_DENY;
  327. }
  328. else
  329. {
  330. szReader = CalaisDisableReader(
  331. (LPVOID)pDev->dbch_handle);
  332. CalaisWarning(
  333. DBGT("Device '%1' removal pending."),
  334. szReader);
  335. }
  336. }
  337. else
  338. {
  339. CalaisError(
  340. 519,
  341. TEXT("DBT_DEVICEQUERYREMOVE/dbch_handle"));
  342. nRetVal = BROADCAST_QUERY_DENY;
  343. }
  344. }
  345. else
  346. {
  347. CalaisWarning(
  348. DBGT("Spurious device removal query event."));
  349. nRetVal = TRUE;
  350. }
  351. }
  352. catch (DWORD dwError)
  353. {
  354. CalaisWarning(
  355. DBGT("Error querying device busy state on reader %2: %1"),
  356. dwError,
  357. szReader);
  358. nRetVal = BROADCAST_QUERY_DENY;
  359. }
  360. catch (...)
  361. {
  362. CalaisWarning(
  363. DBGT("Exception querying device busy state on reader %1"),
  364. szReader);
  365. CalaisError(
  366. 518,
  367. TEXT("DBT_DEVICEQUERYREMOVE"));
  368. nRetVal = BROADCAST_QUERY_DENY;
  369. }
  370. break;
  371. }
  372. //
  373. // Request to remove a device has been canceled.
  374. case DBT_DEVICEQUERYREMOVEFAILED:
  375. {
  376. CBuffer bfDevice;
  377. DEV_BROADCAST_HANDLE *pDev = (DEV_BROADCAST_HANDLE *)EventData;
  378. try
  379. {
  380. if (DBT_DEVTYP_HANDLE == pDev->dbch_devicetype)
  381. {
  382. ASSERT(FIELD_OFFSET(DEV_BROADCAST_HANDLE, dbch_eventguid)
  383. <= pDev->dbch_size);
  384. ASSERT(NULL != pDev->dbch_handle);
  385. ASSERT(NULL != pDev->dbch_hdevnotify);
  386. if (NULL != pDev->dbch_handle)
  387. {
  388. szReader = CalaisConfirmClosingReader(pDev->dbch_handle);
  389. if (NULL != szReader)
  390. {
  391. bfDevice.Set(
  392. (LPBYTE)szReader,
  393. (lstrlen(szReader) + 1) * sizeof(TCHAR));
  394. szReader = (LPCTSTR)bfDevice.Access();
  395. CalaisWarning(
  396. DBGT("Smart Card Resource Manager asked to cancel release of reader %1"),
  397. szReader);
  398. if (NULL != pDev->dbch_hdevnotify)
  399. {
  400. CalaisRemoveReader((LPVOID)pDev->dbch_hdevnotify);
  401. if (NULL != szReader)
  402. dwSts = CalaisAddReader(szReader);
  403. }
  404. }
  405. else
  406. CalaisWarning(
  407. DBGT("Smart Card Resource Manager asked to cancel release on unreleased reader"));
  408. }
  409. else
  410. CalaisError(
  411. 519,
  412. TEXT("DBT_DEVICEQUERYREMOVEFAILED/dbch_handle"));
  413. }
  414. else
  415. {
  416. CalaisWarning(
  417. DBGT("Spurious device removal query failure event."));
  418. }
  419. }
  420. catch (DWORD dwError)
  421. {
  422. CalaisWarning(
  423. DBGT("Error cancelling removal on reader %2: %1"),
  424. dwError,
  425. szReader);
  426. }
  427. catch (...)
  428. {
  429. CalaisWarning(
  430. DBGT("Exception cancelling removal on reader %1"),
  431. szReader);
  432. CalaisError(
  433. 518,
  434. TEXT("DBT_DEVICEQUERYREMOVEFAILED"));
  435. }
  436. break;
  437. }
  438. //
  439. // Device is about to be removed. Cannot be denied.
  440. case DBT_DEVICEREMOVEPENDING:
  441. {
  442. DEV_BROADCAST_HANDLE *pDev = (DEV_BROADCAST_HANDLE *)EventData;
  443. try
  444. {
  445. if (DBT_DEVTYP_HANDLE == pDev->dbch_devicetype)
  446. {
  447. ASSERT(FIELD_OFFSET(DEV_BROADCAST_HANDLE, dbch_eventguid)
  448. <= pDev->dbch_size);
  449. ASSERT(NULL != pDev->dbch_handle);
  450. ASSERT(NULL != pDev->dbch_hdevnotify);
  451. if (NULL != pDev->dbch_handle)
  452. {
  453. szReader = CalaisDisableReader(pDev->dbch_handle);
  454. CalaisWarning(
  455. DBGT("Device '%1' being removed."),
  456. szReader);
  457. }
  458. else
  459. CalaisError(
  460. 519,
  461. TEXT("DBT_DEVICEREMOVEPENDING/dbch_handle"));
  462. }
  463. else
  464. {
  465. CalaisWarning(
  466. DBGT("Spurious device removal pending event."));
  467. }
  468. }
  469. catch (DWORD dwError)
  470. {
  471. CalaisWarning(
  472. DBGT("Error removing reader %2: %1"),
  473. dwError,
  474. szReader);
  475. }
  476. catch (...)
  477. {
  478. CalaisWarning(
  479. DBGT("Exception removing reader %1"),
  480. szReader);
  481. CalaisError(
  482. 518,
  483. TEXT("DBT_DEVICEREMOVEPENDING"));
  484. }
  485. break;
  486. }
  487. //
  488. // Device has been removed.
  489. case DBT_DEVICEREMOVECOMPLETE:
  490. {
  491. try
  492. {
  493. switch (pDevHdr->dbch_devicetype)
  494. {
  495. case DBT_DEVTYP_HANDLE:
  496. {
  497. DEV_BROADCAST_HANDLE *pDev =
  498. (DEV_BROADCAST_HANDLE *)EventData;
  499. try
  500. {
  501. ASSERT(FIELD_OFFSET(DEV_BROADCAST_HANDLE, dbch_eventguid) <= pDev->dbch_size);
  502. ASSERT(DBT_DEVTYP_HANDLE == pDev->dbch_devicetype);
  503. ASSERT(NULL != pDev->dbch_handle);
  504. ASSERT(NULL != pDev->dbch_hdevnotify);
  505. if ((NULL != pDev->dbch_handle)
  506. && (NULL != pDev->dbch_hdevnotify))
  507. {
  508. szReader = CalaisDisableReader(
  509. pDev->dbch_handle);
  510. CalaisRemoveReader(
  511. (LPVOID)pDev->dbch_hdevnotify);
  512. CalaisWarning(
  513. DBGT("Device '%1' removed."),
  514. szReader);
  515. }
  516. else
  517. {
  518. if (NULL == pDev->dbch_handle)
  519. CalaisError(
  520. 519,
  521. TEXT("DBT_DEVICEREMOVECOMPLETE/DBT_DEVTYP_HANDLE/dbch_handle"));
  522. if (NULL == pDev->dbch_hdevnotify)
  523. CalaisError(
  524. 519,
  525. TEXT("DBT_DEVICEREMOVECOMPLETE/DBT_DEVTYP_HANDLE/dbch_hdevnotify"));
  526. }
  527. }
  528. catch (DWORD dwError)
  529. {
  530. CalaisWarning(
  531. DBGT("Error completing removal of reader %2: %1"),
  532. dwError,
  533. szReader);
  534. }
  535. catch (...)
  536. {
  537. CalaisWarning(
  538. DBGT("Exception completing removal of reader %1"),
  539. szReader);
  540. CalaisError(
  541. 518,
  542. TEXT("DBT_DEVICEREMOVECOMPLETE/DBT_DEVTYP_HANDLE"));
  543. }
  544. break;
  545. }
  546. case DBT_DEVTYP_DEVICEINTERFACE:
  547. {
  548. DEV_BROADCAST_DEVICEINTERFACE *pDev
  549. = (DEV_BROADCAST_DEVICEINTERFACE *)EventData;
  550. try
  551. {
  552. CTextString tzReader;
  553. ASSERT(sizeof(DEV_BROADCAST_DEVICEINTERFACE) < pDev->dbcc_size);
  554. ASSERT(DBT_DEVTYP_DEVICEINTERFACE == pDev->dbcc_devicetype);
  555. ASSERT(0 == memcmp(
  556. &pDev->dbcc_classguid,
  557. &l_guidSmartcards,
  558. sizeof(GUID)));
  559. ASSERT(0 != pDev->dbcc_name[0]);
  560. if (0 == pDev->dbcc_name[1])
  561. tzReader = (LPCWSTR)pDev->dbcc_name;
  562. else
  563. tzReader = (LPCTSTR)pDev->dbcc_name;
  564. szReader = tzReader;
  565. dwSts = CalaisRemoveDevice(szReader);
  566. if (ERROR_SUCCESS == dwSts)
  567. CalaisWarning(
  568. DBGT("Device '%1' Removed."),
  569. szReader);
  570. else
  571. CalaisWarning(
  572. DBGT("Error removing device '%2': %1"),
  573. dwSts,
  574. szReader);
  575. }
  576. catch (DWORD dwError)
  577. {
  578. CalaisWarning(
  579. DBGT("Error completing removal of reader %2: %1"),
  580. dwError,
  581. szReader);
  582. }
  583. catch (...)
  584. {
  585. CalaisWarning(
  586. DBGT("Exception completing removal of reader %1"),
  587. szReader);
  588. CalaisError(
  589. 518,
  590. TEXT("DBT_DEVICEREMOVECOMPLETE/DBT_DEVTYP_DEVICEINTERFACE"));
  591. }
  592. break;
  593. }
  594. default:
  595. CalaisWarning(
  596. DBGT("Unrecognized PnP Device Removal Type"));
  597. break;
  598. }
  599. }
  600. catch (...)
  601. {
  602. CalaisError(
  603. 518,
  604. TEXT("DBT_DEVICEREMOVECOMPLETE"));
  605. }
  606. break;
  607. }
  608. default:
  609. CalaisWarning(
  610. DBGT("Unrecognized PnP Event"));
  611. break;
  612. }
  613. }
  614. catch (DWORD dwError)
  615. {
  616. CalaisWarning(
  617. DBGT("Smart Card Resource Manager recieved error on device action: %1"),
  618. dwError);
  619. }
  620. catch (...)
  621. {
  622. CalaisWarning(
  623. DBGT("Smart Card Resource Manager recieved exception on device action"));
  624. }
  625. return nRetVal;
  626. }