IORegistryEntryFromPath() private méthode

private IORegistryEntryFromPath ( int masterPort, io_string_t &path ) : int
masterPort int
path io_string_t
Résultat int
        internal static MacSerialDevice TryCreate(NativeMethods.io_string_t path)
        {
            var d = new MacSerialDevice()
            {
                _path = path
            };

            var handle = NativeMethods.IORegistryEntryFromPath(0, ref path).ToIOObject();

            if (!handle.IsSet)
            {
                return(null);
            }

            using (handle)
            {
                d._fileSystemName = NativeMethods.IORegistryEntryGetCFProperty_String(handle, NativeMethods.kIOCalloutDeviceKey);
                if (d._fileSystemName == null)
                {
                    return(null);
                }
            }

            return(d);
        }
        internal void Init(NativeMethods.io_string_t path)
        {
            IntPtr handle; int retryCount = 0, maxRetries = 10;

            while (true)
            {
                var newPath = path.Clone();
                using (var service = NativeMethods.IORegistryEntryFromPath(0, ref newPath).ToIOObject())
                {
                    string error;

                    if (service.IsSet)
                    {
                        handle = NativeMethods.IOHIDDeviceCreate(IntPtr.Zero, service);
                        if (handle != IntPtr.Zero)
                        {
                            var ret = NativeMethods.IOHIDDeviceOpen(handle);
                            if (ret == NativeMethods.IOReturn.Success)
                            {
                                break;
                            }

                            NativeMethods.CFRelease(handle);

                            // TODO: Only count up if IOReturn is ExclusiveAccess or Offline.
                            error = string.Format("Unable to open HID class device (error {1}): {0}", newPath.ToString(), ret);
                        }
                        else
                        {
                            error = string.Format("HID class device not found: {0}", newPath.ToString());
                        }
                    }
                    else
                    {
                        error = string.Format("HID class device path not found: {0}", newPath.ToString());
                    }

                    if (++retryCount == maxRetries)
                    {
                        throw DeviceException.CreateIOException(Device, error);
                    }

                    Debug.WriteLine(string.Format("Retrying ({0})", error));
                    Thread.Sleep(100);
                }
            }
            _handle = handle;
            HandleInitAndOpen();

            _readThread.Start();
            _writeThread.Start();
        }
        protected override bool TryCreateDevice(object key, out HidDevice device, out object creationState)
        {
            creationState = null;
            var path = (NativeMethods.io_string_t)key; var hidDevice = new MacHidDevice(path);

            using (var handle = NativeMethods.IORegistryEntryFromPath(0, ref path).ToIOObject())
            {
                if (!handle.IsSet || !hidDevice.GetInfo(handle))
                {
                    device = null; return(false);
                }
                device = hidDevice; return(true);
            }
        }
        internal void Init(NativeMethods.io_string_t path, MacHidDevice device)
        {
            IntPtr handle;

            using (var service = NativeMethods.IORegistryEntryFromPath(0, ref path).ToIOObject()) {
                handle = NativeMethods.IOHIDDeviceCreate(IntPtr.Zero, service);
                if (handle == IntPtr.Zero)
                {
                    throw new IOException("HID class device not found.");
                }

                if (NativeMethods.IOReturn.Success != NativeMethods.IOHIDDeviceOpen(handle))
                {
                    NativeMethods.CFRelease(handle);
                    throw new IOException("Unable to open HID class device.");
                }
            }
            _device = device;
            _handle = handle;
            HandleInitAndOpen();

            _readThread.Start();
            _writeThread.Start();
        }
Exemple #5
0
        internal static MacHidDevice TryCreate(NativeMethods.io_string_t path)
        {
            var d = new MacHidDevice()
            {
                _path = path
            };

            var service = NativeMethods.IORegistryEntryFromPath(0, ref path).ToIOObject();

            if (!service.IsSet)
            {
                return(null);
            }

            using (service)
            {
                int?vid     = NativeMethods.IORegistryEntryGetCFProperty_Int(service, NativeMethods.kIOHIDVendorIDKey);
                int?pid     = NativeMethods.IORegistryEntryGetCFProperty_Int(service, NativeMethods.kIOHIDProductIDKey);
                int?version = NativeMethods.IORegistryEntryGetCFProperty_Int(service, NativeMethods.kIOHIDVersionNumberKey);
                if (vid == null || pid == null || version == null)
                {
                    return(null);
                }

                // TODO: Craft the report descriptor from IOHIDElements so we can support it below OS X 10.8...
                //       Also, our report sizes aren't correct for the no-report-ID case without this...

                d._vid              = (int)vid;
                d._pid              = (int)pid;
                d._version          = (int)version;
                d._maxInput         = NativeMethods.IORegistryEntryGetCFProperty_Int(service, NativeMethods.kIOHIDMaxInputReportSizeKey) ?? 0;
                d._maxOutput        = NativeMethods.IORegistryEntryGetCFProperty_Int(service, NativeMethods.kIOHIDMaxOutputReportSizeKey) ?? 0;
                d._maxFeature       = NativeMethods.IORegistryEntryGetCFProperty_Int(service, NativeMethods.kIOHIDMaxFeatureReportSizeKey) ?? 0;
                d._manufacturer     = NativeMethods.IORegistryEntryGetCFProperty_String(service, NativeMethods.kIOHIDManufacturerKey);
                d._productName      = NativeMethods.IORegistryEntryGetCFProperty_String(service, NativeMethods.kIOHIDProductKey);
                d._serialNumber     = NativeMethods.IORegistryEntryGetCFProperty_String(service, NativeMethods.kIOHIDSerialNumberKey);
                d._reportDescriptor = NativeMethods.IORegistryEntryGetCFProperty_Data(service, NativeMethods.kIOHIDReportDescriptorKey);
                if (d._maxInput == 0 && d._maxOutput == 0 && d._maxFeature == 0)
                {
                    return(null);
                }

                // Does this device use Report IDs? Let's find out.
                d._reportsUseID = false; bool hasInput = false, hasOutput = false, hasFeature = false;
                using (var device = NativeMethods.IOHIDDeviceCreate(IntPtr.Zero, service).ToCFType())
                {
                    if (!device.IsSet)
                    {
                        return(null);
                    }

                    using (var elementArray = NativeMethods.IOHIDDeviceCopyMatchingElements(device, IntPtr.Zero).ToCFType())
                    {
                        if (!elementArray.IsSet)
                        {
                            return(null);
                        }

                        int elementCount = checked ((int)NativeMethods.CFArrayGetCount(elementArray));
                        for (int elementIndex = 0; elementIndex < elementCount; elementIndex++)
                        {
                            var element = NativeMethods.CFArrayGetValueAtIndex(elementArray, (IntPtr)elementIndex);
                            if (element == IntPtr.Zero)
                            {
                                continue;
                            }

                            var elementType = NativeMethods.IOHIDElementGetType(element);
                            switch (elementType)
                            {
                            case NativeMethods.IOHIDElementType.InputMisc:
                            case NativeMethods.IOHIDElementType.InputButton:
                            case NativeMethods.IOHIDElementType.InputAxis:
                            case NativeMethods.IOHIDElementType.InputScanCodes:
                                hasInput = true; break;

                            case NativeMethods.IOHIDElementType.Output:
                                hasOutput = true; break;

                            case NativeMethods.IOHIDElementType.Feature:
                                hasFeature = true; break;
                            }

                            if (NativeMethods.IOHIDElementGetReportID(element) != 0)
                            {
                                d._reportsUseID = true;
                            }
                        }
                    }
                }

                if (!d._reportsUseID)
                {
                    // It does not use Report IDs. MacOS's maximums do not include said Report ID.
                    if (d._maxInput != 0)
                    {
                        d._maxInput++;
                    }
                    if (d._maxOutput != 0)
                    {
                        d._maxOutput++;
                    }
                    if (d._maxFeature != 0)
                    {
                        d._maxFeature++;
                    }
                }

                if (!hasInput)
                {
                    d._maxInput = 0;
                }
                if (!hasOutput)
                {
                    d._maxOutput = 0;
                }
                if (!hasFeature)
                {
                    d._maxFeature = 0;
                }
            }

            return(d);
        }
Exemple #6
0
        public override unsafe string GetDeviceString(int index)
        {
            ushort stringIndex(byte index) => (ushort)((((byte)NativeMethods.DESCRIPTOR_TYPE.STRING) << 8) | index);

            void closeDev(NativeMethods.IOUSBDeviceStruct182 **usbDev)
            {
                (*usbDev)->USBDeviceClose(usbDev);
                (*usbDev)->Release(usbDev);
            }

            // Setup the packet for retrieving supported langId
            var setup = new NativeMethods.IOUSBDevRequest
            {
                bmRequestType = (byte)NativeMethods.ENDPOINT_DIRECTION.IN,
                bRequest      = (byte)NativeMethods.STANDARD_REQUEST.GET_DESCRIPTOR,
                wValue        = stringIndex(0),
                wIndex        = 0,
                wLength       = 255
            };

            int kernRet = NativeMethods.IOMasterPort(0, out uint masterPort);

            if (kernRet != 0)
            {
                throw new Exception($"Failed to get IOMasterPort: {kernRet:X}");
            }

            // Determine USB device from HID path
            var    hidEntry                = NativeMethods.IORegistryEntryFromPath(masterPort, ref _path).ToIOObject();
            int    deviceEntry             = 0;
            IntPtr kIOUSBDeviceInterfaceID = NativeMethods.kIOUSBDeviceInterfaceID;

            if (hidEntry.IsSet)
            {
                NativeMethods.IORegistryEntryGetParentEntry(hidEntry, "IOService", out var interfaceEntry);
                if (interfaceEntry != 0)
                {
                    NativeMethods.IORegistryEntryGetParentEntry(interfaceEntry, "IOService", out deviceEntry);
                }
            }

            if (deviceEntry == 0)
            {
                throw new Exception("Failed retrieving USB Device");
            }

            var err = NativeMethods.IOCreatePlugInInterfaceForService(deviceEntry,
                                                                      NativeMethods.kIOUSBDeviceUserClientTypeID, NativeMethods.kIOCFPluginInterfaceID,
                                                                      out var pluginInterface, out var score);

            if (err != NativeMethods.IOReturn.Success)
            {
                throw new Exception($"Plugin Interface creation failed. 0x{err:X}");
            }

            (*pluginInterface)->QueryInterface(pluginInterface, NativeMethods.CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), out var usbDevPtr);
            (*pluginInterface)->Release(pluginInterface);

            if (usbDevPtr != null)
            {
                var usbDev = (NativeMethods.IOUSBDeviceStruct182 * *)usbDevPtr;
                err = (*usbDev)->USBDeviceOpen(usbDev);
                if (err != NativeMethods.IOReturn.Success)
                {
                    (*usbDev)->Release(usbDev);
                    throw new DeviceIOException(this, $"Failed to open USB device: 0x{err:X}");
                }

                fixed(char *sbuf = new char[255])
                {
                    setup.pData = sbuf;
                    err         = (*usbDev)->DeviceRequest(usbDev, &setup);
                    if (err != NativeMethods.IOReturn.Success)
                    {
                        closeDev(usbDev);
                        throw new DeviceIOException(this, $"DeviceRequest failed: 0x{err:X}");
                    }

                    var    buf    = (byte *)setup.pData;
                    ushort langId = (ushort)(buf[2] | buf[3] << 8);

                    for (int i = 0; i < 255; i++)
                    {
                        buf[i] = 0;
                    }

                    // Retrieve string
                    setup.wIndex = langId;
                    setup.wValue = stringIndex((byte)index);

                    (*usbDev)->DeviceRequest(usbDev, &setup);
                    if (err != NativeMethods.IOReturn.Success)
                    {
                        closeDev(usbDev);
                        throw new DeviceIOException(this, $"DeviceRequest failed: 0x{err:X}");
                    }

                    var deviceString = new StringBuilder(255);
                    var ssbuf        = (char *)setup.pData;

                    for (int i = 1; i < 255; i++)
                    {
                        var c = ssbuf[i];
                        if (c == 0)
                        {
                            break;
                        }
                        else
                        {
                            deviceString.Append(c);
                        }
                    }
                    closeDev(usbDev);
                    return(deviceString.ToString());
                }
            }
            else
            {
                throw new DeviceIOException(this, $"USB Device interface retrieval failed");
            }
        }