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);
                }
        }