static void Main(string[] args)
        {
            bool             show_help    = false;
            bool             recursive    = false;
            HashSet <string> exclude_dirs = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            int pid = Process.GetCurrentProcess().Id;

            try
            {
                OptionSet opts = new OptionSet()
                {
                    { "r", "Recursive tree directory listing",
                      v => recursive = v != null },
                    { "sddl", "Print full SDDL security descriptors", v => _print_sddl = v != null },
                    { "p|pid=", "Specify a PID of a process to impersonate when checking", v => pid = int.Parse(v.Trim()) },
                    { "w", "Show only write permissions granted", v => _show_write_only = v != null },
                    { "k=", String.Format("Filter on a specific directory right [{0}]",
                                          String.Join(",", Enum.GetNames(typeof(DirectoryAccessRights)))), v => _dir_rights |= ParseRight(v, typeof(DirectoryAccessRights)) },
                    { "x=", "Specify a base path to exclude from recursive search", v => exclude_dirs.Add(v) },
                    { "t=", "Specify a type of object to include", v => _type_filter.Add(v) },
                    { "g", "Map access mask to generic rights.", v => _map_to_generic = v != null },
                    { "e", "Display errors when opening objects, ignores access denied.", v => _show_errors = v != null },
                    { "h|help", "show this message and exit", v => show_help = v != null },
                };

                List <string> paths = opts.Parse(args);

                if (show_help || (paths.Count == 0))
                {
                    ShowHelp(opts);
                }
                else
                {
                    using (NtToken token = NtToken.OpenProcessToken(pid))
                    {
                        foreach (string path in paths)
                        {
                            try
                            {
                                using (NtDirectory dir = OpenDirectory(path))
                                {
                                    HashSet <string> walked = new HashSet <string>(exclude_dirs, StringComparer.OrdinalIgnoreCase);
                                    Console.WriteLine("Dumping Directory: {0}", path);
                                    DumpDirectory(dir, token, recursive, walked);
                                }
                            }
                            catch (NtException ex)
                            {
                                Console.WriteLine("Couldn't open {0} - {1}", path, ex.Message);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
        /// <summary>
        /// Overidden method to check if an item is a container.
        /// </summary>
        /// <param name="path">The drive path to check.</param>
        /// <returns>True if the item is a container.</returns>
        protected override bool IsItemContainer(string path)
        {
            bool is_container = false;

            if (GetDrive() == null)
            {
                return(false);
            }

            path = GetRelativePath(PSPathToNT(path));
            // The root always exists.
            if (path.Length == 0)
            {
                return(true);
            }

            try
            {
                using (NtDirectory dir = GetPathDirectory(path))
                {
                    ObjectDirectoryInformation dir_info = GetEntry(dir, path);
                    is_container = dir_info != null &&
                                   dir_info.TypeName.Equals("directory", StringComparison.OrdinalIgnoreCase);
                }
            }
            catch (NtException)
            {
            }

            return(is_container || GetDrive().DirectoryRoot.DirectoryExists(path));
        }
        private IEnumerable <string> GetObjectList(string typename)
        {
            HashSet <string> walked = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
            HashSet <string> names  = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            try
            {
                using (NtDirectory dir = NtDirectory.Open(@"\", null, DirectoryAccessRights.Query))
                {
                    UpdateObjectList(typename, walked, dir, names);
                }
            }
            catch (NtException)
            {
            }

            try
            {
                using (NtDirectory dir = NtDirectory.OpenSessionDirectory("BaseNamedObjects"))
                {
                    UpdateObjectList(typename, walked, dir, names);
                }
            }
            catch (NtException)
            {
            }

            List <string> ret = new List <string>(names);

            ret.Sort();

            return(ret);
        }
        protected override void GetItem(string path)
        {
            if (GetDrive() == null)
            {
                return;
            }

            string normalized_path = NormalizePath(path);

            if (_item_cache.ContainsKey(normalized_path))
            {
                ObjectDirectoryEntry entry = _item_cache[normalized_path];
                WriteItemObject(entry, path, entry.IsDirectory);
            }
            else
            {
                using (NtDirectory dir = GetPathDirectory(path))
                {
                    ObjectDirectoryInformation dir_info = GetEntry(dir, path);
                    if (dir_info != null)
                    {
                        WriteItemObject(new ObjectDirectoryEntry(GetDrive().DirectoryRoot, normalized_path, dir_info.Name, dir_info.TypeName), path.TrimStart('\\'), dir_info.IsDirectory);
                    }
                }
            }
        }
        private void UpdateObjectList(string typename, HashSet <string> walked, NtDirectory dir, HashSet <string> names)
        {
            if (!walked.Add(dir.FullPath))
            {
                return;
            }

            foreach (var entry in dir.Query())
            {
                if (entry.NtTypeName.Equals(typename, StringComparison.OrdinalIgnoreCase))
                {
                    names.Add(entry.FullPath);
                }
                else if (entry.IsDirectory)
                {
                    using (var obj_attr = new ObjectAttributes(entry.Name, AttributeFlags.CaseInsensitive, dir))
                    {
                        using (var subdir = NtDirectory.Open(obj_attr, DirectoryAccessRights.Query, false))
                        {
                            if (subdir.IsSuccess)
                            {
                                UpdateObjectList(typename, walked, subdir.Result, names);
                            }
                        }
                    }
                }
            }
        }
 private static NtDirectory OpenNamespace(string path)
 {
     using (BoundaryDescriptor boundary = BoundaryDescriptor.CreateFromString(path))
     {
         return(NtDirectory.OpenPrivateNamespace(boundary));
     }
 }
Esempio n. 7
0
        private void UpdateObjectList(string typename, HashSet <string> walked, NtDirectory dir, HashSet <string> names)
        {
            if (!walked.Add(dir.FullPath))
            {
                return;
            }

            foreach (var entry in dir.Query())
            {
                if (entry.NtTypeName.Equals(typename, StringComparison.OrdinalIgnoreCase))
                {
                    names.Add(entry.FullPath);
                }
                else if (entry.IsDirectory)
                {
                    try
                    {
                        using (NtDirectory subdir = NtDirectory.Open(entry.Name, dir, DirectoryAccessRights.Query))
                        {
                            UpdateObjectList(typename, walked, subdir, names);
                        }
                    }
                    catch (NtException)
                    {
                    }
                }
            }
        }
        void ISecurityDescriptorCmdletProvider.GetSecurityDescriptor(string path, AccessControlSections includeSections)
        {
            string relative_path = GetRelativePath(PSPathToNT(path));

            using (NtDirectory dir = GetPathDirectory(relative_path))
            {
                if (relative_path.Length == 0)
                {
                    WriteItemObject(new GenericObjectSecurity(dir, includeSections), path, true);
                }
                else
                {
                    ObjectDirectoryInformation dir_info = GetEntry(dir, relative_path);
                    if (dir_info == null)
                    {
                        throw new NtException(NtStatus.STATUS_OBJECT_NAME_NOT_FOUND);
                    }

                    using (NtObject obj = dir_info.Open(GenericAccessRights.ReadControl))
                    {
                        WriteItemObject(new GenericObjectSecurity(obj, includeSections), path, obj is NtDirectory);
                    }
                }
            }
        }
        private void GetChildItemsRecursive(string relative_path, bool recurse)
        {
            try
            {
                using (NtDirectory dir = GetDirectory(relative_path))
                {
                    Queue <string> dirs = new Queue <string>();
                    foreach (ObjectDirectoryInformation dir_info in dir.Query())
                    {
                        string new_path = BuildRelativePath(relative_path, dir_info.Name);
                        WriteItemObject(new NtDirectoryEntry(GetDrive().DirectoryRoot, new_path,
                                                             recurse ? new_path : dir_info.Name, dir_info.TypeName), NTPathToPS(BuildDrivePath(new_path)), dir_info.IsDirectory);
                        if (recurse && dir_info.IsDirectory)
                        {
                            dirs.Enqueue(new_path);
                        }
                    }

                    if (recurse && dirs.Count > 0)
                    {
                        foreach (string new_dir in dirs)
                        {
                            GetChildItemsRecursive(new_dir, recurse);
                        }
                    }
                }
            }
            catch (NtException)
            {
                if (!recurse)
                {
                    throw;
                }
            }
        }
 static NtDirectory CreateDirectory()
 {
     using (var obja = CreateObjectAttributes(null, null))
     {
         return(NtDirectory.Create(obja, DirectoryAccessRights.MaximumAllowed, null));
     }
 }
Esempio n. 11
0
 private static void SetupRootDirectory(NtDirectory root)
 {
     ObjectManager.Apply(root, new ObjectManager.ITask[] {
         new ObjectManager.CloneDirectoryTask("FileSystem"),
         new ObjectManager.CloneDirectoryTask("Windows"),
         new ObjectManager.CloneDirectoryTask("Callback"),
         new ObjectManager.CloneDirectoryTask("Driver"),
         new ObjectManager.CloneDirectoryTask("DriverStore"),
         new ObjectManager.CloneDirectoryTask("RPC Control"),
         new ObjectManager.CloneDirectoryTask("BaseNamedObjects")
         {
             new ObjectManager.SymlinkTask("FontCachePort", @"\BaseNamedObjects\FontCachePort", scope: ObjectManager.SymlinkScope.Global),
             new ObjectManager.SymlinkTask("FontCachePort3.0.0.0", @"\BaseNamedObjects\FontCachePort3.0.0.0", scope: ObjectManager.SymlinkScope.Global),
             new ObjectManager.SymlinkTask("CoreMessagingRegistrar", @"\BaseNamedObjects\CoreMessagingRegistrar", scope: ObjectManager.SymlinkScope.Global),
             new ObjectManager.SymlinkTask("Local", @"\BaseNamedObjects"),
             new ObjectManager.SymlinkTask("Global", @"\BaseNamedObjects"),
             new ObjectManager.SymlinkTask("Session", @"\Sessions\BNOLINKS"),
             new ObjectManager.SymlinkTask("AppContainerNamedObject", @"\Sessions\0\AppContainerNamedObject"),
             new ObjectManager.CloneDirectoryTask("Restricted")
         },
         new ObjectManager.CloneDirectoryTask("GLOBAL??")
         {
             new ObjectManager.SymlinkTask("C:", @"\Device\HarddiskVolume4", scope: ObjectManager.SymlinkScope.Global),
             new ObjectManager.SymlinkTask("D:", @"\Device\HarddiskVolume1", scope: ObjectManager.SymlinkScope.Global),
             new ObjectManager.SymlinkTask("X:", @"\Device\HarddiskVolume1\vv", scope: ObjectManager.SymlinkScope.Global),
             new ObjectManager.SymlinkTask("AUX", @"\Device\Null"),
             new ObjectManager.SymlinkTask("CON", @"\Device\ConDrv\Console"),
             new ObjectManager.SymlinkTask("CONIN$", @"\Device\ConDrv\CurrentIn"),
             new ObjectManager.SymlinkTask("CONOUT$", @"\Device\ConDrv\CurrentOut"),
             new ObjectManager.SymlinkTask("NUL", @"\Device\Null"),
             new ObjectManager.SymlinkTask("PIPE", @"\Device\NamedPipe"),
             new ObjectManager.SymlinkTask("Tcp", @"\Device\Tcp"),
         },
     });
 }
Esempio n. 12
0
        /// <summary>
        /// Finds ALPC endpoints which allows for the server binding. This brute forces all ALPC ports to try and find
        /// something which will accept the bind.
        /// </summary>
        /// <remarks>This could hang if the ALPC port is owned by a suspended process.</remarks>
        /// <param name="interface_id">Interface UUID to lookup.</param>
        /// <param name="interface_version">Interface version lookup.</param>
        /// <returns>A list of RPC endpoints which can bind the interface.</returns>
        /// <exception cref="NtException">Throws on error.</exception>
        public static IEnumerable <RpcEndpoint> FindAlpcEndpointForInterface(Guid interface_id, Version interface_version)
        {
            using (var dir = NtDirectory.Open(@"\RPC Control"))
            {
                var nt_type = NtType.GetTypeByType <NtAlpc>().Name;

                foreach (var port in dir.Query().Where(e => e.NtTypeName == nt_type))
                {
                    bool success = false;
                    try
                    {
                        using (var server = new RpcClient(interface_id, interface_version))
                        {
                            server.Connect(port.Name);
                            success = true;
                        }
                    }
                    catch
                    {
                    }
                    if (success)
                    {
                        yield return(new RpcEndpoint(interface_id, interface_version,
                                                     SafeRpcBindingHandle.Compose(null, "ncalrpc", null, port.Name, null), false));
                    }
                }
            }
        }
Esempio n. 13
0
        public override NtObject NewItem(string relative_path, string item_type_name, object new_item_value)
        {
            switch (item_type_name.ToLower())
            {
            case "event":
                return(NtEvent.Create(relative_path, _dir, EventType.NotificationEvent, false));

            case "directory":
                return(NtDirectory.Create(relative_path, _dir, DirectoryAccessRights.MaximumAllowed));

            case "symboliclink":
            case "link":
                if (new_item_value == null)
                {
                    throw new ArgumentNullException(nameof(new_item_value), "Must specify value for the symbolic link");
                }
                return(NtSymbolicLink.Create(relative_path, _dir, new_item_value.ToString()));

            case "mutant":
                return(NtMutant.Create(relative_path, _dir, false));

            case "semaphore":
                int max_count = 1;
                if (new_item_value != null)
                {
                    max_count = Convert.ToInt32(new_item_value);
                }
                return(NtSemaphore.Create(relative_path, _dir, 0, max_count));

            default:
                throw new ArgumentException($"Can't create new object of type {item_type_name}");
            }
        }
        private void FindDevicesInDirectory(NtDirectory dir, Dictionary <string, SecurityDescriptorEntry> devices, int current_depth)
        {
            if (Stopping || current_depth <= 0)
            {
                return;
            }

            foreach (var entry in dir.Query())
            {
                if (entry.IsDirectory && Recurse)
                {
                    using (var new_dir = OpenDirectory(entry.Name, dir))
                    {
                        if (new_dir.IsSuccess)
                        {
                            FindDevicesInDirectory(new_dir.Result, devices, current_depth - 1);
                        }
                        else
                        {
                            WriteAccessWarning(dir, entry.Name, new_dir.Status);
                        }
                    }
                }
                else
                {
                    if (entry.NtTypeName.Equals("Device", StringComparison.OrdinalIgnoreCase))
                    {
                        if (!devices.ContainsKey(entry.FullPath))
                        {
                            devices.Add(entry.FullPath, GetSecurityDescriptor(entry.FullPath));
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Overriden method to check if an item exists.
        /// </summary>
        /// <param name="path">The drive path to check.</param>
        /// <returns>True if the item exists.</returns>
        protected override bool ItemExists(string path)
        {
            bool exists = false;

            if (GetDrive() == null)
            {
                return(false);
            }

            path = GetRelativePath(PSPathToNT(path));
            if (path.Length == 0)
            {
                return(true);
            }

            try
            {
                using (NtDirectory dir = GetPathDirectory(path))
                {
                    exists = GetEntry(dir, path) != null;
                }
            }
            catch (NtException)
            {
            }

            // If we can't find it indirectly, at least see if there's a directory with this name.
            return(exists || GetDrive().DirectoryRoot.DirectoryExists(path));
        }
        /// <summary>
        /// Overridden method to get the item from a path.
        /// </summary>
        /// <param name="path">The drive path.</param>
        protected override void GetItem(string path)
        {
            if (GetDrive() == null)
            {
                return;
            }

            string relative_path = GetRelativePath(PSPathToNT(path));

            using (NtDirectory dir = GetPathDirectory(relative_path))
            {
                if (relative_path.Length == 0)
                {
                    WriteItemObject(new NtDirectoryEntry(GetDrive().DirectoryRoot, relative_path, String.Empty, "Directory"),
                                    NTPathToPS(BuildDrivePath(relative_path)), true);
                }
                else
                {
                    ObjectDirectoryInformation dir_info = GetEntry(dir, relative_path);
                    if (dir_info != null)
                    {
                        WriteItemObject(new NtDirectoryEntry(GetDrive().DirectoryRoot, relative_path, dir_info.Name, dir_info.TypeName),
                                        NTPathToPS(BuildDrivePath(relative_path)), dir_info.IsDirectory);
                    }
                }
            }
        }
        IEnumerable <string> ExpandDirectoryEntryMatches(string path)
        {
            Queue <string> remaining = new Queue <string>(path.Split('\\'));
            List <string>  matches   = new List <string>();

            if (remaining.Count == 0)
            {
                return(matches);
            }

            try
            {
                string      base_path = String.Join(@"\", remaining.Take(remaining.Count - 1));
                NtDirectory root_dir  = GetDrive().DirectoryRoot;
                // We'll first try the general case of unglobbed dir and a globbed final name.
                using (NtDirectory base_dir =
                           remaining.Count > 1 ? NtDirectory.Open(base_path, root_dir, DirectoryAccessRights.Query)
                                        : root_dir.Duplicate(DirectoryAccessRights.Query))
                {
                    AddMatches(base_dir, BuildRelativePath(base_path, String.Empty), new string[] { remaining.Last() }, matches);
                }
            }
            catch (NtException)
            {
                // If we couldn't open the drive then try brute force approach.
                AddMatches(GetDrive().DirectoryRoot, String.Empty, remaining, matches);
            }

            return(matches.Select(s => NTPathToPS(BuildDrivePath(s))));
        }
Esempio n. 18
0
        /// <summary>
        /// Overridden method to create a new drive.
        /// </summary>
        /// <param name="drive">The template drive info.</param>
        /// <returns>The new drive info.</returns>
        protected override PSDriveInfo NewDrive(PSDriveInfo drive)
        {
            if (drive == null)
            {
                WriteError(new ErrorRecord(
                               new ArgumentNullException(nameof(drive)),
                               "NullDrive",
                               ErrorCategory.InvalidArgument,
                               null));

                return(null);
            }

            if (string.IsNullOrWhiteSpace(drive.Root) && (!drive.Root.StartsWith(GLOBAL_ROOT) || !drive.Root.StartsWith(NAMESPACE_ROOT)))
            {
                WriteError(new ErrorRecord(
                               new ArgumentNullException("drive.Root"),
                               "InvalidRoot",
                               ErrorCategory.InvalidArgument,
                               null));

                return(null);
            }

            try
            {
                if (drive.Root.StartsWith(NAMESPACE_ROOT))
                {
                    using (var descriptor = BoundaryDescriptor.CreateFromString(drive.Root.Substring(NAMESPACE_ROOT.Length)))
                    {
                        using (NtDirectory dir = NtDirectory.OpenPrivateNamespace(descriptor))
                        {
                            ObjectManagerPSDriveInfo objmgr_drive = new ObjectManagerPSDriveInfo(dir.Duplicate(), drive);
                            return(objmgr_drive);
                        }
                    }
                }
                else
                {
                    using (NtDirectory root = NtDirectory.Open(@"\"))
                    {
                        using (NtDirectory dir = NtDirectory.Open(drive.Root.Substring(GLOBAL_ROOT.Length), root, DirectoryAccessRights.MaximumAllowed))
                        {
                            ObjectManagerPSDriveInfo objmgr_drive = new ObjectManagerPSDriveInfo(dir.Duplicate(), drive);
                            return(objmgr_drive);
                        }
                    }
                }
            }
            catch (NtException ex)
            {
                WriteError(new ErrorRecord(
                               ex,
                               "NoRoot",
                               ErrorCategory.PermissionDenied,
                               drive));
                return(null);
            }
        }
 private static NtResult <NtDirectory> OpenDirectory(string path, NtObject root)
 {
     using (ObjectAttributes obja = new ObjectAttributes(path,
                                                         AttributeFlags.CaseInsensitive, root))
     {
         return(NtDirectory.Open(obja, DirectoryAccessRights.Query, false));
     }
 }
        private void DumpDirectory(IEnumerable <TokenEntry> tokens, HashSet <string> type_filter,
                                   AccessMask access_rights, NtDirectory dir, int current_depth)
        {
            DumpObject(tokens, type_filter, access_rights, dir, true);

            if (Stopping || current_depth <= 0)
            {
                return;
            }

            if (Recurse && dir.IsAccessGranted(DirectoryAccessRights.Query))
            {
                foreach (var entry in dir.Query())
                {
                    if (entry.IsDirectory)
                    {
                        using (var new_dir = OpenDirectory(entry.Name, dir))
                        {
                            if (new_dir.IsSuccess)
                            {
                                DumpDirectory(tokens, type_filter, access_rights, new_dir.Result, current_depth - 1);
                            }
                            else
                            {
                                WriteAccessWarning(dir, entry.Name, new_dir.Status);
                            }
                        }
                    }
                    else
                    {
                        NtType type = entry.NtType;
                        if (IsTypeFiltered(type.Name, type_filter) && !type.Name.Equals("Device", StringComparison.OrdinalIgnoreCase) &&
                            !type.Name.Equals("Key", StringComparison.OrdinalIgnoreCase))
                        {
                            if (type.CanOpen)
                            {
                                using (var result = OpenObject(entry, dir, GenericAccessRights.MaximumAllowed))
                                {
                                    if (result.IsSuccess)
                                    {
                                        DumpObject(tokens, type_filter, access_rights, result.Result, false);
                                    }
                                    else
                                    {
                                        WriteAccessWarning(dir, entry.Name, result.Status);
                                    }
                                }
                            }
                            else
                            {
                                WriteWarning(String.Format(@"Can't open {0}\{1} with type {2}", dir.FullPath, entry.Name, entry.NtTypeName));
                            }
                        }
                    }
                }
            }
        }
Esempio n. 21
0
 public NtDirectoryContainer(NtDirectory dir)
     : base(dir)
 {
     _dir = dir;
     if (dir.FullPath == @"\")
     {
         _key = new NtKeyContainer();
     }
 }
        /// <summary>
        /// Get the Win32 path for a specified path.
        /// </summary>
        /// <param name="path">The path component.</param>
        /// <returns>The full NT path.</returns>
        protected virtual string GetWin32Path(string path)
        {
            if (path.StartsWith(@"\"))
            {
                throw new ArgumentException("Win32 paths can't start with a path separator");
            }

            return($@"{NtDirectory.GetBasedNamedObjects()}\{path}");
        }
Esempio n. 23
0
        public override NtResult <NtObjectContainer> OpenForQuery(string relative_path, bool throw_on_error)
        {
            if (IsRegistryPath(relative_path))
            {
                return(_key.OpenForQuery(GetRegistryPath(relative_path), throw_on_error));
            }

            return(NtDirectory.Open(relative_path, _dir,
                                    DirectoryAccessRights.Query, throw_on_error).Map(Create));
        }
 static void UpdateDacl(string typename, NtDirectory root, string name, SecurityDescriptor sd)
 {
     using (var obj = NtObject.OpenWithType(typename, name, root, AttributeFlags.CaseInsensitive, GenericAccessRights.WriteDac, null, false))
     {
         if (obj.IsSuccess)
         {
             obj.Result.SetSecurityDescriptor(sd, SecurityInformation.Dacl);
         }
     }
 }
        private ObjectDirectoryInformation GetEntry(NtDirectory dir, string path)
        {
            int last_slash = path.LastIndexOf('\\');

            if (last_slash != -1)
            {
                path = path.Substring(last_slash + 1);
            }

            return(dir.GetDirectoryEntry(path));
        }
        static void FixupDbgView()
        {
            var sd = CreateSecurityDescriptor();

            using (NtDirectory objdir = NtDirectory.OpenBaseNamedObjects())
            {
                UpdateDacl("event", objdir, "DBWIN_DATA_READY", sd);
                UpdateDacl("section", objdir, "DBWIN_BUFFER", sd);
                UpdateDacl("event", objdir, "DBWIN_BUFFER_READY", sd);
            }
        }
Esempio n. 27
0
 private static NtDirectory OpenPath(ObjectDirectory root, string path)
 {
     try
     {
         return(NtDirectory.Open(path, root != null ? root._directory : null, DirectoryAccessRights.MaximumAllowed));
     }
     catch (NtException ex)
     {
         throw ex.AsWin32Exception();
     }
 }
 public NtDirectory OpenDirectory()
 {
     if (Name.StartsWith(@"\") || Directory != null)
     {
         return(NtDirectory.Open(Name, Directory, DirectoryAccessRights.MaximumAllowed));
     }
     else
     {
         return(NtDirectory.OpenPrivateNamespace(BoundaryDescriptor.CreateFromString(Name)));
     }
 }
 static NtDirectory OpenDirectory(string name)
 {
     if (name.StartsWith(@"\"))
     {
         return(NtDirectory.Open(name));
     }
     else
     {
         return(NtDirectory.OpenPrivateNamespace(BoundaryDescriptor.CreateFromString(name)));
     }
 }
        private bool disposedValue = false; // To detect redundant calls

        private void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (_directory != null)
                {
                    _directory.Close();
                    _directory = null;
                }
                disposedValue = true;
            }
        }
        internal ObjectDirectory(ObjectDirectory root, string object_path)
        {
            _orig_path = object_path;

            if (_orig_path.StartsWith("\\") || root != null)
            {
                _directory = OpenPath(root, _orig_path);
            }
            else
            {
                _directory = OpenNamespace(_orig_path);
            }

            PopulateEntries();
        }
        internal NtDirectoryEntry(NtDirectory base_directory, string relative_path, string name, string typename)
        {
            Name = name;
            TypeName = typename;
            RelativePath = relative_path;
            _base_directory = base_directory;

            switch (typename.ToLower())
            {
                case "directory":
                case "key":
                    IsDirectory = true;
                    break;
                case "symboliclink":
                    IsSymbolicLink = true;
                    break;
            }

            _maximum_granted_access = 0;
        }
        private ObjectDirectoryInformation GetEntry(NtDirectory dir, string path)
        {
            int last_slash = path.LastIndexOf('\\');
            if (last_slash != -1)
            {
                path = path.Substring(last_slash + 1);
            }

            return dir.GetDirectoryEntry(path);
        }
 public ObjectManagerPSDriveInfo(NtDirectory root, PSDriveInfo drive_info) 
     : base(drive_info)
 {
     DirectoryRoot = root;
 }            
        private void AddMatches(NtDirectory root, string base_path, IEnumerable<string> remaining, List<string> matches)
        {
            string current_entry = remaining.First();
            bool is_leaf = remaining.Count() == 1;
            List<ObjectDirectoryInformation> matching_entries = new List<ObjectDirectoryInformation>();
            
            if (root.IsAccessGranted(DirectoryAccessRights.Query))
            {
                // If this is not a leaf point we don't care about non-directory entries.
                ObjectDirectoryInformation[] dir_infos = root.Query().Where(d => is_leaf || d.IsDirectory).ToArray();
                foreach (ObjectDirectoryInformation dir_info in dir_infos)
                {
                    if (dir_info.Name.Equals(current_entry, StringComparison.OrdinalIgnoreCase))
                    {                        
                        matching_entries.Add(dir_info);
                        break;
                    }
                }

                // If we didn't find an explicit match then see if it's a glob.
                if (matching_entries.Count == 0 && HasGlobChars(current_entry))
                {
                    Regex globber = GlobToRegex(current_entry, false);
                    foreach (ObjectDirectoryInformation dir_info in dir_infos)
                    {
                        if (globber.IsMatch(dir_info.Name))
                        {
                            matching_entries.Add(dir_info);
                        }
                    }
                }
            }

            // Nothing matched.
            if (matching_entries.Count == 0)
            {
                return;
            }

            // We've reached the end of the road.
            if (is_leaf)
            {
                foreach (ObjectDirectoryInformation dir_info in matching_entries)
                {
                    string full_path = base_path + dir_info.Name;
                    _item_cache[full_path] = new NtDirectoryEntry(GetDrive().DirectoryRoot, PSPathToNT(full_path), dir_info.Name, dir_info.TypeName);
                    matches.Add(full_path);
                }
            }
            else
            {
                foreach (ObjectDirectoryInformation entry in matching_entries)
                {
                    try
                    {
                        using (NtDirectory dir = NtDirectory.Open(entry.Name, root, DirectoryAccessRights.Query))
                        {
                            AddMatches(dir, base_path + entry.Name + @"\", remaining.Skip(1), matches);
                        }
                    }
                    catch (NtException)
                    {
                    }
                }
            }
        }
        private bool disposedValue = false; // To detect redundant calls

        private void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (_directory != null)
                {
                    _directory.Close();
                    _directory = null;
                }
                disposedValue = true;
            }
        }