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.

758 lines
20 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. ocrw.c
  5. Abstract:
  6. read/write io code for printing
  7. Environment:
  8. kernel mode only
  9. Notes:
  10. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  11. KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  12. IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  13. PURPOSE.
  14. Copyright (c) 1999 Microsoft Corporation. All Rights Reserved.
  15. Revision History:
  16. 5-4-96 : created
  17. --*/
  18. #define DRIVER
  19. #include "wdm.h"
  20. #include "stdarg.h"
  21. #include "stdio.h"
  22. #include <usb.h>
  23. #include <usbdrivr.h>
  24. #include "usbdlib.h"
  25. #include "usbprint.h"
  26. //******************************************************************************
  27. //
  28. // USBPRINT_CompletionStop()
  29. //
  30. // IO Completion Routine which just stops further completion of the Irp
  31. //
  32. //******************************************************************************
  33. NTSTATUS
  34. USBPRINT_CompletionStop (
  35. IN PDEVICE_OBJECT DeviceObject,
  36. IN PIRP Irp,
  37. IN PVOID Context
  38. )
  39. {
  40. return STATUS_MORE_PROCESSING_REQUIRED;
  41. }
  42. //******************************************************************************
  43. //
  44. // USBPRINT_GetCurrentFrame()
  45. //
  46. //******************************************************************************
  47. ULONG
  48. USBPRINT_GetCurrentFrame (
  49. IN PDEVICE_OBJECT DeviceObject,
  50. IN PIRP Irp
  51. )
  52. {
  53. PDEVICE_EXTENSION deviceExtension;
  54. PIO_STACK_LOCATION nextStack;
  55. NTSTATUS ntStatus;
  56. struct _URB_GET_CURRENT_FRAME_NUMBER urb;
  57. deviceExtension = DeviceObject->DeviceExtension;
  58. // Initialize the URB
  59. //
  60. urb.Hdr.Function = URB_FUNCTION_GET_CURRENT_FRAME_NUMBER;
  61. urb.Hdr.Length = sizeof(urb);
  62. urb.FrameNumber = (ULONG)-1;
  63. // Set the IRP parameters to pass the URB down the stack
  64. //
  65. nextStack = IoGetNextIrpStackLocation(Irp);
  66. nextStack->Parameters.Others.Argument1 = &urb;
  67. nextStack->Parameters.DeviceIoControl.IoControlCode =
  68. IOCTL_INTERNAL_USB_SUBMIT_URB;
  69. nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
  70. // Since this Irp is borrowed for URB_FUNCTION_GET_CURRENT_FRAME_NUMBER
  71. // before it is passed down later for the real URB request after this
  72. // routine returns, set a completion routine which stop further completion
  73. // of the Irp.
  74. //
  75. IoSetCompletionRoutine(
  76. Irp,
  77. USBPRINT_CompletionStop,
  78. NULL, // Context
  79. TRUE, // InvokeOnSuccess
  80. TRUE, // InvokeOnError
  81. TRUE // InvokeOnCancel
  82. );
  83. // Now pass the Irp down the stack
  84. //
  85. ntStatus = IoCallDriver(
  86. deviceExtension->TopOfStackDeviceObject,
  87. Irp
  88. );
  89. // Don't need to wait for completion because JD guarantees that
  90. // URB_FUNCTION_GET_CURRENT_FRAME_NUMBER will never return STATUS_PENDING
  91. return urb.FrameNumber;
  92. }
  93. PURB
  94. USBPRINT_BuildAsyncRequest(
  95. IN PDEVICE_OBJECT DeviceObject,
  96. IN PIRP Irp,
  97. IN PUSBD_PIPE_INFORMATION PipeHandle,
  98. IN BOOLEAN Read
  99. )
  100. /*++
  101. Routine Description:
  102. Arguments:
  103. DeviceObject - pointer to the device extension for this instance of the
  104. printer
  105. Irp -
  106. PipeHandle -
  107. Return Value:
  108. initialized async urb.
  109. --*/
  110. {
  111. ULONG siz;
  112. ULONG length;
  113. PURB urb = NULL;
  114. USBPRINT_KdPrint3 (("USBPRINT.SYS: handle = 0x%x\n", PipeHandle));
  115. if ( Irp->MdlAddress == NULL )
  116. return NULL;
  117. length = MmGetMdlByteCount(Irp->MdlAddress);
  118. USBPRINT_KdPrint3 (("USBPRINT.SYS: length = 0x%x\n", length));
  119. siz = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);
  120. urb = ExAllocatePoolWithTag(NonPagedPool, siz, USBP_TAG);
  121. USBPRINT_KdPrint3 (("USBPRINT.SYS: siz = 0x%x urb 0x%x\n", siz, urb));
  122. if (urb) {
  123. RtlZeroMemory(urb, siz);
  124. urb->UrbBulkOrInterruptTransfer.Hdr.Length = (USHORT) siz;
  125. urb->UrbBulkOrInterruptTransfer.Hdr.Function =
  126. URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;
  127. urb->UrbBulkOrInterruptTransfer.PipeHandle =
  128. PipeHandle->PipeHandle;
  129. urb->UrbBulkOrInterruptTransfer.TransferFlags =
  130. Read ? USBD_TRANSFER_DIRECTION_IN : 0;
  131. // short packet is not treated as an error.
  132. urb->UrbBulkOrInterruptTransfer.TransferFlags |=
  133. USBD_SHORT_TRANSFER_OK;
  134. //
  135. // no linkage for now
  136. //
  137. urb->UrbBulkOrInterruptTransfer.UrbLink = NULL;
  138. urb->UrbBulkOrInterruptTransfer.TransferBufferMDL =
  139. Irp->MdlAddress;
  140. urb->UrbBulkOrInterruptTransfer.TransferBufferLength =
  141. length;
  142. USBPRINT_KdPrint3 (("USBPRINT.SYS: Init async urb Length = 0x%x buf = 0x%x, mdlBuff=0x%x\n",
  143. urb->UrbBulkOrInterruptTransfer.TransferBufferLength,
  144. urb->UrbBulkOrInterruptTransfer.TransferBuffer,
  145. urb->UrbBulkOrInterruptTransfer.TransferBufferMDL));
  146. }
  147. USBPRINT_KdPrint3 (("USBPRINT.SYS: exit USBPRINT_BuildAsyncRequest\n"));
  148. return urb;
  149. }
  150. NTSTATUS
  151. USBPRINT_AsyncReadWrite_Complete(
  152. IN PDEVICE_OBJECT DeviceObject,
  153. IN PIRP Irp,
  154. IN PVOID Context
  155. )
  156. /*++
  157. Routine Description:
  158. Arguments:
  159. DeviceObject - Pointer to the device object for the USBPRINT device.
  160. Irp - Irp completed.
  161. Context - Driver defined context.
  162. Return Value:
  163. The function value is the final status from the operation.
  164. --*/
  165. {
  166. NTSTATUS ntStatus = STATUS_SUCCESS;
  167. PURB urb;
  168. PUSBPRINT_RW_CONTEXT context = Context;
  169. PDEVICE_OBJECT deviceObject;
  170. PDEVICE_EXTENSION deviceExtension;
  171. PUSBPRINT_WORKITEM_CONTEXT pResetWorkItemObj;
  172. LONG ResetPending;
  173. //Always mark irp pending in dispatch routine now
  174. // if (Irp->PendingReturned) {
  175. // IoMarkIrpPending(Irp);
  176. // }
  177. urb = context->Urb;
  178. deviceObject = context->DeviceObject;
  179. deviceExtension=deviceObject->DeviceExtension;
  180. USBPRINT_KdPrint2 (("USBPRINT.SYS: Async Completion: Length %d, Status 0x%08X\n",
  181. urb->UrbBulkOrInterruptTransfer.TransferBufferLength,
  182. urb->UrbHeader.Status));
  183. //ASSERT(urb->UrbHeader.Status==0);
  184. ntStatus=urb->UrbHeader.Status;
  185. //
  186. // set the length based on the TransferBufferLength
  187. // value in the URB
  188. //
  189. Irp->IoStatus.Information =
  190. urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
  191. if((!NT_SUCCESS(ntStatus))&&(ntStatus!=STATUS_CANCELLED)&&(ntStatus!=STATUS_DEVICE_NOT_CONNECTED)&&(ntStatus!=STATUS_DELETE_PENDING))
  192. { //We've got an error, and it's not "not connected" or "cancelled", we need to reset the connection
  193. ResetPending=InterlockedCompareExchange(&deviceExtension->ResetWorkItemPending,
  194. 1,
  195. 0); //Check to see if ResetWorkItem is 0, if so, set it to 1, and start a Reset
  196. if(!ResetPending)
  197. {
  198. pResetWorkItemObj=ExAllocatePoolWithTag(NonPagedPool,sizeof(USBPRINT_WORKITEM_CONTEXT),USBP_TAG);
  199. if(pResetWorkItemObj)
  200. {
  201. pResetWorkItemObj->ioWorkItem=IoAllocateWorkItem(DeviceObject);
  202. if(pResetWorkItemObj==NULL)
  203. {
  204. USBPRINT_KdPrint1 (("USBPRINT.SYS: Unable to allocate IoAllocateWorkItem in ReadWrite_Complete\n"));
  205. ExFreePool(pResetWorkItemObj);
  206. pResetWorkItemObj=NULL;
  207. }
  208. } //if ALloc RestWorkItem OK
  209. else
  210. {
  211. USBPRINT_KdPrint1 (("USBPRINT.SYS: Unable to allocate WorkItemObj in ReadWrite_Complete\n"));
  212. }
  213. if(pResetWorkItemObj)
  214. {
  215. pResetWorkItemObj->irp=Irp;
  216. pResetWorkItemObj->deviceObject=DeviceObject;
  217. if(context->IsWrite)
  218. pResetWorkItemObj->pPipeInfo=deviceExtension->pWritePipe;
  219. else
  220. pResetWorkItemObj->pPipeInfo=deviceExtension->pReadPipe;
  221. USBPRINT_IncrementIoCount(deviceObject);
  222. IoQueueWorkItem(pResetWorkItemObj->ioWorkItem,
  223. USBPRINT_ResetWorkItem,
  224. DelayedWorkQueue,
  225. pResetWorkItemObj);
  226. ntStatus=STATUS_MORE_PROCESSING_REQUIRED;
  227. //Leave the IRP pending until the reset is complete. This way we won't get flooded with irp's we're not
  228. //prepaired to deal with. The Reset WorkItem completes the IRP when it's done.
  229. } //end if the allocs went OK
  230. } //end if ! Reset Pending
  231. } //end if we need to reset
  232. USBPRINT_DecrementIoCount(deviceObject); //still +1 on the IO count after this, leaving one for the workitem to decrement
  233. ExFreePool(context);
  234. ExFreePool(urb);
  235. return ntStatus;
  236. }
  237. NTSTATUS USBPRINT_ResetWorkItem(IN PDEVICE_OBJECT deviceObject, IN PVOID Context)
  238. {
  239. PUSBPRINT_WORKITEM_CONTEXT pResetWorkItemObj;
  240. PDEVICE_EXTENSION DeviceExtension;
  241. NTSTATUS ntStatus;
  242. ULONG portStatus;
  243. PDEVICE_OBJECT devObj;
  244. USBPRINT_KdPrint2(("USBPRINT.SYS: Entering USBPRINT_ResetWorkItem\n"));
  245. pResetWorkItemObj=(PUSBPRINT_WORKITEM_CONTEXT)Context;
  246. DeviceExtension=pResetWorkItemObj->deviceObject->DeviceExtension;
  247. ntStatus=USBPRINT_ResetPipe(pResetWorkItemObj->deviceObject,pResetWorkItemObj->pPipeInfo,FALSE);
  248. IoCompleteRequest(pResetWorkItemObj->irp,IO_NO_INCREMENT);
  249. IoFreeWorkItem(pResetWorkItemObj->ioWorkItem);
  250. // save off work item device object before freeing work item
  251. devObj = pResetWorkItemObj->deviceObject;
  252. ExFreePool(pResetWorkItemObj);
  253. InterlockedExchange(&(DeviceExtension->ResetWorkItemPending),0);
  254. USBPRINT_DecrementIoCount(devObj);
  255. return ntStatus;
  256. }
  257. NTSTATUS
  258. USBPRINT_Read(
  259. IN PDEVICE_OBJECT DeviceObject,
  260. IN PIRP Irp
  261. )
  262. /*++
  263. Routine Description:
  264. Arguments:
  265. DeviceObject - pointer to the device object for this instance of a printer.
  266. Return Value:
  267. NT status code
  268. --*/
  269. {
  270. NTSTATUS ntStatus = STATUS_SUCCESS;
  271. PUSBD_PIPE_INFORMATION pipeHandle = NULL;
  272. PFILE_OBJECT fileObject;
  273. PIO_STACK_LOCATION irpStack, nextStack;
  274. PDEVICE_EXTENSION deviceExtension;
  275. PURB urb;
  276. PUSBPRINT_RW_CONTEXT context = NULL;
  277. USBPRINT_KdPrint3 (("USBPRINT.SYS: /*dd enter USBPRINT_Read\n\n\n\n\n\n"));
  278. USBPRINT_KdPrint3 (("USBPRINT.SYS: /*dd **************************************************************************\n"));
  279. USBPRINT_IncrementIoCount(DeviceObject);
  280. deviceExtension = DeviceObject->DeviceExtension;
  281. if (deviceExtension->AcceptingRequests == FALSE) {
  282. ntStatus = STATUS_DELETE_PENDING;
  283. Irp->IoStatus.Status = ntStatus;
  284. Irp->IoStatus.Information = 0;
  285. IoCompleteRequest (Irp,
  286. IO_NO_INCREMENT
  287. );
  288. USBPRINT_DecrementIoCount(DeviceObject);
  289. return ntStatus;
  290. }
  291. irpStack = IoGetCurrentIrpStackLocation (Irp);
  292. fileObject = irpStack->FileObject;
  293. pipeHandle = deviceExtension->pReadPipe;
  294. if (!pipeHandle) {
  295. ntStatus = STATUS_INVALID_HANDLE;
  296. goto USBPRINT_Read_Reject;
  297. }
  298. //
  299. // submit the Read request to USB
  300. //
  301. switch (pipeHandle->PipeType) {
  302. case UsbdPipeTypeInterrupt:
  303. case UsbdPipeTypeBulk:
  304. urb = USBPRINT_BuildAsyncRequest(DeviceObject,
  305. Irp,
  306. pipeHandle,
  307. TRUE);
  308. if (urb) {
  309. context = ExAllocatePoolWithTag(NonPagedPool, sizeof(USBPRINT_RW_CONTEXT), USBP_TAG);
  310. if ( !context )
  311. ExFreePool(urb);
  312. }
  313. if (urb && context) {
  314. context->Urb = urb;
  315. context->DeviceObject = DeviceObject;
  316. context->IsWrite=FALSE;
  317. nextStack = IoGetNextIrpStackLocation(Irp);
  318. ASSERT(nextStack != NULL);
  319. ASSERT(DeviceObject->StackSize>1);
  320. nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
  321. nextStack->Parameters.Others.Argument1 = urb;
  322. nextStack->Parameters.DeviceIoControl.IoControlCode =
  323. IOCTL_INTERNAL_USB_SUBMIT_URB;
  324. IoSetCompletionRoutine(Irp,
  325. USBPRINT_AsyncReadWrite_Complete,
  326. context,
  327. TRUE,
  328. TRUE,
  329. TRUE);
  330. USBPRINT_KdPrint3 (("USBPRINT.SYS: IRP = 0x%x current = 0x%x next = 0x%x\n",
  331. Irp, irpStack, nextStack));
  332. // start perf timer here if needed
  333. IoMarkIrpPending(Irp);
  334. ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject,
  335. Irp);
  336. ntStatus=STATUS_PENDING;
  337. goto USBPRINT_Read_Done;
  338. }
  339. else
  340. {
  341. ntStatus = STATUS_INSUFFICIENT_RESOURCES;
  342. }
  343. break;
  344. default:
  345. ntStatus = STATUS_INVALID_PARAMETER;
  346. TRAP();
  347. }
  348. USBPRINT_Read_Reject:
  349. USBPRINT_DecrementIoCount(DeviceObject);
  350. Irp->IoStatus.Status = ntStatus;
  351. Irp->IoStatus.Information = 0;
  352. IoCompleteRequest (Irp,
  353. IO_NO_INCREMENT
  354. );
  355. USBPRINT_Read_Done:
  356. return ntStatus;
  357. }
  358. NTSTATUS
  359. USBPRINT_Write(
  360. IN PDEVICE_OBJECT DeviceObject,
  361. IN PIRP Irp
  362. )
  363. /*++
  364. Routine Description:
  365. This function services WRITE requests for this device (probably from the user mode USB port monitor)
  366. Arguments:
  367. DeviceObject - pointer to the device object for this printer
  368. Return Value:
  369. NT status code
  370. --*/
  371. {
  372. NTSTATUS ntStatus = STATUS_SUCCESS;
  373. PUSBD_PIPE_INFORMATION pipeHandle = NULL;
  374. PFILE_OBJECT fileObject;
  375. PIO_STACK_LOCATION irpStack, nextStack;
  376. PDEVICE_EXTENSION deviceExtension;
  377. PURB urb;
  378. PUSBPRINT_RW_CONTEXT context = NULL;
  379. USBPRINT_KdPrint2 (("USBPRINT.SYS: enter USBPRINT_Write (foo)\n"));
  380. USBPRINT_IncrementIoCount(DeviceObject);
  381. deviceExtension = DeviceObject->DeviceExtension;
  382. if (deviceExtension->AcceptingRequests == FALSE)
  383. {
  384. USBPRINT_KdPrint1 (("USBPRINT.SYS: failure because AcceptingRequests=FALSE\n"));
  385. ntStatus = STATUS_DELETE_PENDING;
  386. Irp->IoStatus.Status = ntStatus;
  387. Irp->IoStatus.Information = 0;
  388. USBPRINT_DecrementIoCount(DeviceObject);
  389. IoCompleteRequest (Irp,IO_NO_INCREMENT);
  390. return ntStatus;
  391. }
  392. irpStack = IoGetCurrentIrpStackLocation (Irp);
  393. fileObject = irpStack->FileObject;
  394. // MmProbeAndLockPages(Irp->MdlAddress,
  395. // KernelMode,
  396. // IoReadAccess);
  397. pipeHandle = deviceExtension->pWritePipe;
  398. if (!pipeHandle)
  399. {
  400. USBPRINT_KdPrint1 (("USBPRINT.SYS: failure because pipe is bad\n"));
  401. ntStatus = STATUS_INVALID_HANDLE;
  402. goto USBPRINT_Write_Reject;
  403. }
  404. //
  405. // submit the write request to USB
  406. //
  407. switch (pipeHandle->PipeType)
  408. {
  409. case UsbdPipeTypeInterrupt:
  410. case UsbdPipeTypeBulk:
  411. urb = USBPRINT_BuildAsyncRequest(DeviceObject,
  412. Irp,
  413. pipeHandle,
  414. FALSE);
  415. if (urb)
  416. {
  417. context = ExAllocatePoolWithTag(NonPagedPool, sizeof(USBPRINT_RW_CONTEXT), USBP_TAG);
  418. if(!context)
  419. ExFreePool(urb);
  420. }
  421. if (urb && context)
  422. {
  423. context->Urb = urb;
  424. context->DeviceObject = DeviceObject;
  425. context->IsWrite=TRUE;
  426. nextStack = IoGetNextIrpStackLocation(Irp);
  427. ASSERT(nextStack != NULL);
  428. ASSERT(DeviceObject->StackSize>1);
  429. nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
  430. nextStack->Parameters.Others.Argument1 = urb;
  431. nextStack->Parameters.DeviceIoControl.IoControlCode =
  432. IOCTL_INTERNAL_USB_SUBMIT_URB;
  433. IoSetCompletionRoutine(Irp,
  434. USBPRINT_AsyncReadWrite_Complete,
  435. context,
  436. TRUE,
  437. TRUE,
  438. TRUE);
  439. USBPRINT_KdPrint3 (("USBPRINT.SYS: IRP = 0x%x current = 0x%x next = 0x%x\n",Irp, irpStack, nextStack));
  440. IoMarkIrpPending(Irp);
  441. ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject,Irp);
  442. ntStatus=STATUS_PENDING;
  443. goto USBPRINT_Write_Done;
  444. }
  445. else
  446. {
  447. ntStatus = STATUS_INSUFFICIENT_RESOURCES;
  448. }
  449. break;
  450. default:
  451. ntStatus = STATUS_INVALID_PARAMETER;
  452. TRAP();
  453. }
  454. USBPRINT_Write_Reject:
  455. USBPRINT_DecrementIoCount(DeviceObject);
  456. Irp->IoStatus.Status = ntStatus;
  457. Irp->IoStatus.Information = 0;
  458. IoCompleteRequest (Irp,
  459. IO_NO_INCREMENT
  460. );
  461. USBPRINT_Write_Done:
  462. USBPRINT_KdPrint3 (("USBPRINT.SYS: Write Done, status= 0x%08X\n",ntStatus));
  463. return ntStatus;
  464. }
  465. NTSTATUS
  466. USBPRINT_Close(
  467. IN PDEVICE_OBJECT DeviceObject,
  468. IN PIRP Irp
  469. )
  470. /*++
  471. Routine Description:
  472. Arguments:
  473. DeviceObject - pointer to the device object for this printer
  474. Return Value:
  475. NT status code
  476. --*/
  477. {
  478. NTSTATUS ntStatus;
  479. PFILE_OBJECT fileObject;
  480. PIO_STACK_LOCATION irpStack;
  481. PDEVICE_EXTENSION deviceExtension;
  482. PUSBD_PIPE_INFORMATION pipeHandle = NULL;
  483. USBPRINT_KdPrint2 (("USBPRINT.SYS: entering USBPRINT_Close\n"));
  484. USBPRINT_IncrementIoCount(DeviceObject);
  485. deviceExtension = DeviceObject->DeviceExtension;
  486. irpStack = IoGetCurrentIrpStackLocation (Irp);
  487. fileObject = irpStack->FileObject;
  488. if (fileObject->FsContext)
  489. {
  490. // closing pipe handle
  491. pipeHandle = fileObject->FsContext;
  492. USBPRINT_KdPrint3 (("USBPRINT.SYS: closing pipe %x\n", pipeHandle));
  493. }
  494. deviceExtension->OpenCnt--;
  495. Irp->IoStatus.Status = STATUS_SUCCESS;
  496. Irp->IoStatus.Information = 0;
  497. ntStatus = Irp->IoStatus.Status;
  498. IoCompleteRequest (Irp,IO_NO_INCREMENT);
  499. USBPRINT_DecrementIoCount(DeviceObject);
  500. if(!deviceExtension->IsChildDevice)
  501. {
  502. USBPRINT_FdoSubmitIdleRequestIrp(deviceExtension);
  503. }
  504. return ntStatus;
  505. }
  506. NTSTATUS
  507. USBPRINT_Create(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
  508. /*++
  509. Routine Description:
  510. //
  511. // Entry point for CreateFile calls
  512. // user mode apps may open "\\.\USBPRINT-x\"
  513. // where x is the "USB virtual printer port"
  514. //
  515. // No more exposing the pipe # to usermode
  516. Arguments:
  517. DeviceObject - pointer to the device object for this printer.
  518. Return Value:
  519. NT status code
  520. --*/
  521. {
  522. NTSTATUS ntStatus = STATUS_SUCCESS;
  523. PFILE_OBJECT fileObject;
  524. PIO_STACK_LOCATION irpStack;
  525. PDEVICE_EXTENSION deviceExtension;
  526. USBPRINT_KdPrint2 (("USBPRINT.SYS: entering USBPRINT_Create\n"));
  527. USBPRINT_IncrementIoCount(DeviceObject);
  528. deviceExtension = DeviceObject->DeviceExtension;
  529. if (deviceExtension->IsChildDevice==TRUE) {
  530. ntStatus = STATUS_NOT_SUPPORTED;
  531. Irp->IoStatus.Status = ntStatus;
  532. Irp->IoStatus.Information = 0;
  533. IoCompleteRequest (Irp,IO_NO_INCREMENT);
  534. USBPRINT_DecrementIoCount(DeviceObject);
  535. return ntStatus;
  536. }
  537. if (deviceExtension->AcceptingRequests == FALSE) {
  538. ntStatus = STATUS_DELETE_PENDING;
  539. Irp->IoStatus.Status = ntStatus;
  540. Irp->IoStatus.Information = 0;
  541. IoCompleteRequest (Irp,IO_NO_INCREMENT);
  542. USBPRINT_DecrementIoCount(DeviceObject);
  543. return ntStatus;
  544. }
  545. USBPRINT_FdoRequestWake(deviceExtension);
  546. irpStack = IoGetCurrentIrpStackLocation (Irp);
  547. fileObject = irpStack->FileObject;
  548. // fscontext is null for device
  549. fileObject->FsContext = NULL;
  550. deviceExtension->OpenCnt++;
  551. ntStatus = STATUS_SUCCESS;
  552. Irp->IoStatus.Status = ntStatus;
  553. Irp->IoStatus.Information = 0;
  554. IoCompleteRequest (Irp,IO_NO_INCREMENT);
  555. USBPRINT_DecrementIoCount(DeviceObject);
  556. USBPRINT_KdPrint2 (("USBPRINT.SYS: exit USBPRINT_Create %x\n", ntStatus));
  557. return ntStatus;
  558. }