readAllRegistryValues static method
Read all registry values from a given key path
keyPath - Registry key path (e.g., r'.DEFAULT\Software\HaloAgent')
Returns a map of registry value names to their values
Implementation
static Future<Map<String, String>> readAllRegistryValues(
String keyPath,
) async {
DebugLogger.log('[WindowsRegistry] === readAllRegistryValues() called ===');
DebugLogger.log('[WindowsRegistry] Key path: $keyPath');
final hKey = calloc<IntPtr>();
final subKeyPtr = keyPath.toNativeUtf16();
final nameBuffer = calloc<Uint16>(256); // Allocate buffer for name (WCHAR)
final valueBuffer = calloc<Uint8>(1024); // Allocate buffer for value (BYTE)
final nameLengthPtr = calloc<DWORD>();
final valueLengthPtr = calloc<DWORD>();
final typePtr = calloc<DWORD>();
final values = <String, String>{};
try {
// Open the registry key
DebugLogger.log('[WindowsRegistry] Opening registry key...');
final openResult = RegOpenKeyEx(
HKEY_USERS,
subKeyPtr,
0,
REG_SAM_FLAGS.KEY_READ,
hKey,
);
if (openResult != WIN32_ERROR.ERROR_SUCCESS) {
DebugLogger.log(
'[WindowsRegistry] ❌ Failed to open registry key. Error code: $openResult',
);
return values;
}
DebugLogger.log('[WindowsRegistry] ✅ Registry key opened successfully');
int index = 0;
while (true) {
// Reset lengths for each iteration
nameLengthPtr.value = 256; // Name buffer length in WCHARs
valueLengthPtr.value = 1024; // Value buffer length in bytes
final enumResult = RegEnumValue(
hKey.value,
index,
nameBuffer as Pointer<Utf16>,
nameLengthPtr,
nullptr,
typePtr,
valueBuffer,
valueLengthPtr,
);
if (enumResult == WIN32_ERROR.ERROR_NO_MORE_ITEMS) {
DebugLogger.log('[WindowsRegistry] No more items to enumerate');
break; // No more items to enumerate
}
if (enumResult != WIN32_ERROR.ERROR_SUCCESS) {
DebugLogger.log(
'[WindowsRegistry] ❌ Error enumerating values. Error code: $enumResult',
);
break;
}
// Decode the name (UTF-16) to Dart String
final name = _decodeUtf16(nameBuffer, nameLengthPtr.value);
DebugLogger.log('[WindowsRegistry] Found registry value: $name');
// Decode the value buffer based on the type
String value;
switch (typePtr.value) {
case REG_VALUE_TYPE.REG_SZ: // String
value = _decodeUtf16(
valueBuffer.cast<Uint16>(),
valueLengthPtr.value,
);
DebugLogger.log('[WindowsRegistry] Value type: REG_SZ, Value: $value');
break;
case REG_VALUE_TYPE.REG_DWORD: // DWORD (integer)
value = valueBuffer.cast<Uint32>().value.toString();
DebugLogger.log('[WindowsRegistry] Value type: REG_DWORD, Value: $value');
break;
default:
value = 'Unsupported value type: ${typePtr.value}';
DebugLogger.log(
'[WindowsRegistry] ⚠️ Unsupported value type: ${typePtr.value}',
);
break;
}
// Add to the map
values[name] = value;
index++;
}
DebugLogger.log('[WindowsRegistry] ✅ Read ${values.length} registry values');
} catch (e) {
DebugLogger.log('[WindowsRegistry] ❌ Exception reading registry: $e');
} finally {
// Free allocated memory
calloc.free(hKey);
calloc.free(subKeyPtr);
calloc.free(nameBuffer);
calloc.free(valueBuffer);
calloc.free(nameLengthPtr);
calloc.free(valueLengthPtr);
calloc.free(typePtr);
}
return values;
}