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.

4504 lines
155 KiB

  1. /*****************************************************************************
  2. @doc INT EXT
  3. ******************************************************************************
  4. * $ProjectName: $
  5. * $ProjectRevision: $
  6. *-----------------------------------------------------------------------------
  7. * $Source: z:/pr/cmeu0/sw/sccmusbm.ms/rcs/scusbwdm.c $
  8. * $Revision: 1.9 $
  9. *-----------------------------------------------------------------------------
  10. * $Author: WFrischauf $
  11. *-----------------------------------------------------------------------------
  12. * History: see EOF
  13. *-----------------------------------------------------------------------------
  14. *
  15. * Copyright 2000 OMNIKEY AG
  16. ******************************************************************************/
  17. #include "wdm.h"
  18. #include "stdarg.h"
  19. #include "stdio.h"
  20. #include "usbdi.h"
  21. #include "usbdlib.h"
  22. #include "sccmusbm.h"
  23. BOOLEAN DeviceSlot[MAXIMUM_USB_READERS];
  24. STRING OemName[MAXIMUM_OEM_NAMES];
  25. CHAR OemNameBuffer[MAXIMUM_OEM_NAMES][64];
  26. BOOLEAN OemDeviceSlot[MAXIMUM_OEM_NAMES][MAXIMUM_USB_READERS];
  27. /*****************************************************************************
  28. Routine Description:
  29. Arguments:
  30. Return Value:
  31. *****************************************************************************/
  32. PURB CMUSB_BuildAsyncRequest(
  33. IN PDEVICE_OBJECT DeviceObject,
  34. IN PIRP Irp,
  35. IN PUSBD_PIPE_INFORMATION PipeHandle
  36. )
  37. {
  38. ULONG siz;
  39. ULONG length;
  40. PURB urb = NULL;
  41. PDEVICE_EXTENSION DeviceExtension;
  42. PUSBD_INTERFACE_INFORMATION interface;
  43. PUSBD_PIPE_INFORMATION pipeHandle = NULL;
  44. PSMARTCARD_EXTENSION SmartcardExtension;
  45. siz = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);
  46. urb = ExAllocatePool(NonPagedPool, siz);
  47. DeviceExtension = DeviceObject->DeviceExtension;
  48. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  49. if (urb != NULL)
  50. {
  51. RtlZeroMemory(urb, siz);
  52. urb->UrbBulkOrInterruptTransfer.Hdr.Length = (USHORT) siz;
  53. urb->UrbBulkOrInterruptTransfer.Hdr.Function =
  54. URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;
  55. urb->UrbBulkOrInterruptTransfer.PipeHandle =
  56. PipeHandle->PipeHandle;
  57. urb->UrbBulkOrInterruptTransfer.TransferFlags =
  58. USBD_TRANSFER_DIRECTION_IN;
  59. // short packet is not treated as an error.
  60. urb->UrbBulkOrInterruptTransfer.TransferFlags |=
  61. USBD_SHORT_TRANSFER_OK;
  62. //
  63. // not using linked urb's
  64. //
  65. urb->UrbBulkOrInterruptTransfer.UrbLink = NULL;
  66. urb->UrbBulkOrInterruptTransfer.TransferBufferMDL = NULL;
  67. urb->UrbBulkOrInterruptTransfer.TransferBufferLength =
  68. SmartcardExtension->SmartcardReply.BufferLength;
  69. urb->UrbBulkOrInterruptTransfer.TransferBuffer =
  70. SmartcardExtension->SmartcardReply.Buffer;
  71. }
  72. return urb;
  73. }
  74. /*****************************************************************************
  75. Routine Description:
  76. Arguments:
  77. Return Value:
  78. *****************************************************************************/
  79. NTSTATUS CMUSB_AsyncReadComplete(
  80. IN PDEVICE_OBJECT DeviceObject,
  81. IN PIRP Irp,
  82. IN PVOID Context
  83. )
  84. {
  85. PURB urb;
  86. PCMUSB_RW_CONTEXT context = Context;
  87. PIO_STACK_LOCATION irpStack;
  88. PDEVICE_OBJECT deviceObject;
  89. PDEVICE_EXTENSION DeviceExtension;
  90. PSMARTCARD_EXTENSION SmartcardExtension;
  91. urb = context->Urb;
  92. deviceObject = context->DeviceObject;
  93. DeviceExtension = deviceObject->DeviceExtension;
  94. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  95. //
  96. // set the length based on the TransferBufferLength
  97. // value in the URB
  98. //
  99. if (Irp->IoStatus.Status == STATUS_SUCCESS)
  100. {
  101. SmartcardExtension->SmartcardReply.BufferLength = urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
  102. SmartcardExtension->ReaderExtension->fP1Stalled = FALSE;
  103. }
  104. else
  105. {
  106. SmartcardDebug(DEBUG_DRIVER,
  107. ("%s!Irp->IoStatus.Status = %lx\n",DRIVER_NAME,Irp->IoStatus.Status));
  108. SmartcardExtension->SmartcardReply.BufferLength = 0;
  109. SmartcardExtension->ReaderExtension->fP1Stalled = TRUE;
  110. }
  111. SmartcardExtension->SmartcardReply.BufferLength = urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
  112. CMUSB_DecrementIoCount(deviceObject);
  113. ExFreePool(context);
  114. ExFreePool(urb);
  115. IoFreeIrp(Irp);
  116. /*
  117. SmartcardDebug(DEBUG_DRIVER,
  118. ("%s!AsyncReadWriteComplete <%ld>\n",
  119. DRIVER_NAME,SmartcardExtension->SmartcardReply.BufferLength)
  120. );
  121. */
  122. KeSetEvent(&DeviceExtension->ReadP1Completed,0,FALSE);
  123. return STATUS_MORE_PROCESSING_REQUIRED;
  124. }
  125. /*****************************************************************************
  126. Routine Description:
  127. Arguments:
  128. Return Value:
  129. NT NTStatus
  130. *****************************************************************************/
  131. #define TIMEOUT_P1_RESPONSE 100
  132. NTSTATUS CMUSB_ReadP1(
  133. IN PDEVICE_OBJECT DeviceObject
  134. )
  135. {
  136. NTSTATUS NTStatus;
  137. NTSTATUS DebugStatus;
  138. PIO_STACK_LOCATION nextStack;
  139. PURB urb;
  140. PCMUSB_RW_CONTEXT context = NULL;
  141. PDEVICE_EXTENSION DeviceExtension;
  142. PSMARTCARD_EXTENSION SmartcardExtension;
  143. PUSBD_INTERFACE_INFORMATION interface;
  144. PUSBD_PIPE_INFORMATION pipeHandle = NULL;
  145. CHAR cStackSize;
  146. PIRP IrpToUSB = NULL;
  147. ULONG ulBytesToRead;
  148. ULONG i;
  149. LARGE_INTEGER liTimeoutP1;
  150. LARGE_INTEGER liTimeoutP1Response;
  151. BOOLEAN fStateTimer;
  152. UCHAR bTmp;
  153. LONG lNullPackets;
  154. BOOLEAN fCancelTimer = FALSE;
  155. /*
  156. SmartcardDebug(DEBUG_TRACE,
  157. ("%s!ReadP1: Enter\n",DRIVER_NAME)
  158. );
  159. */
  160. DeviceExtension = DeviceObject->DeviceExtension;
  161. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  162. interface = DeviceExtension->UsbInterface;
  163. pipeHandle = &interface->Pipes[0];
  164. if (pipeHandle == NULL)
  165. {
  166. NTStatus = STATUS_INVALID_HANDLE;
  167. goto ExitCMUSB_ReadP1;
  168. }
  169. liTimeoutP1 = RtlConvertLongToLargeInteger(SmartcardExtension->ReaderExtension->ulTimeoutP1 * -10000);
  170. KeSetTimer(&SmartcardExtension->ReaderExtension->P1Timer,
  171. liTimeoutP1,
  172. NULL);
  173. fCancelTimer = TRUE;
  174. // we will always read a whole packet (== 8 bytes)
  175. ulBytesToRead = 8;
  176. cStackSize = (CCHAR)(DeviceExtension->TopOfStackDeviceObject->StackSize+1);
  177. lNullPackets = -1;
  178. do
  179. {
  180. fStateTimer = KeReadStateTimer(&SmartcardExtension->ReaderExtension->P1Timer);
  181. if (fStateTimer == TRUE)
  182. {
  183. fCancelTimer = FALSE;
  184. NTStatus = STATUS_IO_TIMEOUT;
  185. SmartcardExtension->SmartcardReply.BufferLength = 0L;
  186. SmartcardDebug(DEBUG_PROTOCOL,
  187. ("%s!Timeout (%ld)while reading from P1\n",
  188. DRIVER_NAME,SmartcardExtension->ReaderExtension->ulTimeoutP1)
  189. );
  190. break;
  191. }
  192. SmartcardExtension->SmartcardReply.BufferLength = ulBytesToRead;
  193. IrpToUSB = IoAllocateIrp(cStackSize,FALSE);
  194. if (IrpToUSB==NULL)
  195. {
  196. SmartcardExtension->SmartcardReply.BufferLength = 0L;
  197. NTStatus = STATUS_INSUFFICIENT_RESOURCES;
  198. goto ExitCMUSB_ReadP1;
  199. }
  200. urb = CMUSB_BuildAsyncRequest(DeviceObject,
  201. IrpToUSB,
  202. pipeHandle
  203. );
  204. if (urb != NULL)
  205. {
  206. context = ExAllocatePool(NonPagedPool, sizeof(CMUSB_RW_CONTEXT));
  207. }
  208. if (urb != NULL && context != NULL)
  209. {
  210. context->Urb = urb;
  211. context->DeviceObject = DeviceObject;
  212. context->Irp = IrpToUSB;
  213. nextStack = IoGetNextIrpStackLocation(IrpToUSB);
  214. ASSERT(nextStack != NULL);
  215. ASSERT(DeviceObject->StackSize>1);
  216. nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
  217. nextStack->Parameters.Others.Argument1 = urb;
  218. nextStack->Parameters.DeviceIoControl.IoControlCode =
  219. IOCTL_INTERNAL_USB_SUBMIT_URB;
  220. IoSetCompletionRoutine(IrpToUSB,
  221. CMUSB_AsyncReadComplete,
  222. context,
  223. TRUE,
  224. TRUE,
  225. TRUE);
  226. ASSERT(DeviceExtension->TopOfStackDeviceObject);
  227. ASSERT(IrpToUSB);
  228. KeClearEvent(&DeviceExtension->ReadP1Completed);
  229. CMUSB_IncrementIoCount(DeviceObject);
  230. NTStatus = IoCallDriver(DeviceExtension->TopOfStackDeviceObject,
  231. IrpToUSB);
  232. liTimeoutP1Response = RtlConvertLongToLargeInteger(TIMEOUT_P1_RESPONSE * -10000);
  233. NTStatus = KeWaitForSingleObject(&DeviceExtension->ReadP1Completed,
  234. Executive,
  235. KernelMode,
  236. FALSE,
  237. &liTimeoutP1Response);
  238. if (NTStatus == STATUS_TIMEOUT)
  239. {
  240. // probably the device has been removed
  241. // there must be at least a null packet received during liTimeoutReponse
  242. SmartcardExtension->SmartcardReply.BufferLength = 0L;
  243. break;
  244. }
  245. // -----------------------------
  246. // check if P1 has been stalled
  247. // -----------------------------
  248. if (SmartcardExtension->ReaderExtension->fP1Stalled == TRUE)
  249. {
  250. break;
  251. }
  252. }
  253. else
  254. {
  255. if (urb != NULL) {
  256. ExFreePool(urb);
  257. }
  258. if (IrpToUSB != NULL) {
  259. IoFreeIrp(IrpToUSB);
  260. }
  261. SmartcardExtension->SmartcardReply.BufferLength = 0L;
  262. NTStatus = STATUS_INSUFFICIENT_RESOURCES;
  263. break;
  264. }
  265. lNullPackets++;
  266. } while (SmartcardExtension->SmartcardReply.BufferLength == 0L);
  267. // -----------------------------
  268. // check if P1 has been stalled
  269. // -----------------------------
  270. if (SmartcardExtension->ReaderExtension->fP1Stalled == TRUE)
  271. {
  272. SmartcardDebug(DEBUG_DRIVER,
  273. ("%s!P1 stalled \n",DRIVER_NAME));
  274. NTStatus = STATUS_DEVICE_DATA_ERROR;
  275. // wait to be sure that we have a stable card state
  276. CMUSB_Wait (50);
  277. // P1 has been stalled ==> we must reset the pipe and send a NTStatus to enable it again
  278. DebugStatus = CMUSB_ResetPipe(DeviceObject,pipeHandle);
  279. }
  280. else
  281. {
  282. // if no bytes have been received , NTStatus has already been set
  283. // to STATUS_TIMEOUT
  284. if (SmartcardExtension->SmartcardReply.BufferLength > 0 )
  285. {
  286. NTStatus = STATUS_SUCCESS;
  287. #if DBG
  288. SmartcardDebug(DEBUG_PROTOCOL,("%s!<==[P1] <%ld> ",DRIVER_NAME,lNullPackets));
  289. for (i=0;i< SmartcardExtension->SmartcardReply.BufferLength;i++)
  290. {
  291. bTmp = SmartcardExtension->SmartcardReply.Buffer[i];
  292. if (SmartcardExtension->ReaderExtension->fInverseAtr &&
  293. SmartcardExtension->ReaderExtension->ulTimeoutP1 != DEFAULT_TIMEOUT_P1)
  294. {
  295. //CMUSB_InverseBuffer(&bTmp,1);
  296. SmartcardDebug(DEBUG_PROTOCOL,("%x ",bTmp));
  297. }
  298. else
  299. {
  300. SmartcardDebug(DEBUG_PROTOCOL,("%x ",bTmp));
  301. }
  302. }
  303. SmartcardDebug(DEBUG_PROTOCOL,("(%ld)\n",SmartcardExtension->SmartcardReply.BufferLength));
  304. #endif
  305. }
  306. }
  307. ExitCMUSB_ReadP1:
  308. if (fCancelTimer == TRUE)
  309. {
  310. // cancel timer
  311. // TRUE if the timer is in the queue
  312. // FALSE if the timer is not in queue
  313. KeCancelTimer(&SmartcardExtension->ReaderExtension->P1Timer);
  314. }
  315. /*
  316. SmartcardDebug(DEBUG_TRACE,
  317. ("%s!ReadP1: Exit %lx\n",DRIVER_NAME,NTStatus));
  318. */
  319. return NTStatus;
  320. }
  321. /*****************************************************************************
  322. Routine Description:
  323. Arguments:
  324. Return Value:
  325. NT NTStatus
  326. *****************************************************************************/
  327. NTSTATUS CMUSB_ReadP1_T0(
  328. IN PDEVICE_OBJECT DeviceObject
  329. )
  330. {
  331. NTSTATUS NTStatus;
  332. PIO_STACK_LOCATION nextStack;
  333. PURB urb;
  334. PCMUSB_RW_CONTEXT context = NULL;
  335. PDEVICE_EXTENSION DeviceExtension;
  336. PSMARTCARD_EXTENSION SmartcardExtension;
  337. PUSBD_INTERFACE_INFORMATION interface;
  338. PUSBD_PIPE_INFORMATION pipeHandle = NULL;
  339. CHAR cStackSize;
  340. PIRP IrpToUSB = NULL;
  341. ULONG ulBytesToRead;
  342. /*
  343. SmartcardDebug(DEBUG_TRACE,
  344. ("%s!ReadP1_T0: Enter\n",DRIVER_NAME));
  345. */
  346. DeviceExtension = DeviceObject->DeviceExtension;
  347. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  348. interface = DeviceExtension->UsbInterface;
  349. pipeHandle = &interface->Pipes[0];
  350. if (pipeHandle == NULL)
  351. {
  352. NTStatus = STATUS_INVALID_HANDLE;
  353. goto ExitCMUSB_ReadP1;
  354. }
  355. ulBytesToRead = SmartcardExtension->SmartcardReply.BufferLength;
  356. cStackSize = (CCHAR)(DeviceExtension->TopOfStackDeviceObject->StackSize+1);
  357. IrpToUSB = IoAllocateIrp(cStackSize,FALSE);
  358. if (IrpToUSB==NULL)
  359. {
  360. SmartcardExtension->SmartcardReply.BufferLength = 0L;
  361. NTStatus = STATUS_INSUFFICIENT_RESOURCES;
  362. goto ExitCMUSB_ReadP1;
  363. }
  364. urb = CMUSB_BuildAsyncRequest(DeviceObject,IrpToUSB,pipeHandle);
  365. if (urb != NULL)
  366. {
  367. context = ExAllocatePool(NonPagedPool, sizeof(CMUSB_RW_CONTEXT));
  368. }
  369. if (urb != NULL && context != NULL)
  370. {
  371. context->Urb = urb;
  372. context->DeviceObject = DeviceObject;
  373. context->Irp = IrpToUSB;
  374. nextStack = IoGetNextIrpStackLocation(IrpToUSB);
  375. ASSERT(nextStack != NULL);
  376. ASSERT(DeviceObject->StackSize>1);
  377. nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
  378. nextStack->Parameters.Others.Argument1 = urb;
  379. nextStack->Parameters.DeviceIoControl.IoControlCode =
  380. IOCTL_INTERNAL_USB_SUBMIT_URB;
  381. IoSetCompletionRoutine(IrpToUSB,
  382. CMUSB_AsyncReadComplete,
  383. context,
  384. TRUE,
  385. TRUE,
  386. TRUE);
  387. ASSERT(DeviceExtension->TopOfStackDeviceObject);
  388. ASSERT(IrpToUSB);
  389. KeClearEvent(&DeviceExtension->ReadP1Completed);
  390. CMUSB_IncrementIoCount(DeviceObject);
  391. NTStatus = IoCallDriver(DeviceExtension->TopOfStackDeviceObject,
  392. IrpToUSB);
  393. if (NTStatus == STATUS_PENDING)
  394. NTStatus = STATUS_SUCCESS;
  395. }
  396. else
  397. {
  398. if (urb != NULL) {
  399. ExFreePool(urb);
  400. }
  401. if (IrpToUSB != NULL) {
  402. IoFreeIrp(IrpToUSB);
  403. }
  404. SmartcardExtension->SmartcardReply.BufferLength = 0L;
  405. NTStatus = STATUS_INSUFFICIENT_RESOURCES;
  406. }
  407. ExitCMUSB_ReadP1:
  408. /*
  409. SmartcardDebug(DEBUG_TRACE,
  410. ("%s!ReadP1_T0: Exit %lx\n",DRIVER_NAME,NTStatus));
  411. */
  412. return NTStatus;
  413. }
  414. /*****************************************************************************
  415. Routine Description:
  416. Dispatch table routine for IRP_MJ_PNP.
  417. Process the Plug and Play IRPs sent to this device.
  418. Arguments:
  419. DeviceObject - pointer to our FDO (Functional Device Object)
  420. Irp - pointer to an I/O Request Packet
  421. Return Value:
  422. NT NTStatus code
  423. *****************************************************************************/
  424. NTSTATUS CMUSB_ProcessPnPIrp(
  425. IN PDEVICE_OBJECT DeviceObject,
  426. IN PIRP Irp
  427. )
  428. {
  429. PIO_STACK_LOCATION irpStack;
  430. PDEVICE_EXTENSION DeviceExtension;
  431. NTSTATUS NTStatus = STATUS_SUCCESS;
  432. NTSTATUS waitStatus;
  433. NTSTATUS DebugStatus;
  434. PDEVICE_OBJECT stackDeviceObject;
  435. KEVENT startDeviceEvent;
  436. PDEVICE_CAPABILITIES DeviceCapabilities;
  437. KEVENT event;
  438. SmartcardDebug(DEBUG_TRACE,
  439. ("%s!ProcessPnPIrp: Enter\n",DRIVER_NAME));
  440. //
  441. // Get a pointer to the device extension
  442. //
  443. DeviceExtension = DeviceObject->DeviceExtension;
  444. stackDeviceObject = DeviceExtension->TopOfStackDeviceObject;
  445. //
  446. // Acquire remove lock,
  447. // so that device can not be removed while
  448. // this function is executed
  449. //
  450. NTStatus = SmartcardAcquireRemoveLock(&DeviceExtension->SmartcardExtension);
  451. ASSERT(NTStatus == STATUS_SUCCESS);
  452. if (NTStatus != STATUS_SUCCESS)
  453. {
  454. Irp->IoStatus.Information = 0;
  455. Irp->IoStatus.Status = NTStatus;
  456. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  457. return NTStatus;
  458. }
  459. //
  460. // Get a pointer to the current location in the Irp. This is where
  461. // the function codes and parameters are located.
  462. //
  463. irpStack = IoGetCurrentIrpStackLocation (Irp);
  464. // inc the FDO device extension's pending IO count for this Irp
  465. CMUSB_IncrementIoCount(DeviceObject);
  466. CMUSB_ASSERT( IRP_MJ_PNP == irpStack->MajorFunction );
  467. switch (irpStack->MinorFunction)
  468. {
  469. // ---------------------
  470. // IRP_MN_START_DEVICE
  471. // ---------------------
  472. case IRP_MN_START_DEVICE:
  473. // The PnP Manager sends this IRP after it has assigned resources,
  474. // if any, to the device. The device may have been recently enumerated
  475. // and is being started for the first time, or the device may be
  476. // restarting after being stopped for resource reconfiguration.
  477. SmartcardDebug(DEBUG_DRIVER,
  478. ("%s!IRP_MN_START_DEVICE received\n",DRIVER_NAME));
  479. // Initialize an event we can wait on for the PDO to be done with this irp
  480. KeInitializeEvent(&startDeviceEvent, NotificationEvent, FALSE);
  481. IoCopyCurrentIrpStackLocationToNext(Irp);
  482. // Set a completion routine so it can signal our event when
  483. // the PDO is done with the Irp
  484. IoSetCompletionRoutine(Irp,
  485. CMUSB_IrpCompletionRoutine,
  486. &startDeviceEvent, // pass the event to the completion routine as the Context
  487. TRUE, // invoke on success
  488. TRUE, // invoke on error
  489. TRUE); // invoke on cancellation
  490. // let the PDO process the IRP
  491. NTStatus = IoCallDriver(stackDeviceObject,Irp);
  492. // if PDO is not done yet, wait for the event to be set in our completion routine
  493. if (NTStatus == STATUS_PENDING)
  494. {
  495. // wait for irp to complete
  496. waitStatus = KeWaitForSingleObject(&startDeviceEvent,
  497. Suspended,
  498. KernelMode,
  499. FALSE,
  500. NULL);
  501. NTStatus = Irp->IoStatus.Status;
  502. }
  503. if (NT_SUCCESS(NTStatus))
  504. {
  505. // Now we're ready to do our own startup processing.
  506. // USB client drivers such as us set up URBs (USB Request Packets) to send requests
  507. // to the host controller driver (HCD). The URB structure defines a format for all
  508. // possible commands that can be sent to a USB device.
  509. // Here, we request the device descriptor and store it,
  510. // and configure the device.
  511. NTStatus = CMUSB_StartDevice(DeviceObject);
  512. Irp->IoStatus.Status = NTStatus;
  513. }
  514. IoCompleteRequest (Irp,IO_NO_INCREMENT);
  515. CMUSB_DecrementIoCount(DeviceObject);
  516. // Release the remove lock
  517. SmartcardReleaseRemoveLock(&DeviceExtension->SmartcardExtension);
  518. return NTStatus; // end, case IRP_MN_START_DEVICE
  519. // ------------------------
  520. // IRP_MN_QUERY_STOP_DEVICE
  521. // ------------------------
  522. case IRP_MN_QUERY_STOP_DEVICE:
  523. // The IRP_MN_QUERY_STOP_DEVICE/IRP_MN_STOP_DEVICE sequence only occurs
  524. // during "polite" shutdowns, such as the user explicitily requesting the
  525. // service be stopped in, or requesting unplug from the Pnp tray icon.
  526. // This sequence is NOT received during "impolite" shutdowns,
  527. // such as someone suddenly yanking the USB cord or otherwise
  528. // unexpectedly disabling/resetting the device.
  529. // If a driver sets STATUS_SUCCESS for this IRP,
  530. // the driver must not start any operations on the device that
  531. // would prevent that driver from successfully completing an IRP_MN_STOP_DEVICE
  532. // for the device.
  533. // For mass storage devices such as disk drives, while the device is in the
  534. // stop-pending state,the driver holds IRPs that require access to the device,
  535. // but for most USB devices, there is no 'persistent storage', so we will just
  536. // refuse any more IO until restarted or the stop is cancelled
  537. // If a driver in the device stack determines that the device cannot be
  538. // stopped for resource reconfiguration, the driver is not required to pass
  539. // the IRP down the device stack. If a query-stop IRP fails,
  540. // the PnP Manager sends an IRP_MN_CANCEL_STOP_DEVICE to the device stack,
  541. // notifying the drivers for the device that the query has been cancelled
  542. // and that the device will not be stopped.
  543. SmartcardDebug(DEBUG_DRIVER,
  544. ("%s!IRP_MN_QUERY_STOP_DEVICE\n",DRIVER_NAME));
  545. // It is possible to receive this irp when the device has not been started
  546. // ( as on a boot device )
  547. if (DeviceExtension->DeviceStarted == FALSE) // if get when never started, just pass on
  548. {
  549. SmartcardDebug(DEBUG_DRIVER,
  550. ("%s!ProcessPnPIrp: IRP_MN_QUERY_STOP_DEVICE when device not started\n",DRIVER_NAME));
  551. IoSkipCurrentIrpStackLocation (Irp);
  552. NTStatus = IoCallDriver (DeviceExtension->TopOfStackDeviceObject, Irp);
  553. CMUSB_DecrementIoCount(DeviceObject);
  554. // Release the remove lock
  555. SmartcardReleaseRemoveLock(&DeviceExtension->SmartcardExtension);
  556. return NTStatus;
  557. }
  558. // We'll not veto it; pass it on and flag that stop was requested.
  559. // Once StopDeviceRequested is set no new IOCTL or read/write irps will be passed
  560. // down the stack to lower drivers; all will be quickly failed
  561. DeviceExtension->StopDeviceRequested = TRUE;
  562. break; // end, case IRP_MN_QUERY_STOP_DEVICE
  563. // -------------------------
  564. // IRP_MN_CANCEL_STOP_DEVICE
  565. // -------------------------
  566. case IRP_MN_CANCEL_STOP_DEVICE:
  567. // The PnP Manager uses this IRP to inform the drivers for a device
  568. // that the device will not be stopped for resource reconfiguration.
  569. // This should only be received after a successful IRP_MN_QUERY_STOP_DEVICE.
  570. SmartcardDebug(DEBUG_DRIVER,
  571. ("%s!IRP_MN_CANCEL_STOP_DEVICE received\n",DRIVER_NAME));
  572. // It is possible to receive this irp when the device has not been started
  573. if (DeviceExtension->DeviceStarted == FALSE) // if get when never started, just pass on
  574. {
  575. SmartcardDebug(DEBUG_DRIVER,
  576. ("%s!ProcessPnPIrp: IRP_MN_CANCEL_STOP_DEVICE when device not started\n",DRIVER_NAME));
  577. IoSkipCurrentIrpStackLocation (Irp);
  578. NTStatus = IoCallDriver (DeviceExtension->TopOfStackDeviceObject, Irp);
  579. CMUSB_DecrementIoCount(DeviceObject);
  580. // Release the remove lock
  581. SmartcardReleaseRemoveLock(&DeviceExtension->SmartcardExtension);
  582. return NTStatus;
  583. }
  584. // Reset this flag so new IOCTL and IO Irp processing will be re-enabled
  585. DeviceExtension->StopDeviceRequested = FALSE;
  586. Irp->IoStatus.Status = STATUS_SUCCESS;
  587. break; // end, case IRP_MN_CANCEL_STOP_DEVICE
  588. // -------------------
  589. // IRP_MN_STOP_DEVICE
  590. // -------------------
  591. case IRP_MN_STOP_DEVICE:
  592. // The PnP Manager sends this IRP to stop a device so it can reconfigure
  593. // its hardware resources. The PnP Manager only sends this IRP if a prior
  594. // IRP_MN_QUERY_STOP_DEVICE completed successfully.
  595. SmartcardDebug(DEBUG_DRIVER,
  596. ("%s!IRP_MN_STOP_DEVICE received\n",DRIVER_NAME));
  597. // Cancel any pending io requests. (there shouldn't be any)
  598. //CMUSB_CancelPendingIo( DeviceObject );
  599. //
  600. // Send the select configuration urb with a NULL pointer for the configuration
  601. // handle, this closes the configuration and puts the device in the 'unconfigured'
  602. // state.
  603. //
  604. NTStatus = CMUSB_StopDevice(DeviceObject);
  605. Irp->IoStatus.Status = NTStatus;
  606. break; // end, case IRP_MN_STOP_DEVICE
  607. // --------------------------
  608. // IRP_MN_QUERY_REMOVE_DEVICE
  609. // --------------------------
  610. case IRP_MN_QUERY_REMOVE_DEVICE:
  611. // In response to this IRP, drivers indicate whether the device can be
  612. // removed without disrupting the system.
  613. // If a driver determines it is safe to remove the device,
  614. // the driver completes any outstanding I/O requests, arranges to hold any subsequent
  615. // read/write requests, and sets Irp->IoStatus.Status to STATUS_SUCCESS. Function
  616. // and filter drivers then pass the IRP to the next-lower driver in the device stack.
  617. // The underlying bus driver calls IoCompleteRequest.
  618. // If a driver sets STATUS_SUCCESS for this IRP, the driver must not start any
  619. // operations on the device that would prevent that driver from succesfully completing
  620. // an IRP_MN_REMOVE_DEVICE for the device. If a driver in the device stack determines
  621. // that the device cannot be removed, the driver is not required to pass the
  622. // query-remove IRP down the device stack. If a query-remove IRP fails, the PnP Manager
  623. // sends an IRP_MN_CANCEL_REMOVE_DEVICE to the device stack, notifying the drivers for
  624. // the device that the query has been cancelled and that the device will not be removed.
  625. SmartcardDebug(DEBUG_DRIVER,
  626. ("%s!IRP_MN_QUERY_REMOVE_DEVICE received\n",DRIVER_NAME));
  627. // It is possible to receive this irp when the device has not been started
  628. if (DeviceExtension->DeviceStarted == FALSE) // if get when never started, just pass on
  629. {
  630. SmartcardDebug( DEBUG_DRIVER,
  631. ("%s!ProcessPnPIrp: IRP_MN_QUERY_STOP_DEVICE when device not started\n",
  632. DRIVER_NAME)
  633. );
  634. IoSkipCurrentIrpStackLocation (Irp);
  635. NTStatus = IoCallDriver (DeviceExtension->TopOfStackDeviceObject, Irp);
  636. CMUSB_DecrementIoCount(DeviceObject);
  637. // Release the remove lock
  638. SmartcardReleaseRemoveLock(&DeviceExtension->SmartcardExtension);
  639. return NTStatus;
  640. }
  641. if (DeviceExtension->fPnPResourceManager == TRUE)
  642. {
  643. // disable the reader
  644. DebugStatus = IoSetDeviceInterfaceState(&DeviceExtension->PnPDeviceName,FALSE);
  645. ASSERT(DebugStatus == STATUS_SUCCESS);
  646. }
  647. // Once RemoveDeviceRequested is set no new IOCTL or read/write irps will be passed
  648. // down the stack to lower drivers; all will be quickly failed
  649. DeviceExtension->RemoveDeviceRequested = TRUE;
  650. // Wait for any io request pending in our driver to
  651. // complete before returning success.
  652. // This event is set when DeviceExtension->PendingIoCount goes to 1
  653. waitStatus = KeWaitForSingleObject(&DeviceExtension->NoPendingIoEvent,
  654. Suspended,
  655. KernelMode,
  656. FALSE,
  657. NULL);
  658. Irp->IoStatus.Status = STATUS_SUCCESS;
  659. break; // end, case IRP_MN_QUERY_REMOVE_DEVICE
  660. // ---------------------------
  661. // IRP_MN_CANCEL_REMOVE_DEVICE
  662. // ---------------------------
  663. case IRP_MN_CANCEL_REMOVE_DEVICE:
  664. SmartcardDebug(DEBUG_DRIVER,
  665. ("%s!IRP_MN_CANCEL_REMOVE_DEVICE received\n",DRIVER_NAME));
  666. // The PnP Manager uses this IRP to inform the drivers
  667. // for a device that the device will not be removed.
  668. // It is sent only after a successful IRP_MN_QUERY_REMOVE_DEVICE.
  669. if (DeviceExtension->DeviceStarted == FALSE) // if get when never started, just pass on
  670. {
  671. SmartcardDebug(DEBUG_DRIVER,
  672. ("%s!ProcessPnPIrp: IRP_MN_CANCEL_REMOVE_DEVICE when device not started\n",DRIVER_NAME));
  673. IoSkipCurrentIrpStackLocation (Irp);
  674. NTStatus = IoCallDriver (DeviceExtension->TopOfStackDeviceObject, Irp);
  675. CMUSB_DecrementIoCount(DeviceObject);
  676. // Release the remove lock
  677. SmartcardReleaseRemoveLock(&DeviceExtension->SmartcardExtension);
  678. return NTStatus;
  679. }
  680. if (DeviceExtension->fPnPResourceManager == TRUE)
  681. {
  682. DebugStatus = IoSetDeviceInterfaceState(&DeviceExtension->PnPDeviceName,
  683. TRUE);
  684. ASSERT(DebugStatus == STATUS_SUCCESS);
  685. }
  686. // Reset this flag so new IOCTL and IO Irp processing will be re-enabled
  687. DeviceExtension->RemoveDeviceRequested = FALSE;
  688. Irp->IoStatus.Status = STATUS_SUCCESS;
  689. break; // end, case IRP_MN_CANCEL_REMOVE_DEVICE
  690. // ---------------------
  691. // IRP_MN_SURPRISE_REMOVAL
  692. // ---------------------
  693. case IRP_MN_SURPRISE_REMOVAL:
  694. // For a surprise-style device removal ( i.e. sudden cord yank ),
  695. // the physical device has already been removed so the PnP Manager sends
  696. // the remove IRP without a prior query-remove. A device can be in any state
  697. // when it receives a remove IRP as a result of a surprise-style removal.
  698. SmartcardDebug(DEBUG_DRIVER,
  699. ("%s!IRP_MN_SURPRISE_REMOVAL received\n",DRIVER_NAME));
  700. // match the inc at the begining of the dispatch routine
  701. CMUSB_DecrementIoCount(DeviceObject);
  702. if (DeviceExtension->fPnPResourceManager == TRUE)
  703. {
  704. // disable the reader
  705. DebugStatus = IoSetDeviceInterfaceState(&DeviceExtension->PnPDeviceName,FALSE);
  706. ASSERT(DebugStatus == STATUS_SUCCESS);
  707. }
  708. // Once RemoveDeviceRequested is set no new IOCTL or read/write irps will be passed
  709. // down the stack to lower drivers; all will be quickly failed
  710. DeviceExtension->DeviceSurpriseRemoval = TRUE;
  711. //
  712. // Mark this handled
  713. //
  714. Irp->IoStatus.Status = STATUS_SUCCESS;
  715. // We don't explicitly wait for the below driver to complete, but just make
  716. // the call and go on, finishing cleanup
  717. IoCopyCurrentIrpStackLocationToNext(Irp);
  718. NTStatus = IoCallDriver(stackDeviceObject,Irp);
  719. // Release the remove lock
  720. SmartcardReleaseRemoveLock(&DeviceExtension->SmartcardExtension);
  721. return NTStatus;
  722. // ---------------------
  723. // IRP_MN_REMOVE_DEVICE
  724. // ---------------------
  725. case IRP_MN_REMOVE_DEVICE:
  726. // The PnP Manager uses this IRP to direct drivers to remove a device.
  727. // For a "polite" device removal, the PnP Manager sends an
  728. // IRP_MN_QUERY_REMOVE_DEVICE prior to the remove IRP. In this case,
  729. // the device is in the remove-pending state when the remove IRP arrives.
  730. // For a surprise-style device removal ( i.e. sudden cord yank ),
  731. // the physical device has already been removed so the PnP Manager sends
  732. // the remove IRP without a prior query-remove. A device can be in any state
  733. // when it receives a remove IRP as a result of a surprise-style removal.
  734. SmartcardDebug(DEBUG_DRIVER,
  735. ("%s!IRP_MN_REMOVE_DEVICE received\n",DRIVER_NAME));
  736. // match the inc at the begining of the dispatch routine
  737. CMUSB_DecrementIoCount(DeviceObject);
  738. //
  739. // Once DeviceRemoved is set no new IOCTL or read/write irps will be passed
  740. // down the stack to lower drivers; all will be quickly failed
  741. //
  742. DeviceExtension->DeviceRemoved = TRUE;
  743. // Cancel any pending io requests; we may not have gotten a query first!
  744. //CMUSB_CancelPendingIo( DeviceObject );
  745. // It is possible to receive this irp when the device has not been started
  746. if (DeviceExtension->DeviceStarted == TRUE) // if get when never started, just pass on
  747. {
  748. // If any pipes are still open, call USBD with URB_FUNCTION_ABORT_PIPE
  749. // This call will also close the pipes; if any user close calls get through,
  750. // they will be noops
  751. CMUSB_AbortPipes( DeviceObject );
  752. }
  753. //
  754. // The final decrement to device extension PendingIoCount == 0
  755. // will set DeviceExtension->RemoveEvent, enabling device removal.
  756. // If there is no pending IO at this point, the below decrement will be it.
  757. // If there is still pending IO,
  758. // the following CancelPendingIo() call will handle it.
  759. //
  760. CMUSB_DecrementIoCount(DeviceObject);
  761. // wait for any io request pending in our driver to
  762. // complete for finishing the remove
  763. KeWaitForSingleObject(&DeviceExtension->RemoveEvent,
  764. Suspended,
  765. KernelMode,
  766. FALSE,
  767. NULL);
  768. //
  769. // Delete the link and FDO we created
  770. //
  771. CMUSB_RemoveDevice(DeviceObject);
  772. // We don't explicitly wait for the below driver to complete, but just make
  773. // the call and go on, finishing cleanup
  774. IoCopyCurrentIrpStackLocationToNext(Irp);
  775. NTStatus = IoCallDriver(stackDeviceObject,Irp);
  776. SmartcardDebug(DEBUG_DRIVER,
  777. ("%s!ProcessPnPIrp: Detaching from %08X\n",DRIVER_NAME,
  778. DeviceExtension->TopOfStackDeviceObject));
  779. IoDetachDevice(DeviceExtension->TopOfStackDeviceObject);
  780. SmartcardDebug(DEBUG_DRIVER,
  781. ("%s!ProcessPnPIrp: Deleting %08X\n",DRIVER_NAME,DeviceObject));
  782. IoDeleteDevice (DeviceObject);
  783. // don't release remove lock here
  784. // because it's relesed in RemoveDevice
  785. return NTStatus; // end, case IRP_MN_REMOVE_DEVICE
  786. // ---------------------
  787. // IRP_MN_QUERY_CAPABILITIES
  788. // ---------------------
  789. case IRP_MN_QUERY_CAPABILITIES:
  790. //
  791. // Get the packet.
  792. //
  793. DeviceCapabilities=irpStack->Parameters.DeviceCapabilities.Capabilities;
  794. if (DeviceCapabilities->Version < 1 ||
  795. DeviceCapabilities->Size < sizeof(DEVICE_CAPABILITIES))
  796. {
  797. //
  798. // We don't support this version. Fail the requests
  799. //
  800. NTStatus = STATUS_UNSUCCESSFUL;
  801. break;
  802. }
  803. //
  804. // Prepare to pass the IRP down
  805. //
  806. // init an event to tell us when the completion routine's been called
  807. KeInitializeEvent(&event, NotificationEvent, FALSE);
  808. IoCopyCurrentIrpStackLocationToNext(Irp);
  809. IoSetCompletionRoutine (Irp,
  810. CMUSB_IrpCompletionRoutine,
  811. &event, // pass the event as Context to completion routine
  812. TRUE, // invoke on success
  813. TRUE, // invoke on error
  814. TRUE); // invoke on cancellation of the Irp
  815. NTStatus = IoCallDriver(stackDeviceObject,Irp);
  816. if (NTStatus == STATUS_PENDING)
  817. {
  818. // wait for irp to complete
  819. NTStatus = KeWaitForSingleObject(&event,
  820. Suspended,
  821. KernelMode,
  822. FALSE,
  823. NULL);
  824. }
  825. // We cannot wake the system.
  826. DeviceCapabilities->SystemWake = PowerSystemUnspecified;
  827. DeviceCapabilities->DeviceWake = PowerDeviceUnspecified;
  828. // We have no latencies
  829. DeviceCapabilities->D1Latency = 0;
  830. DeviceCapabilities->D2Latency = 0;
  831. DeviceCapabilities->D3Latency = 0;
  832. // No locking or ejection
  833. DeviceCapabilities->LockSupported = FALSE;
  834. DeviceCapabilities->EjectSupported = FALSE;
  835. // Device can be physically removed.
  836. // Technically there is no physical device to remove, but this bus
  837. // driver can yank the PDO from the PlugPlay system, when ever it
  838. // receives an IOCTL_GAMEENUM_REMOVE_PORT device control command.
  839. DeviceCapabilities->Removable = TRUE;
  840. // Docking device
  841. DeviceCapabilities->DockDevice = FALSE;
  842. // Device can not be removed any time
  843. // it has a removeable media!!
  844. DeviceCapabilities->SurpriseRemovalOK = FALSE;
  845. Irp->IoStatus.Status = NTStatus;
  846. IoCompleteRequest (Irp,IO_NO_INCREMENT);
  847. // Decrement IO count
  848. CMUSB_DecrementIoCount(DeviceObject);
  849. // Release the remove lock
  850. SmartcardReleaseRemoveLock(&DeviceExtension->SmartcardExtension);
  851. return NTStatus; // end, case IRP_MN_QUERY_CAPABILITIES
  852. // ---------------------
  853. // IRP_MN_ not handled
  854. // ---------------------
  855. default:
  856. SmartcardDebug(DEBUG_DRIVER,
  857. ("%s!ProcessPnPIrp: Minor PnP IOCTL not handled\n",DRIVER_NAME));
  858. } /* case MinorFunction */
  859. if (!NT_SUCCESS(NTStatus))
  860. {
  861. // if anything went wrong, return failure without passing Irp down
  862. Irp->IoStatus.Status = NTStatus;
  863. IoCompleteRequest (Irp,IO_NO_INCREMENT);
  864. CMUSB_DecrementIoCount(DeviceObject);
  865. // Release the remove lock
  866. SmartcardReleaseRemoveLock(&DeviceExtension->SmartcardExtension);
  867. SmartcardDebug(DEBUG_TRACE,
  868. ("%s!ProcessPnPIrp: Exit %lx\n",DRIVER_NAME,NTStatus));
  869. return NTStatus;
  870. }
  871. IoCopyCurrentIrpStackLocationToNext(Irp);
  872. //
  873. // All PNP_POWER messages get passed to the TopOfStackDeviceObject
  874. // we were given in PnPAddDevice
  875. //
  876. SmartcardDebug(DEBUG_DRIVER,
  877. ("%s!ProcessPnPIrp: Passing PnP Irp down, NTStatus = %x\n",DRIVER_NAME,NTStatus));
  878. NTStatus = IoCallDriver(stackDeviceObject,Irp);
  879. CMUSB_DecrementIoCount(DeviceObject);
  880. // Release the remove lock
  881. SmartcardReleaseRemoveLock(&DeviceExtension->SmartcardExtension);
  882. SmartcardDebug(DEBUG_TRACE,
  883. ("%s!ProcessPnPIrp: Exit %lx\n",DRIVER_NAME,NTStatus));
  884. return NTStatus;
  885. }
  886. /*****************************************************************************
  887. Routine Description:
  888. This routine is called to create and initialize our Functional Device Object (FDO).
  889. For monolithic drivers, this is done in DriverEntry(), but Plug and Play devices
  890. wait for a PnP event
  891. Arguments:
  892. DriverObject - pointer to the driver object for this instance of CMUSB
  893. PhysicalDeviceObject - pointer to a device object created by the bus
  894. Return Value:
  895. STATUS_SUCCESS if successful,
  896. STATUS_UNSUCCESSFUL otherwise
  897. *****************************************************************************/
  898. NTSTATUS CMUSB_PnPAddDevice(
  899. IN PDRIVER_OBJECT DriverObject,
  900. IN PDEVICE_OBJECT PhysicalDeviceObject
  901. )
  902. {
  903. NTSTATUS NTStatus = STATUS_SUCCESS;
  904. PDEVICE_OBJECT deviceObject = NULL;
  905. PDEVICE_EXTENSION DeviceExtension;
  906. USBD_VERSION_INFORMATION versionInformation;
  907. ULONG i;
  908. SmartcardDebug(DEBUG_TRACE,
  909. ("%s!PnPAddDevice: Enter\n",DRIVER_NAME));
  910. //
  911. // create our funtional device object (FDO)
  912. //
  913. NTStatus = CMUSB_CreateDeviceObject(DriverObject,
  914. PhysicalDeviceObject,
  915. &deviceObject);
  916. SmartcardDebug(DEBUG_DRIVER,
  917. ("%s!PnPAddDevice: DeviceObject = %p\n",DRIVER_NAME,deviceObject));
  918. if (NT_SUCCESS(NTStatus))
  919. {
  920. DeviceExtension = deviceObject->DeviceExtension;
  921. deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  922. //
  923. // we support direct io for read/write
  924. //
  925. deviceObject->Flags |= DO_DIRECT_IO;
  926. //Set this flag causes the driver to not receive a IRP_MN_STOP_DEVICE
  927. //during suspend and also not get an IRP_MN_START_DEVICE during resume.
  928. //This is neccesary because during the start device call,
  929. // the GetDescriptors() call will be failed by the USB stack.
  930. deviceObject->Flags |= DO_POWER_PAGABLE;
  931. // initialize our device extension
  932. //
  933. // remember the Physical device Object
  934. //
  935. DeviceExtension->PhysicalDeviceObject=PhysicalDeviceObject;
  936. //
  937. // Attach to the PDO
  938. //
  939. DeviceExtension->TopOfStackDeviceObject =
  940. IoAttachDeviceToDeviceStack(deviceObject, PhysicalDeviceObject);
  941. // Get a copy of the physical device's capabilities into a
  942. // DEVICE_CAPABILITIES struct in our device extension;
  943. // We are most interested in learning which system power states
  944. // are to be mapped to which device power states for handling
  945. // IRP_MJ_SET_POWER Irps.
  946. CMUSB_QueryCapabilities(PhysicalDeviceObject,
  947. &DeviceExtension->DeviceCapabilities);
  948. // We want to determine what level to auto-powerdown to; This is the lowest
  949. // sleeping level that is LESS than D3;
  950. // If all are set to D3, auto powerdown/powerup will be disabled.
  951. DeviceExtension->PowerDownLevel = PowerDeviceUnspecified; // init to disabled
  952. for (i=PowerSystemSleeping1; i<= PowerSystemSleeping3; i++)
  953. {
  954. if ( DeviceExtension->DeviceCapabilities.DeviceState[i] < PowerDeviceD3 )
  955. DeviceExtension->PowerDownLevel = DeviceExtension->DeviceCapabilities.DeviceState[i];
  956. }
  957. #if DBG
  958. //
  959. // display the device caps
  960. //
  961. SmartcardDebug( DEBUG_DRIVER,("%s!PnPAddDevice: ----------- DeviceCapabilities ------------\n",
  962. DRIVER_NAME));
  963. SmartcardDebug( DEBUG_DRIVER, ("%s!PnPAddDevice: SystemWake = %s\n",
  964. DRIVER_NAME,
  965. CMUSB_StringForSysState( DeviceExtension->DeviceCapabilities.SystemWake ) ));
  966. SmartcardDebug( DEBUG_DRIVER, ("%s!PnPAddDevice: DeviceWake = %s\n",
  967. DRIVER_NAME,
  968. CMUSB_StringForDevState( DeviceExtension->DeviceCapabilities.DeviceWake) ));
  969. for (i=PowerSystemUnspecified; i< PowerSystemMaximum; i++)
  970. {
  971. SmartcardDebug(DEBUG_DRIVER,("%s!PnPAddDevice: sysstate %s = devstate %s\n",
  972. DRIVER_NAME,
  973. CMUSB_StringForSysState( i ),
  974. CMUSB_StringForDevState( DeviceExtension->DeviceCapabilities.DeviceState[i] ))
  975. );
  976. }
  977. SmartcardDebug( DEBUG_DRIVER,("PnPAddDevice: ---------------------------------------------\n"));
  978. #endif
  979. // We keep a pending IO count ( extension->PendingIoCount ) in the device extension.
  980. // The first increment of this count is done on adding the device.
  981. // Subsequently, the count is incremented for each new IRP received and
  982. // decremented when each IRP is completed or passed on.
  983. // Transition to 'one' therefore indicates no IO is pending and signals
  984. // DeviceExtension->NoPendingIoEvent. This is needed for processing
  985. // IRP_MN_QUERY_REMOVE_DEVICE
  986. // Transition to 'zero' signals an event ( DeviceExtension->RemoveEvent )
  987. // to enable device removal. This is used in processing for IRP_MN_REMOVE_DEVICE
  988. //
  989. CMUSB_IncrementIoCount(deviceObject);
  990. }
  991. USBD_GetUSBDIVersion(&versionInformation);
  992. SmartcardDebug(DEBUG_TRACE,
  993. ("%s!PnPAddDevice: Exit %lx\n",DRIVER_NAME,NTStatus));
  994. return NTStatus;
  995. }
  996. /*****************************************************************************
  997. Routine Description:
  998. Called from CMUSB_ProcessPnPIrp, the dispatch routine for IRP_MJ_PNP.
  999. Initializes a given instance of the device on the USB.
  1000. USB client drivers such as us set up URBs (USB Request Packets) to send requests
  1001. to the host controller driver (HCD). The URB structure defines a format for all
  1002. possible commands that can be sent to a USB device.
  1003. Here, we request the device descriptor and store it, and configure the device.
  1004. Arguments:
  1005. DeviceObject - pointer to the FDO (Functional Device Object)
  1006. Return Value:
  1007. NT NTStatus code
  1008. *****************************************************************************/
  1009. NTSTATUS CMUSB_StartDevice(
  1010. IN PDEVICE_OBJECT DeviceObject
  1011. )
  1012. {
  1013. PDEVICE_EXTENSION DeviceExtension;
  1014. NTSTATUS NTStatus;
  1015. PUSB_DEVICE_DESCRIPTOR deviceDescriptor = NULL;
  1016. PURB urb;
  1017. ULONG siz;
  1018. SmartcardDebug(DEBUG_TRACE,
  1019. ("%s!StartDevice: Enter\n",DRIVER_NAME));
  1020. DeviceExtension = DeviceObject->DeviceExtension;
  1021. urb = ExAllocatePool(NonPagedPool,
  1022. sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
  1023. if (urb != NULL)
  1024. {
  1025. siz = sizeof(USB_DEVICE_DESCRIPTOR);
  1026. deviceDescriptor = ExAllocatePool(NonPagedPool,siz);
  1027. if (deviceDescriptor != NULL)
  1028. {
  1029. UsbBuildGetDescriptorRequest(urb,
  1030. (USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
  1031. USB_DEVICE_DESCRIPTOR_TYPE,
  1032. 0,
  1033. 0,
  1034. deviceDescriptor,
  1035. NULL,
  1036. siz,
  1037. NULL);
  1038. NTStatus = CMUSB_CallUSBD(DeviceObject, urb);
  1039. if (NT_SUCCESS(NTStatus))
  1040. {
  1041. SmartcardDebug( DEBUG_DRIVER,("%s!StartDevice: Device Descriptor = %x, len %x\n",DRIVER_NAME,deviceDescriptor,
  1042. urb->UrbControlDescriptorRequest.TransferBufferLength));
  1043. SmartcardDebug( DEBUG_DRIVER,("%s!StartDevice: CardMan USB Device Descriptor:\n",DRIVER_NAME));
  1044. SmartcardDebug( DEBUG_DRIVER,("%s!StartDevice: -------------------------\n",DRIVER_NAME));
  1045. SmartcardDebug( DEBUG_DRIVER,("%s!StartDevice: bLength %d\n",DRIVER_NAME,deviceDescriptor->bLength));
  1046. SmartcardDebug( DEBUG_DRIVER,("%s!StartDevice: bDescriptorType 0x%x\n",DRIVER_NAME,deviceDescriptor->bDescriptorType));
  1047. SmartcardDebug( DEBUG_DRIVER,("%s!StartDevice: bcdUSB 0x%x\n",DRIVER_NAME,deviceDescriptor->bcdUSB));
  1048. SmartcardDebug( DEBUG_DRIVER,("%s!StartDevice: bDeviceClass 0x%x\n",DRIVER_NAME,deviceDescriptor->bDeviceClass));
  1049. SmartcardDebug( DEBUG_DRIVER,("%s!StartDevice: bDeviceSubClass 0x%x\n",DRIVER_NAME,deviceDescriptor->bDeviceSubClass));
  1050. SmartcardDebug( DEBUG_DRIVER,("%s!StartDevice: bDeviceProtocol 0x%x\n",DRIVER_NAME,deviceDescriptor->bDeviceProtocol));
  1051. SmartcardDebug( DEBUG_DRIVER,("%s!StartDevice: bMaxPacketSize0 0x%x\n",DRIVER_NAME,deviceDescriptor->bMaxPacketSize0));
  1052. SmartcardDebug( DEBUG_DRIVER,("%s!StartDevice: idVendor 0x%x\n",DRIVER_NAME,deviceDescriptor->idVendor));
  1053. SmartcardDebug( DEBUG_DRIVER,("%s!StartDevice: idProduct 0x%x\n",DRIVER_NAME,deviceDescriptor->idProduct));
  1054. SmartcardDebug( DEBUG_DRIVER,("%s!StartDevice: bcdDevice 0x%x\n",DRIVER_NAME,deviceDescriptor->bcdDevice));
  1055. SmartcardDebug( DEBUG_DRIVER,("%s!StartDevice: iManufacturer 0x%x\n",DRIVER_NAME,deviceDescriptor->iManufacturer));
  1056. SmartcardDebug( DEBUG_DRIVER,("%s!StartDevice: iProduct 0x%x\n",DRIVER_NAME,deviceDescriptor->iProduct));
  1057. SmartcardDebug( DEBUG_DRIVER,("%s!StartDevice: iSerialNumber 0x%x\n",DRIVER_NAME,deviceDescriptor->iSerialNumber));
  1058. SmartcardDebug( DEBUG_DRIVER,("%s!StartDevice: bNumConfigurations 0x%x\n",DRIVER_NAME,deviceDescriptor->bNumConfigurations));
  1059. }
  1060. }
  1061. else
  1062. {
  1063. // if we got here we failed to allocate deviceDescriptor
  1064. SmartcardDebug(DEBUG_ERROR,
  1065. ( "%s!StartDevice: ExAllocatePool for deviceDescriptor failed\n",DRIVER_NAME));
  1066. NTStatus = STATUS_INSUFFICIENT_RESOURCES;
  1067. }
  1068. if (NT_SUCCESS(NTStatus))
  1069. {
  1070. DeviceExtension->UsbDeviceDescriptor = deviceDescriptor;
  1071. // -------------------------------------------------------------
  1072. // copy the firmware version to the reader extension structure
  1073. // -------------------------------------------------------------
  1074. DeviceExtension->SmartcardExtension.ReaderExtension->ulFWVersion =
  1075. (ULONG)(((DeviceExtension->UsbDeviceDescriptor->bcdDevice/256)*100)+
  1076. (DeviceExtension->UsbDeviceDescriptor->bcdDevice&0x00FF));
  1077. SmartcardDebug(DEBUG_DRIVER,
  1078. ("%s!StartDevice: FW version = %ld\n",DRIVER_NAME,DeviceExtension->SmartcardExtension.ReaderExtension->ulFWVersion));
  1079. }
  1080. else if (deviceDescriptor != NULL)
  1081. {
  1082. ExFreePool(deviceDescriptor);
  1083. }
  1084. ExFreePool(urb);
  1085. }
  1086. else
  1087. {
  1088. // if we got here we failed to allocate the urb
  1089. SmartcardDebug(DEBUG_ERROR,
  1090. ("%s!StartDevice: ExAllocatePool for usb failed\n",DRIVER_NAME));
  1091. NTStatus = STATUS_INSUFFICIENT_RESOURCES;
  1092. }
  1093. if (NT_SUCCESS(NTStatus))
  1094. {
  1095. NTStatus = CMUSB_ConfigureDevice(DeviceObject);
  1096. }
  1097. if (NT_SUCCESS(NTStatus))
  1098. {
  1099. NTStatus = CMUSB_StartCardTracking(DeviceObject);
  1100. }
  1101. if (NT_SUCCESS(NTStatus) && DeviceExtension->fPnPResourceManager == TRUE)
  1102. {
  1103. // enable interface
  1104. NTStatus = IoSetDeviceInterfaceState(&DeviceExtension->PnPDeviceName,TRUE);
  1105. }
  1106. if (NT_SUCCESS(NTStatus))
  1107. {
  1108. DeviceExtension->DeviceStarted = TRUE;
  1109. }
  1110. SmartcardDebug(DEBUG_TRACE,
  1111. ("%s!StartDevice: Exit %ld\n",DRIVER_NAME,NTStatus));
  1112. return NTStatus;
  1113. }
  1114. /*****************************************************************************
  1115. Routine Description:
  1116. Called from CMUSB_ProcessPnPIrp: to
  1117. clean up our device instance's allocated buffers; free symbolic links
  1118. Arguments:
  1119. DeviceObject - pointer to the FDO
  1120. Return Value:
  1121. NT NTStatus code from free symbolic link operation
  1122. *****************************************************************************/
  1123. NTSTATUS CMUSB_RemoveDevice(
  1124. IN PDEVICE_OBJECT DeviceObject
  1125. )
  1126. {
  1127. PDEVICE_EXTENSION DeviceExtension;
  1128. PSMARTCARD_EXTENSION SmartcardExtension;
  1129. NTSTATUS NTStatus = STATUS_SUCCESS;
  1130. UNICODE_STRING deviceLinkUnicodeString;
  1131. KIRQL irql;
  1132. SmartcardDebug(DEBUG_TRACE,
  1133. ("%s!RemoveDevice: Enter\n",DRIVER_NAME));
  1134. DeviceExtension = DeviceObject->DeviceExtension;
  1135. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  1136. SmartcardDebug(DEBUG_DRIVER,
  1137. ("%s!RemoveDevice: DeviceStarted=%ld\n",DRIVER_NAME,DeviceExtension->DeviceStarted));
  1138. SmartcardDebug(DEBUG_DRIVER,
  1139. ("%s!RemoveDevice: DeviceOpened=%ld\n",DRIVER_NAME,DeviceExtension->lOpenCount));
  1140. if (SmartcardExtension->OsData != NULL)
  1141. {
  1142. // complete pending card tracking requests (if any)
  1143. if (SmartcardExtension->OsData->NotificationIrp != NULL)
  1144. {
  1145. CMUSB_CompleteCardTracking(SmartcardExtension);
  1146. }
  1147. ASSERT(SmartcardExtension->OsData->NotificationIrp == NULL);
  1148. }
  1149. // Wait until we can safely unload the device
  1150. SmartcardReleaseRemoveLockAndWait(SmartcardExtension);
  1151. if (DeviceExtension->DeviceStarted == TRUE)
  1152. {
  1153. if (DeviceExtension->fPnPResourceManager == FALSE)
  1154. {
  1155. KeWaitForSingleObject(&SmartcardExtension->ReaderExtension->CardManIOMutex,
  1156. Executive,
  1157. KernelMode,
  1158. FALSE,
  1159. NULL);
  1160. // issue a card removal event for the resource manager
  1161. if (SmartcardExtension->ReaderExtension->ulOldCardState == INSERTED ||
  1162. SmartcardExtension->ReaderExtension->ulOldCardState == POWERED )
  1163. {
  1164. // card has been removed
  1165. SmartcardDebug(DEBUG_DRIVER,
  1166. ("%s!RemoveDevice: Smartcard removed\n",DRIVER_NAME));
  1167. CMUSB_CompleteCardTracking(SmartcardExtension);
  1168. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  1169. &irql);
  1170. SmartcardExtension->ReaderExtension->ulOldCardState = UNKNOWN;
  1171. SmartcardExtension->ReaderExtension->ulNewCardState = UNKNOWN;
  1172. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_ABSENT;
  1173. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  1174. SmartcardExtension->CardCapabilities.ATR.Length = 0;
  1175. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  1176. irql);
  1177. RtlFillMemory((PVOID)&SmartcardExtension->ReaderExtension->CardParameters,
  1178. sizeof(CARD_PARAMETERS),0x00);
  1179. }
  1180. KeReleaseMutex(&SmartcardExtension->ReaderExtension->CardManIOMutex,FALSE);
  1181. }
  1182. CMUSB_StopDevice(DeviceObject);
  1183. }
  1184. if (DeviceExtension->fPnPResourceManager == TRUE)
  1185. {
  1186. // disable interface
  1187. NTStatus = IoSetDeviceInterfaceState(&DeviceExtension->PnPDeviceName,
  1188. FALSE);
  1189. if (DeviceExtension->PnPDeviceName.Buffer != NULL)
  1190. {
  1191. RtlFreeUnicodeString(&DeviceExtension->PnPDeviceName);
  1192. DeviceExtension->PnPDeviceName.Buffer = NULL;
  1193. }
  1194. SmartcardDebug(DEBUG_DRIVER,
  1195. ("%s!RemoveDevice: PnPDeviceName.Buffer = %lx\n",DRIVER_NAME,
  1196. DeviceExtension->PnPDeviceName.Buffer));
  1197. SmartcardDebug(DEBUG_DRIVER,
  1198. ("%s!RemoveDevice: PnPDeviceName.BufferLength = %lx\n",DRIVER_NAME,
  1199. DeviceExtension->PnPDeviceName.Length));
  1200. }
  1201. else
  1202. {
  1203. //
  1204. // Delete the symbolic link of the smart card reader
  1205. //
  1206. IoDeleteSymbolicLink(&DeviceExtension->DosDeviceName);
  1207. }
  1208. DeviceSlot[SmartcardExtension->ReaderExtension->ulDeviceInstance] = FALSE;
  1209. OemDeviceSlot[SmartcardExtension->ReaderExtension->ulOemNameIndex][SmartcardExtension->ReaderExtension->ulOemDeviceInstance] = FALSE;
  1210. if (DeviceExtension->lOpenCount == 0)
  1211. {
  1212. SmartcardDebug(DEBUG_DRIVER,
  1213. ("%s!RemoveDevice: freeing resources\n",DRIVER_NAME));
  1214. if (DeviceExtension->fPnPResourceManager == FALSE)
  1215. {
  1216. //
  1217. // Free all allocated buffer
  1218. //
  1219. ExFreePool(DeviceExtension->DosDeviceName.Buffer);
  1220. }
  1221. ExFreePool(SmartcardExtension->ReaderExtension);
  1222. SmartcardExtension->ReaderExtension = NULL;
  1223. //
  1224. // Let the lib free the send/receive buffers
  1225. //
  1226. SmartcardExit(SmartcardExtension);
  1227. }
  1228. SmartcardDebug(DEBUG_TRACE,
  1229. ("%s!RemoveDevice: Exit %lx\n",DRIVER_NAME,NTStatus));
  1230. return NTStatus;
  1231. }
  1232. /*****************************************************************************
  1233. Routine Description:
  1234. Stops a given instance of a 82930 device on the USB.
  1235. We basically just tell USB this device is now 'unconfigured'
  1236. Arguments:
  1237. DeviceObject - pointer to the device object for this instance of a 82930
  1238. Return Value:
  1239. NT NTStatus code
  1240. *****************************************************************************/
  1241. NTSTATUS CMUSB_StopDevice(
  1242. IN PDEVICE_OBJECT DeviceObject
  1243. )
  1244. {
  1245. PDEVICE_EXTENSION DeviceExtension;
  1246. PSMARTCARD_EXTENSION SmartcardExtension;
  1247. NTSTATUS NTStatus = STATUS_SUCCESS;
  1248. PURB urb;
  1249. ULONG siz;
  1250. DeviceExtension = DeviceObject->DeviceExtension;
  1251. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  1252. SmartcardDebug(DEBUG_TRACE,
  1253. ("%s!StopDevice: Enter\n",DRIVER_NAME));
  1254. DeviceExtension = DeviceObject->DeviceExtension;
  1255. SmartcardDebug(DEBUG_DRIVER,
  1256. ("%s!StopDevice: DeviceStarted=%ld\n",DRIVER_NAME,
  1257. DeviceExtension->DeviceStarted));
  1258. SmartcardDebug( DEBUG_DRIVER,
  1259. ("%s!StopDevice: DeviceOpened=%ld\n",DRIVER_NAME,
  1260. DeviceExtension->lOpenCount));
  1261. // stop update thread
  1262. CMUSB_StopCardTracking(DeviceObject);
  1263. // power down the card for saftey reasons
  1264. if (DeviceExtension->SmartcardExtension.ReaderExtension->ulOldCardState == POWERED)
  1265. {
  1266. // we have to wait for the mutex before
  1267. KeWaitForSingleObject(&DeviceExtension->SmartcardExtension.ReaderExtension->CardManIOMutex,
  1268. Executive,
  1269. KernelMode,
  1270. FALSE,
  1271. NULL);
  1272. CMUSB_PowerOffCard(&DeviceExtension->SmartcardExtension);
  1273. KeReleaseMutex(&DeviceExtension->SmartcardExtension.ReaderExtension->CardManIOMutex,
  1274. FALSE);
  1275. }
  1276. //
  1277. // Send the select configuration urb with a NULL pointer for the configuration
  1278. // handle. This closes the configuration and puts the device in the 'unconfigured'
  1279. // state.
  1280. //
  1281. siz = sizeof(struct _URB_SELECT_CONFIGURATION);
  1282. urb = ExAllocatePool(NonPagedPool,siz);
  1283. if (urb != NULL)
  1284. {
  1285. UsbBuildSelectConfigurationRequest(urb,
  1286. (USHORT) siz,
  1287. NULL);
  1288. NTStatus = CMUSB_CallUSBD(DeviceObject, urb);
  1289. ExFreePool(urb);
  1290. }
  1291. else
  1292. {
  1293. NTStatus = STATUS_INSUFFICIENT_RESOURCES;
  1294. }
  1295. // now clear the flag whcih indicates if the device is started
  1296. DeviceExtension->DeviceStarted = FALSE;
  1297. DeviceExtension->StopDeviceRequested = FALSE;
  1298. //
  1299. // Free device descriptor structure
  1300. //
  1301. if (DeviceExtension->UsbDeviceDescriptor != NULL)
  1302. {
  1303. SmartcardDebug( DEBUG_DRIVER,
  1304. ("%s!StopDevice: freeing UsbDeviceDescriptor\n",DRIVER_NAME,NTStatus));
  1305. ExFreePool(DeviceExtension->UsbDeviceDescriptor);
  1306. DeviceExtension->UsbDeviceDescriptor = NULL;
  1307. }
  1308. //
  1309. // Free up the UsbInterface structure
  1310. //
  1311. if (DeviceExtension->UsbInterface != NULL)
  1312. {
  1313. SmartcardDebug( DEBUG_DRIVER,
  1314. ("%s!StopDevice: freeing UsbInterface\n",DRIVER_NAME,NTStatus));
  1315. ExFreePool(DeviceExtension->UsbInterface);
  1316. DeviceExtension->UsbInterface = NULL;
  1317. }
  1318. // free up the USB config discriptor
  1319. if (DeviceExtension->UsbConfigurationDescriptor != NULL)
  1320. {
  1321. SmartcardDebug( DEBUG_DRIVER,
  1322. ("%s!StopDevice: freeing UsbConfiguration\n",DRIVER_NAME,NTStatus));
  1323. ExFreePool(DeviceExtension->UsbConfigurationDescriptor);
  1324. DeviceExtension->UsbConfigurationDescriptor = NULL;
  1325. }
  1326. SmartcardDebug( DEBUG_TRACE,
  1327. ("%s!StopDevice: Exit %lx\n",DRIVER_NAME,NTStatus));
  1328. return NTStatus;
  1329. }
  1330. /*****************************************************************************
  1331. Routine Description:
  1332. Used as a general purpose completion routine so it can signal an event,
  1333. passed as the Context, when the next lower driver is done with the input Irp.
  1334. This routine is used by both PnP and Power Management logic.
  1335. Even though this routine does nothing but set an event, it must be defined and
  1336. prototyped as a completetion routine for use as such
  1337. Arguments:
  1338. DeviceObject - Pointer to the device object for the class device.
  1339. Irp - Irp completed.
  1340. Context - Driver defined context, in this case a pointer to an event.
  1341. Return Value:
  1342. The function value is the final NTStatus from the operation.
  1343. *****************************************************************************/
  1344. NTSTATUS CMUSB_IrpCompletionRoutine(
  1345. IN PDEVICE_OBJECT DeviceObject,
  1346. IN PIRP Irp,
  1347. IN PVOID Context
  1348. )
  1349. {
  1350. PKEVENT event = Context;
  1351. // Set the input event
  1352. KeSetEvent(event,
  1353. 1, // Priority increment for waiting thread.
  1354. FALSE); // Flag this call is not immediately followed by wait.
  1355. // This routine must return STATUS_MORE_PROCESSING_REQUIRED because we have not yet called
  1356. // IoFreeIrp() on this IRP.
  1357. return STATUS_MORE_PROCESSING_REQUIRED;
  1358. }
  1359. /*****************************************************************************
  1360. Routine Description:
  1361. This is our FDO's dispatch table function for IRP_MJ_POWER.
  1362. It processes the Power IRPs sent to the PDO for this device.
  1363. For every power IRP, drivers must call PoStartNextPowerIrp and use PoCallDriver
  1364. to pass the IRP all the way down the driver stack to the underlying PDO.
  1365. Arguments:
  1366. DeviceObject - pointer to our device object (FDO)
  1367. Irp - pointer to an I/O Request Packet
  1368. Return Value:
  1369. NT NTStatus code
  1370. *****************************************************************************/
  1371. NTSTATUS CMUSB_ProcessPowerIrp(
  1372. IN PDEVICE_OBJECT DeviceObject,
  1373. IN PIRP Irp
  1374. )
  1375. {
  1376. PIO_STACK_LOCATION irpStack;
  1377. NTSTATUS NTStatus = STATUS_SUCCESS;
  1378. PDEVICE_EXTENSION DeviceExtension;
  1379. BOOLEAN fGoingToD0 = FALSE;
  1380. POWER_STATE sysPowerState, desiredDevicePowerState;
  1381. KEVENT event;
  1382. SmartcardDebug(DEBUG_TRACE,
  1383. ("%s!ProcessPowerIrp Enter\n",DRIVER_NAME));
  1384. DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  1385. irpStack = IoGetCurrentIrpStackLocation (Irp);
  1386. CMUSB_IncrementIoCount(DeviceObject);
  1387. switch (irpStack->MinorFunction)
  1388. {
  1389. // ----------------
  1390. // IRP_MN_WAIT_WAKE
  1391. // ----------------
  1392. case IRP_MN_WAIT_WAKE:
  1393. // A driver sends IRP_MN_WAIT_WAKE to indicate that the system should
  1394. // wait for its device to signal a wake event. The exact nature of the event
  1395. // is device-dependent.
  1396. // Drivers send this IRP for two reasons:
  1397. // 1) To allow a device to wake the system
  1398. // 2) To wake a device that has been put into a sleep state to save power
  1399. // but still must be able to communicate with its driver under certain circumstances.
  1400. // When a wake event occurs, the driver completes the IRP and returns
  1401. // STATUS_SUCCESS. If the device is sleeping when the event occurs,
  1402. // the driver must first wake up the device before completing the IRP.
  1403. // In a completion routine, the driver calls PoRequestPowerIrp to send a
  1404. // PowerDeviceD0 request. When the device has powered up, the driver can
  1405. // handle the IRP_MN_WAIT_WAKE request.
  1406. SmartcardDebug( DEBUG_DRIVER,
  1407. ("%s!IRP_MN_WAIT_WAKE received\n",DRIVER_NAME));
  1408. // DeviceExtension->DeviceCapabilities.DeviceWake specifies the lowest device power state (least powered)
  1409. // from which the device can signal a wake event
  1410. DeviceExtension->PowerDownLevel = DeviceExtension->DeviceCapabilities.DeviceWake;
  1411. if ( ( PowerDeviceD0 == DeviceExtension->CurrentDevicePowerState ) ||
  1412. ( DeviceExtension->DeviceCapabilities.DeviceWake > DeviceExtension->CurrentDevicePowerState ) )
  1413. {
  1414. // STATUS_INVALID_DEVICE_STATE is returned if the device in the PowerD0 state
  1415. // or a state below which it can support waking, or if the SystemWake state
  1416. // is below a state which can be supported. A pending IRP_MN_WAIT_WAKE will complete
  1417. // with this error if the device's state is changed to be incompatible with the wake
  1418. // request.
  1419. // If a driver fails this IRP, it should complete the IRP immediately without
  1420. // passing the IRP to the next-lower driver.
  1421. NTStatus = STATUS_INVALID_DEVICE_STATE;
  1422. Irp->IoStatus.Status = NTStatus;
  1423. IoCompleteRequest (Irp,IO_NO_INCREMENT );
  1424. SmartcardDebug( DEBUG_DRIVER,
  1425. ("%s!ProcessPowerIrp Exit %lx\n",DRIVER_NAME,NTStatus));
  1426. CMUSB_DecrementIoCount(DeviceObject);
  1427. return NTStatus;
  1428. }
  1429. // flag we're enabled for wakeup
  1430. DeviceExtension->EnabledForWakeup = TRUE;
  1431. // init an event for our completion routine to signal when PDO is done with this Irp
  1432. KeInitializeEvent(&event, NotificationEvent, FALSE);
  1433. // If not failing outright, pass this on to our PDO for further handling
  1434. IoCopyCurrentIrpStackLocationToNext(Irp);
  1435. // Set a completion routine so it can signal our event when
  1436. // the PDO is done with the Irp
  1437. IoSetCompletionRoutine(Irp,
  1438. CMUSB_IrpCompletionRoutine,
  1439. &event, // pass the event to the completion routine as the Context
  1440. TRUE, // invoke on success
  1441. TRUE, // invoke on error
  1442. TRUE); // invoke on cancellation
  1443. PoStartNextPowerIrp(Irp);
  1444. NTStatus = PoCallDriver(DeviceExtension->TopOfStackDeviceObject,
  1445. Irp);
  1446. // if PDO is not done yet, wait for the event to be set in our completion routine
  1447. if (NTStatus == STATUS_PENDING)
  1448. {
  1449. // wait for irp to complete
  1450. NTSTATUS waitStatus = KeWaitForSingleObject(&event,
  1451. Suspended,
  1452. KernelMode,
  1453. FALSE,
  1454. NULL);
  1455. SmartcardDebug( DEBUG_DRIVER,
  1456. ("%s!waiting for PDO to finish IRP_MN_WAIT_WAKE completed\n",DRIVER_NAME));
  1457. }
  1458. // now tell the device to actually wake up
  1459. CMUSB_SelfSuspendOrActivate( DeviceObject, FALSE );
  1460. // flag we're done with wakeup irp
  1461. DeviceExtension->EnabledForWakeup = FALSE;
  1462. CMUSB_DecrementIoCount(DeviceObject);
  1463. break;
  1464. // ------------------
  1465. // IRP_MN_SET_POWER
  1466. // ------------------
  1467. case IRP_MN_SET_POWER:
  1468. // The system power policy manager sends this IRP to set the system power state.
  1469. // A device power policy manager sends this IRP to set the device power state for a device.
  1470. // Set Irp->IoStatus.Status to STATUS_SUCCESS to indicate that the device
  1471. // has entered the requested state. Drivers cannot fail this IRP.
  1472. SmartcardDebug( DEBUG_DRIVER,
  1473. ("%s!IRP_MN_SET_POWER\n",DRIVER_NAME));
  1474. switch (irpStack->Parameters.Power.Type)
  1475. {
  1476. // +++++++++++++++++++
  1477. // SystemPowerState
  1478. // +++++++++++++++++++
  1479. case SystemPowerState:
  1480. // Get input system power state
  1481. sysPowerState.SystemState = irpStack->Parameters.Power.State.SystemState;
  1482. SmartcardDebug( DEBUG_DRIVER,
  1483. ("%s!SystemPowerState = %s\n",DRIVER_NAME,
  1484. CMUSB_StringForSysState( sysPowerState.SystemState)));
  1485. // If system is in working state always set our device to D0
  1486. // regardless of the wait state or system-to-device state power map
  1487. if (sysPowerState.SystemState == PowerSystemWorking)
  1488. {
  1489. desiredDevicePowerState.DeviceState = PowerDeviceD0;
  1490. SmartcardDebug( DEBUG_DRIVER,
  1491. ("%s!PowerSystemWorking, will set D0, not use state map\n",DRIVER_NAME));
  1492. }
  1493. else
  1494. {
  1495. // set to corresponding system state if IRP_MN_WAIT_WAKE pending
  1496. if ( DeviceExtension->EnabledForWakeup ) // got a WAIT_WAKE IRP pending?
  1497. {
  1498. // Find the device power state equivalent to the given system state.
  1499. // We get this info from the DEVICE_CAPABILITIES struct in our device
  1500. // extension (initialized in CMUSB_PnPAddDevice() )
  1501. desiredDevicePowerState.DeviceState =
  1502. DeviceExtension->DeviceCapabilities.DeviceState[ sysPowerState.SystemState ];
  1503. SmartcardDebug(DEBUG_DRIVER,
  1504. ("%s!IRP_MN_WAIT_WAKE pending, will use state map\n",DRIVER_NAME));
  1505. }
  1506. else
  1507. {
  1508. // if no wait pending and the system's not in working state, just turn off
  1509. desiredDevicePowerState.DeviceState = PowerDeviceD3;
  1510. SmartcardDebug(DEBUG_DRIVER,
  1511. ("%s!Not EnabledForWakeup and the system's not in working state,\n settting PowerDeviceD3 (off)\n",DRIVER_NAME));
  1512. }
  1513. if (sysPowerState.SystemState == PowerSystemShutdown)
  1514. {
  1515. // power down the card for saftey reasons
  1516. if (DeviceExtension->SmartcardExtension.ReaderExtension->ulOldCardState == POWERED)
  1517. {
  1518. // we have to wait for the mutex before
  1519. KeWaitForSingleObject(&DeviceExtension->SmartcardExtension.ReaderExtension->CardManIOMutex,
  1520. Executive,
  1521. KernelMode,
  1522. FALSE,
  1523. NULL);
  1524. CMUSB_PowerOffCard(&DeviceExtension->SmartcardExtension);
  1525. KeReleaseMutex(&DeviceExtension->SmartcardExtension.ReaderExtension->CardManIOMutex,
  1526. FALSE);
  1527. }
  1528. }
  1529. }
  1530. //
  1531. // We've determined the desired device state; are we already in this state?
  1532. //
  1533. SmartcardDebug(DEBUG_DRIVER,
  1534. ("%s!desiredDevicePowerState = %s\n",DRIVER_NAME,CMUSB_StringForDevState(desiredDevicePowerState.DeviceState)));
  1535. if (desiredDevicePowerState.DeviceState != DeviceExtension->CurrentDevicePowerState)
  1536. {
  1537. CMUSB_IncrementIoCount(DeviceObject);
  1538. // No, request that we be put into this state
  1539. // by requesting a new Power Irp from the Pnp manager
  1540. DeviceExtension->PowerIrp = Irp;
  1541. IoMarkIrpPending(Irp);
  1542. NTStatus = PoRequestPowerIrp(DeviceExtension->PhysicalDeviceObject,
  1543. IRP_MN_SET_POWER,
  1544. desiredDevicePowerState,
  1545. // completion routine will pass the Irp down to the PDO
  1546. CMUSB_PoRequestCompletion,
  1547. DeviceObject,
  1548. NULL);
  1549. }
  1550. else
  1551. {
  1552. // Yes, just pass it on to PDO (Physical Device Object)
  1553. IoCopyCurrentIrpStackLocationToNext(Irp);
  1554. PoStartNextPowerIrp(Irp);
  1555. NTStatus = PoCallDriver(DeviceExtension->TopOfStackDeviceObject,Irp);
  1556. CMUSB_DecrementIoCount(DeviceObject);
  1557. }
  1558. break;
  1559. // ++++++++++++++++++
  1560. // DevicePowerState
  1561. // ++++++++++++++++++
  1562. case DevicePowerState:
  1563. // For requests to D1, D2, or D3 ( sleep or off states ),
  1564. // sets DeviceExtension->CurrentDevicePowerState to DeviceState immediately.
  1565. // This enables any code checking state to consider us as sleeping or off
  1566. // already, as this will imminently become our state.
  1567. SmartcardDebug(DEBUG_DRIVER,
  1568. ("%s!DevicePowerState = %s\n",DRIVER_NAME,
  1569. CMUSB_StringForDevState(irpStack->Parameters.Power.State.DeviceState)));
  1570. // For requests to DeviceState D0 ( fully on ), sets fGoingToD0 flag TRUE
  1571. // to flag that we must set a completion routine and update
  1572. // DeviceExtension->CurrentDevicePowerState there.
  1573. // In the case of powering up to fully on, we really want to make sure
  1574. // the process is completed before updating our CurrentDevicePowerState,
  1575. // so no IO will be attempted or accepted before we're really ready.
  1576. fGoingToD0 = CMUSB_SetDevicePowerState(DeviceObject,
  1577. irpStack->Parameters.Power.State.DeviceState); // returns TRUE for D0
  1578. IoCopyCurrentIrpStackLocationToNext(Irp);
  1579. if (fGoingToD0 == TRUE)
  1580. {
  1581. SmartcardDebug( DEBUG_DRIVER,("%s!going to D0\n",DRIVER_NAME));
  1582. IoSetCompletionRoutine(Irp,
  1583. CMUSB_PowerIrp_Complete,
  1584. // Always pass FDO to completion routine as its Context;
  1585. // This is because the DriverObject passed by the system to the routine
  1586. // is the Physical Device Object ( PDO ) not the Functional Device Object ( FDO )
  1587. DeviceObject,
  1588. TRUE, // invoke on success
  1589. TRUE, // invoke on error
  1590. TRUE); // invoke on cancellation of the Irp
  1591. }
  1592. PoStartNextPowerIrp(Irp);
  1593. NTStatus = PoCallDriver(DeviceExtension->TopOfStackDeviceObject,
  1594. Irp);
  1595. if (fGoingToD0 == FALSE) // completion routine will decrement
  1596. CMUSB_DecrementIoCount(DeviceObject);
  1597. break;
  1598. } /* case irpStack->Parameters.Power.Type */
  1599. break; /* IRP_MN_SET_POWER */
  1600. // ------------------
  1601. // IRP_MN_QUERY_POWER
  1602. // ------------------
  1603. case IRP_MN_QUERY_POWER:
  1604. //
  1605. // A power policy manager sends this IRP to determine whether it can change
  1606. // the system or device power state, typically to go to sleep.
  1607. //
  1608. SmartcardDebug(DEBUG_DRIVER,
  1609. ("%s!IRP_MN_QUERY_POWER received\n",DRIVER_NAME));
  1610. switch (irpStack->Parameters.Power.Type)
  1611. {
  1612. // +++++++++++++++++++
  1613. // SystemPowerState
  1614. // +++++++++++++++++++
  1615. case SystemPowerState:
  1616. SmartcardDebug( DEBUG_DRIVER,
  1617. ("%s!SystemPowerState = %s\n",DRIVER_NAME,
  1618. CMUSB_StringForSysState(irpStack->Parameters.Power.State.SystemState)));
  1619. break;
  1620. // ++++++++++++++++++
  1621. // DevicePowerState
  1622. // ++++++++++++++++++
  1623. case DevicePowerState:
  1624. // For requests to D1, D2, or D3 ( sleep or off states ),
  1625. // sets DeviceExtension->CurrentDevicePowerState to DeviceState immediately.
  1626. // This enables any code checking state to consider us as sleeping or off
  1627. // already, as this will imminently become our state.
  1628. SmartcardDebug(DEBUG_DRIVER,
  1629. ("%s!DevicePowerState = %s\n",DRIVER_NAME,
  1630. CMUSB_StringForDevState(irpStack->Parameters.Power.State.DeviceState)));
  1631. break;
  1632. }
  1633. // we do nothing special here, just let the PDO handle it
  1634. IoCopyCurrentIrpStackLocationToNext(Irp);
  1635. PoStartNextPowerIrp(Irp);
  1636. NTStatus = PoCallDriver(DeviceExtension->TopOfStackDeviceObject,
  1637. Irp);
  1638. CMUSB_DecrementIoCount(DeviceObject);
  1639. break; /* IRP_MN_QUERY_POWER */
  1640. default:
  1641. SmartcardDebug(DEBUG_DRIVER,
  1642. ("%s!unknown POWER IRP received\n",DRIVER_NAME));
  1643. //
  1644. // All unhandled power messages are passed on to the PDO
  1645. //
  1646. IoCopyCurrentIrpStackLocationToNext(Irp);
  1647. PoStartNextPowerIrp(Irp);
  1648. NTStatus = PoCallDriver(DeviceExtension->TopOfStackDeviceObject, Irp);
  1649. CMUSB_DecrementIoCount(DeviceObject);
  1650. } /* irpStack->MinorFunction */
  1651. SmartcardDebug( DEBUG_TRACE,
  1652. ("%s!ProcessPowerIrp Exit %lx\n",DRIVER_NAME,NTStatus));
  1653. return NTStatus;
  1654. }
  1655. /*****************************************************************************
  1656. Routine Description:
  1657. This is the completion routine set in a call to PoRequestPowerIrp()
  1658. that was made in CMUSB_ProcessPowerIrp() in response to receiving
  1659. an IRP_MN_SET_POWER of type 'SystemPowerState' when the device was
  1660. not in a compatible device power state. In this case, a pointer to
  1661. the IRP_MN_SET_POWER Irp is saved into the FDO device extension
  1662. (DeviceExtension->PowerIrp), and then a call must be
  1663. made to PoRequestPowerIrp() to put the device into a proper power state,
  1664. and this routine is set as the completion routine.
  1665. We decrement our pending io count and pass the saved IRP_MN_SET_POWER Irp
  1666. on to the next driver
  1667. Arguments:
  1668. DeviceObject - Pointer to the device object for the class device.
  1669. Note that we must get our own device object from the Context
  1670. Context - Driver defined context, in this case our own functional device object ( FDO )
  1671. Return Value:
  1672. The function value is the final NTStatus from the operation.
  1673. *****************************************************************************/
  1674. NTSTATUS CMUSB_PoRequestCompletion(
  1675. IN PDEVICE_OBJECT DeviceObject,
  1676. IN UCHAR MinorFunction,
  1677. IN POWER_STATE PowerState,
  1678. IN PVOID Context,
  1679. IN PIO_STATUS_BLOCK IoStatus
  1680. )
  1681. {
  1682. PIRP irp;
  1683. PDEVICE_EXTENSION DeviceExtension;
  1684. PDEVICE_OBJECT deviceObject = Context;
  1685. NTSTATUS NTStatus;
  1686. SmartcardDebug(DEBUG_TRACE,("%s!PoRequestCompletion Enter\n",DRIVER_NAME));
  1687. DeviceExtension = deviceObject->DeviceExtension;
  1688. // Get the Irp we saved for later processing in CMUSB_ProcessPowerIrp()
  1689. // when we decided to request the Power Irp that this routine
  1690. // is the completion routine for.
  1691. irp = DeviceExtension->PowerIrp;
  1692. // We will return the NTStatus set by the PDO for the power request we're completing
  1693. NTStatus = IoStatus->Status;
  1694. // we should not be in the midst of handling a self-generated power irp
  1695. CMUSB_ASSERT( !DeviceExtension->SelfPowerIrp );
  1696. // we must pass down to the next driver in the stack
  1697. IoCopyCurrentIrpStackLocationToNext(irp);
  1698. // Calling PoStartNextPowerIrp() indicates that the driver is finished
  1699. // with the previous power IRP, if any, and is ready to handle the next power IRP.
  1700. // It must be called for every power IRP.Although power IRPs are completed only once,
  1701. // typically by the lowest-level driver for a device, PoStartNextPowerIrp must be called
  1702. // for every stack location. Drivers must call PoStartNextPowerIrp while the current IRP
  1703. // stack location points to the current driver. Therefore, this routine must be called
  1704. // before IoCompleteRequest, IoSkipCurrentStackLocation, and PoCallDriver.
  1705. PoStartNextPowerIrp(irp);
  1706. // PoCallDriver is used to pass any power IRPs to the PDO instead of IoCallDriver.
  1707. // When passing a power IRP down to a lower-level driver, the caller should use
  1708. // IoSkipCurrentIrpStackLocation or IoCopyCurrentIrpStackLocationToNext to copy the IRP to
  1709. // the next stack location, then call PoCallDriver. Use IoCopyCurrentIrpStackLocationToNext
  1710. // if processing the IRP requires setting a completion routine, or IoSkipCurrentStackLocation
  1711. // if no completion routine is needed.
  1712. PoCallDriver(DeviceExtension->TopOfStackDeviceObject,irp);
  1713. CMUSB_DecrementIoCount(deviceObject);
  1714. DeviceExtension->PowerIrp = NULL;
  1715. SmartcardDebug(DEBUG_TRACE,("%s!PoRequestCompletion Exit %lx\n",DRIVER_NAME,NTStatus));
  1716. return NTStatus;
  1717. }
  1718. /*****************************************************************************
  1719. Routine Description:
  1720. This routine is called when An IRP_MN_SET_POWER of type 'DevicePowerState'
  1721. has been received by CMUSB_ProcessPowerIrp(), and that routine has determined
  1722. 1) the request is for full powerup ( to PowerDeviceD0 ), and
  1723. 2) We are not already in that state
  1724. A call is then made to PoRequestPowerIrp() with this routine set as the completion routine.
  1725. Arguments:
  1726. DeviceObject - Pointer to the device object for the class device.
  1727. Irp - Irp completed.
  1728. Context - Driver defined context.
  1729. Return Value:
  1730. The function value is the final NTStatus from the operation.
  1731. *****************************************************************************/
  1732. NTSTATUS CMUSB_PowerIrp_Complete(
  1733. IN PDEVICE_OBJECT NullDeviceObject,
  1734. IN PIRP Irp,
  1735. IN PVOID Context
  1736. )
  1737. {
  1738. NTSTATUS NTStatus = STATUS_SUCCESS;
  1739. PDEVICE_OBJECT deviceObject;
  1740. PIO_STACK_LOCATION irpStack;
  1741. PDEVICE_EXTENSION DeviceExtension;
  1742. SmartcardDebug(DEBUG_TRACE,("%s!PowerIrp_Complete Enter\n",DRIVER_NAME));
  1743. deviceObject = (PDEVICE_OBJECT) Context;
  1744. DeviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;
  1745. // if there was a card in the reader set the state to unknown,
  1746. // because we dont know if the card instered is the same as before power down
  1747. if (DeviceExtension->SmartcardExtension.ReaderExtension->ulNewCardState == INSERTED ||
  1748. DeviceExtension->SmartcardExtension.ReaderExtension->ulNewCardState == POWERED )
  1749. {
  1750. DeviceExtension->SmartcardExtension.ReaderExtension->ulOldCardState = UNKNOWN;
  1751. DeviceExtension->SmartcardExtension.ReaderExtension->ulNewCardState = UNKNOWN;
  1752. }
  1753. KeSetEvent(&DeviceExtension->CanRunUpdateThread, 0, FALSE);
  1754. // If the lower driver returned PENDING, mark our stack location as pending also.
  1755. if (Irp->PendingReturned == TRUE)
  1756. {
  1757. IoMarkIrpPending(Irp);
  1758. }
  1759. irpStack = IoGetCurrentIrpStackLocation (Irp);
  1760. // We can assert that we're a device powerup-to D0 request,
  1761. // because that was the only type of request we set a completion routine
  1762. // for in the first place
  1763. CMUSB_ASSERT(irpStack->MajorFunction == IRP_MJ_POWER);
  1764. CMUSB_ASSERT(irpStack->MinorFunction == IRP_MN_SET_POWER);
  1765. CMUSB_ASSERT(irpStack->Parameters.Power.Type==DevicePowerState);
  1766. CMUSB_ASSERT(irpStack->Parameters.Power.State.DeviceState==PowerDeviceD0);
  1767. // Now that we know we've let the lower drivers do what was needed to power up,
  1768. // we can set our device extension flags accordingly
  1769. DeviceExtension->CurrentDevicePowerState = PowerDeviceD0;
  1770. Irp->IoStatus.Status = NTStatus;
  1771. CMUSB_DecrementIoCount(deviceObject);
  1772. KeSetEvent(&DeviceExtension->ReaderEnabled, 0, FALSE);
  1773. SmartcardDebug(DEBUG_TRACE,("%s!PowerIrp_Complete Exit %lx\n",DRIVER_NAME,NTStatus));
  1774. return NTStatus;
  1775. }
  1776. /*****************************************************************************
  1777. Routine Description:
  1778. Called on CMUSB_PnPAddDevice() to power down until needed (i.e., till a pipe is actually opened).
  1779. Called on CMUSB_Create() to power up device to D0 before opening 1st pipe.
  1780. Called on CMUSB_Close() to power down device if this is the last pipe.
  1781. Arguments:
  1782. DeviceObject - Pointer to the device object
  1783. fSuspend; TRUE to Suspend, FALSE to acivate.
  1784. Return Value:
  1785. If the operation is not attemtped, SUCCESS is returned.
  1786. If the operation is attemtped, the value is the final NTStatus from the operation.
  1787. *****************************************************************************/
  1788. NTSTATUS CMUSB_SelfSuspendOrActivate(
  1789. IN PDEVICE_OBJECT DeviceObject,
  1790. IN BOOLEAN fSuspend
  1791. )
  1792. {
  1793. NTSTATUS NTStatus = STATUS_SUCCESS;
  1794. POWER_STATE PowerState;
  1795. PDEVICE_EXTENSION DeviceExtension;
  1796. DeviceExtension = DeviceObject->DeviceExtension;
  1797. SmartcardDebug( DEBUG_TRACE,("%s!SelfSuspendOrActivate: Enter, fSuspend = %d\n",DRIVER_NAME,fSuspend));
  1798. // Can't accept request if:
  1799. // 1) device is removed,
  1800. // 2) has never been started,
  1801. // 3) is stopped,
  1802. // 4) has a remove request pending,
  1803. // 5) has a stop device pending
  1804. if (CMUSB_CanAcceptIoRequests( DeviceObject ) == FALSE)
  1805. {
  1806. NTStatus = STATUS_DELETE_PENDING;
  1807. SmartcardDebug( DEBUG_TRACE,("%s!SelfSuspendOrActivate: ABORTING\n",DRIVER_NAME));
  1808. return NTStatus;
  1809. }
  1810. // don't do anything if any System-generated Device Pnp irps are pending
  1811. if ( DeviceExtension->PowerIrp != NULL)
  1812. {
  1813. SmartcardDebug( DEBUG_TRACE,("%s!SelfSuspendOrActivate: Exit, refusing on pending DeviceExtension->PowerIrp 0x%x\n",DRIVER_NAME,DeviceExtension->PowerIrp));
  1814. return NTStatus;
  1815. }
  1816. // don't do anything if any self-generated Device Pnp irps are pending
  1817. if ( DeviceExtension->SelfPowerIrp == TRUE)
  1818. {
  1819. SmartcardDebug( DEBUG_TRACE,("%s!SelfSuspendOrActivate: Exit, refusing on pending DeviceExtension->SelfPowerIrp\n",DRIVER_NAME));
  1820. return NTStatus;
  1821. }
  1822. // dont do anything if registry CurrentControlSet\Services\CMUSB\Parameters\PowerDownLevel
  1823. // has been set to zero, PowerDeviceD0 ( 1 ), or a bogus high value
  1824. if ( ( DeviceExtension->PowerDownLevel == PowerDeviceD0 ) ||
  1825. ( DeviceExtension->PowerDownLevel == PowerDeviceUnspecified) ||
  1826. ( DeviceExtension->PowerDownLevel >= PowerDeviceMaximum ) )
  1827. {
  1828. SmartcardDebug( DEBUG_TRACE,("%s!SelfSuspendOrActivate: Exit, refusing on DeviceExtension->PowerDownLevel == %d\n",DRIVER_NAME,DeviceExtension->PowerDownLevel));
  1829. return NTStatus;
  1830. }
  1831. if ( fSuspend == TRUE)
  1832. PowerState.DeviceState = DeviceExtension->PowerDownLevel;
  1833. else
  1834. PowerState.DeviceState = PowerDeviceD0; // power up all the way; we're probably just about to do some IO
  1835. NTStatus = CMUSB_SelfRequestPowerIrp( DeviceObject, PowerState );
  1836. SmartcardDebug( DEBUG_TRACE,("%s!SelfSuspendOrActivate: Exit, NTStatus 0x%x on setting dev state %s\n",DRIVER_NAME,NTStatus, CMUSB_StringForDevState(PowerState.DeviceState ) ));
  1837. return NTStatus;
  1838. }
  1839. /*****************************************************************************
  1840. Routine Description:
  1841. This routine is called by CMUSB_SelfSuspendOrActivate() to
  1842. actually make the system request for a powerdown/up to PowerState.
  1843. It first checks to see if we are already in Powerstate and immediately
  1844. returns SUCCESS with no further processing if so
  1845. Arguments:
  1846. DeviceObject - Pointer to the device object
  1847. PowerState. power state requested, e.g PowerDeviceD0.
  1848. Return Value:
  1849. The function value is the final NTStatus from the operation.
  1850. *****************************************************************************/
  1851. NTSTATUS CMUSB_SelfRequestPowerIrp(
  1852. IN PDEVICE_OBJECT DeviceObject,
  1853. IN POWER_STATE PowerState
  1854. )
  1855. {
  1856. NTSTATUS NTStatus = STATUS_SUCCESS;
  1857. NTSTATUS waitStatus;
  1858. PDEVICE_EXTENSION DeviceExtension;
  1859. PIRP pIrp = NULL;
  1860. SmartcardDebug(DEBUG_TRACE,
  1861. ("%s!SelfRequestPowerIrp: request power irp to state %s\n",DRIVER_NAME));
  1862. DeviceExtension = DeviceObject->DeviceExtension;
  1863. // This should have been reset in completion routine
  1864. CMUSB_ASSERT( !DeviceExtension->SelfPowerIrp );
  1865. if ( DeviceExtension->CurrentDevicePowerState == PowerState.DeviceState )
  1866. return STATUS_SUCCESS; // nothing to do
  1867. SmartcardDebug(DEBUG_DRIVER,
  1868. ("%s!SelfRequestPowerIrp: request power irp to state %s\n",DRIVER_NAME,
  1869. CMUSB_StringForDevState( PowerState.DeviceState )));
  1870. CMUSB_IncrementIoCount(DeviceObject);
  1871. // flag we're handling a self-generated power irp
  1872. DeviceExtension->SelfPowerIrp = TRUE;
  1873. // actually request the Irp
  1874. NTStatus = PoRequestPowerIrp(DeviceExtension->PhysicalDeviceObject,
  1875. IRP_MN_SET_POWER,
  1876. PowerState,
  1877. CMUSB_PoSelfRequestCompletion,
  1878. DeviceObject,
  1879. NULL);
  1880. if ( NTStatus == STATUS_PENDING )
  1881. {
  1882. // NTStatus pending is the return code we wanted
  1883. // We only need to wait for completion if we're powering up
  1884. if ( (ULONG) PowerState.DeviceState < DeviceExtension->PowerDownLevel )
  1885. {
  1886. waitStatus = KeWaitForSingleObject(&DeviceExtension->SelfRequestedPowerIrpEvent,
  1887. Suspended,
  1888. KernelMode,
  1889. FALSE,
  1890. NULL);
  1891. }
  1892. NTStatus = STATUS_SUCCESS;
  1893. DeviceExtension->SelfPowerIrp = FALSE;
  1894. }
  1895. else
  1896. {
  1897. // The return NTStatus was not STATUS_PENDING; any other codes must be considered in error here;
  1898. // i.e., it is not possible to get a STATUS_SUCCESS or any other non-error return from this call;
  1899. }
  1900. SmartcardDebug(DEBUG_TRACE,
  1901. ("%s!SelfRequestPowerIrp: Exit %lx\n",DRIVER_NAME,NTStatus));
  1902. return NTStatus;
  1903. }
  1904. /*****************************************************************************
  1905. Routine Description:
  1906. This routine is called when the driver completes a self-originated power IRP
  1907. that was generated by a call to CMUSB_SelfSuspendOrActivate().
  1908. We power down whenever the last pipe is closed and power up when the first pipe is opened.
  1909. For power-up , we set an event in our FDO extension to signal this IRP done
  1910. so the power request can be treated as a synchronous call.
  1911. We need to know the device is powered up before opening the first pipe, for example.
  1912. For power-down, we do not set the event, as no caller waits for powerdown complete.
  1913. Arguments:
  1914. DeviceObject - Pointer to the device object for the class device. ( Physical Device Object )
  1915. Context - Driver defined context, in this case our FDO ( functional device object )
  1916. Return Value:
  1917. The function value is the final NTStatus from the operation.
  1918. *****************************************************************************/
  1919. NTSTATUS CMUSB_PoSelfRequestCompletion(
  1920. IN PDEVICE_OBJECT DeviceObject,
  1921. IN UCHAR MinorFunction,
  1922. IN POWER_STATE PowerState,
  1923. IN PVOID Context,
  1924. IN PIO_STATUS_BLOCK IoStatus
  1925. )
  1926. {
  1927. PDEVICE_OBJECT deviceObject = Context;
  1928. PDEVICE_EXTENSION DeviceExtension = deviceObject->DeviceExtension;
  1929. NTSTATUS NTStatus = IoStatus->Status;
  1930. // we should not be in the midst of handling a system-generated power irp
  1931. CMUSB_ASSERT( NULL == DeviceExtension->PowerIrp );
  1932. // We only need to set the event if we're powering up;
  1933. // No caller waits on power down complete
  1934. if ( (ULONG) PowerState.DeviceState < DeviceExtension->PowerDownLevel )
  1935. {
  1936. // Trigger Self-requested power irp completed event;
  1937. // The caller is waiting for completion
  1938. KeSetEvent(&DeviceExtension->SelfRequestedPowerIrpEvent, 1, FALSE);
  1939. }
  1940. CMUSB_DecrementIoCount(deviceObject);
  1941. return NTStatus;
  1942. }
  1943. /*****************************************************************************
  1944. Routine Description:
  1945. This routine is called when An IRP_MN_SET_POWER of type 'DevicePowerState'
  1946. has been received by CMUSB_ProcessPowerIrp().
  1947. Arguments:
  1948. DeviceObject - Pointer to the device object for the class device.
  1949. DeviceState - Device specific power state to set the device in to.
  1950. Return Value:
  1951. For requests to DeviceState D0 ( fully on ), returns TRUE to signal caller
  1952. that we must set a completion routine and finish there.
  1953. *****************************************************************************/
  1954. BOOLEAN CMUSB_SetDevicePowerState(
  1955. IN PDEVICE_OBJECT DeviceObject,
  1956. IN DEVICE_POWER_STATE DeviceState
  1957. )
  1958. {
  1959. NTSTATUS NTStatus = STATUS_SUCCESS;
  1960. PDEVICE_EXTENSION DeviceExtension;
  1961. BOOLEAN fRes = FALSE;
  1962. SmartcardDebug(DEBUG_TRACE,("%s!SetDevicePowerState Enter\n",DRIVER_NAME));
  1963. DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  1964. switch (DeviceState)
  1965. {
  1966. case PowerDeviceD3:
  1967. SmartcardDebug(DEBUG_DRIVER,
  1968. ("%s!SetDevicePowerState PowerDeviceD3 \n",DRIVER_NAME));
  1969. DeviceExtension->CurrentDevicePowerState = DeviceState;
  1970. KeClearEvent(&DeviceExtension->ReaderEnabled);
  1971. CMUSB_StopCardTracking(DeviceObject);
  1972. break;
  1973. case PowerDeviceD1:
  1974. case PowerDeviceD2:
  1975. SmartcardDebug(DEBUG_DRIVER,
  1976. ("%s!SetDevicePowerState PowerDeviceD1/2 \n",DRIVER_NAME));
  1977. //
  1978. // power states D1,D2 translate to USB suspend
  1979. DeviceExtension->CurrentDevicePowerState = DeviceState;
  1980. break;
  1981. case PowerDeviceD0:
  1982. SmartcardDebug(DEBUG_DRIVER,
  1983. ("%s!SetDevicePowerState PowerDeviceD0 \n",DRIVER_NAME));
  1984. // We'll need to finish the rest in the completion routine;
  1985. // signal caller we're going to D0 and will need to set a completion routine
  1986. fRes = TRUE;
  1987. // Caller will pass on to PDO ( Physical Device object )
  1988. //
  1989. // start update thread be signal that it should not run now
  1990. // this thread should be started in completion rourine
  1991. // but there we have a wrong IRQL for creating a thread
  1992. //
  1993. KeClearEvent(&DeviceExtension->CanRunUpdateThread);
  1994. NTStatus = CMUSB_StartCardTracking(DeviceObject);
  1995. break;
  1996. default:
  1997. SmartcardDebug(DEBUG_DRIVER,
  1998. ("%s!SetDevicePowerState Inalid device power state \n",DRIVER_NAME));
  1999. }
  2000. SmartcardDebug(DEBUG_TRACE,
  2001. ("%s!SetDevicePowerState Exit\n",DRIVER_NAME));
  2002. return fRes;
  2003. }
  2004. /*****************************************************************************
  2005. Routine Description:
  2006. This routine generates an internal IRP from this driver to the PDO
  2007. to obtain information on the Physical Device Object's capabilities.
  2008. We are most interested in learning which system power states
  2009. are to be mapped to which device power states for honoring IRP_MJ_SET_POWER Irps.
  2010. This is a blocking call which waits for the IRP completion routine
  2011. to set an event on finishing.
  2012. Arguments:
  2013. DeviceObject - Physical DeviceObject for this USB controller.
  2014. Return Value:
  2015. NTSTATUS value from the IoCallDriver() call.
  2016. *****************************************************************************/
  2017. NTSTATUS CMUSB_QueryCapabilities(
  2018. IN PDEVICE_OBJECT PdoDeviceObject,
  2019. IN PDEVICE_CAPABILITIES DeviceCapabilities
  2020. )
  2021. {
  2022. PIO_STACK_LOCATION nextStack;
  2023. PIRP irp;
  2024. NTSTATUS NTStatus;
  2025. KEVENT event;
  2026. // This is a DDK-defined DBG-only macro that ASSERTS we are not running pageable code
  2027. // at higher than APC_LEVEL.
  2028. PAGED_CODE();
  2029. // Build an IRP for us to generate an internal query request to the PDO
  2030. irp = IoAllocateIrp(PdoDeviceObject->StackSize, FALSE);
  2031. if (irp == NULL)
  2032. {
  2033. return STATUS_INSUFFICIENT_RESOURCES;
  2034. }
  2035. //
  2036. // Preinit the device capability structures appropriately.
  2037. //
  2038. RtlZeroMemory( DeviceCapabilities, sizeof(DEVICE_CAPABILITIES) );
  2039. DeviceCapabilities->Size = sizeof(DEVICE_CAPABILITIES);
  2040. DeviceCapabilities->Version = 1;
  2041. DeviceCapabilities->Address = -1;
  2042. DeviceCapabilities->UINumber = -1;
  2043. // IoGetNextIrpStackLocation gives a higher level driver access to the next-lower
  2044. // driver's I/O stack location in an IRP so the caller can set it up for the lower driver.
  2045. nextStack = IoGetNextIrpStackLocation(irp);
  2046. CMUSB_ASSERT(nextStack != NULL);
  2047. nextStack->MajorFunction= IRP_MJ_PNP;
  2048. nextStack->MinorFunction= IRP_MN_QUERY_CAPABILITIES;
  2049. // init an event to tell us when the completion routine's been called
  2050. KeInitializeEvent(&event, NotificationEvent, FALSE);
  2051. // Set a completion routine so it can signal our event when
  2052. // the next lower driver is done with the Irp
  2053. IoSetCompletionRoutine(irp,
  2054. CMUSB_IrpCompletionRoutine,
  2055. &event, // pass the event as Context to completion routine
  2056. TRUE, // invoke on success
  2057. TRUE, // invoke on error
  2058. TRUE); // invoke on cancellation of the Irp
  2059. // set our pointer to the DEVICE_CAPABILITIES struct
  2060. nextStack->Parameters.DeviceCapabilities.Capabilities = DeviceCapabilities;
  2061. // preset the irp to report not supported
  2062. irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
  2063. NTStatus = IoCallDriver(PdoDeviceObject,
  2064. irp);
  2065. if (NTStatus == STATUS_PENDING)
  2066. {
  2067. // wait for irp to complete
  2068. KeWaitForSingleObject(&event,
  2069. Suspended,
  2070. KernelMode,
  2071. FALSE,
  2072. NULL);
  2073. NTStatus = irp->IoStatus.Status;
  2074. }
  2075. IoFreeIrp(irp);
  2076. return NTStatus;
  2077. }
  2078. /*****************************************************************************
  2079. Routine Description:
  2080. Installable driver initialization entry point.
  2081. This entry point is called directly by the I/O system.
  2082. Arguments:
  2083. Return Value:
  2084. *****************************************************************************/
  2085. NTSTATUS DriverEntry(
  2086. IN PDRIVER_OBJECT DriverObject,
  2087. IN PUNICODE_STRING RegistryPath
  2088. )
  2089. {
  2090. NTSTATUS NTStatus = STATUS_SUCCESS;
  2091. PDEVICE_OBJECT deviceObject = NULL;
  2092. BOOLEAN fRes;
  2093. ULONG ulIndex;
  2094. //#if DBG
  2095. // SmartcardSetDebugLevel(DEBUG_ALL);
  2096. //#endif
  2097. SmartcardDebug(DEBUG_TRACE,
  2098. ("%s!DriverEntry: Enter - %s %s\n",DRIVER_NAME,__DATE__,__TIME__));
  2099. //
  2100. // Create dispatch points for create, close, unload
  2101. DriverObject->MajorFunction[IRP_MJ_CREATE] = CMUSB_CreateClose;
  2102. DriverObject->MajorFunction[IRP_MJ_CLOSE] = CMUSB_CreateClose;
  2103. DriverObject->MajorFunction[IRP_MJ_CLEANUP] = CMUSB_Cleanup;
  2104. DriverObject->DriverUnload = CMUSB_Unload;
  2105. // User mode DeviceIoControl() calls will be routed here
  2106. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = CMUSB_ProcessIOCTL;
  2107. // routines for handling system PNP and power management requests
  2108. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = CMUSB_ProcessSysControlIrp;
  2109. DriverObject->MajorFunction[IRP_MJ_PNP] = CMUSB_ProcessPnPIrp;
  2110. DriverObject->MajorFunction[IRP_MJ_POWER] = CMUSB_ProcessPowerIrp;
  2111. // The Functional Device Object (FDO) will not be created for PNP devices until
  2112. // this routine is called upon device plug-in.
  2113. DriverObject->DriverExtension->AddDevice = CMUSB_PnPAddDevice;
  2114. for (ulIndex = 0;ulIndex < MAXIMUM_OEM_NAMES;ulIndex++)
  2115. {
  2116. OemName[ulIndex].Buffer = OemNameBuffer[ulIndex];
  2117. OemName[ulIndex].MaximumLength = sizeof(OemNameBuffer[ulIndex]);
  2118. }
  2119. SmartcardDebug(DEBUG_TRACE,
  2120. ("%s!DriverEntry: Exit\n",DRIVER_NAME));
  2121. return NTStatus;
  2122. }
  2123. /*****************************************************************************
  2124. Routine Description:
  2125. Main dispatch table routine for IRP_MJ_SYSTEM_CONTROL
  2126. We basically just pass these down to the PDO
  2127. Arguments:
  2128. DeviceObject - pointer to FDO device object
  2129. Irp - pointer to an I/O Request Packet
  2130. Return Value:
  2131. Status returned from lower driver
  2132. *****************************************************************************/
  2133. NTSTATUS CMUSB_ProcessSysControlIrp(
  2134. IN PDEVICE_OBJECT DeviceObject,
  2135. IN PIRP Irp
  2136. )
  2137. {
  2138. PIO_STACK_LOCATION irpStack;
  2139. PDEVICE_EXTENSION DeviceExtension;
  2140. NTSTATUS NTStatus = STATUS_SUCCESS;
  2141. NTSTATUS waitStatus;
  2142. PDEVICE_OBJECT stackDeviceObject;
  2143. //
  2144. // Get a pointer to the current location in the Irp. This is where
  2145. // the function codes and parameters are located.
  2146. //
  2147. irpStack = IoGetCurrentIrpStackLocation (Irp);
  2148. //
  2149. // Get a pointer to the device extension
  2150. //
  2151. DeviceExtension = DeviceObject->DeviceExtension;
  2152. stackDeviceObject = DeviceExtension->TopOfStackDeviceObject;
  2153. CMUSB_IncrementIoCount(DeviceObject);
  2154. CMUSB_ASSERT( IRP_MJ_SYSTEM_CONTROL == irpStack->MajorFunction );
  2155. IoCopyCurrentIrpStackLocationToNext(Irp);
  2156. NTStatus = IoCallDriver(stackDeviceObject,
  2157. Irp);
  2158. CMUSB_DecrementIoCount(DeviceObject);
  2159. return NTStatus;
  2160. }
  2161. /*****************************************************************************
  2162. Routine Description:
  2163. Free all the allocated resources, etc.
  2164. Arguments:
  2165. DriverObject - pointer to a driver object
  2166. Return Value:
  2167. *****************************************************************************/
  2168. VOID CMUSB_Unload(
  2169. IN PDRIVER_OBJECT DriverObject
  2170. )
  2171. {
  2172. SmartcardDebug(DEBUG_TRACE,
  2173. ("%s!Unload enter\n",DRIVER_NAME));
  2174. //
  2175. // Free any global resources allocated
  2176. // in DriverEntry.
  2177. // We have few or none because for a PNP device, almost all
  2178. // allocation is done in PnpAddDevice() and all freeing
  2179. // while handling IRP_MN_REMOVE_DEVICE:
  2180. //
  2181. SmartcardDebug(DEBUG_TRACE,
  2182. ("%s!Unload exit\n",DRIVER_NAME));
  2183. }
  2184. /*****************************************************************************
  2185. Routine Description:
  2186. Trys to read the reader name from the registry
  2187. Arguments:
  2188. DriverObject context of call
  2189. SmartcardExtension ptr to smartcard extension
  2190. Return Value:
  2191. none
  2192. ******************************************************************************/
  2193. NTSTATUS CMUSB_SetVendorAndIfdName(
  2194. IN PDEVICE_OBJECT PhysicalDeviceObject,
  2195. IN PSMARTCARD_EXTENSION SmartcardExtension
  2196. )
  2197. {
  2198. RTL_QUERY_REGISTRY_TABLE parameters[3];
  2199. UNICODE_STRING vendorNameU;
  2200. ANSI_STRING vendorNameA;
  2201. UNICODE_STRING ifdTypeU;
  2202. ANSI_STRING ifdTypeA;
  2203. HANDLE regKey = NULL;
  2204. ULONG ulIndex;
  2205. ULONG ulInstance;
  2206. CHAR strBuffer[64];
  2207. USHORT usStrLength;
  2208. RtlZeroMemory (parameters, sizeof(parameters));
  2209. RtlZeroMemory (&vendorNameU, sizeof(vendorNameU));
  2210. RtlZeroMemory (&vendorNameA, sizeof(vendorNameA));
  2211. RtlZeroMemory (&ifdTypeU, sizeof(ifdTypeU));
  2212. RtlZeroMemory (&ifdTypeA, sizeof(ifdTypeA));
  2213. try
  2214. {
  2215. //
  2216. // try to read the reader name from the registry
  2217. // if that does not work, we will use the default
  2218. // (hardcoded) name
  2219. //
  2220. if (IoOpenDeviceRegistryKey(PhysicalDeviceObject,
  2221. PLUGPLAY_REGKEY_DEVICE,
  2222. KEY_READ,
  2223. &regKey) != STATUS_SUCCESS)
  2224. {
  2225. SmartcardDebug(DEBUG_ERROR,
  2226. ("%s!SetVendorAndIfdName: IoOpenDeviceRegistryKey failed\n",DRIVER_NAME));
  2227. leave;
  2228. }
  2229. parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
  2230. parameters[0].Name = L"VendorName";
  2231. parameters[0].EntryContext = &vendorNameU;
  2232. parameters[0].DefaultType = REG_SZ;
  2233. parameters[0].DefaultData = &vendorNameU;
  2234. parameters[0].DefaultLength = 0;
  2235. parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
  2236. parameters[1].Name = L"IfdType";
  2237. parameters[1].EntryContext = &ifdTypeU;
  2238. parameters[1].DefaultType = REG_SZ;
  2239. parameters[1].DefaultData = &ifdTypeU;
  2240. parameters[1].DefaultLength = 0;
  2241. if (RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
  2242. (PWSTR) regKey,
  2243. parameters,
  2244. NULL,
  2245. NULL) != STATUS_SUCCESS)
  2246. {
  2247. SmartcardDebug(DEBUG_ERROR,
  2248. ("%s!SetVendorAndIfdName: RtlQueryRegistryValues failed\n",DRIVER_NAME));
  2249. leave;
  2250. }
  2251. if (RtlUnicodeStringToAnsiString(&vendorNameA,&vendorNameU,TRUE) != STATUS_SUCCESS)
  2252. {
  2253. SmartcardDebug(DEBUG_ERROR,
  2254. ("%s!SetVendorAndIfdName: RtlUnicodeStringToAnsiString failed\n",DRIVER_NAME));
  2255. leave;
  2256. }
  2257. if (RtlUnicodeStringToAnsiString(&ifdTypeA,&ifdTypeU,TRUE) != STATUS_SUCCESS)
  2258. {
  2259. SmartcardDebug(DEBUG_ERROR,
  2260. ("%s!SetVendorAndIfdName: RtlUnicodeStringToAnsiString failed\n",DRIVER_NAME));
  2261. leave;
  2262. }
  2263. if (vendorNameA.Length == 0 ||
  2264. vendorNameA.Length > MAXIMUM_ATTR_STRING_LENGTH ||
  2265. ifdTypeA.Length == 0 ||
  2266. ifdTypeA.Length > MAXIMUM_ATTR_STRING_LENGTH)
  2267. {
  2268. SmartcardDebug(DEBUG_ERROR,
  2269. ("%s!SetVendorAndIfdName: vendor name or ifdtype not found or to long\n",DRIVER_NAME));
  2270. leave;
  2271. }
  2272. RtlCopyMemory(SmartcardExtension->VendorAttr.VendorName.Buffer,
  2273. vendorNameA.Buffer,
  2274. vendorNameA.Length);
  2275. SmartcardExtension->VendorAttr.VendorName.Length = vendorNameA.Length;
  2276. RtlCopyMemory(SmartcardExtension->VendorAttr.IfdType.Buffer,
  2277. ifdTypeA.Buffer,
  2278. ifdTypeA.Length);
  2279. SmartcardExtension->VendorAttr.IfdType.Length = ifdTypeA.Length;
  2280. SmartcardDebug(DEBUG_DRIVER,
  2281. ("%s!SetVendorAndIfdName: overwritting vendor name and ifdtype\n",DRIVER_NAME));
  2282. }
  2283. finally
  2284. {
  2285. if (vendorNameU.Buffer != NULL)
  2286. {
  2287. RtlFreeUnicodeString(&vendorNameU);
  2288. }
  2289. if (vendorNameA.Buffer != NULL)
  2290. {
  2291. RtlFreeAnsiString(&vendorNameA);
  2292. }
  2293. if (ifdTypeU.Buffer != NULL)
  2294. {
  2295. RtlFreeUnicodeString(&ifdTypeU);
  2296. }
  2297. if (ifdTypeA.Buffer != NULL)
  2298. {
  2299. RtlFreeAnsiString(&ifdTypeA);
  2300. }
  2301. if (regKey != NULL)
  2302. {
  2303. ZwClose (regKey);
  2304. }
  2305. }
  2306. // correct the unit number
  2307. ifdTypeA.Buffer=strBuffer;
  2308. ifdTypeA.MaximumLength=sizeof(strBuffer);
  2309. usStrLength = (SmartcardExtension->VendorAttr.IfdType.Length < ifdTypeA.MaximumLength) ? SmartcardExtension->VendorAttr.IfdType.Length : ifdTypeA.MaximumLength;
  2310. RtlCopyMemory(ifdTypeA.Buffer,
  2311. SmartcardExtension->VendorAttr.IfdType.Buffer,
  2312. usStrLength);
  2313. ifdTypeA.Length = usStrLength;
  2314. ulIndex=0;
  2315. while (ulIndex < MAXIMUM_OEM_NAMES &&
  2316. OemName[ulIndex].Length > 0 &&
  2317. RtlCompareMemory (ifdTypeA.Buffer, OemName[ulIndex].Buffer, OemName[ulIndex].Length) != OemName[ulIndex].Length)
  2318. {
  2319. ulIndex++;
  2320. }
  2321. if (ulIndex == MAXIMUM_OEM_NAMES)
  2322. {
  2323. // maximum number of OEM names reached
  2324. return STATUS_INSUFFICIENT_RESOURCES;
  2325. }
  2326. if (OemName[ulIndex].Length == 0)
  2327. {
  2328. // new OEM reader name
  2329. usStrLength = (ifdTypeA.Length < OemName[ulIndex].MaximumLength) ? ifdTypeA.Length : OemName[ulIndex].MaximumLength;
  2330. RtlCopyMemory(OemName[ulIndex].Buffer,
  2331. ifdTypeA.Buffer,
  2332. usStrLength);
  2333. OemName[ulIndex].Length = usStrLength;
  2334. }
  2335. for (ulInstance = 0;ulInstance < MAXIMUM_USB_READERS;ulInstance++)
  2336. {
  2337. if (OemDeviceSlot[ulIndex][ulInstance] == FALSE)
  2338. {
  2339. OemDeviceSlot[ulIndex][ulInstance] = TRUE;
  2340. break;
  2341. }
  2342. }
  2343. if (ulInstance == MAXIMUM_USB_READERS)
  2344. {
  2345. return STATUS_INSUFFICIENT_RESOURCES;
  2346. }
  2347. SmartcardExtension->VendorAttr.UnitNo = ulInstance;
  2348. SmartcardExtension->ReaderExtension->ulOemDeviceInstance = ulInstance;
  2349. SmartcardExtension->ReaderExtension->ulOemNameIndex = ulIndex;
  2350. return STATUS_SUCCESS;
  2351. }
  2352. /*****************************************************************************
  2353. Routine Description:
  2354. Creates a Functional DeviceObject
  2355. Arguments:
  2356. DriverObject - pointer to the driver object for device
  2357. DeviceObject - pointer to DeviceObject pointer to return
  2358. created device object.
  2359. Instance - instance of the device create.
  2360. Return Value:
  2361. STATUS_SUCCESS if successful,
  2362. STATUS_UNSUCCESSFUL otherwise
  2363. *****************************************************************************/
  2364. NTSTATUS CMUSB_CreateDeviceObject(
  2365. IN PDRIVER_OBJECT DriverObject,
  2366. IN PDEVICE_OBJECT PhysicalDeviceObject,
  2367. IN PDEVICE_OBJECT *DeviceObject
  2368. )
  2369. {
  2370. UNICODE_STRING deviceNameUnicodeString;
  2371. UNICODE_STRING Tmp;
  2372. NTSTATUS NTStatus = STATUS_SUCCESS;
  2373. ULONG deviceInstance;
  2374. PDEVICE_EXTENSION DeviceExtension;
  2375. PREADER_EXTENSION readerExtension;
  2376. PSMARTCARD_EXTENSION SmartcardExtension;
  2377. WCHAR Buffer[64];
  2378. SmartcardDebug(DEBUG_TRACE,
  2379. ("%s!CreateDeviceObject: Enter\n",DRIVER_NAME));
  2380. for ( deviceInstance = 0;deviceInstance < MAXIMUM_USB_READERS;deviceInstance++ )
  2381. {
  2382. if (DeviceSlot[deviceInstance] == FALSE)
  2383. {
  2384. DeviceSlot[deviceInstance] = TRUE;
  2385. break;
  2386. }
  2387. }
  2388. if (deviceInstance == MAXIMUM_USB_READERS)
  2389. {
  2390. return STATUS_INSUFFICIENT_RESOURCES;
  2391. }
  2392. //
  2393. // construct the device name
  2394. //
  2395. deviceNameUnicodeString.Buffer = Buffer;
  2396. deviceNameUnicodeString.MaximumLength = sizeof(Buffer);
  2397. deviceNameUnicodeString.Length = 0;
  2398. RtlInitUnicodeString(&Tmp,CARDMAN_USB_DEVICE_NAME);
  2399. RtlCopyUnicodeString(&deviceNameUnicodeString,&Tmp);
  2400. Tmp.Buffer = deviceNameUnicodeString.Buffer + deviceNameUnicodeString.Length / sizeof(WCHAR);
  2401. Tmp.MaximumLength = 2 * sizeof(WCHAR);
  2402. Tmp.Length = 0;
  2403. RtlIntegerToUnicodeString(deviceInstance,10,&Tmp);
  2404. deviceNameUnicodeString.Length = (USHORT)( deviceNameUnicodeString.Length+Tmp.Length);
  2405. // Create the device object
  2406. NTStatus = IoCreateDevice(DriverObject,
  2407. sizeof(DEVICE_EXTENSION),
  2408. &deviceNameUnicodeString,
  2409. FILE_DEVICE_SMARTCARD,
  2410. 0,
  2411. TRUE,
  2412. DeviceObject);
  2413. if (NTStatus != STATUS_SUCCESS)
  2414. {
  2415. return NTStatus;
  2416. }
  2417. // ----------------------------------------------
  2418. // initialize device extension
  2419. // ----------------------------------------------
  2420. DeviceExtension = (*DeviceObject)->DeviceExtension;
  2421. DeviceExtension->DeviceInstance = deviceInstance;
  2422. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  2423. // Used for reading from pipe 1
  2424. KeInitializeEvent(&DeviceExtension->ReadP1Completed,
  2425. NotificationEvent,
  2426. FALSE);
  2427. // Used to keep track of open close calls
  2428. KeInitializeEvent(&DeviceExtension->RemoveEvent,
  2429. NotificationEvent,
  2430. TRUE);
  2431. KeInitializeSpinLock(&DeviceExtension->SpinLock);
  2432. // this event is triggered when self-requested power irps complete
  2433. KeInitializeEvent(&DeviceExtension->SelfRequestedPowerIrpEvent, NotificationEvent, FALSE);
  2434. // this event is triggered when there is no pending io (pending io count == 1 )
  2435. KeInitializeEvent(&DeviceExtension->NoPendingIoEvent, NotificationEvent, FALSE);
  2436. // Used for update thread notification after hibernation
  2437. KeInitializeEvent(&DeviceExtension->CanRunUpdateThread,
  2438. NotificationEvent,
  2439. TRUE);
  2440. // Blocks IOControls during hibernation
  2441. KeInitializeEvent(&DeviceExtension->ReaderEnabled,
  2442. NotificationEvent,
  2443. TRUE);
  2444. // ----------------------------------------------
  2445. // create reader extension
  2446. // ----------------------------------------------
  2447. SmartcardExtension->ReaderExtension = ExAllocatePool(NonPagedPool,
  2448. sizeof(READER_EXTENSION));
  2449. if (SmartcardExtension->ReaderExtension == NULL)
  2450. {
  2451. return STATUS_INSUFFICIENT_RESOURCES;
  2452. }
  2453. readerExtension = SmartcardExtension->ReaderExtension;
  2454. RtlZeroMemory(readerExtension, sizeof(READER_EXTENSION));
  2455. // ----------------------------------------------
  2456. // initialize timers
  2457. // ----------------------------------------------
  2458. KeInitializeTimer(&SmartcardExtension->ReaderExtension->WaitTimer);
  2459. KeInitializeTimer(&SmartcardExtension->ReaderExtension->P1Timer);
  2460. // ----------------------------------------------
  2461. // initialize mutex
  2462. // ----------------------------------------------
  2463. KeInitializeMutex(&SmartcardExtension->ReaderExtension->CardManIOMutex,0L);
  2464. // ----------------------------------------------
  2465. // create smartcard extension
  2466. // ----------------------------------------------
  2467. // write the version of the lib we use to the smartcard extension
  2468. SmartcardExtension->Version = SMCLIB_VERSION;
  2469. SmartcardExtension->SmartcardRequest.BufferSize = CMUSB_BUFFER_SIZE;
  2470. SmartcardExtension->SmartcardReply.BufferSize = CMUSB_REPLY_BUFFER_SIZE;
  2471. //
  2472. // Now let the lib allocate the buffer for data transmission
  2473. // We can either tell the lib how big the buffer should be
  2474. // by assigning a value to BufferSize or let the lib
  2475. // allocate the default size
  2476. //
  2477. NTStatus = SmartcardInitialize(SmartcardExtension);
  2478. if (NTStatus != STATUS_SUCCESS)
  2479. {
  2480. // free reader extension
  2481. ExFreePool(DeviceExtension->SmartcardExtension.ReaderExtension);
  2482. SmartcardExtension->ReaderExtension = NULL;
  2483. return NTStatus;
  2484. }
  2485. // ----------------------------------------------
  2486. // initialize smartcard extension
  2487. // ----------------------------------------------
  2488. // Save deviceObject
  2489. SmartcardExtension->OsData->DeviceObject = *DeviceObject;
  2490. // Set up call back functions
  2491. SmartcardExtension->ReaderFunction[RDF_TRANSMIT] = CMUSB_Transmit;
  2492. SmartcardExtension->ReaderFunction[RDF_SET_PROTOCOL] = CMUSB_SetProtocol;
  2493. SmartcardExtension->ReaderFunction[RDF_CARD_POWER] = CMUSB_CardPower;
  2494. SmartcardExtension->ReaderFunction[RDF_CARD_TRACKING] = CMUSB_CardTracking;
  2495. SmartcardExtension->ReaderFunction[RDF_IOCTL_VENDOR] = CMUSB_IoCtlVendor;
  2496. SmartcardExtension->ReaderExtension->ulDeviceInstance = deviceInstance;
  2497. CMUSB_InitializeSmartcardExtension(SmartcardExtension);
  2498. // try to overwrite with registry values
  2499. NTStatus = CMUSB_SetVendorAndIfdName(PhysicalDeviceObject, SmartcardExtension);
  2500. if (NTStatus != STATUS_SUCCESS)
  2501. {
  2502. // free reader extension
  2503. ExFreePool(DeviceExtension->SmartcardExtension.ReaderExtension);
  2504. SmartcardExtension->ReaderExtension = NULL;
  2505. return NTStatus;
  2506. }
  2507. // W2000 is till now the only OS which supports WDM version 1.10
  2508. // So check this to determine if we have an Plug&Play able resource manager
  2509. DeviceExtension->fPnPResourceManager = IoIsWdmVersionAvailable (1,10);
  2510. SmartcardDebug(DEBUG_DRIVER,
  2511. ("%s!CreateDeviceObject: fPnPManager=%ld\n",DRIVER_NAME,DeviceExtension->fPnPResourceManager));
  2512. if (DeviceExtension->fPnPResourceManager == TRUE)
  2513. {
  2514. if (DeviceExtension->PnPDeviceName.Buffer == NULL)
  2515. {
  2516. // register our new device
  2517. NTStatus = IoRegisterDeviceInterface(PhysicalDeviceObject,
  2518. &SmartCardReaderGuid,
  2519. NULL,
  2520. &DeviceExtension->PnPDeviceName);
  2521. SmartcardDebug(DEBUG_DRIVER,
  2522. ("%s!CreateDeviceObject: PnPDeviceName.Buffer = %lx\n",DRIVER_NAME,
  2523. DeviceExtension->PnPDeviceName.Buffer));
  2524. SmartcardDebug(DEBUG_DRIVER,
  2525. ("%s!CreateDeviceObject: PnPDeviceName.BufferLength = %lx\n",DRIVER_NAME,
  2526. DeviceExtension->PnPDeviceName.Length));
  2527. SmartcardDebug(DEBUG_DRIVER,
  2528. ("%s!CreateDeviceObject: IoRegisterDeviceInterface returned=%lx\n",DRIVER_NAME,NTStatus));
  2529. }
  2530. else
  2531. {
  2532. SmartcardDebug(DEBUG_DRIVER,
  2533. ("%s!CreateDeviceObject: Interface already exists\n",DRIVER_NAME));
  2534. }
  2535. }
  2536. else
  2537. {
  2538. // ----------------------------------------------
  2539. // create symbolic link
  2540. // ----------------------------------------------
  2541. NTStatus = SmartcardCreateLink(&DeviceExtension->DosDeviceName,&deviceNameUnicodeString);
  2542. SmartcardDebug(DEBUG_DRIVER,
  2543. ("%s!CreateDeviceObject: SmartcardCreateLink returned=%lx\n",DRIVER_NAME,NTStatus));
  2544. }
  2545. if (NTStatus != STATUS_SUCCESS)
  2546. {
  2547. ExFreePool(DeviceExtension->SmartcardExtension.ReaderExtension);
  2548. SmartcardExtension->ReaderExtension = NULL;
  2549. SmartcardExit(&DeviceExtension->SmartcardExtension);
  2550. IoDeleteDevice(*DeviceObject);
  2551. }
  2552. SmartcardDebug(DEBUG_TRACE,
  2553. ("%s!CreateDeviceObject: Exit %lx\n",DRIVER_NAME,NTStatus));
  2554. return NTStatus;
  2555. }
  2556. /*****************************************************************************
  2557. Routine Description:
  2558. Passes a URB to the USBD class driver
  2559. The client device driver passes USB request block (URB) structures
  2560. to the class driver as a parameter in an IRP with Irp->MajorFunction
  2561. set to IRP_MJ_INTERNAL_DEVICE_CONTROL and the next IRP stack location
  2562. Parameters.DeviceIoControl.IoControlCode field set to
  2563. IOCTL_INTERNAL_USB_SUBMIT_URB.
  2564. Arguments:
  2565. DeviceObject - pointer to the physical device object (PDO)
  2566. Urb - pointer to an already-formatted Urb request block
  2567. Return Value:
  2568. STATUS_SUCCESS if successful,
  2569. STATUS_UNSUCCESSFUL otherwise
  2570. *****************************************************************************/
  2571. NTSTATUS
  2572. CMUSB_CallUSBD(
  2573. IN PDEVICE_OBJECT DeviceObject,
  2574. IN PURB Urb
  2575. )
  2576. {
  2577. NTSTATUS NTStatus = STATUS_SUCCESS;
  2578. NTSTATUS DebugStatus;
  2579. PDEVICE_EXTENSION DeviceExtension;
  2580. PIRP irp;
  2581. KEVENT event;
  2582. IO_STATUS_BLOCK ioStatus;
  2583. PIO_STACK_LOCATION nextStack;
  2584. DeviceExtension = DeviceObject->DeviceExtension;
  2585. //
  2586. // issue a synchronous request
  2587. //
  2588. KeInitializeEvent(&event, NotificationEvent, FALSE);
  2589. irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB,
  2590. DeviceExtension->TopOfStackDeviceObject, //Points to the next-lower driver's device object
  2591. NULL, // optional input bufer; none needed here
  2592. 0, // input buffer len if used
  2593. NULL, // optional output bufer; none needed here
  2594. 0, // output buffer len if used
  2595. TRUE, // If InternalDeviceControl is TRUE the target driver's Dispatch
  2596. // outine for IRP_MJ_INTERNAL_DEVICE_CONTROL or IRP_MJ_SCSI
  2597. // is called; otherwise, the Dispatch routine for
  2598. // IRP_MJ_DEVICE_CONTROL is called.
  2599. &event, // event to be signalled on completion
  2600. &ioStatus); // Specifies an I/O NTStatus block to be set when the request is completed the lower driver.
  2601. if (irp == NULL)
  2602. {
  2603. NTStatus = STATUS_INSUFFICIENT_RESOURCES;
  2604. goto ExitCallUSBD;
  2605. }
  2606. //
  2607. // Call the class driver to perform the operation. If the returned NTStatus
  2608. // is PENDING, wait for the request to complete.
  2609. //
  2610. nextStack = IoGetNextIrpStackLocation(irp);
  2611. CMUSB_ASSERT(nextStack != NULL);
  2612. //
  2613. // pass the URB to the USB driver stack
  2614. //
  2615. nextStack->Parameters.Others.Argument1 = Urb;
  2616. NTStatus = IoCallDriver(DeviceExtension->TopOfStackDeviceObject, irp);
  2617. if (NTStatus == STATUS_PENDING)
  2618. {
  2619. DebugStatus = KeWaitForSingleObject(&event,
  2620. Suspended,
  2621. KernelMode,
  2622. FALSE,
  2623. NULL);
  2624. }
  2625. else
  2626. {
  2627. ioStatus.Status = NTStatus;
  2628. }
  2629. /*
  2630. SmartcardDebug( DEBUG_TRACE,("CMUSB_CallUSBD() URB NTStatus = %x NTStatus = %x irp NTStatus %x\n",
  2631. Urb->UrbHeader.Status, NTStatus, ioStatus.Status));
  2632. */
  2633. //
  2634. // USBD maps the error code for us
  2635. //
  2636. NTStatus = ioStatus.Status;
  2637. ExitCallUSBD:
  2638. return NTStatus;
  2639. }
  2640. /*****************************************************************************
  2641. Routine Description:
  2642. Initializes a given instance of the device on the USB and
  2643. selects and saves the configuration.
  2644. Arguments:
  2645. DeviceObject - pointer to the physical device object for this instance of the 82930
  2646. device.
  2647. Return Value:
  2648. NT NTStatus code
  2649. *****************************************************************************/
  2650. NTSTATUS
  2651. CMUSB_ConfigureDevice(
  2652. IN PDEVICE_OBJECT DeviceObject
  2653. )
  2654. {
  2655. PDEVICE_EXTENSION DeviceExtension;
  2656. NTSTATUS NTStatus;
  2657. PURB urb;
  2658. ULONG siz;
  2659. DeviceExtension = DeviceObject->DeviceExtension;
  2660. CMUSB_ASSERT( DeviceExtension->UsbConfigurationDescriptor == NULL );
  2661. urb = ExAllocatePool(NonPagedPool,
  2662. sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
  2663. if (urb == NULL)
  2664. return STATUS_INSUFFICIENT_RESOURCES;
  2665. // When USB_CONFIGURATION_DESCRIPTOR_TYPE is specified for DescriptorType
  2666. // in a call to UsbBuildGetDescriptorRequest(),
  2667. // all interface, endpoint, class-specific, and vendor-specific descriptors
  2668. // for the configuration also are retrieved.
  2669. // The caller must allocate a buffer large enough to hold all of this
  2670. // information or the data is truncated without error.
  2671. // Therefore the 'siz' set below is just a 'good guess', and we may have to retry
  2672. siz = sizeof(USB_CONFIGURATION_DESCRIPTOR) + 512;
  2673. // We will break out of this 'retry loop' when UsbBuildGetDescriptorRequest()
  2674. // has a big enough DeviceExtension->UsbConfigurationDescriptor buffer not to truncate
  2675. while ( 1 )
  2676. {
  2677. DeviceExtension->UsbConfigurationDescriptor = ExAllocatePool(NonPagedPool, siz);
  2678. if (DeviceExtension->UsbConfigurationDescriptor == NULL)
  2679. {
  2680. ExFreePool(urb);
  2681. return STATUS_INSUFFICIENT_RESOURCES;
  2682. }
  2683. UsbBuildGetDescriptorRequest(urb,
  2684. (USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
  2685. USB_CONFIGURATION_DESCRIPTOR_TYPE,
  2686. 0,
  2687. 0,
  2688. DeviceExtension->UsbConfigurationDescriptor,
  2689. NULL,
  2690. siz,
  2691. NULL);
  2692. NTStatus = CMUSB_CallUSBD(DeviceObject, urb);
  2693. //
  2694. // if we got some data see if it was enough.
  2695. // NOTE: we may get an error in URB because of buffer overrun
  2696. if (urb->UrbControlDescriptorRequest.TransferBufferLength>0 &&
  2697. DeviceExtension->UsbConfigurationDescriptor->wTotalLength > siz)
  2698. {
  2699. siz = DeviceExtension->UsbConfigurationDescriptor->wTotalLength;
  2700. ExFreePool(DeviceExtension->UsbConfigurationDescriptor);
  2701. DeviceExtension->UsbConfigurationDescriptor = NULL;
  2702. }
  2703. else
  2704. {
  2705. break; // we got it on the first try
  2706. }
  2707. } // end, while (retry loop )
  2708. ExFreePool(urb);
  2709. CMUSB_ASSERT( DeviceExtension->UsbConfigurationDescriptor );
  2710. //
  2711. // We have the configuration descriptor for the configuration we want.
  2712. // Now we issue the select configuration command to get
  2713. // the pipes associated with this configuration.
  2714. //
  2715. NTStatus = CMUSB_SelectInterface(DeviceObject,
  2716. DeviceExtension->UsbConfigurationDescriptor);
  2717. return NTStatus;
  2718. }
  2719. /*****************************************************************************
  2720. Routine Description:
  2721. Initializes an CardMan USB
  2722. This minidriver only supports one interface with one endpoint
  2723. Arguments:
  2724. DeviceObject - pointer to the device object for this instance of the
  2725. CardMan USB device
  2726. ConfigurationDescriptor - pointer to the USB configuration
  2727. descriptor containing the interface and endpoint
  2728. descriptors.
  2729. Return Value:
  2730. NT NTStatus code
  2731. *****************************************************************************/
  2732. NTSTATUS
  2733. CMUSB_SelectInterface(
  2734. IN PDEVICE_OBJECT DeviceObject,
  2735. IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
  2736. )
  2737. {
  2738. PDEVICE_EXTENSION DeviceExtension;
  2739. NTSTATUS NTStatus;
  2740. PURB urb = NULL;
  2741. ULONG i;
  2742. PUSB_INTERFACE_DESCRIPTOR interfaceDescriptor = NULL;
  2743. PUSBD_INTERFACE_INFORMATION Interface = NULL;
  2744. USHORT siz;
  2745. DeviceExtension = DeviceObject->DeviceExtension;
  2746. //
  2747. // CMUSB driver only supports one interface, we must parse
  2748. // the configuration descriptor for the interface
  2749. // and remember the pipes.
  2750. //
  2751. urb = USBD_CreateConfigurationRequest(ConfigurationDescriptor, &siz);
  2752. if (urb != NULL)
  2753. {
  2754. //
  2755. // USBD_ParseConfigurationDescriptorEx searches a given configuration
  2756. // descriptor and returns a pointer to an interface that matches the
  2757. // given search criteria. We only support one interface on this device
  2758. //
  2759. interfaceDescriptor =
  2760. USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor,
  2761. ConfigurationDescriptor, //search from start of config descriptro
  2762. -1, // interface number not a criteria; we only support one interface
  2763. -1, // not interested in alternate setting here either
  2764. -1, // interface class not a criteria
  2765. -1, // interface subclass not a criteria
  2766. -1 // interface protocol not a criteria
  2767. );
  2768. if (interfaceDescriptor == NULL)
  2769. {
  2770. ExFreePool(urb);
  2771. return STATUS_INSUFFICIENT_RESOURCES;
  2772. }
  2773. Interface = &urb->UrbSelectConfiguration.Interface;
  2774. for (i=0; i< Interface->NumberOfPipes; i++)
  2775. {
  2776. //
  2777. // perform any pipe initialization here
  2778. //
  2779. Interface->Pipes[i].MaximumTransferSize = 1000;
  2780. Interface->Pipes[i].PipeFlags = 0;
  2781. }
  2782. UsbBuildSelectConfigurationRequest(urb,
  2783. (USHORT) siz,
  2784. ConfigurationDescriptor);
  2785. NTStatus = CMUSB_CallUSBD(DeviceObject, urb);
  2786. DeviceExtension->UsbConfigurationHandle =
  2787. urb->UrbSelectConfiguration.ConfigurationHandle;
  2788. }
  2789. else
  2790. {
  2791. NTStatus = STATUS_INSUFFICIENT_RESOURCES;
  2792. }
  2793. if (NT_SUCCESS(NTStatus))
  2794. {
  2795. //
  2796. // Save the configuration handle for this device
  2797. //
  2798. DeviceExtension->UsbConfigurationHandle =
  2799. urb->UrbSelectConfiguration.ConfigurationHandle;
  2800. DeviceExtension->UsbInterface = ExAllocatePool(NonPagedPool,
  2801. Interface->Length);
  2802. if (DeviceExtension->UsbInterface != NULL)
  2803. {
  2804. ULONG j;
  2805. //
  2806. // save a copy of the interface information returned
  2807. //
  2808. RtlCopyMemory(DeviceExtension->UsbInterface, Interface, Interface->Length);
  2809. //
  2810. // Dump the interface to the debugger
  2811. //
  2812. SmartcardDebug( DEBUG_DRIVER,("%s!SelectInterface: ---------\n",
  2813. DRIVER_NAME));
  2814. SmartcardDebug( DEBUG_DRIVER,("%s!SelectInterface: NumberOfPipes 0x%x\n",
  2815. DRIVER_NAME,
  2816. DeviceExtension->UsbInterface->NumberOfPipes));
  2817. SmartcardDebug( DEBUG_DRIVER,("%s!SelectInterface: Length 0x%x\n",
  2818. DRIVER_NAME,
  2819. DeviceExtension->UsbInterface->Length));
  2820. SmartcardDebug( DEBUG_DRIVER,("%s!SelectInterface: Alt Setting 0x%x\n",
  2821. DRIVER_NAME,
  2822. DeviceExtension->UsbInterface->AlternateSetting));
  2823. SmartcardDebug( DEBUG_DRIVER,("%s!SelectInterface: Interface Number 0x%x\n",
  2824. DRIVER_NAME,
  2825. DeviceExtension->UsbInterface->InterfaceNumber));
  2826. SmartcardDebug( DEBUG_DRIVER,("%s!SelectInterface: Class, subclass, protocol 0x%x 0x%x 0x%x\n",
  2827. DRIVER_NAME,
  2828. DeviceExtension->UsbInterface->Class,
  2829. DeviceExtension->UsbInterface->SubClass,
  2830. DeviceExtension->UsbInterface->Protocol));
  2831. // Dump the pipe info
  2832. for (j=0; j<Interface->NumberOfPipes; j++)
  2833. {
  2834. PUSBD_PIPE_INFORMATION pipeInformation;
  2835. pipeInformation = &DeviceExtension->UsbInterface->Pipes[j];
  2836. pipeInformation->MaximumTransferSize = 256;
  2837. pipeInformation->PipeFlags = TRUE;
  2838. SmartcardDebug( DEBUG_DRIVER,("%s!SelectInterface: ---------\n",
  2839. DRIVER_NAME));
  2840. SmartcardDebug( DEBUG_DRIVER,("%s!SelectInterface: PipeType 0x%x\n",
  2841. DRIVER_NAME,
  2842. pipeInformation->PipeType));
  2843. SmartcardDebug( DEBUG_DRIVER,("%s!SelectInterface: EndpointAddress 0x%x\n",
  2844. DRIVER_NAME,
  2845. pipeInformation->EndpointAddress));
  2846. SmartcardDebug( DEBUG_DRIVER,("%s!SelectInterface: MaxPacketSize 0x%x\n",
  2847. DRIVER_NAME,
  2848. pipeInformation->MaximumPacketSize));
  2849. SmartcardDebug( DEBUG_DRIVER,("%s!SelectInterface: Interval 0x%x\n",
  2850. DRIVER_NAME,
  2851. pipeInformation->Interval));
  2852. SmartcardDebug( DEBUG_DRIVER,("%s!SelectInterface: Handle 0x%x\n",
  2853. DRIVER_NAME,
  2854. pipeInformation->PipeHandle));
  2855. SmartcardDebug( DEBUG_DRIVER,("%s!SelectInterface: MaximumTransferSize 0x%x\n",
  2856. DRIVER_NAME,
  2857. pipeInformation->MaximumTransferSize));
  2858. }
  2859. SmartcardDebug( DEBUG_DRIVER,("%s!SelectInterface: ---------\n",
  2860. DRIVER_NAME));
  2861. }
  2862. }
  2863. if (urb != NULL)
  2864. {
  2865. ExFreePool(urb);
  2866. }
  2867. return NTStatus;
  2868. }
  2869. /*****************************************************************************
  2870. Routine Description:
  2871. Reset a given USB pipe.
  2872. NOTES:
  2873. This will reset the host to Data0 and should also reset the device to Data0
  2874. Arguments:
  2875. Ptrs to our FDO and a USBD_PIPE_INFORMATION struct
  2876. Return Value:
  2877. NT NTStatus code
  2878. *****************************************************************************/
  2879. NTSTATUS
  2880. CMUSB_ResetPipe(
  2881. IN PDEVICE_OBJECT DeviceObject,
  2882. IN PUSBD_PIPE_INFORMATION PipeInfo
  2883. )
  2884. {
  2885. NTSTATUS NTStatus;
  2886. PURB urb;
  2887. PDEVICE_EXTENSION DeviceExtension;
  2888. DeviceExtension = DeviceObject->DeviceExtension;
  2889. SmartcardDebug(
  2890. DEBUG_TRACE,
  2891. ( "%s!ResetPipe : Enter\n",
  2892. DRIVER_NAME)
  2893. );
  2894. urb = ExAllocatePool(NonPagedPool,
  2895. sizeof(struct _URB_PIPE_REQUEST));
  2896. if (urb != NULL)
  2897. {
  2898. urb->UrbHeader.Length = (USHORT) sizeof (struct _URB_PIPE_REQUEST);
  2899. urb->UrbHeader.Function = URB_FUNCTION_RESET_PIPE;
  2900. urb->UrbPipeRequest.PipeHandle =
  2901. PipeInfo->PipeHandle;
  2902. NTStatus = CMUSB_CallUSBD(DeviceObject, urb);
  2903. ExFreePool(urb);
  2904. }
  2905. else
  2906. {
  2907. NTStatus = STATUS_INSUFFICIENT_RESOURCES;
  2908. }
  2909. SmartcardDebug(
  2910. DEBUG_TRACE,
  2911. ( "%s!ResetPipe : Exit %lx\n",
  2912. DRIVER_NAME,NTStatus)
  2913. );
  2914. return NTStatus;
  2915. }
  2916. /*****************************************************************************
  2917. Routine Description:
  2918. We keep a pending IO count ( extension->PendingIoCount ) in the device extension.
  2919. The first increment of this count is done on adding the device.
  2920. Subsequently, the count is incremented for each new IRP received and
  2921. decremented when each IRP is completed or passed on.
  2922. Transition to 'one' therefore indicates no IO is pending and signals
  2923. DeviceExtension->NoPendingIoEvent. This is needed for processing
  2924. IRP_MN_QUERY_REMOVE_DEVICE
  2925. Transition to 'zero' signals an event ( DeviceExtension->RemoveEvent )
  2926. to enable device removal. This is used in processing for IRP_MN_REMOVE_DEVICE
  2927. Arguments:
  2928. DeviceObject -- ptr to our FDO
  2929. Return Value:
  2930. DeviceExtension->PendingIoCount
  2931. *****************************************************************************/
  2932. VOID
  2933. CMUSB_DecrementIoCount(
  2934. IN PDEVICE_OBJECT DeviceObject
  2935. )
  2936. {
  2937. PDEVICE_EXTENSION DeviceExtension;
  2938. LONG ioCount;
  2939. DeviceExtension = DeviceObject->DeviceExtension;
  2940. ioCount = InterlockedDecrement(&DeviceExtension->PendingIoCount);
  2941. if (ioCount==1)
  2942. {
  2943. // trigger no pending io
  2944. KeSetEvent(&DeviceExtension->NoPendingIoEvent,
  2945. 1,
  2946. FALSE);
  2947. }
  2948. if (ioCount==0)
  2949. {
  2950. // trigger remove-device event
  2951. SmartcardDebug( DEBUG_DRIVER,
  2952. ("%s!DecrementIoCount: setting RemoveEvent\n",
  2953. DRIVER_NAME
  2954. )
  2955. );
  2956. KeSetEvent(&DeviceExtension->RemoveEvent,
  2957. 1,
  2958. FALSE);
  2959. }
  2960. return ;
  2961. }
  2962. /*****************************************************************************
  2963. Routine Description:
  2964. We keep a pending IO count ( extension->PendingIoCount ) in the device extension.
  2965. The first increment of this count is done on adding the device.
  2966. Subsequently, the count is incremented for each new IRP received and
  2967. decremented when each IRP is completed or passed on.
  2968. Arguments:
  2969. DeviceObject -- ptr to our FDO
  2970. Return Value:
  2971. None
  2972. *****************************************************************************/
  2973. VOID
  2974. CMUSB_IncrementIoCount(
  2975. IN PDEVICE_OBJECT DeviceObject
  2976. )
  2977. {
  2978. PDEVICE_EXTENSION DeviceExtension;
  2979. DeviceExtension = DeviceObject->DeviceExtension;
  2980. InterlockedIncrement(&DeviceExtension->PendingIoCount);
  2981. }
  2982. /*****************************************************************************
  2983. Routine Description:
  2984. Dispatch table handler for IRP_MJ_DEVICE_CONTROL;
  2985. Handle DeviceIoControl() calls from User mode
  2986. Arguments:
  2987. DeviceObject - pointer to the FDO for this instance of the 82930 device.
  2988. Return Value:
  2989. NT NTStatus code
  2990. *****************************************************************************/
  2991. NTSTATUS
  2992. CMUSB_ProcessIOCTL(
  2993. IN PDEVICE_OBJECT DeviceObject,
  2994. IN PIRP Irp
  2995. )
  2996. {
  2997. NTSTATUS NTStatus;
  2998. PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
  2999. PIO_STACK_LOCATION irpSL;
  3000. irpSL = IoGetCurrentIrpStackLocation(Irp);
  3001. #if DBG
  3002. switch (irpSL->Parameters.DeviceIoControl.IoControlCode)
  3003. {
  3004. case IOCTL_SMARTCARD_EJECT:
  3005. SmartcardDebug(DEBUG_IOCTL,
  3006. ("%s!ProcessIOCTL: %s\n", DRIVER_NAME, "IOCTL_SMARTCARD_EJECT"));
  3007. break;
  3008. case IOCTL_SMARTCARD_GET_ATTRIBUTE:
  3009. SmartcardDebug(DEBUG_IOCTL,
  3010. ("%s!ProcessIOCTL: %s\n", DRIVER_NAME, "IOCTL_SMARTCARD_GET_ATTRIBUTE"));
  3011. break;
  3012. case IOCTL_SMARTCARD_GET_LAST_ERROR:
  3013. SmartcardDebug(DEBUG_IOCTL,
  3014. ("%s!ProcessIOCTL: %s\n", DRIVER_NAME, "IOCTL_SMARTCARD_GET_LAST_ERROR"));
  3015. break;
  3016. case IOCTL_SMARTCARD_GET_STATE:
  3017. SmartcardDebug(DEBUG_IOCTL,
  3018. ("%s!ProcessIOCTL: %s\n", DRIVER_NAME, "IOCTL_SMARTCARD_GET_STATE"));
  3019. break;
  3020. case IOCTL_SMARTCARD_IS_ABSENT:
  3021. SmartcardDebug(DEBUG_IOCTL,
  3022. ("%s!ProcessIOCTL: %s\n", DRIVER_NAME, "IOCTL_SMARTCARD_IS_ABSENT"));
  3023. break;
  3024. case IOCTL_SMARTCARD_IS_PRESENT:
  3025. SmartcardDebug(DEBUG_IOCTL,
  3026. ("%s!ProcessIOCTL: %s\n", DRIVER_NAME, "IOCTL_SMARTCARD_IS_PRESENT"));
  3027. break;
  3028. case IOCTL_SMARTCARD_POWER:
  3029. SmartcardDebug(DEBUG_IOCTL,
  3030. ("%s!ProcessIOCTL: %s\n", DRIVER_NAME, "IOCTL_SMARTCARD_POWER"));
  3031. break;
  3032. case IOCTL_SMARTCARD_SET_ATTRIBUTE:
  3033. SmartcardDebug(DEBUG_IOCTL,
  3034. ("%s!ProcessIOCTL: %s\n", DRIVER_NAME, "IOCTL_SMARTCARD_SET_ATTRIBUTE"));
  3035. break;
  3036. case IOCTL_SMARTCARD_SET_PROTOCOL:
  3037. SmartcardDebug(DEBUG_IOCTL,
  3038. ("%s!ProcessIOCTL: %s\n", DRIVER_NAME, "IOCTL_SMARTCARD_SET_PROTOCOL"));
  3039. break;
  3040. case IOCTL_SMARTCARD_SWALLOW:
  3041. SmartcardDebug(DEBUG_IOCTL,
  3042. ("%s!ProcessIOCTL: %s\n", DRIVER_NAME, "IOCTL_SMARTCARD_SWALLOW"));
  3043. break;
  3044. case IOCTL_SMARTCARD_TRANSMIT:
  3045. SmartcardDebug(DEBUG_IOCTL,
  3046. ("%s!ProcessIOCTL: %s\n", DRIVER_NAME, "IOCTL_SMARTCARD_TRANSMIT"));
  3047. break;
  3048. default:
  3049. SmartcardDebug(DEBUG_IOCTL,
  3050. ("%s!ProcessIOCTL: %s\n", DRIVER_NAME, "Vendor specific or unexpected IOCTL"));
  3051. break;
  3052. }
  3053. #endif
  3054. CMUSB_IncrementIoCount(DeviceObject);
  3055. NTStatus = KeWaitForSingleObject(&DeviceExtension->ReaderEnabled,
  3056. Executive,
  3057. KernelMode,
  3058. FALSE,
  3059. NULL);
  3060. ASSERT(NTStatus == STATUS_SUCCESS);
  3061. // Can't accept a new io request if:
  3062. // 1) device is removed,
  3063. // 2) has never been started,
  3064. // 3) is stopped,
  3065. // 4) has a remove request pending,
  3066. // 5) has a stop device pending
  3067. if (CMUSB_CanAcceptIoRequests( DeviceObject ) == FALSE )
  3068. {
  3069. NTStatus = STATUS_DELETE_PENDING;
  3070. Irp->IoStatus.Status = NTStatus;
  3071. Irp->IoStatus.Information = 0;
  3072. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  3073. CMUSB_DecrementIoCount(DeviceObject);
  3074. return NTStatus;
  3075. }
  3076. NTStatus = SmartcardAcquireRemoveLock(&DeviceExtension->SmartcardExtension);
  3077. if (NTStatus != STATUS_SUCCESS)
  3078. {
  3079. // the device has been removed. Fail the call
  3080. Irp->IoStatus.Information = 0;
  3081. Irp->IoStatus.Status = STATUS_DELETE_PENDING;
  3082. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  3083. return STATUS_DELETE_PENDING;
  3084. }
  3085. KeWaitForSingleObject(&DeviceExtension->SmartcardExtension.ReaderExtension->CardManIOMutex,
  3086. Executive,
  3087. KernelMode,
  3088. FALSE,
  3089. NULL);
  3090. NTStatus = CMUSB_UpdateCurrentState (DeviceObject);
  3091. NTStatus = SmartcardDeviceControl(&DeviceExtension->SmartcardExtension,Irp);
  3092. KeReleaseMutex(&DeviceExtension->SmartcardExtension.ReaderExtension->CardManIOMutex,
  3093. FALSE);
  3094. SmartcardReleaseRemoveLock(&DeviceExtension->SmartcardExtension);
  3095. CMUSB_DecrementIoCount(DeviceObject);
  3096. return NTStatus;
  3097. }
  3098. /*****************************************************************************
  3099. Routine Description:
  3100. Arguments:
  3101. Return Value:
  3102. *****************************************************************************/
  3103. NTSTATUS
  3104. CMUSB_ReadP0(
  3105. IN PDEVICE_OBJECT DeviceObject
  3106. )
  3107. {
  3108. PURB urb = NULL;
  3109. NTSTATUS NTStatus;
  3110. ULONG i;
  3111. PDEVICE_EXTENSION DeviceExtension;
  3112. PSMARTCARD_EXTENSION SmartcardExtension;
  3113. DeviceExtension = DeviceObject->DeviceExtension;
  3114. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  3115. /*
  3116. SmartcardDebug(DEBUG_TRACE,
  3117. ("%s!ReadP0: Enter\n",
  3118. DRIVER_NAME)
  3119. );
  3120. */
  3121. urb = ExAllocatePool(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
  3122. if (urb != NULL)
  3123. {
  3124. RtlZeroMemory(urb, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
  3125. UsbBuildVendorRequest(urb,
  3126. URB_FUNCTION_VENDOR_ENDPOINT,
  3127. (USHORT)sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
  3128. USBD_TRANSFER_DIRECTION_IN,
  3129. 0,
  3130. 0,
  3131. 0,
  3132. 0,
  3133. SmartcardExtension->SmartcardReply.Buffer,
  3134. NULL,
  3135. SmartcardExtension->SmartcardReply.BufferLength,
  3136. NULL);
  3137. NTStatus = CMUSB_CallUSBD(DeviceObject,urb);
  3138. if (NTStatus == STATUS_SUCCESS)
  3139. {
  3140. SmartcardExtension->SmartcardReply.BufferLength = urb->UrbControlVendorClassRequest.TransferBufferLength;
  3141. #if DBG
  3142. SmartcardDebug(DEBUG_PROTOCOL,
  3143. ("%s!<==[P0] ",
  3144. DRIVER_NAME)
  3145. )
  3146. for (i=0;i<SmartcardExtension->SmartcardReply.BufferLength;i++)
  3147. {
  3148. SmartcardDebug(DEBUG_PROTOCOL,
  3149. ("%x ",
  3150. SmartcardExtension->SmartcardReply.Buffer[i]
  3151. )
  3152. );
  3153. }
  3154. SmartcardDebug(DEBUG_PROTOCOL,("\n"));
  3155. #endif
  3156. }
  3157. ExFreePool(urb);
  3158. }
  3159. else
  3160. {
  3161. NTStatus = STATUS_INSUFFICIENT_RESOURCES;
  3162. }
  3163. /*
  3164. SmartcardDebug(DEBUG_TRACE,
  3165. ("%s!ReadP0 Exit %lx\n",
  3166. DRIVER_NAME,
  3167. NTStatus)
  3168. );
  3169. */
  3170. return NTStatus;
  3171. }
  3172. /*****************************************************************************
  3173. Routine Description:
  3174. Write data through the control pipe to the CardMan USB
  3175. Arguments:
  3176. Return Value:
  3177. NT NTStatus code
  3178. *****************************************************************************/
  3179. NTSTATUS
  3180. CMUSB_WriteP0(
  3181. IN PDEVICE_OBJECT DeviceObject,
  3182. IN UCHAR bRequest,
  3183. IN UCHAR bValueLo,
  3184. IN UCHAR bValueHi,
  3185. IN UCHAR bIndexLo,
  3186. IN UCHAR bIndexHi
  3187. )
  3188. {
  3189. PURB urb = NULL;
  3190. NTSTATUS NTStatus = STATUS_UNSUCCESSFUL;
  3191. USHORT usValue;
  3192. USHORT usIndex;
  3193. ULONG length;
  3194. PDEVICE_EXTENSION DeviceExtension;
  3195. PSMARTCARD_EXTENSION SmartcardExtension;
  3196. ULONG ulBytesToWrite;
  3197. ULONG i;
  3198. DeviceExtension = DeviceObject->DeviceExtension;
  3199. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  3200. /*
  3201. SmartcardDebug(DEBUG_TRACE,
  3202. ("%s!WriteP0: Enter\n",
  3203. DRIVER_NAME)
  3204. );
  3205. */
  3206. #if DBG
  3207. SmartcardDebug(DEBUG_PROTOCOL,
  3208. ("%s!==>[P0] ",DRIVER_NAME));
  3209. for (i=0;i< SmartcardExtension->SmartcardRequest.BufferLength;i++)
  3210. {
  3211. SmartcardDebug(DEBUG_PROTOCOL,
  3212. ("%x ",SmartcardExtension->SmartcardRequest.Buffer[i]));
  3213. }
  3214. SmartcardDebug(DEBUG_PROTOCOL,
  3215. ("(%ld)\n",SmartcardExtension->SmartcardRequest.BufferLength));
  3216. #endif
  3217. /*
  3218. SmartcardDebug(DEBUG_TRACE,
  3219. ("%s!ulBytesToWrite = %ld\n",
  3220. DRIVER_NAME,SmartcardExtension->SmartcardRequest.BufferLength)
  3221. );
  3222. */
  3223. ulBytesToWrite = SmartcardExtension->SmartcardRequest.BufferLength;
  3224. urb = ExAllocatePool(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
  3225. if (urb != NULL)
  3226. {
  3227. RtlZeroMemory(urb, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
  3228. usValue = bValueHi * 256 + bValueLo;
  3229. usIndex = bIndexHi * 256 + bIndexLo;
  3230. if (ulBytesToWrite != 0)
  3231. {
  3232. UsbBuildVendorRequest (urb,
  3233. URB_FUNCTION_VENDOR_ENDPOINT,
  3234. (USHORT)sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
  3235. 0,
  3236. 0,
  3237. bRequest,
  3238. usValue,
  3239. usIndex,
  3240. SmartcardExtension->SmartcardRequest.Buffer,
  3241. NULL,
  3242. ulBytesToWrite,
  3243. NULL);
  3244. }
  3245. else
  3246. {
  3247. UsbBuildVendorRequest (urb,
  3248. URB_FUNCTION_VENDOR_ENDPOINT,
  3249. (USHORT)sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
  3250. 0,
  3251. 0,
  3252. bRequest,
  3253. usValue,
  3254. usIndex,
  3255. NULL,
  3256. NULL,
  3257. 0L,
  3258. NULL);
  3259. }
  3260. NTStatus = CMUSB_CallUSBD(DeviceObject,urb);
  3261. ExFreePool(urb);
  3262. }
  3263. if (NTStatus != STATUS_SUCCESS)
  3264. {
  3265. SmartcardDebug(DEBUG_PROTOCOL,
  3266. ("%s!WriteP0: Error on exit %lx\n",DRIVER_NAME,NTStatus));
  3267. }
  3268. return NTStatus;
  3269. }
  3270. /*****************************************************************************
  3271. /*++
  3272. Routine Description:
  3273. Called as part of sudden device removal handling.
  3274. Cancels any pending transfers for all open pipes.
  3275. If any pipes are still open, call USBD with URB_FUNCTION_ABORT_PIPE
  3276. Also marks the pipe 'closed' in our saved configuration info.
  3277. Arguments:
  3278. Ptrs to our FDO
  3279. Return Value:
  3280. NT NTStatus code
  3281. *****************************************************************************/
  3282. NTSTATUS
  3283. CMUSB_AbortPipes(
  3284. IN PDEVICE_OBJECT DeviceObject
  3285. )
  3286. {
  3287. NTSTATUS NTStatus = STATUS_SUCCESS;
  3288. PURB urb;
  3289. PDEVICE_EXTENSION DeviceExtension;
  3290. PUSBD_INTERFACE_INFORMATION interface;
  3291. PUSBD_PIPE_INFORMATION PipeInfo;
  3292. SmartcardDebug(DEBUG_TRACE,
  3293. ( "%s!AbortPipes: Enter\n",DRIVER_NAME));
  3294. DeviceExtension = DeviceObject->DeviceExtension;
  3295. interface = DeviceExtension->UsbInterface;
  3296. PipeInfo = &interface->Pipes[0];
  3297. if (PipeInfo->PipeFlags == TRUE) // we set this if open, clear if closed
  3298. {
  3299. urb = ExAllocatePool(NonPagedPool,sizeof(struct _URB_PIPE_REQUEST));
  3300. if (urb != NULL)
  3301. {
  3302. urb->UrbHeader.Length = (USHORT) sizeof (struct _URB_PIPE_REQUEST);
  3303. urb->UrbHeader.Function = URB_FUNCTION_ABORT_PIPE;
  3304. urb->UrbPipeRequest.PipeHandle = PipeInfo->PipeHandle;
  3305. NTStatus = CMUSB_CallUSBD(DeviceObject, urb);
  3306. ExFreePool(urb);
  3307. }
  3308. else
  3309. {
  3310. NTStatus = STATUS_INSUFFICIENT_RESOURCES;
  3311. SmartcardDebug(DEBUG_ERROR,
  3312. ("%s!AbortPipes: ExAllocatePool failed\n",DRIVER_NAME));
  3313. }
  3314. if (NTStatus == STATUS_SUCCESS)
  3315. {
  3316. PipeInfo->PipeFlags = FALSE; // mark the pipe 'closed'
  3317. }
  3318. } // end, if pipe open
  3319. SmartcardDebug(DEBUG_TRACE,
  3320. ("%s!AbortPipes: Exit %lx\n",DRIVER_NAME,NTStatus));
  3321. return NTStatus;
  3322. }
  3323. /*****************************************************************************
  3324. Routine Description:
  3325. Check device extension NTStatus flags;
  3326. Can't accept a new io request if device:
  3327. 1) is removed,
  3328. 2) has never been started,
  3329. 3) is stopped,
  3330. 4) has a remove request pending, or
  3331. 5) has a stop device pending
  3332. Arguments:
  3333. DeviceObject - pointer to the device object for this instance of the 82930
  3334. device.
  3335. Return Value:
  3336. return TRUE if can accept new io requests, else FALSE
  3337. *****************************************************************************/
  3338. BOOLEAN
  3339. CMUSB_CanAcceptIoRequests(
  3340. IN PDEVICE_OBJECT DeviceObject
  3341. )
  3342. {
  3343. PDEVICE_EXTENSION DeviceExtension;
  3344. BOOLEAN fCan = FALSE;
  3345. DeviceExtension = DeviceObject->DeviceExtension;
  3346. //flag set when processing IRP_MN_REMOVE_DEVICE
  3347. if ( DeviceExtension->DeviceRemoved == FALSE &&
  3348. // device must be started( enabled )
  3349. DeviceExtension->DeviceStarted == TRUE &&
  3350. // flag set when driver has answered success to IRP_MN_QUERY_REMOVE_DEVICE
  3351. DeviceExtension->RemoveDeviceRequested == FALSE&&
  3352. //flag set when processing IRP_MN_SURPRISE_REMOVAL
  3353. DeviceExtension->DeviceSurpriseRemoval == FALSE&&
  3354. // flag set when driver has answered success to IRP_MN_QUERY_STOP_DEVICE
  3355. DeviceExtension->StopDeviceRequested == FALSE)
  3356. {
  3357. fCan = TRUE;
  3358. }
  3359. #if DBG
  3360. if (fCan == FALSE)
  3361. SmartcardDebug(DEBUG_DRIVER,
  3362. ("%s!CanAcceptIoRequests: return FALSE \n",DRIVER_NAME));
  3363. #endif
  3364. return fCan;
  3365. }
  3366. /*****************************************************************************
  3367. * History:
  3368. * $Log: scusbwdm.c $
  3369. * Revision 1.9 2001/01/17 12:36:06 WFrischauf
  3370. * No comment given
  3371. *
  3372. * Revision 1.8 2000/09/25 13:38:23 WFrischauf
  3373. * No comment given
  3374. *
  3375. * Revision 1.7 2000/08/24 09:04:39 TBruendl
  3376. * No comment given
  3377. *
  3378. * Revision 1.6 2000/08/16 08:25:23 TBruendl
  3379. * warning :uninitialized memory removed
  3380. *
  3381. * Revision 1.5 2000/07/24 11:35:01 WFrischauf
  3382. * No comment given
  3383. *
  3384. * Revision 1.1 2000/07/20 11:50:16 WFrischauf
  3385. * No comment given
  3386. *
  3387. *
  3388. ******************************************************************************/