Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
antiufo committed Mar 30, 2017
1 parent eb234b3 commit e7ae1f9
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 0 deletions.
7 changes: 7 additions & 0 deletions NuGet.Config
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="dotnet.myget.org dotnet-core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" protocolVersion="3" />
<add key="dotnet.myget.org dotnet-corefxlab" value="https://dotnet.myget.org/F/dotnet-corefxlab/" />
</packageSources>
</configuration>
Binary file added Shaman.Dokan.Archive/7z.dll
Binary file not shown.
28 changes: 28 additions & 0 deletions Shaman.Dokan.Archive/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using System.Linq;
using System.Diagnostics;
using System.Threading.Tasks;
using SevenZip;
using System.IO;

namespace Shaman.Dokan
{
class SevenZipProgram
{
static int Main(string[] args)
{
SevenZipExtractor.SetLibraryPath(Path.Combine(Path.GetDirectoryName(typeof(SevenZipProgram).Assembly.Location), "7z.dll"));
var file = args.FirstOrDefault(x => !x.StartsWith("-"));
if (file == null)
{
Console.WriteLine("Must specify a file.");
return 1;
}
var mountpoint = new SevenZipFs(file).MountSimple(4);
if (args.Contains("--open"))
Process.Start(mountpoint);
new TaskCompletionSource<bool>().Task.Wait();
return 0;
}
}
}
119 changes: 119 additions & 0 deletions Shaman.Dokan.Archive/SevenZipFs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DokanNet;
using SevenZip;

namespace Shaman.Dokan
{
public class SevenZipFs : ReadOnlyFs
{

public SevenZipExtractor extractor;
private FsNode<ArchiveFileInfo> root;
public SevenZipFs(string path)
{
zipfile = path;
extractor = new SevenZipExtractor(path);
root = CreateTree<ArchiveFileInfo>(extractor.ArchiveFileData, x => x.FileName, x => IsDirectory(x.Attributes));


cache = new MemoryStreamCache<FsNode<ArchiveFileInfo>>((item, stream) =>
{
lock (readerLock)
{
extractor.ExtractFile(item.Info.Index, stream);
}
});
}
private string zipfile;
public override string SimpleMountName => "SevenZipFs-" + zipfile;

private object readerLock = new object();

public override NtStatus CreateFile(string fileName, DokanNet.FileAccess access, FileShare share, FileMode mode, FileOptions options, FileAttributes attributes, DokanFileInfo info)
{

if (IsBadName(fileName)) return NtStatus.ObjectNameInvalid;
if ((access & ModificationAttributes) != 0) return NtStatus.DiskFull;

var item = GetFile(fileName);
if (item == null) return DokanResult.FileNotFound;
if (item.Info.FileName != null && !item.Info.IsDirectory)
{
if ((access & DokanNet.FileAccess.ReadData) != 0)
{
Console.WriteLine("ReadData: " + fileName);
info.Context = cache.OpenStream(item, (long)item.Info.Size);

}
return NtStatus.Success;
}
else
{
info.IsDirectory = true;
return NtStatus.Success;
}
}


private MemoryStreamCache<FsNode<ArchiveFileInfo>> cache;
public override NtStatus GetFileInformation(string fileName, out FileInformation fileInfo, DokanFileInfo info)
{
var item = GetFile(fileName);
if (item == null)
{
fileInfo = default(FileInformation);
return DokanResult.FileNotFound;
}
fileInfo = GetFileInformation(item);
return NtStatus.Success;
}

public override NtStatus GetVolumeInformation(out string volumeLabel, out FileSystemFeatures features, out string fileSystemName, DokanFileInfo info)
{
fileSystemName = volumeLabel = "SevenZipFs";
features = FileSystemFeatures.CasePreservedNames | FileSystemFeatures.ReadOnlyVolume | FileSystemFeatures.UnicodeOnDisk | FileSystemFeatures.VolumeIsCompressed;
return NtStatus.Success;
}

private FsNode<ArchiveFileInfo> GetFile(string fileName)
{
return GetNode(root, fileName);
}

protected override IList<FileInformation> FindFilesHelper(string fileName, string searchPattern)
{
var item = GetFile(fileName);
if (item == null) return null;

if (item == root || IsDirectory(item.Info.Attributes))
{
if (item.Children == null) return new FileInformation[] { };
var matcher = GetMatcher(searchPattern);
return item.Children.Where(x => matcher(x.Name)).Select(x => GetFileInformation(x)).ToList();
}
return null;
}

private FileInformation GetFileInformation(FsNode<ArchiveFileInfo> item)
{
return new FileInformation()
{
Attributes = item == root ? FileAttributes.Directory : (FileAttributes)item.Info.Attributes,
CreationTime = item.Info.CreationTime,
FileName = item.Name,
LastAccessTime = item.Info.LastAccessTime,
LastWriteTime = item.Info.LastWriteTime,
Length = (long)item.Info.Size
};
}

public override void Cleanup(string fileName, DokanFileInfo info)
{
}
}
}
20 changes: 20 additions & 0 deletions Shaman.Dokan.Archive/Shaman.Dokan.Archive.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net46</TargetFramework>
<AssemblyOriginatorKeyFile>ShamanOpenSourceKey.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<ItemGroup />
<ItemGroup>
<PackageReference Include="Shaman.SevenZipSharp" Version="1.0.6.3" />
<PackageReference Include="Shaman.Dokan.Base" Version="1.0.0.1" />
</ItemGroup>
<ItemGroup>
<None Update="7z.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
Binary file added Shaman.Dokan.Archive/ShamanOpenSourceKey.snk
Binary file not shown.

0 comments on commit e7ae1f9

Please sign in to comment.