Mega Search
23.2 Million


Sign Up

Make a donation  
Using NTEnumerateKey to get subkey names  
News Group: embarcadero.public.delphi.nativeapi

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

Vote for best question.
Score: 0  # Vote:  0
Date Posted: 6-Oct-2014, at 4:25 PM EST
From: Nigel Thomas