}
//
- // FIXME: scan string descriptors
+ // check if there is a serial number provided
//
+ if (DeviceExtension->DeviceDescriptor->iSerialNumber)
+ {
+ //
+ // get serial number
+ //
+ Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_STRING_DESCRIPTOR_TYPE, 100 * sizeof(WCHAR), DeviceExtension->DeviceDescriptor->iSerialNumber, 0x0409, (PVOID*)&DeviceExtension->SerialNumber);
+ if (!NT_SUCCESS(Status))
+ {
+ //
+ // failed to get serial number descriptor, free device descriptor
+ //
+ FreeItem(DeviceExtension->DeviceDescriptor);
+ DeviceExtension->DeviceDescriptor = NULL;
+
+ //
+ // free configuration descriptor
+ //
+ FreeItem(DeviceExtension->ConfigurationDescriptor);
+ DeviceExtension->ConfigurationDescriptor = NULL;
+
+ //
+ // set serial number to zero
+ //
+ DeviceExtension->SerialNumber = NULL;
+ return Status;
+ }
+ }
+
return Status;
}
PSTORAGE_PROPERTY_QUERY PropertyQuery;
PSTORAGE_DESCRIPTOR_HEADER DescriptorHeader;
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor;
- ULONG FieldLengthVendor, FieldLengthProduct, FieldLengthRevision, TotalLength;
+ ULONG FieldLengthVendor, FieldLengthProduct, FieldLengthRevision, TotalLength, FieldLengthSerialNumber;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PUFI_INQUIRY_RESPONSE InquiryData;
PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor;
PUCHAR Buffer;
+ PFDO_DEVICE_EXTENSION FDODeviceExtension;
+ UNICODE_STRING SerialNumber;
+ ANSI_STRING AnsiString;
+ NTSTATUS Status;
DPRINT1("USBSTOR_HandleQueryProperty\n");
//
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
ASSERT(PDODeviceExtension);
+ ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
+
+ //
+ // get device extension
+ //
+ FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
+ ASSERT(FDODeviceExtension);
+ ASSERT(FDODeviceExtension->Common.IsFDO);
//
// get inquiry data
FieldLengthRevision = USBSTOR_GetFieldLength(InquiryData->Revision, 4);
//
- // FIXME handle serial number
+ // is there a serial number
//
+ if (FDODeviceExtension->SerialNumber)
+ {
+ //
+ // get length
+ //
+ FieldLengthSerialNumber = wcslen(FDODeviceExtension->SerialNumber->bString);
+ }
+ else
+ {
+ //
+ // no serial number
+ //
+ FieldLengthSerialNumber = 0;
+ }
//
- // total length required is sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLength + 3 extra null bytes - 1
+ // total length required is sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLength + 4 extra null bytes - 1
// -1 due STORAGE_DEVICE_DESCRIPTOR contains one byte length of parameter data
//
- TotalLength = sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + 2;
+ TotalLength = sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3;
//
// check if output buffer is long enough
DeviceDescriptor->VendorIdOffset = sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR);
DeviceDescriptor->ProductIdOffset = DeviceDescriptor->VendorIdOffset + FieldLengthVendor + 1;
DeviceDescriptor->ProductRevisionOffset = DeviceDescriptor->ProductIdOffset + FieldLengthProduct + 1;
- DeviceDescriptor->SerialNumberOffset = 0; //FIXME
- DeviceDescriptor->RawPropertiesLength = FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + 3;
+ DeviceDescriptor->SerialNumberOffset = (FieldLengthSerialNumber > 0 ? DeviceDescriptor->ProductRevisionOffset + FieldLengthRevision + 1 : 0);
+ DeviceDescriptor->RawPropertiesLength = FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3 + (FieldLengthSerialNumber > 0 ? + 1 : 0);
//
// copy descriptors
Buffer += FieldLengthRevision + 1;
//
- // TODO: copy revision
+ // copy serial number
//
+ if (FieldLengthSerialNumber)
+ {
+ //
+ // init unicode string
+ //
+ RtlInitUnicodeString(&SerialNumber, FDODeviceExtension->SerialNumber->bString);
+
+ //
+ // init ansi string
+ //
+ AnsiString.Buffer = (PCHAR)Buffer;
+ AnsiString.Length = 0;
+ AnsiString.MaximumLength = FieldLengthSerialNumber * sizeof(WCHAR);
+
+ //
+ // convert to ansi code
+ //
+ Status = RtlUnicodeStringToAnsiString(&AnsiString, &SerialNumber, FALSE);
+ ASSERT(Status == STATUS_SUCCESS);
+ }
+
DPRINT("Vendor %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->VendorIdOffset));
DPRINT("Product %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductIdOffset));
DPRINT("Revision %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductRevisionOffset));
+ DPRINT("Serial %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->SerialNumberOffset));
//
// done
IN OUT PIRP Irp)
{
PPDO_DEVICE_EXTENSION PDODeviceExtension;
+ PFDO_DEVICE_EXTENSION FDODeviceExtension;
WCHAR Buffer[100];
ULONG Length;
LPWSTR InstanceId;
//
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ //
+ // get FDO device extension
+ //
+ FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
+
//
// format instance id
- // FIXME: retrieve serial number from string device descriptor
//
- swprintf(Buffer, L"%s&%d", L"09188212515A", PDODeviceExtension->LUN);
+ if (FDODeviceExtension->SerialNumber)
+ {
+ //
+ // using serial number from device
+ //
+ swprintf(Buffer, L"%s&%d", FDODeviceExtension->SerialNumber->bString, PDODeviceExtension->LUN);
+ }
+ else
+ {
+ //
+ // FIXME: should use some random value
+ //
+ swprintf(Buffer, L"%s&%d", L"00000000", PDODeviceExtension->LUN);
+ }
//
// calculate length
//
// if list is freezed, dont start this packet
//
- DPRINT1("IrpListFreeze: %lu IrpPendingCount %lu\n", IrpListFreeze, FDODeviceExtension->IrpPendingCount);
+ DPRINT("IrpListFreeze: %lu IrpPendingCount %lu\n", IrpListFreeze, FDODeviceExtension->IrpPendingCount);
return (IrpListFreeze || SrbProcessing);
}
NTSTATUS Status;
BOOLEAN ResetInProgress;
- DPRINT1("USBSTOR_StartIo\n");
+ DPRINT("USBSTOR_StartIo\n");
//
// get FDO device extension
PREAD_CAPACITY_DATA CapacityData;
PUFI_CAPACITY_RESPONSE Response;
- DPRINT1("USBSTOR_CSWCompletionRoutine Irp %p Ctx %p\n", Irp, Ctx);
+ DPRINT("USBSTOR_CSWCompletionRoutine Irp %p Ctx %p\n", Irp, Ctx);
//
// access context
PIRP_CONTEXT Context;
PIO_STACK_LOCATION IoStack;
- DPRINT1("USBSTOR_DataCompletionRoutine Irp %p Ctx %p\n", Irp, Ctx);
+ DPRINT("USBSTOR_DataCompletionRoutine Irp %p Ctx %p\n", Irp, Ctx);
//
// access context
UCHAR Code;
USBD_PIPE_HANDLE PipeHandle;
- DPRINT1("USBSTOR_CBWCompletionRoutine Irp %p Ctx %p\n", Irp, Ctx);
+ DPRINT("USBSTOR_CBWCompletionRoutine Irp %p Ctx %p\n", Irp, Ctx);
//
// access context
Cmd.LogicalBlockByte2 = pCDB->CDB10.LogicalBlockByte2;
Cmd.LogicalBlockByte3 = pCDB->CDB10.LogicalBlockByte3;
- DPRINT1("USBSTOR_SendReadWriteCmd BlockAddress %x%x%x%x BlockCount %lu BlockLength %lu\n", Cmd.LogicalBlockByte0, Cmd.LogicalBlockByte1, Cmd.LogicalBlockByte2, Cmd.LogicalBlockByte3, BlockCount, PDODeviceExtension->BlockLength);
+ DPRINT("USBSTOR_SendReadWriteCmd BlockAddress %x%x%x%x BlockCount %lu BlockLength %lu\n", Cmd.LogicalBlockByte0, Cmd.LogicalBlockByte1, Cmd.LogicalBlockByte2, Cmd.LogicalBlockByte3, BlockCount, PDODeviceExtension->BlockLength);
//
// send request
//
pCDB = (PCDB)Request->Cdb;
- DPRINT1("USBSTOR_HandleExecuteSCSI Operation Code %x\n", pCDB->AsByte[0]);
+ DPRINT("USBSTOR_HandleExecuteSCSI Operation Code %x\n", pCDB->AsByte[0]);
if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY)
{
//
ASSERT(Request->DataBuffer);
- DPRINT1("SCSIOP_READ_CAPACITY Length %\n", Request->DataTransferLength);
+ DPRINT("SCSIOP_READ_CAPACITY Length %\n", Request->DataTransferLength);
Status = USBSTOR_SendCapacityCmd(DeviceObject, Irp);
}
else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_MODE_SENSE)
}
else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_READ || pCDB->MODE_SENSE.OperationCode == SCSIOP_WRITE)
{
- DPRINT1("SCSIOP_READ / SCSIOP_WRITE DataTransferLength %lu\n", Request->DataTransferLength);
+ DPRINT("SCSIOP_READ / SCSIOP_WRITE DataTransferLength %lu\n", Request->DataTransferLength);
//
// send read / write command
}
else if (pCDB->AsByte[0] == SCSIOP_MEDIUM_REMOVAL)
{
- DPRINT1("SCSIOP_MEDIUM_REMOVAL\n");
+ DPRINT("SCSIOP_MEDIUM_REMOVAL\n");
//
// just complete the request
}
else if (pCDB->MODE_SENSE.OperationCode == SCSIOP_TEST_UNIT_READY)
{
- DPRINT1("SCSIOP_TEST_UNIT_READY\n");
+ DPRINT("SCSIOP_TEST_UNIT_READY\n");
//
// send test unit command
//
// function always succeeds ;)
//
- DPRINT1("USBSTOR_DispatchScsi\n");
+ DPRINT("USBSTOR_DispatchClose\n");
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
USB_BUS_INTERFACE_USBDI_V2 BusInterface; // bus interface of device
PUSB_DEVICE_DESCRIPTOR DeviceDescriptor; // usb device descriptor
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor; // usb configuration descriptor
+ PUSB_STRING_DESCRIPTOR SerialNumber; // usb serial number
PUSBD_INTERFACE_INFORMATION InterfaceInformation; // usb interface information
USBD_CONFIGURATION_HANDLE ConfigurationHandle; // usb configuration handle
UCHAR BulkInPipeIndex; // bulk in pipe index
ULONG LastLogicBlockAddress; // last block address
}PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
-
-
-
//
// max lun command identifier
//