ReactOS 0.4.15-dev-7924-g5949c20
pdo.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbstor/pdo.c
5 * PURPOSE: USB block storage device driver.
6 * PROGRAMMERS:
7 * James Tabor
8 * Michael Martin (michael.martin@reactos.org)
9 * Johannes Anderwald (johannes.anderwald@reactos.org)
10 */
11
12#include "usbstor.h"
13
14#define NDEBUG
15#include <debug.h>
16
19 IN PUFI_INQUIRY_RESPONSE InquiryData,
20 IN UCHAR IsFloppy)
21{
22 //
23 // check if device type is zero
24 //
25 if (InquiryData->DeviceType == 0)
26 {
27 if (IsFloppy)
28 {
29 //
30 // floppy device
31 //
32 return "SFloppy";
33 }
34
35 //
36 // direct access device
37 //
38 return "Disk";
39 }
40
41 //
42 // FIXME: use constant - derived from http://en.wikipedia.org/wiki/SCSI_Peripheral_Device_Type
43 //
44 switch (InquiryData->DeviceType)
45 {
46 case 1:
47 {
48 //
49 // sequential device, i.e magnetic tape
50 //
51 return "Sequential";
52 }
53 case 4:
54 {
55 //
56 // write once device
57 //
58 return "Worm";
59 }
60 case 5:
61 {
62 //
63 // CDROM device
64 //
65 return "CdRom";
66 }
67 case 7:
68 {
69 //
70 // optical memory device
71 //
72 return "Optical";
73 }
74 case 8:
75 {
76 //
77 // medium change device
78 //
79 return "Changer";
80 }
81 default:
82 {
83 //
84 // other device
85 //
86 return "Other";
87 }
88 }
89}
90
93 IN PUFI_INQUIRY_RESPONSE InquiryData,
94 IN UCHAR IsFloppy)
95{
96 //
97 // check if device type is zero
98 //
99 if (InquiryData->DeviceType == 0)
100 {
101 if (IsFloppy)
102 {
103 //
104 // floppy device
105 //
106 return "GenSFloppy";
107 }
108
109 //
110 // direct access device
111 //
112 return "GenDisk";
113 }
114
115 //
116 // FIXME: use constant - derived from http://en.wikipedia.org/wiki/SCSI_Peripheral_Device_Type
117 //
118 switch (InquiryData->DeviceType)
119 {
120 case 1:
121 {
122 //
123 // sequential device, i.e magnetic tape
124 //
125 return "GenSequential";
126 }
127 case 4:
128 {
129 //
130 // write once device
131 //
132 return "GenWorm";
133 }
134 case 5:
135 {
136 //
137 // CDROM device
138 //
139 return "GenCdRom";
140 }
141 case 7:
142 {
143 //
144 // optical memory device
145 //
146 return "GenOptical";
147 }
148 case 8:
149 {
150 //
151 // medium change device
152 //
153 return "GenChanger";
154 }
155 default:
156 {
157 //
158 // other device
159 //
160 return "UsbstorOther";
161 }
162 }
163}
164
165
166ULONG
168 IN PUCHAR Name,
170 IN ULONG MaxLength)
171{
172 ULONG Index;
173
174 for(Index = 0; Index < MaxLength; Index++)
175 {
176 if (Name[Index] <= ' ' || Name[Index] >= 0x7F /* last printable ascii character */ || Name[Index] == ',')
177 {
178 //
179 // convert to underscore
180 //
181 Buffer[Index] = '_';
182 }
183 else
184 {
185 //
186 // just copy character
187 //
189 }
190 }
191
192 return MaxLength;
193}
194
198 IN PIRP Irp)
199{
200 //PPDO_DEVICE_EXTENSION DeviceExtension;
201 PIO_STACK_LOCATION IoStack;
203 static WCHAR DeviceText[] = L"USB Mass Storage Device";
204
205 //
206 // get current stack location
207 //
209
210 if (IoStack->Parameters.QueryDeviceText.DeviceTextType == DeviceTextDescription)
211 {
212 DPRINT("USBSTOR_PdoHandleQueryDeviceText DeviceTextDescription\n");
213
214 //
215 // allocate item
216 //
217 Buffer = (LPWSTR)AllocateItem(PagedPool, sizeof(DeviceText));
218 if (!Buffer)
219 {
220 //
221 // no memory
222 //
223 Irp->IoStatus.Information = 0;
225 }
226
227 //
228 // copy buffer
229 //
230 wcscpy(Buffer, DeviceText);
231
232 //
233 // save result
234 //
235 Irp->IoStatus.Information = (ULONG_PTR)Buffer;
236 return STATUS_SUCCESS;
237 }
238 else
239 {
240 DPRINT("USBSTOR_PdoHandleQueryDeviceText DeviceTextLocationInformation\n");
241
242 //
243 // allocate item
244 //
245 Buffer = (LPWSTR)AllocateItem(PagedPool, sizeof(DeviceText));
246 if (!Buffer)
247 {
248 //
249 // no memory
250 //
251 Irp->IoStatus.Information = 0;
253 }
254
255 //
256 // copy buffer
257 //
258 wcscpy(Buffer, DeviceText);
259
260 //
261 // save result
262 //
263 Irp->IoStatus.Information = (ULONG_PTR)Buffer;
264 return STATUS_SUCCESS;
265 }
266
267}
268
269
273 IN PIRP Irp)
274{
275 PPDO_DEVICE_EXTENSION DeviceExtension;
277 CHAR Buffer[100];
279 ULONG Offset = 0;
280 PUFI_INQUIRY_RESPONSE InquiryData;
282 UNICODE_STRING DeviceId;
283
284 //
285 // get device extension
286 //
287 DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
288
289 //
290 // sanity check
291 //
292 ASSERT(DeviceExtension->InquiryData);
293
294 //
295 // get inquiry data
296 //
297 InquiryData = (PUFI_INQUIRY_RESPONSE)DeviceExtension->InquiryData;
298
299 //
300 // get device type
301 //
302 DeviceType = USBSTOR_GetDeviceType(InquiryData, DeviceExtension->IsFloppy);
303
304 //
305 // zero buffer
306 //
307 RtlZeroMemory(Buffer, sizeof(Buffer));
308
309 //
310 // lets create device string
311 //
312 Offset = sprintf(&Buffer[Offset], "USBSTOR\\");
314 Offset += sprintf(&Buffer[Offset], "&Ven_");
315 Offset += CopyField(InquiryData->Vendor, &Buffer[Offset], 8);
316 Offset += sprintf(&Buffer[Offset], "&Prod_");
317 Offset += CopyField(InquiryData->Product, &Buffer[Offset], 16);
318 Offset += sprintf(&Buffer[Offset], "&Rev_");
319 Offset += CopyField(InquiryData->Revision, &Buffer[Offset], 4);
320
321 //
322 // now initialize ansi string
323 //
325
326 //
327 // allocate DeviceId string
328 //
329 DeviceId.Length = 0;
330 DeviceId.MaximumLength = (strlen((PCHAR)Buffer) + 1) * sizeof(WCHAR);
331 DeviceId.Buffer = (LPWSTR)AllocateItem(PagedPool, DeviceId.MaximumLength);
332 if (!DeviceId.Buffer)
333 {
334 //
335 // no memory
336 //
337 Irp->IoStatus.Information = 0;
339 }
340
341
342 //
343 // convert to unicode
344 //
346
347 if (NT_SUCCESS(Status))
348 {
349 //
350 // store result
351 //
352 Irp->IoStatus.Information = (ULONG_PTR)DeviceId.Buffer;
353 }
354
355 DPRINT("DeviceId %wZ Status %x\n", &DeviceId, Status);
356
357 //
358 // done
359 //
360 return Status;
361}
362
363VOID
365 IN CHAR * Buffer,
366 IN ULONG ResultBufferLength,
367 IN ULONG ResultBufferOffset,
369 OUT PULONG NewResultBufferOffset)
370{
371 UNICODE_STRING DeviceString;
374
375 ASSERT(ResultBufferLength);
376 ASSERT(ResultBufferLength > ResultBufferOffset);
377
378 DPRINT("ResultBufferOffset %lu ResultBufferLength %lu Buffer %s Length %lu\n", ResultBufferOffset, ResultBufferLength, Buffer, strlen(Buffer));
379
380 //
381 // construct destination string
382 //
383 DeviceString.Buffer = &ResultBuffer[ResultBufferOffset];
384 DeviceString.Length = 0;
385 DeviceString.MaximumLength = (ResultBufferLength - ResultBufferOffset) * sizeof(WCHAR);
386
387 //
388 // initialize source string
389 //
391
392 //
393 // convert to unicode
394 //
397
398 //
399 // subtract consumed bytes
400 //
401 ResultBufferLength -= (DeviceString.Length + sizeof(WCHAR)) / sizeof(WCHAR);
402 ResultBufferOffset += (DeviceString.Length + sizeof(WCHAR)) / sizeof(WCHAR);
403
404 //
405 // store new offset
406 //
407 *NewResultBufferOffset = ResultBufferOffset;
408}
409
410
411
415 IN OUT PIRP Irp)
416{
417 PPDO_DEVICE_EXTENSION PDODeviceExtension;
418 PFDO_DEVICE_EXTENSION FDODeviceExtension;
419 LPCSTR GenericType, DeviceType;
421 CHAR Id1[50], Id2[50], Id3[50], Id4[50], Id5[50], Id6[50];
422 ULONG Id1Length, Id2Length, Id3Length, Id4Length, Id5Length,Id6Length;
424 PUFI_INQUIRY_RESPONSE InquiryData;
425
426 //
427 // get PDO device extension
428 //
429 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
430
431 //
432 // get FDO device extension
433 //
434 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
435
436 //
437 // sanity check
438 //
439 ASSERT(FDODeviceExtension->DeviceDescriptor);
440
441 //
442 // get inquiry data
443 //
444 InquiryData = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData;
445
446
447 //
448 // get device type and generic type
449 //
450 DeviceType = USBSTOR_GetDeviceType(InquiryData, PDODeviceExtension->IsFloppy);
451 GenericType = USBSTOR_GetGenericType(InquiryData, PDODeviceExtension->IsFloppy);
452
453 ASSERT(GenericType);
454
455 //
456 // generate id 1
457 // USBSTOR\SCSIType_Vendor(8)_Product(16)_Revision(4)
458 //
459 RtlZeroMemory(Id1, sizeof(Id1));
460 Offset = 0;
461 Offset = sprintf(&Id1[Offset], "USBSTOR\\");
462 Offset += sprintf(&Id1[Offset], DeviceType);
463 Offset += CopyField(InquiryData->Vendor, &Id1[Offset], 8);
464 Offset += CopyField(InquiryData->Product, &Id1[Offset], 16);
465 Offset += CopyField(InquiryData->Revision, &Id1[Offset], 4);
466 Id1Length = strlen(Id1) + 1;
467 DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId1 %s\n", Id1);
468
469 //
470 // generate id 2
471 // USBSTOR\SCSIType_VENDOR(8)_Product(16)
472 //
473 RtlZeroMemory(Id2, sizeof(Id2));
474 Offset = 0;
475 Offset = sprintf(&Id2[Offset], "USBSTOR\\");
476 Offset += sprintf(&Id2[Offset], DeviceType);
477 Offset += CopyField(InquiryData->Vendor, &Id2[Offset], 8);
478 Offset += CopyField(InquiryData->Product, &Id2[Offset], 16);
479 Id2Length = strlen(Id2) + 1;
480 DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId2 %s\n", Id2);
481
482 //
483 // generate id 3
484 // USBSTOR\SCSIType_VENDOR(8)
485 //
486 RtlZeroMemory(Id3, sizeof(Id3));
487 Offset = 0;
488 Offset = sprintf(&Id3[Offset], "USBSTOR\\");
489 Offset += sprintf(&Id3[Offset], DeviceType);
490 Offset += CopyField(InquiryData->Vendor, &Id3[Offset], 8);
491 Id3Length = strlen(Id3) + 1;
492 DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId3 %s\n", Id3);
493
494 //
495 // generate id 4
496 // USBSTOR\SCSIType_VENDOR(8)_Product(16)_Revision(1)
497 //
498 RtlZeroMemory(Id4, sizeof(Id4));
499 Offset = 0;
500 Offset = sprintf(&Id4[Offset], "USBSTOR\\");
501 Offset += sprintf(&Id4[Offset], DeviceType);
502 Offset += CopyField(InquiryData->Vendor, &Id4[Offset], 8);
503 Offset += CopyField(InquiryData->Product, &Id4[Offset], 16);
504 Offset += CopyField(InquiryData->Revision, &Id4[Offset], 1);
505 Id4Length = strlen(Id4) + 1;
506 DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId4 %s\n", Id4);
507
508 //
509 // generate id 5
510 // USBSTOR\SCSIType
511 //
512 RtlZeroMemory(Id5, sizeof(Id5));
513 Offset = 0;
514 Offset = sprintf(&Id5[Offset], "USBSTOR\\");
515 Offset += sprintf(&Id5[Offset], GenericType);
516 Id5Length = strlen(Id5) + 1;
517 DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId5 %s\n", Id5);
518
519 //
520 // generate id 6
521 // SCSIType
522 //
523 RtlZeroMemory(Id6, sizeof(Id6));
524 Offset = 0;
525 Offset = sprintf(&Id6[Offset], GenericType);
526 Id6Length = strlen(Id6) + 1;
527 DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId6 %s\n", Id6);
528
529 //
530 // compute total length
531 //
532 TotalLength = Id1Length + Id2Length + Id3Length + Id4Length + Id5Length + Id6Length + 1;
533
534 //
535 // allocate buffer
536 //
538 if (!Buffer)
539 {
540 //
541 // no memory
542 //
543 Irp->IoStatus.Information = 0;
545 }
546
547 //
548 // reset offset
549 //
550 Offset = 0;
552
559
560 //
561 // sanity check
562 //
563 ASSERT(Offset + 1 == Length);
564
565 //
566 // store result
567 //
568 Irp->IoStatus.Information = (ULONG_PTR)Buffer;
569
570 //
571 // done
572 //
573 return STATUS_SUCCESS;
574}
575
579 IN OUT PIRP Irp)
580{
581 PPDO_DEVICE_EXTENSION PDODeviceExtension;
582 PFDO_DEVICE_EXTENSION FDODeviceExtension;
583 CHAR Buffer[100];
587
588 //
589 // get PDO device extension
590 //
591 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
592
593 //
594 // get FDO device extension
595 //
596 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
597
598 //
599 // sanity check
600 //
601 ASSERT(FDODeviceExtension->DeviceDescriptor);
602
603 //
604 // get target device type
605 //
606 DeviceType = USBSTOR_GetDeviceType((PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData, PDODeviceExtension->IsFloppy);
607
608 //
609 // zero memory
610 //
611 RtlZeroMemory(Buffer, sizeof(Buffer));
612
613 //
614 // format instance id
615 //
616 Length = sprintf(Buffer, "USBSTOR\\%s", DeviceType) + 1;
617 Length += sprintf(&Buffer[Length], "USBSTOR\\%s", "RAW") + 2;
618
619 //
620 // allocate instance id
621 //
623 if (!InstanceId)
624 {
625 //
626 // no memory
627 //
628 Irp->IoStatus.Information = 0;
630 }
631
634
635 DPRINT("USBSTOR_PdoHandleQueryCompatibleId %S\n", InstanceId);
636
637 //
638 // store result
639 //
640 Irp->IoStatus.Information = (ULONG_PTR)InstanceId;
641
642 //
643 // completed successfully
644 //
645 return STATUS_SUCCESS;
646}
647
651 IN OUT PIRP Irp)
652{
653 PPDO_DEVICE_EXTENSION PDODeviceExtension;
654 PFDO_DEVICE_EXTENSION FDODeviceExtension;
655 WCHAR Buffer[100];
658
659 //
660 // get PDO device extension
661 //
662 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
663
664 //
665 // get FDO device extension
666 //
667 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
668
669 //
670 // format instance id
671 //
672 if (FDODeviceExtension->SerialNumber)
673 {
674 //
675 // using serial number from device
676 //
677 swprintf(Buffer, L"%s&%c", FDODeviceExtension->SerialNumber->bString, PDODeviceExtension->LUN);
678 }
679 else
680 {
681 //
682 // use instance count and LUN
683 //
684 swprintf(Buffer, L"%04lu&%c", FDODeviceExtension->InstanceCount, PDODeviceExtension->LUN);
685 }
686
687 //
688 // calculate length
689 //
690 Length = wcslen(Buffer) + 1;
691
692 //
693 // allocate instance id
694 //
696 if (!InstanceId)
697 {
698 //
699 // no memory
700 //
701 Irp->IoStatus.Information = 0;
703 }
704
705 //
706 // copy instance id
707 //
709
710 DPRINT("USBSTOR_PdoHandleQueryInstanceId %S\n", InstanceId);
711
712 //
713 // store result
714 //
715 Irp->IoStatus.Information = (ULONG_PTR)InstanceId;
716
717 //
718 // completed successfully
719 //
720 return STATUS_SUCCESS;
721}
722
726 IN OUT PIRP Irp)
727{
728 PDEVICE_RELATIONS DeviceRelations;
729 PIO_STACK_LOCATION IoStack;
730
731 DPRINT("USBSTOR_PdoHandleDeviceRelations\n");
732
733 //
734 // get current irp stack location
735 //
737
738 //
739 // check if relation type is BusRelations
740 //
742 {
743 //
744 // PDO handles only target device relation
745 //
746 return Irp->IoStatus.Status;
747 }
748
749 //
750 // allocate device relations
751 //
752 DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS));
753 if (!DeviceRelations)
754 {
755 //
756 // no memory
757 //
759 }
760
761 //
762 // initialize device relations
763 //
764 DeviceRelations->Count = 1;
765 DeviceRelations->Objects[0] = DeviceObject;
767
768 //
769 // store result
770 //
771 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
772
773 //
774 // completed successfully
775 //
776 return STATUS_SUCCESS;
777}
778
779
783 IN OUT PIRP Irp)
784{
785 PIO_STACK_LOCATION IoStack;
786 PPDO_DEVICE_EXTENSION DeviceExtension;
789 ULONG bDelete;
790
791 //
792 // get current stack location
793 //
795
796 //
797 // get device extension
798 //
799 DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
800
801 //
802 // sanity check
803 //
804 ASSERT(DeviceExtension->Common.IsFDO == FALSE);
805
806 switch(IoStack->MinorFunction)
807 {
809 {
811 break;
812 }
814 {
816 break;
817 }
818 case IRP_MN_QUERY_ID:
819 {
820 if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID)
821 {
822 //
823 // handle query device id
824 //
826 break;
827 }
828 else if (IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs)
829 {
830 //
831 // handle instance id
832 //
834 break;
835 }
836 else if (IoStack->Parameters.QueryId.IdType == BusQueryInstanceID)
837 {
838 //
839 // handle instance id
840 //
842 break;
843 }
844 else if (IoStack->Parameters.QueryId.IdType == BusQueryCompatibleIDs)
845 {
846 //
847 // handle instance id
848 //
850 break;
851 }
852
853 DPRINT1("USBSTOR_PdoHandlePnp: IRP_MN_QUERY_ID IdType %x unimplemented\n", IoStack->Parameters.QueryId.IdType);
855 Irp->IoStatus.Information = 0;
856 break;
857 }
859 {
860 DPRINT("IRP_MN_REMOVE_DEVICE\n");
861
862 if(*DeviceExtension->PDODeviceObject != NULL)
863 {
864 //
865 // clear entry in FDO pdo list
866 //
867 *DeviceExtension->PDODeviceObject = NULL;
868 bDelete = TRUE;
869 }
870 else
871 {
872 //
873 // device object already marked for deletion
874 //
875 bDelete = FALSE;
876 }
877
878 /* Complete the IRP */
879 Irp->IoStatus.Status = STATUS_SUCCESS;
881
882 if (bDelete)
883 {
884 /* Delete the device object */
886 }
887 return STATUS_SUCCESS;
888 }
890 {
891 //
892 // just forward irp to lower device
893 //
894 Status = USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp);
896
897 if (NT_SUCCESS(Status))
898 {
899 //
900 // check if no unique id
901 //
902 Caps = (PDEVICE_CAPABILITIES)IoStack->Parameters.DeviceCapabilities.Capabilities;
903 Caps->UniqueID = FALSE; // no unique id is supported
904 Caps->Removable = TRUE; //FIXME
905 }
906 break;
907 }
910 {
911#if 0
912 //
913 // if we're not claimed it's ok
914 //
915 if (DeviceExtension->Claimed)
916#else
917 if (TRUE)
918#endif
919 {
921 DPRINT1("[USBSTOR] Request %x fails because device is still claimed\n", IoStack->MinorFunction);
922 }
923 else
925 break;
926 }
928 {
929 //
930 // no-op for PDO
931 //
933 break;
934 }
936 {
938 break;
939 }
940 default:
941 {
942 //
943 // do nothing
944 //
945 Status = Irp->IoStatus.Status;
946 }
947 }
948
949 //
950 // complete request
951 //
952 if (Status != STATUS_PENDING)
953 {
954 //
955 // store result
956 //
957 Irp->IoStatus.Status = Status;
958
959 //
960 // complete request
961 //
963 }
964
965 //
966 // done processing
967 //
968 return Status;
969}
970
972NTAPI
975 IN PIRP Irp,
976 IN PVOID Ctx)
977{
978 PKEVENT Event = (PKEVENT)Ctx;
979
980 //
981 // signal event
982 //
985}
986
990 IN ULONG DataTransferLength,
994 OUT PIRP *OutIrp)
995{
996 PIRP Irp;
997 PIO_STACK_LOCATION IoStack;
999 PCDB pCDB;
1000
1001 //
1002 // allocate irp
1003 //
1004 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
1005 if (!Irp)
1006 {
1007 //
1008 // no memory
1009 //
1011 }
1012
1013 //
1014 // get next stack location
1015 //
1016 IoStack = IoGetNextIrpStackLocation(Irp);
1017
1018 //
1019 // create scsi block
1020 //
1022 sizeof(SCSI_REQUEST_BLOCK),
1023 USB_STOR_TAG);
1024 if (!Request)
1025 {
1026 //
1027 // no memory
1028 //
1029 IoFreeIrp(Irp);
1031 }
1032
1033 //
1034 // init request
1035 //
1037
1038 //
1039 // allocate data transfer block
1040 //
1042 DataTransferLength,
1043 USB_STOR_TAG);
1044 if (!Request->DataBuffer)
1045 {
1046 //
1047 // no memory
1048 //
1049 IoFreeIrp(Irp);
1052 }
1053
1054 //
1055 // allocate MDL
1056 //
1057 Irp->MdlAddress = IoAllocateMdl(Request->DataBuffer, DataTransferLength, FALSE, FALSE, NULL);
1058 if (!Irp->MdlAddress)
1059 {
1060 //
1061 // no memory
1062 //
1063 IoFreeIrp(Irp);
1067 }
1068
1069 //
1070 // non paged pool
1071 //
1072 MmBuildMdlForNonPagedPool(Irp->MdlAddress);
1073
1074 //
1075 // init scsi block
1076 //
1077 Request->DataTransferLength = DataTransferLength;
1079 Request->SrbFlags = SRB_FLAGS_DATA_IN;
1080
1081 RtlZeroMemory(Request->DataBuffer, DataTransferLength);
1082
1083
1084 //
1085 // get SCSI command data block
1086 //
1087 pCDB = (PCDB)Request->Cdb;
1088
1089 //
1090 // set op code
1091 //
1092 pCDB->AsByte[0] = OpCode;
1093
1094 //
1095 // store result
1096 //
1098 IoStack->Parameters.Others.Argument1 = Request;
1099 IoStack->DeviceObject = DeviceObject;
1100
1101 //
1102 // init event
1103 //
1105
1106 //
1107 // lets setup a completion routine
1108 //
1110
1111 //
1112 // output result
1113 //
1114 *OutIrp = Irp;
1116 return STATUS_SUCCESS;
1117}
1118
1121 IN PDEVICE_OBJECT PDODeviceObject,
1122 IN ULONG DataTransferLength,
1123 IN UCHAR OpCode,
1124 OUT PVOID *OutData)
1125{
1127 PIRP Irp;
1128 KEVENT Event;
1129 PPDO_DEVICE_EXTENSION PDODeviceExtension;
1131
1132 //
1133 // let's allocate an irp
1134 //
1135 Status = USBSTOR_AllocateIrp(PDODeviceObject, DataTransferLength, OpCode, &Event, &Request, &Irp);
1136 if (!NT_SUCCESS(Status))
1137 {
1138 //
1139 // failed
1140 //
1141 DPRINT1("[USBSTOR] Failed to build irp\n");
1142 return Status;
1143 }
1144
1145 //
1146 // get device extension
1147 //
1148 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension;
1149
1150 //
1151 // send irp
1152 //
1153 ASSERT(Irp);
1154 ASSERT(PDODeviceExtension->LowerDeviceObject);
1155 Status = IoCallDriver(PDODeviceExtension->Self, Irp);
1156
1157 if (Status == STATUS_PENDING)
1158 {
1159 //
1160 // wait for completion
1161 //
1163 Status = Irp->IoStatus.Status;
1164 }
1165
1166 if (NT_SUCCESS(Status))
1167 {
1168 //
1169 // store result
1170 //
1171 *OutData = Request->DataBuffer;
1172 }
1173 else
1174 {
1175 //
1176 // free the data
1177 //
1179 *OutData = NULL;
1180 }
1181
1182 //
1183 // free resources
1184 //
1186 IoFreeMdl(Irp->MdlAddress);
1187 IoFreeIrp(Irp);
1188 return Status;
1189}
1190
1193 IN PDEVICE_OBJECT PDODeviceObject)
1194{
1196 PPDO_DEVICE_EXTENSION PDODeviceExtension;
1198
1199 //
1200 // get device extension
1201 //
1202 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension;
1203
1204 //
1205 // send request
1206 //
1208 if (!NT_SUCCESS(Status))
1209 {
1210 //
1211 // command failed
1212 //
1213 DPRINT1("USBSTOR_SendInquiryIrp Failed with %x\n", Status);
1214 return Status;
1215 }
1216
1217 DPRINT1("Response %p\n", Response);
1218 DPRINT1("DeviceType %x\n", Response->DeviceType);
1219 DPRINT1("RMB %x\n", Response->RMB);
1220 DPRINT1("Version %x\n", Response->Version);
1221 DPRINT1("Format %x\n", Response->Format);
1222 DPRINT1("Length %x\n", Response->Length);
1223 DPRINT1("Reserved %p\n", Response->Reserved);
1224 DPRINT1("Vendor %c%c%c%c%c%c%c%c\n", Response->Vendor[0], Response->Vendor[1], Response->Vendor[2], Response->Vendor[3], Response->Vendor[4], Response->Vendor[5], Response->Vendor[6], Response->Vendor[7]);
1225 DPRINT1("Product %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", Response->Product[0], Response->Product[1], Response->Product[2], Response->Product[3],
1226 Response->Product[4], Response->Product[5], Response->Product[6], Response->Product[7],
1227 Response->Product[8], Response->Product[9], Response->Product[10], Response->Product[11],
1228 Response->Product[12], Response->Product[13], Response->Product[14], Response->Product[15]);
1229
1230 DPRINT1("Revision %c%c%c%c\n", Response->Revision[0], Response->Revision[1], Response->Revision[2], Response->Revision[3]);
1231
1232 //
1233 // store result
1234 //
1235 PDODeviceExtension->InquiryData = (PVOID)Response;
1236 return Status;
1237}
1238
1241 IN PDEVICE_OBJECT PDODeviceObject)
1242{
1244 PPDO_DEVICE_EXTENSION PDODeviceExtension;
1246
1247 //
1248 // get device extension
1249 //
1250 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension;
1251
1252 //
1253 // send request
1254 //
1256 if (!NT_SUCCESS(Status))
1257 {
1258 //
1259 // command failed
1260 //
1261 return Status;
1262 }
1263
1264 //
1265 // check if its a floppy
1266 //
1267 PDODeviceExtension->IsFloppy = USBSTOR_IsFloppy(Response, 0xFC /*FIXME*/, &PDODeviceExtension->MediumTypeCode);
1268
1269 //
1270 // free response
1271 //
1273 return Status;
1274}
1275
1276
1277
1281 IN UCHAR LUN)
1282{
1283 PDEVICE_OBJECT PDO;
1285 PPDO_DEVICE_EXTENSION PDODeviceExtension;
1287 PFDO_DEVICE_EXTENSION FDODeviceExtension;
1288
1289 //
1290 // get device extension
1291 //
1292 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
1293
1294
1295 //
1296 // create child device object
1297 //
1299 if (!NT_SUCCESS(Status))
1300 {
1301 //
1302 // failed to create device
1303 //
1304 return Status;
1305 }
1306
1307 //
1308 // patch the stack size
1309 //
1310 PDO->StackSize = DeviceObject->StackSize;
1311
1312 //
1313 // get device extension
1314 //
1315 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDO->DeviceExtension;
1316
1317 //
1318 // initialize device extension
1319 //
1320 RtlZeroMemory(PDODeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
1321 PDODeviceExtension->Common.IsFDO = FALSE;
1322 PDODeviceExtension->LowerDeviceObject = DeviceObject;
1323 PDODeviceExtension->PDODeviceObject = &FDODeviceExtension->ChildPDO[LUN];
1324 PDODeviceExtension->Self = PDO;
1325 PDODeviceExtension->LUN = LUN;
1326
1327 //
1328 // set device flags
1329 //
1331
1332 //
1333 // device is initialized
1334 //
1335 PDO->Flags &= ~DO_DEVICE_INITIALIZING;
1336
1337 //
1338 // output device object
1339 //
1340 FDODeviceExtension->ChildPDO[LUN] = PDO;
1341
1342 //
1343 // send inquiry command by irp
1344 //
1347
1348 //
1349 // check response data
1350 //
1351 Response = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData;
1353
1354 if (Response->DeviceType == 0)
1355 {
1356 //
1357 // check if it is a floppy
1358 //
1360
1361 //
1362 // display result
1363 //
1364 DPRINT1("[USBSTOR] Status %x IsFloppy %x MediumTypeCode %x\n", Status, PDODeviceExtension->IsFloppy, PDODeviceExtension->MediumTypeCode);
1365
1366 //
1367 // failing command is non critical
1368 //
1370 }
1371
1372 //
1373 // done
1374 //
1375 return Status;
1376}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define SCSIOP_INQUIRY
Definition: cdrw_hw.h:888
union _CDB * PCDB
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
Definition: bufpool.h:45
_In_ PIRP Irp
Definition: csq.h:116
OpCode
Definition: dlist.c:229
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define swprintf
Definition: precomp.h:40
@ AnsiString
Definition: dnslib.h:19
struct _FDO_DEVICE_EXTENSION * PFDO_DEVICE_EXTENSION
struct _PDO_DEVICE_EXTENSION * PPDO_DEVICE_EXTENSION
#define ULONG_PTR
Definition: config.h:101
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:315
#define SRB_FLAGS_DATA_IN
Definition: srb.h:400
BOOLEAN USBSTOR_IsFloppy(IN PUCHAR Buffer, IN ULONG BufferLength, OUT PUCHAR MediumTypeCode)
Definition: misc.c:409
NTSTATUS NTAPI USBSTOR_SyncForwardIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: misc.c:38
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define PKEVENT
Definition: env_spec_w32.h:70
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define NonPagedPool
Definition: env_spec_w32.h:307
#define DO_MAP_IO_BUFFER
Definition: env_spec_w32.h:397
#define PagedPool
Definition: env_spec_w32.h:308
_Must_inspect_result_ _In_opt_ PVOID _In_opt_ PVOID InstanceId
Definition: fsrtlfuncs.h:908
#define IoFreeMdl
Definition: fxmdl.h:89
#define IoAllocateMdl
Definition: fxmdl.h:88
Status
Definition: gdiplustypes.h:25
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
PKMT_RESULTBUFFER ResultBuffer
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:29
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:424
DeviceType
Definition: mmdrv.h:42
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define FILE_DEVICE_MASS_STORAGE
Definition: imports.h:62
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define KernelMode
Definition: asm.h:34
#define FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
@ NotificationEvent
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define IoCompleteRequest
Definition: irp.c:1240
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define L(x)
Definition: ntvdm.h:50
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define SCSIOP_READ_FORMATTED_CAPACITY
Definition: scsi.h:273
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
static ULONG CopyField(IN PUCHAR Name, IN PCHAR Buffer, IN ULONG MaxLength, IN CHAR DefaultCharacter, IN BOOLEAN Trim)
Definition: pdo.c:124
Definition: ncftp.h:89
UCHAR Product[16]
Definition: usbstor.h:146
UCHAR Revision[4]
Definition: usbstor.h:147
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
struct _IO_STACK_LOCATION::@3978::@4017 Others
union _IO_STACK_LOCATION::@1564 Parameters
struct _IO_STACK_LOCATION::@3978::@4003 QueryDeviceRelations
struct _IO_STACK_LOCATION::@3978::@4010 QueryDeviceText
struct _IO_STACK_LOCATION::@3978::@4005 DeviceCapabilities
struct _IO_STACK_LOCATION::@3978::@4009 QueryId
COMMON_DEVICE_EXTENSION Common
Definition: pci.h:59
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
CONST char * PCSZ
Definition: umtypes.h:125
Definition: cdrw_hw.h:28
UCHAR AsByte[16]
Definition: scsi.h:1988
NTSTATUS USBSTOR_PdoHandleQueryInstanceId(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: pdo.c:434
static LPCSTR USBSTOR_GetGenericType(IN PINQUIRYDATA InquiryData)
Definition: pdo.c:45
NTSTATUS USBSTOR_CreatePDO(IN PDEVICE_OBJECT DeviceObject, IN UCHAR LUN)
Definition: pdo.c:864
NTSTATUS USBSTOR_PdoHandleQueryCompatibleId(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: pdo.c:394
NTSTATUS USBSTOR_PdoHandleQueryDeviceId(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pdo.c:179
NTSTATUS USBSTOR_PdoHandleQueryHardwareId(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: pdo.c:267
NTSTATUS USBSTOR_PdoHandlePnp(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: pdo.c:534
VOID USBSTOR_ConvertToUnicodeString(IN CHAR *Buffer, IN ULONG ResultBufferLength, IN ULONG ResultBufferOffset, OUT LPWSTR ResultBuffer, OUT PULONG NewResultBufferOffset)
Definition: pdo.c:232
NTSTATUS USBSTOR_PdoHandleDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: pdo.c:500
static LPCSTR USBSTOR_GetDeviceType(IN PINQUIRYDATA InquiryData)
Definition: pdo.c:20
NTSTATUS USBSTOR_PdoHandleQueryDeviceText(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pdo.c:125
NTSTATUS USBSTOR_SendIrp(IN PDEVICE_OBJECT PDODeviceObject, IN ULONG DataTransferLength, IN UCHAR OpCode, OUT PVOID *OutData)
Definition: pdo.c:1120
NTSTATUS USBSTOR_SendInquiryIrp(IN PDEVICE_OBJECT PDODeviceObject)
Definition: pdo.c:1192
NTSTATUS USBSTOR_AllocateIrp(IN PDEVICE_OBJECT DeviceObject, IN ULONG DataTransferLength, IN UCHAR OpCode, IN PKEVENT Event, OUT PSCSI_REQUEST_BLOCK *OutRequest, OUT PIRP *OutIrp)
Definition: pdo.c:988
NTSTATUS USBSTOR_SendFormatCapacityIrp(IN PDEVICE_OBJECT PDODeviceObject)
Definition: pdo.c:1240
NTSTATUS NTAPI USBSTOR_CompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Ctx)
Definition: pdo.c:973
_In_ ULONG TotalLength
Definition: usbdlib.h:158
#define USB_STOR_TAG
Definition: usbstor.h:11
struct UFI_INQUIRY_RESPONSE * PUFI_INQUIRY_RESPONSE
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
_Must_inspect_result_ _In_ WDFQUEUE _Out_ WDFREQUEST * OutRequest
Definition: wdfio.h:800
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
@ TargetDeviceRelation
Definition: iotypes.h:2156
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MN_START_DEVICE
#define IRP_MN_QUERY_ID
#define IRP_MN_REMOVE_DEVICE
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define IRP_MN_QUERY_STOP_DEVICE
#define IRP_MN_QUERY_DEVICE_TEXT
#define IRP_MN_QUERY_CAPABILITIES
* PDEVICE_CAPABILITIES
Definition: iotypes.h:965
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
@ DeviceTextDescription
Definition: iotypes.h:2945
@ BusQueryCompatibleIDs
Definition: iotypes.h:2938
@ BusQueryInstanceID
Definition: iotypes.h:2939
@ BusQueryDeviceID
Definition: iotypes.h:2936
@ BusQueryHardwareIDs
Definition: iotypes.h:2937
#define IRP_MN_QUERY_REMOVE_DEVICE
@ Executive
Definition: ketypes.h:415
#define ObReferenceObject
Definition: obfuncs.h:204
const char * LPCSTR
Definition: xmlstorage.h:183
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char CHAR
Definition: xmlstorage.h:175