HidD_GetSerialNumberString() private method

private HidD_GetSerialNumberString ( IntPtr HidDeviceObject, byte Buffer, ulong BufferLength ) : bool
HidDeviceObject System.IntPtr
Buffer byte
BufferLength ulong
return bool
Exemplo n.º 1
0
        public string readSerial()
        {
            if (serial != null)
            {
                return(serial);
            }

            if (Capabilities.InputReportByteLength == 64)
            {
                byte[] buffer = new byte[16];
                buffer[0] = 18;
                readFeatureData(buffer);
                serial = String.Format("{0:X02}:{1:X02}:{2:X02}:{3:X02}:{4:X02}:{5:X02}", buffer[6], buffer[5], buffer[4], buffer[3], buffer[2], buffer[1]);
                return(serial);
            }
            else
            {
                byte[] buffer = new byte[126];
                NativeMethods.HidD_GetSerialNumberString(safeReadHandle.DangerousGetHandle(), buffer, (ulong)buffer.Length);
                string MACAddr = System.Text.Encoding.Unicode.GetString(buffer).Replace("\0", string.Empty).ToUpper();
                MACAddr = $"{MACAddr[0]}{MACAddr[1]}:{MACAddr[2]}{MACAddr[3]}:{MACAddr[4]}{MACAddr[5]}:{MACAddr[6]}{MACAddr[7]}:{MACAddr[8]}{MACAddr[9]}:{MACAddr[10]}{MACAddr[11]}";
                serial  = MACAddr;
                return(serial);
            }
        }
Exemplo n.º 2
0
        public string readSerial()
        {
            if (serial != null)
            {
                return(serial);
            }

            // Some devices don't have MAC address (especially gamepads with USB only suports in PC). If the serial number reading fails
            // then use dummy zero MAC address, because there is a good chance the gamepad stll works in DS4Windows app (the code would throw
            // an index out of bounds exception anyway without IF-THEN-ELSE checks after trying to read a serial number).

            if (Capabilities.InputReportByteLength == 64)
            {
                byte[] buffer = new byte[16];
                buffer[0] = 18;
                if (readFeatureData(buffer))
                {
                    serial = String.Format("{0:X02}:{1:X02}:{2:X02}:{3:X02}:{4:X02}:{5:X02}",
                                           buffer[6], buffer[5], buffer[4], buffer[3], buffer[2], buffer[1]);
                }
                else
                {
                    serial = BLANK_SERIAL;
                }

                return(serial);
            }
            else
            {
                byte[] buffer = new byte[126];
#if WIN64
                ulong bufferLen = 126;
#else
                uint bufferLen = 126;
#endif
                if (NativeMethods.HidD_GetSerialNumberString(safeReadHandle.DangerousGetHandle(), buffer, bufferLen))
                {
                    string MACAddr = System.Text.Encoding.Unicode.GetString(buffer).Replace("\0", string.Empty).ToUpper();
                    MACAddr = $"{MACAddr[0]}{MACAddr[1]}:{MACAddr[2]}{MACAddr[3]}:{MACAddr[4]}{MACAddr[5]}:{MACAddr[6]}{MACAddr[7]}:{MACAddr[8]}{MACAddr[9]}:{MACAddr[10]}{MACAddr[11]}";
                    serial  = MACAddr;
                }
                else
                {
                    serial = BLANK_SERIAL;
                }

                return(serial);
            }
        }
Exemplo n.º 3
0
        public string readSerial()
        {
            if (serial != null)
            {
                return(serial);
            }

            // Some devices don't have MAC address (especially gamepads with USB only suports in PC). If the serial number reading fails
            // then use dummy zero MAC address, because there is a good chance the gamepad stll works in DS4Windows app (the code would throw
            // an index out of bounds exception anyway without IF-THEN-ELSE checks after trying to read a serial number).

            if (Capabilities.InputReportByteLength == 64)
            {
                byte[] buffer = new byte[16];
                buffer[0] = 18;
                if (readFeatureData(buffer))
                {
                    serial = String.Format("{0:X02}:{1:X02}:{2:X02}:{3:X02}:{4:X02}:{5:X02}",
                                           buffer[6], buffer[5], buffer[4], buffer[3], buffer[2], buffer[1]);
                }
            }
            else
            {
                byte[] buffer = new byte[126];
#if WIN64
                ulong bufferLen = 126;
#else
                uint bufferLen = 126;
#endif
                if (NativeMethods.HidD_GetSerialNumberString(safeReadHandle.DangerousGetHandle(), buffer, bufferLen))
                {
                    string MACAddr = System.Text.Encoding.Unicode.GetString(buffer).Replace("\0", string.Empty).ToUpper();
                    MACAddr = $"{MACAddr[0]}{MACAddr[1]}:{MACAddr[2]}{MACAddr[3]}:{MACAddr[4]}{MACAddr[5]}:{MACAddr[6]}{MACAddr[7]}:{MACAddr[8]}{MACAddr[9]}:{MACAddr[10]}{MACAddr[11]}";
                    serial  = MACAddr;
                }
            }

            // If serial# reading failed then generate a dummy MAC address based on HID device path (WinOS generated runtime unique value based on connected usb port and hub or BT channel).
            // The device path remains the same as long the gamepad is always connected to the same usb/BT port, but may be different in other usb ports. Therefore this value is unique
            // as long the same device is always connected to the same usb port.
            if (serial == null)
            {
                string MACAddr = string.Empty;

                AppLogger.LogToGui($"WARNING: Failed to read serial# from a gamepad ({this._deviceAttributes.VendorHexId}/{this._deviceAttributes.ProductHexId}). Generating MAC address from a device path. From now on you should connect this gamepad always into the same USB port or BT pairing host to keep the same device path.", true);

                try
                {
                    // Substring: \\?\hid#vid_054c&pid_09cc&mi_03#7&1f882A25&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030} -> \\?\hid#vid_054c&pid_09cc&mi_03#7&1f882A25&0&0001#
                    int endPos = this.DevicePath.LastIndexOf('{');
                    if (endPos < 0)
                    {
                        endPos = this.DevicePath.Length;
                    }

                    // String array: \\?\hid#vid_054c&pid_09cc&mi_03#7&1f882A25&0&0001# -> [0]=\\?\hidvid_054c, [1]=pid_09cc, [2]=mi_037, [3]=1f882A25, [4]=0, [5]=0001
                    string[] devPathItems = this.DevicePath.Substring(0, endPos).Replace("#", "").Replace("-", "").Replace("{", "").Replace("}", "").Split('&');

                    if (devPathItems.Length >= 3)
                    {
                        MACAddr = devPathItems[devPathItems.Length - 3].ToUpper()                   // 1f882A25
                                  + devPathItems[devPathItems.Length - 2].ToUpper()                 // 0
                                  + devPathItems[devPathItems.Length - 1].TrimStart('0').ToUpper(); // 0001 -> 1
                    }
                    else if (devPathItems.Length >= 1)
                    {
                        // Device and usb hub and port identifiers missing in devicePath string. Fallback to use vendor and product ID values and
                        // take a number from the last part of the devicePath. Hopefully the last part is a usb port number as it usually should be.
                        MACAddr = this._deviceAttributes.VendorId.ToString("X4")
                                  + this._deviceAttributes.ProductId.ToString("X4")
                                  + devPathItems[devPathItems.Length - 1].TrimStart('0').ToUpper();
                    }

                    if (!string.IsNullOrEmpty(MACAddr))
                    {
                        MACAddr = MACAddr.PadRight(12, '0');
                        serial  = $"{MACAddr[0]}{MACAddr[1]}:{MACAddr[2]}{MACAddr[3]}:{MACAddr[4]}{MACAddr[5]}:{MACAddr[6]}{MACAddr[7]}:{MACAddr[8]}{MACAddr[9]}:{MACAddr[10]}{MACAddr[11]}";
                    }
                    else
                    {
                        // Hmm... Shold never come here. Strange format in devicePath because all identifier items of devicePath string are missing.
                        serial = BLANK_SERIAL;
                    }
                }
                catch (Exception e)
                {
                    AppLogger.LogToGui($"ERROR: Failed to generate runtime MAC address from device path {this.DevicePath}. {e.Message}", true);
                    serial = BLANK_SERIAL;
                }
            }

            return(serial);
        }