/* * usbshare - public interface * * Shared between the kernel driver and the user mode client. Keep this file * in sync with internal/usb/driver_windows.go: both sides marshal the same * structures, and a mismatch corrupts memory rather than failing cleanly. */ #pragma once #include /* * Device interface GUID. User mode enumerates this to find devices that have * the filter attached. * * Generate a fresh GUID if you fork this driver: two drivers exposing the * same interface would be indistinguishable to clients. */ // {8F3D2A14-6C7B-4E59-9A1D-3F5B7C8E2D40} DEFINE_GUID(GUID_DEVINTERFACE_USBSHARE, 0x8f3d2a14, 0x6c7b, 0x4e59, 0x9a, 0x1d, 0x3f, 0x5b, 0x7c, 0x8e, 0x2d, 0x40); #define USBSHARE_DEVICE_TYPE 0x8000 #define USBSHARE_IOCTL(index) \ CTL_CODE(USBSHARE_DEVICE_TYPE, 0x800 + (index), METHOD_BUFFERED, FILE_ANY_ACCESS) /* * Take exclusive control of the device. * * While claimed the filter stops passing the class driver's requests down, so * the device stops responding to the local system and answers only to URBs * submitted here. The claim is bound to the file handle: closing it — or the * process dying — releases the device, which is what stops a crashed client * from leaving hardware permanently stuck. * * Input: none * Output: USBSHARE_DEVICE_INFO */ #define IOCTL_USBSHARE_CLAIM USBSHARE_IOCTL(0) /* Release the device back to its class driver. Input/output: none. */ #define IOCTL_USBSHARE_RELEASE USBSHARE_IOCTL(1) /* * Read the raw descriptor blob: device descriptor followed by every * configuration descriptor, the same layout a Linux usbdevfs read returns. * * Input: none * Output: raw bytes; STATUS_BUFFER_TOO_SMALL reports the needed size */ #define IOCTL_USBSHARE_GET_DESCRIPTORS USBSHARE_IOCTL(2) /* * Submit a transfer. Completion is asynchronous: the request stays pending * until the device answers. * * Input: USBSHARE_TRANSFER followed by the payload for OUT transfers * Output: USBSHARE_TRANSFER_RESULT followed by the payload for IN transfers */ #define IOCTL_USBSHARE_SUBMIT USBSHARE_IOCTL(3) /* * Cancel a previously submitted transfer. * * Input: USBSHARE_CANCEL * Output: none */ #define IOCTL_USBSHARE_CANCEL USBSHARE_IOCTL(4) /* Select an alternate setting. Input: USBSHARE_SET_INTERFACE. */ #define IOCTL_USBSHARE_SET_INTERFACE USBSHARE_IOCTL(5) /* Clear a stall on an endpoint. Input: USBSHARE_CLEAR_HALT. */ #define IOCTL_USBSHARE_CLEAR_HALT USBSHARE_IOCTL(6) /* Reset the port. Input/output: none. */ #define IOCTL_USBSHARE_RESET USBSHARE_IOCTL(7) #pragma pack(push, 1) /* Transfer types, matching the USB endpoint attribute values. */ #define USBSHARE_TRANSFER_CONTROL 0 #define USBSHARE_TRANSFER_ISOCHRONOUS 1 #define USBSHARE_TRANSFER_BULK 2 #define USBSHARE_TRANSFER_INTERRUPT 3 /* Direction, taken from the endpoint address bit 7. */ #define USBSHARE_DIR_OUT 0 #define USBSHARE_DIR_IN 1 typedef struct _USBSHARE_DEVICE_INFO { USHORT VendorId; USHORT ProductId; USHORT BcdDevice; UCHAR DeviceClass; UCHAR DeviceSubClass; UCHAR DeviceProtocol; UCHAR ConfigurationValue; UCHAR NumConfigurations; /* USB_DEVICE_SPEED_* from usbdi.h, translated by the client. */ ULONG Speed; /* Hub port number, used to build a stable bus ID. */ ULONG PortNumber; } USBSHARE_DEVICE_INFO, *PUSBSHARE_DEVICE_INFO; typedef struct _USBSHARE_TRANSFER { /* Caller-assigned, unique among outstanding transfers. Used to cancel. */ ULONG64 Id; /* Full bEndpointAddress including the direction bit. */ UCHAR EndpointAddress; /* USBSHARE_TRANSFER_* */ UCHAR Type; /* USBSHARE_DIR_*, redundant with the address bit but explicit. */ UCHAR Direction; UCHAR Reserved; /* Bytes of payload following this header (OUT), or expected (IN). */ ULONG BufferLength; /* Milliseconds; 0 means no timeout. */ ULONG Timeout; /* * Setup packet for control transfers, in USB wire order (little endian). * Ignored for other types. */ UCHAR Setup[8]; } USBSHARE_TRANSFER, *PUSBSHARE_TRANSFER; typedef struct _USBSHARE_TRANSFER_RESULT { ULONG64 Id; /* NTSTATUS from the USB stack; 0 means success. */ LONG Status; /* USBD_STATUS, kept separate because it distinguishes stall from timeout. */ ULONG UsbdStatus; /* Bytes actually transferred. Meaningful for OUT transfers too. */ ULONG ActualLength; } USBSHARE_TRANSFER_RESULT, *PUSBSHARE_TRANSFER_RESULT; typedef struct _USBSHARE_CANCEL { ULONG64 Id; } USBSHARE_CANCEL, *PUSBSHARE_CANCEL; typedef struct _USBSHARE_SET_INTERFACE { UCHAR InterfaceNumber; UCHAR AlternateSetting; } USBSHARE_SET_INTERFACE, *PUSBSHARE_SET_INTERFACE; typedef struct _USBSHARE_CLEAR_HALT { UCHAR EndpointAddress; } USBSHARE_CLEAR_HALT, *PUSBSHARE_CLEAR_HALT; #pragma pack(pop)