Пример #1
0
        public static Result CreateSubDirectoryFileSystem(out ReferenceCountedDisposable <IFileSystem> subDirFileSystem,
                                                          ref ReferenceCountedDisposable <IFileSystem> baseFileSystem, U8Span subPath, bool preserveUnc = false)
        {
            UnsafeHelpers.SkipParamInit(out subDirFileSystem);

            // Check if the directory exists
            Result rc = baseFileSystem.Target.OpenDirectory(out IDirectory dir, subPath, OpenDirectoryMode.Directory);

            if (rc.IsFailure())
            {
                return(rc);
            }

            dir.Dispose();

            var fs = new SubdirectoryFileSystem(ref baseFileSystem, preserveUnc);

            using (var subDirFs = new ReferenceCountedDisposable <SubdirectoryFileSystem>(fs))
            {
                rc = subDirFs.Target.Initialize(subPath);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                subDirFileSystem = subDirFs.AddReference <IFileSystem>();
                return(Result.Success);
            }
        }
Пример #2
0
        public static Result GetAndClearPatrolReadAllocateBufferCount(this StorageService service,
                                                                      out long successCount, out long failureCount)
        {
            UnsafeHelpers.SkipParamInit(out successCount, out failureCount);

            ReferenceCountedDisposable <IStorageDeviceOperator> mmcOperator = null;

            try
            {
                Result rc = service.GetMmcManagerOperator(out mmcOperator);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                int       operationId        = MakeOperationId(MmcManagerOperationIdValue.GetAndClearPatrolReadAllocateBufferCount);
                OutBuffer successCountBuffer = OutBuffer.FromStruct(ref successCount);
                OutBuffer failureCountBuffer = OutBuffer.FromStruct(ref failureCount);

                return(mmcOperator.Target.OperateOut2(out _, successCountBuffer, out _, failureCountBuffer,
                                                      operationId));
            }
            finally
            {
                mmcOperator?.Dispose();
            }
        }
Пример #3
0
 public MemoryMappedInfo(ReferenceCountedDisposable <MemoryMappedFile> memoryMappedFile, string name, long offset, long size)
 {
     _memoryMappedFile = memoryMappedFile;
     Name   = name;
     Offset = offset;
     Size   = size;
 }
Пример #4
0
        public Result OpenAccessFailureDetectionEventNotifier(out ReferenceCountedDisposable <IEventNotifier> notifier,
                                                              ulong processId, bool notifyOnDeepRetry)
        {
            UnsafeHelpers.SkipParamInit(out notifier);

            Result rc = GetProgramInfo(out ProgramInfo programInfo);

            if (rc.IsFailure())
            {
                return(rc);
            }

            if (!programInfo.AccessControl.CanCall(OperationType.OpenAccessFailureDetectionEventNotifier))
            {
                return(ResultFs.PermissionDenied.Log());
            }

            rc = _serviceImpl.CreateNotifier(out IEventNotifier tempNotifier, processId, notifyOnDeepRetry);
            if (rc.IsFailure())
            {
                return(rc);
            }

            notifier = new ReferenceCountedDisposable <IEventNotifier>(tempNotifier);
            return(Result.Success);
        }
 public FileInterfaceAdapter(IFile baseFile,
                             ref ReferenceCountedDisposable <FileSystemInterfaceAdapter> parentFileSystem)
 {
     BaseFile         = baseFile;
     ParentFs         = parentFileSystem;
     parentFileSystem = null;
 }
        /// <summary>
        /// Initializes a new <see cref="FileSystemInterfaceAdapter"/> cast to an <see cref="IFileSystemSf"/>
        /// by moving the input file system object. Avoids allocations from incrementing and then decrementing the ref-count.
        /// </summary>
        /// <param name="baseFileSystem">The base file system. Will be null upon returning.</param>
        /// <param name="isHostFsRoot">Does the base file system come from the root directory of a host file system?</param>
        public static ReferenceCountedDisposable <IFileSystemSf> CreateShared(
            ref ReferenceCountedDisposable <IFileSystem> baseFileSystem, bool isHostFsRoot = false)
        {
            var adapter = new FileSystemInterfaceAdapter(ref baseFileSystem, isHostFsRoot);

            return(ReferenceCountedDisposable <IFileSystemSf> .Create(adapter, out adapter._selfReference));
        }
Пример #7
0
 public MultiCommitManager(
     ref ReferenceCountedDisposable <ISaveDataMultiCommitCoreInterface> multiCommitInterface,
     HorizonClient client)
 {
     Hos = client;
     MultiCommitInterface = Shared.Move(ref multiCommitInterface);
 }
Пример #8
0
        public static Result GetRightsId(this FileSystemClient fs, out FsRightsId rightsId, ProgramId programId,
                                         StorageId storageId)
        {
            using ReferenceCountedDisposable <IFileSystemProxy> fsProxy = fs.Impl.GetFileSystemProxyServiceObject();

            return(fsProxy.Target.GetRightsId(out rightsId, programId, storageId));
        }
Пример #9
0
        public UniqueLockWithPin(ref UniqueLockSemaphore semaphore, ref ReferenceCountedDisposable <T> pinnedObject)
        {
            Shared.Move(out _semaphore, ref semaphore);
            Shared.Move(out _pinnedObject, ref pinnedObject);

            Assert.True(_semaphore.IsLocked);
        }
        public Result OpenBaseFileSystem(out ReferenceCountedDisposable <IFileSystemSf> fileSystem,
                                         BaseFileSystemId fileSystemId)
        {
            UnsafeHelpers.SkipParamInit(out fileSystem);

            Result rc = CheckCapabilityById(fileSystemId, _processId);

            if (rc.IsFailure())
            {
                return(rc);
            }

            ReferenceCountedDisposable <IFileSystem> fs = null;

            try
            {
                // Open the file system
                rc = _serviceImpl.OpenBaseFileSystem(out fs, fileSystemId);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                // Create an SF adapter for the file system
                fileSystem = FileSystemInterfaceAdapter.CreateShared(ref fs);

                return(Result.Success);
            }
            finally
            {
                fs?.Dispose();
            }
        }
        public Result Create(out ReferenceCountedDisposable <IFileSystem> subDirFileSystem,
                             ref ReferenceCountedDisposable <IFileSystem> baseFileSystem, U8Span path, bool preserveUnc)
        {
            UnsafeHelpers.SkipParamInit(out subDirFileSystem);

            // Verify the sub-path exists
            Result rc = baseFileSystem.Target.OpenDirectory(out IDirectory _, path, OpenDirectoryMode.Directory);

            if (rc.IsFailure())
            {
                return(rc);
            }

            // Initialize the SubdirectoryFileSystem
            var subDir = new SubdirectoryFileSystem(ref baseFileSystem, preserveUnc);

            using var subDirShared = new ReferenceCountedDisposable <SubdirectoryFileSystem>(subDir);

            rc = subDirShared.Target.Initialize(path);
            if (rc.IsFailure())
            {
                return(rc);
            }

            subDirFileSystem = subDirShared.AddReference <IFileSystem>();
            return(Result.Success);
        }
Пример #12
0
            static Result Mount(FileSystemClientImpl fs, U8Span mountName, BisPartitionId partitionId)
            {
                Result rc = fs.CheckMountNameAcceptingReservedMountName(mountName);

                if (rc.IsFailure())
                {
                    return(rc);
                }

                using ReferenceCountedDisposable <IFileSystemProxy> fsProxy = fs.GetFileSystemProxyServiceObject();

                // Nintendo doesn't use the provided rootPath
                FspPath.CreateEmpty(out FspPath sfPath);

                ReferenceCountedDisposable <IFileSystemSf> fileSystem = null;

                try
                {
                    rc = fsProxy.Target.OpenBisFileSystem(out fileSystem, in sfPath, partitionId);
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }

                    var nameGenerator     = new BisCommonMountNameGenerator(partitionId);
                    var fileSystemAdapter = new FileSystemServiceObjectAdapter(fileSystem);

                    return(fs.Fs.Register(mountName, fileSystemAdapter, nameGenerator));
                }
                finally
                {
                    fileSystem?.Dispose();
                }
            }
        private void LocationServiceStorageLocationChanging(object sender, PersistentStorageLocationChangingEventArgs e)
        {
            ReferenceCountedDisposable <IPersistentStorage> storage = null;

            lock (_lock)
            {
                if (e.SolutionId != _currentPersistentStorageSolutionId)
                {
                    return;
                }

                // We will transfer ownership in a thread-safe way out so we can dispose outside the lock
                storage = _currentPersistentStorage;
                _currentPersistentStorage           = null;
                _currentPersistentStorageSolutionId = null;
            }

            if (storage != null)
            {
                if (e.MustUseNewStorageLocationImmediately)
                {
                    // Dispose storage outside of the lock. Note this only removes our reference count; clients who are still
                    // using this will still be holding a reference count.
                    storage.Dispose();
                }
                else
                {
                    // make it to shutdown asynchronously
                    Task.Run(() => storage.Dispose());
                }
            }
        }
Пример #14
0
        public static Result WrapSubDirectory(out ReferenceCountedDisposable <IFileSystem> fileSystem,
                                              ref ReferenceCountedDisposable <IFileSystem> baseFileSystem, U8Span path, bool createIfMissing)
        {
            UnsafeHelpers.SkipParamInit(out fileSystem);

            // The path must already exist if we're not automatically creating it
            if (!createIfMissing)
            {
                Result result = baseFileSystem.Target.GetEntryType(out _, path);
                if (result.IsFailure())
                {
                    return(result);
                }
            }

            // Ensure the path exists or check if it's a directory
            Result rc = EnsureDirectory(baseFileSystem.Target, path);

            if (rc.IsFailure())
            {
                return(rc);
            }

            return(CreateSubDirectoryFileSystem(out fileSystem, ref baseFileSystem, path));
        }
Пример #15
0
        public void TestWeakReferenceLifetime()
        {
            var target = new DisposableObject();

            var reference     = new ReferenceCountedDisposable <DisposableObject>(target);
            var weakReference = new ReferenceCountedDisposable <DisposableObject> .WeakReference(reference);

            var reference2 = reference.TryAddReference();

            Assert.NotNull(reference2);

            reference.Dispose();

            // TryAddReference fails after dispose for a counted reference
            Assert.Null(reference.TryAddReference());
            Assert.NotNull(reference2.Target);
            Assert.False(target.IsDisposed);

            // However, a WeakReference created from the disposed reference can still add a reference
            var reference3 = weakReference.TryAddReference();

            Assert.NotNull(reference3);

            reference2.Dispose();
            Assert.False(target.IsDisposed);

            reference3.Dispose();
            Assert.True(target.IsDisposed);
        }
        public void Register(ReferenceCountedDisposable <DirectorySaveDataFileSystem> fileSystem)
        {
            if (_maxCachedFileSystemCount <= 0)
            {
                return;
            }

            Assert.SdkRequiresGreaterEqual(_nextCacheIndex, 0);
            Assert.SdkRequiresGreater(_maxCachedFileSystemCount, _nextCacheIndex);

            if (fileSystem.Target.GetSaveDataSpaceId() == SaveDataSpaceId.SdSystem)
            {
                return;
            }

            Result rc = fileSystem.Target.Rollback();

            if (rc.IsFailure())
            {
                return;
            }

            using ScopedLock <SdkRecursiveMutexType> scopedLock = ScopedLock.Lock(ref _mutex);

            _cachedFileSystems[_nextCacheIndex].Register(fileSystem.AddReference <IFileSystem>(),
                                                         fileSystem.Target.GetSaveDataSpaceId(), fileSystem.Target.GetSaveDataId());

            _nextCacheIndex = (_nextCacheIndex + 1) % _maxCachedFileSystemCount;
        }
 /// <summary>
 /// Initializes a new <see cref="FileSystemInterfaceAdapter"/> by moving the file system object.
 /// Avoids allocations from incrementing and then decrementing the ref-count.
 /// </summary>
 /// <param name="fileSystem">The base file system. Will be null upon returning.</param>
 /// <param name="isHostFsRoot">Does the base file system come from the root directory of a host file system?</param>
 private FileSystemInterfaceAdapter(ref ReferenceCountedDisposable <IFileSystem> fileSystem,
                                    bool isHostFsRoot = false)
 {
     BaseFileSystem = fileSystem;
     fileSystem     = null;
     IsHostFsRoot   = isHostFsRoot;
 }
Пример #18
0
            static Result Mount(FileSystemClient fs, U8Span mountName, GameCardHandle handle,
                                GameCardPartition partitionId)
            {
                Result rc = fs.Impl.CheckMountNameAcceptingReservedMountName(mountName);

                if (rc.IsFailure())
                {
                    return(rc);
                }

                using ReferenceCountedDisposable <IFileSystemProxy> fsProxy = fs.Impl.GetFileSystemProxyServiceObject();

                ReferenceCountedDisposable <IFileSystemSf> fileSystem = null;

                try
                {
                    rc = fsProxy.Target.OpenGameCardFileSystem(out fileSystem, handle, partitionId);
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }

                    var fileSystemAdapter  = new FileSystemServiceObjectAdapter(fileSystem);
                    var mountNameGenerator = new GameCardCommonMountNameGenerator(handle, partitionId);
                    return(fs.Register(mountName, fileSystemAdapter, mountNameGenerator));
                }
                finally
                {
                    fileSystem?.Dispose();
                }
            }
Пример #19
0
        /// <summary>
        /// Commits all added file systems.
        /// </summary>
        /// <returns>The <see cref="Result"/> of the operation.</returns>
        public Result Commit()
        {
            lock (Locker)
            {
                Result rc = EnsureSaveDataForContext();
                if (rc.IsFailure())
                {
                    return(rc);
                }

                ReferenceCountedDisposable <IFileSystem> contextFs = null;
                try
                {
                    rc = MultiCommitInterface.Target.OpenMultiCommitContext(out contextFs);
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }

                    return(Commit(contextFs.Target));
                }
                finally
                {
                    contextFs?.Dispose();
                }
            }
        }
Пример #20
0
        public static Result GetGameCardHandle(this FileSystemClient fs, out GameCardHandle handle)
        {
            UnsafeHelpers.SkipParamInit(out handle);

            using ReferenceCountedDisposable <IFileSystemProxy> fsProxy = fs.Impl.GetFileSystemProxyServiceObject();

            ReferenceCountedDisposable <IDeviceOperator> deviceOperator = null;

            try
            {
                Result rc = fsProxy.Target.OpenDeviceOperator(out deviceOperator);
                fs.Impl.AbortIfNeeded(rc);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                rc = deviceOperator.Target.GetGameCardHandle(out handle);
                fs.Impl.AbortIfNeeded(rc);
                return(rc);
            }
            finally
            {
                deviceOperator?.Dispose();
            }
        }
        protected override void Dispose(bool disposing)
        {
            if (_baseFileSystem is null)
            {
                return;
            }

            if (disposing)
            {
                if (typeof(T) == typeof(SaveDataFileSystem))
                {
                    _cacheManager.Register(
                        (ReferenceCountedDisposable <SaveDataFileSystem>)(object) _baseFileSystem);
                }
                else if (typeof(T) == typeof(ApplicationTemporaryFileSystem))
                {
                    _cacheManager.Register(
                        (ReferenceCountedDisposable <ApplicationTemporaryFileSystem>)(object) _baseFileSystem);
                }
                else if (typeof(T) == typeof(DirectorySaveDataFileSystem))
                {
                    _cacheManager.Register(
                        (ReferenceCountedDisposable <DirectorySaveDataFileSystem>)(object) _baseFileSystem);
                }

                _baseFileSystem.Dispose();
                _baseFileSystem = null;
            }

            base.Dispose(disposing);
        }
Пример #22
0
        public static ReferenceCountedDisposable <IFileSystem> CreateShared(
            ref ReferenceCountedDisposable <IFileSystem> baseFileSystem)
        {
            var resultConvertFileSystem = new SaveDataResultConvertFileSystem(ref baseFileSystem);

            return(new ReferenceCountedDisposable <IFileSystem>(resultConvertFileSystem));
        }
Пример #23
0
            /// <summary>
            /// Caller is responsible for disposing the returned stream.
            /// multiple call of this will not increase VM.
            /// </summary>
            public Stream CreateReadableStream()
            {
                // Note: TryAddReference behaves according to its documentation even if the target object has been
                // disposed. If it returns non-null, then the object will not be disposed before the returned
                // reference is disposed (see comments on _memoryMappedFile and TryAddReference).
                var streamAccessor = _weakReadAccessor.TryAddReference();

                if (streamAccessor == null)
                {
                    var rawAccessor = RunWithCompactingGCFallback(
                        info =>
                        info._memoryMappedFile.Target.CreateViewAccessor(
                            info.Offset,
                            info.Size,
                            MemoryMappedFileAccess.Read
                            ),
                        this
                        );
                    streamAccessor = new ReferenceCountedDisposable <MemoryMappedViewAccessor>(
                        rawAccessor
                        );
                    _weakReadAccessor =
                        new ReferenceCountedDisposable <MemoryMappedViewAccessor> .WeakReference(
                            streamAccessor
                            );
                }

                Debug.Assert(streamAccessor.Target.CanRead);
                return(new SharedReadableStream(streamAccessor, Size));
            }
Пример #24
0
        public static ReferenceCountedDisposable <ISaveDataExtraDataAccessor> CreateShared(
            ref ReferenceCountedDisposable <ISaveDataExtraDataAccessor> accessor)
        {
            var resultConvertAccessor = new SaveDataExtraDataResultConvertAccessor(ref accessor);

            return(new ReferenceCountedDisposable <ISaveDataExtraDataAccessor>(resultConvertAccessor));
        }
Пример #25
0
        public static Result GetAndClearMmcErrorInfo(this StorageService service, out StorageErrorInfo errorInfo,
                                                     out long logSize, Span <byte> logBuffer)
        {
            UnsafeHelpers.SkipParamInit(out errorInfo, out logSize);

            ReferenceCountedDisposable <IStorageDeviceOperator> mmcOperator = null;

            try
            {
                Result rc = service.GetMmcManagerOperator(out mmcOperator);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                int       operationId        = MakeOperationId(MmcManagerOperationIdValue.GetAndClearErrorInfo);
                var       logOutBuffer       = new OutBuffer(logBuffer);
                OutBuffer errorInfoOutBuffer = OutBuffer.FromStruct(ref errorInfo);

                return(mmcOperator.Target.OperateOut2(out _, errorInfoOutBuffer, out logSize, logOutBuffer,
                                                      operationId));
            }
            finally
            {
                mmcOperator?.Dispose();
            }
        }
        public static ReferenceCountedDisposable <IStorageSf> CreateShared(
            ref ReferenceCountedDisposable <IStorage> baseStorage)
        {
            var adapter = new StorageInterfaceAdapter(ref baseStorage);

            return(new ReferenceCountedDisposable <IStorageSf>(adapter));
        }
Пример #27
0
 protected OpenCountFileSystem(ref ReferenceCountedDisposable <IFileSystem> baseFileSystem,
                               ref ReferenceCountedDisposable <IEntryOpenCountSemaphoreManager> entryCountSemaphore,
                               ref IUniqueLock mountCountSemaphore) : base(ref baseFileSystem)
 {
     Shared.Move(out _entryCountSemaphore, ref entryCountSemaphore);
     Shared.Move(out _mountCountSemaphore, ref mountCountSemaphore);
 }
        public IReferenceCountedDisposable <IRuleSetFile> GetOrCreateRuleSet(string ruleSetFileFullPath)
        {
            ReferenceCountedDisposable <RuleSetFile> disposable = null;

            lock (_gate)
            {
                // If we already have one in the map to hand out, great
                if (_ruleSetFileMap.TryGetValue(ruleSetFileFullPath, out var weakReference))
                {
                    disposable = weakReference.TryAddReference();
                }

                if (disposable == null)
                {
                    // We didn't easily get a disposable, so one of two things is the case:
                    //
                    // 1. We have no entry in _ruleSetFileMap at all for this.
                    // 2. We had an entry, but it was disposed and is no longer valid.

                    // In either case, we'll create a new rule set file and add it to the map.
                    disposable = new ReferenceCountedDisposable <RuleSetFile>(new RuleSetFile(ruleSetFileFullPath, this));
                    _ruleSetFileMap[ruleSetFileFullPath] = new ReferenceCountedDisposable <RuleSetFile> .WeakReference(disposable);
                }
            }

            // Call InitializeFileTracking outside the lock, so we don't have requests for other files blocking behind the initialization of this one.
            // RuleSetFile itself will ensure InitializeFileTracking is locked as appropriate.
            disposable.Target.InitializeFileTracking(_fileChangeWatcher);

            return(disposable);
        }
Пример #29
0
            private async IAsyncEnumerable <SuggestedActionSet> GetCodeFixesAndRefactoringsAsync(
                ReferenceCountedDisposable <State> state,
                ISuggestedActionCategorySet requestedActionCategories,
                Document document,
                SnapshotSpan range,
                TextSpan?selection,
                Func <string, IDisposable?> addOperationScope,
                CodeActionRequestPriority priority,
                int currentActionCount,
                [EnumeratorCancellation] CancellationToken cancellationToken)
            {
                var workspace = document.Project.Solution.Workspace;
                var supportsFeatureService = workspace.Services.GetRequiredService <ITextBufferSupportsFeatureService>();

                var fixesTask = GetCodeFixesAsync(
                    state, supportsFeatureService, requestedActionCategories, workspace, document, range,
                    addOperationScope, priority, isBlocking: false, cancellationToken);
                var refactoringsTask = GetRefactoringsAsync(
                    state, supportsFeatureService, requestedActionCategories, GlobalOptions, workspace, document, selection,
                    addOperationScope, priority, isBlocking: false, cancellationToken);

                await Task.WhenAll(fixesTask, refactoringsTask).ConfigureAwait(false);

                var fixes = await fixesTask.ConfigureAwait(false);

                var refactorings = await refactoringsTask.ConfigureAwait(false);

                foreach (var set in ConvertToSuggestedActionSets(state, selection, fixes, refactorings, currentActionCount))
                {
                    yield return(set);
                }
            }
Пример #30
0
            static Result OpenFileSystem(FileSystemClient fs, ReferenceCountedDisposable <IFileSystemProxy> fsProxy,
                                         out ReferenceCountedDisposable <IFileSystemSf> fileSystem)
            {
                UnsafeHelpers.SkipParamInit(out fileSystem);

                // Retry a few times if the storage device isn't ready yet
                const int maxRetries    = 10;
                const int retryInterval = 1000;

                for (int i = 0; i < maxRetries; i++)
                {
                    Result rc = fsProxy.Target.OpenSdCardFileSystem(out fileSystem);

                    if (rc.IsSuccess())
                    {
                        break;
                    }

                    if (!ResultFs.StorageDeviceNotReady.Includes(rc))
                    {
                        return(rc);
                    }

                    if (i == maxRetries - 1)
                    {
                        return(rc);
                    }

                    fs.Hos.Os.SleepThread(TimeSpan.FromMilliSeconds(retryInterval));
                }

                return(Result.Success);
            }