private HRESULT ProcessPlaceholderRequest( PRJ_CALLBACK_DATA callbackData ) { return(_asyncOperations.ProcessCommandPossibleAsync( callbackData.NamespaceVirtualizationContext, callbackData.CommandId, cts => FileSystem.GetPlaceholder( callbackData.FilePathName, s => _outboundFunctions.PrjFileNameMatch(s, callbackData.FilePathName), cts.Token), placeholder => { if (placeholder == null) { return HRESULT.ERROR_FILE_NOT_FOUND; } using (var buffer = LevelShifter.PRJ_PLACEHOLDER_INFOFromPlaceholderInfo(placeholder)) { var result = _outboundFunctions.PrjWritePlaceholderInfo(callbackData.NamespaceVirtualizationContext, placeholder.DestinationFileName, buffer.Buffer, buffer.Sizes.totalSize); return result; } } )); }
private HRESULT ProcessStartEnumeration( PRJ_CALLBACK_DATA callbackData, Guid enumerationId ) { try { var cts = new CancellationTokenSource(); var ongoing = new OngoingEnumeration { Path = callbackData.FilePathName, VersionInfo = LevelShifter.PlaceholderVersionFromPRJ_PLACEHOLDER_VERSION_INFO(callbackData.VersionInfo), State = EnumerationState.Init }; if (!_inFlightEnumerations.TryAdd(enumerationId, ongoing)) { cts.Cancel(); return(HRESULT.E_INVALIDARG); } return(HRESULT.S_OK); } catch (Exception) { return(HRESULT.E_INVALIDARG); } }
internal HRESULT ProcessDataRequest( PRJ_CALLBACK_DATA callbackData, ulong byteOffset, uint length ) { var weirdnessOffset = byteOffset % (ulong)_virtualizationInfo.WriteAlignment; byteOffset -= weirdnessOffset; length += (uint)weirdnessOffset; var stream = new FileWriteStream(byteOffset, _virtualizationInfo.WriteAlignment, callbackData.NamespaceVirtualizationContext, callbackData.DataStreamId, _outboundFunctions); return(_asyncOperations.ProcessCommandPossibleAsync( callbackData.NamespaceVirtualizationContext, callbackData.CommandId, cts => FileSystem.GetFileData( callbackData.FilePathName, LevelShifter.PlaceholderVersionFromPRJ_PLACEHOLDER_VERSION_INFO(callbackData.VersionInfo), (long)byteOffset, (int)length, stream).ContinueWith(t => { stream.Close(); }))); }
private HRESULT ProcessEnumerationStep( PRJ_CALLBACK_DATA callbackData, Guid enumerationId, String searchExpression, IntPtr dirEntryBufferHandle ) { if (!_inFlightEnumerations.TryGetValue(enumerationId, out var ongoing)) { return(HRESULT.E_INVALIDARG); } InitializeEnumeration(callbackData, ongoing); if (ongoing.State == EnumerationState.CurrentPending) { if (!SendCurrentEnumeratorValue(ongoing, dirEntryBufferHandle)) { return(HRESULT.ERROR_INSUFFICIENT_BUFFER); } ongoing.State = EnumerationState.Ongoing; } else { ongoing.State = EnumerationState.NotOneSent; } var mnTask = ongoing.Enumerator.MoveNextAsync(); while (true) { if (mnTask.IsCompleted) { if (!mnTask.Result) { return(HRESULT.S_OK); } if (SendCurrentEnumeratorValue(ongoing, dirEntryBufferHandle)) { ongoing.State = EnumerationState.Ongoing; mnTask = ongoing.Enumerator.MoveNextAsync(); continue; } else { var returnSync = ongoing.State == EnumerationState.NotOneSent ? HRESULT.ERROR_INSUFFICIENT_BUFFER : HRESULT.S_OK; ongoing.State = EnumerationState.CurrentPending; return(returnSync); } } var cts = _asyncOperations.GetCancellationTokenForCommand(callbackData.CommandId); cts.Token.Register(ongoing.CancellationForEnumeration.Cancel); mnTask.AsTask().ContinueWith(answer => ContinueEnumerationAsync(callbackData.NamespaceVirtualizationContext, answer.Result, ongoing, dirEntryBufferHandle, callbackData.CommandId), TaskContinuationOptions.RunContinuationsAsynchronously); return(HRESULT.ERROR_IO_PENDING); } }
public async Task QuickEnumeration_SmallBuffer_MultiFile_Successful() { //Arrange const string RootPath = @"D:\"; var functions = new Mock <Functions>(); var nsVirtualizationContext = (IntPtr)4; var instanceGuid = Guid.NewGuid(); var tcsStarted = new TaskCompletionSource <IntPtr>(); var enumerationId = Guid.NewGuid(); var callbackData = new PRJ_CALLBACK_DATA { VersionInfo = new PRJ_PLACEHOLDER_VERSION_INFO() }; var dirBuffer1 = (IntPtr)99; var dirBuffer2 = (IntPtr)713; functions.Setup(f => f.PrjStartVirtualizing(RootPath, It.IsAny <IntPtr>(), IntPtr.Zero, It.IsAny <PRJ_STARTVIRTUALIZING_OPTIONS>(), out It.Ref <IntPtr> .IsAny)) .Callback(new StartVirtualizingCallback((String virtualizationRootPath, IntPtr callbacks, IntPtr instanceContext, PRJ_STARTVIRTUALIZING_OPTIONS options, out IntPtr namespaceVirtualizationContext) => { tcsStarted.SetResult(callbacks); namespaceVirtualizationContext = nsVirtualizationContext; }) ).Returns(() => HRESULT.S_OK); functions.Setup(f => f.PrjFileNameMatch(It.IsAny <string>(), null)).Returns(true); functions.SetupSequence(f => f.PrjFillDirEntryBuffer("Boris.txt", It.IsAny <PRJ_FILE_BASIC_INFO>(), dirBuffer1)) .Returns(HRESULT.S_OK) .Returns(HRESULT.ERROR_INSUFFICIENT_BUFFER) .Returns(HRESULT.S_OK); ConfigureVirtualizationInfo(functions, nsVirtualizationContext, instanceGuid); var runnable = new RunnableInstance("Boris", RootPath, instanceGuid, new InstanceOptions(), functions.Object); var fs = TestableFileSystem.MultiFile(); //Act using (var running = runnable.Start(fs)) { var callbacks = NativeBuffer <PRJ_CALLBACKS> .Recover(await tcsStarted.Task); var hr = callbacks.StartDirectoryEnumerationCallback(callbackData, enumerationId); Assert.Equal(HRESULT.S_OK, hr); hr = callbacks.GetDirectoryEnumerationCallback(callbackData, enumerationId, null, dirBuffer1); Assert.Equal(HRESULT.S_OK, hr); hr = callbacks.GetDirectoryEnumerationCallback(callbackData, enumerationId, null, dirBuffer2); Assert.Equal(HRESULT.S_OK, hr); hr = callbacks.EndDirectoryEnumerationCallback(callbackData, enumerationId); Assert.Equal(HRESULT.S_OK, hr); //Assert functions.VerifyAll(); } }
private HRESULT ProcessNotification( PRJ_CALLBACK_DATA callbackData, bool isDirectory, PRJ_NOTIFICATION notification, String destinationFileName, ref PRJ_NOTIFICATION_PARAMETERS operationParameters ) { switch (notification) { case PRJ_NOTIFICATION.PRJ_NOTIFICATION_FILE_OPENED: return(_asyncOperations.ProcessCommandPossibleAsyncWithNotificationMask(callbackData.NamespaceVirtualizationContext, callbackData.CommandId, cts => Notifiable.FileOpened(callbackData.FilePathName, isDirectory, cts.Token), operationParameters)); case PRJ_NOTIFICATION.PRJ_NOTIFICATION_NEW_FILE_CREATED: return(_asyncOperations.ProcessCommandPossibleAsyncWithNotificationMask(callbackData.NamespaceVirtualizationContext, callbackData.CommandId, cts => Notifiable.FileCreated(callbackData.FilePathName, isDirectory, cts.Token), operationParameters)); case PRJ_NOTIFICATION.PRJ_NOTIFICATION_FILE_OVERWRITTEN: return(_asyncOperations.ProcessCommandPossibleAsyncWithNotificationMask(callbackData.NamespaceVirtualizationContext, callbackData.CommandId, cts => Notifiable.FileOverwritten(callbackData.FilePathName, isDirectory, cts.Token), operationParameters)); case PRJ_NOTIFICATION.PRJ_NOTIFICATION_PRE_DELETE: return(_asyncOperations.ProcessCommandPossibleAsync(callbackData.NamespaceVirtualizationContext, callbackData.CommandId, cts => Notifiable.PreDelete(callbackData.FilePathName, isDirectory, cts.Token), b => b ? HRESULT.S_OK : HRESULT.E_INVALIDARG)); case PRJ_NOTIFICATION.PRJ_NOTIFICATION_PRE_RENAME: return(_asyncOperations.ProcessCommandPossibleAsync(callbackData.NamespaceVirtualizationContext, callbackData.CommandId, cts => Notifiable.PreRename(callbackData.FilePathName, destinationFileName, isDirectory, cts.Token), b => b ? HRESULT.S_OK : HRESULT.E_INVALIDARG)); case PRJ_NOTIFICATION.PRJ_NOTIFICATION_PRE_SET_HARDLINK: return(_asyncOperations.ProcessCommandPossibleAsync(callbackData.NamespaceVirtualizationContext, callbackData.CommandId, cts => Notifiable.PreHardlink(callbackData.FilePathName, destinationFileName, isDirectory, cts.Token), b => b ? HRESULT.S_OK : HRESULT.E_INVALIDARG)); case PRJ_NOTIFICATION.PRJ_NOTIFICATION_FILE_RENAMED: return(_asyncOperations.ProcessCommandPossibleAsyncWithNotificationMask(callbackData.NamespaceVirtualizationContext, callbackData.CommandId, cts => Notifiable.FileRenamed(callbackData.FilePathName, destinationFileName, isDirectory, cts.Token), operationParameters)); case PRJ_NOTIFICATION.PRJ_NOTIFICATION_HARDLINK_CREATED: return(_asyncOperations.ProcessCommandPossibleAsync(callbackData.NamespaceVirtualizationContext, callbackData.CommandId, cts => Notifiable.FileHardlinked(callbackData.FilePathName, destinationFileName, isDirectory, cts.Token))); case PRJ_NOTIFICATION.PRJ_NOTIFICATION_FILE_HANDLE_CLOSED_NO_MODIFICATION: return(_asyncOperations.ProcessCommandPossibleAsync(callbackData.NamespaceVirtualizationContext, callbackData.CommandId, cts => Notifiable.FileClosed(callbackData.FilePathName, isDirectory, CloseState.Unmodified, cts.Token))); case PRJ_NOTIFICATION.PRJ_NOTIFICATION_FILE_HANDLE_CLOSED_FILE_MODIFIED: return(_asyncOperations.ProcessCommandPossibleAsync(callbackData.NamespaceVirtualizationContext, callbackData.CommandId, cts => Notifiable.FileClosed(callbackData.FilePathName, isDirectory, CloseState.Modified, cts.Token))); case PRJ_NOTIFICATION.PRJ_NOTIFICATION_FILE_HANDLE_CLOSED_FILE_DELETED: CloseState state = operationParameters.IsFileModified ? CloseState.Modified | CloseState.Deleted : CloseState.Deleted; return(_asyncOperations.ProcessCommandPossibleAsync(callbackData.NamespaceVirtualizationContext, callbackData.CommandId, cts => Notifiable.FileClosed(callbackData.FilePathName, isDirectory, state, cts.Token))); case PRJ_NOTIFICATION.PRJ_NOTIFICATION_FILE_PRE_CONVERT_TO_FULL: return(_asyncOperations.ProcessCommandPossibleAsync(callbackData.NamespaceVirtualizationContext, callbackData.CommandId, cts => Notifiable.PreConvertToFull(callbackData.FilePathName, isDirectory, cts.Token))); } return(HRESULT.E_INVALIDARG); }
private HRESULT ProcessEndEnumeration( PRJ_CALLBACK_DATA callbackData, Guid enumerationId ) { if (!_inFlightEnumerations.TryRemove(enumerationId, out var ongoing)) { return(HRESULT.E_INVALIDARG); } return(_asyncOperations.ProcessCommandPossibleAsync(callbackData.NamespaceVirtualizationContext, callbackData.CommandId, cts => { ongoing.CancellationForEnumeration.Cancel(); return ongoing.Enumerator.DisposeAsync(); })); }
private HRESULT ProcessQueryFileName( PRJ_CALLBACK_DATA callbackData ) { return(_asyncOperations.ProcessCommandPossibleAsync( callbackData.NamespaceVirtualizationContext, callbackData.CommandId, cts => { return Seekable.FileExists( callbackData.FilePathName, fileName => _outboundFunctions.PrjFileNameCompare(fileName, callbackData.FilePathName) == 0, cts.Token); }, answer => answer ? HRESULT.S_OK : HRESULT.ERROR_FILE_NOT_FOUND )); }
private void InitializeEnumeration(PRJ_CALLBACK_DATA callbackData, OngoingEnumeration ongoing) { if ((callbackData.Flags & PRJ_CALLBACK_DATA_FLAGS.PRJ_CB_DATA_FLAG_ENUM_RESTART_SCAN) != 0 || ongoing.State == EnumerationState.Init) { ongoing.MatchPattern = callbackData.FilePathName; if (ongoing.CancellationForEnumeration != null) { ongoing.CancellationForEnumeration.Cancel(); } ongoing.CancellationForEnumeration = new CancellationTokenSource(); ongoing.Enumerator = FileSystem.FindContent( ongoing.Path, ongoing.VersionInfo, s => _outboundFunctions.PrjFileNameMatch(s, ongoing.MatchPattern), new SortComparer(_outboundFunctions), ongoing.CancellationForEnumeration.Token ); ongoing.State = EnumerationState.Ongoing; } }
public void ProcessCancelCommand(PRJ_CALLBACK_DATA callbackData) { _asyncOperations.ProcessCancelCommand(callbackData.CommandId); }