testing remote stuff
This commit is contained in:
parent
1e05d4576d
commit
3c9ccaafeb
374 changed files with 10526 additions and 2037 deletions
172
src/Remote/Insight.Remote.Windows/Services/WinFileProvider.cs
Normal file
172
src/Remote/Insight.Remote.Windows/Services/WinFileProvider.cs
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
using Insight.Remote.Shared.Abstractions;
|
||||
using Insight.Remote.Shared.Services;
|
||||
using Insight.Remote.Shared.ViewModels;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Security.AccessControl;
|
||||
using System.Security.Principal;
|
||||
using System.Windows;
|
||||
using MessageBoxOptions = System.Windows.MessageBoxOptions;
|
||||
|
||||
namespace Insight.Remote.Windows.Services;
|
||||
|
||||
internal class WinFileProvider : IFileProvider
|
||||
{
|
||||
private static MessageBoxResult? _result;
|
||||
private static readonly ConcurrentDictionary<string, FileStream> _partialTransfers = new();
|
||||
private static readonly SemaphoreSlim _writeLock = new(1, 1);
|
||||
private readonly ILogger<WinFileProvider> _logger;
|
||||
|
||||
public WinFileProvider(ILogger<WinFileProvider> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public string GetBaseDirectory()
|
||||
{
|
||||
var programDataPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
|
||||
return Directory.CreateDirectory(Path.Combine(programDataPath, "RemoteControl", "Shared")).FullName;
|
||||
}
|
||||
|
||||
public async Task ReceiveFile(byte[] buffer, string fileName, string messageId, bool endOfFile, bool startOfFile)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _writeLock.WaitAsync();
|
||||
|
||||
var baseDir = GetBaseDirectory();
|
||||
|
||||
SetFileOrFolderPermissions(baseDir);
|
||||
|
||||
if (startOfFile)
|
||||
{
|
||||
var filePath = Path.Combine(baseDir, fileName);
|
||||
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
var count = 0;
|
||||
var ext = Path.GetExtension(fileName);
|
||||
var fileWithoutExt = Path.GetFileNameWithoutExtension(fileName);
|
||||
while (File.Exists(filePath))
|
||||
{
|
||||
filePath = Path.Combine(baseDir, $"{fileWithoutExt}-{count}{ext}");
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
File.Create(filePath).Close();
|
||||
SetFileOrFolderPermissions(filePath);
|
||||
var fs = new FileStream(filePath, FileMode.OpenOrCreate);
|
||||
_partialTransfers.AddOrUpdate(messageId, fs, (k, v) => fs);
|
||||
}
|
||||
|
||||
var fileStream = _partialTransfers[messageId];
|
||||
|
||||
if (buffer?.Length > 0)
|
||||
{
|
||||
await fileStream.WriteAsync(buffer);
|
||||
}
|
||||
|
||||
if (endOfFile)
|
||||
{
|
||||
fileStream.Close();
|
||||
_partialTransfers.Remove(messageId, out _);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error while receiving file.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeLock.Release();
|
||||
if (endOfFile)
|
||||
{
|
||||
await Task.Run(ShowTransferComplete);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task UploadFile(FileUpload fileUpload, Streamer viewer, Action<double> progressUpdateCallback, CancellationToken cancelToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
//await viewer.SendFileAsync(fileUpload, progressUpdateCallback, cancelToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error while uploading file.");
|
||||
}
|
||||
}
|
||||
|
||||
private void SetFileOrFolderPermissions(string path)
|
||||
{
|
||||
FileSystemSecurity ds;
|
||||
|
||||
var aclSections = AccessControlSections.Access | AccessControlSections.Group | AccessControlSections.Owner;
|
||||
if (File.Exists(path))
|
||||
{
|
||||
ds = new FileSecurity(path, aclSections);
|
||||
}
|
||||
else if (Directory.Exists(path))
|
||||
{
|
||||
ds = new DirectorySecurity(path, aclSections);
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var sid = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null);
|
||||
var account = (NTAccount)sid.Translate(typeof(NTAccount));
|
||||
|
||||
var accessAlreadySet = false;
|
||||
|
||||
foreach (FileSystemAccessRule rule in ds.GetAccessRules(true, true, typeof(NTAccount)))
|
||||
{
|
||||
if (rule.IdentityReference == account &&
|
||||
rule.FileSystemRights.HasFlag(FileSystemRights.Modify) &&
|
||||
rule.AccessControlType == AccessControlType.Allow)
|
||||
{
|
||||
accessAlreadySet = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!accessAlreadySet)
|
||||
{
|
||||
ds.AddAccessRule(new FileSystemAccessRule(account, FileSystemRights.Modify, AccessControlType.Allow));
|
||||
if (File.Exists(path))
|
||||
{
|
||||
new FileInfo(path).SetAccessControl((FileSecurity)ds);
|
||||
}
|
||||
else if (Directory.Exists(path))
|
||||
{
|
||||
new DirectoryInfo(path).SetAccessControl((DirectorySecurity)ds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowTransferComplete()
|
||||
{
|
||||
// Prevent multiple dialogs from popping up.
|
||||
if (_result is null)
|
||||
{
|
||||
_result = System.Windows.MessageBox.Show("File transfer complete. Show folder?",
|
||||
"Transfer Complete",
|
||||
MessageBoxButton.YesNo,
|
||||
MessageBoxImage.Question,
|
||||
MessageBoxResult.Yes,
|
||||
MessageBoxOptions.ServiceNotification);
|
||||
|
||||
if (_result == MessageBoxResult.Yes)
|
||||
{
|
||||
Process.Start("explorer.exe", GetBaseDirectory());
|
||||
}
|
||||
|
||||
_result = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue