Author: janderwald
Date: Wed May 4 12:33:01 2011
New Revision: 51575
URL:
http://svn.reactos.org/svn/reactos?rev=51575&view=rev
Log:
[USBSTOR]
- Don't free device descriptor if it failed to acquire it
- Don't move out of usb configuration array. Found by special pool
- Fix bug when storing interface information which lead to a overwrite
- Implement retrieving generic type for device
- Fix bugs in QueryDeviceId
- Implement querying hardware ids
- Implement querying instance ids
- With these changes, usbstor now initializes and create pdo, which is also enumerated
- Needs more code / fixes so that disk.sys attaches to usbstor
- WIP
Modified:
branches/usb-bringup/drivers/usb/usbstor/descriptor.c
branches/usb-bringup/drivers/usb/usbstor/misc.c
branches/usb-bringup/drivers/usb/usbstor/pdo.c
Modified: branches/usb-bringup/drivers/usb/usbstor/descriptor.c
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbstor/descriptor.c [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbstor/descriptor.c [iso-8859-1] Wed May 4 12:33:01
2011
@@ -115,7 +115,6 @@
//
// failed to get device descriptor
//
- FreeItem(DeviceExtension->DeviceDescriptor);
DeviceExtension->DeviceDescriptor = NULL;
return Status;
}
@@ -271,7 +270,7 @@
//
// was it the last descriptor
//
- if ((ULONG_PTR)CurrentDescriptor > ((ULONG_PTR)ConfigurationDescriptor +
ConfigurationDescriptor->wTotalLength))
+ if ((ULONG_PTR)CurrentDescriptor >= ((ULONG_PTR)ConfigurationDescriptor +
ConfigurationDescriptor->wTotalLength))
{
//
// reached last descriptor
@@ -433,7 +432,8 @@
//
// update configuration info
//
- RtlCopyMemory(DeviceExtension->InterfaceInformation,
&Urb->UrbSelectInterface.Interface,
Urb->UrbSelectConfiguration.Interface.Length);
+ ASSERT(Urb->UrbSelectInterface.Interface.Length ==
DeviceExtension->InterfaceInformation->Length);
+ RtlCopyMemory(DeviceExtension->InterfaceInformation,
&Urb->UrbSelectInterface.Interface, Urb->UrbSelectInterface.Interface.Length);
}
//
Modified: branches/usb-bringup/drivers/usb/usbstor/misc.c
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbstor/misc.c [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbstor/misc.c [iso-8859-1] Wed May 4 12:33:01 2011
@@ -203,6 +203,8 @@
IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
IoStack->Parameters.DeviceIoControl.IoControlCode =
IOCTL_INTERNAL_USB_SUBMIT_URB;
IoStack->Parameters.Others.Argument1 = (PVOID)UrbRequest;
+ IoStack->Parameters.DeviceIoControl.InputBufferLength =
UrbRequest->UrbHeader.Length;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
//
// setup completion routine
Modified: branches/usb-bringup/drivers/usb/usbstor/pdo.c
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbstor/pdo.c [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbstor/pdo.c [iso-8859-1] Wed May 4 12:33:01 2011
@@ -75,10 +75,80 @@
//
// other device
//
- return "CdRom";
- }
- }
-}
+ return "Other";
+ }
+ }
+}
+
+LPCWSTR
+USBSTOR_GetGenericType(
+ IN PUFI_INQUIRY_RESPONSE InquiryData)
+{
+ //
+ // check if device type is zero
+ //
+ if (InquiryData->DeviceType == 0)
+ {
+ //
+ // direct access device
+ //
+
+ //
+ // FIXME: check if floppy
+ //
+ return L"GenDisk";
+ }
+
+ //
+ // FIXME: use constant - derrived from
http://en.wikipedia.org/wiki/SCSI_Peripheral_Device_Type
+ //
+ switch (InquiryData->DeviceType)
+ {
+ case 1:
+ {
+ //
+ // sequential device, i.e magnetic tape
+ //
+ return L"GenSequential";
+ }
+ case 4:
+ {
+ //
+ // write once device
+ //
+ return L"GenWorm";
+ }
+ case 5:
+ {
+ //
+ // CDROM device
+ //
+ return L"GenCdRom";
+ }
+ case 7:
+ {
+ //
+ // optical memory device
+ //
+ return L"GenOptical";
+ }
+ case 8:
+ {
+ //
+ // medium change device
+ //
+ return L"GenChanger";
+ }
+ default:
+ {
+ //
+ // other device
+ //
+ return L"UsbstorOther";
+ }
+ }
+}
+
ULONG
CopyField(
@@ -114,6 +184,8 @@
ANSI_STRING AnsiString;
UNICODE_STRING DeviceId;
+ DPRINT1("USBSTOR_PdoHandleQueryDeviceId\n");
+
//
// get device extension
//
@@ -135,6 +207,11 @@
DeviceType = USBSTOR_GetDeviceType(InquiryData);
//
+ // zero buffer
+ //
+ RtlZeroMemory(Buffer, sizeof(Buffer));
+
+ //
// lets create device string
//
Offset = sprintf(&Buffer[Offset], "USBSTOR\\%s&Ven_", DeviceType);
@@ -192,7 +269,7 @@
// allocate DeviceId string
//
DeviceId.Length = 0;
- DeviceId.MaximumLength = (Offset + 2) * sizeof(WCHAR);
+ DeviceId.MaximumLength = (strlen((PCHAR)Buffer) + 1) * sizeof(WCHAR);
DeviceId.Buffer = (LPWSTR)AllocateItem(PagedPool, DeviceId.MaximumLength);
if (!DeviceId.Buffer)
{
@@ -217,7 +294,7 @@
Irp->IoStatus.Information = (ULONG_PTR)DeviceId.Buffer;
}
- DPRINT1("DeviceId %wZ\n", &DeviceId);
+ DPRINT1("DeviceId %wZ Status %x\n", &DeviceId, Status);
//
// done
@@ -225,6 +302,161 @@
return Status;
}
+NTSTATUS
+USBSTOR_PdoHandleQueryHardwareId(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN OUT PIRP Irp)
+{
+ PPDO_DEVICE_EXTENSION PDODeviceExtension;
+ PFDO_DEVICE_EXTENSION FDODeviceExtension;
+ WCHAR Buffer[200];
+ ULONG Length;
+ LPWSTR DeviceName;
+ LPCWSTR GenericType;
+
+ DPRINT1("USBSTOR_PdoHandleQueryInstanceId\n");
+
+ //
+ // get PDO device extension
+ //
+ PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ //
+ // get FDO device extension
+ //
+ FDODeviceExtension =
(PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
+
+ //
+ // sanity check
+ //
+ ASSERT(FDODeviceExtension->DeviceDescriptor);
+
+ //
+ // get generic type
+ //
+ GenericType =
USBSTOR_GetGenericType((PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData);
+ ASSERT(GenericType);
+
+ //
+ // zero buffer
+ //
+ RtlZeroMemory(Buffer, sizeof(Buffer));
+
+ //
+ // format hardware id
+ //
+ Length = swprintf(Buffer, L"USB\\VID_%04x&Pid_%04x&Rev_%04x",
FDODeviceExtension->DeviceDescriptor->idVendor,
FDODeviceExtension->DeviceDescriptor->idProduct,
FDODeviceExtension->DeviceDescriptor->bcdDevice) + 1;
+ Length += swprintf(&Buffer[Length], L"USB\\VID_%04x&Pid_%04x",
FDODeviceExtension->DeviceDescriptor->idVendor,
FDODeviceExtension->DeviceDescriptor->idProduct) + 1;
+ Length += swprintf(&Buffer[Length], L"USBSTOR\\%s", GenericType) + 1;
+ Length += swprintf(&Buffer[Length], L"%s", GenericType) + 1;
+
+ //
+ // TODO: add more ids
+ //
+
+ Buffer[Length] = UNICODE_NULL;
+ Length++;
+
+ DPRINT1("Name %S\n", Buffer);
+
+ //
+ // allocate buffer
+ //
+ DeviceName = (LPWSTR)AllocateItem(PagedPool, Length * sizeof(WCHAR));
+
+ if (!DeviceName)
+ {
+ //
+ // no memory
+ //
+ Irp->IoStatus.Information = 0;
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ //
+ // copy device name
+ //
+ RtlMoveMemory(DeviceName, Buffer, Length * sizeof(WCHAR));
+
+ //
+ // store result
+ //
+ Irp->IoStatus.Information = (ULONG_PTR)DeviceName;
+
+ //
+ // done
+ //
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+USBSTOR_PdoHandleQueryInstanceId(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN OUT PIRP Irp)
+{
+ PPDO_DEVICE_EXTENSION PDODeviceExtension;
+ PFDO_DEVICE_EXTENSION FDODeviceExtension;
+ WCHAR Buffer[100];
+ ULONG Length;
+ LPWSTR InstanceId;
+
+ DPRINT1("USBSTOR_PdoHandleQueryInstanceId\n");
+
+ //
+ // get PDO device extension
+ //
+ PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ //
+ // get FDO device extension
+ //
+ FDODeviceExtension =
(PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
+
+ //
+ // sanity check
+ //
+ ASSERT(FDODeviceExtension->DeviceDescriptor);
+
+ //
+ // format instance id
+ //
+ swprintf(Buffer, L"USB\\VID_%04x&PID_%04x\\%s",
FDODeviceExtension->DeviceDescriptor->idVendor,
FDODeviceExtension->DeviceDescriptor->idProduct, L"00000000");
+
+ //
+ // calculate length
+ //
+ Length = wcslen(Buffer) + 1;
+
+ //
+ // allocate instance id
+ //
+ InstanceId = (LPWSTR)AllocateItem(PagedPool, Length * sizeof(WCHAR));
+ if (!InstanceId)
+ {
+ //
+ // no memory
+ //
+ Irp->IoStatus.Information = 0;
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ //
+ // copy instance id
+ //
+ wcscpy(InstanceId, Buffer);
+
+ DPRINT1("USBSTOR_PdoHandleQueryInstanceId %S\n", InstanceId);
+
+ //
+ // store result
+ //
+ Irp->IoStatus.Information = (ULONG_PTR)InstanceId;
+
+ //
+ // completed successfully
+ //
+ return STATUS_SUCCESS;
+}
NTSTATUS
USBSTOR_PdoHandleDeviceRelations(
@@ -234,6 +466,8 @@
PDEVICE_RELATIONS DeviceRelations;
PIO_STACK_LOCATION IoStack;
+ DPRINT1("USBSTOR_PdoHandleDeviceRelations\n");
+
//
// get current irp stack location
//
@@ -289,6 +523,7 @@
PIO_STACK_LOCATION IoStack;
PPDO_DEVICE_EXTENSION DeviceExtension;
NTSTATUS Status;
+ PDEVICE_CAPABILITIES Caps;
//
// get current stack location
@@ -326,9 +561,26 @@
Status = USBSTOR_PdoHandleQueryDeviceId(DeviceObject, Irp);
break;
}
+ else if (IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs)
+ {
+ //
+ // handle instance id
+ //
+ Status = USBSTOR_PdoHandleQueryHardwareId(DeviceObject, Irp);
+ break;
+ }
+ else if (IoStack->Parameters.QueryId.IdType == BusQueryInstanceID)
+ {
+ //
+ // handle instance id
+ //
+ Status = USBSTOR_PdoHandleQueryInstanceId(DeviceObject, Irp);
+ break;
+ }
DPRINT1("USBSTOR_PdoHandlePnp: IRP_MN_QUERY_ID IdType %x
unimplemented\n", IoStack->Parameters.QueryId.IdType);
Status = STATUS_NOT_SUPPORTED;
+ Irp->IoStatus.Information = 0;
break;
}
case IRP_MN_REMOVE_DEVICE:
@@ -341,6 +593,16 @@
// just forward irp to lower device
//
Status = USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp);
+
+ if (NT_SUCCESS(Status))
+ {
+ //
+ // check if no unique id
+ //
+ Caps =
(PDEVICE_CAPABILITIES)IoStack->Parameters.DeviceCapabilities.Capabilities;
+ Caps->UniqueID = FALSE; //FIXME
+ Caps->Removable = TRUE; //FIXME
+ }
break;
}
case IRP_MN_START_DEVICE: