/*++ Copyright (c) Microsoft Corporation. All rights reserved. Module Name: UMGUSB.C Abstract: This module contains the code for the helper lib that talks to the generic USB driver Environment: Kernel & user mode Revision History: Sept-01 : created by Kenneth Ray --*/ #include #include #include #include #include "genusbio.h" #include "umgusb.h" // // __cdecl main (int argc, char *argv[]) // { // return 0; // } // STDAPI_(BOOL) Entry32(HINSTANCE hinst, DWORD dwReason, LPVOID lpReserved) { switch (dwReason) { default: return TRUE; } } int GenUSB_Hello (char * buff, int len) { CHAR ret[] = "Hello\n"; ULONG length = (sizeof (ret) < len) ? sizeof (ret) : len; CopyMemory (buff, ret, length); return sizeof (ret); } void __stdcall GenUSB_GetDeviceInterfaceGuid ( OUT LPGUID Guid ) /*++ Routine Description: Please see hidsdi.h for explination Notes: --*/ { *Guid = GUID_DEVINTERFACE_GENUSB; } BOOL __stdcall GenUSB_GetCapabilities ( IN HANDLE GenUSBDeviceObject, OUT PGENUSB_CAPABILITIES Capabilities ) /*++ Routine Description: please see gusb.h for explination Notes: --*/ { ULONG bytes; return DeviceIoControl (GenUSBDeviceObject, IOCTL_GENUSB_GET_CAPS, 0, 0, Capabilities, sizeof (GENUSB_CAPABILITIES), &bytes, NULL); } BOOL __stdcall GenUSB_GetDeviceDescriptor ( IN HANDLE GenUSBDeviceObject, OUT PUSB_DEVICE_DESCRIPTOR Descriptor, IN ULONG DescriptorLength ) /*++ Routine Description: please see gusb.h for explination Notes: --*/ { ULONG bytes; return DeviceIoControl (GenUSBDeviceObject, IOCTL_GENUSB_GET_DEVICE_DESCRIPTOR, 0, 0, Descriptor, DescriptorLength, &bytes, NULL); } BOOL __stdcall GenUSB_GetConfigurationInformation ( IN HANDLE GenUSBDeviceObject, OUT PUSB_CONFIGURATION_DESCRIPTOR Descriptor, IN ULONG DescriptorLength ) /*++ Routine Description: please see gusb.h for explination Notes: --*/ { ULONG bytes; return DeviceIoControl (GenUSBDeviceObject, IOCTL_GENUSB_GET_CONFIGURATION_DESCRIPTOR, 0, 0, Descriptor, DescriptorLength, &bytes, NULL); } BOOL __stdcall GenUSB_GetStringDescriptor ( IN HANDLE GenUSBDeviceObject, IN UCHAR Recipient, IN UCHAR Index, IN USHORT LanguageId, OUT PUCHAR Descriptor, IN USHORT DescriptorLength ) /*++ Routine Description: please see gusb.h for explination Notes: --*/ { ULONG bytes; GENUSB_GET_STRING_DESCRIPTOR getString; getString.Recipient = Recipient; getString.Index = Index; getString.LanguageId = LanguageId; return DeviceIoControl (GenUSBDeviceObject, IOCTL_GENUSB_GET_STRING_DESCRIPTOR, &getString, sizeof (GENUSB_GET_STRING_DESCRIPTOR), Descriptor, DescriptorLength, &bytes, NULL); } BOOL __stdcall GenUSB_DefaultControlRequest ( IN HANDLE GenUSBDeviceObject, IN UCHAR RequestType, IN UCHAR Request, IN USHORT Value, IN USHORT Index, IN OUT PGENUSB_REQUEST_RESULTS Result, IN USHORT BufferLength ) /*++ Routine Description: please see gusb.h for explination Notes: --*/ { ULONG bytes; GENUSB_GET_REQUEST getReq; BOOL result; getReq.RequestType = RequestType; getReq.Request = Request; getReq.Value = Value; getReq.Index = Index; if (BufferLength < sizeof (GENUSB_REQUEST_RESULTS)) { SetLastError (ERROR_INSUFFICIENT_BUFFER); return FALSE; } return DeviceIoControl (GenUSBDeviceObject, IOCTL_GENUSB_GET_REQUEST, &getReq, sizeof (GENUSB_GET_REQUEST), Result, BufferLength, &bytes, NULL); } BOOL __stdcall GenUSB_SelectConfiguration ( IN HANDLE GenUSBDeviceObject, IN UCHAR RequestedNumberInterfaces, IN USB_INTERFACE_DESCRIPTOR RequestedInterfaces[], OUT PUCHAR FoundNumberInterfaces, OUT USB_INTERFACE_DESCRIPTOR FoundInterfaces[] ) { ULONG i; ULONG size; ULONG bytes; PGENUSB_SELECT_CONFIGURATION select; size = sizeof (GENUSB_SELECT_CONFIGURATION) + (sizeof (USB_INTERFACE_DESCRIPTOR) * RequestedNumberInterfaces); select = malloc (size); if (NULL == select) { SetLastError (ERROR_NOT_ENOUGH_MEMORY); return FALSE; } select->NumberInterfaces = RequestedNumberInterfaces; for (i=0; i < RequestedNumberInterfaces; i++) { select->Interfaces[i] = RequestedInterfaces[i]; } if (!DeviceIoControl (GenUSBDeviceObject, IOCTL_GENUSB_SELECT_CONFIGURATION, select, size, select, size, &bytes, NULL)) { free (select); return FALSE; } *FoundNumberInterfaces = select->NumberInterfaces; for (i=0; i < *FoundNumberInterfaces; i++) { FoundInterfaces[i] = select->Interfaces[i]; } free (select); return TRUE; } BOOL __stdcall GenUSB_DeselectConfiguration ( IN HANDLE GenUSBDeviceObject ) { ULONG bytes; return DeviceIoControl (GenUSBDeviceObject, IOCTL_GENUSB_DESELECT_CONFIGURATION, NULL, 0, NULL, 0, &bytes, NULL); } BOOL __stdcall GenUSB_GetPipeInformation ( IN HANDLE GenUSBDeviceObject, IN UCHAR InterfaceNumber, IN UCHAR EndpointAddress, OUT PUSBD_PIPE_INFORMATION PipeInformation ) { ULONG bytes; BOOL result; GENUSB_PIPE_INFORMATION pipeInfo; GENUSB_PIPE_INFO_REQUEST pipeReq; pipeReq.InterfaceNumber = InterfaceNumber; pipeReq.EndpointAddress = EndpointAddress; RtlZeroMemory (&pipeInfo, sizeof (GENUSB_PIPE_INFORMATION)); result = DeviceIoControl (GenUSBDeviceObject, IOCTL_GENUSB_GET_PIPE_INFO, &pipeReq, sizeof (GENUSB_PIPE_INFO_REQUEST), &pipeInfo, sizeof (GENUSB_PIPE_INFORMATION), &bytes, NULL); PipeInformation->MaximumPacketSize = pipeInfo.MaximumPacketSize; PipeInformation->EndpointAddress = pipeInfo.EndpointAddress; PipeInformation->Interval = pipeInfo.Interval; PipeInformation->PipeType = pipeInfo.PipeType; PipeInformation->MaximumTransferSize = pipeInfo.MaximumTransferSize; PipeInformation->PipeFlags = pipeInfo.PipeFlags; // // We are retrieving an ulong from kernel mode, but for simplicity // we pass back a USBD_PIPE_HANDLE, which happens to be a PVOID. // PipeInformation->PipeHandle = (PVOID) (ULONG_PTR) pipeInfo.PipeHandle; return result; } BOOL __stdcall GenUSB_GetPipeProperties ( IN HANDLE GenUSBDeviceObject, IN USBD_PIPE_HANDLE PipeHandle, OUT PGENUSB_PIPE_PROPERTIES Properties ) { ULONG bytes; ULONG ulongPipeHandle; ulongPipeHandle = (GENUSB_PIPE_HANDLE) (ULONG_PTR) PipeHandle; return DeviceIoControl (GenUSBDeviceObject, IOCTL_GENUSB_GET_PIPE_PROPERTIES, &ulongPipeHandle, sizeof (ULONG), Properties, sizeof (GENUSB_PIPE_PROPERTIES), &bytes, NULL); } BOOL __stdcall GenUSB_SetPipeProperties ( IN HANDLE GenUSBDeviceObject, IN USBD_PIPE_HANDLE PipeHandle, IN PGENUSB_PIPE_PROPERTIES Properties ) { ULONG bytes; struct { ULONG PipeHandle; GENUSB_PIPE_PROPERTIES Properties; } data; data.PipeHandle = (GENUSB_PIPE_HANDLE) (ULONG_PTR) PipeHandle; data.Properties = *Properties; return DeviceIoControl (GenUSBDeviceObject, IOCTL_GENUSB_SET_PIPE_PROPERTIES, &data, sizeof (data), NULL, 0, &bytes, NULL); } BOOL __stdcall GenUSB_ResetPipe ( IN HANDLE GenUSBDeviceObject, IN USBD_PIPE_HANDLE PipeHandle, IN BOOL ResetPipe, IN BOOL ClearStall, IN BOOL FlushData ) { GENUSB_RESET_PIPE reset; ULONG bytes; reset.Pipe = (GENUSB_PIPE_HANDLE) (ULONG_PTR) PipeHandle; reset.ResetPipe = (ResetPipe ? TRUE : FALSE); reset.ClearStall = (ClearStall ? TRUE : FALSE); reset.FlushData = (FlushData ? TRUE : FALSE); return DeviceIoControl (GenUSBDeviceObject, IOCTL_GENUSB_RESET_PIPE, &reset, sizeof (reset), NULL, 0, &bytes, NULL); } BOOL __stdcall GenUSB_SetReadWritePipes ( IN HANDLE GenUSBDeviceObject, IN USBD_PIPE_HANDLE ReadPipe, IN USBD_PIPE_HANDLE WritePipe ) { ULONG bytes; GENUSB_SET_READ_WRITE_PIPES pipes; pipes.ReadPipe = (GENUSB_PIPE_HANDLE) (ULONG_PTR) ReadPipe; pipes.WritePipe = (GENUSB_PIPE_HANDLE) (ULONG_PTR) WritePipe; return DeviceIoControl (GenUSBDeviceObject, IOCTL_GENUSB_SET_READ_WRITE_PIPES, &pipes, sizeof (GENUSB_SET_READ_WRITE_PIPES), NULL, 0, &bytes, NULL); } BOOL __stdcall GenUSB_ReadPipe ( IN HANDLE GenUSBDeviceObject, IN USBD_PIPE_HANDLE Pipe, IN BOOL ShortTransferOk, IN PVOID Buffer, IN ULONG RequestedBufferLength, OUT PULONG ReturnedBufferLength, OUT USBD_STATUS * UrbStatus ) { ULONG bytes; BOOL result; GENUSB_READ_WRITE_PIPE transfer; transfer.Pipe = (GENUSB_PIPE_HANDLE) (ULONG_PTR) Pipe; transfer.UsbdTransferFlags = USBD_TRANSFER_DIRECTION_IN | (ShortTransferOk ? USBD_SHORT_TRANSFER_OK : 0); transfer.UrbStatus = USBD_STATUS_SUCCESS; transfer.BufferLength = RequestedBufferLength; // Junk is a union with UserBuffer, which initializes the upper bits in // case we are calling a 64 bit kernel with a 32 bit user mode dll. transfer.Junk = 0; transfer.UserBuffer = Buffer; *ReturnedBufferLength = 0; *UrbStatus = 0; result = DeviceIoControl (GenUSBDeviceObject, IOCTL_GENUSB_READ_WRITE_PIPE, &transfer, sizeof (GENUSB_READ_WRITE_PIPE), NULL, 0, &bytes, NULL); *ReturnedBufferLength = transfer.BufferLength; *UrbStatus= transfer.UrbStatus; return result; } BOOL __stdcall GenUSB_WritePipe ( IN HANDLE GenUSBDeviceObject, IN USBD_PIPE_HANDLE Pipe, IN BOOL ShortTransferOk, IN PVOID Buffer, IN ULONG RequestedBufferLength, OUT PULONG ReturnedBufferLength, OUT USBD_STATUS * UrbStatus ) { ULONG bytes; BOOL result; GENUSB_READ_WRITE_PIPE transfer; transfer.Pipe = (GENUSB_PIPE_HANDLE) (ULONG_PTR) Pipe; transfer.UsbdTransferFlags = USBD_TRANSFER_DIRECTION_OUT | (ShortTransferOk ? USBD_SHORT_TRANSFER_OK : 0); transfer.UrbStatus = USBD_STATUS_SUCCESS; transfer.BufferLength = RequestedBufferLength; // Junk is a union with UserBuffer, which initializes the upper bits in // case we are calling a 64 bit kernel with a 32 bit user mode dll. transfer.Junk = 0; transfer.UserBuffer = Buffer; *ReturnedBufferLength = 0; *UrbStatus = 0; result = DeviceIoControl (GenUSBDeviceObject, IOCTL_GENUSB_READ_WRITE_PIPE, &transfer, sizeof (GENUSB_READ_WRITE_PIPE), NULL, 0, &bytes, NULL); *ReturnedBufferLength = transfer.BufferLength; *UrbStatus= transfer.UrbStatus; return result; }