ReactOS  0.4.14-dev-115-g4576127
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 
18 LPCSTR
20  IN PINQUIRYDATA InquiryData,
21  IN UCHAR IsFloppy)
22 {
23  if (InquiryData->DeviceType == 0)
24  {
25  if (IsFloppy)
26  {
27  // floppy device
28  return "SFloppy";
29  }
30 
31  // direct access device
32  return "Disk";
33  }
34 
35  switch (InquiryData->DeviceType)
36  {
37  case 1:
38  {
39  // sequential device, i.e magnetic tape
40  return "Sequential";
41  }
42  case 4:
43  {
44  // write once device
45  return "Worm";
46  }
47  case 5:
48  {
49  // CDROM device
50  return "CdRom";
51  }
52  case 7:
53  {
54  // optical memory device
55  return "Optical";
56  }
57  case 8:
58  {
59  // medium change device
60  return "Changer";
61  }
62  default:
63  {
64  // other device
65  return "Other";
66  }
67  }
68 }
69 
70 LPCSTR
72  IN PINQUIRYDATA InquiryData,
73  IN UCHAR IsFloppy)
74 {
75  if (InquiryData->DeviceType == 0)
76  {
77  if (IsFloppy)
78  {
79  // floppy device
80  return "GenSFloppy";
81  }
82 
83  // direct access device
84  return "GenDisk";
85  }
86 
87  switch (InquiryData->DeviceType)
88  {
89  case 1:
90  {
91  // sequential device, i.e magnetic tape
92  return "GenSequential";
93  }
94  case 4:
95  {
96  // write once device
97  return "GenWorm";
98  }
99  case 5:
100  {
101  // CDROM device
102  return "GenCdRom";
103  }
104  case 7:
105  {
106  // optical memory device
107  return "GenOptical";
108  }
109  case 8:
110  {
111  // medium change device
112  return "GenChanger";
113  }
114  default:
115  {
116  // other device
117  return "UsbstorOther";
118  }
119  }
120 }
121 
122 static
123 ULONG
125  IN PUCHAR Name,
126  IN PCHAR Buffer,
127  IN ULONG MaxLength)
128 {
129  ULONG Index;
130 
131  for (Index = 0; Index < MaxLength; Index++)
132  {
133  if (Name[Index] <= ' ' || Name[Index] >= 0x7F /* last printable ascii character */ || Name[Index] == ',')
134  {
135  // convert to underscore
136  Buffer[Index] = '_';
137  }
138  else
139  {
140  // just copy character
141  Buffer[Index] = Name[Index];
142  }
143  }
144 
145  return MaxLength;
146 }
147 
148 static
149 ULONG
151  IN PUCHAR Name,
152  IN PCHAR Buffer,
153  IN ULONG MaxLength)
154 {
155  ULONG Index;
156 
157  for (Index = 0; Index < MaxLength; Index++)
158  {
159  if (Name[Index] == '\0')
160  {
161  break;
162  }
163  else if (Name[Index] <= ' ' || Name[Index] >= 0x7F /* last printable ascii character */ || Name[Index] == ',')
164  {
165  // convert to underscore
166  Buffer[Index] = ' ';
167  }
168  else
169  {
170  // just copy character
171  Buffer[Index] = Name[Index];
172  }
173  }
174 
175  return Index;
176 }
177 
178 NTSTATUS
181  IN PIRP Irp)
182 {
183  PPDO_DEVICE_EXTENSION DeviceExtension;
184  PIO_STACK_LOCATION IoStack;
185  CHAR LocalBuffer[26];
186  UINT32 Offset = 0;
187  PINQUIRYDATA InquiryData;
190 
192 
194  ASSERT(DeviceExtension->InquiryData);
195  InquiryData = DeviceExtension->InquiryData;
196 
197  switch (IoStack->Parameters.QueryDeviceText.DeviceTextType)
198  {
201  {
202  DPRINT("USBSTOR_PdoHandleQueryDeviceText\n");
203 
204  Offset += CopyFieldTruncate(InquiryData->VendorId, &LocalBuffer[Offset], sizeof(InquiryData->VendorId));
205  LocalBuffer[Offset++] = ' ';
206  Offset += CopyFieldTruncate(InquiryData->ProductId, &LocalBuffer[Offset], sizeof(InquiryData->ProductId));
207  LocalBuffer[Offset++] = '\0';
208 
209  RtlInitAnsiString(&AnsiString, (PCSZ)&LocalBuffer);
210 
211  DeviceDescription.Length = 0;
214  if (!DeviceDescription.Buffer)
215  {
216  Irp->IoStatus.Information = 0;
218  }
219 
221 
222  Irp->IoStatus.Information = (ULONG_PTR)DeviceDescription.Buffer;
223  return STATUS_SUCCESS;
224  }
225  default:
226  {
227  Irp->IoStatus.Information = 0;
228  return Irp->IoStatus.Status;
229  }
230  }
231 }
232 
233 NTSTATUS
236  IN PIRP Irp)
237 {
238  PPDO_DEVICE_EXTENSION DeviceExtension;
240  CHAR Buffer[100] = {0};
242  ULONG Offset = 0;
243  PINQUIRYDATA InquiryData;
245  UNICODE_STRING DeviceId;
246 
248  ASSERT(DeviceExtension->InquiryData);
249  InquiryData = DeviceExtension->InquiryData;
250 
251  DeviceType = USBSTOR_GetDeviceType(InquiryData, DeviceExtension->IsFloppy);
252 
253  // lets create device string
254  Offset = sprintf(&Buffer[Offset], "USBSTOR\\");
256  Offset += sprintf(&Buffer[Offset], "&Ven_");
257  Offset += CopyField(InquiryData->VendorId, &Buffer[Offset], 8);
258  Offset += sprintf(&Buffer[Offset], "&Prod_");
259  Offset += CopyField(InquiryData->ProductId, &Buffer[Offset], 16);
260  Offset += sprintf(&Buffer[Offset], "&Rev_");
261  Offset += CopyField(InquiryData->ProductRevisionLevel, &Buffer[Offset], 4);
262 
264 
265  // allocate DeviceId string
266  DeviceId.Length = 0;
267  DeviceId.MaximumLength = (USHORT)((strlen((PCHAR)Buffer) + 1) * sizeof(WCHAR));
268  DeviceId.Buffer = (LPWSTR)AllocateItem(PagedPool, DeviceId.MaximumLength);
269  if (!DeviceId.Buffer)
270  {
271  Irp->IoStatus.Information = 0;
273  }
274 
276 
277  if (NT_SUCCESS(Status))
278  {
279  Irp->IoStatus.Information = (ULONG_PTR)DeviceId.Buffer;
280  }
281 
282  DPRINT("DeviceId %wZ Status %x\n", &DeviceId, Status);
283 
284  return Status;
285 }
286 
287 VOID
289  IN CHAR * Buffer,
290  IN ULONG ResultBufferLength,
291  IN ULONG ResultBufferOffset,
293  OUT PULONG NewResultBufferOffset)
294 {
295  UNICODE_STRING DeviceString;
298 
299  ASSERT(ResultBufferLength);
300  ASSERT(ResultBufferLength > ResultBufferOffset);
301 
302  DPRINT("ResultBufferOffset %lu ResultBufferLength %lu Buffer %s Length %lu\n", ResultBufferOffset, ResultBufferLength, Buffer, strlen(Buffer));
303 
304  // construct destination string
305  DeviceString.Buffer = &ResultBuffer[ResultBufferOffset];
306  DeviceString.Length = 0;
307  DeviceString.MaximumLength = (ResultBufferLength - ResultBufferOffset) * sizeof(WCHAR);
308 
309  // initialize source string
311 
314 
315  // subtract consumed bytes
316  ResultBufferLength -= (DeviceString.Length + sizeof(WCHAR)) / sizeof(WCHAR);
317  ResultBufferOffset += (DeviceString.Length + sizeof(WCHAR)) / sizeof(WCHAR);
318 
319  *NewResultBufferOffset = ResultBufferOffset;
320 }
321 
322 NTSTATUS
325  IN OUT PIRP Irp)
326 {
327  PPDO_DEVICE_EXTENSION PDODeviceExtension;
328  PFDO_DEVICE_EXTENSION FDODeviceExtension;
329  LPCSTR GenericType, DeviceType;
330  LPWSTR Buffer;
331  CHAR Id1[50], Id2[50], Id3[50], Id4[50], Id5[50], Id6[50];
332  ULONG Id1Length, Id2Length, Id3Length, Id4Length, Id5Length,Id6Length;
334  PINQUIRYDATA InquiryData;
335 
336  PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
337  FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
338  ASSERT(FDODeviceExtension->DeviceDescriptor);
339  InquiryData = PDODeviceExtension->InquiryData;
340 
341  DeviceType = USBSTOR_GetDeviceType(InquiryData, PDODeviceExtension->IsFloppy);
342  GenericType = USBSTOR_GetGenericType(InquiryData, PDODeviceExtension->IsFloppy);
343 
344  ASSERT(GenericType);
345 
346  // generate id 1
347  // USBSTOR\SCSIType_VendorId(8)_ProductId(16)_Revision(4)
348  RtlZeroMemory(Id1, sizeof(Id1));
349  Offset = 0;
350  Offset = sprintf(&Id1[Offset], "USBSTOR\\");
351  Offset += sprintf(&Id1[Offset], DeviceType);
352  Offset += CopyField(InquiryData->VendorId, &Id1[Offset], 8);
353  Offset += CopyField(InquiryData->ProductId, &Id1[Offset], 16);
354  Offset += CopyField(InquiryData->ProductRevisionLevel, &Id1[Offset], 4);
355  Id1Length = strlen(Id1) + 1;
356  DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId1 %s\n", Id1);
357 
358  // generate id 2
359  // USBSTOR\SCSIType_VendorId(8)_ProductId(16)
360  RtlZeroMemory(Id2, sizeof(Id2));
361  Offset = 0;
362  Offset = sprintf(&Id2[Offset], "USBSTOR\\");
363  Offset += sprintf(&Id2[Offset], DeviceType);
364  Offset += CopyField(InquiryData->VendorId, &Id2[Offset], 8);
365  Offset += CopyField(InquiryData->ProductId, &Id2[Offset], 16);
366  Id2Length = strlen(Id2) + 1;
367  DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId2 %s\n", Id2);
368 
369  // generate id 3
370  // USBSTOR\SCSIType_VendorId(8)
371  RtlZeroMemory(Id3, sizeof(Id3));
372  Offset = 0;
373  Offset = sprintf(&Id3[Offset], "USBSTOR\\");
374  Offset += sprintf(&Id3[Offset], DeviceType);
375  Offset += CopyField(InquiryData->VendorId, &Id3[Offset], 8);
376  Id3Length = strlen(Id3) + 1;
377  DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId3 %s\n", Id3);
378 
379  // generate id 4
380  // USBSTOR\SCSIType_VendorId(8)_ProductId(16)_Revision(1)
381  RtlZeroMemory(Id4, sizeof(Id4));
382  Offset = 0;
383  Offset = sprintf(&Id4[Offset], "USBSTOR\\");
384  Offset += sprintf(&Id4[Offset], DeviceType);
385  Offset += CopyField(InquiryData->VendorId, &Id4[Offset], 8);
386  Offset += CopyField(InquiryData->ProductId, &Id4[Offset], 16);
387  Offset += CopyField(InquiryData->ProductRevisionLevel, &Id4[Offset], 1);
388  Id4Length = strlen(Id4) + 1;
389  DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId4 %s\n", Id4);
390 
391  // generate id 5
392  // USBSTOR\SCSIType
393  RtlZeroMemory(Id5, sizeof(Id5));
394  Offset = 0;
395  Offset = sprintf(&Id5[Offset], "USBSTOR\\");
396  Offset += sprintf(&Id5[Offset], GenericType);
397  Id5Length = strlen(Id5) + 1;
398  DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId5 %s\n", Id5);
399 
400  // generate id 6
401  // SCSIType
402  RtlZeroMemory(Id6, sizeof(Id6));
403  Offset = 0;
404  Offset = sprintf(&Id6[Offset], GenericType);
405  Id6Length = strlen(Id6) + 1;
406  DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId6 %s\n", Id6);
407 
408  TotalLength = Id1Length + Id2Length + Id3Length + Id4Length + Id5Length + Id6Length + 1;
409 
411  if (!Buffer)
412  {
413  Irp->IoStatus.Information = 0;
415  }
416 
417  // reset offset
418  Offset = 0;
420 
427 
428  ASSERT(Offset + 1 == Length);
429 
430  Irp->IoStatus.Information = (ULONG_PTR)Buffer;
431  return STATUS_SUCCESS;
432 }
433 
434 NTSTATUS
437  IN OUT PIRP Irp)
438 {
439  PPDO_DEVICE_EXTENSION PDODeviceExtension;
440  PFDO_DEVICE_EXTENSION FDODeviceExtension;
441  CHAR Buffer[100] = {0};
445 
446  PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
447  FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
448  ASSERT(FDODeviceExtension->DeviceDescriptor);
449  DeviceType = USBSTOR_GetDeviceType(PDODeviceExtension->InquiryData, PDODeviceExtension->IsFloppy);
450 
451  // format instance id
452  Length = sprintf(Buffer, "USBSTOR\\%s", DeviceType) + 1;
453  Length += sprintf(&Buffer[Length], "USBSTOR\\%s", "RAW") + 2;
454 
456  if (!InstanceId)
457  {
458  Irp->IoStatus.Information = 0;
460  }
461 
464 
465  DPRINT("USBSTOR_PdoHandleQueryCompatibleId %S\n", InstanceId);
466 
467  Irp->IoStatus.Information = (ULONG_PTR)InstanceId;
468  return STATUS_SUCCESS;
469 }
470 
471 NTSTATUS
474  IN OUT PIRP Irp)
475 {
476  PPDO_DEVICE_EXTENSION PDODeviceExtension;
477  PFDO_DEVICE_EXTENSION FDODeviceExtension;
478  WCHAR Buffer[100];
479  ULONG Length;
481 
482  PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
483  FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
484 
485  // format instance id
486  if (FDODeviceExtension->SerialNumber)
487  {
488  // using serial number from device
489  swprintf(Buffer, L"%s&%c", FDODeviceExtension->SerialNumber->bString, PDODeviceExtension->LUN);
490  }
491  else
492  {
493  // use instance count and LUN
494  swprintf(Buffer, L"%04lu&%c", FDODeviceExtension->InstanceCount, PDODeviceExtension->LUN);
495  }
496 
497  Length = wcslen(Buffer) + 1;
498 
500  if (!InstanceId)
501  {
502  Irp->IoStatus.Information = 0;
504  }
505 
507 
508  DPRINT("USBSTOR_PdoHandleQueryInstanceId %S\n", InstanceId);
509 
510  Irp->IoStatus.Information = (ULONG_PTR)InstanceId;
511  return STATUS_SUCCESS;
512 }
513 
514 NTSTATUS
517  IN OUT PIRP Irp)
518 {
519  PDEVICE_RELATIONS DeviceRelations;
520  PIO_STACK_LOCATION IoStack;
521 
522  DPRINT("USBSTOR_PdoHandleDeviceRelations\n");
523 
525 
526  // check if relation type is BusRelations
527  if (IoStack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
528  {
529  // PDO handles only target device relation
530  return Irp->IoStatus.Status;
531  }
532 
533  DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS));
534  if (!DeviceRelations)
535  {
537  }
538 
539  // initialize device relations
540  DeviceRelations->Count = 1;
541  DeviceRelations->Objects[0] = DeviceObject;
543 
544  Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
545  return STATUS_SUCCESS;
546 }
547 
548 NTSTATUS
551  IN OUT PIRP Irp)
552 {
553  PIO_STACK_LOCATION IoStack;
554  PPDO_DEVICE_EXTENSION DeviceExtension;
557  ULONG bDelete;
558 
561  ASSERT(DeviceExtension->Common.IsFDO == FALSE);
562 
563  switch(IoStack->MinorFunction)
564  {
566  {
568  break;
569  }
571  {
573  break;
574  }
575  case IRP_MN_QUERY_ID:
576  {
577  if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID)
578  {
580  break;
581  }
582  else if (IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs)
583  {
585  break;
586  }
587  else if (IoStack->Parameters.QueryId.IdType == BusQueryInstanceID)
588  {
590  break;
591  }
592  else if (IoStack->Parameters.QueryId.IdType == BusQueryCompatibleIDs)
593  {
595  break;
596  }
597 
598  DPRINT1("USBSTOR_PdoHandlePnp: IRP_MN_QUERY_ID IdType %x unimplemented\n", IoStack->Parameters.QueryId.IdType);
600  Irp->IoStatus.Information = 0;
601  break;
602  }
604  {
605  DPRINT("IRP_MN_REMOVE_DEVICE\n");
606 
607  if(*DeviceExtension->PDODeviceObject != NULL)
608  {
609  *DeviceExtension->PDODeviceObject = NULL;
610  bDelete = TRUE;
611  }
612  else
613  {
614  // device object already marked for deletion
615  bDelete = FALSE;
616  }
617 
618  // clean up the device extension
619  ASSERT(DeviceExtension->InquiryData);
620  ExFreePoolWithTag(DeviceExtension->InquiryData, USB_STOR_TAG);
621 
622  Irp->IoStatus.Status = STATUS_SUCCESS;
624 
625  if (bDelete)
626  {
628  }
629  return STATUS_SUCCESS;
630  }
632  {
633  // just forward irp to lower device
634  Status = USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp);
636 
637  if (NT_SUCCESS(Status))
638  {
639  // check if no unique id
640  Caps = (PDEVICE_CAPABILITIES)IoStack->Parameters.DeviceCapabilities.Capabilities;
641  Caps->UniqueID = FALSE; // no unique id is supported
642  Caps->Removable = TRUE; //FIXME
643  }
644  break;
645  }
648  {
649 #if 0
650  //
651  // if we're not claimed it's ok
652  //
653  if (DeviceExtension->Claimed)
654 #else
655  if (TRUE)
656 #endif
657  {
659  DPRINT1("[USBSTOR] Request %x fails because device is still claimed\n", IoStack->MinorFunction);
660  }
661  else
663  break;
664  }
665  case IRP_MN_START_DEVICE:
666  {
667  // no-op for PDO
669  break;
670  }
672  {
674  break;
675  }
676  default:
677  {
678  // do nothing
679  Status = Irp->IoStatus.Status;
680  }
681  }
682 
683  if (Status != STATUS_PENDING)
684  {
685  Irp->IoStatus.Status = Status;
687  }
688 
689  return Status;
690 }
691 
692 NTSTATUS
693 NTAPI
696  IN PIRP Irp,
697  IN PVOID Ctx)
698 {
701 }
702 
703 /*
704 * @name USBSTOR_SendInternalCdb
705 *
706 * Issues an internal SCSI request to device.
707 * The request is sent in a synchronous way.
708 */
709 static
710 NTSTATUS
712  IN PDEVICE_OBJECT PdoDevice,
713  IN PCDB Cdb,
714  IN UCHAR CdbLength,
715  IN ULONG TimeOutValue,
716  OUT PVOID OutDataBuffer,
717  OUT PULONG OutDataTransferLength)
718 {
720  PSENSE_DATA SenseBuffer;
721  PIO_STACK_LOCATION IoStack;
722  KEVENT Event;
723  PIRP Irp = NULL;
724  PMDL Mdl = NULL;
725  ULONG ix = 0;
727  UCHAR SrbStatus;
728 
729  DPRINT("USBSTOR_SendInternalCdb SCSIOP %x\n", Cdb->CDB6GENERIC.OperationCode);
730 
732  sizeof(SCSI_REQUEST_BLOCK),
733  USB_STOR_TAG);
734 
735  if (Srb)
736  {
737  SenseBuffer = ExAllocatePoolWithTag(NonPagedPool,
739  USB_STOR_TAG);
740 
741  if (SenseBuffer)
742  {
743  Mdl = IoAllocateMdl(OutDataBuffer,
744  *OutDataTransferLength,
745  FALSE,
746  FALSE,
747  NULL);
748 
749  if (!Mdl)
750  {
751  ExFreePoolWithTag(SenseBuffer, USB_STOR_TAG);
753  return Status;
754  }
755 
757 
758  // make 3 attempts - the device may be in STALL state after the first one
759  do
760  {
761  Irp = IoAllocateIrp(PdoDevice->StackSize, FALSE);
762 
763  if (!Irp)
764  {
765  break;
766  }
767 
768  IoStack = IoGetNextIrpStackLocation(Irp);
770  IoStack->Parameters.Scsi.Srb = Srb;
771 
773 
774  Srb->Length = sizeof(SCSI_REQUEST_BLOCK);
775  Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
776  Srb->CdbLength = CdbLength;
777  Srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
779  Srb->DataTransferLength = *OutDataTransferLength;
780  Srb->TimeOutValue = TimeOutValue;
781  Srb->DataBuffer = OutDataBuffer;
782  Srb->SenseInfoBuffer = SenseBuffer;
783 
784  RtlCopyMemory(Srb->Cdb, Cdb, CdbLength);
785 
786  Irp->MdlAddress = Mdl;
787 
789 
792  &Event,
793  TRUE,
794  TRUE,
795  TRUE);
796 
797  if (IoCallDriver(PdoDevice, Irp) == STATUS_PENDING)
798  {
800  Executive,
801  KernelMode,
802  FALSE,
803  NULL);
804  }
805 
806  SrbStatus = SRB_STATUS(Srb->SrbStatus);
807 
808  IoFreeIrp(Irp);
809  Irp = NULL;
810 
811  if (SrbStatus == SRB_STATUS_SUCCESS ||
812  SrbStatus == SRB_STATUS_DATA_OVERRUN)
813  {
815  *OutDataTransferLength = Srb->DataTransferLength;
816  break;
817  }
818 
820 
821  ++ix;
822  } while (ix < 3);
823 
824  if (Mdl)
825  {
826  IoFreeMdl(Mdl);
827  }
828 
829  ExFreePoolWithTag(SenseBuffer, USB_STOR_TAG);
830  }
831 
833  }
834 
835  return Status;
836 }
837 
838 /*
839 * @name USBSTOR_FillInquiryData
840 *
841 * Sends a SCSI Inquiry request and fills in the PDODeviceExtension->InquiryData field with a result.
842 */
843 static
844 NTSTATUS
846  IN PDEVICE_OBJECT PDODeviceObject)
847 {
849  PPDO_DEVICE_EXTENSION PDODeviceExtension;
850  CDB Cdb;
851  ULONG DataTransferLength = INQUIRYDATABUFFERSIZE;
852  PINQUIRYDATA InquiryData;
853 
854  PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension;
856 
857  if (!InquiryData)
858  {
859  DPRINT1("USBSTOR_FillInquiryData failed with %x\n", Status);
860  return Status;
861  }
862 
863  RtlZeroMemory(&Cdb, sizeof(Cdb));
864  Cdb.CDB6INQUIRY.OperationCode = SCSIOP_INQUIRY;
865  Cdb.CDB6INQUIRY.AllocationLength = INQUIRYDATABUFFERSIZE;
866 
867  Status = USBSTOR_SendInternalCdb(PDODeviceObject, &Cdb, CDB6GENERIC_LENGTH, 20, InquiryData, &DataTransferLength);
868 
869  if (!NT_SUCCESS(Status))
870  {
871  DPRINT1("USBSTOR_FillInquiryData failed with %x\n", Status);
872  ExFreePoolWithTag(InquiryData, USB_STOR_TAG);
873  return Status;
874  }
875 
876  DPRINT("DeviceType %x\n", InquiryData->DeviceType);
877  DPRINT("DeviceTypeModifier %x\n", InquiryData->DeviceTypeModifier);
878  DPRINT("RemovableMedia %x\n", InquiryData->RemovableMedia);
879  DPRINT("Version %x\n", InquiryData->Versions);
880  DPRINT("Format %x\n", InquiryData->ResponseDataFormat);
881  DPRINT("Length %x\n", InquiryData->AdditionalLength);
882  DPRINT("Reserved %p\n", InquiryData->Reserved);
883  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]);
884  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],
885  InquiryData->ProductId[4], InquiryData->ProductId[5], InquiryData->ProductId[6], InquiryData->ProductId[7],
886  InquiryData->ProductId[8], InquiryData->ProductId[9], InquiryData->ProductId[10], InquiryData->ProductId[11],
887  InquiryData->ProductId[12], InquiryData->ProductId[13], InquiryData->ProductId[14], InquiryData->ProductId[15]);
888 
889  DPRINT("Revision %c%c%c%c\n", InquiryData->ProductRevisionLevel[0], InquiryData->ProductRevisionLevel[1], InquiryData->ProductRevisionLevel[2], InquiryData->ProductRevisionLevel[3]);
890 
891  PDODeviceExtension->InquiryData = InquiryData;
892  return Status;
893 }
894 
895 NTSTATUS
898  IN UCHAR LUN)
899 {
900  PDEVICE_OBJECT PDO;
902  PPDO_DEVICE_EXTENSION PDODeviceExtension;
903  PFDO_DEVICE_EXTENSION FDODeviceExtension;
904 
905  FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
906 
907  // create child device object
909  if (!NT_SUCCESS(Status))
910  {
911  DPRINT1("Failed to create PDO, status %x\n", Status);
912  return Status;
913  }
914 
915  // patch the stack size
917 
918  PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDO->DeviceExtension;
919 
920  // initialize device extension
921  RtlZeroMemory(PDODeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
922  PDODeviceExtension->Common.IsFDO = FALSE;
923  PDODeviceExtension->LowerDeviceObject = DeviceObject;
924  PDODeviceExtension->PDODeviceObject = &FDODeviceExtension->ChildPDO[LUN];
925  PDODeviceExtension->Self = PDO;
926  PDODeviceExtension->LUN = LUN;
927 
928  PDO->Flags |= DO_DIRECT_IO;
929 
930  // device is initialized
931  PDO->Flags &= ~DO_DEVICE_INITIALIZING;
932 
933  // output device object
934  FDODeviceExtension->ChildPDO[LUN] = PDO;
935 
936  // send inquiry command by irp
938 
939  if (!NT_SUCCESS(Status))
940  {
941  return Status;
942  }
943 
944  if (PDODeviceExtension->InquiryData->DeviceType == DIRECT_ACCESS_DEVICE || PDODeviceExtension->InquiryData->DeviceType == READ_ONLY_DIRECT_ACCESS_DEVICE)
945  {
946  PDODeviceExtension->IsFloppy = FALSE; // TODO: implement the actual check
947  }
948  else
949  {
950  // we work only with DIRECT_ACCESS_DEVICE for now
951  return STATUS_NOT_SUPPORTED;
952  }
953 
954  return Status;
955 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
signed char * PCHAR
Definition: retypes.h:7
CONST char * PCSZ
Definition: umtypes.h:125
#define IN
Definition: typedefs.h:38
#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
VOID USBSTOR_ConvertToUnicodeString(IN CHAR *Buffer, IN ULONG ResultBufferLength, IN ULONG ResultBufferOffset, OUT LPWSTR ResultBuffer, OUT PULONG NewResultBufferOffset)
Definition: pdo.c:288
UCHAR ProductRevisionLevel[4]
Definition: cdrw_hw.h:1134
NTSTATUS USBSTOR_PdoHandleDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: pdo.c:515
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
_In_ PIRP Irp
Definition: csq.h:116
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:396
UCHAR ResponseDataFormat
Definition: cdrw_hw.h:1121
DeviceType
Definition: mmdrv.h:41
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2055
unsigned char * PUCHAR
Definition: retypes.h:3
char CHAR
Definition: xmlstorage.h:175
static ULONG CopyField(IN PUCHAR Name, IN PCHAR Buffer, IN ULONG MaxLength)
Definition: pdo.c:124
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:428
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:30
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS USBSTOR_PdoHandleQueryDeviceText(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pdo.c:179
struct _PDO_DEVICE_EXTENSION * PPDO_DEVICE_EXTENSION
#define FILE_DEVICE_MASS_STORAGE
Definition: imports.h:62
UCHAR ProductId[16]
Definition: cdrw_hw.h:1133
UCHAR VendorId[8]
Definition: cdrw_hw.h:1132
_In_ ULONG TotalLength
Definition: usbdlib.h:145
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define SRB_STATUS(Status)
Definition: srb.h:381
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
struct _FDO_DEVICE_EXTENSION * PFDO_DEVICE_EXTENSION
LPCSTR USBSTOR_GetDeviceType(IN PINQUIRYDATA InquiryData, IN UCHAR IsFloppy)
Definition: pdo.c:19
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define sprintf(buf, format,...)
Definition: sprintf.c:55
NTSTATUS USBSTOR_PdoHandleQueryDeviceId(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pdo.c:234
UCHAR Reserved[2]
Definition: cdrw_hw.h:1123
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
unsigned int UINT32
#define IRP_MN_QUERY_REMOVE_DEVICE
LPCSTR USBSTOR_GetGenericType(IN PINQUIRYDATA InquiryData, IN UCHAR IsFloppy)
Definition: pdo.c:71
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
_Must_inspect_result_ _In_opt_ PVOID _In_opt_ PVOID InstanceId
Definition: fsrtlfuncs.h:907
UCHAR RemovableMedia
Definition: cdrw_hw.h:1119
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
PVOID DeviceExtension
Definition: env_spec_w32.h:418
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:711
smooth NULL
Definition: ftsmooth.c:416
#define INQUIRYDATABUFFERSIZE
Definition: cdrw_hw.h:1113
#define IoCompleteRequest
Definition: irp.c:1240
NTSTATUS NTAPI USBSTOR_SyncForwardIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: misc.c:34
NTSTATUS USBSTOR_PdoHandleQueryInstanceId(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: pdo.c:472
COMMON_DEVICE_EXTENSION Common
Definition: pci.h:55
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
const char * LPCSTR
Definition: xmlstorage.h:183
#define FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
#define IRP_MN_QUERY_STOP_DEVICE
#define SCSIOP_INQUIRY
Definition: cdrw_hw.h:888
#define DIRECT_ACCESS_DEVICE
Definition: cdrw_hw.h:1144
_Must_inspect_result_ _In_ PDEVICE_DESCRIPTION DeviceDescription
Definition: iofuncs.h:1015
static ULONG CopyFieldTruncate(IN PUCHAR Name, IN PCHAR Buffer, IN ULONG MaxLength)
Definition: pdo.c:150
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
#define CDB6GENERIC_LENGTH
Definition: cdrw_hw.h:830
NTSTATUS USBSTOR_PdoHandlePnp(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: pdo.c:549
__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
#define IRP_MN_QUERY_DEVICE_TEXT
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
UCHAR Versions
Definition: cdrw_hw.h:1120
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:349
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS USBSTOR_PdoHandleQueryCompatibleId(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: pdo.c:435
unsigned char UCHAR
Definition: xmlstorage.h:181
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
#define USB_STOR_TAG
Definition: usbstor.h:10
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
NTSTATUS USBSTOR_PdoHandleQueryHardwareId(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: pdo.c:323
UCHAR AdditionalLength
Definition: cdrw_hw.h:1122
UCHAR DeviceTypeModifier
Definition: cdrw_hw.h:1118
* PDEVICE_CAPABILITIES
Definition: iotypes.h:928
Status
Definition: gdiplustypes.h:24
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
UCHAR DeviceType
Definition: cdrw_hw.h:1116
__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
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
unsigned short USHORT
Definition: pedump.c:61
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define DPRINT1
Definition: precomp.h:8
#define READ_ONLY_DIRECT_ACCESS_DEVICE
Definition: cdrw_hw.h:1149
NTSTATUS USBSTOR_CreatePDO(IN PDEVICE_OBJECT DeviceObject, IN UCHAR LUN)
Definition: pdo.c:896
#define OUT
Definition: typedefs.h:39
#define ObReferenceObject
Definition: obfuncs.h:204
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
NTSTATUS NTAPI USBSTOR_SyncCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Ctx)
Definition: pdo.c:694
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
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
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
struct _CDB::_CDB6INQUIRY CDB6INQUIRY
static NTSTATUS USBSTOR_FillInquiryData(IN PDEVICE_OBJECT PDODeviceObject)
Definition: pdo.c:845
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
WCHAR * LPWSTR
Definition: xmlstorage.h:184
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2966
PKMT_RESULTBUFFER ResultBuffer
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define IRP_MN_QUERY_CAPABILITIES