Copy from ISO

This commit is contained in:
2023-09-04 18:05:01 +02:00
parent a323edafd3
commit 3a29991948
20 changed files with 241 additions and 48 deletions

View File

@@ -100,6 +100,9 @@ public class ContainerSizeSizeScanProvider : ContentProviderBase, IContainerSize
public override VolumeSizeInfo? GetVolumeSizeInfo(FullName path) => null; public override VolumeSizeInfo? GetVolumeSizeInfo(FullName path) => null;
public override ValueTask<NativePath?> GetSupportedPathPart(NativePath nativePath)
=> ValueTask.FromResult<NativePath?>(nativePath);
public ISizeScanTask StartSizeScan(IContainer scanSizeOf) public ISizeScanTask StartSizeScan(IContainer scanSizeOf)
{ {
var searchTask = _serviceProvider var searchTask = _serviceProvider

View File

@@ -22,6 +22,7 @@ namespace FileTime.App.Core.Services.UserCommandHandler;
public class NavigationUserCommandHandlerService : UserCommandHandlerServiceBase public class NavigationUserCommandHandlerService : UserCommandHandlerServiceBase
{ {
private const int PageSize = 8; private const int PageSize = 8;
private readonly IAppState _appState; private readonly IAppState _appState;
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
private readonly ILocalContentProvider _localContentProvider; private readonly ILocalContentProvider _localContentProvider;
@@ -33,6 +34,7 @@ public class NavigationUserCommandHandlerService : UserCommandHandlerServiceBase
private readonly IContentProviderRegistry _contentProviderRegistry; private readonly IContentProviderRegistry _contentProviderRegistry;
private readonly ILogger<NavigationUserCommandHandlerService> _logger; private readonly ILogger<NavigationUserCommandHandlerService> _logger;
private readonly ApplicationConfiguration _applicationConfiguration; private readonly ApplicationConfiguration _applicationConfiguration;
private ITabViewModel? _selectedTab; private ITabViewModel? _selectedTab;
private IDeclarativeProperty<IContainer?>? _currentLocation; private IDeclarativeProperty<IContainer?>? _currentLocation;
private IDeclarativeProperty<IItemViewModel?>? _currentSelectedItem; private IDeclarativeProperty<IItemViewModel?>? _currentSelectedItem;
@@ -147,9 +149,7 @@ public class NavigationUserCommandHandlerService : UserCommandHandlerServiceBase
} }
private async Task GoByFrequency() private async Task GoByFrequency()
{ => await _frequencyNavigationService.OpenNavigationWindow();
await _frequencyNavigationService.OpenNavigationWindow();
}
private async Task GoToPath() private async Task GoToPath()
{ {
@@ -166,6 +166,7 @@ public class NavigationUserCommandHandlerService : UserCommandHandlerServiceBase
} }
catch catch
{ {
// ignored
} }
if (resolvedPath is IContainer container) if (resolvedPath is IContainer container)
@@ -173,10 +174,10 @@ public class NavigationUserCommandHandlerService : UserCommandHandlerServiceBase
await _userCommandHandlerService.HandleCommandAsync( await _userCommandHandlerService.HandleCommandAsync(
new OpenContainerCommand(new AbsolutePath(_timelessContentProvider, container))); new OpenContainerCommand(new AbsolutePath(_timelessContentProvider, container)));
} }
else if (resolvedPath is IElement element) else if (resolvedPath is IElement {Parent: { } parent})
{ {
await _userCommandHandlerService.HandleCommandAsync( await _userCommandHandlerService.HandleCommandAsync(
new OpenContainerCommand(element.Parent!)); new OpenContainerCommand(parent));
} }
else else
{ {
@@ -492,7 +493,10 @@ public class NavigationUserCommandHandlerService : UserCommandHandlerServiceBase
private Task CloseTab() private Task CloseTab()
{ {
if ((!_applicationConfiguration.AllowCloseLastTab && _appState.Tabs.Count < 2) || _selectedTab == null) return Task.CompletedTask; if ((!_applicationConfiguration.AllowCloseLastTab && _appState.Tabs.Count < 2) || _selectedTab == null)
{
return Task.CompletedTask;
}
var tabToRemove = _selectedTab; var tabToRemove = _selectedTab;
_appState.RemoveTab(tabToRemove!); _appState.RemoveTab(tabToRemove!);
@@ -503,6 +507,7 @@ public class NavigationUserCommandHandlerService : UserCommandHandlerServiceBase
} }
catch catch
{ {
// ignored
} }
return Task.CompletedTask; return Task.CompletedTask;

View File

@@ -80,6 +80,7 @@ public class SearchContentProvider : ContentProviderBase, ISearchContentProvider
public override Task<bool> CanHandlePathAsync(NativePath path) => Task.FromResult(path.Path.StartsWith(ContentProviderName)); public override Task<bool> CanHandlePathAsync(NativePath path) => Task.FromResult(path.Path.StartsWith(ContentProviderName));
public override VolumeSizeInfo? GetVolumeSizeInfo(FullName path) => null; public override VolumeSizeInfo? GetVolumeSizeInfo(FullName path) => null;
public override ValueTask<NativePath?> GetSupportedPathPart(NativePath nativePath) => throw new NotImplementedException();
public async Task<ISearchTask> StartSearchAsync(ISearchMatcher matcher, IContainer searchIn) public async Task<ISearchTask> StartSearchAsync(ISearchMatcher matcher, IContainer searchIn)
{ {

View File

@@ -29,4 +29,5 @@ public interface IContentProvider : IContainer, IOnContainerEnter
Task<bool> CanHandlePathAsync(NativePath path); Task<bool> CanHandlePathAsync(NativePath path);
Task<bool> CanHandlePathAsync(FullName path); Task<bool> CanHandlePathAsync(FullName path);
VolumeSizeInfo? GetVolumeSizeInfo(FullName path); VolumeSizeInfo? GetVolumeSizeInfo(FullName path);
ValueTask<NativePath?> GetSupportedPathPart(NativePath nativePath);
} }

View File

@@ -96,4 +96,5 @@ public abstract class ContentProviderBase : IContentProvider
public abstract VolumeSizeInfo? GetVolumeSizeInfo(FullName path); public abstract VolumeSizeInfo? GetVolumeSizeInfo(FullName path);
public IItem WithParent(AbsolutePath parent) => this; public IItem WithParent(AbsolutePath parent) => this;
public abstract ValueTask<NativePath?> GetSupportedPathPart(NativePath nativePath);
} }

View File

@@ -86,6 +86,7 @@ public class RootContentProvider : IRootContentProvider
public Task<bool> CanHandlePathAsync(FullName path) => throw new NotImplementedException(); public Task<bool> CanHandlePathAsync(FullName path) => throw new NotImplementedException();
public VolumeSizeInfo? GetVolumeSizeInfo(FullName path) => null; public VolumeSizeInfo? GetVolumeSizeInfo(FullName path) => null;
public ValueTask<NativePath?> GetSupportedPathPart(NativePath nativePath) => throw new NotImplementedException();
public IItem WithParent(AbsolutePath parent) => this; public IItem WithParent(AbsolutePath parent) => this;
} }

View File

@@ -6,14 +6,14 @@ namespace FileTime.Core.ContentAccess;
public abstract class SubContentProviderBase : ContentProviderBase public abstract class SubContentProviderBase : ContentProviderBase
{ {
private readonly IContentProvider _parentContentProvider; public IContentProvider ParentContentProvider { get; }
protected SubContentProviderBase( protected SubContentProviderBase(
IContentProvider parentContentProvider, IContentProvider parentContentProvider,
string name, string name,
ITimelessContentProvider timelessContentProvider) : base(name, timelessContentProvider) ITimelessContentProvider timelessContentProvider) : base(name, timelessContentProvider)
{ {
_parentContentProvider = parentContentProvider; ParentContentProvider = parentContentProvider;
} }
public override async Task<IItem> GetItemByNativePathAsync( public override async Task<IItem> GetItemByNativePathAsync(
@@ -22,7 +22,7 @@ public abstract class SubContentProviderBase : ContentProviderBase
bool forceResolve = false, bool forceResolve = false,
AbsolutePathType forceResolvePathType = AbsolutePathType.Unknown, AbsolutePathType forceResolvePathType = AbsolutePathType.Unknown,
ItemInitializationSettings itemInitializationSettings = default) ItemInitializationSettings itemInitializationSettings = default)
=> await _parentContentProvider.GetItemByNativePathAsync( => await ParentContentProvider.GetItemByNativePathAsync(
nativePath, nativePath,
pointInTime, pointInTime,
forceResolve, forceResolve,
@@ -30,17 +30,14 @@ public abstract class SubContentProviderBase : ContentProviderBase
itemInitializationSettings); itemInitializationSettings);
public override async ValueTask<NativePath> GetNativePathAsync(FullName fullName) public override async ValueTask<NativePath> GetNativePathAsync(FullName fullName)
=> await _parentContentProvider.GetNativePathAsync(fullName); => await ParentContentProvider.GetNativePathAsync(fullName);
public override FullName GetFullName(NativePath nativePath) public override FullName GetFullName(NativePath nativePath)
=> _parentContentProvider.GetFullName(nativePath); => ParentContentProvider.GetFullName(nativePath);
public override async Task<byte[]?> GetContentAsync(IElement element, int? maxLength = null, CancellationToken cancellationToken = default)
=> await _parentContentProvider.GetContentAsync(element, maxLength, cancellationToken);
public override async Task<bool> CanHandlePathAsync(NativePath path) public override async Task<bool> CanHandlePathAsync(NativePath path)
=> await _parentContentProvider.CanHandlePathAsync(path); => await ParentContentProvider.CanHandlePathAsync(path);
public override VolumeSizeInfo? GetVolumeSizeInfo(FullName path) public override async ValueTask<NativePath?> GetSupportedPathPart(NativePath nativePath)
=> _parentContentProvider.GetVolumeSizeInfo(path); => await ParentContentProvider.GetSupportedPathPart(nativePath);
} }

View File

@@ -164,6 +164,22 @@ public sealed partial class LocalContentProvider : ContentProviderBase, ILocalCo
}; };
} }
public override ValueTask<NativePath?> GetSupportedPathPart(NativePath nativePath)
{
var path = nativePath.Path;
var pathParts = path.Split(Path.DirectorySeparatorChar).SelectMany(p => p.Split(Constants.SeparatorChar)).ToArray();
for (var i = pathParts.Length - 1; i > 0; i--)
{
var possiblePath = string.Join(Path.DirectorySeparatorChar, pathParts.Take(i));
if (!File.Exists(possiblePath) && !Directory.Exists(possiblePath)) continue;
return ValueTask.FromResult<NativePath?>(new NativePath(possiblePath));
}
return ValueTask.FromResult<NativePath?>(null);
}
private Container CreateEmptyContainer(NativePath nativePath, private Container CreateEmptyContainer(NativePath nativePath,
PointInTime pointInTime, PointInTime pointInTime,
IEnumerable<Exception>? initialExceptions = null) IEnumerable<Exception>? initialExceptions = null)

View File

@@ -40,10 +40,7 @@ public class LocalContentReader : IContentReader
} }
} }
public void SetPosition(long position) public void SetPosition(long position) => Position = position;
{
Position = position;
}
public Stream AsStream() => _binaryReader.BaseStream; public Stream AsStream() => _binaryReader.BaseStream;

View File

@@ -104,6 +104,7 @@ public sealed class RemoteContentProvider : ContentProviderBase, IRemoteContentP
public override Task<bool> CanHandlePathAsync(NativePath path) => throw new NotImplementedException(); public override Task<bool> CanHandlePathAsync(NativePath path) => throw new NotImplementedException();
public override VolumeSizeInfo? GetVolumeSizeInfo(FullName path) => throw new NotImplementedException(); public override VolumeSizeInfo? GetVolumeSizeInfo(FullName path) => throw new NotImplementedException();
public override ValueTask<NativePath?> GetSupportedPathPart(NativePath nativePath) => throw new NotImplementedException();
private string ConvertLocalFullNameToRemote(FullName fullName) private string ConvertLocalFullNameToRemote(FullName fullName)
{ {

View File

@@ -4,6 +4,7 @@
<TargetFramework>net7.0</TargetFramework> <TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<RootNamespace>FileTime.Tools.VirtualDiskSources</RootNamespace>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@@ -0,0 +1,8 @@
using FileTime.Core.ContentAccess;
namespace FileTime.Tools.VirtualDiskSources;
public interface IVirtualDiskContentProvider : IContentProvider
{
}

View File

@@ -0,0 +1,8 @@
using FileTime.Core.ContentAccess;
namespace FileTime.Tools.VirtualDiskSources;
public interface IVirtualDiskContentProviderFactory
{
IVirtualDiskContentProvider Create(IContentProvider parentContentProvider);
}

View File

@@ -1,6 +1,6 @@
using FileTime.Core.ContentAccess; using FileTime.Core.ContentAccess;
namespace FileTime.Tools.VirtualDiskSources.Abstractions; namespace FileTime.Tools.VirtualDiskSources;
public interface IVirtualDiskSubContentProvider : ISubContentProvider public interface IVirtualDiskSubContentProvider : ISubContentProvider
{ {

View File

@@ -1,6 +1,5 @@
using FileTime.App.Core.Services; using FileTime.App.Core.Services;
using FileTime.Core.ContentAccess; using FileTime.Core.ContentAccess;
using FileTime.Tools.VirtualDiskSources.Abstractions;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.DependencyInjection.Extensions;
@@ -13,6 +12,8 @@ public static class Startup
services.TryAddSingleton<IVirtualDiskSubContentProvider, VirtualDiskSubContentProvider>(); services.TryAddSingleton<IVirtualDiskSubContentProvider, VirtualDiskSubContentProvider>();
services.AddSingleton<ISubContentProvider>(sp => sp.GetRequiredService<IVirtualDiskSubContentProvider>()); services.AddSingleton<ISubContentProvider>(sp => sp.GetRequiredService<IVirtualDiskSubContentProvider>());
services.AddSingleton<IPreStartupHandler, DiscUtilsInitializer>(); services.AddSingleton<IPreStartupHandler, DiscUtilsInitializer>();
services.TryAddSingleton<IVirtualDiskContentProviderFactory, VirtualDiskContentProviderFactory>();
services.TryAddSingleton<IContentReaderFactory<VirtualDiskContentProvider>, VirtualDiskContentReaderFactory>();
return services; return services;
} }
} }

View File

@@ -1,14 +1,50 @@
using FileTime.Core.ContentAccess; using DiscUtils.Udf;
using FileTime.Core.ContentAccess;
using FileTime.Core.Models;
using FileTime.Core.Timeline; using FileTime.Core.Timeline;
namespace FileTime.Tools.VirtualDiskSources; namespace FileTime.Tools.VirtualDiskSources;
public class VirtualDiskContentProvider : SubContentProviderBase public class VirtualDiskContentProvider : SubContentProviderBase, IVirtualDiskContentProvider
{ {
private readonly IContentAccessorFactory _contentAccessorFactory;
public VirtualDiskContentProvider( public VirtualDiskContentProvider(
IContentProvider parentContentProvider, IContentProvider parentContentProvider,
ITimelessContentProvider timelessContentProvider) ITimelessContentProvider timelessContentProvider,
IContentAccessorFactory contentAccessorFactory)
: base(parentContentProvider, "virtual-disk", timelessContentProvider) : base(parentContentProvider, "virtual-disk", timelessContentProvider)
{ {
_contentAccessorFactory = contentAccessorFactory;
} }
public override async Task<byte[]?> GetContentAsync(IElement element, int? maxLength = null, CancellationToken cancellationToken = default)
{
var elementNativePath = element.NativePath!;
var supportedPath = await ParentContentProvider.GetSupportedPathPart(elementNativePath);
if (supportedPath is null) return null;
var parentItem = await ParentContentProvider.GetItemByNativePathAsync(supportedPath, element.PointInTime);
if (parentItem is not IElement parentElement) return null;
var contentReaderFactory = _contentAccessorFactory.GetContentReaderFactory(parentElement.Provider);
var reader = await contentReaderFactory.CreateContentReaderAsync(parentElement);
await using var readerStream = reader.AsStream();
using var discReader = new UdfReader(readerStream);
var subPath = elementNativePath.Path.Substring(supportedPath.Path.Length + 2 + Constants.SubContentProviderRootContainer.Length);
var fileInfo = discReader.GetFileInfo(subPath);
await using var contentReader = fileInfo.Open(FileMode.Open, FileAccess.Read);
var data = new byte[1024 * 1024];
var readAsync = await contentReader.ReadAsync(data, cancellationToken);
return data[0..readAsync].ToArray();
}
public override VolumeSizeInfo? GetVolumeSizeInfo(FullName path)
=> ParentContentProvider.GetVolumeSizeInfo(path);
} }

View File

@@ -0,0 +1,21 @@
using FileTime.Core.ContentAccess;
using FileTime.Core.Timeline;
namespace FileTime.Tools.VirtualDiskSources;
public class VirtualDiskContentProviderFactory : IVirtualDiskContentProviderFactory
{
private readonly ITimelessContentProvider _timelessContentProvider;
private readonly IContentAccessorFactory _contentAccessorFactory;
public VirtualDiskContentProviderFactory(
ITimelessContentProvider timelessContentProvider,
IContentAccessorFactory contentAccessorFactory)
{
_timelessContentProvider = timelessContentProvider;
_contentAccessorFactory = contentAccessorFactory;
}
public IVirtualDiskContentProvider Create(IContentProvider parentContentProvider)
=> new VirtualDiskContentProvider(parentContentProvider, _timelessContentProvider, _contentAccessorFactory);
}

View File

@@ -0,0 +1,39 @@
using FileTime.Core.ContentAccess;
namespace FileTime.Tools.VirtualDiskSources;
public class VirtualDiskContentReader : IContentReader
{
private readonly Stream _stream;
private readonly ICollection<IDisposable> _disposables;
public int PreferredBufferSize => 1024 * 1024;
public long? Position => _stream.Position;
public VirtualDiskContentReader(Stream stream, ICollection<IDisposable> disposables)
{
_stream = stream;
_disposables = disposables;
}
public async Task<byte[]> ReadBytesAsync(int bufferSize, int? offset = null)
{
var data = new byte[bufferSize];
var read = await _stream.ReadAsync(data, offset ?? 0, bufferSize);
return data[..read].ToArray();
}
public void SetPosition(long position) => _stream.Seek(position, SeekOrigin.Begin);
public Stream AsStream() => _stream;
public void Dispose()
{
_stream.Dispose();
foreach (var disposable in _disposables)
{
disposable.Dispose();
}
}
}

View File

@@ -0,0 +1,43 @@
using DiscUtils.Udf;
using FileTime.Core.ContentAccess;
using FileTime.Core.Models;
namespace FileTime.Tools.VirtualDiskSources;
public class VirtualDiskContentReaderFactory : IContentReaderFactory<VirtualDiskContentProvider>
{
private readonly IContentAccessorFactory _contentAccessorFactory;
public VirtualDiskContentReaderFactory(IContentAccessorFactory contentAccessorFactory)
{
_contentAccessorFactory = contentAccessorFactory;
}
public async Task<IContentReader> CreateContentReaderAsync(IElement element)
{
if (element.Provider is not VirtualDiskContentProvider provider)
throw new ArgumentException(
"Provider must be VirtualDiskContentProvider, but it is " + element.Provider.GetType(),
nameof(element));
var elementNativePath = element.NativePath!;
var supportedPath = (await provider.ParentContentProvider.GetSupportedPathPart(elementNativePath))!;
var parentElement = (IElement) await provider.ParentContentProvider.GetItemByNativePathAsync(supportedPath, element.PointInTime);
var contentReaderFactory = _contentAccessorFactory.GetContentReaderFactory(parentElement.Provider);
var reader = await contentReaderFactory.CreateContentReaderAsync(parentElement);
var readerStream = reader.AsStream();
var discReader = new UdfReader(readerStream);
var subPath = elementNativePath.Path.Substring(supportedPath.Path.Length + 2 + Constants.SubContentProviderRootContainer.Length);
var fileInfo = discReader.GetFileInfo(subPath);
var contentReader = fileInfo.Open(FileMode.Open, FileAccess.Read);
return new VirtualDiskContentReader(contentReader, new IDisposable[] {discReader, readerStream, contentReader});
}
}

View File

@@ -1,12 +1,10 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using DiscUtils; using DiscUtils;
using DiscUtils.Iso9660;
using DiscUtils.Udf; using DiscUtils.Udf;
using FileTime.Core.ContentAccess; using FileTime.Core.ContentAccess;
using FileTime.Core.Enums; using FileTime.Core.Enums;
using FileTime.Core.Models; using FileTime.Core.Models;
using FileTime.Core.Timeline; using FileTime.Core.Timeline;
using FileTime.Tools.VirtualDiskSources.Abstractions;
namespace FileTime.Tools.VirtualDiskSources; namespace FileTime.Tools.VirtualDiskSources;
@@ -14,14 +12,17 @@ public class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvider
{ {
private readonly IContentAccessorFactory _contentAccessorFactory; private readonly IContentAccessorFactory _contentAccessorFactory;
private readonly ITimelessContentProvider _timelessContentProvider; private readonly ITimelessContentProvider _timelessContentProvider;
private readonly IVirtualDiskContentProviderFactory _virtualDiskContentProviderFactory;
public VirtualDiskSubContentProvider( public VirtualDiskSubContentProvider(
IContentAccessorFactory contentAccessorFactory, IContentAccessorFactory contentAccessorFactory,
ITimelessContentProvider timelessContentProvider ITimelessContentProvider timelessContentProvider,
IVirtualDiskContentProviderFactory virtualDiskContentProviderFactory
) )
{ {
_contentAccessorFactory = contentAccessorFactory; _contentAccessorFactory = contentAccessorFactory;
_timelessContentProvider = timelessContentProvider; _timelessContentProvider = timelessContentProvider;
_virtualDiskContentProviderFactory = virtualDiskContentProviderFactory;
} }
public Task<bool> CanHandleAsync(IElement parentElement) public Task<bool> CanHandleAsync(IElement parentElement)
@@ -48,13 +49,16 @@ public class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvider
var rootFullName = new FullName(rootFullNameBase); var rootFullName = new FullName(rootFullNameBase);
var rootNativePath = new NativePath(rootNativePathBase); var rootNativePath = new NativePath(rootNativePathBase);
return CreateContainer(discReader.Root, var container = CreateContainer(
discReader,
discReader.Root,
rootFullName, rootFullName,
rootNativePath, rootNativePath,
parentElement.Provider, parentElement.Provider,
parentElement.Parent!, parentElement.Parent!,
parentElement.PointInTime, parentElement.PointInTime,
itemInitializationSettings); itemInitializationSettings);
return container;
} }
return ResolveNonRootChild(discReader, parentElement, itemPath, pointInTime, itemInitializationSettings); return ResolveNonRootChild(discReader, parentElement, itemPath, pointInTime, itemInitializationSettings);
@@ -89,6 +93,7 @@ public class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvider
if (container.GetDirectories().FirstOrDefault(d => d.Name == pathParts[^1]) is { } childContainer) if (container.GetDirectories().FirstOrDefault(d => d.Name == pathParts[^1]) is { } childContainer)
{ {
return CreateContainer( return CreateContainer(
discReader,
childContainer, childContainer,
childFullName, childFullName,
childNativePath, childNativePath,
@@ -99,9 +104,12 @@ public class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvider
); );
} }
if (container.GetFiles().FirstOrDefault(d => d.Name == pathParts[^1]) is { } childElement) if (container.GetFiles().FirstOrDefault(d => d.Name == pathParts[^1]) is not { } childElement)
{ {
return CreateElement( return null;
}
var element = CreateElement(
childElement, childElement,
childFullName, childFullName,
childNativePath, childNativePath,
@@ -109,12 +117,13 @@ public class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvider
parent, parent,
pointInTime pointInTime
); );
}
return null; discReader.Dispose();
return element;
} }
private IContainer CreateContainer( private IContainer CreateContainer(
UdfReader discReader,
DiscDirectoryInfo sourceContainer, DiscDirectoryInfo sourceContainer,
FullName fullname, FullName fullname,
NativePath nativePath, NativePath nativePath,
@@ -138,7 +147,7 @@ public class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvider
SupportsDelete.False, SupportsDelete.False,
false, false,
FormatAttributes(sourceContainer.Attributes), FormatAttributes(sourceContainer.Attributes),
new VirtualDiskContentProvider(parentContentProvider, _timelessContentProvider), _virtualDiskContentProviderFactory.Create(parentContentProvider),
false, false,
pointInTime, pointInTime,
exceptions, exceptions,
@@ -148,7 +157,11 @@ public class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvider
if (!initializationSettings.SkipChildInitialization) if (!initializationSettings.SkipChildInitialization)
{ {
ThreadPool.QueueUserWorkItem(_ => LoadChildren(container, sourceContainer, children, pointInTime, exceptions)); ThreadPool.QueueUserWorkItem(_ =>
{
LoadChildren(container, sourceContainer, children, pointInTime, exceptions);
discReader.Dispose();
});
} }
return container; return container;
@@ -204,7 +217,7 @@ public class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvider
false, false,
FormatAttributes(childElement.Attributes), FormatAttributes(childElement.Attributes),
childElement.Length, childElement.Length,
new VirtualDiskContentProvider(parentContentProvider, _timelessContentProvider), _virtualDiskContentProviderFactory.Create(parentContentProvider),
pointInTime, pointInTime,
new ObservableCollection<Exception>(), new ObservableCollection<Exception>(),
new ReadOnlyExtensionCollection(new ExtensionCollection()) new ReadOnlyExtensionCollection(new ExtensionCollection())