External and Fix (#100)

* Progress report updates log

* Logging additions

* Minor update

* Set halfway point only if nothing can be found

* Better population metrics

* QOL improvements

* More tiny logging updates

* Autoscroll

* Be consistent

* Update packages, use submodules

* Use NuGet

* Not 100% sure why I did it that way...

* Update README.md

* Make copy protect scan prompt an option

* Enhanced-CD might be Win/Mac

* Add unconfirmed formats

* Enhance!
This commit is contained in:
Matt Nadareski
2018-07-17 10:21:37 -07:00
committed by GitHub
parent e307cb217f
commit 8a5c114a7e
30 changed files with 111 additions and 3878 deletions

View File

@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.props" Condition="Exists('..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.props')" />
<Import Project="..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.props" Condition="Exists('..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.props')" />
<Import Project="..\packages\xunit.runner.visualstudio.2.3.1\build\net20\xunit.runner.visualstudio.props" Condition="Exists('..\packages\xunit.runner.visualstudio.2.3.1\build\net20\xunit.runner.visualstudio.props')" />
<Import Project="..\packages\Microsoft.NET.Test.Sdk.15.7.2\build\net45\Microsoft.Net.Test.Sdk.props" Condition="Exists('..\packages\Microsoft.NET.Test.Sdk.15.7.2\build\net45\Microsoft.Net.Test.Sdk.props')" />
<Import Project="..\packages\xunit.runner.console.2.3.1\build\xunit.runner.console.props" Condition="Exists('..\packages\xunit.runner.console.2.3.1\build\xunit.runner.console.props')" />
<Import Project="..\packages\xunit.core.2.3.1\build\xunit.core.props" Condition="Exists('..\packages\xunit.core.2.3.1\build\xunit.core.props')" />
<PropertyGroup>
@@ -42,7 +43,7 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.CodeCoverage.Shim, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeCoverage.1.0.3\lib\netstandard1.0\Microsoft.VisualStudio.CodeCoverage.Shim.dll</HintPath>
<HintPath>..\packages\Microsoft.CodeCoverage.15.8.0\lib\net45\Microsoft.VisualStudio.CodeCoverage.Shim.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
@@ -83,7 +84,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\xunit.analyzers.0.9.0\analyzers\dotnet\cs\xunit.analyzers.dll" />
<Analyzer Include="..\packages\xunit.analyzers.0.10.0\analyzers\dotnet\cs\xunit.analyzers.dll" />
</ItemGroup>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
@@ -94,10 +95,13 @@
<Error Condition="!Exists('..\packages\xunit.core.2.3.1\build\xunit.core.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.core.2.3.1\build\xunit.core.props'))" />
<Error Condition="!Exists('..\packages\xunit.core.2.3.1\build\xunit.core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.core.2.3.1\build\xunit.core.targets'))" />
<Error Condition="!Exists('..\packages\xunit.runner.console.2.3.1\build\xunit.runner.console.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.runner.console.2.3.1\build\xunit.runner.console.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.NET.Test.Sdk.15.7.2\build\net45\Microsoft.Net.Test.Sdk.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.NET.Test.Sdk.15.7.2\build\net45\Microsoft.Net.Test.Sdk.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.NET.Test.Sdk.15.7.2\build\net45\Microsoft.Net.Test.Sdk.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.NET.Test.Sdk.15.7.2\build\net45\Microsoft.Net.Test.Sdk.targets'))" />
<Error Condition="!Exists('..\packages\xunit.runner.visualstudio.2.3.1\build\net20\xunit.runner.visualstudio.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.runner.visualstudio.2.3.1\build\net20\xunit.runner.visualstudio.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.targets'))" />
</Target>
<Import Project="..\packages\xunit.core.2.3.1\build\xunit.core.targets" Condition="Exists('..\packages\xunit.core.2.3.1\build\xunit.core.targets')" />
<Import Project="..\packages\Microsoft.NET.Test.Sdk.15.7.2\build\net45\Microsoft.Net.Test.Sdk.targets" Condition="Exists('..\packages\Microsoft.NET.Test.Sdk.15.7.2\build\net45\Microsoft.Net.Test.Sdk.targets')" />
<Import Project="..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.targets" Condition="Exists('..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.targets')" />
<Import Project="..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.targets" Condition="Exists('..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.targets')" />
</Project>

View File

@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.CodeCoverage" version="1.0.3" targetFramework="net461" />
<package id="Microsoft.NET.Test.Sdk" version="15.7.2" targetFramework="net461" />
<package id="Microsoft.CodeCoverage" version="15.8.0" targetFramework="net461" />
<package id="Microsoft.NET.Test.Sdk" version="15.8.0" targetFramework="net461" />
<package id="xunit" version="2.3.1" targetFramework="net461" />
<package id="xunit.abstractions" version="2.0.1" targetFramework="net461" />
<package id="xunit.analyzers" version="0.9.0" targetFramework="net461" />
<package id="xunit.analyzers" version="0.10.0" targetFramework="net461" />
<package id="xunit.assert" version="2.3.1" targetFramework="net461" />
<package id="xunit.core" version="2.3.1" targetFramework="net461" />
<package id="xunit.extensibility.core" version="2.3.1" targetFramework="net461" />

View File

@@ -67,6 +67,9 @@
</PropertyGroup>
<PropertyGroup />
<ItemGroup>
<Reference Include="BurnOutSharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\BurnOutSharp.1.3.5\lib\net461\BurnOutSharp.dll</HintPath>
</Reference>
<Reference Include="LessIO, Version=0.5.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LessIO.0.5.0\lib\net40\LessIO.dll</HintPath>
</Reference>
@@ -89,6 +92,9 @@
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="UnshieldSharp, Version=1.4.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\UnshieldSharp.1.4.2.1\lib\net461\UnshieldSharp.dll</HintPath>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
@@ -105,27 +111,12 @@
<DependentUpon>LogWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Data\Constants.cs" />
<Compile Include="External\BurnOut\EVORE.cs" />
<Compile Include="External\Unshield\CabDescriptor.cs" />
<Compile Include="External\Unshield\CommonHeader.cs" />
<Compile Include="External\Unshield\FileDescriptor.cs" />
<Compile Include="External\Unshield\Header.cs" />
<None Include="External\Unshield\LICENSE" />
<Compile Include="External\Unshield\OffsetList.cs" />
<Compile Include="External\Unshield\StringBuffer.cs" />
<Compile Include="External\Unshield\UnshieldCabinet.cs" />
<Compile Include="External\Unshield\UnshieldComponent.cs" />
<Compile Include="External\Unshield\UnshieldFileGroup.cs" />
<Compile Include="External\Unshield\UnshieldReader.cs" />
<Compile Include="External\Unshield\VolumeHeader.cs" />
<Compile Include="Options.cs" />
<Compile Include="External\BurnOut\ProtectionFind.cs" />
<Compile Include="UI\KnownSystemComboBoxItem.cs" />
<Compile Include="UI\AllowedSpeeds.cs" />
<Compile Include="UI\ViewModels.cs" />
<Compile Include="Utilities\DumpEnvironment.cs" />
<Compile Include="Utilities\Extensions.cs" />
<Compile Include="Utilities\CaseInsensitiveDictionary.cs" />
<Compile Include="Utilities\Parameters.cs" />
<Compile Include="Utilities\Result.cs" />
<Compile Include="Utilities\Validators.cs" />

View File

@@ -178,6 +178,8 @@
BDVideo,
DVDVideo,
EnhancedCD,
EnhancedDVD,
EnhancedBD,
HDDVDVideo,
PalmOS,
PhilipsCDiDigitalVideo,

View File

@@ -1,424 +0,0 @@
//this file is part of BurnOut
//Copyright (C)2005-2010 Gernot Knippen
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You can get a copy of the GNU General Public License
//by writing to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
namespace DICUI.External.BurnOut
{
struct Section
{
public uint iVirtualSize;
public uint iVirtualOffset;
public uint iRawOffset;
}
public static class EVORE
{
private const int WaitSeconds = 20;
private static Process StartSafe(string file)
{
Process startingprocess = new Process();
startingprocess.StartInfo.FileName = file;
startingprocess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
startingprocess.StartInfo.CreateNoWindow = true;
startingprocess.StartInfo.ErrorDialog = false;
try
{
startingprocess.Start();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
return startingprocess;
}
private static string MakeTempFile(string file, string sExtension = ".exe")
{
FileInfo filei = new FileInfo(file);
try
{
File.Delete(Path.Combine(Path.GetTempPath(), "tmp", filei.Name + "*" + sExtension));
}
catch { }
filei = filei.CopyTo(Path.GetTempPath() + "tmp" + filei.Name + Directory.GetFiles(Path.GetTempPath(), "tmp" + filei.Name + "*" + sExtension).Length + sExtension, true);
filei.Attributes = FileAttributes.Temporary | FileAttributes.NotContentIndexed;
return filei.FullName;
}
private static bool IsEXE(string file)
{
BinaryReader breader = new BinaryReader(File.OpenRead(file));
breader.ReadBytes(60);
int PEHeaderOffset = breader.ReadInt32();
breader.BaseStream.Seek(PEHeaderOffset, SeekOrigin.Begin);
breader.ReadBytes(22);
short Characteristics = breader.ReadInt16();
breader.Close();
//check if file is dll
if ((Characteristics & 0x2000) == 0x2000)
return false;
else
return true;
}
private static string[] CopyDependentDlls(string exefile)
{
FileInfo fiExe = new FileInfo(exefile);
Section[] sections = ReadSections(exefile);
BinaryReader breader = new BinaryReader(File.OpenRead(exefile), Encoding.Default);
long lastPosition;
string[] saDependentDLLs = null;
breader.ReadBytes(60);
int PEHeaderOffset = breader.ReadInt32();
breader.BaseStream.Seek(PEHeaderOffset + 120 + 8, SeekOrigin.Begin); //120 Bytes till IMAGE_DATA_DIRECTORY array,8 Bytes=size of IMAGE_DATA_DIRECTORY
uint ImportTableRVA = breader.ReadUInt32();
uint ImportTableSize = breader.ReadUInt32();
breader.BaseStream.Seek(RVA2Offset(ImportTableRVA, sections), SeekOrigin.Begin);
breader.BaseStream.Seek(12, SeekOrigin.Current);
uint DllNameRVA = breader.ReadUInt32();
while (DllNameRVA != 0)
{
string sDllName = "";
byte bChar;
lastPosition = breader.BaseStream.Position;
uint DLLNameOffset = RVA2Offset(DllNameRVA, sections);
if (DLLNameOffset > 0)
{
breader.BaseStream.Seek(DLLNameOffset, SeekOrigin.Begin);
if (breader.PeekChar() > -1)
{
do
{
bChar = breader.ReadByte();
sDllName += (char)bChar;
} while (bChar != 0 && breader.PeekChar() > -1);
sDllName = sDllName.Remove(sDllName.Length - 1, 1);
if (File.Exists(Path.Combine(fiExe.DirectoryName, sDllName)))
{
if (saDependentDLLs == null)
saDependentDLLs = new string[0];
else
saDependentDLLs = new string[saDependentDLLs.Length];
FileInfo fiDLL = new FileInfo(Path.Combine(fiExe.DirectoryName, sDllName));
saDependentDLLs[saDependentDLLs.Length - 1] = fiDLL.CopyTo(Path.GetTempPath() + sDllName, true).FullName;
}
}
breader.BaseStream.Seek(lastPosition, SeekOrigin.Begin);
}
breader.BaseStream.Seek(4 + 12, SeekOrigin.Current);
DllNameRVA = breader.ReadUInt32();
}
breader.Close();
return saDependentDLLs;
}
private static Section[] ReadSections(string exefile)
{
BinaryReader breader = new BinaryReader(File.OpenRead(exefile));
breader.ReadBytes(60);
uint PEHeaderOffset = breader.ReadUInt32();
breader.BaseStream.Seek(PEHeaderOffset + 6, SeekOrigin.Begin);
ushort NumberOfSections = breader.ReadUInt16();
breader.BaseStream.Seek(PEHeaderOffset + 120 + 16 * 8, SeekOrigin.Begin);
Section[] sections = new Section[NumberOfSections];
for (int i = 0; i < NumberOfSections; i++)
{
breader.BaseStream.Seek(8, SeekOrigin.Current);
uint ivs = breader.ReadUInt32();
uint ivo = breader.ReadUInt32();
breader.BaseStream.Seek(4, SeekOrigin.Current);
uint iro = breader.ReadUInt32();
breader.BaseStream.Seek(16, SeekOrigin.Current);
sections[i] = new Section()
{
iVirtualSize = ivs,
iVirtualOffset = ivo,
iRawOffset = iro,
};
}
breader.Close();
return sections;
}
private static uint RVA2Offset(uint RVA, Section[] sections)
{
int i = 0;
while (i != sections.Length)
{
if (sections[i].iVirtualOffset <= RVA && sections[i].iVirtualOffset + sections[i].iVirtualSize > RVA)
return RVA - sections[i].iVirtualOffset + sections[i].iRawOffset;
i++;
}
return 0;
}
#region "EVORE version-search-functions"
public static string SearchProtectDiscVersion(string file)
{
Process exe = new Process();
Process[] processes = new Process[0];
string version = "";
DateTime timestart;
if (!IsEXE(file))
return "";
string tempexe = MakeTempFile(file);
string[] DependentDlls = CopyDependentDlls(file);
try
{
File.Delete(Path.Combine(Path.GetTempPath(), "a*.tmp"));
}
catch { }
try
{
File.Delete(Path.Combine(Path.GetTempPath(), "PCD*.sys"));
}
catch { }
if (Directory.Exists(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ProtectDisc")))
{
try
{
File.Delete(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ProtectDisc", "p*.dll"));
}
catch { }
}
exe = StartSafe(tempexe);
if (exe == null)
return "";
timestart = DateTime.Now;
do
{
exe.Refresh();
string[] files = null;
//check for ProtectDisc 8.2-x
if (Directory.Exists(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ProtectDisc")))
{
files = Directory.GetFiles(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ProtectDisc"), "p*.dll");
}
if (files != null)
{
if (files.Length > 0)
{
FileVersionInfo fvinfo = FileVersionInfo.GetVersionInfo(files[0]);
if (fvinfo.FileVersion != "")
{
version = fvinfo.FileVersion.Replace(" ", "").Replace(",", ".");
//ProtectDisc 9 uses a ProtectDisc-Core dll version 8.0.x
if (version.StartsWith("8.0"))
version = "";
fvinfo = null;
break;
}
}
}
//check for ProtectDisc 7.1-8.1
files = Directory.GetFiles(Path.GetTempPath(), "a*.tmp");
if (files.Length > 0)
{
FileVersionInfo fvinfo = FileVersionInfo.GetVersionInfo(files[0]);
if (fvinfo.FileVersion != "")
{
version = fvinfo.FileVersion.Replace(" ", "").Replace(",", ".");
fvinfo = null;
break;
}
}
if (exe.HasExited)
break;
processes = Process.GetProcessesByName(exe.ProcessName);
if (processes.Length == 2)
{
processes[0].Refresh();
processes[1].Refresh();
if (processes[1].WorkingSet64 > exe.WorkingSet64)
exe = processes[1];
else if (processes[0].WorkingSet64 > exe.WorkingSet64) //else if (processes[0].Modules.Count > exe.Modules.Count)
exe = processes[0];
}
} while (processes.Length > 0 && DateTime.Now.Subtract(timestart).TotalSeconds < WaitSeconds);
Thread.Sleep(500);
if (!exe.HasExited)
{
processes = Process.GetProcessesByName(exe.ProcessName);
if (processes.Length == 2)
{
try
{
processes[0].Kill();
}
catch { }
processes[0].Close();
try
{
processes[1].Kill();
}
catch { }
}
else
{
exe.Refresh();
try
{
exe.Kill();
}
catch { }
}
}
exe.Close();
Thread.Sleep(500);
if (Directory.Exists(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ProtectDisc")))
{
try
{
File.Delete(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ProtectDisc", "p*.dll"));
}
catch { }
}
try
{
File.Delete(Path.Combine(Path.GetTempPath(), "a*.tmp"));
}
catch { }
try
{
File.Delete(Path.Combine(Path.GetTempPath(), "PCD*.sys"));
}
catch { }
File.Delete(tempexe);
if (DependentDlls != null)
{
for (int i = 0; i < DependentDlls.Length; i++)
{
try
{
File.Delete(DependentDlls[i]);
}
catch (Exception ex)
{
Console.WriteLine("!error while deleting file " + DependentDlls[i] + "; " + ex.Message);
}
}
}
return version;
}
public static string SearchSafeDiscVersion(string file)
{
Process exe = new Process();
string version = "";
DateTime timestart;
if (!IsEXE(file))
return "";
string tempexe = MakeTempFile(file);
string[] DependentDlls = CopyDependentDlls(file);
try
{
Directory.Delete(Path.Combine(Path.GetTempPath(), "~e*"), true);
}
catch { }
try
{
File.Delete(Path.Combine(Path.GetTempPath(), "~e*"));
}
catch { }
exe = StartSafe(tempexe);
if (exe == null)
return "";
timestart = DateTime.Now;
do
{
if (Directory.GetDirectories(Path.GetTempPath(), "~e*").Length > 0)
{
string[] files = Directory.GetFiles(Directory.GetDirectories(Path.GetTempPath(), "~e*")[0], "~de*.tmp");
if (files.Length > 0)
{
StreamReader sr;
try
{
sr = new StreamReader(files[0], Encoding.Default);
string FileContent = sr.ReadToEnd();
sr.Close();
int position = FileContent.IndexOf("%ld.%ld.%ld, %ld, %s,") - 1;
if (position > -1)
version = FileContent.Substring(position + 28, 12);
break;
}
catch { }
}
}
} while (!exe.HasExited && DateTime.Now.Subtract(timestart).TotalSeconds < WaitSeconds);
if (!exe.HasExited)
exe.Kill();
exe.Close();
try
{
Directory.Delete(Path.Combine(Path.GetTempPath(), "~e*"), true);
}
catch { }
try
{
File.Delete(Path.Combine(Path.GetTempPath(), "~e*"));
}
catch { }
File.Delete(tempexe);
if (DependentDlls != null)
{
for (int i = 0; i < DependentDlls.Length; i--)
{
try
{
File.Delete(DependentDlls[i]);
}
catch (Exception ex)
{
Console.WriteLine("!error while deleting file " + DependentDlls[i] + "; " + ex.Message);
}
}
}
return version;
}
#endregion
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +0,0 @@
namespace DICUI.External.Unshield
{
public class CabDescriptor
{
public uint FileTableOffset; /* 0c */
public uint FileTableSize; /* 14 */
public uint FileTableSize2; /* 18 */
public uint DirectoryCount; /* 1c */
public uint FileCount; /* 28 */
public uint FileTableOffset2; /* 2c */
public uint[] FileGroupOffsets = new uint[Constants.MAX_FILE_GROUP_COUNT]; /* 0x3e */
public uint[] ComponentOffsets = new uint[Constants.MAX_COMPONENT_COUNT]; /* 0x15a */
}
}

View File

@@ -1,48 +0,0 @@
using System;
namespace DICUI.External.Unshield
{
public class CommonHeader
{
public uint Signature; // 00
public uint Version;
public uint VolumeInfo;
public uint CabDescriptorOffset;
public uint CabDescriptorSize; // 10
/// <summary>
/// Populate a CommonHeader from an input buffer
/// </summary>
public static bool ReadCommonHeader(ref byte[] buffer, int bufferPointer, CommonHeader common)
{
common.Signature = BitConverter.ToUInt32(buffer, bufferPointer); bufferPointer += 4;
if (common.Signature != Constants.CAB_SIGNATURE)
{
// unshield_error("Invalid file signature");
if (common.Signature == Constants.MSCF_SIGNATURE)
{
// unshield_warning("Found Microsoft Cabinet header. Use cabextract (http://www.kyz.uklinux.net/cabextract.php) to unpack this file.");
}
return false;
}
common.Version = BitConverter.ToUInt32(buffer, bufferPointer); bufferPointer += 4;
common.VolumeInfo = BitConverter.ToUInt32(buffer, bufferPointer); bufferPointer += 4;
common.CabDescriptorOffset = BitConverter.ToUInt32(buffer, bufferPointer); bufferPointer += 4;
common.CabDescriptorSize = BitConverter.ToUInt32(buffer, bufferPointer); bufferPointer += 4;
/*
unshield_trace("Common header: %08x %08x %08x %08x",
common->version,
ommon->volume_info,
common->cab_descriptor_offset,
common->cab_descriptor_size);
*/
return true;
}
}
}

View File

@@ -1,17 +0,0 @@
namespace DICUI.External.Unshield
{
public class FileDescriptor
{
public uint NameOffset;
public uint DirectoryIndex;
public ushort Flags;
public uint ExpandedSize;
public uint CompressedSize;
public uint DataOffset;
public byte[] Md5 = new byte[16];
public ushort Volume;
public uint LinkPrevious;
public uint LinkNext;
public byte LinkFlags;
}
}

View File

@@ -1,240 +0,0 @@
using System;
namespace DICUI.External.Unshield
{
public class Header
{
public Header Next;
public int Index;
public byte[] Data;
public int DataPointer = 0;
public long Size;
public int MajorVersion;
// Shortcuts
public CommonHeader Common = new CommonHeader();
public CabDescriptor Cab = new CabDescriptor();
public uint[] FileTable;
public int FileTablePointer;
public FileDescriptor[] FileDescriptors;
public int FileDescriptorsPointer;
public int ComponentCount;
public UnshieldComponent[] Components;
public int ComponentsPointer;
public int FileGroupCount;
public UnshieldFileGroup[] FileGroups;
public int FileGroupsCounter;
public StringBuffer StringBuffer = new StringBuffer();
/// <summary>
/// Add a new StringBuffer to the existing list
/// </summary>
public StringBuffer AddStringBuffer()
{
StringBuffer result = new StringBuffer();
result.Next = this.StringBuffer;
this.StringBuffer = result;
return result;
}
/// <summary>
/// Populate the CabDescriptor from header data
/// </summary>
public bool GetCabDescriptor()
{
if (this.Common.CabDescriptorSize > 0)
{
int p = (int)(this.Common.CabDescriptorOffset);
p += 0xc;
this.Cab.FileTableOffset = BitConverter.ToUInt32(this.Data, p); p += 4;
p += 4;
this.Cab.FileTableSize = BitConverter.ToUInt32(this.Data, p); p += 4;
this.Cab.FileTableSize2 = BitConverter.ToUInt32(this.Data, p); p += 4;
this.Cab.DirectoryCount = BitConverter.ToUInt32(this.Data, p); p += 4;
p += 8;
this.Cab.FileCount = BitConverter.ToUInt32(this.Data, p); p += 4;
this.Cab.FileTableOffset2 = BitConverter.ToUInt32(this.Data, p); p += 4;
// assert((p - (header->data + header->common.cab_descriptor_offset)) == 0x30);
if (this.Cab.FileTableSize != this.Cab.FileTableSize2)
{
// unshield_warning("File table sizes do not match");
}
/*
unshield_trace("Cabinet descriptor: %08x %08x %08x %08x",
header->cab.file_table_offset,
header->cab.file_table_size,
header->cab.file_table_size2,
header->cab.file_table_offset2
);
unshield_trace("Directory count: %i", header->cab.directory_count);
unshield_trace("File count: %i", header->cab.file_count);
*/
p += 0xe;
for (int i = 0; i < Constants.MAX_FILE_GROUP_COUNT; i++)
{
this.Cab.FileGroupOffsets[i] = BitConverter.ToUInt32(this.Data, p); p += 4;
}
for (int i = 0; i < Constants.MAX_COMPONENT_COUNT; i++)
{
this.Cab.ComponentOffsets[i] = this.Cab.FileGroupOffsets[i] = BitConverter.ToUInt32(this.Data, p); p += 4;
}
return true;
}
else
{
// unshield_error("No CAB descriptor available!");
return false;
}
}
/// <summary>
/// Populate the CommonHeader from header data
/// </summary>
public bool GetCommmonHeader()
{
return CommonHeader.ReadCommonHeader(ref this.Data, this.DataPointer, this.Common);
}
/// <summary>
/// Populate the component list from header data
/// </summary>
public bool GetComponents()
{
int count = 0;
int available = 16;
this.Components = new UnshieldComponent[available];
for (int i = 0; i < Constants.MAX_COMPONENT_COUNT; i++)
{
if (this.Cab.ComponentOffsets[i] > 0)
{
OffsetList list = new OffsetList();
list.NextOffset = this.Cab.ComponentOffsets[i];
while (list.NextOffset > 0)
{
int p = GetDataOffset(list.NextOffset);
list.NameOffset = BitConverter.ToUInt32(this.Data, p); p += 4;
list.DescriptorOffset = BitConverter.ToUInt32(this.Data, p); p += 4;
list.NextOffset = BitConverter.ToUInt32(this.Data, p); p += 4;
if (count == available)
{
available <<= 1;
Array.Resize(ref this.Components, available);
}
this.Components[count++] = UnshieldComponent.Create(this, list.DescriptorOffset);
}
}
}
this.ComponentCount = count;
return true;
}
/// <summary>
/// Get the real data offset
/// </summary>
public int GetDataOffset(uint offset)
{
if (offset > 0)
return (int)(this.Common.CabDescriptorOffset + offset);
else
return -1;
}
/// <summary>
/// Populate the file group list from header data
/// </summary>
public bool GetFileGroups()
{
int count = 0;
int available = 16;
this.FileGroups = new UnshieldFileGroup[available];
for (int i = 0; i < Constants.MAX_FILE_GROUP_COUNT; i++)
{
if (this.Cab.FileGroupOffsets[i] > 0)
{
OffsetList list = new OffsetList();
list.NextOffset = this.Cab.FileGroupOffsets[i];
while (list.NextOffset > 0)
{
int p = GetDataOffset(list.NextOffset);
list.NameOffset = BitConverter.ToUInt32(this.Data, p); p += 4;
list.DescriptorOffset = BitConverter.ToUInt32(this.Data, p); p += 4;
list.NextOffset = BitConverter.ToUInt32(this.Data, p); p += 4;
if (count == available)
{
available <<= 1;
Array.Resize(ref this.FileGroups, available);
}
this.FileGroups[count++] = UnshieldFileGroup.Create(this, list.DescriptorOffset);
}
}
}
this.FileGroupCount = count;
return true;
}
/// <summary>
/// Populate the file table from header data
/// </summary>
public bool GetFileTable()
{
int p = (int)(this.Common.CabDescriptorOffset +
this.Cab.FileTableOffset);
int count = (int)(this.Cab.DirectoryCount + this.Cab.FileCount);
this.FileTable = new uint[count];
for (int i = 0; i < count; i++)
{
this.FileTable[i] = BitConverter.ToUInt32(this.Data, p); p += 4;
}
return true;
}
/// <summary>
/// Get the UInt32 at the given offset in the header data as a string
/// </summary>
public string GetString(uint offset)
{
return GetUTF8String(this.Data, GetDataOffset(offset));
}
/// <summary>
/// Convert a UInt32 read from a buffer to a string
/// </summary>
public string GetUTF8String(byte[] buffer, int bufferPointer)
{
return BitConverter.ToUInt32(buffer, bufferPointer).ToString("X8");
}
}
}

View File

@@ -1,24 +0,0 @@
Copyright (c) 2003 David Eriksson <twogood@users.sourceforge.net>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Addendum:
The code in this part of the project has been adapted from the original source
by Matt Nadareski for DICUI.

View File

@@ -1,9 +0,0 @@
namespace DICUI.External.Unshield
{
public class OffsetList
{
public uint NameOffset;
public uint DescriptorOffset;
public uint NextOffset;
}
}

View File

@@ -1,8 +0,0 @@
namespace DICUI.External.Unshield
{
public class StringBuffer
{
public StringBuffer Next;
public string String;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,61 +0,0 @@
using System;
namespace DICUI.External.Unshield
{
public class UnshieldComponent
{
public string Name;
public uint FileGroupCount;
public string[] FileGroupNames;
public int FileGroupNamesPointer = 0;
/// <summary>
/// Create a new UnshieldComponent from a header and data offset
/// </summary>
public static UnshieldComponent Create(Header header, uint offset)
{
UnshieldComponent self = new UnshieldComponent();
int bufferPointer = header.GetDataOffset(offset);
uint fileGroupTableOffset;
self.Name = header.GetString((uint)bufferPointer); bufferPointer += 4;
switch (header.MajorVersion)
{
case 0:
case 5:
bufferPointer += 0x6c;
break;
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
default:
bufferPointer += 0x6b;
break;
}
self.FileGroupCount = BitConverter.ToUInt16(header.Data, bufferPointer); bufferPointer += 2;
if (self.FileGroupCount > Constants.MAX_FILE_GROUP_COUNT)
return default(UnshieldComponent);
self.FileGroupNames = new string[self.FileGroupCount];
fileGroupTableOffset = BitConverter.ToUInt32(header.Data, bufferPointer); bufferPointer += 4;
bufferPointer = header.GetDataOffset(fileGroupTableOffset);
for (int i = 0; i < self.FileGroupCount; i++)
{
self.FileGroupNames[i] = header.GetString((uint)bufferPointer); bufferPointer += 4;
}
return self;
}
}
}

View File

@@ -1,36 +0,0 @@
using System;
namespace DICUI.External.Unshield
{
public class UnshieldFileGroup
{
public string Name;
public uint FirstFile;
public uint LastFile;
/// <summary>
/// Create a new UnshieldFileGroup from a header and data offset
/// </summary>
public static UnshieldFileGroup Create(Header header, uint offset)
{
UnshieldFileGroup self = new UnshieldFileGroup();
int pPointer = header.GetDataOffset(offset);
// unshield_trace("File group descriptor offset: %08x", offset);
self.Name = header.GetString(BitConverter.ToUInt32(header.Data, pPointer)); pPointer += 4;
if (header.MajorVersion <= 5)
pPointer += 0x48;
else
pPointer += 0x12;
self.FirstFile = BitConverter.ToUInt32(header.Data, pPointer); pPointer += 4;
self.LastFile = BitConverter.ToUInt32(header.Data, pPointer); pPointer += 4;
// unshield_trace("File group %08x first file = %i, last file = %i", offset, self->first_file, self->last_file);
return self;
}
}
}

View File

@@ -1,327 +0,0 @@
using System;
using System.IO;
namespace DICUI.External.Unshield
{
public class UnshieldReader
{
public UnshieldCabinet Unshield;
public uint Index;
public FileDescriptor FileDescriptor;
public int Volume;
public FileStream VolumeFile;
public VolumeHeader VolumeHeader;
public uint VolumeBytesLeft;
public uint ObfuscationOffset;
/// <summary>
/// Create a new UnshieldReader from an existing cabinet, index, and file descriptor
/// </summary>
public static UnshieldReader Create(UnshieldCabinet unshield, int index, FileDescriptor fileDescriptor)
{
UnshieldReader reader = new UnshieldReader();
if (reader == null)
return null;
reader.Unshield = unshield;
reader.Index = (uint)index;
reader.FileDescriptor = fileDescriptor;
for (; ; )
{
if (!reader.OpenVolume(fileDescriptor.Volume))
{
// unshield_error("Failed to open volume %i", file_descriptor->volume);
return null;
}
// Start with the correct volume for IS5 cabinets
if (reader.Unshield.HeaderList.MajorVersion <= 5 &&
index > (int)reader.VolumeHeader.LastFileIndex)
{
// unshield_trace("Trying next volume...");
fileDescriptor.Volume++;
continue;
}
break;
}
return reader;
}
/// <summary>
/// Dispose of the current object
/// </summary>
public void Dispose()
{
VolumeFile?.Close();
}
/// <summary>
/// Open the volume at the inputted index
/// </summary>
public bool OpenVolume(int volume)
{
bool success = false;
uint dataOffset = 0;
uint volumeBytesLeftCompressed;
uint volumeBytesLeftExpanded;
CommonHeader commonHeader = new CommonHeader();
// unshield_trace("Open volume %i", volume);
this.VolumeFile?.Close();
this.VolumeFile = this.Unshield.OpenFileForReading(volume, Constants.CABINET_SUFFIX);
if (this.VolumeFile == null)
{
// unshield_error("Failed to open input cabinet file %i", volume);
return success;
}
{
byte[] tmp = new byte[Constants.COMMON_HEADER_SIZE];
int p = 0;
if (Constants.COMMON_HEADER_SIZE !=
this.VolumeFile.Read(tmp, 0, Constants.COMMON_HEADER_SIZE))
return success;
if (!CommonHeader.ReadCommonHeader(ref tmp, p, commonHeader))
return success;
}
this.VolumeHeader = new VolumeHeader();
switch (this.Unshield.HeaderList.MajorVersion)
{
case 0:
case 5:
{
byte[] fiveHeader = new byte[Constants.VOLUME_HEADER_SIZE_V5];
int p = 0;
if (Constants.VOLUME_HEADER_SIZE_V5 !=
this.VolumeFile.Read(fiveHeader, 0, Constants.VOLUME_HEADER_SIZE_V5))
return success;
this.VolumeHeader.DataOffset = BitConverter.ToUInt32(fiveHeader, p); p += 4;
/*
if (READ_UINT32(p))
unshield_trace("Unknown = %08x", READ_UINT32(p));
*/
/* unknown */
p += 4;
this.VolumeHeader.FirstFileIndex = BitConverter.ToUInt32(fiveHeader, p); p += 4;
this.VolumeHeader.LastFileIndex = BitConverter.ToUInt32(fiveHeader, p); p += 4;
this.VolumeHeader.FirstFileOffset = BitConverter.ToUInt32(fiveHeader, p); p += 4;
this.VolumeHeader.FirstFileSizeExpanded = BitConverter.ToUInt32(fiveHeader, p); p += 4;
this.VolumeHeader.FirstFileSizeCompressed = BitConverter.ToUInt32(fiveHeader, p); p += 4;
this.VolumeHeader.LastFileOffset = BitConverter.ToUInt32(fiveHeader, p); p += 4;
this.VolumeHeader.LastFileSizeExpanded = BitConverter.ToUInt32(fiveHeader, p); p += 4;
this.VolumeHeader.LastFileSizeCompressed = BitConverter.ToUInt32(fiveHeader, p); p += 4;
if (this.VolumeHeader.LastFileOffset == 0)
this.VolumeHeader.LastFileOffset = Int32.MaxValue;
}
break;
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
default:
{
byte[] sixHeader = new byte[Constants.VOLUME_HEADER_SIZE_V6];
int p = 0;
if (Constants.VOLUME_HEADER_SIZE_V6 !=
this.VolumeFile.Read(sixHeader, 0, Constants.VOLUME_HEADER_SIZE_V6))
return success;
this.VolumeHeader.DataOffset = BitConverter.ToUInt32(sixHeader, p); p += 4;
this.VolumeHeader.DataOffsetHigh = BitConverter.ToUInt32(sixHeader, p); p += 4;
this.VolumeHeader.FirstFileIndex = BitConverter.ToUInt32(sixHeader, p); p += 4;
this.VolumeHeader.LastFileIndex = BitConverter.ToUInt32(sixHeader, p); p += 4;
this.VolumeHeader.FirstFileOffset = BitConverter.ToUInt32(sixHeader, p); p += 4;
this.VolumeHeader.FirstFileOffsetHigh = BitConverter.ToUInt32(sixHeader, p); p += 4;
this.VolumeHeader.FirstFileSizeExpanded = BitConverter.ToUInt32(sixHeader, p); p += 4;
this.VolumeHeader.FirstFileSizeExpandedHigh = BitConverter.ToUInt32(sixHeader, p); p += 4;
this.VolumeHeader.FirstFileSizeCompressed = BitConverter.ToUInt32(sixHeader, p); p += 4;
this.VolumeHeader.FirstFileSizeCompressedHigh = BitConverter.ToUInt32(sixHeader, p); p += 4;
this.VolumeHeader.LastFileOffset = BitConverter.ToUInt32(sixHeader, p); p += 4;
this.VolumeHeader.LastFileOffsetHigh = BitConverter.ToUInt32(sixHeader, p); p += 4;
this.VolumeHeader.LastFileSizeExpanded = BitConverter.ToUInt32(sixHeader, p); p += 4;
this.VolumeHeader.LastFileSizeExpandedHigh = BitConverter.ToUInt32(sixHeader, p); p += 4;
this.VolumeHeader.LastFileSizeCompressed = BitConverter.ToUInt32(sixHeader, p); p += 4;
this.VolumeHeader.LastFileSizeCompressedHigh = BitConverter.ToUInt32(sixHeader, p); p += 4;
}
break;
}
/*
unshield_trace("First file index = %i, last file index = %i",
reader->volume_header.first_file_index, reader->volume_header.last_file_index);
unshield_trace("First file offset = %08x, last file offset = %08x",
reader->volume_header.first_file_offset, reader->volume_header.last_file_offset);
*/
// enable support for split archives for IS5
if (this.Unshield.HeaderList.MajorVersion == 5)
{
if (this.Index < (this.Unshield.HeaderList.Cab.FileCount - 1) &&
this.Index == this.VolumeHeader.LastFileIndex &&
this.VolumeHeader.LastFileSizeCompressed != this.FileDescriptor.CompressedSize)
{
// unshield_trace("IS5 split file last in volume");
this.FileDescriptor.Flags |= Constants.FILE_SPLIT;
}
else if (this.Index > 0 &&
this.Index == this.VolumeHeader.FirstFileIndex &&
this.VolumeHeader.FirstFileSizeCompressed != this.FileDescriptor.CompressedSize)
{
// unshield_trace("IS5 split file first in volume");
this.FileDescriptor.Flags |= Constants.FILE_SPLIT;
}
}
if ((this.FileDescriptor.Flags & Constants.FILE_SPLIT) != 0)
{
// unshield_trace(/*"Total bytes left = 0x08%x, "*/"previous data offset = 0x08%x", /*total_bytes_left, */ data_offset);
if (this.Index == this.VolumeHeader.LastFileIndex && this.VolumeHeader.LastFileOffset != 0x7FFFFFFF)
{
// can be first file too
// unshield_trace("Index %i is last file in cabinet file %i", reader->index, volume);
dataOffset = this.VolumeHeader.LastFileOffset;
volumeBytesLeftExpanded = this.VolumeHeader.LastFileSizeExpanded;
volumeBytesLeftCompressed = this.VolumeHeader.LastFileSizeCompressed;
}
else if (this.Index == this.VolumeHeader.FirstFileIndex)
{
// unshield_trace("Index %i is first file in cabinet file %i", reader->index, volume);
dataOffset = this.VolumeHeader.FirstFileOffset;
volumeBytesLeftExpanded = this.VolumeHeader.FirstFileSizeExpanded;
volumeBytesLeftCompressed = this.VolumeHeader.FirstFileSizeCompressed;
}
else
{
success = true;
return success;
}
// unshield_trace("Will read 0x%08x bytes from offset 0x%08x", volume_bytes_left_compressed, data_offset);
}
else
{
dataOffset = this.FileDescriptor.DataOffset;
volumeBytesLeftExpanded = this.FileDescriptor.ExpandedSize;
volumeBytesLeftCompressed = this.FileDescriptor.CompressedSize;
}
if ((this.FileDescriptor.Flags & Constants.FILE_COMPRESSED) != 0)
this.VolumeBytesLeft = volumeBytesLeftCompressed;
else
this.VolumeBytesLeft = volumeBytesLeftExpanded;
this.VolumeFile.Seek(dataOffset, SeekOrigin.Begin);
this.Volume = volume;
success = true;
return success;
}
/// <summary>
/// Deobfuscate a buffer
/// </summary>
public void Deobfuscate(ref byte[] buffer, ref int bufferPointer, int size)
{
this.Deobfuscate(ref buffer, ref bufferPointer, size, ref this.ObfuscationOffset);
}
/// <summary>
/// Read a certain number of bytes from the current volume
/// </summary>
public bool Read(ref byte[] buffer, ref int bufferPointer, int size)
{
bool success = false;
int p = bufferPointer;
int bytesLeft = size;
// unshield_trace("unshield_reader_read start: bytes_left = 0x%x, volume_bytes_left = 0x%x", bytes_left, reader->volume_bytes_left);
for (; ; )
{
// Read as much as possible from this volume
int bytesToRead = (int)Math.Min(bytesLeft, this.VolumeBytesLeft);
// unshield_trace("Trying to read 0x%x bytes from offset %08x in volume %i", bytes_to_read, ftell(reader->volume_file), reader->volume);
if (bytesToRead == 0)
{
// unshield_error("bytes_to_read can't be zero");
return success;
}
if (bytesToRead != this.VolumeFile.Read(buffer, p, bytesToRead))
{
// unshield_error("Failed to read 0x%08x bytes of file %i (%s) from volume %i. Current offset = 0x%08x", bytes_to_read, reader->index, unshield_file_name(reader->unshield, reader->index), reader->volume, ftell(reader->volume_file));
return success;
}
bytesLeft -= bytesToRead;
this.VolumeBytesLeft -= (uint)bytesToRead;
// unshield_trace("bytes_left = %i, volume_bytes_left = %i", bytes_left, reader->volume_bytes_left);
if (bytesLeft == 0)
break;
p += bytesToRead;
// Open next volume
if (!this.OpenVolume(this.Volume + 1))
{
// unshield_error("Failed to open volume %i to read %i more bytes", reader->volume + 1, bytes_to_read);
return success;
}
}
if ((this.FileDescriptor.Flags & Constants.FILE_OBFUSCATED) != 0)
this.Deobfuscate(ref buffer, ref bufferPointer, size);
success = true;
return success;
}
/// <summary>
/// Deobfuscate a buffer with a seed value
/// </summary>
/// <remarks>Seed is 0 at file start</remarks>
private void Deobfuscate(ref byte[] buffer, ref int bufferPointer, int size, ref uint seed)
{
uint tmpSeed = seed;
for (; size > 0; size--, bufferPointer++, tmpSeed++)
{
buffer[bufferPointer] = (byte)(ROR8(buffer[bufferPointer] ^ 0xd5, 2) - (tmpSeed % 0x47));
}
seed = tmpSeed;
}
/// <summary>
/// Rotate Right 8
/// </summary>
private int ROR8(int x, int n) { return (((x) >> ((int)(n))) | ((x) << (8 - (int)(n)))); }
}
}

View File

@@ -1,22 +0,0 @@
namespace DICUI.External.Unshield
{
public class VolumeHeader
{
public uint DataOffset;
public uint DataOffsetHigh;
public uint FirstFileIndex;
public uint LastFileIndex;
public uint FirstFileOffset;
public uint FirstFileOffsetHigh;
public uint FirstFileSizeExpanded;
public uint FirstFileSizeExpandedHigh;
public uint FirstFileSizeCompressed;
public uint FirstFileSizeCompressedHigh;
public uint LastFileOffset;
public uint LastFileOffsetHigh;
public uint LastFileSizeExpanded;
public uint LastFileSizeExpandedHigh;
public uint LastFileSizeCompressed;
public uint LastFileSizeCompressedHigh;
}
}

View File

@@ -17,7 +17,7 @@
</Grid>
<Border Grid.Row="1" Background="White" BorderBrush="Gainsboro" BorderThickness="1" Margin="10">
<ScrollViewer Name="outputViewer" SizeChanged="ScrollViewer_SizeChanged">
<RichTextBox Name="output" FontFamily="Consolas" Background="#202020" IsReadOnly="true" />
<RichTextBox Name="output" FontFamily="Consolas" Background="#202020" IsReadOnly="true" TextChanged="OnTextChanged" />
</ScrollViewer>
</Border>

View File

@@ -7,6 +7,7 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Interop;
using System.Windows.Media;
@@ -375,6 +376,11 @@ namespace DICUI
StartDump("cd e Gam.iso 16");
}
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
outputViewer.ScrollToBottom();
}
#endregion
}

View File

@@ -165,6 +165,7 @@ namespace DICUI
return;
}
ViewModels.LoggerViewModel.VerboseLogLn("Changed system to: {0}", (SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem).Name);
PopulateMediaType();
EnsureDiscInformation();
}
@@ -175,9 +176,9 @@ namespace DICUI
if (e.RemovedItems.Count == 1 && e.AddedItems.Count == 1)
{
_currentMediaType = MediaTypeComboBox.SelectedItem as MediaType?;
SetSupportedDriveSpeed();
}
SetSupportedDriveSpeed();
GetOutputNames();
EnsureDiscInformation();
}
@@ -208,6 +209,7 @@ namespace DICUI
private void ProgressUpdated(object sender, Result value)
{
StatusLabel.Content = value.Message;
ViewModels.LoggerViewModel.VerboseLogLn(value.Message);
}
private void MainWindowLocationChanged(object sender, EventArgs e)
@@ -352,20 +354,20 @@ namespace DICUI
{
int index = _drives.FindIndex(d => d.MarkedActive);
DriveLetterComboBox.SelectedIndex = (index != -1 ? index : 0);
StatusLabel.Content = "Valid media found! Choose your Media Type";
StatusLabel.Content = "Valid drive found! Choose your Media Type";
StartStopButton.IsEnabled = true;
CopyProtectScanButton.IsEnabled = true;
ViewModels.LoggerViewModel.VerboseLogLn("Found {0} drives containing media: {1}", _drives.Count, String.Join(", ", _drives.Select(d => d.Letter)));
ViewModels.LoggerViewModel.VerboseLogLn("Found {0} drives: {1}", _drives.Count, String.Join(", ", _drives.Select(d => d.Letter)));
}
else
{
DriveLetterComboBox.SelectedIndex = -1;
StatusLabel.Content = "No valid media found!";
StatusLabel.Content = "No valid drive found!";
StartStopButton.IsEnabled = false;
CopyProtectScanButton.IsEnabled = false;
ViewModels.LoggerViewModel.VerboseLogLn("Found no drives contaning valid media.");
ViewModels.LoggerViewModel.VerboseLogLn("Found no drives");
}
}
@@ -405,6 +407,7 @@ namespace DICUI
QuietMode = _options.QuietMode,
ParanoidMode = _options.ParanoidMode,
ScanForProtection = _options.ScanForProtection,
RereadAmountC2 = _options.RereadAmountForC2,
System = SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem,
@@ -429,6 +432,7 @@ namespace DICUI
Result result = await _env.StartDumping(progress);
StatusLabel.Content = result ? "Dumping complete!" : result.Message;
ViewModels.LoggerViewModel.VerboseLogLn(result ? "Dumping complete!" : result.Message);
StartStopButton.Content = UIElements.StartDumping;
CopyProtectScanButton.IsEnabled = true;
@@ -549,8 +553,6 @@ namespace DICUI
{
// Set the drive speed list that's appropriate
var values = AllowedSpeeds.GetForMediaType(_currentMediaType);
DriveSpeedComboBox.ItemsSource = values;
DriveSpeedComboBox.SelectedIndex = values.Count / 2;
// Get the current environment
_env = DetermineEnvironment();
@@ -560,16 +562,24 @@ namespace DICUI
// If we have an invalid speed, we need to jump out
if (speed == -1)
{
DriveSpeedComboBox.ItemsSource = values;
DriveSpeedComboBox.SelectedIndex = values.Count / 2;
return;
}
ViewModels.LoggerViewModel.VerboseLogLn("Determined max drive speed for {0}: {1}.", _env.Drive.Letter, speed);
ViewModels.LoggerViewModel.VerboseLogLn("Determined max drive speed for {0} ({1}): {2}", _env.Drive.Letter, _currentMediaType.Name(), speed);
DriveSpeedComboBox.ItemsSource = values.Where(s => s <= speed);
ViewModels.LoggerViewModel.VerboseLogLn("Supported drive speeds: {0}", string.Join(",", values.Where(s => s <= speed)));
// Choose the lower of the two speeds between the allowed speeds and the user-defined one
int chosenSpeed = Math.Min(
AllowedSpeeds.GetForMediaType(_currentMediaType).Where(s => s <= speed).Last(),
values.Where(s => s <= speed).Last(),
_options.preferredDumpSpeedCD
);
ViewModels.LoggerViewModel.VerboseLogLn("Setting drive speed to: {0}", chosenSpeed);
DriveSpeedComboBox.SelectedValue = chosenSpeed;
}

View File

@@ -16,6 +16,7 @@ namespace DICUI
public bool QuietMode { get; set; }
public bool ParanoidMode { get; set; }
public bool ScanForProtection { get; set; }
public int RereadAmountForC2 { get; set; }
public bool SkipMediaTypeDetection { get; set; }
@@ -52,6 +53,7 @@ namespace DICUI
this.QuietMode = Boolean.TryParse(ConfigurationManager.AppSettings["QuietMode"], out bool quietMode) ? quietMode : false;
this.ParanoidMode = Boolean.TryParse(ConfigurationManager.AppSettings["ParanoidMode"], out bool paranoidMode) ? paranoidMode : false;
this.ScanForProtection = Boolean.TryParse(ConfigurationManager.AppSettings["ScanForProtection"], out bool scanForProtection) ? scanForProtection : true;
this.SkipMediaTypeDetection = Boolean.TryParse(ConfigurationManager.AppSettings["SkipMediaTypeDetection"], out bool skipMediaTypeDetection) ? skipMediaTypeDetection : false;
this.RereadAmountForC2 = Int32.TryParse(ConfigurationManager.AppSettings["RereadAmountForC2"], out int rereadAmountForC2) ? rereadAmountForC2 : 20;
this.VerboseLogging = Boolean.TryParse(ConfigurationManager.AppSettings["VerboseLogging"], out bool verboseLogging) ? verboseLogging : true;

View File

@@ -7,7 +7,7 @@
xmlns:l="clr-namespace:DICUI"
mc:Ignorable="d"
Title="Options" Height="400" Width="515.132">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
@@ -66,7 +66,7 @@
<TextBox x:Name="DumpSpeedDVDTextBox" Grid.Row="1" Grid.Column="2" Width="22" Height="22" TextAlignment="Center" IsReadOnly="True" IsReadOnlyCaretVisible="False" VerticalAlignment="Center" Text="{Binding ElementName=DumpSpeedDVDSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}" Background="LightGray" Foreground="Gray"/>
</Grid>
</GroupBox>
<GroupBox Grid.Row="2" Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Options" Padding="10">
@@ -75,6 +75,7 @@
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
@@ -93,7 +94,7 @@
IsChecked="{Binding Path=ParanoidMode}"
ToolTip="Enable pedandic and super-safe flags"
/>
<Grid Grid.Column="2" Grid.Row="0">
<Grid Grid.Column="2" Grid.ColumnSpan="2" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition />
@@ -107,7 +108,13 @@
/>
</Grid>
<CheckBox Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" VerticalAlignment="Center" Content="Skip Media Type Detection"
<CheckBox Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" VerticalAlignment="Top" Content="Automatically Scan for Protection"
DataContext="{Binding Source={x:Static lui:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=ScanForProtection}"
ToolTip="Enable automatic checking for copy protection on dumped media" Margin="0,4,0,0"
/>
<CheckBox Grid.Column="2" Grid.Row="1" Grid.ColumnSpan="2" VerticalAlignment="Center" Content="Skip Media Type Detection"
DataContext="{Binding Source={x:Static lui:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=SkipMediaTypeDetection}"
ToolTip="Disable trying to guess media type inserted (may improve performance at startup)"

View File

@@ -24,6 +24,12 @@ namespace DICUI.UI
set { _options.ParanoidMode = value; }
}
public bool ScanForProtection
{
get { return _options.ScanForProtection; }
set { _options.ScanForProtection = value; }
}
public bool SkipMediaTypeDetection
{
get { return _options.SkipMediaTypeDetection; }

View File

@@ -1,95 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace DICUI.Utilities
{
public class CaseInsensitiveDictionary<TValue> : IDictionary<string, TValue>
{
private Dictionary<string, TValue> _dict = new Dictionary<string, TValue>();
public TValue this[string key]
{
get
{
key = key.ToLower();
if (_dict.ContainsKey(key))
return _dict[key];
throw new ArgumentException("Key could not be found in the dictionary");
}
set
{
key = key.ToLower();
_dict[key] = value;
}
}
public ICollection<string> Keys => _dict.Keys;
public ICollection<TValue> Values => _dict.Values;
public int Count => _dict.Count;
public bool IsReadOnly => false;
public void Add(string key, TValue value)
{
key = key.ToLower();
_dict[key] = value;
}
public void Add(KeyValuePair<string, TValue> item)
{
string key = item.Key.ToLower();
_dict[key] = item.Value; ;
}
public void Clear()
{
_dict.Clear();
}
public bool Contains(KeyValuePair<string, TValue> item)
{
KeyValuePair<string, TValue> temp = new KeyValuePair<string, TValue>(item.Key.ToLower(), item.Value);
return _dict.Contains(temp);
}
public bool ContainsKey(string key)
{
return _dict.ContainsKey(key.ToLower());
}
public void CopyTo(KeyValuePair<string, TValue>[] array, int arrayIndex)
{
throw new NotImplementedException();
}
public IEnumerator<KeyValuePair<string, TValue>> GetEnumerator()
{
return _dict.GetEnumerator();
}
public bool Remove(string key)
{
return _dict.Remove(key.ToLower());
}
public bool Remove(KeyValuePair<string, TValue> item)
{
throw new NotImplementedException();
}
public bool TryGetValue(string key, out TValue value)
{
key = key.ToLower();
return _dict.TryGetValue(key, out value);
}
IEnumerator IEnumerable.GetEnumerator()
{
return _dict.GetEnumerator();
}
}
}

View File

@@ -534,6 +534,10 @@ namespace DICUI.Utilities
return "DVD-Video";
case KnownSystem.EnhancedCD:
return "Enhanced CD";
case KnownSystem.EnhancedDVD:
return "Enhanced DVD";
case KnownSystem.EnhancedBD:
return "Enhanced BD";
case KnownSystem.HDDVDVideo:
return "HD-DVD-Video";
case KnownSystem.PalmOS:

View File

@@ -57,6 +57,7 @@ namespace DICUI.Utilities
// extra DIC arguments
public bool QuietMode;
public bool ParanoidMode;
public bool ScanForProtection;
public int RereadAmountC2;
// External process information
@@ -69,6 +70,8 @@ namespace DICUI.Utilities
/// </summary>
public void CancelDumping()
{
ViewModels.LoggerViewModel.VerboseLogLn("Canceling dumping process...");
try
{
if (dicProcess != null && !dicProcess.HasExited)
@@ -83,7 +86,7 @@ namespace DICUI.Utilities
/// </summary>
public async void EjectDisc()
{
ViewModels.LoggerViewModel.VerboseLogLn("Ejecting Disc..");
ViewModels.LoggerViewModel.VerboseLogLn($"Ejecting disc in drive {Drive.Letter}");
// Validate that the required program exists
if (!File.Exists(DICPath))
@@ -293,7 +296,7 @@ namespace DICUI.Utilities
// Only fix OutputFilename if it's not blank or null
if (!String.IsNullOrWhiteSpace(OutputFilename))
OutputFilename = new StringBuilder(OutputFilename.Replace('&', '_')).Replace('.', '_', 0, OutputFilename.LastIndexOf('.')).ToString();
OutputFilename = new StringBuilder(OutputFilename.Replace('&', '_')).Replace('.', '_', 0, OutputFilename.LastIndexOf('.') == -1 ? 0 : OutputFilename.LastIndexOf('.')).ToString();
}
/// <summary>
@@ -433,6 +436,9 @@ namespace DICUI.Utilities
switch (System)
{
case KnownSystem.AppleMacintosh:
case KnownSystem.EnhancedCD:
case KnownSystem.EnhancedDVD:
case KnownSystem.EnhancedBD:
case KnownSystem.IBMPCCompatible:
mappings[Template.ISBNField] = Template.OptionalValue;
mappings[Template.CopyProtectionField] = GetCopyProtection() ?? Template.RequiredIfExistsValue;
@@ -456,7 +462,7 @@ namespace DICUI.Utilities
break;
case KnownSystem.SonyPlayStation:
mappings[Template.PlaystationEXEDateField] = GetPlayStationEXEDate(Drive.Letter) ?? "";
mappings[Template.PlayStationEDCField] = GetMissingEDCCount(combinedBase + ".img_eccEdc.txt") > 0 ? "No" : "Yes"; // TODO: This needs to be verified
mappings[Template.PlayStationEDCField] = GetMissingEDCCount(combinedBase + ".img_EdcEcc.txt") > 0 ? "No" : "Yes";
mappings[Template.PlayStationAntiModchipField] = GetAntiModchipDetected(combinedBase + "_disc.txt") ? "Yes" : "No";
mappings[Template.PlayStationLibCryptField] = "No";
if (File.Exists(combinedBase + "_subIntention.txt"))
@@ -529,6 +535,9 @@ namespace DICUI.Utilities
switch (System)
{
case KnownSystem.AppleMacintosh:
case KnownSystem.EnhancedCD:
case KnownSystem.EnhancedDVD:
case KnownSystem.EnhancedBD:
case KnownSystem.IBMPCCompatible:
mappings[Template.ISBNField] = Template.OptionalValue;
mappings[Template.CopyProtectionField] = GetCopyProtection() ?? Template.RequiredIfExistsValue;
@@ -750,7 +759,7 @@ namespace DICUI.Utilities
&& File.Exists(combinedBase + "_subError.txt")
&& File.Exists(combinedBase + "_subInfo.txt")
// && File.Exists(combinedBase + "_subIntention.txt")
&& File.Exists(combinedBase + "_subReadable.txt")
&& (File.Exists(combinedBase + "_subReadable.txt") || File.Exists(combinedBase + "_sub.txt"))
&& File.Exists(combinedBase + "_volDesc.txt");
case MediaType.DVD:
case MediaType.HDDVD:
@@ -823,13 +832,9 @@ namespace DICUI.Utilities
/// <returns>Copy protection scheme if possible, null on error</returns>
private string GetCopyProtection()
{
MessageBoxResult result = MessageBox.Show("Would you like to scan for copy protection? Warning: This may take a long time depending on the size of the disc!", "Copy Protection Scan", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (result == MessageBoxResult.No || result == MessageBoxResult.Cancel || result == MessageBoxResult.None)
{
return "(CHECK WITH PROTECTIONID)";
}
return Task.Run(() => Validators.RunProtectionScanOnPath(Drive.Letter + ":\\")).GetAwaiter().GetResult();
if (ScanForProtection)
return Task.Run(() => Validators.RunProtectionScanOnPath(Drive.Letter + ":\\")).GetAwaiter().GetResult();
return "(CHECK WITH PROTECTIONID)";
}
/// <summary>
@@ -1039,7 +1044,7 @@ namespace DICUI.Utilities
{
// Fast forward to the PVD
string line = sr.ReadLine();
while (!line.StartsWith("[INFO]"))
while (!line.StartsWith("[INFO] Number of sector(s) where EDC doesn't exist: "))
{
line = sr.ReadLine();
}

View File

@@ -5,9 +5,9 @@ using System.Linq;
using System.Management;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using BurnOutSharp;
using IMAPI2;
using DICUI.Data;
using DICUI.External.BurnOut;
namespace DICUI.Utilities
{
@@ -98,12 +98,14 @@ namespace DICUI.Utilities
break;
case KnownSystem.SonyPlayStation3:
types.Add(MediaType.BluRay);
types.Add(MediaType.CD); // TODO: Confirm this
break;
case KnownSystem.SonyPlayStation4:
types.Add(MediaType.BluRay);
break;
case KnownSystem.SonyPlayStationPortable:
types.Add(MediaType.UMD);
types.Add(MediaType.DVD); // TODO: Confirm this
break;
case KnownSystem.VMLabsNuon:
types.Add(MediaType.DVD);
@@ -334,6 +336,12 @@ namespace DICUI.Utilities
case KnownSystem.EnhancedCD:
types.Add(MediaType.CD);
break;
case KnownSystem.EnhancedDVD:
types.Add(MediaType.DVD);
break;
case KnownSystem.EnhancedBD:
types.Add(MediaType.BluRay);
break;
case KnownSystem.HDDVDVideo:
types.Add(MediaType.HDDVD);
break;

View File

@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="BurnOutSharp" version="1.3.5" targetFramework="net461" />
<package id="LessIO" version="0.5.0" targetFramework="net461" />
<package id="libmspack4n" version="0.8.0" targetFramework="net461" />
<package id="UnshieldSharp" version="1.4.2.1" targetFramework="net461" />
<package id="zlib.net" version="1.0.4.0" targetFramework="net461" />
</packages>

View File

@@ -1,4 +1,4 @@
# DICUI
i'# DICUI
DiscImageCreator UI in C#
@@ -6,6 +6,8 @@ This is a community project, so if you have some time and knowledge to give, we'
We are using DiscImageCreator (DIC), created by Sarami, and we would like to thanks him for his great software. The latest release of DIC can be found on [the GitHub page](https://github.com/saramibreak/DiscImageCreator)
This project relies on two open-source code ports to help perform copy protection scanning: [BurnOutSharp](https://github.com/mnadareski/BurnOutSharp) and [UnshieldSharp](https://github.com/mnadareski/UnshieldSharp)
## System Requirements
Even though this is written in C#, this program can only be used on Windows systems due to the base program, DiscImageCreator, being Windows-only.
@@ -30,12 +32,16 @@ A list of all changes can now be found [here](https://github.com/reignstumble/DI
Here are the talented people who have contributed to the project so far:
**ReignStumble** - Project Lead / UI Design
- **ReignStumble** - Project Lead / UI Design
- **darksabre76** - Project Co-Lead / Backend Design
- **Jakz** - Primary Feature Contributor
- **NHellFire** - Feature Contributor
**darksabre76** - Project Co-Lead / Backend Design
## Notable Testers
**Jakz** - Feature Contributor
These are the tireless individuals who have dedicated countless hours to help test the many features of DICUI and have worked with the development team closely:
**NHellFire** - Feature Contributor
**Dizzzy** - Concept/Ideas/Beta tester
- **Dizzzy/user7** - Concept, ideas, tester
- **Kludge** - Primary stress tester
- **ajshell1** - Tester
- **eientei95** - Tester