ReactOS  0.4.15-dev-489-g75a0787
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  Status = USBCCGP_SyncForwardIrp(PDODeviceExtension->NextDeviceObject, Irp);
235  if (NT_SUCCESS(Status))
236  {
237  //
238  // allocate buffer
239  //
240  Buffer = AllocateItem(NonPagedPool, (wcslen((LPWSTR)Irp->IoStatus.Information) + 7) * sizeof(WCHAR));
241  if (Buffer)
242  {
243  //
244  // append interface number
245  //
246  ASSERT(Irp->IoStatus.Information);
247  swprintf(Buffer, L"%s&MI_%02x", (LPWSTR)Irp->IoStatus.Information, PDODeviceExtension->FunctionDescriptor->FunctionNumber);
248  DPRINT("BusQueryDeviceID %S\n", Buffer);
249 
250  ExFreePool((PVOID)Irp->IoStatus.Information);
251  Irp->IoStatus.Information = (ULONG_PTR)Buffer;
252  }
253  else
254  {
255  //
256  // no memory
257  //
259  }
260  }
261  return Status;
262  }
263  else if (IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs)
264  {
265  //
266  // handle instance id
267  //
268  DeviceString = &PDODeviceExtension->FunctionDescriptor->HardwareId;
269  }
270  else if (IoStack->Parameters.QueryId.IdType == BusQueryInstanceID)
271  {
272  //
273  // handle instance id
274  //
275  Buffer = AllocateItem(NonPagedPool, 5 * sizeof(WCHAR));
276  if (!Buffer)
277  {
278  //
279  // no memory
280  //
282  }
283 
284  //
285  // use function number
286  //
287  swprintf(Buffer, L"%04x", PDODeviceExtension->FunctionDescriptor->FunctionNumber);
288  Irp->IoStatus.Information = (ULONG_PTR)Buffer;
289  return STATUS_SUCCESS;
290  }
291  else if (IoStack->Parameters.QueryId.IdType == BusQueryCompatibleIDs)
292  {
293  //
294  // handle instance id
295  //
296  DeviceString = &PDODeviceExtension->FunctionDescriptor->CompatibleId;
297  }
298  else
299  {
300  //
301  // unsupported query
302  //
303  return Irp->IoStatus.Status;
304  }
305 
306  //
307  // sanity check
308  //
309  ASSERT(DeviceString != NULL);
310 
311  //
312  // allocate buffer
313  //
314  Buffer = AllocateItem(NonPagedPool, DeviceString->Length + sizeof(WCHAR));
315  if (!Buffer)
316  {
317  //
318  // no memory
319  //
321  }
322 
323  //
324  // copy buffer
325  //
326  RtlCopyMemory(Buffer, DeviceString->Buffer, DeviceString->Length);
327  Buffer[DeviceString->Length / sizeof(WCHAR)] = UNICODE_NULL;
328  Irp->IoStatus.Information = (ULONG_PTR)Buffer;
329 
330  return STATUS_SUCCESS;
331 }
332 
333 NTSTATUS
336  PIRP Irp)
337 {
338  PIO_STACK_LOCATION IoStack;
339  PPDO_DEVICE_EXTENSION PDODeviceExtension;
341  ULONG Index, bFound;
342 
343  //
344  // get current stack location
345  //
347 
348  //
349  // get device extension
350  //
351  PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
352 
353  //
354  // sanity check
355  //
356  ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
357 
358  switch(IoStack->MinorFunction)
359  {
361  {
362  //
363  // handle device relations
364  //
366  break;
367  }
369  {
370  //
371  // handle query device text
372  //
374  break;
375  }
376  case IRP_MN_QUERY_ID:
377  {
378  //
379  // handle request
380  //
382  break;
383  }
385  {
386  //
387  // remove us from the fdo's pdo list
388  //
389  bFound = FALSE;
390  for(Index = 0; Index < PDODeviceExtension->FDODeviceExtension->FunctionDescriptorCount; Index++)
391  {
392  if (PDODeviceExtension->FDODeviceExtension->ChildPDO[Index] == DeviceObject)
393  {
394  //
395  // remove us
396  //
397  PDODeviceExtension->FDODeviceExtension->ChildPDO[Index] = NULL;
398  bFound = TRUE;
399  break;
400  }
401  }
402 
403  //
404  // Complete the IRP
405  //
406  Irp->IoStatus.Status = STATUS_SUCCESS;
408 
409  if (bFound)
410  {
411  //
412  // Delete the device object
413  //
415  }
416  return STATUS_SUCCESS;
417  }
419  {
420  //
421  // copy device capabilities
422  //
423  RtlCopyMemory(IoStack->Parameters.DeviceCapabilities.Capabilities, &PDODeviceExtension->Capabilities, sizeof(DEVICE_CAPABILITIES));
424 
425  /* Complete the IRP */
426  Irp->IoStatus.Status = STATUS_SUCCESS;
428  return STATUS_SUCCESS;
429  }
432  {
433  //
434  // sure
435  //
437  break;
438  }
439  case IRP_MN_START_DEVICE:
440  {
441  //
442  // no-op for PDO
443  //
444  DPRINT("[USBCCGP] PDO IRP_MN_START\n");
446  break;
447  }
449  {
450  //
451  // forward to lower device object
452  //
454  return IoCallDriver(PDODeviceExtension->NextDeviceObject, Irp);
455  }
456  default:
457  {
458  //
459  // do nothing
460  //
461  Status = Irp->IoStatus.Status;
462  break;
463  }
464  }
465 
466  //
467  // complete request
468  //
469  if (Status != STATUS_PENDING)
470  {
471  //
472  // store result
473  //
474  Irp->IoStatus.Status = Status;
475 
476  //
477  // complete request
478  //
480  }
481 
482  //
483  // done processing
484  //
485  return Status;
486 
487 }
488 
489 NTSTATUS
492  PIRP Irp)
493 {
494  PIO_STACK_LOCATION IoStack;
495  PPDO_DEVICE_EXTENSION PDODeviceExtension;
496  PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
497  PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
498  ULONG TotalSize, Index;
499  ULONG Size;
500  PURB Urb;
501  PVOID Buffer;
502  PUCHAR BufferPtr;
504 
505  //
506  // get current stack location
507  //
509 
510  DPRINT("USBCCGP_BuildConfigurationDescriptor\n");
511 
512  //
513  // get device extension
514  //
515  PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
516 
517  //
518  // get configuration descriptor
519  //
520  ConfigurationDescriptor = PDODeviceExtension->ConfigurationDescriptor;
521 
522  //
523  // calculate size of configuration descriptor
524  //
525  TotalSize = sizeof(USB_CONFIGURATION_DESCRIPTOR);
526 
527  for (Index = 0; Index < PDODeviceExtension->FunctionDescriptor->NumberOfInterfaces; Index++)
528  {
529  //
530  // get current interface descriptor
531  //
532  InterfaceDescriptor = PDODeviceExtension->FunctionDescriptor->InterfaceDescriptorList[Index];
533  InterfaceNumber = InterfaceDescriptor->bInterfaceNumber;
534 
535  //
536  // add to size and move to next descriptor
537  //
538  TotalSize += InterfaceDescriptor->bLength;
539  InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength);
540 
541  do
542  {
543  if ((ULONG_PTR)InterfaceDescriptor >= ((ULONG_PTR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength))
544  {
545  //
546  // reached end of configuration descriptor
547  //
548  break;
549  }
550 
551  //
552  // association descriptors are removed
553  //
555  {
556  if (InterfaceDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
557  {
558  if (InterfaceNumber != InterfaceDescriptor->bInterfaceNumber)
559  {
560  //
561  // reached next descriptor
562  //
563  break;
564  }
565 
566  //
567  // include alternate descriptor
568  //
569  }
570 
571  //
572  // append size
573  //
574  TotalSize += InterfaceDescriptor->bLength;
575  }
576 
577  //
578  // move to next descriptor
579  //
580  InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength);
581  } while(TRUE);
582  }
583 
584  //
585  // now allocate temporary buffer for the configuration descriptor
586  //
587  Buffer = AllocateItem(NonPagedPool, TotalSize);
588  if (!Buffer)
589  {
590  //
591  // failed to allocate buffer
592  //
593  DPRINT1("[USBCCGP] Failed to allocate %lu Bytes\n", TotalSize);
595  }
596 
597  //
598  // first copy the configuration descriptor
599  //
600  RtlCopyMemory(Buffer, ConfigurationDescriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
601  BufferPtr = (PUCHAR)((ULONG_PTR)Buffer + ConfigurationDescriptor->bLength);
602 
603  for (Index = 0; Index < PDODeviceExtension->FunctionDescriptor->NumberOfInterfaces; Index++)
604  {
605  //
606  // get current interface descriptor
607  //
608  InterfaceDescriptor = PDODeviceExtension->FunctionDescriptor->InterfaceDescriptorList[Index];
609  InterfaceNumber = InterfaceDescriptor->bInterfaceNumber;
610 
611  //
612  // copy descriptor and move to next descriptor
613  //
614  RtlCopyMemory(BufferPtr, InterfaceDescriptor, InterfaceDescriptor->bLength);
615  BufferPtr += InterfaceDescriptor->bLength;
616  InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength);
617 
618  do
619  {
620  if ((ULONG_PTR)InterfaceDescriptor >= ((ULONG_PTR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength))
621  {
622  //
623  // reached end of configuration descriptor
624  //
625  break;
626  }
627 
628  //
629  // association descriptors are removed
630  //
632  {
633  if (InterfaceDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
634  {
635  if (InterfaceNumber != InterfaceDescriptor->bInterfaceNumber)
636  {
637  //
638  // reached next descriptor
639  //
640  break;
641  }
642 
643  //
644  // include alternate descriptor
645  //
646  DPRINT("InterfaceDescriptor %p Alternate %x InterfaceNumber %x\n", InterfaceDescriptor, InterfaceDescriptor->bAlternateSetting, InterfaceDescriptor->bInterfaceNumber);
647  }
648 
649  //
650  // copy descriptor
651  //
652  RtlCopyMemory(BufferPtr, InterfaceDescriptor, InterfaceDescriptor->bLength);
653  BufferPtr += InterfaceDescriptor->bLength;
654  }
655 
656  //
657  // move to next descriptor
658  //
659  InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength);
660  } while(TRUE);
661  }
662 
663  //
664  // modify configuration descriptor
665  //
666  ConfigurationDescriptor = Buffer;
667  ConfigurationDescriptor->wTotalLength = (USHORT)TotalSize;
668  ConfigurationDescriptor->bNumInterfaces = PDODeviceExtension->FunctionDescriptor->NumberOfInterfaces;
669 
670  //
671  // get urb
672  //
673  Urb = (PURB)IoStack->Parameters.Others.Argument1;
674  ASSERT(Urb);
675 
676  //
677  // copy descriptor
678  //
679  Size = min(TotalSize, Urb->UrbControlDescriptorRequest.TransferBufferLength);
680  RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, Buffer, Size);
681 
682  //
683  // store final size
684  //
685  Urb->UrbControlDescriptorRequest.TransferBufferLength = Size;
686 
687  //
688  // free buffer
689  //
690  FreeItem(Buffer);
691 
692  //
693  // done
694  //
695  return STATUS_SUCCESS;
696 }
697 
698 NTSTATUS
701  PIRP Irp)
702 {
703  PIO_STACK_LOCATION IoStack;
704  PPDO_DEVICE_EXTENSION PDODeviceExtension;
705  PURB Urb, NewUrb;
706  PUSBD_INTERFACE_INFORMATION InterfaceInformation;
707  ULONG InterfaceIndex, Length;
709  ULONG NeedSelect, FoundInterface;
711 
712  //
713  // get current stack location
714  //
716 
717  //
718  // get device extension
719  //
720  PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
721 
722  //
723  // get urb
724  //
725  Urb = (PURB)IoStack->Parameters.Others.Argument1;
726  ASSERT(Urb);
727 
728  //
729  // is there already an configuration handle
730  //
731  if (Urb->UrbSelectConfiguration.ConfigurationHandle)
732  {
733  //
734  // nothing to do
735  //
736  return STATUS_SUCCESS;
737  }
738 
739  //
740  // if there is no configuration descriptor, unconfigure the device
741  //
742  if (Urb->UrbSelectConfiguration.ConfigurationDescriptor == NULL)
743  {
744  return STATUS_SUCCESS;
745  }
746 
747  // sanity checks
748  //C_ASSERT(sizeof(struct _URB_HEADER) == 16);
749  //C_ASSERT(FIELD_OFFSET(struct _URB_SELECT_CONFIGURATION, Interface.Length) == 24);
750  //C_ASSERT(sizeof(USBD_INTERFACE_INFORMATION) == 36);
751  //C_ASSERT(sizeof(struct _URB_SELECT_CONFIGURATION) == 0x3C);
752 
753  // available buffer length
755 
756  //
757  // check all interfaces
758  //
759  InterfaceInformation = &Urb->UrbSelectConfiguration.Interface;
760 
761  Entry = NULL;
762  do
763  {
764  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);
765  ASSERT(InterfaceInformation->Length);
766  //
767  // search for the interface in the local interface list
768  //
769  FoundInterface = FALSE;
770  for (InterfaceIndex = 0; InterfaceIndex < PDODeviceExtension->FunctionDescriptor->NumberOfInterfaces; InterfaceIndex++)
771  {
772  if (PDODeviceExtension->FunctionDescriptor->InterfaceDescriptorList[InterfaceIndex]->bInterfaceNumber == InterfaceInformation->InterfaceNumber)
773  {
774  // found interface entry
775  FoundInterface = TRUE;
776  break;
777  }
778  }
779 
780  if (!FoundInterface)
781  {
782  //
783  // invalid parameter
784  //
785  DPRINT1("InterfaceInformation InterfaceNumber %x Alternative %x NumberOfPipes %x not found\n", InterfaceInformation->InterfaceNumber, InterfaceInformation->AlternateSetting, InterfaceInformation->NumberOfPipes);
787  }
788 
789  //
790  // now query the total interface list
791  //
792  Entry = NULL;
793  for (InterfaceIndex = 0; InterfaceIndex < PDODeviceExtension->InterfaceListCount; InterfaceIndex++)
794  {
795  if (PDODeviceExtension->InterfaceList[InterfaceIndex].Interface->InterfaceNumber == InterfaceInformation->InterfaceNumber)
796  {
797  //
798  // found entry
799  //
800  Entry = &PDODeviceExtension->InterfaceList[InterfaceIndex];
801  }
802  }
803 
804  //
805  // sanity check
806  //
807  ASSERT(Entry);
808  if (!Entry)
809  {
810  //
811  // corruption detected
812  //
813  KeBugCheck(0);
814  }
815 
816  NeedSelect = FALSE;
817  if (Entry->InterfaceDescriptor->bAlternateSetting == InterfaceInformation->AlternateSetting)
818  {
819  for(InterfaceIndex = 0; InterfaceIndex < InterfaceInformation->NumberOfPipes; InterfaceIndex++)
820  {
821  if (InterfaceInformation->Pipes[InterfaceIndex].MaximumTransferSize != Entry->Interface->Pipes[InterfaceIndex].MaximumTransferSize)
822  {
823  //
824  // changed interface
825  //
826  NeedSelect = TRUE;
827  }
828  }
829  }
830  else
831  {
832  //
833  // need select as the interface number differ
834  //
835  NeedSelect = TRUE;
836  }
837 
838  if (!NeedSelect)
839  {
840  //
841  // interface is already selected
842  //
843  ASSERT(Length >= Entry->Interface->Length);
844  RtlCopyMemory(InterfaceInformation, Entry->Interface, Entry->Interface->Length);
845 
846  //
847  // adjust remaining buffer size
848  //
849  ASSERT(Entry->Interface->Length);
850  Length -= Entry->Interface->Length;
851 
852  //
853  // move to next output interface information
854  //
855  InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)InterfaceInformation + Entry->Interface->Length);
856  }
857  else
858  {
859  //
860  // select interface
861  //
862  DPRINT1("Selecting InterfaceIndex %lu AlternateSetting %lu NumberOfPipes %lu\n", InterfaceInformation->InterfaceNumber, InterfaceInformation->AlternateSetting, InterfaceInformation->NumberOfPipes);
863  ASSERT(InterfaceInformation->Length == Entry->Interface->Length);
864 
865  //
866  // build urb
867  //
869  if (!NewUrb)
870  {
871  //
872  // no memory
873  //
875  }
876 
877  //
878  // now prepare interface urb
879  //
880  UsbBuildSelectInterfaceRequest(NewUrb, (USHORT)GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceInformation->NumberOfPipes), PDODeviceExtension->ConfigurationHandle, InterfaceInformation->InterfaceNumber, InterfaceInformation->AlternateSetting);
881 
882  //
883  // now select the interface
884  //
885  Status = USBCCGP_SyncUrbRequest(PDODeviceExtension->NextDeviceObject, NewUrb);
886  DPRINT1("SelectInterface Status %x\n", Status);
887 
888  if (!NT_SUCCESS(Status))
889  {
890  //
891  // failed
892  //
893  break;
894  }
895 
896  //
897  // update configuration info
898  //
899  ASSERT(Entry->Interface->Length >= NewUrb->UrbSelectInterface.Interface.Length);
900  ASSERT(Length >= NewUrb->UrbSelectInterface.Interface.Length);
901  RtlCopyMemory(Entry->Interface, &NewUrb->UrbSelectInterface.Interface, NewUrb->UrbSelectInterface.Interface.Length);
902 
903  //
904  // update provided interface information
905  //
906  ASSERT(Length >= Entry->Interface->Length);
907  RtlCopyMemory(InterfaceInformation, Entry->Interface, Entry->Interface->Length);
908 
909  //
910  // decrement remaining buffer size
911  //
912  ASSERT(Entry->Interface->Length);
913  Length -= Entry->Interface->Length;
914 
915  //
916  // adjust output buffer offset
917  //
918  InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)InterfaceInformation + Entry->Interface->Length);
919 
920  //
921  // free urb
922  //
923  FreeItem(NewUrb);
924  }
925 
926  } while(Length);
927 
928  //
929  // store configuration handle
930  //
931  Urb->UrbSelectConfiguration.ConfigurationHandle = PDODeviceExtension->ConfigurationHandle;
932 
933  DPRINT1("[USBCCGP] SelectConfiguration Function %x Completed\n", PDODeviceExtension->FunctionDescriptor->FunctionNumber);
934 
935  //
936  // done
937  //
938  return STATUS_SUCCESS;
939 }
940 
941 NTSTATUS
944  PIRP Irp)
945 {
946  PIO_STACK_LOCATION IoStack;
947  PPDO_DEVICE_EXTENSION PDODeviceExtension;
949  PURB Urb;
950 
951  //
952  // get current stack location
953  //
955 
956  //
957  // get device extension
958  //
959  PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
960 
961  if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_SUBMIT_URB)
962  {
963  //
964  // get urb
965  //
966  Urb = (PURB)IoStack->Parameters.Others.Argument1;
967  ASSERT(Urb);
968  DPRINT("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x\n", Urb->UrbHeader.Function);
969 
970  if (Urb->UrbHeader.Function == URB_FUNCTION_SELECT_CONFIGURATION)
971  {
972  //
973  // select configuration
974  //
976  Irp->IoStatus.Status = Status;
978  return Status;
979  }
980  else if (Urb->UrbHeader.Function == URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE)
981  {
982  if (Urb->UrbControlDescriptorRequest.DescriptorType == USB_DEVICE_DESCRIPTOR_TYPE)
983  {
984  //
985  // is the buffer big enough
986  //
987  if (Urb->UrbControlDescriptorRequest.TransferBufferLength < sizeof(USB_DEVICE_DESCRIPTOR))
988  {
989  //
990  // invalid buffer size
991  //
992  DPRINT1("[USBCCGP] invalid device descriptor size %lu\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
993  Urb->UrbControlDescriptorRequest.TransferBufferLength = sizeof(USB_DEVICE_DESCRIPTOR);
994  Irp->IoStatus.Status = STATUS_INVALID_BUFFER_SIZE;
997  }
998 
999  //
1000  // copy device descriptor
1001  //
1002  ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
1003  RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, &PDODeviceExtension->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
1004  Irp->IoStatus.Status = STATUS_SUCCESS;
1006  return STATUS_SUCCESS;
1007  }
1008  else if (Urb->UrbControlDescriptorRequest.DescriptorType == USB_CONFIGURATION_DESCRIPTOR_TYPE)
1009  {
1010  //
1011  // build configuration descriptor
1012  //
1014  Irp->IoStatus.Status = Status;
1016  return Status;
1017  }
1018  else if (Urb->UrbControlDescriptorRequest.DescriptorType == USB_STRING_DESCRIPTOR_TYPE)
1019  {
1020  PUSB_STRING_DESCRIPTOR StringDescriptor;
1021 
1022  //
1023  // get the requested string descriptor
1024  //
1025  ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
1026  Status = USBCCGP_GetDescriptor(PDODeviceExtension->FDODeviceExtension->NextDeviceObject,
1028  Urb->UrbControlDescriptorRequest.TransferBufferLength,
1029  Urb->UrbControlDescriptorRequest.Index,
1030  Urb->UrbControlDescriptorRequest.LanguageId,
1031  (PVOID*)&StringDescriptor);
1032  if (NT_SUCCESS(Status))
1033  {
1034  if (StringDescriptor->bLength == 2)
1035  {
1036  FreeItem(StringDescriptor);
1038  }
1039  else
1040  {
1041  RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer,
1042  StringDescriptor->bString,
1043  StringDescriptor->bLength + sizeof(WCHAR));
1044  FreeItem(StringDescriptor);
1046  }
1047  }
1048  Irp->IoStatus.Status = Status;
1050  return Status;
1051  }
1052  }
1053  else
1054  {
1056  Status = IoCallDriver(PDODeviceExtension->NextDeviceObject, Irp);
1057  return Status;
1058  }
1059  }
1060  else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_GET_PORT_STATUS)
1061  {
1063  Status = IoCallDriver(PDODeviceExtension->NextDeviceObject, Irp);
1064  return Status;
1065  }
1066  else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_RESET_PORT)
1067  {
1069  Status = IoCallDriver(PDODeviceExtension->NextDeviceObject, Irp);
1070  return Status;
1071  }
1072  else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_CYCLE_PORT)
1073  {
1075  Status = IoCallDriver(PDODeviceExtension->NextDeviceObject, Irp);
1076  return Status;
1077  }
1078 
1079  DPRINT1("IOCTL %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
1080  DPRINT1("InputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.InputBufferLength);
1081  DPRINT1("OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength);
1082  DPRINT1("Type3InputBuffer %p\n", IoStack->Parameters.DeviceIoControl.Type3InputBuffer);
1083 
1084  ASSERT(FALSE);
1085 
1086  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
1088  return STATUS_NOT_IMPLEMENTED;
1089 }
1090 
1091 NTSTATUS
1094  PIRP Irp)
1095 {
1096  NTSTATUS Status;
1097  PIO_STACK_LOCATION IoStack;
1098 
1099  IoStack = IoGetCurrentIrpStackLocation(Irp);
1100 
1101  switch (IoStack->MinorFunction)
1102  {
1103  case IRP_MN_SET_POWER:
1104  case IRP_MN_QUERY_POWER:
1105  Irp->IoStatus.Status = STATUS_SUCCESS;
1106  break;
1107  }
1108 
1109  Status = Irp->IoStatus.Status;
1112  return Status;
1113 }
1114 
1115 
1116 NTSTATUS
1119  PIRP Irp)
1120 {
1121  PIO_STACK_LOCATION IoStack;
1122  NTSTATUS Status;
1123 
1124  /* get stack location */
1125  IoStack = IoGetCurrentIrpStackLocation(Irp);
1126 
1127  switch(IoStack->MajorFunction)
1128  {
1129  case IRP_MJ_PNP:
1130  return PDO_HandlePnp(DeviceObject, Irp);
1133  case IRP_MJ_POWER:
1134  return PDO_HandlePower(DeviceObject, Irp);
1135  default:
1136  DPRINT1("PDO_Dispatch Function %x not implemented\n", IoStack->MajorFunction);
1137  Status = Irp->IoStatus.Status;
1139  return Status;
1140  }
1141 }
struct _USB_DEVICE_DESCRIPTOR USB_DEVICE_DESCRIPTOR
#define IN
Definition: typedefs.h:39
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define IRP_MN_REMOVE_DEVICE
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define IRP_MN_QUERY_ID
struct _Entry Entry
Definition: kefuncs.h:627
#define IOCTL_INTERNAL_USB_SUBMIT_URB
Definition: usbioctl.h:32
#define IRP_MN_QUERY_POWER
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2057
unsigned char * PUCHAR
Definition: retypes.h:3
USBD_PIPE_INFORMATION Pipes[1]
Definition: usb.h:286
#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:490
#define GET_SELECT_INTERFACE_REQUEST_SIZE(totalPipes)
Definition: usbdlib.h:104
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:334
DEVICE_CAPABILITIES
Definition: iotypes.h:930
static WCHAR String[]
Definition: stringtable.c:55
struct _USB_INTERFACE_DESCRIPTOR * PUSB_INTERFACE_DESCRIPTOR
#define USB_STRING_DESCRIPTOR_TYPE
Definition: usb100.h:51
uint32_t ULONG_PTR
Definition: typedefs.h:64
Definition: usbdlib.h:7
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 USB_DEVICE_DESCRIPTOR_TYPE
Definition: usb100.h:49
#define UNICODE_NULL
#define IRP_MN_QUERY_REMOVE_DEVICE
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1431
#define USB_CONFIGURATION_DESCRIPTOR_TYPE
Definition: usb100.h:50
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define USB_INTERFACE_DESCRIPTOR_TYPE
Definition: usb100.h:52
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
COMMON_DEVICE_EXTENSION Common
Definition: pci.h:56
void DPRINT(...)
Definition: polytest.cpp:61
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
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:636
struct _URB_HEADER UrbHeader
Definition: usb.h:531
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:361
_In_ PVOID _In_ LONG InterfaceNumber
Definition: usbdlib.h:155
NTSTATUS PDO_HandlePower(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pdo.c:1092
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define swprintf(buf, format,...)
Definition: sprintf.c:56
#define IRP_MN_START_DEVICE
static const UCHAR Index[8]
Definition: usbohci.c:18
NTSTATUS USBCCGP_PDOSelectConfiguration(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pdo.c:699
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
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
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
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#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
static const WCHAR L[]
Definition: oid.c:1250
#define IRP_MN_SET_POWER
NTSTATUS PDO_Dispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pdo.c:1117
#define URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
Definition: usb.h:97
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
struct _URB * PURB
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1569
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
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:737
Definition: usb.h:529
NTSTATUS USBCCGP_SyncUrbRequest(IN PDEVICE_OBJECT DeviceObject, OUT PURB UrbRequest)
Definition: misc.c:75
unsigned short USHORT
Definition: pedump.c:61
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define min(a, b)
Definition: monoChain.cc:55
NTSTATUS USBCCGP_PdoHandleQueryId(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pdo.c:208
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
#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:568
#define UNIMPLEMENTED
Definition: debug.h:115
#define ULONG_PTR
Definition: config.h:101
struct _URB_CONTROL_DESCRIPTOR_REQUEST UrbControlDescriptorRequest
Definition: usb.h:545
WCHAR * LPWSTR
Definition: xmlstorage.h:184
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2774
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:3014
NTSTATUS PDO_HandleInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pdo.c:942
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
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
NTSTATUS NTAPI USBCCGP_SyncForwardIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: misc.c:36
#define IRP_MN_QUERY_CAPABILITIES