reactos/drivers/usb/usbstor/usbstor.c

296 lines
6.1 KiB
C

/*
* PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
* LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/usb/usbstor/usbstor.c
* PURPOSE: USB block storage device driver.
* PROGRAMMERS:
* James Tabor
Johannes Anderwald
*/
/* INCLUDES ******************************************************************/
#include "usbstor.h"
#define NDEBUG
#include <debug.h>
/* PUBLIC AND PRIVATE FUNCTIONS **********************************************/
NTSTATUS
NTAPI
USBSTOR_AddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject)
{
NTSTATUS Status;
PDEVICE_OBJECT DeviceObject;
PFDO_DEVICE_EXTENSION DeviceExtension;
//
// lets create the device
//
Status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_EXTENSION), 0, FILE_DEVICE_BUS_EXTENDER, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, 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);
//
// init timer
//
IoInitializeTimer(DeviceObject, USBSTOR_TimerRoutine, (PVOID)DeviceExtension);
//
// 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
USBSTOR_Unload(
PDRIVER_OBJECT DriverObject)
{
//
// no-op
//
}
NTSTATUS
NTAPI
USBSTOR_DispatchClose(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
//
// function always succeeds ;)
//
DPRINT("USBSTOR_DispatchClose\n");
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
USBSTOR_DispatchDeviceControl(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
NTSTATUS Status;
//
// handle requests
//
Status = USBSTOR_HandleDeviceControl(DeviceObject, Irp);
//
// complete request
//
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
//
// done
//
return Status;
}
NTSTATUS
NTAPI
USBSTOR_DispatchScsi(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
//
// handle requests
//
return USBSTOR_HandleInternalDeviceControl(DeviceObject, Irp);
}
NTSTATUS
NTAPI
USBSTOR_DispatchReadWrite(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
//
// 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;
}
NTSTATUS
NTAPI
USBSTOR_DispatchPnp(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PUSBSTOR_COMMON_DEVICE_EXTENSION DeviceExtension;
//
// get common device extension
//
DeviceExtension = (PUSBSTOR_COMMON_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);
}
}
NTSTATUS
NTAPI
USBSTOR_DispatchPower(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PFDO_DEVICE_EXTENSION DeviceExtension;
// get common device extension
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
if (DeviceExtension->Common.IsFDO)
{
PoStartNextPowerIrp(Irp);
IoSkipCurrentIrpStackLocation(Irp);
return PoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
}
else
{
PoStartNextPowerIrp(Irp);
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
}
NTSTATUS
NTAPI
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegPath)
{
DPRINT("********* USB Storage *********\n");
//
// driver unload routine
//
DriverObject->DriverUnload = USBSTOR_Unload;
//
// add device function
//
DriverObject->DriverExtension->AddDevice = USBSTOR_AddDevice;
//
// driver start i/o routine
//
DriverObject->DriverStartIo = USBSTOR_StartIo;
//
// create / close
//
DriverObject->MajorFunction[IRP_MJ_CREATE] = USBSTOR_DispatchClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBSTOR_DispatchClose;
//
// 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;
}