Skip to content

Commit d84fb2a

Browse files
committed
v6.1.19907.0-Beta
1 parent ec25f54 commit d84fb2a

31 files changed

+559
-365
lines changed

Common/Common.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<Platforms>AnyCPU;x64</Platforms>
1111
</PropertyGroup>
1212
<ItemGroup>
13-
<PackageReference Include="ITHit.FileSystem" Version="6.1.18982.0-Beta" />
13+
<PackageReference Include="ITHit.FileSystem.Windows" Version="6.1.19907.0-Beta" />
14+
<PackageReference Include="ITHit.FileSystem" Version="6.1.19907.0-Beta" />
1415
</ItemGroup>
1516
</Project>

Common/CustomColumnIds.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,6 @@ public enum CustomColumnIds
1515
/// </summary>
1616
LockOwnerIcon = 2,
1717

18-
/// <summary>
19-
/// Conflict icon column ID. The conflict icon is being displayed in the Windows File Manager Status column.
20-
/// </summary>
21-
ConflictIcon = 3,
22-
2318
/// <summary>
2419
/// Lock Scope column ID. Shows if the lock is Exclusive or Shared.
2520
/// </summary>
@@ -33,6 +28,6 @@ public enum CustomColumnIds
3328
/// <summary>
3429
/// ETag column ID.
3530
/// </summary>
36-
ETag = 6
31+
ETag = 6,
3732
}
3833
}

Common/ServerLockInfo.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
using ITHit.FileSystem.Windows;
12
using System;
23
using System.Collections.Generic;
34
using System.Text;
45

56
namespace ITHit.FileSystem.Samples.Common
67
{
78
/// <summary>
8-
/// Information about the lock returned from the remote storage as a result of the lock operation.
9+
/// Information about the lock.
910
/// </summary>
1011
public class ServerLockInfo
1112
{
@@ -28,5 +29,14 @@ public class ServerLockInfo
2829
/// True if the item is locked exclusively. False in case the item has a shared lock.
2930
/// </summary>
3031
public bool Exclusive { get; set; } = true;
32+
33+
/// <summary>
34+
/// Lock mode.
35+
/// </summary>
36+
/// <remarks>
37+
/// If the item is locked by this user on this machine the value of this property indicates automatic or manual lock.
38+
/// If the item is locked by other user or locked by this user on other machine contains <see cref="LockMode.None"/> value.
39+
/// </remarks>
40+
public LockMode Mode { get; set; } = LockMode.None;
3141
}
3242
}

Windows/Common/Core/Common.Windows.Core.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
<PackageReference Include="Microsoft.Windows.SDK.Contracts" Version="10.0.19041.1" />
2121
</ItemGroup>
2222
<ItemGroup>
23-
<PackageReference Include="ITHit.FileSystem.Windows.Package" Version="6.1.18982.0-Beta" />
24-
<PackageReference Include="ITHit.FileSystem.Windows" Version="6.1.18982.0-Beta" />
23+
<PackageReference Include="ITHit.FileSystem.Windows.Package" Version="6.1.19907.0-Beta" />
24+
<PackageReference Include="ITHit.FileSystem.Windows" Version="6.1.19907.0-Beta" />
2525
<ProjectReference Include="..\..\..\Common\Common.csproj" />
2626
</ItemGroup>
2727
</Project>

Windows/Common/VirtualDrive/Common.Windows.VirtualDrive.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
<Authors>IT Hit LTD.</Authors>
66
<Product>IT Hit User File System</Product>
77
<Copyright>IT Hit LTD.</Copyright>
8-
<RootNamespace>ITHit.FileSystem.Samples.Common.Windows.VirtualDrive</RootNamespace>
8+
<RootNamespace>ITHit.FileSystem.Samples.Common.Windows</RootNamespace>
99
<Platforms>AnyCPU;x64</Platforms>
1010
</PropertyGroup>
1111
<ItemGroup>
1212
<Compile Remove="IncomingFullSync.cs" />
1313
<Compile Remove="IVirtualFolder.cs" />
1414
</ItemGroup>
1515
<ItemGroup>
16-
<PackageReference Include="ITHit.FileSystem.Windows" Version="6.1.18982.0-Beta" />
16+
<PackageReference Include="ITHit.FileSystem.Windows" Version="6.1.19907.0-Beta" />
1717
<ProjectReference Include="..\..\..\Common\Common.csproj" />
1818
<ProjectReference Include="..\Core\Common.Windows.Core.csproj" />
1919
</ItemGroup>

Windows/WebDAVDrive/WebDAVDrive/IncomingServerNotifications.cs renamed to Windows/Common/VirtualDrive/IncomingServerNotifications.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@
66
using ITHit.FileSystem.Samples.Common.Windows;
77
using ITHit.FileSystem.Windows;
88

9-
namespace WebDAVDrive
9+
namespace ITHit.FileSystem.Samples.Common.Windows
1010
{
1111
/// <summary>
1212
/// Provides custom properties storage and logging for incoming updates from remote storage.
1313
/// </summary>
14-
internal class IncomingServerNotifications
14+
public class IncomingServerNotifications
1515
{
1616
/// <summary>
1717
/// Virtual drive.
1818
/// </summary>
19-
protected readonly VirtualEngine Engine;
19+
protected readonly EngineWindows Engine;
2020

2121
/// <summary>
2222
/// Logger.
@@ -27,7 +27,7 @@ internal class IncomingServerNotifications
2727
/// Creates instance of this class.
2828
/// </summary>
2929
/// <param name="engine">Engine instance.</param>
30-
internal IncomingServerNotifications(VirtualEngine engine, ILogger logger)
30+
public IncomingServerNotifications(EngineWindows engine, ILogger logger)
3131
{
3232
this.Engine = engine;
3333
this.Logger = logger;

Windows/Common/VirtualDrive/MenuCommandLock.cs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
using System.IO;
44
using System.Threading;
55
using System.Threading.Tasks;
6+
67
using ITHit.FileSystem.Windows;
78

9+
810
namespace ITHit.FileSystem.Samples.Common.Windows
911
{
1012

@@ -15,7 +17,7 @@ namespace ITHit.FileSystem.Samples.Common.Windows
1517
/// </summary>
1618
public class MenuCommandLock : IMenuCommandWindows
1719
{
18-
private readonly EngineWindows engine;
20+
private readonly VirtualEngineBase engine;
1921
private readonly ILogger logger;
2022

2123
private const string lockCommandIcon = @"Images\Locked.ico";
@@ -26,7 +28,7 @@ public class MenuCommandLock : IMenuCommandWindows
2628
/// </summary>
2729
/// <param name="engine">Engine instance.</param>
2830
/// <param name="logger">Logger.</param>
29-
public MenuCommandLock(EngineWindows engine, ILogger logger)
31+
public MenuCommandLock(VirtualEngineBase engine, ILogger logger)
3032
{
3133
this.engine = engine;
3234
this.logger = logger.CreateLogger("Lock Menu Command");
@@ -96,7 +98,9 @@ public async Task<string> GetToolTipAsync(IEnumerable<string> filesPath)
9698
/// Returns files lock status.
9799
/// </summary>
98100
/// <remarks>
99-
/// True - if all items are locked. False - if all items are unlocked. null - if some items are locked, others unlocked.
101+
/// True - if all items are locked by this user.
102+
/// False - if all items are unlocked.
103+
/// null - if some items are locked, others unlocked or if any item is locked by another user.
100104
/// </remarks>
101105
private async Task<bool?> IsLockedAsync(IEnumerable<string> filesPath, CancellationToken cancellationToken = default)
102106
{
@@ -105,12 +109,24 @@ public async Task<string> GetToolTipAsync(IEnumerable<string> filesPath)
105109
{
106110
try
107111
{
108-
IClientNotifications clientNotifications = engine.ClientNotifications(userFileSystemPath, logger);
109-
LockMode lockMode = await clientNotifications.GetLockModeAsync(cancellationToken);
112+
bool isLocked = false;
113+
if (engine.Placeholders.TryGetItem(userFileSystemPath, out PlaceholderItem placeholder))
114+
{
115+
if (placeholder.TryGetLockInfo(out ServerLockInfo lockInfo))
116+
{
117+
// Detect if locked by this user.
118+
bool thisUser = engine.CurrentUserPrincipal.Equals(lockInfo.Owner, StringComparison.InvariantCultureIgnoreCase);
119+
if (!thisUser)
120+
{
121+
// Typically we can not unlock items locked by other users. We must hide or disable the menu in tis case.
122+
return null;
123+
}
110124

111-
bool isLocked = lockMode != LockMode.None;
125+
isLocked = true;
126+
}
127+
}
112128

113-
if(allLocked.HasValue && (allLocked != isLocked))
129+
if (allLocked.HasValue && (allLocked != isLocked))
114130
{
115131
return null;
116132
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
using ITHit.FileSystem.Windows;
8+
9+
10+
namespace ITHit.FileSystem.Samples.Common.Windows
11+
{
12+
/// <summary>
13+
/// Provides methods for getting and setting custom data associated with a file or folder.
14+
/// </summary>
15+
public static class PlaceholderItemExtensions
16+
{
17+
/// <summary>
18+
/// Returns true if the remote item is modified. False - otherwise.
19+
/// </summary>
20+
/// <remarks>
21+
/// This method compares client and server eTags and returns true if the
22+
/// item in the user file system must be updated with the data from the remote storage.
23+
/// </remarks>
24+
/// <param name="placeholder">User file system placeholder item.</param>
25+
/// <param name="remoteStorageItem">Remote storage item metadata.</param>
26+
/// <returns></returns>
27+
public static async Task<bool> IsModifiedAsync(this PlaceholderItem placeholder, FileSystemItemMetadataExt remoteStorageItemMetadata)
28+
{
29+
placeholder.TryGetETag(out string clientEtag);
30+
return clientEtag != remoteStorageItemMetadata.ETag;
31+
}
32+
33+
34+
/// <summary>
35+
/// Saves all data that is displayed in custom columns in file manager
36+
/// as well as any additional custom data required by the client.
37+
/// </summary>
38+
/// <param name="placeholder">User file system placeholder item.</param>
39+
/// <param name="remoteStorageItem">Remote storage item metadata.</param>
40+
/// <returns>A task object that can be awaited.</returns>
41+
public static async Task SavePropertiesAsync(this PlaceholderItem placeholder, FileSystemItemMetadataExt metadata)
42+
{
43+
// Save lock.
44+
if (metadata.Lock != null)
45+
{
46+
placeholder.SetLockInfo(metadata.Lock);
47+
}
48+
49+
// Save eTag.
50+
if (metadata.ETag != null)
51+
{
52+
placeholder.SetETag(metadata.ETag);
53+
}
54+
55+
//foreach (FileSystemItemPropertyData prop in metadata.CustomProperties)
56+
//{
57+
// string key = ((CustomColumnIds)prop.Id).ToString();
58+
// await placeholder.Properties.AddOrUpdateAsync(key, prop);
59+
//}
60+
}
61+
62+
/// <summary>
63+
/// Tries to get eTag.
64+
/// </summary>
65+
/// <param name="placeholder">User file system placeholder item.</param>
66+
/// <param name="eTag">eTag.</param>
67+
/// <returns>True if method succeeded. False - otherwise.</returns>
68+
public static bool TryGetETag(this PlaceholderItem placeholder, out string eTag)
69+
{
70+
if (placeholder.Properties.TryGetValue("ETag", out IDataItem propETag))
71+
{
72+
return propETag.TryGetValue<string>(out eTag);
73+
}
74+
eTag = null;
75+
return false;
76+
}
77+
78+
/// <summary>
79+
/// Sets eTag.
80+
/// </summary>
81+
/// <param name="placeholder">User file system placeholder item.</param>
82+
/// <param name="eTag">eTag.</param>
83+
public static void SetETag(this PlaceholderItem placeholder, string eTag)
84+
{
85+
placeholder.Properties.AddOrUpdate("ETag", eTag);
86+
}
87+
88+
/// <summary>
89+
/// Tries to get lock info.
90+
/// </summary>
91+
/// <param name="placeholder">User file system placeholder item.</param>
92+
/// <param name="serverLockInfo">Lock info.</param>
93+
/// <returns>True if method succeeded and the item is locked. False if the method failed or the item is not locked.</returns>
94+
public static bool TryGetLockInfo(this PlaceholderItem placeholder, out ServerLockInfo serverLockInfo)
95+
{
96+
if (placeholder.Properties.TryGetValue("LockInfo", out IDataItem propLockInfo))
97+
{
98+
if (propLockInfo.TryGetValue<ServerLockInfo>(out ServerLockInfo lockInfo))
99+
{
100+
if (lockInfo.LockExpirationDateUtc > DateTimeOffset.Now)
101+
{
102+
serverLockInfo = lockInfo;
103+
return true;
104+
}
105+
}
106+
}
107+
serverLockInfo = null;
108+
return false;
109+
}
110+
111+
/// <summary>
112+
/// Sets lock info.
113+
/// </summary>
114+
/// <param name="placeholder">User file system placeholder item.</param>
115+
/// <param name="serverLockInfo">Lock info.</param>
116+
public static void SetLockInfo(this PlaceholderItem placeholder, ServerLockInfo serverLockInfo)
117+
{
118+
placeholder.Properties.AddOrUpdate("LockInfo", serverLockInfo);
119+
}
120+
121+
/// <summary>
122+
/// Tries to delete lock info.
123+
/// </summary>
124+
/// <param name="placeholder">User file system placeholder item.</param>
125+
/// <returns>True if method succeeded. False - otherwise.</returns>
126+
public static bool TryDeleteLockInfo(this PlaceholderItem placeholder)
127+
{
128+
return placeholder.Properties.Remove("LockInfo");
129+
}
130+
}
131+
}

Windows/Common/VirtualDrive/VirtualEngineBase.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,15 @@ namespace ITHit.FileSystem.Samples.Common.Windows
1212
public abstract class VirtualEngineBase : EngineWindows
1313
{
1414
/// <summary>
15-
/// Monitors changes in the remote storage, notifies the client and updates the user file system.
15+
/// Currently loged-in user name or user ID.
1616
/// </summary>
17-
// public readonly RemoteStorageMonitor RemoteStorageMonitor;
17+
/// <remarks>
18+
/// Used to set lock Owner name as well as to distinguish locks applied
19+
/// by the currently loged-in user from locks applied by other users, across multiple devices.
20+
///
21+
/// The default value of the Environment.UserName is used for demo purposes only.
22+
/// </remarks>
23+
public string CurrentUserPrincipal { get; set; } = Environment.UserName;
1824

1925
/// <summary>
2026
/// Path to the icons folder.
@@ -26,8 +32,6 @@ public abstract class VirtualEngineBase : EngineWindows
2632
/// </summary>
2733
public string IconsFolderPath => iconsFolderPath;
2834

29-
//public abstract IMapping Mapping { get; }
30-
3135
/// <summary>
3236
/// Creates a vitual file system Engine.
3337
/// </summary>
@@ -59,8 +63,6 @@ public VirtualEngineBase(
5963
Error += logFormatter.LogError;
6064
Message += logFormatter.LogMessage;
6165
Debug += logFormatter.LogDebug;
62-
63-
//RemoteStorageMonitor = new RemoteStorageMonitor(remoteStorageRootPath, this, log4net);
6466
}
6567

6668
/// <inheritdoc/>
@@ -98,13 +100,11 @@ public override async Task<bool> FilterAsync(SyncDirection direction, OperationT
98100
public override async Task StartAsync(bool processModified = true, CancellationToken cancellationToken = default)
99101
{
100102
await base.StartAsync(processModified, cancellationToken);
101-
//RemoteStorageMonitor.Start();
102103
}
103104

104105
public override async Task StopAsync()
105106
{
106-
await base.StopAsync();
107-
//RemoteStorageMonitor.Stop();
107+
await base.StopAsync();
108108
}
109109

110110
/// <summary>
@@ -139,7 +139,7 @@ protected override void Dispose(bool disposing)
139139
{
140140
if (disposing)
141141
{
142-
//RemoteStorageMonitor.Dispose();
142+
143143
}
144144

145145
// TODO: free unmanaged resources (unmanaged objects) and override finalizer

Windows/VirtualDrive/VirtualDrive.ShellExtension/VirtualDrive.ShellExtension.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<PackageReference Include="System.Drawing.Common" Version="6.0.0" />
2020
</ItemGroup>
2121
<ItemGroup>
22-
<PackageReference Include="ITHit.FileSystem.Windows.ShellExtension" Version="6.1.18982.0-Beta" />
22+
<PackageReference Include="ITHit.FileSystem.Windows.ShellExtension" Version="6.1.19907.0-Beta" />
2323
</ItemGroup>
2424
<ItemGroup>
2525
<None Update="log4net.config">

0 commit comments

Comments
 (0)