Beispiel #1
0
        private static string GetDevicePath(IntPtr deviceInfoSet, ref NativeMethods.SP_DEVICE_INTERFACE_DATA deviceInterfaceData)
        {
            // Final result
            string result = null;

            // Object to store device path
            var deviceInterfaceDetail = new NativeMethods.SP_DEVICE_INTERFACE_DETAIL_DATA
            {
                cbSize = (IntPtr.Size == 8)
                                        ? 8                                 // 64 bit
                                        : 4 + Marshal.SystemDefaultCharSize // 32 bit
            };

            // Sizes
            uint       requiredSize = 0;
            const uint bufferSize   = 1024;

            // Get device path
            if (NativeMethods.SetupDiGetDeviceInterfaceDetail(deviceInfoSet,
                                                              ref deviceInterfaceData,
                                                              ref deviceInterfaceDetail,
                                                              bufferSize,
                                                              ref requiredSize,
                                                              IntPtr.Zero))
            {
                result = deviceInterfaceDetail.DevicePath;
            }

            // Return
            return(result);
        }
        private int EnumDeviceInterfaceDetails(int index, IntPtr devInfoSet, Guid iFaceGuid, out String devPath, NativeMethods.SP_DEVINFO_DATA devInfoData)
        {
            NativeMethods.SP_DEVICE_INTERFACE_DATA interfaceData = new NativeMethods.SP_DEVICE_INTERFACE_DATA();

            if (!NativeMethods.SetupDiEnumDeviceInterfaces(devInfoSet, null, ref iFaceGuid, index, interfaceData))
            {
                int error = Marshal.GetLastWin32Error();
                if (error == NativeMethods.ERROR_NO_MORE_ITEMS)
                {
                    devPath     = String.Empty;
                    devInfoData = null;
                    return(error);
                }
                else
                {
                    throw new Win32Exception(error);
                }
            }

            int requiredSize = 0;

            if (!NativeMethods.SetupDiGetDeviceInterfaceDetail(devInfoSet, interfaceData, IntPtr.Zero, 0, ref requiredSize, devInfoData))
            {
                int error = Marshal.GetLastWin32Error();
                if (error != NativeMethods.ERROR_INSUFFICIENT_BUFFER)
                {
                    throw new Win32Exception(error);
                }
            }

            IntPtr buffer = Marshal.AllocHGlobal(requiredSize);

            NativeMethods.SP_DEVICE_INTERFACE_DETAIL_DATA detailData = new NativeMethods.SP_DEVICE_INTERFACE_DETAIL_DATA();
            Marshal.StructureToPtr(detailData, buffer, false);

            if (!NativeMethods.SetupDiGetDeviceInterfaceDetail(devInfoSet, interfaceData, buffer, requiredSize, ref requiredSize, devInfoData))
            {
                int error = Marshal.GetLastWin32Error();
                Marshal.FreeHGlobal(buffer);
                throw new Win32Exception(error);
            }

            IntPtr pDevicePath = (IntPtr)((int)buffer + (int)Marshal.OffsetOf(typeof(NativeMethods.SP_DEVICE_INTERFACE_DETAIL_DATA), "devicePath"));

            devPath = Marshal.PtrToStringAuto(pDevicePath);
            Marshal.FreeHGlobal(buffer);

            return(NativeMethods.ERROR_SUCCESS);
        }
Beispiel #3
0
        IList <string> FindHidDevicePathList()
        {
            // TODO: MUSTDO: fix for multiple device connection
            // Use UpdateDevicePathIfDevicePathIsNullOrEmpty() in normal use case.
            // Because if you always use this method in every HID access, CPU usage increase from <1% to 5%-10%.
            // And the UpdateDevicePath() occupies 87.8% of all application CPU times.

            // TODO: MUSTDO: GetInstalledDeviceDevicePathListByInterfaceClassGuid duplicated.  This is not deleted because this code may be faster since it does not get Capability and this was correct.
            // TODO: MUSTDO: Like GetInstalledDeviceDevicePathListByInterfaceClassGuid, it should detect when the app starts and device connection status changes.
            var ret = new List <string>();

            // TODO: MUSTDO: ProductIdは0xA001に統一される。
            foreach (var targetHidGuid in TargetHidGuidList)
            {
                int index = 0;
                // copy
                Guid hidGuid = targetHidGuid;
                NativeMethods.SP_DEVICE_INTERFACE_DATA deviceInterfaceData = new NativeMethods.SP_DEVICE_INTERFACE_DATA();
                deviceInterfaceData.cbSize = (uint)Marshal.SizeOf(deviceInterfaceData);

                // Enumerate devices.
                var hDevInfo = NativeMethods.SetupDiGetClassDevs(ref hidGuid, IntPtr.Zero, IntPtr.Zero, NativeMethods.DIGCF_DEVICEINTERFACE | NativeMethods.DIGCF_PRESENT);

                while (NativeMethods.SetupDiEnumDeviceInterfaces(hDevInfo, IntPtr.Zero, ref hidGuid, index, ref deviceInterfaceData))
                {
                    UInt32 size;
                    NativeMethods.SetupDiGetDeviceInterfaceDetail(hDevInfo, ref deviceInterfaceData, IntPtr.Zero, 0, out size, IntPtr.Zero);
                    NativeMethods.SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = new NativeMethods.SP_DEVICE_INTERFACE_DETAIL_DATA();
                    deviceInterfaceDetailData.cbSize = (uint)(IntPtr.Size == 8 ? 8 : 5);
                    // Get detail information
                    NativeMethods.SetupDiGetDeviceInterfaceDetail(hDevInfo, ref deviceInterfaceData, ref deviceInterfaceDetailData, size, out size, IntPtr.Zero);
                    //Debug.WriteLine(index + " " + deviceInterfaceDetailData.DevicePath + " " + Marshal.GetLastWin32Error());

                    // open a read/write handle to our device using the DevicePath returned
                    SafeFileHandle handle = null;
                    try
                    {
                        handle = NativeMethods.CreateFile(deviceInterfaceDetailData.DevicePath, 0, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, NativeMethods.EFileAttributes.Overlapped, IntPtr.Zero);
                        // create an attributes struct and initialize the size
                        NativeMethods.HIDD_ATTRIBUTES attrib = new NativeMethods.HIDD_ATTRIBUTES();
                        attrib.Size = (uint)Marshal.SizeOf(attrib);
                        // get the attributes of the current device
                        if (NativeMethods.HidD_GetAttributes(handle.DangerousGetHandle(), ref attrib))
                        {
                            //Debug.WriteLine(deviceInterfaceDetailData.DevicePath + " " + attrib.VendorID +" / " +attrib.ProductID);

                            // if the vendor and product IDs match up
                            if (attrib.VendorID != VendorId)
                            {
                                continue;
                            }
                            if (attrib.ProductID != ProductId)
                            {
                                continue;
                            }
                            var lowered = deviceInterfaceDetailData.DevicePath.ToLower(System.Globalization.CultureInfo.InvariantCulture);
                            if (lowered.Contains(HidEgsGestureInterfaceTag) == false)
                            {
                                continue;
                            }
                            if (lowered.Contains(HidEgsGestureInterface_VendorSpecificCollectionTag) == false)
                            {
                                continue;
                            }
                            ret.Add(deviceInterfaceDetailData.DevicePath);
                        }
                    }
                    finally
                    {
                        handle.Close();
                        index++;
                    }
                }
            }
            return(ret);
        }