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.

312 lines
8.6 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. ioctl.c
  5. Abstract:
  6. USB device driver for Intel/Microsoft diagnostic apps
  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. 7-21-97 : Added Chapter 11 IOCTL's (t-toddca)
  18. --*/
  19. #define DRIVER
  20. #include "wdm.h"
  21. #include "stdarg.h"
  22. #include "stdio.h"
  23. // Enable 1-byte alignment in structs
  24. #pragma pack (push,1)
  25. #include "usb100.h"
  26. #include "usbdi.h"
  27. #include "usbdlib.h"
  28. #include "usbioctl.h"
  29. #pragma pack (pop) //disable 1-byte alignment
  30. #include "opaque.h"
  31. // Enable 1-byte alignment in structs
  32. #pragma pack (push,1)
  33. #include "ioctl.h"
  34. #include "chap9drv.h"
  35. #include "USBDIAG.h"
  36. #pragma pack (pop) //disable 1-byte alignment
  37. extern USBD_VERSION_INFORMATION gVersionInformation;
  38. NTSTATUS
  39. USBDIAG_ProcessIOCTL(
  40. IN PDEVICE_OBJECT DeviceObject,
  41. IN PIRP Irp
  42. )
  43. /*++
  44. Routine Description:
  45. Arguments:
  46. DeviceObject - pointer to the device object for this instance of the 82930
  47. devcice.
  48. Return Value:
  49. NT status code
  50. --*/
  51. {
  52. PIO_STACK_LOCATION irpStack;
  53. PVOID ioBuffer;
  54. ULONG inputBufferLength;
  55. ULONG outputBufferLength;
  56. PDEVICE_EXTENSION deviceExtension;
  57. ULONG ioControlCode;
  58. NTSTATUS ntStatus = STATUS_SUCCESS;
  59. USBDIAG_KdPrint(("USBDIAG.SYS: IRP_MJ_DEVICE_CONTROL\n"));
  60. //
  61. // Get a pointer to the current location in the Irp. This is where
  62. // the function codes and parameters are located.
  63. //
  64. irpStack = IoGetCurrentIrpStackLocation (Irp);
  65. Irp->IoStatus.Status = STATUS_SUCCESS;
  66. Irp->IoStatus.Information = 0;
  67. //
  68. // Get a pointer to the device extension
  69. //
  70. deviceExtension = DeviceObject->DeviceExtension;
  71. //USBDIAG_KdPrint(("USBDIAG.SYS: DeviceObj: %X | DeviceExt: %X\n",DeviceObject, DeviceObject->DeviceExtension));
  72. ioBuffer = Irp->AssociatedIrp.SystemBuffer;
  73. inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
  74. outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
  75. ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
  76. USBDIAG_KdPrint(("USBDIAG.SYS: IOControlCode: %X\n", ioControlCode));
  77. //
  78. // Handle Ioctls from User mode
  79. //
  80. switch (ioControlCode) {
  81. case IOCTL_USBDIAG_GET_USBDI_VERSION:
  82. {
  83. PULONG pulUSBDIVersion = (PULONG)ioBuffer;
  84. *pulUSBDIVersion = gVersionInformation.USBDI_Version;
  85. Irp->IoStatus.Status = ntStatus = STATUS_SUCCESS;
  86. Irp->IoStatus.Information = sizeof(ULONG);
  87. }
  88. break;
  89. case IOCTL_USBDIAG_CHAP9_GET_DEVHANDLE:
  90. {
  91. //
  92. // inputs - ptr to _REQ_DEVICE_HANDLES structure
  93. // with devicehandle set to the last handle
  94. // returned or NULL.
  95. // outputs -
  96. //
  97. struct _REQ_DEVICE_HANDLES *reqDeviceHandles;
  98. PDEVICE_LIST_ENTRY device;
  99. PDEVICE_EXTENSION localDeviceExtension;
  100. PDEVICE_OBJECT deviceObject;
  101. //USBDIAG_KdPrint(("USBDIAG.SYS: IOCTL_USBDIAG_CHAP9_GET_DEVHANDLE\n"));
  102. // walk our list of PDOs and find the current one
  103. // if cuurent is NULL return the first PDO in our list
  104. // if current can not be found then return NULL for next_device
  105. reqDeviceHandles = ioBuffer;
  106. //
  107. // Check that the buffer length is of the appropriate size
  108. //
  109. if (inputBufferLength < sizeof(struct _REQ_DEVICE_HANDLES) ||
  110. outputBufferLength < sizeof(struct _REQ_DEVICE_HANDLES)) {
  111. Irp->IoStatus.Information = 0;
  112. Irp->IoStatus.Status = STATUS_INVALID_BUFFER_SIZE;
  113. break;
  114. }
  115. device = deviceExtension->DeviceList;
  116. // should always have at least one
  117. if (device != NULL)
  118. {
  119. if (reqDeviceHandles->DeviceHandle != NULL)
  120. {
  121. //
  122. // Searching for the next device in the list
  123. //
  124. while (device != NULL && device != reqDeviceHandles->DeviceHandle)
  125. {
  126. device = device->Next;
  127. }
  128. //
  129. // Make device point to the next possible device in our list,
  130. // if we haven't reached the end of the list
  131. //
  132. if (NULL != device)
  133. {
  134. device = device -> Next;
  135. }
  136. }
  137. //
  138. // At this point, device is either NULL or points to a usbdiag
  139. // device. However, the diag device may not yet be started and
  140. // if so, should not be reported in this query so we must skip
  141. // over it. We will skip over all such devices in our list.
  142. // Do that here.
  143. //
  144. while (device != NULL)
  145. {
  146. deviceObject = FDO_FROM_DEVICE_HANDLE(device);
  147. localDeviceExtension = deviceObject -> DeviceExtension;
  148. if (!(localDeviceExtension -> Stopped))
  149. {
  150. //
  151. // Found a legit started device, break out of this loop
  152. //
  153. break;
  154. }
  155. //
  156. // Oops, we've got a device but it hasn't been started yet,
  157. // don't return it in the query. Try the next one in the list.
  158. //
  159. device = device -> Next;
  160. }
  161. //
  162. // At this point, device is either NULL or points to a device that
  163. // can be legitimately returned to the calling app. If a legit
  164. // device, then create a device string for it.
  165. //
  166. if (NULL != device)
  167. {
  168. sprintf(reqDeviceHandles->DeviceString,
  169. "%2.2d Vid (0x%4.4x) Pid (0x%4.4x)",
  170. device->DeviceNumber,
  171. localDeviceExtension->pDeviceDescriptor->idVendor,
  172. localDeviceExtension->pDeviceDescriptor->idProduct);
  173. }
  174. }
  175. reqDeviceHandles -> NextDeviceHandle = device;
  176. Irp->IoStatus.Information = sizeof(struct _REQ_DEVICE_HANDLES);
  177. Irp->IoStatus.Status = STATUS_SUCCESS;
  178. }
  179. break;
  180. case IOCTL_USBDIAG_CHAP9_CONTROL:
  181. //
  182. // inputs -
  183. // outputs -
  184. //
  185. //USBDIAG_KdPrint(("USBDIAG.SYS: IOCTL_USBDIAG_CHAP9_CONTROL\n"));
  186. ntStatus = USBDIAG_Chap9Control(DeviceObject, Irp);
  187. //USBDIAG_KdPrint(("USBDIAG.SYS: Done w/ IOCTL_USBDIAG_CHAP9_CONTROL\n"));
  188. goto USBDIAG_ProcessIOCTL_Done;
  189. break;
  190. case IOCTL_USBDIAG_HIDP_GETCOLLECTION:
  191. /*
  192. // calls thru to the HID Parser
  193. // NOTE: The function called will complete the IRP since it will
  194. // free the buffers created by the HID parser immediately
  195. // thereafter, and since BUFFERED method is used, the IOS
  196. // needs the buffers to be present while it's copying it
  197. // back to the user space. So, we jump to the end to avoid this.
  198. */
  199. //USBDIAG_KdPrint(("USBDIAG.SYS: IOCTL_USBDIAG_HIDP_GETCOLLECTION\n"));
  200. ntStatus = USBDIAG_HIDP_GetCollection (DeviceObject, Irp);
  201. break;
  202. case IOCTL_USBDIAG_CONFIGURE_DEVICE:
  203. /*
  204. // Configures a given device in the given configuration
  205. // Input: IOCTL block indicating what configuration to put
  206. // device into
  207. // Output: Success/error code
  208. //
  209. */
  210. //USBDIAG_KdPrint(("USBDIAG.SYS: IOCTL_USBDIAG_CONFIGURE_DEVICE\n"));
  211. ntStatus = USBDIAG_Configure_Device (DeviceObject, Irp);
  212. break;
  213. default:
  214. Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
  215. }
  216. //USBDIAG_KdPrint(("USBDIAG.SYS: Chap9Ctrl Compltng Irp w/ IoStatus.Status=%X | .Inf = %X | ntSt=%X\n",
  217. //Irp->IoStatus.Status, Irp->IoStatus.Information, ntStatus));
  218. ntStatus = Irp->IoStatus.Status;
  219. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  220. USBDIAG_ProcessIOCTL_Done:
  221. return ntStatus;
  222. }