| 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
 |