Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

594 lines
15 KiB

/*++
Copyright (c) 1996-2001 Microsoft Corporation
Module Name:
USBMASS.H
Abstract:
Header file for USBSTOR driver
Environment:
kernel mode
Revision History:
06-01-98 : started rewrite
--*/
//*****************************************************************************
// I N C L U D E S
//*****************************************************************************
#ifndef KDEXTMODE
#include <wdm.h>
#include <usb.h>
#include <usbioctl.h>
#include <usbdlib.h>
#endif
#define __GUSB_H_KERNEL_
#include "genusbio.h"
struct _DEVICE_EXTENSION;
#include "dbg.h"
//*****************************************************************************
// D E F I N E S
//*****************************************************************************
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define CLASS_URB(urb) urb->UrbControlVendorClassRequest
#define FEATURE_URB(urb) urb->UrbControlFeatureRequest
#define POOL_TAG 'UNEG'
#undef ExAllocatePool
#define ExAllocatePool(_type_, _length_) \
ExAllocatePoolWithTag(_type_, _length_, POOL_TAG)
//*****************************************************************************
// Registry Strings
//*****************************************************************************
// driver keys
// The pipe number for IRP_MJ_READ
#define REGKEY_DEFAULT_READ_PIPE L"DefaultReadPipe"
// The pipe number for IRP_MJ_WRITE
#define REGKEY_DEFAULT_WRITE_PIPE L"DefaultWritePipe"
#define USB_RECIPIENT_DEVICE URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
#define USB_RECIPIENT_INTERFACE URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE
#define USB_RECIPIENT_ENDPOINT URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT
typedef struct _GENUSB_PIPE_INFO
{
USBD_PIPE_INFORMATION Info;
GENUSB_PIPE_PROPERTIES Properties;
LONG CurrentTimeout;
ULONG OutstandingIO;
} GENUSB_PIPE_INFO, *PGENUSB_PIPE_INFO;
typedef struct _GENUSB_INTERFACE
{
UCHAR InterfaceNumber;
UCHAR CurrentAlternate;
UCHAR NumberOfPipes;
UCHAR Reserved;
USBD_INTERFACE_HANDLE Handle;
GENUSB_PIPE_INFO Pipes[];
} GENUSB_INTERFACE, *PGENUSB_INTERFACE;
typedef struct _GENUSB_TRANSFER
{
GENUSB_READ_WRITE_PIPE UserCopy;
PMDL UserMdl;
PMDL TransferMdl;
PGENUSB_READ_WRITE_PIPE SystemAddress;
} GENUSB_TRANSFER, *PGENUSB_TRANSFER;
typedef struct _GENUSB_PIPE_HANDLE {
UCHAR InterfaceIndex;
UCHAR PipeIndex;
USHORT Signature;
} *PGENUSB_PIPE_HANDLE;
C_ASSERT (sizeof (GENUSB_PIPE_HANDLE) == sizeof (struct _GENUSB_PIPE_HANDLE));
//
// Note: these routines do NOT actually secure that a transaction to a Pipe
// handle is no longer valid across a DeselectConfiguration, since the
// new configuration Handle might fall in the same address, and the old pipe
// handle might capture the same interface Index and Pipe Index. It does
// however catch a few sainity checks, and will prevent the user mode piece
// from manufacturing their own configuration handles (Without at least seeing
// the first one from a given configuration.) This just keeps them more
// honest, and doesn't really cause us any additional pain.
//
// In every case where we check the signatures, we also check to make sure
// that the interface and pipe indices contained in the handle are also
// still valid.
//
#define CONFIGURATION_CHECK_BITS(DeviceExtension) \
((USHORT) (((ULONG_PTR) ((DeviceExtension)->ConfigurationHandle)) >> 6))
#define VERIFY_PIPE_HANDLE_SIG(Handle, DeviceExtension) \
(CONFIGURATION_CHECK_BITS(DeviceExtension) == \
((PGENUSB_PIPE_HANDLE) (Handle))->Signature)
//
// Do something similar with the Pipe properties so that people are forced to
// do a get and set of the pipe properties. This will help to ensure that
// they are honest with these values and don't change other fields inadvertantly
//
#define PIPE_PROPERTIES_CHECK_BITS(PipeInfo) \
((USHORT) (((ULONG_PTR) &((PipeInfo)->Info)) >> 6))
// ((USHORT) (((ULONG_PTR) (PipeInfo) is equiv, but we do it this other way
// to check the type, by referecing the first field.
#define VERIFY_PIPE_PROPERTIES_HANDLE(PipeProperty, PipeInfo) \
(PIPE_PROPERTIES_CHECK_BITS(PipeInfo) == (PipeProperty)->PipePropertyHandle)
// Device Extension for the FDO we attach on top of the USB enumerated PDO.
//
typedef struct _DEVICE_EXTENSION
{
// Back pointer to Device Object for this Device Extension
PDEVICE_OBJECT Self;
BOOLEAN IsStarted;
BOOLEAN Reserved0[3];
// PDO passed to AddDevice
PDEVICE_OBJECT PhysicalDeviceObject;
// Our FDO is attached to this device object
PDEVICE_OBJECT StackDeviceObject;
// Device specific log.
PGENUSB_LOG_ENTRY LogStart; // Start of log buffer (older entries)
ULONG LogIndex;
ULONG LogMask;
// lock to protect from IRP_MN_REMOVE
IO_REMOVE_LOCK RemoveLock;
// Current power states
SYSTEM_POWER_STATE SystemPowerState;
DEVICE_POWER_STATE DevicePowerState;
PIRP CurrentPowerIrp;
// SpinLock which protects the allocated data
KSPIN_LOCK SpinLock;
// Mutex to protect from overlapped changes to the configuration
FAST_MUTEX ConfigMutex;
// Device Descriptor retrieved from the device
PUSB_DEVICE_DESCRIPTOR DeviceDescriptor;
// Configuration Descriptor retrieved from the device
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
// Serial Number String Descriptor
PUSB_STRING_DESCRIPTOR SerialNumber;
// track the number of Creates verses Closes
ULONG OpenedCount;
// A string to hold the Symbolic Link name for a device interface
UNICODE_STRING DevInterfaceLinkName;
// The Configuration Handle
// If this value is NULL then the device is assumed to be unconfigured.
USBD_CONFIGURATION_HANDLE ConfigurationHandle;
// a lock to track users of a configuration so that when it is deselected
// we won't delete the resouces too soon.
IO_REMOVE_LOCK ConfigurationRemoveLock;
// An array of Interface Information
PGENUSB_INTERFACE * Interface;
// The lenght of said Interface information
UCHAR InterfacesFound;
UCHAR TotalNumberOfPipes;
// The default language ID of this device
USHORT LanguageId;
// The Interface and Pipe of used for IRP_MJ_READ
// -1 means unconfigured
UCHAR ReadInterface;
UCHAR ReadPipe;
// The Interface and Pipe of used for IRP_MJ_WRITE
// -1 means unconfigured
UCHAR WriteInterface;
UCHAR WritePipe;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
typedef
NTSTATUS
(*PGENUSB_COMPLETION_ROUTINE) (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context,
IN USBD_STATUS UrbStatus,
IN ULONG TransferLength
);
typedef struct _GENUSB_TRANS_RECV {
PVOID Context;
PGENUSB_PIPE_INFO Pipe;
PGENUSB_COMPLETION_ROUTINE CompletionRoutine;
struct _URB_BULK_OR_INTERRUPT_TRANSFER TransUrb;
struct _URB_PIPE_REQUEST ResetUrb;
} GENUSB_TRANS_RECV, *PGENUSB_TRANS_RECV;
//*****************************************************************************
//
// F U N C T I O N P R O T O T Y P E S
//
//*****************************************************************************
//
// GENUSB.C
//
NTSTATUS
DriverEntry (
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
VOID
GenUSB_Unload (
IN PDRIVER_OBJECT DriverObject
);
NTSTATUS
GenUSB_AddDevice (
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
);
VOID
GenUSB_QueryParams (
IN PDEVICE_OBJECT DeviceObject
);
NTSTATUS
GenUSB_Pnp (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
GenUSB_StartDevice (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
GenUSB_StopDevice (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
GenUSB_RemoveDevice (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
GenUSB_QueryStopRemoveDevice (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
GenUSB_CancelStopRemoveDevice (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
GenUSB_SyncPassDownIrp (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
GenUSB_SyncSendUsbRequest (
IN PDEVICE_OBJECT DeviceObject,
IN PURB Urb
);
NTSTATUS
GenUSB_SetDeviceInterface (
IN PDEVICE_EXTENSION DeviceExtension,
IN BOOLEAN Create,
IN BOOLEAN Set
);
NTSTATUS
GenUSB_SetDIRegValues (
IN PDEVICE_EXTENSION DeviceExtension
);
NTSTATUS
GenUSB_Power (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
GenUSB_SetPower (
IN PDEVICE_EXTENSION DeviceExtension,
IN PIRP Irp
);
VOID
GenUSB_SetPowerCompletion(
IN PDEVICE_OBJECT PdoDeviceObject,
IN UCHAR MinorFunction,
IN POWER_STATE PowerState,
IN PVOID Context,
IN PIO_STATUS_BLOCK IoStatus
);
NTSTATUS
GenUSB_SetPowerD0Completion (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID NotUsed
);
NTSTATUS
GenUSB_SystemControl (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
//
// USB.C
//
NTSTATUS
GenUSB_GetDescriptors (
IN PDEVICE_OBJECT DeviceObject
);
NTSTATUS
GenUSB_GetDescriptor (
IN PDEVICE_OBJECT DeviceObject,
IN UCHAR Recipient,
IN UCHAR DescriptorType,
IN UCHAR Index,
IN USHORT LanguageId,
IN ULONG RetryCount,
IN ULONG DescriptorLength,
OUT PUCHAR *Descriptor
);
GenUSB_GetStringDescriptors (
IN PDEVICE_OBJECT DeviceObject
);
NTSTATUS
GenUSB_VendorControlRequest (
IN PDEVICE_OBJECT DeviceObject,
IN UCHAR RequestType,
IN UCHAR Request,
IN USHORT Value,
IN USHORT Index,
IN USHORT Length,
IN ULONG RetryCount,
OUT PULONG UrbStatus,
OUT PUSHORT ResultLength,
OUT PUCHAR *Result
);
NTSTATUS
GenUSB_SelectConfiguration (
IN PDEVICE_EXTENSION DeviceExtension,
IN ULONG NubmerInterfaces,
IN PUSB_INTERFACE_DESCRIPTOR DesiredArray,
OUT PUSB_INTERFACE_DESCRIPTOR FoundArray
);
NTSTATUS
GenUSB_DeselectConfiguration (
IN PDEVICE_EXTENSION DeviceExtension,
IN BOOLEAN SendUrb
);
NTSTATUS
GenUSB_GetSetPipe (
IN PDEVICE_EXTENSION DeviceExtension,
IN PUCHAR InterfaceIndex, // Optional
IN PUCHAR InterfaceNumber, // Optional
IN PUCHAR PipeIndex, // Optional
IN PUCHAR EndpointAddress, // Optional
IN PGENUSB_PIPE_PROPERTIES SetPipeProperties, // Optional
OUT PGENUSB_PIPE_INFORMATION PipeInfo, // Optional
OUT PGENUSB_PIPE_PROPERTIES GetPipeProperties, // Optional
OUT USBD_PIPE_HANDLE * UsbdPipeHandle // Optional
);
NTSTATUS
GenUSB_SetReadWritePipes (
IN PDEVICE_EXTENSION DeviceExtension,
IN PGENUSB_PIPE_HANDLE ReadPipe,
IN PGENUSB_PIPE_HANDLE WritePipe
);
NTSTATUS
GenUSB_RestartTimer (
PDEVICE_EXTENSION DeviceExtension,
PGENUSB_PIPE_INFO Pipe
);
VOID
GenUSB_FreeInterfaceTable (
PDEVICE_EXTENSION DeviceExtension
);
NTSTATUS
GenUSB_TransmitReceive (
IN PDEVICE_EXTENSION DeviceExtension,
IN PIRP Irp,
IN UCHAR InterfaceNo,
IN UCHAR PipeNo,
IN ULONG TransferFlags,
IN PCHAR Buffer,
IN PMDL BufferMDL,
IN ULONG BufferLength,
IN PVOID Context,
IN PGENUSB_COMPLETION_ROUTINE CompletionRoutine
);
NTSTATUS
GenUSB_ResetPipe (
IN PDEVICE_EXTENSION DeviceExtension,
IN USBD_PIPE_HANDLE UsbdPipeHandle,
IN BOOLEAN ResetPipe,
IN BOOLEAN ClearStall,
IN BOOLEAN FlushData
);
VOID
GenUSB_Timer (
PDEVICE_OBJECT DeviceObject,
PVOID Context
);
#if 0
VOID
GenUSB_AdjustConfigurationDescriptor (
IN PDEVICE_OBJECT DeviceObject,
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc,
OUT PUSB_INTERFACE_DESCRIPTOR *InterfaceDesc,
OUT PLONG BulkInIndex,
OUT PLONG BulkOutIndex,
OUT PLONG InterruptInIndex
);
NTSTATUS
GenUSB_GetPipes (
IN PDEVICE_OBJECT DeviceObject
);
NTSTATUS
GenUSB_CreateChildPDO (
IN PDEVICE_OBJECT FdoDeviceObject,
IN UCHAR Lun
);
NTSTATUS
GenUSB_FdoQueryDeviceRelations (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
VOID
CopyField (
IN PUCHAR Destination,
IN PUCHAR Source,
IN ULONG Count,
IN UCHAR Change
);
NTSTATUS
GenUSB_StringArrayToMultiSz(
PUNICODE_STRING MultiString,
PCSTR StringArray[]
);
NTSTATUS
GenUSB_GetMaxLun (
IN PDEVICE_OBJECT DeviceObject,
OUT PUCHAR MaxLun
);
NTSTATUS
GenUSB_AbortPipe (
IN PDEVICE_OBJECT DeviceObject,
IN USBD_PIPE_HANDLE Pipe
);
#endif
//
// OCRW.C
//
NTSTATUS
GenUSB_Create (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
GenUSB_Close (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
GenUSB_Read (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
GenUSB_Write (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
//
// DEVIOCTL.C
//
NTSTATUS
GenUSB_DeviceControl (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
GenUSB_ProbeAndSubmitTransfer (
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp,
IN PDEVICE_EXTENSION DeviceExtension
);