private HidD_GetSerialNumberString ( |
||
HidDeviceObject | ||
Buffer | byte | |
BufferLength | ulong | |
return | bool |
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); } }
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); } }
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); }