Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1004 lines
32 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. ioctl.c
  5. Abstract:
  6. Device driver for USB printers
  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) 1996 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. #include "ioctl.h"
  27. #include "usbdlib.h"
  28. #include "ntddpar.h"
  29. int USBPRINT_GetLptStatus(IN PDEVICE_OBJECT DeviceObject);
  30. NTSTATUS HPUsbIOCTLVendorSetCommand(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);
  31. NTSTATUS HPUsbIOCTLVendorGetCommand(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);
  32. NTSTATUS HPUsbVendorSetCommand(IN PDEVICE_OBJECT DeviceObject,IN PUCHAR buffer,IN ULONG length);
  33. NTSTATUS HPUsbVendorGetCommand(IN PDEVICE_OBJECT DeviceObject,IN PUCHAR buffer,IN ULONG length,OUT PULONG pBytesRead);
  34. NTSTATUS USBPRINT_SoftReset(IN PDEVICE_OBJECT DeviceObject)
  35. /*++
  36. Routine Description:
  37. Issues the class specific "Soft reset" command to the printer
  38. Arguments:
  39. DeviceObject - pointer to the device object for this instance of the printer device.
  40. Return Value:
  41. ntStatus of the URB
  42. --*/
  43. {
  44. NTSTATUS ntStatus;
  45. PURB urb;
  46. PUSB_CONFIGURATION_DESCRIPTOR configurationDescriptor = NULL;
  47. PDEVICE_EXTENSION deviceExtension;
  48. LARGE_INTEGER timeOut;
  49. USBPRINT_KdPrint2 (("'USBPRINT.SYS: enter USBPRINT_SoftReset\n"));
  50. deviceExtension = DeviceObject->DeviceExtension;
  51. urb = ExAllocatePoolWithTag(NonPagedPool,sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), USBP_TAG);
  52. if (urb) {
  53. UsbBuildVendorRequest(urb, //urb
  54. URB_FUNCTION_CLASS_INTERFACE, //request target
  55. sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), //request len
  56. USBD_TRANSFER_DIRECTION_OUT|USBD_SHORT_TRANSFER_OK, //flags
  57. 0, //reserved bits
  58. 2, //request code
  59. 0, //wValue
  60. deviceExtension->Interface->InterfaceNumber<<8, //wIndex
  61. NULL, //return buffer address
  62. NULL, //mdl
  63. 0, //return length
  64. NULL); //link param
  65. timeOut.QuadPart = FAILURE_TIMEOUT;
  66. ntStatus = USBPRINT_CallUSBD(DeviceObject, urb, &timeOut);
  67. USBPRINT_KdPrint3 (("'USBPRINT.SYS: urb->Hdr.Status=%d\n",((struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST *)urb)->Hdr.Status));
  68. if (NT_SUCCESS(ntStatus) &&
  69. urb->UrbControlVendorClassRequest.TransferBufferLength > 2)
  70. {
  71. USBPRINT_KdPrint3 (("'USBPRINT.SYS: CallUSBD succeeded\n"));
  72. }
  73. else
  74. {
  75. USBPRINT_KdPrint1(("'USBPRINT.SYS: Error; CallUSBD failed"));
  76. }
  77. ExFreePool(urb);
  78. } /*end if URB OK*/
  79. else
  80. {
  81. USBPRINT_KdPrint1(("'USBPRINT.SYS: Error; urb allocation failed"));
  82. ntStatus=STATUS_NO_MEMORY;
  83. }
  84. return ntStatus;
  85. } /*end function Get1284_Id*/
  86. int USBPRINT_Get1284Id(IN PDEVICE_OBJECT DeviceObject,PVOID pIoBuffer,int iLen)
  87. /*++
  88. Routine Description:
  89. Requests and returns Printer 1284 Device ID
  90. Arguments:
  91. DeviceObject - pointer to the device object for this instance of the printer device.
  92. pIoBuffer - pointer to IO buffer from user mode
  93. iLen - Length of *pIoBuffer;
  94. Return Value:
  95. Success: Length of data written to *pIoBuffer (icluding lenght field in first two bytes of data)
  96. Failure: -1
  97. --*/
  98. {
  99. NTSTATUS ntStatus;
  100. PURB urb;
  101. ULONG siz;
  102. int iReturn = -1;
  103. PUSB_CONFIGURATION_DESCRIPTOR configurationDescriptor = NULL;
  104. PDEVICE_EXTENSION deviceExtension;
  105. LARGE_INTEGER timeOut;
  106. USBPRINT_KdPrint2 (("'USBPRINT.SYS: enter USBPRINT_Get1284\n"));
  107. deviceExtension = DeviceObject->DeviceExtension;
  108. urb = ExAllocatePoolWithTag(NonPagedPool,sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), USBP_TAG);
  109. if (urb) {
  110. siz = iLen;
  111. UsbBuildVendorRequest(urb, //urb
  112. URB_FUNCTION_CLASS_INTERFACE, //request target
  113. sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), //request len
  114. USBD_TRANSFER_DIRECTION_IN|USBD_SHORT_TRANSFER_OK, //flags
  115. 0, //reserved bits
  116. 0, //request code
  117. 0, //wValue
  118. deviceExtension->Interface->InterfaceNumber<<8, //wIndex
  119. pIoBuffer, //return buffer address
  120. NULL, //mdl
  121. iLen, //return length
  122. NULL); //link param
  123. timeOut.QuadPart = FAILURE_TIMEOUT;
  124. ntStatus = USBPRINT_CallUSBD(DeviceObject, urb, &timeOut);
  125. USBPRINT_KdPrint3 (("'USBPRINT.SYS: urb->Hdr.Status=%d\n",((struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST *)urb)->Hdr.Status));
  126. if (NT_SUCCESS(ntStatus) &&
  127. urb->UrbControlVendorClassRequest.TransferBufferLength > 2)
  128. {
  129. USBPRINT_KdPrint3 (("'USBPRINT.SYS: CallUSBD succeeded\n"));
  130. iReturn= *((unsigned char *)pIoBuffer);
  131. iReturn<<=8;
  132. iReturn+=*(((unsigned char *)pIoBuffer)+1);
  133. if ( iReturn > 0 && iReturn < iLen )
  134. {
  135. *(((char *)pIoBuffer)+iReturn)='\0';
  136. USBPRINT_KdPrint3 (("'USBPRINT.SYS: return size ==%d\n",iReturn));
  137. }
  138. else
  139. {
  140. iReturn = -1;
  141. }
  142. }
  143. else
  144. {
  145. USBPRINT_KdPrint1(("'USBPRINT.SYS: Error; CallUSBD failed\n"));
  146. iReturn=-1;
  147. }
  148. ExFreePool(urb);
  149. } /*end if URB OK*/
  150. else
  151. {
  152. USBPRINT_KdPrint1(("'USBPRINT.SYS: Error; urb allocation failed"));
  153. iReturn=-1;
  154. }
  155. return iReturn;
  156. } /*end function Get1284_Id*/
  157. int USBPRINT_GetLptStatus(IN PDEVICE_OBJECT DeviceObject)
  158. /*++
  159. Routine Description:
  160. Requests and returns Printer status byte from USB printer
  161. Arguments:
  162. DeviceObject - pointer to the device object for this instance of the printer device.
  163. Return Value:
  164. Success: status value 0-255
  165. Failure: -1
  166. --*/
  167. {
  168. NTSTATUS ntStatus;
  169. PURB urb;
  170. ULONG siz;
  171. unsigned char RETURN_BUFF[1];
  172. PUSB_CONFIGURATION_DESCRIPTOR configurationDescriptor = NULL;
  173. PDEVICE_EXTENSION deviceExtension;
  174. LARGE_INTEGER timeOut;
  175. RETURN_BUFF[0] = 0;
  176. timeOut.QuadPart = FAILURE_TIMEOUT;
  177. deviceExtension = DeviceObject->DeviceExtension;
  178. urb = ExAllocatePoolWithTag(NonPagedPool,sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), USBP_TAG);
  179. if (urb) {
  180. siz = sizeof(RETURN_BUFF);
  181. UsbBuildVendorRequest(urb,
  182. URB_FUNCTION_CLASS_INTERFACE,
  183. sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
  184. USBD_TRANSFER_DIRECTION_IN|USBD_SHORT_TRANSFER_OK,
  185. 0, //reserved bits
  186. 1, //request code
  187. 0,
  188. deviceExtension->Interface->InterfaceNumber,
  189. RETURN_BUFF, //return buffer address
  190. NULL, //mdl
  191. sizeof(RETURN_BUFF), //return length
  192. NULL); //link param
  193. ntStatus = USBPRINT_CallUSBD(DeviceObject, urb, &timeOut);
  194. USBPRINT_KdPrint3 (("'USBPRINT.SYS: urb->Hdr.Status=%d\n",((struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST *)urb)->Hdr.Status));
  195. ExFreePool(urb);
  196. if (NT_SUCCESS(ntStatus))
  197. {
  198. USBPRINT_KdPrint3 (("'USBPRINT.SYS: CallUSBD succeeded\n"));
  199. return (int) RETURN_BUFF[0];
  200. }
  201. else
  202. {
  203. USBPRINT_KdPrint1(("'USBPRINT.SYS: Error; CallUSBD failed"));
  204. return -1;
  205. }
  206. } /*end if URB OK*/
  207. else {
  208. return -1;
  209. }
  210. } /*end function GetLptStatus*/
  211. NTSTATUS
  212. USBPRINT_GetPortStatus(
  213. IN PDEVICE_OBJECT DeviceObject,
  214. IN PULONG PortStatus
  215. )
  216. /*++
  217. Routine Description:
  218. returns the port status for our device
  219. Arguments:
  220. Return Value:
  221. STATUS_SUCCESS if successful,
  222. STATUS_UNSUCCESSFUL otherwise
  223. --*/
  224. {
  225. NTSTATUS ntStatus, status = STATUS_SUCCESS;
  226. PIRP irp;
  227. KEVENT event;
  228. IO_STATUS_BLOCK ioStatus;
  229. PIO_STACK_LOCATION nextStack;
  230. PDEVICE_EXTENSION deviceExtension;
  231. USBPRINT_KdPrint2 (("'USBPRINT.SYS: enter USBPRINT_GetPortStatus\n"));
  232. deviceExtension = DeviceObject->DeviceExtension;
  233. *PortStatus = 0;
  234. //
  235. // issue a synchronous request
  236. //
  237. KeInitializeEvent(&event, NotificationEvent, FALSE);
  238. irp = IoBuildDeviceIoControlRequest(
  239. IOCTL_INTERNAL_USB_GET_PORT_STATUS,
  240. deviceExtension->TopOfStackDeviceObject,
  241. NULL,
  242. 0,
  243. NULL,
  244. 0,
  245. TRUE, /* INTERNAL */
  246. &event,
  247. &ioStatus);
  248. if(irp==NULL)
  249. {
  250. ioStatus.Status=STATUS_NO_MEMORY;
  251. goto GetPortStatusDone;
  252. }
  253. //
  254. // Call the class driver to perform the operation. If the returned status
  255. // is PENDING, wait for the request to complete.
  256. //
  257. nextStack = IoGetNextIrpStackLocation(irp);
  258. ASSERT(nextStack != NULL);
  259. nextStack->Parameters.Others.Argument1 = PortStatus;
  260. USBPRINT_KdPrint3 (("'USBPRINT.SYS: calling USBD port status api\n"));
  261. ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject,
  262. irp);
  263. USBPRINT_KdPrint3 (("'USBPRINT.SYS: return from IoCallDriver USBD (in getportstatus)%x\n", ntStatus));
  264. if (ntStatus == STATUS_PENDING) {
  265. USBPRINT_KdPrint3 (("'USBPRINT.SYS: Wait for single object\n"));
  266. status = KeWaitForSingleObject(
  267. &event,
  268. Suspended,
  269. KernelMode,
  270. FALSE,
  271. NULL);
  272. USBPRINT_KdPrint3 (("'USBPRINT.SYS: Wait for single object, returned %x\n", status));
  273. } else {
  274. ioStatus.Status = ntStatus;
  275. }
  276. if (!NT_SUCCESS(ntStatus))
  277. {
  278. USBPRINT_KdPrint1 (("'USBPRINT.SYS: Error! IoCallDriver failed\n"));
  279. }
  280. else
  281. {
  282. USBPRINT_KdPrint3 (("'USBPRINT.SYS: Success! IoCallDriver did not fail\n"));
  283. }
  284. USBPRINT_KdPrint3 (("'USBPRINT.SYS: Port status = %x\n", *PortStatus));
  285. //
  286. // USBD maps the error code for us
  287. //
  288. GetPortStatusDone:
  289. ntStatus = ioStatus.Status;
  290. USBPRINT_KdPrint3 (("'USBPRINT.SYS: USBPRINT_GetPortStatus (%x)\n", ntStatus));
  291. return ntStatus;
  292. }
  293. NTSTATUS
  294. USBPRINT_ResetParentPort(
  295. IN IN PDEVICE_OBJECT DeviceObject
  296. )
  297. /*++
  298. Routine Description:
  299. Reset the our parent port
  300. Arguments:
  301. Return Value:
  302. STATUS_SUCCESS if successful,
  303. STATUS_UNSUCCESSFUL otherwise
  304. --*/
  305. {
  306. NTSTATUS ntStatus, status = STATUS_SUCCESS;
  307. PIRP irp;
  308. KEVENT event;
  309. IO_STATUS_BLOCK ioStatus;
  310. PIO_STACK_LOCATION nextStack;
  311. PDEVICE_EXTENSION deviceExtension;
  312. USBPRINT_KdPrint2 (("'USBPRINT.SYS: enter USBPRINT_ResetPort\n"));
  313. deviceExtension = DeviceObject->DeviceExtension;
  314. //
  315. // issue a synchronous request
  316. //
  317. KeInitializeEvent(&event, NotificationEvent, FALSE);
  318. irp = IoBuildDeviceIoControlRequest(
  319. IOCTL_INTERNAL_USB_RESET_PORT,
  320. deviceExtension->TopOfStackDeviceObject,
  321. NULL,
  322. 0,
  323. NULL,
  324. 0,
  325. TRUE, /* INTERNAL */
  326. &event,
  327. &ioStatus);
  328. //
  329. // Call the class driver to perform the operation. If the returned status
  330. // is PENDING, wait for the request to complete.
  331. //
  332. if(irp==NULL)
  333. {
  334. ioStatus.Status=STATUS_NO_MEMORY;
  335. goto ResetPortDone;
  336. }
  337. nextStack = IoGetNextIrpStackLocation(irp);
  338. ASSERT(nextStack != NULL);
  339. USBPRINT_KdPrint3 (("'USBPRINT.SYS: calling USBD enable port api\n"));
  340. ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject,
  341. irp);
  342. USBPRINT_KdPrint3 (("'USBPRINT.SYS: return from IoCallDriver USBD (in reset parent port)%x\n", ntStatus));
  343. if (ntStatus == STATUS_PENDING) {
  344. USBPRINT_KdPrint3 (("'USBPRINT.SYS: Wait for single object\n"));
  345. status = KeWaitForSingleObject(
  346. &event,
  347. Suspended,
  348. KernelMode,
  349. FALSE,
  350. NULL);
  351. USBPRINT_KdPrint3 (("'USBPRINT.SYS: Wait for single object, returned %x\n", status));
  352. } else {
  353. ioStatus.Status = ntStatus;
  354. }
  355. //
  356. // USBD maps the error code for us
  357. //
  358. ResetPortDone:
  359. ntStatus = ioStatus.Status;
  360. USBPRINT_KdPrint3 (("'USBPRINT.SYS: USBPRINT_ResetPort (%x)\n", ntStatus));
  361. return ntStatus;
  362. }
  363. NTSTATUS
  364. USBPRINT_ProcessIOCTL(
  365. IN PDEVICE_OBJECT DeviceObject,
  366. IN PIRP Irp
  367. )
  368. /*++
  369. Routine Description:
  370. Arguments:
  371. DeviceObject - pointer to the device object for this printer
  372. Return Value:
  373. NT status code
  374. --*/
  375. {
  376. PIO_STACK_LOCATION irpStack;
  377. PVOID ioBuffer;
  378. ULONG inputBufferLength;
  379. ULONG outputBufferLength;
  380. PDEVICE_EXTENSION deviceExtension;
  381. ULONG ioControlCode;
  382. NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
  383. PUCHAR pch;
  384. USBPRINT_KdPrint2 (("'USBPRINT.SYS: IRP_MJ_DEVICE_CONTROL\n"));
  385. USBPRINT_IncrementIoCount(DeviceObject);
  386. //
  387. // Get a pointer to the current location in the Irp. This is where
  388. // the function codes and parameters are located.
  389. //
  390. deviceExtension = DeviceObject->DeviceExtension;
  391. if (deviceExtension->IsChildDevice == TRUE)
  392. {
  393. ntStatus = STATUS_NOT_SUPPORTED;
  394. Irp->IoStatus.Status = ntStatus;
  395. Irp->IoStatus.Information = 0;
  396. IoCompleteRequest (Irp,IO_NO_INCREMENT);
  397. USBPRINT_DecrementIoCount(DeviceObject);
  398. return ntStatus;
  399. }
  400. if (deviceExtension->AcceptingRequests == FALSE)
  401. {
  402. ntStatus = STATUS_DEVICE_DATA_ERROR;
  403. Irp->IoStatus.Status = ntStatus;
  404. Irp->IoStatus.Information = 0;
  405. IoCompleteRequest (Irp,IO_NO_INCREMENT);
  406. USBPRINT_DecrementIoCount(DeviceObject);
  407. return ntStatus;
  408. }
  409. irpStack = IoGetCurrentIrpStackLocation (Irp);
  410. Irp->IoStatus.Information = 0;
  411. ioBuffer = Irp->AssociatedIrp.SystemBuffer;
  412. inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
  413. outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
  414. ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
  415. //
  416. // Handle Ioctls from User mode
  417. //
  418. switch (ioControlCode) {
  419. case IOCTL_PAR_QUERY_DEVICE_ID:
  420. {
  421. int iReturn;
  422. char * pTempBuffer;
  423. USBPRINT_KdPrint1 (("'USBPRINT.SYS: Enter in PAR_QUERY_DEVICE_ID\n"));
  424. pTempBuffer=ExAllocatePool(NonPagedPool,outputBufferLength+3); //3 == 2 bytes for the size at the beginning, plus 1 for the null at the end
  425. if(pTempBuffer==NULL)
  426. {
  427. Irp->IoStatus.Information=0;
  428. ntStatus=STATUS_NO_MEMORY;
  429. }
  430. else
  431. {
  432. iReturn=USBPRINT_Get1284Id(DeviceObject,pTempBuffer,outputBufferLength+2);
  433. if(iReturn>0)
  434. {
  435. USBPRINT_KdPrint3 (("'USBPRINT.SYS: Success in PAR_QUERY_DEVICE_ID\n"));
  436. Irp->IoStatus.Information=iReturn-1;
  437. *(pTempBuffer+iReturn)='\0';
  438. RtlCopyBytes(ioBuffer,pTempBuffer+2,iReturn-1); //+2 to step past the size bytes at the beginning, -1 is +1 for null -2 for size bytes
  439. ntStatus=STATUS_SUCCESS;
  440. } /*if success*/
  441. else
  442. {
  443. USBPRINT_KdPrint1 (("'USBPRINT.SYS: Failure in PAR_QUERY_DEVICE_ID\n"));
  444. Irp->IoStatus.Information=0;
  445. ntStatus=STATUS_DEVICE_DATA_ERROR;
  446. } /*else failure*/
  447. ExFreePool(pTempBuffer);
  448. } /*end else malloc OK*/
  449. USBPRINT_KdPrint1 (("'USBPRINT.SYS: Exit in PAR_QUERY_DEVICE_ID\n"));
  450. }
  451. break;
  452. case IOCTL_USBPRINT_SOFT_RESET:
  453. ntStatus=USBPRINT_SoftReset(DeviceObject);
  454. Irp->IoStatus.Information=0;
  455. break;
  456. case IOCTL_USBPRINT_GET_1284_ID:
  457. {
  458. int iReturn;
  459. pch = (PUCHAR) ioBuffer;
  460. if(outputBufferLength<sizeof(UCHAR))
  461. {
  462. USBPRINT_KdPrint1 (("'USBPRINT.SYS: Buffer to small in GET_1284_ID\n"));
  463. Irp->IoStatus.Information=0;
  464. ntStatus=STATUS_BUFFER_TOO_SMALL;
  465. }
  466. else
  467. {
  468. iReturn=USBPRINT_Get1284Id(DeviceObject,ioBuffer,outputBufferLength);
  469. if(iReturn>=0)
  470. {
  471. USBPRINT_KdPrint3 (("'USBPRINT.SYS: Success in GET_1284_ID\n"));
  472. *pch=(UCHAR)iReturn;
  473. Irp->IoStatus.Information=iReturn;
  474. ntStatus=STATUS_SUCCESS;
  475. } /*if success*/
  476. else
  477. {
  478. USBPRINT_KdPrint1 (("'USBPRINT.SYS: Failure in GET_1284_ID\n"));
  479. Irp->IoStatus.Information=0;
  480. ntStatus=STATUS_DEVICE_DATA_ERROR;
  481. } /*else failure*/
  482. } /*end else buffer len OK*/
  483. }
  484. break; //end case GET_1284_ID
  485. case IOCTL_USBPRINT_GET_LPT_STATUS:
  486. {
  487. int iReturn;
  488. pch = (PUCHAR) ioBuffer;
  489. if(outputBufferLength<sizeof(UCHAR))
  490. {
  491. USBPRINT_KdPrint1 (("'USBPRINT.SYS: Buffer to small in GET_LPT_STATUS\n"));
  492. Irp->IoStatus.Information=0;
  493. ntStatus=STATUS_BUFFER_TOO_SMALL;
  494. }
  495. else
  496. {
  497. iReturn= USBPRINT_GetLptStatus(DeviceObject);
  498. if(iReturn>=0)
  499. {
  500. USBPRINT_KdPrint3 (("'USBPRINT.SYS: Success in GET_LPT_STATUS\n"));
  501. *pch=(UCHAR)iReturn;
  502. Irp->IoStatus.Information=1;
  503. ntStatus=STATUS_SUCCESS;
  504. } /*if success*/
  505. else
  506. {
  507. USBPRINT_KdPrint1 (("'USBPRINT.SYS: Failure in GET_LPT_STATUS\n"));
  508. Irp->IoStatus.Information=0;
  509. ntStatus=STATUS_DEVICE_DATA_ERROR;
  510. } /*else failure*/
  511. } /*end else buffer OK*/
  512. }
  513. break;
  514. case IOCTL_USBPRINT_VENDOR_SET_COMMAND:
  515. ntStatus=HPUsbIOCTLVendorSetCommand(DeviceObject,Irp);
  516. break;
  517. case IOCTL_USBPRINT_VENDOR_GET_COMMAND:
  518. ntStatus=HPUsbIOCTLVendorGetCommand(DeviceObject,Irp);
  519. break;
  520. case IOCTL_USBPRINT_RESET_DEVICE:
  521. {
  522. ULONG portStatus;
  523. USBPRINT_KdPrint3 (("'USBPRINT.SYS: Reset Device Test\n"));
  524. TRAP(); // test this
  525. //
  526. // Check the port state, if it is disabled we will need
  527. // to re-enable it
  528. //
  529. ntStatus = USBPRINT_GetPortStatus(DeviceObject, &portStatus);
  530. if (NT_SUCCESS(ntStatus) && !(portStatus & USBD_PORT_ENABLED) &&portStatus & USBD_PORT_CONNECTED)
  531. {
  532. //
  533. // port is disabled, attempt reset
  534. //
  535. //USBPRINT_EnableParentPort(DeviceObject);
  536. USBPRINT_KdPrint2 (("'USBPRINT.SYS: Resetting port\n"));
  537. USBPRINT_ResetParentPort(DeviceObject);
  538. }
  539. }
  540. break;
  541. default:
  542. ntStatus = STATUS_INVALID_DEVICE_REQUEST;
  543. break;
  544. }
  545. Irp->IoStatus.Status = ntStatus;
  546. IoCompleteRequest (Irp,
  547. IO_NO_INCREMENT
  548. );
  549. USBPRINT_DecrementIoCount(DeviceObject);
  550. return ntStatus;
  551. }
  552. /****************STUFF FROM HP:*************************/
  553. /*-------------------------------------------------------------------------------
  554. * HPUsbIOCTLVendorSetCommand() - Send a vendor defined SET command
  555. *-------------------------------------------------------------------------------
  556. */
  557. NTSTATUS HPUsbIOCTLVendorSetCommand(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
  558. {
  559. // Local Variables
  560. NTSTATUS ntStatus;
  561. PIO_STACK_LOCATION currentIrpStack;
  562. // Set up a local pointer to the Irp stack
  563. currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
  564. // Send the SET command
  565. ntStatus = HPUsbVendorSetCommand(DeviceObject,
  566. (PUCHAR) Irp->AssociatedIrp.SystemBuffer,
  567. currentIrpStack->Parameters.DeviceIoControl.InputBufferLength);
  568. // Set the Irp information values
  569. Irp->IoStatus.Status = ntStatus;
  570. Irp->IoStatus.Information = 0;
  571. // Return
  572. return ntStatus;
  573. }
  574. /*-------------------------------------------------------------------------------
  575. * HPUsbIOCTLVendorGetCommand() - Send a vendor defined GET command
  576. *-------------------------------------------------------------------------------
  577. */
  578. NTSTATUS HPUsbIOCTLVendorGetCommand(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
  579. {
  580. // Local Variables
  581. NTSTATUS ntStatus;
  582. PIO_STACK_LOCATION currentIrpStack;
  583. ULONG bytesRead = 0;
  584. // Set up a local pointer to the Irp stack
  585. currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
  586. // Get the port status
  587. ntStatus = HPUsbVendorGetCommand(DeviceObject,
  588. (PUCHAR) Irp->AssociatedIrp.SystemBuffer,
  589. currentIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
  590. &bytesRead);
  591. // Set the Irp information values
  592. Irp->IoStatus.Status = ntStatus;
  593. Irp->IoStatus.Information = bytesRead;
  594. // Return
  595. return ntStatus;
  596. }
  597. /*-------------------------------------------------------------------------------
  598. * HPUsbVendorSetCommand() - Send a vendor specified SET command
  599. *
  600. * Inputs:
  601. * buffer[0] - Vendor Request Code (bRequest function code)
  602. * buffer[1] - Vendor Request Value Most Significant Byte (wValue MSB)
  603. * buffer[2] - Vendor Request Value Least Significant Byte (wValue LSB)
  604. * buffer[3...] - Any data to be sent as part of the command
  605. *
  606. *-------------------------------------------------------------------------------
  607. */
  608. NTSTATUS HPUsbVendorSetCommand(IN PDEVICE_OBJECT DeviceObject,
  609. IN PUCHAR buffer,
  610. IN ULONG length)
  611. {
  612. // Local variables
  613. NTSTATUS ntStatus;
  614. PDEVICE_EXTENSION deviceExtension;
  615. PUSBD_INTERFACE_INFORMATION interface;
  616. PURB urb;
  617. ULONG size;
  618. UCHAR bRequest;
  619. USHORT wValue;
  620. USHORT wIndex;
  621. if ( buffer == NULL || length < 3 )
  622. return STATUS_INVALID_PARAMETER;
  623. // Set up a local pointer to the device extension
  624. deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  625. // Set up a local pointer to the interface
  626. interface = deviceExtension->Interface;
  627. // Determine the size of the URB
  628. size = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
  629. // Allocate memory for the USB Request Block (URB)
  630. // urb = (PURB)
  631. // ExAllocatePoolWithTag(NonPagedPool,size,HPUSB_ALLOC_TAG);
  632. urb = ExAllocatePoolWithTag(NonPagedPool,size, USBP_TAG);
  633. // Check for an error
  634. if (urb == NULL)
  635. return STATUS_NO_MEMORY;
  636. // Store the vendor request code
  637. bRequest = buffer[0];
  638. // Store the vendor request parameter
  639. wValue = (buffer[1] << 8) | buffer[2];
  640. // Create the wIndex value (Interface:Alternate)
  641. wIndex = (interface->InterfaceNumber << 8) |
  642. (interface->AlternateSetting);
  643. // Use a macro in the standard USB header files to build the URB
  644. UsbBuildVendorRequest(urb,
  645. URB_FUNCTION_VENDOR_INTERFACE,
  646. (USHORT) size,
  647. 0,
  648. 0,
  649. bRequest,
  650. wValue,
  651. wIndex,
  652. buffer,
  653. NULL,
  654. length,
  655. NULL);
  656. //
  657. // Timeout cancellation should happen from user mode
  658. //
  659. ntStatus = USBPRINT_CallUSBD(DeviceObject,urb, NULL);
  660. // Free allocated memory
  661. ExFreePool(urb);
  662. // Return Success
  663. return ntStatus;
  664. }
  665. /*-------------------------------------------------------------------------------
  666. * HPUsbVendorGetCommand() - Send a vendor specified GET command
  667. *
  668. * Inputs:
  669. * buffer[0] - Vendor Request Code (bRequest function code)
  670. * buffer[1] - Vendor Request Value Most Significant Byte (wValue MSB)
  671. * buffer[2] - Vendor Request Value Least Significant Byte (wValue LSB)
  672. * Outputs:
  673. * buffer[ ] - Response data
  674. *
  675. *-------------------------------------------------------------------------------
  676. */
  677. NTSTATUS HPUsbVendorGetCommand(IN PDEVICE_OBJECT DeviceObject,
  678. IN PUCHAR buffer,
  679. IN ULONG length,
  680. OUT PULONG pBytesRead)
  681. {
  682. // Local variables
  683. NTSTATUS ntStatus;
  684. PDEVICE_EXTENSION deviceExtension;
  685. PUSBD_INTERFACE_INFORMATION interface;
  686. PURB urb;
  687. ULONG size;
  688. UCHAR bRequest;
  689. USHORT wValue;
  690. USHORT wIndex;
  691. if ( buffer == NULL || length < 3 )
  692. return STATUS_INVALID_PARAMETER;
  693. // Initialize the pBytesRead return value
  694. *pBytesRead = 0;
  695. // Set up a local pointer to the device extension
  696. deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  697. // Set up a local pointer to the interface
  698. interface = deviceExtension->Interface;
  699. // Determine the size of the URB
  700. size = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
  701. // Allocate memory for the USB Request Block (URB)
  702. // urb = (PURB)
  703. // ExAllocatePoolWithTag(NonPagedPool,size,HPUSB_ALLOC_TAG);
  704. urb = ExAllocatePoolWithTag(NonPagedPool,size, USBP_TAG);
  705. // Check for an error
  706. if (urb == NULL)
  707. return STATUS_NO_MEMORY;
  708. // Store the vendor request code
  709. bRequest = buffer[0];
  710. // Store the vendor request parameter
  711. wValue = (buffer[1] << 8) | buffer[2];
  712. // Create the wIndex value (Interface:Alternate)
  713. wIndex = (interface->InterfaceNumber << 8) |
  714. (interface->AlternateSetting);
  715. // Use a macro in the standard USB header files to build the URB
  716. UsbBuildVendorRequest(urb,
  717. URB_FUNCTION_VENDOR_INTERFACE,
  718. (USHORT) size,
  719. USBD_TRANSFER_DIRECTION_IN |
  720. USBD_SHORT_TRANSFER_OK,
  721. 0,
  722. bRequest,
  723. wValue,
  724. wIndex,
  725. buffer,
  726. NULL,
  727. length,
  728. NULL);
  729. //
  730. // Timeout cancellation should happen from user mode
  731. //
  732. ntStatus = USBPRINT_CallUSBD(DeviceObject,urb, NULL);
  733. // Retrieve the number of bytes read
  734. if (NT_SUCCESS(ntStatus))
  735. *pBytesRead = urb->UrbControlVendorClassRequest.TransferBufferLength;
  736. // Free allocated memory
  737. ExFreePool(urb);
  738. // Return Success
  739. return ntStatus;
  740. }
  741. /*
  742. // -----------------------------------------------------------
  743. // Kernel Mode Usage
  744. // -----------------------------------------------------------
  745. // Create the channel change request
  746. Buffer[0] = HP_VENDOR_COMMAND_DO_SOMETHING;
  747. Buffer[1] = HP_PARAMETER_UPPER_BYTE;
  748. Buffer[2] = HP_PARAMETER_LOWER_BYTE;
  749. // Send the request
  750. status = CallDeviceIoControl(
  751. m_pTargetDeviceObject, // the device to send the new irp to
  752. IOCTL_HPUSB_VENDOR_GET_COMMAND, // the ioctl to send to the driver ,
  753. Buffer, // the input buffer for the ioctl
  754. 3, // the length of the input buffer
  755. Buffer, // the output buffer for the ioctl
  756. 1, // the length of the output buffer
  757. FALSE, // create the irp with IRP_MJ_DEVICE_CONTROL
  758. NULL); // use the provided completion routine
  759. */