// ignore_for_file: unused_import, non_constant_identifier_names, unused_field // ignore_for_file: constant_identifier_names import 'dart:convert'; import 'dart:ffi'; import 'dart:io'; import 'package:ffi/ffi.dart'; String getMachineGuid() { if (!Platform.isWindows) { throw Exception('"getMachineGuid" only supports Windows.'); } return using((alloc) { final hkey = calloc(); _Native.RegOpenKeyEx(hkey); try { return _Native.RegQueryValueEx(alloc, hkey); } catch (e) { rethrow; } finally { _Native.RegCloseKey(hkey); } }).replaceAll(RegExp(r'[\u0000-\u001F\u007F]'), '').trim(); } class _Native { // Load the advapi32.dll library static final _advapi32 = DynamicLibrary.open('Advapi32.dll'); // Define the RegOpenKeyExW function signature static final _RegOpenKeyExA = _advapi32 .lookupFunction< Int32 Function(IntPtr, Pointer, Uint32, Uint32, Pointer), int Function(int, Pointer, int, int, Pointer) >('RegOpenKeyExA'); // Define the RegCloseKey function signature static final _RegCloseKey = _advapi32 .lookupFunction('RegCloseKey'); // Define the RegQueryValueExW function signature static final _RegQueryValueExA = _advapi32 .lookupFunction< Int32 Function( IntPtr, Pointer, Pointer, Pointer, Pointer, Pointer, ), int Function( int, Pointer, Pointer, Pointer, Pointer, Pointer, ) >('RegQueryValueExA'); // Define the HKEY_LOCAL_MACHINE constant static const _HKEY_LOCAL_MACHINE = 0x80000002; static const _KEY_QUERY_VALUE = 0x0001; static const _KEY_WOW64_64KEY = 0x0100; static const kSuccess = 0; static const kRegKey = "SOFTWARE\\Microsoft\\Cryptography"; static const kValueKey = "MachineGuid"; static void RegOpenKeyEx(Pointer hkey) { final res = _RegOpenKeyExA( _HKEY_LOCAL_MACHINE, kRegKey.toNativeUtf8(), 0, _KEY_QUERY_VALUE | _KEY_WOW64_64KEY, hkey, ); if (res != _Native.kSuccess) { throw Exception('Failed to open registry: $res'); } } static void RegCloseKey(Pointer hkey) { _RegCloseKey(hkey.value); } static String RegQueryValueEx(Arena alloc, Pointer hkey) { final dataTypePtr = alloc(); dataTypePtr.value = 0; final dataSizePtr = alloc(); var res = _RegQueryValueExA( hkey.value, kValueKey.toNativeUtf8(), nullptr, dataTypePtr, nullptr, dataSizePtr, ); if (kSuccess != res) { throw Exception('Failed to get registry value size: $res'); } final data = alloc(dataSizePtr.value); res = _RegQueryValueExA( hkey.value, kValueKey.toNativeUtf8(), nullptr, dataTypePtr, data, dataSizePtr, ); if (kSuccess != res) { throw Exception('Failed to get registry value: $res'); } return utf8.decode(data.asTypedList(dataSizePtr.value)); } }