Einzelnen Beitrag anzeigen

Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#7

AW: (T)Registry und Wow6432Node

  Alt 10. Mai 2015, 15:56
So, nachdem ein erstes Win32-Kompilat sofort funktionierte und ich einige Stunden brauchte, um herauszufinden, dass Enums für die API 4 Byte groß sein müssen, funktioniert es nun auch mit Win64.

Den Code hab ich aus verschiedenen Quellen zusammengestöpselt, vor allem von dieser russischen Seite, und ein bisschen angepasst:
Delphi-Quellcode:
type NTSTATUS = Cardinal;

  {$MINENUMSIZE 4}
  KEY_INFORMATION_CLASS = (KeyBasicInformation, KeyNodeInformation, KeyFullInformation,
                           KeyNameInformation, KeyCachedInformation, KeyFlagsInformation,
                           KeyVirtualizationInformation, KeyHandleTagsInformation, MaxKeyInfoClass);
  {$MINENUMSIZE 1}

  KEY_NAME_INFORMATION = packed record
    NameLength: ULONG;
    Name: array[0..0] of WideChar;
  end;
  PKEY_NAME_INFORMATION = ^KEY_NAME_INFORMATION;

function NtQueryKey(KeyHandle: HKEY; KeyInformationClass: KEY_INFORMATION_CLASS; KeyInformation: Pointer;
                    Length: ULONG; ResultLength: PULONG): NTSTATUS; stdcall; external 'ntdll.dll';

//------------------------------------------------------------------------------

function GetNtKeyNameFromHKEY(const AHKEY: HKEY): string;
var Len: Cardinal;
    Info: PKEY_NAME_INFORMATION;
    Name: PWideChar;
begin
  NtQueryKey(AHKEY, KeyNameInformation, nil, 0, @Len);
  GetMem(Info, Len);
  try
    if NtQueryKey(AHKEY, KeyNameInformation, Info, Len, @Len) = 0 then
    begin
      GetMem(Name, Info.NameLength + 2);
      try
        Move(Info.Name, Name^, Info.NameLength);
        Name[Info.NameLength div 2]:= #0;
        {$IFDEF UNICODE}
        Result:= Name;
        {$ELSE}
        Result:= AnsiString(Name);
        {$ENDIF}
       finally
         FreeMem(Name);
       end;
     end;
  finally
    FreeMem(Info);
  end;
end;

//------------------------------------------------------------------------------

procedure TForm1.Button1Click(Sender: TObject);
const KEY = '\Software\Microsoft\Windows\CurrentVersion\Run';
var reg: TRegistry;
begin
// ShowMessage(IntToStr(SizeOf(KEY_INFORMATION_CLASS)));
    reg:= TRegistry.Create(KEY_READ);
    reg.RootKey:= HKEY_LOCAL_MACHINE;
    try
      if reg.OpenKey(KEY, False) then begin
          Edit1.Text:= reg.CurrentPath;
          Edit2.Text:= GetNtKeyNameFromHKEY(reg.CurrentKey);
      end;
    finally
      reg.Free;
    end;
end;
Nun, das funktioniert auch gut und gibt auf einem XP64
Code:
\REGISTRY\MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run
zurück. Da ich die Schlüssel aber gern im normalen Format haben möchte, muss hinterher noch ein StringReplace erfolgen. Nun weiß ich aber eigentlich schon vorher, ob hier ein Wow6432Node rauskommen müsste, denn ich habe ein Enum der verschiedenen Schlüssel, in dem die 32 und 64 Bit Zweige getrennt aufgeführt sind.

Fazit: Ich hab die Wahl zwischen NtQueryKey + StringReplace oder nur StringReplace (bzw. Verketten von Strings, wenn man es entsprechend anstellt) .

Unabhängig davon danke an himitsu für den richtigen Hinweis!

MfG Dalai
  Mit Zitat antworten Zitat