Пример #1
0
        public static bool WriteRawReportToDevice(byte[] outputReportBuffer, ref DeviceInformationStructure deviceInformation)
        {
            // Make sure a device is attached
            if (!deviceInformation.IsDeviceAttached)
            {
                return(false);
            }

            var numberOfBytesWritten = 0;

            try
            {
                // Set an output report via interrupt to the device
                var success = Kernel32.WriteFile(
                    deviceInformation.WriteHandle,
                    outputReportBuffer,
                    outputReportBuffer.Length,
                    ref numberOfBytesWritten,
                    IntPtr.Zero);

                return(success);
            }
            catch (Exception)
            {
                // An error - send out some debug and return failure
                return(false);
            }
        }
Пример #2
0
        public static bool WriteRawReportToDevice(byte[] outputReportBuffer, ref DeviceInformationStructure deviceInformation)
        {
            // Make sure a device is attached
            if (!deviceInformation.IsDeviceAttached)
            {
                Debug.WriteLine("usbGenericHidCommunication:writeReportToDevice(): -> No device attached!");
                return(false);
            }

            var numberOfBytesWritten = 0;

            try
            {
                // Set an output report via interrupt to the device
                var success = Kernel32.WriteFile(
                    deviceInformation.WriteHandle,
                    outputReportBuffer,
                    outputReportBuffer.Length,
                    ref numberOfBytesWritten,
                    IntPtr.Zero);

                Debug.WriteLine(success
                                    ? "usbGenericHidCommunication:writeReportToDevice(): -> Write report succeeded"
                                    : "usbGenericHidCommunication:writeReportToDevice(): -> Write report failed!");
                return(success);
            }
            catch (Exception)
            {
                // An error - send out some debug and return failure
                Debug.WriteLine(
                    "usbGenericHidCommunication:writeReportToDevice(): -> EXCEPTION: When attempting to send an output report");
                return(false);
            }
        }
Пример #3
0
        public static bool FindTargetDevice(ref DeviceInformationStructure deviceInformation)
        {
            deviceInformation.HidHandle   = GetDeviceInformationHidHandle(deviceInformation.DevicePathName);
            deviceInformation.ReadHandle  = GetDeviceInformationReadHandle(deviceInformation.DevicePathName);
            deviceInformation.WriteHandle = GetDeviceInformationWriteHandle(deviceInformation.DevicePathName);

            if (deviceInformation.HidHandle.IsInvalid || deviceInformation.ReadHandle.IsInvalid || deviceInformation.WriteHandle.IsInvalid)
            {
                return(false);
            }

            if (!GetAttributes(ref deviceInformation))
            {
                return(false);
            }

            deviceInformation.DescriptorStrings = GetDescriptionStrings(deviceInformation.HidHandle);

            if (!QueryDeviceCapabilities(ref deviceInformation))
            {
                return(false);
            }

            deviceInformation.IsDeviceAttached = true;

            return(true);
        }
Пример #4
0
        private static bool FindHIDs(DeviceInformationStructure deviceInformation, List <string> InputList, ref List <string> FoundList)
        {
            List <SingleDevice> devices = FindDevices(deviceInformation);

            if (devices.Count > 0)
            {
                foreach (SingleDevice sdev in devices)
                {
                    SingleHID singleHID = new SingleHID(sdev);

                    foreach (string path in InputList)
                    {
                        Match  match = Regex.Match(path, "VID_(.{4})", RegexOptions.IgnoreCase);
                        ushort Vid;
                        if (match.Success)
                        {
                            string vid_string = match.Groups[1].Value;
                            Vid = ushort.Parse(vid_string, System.Globalization.NumberStyles.HexNumber);
                        }
                        else
                        {
                            Vid = 0;
                        }
                        match = Regex.Match(path, "PID_(.{4})", RegexOptions.IgnoreCase);
                        ushort Pid;
                        if (match.Success)
                        {
                            string pid_string = match.Groups[1].Value;
                            Pid = ushort.Parse(pid_string, System.Globalization.NumberStyles.HexNumber);
                        }
                        else
                        {
                            Pid = 0;
                        }
                        match = Regex.Match(path, "MI_(.{2})", RegexOptions.IgnoreCase);
                        ushort MI;
                        if (match.Success)
                        {
                            string mi_string = match.Groups[1].Value;
                            MI = ushort.Parse(mi_string, System.Globalization.NumberStyles.HexNumber);
                        }
                        else
                        {
                            MI = 0;
                        }

                        bool Detected = (Vid == singleHID.Vid) && (Pid == singleHID.Pid) && (MI == singleHID.MI);

                        if (Detected)
                        {
                            FoundList.Add(path);
                            //break;
                            // Matching device found
                            Debug.WriteLine("findTargetDevice() -> Device with matching VID and PID found!");
                        }
                    }
                }
            }
            return(FoundList.Count > 0);
        }
Пример #5
0
        private static bool InitSelectedHID(ref DeviceInformationStructure deviceInformation)
        {
            deviceInformation.IsDeviceAttached = false;
            // Query the HID device's capabilities (primarily we are only really interested in the
            // input and output report byte lengths as this allows us to validate information sent
            // to and from the device does not exceed the devices capabilities.
            //
            // We could determine the 'type' of HID device here too, but since this class is only
            // for generic HID communication we don't care...


            Debug.WriteLine("findTargetDevice() -> Performing CreateFile ");
            deviceInformation.HidHandle = Kernel32.CreateFile(deviceInformation.DevicePathName, 0, Constants.FileShareRead | Constants.FileShareWrite, IntPtr.Zero, Constants.OpenExisting, 0, 0);
            QueryDeviceCapabilities(ref deviceInformation);
            //deviceInformation.HidHandle.Close();

            // Open the readHandle to the device
            Debug.WriteLine("findTargetDevice() -> Opening a readHandle to the device");
            deviceInformation.ReadHandle = Kernel32.CreateFile(
                deviceInformation.DevicePathName,
                Constants.GenericRead,
                Constants.FileShareRead | Constants.FileShareWrite,
                IntPtr.Zero, Constants.OpenExisting,
                Constants.FileFlagOverlapped,
                0);

            // Did we open the readHandle successfully?
            if (deviceInformation.ReadHandle.IsInvalid)
            {
                Debug.WriteLine("findTargetDevice() -> Unable to open a readHandle to the device!");
                //
                deviceInformation.ReadHandle.Close();
                deviceInformation.IsDeviceAttached = false;
                return(deviceInformation.IsDeviceAttached);
            }

            Debug.WriteLine("findTargetDevice() -> Opening a writeHandle to the device");
            deviceInformation.WriteHandle = Kernel32.CreateFile(
                deviceInformation.DevicePathName,
                Constants.GenericWrite,
                Constants.FileShareRead | Constants.FileShareWrite,
                IntPtr.Zero,
                Constants.OpenExisting, 0, 0);

            // Did we open the writeHandle successfully?
            if (deviceInformation.WriteHandle.IsInvalid)
            {
                Debug.WriteLine("findTargetDevice() -> Unable to open a writeHandle to the device!");

                // Attempt to close the writeHandle
                deviceInformation.WriteHandle.Close();
                deviceInformation.IsDeviceAttached = false;
                return(deviceInformation.IsDeviceAttached);
            }

            // Device is now discovered and ready for use, update the status
            deviceInformation.IsDeviceAttached = true;
            return(deviceInformation.IsDeviceAttached);
        }
Пример #6
0
        private static bool CheckDevice(DeviceInformationStructure dev1, SingleHID dev2)
        {
            bool Found = false;

            if (dev1.TargetCaption == dev2.Caption && dev1.TargetProductId == dev2.Pid && dev1.TargetVendorId == dev2.Vid && dev1.TargetMultiInterface == dev2.MI)
            {
                Found = true;
            }
            return(Found);
        }
Пример #7
0
        private static List <SingleDevice> FindDevices(DeviceInformationStructure dev1)
        {
            List <SingleDevice> singleDevices = GetDeviceList();
            List <SingleDevice> FoundDevices  = new List <SingleDevice>();

            foreach (SingleDevice dev2 in singleDevices)
            {
                if (CheckDevice(dev1, new SingleHID(dev2)))
                {
                    FoundDevices.Add(dev2);
                }
            }
            return(FoundDevices);
        }
Пример #8
0
        public static bool ReadSingleReportFromDevice(ref byte[] inputReportBuffer, ref DeviceInformationStructure deviceInformation)
        {
            var numberOfBytesRead = 0;

            // The size of our inputReportBuffer must be at least the same size as the input report.
            if (inputReportBuffer.Length != deviceInformation.Capabilities.InputReportByteLength)
            {
                // inputReportBuffer is not the right length!
                return(false);
            }

            // The readRawReportFromDevice method will fill the passed readBuffer or return false
            return(ReadRawReportFromDevice(ref inputReportBuffer, ref numberOfBytesRead, ref deviceInformation));
        }
Пример #9
0
        public static bool ReadSingleReportFromDevice(ref byte[] inputReportBuffer, ref DeviceInformationStructure deviceInformation)
        {
            var numberOfBytesRead = 0;

            // The size of our inputReportBuffer must be at least the same size as the input report.
            if (inputReportBuffer.Length != deviceInformation.Capabilities.InputReportByteLength)
            {
                // inputReportBuffer is not the right length!
                Debug.WriteLine(
                    "usbGenericHidCommunication:readSingleReportFromDevice(): -> ERROR: The referenced inputReportBuffer size is incorrect for the input report size!");
                return(false);
            }

            // The readRawReportFromDevice method will fill the passed readBuffer or return false
            return(ReadRawReportFromDevice(ref inputReportBuffer, ref numberOfBytesRead, ref deviceInformation));
        }
Пример #10
0
        private static bool GetAttributes(ref DeviceInformationStructure deviceInformation)
        {
            try
            {
                deviceInformation.Attributes.Size = Marshal.SizeOf(deviceInformation.Attributes);

                if (Hid.HidD_GetAttributes(deviceInformation.HidHandle, ref deviceInformation.Attributes))
                {
                    return(true);
                }
            }
            catch
            {
                Debug.WriteLine("GetAttributes failed");
                return(false);
            }
            return(false);
        }
        public static bool WriteRawReportToDevice(byte[] outputReportBuffer, ref DeviceInformationStructure deviceInformation)
        {
            // Make sure a device is attached
            if (!deviceInformation.IsDeviceAttached)
            {
                Debug.WriteLine("DeviceCommunication:writeReportToDevice(): -> 发送失败-设备未连接!");
                return(false);
            }

            var numberOfBytesWritten = 0;

            try
            {
                var success   = false;
                int sendCount = (int)Math.Ceiling(outputReportBuffer.Length / 8.0);
                for (int i = 0; i < sendCount; i++)
                {
                    int    surplusCount = outputReportBuffer.Length - i * 8;
                    byte[] send         = new byte[9];
                    send[0] = 255;
                    int len = surplusCount >= 8 ? 8 : surplusCount;
                    Array.Copy(outputReportBuffer, 8 * i, send, 1, len);
                    success = Kernel32.WriteFile(
                        deviceInformation.WriteHandle,
                        send,
                        deviceInformation.Capabilities.OutputReportByteLength,
                        ref numberOfBytesWritten,
                        IntPtr.Zero);
                }
                // Set an output report via interrupt to the device


                Debug.WriteLine(success
                                    ? "DeviceCommunication:writeReportToDevice(): -> 发送数据成功"
                                    : "DeviceCommunication:writeReportToDevice(): -> 发送失败!错误码:" + Marshal.GetLastWin32Error());
                return(success);
            }
            catch (Exception ex)
            {
                // An error - send out some debug and return failure
                Debug.WriteLine("DeviceCommunication:writeReportToDevice(): -> 发生异常: " + ex.Message);
                return(false);
            }
        }
Пример #12
0
        public static bool FindTargetDevices(ref DeviceInformationStructure deviceInformation, string Path = "")
        {
            Debug.WriteLine("findTargetDevice() -> Method called");
            List <string> listOfDevicePathNames = new List <string>(); // 128 is the maximum number of USB devices allowed on a single host
            bool          isDeviceDetected      = false;
            List <string> DevicePaths           = new List <string>();

            try
            {
                bool deviceFoundByGuid = FindHidDevices(ref listOfDevicePathNames); // Get all the devices with the correct HID GUID

                if (deviceFoundByGuid)
                {
                    isDeviceDetected        = FindHIDs(deviceInformation, listOfDevicePathNames, ref DevicePaths);
                    deviceInformation.Paths = DevicePaths;
                }
                if (Path == "") // take first
                {
                    // Store the device's pathname in the device information
                    deviceInformation.DevicePathName = DevicePaths[0];
                }
                else
                {
                    deviceInformation.DevicePathName = DevicePaths.Find(x => x.Equals(Path));
                }

                // If we found a matching device
                // then open read and write handles to the device to allow communication
                if (isDeviceDetected)
                {
                    InitSelectedHID(ref deviceInformation);
                }

                return(isDeviceDetected);
            }
            catch (Exception)
            {
                Debug.WriteLine("findTargetDevice() -> EXCEPTION: Unknown - device not found");

                return(isDeviceDetected);
            }
        }
Пример #13
0
        public static bool QueryDeviceCapabilities(ref DeviceInformationStructure deviceInformation)
        {
            var preparsedData = new IntPtr();

            try
            {
                Hid.HidD_GetPreparsedData(deviceInformation.HidHandle, ref preparsedData);
                Hid.HidP_GetCaps(preparsedData, ref deviceInformation.Capabilities);
            }
            catch
            {
                Debug.WriteLine("QueryDeviceCapabilities failed with error {0}", Marshal.GetLastWin32Error());
                return(false);
            }
            finally
            {
                // Free up the memory before finishing
                Hid.HidD_FreePreparsedData(preparsedData);
            }
            return(true);
        }
Пример #14
0
        public static bool ReadRawReportFromDevice(ref byte[] inputReportBuffer, ref int numberOfBytesRead, ref DeviceInformationStructure deviceInformation)
        {
            // Make sure a device is attached
            if (!deviceInformation.IsDeviceAttached)
            {
                return(false);
            }

            IntPtr eventObject;
            var    hidOverlapped = new NativeOverlapped();
            IntPtr nonManagedBuffer;
            IntPtr nonManagedOverlapped;

            try
            {
                // Prepare an event object for the overlapped ReadFile
                eventObject = Kernel32.CreateEvent(IntPtr.Zero, false, false, "");

                hidOverlapped.OffsetLow   = 0;
                hidOverlapped.OffsetHigh  = 0;
                hidOverlapped.EventHandle = eventObject;

                // Allocate memory for the unmanaged input buffer and overlap structure.
                nonManagedBuffer     = Marshal.AllocHGlobal(inputReportBuffer.Length);
                nonManagedOverlapped = Marshal.AllocHGlobal(Marshal.SizeOf(hidOverlapped));
                Marshal.StructureToPtr(hidOverlapped, nonManagedOverlapped, false);

                // Read the input report buffer
                var success = Kernel32.ReadFile(
                    deviceInformation.ReadHandle,
                    nonManagedBuffer,
                    inputReportBuffer.Length,
                    ref numberOfBytesRead,
                    nonManagedOverlapped);

                if (!success)
                {
                    // We are now waiting for the FileRead to complete
                    // Wait a maximum of 3 seconds for the FileRead to complete
                    var result = Kernel32.WaitForSingleObject(eventObject, 3000);

                    switch (result)
                    {
                    // Has the ReadFile completed successfully?
                    case Constants.WaitObject0:

                        // Get the number of bytes transferred
                        Kernel32.GetOverlappedResult(deviceInformation.ReadHandle, nonManagedOverlapped, ref numberOfBytesRead, false);
                        break;

                    // Did the FileRead operation timeout?
                    case Constants.WaitTimeout:

                        // Cancel the ReadFile operation
                        Kernel32.CancelIo(deviceInformation.ReadHandle);
                        if (!deviceInformation.HidHandle.IsInvalid)
                        {
                            deviceInformation.HidHandle.Close();
                        }
                        if (!deviceInformation.ReadHandle.IsInvalid)
                        {
                            deviceInformation.ReadHandle.Close();
                        }
                        if (!deviceInformation.WriteHandle.IsInvalid)
                        {
                            deviceInformation.WriteHandle.Close();
                        }

                        // Detach the USB device to try to get us back in a known state
                        //detachUsbDevice();

                        return(false);

                    // Some other unspecified error has occurred?
                    default:

                        // Cancel the ReadFile operation

                        // Detach the USB device to try to get us back in a known state

                        return(false);
                    }
                }
                // Report receieved correctly, copy the unmanaged input buffer over to the managed buffer
                Marshal.Copy(nonManagedBuffer, inputReportBuffer, 0, numberOfBytesRead);
            }
            catch (Exception)
            {
                // An error - send out some debug and return failure
                return(false);
            }

            // Release non-managed objects before returning
            Marshal.FreeHGlobal(nonManagedBuffer);
            Marshal.FreeHGlobal(nonManagedOverlapped);

            // Close the file handle to release the object
            Kernel32.CloseHandle(eventObject);

            return(true);
        }
Пример #15
0
        public static bool ReadRawReportFromDeviceAsync(ref byte[] inputReportBuffer, ref int numberOfBytesRead, ref DeviceInformationStructure deviceInformation)
        {
            bool success;

            // Make sure a device is attached
            if (!deviceInformation.IsDeviceAttached)
            {
                return(false);
            }

            IntPtr eventObject;
            var    hidOverlapped = new NativeOverlapped();
            IntPtr nonManagedBuffer;
            IntPtr nonManagedOverlapped;

            try
            {
                // Prepare an event object for the overlapped ReadFile
                eventObject = Kernel32.CreateEvent(IntPtr.Zero, false, false, "");

                hidOverlapped.OffsetLow   = 0;
                hidOverlapped.OffsetHigh  = 0;
                hidOverlapped.EventHandle = eventObject;

                // Allocate memory for the unmanaged input buffer and overlap structure.
                nonManagedBuffer     = Marshal.AllocHGlobal(inputReportBuffer.Length);
                nonManagedOverlapped = Marshal.AllocHGlobal(Marshal.SizeOf(hidOverlapped));
                Marshal.StructureToPtr(hidOverlapped, nonManagedOverlapped, false);

                // Read the input report buffer
                success = Kernel32.ReadFile(
                    deviceInformation.ReadHandle,
                    nonManagedBuffer,
                    inputReportBuffer.Length,
                    ref numberOfBytesRead,
                    nonManagedOverlapped);

                // Report receieved correctly, copy the unmanaged input buffer over to the managed buffer
                Marshal.Copy(nonManagedBuffer, inputReportBuffer, 0, numberOfBytesRead);
            }
            catch (Exception)
            {
                return(false);
            }

            // Release non-managed objects before returning
            Marshal.FreeHGlobal(nonManagedBuffer);
            Marshal.FreeHGlobal(nonManagedOverlapped);

            // Close the file handle to release the object
            Kernel32.CloseHandle(eventObject);

            return(success);
        }
Пример #16
0
        public static bool ReadMultipleReportsFromDevice(ref byte[] inputReportBuffer, int numberOfReports, ref DeviceInformationStructure deviceInformation)
        {
            var  success           = false;
            var  numberOfBytesRead = 0;
            long pointerToBuffer   = 0;

            // Define a temporary buffer for assembling partial data reads into the completed inputReportBuffer
            var temporaryBuffer = new Byte[inputReportBuffer.Length];

            // Range check the number of reports
            if (numberOfReports == 0)
            {
                return(false);
            }

            if (numberOfReports > 128)
            {
                return(false);
            }

            // The size of our inputReportBuffer must be at least the same size as the input report multiplied by the number of reports requested.
            if (inputReportBuffer.Length != (deviceInformation.Capabilities.InputReportByteLength * numberOfReports))
            {
                // inputReportBuffer is not the right length!
                return(false);
            }

            // The readRawReportFromDevice method will fill the passed read buffer or return false
            while (pointerToBuffer != (deviceInformation.Capabilities.InputReportByteLength * numberOfReports))
            {
                success = ReadRawReportFromDevice(ref temporaryBuffer, ref numberOfBytesRead, ref deviceInformation);

                // Was the read successful?
                if (!success)
                {
                    return(false);
                }

                // Copy the received data into the referenced input buffer
                Array.Copy(temporaryBuffer, 0, inputReportBuffer, pointerToBuffer, numberOfBytesRead);
                pointerToBuffer += numberOfBytesRead;
            }

            return(success);
        }
Пример #17
0
        public static bool FindTargetDevice(ref DeviceInformationStructure deviceInformation, bool callOther = true)
        {
            TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 开始扫描设备");

            var listOfDevicePathNames = new String[128]; // 128 is the maximum number of USB devices allowed on a single host
            var numberOfDevicesFound  = 0;

            try
            {
                // Reset the device detection flag
                var isDeviceDetected = false;
                deviceInformation.IsDeviceAttached = false;

                // Get all the devices with the correct HID GUID
                bool deviceFoundByGuid = FindHidDevices(ref listOfDevicePathNames, ref numberOfDevicesFound);

                if (deviceFoundByGuid)
                {
                    TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 找到一堆设备");
                    var listIndex = 0;
                    do
                    {
                        TmoShare.WriteLog(string.Format("DeviceDiscovery:findTargetDevice() ->遍历第{0}个设备", listIndex + 1));
                        deviceInformation.HidHandle = Kernel32.CreateFile(listOfDevicePathNames[listIndex], 0, Constants.FileShareRead | Constants.FileShareWrite, IntPtr.Zero, Constants.OpenExisting, 0, 0);

                        if (!deviceInformation.HidHandle.IsInvalid())
                        {
                            deviceInformation.Attributes.Size = Marshal.SizeOf(deviceInformation.Attributes);
                            var success = Hid.HidD_GetAttributes(deviceInformation.HidHandle, ref deviceInformation.Attributes);

                            if (success)
                            {
                                TmoShare.WriteLog(string.Format("DeviceDiscovery:findTargetDevice() -> 发现设备 VID_{0}, PID_{1} Ver_{2}",
                                                                Convert.ToString(deviceInformation.Attributes.VendorID, 16),
                                                                Convert.ToString(deviceInformation.Attributes.ProductID, 16),
                                                                Convert.ToString(deviceInformation.Attributes.VersionNumber, 16)));

                                //  Do the VID and PID of the device match our target device?
                                if ((deviceInformation.Attributes.VendorID == deviceInformation.TargetVendorId) &&
                                    (deviceInformation.Attributes.ProductID == deviceInformation.TargetProductId))
                                {
                                    // Matching device found
                                    if (string.IsNullOrWhiteSpace(deviceInformation.DevicePathName))
                                    {
                                        deviceInformation.DevicePathName = listOfDevicePathNames[listIndex];
                                        isDeviceDetected = true;
                                        TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 找到目标设备!");
                                    }
                                    else if (string.Compare(deviceInformation.DevicePathName, listOfDevicePathNames[listIndex], true) == 0)
                                    {
                                        isDeviceDetected = true;
                                        TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 找到目标设备!");
                                    }
                                    else
                                    {
                                        TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 不是目标设备... 继续寻找...");
                                        deviceInformation.HidHandle.Close();
                                    }
                                    // Store the device's pathname in the device information
                                }
                                else
                                {
                                    // Wrong device, close the handle
                                    TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 不是目标设备... 继续寻找...");
                                    deviceInformation.HidHandle.Close();
                                }
                            }
                            else
                            {
                                //  Something went rapidly south...  give up!
                                TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 识别设备失败, 继续下一个!");
                                deviceInformation.HidHandle.Close();
                            }
                        }
                        else
                        {
                            TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 句柄创建失败");
                        }

                        //  Move to the next device, or quit if there are no more devices to examine
                        listIndex++;
                    }while (!((isDeviceDetected || (listIndex == numberOfDevicesFound))));
                }

                // If we found a matching device then we need discover more details about the attached device
                // and then open read and write handles to the device to allow communication
                if (isDeviceDetected)
                {
                    // Query the HID device's capabilities (primarily we are only really interested in the
                    // input and output report byte lengths as this allows us to validate information sent
                    // to and from the device does not exceed the devices capabilities.
                    //
                    // We could determine the 'type' of HID device here too, but since this class is only
                    // for generic HID communication we don't care...

                    if (!callOther)
                    {
                        // Open the readHandle to the device
                        TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 开始创建读文件句柄");
                        deviceInformation.ReadHandle = Kernel32.CreateFile(
                            deviceInformation.DevicePathName,
                            Constants.GenericRead,
                            Constants.FileShareRead | Constants.FileShareWrite,
                            IntPtr.Zero,
                            Constants.OpenExisting,
                            Constants.FileFlagOverlapped,
                            0);

                        // Did we open the readHandle successfully?
                        if (deviceInformation.ReadHandle.IsInvalid())
                        {
                            TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 读文件句柄创建失败" + Marshal.GetLastWin32Error());
                            return(false);
                        }

                        //Open the writeHandel to the device
                        TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 开始创建写文件句柄");
                        deviceInformation.WriteHandle = Kernel32.CreateFile(
                            deviceInformation.DevicePathName,
                            Constants.GenericWrite,
                            Constants.FileShareWrite | Constants.FileShareRead,
                            IntPtr.Zero,
                            Constants.OpenExisting, 0, 0);

                        // Did we open the writeHandle successfully?
                        if (deviceInformation.WriteHandle.IsInvalid())
                        {
                            TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 写文件句柄创建失败" + Marshal.GetLastWin32Error());
                            return(false);
                        }
                    }

                    QueryDeviceCapabilities(ref deviceInformation);
                    // Device is now discovered and ready for use, update the status
                    deviceInformation.IsDeviceAttached = true;
                    return(true);
                }

                //  The device wasn't detected.
                TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 未找到目标设备!");
                return(false);
            }
            catch (Exception ex)
            {
                TmoShare.WriteLog("DeviceDiscovery:findTargetDevice() -> 发生异常:" + ex.Message);
                return(false);
            }
        }
Пример #18
0
        public static void QueryDeviceCapabilities(ref DeviceInformationStructure deviceInformation)
        {
            var preparsedData = new IntPtr();

            try
            {
                // Get the preparsed data from the HID driver
                Hid.HidD_GetPreparsedData(deviceInformation.HidHandle, ref preparsedData);

                // Get the HID device's capabilities
                var result = Hid.HidP_GetCaps(preparsedData, ref deviceInformation.Capabilities);
                if ((result == 0))
                {
                    return;
                }

                Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() -> Device query results:");
                Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() ->     Usage: {0}",
                                Convert.ToString(deviceInformation.Capabilities.Usage, 16));
                Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() ->     Usage Page: {0}",
                                Convert.ToString(deviceInformation.Capabilities.UsagePage, 16));
                Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() ->     Input Report Byte Length: {0}",
                                deviceInformation.Capabilities.InputReportByteLength.ToString(CultureInfo.InvariantCulture));
                Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() ->     Output Report Byte Length: {0}",
                                deviceInformation.Capabilities.OutputReportByteLength.ToString(CultureInfo.InvariantCulture));
                Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() ->     Feature Report Byte Length: {0}",
                                deviceInformation.Capabilities.FeatureReportByteLength.ToString(CultureInfo.InvariantCulture));
                Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() ->     Number of Link Collection Nodes: {0}",
                                deviceInformation.Capabilities.NumberLinkCollectionNodes.ToString(CultureInfo.InvariantCulture));
                Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() ->     Number of Input Button Caps: {0}",
                                deviceInformation.Capabilities.NumberInputButtonCaps.ToString(CultureInfo.InvariantCulture));
                Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() ->     Number of Input Value Caps: {0}",
                                deviceInformation.Capabilities.NumberInputValueCaps.ToString(CultureInfo.InvariantCulture));
                Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() ->     Number of Input Data Indices: {0}",
                                deviceInformation.Capabilities.NumberInputDataIndices.ToString(CultureInfo.InvariantCulture));
                Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() ->     Number of Output Button Caps: {0}",
                                deviceInformation.Capabilities.NumberOutputButtonCaps.ToString(CultureInfo.InvariantCulture));
                Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() ->     Number of Output Value Caps: {0}",
                                deviceInformation.Capabilities.NumberOutputValueCaps.ToString(CultureInfo.InvariantCulture));
                Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() ->     Number of Output Data Indices: {0}",
                                deviceInformation.Capabilities.NumberOutputDataIndices.ToString(CultureInfo.InvariantCulture));
                Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() ->     Number of Feature Button Caps: {0}",
                                deviceInformation.Capabilities.NumberFeatureButtonCaps.ToString(CultureInfo.InvariantCulture));
                Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() ->     Number of Feature Value Caps: {0}",
                                deviceInformation.Capabilities.NumberFeatureValueCaps.ToString(CultureInfo.InvariantCulture));
                Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() ->     Number of Feature Data Indices: {0}",
                                deviceInformation.Capabilities.NumberFeatureDataIndices.ToString(CultureInfo.InvariantCulture));
            }
            catch (Exception)
            {
                // Something went badly wrong... this shouldn't happen, so we throw an exception
                Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() -> EXECEPTION: An unrecoverable error has occurred!");
                throw;
            }
            finally
            {
                // Free up the memory before finishing
                if (preparsedData != IntPtr.Zero)
                {
                    Hid.HidD_FreePreparsedData(preparsedData);
                }
            }
        }
Пример #19
0
        public static bool ReadMultipleReportsFromDevice(ref byte[] inputReportBuffer, int numberOfReports, ref DeviceInformationStructure deviceInformation)
        {
            var  success           = false;
            var  numberOfBytesRead = 0;
            long pointerToBuffer   = 0;

            // Define a temporary buffer for assembling partial data reads into the completed inputReportBuffer
            var temporaryBuffer = new Byte[inputReportBuffer.Length];

            // Range check the number of reports
            if (numberOfReports == 0)
            {
                Debug.WriteLine(
                    "usbGenericHidCommunication:readMultipleReportsFromDevice(): -> ERROR: You cannot request 0 reports!");
                return(false);
            }

            if (numberOfReports > 128)
            {
                Debug.WriteLine(
                    "usbGenericHidCommunication:readMultipleReportsFromDevice(): -> ERROR: Reference application testing does not verify the code for more than 128 reports");
                return(false);
            }

            // The size of our inputReportBuffer must be at least the same size as the input report multiplied by the number of reports requested.
            if (inputReportBuffer.Length != (deviceInformation.Capabilities.InputReportByteLength * numberOfReports))
            {
                // inputReportBuffer is not the right length!
                Debug.WriteLine(
                    "usbGenericHidCommunication:readMultipleReportsFromDevice(): -> ERROR: The referenced inputReportBuffer size is incorrect for the number of input reports requested!");
                return(false);
            }

            // The readRawReportFromDevice method will fill the passed read buffer or return false
            while (pointerToBuffer != (deviceInformation.Capabilities.InputReportByteLength * numberOfReports))
            {
                Debug.WriteLine(
                    "usbGenericHidCommunication:readMultipleReportsFromDevice(): -> Reading from device...");
                success = ReadRawReportFromDevice(ref temporaryBuffer, ref numberOfBytesRead, ref deviceInformation);

                // Was the read successful?
                if (!success)
                {
                    return(false);
                }

                // Copy the received data into the referenced input buffer
                Array.Copy(temporaryBuffer, 0, inputReportBuffer, pointerToBuffer, numberOfBytesRead);
                pointerToBuffer += numberOfBytesRead;
            }

            return(success);
        }
Пример #20
0
        public static bool FindTargetDevice(ref DeviceInformationStructure deviceInformation)
        {
            Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Method called");

            var listOfDevicePathNames = new String[128]; // 128 is the maximum number of USB devices allowed on a single host
            var numberOfDevicesFound  = 0;

            try
            {
                // Reset the device detection flag
                var isDeviceDetected = false;
                deviceInformation.IsDeviceAttached = false;

                // Get all the devices with the correct HID GUID
                var deviceFoundByGuid = FindHidDevices(ref listOfDevicePathNames, ref numberOfDevicesFound);

                if (deviceFoundByGuid)
                {
                    Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Devices with matching GUID found...");
                    var listIndex = 0;

                    do
                    {
                        Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Performing CreateFile to listIndex {0}", listIndex);
                        deviceInformation.HidHandle = Kernel32.CreateFile(listOfDevicePathNames[listIndex], 0, Constants.FileShareRead | Constants.FileShareWrite, IntPtr.Zero, Constants.OpenExisting, 0, 0);

                        if (!deviceInformation.HidHandle.IsInvalid)
                        {
                            deviceInformation.Attributes.Size = Marshal.SizeOf(deviceInformation.Attributes);
                            var success = Hid.HidD_GetAttributes(deviceInformation.HidHandle, ref deviceInformation.Attributes);

                            if (success)
                            {
                                Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Found device with VID {0}, PID {1} and Version number {2}",
                                                Convert.ToString(deviceInformation.Attributes.VendorID, 16),
                                                Convert.ToString(deviceInformation.Attributes.ProductID, 16),
                                                Convert.ToString(deviceInformation.Attributes.VersionNumber, 16));

                                //  Do the VID and PID of the device match our target device?
                                if ((deviceInformation.Attributes.VendorID == deviceInformation.TargetVendorId) &&
                                    (deviceInformation.Attributes.ProductID == deviceInformation.TargetProductId))
                                {
                                    // Matching device found
                                    Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Device with matching VID and PID found!");
                                    isDeviceDetected = true;

                                    // Store the device's pathname in the device information
                                    deviceInformation.DevicePathName = listOfDevicePathNames[listIndex];
                                }
                                else
                                {
                                    // Wrong device, close the handle
                                    Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Device didn't match... Continuing...");
                                    deviceInformation.HidHandle.Close();
                                }
                            }
                            else
                            {
                                //  Something went rapidly south...  give up!
                                Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Something bad happened - couldn't fill the HIDD_ATTRIBUTES, giving up!");
                                deviceInformation.HidHandle.Close();
                            }
                        }

                        //  Move to the next device, or quit if there are no more devices to examine
                        listIndex++;
                    }while (!((isDeviceDetected || (listIndex == numberOfDevicesFound + 1))));
                }

                // If we found a matching device then we need discover more details about the attached device
                // and then open read and write handles to the device to allow communication
                if (isDeviceDetected)
                {
                    // Query the HID device's capabilities (primarily we are only really interested in the
                    // input and output report byte lengths as this allows us to validate information sent
                    // to and from the device does not exceed the devices capabilities.
                    //
                    // We could determine the 'type' of HID device here too, but since this class is only
                    // for generic HID communication we don't care...
                    QueryDeviceCapabilities(ref deviceInformation);

                    // Open the readHandle to the device
                    Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Opening a readHandle to the device");
                    deviceInformation.ReadHandle = Kernel32.CreateFile(
                        deviceInformation.DevicePathName,
                        Constants.GenericRead,
                        Constants.FileShareRead | Constants.FileShareWrite,
                        IntPtr.Zero, Constants.OpenExisting,
                        Constants.FileFlagOverlapped,
                        0);

                    // Did we open the readHandle successfully?
                    if (deviceInformation.ReadHandle.IsInvalid)
                    {
                        Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Unable to open a readHandle to the device!");
                        return(false);
                    }

                    Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Opening a writeHandle to the device");
                    deviceInformation.WriteHandle = Kernel32.CreateFile(
                        deviceInformation.DevicePathName,
                        Constants.GenericWrite,
                        Constants.FileShareRead | Constants.FileShareWrite,
                        IntPtr.Zero,
                        Constants.OpenExisting, 0, 0);

                    // Did we open the writeHandle successfully?
                    if (deviceInformation.WriteHandle.IsInvalid)
                    {
                        Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> Unable to open a writeHandle to the device!");

                        // Attempt to close the writeHandle
                        deviceInformation.WriteHandle.Close();
                        return(false);
                    }

                    // Device is now discovered and ready for use, update the status
                    deviceInformation.IsDeviceAttached = true;
                    return(true);
                }

                //  The device wasn't detected.
                Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> No matching device found!");
                return(false);
            }
            catch (Exception)
            {
                Debug.WriteLine("usbGenericHidCommunication:findTargetDevice() -> EXCEPTION: Unknown - device not found");
                return(false);
            }
        }