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