Read Registry Value - Delphi

DarkCoderSc personal avatar
DarkCoderSc

Jean-Pierre LESUEUR

// ...

const
  RRF_RT_ANY = $0000FFFF;

// ...

function RegGetValueW(hkey : HKEY; lpSubKey : LPCWSTR; lpValue : LPCWSTR; dwFlags : DWORD; out dwType : DWORD;
  pvData : PVOID; out pcbData : DWORD) : LONG; stdcall; external 'Advapi32.dll';

// ...

procedure ReadRegistryValue(const AHive : HKEY; const AKeyPath, AValueName : String; out AValueType : DWORD;
  out pData : Pointer; out ADataSize : DWORD);
begin
  var AKeyHandle : HKEY;
  var AResult := RegOpenKeyExW(AHive, PWideChar(AKeyPath), 0, KEY_QUERY_VALUE, AKeyHandle);
  if AResult <> ERROR_SUCCESS then
    raise EWindowsException.Create('RegOpenKeyW', AResult);
  try
    pData := nil;
    ADataSize := 0;
    ///

    AResult := RegGetValueW(AKeyHandle, nil, PWideChar(AValueName), RRF_RT_ANY, AValueType, nil, ADataSize);
    if (AResult <> ERROR_SUCCESS) and (AResult <> ERROR_MORE_DATA) then
      raise EWindowsException.Create('RegGetValueW', AResult);
    ///

    GetMem(pData, ADataSize * SizeOf(WideChar));
    try
      AResult := RegGetValueW(
        AKeyHandle,
        nil,
        PWideChar(AValueName),
        RRF_RT_ANY,
        AValueType,
        pData,
        ADataSize
      );
      if AResult <> ERROR_SUCCESS then
        raise EWindowsException.Create('RegGetValueW', AResult);
    except
      FreeMem(pData, ADataSize);
    end;
  finally
    RegCloseKey(AKeyHandle);
  end;
end;

function ReadRegistryValueAsGenericString(const AHive : HKEY; const AKeyPath, AValueName : String) : String;
begin
  result := '';
  ///

  var AValueType : DWORD;
  var pData := nil;
  var ADataSize : DWORD;

  ReadRegistryValue(AHive, AKeyPath, AValueName, AValueType, pData, ADataSize);
  try
    if not Assigned(pData) or (ADataSize = 0) then
      Exit();
    ///

    case AValueType of
      REG_SZ, REG_EXPAND_SZ:
        result := Format('REG_SZ: %s', [PWideChar(pData)]);

      REG_MULTI_SZ: begin
        var AStringList := TStringList.Create();
        try
          var p := PWideChar(pData);
          while p^ <> #0 do begin
            AStringList.Add(String(p));

            ///
            Inc(p, lstrlenW(p) + 1);
          end;

          ///
          AStringList.LineBreak := '\0';
          result := 'REG_MSZ: ' + AStringList.Text;
        finally
          if Assigned(AStringList) then
            FreeAndNil(AStringList);
        end;
      end;

      REG_DWORD:
        result := Format('DWORD: 0x%.8X (%d)', [PDWORD(pData)^, PDWORD(pData)^]);

      REG_QWORD:
        result := Format('QWORD: 0x%.16X (%d)', [PUInt64(pData)^, PUInt64(pData)^]);

      REG_BINARY: begin
        var AStringBuilder := TStringBuilder.Create(ADataSize * 3 (* 1 Byte = 2 (Hex) + 1 (Space) *));
        try
          for var n := 0 to ADataSize -1 do begin
            AStringBuilder.AppendFormat('%.2X ', [PByte(NativeUInt(pData) + n)^]);
          end;

          ///
          result := 'Binary: ' + AStringBuilder.ToString.TrimRight;
        finally
          if Assigned(AStringBuilder) then
            FreeAndNil(AStringBuilder);
        end;
      end;
    end;
  finally
    FreeMem(pData, ADataSize);
  end;
end;

// ...

begin
  try
    var ATargetHive := HKEY_CURRENT_USER;
    var ATargetKey := 'Software';

    WriteLn(ReadRegistryValueAsGenericString(ATargetHive, ATargetKey, 'My DWORD'));
    WriteLn(ReadRegistryValueAsGenericString(ATargetHive, ATargetKey, 'My QWORD'));
    WriteLn(ReadRegistryValueAsGenericString(ATargetHive, ATargetKey, 'My String'));
    WriteLn(ReadRegistryValueAsGenericString(ATargetHive, ATargetKey, 'My Binary'));
  except
    on e : Exception do
      WriteLn(e.Message);
  end;

// ...

Creating and researching code snippets takes time and effort. You’re welcome to share them through your own platforms, but please don’t forget to credit the original author, here: Jean-Pierre LESUEUR.

no AI logo


Depends On


Created

December 2, 2025

Last Revised

December 2, 2025