diff --git a/win32/CMakeLists.txt b/win32/CMakeLists.txt index 408ef72..85bfaa6 100644 --- a/win32/CMakeLists.txt +++ b/win32/CMakeLists.txt @@ -41,8 +41,8 @@ if (HAVE_SDCMDD) add_definitions(-DHAS_SDCMDD) endif () -set(PLATFORM_SOURCES "win32.h" network.c hello.c "win32.c" list_devices.c ata.c device.c ieee1394.c pcmcia.c scsi.c sdhci.c usb.c ntioctl.h) +set(PLATFORM_SOURCES "win32.h" network.c hello.c "win32.c" list_devices.c ata.c device.c ieee1394.c pcmcia.c scsi.c sdhci.c usb.h usb.c ntioctl.h) add_executable(dicremote ${PLATFORM_SOURCES}) -target_link_libraries(dicremote dicremotecore ws2_32 iphlpapi version) \ No newline at end of file +target_link_libraries(dicremote dicremotecore ws2_32 iphlpapi version setupapi cfgmgr32) \ No newline at end of file diff --git a/win32/usb.c b/win32/usb.c index 2d95829..edafa5c 100644 --- a/win32/usb.c +++ b/win32/usb.c @@ -15,9 +15,588 @@ * along with this program. If not, see . */ +#include "usb.h" + #include "win32.h" +#include +#include +#include #include +#include +#include + +#ifndef DIGCF_PRESENT +#define DIGCF_PRESENT 0x00000002 +#endif +#ifndef DIGCF_DEVICEINTERFACE +#define DIGCF_DEVICEINTERFACE 0x00000010 +#endif + +UsbController_t* GetHostControllers(DWORD* length) +{ + GUID hostGuid = GUID_DEVINTERFACE_USB_HOST_CONTROLLER; + HDEVINFO h; + UsbController_t* hostlist; + UsbController_t* host; + DWORD i; + BOOL success; + SP_DEVICE_INTERFACE_DATA dia; + SP_DEVINFO_DATA da; + PSP_DEVICE_INTERFACE_DETAIL_DATA didd; + DWORD nRequiredSize = 0; + DWORD N_BYTES = USB_BUFFER_SIZE; + DWORD requiredSize; + DWORD regType; + CHAR ptrBuf[USB_BUFFER_SIZE]; + + *length = 0; + + didd = malloc(sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + USB_BUFFER_SIZE); + + hostlist = malloc(sizeof(UsbController_t) * 64); + if(!hostlist) return NULL; + + memset(hostlist, 0, sizeof(UsbController_t) * 64); + + // We start at the "root" of the device tree and look for all + // devices that match the interface GUID of a Hub Controller + h = SetupDiGetClassDevs(&hostGuid, 0, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); + + if(h == INVALID_HANDLE_VALUE) return NULL; + + i = 0; + + do + { + host = &hostlist[*length]; + memset(host, 0, sizeof(UsbController_t)); + host->ControllerIndex = i; + + // create a Device Interface Data structure + memset(&dia, 0, sizeof(SP_DEVICE_INTERFACE_DATA)); + dia.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + + // start the enumeration + success = SetupDiEnumDeviceInterfaces(h, NULL, &hostGuid, i, &dia); + if(success) + { + // build a DevInfo Data structure + memset(&da, 0, sizeof(SP_DEVINFO_DATA)); + da.cbSize = sizeof(SP_DEVINFO_DATA); + // build a Device Interface Detail Data structure + memset(didd, 0, USB_BUFFER_SIZE + sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA)); + didd->cbSize = 4 + sizeof(TCHAR); + + // now we can get some more detailed information + nRequiredSize = 0; + if(SetupDiGetDeviceInterfaceDetail(h, &dia, didd, N_BYTES, &nRequiredSize, &da)) + { + strncpy(host->ControllerDevicePath, didd->DevicePath, USB_BUFFER_SIZE); + + // get the Device Description and DriverKeyName + requiredSize = 0; + regType = REG_SZ; + + if(SetupDiGetDeviceRegistryProperty( + h, &da, SPDRP_DEVICEDESC, ®Type, (PBYTE)ptrBuf, USB_BUFFER_SIZE, &requiredSize)) + strncpy(host->ControllerDeviceDesc, ptrBuf, USB_BUFFER_SIZE); + if(SetupDiGetDeviceRegistryProperty( + h, &da, SPDRP_DRIVER, ®Type, (PBYTE)ptrBuf, USB_BUFFER_SIZE, &requiredSize)) + strncpy(host->ControllerDriverKeyName, ptrBuf, USB_BUFFER_SIZE); + } + + (*length)++; + } + + i++; + } while(success); + + SetupDiDestroyDeviceInfoList(h); + + return hostlist; +} + +DWORD GetDeviceNumberWithHandle(HANDLE handle) +{ + STORAGE_DEVICE_NUMBER sdn; + DWORD ans = -1; + DWORD k = 0; + + if(DeviceIoControl(handle, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(STORAGE_DEVICE_NUMBER), &k, NULL)) + { ans = (sdn.DeviceType << 8) + sdn.DeviceNumber; } + + return ans; +} + +DWORD GetDeviceNumber(char* devicePath) +{ + DWORD len = strlen(devicePath); + HANDLE h; + DWORD ans = -1; + + if(devicePath[len - 1] == '\\') devicePath[len - 1] = 0; + + h = CreateFile(devicePath, 0, 0, NULL, OPEN_EXISTING, 0, NULL); + + if(h != INVALID_HANDLE_VALUE) + { + ans = GetDeviceNumberWithHandle(h); + CloseHandle(h); + } + + return ans; +} + +UsbHub_t* GetRootHub(UsbController_t* controller) +{ + HANDLE h, h2; + UsbHub_t* root; + PUSB_ROOT_HUB_NAME hubName; + DWORD nBytes; + DWORD k = 0; + USB_NODE_INFORMATION nodeInfo; + + root = malloc(sizeof(UsbHub_t)); + hubName = malloc(sizeof(USB_ROOT_HUB_NAME) + USB_BUFFER_SIZE - 1); + + if(!root) return NULL; + + root->HubIsRootHub = TRUE; + strncpy(root->HubDeviceDesc, "Root Hub", 8); + + // Open a handle to the Host Controller + h = CreateFile(controller->ControllerDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + + if(h == INVALID_HANDLE_VALUE) return root; + + memset(&hubName, 0, sizeof(USB_ROOT_HUB_NAME) + USB_BUFFER_SIZE - 1); + nBytes = sizeof(USB_ROOT_HUB_NAME) + USB_BUFFER_SIZE - 1; + + // get the Hub Name + if(DeviceIoControl(h, IOCTL_USB_GET_ROOT_HUB_NAME, &hubName, nBytes, &hubName, nBytes, &k, NULL)) + { snprintf(root->HubDevicePath, USB_BUFFER_SIZE, "\\\\.\\%ws", hubName->RootHubName); } + + // TODO: Get DriverKeyName for Root Hub + + // Now let's open the Hub (based upon the HubName we got above) + h2 = CreateFile(root->HubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if(h2 != INVALID_HANDLE_VALUE) + { + memset(&nodeInfo, 0, sizeof(USB_NODE_INFORMATION)); + nodeInfo.NodeType = UsbHub; + + nBytes = sizeof(USB_NODE_INFORMATION); + + // get the Hub Information + if(DeviceIoControl(h2, IOCTL_USB_GET_NODE_INFORMATION, &nodeInfo, nBytes, &nodeInfo, nBytes, &k, NULL)) + { + root->HubIsBusPowered = nodeInfo.u.HubInformation.HubIsBusPowered; + root->HubPortCount = nodeInfo.u.HubInformation.HubDescriptor.bNumberOfPorts; + } + + CloseHandle(h2); + } + + free(hubName); + CloseHandle(h); + return root; +} + +UsbPort_t* GetHubPorts(UsbHub_t* hub, DWORD* length) +{ + UsbPort_t* portList; + UsbPort_t* port; + HANDLE h; + USB_NODE_CONNECTION_INFORMATION_EX nodeConnection; + DWORD nBytes; + DWORD k = 0; + DWORD i; + + *length = 0; + + if(hub == NULL) return NULL; + + h = CreateFile(hub->HubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + + if(h == INVALID_HANDLE_VALUE) return NULL; + + portList = malloc(sizeof(UsbPort_t) * hub->HubPortCount); + + if(!portList) return NULL; + + for(i = 1; i <= hub->HubPortCount; i++) + { + nBytes = sizeof(USB_NODE_CONNECTION_INFORMATION_EX); + memset(&nodeConnection, 0, nBytes); + nodeConnection.ConnectionIndex = i; + k = 0; + + if(!DeviceIoControl(h, + IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, + &nodeConnection, + nBytes, + &nodeConnection, + nBytes, + &k, + NULL)) + continue; + + // load up the USBPort class + port = &portList[*length]; + + port->PortPortNumber = i; + strncpy(port->PortHubDevicePath, hub->HubDevicePath, USB_BUFFER_SIZE); + port->PortStatus = nodeConnection.ConnectionStatus; + port->PortSpeed = nodeConnection.Speed; + port->PortIsDeviceConnected = nodeConnection.ConnectionStatus == DeviceConnected; + port->PortIsHub = nodeConnection.DeviceIsHub; + memcpy(&port->PortDeviceDescriptor, &nodeConnection.DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR)); + + // add it to the list + (*length)++; + } + + CloseHandle(h); + return portList; +} + +UsbDevice_t* GetPortDevice(UsbPort_t* port) +{ + UsbDevice_t* device; + HANDLE h; + DWORD nBytesReturned; + DWORD nBytes = USB_BUFFER_SIZE + sizeof(USB_DESCRIPTOR_REQUEST) + sizeof(USB_STRING_DESCRIPTOR); + PUSB_DESCRIPTOR_REQUEST request; + PUSB_STRING_DESCRIPTOR descriptor; + DWORD k; + + if(port == NULL || port->PortIsDeviceConnected) return NULL; + + device = malloc(sizeof(UsbDevice_t)); + request = malloc(nBytes); + + if(!device) return NULL; + + memset(device, 0, sizeof(UsbDevice_t)); + + // Copy over some values from the Port class + device->PortNumber = port->PortPortNumber; + strncpy(device->HubDevicePath, port->PortHubDevicePath, USB_BUFFER_SIZE); + memcpy(&device->DeviceDescriptor, &port->PortDeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR)); + + // Open a handle to the Hub device + h = CreateFile(port->PortHubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if(h == INVALID_HANDLE_VALUE) return device; + + // The iManufacturer, iProduct and iSerialNumber entries in the + // Device Descriptor are really just indexes. So, we have to + // request a String Descriptor to get the values for those strings. + if(port->PortDeviceDescriptor.iManufacturer > 0) + { + memset(request, 0, nBytes); + + request->ConnectionIndex = port->PortPortNumber; + request->SetupPacket.wIndex = 0x409; + request->SetupPacket.wValue = ((USB_STRING_DESCRIPTOR_TYPE << 8) + port->PortDeviceDescriptor.iManufacturer); + request->SetupPacket.wLength = nBytes - sizeof(USB_DESCRIPTOR_REQUEST); + + // Use an IOCTL call to request the String Descriptor + if(DeviceIoControl( + h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, request, nBytes, request, nBytes, &k, NULL)) + { + // The location of the string descriptor is immediately after + // the Request structure. Because this location is not "covered" + // by the structure allocation, we're forced to zero out this + // chunk of memory by using the StringToHGlobalAuto() hack above + descriptor = (PUSB_STRING_DESCRIPTOR)(request + sizeof(USB_DESCRIPTOR_REQUEST)); + snprintf(device->Manufacturer, USB_BUFFER_SIZE, "%ws", descriptor->bString); + } + } + if(port->PortDeviceDescriptor.iProduct > 0) + { + memset(request, 0, nBytes); + + request->ConnectionIndex = port->PortPortNumber; + request->SetupPacket.wIndex = 0x409; + request->SetupPacket.wValue = ((USB_STRING_DESCRIPTOR_TYPE << 8) + port->PortDeviceDescriptor.iProduct); + request->SetupPacket.wLength = nBytes - sizeof(USB_DESCRIPTOR_REQUEST); + + // Use an IOCTL call to request the String Descriptor + if(DeviceIoControl( + h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, request, nBytes, request, nBytes, &k, NULL)) + { + // The location of the string descriptor is immediately after + // the Request structure. Because this location is not "covered" + // by the structure allocation, we're forced to zero out this + // chunk of memory by using the StringToHGlobalAuto() hack above + descriptor = (PUSB_STRING_DESCRIPTOR)(request + sizeof(USB_DESCRIPTOR_REQUEST)); + snprintf(device->Product, USB_BUFFER_SIZE, "%ws", descriptor->bString); + } + } + if(port->PortDeviceDescriptor.iSerialNumber > 0) + { + memset(request, 0, nBytes); + + request->ConnectionIndex = port->PortPortNumber; + request->SetupPacket.wIndex = 0x409; + request->SetupPacket.wValue = ((USB_STRING_DESCRIPTOR_TYPE << 8) + port->PortDeviceDescriptor.iSerialNumber); + request->SetupPacket.wLength = nBytes - sizeof(USB_DESCRIPTOR_REQUEST); + + // Use an IOCTL call to request the String Descriptor + if(DeviceIoControl( + h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, request, nBytes, request, nBytes, &k, NULL)) + { + // The location of the string descriptor is immediately after + // the Request structure. Because this location is not "covered" + // by the structure allocation, we're forced to zero out this + // chunk of memory by using the StringToHGlobalAuto() hack above + descriptor = (PUSB_STRING_DESCRIPTOR)(request + sizeof(USB_DESCRIPTOR_REQUEST)); + snprintf(device->SerialNumber, USB_BUFFER_SIZE, "%ws", descriptor->bString); + } + } + + // build a request for configuration descriptor + memset(request, 0, nBytes); + + request->ConnectionIndex = port->PortPortNumber; + request->SetupPacket.wIndex = 0; + request->SetupPacket.wValue = ((USB_STRING_DESCRIPTOR_TYPE << 8)); + request->SetupPacket.wLength = nBytes - sizeof(USB_DESCRIPTOR_REQUEST); + + // Use an IOCTL call to request the String Descriptor + if(DeviceIoControl( + h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, request, nBytes, request, nBytes, &nBytesReturned, NULL)) + { + if(nBytesReturned > USB_BUFFER_SIZE) nBytesReturned = USB_BUFFER_SIZE; + + memcpy(&device->BinaryDeviceDescriptors, request + sizeof(USB_DESCRIPTOR_REQUEST), nBytesReturned); + device->BinaryDeviceDescriptorsLength = nBytesReturned; + } + + free(request); + CloseHandle(h); + return device; +} + +UsbHub_t* GetPortHub(UsbPort_t* port) +{ + UsbHub_t* hub; + HANDLE h, h2; + PUSB_NODE_CONNECTION_NAME nodeName; + DWORD nBytes; + DWORD k = 0; + USB_NODE_INFORMATION nodeInfo; + UsbDevice_t* device; + + nodeName = malloc(sizeof(USB_NODE_CONNECTION_NAME) + USB_BUFFER_SIZE - 1); + + if(port == NULL || port->PortIsHub || nodeName == NULL) return NULL; + + hub = malloc(sizeof(UsbHub_t)); + + if(!hub) return NULL; + + hub->HubIsRootHub = FALSE; + strncpy(hub->HubDeviceDesc, "External Hub", 12); + + // Open a handle to the Host Controller + h = CreateFile(port->PortHubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if(h == INVALID_HANDLE_VALUE) + { + free(nodeName); + return hub; + } + + // Get the DevicePath for downstream hub + nBytes = sizeof(USB_NODE_CONNECTION_NAME) + USB_BUFFER_SIZE - 1; + memset(nodeName, 0, nBytes); + nodeName->ConnectionIndex = port->PortPortNumber; + k = 0; + + // Use an IOCTL call to request the Node Name + if(DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_NAME, nodeName, nBytes, nodeName, nBytes, &k, NULL)) + { snprintf(hub->HubDevicePath, USB_BUFFER_SIZE, "\\\\.\\%ws", nodeName->NodeName); } + + // Now let's open the Hub (based upon the HubName we got above) + h2 = CreateFile(hub->HubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + + if(h2 != INVALID_HANDLE_VALUE) + { + memset(&nodeInfo, 0, sizeof(USB_NODE_INFORMATION)); + nodeInfo.NodeType = UsbHub; + nBytes = sizeof(USB_NODE_INFORMATION); + k = 0; + + // get the Hub Information + if(DeviceIoControl(h2, IOCTL_USB_GET_NODE_INFORMATION, &nodeInfo, nBytes, &nodeInfo, nBytes, &k, NULL)) + { + hub->HubIsBusPowered = nodeInfo.u.HubInformation.HubIsBusPowered; + hub->HubPortCount = nodeInfo.u.HubInformation.HubDescriptor.bNumberOfPorts; + } + + CloseHandle(h2); + } + + // Fill in the missing Manufacture, Product, and SerialNumber values + // values by just creating a Device instance and copying the values + device = GetPortDevice(port); + if(device != NULL) + { + strncpy(hub->InstanceId, device->InstanceId, USB_BUFFER_SIZE); + strncpy(hub->Manufacturer, device->Manufacturer, USB_BUFFER_SIZE); + strncpy(hub->Product, device->Product, USB_BUFFER_SIZE); + strncpy(hub->SerialNumber, device->SerialNumber, USB_BUFFER_SIZE); + strncpy(hub->DriverKey, device->DriverKey, USB_BUFFER_SIZE); + free(device); + } + + CloseHandle(h); + return hub; +} + +static void SearchHubInstanceId(UsbHub_t* hub, UsbDevice_t** foundDevice, const char* instanceId) +{ + UsbPort_t* portList; + DWORD portCount = 0; + DWORD i; + UsbDevice_t* device; + UsbHub_t* childHub; + *foundDevice = NULL; + + if(hub == NULL) return; + + portList = GetHubPorts(hub, &portCount); + + if(portList == NULL || portCount == 0) return; + + for(i = 0; i < portCount; i++) + { + if(portList[i].PortIsHub) + { + childHub = GetPortHub(&portList[i]); + + if(childHub == NULL) continue; + + SearchHubInstanceId(childHub, foundDevice, instanceId); + + free(childHub); + } + else + { + if(!portList[i].PortIsDeviceConnected) continue; + + device = GetPortDevice(&portList[i]); + if(device == NULL || strncmp(device->InstanceId, instanceId, USB_BUFFER_SIZE) != 0) continue; + + *foundDevice = device; + break; + } + } + + free(portList); +} + +UsbDevice_t* FindDeviceByInstanceId(const char* instanceId) +{ + UsbController_t* controllers; + DWORD controllers_len = 0; + DWORD i; + UsbDevice_t* foundDevice = NULL; + + controllers = GetHostControllers(&controllers_len); + + if(controllers == NULL || controllers_len == 0) return NULL; + + for(i = 0; i < controllers_len; i++) + { + SearchHubInstanceId(GetRootHub(&controllers[i]), &foundDevice, instanceId); + if(foundDevice != NULL) break; + } + + return foundDevice; +} + +UsbDevice_t* FindDeviceNumber(DWORD devNum, GUID diskGuid) +{ + HDEVINFO h; + BOOL success; + DWORD i = 0; + SP_DEVICE_INTERFACE_DATA dia; + SP_DEVINFO_DATA da; + PSP_DEVICE_INTERFACE_DETAIL_DATA didd; + DWORD nRequiredSize = 0; + DWORD N_BYTES = USB_BUFFER_SIZE; + DEVINST ptrPrevious; + PSTR instanceId = malloc(N_BYTES); + UsbDevice_t* foundDevice = NULL; // TODO: Determine type + + didd = malloc(USB_BUFFER_SIZE + sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA)); + if(instanceId) return NULL; + + memset(instanceId, 0, N_BYTES); + + // We start at the "root" of the device tree and look for all + // devices that match the interface GUID of a disk + h = SetupDiGetClassDevs(&diskGuid, 0, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); + + if(h != INVALID_HANDLE_VALUE) + { + do + { + // create a Device Interface Data structure + memset(&dia, 0, sizeof(SP_DEVICE_INTERFACE_DATA)); + dia.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + + // start the enumeration + success = SetupDiEnumDeviceInterfaces(h, NULL, &diskGuid, i, &dia); + if(success) + { + // build a DevInfo Data structure + memset(&da, 0, sizeof(SP_DEVINFO_DATA)); + da.cbSize = sizeof(SP_DEVINFO_DATA); + + // build a Device Interface Detail Data structure + memset(didd, 0, USB_BUFFER_SIZE + sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA)); + didd->cbSize = 4 + sizeof(TCHAR); + + // now we can get some more detailed information + nRequiredSize = 0; + + if(SetupDiGetDeviceInterfaceDetail(h, &dia, didd, N_BYTES, &nRequiredSize, &da)) + if(GetDeviceNumber(didd->DevicePath) == devNum) + { + // current InstanceID is at the "USBSTOR" level, so we + // need up "move up" one level to get to the "USB" level + CM_Get_Parent(&ptrPrevious, da.DevInst, 0); + + // Now we get the InstanceID of the USB level device + memset(instanceId, 0, N_BYTES); + CM_Get_Device_ID(ptrPrevious, instanceId, N_BYTES, 0); + } + } + + i++; + } while(success); + + SetupDiDestroyClassImageList(h); + } + + // Did we find an InterfaceID of a USB device? + if(strlen(instanceId) > 0 && strncmp(instanceId, "USB\\", 3) == 0) foundDevice = FindDeviceByInstanceId(instanceId); + + free(didd); + return foundDevice; +} + +UsbDevice_t* FindDrivePath(Win32DeviceContext* ctx, GUID deviceGuid) +{ + // We start by getting the unique DeviceNumber of the given + // DriveLetter. We'll use this later to find a matching + // DevicePath "symbolic name" + DWORD devNum = GetDeviceNumber(ctx->handle); + return devNum < 0 ? NULL : FindDeviceNumber(devNum, deviceGuid); +} uint8_t Win32GetUsbData(void* device_ctx, uint16_t* desc_len, @@ -28,10 +607,33 @@ uint8_t Win32GetUsbData(void* device_ctx, char* product, char* serial) { - Win32DeviceContext* ctx = device_ctx; + Win32DeviceContext* ctx = device_ctx; + UsbDevice_t* device = NULL; + GUID floppyGuid = GUID_DEVINTERFACE_FLOPPY; + GUID tapeGuid = GUID_DEVINTERFACE_TAPE; + GUID diskGuid = GUID_DEVINTERFACE_DISK; + GUID cdromGuid = GUID_DEVINTERFACE_CDROM; + GUID guids[4] = {floppyGuid, cdromGuid, diskGuid, tapeGuid}; + int i; if(!ctx) return -1; - // TODO: Implement - return -1; -} + for(i = 0; i < 4; i++) + { + device = FindDrivePath(ctx, guids[i]); + + if(device != NULL) break; + } + + if(device == NULL) return 0; + + memcpy(descriptors, device->BinaryDeviceDescriptors, device->BinaryDeviceDescriptorsLength); + *desc_len = device->BinaryDeviceDescriptorsLength; + *id_vendor = device->DeviceDescriptor.idVendor; + *id_product = device->DeviceDescriptor.idProduct; + strncpy(manufacturer, device->Manufacturer, 256); + strncpy(product, device->Product, 256); + strncpy(serial, device->SerialNumber, 256); + + return 1; +} \ No newline at end of file diff --git a/win32/usb.h b/win32/usb.h new file mode 100644 index 0000000..000bd92 --- /dev/null +++ b/win32/usb.h @@ -0,0 +1,76 @@ +/* + * This file is part of the DiscImageChef Remote Server. + * Copyright (c) 2019 Natalia Portillo. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#define USB_BUFFER_SIZE 2048 + +#include +#include +#include + +#ifndef GUID_DEVINTERFACE_USB_HOST_CONTROLLER +#define GUID_DEVINTERFACE_USB_HOST_CONTROLLER \ + { \ + 0x3abf6f2d, 0x71c4, 0x462a, { 0x8a, 0x92, 0x1e, 0x68, 0x61, 0xe6, 0xaf, 0x27 } \ + } +#endif + +typedef struct +{ + DWORD ControllerIndex; + CHAR ControllerDevicePath[USB_BUFFER_SIZE]; + CHAR ControllerDeviceDesc[USB_BUFFER_SIZE]; + CHAR ControllerDriverKeyName[USB_BUFFER_SIZE]; +} UsbController_t; + +typedef struct +{ + CHAR InstanceId[USB_BUFFER_SIZE]; + CHAR Manufacturer[USB_BUFFER_SIZE]; + CHAR Product[USB_BUFFER_SIZE]; + CHAR SerialNumber[USB_BUFFER_SIZE]; + CHAR DriverKey[USB_BUFFER_SIZE]; + DWORD PortNumber; + USB_DEVICE_DESCRIPTOR DeviceDescriptor; + CHAR HubDevicePath[USB_BUFFER_SIZE]; + CHAR BinaryDeviceDescriptors[USB_BUFFER_SIZE]; + DWORD BinaryDeviceDescriptorsLength; +} UsbDevice_t; + +typedef struct +{ + BOOL HubIsRootHub; + CHAR HubDeviceDesc[USB_BUFFER_SIZE]; + CHAR HubDevicePath[USB_BUFFER_SIZE]; + BOOL HubIsBusPowered; + UCHAR HubPortCount; + CHAR InstanceId[USB_BUFFER_SIZE]; + CHAR Manufacturer[USB_BUFFER_SIZE]; + CHAR Product[USB_BUFFER_SIZE]; + CHAR SerialNumber[USB_BUFFER_SIZE]; + CHAR DriverKey[USB_BUFFER_SIZE]; +} UsbHub_t; + +typedef struct +{ + DWORD PortPortNumber; + CHAR PortHubDevicePath[USB_BUFFER_SIZE]; + DWORD PortStatus; + UCHAR PortSpeed; + BOOL PortIsDeviceConnected; + BOOL PortIsHub; + USB_DEVICE_DESCRIPTOR PortDeviceDescriptor; +} UsbPort_t; \ No newline at end of file