308 lines
7 KiB
C
308 lines
7 KiB
C
|
/****************************************************************************
|
|||
|
|
|||
|
Copyright (c) 1993 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
usbloop.h
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This header file is used both by ring3 app and ring0 driver, hence the
|
|||
|
use of #define DRIVER
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
Kernel & user mode
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
1-10-96 : created
|
|||
|
|
|||
|
****************************************************************************/
|
|||
|
|
|||
|
#ifdef DRIVER
|
|||
|
|
|||
|
#include <wdm.h>
|
|||
|
#include <usbdi.h>
|
|||
|
#include <usbdlib.h>
|
|||
|
|
|||
|
#else
|
|||
|
|
|||
|
#include <usbdi.h>
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
#include <stdarg.h>
|
|||
|
#include <stdio.h>
|
|||
|
#include <stdlib.h>
|
|||
|
|
|||
|
|
|||
|
#define NAME_MAX 256
|
|||
|
#define MAX_INTERFACE 8
|
|||
|
#define USBLOOP_PARENT "\\\\.\\USBLOOPXXX"
|
|||
|
|
|||
|
// IOCTL info
|
|||
|
|
|||
|
#define USBLOOP_IOCTL_INDEX 0x0080
|
|||
|
|
|||
|
#define GET_NUM_DEVICES CTL_CODE(FILE_DEVICE_UNKNOWN, \
|
|||
|
USBLOOP_IOCTL_INDEX+0, \
|
|||
|
METHOD_BUFFERED, \
|
|||
|
FILE_ANY_ACCESS)
|
|||
|
|
|||
|
#define GET_DEVICE_INFO CTL_CODE(FILE_DEVICE_UNKNOWN, \
|
|||
|
USBLOOP_IOCTL_INDEX+1, \
|
|||
|
METHOD_BUFFERED, \
|
|||
|
FILE_ANY_ACCESS)
|
|||
|
|
|||
|
#define GET_DEVICE_DESCRIPTOR CTL_CODE(FILE_DEVICE_UNKNOWN, \
|
|||
|
USBLOOP_IOCTL_INDEX+2, \
|
|||
|
METHOD_BUFFERED, \
|
|||
|
FILE_ANY_ACCESS)
|
|||
|
|
|||
|
#define GET_CONFIG_DESCRIPTOR CTL_CODE(FILE_DEVICE_UNKNOWN, \
|
|||
|
USBLOOP_IOCTL_INDEX+3, \
|
|||
|
METHOD_BUFFERED, \
|
|||
|
FILE_ANY_ACCESS)
|
|||
|
|
|||
|
|
|||
|
#define GET_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN, \
|
|||
|
USBLOOP_IOCTL_INDEX+4, \
|
|||
|
METHOD_BUFFERED, \
|
|||
|
FILE_ANY_ACCESS)
|
|||
|
|
|||
|
#define GET_INTERFACE_INFO CTL_CODE(FILE_DEVICE_UNKNOWN, \
|
|||
|
USBLOOP_IOCTL_INDEX+5, \
|
|||
|
METHOD_BUFFERED, \
|
|||
|
FILE_ANY_ACCESS)
|
|||
|
|
|||
|
#define USBLOOP_START_ISO_TEST CTL_CODE(FILE_DEVICE_UNKNOWN, \
|
|||
|
USBLOOP_IOCTL_INDEX+6, \
|
|||
|
METHOD_BUFFERED, \
|
|||
|
FILE_ANY_ACCESS)
|
|||
|
|
|||
|
#ifdef DRIVER
|
|||
|
|
|||
|
#define USBDIAG_NAME_MAX 64
|
|||
|
#define USBLOOP_MAX_PIPES 256
|
|||
|
#define USBLOOP_MAX_XFER_SIZE 16384 // 16K
|
|||
|
#define USBLOOP_MAX_ENUM_DEVICES 8
|
|||
|
|
|||
|
typedef struct _DEVICE_LIST_ENTRY {
|
|||
|
PDEVICE_OBJECT PhysicalDeviceObject;
|
|||
|
PDEVICE_OBJECT DeviceObject;
|
|||
|
struct _DEVICE_LIST_ENTRY *Next;
|
|||
|
ULONG DeviceNumber;
|
|||
|
} DEVICE_LIST_ENTRY, *PDEVICE_LIST_ENTRY;
|
|||
|
|
|||
|
// data structure to describe each pipe
|
|||
|
typedef struct _PipeDescr
|
|||
|
{
|
|||
|
BOOLEAN bPipeInUse; // pipe in use flag
|
|||
|
// layout of PipeAttr is LSB|ep|alt_interface|interface|configuration|MSB
|
|||
|
ULONG PipeAttr; // describes pipe configuration, interface, etc.
|
|||
|
} PipeDescr, *pPipeDescr;
|
|||
|
|
|||
|
// device extension for driver instance, used to store needed data
|
|||
|
|
|||
|
typedef struct _DEVICE_EXTENSION
|
|||
|
{
|
|||
|
PDEVICE_OBJECT PhysicalDeviceObject; // physical device object
|
|||
|
PDEVICE_OBJECT StackDeviceObject; // stack device object
|
|||
|
PDEVICE_LIST_ENTRY DeviceList;
|
|||
|
ULONG ulInstance; // keeps track of device instance
|
|||
|
|
|||
|
// Name buffer for our named Functional device object link
|
|||
|
WCHAR DeviceLinkNameBuffer[USBDIAG_NAME_MAX];
|
|||
|
|
|||
|
// descriptors for device instance
|
|||
|
|
|||
|
PUSB_CONFIGURATION_DESCRIPTOR pUsbConfigDesc;
|
|||
|
PUSBD_INTERFACE_INFORMATION Interface[MAX_INTERFACE];
|
|||
|
|
|||
|
ULONG OpenFRC;
|
|||
|
|
|||
|
PUSB_DEVICE_DESCRIPTOR pDeviceDescriptor;
|
|||
|
|
|||
|
KTIMER TimeoutTimer;
|
|||
|
KDPC TimeoutDpc;
|
|||
|
|
|||
|
// handle to configuration that was selected
|
|||
|
USBD_CONFIGURATION_HANDLE ConfigurationHandle;
|
|||
|
ULONG numPipesInUse; // number of pipes in use
|
|||
|
PipeDescr pipes[USBLOOP_MAX_PIPES]; // array of pipe descriptors
|
|||
|
//Pointer to an Irp outstanding on this device
|
|||
|
// BUGBUG (kosar) This should really be kept on a per-pipe basis but
|
|||
|
// we're only keeping on outstanding Irp on this device
|
|||
|
// at a time.
|
|||
|
PIRP pIrp;
|
|||
|
BOOLEAN Stopped; // keeps track of device status
|
|||
|
BOOLEAN bTestDevice; // flag for test devices
|
|||
|
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#define PIPE_MASK 0xff
|
|||
|
#define NUM_ATTR_BYTES 4
|
|||
|
#define ALT_INT_SHIFT 8
|
|||
|
#define INT_SHIFT 16
|
|||
|
#define CONFIG_SHIFT 24
|
|||
|
#define DEADMAN_TIMEOUT 5000
|
|||
|
|
|||
|
// extract alt interface from FsContext
|
|||
|
#define ALT_INTERFACE(context) ((ULONG) ((ULONG) context >> ALT_INT_SHIFT) & PIPE_MASK)
|
|||
|
|
|||
|
// extract interface from FsContext
|
|||
|
#define INTERFACE(context) ((ULONG) ((ULONG) context >> INT_SHIFT) & PIPE_MASK)
|
|||
|
|
|||
|
// extract configuration from FsContext
|
|||
|
#define CONFIGURATION(context) ((ULONG) ((ULONG) context >> CONFIG_SHIFT) & PIPE_MASK)
|
|||
|
|
|||
|
// extract pipe number from FsContext
|
|||
|
#define PIPENUM(context) ((ULONG) context & PIPE_MASK)
|
|||
|
|
|||
|
// turns ULONGs into attribute byte for pipe
|
|||
|
#define MAKEPIPEATTR(config, interface, alt_interface, pipenum) \
|
|||
|
((ULONG) (((config & PIPE_MASK) << CONFIG_SHIFT) + \
|
|||
|
((interface & PIPE_MASK) << INT_SHIFT) + \
|
|||
|
((alt_interface & PIPE_MASK) << ALT_INT_SHIFT) + \
|
|||
|
(pipenum & PIPE_MASK)))
|
|||
|
|
|||
|
ULONG ulNumLogDev;
|
|||
|
|
|||
|
static WCHAR deviceLinkBuffer[NAME_MAX] = L"\\DosDevices\\USBLOOP";
|
|||
|
static WCHAR deviceNameBuffer[NAME_MAX] = L"\\Device\\USBLOOP";
|
|||
|
|
|||
|
|
|||
|
// this data structure will be used for async transfers, contains urb
|
|||
|
// structure, a timer object, pointer to the irp, and a callback object for
|
|||
|
// the timer. The timer will be cancelled when the USB transfer completes
|
|||
|
typedef struct AsyncTransfer
|
|||
|
{
|
|||
|
struct _URB_BULK_OR_INTERRUPT_TRANSFER urb;
|
|||
|
KTIMER TimeoutTimer;
|
|||
|
PIRP irp;
|
|||
|
KDPC TimeoutDpc;
|
|||
|
BOOLEAN bTimerExpired;
|
|||
|
} AsyncTransfer, *pAsyncTransfer;
|
|||
|
|
|||
|
|
|||
|
#if DBG
|
|||
|
|
|||
|
#define USBLOOP_KdPrint(_x_) DbgPrint("USBLOOP.SYS: "); \
|
|||
|
DbgPrint _x_ ;
|
|||
|
#define USBLOOP_TRAP() DbgBreakPoint()
|
|||
|
|
|||
|
#else
|
|||
|
|
|||
|
#define USBLOOP_KdPrint(_x_)
|
|||
|
|
|||
|
#define USBLOOP_TRAP()
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
USBLOOP_Dispatch(
|
|||
|
IN PDEVICE_OBJECT DeviceObject,
|
|||
|
IN PIRP Irp
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
USBLOOP_Unload(
|
|||
|
IN PDRIVER_OBJECT DriverObject
|
|||
|
);
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
USBLOOP_StartDevice(
|
|||
|
IN PDEVICE_OBJECT DeviceObject
|
|||
|
);
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
USBLOOP_StopDevice(
|
|||
|
IN PDEVICE_OBJECT DeviceObject
|
|||
|
);
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
USBLOOP_CreateDeviceObject(
|
|||
|
IN PDRIVER_OBJECT DriverObject,
|
|||
|
IN PDEVICE_OBJECT *DeviceObject,
|
|||
|
ULONG Instance
|
|||
|
);
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
USBLOOP_CallUSBD(
|
|||
|
IN PDEVICE_OBJECT DeviceObject,
|
|||
|
IN PURB Urb
|
|||
|
);
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
USBLOOP_PnPAddDevice(
|
|||
|
IN PDRIVER_OBJECT DriverObject,
|
|||
|
IN PDEVICE_OBJECT PhysicalDeviceObject
|
|||
|
);
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
USBLOOP_SelectInterfaces(
|
|||
|
IN PDEVICE_OBJECT DeviceObject,
|
|||
|
IN PUSB_CONFIGURATION_DESCRIPTOR configDesc
|
|||
|
);
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
USBLOOP_ConfigureDevice(
|
|||
|
IN PDEVICE_OBJECT DeviceObject
|
|||
|
);
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
USBLOOP_GetDescriptor(
|
|||
|
IN PDEVICE_OBJECT DeviceObject,
|
|||
|
IN UCHAR DescType,
|
|||
|
IN OUT PVOID pvBuffer
|
|||
|
);
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
USBLOOP_Read(
|
|||
|
IN PDEVICE_OBJECT DeviceObject,
|
|||
|
IN PIRP Irp
|
|||
|
);
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
USBLOOP_Write(
|
|||
|
IN PDEVICE_OBJECT DeviceObject,
|
|||
|
IN PIRP Irp
|
|||
|
);
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
USBLOOP_getPipeAttr(
|
|||
|
IN PCWSTR pDeviceName,
|
|||
|
OUT PULONG pPipeAttr
|
|||
|
);
|
|||
|
|
|||
|
pAsyncTransfer
|
|||
|
USBLOOP_BuildAsyncRequest(
|
|||
|
IN PDEVICE_OBJECT DeviceObject,
|
|||
|
IN PIRP Irp,
|
|||
|
IN USBD_PIPE_HANDLE PipeHandle,
|
|||
|
IN BOOLEAN Read
|
|||
|
);
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
USBLOOP_AsyncReadWrite_Complete(
|
|||
|
IN PDEVICE_OBJECT DeviceObject,
|
|||
|
IN PIRP Irp,
|
|||
|
IN PVOID Context
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
USBLOOP_SyncTimeoutDPC(
|
|||
|
IN PKDPC Dpc,
|
|||
|
IN PVOID DeferredContext,
|
|||
|
IN PVOID SystemArgument1,
|
|||
|
IN PVOID SystemArgument2
|
|||
|
);
|
|||
|
|
|||
|
#endif
|
|||
|
|