Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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