ReactOS 0.4.15-dev-7674-gc0b4db1
pdo.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: USB block storage device driver.
5 * COPYRIGHT: 2005-2006 James Tabor
6 * 2011-2012 Michael Martin (michael.martin@reactos.org)
7 * 2011-2013 Johannes Anderwald (johannes.anderwald@reactos.org)
8 * 2017 Vadim Galyant
9 * 2019 Victor Perevertkin (victor.perevertkin@reactos.org)
10 */
11
12#include "usbstor.h"
13
14#define NDEBUG
15#include <debug.h>
16
17
18static
21 IN PINQUIRYDATA InquiryData)
22{
23 switch (InquiryData->DeviceType)
24 {
26 return "Disk";
28 // sequential device, i.e magnetic tape
29 return "Sequential";
31 return "Worm";
33 return "CdRom";
34 case OPTICAL_DEVICE:
35 return "Optical";
36 case MEDIUM_CHANGER:
37 return "Changer";
38 default:
39 return "Other";
40 }
41}
42
43static
46 IN PINQUIRYDATA InquiryData)
47{
48 switch (InquiryData->DeviceType)
49 {
51 return "GenDisk";
53 // sequential device, i.e magnetic tape
54 return "GenSequential";
56 return "GenWorm";
58 return "GenCdRom";
59 case OPTICAL_DEVICE:
60 return "GenOptical";
61 case MEDIUM_CHANGER:
62 return "GenChanger";
63 default:
64 return "UsbstorOther";
65 }
66}
67
68static
73 IN ULONG MaxLength)
74{
76
77 for (Index = 0; Index < MaxLength; Index++)
78 {
79 if (Name[Index] <= ' ' || Name[Index] >= 0x7F /* last printable ascii character */ || Name[Index] == ',')
80 {
81 // convert to underscore
82 Buffer[Index] = '_';
83 }
84 else
85 {
86 // just copy character
88 }
89 }
90
91 return MaxLength;
92}
93
94static
99 IN ULONG MaxLength)
100{
101 ULONG Index;
102
103 for (Index = 0; Index < MaxLength; Index++)
104 {
105 if (Name[Index] == '\0')
106 {
107 break;
108 }
109 else if (Name[Index] <= ' ' || Name[Index] >= 0x7F /* last printable ascii character */ || Name[Index] == ',')
110 {
111 // convert to underscore
112 Buffer[Index] = ' ';
113 }
114 else
115 {
116 // just copy character
118 }
119 }
120
121 return Index;
122}
123
127 IN PIRP Irp)
128{
129 PPDO_DEVICE_EXTENSION DeviceExtension;
130 PIO_STACK_LOCATION IoStack;
131 CHAR LocalBuffer[26];
132 UINT32 Offset = 0;
133 PINQUIRYDATA InquiryData;
136
138
139 DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
140 InquiryData = (PINQUIRYDATA)&DeviceExtension->InquiryData;
141
142 switch (IoStack->Parameters.QueryDeviceText.DeviceTextType)
143 {
146 {
147 DPRINT("USBSTOR_PdoHandleQueryDeviceText\n");
148
149 Offset += CopyFieldTruncate(InquiryData->VendorId, &LocalBuffer[Offset], sizeof(InquiryData->VendorId));
150 LocalBuffer[Offset++] = ' ';
151 Offset += CopyFieldTruncate(InquiryData->ProductId, &LocalBuffer[Offset], sizeof(InquiryData->ProductId));
152 LocalBuffer[Offset++] = '\0';
153
154 RtlInitAnsiString(&AnsiString, (PCSZ)&LocalBuffer);
155
156 DeviceDescription.Length = 0;
157 DeviceDescription.MaximumLength = (USHORT)(Offset * sizeof(WCHAR));
159 if (!DeviceDescription.Buffer)
160 {
161 Irp->IoStatus.Information = 0;
163 }
164
166
167 Irp->IoStatus.Information = (ULONG_PTR)DeviceDescription.Buffer;
168 return STATUS_SUCCESS;
169 }
170 default:
171 {
172 Irp->IoStatus.Information = 0;
173 return Irp->IoStatus.Status;
174 }
175 }
176}
177
181 IN PIRP Irp)
182{
183 PPDO_DEVICE_EXTENSION DeviceExtension;
185 CHAR Buffer[100] = {0};
187 ULONG Offset = 0;
188 PINQUIRYDATA InquiryData;
190 UNICODE_STRING DeviceId;
191
192 DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
193 InquiryData = (PINQUIRYDATA)&DeviceExtension->InquiryData;
194
195 DeviceType = USBSTOR_GetDeviceType(InquiryData);
196
197 // lets create device string
198 Offset = sprintf(&Buffer[Offset], "USBSTOR\\");
200 Offset += sprintf(&Buffer[Offset], "&Ven_");
201 Offset += CopyField(InquiryData->VendorId, &Buffer[Offset], 8);
202 Offset += sprintf(&Buffer[Offset], "&Prod_");
203 Offset += CopyField(InquiryData->ProductId, &Buffer[Offset], 16);
204 Offset += sprintf(&Buffer[Offset], "&Rev_");
205 Offset += CopyField(InquiryData->ProductRevisionLevel, &Buffer[Offset], 4);
206
208
209 // allocate DeviceId string
210 DeviceId.Length = 0;
211 DeviceId.MaximumLength = (USHORT)((strlen((PCHAR)Buffer) + 1) * sizeof(WCHAR));
213 if (!DeviceId.Buffer)
214 {
215 Irp->IoStatus.Information = 0;
217 }
218
220
221 if (NT_SUCCESS(Status))
222 {
223 Irp->IoStatus.Information = (ULONG_PTR)DeviceId.Buffer;
224 }
225
226 DPRINT("DeviceId %wZ Status %x\n", &DeviceId, Status);
227
228 return Status;
229}
230
231VOID
233 IN CHAR * Buffer,
234 IN ULONG ResultBufferLength,
235 IN ULONG ResultBufferOffset,
237 OUT PULONG NewResultBufferOffset)
238{
239 UNICODE_STRING DeviceString;
242
243 ASSERT(ResultBufferLength);
244 ASSERT(ResultBufferLength > ResultBufferOffset);
245
246 DPRINT("ResultBufferOffset %lu ResultBufferLength %lu Buffer %s Length %lu\n", ResultBufferOffset, ResultBufferLength, Buffer, strlen(Buffer));
247
248 // construct destination string
249 DeviceString.Buffer = &ResultBuffer[ResultBufferOffset];
250 DeviceString.Length = 0;
251 DeviceString.MaximumLength = (ResultBufferLength - ResultBufferOffset) * sizeof(WCHAR);
252
253 // initialize source string
255
258
259 // subtract consumed bytes
260 ResultBufferLength -= (DeviceString.Length + sizeof(WCHAR)) / sizeof(WCHAR);
261 ResultBufferOffset += (DeviceString.Length + sizeof(WCHAR)) / sizeof(WCHAR);
262
263 *NewResultBufferOffset = ResultBufferOffset;
264}
265
269 IN OUT PIRP Irp)
270{
271 PPDO_DEVICE_EXTENSION PDODeviceExtension;
272 PFDO_DEVICE_EXTENSION FDODeviceExtension;
273 LPCSTR GenericType, DeviceType;
275 CHAR Id1[50], Id2[50], Id3[50], Id4[50], Id5[50], Id6[50], Id7[50];
276 ULONG Id1Length, Id2Length, Id3Length, Id4Length, Id5Length, Id6Length, Id7Length;
278 PINQUIRYDATA InquiryData;
279
280 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
281 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
282 ASSERT(FDODeviceExtension->DeviceDescriptor);
283 InquiryData = (PINQUIRYDATA)&PDODeviceExtension->InquiryData;
284
285 DeviceType = USBSTOR_GetDeviceType(InquiryData);
286 GenericType = USBSTOR_GetGenericType(InquiryData);
287
288 ASSERT(GenericType);
289
290 // generate id 1
291 // USBSTOR\SCSIType_VendorId(8)_ProductId(16)_Revision(4)
292 RtlZeroMemory(Id1, sizeof(Id1));
293 Offset = 0;
294 Offset = sprintf(&Id1[Offset], "USBSTOR\\");
295 Offset += sprintf(&Id1[Offset], DeviceType);
296 Offset += CopyField(InquiryData->VendorId, &Id1[Offset], 8);
297 Offset += CopyField(InquiryData->ProductId, &Id1[Offset], 16);
298 Offset += CopyField(InquiryData->ProductRevisionLevel, &Id1[Offset], 4);
299 Id1Length = strlen(Id1) + 1;
300 DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId1 %s\n", Id1);
301
302 // generate id 2
303 // USBSTOR\SCSIType_VendorId(8)_ProductId(16)
304 RtlZeroMemory(Id2, sizeof(Id2));
305 Offset = 0;
306 Offset = sprintf(&Id2[Offset], "USBSTOR\\");
307 Offset += sprintf(&Id2[Offset], DeviceType);
308 Offset += CopyField(InquiryData->VendorId, &Id2[Offset], 8);
309 Offset += CopyField(InquiryData->ProductId, &Id2[Offset], 16);
310 Id2Length = strlen(Id2) + 1;
311 DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId2 %s\n", Id2);
312
313 // generate id 3
314 // USBSTOR\SCSIType_VendorId(8)
315 RtlZeroMemory(Id3, sizeof(Id3));
316 Offset = 0;
317 Offset = sprintf(&Id3[Offset], "USBSTOR\\");
318 Offset += sprintf(&Id3[Offset], DeviceType);
319 Offset += CopyField(InquiryData->VendorId, &Id3[Offset], 8);
320 Id3Length = strlen(Id3) + 1;
321 DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId3 %s\n", Id3);
322
323 // generate id 4
324 // USBSTOR\SCSIType_VendorId(8)_ProductId(16)_Revision(1)
325 RtlZeroMemory(Id4, sizeof(Id4));
326 Offset = 0;
327 Offset = sprintf(&Id4[Offset], "USBSTOR\\");
328 Offset += sprintf(&Id4[Offset], DeviceType);
329 Offset += CopyField(InquiryData->VendorId, &Id4[Offset], 8);
330 Offset += CopyField(InquiryData->ProductId, &Id4[Offset], 16);
331 Offset += CopyField(InquiryData->ProductRevisionLevel, &Id4[Offset], 1);
332 Id4Length = strlen(Id4) + 1;
333 DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId4 %s\n", Id4);
334
335 // generate id 5
336 // SCSIType_VendorId(8)_ProductId(16)_Revision(1)
337 RtlZeroMemory(Id5, sizeof(Id5));
338 Offset = 0;
340 Offset += CopyField(InquiryData->VendorId, &Id5[Offset], 8);
341 Offset += CopyField(InquiryData->ProductId, &Id5[Offset], 16);
342 Offset += CopyField(InquiryData->ProductRevisionLevel, &Id5[Offset], 1);
343 Id5Length = strlen(Id5) + 1;
344 DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId5 %s\n", Id5);
345
346 // generate id 6
347 // USBSTOR\SCSIType
348 RtlZeroMemory(Id6, sizeof(Id6));
349 Offset = 0;
350 Offset = sprintf(&Id6[Offset], "USBSTOR\\");
351 Offset += sprintf(&Id6[Offset], GenericType);
352 Id6Length = strlen(Id6) + 1;
353 DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId6 %s\n", Id6);
354
355 // generate id 7
356 // SCSIType
357 RtlZeroMemory(Id7, sizeof(Id7));
358 Offset = 0;
359 Offset = sprintf(&Id7[Offset], GenericType);
360 Id7Length = strlen(Id7) + 1;
361 DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId7 %s\n", Id7);
362
363 // last +1 is for terminating \0 of REG_MULTI_SZ
364 TotalLength = Id1Length + Id2Length + Id3Length + Id4Length + Id5Length + Id6Length + Id7Length + 1;
365
367 if (!Buffer)
368 {
369 Irp->IoStatus.Information = 0;
371 }
372
373 // reset offset
374 Offset = 0;
376
384
385 Buffer[Offset] = UNICODE_NULL; // finish the REG_MULTI_SZ
386
387 ASSERT(Offset + 1 == Length);
388
389 Irp->IoStatus.Information = (ULONG_PTR)Buffer;
390 return STATUS_SUCCESS;
391}
392
396 IN OUT PIRP Irp)
397{
398 PPDO_DEVICE_EXTENSION PDODeviceExtension;
399 PFDO_DEVICE_EXTENSION FDODeviceExtension;
400 CHAR Buffer[100] = {0};
404
405 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
406 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
407 ASSERT(FDODeviceExtension->DeviceDescriptor);
408 DeviceType = USBSTOR_GetDeviceType((PINQUIRYDATA)&PDODeviceExtension->InquiryData);
409
410 // format instance id
411 Length = sprintf(Buffer, "USBSTOR\\%s", DeviceType) + 1;
412 // +1 for terminating \0 and another +1 for \0 at the end of REG_MULTI_SZ
413 Length += sprintf(&Buffer[Length], "USBSTOR\\%s", "RAW") + 2;
414
416 if (!InstanceId)
417 {
418 Irp->IoStatus.Information = 0;
420 }
421
424
425 InstanceId[Offset] = UNICODE_NULL; // finish the REG_MULTI_SZ
426
427 DPRINT("USBSTOR_PdoHandleQueryCompatibleId %S\n", InstanceId);
428
429 Irp->IoStatus.Information = (ULONG_PTR)InstanceId;
430 return STATUS_SUCCESS;
431}
432
436 IN OUT PIRP Irp)
437{
438 PPDO_DEVICE_EXTENSION PDODeviceExtension;
439 PFDO_DEVICE_EXTENSION FDODeviceExtension;
441 ULONG CharCount;
444
445 PDODeviceExtension = DeviceObject->DeviceExtension;
446 FDODeviceExtension = PDODeviceExtension->LowerDeviceObject->DeviceExtension;
447
448 Descriptor = FDODeviceExtension->SerialNumber;
449 if (Descriptor && (Descriptor->bLength >= sizeof(USB_COMMON_DESCRIPTOR) + sizeof(WCHAR)))
450 {
451 /* Format the serial number descriptor only if supported by the device */
452 CharCount = (Descriptor->bLength - sizeof(USB_COMMON_DESCRIPTOR)) / sizeof(WCHAR) +
453 (sizeof("&") - 1) +
454 (sizeof("F") - 1) + // LUN: 1 char (MAX_LUN)
455 sizeof(ANSI_NULL);
456 }
457 else
458 {
459 /* Use the instance count and LUN as a fallback */
460 CharCount = (sizeof("99999999") - 1) + // Instance Count: 8 chars
461 (sizeof("&") - 1) +
462 (sizeof("F") - 1) + // LUN: 1 char (MAX_LUN)
463 sizeof(ANSI_NULL);
464 }
465
466 InstanceId = ExAllocatePoolUninitialized(PagedPool, CharCount * sizeof(WCHAR), USB_STOR_TAG);
467 if (!InstanceId)
468 {
469 Irp->IoStatus.Information = 0;
471 }
472
473 if (Descriptor && (Descriptor->bLength >= sizeof(USB_COMMON_DESCRIPTOR) + sizeof(WCHAR)))
474 {
476 CharCount,
477 L"%s&%x",
478 Descriptor->bString,
479 PDODeviceExtension->LUN);
480 }
481 else
482 {
484 CharCount,
485 L"%04lu&%x",
486 FDODeviceExtension->InstanceCount,
487 PDODeviceExtension->LUN);
488 }
489
490 /* This should not happen */
492
493 DPRINT("USBSTOR_PdoHandleQueryInstanceId '%S'\n", InstanceId);
494
495 Irp->IoStatus.Information = (ULONG_PTR)InstanceId;
496 return STATUS_SUCCESS;
497}
498
502 IN OUT PIRP Irp)
503{
504 PDEVICE_RELATIONS DeviceRelations;
505 PIO_STACK_LOCATION IoStack;
506
507 DPRINT("USBSTOR_PdoHandleDeviceRelations\n");
508
510
511 // check if relation type is BusRelations
512 if (IoStack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
513 {
514 // PDO handles only target device relation
515 return Irp->IoStatus.Status;
516 }
517
519 if (!DeviceRelations)
520 {
522 }
523
524 // initialize device relations
525 DeviceRelations->Count = 1;
526 DeviceRelations->Objects[0] = DeviceObject;
528
529 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
530 return STATUS_SUCCESS;
531}
532
536 IN OUT PIRP Irp)
537{
538 PIO_STACK_LOCATION IoStack;
539 PPDO_DEVICE_EXTENSION DeviceExtension;
542 ULONG bDelete;
543
545 DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
546 ASSERT(DeviceExtension->Common.IsFDO == FALSE);
547
548 switch(IoStack->MinorFunction)
549 {
551 {
553 break;
554 }
556 {
558 break;
559 }
560 case IRP_MN_QUERY_ID:
561 {
562 if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID)
563 {
565 break;
566 }
567 else if (IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs)
568 {
570 break;
571 }
572 else if (IoStack->Parameters.QueryId.IdType == BusQueryInstanceID)
573 {
575 break;
576 }
577 else if (IoStack->Parameters.QueryId.IdType == BusQueryCompatibleIDs)
578 {
580 break;
581 }
582
583 DPRINT1("USBSTOR_PdoHandlePnp: IRP_MN_QUERY_ID IdType %x unimplemented\n", IoStack->Parameters.QueryId.IdType);
585 Irp->IoStatus.Information = 0;
586 break;
587 }
589 {
590 DPRINT("IRP_MN_REMOVE_DEVICE\n");
591
592 if(*DeviceExtension->PDODeviceObject != NULL)
593 {
594 *DeviceExtension->PDODeviceObject = NULL;
595 bDelete = TRUE;
596 }
597 else
598 {
599 // device object already marked for deletion
600 bDelete = FALSE;
601 }
602
603 Irp->IoStatus.Status = STATUS_SUCCESS;
605
606 if (bDelete)
607 {
609 }
610 return STATUS_SUCCESS;
611 }
613 {
614 // just forward irp to lower device
616
617 if (IoForwardIrpSynchronously(DeviceExtension->LowerDeviceObject, Irp))
618 {
619 Status = Irp->IoStatus.Status;
621
622 if (NT_SUCCESS(Status))
623 {
624 // check if no unique id
625 Caps = (PDEVICE_CAPABILITIES)IoStack->Parameters.DeviceCapabilities.Capabilities;
626 Caps->UniqueID = FALSE; // no unique id is supported
627 Caps->Removable = TRUE; //FIXME
628 }
629 }
630 break;
631 }
634 {
635 if (DeviceExtension->Claimed)
636 {
638 DPRINT1("[USBSTOR] Request %x fails because device is still claimed\n", IoStack->MinorFunction);
639 }
640 else
642 break;
643 }
645 {
646 // no-op for PDO
648 break;
649 }
651 {
653 break;
654 }
655 default:
656 {
657 // do nothing
658 Status = Irp->IoStatus.Status;
659 }
660 }
661
662 if (Status != STATUS_PENDING)
663 {
664 Irp->IoStatus.Status = Status;
666 }
667
668 return Status;
669}
670
672NTAPI
675 IN PIRP Irp,
676 IN PVOID Ctx)
677{
680}
681
682/*
683* @name USBSTOR_SendInternalCdb
684*
685* Issues an internal SCSI request to device.
686* The request is sent in a synchronous way.
687*/
688static
691 IN PDEVICE_OBJECT PdoDevice,
692 IN PCDB Cdb,
693 IN UCHAR CdbLength,
694 IN ULONG TimeOutValue,
695 OUT PVOID OutDataBuffer,
696 OUT PULONG OutDataTransferLength)
697{
699 PSENSE_DATA SenseBuffer;
700 PIO_STACK_LOCATION IoStack;
702 PIRP Irp = NULL;
703 PMDL Mdl = NULL;
704 ULONG ix = 0;
706 UCHAR SrbStatus;
707
708 DPRINT("USBSTOR_SendInternalCdb SCSIOP %x\n", Cdb->CDB6GENERIC.OperationCode);
709
711 sizeof(SCSI_REQUEST_BLOCK),
713
714 if (Srb)
715 {
719
720 if (SenseBuffer)
721 {
722 Mdl = IoAllocateMdl(OutDataBuffer,
723 *OutDataTransferLength,
724 FALSE,
725 FALSE,
726 NULL);
727
728 if (!Mdl)
729 {
730 ExFreePoolWithTag(SenseBuffer, USB_STOR_TAG);
732 return Status;
733 }
734
736
737 // make 3 attempts - the device may be in STALL state after the first one
738 do
739 {
740 Irp = IoAllocateIrp(PdoDevice->StackSize, FALSE);
741
742 if (!Irp)
743 {
744 break;
745 }
746
749 IoStack->Parameters.Scsi.Srb = Srb;
750
752
753 Srb->Length = sizeof(SCSI_REQUEST_BLOCK);
755 Srb->CdbLength = CdbLength;
758 Srb->DataTransferLength = *OutDataTransferLength;
759 Srb->TimeOutValue = TimeOutValue;
760 Srb->DataBuffer = OutDataBuffer;
761 Srb->SenseInfoBuffer = SenseBuffer;
762
763 RtlCopyMemory(Srb->Cdb, Cdb, CdbLength);
764
765 Irp->MdlAddress = Mdl;
766
768
771 &Event,
772 TRUE,
773 TRUE,
774 TRUE);
775
776 if (IoCallDriver(PdoDevice, Irp) == STATUS_PENDING)
777 {
779 Executive,
781 FALSE,
782 NULL);
783 }
784
785 SrbStatus = SRB_STATUS(Srb->SrbStatus);
786
787 IoFreeIrp(Irp);
788 Irp = NULL;
789
790 if (SrbStatus == SRB_STATUS_SUCCESS ||
791 SrbStatus == SRB_STATUS_DATA_OVERRUN)
792 {
794 *OutDataTransferLength = Srb->DataTransferLength;
795 break;
796 }
797
799
800 ++ix;
801 } while (ix < 3);
802
803 if (Mdl)
804 {
805 IoFreeMdl(Mdl);
806 }
807
808 ExFreePoolWithTag(SenseBuffer, USB_STOR_TAG);
809 }
810
812 }
813
814 return Status;
815}
816
817/*
818* @name USBSTOR_FillInquiryData
819*
820* Sends a SCSI Inquiry request and fills in the PDODeviceExtension->InquiryData field with a result.
821*/
822static
825 IN PDEVICE_OBJECT PDODeviceObject)
826{
828 PPDO_DEVICE_EXTENSION PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension;
829 CDB Cdb;
830 ULONG DataTransferLength = INQUIRYDATABUFFERSIZE;
831 PINQUIRYDATA InquiryData = (PINQUIRYDATA)&PDODeviceExtension->InquiryData;
832
833 RtlZeroMemory(&Cdb, sizeof(Cdb));
834 Cdb.CDB6INQUIRY.OperationCode = SCSIOP_INQUIRY;
835 Cdb.CDB6INQUIRY.AllocationLength = INQUIRYDATABUFFERSIZE;
836
837 Status = USBSTOR_SendInternalCdb(PDODeviceObject, &Cdb, CDB6GENERIC_LENGTH, 20, InquiryData, &DataTransferLength);
838
839 if (!NT_SUCCESS(Status))
840 {
841 DPRINT1("USBSTOR_FillInquiryData failed with %x\n", Status);
842 return Status;
843 }
844
845 DPRINT("DeviceType %x\n", InquiryData->DeviceType);
846 DPRINT("DeviceTypeModifier %x\n", InquiryData->DeviceTypeModifier);
847 DPRINT("RemovableMedia %x\n", InquiryData->RemovableMedia);
848 DPRINT("Version %x\n", InquiryData->Versions);
849 DPRINT("Format %x\n", InquiryData->ResponseDataFormat);
850 DPRINT("Length %x\n", InquiryData->AdditionalLength);
851 DPRINT("Reserved %p\n", InquiryData->Reserved);
852 DPRINT("VendorId %c%c%c%c%c%c%c%c\n", InquiryData->VendorId[0], InquiryData->VendorId[1], InquiryData->VendorId[2], InquiryData->VendorId[3], InquiryData->VendorId[4], InquiryData->VendorId[5], InquiryData->VendorId[6], InquiryData->VendorId[7]);
853 DPRINT("ProductId %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", InquiryData->ProductId[0], InquiryData->ProductId[1], InquiryData->ProductId[2], InquiryData->ProductId[3],
854 InquiryData->ProductId[4], InquiryData->ProductId[5], InquiryData->ProductId[6], InquiryData->ProductId[7],
855 InquiryData->ProductId[8], InquiryData->ProductId[9], InquiryData->ProductId[10], InquiryData->ProductId[11],
856 InquiryData->ProductId[12], InquiryData->ProductId[13], InquiryData->ProductId[14], InquiryData->ProductId[15]);
857
858 DPRINT("Revision %c%c%c%c\n", InquiryData->ProductRevisionLevel[0], InquiryData->ProductRevisionLevel[1], InquiryData->ProductRevisionLevel[2], InquiryData->ProductRevisionLevel[3]);
859
860 return Status;
861}
862
866 IN UCHAR LUN)
867{
868 PDEVICE_OBJECT PDO;
870 PPDO_DEVICE_EXTENSION PDODeviceExtension;
871 PFDO_DEVICE_EXTENSION FDODeviceExtension;
872 PINQUIRYDATA InquiryData;
873
874 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
875
876 // create child device object
878 if (!NT_SUCCESS(Status))
879 {
880 DPRINT1("Failed to create PDO, status %x\n", Status);
881 return Status;
882 }
883
884 // patch the stack size
885 PDO->StackSize = DeviceObject->StackSize;
886
887 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDO->DeviceExtension;
888 InquiryData = (PINQUIRYDATA)&PDODeviceExtension->InquiryData;
889
890 // initialize device extension
891 RtlZeroMemory(PDODeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
892 PDODeviceExtension->Common.IsFDO = FALSE;
893 PDODeviceExtension->LowerDeviceObject = DeviceObject;
894 PDODeviceExtension->PDODeviceObject = &FDODeviceExtension->ChildPDO[LUN];
895 PDODeviceExtension->Self = PDO;
896 PDODeviceExtension->LUN = LUN;
897
898 PDO->Flags |= DO_DIRECT_IO;
899
900 // device is initialized
901 PDO->Flags &= ~DO_DEVICE_INITIALIZING;
902
903 // output device object
904 FDODeviceExtension->ChildPDO[LUN] = PDO;
905
906 // send inquiry command by irp
908
909 if (!NT_SUCCESS(Status))
910 {
911 return Status;
912 }
913
914 if (InquiryData->DeviceType != DIRECT_ACCESS_DEVICE &&
916 {
918 }
919
920 return Status;
921}
unsigned int UINT32
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
_In_ PSCSI_REQUEST_BLOCK Srb
Definition: cdrom.h:989
struct _INQUIRYDATA * PINQUIRYDATA
#define SCSIOP_INQUIRY
Definition: cdrw_hw.h:888
#define CDB6GENERIC_LENGTH
Definition: cdrw_hw.h:830
#define WRITE_ONCE_READ_MULTIPLE_DEVICE
Definition: cdrw_hw.h:1148
#define DIRECT_ACCESS_DEVICE
Definition: cdrw_hw.h:1144
#define OPTICAL_DEVICE
Definition: cdrw_hw.h:1151
#define READ_ONLY_DIRECT_ACCESS_DEVICE
Definition: cdrw_hw.h:1149
#define SEQUENTIAL_ACCESS_DEVICE
Definition: cdrw_hw.h:1145
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
#define MEDIUM_CHANGER
Definition: cdrw_hw.h:1152
#define INQUIRYDATABUFFERSIZE
Definition: cdrw_hw.h:1113
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
Definition: bufpool.h:45
_In_ PIRP Irp
Definition: csq.h:116
#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
@ 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
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:315
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:357
#define SRB_FLAGS_DATA_IN
Definition: srb.h:400
#define SRB_STATUS(Status)
Definition: srb.h:389
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:404
#define SRB_STATUS_SUCCESS
Definition: srb.h:341
#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 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 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
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
PKMT_RESULTBUFFER ResultBuffer
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)
#define UNICODE_NULL
#define ANSI_NULL
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
@ SynchronizationEvent
#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
BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1625
#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
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN _In_ PCDB Cdb
Definition: scratch.h:159
#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
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
UCHAR ProductId[16]
Definition: cdrw_hw.h:1133
UCHAR ProductRevisionLevel[4]
Definition: cdrw_hw.h:1134
UCHAR VendorId[8]
Definition: cdrw_hw.h:1132
UCHAR DeviceType
Definition: cdrw_hw.h:1116
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
COMMON_DEVICE_EXTENSION Common
Definition: pci.h:59
ULONG TimeOutValue
Definition: srb.h:262
UCHAR SenseInfoBufferLength
Definition: srb.h:259
PVOID DataBuffer
Definition: srb.h:263
UCHAR CdbLength
Definition: srb.h:258
UCHAR Cdb[16]
Definition: srb.h:279
PVOID SenseInfoBuffer
Definition: srb.h:264
UCHAR Function
Definition: srb.h:250
ULONG DataTransferLength
Definition: srb.h:261
ULONG SrbFlags
Definition: srb.h:260
USHORT Length
Definition: srb.h:249
UCHAR SrbStatus
Definition: srb.h:251
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#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
struct _CDB::_CDB6GENERIC CDB6GENERIC
struct _CDB::_CDB6INQUIRY CDB6INQUIRY
struct _USB_COMMON_DESCRIPTOR USB_COMMON_DESCRIPTOR
NTSTATUS USBSTOR_PdoHandleQueryInstanceId(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: pdo.c:434
static NTSTATUS USBSTOR_FillInquiryData(IN PDEVICE_OBJECT PDODeviceObject)
Definition: pdo.c:824
static NTSTATUS USBSTOR_SendInternalCdb(IN PDEVICE_OBJECT PdoDevice, IN PCDB Cdb, IN UCHAR CdbLength, IN ULONG TimeOutValue, OUT PVOID OutDataBuffer, OUT PULONG OutDataTransferLength)
Definition: pdo.c:690
static ULONG CopyFieldTruncate(IN PUCHAR Name, IN PCHAR Buffer, IN ULONG MaxLength)
Definition: pdo.c:96
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 NTAPI USBSTOR_SyncCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Ctx)
Definition: pdo.c:673
NTSTATUS USBSTOR_PdoHandleQueryDeviceText(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pdo.c:125
_In_ ULONG TotalLength
Definition: usbdlib.h:158
#define USB_STOR_TAG
Definition: usbstor.h:11
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING DeviceDescription
Definition: wdfpdo.h:432
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
@ 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
#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
@ DeviceTextLocationInformation
Definition: iotypes.h:2946
@ 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