Using NTEnumerateKey to get subkey names |
|
Hi all,
Using D2007.
I've been getting to grips with using Native API registry calls over
the last couple of weeks, so I can try to remove keys that have null,
or "invalid" - i.e. not readable by the Windows API registry
routines - characters.
I now know how to delete a registry key using the native API, so long
as I know its name. However NtDeleteKey can only delete keys if there
are no subkeys.
What I need to do is to be able to enumerate a registry key and obtain
all its subkey names, so that I can delete each subkey in turn before
finally being able to delete the targeted key. For that, my research
indicates I need to call NtEnumerateKey on an open key, and parse it
for any subkeys. Delphi examples of calling NtEnumerateKey are few in
number, and both conflicting and confusing.
I would be very grateful if someone who knows how to successfully use
this function to obtain subkey names could point me in the right
direction.
This is the code I use to open the key:
{code}
function NhtNtOpenKey(const rootKey: HKEY; const sKeyName: String;
const dwAccessRequired: DWORD; var KeyHandle: THandle;
const bNoRedir: boolean = False): boolean;
////////////////////////////////////////////////////////////////////////////////
///
/// Routine to open a registry key using Native API
///
/// Returns True if key opened, returning a handle to the open key in
/// KeyHandle
///
/// Raises an exception on failure, which should be handled by the
calling
/// routine
///
/// NB: if the function returns TRUE, the calling function is
responsible
/// for closing the returned KeyHandle
///
////////////////////////////////////////////////////////////////////////////////
var
KeyName: UNICODE_STRING;
sKey: WideString;
dwAccessMode: DWORD;
ObjectAttributes: OBJECT_ATTRIBUTES;
Status: LongWord;
begin
// create the registry key string
sKey := ConvertRootKeyToNativeRootKey(rootKey) + sKeyName; //
converts rootkey to "\Registry\Machine" or "Registry\User\"
// convert the keyname string to a UnicodeString
KeyName.Buffer := PWideChar(sKey);
KeyName.Length := Length(sKey) * SizeOf(WideChar);
KeyName.MaximumLength := KeyName.Length;
// set the access mode required: if bNoRedir is TRUE then set x64
// redirection off
if bNoRedir then
dwAccessMode := dwAccessRequired or KEY_WOW64_64KEY
else
dwAccessMode := dwAccessRequired;
InitializeObjectAttributes(ObjectAttributes, @KeyName,
OBJ_CASE_INSENSITIVE,
0, nil);
Status := NtOpenKey(KeyHandle, dwAccessMode, ObjectAttributes);
Result := NT_SUCCESS(Status);
if not Result then
RaiseLastOSError(RtlNtStatusToDosError(Status));
end; // NhtNtOpenKey
{code}
--
Nigel
|