Exemple #1
0
        public static async Task Download(DateTime dateTime)
        {
            var directoryPath = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "NYTimesPdfs");

            Directory.CreateDirectory(directoryPath);
            var path = Path.Join(directoryPath, SubPath(dateTime));

            if (File.Exists(path))
            {
                return;
            }
            var url      = $"http://www.hawes.com/{dateTime.Year}/{SubPath(dateTime)}";
            var response = await Client.GetAsync(url);

            var j = 1;

            while (!response.IsSuccessStatusCode)
            {
                Thread.Sleep(j * 1000);
                response = await Client.GetAsync(url);

                j *= 2;
            }
            Console.WriteLine(dateTime);

            var responseBody = await response.Content.ReadAsByteArrayAsync();

            await File.WriteAllBytesAsync(path, responseBody);
        }
Exemple #2
0
        private static void WriteDummyFile(string prefix, string dirName, string subdirName, string name)
        {
            var parent = Path.Join(prefix, dirName, subdirName);

            System.IO.Directory.CreateDirectory(parent);

            var path = Path.Join(parent, name);

            System.IO.File.WriteAllText(path, "some content");
        }
Exemple #3
0
        public void TestThatFilesAreMatchedAsRootedPaths()
        {
            using var tmpdir = new TemporaryDirectory();

            WriteDummyFile(tmpdir.Path, "a", "b", "Program.cs");

            List <string> matchedFiles = Input.MatchFiles(
                tmpdir.Path,
                new List <string> {
                Path.Join(tmpdir.Path, "**", "*.cs")
            },
                new List <string>())
                                         .ToList();

            var expectedFiles = new List <string>()
            {
                Path.Join(tmpdir.Path, "a", "b", "Program.cs")
            };

            Assert.That(matchedFiles, Is.EquivalentTo(expectedFiles));
        }
Exemple #4
0
        public void TestExclude(bool patternIsRooted, bool excludeIsRooted)
        {
            using var tmpdir = new TemporaryDirectory();

            WriteDummyFile(tmpdir.Path, "a", "b", "Program.cs");
            WriteDummyFile(tmpdir.Path, "a", "obj", "AnotherProgram.cs");

            string pattern = (patternIsRooted)
                ? Path.Join(tmpdir.Path, "**", "*.cs")
                : Path.Join("**", "*.cs");

            string exclude = (excludeIsRooted)
                ? Path.Join(tmpdir.Path, "**", "obj", "**", "*.cs")
                : Path.Join("**", "obj", "**", "*.cs");

            List <string> matchedFiles = Input.MatchFiles(
                tmpdir.Path,
                new List <string>()
            {
                pattern
            },
                new List <string>()
            {
                exclude
            })
                                         .ToList();

            var expectedFiles = (patternIsRooted)
                ? new List <string>()
            {
                Path.Join(tmpdir.Path, "a", "b", "Program.cs")
            }
                : new List <string>()
            {
                Path.Join("a", "b", "Program.cs")
            };

            Assert.That(matchedFiles, Is.EquivalentTo(expectedFiles));
        }
 public static string Join(string path1, string path2, string path3, string path4)
 {
     return(Path.Join(path1.AsSpan(), path2.AsSpan(), path3.AsSpan(), path4.AsSpan()));
 }
        /// <summary>
        /// Gets reparse point information associated to <paramref name="linkPath"/>.
        /// </summary>
        /// <returns>The immediate link target, absolute or relative or null if the file is not a supported link.</returns>
        internal static unsafe string?GetImmediateLinkTarget(string linkPath, bool isDirectory, bool throwOnError, bool returnFullPath)
        {
            using SafeFileHandle handle = OpenSafeFileHandle(linkPath,
                                                             Interop.Kernel32.FileOperations.FILE_FLAG_BACKUP_SEMANTICS |
                                                             Interop.Kernel32.FileOperations.FILE_FLAG_OPEN_REPARSE_POINT);

            if (handle.IsInvalid)
            {
                if (!throwOnError)
                {
                    return(null);
                }

                int error = Marshal.GetLastWin32Error();
                // File not found doesn't make much sense coming from a directory.
                if (isDirectory && error == Interop.Errors.ERROR_FILE_NOT_FOUND)
                {
                    error = Interop.Errors.ERROR_PATH_NOT_FOUND;
                }

                throw Win32Marshal.GetExceptionForWin32Error(error, linkPath);
            }

            byte[] buffer = ArrayPool <byte> .Shared.Rent(Interop.Kernel32.MAXIMUM_REPARSE_DATA_BUFFER_SIZE);

            try
            {
                bool success = Interop.Kernel32.DeviceIoControl(
                    handle,
                    dwIoControlCode: Interop.Kernel32.FSCTL_GET_REPARSE_POINT,
                    lpInBuffer: IntPtr.Zero,
                    nInBufferSize: 0,
                    lpOutBuffer: buffer,
                    nOutBufferSize: Interop.Kernel32.MAXIMUM_REPARSE_DATA_BUFFER_SIZE,
                    out _,
                    IntPtr.Zero);

                if (!success)
                {
                    if (!throwOnError)
                    {
                        return(null);
                    }

                    int error = Marshal.GetLastWin32Error();
                    // The file or directory is not a reparse point.
                    if (error == Interop.Errors.ERROR_NOT_A_REPARSE_POINT)
                    {
                        return(null);
                    }

                    throw Win32Marshal.GetExceptionForWin32Error(error, linkPath);
                }

                Span <byte> bufferSpan = new(buffer);
                success = MemoryMarshal.TryRead(bufferSpan, out Interop.Kernel32.SymbolicLinkReparseBuffer rbSymlink);
                Debug.Assert(success);

                // We always use SubstituteName(Offset|Length) instead of PrintName(Offset|Length),
                // the latter is just the display name of the reparse point and it can show something completely unrelated to the target.

                if (rbSymlink.ReparseTag == Interop.Kernel32.IOReparseOptions.IO_REPARSE_TAG_SYMLINK)
                {
                    int offset = sizeof(Interop.Kernel32.SymbolicLinkReparseBuffer) + rbSymlink.SubstituteNameOffset;
                    int length = rbSymlink.SubstituteNameLength;

                    Span <char> targetPath = MemoryMarshal.Cast <byte, char>(bufferSpan.Slice(offset, length));

                    bool isRelative = (rbSymlink.Flags & Interop.Kernel32.SYMLINK_FLAG_RELATIVE) != 0;
                    if (!isRelative)
                    {
                        // Absolute target is in NT format and we need to clean it up before return it to the user.
                        if (targetPath.StartsWith(PathInternal.UncNTPathPrefix.AsSpan()))
                        {
                            // We need to prepend the Win32 equivalent of UNC NT prefix.
                            return(Path.Join(PathInternal.UncPathPrefix.AsSpan(), targetPath.Slice(PathInternal.UncNTPathPrefix.Length)));
                        }

                        return(GetTargetPathWithoutNTPrefix(targetPath));
                    }
                    else if (returnFullPath)
                    {
                        return(Path.Join(Path.GetDirectoryName(linkPath.AsSpan()), targetPath));
                    }
                    else
                    {
                        return(targetPath.ToString());
                    }
                }
                else if (rbSymlink.ReparseTag == Interop.Kernel32.IOReparseOptions.IO_REPARSE_TAG_MOUNT_POINT)
                {
                    success = MemoryMarshal.TryRead(bufferSpan, out Interop.Kernel32.MountPointReparseBuffer rbMountPoint);
                    Debug.Assert(success);

                    int offset = sizeof(Interop.Kernel32.MountPointReparseBuffer) + rbMountPoint.SubstituteNameOffset;
                    int length = rbMountPoint.SubstituteNameLength;

                    Span <char> targetPath = MemoryMarshal.Cast <byte, char>(bufferSpan.Slice(offset, length));

                    // Unlike symbolic links, mount point paths cannot be relative.
                    Debug.Assert(!PathInternal.IsPartiallyQualified(targetPath));
                    // Mount points cannot point to a remote location.
                    Debug.Assert(!targetPath.StartsWith(PathInternal.UncNTPathPrefix.AsSpan()));
                    return(GetTargetPathWithoutNTPrefix(targetPath));
                }

                return(null);
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(buffer);
            }
        private static void RemoveDirectoryRecursive(string fullPath, ref Interop.Kernel32.WIN32_FIND_DATA findData, bool topLevel)
        {
            int       errorCode;
            Exception?exception = null;

            using (SafeFindHandle handle = Interop.Kernel32.FindFirstFile(Path.Join(fullPath, "*"), ref findData))
            {
                if (handle.IsInvalid)
                {
                    throw Win32Marshal.GetExceptionForLastWin32Error(fullPath);
                }

                do
                {
                    if ((findData.dwFileAttributes & Interop.Kernel32.FileAttributes.FILE_ATTRIBUTE_DIRECTORY) == 0)
                    {
                        // File
                        string fileName = findData.cFileName.GetStringFromFixedBuffer();
                        if (!Interop.Kernel32.DeleteFile(Path.Combine(fullPath, fileName)) && exception == null)
                        {
                            errorCode = Marshal.GetLastWin32Error();

                            // We don't care if something else deleted the file first
                            if (errorCode != Interop.Errors.ERROR_FILE_NOT_FOUND)
                            {
                                exception = Win32Marshal.GetExceptionForWin32Error(errorCode, fileName);
                            }
                        }
                    }
                    else
                    {
                        // Directory, skip ".", "..".
                        if (findData.cFileName.FixedBufferEqualsString(".") || findData.cFileName.FixedBufferEqualsString(".."))
                        {
                            continue;
                        }

                        string fileName = findData.cFileName.GetStringFromFixedBuffer();

                        if (!IsNameSurrogateReparsePoint(ref findData))
                        {
                            // Not a reparse point, or the reparse point isn't a name surrogate, recurse.
                            try
                            {
                                RemoveDirectoryRecursive(
                                    Path.Combine(fullPath, fileName),
                                    findData: ref findData,
                                    topLevel: false);
                            }
                            catch (Exception e)
                            {
                                if (exception == null)
                                {
                                    exception = e;
                                }
                            }
                        }
                        else
                        {
                            // Name surrogate reparse point, don't recurse, simply remove the directory.
                            // If a mount point, we have to delete the mount point first.
                            if (findData.dwReserved0 == Interop.Kernel32.IOReparseOptions.IO_REPARSE_TAG_MOUNT_POINT)
                            {
                                // Mount point. Unmount using full path plus a trailing '\'.
                                // (Note: This doesn't remove the underlying directory)
                                string mountPoint = Path.Join(fullPath, fileName, PathInternal.DirectorySeparatorCharAsString);
                                if (!Interop.Kernel32.DeleteVolumeMountPoint(mountPoint) && exception == null)
                                {
                                    errorCode = Marshal.GetLastWin32Error();
                                    if (errorCode != Interop.Errors.ERROR_SUCCESS &&
                                        errorCode != Interop.Errors.ERROR_PATH_NOT_FOUND)
                                    {
                                        exception = Win32Marshal.GetExceptionForWin32Error(errorCode, fileName);
                                    }
                                }
                            }

                            // Note that RemoveDirectory on a symbolic link will remove the link itself.
                            if (!Interop.Kernel32.RemoveDirectory(Path.Combine(fullPath, fileName)) && exception == null)
                            {
                                errorCode = Marshal.GetLastWin32Error();
                                if (errorCode != Interop.Errors.ERROR_PATH_NOT_FOUND)
                                {
                                    exception = Win32Marshal.GetExceptionForWin32Error(errorCode, fileName);
                                }
                            }
                        }
                    }
                } while (Interop.Kernel32.FindNextFile(handle, ref findData));

                if (exception != null)
                {
                    throw exception;
                }

                errorCode = Marshal.GetLastWin32Error();
                if (errorCode != Interop.Errors.ERROR_SUCCESS && errorCode != Interop.Errors.ERROR_NO_MORE_FILES)
                {
                    throw Win32Marshal.GetExceptionForWin32Error(errorCode, fullPath);
                }
            }

            // As we successfully removed all of the files we shouldn't care about the directory itself
            // not being empty. As file deletion is just a marker to remove the file when all handles
            // are closed we could still have undeleted contents.
            RemoveDirectoryInternal(fullPath, topLevel: topLevel, allowDirectoryNotEmpty: true);
        }
Exemple #8
0
 /// <summary>
 ///   Creates a temporary file with the specified extension.
 /// </summary>
 /// <param name="extension">
 ///   The extension to give the file.
 /// </param>
 public RandomFile(string extension)
 {
     extension   = Guard.NotNullOrWhiteSpace(extension, nameof(extension));
     Path        = IoPath.Join(IoPath.GetTempPath(), $"{Guid.NewGuid().ToStringWithDigitsOnly()}.{extension.ReplaceInvariant(".", "")}");
     using var _ = File.Create(Path);
 }