public IEnumerable <NtObjectBase> ListDirectory(string path, bool recurse = false, WellKnownType filterType = WellKnownType.Unknown) { OBJECT_ATTRIBUTES objectAttributes = new OBJECT_ATTRIBUTES(path, 0); NtStatus retVal = Win32.NtOpenDirectoryObject(out var directoryHandle, DirectoryAccessEnum.DIRECTORY_QUERY, ref objectAttributes); if (retVal != NtStatus.STATUS_SUCCESS) { ErrorHelper.Throw(retVal, $"NtOpenDirectoryObject, parentPath: {path}"); } uint singleDirInfo = (uint)Marshal.SizeOf <OBJECT_DIRECTORY_INFORMATION>(); using (directoryHandle) using (UnmanagedMemory mem = new UnmanagedMemory((int)(256 * singleDirInfo))) { bool restart = true; NtStatus status; uint context = 0; do { mem.Clear(); status = Win32.NtQueryDirectoryObject(directoryHandle, mem.Handle, mem.Bytes, false, restart, ref context, out _); restart = false; IntPtr ptr = mem.Handle; while (true) { OBJECT_DIRECTORY_INFORMATION dir = Marshal.PtrToStructure <OBJECT_DIRECTORY_INFORMATION>(ptr); ptr = new IntPtr(ptr.ToInt64() + (int)singleDirInfo); if (dir.Name.Length == 0) { break; } string typeName = dir.TypeName.ToString(); string name = dir.Name.ToString(); WellKnownType wellKnownType = StaticStrings.ToWellKnownType(typeName); if (filterType != WellKnownType.Unknown && filterType != wellKnownType) { continue; } if (wellKnownType == WellKnownType.Directory) { NtDirectory directory = new NtDirectory(typeName, path, name); yield return(directory); if (recurse) { foreach (NtObjectBase subObject in ListDirectory(directory.FullName, true, filterType)) { yield return(subObject); } } continue; } NtObjectBase result = new NtObjectBase(typeName, path, name); result = ConvertToSpecificType(result); yield return(result); } } while (status == NtStatus.STATUS_MORE_ENTRIES); } }