Ejemplo n.º 1
0
        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;
                }
            }
                       ));
        }
Ejemplo n.º 2
0
 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();
            })));
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 7
0
 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
                ));
 }
Ejemplo n.º 9
0
 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);
 }