示例#1
0
        public static string GetDisplayName(DirectoryInfoEx dx)
        {
            IntPtr pidl;
            uint   pchEaten = 0;
            var    sfgao    = new ShellAPI.SFGAO();

            DirectoryInfoEx.DesktopDirectory.ShellFolder.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, dx.FullName, ref pchEaten, out pidl, ref sfgao);

            var ptrStr = Marshal.AllocCoTaskMem(ShellAPI.MAX_PATH * 2 + 4);

            Marshal.WriteInt32(ptrStr, 0, 0);
            var buf = new StringBuilder(ShellAPI.MAX_PATH);

            try
            {
                DirectoryInfoEx.DesktopDirectory.ShellFolder.GetDisplayNameOf(pidl, ShellAPI.SHGNO.NORMAL, ptrStr);
                ShellAPI.StrRetToBuf(ptrStr, pidl, buf, ShellAPI.MAX_PATH);
            }
            finally
            {
                if (ptrStr != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(ptrStr);
                }
                ptrStr = IntPtr.Zero;
            }

            return(buf.ToString());
        }
示例#2
0
        private static FileAttributes loadAttributes(IShellFolder2 iShellFolder, PIDL pidlFull, PIDL pidlRel)
        {
            FileAttributes retVal = new FileAttributes();


            //ShellAPI.SFGAO attribute = shGetFileAttribute(pidlFull, ShellAPI.SFGAO.READONLY |
            //    ShellAPI.SFGAO.FOLDER | ShellAPI.SFGAO.FILESYSTEM | ShellAPI.SFGAO.STREAM | ShellAPI.SFGAO.FILESYSANCESTOR |
            //    ShellAPI.SFGAO.HIDDEN);
            ShellAPI.SFGAO attribute = ShellAPI.SFGAO.READONLY | ShellAPI.SFGAO.FOLDER | ShellAPI.SFGAO.FILESYSTEM | ShellAPI.SFGAO.STREAM | ShellAPI.SFGAO.FILESYSANCESTOR;
            iShellFolder.GetAttributesOf(1, new IntPtr[] { pidlRel.Ptr }, ref attribute);

            if (!IOTools.IsZip(attribute) && (attribute & ShellAPI.SFGAO.FOLDER) != 0)
            {
                retVal |= FileAttributes.Directory;
            }
            if ((attribute & ShellAPI.SFGAO.HIDDEN) != 0)
            {
                retVal |= FileAttributes.Hidden;
            }
            if ((attribute & ShellAPI.SFGAO.READONLY) != 0)
            {
                retVal |= FileAttributes.ReadOnly;
            }

            return(retVal);
        }
示例#3
0
        /// <summary>
        /// Get the PIDLs
        /// </summary>
        /// <param name="arrayOfFileInfo">Array of FileInfo</param>
        /// <returns>Array of PIDLs</returns>
        protected IntPtr[] GetPIDL(FileInfo[] arrayOfFileInfo)
        {
            if (null == arrayOfFileInfo || 0 == arrayOfFileInfo.Length)
            {
                return(null);
            }

            IShellFolder oParentFolder = GetParentFolder(arrayOfFileInfo[0].DirectoryName);

            if (null == oParentFolder)
            {
                return(null);
            }

            var arrPIDL = new IntPtr[arrayOfFileInfo.Length];
            int n       = 0;

            foreach (FileInfo fi in arrayOfFileInfo)
            {
                // Get the file relative to folder
                uint           pchEaten      = 0;
                ShellAPI.SFGAO pdwAttributes = 0;
                IntPtr         pPIDL;
                int            nResult = oParentFolder.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, fi.Name, ref pchEaten, out pPIDL, ref pdwAttributes);
                if (S_OK != nResult)
                {
                    FreePIDL(arrPIDL);
                    return(null);
                }
                arrPIDL[n] = pPIDL;
                n++;
            }

            return(arrPIDL);
        }
示例#4
0
        protected override void refresh(IShellFolder2 parentShellFolder, PIDL relPIDL, PIDL fullPIDL, RefreshModeEnum mode)
        {
            base.refresh(parentShellFolder, relPIDL, fullPIDL, mode);

            if ((mode & RefreshModeEnum.FullProps) != 0 &&
                parentShellFolder != null && relPIDL != null && fullPIDL != null)
            {
                if (!FullName.StartsWith("::") && File.Exists(FullName))
                {
                    try
                    {
                        FileInfo fi = new FileInfo(FullName);
                        IsReadOnly     = fi.IsReadOnly;
                        Attributes     = fi.Attributes;
                        Length         = fi.Length;
                        LastAccessTime = fi.LastAccessTime;
                        LastWriteTime  = fi.LastWriteTime;
                        CreationTime   = fi.CreationTime;
                    }
                    catch { }
                }
                else //0.18: Uses File to return FileInfo by default
                {
                    ShellAPI.SFGAO attribute = shGetFileAttribute(fullPIDL, ShellAPI.SFGAO.READONLY);
                    IsReadOnly = (attribute & ShellAPI.SFGAO.READONLY) != 0;

                    Length = 0;
                }
            }
        }
示例#5
0
        protected override void refresh(IShellFolder2 parentShellFolder, PIDL relPIDL, PIDL fullPIDL)
        {
            base.refresh(parentShellFolder, relPIDL, fullPIDL);

            if (parentShellFolder != null && relPIDL != null && fullPIDL != null)
            {
                ShellAPI.SFGAO attribute = shGetFileAttribute(fullPIDL, ShellAPI.SFGAO.BROWSABLE |
                                                              ShellAPI.SFGAO.FILESYSTEM | ShellAPI.SFGAO.HASSUBFOLDER);
                IsBrowsable  = (attribute & ShellAPI.SFGAO.BROWSABLE) != 0 || (attribute & ShellAPI.SFGAO.CONTENTSMASK) != 0;
                IsFileSystem = (attribute & ShellAPI.SFGAO.FILESYSTEM) != 0;
                HasSubFolder = (attribute & ShellAPI.SFGAO.HASSUBFOLDER) != 0;

                if (!FullName.StartsWith("::") && Directory.Exists(FullName))
                {
                    try
                    {
                        DirectoryInfo di = new DirectoryInfo(FullName);
                        Attributes     = di.Attributes;
                        LastAccessTime = di.LastAccessTime;
                        LastWriteTime  = di.LastWriteTime;
                        CreationTime   = di.CreationTime;
                    }
                    catch { }
                }

                initDirectoryType();
            }
        }
示例#6
0
        private void InitVars()
        {
            IntPtr tempPidl;

            ShellAPI.SHFILEINFO info;

            //My Computer
            info     = new ShellAPI.SHFILEINFO();
            tempPidl = IntPtr.Zero;
            ShellAPI.SHGetSpecialFolderLocation(IntPtr.Zero, ShellAPI.CSIDL.DRIVES, out tempPidl);

            ShellAPI.SHGetFileInfo(tempPidl, 0, ref info, ShellAPI.cbFileInfo,
                                   ShellAPI.SHGFI.PIDL | ShellAPI.SHGFI.DISPLAYNAME | ShellAPI.SHGFI.TYPENAME);

            sysfolderName = info.szTypeName;
            mycompName    = info.szDisplayName;
            Marshal.FreeCoTaskMem(tempPidl);
            //

            //Dekstop
            tempPidl = IntPtr.Zero;
            ShellAPI.SHGetSpecialFolderLocation(IntPtr.Zero, ShellAPI.CSIDL.DESKTOP, out tempPidl);
            IntPtr desktopFolderPtr;

            ShellAPI.SHGetDesktopFolder(out desktopFolderPtr);
            desktopItem = new ShellItem(this, tempPidl, desktopFolderPtr);
            //

            //My Documents
            uint pchEaten = 0;

            ShellAPI.SFGAO pdwAttributes = 0;
            desktopItem.ShellFolder.ParseDisplayName(
                IntPtr.Zero,
                IntPtr.Zero,
                "::{450d8fba-ad25-11d0-98a8-0800361b1103}",
                ref pchEaten,
                out tempPidl,
                ref pdwAttributes);

            info = new ShellAPI.SHFILEINFO();
            ShellAPI.SHGetFileInfo(tempPidl, 0, ref info, ShellAPI.cbFileInfo,
                                   ShellAPI.SHGFI.PIDL | ShellAPI.SHGFI.DISPLAYNAME);

            mydocsName = info.szDisplayName;
            Marshal.FreeCoTaskMem(tempPidl);

            StringBuilder path = new StringBuilder(ShellAPI.MAX_PATH);

            ShellAPI.SHGetFolderPath(
                IntPtr.Zero, ShellAPI.CSIDL.PERSONAL,
                IntPtr.Zero, ShellAPI.SHGFP.TYPE_CURRENT, path);
            mydocsPath = path.ToString();
            //
        }
示例#7
0
        /// <summary>
        /// Convert a Parsable path to PIDL
        /// </summary>
        private static PIDL PathtoPIDL(string path)
        {
            IntPtr pidlPtr;
            uint   pchEaten = 0;

            ShellAPI.SFGAO pdwAttributes = 0;
            using (ShellFolder2 _desktopShellFolder = getDesktopShellFolder())
                _desktopShellFolder.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, path, ref pchEaten, out pidlPtr, ref pdwAttributes);
            PIDL pidl = new PIDL(pidlPtr, false);

            return(pidl);
        }
示例#8
0
        protected static ShellAPI.SFGAO shGetFileAttribute(PIDL pidl, ShellAPI.SFGAO lookup)
        {
            ShellAPI.SHFILEINFO shfi = new ShellAPI.SHFILEINFO();
            shfi.dwAttributes = ShellAPI.SFGAO.READONLY | ShellAPI.SFGAO.HIDDEN | ShellAPI.SFGAO.BROWSABLE |
                                ShellAPI.SFGAO.FILESYSTEM | ShellAPI.SFGAO.HASSUBFOLDER;
            ShellAPI.SHGFI dwFlag = ShellAPI.SHGFI.PIDL | ShellAPI.SHGFI.ATTRIBUTES | ShellAPI.SHGFI.ATTR_SPECIFIED |
                                    ShellAPI.SHGFI.USEFILEATTRIBUTES;
            ShellAPI.FILE_ATTRIBUTE dwAttr = 0;
            int    cbFileInfo = Marshal.SizeOf(shfi.GetType());
            IntPtr retPtr     = ShellAPI.SHGetFileInfo(pidl.Ptr, dwAttr, ref shfi, cbFileInfo, dwFlag);

            if (retPtr.ToInt32() != ShellAPI.S_OK && retPtr.ToInt32() != 1)
            {
                Marshal.ThrowExceptionForHR(retPtr.ToInt32());
            }
            return(shfi.dwAttributes);
        }
示例#9
0
        /// <summary>
        /// Gets the parent folder
        /// </summary>
        /// <param name="folderName">Folder path</param>
        /// <returns>IShellFolder for the folder (relative from the desktop)</returns>
        private IShellFolder GetParentFolder(string folderName)
        {
            if (null == _oParentFolder)
            {
                IShellFolder oDesktopFolder = GetDesktopFolder();
                if (null == oDesktopFolder)
                {
                    return(null);
                }

                // Get the PIDL for the folder file is in
                IntPtr         pPIDL;
                uint           pchEaten      = 0;
                ShellAPI.SFGAO pdwAttributes = 0;
                int            nResult       = oDesktopFolder.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, folderName, ref pchEaten, out pPIDL, ref pdwAttributes);
                if (S_OK != nResult)
                {
                    return(null);
                }

                IntPtr pStrRet = Marshal.AllocCoTaskMem(MAX_PATH * 2 + 4);
                Marshal.WriteInt32(pStrRet, 0, 0);
                _oDesktopFolder.GetDisplayNameOf(pPIDL, SHGNO.FORPARSING, pStrRet);
                var strFolder = new StringBuilder(MAX_PATH);
                StrRetToBuf(pStrRet, pPIDL, strFolder, MAX_PATH);
                Marshal.FreeCoTaskMem(pStrRet);
                _strParentFolder = strFolder.ToString();

                // Get the IShellFolder for folder
                IntPtr pUnknownParentFolder;
                nResult = oDesktopFolder.BindToObject(pPIDL, IntPtr.Zero, ref IID_IShellFolder, out pUnknownParentFolder);
                // Free the PIDL first
                Marshal.FreeCoTaskMem(pPIDL);
                if (S_OK != nResult)
                {
                    return(null);
                }
                _oParentFolder = (IShellFolder)Marshal.GetTypedObjectForIUnknown(pUnknownParentFolder, typeof(IShellFolder));
            }

            return(_oParentFolder);
        }
示例#10
0
        internal static PIDL PathToPIDL(string path)
        {
            path = Helper.RemoveSlash(path);
            IntPtr pidlPtr;
            uint   pchEaten = 0;

            ShellAPI.SFGAO pdwAttributes = 0;

            using (ShellFolder2 _desktopShellFolder = getDesktopShellFolder())
            {
                int hr = _desktopShellFolder.ParseDisplayName(
                    IntPtr.Zero, IntPtr.Zero, path, ref pchEaten, out pidlPtr, ref pdwAttributes);

                if (pidlPtr == IntPtr.Zero || hr != ShellAPI.S_OK)
                { /*Marshal.ThrowExceptionForHR(hr);*/
                    return(null);
                }
                //Commented because this is part of init and it's too time consuming.
            }
            return(new PIDL(pidlPtr, false));
        }
示例#11
0
 /// <summary>
 /// Sets the attributes for a file ShellItem
 /// </summary>
 private void SetFileAttributes()
 {
     // file attributes to retrieve with GetAttributesOf
     ShellAPI.SFGAO attr = ShellAPI.SFGAO.LINK |
                           ShellAPI.SFGAO.SHARE |
                           ShellAPI.SFGAO.FILESYSTEM |
                           ShellAPI.SFGAO.HIDDEN |
                           ShellAPI.SFGAO.CANRENAME |
                           ShellAPI.SFGAO.STREAM;
     parent.folder.GetAttributesOf(1,
                                   new IntPtr[] { relPidl.Ptr },
                                   ref attr);
     isFolder     = false;
     isLink       = (attr & ShellAPI.SFGAO.LINK) != 0;
     isShared     = (attr & ShellAPI.SFGAO.SHARE) != 0;
     isFileSystem = (attr & ShellAPI.SFGAO.FILESYSTEM) != 0;
     isHidden     = (attr & ShellAPI.SFGAO.HIDDEN) != 0;
     hasSubFolder = false;
     isExplorable = false;
     canRename    = (attr & ShellAPI.SFGAO.CANRENAME) != 0;
     canRead      = (attr & ShellAPI.SFGAO.STREAM) != 0;
     isDisk       = false;
 }
        public static string GetDisplayName(DirectoryInfoEx dx)
        {
            IntPtr pidl;
            uint pchEaten = 0;
            var sfgao = new ShellAPI.SFGAO();
            DirectoryInfoEx.DesktopDirectory.ShellFolder.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, dx.FullName, ref pchEaten, out pidl, ref sfgao);

            var ptrStr = Marshal.AllocCoTaskMem(ShellAPI.MAX_PATH * 2 + 4);
            Marshal.WriteInt32(ptrStr, 0, 0);
            var buf = new StringBuilder(ShellAPI.MAX_PATH);
            try
            {
                DirectoryInfoEx.DesktopDirectory.ShellFolder.GetDisplayNameOf(pidl, ShellAPI.SHGNO.NORMAL, ptrStr);
                ShellAPI.StrRetToBuf(ptrStr, pidl, buf, ShellAPI.MAX_PATH);
            }
            finally
            {
                if (ptrStr != IntPtr.Zero)
                    Marshal.FreeCoTaskMem(ptrStr);
                ptrStr = IntPtr.Zero;
            }

            return buf.ToString();
        }
示例#13
0
 /// <summary>
 /// Sets the attributes of a folder ShellItem.
 /// </summary>
 private void SetFolderAttributes()
 {
     // folder attributes to retrieve with GetAttributesOf
     ShellAPI.SFGAO attr = ShellAPI.SFGAO.SHARE |
                           ShellAPI.SFGAO.FILESYSTEM |
                           ShellAPI.SFGAO.HIDDEN |
                           ShellAPI.SFGAO.HASSUBFOLDER |
                           ShellAPI.SFGAO.BROWSABLE |
                           ShellAPI.SFGAO.CANRENAME |
                           ShellAPI.SFGAO.STORAGE;
     parent.folder.GetAttributesOf(1,
                                   new IntPtr[] { relPidl.Ptr },
                                   ref attr);
     isFolder     = true;
     isLink       = false;
     isShared     = (attr & ShellAPI.SFGAO.SHARE) != 0;
     isFileSystem = (attr & ShellAPI.SFGAO.FILESYSTEM) != 0;
     isHidden     = (attr & ShellAPI.SFGAO.HIDDEN) != 0;
     hasSubFolder = (attr & ShellAPI.SFGAO.HASSUBFOLDER) != 0;
     isExplorable = (attr & ShellAPI.SFGAO.BROWSABLE) != 0;
     canRename    = (attr & ShellAPI.SFGAO.CANRENAME) != 0;
     canRead      = (attr & ShellAPI.SFGAO.STORAGE) != 0;
     isDisk       = (path.Length == 4) && (path.EndsWith(":\\"));
 }
示例#14
0
 public int GetAttributesOf(uint cidl, IntPtr[] apidl, ref ShellAPI.SFGAO rgfInOut)
 {
     checkDisposed();
     return(_iShellFolder2.GetAttributesOf(cidl, apidl, ref rgfInOut));
 }
示例#15
0
 public int ParseDisplayName(IntPtr hwnd, IntPtr pbc, string pszDisplayName, ref uint pchEaten, out IntPtr ppidl, ref ShellAPI.SFGAO pdwAttributes)
 {
     checkDisposed();
     return(_iShellFolder2.ParseDisplayName(hwnd, pbc, pszDisplayName, ref pchEaten, out ppidl, ref pdwAttributes));
 }
示例#16
0
        /// <summary>
        /// Selects a path from a value from the SpecialFolders enumeration.
        /// </summary>
        /// <param name="specialFolder">The SpecialFolder to select</param>
        /// <returns>The TreeNode of the directory which was selected, this will be null if the directory
        /// doesn't exist</returns>
        public TreeNode SelectPath(SpecialFolders specialFolder, bool expandNode)
        {
            StringBuilder path = new StringBuilder(256);
            IntPtr        pidl = IntPtr.Zero;

            if (specialFolder == SpecialFolders.Desktop)
            {
                return(SelectPath("Desktop", expandNode));
            }
            else if (ShellAPI.SHGetFolderPath(
                         IntPtr.Zero, (ShellAPI.CSIDL)specialFolder,
                         IntPtr.Zero, ShellAPI.SHGFP.TYPE_CURRENT, path) == ShellAPI.S_OK)
            {
                path.Replace(ShellBrowser.MyDocumentsPath, ShellBrowser.MyDocumentsName);
                return(SelectPath(path.ToString(), expandNode));
            }
            else
            {
                #region Get Pidl

                if (specialFolder == SpecialFolders.MyDocuments)
                {
                    uint           pchEaten      = 0;
                    ShellAPI.SFGAO pdwAttributes = 0;
                    ShellBrowser.DesktopItem.ShellFolder.ParseDisplayName(
                        IntPtr.Zero,
                        IntPtr.Zero,
                        "::{450d8fba-ad25-11d0-98a8-0800361b1103}",
                        ref pchEaten,
                        out pidl,
                        ref pdwAttributes);
                }
                else
                {
                    ShellAPI.SHGetSpecialFolderLocation(
                        IntPtr.Zero,
                        (ShellAPI.CSIDL)specialFolder,
                        out pidl);
                }

                #endregion

                #region Make Path

                if (pidl != IntPtr.Zero)
                {
                    IntPtr strr = Marshal.AllocCoTaskMem(ShellAPI.MAX_PATH * 2 + 4);
                    Marshal.WriteInt32(strr, 0, 0);
                    StringBuilder buf = new StringBuilder(ShellAPI.MAX_PATH);

                    if (ShellBrowser.DesktopItem.ShellFolder.GetDisplayNameOf(
                            pidl,
                            ShellAPI.SHGNO.FORADDRESSBAR | ShellAPI.SHGNO.FORPARSING,
                            strr) == ShellAPI.S_OK)
                    {
                        ShellAPI.StrRetToBuf(strr, pidl, buf, ShellAPI.MAX_PATH);
                    }

                    Marshal.FreeCoTaskMem(pidl);
                    Marshal.FreeCoTaskMem(strr);

                    if (!string.IsNullOrEmpty(buf.ToString()))
                    {
                        return(SelectPath(buf.ToString(), expandNode));
                    }
                    else
                    {
                        return(null);
                    }
                }
                else
                {
                    return(null);
                }

                #endregion
            }
        }
示例#17
0
        //0.17: Added DirectoryInfoEx.EnumerateFiles/EnumerateDirectories/EnumerateFileSystemInfos() methods which work similar as the one in .Net4
        public IEnumerable <FileInfoEx> EnumerateFiles(String searchPattern, SearchOption searchOption, CancelDelegate cancel)
        {
            IntPtr      ptrEnum    = IntPtr.Zero;
            IEnumIDList IEnum      = null;
            PIDL        parentPIDL = this.PIDL;

            using (ShellFolder2 sf = this.ShellFolder)
                try
                {
                    if (sf.EnumObjects(IntPtr.Zero, flag, out ptrEnum) == ShellAPI.S_OK)
                    {
                        IEnum = (IEnumIDList)Marshal.GetTypedObjectForIUnknown(ptrEnum, typeof(IEnumIDList));
                        IntPtr pidlSubItem;
                        int    celtFetched;

                        while (!IOTools.IsCancelTriggered(cancel) && IEnum.Next(1, out pidlSubItem, out celtFetched) == ShellAPI.S_OK && celtFetched == 1)
                        {
                            ShellAPI.SFGAO attribs = ShellAPI.SFGAO.FOLDER | ShellAPI.SFGAO.FILESYSTEM | ShellAPI.SFGAO.STREAM;
                            sf.GetAttributesOf(1, new IntPtr[] { pidlSubItem }, ref attribs);
                            //http://www.eggheadcafe.com/aspnet_answers/platformsdkshell/Mar2006/post26165601.asp
                            bool isZip = ((attribs & ShellAPI.SFGAO.FOLDER) != 0 && (attribs & ShellAPI.SFGAO.STREAM) != 0);
                            bool isDir = ((attribs & ShellAPI.SFGAO.FOLDER) != 0);
                            if (isZip || !isDir)
                            {
                                PIDL subRelPidl = new PIDL(pidlSubItem, false);
                                //FileInfoEx fi = new FileInfoEx(sf, this, subRelPidl);
                                FileInfoEx fi = new FileInfoEx(sf, parentPIDL, subRelPidl);
                                if (IOTools.MatchFileMask(fi.Name, searchPattern))
                                {
                                    yield return(fi);
                                }
                                //0.18: Fixed DirectoryInfoEx.EnumerateFiles, SearchPattern is ignored.
                            }
                        }

                        if (searchOption == SearchOption.AllDirectories)
                        {
                            IEnumerator <DirectoryInfoEx> dirEnumerator = EnumerateDirectories("*", SearchOption.TopDirectoryOnly, cancel).GetEnumerator();

                            while (!IOTools.IsCancelTriggered(cancel) && dirEnumerator.MoveNext())
                            {
                                IEnumerator <FileInfoEx> fileEnumerator = dirEnumerator.Current.EnumerateFiles(searchPattern, searchOption, cancel).GetEnumerator();

                                while (fileEnumerator.MoveNext())
                                {
                                    //Debug.Assert(!fileEnumerator.Current.IsFolder);
                                    yield return(fileEnumerator.Current);
                                }
                            }
                        }
                    }
                }
                finally
                {
                    if (parentPIDL != null)
                    {
                        parentPIDL.Free();
                        parentPIDL = null;
                    }

                    if (IEnum != null)
                    {
                        Marshal.ReleaseComObject(IEnum);
                        Marshal.Release(ptrEnum);
                    }
                }
        }
示例#18
0
 public static bool IsZip(ShellAPI.SFGAO attribs)
 {
     return((attribs & ShellAPI.SFGAO.FOLDER) != 0 && (attribs & ShellAPI.SFGAO.STREAM) != 0);
 }
示例#19
0
        public IEnumerable <DirectoryInfoEx> EnumerateDirectories(String searchPattern, SearchOption searchOption, CancelDelegate cancel)
        {
            IntPtr      ptrEnum    = IntPtr.Zero;
            IEnumIDList IEnum      = null;
            PIDL        parentPIDL = this.PIDL;

            using (ShellFolder2 sf = this.ShellFolder)
                try
                {
                    if (sf.EnumObjects(IntPtr.Zero, flag, out ptrEnum) == ShellAPI.S_OK)
                    {
                        IEnum = (IEnumIDList)Marshal.GetTypedObjectForIUnknown(ptrEnum, typeof(IEnumIDList));
                        IntPtr pidlSubItem;
                        int    celtFetched;

                        while (!IOTools.IsCancelTriggered(cancel) && IEnum.Next(1, out pidlSubItem, out celtFetched) == ShellAPI.S_OK && celtFetched == 1)
                        {
                            ShellAPI.SFGAO attribs = ShellAPI.SFGAO.FOLDER | ShellAPI.SFGAO.FILESYSTEM | ShellAPI.SFGAO.STREAM |
                                                     ShellAPI.SFGAO.FILESYSANCESTOR | ShellAPI.SFGAO.NONENUMERATED;
                            sf.GetAttributesOf(1, new IntPtr[] { pidlSubItem }, ref attribs);
                            bool isZip = ((attribs & ShellAPI.SFGAO.FOLDER) != 0 && (attribs & ShellAPI.SFGAO.STREAM) != 0);
                            bool isDir = ((attribs & ShellAPI.SFGAO.FOLDER) != 0);
                            //0.18 Added a check for NonEnumerated items so DirectoryInfoEx.EnumerateDirectories wont return some system directories (e.g. C:\MSOCache)
                            //bool isNonEnumerated = ((attribs & ShellAPI.SFGAO.NONENUMERATED) != 0);
                            bool isFileAncestor = ((attribs & ShellAPI.SFGAO.FILESYSANCESTOR) != 0);
                            bool includedFolder = false;

                            if (!isZip && !isFileAncestor) //0.14 : Added allowed folder list so Non-FileAncestor directory (e.g. recycle-bin) is listed.
                            {
                                string[] allowedPaths = new string[]
                                {
                                    "::{645FF040-5081-101B-9F08-00AA002F954E}"
                                };
                                string path = PIDLToPath(new PIDL(pidlSubItem, false));
                                foreach (string allowedPath in allowedPaths)
                                {
                                    if (allowedPath == path)
                                    {
                                        includedFolder = true;
                                    }
                                }
                                if (!includedFolder)
                                {
                                    if (IOTools.HasParent(this, NetworkDirectory))
                                    {
                                        includedFolder = true;
                                    }
                                }
                            }
                            if (isDir && !isZip /*&& !isNonEnumerated*/ && (isFileAncestor || includedFolder))
                            {
                                PIDL subPidl = new PIDL(pidlSubItem, false);
                                //DirectoryInfoEx di = new DirectoryInfoEx(this, subPidl);

                                //0.22: Fix illegal PIDL for Directory under Library.ms directory
                                bool            isLibraryItem = IOTools.IsLibraryItem(FullName);
                                DirectoryInfoEx di            = new DirectoryInfoEx(sf, parentPIDL, subPidl, isLibraryItem);

                                if (IOTools.MatchFileMask(di.Name, searchPattern))
                                {
                                    yield return(di);
                                }
                                if (searchOption == SearchOption.AllDirectories)
                                {
                                    IEnumerator <DirectoryInfoEx> dirEnumerator = di.EnumerateDirectories(searchPattern, searchOption, cancel).GetEnumerator();

                                    while (dirEnumerator.MoveNext())
                                    {
                                        //Debug.Assert(dirEnumerator.Current.IsFolder);
                                        yield return(dirEnumerator.Current);
                                    }
                                }
                            }
                        }
                    }
                }
                finally
                {
                    if (parentPIDL != null)
                    {
                        parentPIDL.Free();
                        parentPIDL = null;
                    }

                    if (IEnum != null)
                    {
                        Marshal.ReleaseComObject(IEnum);
                        Marshal.Release(ptrEnum);
                    }
                }
        }