Example #1
0
        public void ReplacementChecking()
        {
            var wnt = new WindowsNameTransform();

            try {
                wnt.Replacement = '*';
                Assert.Fail("Expected an exception");
            } catch (ArgumentException) {
            }

            try {
                wnt.Replacement = '?';
                Assert.Fail("Expected an exception");
            } catch (ArgumentException) {
            }

            try {
                wnt.Replacement = ':';
                Assert.Fail("Expected an exception");
            } catch (ArgumentException) {
            }

            try {
                wnt.Replacement = '/';
                Assert.Fail("Expected an exception");
            } catch (ArgumentException) {
            }

            try {
                wnt.Replacement = '\\';
                Assert.Fail("Expected an exception");
            } catch (ArgumentException) {
            }
        }
Example #2
0
 public override IAsyncOperation <IStorageItem> GetItemAsync(string name)
 {
     return(AsyncInfo.Run <IStorageItem>(async(cancellationToken) =>
     {
         var hFile = NativeFileOperationsHelper.OpenFileForRead(ContainerPath);
         if (hFile.IsInvalid)
         {
             return null;
         }
         using (ZipFile zipFile = new ZipFile(new FileStream(hFile, FileAccess.Read)))
         {
             zipFile.IsStreamOwner = true;
             ZipEncoding ??= DetectFileEncoding(zipFile);
             var entry = zipFile.GetEntry(name);
             if (entry != null)
             {
                 var wnt = new WindowsNameTransform(ContainerPath);
                 if (entry.IsDirectory)
                 {
                     return new ZipStorageFolder(wnt.TransformDirectory(DecodeEntryName(entry, ZipEncoding)), ContainerPath, entry)
                     {
                         ZipEncoding = ZipEncoding
                     };
                 }
                 else
                 {
                     return new ZipStorageFile(wnt.TransformFile(DecodeEntryName(entry, ZipEncoding)), ContainerPath, entry);
                 }
             }
             return null;
         }
     }));
 }
Example #3
0
 public override IAsyncOperation <IStorageItem> GetItemAsync(string name)
 {
     return(AsyncInfo.Run <IStorageItem>(async(cancellationToken) =>
     {
         using ZipFile zipFile = await OpenZipFileAsync(FileAccessMode.Read);
         if (zipFile == null)
         {
             return null;
         }
         zipFile.IsStreamOwner = true;
         ZipEncoding ??= DetectFileEncoding(zipFile);
         var entry = zipFile.GetEntry(name);
         if (entry != null)
         {
             var wnt = new WindowsNameTransform(ContainerPath);
             if (entry.IsDirectory)
             {
                 return new ZipStorageFolder(wnt.TransformDirectory(DecodeEntryName(entry, ZipEncoding)), ContainerPath, entry)
                 {
                     ZipEncoding = ZipEncoding,
                     BackingFile = BackingFile
                 };
             }
             else
             {
                 return new ZipStorageFile(wnt.TransformFile(DecodeEntryName(entry, ZipEncoding)), ContainerPath, entry)
                 {
                     BackingFile = BackingFile
                 };
             }
         }
         return null;
     }));
 }
        public void Replacement()
        {
            var wnt = new WindowsNameTransform();

            wnt.TrimIncomingPaths = false;

            TestFile(wnt, "c::", "_");
            TestFile(wnt, "c\\/>", Path.Combine("c", "_"));
        }
Example #5
0
        public void LengthBoundaryOk()
        {
            var    wnt      = new WindowsNameTransform();
            string veryLong = "c:\\" + new string('x', 260);

            try {
                string transformed = wnt.TransformDirectory(veryLong);
            } catch {
                Assert.Fail("Expected no exception");
            }
        }
Example #6
0
        public void NameTooLong()
        {
            var wnt      = new WindowsNameTransform();
            var veryLong = new string('x', 261);

            try {
                wnt.TransformDirectory(veryLong);
                Assert.Fail("Expected an exception");
            } catch (PathTooLongException) {
            }
        }
        public void BasicFiles()
        {
            var wnt = new WindowsNameTransform();

            wnt.TrimIncomingPaths = false;

            TestFile(wnt, "Bogan", "Bogan");
            TestFile(wnt, "absolute/file2", Path.Combine("absolute", "file2"));
            TestFile(wnt, "C:/base/////////t", Path.Combine("base", "t"));
            TestFile(wnt, "//unc/share/zebidi/and/dylan", Path.Combine("zebidi", "and", "dylan"));
            TestFile(wnt, @"\\unc\share\/zebidi\/and\/dylan", Path.Combine("zebidi", "and", "dylan"));
        }
Example #8
0
 public override IAsyncOperation <IReadOnlyList <IStorageItem> > GetItemsAsync()
 {
     return(AsyncInfo.Run <IReadOnlyList <IStorageItem> >(async(cancellationToken) =>
     {
         using (ZipFile zipFile = await OpenZipFileAsync(FileAccessMode.Read))
         {
             if (zipFile == null)
             {
                 return null;
             }
             zipFile.IsStreamOwner = true;
             ZipEncoding ??= DetectFileEncoding(zipFile);
             var wnt = new WindowsNameTransform(ContainerPath, true); // Check with Path.GetFullPath
             var items = new List <IStorageItem>();
             foreach (var entry in zipFile.OfType <ZipEntry>())       // Returns all items recursively
             {
                 string winPath = System.IO.Path.GetFullPath(entry.IsDirectory ? wnt.TransformDirectory(DecodeEntryName(entry, ZipEncoding)) : wnt.TransformFile(DecodeEntryName(entry, ZipEncoding)));
                 if (winPath.StartsWith(Path.WithEnding("\\"), StringComparison.Ordinal)) // Child of self
                 {
                     var split = winPath.Substring(Path.Length).Split('\\', StringSplitOptions.RemoveEmptyEntries);
                     if (split.Length > 0)
                     {
                         if (entry.IsDirectory || split.Length > 1) // Not all folders have a ZipEntry
                         {
                             var itemPath = System.IO.Path.Combine(Path, split[0]);
                             if (!items.Any(x => x.Path == itemPath))
                             {
                                 items.Add(new ZipStorageFolder(itemPath, ContainerPath, entry)
                                 {
                                     ZipEncoding = ZipEncoding,
                                     BackingFile = BackingFile
                                 });
                             }
                         }
                         else
                         {
                             items.Add(new ZipStorageFile(winPath, ContainerPath, entry)
                             {
                                 BackingFile = BackingFile
                             });
                         }
                     }
                 }
             }
             return items;
         }
     }));
 }
Example #9
0
        public override IAsyncOperation <BaseStorageFile> CreateFileAsync(string desiredName, CreationCollisionOption options)
        {
            return(AsyncInfo.Run <BaseStorageFile>(async(cancellationToken) =>
            {
                using (ZipFile zipFile = await OpenZipFileAsync(FileAccessMode.ReadWrite))
                {
                    if (zipFile == null)
                    {
                        return null;
                    }
                    zipFile.IsStreamOwner = true;

                    var znt = new ZipNameTransform(ContainerPath);
                    var zipDesiredName = znt.TransformFile(System.IO.Path.Combine(Path, desiredName));
                    var entry = zipFile.GetEntry(zipDesiredName);

                    zipFile.BeginUpdate(new MemoryArchiveStorage(FileUpdateMode.Direct));
                    if (entry != null)
                    {
                        if (options != CreationCollisionOption.ReplaceExisting)
                        {
                            zipFile.AbortUpdate();
                            return null;
                        }
                        zipFile.Delete(entry);
                    }
                    zipFile.Add(new FileDataSource()
                    {
                        Stream = new MemoryStream()
                    }, zipDesiredName);
                    zipFile.CommitUpdate();

                    var wnt = new WindowsNameTransform(ContainerPath);
                    return new ZipStorageFile(wnt.TransformFile(zipDesiredName), ContainerPath)
                    {
                        BackingFile = BackingFile
                    };
                }
            }));
        }
Example #10
0
        public override IAsyncOperation <BaseStorageFolder> CreateFolderAsync(string desiredName, CreationCollisionOption options)
        {
            return(AsyncInfo.Run <BaseStorageFolder>(async(cancellationToken) =>
            {
                var hFile = NativeFileOperationsHelper.OpenFileForRead(ContainerPath, true);
                if (hFile.IsInvalid)
                {
                    return null;
                }
                using (ZipFile zipFile = new ZipFile(new FileStream(hFile, FileAccess.ReadWrite)))
                {
                    zipFile.IsStreamOwner = true;

                    var znt = new ZipNameTransform(ContainerPath);
                    var zipDesiredName = znt.TransformDirectory(System.IO.Path.Combine(Path, desiredName));
                    var entry = zipFile.GetEntry(zipDesiredName);

                    zipFile.BeginUpdate(new MemoryArchiveStorage(FileUpdateMode.Direct));
                    if (entry != null)
                    {
                        if (options != CreationCollisionOption.ReplaceExisting)
                        {
                            zipFile.AbortUpdate();
                            return null;
                        }
                        zipFile.Delete(entry);
                    }
                    zipFile.AddDirectory(zipDesiredName);
                    zipFile.CommitUpdate();

                    var wnt = new WindowsNameTransform(ContainerPath);
                    return new ZipStorageFolder(wnt.TransformFile(zipDesiredName), ContainerPath)
                    {
                        ZipEncoding = ZipEncoding
                    };
                }
            }));
        }
Example #11
0
        protected static bool ExtractPackage(IFile wrapFile, IDirectory destinationDirectory)
        {
            try
            {
                var nt = new WindowsNameTransform(destinationDirectory.Path.FullPath);
                using (var zipFile = new ZipFile(wrapFile.OpenRead()))
                {
                    foreach (ZipEntry zipEntry in zipFile)
                    {
                        if (zipEntry.IsFile)
                        {
                            IFile destinationFile;

                            if (System.IO.Path.DirectorySeparatorChar == '\\')
                            {
                                destinationFile = destinationDirectory.FileSystem.GetFile(nt.TransformFile(zipEntry.Name));
                            }
                            else
                            {
                                destinationFile = destinationDirectory.GetFile(zipEntry.Name);
                            }

                            using (var targetFile = destinationFile.MustExist().OpenWrite())
                                using (var sourceFile = zipFile.GetInputStream(zipEntry))
                                    StreamExtensions.CopyTo(sourceFile, targetFile);

                            destinationFile.LastModifiedTimeUtc = zipEntry.DateTime.ToUniversalTime();
                        }
                    }
                }
            }
            catch (Exception)
            {
                return(false);
            }
            return(true);
        }
        public void BasicDirectories()
        {
            WindowsNameTransform wnt = new WindowsNameTransform();

            wnt.TrimIncomingPaths = false;

            string tutu = Path.GetDirectoryName("\\bogan\\ping.txt");

            TestDirectory(wnt, "d/", "d");
            TestDirectory(wnt, "d", "d");
            TestDirectory(wnt, "absolute/file2", @"absolute\file2");

            const string BaseDir1 = @"C:\Dir";

            wnt.BaseDirectory = BaseDir1;

            TestDirectory(wnt, "talofa", Path.Combine(BaseDir1, "talofa"));

            const string BaseDir2 = @"C:\Dir\";

            wnt.BaseDirectory = BaseDir2;

            TestDirectory(wnt, "talofa", Path.Combine(BaseDir2, "talofa"));
        }
        public void BasicDirectories()
        {
            var wnt = new WindowsNameTransform();

            wnt.TrimIncomingPaths = false;

            string tutu = Path.GetDirectoryName("\\bogan\\ping.txt");

            TestDirectory(wnt, "d/", "d");
            TestDirectory(wnt, "d", "d");
            TestDirectory(wnt, "absolute/file2", @"absolute\file2");

            string BaseDir1 = Path.Combine("C:\\", "Dir");

            wnt.BaseDirectory = BaseDir1;

            TestDirectory(wnt, "talofa", Path.Combine(BaseDir1, "talofa"));

            string BaseDir2 = string.Format(@"C:{0}Dir{0}", Path.DirectorySeparatorChar);

            wnt.BaseDirectory = BaseDir2;

            TestDirectory(wnt, "talofa", Path.Combine(BaseDir2, "talofa"));
        }
Example #14
0
        object extractZip(object zipFileName, string rootDirectory, IStringFilter nf, IStringFilter df)
        {
            object ret = null;
            WindowsNameTransform      extractNameTransform = new WindowsNameTransform(rootDirectory);
            Dictionary <string, bool> dirs = new Dictionary <string, bool>(StringComparer.InvariantCultureIgnoreCase);

            Stream str;

            if (zipFileName is byte[])
            {
                str = new MemoryStream((byte[])zipFileName);
            }
            else
            {
                str = new SeekableStream(Context.OpenStream(zipFileName.ToString()), true);
            }
            using (ZipFile zip = new ZipFile(str))
            {
                if (Password != null)
                {
                    zip.Password = Context.TransformStr(Password, Transform);
                }

                foreach (ZipEntry entry in zip)
                {
                    string targetName = null;
                    if (entry.IsFile)
                    {
                        targetName = extractNameTransform.TransformFile(entry.Name);
                        if (!UsePath)
                        {
                            targetName = Path.Combine(rootDirectory, Path.GetFileName(targetName));
                        }
                    }
                    else if (entry.IsDirectory)
                    {
                        if (UsePath)
                        {
                            targetName = extractNameTransform.TransformDirectory(entry.Name);
                        }
                        else
                        {
                            targetName = rootDirectory;
                        }
                    }
                    if (string.IsNullOrEmpty(targetName))
                    {
                        continue;
                    }
                    if (!Hidden)
                    {
                        if (isDos(entry) && (((FileAttributes)entry.ExternalFileAttributes) & (FileAttributes.Hidden)) != 0)
                        {
                            continue;
                        }
                    }
                    if (string.IsNullOrEmpty(entry.Name))
                    {
                        continue;
                    }
                    var n = new ZipFSEntry(entry, ZipTime);
                    if ((entry.IsFile && df.IsMatch(Path.GetDirectoryName(n.FullName)) && nf.IsMatch(n.Name)) ||
                        (entry.IsDirectory && df.IsMatch(n.FullName)))
                    {
                        object r = extract(zip, rootDirectory, targetName, entry, dirs);
                        if (r != null)
                        {
                            return(r);
                        }
                    }
                }
            }
            return(ret);
        }
        public static async Task ExtractArchive(BaseStorageFile archive, BaseStorageFolder destinationFolder, IProgress <float> progressDelegate, CancellationToken cancellationToken)
        {
            ZipFile zipFile = await Filesystem.FilesystemTasks.Wrap(async() => new ZipFile(await archive.OpenStreamForReadAsync()));

            if (zipFile == null)
            {
                return;
            }
            using (zipFile)
            {
                zipFile.IsStreamOwner = true;
                List <ZipEntry> directoryEntries = new List <ZipEntry>();
                List <ZipEntry> fileEntries      = new List <ZipEntry>();
                foreach (ZipEntry entry in zipFile)
                {
                    if (entry.IsFile)
                    {
                        fileEntries.Add(entry);
                    }
                    else
                    {
                        directoryEntries.Add(entry);
                    }
                }

                if (cancellationToken.IsCancellationRequested) // Check if cancelled
                {
                    return;
                }

                var wnt         = new WindowsNameTransform(destinationFolder.Path);
                var zipEncoding = ZipStorageFolder.DetectFileEncoding(zipFile);

                var directories = new List <string>();
                try
                {
                    directories.AddRange(directoryEntries.Select((entry) => wnt.TransformDirectory(ZipStorageFolder.DecodeEntryName(entry, zipEncoding))));
                    directories.AddRange(fileEntries.Select((entry) => Path.GetDirectoryName(wnt.TransformFile(ZipStorageFolder.DecodeEntryName(entry, zipEncoding)))));
                }
                catch (InvalidNameException ex)
                {
                    App.Logger.Warn(ex, $"Error transforming zip names into: {destinationFolder.Path}\n" +
                                    $"Directories: {string.Join(", ", directoryEntries.Select(x => x.Name))}\n" +
                                    $"Files: {string.Join(", ", fileEntries.Select(x => x.Name))}");
                    return;
                }

                foreach (var dir in directories.Distinct().OrderBy(x => x.Length))
                {
                    if (!NativeFileOperationsHelper.CreateDirectoryFromApp(dir, IntPtr.Zero))
                    {
                        var dirName = destinationFolder.Path;
                        foreach (var component in dir.Substring(destinationFolder.Path.Length).Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries))
                        {
                            dirName = Path.Combine(dirName, component);
                            NativeFileOperationsHelper.CreateDirectoryFromApp(dirName, IntPtr.Zero);
                        }
                    }

                    if (cancellationToken.IsCancellationRequested) // Check if canceled
                    {
                        return;
                    }
                }

                if (cancellationToken.IsCancellationRequested) // Check if canceled
                {
                    return;
                }

                // Fill files

                byte[] buffer          = new byte[4096];
                int    entriesAmount   = fileEntries.Count;
                int    entriesFinished = 0;

                foreach (var entry in fileEntries)
                {
                    if (cancellationToken.IsCancellationRequested) // Check if canceled
                    {
                        return;
                    }
                    if (entry.IsCrypted)
                    {
                        App.Logger.Info($"Skipped encrypted zip entry: {entry.Name}");
                        continue; // TODO: support password protected archives
                    }

                    string filePath = wnt.TransformFile(ZipStorageFolder.DecodeEntryName(entry, zipEncoding));

                    var hFile = NativeFileOperationsHelper.CreateFileForWrite(filePath);
                    if (hFile.IsInvalid)
                    {
                        return; // TODO: handle error
                    }

                    // We don't close hFile because FileStream.Dispose() already does that
                    using (FileStream destinationStream = new FileStream(hFile, FileAccess.Write))
                    {
                        int currentBlockSize = 0;

                        using (Stream entryStream = zipFile.GetInputStream(entry))
                        {
                            while ((currentBlockSize = await entryStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                            {
                                await destinationStream.WriteAsync(buffer, 0, currentBlockSize);

                                if (cancellationToken.IsCancellationRequested) // Check if cancelled
                                {
                                    return;
                                }
                            }
                        }
                    }

                    entriesFinished++;
                    float percentage = (float)((float)entriesFinished / (float)entriesAmount) * 100.0f;
                    progressDelegate?.Report(percentage);
                }
            }
        }
Example #16
0
        public static async Task ExtractArchive(StorageFile archive, StorageFolder destinationFolder, IProgress <float> progressDelegate, CancellationToken cancellationToken)
        {
            using (ZipFile zipFile = new ZipFile(await archive.OpenStreamForReadAsync()))
            {
                zipFile.IsStreamOwner = true;
                List <ZipEntry> directoryEntries = new List <ZipEntry>();
                List <ZipEntry> fileEntries      = new List <ZipEntry>();
                foreach (ZipEntry entry in zipFile)
                {
                    if (entry.IsFile)
                    {
                        fileEntries.Add(entry);
                    }
                    else
                    {
                        directoryEntries.Add(entry);
                    }
                }

                if (cancellationToken.IsCancellationRequested) // Check if cancelled
                {
                    return;
                }

                var wnt = new WindowsNameTransform(destinationFolder.Path);

                var directories = new List <string>();
                directories.AddRange(directoryEntries.Select((item) => wnt.TransformDirectory(item.Name)));
                directories.AddRange(fileEntries.Select((item) => Path.GetDirectoryName(wnt.TransformFile(item.Name))));
                foreach (var dir in directories.Distinct().OrderBy(x => x.Length))
                {
                    if (!NativeFileOperationsHelper.CreateDirectoryFromApp(dir, IntPtr.Zero))
                    {
                        var dirName = destinationFolder.Path;
                        foreach (var component in dir.Substring(destinationFolder.Path.Length).Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries))
                        {
                            dirName = Path.Combine(dirName, component);
                            NativeFileOperationsHelper.CreateDirectoryFromApp(dirName, IntPtr.Zero);
                        }
                    }
                }

                if (cancellationToken.IsCancellationRequested) // Check if cancelled
                {
                    return;
                }

                // Fill files

                byte[] buffer          = new byte[4096];
                int    entriesAmount   = fileEntries.Count;
                int    entriesFinished = 0;

                foreach (var entry in fileEntries)
                {
                    if (cancellationToken.IsCancellationRequested) // Check if cancelled
                    {
                        return;
                    }

                    string filePath = wnt.TransformFile(entry.Name);

                    var hFile = NativeFileOperationsHelper.CreateFileForWrite(filePath);
                    if (hFile.IsInvalid)
                    {
                        return; // TODO: handle error
                    }

                    using (FileStream destinationStream = new FileStream(hFile, FileAccess.ReadWrite))
                    {
                        int currentBlockSize = 0;

                        using (Stream entryStream = zipFile.GetInputStream(entry))
                        {
                            while ((currentBlockSize = await entryStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                            {
                                await destinationStream.WriteAsync(buffer, 0, buffer.Length);

                                if (cancellationToken.IsCancellationRequested) // Check if cancelled
                                {
                                    return;
                                }
                            }
                        }
                    }
                    // We don't close handleContext because FileStream.Dispose() already does that

                    entriesFinished++;
                    float percentage = (float)((float)entriesFinished / (float)entriesAmount) * 100.0f;
                    progressDelegate?.Report(percentage);
                }
            }
        }