public static void StopDeviceDeviceNotifications(IntPtr deviceNotificationHandle) { if (!DeviceManagement.UnregisterDeviceNotification(deviceNotificationHandle)) { throw APIException.Win32("Failed to unregister device notification"); } }
private unsafe void PipeIOCallback(uint errorCode, uint numBytes, NativeOverlapped *pOverlapped) { try { Exception error = null; if (errorCode != 0) { error = APIException.Win32("Asynchronous operation on WinUSB device failed.", (int)errorCode); } Overlapped overlapped = Overlapped.Unpack(pOverlapped); USBAsyncResult result = (USBAsyncResult)overlapped.AsyncResult; Overlapped.Free(pOverlapped); pOverlapped = null; result.OnCompletion(false, error, (int)numBytes, true); } finally { if (pOverlapped != null) { Overlapped.Unpack(pOverlapped); Overlapped.Free(pOverlapped); } } }
public void OpenDevice(string devicePathName) { try { _deviceHandle = FileIO.CreateFile(devicePathName, (FileIO.GENERIC_WRITE | FileIO.GENERIC_READ), FileIO.FILE_SHARE_READ | FileIO.FILE_SHARE_WRITE, IntPtr.Zero, FileIO.OPEN_EXISTING, FileIO.FILE_ATTRIBUTE_NORMAL | FileIO.FILE_FLAG_OVERLAPPED, 0); if (_deviceHandle.IsInvalid) { throw APIException.Win32("Failed to open WinUSB device handle."); } InitializeDevice(); } catch (Exception) { if (_deviceHandle != null) { _deviceHandle.Dispose(); _deviceHandle = null; } FreeWinUSB(); throw; } }
public void GetInterfaceInfo(int interfaceIndex, out USB_INTERFACE_DESCRIPTOR descriptor, out WINUSB_PIPE_INFORMATION[] pipes) { var pipeList = new List <WINUSB_PIPE_INFORMATION>(); bool success = WinUsb_QueryInterfaceSettings(InterfaceHandle(interfaceIndex), 0, out descriptor); if (!success) { throw APIException.Win32("Failed to get WinUSB device interface descriptor."); } IntPtr interfaceHandle = InterfaceHandle(interfaceIndex); for (byte pipeIdx = 0; pipeIdx < descriptor.bNumEndpoints; pipeIdx++) { WINUSB_PIPE_INFORMATION pipeInfo; success = WinUsb_QueryPipe(interfaceHandle, 0, pipeIdx, out pipeInfo); pipeList.Add(pipeInfo); if (!success) { throw APIException.Win32("Failed to get WinUSB device pipe information."); } } pipes = pipeList.ToArray(); }
public void FlushPipe(int ifaceIndex, byte pipeID) { bool success = WinUsb_FlushPipe(InterfaceHandle(ifaceIndex), pipeID); if (!success) { throw APIException.Win32("Failed to flush pipe on WinUSB device."); } }
public void SetPipePolicy(int ifaceIndex, byte pipeID, POLICY_TYPE policyType, uint value) { bool success = WinUsb_SetPipePolicy(InterfaceHandle(ifaceIndex), pipeID, (uint)policyType, 4, ref value); if (!success) { throw APIException.Win32("Failed to set WinUSB pipe policy."); } }
public static APIException Win32(string message) { return(APIException.Win32(message, Marshal.GetLastWin32Error())); // TEST!! // int ErrorCode = Marshal.GetLastWin32Error(); // if ((ErrorCode & 0xffff) == 0x1f) // ErrorCode = ErrorCode; // Break here // return APIException.Win32(message, ErrorCode); }
public void SetPipePolicy(int ifaceIndex, byte pipeID, POLICY_TYPE policyType, bool value) { byte byteVal = (byte)(value ? 1 : 0); bool success = WinUsb_SetPipePolicy(InterfaceHandle(ifaceIndex), pipeID, (uint)policyType, 1, ref byteVal); if (!success) { throw APIException.Win32("Failed to set WinUSB pipe policy."); } }
public uint GetPipePolicyUInt(int ifaceIndex, byte pipeID, POLICY_TYPE policyType) { uint result; uint length = 4; bool success = WinUsb_GetPipePolicy(InterfaceHandle(ifaceIndex), pipeID, (uint)policyType, ref length, out result); if (!success || length != 4) { throw APIException.Win32("Failed to get WinUSB pipe policy."); } return(result); }
private void InitializeDevice() { bool success; success = WinUsb_Initialize(_deviceHandle, ref _winUsbHandle); if (!success) { throw APIException.Win32("Failed to initialize WinUSB handle. Device might not be connected."); } List <IntPtr> interfaces = new List <IntPtr>(); byte numAddInterfaces = 0; byte idx = 0; try { while (true) { IntPtr ifaceHandle = IntPtr.Zero; success = WinUsb_GetAssociatedInterface(_winUsbHandle, idx, out ifaceHandle); if (!success) { if (Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS) { break; } throw APIException.Win32("Failed to enumerate interfaces for WinUSB device."); } interfaces.Add(ifaceHandle); idx++; numAddInterfaces++; } } finally { // Save interface handles (will be cleaned by Dispose) // also in case of exception (which is why it is in finally block), // because some handles might have already been opened and need // to be disposed. _addInterfaces = interfaces.ToArray(); } // Bind handle (needed for overlapped I/O thread pool) ThreadPool.BindHandle(_deviceHandle); // TODO: bind interface handles as well? doesn't seem to be necessary }
private static byte[] GetProperty(IntPtr deviceInfoSet, SP_DEVINFO_DATA deviceInfoData, SPDRP property, out int regType) { if (!SetupDiGetDeviceRegistryProperty(deviceInfoSet, ref deviceInfoData, property, IntPtr.Zero, IntPtr.Zero, 0, out uint requiredSize) && Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER) { throw APIException.Win32("Failed to get buffer size for device registry property."); } byte[] buffer = new byte[requiredSize]; if (!SetupDiGetDeviceRegistryProperty(deviceInfoSet, ref deviceInfoData, property, out regType, buffer, (uint)buffer.Length, out requiredSize)) { throw APIException.Win32("Failed to get device registry property."); } return(buffer); }
public void ReadPipe(int ifaceIndex, byte pipeID, byte[] buffer, int offset, int bytesToRead, out uint bytesRead) { bool success; unsafe { fixed(byte *pBuffer = buffer) { success = WinUsb_ReadPipe(InterfaceHandle(ifaceIndex), pipeID, pBuffer + offset, (uint)bytesToRead, out bytesRead, IntPtr.Zero); } } if (!success) { throw APIException.Win32("Failed to read pipe on WinUSB device."); } }
public void ControlTransfer(byte requestType, byte request, ushort value, ushort index, ushort length, byte[] data) { uint bytesReturned = 0; WINUSB_SETUP_PACKET setupPacket; setupPacket.RequestType = requestType; setupPacket.Request = request; setupPacket.Value = value; setupPacket.Index = index; setupPacket.Length = length; bool success = WinUsb_ControlTransfer(_winUsbHandle, setupPacket, data, length, ref bytesReturned, IntPtr.Zero); if (!success) // todo check bytes returned? { throw APIException.Win32("Control transfer on WinUSB device failed."); } }
public void WritePipe(int ifaceIndex, byte pipeID, byte[] buffer, int offset, int length) { uint bytesWritten; bool success; unsafe { fixed(byte *pBuffer = buffer) { success = WinUsb_WritePipe(InterfaceHandle(ifaceIndex), pipeID, pBuffer + offset, (uint)length, out bytesWritten, IntPtr.Zero); } } if (!success || (bytesWritten != length)) { throw APIException.Win32("Failed to write pipe on WinUSB device."); } }
public USB_DEVICE_DESCRIPTOR GetDeviceDescriptor() { uint size = (uint)Marshal.SizeOf(typeof(USB_DEVICE_DESCRIPTOR)); bool success = WinUsb_GetDescriptor(_winUsbHandle, USB_DEVICE_DESCRIPTOR_TYPE, 0, 0, out USB_DEVICE_DESCRIPTOR deviceDesc, size, out uint transfered); if (!success) { throw APIException.Win32("Failed to get USB device descriptor."); } if (transfered != size) { throw APIException.Win32("Incomplete USB device descriptor."); } return(deviceDesc); }
public void ReadPipe(int ifaceIndex, byte pipeID, byte[] buffer, int offset, int bytesToRead, out uint bytesRead) { bool success; unsafe { fixed(byte *pBuffer = buffer) { //WPinternals.LogFile.Log("Start WinUSB_ReadPipe"); success = WinUsb_ReadPipe(InterfaceHandle(ifaceIndex), pipeID, pBuffer + offset, (uint)bytesToRead, out bytesRead, IntPtr.Zero); //WPinternals.LogFile.Log("End WinUSB_ReadPipe: " + (success ? "True" : "False")); } } if (!success) { throw APIException.Win32("Failed to read pipe on WinUSB device."); } }
public void WritePipe(int ifaceIndex, byte pipeID, byte[] buffer, int offset, int length) { uint bytesWritten; bool success; unsafe { fixed(byte *pBuffer = buffer) { //WPinternals.LogFile.Log("Start WinUSB_WritePipe"); success = WinUsb_WritePipe(InterfaceHandle(ifaceIndex), pipeID, pBuffer + offset, (uint)length, out bytesWritten, IntPtr.Zero); //WPinternals.LogFile.Log("End WinUSB_WritePipe: " + (success ? "True" : "False")); } } if (!success || (bytesWritten != length)) { throw APIException.Win32("Failed to write pipe on WinUSB device."); } }
public string GetStringDescriptor(byte index) { byte[] buffer = new byte[256]; uint transfered; bool success = WinUsb_GetDescriptor(_winUsbHandle, USB_STRING_DESCRIPTOR_TYPE, index, 0, buffer, (uint)buffer.Length, out transfered); if (!success) { throw APIException.Win32("Failed to get USB string descriptor (" + index + "): 0x" + Marshal.GetLastWin32Error().ToString("X8")); } int length = buffer[0] - 2; if (length <= 0) { return(null); } char[] chars = System.Text.Encoding.Unicode.GetChars(buffer, 2, length); return(new string(chars)); }
private unsafe void HandleOverlappedAPI(bool success, string errorMessage, NativeOverlapped *pOverlapped, USBAsyncResult result, int bytesTransfered) { if (!success) { if (Marshal.GetLastWin32Error() != FileIO.ERROR_IO_PENDING) { Overlapped.Unpack(pOverlapped); Overlapped.Free(pOverlapped); throw APIException.Win32(errorMessage); } } else { // Immediate success! Overlapped.Unpack(pOverlapped); Overlapped.Free(pOverlapped); result.OnCompletion(true, null, bytesTransfered, false); // is the callback still called in this case?? todo } }
//DEFINE_DEVPROPKEY(DEVPKEY_Device_BusReportedDeviceDesc, 0x540b947e, 0x8b40, 0x45bc, 0xa8, 0xa2, 0x6a, 0x0b, 0x89, 0x4c, 0xbd, 0xa2, 4); // DEVPROP_TYPE_STRING //DEFINE_DEVPROPKEY(DEVPKEY_Device_ContainerId, 0x8c7ed206, 0x3f8a, 0x4827, 0xb3, 0xab, 0xae, 0x9e, 0x1f, 0xae, 0xfc, 0x6c, 2); // DEVPROP_TYPE_GUID //DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14); // DEVPROP_TYPE_STRING //DEFINE_DEVPROPKEY(DEVPKEY_DeviceDisplay_Category, 0x78c34fc8, 0x104a, 0x4aca, 0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57, 0x5a); // DEVPROP_TYPE_STRING_LIST //DEFINE_DEVPROPKEY(DEVPKEY_Device_LocationInfo, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 15); // DEVPROP_TYPE_STRING //DEFINE_DEVPROPKEY(DEVPKEY_Device_Manufacturer, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 13); // DEVPROP_TYPE_STRING //DEFINE_DEVPROPKEY(DEVPKEY_Device_SecuritySDS, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 26); // DEVPROP_TYPE_SECURITY_DESCRIPTOR_STRING // Heathcliff74 private static byte[] GetProperty(IntPtr deviceInfoSet, SP_DEVINFO_DATA deviceInfoData, DEVPROPKEY property, out uint propertyType) { int requiredSize; if (!SetupDiGetDeviceProperty(deviceInfoSet, ref deviceInfoData, ref property, out propertyType, null, 0, out requiredSize, 0)) { if (Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER) { throw APIException.Win32("Failed to get buffer size for device registry property."); } } byte[] buffer = new byte[requiredSize]; if (!SetupDiGetDeviceProperty(deviceInfoSet, ref deviceInfoData, ref property, out propertyType, buffer, buffer.Length, out requiredSize, 0)) { throw APIException.Win32("Failed to get device registry property."); } return(buffer); }
public static void RegisterForDeviceNotifications(IntPtr controlHandle, Guid classGuid, ref IntPtr deviceNotificationHandle) { DEV_BROADCAST_DEVICEINTERFACE devBroadcastDeviceInterface = new DEV_BROADCAST_DEVICEINTERFACE(); IntPtr devBroadcastDeviceInterfaceBuffer = IntPtr.Zero; try { int size = Marshal.SizeOf(devBroadcastDeviceInterface); devBroadcastDeviceInterface.dbcc_size = size; devBroadcastDeviceInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; devBroadcastDeviceInterface.dbcc_reserved = 0; devBroadcastDeviceInterface.dbcc_classguid = classGuid; devBroadcastDeviceInterfaceBuffer = Marshal.AllocHGlobal(size); // Copy the DEV_BROADCAST_DEVICEINTERFACE structure to the buffer. // Set fDeleteOld True to prevent memory leaks. Marshal.StructureToPtr(devBroadcastDeviceInterface, devBroadcastDeviceInterfaceBuffer, true); deviceNotificationHandle = RegisterDeviceNotification(controlHandle, devBroadcastDeviceInterfaceBuffer, DEVICE_NOTIFY_WINDOW_HANDLE); if (deviceNotificationHandle == IntPtr.Zero) { throw APIException.Win32("Failed to register device notification"); } // Marshal data from the unmanaged block devBroadcastDeviceInterfaceBuffer to // the managed object devBroadcastDeviceInterface Marshal.PtrToStructure(devBroadcastDeviceInterfaceBuffer, devBroadcastDeviceInterface); } finally { // Free the memory allocated previously by AllocHGlobal. if (devBroadcastDeviceInterfaceBuffer != IntPtr.Zero) { Marshal.FreeHGlobal(devBroadcastDeviceInterfaceBuffer); } } }
private int ReadStringDescriptor(byte index, ushort languageID, byte[] buffer) { uint transfered; bool success = WinUsb_GetDescriptor(_winUsbHandle, USB_STRING_DESCRIPTOR_TYPE, index, languageID, buffer, (uint)buffer.Length, out transfered); if (!success) { throw APIException.Win32("Failed to get USB string descriptor (" + index + ")."); } if (transfered == 0) { throw new APIException("No data returned when reading USB descriptor."); } int length = buffer[0]; if (length != transfered) { throw new APIException("Unexpected length when reading USB descriptor."); } return(length); }
public static APIException Win32(string message) { return(APIException.Win32(message, Marshal.GetLastWin32Error())); }
public static DeviceDetails[] FindDevicesFromGuid(Guid guid) { IntPtr deviceInfoSet = IntPtr.Zero; List <DeviceDetails> deviceList = new List <DeviceDetails>(); try { deviceInfoSet = SetupDiGetClassDevs(ref guid, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (deviceInfoSet == FileIO.INVALID_HANDLE_VALUE) { throw APIException.Win32("Failed to enumerate devices."); } int memberIndex = 0; while (true) { // Begin with 0 and increment through the device information set until // no more devices are available. SP_DEVICE_INTERFACE_DATA deviceInterfaceData = new SP_DEVICE_INTERFACE_DATA(); // The cbSize element of the deviceInterfaceData structure must be set to // the structure's size in bytes. // The size is 28 bytes for 32-bit code and 32 bytes for 64-bit code. deviceInterfaceData.cbSize = Marshal.SizeOf(deviceInterfaceData); bool success; success = SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref guid, memberIndex, ref deviceInterfaceData); // Find out if a device information set was retrieved. if (!success) { int lastError = Marshal.GetLastWin32Error(); if (lastError == ERROR_NO_MORE_ITEMS) { break; } throw APIException.Win32("Failed to get device interface."); } // A device is present. int bufferSize = 0; success = SetupDiGetDeviceInterfaceDetail (deviceInfoSet, ref deviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, IntPtr.Zero); if (!success) { if (Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER) { throw APIException.Win32("Failed to get interface details buffer size."); } } IntPtr detailDataBuffer = IntPtr.Zero; try { // Allocate memory for the SP_DEVICE_INTERFACE_DETAIL_DATA structure using the returned buffer size. detailDataBuffer = Marshal.AllocHGlobal(bufferSize); // Store cbSize in the first bytes of the array. The number of bytes varies with 32- and 64-bit systems. Marshal.WriteInt32(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8); // Call SetupDiGetDeviceInterfaceDetail again. // This time, pass a pointer to DetailDataBuffer // and the returned required buffer size. // build a DevInfo Data structure SP_DEVINFO_DATA da = new SP_DEVINFO_DATA(); da.cbSize = Marshal.SizeOf(da); success = SetupDiGetDeviceInterfaceDetail (deviceInfoSet, ref deviceInterfaceData, detailDataBuffer, bufferSize, ref bufferSize, ref da); if (!success) { throw APIException.Win32("Failed to get device interface details."); } // Skip over cbsize (4 bytes) to get the address of the devicePathName. IntPtr pDevicePathName = new IntPtr(detailDataBuffer.ToInt64() + 4); string pathName = Marshal.PtrToStringUni(pDevicePathName); // Get the String containing the devicePathName. DeviceDetails details = GetDeviceDetails(pathName, deviceInfoSet, da); deviceList.Add(details); } finally { if (detailDataBuffer != IntPtr.Zero) { Marshal.FreeHGlobal(detailDataBuffer); detailDataBuffer = IntPtr.Zero; } } memberIndex++; } } finally { if (deviceInfoSet != IntPtr.Zero && deviceInfoSet != FileIO.INVALID_HANDLE_VALUE) { SetupDiDestroyDeviceInfoList(deviceInfoSet); } } return(deviceList.ToArray()); }