コード例 #1
0
ファイル: Managed.cs プロジェクト: burnsba/BurnsBac.WinApi
        /// <summary>
        /// Calls Hid.HidP_GetValueCaps. Gets HID button capabilities.
        /// </summary>
        /// <param name="hidpcaps">HID capabilities.</param>
        /// <param name="preparsedData">Pointer to preparsed data structure.</param>
        /// <returns>HID button capabilities.</returns>
        public static HidpValueCaps[] HidpGetValueCapabilities(HidpCaps hidpcaps, IntPtr preparsedData)
        {
            if (preparsedData == IntPtr.Zero)
            {
                throw new ArgumentException($"{nameof(preparsedData)} pointer is not set.");
            }

            uint       dwSize;
            HidpStatus hidpstatus;
            IntPtr     pvaluecaps          = IntPtr.Zero;
            bool       pvaluecapsAllocated = false;

            try
            {
                dwSize = hidpcaps.NumberInputValueCaps;
                var             bytelength = Marshal.SizeOf(typeof(HidpValueCaps)) * (int)dwSize;
                HidpValueCaps[] valueCaps  = new HidpValueCaps[(int)dwSize];

                pvaluecaps          = Marshal.AllocHGlobal(bytelength);
                pvaluecapsAllocated = true;

                hidpstatus = (HidpStatus)WinApi.Hid.Api.HidP_GetValueCaps(HidpReportType.HidP_Input, pvaluecaps, ref dwSize, preparsedData);
                if (hidpstatus != HidpStatus.HIDP_STATUS_SUCCESS)
                {
                    throw new HidpStatusException($"HidP_GetValueCaps: {hidpstatus.ToString()}")
                          {
                              StatusCode = hidpstatus
                          };
                }

                var valueCapBytes = new byte[bytelength];
                Marshal.Copy(pvaluecaps, valueCapBytes, 0, bytelength);
                for (int i = 0; i < (int)hidpcaps.NumberInputValueCaps; i++)
                {
                    valueCaps[i] = HidpValueCaps.FromBytes(valueCapBytes, i * Marshal.SizeOf(typeof(HidpValueCaps)), out int t);
                }

                return(valueCaps);
            }
            finally
            {
                if (pvaluecapsAllocated)
                {
                    Marshal.FreeHGlobal(pvaluecaps);
                }
            }
        }
コード例 #2
0
 internal static extern Int32 HidP_GetCaps(IntPtr preparsedData, ref HidpCaps capabilities);
コード例 #3
0
ファイル: Hid.cs プロジェクト: wushian/pinvoke
 public static extern NTSTATUS HidP_GetCaps(SafePreparsedDataHandle preparsedData, ref HidpCaps capabilities);
コード例 #4
0
ファイル: Hid.cs プロジェクト: jmelosegui/pinvoke
 public static extern NTSTATUS HidP_GetCaps(SafePreparsedDataHandle preparsedData, ref HidpCaps capabilities);
コード例 #5
0
ファイル: HidMockable.cs プロジェクト: ffMathy/pinvoke-1
        /// <summary>
        /// Returns a top-level collection's <see cref="HidpCaps" /> structure.
        /// </summary>
        /// <param name="preparsedData">Pointer to a top-level collection's preparsed data.</param>
        /// <param name="capabilities">
        /// Pointer to a caller-allocated buffer that the routine uses to return a collection's
        /// <see cref="HidpCaps" /> structure.
        /// </param>
        /// <returns>
        /// <see cref="NTStatus.HIDP_STATUS_SUCCESS" /> on success or <see cref="NTStatus.HIDP_STATUS_INVALID_PREPARSED_DATA" /> if rhe
        /// specified preparsed data is invalid.
        /// </returns>
        public NTStatus InvokeHidP_GetCaps(SafePreparsedDataHandle preparsedData, ref HidpCaps capabilities)
			=> HidP_GetCaps(preparsedData, capabilities);
コード例 #6
0
ファイル: Hid.cs プロジェクト: noxryan/LCDLightControl
 public static extern Int32 HidP_GetCaps(IntPtr preparsedData,ref HidpCaps capabilities);
コード例 #7
0
 internal static extern int HidP_GetCaps(IntPtr preparsedData, ref HidpCaps capabilities);
コード例 #8
0
ファイル: Hid.cs プロジェクト: flier268/USBHid
 public static extern int HidP_GetCaps(IntPtr preparsedData, ref HidpCaps capabilities);
コード例 #9
0
ファイル: DeviceManager.cs プロジェクト: helluvamatt/MattLamp
 public UsbDevice(DeviceInstance instance, HidpCaps caps)
 {
     Instance     = instance;
     Capabilities = caps;
 }
コード例 #10
0
ファイル: DeviceManager.cs プロジェクト: helluvamatt/MattLamp
        private void _DeviceSearchThread()
        {
            _Logger.Info("Started");
            while (_Running)
            {
                var loopStart = DateTime.Now;

                #region Device enumeration

                var devices = new List <UsbDevice>();

                var detailDataBuffer = IntPtr.Zero;
                var deviceInfoSet    = IntPtr.Zero;
                try
                {
                    int listIndex           = 0;
                    int lastError           = 0;
                    var deviceInterfaceData = new SpDeviceInterfaceData();

                    var systemHidGuid = new Guid();
                    Hid.HidD_GetHidGuid(ref systemHidGuid);
                    deviceInfoSet = SetupApi.SetupDiGetClassDevs(ref systemHidGuid, IntPtr.Zero, IntPtr.Zero, Constants.DigcfPresent | Constants.DigcfDeviceinterface);
                    deviceInterfaceData.cbSize = Marshal.SizeOf(deviceInterfaceData);

                    while (SetupApi.SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref systemHidGuid, listIndex++, ref deviceInterfaceData) || (lastError = Marshal.GetLastWin32Error()) != Constants.ERROR_NO_MORE_ITEMS)
                    {
                        if (lastError == 0)
                        {
                            int bufferSize = 0;
                            SetupApi.SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref deviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, IntPtr.Zero);
                            detailDataBuffer = Marshal.AllocHGlobal(bufferSize);
                            Marshal.WriteInt32(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8);
                            if (SetupApi.SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref deviceInterfaceData, detailDataBuffer, bufferSize, ref bufferSize, IntPtr.Zero))
                            {
                                var pDevicePathName = IntPtr.Add(detailDataBuffer, 4);
                                var devicePath      = Marshal.PtrToStringAuto(pDevicePathName);

                                // Get device capabilities (to determine usage page)
                                using (var hidHandle = Kernel32.CreateFile(devicePath, 0, Constants.FileShareRead | Constants.FileShareWrite, IntPtr.Zero, Constants.OpenExisting, 0, 0))
                                {
                                    var preparsedData = IntPtr.Zero;
                                    try
                                    {
                                        preparsedData = new IntPtr();
                                        Hid.HidD_GetPreparsedData(hidHandle, ref preparsedData);
                                        var caps = new HidpCaps();
                                        Hid.HidP_GetCaps(preparsedData, ref caps);

                                        var attrs = new HiddAttributes();
                                        Hid.HidD_GetAttributes(hidHandle, ref attrs);

                                        // Only add the device if it has our VID, PID, and RAW usage page
                                        var deviceClass = FindDeviceClass(attrs.VendorID, attrs.ProductID, attrs.VersionNumber, caps.UsagePage);
                                        if (deviceClass != null)
                                        {
                                            var manufacturer = new StringBuilder(STRING_SIZE_LIMIT);
                                            var product      = new StringBuilder(STRING_SIZE_LIMIT);
                                            var serial       = new StringBuilder(STRING_SIZE_LIMIT);
                                            Hid.HidD_GetManufacturerString(hidHandle, manufacturer, STRING_SIZE_LIMIT);
                                            Hid.HidD_GetProductString(hidHandle, product, STRING_SIZE_LIMIT);
                                            Hid.HidD_GetSerialNumberString(hidHandle, serial, STRING_SIZE_LIMIT);
                                            var device = new UsbDevice(new DeviceInstance(deviceClass, devicePath, manufacturer.ToString(), product.ToString(), serial.ToString()), caps);
                                            devices.Add(device);
                                        }
                                    }
                                    finally
                                    {
                                        // Free up the memory before finishing
                                        if (preparsedData != IntPtr.Zero)
                                        {
                                            Hid.HidD_FreePreparsedData(preparsedData);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    _Logger.Error(ex, "Error scanning for devices:");
                    devices.Clear();
                }
                finally
                {
                    // Clean up the unmanaged memory allocations and free resources held by the windows API
                    if (detailDataBuffer != IntPtr.Zero)
                    {
                        Marshal.FreeHGlobal(detailDataBuffer);
                    }
                    if (deviceInfoSet != IntPtr.Zero)
                    {
                        SetupApi.SetupDiDestroyDeviceInfoList(deviceInfoSet);
                    }
                }

                var addedDevices   = devices.Except(_CurrentDevices);
                var removedDevices = _CurrentDevices.Except(devices);

                _CurrentDevices = devices;

                if (DeviceRemoved != null)
                {
                    foreach (var dev in removedDevices)
                    {
                        _Logger.Info("Device removed: {0}", dev);
                        DeviceRemoved(this, new DeviceEventArgs(dev.Instance));
                    }
                }
                if (DeviceAdded != null)
                {
                    foreach (var dev in addedDevices)
                    {
                        _Logger.Info("Device added: {0}", dev);
                        DeviceAdded(this, new DeviceEventArgs(dev.Instance));
                    }
                }

                #endregion

                #region Active device I/O

                // If we receive a request to change the active device while we are processing messages, we need to stop immediately because they are about to become invalid
                {
                    byte[] msg;
                    while (true)
                    {
                        byte[] response = null;

                        // Block until SetActiveDevice finishes
                        lock (_LockObject)
                        {
                            // If we created a new message queue in the call to SetActiveDevice, this will return false and we'll break out of the loop
                            if (_ActiveDevice == null || !_MessageQueue.TryDequeue(out msg))
                            {
                                break;
                            }
                            try
                            {
                                response = SendDeviceRequest(_ActiveDevice, msg);
                            }
                            catch (Exception ex)
                            {
                                _Logger.Error(ex, "Error communicating with device: {0} (0x{1:X8})", ex.Message, ex.HResult);
                            }
                        }

                        if (response != null)
                        {
                            ProcessResponse(msg, response);
                        }
                        else
                        {
                            _Logger.Error("Failed to read data from device. req = {0}", FormatByteArray(msg));
                        }
                    }
                }

                // Get LED config (it may have changed)
                {
                    byte[] response = null;
                    byte[] msg      = CreateSimpleMessage(hid_pkt_req.HID_PKT_REQ_CONFIG_LED_GET);

                    // Block until SetActiveDevice finishes
                    lock (_LockObject)
                    {
                        if (_ActiveDevice != null)
                        {
                            try
                            {
                                response = SendDeviceRequest(_ActiveDevice, msg);
                            }
                            catch (Exception ex)
                            {
                                _Logger.Error(ex, "Error communicating with device: {0} (0x{1:X8})", ex.Message, ex.HResult);
                            }
                        }
                    }

                    if (response != null)
                    {
                        ProcessResponse(msg, response);
                    }
                }

                // Get LED status
                {
                    byte[] response = null;
                    byte[] msg      = new byte[2];
                    msg[0] = (byte)hid_pkt_req.HID_PKT_REQ_LED_STATUS;
                    msg[1] = 0;

                    var ledStatuses = new List <LedColor>();

                    do
                    {
                        lock (_LockObject)
                        {
                            if (_ActiveDevice != null)
                            {
                                try
                                {
                                    response = SendDeviceRequest(_ActiveDevice, msg);
                                }
                                catch (Exception ex)
                                {
                                    _Logger.Error(ex, "Error communicating with device: {0} (0x{1:X8})", ex.Message, ex.HResult);
                                }
                            }
                        }

                        if (response != null)
                        {
                            // Parse response
                            for (byte i = 0; i < response[1] && i < 10; i++)
                            {
                                var led = new LedColor(
                                    response[i * 3 + 2],
                                    response[i * 3 + 3],
                                    response[i * 3 + 4]
                                    );
                                ledStatuses.Add(led);
                            }

                            msg[1] += 10;
                        }
                    } while (response != null && response[0] == (byte)hid_pkt_res.HID_PKT_RES_MORE);

                    LedStatusReceived?.Invoke(this, new LedStatusReceivedEventArgs(ledStatuses));
                }

                #endregion

                // Wait until the entire loop execution is at least 100ms
                var loopTime = DateTime.Now - loopStart;
                if (loopTime < LOOP_DELAY)
                {
                    var waitTime = LOOP_DELAY - loopTime;
                    Thread.Sleep(waitTime);
                }
            }
        }