ReactOS  0.4.15-dev-5112-g22d8c0f
pdo.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: drivers/usb/usbccgp/pdo.c
5  * PURPOSE: USB device driver.
6  * PROGRAMMERS:
7  * Michael Martin (michael.martin@reactos.org)
8  * Johannes Anderwald (johannes.anderwald@reactos.org)
9  * Cameron Gutman
10  */
11 
12 #include "usbccgp.h"
13 
14 #include <ntddk.h>
15 
16 #define NDEBUG
17 #include <debug.h>
18 
22  IN OUT PIRP Irp)
23 {
24  PIO_STACK_LOCATION IoStack;
25  LPWSTR Buffer;
26  PPDO_DEVICE_EXTENSION PDODeviceExtension;
27  LPWSTR GenericString = L"Composite USB Device";
28 
29  //
30  // get current irp stack location
31  //
33 
34  //
35  // get device extension
36  //
37  PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
38 
39  //
40  // check if type is description
41  //
42  if (IoStack->Parameters.QueryDeviceText.DeviceTextType != DeviceTextDescription)
43  {
44  //
45  // we only handle description
46  //
47  return Irp->IoStatus.Status;
48  }
49 
50  //
51  // is there a device description
52  //
53  if (PDODeviceExtension->FunctionDescriptor->FunctionDescription.Length)
54  {
55  //
56  // allocate buffer
57  //
58  Buffer = AllocateItem(NonPagedPool, PDODeviceExtension->FunctionDescriptor->FunctionDescription.Length + sizeof(WCHAR));
59  if (!Buffer)
60  {
61  //
62  // no memory
63  //
65  }
66 
67  //
68  // copy buffer
69  //
70  Irp->IoStatus.Information = (ULONG_PTR)Buffer;
71  RtlCopyMemory(Buffer, PDODeviceExtension->FunctionDescriptor->FunctionDescription.Buffer, PDODeviceExtension->FunctionDescriptor->FunctionDescription.Length);
72  return STATUS_SUCCESS;
73  }
74 
75  //
76  // FIXME use GenericCompositeUSBDeviceString
77  //
79  Buffer = AllocateItem(PagedPool, (wcslen(GenericString) + 1) * sizeof(WCHAR));
80  if (!Buffer)
81  {
82  //
83  // no memory
84  //
86  }
87  RtlCopyMemory(Buffer, GenericString, (wcslen(GenericString) + 1) * sizeof(WCHAR));
88  Irp->IoStatus.Information = (ULONG_PTR)Buffer;
89 
90  return STATUS_SUCCESS;
91 }
92 
96  IN OUT PIRP Irp)
97 {
98  PDEVICE_RELATIONS DeviceRelations;
99  PIO_STACK_LOCATION IoStack;
100 
101  DPRINT("USBCCGP_PdoHandleDeviceRelations\n");
102 
103  //
104  // get current irp stack location
105  //
107 
108  //
109  // check if relation type is BusRelations
110  //
111  if (IoStack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
112  {
113  //
114  // PDO handles only target device relation
115  //
116  return Irp->IoStatus.Status;
117  }
118 
119  //
120  // allocate device relations
121  //
122  DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS));
123  if (!DeviceRelations)
124  {
125  //
126  // no memory
127  //
129  }
130 
131  //
132  // initialize device relations
133  //
134  DeviceRelations->Count = 1;
135  DeviceRelations->Objects[0] = DeviceObject;
137 
138  //
139  // store result
140  //
141  Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
142 
143  //
144  // completed successfully
145  //
146  return STATUS_SUCCESS;
147 }
148 
149 NTSTATUS
151  IN LPWSTR DeviceId,
153  OUT LPWSTR *OutString)
154 {
155  ULONG Length = 0, StringLength;
156  LPWSTR String;
157 
158  //
159  // count length of string
160  //
161  String = DeviceId;
162  while (*String)
163  {
164  StringLength = wcslen(String) + 1;
165  Length += StringLength;
166  Length += 6; //&MI_XX
167  String += StringLength;
168  }
169 
170  //
171  // now allocate the buffer
172  //
173  String = AllocateItem(NonPagedPool, (Length + 2) * sizeof(WCHAR));
174  if (!String)
175  {
176  //
177  // no memory
178  //
180  }
181 
182  //
183  // store result
184  //
185  *OutString = String;
186 
187  while (*DeviceId)
188  {
189  StringLength = swprintf(String, L"%s&MI_%02x", DeviceId, InterfaceNumber) + 1;
190  Length = wcslen(DeviceId) + 1;
191  DPRINT("String %p\n", String);
192 
193  //
194  // next string
195  //
196  String += StringLength;
197  DeviceId += Length;
198  }
199 
200  //
201  // success
202  //
203  return STATUS_SUCCESS;
204 }
205 
206 
207 NTSTATUS
210  PIRP Irp)
211 {
212  PIO_STACK_LOCATION IoStack;
213  PUNICODE_STRING DeviceString = NULL;
214  PPDO_DEVICE_EXTENSION PDODeviceExtension;
216  LPWSTR Buffer;
217 
218  //
219  // get current irp stack location
220  //
222 
223  //
224  // get device extension
225  //
226  PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
227 
228 
229  if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID)
230  {
231  //
232  // handle query device id
233  //
234  if (IoForwardIrpSynchronously(PDODeviceExtension->NextDeviceObject, Irp))
235  {
236  Status = Irp->IoStatus.Status;
237  }
238  else
239  {
241  }
242 
243  if (NT_SUCCESS(Status))
244  {
245  //
246  // allocate buffer
247  //
248  Buffer = AllocateItem(NonPagedPool, (wcslen((LPWSTR)Irp->IoStatus.Information) + 7) * sizeof(WCHAR));
249  if (Buffer)
250  {
251  //
252  // append interface number
253  //
254  ASSERT(Irp->IoStatus.Information);
255  swprintf(Buffer, L"%s&MI_%02x", (LPWSTR)Irp->IoStatus.Information, PDODeviceExtension->FunctionDescriptor->FunctionNumber);
256  DPRINT("BusQueryDeviceID %S\n", Buffer);
257 
258  ExFreePool((PVOID)Irp->IoStatus.Information);
259  Irp->IoStatus.Information = (ULONG_PTR)Buffer;
260  }
261  else
262  {
263  //
264  // no memory
265  //
267  }
268  }
269  return Status;
270  }
271  else if (IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs)
272  {
273  //
274  // handle instance id
275  //
276  DeviceString = &PDODeviceExtension->FunctionDescriptor->HardwareId;
277  }
278  else if (IoStack->Parameters.QueryId.IdType == BusQueryInstanceID)
279  {
280  //
281  // handle instance id
282  //
283  Buffer = AllocateItem(NonPagedPool, 5 * sizeof(WCHAR));
284  if (!Buffer)
285  {
286  //
287  // no memory
288  //
290  }
291 
292  //
293  // use function number
294  //
295  swprintf(Buffer, L"%04x", PDODeviceExtension->FunctionDescriptor->FunctionNumber);
296  Irp->IoStatus.Information = (ULONG_PTR)Buffer;
297  return STATUS_SUCCESS;
298  }
299  else if (IoStack->Parameters.QueryId.IdType == BusQueryCompatibleIDs)
300  {
301  //
302  // handle instance id
303  //
304  DeviceString = &PDODeviceExtension->FunctionDescriptor->CompatibleId;
305  }
306  else
307  {
308  //
309  // unsupported query
310  //
311  return Irp->IoStatus.Status;
312  }
313 
314  //
315  // sanity check
316  //
317  ASSERT(DeviceString != NULL);
318 
319  //
320  // allocate buffer
321  //
322  Buffer = AllocateItem(NonPagedPool, DeviceString->Length + sizeof(WCHAR));
323  if (!Buffer)
324  {
325  //
326  // no memory
327  //
329  }
330 
331  //
332  // copy buffer
333  //
334  RtlCopyMemory(Buffer, DeviceString->Buffer, DeviceString->Length);
335  Buffer[DeviceString->Length / sizeof(WCHAR)] = UNICODE_NULL;
336  Irp->IoStatus.Information = (ULONG_PTR)Buffer;
337 
338  return STATUS_SUCCESS;
339 }
340 
341 NTSTATUS
344  PIRP Irp)
345 {
346  PIO_STACK_LOCATION IoStack;
347  PPDO_DEVICE_EXTENSION PDODeviceExtension;
349  ULONG Index, bFound;
350 
351  //
352  // get current stack location
353  //
355 
356  //
357  // get device extension
358  //
359  PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
360 
361  //
362  // sanity check
363  //
364  ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
365 
366  switch(IoStack->MinorFunction)
367  {
369  {
370  //
371  // handle device relations
372  //
374  break;
375  }
377  {
378  //
379  // handle query device text
380  //
382  break;
383  }
384  case IRP_MN_QUERY_ID:
385  {
386  //
387  // handle request
388  //
390  break;
391  }
393  {
394  //
395  // remove us from the fdo's pdo list
396  //
397  bFound = FALSE;
398  for(Index = 0; Index < PDODeviceExtension->FDODeviceExtension->FunctionDescriptorCount; Index++)
399  {
400  if (PDODeviceExtension->FDODeviceExtension->ChildPDO[Index] == DeviceObject)
401  {
402  //
403  // remove us
404  //
405  PDODeviceExtension->FDODeviceExtension->ChildPDO[Index] = NULL;
406  bFound = TRUE;
407  break;
408  }
409  }
410 
411  //
412  // Complete the IRP
413  //
414  Irp->IoStatus.Status = STATUS_SUCCESS;
416 
417  if (bFound)
418  {
419  //
420  // Delete the device object
421  //
423  }
424  return STATUS_SUCCESS;
425  }
427  {
428  //
429  // copy device capabilities
430  //
431  RtlCopyMemory(IoStack->Parameters.DeviceCapabilities.Capabilities, &PDODeviceExtension->Capabilities, sizeof(DEVICE_CAPABILITIES));
432 
433  /* Complete the IRP */
434  Irp->IoStatus.Status = STATUS_SUCCESS;
436  return STATUS_SUCCESS;
437  }
440  {
441  //
442  // sure
443  //
445  break;
446  }
447  case IRP_MN_START_DEVICE:
448  {
449  //
450  // no-op for PDO
451  //
452  DPRINT("[USBCCGP] PDO IRP_MN_START\n");
454  break;
455  }
457  {
458  //
459  // forward to lower device object
460  //
462  return IoCallDriver(PDODeviceExtension->NextDeviceObject, Irp);
463  }
464  default:
465  {
466  //
467  // do nothing
468  //
469  Status = Irp->IoStatus.Status;
470  break;
471  }
472  }
473 
474  //
475  // complete request
476  //
477  if (Status != STATUS_PENDING)
478  {
479  //
480  // store result
481  //
482  Irp->IoStatus.Status = Status;
483 
484  //
485  // complete request
486  //
488  }
489 
490  //
491  // done processing
492  //
493  return Status;
494 
495 }
496 
497 NTSTATUS
500  PIRP Irp)
501 {
502  PIO_STACK_LOCATION IoStack;
503  PPDO_DEVICE_EXTENSION PDODeviceExtension;
504  PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
506  ULONG TotalSize, Index;
507  ULONG Size;
508  PURB Urb;
509  PVOID Buffer;
510  PUCHAR BufferPtr;
512 
513  //
514  // get current stack location
515  //
517 
518  DPRINT("USBCCGP_BuildConfigurationDescriptor\n");
519 
520  //
521  // get device extension
522  //
523  PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
524 
525  //
526  // get configuration descriptor
527  //
528  ConfigurationDescriptor = PDODeviceExtension->ConfigurationDescriptor;
529 
530  //
531  // calculate size of configuration descriptor
532  //
533  TotalSize = sizeof(USB_CONFIGURATION_DESCRIPTOR);
534 
535  for (Index = 0; Index < PDODeviceExtension->FunctionDescriptor->NumberOfInterfaces; Index++)
536  {
537  //
538  // get current interface descriptor
539  //
540  InterfaceDescriptor = PDODeviceExtension->FunctionDescriptor->InterfaceDescriptorList[Index];
541  InterfaceNumber = InterfaceDescriptor->bInterfaceNumber;
542 
543  //
544  // add to size and move to next descriptor
545  //
546  TotalSize += InterfaceDescriptor->bLength;
548 
549  do
550  {
551  if ((ULONG_PTR)InterfaceDescriptor >= ((ULONG_PTR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength))
552  {
553  //
554  // reached end of configuration descriptor
555  //
556  break;
557  }
558 
559  //
560  // association descriptors are removed
561  //
563  {
564  if (InterfaceDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
565  {
566  if (InterfaceNumber != InterfaceDescriptor->bInterfaceNumber)
567  {
568  //
569  // reached next descriptor
570  //
571  break;
572  }
573 
574  //
575  // include alternate descriptor
576  //
577  }
578 
579  //
580  // append size
581  //
582  TotalSize += InterfaceDescriptor->bLength;
583  }
584 
585  //
586  // move to next descriptor
587  //
589  } while(TRUE);
590  }
591 
592  //
593  // now allocate temporary buffer for the configuration descriptor
594  //
595  Buffer = AllocateItem(NonPagedPool, TotalSize);
596  if (!Buffer)
597  {
598  //
599  // failed to allocate buffer
600  //
601  DPRINT1("[USBCCGP] Failed to allocate %lu Bytes\n", TotalSize);
603  }
604 
605  //
606  // first copy the configuration descriptor
607  //
608  RtlCopyMemory(Buffer, ConfigurationDescriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
609  BufferPtr = (PUCHAR)((ULONG_PTR)Buffer + ConfigurationDescriptor->bLength);
610 
611  for (Index = 0; Index < PDODeviceExtension->FunctionDescriptor->NumberOfInterfaces; Index++)
612  {
613  //
614  // get current interface descriptor
615  //
616  InterfaceDescriptor = PDODeviceExtension->FunctionDescriptor->InterfaceDescriptorList[Index];
617  InterfaceNumber = InterfaceDescriptor->bInterfaceNumber;
618 
619  //
620  // copy descriptor and move to next descriptor
621  //
623  BufferPtr += InterfaceDescriptor->bLength;
625 
626  do
627  {
628  if ((ULONG_PTR)InterfaceDescriptor >= ((ULONG_PTR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength))
629  {
630  //
631  // reached end of configuration descriptor
632  //
633  break;
634  }
635 
636  //
637  // association descriptors are removed
638  //
640  {
641  if (InterfaceDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
642  {
643  if (InterfaceNumber != InterfaceDescriptor->bInterfaceNumber)
644  {
645  //
646  // reached next descriptor
647  //
648  break;
649  }
650 
651  //
652  // include alternate descriptor
653  //
654  DPRINT("InterfaceDescriptor %p Alternate %x InterfaceNumber %x\n", InterfaceDescriptor, InterfaceDescriptor->bAlternateSetting, InterfaceDescriptor->bInterfaceNumber);
655  }
656 
657  //
658  // copy descriptor
659  //
661  BufferPtr += InterfaceDescriptor->bLength;
662  }
663 
664  //
665  // move to next descriptor
666  //
668  } while(TRUE);
669  }
670 
671  //
672  // modify configuration descriptor
673  //
674  ConfigurationDescriptor = Buffer;
675  ConfigurationDescriptor->wTotalLength = (USHORT)TotalSize;
676  ConfigurationDescriptor->bNumInterfaces = PDODeviceExtension->FunctionDescriptor->NumberOfInterfaces;
677 
678  //
679  // get urb
680  //
681  Urb = (PURB)IoStack->Parameters.Others.Argument1;
682  ASSERT(Urb);
683 
684  //
685  // copy descriptor
686  //
687  Size = min(TotalSize, Urb->UrbControlDescriptorRequest.TransferBufferLength);
688  RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, Buffer, Size);
689 
690  //
691  // store final size
692  //
693  Urb->UrbControlDescriptorRequest.TransferBufferLength = Size;
694 
695  //
696  // free buffer
697  //
698  FreeItem(Buffer);
699 
700  //
701  // done
702  //
703  return STATUS_SUCCESS;
704 }
705 
706 NTSTATUS
709  PIRP Irp)
710 {
711  PIO_STACK_LOCATION IoStack;
712  PPDO_DEVICE_EXTENSION PDODeviceExtension;
713  PURB Urb, NewUrb;
714  PUSBD_INTERFACE_INFORMATION InterfaceInformation;
717  ULONG NeedSelect, FoundInterface;
719 
720  //
721  // get current stack location
722  //
724 
725  //
726  // get device extension
727  //
728  PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
729 
730  //
731  // get urb
732  //
733  Urb = (PURB)IoStack->Parameters.Others.Argument1;
734  ASSERT(Urb);
735 
736  //
737  // is there already an configuration handle
738  //
739  if (Urb->UrbSelectConfiguration.ConfigurationHandle)
740  {
741  //
742  // nothing to do
743  //
744  return STATUS_SUCCESS;
745  }
746 
747  //
748  // if there is no configuration descriptor, unconfigure the device
749  //
750  if (Urb->UrbSelectConfiguration.ConfigurationDescriptor == NULL)
751  {
752  return STATUS_SUCCESS;
753  }
754 
755  // sanity checks
756  //C_ASSERT(sizeof(struct _URB_HEADER) == 16);
757  //C_ASSERT(FIELD_OFFSET(struct _URB_SELECT_CONFIGURATION, Interface.Length) == 24);
758  //C_ASSERT(sizeof(USBD_INTERFACE_INFORMATION) == 36);
759  //C_ASSERT(sizeof(struct _URB_SELECT_CONFIGURATION) == 0x3C);
760 
761  // available buffer length
763 
764  //
765  // check all interfaces
766  //
767  InterfaceInformation = &Urb->UrbSelectConfiguration.Interface;
768 
769  Entry = NULL;
770  do
771  {
772  DPRINT1("[USBCCGP] SelectConfiguration Function %x InterfaceNumber %x Alternative %x Length %lu InterfaceInformation->Length %lu\n", PDODeviceExtension->FunctionDescriptor->FunctionNumber, InterfaceInformation->InterfaceNumber, InterfaceInformation->AlternateSetting, Length, InterfaceInformation->Length);
773  ASSERT(InterfaceInformation->Length);
774  //
775  // search for the interface in the local interface list
776  //
777  FoundInterface = FALSE;
778  for (InterfaceIndex = 0; InterfaceIndex < PDODeviceExtension->FunctionDescriptor->NumberOfInterfaces; InterfaceIndex++)
779  {
780  if (PDODeviceExtension->FunctionDescriptor->InterfaceDescriptorList[InterfaceIndex]->bInterfaceNumber == InterfaceInformation->InterfaceNumber)
781  {
782  // found interface entry
783  FoundInterface = TRUE;
784  break;
785  }
786  }
787 
788  if (!FoundInterface)
789  {
790  //
791  // invalid parameter
792  //
793  DPRINT1("InterfaceInformation InterfaceNumber %x Alternative %x NumberOfPipes %x not found\n", InterfaceInformation->InterfaceNumber, InterfaceInformation->AlternateSetting, InterfaceInformation->NumberOfPipes);
795  }
796 
797  //
798  // now query the total interface list
799  //
800  Entry = NULL;
801  for (InterfaceIndex = 0; InterfaceIndex < PDODeviceExtension->InterfaceListCount; InterfaceIndex++)
802  {
803  if (PDODeviceExtension->InterfaceList[InterfaceIndex].Interface->InterfaceNumber == InterfaceInformation->InterfaceNumber)
804  {
805  //
806  // found entry
807  //
808  Entry = &PDODeviceExtension->InterfaceList[InterfaceIndex];
809  }
810  }
811 
812  //
813  // sanity check
814  //
815  ASSERT(Entry);
816  if (!Entry)
817  {
818  //
819  // corruption detected
820  //
821  KeBugCheck(0);
822  }
823 
824  NeedSelect = FALSE;
825  if (Entry->InterfaceDescriptor->bAlternateSetting == InterfaceInformation->AlternateSetting)
826  {
827  for(InterfaceIndex = 0; InterfaceIndex < InterfaceInformation->NumberOfPipes; InterfaceIndex++)
828  {
829  if (InterfaceInformation->Pipes[InterfaceIndex].MaximumTransferSize != Entry->Interface->Pipes[InterfaceIndex].MaximumTransferSize)
830  {
831  //
832  // changed interface
833  //
834  NeedSelect = TRUE;
835  }
836  }
837  }
838  else
839  {
840  //
841  // need select as the interface number differ
842  //
843  NeedSelect = TRUE;
844  }
845 
846  if (!NeedSelect)
847  {
848  //
849  // interface is already selected
850  //
851  ASSERT(Length >= Entry->Interface->Length);
852  RtlCopyMemory(InterfaceInformation, Entry->Interface, Entry->Interface->Length);
853 
854  //
855  // adjust remaining buffer size
856  //
857  ASSERT(Entry->Interface->Length);
858  Length -= Entry->Interface->Length;
859 
860  //
861  // move to next output interface information
862  //
863  InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)InterfaceInformation + Entry->Interface->Length);
864  }
865  else
866  {
867  //
868  // select interface
869  //
870  DPRINT1("Selecting InterfaceIndex %lu AlternateSetting %lu NumberOfPipes %lu\n", InterfaceInformation->InterfaceNumber, InterfaceInformation->AlternateSetting, InterfaceInformation->NumberOfPipes);
871  ASSERT(InterfaceInformation->Length == Entry->Interface->Length);
872 
873  //
874  // build urb
875  //
877  if (!NewUrb)
878  {
879  //
880  // no memory
881  //
883  }
884 
885  //
886  // now prepare interface urb
887  //
888  UsbBuildSelectInterfaceRequest(NewUrb, (USHORT)GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceInformation->NumberOfPipes), PDODeviceExtension->ConfigurationHandle, InterfaceInformation->InterfaceNumber, InterfaceInformation->AlternateSetting);
889 
890  //
891  // now select the interface
892  //
893  Status = USBCCGP_SyncUrbRequest(PDODeviceExtension->NextDeviceObject, NewUrb);
894  DPRINT1("SelectInterface Status %x\n", Status);
895 
896  if (!NT_SUCCESS(Status))
897  {
898  //
899  // failed
900  //
901  break;
902  }
903 
904  //
905  // update configuration info
906  //
907  ASSERT(Entry->Interface->Length >= NewUrb->UrbSelectInterface.Interface.Length);
908  ASSERT(Length >= NewUrb->UrbSelectInterface.Interface.Length);
909  RtlCopyMemory(Entry->Interface, &NewUrb->UrbSelectInterface.Interface, NewUrb->UrbSelectInterface.Interface.Length);
910 
911  //
912  // update provided interface information
913  //
914  ASSERT(Length >= Entry->Interface->Length);
915  RtlCopyMemory(InterfaceInformation, Entry->Interface, Entry->Interface->Length);
916 
917  //
918  // decrement remaining buffer size
919  //
920  ASSERT(Entry->Interface->Length);
921  Length -= Entry->Interface->Length;
922 
923  //
924  // adjust output buffer offset
925  //
926  InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)InterfaceInformation + Entry->Interface->Length);
927 
928  //
929  // free urb
930  //
931  FreeItem(NewUrb);
932  }
933 
934  } while(Length);
935 
936  //
937  // store configuration handle
938  //
939  Urb->UrbSelectConfiguration.ConfigurationHandle = PDODeviceExtension->ConfigurationHandle;
940 
941  DPRINT1("[USBCCGP] SelectConfiguration Function %x Completed\n", PDODeviceExtension->FunctionDescriptor->FunctionNumber);
942 
943  //
944  // done
945  //
946  return STATUS_SUCCESS;
947 }
948 
949 NTSTATUS
952  PIRP Irp)
953 {
954  PIO_STACK_LOCATION IoStack;
955  PPDO_DEVICE_EXTENSION PDODeviceExtension;
957  PURB Urb;
958 
959  //
960  // get current stack location
961  //
963 
964  //
965  // get device extension
966  //
967  PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
968 
969  if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_SUBMIT_URB)
970  {
971  //
972  // get urb
973  //
974  Urb = (PURB)IoStack->Parameters.Others.Argument1;
975  ASSERT(Urb);
976  DPRINT("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x\n", Urb->UrbHeader.Function);
977 
978  if (Urb->UrbHeader.Function == URB_FUNCTION_SELECT_CONFIGURATION)
979  {
980  //
981  // select configuration
982  //
984  Irp->IoStatus.Status = Status;
986  return Status;
987  }
988  else if (Urb->UrbHeader.Function == URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE)
989  {
990  if (Urb->UrbControlDescriptorRequest.DescriptorType == USB_DEVICE_DESCRIPTOR_TYPE)
991  {
992  //
993  // is the buffer big enough
994  //
995  if (Urb->UrbControlDescriptorRequest.TransferBufferLength < sizeof(USB_DEVICE_DESCRIPTOR))
996  {
997  //
998  // invalid buffer size
999  //
1000  DPRINT1("[USBCCGP] invalid device descriptor size %lu\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
1001  Urb->UrbControlDescriptorRequest.TransferBufferLength = sizeof(USB_DEVICE_DESCRIPTOR);
1002  Irp->IoStatus.Status = STATUS_INVALID_BUFFER_SIZE;
1005  }
1006 
1007  //
1008  // copy device descriptor
1009  //
1010  ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
1011  RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, &PDODeviceExtension->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
1012  Irp->IoStatus.Status = STATUS_SUCCESS;
1014  return STATUS_SUCCESS;
1015  }
1016  else if (Urb->UrbControlDescriptorRequest.DescriptorType == USB_CONFIGURATION_DESCRIPTOR_TYPE)
1017  {
1018  //
1019  // build configuration descriptor
1020  //
1022  Irp->IoStatus.Status = Status;
1024  return Status;
1025  }
1026  else if (Urb->UrbControlDescriptorRequest.DescriptorType == USB_STRING_DESCRIPTOR_TYPE)
1027  {
1028  PUSB_STRING_DESCRIPTOR StringDescriptor;
1029 
1030  //
1031  // get the requested string descriptor
1032  //
1033  ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
1034  Status = USBCCGP_GetDescriptor(PDODeviceExtension->FDODeviceExtension->NextDeviceObject,
1036  Urb->UrbControlDescriptorRequest.TransferBufferLength,
1037  Urb->UrbControlDescriptorRequest.Index,
1038  Urb->UrbControlDescriptorRequest.LanguageId,
1039  (PVOID*)&StringDescriptor);
1040  if (NT_SUCCESS(Status))
1041  {
1042  if (StringDescriptor->bLength == 2)
1043  {
1044  FreeItem(StringDescriptor);
1046  }
1047  else
1048  {
1049  RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer,
1050  StringDescriptor->bString,
1051  StringDescriptor->bLength + sizeof(WCHAR));
1052  FreeItem(StringDescriptor);
1054  }
1055  }
1056  Irp->IoStatus.Status = Status;
1058  return Status;
1059  }
1060  }
1061  else
1062  {
1064  Status = IoCallDriver(PDODeviceExtension->NextDeviceObject, Irp);
1065  return Status;
1066  }
1067  }
1068  else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_GET_PORT_STATUS)
1069  {
1071  Status = IoCallDriver(PDODeviceExtension->NextDeviceObject, Irp);
1072  return Status;
1073  }
1074  else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_RESET_PORT)
1075  {
1077  Status = IoCallDriver(PDODeviceExtension->NextDeviceObject, Irp);
1078  return Status;
1079  }
1080  else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_CYCLE_PORT)
1081  {
1083  Status = IoCallDriver(PDODeviceExtension->NextDeviceObject, Irp);
1084  return Status;
1085  }
1086 
1087  DPRINT1("IOCTL %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
1088  DPRINT1("InputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.InputBufferLength);
1089  DPRINT1("OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength);
1090  DPRINT1("Type3InputBuffer %p\n", IoStack->Parameters.DeviceIoControl.Type3InputBuffer);
1091 
1092  ASSERT(FALSE);
1093 
1094  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
1096  return STATUS_NOT_IMPLEMENTED;
1097 }
1098 
1099 NTSTATUS
1102  PIRP Irp)
1103 {
1104  NTSTATUS Status;
1105  PIO_STACK_LOCATION IoStack;
1106 
1107  IoStack = IoGetCurrentIrpStackLocation(Irp);
1108 
1109  switch (IoStack->MinorFunction)
1110  {
1111  case IRP_MN_SET_POWER:
1112  case IRP_MN_QUERY_POWER:
1113  Irp->IoStatus.Status = STATUS_SUCCESS;
1114  break;
1115  }
1116 
1117  Status = Irp->IoStatus.Status;
1120  return Status;
1121 }
1122 
1123 
1124 NTSTATUS
1127  PIRP Irp)
1128 {
1129  PIO_STACK_LOCATION IoStack;
1130  NTSTATUS Status;
1131 
1132  /* get stack location */
1133  IoStack = IoGetCurrentIrpStackLocation(Irp);
1134 
1135  switch(IoStack->MajorFunction)
1136  {
1137  case IRP_MJ_PNP:
1138  return PDO_HandlePnp(DeviceObject, Irp);
1141  case IRP_MJ_POWER:
1142  return PDO_HandlePower(DeviceObject, Irp);
1143  default:
1144  DPRINT1("PDO_Dispatch Function %x not implemented\n", IoStack->MajorFunction);
1145  Status = Irp->IoStatus.Status;
1147  return Status;
1148  }
1149 }
struct _USB_DEVICE_DESCRIPTOR USB_DEVICE_DESCRIPTOR
#define IN
Definition: typedefs.h:39
_In_ WDFUSBDEVICE _In_ UCHAR InterfaceIndex
Definition: wdfusb.h:2459
#define IRP_MN_REMOVE_DEVICE
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define IRP_MN_QUERY_ID
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
struct _Entry Entry
Definition: kefuncs.h:629
#define IOCTL_INTERNAL_USB_SUBMIT_URB
Definition: usbioctl.h:32
#define IRP_MN_QUERY_POWER
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1625
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
unsigned char * PUCHAR
Definition: retypes.h:3
USBD_PIPE_INFORMATION Pipes[1]
Definition: usb.h:286
_In_ WDFUSBINTERFACE _In_ UCHAR _Out_ PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
Definition: wdfusb.h:2329
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:30
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS USBCCGP_BuildConfigurationDescriptor(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pdo.c:498
#define GET_SELECT_INTERFACE_REQUEST_SIZE(totalPipes)
Definition: usbdlib.h:117
struct _PDO_DEVICE_EXTENSION * PPDO_DEVICE_EXTENSION
struct _USBD_INTERFACE_INFORMATION * PUSBD_INTERFACE_INFORMATION
NTSTATUS PDO_HandlePnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pdo.c:342
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
DEVICE_CAPABILITIES
Definition: iotypes.h:965
struct _USB_INTERFACE_DESCRIPTOR * PUSB_INTERFACE_DESCRIPTOR
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#define USB_STRING_DESCRIPTOR_TYPE
Definition: usb100.h:51
uint32_t ULONG_PTR
Definition: typedefs.h:65
Definition: usbdlib.h:7
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
return STATUS_NOT_IMPLEMENTED
NTSTATUS USBCCGP_PdoHandleQueryDeviceText(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: pdo.c:20
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
#define L(x)
Definition: ntvdm.h:50
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2430
#define USB_DEVICE_DESCRIPTOR_TYPE
Definition: usb100.h:49
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
_In_ PIRP Irp
Definition: csq.h:116
#define IRP_MN_QUERY_REMOVE_DEVICE
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1427
#define USB_CONFIGURATION_DESCRIPTOR_TYPE
Definition: usb100.h:50
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
#define USB_INTERFACE_DESCRIPTOR_TYPE
Definition: usb100.h:52
#define IoCompleteRequest
Definition: irp.c:1240
COMMON_DEVICE_EXTENSION Common
Definition: pci.h:59
NTSTATUS USBCCGP_PdoAppendInterfaceNumber(IN LPWSTR DeviceId, IN ULONG InterfaceNumber, OUT LPWSTR *OutString)
Definition: pdo.c:150
Definition: bufpool.h:45
#define IOCTL_INTERNAL_USB_CYCLE_PORT
Definition: usbioctl.h:53
#define IRP_MN_QUERY_STOP_DEVICE
Status
Definition: gdiplustypes.h:24
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:650
struct _URB_HEADER UrbHeader
Definition: usb.h:531
_In_ PVOID _In_ LONG InterfaceNumber
Definition: usbdlib.h:168
NTSTATUS PDO_HandlePower(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pdo.c:1100
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
_In_ WDFCOLLECTION _In_ ULONG Index
#define IRP_MN_START_DEVICE
NTSTATUS USBCCGP_PDOSelectConfiguration(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pdo.c:707
NTSTATUS USBCCGP_PdoHandleDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: pdo.c:94
#define IRP_MN_QUERY_DEVICE_TEXT
#define IRP_MN_QUERY_INTERFACE
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
NTSTATUS NTAPI USBCCGP_GetDescriptor(IN PDEVICE_OBJECT DeviceObject, IN UCHAR DescriptorType, IN ULONG DescriptorLength, IN UCHAR DescriptorIndex, IN LANGID LanguageId, OUT PVOID *OutDescriptor)
Definition: descriptor.c:19
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE
Definition: usb200.h:117
ULONG MaximumTransferSize
Definition: usb.h:265
unsigned char UCHAR
Definition: xmlstorage.h:181
#define IRP_MJ_POWER
#define URB_FUNCTION_SELECT_CONFIGURATION
Definition: usb.h:86
#define IRP_MN_SET_POWER
NTSTATUS PDO_Dispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pdo.c:1125
#define URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
Definition: usb.h:97
int _cdecl swprintf(const WCHAR *,...)
struct _URB * PURB
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
struct _URB_SELECT_CONFIGURATION UrbSelectConfiguration
Definition: usb.h:533
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:746
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:361
Definition: usb.h:529
NTSTATUS USBCCGP_SyncUrbRequest(IN PDEVICE_OBJECT DeviceObject, OUT PURB UrbRequest)
Definition: misc.c:35
unsigned short USHORT
Definition: pedump.c:61
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define min(a, b)
Definition: monoChain.cc:55
NTSTATUS USBCCGP_PdoHandleQueryId(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pdo.c:208
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IOCTL_INTERNAL_USB_RESET_PORT
Definition: usbioctl.h:35
#define IOCTL_INTERNAL_USB_GET_PORT_STATUS
Definition: usbioctl.h:44
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define DPRINT1
Definition: precomp.h:8
#define UsbBuildSelectInterfaceRequest(urb, length, configurationHandle, interfaceNumber, alternateSetting)
Definition: usbdlib.h:59
#define OUT
Definition: typedefs.h:40
#define ObReferenceObject
Definition: obfuncs.h:204
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define UNIMPLEMENTED
Definition: debug.h:115
#define ULONG_PTR
Definition: config.h:101
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _URB_CONTROL_DESCRIPTOR_REQUEST UrbControlDescriptorRequest
Definition: usb.h:545
#define DPRINT
Definition: sndvol32.h:71
WCHAR * LPWSTR
Definition: xmlstorage.h:184
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
NTSTATUS PDO_HandleInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pdo.c:950
base of all file and directory entries
Definition: entries.h:82
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
struct _URB_SELECT_INTERFACE UrbSelectInterface
Definition: usb.h:532
#define STATUS_DEVICE_DATA_ERROR
Definition: udferr_usr.h:159
#define IRP_MN_QUERY_CAPABILITIES