ProjectArcade
117 строк · 4.8 Кб
1using System;
2using DokanNet.Logging;
3using DokanNet.Native;
4
5namespace DokanNet
6{
7/// <summary>
8/// Created by <see cref="Dokan.CreateFileSystem"/>.
9/// It holds all the resources required to be alive for the time of the mount.
10/// </summary>
11public class DokanInstance : IDisposable
12{
13private static DOKAN_OPERATIONS PrepareOperations(ILogger logger, IDokanOperations operations)
14{
15var dokanOperationProxy = new DokanOperationProxy(logger, operations);
16
17return new DOKAN_OPERATIONS
18{
19ZwCreateFile = dokanOperationProxy.ZwCreateFileProxy,
20Cleanup = dokanOperationProxy.CleanupProxy,
21CloseFile = dokanOperationProxy.CloseFileProxy,
22ReadFile = dokanOperationProxy.ReadFileProxy,
23WriteFile = dokanOperationProxy.WriteFileProxy,
24FlushFileBuffers = dokanOperationProxy.FlushFileBuffersProxy,
25GetFileInformation = dokanOperationProxy.GetFileInformationProxy,
26FindFiles = dokanOperationProxy.FindFilesProxy,
27FindFilesWithPattern = dokanOperationProxy.FindFilesWithPatternProxy,
28SetFileAttributes = dokanOperationProxy.SetFileAttributesProxy,
29SetFileTime = dokanOperationProxy.SetFileTimeProxy,
30DeleteFile = dokanOperationProxy.DeleteFileProxy,
31DeleteDirectory = dokanOperationProxy.DeleteDirectoryProxy,
32MoveFile = dokanOperationProxy.MoveFileProxy,
33SetEndOfFile = dokanOperationProxy.SetEndOfFileProxy,
34SetAllocationSize = dokanOperationProxy.SetAllocationSizeProxy,
35LockFile = dokanOperationProxy.LockFileProxy,
36UnlockFile = dokanOperationProxy.UnlockFileProxy,
37GetDiskFreeSpace = dokanOperationProxy.GetDiskFreeSpaceProxy,
38GetVolumeInformation = dokanOperationProxy.GetVolumeInformationProxy,
39Mounted = dokanOperationProxy.MountedProxy,
40Unmounted = dokanOperationProxy.UnmountedProxy,
41GetFileSecurity = dokanOperationProxy.GetFileSecurityProxy,
42SetFileSecurity = dokanOperationProxy.SetFileSecurityProxy,
43FindStreams = dokanOperationProxy.FindStreamsProxy
44};
45}
46
47internal NativeStructWrapper<DOKAN_OPTIONS> DokanOptions { get; private set; }
48internal NativeStructWrapper<DOKAN_OPERATIONS> DokanOperations { get; private set; }
49internal DokanHandle DokanHandle { get; private set; }
50private readonly object _disposeLock;
51private bool _disposed = false;
52public bool IsDisposed
53{
54get { lock (_disposeLock) return _disposed; }
55}
56
57internal DokanInstance(ILogger logger, DOKAN_OPTIONS options, IDokanOperations operations)
58{
59DokanOptions = NativeStructWrapper.Wrap(options);
60var preparedOperations = PrepareOperations(logger, operations);
61DokanOperations = NativeStructWrapper.Wrap(preparedOperations);
62_disposeLock = new object();
63
64DokanHandle handle;
65var status = NativeMethods.DokanCreateFileSystem(DokanOptions, DokanOperations, out handle);
66if (status != DokanStatus.Success)
67{
68throw new DokanException(status);
69}
70DokanHandle = handle;
71}
72
73protected virtual void Dispose(bool disposing)
74{
75lock (_disposeLock)
76{
77if (!_disposed)
78{
79if (disposing)
80{
81// Dispose managed state (managed objects)
82if (DokanHandle != null)
83DokanHandle.Dispose(); // This calls DokanCloseHandle and waits for dismount
84
85if (DokanOptions != null)
86DokanOptions.Dispose(); // After that, it is safe to free unmanaged memory
87
88if (DokanOperations != null)
89DokanOperations.Dispose();
90}
91
92// Free unmanaged resources (unmanaged objects) and override finalizer
93
94// Set fields to null
95DokanOptions = null;
96DokanOperations = null;
97DokanHandle = null;
98
99_disposed = true;
100}
101}
102}
103
104~DokanInstance()
105{
106// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
107Dispose(disposing: false);
108}
109
110public void Dispose()
111{
112// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
113Dispose(disposing: true);
114GC.SuppressFinalize(this);
115}
116}
117}
118