Open PK3 archives as read-only

This commit is contained in:
spherallic 2023-02-16 17:34:31 +01:00
parent 448f85d7ad
commit e65108a177

View file

@ -37,6 +37,7 @@ namespace CodeImp.DoomBuilder.Data
private readonly ArchiveType archivetype; //mxd
private readonly Dictionary<string, byte[]> sevenzipentries; //mxd
private bool bathmode = true; //mxd
private FileStream filestream;
#endregion
@ -51,6 +52,9 @@ namespace CodeImp.DoomBuilder.Data
// Constructor
public PK3Reader(DataLocation dl) : base(dl)
{
FileAccess access = FileAccess.Read;
FileShare share = FileShare.ReadWrite;
General.WriteLogLine("Opening " + Path.GetExtension(location.location).ToUpper().Replace(".", "") + " resource '" + location.location + "'");
if(!File.Exists(location.location))
@ -59,8 +63,11 @@ namespace CodeImp.DoomBuilder.Data
// Make list of all files
List<DirectoryFileEntry> fileentries = new List<DirectoryFileEntry>();
// Take the detour with a FileStream because SharpCompress doesn't directly support opening files as read-only
filestream = File.Open(location.location, FileMode.OpenOrCreate, access, share);
// Create archive
archive = ArchiveFactory.Open(location.location, Options.KeepStreamsOpen);
archive = ArchiveFactory.Open(filestream);
archivetype = archive.Type;
// Random access of 7z archives works TERRIBLY slow in SharpCompress
@ -92,6 +99,9 @@ namespace CodeImp.DoomBuilder.Data
archive.Dispose();
archive = null;
filestream.Dispose();
filestream = null;
// Make files list
files = new DirectoryFilesList(fileentries);
@ -117,6 +127,12 @@ namespace CodeImp.DoomBuilder.Data
archive = null;
}
if (filestream != null)
{
filestream.Dispose();
filestream = null;
}
// Done
base.Dispose();
}
@ -129,12 +145,25 @@ namespace CodeImp.DoomBuilder.Data
if(enable && archive == null)
{
archive = ArchiveFactory.Open(location.location);
FileAccess access = FileAccess.Read;
FileShare share = FileShare.ReadWrite;
// The file might have vanished in the meantime
if (!File.Exists(location.location))
throw new FileNotFoundException("Could not find the file \"" + location.location + "\"", location.location);
// Take the detour with a FileStream because SharpCompress doesn't directly support opening files as read-only
filestream = File.Open(location.location, FileMode.OpenOrCreate, access, share);
archive = ArchiveFactory.Open(filestream);
}
else if(!enable && !bathmode && archive != null)
{
archive.Dispose();
archive = null;
filestream.Dispose();
filestream = null;
}
}