Skip to content

Commit 5b55b2a

Browse files
feat(webui): root contains shortcut to the IPFFS WebUI
1 parent 3d8da7a commit 5b55b2a

File tree

6 files changed

+91
-2
lines changed

6 files changed

+91
-2
lines changed

IpfsMount/IpfsDokan.cs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ public NtStatus CreateFile(string fileName, DokanNet.FileAccess access, FileShar
5151
return DokanResult.Success;
5252
}
5353

54+
// Predefined files
55+
PredefinedFile predefinedFile = null;
56+
if (PredefinedFile.All.TryGetValue(fileName, out predefinedFile))
57+
{
58+
info.Context = predefinedFile;
59+
return DokanResult.Success;
60+
}
61+
5462
// Get file info from IPFS
5563
var ipfsFileName = fileName.Replace(@"\", "/");
5664
try
@@ -112,6 +120,13 @@ public NtStatus GetFileInformation(string fileName, out FileInformation fileInfo
112120
return DokanResult.Success;
113121
}
114122

123+
var predefinedFile = info.Context as PredefinedFile;
124+
if (predefinedFile != null)
125+
{
126+
fileInfo.Length = predefinedFile.Data.Length;
127+
return DokanResult.Success;
128+
}
129+
115130
// Root info
116131
if (fileName == rootName)
117132
{
@@ -185,6 +200,15 @@ public NtStatus Unmounted(DokanFileInfo info)
185200
#region File Operations
186201
public NtStatus ReadFile(string fileName, byte[] buffer, out int bytesRead, long offset, DokanFileInfo info)
187202
{
203+
var predefinedFile = info.Context as PredefinedFile;
204+
if (predefinedFile != null)
205+
{
206+
bytesRead = (int) Math.Min(buffer.LongLength, predefinedFile.Data.LongLength - offset);
207+
Buffer.BlockCopy(predefinedFile.Data, (int)offset, buffer, 0, bytesRead);
208+
return DokanResult.Success;
209+
}
210+
211+
188212
var file = (IpfsFile)info.Context;
189213

190214
// TODO: Not very efficient. Maybe access the merkle dags.
@@ -301,17 +325,26 @@ public NtStatus FindFiles(string fileName, out IList<FileInformation> files, Dok
301325
return DokanResult.Success;
302326
}
303327

304-
// The root consists only of the root folders.
328+
// The root consists of the root folders and the predefined files.
305329
if (fileName == rootName)
306330
{
307331
files = rootFolders
308-
.Select(name => new FileInformation()
332+
.Select(name => new FileInformation
309333
{
310334
FileName = name,
311335
Attributes = FileAttributes.Directory | FileAttributes.ReadOnly,
312336
LastAccessTime = DateTime.Now
313337
})
314338
.ToList();
339+
foreach (var predefinedFile in PredefinedFile.All.Values)
340+
{
341+
files.Add(new FileInformation
342+
{
343+
FileName = Path.GetFileName(predefinedFile.Name),
344+
Attributes = FileAttributes.ReadOnly,
345+
Length = predefinedFile.Data.Length
346+
});
347+
}
315348
return DokanResult.Success;
316349
}
317350

IpfsMount/IpfsMount.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
<Compile Include="DokanLogger.cs" />
8585
<Compile Include="IpfsDokan.cs" />
8686
<Compile Include="IpfsFile.cs" />
87+
<Compile Include="PredefinedFile.cs" />
8788
<Compile Include="Program.cs" />
8889
<Compile Include="Properties\AssemblyInfo.cs" />
8990
</ItemGroup>
@@ -93,6 +94,7 @@
9394
</ItemGroup>
9495
<ItemGroup>
9596
<Content Include="FodyWeavers.xml" />
97+
<EmbeddedResource Include="Resources\PredefineFiles\Manage IPFS.url" />
9698
</ItemGroup>
9799
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
98100
<Import Project="..\packages\Fody.1.28.3\build\Fody.targets" Condition="Exists('..\packages\Fody.1.28.3\build\Fody.targets')" />

IpfsMount/PredefinedFile.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Reflection;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
9+
namespace Ipfs.VirtualDisk
10+
{
11+
class PredefinedFile
12+
{
13+
public static Dictionary<string, PredefinedFile> All { get; private set; }
14+
15+
static PredefinedFile()
16+
{
17+
const string prefix = "Ipfs.VirtualDisk.Resources.PredefineFiles.";
18+
All = Assembly.GetExecutingAssembly()
19+
.GetManifestResourceNames()
20+
.Where(name => name.StartsWith(prefix))
21+
.Select(name => new PredefinedFile
22+
{
23+
Name = @"\" + name.Substring(prefix.Length),
24+
Data = GetData(name)
25+
})
26+
.ToDictionary(f => f.Name, f => f);
27+
}
28+
29+
public string Name { get; set; }
30+
public byte[] Data { get; set; }
31+
32+
static byte[] GetData(string name)
33+
{
34+
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name))
35+
using (var ms = new MemoryStream())
36+
{
37+
stream.CopyTo(ms);
38+
return ms.ToArray();
39+
}
40+
}
41+
}
42+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[InternetShortcut]
2+
URL=http://localhost:5001/webui

IpfsMountTests/DriveTest.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,14 @@ public void Root_Enumerate_Special_Folders()
6262
Assert.AreEqual(2, folders.Count());
6363
}
6464

65+
[TestMethod]
66+
public void Root_has_Shortcut_to_WebUI()
67+
{
68+
const string shortcut = @"t:\Manage IPFS.url";
69+
Assert.IsTrue(File.Exists(shortcut));
70+
var lines = File.ReadAllLines(shortcut);
71+
Assert.AreEqual("[InternetShortcut]", lines[0]);
72+
}
73+
6574
}
6675
}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Mount the [InterPlanetary File System](https://ipfs.io/) as a mapped drive on Wi
1010
- Mounts IPFS and IPNS on a drive letter, `ipfs-mount z:`
1111
- Unmounts the drive, `ipfs-mount z: /u`
1212
- [Pinned files](https://github.com/ipfs/examples/blob/master/examples/pinning/readme.md) are available in `z:\ipfs`
13+
- Root contains shortcut to the IPFS WebUI
1314

1415
## Installation
1516

0 commit comments

Comments
 (0)