[USBEHCI_NEW]

- Remove function declaration
[USBSTOR]
- Start on usbstor driver (USB Mass Storage Driver)
- Implement reading device descriptor / configuration descriptor
- Implement scanning of configuration descriptor for bulk in / bulk out endpoints
- Implement selecting configuration and interface and verify selected interface
- Implement reading max lun and create child device object for each lun
- Handle PnP requests for functional device object
- Implement support routines to send urb's to lower device object (usbhub)
- Start implementing PDO routines

svn path=/branches/usb-bringup/; revision=51563
This commit is contained in:
Johannes Anderwald 2011-05-03 00:15:23 +00:00
parent bca978808b
commit 991d02daa5
10 changed files with 1750 additions and 126 deletions

View file

@ -2,5 +2,5 @@
add_subdirectory(nt4compat)
add_subdirectory(usbd)
add_subdirectory(usbehci_new)
#add_subdirectory(usbhub) Compiles, just skipped in trunk
#add_subdirectory(usbstor) Compiles, just skipped in trunk
add_subdirectory(usbhub)
add_subdirectory(usbstor)

View file

@ -44,7 +44,6 @@ public:
// local functions
NTSTATUS CreateFDO(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT * OutDeviceObject);
NTSTATUS CreatePDO(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT * OutDeviceObject);
NTSTATUS SetSymbolicLink(BOOLEAN Enable);
// constructor / destructor

View file

@ -80,8 +80,11 @@ SyncForwardIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
return Status;
}
NTSTATUS NTAPI
GetBusInterface(PDEVICE_OBJECT DeviceObject, PBUS_INTERFACE_STANDARD busInterface)
NTSTATUS
NTAPI
GetBusInterface(
PDEVICE_OBJECT DeviceObject,
PBUS_INTERFACE_STANDARD busInterface)
{
KEVENT Event;
NTSTATUS Status;

View file

@ -3,8 +3,8 @@ add_definitions(-DDEBUG_MODE)
include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include)
add_library(usbstor SHARED usbstor.c usbstor.rc)
add_library(usbstor SHARED descriptor.c fdo.c misc.c pdo.c usbstor.c usbstor.rc)
set_module_type(usbstor kernelmodedriver)
add_importlibs(usbstor ntoskrnl hal)
add_importlibs(usbstor ntoskrnl hal usbd)
add_cab_target(usbstor 2)

View file

@ -0,0 +1,516 @@
/*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
* LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/usb/usbstor/descriptor.c
* PURPOSE: USB block storage device driver.
* PROGRAMMERS:
* James Tabor
* Michael Martin (michael.martin@reactos.org)
* Johannes Anderwald (johannes.anderwald@reactos.org)
*/
#include "usbstor.h"
NTSTATUS
NTAPI
USBSTOR_GetDescriptor(
IN PDEVICE_OBJECT DeviceObject,
IN UCHAR DescriptorType,
IN ULONG DescriptorLength,
IN UCHAR DescriptorIndex,
IN LANGID LanguageId,
OUT PVOID *OutDescriptor)
{
PURB Urb;
NTSTATUS Status;
PVOID Descriptor;
//
// sanity checks
//
ASSERT(DeviceObject);
ASSERT(OutDescriptor);
ASSERT(DescriptorLength);
//
// first allocate descriptor buffer
//
Descriptor = AllocateItem(NonPagedPool, DescriptorLength);
if (!Descriptor)
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// allocate urb
//
Urb = (PURB) AllocateItem(NonPagedPool, sizeof(URB));
if (!Urb)
{
//
// no memory
//
FreeItem(Descriptor);
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// initialize urb
//
Urb->UrbHeader.Function = URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE;
Urb->UrbHeader.Length = sizeof(URB);
Urb->UrbControlDescriptorRequest.DescriptorType = DescriptorType;
Urb->UrbControlDescriptorRequest.TransferBuffer = Descriptor;
Urb->UrbControlDescriptorRequest.TransferBufferLength = DescriptorLength;
Urb->UrbControlDescriptorRequest.Index = DescriptorIndex;
Urb->UrbControlDescriptorRequest.LanguageId = LanguageId;
//
// submit urb
//
Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb);
//
// free urb
//
FreeItem(Urb);
if (NT_SUCCESS(Status))
{
//
// store result
//
*OutDescriptor = Descriptor;
}
//
// done
//
return Status;
}
NTSTATUS
USBSTOR_GetDescriptors(
IN PDEVICE_OBJECT DeviceObject)
{
NTSTATUS Status;
PFDO_DEVICE_EXTENSION DeviceExtension;
USHORT DescriptorLength;
//
// get device extension
//
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// first get device descriptor
//
Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_DEVICE_DESCRIPTOR_TYPE, sizeof(USB_DEVICE_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->DeviceDescriptor);
if (!NT_SUCCESS(Status))
{
//
// failed to get device descriptor
//
FreeItem(DeviceExtension->DeviceDescriptor);
DeviceExtension->DeviceDescriptor = NULL;
return Status;
}
//
// now get basic configuration descriptor
//
Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, sizeof(USB_CONFIGURATION_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor);
if (!NT_SUCCESS(Status))
{
//
// failed to get configuration descriptor
//
FreeItem(DeviceExtension->DeviceDescriptor);
DeviceExtension->DeviceDescriptor = NULL;
return Status;
}
//
// backup length
//
DescriptorLength = DeviceExtension->ConfigurationDescriptor->wTotalLength;
//
// release basic descriptor
//
FreeItem(DeviceExtension->ConfigurationDescriptor);
DeviceExtension->ConfigurationDescriptor = NULL;
//
// allocate full descriptor
//
Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, DescriptorLength, 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor);
if (!NT_SUCCESS(Status))
{
//
// failed to get configuration descriptor
//
FreeItem(DeviceExtension->DeviceDescriptor);
DeviceExtension->DeviceDescriptor = NULL;
return Status;
}
//
// FIXME: scan string descriptors
//
return Status;
}
NTSTATUS
NTAPI
USBSTOR_ScanConfigurationDescriptor(
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
OUT PUSB_INTERFACE_DESCRIPTOR * OutInterfaceDescriptor,
OUT PUSB_ENDPOINT_DESCRIPTOR * InEndpointDescriptor,
OUT PUSB_ENDPOINT_DESCRIPTOR * OutEndpointDescriptor)
{
PUSB_CONFIGURATION_DESCRIPTOR CurrentDescriptor;
PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
//
// sanity checks
//
ASSERT(ConfigurationDescriptor);
ASSERT(OutInterfaceDescriptor);
ASSERT(InEndpointDescriptor);
ASSERT(OutEndpointDescriptor);
//
// nullify pointers
//
*OutInterfaceDescriptor = NULL;
*InEndpointDescriptor = NULL;
*OutEndpointDescriptor = NULL;
//
// start scanning
//
CurrentDescriptor = ConfigurationDescriptor;
do
{
//
// check current descriptor type
//
if (CurrentDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
{
//
// found interface descriptor
//
if (*OutInterfaceDescriptor)
{
//
// we only process the first interface descriptor as ms does -> see documentation
//
break;
}
//
// store interface descriptor
//
*OutInterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)CurrentDescriptor;
}
else if (CurrentDescriptor->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE)
{
//
// convert to endpoint descriptor
//
EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)CurrentDescriptor;
//
// sanity check
//
ASSERT(*OutInterfaceDescriptor);
//
// get endpoint type
//
if ((EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK)
{
//
// bulk endpoint type
//
if (USB_ENDPOINT_DIRECTION_IN(EndpointDescriptor->bEndpointAddress))
{
//
// bulk in
//
*InEndpointDescriptor = EndpointDescriptor;
}
else
{
//
// bulk out
//
*OutEndpointDescriptor = EndpointDescriptor;
}
}
else if ((EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_INTERRUPT)
{
//
// interrupt endpoint type
//
UNIMPLEMENTED
}
}
//
// move to next descriptor
//
CurrentDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)((ULONG_PTR)CurrentDescriptor + CurrentDescriptor->bLength);
//
// was it the last descriptor
//
if ((ULONG_PTR)CurrentDescriptor > ((ULONG_PTR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength))
{
//
// reached last descriptor
//
break;
}
}while(TRUE);
//
// check if everything has been found
//
if (*OutInterfaceDescriptor == NULL || *InEndpointDescriptor == NULL || *OutEndpointDescriptor == NULL)
{
//
// failed to find interface / endpoint descriptor
//
DPRINT1("USBSTOR_ScanConfigurationDescriptor: Failed to find InterfaceDescriptor %p InEndpointDescriptor %p OutEndpointDescriptor %p\n", *OutInterfaceDescriptor, *InEndpointDescriptor, *OutEndpointDescriptor);
return STATUS_UNSUCCESSFUL;
}
//
// completed successfully
//
return STATUS_SUCCESS;
}
VOID
DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
{
DPRINT1("Dumping ConfigurationDescriptor %x\n", ConfigurationDescriptor);
DPRINT1("bLength %x\n", ConfigurationDescriptor->bLength);
DPRINT1("bDescriptorType %x\n", ConfigurationDescriptor->bDescriptorType);
DPRINT1("wTotalLength %x\n", ConfigurationDescriptor->wTotalLength);
DPRINT1("bNumInterfaces %x\n", ConfigurationDescriptor->bNumInterfaces);
DPRINT1("bConfigurationValue %x\n", ConfigurationDescriptor->bConfigurationValue);
DPRINT1("iConfiguration %x\n", ConfigurationDescriptor->iConfiguration);
DPRINT1("bmAttributes %x\n", ConfigurationDescriptor->bmAttributes);
DPRINT1("MaxPower %x\n", ConfigurationDescriptor->MaxPower);
}
NTSTATUS
USBSTOR_SelectConfigurationAndInterface(
IN PDEVICE_OBJECT DeviceObject,
IN PFDO_DEVICE_EXTENSION DeviceExtension)
{
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
PUSB_ENDPOINT_DESCRIPTOR InEndpointDescriptor, OutEndpointDescriptor;
NTSTATUS Status;
PURB Urb;
PUSBD_INTERFACE_LIST_ENTRY InterfaceList;
//
// now scan configuration descriptors
//
Status = USBSTOR_ScanConfigurationDescriptor(DeviceExtension->ConfigurationDescriptor, &InterfaceDescriptor, &InEndpointDescriptor, &OutEndpointDescriptor);
if (!NT_SUCCESS(Status))
{
//
// failed to scan
//
return Status;
}
//
// now allocate one interface entry and terminating null entry
//
InterfaceList = (PUSBD_INTERFACE_LIST_ENTRY)AllocateItem(PagedPool, sizeof(USBD_INTERFACE_LIST_ENTRY) * 2);
if (!InterfaceList)
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// initialize interface list entry
//
InterfaceList[0].InterfaceDescriptor = InterfaceDescriptor;
//
// now allocate the urb
//
Urb = USBD_CreateConfigurationRequestEx(DeviceExtension->ConfigurationDescriptor, InterfaceList);
if (!Urb)
{
//
// no memory
//
FreeItem(InterfaceList);
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// sanity check
//
ASSERT(InterfaceList[0].Interface);
//
// submit urb
//
Status = USBSTOR_SyncUrbRequest(DeviceExtension->LowerDeviceObject, Urb);
if (!NT_SUCCESS(Status))
{
//
// failed to set configuration
//
DPRINT1("USBSTOR_SelectConfiguration failed to set interface %x\n", Status);
FreeItem(InterfaceList);
FreeItem(Urb);
return Status;
}
//
// backup interface information
//
DeviceExtension->InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)AllocateItem(NonPagedPool, Urb->UrbSelectConfiguration.Interface.Length);
if (!NT_SUCCESS(Status))
{
//
// failed to allocate interface information structure
//
FreeItem(InterfaceList);
FreeItem(Urb);
return Status;
}
//
// copy interface information
//
RtlCopyMemory(DeviceExtension->InterfaceInformation, &Urb->UrbSelectConfiguration.Interface, Urb->UrbSelectConfiguration.Interface.Length);
//
// store pipe handle
//
DeviceExtension->ConfigurationHandle = Urb->UrbSelectConfiguration.ConfigurationHandle;
//
// now prepare interface urb
//
UsbBuildSelectInterfaceRequest(Urb, GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceDescriptor->bNumEndpoints), DeviceExtension->ConfigurationHandle, InterfaceDescriptor->bInterfaceNumber, InterfaceDescriptor->bAlternateSetting);
//
// copy interface information structure back - as offset for SelectConfiguration / SelectInterface request do differ
//
RtlCopyMemory(&Urb->UrbSelectInterface.Interface, DeviceExtension->InterfaceInformation, DeviceExtension->InterfaceInformation->Length);
//
// now select the interface
//
Status = USBSTOR_SyncUrbRequest(DeviceExtension->LowerDeviceObject, Urb);
//
// did it succeeed
//
if (NT_SUCCESS(Status))
{
//
// update configuration info
//
RtlCopyMemory(DeviceExtension->InterfaceInformation, &Urb->UrbSelectInterface.Interface, Urb->UrbSelectConfiguration.Interface.Length);
}
//
// free interface list & urb
//
FreeItem(InterfaceList);
FreeItem(Urb);
//
// done
//
return Status;
}
NTSTATUS
USBSTOR_GetPipeHandles(
IN PFDO_DEVICE_EXTENSION DeviceExtension)
{
ULONG Index;
BOOLEAN BulkInFound = FALSE, BulkOutFound = FALSE;
//
// no enumerate all pipes and extract bulk-in / bulk-out pipe handle
//
for(Index = 0; Index < DeviceExtension->InterfaceInformation->NumberOfPipes; Index++)
{
//
// check pipe type
//
if (DeviceExtension->InterfaceInformation->Pipes[Index].PipeType == UsbdPipeTypeBulk)
{
//
// check direction
//
if (USB_ENDPOINT_DIRECTION_IN(DeviceExtension->InterfaceInformation->Pipes[Index].EndpointAddress))
{
//
// bulk in pipe
//
DeviceExtension->BulkInPipeIndex = Index;
//
// there should not be another bulk in pipe
//
ASSERT(BulkInFound == FALSE);
BulkInFound = TRUE;
}
else
{
//
// bulk out pipe
//
DeviceExtension->BulkOutPipeIndex = Index;
//
// there should not be another bulk out pipe
//
ASSERT(BulkOutFound == FALSE);
BulkOutFound = TRUE;
}
}
}
//
// check if both bulk pipes have been found
//
if (!BulkInFound || !BulkOutFound)
{
//
// WTF? usb port driver does not give us bulk pipe access
//
DPRINT1("USBSTOR_GetPipeHandles> BulkInFound %d BulkOutFound %d missing!!!\n", BulkInFound, BulkOutFound);
return STATUS_DEVICE_CONFIGURATION_ERROR;
}
//
// device is configured
//
return STATUS_SUCCESS;
}

331
drivers/usb/usbstor/fdo.c Normal file
View file

@ -0,0 +1,331 @@
/*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
* LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/usb/usbstor/fdo.c
* PURPOSE: USB block storage device driver.
* PROGRAMMERS:
* James Tabor
* Michael Martin (michael.martin@reactos.org)
* Johannes Anderwald (johannes.anderwald@reactos.org)
*/
#include "usbstor.h"
VOID
USBSTOR_DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor)
{
DPRINT1("Dumping Device Descriptor %x\n", DeviceDescriptor);
DPRINT1("bLength %x\n", DeviceDescriptor->bLength);
DPRINT1("bDescriptorType %x\n", DeviceDescriptor->bDescriptorType);
DPRINT1("bcdUSB %x\n", DeviceDescriptor->bcdUSB);
DPRINT1("bDeviceClass %x\n", DeviceDescriptor->bDeviceClass);
DPRINT1("bDeviceSubClass %x\n", DeviceDescriptor->bDeviceSubClass);
DPRINT1("bDeviceProtocol %x\n", DeviceDescriptor->bDeviceProtocol);
DPRINT1("bMaxPacketSize0 %x\n", DeviceDescriptor->bMaxPacketSize0);
DPRINT1("idVendor %x\n", DeviceDescriptor->idVendor);
DPRINT1("idProduct %x\n", DeviceDescriptor->idProduct);
DPRINT1("bcdDevice %x\n", DeviceDescriptor->bcdDevice);
DPRINT1("iManufacturer %x\n", DeviceDescriptor->iManufacturer);
DPRINT1("iProduct %x\n", DeviceDescriptor->iProduct);
DPRINT1("iSerialNumber %x\n", DeviceDescriptor->iSerialNumber);
DPRINT1("bNumConfigurations %x\n", DeviceDescriptor->bNumConfigurations);
}
NTSTATUS
USBSTOR_FdoHandleDeviceRelations(
IN PFDO_DEVICE_EXTENSION DeviceExtension,
IN OUT PIRP Irp)
{
ULONG DeviceCount = 0;
ULONG Index;
PDEVICE_RELATIONS DeviceRelations;
PIO_STACK_LOCATION IoStack;
//
// get current irp stack location
//
IoStack = IoGetCurrentIrpStackLocation(Irp);
//
// check if relation type is BusRelations
//
if (IoStack->Parameters.QueryDeviceRelations.Type != BusRelations)
{
//
// FDO always only handles bus relations
//
return USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp);
}
//
// go through array and count device objects
//
for(Index = 0; Index < max(DeviceExtension->MaxLUN, 1); Index++)
{
if (DeviceExtension->ChildPDO[Index])
{
//
// child pdo
//
DeviceCount++;
}
}
//
// allocate device relations
//
DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS) + (DeviceCount > 1 ? (DeviceCount-1) * sizeof(PDEVICE_OBJECT) : 0));
if (!DeviceRelations)
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// add device objects
//
for(Index = 0; Index < max(DeviceExtension->MaxLUN, 1); Index++)
{
if (DeviceExtension->ChildPDO[Index])
{
//
// store child pdo
//
DeviceRelations->Objects[DeviceRelations->Count] = DeviceExtension->ChildPDO[Index];
//
// add reference
//
ObReferenceObject(DeviceExtension->ChildPDO[Index]);
//
// increment count
//
DeviceRelations->Count++;
}
}
//
// store result
//
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
//
// request completed successfully
//
return STATUS_SUCCESS;
}
NTSTATUS
USBSTOR_FdoHandleStartDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PFDO_DEVICE_EXTENSION DeviceExtension,
IN OUT PIRP Irp)
{
NTSTATUS Status;
UCHAR Index = 0;
//
// forward irp to lower device
//
Status = USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp);
if (!NT_SUCCESS(Status))
{
//
// failed to start
//
DPRINT1("USBSTOR_FdoHandleStartDevice Lower device failed to start %x\n", Status);
return Status;
}
//
// first get device & configuration & string descriptor
//
Status = USBSTOR_GetDescriptors(DeviceObject);
if (!NT_SUCCESS(Status))
{
//
// failed to get device descriptor
//
DPRINT1("USBSTOR_FdoHandleStartDevice failed to get device descriptor with %x\n", Status);
return Status;
}
//
// dump device descriptor
//
USBSTOR_DumpDeviceDescriptor(DeviceExtension->DeviceDescriptor);
//
// now select an interface
//
Status = USBSTOR_SelectConfigurationAndInterface(DeviceObject, DeviceExtension);
if (!NT_SUCCESS(Status))
{
//
// failed to get device descriptor
//
DPRINT1("USBSTOR_FdoHandleStartDevice failed to select configuration / interface with %x\n", Status);
return Status;
}
//
// check if we got a bulk in + bulk out endpoint
//
Status = USBSTOR_GetPipeHandles(DeviceExtension);
if (!NT_SUCCESS(Status))
{
//
// failed to get pipe handles descriptor
//
DPRINT1("USBSTOR_FdoHandleStartDevice no pipe handles %x\n", Status);
return Status;
}
//
// get num of lun which are supported
//
Status = USBSTOR_GetMaxLUN(DeviceExtension->LowerDeviceObject, DeviceExtension);
if (!NT_SUCCESS(Status))
{
//
// failed to get max LUN
//
DPRINT1("USBSTOR_FdoHandleStartDevice failed to get max lun %x\n", Status);
return Status;
}
//
// now create for each LUN a device object, 1 minimum
//
do
{
//
// create pdo
//
Status = USBSTOR_CreatePDO(DeviceObject, &DeviceExtension->ChildPDO[Index]);
//
// check for failure
//
if (!NT_SUCCESS(Status))
{
//
// failed to create child pdo
//
DPRINT1("USBSTOR_FdoHandleStartDevice USBSTOR_CreatePDO failed for Index %lu with Status %x\n", Index, Status);
return Status;
}
//
// increment pdo index
//
Index++;
}while(Index < DeviceExtension->MaxLUN);
//
// finally get usb device interface
//
Status = USBSTOR_GetBusInterface(DeviceExtension->LowerDeviceObject, &DeviceExtension->BusInterface);
if (!NT_SUCCESS(Status))
{
//
// failed to device interface
//
DPRINT1("USBSTOR_FdoHandleStartDevice failed to device interface %x\n", Status);
return Status;
}
//
// fdo is now initialized
//
DPRINT1("USBSTOR_FdoHandleStartDevice FDO is initialized\n");
return STATUS_SUCCESS;
}
NTSTATUS
USBSTOR_FdoHandlePnp(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
PFDO_DEVICE_EXTENSION DeviceExtension;
NTSTATUS Status;
//
// get current stack location
//
IoStack = IoGetCurrentIrpStackLocation(Irp);
//
// get device extension
//
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// sanity check
//
ASSERT(DeviceExtension->Common.IsFDO);
switch(IoStack->MinorFunction)
{
case IRP_MN_QUERY_DEVICE_RELATIONS:
{
Status = USBSTOR_FdoHandleDeviceRelations(DeviceExtension, Irp);
break;
}
case IRP_MN_STOP_DEVICE:
DPRINT1("USBSTOR_FdoHandlePnp: IRP_MN_STOP_DEVICE unimplemented\n");
Status = STATUS_NOT_SUPPORTED;
break;
case IRP_MN_REMOVE_DEVICE:
DPRINT1("USBSTOR_FdoHandlePnp: IRP_MN_REMOVE_DEVICE unimplemented\n");
Status = STATUS_NOT_SUPPORTED;
break;
case IRP_MN_QUERY_CAPABILITIES:
{
//
// just forward irp to lower device
//
Status = USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp);
break;
}
case IRP_MN_START_DEVICE:
{
Status = USBSTOR_FdoHandleStartDevice(DeviceObject, DeviceExtension, Irp);
break;
}
default:
{
//
// forward irp to next device object
//
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
}
}
//
// complete request
//
if (Status != STATUS_PENDING)
{
//
// store result
//
Irp->IoStatus.Status = Status;
//
// complete request
//
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
//
// done processing
//
return Status;
}

359
drivers/usb/usbstor/misc.c Normal file
View file

@ -0,0 +1,359 @@
/*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
* LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/usb/usbstor/misc.c
* PURPOSE: USB block storage device driver.
* PROGRAMMERS:
* James Tabor
* Michael Martin (michael.martin@reactos.org)
* Johannes Anderwald (johannes.anderwald@reactos.org)
*/
#include "usbstor.h"
//
// driver verifier
//
IO_COMPLETION_ROUTINE SyncForwardIrpCompletionRoutine;
NTSTATUS
NTAPI
USBSTOR_SyncForwardIrpCompletionRoutine(
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context)
{
if (Irp->PendingReturned)
{
KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
}
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS
NTAPI
USBSTOR_SyncForwardIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
KEVENT Event;
NTSTATUS Status;
//
// initialize event
//
KeInitializeEvent(&Event, NotificationEvent, FALSE);
//
// copy irp stack location
//
IoCopyCurrentIrpStackLocationToNext(Irp);
//
// set completion routine
//
IoSetCompletionRoutine(Irp, USBSTOR_SyncForwardIrpCompletionRoutine, &Event, TRUE, TRUE, TRUE);
//
// call driver
//
Status = IoCallDriver(DeviceObject, Irp);
//
// check if pending
//
if (Status == STATUS_PENDING)
{
//
// wait for the request to finish
//
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
//
// copy status code
//
Status = Irp->IoStatus.Status;
}
//
// done
//
return Status;
}
NTSTATUS
NTAPI
USBSTOR_GetBusInterface(
IN PDEVICE_OBJECT DeviceObject,
OUT PUSB_BUS_INTERFACE_USBDI_V2 BusInterface)
{
KEVENT Event;
NTSTATUS Status;
PIRP Irp;
IO_STATUS_BLOCK IoStatus;
PIO_STACK_LOCATION Stack;
//
// sanity checks
//
ASSERT(DeviceObject);
ASSERT(BusInterface);
//
// initialize event
//
KeInitializeEvent(&Event, NotificationEvent, FALSE);
//
// create irp
//
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
DeviceObject,
NULL,
0,
NULL,
&Event,
&IoStatus);
//
// was irp built
//
if (Irp == NULL)
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// initialize request
//
Stack=IoGetNextIrpStackLocation(Irp);
Stack->MajorFunction = IRP_MJ_PNP;
Stack->MinorFunction = IRP_MN_QUERY_INTERFACE;
Stack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
Stack->Parameters.QueryInterface.InterfaceType = (LPGUID)&USB_BUS_INTERFACE_USBDI_GUID;
Stack->Parameters.QueryInterface.Version = 2;
Stack->Parameters.QueryInterface.Interface = (PINTERFACE)BusInterface;
Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
//
// call driver
//
Status= IoCallDriver(DeviceObject, Irp);
//
// did operation complete
//
if (Status == STATUS_PENDING)
{
//
// wait for completion
//
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
//
// collect status
//
Status=IoStatus.Status;
}
return Status;
}
NTSTATUS
USBSTOR_SyncUrbRequest(
IN PDEVICE_OBJECT DeviceObject,
OUT PURB UrbRequest)
{
PIRP Irp;
PIO_STACK_LOCATION IoStack;
KEVENT Event;
NTSTATUS Status;
//
// allocate irp
//
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (!Irp)
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// initialize event
//
KeInitializeEvent(&Event, NotificationEvent, FALSE);
//
// get next stack location
//
IoStack = IoGetNextIrpStackLocation(Irp);
//
// initialize stack location
//
IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
IoStack->Parameters.Others.Argument1 = (PVOID)UrbRequest;
//
// setup completion routine
//
IoSetCompletionRoutine(Irp, USBSTOR_SyncForwardIrpCompletionRoutine, &Event, TRUE, TRUE, TRUE);
//
// call driver
//
Status = IoCallDriver(DeviceObject, Irp);
//
// check if request is pending
//
if (Status == STATUS_PENDING)
{
//
// wait for completion
//
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
//
// update status
//
Status = Irp->IoStatus.Status;
}
//
// free irp
//
IoFreeIrp(Irp);
//
// done
//
return Status;
}
PVOID
AllocateItem(
IN POOL_TYPE PoolType,
IN ULONG ItemSize)
{
//
// allocate item
//
PVOID Item = ExAllocatePoolWithTag(PoolType, ItemSize, USB_STOR_TAG);
if (Item)
{
//
// zero item
//
RtlZeroMemory(Item, ItemSize);
}
//
// return element
//
return Item;
}
VOID
FreeItem(
IN PVOID Item)
{
//
// free item
//
ExFreePoolWithTag(Item, USB_STOR_TAG);
}
NTSTATUS
USBSTOR_GetMaxLUN(
IN PDEVICE_OBJECT DeviceObject,
IN PFDO_DEVICE_EXTENSION DeviceExtension)
{
PURB Urb;
PUCHAR Buffer;
NTSTATUS Status;
//
// first allocate urb
//
Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
if (!Urb)
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// allocate 1-byte buffer
//
Buffer = (PUCHAR)AllocateItem(NonPagedPool, sizeof(UCHAR));
if (!Buffer)
{
//
// no memory
//
FreeItem(Buffer);
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// initialize vendor request
//
Urb->UrbControlVendorClassRequest.Hdr.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
Urb->UrbControlVendorClassRequest.Hdr.Function = URB_FUNCTION_CLASS_INTERFACE;
Urb->UrbControlVendorClassRequest.TransferFlags = USBD_TRANSFER_DIRECTION_IN;
Urb->UrbControlVendorClassRequest.TransferBufferLength = 1;
Urb->UrbControlVendorClassRequest.TransferBuffer = Buffer;
Urb->UrbControlVendorClassRequest.Request = USB_BULK_GET_MAX_LUN;
//
// submit request
//
Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb);
//
// free urb
//
FreeItem(Urb);
DPRINT1("MaxLUN: %x\n", *Buffer);
if (*Buffer > 0xF)
{
//
// invalid response documented in usb mass storage specification
//
Status = STATUS_DEVICE_DATA_ERROR;
}
else
{
//
// store maxlun
//
DeviceExtension->MaxLUN = *Buffer;
}
//
// free buffer
//
FreeItem(Buffer);
//
// done
//
return Status;
}

216
drivers/usb/usbstor/pdo.c Normal file
View file

@ -0,0 +1,216 @@
/*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
* LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/usb/usbstor/pdo.c
* PURPOSE: USB block storage device driver.
* PROGRAMMERS:
* James Tabor
* Michael Martin (michael.martin@reactos.org)
* Johannes Anderwald (johannes.anderwald@reactos.org)
*/
#include "usbstor.h"
NTSTATUS
USBSTOR_PdoHandleDeviceRelations(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp)
{
PDEVICE_RELATIONS DeviceRelations;
PIO_STACK_LOCATION IoStack;
//
// get current irp stack location
//
IoStack = IoGetCurrentIrpStackLocation(Irp);
//
// check if relation type is BusRelations
//
if (IoStack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
{
//
// PDO handles only target device relation
//
return Irp->IoStatus.Status;
}
//
// allocate device relations
//
DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS));
if (!DeviceRelations)
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// initialize device relations
//
DeviceRelations->Count = 1;
DeviceRelations->Objects[0] = DeviceObject;
ObReferenceObject(DeviceObject);
//
// store result
//
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
//
// completed successfully
//
return STATUS_SUCCESS;
}
NTSTATUS
USBSTOR_PdoHandlePnp(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
PPDO_DEVICE_EXTENSION DeviceExtension;
NTSTATUS Status;
//
// get current stack location
//
IoStack = IoGetCurrentIrpStackLocation(Irp);
//
// get device extension
//
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// sanity check
//
ASSERT(DeviceExtension->Common.IsFDO == FALSE);
switch(IoStack->MinorFunction)
{
case IRP_MN_QUERY_DEVICE_RELATIONS:
{
Status = USBSTOR_PdoHandleDeviceRelations(DeviceObject, Irp);
break;
}
case IRP_MN_QUERY_DEVICE_TEXT:
DPRINT1("USBSTOR_PdoHandlePnp: IRP_MN_QUERY_DEVICE_TEXT unimplemented\n");
Status = STATUS_NOT_SUPPORTED;
break;
case IRP_MN_QUERY_ID:
DPRINT1("USBSTOR_PdoHandlePnp: IRP_MN_QUERY_ID unimplemented\n");
Status = STATUS_NOT_SUPPORTED;
break;
case IRP_MN_REMOVE_DEVICE:
DPRINT1("USBSTOR_PdoHandlePnp: IRP_MN_REMOVE_DEVICE unimplemented\n");
Status = STATUS_SUCCESS;
break;
case IRP_MN_QUERY_CAPABILITIES:
{
//
// just forward irp to lower device
//
Status = USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp);
break;
}
case IRP_MN_START_DEVICE:
{
//
// no-op for PDO
//
Status = STATUS_SUCCESS;
break;
}
default:
{
//
// do nothing
//
Status = Irp->IoStatus.Status;
}
}
//
// complete request
//
if (Status != STATUS_PENDING)
{
//
// store result
//
Irp->IoStatus.Status = Status;
//
// complete request
//
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
//
// done processing
//
return Status;
}
NTSTATUS
USBSTOR_CreatePDO(
IN PDEVICE_OBJECT DeviceObject,
OUT PDEVICE_OBJECT *ChildDeviceObject)
{
PDEVICE_OBJECT PDO;
NTSTATUS Status;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
//
// create child device object
//
Status = IoCreateDevice(DeviceObject->DriverObject, sizeof(PDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_MASS_STORAGE, 0, FALSE, &PDO);
if (!NT_SUCCESS(Status))
{
//
// failed to create device
//
return Status;
}
//
// patch the stack size
//
PDO->StackSize = DeviceObject->StackSize;
//
// get device extension
//
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDO->DeviceExtension;
//
// initialize device extension
//
RtlZeroMemory(PDODeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
PDODeviceExtension->Common.IsFDO = FALSE;
PDODeviceExtension->LowerDeviceObject = DeviceObject;
//
// set device flags
//
PDO->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
//
// device is initialized
//
PDO->Flags &= ~DO_DEVICE_INITIALIZING;
//
// output device object
//
*ChildDeviceObject = PDO;
//
// done
//
return Status;
}

View file

@ -5,6 +5,7 @@
* PURPOSE: USB block storage device driver.
* PROGRAMMERS:
* James Tabor
Johannes Anderwald
*/
/* INCLUDES ******************************************************************/
@ -15,84 +16,201 @@
/* PUBLIC AND PRIVATE FUNCTIONS **********************************************/
NTSTATUS NTAPI
IrpStub(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
NTSTATUS
NTAPI
USBSTOR_AddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject)
{
NTSTATUS Status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
NTSTATUS Status;
PDEVICE_OBJECT DeviceObject;
PFDO_DEVICE_EXTENSION DeviceExtension;
NTSTATUS NTAPI
AddDevice(IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT pdo)
{
//
// lets create the device
//
Status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_EXTENSION), 0, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &DeviceObject);
//
// check for success
//
if (!NT_SUCCESS(Status))
{
DPRINT1("USBSTOR_AddDevice: Failed to create FDO Status %x\n", Status);
return Status;
}
//
// get device extension
//
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
ASSERT(DeviceExtension);
//
// zero device extension
//
RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
//
// initialize device extension
//
DeviceExtension->Common.IsFDO = TRUE;
DeviceExtension->FunctionalDeviceObject = DeviceObject;
DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
DeviceExtension->LowerDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
//
// did attaching fail
//
if (!DeviceExtension->LowerDeviceObject)
{
//
// device removed
//
IoDeleteDevice(DeviceObject);
return STATUS_DEVICE_REMOVED;
}
//
// set device flags
//
DeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
//
// device is initialized
//
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
//
// done
//
return STATUS_SUCCESS;
}
VOID NTAPI
DriverUnload(PDRIVER_OBJECT DriverObject)
VOID
NTAPI
USBSTOR_Unload(
PDRIVER_OBJECT DriverObject)
{
//
// no-op
//
}
VOID NTAPI
StartIo(PUSBSTOR_DEVICE_EXTENSION DeviceExtension,
PIRP Irp)
VOID
NTAPI
USBSTOR_StartIo(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
//
// implement me
//
UNIMPLEMENTED
}
static NTSTATUS NTAPI
DispatchClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
NTSTATUS
NTAPI
USBSTOR_DispatchClose(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
//
// function always succeeds ;)
//
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
static NTSTATUS NTAPI
DispatchCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
return STATUS_SUCCESS;
}
static NTSTATUS NTAPI
DispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
NTSTATUS
NTAPI
USBSTOR_DispatchDeviceControl(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
UNIMPLEMENTED
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
static NTSTATUS NTAPI
DispatchScsi(PDEVICE_OBJECT DeviceObject, PIRP Irp)
NTSTATUS
NTAPI
USBSTOR_DispatchScsi(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
UNIMPLEMENTED
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
static NTSTATUS NTAPI
DispatchReadWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
NTSTATUS
NTAPI
USBSTOR_DispatchReadWrite(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
return STATUS_SUCCESS;
//
// read write ioctl is not supported
//
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INVALID_PARAMETER;
}
static NTSTATUS NTAPI
DispatchSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
NTSTATUS
NTAPI
USBSTOR_DispatchPnp(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
return STATUS_SUCCESS;
PCOMMON_DEVICE_EXTENSION DeviceExtension;
//
// get common device extension
//
DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// is it for the FDO
//
if (DeviceExtension->IsFDO)
{
//
// dispatch pnp request to fdo pnp handler
//
return USBSTOR_FdoHandlePnp(DeviceObject, Irp);
}
else
{
//
// dispatch request to pdo pnp handler
//
return USBSTOR_PdoHandlePnp(DeviceObject, Irp);
}
}
static NTSTATUS NTAPI
DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
NTSTATUS
NTAPI
USBSTOR_DispatchPower(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
return STATUS_SUCCESS;
}
UNIMPLEMENTED
static NTSTATUS NTAPI
DispatchPower(PDEVICE_OBJECT fido, PIRP Irp)
{
DPRINT1("USBSTOR: IRP_MJ_POWER unimplemented\n");
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
@ -101,37 +219,62 @@ DispatchPower(PDEVICE_OBJECT fido, PIRP Irp)
/*
* Standard DriverEntry method.
*/
NTSTATUS NTAPI
DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegPath)
NTSTATUS
NTAPI
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegPath)
{
ULONG i;
DPRINT("********* USB Storage *********\n");
DPRINT1("********* USB Storage *********\n");
DriverObject->DriverUnload = DriverUnload;
DriverObject->DriverExtension->AddDevice = AddDevice;
//
// driver unload routine
//
DriverObject->DriverUnload = USBSTOR_Unload;
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
DriverObject->MajorFunction[i] = IrpStub;
//
// add device function
//
DriverObject->DriverExtension->AddDevice = USBSTOR_AddDevice;
DriverObject->DriverStartIo = (PVOID)StartIo;
//
// driver start i/o routine
//
DriverObject->DriverStartIo = USBSTOR_StartIo;
DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DispatchCleanup;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
DriverObject->MajorFunction[IRP_MJ_READ] = DispatchReadWrite;
DriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchReadWrite;
/* Scsi Miniport support */
DriverObject->MajorFunction[IRP_MJ_SCSI] = DispatchScsi;
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = DispatchSystemControl;
//
// create / close
//
DriverObject->MajorFunction[IRP_MJ_CREATE] = USBSTOR_DispatchClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBSTOR_DispatchClose;
DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
//
// scsi pass through requests
//
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBSTOR_DispatchDeviceControl;
//
// irp dispatch read / write
//
DriverObject->MajorFunction[IRP_MJ_READ] = USBSTOR_DispatchReadWrite;
DriverObject->MajorFunction[IRP_MJ_WRITE] = USBSTOR_DispatchReadWrite;
//
// scsi queue ioctl
//
DriverObject->MajorFunction[IRP_MJ_SCSI] = USBSTOR_DispatchScsi;
//
// pnp processing
//
DriverObject->MajorFunction[IRP_MJ_PNP] = USBSTOR_DispatchPnp;
//
// power processing
//
DriverObject->MajorFunction[IRP_MJ_POWER] = USBSTOR_DispatchPower;
return STATUS_SUCCESS;
}

View file

@ -1,8 +1,19 @@
#pragma once
#include <ntddk.h>
#include <usbdi.h>
#include <usbiodef.h>
#include <initguid.h>
#define NDEBUG
#include <debug.h>
#include <usbdi.h>
#include <hubbusif.h>
#include <usbbusif.h>
#include <usbioctl.h>
#include <usbiodef.h>
#include <usb.h>
#include <usbdlib.h>
#include <stdio.h>
#include <wdmguid.h>
#define USB_STOR_TAG 'sbsu'
#define USB_MAXCHILDREN (16)
@ -13,71 +24,117 @@ IoAttachDeviceToDeviceStackSafe(
IN PDEVICE_OBJECT TargetDevice,
OUT PDEVICE_OBJECT *AttachedToDeviceObject);
typedef struct _USBSTOR_DEVICE_EXTENSION
typedef struct _COMMON_DEVICE_EXTENSION
{
BOOLEAN IsFDO;
struct usb_device* dev;
PDEVICE_OBJECT LowerDevice;
BOOLEAN IsFDO;
PDEVICE_OBJECT Children[USB_MAXCHILDREN];
}COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
/* Fields valid only when IsFDO == FALSE */
UNICODE_STRING DeviceDescription; // REG_SZ
UNICODE_STRING DeviceId; // REG_SZ
UNICODE_STRING InstanceId; // REG_SZ
UNICODE_STRING HardwareIds; // REG_MULTI_SZ
UNICODE_STRING CompatibleIds; // REG_MULTI_SZ
UNICODE_STRING SymbolicLinkName;
} USBSTOR_DEVICE_EXTENSION, *PUSBSTOR_DEVICE_EXTENSION;
typedef struct
{
COMMON_DEVICE_EXTENSION Common; // common device extension
PDEVICE_OBJECT FunctionalDeviceObject; // functional device object
PDEVICE_OBJECT PhysicalDeviceObject; // physical device object
PDEVICE_OBJECT LowerDeviceObject; // lower device object
USB_BUS_INTERFACE_USBDI_V2 BusInterface; // bus interface of device
PUSB_DEVICE_DESCRIPTOR DeviceDescriptor; // usb device descriptor
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor; // usb configuration descriptor
PUSBD_INTERFACE_INFORMATION InterfaceInformation; // usb interface information
USBD_CONFIGURATION_HANDLE ConfigurationHandle; // usb configuration handle
UCHAR BulkInPipeIndex; // bulk in pipe index
UCHAR BulkOutPipeIndex; // bulk out pipe index
UCHAR MaxLUN; // max lun for device
PDEVICE_OBJECT ChildPDO[16]; // max 16 child pdo devices
}FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
typedef struct
{
COMMON_DEVICE_EXTENSION Common;
PDEVICE_OBJECT LowerDeviceObject; // points to FDO
}PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
/* cleanup.c */
NTSTATUS NTAPI
UsbStorCleanup(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
//
// max lun command identifier
//
#define USB_BULK_GET_MAX_LUN 0xFE
/* fdo.c */
NTSTATUS NTAPI
UsbStorPnpFdo(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
//---------------------------------------------------------------------
//
// fdo.c routines
//
NTSTATUS
USBSTOR_FdoHandlePnp(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp);
//---------------------------------------------------------------------
//
// pdo.c routines
//
NTSTATUS
USBSTOR_PdoHandlePnp(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp);
NTSTATUS
UsbStorDeviceControlFdo(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
USBSTOR_CreatePDO(
IN PDEVICE_OBJECT DeviceObject,
OUT PDEVICE_OBJECT *ChildDeviceObject);
/* misc.c */
//---------------------------------------------------------------------
//
// misc.c routines
//
NTSTATUS
ForwardIrpAndWait(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS NTAPI
ForwardIrpAndForget(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTAPI
USBSTOR_SyncForwardIrp(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp);
NTSTATUS
UsbStorDuplicateUnicodeString(
OUT PUNICODE_STRING Destination,
IN PUNICODE_STRING Source,
IN POOL_TYPE PoolType);
NTAPI
USBSTOR_GetBusInterface(
IN PDEVICE_OBJECT DeviceObject,
OUT PUSB_BUS_INTERFACE_USBDI_V2 BusInterface);
PVOID
AllocateItem(
IN POOL_TYPE PoolType,
IN ULONG ItemSize);
VOID
FreeItem(
IN PVOID Item);
NTSTATUS
UsbStorInitMultiSzString(
OUT PUNICODE_STRING Destination,
... /* list of PCSZ */);
/* pdo.c */
NTSTATUS NTAPI
UsbStorPnpPdo(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
USBSTOR_SyncUrbRequest(
IN PDEVICE_OBJECT DeviceObject,
OUT PURB UrbRequest);
NTSTATUS
UsbStorDeviceControlPdo(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
USBSTOR_GetMaxLUN(
IN PDEVICE_OBJECT DeviceObject,
IN PFDO_DEVICE_EXTENSION DeviceExtension);
//---------------------------------------------------------------------
//
// descriptor.c routines
//
NTSTATUS
USBSTOR_GetDescriptors(
IN PDEVICE_OBJECT DeviceObject);
NTSTATUS
USBSTOR_SelectConfigurationAndInterface(
IN PDEVICE_OBJECT DeviceObject,
IN PFDO_DEVICE_EXTENSION DeviceExtension);
NTSTATUS
USBSTOR_GetPipeHandles(
IN PFDO_DEVICE_EXTENSION DeviceExtension);