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.

521 lines
14 KiB

  1. //----------------- Original Sig ------------------------
  2. /*++
  3. Copyright (c) 1991-1999 Microsoft Corporation
  4. Module Name:
  5. fpfilter.c
  6. --*/
  7. #define INITGUID
  8. #include "wdm.h"
  9. #include "stdarg.h"
  10. #include "stdio.h"
  11. #include "usbdi.h"
  12. #include "usbdlib.h"
  13. //
  14. // Bit Flag Macros
  15. //
  16. #define SET_FLAG(Flags, Bit) ((Flags) |= (Bit))
  17. #define CLEAR_FLAG(Flags, Bit) ((Flags) &= ~(Bit))
  18. #define TEST_FLAG(Flags, Bit) (((Flags) & (Bit)) != 0)
  19. //
  20. // Remove lock
  21. //
  22. #define REMLOCK_TAG 'QV2K'
  23. #define REMLOCK_MAXIMUM 1 // Max minutes system allows lock to be held
  24. #define REMLOCK_HIGHWATER 250 // Max number of irps holding lock at one time
  25. //
  26. // Device Extension
  27. //
  28. typedef struct _FDO_EXTENSION {
  29. ULONG Signature;
  30. PDEVICE_OBJECT Fdo; // Back pointer to Fdo
  31. PDEVICE_OBJECT Pdo; // Not Used
  32. PDEVICE_OBJECT Ldo; // Lower Device Object
  33. PDEVICE_OBJECT PhysicalDeviceObject; // Not Used
  34. KEVENT SyncEvent; // for ForwardIrpSynchronous
  35. } FDO_EXTENSION, *PFDO_EXTENSION;
  36. #define FDO_EXTENSION_SIZE sizeof(FDO_EXTENSION)
  37. //
  38. // Function declarations
  39. //
  40. NTSTATUS DriverEntry ( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
  41. NTSTATUS QV2KUX_AddDevice ( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject);
  42. VOID QV2KUX_Unload ( IN PDRIVER_OBJECT DriverObject );
  43. NTSTATUS QV2KUX_ForwardIrpSynchronous( IN PDEVICE_OBJECT Fdo, IN PIRP Irp);
  44. NTSTATUS QV2KUX_DispatchPnp ( IN PDEVICE_OBJECT Fdo, IN PIRP Irp);
  45. NTSTATUS QV2KUX_DispatchPower ( IN PDEVICE_OBJECT Fdo, IN PIRP Irp);
  46. NTSTATUS QV2KUX_StartDevice ( IN PDEVICE_OBJECT Fdo, IN PIRP Irp);
  47. NTSTATUS QV2KUX_RemoveDevice ( IN PDEVICE_OBJECT Fdo, IN PIRP Irp);
  48. NTSTATUS QV2KUX_SendToNextDriver ( IN PDEVICE_OBJECT Fdo, IN PIRP Irp);
  49. NTSTATUS QV2KUX_Internal_IOCTL ( IN PDEVICE_OBJECT Fdo, IN PIRP Irp);
  50. NTSTATUS QV2KUX_IrpCompletion ( IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN PVOID Context);
  51. VOID QV2KUX_SyncFilterWithLdo ( IN PDEVICE_OBJECT Fdo, IN PDEVICE_OBJECT Ldo);
  52. #if DBG
  53. #define DEBUG_BUFFER_LENGTH 256
  54. ULONG QV2KUX_Debug = 0;
  55. UCHAR QV2KUX_DebugBuffer[DEBUG_BUFFER_LENGTH];
  56. VOID QV2KUX_DebugPrint( ULONG DebugPrintLevel, PCCHAR DebugMessage, ...);
  57. #define DebugPrint(x) QV2KUX_DebugPrint x
  58. #else
  59. #define DebugPrint(x)
  60. #endif
  61. NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
  62. /*++
  63. Routine Description:
  64. ł̓Gg[|Cg̐ݒ
  65. Arguments:
  66. DriverObject - The disk performance driver object.
  67. RegistryPath - pointer to a unicode string representing the path,
  68. to driver-specific key in the registry.
  69. Return Value:
  70. STATUS_SUCCESS
  71. --*/
  72. {
  73. ULONG ulIndex;
  74. PDRIVER_DISPATCH * dispatch;
  75. // �Ƃ肠�����S�ăo�C�p�X�����悤�ɐݒ�
  76. for (ulIndex = 0, dispatch = DriverObject->MajorFunction;
  77. ulIndex <= IRP_MJ_MAXIMUM_FUNCTION;
  78. ulIndex++, dispatch++) {
  79. *dispatch = QV2KUX_SendToNextDriver;
  80. }
  81. // ���L�̐ݒ��ł͂܂��������̕ύX
  82. DriverObject->MajorFunction[IRP_MJ_POWER] = QV2KUX_DispatchPower;
  83. DriverObject->DriverUnload = QV2KUX_Unload;
  84. //�Œ����K�v�Ȃ���
  85. DriverObject->MajorFunction[IRP_MJ_PNP] = QV2KUX_DispatchPnp;
  86. DriverObject->DriverExtension->AddDevice = QV2KUX_AddDevice;
  87. // �����I�ɂ��肽����������
  88. DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = QV2KUX_Internal_IOCTL;
  89. return(STATUS_SUCCESS);
  90. } // end DriverEntry()
  91. #define FILTER_DEVICE_PROPOGATE_FLAGS 0
  92. #define FILTER_DEVICE_PROPOGATE_CHARACTERISTICS (FILE_REMOVABLE_MEDIA | \
  93. FILE_READ_ONLY_DEVICE | \
  94. FILE_FLOPPY_DISKETTE \
  95. )
  96. VOID QV2KUX_SyncFilterWithLdo( IN PDEVICE_OBJECT Fdo, IN PDEVICE_OBJECT Ldo)
  97. {
  98. ULONG propFlags;
  99. //
  100. // Propogate all useful flags from target to QV2KUX_. MountMgr will look
  101. // at the QV2KUX_ object capabilities to figure out if the disk is
  102. // a removable and perhaps other things.
  103. //
  104. propFlags = Ldo->Flags & FILTER_DEVICE_PROPOGATE_FLAGS;
  105. SET_FLAG(Fdo->Flags, propFlags);
  106. propFlags = Ldo->Characteristics & FILTER_DEVICE_PROPOGATE_CHARACTERISTICS;
  107. SET_FLAG(Fdo->Characteristics, propFlags);
  108. }
  109. NTSTATUS QV2KUX_AddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
  110. /*++
  111. Routine Description:
  112. DeviceObject̍ƂDeviceExtension̏
  113. ̃vOł́APDO͍ȂFDÔݎgp
  114. Arguments:
  115. DriverObject - Disk performance driver object.
  116. PhysicalDeviceObject - Physical Device Object from the underlying layered driver
  117. Return Value:
  118. NTSTATUS
  119. --*/
  120. {
  121. NTSTATUS status;
  122. PDEVICE_OBJECT Fdo;
  123. PFDO_EXTENSION fdoExtension;
  124. PIRP irp;
  125. // Create a filter device object for this device (partition).
  126. DebugPrint((2, "QV2KUX_AddDevice: Driver %p Device %p\n", DriverObject, PhysicalDeviceObject));
  127. status = IoCreateDevice(DriverObject, FDO_EXTENSION_SIZE, NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &Fdo);
  128. if (!NT_SUCCESS(status)) {
  129. DebugPrint((1, "QV2KUX_AddDevice: Cannot create Fdo\n"));
  130. return status;
  131. }
  132. SET_FLAG(Fdo->Flags, DO_DIRECT_IO);
  133. fdoExtension = Fdo->DeviceExtension;
  134. RtlZeroMemory(fdoExtension, FDO_EXTENSION_SIZE);
  135. fdoExtension->Signature = 'QV2K';
  136. fdoExtension->Fdo = Fdo;
  137. fdoExtension->PhysicalDeviceObject = PhysicalDeviceObject;
  138. // ���ʃh���C�o�ɐڑ�
  139. fdoExtension->Ldo = IoAttachDeviceToDeviceStack(Fdo, PhysicalDeviceObject);
  140. if (fdoExtension->Ldo == NULL) {
  141. IoDeleteDevice(Fdo);
  142. DebugPrint((1, "QV2KUX_AddDevice: Unable to attach %X to target %X\n", Fdo, PhysicalDeviceObject));
  143. return STATUS_NO_SUCH_DEVICE;
  144. }
  145. // ForwardIrpSynchronous�Ŏg�p����
  146. KeInitializeEvent(&fdoExtension->SyncEvent, NotificationEvent, FALSE);
  147. // default to DO_POWER_PAGABLE
  148. SET_FLAG(Fdo->Flags, DO_POWER_PAGABLE);
  149. // Clear the DO_DEVICE_INITIALIZING flag
  150. CLEAR_FLAG(Fdo->Flags, DO_DEVICE_INITIALIZING);
  151. return STATUS_SUCCESS;
  152. } // end QV2KUX_AddDevice()
  153. NTSTATUS QV2KUX_DispatchPnp(IN PDEVICE_OBJECT Fdo, IN PIRP Irp)
  154. /*++
  155. Routine Description:
  156. Dispatch for PNP
  157. Arguments:
  158. Fdo - Supplies the device object.
  159. Irp - Supplies the I/O request packet.
  160. Return Value:
  161. NTSTATUS
  162. --*/
  163. {
  164. PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
  165. NTSTATUS status;
  166. PFDO_EXTENSION fdoExtension = Fdo->DeviceExtension;
  167. BOOLEAN lockHeld;
  168. BOOLEAN irpCompleted;
  169. DebugPrint((2, "QV2KUX_DispatchPnp: Device %X Irp %X\n", Fdo, Irp));
  170. irpCompleted = FALSE;
  171. switch(irpSp->MinorFunction) {
  172. case IRP_MN_START_DEVICE: status = QV2KUX_StartDevice(Fdo, Irp); break;
  173. case IRP_MN_REMOVE_DEVICE: status = QV2KUX_RemoveDevice(Fdo, Irp); break;
  174. default: status = QV2KUX_SendToNextDriver(Fdo, Irp); irpCompleted = TRUE; break;
  175. }
  176. if (! irpCompleted) {
  177. Irp->IoStatus.Status = status;
  178. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  179. }
  180. return status;
  181. } // end QV2KUX_DispatchPnp()
  182. NTSTATUS QV2KUX_IrpCompletion( IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN PVOID Context)
  183. /*++
  184. Routine Description:
  185. Forwarded IRP completion routine. Set an event and return
  186. STATUS_MORE_PROCESSING_REQUIRED. Irp forwarder will wait on this
  187. event and then re-complete the irp after cleaning up.
  188. Arguments:
  189. Fdo is the device object of the WMI driver
  190. Irp is the WMI irp that was just completed
  191. Context is a PKEVENT that forwarder will wait on
  192. Return Value:
  193. STATUS_MORE_PORCESSING_REQUIRED
  194. --*/
  195. {
  196. PKEVENT Event = (PKEVENT) Context;
  197. UNREFERENCED_PARAMETER(Fdo);
  198. UNREFERENCED_PARAMETER(Irp);
  199. KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
  200. // Irp���܂��g���A���ɂ�Completion���܂��m�点�Ȃ�
  201. return(STATUS_MORE_PROCESSING_REQUIRED);
  202. } // end QV2KUX_IrpCompletion()
  203. NTSTATUS QV2KUX_StartDevice( IN PDEVICE_OBJECT Fdo, IN PIRP Irp)
  204. /*++
  205. Routine Description:
  206. This routine is called when a Pnp Start Irp is received.
  207. It will schedule a completion routine to initialize and register with WMI.
  208. Arguments:
  209. Fdo - a pointer to the device object
  210. Irp - a pointer to the irp
  211. Return Value:
  212. Status of processing the Start Irp
  213. --*/
  214. {
  215. PFDO_EXTENSION fdoExtension = Fdo->DeviceExtension;
  216. KEVENT event;
  217. NTSTATUS status;
  218. status = QV2KUX_ForwardIrpSynchronous(Fdo, Irp);
  219. QV2KUX_SyncFilterWithLdo(Fdo, fdoExtension->Ldo);
  220. return status;
  221. }
  222. NTSTATUS QV2KUX_RemoveDevice( IN PDEVICE_OBJECT Fdo, IN PIRP Irp)
  223. /*++
  224. Routine Description:
  225. This routine is called when the device is to be removed.
  226. It will de-register itself from WMI first, detach itself from the
  227. stack before deleting itself.
  228. Arguments:
  229. Fdo - a pointer to the device object
  230. Irp - a pointer to the irp
  231. Return Value:
  232. Status of removing the device
  233. --*/
  234. {
  235. NTSTATUS status;
  236. PFDO_EXTENSION fdoExtension = Fdo->DeviceExtension;
  237. status = QV2KUX_ForwardIrpSynchronous(Fdo, Irp);
  238. IoDetachDevice(fdoExtension->Ldo);
  239. IoDeleteDevice(Fdo);
  240. return status;
  241. }
  242. NTSTATUS QV2KUX_SendToNextDriver( IN PDEVICE_OBJECT Fdo, IN PIRP Irp)
  243. /*++
  244. Routine Description:
  245. This routine sends the Irp to the next driver in line
  246. when the Irp is not processed by this driver.
  247. Arguments:
  248. Fdo
  249. Irp
  250. Return Value:
  251. NTSTATUS
  252. --*/
  253. {
  254. PFDO_EXTENSION fdoExtension = Fdo->DeviceExtension;
  255. IoSkipCurrentIrpStackLocation(Irp);
  256. return IoCallDriver(fdoExtension->Ldo, Irp);
  257. } // end QV2KUX_SendToNextDriver()
  258. NTSTATUS QV2KUX_DispatchPower( IN PDEVICE_OBJECT Fdo, IN PIRP Irp)
  259. {
  260. PFDO_EXTENSION fdoExtension = Fdo->DeviceExtension;
  261. PoStartNextPowerIrp(Irp);
  262. IoSkipCurrentIrpStackLocation(Irp);
  263. return PoCallDriver(fdoExtension->Ldo, Irp);
  264. } // end QV2KUX_DispatchPower
  265. NTSTATUS QV2KUX_ForwardIrpSynchronous( IN PDEVICE_OBJECT Fdo, IN PIRP Irp)
  266. /*++
  267. Routine Description:
  268. This routine sends the Irp to the next driver in line
  269. when the Irp needs to be processed by the lower drivers
  270. prior to being processed by this one.
  271. Arguments:
  272. Fdo
  273. Irp
  274. Return Value:
  275. NTSTATUS
  276. --*/
  277. {
  278. PFDO_EXTENSION fdoExtension = Fdo->DeviceExtension;
  279. NTSTATUS status;
  280. //�C�x���g�̃N���A
  281. KeClearEvent(&fdoExtension->SyncEvent);
  282. //IrpStack�̃R�s�[
  283. IoCopyCurrentIrpStackLocationToNext(Irp);
  284. // IrpCompletion�̐ݒ�
  285. IoSetCompletionRoutine(Irp, QV2KUX_IrpCompletion, &fdoExtension->SyncEvent, TRUE, TRUE, TRUE);
  286. // call the next lower device
  287. status = IoCallDriver(fdoExtension->Ldo, Irp);
  288. // wait for the actual completion
  289. if (status == STATUS_PENDING) {
  290. KeWaitForSingleObject(&fdoExtension->SyncEvent, Executive, KernelMode, FALSE, NULL);
  291. status = Irp->IoStatus.Status;
  292. }
  293. return status;
  294. } // end QV2KUX_ForwardIrpSynchronous()
  295. VOID QV2KUX_Unload( IN PDRIVER_OBJECT DriverObject)
  296. /*++
  297. Routine Description:
  298. Free all the allocated resources, etc.
  299. Arguments:
  300. DriverObject - pointer to a driver object.
  301. Return Value:
  302. VOID.
  303. --*/
  304. {
  305. return;
  306. }
  307. NTSTATUS QV2KUX_Internal_IOCTL(IN PDEVICE_OBJECT Fdo, IN PIRP Irp)
  308. {
  309. PFDO_EXTENSION fdoExtension = Fdo->DeviceExtension;
  310. NTSTATUS ntStatus;
  311. PIO_STACK_LOCATION IrpSp;
  312. PURB urb;
  313. PUCHAR IoBuffer;
  314. USHORT length;
  315. UCHAR subclass;
  316. if (fdoExtension->Signature != 'QV2K') return QV2KUX_SendToNextDriver(Fdo,Irp);
  317. IrpSp = IoGetCurrentIrpStackLocation(Irp);
  318. urb = IrpSp->Parameters.Others.Argument1;
  319. if (!urb) return QV2KUX_SendToNextDriver(Fdo,Irp);
  320. if (urb->UrbHeader.Function != URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE)
  321. return QV2KUX_SendToNextDriver(Fdo,Irp);
  322. // �P���ڂ� USB_DEVICE_DESCRIPTOR_TYPE Length = 0x12;
  323. // �Q���ڂ� USB_CONFIGURATION_DESCRIPTOR_TYPE LENGHT = 0x9
  324. // �R���ڂ� USB_CONFIGURATION_DESCRIPTOR_TYPE LENGHT = interface,endpoint descriptor���܂߂�����
  325. if (urb->UrbControlDescriptorRequest.TransferBufferLength <= 0x12)
  326. return QV2KUX_SendToNextDriver(Fdo,Irp);
  327. // �R���ڂ������ʉ߂���
  328. DebugPrint((0,"URB Get All of Configuration Descriptor \n"));
  329. ntStatus = QV2KUX_ForwardIrpSynchronous(Fdo,Irp);
  330. if (NT_SUCCESS(ntStatus)) {
  331. IoBuffer = (UCHAR *)urb->UrbControlDescriptorRequest.TransferBuffer;
  332. length = (USHORT)urb->UrbControlDescriptorRequest.TransferBufferLength;
  333. while(length >= 9) {
  334. //InterfaceDescriptor���؂蕪����
  335. if (*(IoBuffer+1) == 4) {
  336. subclass = *(IoBuffer+6);
  337. DebugPrint((0,"QV2K_IntIoctl: SubCrass = %d \n",subclass));
  338. if (*(IoBuffer+6) == 6) *(IoBuffer+6) = 5;
  339. }
  340. length -= *IoBuffer;
  341. IoBuffer += *IoBuffer;
  342. }
  343. }
  344. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  345. return ntStatus;
  346. }
  347. #if DBG
  348. VOID
  349. QV2KUX_DebugPrint(
  350. ULONG DebugPrintLevel,
  351. PCCHAR DebugMessage,
  352. ...
  353. )
  354. /*++
  355. Routine Description:
  356. Debug print for all QV2KUX_
  357. Arguments:
  358. Debug print level between 0 and 3, with 3 being the most verbose.
  359. Return Value:
  360. None
  361. --*/
  362. {
  363. va_list ap;
  364. va_start(ap, DebugMessage);
  365. if ((DebugPrintLevel <= (QV2KUX_Debug & 0x0000ffff)) ||
  366. ((1 << (DebugPrintLevel + 15)) & QV2KUX_Debug)) {
  367. _vsnprintf(QV2KUX_DebugBuffer, DEBUG_BUFFER_LENGTH, DebugMessage, ap);
  368. DbgPrint(QV2KUX_DebugBuffer);
  369. }
  370. va_end(ap);
  371. }
  372. #endif
  373.