public static bool Exists(string path)
        {
#if DOTNET5_4
            return(Directory.Exists(path));
#else
            try
            {
                if (String.IsNullOrEmpty(path))
                {
                    return(false);
                }
                path = LongPath.ToUncPath(path);
                bool success = NativeMethods.PathFileExistsW(path);
                if (!success)
                {
                    NativeMethods.ThrowExceptionForLastWin32ErrorIfExists(new int[] { 0, NativeMethods.ERROR_DIRECTORY_NOT_FOUND, NativeMethods.ERROR_FILE_NOT_FOUND });
                }
                var fileAttributes = LongPathFile.GetAttributes(path);
                return(success && (FileAttributes.Directory == (fileAttributes & FileAttributes.Directory)));
            }
            catch (ArgumentException) { }
            catch (NotSupportedException) { }  // Security can throw this on ":"
            catch (System.Security.SecurityException) { }
            catch (IOException) { }
            catch (UnauthorizedAccessException) { }

            return(false);
#endif
        }
        public static void GetFileProperties(string path, out DateTimeOffset?creationTime, out DateTimeOffset?lastWriteTime, out FileAttributes?fileAttributes
#if DOTNET5_4
                                             , bool isDirectory = false
#endif
                                             )
        {
#if !DOTNET5_4
            path = LongPath.ToUncPath(path);

            if (path.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
            {
                path = path.Substring(0, path.Length - 1);
            }

            NativeMethods.WIN32_FIND_DATA findData;
            NativeMethods.SafeFindHandle  findHandle;

            findHandle = NativeMethods.FindFirstFileW(path, out findData);

            if (findHandle.IsInvalid)
            {
                NativeMethods.ThrowExceptionForLastWin32ErrorIfExists();
            }
            else
            {
                findHandle.Dispose();
                findHandle = null;
            }

            long dt = (findData.LastWriteTime.dwLowDateTime & 0xFFFFFFFF);
            dt           |= ((long)findData.LastWriteTime.dwHighDateTime) << 32;
            lastWriteTime = DateTimeOffset.FromFileTime(dt).UtcDateTime;

            dt           = (findData.CreationTime.dwLowDateTime & 0xFFFFFFFF);
            dt          |= ((long)findData.CreationTime.dwHighDateTime) << 32;
            creationTime = DateTimeOffset.FromFileTime(dt).UtcDateTime;

            fileAttributes = (FileAttributes)findData.FileAttributes;
#else
            fileAttributes = File.GetAttributes(path);

            if (isDirectory)
            {
                creationTime  = Directory.GetCreationTimeUtc(path);
                lastWriteTime = Directory.GetLastWriteTimeUtc(path);
            }
            else
            {
                creationTime  = File.GetCreationTimeUtc(path);
                lastWriteTime = File.GetLastWriteTimeUtc(path);
            }
#endif

#if DEBUG
            if (null != TestHookCallbacks.GetFileAttributesCallback)
            {
                fileAttributes = TestHookCallbacks.GetFileAttributesCallback(path);
            }
#endif
        }
예제 #3
0
 public void SetDirectoryPath(string directoryPath)
 {
     if (directoryPath != null)
     {
         this.FilePath = LongPath.Combine(directoryPath, this.RelativePath);
     }
 }
        public static string ToUncPath(string path)
        {
            if (IsDevice(path))
            {
                return(LongPath.GetFullPath(path));
            }

            if (IsPartiallyQualified(path))
            {
                path = LongPath.GetFullPath(path);
                if (IsDevice(path))
                {
                    return(path);
                }
                else
                {
                    return(ExtendedPathPrefix + path);
                }
            }

            //// Given \\server\share in longpath becomes \\?\UNC\server\share
            if (path.StartsWith(UncPathPrefix, StringComparison.OrdinalIgnoreCase))
            {
                return(LongPath.GetFullPath(path.Insert(2, UncExtendedPrefixToInsert)));
            }
            return(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
                ? LongPath.GetFullPath(ExtendedPathPrefix + path)
                : LongPath.GetFullPath(path));
        }
예제 #5
0
        public static void CreateParentDirectoryIfNotExists(string path)
        {
            string dir = LongPath.GetDirectoryName(path);

            if (!string.IsNullOrEmpty(dir) && !LongPathDirectory.Exists(dir))
            {
                LongPathDirectory.CreateDirectory(dir);
            }
        }
예제 #6
0
        private static string GetFileSDDL(
            string filePath,
            NativeMethods.SECURITY_INFORMATION securityInfo)
        {
            filePath = LongPath.ToUncPath(filePath);

            // Note: to get the SACL, special permissions are needed. Refer https://docs.microsoft.com/en-us/windows/win32/api/aclapi/nf-aclapi-getsecurityinfo
            IntPtr pZero = IntPtr.Zero;
            IntPtr pSid  = pZero;
            IntPtr psd   = pZero;

            uint errorReturn = NativeMethods.GetNamedSecurityInfoW(
                filePath,
                NativeMethods.SE_OBJECT_TYPE.SE_FILE_OBJECT,
                securityInfo,
                out pSid, out pZero, out pZero, out pZero, out psd);

#if !DMLIB_TEST
            if (errorReturn == NativeMethods.ERROR_PRIVILEGE_NOT_HELD)
            {
                throw new TransferException(
                          string.Format(
                              CultureInfo.CurrentCulture,
                              Resources.PrivilegeRequiredException,
                              NativeMethods.SACLPrivilegeName));
            }
            else if (errorReturn != 0)
            {
                throw new Win32Exception((int)errorReturn);
            }
#else
            if (errorReturn != 0)
            {
                throw new Win32Exception((int)errorReturn);
            }
#endif

            try
            {
                IntPtr  sdString           = IntPtr.Zero;
                UIntPtr sd_string_size_ptr = new UIntPtr();
                bool    success            = NativeMethods.ConvertSecurityDescriptorToStringSecurityDescriptor(psd, NativeMethods.SDDL_REVISION_1, securityInfo, out sdString, out sd_string_size_ptr);
                try
                {
                    return(Marshal.PtrToStringAuto(sdString));
                }
                finally
                {
                    Marshal.FreeHGlobal(sdString);
                }
            }
            finally
            {
                NativeMethods.LocalFree(psd);
            }
        }
        public static FileStream Open(string filePath, FileMode mode, FileAccess access, FileShare share)
        {
#if DOTNET5_4
            return(new FileStream(filePath, mode, access, share));
#else
            filePath = LongPath.ToUncPath(filePath);
            SafeFileHandle fileHandle = GetFileHandle(filePath, mode, access, share);
            return(new FileStream(fileHandle, access));
#endif
        }
예제 #8
0
        private FileLocation(SerializationInfo info, StreamingContext context)
        {
            if (info == null)
            {
                throw new System.ArgumentNullException("info");
            }

            if (context.Context is StreamJournal &&
                "RelativePath".Equals(info.GetString(FilePathType)))
            {
                this.RelativePath = info.GetString(FilePathName);
                this.FilePath     = LongPath.Combine(((StreamJournal)context.Context).DirectoryPath, this.RelativePath);
            }
            else
            {
                this.RelativePath = null;
                this.FilePath     = info.GetString(FilePathName);
            }
        }
        public static void SetFileTime(string path, DateTimeOffset creationTimeUtc, DateTimeOffset lastWriteTimeUtc, bool isDirectory = false)
        {
#if !DOTNET5_4
            path = LongPath.ToUncPath(path);
            SafeFileHandle fileHandle = GetFileHandle(path, FileMode.Open, FileAccess.Write, FileShare.None, isDirectory);

            try
            {
                NativeMethods.FILETIME ftCreationTime   = new NativeMethods.FILETIME();
                NativeMethods.FILETIME ftLastAccessTime = new NativeMethods.FILETIME();
                NativeMethods.FILETIME ftLastWriteTime  = new NativeMethods.FILETIME();
                long dt = lastWriteTimeUtc.UtcDateTime.ToFileTimeUtc();
                ftLastWriteTime.dwLowDateTime  = (uint)dt & 0xFFFFFFFF;
                ftLastWriteTime.dwHighDateTime = (uint)(dt >> 32) & 0xFFFFFFFF;

                dt = creationTimeUtc.UtcDateTime.ToFileTimeUtc();
                ftCreationTime.dwLowDateTime  = (uint)dt & 0xFFFFFFFF;
                ftCreationTime.dwHighDateTime = (uint)(dt >> 32) & 0xFFFFFFFF;

                if (true != NativeMethods.SetFileTime(fileHandle, ref ftCreationTime, ref ftLastAccessTime, ref ftLastWriteTime))
                {
                    NativeMethods.ThrowExceptionForLastWin32ErrorIfExists();
                }
            }
            finally
            {
                fileHandle.Close();
                fileHandle = null;
            }
#else
            if (isDirectory)
            {
                Directory.SetCreationTimeUtc(path, creationTimeUtc.UtcDateTime);
                Directory.SetLastWriteTimeUtc(path, lastWriteTimeUtc.UtcDateTime);
            }
            else
            {
                File.SetCreationTimeUtc(path, creationTimeUtc.UtcDateTime);
                File.SetLastWriteTimeUtc(path, lastWriteTimeUtc.UtcDateTime);
            }
#endif
        }
        /// <summary>
        /// Creates all directories and subdirectories in the specified path unless they already exist.
        /// </summary>
        /// <param name="path">The directory to create.</param>
        public static void CreateDirectory(string path)
        {
#if DOTNET5_4
            Directory.CreateDirectory(path);
#else
            var dir = LongPath.GetDirectoryName(path);
            if (!string.IsNullOrEmpty(dir) && !LongPathDirectory.Exists(dir))
            {
                LongPathDirectory.CreateDirectory(dir);
            }

            if (!NativeMethods.CreateDirectoryW(path, IntPtr.Zero))
            {
                NativeMethods.ThrowExceptionForLastWin32ErrorIfExists(new int[] {
                    NativeMethods.ERROR_SUCCESS,
                    NativeMethods.ERROR_ALREADY_EXISTS
                });
            }
#endif
        }
        public static void SetAttributes(string path, FileAttributes fileAttributes)
        {
#if DEBUG
            if (null != TestHookCallbacks.SetFileAttributesCallback)
            {
                TestHookCallbacks.SetFileAttributesCallback(path, fileAttributes);
                return;
            }
#endif

#if DOTNET5_4
            File.SetAttributes(path, fileAttributes);
#else
            path = LongPath.ToUncPath(path);
            if (!NativeMethods.SetFileAttributesW(path, (uint)(fileAttributes)))
            {
                NativeMethods.ThrowExceptionForLastWin32ErrorIfExists();
            }
#endif
        }
 protected TransferEntry CreateDirectoryTransferEntry(string relativePath)
 {
     if (this.Source.Type == TransferLocationType.AzureFileDirectory)
     {
         return(new AzureFileDirectoryEntry(
                    relativePath,
                    (this.Source as AzureFileDirectoryLocation).FileDirectory.GetDirectoryReference(relativePath),
                    null));
     }
     else if (this.Source.Type == TransferLocationType.LocalDirectory)
     {
         return(new DirectoryEntry
                    (relativePath,
                    LongPath.Combine(this.Source.Instance as string, relativePath), null));
     }
     else
     {
         // For now, HierarchyDirectoryTransfer should only be used when source is Azure File Directory.
         throw new ArgumentException("TransferLocationType");
     }
 }
        protected TransferLocation GetDestinationSubDirTransferLocation(TransferLocation dirLocation, TransferEntry entry)
        {
            string destRelativePath = this.NameResolver.ResolveName(entry);

            switch (dirLocation.Type)
            {
            case TransferLocationType.AzureBlobDirectory:
            {
                AzureBlobDirectoryLocation blobDirLocation = dirLocation as AzureBlobDirectoryLocation;
                BlobType destBlobType = this.BlobType;

                // TODO: should handle blob type here.
                AzureBlobDirectoryLocation retLocation = new AzureBlobDirectoryLocation(blobDirLocation.BlobDirectory.GetDirectoryReference(destRelativePath));
                retLocation.BlobRequestOptions = blobDirLocation.BlobRequestOptions;
                return(retLocation);
            }

            case TransferLocationType.AzureFileDirectory:
            {
                AzureFileDirectoryLocation fileDirLocation = dirLocation as AzureFileDirectoryLocation;
                CloudFileDirectory         azureDirectory  = fileDirLocation.FileDirectory.GetDirectoryReference(destRelativePath);

                AzureFileDirectoryLocation retLocation = new AzureFileDirectoryLocation(azureDirectory);
                retLocation.FileRequestOptions = fileDirLocation.FileRequestOptions;
                return(retLocation);
            }

            case TransferLocationType.LocalDirectory:
            {
                DirectoryLocation localDirLocation = dirLocation as DirectoryLocation;
                string            path             = LongPath.Combine(localDirLocation.DirectoryPath, destRelativePath);

                return(new DirectoryLocation(path));
            }

            default:
                throw new ArgumentException("TransferLocationType");
            }
        }
        public TransferConfigurations()
        {
            // setup default values.
            this.blockSize          = Constants.DefaultTransferChunkSize;
            this.parallelOperations = Environment.ProcessorCount * 8;
            this.MemoryChunkSize    = Constants.DefaultMemoryChunkSize;

            this.UpdateMaximumCacheSize(this.blockSize);
            this.SupportUncPath = false;

            if (Interop.CrossPlatformHelpers.IsWindows)
            {
                try
                {
                    LongPath.GetFullPath("\\\\?\\F:");
                    this.SupportUncPath = true;
                }
                catch (Exception)
                {
                }
            }
        }
예제 #15
0
        private static bool IsValidWindowsFileName(string fileName)
        {
            string fileNameNoExt   = LongPath.GetFileNameWithoutExtension(fileName);
            string fileNameWithExt = LongPath.GetFileName(fileName);

            if (Array.Exists <string>(ReservedBaseFileNames, delegate(string s) { return(fileNameNoExt.Equals(s, StringComparison.OrdinalIgnoreCase)); }))
            {
                return(false);
            }

            if (Array.Exists <string>(ReservedFileNames, delegate(string s) { return(fileNameWithExt.Equals(s, StringComparison.OrdinalIgnoreCase)); }))
            {
                return(false);
            }

            if (string.IsNullOrWhiteSpace(fileNameWithExt))
            {
                return(false);
            }

            bool allDotsOrWhiteSpace = true;

            for (int i = 0; i < fileName.Length; ++i)
            {
                if (fileName[i] != '.' && !char.IsWhiteSpace(fileName[i]))
                {
                    allDotsOrWhiteSpace = false;
                    break;
                }
            }

            if (allDotsOrWhiteSpace)
            {
                return(false);
            }

            return(true);
        }
예제 #16
0
 public static string ToLongPath(this string originPath)
 {
     return(TransferManager.Configurations.SupportUncPath ? LongPath.ToUncPath(originPath) : originPath);
 }
        private void CreateDestinationDirectory(CancellationToken cancellationToken)
        {
            if (this.dest.Type == TransferLocationType.AzureBlobDirectory)
            {
                // No physical destination directory needed.
                return;
            }

            if ((this.dest.Type == TransferLocationType.AzureFileDirectory) &&
                (null == (this.dest as AzureFileDirectoryLocation).FileDirectory.Parent))
            {
                //Root Azure File directory, no need to create.
                return;
            }

            CloudFileNtfsAttributes?     fileAttributes = null;
            DateTimeOffset?              creationTime   = null;
            DateTimeOffset?              lastWriteTime  = null;
            IDictionary <string, string> metadata       = null;

            if (this.source.Type == TransferLocationType.LocalDirectory)
            {
                if (this.baseDirectoryTransfer.PreserveSMBAttributes)
                {
                    var sourceLocalDirLocation = this.source as DirectoryLocation;

                    FileAttributes?localFileAttributes = null;

                    string longDirectoryPath = sourceLocalDirLocation.DirectoryPath;

                    if (Interop.CrossPlatformHelpers.IsWindows)
                    {
                        longDirectoryPath = LongPath.ToUncPath(longDirectoryPath);
                    }

#if DOTNET5_4
                    LongPathFile.GetFileProperties(longDirectoryPath, out creationTime, out lastWriteTime, out localFileAttributes, true);
#else
                    LongPathFile.GetFileProperties(longDirectoryPath, out creationTime, out lastWriteTime, out localFileAttributes);
#endif
                    fileAttributes = Utils.LocalAttributesToAzureFileNtfsAttributes(localFileAttributes.Value);
                }
            }
            else if (this.source.Type == TransferLocationType.AzureFileDirectory)
            {
                if (this.baseDirectoryTransfer.PreserveSMBAttributes || this.dest.Type == TransferLocationType.AzureFileDirectory)
                {
                    AzureFileDirectoryLocation sourceFileDirLocation = this.source as AzureFileDirectoryLocation;

                    var sourceFileDirectory = sourceFileDirLocation.FileDirectory;
                    sourceFileDirectory.FetchAttributesAsync(
                        null,
                        Utils.GenerateFileRequestOptions(sourceFileDirLocation.FileRequestOptions),
                        Utils.GenerateOperationContext(this.baseDirectoryTransfer.Context),
                        cancellationToken).GetAwaiter().GetResult();

                    if (this.baseDirectoryTransfer.PreserveSMBAttributes)
                    {
                        fileAttributes = sourceFileDirectory.Properties.NtfsAttributes;
                        creationTime   = sourceFileDirectory.Properties.CreationTime;
                        lastWriteTime  = sourceFileDirectory.Properties.LastWriteTime;
                    }

                    metadata = sourceFileDirectory.Metadata;
                }
            }

            if (this.dest.Type == TransferLocationType.LocalDirectory)
            {
                var localFileDestLocation = this.dest as DirectoryLocation;
                if (!LongPathDirectory.Exists(localFileDestLocation.DirectoryPath))
                {
                    LongPathDirectory.CreateDirectory(localFileDestLocation.DirectoryPath);
                }

                if (fileAttributes.HasValue)
                {
                    LongPathFile.SetFileTime(localFileDestLocation.DirectoryPath, creationTime.Value, lastWriteTime.Value, true);
                    LongPathFile.SetAttributes(localFileDestLocation.DirectoryPath, Utils.AzureFileNtfsAttributesToLocalAttributes(fileAttributes.Value));
                }
            }
            else if (this.dest.Type == TransferLocationType.AzureFileDirectory)
            {
                AzureFileDirectoryLocation fileDirLocation = this.dest as AzureFileDirectoryLocation;

                var fileDirectory = fileDirLocation.FileDirectory;

                if (string.Equals(fileDirectory.SnapshotQualifiedUri.AbsolutePath, fileDirectory.Share.SnapshotQualifiedUri.AbsolutePath))
                {
                    return;
                }

                try
                {
                    CreateCloudFileDestinationDirectory(fileDirectory,
                                                        fileAttributes,
                                                        creationTime,
                                                        lastWriteTime,
                                                        metadata,
                                                        cancellationToken);
                }
                catch (StorageException storageException)
                {
                    if ((null != storageException.InnerException) &&
                        (storageException.InnerException is OperationCanceledException))
                    {
                        throw storageException.InnerException;
                    }
                    else
                    {
                        throw new TransferException(TransferErrorCode.FailToVadlidateDestination,
                                                    string.Format(CultureInfo.CurrentCulture,
                                                                  Resources.FailedToValidateDestinationException,
                                                                  storageException.ToErrorDetail()),
                                                    storageException);
                    }
                }
            }
        }
예제 #18
0
        public static void SetFileSecurity(string filePath, string portableSDDL, PreserveSMBPermissions preserveSMBPermissions)
        {
#if DEBUG
            if (null != TestHookCallbacks.SetFilePermissionsCallback)
            {
                TestHookCallbacks.SetFilePermissionsCallback(filePath, portableSDDL, preserveSMBPermissions);
                return;
            }
#endif

            filePath = LongPath.ToUncPath(filePath);

            if (PreserveSMBPermissions.None == preserveSMBPermissions)
            {
                return;
            }

            if (string.IsNullOrEmpty(portableSDDL))
            {
                return;
            }

            IntPtr  pSecurityDescriptor      = new IntPtr();
            UIntPtr securityDescriptorLength = new UIntPtr();

            if (!NativeMethods.ConvertStringSecurityDescriptorToSecurityDescriptor(portableSDDL,
                                                                                   NativeMethods.SDDL_REVISION_1,
                                                                                   out pSecurityDescriptor,
                                                                                   out securityDescriptorLength))
            {
                throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
            }

            try
            {
                NativeMethods.SetFileSecurity(filePath,
                                              (int)(ToSecurityInfo(preserveSMBPermissions)),
                                              pSecurityDescriptor);

                int errorCode = Marshal.GetLastWin32Error();
                int hresult   = Marshal.GetHRForLastWin32Error();

                if ((errorCode == NativeMethods.ERROR_PRIVILEGE_NOT_HELD) ||
                    (errorCode == NativeMethods.ERROR_ACCESS_DENIED) ||
                    (errorCode == NativeMethods.ERROR_INVALID_OWNER))
                {
#if !DMLIB_TEST
                    string privilegeName = null;

                    if ((preserveSMBPermissions & PreserveSMBPermissions.Owner) == PreserveSMBPermissions.Owner)
                    {
                        privilegeName = NativeMethods.OwnerPrivilegeName;
                    }

                    if ((preserveSMBPermissions & PreserveSMBPermissions.SACL) == PreserveSMBPermissions.SACL)
                    {
                        if (null == privilegeName)
                        {
                            privilegeName = NativeMethods.SACLPrivilegeName;
                        }
                        else
                        {
                            privilegeName += " ";
                            privilegeName += NativeMethods.SACLPrivilegeName;
                        }
                    }

                    if (null != privilegeName)
                    {
                        throw new TransferException(
                                  string.Format(
                                      CultureInfo.CurrentCulture,
                                      Resources.PrivilegeRequiredException,
                                      privilegeName));
                    }
#else
                    throw new Win32Exception(errorCode);
#endif
                }

                if (errorCode != 0)
                {
                    Marshal.ThrowExceptionForHR(hresult);
                }
            }
            finally
            {
                NativeMethods.LocalFree(pSecurityDescriptor);
            }
        }
        public static IEnumerable <string> EnumerateFileSystemEntries(string path, string searchPattern, SearchOption searchOption, FilesOrDirectory filter)
        {
#if DOTNET5_4
            return(Directory.EnumerateFileSystemEntries(path, searchPattern, searchOption));
#else
            NativeMethods.WIN32_FIND_DATA findData;
            NativeMethods.SafeFindHandle  findHandle;
            string currentPath = null;
            int    errorCode   = 0;

            Queue <string> folders    = new Queue <string>();
            String         searchPath = LongPath.Combine(path, searchPattern);
            path          = LongPath.GetDirectoryName(searchPath);
            searchPattern = LongPath.GetFileName(searchPath);
            folders.Enqueue(path);
            while (folders.Count > 0)
            {
                currentPath = folders.Dequeue();
                if (searchOption == SearchOption.AllDirectories)
                {
                    findHandle = NativeMethods.FindFirstFileW(LongPath.Combine(LongPath.ToUncPath(currentPath), "*"), out findData);
                    if (!findHandle.IsInvalid)
                    {
                        do
                        {
                            if (findData.FileName != "." &&
                                findData.FileName != "..")
                            {
                                if (findData.FileAttributes == FileAttributes.Directory)
                                {
                                    folders.Enqueue(LongPath.Combine(currentPath, findData.FileName));
                                }
                            }
                        }while (NativeMethods.FindNextFileW(findHandle, out findData));

                        // Get last Win32 error right after native calls.
                        // Dispose SafeFindHandle will call native methods, it is possible to set last Win32 error.
                        errorCode = Marshal.GetLastWin32Error();
                        if (findHandle != null &&
                            !findHandle.IsInvalid)
                        {
                            findHandle.Dispose();
                        }
                        NativeMethods.ThrowExceptionForLastWin32ErrorIfExists(errorCode,
                                                                              new int[] {
                            NativeMethods.ERROR_SUCCESS,
                            NativeMethods.ERROR_NO_MORE_FILES,
                            NativeMethods.ERROR_FILE_NOT_FOUND
                        });
                    }
                    else
                    {
                        NativeMethods.ThrowExceptionForLastWin32ErrorIfExists(new int[] {
                            NativeMethods.ERROR_SUCCESS,
                            NativeMethods.ERROR_NO_MORE_FILES,
                            NativeMethods.ERROR_FILE_NOT_FOUND
                        });
                    }
                }

                findHandle = NativeMethods.FindFirstFileW(LongPath.Combine(LongPath.ToUncPath(currentPath), searchPattern), out findData);
                if (!findHandle.IsInvalid)
                {
                    do
                    {
                        if (findData.FileName != "." &&
                            findData.FileName != "..")
                        {
                            if ((filter == FilesOrDirectory.All) ||
                                (filter == FilesOrDirectory.Directory && findData.FileAttributes == FileAttributes.Directory) ||
                                (filter == FilesOrDirectory.File && findData.FileAttributes != FileAttributes.Directory))
                            {
                                yield return(LongPath.Combine(currentPath, findData.FileName));
                            }
                        }
                    }while (NativeMethods.FindNextFileW(findHandle, out findData));

                    // Get last Win32 error right after native calls.
                    // Dispose SafeFindHandle will call native methods, it is possible to set last Win32 error.
                    errorCode = Marshal.GetLastWin32Error();
                    if (findHandle != null &&
                        !findHandle.IsInvalid)
                    {
                        findHandle.Dispose();
                    }
                    NativeMethods.ThrowExceptionForLastWin32ErrorIfExists(errorCode,
                                                                          new int[] {
                        NativeMethods.ERROR_SUCCESS,
                        NativeMethods.ERROR_NO_MORE_FILES,
                        NativeMethods.ERROR_FILE_NOT_FOUND
                    });
                }
                else
                {
                    NativeMethods.ThrowExceptionForLastWin32ErrorIfExists(new int[] {
                        NativeMethods.ERROR_SUCCESS,
                        NativeMethods.ERROR_NO_MORE_FILES,
                        NativeMethods.ERROR_FILE_NOT_FOUND
                    });
                }
            }
#endif
        }