First Public Release.

This commit is contained in:
gjefferyes
2014-09-23 12:06:15 -07:00
parent 5ce43ac380
commit 5179fafbc0
102 changed files with 46849 additions and 0 deletions

30
ROMVault2.sln Normal file
View File

@@ -0,0 +1,30 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.30501.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ROMVault2", "ROMVault2\ROMVault2.csproj", "{437E12AB-46F3-4A75-A3D5-6C524B5A79B5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FFD35B18-3366-4460-9095-2B520EE73C87}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{437E12AB-46F3-4A75-A3D5-6C524B5A79B5}.Debug|Any CPU.ActiveCfg = Debug|x86
{437E12AB-46F3-4A75-A3D5-6C524B5A79B5}.Debug|Any CPU.Build.0 = Debug|x86
{437E12AB-46F3-4A75-A3D5-6C524B5A79B5}.Debug|x86.ActiveCfg = Debug|x86
{437E12AB-46F3-4A75-A3D5-6C524B5A79B5}.Debug|x86.Build.0 = Debug|x86
{437E12AB-46F3-4A75-A3D5-6C524B5A79B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{437E12AB-46F3-4A75-A3D5-6C524B5A79B5}.Release|Any CPU.Build.0 = Release|Any CPU
{437E12AB-46F3-4A75-A3D5-6C524B5A79B5}.Release|x86.ActiveCfg = Release|Any CPU
{437E12AB-46F3-4A75-A3D5-6C524B5A79B5}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,152 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using ROMVault2.SupportedFiles;
namespace ROMVault2
{
public class bgwProgress
{
public bgwProgress(int Progress)
{
this.Progress = Progress;
}
public int Progress { get; private set; }
}
public class bgwText
{
public bgwText(string Text)
{
this.Text = Text;
}
public string Text { get; private set; }
}
public class bgwText2
{
public bgwText2(string Text)
{
this.Text = Text;
}
public string Text { get; private set; }
}
public class bgwText3
{
public bgwText3(string Text)
{
this.Text = Text;
}
public string Text { get; private set; }
}
public class bgwSetRange
{
public bgwSetRange(int MaxVal)
{
this.MaxVal = MaxVal;
}
public int MaxVal { get; private set; }
}
public class bgwSetRange2
{
public bgwSetRange2(int MaxVal)
{
this.MaxVal = MaxVal;
}
public int MaxVal { get; private set; }
}
public class bgwValue2
{
public bgwValue2(int Value)
{
this.Value = Value;
}
public int Value { get; private set; }
}
public class bgwRange2Visible
{
public bgwRange2Visible(bool Visible)
{
this.Visible = Visible;
}
public bool Visible { get; private set; }
}
public class bgwShowCorrupt
{
public bgwShowCorrupt(ZipReturn zr, string filename)
{
this.zr = zr;
this.filename = filename;
}
public ZipReturn zr { get; private set; }
public string filename { get; private set; }
}
public class bgwShowError
{
public bgwShowError(string filename, string error)
{
this.error = error;
this.filename = filename;
}
public string filename { get; private set; }
public string error { get; private set; }
}
public class bgwShowFix
{
public bgwShowFix(string fixDir, string fixZip, string fixFile, ulong? size, string dir, string sourceDir, string sourceZip, string sourceFile)
{
FixDir = fixDir;
FixZip = fixZip;
FixFile = fixFile;
Size = size.ToString();
Dir = dir;
SourceDir = sourceDir;
SourceZip = sourceZip;
SourceFile = sourceFile;
}
public string FixDir { get; private set; }
public string FixZip { get; private set; }
public string FixFile { get; private set; }
public string Size { get; private set; }
public string Dir { get; private set; }
public string SourceDir { get; private set; }
public string SourceZip { get; private set; }
public string SourceFile { get; private set; }
}
public class bgwShowFixError
{
public bgwShowFixError(string FixError)
{
this.FixError = FixError;
}
public string FixError { get; private set; }
}
}

507
ROMVault2/DBHelper.cs Normal file
View File

@@ -0,0 +1,507 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2013 *
******************************************************/
using System;
using System.Collections.Generic;
using ROMVault2.RvDB;
using ROMVault2.Utils;
namespace ROMVault2
{
public enum EFile
{
Keep,
Delete
}
public static class DBHelper
{
private static readonly byte[] ZeroByteMD5;
private static readonly byte[] ZeroByteSHA1;
private static readonly byte[] ZeroByteCRC;
static DBHelper()
{
ZeroByteMD5 = VarFix.CleanMD5SHA1("d41d8cd98f00b204e9800998ecf8427e", 32);
ZeroByteSHA1 = VarFix.CleanMD5SHA1("da39a3ee5e6b4b0d3255bfef95601890afd80709", 40);
ZeroByteCRC = VarFix.CleanMD5SHA1("00000000", 8);
}
public static void GetSelectedDirList(ref List<RvDir> lstDir)
{
GetSelectedDirList(ref lstDir, DB.DirTree);
}
private static void GetSelectedDirList(ref List<RvDir> lstDir, RvDir thisDir)
{
for (int i = 0; i < thisDir.ChildCount; i++)
{
if (thisDir.DatStatus != DatStatus.InDatCollect) continue;
RvDir tDir = thisDir.Child(i) as RvDir;
if (tDir == null) continue;
if (tDir.Tree == null) continue;
if (tDir.Tree.Checked == RvTreeRow.TreeSelect.Selected)
lstDir.Add(tDir);
GetSelectedDirList(ref lstDir, tDir);
}
}
public static int CompareName(RvBase var1, RvBase var2)
{
int retv = TrrntZipStringCompare(var1.Name, var2.Name);
if (retv != 0) return retv;
FileType f1 = var1.FileType;
FileType f2 = var2.FileType;
if (f1 == FileType.ZipFile)
{
if (f2 != FileType.ZipFile)
ReportError.SendAndShow("Incompatible Compare type");
return Math.Sign(String.Compare(var1.Name, var2.Name, StringComparison.Ordinal));
}
return f1.CompareTo(f2);
}
private static int TrrntZipStringCompare(string string1, string string2)
{
char[] bytes1 = string1.ToCharArray();
char[] bytes2 = string2.ToCharArray();
int pos1 = 0;
int pos2 = 0;
for (; ; )
{
if (pos1 == bytes1.Length)
return ((pos2 == bytes2.Length) ? 0 : -1);
if (pos2 == bytes2.Length)
return 1;
int byte1 = bytes1[pos1++];
int byte2 = bytes2[pos2++];
if (byte1 >= 65 && byte1 <= 90) byte1 += 0x20;
if (byte2 >= 65 && byte2 <= 90) byte2 += 0x20;
if (byte1 < byte2)
return -1;
if (byte1 > byte2)
return 1;
}
}
public static int DatCompare(RvDat var1, RvDat var2)
{
int retv = Math.Sign(string.Compare(var1.GetData(RvDat.DatData.DatFullName), var2.GetData(RvDat.DatData.DatFullName), StringComparison.CurrentCultureIgnoreCase));
if (retv != 0) return retv;
retv = Math.Sign(var1.TimeStamp.CompareTo(var2.TimeStamp));
if (retv != 0) return retv;
retv = Math.Sign(var1.AutoAddDirectory.CompareTo(var2.AutoAddDirectory));
if (retv != 0) return retv;
return 0;
}
public static string GetRealPath(string rootPath)
{
string strFullPath = "";
int lenFound = 0;
foreach (DirMap dirPathMap in Settings.DirPathMap)
{
string dirKey = dirPathMap.DirKey;
int dirKeyLen = dirKey.Length;
if (rootPath.Length >= dirKeyLen)
if (String.Compare(rootPath.Substring(0, dirKeyLen), dirKey, StringComparison.Ordinal) == 0)
{
if (lenFound < dirKeyLen)
{
string dirPath = dirPathMap.DirPath;
lenFound = dirKeyLen;
strFullPath = rootPath == dirKey ? dirPath : IO.Path.Combine(dirPath, rootPath.Substring(dirKeyLen + 1));
}
}
}
return strFullPath;
}
public static string GetDatPath(string rootPath)
{
if (rootPath == "")
return Settings.DatRoot;
if (rootPath.Substring(0, 6) == "ToSort")
return "Error";
if (rootPath.Substring(0, 8) == "RomVault")
return Settings.DatRoot + rootPath.Substring(8);
return Settings.DatRoot;
}
public static void GetSelectedFilesSortCRCSize(out List<RvFile> lstFiles)
{
lstFiles = new List<RvFile>();
GetSelectedFilesSortCRCSize(ref lstFiles, DB.DirTree, true);
RomSortCRCSize(lstFiles);
}
private static void GetSelectedFilesSortCRCSize(ref List<RvFile> lstFiles, RvBase val, bool selected)
{
if (selected)
{
RvFile rvFile = val as RvFile;
if (rvFile != null)
{
if ((rvFile.Size != null && rvFile.CRC != null) || rvFile.Size == 0)
lstFiles.Add(rvFile);
}
}
RvDir rvVal = val as RvDir;
if (rvVal == null) return;
for (int i = 0; i < rvVal.ChildCount; i++)
{
bool nextSelect = selected;
if (rvVal.Tree != null)
nextSelect = rvVal.Tree.Checked == RvTreeRow.TreeSelect.Selected;
GetSelectedFilesSortCRCSize(ref lstFiles, rvVal.Child(i), nextSelect);
}
}
private static void RomSortCRCSize(List<RvFile> lstFiles)
{
RomSortCRCSize(0, lstFiles.Count, lstFiles);
}
private static void RomSortCRCSize(int intBase, int intTop, List<RvFile> lstFiles)
{
if ((intTop - intBase) <= 1) return;
int intMiddle = (intTop + intBase) / 2;
if ((intMiddle - intBase) > 1)
RomSortCRCSize(intBase, intMiddle, lstFiles);
if ((intTop - intMiddle) > 1)
RomSortCRCSize(intMiddle, intTop, lstFiles);
int intBottomSize = intMiddle - intBase;
int intTopSize = intTop - intMiddle;
RvFile[] lstBottom = new RvFile[intBottomSize];
RvFile[] lstTop = new RvFile[intTopSize];
for (int intloop = 0; intloop < intBottomSize; intloop++)
lstBottom[intloop] = lstFiles[intBase + intloop];
for (int intloop = 0; intloop < intTopSize; intloop++)
lstTop[intloop] = lstFiles[intMiddle + intloop];
int intBottomCount = 0;
int intTopCount = 0;
int intCount = intBase;
while (intBottomCount < intBottomSize && intTopCount < intTopSize)
{
if (RomSortCRCSizeFunc(lstBottom[intBottomCount], lstTop[intTopCount]) < 1)
{
lstFiles[intCount] = lstBottom[intBottomCount];
intCount++;
intBottomCount++;
}
else
{
lstFiles[intCount] = lstTop[intTopCount];
intCount++;
intTopCount++;
}
}
while (intBottomCount < intBottomSize)
{
lstFiles[intCount] = lstBottom[intBottomCount];
intCount++;
intBottomCount++;
}
while (intTopCount < intTopSize)
{
lstFiles[intCount] = lstTop[intTopCount];
intCount++;
intTopCount++;
}
}
private static int RomSortCRCSizeFunc(RvFile a, RvFile b)
{
int retv = ArrByte.iCompare(a.CRC, b.CRC);
if (retv == 0)
retv = ULong.iCompare(a.Size, b.Size);
return retv;
}
public static int RomSearchCRCSize(RvFile tRom, List<RvFile> lstFiles, out int index)
{
if (lstFiles.Count == 0)
{
index = 0;
return -1;
}
// this one below method will always return the first item in a list if there is more than one matching result.
int intBottom = -1;
int intTop = lstFiles.Count - 1;
while (intBottom + 1 < intTop)
{
int intMid = (intBottom + intTop + 1) / 2;
int intRes = RomSortCRCSizeFunc(lstFiles[intMid], tRom);
if (intRes >= 0)
intTop = intMid;
else
intBottom = intMid;
}
intBottom++;
index = intBottom;
return RomSortCRCSizeFunc(lstFiles[intBottom], tRom);
}
// find all of the files that we think we have that match the needed CRC and Size.
public static void RomSearchFindFixes(RvFile tRom, List<RvFile> lstFiles, out List<RvFile> lstFilesOut)
{
lstFilesOut = new List<RvFile>();
if (tRom.CRC == null || tRom.Size == null)
return;
int intIndex;
int intRes = RomSearchCRCSize(tRom, lstFiles, out intIndex);
while (intRes == 0)
{
if (lstFiles[intIndex].GotStatus == GotStatus.Got && FindFixes.CheckIfMissingFileCanBeFixedByGotFile(tRom, lstFiles[intIndex]))
lstFilesOut.Add(lstFiles[intIndex]);
intIndex++;
intRes = intIndex < lstFiles.Count ? RomSortCRCSizeFunc(lstFiles[intIndex], tRom) : 1;
}
}
// find all of the files that we think we have that match the needed CRC and Size.
public static void RomSearchFindMatchingFiles(RvFile tRom, List<RvFile> lstFiles, out int startIndex, out int length)
{
int intIndex;
int intRes = RomSearchCRCSize(tRom, lstFiles, out intIndex);
startIndex = intIndex;
while (intRes == 0)
{
intIndex++;
intRes = intIndex < lstFiles.Count ? RomSortCRCSizeFunc(lstFiles[intIndex], tRom) : 1;
}
length = intIndex - startIndex;
}
public static bool IsZeroLengthFile(RvFile tFile)
{
if (tFile.MD5 != null)
{
if (!ArrByte.bCompare(tFile.MD5, ZeroByteMD5))
return false;
}
if (tFile.SHA1 != null)
{
if (!ArrByte.bCompare(tFile.SHA1, ZeroByteSHA1))
return false;
}
if (tFile.CRC != null)
if (!ArrByte.bCompare(tFile.CRC, ZeroByteCRC))
return false;
return tFile.Size == 0;
}
public static bool RomFromSameGame(RvFile a, RvFile b)
{
if (a.Parent == null)
return false;
if (b.Parent == null)
return false;
return a.Parent == b.Parent;
}
public static void GetSelectedFilesSortSHA1CHD(out List<RvFile> lstFiles)
{
lstFiles = new List<RvFile>();
GetSelectedFilesSortSHA1CHD(ref lstFiles, DB.DirTree, true);
RomSortSHA1CHD(lstFiles);
}
private static void GetSelectedFilesSortSHA1CHD(ref List<RvFile> lstFiles, RvBase val, bool selected)
{
if (selected)
{
RvFile rvFile = val as RvFile;
if (rvFile != null)
{
if (rvFile.SHA1CHD != null)
lstFiles.Add(rvFile);
}
}
RvDir rvVal = val as RvDir;
if (rvVal == null) return;
for (int i = 0; i < rvVal.ChildCount; i++)
{
bool nextSelect = selected;
if (rvVal.Tree != null)
nextSelect = rvVal.Tree.Checked == RvTreeRow.TreeSelect.Selected;
GetSelectedFilesSortSHA1CHD(ref lstFiles, rvVal.Child(i), nextSelect);
}
}
private static void RomSortSHA1CHD(List<RvFile> lstFiles)
{
RomSortSHA1CHD(0, lstFiles.Count, lstFiles);
}
private static void RomSortSHA1CHD(int intBase, int intTop, List<RvFile> lstFiles)
{
if ((intTop - intBase) <= 1) return;
int intMiddle = (intTop + intBase) / 2;
if ((intMiddle - intBase) > 1)
RomSortSHA1CHD(intBase, intMiddle, lstFiles);
if ((intTop - intMiddle) > 1)
RomSortSHA1CHD(intMiddle, intTop, lstFiles);
int intBottomSize = intMiddle - intBase;
int intTopSize = intTop - intMiddle;
RvFile[] lstBottom = new RvFile[intBottomSize];
RvFile[] lstTop = new RvFile[intTopSize];
for (int intloop = 0; intloop < intBottomSize; intloop++)
lstBottom[intloop] = lstFiles[intBase + intloop];
for (int intloop = 0; intloop < intTopSize; intloop++)
lstTop[intloop] = lstFiles[intMiddle + intloop];
int intBottomCount = 0;
int intTopCount = 0;
int intCount = intBase;
while (intBottomCount < intBottomSize && intTopCount < intTopSize)
{
if (RomSortSHA1CHDFunc(lstBottom[intBottomCount], lstTop[intTopCount]) < 1)
{
lstFiles[intCount] = lstBottom[intBottomCount];
intCount++;
intBottomCount++;
}
else
{
lstFiles[intCount] = lstTop[intTopCount];
intCount++;
intTopCount++;
}
}
while (intBottomCount < intBottomSize)
{
lstFiles[intCount] = lstBottom[intBottomCount];
intCount++;
intBottomCount++;
}
while (intTopCount < intTopSize)
{
lstFiles[intCount] = lstTop[intTopCount];
intCount++;
intTopCount++;
}
}
private static int RomSortSHA1CHDFunc(RvFile a, RvFile b)
{
int retv = ArrByte.iCompare(a.SHA1CHD, b.SHA1CHD);
return retv;
}
private static int RomSearchSHA1CHD(RvFile tRom, List<RvFile> lstFiles, out int index)
{
if (lstFiles.Count == 0)
{
index = 0;
return -1;
}
// this one below method will always return the first item in a list if there is more than one matching result.
int intBottom = -1;
int intTop = lstFiles.Count - 1;
while (intBottom + 1 < intTop)
{
int intMid = (intBottom + intTop + 1) / 2;
int intRes = RomSortSHA1CHDFunc(lstFiles[intMid], tRom);
if (intRes >= 0)
intTop = intMid;
else
intBottom = intMid;
}
intBottom++;
index = intBottom;
return RomSortSHA1CHDFunc(lstFiles[intBottom], tRom);
}
// find all of the files that we have that match the needed SHA1 CHD.
public static void RomSearchFindFixesSHA1CHD(RvFile tRom, List<RvFile> lstFiles, out List<RvFile> lstFilesOut)
{
lstFilesOut = new List<RvFile>();
if (tRom.SHA1CHD == null)
return;
int intIndex;
int intRes = RomSearchSHA1CHD(tRom, lstFiles, out intIndex);
while (intRes == 0)
{
if (lstFiles[intIndex].GotStatus == GotStatus.Got)
lstFilesOut.Add(lstFiles[intIndex]);
intIndex++;
intRes = intIndex < lstFiles.Count ? RomSortSHA1CHDFunc(lstFiles[intIndex], tRom) : 1;
}
}
}
}

105
ROMVault2/DatMaker.cs Normal file
View File

@@ -0,0 +1,105 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.IO;
using ROMVault2.RvDB;
namespace ROMVault2
{
public static class DatMaker
{
private static StreamWriter _sw;
private static string _datName;
private static string _datDir;
public static void MakeDatFromDir(RvDir startingDir)
{
_datName = startingDir.Name;
_datDir = startingDir.Name;
Console.WriteLine("Creating Dat: " + startingDir.Name + ".dat");
_sw = new StreamWriter(startingDir.Name + ".dat");
WriteDatFile(startingDir);
_sw.Close();
Console.WriteLine("Dat creation complete");
Console.ReadLine();
}
private static void WriteDatFile(RvDir dir)
{
WriteLine("<?xml version=\"1.0\"?>");
WriteLine("");
WriteLine("<datafile>");
WriteHeader();
/* write Games/Dirs */
ProcessDir(dir);
WriteLine("</datafile>");
}
private static void WriteHeader()
{
WriteLine(" <header>");
WriteLine(" <name>" + clean(_datName) + "</name>");
WriteLine(" <rootdir>" + clean(_datDir) + "</rootdir>");
WriteLine(" </header>");
}
private static void WriteLine(string s)
{
_sw.WriteLine(s);
}
private static string clean(string s)
{
s = s.Replace("\"", "&quot;");
s = s.Replace("'", "&apos;");
s = s.Replace("<", "&lt;");
s = s.Replace(">", "&gt;");
s = s.Replace("&", "&amp;");
return s;
}
private static void ProcessDir(RvDir dir, int depth = 1)
{
string d = new string(' ', 4 * depth);
for (int i = 0; i < dir.ChildCount; i++)
{
RvDir game = dir.Child(i) as RvDir;
if (game != null && game.FileType == FileType.Zip)
{
WriteLine(d + "<game name=\"" + clean(Path.GetFileNameWithoutExtension(game.Name)) + "\">");
WriteLine(d + " <description>" + clean(Path.GetFileNameWithoutExtension(game.Name)) + "</description>");
for (int j = 0; j < game.ChildCount; j++)
{
RvFile file = game.Child(j) as RvFile;
if (file != null)
{
WriteLine(d + " <rom name=\"" + clean(file.Name) + "\" size=\"" + file.Size + "\" crc=\"" + Utils.ArrByte.ToString(file.CRC) + "\" md5=\"" + Utils.ArrByte.ToString(file.MD5) + "\" sha1=\"" + Utils.ArrByte.ToString(file.SHA1) + "\"/>");
}
}
WriteLine(d + "</game>");
}
if (game != null && game.FileType == FileType.Dir)
{
WriteLine(d + "<dir name=\"" + clean(game.Name) + "\">");
ProcessDir(game, depth + 1);
WriteLine(d + "</dir>");
}
}
}
}
}

View File

@@ -0,0 +1,615 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.ComponentModel;
using System.IO;
using ROMVault2.Properties;
using ROMVault2.RvDB;
using ROMVault2.Utils;
namespace ROMVault2.DatReaders
{
public static class DatCmpReader
{
private static bool _cleanFileNames = true;
public static bool ReadDat(ref RvDir tDat, string strFilename)
{
RvDir tNow = tDat;
FileType thisFileType = FileType.ZipFile;
int errorCode = DatFileLoader.LoadDat(strFilename);
if (errorCode != 0)
{
DatUpdate.ShowDat(new Win32Exception(errorCode).Message, strFilename);
return false;
}
DatFileLoader.Gn();
if (DatFileLoader.EndOfStream())
return false;
if (DatFileLoader.Next.ToLower() == "clrmamepro")
{
_cleanFileNames = true;
DatFileLoader.Gn();
if (!LoadHeaderFromDat(ref tNow, ref thisFileType))
return false;
DatFileLoader.Gn();
}
if (DatFileLoader.Next.ToLower() == "romvault")
{
_cleanFileNames = false;
DatFileLoader.Gn();
if (!LoadHeaderFromDat(ref tNow, ref thisFileType))
return false;
DatFileLoader.Gn();
}
if (tNow.Dat == null)
{
tNow.Dat = new RvDat();
string cleanedName = IO.Path.GetFileNameWithoutExtension(strFilename);
tNow.Dat.AddData(RvDat.DatData.DatName, cleanedName);
tNow.Dat.AddData(RvDat.DatData.Description, cleanedName);
}
while (!DatFileLoader.EndOfStream())
{
switch (DatFileLoader.Next.ToLower())
{
case "dir":
DatFileLoader.Gn();
if (!LoadDirFromDat(ref tNow, ref thisFileType))
return false;
DatFileLoader.Gn();
break;
case "game":
DatFileLoader.Gn();
if (!LoadGameFromDat(ref tNow, false, thisFileType))
return false;
DatFileLoader.Gn();
break;
case "resource":
DatFileLoader.Gn();
if (!LoadGameFromDat(ref tNow, true, thisFileType))
return false;
DatFileLoader.Gn();
break;
case "emulator":
DatFileLoader.Gn();
if (!LoadEmulator())
return false;
DatFileLoader.Gn();
break;
default:
DatUpdate.SendAndShowDat(Resources.DatCmpReader_ReadDat_Error_keyword + DatFileLoader.Next + Resources.DatCmpReader_ReadDat_not_known, DatFileLoader.Filename);
DatFileLoader.Gn();
break;
}
}
DatFileLoader.Close();
return true;
}
private static bool LoadHeaderFromDat(ref RvDir tDir, ref FileType thisFileType)
{
if (DatFileLoader.Next != "(")
{
DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadHeaderFromDat_not_found_after_clrmamepro, DatFileLoader.Filename);
return false;
}
DatFileLoader.Gn();
string forceZipping = "";
RvDat tDat = new RvDat();
while (DatFileLoader.Next != ")")
{
switch (DatFileLoader.Next.ToLower())
{
case "name": tDat.AddData(RvDat.DatData.DatName, VarFix.CleanFileName(DatFileLoader.GnRest())); DatFileLoader.Gn(); break;
case "description": tDat.AddData(RvDat.DatData.Description, DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
case "category": tDat.AddData(RvDat.DatData.Category, DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
case "version": tDat.AddData(RvDat.DatData.Version, DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
case "date": tDat.AddData(RvDat.DatData.Date, DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
case "author": tDat.AddData(RvDat.DatData.Author, DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
case "email": tDat.AddData(RvDat.DatData.Email, DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
case "homepage": tDat.AddData(RvDat.DatData.HomePage, DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
case "url": tDat.AddData(RvDat.DatData.URL, DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
case "comment": DatFileLoader.GnRest(); DatFileLoader.Gn(); break;
case "header": DatFileLoader.GnRest(); DatFileLoader.Gn(); break;
case "forcezipping": forceZipping = DatFileLoader.GnRest(); DatFileLoader.Gn(); break;
case "forcepacking": DatFileLoader.GnRest(); DatFileLoader.Gn(); break; // incorrect usage
case "forcemerging": tDat.AddData(RvDat.DatData.MergeType, DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
case "forcenodump": DatFileLoader.GnRest(); DatFileLoader.Gn(); break;
case "dir": tDat.AddData(RvDat.DatData.DirSetup, DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
default:
DatUpdate.SendAndShowDat(Resources.DatCmpReader_ReadDat_Error_keyword + DatFileLoader.Next + Resources.DatCmpReader_LoadHeaderFromDat_not_known_in_clrmamepro, DatFileLoader.Filename);
DatFileLoader.Gn();
break;
}
}
thisFileType = forceZipping.ToLower() != "no" ? FileType.ZipFile : FileType.File;
tDir.Dat = tDat;
return true;
}
private static bool LoadEmulator()
{
if (DatFileLoader.Next != "(")
{
DatUpdate.SendAndShowDat("( not found after emulator", DatFileLoader.Filename);
return false;
}
DatFileLoader.Gn();
while (DatFileLoader.Next != ")")
{
switch (DatFileLoader.Next.ToLower())
{
case "name": DatFileLoader.GnRest(); DatFileLoader.Gn(); break;
case "version": DatFileLoader.GnRest(); DatFileLoader.Gn(); break;
}
}
return true;
}
private static bool LoadDirFromDat(ref RvDir tDat, ref FileType thisFileType)
{
if (DatFileLoader.Next != "(")
{
DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadGameFromDat_not_found_after_game, DatFileLoader.Filename);
return false;
}
DatFileLoader.Gn();
if (DatFileLoader.Next.ToLower() != "name")
{
DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadGameFromDat_Name_not_found_as_first_object_in, DatFileLoader.Filename);
return false;
}
RvDir parent = tDat;
string fullname = VarFix.CleanFullFileName(DatFileLoader.GnRest());
while (fullname.Contains("/"))
{
int firstSlash = fullname.IndexOf("/", StringComparison.Ordinal);
string dir = fullname.Substring(0, firstSlash);
dir = VarFix.CleanFileName(dir);
fullname = fullname.Substring(firstSlash + 1);
int index;
if (parent.ChildNameSearch(new RvDir(FileType.Dir) { Name = dir }, out index) == 0)
{
parent = (RvDir)parent.Child(index);
}
else
{
RvDir tpDir = new RvDir(FileType.Dir)
{
Name = dir,
DatStatus = DatStatus.InDatCollect,
Dat = tDat.Dat,
Tree = new RvTreeRow()
};
parent.ChildAdd(tpDir, index);
parent = tpDir;
}
}
RvDir tDir = new RvDir(FileType.Dir)
{
Name = fullname
};
DatFileLoader.Gn();
tDir.DatStatus = DatStatus.InDatCollect;
tDir.Dat = tDat.Dat;
int index1;
if (parent.ChildNameSearch(tDir, out index1) == 0)
tDir = (RvDir)parent.Child(index1);
else
parent.ChildAdd(tDir, index1);
while (DatFileLoader.Next != ")")
{
switch (DatFileLoader.Next.ToLower())
{
case "dir":
DatFileLoader.Gn();
if (!LoadDirFromDat(ref tDir, ref thisFileType))
return false;
DatFileLoader.Gn();
break;
case "game":
DatFileLoader.Gn();
if (!LoadGameFromDat(ref tDir, false, thisFileType))
return false;
DatFileLoader.Gn();
break;
case "resource":
DatFileLoader.Gn();
if (!LoadGameFromDat(ref tDir, true, thisFileType))
return false;
DatFileLoader.Gn();
break;
default:
DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadDirFromDat_Error_Keyword + DatFileLoader.Next + Resources.DatCmpReader_LoadDirFromDat_not_know_in_dir, DatFileLoader.Filename);
DatFileLoader.Gn();
break;
}
}
return true;
}
private static bool LoadGameFromDat(ref RvDir tDat, bool bolresource, FileType thisFileType)
{
if (DatFileLoader.Next != "(")
{
DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadGameFromDat_not_found_after_game, DatFileLoader.Filename);
return false;
}
DatFileLoader.Gn();
string snext = DatFileLoader.Next.ToLower();
string pathextra = "";
if (snext == "rebuildto")
{
pathextra = VarFix.CleanFullFileName(DatFileLoader.Gn()); DatFileLoader.Gn();
snext = DatFileLoader.Next.ToLower();
}
if (snext != "name")
{
DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadGameFromDat_Name_not_found_as_first_object_in, DatFileLoader.Filename);
return false;
}
RvDir parent = tDat;
string fullname = VarFix.CleanFullFileName(DatFileLoader.GnRest());
if (_cleanFileNames)
fullname = fullname.Replace("/", "-");
if (!String.IsNullOrEmpty(pathextra))
fullname = pathextra + "/" + fullname;
while (fullname.Contains("/"))
{
int firstSlash = fullname.IndexOf("/", StringComparison.Ordinal);
string dir = fullname.Substring(0, firstSlash);
fullname = fullname.Substring(firstSlash + 1);
int index;
if (parent.ChildNameSearch(new RvDir(FileType.Dir) { Name = dir }, out index) == 0)
{
parent = (RvDir)parent.Child(index);
}
else
{
RvDir tpDir = new RvDir(FileType.Dir)
{
Name = dir,
DatStatus = DatStatus.InDatCollect,
Dat = tDat.Dat,
Tree = new RvTreeRow()
};
parent.ChildAdd(tpDir, index);
parent = tpDir;
}
}
RvDir tDir = new RvDir(thisFileType == FileType.File ? FileType.Dir : FileType.Zip)
{
Name = fullname,
DatStatus = DatStatus.InDatCollect,
Dat = tDat.Dat
};
int index1;
string testName = tDir.Name;
int nameCount = 0;
while (parent.ChildNameSearch(tDir, out index1) == 0)
{
tDir.Name = testName + "_" + nameCount;
nameCount++;
}
DatFileLoader.Gn();
tDir.Game = new RvGame();
tDir.Game.AddData(RvGame.GameData.IsBios, bolresource ? "Yes" : "No");
RvDir tDirCHD = new RvDir(FileType.Dir)
{
Name = tDir.Name,
DatStatus = tDir.DatStatus,
Dat = tDir.Dat,
Game = tDir.Game
};
while (DatFileLoader.Next != ")")
{
switch (DatFileLoader.Next.ToLower())
{
case "romof": tDir.Game.AddData(RvGame.GameData.RomOf, VarFix.CleanFileName(DatFileLoader.GnRest())); DatFileLoader.Gn(); break;
case "description": tDir.Game.AddData(RvGame.GameData.Description, DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
case "sourcefile": tDir.Game.AddData(RvGame.GameData.Sourcefile, DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
case "cloneof": tDir.Game.AddData(RvGame.GameData.CloneOf, DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
case "sampleof": tDir.Game.AddData(RvGame.GameData.SampleOf, DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
case "board": tDir.Game.AddData(RvGame.GameData.Board, DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
case "year": tDir.Game.AddData(RvGame.GameData.Year, DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
case "manufacturer": tDir.Game.AddData(RvGame.GameData.Manufacturer, DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
case "serial": DatFileLoader.GnRest(); DatFileLoader.Gn(); break;
case "rebuildto": DatFileLoader.GnRest(); DatFileLoader.Gn(); break;
case "sample": DatFileLoader.GnRest(); DatFileLoader.Gn(); break;
case "biosset": DatFileLoader.GnRest(); DatFileLoader.Gn(); break;
case "chip": DatFileLoader.GnRest(); DatFileLoader.Gn(); break;
case "video": DatFileLoader.GnRest(); DatFileLoader.Gn(); break;
case "sound": DatFileLoader.GnRest(); DatFileLoader.Gn(); break;
case "input": DatFileLoader.GnRest(); DatFileLoader.Gn(); break;
case "dipswitch": DatFileLoader.GnRest(); DatFileLoader.Gn(); break;
case "driver": DatFileLoader.GnRest(); DatFileLoader.Gn(); break;
case "rom":
DatFileLoader.Gn();
if (!LoadRomFromDat(ref tDir, thisFileType))
return false;
DatFileLoader.Gn();
break;
case "disk":
DatFileLoader.Gn();
if (!LoadDiskFromDat(ref tDirCHD))
return false;
DatFileLoader.Gn();
break;
case "archive":
DatFileLoader.Gn();
if (!LoadArchiveFromDat())
return false;
DatFileLoader.Gn();
break;
default:
DatUpdate.SendAndShowDat(Resources.DatCmpReader_ReadDat_Error_keyword + DatFileLoader.Next + Resources.DatCmpReader_LoadGameFromDat_not_known_in_game, DatFileLoader.Filename);
DatFileLoader.Gn();
break;
}
}
if (tDir.ChildCount > 0)
parent.ChildAdd(tDir, index1);
if (tDirCHD.ChildCount > 0)
parent.ChildAdd(tDirCHD);
return true;
}
private static bool LoadRomFromDat(ref RvDir tGame, FileType thisFileType)
{
if (DatFileLoader.Next != "(")
{
DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadRomFromDat_not_found_after_rom, DatFileLoader.Filename);
return false;
}
DatFileLoader.Gn();
if (DatFileLoader.Next.ToLower() != "name")
{
DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadGameFromDat_Name_not_found_as_first_object_in, DatFileLoader.Filename);
return false;
}
string filename = VarFix.CleanFullFileName(DatFileLoader.Gn());
RvFile tRom = new RvFile(thisFileType) { Name = filename };
DatFileLoader.Gn();
tRom.Dat = tGame.Dat;
while (DatFileLoader.Next != ")")
{
switch (DatFileLoader.Next.ToLower())
{
case "size": tRom.Size = VarFix.ULong(DatFileLoader.Gn()); DatFileLoader.Gn(); break;
case "crc": tRom.CRC = VarFix.CleanMD5SHA1(DatFileLoader.Gn(), 8); DatFileLoader.Gn(); break;
case "sha1": tRom.SHA1 = VarFix.CleanMD5SHA1(DatFileLoader.Gn(), 40); DatFileLoader.Gn(); break;
case "md5": tRom.MD5 = VarFix.CleanMD5SHA1(DatFileLoader.Gn(), 32); DatFileLoader.Gn(); break;
case "merge": tRom.Merge = VarFix.CleanFullFileName(DatFileLoader.Gn()); DatFileLoader.Gn(); break;
case "flags": tRom.Status = VarFix.ToLower(DatFileLoader.Gn()); DatFileLoader.Gn(); break;
case "date": DatFileLoader.Gn(); DatFileLoader.Gn(); break;
case "bios": DatFileLoader.Gn(); DatFileLoader.Gn(); break;
case "region": DatFileLoader.Gn(); DatFileLoader.Gn(); break;
case "offs": DatFileLoader.Gn(); DatFileLoader.Gn(); break;
case "nodump": tRom.Status = "nodump"; DatFileLoader.Gn(); break;
default:
DatUpdate.SendAndShowDat(Resources.DatCmpReader_ReadDat_Error_keyword + DatFileLoader.Next + Resources.DatCmpReader_LoadRomFromDat_not_known_in_rom, DatFileLoader.Filename);
DatFileLoader.Gn();
break;
}
}
if (tRom.Size != null) tRom.FileStatusSet(FileStatus.SizeFromDAT);
if (tRom.CRC != null) tRom.FileStatusSet(FileStatus.CRCFromDAT);
if (tRom.SHA1 != null) tRom.FileStatusSet(FileStatus.SHA1FromDAT);
if (tRom.MD5 != null) tRom.FileStatusSet(FileStatus.MD5FromDAT);
tGame.ChildAdd(tRom);
return true;
}
private static bool LoadDiskFromDat(ref RvDir tGame)
{
if (DatFileLoader.Next != "(")
{
DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadRomFromDat_not_found_after_rom, DatFileLoader.Filename);
return false;
}
DatFileLoader.Gn();
if (DatFileLoader.Next.ToLower() != "name")
{
DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadGameFromDat_Name_not_found_as_first_object_in, DatFileLoader.Filename);
return false;
}
string filename = VarFix.CleanFullFileName(DatFileLoader.Gn());
RvFile tRom = new RvFile(FileType.File) { Name = filename };
DatFileLoader.Gn();
tRom.Dat = tGame.Dat;
while (DatFileLoader.Next != ")")
{
switch (DatFileLoader.Next.ToLower())
{
case "sha1": tRom.SHA1CHD = VarFix.CleanMD5SHA1(DatFileLoader.Gn(), 40); DatFileLoader.Gn(); break;
case "md5": tRom.MD5CHD = VarFix.CleanMD5SHA1(DatFileLoader.Gn(), 32); DatFileLoader.Gn(); break;
case "merge": tRom.Merge = VarFix.CleanFullFileName(DatFileLoader.Gn()); DatFileLoader.Gn(); break;
case "flags": tRom.Status = VarFix.ToLower(DatFileLoader.Gn()); DatFileLoader.Gn(); break;
case "nodump": tRom.Status = "nodump"; DatFileLoader.Gn(); break;
default:
DatUpdate.SendAndShowDat(Resources.DatCmpReader_ReadDat_Error_keyword + DatFileLoader.Next + Resources.DatCmpReader_LoadRomFromDat_not_known_in_rom, DatFileLoader.Filename);
DatFileLoader.Gn();
break;
}
}
if (tRom.SHA1CHD != null) tRom.FileStatusSet(FileStatus.SHA1CHDFromDAT);
if (tRom.MD5CHD != null) tRom.FileStatusSet(FileStatus.MD5CHDFromDAT);
tGame.ChildAdd(tRom);
return true;
}
private static bool LoadArchiveFromDat()
{
if (DatFileLoader.Next != "(")
{
DatUpdate.SendAndShowDat("( not found after Archive", DatFileLoader.Filename);
return false;
}
DatFileLoader.Gn();
while (DatFileLoader.Next != ")")
{
switch (DatFileLoader.Next.ToLower())
{
case "name": DatFileLoader.Gn(); DatFileLoader.Gn(); break;
default:
DatUpdate.SendAndShowDat(Resources.DatCmpReader_ReadDat_Error_keyword + DatFileLoader.Next + " not know in Archive", DatFileLoader.Filename);
DatFileLoader.Gn();
break;
}
}
return true;
}
private static class DatFileLoader
{
public static String Filename { get; private set; }
private static Stream _fileStream;
private static StreamReader _streamReader;
private static string _line = "";
public static string Next;
public static int LoadDat(string strFilename)
{
Filename = strFilename;
_streamReader = null;
int errorCode = IO.FileStream.OpenFileRead(strFilename, out _fileStream);
if (errorCode != 0)
return errorCode;
_streamReader = new StreamReader(_fileStream, Program.Enc);
return 0;
}
public static void Close()
{
_streamReader.Close();
_fileStream.Close();
_streamReader.Dispose();
_fileStream.Dispose();
}
public static bool EndOfStream()
{
return _streamReader.EndOfStream;
}
public static string GnRest()
{
string strret = _line.Replace("\"", "");
_line = "";
Next = strret;
return strret;
}
public static string Gn()
{
string ret;
while ((_line.Trim().Length == 0) && (!_streamReader.EndOfStream))
{
_line = _streamReader.ReadLine();
_line = (_line??"").Replace("" + (char)9, " ");
if (_line.TrimStart().Length > 2 && _line.TrimStart().Substring(0, 2) == @"//") _line = "";
if (_line.TrimStart().Length > 1 && _line.TrimStart().Substring(0, 1) == @"#") _line = "";
if (_line.TrimStart().Length > 1 && _line.TrimStart().Substring(0, 1) == @";") _line = "";
_line = _line.Trim() + " ";
}
if (_line.Trim().Length > 0)
{
int intS;
if (_line.Substring(0, 1) == "\"")
{
intS = (_line + "\"").IndexOf("\"", 1, StringComparison.Ordinal);
ret = _line.Substring(1, intS - 1);
_line = (_line + " ").Substring(intS + 1).Trim();
}
else
{
intS = (_line + " ").IndexOf(" ", StringComparison.Ordinal);
ret = _line.Substring(0, intS);
_line = (_line + " ").Substring(intS).Trim();
}
}
else
{
ret = "";
}
Next = ret;
return ret;
}
}
}
}

View File

@@ -0,0 +1,321 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.ComponentModel;
using System.IO;
using ROMVault2.Properties;
using ROMVault2.RvDB;
using ROMVault2.Utils;
namespace ROMVault2.DatReaders
{
public static class DatDOSReader
{
private static bool _cleanFileNames = true;
public static bool ReadDat(ref RvDir tDat, string strFilename)
{
RvDir tNow = tDat;
FileType thisFileType = FileType.Unknown;
int errorCode = DatFileLoader.LoadDat(strFilename);
if (errorCode != 0)
{
DatUpdate.ShowDat(new Win32Exception(errorCode).Message, strFilename);
return false;
}
DatFileLoader.Gn();
while (!DatFileLoader.EndOfStream())
{
switch (DatFileLoader.Next.ToLower())
{
case "doscenter":
_cleanFileNames = true;
DatFileLoader.Gn();
if (!LoadHeaderFromDat(ref tNow, ref thisFileType))
return false;
DatFileLoader.Gn();
break;
case "game":
DatFileLoader.Gn();
if (!LoadGameFromDat(ref tNow, thisFileType))
return false;
DatFileLoader.Gn();
break;
default:
DatUpdate.SendAndShowDat(Resources.DatCmpReader_ReadDat_Error_keyword + DatFileLoader.Next + Resources.DatCmpReader_ReadDat_not_known, DatFileLoader.Filename);
DatFileLoader.Gn();
break;
}
}
DatFileLoader.Close();
return true;
}
private static bool LoadHeaderFromDat(ref RvDir tDir, ref FileType thisFileType)
{
if (DatFileLoader.Next != "(")
{
DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadHeaderFromDat_not_found_after_clrmamepro, DatFileLoader.Filename);
return false;
}
DatFileLoader.Gn();
RvDat tDat = new RvDat();
while (DatFileLoader.Next != ")")
{
string nextstr = DatFileLoader.Next.ToLower();
if (nextstr.Length > 5 && nextstr.Substring(0, 5) == "name:")
{
tDat.AddData(RvDat.DatData.DatName, VarFix.CleanFileName(DatFileLoader.Next.Substring(5) + " " + DatFileLoader.GnRest()).Trim()); DatFileLoader.Gn();
}
else
{
switch (nextstr)
{
case "name:": tDat.AddData(RvDat.DatData.DatName, VarFix.CleanFileName(DatFileLoader.GnRest())); DatFileLoader.Gn(); break;
case "description:": tDat.AddData(RvDat.DatData.Description , DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
case "version:": tDat.AddData(RvDat.DatData.Version , DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
case "date:": tDat.AddData(RvDat.DatData.Date , DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
case "author:": tDat.AddData(RvDat.DatData.Author , DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
case "homepage:": tDat.AddData(RvDat.DatData.HomePage , DatFileLoader.GnRest()); DatFileLoader.Gn(); break;
case "comment:": DatFileLoader.GnRest(); DatFileLoader.Gn(); break;
default:
DatUpdate.SendAndShowDat(Resources.DatCmpReader_ReadDat_Error_keyword + DatFileLoader.Next + Resources.DatCmpReader_LoadHeaderFromDat_not_known_in_clrmamepro, DatFileLoader.Filename);
DatFileLoader.Gn();
break;
}
}
}
thisFileType = FileType.ZipFile;
tDir.Dat = tDat;
return true;
}
private static bool LoadGameFromDat(ref RvDir tDat, FileType thisFileType)
{
if (DatFileLoader.Next != "(")
{
DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadGameFromDat_not_found_after_game, DatFileLoader.Filename);
return false;
}
DatFileLoader.Gn();
string snext = DatFileLoader.Next.ToLower();
if (snext != "name")
{
DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadGameFromDat_Name_not_found_as_first_object_in, DatFileLoader.Filename);
return false;
}
RvDir parent = tDat;
string fullname = VarFix.CleanFullFileName(DatFileLoader.GnRest());
if (_cleanFileNames)
fullname = fullname.Replace("/", "-");
while (fullname.Contains("/"))
{
int firstSlash = fullname.IndexOf("/", StringComparison.Ordinal);
string dir = fullname.Substring(0, firstSlash);
fullname = fullname.Substring(firstSlash + 1);
int index;
if (parent.ChildNameSearch(new RvDir(FileType.Dir) { Name = dir }, out index) == 0)
{
parent = (RvDir)parent.Child(index);
}
else
{
RvDir tpDir = new RvDir(FileType.Dir)
{
Name = dir,
DatStatus = DatStatus.InDatCollect,
Dat = tDat.Dat,
Tree = new RvTreeRow()
};
parent.ChildAdd(tpDir, index);
parent = tpDir;
}
}
if (fullname.Length > 4 && fullname.ToLower().Substring(fullname.Length - 4, 4) == ".zip")
fullname = fullname.Substring(0, fullname.Length - 4);
RvDir tDir = new RvDir(thisFileType == FileType.File ? FileType.Dir : FileType.Zip) { Name = fullname };
DatFileLoader.Gn();
tDir.Game = new RvGame();
tDir.DatStatus = DatStatus.InDatCollect;
tDir.Dat = tDat.Dat;
int index1;
string testName = tDir.Name;
int nameCount = 0;
while (parent.ChildNameSearch(tDir, out index1) == 0)
{
tDir.Name = testName + "_" + nameCount;
nameCount++;
}
parent.ChildAdd(tDir, index1);
while (DatFileLoader.Next != ")")
{
switch (DatFileLoader.Next.ToLower())
{
case "file":
DatFileLoader.Gn();
if (!LoadRomFromDat(ref tDir, thisFileType))
return false;
DatFileLoader.Gn();
break;
default:
DatUpdate.SendAndShowDat(Resources.DatCmpReader_ReadDat_Error_keyword + DatFileLoader.Next + Resources.DatCmpReader_LoadGameFromDat_not_known_in_game, DatFileLoader.Filename);
DatFileLoader.Gn();
break;
}
}
return true;
}
private static bool LoadRomFromDat(ref RvDir tGame, FileType thisFileType)
{
if (DatFileLoader.Next != "(")
{
DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadRomFromDat_not_found_after_rom, DatFileLoader.Filename);
return false;
}
string line=DatFileLoader.GnRest();
string linelc = line.ToLower();
int posName = linelc.IndexOf("name ", StringComparison.Ordinal);
int posSize = linelc.IndexOf(" size ", posName+5,StringComparison.Ordinal);
int posDate = linelc.IndexOf(" date ", posSize+6,StringComparison.Ordinal);
int posCrc = linelc.IndexOf(" crc ", posDate+6,StringComparison.Ordinal);
int posEnd = linelc.IndexOf(" )", posCrc+5,StringComparison.Ordinal);
if (posName < 0 || posSize < 0 || posDate < 0 || posCrc < 0 || posEnd < 0)
{
DatFileLoader.Gn();
return false;
}
string name = line.Substring(posName + 5, posSize - (posName + 5));
string size = line.Substring(posSize + 6, posDate - (posSize + 6));
//string date = line.Substring(posDate + 6, posCrc - (posDate + 6));
string crc = line.Substring(posCrc + 5, posEnd - (posCrc + 5));
RvFile tRom = new RvFile(thisFileType)
{
Dat = tGame.Dat,
Name = VarFix.CleanFullFileName(name.Trim()),
Size = VarFix.ULong(size.Trim()),
CRC = VarFix.CleanMD5SHA1(crc.Trim(), 8)
};
if (tRom.Size != null) tRom.FileStatusSet(FileStatus.SizeFromDAT);
if (tRom.CRC != null) tRom.FileStatusSet(FileStatus.CRCFromDAT);
tGame.ChildAdd(tRom);
return true;
}
private static class DatFileLoader
{
public static String Filename { get; private set; }
private static Stream _fileStream;
private static StreamReader _streamReader;
private static string _line = "";
public static string Next;
public static int LoadDat(string strFilename)
{
Filename = strFilename;
_streamReader = null;
int errorCode = IO.FileStream.OpenFileRead(strFilename, out _fileStream);
if (errorCode != 0)
return errorCode;
_streamReader = new StreamReader(_fileStream, Program.Enc);
return 0;
}
public static void Close()
{
_streamReader.Close();
_fileStream.Close();
_streamReader.Dispose();
_fileStream.Dispose();
}
public static bool EndOfStream()
{
return _streamReader.EndOfStream;
}
public static string GnRest()
{
string strret = _line.Replace("\"", "");
_line = "";
Next = strret;
return strret;
}
public static void Gn()
{
string ret;
while ((_line.Trim().Length == 0) && (!_streamReader.EndOfStream))
{
_line = _streamReader.ReadLine();
if (String.IsNullOrEmpty(_line)) _line = "";
_line = _line.Replace("" + (char)9, " ");
_line = _line.Trim() + " ";
}
if (_line.Trim().Length > 0)
{
int intS;
if (_line.Substring(0, 1) == "\"")
{
intS = (_line + "\"").IndexOf("\"", 1, StringComparison.Ordinal);
ret = _line.Substring(1, intS - 1);
_line = (_line + " ").Substring(intS + 1).Trim();
}
else
{
intS = (_line + " ").IndexOf(" ", StringComparison.Ordinal);
ret = _line.Substring(0, intS);
_line = (_line + " ").Substring(intS).Trim();
}
}
else
{
ret = "";
}
Next = ret;
}
}
}
}

View File

@@ -0,0 +1,223 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System.Xml;
using ROMVault2.RvDB;
using ROMVault2.Utils;
namespace ROMVault2.DatReaders
{
public static class DatMessXmlReader
{
private static int _indexContinue;
public static bool ReadDat(ref RvDir tDat, XmlDocument doc)
{
if (!LoadHeaderFromDat(ref tDat, ref doc))
return false;
if (doc.DocumentElement == null)
return false;
XmlNodeList gameNodeList = doc.DocumentElement.SelectNodes("software");
if (gameNodeList == null)
return false;
for (int i = 0; i < gameNodeList.Count; i++)
{
LoadGameFromDat(ref tDat, gameNodeList[i]);
}
return true;
}
private static bool LoadHeaderFromDat(ref RvDir tDir, ref XmlDocument doc)
{
XmlNodeList head = doc.SelectNodes("softwarelist");
if (head == null)
return false;
if (head.Count == 0)
return false;
if (head[0].Attributes == null)
return false;
RvDat tDat = new RvDat();
tDat.AddData(RvDat.DatData.DatName, VarFix.CleanFileName(head[0].Attributes.GetNamedItem("name")));
tDat.AddData(RvDat.DatData.Description, VarFix.String(head[0].Attributes.GetNamedItem("description")));
string val = VarFix.String(head[0].Attributes.GetNamedItem("forcemerging")).ToLower();
switch (val.ToLower())
{
case "split":
tDat.AddData(RvDat.DatData.MergeType, "split");
break;
case "full":
tDat.AddData(RvDat.DatData.MergeType, "full");
break;
default:
tDat.AddData(RvDat.DatData.MergeType, "split");
break;
}
tDir.Dat = tDat;
return true;
}
private static void LoadGameFromDat(ref RvDir tDat, XmlNode gameNode)
{
if (gameNode.Attributes == null)
return;
RvDir parent = tDat;
RvDir tDir = new RvDir(FileType.Zip)
{
Name = VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("name")),
Game = new RvGame(),
Dat = tDat.Dat,
DatStatus = DatStatus.InDatCollect
};
tDir.Game.AddData(RvGame.GameData.Description, VarFix.String(gameNode.SelectSingleNode("description")));
tDir.Game.AddData(RvGame.GameData.RomOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("cloneof")));
tDir.Game.AddData(RvGame.GameData.CloneOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("cloneof")));
tDir.Game.AddData(RvGame.GameData.Year, VarFix.CleanFileName(gameNode.SelectSingleNode("year")));
tDir.Game.AddData(RvGame.GameData.Manufacturer, VarFix.CleanFileName(gameNode.SelectSingleNode("publisher")));
RvDir tDirCHD = new RvDir(FileType.Dir)
{
Name = VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("name")),
Game = new RvGame(),
Dat = tDat.Dat,
DatStatus = DatStatus.InDatCollect
};
tDirCHD.Game.AddData(RvGame.GameData.Description, VarFix.String(gameNode.SelectSingleNode("description")));
tDirCHD.Game.AddData(RvGame.GameData.RomOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("cloneof")));
tDirCHD.Game.AddData(RvGame.GameData.CloneOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("cloneof")));
tDirCHD.Game.AddData(RvGame.GameData.Year, VarFix.CleanFileName(gameNode.SelectSingleNode("year")));
tDirCHD.Game.AddData(RvGame.GameData.Manufacturer, VarFix.CleanFileName(gameNode.SelectSingleNode("publisher")));
int index1;
string testName = tDir.Name;
int nameCount = 0;
while (parent.ChildNameSearch(tDir, out index1) == 0)
{
tDir.Name = testName + "_" + nameCount;
nameCount++;
}
tDirCHD.Name = tDir.Name;
XmlNodeList partNodeList = gameNode.SelectNodes("part");
if (partNodeList == null) return;
for (int iP = 0; iP < partNodeList.Count; iP++)
{
_indexContinue = -1;
XmlNodeList dataAreaNodeList = partNodeList[iP].SelectNodes("dataarea");
if (dataAreaNodeList != null)
for (int iD = 0; iD < dataAreaNodeList.Count; iD++)
{
XmlNodeList romNodeList = dataAreaNodeList[iD].SelectNodes("rom");
if (romNodeList != null)
for (int iR = 0; iR < romNodeList.Count; iR++)
{
LoadRomFromDat(ref tDir, romNodeList[iR]);
}
}
}
for (int iP = 0; iP < partNodeList.Count; iP++)
{
XmlNodeList diskAreaNodeList = partNodeList[iP].SelectNodes("diskarea");
if (diskAreaNodeList != null)
for (int iD = 0; iD < diskAreaNodeList.Count; iD++)
{
XmlNodeList romNodeList = diskAreaNodeList[iD].SelectNodes("disk");
if (romNodeList != null)
for (int iR = 0; iR < romNodeList.Count; iR++)
{
LoadDiskFromDat(ref tDirCHD, romNodeList[iR]);
}
}
}
if (tDir.ChildCount > 0)
parent.ChildAdd(tDir, index1);
if (tDirCHD.ChildCount > 0)
parent.ChildAdd(tDirCHD, index1);
}
private static void LoadRomFromDat(ref RvDir tGame, XmlNode romNode)
{
if (romNode.Attributes == null)
return;
XmlNode name = romNode.Attributes.GetNamedItem("name");
string loadflag = VarFix.String(romNode.Attributes.GetNamedItem("loadflag"));
if (name != null)
{
RvFile tRom = new RvFile(FileType.ZipFile)
{
Name = VarFix.CleanFullFileName(name),
Size = VarFix.ULong(romNode.Attributes.GetNamedItem("size")),
CRC = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("crc"), 8),
SHA1 = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("sha1"), 40),
Status = VarFix.ToLower(romNode.Attributes.GetNamedItem("status")),
Dat = tGame.Dat
};
if (tRom.Size != null) tRom.FileStatusSet(FileStatus.SizeFromDAT);
if (tRom.CRC != null) tRom.FileStatusSet(FileStatus.CRCFromDAT);
if (tRom.SHA1 != null) tRom.FileStatusSet(FileStatus.SHA1FromDAT);
_indexContinue = tGame.ChildAdd(tRom);
}
else if (loadflag.ToLower() == "continue")
{
RvFile tZippedFile = (RvFile)tGame.Child(_indexContinue);
tZippedFile.Size += VarFix.ULong(romNode.Attributes.GetNamedItem("size"));
}
}
private static void LoadDiskFromDat(ref RvDir tGame, XmlNode romNode)
{
if (romNode.Attributes == null)
return;
XmlNode name = romNode.Attributes.GetNamedItem("name");
RvFile tRom = new RvFile(FileType.File)
{
Name = VarFix.CleanFullFileName(name) + ".chd",
SHA1CHD = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("sha1"), 40),
Status = VarFix.ToLower(romNode.Attributes.GetNamedItem("status")),
Dat = tGame.Dat
};
if (tRom.SHA1CHD != null) tRom.FileStatusSet(FileStatus.SHA1CHDFromDAT);
tGame.ChildAdd(tRom);
}
}
}

View File

@@ -0,0 +1,601 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Xml;
using ROMVault2.RvDB;
using ROMVault2.Utils;
namespace ROMVault2.DatReaders
{
public static class DatReader
{
private static BackgroundWorker _bgw;
public static RvDir ReadInDatFile(RvDat datFile, BackgroundWorker bgw)
{
_bgw = bgw;
RvDir newDir = new RvDir(FileType.Dir);
string datFullName = datFile.GetData(RvDat.DatData.DatFullName);
System.IO.Stream fs;
int errorCode = IO.FileStream.OpenFileRead(datFullName, out fs);
if (errorCode != 0)
{
_bgw.ReportProgress(0, new bgwShowError(datFullName, errorCode + ": " + new Win32Exception(errorCode).Message));
return null;
}
System.IO.StreamReader myfile = new System.IO.StreamReader(fs, Program.Enc);
string strLine = myfile.ReadLine();
myfile.Close();
fs.Close();
fs.Dispose();
if (strLine == null)
return null;
if (strLine.ToLower().IndexOf("xml", StringComparison.Ordinal) >= 0)
{
if (!ReadXMLDat(ref newDir, datFullName))
return null;
}
else if (strLine.ToLower().IndexOf("clrmamepro", StringComparison.Ordinal) >= 0 || strLine.ToLower().IndexOf("romvault", StringComparison.Ordinal) >= 0 || strLine.ToLower().IndexOf("game", StringComparison.Ordinal) >= 0)
{
if (!DatCmpReader.ReadDat(ref newDir, datFullName))
return null;
}
else if (strLine.ToLower().IndexOf("doscenter", StringComparison.Ordinal) >= 0)
{
if (!DatDOSReader.ReadDat(ref newDir, datFullName))
return null;
}
else
{
_bgw.ReportProgress(0, new bgwShowError(datFullName, "Invalid DAT File"));
return null;
}
if (newDir.Dat == null)
{
_bgw.ReportProgress(0, new bgwShowError(datFullName, "Invalid Header"));
return null;
}
newDir.Dat.AddData(RvDat.DatData.DatFullName, datFullName);
newDir.Dat.TimeStamp = datFile.TimeStamp;
newDir.Dat.Status = DatUpdateStatus.Correct;
DatSetRemoveUnneededDirs(newDir);
DatSetCheckParentSets(newDir);
DatSetRenameAndRemoveDups(newDir);
if (newDir.Dat.GetData(RvDat.DatData.MergeType).ToLower() == "full")
DatSetMergeSets(newDir);
DatSetCheckCollect(newDir);
DatSetCreateSubDirs(newDir);
if (newDir.Dat.GetData(RvDat.DatData.DirSetup).ToLower() == "nogame")
{
DatSetRemoveGameDir(newDir);
}
return newDir;
}
private static bool ReadXMLDat(ref RvDir tDat, string strFilename)
{
System.IO.Stream fs;
int errorCode = IO.FileStream.OpenFileRead(strFilename, out fs);
if (errorCode != 0)
{
_bgw.ReportProgress(0, new bgwShowError(strFilename, errorCode + ": " + new Win32Exception(errorCode).Message));
return false;
}
XmlDocument doc = new XmlDocument { XmlResolver = null };
try
{
doc.Load(fs);
}
catch (Exception e)
{
fs.Close();
fs.Dispose();
string message = string.Format("Error Occured Reading Dat: {0}\r\nSource: {1}\r\nMessage: {2}\r\n", strFilename, e.Source, e.Message);
if (e.InnerException != null)
message += string.Format("\r\nINNER EXCEPTION:\r\nSource: {0}\r\nMessage: {1}\r\n", e.InnerException.Source, e.InnerException.Message);
ReportError.SendErrorMessageDat(message, strFilename);
_bgw.ReportProgress(0, new bgwShowError(strFilename, string.Format("Error Occured Reading Dat:\r\n{0}\r\n", e.Message)));
return false;
}
fs.Close();
fs.Dispose();
if (doc.DocumentElement == null)
return false;
XmlNode mame = doc.SelectSingleNode("mame");
if (mame != null)
return DatXmlReader.ReadMameDat(ref tDat, doc);
if (doc.DocumentElement != null)
{
XmlNode head = doc.DocumentElement.SelectSingleNode("header");
if (head != null)
return DatXmlReader.ReadDat(ref tDat, doc);
}
XmlNodeList headList = doc.SelectNodes("softwarelist");
if (headList != null)
return DatMessXmlReader.ReadDat(ref tDat, doc);
return false;
}
private static void DatSetRenameAndRemoveDups(RvDir tDat)
{
for (int g = 0; g < tDat.ChildCount; g++)
{
RvDir tDir = (RvDir)tDat.Child(g);
if (tDir.Game == null)
{
DatSetRenameAndRemoveDups(tDir);
}
else
{
for (int r = 0; r < tDir.ChildCount - 1; r++)
{
RvFile f0 = (RvFile)tDir.Child(r);
RvFile f1 = (RvFile)tDir.Child(r + 1);
if (f0.Name != f1.Name)
continue;
if (f0.Size != f1.Size || !ArrByte.bCompare(f0.CRC, f1.CRC))
{
tDir.ChildRemove(r + 1); // remove F1
f1.Name = f1.Name + "_" + ArrByte.ToString(f1.CRC); // rename F1;
int pos = tDir.ChildAdd(f1);
if (pos < r)
r = pos;
// if this rename moved the File back up the list, start checking again from that file.
}
else
{
tDir.ChildRemove(r + 1);
}
r--;
}
}
}
}
private static void DatSetRemoveUnneededDirs(RvDir tDat)
{
for (int g = 0; g < tDat.ChildCount; g++)
{
RvDir tGame = (RvDir)tDat.Child(g);
if (tGame.Game == null)
{
DatSetRemoveUnneededDirs(tGame);
}
else
{
for (int r = 0; r < tGame.ChildCount - 1; r++)
{
// first find any directories, zero length with filename ending in a '/'
// there are RvFiles that are really directories (probably inside a zip file)
RvFile f0 = (RvFile)tGame.Child(r);
if (f0.Name.Length == 0)
continue;
if (f0.Name.Substring(f0.Name.Length - 1, 1) != "/")
continue;
// if the next file contains that found directory, then the directory file can be deleted
RvFile f1 = (RvFile)tGame.Child(r + 1);
if (f1.Name.Length <= f0.Name.Length)
continue;
if (f0.Name != f1.Name.Substring(0, f0.Name.Length))
continue;
tGame.ChildRemove(r);
r--;
}
}
}
}
private static void DatSetCheckParentSets(RvDir tDat)
{
// First we are going to try and fix any missing CRC information by checking for roms with the same names
// in Parent and Child sets, and if the same named rom is found and one has a CRC and the other does not
// then we will set the missing CRC by using the CRC in the other set.
// we keep trying to find fixes until no more fixes are found.
// this is need as the first time round a fix could be found in a parent set from one child set.
// then the second time around that fixed parent set could fix another of its childs sets.
for (int g = 0; g < tDat.ChildCount; g++)
{
RvDir mGame = (RvDir)tDat.Child(g);
if (mGame.Game == null)
// this is a directory so recuse into it
DatSetCheckParentSets(mGame);
}
bool fix = true;
while (fix)
{
fix = false;
// loop around every ROM Set looking for fixes.
for (int g = 0; g < tDat.ChildCount; g++)
{
// get a list of that ROM Sets parents.
RvDir mGame = (RvDir)tDat.Child(g);
if (mGame.Game == null)
continue;
List<RvDir> lstParentGames = new List<RvDir>();
FindParentSet(mGame, tDat, ref lstParentGames);
// if this set have parents
if (lstParentGames.Count == 0)
continue;
// now loop every ROM in the current set.
for (int r = 0; r < mGame.ChildCount; r++)
{
// and loop every ROM of every parent set of this current set.
// and see if anything can be fixed.
bool found = false;
// loop the parent sets
foreach (RvDir romofGame in lstParentGames)
{
// loop the ROMs in the parent sets
for (int r1 = 0; r1 < romofGame.ChildCount; r1++)
{
// only find fixes if the Name and the Size of the ROMs are the same
if (mGame.Child(r).Name != romofGame.Child(r1).Name || ((RvFile)mGame.Child(r)).Size != ((RvFile)romofGame.Child(r1)).Size)
continue;
// now check if one of the matching roms has missing or incorrect CRC information
bool b1 = ((RvFile)mGame.Child(r)).CRC == null;
bool b2 = ((RvFile)romofGame.Child(r1)).CRC == null;
// if one has correct information and the other does not, fix the missing one
if (b1 == b2)
continue;
if (b1)
{
((RvFile)mGame.Child(r)).CRC = ((RvFile)romofGame.Child(r1)).CRC;
((RvFile)mGame.Child(r)).Status = "(CRCFound)";
}
else
{
((RvFile)romofGame.Child(r1)).CRC = ((RvFile)mGame.Child(r)).CRC;
((RvFile)romofGame.Child(r1)).Status = "(CRCFound)";
}
// flag that a fix was found so that we will go all the way around again.
fix = true;
found = true;
break;
}
if (found) break;
}
}
}
}
}
private static void DatSetMergeSets(RvDir tDat)
{
for (int g = tDat.ChildCount - 1; g >= 0; g--)
{
RvDir mGame = (RvDir)tDat.Child(g);
if (mGame.Game == null)
{
DatSetMergeSets(mGame);
continue;
}
List<RvDir> lstParentGames = new List<RvDir>();
FindParentSet(mGame, tDat, ref lstParentGames);
while (lstParentGames.Count > 0 && lstParentGames[lstParentGames.Count - 1].Game.GetData(RvGame.GameData.IsBios).ToLower() == "yes")
lstParentGames.RemoveAt(lstParentGames.Count - 1);
if (lstParentGames.Count <= 0) continue;
RvDir romofGame = lstParentGames[lstParentGames.Count - 1];
bool founderror = false;
for (int r = 0; r < mGame.ChildCount; r++)
{
string name = mGame.Child(r).Name;
string mergename = ((RvFile)mGame.Child(r)).Merge;
for (int r1 = 0; r1 < romofGame.ChildCount; r1++)
{
if ((name == romofGame.Child(r1).Name || mergename == romofGame.Child(r1).Name) &&
(ArrByte.iCompare(((RvFile)mGame.Child(r)).CRC, ((RvFile)romofGame.Child(r1)).CRC) != 0 ||
((RvFile)mGame.Child(r)).Size != ((RvFile)romofGame.Child(r1)).Size))
founderror = true;
}
}
if (founderror)
{
mGame.Game.DeleteData(RvGame.GameData.RomOf);
continue;
}
for (int r = 0; r < mGame.ChildCount; r++)
{
string name = mGame.Child(r).Name;
string mergename = ((RvFile)mGame.Child(r)).Merge;
bool found = false;
for (int r1 = 0; r1 < romofGame.ChildCount; r1++)
{
if ((name == romofGame.Child(r1).Name || mergename == romofGame.Child(r1).Name) &&
(ArrByte.iCompare(((RvFile)mGame.Child(r)).CRC, ((RvFile)romofGame.Child(r1)).CRC) == 0 &&
((RvFile)mGame.Child(r)).Size == ((RvFile)romofGame.Child(r1)).Size))
{
found = true;
break;
}
}
if (!found)
romofGame.ChildAdd(mGame.Child(r));
}
tDat.ChildRemove(g);
}
}
private static void DatSetCheckCollect(RvDir tDat)
{
// now look for merged roms.
// check if a rom exists in a parent set where the Name,Size and CRC all match.
for (int g = 0; g < tDat.ChildCount; g++)
{
RvDir mGame = (RvDir)tDat.Child(g);
if (mGame.Game == null)
DatSetCheckCollect(mGame);
else
{
List<RvDir> lstParentGames = new List<RvDir>();
FindParentSet(mGame, tDat, ref lstParentGames);
if (lstParentGames.Count == 0)
{
for (int r = 0; r < mGame.ChildCount; r++)
RomCheckCollect((RvFile)mGame.Child(r), false);
}
else
{
for (int r = 0; r < mGame.ChildCount; r++)
{
bool found = false;
foreach (RvDir romofGame in lstParentGames)
{
for (int r1 = 0; r1 < romofGame.ChildCount; r1++)
{
if (mGame.Child(r).Name != romofGame.Child(r1).Name) continue;
ulong? Size0 = ((RvFile)mGame.Child(r)).Size;
ulong? Size1 = ((RvFile)romofGame.Child(r1)).Size;
if (Size0 != null && Size1 != null && Size0 != Size1) continue;
byte[] CRC0 = ((RvFile)mGame.Child(r)).CRC;
byte[] CRC1 = ((RvFile)romofGame.Child(r1)).CRC;
if (CRC0 != null && CRC1 != null && !ArrByte.bCompare(CRC0, CRC1)) continue;
byte[] SHA0 = ((RvFile)mGame.Child(r)).SHA1;
byte[] SHA1 = ((RvFile)romofGame.Child(r1)).SHA1;
if (SHA0 != null && SHA1 != null && !ArrByte.bCompare(SHA0, SHA1)) continue;
byte[] MD50 = ((RvFile)mGame.Child(r)).MD5;
byte[] MD51 = ((RvFile)romofGame.Child(r1)).MD5;
if (MD50 != null && MD51 != null && !ArrByte.bCompare(MD50, MD51)) continue;
byte[] chdSHA0 = ((RvFile)mGame.Child(r)).SHA1CHD;
byte[] chdSHA1 = ((RvFile)romofGame.Child(r1)).SHA1CHD;
if (chdSHA0 != null && chdSHA1 != null && !ArrByte.bCompare(chdSHA0, chdSHA1)) continue;
byte[] chdMD50 = ((RvFile)mGame.Child(r)).MD5CHD;
byte[] chdMD51 = ((RvFile)romofGame.Child(r1)).MD5CHD;
if (chdMD50 != null && chdMD51 != null && !ArrByte.bCompare(chdMD50, chdMD51)) continue;
found = true;
break;
}
if (found) break;
}
RomCheckCollect((RvFile)mGame.Child(r), found);
}
}
}
}
}
private static void FindParentSet(RvDir searchGame, RvDir parentDir, ref List<RvDir> lstParentGames)
{
if (searchGame.Game == null)
return;
string parentName = searchGame.Game.GetData(RvGame.GameData.RomOf);
if (String.IsNullOrEmpty(parentName) || parentName==searchGame.Name)
parentName = searchGame.Game.GetData(RvGame.GameData.CloneOf);
if (String.IsNullOrEmpty(parentName) || parentName==searchGame.Name)
return;
int intIndex;
int intResult = parentDir.ChildNameSearch(new RvDir(searchGame.FileType) { Name = parentName }, out intIndex);
if (intResult == 0)
{
RvDir parentGame = (RvDir)parentDir.Child(intIndex);
lstParentGames.Add(parentGame);
FindParentSet(parentGame, parentDir, ref lstParentGames);
}
}
/*
* In the mame Dat:
* status="nodump" has a size but no CRC
* status="baddump" has a size and crc
*/
private static void RomCheckCollect(RvFile tRom, bool merge)
{
if (merge)
{
if (string.IsNullOrEmpty(tRom.Merge))
tRom.Merge = "(Auto Merged)";
tRom.DatStatus = DatStatus.InDatMerged;
return;
}
if (!string.IsNullOrEmpty(tRom.Merge))
tRom.Merge = "(No-Merge) " + tRom.Merge;
if (tRom.Status == "nodump")
{
tRom.CRC = null;
tRom.DatStatus = DatStatus.InDatBad;
return;
}
if (ArrByte.bCompare(tRom.CRC, new byte[] { 0, 0, 0, 0 }) && tRom.Size == 0)
{
tRom.DatStatus = DatStatus.InDatCollect;
return;
}
/*
if (ArrByte.bCompare(tRom.CRC, new byte[] { 0, 0, 0, 0 }) || (tRom.CRC.Length != 8))
{
tRom.CRC = null;
tRom.DatStatus = DatStatus.InDatBad;
return;
}
*/
tRom.DatStatus = DatStatus.InDatCollect;
}
private static void DatSetCreateSubDirs(RvDir tDat)
{
for (int g = 0; g < tDat.ChildCount; g++)
{
if (tDat.Child(g).FileType == FileType.Zip)
continue;
RvDir datGame = (RvDir)tDat.Child(g);
// first do a quick check to see if anything needs done.
bool fixNeeded = false;
for (int r = 0; r < datGame.ChildCount; r++)
{
fixNeeded = datGame.Child(r).Name.Contains("/");
if (fixNeeded)
break;
}
// if nothing needs done skip to next game
if (!fixNeeded)
continue;
RvDir fixedGame = new RvDir(FileType.Dir);
while (datGame.ChildCount > 0)
{
RvBase nextChild = datGame.Child(0);
datGame.ChildRemove(0);
if (nextChild.GetType() == typeof(RvFile))
{
RvFile tFile = (RvFile)nextChild;
if (tFile.Name.Contains("/"))
{
RvDir tBase = fixedGame;
Debug.WriteLine("tFile " + tFile.TreeFullName);
while (tFile.Name.Contains("/"))
{
int dirIndex = tFile.Name.IndexOf("/", StringComparison.Ordinal);
string dirName = tFile.Name.Substring(0, dirIndex);
RvDir tDir = new RvDir(FileType.Dir)
{
Name = dirName,
DatStatus = DatStatus.InDatCollect,
Dat = datGame.Dat
};
int index;
if (tBase.ChildNameSearch(tDir, out index) != 0)
tBase.ChildAdd(tDir, index);
tBase = (RvDir)tBase.Child(index);
tFile.Name = tFile.Name.Substring(tFile.Name.IndexOf("/", StringComparison.Ordinal) + 1);
}
tBase.ChildAdd(tFile);
}
else
fixedGame.ChildAdd(nextChild);
}
else
fixedGame.ChildAdd(nextChild);
}
for (int r = 0; r < fixedGame.ChildCount; r++)
datGame.ChildAdd(fixedGame.Child(r), r);
}
}
private static void DatSetRemoveGameDir(RvDir newDir)
{
if (newDir.ChildCount != 1)
return;
RvDir child = newDir.Child(0) as RvDir;
if (child.FileType != FileType.Dir)
return;
if (child.Game == null)
return;
newDir.ChildRemove(0);
newDir.Game = child.Game;
for (int i = 0; i < child.ChildCount; i++)
newDir.ChildAdd(child.Child(i), i);
}
}
}

View File

@@ -0,0 +1,410 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Xml;
using ROMVault2.RvDB;
using ROMVault2.Utils;
namespace ROMVault2.DatReaders
{
public static class DatXmlReader
{
private static bool _cleanFileNames = true;
public static bool ReadDat(ref RvDir tDat, XmlDocument doc)
{
FileType thisFileType = FileType.Unknown;
if (!LoadHeaderFromDat(ref tDat, ref doc, ref thisFileType))
return false;
if (doc.DocumentElement == null)
return false;
XmlNodeList dirNodeList = doc.DocumentElement.SelectNodes("dir");
if (dirNodeList != null)
{
for (int i = 0; i < dirNodeList.Count; i++)
{
LoadDirFromDat(ref tDat, dirNodeList[i], thisFileType);
}
}
XmlNodeList gameNodeList = doc.DocumentElement.SelectNodes("game");
if (gameNodeList != null)
{
for (int i = 0; i < gameNodeList.Count; i++)
{
LoadGameFromDat(ref tDat, gameNodeList[i], thisFileType);
}
}
return true;
}
public static bool ReadMameDat(ref RvDir tDat, XmlDocument doc)
{
FileType thisFileType = FileType.Unknown;
if (!LoadMameHeaderFromDat(ref tDat, ref doc, ref thisFileType))
return false;
if (doc.DocumentElement == null)
return false;
XmlNodeList dirNodeList = doc.DocumentElement.SelectNodes("dir");
if (dirNodeList != null)
{
for (int i = 0; i < dirNodeList.Count; i++)
{
LoadDirFromDat(ref tDat, dirNodeList[i], thisFileType);
}
}
XmlNodeList gameNodeList = doc.DocumentElement.SelectNodes("game");
if (gameNodeList != null)
{
for (int i = 0; i < gameNodeList.Count; i++)
{
LoadGameFromDat(ref tDat, gameNodeList[i], thisFileType);
}
}
return true;
}
private static bool LoadHeaderFromDat(ref RvDir tDir, ref XmlDocument doc, ref FileType thisFileType)
{
if (doc.DocumentElement == null)
return false;
XmlNode head = doc.DocumentElement.SelectSingleNode("header");
if (head == null)
return false;
RvDat tDat = new RvDat();
tDat.AddData(RvDat.DatData.DatName, VarFix.CleanFileName(head.SelectSingleNode("name")));
tDat.AddData(RvDat.DatData.RootDir, VarFix.CleanFileName(head.SelectSingleNode("rootdir")));
tDat.AddData(RvDat.DatData.Description, VarFix.String(head.SelectSingleNode("description")));
tDat.AddData(RvDat.DatData.Category, VarFix.String(head.SelectSingleNode("category")));
tDat.AddData(RvDat.DatData.Version, VarFix.String(head.SelectSingleNode("version")));
tDat.AddData(RvDat.DatData.Date, VarFix.String(head.SelectSingleNode("date")));
tDat.AddData(RvDat.DatData.Author, VarFix.String(head.SelectSingleNode("author")));
tDat.AddData(RvDat.DatData.Email, VarFix.String(head.SelectSingleNode("email")));
tDat.AddData(RvDat.DatData.HomePage, VarFix.String(head.SelectSingleNode("homepage")));
tDat.AddData(RvDat.DatData.URL, VarFix.String(head.SelectSingleNode("url")));
string superDAT = VarFix.String(head.SelectSingleNode("type"));
_cleanFileNames = superDAT.ToLower() != "superdat" && superDAT.ToLower() != "gigadat";
if (!_cleanFileNames) tDat.AddData(RvDat.DatData.SuperDat, "superdat");
thisFileType = FileType.ZipFile;
// Look for: <romvault forcepacking="unzip"/>
XmlNode packingNode = head.SelectSingleNode("romvault");
if (packingNode == null)
// Look for: <clrmamepro forcepacking="unzip"/>
packingNode = head.SelectSingleNode("clrmamepro");
if (packingNode != null)
{
if (packingNode.Attributes != null)
{
string val = VarFix.String(packingNode.Attributes.GetNamedItem("forcepacking")).ToLower();
switch (val.ToLower())
{
case "zip":
tDat.AddData(RvDat.DatData.FileType, "zip");
thisFileType = FileType.ZipFile;
break;
case "unzip":
case "file":
tDat.AddData(RvDat.DatData.FileType, "file");
thisFileType = FileType.File;
break;
default:
thisFileType = FileType.ZipFile;
break;
}
val = VarFix.String(packingNode.Attributes.GetNamedItem("forcemerging")).ToLower();
switch (val.ToLower())
{
case "split":
tDat.AddData(RvDat.DatData.MergeType, "split");
break;
case "full":
tDat.AddData(RvDat.DatData.MergeType, "full");
break;
default:
tDat.AddData(RvDat.DatData.MergeType, "split");
break;
}
val = VarFix.String(packingNode.Attributes.GetNamedItem("dir")).ToLower(); // noautodir , nogame
if (!String.IsNullOrEmpty(val))
tDat.AddData(RvDat.DatData.DirSetup,val);
}
}
// Look for: <notzipped>true</notzipped>
string notzipped = VarFix.String(head.SelectSingleNode("notzipped"));
if (notzipped.ToLower() == "true" || notzipped.ToLower() == "yes") thisFileType = FileType.File;
tDir.Dat = tDat;
return true;
}
private static bool LoadMameHeaderFromDat(ref RvDir tDir, ref XmlDocument doc, ref FileType thisFileType)
{
if (doc.DocumentElement == null)
return false;
XmlNode head = doc.SelectSingleNode("mame");
if (head == null || head.Attributes == null)
return false;
RvDat tDat = new RvDat();
tDat.AddData(RvDat.DatData.DatName, VarFix.CleanFileName(head.Attributes.GetNamedItem("build")));
tDat.AddData(RvDat.DatData.Description, VarFix.String(head.Attributes.GetNamedItem("build")));
thisFileType = FileType.ZipFile;
tDir.Dat = tDat;
return true;
}
private static void LoadDirFromDat(ref RvDir tDat, XmlNode dirNode, FileType thisFileType)
{
if (dirNode.Attributes == null)
return;
RvDir parent = tDat;
string fullname = VarFix.CleanFullFileName(dirNode.Attributes.GetNamedItem("name"));
while (fullname.Contains("/"))
{
int firstSlash = fullname.IndexOf("/", StringComparison.Ordinal);
string dir = fullname.Substring(0, firstSlash);
dir = VarFix.CleanFileName(dir);
fullname = fullname.Substring(firstSlash + 1);
int index;
if (parent.ChildNameSearch(new RvDir(FileType.Dir) { Name = dir }, out index) == 0)
{
parent = (RvDir)parent.Child(index);
}
else
{
RvDir tpDir = new RvDir(FileType.Dir)
{
Name = dir,
DatStatus = DatStatus.InDatCollect,
Dat = tDat.Dat,
Tree = new RvTreeRow()
};
parent.ChildAdd(tpDir, index);
parent = tpDir;
}
}
RvDir tDir = new RvDir(FileType.Dir)
{
Name = fullname,
DatStatus = DatStatus.InDatCollect,
Dat = tDat.Dat,
Tree = new RvTreeRow()
};
int index1;
if (parent.ChildNameSearch(tDir, out index1) == 0)
tDir = (RvDir)parent.Child(index1);
else
tDat.ChildAdd(tDir, index1);
XmlNodeList dirNodeList = dirNode.SelectNodes("dir");
if (dirNodeList != null)
{
for (int i = 0; i < dirNodeList.Count; i++)
{
LoadDirFromDat(ref tDir, dirNodeList[i], thisFileType);
}
}
XmlNodeList gameNodeList = dirNode.SelectNodes("game");
if (gameNodeList != null)
{
for (int i = 0; i < gameNodeList.Count; i++)
{
LoadGameFromDat(ref tDir, gameNodeList[i], thisFileType);
}
}
}
private static void LoadGameFromDat(ref RvDir tDat, XmlNode gameNode, FileType thisFileType)
{
if (gameNode.Attributes == null)
return;
RvDir parent = tDat;
RvDir tDir;
int index1 = 0;
string fullname = VarFix.CleanFullFileName(gameNode.Attributes.GetNamedItem("name"));
if (_cleanFileNames)
fullname = fullname.Replace("/", "-");
else
{
while (fullname.Contains("/"))
{
int firstSlash = fullname.IndexOf("/", StringComparison.Ordinal);
string dir = fullname.Substring(0, firstSlash);
dir = VarFix.CleanFileName(dir);
fullname = fullname.Substring(firstSlash + 1);
int index;
if (parent.ChildNameSearch(new RvDir(FileType.Dir) { Name = dir }, out index) == 0)
{
parent = (RvDir)parent.Child(index);
}
else
{
RvDir tpDir = new RvDir(FileType.Dir)
{
Name = dir,
DatStatus = DatStatus.InDatCollect,
Dat = tDat.Dat,
Tree = new RvTreeRow()
};
parent.ChildAdd(tpDir, index);
parent = tpDir;
}
}
}
tDir = new RvDir(DBTypeGet.DirFromFile(thisFileType))
{
Name = fullname,
DatStatus = DatStatus.InDatCollect,
Dat = tDat.Dat
};
string testName = tDir.Name;
int nameCount = 0;
while (parent.ChildNameSearch(tDir, out index1) == 0)
{
tDir.Name = testName + "_" + nameCount;
nameCount++;
}
tDir.Game = new RvGame();
tDir.Game.AddData(RvGame.GameData.RomOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("romof")));
tDir.Game.AddData(RvGame.GameData.Description, VarFix.String(gameNode.SelectSingleNode("description")));
tDir.Game.AddData(RvGame.GameData.Sourcefile, VarFix.String(gameNode.Attributes.GetNamedItem("sourcefile")));
tDir.Game.AddData(RvGame.GameData.IsBios, VarFix.String(gameNode.Attributes.GetNamedItem("isbios")));
tDir.Game.AddData(RvGame.GameData.CloneOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("cloneof")));
tDir.Game.AddData(RvGame.GameData.SampleOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("sampleof")));
tDir.Game.AddData(RvGame.GameData.Board, VarFix.String(gameNode.Attributes.GetNamedItem("board")));
tDir.Game.AddData(RvGame.GameData.Year, VarFix.String(gameNode.SelectSingleNode("year")));
tDir.Game.AddData(RvGame.GameData.Manufacturer, VarFix.String(gameNode.SelectSingleNode("manufacturer")));
XmlNode trurip = gameNode.SelectSingleNode("trurip");
if (trurip != null)
{
tDir.Game.AddData(RvGame.GameData.Trurip, "yes");
tDir.Game.AddData(RvGame.GameData.Year, VarFix.String(trurip.SelectSingleNode("year")));
tDir.Game.AddData(RvGame.GameData.Publisher, VarFix.String(trurip.SelectSingleNode("publisher")));
tDir.Game.AddData(RvGame.GameData.Developer, VarFix.String(trurip.SelectSingleNode("developer")));
tDir.Game.AddData(RvGame.GameData.Edition, VarFix.String(trurip.SelectSingleNode("edition")));
tDir.Game.AddData(RvGame.GameData.Version, VarFix.String(trurip.SelectSingleNode("version")));
tDir.Game.AddData(RvGame.GameData.Type, VarFix.String(trurip.SelectSingleNode("type")));
tDir.Game.AddData(RvGame.GameData.Media, VarFix.String(trurip.SelectSingleNode("media")));
tDir.Game.AddData(RvGame.GameData.Language, VarFix.String(trurip.SelectSingleNode("language")));
tDir.Game.AddData(RvGame.GameData.Players, VarFix.String(trurip.SelectSingleNode("players")));
tDir.Game.AddData(RvGame.GameData.Ratings, VarFix.String(trurip.SelectSingleNode("ratings")));
tDir.Game.AddData(RvGame.GameData.Peripheral, VarFix.String(trurip.SelectSingleNode("peripheral")));
tDir.Game.AddData(RvGame.GameData.Genre, VarFix.String(trurip.SelectSingleNode("genre")));
tDir.Game.AddData(RvGame.GameData.MediaCatalogNumber, VarFix.String(trurip.SelectSingleNode("mediacatalognumber")));
tDir.Game.AddData(RvGame.GameData.BarCode, VarFix.String(trurip.SelectSingleNode("barcode")));
}
RvDir tDirCHD = new RvDir(FileType.Dir)
{
Name = tDir.Name,
DatStatus = tDir.DatStatus,
Dat = tDir.Dat,
Game = tDir.Game
};
XmlNodeList romNodeList = gameNode.SelectNodes("rom");
if (romNodeList != null)
for (int i = 0; i < romNodeList.Count; i++)
LoadRomFromDat(ref tDir, romNodeList[i], thisFileType);
XmlNodeList diskNodeList = gameNode.SelectNodes("disk");
if (diskNodeList != null)
for (int i = 0; i < diskNodeList.Count; i++)
LoadDiskFromDat(ref tDirCHD, diskNodeList[i]);
if (tDir.ChildCount > 0)
parent.ChildAdd(tDir, index1);
if (tDirCHD.ChildCount > 0)
parent.ChildAdd(tDirCHD);
}
private static void LoadRomFromDat(ref RvDir tGame, XmlNode romNode, FileType thisFileType)
{
if (romNode.Attributes == null)
return;
RvFile tRom = new RvFile(thisFileType)
{
Dat = tGame.Dat,
Size = VarFix.ULong(romNode.Attributes.GetNamedItem("size")),
Name = VarFix.CleanFullFileName(romNode.Attributes.GetNamedItem("name")),
CRC = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("crc"), 8),
SHA1 = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("sha1"), 40),
MD5 = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("md5"), 32),
Merge = VarFix.CleanFullFileName(romNode.Attributes.GetNamedItem("merge")),
Status = VarFix.ToLower(romNode.Attributes.GetNamedItem("status"))
};
if (tRom.Size != null) tRom.FileStatusSet(FileStatus.SizeFromDAT);
if (tRom.CRC != null) tRom.FileStatusSet(FileStatus.CRCFromDAT);
if (tRom.SHA1 != null) tRom.FileStatusSet(FileStatus.SHA1FromDAT);
if (tRom.MD5 != null) tRom.FileStatusSet(FileStatus.MD5FromDAT);
tGame.ChildAdd(tRom);
}
private static void LoadDiskFromDat(ref RvDir tGame, XmlNode romNode)
{
if (romNode.Attributes == null)
return;
RvFile tRom = new RvFile(FileType.File)
{
Dat = tGame.Dat,
Name = VarFix.CleanFullFileName(romNode.Attributes.GetNamedItem("name")) + ".chd",
SHA1CHD = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("sha1"), 40),
MD5CHD = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("md5"), 32),
Merge = VarFix.CleanFullFileName(romNode.Attributes.GetNamedItem("merge")),
Status = VarFix.ToLower(romNode.Attributes.GetNamedItem("status"))
};
if (tRom.SHA1CHD != null) tRom.FileStatusSet(FileStatus.SHA1CHDFromDAT);
if (tRom.MD5CHD != null) tRom.FileStatusSet(FileStatus.MD5CHDFromDAT);
tGame.ChildAdd(tRom);
}
}
}

784
ROMVault2/DatUpdate.cs Normal file
View File

@@ -0,0 +1,784 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2013 *
******************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading;
using ROMVault2.IO;
using ROMVault2.DatReaders;
using ROMVault2.Properties;
using ROMVault2.RvDB;
using ROMVault2.Utils;
namespace ROMVault2
{
public static class DatUpdate
{
private static int _datCount;
private static int _datsProcessed;
private static BackgroundWorker _bgw;
public static void ShowDat(string message, string filename)
{
if (_bgw != null)
_bgw.ReportProgress(0, new bgwShowError(filename, message));
}
public static void SendAndShowDat(string message, string filename)
{
ReportError.SendErrorMessageDat(message, filename);
if (_bgw != null)
_bgw.ReportProgress(0, new bgwShowError(filename, message));
}
public static void UpdateDat(object sender, DoWorkEventArgs e)
{
try
{
_bgw = sender as BackgroundWorker;
if (_bgw == null) return;
Program.SyncCont = e.Argument as SynchronizationContext;
if (Program.SyncCont == null)
{
_bgw = null;
return;
}
_bgw.ReportProgress(0, new bgwText("Clearing DB Status"));
RepairStatus.ReportStatusReset(DB.DirTree);
_datCount = 0;
_bgw.ReportProgress(0, new bgwText("Finding Dats"));
RvDir datRoot = new RvDir(FileType.Dir) { Name = "RomVault", DatStatus = DatStatus.InDatCollect };
// build a datRoot tree of the DAT's in DatRoot, and count how many dats are found
if (!RecursiveDatTree(datRoot, out _datCount))
{
_bgw.ReportProgress(0, new bgwText("Dat Update Complete"));
_bgw = null;
Program.SyncCont = null;
return;
}
_bgw.ReportProgress(0, new bgwText("Scanning Dats"));
_datsProcessed = 0;
// now compare the database DAT's with datRoot removing any old DAT's
RemoveOldDats(DB.DirTree.Child(0), datRoot);
// next clean up the File status removing any old DAT's
RemoveOldDatsCleanUpFiles(DB.DirTree.Child(0));
_bgw.ReportProgress(0, new bgwSetRange(_datCount - 1));
// next add in new DAT and update the files
UpdateDatList((RvDir)DB.DirTree.Child(0),datRoot);
// finally remove any unneeded DIR's from the TreeView
RemoveOldTree(DB.DirTree.Child(0));
_bgw.ReportProgress(0, new bgwText("Updating Cache"));
DB.Write();
_bgw.ReportProgress(0, new bgwText("Dat Update Complete"));
_bgw = null;
Program.SyncCont = null;
}
catch (Exception exc)
{
ReportError.UnhandledExceptionHandler(exc);
if (_bgw != null) _bgw.ReportProgress(0, new bgwText("Updating Cache"));
DB.Write();
if (_bgw != null) _bgw.ReportProgress(0, new bgwText("Complete"));
_bgw = null;
Program.SyncCont = null;
}
}
private static bool RecursiveDatTree(RvDir tDir, out int datCount)
{
datCount = 0;
string strPath = tDir.DatFullName;
if (!Directory.Exists(strPath))
{
ReportError.Show(Resources.DatUpdate_UpdateDatList_Path + strPath + Resources.DatUpdate_UpdateDatList_Not_Found);
return false;
}
DirectoryInfo oDir = new DirectoryInfo(strPath);
FileInfo[] oFilesIn = oDir.GetFiles("*.dat", false);
datCount += oFilesIn.Length;
foreach (FileInfo file in oFilesIn)
{
RvDat tDat = new RvDat();
tDat.AddData(RvDat.DatData.DatFullName, file.FullName);
tDat.TimeStamp = file.LastWriteTime;
tDir.DirDatAdd(tDat);
}
oFilesIn = oDir.GetFiles("*.xml", false);
datCount += oFilesIn.Length;
foreach (FileInfo file in oFilesIn)
{
RvDat tDat = new RvDat();
tDat.AddData(RvDat.DatData.DatFullName, file.FullName);
tDat.TimeStamp = file.LastWriteTime;
tDir.DirDatAdd(tDat);
}
if (tDir.DirDatCount > 1)
for (int i = 0; i < tDir.DirDatCount; i++)
tDir.DirDat(i).AutoAddDirectory = true;
DirectoryInfo[] oSubDir = oDir.GetDirectories(false);
foreach (DirectoryInfo t in oSubDir)
{
RvDir cDir = new RvDir(FileType.Dir) { Name = t.Name, DatStatus = DatStatus.InDatCollect };
int index = tDir.ChildAdd(cDir);
int retDatCount;
RecursiveDatTree(cDir, out retDatCount);
datCount += retDatCount;
if (retDatCount == 0)
tDir.ChildRemove(index);
}
return true;
}
private static void RemoveOldDats(RvBase dbDir, RvDir tmpDir)
{
// now compare the old and new dats removing any old dats
// in the current directory
RvDir lDir = dbDir as RvDir;
if (lDir == null) return;
int dbIndex = 0;
int scanIndex = 0;
while (dbIndex < lDir.DirDatCount || scanIndex < tmpDir.DirDatCount)
{
RvDat dbDat = null;
RvDat fileDat = null;
int res = 0;
if (dbIndex < lDir.DirDatCount && scanIndex < tmpDir.DirDatCount)
{
dbDat = lDir.DirDat(dbIndex);
fileDat = tmpDir.DirDat(scanIndex);
res = DBHelper.DatCompare(dbDat, fileDat);
}
else if (scanIndex < tmpDir.DirDatCount)
{
//this is a new dat that we have now found at the end of the list
//fileDat = tmpDir.DirDat(scanIndex);
res = 1;
}
else if (dbIndex < lDir.DirDatCount)
{
dbDat = lDir.DirDat(dbIndex);
res = -1;
}
switch (res)
{
case 0:
dbDat.Status = DatUpdateStatus.Correct;
dbIndex++;
scanIndex++;
break;
case 1:
// this is a new dat that we will add next time around
scanIndex++;
break;
case -1:
dbDat.Status = DatUpdateStatus.Delete;
lDir.DirDatRemove(dbIndex);
break;
}
}
// now scan the child directory structure of this directory
dbIndex = 0;
scanIndex = 0;
while (dbIndex < lDir.ChildCount || scanIndex < tmpDir.ChildCount)
{
RvBase dbChild = null;
RvBase fileChild = null;
int res = 0;
if (dbIndex < lDir.ChildCount && scanIndex < tmpDir.ChildCount)
{
dbChild = lDir.Child(dbIndex);
fileChild = tmpDir.Child(scanIndex);
res = DBHelper.CompareName(dbChild, fileChild);
}
else if (scanIndex < tmpDir.ChildCount)
{
//found a new directory on the end of the list
//fileChild = tmpDir.Child(scanIndex);
res = 1;
}
else if (dbIndex < lDir.ChildCount)
{
dbChild = lDir.Child(dbIndex);
res = -1;
}
switch (res)
{
case 0:
// found a matching directory in DatRoot So recurse back into it
RemoveOldDats(dbChild, (RvDir)fileChild);
dbIndex++;
scanIndex++;
break;
case 1:
// found a new directory will be added later
scanIndex++;
break;
case -1:
if (dbChild.FileType == FileType.Dir && dbChild.Dat == null)
RemoveOldDats(dbChild, new RvDir(FileType.Dir));
dbIndex++;
break;
}
}
}
private static EFile RemoveOldDatsCleanUpFiles(RvBase dbDir)
{
if (dbDir.Dat != null)
{
if (dbDir.Dat.Status == DatUpdateStatus.Correct)
return EFile.Keep;
if (dbDir.Dat.Status == DatUpdateStatus.Delete)
{
if (dbDir.DatRemove() == EFile.Delete)
return EFile.Delete; //delete
}
}
FileType ft = dbDir.FileType;
// if we are checking a dir or zip recurse into it.
if (ft != FileType.Zip && ft != FileType.Dir) return EFile.Keep;
RvDir tDir = dbDir as RvDir;
// remove all DATStatus's here they will get set back correctly when adding dats back in below.
dbDir.DatStatus = DatStatus.NotInDat;
for (int i = 0; i < tDir.ChildCount; i++)
{
if (RemoveOldDatsCleanUpFiles(tDir.Child(i)) == EFile.Keep) continue;
tDir.ChildRemove(i);
i--;
}
if (ft == FileType.Zip && dbDir.GotStatus == GotStatus.Corrupt) return EFile.Keep;
// if this directory is now empty it should be deleted
return tDir.ChildCount == 0 ? EFile.Delete : EFile.Keep;
}
private static void UpdateDatList(RvDir dbDir, RvDir tmpDir)
{
AddNewDats(dbDir, tmpDir);
UpdateDirs(dbDir, tmpDir);
}
/// <summary>
/// Add the new DAT's into the DAT list
/// And merge in the new DAT data into the database
/// </summary>
/// <param name="dbDir">The Current database dir</param>
/// <param name="tmpDir">A temp directory containing the DAT found in this directory in DatRoot</param>
private static void AddNewDats(RvDir dbDir, RvDir tmpDir)
{
bool autoAddDirectory = (tmpDir.DirDatCount) > 1;
int dbIndex = 0;
int scanIndex = 0;
Debug.WriteLine("");
Debug.WriteLine("Scanning for Adding new DATS");
while (dbIndex < dbDir.DirDatCount || scanIndex < tmpDir.DirDatCount)
{
RvDat dbDat = null;
RvDat fileDat = null;
int res = 0;
if (dbIndex < dbDir.DirDatCount && scanIndex < tmpDir.DirDatCount)
{
dbDat = dbDir.DirDat(dbIndex);
fileDat = tmpDir.DirDat(scanIndex);
res = DBHelper.DatCompare(dbDat, fileDat);
Debug.WriteLine("Checking " + dbDat.GetData(RvDat.DatData.DatFullName) + " : and " + fileDat.GetData(RvDat.DatData.DatFullName) + " : " + res);
}
else if (scanIndex < tmpDir.DirDatCount)
{
fileDat = tmpDir.DirDat(scanIndex);
res = 1;
Debug.WriteLine("Checking : and " + fileDat.GetData(RvDat.DatData.DatFullName) + " : " + res);
}
else if (dbIndex < dbDir.DirDatCount)
{
dbDat = dbDir.DirDat(dbIndex);
res = -1;
Debug.WriteLine("Checking " + dbDat.GetData(RvDat.DatData.DatFullName) + " : and : " + res);
}
switch (res)
{
case 0:
_datsProcessed++;
_bgw.ReportProgress(_datsProcessed);
_bgw.ReportProgress(0, new bgwText("Dat : " + Path.GetFileNameWithoutExtension(fileDat.GetData(RvDat.DatData.DatFullName))));
Debug.WriteLine("Correct");
// Should already be set as correct above
dbDat.Status = DatUpdateStatus.Correct;
dbIndex++;
scanIndex++;
break;
case 1:
_datsProcessed++;
_bgw.ReportProgress(_datsProcessed);
_bgw.ReportProgress(0, new bgwText("Scanning New Dat : " + Path.GetFileNameWithoutExtension(fileDat.GetData(RvDat.DatData.DatFullName))));
Debug.WriteLine("Adding new DAT");
if (UpdateDatFile(fileDat, autoAddDirectory, dbDir))
dbIndex++;
scanIndex++;
break;
case -1:
// This should not happen as deleted dat have been removed above
//dbIndex++;
ReportError.SendAndShow(Resources.DatUpdate_UpdateDatList_ERROR_Deleting_a_DAT_that_should_already_be_deleted);
break;
}
}
}
private static bool UpdateDatFile(RvDat file, bool autoAddDirectory, RvDir thisDirectory)
{
// Read the new Dat File into newDatFile
RvDir newDatFile = DatReader.ReadInDatFile(file, _bgw);
// If we got a valid Dat File back
if (newDatFile == null || newDatFile.Dat == null)
{
ReportError.Show("Error reading Dat " + file.GetData(RvDat.DatData.DatFullName));
return false;
}
newDatFile.Dat.AutoAddDirectory = autoAddDirectory;
if ((autoAddDirectory || !String.IsNullOrEmpty(newDatFile.Dat.GetData(RvDat.DatData.RootDir))) && newDatFile.Dat.GetData(RvDat.DatData.DirSetup)!= "noautodir")
{ // if we are auto adding extra directorys then create a new directory.
newDatFile.Name = !String.IsNullOrEmpty(newDatFile.Dat.GetData(RvDat.DatData.RootDir)) ?
newDatFile.Dat.GetData(RvDat.DatData.RootDir) : newDatFile.Dat.GetData(RvDat.DatData.DatName);
newDatFile.DatStatus = DatStatus.InDatCollect;
newDatFile.Tree = new RvTreeRow();
RvDir newDirectory = new RvDir(FileType.Dir) { Dat = newDatFile.Dat };
// add the DAT into this directory
newDirectory.ChildAdd(newDatFile);
newDatFile = newDirectory;
}
if (thisDirectory.Tree == null)
thisDirectory.Tree = new RvTreeRow();
RvDat conflictDat;
if (MergeInDat(thisDirectory, newDatFile, out conflictDat, true))
{
ReportError.Show("Dat Merge conflict occured Cache contains " + conflictDat.GetData(RvDat.DatData.DatFullName) + " new dat " + newDatFile.Dat.GetData(RvDat.DatData.DatFullName) + " is trying to use the same dirctory and so will be ignored.");
return false;
}
//SetInDat(thisDirectory);
// Add the new Dat
thisDirectory.DirDatAdd(newDatFile.Dat);
// Merge the files/directories in the Dat
MergeInDat(thisDirectory, newDatFile, out conflictDat, false);
return true;
}
/*
private static void SetInDat(RvDir tDir)
{
tDir.DatStatus = DatStatus.InDatCollect;
if (tDir.Parent != null)
SetInDat(tDir.Parent);
}
*/
private static Boolean MergeInDat(RvDir dbDat, RvDir newDat, out RvDat conflict, bool checkOnly)
{
conflict = null;
int dbIndex = 0;
int newIndex = 0;
while (dbIndex < dbDat.ChildCount || newIndex < newDat.ChildCount)
{
RvBase dbChild = null;
RvBase newDatChild = null;
int res = 0;
if (dbIndex < dbDat.ChildCount && newIndex < newDat.ChildCount)
{
dbChild = dbDat.Child(dbIndex); // are files
newDatChild = newDat.Child(newIndex); // is from a dat item
res = DBHelper.CompareName(dbChild, newDatChild);
}
else if (newIndex < newDat.ChildCount)
{
newDatChild = newDat.Child(newIndex);
res = 1;
}
else if (dbIndex < dbDat.ChildCount)
{
dbChild = dbDat.Child(dbIndex);
res = -1;
}
if (res == 0)
{
if (dbChild == null || newDatChild == null)
{
SendAndShowDat(Resources.DatUpdate_MergeInDat_Error_in_Logic, dbDat.FullName);
break;
}
List<RvBase> dbDats = new List<RvBase>();
List<RvBase> newDats = new List<RvBase>();
int dbDatsCount = 1;
int newDatsCount = 1;
dbDats.Add(dbChild);
newDats.Add(newDatChild);
while (dbIndex + dbDatsCount < dbDat.ChildCount && DBHelper.CompareName(dbChild, dbDat.Child(dbIndex + dbDatsCount)) == 0)
{
dbDats.Add(dbDat.Child(dbIndex + dbDatsCount));
dbDatsCount += 1;
}
while (newIndex + newDatsCount < newDat.ChildCount && DBHelper.CompareName(newDatChild, newDat.Child(newIndex + newDatsCount)) == 0)
{
newDats.Add(newDat.Child(newIndex + newDatsCount));
newDatsCount += 1;
}
if (dbDatsCount > 1 || newDatsCount > 1)
{
ReportError.SendAndShow("Double Name Found");
}
for (int indexdb = 0; indexdb < dbDatsCount; indexdb++)
{
if (dbDats[indexdb].DatStatus == DatStatus.NotInDat) continue;
if (checkOnly)
{
conflict = dbChild.Dat;
return true;
}
SendAndShowDat(Resources.DatUpdate_MergeInDat_Unkown_Update_Dat_Status + dbChild.DatStatus, dbDat.FullName);
break;
}
if (!checkOnly)
{
for (int indexNewDats = 0; indexNewDats < newDatsCount; indexNewDats++)
{
if (newDats[indexNewDats].SearchFound) continue;
for (int indexDbDats = 0; indexDbDats < dbDatsCount; indexDbDats++)
{
if (dbDats[indexDbDats].SearchFound) continue;
bool matched = FullCompare(dbDats[indexDbDats], newDats[indexNewDats]);
if (!matched) continue;
dbDats[indexDbDats].DatAdd(newDats[indexNewDats]);
FileType ft = dbChild.FileType;
if (ft == FileType.Zip || ft == FileType.Dir)
{
RvDir dChild = (RvDir)dbChild;
RvDir dNewChild = (RvDir)newDatChild;
MergeInDat(dChild, dNewChild, out conflict, checkOnly);
}
dbDats[indexDbDats].SearchFound = true;
newDats[indexNewDats].SearchFound = true;
}
}
for (int indexNewDats = 0; indexNewDats < newDatsCount; indexNewDats++)
{
if (newDats[indexNewDats].SearchFound) continue;
dbDat.ChildAdd(newDats[indexNewDats], dbIndex);
dbChild = dbDat.Child(dbIndex);
SetMissingStatus(dbChild);
dbIndex++;
}
}
dbIndex += dbDatsCount;
newIndex += newDatsCount;
}
if (res == 1)
{
if (!checkOnly)
{
dbDat.ChildAdd(newDatChild, dbIndex);
dbChild = dbDat.Child(dbIndex);
SetMissingStatus(dbChild);
dbIndex++;
}
newIndex++;
}
if (res == -1)
{
dbIndex++;
}
}
return false;
}
private static void SetMissingStatus(RvBase dbChild)
{
if (dbChild.FileRemove() == EFile.Delete)
{
ReportError.SendAndShow("Error is Set Mssing Status in DatUpdate");
return;
}
FileType ft = dbChild.FileType;
if (ft == FileType.Zip || ft == FileType.Dir)
{
RvDir dbDir = (RvDir)dbChild;
for (int i = 0; i < dbDir.ChildCount; i++)
SetMissingStatus(dbDir.Child(i));
}
}
private static bool FullCompare(RvBase var1, RvBase var2)
{
int retv = DBHelper.CompareName(var1, var2);
if (retv != 0) return false;
FileType v1 = var1.FileType;
FileType v2 = var2.FileType;
retv = Math.Sign(v1.CompareTo(v2));
if (retv != 0) return false;
// filetypes are now know to be the same
// Dir's and Zip's are not deep scanned so matching here is done
if ((v1 == FileType.Dir) || (v1 == FileType.Zip))
return true;
RvFile f1 = (RvFile)var1;
RvFile f2 = (RvFile)var2;
if (f1.Size != null && f2.Size != null)
{
retv = ULong.iCompare(f1.Size, f2.Size);
if (retv != 0) return false;
}
if (f1.CRC != null && f2.CRC != null)
{
retv = ArrByte.iCompare(f1.CRC, f2.CRC);
if (retv != 0) return false;
}
if (f1.SHA1 != null && f2.SHA1 != null)
{
retv = ArrByte.iCompare(f1.SHA1, f2.SHA1);
if (retv != 0) return false;
}
if (f1.MD5 != null && f2.MD5 != null)
{
retv = ArrByte.iCompare(f1.MD5, f2.MD5);
if (retv != 0) return false;
}
if (f1.SHA1CHD != null && f2.SHA1CHD != null)
{
retv = ArrByte.iCompare(f1.SHA1CHD, f2.SHA1CHD);
if (retv != 0) return false;
}
if (f1.MD5CHD != null && f2.MD5CHD != null)
{
retv = ArrByte.iCompare(f1.MD5CHD, f2.MD5CHD);
if (retv != 0) return false;
}
return true;
}
private static void UpdateDirs(RvDir dbDir, RvDir fileDir)
{
int dbIndex = 0;
int scanIndex = 0;
dbDir.DatStatus=DatStatus.InDatCollect;
if (dbDir.Tree == null)
{
Debug.WriteLine("Adding Tree View to " + dbDir.Name);
dbDir.Tree = new RvTreeRow();
}
Debug.WriteLine("");
Debug.WriteLine("Now scanning dirs");
while (dbIndex < dbDir.ChildCount || scanIndex < fileDir.ChildCount)
{
RvBase dbChild = null;
RvBase fileChild = null;
int res = 0;
if (dbIndex < dbDir.ChildCount && scanIndex < fileDir.ChildCount)
{
dbChild = dbDir.Child(dbIndex);
fileChild = fileDir.Child(scanIndex);
res = DBHelper.CompareName(dbChild, fileChild);
Debug.WriteLine("Checking " + dbChild.Name + " : and " + fileChild.Name + " : " + res);
}
else if (scanIndex < fileDir.ChildCount)
{
fileChild = fileDir.Child(scanIndex);
res = 1;
Debug.WriteLine("Checking : and " + fileChild.Name + " : " + res);
}
else if (dbIndex < dbDir.ChildCount)
{
dbChild = dbDir.Child(dbIndex);
res = -1;
}
switch (res)
{
case 0:
// found a matching directory in DatRoot So recurse back into it
if (dbChild.GotStatus == GotStatus.Got)
{
if (dbChild.Name != fileChild.Name) // check if the case of the Item in the DB is different from the Dat Root Actual filename
{
if (!string.IsNullOrEmpty(dbChild.FileName)) // if we do not already have a different case name stored
{
dbChild.FileName = dbChild.Name; // copy the DB filename to the FileName
}
else // We already have a different case filename found in RomRoot
{
if (dbChild.FileName == fileChild.Name) // check if the Datroot name does now match the name in the DB Filename
{
dbChild.FileName = null; // if it does undo the BadCase Flag
}
}
dbChild.Name = fileChild.Name; // Set the db Name to match the Datroot Name.
}
}
else
dbChild.Name = fileChild.Name;
UpdateDatList((RvDir)dbChild,(RvDir)fileChild);
dbIndex++;
scanIndex++;
break;
case 1:
// found a new directory in Dat
RvDir tDir = new RvDir(FileType.Dir)
{
Name = fileChild.Name,
Tree = new RvTreeRow(),
DatStatus = DatStatus.InDatCollect,
};
dbDir.ChildAdd(tDir, dbIndex);
Debug.WriteLine("Adding new Dir and Calling back in to check this DIR " + tDir.Name);
UpdateDatList(tDir,(RvDir)fileChild);
dbIndex++;
scanIndex++;
break;
case -1:
// all files
dbIndex++;
break;
}
}
}
private static void RemoveOldTree(RvBase dbBase)
{
RvDir dbDir = dbBase as RvDir;
if (dbDir == null) return;
if (dbDir.DatStatus == DatStatus.NotInDat && dbDir.Tree != null)
dbDir.Tree = null;
for (int i = 0; i < dbDir.ChildCount; i++)
RemoveOldTree(dbDir.Child(i));
}
}
}

146
ROMVault2/DirCellDraw.cs Normal file
View File

@@ -0,0 +1,146 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.Windows.Forms;
using ROMVault2.RvDB;
using ROMVault2.SupportedFiles;
namespace ROMVault2
{
public class RomCellDraw : DataGridViewImageCell
{
private readonly Color _bgCol;
private readonly string _bitmapName;
public RomCellDraw(string name,Color bgCol)
{
_bitmapName = name;
_bgCol = bgCol;
}
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
graphics.FillRectangle(new SolidBrush(_bgCol), cellBounds);
Bitmap bm= rvImages.GetBitmap(_bitmapName);
if (bm != null)
{
graphics.DrawImage(bm, cellBounds.Left, cellBounds.Top, bm.Width,bm.Height);
bm.Dispose();
}
else
Debug.WriteLine("Missing Graphic for " + _bitmapName);
}
}
public class DirCellDraw : DataGridViewImageCell
{
private readonly Color _bgCol;
private readonly RvDir _cellDir;
public DirCellDraw(RvDir cellDir, Color bgCol)
{
_cellDir = cellDir;
_bgCol = bgCol;
}
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
graphics.FillRectangle(new SolidBrush(_bgCol), cellBounds);
string bitmapName;
switch (_cellDir.FileType)
{
case FileType.Zip:
if (_cellDir.RepStatus == RepStatus.DirCorrect && _cellDir.ZipStatus==ZipStatus.TrrntZip)
bitmapName = "ZipTZ";
else
bitmapName = "Zip" + _cellDir.RepStatus;
break;
default:
bitmapName = "Dir" + _cellDir.RepStatus;
break;
}
Bitmap bm = rvImages.GetBitmap(bitmapName);
if (bm != null)
{
graphics.DrawImage(bm, cellBounds.Left + 10, cellBounds.Top, 21, 17);
bm.Dispose();
}
else
Debug.WriteLine("Missing Graphic for " + bitmapName);
}
}
public class DirCellStatusDraw : DataGridViewImageCell
{
private readonly RvDir _dir;
public DirCellStatusDraw(RvDir dir)
{
_dir = dir;
}
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
Font drawFont = new Font("Arial", 9);
SolidBrush drawBrushBlack = new SolidBrush(Color.Black);
SolidBrush drawBrushWhite = new SolidBrush(Color.White);
graphics.FillRectangle(drawBrushWhite, cellBounds);
int gOff;
int columnIndex = 0;
for (int l = 0; l < RepairStatus.DisplayOrder.Length; l++)
{
if (l >= 13) columnIndex = l;
if (_dir.DirStatus.Get(RepairStatus.DisplayOrder[l]) <= 0) continue;
gOff = cellBounds.Left + FrmMain.GameGridColumnXPositions[columnIndex];
Bitmap bm = rvImages.GetBitmap(@"G_" + RepairStatus.DisplayOrder[l]);
if (bm != null)
{
graphics.DrawImage(bm, gOff, cellBounds.Top, 21, 18);
bm.Dispose();
}
else
Debug.WriteLine("Missing Graphics for " + "G_" + RepairStatus.DisplayOrder[l]);
columnIndex++;
}
columnIndex = 0;
for (int l = 0; l < RepairStatus.DisplayOrder.Length; l++)
{
if (l >= 13)
columnIndex = l;
if (_dir.DirStatus.Get(RepairStatus.DisplayOrder[l]) > 0)
{
gOff = cellBounds.Left + FrmMain.GameGridColumnXPositions[columnIndex];
graphics.DrawString(_dir.DirStatus.Get(RepairStatus.DisplayOrder[l]).ToString(CultureInfo.InvariantCulture), drawFont, drawBrushBlack, new PointF(gOff + 20, cellBounds.Top + 3));
columnIndex++;
}
}
drawBrushBlack.Dispose();
drawBrushWhite.Dispose();
drawFont.Dispose();
}
}
}

842
ROMVault2/FileScanning.cs Normal file
View File

@@ -0,0 +1,842 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using ROMVault2.IO;
using System.Threading;
using ROMVault2.Properties;
using ROMVault2.RvDB;
using ROMVault2.SupportedFiles;
using ROMVault2.SupportedFiles.CHD;
using ROMVault2.SupportedFiles.Files;
using ROMVault2.SupportedFiles.Zip;
using ROMVault2.Utils;
using FileInfo = ROMVault2.IO.FileInfo;
namespace ROMVault2
{
public static class FileScanning
{
private static Stopwatch _cacheSaveTimer;
private static long _lastUpdateTime;
private static BackgroundWorker _bgw;
public static eScanLevel EScanLevel;
private static bool _fileErrorAbort;
public static void ScanFiles(object sender, DoWorkEventArgs e)
{
#if !Debug
try
{
#endif
_fileErrorAbort = false;
_cacheSaveTimer = new Stopwatch();
_cacheSaveTimer.Reset();
if (Settings.CacheSaveTimerEnabled)
_cacheSaveTimer.Start();
_bgw = sender as BackgroundWorker;
if (_bgw == null) return;
Program.SyncCont = e.Argument as SynchronizationContext;
if (Program.SyncCont == null)
{
_bgw = null;
return;
}
_bgw.ReportProgress(0, new bgwText("Clearing DB Status"));
RepairStatus.ReportStatusReset(DB.DirTree);
_bgw.ReportProgress(0, new bgwText("Finding Dir's to Scan"));
//Next get a list of all the directories to be scanned
List<RvDir> lstDir = new List<RvDir>();
DBHelper.GetSelectedDirList(ref lstDir);
_bgw.ReportProgress(0, new bgwText("Scanning Dir's"));
_bgw.ReportProgress(0, new bgwSetRange(lstDir.Count - 1));
//Scan the list of directories.
for (int i = 0; i < lstDir.Count; i++)
{
_bgw.ReportProgress(i);
_bgw.ReportProgress(0, new bgwText("Scanning Dir : " + lstDir[i].FullName));
string lDir = lstDir[i].FullName;
Console.WriteLine(lDir);
if (Directory.Exists(lDir))
CheckADir(lstDir[i], true);
else
MarkAsMissing(lstDir[i]);
if (_bgw.CancellationPending || _fileErrorAbort) break;
}
_bgw.ReportProgress(0, new bgwText("Updating Cache"));
DB.Write();
_bgw.ReportProgress(0, new bgwText("File Scan Complete"));
_bgw = null;
Program.SyncCont = null;
#if !Debug
}
catch (Exception exc)
{
ReportError.UnhandledExceptionHandler(exc);
if (_bgw != null) _bgw.ReportProgress(0, new bgwText("Updating Cache"));
DB.Write();
if (_bgw != null) _bgw.ReportProgress(0, new bgwText("Complete"));
_bgw = null;
Program.SyncCont = null;
}
#endif
}
private static void CheckADir(RvDir dbDir, bool report)
{
if (_cacheSaveTimer.Elapsed.TotalMinutes > Settings.CacheSaveTimePeriod)
{
_bgw.ReportProgress(0, "Saving Cache");
DB.Write();
_bgw.ReportProgress(0, "Saving Cache Complete");
_cacheSaveTimer.Reset();
_cacheSaveTimer.Start();
}
string fullDir = dbDir.FullName;
if (report)
_bgw.ReportProgress(0, new bgwText2(fullDir));
DatStatus chechingDatStatus = dbDir.IsInToSort ? DatStatus.InToSort : DatStatus.NotInDat;
// this is a temporary rvDir structure to store the data about the actual directory/files we are scanning
// we will first populate this variable with the real file data from the directory, and then compare it
// with the data in dbDir.
RvDir fileDir = null;
Debug.WriteLine(fullDir);
FileType ft = dbDir.FileType;
#region "Populate fileDir"
// if we are scanning a ZIP file then populate scanDir from the ZIP file
switch (ft)
{
case FileType.Zip:
{
fileDir = new RvDir(ft);
// open the zip file
ZipFile checkZ = new ZipFile();
ZipReturn zr = checkZ.ZipFileOpen(fullDir, dbDir.TimeStamp, true);
if (zr == ZipReturn.ZipGood)
{
dbDir.ZipStatus = checkZ.ZipStatus;
// to be Scanning a ZIP file means it is either new or has changed.
// as the code below only calls back here if that is true.
//
// Level1: Only use header CRC's
// Just get the CRC for the ZIP headers.
//
// Level2: Fully checksum changed only files
// We know this file has been changed to do a full checksum scan.
//
// Level3: Fully checksum everything
// So do a full checksum scan.
if (EScanLevel == eScanLevel.Level2 || EScanLevel == eScanLevel.Level3)
checkZ.DeepScan();
// add all of the file information from the zip file into scanDir
for (int i = 0; i < checkZ.LocalFilesCount(); i++)
{
RvFile tFile = new RvFile(DBTypeGet.FileFromDir(ft))
{
Name = checkZ.Filename(i),
ZipFileIndex = i,
ZipFileHeaderPosition = checkZ.LocalHeader(i),
Size = checkZ.UncompressedSize(i),
CRC = checkZ.CRC32(i)
};
// all 3 levels read the CRC from the ZIP header
tFile.SetStatus(chechingDatStatus, GotStatus.Got);
tFile.FileStatusSet(FileStatus.SizeFromHeader | FileStatus.CRCFromHeader);
// if we are in level 2 or level 3 then do a full CheckSum Scan.
if (EScanLevel == eScanLevel.Level2 || EScanLevel == eScanLevel.Level3)
{
// DeepScan will return ZipReturn.ZipCRCDecodeError if the headers CRC and
// the actual CRC do not match.
// So we just need to set the MD5 and SHA1 from the ZIP file.
zr = checkZ.FileStatus(i);
if (zr == ZipReturn.ZipUntested)
{
_bgw.ReportProgress(0, new bgwShowCorrupt(zr, fullDir + " : " + checkZ.Filename(i)));
}
else if (zr != ZipReturn.ZipGood)
{
_bgw.ReportProgress(0, new bgwShowCorrupt(zr, fullDir + " : " + checkZ.Filename(i)));
tFile.GotStatus = GotStatus.Corrupt;
}
else
{
tFile.MD5 = checkZ.MD5(i);
tFile.SHA1 = checkZ.SHA1(i);
tFile.FileStatusSet(FileStatus.SizeVerified | FileStatus.CRCVerified | FileStatus.SHA1Verified | FileStatus.MD5Verified);
}
}
fileDir.ChildAdd(tFile);
}
}
else if (zr == ZipReturn.ZipFileLocked)
{
_bgw.ReportProgress(0, new bgwShowError(fullDir, "Zip File Locked"));
dbDir.TimeStamp = 0;
dbDir.GotStatus = GotStatus.FileLocked;
}
else
{
_bgw.ReportProgress(0, new bgwShowCorrupt(zr, fullDir));
dbDir.GotStatus = GotStatus.Corrupt;
}
checkZ.ZipFileClose();
}
break;
case FileType.Dir:
{
fileDir = new RvDir(FileType.Dir);
DirectoryInfo oDir = new DirectoryInfo(fullDir);
DirectoryInfo[] oDirs = oDir.GetDirectories();
FileInfo[] oFiles = oDir.GetFiles();
// add all the subdirectories into scanDir
foreach (DirectoryInfo dir in oDirs)
{
RvBase tDir = new RvDir(FileType.Dir)
{
Name = dir.Name,
TimeStamp = dir.LastWriteTime,
};
tDir.SetStatus(chechingDatStatus, GotStatus.Got);
fileDir.ChildAdd(tDir);
}
// add all the files into scanDir
foreach (FileInfo oFile in oFiles)
{
// if we find any zip files add them as zip files.
string fExt = Path.GetExtension(oFile.Name);
switch (fExt.ToLower())
{
case ".zip":
{
RvDir tGame = new RvDir(FileType.Zip)
{
Name = Path.GetFileNameWithoutExtension(oFile.Name),
TimeStamp = oFile.LastWriteTime,
};
tGame.SetStatus(chechingDatStatus, GotStatus.Got);
fileDir.ChildAdd(tGame);
}
break;
default:
{
string fName = oFile.Name;
if (fName == "__RomVault.tmp")
{
File.Delete(oFile.FullName);
continue;
}
// Scanning a file
//
// Level1 & 2 : (are the same for files) Fully checksum changed only files
// Here we are just getting the TimeStamp of the File, and later
// if the TimeStamp was not matched we will have to read the files CRC, MD5 & SHA1
//
// Level3: Fully checksum everything
// Get everything about the file right here so
// read CRC, MD5 & SHA1
// add all the files in the sub-directory to scanDir
RvFile tFile = new RvFile(FileType.File)
{
Name = fName,
Size = (ulong)oFile.Length,
TimeStamp = oFile.LastWriteTime
};
tFile.FileStatusSet(FileStatus.SizeVerified);
int errorCode = CHD.CheckFile(oFile, out tFile.SHA1CHD, out tFile.MD5CHD, out tFile.CHDVersion);
if (errorCode == 0)
{
if (tFile.SHA1CHD != null) tFile.FileStatusSet(FileStatus.SHA1CHDFromHeader);
if (tFile.MD5CHD != null) tFile.FileStatusSet(FileStatus.MD5CHDFromHeader);
tFile.SetStatus(chechingDatStatus, GotStatus.Got);
// if we are scanning at Level3 then we get all the info here
if (EScanLevel == eScanLevel.Level3)
{
DeepScanFile(fullDir, tFile);
ChdManCheck(fullDir, tFile);
}
}
else if (errorCode == 32)
{
tFile.GotStatus = GotStatus.FileLocked;
_bgw.ReportProgress(0, new bgwShowError(fullDir, "File Locked"));
}
else
{
string filename = Path.Combine(fullDir, tFile.Name);
ReportError.Show("File: " + filename + " Error: " + new Win32Exception(errorCode).Message + ". Scan Aborted.");
_fileErrorAbort = true;
return;
}
fileDir.ChildAdd(tFile);
}
break;
}
}
}
break;
default:
ReportError.SendAndShow("Un supported file type in CheckADir " + ft);
break;
}
#endregion
if (fileDir == null)
{
ReportError.SendAndShow("Unknown Reading File Type in Dir Scanner");
return;
}
if (report)
{
_bgw.ReportProgress(0, new bgwSetRange2(fileDir.ChildCount - 1));
_bgw.ReportProgress(0, new bgwRange2Visible(true));
}
if (!DBTypeGet.isCompressedDir(ft) && _bgw.CancellationPending) return;
Compare(dbDir, fileDir, report, true);
}
public static void Compare(RvDir dbDir, RvDir fileDir, bool report, bool enableCancel)
{
string fullDir = dbDir.FullName;
FileType ft = dbDir.FileType;
// now we scan down the dbDir and the scanDir, comparing them.
// if we find a match we mark dbDir as found.
// if we are missing a file in scanDir we mark that file in dbDir as missing.
// if we find extra files in scanDir we add it to dbDir and mark it as unknown.
// we also recurse into any sub directories.
int dbIndex = 0;
int fileIndex = 0;
while (dbIndex < dbDir.ChildCount || fileIndex < fileDir.ChildCount)
{
RvBase dbChild = null;
RvBase fileChild = null;
int res = 0;
if (dbIndex < dbDir.ChildCount && fileIndex < fileDir.ChildCount)
{
dbChild = dbDir.Child(dbIndex);
fileChild = fileDir.Child(fileIndex);
res = DBHelper.CompareName(dbChild, fileChild);
}
else if (fileIndex < fileDir.ChildCount)
{
//Get any remaining filedir's
fileChild = fileDir.Child(fileIndex);
res = 1;
}
else if (dbIndex < dbDir.ChildCount)
{
//Get any remaining dbDir's
dbChild = dbDir.Child(dbIndex);
res = -1;
}
if (report)
{
if (fileChild != null)
{
long timenow = DateTime.Now.Ticks;
if ((timenow - _lastUpdateTime) > (TimeSpan.TicksPerSecond / 10))
{
_lastUpdateTime = timenow;
_bgw.ReportProgress(0, new bgwValue2(fileIndex));
_bgw.ReportProgress(0, new bgwText2(Path.Combine(fullDir, fileChild.Name)));
}
}
}
// if this file was found in the DB
switch (res)
{
case 0:
if (dbChild == null || fileChild == null)
{
ReportError.SendAndShow(Resources.FileScanning_CheckADir_Error_in_File_Scanning_Code);
break;
}
//Complete MultiName Compare
List<RvBase> dbs = new List<RvBase>();
List<RvBase> files = new List<RvBase>();
int dbsCount = 1;
int filesCount = 1;
dbs.Add(dbChild);
files.Add(fileChild);
while (dbIndex + dbsCount < dbDir.ChildCount && DBHelper.CompareName(dbChild, dbDir.Child(dbIndex + dbsCount)) == 0)
{
dbs.Add(dbDir.Child(dbIndex + dbsCount));
dbsCount += 1;
}
while (fileIndex + filesCount < fileDir.ChildCount && DBHelper.CompareName(fileChild, fileDir.Child(fileIndex + filesCount)) == 0)
{
files.Add(fileDir.Child(fileIndex + filesCount));
filesCount += 1;
}
for (int indexfile = 0; indexfile < filesCount; indexfile++)
{
if (files[indexfile].SearchFound) continue;
for (int indexdb = 0; indexdb < dbsCount; indexdb++)
{
if (dbs[indexdb].SearchFound) continue;
bool matched = FullCompare(dbs[indexdb], files[indexfile], false, fullDir, EScanLevel);
if (!matched) continue;
MatchFound(dbs[indexdb], files[indexfile]);
dbs[indexdb].SearchFound = true;
files[indexfile].SearchFound = true;
}
if (files[indexfile].SearchFound) continue;
for (int indexdb = 0; indexdb < dbsCount; indexdb++)
{
if (dbs[indexdb].SearchFound) continue;
bool matched = FullCompare(dbs[indexdb], files[indexfile], true, fullDir, EScanLevel);
if (!matched) continue;
MatchFound(dbs[indexdb], files[indexfile]);
dbs[indexdb].SearchFound = true;
files[indexfile].SearchFound = true;
}
}
for (int indexdb = 0; indexdb < dbsCount; indexdb++)
{
if (dbs[indexdb].SearchFound)
{
dbIndex++;
continue;
}
DBFileNotFound(dbs[indexdb], dbDir, ref dbIndex);
}
for (int indexfile = 0; indexfile < filesCount; indexfile++)
{
if (files[indexfile].SearchFound)
continue;
NewFileFound(files[indexfile], dbDir, dbIndex);
dbIndex++;
}
fileIndex += filesCount;
break;
case 1:
NewFileFound(fileChild, dbDir, dbIndex);
dbIndex++;
fileIndex++;
break;
case -1:
DBFileNotFound(dbChild, dbDir, ref dbIndex);
break;
}
if (_fileErrorAbort) return;
if (enableCancel && !DBTypeGet.isCompressedDir(ft) && _bgw.CancellationPending) return;
}
}
private static void MatchFound(RvBase dbChild, RvBase fileChild)
{
// only check a zip if the filestamp has changed, we asume it is the same if the filestamp has not changed.
switch (dbChild.FileType)
{
case FileType.Zip:
if (dbChild.TimeStamp != fileChild.TimeStamp || EScanLevel == eScanLevel.Level3 ||
(EScanLevel == eScanLevel.Level2 && !IsDeepScanned((RvDir)dbChild)))
{
// this is done first as the CheckADir could change this value if the zip turns out to be corrupt
dbChild.FileAdd(fileChild);
CheckADir((RvDir)dbChild, false);
}
else
// this is still needed incase the filenames case (upper/lower characters) have changed, but nothing else
dbChild.FileCheckName(fileChild);
break;
case FileType.Dir:
RvDir tDir = (RvDir)dbChild;
if (tDir.Tree == null) // do not recurse into directories that are in the tree, as they are processed by the top level code.
CheckADir(tDir, true);
if (_fileErrorAbort) return;
dbChild.FileAdd(fileChild);
break;
case FileType.File:
case FileType.ZipFile:
if (dbChild.TimeStamp == fileChild.TimeStamp && dbChild.GotStatus == GotStatus.Corrupt)
fileChild.GotStatus = GotStatus.Corrupt;
dbChild.FileAdd(fileChild);
break;
default:
throw new Exception("Unsuported file type " + dbChild.FileType);
}
}
private static void NewFileFound(RvBase fileChild, RvDir dbDir, int dbIndex)
{
if (fileChild == null)
{
ReportError.SendAndShow(Resources.FileScanning_CheckADir_Error_in_File_Scanning_Code);
return;
}
// this could be an unknown file, or dirctory.
// if item is a directory add the directory and call back in again
// add the newly found item
switch (fileChild.FileType)
{
case FileType.Zip:
dbDir.ChildAdd(fileChild, dbIndex);
CheckADir((RvDir)fileChild, false);
break;
case FileType.Dir:
dbDir.ChildAdd(fileChild, dbIndex);
CheckADir((RvDir)fileChild, true);
break;
case FileType.File:
RvFile tChild = (RvFile)fileChild;
// if we have not read the files CRC in the checking code, we need to read it now.
if (tChild.GotStatus != GotStatus.FileLocked)
{
if (!IsDeepScanned(tChild))
DeepScanFile(dbDir.FullName, tChild);
if (!IschdmanScanned(tChild) && EScanLevel == eScanLevel.Level2)
ChdManCheck(dbDir.FullName, tChild);
}
dbDir.ChildAdd(fileChild, dbIndex);
break;
case FileType.ZipFile:
dbDir.ChildAdd(fileChild, dbIndex);
break;
default:
throw new Exception("Unsuported file type " + fileChild.FileType);
}
}
private static void DBFileNotFound(RvBase dbChild, RvDir dbDir, ref int dbIndex)
{
if (dbChild == null)
{
ReportError.SendAndShow(Resources.FileScanning_CheckADir_Error_in_File_Scanning_Code);
return;
}
if (dbChild.FileRemove() == EFile.Delete)
dbDir.ChildRemove(dbIndex);
else
{
switch (dbChild.FileType)
{
case FileType.Zip:
MarkAsMissing((RvDir)dbChild);
break;
case FileType.Dir:
RvDir tDir = (RvDir)dbChild;
if (tDir.Tree == null)
MarkAsMissing(tDir);
break;
}
dbIndex++;
}
}
private static bool IsDeepScanned(RvDir tZip)
{
for (int i = 0; i < tZip.ChildCount; i++)
{
RvFile zFile = tZip.Child(i) as RvFile;
if (zFile != null && zFile.GotStatus == GotStatus.Got &&
(!zFile.FileStatusIs(FileStatus.SizeVerified) || !zFile.FileStatusIs(FileStatus.CRCVerified) || !zFile.FileStatusIs(FileStatus.SHA1Verified) || !zFile.FileStatusIs(FileStatus.MD5Verified)))
return false;
}
return true;
}
private static void MarkAsMissing(RvDir dbDir)
{
for (int i = 0; i < dbDir.ChildCount; i++)
{
RvBase dbChild = dbDir.Child(i);
if (dbChild.FileRemove() == EFile.Delete)
{
dbDir.ChildRemove(i);
i--;
}
else
{
switch (dbChild.FileType)
{
case FileType.Zip:
MarkAsMissing((RvDir)dbChild);
break;
case FileType.Dir:
RvDir tDir = (RvDir)dbChild;
if (tDir.Tree == null)
MarkAsMissing(tDir);
break;
}
}
}
}
private static bool FullCompare(RvBase dbFile, RvBase testFile, bool secondPass, string fullDir = "", eScanLevel sLevel = eScanLevel.Level3)
{
Debug.WriteLine("Comparing Dat File " + dbFile.TreeFullName);
Debug.WriteLine("Comparing File " + testFile.TreeFullName);
int retv = DBHelper.CompareName(dbFile, testFile);
if (retv != 0) return false;
FileType dbfileType = dbFile.FileType;
FileType dbtestFile = testFile.FileType;
retv = Math.Sign(dbfileType.CompareTo(dbtestFile));
if (retv != 0) return false;
// filetypes are now know to be the same
// Dir's and Zip's are not deep scanned so matching here is done
if ((dbfileType == FileType.Dir) || (dbfileType == FileType.Zip))
return true;
RvFile dbFileF = (RvFile)dbFile;
RvFile testFileF = (RvFile)testFile;
if (dbFileF.Size != null && testFileF.Size != null)
{
retv = ULong.iCompare(dbFileF.Size, testFileF.Size);
if (retv != 0) return false;
}
if (dbFileF.CRC != null && testFileF.CRC != null)
{
retv = ArrByte.iCompare(dbFileF.CRC, testFileF.CRC);
if (retv != 0) return false;
}
if (dbFileF.SHA1 != null && testFileF.SHA1 != null)
{
retv = ArrByte.iCompare(dbFileF.SHA1, testFileF.SHA1);
if (retv != 0) return false;
}
if (dbFileF.MD5 != null && testFileF.MD5 != null)
{
retv = ArrByte.iCompare(dbFileF.MD5, testFileF.MD5);
if (retv != 0) return false;
}
if (dbFileF.SHA1CHD != null && testFileF.SHA1CHD != null)
{
retv = ArrByte.iCompare(dbFileF.SHA1CHD, testFileF.SHA1CHD);
if (retv != 0) return false;
}
if (dbFileF.MD5CHD != null && testFileF.MD5CHD != null)
{
retv = ArrByte.iCompare(dbFileF.MD5CHD, testFileF.MD5CHD);
if (retv != 0) return false;
}
// beyond here we only test files
if (dbtestFile != FileType.File)
return true;
// if scanning at level 3 then we have already deep checked the file so all is OK.
if (sLevel == eScanLevel.Level3)
return true;
// if we got this far then everything we have so far has matched, but that may not be enough.
// now we see if we need to get any more info and try again.
// if the file stamps do not match or the file in the DB we are comparing with has not been deep scanned
// and the file we are scanning has not already been deep scanned, then we need to do a deep scan, and check the deep scan values
// files are always deep scanned, so the test for IsDeepScanned(dbFileF) is probably not really needed here.
if ((dbFileF.TimeStamp != testFileF.TimeStamp || !IsDeepScanned(dbFileF)) && !IsDeepScanned(testFileF))
{
if (!secondPass)
return false;
DeepScanFile(fullDir, testFileF);
if (dbFileF.CRC != null && testFileF.CRC != null)
{
retv = ArrByte.iCompare(dbFileF.CRC, testFileF.CRC);
if (retv != 0) return false;
}
if (dbFileF.SHA1 != null && testFileF.SHA1 != null)
{
retv = ArrByte.iCompare(dbFileF.SHA1, testFileF.SHA1);
if (retv != 0) return false;
}
if (dbFileF.MD5 != null && testFileF.MD5 != null)
{
retv = ArrByte.iCompare(dbFileF.MD5, testFileF.MD5);
if (retv != 0) return false;
}
}
// CHDman test, if we are only scanning at level 1 then don't do CHDman test so we are done.
if (sLevel == eScanLevel.Level1)
return true;
if ((dbFileF.TimeStamp != testFileF.TimeStamp || (!IschdmanScanned(dbFileF)) && !IschdmanScanned(testFileF)))
{
ChdManCheck(fullDir, testFileF);
}
return true;
}
private static bool IsDeepScanned(RvFile tFile)
{
return (
tFile.FileStatusIs(FileStatus.SizeVerified) &&
tFile.FileStatusIs(FileStatus.CRCVerified) &&
tFile.FileStatusIs(FileStatus.SHA1Verified) &&
tFile.FileStatusIs(FileStatus.MD5Verified)
);
}
private static bool IschdmanScanned(RvFile tFile)
{
//if (!tFile.FileStatusIs(FileStatus.SHA1CHDFromHeader))
// return true;
if (tFile.GotStatus == GotStatus.Corrupt)
return true;
return tFile.FileStatusIs(FileStatus.SHA1CHDVerified);
}
private static void DeepScanFile(string directory, RvFile tFile)
{
string filename = Path.Combine(directory, tFile.Name);
int errorCode = UnCompFiles.CheckSumRead(filename, true, out tFile.CRC, out tFile.MD5, out tFile.SHA1);
if (errorCode == 32)
{
tFile.GotStatus = GotStatus.FileLocked;
return;
}
if (errorCode != 0)
{
ReportError.Show("File: " + filename + " Error: " + new Win32Exception(errorCode).Message + ". Scan Aborted.");
_fileErrorAbort = true;
return;
}
tFile.FileStatusSet(FileStatus.SizeVerified | FileStatus.CRCVerified | FileStatus.SHA1Verified | FileStatus.MD5Verified);
}
private static void ChdManCheck(string directory, RvFile tFile)
{
string filename = Path.Combine(directory, tFile.Name);
if (!tFile.FileStatusIs(FileStatus.SHA1CHDFromHeader)) return;
_bgw.ReportProgress(0, new bgwText2(filename));
string error;
CHD.CHDManCheck res = CHD.ChdmanCheck(filename, _bgw, out error);
switch (res)
{
case CHD.CHDManCheck.Good:
tFile.FileStatusSet(FileStatus.SHA1CHDVerified);
return;
case CHD.CHDManCheck.Corrupt:
_bgw.ReportProgress(0, new bgwShowError(error, filename));
tFile.GotStatus = GotStatus.Corrupt;
return;
case CHD.CHDManCheck.CHDUnknownError:
_bgw.ReportProgress(0, new bgwShowError(error, filename));
return;
case CHD.CHDManCheck.ChdmanNotFound:
return;
case CHD.CHDManCheck.CHDNotFound:
ReportError.Show("File: " + filename + " Error: Not Found scan Aborted.");
_fileErrorAbort = true;
return;
default:
ReportError.UnhandledExceptionHandler(error);
return;
}
}
}
}

479
ROMVault2/FindFixes.cs Normal file
View File

@@ -0,0 +1,479 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
using ROMVault2.Properties;
using ROMVault2.RvDB;
using ROMVault2.Utils;
namespace ROMVault2
{
public static class FindFixes
{
private static BackgroundWorker _bgw;
public static void ScanFiles(object sender, DoWorkEventArgs e)
{
try
{
_bgw = sender as BackgroundWorker;
if (_bgw == null) return;
Program.SyncCont = e.Argument as SynchronizationContext;
if (Program.SyncCont == null)
{
_bgw = null;
return;
}
_bgw.ReportProgress(0, new bgwText("Clearing DB Status"));
RepairStatus.ReportStatusReset(DB.DirTree);
List<RvFile> lstRomTableSortedCRCSize;
List<RvFile> lstRomTableSortedSHA1CHD;
_bgw.ReportProgress(0, new bgwText("Loading Rom List"));
DBHelper.GetSelectedFilesSortCRCSize(out lstRomTableSortedCRCSize);
DBHelper.GetSelectedFilesSortSHA1CHD(out lstRomTableSortedSHA1CHD);
_bgw.ReportProgress(0, new bgwText("Scanning for Fixes"));
_bgw.ReportProgress(0, new bgwSetRange(lstRomTableSortedCRCSize.Count));
int romIndex0 = 0;
int romIndex1 = 1;
while (romIndex1 < lstRomTableSortedCRCSize.Count)
{
if (romIndex1 % 100 == 0) _bgw.ReportProgress(romIndex1);
if (!ArrByte.bCompare(lstRomTableSortedCRCSize[romIndex0].CRC,lstRomTableSortedCRCSize[romIndex1].CRC) || lstRomTableSortedCRCSize[romIndex0].Size != lstRomTableSortedCRCSize[romIndex1].Size)
{
ListCheck(lstRomTableSortedCRCSize, romIndex0, romIndex1 - romIndex0);
romIndex0 = romIndex1;
}
romIndex1++;
}
ListCheck(lstRomTableSortedCRCSize, romIndex0, romIndex1 - romIndex0);
_bgw.ReportProgress(0, new bgwSetRange(lstRomTableSortedSHA1CHD.Count));
romIndex0 = 0;
romIndex1 = 1;
while (romIndex1 < lstRomTableSortedSHA1CHD.Count)
{
if (romIndex1 % 100 == 0) _bgw.ReportProgress(romIndex1);
if (!ArrByte.bCompare(lstRomTableSortedSHA1CHD[romIndex0].SHA1CHD,lstRomTableSortedSHA1CHD[romIndex1].SHA1CHD) )
{
ListCheckSHA1CHD(lstRomTableSortedSHA1CHD, romIndex0, romIndex1 - romIndex0);
romIndex0 = romIndex1;
}
romIndex1++;
}
ListCheckSHA1CHD(lstRomTableSortedSHA1CHD, romIndex0, romIndex1 - romIndex0);
_bgw = null;
Program.SyncCont = null;
}
catch (Exception exc)
{
ReportError.UnhandledExceptionHandler(exc);
if (_bgw != null) _bgw.ReportProgress(0, new bgwText("Updating Cache"));
DB.Write();
if (_bgw != null) _bgw.ReportProgress(0, new bgwText("Complete"));
_bgw = null;
Program.SyncCont = null;
}
}
public static void ListCheck(List<RvFile> lstRomTableSortedCRC, int start, int length)
{
if (lstRomTableSortedCRC.Count == 0)
return;
List<RvFile> missingFiles = new List<RvFile>(); // files we dont have that we need
List<RvFile> correctFiles = new List<RvFile>(); // files we have that are in the correct place
List<RvFile> unNeededFiles = new List<RvFile>(); // files we have that are not in the correct place
List<RvFile> inToSortFiles = new List<RvFile>(); // files we have that are in tosort
List<RvFile> allGotFiles = new List<RvFile>(); // all files we have
List<RvFile> corruptFiles = new List<RvFile>(); // corrupt files that we do not need, a corrupt file is missing if it is needed
// set the found status of this file
for (int iLoop = 0; iLoop < length; iLoop++)
{
RvFile tFile = lstRomTableSortedCRC[start + iLoop];
switch (tFile.RepStatus)
{
case RepStatus.UnScanned:
break;
case RepStatus.Missing:
missingFiles.Add(tFile); // these are checked in step 1 to fixes from the allGotFiles List.
break;
case RepStatus.Correct:
correctFiles.Add(tFile);
break;
case RepStatus.Corrupt:
if (tFile.DatStatus == DatStatus.InDatCollect)
missingFiles.Add(tFile); // corrupt files that are also InDatcollect are treated as missing files, and a fix should be found.
else
corruptFiles.Add(tFile); // all other corrupt files should be deleted or moved to tosort/corrupt
break;
case RepStatus.UnNeeded:
case RepStatus.Unknown:
unNeededFiles.Add(tFile);
break;
case RepStatus.NotCollected:
break;
case RepStatus.InToSort:
inToSortFiles.Add(tFile);
break;
case RepStatus.Ignore:
break; // Ignore File
default:
ReportError.SendAndShow(Resources.FindFixes_ListCheck_Unknown_test_status + tFile.DatFullName + Resources.Comma + tFile.DatStatus + Resources.Comma + tFile.RepStatus);
break;
}
}
allGotFiles.AddRange(correctFiles);
allGotFiles.AddRange(unNeededFiles);
allGotFiles.AddRange(inToSortFiles);
#region Step 1 Check the Missing files from the allGotFiles List.
// check to see if we can find any of the missing files in the gotFiles list.
// if we find them mark them as CanBeFixed,
// or if they are missing corrupt files set then as corruptCanBefixed
foreach (RvFile missingFile in missingFiles)
{
if (DBHelper.IsZeroLengthFile(missingFile))
{
missingFile.RepStatus = missingFile.RepStatus == RepStatus.Corrupt ? RepStatus.CorruptCanBeFixed : RepStatus.CanBeFixed;
continue;
}
foreach (RvFile gotFile in allGotFiles)
{
if (!CheckIfMissingFileCanBeFixedByGotFile(missingFile, gotFile)) continue;
missingFile.RepStatus = missingFile.RepStatus == RepStatus.Corrupt ? RepStatus.CorruptCanBeFixed : RepStatus.CanBeFixed;
break;
}
if (missingFile.RepStatus == RepStatus.Corrupt) missingFile.RepStatus = RepStatus.MoveToCorrupt;
}
#endregion
#region Step 2 Check all corrupt files.
// if we have a correct version of the corrupt file then the corrput file can just be deleted,
// otherwise if the corrupt file is not already in ToSort it should be moved out to ToSort.
// we can only check corrupt files using the CRC from the ZIP header, as it is corrupt so we cannot get a correct SHA1 / MD5 to check with
foreach (RvFile corruptFile in corruptFiles)
{
if (allGotFiles.Count>0)
corruptFile.RepStatus = RepStatus.Delete;
if (corruptFile.RepStatus == RepStatus.Corrupt && corruptFile.DatStatus != DatStatus.InToSort)
corruptFile.RepStatus = RepStatus.MoveToCorrupt;
}
#endregion
#region Step 3 Check if unNeeded files are needed for a fix, otherwise delete them or move them to tosort
foreach (RvFile unNeededFile in unNeededFiles)
{
/*
// check if we have a confirmed SHA1 / MD5 match of this file, and if we do we just mark this file to be deleted.
foreach (RvFile correctFile in correctFiles)
{
if (!FindSHA1MD5MatchingFiles(unNeededFile, correctFile)) continue;
unNeededFile.RepStatus = RepStatus.Delete;
break;
}
if (unNeededFile.RepStatus == RepStatus.Delete) continue;
*/
if (DBHelper.IsZeroLengthFile(unNeededFile))
{
unNeededFile.RepStatus = RepStatus.Delete;
continue;
}
// check if the unNeededFile is needed to fix a missing file
foreach (RvFile missingFile in missingFiles)
{
if (!CheckIfMissingFileCanBeFixedByGotFile(missingFile, unNeededFile)) continue;
unNeededFile.RepStatus = RepStatus.NeededForFix;
break;
}
if (unNeededFile.RepStatus == RepStatus.NeededForFix) continue;
// now that we know this file is not needed for a fix do a CRC only find against correct files to see if this file can be deleted.
foreach (RvFile correctFile in correctFiles)
{
if (!CheckIfGotfileAndMatchingFileAreFullMatches(unNeededFile, correctFile)) continue;
unNeededFile.RepStatus = RepStatus.Delete;
break;
}
if (unNeededFile.RepStatus == RepStatus.Delete) continue;
// and finally see if the file is already in ToSort, and if it is deleted.
foreach (RvFile inToSortFile in inToSortFiles)
{
if (!CheckIfGotfileAndMatchingFileAreFullMatches(unNeededFile, inToSortFile)) continue;
unNeededFile.RepStatus = RepStatus.Delete;
break;
}
if (unNeededFile.RepStatus == RepStatus.Delete) continue;
// otherwise move the file out to ToSort
unNeededFile.RepStatus = RepStatus.MoveToSort;
}
#endregion
#region Step 4 Check if ToSort files are needed for a fix, otherwise delete them or leave them in tosort
foreach (RvFile inToSortFile in inToSortFiles)
{
/*
// check if we have a confirmed SHA1 / MD5 match of this file, and if we do we just mark this file to be deleted.
foreach (RvFile correctFile in correctFiles)
{
if (!FindSHA1MD5MatchingFiles(inToSortFile, correctFile)) continue;
inToSortFile.RepStatus = RepStatus.Delete;
break;
}
if (inToSortFile.RepStatus == RepStatus.Delete) continue;
*/
// check if the ToSortFile is needed to fix a missing file
foreach (RvFile missingFile in missingFiles)
{
if (!CheckIfMissingFileCanBeFixedByGotFile(missingFile, inToSortFile)) continue;
inToSortFile.RepStatus = RepStatus.NeededForFix;
break;
}
if (inToSortFile.RepStatus == RepStatus.NeededForFix) continue;
// now that we know this file is not needed for a fix do a CRC only find against correct files to see if this file can be deleted.
foreach (RvFile correctFile in correctFiles)
{
if (!CheckIfGotfileAndMatchingFileAreFullMatches(inToSortFile, correctFile)) continue;
inToSortFile.RepStatus = RepStatus.Delete;
break;
}
// otherwise leave the file in ToSort
}
#endregion
//need to check here for roms that just need renamed inside the one ZIP
//this prevents Zips from self deadlocking
for (int iLoop0 = 0; iLoop0 < length; iLoop0++)
{
if (lstRomTableSortedCRC[start + iLoop0].RepStatus != RepStatus.NeededForFix) continue;
for (int iLoop1 = 0; iLoop1 < length; iLoop1++)
{
if (lstRomTableSortedCRC[start + iLoop1].RepStatus != RepStatus.CanBeFixed) continue;
if (!CheckIfMissingFileCanBeFixedByGotFile(lstRomTableSortedCRC[start + iLoop1], lstRomTableSortedCRC[start + iLoop0])) continue;
if (DBHelper.RomFromSameGame(lstRomTableSortedCRC[start + iLoop0], lstRomTableSortedCRC[start + iLoop1]))
lstRomTableSortedCRC[start + iLoop0].RepStatus = RepStatus.Rename;
}
}
}
// find fix files, if the gotFile has been fully scanned check the SHA1/MD5, if not then just return true as the CRC/Size is all we have to go on.
// this means that if the gotfile has not been fully scanned this will return true even with the source and destination SHA1/MD5 possibly different.
public static bool CheckIfMissingFileCanBeFixedByGotFile(RvFile missingFile, RvFile gotFile)
{
if (missingFile.FileStatusIs(FileStatus.SHA1FromDAT) && gotFile.FileStatusIs(FileStatus.SHA1Verified) && !ArrByte.bCompare(missingFile.SHA1, gotFile.SHA1))
return false;
if (missingFile.FileStatusIs(FileStatus.MD5FromDAT) && gotFile.FileStatusIs(FileStatus.MD5Verified) && !ArrByte.bCompare(missingFile.MD5, gotFile.MD5))
return false;
return true;
}
private static bool CheckIfGotfileAndMatchingFileAreFullMatches(RvFile gotFile, RvFile matchingFile)
{
if (gotFile.FileStatusIs(FileStatus.SHA1Verified) && matchingFile.FileStatusIs(FileStatus.SHA1Verified) && !ArrByte.bCompare(gotFile.SHA1, matchingFile.SHA1))
return false;
if (gotFile.FileStatusIs(FileStatus.MD5Verified) && matchingFile.FileStatusIs(FileStatus.MD5Verified) && !ArrByte.bCompare(gotFile.MD5, matchingFile.MD5))
return false;
return true;
}
private static void ListCheckSHA1CHD(List<RvFile> lstRomTableSortedSHA1CHD, int start, int length)
{
if (lstRomTableSortedSHA1CHD.Count == 0)
return;
List<RvFile> missingFiles = new List<RvFile>(); // files we done have have that we need
List<RvFile> correctFiles = new List<RvFile>(); // files we have that are in the correct place
List<RvFile> unNeededFiles = new List<RvFile>(); // files we have that are not in the correct place
List<RvFile> inToSortFiles = new List<RvFile>(); // files we have that are in tosort
List<RvFile> allGotFiles = new List<RvFile>(); // all files we have
List<RvFile> corruptFiles = new List<RvFile>(); // corrupt files that we do not need, a corrupt file is missing if it is needed
// set the found status of this file
for (int iLoop = 0; iLoop < length; iLoop++)
{
RvFile tFile = lstRomTableSortedSHA1CHD[start + iLoop];
switch (tFile.RepStatus)
{
case RepStatus.Missing:
missingFiles.Add(tFile); // these are checked in step 1 to fixes from the allGotFiles List.
break;
case RepStatus.Correct:
correctFiles.Add(tFile);
break;
case RepStatus.Corrupt:
case RepStatus.MoveToCorrupt:
if (tFile.DatStatus == DatStatus.InDatCollect)
missingFiles.Add(tFile); // corrupt files that are also InDatcollect are treated as missing files, and a fix should be found.
else
corruptFiles.Add(tFile); // all other corrupt files should be deleted or moved to tosort/corrupt
break;
case RepStatus.UnNeeded:
case RepStatus.Unknown:
case RepStatus.MoveToSort:
case RepStatus.InToSort:
case RepStatus.Delete:
case RepStatus.NeededForFix:
case RepStatus.Rename:
if (tFile.IsInToSort)
inToSortFiles.Add(tFile);
else
unNeededFiles.Add(tFile);
break;
case RepStatus.NotCollected:
break;
case RepStatus.Ignore:
break; // Ignore File
default:
ReportError.SendAndShow(Resources.FindFixes_ListCheck_Unknown_test_status + tFile.DatFullName + Resources.Comma + tFile.DatStatus + Resources.Comma + tFile.RepStatus);
break;
}
}
allGotFiles.AddRange(correctFiles);
allGotFiles.AddRange(unNeededFiles);
allGotFiles.AddRange(inToSortFiles);
#region Step 1 Check the Missing files from the allGotFiles List.
// check to see if we can find any of the missing files in the gotFiles list.
// if we find them mark them as CanBeFixed,
foreach (RvFile missingFile in missingFiles)
{
if (allGotFiles.Count>0)
missingFile.RepStatus = (missingFile.RepStatus == RepStatus.Corrupt) || (missingFile.RepStatus == RepStatus.MoveToCorrupt) ? RepStatus.CorruptCanBeFixed : RepStatus.CanBeFixed;
}
#endregion
#region Step 2 Check all corrupt files.
// if we have a correct version of the corrupt file then the corrput file can just be deleted,
// otherwise if the corrupt file is not already in ToSort it should be moved out to ToSort.
// we can only check corrupt files using the CRC from the ZIP header, as it is corrupt so we cannot get a correct SHA1 / MD5 to check with
foreach (RvFile corruptFile in corruptFiles)
{
if (allGotFiles.Count > 0)
corruptFile.RepStatus = RepStatus.Delete;
if (corruptFile.RepStatus == RepStatus.Corrupt && corruptFile.DatStatus != DatStatus.InToSort)
corruptFile.RepStatus = RepStatus.MoveToCorrupt;
}
#endregion
#region Step 3 Check if unNeeded files are needed for a fix, otherwise delete them or move them to tosort
foreach (RvFile unNeededFile in unNeededFiles)
{
// check if the unNeededFile is needed to fix a missing file
if (missingFiles.Count > 0)
{
unNeededFile.RepStatus = RepStatus.NeededForFix;
continue;
}
// now that we know this file is not needed for a fix if we have a correct version of it, it can be deleted.
if (correctFiles.Count > 0)
{
// this probably should check its old state
if (unNeededFile.RepStatus!=RepStatus.NeededForFix)
unNeededFile.RepStatus = RepStatus.Delete;
continue;
}
if (inToSortFiles.Count > 0)
{
if (unNeededFile.RepStatus != RepStatus.NeededForFix)
unNeededFile.RepStatus = RepStatus.Delete;
continue;
}
// otherwise move the file out to ToSort
if (unNeededFile.RepStatus != RepStatus.NeededForFix)
unNeededFile.RepStatus = RepStatus.MoveToSort;
}
#endregion
#region Step 4 Check if ToSort files are needed for a fix, otherwise delete them or leave them in tosort
foreach (RvFile inToSortFile in inToSortFiles)
{
// check if the ToSortFile is needed to fix a missing file
if (missingFiles.Count > 0)
{
inToSortFile.RepStatus=RepStatus.NeededForFix;
continue;
}
// now that we know this file is not needed for a fix do a CRC only find against correct files to see if this file can be deleted.
if (correctFiles.Count <= 0) continue;
if (inToSortFile.RepStatus != RepStatus.NeededForFix)
inToSortFile.RepStatus = RepStatus.Delete;
// otherwise leave the file in ToSort
}
#endregion
}
}
}

675
ROMVault2/FixFileCopy.cs Normal file
View File

@@ -0,0 +1,675 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Security.Cryptography;
using ROMVault2.RvDB;
using ROMVault2.SupportedFiles;
using ROMVault2.SupportedFiles.Zip;
using ROMVault2.SupportedFiles.Zip.ZLib;
using ROMVault2.Utils;
namespace ROMVault2
{
public enum ReturnCode { Good, RescanNeeded, FindFixes, LogicError, FileSystemError, SourceCRCCheckSumError, SourceCheckSumError, DestinationCheckSumError, StartOver }
public static class FixFileCopy
{
private const int BufferSize = 4096 * 128;
private static byte[] _buffer;
// This Function returns:
// Good : Everything Worked Correctly
// RescanNeeded : Something unexpectidly changed in the files, so Stop prompt user to rescan.
// LogicError : This Should never happen and is a logic problem in the code
// FileSystemError : Something is wrong with the files
/// <summary>
/// Performs the RomVault File Copy, with the source and destination being files or zipped files
/// </summary>
/// <param name="fileIn">This is the file being copied, it may be a zipped file or a regular file system file</param>
/// <param name="zipFileOut">This is the zip file that is being writen to, if it is null a new zip file will be made if we are coping to a zip</param>
/// <param name="zipFilenameOut">This is the name of the .zip file to be made that will be created in zipFileOut</param>
/// <param name="fileOut">This is the actual output filename</param>
/// <param name="forceRaw">if true then we will do a raw copy, this is so that we can copy corrupt zips</param>
/// <param name="error">This is the returned error message if this copy fails</param>
/// <param name="foundFile">If we are SHA1/MD5 checking the source file for the first time, and it is different from what we expected the correct values for this file are returned in foundFile</param>
/// <returns>ReturnCode.Good is the valid return code otherwire we have an error</returns>
public static ReturnCode CopyFile(RvFile fileIn, ref ZipFile zipFileOut, string zipFilenameOut, RvFile fileOut, bool forceRaw, out string error, out RvFile foundFile)
{
foundFile = null;
error = "";
if (_buffer == null)
_buffer = new byte[BufferSize];
bool rawCopy = RawCopy(fileIn, fileOut, forceRaw);
ulong streamSize = 0;
ushort compressionMethod = 8;
bool sourceTrrntzip = false;
ZipFile zipFileIn = null;
System.IO.Stream readStream = null;
bool isZeroLengthFile = DBHelper.IsZeroLengthFile(fileOut);
if (!isZeroLengthFile)
{
#region check that the in and out file match
if (fileOut.FileStatusIs(FileStatus.SizeFromDAT) && fileOut.Size != null && fileIn.Size != fileOut.Size)
{
error = "Source and destination Size does not match. Logic Error.";
return ReturnCode.LogicError;
}
if (fileOut.FileStatusIs(FileStatus.CRCFromDAT) && fileOut.CRC != null && !ArrByte.bCompare(fileIn.CRC, fileOut.CRC))
{
error = "Source and destination CRC does not match. Logic Error.";
return ReturnCode.LogicError;
}
if (fileOut.FileStatusIs(FileStatus.SHA1FromDAT) && fileIn.FileStatusIs(FileStatus.SHA1Verified))
{
if (fileIn.SHA1 != null && fileOut.SHA1 != null && !ArrByte.bCompare(fileIn.SHA1, fileOut.SHA1))
{
error = "Source and destination SHA1 does not match. Logic Error.";
return ReturnCode.LogicError;
}
}
if (fileOut.FileStatusIs(FileStatus.MD5CHDFromDAT) && fileIn.FileStatusIs(FileStatus.MD5Verified))
{
if (fileIn.MD5 != null && fileOut.MD5 != null && !ArrByte.bCompare(fileIn.MD5, fileOut.MD5))
{
error = "Source and destination SHA1 does not match. Logic Error.";
return ReturnCode.LogicError;
}
}
#endregion
#region Find and Check/Open Input Files
if (fileIn.FileType == FileType.ZipFile) // Input is a ZipFile
{
RvDir zZipFileIn = fileIn.Parent;
if (zZipFileIn.FileType != FileType.Zip)
{
error = "Zip File Open but Source File is not a zip, Logic Error.";
return ReturnCode.LogicError;
}
string fileNameIn = zZipFileIn.FullName;
sourceTrrntzip = (zZipFileIn.ZipStatus & ZipStatus.TrrntZip) == ZipStatus.TrrntZip;
//if (zZipFileIn.ZipFileType == RvZip.ZipType.Zip)
//{
zipFileIn = new ZipFile();
ZipReturn zr1;
if (fileIn.ZipFileHeaderPosition != null)
zr1 = zipFileIn.ZipFileOpen(fileNameIn, zZipFileIn.TimeStamp, false);
else
zr1 = zipFileIn.ZipFileOpen(fileNameIn, zZipFileIn.TimeStamp, true);
switch (zr1)
{
case ZipReturn.ZipGood:
break;
case ZipReturn.ZipErrorFileNotFound:
error = "File not found, Rescan required before fixing " + fileIn.Name;
return ReturnCode.FileSystemError;
case ZipReturn.ZipErrorTimeStamp:
error = "File has changed, Rescan required before fixing " + fileIn.Name;
return ReturnCode.FileSystemError;
default:
error = "Error Open Zip" + zr1 + ", with File " + fileIn.DatFullName;
return ReturnCode.FileSystemError;
}
if (fileIn.ZipFileHeaderPosition != null)
zipFileIn.ZipFileOpenReadStreamQuick((ulong)fileIn.ZipFileHeaderPosition, rawCopy, out readStream, out streamSize, out compressionMethod);
else
zipFileIn.ZipFileOpenReadStream(fileIn.ZipFileIndex, rawCopy, out readStream, out streamSize, out compressionMethod);
}
else // Input is a regular file
{
string fileNameIn = fileIn.FullName;
if (!IO.File.Exists(fileNameIn))
{
error = "Rescan needed, File Changed :" + fileNameIn;
return ReturnCode.RescanNeeded;
}
IO.FileInfo fileInInfo = new IO.FileInfo(fileNameIn);
if (fileInInfo.LastWriteTime != fileIn.TimeStamp)
{
error = "Rescan needed, File Changed :" + fileNameIn;
return ReturnCode.RescanNeeded;
}
int errorCode = IO.FileStream.OpenFileRead(fileNameIn, out readStream);
if (errorCode != 0)
{
error = new Win32Exception(errorCode).Message + ". " + fileNameIn;
return ReturnCode.FileSystemError;
}
if (fileIn.Size == null)
{
error = "Null File Size found in Fixing File :" + fileNameIn;
return ReturnCode.LogicError;
}
streamSize = (ulong)fileIn.Size;
if ((ulong)readStream.Length != streamSize)
{
error = "Rescan needed, File Length Changed :" + fileNameIn;
return ReturnCode.RescanNeeded;
}
}
#endregion
}
else
{
sourceTrrntzip = true;
}
if (!rawCopy && (Settings.FixLevel == eFixLevel.TrrntZipLevel1 || Settings.FixLevel == eFixLevel.TrrntZipLevel2 || Settings.FixLevel == eFixLevel.TrrntZipLevel3))
compressionMethod = 8;
#region Find and Check/Open Output Files
System.IO.Stream writeStream;
if (fileOut.FileType == FileType.ZipFile)
{
// if ZipFileOut == null then we have not open the output zip yet so open it from writing.
if (zipFileOut == null)
{
if (IO.Path.GetFileName(zipFilenameOut) == "__RomVault.tmp")
{
if (IO.File.Exists(zipFilenameOut))
IO.File.Delete(zipFilenameOut);
}
else if (IO.File.Exists(zipFilenameOut))
{
error = "Rescan needed, File Changed :" + zipFilenameOut;
return ReturnCode.RescanNeeded;
}
zipFileOut = new ZipFile();
ZipReturn zrf = zipFileOut.ZipFileCreate(zipFilenameOut);
if (zrf != ZipReturn.ZipGood)
{
error = "Error Opening Write Stream " + zrf;
return ReturnCode.FileSystemError;
}
}
else
{
if (zipFileOut.ZipOpen != ZipOpenType.OpenWrite)
{
error = "Output Zip File is not set to OpenWrite, Logic Error.";
return ReturnCode.LogicError;
}
if (zipFileOut.ZipFilename != (new IO.FileInfo(zipFilenameOut).FullName))
{
error = "Output Zip file has changed name from " + zipFileOut.ZipFilename + " to " + zipFilenameOut + ". Logic Error";
return ReturnCode.LogicError;
}
}
if (fileIn.Size == null)
{
error = "Null File Size found in Fixing File :" + fileIn.FullName;
return ReturnCode.LogicError;
}
ZipReturn zr = zipFileOut.ZipFileOpenWriteStream(rawCopy, sourceTrrntzip, fileOut.Name, (ulong)fileIn.Size, compressionMethod, out writeStream);
if (zr != ZipReturn.ZipGood)
{
error = "Error Opening Write Stream " + zr;
return ReturnCode.FileSystemError;
}
}
else
{
if (IO.File.Exists(zipFilenameOut) && fileOut.GotStatus != GotStatus.Corrupt)
{
error = "Rescan needed, File Changed :" + zipFilenameOut;
return ReturnCode.RescanNeeded;
}
int errorCode = IO.FileStream.OpenFileWrite(zipFilenameOut, out writeStream);
if (errorCode != 0)
{
error = new Win32Exception(errorCode).Message + ". " + zipFilenameOut;
return ReturnCode.FileSystemError;
}
}
#endregion
byte[] bCRC;
byte[] bMD5 = null;
byte[] bSHA1 = null;
if (!isZeroLengthFile)
{
#region Do Data Tranfer
CRC32Hash crc32 = null;
MD5 md5 = null;
SHA1 sha1 = null;
if (!rawCopy)
{
crc32 = new CRC32Hash();
md5 = MD5.Create();
sha1 = SHA1.Create();
}
ulong sizetogo = streamSize;
while (sizetogo > 0)
{
int sizenow = sizetogo > BufferSize ? BufferSize : (int)sizetogo;
try
{
readStream.Read(_buffer, 0, sizenow);
}
catch (ZlibException)
{
if (fileIn.FileType == FileType.ZipFile && zipFileIn != null)
{
ZipReturn zr = zipFileIn.ZipFileCloseReadStream();
if (zr != ZipReturn.ZipGood)
{
error = "Error Closing " + zr + " Stream :" + zipFileIn.Filename(fileIn.ReportIndex);
return ReturnCode.FileSystemError;
}
zipFileIn.ZipFileClose();
}
else
{
readStream.Close();
}
if (fileOut.FileType == FileType.ZipFile)
{
ZipReturn zr = zipFileOut.ZipFileCloseWriteStream(new byte[] { 0, 0, 0, 0 });
if (zr != ZipReturn.ZipGood)
{
error = "Error Closing Stream " + zr;
return ReturnCode.FileSystemError;
}
zipFileOut.ZipFileRollBack();
}
else
{
writeStream.Flush();
writeStream.Close();
IO.File.Delete(zipFilenameOut);
}
error = "Error in Data Stream";
return ReturnCode.SourceCRCCheckSumError;
}
catch (Exception e)
{
error = "Error reading Source File " + e.Message;
return ReturnCode.FileSystemError;
}
if (!rawCopy)
{
crc32.TransformBlock(_buffer, 0, sizenow, null, 0);
md5.TransformBlock(_buffer, 0, sizenow, null, 0);
sha1.TransformBlock(_buffer, 0, sizenow, null, 0);
}
try
{
writeStream.Write(_buffer, 0, sizenow);
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
error = "Error writing out file. " + Environment.NewLine + e.Message;
return ReturnCode.FileSystemError;
}
sizetogo = sizetogo - (ulong)sizenow;
}
writeStream.Flush();
#endregion
#region Collect Checksums
// if we did a full copy then we just calculated all the checksums while doing the copy
if (!rawCopy)
{
crc32.TransformFinalBlock(_buffer, 0, 0);
md5.TransformFinalBlock(_buffer, 0, 0);
sha1.TransformFinalBlock(_buffer, 0, 0);
bCRC = crc32.Hash;
bMD5 = md5.Hash;
bSHA1 = sha1.Hash;
}
// if we raw copied and the source file has been FileChecked then we can trust the checksums in the source file
else
{
bCRC = ArrByte.Copy(fileIn.CRC);
if (fileIn.FileStatusIs(FileStatus.MD5Verified)) bMD5 = ArrByte.Copy(fileIn.MD5);
if (fileIn.FileStatusIs(FileStatus.SHA1Verified)) bSHA1 = ArrByte.Copy(fileIn.SHA1);
}
#endregion
#region close the ReadStream
if (fileIn.FileType == FileType.ZipFile && zipFileIn != null)
{
ZipReturn zr = zipFileIn.ZipFileCloseReadStream();
if (zr != ZipReturn.ZipGood)
{
error = "Error Closing " + zr + " Stream :" + zipFileIn.Filename(fileIn.ReportIndex);
return ReturnCode.FileSystemError;
}
zipFileIn.ZipFileClose();
}
else
{
readStream.Close();
//if (IO.File.Exists(tmpFilename))
// IO.File.Delete(tmpFilename);
}
#endregion
}
else
{
// Zero Length File (Directory in a Zip)
if (fileOut.FileType == FileType.ZipFile)
{
zipFileOut.ZipFileAddDirectory();
}
bCRC = VarFix.CleanMD5SHA1("00000000", 8);
bMD5 = VarFix.CleanMD5SHA1("d41d8cd98f00b204e9800998ecf8427e", 32);
bSHA1 = VarFix.CleanMD5SHA1("da39a3ee5e6b4b0d3255bfef95601890afd80709", 40);
}
#region close the WriteStream
if (fileOut.FileType == FileType.ZipFile)
{
ZipReturn zr = zipFileOut.ZipFileCloseWriteStream(bCRC);
if (zr != ZipReturn.ZipGood)
{
error = "Error Closing Stream " + zr;
return ReturnCode.FileSystemError;
}
fileOut.ZipFileIndex = zipFileOut.LocalFilesCount() - 1;
fileOut.ZipFileHeaderPosition = zipFileOut.LocalHeader(fileOut.ZipFileIndex);
}
else
{
writeStream.Flush();
writeStream.Close();
IO.FileInfo fi = new IO.FileInfo(zipFilenameOut);
fileOut.TimeStamp = fi.LastWriteTime;
}
#endregion
if (!isZeroLengthFile)
{
if (!rawCopy)
{
if (!ArrByte.bCompare(bCRC, fileIn.CRC))
{
fileIn.GotStatus = GotStatus.Corrupt;
error = "Source CRC does not match Source Data stream, corrupt Zip";
if (fileOut.FileType == FileType.ZipFile)
zipFileOut.ZipFileRollBack();
else
IO.File.Delete(zipFilenameOut);
return ReturnCode.SourceCRCCheckSumError;
}
fileIn.FileStatusSet(FileStatus.CRCVerified | FileStatus.SizeVerified);
bool sourceFailed = false;
// check to see if we have a MD5 from the DAT file
if (fileIn.FileStatusIs(FileStatus.MD5FromDAT))
{
if (fileIn.MD5 == null)
{
error = "Should have an filein MD5 from Dat but not found. Logic Error.";
return ReturnCode.LogicError;
}
if (!ArrByte.bCompare(fileIn.MD5, bMD5))
sourceFailed = true;
else
fileIn.FileStatusSet(FileStatus.MD5Verified);
}
// check to see if we have an MD5 (not from the DAT) so must be from previously scanning this file.
else if (fileIn.MD5 != null)
{
if (!ArrByte.bCompare(fileIn.MD5, bMD5))
{
// if we had an MD5 from a preview scan and it now does not match, something has gone really bad.
error = "The MD5 found does not match a previously scanned MD5, this should not happen, unless something got corrupt.";
return ReturnCode.LogicError;
}
}
else // (FileIn.MD5 == null)
{
fileIn.MD5 = bMD5;
fileIn.FileStatusSet(FileStatus.MD5Verified);
}
// check to see if we have a SHA1 from the DAT file
if (fileIn.FileStatusIs(FileStatus.SHA1FromDAT))
{
if (fileIn.SHA1 == null)
{
error = "Should have an filein SHA1 from Dat but not found. Logic Error.";
return ReturnCode.LogicError;
}
if (!ArrByte.bCompare(fileIn.SHA1, bSHA1))
sourceFailed = true;
else
fileIn.FileStatusSet(FileStatus.SHA1Verified);
}
// check to see if we have an SHA1 (not from the DAT) so must be from previously scanning this file.
else if (fileIn.SHA1 != null)
{
if (!ArrByte.bCompare(fileIn.SHA1, bSHA1))
{
// if we had an SHA1 from a preview scan and it now does not match, something has gone really bad.
error = "The SHA1 found does not match a previously scanned SHA1, this should not happen, unless something got corrupt.";
return ReturnCode.LogicError;
}
}
else // (FileIn.SHA1 == null)
{
fileIn.SHA1 = bSHA1;
fileIn.FileStatusSet(FileStatus.SHA1Verified);
}
if (sourceFailed)
{
if (fileIn.FileType == FileType.ZipFile)
{
RvFile tZFile = new RvFile(FileType.ZipFile);
foundFile = tZFile;
tZFile.ZipFileIndex = fileIn.ZipFileIndex;
tZFile.ZipFileHeaderPosition = fileIn.ZipFileHeaderPosition;
}
else
{
foundFile = new RvFile(fileIn.FileType);
}
foundFile.Name = fileIn.Name;
foundFile.Size = fileIn.Size;
foundFile.CRC = bCRC;
foundFile.MD5 = bMD5;
foundFile.SHA1 = bSHA1;
foundFile.TimeStamp = fileIn.TimeStamp;
foundFile.SetStatus(DatStatus.NotInDat, GotStatus.Got);
foundFile.FileStatusSet(FileStatus.SizeVerified | FileStatus.CRCVerified | FileStatus.MD5Verified | FileStatus.SHA1Verified);
if (fileOut.FileType == FileType.ZipFile)
zipFileOut.ZipFileRollBack();
else
IO.File.Delete(zipFilenameOut);
return ReturnCode.SourceCheckSumError;
}
}
}
if (fileOut.FileType == FileType.ZipFile)
{
fileOut.FileStatusSet(FileStatus.SizeFromHeader | FileStatus.CRCFromHeader);
}
if (fileOut.FileStatusIs(FileStatus.CRCFromDAT) && fileOut.CRC != null && !ArrByte.bCompare(fileOut.CRC, bCRC))
{
//Rollback the file
if (fileOut.FileType == FileType.ZipFile)
zipFileOut.ZipFileRollBack();
else
IO.File.Delete(zipFilenameOut);
return ReturnCode.DestinationCheckSumError;
}
fileOut.CRC = bCRC;
if (!rawCopy || fileIn.FileStatusIs(FileStatus.CRCVerified))
fileOut.FileStatusSet(FileStatus.CRCVerified);
if (bSHA1 != null)
{
if (fileOut.FileStatusIs(FileStatus.SHA1FromDAT) && fileOut.SHA1 != null && !ArrByte.bCompare(fileOut.SHA1, bSHA1))
{
//Rollback the file
if (fileOut.FileType == FileType.ZipFile)
zipFileOut.ZipFileRollBack();
else
IO.File.Delete(zipFilenameOut);
return ReturnCode.DestinationCheckSumError;
}
fileOut.SHA1 = bSHA1;
fileOut.FileStatusSet(FileStatus.SHA1Verified);
}
if (bMD5 != null)
{
if (fileOut.FileStatusIs(FileStatus.MD5FromDAT) && fileOut.MD5 != null && !ArrByte.bCompare(fileOut.MD5, bMD5))
{
//Rollback the file
if (fileOut.FileType == FileType.ZipFile)
zipFileOut.ZipFileRollBack();
else
IO.File.Delete(zipFilenameOut);
return ReturnCode.DestinationCheckSumError;
}
fileOut.MD5 = bMD5;
fileOut.FileStatusSet(FileStatus.MD5Verified);
}
if (fileIn.Size != null)
{
fileOut.Size = fileIn.Size;
fileOut.FileStatusSet(FileStatus.SizeVerified);
}
if (fileIn.GotStatus == GotStatus.Corrupt)
fileOut.GotStatus = GotStatus.Corrupt;
else
fileOut.GotStatus = GotStatus.Got; // Changes RepStatus to Correct
fileOut.FileStatusSet(FileStatus.SizeVerified);
if (fileOut.SHA1CHD == null && fileIn.SHA1CHD != null) fileOut.SHA1CHD = fileIn.SHA1CHD;
if (fileOut.MD5CHD == null && fileIn.MD5CHD != null) fileOut.MD5CHD = fileIn.MD5CHD;
fileOut.CHDVersion = fileIn.CHDVersion;
fileOut.FileStatusSet(FileStatus.SHA1CHDFromHeader | FileStatus.MD5CHDFromHeader | FileStatus.SHA1CHDVerified | FileStatus.MD5CHDVerified, fileIn);
return ReturnCode.Good;
}
//Raw Copy
// Returns True is a raw copy can be used
// Returns False is a full recompression is required
private static bool RawCopy(RvFile fileIn, RvFile fileOut, bool forceRaw)
{
if (fileIn == null || fileOut == null)
return false;
if ((fileIn.FileType != FileType.ZipFile) || (fileOut.FileType != FileType.ZipFile))
return false;
if (fileIn.Parent == null)
return false;
if (forceRaw) return true;
bool trrntzipped = (fileIn.Parent.ZipStatus & ZipStatus.TrrntZip) == ZipStatus.TrrntZip;
bool deepchecked = fileIn.FileStatusIs(FileStatus.SHA1Verified) && fileIn.FileStatusIs(FileStatus.MD5Verified);
switch (Settings.FixLevel)
{
case eFixLevel.TrrntZipLevel1:
return trrntzipped;
case eFixLevel.TrrntZipLevel2:
return trrntzipped && deepchecked;
case eFixLevel.TrrntZipLevel3:
return false;
case eFixLevel.Level1:
return true;
case eFixLevel.Level2:
return deepchecked;
case eFixLevel.Level3:
return false;
}
return false;
}
}
}

1850
ROMVault2/FixFiles.cs Normal file

File diff suppressed because it is too large Load Diff

220
ROMVault2/FrmProgressWindow.Designer.cs generated Normal file
View File

@@ -0,0 +1,220 @@
namespace ROMVault2
{
partial class FrmProgressWindow
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmProgressWindow));
this.progressBar2 = new System.Windows.Forms.ProgressBar();
this.progressBar = new System.Windows.Forms.ProgressBar();
this.label = new System.Windows.Forms.Label();
this.cancelButton = new System.Windows.Forms.Button();
this.label2 = new System.Windows.Forms.Label();
this.lbl2Prog = new System.Windows.Forms.Label();
this.ErrorGrid = new System.Windows.Forms.DataGridView();
this.CError = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.CErrorFile = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.label3 = new System.Windows.Forms.Label();
this.bgWork = new System.ComponentModel.BackgroundWorker();
((System.ComponentModel.ISupportInitialize)(this.ErrorGrid)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
this.SuspendLayout();
//
// progressBar2
//
this.progressBar2.Location = new System.Drawing.Point(12, 71);
this.progressBar2.Name = "progressBar2";
this.progressBar2.Size = new System.Drawing.Size(400, 22);
this.progressBar2.TabIndex = 3;
this.progressBar2.Visible = false;
//
// progressBar
//
this.progressBar.Location = new System.Drawing.Point(12, 99);
this.progressBar.Name = "progressBar";
this.progressBar.Size = new System.Drawing.Size(400, 23);
this.progressBar.TabIndex = 1;
//
// label
//
this.label.AutoEllipsis = true;
this.label.Location = new System.Drawing.Point(12, 9);
this.label.Name = "label";
this.label.Size = new System.Drawing.Size(368, 15);
this.label.TabIndex = 0;
this.label.Text = "Starting operation...";
//
// cancelButton
//
this.cancelButton.Location = new System.Drawing.Point(420, 99);
this.cancelButton.Name = "cancelButton";
this.cancelButton.Size = new System.Drawing.Size(75, 23);
this.cancelButton.TabIndex = 2;
this.cancelButton.Text = "Cancel";
this.cancelButton.Click += new System.EventHandler(this.CancelButtonClick);
//
// label2
//
this.label2.AutoEllipsis = true;
this.label2.Location = new System.Drawing.Point(12, 34);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(480, 16);
this.label2.TabIndex = 4;
this.label2.Visible = false;
//
// lbl2Prog
//
this.lbl2Prog.Location = new System.Drawing.Point(386, 9);
this.lbl2Prog.Name = "lbl2Prog";
this.lbl2Prog.Size = new System.Drawing.Size(109, 25);
this.lbl2Prog.TabIndex = 5;
this.lbl2Prog.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.lbl2Prog.Visible = false;
//
// ErrorGrid
//
this.ErrorGrid.AllowUserToAddRows = false;
this.ErrorGrid.AllowUserToDeleteRows = false;
this.ErrorGrid.AllowUserToResizeRows = false;
this.ErrorGrid.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.AllCells;
this.ErrorGrid.BackgroundColor = System.Drawing.Color.White;
this.ErrorGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.ErrorGrid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.CError,
this.CErrorFile});
this.ErrorGrid.Dock = System.Windows.Forms.DockStyle.Fill;
this.ErrorGrid.GridColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
this.ErrorGrid.Location = new System.Drawing.Point(0, 0);
this.ErrorGrid.MultiSelect = false;
this.ErrorGrid.Name = "ErrorGrid";
this.ErrorGrid.ReadOnly = true;
this.ErrorGrid.RowHeadersVisible = false;
this.ErrorGrid.RowTemplate.Height = 17;
this.ErrorGrid.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
this.ErrorGrid.ShowCellErrors = false;
this.ErrorGrid.ShowCellToolTips = false;
this.ErrorGrid.ShowEditingIcon = false;
this.ErrorGrid.ShowRowErrors = false;
this.ErrorGrid.Size = new System.Drawing.Size(591, 186);
this.ErrorGrid.TabIndex = 6;
this.ErrorGrid.SelectionChanged += new System.EventHandler(this.ErrorGridSelectionChanged);
//
// CError
//
dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
this.CError.DefaultCellStyle = dataGridViewCellStyle1;
this.CError.HeaderText = "Error";
this.CError.Name = "CError";
this.CError.ReadOnly = true;
this.CError.Width = 200;
//
// CErrorFile
//
this.CErrorFile.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.CErrorFile.HeaderText = "Error Filename";
this.CErrorFile.Name = "CErrorFile";
this.CErrorFile.ReadOnly = true;
//
// splitContainer1
//
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
this.splitContainer1.IsSplitterFixed = true;
this.splitContainer1.Location = new System.Drawing.Point(0, 0);
this.splitContainer1.Name = "splitContainer1";
this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.Controls.Add(this.label3);
this.splitContainer1.Panel1.Controls.Add(this.progressBar2);
this.splitContainer1.Panel1.Controls.Add(this.label);
this.splitContainer1.Panel1.Controls.Add(this.progressBar);
this.splitContainer1.Panel1.Controls.Add(this.lbl2Prog);
this.splitContainer1.Panel1.Controls.Add(this.label2);
this.splitContainer1.Panel1.Controls.Add(this.cancelButton);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.ErrorGrid);
this.splitContainer1.Size = new System.Drawing.Size(591, 320);
this.splitContainer1.SplitterDistance = 130;
this.splitContainer1.TabIndex = 8;
//
// label3
//
this.label3.AutoEllipsis = true;
this.label3.Location = new System.Drawing.Point(12, 50);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(480, 16);
this.label3.TabIndex = 6;
//
// bgWork
//
this.bgWork.WorkerReportsProgress = true;
this.bgWork.WorkerSupportsCancellation = true;
//
// FrmProgressWindow
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(591, 320);
this.Controls.Add(this.splitContainer1);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "FrmProgressWindow";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "RomVault Progress";
this.Shown += new System.EventHandler(this.FrmProgressWindowNewShown);
this.Resize += new System.EventHandler(this.FrmProgressWindow_Resize);
((System.ComponentModel.ISupportInitialize)(this.ErrorGrid)).EndInit();
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel2.ResumeLayout(false);
this.splitContainer1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ProgressBar progressBar2;
private System.Windows.Forms.ProgressBar progressBar;
private System.Windows.Forms.Label label;
private System.Windows.Forms.Button cancelButton;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label lbl2Prog;
private System.Windows.Forms.DataGridView ErrorGrid;
private System.Windows.Forms.SplitContainer splitContainer1;
private System.ComponentModel.BackgroundWorker bgWork;
private System.Windows.Forms.DataGridViewTextBoxColumn CError;
private System.Windows.Forms.DataGridViewTextBoxColumn CErrorFile;
private System.Windows.Forms.Label label3;
}
}

View File

@@ -0,0 +1,241 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.ComponentModel;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using ROMVault2.Properties;
namespace ROMVault2
{
public partial class FrmProgressWindow : Form
{
private readonly string _titleRoot;
private bool _errorOpen;
private bool _bDone;
private Form _parentForm;
public FrmProgressWindow(Form parentForm, string titleRoot, DoWorkEventHandler function)
{
_parentForm = parentForm;
_titleRoot = titleRoot;
InitializeComponent();
ClientSize = new Size(498, 131);
_titleRoot = titleRoot;
bgWork.DoWork += function;
}
protected override CreateParams CreateParams
{
get
{
const int CP_NOCLOSE_BUTTON = 0x200;
CreateParams mdiCp = base.CreateParams;
mdiCp.ClassStyle = mdiCp.ClassStyle | CP_NOCLOSE_BUTTON;
return mdiCp;
}
}
private void FrmProgressWindowNewShown(object sender, EventArgs e)
{
bgWork.ProgressChanged += BgwProgressChanged;
bgWork.RunWorkerCompleted += BgwRunWorkerCompleted;
bgWork.RunWorkerAsync(SynchronizationContext.Current);
}
private void BgwProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (e.UserState == null)
{
if (e.ProgressPercentage >= progressBar.Minimum && e.ProgressPercentage <= progressBar.Maximum)
progressBar.Value = e.ProgressPercentage;
UpdateStatusText();
return;
}
bgwText bgwT = e.UserState as bgwText;
if (bgwT != null)
{
label.Text = bgwT.Text;
return;
}
bgwSetRange bgwSR = e.UserState as bgwSetRange;
if (bgwSR != null)
{
progressBar.Minimum = 0;
progressBar.Maximum = bgwSR.MaxVal >= 0 ? bgwSR.MaxVal : 0;
progressBar.Value = 0;
UpdateStatusText();
return;
}
bgwText2 bgwT2 = e.UserState as bgwText2;
if (bgwT2 != null)
{
label2.Text = bgwT2.Text;
return;
}
bgwValue2 bgwV2 = e.UserState as bgwValue2;
if (bgwV2 != null)
{
if (bgwV2.Value >= progressBar2.Minimum && bgwV2.Value <= progressBar2.Maximum)
progressBar2.Value = bgwV2.Value;
UpdateStatusText2();
return;
}
bgwSetRange2 bgwSR2 = e.UserState as bgwSetRange2;
if (bgwSR2 != null)
{
progressBar2.Minimum = 0;
progressBar2.Maximum = bgwSR2.MaxVal >= 0 ? bgwSR2.MaxVal : 0;
progressBar2.Value = 0;
UpdateStatusText2();
return;
}
bgwRange2Visible bgwR2V = e.UserState as bgwRange2Visible;
if (bgwR2V != null)
{
label2.Visible = bgwR2V.Visible;
progressBar2.Visible = bgwR2V.Visible;
lbl2Prog.Visible = bgwR2V.Visible;
return;
}
bgwText3 bgwT3 = e.UserState as bgwText3;
if (bgwT3 != null)
{
label3.Text = bgwT3.Text;
return;
}
bgwShowCorrupt bgwSC = e.UserState as bgwShowCorrupt;
if (bgwSC != null)
{
if (!_errorOpen)
{
_errorOpen = true;
ClientSize = new Size(498, 292);
MinimumSize = new Size(498, 292);
FormBorderStyle = FormBorderStyle.SizableToolWindow;
}
ErrorGrid.Rows.Add();
int row = ErrorGrid.Rows.Count - 1;
ErrorGrid.Rows[row].Cells["CError"].Value = bgwSC.zr;
ErrorGrid.Rows[row].Cells["CError"].Style.ForeColor = Color.FromArgb(255, 0, 0);
ErrorGrid.Rows[row].Cells["CErrorFile"].Value = bgwSC.filename;
ErrorGrid.Rows[row].Cells["CErrorFile"].Style.ForeColor = Color.FromArgb(255, 0, 0);
if (row >= 0) ErrorGrid.FirstDisplayedScrollingRowIndex = row;
}
bgwShowError bgwSDE = e.UserState as bgwShowError;
if (bgwSDE != null)
{
if (!_errorOpen)
{
_errorOpen = true;
ClientSize = new Size(498, 292);
MinimumSize = new Size(498, 292);
FormBorderStyle = FormBorderStyle.SizableToolWindow;
}
ErrorGrid.Rows.Add();
int row = ErrorGrid.Rows.Count - 1;
ErrorGrid.Rows[row].Cells["CError"].Value = bgwSDE.error;
ErrorGrid.Rows[row].Cells["CError"].Style.ForeColor = Color.FromArgb(255, 0, 0);
ErrorGrid.Rows[row].Cells["CErrorFile"].Value = bgwSDE.filename;
ErrorGrid.Rows[row].Cells["CErrorFile"].Style.ForeColor = Color.FromArgb(255, 0, 0);
if (row >= 0) ErrorGrid.FirstDisplayedScrollingRowIndex = row;
}
}
private void UpdateStatusText()
{
int range = progressBar.Maximum - progressBar.Minimum;
int percent = range > 0 ? (progressBar.Value * 100) / range : 0;
Text = _titleRoot + String.Format(" - {0}% complete", percent);
}
private void UpdateStatusText2()
{
lbl2Prog.Text = progressBar2.Maximum > 0 ? string.Format("{0}/{1}", progressBar2.Value, progressBar2.Maximum) : "";
}
private void BgwRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (_errorOpen)
{
cancelButton.Text = Resources.ProgressWindowFix_DoDone_Close;
cancelButton.Enabled = true;
_bDone = true;
}
else
{
_parentForm.Show();
Close();
}
}
private void CancelButtonClick(object sender, EventArgs e)
{
if (_bDone)
{
if (!_parentForm.Visible) _parentForm.Show();
Close();
}
else
{
cancelButton.Text = Resources.ProgressWindowFix_OnClosing_Cancelling;
cancelButton.Enabled = false;
bgWork.CancelAsync();
}
}
private void ErrorGridSelectionChanged(object sender, EventArgs e)
{
ErrorGrid.ClearSelection();
}
private void FrmProgressWindow_Resize(object sender, EventArgs e)
{
switch (WindowState)
{
case FormWindowState.Minimized:
if (_parentForm.Visible) _parentForm.Hide();
return;
case FormWindowState.Maximized:
if (!_parentForm.Visible) _parentForm.Show();
return;
case FormWindowState.Normal:
if (!_parentForm.Visible) _parentForm.Show();
return;
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,181 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using ROMVault2.Properties;
namespace ROMVault2
{
public partial class FrmProgressWindowFix : Form
{
private bool _bDone;
private readonly Form _parentForm;
private readonly Queue<DataGridViewRow> _rowQueue;
public FrmProgressWindowFix(Form parentForm)
{
_rowQueue = new Queue<DataGridViewRow>();
_parentForm = parentForm;
InitializeComponent();
timer1.Interval = 100;
timer1.Enabled = true;
}
private void Timer1Tick(object sender, EventArgs e)
{
int rowCount = _rowQueue.Count;
if (rowCount == 0)
return;
DataGridViewRow[] dgvr = new DataGridViewRow[rowCount];
for (int i = 0; i < rowCount; i++)
dgvr[i] = _rowQueue.Dequeue();
dataGridView1.Rows.AddRange(dgvr);
int iRow = dataGridView1.Rows.Count - 1;
dataGridView1.FirstDisplayedScrollingRowIndex = iRow;
}
protected override CreateParams CreateParams
{
get
{
const int CP_NOCLOSE_BUTTON = 0x200;
CreateParams mdiCp = base.CreateParams;
mdiCp.ClassStyle = mdiCp.ClassStyle | CP_NOCLOSE_BUTTON;
return mdiCp;
}
}
private void FrmProgressWindowFixShown(object sender, EventArgs e)
{
bgWork.DoWork += FixFiles.PerformFixes;
bgWork.ProgressChanged += BgwProgressChanged;
bgWork.RunWorkerCompleted += BgwRunWorkerCompleted;
bgWork.RunWorkerAsync(SynchronizationContext.Current);
}
private void BgwProgressChanged(object sender, ProgressChangedEventArgs e)
{
BgwProgressChanged(e.UserState);
}
private void BgwProgressChanged(object e)
{
bgwShowFix bgwSf = e as bgwShowFix;
if (bgwSf != null)
{
DataGridViewRow dgrq = (DataGridViewRow)dataGridView1.RowTemplate.Clone();
dgrq.CreateCells(dataGridView1, bgwSf.FixDir, bgwSf.FixZip, bgwSf.FixFile, bgwSf.Size, bgwSf.Dir, bgwSf.SourceDir, bgwSf.SourceZip, bgwSf.SourceFile);
_rowQueue.Enqueue(dgrq);
return;
}
bgwShowFixError bgwSFE = e as bgwShowFixError;
if (bgwSFE != null)
{
int iRow = dataGridView1.Rows.Count - 1;
dataGridView1.Rows[iRow].Cells[4].Style.BackColor = Color.Red;
dataGridView1.Rows[iRow].Cells[4].Style.ForeColor = Color.Black;
dataGridView1.Rows[iRow].Cells[4].Value = bgwSFE.FixError;
return;
}
bgwProgress bgwProg = e as bgwProgress;
if (bgwProg != null)
{
if (bgwProg.Progress >= progressBar.Minimum && bgwProg.Progress <= progressBar.Maximum)
progressBar.Value = bgwProg.Progress;
UpdateStatusText();
return;
}
bgwText bgwT = e as bgwText;
if (bgwT != null)
{
label.Text = bgwT.Text;
return;
}
bgwSetRange bgwSR = e as bgwSetRange;
if (bgwSR != null)
{
progressBar.Minimum = 0;
progressBar.Maximum = bgwSR.MaxVal >= 0 ? bgwSR.MaxVal : 0;
progressBar.Value = 0;
UpdateStatusText();
}
}
private void BgwRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
cancelButton.Text = Resources.ProgressWindowFix_DoDone_Close;
cancelButton.Enabled = true;
_bDone = true;
}
private void UpdateStatusText()
{
int range = progressBar.Maximum - progressBar.Minimum;
int percent = range > 0 ? (progressBar.Value * 100) / range : 0;
Text = String.Format("Fixing Files - {0}% complete", percent);
}
private void CancelButtonClick(object sender, EventArgs e)
{
if (_bDone)
Close();
else
{
cancelButton.Enabled = false;
cancelButton.Text = Resources.ProgressWindowFix_OnClosing_Cancelling;
bgWork.CancelAsync();
}
}
private void DataGridView1SelectionChanged(object sender, EventArgs e)
{
dataGridView1.ClearSelection();
}
private void FrmProgressWindowFixResize(object sender, EventArgs e)
{
switch (WindowState)
{
case FormWindowState.Minimized:
if (_parentForm.Visible) _parentForm.Hide();
return;
case FormWindowState.Maximized:
if (!_parentForm.Visible) _parentForm.Show();
return;
case FormWindowState.Normal:
if (!_parentForm.Visible) _parentForm.Show();
return;
}
}
}
}

290
ROMVault2/FrmProgressWindowFix.designer.cs generated Normal file
View File

@@ -0,0 +1,290 @@
namespace ROMVault2
{
partial class FrmProgressWindowFix
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmProgressWindowFix));
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.cancelButton = new System.Windows.Forms.Button();
this.progressBar = new System.Windows.Forms.ProgressBar();
this.label = new System.Windows.Forms.Label();
this.dataGridView1 = new System.Windows.Forms.DataGridView();
this.DatTo = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.GameTo = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.RomTo = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.FileSize = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Status = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.DatFrom = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.GameFrom = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.ROMFrom = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.dataGridViewTextBoxColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.dataGridViewTextBoxColumn3 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.dataGridViewTextBoxColumn4 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.dataGridViewTextBoxColumn5 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.dataGridViewTextBoxColumn6 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.dataGridViewTextBoxColumn7 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.bgWork = new System.ComponentModel.BackgroundWorker();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
this.SuspendLayout();
//
// splitContainer1
//
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
this.splitContainer1.Location = new System.Drawing.Point(0, 0);
this.splitContainer1.Name = "splitContainer1";
this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.Controls.Add(this.cancelButton);
this.splitContainer1.Panel1.Controls.Add(this.progressBar);
this.splitContainer1.Panel1.Controls.Add(this.label);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.dataGridView1);
this.splitContainer1.Size = new System.Drawing.Size(1027, 500);
this.splitContainer1.SplitterDistance = 64;
this.splitContainer1.TabIndex = 7;
//
// cancelButton
//
this.cancelButton.Location = new System.Drawing.Point(759, 32);
this.cancelButton.Name = "cancelButton";
this.cancelButton.Size = new System.Drawing.Size(75, 23);
this.cancelButton.TabIndex = 9;
this.cancelButton.Text = "Cancel";
this.cancelButton.Click += new System.EventHandler(this.CancelButtonClick);
//
// progressBar
//
this.progressBar.Location = new System.Drawing.Point(12, 32);
this.progressBar.Name = "progressBar";
this.progressBar.Size = new System.Drawing.Size(741, 23);
this.progressBar.TabIndex = 8;
//
// label
//
this.label.Location = new System.Drawing.Point(13, 9);
this.label.Name = "label";
this.label.Size = new System.Drawing.Size(480, 20);
this.label.TabIndex = 4;
this.label.Text = "Starting operation...";
//
// dataGridView1
//
this.dataGridView1.AllowUserToAddRows = false;
this.dataGridView1.AllowUserToDeleteRows = false;
this.dataGridView1.AllowUserToResizeRows = false;
this.dataGridView1.BackgroundColor = System.Drawing.Color.White;
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.DatTo,
this.GameTo,
this.RomTo,
this.FileSize,
this.Status,
this.DatFrom,
this.GameFrom,
this.ROMFrom});
this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.dataGridView1.GridColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
this.dataGridView1.Location = new System.Drawing.Point(0, 0);
this.dataGridView1.MultiSelect = false;
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.ReadOnly = true;
this.dataGridView1.RowHeadersVisible = false;
this.dataGridView1.RowTemplate.Height = 17;
this.dataGridView1.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
this.dataGridView1.ShowCellErrors = false;
this.dataGridView1.ShowCellToolTips = false;
this.dataGridView1.ShowEditingIcon = false;
this.dataGridView1.ShowRowErrors = false;
this.dataGridView1.Size = new System.Drawing.Size(1027, 432);
this.dataGridView1.TabIndex = 7;
this.dataGridView1.SelectionChanged += new System.EventHandler(this.DataGridView1SelectionChanged);
//
// DatTo
//
this.DatTo.HeaderText = "Directory (Fixing)";
this.DatTo.Name = "DatTo";
this.DatTo.ReadOnly = true;
this.DatTo.Width = 250;
//
// GameTo
//
this.GameTo.HeaderText = "Archive (Fixing)";
this.GameTo.Name = "GameTo";
this.GameTo.ReadOnly = true;
this.GameTo.Width = 200;
//
// RomTo
//
this.RomTo.HeaderText = "File (Fixing)";
this.RomTo.Name = "RomTo";
this.RomTo.ReadOnly = true;
this.RomTo.Width = 200;
//
// FileSize
//
this.FileSize.HeaderText = "Size (Fixing)";
this.FileSize.Name = "FileSize";
this.FileSize.ReadOnly = true;
//
// Status
//
this.Status.HeaderText = "Status";
this.Status.Name = "Status";
this.Status.ReadOnly = true;
//
// DatFrom
//
this.DatFrom.HeaderText = "Directory (From)";
this.DatFrom.Name = "DatFrom";
this.DatFrom.ReadOnly = true;
this.DatFrom.Width = 150;
//
// GameFrom
//
this.GameFrom.HeaderText = "Archive (From)";
this.GameFrom.Name = "GameFrom";
this.GameFrom.ReadOnly = true;
//
// ROMFrom
//
this.ROMFrom.HeaderText = "File (From)";
this.ROMFrom.Name = "ROMFrom";
this.ROMFrom.ReadOnly = true;
//
// dataGridViewTextBoxColumn1
//
this.dataGridViewTextBoxColumn1.HeaderText = "Dat (Fixing)";
this.dataGridViewTextBoxColumn1.Name = "dataGridViewTextBoxColumn1";
this.dataGridViewTextBoxColumn1.ReadOnly = true;
this.dataGridViewTextBoxColumn1.Width = 150;
//
// dataGridViewTextBoxColumn2
//
this.dataGridViewTextBoxColumn2.HeaderText = "Game (Fixing)";
this.dataGridViewTextBoxColumn2.Name = "dataGridViewTextBoxColumn2";
this.dataGridViewTextBoxColumn2.ReadOnly = true;
//
// dataGridViewTextBoxColumn3
//
this.dataGridViewTextBoxColumn3.HeaderText = "ROM (Fixing)";
this.dataGridViewTextBoxColumn3.Name = "dataGridViewTextBoxColumn3";
this.dataGridViewTextBoxColumn3.ReadOnly = true;
//
// dataGridViewTextBoxColumn4
//
this.dataGridViewTextBoxColumn4.HeaderText = "Status";
this.dataGridViewTextBoxColumn4.Name = "dataGridViewTextBoxColumn4";
this.dataGridViewTextBoxColumn4.ReadOnly = true;
//
// dataGridViewTextBoxColumn5
//
this.dataGridViewTextBoxColumn5.HeaderText = "Dat (From)";
this.dataGridViewTextBoxColumn5.Name = "dataGridViewTextBoxColumn5";
this.dataGridViewTextBoxColumn5.ReadOnly = true;
this.dataGridViewTextBoxColumn5.Width = 150;
//
// dataGridViewTextBoxColumn6
//
this.dataGridViewTextBoxColumn6.HeaderText = "Game (From)";
this.dataGridViewTextBoxColumn6.Name = "dataGridViewTextBoxColumn6";
this.dataGridViewTextBoxColumn6.ReadOnly = true;
//
// dataGridViewTextBoxColumn7
//
this.dataGridViewTextBoxColumn7.HeaderText = "Rom (From)";
this.dataGridViewTextBoxColumn7.Name = "dataGridViewTextBoxColumn7";
this.dataGridViewTextBoxColumn7.ReadOnly = true;
//
// bgWork
//
this.bgWork.WorkerReportsProgress = true;
this.bgWork.WorkerSupportsCancellation = true;
//
// timer1
//
this.timer1.Tick += new System.EventHandler(this.Timer1Tick);
//
// FrmProgressWindowFix
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.White;
this.ClientSize = new System.Drawing.Size(1027, 500);
this.Controls.Add(this.splitContainer1);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "FrmProgressWindowFix";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Fixing Files";
this.Shown += new System.EventHandler(this.FrmProgressWindowFixShown);
this.Resize += new System.EventHandler(this.FrmProgressWindowFixResize);
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel2.ResumeLayout(false);
this.splitContainer1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn1;
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn2;
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn3;
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn4;
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn5;
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn6;
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn7;
private System.Windows.Forms.SplitContainer splitContainer1;
private System.Windows.Forms.Label label;
private System.Windows.Forms.Button cancelButton;
private System.Windows.Forms.ProgressBar progressBar;
private System.ComponentModel.BackgroundWorker bgWork;
private System.Windows.Forms.DataGridViewTextBoxColumn DatTo;
private System.Windows.Forms.DataGridViewTextBoxColumn GameTo;
private System.Windows.Forms.DataGridViewTextBoxColumn RomTo;
private System.Windows.Forms.DataGridViewTextBoxColumn Status;
private System.Windows.Forms.DataGridViewTextBoxColumn DatFrom;
private System.Windows.Forms.DataGridViewTextBoxColumn GameFrom;
private System.Windows.Forms.DataGridViewTextBoxColumn ROMFrom;
private System.Windows.Forms.DataGridViewTextBoxColumn FileSize;
private System.Windows.Forms.DataGridView dataGridView1;
private System.Windows.Forms.Timer timer1;
}
}

File diff suppressed because it is too large Load Diff

121
ROMVault2/FrmRegistration.Designer.cs generated Normal file
View File

@@ -0,0 +1,121 @@
namespace ROMVault2
{
partial class FrmRegistration
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.txtName = new System.Windows.Forms.TextBox();
this.txtEmail = new System.Windows.Forms.TextBox();
this.btnOK = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// label1
//
this.label1.Location = new System.Drawing.Point(12, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(420, 49);
this.label1.TabIndex = 0;
this.label1.Text = "To make RomVault 2 the best is can be, RomVault 2 will send error reports to the " +
"author. Please fill out this from so that the Author can contact you in the case" +
" of a crash.";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(12, 58);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(120, 13);
this.label2.TabIndex = 1;
this.label2.Text = "Your Name: (Username)";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(12, 100);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(103, 13);
this.label3.TabIndex = 2;
this.label3.Text = "Your Contact Email :";
//
// txtName
//
this.txtName.Location = new System.Drawing.Point(15, 74);
this.txtName.Name = "txtName";
this.txtName.Size = new System.Drawing.Size(417, 20);
this.txtName.TabIndex = 3;
//
// txtEmail
//
this.txtEmail.Location = new System.Drawing.Point(15, 116);
this.txtEmail.Name = "txtEmail";
this.txtEmail.Size = new System.Drawing.Size(417, 20);
this.txtEmail.TabIndex = 4;
//
// btnOK
//
this.btnOK.Location = new System.Drawing.Point(303, 145);
this.btnOK.Name = "btnOK";
this.btnOK.Size = new System.Drawing.Size(128, 23);
this.btnOK.TabIndex = 5;
this.btnOK.Text = "OK";
this.btnOK.UseVisualStyleBackColor = true;
this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
//
// FrmRegistration
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(444, 178);
this.ControlBox = false;
this.Controls.Add(this.btnOK);
this.Controls.Add(this.txtEmail);
this.Controls.Add(this.txtName);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "FrmRegistration";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Registration";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.TextBox txtName;
private System.Windows.Forms.TextBox txtEmail;
private System.Windows.Forms.Button btnOK;
}
}

View File

@@ -0,0 +1,28 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Windows.Forms;
namespace ROMVault2
{
public partial class FrmRegistration : Form
{
public FrmRegistration()
{
InitializeComponent();
txtName.Text = Settings.Username;
txtEmail.Text = Settings.EMail;
}
private void btnOK_Click(object sender, EventArgs e)
{
Settings.Username = txtName.Text;
Settings.EMail = txtEmail.Text;
Close();
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

606
ROMVault2/IO/RVIO.cs Normal file
View File

@@ -0,0 +1,606 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Win32.SafeHandles;
namespace ROMVault2.IO
{
[Flags]
[ComVisible(true)]
[Serializable]
public enum FileAttributes
{
ReadOnly = 1,
Hidden = 2,
System = 4,
Directory = 16,
Archive = 32,
Device = 64,
Normal = 128,
Temporary = 256,
SparseFile = 512,
ReparsePoint = 1024,
Compressed = 2048,
Offline = 4096,
NotContentIndexed = 8192,
Encrypted = 16384,
}
public static class Error
{
public static int GetLastError()
{
return Marshal.GetLastWin32Error();
}
}
public class FileInfo
{
public string Name;
public string FullName;
public long LastWriteTime;
public long Length;
public int fileAttributes;
public bool isHidden
{
get { return (fileAttributes & Win32Native.FILE_ATTRIBUTE_HIDDEN) != 0; }
}
public FileInfo()
{ }
public FileInfo(string path)
{
FullName = path;
Name = Path.GetFileName(path);
string fileName = NameFix.AddLongPathPrefix(path);
Win32Native.WIN32_FILE_ATTRIBUTE_DATA wIn32FileAttributeData = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
bool b = Win32Native.GetFileAttributesEx(fileName, 0, ref wIn32FileAttributeData);
if (!b || (wIn32FileAttributeData.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) != 0) return;
Length = Convert.Length(wIn32FileAttributeData.fileSizeHigh, wIn32FileAttributeData.fileSizeLow);
LastWriteTime = Convert.Time(wIn32FileAttributeData.ftLastWriteTimeHigh, wIn32FileAttributeData.ftLastWriteTimeLow);
fileAttributes = wIn32FileAttributeData.fileAttributes;
}
}
public class DirectoryInfo
{
public string Name;
public string FullName;
public long LastWriteTime;
public int fileAttributes;
public bool isHidden
{
get { return (fileAttributes & Win32Native.FILE_ATTRIBUTE_HIDDEN) != 0; }
}
public DirectoryInfo()
{ }
public DirectoryInfo(string path)
{
FullName = path;
Name = Path.GetFileName(path);
string fileName = NameFix.AddLongPathPrefix(path);
Win32Native.WIN32_FILE_ATTRIBUTE_DATA wIn32FileAttributeData = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
bool b = Win32Native.GetFileAttributesEx(fileName, 0, ref wIn32FileAttributeData);
if (!b || (wIn32FileAttributeData.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) == 0) return;
LastWriteTime = Convert.Time(wIn32FileAttributeData.ftLastWriteTimeHigh, wIn32FileAttributeData.ftLastWriteTimeLow);
fileAttributes = wIn32FileAttributeData.fileAttributes;
}
public DirectoryInfo[] GetDirectories(bool includeHidden = true)
{
return GetDirectories("*", includeHidden);
}
public DirectoryInfo[] GetDirectories(string SearchPattern, bool includeHidden = true)
{
List<DirectoryInfo> dirs = new List<DirectoryInfo>();
string dirName = NameFix.AddLongPathPrefix(FullName);
Win32Native.WIN32_FIND_DATA findData = new Win32Native.WIN32_FIND_DATA();
SafeFindHandle findHandle = Win32Native.FindFirstFile(dirName + @"\" + SearchPattern, findData);
if (!findHandle.IsInvalid)
{
do
{
string currentFileName = findData.cFileName;
// if this is a directory, find its contents
if ((findData.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) == 0) continue;
if (currentFileName == "." || currentFileName == "..") continue;
if (!includeHidden && (findData.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_HIDDEN) != 0) continue;
DirectoryInfo di = new DirectoryInfo
{
Name = currentFileName,
FullName = Path.Combine(FullName, currentFileName),
LastWriteTime = Convert.Time(findData.ftLastWriteTimeHigh, findData.ftLastWriteTimeLow),
fileAttributes = findData.dwFileAttributes
};
dirs.Add(di);
}
while (Win32Native.FindNextFile(findHandle, findData));
}
// close the find handle
findHandle.Dispose();
return dirs.ToArray();
}
public FileInfo[] GetFiles()
{
return GetFiles("*");
}
public FileInfo[] GetFiles(string SearchPattern, bool includeHidden = true)
{
List<FileInfo> files = new List<FileInfo>();
string dirName = NameFix.AddLongPathPrefix(FullName);
Win32Native.WIN32_FIND_DATA findData = new Win32Native.WIN32_FIND_DATA();
SafeFindHandle findHandle = Win32Native.FindFirstFile(dirName + @"\" + SearchPattern, findData);
if (!findHandle.IsInvalid)
{
do
{
string currentFileName = findData.cFileName;
// if this is a directory, find its contents
if ((findData.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) != 0) continue;
if (!includeHidden && (findData.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_HIDDEN) != 0) continue;
FileInfo fi = new FileInfo
{
Name = currentFileName,
FullName = Path.Combine(FullName, currentFileName),
Length = Convert.Length(findData.nFileSizeHigh, findData.nFileSizeLow),
LastWriteTime = Convert.Time(findData.ftLastWriteTimeHigh, findData.ftLastWriteTimeLow),
fileAttributes = findData.dwFileAttributes
};
files.Add(fi);
}
while (Win32Native.FindNextFile(findHandle, findData));
}
// close the find handle
findHandle.Dispose();
return files.ToArray();
}
}
public static class Directory
{
public static bool Exists(string path)
{
string fixPath = NameFix.AddLongPathPrefix(path);
Win32Native.WIN32_FILE_ATTRIBUTE_DATA wIn32FileAttributeData = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
bool b = Win32Native.GetFileAttributesEx(fixPath, 0, ref wIn32FileAttributeData);
return b && (wIn32FileAttributeData.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) != 0;
}
public static void Move(String sourceDirName, String destDirName)
{
if (sourceDirName == null)
throw new ArgumentNullException("sourceDirName");
if (sourceDirName.Length == 0)
throw new ArgumentException("Argument_EmptyFileName", "sourceDirName");
if (destDirName == null)
throw new ArgumentNullException("destDirName");
if (destDirName.Length == 0)
throw new ArgumentException("Argument_EmptyFileName", "destDirName");
String fullsourceDirName = NameFix.AddLongPathPrefix(sourceDirName);
String fulldestDirName = NameFix.AddLongPathPrefix(destDirName);
if (!Win32Native.MoveFile(fullsourceDirName, fulldestDirName))
{
int hr = Marshal.GetLastWin32Error();
if (hr == Win32Native.ERROR_FILE_NOT_FOUND) // Source dir not found
{
throw new Exception("ERROR_PATH_NOT_FOUND " + fullsourceDirName);
}
if (hr == Win32Native.ERROR_ACCESS_DENIED) // WinNT throws IOException. This check is for Win9x. We can't change it for backcomp.
{
throw new Exception("UnauthorizedAccess_IODenied_Path" + sourceDirName);
}
}
}
public static void Delete(String path)
{
String fullPath = NameFix.AddLongPathPrefix(path);
Win32Native.RemoveDirectory(fullPath);
}
public static void CreateDirectory(String path)
{
if (path == null)
throw new ArgumentNullException("path");
if (path.Length == 0)
throw new ArgumentException("Argument_PathEmpty");
String fullPath = NameFix.AddLongPathPrefix(path);
Win32Native.CreateDirectory(fullPath, IntPtr.Zero);
}
}
public static class File
{
public static bool Exists(string path)
{
string fixPath = NameFix.AddLongPathPrefix(path);
Win32Native.WIN32_FILE_ATTRIBUTE_DATA wIn32FileAttributeData = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
bool b = Win32Native.GetFileAttributesEx(fixPath, 0, ref wIn32FileAttributeData);
return b && (wIn32FileAttributeData.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) == 0;
}
public static void Copy(String sourceFileName, string destfileName)
{
Copy(sourceFileName, destfileName, true);
}
public static void Copy(String sourceFileName, String destFileName, bool overwrite)
{
if (sourceFileName == null || destFileName == null)
throw new ArgumentNullException((sourceFileName == null ? "sourceFileName" : "destFileName"), "ArgumentNull_FileName");
if (sourceFileName.Length == 0 || destFileName.Length == 0)
throw new ArgumentException("Argument_EmptyFileName", (sourceFileName.Length == 0 ? "sourceFileName" : "destFileName"));
String fullSourceFileName = NameFix.AddLongPathPrefix(sourceFileName);
String fullDestFileName = NameFix.AddLongPathPrefix(destFileName);
bool r = Win32Native.CopyFile(fullSourceFileName, fullDestFileName, !overwrite);
if (!r)
{
// Save Win32 error because subsequent checks will overwrite this HRESULT.
int errorCode = Marshal.GetLastWin32Error();
String fileName = destFileName;
/*
if (errorCode != Win32Native.ERROR_FILE_EXISTS)
{
// For a number of error codes (sharing violation, path
// not found, etc) we don't know if the problem was with
// the source or dest file. Try reading the source file.
using (SafeFileHandle handle = Win32Native.UnsafeCreateFile(fullSourceFileName, FileStream.GENERIC_READ, FileShare.Read, null, FileMode.Open, 0, IntPtr.Zero))
{
if (handle.IsInvalid)
fileName = sourceFileName;
}
if (errorCode == Win32Native.ERROR_ACCESS_DENIED)
{
if (Directory.InternalExists(fullDestFileName))
throw new IOException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Arg_FileIsDirectory_Name"), destFileName), Win32Native.ERROR_ACCESS_DENIED, fullDestFileName);
}
}
__Error.WinIOError(errorCode, fileName);
*/
}
}
public static void Move(String sourceFileName, String destFileName)
{
if (sourceFileName == null || destFileName == null)
throw new ArgumentNullException((sourceFileName == null ? "sourceFileName" : "destFileName"), "ArgumentNull_FileName");
if (sourceFileName.Length == 0 || destFileName.Length == 0)
throw new ArgumentException("Argument_EmptyFileName", (sourceFileName.Length == 0 ? "sourceFileName" : "destFileName"));
String fullSourceFileName = NameFix.AddLongPathPrefix(sourceFileName);
String fullDestFileName = NameFix.AddLongPathPrefix(destFileName);
if (!Exists(fullSourceFileName))
throw new Exception("ERROR_FILE_NOT_FOUND" + fullSourceFileName);
if (!Win32Native.MoveFile(fullSourceFileName, fullDestFileName))
{
int hr = Marshal.GetLastWin32Error();
throw new Exception("ERROR_MOVING_FILE. Error Code ("+hr+")");
}
}
public static void Delete(String path)
{
string fixPath = NameFix.AddLongPathPrefix(path);
if (!Win32Native.DeleteFile(fixPath))
{
int hr = Marshal.GetLastWin32Error();
if (hr != Win32Native.ERROR_FILE_NOT_FOUND)
throw new Exception("Error while deleting file :" + path);
}
}
public static bool SetAttributes(String path, FileAttributes fileAttributes)
{
String fullPath = NameFix.AddLongPathPrefix(path);
return Win32Native.SetFileAttributes(fullPath, (int)fileAttributes);
}
private const int ERROR_INVALID_PARAMETER = 87;
private const int ERROR_ACCESS_DENIED = 0x5;
}
public static class Path
{
public static readonly char DirectorySeparatorChar = '\\';
public static readonly char AltDirectorySeparatorChar = '/';
public static readonly char VolumeSeparatorChar = ':';
public static string GetExtension(String path)
{
return System.IO.Path.GetExtension(path);
}
public static string Combine(string path1, string path2)
{
if (path1 == null || path2 == null)
throw new ArgumentNullException((path1 == null) ? "path1" : "path2");
//CheckInvalidPathChars(path1);
//CheckInvalidPathChars(path2);
if (path2.Length == 0)
return path1;
if (path1.Length == 0)
return path2;
if (IsPathRooted(path2))
return path2;
char ch = path1[path1.Length - 1];
if (ch != DirectorySeparatorChar && ch != AltDirectorySeparatorChar && ch != VolumeSeparatorChar)
return path1 + DirectorySeparatorChar + path2;
return path1 + path2;
}
private static bool IsPathRooted(String path)
{
if (path != null)
{
//CheckInvalidPathChars(path);
int length = path.Length;
if (
(length >= 1 && (path[0] == DirectorySeparatorChar ||
path[0] == AltDirectorySeparatorChar)) ||
(length >= 2 && path[1] == VolumeSeparatorChar)
) return true;
}
return false;
}
/*
private static void CheckInvalidPathChars(string path)
{
for (int index = 0; index < path.Length; ++index)
{
int num = path[index];
switch (num)
{
case 34:
case 60:
case 62:
case 124:
ReportError.SendErrorMessage("Invalid Character " + num + " in filename " + path);
continue;
default:
if (num >= 32)
continue;
goto case 34;
}
}
}
*/
public static string GetFileNameWithoutExtension(string path)
{
return System.IO.Path.GetFileNameWithoutExtension(path);
}
public static string GetFileName(String path)
{
return System.IO.Path.GetFileName(path);
}
public static String GetDirectoryName(String path)
{
if (path != null)
{
int root = GetRootLength(path);
int i = path.Length;
if (i > root)
{
i = path.Length;
if (i == root) return null;
while (i > root && path[--i] != DirectorySeparatorChar && path[i] != AltDirectorySeparatorChar) ;
return path.Substring(0, i);
}
}
return null;
}
private static int GetRootLength(String path)
{
int i = 0;
int length = path.Length;
if (length >= 1 && (IsDirectorySeparator(path[0])))
{
// handles UNC names and directories off current drive's root.
i = 1;
if (length >= 2 && (IsDirectorySeparator(path[1])))
{
i = 2;
int n = 2;
while (i < length && ((path[i] != DirectorySeparatorChar && path[i] != AltDirectorySeparatorChar) || --n > 0)) i++;
}
}
else if (length >= 2 && path[1] == VolumeSeparatorChar)
{
// handles A:\foo.
i = 2;
if (length >= 3 && (IsDirectorySeparator(path[2]))) i++;
}
return i;
}
private static bool IsDirectorySeparator(char c)
{
return (c == DirectorySeparatorChar || c == AltDirectorySeparatorChar);
}
}
public static class FileStream
{
private const uint GENERIC_READ = 0x80000000;
private const uint GENERIC_WRITE = 0x40000000;
private const uint FILE_ATTRIBUTE_NORMAL = 0x80;
// errorMessage = new Win32Exception(errorCode).Message;
public static int OpenFileRead(string path, out System.IO.Stream stream)
{
string filename = NameFix.AddLongPathPrefix(path);
SafeFileHandle hFile = Win32Native.CreateFile(filename,
GENERIC_READ,
System.IO.FileShare.Read,
IntPtr.Zero,
System.IO.FileMode.Open,
FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero);
if (hFile.IsInvalid)
{
stream = null;
return Marshal.GetLastWin32Error();
}
stream = new System.IO.FileStream(hFile, System.IO.FileAccess.Read);
return 0;
}
public static int OpenFileWrite(string path, out System.IO.Stream stream)
{
string filename = NameFix.AddLongPathPrefix(path);
SafeFileHandle hFile = Win32Native.CreateFile(filename,
GENERIC_WRITE,
System.IO.FileShare.None,
IntPtr.Zero,
System.IO.FileMode.Create,
FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero);
if (hFile.IsInvalid)
{
stream = null;
return Marshal.GetLastWin32Error();
}
stream = new System.IO.FileStream(hFile, System.IO.FileAccess.Write);
return 0;
}
}
public static class NameFix
{
public static string GetShortPath(string path)
{
int remove = 0;
string retPath;
if (path.StartsWith(@"\\"))
{
retPath = @"\\?\UNC\" + path.Substring(2);
remove = 8;
}
else
{
retPath = path;
if (path.Substring(1, 1) != ":")
retPath = Path.Combine(System.IO.Directory.GetCurrentDirectory(), retPath);
retPath = cleandots(retPath);
retPath = @"\\?\" + retPath;
remove = 4;
}
const int MAX_PATH = 300;
var shortPath = new StringBuilder(MAX_PATH);
Win32Native.GetShortPathName(retPath, shortPath, MAX_PATH);
retPath = shortPath.ToString();
retPath = retPath.Substring(remove);
if (remove == 8) retPath = "\\" + retPath;
return retPath;
}
internal static string AddLongPathPrefix(string path)
{
if (string.IsNullOrEmpty(path) || path.StartsWith(@"\\?\"))
return path;
if (path.StartsWith(@"\\"))
return @"\\?\UNC\" + path.Substring(2);
string retPath = path;
if (path.Substring(1, 1) != ":")
retPath = Path.Combine(System.IO.Directory.GetCurrentDirectory(), retPath);
retPath = cleandots(retPath);
return @"\\?\" + retPath;
}
private static string cleandots(string path)
{
string retPath = path;
while (retPath.Contains(@"\..\"))
{
int index = retPath.IndexOf(@"\..\");
string path1 = retPath.Substring(0, index);
string path2 = retPath.Substring(index + 4);
int path1Back = path1.LastIndexOf(@"\");
retPath = path1.Substring(0, path1Back + 1) + path2;
}
return retPath;
}
}
}

181
ROMVault2/IO/Win32Native.cs Normal file
View File

@@ -0,0 +1,181 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.IO;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Text;
using Microsoft.Win32.SafeHandles;
namespace ROMVault2.IO
{
internal static class Win32Native
{
private const String KERNEL32 = "kernel32.dll";
public const int FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
public const int FILE_ATTRIBUTE_HIDDEN = 0x00000002;
internal const int ERROR_FILE_NOT_FOUND = 0x2;
internal const int ERROR_ACCESS_DENIED = 0x5;
internal const int ERROR_FILE_EXISTS = 0x50;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
[BestFitMapping(false)]
internal class WIN32_FIND_DATA
{
internal int dwFileAttributes = 0;
internal uint ftCreationTimeLow;
internal uint ftCreationTimeHigh;
internal uint ftLastAccessTimeLow;
internal uint ftLastAccessTimeHigh;
internal uint ftLastWriteTimeLow;
internal uint ftLastWriteTimeHigh;
internal int nFileSizeHigh = 0;
internal int nFileSizeLow = 0;
internal int dwReserved0 = 0;
internal int dwReserved1 = 0;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
internal String cFileName = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
internal String cAlternateFileName = null;
}
[StructLayout(LayoutKind.Sequential), Serializable]
internal struct WIN32_FILE_ATTRIBUTE_DATA
{
internal int fileAttributes;
internal uint ftCreationTimeLow;
internal uint ftCreationTimeHigh;
internal uint ftLastAccessTimeLow;
internal uint ftLastAccessTimeHigh;
internal uint ftLastWriteTimeLow;
internal uint ftLastWriteTimeHigh;
internal int fileSizeHigh;
internal int fileSizeLow;
}
[DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
[ResourceExposure(ResourceScope.None)]
internal static extern bool GetFileAttributesEx(String fileName, int fileInfoLevel, ref WIN32_FILE_ATTRIBUTE_DATA lpFileInformation);
[DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
[ResourceExposure(ResourceScope.None)]
internal static extern SafeFindHandle FindFirstFile(String fileName, [In, Out] WIN32_FIND_DATA data);
[DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
[ResourceExposure(ResourceScope.None)]
internal static extern bool FindNextFile(SafeFindHandle hndFindFile, [In, Out, MarshalAs(UnmanagedType.LPStruct)] WIN32_FIND_DATA lpFindFileData);
[DllImport(KERNEL32)]
[ResourceExposure(ResourceScope.None)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal static extern bool FindClose(IntPtr handle);
[DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
[ResourceExposure(ResourceScope.Machine)]
internal static extern SafeFileHandle CreateFile(String lpFileName,
uint dwDesiredAccess, FileShare dwShareMode,
IntPtr securityAttrs, FileMode dwCreationDisposition,
uint dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
[ResourceExposure(ResourceScope.Machine)]
internal static extern bool CreateDirectory(String path, IntPtr lpSecurityAttributes);
[DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
[ResourceExposure(ResourceScope.Machine)]
internal static extern bool RemoveDirectory(String path);
[DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
[ResourceExposure(ResourceScope.Machine)]
internal static extern bool CopyFile(String src, String dst, bool failIfExists);
[DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
[ResourceExposure(ResourceScope.Machine)]
internal static extern bool MoveFile(String src, String dst);
[DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
[ResourceExposure(ResourceScope.Machine)]
internal static extern bool DeleteFile(String path);
[DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
[ResourceExposure(ResourceScope.None)]
internal static extern bool SetFileAttributes(String name, int attr);
[DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
[ResourceExposure(ResourceScope.Machine)]
internal static extern int GetShortPathName(
[MarshalAs(UnmanagedType.LPTStr)] string path,
[MarshalAs(UnmanagedType.LPTStr)] StringBuilder shortPath,
int shortPathLength
);
}
internal sealed class SafeFindHandle : SafeHandleZeroOrMinusOneIsInvalid
{
[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
internal SafeFindHandle() : base(true) { }
override protected bool ReleaseHandle()
{
return Win32Native.FindClose(handle);
}
}
internal static class Convert
{
private const long TicksPerMillisecond = 10000;
private const long TicksPerSecond = TicksPerMillisecond * 1000;
private const long TicksPerMinute = TicksPerSecond * 60;
private const long TicksPerHour = TicksPerMinute * 60;
private const long TicksPerDay = TicksPerHour * 24;
// Number of days in a non-leap year
private const int DaysPerYear = 365;
// Number of days in 4 years
private const int DaysPer4Years = DaysPerYear * 4 + 1;
// Number of days in 100 years
private const int DaysPer100Years = DaysPer4Years * 25 - 1;
// Number of days in 400 years
private const int DaysPer400Years = DaysPer100Years * 4 + 1;
// Number of days from 1/1/0001 to 12/31/1600
private const int DaysTo1601 = DaysPer400Years * 4;
public const long FileTimeOffset = DaysTo1601 * TicksPerDay;
// Number of days from 1/1/0001 to 12/31/9999
private const int DaysTo10000 = DaysPer400Years * 25 - 366;
private const long MinTicks = 0;
private const long MaxTicks = DaysTo10000 * TicksPerDay - 1;
public static long Length(int high, int low)
{
return ((long) high) << 32 | ((long) low & 0xFFFFFFFFL);
}
public static long Time(uint high, uint low)
{
return ((long)high << 32) | low;
}
}
}

54
ROMVault2/Program.cs Normal file
View File

@@ -0,0 +1,54 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace ROMVault2
{
static class Program
{
//public static UsernamePassword Up;
public static readonly Encoding Enc = Encoding.GetEncoding(28591);
public const string Version = "2.1";
public const int SubVersion = 25;
public static string ErrorMessage;
public static string URL;
public static SynchronizationContext SyncCont;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
#if !DEBUG
Application.ThreadException += ReportError.UnhandledExceptionHandler;
#endif
FrmSplashScreen progress = new FrmSplashScreen();
progress.ShowDialog();
progress.Dispose();
if (!String.IsNullOrEmpty(ErrorMessage))
{
MessageBox.Show(ErrorMessage);
if (!String.IsNullOrEmpty(URL))
System.Diagnostics.Process.Start(URL);
return;
}
Application.Run(new FrmMain());
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ROMVault2")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("ROMVault2")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("12c7682b-3530-4e92-a696-94a92cf3fedf")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

741
ROMVault2/Properties/Resources.Designer.cs generated Normal file
View File

@@ -0,0 +1,741 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.34003
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ROMVault2.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ROMVault2.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to , .
/// </summary>
internal static string Comma {
get {
return ResourceManager.GetString("Comma", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error Keyword .
/// </summary>
internal static string DatCmpReader_LoadDirFromDat_Error_Keyword {
get {
return ResourceManager.GetString("DatCmpReader_LoadDirFromDat_Error_Keyword", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to not know in dir.
/// </summary>
internal static string DatCmpReader_LoadDirFromDat_not_know_in_dir {
get {
return ResourceManager.GetString("DatCmpReader_LoadDirFromDat_not_know_in_dir", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Name not found as first object in ( ).
/// </summary>
internal static string DatCmpReader_LoadGameFromDat_Name_not_found_as_first_object_in {
get {
return ResourceManager.GetString("DatCmpReader_LoadGameFromDat_Name_not_found_as_first_object_in", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to ( not found after game.
/// </summary>
internal static string DatCmpReader_LoadGameFromDat_not_found_after_game {
get {
return ResourceManager.GetString("DatCmpReader_LoadGameFromDat_not_found_after_game", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &apos; not known in game.
/// </summary>
internal static string DatCmpReader_LoadGameFromDat_not_known_in_game {
get {
return ResourceManager.GetString("DatCmpReader_LoadGameFromDat_not_known_in_game", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to ( not found after clrmamepro.
/// </summary>
internal static string DatCmpReader_LoadHeaderFromDat_not_found_after_clrmamepro {
get {
return ResourceManager.GetString("DatCmpReader_LoadHeaderFromDat_not_found_after_clrmamepro", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &apos; not known in clrmamepro.
/// </summary>
internal static string DatCmpReader_LoadHeaderFromDat_not_known_in_clrmamepro {
get {
return ResourceManager.GetString("DatCmpReader_LoadHeaderFromDat_not_known_in_clrmamepro", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to ( not found after rom.
/// </summary>
internal static string DatCmpReader_LoadRomFromDat_not_found_after_rom {
get {
return ResourceManager.GetString("DatCmpReader_LoadRomFromDat_not_found_after_rom", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &apos; not known in rom.
/// </summary>
internal static string DatCmpReader_LoadRomFromDat_not_known_in_rom {
get {
return ResourceManager.GetString("DatCmpReader_LoadRomFromDat_not_known_in_rom", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error: key word &apos;.
/// </summary>
internal static string DatCmpReader_ReadDat_Error_keyword {
get {
return ResourceManager.GetString("DatCmpReader_ReadDat_Error_keyword", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &apos; not known.
/// </summary>
internal static string DatCmpReader_ReadDat_not_known {
get {
return ResourceManager.GetString("DatCmpReader_ReadDat_not_known", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error dat found on item listed as not in dat.
/// </summary>
internal static string DatUpdate_ClearOldDats_Error_dat_found_on_item_listed_as_not_in_dat {
get {
return ResourceManager.GetString("DatUpdate_ClearOldDats_Error_dat_found_on_item_listed_as_not_in_dat", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Got to a non dir when checking Dir&apos;s for dats to remove.
/// </summary>
internal static string DatUpdate_ClearOldDats_Got_to_a_non_dir_when_checking_Dir_s_for_dats_to_remove {
get {
return ResourceManager.GetString("DatUpdate_ClearOldDats_Got_to_a_non_dir_when_checking_Dir_s_for_dats_to_remove", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This is bad, rBase.Dat is set to a dat, and rBase.DatStatus is not.
/// </summary>
internal static string DatUpdate_ClearOldDats_This_is_bad__rBase_Dat_is_set_to_a_dat_and_rBase_DatStatus_is_not {
get {
return ResourceManager.GetString("DatUpdate_ClearOldDats_This_is_bad__rBase_Dat_is_set_to_a_dat_and_rBase_DatStatus" +
"_is_not", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unknown File Delete Test .
/// </summary>
internal static string DatUpdate_ClearOldDats_Unknown_File_Delete_Test {
get {
return ResourceManager.GetString("DatUpdate_ClearOldDats_Unknown_File_Delete_Test", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unknown file setup.
/// </summary>
internal static string DatUpdate_ClearOldDats_Unknown_file_setup {
get {
return ResourceManager.GetString("DatUpdate_ClearOldDats_Unknown_file_setup", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This should also never happen..
/// </summary>
internal static string DatUpdate_ClearRemovedDatsFromTheDb_This_should_also_never_happen {
get {
return ResourceManager.GetString("DatUpdate_ClearRemovedDatsFromTheDb_This_should_also_never_happen", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error in Logic.
/// </summary>
internal static string DatUpdate_MergeInDat_Error_in_Logic {
get {
return ResourceManager.GetString("DatUpdate_MergeInDat_Error_in_Logic", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unkown Update Dat Status .
/// </summary>
internal static string DatUpdate_MergeInDat_Unkown_Update_Dat_Status {
get {
return ResourceManager.GetString("DatUpdate_MergeInDat_Unkown_Update_Dat_Status", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unknown Merge Status.
/// </summary>
internal static string DatUpdate_UpdateDatFile_Unknown_Merge_Status {
get {
return ResourceManager.GetString("DatUpdate_UpdateDatFile_Unknown_Merge_Status", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &apos; Directory will be ignored..
/// </summary>
internal static string DatUpdate_UpdateDatList_Directory_will_be_ignored {
get {
return ResourceManager.GetString("DatUpdate_UpdateDatList_Directory_will_be_ignored", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Empty Directories found in &apos;.
/// </summary>
internal static string DatUpdate_UpdateDatList_Empty_Directories_found_in {
get {
return ResourceManager.GetString("DatUpdate_UpdateDatList_Empty_Directories_found_in", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to ERROR Deleting a DAT that should already be deleted.
/// </summary>
internal static string DatUpdate_UpdateDatList_ERROR_Deleting_a_DAT_that_should_already_be_deleted {
get {
return ResourceManager.GetString("DatUpdate_UpdateDatList_ERROR_Deleting_a_DAT_that_should_already_be_deleted", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Not Found..
/// </summary>
internal static string DatUpdate_UpdateDatList_Not_Found {
get {
return ResourceManager.GetString("DatUpdate_UpdateDatList_Not_Found", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Path: .
/// </summary>
internal static string DatUpdate_UpdateDatList_Path {
get {
return ResourceManager.GetString("DatUpdate_UpdateDatList_Path", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to RomValue Scan Error:.
/// </summary>
internal static string DatUpdate_UpdateDatList_RomValue_Scan_Error {
get {
return ResourceManager.GetString("DatUpdate_UpdateDatList_RomValue_Scan_Error", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Data Cache version is out of date you should now rescan your dat directory and roms directory..
/// </summary>
internal static string DB_Read_Data_Cache_version_is_out_of_date_you_should_now_rescan_your_dat_directory_and_roms_directory_ {
get {
return ResourceManager.GetString("DB_Read_Data_Cache_version_is_out_of_date_you_should_now_rescan_your_dat_director" +
"y_and_roms_directory_", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error in File Scanning Code..
/// </summary>
internal static string FileScanning_CheckADir_Error_in_File_Scanning_Code {
get {
return ResourceManager.GetString("FileScanning_CheckADir_Error_in_File_Scanning_Code", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error Case .
/// </summary>
internal static string FindFixes_ListCheck_Error_Case {
get {
return ResourceManager.GetString("FindFixes_ListCheck_Error_Case", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Nothing Set For .
/// </summary>
internal static string FindFixes_ListCheck_Nothing_Set_For {
get {
return ResourceManager.GetString("FindFixes_ListCheck_Nothing_Set_For", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unknown test status .
/// </summary>
internal static string FindFixes_ListCheck_Unknown_test_status {
get {
return ResourceManager.GetString("FindFixes_ListCheck_Unknown_test_status", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unknown result type.
/// </summary>
internal static string FixFiles_FixDirChildren_Unknown_result_type {
get {
return ResourceManager.GetString("FixFiles_FixDirChildren_Unknown_result_type", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to But the case of the unknown file is wrong. Rescan and try agian..
/// </summary>
internal static string FixFiles_FixFile__But_the_case_of_the_unknown_file_is_wrong_Rescan_and_try_agian {
get {
return ResourceManager.GetString("FixFiles_FixFile__But_the_case_of_the_unknown_file_is_wrong_Rescan_and_try_agian", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Did you manualy fix this file without rescanning?.
/// </summary>
internal static string FixFiles_FixFile__Did_you_manualy_fix_this_file_without_rescanning {
get {
return ResourceManager.GetString("FixFiles_FixFile__Did_you_manualy_fix_this_file_without_rescanning", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Trying to fix a file that already exists .
/// </summary>
internal static string FixFiles_FixFile_Trying_to_fix_a_file_that_already_exists {
get {
return ResourceManager.GetString("FixFiles_FixFile_Trying_to_fix_a_file_that_already_exists", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unable to Find the file used to fix .
/// </summary>
internal static string FixFiles_FixFile_Unable_to_Find_the_file_used_to_fix {
get {
return ResourceManager.GetString("FixFiles_FixFile_Unable_to_Find_the_file_used_to_fix", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unknown fix file type .
/// </summary>
internal static string FixFiles_FixFile_Unknown_fix_file_type {
get {
return ResourceManager.GetString("FixFiles_FixFile_Unknown_fix_file_type", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unsupported file Fix.
/// </summary>
internal static string FixFiles_FixFile_Unsupported_file_Fix {
get {
return ResourceManager.GetString("FixFiles_FixFile_Unsupported_file_Fix", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to : .
/// </summary>
internal static string FixFiles_FixZip_Colon {
get {
return ResourceManager.GetString("FixFiles_FixZip_Colon", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error finding Fixing Rom, Database is corrupt..
/// </summary>
internal static string FixFiles_FixZip_Error_finding_Fixing_Rom_Database_is_corrupt {
get {
return ResourceManager.GetString("FixFiles_FixZip_Error_finding_Fixing_Rom_Database_is_corrupt", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error in Fix Rom Status .
/// </summary>
internal static string FixFiles_FixZip_Error_in_Fix_Rom_Status {
get {
return ResourceManager.GetString("FixFiles_FixZip_Error_in_Fix_Rom_Status", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error processing zip .
/// </summary>
internal static string FixFiles_FixZip_Error_processing_zip {
get {
return ResourceManager.GetString("FixFiles_FixZip_Error_processing_zip", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This Delete case should never happen, help .
/// </summary>
internal static string FixFiles_FixZip_This_Delete_case_should_never_happen__help {
get {
return ResourceManager.GetString("FixFiles_FixZip_This_Delete_case_should_never_happen__help", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This Delete case should never happen, you do not delete a rom you collect..
/// </summary>
internal static string FixFiles_FixZip_This_Delete_case_should_never_happen__you_do_not_delete_a_rom_you_collect {
get {
return ResourceManager.GetString("FixFiles_FixZip_This_Delete_case_should_never_happen__you_do_not_delete_a_rom_you" +
"_collect", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unknown type.
/// </summary>
internal static string FixFiles_FixZip_Unknown_type {
get {
return ResourceManager.GetString("FixFiles_FixZip_Unknown_type", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to did you delete it?.
/// </summary>
internal static string FixFiles_OpenOriginalZip_did_you_delete_it {
get {
return ResourceManager.GetString("FixFiles_OpenOriginalZip_did_you_delete_it", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to File not found :.
/// </summary>
internal static string FixFiles_OpenOriginalZip_File_not_found {
get {
return ResourceManager.GetString("FixFiles_OpenOriginalZip_File_not_found", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to File TimeStamp has changed in file .
/// </summary>
internal static string FixFiles_OpenOriginalZip_File_TimeStamp_has_changed_in_file {
get {
return ResourceManager.GetString("FixFiles_OpenOriginalZip_File_TimeStamp_has_changed_in_file", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Found an unknown file :.
/// </summary>
internal static string FixFiles_OpenOriginalZip_Found_an_unknown_file {
get {
return ResourceManager.GetString("FixFiles_OpenOriginalZip_Found_an_unknown_file", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Trying to open an unscanned file :.
/// </summary>
internal static string FixFiles_OpenOriginalZip_Trying_to_open_an_unscanned_file {
get {
return ResourceManager.GetString("FixFiles_OpenOriginalZip_Trying_to_open_an_unscanned_file", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unknown File Open Type..
/// </summary>
internal static string FixFiles_OpenOriginalZip_Unknown_File_Open_Type {
get {
return ResourceManager.GetString("FixFiles_OpenOriginalZip_Unknown_File_Open_Type", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Trying to fix unscanned dir&apos;s.
/// </summary>
internal static string FixFiles_PerformFixes_Trying_to_fix_unscanned_dir_s {
get {
return ResourceManager.GetString("FixFiles_PerformFixes_Trying_to_fix_unscanned_dir_s", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Set ROM DIR.
/// </summary>
internal static string FrmMain_DirTreeRvSelected_Set_ROM_DIR {
get {
return ResourceManager.GetString("FrmMain_DirTreeRvSelected_Set_ROM_DIR", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to File Type Missing .
/// </summary>
internal static string FrmMain_UpdateRomGrid_File_Type_Missing_ {
get {
return ResourceManager.GetString("FrmMain_UpdateRomGrid_File_Type_Missing_", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Directory Settings.
/// </summary>
internal static string FrmSetDir_BtnDeleteSelectedClick_Directory_Settings {
get {
return ResourceManager.GetString("FrmSetDir_BtnDeleteSelectedClick_Directory_Settings", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to RomVault Rom Location.
/// </summary>
internal static string FrmSetDir_BtnDeleteSelectedClick_RomVault_Rom_Location {
get {
return ResourceManager.GetString("FrmSetDir_BtnDeleteSelectedClick_RomVault_Rom_Location", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to You cannot delete the .
/// </summary>
internal static string FrmSetDir_BtnDeleteSelectedClick_You_cannot_delete_the {
get {
return ResourceManager.GetString("FrmSetDir_BtnDeleteSelectedClick_You_cannot_delete_the", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Please select a folder for This Rom Set.
/// </summary>
internal static string FrmSetDir_BtnSetRomLocationClick_Please_select_a_folder_for_This_Rom_Set {
get {
return ResourceManager.GetString("FrmSetDir_BtnSetRomLocationClick_Please_select_a_folder_for_This_Rom_Set", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Edit Existing Directory Mapping.
/// </summary>
internal static string FrmSetDir_DataGridGamesDoubleClick_Edit_Existing_Directory_Mapping {
get {
return ResourceManager.GetString("FrmSetDir_DataGridGamesDoubleClick_Edit_Existing_Directory_Mapping", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Please select a folder for DAT Root.
/// </summary>
internal static string FrmSettings_BtnDatClick_Please_select_a_folder_for_DAT_Root {
get {
return ResourceManager.GetString("FrmSettings_BtnDatClick_Please_select_a_folder_for_DAT_Root", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to There is a new release download now from .
/// </summary>
internal static string Program_Main_There_is_a_new_release_download_now_from {
get {
return ResourceManager.GetString("Program_Main_There_is_a_new_release_download_now_from", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to You are not Authorised to use this program..
/// </summary>
internal static string Program_Main_You_are_not_Authorised_to_use_this_program {
get {
return ResourceManager.GetString("Program_Main_You_are_not_Authorised_to_use_this_program", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to You must have a &apos;user - &lt;NAME&gt;.xml&apos; file to use RomVault.
/// </summary>
internal static string Program_Main_You_must_have_a__user____NAME__xml__file_to_use_RomVault {
get {
return ResourceManager.GetString("Program_Main_You_must_have_a__user____NAME__xml__file_to_use_RomVault", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Close.
/// </summary>
internal static string ProgressWindowFix_DoDone_Close {
get {
return ResourceManager.GetString("ProgressWindowFix_DoDone_Close", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cancelling.
/// </summary>
internal static string ProgressWindowFix_OnClosing_Cancelling {
get {
return ResourceManager.GetString("ProgressWindowFix_OnClosing_Cancelling", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Please select a folder for Dats.
/// </summary>
internal static string Report_MakeFixFiles_Please_select_a_folder_for_Dats {
get {
return ResourceManager.GetString("Report_MakeFixFiles_Please_select_a_folder_for_Dats", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to , .
/// </summary>
internal static string RvBase_Check {
get {
return ResourceManager.GetString("RvBase_Check", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unknown Error Status File .
/// </summary>
internal static string RvBase_Check_Unknown_Error_Status_File {
get {
return ResourceManager.GetString("RvBase_Check_Unknown_Error_Status_File", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Dat found without an index.
/// </summary>
internal static string RvBase_Read_Dat_found_without_an_index {
get {
return ResourceManager.GetString("RvBase_Read_Dat_found_without_an_index", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unknown Set Got Status .
/// </summary>
internal static string RvBase_SetGot_Unknown_Set_Got_Status {
get {
return ResourceManager.GetString("RvBase_SetGot_Unknown_Set_Got_Status", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Clearing Dir with a dat list.
/// </summary>
internal static string RvDir_ClearDat_Clearing_Dir_with_a_dat_list {
get {
return ResourceManager.GetString("RvDir_ClearDat_Clearing_Dir_with_a_dat_list", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Setting Dir with a dat list.
/// </summary>
internal static string RvDir_SetDat_Setting_Dir_with_a_dat_list {
get {
return ResourceManager.GetString("RvDir_SetDat_Setting_Dir_with_a_dat_list", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Count went negative..
/// </summary>
internal static string RvDir_UpdateArrGotStatus_Count_went_negative {
get {
return ResourceManager.GetString("RvDir_UpdateArrGotStatus_Count_went_negative", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unknown Reset Got status .
/// </summary>
internal static string Utils_ResetGotStatus_Unknown_Reset_Got_status {
get {
return ResourceManager.GetString("Utils_ResetGotStatus_Unknown_Reset_Got_status", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,345 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="DatUpdate_ClearOldDats_Error_dat_found_on_item_listed_as_not_in_dat" xml:space="preserve">
<value>Error dat found on item listed as not in dat</value>
</data>
<data name="DatUpdate_ClearOldDats_This_is_bad__rBase_Dat_is_set_to_a_dat_and_rBase_DatStatus_is_not" xml:space="preserve">
<value>This is bad, rBase.Dat is set to a dat, and rBase.DatStatus is not</value>
</data>
<data name="DatUpdate_ClearOldDats_Unknown_File_Delete_Test" xml:space="preserve">
<value>Unknown File Delete Test </value>
</data>
<data name="DatUpdate_ClearOldDats_Got_to_a_non_dir_when_checking_Dir_s_for_dats_to_remove" xml:space="preserve">
<value>Got to a non dir when checking Dir's for dats to remove</value>
</data>
<data name="DatUpdate_ClearOldDats_Unknown_file_setup" xml:space="preserve">
<value>Unknown file setup</value>
</data>
<data name="DatUpdate_UpdateDatList_Path" xml:space="preserve">
<value>Path: </value>
</data>
<data name="DatUpdate_UpdateDatList_Not_Found" xml:space="preserve">
<value> Not Found.</value>
</data>
<data name="DatUpdate_UpdateDatList_Empty_Directories_found_in" xml:space="preserve">
<value>Empty Directories found in '</value>
</data>
<data name="DatUpdate_UpdateDatList_Directory_will_be_ignored" xml:space="preserve">
<value>' Directory will be ignored.</value>
</data>
<data name="DatUpdate_UpdateDatList_RomValue_Scan_Error" xml:space="preserve">
<value>RomValue Scan Error:</value>
</data>
<data name="DatCmpReader_ReadDat_Error_keyword" xml:space="preserve">
<value>Error: key word '</value>
</data>
<data name="DatCmpReader_ReadDat_not_known" xml:space="preserve">
<value>' not known</value>
</data>
<data name="DatCmpReader_LoadHeaderFromDat_not_found_after_clrmamepro" xml:space="preserve">
<value>( not found after clrmamepro</value>
</data>
<data name="DatCmpReader_LoadHeaderFromDat_not_known_in_clrmamepro" xml:space="preserve">
<value>' not known in clrmamepro</value>
</data>
<data name="DatCmpReader_LoadGameFromDat_not_found_after_game" xml:space="preserve">
<value>( not found after game</value>
</data>
<data name="DatCmpReader_LoadGameFromDat_Name_not_found_as_first_object_in" xml:space="preserve">
<value>Name not found as first object in ( )</value>
</data>
<data name="DatCmpReader_LoadGameFromDat_not_known_in_game" xml:space="preserve">
<value>' not known in game</value>
</data>
<data name="DatCmpReader_LoadRomFromDat_not_found_after_rom" xml:space="preserve">
<value>( not found after rom</value>
</data>
<data name="DatCmpReader_LoadRomFromDat_not_known_in_rom" xml:space="preserve">
<value>' not known in rom</value>
</data>
<data name="FixFiles_FixFile_Trying_to_fix_a_file_that_already_exists" xml:space="preserve">
<value>Trying to fix a file that already exists </value>
</data>
<data name="FixFiles_FixFile__Did_you_manualy_fix_this_file_without_rescanning" xml:space="preserve">
<value> Did you manualy fix this file without rescanning?</value>
</data>
<data name="FixFiles_FixFile__But_the_case_of_the_unknown_file_is_wrong_Rescan_and_try_agian" xml:space="preserve">
<value> But the case of the unknown file is wrong. Rescan and try agian.</value>
</data>
<data name="FixFiles_FixFile_Unable_to_Find_the_file_used_to_fix" xml:space="preserve">
<value>Unable to Find the file used to fix </value>
</data>
<data name="FixFiles_FixFile_Unsupported_file_Fix" xml:space="preserve">
<value>Unsupported file Fix</value>
</data>
<data name="FixFiles_FixFile_Unknown_fix_file_type" xml:space="preserve">
<value>Unknown fix file type </value>
</data>
<data name="FixFiles_FixZip_Error_finding_Fixing_Rom_Database_is_corrupt" xml:space="preserve">
<value>Error finding Fixing Rom, Database is corrupt.</value>
</data>
<data name="FixFiles_FixZip_Unknown_type" xml:space="preserve">
<value>Unknown type</value>
</data>
<data name="FixFiles_FixZip_This_Delete_case_should_never_happen__you_do_not_delete_a_rom_you_collect" xml:space="preserve">
<value>This Delete case should never happen, you do not delete a rom you collect.</value>
</data>
<data name="FixFiles_FixZip_This_Delete_case_should_never_happen__help" xml:space="preserve">
<value>This Delete case should never happen, help </value>
</data>
<data name="FixFiles_OpenOriginalZip_Unknown_File_Open_Type" xml:space="preserve">
<value>Unknown File Open Type.</value>
</data>
<data name="FixFiles_OpenOriginalZip_File_TimeStamp_has_changed_in_file" xml:space="preserve">
<value>File TimeStamp has changed in file </value>
</data>
<data name="FixFiles_OpenOriginalZip_File_not_found" xml:space="preserve">
<value>File not found :</value>
</data>
<data name="FixFiles_OpenOriginalZip_Trying_to_open_an_unscanned_file" xml:space="preserve">
<value>Trying to open an unscanned file :</value>
</data>
<data name="FixFiles_OpenOriginalZip_Found_an_unknown_file" xml:space="preserve">
<value>Found an unknown file :</value>
</data>
<data name="FixFiles_OpenOriginalZip_did_you_delete_it" xml:space="preserve">
<value> did you delete it?</value>
</data>
<data name="FixFiles_PerformFixes_Trying_to_fix_unscanned_dir_s" xml:space="preserve">
<value>Trying to fix unscanned dir's</value>
</data>
<data name="DatUpdate_MergeInDat_Error_in_Logic" xml:space="preserve">
<value>Error in Logic</value>
</data>
<data name="DatUpdate_MergeInDat_Unkown_Update_Dat_Status" xml:space="preserve">
<value>Unkown Update Dat Status </value>
</data>
<data name="FrmMain_UpdateRomGrid_File_Type_Missing_" xml:space="preserve">
<value>File Type Missing </value>
</data>
<data name="RvBase_Read_Dat_found_without_an_index" xml:space="preserve">
<value>Dat found without an index</value>
</data>
<data name="RvDir_ClearDat_Clearing_Dir_with_a_dat_list" xml:space="preserve">
<value>Clearing Dir with a dat list</value>
</data>
<data name="RvDir_SetDat_Setting_Dir_with_a_dat_list" xml:space="preserve">
<value>Setting Dir with a dat list</value>
</data>
<data name="DB_Read_Data_Cache_version_is_out_of_date_you_should_now_rescan_your_dat_directory_and_roms_directory_" xml:space="preserve">
<value>Data Cache version is out of date you should now rescan your dat directory and roms directory.</value>
</data>
<data name="ProgressWindowFix_OnClosing_Cancelling" xml:space="preserve">
<value>Cancelling</value>
</data>
<data name="ProgressWindowFix_DoDone_Close" xml:space="preserve">
<value>Close</value>
</data>
<data name="FindFixes_ListCheck_Unknown_test_status" xml:space="preserve">
<value>Unknown test status </value>
</data>
<data name="Comma" xml:space="preserve">
<value> , </value>
</data>
<data name="FindFixes_ListCheck_Error_Case" xml:space="preserve">
<value>Error Case </value>
</data>
<data name="FindFixes_ListCheck_Nothing_Set_For" xml:space="preserve">
<value>Nothing Set For </value>
</data>
<data name="Utils_ResetGotStatus_Unknown_Reset_Got_status" xml:space="preserve">
<value>Unknown Reset Got status </value>
</data>
<data name="FrmSetDir_BtnSetRomLocationClick_Please_select_a_folder_for_This_Rom_Set" xml:space="preserve">
<value>Please select a folder for This Rom Set</value>
</data>
<data name="FrmSetDir_BtnDeleteSelectedClick_You_cannot_delete_the" xml:space="preserve">
<value>You cannot delete the </value>
</data>
<data name="FrmSetDir_BtnDeleteSelectedClick_Directory_Settings" xml:space="preserve">
<value> Directory Settings</value>
</data>
<data name="FrmSetDir_BtnDeleteSelectedClick_RomVault_Rom_Location" xml:space="preserve">
<value>RomVault Rom Location</value>
</data>
<data name="FrmSetDir_DataGridGamesDoubleClick_Edit_Existing_Directory_Mapping" xml:space="preserve">
<value>Edit Existing Directory Mapping</value>
</data>
<data name="FrmSettings_BtnDatClick_Please_select_a_folder_for_DAT_Root" xml:space="preserve">
<value>Please select a folder for DAT Root</value>
</data>
<data name="RvBase_Check_Unknown_Error_Status_File" xml:space="preserve">
<value>Unknown Error Status File </value>
</data>
<data name="RvBase_Check" xml:space="preserve">
<value> , </value>
</data>
<data name="RvBase_SetGot_Unknown_Set_Got_Status" xml:space="preserve">
<value>Unknown Set Got Status </value>
</data>
<data name="RvDir_UpdateArrGotStatus_Count_went_negative" xml:space="preserve">
<value>Count went negative.</value>
</data>
<data name="DatUpdate_ClearRemovedDatsFromTheDb_This_should_also_never_happen" xml:space="preserve">
<value>This should also never happen.</value>
</data>
<data name="DatUpdate_UpdateDatFile_Unknown_Merge_Status" xml:space="preserve">
<value>Unknown Merge Status</value>
</data>
<data name="FixFiles_FixDirChildren_Unknown_result_type" xml:space="preserve">
<value>Unknown result type</value>
</data>
<data name="FixFiles_FixZip_Error_in_Fix_Rom_Status" xml:space="preserve">
<value>Error in Fix Rom Status </value>
</data>
<data name="FixFiles_FixZip_Colon" xml:space="preserve">
<value> : </value>
</data>
<data name="FileScanning_CheckADir_Error_in_File_Scanning_Code" xml:space="preserve">
<value>Error in File Scanning Code.</value>
</data>
<data name="DatCmpReader_LoadDirFromDat_Error_Keyword" xml:space="preserve">
<value>Error Keyword </value>
</data>
<data name="DatCmpReader_LoadDirFromDat_not_know_in_dir" xml:space="preserve">
<value>not know in dir</value>
</data>
<data name="Program_Main_You_must_have_a__user____NAME__xml__file_to_use_RomVault" xml:space="preserve">
<value>You must have a 'user - &lt;NAME&gt;.xml' file to use RomVault</value>
</data>
<data name="Program_Main_You_are_not_Authorised_to_use_this_program" xml:space="preserve">
<value>You are not Authorised to use this program.</value>
</data>
<data name="Program_Main_There_is_a_new_release_download_now_from" xml:space="preserve">
<value>There is a new release download now from </value>
</data>
<data name="DatUpdate_UpdateDatList_ERROR_Deleting_a_DAT_that_should_already_be_deleted" xml:space="preserve">
<value>ERROR Deleting a DAT that should already be deleted</value>
</data>
<data name="FixFiles_FixZip_Error_processing_zip" xml:space="preserve">
<value>Error processing zip </value>
</data>
<data name="Report_MakeFixFiles_Please_select_a_folder_for_Dats" xml:space="preserve">
<value>Please select a folder for Dats</value>
</data>
<data name="FrmMain_DirTreeRvSelected_Set_ROM_DIR">
<value xml:space="preserve">Set ROM DIR</value>
</data>
</root>

View File

@@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.34003
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ROMVault2.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

337
ROMVault2/ROMVault2.csproj Normal file
View File

@@ -0,0 +1,337 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{437E12AB-46F3-4A75-A3D5-6C524B5A79B5}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ROMVault2</RootNamespace>
<AssemblyName>ROMVault21</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
<IsWebBootstrapper>false</IsWebBootstrapper>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\Stage\</OutputPath>
<DefineConstants>TRACE;DEBUG;UNMANAGED, COMPRESS, LZMA_STREAM, DOTNET20</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\Stage\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\..\Stage\</OutputPath>
<DefineConstants>TRACE;DEBUG;UNMANAGED, COMPRESS, LZMA_STREAM, DOTNET20</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<CodeAnalysisLogFile>..\..\Stage2\ROMVault2.exe.CodeAnalysisLog.xml</CodeAnalysisLogFile>
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
<CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
<CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<OutputPath>..\..\Stage\</OutputPath>
<DefineConstants>TRACE;UNMANAGED, COMPRESS, LZMA_STREAM, DOTNET20</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<CodeAnalysisLogFile>bin\Release\ROMVault2.exe.CodeAnalysisLog.xml</CodeAnalysisLogFile>
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
<CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>chip.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="DatMaker.cs" />
<Compile Include="Report.cs" />
<Compile Include="SupportedFiles\CHD\CHD.cs" />
<Compile Include="DatReaders\DatDOSReader.cs" />
<Compile Include="FindFixes.cs" />
<Compile Include="FixFileCopy.cs" />
<Compile Include="FixFiles.cs" />
<Compile Include="FrmProgressWindowFix.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="FrmProgressWindowFix.designer.cs">
<DependentUpon>FrmProgressWindowFix.cs</DependentUpon>
</Compile>
<Compile Include="RvDB\FileStatus.cs" />
<Compile Include="RvDB\RvBase.cs" />
<Compile Include="RvDB\RvDat.cs" />
<Compile Include="RvDB\RvDir.cs" />
<Compile Include="RvDB\RvFile.cs" />
<Compile Include="RvDB\RvGame.cs" />
<Compile Include="rvTreeRow.cs" />
<Compile Include="rvImages.cs" />
<Compile Include="SupportedFiles\Files\UnCompFiles.cs" />
<Compile Include="SupportedFiles\ZipEnums.cs" />
<Compile Include="Utils\ArrByte.cs" />
<Compile Include="BackGroundWorkerInterface.cs" />
<Compile Include="DatReaders\DatCmpReader.cs" />
<Compile Include="DatReaders\DatMessXMLReader.cs" />
<Compile Include="DatReaders\DatReader.cs" />
<Compile Include="DatReaders\DatXMLReader.cs" />
<Compile Include="DatUpdate.cs" />
<Compile Include="FileScanning.cs" />
<Compile Include="frmHelpAbout.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="frmHelpAbout.Designer.cs">
<DependentUpon>frmHelpAbout.cs</DependentUpon>
</Compile>
<Compile Include="frmKey.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="frmKey.designer.cs">
<DependentUpon>frmKey.cs</DependentUpon>
</Compile>
<Compile Include="FrmProgressWindow.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="FrmProgressWindow.Designer.cs">
<DependentUpon>FrmProgressWindow.cs</DependentUpon>
</Compile>
<Compile Include="FrmRegistration.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="FrmRegistration.Designer.cs">
<DependentUpon>FrmRegistration.cs</DependentUpon>
</Compile>
<Compile Include="frmSetDir.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="frmSetDir.Designer.cs">
<DependentUpon>frmSetDir.cs</DependentUpon>
</Compile>
<Compile Include="frmSettings.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="frmSettings.Designer.cs">
<DependentUpon>frmSettings.cs</DependentUpon>
</Compile>
<Compile Include="DirCellDraw.cs" />
<Compile Include="frmShowError.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="frmShowError.designer.cs">
<DependentUpon>frmShowError.cs</DependentUpon>
</Compile>
<Compile Include="frmSplashScreen.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="frmSplashScreen.Designer.cs">
<DependentUpon>frmSplashScreen.cs</DependentUpon>
</Compile>
<Compile Include="ReportError.cs" />
<Compile Include="rvImages1.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>rvImages1.resx</DependentUpon>
</Compile>
<Compile Include="IO\RVIO.cs" />
<Compile Include="rvTree.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="rvTree.Designer.cs">
<DependentUpon>rvTree.cs</DependentUpon>
</Compile>
<Compile Include="Service References\RVRef\Reference.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Reference.svcmap</DependentUpon>
</Compile>
<Compile Include="Settings.cs" />
<Compile Include="RvDB\DB.cs" />
<Compile Include="FrmMain.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="FrmMain.Designer.cs">
<DependentUpon>FrmMain.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RepairStatus.cs" />
<Compile Include="DBHelper.cs" />
<Compile Include="Utils\DBTypeGet.cs" />
<Compile Include="Utils\RelativePath.cs" />
<Compile Include="Utils\ULong.cs" />
<Compile Include="Utils\VarFix.cs" />
<Compile Include="IO\Win32Native.cs" />
<Compile Include="SupportedFiles\Zip\zipFile.cs" />
<Compile Include="SupportedFiles\Zip\ZLib\Crc32.cs" />
<Compile Include="SupportedFiles\Zip\ZLib\Deflate.cs" />
<Compile Include="SupportedFiles\Zip\ZLib\DeflateStream.cs" />
<Compile Include="SupportedFiles\Zip\ZLib\GZipStream.cs" />
<Compile Include="SupportedFiles\Zip\ZLib\Inflate.cs" />
<Compile Include="SupportedFiles\Zip\ZLib\InfTree.cs" />
<Compile Include="SupportedFiles\Zip\ZLib\Tree.cs" />
<Compile Include="SupportedFiles\Zip\ZLib\Zlib.cs" />
<Compile Include="SupportedFiles\Zip\ZLib\ZlibBaseStream.cs" />
<Compile Include="SupportedFiles\Zip\ZLib\ZlibCodec.cs" />
<Compile Include="SupportedFiles\Zip\ZLib\ZlibConstants.cs" />
<Compile Include="SupportedFiles\Zip\ZLib\ZlibStream.cs" />
<EmbeddedResource Include="frmHelpAbout.resx">
<DependentUpon>frmHelpAbout.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="frmKey.resx">
<DependentUpon>frmKey.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="FrmMain.resx">
<DependentUpon>FrmMain.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="FrmProgressWindow.resx">
<DependentUpon>FrmProgressWindow.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="FrmProgressWindowFix.resx">
<DependentUpon>FrmProgressWindowFix.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="FrmRegistration.resx">
<DependentUpon>FrmRegistration.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="frmSettings.resx">
<DependentUpon>frmSettings.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="frmShowError.resx">
<DependentUpon>frmShowError.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="frmSplashScreen.resx">
<DependentUpon>frmSplashScreen.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<EmbeddedResource Include="rvImages1.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>rvImages1.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="rvTree.resx">
<DependentUpon>rvTree.cs</DependentUpon>
</EmbeddedResource>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<None Include="Service References\RVRef\Service1.xsd">
<SubType>Designer</SubType>
</None>
<None Include="Service References\RVRef\Service11.wsdl" />
<None Include="Service References\RVRef\Service11.xsd">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<Content Include="chdman.exe">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="chip.ico" />
<None Include="Service References\RVRef\Service11.disco" />
<None Include="Service References\RVRef\Reference.svcmap">
<Generator>WCF Proxy Generator</Generator>
<LastGenOutput>Reference.cs</LastGenOutput>
</None>
<None Include="Service References\RVRef\configuration.svcinfo" />
<None Include="Service References\RVRef\configuration91.svcinfo" />
</ItemGroup>
<ItemGroup>
<WCFMetadata Include="Service References\" />
</ItemGroup>
<ItemGroup>
<WCFMetadataStorage Include="Service References\RVRef\" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

318
ROMVault2/RepairStatus.cs Normal file
View File

@@ -0,0 +1,318 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Collections.Generic;
using ROMVault2.RvDB;
namespace ROMVault2
{
public enum RepStatus
{
// Scanning Status:
Error,
UnSet,
UnScanned,
DirCorrect,
DirMissing,
DirUnknown,
DirInToSort,
DirCorrupt,
Missing, // a files or directory from a DAT that we do not have
Correct, // a files or directory from a DAT that we have
NotCollected, // a file from a DAT that is not collected that we do not have (either a merged or bad file.)
UnNeeded, // a file from a DAT that is not collected that we do have, and so do not need. (a merged file in a child set)
Unknown, // a file that is not in a DAT
InToSort, // a file that is in the ToSort directory
Corrupt, // either a Zip file that is corrupt, or a Zipped file that is corrupt
Ignore, // a file found in the ignore list
// Fix Status:
CanBeFixed, // a missing file that can be fixed from another file. (Will be set to correct once it has been corrected)
MoveToSort, // a file that is not in any DAT (Unknown) and should be moved to ToSort
Delete, // a file that can be deleted
NeededForFix, // a file that is Unknown where it is, but is needed somewhere else.
Rename, // a file that is Unknown where it is, but is needed with other name inside the same Zip.
CorruptCanBeFixed, // a corrupt file that can be replaced and fixed from another file.
MoveToCorrupt, // a corrupt file that should just be moved out the way to a corrupt directory in ToSort.
Deleted, // this is a temporary value used while fixing sets, this value should never been seen.
EndValue
}
public static class RepairStatus
{
public static List<RepStatus>[, ,] StatusCheck;
public static RepStatus[] DisplayOrder;
public static void InitStatusCheck()
{
StatusCheck = new List<RepStatus>
[
Enum.GetValues(typeof(FileType)).Length,
Enum.GetValues(typeof(DatStatus)).Length,
Enum.GetValues(typeof(GotStatus)).Length
];
//sorted alphabetically
StatusCheck[(int)FileType.Dir, (int)DatStatus.InDatCollect, (int)GotStatus.Got] = new List<RepStatus> { RepStatus.DirCorrect };
StatusCheck[(int)FileType.Dir, (int)DatStatus.InDatCollect, (int)GotStatus.NotGot] = new List<RepStatus> { RepStatus.DirMissing };
StatusCheck[(int)FileType.Dir, (int)DatStatus.InToSort, (int)GotStatus.Got] = new List<RepStatus> { RepStatus.DirInToSort };
StatusCheck[(int)FileType.Dir, (int)DatStatus.InToSort, (int)GotStatus.NotGot] = new List<RepStatus> { RepStatus.Deleted };
StatusCheck[(int)FileType.Dir, (int)DatStatus.NotInDat, (int)GotStatus.Got] = new List<RepStatus> { RepStatus.DirUnknown };
StatusCheck[(int)FileType.Dir, (int)DatStatus.NotInDat, (int)GotStatus.NotGot] = new List<RepStatus> { RepStatus.Deleted };
StatusCheck[(int)FileType.Zip, (int)DatStatus.InDatCollect, (int)GotStatus.Got] = new List<RepStatus> { RepStatus.DirCorrect };
StatusCheck[(int)FileType.Zip, (int)DatStatus.InDatCollect, (int)GotStatus.Corrupt] = new List<RepStatus> { RepStatus.DirCorrupt };
StatusCheck[(int)FileType.Zip, (int)DatStatus.InDatCollect, (int)GotStatus.FileLocked] = new List<RepStatus> { RepStatus.UnScanned };
StatusCheck[(int)FileType.Zip, (int)DatStatus.InDatCollect, (int)GotStatus.NotGot] = new List<RepStatus> { RepStatus.DirMissing };
StatusCheck[(int)FileType.Zip, (int)DatStatus.InToSort, (int)GotStatus.Got] = new List<RepStatus> { RepStatus.DirInToSort };
StatusCheck[(int)FileType.Zip, (int)DatStatus.InToSort, (int)GotStatus.Corrupt] = new List<RepStatus> { RepStatus.DirCorrupt };
StatusCheck[(int)FileType.Zip, (int)DatStatus.InToSort, (int)GotStatus.FileLocked] = new List<RepStatus> { RepStatus.UnScanned };
StatusCheck[(int)FileType.Zip, (int)DatStatus.InToSort, (int)GotStatus.NotGot] = new List<RepStatus> { RepStatus.Deleted };
StatusCheck[(int)FileType.Zip, (int)DatStatus.NotInDat, (int)GotStatus.Got] = new List<RepStatus> { RepStatus.DirUnknown };
StatusCheck[(int)FileType.Zip, (int)DatStatus.NotInDat, (int)GotStatus.Corrupt] = new List<RepStatus> { RepStatus.DirCorrupt };
StatusCheck[(int)FileType.Zip, (int)DatStatus.NotInDat, (int)GotStatus.FileLocked] = new List<RepStatus> { RepStatus.UnScanned };
StatusCheck[(int)FileType.Zip, (int)DatStatus.NotInDat, (int)GotStatus.NotGot] = new List<RepStatus> { RepStatus.Deleted };
StatusCheck[(int)FileType.File, (int)DatStatus.InDatBad, (int)GotStatus.FileLocked] = new List<RepStatus> { RepStatus.UnScanned };
StatusCheck[(int)FileType.File, (int)DatStatus.InDatBad, (int)GotStatus.NotGot] = new List<RepStatus> { RepStatus.NotCollected };
StatusCheck[(int)FileType.File, (int)DatStatus.InDatCollect, (int)GotStatus.Corrupt] = new List<RepStatus> { RepStatus.Corrupt, RepStatus.MoveToCorrupt, RepStatus.CorruptCanBeFixed };
StatusCheck[(int)FileType.File, (int)DatStatus.InDatCollect, (int)GotStatus.FileLocked] = new List<RepStatus> { RepStatus.UnScanned };
StatusCheck[(int)FileType.File, (int)DatStatus.InDatCollect, (int)GotStatus.Got] = new List<RepStatus> { RepStatus.Correct };
StatusCheck[(int)FileType.File, (int)DatStatus.InDatCollect, (int)GotStatus.NotGot] = new List<RepStatus> { RepStatus.Missing, RepStatus.CanBeFixed };
StatusCheck[(int)FileType.File, (int)DatStatus.InDatMerged, (int)GotStatus.Corrupt] = new List<RepStatus> { RepStatus.Corrupt, RepStatus.MoveToCorrupt, RepStatus.Delete };
StatusCheck[(int)FileType.File, (int)DatStatus.InDatMerged, (int)GotStatus.FileLocked] = new List<RepStatus> { RepStatus.UnScanned };
StatusCheck[(int)FileType.File, (int)DatStatus.InDatMerged, (int)GotStatus.Got] = new List<RepStatus> { RepStatus.UnNeeded, RepStatus.Delete, RepStatus.NeededForFix };
StatusCheck[(int)FileType.File, (int)DatStatus.InDatMerged, (int)GotStatus.NotGot] = new List<RepStatus> { RepStatus.NotCollected };
StatusCheck[(int)FileType.File, (int)DatStatus.InToSort, (int)GotStatus.Corrupt] = new List<RepStatus> { RepStatus.Corrupt, RepStatus.Delete };
StatusCheck[(int)FileType.File, (int)DatStatus.InToSort, (int)GotStatus.FileLocked] = new List<RepStatus> { RepStatus.UnScanned };
StatusCheck[(int)FileType.File, (int)DatStatus.InToSort, (int)GotStatus.Got] = new List<RepStatus> { RepStatus.InToSort, RepStatus.Ignore, RepStatus.NeededForFix, RepStatus.Delete };
StatusCheck[(int)FileType.File, (int)DatStatus.InToSort, (int)GotStatus.NotGot] = new List<RepStatus> { RepStatus.Deleted };
StatusCheck[(int)FileType.File, (int)DatStatus.NotInDat, (int)GotStatus.Corrupt] = new List<RepStatus> { RepStatus.Corrupt, RepStatus.MoveToCorrupt, RepStatus.Delete };
StatusCheck[(int)FileType.File, (int)DatStatus.NotInDat, (int)GotStatus.Got] = new List<RepStatus> { RepStatus.Unknown, RepStatus.Ignore, RepStatus.Delete, RepStatus.MoveToSort, RepStatus.NeededForFix, RepStatus.Rename };
StatusCheck[(int)FileType.File, (int)DatStatus.NotInDat, (int)GotStatus.FileLocked] = new List<RepStatus> { RepStatus.UnScanned };
StatusCheck[(int)FileType.File, (int)DatStatus.NotInDat, (int)GotStatus.NotGot] = new List<RepStatus> { RepStatus.Deleted };
StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InDatBad, (int)GotStatus.NotGot] = new List<RepStatus> { RepStatus.NotCollected };
StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InDatBad, (int)GotStatus.Got] = new List<RepStatus> { RepStatus.Correct };
StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InDatCollect, (int)GotStatus.Corrupt] = new List<RepStatus> { RepStatus.Corrupt, RepStatus.MoveToCorrupt, RepStatus.CorruptCanBeFixed };
StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InDatCollect, (int)GotStatus.Got] = new List<RepStatus> { RepStatus.Correct };
StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InDatCollect, (int)GotStatus.FileLocked] = new List<RepStatus> { RepStatus.UnScanned };
StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InDatCollect, (int)GotStatus.NotGot] = new List<RepStatus> { RepStatus.Missing, RepStatus.CanBeFixed };
StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InDatMerged, (int)GotStatus.Got] = new List<RepStatus> { RepStatus.UnNeeded, RepStatus.Delete, RepStatus.NeededForFix, RepStatus.Rename };
StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InDatMerged, (int)GotStatus.NotGot] = new List<RepStatus> { RepStatus.NotCollected };
StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InToSort, (int)GotStatus.Corrupt] = new List<RepStatus> { RepStatus.Corrupt, RepStatus.Delete };
StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InToSort, (int)GotStatus.Got] = new List<RepStatus> { RepStatus.InToSort, RepStatus.NeededForFix, RepStatus.Delete };
StatusCheck[(int)FileType.ZipFile, (int)DatStatus.InToSort, (int)GotStatus.NotGot] = new List<RepStatus> { RepStatus.Deleted };
StatusCheck[(int)FileType.ZipFile, (int)DatStatus.NotInDat, (int)GotStatus.Corrupt] = new List<RepStatus> { RepStatus.Corrupt, RepStatus.MoveToCorrupt, RepStatus.Delete };
StatusCheck[(int)FileType.ZipFile, (int)DatStatus.NotInDat, (int)GotStatus.Got] = new List<RepStatus> { RepStatus.Unknown, RepStatus.Delete, RepStatus.MoveToSort, RepStatus.NeededForFix, RepStatus.Rename };
StatusCheck[(int)FileType.ZipFile, (int)DatStatus.NotInDat, (int)GotStatus.NotGot] = new List<RepStatus> { RepStatus.Deleted };
DisplayOrder = new[]
{
RepStatus.Error,
RepStatus.UnSet,
RepStatus.UnScanned,
//RepStatus.DirCorrect,
//RepStatus.DirCorrectBadCase,
//RepStatus.DirMissing,
//RepStatus.DirUnknown,
RepStatus.DirCorrupt,
RepStatus.MoveToCorrupt,
RepStatus.CorruptCanBeFixed,
RepStatus.CanBeFixed,
RepStatus.MoveToSort,
RepStatus.Delete,
RepStatus.NeededForFix,
RepStatus.Rename,
RepStatus.Corrupt,
RepStatus.Unknown,
RepStatus.UnNeeded,
RepStatus.Missing,
RepStatus.Correct,
RepStatus.InToSort,
RepStatus.NotCollected,
RepStatus.Ignore,
RepStatus.Deleted
};
}
public static void ReportStatusReset(RvBase tBase)
{
tBase.RepStatusReset();
FileType ftBase = tBase.FileType;
if (ftBase != FileType.Zip && ftBase != FileType.Dir) return;
RvDir tDir = (RvDir)tBase;
for (int i = 0; i < tDir.ChildCount; i++)
ReportStatusReset(tDir.Child(i));
}
}
public class ReportStatus
{
private readonly int[] _arrRepStatus = new int[(int)RepStatus.EndValue];
public void UpdateRepStatus(ReportStatus rs, int dir)
{
for (int i = 0; i < _arrRepStatus.Length; i++)
_arrRepStatus[i] += rs.Get((RepStatus)i) * dir;
}
public void UpdateRepStatus(RepStatus rs, int dir)
{
_arrRepStatus[(int)rs] += dir;
}
#region "arrGotStatus Processing"
public int Get(RepStatus v)
{
return _arrRepStatus[(int)v];
}
public int CountCorrect()
{
return _arrRepStatus[(int)RepStatus.Correct];
}
public bool HasCorrect()
{
return CountCorrect() > 0;
}
public int CountMissing()
{
return (
_arrRepStatus[(int)RepStatus.UnScanned] +
_arrRepStatus[(int)RepStatus.Missing] +
_arrRepStatus[(int)RepStatus.DirCorrupt] +
_arrRepStatus[(int)RepStatus.Corrupt] +
_arrRepStatus[(int)RepStatus.CanBeFixed] +
_arrRepStatus[(int)RepStatus.CorruptCanBeFixed]
);
}
public bool HasMissing()
{
return CountMissing() > 0;
}
public int CountFixesNeeded()
{
return (
_arrRepStatus[(int)RepStatus.CanBeFixed] +
_arrRepStatus[(int)RepStatus.MoveToSort] +
_arrRepStatus[(int)RepStatus.Delete] +
_arrRepStatus[(int)RepStatus.NeededForFix] +
_arrRepStatus[(int)RepStatus.Rename] +
_arrRepStatus[(int)RepStatus.CorruptCanBeFixed] +
_arrRepStatus[(int)RepStatus.MoveToCorrupt]
);
}
public bool HasFixesNeeded()
{
return CountFixesNeeded() > 0;
}
public int CountCanBeFixed()
{
return (
_arrRepStatus[(int)RepStatus.CanBeFixed] +
_arrRepStatus[(int)RepStatus.CorruptCanBeFixed]);
}
private int CountFixable()
{
return (
_arrRepStatus[(int)RepStatus.CanBeFixed] +
_arrRepStatus[(int)RepStatus.MoveToSort] +
_arrRepStatus[(int)RepStatus.Delete] +
_arrRepStatus[(int)RepStatus.CorruptCanBeFixed] +
_arrRepStatus[(int)RepStatus.MoveToCorrupt]
);
}
public bool HasFixable()
{
return CountFixable() > 0;
}
private int CountAnyFiles()
{
// this list include probably more status's than are needed, but all are here to double check I don't delete something I should not.
return (
_arrRepStatus[(int)RepStatus.Correct] +
_arrRepStatus[(int)RepStatus.UnNeeded] +
_arrRepStatus[(int)RepStatus.Unknown] +
_arrRepStatus[(int)RepStatus.InToSort] +
_arrRepStatus[(int)RepStatus.Corrupt] +
_arrRepStatus[(int)RepStatus.Ignore] +
_arrRepStatus[(int)RepStatus.MoveToSort] +
_arrRepStatus[(int)RepStatus.Delete] +
_arrRepStatus[(int)RepStatus.NeededForFix] +
_arrRepStatus[(int)RepStatus.Rename] +
_arrRepStatus[(int)RepStatus.MoveToCorrupt]
);
}
public bool HasAnyFiles()
{
return CountAnyFiles() > 0;
}
public int CountUnknown()
{
return _arrRepStatus[(int)RepStatus.Unknown];
}
public bool HasUnknown()
{
return CountUnknown() > 0;
}
public int CountInToSort()
{
return _arrRepStatus[(int)RepStatus.InToSort];
}
public bool HasInToSort()
{
return CountInToSort() > 0;
}
#endregion
}
}

430
ROMVault2/Report.cs Normal file
View File

@@ -0,0 +1,430 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using ROMVault2.RvDB;
using ROMVault2.Utils;
namespace ROMVault2
{
static class Report
{
private static StreamWriter _ts;
private static RvDat _tDat;
private static string _outdir;
private static string Etxt(string e)
{
string ret = e;
ret = ret.Replace("&", "&amp;");
ret = ret.Replace("\"", "&quot;");
ret = ret.Replace("'", "&apos;");
ret = ret.Replace("<", "&lt;");
ret = ret.Replace(">", "&gt;");
return ret;
}
public static void MakeFixFiles()
{
_tDat = null;
_ts = null;
FolderBrowserDialog browse = new FolderBrowserDialog
{
ShowNewFolderButton = true,
Description = @"Please select a folder for Dats",
RootFolder = Environment.SpecialFolder.DesktopDirectory,
SelectedPath = @"apps"
};
if (browse.ShowDialog() != DialogResult.OK) return;
_outdir = browse.SelectedPath;
_tDat = null;
MakeFixFilesRecurse(DB.DirTree.Child(0), true);
if (_ts == null) return;
_ts.WriteLine("</datafile>");
_ts.Close();
}
private static void MakeFixFilesRecurse(RvBase b, bool selected)
{
if (selected)
{
if (b.Dat != null)
{
RvDir tDir = b as RvDir;
if (tDir != null && tDir.Game != null && tDir.DirStatus.HasMissing())
{
if (_tDat != b.Dat)
{
if (_tDat != null)
{
_ts.WriteLine("</datafile>");
_ts.WriteLine();
}
if (_ts != null) _ts.Close();
_tDat = b.Dat;
int test = 0;
string datFilename = Path.Combine(_outdir, "fixDat_" + Path.GetFileNameWithoutExtension(_tDat.GetData(RvDat.DatData.DatFullName)) + ".dat");
while (File.Exists(datFilename))
{
test++;
datFilename = Path.Combine(_outdir, "fixDat_" + Path.GetFileNameWithoutExtension(_tDat.GetData(RvDat.DatData.DatFullName)) + "(" + test + ").dat");
}
_ts = new StreamWriter(datFilename);
_ts.WriteLine("<?xml version=\"1.0\"?>");
_ts.WriteLine(
"<!DOCTYPE datafile PUBLIC \"-//Logiqx//DTD ROM Management Datafile//EN\" \"http://www.logiqx.com/Dats/datafile.dtd\">");
_ts.WriteLine("");
_ts.WriteLine("<datafile>");
_ts.WriteLine("\t<header>");
_ts.WriteLine("\t\t<name>fix_" + Etxt(_tDat.GetData(RvDat.DatData.DatName)) + "</name>");
if (_tDat.GetData(RvDat.DatData.SuperDat) == "superdat")
_ts.WriteLine("\t\t<type>SuperDAT</type>");
_ts.WriteLine("\t\t<description>fix_" + Etxt(_tDat.GetData(RvDat.DatData.Description)) + "</description>");
_ts.WriteLine("\t\t<category>FIXDATFILE</category>");
_ts.WriteLine("\t\t<version>" + DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss") + "</version>");
_ts.WriteLine("\t\t<date>" + DateTime.Now.ToString("MM/dd/yyyy") + "</date>");
_ts.WriteLine("\t\t<author>RomVault</author>");
_ts.WriteLine("\t</header>");
}
_ts.WriteLine("\t<game name=\"" + Etxt(tDir.SuperDatFileName()) + "\">");
if (!string.IsNullOrEmpty(tDir.Game.GetData(RvGame.GameData.Description)))
_ts.WriteLine("\t\t<description>" + Etxt(tDir.Game.GetData(RvGame.GameData.Description)) + "</description>");
}
RvFile tRom = b as RvFile;
if (tRom != null)
{
if (tRom.DatStatus == DatStatus.InDatCollect && tRom.GotStatus != GotStatus.Got)
{
string strRom;
if (tRom.FileStatusIs(FileStatus.SHA1CHDFromDAT | FileStatus.MD5CHDFromDAT))
strRom = "\t\t<disk name=\"" + Etxt(tRom.Name) + "\"";
else
strRom = "\t\t<rom name=\"" + Etxt(tRom.Name) + "\"";
if (tRom.FileStatusIs(FileStatus.SizeFromDAT) && tRom.Size != null)
strRom += " size=\"" + tRom.Size + "\"";
string strCRC = ArrByte.ToString(tRom.CRC);
if (tRom.FileStatusIs(FileStatus.CRCFromDAT) && !string.IsNullOrEmpty(strCRC))
strRom += " crc=\"" + strCRC + "\"";
string strSHA1 = ArrByte.ToString(tRom.SHA1);
if (tRom.FileStatusIs(FileStatus.SHA1FromDAT) && !string.IsNullOrEmpty(strSHA1))
strRom += " sha1=\"" + strSHA1 + "\"";
string strMD5 = ArrByte.ToString(tRom.MD5);
if (tRom.FileStatusIs(FileStatus.MD5FromDAT) && !string.IsNullOrEmpty(strMD5))
strRom += " md5=\"" + strMD5 + "\"";
string strSHA1CHD = ArrByte.ToString(tRom.SHA1CHD);
if (tRom.FileStatusIs(FileStatus.SHA1CHDFromDAT) && !string.IsNullOrEmpty(strSHA1CHD))
strRom += " sha1=\"" + strSHA1CHD + "\"";
string strMD5CHD = ArrByte.ToString(tRom.MD5CHD);
if (tRom.FileStatusIs(FileStatus.MD5CHDFromDAT) && !string.IsNullOrEmpty(strMD5CHD))
strRom += " md5=\"" + strMD5CHD + "\"";
strRom += "/>";
_ts.WriteLine(strRom);
}
}
}
}
RvDir d = b as RvDir;
if (d != null)
{
for (int i = 0; i < d.ChildCount; i++)
{
bool nextSelected = selected;
if (d.Tree != null)
nextSelected = d.Tree.Checked == RvTreeRow.TreeSelect.Selected;
MakeFixFilesRecurse(d.Child(i), nextSelected);
}
}
if (selected)
{
if (b.Dat != null)
{
RvDir tDir = b as RvDir;
if (tDir != null && tDir.Game != null && tDir.DirStatus.HasMissing())
{
_ts.WriteLine("\t</game>");
}
}
}
}
private enum ReportType
{
Complete,
CompletelyMissing,
PartialMissing,
Fixing
}
private static string CleanTime()
{
return " (" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ")";
}
public static void GenerateReport()
{
SaveFileDialog saveFileDialog1 = new SaveFileDialog
{
Title = @"Generate Full Report",
FileName = @"RVFullReport"+CleanTime()+".txt",
Filter = @"Rom Vault Report (*.txt)|*.txt|All Files (*.*)|*.*",
FilterIndex = 1
};
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
_ts = new StreamWriter(saveFileDialog1.FileName);
_ts.WriteLine("Complete DAT Sets");
_ts.WriteLine("-----------------------------------------");
FindAllDats(DB.DirTree.Child(0), ReportType.Complete);
_ts.WriteLine("");
_ts.WriteLine("");
_ts.WriteLine("Empty DAT Sets");
_ts.WriteLine("-----------------------------------------");
FindAllDats(DB.DirTree.Child(0), ReportType.CompletelyMissing);
_ts.WriteLine("");
_ts.WriteLine("");
_ts.WriteLine("Partial DAT Sets - (Listing Missing ROMs)");
_ts.WriteLine("-----------------------------------------");
FindAllDats(DB.DirTree.Child(0), ReportType.PartialMissing);
_ts.Close();
}
}
public static void GenerateFixReport()
{
SaveFileDialog saveFileDialog1 = new SaveFileDialog
{
Title = @"Generate Fix Report",
FileName = @"RVFixReport"+CleanTime()+".txt",
Filter = @"Rom Vault Fixing Report (*.txt)|*.txt|All Files (*.*)|*.*",
FilterIndex = 1
};
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
_ts = new StreamWriter(saveFileDialog1.FileName);
_ts.WriteLine("Listing Fixes");
_ts.WriteLine("-----------------------------------------");
FindAllDats(DB.DirTree.Child(0), ReportType.Fixing);
_ts.Close();
}
}
private static void FindAllDats(RvBase b, ReportType rt)
{
RvDir d = b as RvDir;
if (d == null) return;
if (d.DirDatCount > 0)
{
for (int i = 0; i < d.DirDatCount; i++)
{
RvDat dat = d.DirDat(i);
int correct = 0;
int missing = 0;
int fixesNeeded = 0;
if (d.Dat == dat)
{
correct += d.DirStatus.CountCorrect();
missing += d.DirStatus.CountMissing();
fixesNeeded += d.DirStatus.CountFixesNeeded();
}
else
{
for (int j = 0; j < d.ChildCount; j++)
{
RvDir c = d.Child(j) as RvDir;
if (c == null || c.Dat != dat) continue;
correct += c.DirStatus.CountCorrect();
missing += c.DirStatus.CountMissing();
fixesNeeded += c.DirStatus.CountFixesNeeded();
}
}
switch (rt)
{
case ReportType.Complete:
if (correct > 0 && missing == 0 && fixesNeeded == 0)
_ts.WriteLine(RemoveBase(dat.GetData(RvDat.DatData.DatFullName)));
break;
case ReportType.CompletelyMissing:
if (correct == 0 && missing > 0 && fixesNeeded == 0)
_ts.WriteLine(RemoveBase(dat.GetData(RvDat.DatData.DatFullName)));
break;
case ReportType.PartialMissing:
if ((correct > 0 && missing > 0) || fixesNeeded > 0)
{
_ts.WriteLine(RemoveBase(dat.GetData(RvDat.DatData.DatFullName)));
_fileNameLength = 0;
_fileSizeLength = 0;
_repStatusLength = 0;
ReportMissingFindSizes(d, dat, rt);
ReportDrawBars();
ReportMissing(d, dat, rt);
ReportDrawBars();
_ts.WriteLine();
}
break;
case ReportType.Fixing:
if (fixesNeeded > 0)
{
_ts.WriteLine(RemoveBase(dat.GetData(RvDat.DatData.DatFullName)));
_fileNameLength = 0;
_fileSizeLength = 0;
_repStatusLength = 0;
ReportMissingFindSizes(d, dat, rt);
ReportDrawBars();
ReportMissing(d, dat, rt);
ReportDrawBars();
_ts.WriteLine();
}
break;
}
}
}
if (b.Dat != null) return;
for (int i = 0; i < d.ChildCount; i++)
FindAllDats(d.Child(i), rt);
}
private static string RemoveBase(string name)
{
int p = name.IndexOf("\\", StringComparison.Ordinal);
return p > 0 ? name.Substring(p + 1) : name;
}
private static int _fileNameLength;
private static int _fileSizeLength;
private static int _repStatusLength;
private static readonly RepStatus[] Partial =
{
RepStatus.UnScanned,
RepStatus.Missing,
RepStatus.Corrupt,
RepStatus.CanBeFixed,
RepStatus.CorruptCanBeFixed,
};
private static readonly RepStatus[] Fixing =
{
RepStatus.CanBeFixed,
RepStatus.MoveToSort,
RepStatus.Delete,
RepStatus.NeededForFix,
RepStatus.Rename,
RepStatus.CorruptCanBeFixed,
RepStatus.MoveToCorrupt
};
private static void ReportMissingFindSizes(RvDir dir, RvDat dat, ReportType rt)
{
for (int i = 0; i < dir.ChildCount; i++)
{
RvBase b = dir.Child(i);
if (b.Dat != null && b.Dat != dat)
continue;
RvFile f = b as RvFile;
if (f != null)
{
if (
(rt == ReportType.PartialMissing && Partial.Contains(f.RepStatus)) ||
(rt == ReportType.Fixing && Fixing.Contains(f.RepStatus))
)
{
int fileNameLength = f.FileNameInsideGame().Length;
int fileSizeLength = f.Size.ToString().Length;
int repStatusLength = f.RepStatus.ToString().Length;
if (fileNameLength > _fileNameLength) _fileNameLength = fileNameLength;
if (fileSizeLength > _fileSizeLength) _fileSizeLength = fileSizeLength;
if (repStatusLength > _repStatusLength) _repStatusLength = repStatusLength;
}
}
RvDir d = b as RvDir;
if (d != null)
ReportMissingFindSizes(d, dat, rt);
}
}
private static void ReportDrawBars()
{
_ts.WriteLine("+" + new string('-', _fileNameLength + 2) + "+" + new string('-', _fileSizeLength + 2) + "+----------+" + new string('-', _repStatusLength + 2) + "+");
}
private static void ReportMissing(RvDir dir, RvDat dat, ReportType rt)
{
for (int i = 0; i < dir.ChildCount; i++)
{
RvBase b = dir.Child(i);
if (b.Dat != null && b.Dat != dat)
continue;
RvFile f = b as RvFile;
if (f != null)
{
if (
(rt == ReportType.PartialMissing && Partial.Contains(f.RepStatus)) ||
(rt == ReportType.Fixing && Fixing.Contains(f.RepStatus))
)
{
string filename = f.FileNameInsideGame();
string crc = ArrByte.ToString(f.CRC);
_ts.WriteLine("| " + filename + new string(' ', _fileNameLength + 1 - filename.Length) + "| "
+ f.Size + new string(' ', _fileSizeLength + 1 - f.Size.ToString().Length) + "| "
+ crc + new string(' ', 9 - crc.Length) + "| "
+ f.RepStatus + new string(' ', _repStatusLength + 1 - f.RepStatus.ToString().Length) + "|");
}
}
RvDir d = b as RvDir;
if (d != null)
ReportMissing(d, dat, rt);
}
}
}
}

228
ROMVault2/ReportError.cs Normal file
View File

@@ -0,0 +1,228 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.ServiceModel;
using System.Windows.Forms;
using ROMVault2.RVRef;
using ROMVault2.RvDB;
using ROMVault2.Utils;
namespace ROMVault2
{
public static class ReportError
{
public static void UnhandledExceptionHandler(object sender, System.Threading.ThreadExceptionEventArgs e)
{
try
{
// Create Error Message
string message = string.Format("An Application Error has occurred.\r\n\r\nEXCEPTION:\r\nSource: {0}\r\nMessage: {1}\r\n", e.Exception.Source, e.Exception.Message);
if (e.Exception.InnerException != null)
{
message += string.Format("\r\nINNER EXCEPTION:\r\nSource: {0}\r\nMessage: {1}\r\n", e.Exception.InnerException.Source, e.Exception.InnerException.Message);
}
message += string.Format("\r\nSTACK TRACE:\r\n{0}", e.Exception.StackTrace);
SendErrorMessage(message);
frmShowError fshow = new frmShowError();
fshow.settype(message);
fshow.ShowDialog();
Environment.Exit(0);
}
catch
{
Environment.Exit(0);
}
}
public static void UnhandledExceptionHandler(Exception e)
{
try
{
// Create Error Message
string message = string.Format("An Application Error has occurred.\r\n\r\nEXCEPTION:\r\nSource: {0}\r\nMessage: {1}\r\n", e.Source, e.Message);
if (e.InnerException != null)
{
message += string.Format("\r\nINNER EXCEPTION:\r\nSource: {0}\r\nMessage: {1}\r\n", e.InnerException.Source, e.InnerException.Message);
}
message += string.Format("\r\nSTACK TRACE:\r\n{0}", e.StackTrace);
SendErrorMessage(message);
frmShowError fshow = new frmShowError();
fshow.settype(message);
fshow.ShowDialog();
}
catch
{
}
}
public static void UnhandledExceptionHandler(string e1)
{
try
{
// Create Error Message
string message = string.Format("An Application Error has occurred.\r\n\r\nEXCEPTION:\r\nMessage:");
message += e1 + "\r\n";
message += string.Format("\r\nSTACK TRACE:\r\n{0}", Environment.StackTrace);
SendErrorMessage(message);
frmShowError fshow = new frmShowError();
fshow.settype(message);
fshow.ShowDialog();
Environment.Exit(0);
}
catch
{
Environment.Exit(0);
}
}
//public static void SendAndShowDat(string message, string filename)
//{
// SendErrorMessageDat(message, filename);
// Show(message, "RomVault - Dat Reading Error");
//}
public static void SendAndShow(string message, string caption = "RomVault", MessageBoxButtons buttons = MessageBoxButtons.OK, MessageBoxIcon icon = MessageBoxIcon.Exclamation)
{
SendErrorMessage(message);
Show(message, caption, buttons, icon);
}
public static void Show(string text, string caption = "RomVault", MessageBoxButtons buttons = MessageBoxButtons.OK, MessageBoxIcon icon = MessageBoxIcon.Exclamation)
{
if (Program.SyncCont != null)
Program.SyncCont.Send(callback => MessageBox.Show(text, caption, buttons, icon), null);
else
MessageBox.Show(text, caption, buttons, icon);
}
public static void SendErrorMessage(string message)
{
bool isNetworkAvailable = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();
if (!isNetworkAvailable) return;
string st = Environment.StackTrace;
BasicHttpBinding b = new BasicHttpBinding { SendTimeout = new TimeSpan(0, 0, 5), ReceiveTimeout = new TimeSpan(0, 0, 5) };
EndpointAddress e = new EndpointAddress(@"http://services.romvault.com/Service1.svc");
Service1Client s = new Service1Client(b, e);
try
{
s.SendErrorMessage3(Settings.Username, Settings.EMail, Program.Version, Program.SubVersion, message + "\n" + st);
}
catch
{
}
s.Close();
}
public static void SendErrorMessageDat(string message, string filename)
{
bool isNetworkAvailable = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();
if (!isNetworkAvailable) return;
BasicHttpBinding b = new BasicHttpBinding { SendTimeout = new TimeSpan(0, 0, 5), ReceiveTimeout = new TimeSpan(0, 0, 5) };
EndpointAddress e = new EndpointAddress(@"http://services.romvault.com/Service1.svc");
Service1Client s = new Service1Client(b, e);
try
{
s.SendDATErrorMessage3(Settings.Username, Settings.EMail, Program.Version, Program.SubVersion, message, filename);
}
catch
{
}
s.Close();
}
private static string _logfilename;
public static void ReportList(List<RvFile> files)
{
if (!Settings.DebugLogsEnabled) return;
string dir, now;
OpenLogFile(out dir, out now);
dir = Path.Combine(dir, now + " DataBaseLog.txt");
TextWriter sw = new StreamWriter(dir, false);
for (int i = 0; i < files.Count; i++)
{
RvFile f = files[i];
f.ReportIndex = i;
ReportFile(sw, f);
}
sw.Flush();
sw.Close();
}
private static void OpenLogFile(out string dir, out string now)
{
dir = Path.Combine(Application.StartupPath, "Logs");
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
now = DateTime.Now.ToString(CultureInfo.InvariantCulture);
now = now.Replace("\\", "-");
now = now.Replace("/", "-");
now = now.Replace(":", "-");
_logfilename = Path.Combine(dir, now + " UpdateLog.txt");
}
private static void ReportFile(TextWriter sw, RvFile f)
{
sw.WriteLine(f.ReportIndex.ToString("D8") + " " + ArrByte.ToString(f.CRC) + " " + f.GotStatus.ToString().PadRight(10) + " " + f.RepStatus.ToString().PadRight(15) + " " + f.TreeFullName);
}
public static void LogOut(string s)
{
if (!Settings.DebugLogsEnabled) return;
if (_logfilename == null)
{
string dir, now;
OpenLogFile(out dir, out now);
}
StreamWriter sw = new StreamWriter(_logfilename, true);
sw.WriteLine(s);
sw.Flush();
sw.Close();
}
public static void LogOut(RvFile f)
{
if (!Settings.DebugLogsEnabled) return;
StreamWriter sw = new StreamWriter(_logfilename, true);
ReportFile(sw, f);
sw.Flush();
sw.Close();
}
}
}

138
ROMVault2/RvDB/DB.cs Normal file
View File

@@ -0,0 +1,138 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System.ComponentModel;
using System.IO;
using System.Threading;
using ROMVault2.Properties;
namespace ROMVault2.RvDB
{
public static class DBVersion
{
public static int VersionNow;
public const int Version = 7;
}
public static class DB
{
private const ulong EndCacheMarker = 0x15a600dda7;
public static BackgroundWorker Bgw;
public static RvDir DirTree;
private static void OpenDefaultDB()
{
DirTree = new RvDir(FileType.Dir)
{
Tree = new RvTreeRow(),
DatStatus = DatStatus.InDatCollect
};
RvDir rv = new RvDir(FileType.Dir)
{
Name = "RomVault",
Tree = new RvTreeRow(),
DatStatus = DatStatus.InDatCollect
};
DirTree.ChildAdd(rv);
RvDir ts = new RvDir(FileType.Dir)
{
Name = "ToSort",
Tree = new RvTreeRow(),
DatStatus = DatStatus.InDatCollect
};
DirTree.ChildAdd(ts);
}
public static void Write()
{
if (File.Exists(Settings.CacheFile))
{
string bname = Settings.CacheFile + "Backup";
if (File.Exists(bname))
File.Delete(bname);
File.Move(Settings.CacheFile, bname);
}
FileStream fs = new FileStream(Settings.CacheFile, FileMode.CreateNew, FileAccess.Write);
BinaryWriter bw = new BinaryWriter(fs);
DBVersion.VersionNow = DBVersion.Version;
bw.Write(DBVersion.Version);
DirTree.Write(bw);
bw.Write(EndCacheMarker);
bw.Flush();
bw.Close();
fs.Close();
fs.Dispose();
}
public static void Read(object sender, DoWorkEventArgs e)
{
Bgw = sender as BackgroundWorker;
Program.SyncCont = e.Argument as SynchronizationContext;
if (!File.Exists(Settings.CacheFile))
{
OpenDefaultDB();
Bgw = null;
Program.SyncCont = null;
return;
}
DirTree = new RvDir(FileType.Dir);
FileStream fs = new FileStream(Settings.CacheFile, FileMode.Open, FileAccess.Read);
if (fs.Length < 4)
ReportError.UnhandledExceptionHandler("Cache is Corrupt, revert to Backup.");
BinaryReader br = new BinaryReader(fs);
if (Bgw != null)
Bgw.ReportProgress(0, new bgwSetRange((int)fs.Length));
DBVersion.VersionNow = br.ReadInt32();
if (DBVersion.VersionNow != DBVersion.Version)
{
ReportError.Show(Resources.DB_Read_Data_Cache_version_is_out_of_date_you_should_now_rescan_your_dat_directory_and_roms_directory_);
OpenDefaultDB();
}
else
{
DirTree.Read(br, null);
}
if (fs.Position > fs.Length - 8)
ReportError.UnhandledExceptionHandler("Cache is Corrupt, revert to Backup.");
ulong testEOF = br.ReadUInt64();
if (testEOF != EndCacheMarker)
ReportError.UnhandledExceptionHandler("Cache is Corrupt, revert to Backup.");
br.Close();
fs.Close();
fs.Dispose();
Bgw = null;
Program.SyncCont = null;
}
public static string Fn(string v)
{
return v ?? "";
}
}
}

View File

@@ -0,0 +1,35 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
namespace ROMVault2.RvDB
{
[Flags]
public enum FileStatus
{
SizeFromDAT = 0x00000001,
CRCFromDAT = 0x00000002,
SHA1FromDAT = 0x00000004,
MD5FromDAT = 0x00000008,
SHA1CHDFromDAT = 0x00000010,
MD5CHDFromDAT = 0x00000020,
SizeFromHeader = 0x00000100,
CRCFromHeader = 0x00000200,
SHA1FromHeader = 0x00000400,
MD5FromHeader = 0x00000800,
SHA1CHDFromHeader = 0x00001000,
MD5CHDFromHeader = 0x00002000,
SizeVerified = 0x00010000,
CRCVerified = 0x00020000,
SHA1Verified = 0x00040000,
MD5Verified = 0x00080000,
SHA1CHDVerified = 0x00100000,
MD5CHDVerified = 0x00200000
}
}

308
ROMVault2/RvDB/RvBase.cs Normal file
View File

@@ -0,0 +1,308 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Collections.Generic;
using System.IO;
using ROMVault2.Properties;
namespace ROMVault2.RvDB
{
public enum DatStatus { InDatCollect, InDatMerged, InDatBad, NotInDat, InToSort }
public enum GotStatus { NotGot, Got, Corrupt, FileLocked }
public enum FileType { Unknown, Dir, Zip, xSevenZip, xRAR, File, ZipFile, xSevenZipFile }
public abstract class RvBase
{
private readonly FileType _type;
public string Name; // The Name of the File or Directory
public string FileName; // Found filename if different from Name
public RvDir Parent; // A link to the Parent Directory
public RvDat Dat;
public long TimeStamp;
public int ReportIndex;
public bool SearchFound;
private DatStatus _datStatus = DatStatus.NotInDat;
private GotStatus _gotStatus = GotStatus.NotGot;
private RepStatus _repStatus = RepStatus.UnSet;
protected RvBase(FileType type)
{
_type = type;
}
public FileType FileType
{
get { return _type; }
}
public virtual void Write(BinaryWriter bw)
{
bw.Write(DB.Fn(Name));
bw.Write(DB.Fn(FileName));
bw.Write(TimeStamp);
if (Dat == null)
{
bw.Write(false);
}
else
{
//Debug.WriteLine("Dat is not null");
bw.Write(true);
//Debug.WriteLine("Dat index is "+ Dat.DatIndex);
bw.Write(Dat.DatIndex);
}
bw.Write((byte)_datStatus);
bw.Write((byte)_gotStatus);
}
public virtual void Read(BinaryReader br, List<RvDat> parentDirDats)
{
Name = br.ReadString();
FileName = br.ReadString();
TimeStamp = br.ReadInt64();
bool foundDat = br.ReadBoolean();
if (foundDat)
{
int index = br.ReadInt32();
if (index == -1)
ReportError.SendAndShow(Resources.RvBase_Read_Dat_found_without_an_index);
else
Dat = parentDirDats[index];
}
else
{
Dat = null;
}
_datStatus = (DatStatus)br.ReadByte();
_gotStatus = (GotStatus)br.ReadByte();
RepStatusReset();
}
public virtual EFile DatRemove()
{
Dat = null;
if (GotStatus == GotStatus.NotGot)
return EFile.Delete;
if (!String.IsNullOrEmpty(FileName))
{
Name = FileName;
FileName = null;
}
DatStatus = DatStatus.NotInDat;
return EFile.Keep;
}
public virtual void DatAdd(RvBase b)
{
// Parent , TimeStamp Should already be correct.
if (GotStatus == GotStatus.NotGot)
ReportError.SendAndShow("Error Adding DAT to NotGot File " + b.GotStatus);
SetStatus(b.DatStatus, GotStatus.Got);
if (Name == b.Name) // case match so all is good
{
FileName = null;
}
else
{
FileName = Name;
Name = b.Name;
}
Dat = b.Dat;
}
public virtual EFile FileRemove()
{
TimeStamp = 0;
FileName = null;
GotStatus = (Parent.GotStatus == GotStatus.FileLocked) ? GotStatus.FileLocked : GotStatus.NotGot;
switch (DatStatus)
{
case DatStatus.InDatCollect:
case DatStatus.InDatMerged:
case DatStatus.InDatBad:
return EFile.Keep;
case DatStatus.NotInDat:
case DatStatus.InToSort:
return EFile.Delete; // this item should be removed from the db.
default:
ReportError.SendAndShow(Resources.RvBase_SetGot_Unknown_Set_Got_Status + DatStatus);
return EFile.Keep;
}
}
public virtual void FileAdd(RvBase file)
{
TimeStamp = file.TimeStamp;
FileCheckName(file);
if (file.GotStatus == GotStatus.NotGot)
ReportError.SendAndShow("Error setting got to a NotGot File");
GotStatus = file.GotStatus;
}
public void FileCheckName(RvBase file)
{
// Don't care about bad case if the file is not in a dat.
if (DatStatus == DatStatus.NotInDat || DatStatus == DatStatus.InToSort)
Name = file.Name;
FileName = Name == file.Name ? null : file.Name;
}
public virtual void CopyTo(RvBase c)
{
c.Name = Name;
c.FileName = FileName;
//c.Parent = Parent;
c.Dat = Dat;
c.TimeStamp = TimeStamp;
c.ReportIndex = ReportIndex;
c._datStatus = _datStatus;
c._gotStatus = _gotStatus;
c.RepStatus = RepStatus;
}
private string Extention
{
get
{
switch (FileType)
{
case FileType.Zip: return ".zip";
//case FileType.SevenZip: return ".7z";
//case FileType.RAR: return ".rar";
}
return "";
}
}
public string FullName
{
get { return DBHelper.GetRealPath(TreeFullName); }
}
public string DatFullName
{
get { return DBHelper.GetDatPath(TreeFullName); }
}
public string TreeFullName
{
get
{
if (Parent == null) return Name + Extention;
return IO.Path.Combine(Parent.TreeFullName, Name + Extention);
}
}
public bool IsInToSort
{
get
{
string fullName = TreeFullName;
return fullName.Substring(0, 6) == "ToSort";
}
}
public string SuperDatFileName()
{
return SuperDatFileName(Dat);
}
private string SuperDatFileName(RvDat dat)
{
if (dat.AutoAddDirectory)
{
if (Parent == null || Parent.Parent == null || Parent.Parent.Dat != dat) return Name;
}
else
{
if (Parent == null || Parent.Dat != dat) return Name;
}
return IO.Path.Combine(Parent.SuperDatFileName(dat), Name);
}
public string FileNameInsideGame()
{
RvDir d = this as RvDir;
if (d != null && d.Game != null) return Name;
return IO.Path.Combine(Parent.FileNameInsideGame(), Name);
}
public DatStatus DatStatus
{
set
{
_datStatus = value;
RepStatusReset();
}
get { return _datStatus; }
}
public GotStatus GotStatus
{
get { return _gotStatus; }
set
{
_gotStatus = value;
RepStatusReset();
}
}
public void SetStatus(DatStatus dt, GotStatus flag)
{
_datStatus = dt;
_gotStatus = flag;
RepStatusReset();
}
public RepStatus RepStatus
{
get { return _repStatus; }
set
{
if (Parent != null) Parent.UpdateRepStatusUpTree(_repStatus, -1);
List<RepStatus> rs = RepairStatus.StatusCheck[(int)FileType, (int)_datStatus, (int)_gotStatus];
if (rs == null || !rs.Contains(value))
{
ReportError.SendAndShow(FullName + " " + Resources.RvBase_Check + FileType + Resources.RvBase_Check + _datStatus + Resources.RvBase_Check + _gotStatus + " from: " + _repStatus + " to: " + value);
_repStatus = RepStatus.Error;
}
else
_repStatus = value;
if (Parent != null) Parent.UpdateRepStatusUpTree(_repStatus, 1);
}
}
public void RepStatusReset()
{
SearchFound = false;
if ((RepStatus == RepStatus.UnSet || RepStatus == RepStatus.Unknown || RepStatus == RepStatus.Ignore) && FileType == FileType.File && GotStatus == GotStatus.Got && DatStatus==DatStatus.NotInDat)
foreach (string file in Settings.IgnoreFiles)
if (Name == file)
{
RepStatus = RepStatus.Ignore;
return;
}
List<RepStatus> rs = RepairStatus.StatusCheck[(int)FileType, (int)_datStatus, (int)_gotStatus];
RepStatus = rs == null ? RepStatus.Error : rs[0];
}
}
}

118
ROMVault2/RvDB/RvDat.cs Normal file
View File

@@ -0,0 +1,118 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Collections.Generic;
using System.IO;
namespace ROMVault2.RvDB
{
public enum DatUpdateStatus
{
Delete,
Correct
}
public class RvDat
{
public int DatIndex = -1;
public DatUpdateStatus Status;
public long TimeStamp;
public bool AutoAddDirectory;
public enum DatData
{
DatName = 1,
DatFullName = 2,
RootDir = 3,
Description = 4,
Category = 5,
Version = 6,
Date = 7,
Author = 8,
Email = 9,
HomePage = 10,
URL = 11,
FileType = 12,
MergeType = 13,
SuperDat = 14,
DirSetup = 15
}
private class GameMetaData
{
public DatData Id { get; private set; }
public String Value { get; private set; }
public GameMetaData(DatData id, String value)
{
Id = id;
Value = value;
}
public GameMetaData(BinaryReader br)
{
Id = (DatData)br.ReadByte();
Value = br.ReadString();
}
public void Write(BinaryWriter bw)
{
bw.Write((byte)Id);
bw.Write(DB.Fn(Value));
}
}
private readonly List<GameMetaData> _gameMetaData = new List<GameMetaData>();
public void Write(BinaryWriter bw)
{
bw.Write(TimeStamp);
bw.Write(AutoAddDirectory);
bw.Write((byte)_gameMetaData.Count);
foreach (GameMetaData gameMD in _gameMetaData)
gameMD.Write(bw);
}
public void Read(BinaryReader br)
{
TimeStamp = br.ReadInt64();
AutoAddDirectory = br.ReadBoolean();
byte c = br.ReadByte();
_gameMetaData.Clear();
_gameMetaData.Capacity = c;
for (byte i = 0; i < c; i++)
_gameMetaData.Add(new GameMetaData(br));
}
public void AddData(DatData id, string val)
{
if (string.IsNullOrEmpty(val))
return;
int pos = 0;
while (pos < _gameMetaData.Count && _gameMetaData[pos].Id < id)
pos++;
_gameMetaData.Insert(pos, new GameMetaData(id, val));
}
public string GetData(DatData id)
{
foreach (GameMetaData gameMD in _gameMetaData)
{
if (id == gameMD.Id) return gameMD.Value;
if (id < gameMD.Id) return "";
}
return "";
}
}
}

345
ROMVault2/RvDB/RvDir.cs Normal file
View File

@@ -0,0 +1,345 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System.Collections.Generic;
using System.IO;
using ROMVault2.Properties;
using ROMVault2.SupportedFiles;
using ROMVault2.Utils;
namespace ROMVault2.RvDB
{
public class RvDir : RvBase
{
public RvTreeRow Tree;
public RvGame Game;
private readonly List<RvDat> _dirDats = new List<RvDat>();
private readonly List<RvBase> _children = new List<RvBase>();
public readonly ReportStatus DirStatus = new ReportStatus();
public ZipStatus ZipStatus;
public RvDir(FileType type)
: base(type)
{
if (type != FileType.Dir && type != FileType.Zip)
ReportError.SendAndShow("Trying to set Dir type to " + type);
}
public override void Write(BinaryWriter bw)
{
base.Write(bw);
if (Tree == null)
bw.Write(false);
else
{
bw.Write(true);
Tree.Write(bw);
}
if (Game == null)
bw.Write(false);
else
{
bw.Write(true);
Game.Write(bw);
}
int count = _dirDats.Count;
bw.Write(count);
for (int i = 0; i < count; i++)
{
_dirDats[i].Write(bw);
}
count = _children.Count;
bw.Write(count);
for (int i = 0; i < count; i++)
{
FileType type = _children[i].FileType;
bw.Write((byte)type);
_children[i].Write(bw);
}
if (DBTypeGet.isCompressedDir(FileType))
bw.Write((byte)ZipStatus);
}
public override void Read(BinaryReader br, List<RvDat> parentDirDats)
{
base.Read(br, parentDirDats);
bool foundTree = br.ReadBoolean();
if (foundTree)
{
Tree = new RvTreeRow();
Tree.Read(br);
}
else
Tree = null;
bool foundGame = br.ReadBoolean();
if (foundGame)
{
Game = new RvGame();
Game.Read(br);
}
else
Game = null;
int count = br.ReadInt32();
_dirDats.Clear();
for (int i = 0; i < count; i++)
{
RvDat dat = new RvDat { DatIndex = i };
dat.Read(br);
_dirDats.Add(dat);
string datname = TreeFullName + @"\" + dat.GetData(RvDat.DatData.DatName);
if (datname.Length >= 9 && datname.Substring(0, 9) == @"RomVault\")
datname = datname.Substring(9);
DB.Bgw.ReportProgress(0, new bgwText("Loading: " + datname));
DB.Bgw.ReportProgress((int)br.BaseStream.Position);
}
if (_dirDats.Count > 0)
parentDirDats = _dirDats;
count = br.ReadInt32();
_children.Clear();
for (int i = 0; i < count; i++)
{
RvBase tChild = DBTypeGet.GetRvType((FileType)br.ReadByte());
tChild.Parent = this;
tChild.Read(br, parentDirDats);
_children.Add(tChild);
}
if (DBTypeGet.isCompressedDir(FileType))
ZipStatus = (ZipStatus)br.ReadByte();
}
public override EFile DatRemove()
{
Tree = null;
Game = null;
_dirDats.Clear();
return base.DatRemove();
}
public override void DatAdd(RvBase b)
{
Tree = ((RvDir)b).Tree;
Game = ((RvDir)b).Game;
if (_dirDats.Count > 0)
ReportError.SendAndShow(Resources.RvDir_SetDat_Setting_Dir_with_a_dat_list);
base.DatAdd(b);
}
public override EFile FileRemove()
{
ZipStatus = ZipStatus.None;
return base.FileRemove();
}
public int DirDatCount
{
get
{
return _dirDats.Count;
}
}
public RvDat DirDat(int index)
{
return _dirDats[index];
}
public void DirDatAdd(RvDat dat)
{
int index;
DirDatSearch(dat, out index);
_dirDats.Insert(index, dat);
for (int i = 0; i < _dirDats.Count; i++)
_dirDats[i].DatIndex = i;
}
public void DirDatRemove(int index)
{
_dirDats.RemoveAt(index);
for (int i = 0; i < _dirDats.Count; i++)
_dirDats[i].DatIndex = i;
}
private void DirDatSearch(RvDat dat, out int index)
{
int intBottom = 0;
int intTop = _dirDats.Count;
int intMid = 0;
int intRes = -1;
//Binary chop to find the closest match
while (intBottom < intTop && intRes != 0)
{
intMid = (intBottom + intTop) / 2;
intRes = DBHelper.DatCompare(dat, _dirDats[intMid]);
if (intRes < 0)
intTop = intMid;
else if (intRes > 0)
intBottom = intMid + 1;
}
index = intMid;
// if match was found check up the list for the first match
if (intRes == 0)
{
int intRes1 = 0;
while (index > 0 && intRes1 == 0)
{
intRes1 = DBHelper.DatCompare(dat, _dirDats[index - 1]);
if (intRes1 == 0)
index--;
}
}
// if the search is greater than the closest match move one up the list
else if (intRes > 0)
index++;
}
public int ChildCount
{
get
{
return _children.Count;
}
}
public RvBase Child(int index)
{
return _children[index];
}
public int ChildAdd(RvBase child)
{
int index;
ChildNameSearch(child, out index);
ChildAdd(child, index);
return index;
}
public void ChildAdd(RvBase child, int index)
{
if (
(FileType == FileType.Dir && child.FileType == FileType.ZipFile) ||
(FileType == FileType.Zip && child.FileType != FileType.ZipFile)
)
ReportError.SendAndShow("Typing to add a " + child.FileType + " to a " + FileType);
_children.Insert(index, child);
child.Parent = this;
UpdateRepStatusArrUpTree(child, 1);
}
public void ChildRemove(int index)
{
UpdateRepStatusArrUpTree(_children[index], -1);
if (_children[index].Parent == this)
_children[index].Parent = null;
_children.RemoveAt(index);
}
public int ChildNameSearch(RvBase lName, out int index)
{
int intBottom = 0;
int intTop = _children.Count;
int intMid = 0;
int intRes = -1;
//Binary chop to find the closest match
while (intBottom < intTop && intRes != 0)
{
intMid = (intBottom + intTop) / 2;
intRes = DBHelper.CompareName(lName, _children[intMid]);
if (intRes < 0)
intTop = intMid;
else if (intRes > 0)
intBottom = intMid + 1;
}
index = intMid;
// if match was found check up the list for the first match
if (intRes == 0)
{
int intRes1 = 0;
while (index > 0 && intRes1 == 0)
{
intRes1 = DBHelper.CompareName(lName, _children[index - 1]);
if (intRes1 == 0)
index--;
}
}
// if the search is greater than the closest match move one up the list
else if (intRes > 0)
index++;
return intRes;
}
public bool FindChild(RvBase lName, out int index)
{
if (ChildNameSearch(lName, out index) != 0)
{
ReportError.UnhandledExceptionHandler("Could not find self in Parent " + FullName);
return false;
}
do
{
if (_children[index] == lName)
return true;
index++;
} while (index < _children.Count && DBHelper.CompareName(lName, _children[index]) == 0);
return false;
}
public void UpdateRepStatusUpTree(RepStatus rStat, int dir)
{
DirStatus.UpdateRepStatus(rStat, dir);
if (Parent != null)
Parent.UpdateRepStatusUpTree(rStat, dir);
}
private void UpdateRepStatusArrUpTree(RvBase child, int dir)
{
DirStatus.UpdateRepStatus(child.RepStatus, dir);
RvDir rvDir = child as RvDir;
if (rvDir != null)
DirStatus.UpdateRepStatus(rvDir.DirStatus, dir);
if (Parent != null)
Parent.UpdateRepStatusArrUpTree(child, dir);
}
}
}

251
ROMVault2/RvDB/RvFile.cs Normal file
View File

@@ -0,0 +1,251 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Collections.Generic;
using System.IO;
using ROMVault2.Utils;
namespace ROMVault2.RvDB
{
public class RvFile : RvBase
{
public ulong? Size;
public byte[] CRC;
public byte[] SHA1;
public byte[] MD5;
public byte[] SHA1CHD;
public byte[] MD5CHD;
public string Merge = "";
public string Status;
private FileStatus _fileStatus;
public int ZipFileIndex = -1;
public ulong? ZipFileHeaderPosition;
public uint? CHDVersion;
public RvFile(FileType type)
: base(type)
{
if (type != FileType.File && type != FileType.ZipFile)
ReportError.SendAndShow("Trying to set file type to " + type);
}
[Flags]
private enum FileFlags
{
Size = 0x01,
CRC = 0x02,
SHA1 = 0x04,
MD5 = 0x08,
SHA1CHD = 0x10,
MD5CHD = 0x20,
Merge = 0x40,
Status = 0x80,
ZipFileIndex = 0x100,
ZipFileHeader = 0x200,
CHDVersion = 0x400
}
public override void Write(BinaryWriter bw)
{
base.Write(bw);
FileFlags fFlags = 0;
if (Size != null) fFlags |= FileFlags.Size;
if (CRC != null) fFlags |= FileFlags.CRC;
if (SHA1 != null) fFlags |= FileFlags.SHA1;
if (MD5 != null) fFlags |= FileFlags.MD5;
if (SHA1CHD != null) fFlags |= FileFlags.SHA1CHD;
if (MD5CHD != null) fFlags |= FileFlags.MD5CHD;
if (!String.IsNullOrEmpty(Merge)) fFlags |= FileFlags.Merge;
if (!String.IsNullOrEmpty(Status)) fFlags |= FileFlags.Status;
if (ZipFileIndex >= 0) fFlags |= FileFlags.ZipFileIndex;
if (ZipFileHeaderPosition != null) fFlags |= FileFlags.ZipFileHeader;
if (CHDVersion != null) fFlags |= FileFlags.CHDVersion;
bw.Write((UInt16)fFlags);
if (Size != null) bw.Write((ulong)Size);
if (CRC != null) ArrByte.Write(bw, CRC);
if (SHA1 != null) ArrByte.Write(bw, SHA1);
if (MD5 != null) ArrByte.Write(bw, MD5);
if (SHA1CHD != null) ArrByte.Write(bw, SHA1CHD);
if (MD5CHD != null) ArrByte.Write(bw, MD5CHD);
if (!String.IsNullOrEmpty(Merge)) bw.Write(Merge);
if (!String.IsNullOrEmpty(Status)) bw.Write(Status);
if (ZipFileIndex >= 0) bw.Write(ZipFileIndex);
if (ZipFileHeaderPosition != null) bw.Write((long)ZipFileHeaderPosition);
if (CHDVersion != null) bw.Write((uint)CHDVersion);
bw.Write((uint)_fileStatus);
}
public override void Read(BinaryReader br, List<RvDat> parentDirDats)
{
base.Read(br, parentDirDats);
FileFlags fFlags = (FileFlags)br.ReadUInt16();
Size = (fFlags & FileFlags.Size) > 0 ? (ulong?)br.ReadUInt64() : null;
CRC = (fFlags & FileFlags.CRC) > 0 ? ArrByte.Read(br) : null;
SHA1 = (fFlags & FileFlags.SHA1) > 0 ? ArrByte.Read(br) : null;
MD5 = (fFlags & FileFlags.MD5) > 0 ? ArrByte.Read(br) : null;
SHA1CHD = (fFlags & FileFlags.SHA1CHD) > 0 ? ArrByte.Read(br) : null;
MD5CHD = (fFlags & FileFlags.MD5CHD) > 0 ? ArrByte.Read(br) : null;
Merge = (fFlags & FileFlags.Merge) > 0 ? br.ReadString() : null;
Status = (fFlags & FileFlags.Status) > 0 ? br.ReadString() : null;
ZipFileIndex = (fFlags & FileFlags.ZipFileIndex) > 0 ? br.ReadInt32() : -1;
ZipFileHeaderPosition = (fFlags & FileFlags.ZipFileHeader) > 0 ? (ulong?)br.ReadUInt64() : null;
CHDVersion = (fFlags & FileFlags.CHDVersion) > 0 ? (uint?)br.ReadInt32() : null;
_fileStatus = (FileStatus)br.ReadUInt32();
}
public override EFile DatRemove()
{
if (!FileStatusIs(FileStatus.SizeFromHeader) && !FileStatusIs(FileStatus.SizeVerified)) Size = null;
if (!FileStatusIs(FileStatus.CRCFromHeader) && !FileStatusIs(FileStatus.CRCVerified)) CRC = null;
if (!FileStatusIs(FileStatus.SHA1FromHeader) && !FileStatusIs(FileStatus.SHA1Verified)) SHA1 = null;
if (!FileStatusIs(FileStatus.MD5FromHeader) && !FileStatusIs(FileStatus.MD5Verified)) MD5 = null;
if (!FileStatusIs(FileStatus.SHA1CHDFromHeader) && !FileStatusIs(FileStatus.SHA1CHDVerified)) SHA1CHD = null;
if (!FileStatusIs(FileStatus.MD5CHDFromHeader) && !FileStatusIs(FileStatus.MD5CHDVerified)) MD5CHD = null;
FileStatusClear(FileStatus.SizeFromDAT | FileStatus.CRCFromDAT | FileStatus.SHA1FromDAT | FileStatus.MD5FromDAT | FileStatus.SHA1CHDFromDAT | FileStatus.MD5CHDFromDAT);
Merge = "";
Status = "";
return base.DatRemove();
}
public override void DatAdd(RvBase file)
{
RvFile tFile = file as RvFile;
if (tFile == null)
{
ReportError.SendAndShow("Error setting Dat Set Got");
return;
}
if (Size == null && tFile.Size != null) Size = tFile.Size;
if (CRC == null && tFile.CRC != null) CRC = tFile.CRC;
if (SHA1 == null && tFile.SHA1 != null) SHA1 = tFile.SHA1;
if (MD5 == null && tFile.MD5 != null) MD5 = tFile.MD5;
if (SHA1CHD == null && tFile.SHA1CHD != null) SHA1CHD = tFile.SHA1CHD;
if (MD5CHD == null && tFile.MD5CHD != null) MD5CHD = tFile.MD5CHD;
FileStatusSet(
FileStatus.SizeFromDAT | FileStatus.CRCFromDAT | FileStatus.SHA1FromDAT | FileStatus.MD5FromDAT | FileStatus.SHA1CHDFromDAT | FileStatus.MD5CHDFromDAT,
tFile);
Merge = tFile.Merge;
Status = tFile.Status;
base.DatAdd(file);
}
public override EFile FileRemove()
{
ZipFileIndex = -1;
ZipFileHeaderPosition = null;
if (base.FileRemove() == EFile.Delete)
return EFile.Delete;
if (!FileStatusIs(FileStatus.SizeFromDAT)) Size = null;
if (!FileStatusIs(FileStatus.CRCFromDAT)) CRC = null;
if (!FileStatusIs(FileStatus.SHA1FromDAT)) SHA1 = null;
if (!FileStatusIs(FileStatus.MD5FromDAT)) MD5 = null;
if (!FileStatusIs(FileStatus.SHA1CHDFromDAT)) SHA1CHD = null;
if (!FileStatusIs(FileStatus.MD5CHDFromDAT)) MD5CHD = null;
CHDVersion = null;
FileStatusClear(
FileStatus.SizeFromHeader | FileStatus.CRCFromHeader | FileStatus.SHA1FromHeader | FileStatus.MD5FromHeader | FileStatus.SHA1CHDFromHeader | FileStatus.MD5CHDFromHeader |
FileStatus.SizeVerified | FileStatus.CRCVerified | FileStatus.SHA1Verified | FileStatus.MD5Verified | FileStatus.SHA1CHDVerified | FileStatus.MD5CHDVerified);
return EFile.Keep;
}
public override void FileAdd(RvBase file)
{
RvFile tFile = file as RvFile;
if (tFile == null)
{
ReportError.SendAndShow("Error setting File Got");
return;
}
if (Size == null && tFile.Size != null) Size = tFile.Size;
if (CRC == null && tFile.CRC != null) CRC = tFile.CRC;
if (SHA1 == null && tFile.SHA1 != null) SHA1 = tFile.SHA1;
if (MD5 == null && tFile.MD5 != null) MD5 = tFile.MD5;
if (SHA1CHD == null && tFile.SHA1CHD != null) SHA1CHD = tFile.SHA1CHD;
if (MD5CHD == null && tFile.MD5CHD != null) MD5CHD = tFile.MD5CHD;
CHDVersion = tFile.CHDVersion;
FileStatusSet(
FileStatus.SizeFromHeader | FileStatus.CRCFromHeader | FileStatus.SHA1FromHeader | FileStatus.MD5FromHeader | FileStatus.SHA1CHDFromHeader | FileStatus.MD5CHDFromHeader |
FileStatus.SizeVerified | FileStatus.CRCVerified | FileStatus.SHA1Verified | FileStatus.MD5Verified | FileStatus.SHA1CHDVerified | FileStatus.MD5CHDVerified,
tFile);
ZipFileIndex = tFile.ZipFileIndex;
ZipFileHeaderPosition = tFile.ZipFileHeaderPosition;
base.FileAdd(file);
}
public override void CopyTo(RvBase c)
{
RvFile cf = c as RvFile;
if (cf != null)
{
cf.Size = Size;
cf.CRC = CRC;
cf.SHA1 = SHA1;
cf.MD5 = MD5;
cf.Merge = Merge;
cf.Status = Status;
cf._fileStatus = _fileStatus;
cf.SHA1CHD = SHA1CHD;
cf.MD5CHD = MD5CHD;
cf.ZipFileIndex = ZipFileIndex;
cf.ZipFileHeaderPosition = ZipFileHeaderPosition;
cf.CHDVersion = CHDVersion;
}
base.CopyTo(c);
}
public void FileStatusSet(FileStatus flag)
{
_fileStatus |= flag;
}
public void FileStatusSet(FileStatus flag, RvFile copyFrom)
{
_fileStatus |= (flag & copyFrom._fileStatus);
}
private void FileStatusClear(FileStatus flag)
{
_fileStatus &= ~flag;
}
public bool FileStatusIs(FileStatus flag)
{
return (_fileStatus & flag) == flag;
}
}
}

122
ROMVault2/RvDB/RvGame.cs Normal file
View File

@@ -0,0 +1,122 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Collections.Generic;
using System.IO;
namespace ROMVault2.RvDB
{
public class RvGame
{
public enum GameData
{
Description = 1,
RomOf = 2,
IsBios = 3,
Sourcefile = 4,
CloneOf = 5,
SampleOf = 6,
Board = 7,
Year = 8,
Manufacturer = 9,
Trurip = 10,
Publisher = 11,
Developer = 12,
Edition = 13,
Version = 14,
Type = 15,
Media = 16,
Language = 17,
Players = 18,
Ratings = 19,
Peripheral = 20,
Genre = 21,
MediaCatalogNumber=22,
BarCode=23
}
private class GameMetaData
{
public GameData Id { get; private set; }
public String Value { get; private set; }
public GameMetaData(GameData id, String value)
{
Id = id;
Value = value;
}
public GameMetaData(BinaryReader br)
{
Id = (GameData)br.ReadByte();
Value = br.ReadString();
}
public void Write(BinaryWriter bw)
{
bw.Write((byte)Id);
bw.Write(DB.Fn(Value));
}
}
private readonly List<GameMetaData> _gameMetaData = new List<GameMetaData>();
public void Write(BinaryWriter bw)
{
bw.Write((byte)_gameMetaData.Count);
foreach (GameMetaData gameMD in _gameMetaData)
gameMD.Write(bw);
}
public void Read(BinaryReader br)
{
byte c = br.ReadByte();
_gameMetaData.Clear();
_gameMetaData.Capacity = c;
for (byte i = 0; i < c; i++)
_gameMetaData.Add(new GameMetaData(br));
}
public void AddData(GameData id, string val)
{
if (string.IsNullOrEmpty(val))
return;
int pos = 0;
while (pos < _gameMetaData.Count && _gameMetaData[pos].Id < id)
pos++;
_gameMetaData.Insert(pos, new GameMetaData(id, val));
}
public string GetData(GameData id)
{
foreach (GameMetaData gameMD in _gameMetaData)
{
if (id == gameMD.Id) return gameMD.Value;
if (id < gameMD.Id) return "";
}
return "";
}
public void DeleteData(GameData id)
{
for (int i = 0; i < _gameMetaData.Count; i++)
{
if (id == _gameMetaData[i].Id)
{
_gameMetaData.RemoveAt(i);
return;
}
if (id < _gameMetaData[i].Id) return;
}
}
}
}

View File

@@ -0,0 +1,137 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.34003
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ROMVault2.RVRef {
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="RVRef.IService1")]
public interface IService1 {
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/CheckPassword", ReplyAction="http://tempuri.org/IService1/CheckPasswordResponse")]
string CheckPassword(string username, string password);
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/SendUser", ReplyAction="http://tempuri.org/IService1/SendUserResponse")]
string SendUser(string username, string email, int version);
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/SendUser1", ReplyAction="http://tempuri.org/IService1/SendUser1Response")]
string SendUser1(string username, string email, string version, int subversion);
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/GetLatestVersion", ReplyAction="http://tempuri.org/IService1/GetLatestVersionResponse")]
int GetLatestVersion(int versionNow);
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/GetLatestVersion1", ReplyAction="http://tempuri.org/IService1/GetLatestVersion1Response")]
string GetLatestVersion1(string version, int subversion);
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/GetUpdateLink", ReplyAction="http://tempuri.org/IService1/GetUpdateLinkResponse")]
string GetUpdateLink();
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/GetUpdateLink1", ReplyAction="http://tempuri.org/IService1/GetUpdateLink1Response")]
string GetUpdateLink1(string version, int subversion);
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/SendErrorMessage", ReplyAction="http://tempuri.org/IService1/SendErrorMessageResponse")]
void SendErrorMessage(string username, string error);
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/SendErrorMessage1", ReplyAction="http://tempuri.org/IService1/SendErrorMessage1Response")]
void SendErrorMessage1(string username, string email, string error);
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/SendErrorMessage2", ReplyAction="http://tempuri.org/IService1/SendErrorMessage2Response")]
void SendErrorMessage2(string username, string email, int version, string error);
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/SendErrorMessage3", ReplyAction="http://tempuri.org/IService1/SendErrorMessage3Response")]
void SendErrorMessage3(string username, string email, string version, int subversion, string error);
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/SendDATErrorMessage2", ReplyAction="http://tempuri.org/IService1/SendDATErrorMessage2Response")]
void SendDATErrorMessage2(string username, string email, int version, string error, string filename);
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/SendDATErrorMessage3", ReplyAction="http://tempuri.org/IService1/SendDATErrorMessage3Response")]
void SendDATErrorMessage3(string username, string email, string version, int subversion, string error, string filename);
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface IService1Channel : ROMVault2.RVRef.IService1, System.ServiceModel.IClientChannel {
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class Service1Client : System.ServiceModel.ClientBase<ROMVault2.RVRef.IService1>, ROMVault2.RVRef.IService1 {
public Service1Client() {
}
public Service1Client(string endpointConfigurationName) :
base(endpointConfigurationName) {
}
public Service1Client(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}
public Service1Client(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}
public Service1Client(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress) {
}
public string CheckPassword(string username, string password) {
return base.Channel.CheckPassword(username, password);
}
public string SendUser(string username, string email, int version) {
return base.Channel.SendUser(username, email, version);
}
public string SendUser1(string username, string email, string version, int subversion) {
return base.Channel.SendUser1(username, email, version, subversion);
}
public int GetLatestVersion(int versionNow) {
return base.Channel.GetLatestVersion(versionNow);
}
public string GetLatestVersion1(string version, int subversion) {
return base.Channel.GetLatestVersion1(version, subversion);
}
public string GetUpdateLink() {
return base.Channel.GetUpdateLink();
}
public string GetUpdateLink1(string version, int subversion) {
return base.Channel.GetUpdateLink1(version, subversion);
}
public void SendErrorMessage(string username, string error) {
base.Channel.SendErrorMessage(username, error);
}
public void SendErrorMessage1(string username, string email, string error) {
base.Channel.SendErrorMessage1(username, email, error);
}
public void SendErrorMessage2(string username, string email, int version, string error) {
base.Channel.SendErrorMessage2(username, email, version, error);
}
public void SendErrorMessage3(string username, string email, string version, int subversion, string error) {
base.Channel.SendErrorMessage3(username, email, version, subversion, error);
}
public void SendDATErrorMessage2(string username, string email, int version, string error, string filename) {
base.Channel.SendDATErrorMessage2(username, email, version, error, filename);
}
public void SendDATErrorMessage3(string username, string email, string version, int subversion, string error, string filename) {
base.Channel.SendDATErrorMessage3(username, email, version, subversion, error, filename);
}
}
}

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<ReferenceGroup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ID="bf99e9bc-8e26-46b0-b7b2-041f41153d41" xmlns="urn:schemas-microsoft-com:xml-wcfservicemap">
<ClientOptions>
<GenerateAsynchronousMethods>false</GenerateAsynchronousMethods>
<EnableDataBinding>true</EnableDataBinding>
<ExcludedTypes />
<ImportXmlTypes>false</ImportXmlTypes>
<GenerateInternalTypes>false</GenerateInternalTypes>
<GenerateMessageContracts>false</GenerateMessageContracts>
<NamespaceMappings />
<CollectionMappings />
<GenerateSerializableTypes>true</GenerateSerializableTypes>
<Serializer>Auto</Serializer>
<UseSerializerForFaults>true</UseSerializerForFaults>
<ReferenceAllAssemblies>true</ReferenceAllAssemblies>
<ReferencedAssemblies />
<ReferencedDataContractTypes />
<ServiceContractMappings />
</ClientOptions>
<MetadataSources>
<MetadataSource Address="http://services.romvault.com/Service1.svc" Protocol="http" SourceId="1" />
</MetadataSources>
<Metadata>
<MetadataFile FileName="Service1.xsd" MetadataType="Schema" ID="e82447ff-62bb-409b-a9a8-1eb69a23803f" SourceId="1" SourceUrl="http://services.romvault.com/Service1.svc?xsd=xsd1" />
<MetadataFile FileName="Service11.xsd" MetadataType="Schema" ID="b1a313ae-4281-4d1f-899f-b62a9030ce84" SourceId="1" SourceUrl="http://services.romvault.com/Service1.svc?xsd=xsd0" />
<MetadataFile FileName="Service11.disco" MetadataType="Disco" ID="4d89d5a9-fda6-41a7-8ea9-42e5667474e7" SourceId="1" SourceUrl="http://services.romvault.com/Service1.svc?disco" />
<MetadataFile FileName="Service11.wsdl" MetadataType="Wsdl" ID="6ec539f3-86eb-438b-b86f-c5ee07c53368" SourceId="1" SourceUrl="http://services.romvault.com/Service1.svc?wsdl" />
</Metadata>
<Extensions>
<ExtensionFile FileName="configuration91.svcinfo" Name="configuration91.svcinfo" />
<ExtensionFile FileName="configuration.svcinfo" Name="configuration.svcinfo" />
</Extensions>
</ReferenceGroup>

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="anyType" nillable="true" type="xs:anyType" />
<xs:element name="anyURI" nillable="true" type="xs:anyURI" />
<xs:element name="base64Binary" nillable="true" type="xs:base64Binary" />
<xs:element name="boolean" nillable="true" type="xs:boolean" />
<xs:element name="byte" nillable="true" type="xs:byte" />
<xs:element name="dateTime" nillable="true" type="xs:dateTime" />
<xs:element name="decimal" nillable="true" type="xs:decimal" />
<xs:element name="double" nillable="true" type="xs:double" />
<xs:element name="float" nillable="true" type="xs:float" />
<xs:element name="int" nillable="true" type="xs:int" />
<xs:element name="long" nillable="true" type="xs:long" />
<xs:element name="QName" nillable="true" type="xs:QName" />
<xs:element name="short" nillable="true" type="xs:short" />
<xs:element name="string" nillable="true" type="xs:string" />
<xs:element name="unsignedByte" nillable="true" type="xs:unsignedByte" />
<xs:element name="unsignedInt" nillable="true" type="xs:unsignedInt" />
<xs:element name="unsignedLong" nillable="true" type="xs:unsignedLong" />
<xs:element name="unsignedShort" nillable="true" type="xs:unsignedShort" />
<xs:element name="char" nillable="true" type="tns:char" />
<xs:simpleType name="char">
<xs:restriction base="xs:int" />
</xs:simpleType>
<xs:element name="duration" nillable="true" type="tns:duration" />
<xs:simpleType name="duration">
<xs:restriction base="xs:duration">
<xs:pattern value="\-?P(\d*D)?(T(\d*H)?(\d*M)?(\d*(\.\d*)?S)?)?" />
<xs:minInclusive value="-P10675199DT2H48M5.4775808S" />
<xs:maxInclusive value="P10675199DT2H48M5.4775807S" />
</xs:restriction>
</xs:simpleType>
<xs:element name="guid" nillable="true" type="tns:guid" />
<xs:simpleType name="guid">
<xs:restriction base="xs:string">
<xs:pattern value="[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}" />
</xs:restriction>
</xs:simpleType>
<xs:attribute name="FactoryType" type="xs:QName" />
<xs:attribute name="Id" type="xs:ID" />
<xs:attribute name="Ref" type="xs:IDREF" />
</xs:schema>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<discovery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/disco/">
<contractRef ref="http://services.romvault.com/Service1.svc?wsdl" docRef="http://services.romvault.com/Service1.svc" xmlns="http://schemas.xmlsoap.org/disco/scl/" />
</discovery>

View File

@@ -0,0 +1,266 @@
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:tns="http://tempuri.org/" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="Service1" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="http://services.romvault.com/Service1.svc?xsd=xsd0" namespace="http://tempuri.org/" />
<xsd:import schemaLocation="http://services.romvault.com/Service1.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
</xsd:schema>
</wsdl:types>
<wsdl:message name="IService1_CheckPassword_InputMessage">
<wsdl:part name="parameters" element="tns:CheckPassword" />
</wsdl:message>
<wsdl:message name="IService1_CheckPassword_OutputMessage">
<wsdl:part name="parameters" element="tns:CheckPasswordResponse" />
</wsdl:message>
<wsdl:message name="IService1_SendUser_InputMessage">
<wsdl:part name="parameters" element="tns:SendUser" />
</wsdl:message>
<wsdl:message name="IService1_SendUser_OutputMessage">
<wsdl:part name="parameters" element="tns:SendUserResponse" />
</wsdl:message>
<wsdl:message name="IService1_SendUser1_InputMessage">
<wsdl:part name="parameters" element="tns:SendUser1" />
</wsdl:message>
<wsdl:message name="IService1_SendUser1_OutputMessage">
<wsdl:part name="parameters" element="tns:SendUser1Response" />
</wsdl:message>
<wsdl:message name="IService1_GetLatestVersion_InputMessage">
<wsdl:part name="parameters" element="tns:GetLatestVersion" />
</wsdl:message>
<wsdl:message name="IService1_GetLatestVersion_OutputMessage">
<wsdl:part name="parameters" element="tns:GetLatestVersionResponse" />
</wsdl:message>
<wsdl:message name="IService1_GetLatestVersion1_InputMessage">
<wsdl:part name="parameters" element="tns:GetLatestVersion1" />
</wsdl:message>
<wsdl:message name="IService1_GetLatestVersion1_OutputMessage">
<wsdl:part name="parameters" element="tns:GetLatestVersion1Response" />
</wsdl:message>
<wsdl:message name="IService1_GetUpdateLink_InputMessage">
<wsdl:part name="parameters" element="tns:GetUpdateLink" />
</wsdl:message>
<wsdl:message name="IService1_GetUpdateLink_OutputMessage">
<wsdl:part name="parameters" element="tns:GetUpdateLinkResponse" />
</wsdl:message>
<wsdl:message name="IService1_GetUpdateLink1_InputMessage">
<wsdl:part name="parameters" element="tns:GetUpdateLink1" />
</wsdl:message>
<wsdl:message name="IService1_GetUpdateLink1_OutputMessage">
<wsdl:part name="parameters" element="tns:GetUpdateLink1Response" />
</wsdl:message>
<wsdl:message name="IService1_SendErrorMessage_InputMessage">
<wsdl:part name="parameters" element="tns:SendErrorMessage" />
</wsdl:message>
<wsdl:message name="IService1_SendErrorMessage_OutputMessage">
<wsdl:part name="parameters" element="tns:SendErrorMessageResponse" />
</wsdl:message>
<wsdl:message name="IService1_SendErrorMessage1_InputMessage">
<wsdl:part name="parameters" element="tns:SendErrorMessage1" />
</wsdl:message>
<wsdl:message name="IService1_SendErrorMessage1_OutputMessage">
<wsdl:part name="parameters" element="tns:SendErrorMessage1Response" />
</wsdl:message>
<wsdl:message name="IService1_SendErrorMessage2_InputMessage">
<wsdl:part name="parameters" element="tns:SendErrorMessage2" />
</wsdl:message>
<wsdl:message name="IService1_SendErrorMessage2_OutputMessage">
<wsdl:part name="parameters" element="tns:SendErrorMessage2Response" />
</wsdl:message>
<wsdl:message name="IService1_SendErrorMessage3_InputMessage">
<wsdl:part name="parameters" element="tns:SendErrorMessage3" />
</wsdl:message>
<wsdl:message name="IService1_SendErrorMessage3_OutputMessage">
<wsdl:part name="parameters" element="tns:SendErrorMessage3Response" />
</wsdl:message>
<wsdl:message name="IService1_SendDATErrorMessage2_InputMessage">
<wsdl:part name="parameters" element="tns:SendDATErrorMessage2" />
</wsdl:message>
<wsdl:message name="IService1_SendDATErrorMessage2_OutputMessage">
<wsdl:part name="parameters" element="tns:SendDATErrorMessage2Response" />
</wsdl:message>
<wsdl:message name="IService1_SendDATErrorMessage3_InputMessage">
<wsdl:part name="parameters" element="tns:SendDATErrorMessage3" />
</wsdl:message>
<wsdl:message name="IService1_SendDATErrorMessage3_OutputMessage">
<wsdl:part name="parameters" element="tns:SendDATErrorMessage3Response" />
</wsdl:message>
<wsdl:portType name="IService1">
<wsdl:operation name="CheckPassword">
<wsdl:input wsaw:Action="http://tempuri.org/IService1/CheckPassword" message="tns:IService1_CheckPassword_InputMessage" />
<wsdl:output wsaw:Action="http://tempuri.org/IService1/CheckPasswordResponse" message="tns:IService1_CheckPassword_OutputMessage" />
</wsdl:operation>
<wsdl:operation name="SendUser">
<wsdl:input wsaw:Action="http://tempuri.org/IService1/SendUser" message="tns:IService1_SendUser_InputMessage" />
<wsdl:output wsaw:Action="http://tempuri.org/IService1/SendUserResponse" message="tns:IService1_SendUser_OutputMessage" />
</wsdl:operation>
<wsdl:operation name="SendUser1">
<wsdl:input wsaw:Action="http://tempuri.org/IService1/SendUser1" message="tns:IService1_SendUser1_InputMessage" />
<wsdl:output wsaw:Action="http://tempuri.org/IService1/SendUser1Response" message="tns:IService1_SendUser1_OutputMessage" />
</wsdl:operation>
<wsdl:operation name="GetLatestVersion">
<wsdl:input wsaw:Action="http://tempuri.org/IService1/GetLatestVersion" message="tns:IService1_GetLatestVersion_InputMessage" />
<wsdl:output wsaw:Action="http://tempuri.org/IService1/GetLatestVersionResponse" message="tns:IService1_GetLatestVersion_OutputMessage" />
</wsdl:operation>
<wsdl:operation name="GetLatestVersion1">
<wsdl:input wsaw:Action="http://tempuri.org/IService1/GetLatestVersion1" message="tns:IService1_GetLatestVersion1_InputMessage" />
<wsdl:output wsaw:Action="http://tempuri.org/IService1/GetLatestVersion1Response" message="tns:IService1_GetLatestVersion1_OutputMessage" />
</wsdl:operation>
<wsdl:operation name="GetUpdateLink">
<wsdl:input wsaw:Action="http://tempuri.org/IService1/GetUpdateLink" message="tns:IService1_GetUpdateLink_InputMessage" />
<wsdl:output wsaw:Action="http://tempuri.org/IService1/GetUpdateLinkResponse" message="tns:IService1_GetUpdateLink_OutputMessage" />
</wsdl:operation>
<wsdl:operation name="GetUpdateLink1">
<wsdl:input wsaw:Action="http://tempuri.org/IService1/GetUpdateLink1" message="tns:IService1_GetUpdateLink1_InputMessage" />
<wsdl:output wsaw:Action="http://tempuri.org/IService1/GetUpdateLink1Response" message="tns:IService1_GetUpdateLink1_OutputMessage" />
</wsdl:operation>
<wsdl:operation name="SendErrorMessage">
<wsdl:input wsaw:Action="http://tempuri.org/IService1/SendErrorMessage" message="tns:IService1_SendErrorMessage_InputMessage" />
<wsdl:output wsaw:Action="http://tempuri.org/IService1/SendErrorMessageResponse" message="tns:IService1_SendErrorMessage_OutputMessage" />
</wsdl:operation>
<wsdl:operation name="SendErrorMessage1">
<wsdl:input wsaw:Action="http://tempuri.org/IService1/SendErrorMessage1" message="tns:IService1_SendErrorMessage1_InputMessage" />
<wsdl:output wsaw:Action="http://tempuri.org/IService1/SendErrorMessage1Response" message="tns:IService1_SendErrorMessage1_OutputMessage" />
</wsdl:operation>
<wsdl:operation name="SendErrorMessage2">
<wsdl:input wsaw:Action="http://tempuri.org/IService1/SendErrorMessage2" message="tns:IService1_SendErrorMessage2_InputMessage" />
<wsdl:output wsaw:Action="http://tempuri.org/IService1/SendErrorMessage2Response" message="tns:IService1_SendErrorMessage2_OutputMessage" />
</wsdl:operation>
<wsdl:operation name="SendErrorMessage3">
<wsdl:input wsaw:Action="http://tempuri.org/IService1/SendErrorMessage3" message="tns:IService1_SendErrorMessage3_InputMessage" />
<wsdl:output wsaw:Action="http://tempuri.org/IService1/SendErrorMessage3Response" message="tns:IService1_SendErrorMessage3_OutputMessage" />
</wsdl:operation>
<wsdl:operation name="SendDATErrorMessage2">
<wsdl:input wsaw:Action="http://tempuri.org/IService1/SendDATErrorMessage2" message="tns:IService1_SendDATErrorMessage2_InputMessage" />
<wsdl:output wsaw:Action="http://tempuri.org/IService1/SendDATErrorMessage2Response" message="tns:IService1_SendDATErrorMessage2_OutputMessage" />
</wsdl:operation>
<wsdl:operation name="SendDATErrorMessage3">
<wsdl:input wsaw:Action="http://tempuri.org/IService1/SendDATErrorMessage3" message="tns:IService1_SendDATErrorMessage3_InputMessage" />
<wsdl:output wsaw:Action="http://tempuri.org/IService1/SendDATErrorMessage3Response" message="tns:IService1_SendDATErrorMessage3_OutputMessage" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="BasicHttpBinding_IService1" type="tns:IService1">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="CheckPassword">
<soap:operation soapAction="http://tempuri.org/IService1/CheckPassword" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="SendUser">
<soap:operation soapAction="http://tempuri.org/IService1/SendUser" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="SendUser1">
<soap:operation soapAction="http://tempuri.org/IService1/SendUser1" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetLatestVersion">
<soap:operation soapAction="http://tempuri.org/IService1/GetLatestVersion" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetLatestVersion1">
<soap:operation soapAction="http://tempuri.org/IService1/GetLatestVersion1" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetUpdateLink">
<soap:operation soapAction="http://tempuri.org/IService1/GetUpdateLink" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetUpdateLink1">
<soap:operation soapAction="http://tempuri.org/IService1/GetUpdateLink1" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="SendErrorMessage">
<soap:operation soapAction="http://tempuri.org/IService1/SendErrorMessage" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="SendErrorMessage1">
<soap:operation soapAction="http://tempuri.org/IService1/SendErrorMessage1" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="SendErrorMessage2">
<soap:operation soapAction="http://tempuri.org/IService1/SendErrorMessage2" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="SendErrorMessage3">
<soap:operation soapAction="http://tempuri.org/IService1/SendErrorMessage3" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="SendDATErrorMessage2">
<soap:operation soapAction="http://tempuri.org/IService1/SendDATErrorMessage2" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="SendDATErrorMessage3">
<soap:operation soapAction="http://tempuri.org/IService1/SendDATErrorMessage3" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Service1">
<wsdl:port name="BasicHttpBinding_IService1" binding="tns:BasicHttpBinding_IService1">
<soap:address location="http://services.romvault.com/Service1.svc" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

View File

@@ -0,0 +1,198 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tns="http://tempuri.org/" elementFormDefault="qualified" targetNamespace="http://tempuri.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="CheckPassword">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="username" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="password" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="CheckPasswordResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="CheckPasswordResult" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SendUser">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="username" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="email" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="version" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SendUserResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="SendUserResult" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SendUser1">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="username" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="email" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="version" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="subversion" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SendUser1Response">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="SendUser1Result" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="GetLatestVersion">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="versionNow" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="GetLatestVersionResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="GetLatestVersionResult" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="GetLatestVersion1">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="version" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="subversion" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="GetLatestVersion1Response">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="GetLatestVersion1Result" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="GetUpdateLink">
<xs:complexType>
<xs:sequence />
</xs:complexType>
</xs:element>
<xs:element name="GetUpdateLinkResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="GetUpdateLinkResult" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="GetUpdateLink1">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="version" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="subversion" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="GetUpdateLink1Response">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="GetUpdateLink1Result" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SendErrorMessage">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="username" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="error" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SendErrorMessageResponse">
<xs:complexType>
<xs:sequence />
</xs:complexType>
</xs:element>
<xs:element name="SendErrorMessage1">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="username" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="email" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="error" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SendErrorMessage1Response">
<xs:complexType>
<xs:sequence />
</xs:complexType>
</xs:element>
<xs:element name="SendErrorMessage2">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="username" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="email" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="version" type="xs:int" />
<xs:element minOccurs="0" name="error" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SendErrorMessage2Response">
<xs:complexType>
<xs:sequence />
</xs:complexType>
</xs:element>
<xs:element name="SendErrorMessage3">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="username" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="email" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="version" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="subversion" type="xs:int" />
<xs:element minOccurs="0" name="error" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SendErrorMessage3Response">
<xs:complexType>
<xs:sequence />
</xs:complexType>
</xs:element>
<xs:element name="SendDATErrorMessage2">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="username" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="email" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="version" type="xs:int" />
<xs:element minOccurs="0" name="error" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="filename" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SendDATErrorMessage2Response">
<xs:complexType>
<xs:sequence />
</xs:complexType>
</xs:element>
<xs:element name="SendDATErrorMessage3">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="username" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="email" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="version" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="subversion" type="xs:int" />
<xs:element minOccurs="0" name="error" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="filename" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SendDATErrorMessage3Response">
<xs:complexType>
<xs:sequence />
</xs:complexType>
</xs:element>
</xs:schema>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<configurationSnapshot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:schemas-microsoft-com:xml-wcfconfigurationsnapshot">
<behaviors />
<bindings>
<binding digest="System.ServiceModel.Configuration.BasicHttpBindingElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089:&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data name=&quot;BasicHttpBinding_IService1&quot; /&gt;" bindingType="basicHttpBinding" name="BasicHttpBinding_IService1" />
</bindings>
<endpoints>
<endpoint normalizedDigest="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data address=&quot;http://services.romvault.com/Service1.svc&quot; binding=&quot;basicHttpBinding&quot; bindingConfiguration=&quot;BasicHttpBinding_IService1&quot; contract=&quot;RVRef.IService1&quot; name=&quot;BasicHttpBinding_IService1&quot; /&gt;" digest="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data address=&quot;http://services.romvault.com/Service1.svc&quot; binding=&quot;basicHttpBinding&quot; bindingConfiguration=&quot;BasicHttpBinding_IService1&quot; contract=&quot;RVRef.IService1&quot; name=&quot;BasicHttpBinding_IService1&quot; /&gt;" contractName="RVRef.IService1" name="BasicHttpBinding_IService1" />
</endpoints>
</configurationSnapshot>

View File

@@ -0,0 +1,201 @@
<?xml version="1.0" encoding="utf-8"?>
<SavedWcfConfigurationInformation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="9.1" CheckSum="Q9vfTyG5baoe1++y9zlXEcaBfIk=">
<bindingConfigurations>
<bindingConfiguration bindingType="basicHttpBinding" name="BasicHttpBinding_IService1">
<properties>
<property path="/name" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>BasicHttpBinding_IService1</serializedValue>
</property>
<property path="/closeTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/openTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/receiveTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/sendTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/allowCookies" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/bypassProxyOnLocal" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/hostNameComparisonMode" isComplexType="false" isExplicitlyDefined="false" clrType="System.ServiceModel.HostNameComparisonMode, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>StrongWildcard</serializedValue>
</property>
<property path="/maxBufferPoolSize" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/maxBufferSize" isComplexType="false" isExplicitlyDefined="false" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>65536</serializedValue>
</property>
<property path="/maxReceivedMessageSize" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/proxyAddress" isComplexType="false" isExplicitlyDefined="false" clrType="System.Uri, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/readerQuotas" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.XmlDictionaryReaderQuotasElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.XmlDictionaryReaderQuotasElement</serializedValue>
</property>
<property path="/readerQuotas/maxDepth" isComplexType="false" isExplicitlyDefined="false" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>0</serializedValue>
</property>
<property path="/readerQuotas/maxStringContentLength" isComplexType="false" isExplicitlyDefined="false" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>0</serializedValue>
</property>
<property path="/readerQuotas/maxArrayLength" isComplexType="false" isExplicitlyDefined="false" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>0</serializedValue>
</property>
<property path="/readerQuotas/maxBytesPerRead" isComplexType="false" isExplicitlyDefined="false" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>0</serializedValue>
</property>
<property path="/readerQuotas/maxNameTableCharCount" isComplexType="false" isExplicitlyDefined="false" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>0</serializedValue>
</property>
<property path="/textEncoding" isComplexType="false" isExplicitlyDefined="false" clrType="System.Text.Encoding, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.Text.UTF8Encoding</serializedValue>
</property>
<property path="/transferMode" isComplexType="false" isExplicitlyDefined="false" clrType="System.ServiceModel.TransferMode, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>Buffered</serializedValue>
</property>
<property path="/useDefaultWebProxy" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/messageEncoding" isComplexType="false" isExplicitlyDefined="false" clrType="System.ServiceModel.WSMessageEncoding, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>Text</serializedValue>
</property>
<property path="/security" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.BasicHttpSecurityElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.BasicHttpSecurityElement</serializedValue>
</property>
<property path="/security/mode" isComplexType="false" isExplicitlyDefined="false" clrType="System.ServiceModel.BasicHttpSecurityMode, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>None</serializedValue>
</property>
<property path="/security/transport" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.HttpTransportSecurityElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.HttpTransportSecurityElement</serializedValue>
</property>
<property path="/security/transport/clientCredentialType" isComplexType="false" isExplicitlyDefined="false" clrType="System.ServiceModel.HttpClientCredentialType, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>None</serializedValue>
</property>
<property path="/security/transport/proxyCredentialType" isComplexType="false" isExplicitlyDefined="false" clrType="System.ServiceModel.HttpProxyCredentialType, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>None</serializedValue>
</property>
<property path="/security/transport/extendedProtectionPolicy" isComplexType="true" isExplicitlyDefined="false" clrType="System.Security.Authentication.ExtendedProtection.Configuration.ExtendedProtectionPolicyElement, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.Security.Authentication.ExtendedProtection.Configuration.ExtendedProtectionPolicyElement</serializedValue>
</property>
<property path="/security/transport/extendedProtectionPolicy/policyEnforcement" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Authentication.ExtendedProtection.PolicyEnforcement, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>Never</serializedValue>
</property>
<property path="/security/transport/extendedProtectionPolicy/protectionScenario" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Authentication.ExtendedProtection.ProtectionScenario, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>TransportSelected</serializedValue>
</property>
<property path="/security/transport/extendedProtectionPolicy/customServiceNames" isComplexType="true" isExplicitlyDefined="false" clrType="System.Security.Authentication.ExtendedProtection.Configuration.ServiceNameElementCollection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>(Collection)</serializedValue>
</property>
<property path="/security/transport/realm" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/security/message" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.BasicHttpMessageSecurityElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.BasicHttpMessageSecurityElement</serializedValue>
</property>
<property path="/security/message/clientCredentialType" isComplexType="false" isExplicitlyDefined="false" clrType="System.ServiceModel.BasicHttpMessageCredentialType, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>UserName</serializedValue>
</property>
<property path="/security/message/algorithmSuite" isComplexType="false" isExplicitlyDefined="false" clrType="System.ServiceModel.Security.SecurityAlgorithmSuite, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>Default</serializedValue>
</property>
</properties>
</bindingConfiguration>
</bindingConfigurations>
<endpoints>
<endpoint name="BasicHttpBinding_IService1" contract="RVRef.IService1" bindingType="basicHttpBinding" address="http://services.romvault.com/Service1.svc" bindingConfiguration="BasicHttpBinding_IService1">
<properties>
<property path="/address" isComplexType="false" isExplicitlyDefined="true" clrType="System.Uri, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>http://services.romvault.com/Service1.svc</serializedValue>
</property>
<property path="/behaviorConfiguration" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/binding" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>basicHttpBinding</serializedValue>
</property>
<property path="/bindingConfiguration" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>BasicHttpBinding_IService1</serializedValue>
</property>
<property path="/contract" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>RVRef.IService1</serializedValue>
</property>
<property path="/headers" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.AddressHeaderCollectionElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.AddressHeaderCollectionElement</serializedValue>
</property>
<property path="/headers/headers" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.Channels.AddressHeaderCollection, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>&lt;Header /&gt;</serializedValue>
</property>
<property path="/identity" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.IdentityElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.IdentityElement</serializedValue>
</property>
<property path="/identity/userPrincipalName" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.UserPrincipalNameElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.UserPrincipalNameElement</serializedValue>
</property>
<property path="/identity/userPrincipalName/value" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/identity/servicePrincipalName" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.ServicePrincipalNameElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.ServicePrincipalNameElement</serializedValue>
</property>
<property path="/identity/servicePrincipalName/value" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/identity/dns" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.DnsElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.DnsElement</serializedValue>
</property>
<property path="/identity/dns/value" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/identity/rsa" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.RsaElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.RsaElement</serializedValue>
</property>
<property path="/identity/rsa/value" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/identity/certificate" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.CertificateElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.CertificateElement</serializedValue>
</property>
<property path="/identity/certificate/encodedValue" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/identity/certificateReference" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.CertificateReferenceElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>System.ServiceModel.Configuration.CertificateReferenceElement</serializedValue>
</property>
<property path="/identity/certificateReference/storeName" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Cryptography.X509Certificates.StoreName, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>My</serializedValue>
</property>
<property path="/identity/certificateReference/storeLocation" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Cryptography.X509Certificates.StoreLocation, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>LocalMachine</serializedValue>
</property>
<property path="/identity/certificateReference/x509FindType" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Cryptography.X509Certificates.X509FindType, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>FindBySubjectDistinguishedName</serializedValue>
</property>
<property path="/identity/certificateReference/findValue" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/identity/certificateReference/isChainIncluded" isComplexType="false" isExplicitlyDefined="false" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>False</serializedValue>
</property>
<property path="/name" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue>BasicHttpBinding_IService1</serializedValue>
</property>
<property path="/kind" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
<property path="/endpointConfiguration" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<serializedValue />
</property>
</properties>
</endpoint>
</endpoints>
</SavedWcfConfigurationInformation>

314
ROMVault2/Settings.cs Normal file
View File

@@ -0,0 +1,314 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Win32;
using ROMVault2.RvDB;
namespace ROMVault2
{
public enum eScanLevel
{
Level1,
Level2,
Level3
}
public enum eFixLevel
{
TrrntZipLevel1,
TrrntZipLevel2,
TrrntZipLevel3,
Level1,
Level2,
Level3
}
public static class Settings
{
public static string DatRoot;
public static string CacheFile;
public static eScanLevel ScanLevel;
public static eFixLevel FixLevel;
public static List<DirMap> DirPathMap;
public static List<string> IgnoreFiles;
public static bool DoubleCheckDelete = true;
public static bool DebugLogsEnabled;
public static bool CacheSaveTimerEnabled = true;
public static int CacheSaveTimePeriod = 10;
public static string EMail
{
get
{
RegistryKey regKey1 = Registry.CurrentUser;
regKey1 = regKey1.CreateSubKey("Software\\RomVault2\\User");
return regKey1.GetValue("Email", "").ToString();
}
set
{
RegistryKey regKey = Registry.CurrentUser;
regKey = regKey.CreateSubKey("Software\\RomVault2\\User");
regKey.SetValue("Email", value);
}
}
public static string Username
{
get
{
RegistryKey regKey1 = Registry.CurrentUser;
regKey1 = regKey1.CreateSubKey("Software\\RomVault2\\User");
return regKey1.GetValue("UserName", "").ToString();
}
set
{
RegistryKey regKey = Registry.CurrentUser;
regKey = regKey.CreateSubKey("Software\\RomVault2\\User");
regKey.SetValue("UserName", value);
}
}
public static void SetDefaults()
{
CacheFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RomVault2_"+DBVersion.Version+".Cache");
//DatRoot = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DatRoot");
DatRoot = "DatRoot";
ScanLevel = eScanLevel.Level2;
FixLevel = eFixLevel.TrrntZipLevel2;
IgnoreFiles = new List<string> { "_ReadMe_.txt" };
ResetDirectories();
ReadConfig();
DirPathMap.Sort();
}
public static void ResetDirectories()
{
DirPathMap = new List<DirMap>
{
new DirMap("RomVault", "RomRoot"),
new DirMap("ToSort", "ToSort")
};
}
public static string ToSort()
{
foreach (DirMap t in DirPathMap)
{
if (t.DirKey == "ToSort")
return t.DirPath;
}
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ToSort");
}
public static void WriteConfig()
{
if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RomVault2.cfg")))
File.Delete(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RomVault2.cfg"));
FileStream fs = new FileStream(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RomVault2.cfg"), FileMode.CreateNew, FileAccess.Write);
BinaryWriter bw = new BinaryWriter(fs);
const int ver = 5;
bw.Write(ver); //int
bw.Write(DatRoot); //string
bw.Write((Int32)ScanLevel);
bw.Write((Int32)FixLevel);
bw.Write(DebugLogsEnabled); //bool
bw.Write(IgnoreFiles.Count); //int
foreach (string t in IgnoreFiles)
{
bw.Write(t); //string
}
bw.Write(DirPathMap.Count); //int
foreach (DirMap t in DirPathMap)
{
bw.Write(t.DirKey); //string
bw.Write(t.DirPath); //string
}
bw.Write(CacheSaveTimerEnabled); //bool
bw.Write(CacheSaveTimePeriod); //int
bw.Write(DoubleCheckDelete); //bool
fs.Flush();
fs.Close();
}
private static void ReadConfig()
{
if (!File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RomVault2.cfg"))) return;
FileStream fs = new FileStream(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RomVault2.cfg"), FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
int ver = br.ReadInt32();
if (ver == 1)
{
DatRoot = br.ReadString();
ScanLevel = eScanLevel.Level1;
FixLevel = (eFixLevel)br.ReadInt32();
IgnoreFiles = new List<string>();
int c = br.ReadInt32();
for (int i = 0; i < c; i++)
IgnoreFiles.Add(br.ReadString());
DirPathMap = new List<DirMap>();
c = br.ReadInt32();
for (int i = 0; i < c; i++)
DirPathMap.Add(new DirMap(br.ReadString(), br.ReadString()));
}
if (ver == 2)
{
DatRoot = br.ReadString();
ScanLevel = (eScanLevel)br.ReadInt32();
FixLevel = (eFixLevel)br.ReadInt32();
IgnoreFiles = new List<string>();
int c = br.ReadInt32();
for (int i = 0; i < c; i++)
IgnoreFiles.Add(br.ReadString());
DirPathMap = new List<DirMap>();
c = br.ReadInt32();
for (int i = 0; i < c; i++)
DirPathMap.Add(new DirMap(br.ReadString(), br.ReadString()));
}
if (ver == 3)
{
DatRoot = br.ReadString();
ScanLevel = (eScanLevel)br.ReadInt32();
FixLevel = (eFixLevel)br.ReadInt32();
DebugLogsEnabled = br.ReadBoolean();
IgnoreFiles = new List<string>();
int c = br.ReadInt32();
for (int i = 0; i < c; i++)
IgnoreFiles.Add(br.ReadString());
DirPathMap = new List<DirMap>();
c = br.ReadInt32();
for (int i = 0; i < c; i++)
DirPathMap.Add(new DirMap(br.ReadString(), br.ReadString()));
}
if (ver == 4)
{
DatRoot = br.ReadString();
ScanLevel = (eScanLevel)br.ReadInt32();
FixLevel = (eFixLevel)br.ReadInt32();
DebugLogsEnabled = br.ReadBoolean();
IgnoreFiles = new List<string>();
int c = br.ReadInt32();
for (int i = 0; i < c; i++)
IgnoreFiles.Add(br.ReadString());
DirPathMap = new List<DirMap>();
c = br.ReadInt32();
for (int i = 0; i < c; i++)
DirPathMap.Add(new DirMap(br.ReadString(), br.ReadString()));
CacheSaveTimerEnabled = br.ReadBoolean();
CacheSaveTimePeriod = br.ReadInt32();
}
if (ver == 5)
{
DatRoot = br.ReadString();
ScanLevel = (eScanLevel)br.ReadInt32();
FixLevel = (eFixLevel)br.ReadInt32();
DebugLogsEnabled = br.ReadBoolean();
IgnoreFiles = new List<string>();
int c = br.ReadInt32();
for (int i = 0; i < c; i++)
IgnoreFiles.Add(br.ReadString());
DirPathMap = new List<DirMap>();
c = br.ReadInt32();
for (int i = 0; i < c; i++)
DirPathMap.Add(new DirMap(br.ReadString(), br.ReadString()));
CacheSaveTimerEnabled = br.ReadBoolean();
CacheSaveTimePeriod = br.ReadInt32();
DoubleCheckDelete = br.ReadBoolean();
}
if (ver == 6)
{
DatRoot = br.ReadString();
ScanLevel = (eScanLevel)br.ReadInt32();
FixLevel = (eFixLevel)br.ReadInt32();
DebugLogsEnabled = br.ReadBoolean();
bool UserLongFilenames = br.ReadBoolean();
IgnoreFiles = new List<string>();
int c = br.ReadInt32();
for (int i = 0; i < c; i++)
IgnoreFiles.Add(br.ReadString());
DirPathMap = new List<DirMap>();
c = br.ReadInt32();
for (int i = 0; i < c; i++)
DirPathMap.Add(new DirMap(br.ReadString(), br.ReadString()));
CacheSaveTimerEnabled = br.ReadBoolean();
CacheSaveTimePeriod = br.ReadInt32();
DoubleCheckDelete = br.ReadBoolean();
}
br.Close();
fs.Close();
}
}
public class DirMap : IComparable<DirMap>
{
public readonly string DirKey;
public readonly string DirPath;
public DirMap(string key, string path)
{
DirKey = key;
DirPath = path;
}
public int CompareTo(DirMap obj)
{
return Math.Sign(String.Compare(DirKey, obj.DirKey, StringComparison.Ordinal));
}
}
}

View File

@@ -0,0 +1,438 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using ROMVault2.IO;
using File = System.IO.File;
using Path = System.IO.Path;
namespace ROMVault2.SupportedFiles.CHD
{
public static class CHD
{
private const int MaxHeader = 124;
public static int CheckFile(IO.FileInfo ofile, out byte[] SHA1CHD, out byte[] MD5CHD, out uint? version)
{
SHA1CHD = null;
MD5CHD = null;
version = null;
string ext = IO.Path.GetExtension(ofile.Name).ToLower();
if (ext != ".chd")
return 0;
if (ofile.Length < MaxHeader)
return 0;
Stream s;
int retval = IO.FileStream.OpenFileRead(ofile.FullName, out s);
if (retval != 0)
return retval;
if (s == null) return 1;
CheckFile(s, out SHA1CHD, out MD5CHD, out version);
s.Close();
s.Dispose();
return 0;
}
private static void CheckFile(Stream s, out byte[] SHA1CHD, out byte[] MD5CHD, out uint? version)
{
using (BinaryReader br = new BinaryReader(s))
{
byte[] buff = br.ReadBytes(MaxHeader);
CheckFile(buff, out SHA1CHD, out MD5CHD, out version);
}
}
private static void CheckFile(byte[] buff, out byte[] SHA1CHD, out byte[] MD5CHD, out uint? version)
{
SHA1CHD = null;
MD5CHD = null;
version = null;
UInt32 compression = 0;
byte[] header = new[] { (byte)'M', (byte)'C', (byte)'o', (byte)'m', (byte)'p', (byte)'r', (byte)'H', (byte)'D' };
for (int i = 0; i < header.Length; i++)
{
if (buff[i] != header[i])
return;
}
UInt32 length = ReadUInt32(buff, 8);
version = ReadUInt32(buff, 12);
if (version > 5)
return;
switch (version)
{
case 1:
if (length != 76) return;
// V1 header:
// [ 0] char tag[8]; // 'MComprHD'
// [ 8] UINT32 length; // length of header (including tag and length fields)
// [ 12] UINT32 version; // drive format version
// [ 16] UINT32 flags; // flags (see below)
// [ 20] UINT32 compression; // compression type
compression = ReadUInt32(buff, 20);
if (compression == 0) return;
// [ 24] UINT32 hunksize; // 512-byte sectors per hunk
// [ 28] UINT32 totalhunks; // total # of hunks represented
// [ 32] UINT32 cylinders; // number of cylinders on hard disk
// [ 36] UINT32 heads; // number of heads on hard disk
// [ 40] UINT32 sectors; // number of sectors on hard disk
// [ 44] UINT8 md5[16]; // MD5 checksum of raw data
MD5CHD = ReadBytes(buff, 44, 16);
// [ 60] UINT8 parentmd5[16]; // MD5 checksum of parent file
// [ 76] (V1 header length)
return;
case 2:
if (length != 80) return;
// V2 header:
// [ 0] char tag[8]; // 'MComprHD'
// [ 8] UINT32 length; // length of header (including tag and length fields)
// [ 12] UINT32 version; // drive format version
// [ 16] UINT32 flags; // flags (see below)
// [ 20] UINT32 compression; // compression type
compression = ReadUInt32(buff, 20);
if (compression == 0) return;
// [ 24] UINT32 hunksize; // seclen-byte sectors per hunk
// [ 28] UINT32 totalhunks; // total # of hunks represented
// [ 32] UINT32 cylinders; // number of cylinders on hard disk
// [ 36] UINT32 heads; // number of heads on hard disk
// [ 40] UINT32 sectors; // number of sectors on hard disk
// [ 44] UINT8 md5[16]; // MD5 checksum of raw data
MD5CHD = ReadBytes(buff, 44, 16);
// [ 60] UINT8 parentmd5[16]; // MD5 checksum of parent file
// [ 76] UINT32 seclen; // number of bytes per sector
// [ 80] (V2 header length)
return;
case 3:
if (length != 120) return;
// V3 header:
// [ 0] char tag[8]; // 'MComprHD'
// [ 8] UINT32 length; // length of header (including tag and length fields)
// [ 12] UINT32 version; // drive format version
// [ 16] UINT32 flags; // flags (see below)
// [ 20] UINT32 compression; // compression type
compression = ReadUInt32(buff, 20);
if (compression == 0) return;
// [ 24] UINT32 totalhunks; // total # of hunks represented
// [ 28] UINT64 logicalbytes; // logical size of the data (in bytes)
// [ 36] UINT64 metaoffset; // offset to the first blob of metadata
// [ 44] UINT8 md5[16]; // MD5 checksum of raw data
MD5CHD = ReadBytes(buff, 44, 16);
// [ 60] UINT8 parentmd5[16]; // MD5 checksum of parent file
// [ 76] UINT32 hunkbytes; // number of bytes per hunk
// [ 80] UINT8 sha1[20]; // SHA1 checksum of raw data
SHA1CHD = ReadBytes(buff, 80, 20);
// [100] UINT8 parentsha1[20];// SHA1 checksum of parent file
// [120] (V3 header length)
return;
case 4:
if (length != 108) return;
// V4 header:
// [ 0] char tag[8]; // 'MComprHD'
// [ 8] UINT32 length; // length of header (including tag and length fields)
// [ 12] UINT32 version; // drive format version
// [ 16] UINT32 flags; // flags (see below)
// [ 20] UINT32 compression; // compression type
compression = ReadUInt32(buff, 20);
if (compression == 0) return;
// [ 24] UINT32 totalhunks; // total # of hunks represented
// [ 28] UINT64 logicalbytes; // logical size of the data (in bytes)
// [ 36] UINT64 metaoffset; // offset to the first blob of metadata
// [ 44] UINT32 hunkbytes; // number of bytes per hunk
// [ 48] UINT8 sha1[20]; // combined raw+meta SHA1
SHA1CHD = ReadBytes(buff, 48, 20);
// [ 68] UINT8 parentsha1[20];// combined raw+meta SHA1 of parent
// [ 88] UINT8 rawsha1[20]; // raw data SHA1
// [108] (V4 header length)
return;
case 5:
if (length != 124) return;
// V5 header:
// [ 0] char tag[8]; // 'MComprHD'
// [ 8] UINT32 length; // length of header (including tag and length fields)
// [ 12] UINT32 version; // drive format version
// [ 16] UINT32 compressors[4];// which custom compressors are used?
UInt32 compression0 = ReadUInt32(buff, 16);
UInt32 compression1 = ReadUInt32(buff, 20);
UInt32 compression2 = ReadUInt32(buff, 24);
UInt32 compression3 = ReadUInt32(buff, 28);
if (compression0 == 0 && compression1 == 0 && compression2 == 0 && compression3 == 0) return;
// [ 32] UINT64 logicalbytes; // logical size of the data (in bytes)
// [ 40] UINT64 mapoffset; // offset to the map
// [ 48] UINT64 metaoffset; // offset to the first blob of metadata
// [ 56] UINT32 hunkbytes; // number of bytes per hunk (512k maximum)
// [ 60] UINT32 unitbytes; // number of bytes per unit within each hunk
// [ 64] UINT8 rawsha1[20]; // raw data SHA1
// [ 84] UINT8 sha1[20]; // combined raw+meta SHA1
SHA1CHD = ReadBytes(buff, 84, 20);
// [104] UINT8 parentsha1[20];// combined raw+meta SHA1 of parent
// [124] (V5 header length)
return;
}
}
private static UInt32 ReadUInt32(byte[] b, int p)
{
return
((UInt32)b[p + 0]) << 24 |
((UInt32)b[p + 1]) << 16 |
((UInt32)b[p + 2]) << 8 |
(b[p + 3]);
}
private static byte[] ReadBytes(byte[] b, int p, int length)
{
byte[] ret = new byte[length];
for (int i = 0; i < length; i++)
ret[i] = b[p + i];
return ret;
}
private static string _result;
private static BackgroundWorker _bgw;
private static CHDManCheck _resultType;
public enum CHDManCheck
{
Unset,
Good,
Corrupt,
CHDNotFound,
ChdmanNotFound,
CHDUnknownError,
CHDReturnError
}
public static CHDManCheck ChdmanCheck(string filename, BackgroundWorker bgw, out string result)
{
_bgw = bgw;
_result = "";
_resultType = CHDManCheck.Unset;
string chdPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "chdman.exe");
if (!File.Exists(chdPath))
{
result = "chdman not found";
return CHDManCheck.ChdmanNotFound;
}
if (!IO.File.Exists(filename))
{
result = filename + " Not Found.";
return CHDManCheck.CHDNotFound;
}
string shortName = NameFix.GetShortPath(filename);
using (Process exeProcess = new Process())
{
exeProcess.StartInfo.FileName = chdPath;
ReportError.LogOut("CHD: FileName :" + exeProcess.StartInfo.FileName);
exeProcess.StartInfo.Arguments = "verify -i \"" + shortName + "\"";
ReportError.LogOut("CHD: Arguments :" + exeProcess.StartInfo.Arguments);
// Set UseShellExecute to false for redirection.
exeProcess.StartInfo.UseShellExecute = false;
// Stops the Command window from popping up.
exeProcess.StartInfo.CreateNoWindow = true;
// Redirect the standard output.
// This stream is read asynchronously using an event handler.
exeProcess.StartInfo.RedirectStandardOutput = true;
exeProcess.StartInfo.RedirectStandardError = true;
// Set our event handler to asynchronously read the process output.
exeProcess.OutputDataReceived += CHDOutputHandler;
exeProcess.ErrorDataReceived += CHDErrorHandler;
_outputLineCount = 0;
_errorLines=0;
ReportError.LogOut("CHD: Scanning Starting");
exeProcess.Start();
// Start the asynchronous read of the process output stream.
exeProcess.BeginOutputReadLine();
exeProcess.BeginErrorReadLine();
// Wait for the process finish.
exeProcess.WaitForExit();
ReportError.LogOut("CHD: Scanning Finished");
}
result = _result;
if (_resultType == CHDManCheck.Unset)
_resultType = CHDManCheck.Good;
_bgw.ReportProgress(0, new bgwText3(""));
ReportError.LogOut("CHD: returning result " + _resultType + " " + result);
return _resultType;
}
/*
chdman - MAME Compressed Hunks of Data (CHD) manager 0.147 (Sep 18 2012)
Raw SHA1 verification successful!
Overall SHA1 verification successful!
*/
private static int _outputLineCount;
private static void CHDOutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
// Collect the process command output.
if (String.IsNullOrEmpty(outLine.Data)) return;
string sOut = outLine.Data;
//ReportError.LogOut("CHDOutput: " + _outputLineCount + " : " + sOut);
switch (_outputLineCount)
{
case 0:
if (sOut.Length < 53 || sOut.Substring(0, 53) != "chdman - MAME Compressed Hunks of Data (CHD) manager ")
{
_result = "Incorrect startup of CHDMan :" + sOut;
_resultType = CHDManCheck.CHDReturnError;
}
break;
case 1:
if (sOut != "Raw SHA1 verification successful!")
{
_result = "Raw SHA1 check failed :" + sOut;
_resultType = CHDManCheck.CHDReturnError;
}
break;
case 2:
if (sOut != "Overall SHA1 verification successful!")
{
_result = "Overall SHA1 check failed :" + sOut;
_resultType = CHDManCheck.CHDReturnError;
}
break;
default:
_result = "Unexpected output from chdman :" + sOut;
ReportError.SendErrorMessage("CHDOutputHandler returned =" + sOut);
_resultType = CHDManCheck.CHDUnknownError;
break;
}
_outputLineCount++;
}
private static int _errorLines;
private static void CHDErrorHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
// Collect the process command output.
if (String.IsNullOrEmpty(outLine.Data)) return;
string sOut = outLine.Data;
ReportError.LogOut("CHDError: " + sOut);
_bgw.ReportProgress(0, new bgwText3(sOut));
if (_resultType != CHDManCheck.Unset)
{
if(_errorLines>0)
{
_errorLines -= 1;
_result += "\r\n" + sOut;
}
return;
}
if (sOut.Length > 44)
if (sOut.Substring(0, 23) == "Error reading CHD file " && sOut.Substring(sOut.Length - 21, 21) == ": decompression error")
{
_result = sOut;
_resultType = CHDManCheck.Corrupt;
return;
}
if (sOut.Length > 35)
if (sOut.Substring(0, 23) == "Error opening CHD file " && sOut.Substring(sOut.Length - 21, 21) == ": decompression error")
{
_result = sOut;
_resultType = CHDManCheck.Corrupt;
return;
}
if (sOut.Length > 35)
if (sOut.Substring(0, 23) == "Error opening CHD file " && sOut.Substring(sOut.Length - 12, 12) == ": read error")
{
_result = sOut;
_resultType = CHDManCheck.Corrupt;
return;
}
if (sOut.Length > 25)
if (sOut.Substring(0, 25) == "Error: Raw SHA1 in header")
{
_result = sOut;
_errorLines = 1;
_resultType = CHDManCheck.Corrupt;
return;
}
if (sOut.Length == 13)
if (sOut == "Out of memory")
{
_result = sOut;
_resultType = CHDManCheck.Corrupt;
return;
}
// check for Verifying message
if (sOut.Length >= 24)
if (sOut.Substring(0, 11) == "Verifying, " && sOut.Substring(sOut.Length - 13, 13) == " complete... ")
{
//_resultType = CHDManCheck.Good;
return;
}
ReportError.SendErrorMessage("CHDErrorHandler returned =" + sOut);
_result = "Unknown message : " + sOut;
_resultType = CHDManCheck.CHDUnknownError;
}
}
}

View File

@@ -0,0 +1,70 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System.IO;
using System.Security.Cryptography;
using ROMVault2.SupportedFiles.Zip.ZLib;
namespace ROMVault2.SupportedFiles.Files
{
public static class UnCompFiles
{
private const int Buffersize = 4096;
private static readonly byte[] Buffer;
static UnCompFiles()
{
Buffer = new byte[Buffersize];
}
public static int CheckSumRead(string filename, bool testDeep, out byte[] crc, out byte[] bMD5, out byte[] bSHA1)
{
bMD5 = null;
bSHA1 = null;
crc = null;
Stream ds;
int errorCode = IO.FileStream.OpenFileRead(filename, out ds);
if (errorCode != 0)
return errorCode;
CRC32Hash crc32 = new CRC32Hash();
MD5 md5 = null;
if (testDeep) md5 = MD5.Create();
SHA1 sha1 = null;
if (testDeep) sha1 = SHA1.Create();
long sizetogo = ds.Length;
while (sizetogo > 0)
{
int sizenow = sizetogo > Buffersize ? Buffersize : (int)sizetogo;
ds.Read(Buffer, 0, sizenow);
crc32.TransformBlock(Buffer, 0, sizenow, null, 0);
if (testDeep) md5.TransformBlock(Buffer, 0, sizenow, null, 0);
if (testDeep) sha1.TransformBlock(Buffer, 0, sizenow, null, 0);
sizetogo -= sizenow;
}
crc32.TransformFinalBlock(Buffer, 0, 0);
if (testDeep) md5.TransformFinalBlock(Buffer, 0, 0);
if (testDeep) sha1.TransformFinalBlock(Buffer, 0, 0);
ds.Close();
crc = crc32.Hash;
if (testDeep) bMD5 = md5.Hash;
if (testDeep) bSHA1 = sha1.Hash;
return 0;
}
}
}

View File

@@ -0,0 +1,856 @@
// CRC32.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2011 Dino Chiesa.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// Last Saved: <2011-August-02 18:25:54>
//
// ------------------------------------------------------------------
//
// This module defines the CRC32 class, which can do the CRC32 algorithm, using
// arbitrary starting polynomials, and bit reversal. The bit reversal is what
// distinguishes this CRC-32 used in BZip2 from the CRC-32 that is used in PKZIP
// files, or GZIP files. This class does both.
//
// ------------------------------------------------------------------
using System;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
namespace ROMVault2.SupportedFiles.Zip.ZLib
{
/// <summary>
/// Computes a CRC-32. The CRC-32 algorithm is parameterized - you
/// can set the polynomial and enable or disable bit
/// reversal. This can be used for GZIP, BZip2, or ZIP.
/// </summary>
/// <remarks>
/// This type is used internally by DotNetZip; it is generally not used
/// directly by applications wishing to create, read, or manipulate zip
/// archive files.
/// </remarks>
[Guid("ebc25cf6-9120-4283-b972-0e5520d0000C")]
[System.Runtime.InteropServices.ComVisible(true)]
#if !NETCF
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.AutoDispatch)]
#endif
public class CRC32
{
/// <summary>
/// Indicates the total number of bytes applied to the CRC.
/// </summary>
public Int64 TotalBytesRead
{
get
{
return _TotalBytesRead;
}
}
/// <summary>
/// Indicates the current CRC for all blocks slurped in.
/// </summary>
public Int32 Crc32Result
{
get
{
return unchecked((Int32)(~_register));
}
}
public uint Crc32ResultU
{
get
{
return ~_register;
}
}
/// <summary>
/// Returns the CRC32 for the specified stream.
/// </summary>
/// <param name="input">The stream over which to calculate the CRC32</param>
/// <returns>the CRC32 calculation</returns>
public Int32 GetCrc32(System.IO.Stream input)
{
return GetCrc32AndCopy(input, null);
}
/// <summary>
/// Returns the CRC32 for the specified stream, and writes the input into the
/// output stream.
/// </summary>
/// <param name="input">The stream over which to calculate the CRC32</param>
/// <param name="output">The stream into which to deflate the input</param>
/// <returns>the CRC32 calculation</returns>
public Int32 GetCrc32AndCopy(System.IO.Stream input, System.IO.Stream output)
{
if (input == null)
throw new Exception("The input stream must not be null.");
unchecked
{
byte[] buffer = new byte[BUFFER_SIZE];
int readSize = BUFFER_SIZE;
_TotalBytesRead = 0;
int count = input.Read(buffer, 0, readSize);
if (output != null) output.Write(buffer, 0, count);
_TotalBytesRead += count;
while (count > 0)
{
SlurpBlock(buffer, 0, count);
count = input.Read(buffer, 0, readSize);
if (output != null) output.Write(buffer, 0, count);
_TotalBytesRead += count;
}
return (Int32)(~_register);
}
}
/// <summary>
/// Get the CRC32 for the given (word,byte) combo. This is a
/// computation defined by PKzip for PKZIP 2.0 (weak) encryption.
/// </summary>
/// <param name="W">The word to start with.</param>
/// <param name="B">The byte to combine it with.</param>
/// <returns>The CRC-ized result.</returns>
public Int32 ComputeCrc32(Int32 W, byte B)
{
return _InternalComputeCrc32((UInt32)W, B);
}
internal Int32 _InternalComputeCrc32(UInt32 W, byte B)
{
return (Int32)(crc32Table[(W ^ B) & 0xFF] ^ (W >> 8));
}
/// <summary>
/// Update the value for the running CRC32 using the given block of bytes.
/// This is useful when using the CRC32() class in a Stream.
/// </summary>
/// <param name="block">block of bytes to slurp</param>
/// <param name="offset">starting point in the block</param>
/// <param name="count">how many bytes within the block to slurp</param>
public void SlurpBlock(byte[] block, int offset, int count)
{
if (block == null)
throw new Exception("The data buffer must not be null.");
// bzip algorithm
for (int i = 0; i < count; i++)
{
int x = offset + i;
byte b = block[x];
if (this.reverseBits)
{
UInt32 temp = (_register >> 24) ^ b;
_register = (_register << 8) ^ crc32Table[temp];
}
else
{
UInt32 temp = (_register & 0x000000FF) ^ b;
_register = (_register >> 8) ^ crc32Table[temp];
}
}
_TotalBytesRead += count;
}
/// <summary>
/// Process one byte in the CRC.
/// </summary>
/// <param name = "b">the byte to include into the CRC . </param>
public void UpdateCRC(byte b)
{
if (this.reverseBits)
{
UInt32 temp = (_register >> 24) ^ b;
_register = (_register << 8) ^ crc32Table[temp];
}
else
{
UInt32 temp = (_register & 0x000000FF) ^ b;
_register = (_register >> 8) ^ crc32Table[temp];
}
}
/// <summary>
/// Process a run of N identical bytes into the CRC.
/// </summary>
/// <remarks>
/// <para>
/// This method serves as an optimization for updating the CRC when a
/// run of identical bytes is found. Rather than passing in a buffer of
/// length n, containing all identical bytes b, this method accepts the
/// byte value and the length of the (virtual) buffer - the length of
/// the run.
/// </para>
/// </remarks>
/// <param name = "b">the byte to include into the CRC. </param>
/// <param name = "n">the number of times that byte should be repeated. </param>
public void UpdateCRC(byte b, int n)
{
while (n-- > 0)
{
if (this.reverseBits)
{
uint temp = (_register >> 24) ^ b;
_register = (_register << 8) ^ crc32Table[(temp >= 0)
? temp
: (temp + 256)];
}
else
{
UInt32 temp = (_register & 0x000000FF) ^ b;
_register = (_register >> 8) ^ crc32Table[(temp >= 0)
? temp
: (temp + 256)];
}
}
}
private static uint ReverseBits(uint data)
{
unchecked
{
uint ret = data;
ret = (ret & 0x55555555) << 1 | (ret >> 1) & 0x55555555;
ret = (ret & 0x33333333) << 2 | (ret >> 2) & 0x33333333;
ret = (ret & 0x0F0F0F0F) << 4 | (ret >> 4) & 0x0F0F0F0F;
ret = (ret << 24) | ((ret & 0xFF00) << 8) | ((ret >> 8) & 0xFF00) | (ret >> 24);
return ret;
}
}
private static byte ReverseBits(byte data)
{
unchecked
{
uint u = (uint)data * 0x00020202;
uint m = 0x01044010;
uint s = u & m;
uint t = (u << 2) & (m << 1);
return (byte)((0x01001001 * (s + t)) >> 24);
}
}
private void GenerateLookupTable()
{
crc32Table = new UInt32[256];
unchecked
{
UInt32 dwCrc;
byte i = 0;
do
{
dwCrc = i;
for (byte j = 8; j > 0; j--)
{
if ((dwCrc & 1) == 1)
{
dwCrc = (dwCrc >> 1) ^ dwPolynomial;
}
else
{
dwCrc >>= 1;
}
}
if (reverseBits)
{
crc32Table[ReverseBits(i)] = ReverseBits(dwCrc);
}
else
{
crc32Table[i] = dwCrc;
}
i++;
} while (i != 0);
}
#if VERBOSE
Console.WriteLine();
Console.WriteLine("private static readonly UInt32[] crc32Table = {");
for (int i = 0; i < crc32Table.Length; i+=4)
{
Console.Write(" ");
for (int j=0; j < 4; j++)
{
Console.Write(" 0x{0:X8}U,", crc32Table[i+j]);
}
Console.WriteLine();
}
Console.WriteLine("};");
Console.WriteLine();
#endif
}
private uint gf2_matrix_times(uint[] matrix, uint vec)
{
uint sum = 0;
int i = 0;
while (vec != 0)
{
if ((vec & 0x01) == 0x01)
sum ^= matrix[i];
vec >>= 1;
i++;
}
return sum;
}
private void gf2_matrix_square(uint[] square, uint[] mat)
{
for (int i = 0; i < 32; i++)
square[i] = gf2_matrix_times(mat, mat[i]);
}
/// <summary>
/// Combines the given CRC32 value with the current running total.
/// </summary>
/// <remarks>
/// This is useful when using a divide-and-conquer approach to
/// calculating a CRC. Multiple threads can each calculate a
/// CRC32 on a segment of the data, and then combine the
/// individual CRC32 values at the end.
/// </remarks>
/// <param name="crc">the crc value to be combined with this one</param>
/// <param name="length">the length of data the CRC value was calculated on</param>
public void Combine(int crc, int length)
{
uint[] even = new uint[32]; // even-power-of-two zeros operator
uint[] odd = new uint[32]; // odd-power-of-two zeros operator
if (length == 0)
return;
uint crc1 = ~_register;
uint crc2 = (uint)crc;
// put operator for one zero bit in odd
odd[0] = this.dwPolynomial; // the CRC-32 polynomial
uint row = 1;
for (int i = 1; i < 32; i++)
{
odd[i] = row;
row <<= 1;
}
// put operator for two zero bits in even
gf2_matrix_square(even, odd);
// put operator for four zero bits in odd
gf2_matrix_square(odd, even);
uint len2 = (uint)length;
// apply len2 zeros to crc1 (first square will put the operator for one
// zero byte, eight zero bits, in even)
do
{
// apply zeros operator for this bit of len2
gf2_matrix_square(even, odd);
if ((len2 & 1) == 1)
crc1 = gf2_matrix_times(even, crc1);
len2 >>= 1;
if (len2 == 0)
break;
// another iteration of the loop with odd and even swapped
gf2_matrix_square(odd, even);
if ((len2 & 1) == 1)
crc1 = gf2_matrix_times(odd, crc1);
len2 >>= 1;
} while (len2 != 0);
crc1 ^= crc2;
_register = ~crc1;
//return (int) crc1;
return;
}
/// <summary>
/// Create an instance of the CRC32 class using the default settings: no
/// bit reversal, and a polynomial of 0xEDB88320.
/// </summary>
public CRC32()
: this(false)
{
}
/// <summary>
/// Create an instance of the CRC32 class, specifying whether to reverse
/// data bits or not.
/// </summary>
/// <param name='reverseBits'>
/// specify true if the instance should reverse data bits.
/// </param>
/// <remarks>
/// <para>
/// In the CRC-32 used by BZip2, the bits are reversed. Therefore if you
/// want a CRC32 with compatibility with BZip2, you should pass true
/// here. In the CRC-32 used by GZIP and PKZIP, the bits are not
/// reversed; Therefore if you want a CRC32 with compatibility with
/// those, you should pass false.
/// </para>
/// </remarks>
public CRC32(bool reverseBits) :
this(unchecked((int)0xEDB88320), reverseBits)
{
}
/// <summary>
/// Create an instance of the CRC32 class, specifying the polynomial and
/// whether to reverse data bits or not.
/// </summary>
/// <param name='polynomial'>
/// The polynomial to use for the CRC, expressed in the reversed (LSB)
/// format: the highest ordered bit in the polynomial value is the
/// coefficient of the 0th power; the second-highest order bit is the
/// coefficient of the 1 power, and so on. Expressed this way, the
/// polynomial for the CRC-32C used in IEEE 802.3, is 0xEDB88320.
/// </param>
/// <param name='reverseBits'>
/// specify true if the instance should reverse data bits.
/// </param>
///
/// <remarks>
/// <para>
/// In the CRC-32 used by BZip2, the bits are reversed. Therefore if you
/// want a CRC32 with compatibility with BZip2, you should pass true
/// here for the <c>reverseBits</c> parameter. In the CRC-32 used by
/// GZIP and PKZIP, the bits are not reversed; Therefore if you want a
/// CRC32 with compatibility with those, you should pass false for the
/// <c>reverseBits</c> parameter.
/// </para>
/// </remarks>
public CRC32(int polynomial, bool reverseBits)
{
this.reverseBits = reverseBits;
this.dwPolynomial = (uint)polynomial;
this.GenerateLookupTable();
}
/// <summary>
/// Reset the CRC-32 class - clear the CRC "remainder register."
/// </summary>
/// <remarks>
/// <para>
/// Use this when employing a single instance of this class to compute
/// multiple, distinct CRCs on multiple, distinct data blocks.
/// </para>
/// </remarks>
public void Reset()
{
_register = 0xFFFFFFFFU;
}
// private member vars
private UInt32 dwPolynomial;
private Int64 _TotalBytesRead;
private bool reverseBits;
private UInt32[] crc32Table;
private const int BUFFER_SIZE = 8192;
private UInt32 _register = 0xFFFFFFFFU;
}
/// <summary>
/// A Stream that calculates a CRC32 (a checksum) on all bytes read,
/// or on all bytes written.
/// </summary>
///
/// <remarks>
/// <para>
/// This class can be used to verify the CRC of a ZipEntry when
/// reading from a stream, or to calculate a CRC when writing to a
/// stream. The stream should be used to either read, or write, but
/// not both. If you intermix reads and writes, the results are not
/// defined.
/// </para>
///
/// <para>
/// This class is intended primarily for use internally by the
/// DotNetZip library.
/// </para>
/// </remarks>
public class CrcCalculatorStream : System.IO.Stream, System.IDisposable
{
private static readonly Int64 UnsetLengthLimit = -99;
internal System.IO.Stream _innerStream;
private CRC32 _Crc32;
private Int64 _lengthLimit = -99;
private bool _leaveOpen;
/// <summary>
/// The default constructor.
/// </summary>
/// <remarks>
/// <para>
/// Instances returned from this constructor will leave the underlying
/// stream open upon Close(). The stream uses the default CRC32
/// algorithm, which implies a polynomial of 0xEDB88320.
/// </para>
/// </remarks>
/// <param name="stream">The underlying stream</param>
public CrcCalculatorStream(System.IO.Stream stream)
: this(true, CrcCalculatorStream.UnsetLengthLimit, stream, null)
{
}
/// <summary>
/// The constructor allows the caller to specify how to handle the
/// underlying stream at close.
/// </summary>
/// <remarks>
/// <para>
/// The stream uses the default CRC32 algorithm, which implies a
/// polynomial of 0xEDB88320.
/// </para>
/// </remarks>
/// <param name="stream">The underlying stream</param>
/// <param name="leaveOpen">true to leave the underlying stream
/// open upon close of the <c>CrcCalculatorStream</c>; false otherwise.</param>
public CrcCalculatorStream(System.IO.Stream stream, bool leaveOpen)
: this(leaveOpen, CrcCalculatorStream.UnsetLengthLimit, stream, null)
{
}
/// <summary>
/// A constructor allowing the specification of the length of the stream
/// to read.
/// </summary>
/// <remarks>
/// <para>
/// The stream uses the default CRC32 algorithm, which implies a
/// polynomial of 0xEDB88320.
/// </para>
/// <para>
/// Instances returned from this constructor will leave the underlying
/// stream open upon Close().
/// </para>
/// </remarks>
/// <param name="stream">The underlying stream</param>
/// <param name="length">The length of the stream to slurp</param>
public CrcCalculatorStream(System.IO.Stream stream, Int64 length)
: this(true, length, stream, null)
{
if (length < 0)
throw new ArgumentException("length");
}
/// <summary>
/// A constructor allowing the specification of the length of the stream
/// to read, as well as whether to keep the underlying stream open upon
/// Close().
/// </summary>
/// <remarks>
/// <para>
/// The stream uses the default CRC32 algorithm, which implies a
/// polynomial of 0xEDB88320.
/// </para>
/// </remarks>
/// <param name="stream">The underlying stream</param>
/// <param name="length">The length of the stream to slurp</param>
/// <param name="leaveOpen">true to leave the underlying stream
/// open upon close of the <c>CrcCalculatorStream</c>; false otherwise.</param>
public CrcCalculatorStream(System.IO.Stream stream, Int64 length, bool leaveOpen)
: this(leaveOpen, length, stream, null)
{
if (length < 0)
throw new ArgumentException("length");
}
/// <summary>
/// A constructor allowing the specification of the length of the stream
/// to read, as well as whether to keep the underlying stream open upon
/// Close(), and the CRC32 instance to use.
/// </summary>
/// <remarks>
/// <para>
/// The stream uses the specified CRC32 instance, which allows the
/// application to specify how the CRC gets calculated.
/// </para>
/// </remarks>
/// <param name="stream">The underlying stream</param>
/// <param name="length">The length of the stream to slurp</param>
/// <param name="leaveOpen">true to leave the underlying stream
/// open upon close of the <c>CrcCalculatorStream</c>; false otherwise.</param>
/// <param name="crc32">the CRC32 instance to use to calculate the CRC32</param>
public CrcCalculatorStream(System.IO.Stream stream, Int64 length, bool leaveOpen,
CRC32 crc32)
: this(leaveOpen, length, stream, crc32)
{
if (length < 0)
throw new ArgumentException("length");
}
// This ctor is private - no validation is done here. This is to allow the use
// of a (specific) negative value for the _lengthLimit, to indicate that there
// is no length set. So we validate the length limit in those ctors that use an
// explicit param, otherwise we don't validate, because it could be our special
// value.
private CrcCalculatorStream
(bool leaveOpen, Int64 length, System.IO.Stream stream, CRC32 crc32)
: base()
{
_innerStream = stream;
_Crc32 = crc32 ?? new CRC32();
_lengthLimit = length;
_leaveOpen = leaveOpen;
}
/// <summary>
/// Gets the total number of bytes run through the CRC32 calculator.
/// </summary>
///
/// <remarks>
/// This is either the total number of bytes read, or the total number of
/// bytes written, depending on the direction of this stream.
/// </remarks>
public Int64 TotalBytesSlurped
{
get { return _Crc32.TotalBytesRead; }
}
/// <summary>
/// Provides the current CRC for all blocks slurped in.
/// </summary>
/// <remarks>
/// <para>
/// The running total of the CRC is kept as data is written or read
/// through the stream. read this property after all reads or writes to
/// get an accurate CRC for the entire stream.
/// </para>
/// </remarks>
public Int32 Crc
{
get { return _Crc32.Crc32Result; }
}
/// <summary>
/// Indicates whether the underlying stream will be left open when the
/// <c>CrcCalculatorStream</c> is Closed.
/// </summary>
/// <remarks>
/// <para>
/// Set this at any point before calling <see cref="Close()"/>.
/// </para>
/// </remarks>
public bool LeaveOpen
{
get { return _leaveOpen; }
set { _leaveOpen = value; }
}
/// <summary>
/// Read from the stream
/// </summary>
/// <param name="buffer">the buffer to read</param>
/// <param name="offset">the offset at which to start</param>
/// <param name="count">the number of bytes to read</param>
/// <returns>the number of bytes actually read</returns>
public override int Read(byte[] buffer, int offset, int count)
{
int bytesToRead = count;
// Need to limit the # of bytes returned, if the stream is intended to have
// a definite length. This is especially useful when returning a stream for
// the uncompressed data directly to the application. The app won't
// necessarily read only the UncompressedSize number of bytes. For example
// wrapping the stream returned from OpenReader() into a StreadReader() and
// calling ReadToEnd() on it, We can "over-read" the zip data and get a
// corrupt string. The length limits that, prevents that problem.
if (_lengthLimit != CrcCalculatorStream.UnsetLengthLimit)
{
if (_Crc32.TotalBytesRead >= _lengthLimit) return 0; // EOF
Int64 bytesRemaining = _lengthLimit - _Crc32.TotalBytesRead;
if (bytesRemaining < count) bytesToRead = (int)bytesRemaining;
}
int n = _innerStream.Read(buffer, offset, bytesToRead);
if (n > 0) _Crc32.SlurpBlock(buffer, offset, n);
return n;
}
/// <summary>
/// Write to the stream.
/// </summary>
/// <param name="buffer">the buffer from which to write</param>
/// <param name="offset">the offset at which to start writing</param>
/// <param name="count">the number of bytes to write</param>
public override void Write(byte[] buffer, int offset, int count)
{
if (count > 0) _Crc32.SlurpBlock(buffer, offset, count);
_innerStream.Write(buffer, offset, count);
}
/// <summary>
/// Indicates whether the stream supports reading.
/// </summary>
public override bool CanRead
{
get { return _innerStream.CanRead; }
}
/// <summary>
/// Indicates whether the stream supports seeking.
/// </summary>
/// <remarks>
/// <para>
/// Always returns false.
/// </para>
/// </remarks>
public override bool CanSeek
{
get { return false; }
}
/// <summary>
/// Indicates whether the stream supports writing.
/// </summary>
public override bool CanWrite
{
get { return _innerStream.CanWrite; }
}
/// <summary>
/// Flush the stream.
/// </summary>
public override void Flush()
{
_innerStream.Flush();
}
/// <summary>
/// Returns the length of the underlying stream.
/// </summary>
public override long Length
{
get
{
if (_lengthLimit == CrcCalculatorStream.UnsetLengthLimit)
return _innerStream.Length;
else return _lengthLimit;
}
}
/// <summary>
/// The getter for this property returns the total bytes read.
/// If you use the setter, it will throw
/// <see cref="NotSupportedException"/>.
/// </summary>
public override long Position
{
get { return _Crc32.TotalBytesRead; }
set { throw new NotSupportedException(); }
}
/// <summary>
/// Seeking is not supported on this stream. This method always throws
/// <see cref="NotSupportedException"/>
/// </summary>
/// <param name="offset">N/A</param>
/// <param name="origin">N/A</param>
/// <returns>N/A</returns>
public override long Seek(long offset, System.IO.SeekOrigin origin)
{
throw new NotSupportedException();
}
/// <summary>
/// This method always throws
/// <see cref="NotSupportedException"/>
/// </summary>
/// <param name="value">N/A</param>
public override void SetLength(long value)
{
throw new NotSupportedException();
}
void IDisposable.Dispose()
{
Close();
}
/// <summary>
/// Closes the stream.
/// </summary>
public override void Close()
{
base.Close();
if (!_leaveOpen)
_innerStream.Close();
}
}
public class CRC32Hash : HashAlgorithm
{
private CRC32 _Crc32=new CRC32();
public override void Initialize()
{
_Crc32.Reset();
}
protected override void HashCore(byte[] buffer, int start, int length)
{
_Crc32.SlurpBlock(buffer, start, length);
}
protected override byte[] HashFinal()
{
uint crcValue =(uint) _Crc32.Crc32Result;
HashValue = new[]
{
(byte) ((crcValue >> 24) & 0xff),
(byte) ((crcValue >> 16) & 0xff),
(byte) ((crcValue >> 8) & 0xff),
(byte) (crcValue & 0xff)
};
return HashValue;
}
public override int HashSize
{
get { return 32; }
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,740 @@
// DeflateStream.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009-2010 Dino Chiesa.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// last saved (in emacs):
// Time-stamp: <2011-July-31 14:48:11>
//
// ------------------------------------------------------------------
//
// This module defines the DeflateStream class, which can be used as a replacement for
// the System.IO.Compression.DeflateStream class in the .NET BCL.
//
// ------------------------------------------------------------------
using System;
namespace ROMVault2.SupportedFiles.Zip.ZLib
{
/// <summary>
/// A class for compressing and decompressing streams using the Deflate algorithm.
/// </summary>
///
/// <remarks>
///
/// <para>
/// The DeflateStream is a <see
/// href="http://en.wikipedia.org/wiki/Decorator_pattern">Decorator</see> on a <see
/// cref="System.IO.Stream"/>. It adds DEFLATE compression or decompression to any
/// stream.
/// </para>
///
/// <para>
/// Using this stream, applications can compress or decompress data via stream
/// <c>Read</c> and <c>Write</c> operations. Either compresssion or decompression
/// can occur through either reading or writing. The compression format used is
/// DEFLATE, which is documented in <see
/// href="http://www.ietf.org/rfc/rfc1951.txt">IETF RFC 1951</see>, "DEFLATE
/// Compressed Data Format Specification version 1.3.".
/// </para>
///
/// <para>
/// This class is similar to <see cref="ZlibStream"/>, except that
/// <c>ZlibStream</c> adds the <see href="http://www.ietf.org/rfc/rfc1950.txt">RFC
/// 1950 - ZLIB</see> framing bytes to a compressed stream when compressing, or
/// expects the RFC1950 framing bytes when decompressing. The <c>DeflateStream</c>
/// does not.
/// </para>
///
/// </remarks>
///
/// <seealso cref="ZlibStream" />
/// <seealso cref="GZipStream" />
public class DeflateStream : System.IO.Stream
{
internal ZlibBaseStream _baseStream;
internal System.IO.Stream _innerStream;
bool _disposed;
/// <summary>
/// Create a DeflateStream using the specified CompressionMode.
/// </summary>
///
/// <remarks>
/// When mode is <c>CompressionMode.Compress</c>, the DeflateStream will use
/// the default compression level. The "captive" stream will be closed when
/// the DeflateStream is closed.
/// </remarks>
///
/// <example>
/// This example uses a DeflateStream to compress data from a file, and writes
/// the compressed data to another file.
/// <code>
/// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
/// {
/// using (var raw = System.IO.File.Create(fileToCompress + ".deflated"))
/// {
/// using (Stream compressor = new DeflateStream(raw, CompressionMode.Compress))
/// {
/// byte[] buffer = new byte[WORKING_BUFFER_SIZE];
/// int n;
/// while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
/// {
/// compressor.Write(buffer, 0, n);
/// }
/// }
/// }
/// }
/// </code>
///
/// <code lang="VB">
/// Using input As Stream = File.OpenRead(fileToCompress)
/// Using raw As FileStream = File.Create(fileToCompress &amp; ".deflated")
/// Using compressor As Stream = New DeflateStream(raw, CompressionMode.Compress)
/// Dim buffer As Byte() = New Byte(4096) {}
/// Dim n As Integer = -1
/// Do While (n &lt;&gt; 0)
/// If (n &gt; 0) Then
/// compressor.Write(buffer, 0, n)
/// End If
/// n = input.Read(buffer, 0, buffer.Length)
/// Loop
/// End Using
/// End Using
/// End Using
/// </code>
/// </example>
/// <param name="stream">The stream which will be read or written.</param>
/// <param name="mode">Indicates whether the DeflateStream will compress or decompress.</param>
public DeflateStream(System.IO.Stream stream, CompressionMode mode)
: this(stream, mode, CompressionLevel.Default, false)
{
}
/// <summary>
/// Create a DeflateStream using the specified CompressionMode and the specified CompressionLevel.
/// </summary>
///
/// <remarks>
///
/// <para>
/// When mode is <c>CompressionMode.Decompress</c>, the level parameter is
/// ignored. The "captive" stream will be closed when the DeflateStream is
/// closed.
/// </para>
///
/// </remarks>
///
/// <example>
///
/// This example uses a DeflateStream to compress data from a file, and writes
/// the compressed data to another file.
///
/// <code>
/// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
/// {
/// using (var raw = System.IO.File.Create(fileToCompress + ".deflated"))
/// {
/// using (Stream compressor = new DeflateStream(raw,
/// CompressionMode.Compress,
/// CompressionLevel.BestCompression))
/// {
/// byte[] buffer = new byte[WORKING_BUFFER_SIZE];
/// int n= -1;
/// while (n != 0)
/// {
/// if (n &gt; 0)
/// compressor.Write(buffer, 0, n);
/// n= input.Read(buffer, 0, buffer.Length);
/// }
/// }
/// }
/// }
/// </code>
///
/// <code lang="VB">
/// Using input As Stream = File.OpenRead(fileToCompress)
/// Using raw As FileStream = File.Create(fileToCompress &amp; ".deflated")
/// Using compressor As Stream = New DeflateStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression)
/// Dim buffer As Byte() = New Byte(4096) {}
/// Dim n As Integer = -1
/// Do While (n &lt;&gt; 0)
/// If (n &gt; 0) Then
/// compressor.Write(buffer, 0, n)
/// End If
/// n = input.Read(buffer, 0, buffer.Length)
/// Loop
/// End Using
/// End Using
/// End Using
/// </code>
/// </example>
/// <param name="stream">The stream to be read or written while deflating or inflating.</param>
/// <param name="mode">Indicates whether the <c>DeflateStream</c> will compress or decompress.</param>
/// <param name="level">A tuning knob to trade speed for effectiveness.</param>
public DeflateStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level)
: this(stream, mode, level, false)
{
}
/// <summary>
/// Create a <c>DeflateStream</c> using the specified
/// <c>CompressionMode</c>, and explicitly specify whether the
/// stream should be left open after Deflation or Inflation.
/// </summary>
///
/// <remarks>
///
/// <para>
/// This constructor allows the application to request that the captive stream
/// remain open after the deflation or inflation occurs. By default, after
/// <c>Close()</c> is called on the stream, the captive stream is also
/// closed. In some cases this is not desired, for example if the stream is a
/// memory stream that will be re-read after compression. Specify true for
/// the <paramref name="leaveOpen"/> parameter to leave the stream open.
/// </para>
///
/// <para>
/// The <c>DeflateStream</c> will use the default compression level.
/// </para>
///
/// <para>
/// See the other overloads of this constructor for example code.
/// </para>
/// </remarks>
///
/// <param name="stream">
/// The stream which will be read or written. This is called the
/// "captive" stream in other places in this documentation.
/// </param>
///
/// <param name="mode">
/// Indicates whether the <c>DeflateStream</c> will compress or decompress.
/// </param>
///
/// <param name="leaveOpen">true if the application would like the stream to
/// remain open after inflation/deflation.</param>
public DeflateStream(System.IO.Stream stream, CompressionMode mode, bool leaveOpen)
: this(stream, mode, CompressionLevel.Default, leaveOpen)
{
}
/// <summary>
/// Create a <c>DeflateStream</c> using the specified <c>CompressionMode</c>
/// and the specified <c>CompressionLevel</c>, and explicitly specify whether
/// the stream should be left open after Deflation or Inflation.
/// </summary>
///
/// <remarks>
///
/// <para>
/// When mode is <c>CompressionMode.Decompress</c>, the level parameter is ignored.
/// </para>
///
/// <para>
/// This constructor allows the application to request that the captive stream
/// remain open after the deflation or inflation occurs. By default, after
/// <c>Close()</c> is called on the stream, the captive stream is also
/// closed. In some cases this is not desired, for example if the stream is a
/// <see cref="System.IO.MemoryStream"/> that will be re-read after
/// compression. Specify true for the <paramref name="leaveOpen"/> parameter
/// to leave the stream open.
/// </para>
///
/// </remarks>
///
/// <example>
///
/// This example shows how to use a <c>DeflateStream</c> to compress data from
/// a file, and store the compressed data into another file.
///
/// <code>
/// using (var output = System.IO.File.Create(fileToCompress + ".deflated"))
/// {
/// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
/// {
/// using (Stream compressor = new DeflateStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, true))
/// {
/// byte[] buffer = new byte[WORKING_BUFFER_SIZE];
/// int n= -1;
/// while (n != 0)
/// {
/// if (n &gt; 0)
/// compressor.Write(buffer, 0, n);
/// n= input.Read(buffer, 0, buffer.Length);
/// }
/// }
/// }
/// // can write additional data to the output stream here
/// }
/// </code>
///
/// <code lang="VB">
/// Using output As FileStream = File.Create(fileToCompress &amp; ".deflated")
/// Using input As Stream = File.OpenRead(fileToCompress)
/// Using compressor As Stream = New DeflateStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, True)
/// Dim buffer As Byte() = New Byte(4096) {}
/// Dim n As Integer = -1
/// Do While (n &lt;&gt; 0)
/// If (n &gt; 0) Then
/// compressor.Write(buffer, 0, n)
/// End If
/// n = input.Read(buffer, 0, buffer.Length)
/// Loop
/// End Using
/// End Using
/// ' can write additional data to the output stream here.
/// End Using
/// </code>
/// </example>
/// <param name="stream">The stream which will be read or written.</param>
/// <param name="mode">Indicates whether the DeflateStream will compress or decompress.</param>
/// <param name="leaveOpen">true if the application would like the stream to remain open after inflation/deflation.</param>
/// <param name="level">A tuning knob to trade speed for effectiveness.</param>
public DeflateStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen)
{
_innerStream = stream;
_baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.DEFLATE, leaveOpen);
}
#region Zlib properties
/// <summary>
/// This property sets the flush behavior on the stream.
/// </summary>
/// <remarks> See the ZLIB documentation for the meaning of the flush behavior.
/// </remarks>
virtual public FlushType FlushMode
{
get { return (this._baseStream._flushMode); }
set
{
if (_disposed) throw new ObjectDisposedException("DeflateStream");
this._baseStream._flushMode = value;
}
}
/// <summary>
/// The size of the working buffer for the compression codec.
/// </summary>
///
/// <remarks>
/// <para>
/// The working buffer is used for all stream operations. The default size is
/// 1024 bytes. The minimum size is 128 bytes. You may get better performance
/// with a larger buffer. Then again, you might not. You would have to test
/// it.
/// </para>
///
/// <para>
/// Set this before the first call to <c>Read()</c> or <c>Write()</c> on the
/// stream. If you try to set it afterwards, it will throw.
/// </para>
/// </remarks>
public int BufferSize
{
get
{
return this._baseStream._bufferSize;
}
set
{
if (_disposed) throw new ObjectDisposedException("DeflateStream");
if (this._baseStream._workingBuffer != null)
throw new ZlibException("The working buffer is already set.");
if (value < ZlibConstants.WorkingBufferSizeMin)
throw new ZlibException(String.Format("Don't be silly. {0} bytes?? Use a bigger buffer, at least {1}.", value, ZlibConstants.WorkingBufferSizeMin));
this._baseStream._bufferSize = value;
}
}
/// <summary>
/// The ZLIB strategy to be used during compression.
/// </summary>
///
/// <remarks>
/// By tweaking this parameter, you may be able to optimize the compression for
/// data with particular characteristics.
/// </remarks>
public CompressionStrategy Strategy
{
get
{
return this._baseStream.Strategy;
}
set
{
if (_disposed) throw new ObjectDisposedException("DeflateStream");
this._baseStream.Strategy = value;
}
}
/// <summary> Returns the total number of bytes input so far.</summary>
virtual public long TotalIn
{
get
{
return this._baseStream._z.TotalBytesIn;
}
}
/// <summary> Returns the total number of bytes output so far.</summary>
virtual public long TotalOut
{
get
{
return this._baseStream._z.TotalBytesOut;
}
}
#endregion
#region System.IO.Stream methods
/// <summary>
/// Dispose the stream.
/// </summary>
/// <remarks>
/// <para>
/// This may or may not result in a <c>Close()</c> call on the captive
/// stream. See the constructors that have a <c>leaveOpen</c> parameter
/// for more information.
/// </para>
/// <para>
/// Application code won't call this code directly. This method may be
/// invoked in two distinct scenarios. If disposing == true, the method
/// has been called directly or indirectly by a user's code, for example
/// via the public Dispose() method. In this case, both managed and
/// unmanaged resources can be referenced and disposed. If disposing ==
/// false, the method has been called by the runtime from inside the
/// object finalizer and this method should not reference other objects;
/// in that case only unmanaged resources must be referenced or
/// disposed.
/// </para>
/// </remarks>
/// <param name="disposing">
/// true if the Dispose method was invoked by user code.
/// </param>
protected override void Dispose(bool disposing)
{
try
{
if (!_disposed)
{
if (disposing && (this._baseStream != null))
this._baseStream.Close();
_disposed = true;
}
}
finally
{
base.Dispose(disposing);
}
}
/// <summary>
/// Indicates whether the stream can be read.
/// </summary>
/// <remarks>
/// The return value depends on whether the captive stream supports reading.
/// </remarks>
public override bool CanRead
{
get
{
if (_disposed) throw new ObjectDisposedException("DeflateStream");
return _baseStream._stream.CanRead;
}
}
/// <summary>
/// Indicates whether the stream supports Seek operations.
/// </summary>
/// <remarks>
/// Always returns false.
/// </remarks>
public override bool CanSeek
{
get { return false; }
}
/// <summary>
/// Indicates whether the stream can be written.
/// </summary>
/// <remarks>
/// The return value depends on whether the captive stream supports writing.
/// </remarks>
public override bool CanWrite
{
get
{
if (_disposed) throw new ObjectDisposedException("DeflateStream");
return _baseStream._stream.CanWrite;
}
}
/// <summary>
/// Flush the stream.
/// </summary>
public override void Flush()
{
if (_disposed) throw new ObjectDisposedException("DeflateStream");
_baseStream.Flush();
}
/// <summary>
/// Reading this property always throws a <see cref="NotImplementedException"/>.
/// </summary>
public override long Length
{
get { throw new NotImplementedException(); }
}
/// <summary>
/// The position of the stream pointer.
/// </summary>
///
/// <remarks>
/// Setting this property always throws a <see
/// cref="NotImplementedException"/>. Reading will return the total bytes
/// written out, if used in writing, or the total bytes read in, if used in
/// reading. The count may refer to compressed bytes or uncompressed bytes,
/// depending on how you've used the stream.
/// </remarks>
public override long Position
{
get
{
if (this._baseStream._streamMode == ZlibBaseStream.StreamMode.Writer)
return this._baseStream._z.TotalBytesOut;
if (this._baseStream._streamMode == ZlibBaseStream.StreamMode.Reader)
return this._baseStream._z.TotalBytesIn;
return 0;
}
set { throw new NotImplementedException(); }
}
/// <summary>
/// Read data from the stream.
/// </summary>
/// <remarks>
///
/// <para>
/// If you wish to use the <c>DeflateStream</c> to compress data while
/// reading, you can create a <c>DeflateStream</c> with
/// <c>CompressionMode.Compress</c>, providing an uncompressed data stream.
/// Then call Read() on that <c>DeflateStream</c>, and the data read will be
/// compressed as you read. If you wish to use the <c>DeflateStream</c> to
/// decompress data while reading, you can create a <c>DeflateStream</c> with
/// <c>CompressionMode.Decompress</c>, providing a readable compressed data
/// stream. Then call Read() on that <c>DeflateStream</c>, and the data read
/// will be decompressed as you read.
/// </para>
///
/// <para>
/// A <c>DeflateStream</c> can be used for <c>Read()</c> or <c>Write()</c>, but not both.
/// </para>
///
/// </remarks>
/// <param name="buffer">The buffer into which the read data should be placed.</param>
/// <param name="offset">the offset within that data array to put the first byte read.</param>
/// <param name="count">the number of bytes to read.</param>
/// <returns>the number of bytes actually read</returns>
public override int Read(byte[] buffer, int offset, int count)
{
if (_disposed) throw new ObjectDisposedException("DeflateStream");
return _baseStream.Read(buffer, offset, count);
}
/// <summary>
/// Calling this method always throws a <see cref="NotImplementedException"/>.
/// </summary>
/// <param name="offset">this is irrelevant, since it will always throw!</param>
/// <param name="origin">this is irrelevant, since it will always throw!</param>
/// <returns>irrelevant!</returns>
public override long Seek(long offset, System.IO.SeekOrigin origin)
{
throw new NotImplementedException();
}
/// <summary>
/// Calling this method always throws a <see cref="NotImplementedException"/>.
/// </summary>
/// <param name="value">this is irrelevant, since it will always throw!</param>
public override void SetLength(long value)
{
throw new NotImplementedException();
}
/// <summary>
/// Write data to the stream.
/// </summary>
/// <remarks>
///
/// <para>
/// If you wish to use the <c>DeflateStream</c> to compress data while
/// writing, you can create a <c>DeflateStream</c> with
/// <c>CompressionMode.Compress</c>, and a writable output stream. Then call
/// <c>Write()</c> on that <c>DeflateStream</c>, providing uncompressed data
/// as input. The data sent to the output stream will be the compressed form
/// of the data written. If you wish to use the <c>DeflateStream</c> to
/// decompress data while writing, you can create a <c>DeflateStream</c> with
/// <c>CompressionMode.Decompress</c>, and a writable output stream. Then
/// call <c>Write()</c> on that stream, providing previously compressed
/// data. The data sent to the output stream will be the decompressed form of
/// the data written.
/// </para>
///
/// <para>
/// A <c>DeflateStream</c> can be used for <c>Read()</c> or <c>Write()</c>,
/// but not both.
/// </para>
///
/// </remarks>
///
/// <param name="buffer">The buffer holding data to write to the stream.</param>
/// <param name="offset">the offset within that data array to find the first byte to write.</param>
/// <param name="count">the number of bytes to write.</param>
public override void Write(byte[] buffer, int offset, int count)
{
if (_disposed) throw new ObjectDisposedException("DeflateStream");
_baseStream.Write(buffer, offset, count);
}
#endregion
/// <summary>
/// Compress a string into a byte array using DEFLATE (RFC 1951).
/// </summary>
///
/// <remarks>
/// Uncompress it with <see cref="DeflateStream.UncompressString(byte[])"/>.
/// </remarks>
///
/// <seealso cref="DeflateStream.UncompressString(byte[])">DeflateStream.UncompressString(byte[])</seealso>
/// <seealso cref="DeflateStream.CompressBuffer(byte[])">DeflateStream.CompressBuffer(byte[])</seealso>
/// <seealso cref="GZipStream.CompressString(string)">GZipStream.CompressString(string)</seealso>
/// <seealso cref="ZlibStream.CompressString(string)">ZlibStream.CompressString(string)</seealso>
///
/// <param name="s">
/// A string to compress. The string will first be encoded
/// using UTF8, then compressed.
/// </param>
///
/// <returns>The string in compressed form</returns>
public static byte[] CompressString(String s)
{
using (var ms = new System.IO.MemoryStream())
{
System.IO.Stream compressor =
new DeflateStream(ms, CompressionMode.Compress, CompressionLevel.BestCompression);
ZlibBaseStream.CompressString(s, compressor);
return ms.ToArray();
}
}
/// <summary>
/// Compress a byte array into a new byte array using DEFLATE.
/// </summary>
///
/// <remarks>
/// Uncompress it with <see cref="DeflateStream.UncompressBuffer(byte[])"/>.
/// </remarks>
///
/// <seealso cref="DeflateStream.CompressString(string)">DeflateStream.CompressString(string)</seealso>
/// <seealso cref="DeflateStream.UncompressBuffer(byte[])">DeflateStream.UncompressBuffer(byte[])</seealso>
/// <seealso cref="GZipStream.CompressBuffer(byte[])">GZipStream.CompressBuffer(byte[])</seealso>
/// <seealso cref="ZlibStream.CompressBuffer(byte[])">ZlibStream.CompressBuffer(byte[])</seealso>
///
/// <param name="b">
/// A buffer to compress.
/// </param>
///
/// <returns>The data in compressed form</returns>
public static byte[] CompressBuffer(byte[] b)
{
using (var ms = new System.IO.MemoryStream())
{
System.IO.Stream compressor =
new DeflateStream( ms, CompressionMode.Compress, CompressionLevel.BestCompression );
ZlibBaseStream.CompressBuffer(b, compressor);
return ms.ToArray();
}
}
/// <summary>
/// Uncompress a DEFLATE'd byte array into a single string.
/// </summary>
///
/// <seealso cref="DeflateStream.CompressString(String)">DeflateStream.CompressString(String)</seealso>
/// <seealso cref="DeflateStream.UncompressBuffer(byte[])">DeflateStream.UncompressBuffer(byte[])</seealso>
/// <seealso cref="GZipStream.UncompressString(byte[])">GZipStream.UncompressString(byte[])</seealso>
/// <seealso cref="ZlibStream.UncompressString(byte[])">ZlibStream.UncompressString(byte[])</seealso>
///
/// <param name="compressed">
/// A buffer containing DEFLATE-compressed data.
/// </param>
///
/// <returns>The uncompressed string</returns>
public static String UncompressString(byte[] compressed)
{
using (var input = new System.IO.MemoryStream(compressed))
{
System.IO.Stream decompressor =
new DeflateStream(input, CompressionMode.Decompress);
return ZlibBaseStream.UncompressString(compressed, decompressor);
}
}
/// <summary>
/// Uncompress a DEFLATE'd byte array into a byte array.
/// </summary>
///
/// <seealso cref="DeflateStream.CompressBuffer(byte[])">DeflateStream.CompressBuffer(byte[])</seealso>
/// <seealso cref="DeflateStream.UncompressString(byte[])">DeflateStream.UncompressString(byte[])</seealso>
/// <seealso cref="GZipStream.UncompressBuffer(byte[])">GZipStream.UncompressBuffer(byte[])</seealso>
/// <seealso cref="ZlibStream.UncompressBuffer(byte[])">ZlibStream.UncompressBuffer(byte[])</seealso>
///
/// <param name="compressed">
/// A buffer containing data that has been compressed with DEFLATE.
/// </param>
///
/// <returns>The data in uncompressed form</returns>
public static byte[] UncompressBuffer(byte[] compressed)
{
using (var input = new System.IO.MemoryStream(compressed))
{
System.IO.Stream decompressor =
new DeflateStream( input, CompressionMode.Decompress );
return ZlibBaseStream.UncompressBuffer(compressed, decompressor);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,436 @@
// Inftree.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// last saved (in emacs):
// Time-stamp: <2009-October-28 12:43:54>
//
// ------------------------------------------------------------------
//
// This module defines classes used in decompression. This code is derived
// from the jzlib implementation of zlib. In keeping with the license for jzlib,
// the copyright to that code is below.
//
// ------------------------------------------------------------------
//
// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the distribution.
//
// 3. The names of the authors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------
//
// This program is based on zlib-1.1.3; credit to authors
// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
// and contributors of zlib.
//
// -----------------------------------------------------------------------
using System;
namespace ROMVault2.SupportedFiles.Zip.ZLib
{
sealed class InfTree
{
private const int MANY = 1440;
private const int Z_OK = 0;
private const int Z_STREAM_END = 1;
private const int Z_NEED_DICT = 2;
private const int Z_ERRNO = - 1;
private const int Z_STREAM_ERROR = - 2;
private const int Z_DATA_ERROR = - 3;
private const int Z_MEM_ERROR = - 4;
private const int Z_BUF_ERROR = - 5;
private const int Z_VERSION_ERROR = - 6;
internal const int fixed_bl = 9;
internal const int fixed_bd = 5;
//UPGRADE_NOTE: Final was removed from the declaration of 'fixed_tl'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly int[] fixed_tl = new int[]{96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 176, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 216, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 236, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 162, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186,
0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 190, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 193, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 209, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 249, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 229, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 181, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 221, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, 0, 8,
14, 0, 8, 142, 0, 8, 78, 0, 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 147, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 235, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 167, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 183, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 207, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255};
//UPGRADE_NOTE: Final was removed from the declaration of 'fixed_td'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly int[] fixed_td = new int[]{80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5, 8193, 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5, 24577, 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577};
// Tables for deflate from PKZIP's appnote.txt.
//UPGRADE_NOTE: Final was removed from the declaration of 'cplens'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly int[] cplens = new int[]{3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
// see note #13 above about 258
//UPGRADE_NOTE: Final was removed from the declaration of 'cplext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly int[] cplext = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112};
//UPGRADE_NOTE: Final was removed from the declaration of 'cpdist'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly int[] cpdist = new int[]{1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
//UPGRADE_NOTE: Final was removed from the declaration of 'cpdext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly int[] cpdext = new int[]{0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
// If BMAX needs to be larger than 16, then h and x[] should be uLong.
internal const int BMAX = 15; // maximum bit length of any code
internal int[] hn = null; // hufts used in space
internal int[] v = null; // work area for huft_build
internal int[] c = null; // bit length count table
internal int[] r = null; // table entry for structure assignment
internal int[] u = null; // table stack
internal int[] x = null; // bit offsets, then code stack
private int huft_build(int[] b, int bindex, int n, int s, int[] d, int[] e, int[] t, int[] m, int[] hp, int[] hn, int[] v)
{
// Given a list of code lengths and a maximum table size, make a set of
// tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
// if the given code set is incomplete (the tables are still built in this
// case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
// lengths), or Z_MEM_ERROR if not enough memory.
int a; // counter for codes of length k
int f; // i repeats in table every f entries
int g; // maximum code length
int h; // table level
int i; // counter, current code
int j; // counter
int k; // number of bits in current code
int l; // bits per table (returned in m)
int mask; // (1 << w) - 1, to avoid cc -O bug on HP
int p; // pointer into c[], b[], or v[]
int q; // points to current table
int w; // bits before this table == (l * h)
int xp; // pointer into x
int y; // number of dummy codes added
int z; // number of entries in current table
// Generate counts for each bit length
p = 0; i = n;
do
{
c[b[bindex + p]]++; p++; i--; // assume all entries <= BMAX
}
while (i != 0);
if (c[0] == n)
{
// null input--all zero length codes
t[0] = - 1;
m[0] = 0;
return Z_OK;
}
// Find minimum and maximum length, bound *m by those
l = m[0];
for (j = 1; j <= BMAX; j++)
if (c[j] != 0)
break;
k = j; // minimum code length
if (l < j)
{
l = j;
}
for (i = BMAX; i != 0; i--)
{
if (c[i] != 0)
break;
}
g = i; // maximum code length
if (l > i)
{
l = i;
}
m[0] = l;
// Adjust last length count to fill out codes, if needed
for (y = 1 << j; j < i; j++, y <<= 1)
{
if ((y -= c[j]) < 0)
{
return Z_DATA_ERROR;
}
}
if ((y -= c[i]) < 0)
{
return Z_DATA_ERROR;
}
c[i] += y;
// Generate starting offsets into the value table for each length
x[1] = j = 0;
p = 1; xp = 2;
while (--i != 0)
{
// note that i == g from above
x[xp] = (j += c[p]);
xp++;
p++;
}
// Make a table of values in order of bit lengths
i = 0; p = 0;
do
{
if ((j = b[bindex + p]) != 0)
{
v[x[j]++] = i;
}
p++;
}
while (++i < n);
n = x[g]; // set n to length of v
// Generate the Huffman codes and for each, make the table entries
x[0] = i = 0; // first Huffman code is zero
p = 0; // grab values in bit order
h = - 1; // no tables yet--level -1
w = - l; // bits decoded == (l * h)
u[0] = 0; // just to keep compilers happy
q = 0; // ditto
z = 0; // ditto
// go through the bit lengths (k already is bits in shortest code)
for (; k <= g; k++)
{
a = c[k];
while (a-- != 0)
{
// here i is the Huffman code of length k bits for value *p
// make tables up to required level
while (k > w + l)
{
h++;
w += l; // previous table always l bits
// compute minimum size table less than or equal to l bits
z = g - w;
z = (z > l)?l:z; // table size upper limit
if ((f = 1 << (j = k - w)) > a + 1)
{
// try a k-w bit table
// too few codes for k-w bit table
f -= (a + 1); // deduct codes from patterns left
xp = k;
if (j < z)
{
while (++j < z)
{
// try smaller tables up to z bits
if ((f <<= 1) <= c[++xp])
break; // enough codes to use up j bits
f -= c[xp]; // else deduct codes from patterns
}
}
}
z = 1 << j; // table entries for j-bit table
// allocate new table
if (hn[0] + z > MANY)
{
// (note: doesn't matter for fixed)
return Z_DATA_ERROR; // overflow of MANY
}
u[h] = q = hn[0]; // DEBUG
hn[0] += z;
// connect to last table, if there is one
if (h != 0)
{
x[h] = i; // save pattern for backing up
r[0] = (sbyte) j; // bits in this table
r[1] = (sbyte) l; // bits to dump before this table
j = SharedUtils.URShift(i, (w - l));
r[2] = (int) (q - u[h - 1] - j); // offset to this table
Array.Copy(r, 0, hp, (u[h - 1] + j) * 3, 3); // connect to last table
}
else
{
t[0] = q; // first table is returned result
}
}
// set up table entry in r
r[1] = (sbyte) (k - w);
if (p >= n)
{
r[0] = 128 + 64; // out of values--invalid code
}
else if (v[p] < s)
{
r[0] = (sbyte) (v[p] < 256?0:32 + 64); // 256 is end-of-block
r[2] = v[p++]; // simple code is just the value
}
else
{
r[0] = (sbyte) (e[v[p] - s] + 16 + 64); // non-simple--look up in lists
r[2] = d[v[p++] - s];
}
// fill code-like entries with r
f = 1 << (k - w);
for (j = SharedUtils.URShift(i, w); j < z; j += f)
{
Array.Copy(r, 0, hp, (q + j) * 3, 3);
}
// backwards increment the k-bit code i
for (j = 1 << (k - 1); (i & j) != 0; j = SharedUtils.URShift(j, 1))
{
i ^= j;
}
i ^= j;
// backup over finished tables
mask = (1 << w) - 1; // needed on HP, cc -O bug
while ((i & mask) != x[h])
{
h--; // don't need to update q
w -= l;
mask = (1 << w) - 1;
}
}
}
// Return Z_BUF_ERROR if we were given an incomplete table
return y != 0 && g != 1?Z_BUF_ERROR:Z_OK;
}
internal int inflate_trees_bits(int[] c, int[] bb, int[] tb, int[] hp, ZlibCodec z)
{
int result;
initWorkArea(19);
hn[0] = 0;
result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v);
if (result == Z_DATA_ERROR)
{
z.Message = "oversubscribed dynamic bit lengths tree";
}
else if (result == Z_BUF_ERROR || bb[0] == 0)
{
z.Message = "incomplete dynamic bit lengths tree";
result = Z_DATA_ERROR;
}
return result;
}
internal int inflate_trees_dynamic(int nl, int nd, int[] c, int[] bl, int[] bd, int[] tl, int[] td, int[] hp, ZlibCodec z)
{
int result;
// build literal/length tree
initWorkArea(288);
hn[0] = 0;
result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v);
if (result != Z_OK || bl[0] == 0)
{
if (result == Z_DATA_ERROR)
{
z.Message = "oversubscribed literal/length tree";
}
else if (result != Z_MEM_ERROR)
{
z.Message = "incomplete literal/length tree";
result = Z_DATA_ERROR;
}
return result;
}
// build distance tree
initWorkArea(288);
result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v);
if (result != Z_OK || (bd[0] == 0 && nl > 257))
{
if (result == Z_DATA_ERROR)
{
z.Message = "oversubscribed distance tree";
}
else if (result == Z_BUF_ERROR)
{
z.Message = "incomplete distance tree";
result = Z_DATA_ERROR;
}
else if (result != Z_MEM_ERROR)
{
z.Message = "empty distance tree with lengths";
result = Z_DATA_ERROR;
}
return result;
}
return Z_OK;
}
internal static int inflate_trees_fixed(int[] bl, int[] bd, int[][] tl, int[][] td, ZlibCodec z)
{
bl[0] = fixed_bl;
bd[0] = fixed_bd;
tl[0] = fixed_tl;
td[0] = fixed_td;
return Z_OK;
}
private void initWorkArea(int vsize)
{
if (hn == null)
{
hn = new int[1];
v = new int[vsize];
c = new int[BMAX + 1];
r = new int[3];
u = new int[BMAX];
x = new int[BMAX + 1];
}
else
{
if (v.Length < vsize)
{
v = new int[vsize];
}
Array.Clear(v,0,vsize);
Array.Clear(c,0,BMAX+1);
r[0]=0; r[1]=0; r[2]=0;
// for(int i=0; i<BMAX; i++){u[i]=0;}
//Array.Copy(c, 0, u, 0, BMAX);
Array.Clear(u,0,BMAX);
// for(int i=0; i<BMAX+1; i++){x[i]=0;}
//Array.Copy(c, 0, x, 0, BMAX + 1);
Array.Clear(x,0,BMAX+1);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,421 @@
// Tree.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// last saved (in emacs):
// Time-stamp: <2009-October-28 13:29:50>
//
// ------------------------------------------------------------------
//
// This module defines classes for zlib compression and
// decompression. This code is derived from the jzlib implementation of
// zlib. In keeping with the license for jzlib, the copyright to that
// code is below.
//
// ------------------------------------------------------------------
//
// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the distribution.
//
// 3. The names of the authors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------
//
// This program is based on zlib-1.1.3; credit to authors
// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
// and contributors of zlib.
//
// -----------------------------------------------------------------------
namespace ROMVault2.SupportedFiles.Zip.ZLib
{
sealed class Tree
{
private static readonly int HEAP_SIZE = (2 * InternalConstants.L_CODES + 1);
// extra bits for each length code
internal static readonly int[] ExtraLengthBits = new int[]
{
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0
};
// extra bits for each distance code
internal static readonly int[] ExtraDistanceBits = new int[]
{
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13
};
// extra bits for each bit length code
internal static readonly int[] extra_blbits = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7};
internal static readonly sbyte[] bl_order = new sbyte[]{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
// The lengths of the bit length codes are sent in order of decreasing
// probability, to avoid transmitting the lengths for unused bit
// length codes.
internal const int Buf_size = 8 * 2;
// see definition of array dist_code below
//internal const int DIST_CODE_LEN = 512;
private static readonly sbyte[] _dist_code = new sbyte[]
{
0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
0, 0, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21,
22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
};
internal static readonly sbyte[] LengthCode = new sbyte[]
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11,
12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15,
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17,
18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
};
internal static readonly int[] LengthBase = new int[]
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28,
32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0
};
internal static readonly int[] DistanceBase = new int[]
{
0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192,
256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
};
/// <summary>
/// Map from a distance to a distance code.
/// </summary>
/// <remarks>
/// No side effects. _dist_code[256] and _dist_code[257] are never used.
/// </remarks>
internal static int DistanceCode(int dist)
{
return (dist < 256)
? _dist_code[dist]
: _dist_code[256 + SharedUtils.URShift(dist, 7)];
}
internal short[] dyn_tree; // the dynamic tree
internal int max_code; // largest code with non zero frequency
internal StaticTree staticTree; // the corresponding static tree
// Compute the optimal bit lengths for a tree and update the total bit length
// for the current block.
// IN assertion: the fields freq and dad are set, heap[heap_max] and
// above are the tree nodes sorted by increasing frequency.
// OUT assertions: the field len is set to the optimal bit length, the
// array bl_count contains the frequencies for each bit length.
// The length opt_len is updated; static_len is also updated if stree is
// not null.
internal void gen_bitlen(DeflateManager s)
{
short[] tree = dyn_tree;
short[] stree = staticTree.treeCodes;
int[] extra = staticTree.extraBits;
int base_Renamed = staticTree.extraBase;
int max_length = staticTree.maxLength;
int h; // heap index
int n, m; // iterate over the tree elements
int bits; // bit length
int xbits; // extra bits
short f; // frequency
int overflow = 0; // number of elements with bit length too large
for (bits = 0; bits <= InternalConstants.MAX_BITS; bits++)
s.bl_count[bits] = 0;
// In a first pass, compute the optimal bit lengths (which may
// overflow in the case of the bit length tree).
tree[s.heap[s.heap_max] * 2 + 1] = 0; // root of the heap
for (h = s.heap_max + 1; h < HEAP_SIZE; h++)
{
n = s.heap[h];
bits = tree[tree[n * 2 + 1] * 2 + 1] + 1;
if (bits > max_length)
{
bits = max_length; overflow++;
}
tree[n * 2 + 1] = (short) bits;
// We overwrite tree[n*2+1] which is no longer needed
if (n > max_code)
continue; // not a leaf node
s.bl_count[bits]++;
xbits = 0;
if (n >= base_Renamed)
xbits = extra[n - base_Renamed];
f = tree[n * 2];
s.opt_len += f * (bits + xbits);
if (stree != null)
s.static_len += f * (stree[n * 2 + 1] + xbits);
}
if (overflow == 0)
return ;
// This happens for example on obj2 and pic of the Calgary corpus
// Find the first bit length which could increase:
do
{
bits = max_length - 1;
while (s.bl_count[bits] == 0)
bits--;
s.bl_count[bits]--; // move one leaf down the tree
s.bl_count[bits + 1] = (short) (s.bl_count[bits + 1] + 2); // move one overflow item as its brother
s.bl_count[max_length]--;
// The brother of the overflow item also moves one step up,
// but this does not affect bl_count[max_length]
overflow -= 2;
}
while (overflow > 0);
for (bits = max_length; bits != 0; bits--)
{
n = s.bl_count[bits];
while (n != 0)
{
m = s.heap[--h];
if (m > max_code)
continue;
if (tree[m * 2 + 1] != bits)
{
s.opt_len = (int) (s.opt_len + ((long) bits - (long) tree[m * 2 + 1]) * (long) tree[m * 2]);
tree[m * 2 + 1] = (short) bits;
}
n--;
}
}
}
// Construct one Huffman tree and assigns the code bit strings and lengths.
// Update the total bit length for the current block.
// IN assertion: the field freq is set for all tree elements.
// OUT assertions: the fields len and code are set to the optimal bit length
// and corresponding code. The length opt_len is updated; static_len is
// also updated if stree is not null. The field max_code is set.
internal void build_tree(DeflateManager s)
{
short[] tree = dyn_tree;
short[] stree = staticTree.treeCodes;
int elems = staticTree.elems;
int n, m; // iterate over heap elements
int max_code = -1; // largest code with non zero frequency
int node; // new node being created
// Construct the initial heap, with least frequent element in
// heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
// heap[0] is not used.
s.heap_len = 0;
s.heap_max = HEAP_SIZE;
for (n = 0; n < elems; n++)
{
if (tree[n * 2] != 0)
{
s.heap[++s.heap_len] = max_code = n;
s.depth[n] = 0;
}
else
{
tree[n * 2 + 1] = 0;
}
}
// The pkzip format requires that at least one distance code exists,
// and that at least one bit should be sent even if there is only one
// possible code. So to avoid special checks later on we force at least
// two codes of non zero frequency.
while (s.heap_len < 2)
{
node = s.heap[++s.heap_len] = (max_code < 2?++max_code:0);
tree[node * 2] = 1;
s.depth[node] = 0;
s.opt_len--;
if (stree != null)
s.static_len -= stree[node * 2 + 1];
// node is 0 or 1 so it does not have extra bits
}
this.max_code = max_code;
// The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
// establish sub-heaps of increasing lengths:
for (n = s.heap_len / 2; n >= 1; n--)
s.pqdownheap(tree, n);
// Construct the Huffman tree by repeatedly combining the least two
// frequent nodes.
node = elems; // next internal node of the tree
do
{
// n = node of least frequency
n = s.heap[1];
s.heap[1] = s.heap[s.heap_len--];
s.pqdownheap(tree, 1);
m = s.heap[1]; // m = node of next least frequency
s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency
s.heap[--s.heap_max] = m;
// Create a new node father of n and m
tree[node * 2] = unchecked((short) (tree[n * 2] + tree[m * 2]));
s.depth[node] = (sbyte) (System.Math.Max((byte) s.depth[n], (byte) s.depth[m]) + 1);
tree[n * 2 + 1] = tree[m * 2 + 1] = (short) node;
// and insert the new node in the heap
s.heap[1] = node++;
s.pqdownheap(tree, 1);
}
while (s.heap_len >= 2);
s.heap[--s.heap_max] = s.heap[1];
// At this point, the fields freq and dad are set. We can now
// generate the bit lengths.
gen_bitlen(s);
// The field len is now set, we can generate the bit codes
gen_codes(tree, max_code, s.bl_count);
}
// Generate the codes for a given tree and bit counts (which need not be
// optimal).
// IN assertion: the array bl_count contains the bit length statistics for
// the given tree and the field len is set for all tree elements.
// OUT assertion: the field code is set for all tree elements of non
// zero code length.
internal static void gen_codes(short[] tree, int max_code, short[] bl_count)
{
short[] next_code = new short[InternalConstants.MAX_BITS + 1]; // next code value for each bit length
short code = 0; // running code value
int bits; // bit index
int n; // code index
// The distribution counts are first used to generate the code values
// without bit reversal.
for (bits = 1; bits <= InternalConstants.MAX_BITS; bits++)
unchecked {
next_code[bits] = code = (short) ((code + bl_count[bits - 1]) << 1);
}
// Check that the bit counts in bl_count are consistent. The last code
// must be all ones.
//Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
// "inconsistent bit counts");
//Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
for (n = 0; n <= max_code; n++)
{
int len = tree[n * 2 + 1];
if (len == 0)
continue;
// Now reverse the bits
tree[n * 2] = unchecked((short) (bi_reverse(next_code[len]++, len)));
}
}
// Reverse the first len bits of a code, using straightforward code (a faster
// method would use a table)
// IN assertion: 1 <= len <= 15
internal static int bi_reverse(int code, int len)
{
int res = 0;
do
{
res |= code & 1;
code >>= 1; //SharedUtils.URShift(code, 1);
res <<= 1;
}
while (--len > 0);
return res >> 1;
}
}
}

View File

@@ -0,0 +1,544 @@
// Zlib.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009-2011 Dino Chiesa and Microsoft Corporation.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// Last Saved: <2011-August-03 19:52:28>
//
// ------------------------------------------------------------------
//
// This module defines classes for ZLIB compression and
// decompression. This code is derived from the jzlib implementation of
// zlib, but significantly modified. The object model is not the same,
// and many of the behaviors are new or different. Nonetheless, in
// keeping with the license for jzlib, the copyright to that code is
// included below.
//
// ------------------------------------------------------------------
//
// The following notice applies to jzlib:
//
// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the distribution.
//
// 3. The names of the authors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------
//
// jzlib is based on zlib-1.1.3.
//
// The following notice applies to zlib:
//
// -----------------------------------------------------------------------
//
// Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler
//
// The ZLIB software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
//
// Jean-loup Gailly jloup@gzip.org
// Mark Adler madler@alumni.caltech.edu
//
// -----------------------------------------------------------------------
using System.Runtime.InteropServices;
namespace ROMVault2.SupportedFiles.Zip.ZLib
{
/// <summary>
/// Describes how to flush the current deflate operation.
/// </summary>
/// <remarks>
/// The different FlushType values are useful when using a Deflate in a streaming application.
/// </remarks>
public enum FlushType
{
/// <summary>No flush at all.</summary>
None = 0,
/// <summary>Closes the current block, but doesn't flush it to
/// the output. Used internally only in hypothetical
/// scenarios. This was supposed to be removed by Zlib, but it is
/// still in use in some edge cases.
/// </summary>
Partial,
/// <summary>
/// Use this during compression to specify that all pending output should be
/// flushed to the output buffer and the output should be aligned on a byte
/// boundary. You might use this in a streaming communication scenario, so that
/// the decompressor can get all input data available so far. When using this
/// with a ZlibCodec, <c>AvailableBytesIn</c> will be zero after the call if
/// enough output space has been provided before the call. Flushing will
/// degrade compression and so it should be used only when necessary.
/// </summary>
Sync,
/// <summary>
/// Use this during compression to specify that all output should be flushed, as
/// with <c>FlushType.Sync</c>, but also, the compression state should be reset
/// so that decompression can restart from this point if previous compressed
/// data has been damaged or if random access is desired. Using
/// <c>FlushType.Full</c> too often can significantly degrade the compression.
/// </summary>
Full,
/// <summary>Signals the end of the compression/decompression stream.</summary>
Finish,
}
/// <summary>
/// The compression level to be used when using a DeflateStream or ZlibStream with CompressionMode.Compress.
/// </summary>
public enum CompressionLevel
{
/// <summary>
/// None means that the data will be simply stored, with no change at all.
/// If you are producing ZIPs for use on Mac OSX, be aware that archives produced with CompressionLevel.None
/// cannot be opened with the default zip reader. Use a different CompressionLevel.
/// </summary>
None= 0,
/// <summary>
/// Same as None.
/// </summary>
Level0 = 0,
/// <summary>
/// The fastest but least effective compression.
/// </summary>
BestSpeed = 1,
/// <summary>
/// A synonym for BestSpeed.
/// </summary>
Level1 = 1,
/// <summary>
/// A little slower, but better, than level 1.
/// </summary>
Level2 = 2,
/// <summary>
/// A little slower, but better, than level 2.
/// </summary>
Level3 = 3,
/// <summary>
/// A little slower, but better, than level 3.
/// </summary>
Level4 = 4,
/// <summary>
/// A little slower than level 4, but with better compression.
/// </summary>
Level5 = 5,
/// <summary>
/// The default compression level, with a good balance of speed and compression efficiency.
/// </summary>
Default = 6,
/// <summary>
/// A synonym for Default.
/// </summary>
Level6 = 6,
/// <summary>
/// Pretty good compression!
/// </summary>
Level7 = 7,
/// <summary>
/// Better compression than Level7!
/// </summary>
Level8 = 8,
/// <summary>
/// The "best" compression, where best means greatest reduction in size of the input data stream.
/// This is also the slowest compression.
/// </summary>
BestCompression = 9,
/// <summary>
/// A synonym for BestCompression.
/// </summary>
Level9 = 9,
}
/// <summary>
/// Describes options for how the compression algorithm is executed. Different strategies
/// work better on different sorts of data. The strategy parameter can affect the compression
/// ratio and the speed of compression but not the correctness of the compresssion.
/// </summary>
public enum CompressionStrategy
{
/// <summary>
/// The default strategy is probably the best for normal data.
/// </summary>
Default = 0,
/// <summary>
/// The <c>Filtered</c> strategy is intended to be used most effectively with data produced by a
/// filter or predictor. By this definition, filtered data consists mostly of small
/// values with a somewhat random distribution. In this case, the compression algorithm
/// is tuned to compress them better. The effect of <c>Filtered</c> is to force more Huffman
/// coding and less string matching; it is a half-step between <c>Default</c> and <c>HuffmanOnly</c>.
/// </summary>
Filtered = 1,
/// <summary>
/// Using <c>HuffmanOnly</c> will force the compressor to do Huffman encoding only, with no
/// string matching.
/// </summary>
HuffmanOnly = 2,
}
/// <summary>
/// An enum to specify the direction of transcoding - whether to compress or decompress.
/// </summary>
public enum CompressionMode
{
/// <summary>
/// Used to specify that the stream should compress the data.
/// </summary>
Compress= 0,
/// <summary>
/// Used to specify that the stream should decompress the data.
/// </summary>
Decompress = 1,
}
/// <summary>
/// A general purpose exception class for exceptions in the Zlib library.
/// </summary>
[Guid("ebc25cf6-9120-4283-b972-0e5520d0000E")]
public class ZlibException : System.Exception
{
/// <summary>
/// The ZlibException class captures exception information generated
/// by the Zlib library.
/// </summary>
public ZlibException()
: base()
{
}
/// <summary>
/// This ctor collects a message attached to the exception.
/// </summary>
/// <param name="s">the message for the exception.</param>
public ZlibException(System.String s)
: base(s)
{
}
}
internal class SharedUtils
{
/// <summary>
/// Performs an unsigned bitwise right shift with the specified number
/// </summary>
/// <param name="number">Number to operate on</param>
/// <param name="bits">Ammount of bits to shift</param>
/// <returns>The resulting number from the shift operation</returns>
public static int URShift(int number, int bits)
{
return (int)((uint)number >> bits);
}
#if NOT
/// <summary>
/// Performs an unsigned bitwise right shift with the specified number
/// </summary>
/// <param name="number">Number to operate on</param>
/// <param name="bits">Ammount of bits to shift</param>
/// <returns>The resulting number from the shift operation</returns>
public static long URShift(long number, int bits)
{
return (long) ((UInt64)number >> bits);
}
#endif
/// <summary>
/// Reads a number of characters from the current source TextReader and writes
/// the data to the target array at the specified index.
/// </summary>
///
/// <param name="sourceTextReader">The source TextReader to read from</param>
/// <param name="target">Contains the array of characteres read from the source TextReader.</param>
/// <param name="start">The starting index of the target array.</param>
/// <param name="count">The maximum number of characters to read from the source TextReader.</param>
///
/// <returns>
/// The number of characters read. The number will be less than or equal to
/// count depending on the data available in the source TextReader. Returns -1
/// if the end of the stream is reached.
/// </returns>
public static System.Int32 ReadInput(System.IO.TextReader sourceTextReader, byte[] target, int start, int count)
{
// Returns 0 bytes if not enough space in target
if (target.Length == 0) return 0;
char[] charArray = new char[target.Length];
int bytesRead = sourceTextReader.Read(charArray, start, count);
// Returns -1 if EOF
if (bytesRead == 0) return -1;
for (int index = start; index < start + bytesRead; index++)
target[index] = (byte)charArray[index];
return bytesRead;
}
internal static byte[] ToByteArray(System.String sourceString)
{
return System.Text.UTF8Encoding.UTF8.GetBytes(sourceString);
}
internal static char[] ToCharArray(byte[] byteArray)
{
return System.Text.UTF8Encoding.UTF8.GetChars(byteArray);
}
}
internal static class InternalConstants
{
internal static readonly int MAX_BITS = 15;
internal static readonly int BL_CODES = 19;
internal static readonly int D_CODES = 30;
internal static readonly int LITERALS = 256;
internal static readonly int LENGTH_CODES = 29;
internal static readonly int L_CODES = (LITERALS + 1 + LENGTH_CODES);
// Bit length codes must not exceed MAX_BL_BITS bits
internal static readonly int MAX_BL_BITS = 7;
// repeat previous bit length 3-6 times (2 bits of repeat count)
internal static readonly int REP_3_6 = 16;
// repeat a zero length 3-10 times (3 bits of repeat count)
internal static readonly int REPZ_3_10 = 17;
// repeat a zero length 11-138 times (7 bits of repeat count)
internal static readonly int REPZ_11_138 = 18;
}
internal sealed class StaticTree
{
internal static readonly short[] lengthAndLiteralsTreeCodes = new short[] {
12, 8, 140, 8, 76, 8, 204, 8, 44, 8, 172, 8, 108, 8, 236, 8,
28, 8, 156, 8, 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, 252, 8,
2, 8, 130, 8, 66, 8, 194, 8, 34, 8, 162, 8, 98, 8, 226, 8,
18, 8, 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, 114, 8, 242, 8,
10, 8, 138, 8, 74, 8, 202, 8, 42, 8, 170, 8, 106, 8, 234, 8,
26, 8, 154, 8, 90, 8, 218, 8, 58, 8, 186, 8, 122, 8, 250, 8,
6, 8, 134, 8, 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, 230, 8,
22, 8, 150, 8, 86, 8, 214, 8, 54, 8, 182, 8, 118, 8, 246, 8,
14, 8, 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, 110, 8, 238, 8,
30, 8, 158, 8, 94, 8, 222, 8, 62, 8, 190, 8, 126, 8, 254, 8,
1, 8, 129, 8, 65, 8, 193, 8, 33, 8, 161, 8, 97, 8, 225, 8,
17, 8, 145, 8, 81, 8, 209, 8, 49, 8, 177, 8, 113, 8, 241, 8,
9, 8, 137, 8, 73, 8, 201, 8, 41, 8, 169, 8, 105, 8, 233, 8,
25, 8, 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, 121, 8, 249, 8,
5, 8, 133, 8, 69, 8, 197, 8, 37, 8, 165, 8, 101, 8, 229, 8,
21, 8, 149, 8, 85, 8, 213, 8, 53, 8, 181, 8, 117, 8, 245, 8,
13, 8, 141, 8, 77, 8, 205, 8, 45, 8, 173, 8, 109, 8, 237, 8,
29, 8, 157, 8, 93, 8, 221, 8, 61, 8, 189, 8, 125, 8, 253, 8,
19, 9, 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, 211, 9, 467, 9,
51, 9, 307, 9, 179, 9, 435, 9, 115, 9, 371, 9, 243, 9, 499, 9,
11, 9, 267, 9, 139, 9, 395, 9, 75, 9, 331, 9, 203, 9, 459, 9,
43, 9, 299, 9, 171, 9, 427, 9, 107, 9, 363, 9, 235, 9, 491, 9,
27, 9, 283, 9, 155, 9, 411, 9, 91, 9, 347, 9, 219, 9, 475, 9,
59, 9, 315, 9, 187, 9, 443, 9, 123, 9, 379, 9, 251, 9, 507, 9,
7, 9, 263, 9, 135, 9, 391, 9, 71, 9, 327, 9, 199, 9, 455, 9,
39, 9, 295, 9, 167, 9, 423, 9, 103, 9, 359, 9, 231, 9, 487, 9,
23, 9, 279, 9, 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, 471, 9,
55, 9, 311, 9, 183, 9, 439, 9, 119, 9, 375, 9, 247, 9, 503, 9,
15, 9, 271, 9, 143, 9, 399, 9, 79, 9, 335, 9, 207, 9, 463, 9,
47, 9, 303, 9, 175, 9, 431, 9, 111, 9, 367, 9, 239, 9, 495, 9,
31, 9, 287, 9, 159, 9, 415, 9, 95, 9, 351, 9, 223, 9, 479, 9,
63, 9, 319, 9, 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, 511, 9,
0, 7, 64, 7, 32, 7, 96, 7, 16, 7, 80, 7, 48, 7, 112, 7,
8, 7, 72, 7, 40, 7, 104, 7, 24, 7, 88, 7, 56, 7, 120, 7,
4, 7, 68, 7, 36, 7, 100, 7, 20, 7, 84, 7, 52, 7, 116, 7,
3, 8, 131, 8, 67, 8, 195, 8, 35, 8, 163, 8, 99, 8, 227, 8
};
internal static readonly short[] distTreeCodes = new short[] {
0, 5, 16, 5, 8, 5, 24, 5, 4, 5, 20, 5, 12, 5, 28, 5,
2, 5, 18, 5, 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, 30, 5,
1, 5, 17, 5, 9, 5, 25, 5, 5, 5, 21, 5, 13, 5, 29, 5,
3, 5, 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 };
internal static readonly StaticTree Literals;
internal static readonly StaticTree Distances;
internal static readonly StaticTree BitLengths;
internal short[] treeCodes; // static tree or null
internal int[] extraBits; // extra bits for each code or null
internal int extraBase; // base index for extra_bits
internal int elems; // max number of elements in the tree
internal int maxLength; // max bit length for the codes
private StaticTree(short[] treeCodes, int[] extraBits, int extraBase, int elems, int maxLength)
{
this.treeCodes = treeCodes;
this.extraBits = extraBits;
this.extraBase = extraBase;
this.elems = elems;
this.maxLength = maxLength;
}
static StaticTree()
{
Literals = new StaticTree(lengthAndLiteralsTreeCodes, Tree.ExtraLengthBits, InternalConstants.LITERALS + 1, InternalConstants.L_CODES, InternalConstants.MAX_BITS);
Distances = new StaticTree(distTreeCodes, Tree.ExtraDistanceBits, 0, InternalConstants.D_CODES, InternalConstants.MAX_BITS);
BitLengths = new StaticTree(null, Tree.extra_blbits, 0, InternalConstants.BL_CODES, InternalConstants.MAX_BL_BITS);
}
}
/// <summary>
/// Computes an Adler-32 checksum.
/// </summary>
/// <remarks>
/// The Adler checksum is similar to a CRC checksum, but faster to compute, though less
/// reliable. It is used in producing RFC1950 compressed streams. The Adler checksum
/// is a required part of the "ZLIB" standard. Applications will almost never need to
/// use this class directly.
/// </remarks>
///
/// <exclude/>
public sealed class Adler
{
// largest prime smaller than 65536
private static readonly uint BASE = 65521;
// NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1
private static readonly int NMAX = 5552;
#pragma warning disable 3001
#pragma warning disable 3002
/// <summary>
/// Calculates the Adler32 checksum.
/// </summary>
/// <remarks>
/// <para>
/// This is used within ZLIB. You probably don't need to use this directly.
/// </para>
/// </remarks>
/// <example>
/// To compute an Adler32 checksum on a byte array:
/// <code>
/// var adler = Adler.Adler32(0, null, 0, 0);
/// adler = Adler.Adler32(adler, buffer, index, length);
/// </code>
/// </example>
public static uint Adler32(uint adler, byte[] buf, int index, int len)
{
if (buf == null)
return 1;
uint s1 = (uint) (adler & 0xffff);
uint s2 = (uint) ((adler >> 16) & 0xffff);
while (len > 0)
{
int k = len < NMAX ? len : NMAX;
len -= k;
while (k >= 16)
{
//s1 += (buf[index++] & 0xff); s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
s1 += buf[index++]; s2 += s1;
k -= 16;
}
if (k != 0)
{
do
{
s1 += buf[index++];
s2 += s1;
}
while (--k != 0);
}
s1 %= BASE;
s2 %= BASE;
}
return (uint)((s2 << 16) | s1);
}
#pragma warning restore 3001
#pragma warning restore 3002
}
}

View File

@@ -0,0 +1,627 @@
// ZlibBaseStream.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// last saved (in emacs):
// Time-stamp: <2011-August-06 21:22:38>
//
// ------------------------------------------------------------------
//
// This module defines the ZlibBaseStream class, which is an intnernal
// base class for DeflateStream, ZlibStream and GZipStream.
//
// ------------------------------------------------------------------
using System;
using System.IO;
namespace ROMVault2.SupportedFiles.Zip.ZLib
{
internal enum ZlibStreamFlavor { ZLIB = 1950, DEFLATE = 1951, GZIP = 1952 }
internal class ZlibBaseStream : System.IO.Stream
{
protected internal ZlibCodec _z = null; // deferred init... new ZlibCodec();
protected internal StreamMode _streamMode = StreamMode.Undefined;
protected internal FlushType _flushMode;
protected internal ZlibStreamFlavor _flavor;
protected internal CompressionMode _compressionMode;
protected internal CompressionLevel _level;
protected internal bool _leaveOpen;
protected internal byte[] _workingBuffer;
protected internal int _bufferSize = ZlibConstants.WorkingBufferSizeDefault;
protected internal byte[] _buf1 = new byte[1];
protected internal System.IO.Stream _stream;
protected internal CompressionStrategy Strategy = CompressionStrategy.Default;
// workitem 7159
CRC32 crc;
protected internal string _GzipFileName;
protected internal string _GzipComment;
protected internal DateTime _GzipMtime;
protected internal int _gzipHeaderByteCount;
internal int Crc32 { get { if (crc == null) return 0; return crc.Crc32Result; } }
public ZlibBaseStream(System.IO.Stream stream,
CompressionMode compressionMode,
CompressionLevel level,
ZlibStreamFlavor flavor,
bool leaveOpen)
: base()
{
this._flushMode = FlushType.None;
//this._workingBuffer = new byte[WORKING_BUFFER_SIZE_DEFAULT];
this._stream = stream;
this._leaveOpen = leaveOpen;
this._compressionMode = compressionMode;
this._flavor = flavor;
this._level = level;
// workitem 7159
if (flavor == ZlibStreamFlavor.GZIP)
{
this.crc = new CRC32();
}
}
protected internal bool _wantCompress
{
get
{
return (this._compressionMode == CompressionMode.Compress);
}
}
private ZlibCodec z
{
get
{
if (_z == null)
{
bool wantRfc1950Header = (this._flavor == ZlibStreamFlavor.ZLIB);
_z = new ZlibCodec();
if (this._compressionMode == CompressionMode.Decompress)
{
_z.InitializeInflate(wantRfc1950Header);
}
else
{
_z.Strategy = Strategy;
_z.InitializeDeflate(this._level, wantRfc1950Header);
}
}
return _z;
}
}
private byte[] workingBuffer
{
get
{
if (_workingBuffer == null)
_workingBuffer = new byte[_bufferSize];
return _workingBuffer;
}
}
public override void Write(System.Byte[] buffer, int offset, int count)
{
// workitem 7159
// calculate the CRC on the unccompressed data (before writing)
if (crc != null)
crc.SlurpBlock(buffer, offset, count);
if (_streamMode == StreamMode.Undefined)
_streamMode = StreamMode.Writer;
else if (_streamMode != StreamMode.Writer)
throw new ZlibException("Cannot Write after Reading.");
if (count == 0)
return;
// first reference of z property will initialize the private var _z
z.InputBuffer = buffer;
_z.NextIn = offset;
_z.AvailableBytesIn = count;
bool done = false;
do
{
_z.OutputBuffer = workingBuffer;
_z.NextOut = 0;
_z.AvailableBytesOut = _workingBuffer.Length;
int rc = (_wantCompress)
? _z.Deflate(_flushMode)
: _z.Inflate(_flushMode);
if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END)
throw new ZlibException((_wantCompress ? "de" : "in") + "flating: " + _z.Message);
//if (_workingBuffer.Length - _z.AvailableBytesOut > 0)
_stream.Write(_workingBuffer, 0, _workingBuffer.Length - _z.AvailableBytesOut);
done = _z.AvailableBytesIn == 0 && _z.AvailableBytesOut != 0;
// If GZIP and de-compress, we're done when 8 bytes remain.
if (_flavor == ZlibStreamFlavor.GZIP && !_wantCompress)
done = (_z.AvailableBytesIn == 8 && _z.AvailableBytesOut != 0);
}
while (!done);
}
private void finish()
{
if (_z == null) return;
if (_streamMode == StreamMode.Writer)
{
bool done = false;
do
{
_z.OutputBuffer = workingBuffer;
_z.NextOut = 0;
_z.AvailableBytesOut = _workingBuffer.Length;
int rc = (_wantCompress)
? _z.Deflate(FlushType.Finish)
: _z.Inflate(FlushType.Finish);
if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK)
{
string verb = (_wantCompress ? "de" : "in") + "flating";
if (_z.Message == null)
throw new ZlibException(String.Format("{0}: (rc = {1})", verb, rc));
else
throw new ZlibException(verb + ": " + _z.Message);
}
if (_workingBuffer.Length - _z.AvailableBytesOut > 0)
{
_stream.Write(_workingBuffer, 0, _workingBuffer.Length - _z.AvailableBytesOut);
}
done = _z.AvailableBytesIn == 0 && _z.AvailableBytesOut != 0;
// If GZIP and de-compress, we're done when 8 bytes remain.
if (_flavor == ZlibStreamFlavor.GZIP && !_wantCompress)
done = (_z.AvailableBytesIn == 8 && _z.AvailableBytesOut != 0);
}
while (!done);
Flush();
// workitem 7159
if (_flavor == ZlibStreamFlavor.GZIP)
{
if (_wantCompress)
{
// Emit the GZIP trailer: CRC32 and size mod 2^32
int c1 = crc.Crc32Result;
_stream.Write(BitConverter.GetBytes(c1), 0, 4);
int c2 = (Int32)(crc.TotalBytesRead & 0x00000000FFFFFFFF);
_stream.Write(BitConverter.GetBytes(c2), 0, 4);
}
else
{
throw new ZlibException("Writing with decompression is not supported.");
}
}
}
// workitem 7159
else if (_streamMode == StreamMode.Reader)
{
if (_flavor == ZlibStreamFlavor.GZIP)
{
if (!_wantCompress)
{
// workitem 8501: handle edge case (decompress empty stream)
if (_z.TotalBytesOut == 0L)
return;
// Read and potentially verify the GZIP trailer:
// CRC32 and size mod 2^32
byte[] trailer = new byte[8];
// workitems 8679 & 12554
if (_z.AvailableBytesIn < 8)
{
// Make sure we have read to the end of the stream
Array.Copy(_z.InputBuffer, _z.NextIn, trailer, 0, _z.AvailableBytesIn);
int bytesNeeded = 8 - _z.AvailableBytesIn;
int bytesRead = _stream.Read(trailer,
_z.AvailableBytesIn,
bytesNeeded);
if (bytesNeeded != bytesRead)
{
throw new ZlibException(String.Format("Missing or incomplete GZIP trailer. Expected 8 bytes, got {0}.",
_z.AvailableBytesIn + bytesRead));
}
}
else
{
Array.Copy(_z.InputBuffer, _z.NextIn, trailer, 0, trailer.Length);
}
Int32 crc32_expected = BitConverter.ToInt32(trailer, 0);
Int32 crc32_actual = crc.Crc32Result;
Int32 isize_expected = BitConverter.ToInt32(trailer, 4);
Int32 isize_actual = (Int32)(_z.TotalBytesOut & 0x00000000FFFFFFFF);
if (crc32_actual != crc32_expected)
throw new ZlibException(String.Format("Bad CRC32 in GZIP trailer. (actual({0:X8})!=expected({1:X8}))", crc32_actual, crc32_expected));
if (isize_actual != isize_expected)
throw new ZlibException(String.Format("Bad size in GZIP trailer. (actual({0})!=expected({1}))", isize_actual, isize_expected));
}
else
{
throw new ZlibException("Reading with compression is not supported.");
}
}
}
}
private void end()
{
if (z == null)
return;
if (_wantCompress)
{
_z.EndDeflate();
}
else
{
_z.EndInflate();
}
_z = null;
}
public override void Close()
{
if (_stream == null) return;
try
{
finish();
}
finally
{
end();
if (!_leaveOpen) _stream.Close();
_stream = null;
}
}
public override void Flush()
{
_stream.Flush();
}
public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin)
{
throw new NotImplementedException();
//_outStream.Seek(offset, origin);
}
public override void SetLength(System.Int64 value)
{
_stream.SetLength(value);
}
#if NOT
public int Read()
{
if (Read(_buf1, 0, 1) == 0)
return 0;
// calculate CRC after reading
if (crc!=null)
crc.SlurpBlock(_buf1,0,1);
return (_buf1[0] & 0xFF);
}
#endif
private bool nomoreinput = false;
private string ReadZeroTerminatedString()
{
var list = new System.Collections.Generic.List<byte>();
bool done = false;
do
{
// workitem 7740
int n = _stream.Read(_buf1, 0, 1);
if (n != 1)
throw new ZlibException("Unexpected EOF reading GZIP header.");
else
{
if (_buf1[0] == 0)
done = true;
else
list.Add(_buf1[0]);
}
} while (!done);
byte[] a = list.ToArray();
return GZipStream.iso8859dash1.GetString(a, 0, a.Length);
}
private int _ReadAndValidateGzipHeader()
{
int totalBytesRead = 0;
// read the header on the first read
byte[] header = new byte[10];
int n = _stream.Read(header, 0, header.Length);
// workitem 8501: handle edge case (decompress empty stream)
if (n == 0)
return 0;
if (n != 10)
throw new ZlibException("Not a valid GZIP stream.");
if (header[0] != 0x1F || header[1] != 0x8B || header[2] != 8)
throw new ZlibException("Bad GZIP header.");
Int32 timet = BitConverter.ToInt32(header, 4);
_GzipMtime = GZipStream._unixEpoch.AddSeconds(timet);
totalBytesRead += n;
if ((header[3] & 0x04) == 0x04)
{
// read and discard extra field
n = _stream.Read(header, 0, 2); // 2-byte length field
totalBytesRead += n;
Int16 extraLength = (Int16)(header[0] + header[1] * 256);
byte[] extra = new byte[extraLength];
n = _stream.Read(extra, 0, extra.Length);
if (n != extraLength)
throw new ZlibException("Unexpected end-of-file reading GZIP header.");
totalBytesRead += n;
}
if ((header[3] & 0x08) == 0x08)
_GzipFileName = ReadZeroTerminatedString();
if ((header[3] & 0x10) == 0x010)
_GzipComment = ReadZeroTerminatedString();
if ((header[3] & 0x02) == 0x02)
Read(_buf1, 0, 1); // CRC16, ignore
return totalBytesRead;
}
public override System.Int32 Read(System.Byte[] buffer, System.Int32 offset, System.Int32 count)
{
// According to MS documentation, any implementation of the IO.Stream.Read function must:
// (a) throw an exception if offset & count reference an invalid part of the buffer,
// or if count < 0, or if buffer is null
// (b) return 0 only upon EOF, or if count = 0
// (c) if not EOF, then return at least 1 byte, up to <count> bytes
if (_streamMode == StreamMode.Undefined)
{
if (!this._stream.CanRead) throw new ZlibException("The stream is not readable.");
// for the first read, set up some controls.
_streamMode = StreamMode.Reader;
// (The first reference to _z goes through the private accessor which
// may initialize it.)
z.AvailableBytesIn = 0;
if (_flavor == ZlibStreamFlavor.GZIP)
{
_gzipHeaderByteCount = _ReadAndValidateGzipHeader();
// workitem 8501: handle edge case (decompress empty stream)
if (_gzipHeaderByteCount == 0)
return 0;
}
}
if (_streamMode != StreamMode.Reader)
throw new ZlibException("Cannot Read after Writing.");
if (count == 0) return 0;
if (nomoreinput && _wantCompress) return 0; // workitem 8557
if (buffer == null) throw new ArgumentNullException("buffer");
if (count < 0) throw new ArgumentOutOfRangeException("count");
if (offset < buffer.GetLowerBound(0)) throw new ArgumentOutOfRangeException("offset");
if ((offset + count) > buffer.GetLength(0)) throw new ArgumentOutOfRangeException("count");
int rc = 0;
// set up the output of the deflate/inflate codec:
_z.OutputBuffer = buffer;
_z.NextOut = offset;
_z.AvailableBytesOut = count;
// This is necessary in case _workingBuffer has been resized. (new byte[])
// (The first reference to _workingBuffer goes through the private accessor which
// may initialize it.)
_z.InputBuffer = workingBuffer;
do
{
// need data in _workingBuffer in order to deflate/inflate. Here, we check if we have any.
if ((_z.AvailableBytesIn == 0) && (!nomoreinput))
{
// No data available, so try to Read data from the captive stream.
_z.NextIn = 0;
_z.AvailableBytesIn = _stream.Read(_workingBuffer, 0, _workingBuffer.Length);
if (_z.AvailableBytesIn == 0)
nomoreinput = true;
}
// we have data in InputBuffer; now compress or decompress as appropriate
rc = (_wantCompress)
? _z.Deflate(_flushMode)
: _z.Inflate(_flushMode);
if (nomoreinput && (rc == ZlibConstants.Z_BUF_ERROR))
return 0;
if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END)
throw new ZlibException(String.Format("{0}flating: rc={1} msg={2}", (_wantCompress ? "de" : "in"), rc, _z.Message));
if ((nomoreinput || rc == ZlibConstants.Z_STREAM_END) && (_z.AvailableBytesOut == count))
break; // nothing more to read
}
//while (_z.AvailableBytesOut == count && rc == ZlibConstants.Z_OK);
while (_z.AvailableBytesOut > 0 && !nomoreinput && rc == ZlibConstants.Z_OK);
// workitem 8557
// is there more room in output?
if (_z.AvailableBytesOut > 0)
{
if (rc == ZlibConstants.Z_OK && _z.AvailableBytesIn == 0)
{
// deferred
}
// are we completely done reading?
if (nomoreinput)
{
// and in compression?
if (_wantCompress)
{
// no more input data available; therefore we flush to
// try to complete the read
rc = _z.Deflate(FlushType.Finish);
if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END)
throw new ZlibException(String.Format("Deflating: rc={0} msg={1}", rc, _z.Message));
}
}
}
rc = (count - _z.AvailableBytesOut);
// calculate CRC after reading
if (crc != null)
crc.SlurpBlock(buffer, offset, rc);
return rc;
}
public override System.Boolean CanRead
{
get { return this._stream.CanRead; }
}
public override System.Boolean CanSeek
{
get { return this._stream.CanSeek; }
}
public override System.Boolean CanWrite
{
get { return this._stream.CanWrite; }
}
public override System.Int64 Length
{
get { return _stream.Length; }
}
public override long Position
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
internal enum StreamMode
{
Writer,
Reader,
Undefined,
}
public static void CompressString(String s, Stream compressor)
{
byte[] uncompressed = System.Text.Encoding.UTF8.GetBytes(s);
using (compressor)
{
compressor.Write(uncompressed, 0, uncompressed.Length);
}
}
public static void CompressBuffer(byte[] b, Stream compressor)
{
// workitem 8460
using (compressor)
{
compressor.Write(b, 0, b.Length);
}
}
public static String UncompressString(byte[] compressed, Stream decompressor)
{
// workitem 8460
byte[] working = new byte[1024];
var encoding = System.Text.Encoding.UTF8;
using (var output = new MemoryStream())
{
using (decompressor)
{
int n;
while ((n = decompressor.Read(working, 0, working.Length)) != 0)
{
output.Write(working, 0, n);
}
}
// reset to allow read from start
output.Seek(0, SeekOrigin.Begin);
var sr = new StreamReader(output, encoding);
return sr.ReadToEnd();
}
}
public static byte[] UncompressBuffer(byte[] compressed, Stream decompressor)
{
// workitem 8460
byte[] working = new byte[1024];
using (var output = new MemoryStream())
{
using (decompressor)
{
int n;
while ((n = decompressor.Read(working, 0, working.Length)) != 0)
{
output.Write(working, 0, n);
}
}
return output.ToArray();
}
}
}
}

View File

@@ -0,0 +1,717 @@
// ZlibCodec.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// last saved (in emacs):
// Time-stamp: <2009-November-03 15:40:51>
//
// ------------------------------------------------------------------
//
// This module defines a Codec for ZLIB compression and
// decompression. This code extends code that was based the jzlib
// implementation of zlib, but this code is completely novel. The codec
// class is new, and encapsulates some behaviors that are new, and some
// that were present in other classes in the jzlib code base. In
// keeping with the license for jzlib, the copyright to the jzlib code
// is included below.
//
// ------------------------------------------------------------------
//
// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the distribution.
//
// 3. The names of the authors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------
//
// This program is based on zlib-1.1.3; credit to authors
// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
// and contributors of zlib.
//
// -----------------------------------------------------------------------
using System;
using System.Runtime.InteropServices;
namespace ROMVault2.SupportedFiles.Zip.ZLib
{
/// <summary>
/// Encoder and Decoder for ZLIB and DEFLATE (IETF RFC1950 and RFC1951).
/// </summary>
///
/// <remarks>
/// This class compresses and decompresses data according to the Deflate algorithm
/// and optionally, the ZLIB format, as documented in <see
/// href="http://www.ietf.org/rfc/rfc1950.txt">RFC 1950 - ZLIB</see> and <see
/// href="http://www.ietf.org/rfc/rfc1951.txt">RFC 1951 - DEFLATE</see>.
/// </remarks>
[Guid("ebc25cf6-9120-4283-b972-0e5520d0000D")]
[System.Runtime.InteropServices.ComVisible(true)]
#if !NETCF
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.AutoDispatch)]
#endif
sealed public class ZlibCodec
{
/// <summary>
/// The buffer from which data is taken.
/// </summary>
public byte[] InputBuffer;
/// <summary>
/// An index into the InputBuffer array, indicating where to start reading.
/// </summary>
public int NextIn;
/// <summary>
/// The number of bytes available in the InputBuffer, starting at NextIn.
/// </summary>
/// <remarks>
/// Generally you should set this to InputBuffer.Length before the first Inflate() or Deflate() call.
/// The class will update this number as calls to Inflate/Deflate are made.
/// </remarks>
public int AvailableBytesIn;
/// <summary>
/// Total number of bytes read so far, through all calls to Inflate()/Deflate().
/// </summary>
public long TotalBytesIn;
/// <summary>
/// Buffer to store output data.
/// </summary>
public byte[] OutputBuffer;
/// <summary>
/// An index into the OutputBuffer array, indicating where to start writing.
/// </summary>
public int NextOut;
/// <summary>
/// The number of bytes available in the OutputBuffer, starting at NextOut.
/// </summary>
/// <remarks>
/// Generally you should set this to OutputBuffer.Length before the first Inflate() or Deflate() call.
/// The class will update this number as calls to Inflate/Deflate are made.
/// </remarks>
public int AvailableBytesOut;
/// <summary>
/// Total number of bytes written to the output so far, through all calls to Inflate()/Deflate().
/// </summary>
public long TotalBytesOut;
/// <summary>
/// used for diagnostics, when something goes wrong!
/// </summary>
public System.String Message;
internal DeflateManager dstate;
internal InflateManager istate;
internal uint _Adler32;
/// <summary>
/// The compression level to use in this codec. Useful only in compression mode.
/// </summary>
public CompressionLevel CompressLevel = CompressionLevel.Default;
/// <summary>
/// The number of Window Bits to use.
/// </summary>
/// <remarks>
/// This gauges the size of the sliding window, and hence the
/// compression effectiveness as well as memory consumption. It's best to just leave this
/// setting alone if you don't know what it is. The maximum value is 15 bits, which implies
/// a 32k window.
/// </remarks>
public int WindowBits = ZlibConstants.WindowBitsDefault;
/// <summary>
/// The compression strategy to use.
/// </summary>
/// <remarks>
/// This is only effective in compression. The theory offered by ZLIB is that different
/// strategies could potentially produce significant differences in compression behavior
/// for different data sets. Unfortunately I don't have any good recommendations for how
/// to set it differently. When I tested changing the strategy I got minimally different
/// compression performance. It's best to leave this property alone if you don't have a
/// good feel for it. Or, you may want to produce a test harness that runs through the
/// different strategy options and evaluates them on different file types. If you do that,
/// let me know your results.
/// </remarks>
public CompressionStrategy Strategy = CompressionStrategy.Default;
/// <summary>
/// The Adler32 checksum on the data transferred through the codec so far. You probably don't need to look at this.
/// </summary>
public int Adler32 { get { return (int)_Adler32; } }
/// <summary>
/// Create a ZlibCodec.
/// </summary>
/// <remarks>
/// If you use this default constructor, you will later have to explicitly call
/// InitializeInflate() or InitializeDeflate() before using the ZlibCodec to compress
/// or decompress.
/// </remarks>
public ZlibCodec() { }
/// <summary>
/// Create a ZlibCodec that either compresses or decompresses.
/// </summary>
/// <param name="mode">
/// Indicates whether the codec should compress (deflate) or decompress (inflate).
/// </param>
public ZlibCodec(CompressionMode mode)
{
if (mode == CompressionMode.Compress)
{
int rc = InitializeDeflate();
if (rc != ZlibConstants.Z_OK) throw new ZlibException("Cannot initialize for deflate.");
}
else if (mode == CompressionMode.Decompress)
{
int rc = InitializeInflate();
if (rc != ZlibConstants.Z_OK) throw new ZlibException("Cannot initialize for inflate.");
}
else throw new ZlibException("Invalid ZlibStreamFlavor.");
}
/// <summary>
/// Initialize the inflation state.
/// </summary>
/// <remarks>
/// It is not necessary to call this before using the ZlibCodec to inflate data;
/// It is implicitly called when you call the constructor.
/// </remarks>
/// <returns>Z_OK if everything goes well.</returns>
public int InitializeInflate()
{
return InitializeInflate(this.WindowBits);
}
/// <summary>
/// Initialize the inflation state with an explicit flag to
/// govern the handling of RFC1950 header bytes.
/// </summary>
///
/// <remarks>
/// By default, the ZLIB header defined in <see
/// href="http://www.ietf.org/rfc/rfc1950.txt">RFC 1950</see> is expected. If
/// you want to read a zlib stream you should specify true for
/// expectRfc1950Header. If you have a deflate stream, you will want to specify
/// false. It is only necessary to invoke this initializer explicitly if you
/// want to specify false.
/// </remarks>
///
/// <param name="expectRfc1950Header">whether to expect an RFC1950 header byte
/// pair when reading the stream of data to be inflated.</param>
///
/// <returns>Z_OK if everything goes well.</returns>
public int InitializeInflate(bool expectRfc1950Header)
{
return InitializeInflate(this.WindowBits, expectRfc1950Header);
}
/// <summary>
/// Initialize the ZlibCodec for inflation, with the specified number of window bits.
/// </summary>
/// <param name="windowBits">The number of window bits to use. If you need to ask what that is,
/// then you shouldn't be calling this initializer.</param>
/// <returns>Z_OK if all goes well.</returns>
public int InitializeInflate(int windowBits)
{
this.WindowBits = windowBits;
return InitializeInflate(windowBits, true);
}
/// <summary>
/// Initialize the inflation state with an explicit flag to govern the handling of
/// RFC1950 header bytes.
/// </summary>
///
/// <remarks>
/// If you want to read a zlib stream you should specify true for
/// expectRfc1950Header. In this case, the library will expect to find a ZLIB
/// header, as defined in <see href="http://www.ietf.org/rfc/rfc1950.txt">RFC
/// 1950</see>, in the compressed stream. If you will be reading a DEFLATE or
/// GZIP stream, which does not have such a header, you will want to specify
/// false.
/// </remarks>
///
/// <param name="expectRfc1950Header">whether to expect an RFC1950 header byte pair when reading
/// the stream of data to be inflated.</param>
/// <param name="windowBits">The number of window bits to use. If you need to ask what that is,
/// then you shouldn't be calling this initializer.</param>
/// <returns>Z_OK if everything goes well.</returns>
public int InitializeInflate(int windowBits, bool expectRfc1950Header)
{
this.WindowBits = windowBits;
if (dstate != null) throw new ZlibException("You may not call InitializeInflate() after calling InitializeDeflate().");
istate = new InflateManager(expectRfc1950Header);
return istate.Initialize(this, windowBits);
}
/// <summary>
/// Inflate the data in the InputBuffer, placing the result in the OutputBuffer.
/// </summary>
/// <remarks>
/// You must have set InputBuffer and OutputBuffer, NextIn and NextOut, and AvailableBytesIn and
/// AvailableBytesOut before calling this method.
/// </remarks>
/// <example>
/// <code>
/// private void InflateBuffer()
/// {
/// int bufferSize = 1024;
/// byte[] buffer = new byte[bufferSize];
/// ZlibCodec decompressor = new ZlibCodec();
///
/// Console.WriteLine("\n============================================");
/// Console.WriteLine("Size of Buffer to Inflate: {0} bytes.", CompressedBytes.Length);
/// MemoryStream ms = new MemoryStream(DecompressedBytes);
///
/// int rc = decompressor.InitializeInflate();
///
/// decompressor.InputBuffer = CompressedBytes;
/// decompressor.NextIn = 0;
/// decompressor.AvailableBytesIn = CompressedBytes.Length;
///
/// decompressor.OutputBuffer = buffer;
///
/// // pass 1: inflate
/// do
/// {
/// decompressor.NextOut = 0;
/// decompressor.AvailableBytesOut = buffer.Length;
/// rc = decompressor.Inflate(FlushType.None);
///
/// if (rc != ZlibConstants.Z_OK &amp;&amp; rc != ZlibConstants.Z_STREAM_END)
/// throw new Exception("inflating: " + decompressor.Message);
///
/// ms.Write(decompressor.OutputBuffer, 0, buffer.Length - decompressor.AvailableBytesOut);
/// }
/// while (decompressor.AvailableBytesIn &gt; 0 || decompressor.AvailableBytesOut == 0);
///
/// // pass 2: finish and flush
/// do
/// {
/// decompressor.NextOut = 0;
/// decompressor.AvailableBytesOut = buffer.Length;
/// rc = decompressor.Inflate(FlushType.Finish);
///
/// if (rc != ZlibConstants.Z_STREAM_END &amp;&amp; rc != ZlibConstants.Z_OK)
/// throw new Exception("inflating: " + decompressor.Message);
///
/// if (buffer.Length - decompressor.AvailableBytesOut &gt; 0)
/// ms.Write(buffer, 0, buffer.Length - decompressor.AvailableBytesOut);
/// }
/// while (decompressor.AvailableBytesIn &gt; 0 || decompressor.AvailableBytesOut == 0);
///
/// decompressor.EndInflate();
/// }
///
/// </code>
/// </example>
/// <param name="flush">The flush to use when inflating.</param>
/// <returns>Z_OK if everything goes well.</returns>
public int Inflate(FlushType flush)
{
if (istate == null)
throw new ZlibException("No Inflate State!");
return istate.Inflate(flush);
}
/// <summary>
/// Ends an inflation session.
/// </summary>
/// <remarks>
/// Call this after successively calling Inflate(). This will cause all buffers to be flushed.
/// After calling this you cannot call Inflate() without a intervening call to one of the
/// InitializeInflate() overloads.
/// </remarks>
/// <returns>Z_OK if everything goes well.</returns>
public int EndInflate()
{
if (istate == null)
throw new ZlibException("No Inflate State!");
int ret = istate.End();
istate = null;
return ret;
}
/// <summary>
/// I don't know what this does!
/// </summary>
/// <returns>Z_OK if everything goes well.</returns>
public int SyncInflate()
{
if (istate == null)
throw new ZlibException("No Inflate State!");
return istate.Sync();
}
/// <summary>
/// Initialize the ZlibCodec for deflation operation.
/// </summary>
/// <remarks>
/// The codec will use the MAX window bits and the default level of compression.
/// </remarks>
/// <example>
/// <code>
/// int bufferSize = 40000;
/// byte[] CompressedBytes = new byte[bufferSize];
/// byte[] DecompressedBytes = new byte[bufferSize];
///
/// ZlibCodec compressor = new ZlibCodec();
///
/// compressor.InitializeDeflate(CompressionLevel.Default);
///
/// compressor.InputBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(TextToCompress);
/// compressor.NextIn = 0;
/// compressor.AvailableBytesIn = compressor.InputBuffer.Length;
///
/// compressor.OutputBuffer = CompressedBytes;
/// compressor.NextOut = 0;
/// compressor.AvailableBytesOut = CompressedBytes.Length;
///
/// while (compressor.TotalBytesIn != TextToCompress.Length &amp;&amp; compressor.TotalBytesOut &lt; bufferSize)
/// {
/// compressor.Deflate(FlushType.None);
/// }
///
/// while (true)
/// {
/// int rc= compressor.Deflate(FlushType.Finish);
/// if (rc == ZlibConstants.Z_STREAM_END) break;
/// }
///
/// compressor.EndDeflate();
///
/// </code>
/// </example>
/// <returns>Z_OK if all goes well. You generally don't need to check the return code.</returns>
public int InitializeDeflate()
{
return _InternalInitializeDeflate(true);
}
/// <summary>
/// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel.
/// </summary>
/// <remarks>
/// The codec will use the maximum window bits (15) and the specified
/// CompressionLevel. It will emit a ZLIB stream as it compresses.
/// </remarks>
/// <param name="level">The compression level for the codec.</param>
/// <returns>Z_OK if all goes well.</returns>
public int InitializeDeflate(CompressionLevel level)
{
this.CompressLevel = level;
return _InternalInitializeDeflate(true);
}
/// <summary>
/// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel,
/// and the explicit flag governing whether to emit an RFC1950 header byte pair.
/// </summary>
/// <remarks>
/// The codec will use the maximum window bits (15) and the specified CompressionLevel.
/// If you want to generate a zlib stream, you should specify true for
/// wantRfc1950Header. In this case, the library will emit a ZLIB
/// header, as defined in <see href="http://www.ietf.org/rfc/rfc1950.txt">RFC
/// 1950</see>, in the compressed stream.
/// </remarks>
/// <param name="level">The compression level for the codec.</param>
/// <param name="wantRfc1950Header">whether to emit an initial RFC1950 byte pair in the compressed stream.</param>
/// <returns>Z_OK if all goes well.</returns>
public int InitializeDeflate(CompressionLevel level, bool wantRfc1950Header)
{
this.CompressLevel = level;
return _InternalInitializeDeflate(wantRfc1950Header);
}
/// <summary>
/// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel,
/// and the specified number of window bits.
/// </summary>
/// <remarks>
/// The codec will use the specified number of window bits and the specified CompressionLevel.
/// </remarks>
/// <param name="level">The compression level for the codec.</param>
/// <param name="bits">the number of window bits to use. If you don't know what this means, don't use this method.</param>
/// <returns>Z_OK if all goes well.</returns>
public int InitializeDeflate(CompressionLevel level, int bits)
{
this.CompressLevel = level;
this.WindowBits = bits;
return _InternalInitializeDeflate(true);
}
/// <summary>
/// Initialize the ZlibCodec for deflation operation, using the specified
/// CompressionLevel, the specified number of window bits, and the explicit flag
/// governing whether to emit an RFC1950 header byte pair.
/// </summary>
///
/// <param name="level">The compression level for the codec.</param>
/// <param name="wantRfc1950Header">whether to emit an initial RFC1950 byte pair in the compressed stream.</param>
/// <param name="bits">the number of window bits to use. If you don't know what this means, don't use this method.</param>
/// <returns>Z_OK if all goes well.</returns>
public int InitializeDeflate(CompressionLevel level, int bits, bool wantRfc1950Header)
{
this.CompressLevel = level;
this.WindowBits = bits;
return _InternalInitializeDeflate(wantRfc1950Header);
}
private int _InternalInitializeDeflate(bool wantRfc1950Header)
{
if (istate != null) throw new ZlibException("You may not call InitializeDeflate() after calling InitializeInflate().");
dstate = new DeflateManager();
dstate.WantRfc1950HeaderBytes = wantRfc1950Header;
return dstate.Initialize(this, this.CompressLevel, this.WindowBits, this.Strategy);
}
/// <summary>
/// Deflate one batch of data.
/// </summary>
/// <remarks>
/// You must have set InputBuffer and OutputBuffer before calling this method.
/// </remarks>
/// <example>
/// <code>
/// private void DeflateBuffer(CompressionLevel level)
/// {
/// int bufferSize = 1024;
/// byte[] buffer = new byte[bufferSize];
/// ZlibCodec compressor = new ZlibCodec();
///
/// Console.WriteLine("\n============================================");
/// Console.WriteLine("Size of Buffer to Deflate: {0} bytes.", UncompressedBytes.Length);
/// MemoryStream ms = new MemoryStream();
///
/// int rc = compressor.InitializeDeflate(level);
///
/// compressor.InputBuffer = UncompressedBytes;
/// compressor.NextIn = 0;
/// compressor.AvailableBytesIn = UncompressedBytes.Length;
///
/// compressor.OutputBuffer = buffer;
///
/// // pass 1: deflate
/// do
/// {
/// compressor.NextOut = 0;
/// compressor.AvailableBytesOut = buffer.Length;
/// rc = compressor.Deflate(FlushType.None);
///
/// if (rc != ZlibConstants.Z_OK &amp;&amp; rc != ZlibConstants.Z_STREAM_END)
/// throw new Exception("deflating: " + compressor.Message);
///
/// ms.Write(compressor.OutputBuffer, 0, buffer.Length - compressor.AvailableBytesOut);
/// }
/// while (compressor.AvailableBytesIn &gt; 0 || compressor.AvailableBytesOut == 0);
///
/// // pass 2: finish and flush
/// do
/// {
/// compressor.NextOut = 0;
/// compressor.AvailableBytesOut = buffer.Length;
/// rc = compressor.Deflate(FlushType.Finish);
///
/// if (rc != ZlibConstants.Z_STREAM_END &amp;&amp; rc != ZlibConstants.Z_OK)
/// throw new Exception("deflating: " + compressor.Message);
///
/// if (buffer.Length - compressor.AvailableBytesOut &gt; 0)
/// ms.Write(buffer, 0, buffer.Length - compressor.AvailableBytesOut);
/// }
/// while (compressor.AvailableBytesIn &gt; 0 || compressor.AvailableBytesOut == 0);
///
/// compressor.EndDeflate();
///
/// ms.Seek(0, SeekOrigin.Begin);
/// CompressedBytes = new byte[compressor.TotalBytesOut];
/// ms.Read(CompressedBytes, 0, CompressedBytes.Length);
/// }
/// </code>
/// </example>
/// <param name="flush">whether to flush all data as you deflate. Generally you will want to
/// use Z_NO_FLUSH here, in a series of calls to Deflate(), and then call EndDeflate() to
/// flush everything.
/// </param>
/// <returns>Z_OK if all goes well.</returns>
public int Deflate(FlushType flush)
{
if (dstate == null)
throw new ZlibException("No Deflate State!");
return dstate.Deflate(flush);
}
/// <summary>
/// End a deflation session.
/// </summary>
/// <remarks>
/// Call this after making a series of one or more calls to Deflate(). All buffers are flushed.
/// </remarks>
/// <returns>Z_OK if all goes well.</returns>
public int EndDeflate()
{
if (dstate == null)
throw new ZlibException("No Deflate State!");
// TODO: dinoch Tue, 03 Nov 2009 15:39 (test this)
//int ret = dstate.End();
dstate = null;
return ZlibConstants.Z_OK; //ret;
}
/// <summary>
/// Reset a codec for another deflation session.
/// </summary>
/// <remarks>
/// Call this to reset the deflation state. For example if a thread is deflating
/// non-consecutive blocks, you can call Reset() after the Deflate(Sync) of the first
/// block and before the next Deflate(None) of the second block.
/// </remarks>
/// <returns>Z_OK if all goes well.</returns>
public void ResetDeflate()
{
if (dstate == null)
throw new ZlibException("No Deflate State!");
dstate.Reset();
}
/// <summary>
/// Set the CompressionStrategy and CompressionLevel for a deflation session.
/// </summary>
/// <param name="level">the level of compression to use.</param>
/// <param name="strategy">the strategy to use for compression.</param>
/// <returns>Z_OK if all goes well.</returns>
public int SetDeflateParams(CompressionLevel level, CompressionStrategy strategy)
{
if (dstate == null)
throw new ZlibException("No Deflate State!");
return dstate.SetParams(level, strategy);
}
/// <summary>
/// Set the dictionary to be used for either Inflation or Deflation.
/// </summary>
/// <param name="dictionary">The dictionary bytes to use.</param>
/// <returns>Z_OK if all goes well.</returns>
public int SetDictionary(byte[] dictionary)
{
if (istate != null)
return istate.SetDictionary(dictionary);
if (dstate != null)
return dstate.SetDictionary(dictionary);
throw new ZlibException("No Inflate or Deflate state!");
}
// Flush as much pending output as possible. All deflate() output goes
// through this function so some applications may wish to modify it
// to avoid allocating a large strm->next_out buffer and copying into it.
// (See also read_buf()).
internal void flush_pending()
{
int len = dstate.pendingCount;
if (len > AvailableBytesOut)
len = AvailableBytesOut;
if (len == 0)
return;
if (dstate.pending.Length <= dstate.nextPending ||
OutputBuffer.Length <= NextOut ||
dstate.pending.Length < (dstate.nextPending + len) ||
OutputBuffer.Length < (NextOut + len))
{
throw new ZlibException(String.Format("Invalid State. (pending.Length={0}, pendingCount={1})",
dstate.pending.Length, dstate.pendingCount));
}
Array.Copy(dstate.pending, dstate.nextPending, OutputBuffer, NextOut, len);
NextOut += len;
dstate.nextPending += len;
TotalBytesOut += len;
AvailableBytesOut -= len;
dstate.pendingCount -= len;
if (dstate.pendingCount == 0)
{
dstate.nextPending = 0;
}
}
// Read a new buffer from the current input stream, update the adler32
// and total number of bytes read. All deflate() input goes through
// this function so some applications may wish to modify it to avoid
// allocating a large strm->next_in buffer and copying from it.
// (See also flush_pending()).
internal int read_buf(byte[] buf, int start, int size)
{
int len = AvailableBytesIn;
if (len > size)
len = size;
if (len == 0)
return 0;
AvailableBytesIn -= len;
if (dstate.WantRfc1950HeaderBytes)
{
_Adler32 = Adler.Adler32(_Adler32, InputBuffer, NextIn, len);
}
Array.Copy(InputBuffer, NextIn, buf, start, len);
NextIn += len;
TotalBytesIn += len;
return len;
}
}
}

View File

@@ -0,0 +1,126 @@
// ZlibConstants.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// last saved (in emacs):
// Time-stamp: <2009-November-03 18:50:19>
//
// ------------------------------------------------------------------
//
// This module defines constants used by the zlib class library. This
// code is derived from the jzlib implementation of zlib, but
// significantly modified. In keeping with the license for jzlib, the
// copyright to that code is included here.
//
// ------------------------------------------------------------------
//
// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the distribution.
//
// 3. The names of the authors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------
//
// This program is based on zlib-1.1.3; credit to authors
// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
// and contributors of zlib.
//
// -----------------------------------------------------------------------
namespace ROMVault2.SupportedFiles.Zip.ZLib
{
/// <summary>
/// A bunch of constants used in the Zlib interface.
/// </summary>
public static class ZlibConstants
{
/// <summary>
/// The maximum number of window bits for the Deflate algorithm.
/// </summary>
public const int WindowBitsMax = 15; // 32K LZ77 window
/// <summary>
/// The default number of window bits for the Deflate algorithm.
/// </summary>
public const int WindowBitsDefault = WindowBitsMax;
/// <summary>
/// indicates everything is A-OK
/// </summary>
public const int Z_OK = 0;
/// <summary>
/// Indicates that the last operation reached the end of the stream.
/// </summary>
public const int Z_STREAM_END = 1;
/// <summary>
/// The operation ended in need of a dictionary.
/// </summary>
public const int Z_NEED_DICT = 2;
/// <summary>
/// There was an error with the stream - not enough data, not open and readable, etc.
/// </summary>
public const int Z_STREAM_ERROR = -2;
/// <summary>
/// There was an error with the data - not enough data, bad data, etc.
/// </summary>
public const int Z_DATA_ERROR = -3;
/// <summary>
/// There was an error with the working buffer.
/// </summary>
public const int Z_BUF_ERROR = -5;
/// <summary>
/// The size of the working buffer used in the ZlibCodec class. Defaults to 8192 bytes.
/// </summary>
#if NETCF
public const int WorkingBufferSizeDefault = 8192;
#else
public const int WorkingBufferSizeDefault = 16384;
#endif
/// <summary>
/// The minimum size of the working buffer used in the ZlibCodec class. Currently it is 128 bytes.
/// </summary>
public const int WorkingBufferSizeMin = 1024;
}
}

View File

@@ -0,0 +1,725 @@
// ZlibStream.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// last saved (in emacs):
// Time-stamp: <2011-July-31 14:53:33>
//
// ------------------------------------------------------------------
//
// This module defines the ZlibStream class, which is similar in idea to
// the System.IO.Compression.DeflateStream and
// System.IO.Compression.GZipStream classes in the .NET BCL.
//
// ------------------------------------------------------------------
using System;
using System.IO;
namespace ROMVault2.SupportedFiles.Zip.ZLib
{
/// <summary>
/// Represents a Zlib stream for compression or decompression.
/// </summary>
/// <remarks>
///
/// <para>
/// The ZlibStream is a <see
/// href="http://en.wikipedia.org/wiki/Decorator_pattern">Decorator</see> on a <see
/// cref="System.IO.Stream"/>. It adds ZLIB compression or decompression to any
/// stream.
/// </para>
///
/// <para> Using this stream, applications can compress or decompress data via
/// stream <c>Read()</c> and <c>Write()</c> operations. Either compresssion or
/// decompression can occur through either reading or writing. The compression
/// format used is ZLIB, which is documented in <see
/// href="http://www.ietf.org/rfc/rfc1950.txt">IETF RFC 1950</see>, "ZLIB Compressed
/// Data Format Specification version 3.3". This implementation of ZLIB always uses
/// DEFLATE as the compression method. (see <see
/// href="http://www.ietf.org/rfc/rfc1951.txt">IETF RFC 1951</see>, "DEFLATE
/// Compressed Data Format Specification version 1.3.") </para>
///
/// <para>
/// The ZLIB format allows for varying compression methods, window sizes, and dictionaries.
/// This implementation always uses the DEFLATE compression method, a preset dictionary,
/// and 15 window bits by default.
/// </para>
///
/// <para>
/// This class is similar to <see cref="DeflateStream"/>, except that it adds the
/// RFC1950 header and trailer bytes to a compressed stream when compressing, or expects
/// the RFC1950 header and trailer bytes when decompressing. It is also similar to the
/// <see cref="GZipStream"/>.
/// </para>
/// </remarks>
/// <seealso cref="DeflateStream" />
/// <seealso cref="GZipStream" />
public class ZlibStream : System.IO.Stream
{
internal ZlibBaseStream _baseStream;
bool _disposed;
/// <summary>
/// Create a <c>ZlibStream</c> using the specified <c>CompressionMode</c>.
/// </summary>
/// <remarks>
///
/// <para>
/// When mode is <c>CompressionMode.Compress</c>, the <c>ZlibStream</c>
/// will use the default compression level. The "captive" stream will be
/// closed when the <c>ZlibStream</c> is closed.
/// </para>
///
/// </remarks>
///
/// <example>
/// This example uses a <c>ZlibStream</c> to compress a file, and writes the
/// compressed data to another file.
/// <code>
/// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
/// {
/// using (var raw = System.IO.File.Create(fileToCompress + ".zlib"))
/// {
/// using (Stream compressor = new ZlibStream(raw, CompressionMode.Compress))
/// {
/// byte[] buffer = new byte[WORKING_BUFFER_SIZE];
/// int n;
/// while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
/// {
/// compressor.Write(buffer, 0, n);
/// }
/// }
/// }
/// }
/// </code>
/// <code lang="VB">
/// Using input As Stream = File.OpenRead(fileToCompress)
/// Using raw As FileStream = File.Create(fileToCompress &amp; ".zlib")
/// Using compressor As Stream = New ZlibStream(raw, CompressionMode.Compress)
/// Dim buffer As Byte() = New Byte(4096) {}
/// Dim n As Integer = -1
/// Do While (n &lt;&gt; 0)
/// If (n &gt; 0) Then
/// compressor.Write(buffer, 0, n)
/// End If
/// n = input.Read(buffer, 0, buffer.Length)
/// Loop
/// End Using
/// End Using
/// End Using
/// </code>
/// </example>
///
/// <param name="stream">The stream which will be read or written.</param>
/// <param name="mode">Indicates whether the ZlibStream will compress or decompress.</param>
public ZlibStream(System.IO.Stream stream, CompressionMode mode)
: this(stream, mode, CompressionLevel.Default, false)
{
}
/// <summary>
/// Create a <c>ZlibStream</c> using the specified <c>CompressionMode</c> and
/// the specified <c>CompressionLevel</c>.
/// </summary>
///
/// <remarks>
///
/// <para>
/// When mode is <c>CompressionMode.Decompress</c>, the level parameter is ignored.
/// The "captive" stream will be closed when the <c>ZlibStream</c> is closed.
/// </para>
///
/// </remarks>
///
/// <example>
/// This example uses a <c>ZlibStream</c> to compress data from a file, and writes the
/// compressed data to another file.
///
/// <code>
/// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
/// {
/// using (var raw = System.IO.File.Create(fileToCompress + ".zlib"))
/// {
/// using (Stream compressor = new ZlibStream(raw,
/// CompressionMode.Compress,
/// CompressionLevel.BestCompression))
/// {
/// byte[] buffer = new byte[WORKING_BUFFER_SIZE];
/// int n;
/// while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
/// {
/// compressor.Write(buffer, 0, n);
/// }
/// }
/// }
/// }
/// </code>
///
/// <code lang="VB">
/// Using input As Stream = File.OpenRead(fileToCompress)
/// Using raw As FileStream = File.Create(fileToCompress &amp; ".zlib")
/// Using compressor As Stream = New ZlibStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression)
/// Dim buffer As Byte() = New Byte(4096) {}
/// Dim n As Integer = -1
/// Do While (n &lt;&gt; 0)
/// If (n &gt; 0) Then
/// compressor.Write(buffer, 0, n)
/// End If
/// n = input.Read(buffer, 0, buffer.Length)
/// Loop
/// End Using
/// End Using
/// End Using
/// </code>
/// </example>
///
/// <param name="stream">The stream to be read or written while deflating or inflating.</param>
/// <param name="mode">Indicates whether the ZlibStream will compress or decompress.</param>
/// <param name="level">A tuning knob to trade speed for effectiveness.</param>
public ZlibStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level)
: this(stream, mode, level, false)
{
}
/// <summary>
/// Create a <c>ZlibStream</c> using the specified <c>CompressionMode</c>, and
/// explicitly specify whether the captive stream should be left open after
/// Deflation or Inflation.
/// </summary>
///
/// <remarks>
///
/// <para>
/// When mode is <c>CompressionMode.Compress</c>, the <c>ZlibStream</c> will use
/// the default compression level.
/// </para>
///
/// <para>
/// This constructor allows the application to request that the captive stream
/// remain open after the deflation or inflation occurs. By default, after
/// <c>Close()</c> is called on the stream, the captive stream is also
/// closed. In some cases this is not desired, for example if the stream is a
/// <see cref="System.IO.MemoryStream"/> that will be re-read after
/// compression. Specify true for the <paramref name="leaveOpen"/> parameter to leave the stream
/// open.
/// </para>
///
/// <para>
/// See the other overloads of this constructor for example code.
/// </para>
///
/// </remarks>
///
/// <param name="stream">The stream which will be read or written. This is called the
/// "captive" stream in other places in this documentation.</param>
/// <param name="mode">Indicates whether the ZlibStream will compress or decompress.</param>
/// <param name="leaveOpen">true if the application would like the stream to remain
/// open after inflation/deflation.</param>
public ZlibStream(System.IO.Stream stream, CompressionMode mode, bool leaveOpen)
: this(stream, mode, CompressionLevel.Default, leaveOpen)
{
}
/// <summary>
/// Create a <c>ZlibStream</c> using the specified <c>CompressionMode</c>
/// and the specified <c>CompressionLevel</c>, and explicitly specify
/// whether the stream should be left open after Deflation or Inflation.
/// </summary>
///
/// <remarks>
///
/// <para>
/// This constructor allows the application to request that the captive
/// stream remain open after the deflation or inflation occurs. By
/// default, after <c>Close()</c> is called on the stream, the captive
/// stream is also closed. In some cases this is not desired, for example
/// if the stream is a <see cref="System.IO.MemoryStream"/> that will be
/// re-read after compression. Specify true for the <paramref
/// name="leaveOpen"/> parameter to leave the stream open.
/// </para>
///
/// <para>
/// When mode is <c>CompressionMode.Decompress</c>, the level parameter is
/// ignored.
/// </para>
///
/// </remarks>
///
/// <example>
///
/// This example shows how to use a ZlibStream to compress the data from a file,
/// and store the result into another file. The filestream remains open to allow
/// additional data to be written to it.
///
/// <code>
/// using (var output = System.IO.File.Create(fileToCompress + ".zlib"))
/// {
/// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
/// {
/// using (Stream compressor = new ZlibStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, true))
/// {
/// byte[] buffer = new byte[WORKING_BUFFER_SIZE];
/// int n;
/// while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
/// {
/// compressor.Write(buffer, 0, n);
/// }
/// }
/// }
/// // can write additional data to the output stream here
/// }
/// </code>
/// <code lang="VB">
/// Using output As FileStream = File.Create(fileToCompress &amp; ".zlib")
/// Using input As Stream = File.OpenRead(fileToCompress)
/// Using compressor As Stream = New ZlibStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, True)
/// Dim buffer As Byte() = New Byte(4096) {}
/// Dim n As Integer = -1
/// Do While (n &lt;&gt; 0)
/// If (n &gt; 0) Then
/// compressor.Write(buffer, 0, n)
/// End If
/// n = input.Read(buffer, 0, buffer.Length)
/// Loop
/// End Using
/// End Using
/// ' can write additional data to the output stream here.
/// End Using
/// </code>
/// </example>
///
/// <param name="stream">The stream which will be read or written.</param>
///
/// <param name="mode">Indicates whether the ZlibStream will compress or decompress.</param>
///
/// <param name="leaveOpen">
/// true if the application would like the stream to remain open after
/// inflation/deflation.
/// </param>
///
/// <param name="level">
/// A tuning knob to trade speed for effectiveness. This parameter is
/// effective only when mode is <c>CompressionMode.Compress</c>.
/// </param>
public ZlibStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen)
{
_baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.ZLIB, leaveOpen);
}
#region Zlib properties
/// <summary>
/// This property sets the flush behavior on the stream.
/// Sorry, though, not sure exactly how to describe all the various settings.
/// </summary>
virtual public FlushType FlushMode
{
get { return (this._baseStream._flushMode); }
set
{
if (_disposed) throw new ObjectDisposedException("ZlibStream");
this._baseStream._flushMode = value;
}
}
/// <summary>
/// The size of the working buffer for the compression codec.
/// </summary>
///
/// <remarks>
/// <para>
/// The working buffer is used for all stream operations. The default size is
/// 1024 bytes. The minimum size is 128 bytes. You may get better performance
/// with a larger buffer. Then again, you might not. You would have to test
/// it.
/// </para>
///
/// <para>
/// Set this before the first call to <c>Read()</c> or <c>Write()</c> on the
/// stream. If you try to set it afterwards, it will throw.
/// </para>
/// </remarks>
public int BufferSize
{
get
{
return this._baseStream._bufferSize;
}
set
{
if (_disposed) throw new ObjectDisposedException("ZlibStream");
if (this._baseStream._workingBuffer != null)
throw new ZlibException("The working buffer is already set.");
if (value < ZlibConstants.WorkingBufferSizeMin)
throw new ZlibException(String.Format("Don't be silly. {0} bytes?? Use a bigger buffer, at least {1}.", value, ZlibConstants.WorkingBufferSizeMin));
this._baseStream._bufferSize = value;
}
}
/// <summary> Returns the total number of bytes input so far.</summary>
virtual public long TotalIn
{
get { return this._baseStream._z.TotalBytesIn; }
}
/// <summary> Returns the total number of bytes output so far.</summary>
virtual public long TotalOut
{
get { return this._baseStream._z.TotalBytesOut; }
}
#endregion
#region System.IO.Stream methods
/// <summary>
/// Dispose the stream.
/// </summary>
/// <remarks>
/// <para>
/// This may or may not result in a <c>Close()</c> call on the captive
/// stream. See the constructors that have a <c>leaveOpen</c> parameter
/// for more information.
/// </para>
/// <para>
/// This method may be invoked in two distinct scenarios. If disposing
/// == true, the method has been called directly or indirectly by a
/// user's code, for example via the public Dispose() method. In this
/// case, both managed and unmanaged resources can be referenced and
/// disposed. If disposing == false, the method has been called by the
/// runtime from inside the object finalizer and this method should not
/// reference other objects; in that case only unmanaged resources must
/// be referenced or disposed.
/// </para>
/// </remarks>
/// <param name="disposing">
/// indicates whether the Dispose method was invoked by user code.
/// </param>
protected override void Dispose(bool disposing)
{
try
{
if (!_disposed)
{
if (disposing && (this._baseStream != null))
this._baseStream.Close();
_disposed = true;
}
}
finally
{
base.Dispose(disposing);
}
}
/// <summary>
/// Indicates whether the stream can be read.
/// </summary>
/// <remarks>
/// The return value depends on whether the captive stream supports reading.
/// </remarks>
public override bool CanRead
{
get
{
if (_disposed) throw new ObjectDisposedException("ZlibStream");
return _baseStream._stream.CanRead;
}
}
/// <summary>
/// Indicates whether the stream supports Seek operations.
/// </summary>
/// <remarks>
/// Always returns false.
/// </remarks>
public override bool CanSeek
{
get { return false; }
}
/// <summary>
/// Indicates whether the stream can be written.
/// </summary>
/// <remarks>
/// The return value depends on whether the captive stream supports writing.
/// </remarks>
public override bool CanWrite
{
get
{
if (_disposed) throw new ObjectDisposedException("ZlibStream");
return _baseStream._stream.CanWrite;
}
}
/// <summary>
/// Flush the stream.
/// </summary>
public override void Flush()
{
if (_disposed) throw new ObjectDisposedException("ZlibStream");
_baseStream.Flush();
}
/// <summary>
/// Reading this property always throws a <see cref="NotSupportedException"/>.
/// </summary>
public override long Length
{
get { throw new NotSupportedException(); }
}
/// <summary>
/// The position of the stream pointer.
/// </summary>
///
/// <remarks>
/// Setting this property always throws a <see
/// cref="NotSupportedException"/>. Reading will return the total bytes
/// written out, if used in writing, or the total bytes read in, if used in
/// reading. The count may refer to compressed bytes or uncompressed bytes,
/// depending on how you've used the stream.
/// </remarks>
public override long Position
{
get
{
if (this._baseStream._streamMode == ZlibBaseStream.StreamMode.Writer)
return this._baseStream._z.TotalBytesOut;
if (this._baseStream._streamMode == ZlibBaseStream.StreamMode.Reader)
return this._baseStream._z.TotalBytesIn;
return 0;
}
set { throw new NotSupportedException(); }
}
/// <summary>
/// Read data from the stream.
/// </summary>
///
/// <remarks>
///
/// <para>
/// If you wish to use the <c>ZlibStream</c> to compress data while reading,
/// you can create a <c>ZlibStream</c> with <c>CompressionMode.Compress</c>,
/// providing an uncompressed data stream. Then call <c>Read()</c> on that
/// <c>ZlibStream</c>, and the data read will be compressed. If you wish to
/// use the <c>ZlibStream</c> to decompress data while reading, you can create
/// a <c>ZlibStream</c> with <c>CompressionMode.Decompress</c>, providing a
/// readable compressed data stream. Then call <c>Read()</c> on that
/// <c>ZlibStream</c>, and the data will be decompressed as it is read.
/// </para>
///
/// <para>
/// A <c>ZlibStream</c> can be used for <c>Read()</c> or <c>Write()</c>, but
/// not both.
/// </para>
///
/// </remarks>
///
/// <param name="buffer">
/// The buffer into which the read data should be placed.</param>
///
/// <param name="offset">
/// the offset within that data array to put the first byte read.</param>
///
/// <param name="count">the number of bytes to read.</param>
///
/// <returns>the number of bytes read</returns>
public override int Read(byte[] buffer, int offset, int count)
{
if (_disposed) throw new ObjectDisposedException("ZlibStream");
return _baseStream.Read(buffer, offset, count);
}
/// <summary>
/// Calling this method always throws a <see cref="NotSupportedException"/>.
/// </summary>
/// <param name="offset">
/// The offset to seek to....
/// IF THIS METHOD ACTUALLY DID ANYTHING.
/// </param>
/// <param name="origin">
/// The reference specifying how to apply the offset.... IF
/// THIS METHOD ACTUALLY DID ANYTHING.
/// </param>
///
/// <returns>nothing. This method always throws.</returns>
public override long Seek(long offset, System.IO.SeekOrigin origin)
{
throw new NotSupportedException();
}
/// <summary>
/// Calling this method always throws a <see cref="NotSupportedException"/>.
/// </summary>
/// <param name="value">
/// The new value for the stream length.... IF
/// THIS METHOD ACTUALLY DID ANYTHING.
/// </param>
public override void SetLength(long value)
{
throw new NotSupportedException();
}
/// <summary>
/// Write data to the stream.
/// </summary>
///
/// <remarks>
///
/// <para>
/// If you wish to use the <c>ZlibStream</c> to compress data while writing,
/// you can create a <c>ZlibStream</c> with <c>CompressionMode.Compress</c>,
/// and a writable output stream. Then call <c>Write()</c> on that
/// <c>ZlibStream</c>, providing uncompressed data as input. The data sent to
/// the output stream will be the compressed form of the data written. If you
/// wish to use the <c>ZlibStream</c> to decompress data while writing, you
/// can create a <c>ZlibStream</c> with <c>CompressionMode.Decompress</c>, and a
/// writable output stream. Then call <c>Write()</c> on that stream,
/// providing previously compressed data. The data sent to the output stream
/// will be the decompressed form of the data written.
/// </para>
///
/// <para>
/// A <c>ZlibStream</c> can be used for <c>Read()</c> or <c>Write()</c>, but not both.
/// </para>
/// </remarks>
/// <param name="buffer">The buffer holding data to write to the stream.</param>
/// <param name="offset">the offset within that data array to find the first byte to write.</param>
/// <param name="count">the number of bytes to write.</param>
public override void Write(byte[] buffer, int offset, int count)
{
if (_disposed) throw new ObjectDisposedException("ZlibStream");
_baseStream.Write(buffer, offset, count);
}
#endregion
/// <summary>
/// Compress a string into a byte array using ZLIB.
/// </summary>
///
/// <remarks>
/// Uncompress it with <see cref="ZlibStream.UncompressString(byte[])"/>.
/// </remarks>
///
/// <seealso cref="ZlibStream.UncompressString(byte[])"/>
/// <seealso cref="ZlibStream.CompressBuffer(byte[])"/>
/// <seealso cref="GZipStream.CompressString(string)"/>
///
/// <param name="s">
/// A string to compress. The string will first be encoded
/// using UTF8, then compressed.
/// </param>
///
/// <returns>The string in compressed form</returns>
public static byte[] CompressString(String s)
{
using (var ms = new MemoryStream())
{
Stream compressor =
new ZlibStream(ms, CompressionMode.Compress, CompressionLevel.BestCompression);
ZlibBaseStream.CompressString(s, compressor);
return ms.ToArray();
}
}
/// <summary>
/// Compress a byte array into a new byte array using ZLIB.
/// </summary>
///
/// <remarks>
/// Uncompress it with <see cref="ZlibStream.UncompressBuffer(byte[])"/>.
/// </remarks>
///
/// <seealso cref="ZlibStream.CompressString(string)"/>
/// <seealso cref="ZlibStream.UncompressBuffer(byte[])"/>
///
/// <param name="b">
/// A buffer to compress.
/// </param>
///
/// <returns>The data in compressed form</returns>
public static byte[] CompressBuffer(byte[] b)
{
using (var ms = new MemoryStream())
{
Stream compressor =
new ZlibStream( ms, CompressionMode.Compress, CompressionLevel.BestCompression );
ZlibBaseStream.CompressBuffer(b, compressor);
return ms.ToArray();
}
}
/// <summary>
/// Uncompress a ZLIB-compressed byte array into a single string.
/// </summary>
///
/// <seealso cref="ZlibStream.CompressString(String)"/>
/// <seealso cref="ZlibStream.UncompressBuffer(byte[])"/>
///
/// <param name="compressed">
/// A buffer containing ZLIB-compressed data.
/// </param>
///
/// <returns>The uncompressed string</returns>
public static String UncompressString(byte[] compressed)
{
using (var input = new MemoryStream(compressed))
{
Stream decompressor =
new ZlibStream(input, CompressionMode.Decompress);
return ZlibBaseStream.UncompressString(compressed, decompressor);
}
}
/// <summary>
/// Uncompress a ZLIB-compressed byte array into a byte array.
/// </summary>
///
/// <seealso cref="ZlibStream.CompressBuffer(byte[])"/>
/// <seealso cref="ZlibStream.UncompressString(byte[])"/>
///
/// <param name="compressed">
/// A buffer containing ZLIB-compressed data.
/// </param>
///
/// <returns>The data in uncompressed form</returns>
public static byte[] UncompressBuffer(byte[] compressed)
{
using (var input = new MemoryStream(compressed))
{
Stream decompressor =
new ZlibStream( input, CompressionMode.Decompress );
return ZlibBaseStream.UncompressBuffer(compressed, decompressor);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,57 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
namespace ROMVault2.SupportedFiles
{
public enum ZipReturn
{
ZipGood,
ZipFileLocked,
ZipFileCountError,
ZipSignatureError,
ZipExtraDataOnEndOfZip,
ZipUnsupportedCompression,
ZipLocalFileHeaderError,
ZipCenteralDirError,
ZipEndOfCentralDirectoryError,
Zip64EndOfCentralDirError,
Zip64EndOfCentralDirectoryLocatorError,
ZipReadingFromOutputFile,
ZipWritingToInputFile,
ZipErrorGettingDataStream,
ZipCRCDecodeError,
ZipDecodeError,
ZipFileNameToLong,
ZipFileAlreadyOpen,
ZipCannotFastOpen,
ZipErrorOpeningFile,
ZipErrorFileNotFound,
ZipErrorReadingFile,
ZipErrorTimeStamp,
ZipErrorRollBackFile,
ZipUntested
}
public enum ZipOpenType
{
Closed,
OpenRead,
OpenWrite
}
[Flags]
public enum ZipStatus
{
None = 0x0,
TrrntZip = 0x1,
ExtraData = 0x2
}
}

View File

@@ -0,0 +1,72 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.IO;
namespace ROMVault2.Utils
{
public static class ArrByte
{
public static void Write(BinaryWriter bw, byte[] b)
{
bw.Write((byte)b.Length);
bw.Write(b);
}
public static byte[] Read(BinaryReader br)
{
byte len = br.ReadByte();
return br.ReadBytes(len);
}
public static byte[] Copy(byte[] b)
{
if (b == null) return null;
byte[] retB = new byte[b.Length];
for (int i = 0; i < b.Length; i++)
retB[i] = b[i];
return retB;
}
public static bool bCompare(byte[] b1, byte[] b2)
{
if (b1 == null || b2 == null) return false;
if (b1.Length != b2.Length) return false;
for (int i = 0; i < b1.Length; i++)
if (b1[i] != b2[i]) return false;
return true;
}
public static int iCompare(byte[] b1, byte[] b2)
{
int b1Len = (b1 == null) ? 0 : b1.Length;
int b2Len = (b2 == null) ? 0 : b2.Length;
int p = 0;
for (; ; )
{
if (b1Len == p)
return (b2Len == p) ? 0 : -1;
if (b2Len == p)
return 1;
if (b1[p] < b2[p])
return -1;
if (b1[p] > b2[p])
return 1;
p++;
}
}
public static string ToString(byte[] b)
{
return b == null ? "" : BitConverter.ToString(b).ToLower().Replace("-", "");
}
}
}

View File

@@ -0,0 +1,58 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using ROMVault2.RvDB;
namespace ROMVault2.Utils
{
public class DBTypeGet
{
public static FileType DirFromFile(FileType ft)
{
switch (ft)
{
case FileType.File:
return FileType.Dir;
case FileType.ZipFile:
return FileType.Zip;
}
return FileType.Zip;
}
public static FileType FileFromDir(FileType ft)
{
switch (ft)
{
case FileType.Dir:
return FileType.File;
case FileType.Zip:
return FileType.ZipFile;
}
return FileType.Zip;
}
public static bool isCompressedDir(FileType fileType)
{
return (fileType == FileType.Zip);
}
public static RvBase GetRvType(FileType fileType)
{
switch (fileType)
{
case FileType.Dir:
case FileType.Zip:
return new RvDir(fileType);
case FileType.File:
case FileType.ZipFile:
return new RvFile(fileType);
default:
throw new Exception("Unknown file type");
}
}
}
}

View File

@@ -0,0 +1,95 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
namespace ROMVault2.Utils
{
public static class RelativePath
{
/// <summary>
/// Creates a relative path from one file
/// or folder to another.
/// </summary>
/// <param name="fromDirectory">
/// Contains the directory that defines the
/// start of the relative path.
/// </param>
/// <param name="toPath">
/// Contains the path that defines the
/// endpoint of the relative path.
/// </param>
/// <returns>
/// The relative path from the start
/// directory to the end path.
/// </returns>
/// <exception cref="ArgumentNullException"></exception>
public static string MakeRelative(string fromDirectory, string toPath)
{
if (fromDirectory == null)
throw new ArgumentNullException("fromDirectory");
if (toPath == null)
throw new ArgumentNullException("toPath");
bool isRooted = (Path.IsPathRooted(fromDirectory) && Path.IsPathRooted(toPath));
if (isRooted)
{
bool isDifferentRoot = (String.Compare(Path.GetPathRoot(fromDirectory), Path.GetPathRoot(toPath), StringComparison.OrdinalIgnoreCase) != 0);
if (isDifferentRoot)
return toPath;
}
List<string> relativePath = new List<string>();
string[] fromDirectories = fromDirectory.Split(Path.DirectorySeparatorChar);
string[] toDirectories = toPath.Split(Path.DirectorySeparatorChar);
int length = Math.Min(fromDirectories.Length, toDirectories.Length);
int lastCommonRoot = -1;
// find common root
for (int x = 0; x < length; x++)
{
if (String.Compare(fromDirectories[x], toDirectories[x], StringComparison.OrdinalIgnoreCase) != 0)
break;
lastCommonRoot = x;
}
if (lastCommonRoot == -1)
return toPath;
// add relative folders in from path
for (int x = lastCommonRoot + 1; x < fromDirectories.Length; x++)
{
if (fromDirectories[x].Length > 0)
relativePath.Add("..");
}
// add to folders to path
for (int x = lastCommonRoot + 1; x < toDirectories.Length; x++)
{
relativePath.Add(toDirectories[x]);
}
// create relative path
string[] relativeParts = new string[relativePath.Count];
relativePath.CopyTo(relativeParts, 0);
string newPath = string.Join(Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture), relativeParts);
return newPath;
}
}
}

23
ROMVault2/Utils/ULong.cs Normal file
View File

@@ -0,0 +1,23 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
namespace ROMVault2.Utils
{
public static class ULong
{
public static int iCompare(ulong? a, ulong? b)
{
if ((a == null) || (b == null))
{
ReportError.SendAndShow("comparing null ulong? ");
return -1;
}
return Math.Sign(((ulong) a).CompareTo((ulong) b));
}
}
}

183
ROMVault2/Utils/VarFix.cs Normal file
View File

@@ -0,0 +1,183 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Xml;
namespace ROMVault2.Utils
{
public static class VarFix
{
public static bool StringYesNo(string b)
{
return b != null && ((b.ToLower() == "yes") || (b.ToLower() == "true"));
}
public static ulong? ULong(XmlNode n)
{
return ULong(n == null ? "" : n.InnerText);
}
public static ulong? ULong(string n)
{
if (string.IsNullOrEmpty(n))
return null;
if (n == "-")
return null;
try
{
if (n.Length >= 2 && n.Substring(0, 2).ToLower() == "0x")
{
return Convert.ToUInt64(n.Substring(2), 16);
}
return Convert.ToUInt64(n);
}
catch
{
return null;
}
}
public static string String(XmlNode n)
{
return String(n == null ? "" : n.InnerText);
}
public static string String(string n)
{
return n ?? "";
}
private const string ValidHexChar = "0123456789abcdef";
private static string CleanCheck(string crc, int length)
{
string retcrc = crc ?? "";
retcrc = retcrc.ToLower().Trim();
if (retcrc.Length >= 2 && retcrc.Substring(0, 2).ToLower() == "0x")
retcrc = retcrc.Substring(2);
if (retcrc == "-") retcrc="00000000";
for (int i = 0; i < retcrc.Length; i++)
if (ValidHexChar.IndexOf(retcrc.Substring(i, 1), StringComparison.Ordinal) < 0)
return "";
retcrc = (new String('0', length)) + retcrc;
retcrc = retcrc.Substring(retcrc.Length - length);
return retcrc;
}
//CleanMD5SHA1 with a null or empty string will return null
public static byte[] CleanMD5SHA1(XmlNode n, int length)
{
return CleanMD5SHA1(n == null ? null : n.InnerText, length);
}
public static byte[] CleanMD5SHA1(string checksum, int length)
{
if (string.IsNullOrEmpty(checksum)) return null;
checksum = checksum.ToLower().Trim();
if (checksum.Length >= 2)
if (checksum.Substring(0, 2) == "0x")
checksum = checksum.Substring(2);
if (string.IsNullOrEmpty(checksum)) return null;
if (checksum == "-") return null;
//if (checksum.Length % 2 == 1)
// checksum = "0" + checksum;
//if (checksum.Length != length)
// return null;
while (checksum.Length < length)
checksum = "0" + checksum;
int retL = checksum.Length / 2;
byte[] retB = new byte[retL];
for (int i = 0; i < retL; i++)
retB[i] = Convert.ToByte(checksum.Substring(i * 2, 2), 16);
return retB;
}
public static string CleanFullFileName(XmlNode n)
{
return CleanFullFileName(n == null ? "" : n.InnerText);
}
public static string CleanFullFileName(string name)
{
if (System.String.IsNullOrEmpty(name)) return "";
string retName = name;
retName = retName.TrimStart();
retName = retName.TrimEnd(new []{ '.', ' ' });
char[] charName = retName.ToCharArray();
for (int i = 0; i < charName.Length; i++)
{
int c = charName[i];
if (c == ':' || c == '*' || c == '?' || c == '<' || c == '>' || c == '|' || c < 32)
charName[i] = '-';
else if (c == '\\')
charName[i] = '/';
}
return new string(charName);
}
public static string CleanFileName(XmlNode n)
{
return CleanFileName(n == null ? "" : n.InnerText);
}
public static string CleanFileName(string name,char crep='-')
{
if (System.String.IsNullOrEmpty(name)) return "";
string retName = name;
retName = retName.TrimStart();
retName = retName.TrimEnd(new[] { '.', ' ' });
char[] charName = retName.ToCharArray();
for (int i = 0; i < charName.Length; i++)
{
int c = charName[i];
if (c == ':' || c == '*' || c == '?' || c == '<' || c == '>' || c == '|' || c == '\\' || c == '/' || c < 32)
charName[i] = crep;
}
return new string(charName);
}
public static string ToLower(XmlNode n)
{
return ToLower(n == null ? "" : n.InnerText);
}
public static string ToLower(string name)
{
return name == null ? "" : name.ToLower();
}
public static string PCombine(string path1, string path2)
{
if (System.String.IsNullOrEmpty(path1)) return path2;
if (System.String.IsNullOrEmpty(path2)) return path1;
return path1 + "/" + path2;
}
}
}

BIN
ROMVault2/chdman.exe Normal file

Binary file not shown.

BIN
ROMVault2/chip.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

97
ROMVault2/frmHelpAbout.Designer.cs generated Normal file
View File

@@ -0,0 +1,97 @@
namespace ROMVault2
{
partial class frmHelpAbout
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.lblVersion = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// lblVersion
//
this.lblVersion.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblVersion.Location = new System.Drawing.Point(12, 115);
this.lblVersion.Name = "lblVersion";
this.lblVersion.Size = new System.Drawing.Size(445, 15);
this.lblVersion.TabIndex = 6;
this.lblVersion.Text = "label1";
this.lblVersion.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Underline))), System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.ForeColor = System.Drawing.Color.Blue;
this.label1.Location = new System.Drawing.Point(279, 142);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(178, 16);
this.label1.TabIndex = 7;
this.label1.Text = "http://www.romvault.com/";
this.label1.Click += new System.EventHandler(this.label1_Click);
//
// label2
//
this.label2.AutoSize = true;
this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Underline))), System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label2.ForeColor = System.Drawing.Color.Blue;
this.label2.Location = new System.Drawing.Point(12, 142);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(167, 16);
this.label2.TabIndex = 8;
this.label2.Text = "support@romvault.com";
this.label2.Click += new System.EventHandler(this.label2_Click);
//
// frmHelpAbout
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackgroundImage = global::ROMVault2.rvImages.romvaultTZ;
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
this.ClientSize = new System.Drawing.Size(471, 172);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.lblVersion);
this.DoubleBuffered = true;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "frmHelpAbout";
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "frmHelpAbout";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label lblVersion;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
}
}

40
ROMVault2/frmHelpAbout.cs Normal file
View File

@@ -0,0 +1,40 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Windows.Forms;
namespace ROMVault2
{
public partial class frmHelpAbout : Form
{
public frmHelpAbout()
{
InitializeComponent();
Text = "Version "+Program.Version+"." + Program.SubVersion + " : " + Application.StartupPath;
lblVersion.Text = "Version "+Program.Version+"." + Program.SubVersion;
}
private void label1_Click(object sender, EventArgs e)
{
string url = "http://www.romvault.com/";
System.Diagnostics.Process.Start(url);
}
private void label2_Click(object sender, EventArgs e)
{
try
{
string url = "mailto:support@romvault.com?subject=Support " + Program.Version + "." + Program.SubVersion;
System.Diagnostics.Process.Start(url);
}
catch
{ }
}
}
}

120
ROMVault2/frmHelpAbout.resx Normal file
View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

55
ROMVault2/frmKey.Designer.cs generated Normal file
View File

@@ -0,0 +1,55 @@
namespace ROMVault2
{
partial class frmKey
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmKey));
this.SuspendLayout();
//
// frmKey
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.ControlDark;
this.ClientSize = new System.Drawing.Size(600, 532);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "frmKey";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Color Key to ROM Status";
this.Load += new System.EventHandler(this.frmKey_Load);
this.ResumeLayout(false);
}
#endregion
}
}

117
ROMVault2/frmKey.cs Normal file
View File

@@ -0,0 +1,117 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace ROMVault2
{
public partial class frmKey : Form
{
public frmKey()
{
InitializeComponent();
}
private void frmKey_Load(object sender, EventArgs e)
{
List<RepStatus> displayList= new List<RepStatus>
{
RepStatus.Missing,
RepStatus.Correct,
RepStatus.NotCollected,
RepStatus.UnNeeded,
RepStatus.Unknown,
RepStatus.InToSort,
RepStatus.Corrupt,
RepStatus.UnScanned,
RepStatus.Ignore,
RepStatus.CanBeFixed,
RepStatus.MoveToSort,
RepStatus.Delete,
RepStatus.NeededForFix,
};
Height = displayList.Count * 44 + 32;
for (int i = 0; i < displayList.Count; i++)
{
PictureBox pictureBox = new PictureBox();
pictureBox.BorderStyle = BorderStyle.FixedSingle;
pictureBox.Location = new Point(4, 4 + i * 44);
pictureBox.Name = "pictureBox" + i;
pictureBox.Size = new Size(48, 42);
pictureBox.TabIndex = 0;
pictureBox.TabStop = false;
Controls.Add(pictureBox);
Bitmap bm = rvImages.GetBitmap("G_" + displayList[i]);
pictureBox.Image = bm;
Label label = new Label();
label.BackColor = SystemColors.Control;
label.BorderStyle = BorderStyle.FixedSingle;
label.Location = new Point(54, 4 + i * 44);
label.TextAlign = ContentAlignment.MiddleLeft;
label.Name = "label" + i;
label.Size = new Size(542, 42);
label.TabIndex = 0;
String text;
switch (displayList[i])
{
case RepStatus.Missing:
text = "Red - This ROM is missing.";
break;
case RepStatus.Correct:
text = "Green - This ROM is Correct.";
break;
case RepStatus.NotCollected:
text = "Gray - This ROM is not collected. Either it is in the parent set, or it is a 'BadDump ROM'";
break;
case RepStatus.UnNeeded:
text = "Light Cyan - This ROM is unneeded here, as this ROM is collected in the parent set.";
break;
case RepStatus.Unknown:
text = "Cyan - This ROM is not needed here. (Find Fixes to see what should be done with this ROM)";
break;
case RepStatus.InToSort:
text = "Magenta - This ROM is in the ToSort directory, after Finding Fixes this ROM is not needed in any sets.";
break;
case RepStatus.Corrupt:
text = "Red - This ROM is Corrupt in the Zip File.";
break;
case RepStatus.UnScanned:
text = "Blue - This file could not be scanned as it is locked by another process.";
break;
case RepStatus.Ignore:
text = "GreyBlue - This file is found in the Ignore file list.";
break;
case RepStatus.CanBeFixed:
text = "Yellow - This ROM is missing here but has been found somewhere else, and so can be fixed.";
break;
case RepStatus.MoveToSort:
text = "Purple - This ROM is not found in any DAT set, and so will be moved out to ToSort.";
break;
case RepStatus.Delete:
text = "Brown - This ROM should be deleted, as a copy of it is correctly located somewhere else.";
break;
case RepStatus.NeededForFix:
text = "Orange - This Rom in not needed here, but is required in another set somewhere else.";
break;
default:
text = "";
break;
}
label.Text = text;
Controls.Add(label);
}
}
}
}

1787
ROMVault2/frmKey.resx Normal file

File diff suppressed because it is too large Load Diff

1104
ROMVault2/frmMain.Designer.cs generated Normal file

File diff suppressed because it is too large Load Diff

1339
ROMVault2/frmMain.cs Normal file

File diff suppressed because it is too large Load Diff

2236
ROMVault2/frmMain.resx Normal file

File diff suppressed because it is too large Load Diff

241
ROMVault2/frmSetDir.Designer.cs generated Normal file
View File

@@ -0,0 +1,241 @@
namespace ROMVault2
{
partial class FrmSetDir
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmSetDir));
this.DataGridGames = new System.Windows.Forms.DataGridView();
this.CDAT = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.CROM = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.btnDeleteSelected = new System.Windows.Forms.Button();
this.grpBoxAddNew = new System.Windows.Forms.GroupBox();
this.btnSetRomLocation = new System.Windows.Forms.Button();
this.txtROMLocation = new System.Windows.Forms.Label();
this.lblROMLocation = new System.Windows.Forms.Label();
this.txtDATLocation = new System.Windows.Forms.Label();
this.lblDATLocation = new System.Windows.Forms.Label();
this.lblDelete = new System.Windows.Forms.Label();
this.btnClose = new System.Windows.Forms.Button();
this.btnResetAll = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.DataGridGames)).BeginInit();
this.grpBoxAddNew.SuspendLayout();
this.SuspendLayout();
//
// DataGridGames
//
this.DataGridGames.AllowUserToAddRows = false;
this.DataGridGames.AllowUserToDeleteRows = false;
this.DataGridGames.AllowUserToResizeRows = false;
this.DataGridGames.BackgroundColor = System.Drawing.Color.White;
this.DataGridGames.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.DataGridGames.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.CDAT,
this.CROM});
this.DataGridGames.GridColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
this.DataGridGames.Location = new System.Drawing.Point(12, 135);
this.DataGridGames.Name = "DataGridGames";
this.DataGridGames.ReadOnly = true;
this.DataGridGames.RowHeadersVisible = false;
this.DataGridGames.RowTemplate.Height = 17;
this.DataGridGames.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
this.DataGridGames.ShowCellErrors = false;
this.DataGridGames.ShowCellToolTips = false;
this.DataGridGames.ShowEditingIcon = false;
this.DataGridGames.ShowRowErrors = false;
this.DataGridGames.Size = new System.Drawing.Size(670, 214);
this.DataGridGames.TabIndex = 10;
this.DataGridGames.DoubleClick += new System.EventHandler(this.DataGridGamesDoubleClick);
//
// CDAT
//
this.CDAT.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.CDAT.HeaderText = "DAT Location";
this.CDAT.Name = "CDAT";
this.CDAT.ReadOnly = true;
//
// CROM
//
this.CROM.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.CROM.HeaderText = "ROM Location";
this.CROM.Name = "CROM";
this.CROM.ReadOnly = true;
//
// btnDeleteSelected
//
this.btnDeleteSelected.Location = new System.Drawing.Point(12, 355);
this.btnDeleteSelected.Name = "btnDeleteSelected";
this.btnDeleteSelected.Size = new System.Drawing.Size(96, 25);
this.btnDeleteSelected.TabIndex = 11;
this.btnDeleteSelected.Text = "Delete Selected";
this.btnDeleteSelected.UseVisualStyleBackColor = true;
this.btnDeleteSelected.Click += new System.EventHandler(this.BtnDeleteSelectedClick);
//
// grpBoxAddNew
//
this.grpBoxAddNew.Controls.Add(this.btnSetRomLocation);
this.grpBoxAddNew.Controls.Add(this.txtROMLocation);
this.grpBoxAddNew.Controls.Add(this.lblROMLocation);
this.grpBoxAddNew.Controls.Add(this.txtDATLocation);
this.grpBoxAddNew.Controls.Add(this.lblDATLocation);
this.grpBoxAddNew.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.grpBoxAddNew.Location = new System.Drawing.Point(12, 12);
this.grpBoxAddNew.Name = "grpBoxAddNew";
this.grpBoxAddNew.Size = new System.Drawing.Size(670, 91);
this.grpBoxAddNew.TabIndex = 14;
this.grpBoxAddNew.TabStop = false;
this.grpBoxAddNew.Text = "Add New Directory Mapping";
//
// btnSetRomLocation
//
this.btnSetRomLocation.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnSetRomLocation.Location = new System.Drawing.Point(617, 53);
this.btnSetRomLocation.Name = "btnSetRomLocation";
this.btnSetRomLocation.Size = new System.Drawing.Size(47, 24);
this.btnSetRomLocation.TabIndex = 14;
this.btnSetRomLocation.Text = "Set";
this.btnSetRomLocation.UseVisualStyleBackColor = true;
this.btnSetRomLocation.Click += new System.EventHandler(this.BtnSetRomLocationClick);
//
// txtROMLocation
//
this.txtROMLocation.BackColor = System.Drawing.Color.White;
this.txtROMLocation.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.txtROMLocation.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtROMLocation.Location = new System.Drawing.Point(89, 55);
this.txtROMLocation.Name = "txtROMLocation";
this.txtROMLocation.Size = new System.Drawing.Size(515, 22);
this.txtROMLocation.TabIndex = 13;
this.txtROMLocation.Text = "label2";
this.txtROMLocation.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// lblROMLocation
//
this.lblROMLocation.AutoSize = true;
this.lblROMLocation.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblROMLocation.Location = new System.Drawing.Point(12, 60);
this.lblROMLocation.Name = "lblROMLocation";
this.lblROMLocation.Size = new System.Drawing.Size(79, 13);
this.lblROMLocation.TabIndex = 12;
this.lblROMLocation.Text = "ROM Location:";
//
// txtDATLocation
//
this.txtDATLocation.BackColor = System.Drawing.Color.White;
this.txtDATLocation.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.txtDATLocation.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtDATLocation.Location = new System.Drawing.Point(89, 25);
this.txtDATLocation.Name = "txtDATLocation";
this.txtDATLocation.Size = new System.Drawing.Size(515, 22);
this.txtDATLocation.TabIndex = 11;
this.txtDATLocation.Text = "label2";
this.txtDATLocation.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// lblDATLocation
//
this.lblDATLocation.AutoSize = true;
this.lblDATLocation.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblDATLocation.Location = new System.Drawing.Point(12, 30);
this.lblDATLocation.Name = "lblDATLocation";
this.lblDATLocation.Size = new System.Drawing.Size(76, 13);
this.lblDATLocation.TabIndex = 10;
this.lblDATLocation.Text = "DAT Location:";
//
// lblDelete
//
this.lblDelete.AutoSize = true;
this.lblDelete.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblDelete.Location = new System.Drawing.Point(20, 111);
this.lblDelete.Name = "lblDelete";
this.lblDelete.Size = new System.Drawing.Size(144, 13);
this.lblDelete.TabIndex = 15;
this.lblDelete.Text = "Delete Existing Mapping";
//
// btnClose
//
this.btnClose.Location = new System.Drawing.Point(586, 355);
this.btnClose.Name = "btnClose";
this.btnClose.Size = new System.Drawing.Size(96, 25);
this.btnClose.TabIndex = 16;
this.btnClose.Text = "Done";
this.btnClose.UseVisualStyleBackColor = true;
this.btnClose.Click += new System.EventHandler(this.BtnCloseClick);
//
// btnResetAll
//
this.btnResetAll.Location = new System.Drawing.Point(138, 355);
this.btnResetAll.Name = "btnResetAll";
this.btnResetAll.Size = new System.Drawing.Size(96, 25);
this.btnResetAll.TabIndex = 17;
this.btnResetAll.Text = "Reset All";
this.btnResetAll.UseVisualStyleBackColor = true;
this.btnResetAll.Click += new System.EventHandler(this.BtnResetAllClick);
//
// FrmSetDir
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(694, 391);
this.Controls.Add(this.btnResetAll);
this.Controls.Add(this.btnClose);
this.Controls.Add(this.lblDelete);
this.Controls.Add(this.grpBoxAddNew);
this.Controls.Add(this.btnDeleteSelected);
this.Controls.Add(this.DataGridGames);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "FrmSetDir";
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Set ROM Directories";
this.Activated += new System.EventHandler(this.FrmSetDirActivated);
((System.ComponentModel.ISupportInitialize)(this.DataGridGames)).EndInit();
this.grpBoxAddNew.ResumeLayout(false);
this.grpBoxAddNew.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.DataGridView DataGridGames;
private System.Windows.Forms.DataGridViewTextBoxColumn CDAT;
private System.Windows.Forms.DataGridViewTextBoxColumn CROM;
private System.Windows.Forms.Button btnDeleteSelected;
private System.Windows.Forms.GroupBox grpBoxAddNew;
private System.Windows.Forms.Button btnSetRomLocation;
private System.Windows.Forms.Label txtROMLocation;
private System.Windows.Forms.Label lblROMLocation;
private System.Windows.Forms.Label txtDATLocation;
private System.Windows.Forms.Label lblDATLocation;
private System.Windows.Forms.Label lblDelete;
private System.Windows.Forms.Button btnClose;
private System.Windows.Forms.Button btnResetAll;
}
}

167
ROMVault2/frmSetDir.cs Normal file
View File

@@ -0,0 +1,167 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Drawing;
using System.Windows.Forms;
using ROMVault2.Properties;
using ROMVault2.Utils;
namespace ROMVault2
{
public partial class FrmSetDir : Form
{
private string _datLocation;
private readonly Color _cMagenta = Color.FromArgb(255, 214, 255);
private readonly Color _cGreen = Color.FromArgb(214, 255, 214);
private readonly Color _cYellow = Color.FromArgb(255, 255, 214);
public FrmSetDir()
{
InitializeComponent();
}
public void SetLocation(string dLocation)
{
_datLocation = dLocation;
txtDATLocation.Text = _datLocation;
txtROMLocation.Text = DBHelper.GetRealPath(_datLocation);
UpdateGrid();
}
private void UpdateGrid()
{
DataGridGames.Rows.Clear();
foreach (DirMap t in Settings.DirPathMap)
{
DataGridGames.Rows.Add();
int row = DataGridGames.Rows.Count - 1;
string key = t.DirKey;
DataGridGames.Rows[row].Cells["CDAT"].Value = t.DirKey;
DataGridGames.Rows[row].Cells["CROM"].Value = t.DirPath;
if (key == "ToSort")
{
DataGridGames.Rows[row].Cells["CDAT"].Style.BackColor = _cMagenta;
DataGridGames.Rows[row].Cells["CROM"].Style.BackColor = _cMagenta;
}
else if (key == _datLocation)
{
DataGridGames.Rows[row].Cells["CDAT"].Style.BackColor = _cGreen;
DataGridGames.Rows[row].Cells["CROM"].Style.BackColor = _cGreen;
}
else if (key.Length >= _datLocation.Length)
{
if (key.Substring(0, _datLocation.Length) == _datLocation)
{
DataGridGames.Rows[row].Cells["CDAT"].Style.BackColor = _cYellow;
DataGridGames.Rows[row].Cells["CROM"].Style.BackColor = _cYellow;
}
}
}
for (int j = 0; j < DataGridGames.Rows.Count; j++)
{
DataGridGames.Rows[j].Selected = false;
}
}
private void BtnSetRomLocationClick(object sender, EventArgs e)
{
FolderBrowserDialog browse = new FolderBrowserDialog
{
ShowNewFolderButton = true,
Description = Resources.FrmSetDir_BtnSetRomLocationClick_Please_select_a_folder_for_This_Rom_Set,
RootFolder = Environment.SpecialFolder.DesktopDirectory,
SelectedPath = DBHelper.GetRealPath(_datLocation)
};
if (browse.ShowDialog() == DialogResult.OK)
{
for (int i = 0; i < Settings.DirPathMap.Count; i++)
{
if (Settings.DirPathMap[i].DirKey == _datLocation)
{
Settings.DirPathMap.RemoveAt(i);
i--;
}
}
string relPath = RelativePath.MakeRelative(AppDomain.CurrentDomain.BaseDirectory, browse.SelectedPath);
Settings.DirPathMap.Add(new DirMap(_datLocation, relPath));
Settings.DirPathMap.Sort();
SetLocation(_datLocation);
Settings.WriteConfig();
//db.CheckNamesToLong();
}
}
private void BtnDeleteSelectedClick(object sender, EventArgs e)
{
for (int j = 0; j < DataGridGames.SelectedRows.Count; j++)
{
string datLocation = DataGridGames.SelectedRows[j].Cells["CDAT"].Value.ToString();
if (datLocation == "ToSort" || datLocation == "RomVault")
{
ReportError.Show(Resources.FrmSetDir_BtnDeleteSelectedClick_You_cannot_delete_the + datLocation + Resources.FrmSetDir_BtnDeleteSelectedClick_Directory_Settings,
Resources.FrmSetDir_BtnDeleteSelectedClick_RomVault_Rom_Location);
}
else
{
for (int i = 0; i < Settings.DirPathMap.Count; i++)
{
if (Settings.DirPathMap[i].DirKey == datLocation)
{
Settings.DirPathMap.RemoveAt(i);
i--;
}
}
}
}
Settings.WriteConfig();
UpdateGrid();
//db.CheckNamesToLong();
}
private void BtnCloseClick(object sender, EventArgs e)
{
//db.CheckNamesToLong();
Close();
}
private void DataGridGamesDoubleClick(object sender, EventArgs e)
{
if (DataGridGames.SelectedRows.Count <= 0) return;
grpBoxAddNew.Text = Resources.FrmSetDir_DataGridGamesDoubleClick_Edit_Existing_Directory_Mapping;
SetLocation(DataGridGames.SelectedRows[0].Cells["CDAT"].Value.ToString());
}
private void FrmSetDirActivated(object sender, EventArgs e)
{
for (int j = 0; j < DataGridGames.Rows.Count; j++)
{
DataGridGames.Rows[j].Selected = false;
}
}
private void BtnResetAllClick(object sender, EventArgs e)
{
Settings.ResetDirectories();
Settings.WriteConfig();
UpdateGrid();
}
}
}

271
ROMVault2/frmSettings.Designer.cs generated Normal file
View File

@@ -0,0 +1,271 @@
namespace ROMVault2
{
partial class FrmSettings
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.lblDATRoot = new System.Windows.Forms.Label();
this.btnDAT = new System.Windows.Forms.Button();
this.btnOK = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.label4 = new System.Windows.Forms.Label();
this.cboFixLevel = new System.Windows.Forms.ComboBox();
this.cboScanLevel = new System.Windows.Forms.ComboBox();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.chkDebugLogs = new System.Windows.Forms.CheckBox();
this.chkCacheSaveTimer = new System.Windows.Forms.CheckBox();
this.upTime = new System.Windows.Forms.NumericUpDown();
this.label5 = new System.Windows.Forms.Label();
this.chkDoubleCheckDelete = new System.Windows.Forms.CheckBox();
((System.ComponentModel.ISupportInitialize)(this.upTime)).BeginInit();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(8, 19);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(103, 13);
this.label1.TabIndex = 0;
this.label1.Text = "DAT Root Directory:";
//
// lblDATRoot
//
this.lblDATRoot.BackColor = System.Drawing.Color.White;
this.lblDATRoot.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.lblDATRoot.Location = new System.Drawing.Point(123, 14);
this.lblDATRoot.Name = "lblDATRoot";
this.lblDATRoot.Size = new System.Drawing.Size(357, 22);
this.lblDATRoot.TabIndex = 3;
this.lblDATRoot.Text = "label4";
this.lblDATRoot.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// btnDAT
//
this.btnDAT.Location = new System.Drawing.Point(486, 12);
this.btnDAT.Name = "btnDAT";
this.btnDAT.Size = new System.Drawing.Size(47, 24);
this.btnDAT.TabIndex = 6;
this.btnDAT.Text = "Set";
this.btnDAT.UseVisualStyleBackColor = true;
this.btnDAT.Click += new System.EventHandler(this.BtnDatClick);
//
// btnOK
//
this.btnOK.Location = new System.Drawing.Point(167, 314);
this.btnOK.Name = "btnOK";
this.btnOK.Size = new System.Drawing.Size(89, 23);
this.btnOK.TabIndex = 9;
this.btnOK.Text = "OK";
this.btnOK.UseVisualStyleBackColor = true;
this.btnOK.Click += new System.EventHandler(this.BtnOkClick);
//
// btnCancel
//
this.btnCancel.Location = new System.Drawing.Point(280, 314);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(89, 23);
this.btnCancel.TabIndex = 10;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
this.btnCancel.Click += new System.EventHandler(this.BtnCancelClick);
//
// textBox1
//
this.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.textBox1.Location = new System.Drawing.Point(123, 111);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(357, 136);
this.textBox1.TabIndex = 12;
//
// label4
//
this.label4.Location = new System.Drawing.Point(8, 113);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(106, 72);
this.label4.TabIndex = 13;
this.label4.Text = "Filenames not to remove from RomDir\'s : (Put each file on its ow" +
"n line)";
//
// cboFixLevel
//
this.cboFixLevel.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cboFixLevel.FormattingEnabled = true;
this.cboFixLevel.Location = new System.Drawing.Point(123, 75);
this.cboFixLevel.Name = "cboFixLevel";
this.cboFixLevel.Size = new System.Drawing.Size(357, 21);
this.cboFixLevel.TabIndex = 14;
//
// cboScanLevel
//
this.cboScanLevel.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cboScanLevel.FormattingEnabled = true;
this.cboScanLevel.Location = new System.Drawing.Point(123, 48);
this.cboScanLevel.Name = "cboScanLevel";
this.cboScanLevel.Size = new System.Drawing.Size(357, 21);
this.cboScanLevel.TabIndex = 15;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(8, 51);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(84, 13);
this.label2.TabIndex = 16;
this.label2.Text = "Scanning Level:";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(8, 79);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(66, 13);
this.label3.TabIndex = 17;
this.label3.Text = "Fixing Level:";
//
// chkDebugLogs
//
this.chkDebugLogs.AutoSize = true;
this.chkDebugLogs.Location = new System.Drawing.Point(279, 261);
this.chkDebugLogs.Name = "chkDebugLogs";
this.chkDebugLogs.Size = new System.Drawing.Size(126, 17);
this.chkDebugLogs.TabIndex = 18;
this.chkDebugLogs.Text = "Debug Logs Enabled";
this.chkDebugLogs.UseVisualStyleBackColor = true;
//
// chkCacheSaveTimer
//
this.chkCacheSaveTimer.AutoSize = true;
this.chkCacheSaveTimer.Location = new System.Drawing.Point(125, 285);
this.chkCacheSaveTimer.Name = "chkCacheSaveTimer";
this.chkCacheSaveTimer.Size = new System.Drawing.Size(156, 17);
this.chkCacheSaveTimer.TabIndex = 19;
this.chkCacheSaveTimer.Text = "Save Cache On Timer Ever";
this.chkCacheSaveTimer.UseVisualStyleBackColor = true;
//
// upTime
//
this.upTime.Increment = new decimal(new int[] {
5,
0,
0,
0});
this.upTime.Location = new System.Drawing.Point(279, 283);
this.upTime.Maximum = new decimal(new int[] {
60,
0,
0,
0});
this.upTime.Minimum = new decimal(new int[] {
5,
0,
0,
0});
this.upTime.Name = "upTime";
this.upTime.Size = new System.Drawing.Size(47, 20);
this.upTime.TabIndex = 20;
this.upTime.Value = new decimal(new int[] {
10,
0,
0,
0});
//
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(329, 286);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(44, 13);
this.label5.TabIndex = 21;
this.label5.Text = "Minutes";
//
// chkDoubleCheckDelete
//
this.chkDoubleCheckDelete.AutoSize = true;
this.chkDoubleCheckDelete.Location = new System.Drawing.Point(125, 261);
this.chkDoubleCheckDelete.Name = "chkDoubleCheckDelete";
this.chkDoubleCheckDelete.Size = new System.Drawing.Size(128, 17);
this.chkDoubleCheckDelete.TabIndex = 22;
this.chkDoubleCheckDelete.Text = "Double Check Delete";
this.chkDoubleCheckDelete.UseVisualStyleBackColor = true;
//
// FrmSettings
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(545, 346);
this.Controls.Add(this.chkDoubleCheckDelete);
this.Controls.Add(this.label5);
this.Controls.Add(this.upTime);
this.Controls.Add(this.chkCacheSaveTimer);
this.Controls.Add(this.chkDebugLogs);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.cboScanLevel);
this.Controls.Add(this.cboFixLevel);
this.Controls.Add(this.label4);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnOK);
this.Controls.Add(this.btnDAT);
this.Controls.Add(this.lblDATRoot);
this.Controls.Add(this.label1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "FrmSettings";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "RomVault Settings";
this.Load += new System.EventHandler(this.FrmConfigLoad);
((System.ComponentModel.ISupportInitialize)(this.upTime)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label lblDATRoot;
private System.Windows.Forms.Button btnDAT;
private System.Windows.Forms.Button btnOK;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.ComboBox cboFixLevel;
private System.Windows.Forms.ComboBox cboScanLevel;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.CheckBox chkDebugLogs;
private System.Windows.Forms.CheckBox chkCacheSaveTimer;
private System.Windows.Forms.NumericUpDown upTime;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.CheckBox chkDoubleCheckDelete;
}
}

101
ROMVault2/frmSettings.cs Normal file
View File

@@ -0,0 +1,101 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using ROMVault2.Properties;
namespace ROMVault2
{
public partial class FrmSettings : Form
{
public FrmSettings()
{
InitializeComponent();
cboScanLevel.Items.Clear();
cboScanLevel.Items.Add("Level1");
cboScanLevel.Items.Add("Level2");
cboScanLevel.Items.Add("Level3");
cboFixLevel.Items.Clear();
cboFixLevel.Items.Add("TorrentZip Level 1");
cboFixLevel.Items.Add("TorrentZip Level 2");
cboFixLevel.Items.Add("TorrentZip Level 3");
cboFixLevel.Items.Add("Level1");
cboFixLevel.Items.Add("Level2");
cboFixLevel.Items.Add("Level3");
}
private void FrmConfigLoad(object sender, EventArgs e)
{
lblDATRoot.Text = Settings.DatRoot;
cboScanLevel.SelectedIndex = (int)Settings.ScanLevel;
cboFixLevel.SelectedIndex = (int)Settings.FixLevel;
textBox1.Text = "";
for (int i = 0; i < Settings.IgnoreFiles.Count; i++)
textBox1.Text += Settings.IgnoreFiles[i] + Environment.NewLine;
chkDoubleCheckDelete.Checked = Settings.DoubleCheckDelete;
chkCacheSaveTimer.Checked = Settings.CacheSaveTimerEnabled;
upTime.Value = Settings.CacheSaveTimePeriod;
chkDebugLogs.Checked = Settings.DebugLogsEnabled;
}
private void BtnCancelClick(object sender, EventArgs e)
{
Close();
}
private void BtnOkClick(object sender, EventArgs e)
{
Settings.DatRoot = lblDATRoot.Text;
Settings.ScanLevel = (eScanLevel)cboScanLevel.SelectedIndex;
Settings.FixLevel = (eFixLevel)cboFixLevel.SelectedIndex;
string strtxt = textBox1.Text;
strtxt = strtxt.Replace("\r", "");
string[] strsplit = strtxt.Split('\n');
Settings.IgnoreFiles = new List<string>(strsplit);
for (int i = 0; i < Settings.IgnoreFiles.Count; i++)
{
Settings.IgnoreFiles[i] = Settings.IgnoreFiles[i].Trim();
if (string.IsNullOrEmpty(Settings.IgnoreFiles[i]))
{
Settings.IgnoreFiles.RemoveAt(i);
i--;
}
}
Settings.DoubleCheckDelete = chkDoubleCheckDelete.Checked;
Settings.DebugLogsEnabled = chkDebugLogs.Checked;
Settings.CacheSaveTimerEnabled = chkCacheSaveTimer.Checked;
Settings.CacheSaveTimePeriod = (int)upTime.Value;
Settings.WriteConfig();
Close();
}
private void BtnDatClick(object sender, EventArgs e)
{
FolderBrowserDialog browse = new FolderBrowserDialog
{
ShowNewFolderButton = true,
Description = Resources.FrmSettings_BtnDatClick_Please_select_a_folder_for_DAT_Root,
RootFolder = Environment.SpecialFolder.DesktopDirectory,
SelectedPath = Settings.DatRoot
};
if (browse.ShowDialog() != DialogResult.OK) return;
lblDATRoot.Text = Utils.RelativePath.MakeRelative(AppDomain.CurrentDomain.BaseDirectory, browse.SelectedPath);
}
}
}

120
ROMVault2/frmSettings.resx Normal file
View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

89
ROMVault2/frmShowError.Designer.cs generated Normal file
View File

@@ -0,0 +1,89 @@
namespace ROMVault2
{
partial class frmShowError
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmShowError));
this.textBox1 = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(12, 12);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.textBox1.Size = new System.Drawing.Size(565, 525);
this.textBox1.TabIndex = 0;
//
// button1
//
this.button1.Location = new System.Drawing.Point(460, 543);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(117, 28);
this.button1.TabIndex = 1;
this.button1.Text = "Exit";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(20, 551);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(202, 13);
this.label1.TabIndex = 2;
this.label1.Text = "Sending Error Message to RomVault.Com";
//
// frmShowError
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(589, 583);
this.Controls.Add(this.label1);
this.Controls.Add(this.button1);
this.Controls.Add(this.textBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "frmShowError";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "RomVault Error report";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Label label1;
}
}

29
ROMVault2/frmShowError.cs Normal file
View File

@@ -0,0 +1,29 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Windows.Forms;
namespace ROMVault2
{
public partial class frmShowError : Form
{
public frmShowError()
{
InitializeComponent();
}
public void settype(string s)
{
textBox1.Text = s;
}
private void button1_Click(object sender, EventArgs e)
{
Environment.Exit(0);
}
}
}

1787
ROMVault2/frmShowError.resx Normal file

File diff suppressed because it is too large Load Diff

119
ROMVault2/frmSplashScreen.Designer.cs generated Normal file
View File

@@ -0,0 +1,119 @@
namespace ROMVault2
{
partial class FrmSplashScreen
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmSplashScreen));
this.lblStatus = new System.Windows.Forms.Label();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.progressBar = new System.Windows.Forms.ProgressBar();
this.lblVersion = new System.Windows.Forms.Label();
this.bgWork = new System.ComponentModel.BackgroundWorker();
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// lblStatus
//
this.lblStatus.BackColor = System.Drawing.Color.White;
this.lblStatus.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.lblStatus.ImageAlign = System.Drawing.ContentAlignment.TopLeft;
this.lblStatus.Location = new System.Drawing.Point(7, 135);
this.lblStatus.Name = "lblStatus";
this.lblStatus.Padding = new System.Windows.Forms.Padding(2, 2, 0, 0);
this.lblStatus.Size = new System.Drawing.Size(450, 20);
this.lblStatus.TabIndex = 0;
//
// timer1
//
this.timer1.Tick += new System.EventHandler(this.Timer1Tick);
//
// progressBar
//
this.progressBar.Location = new System.Drawing.Point(7, 159);
this.progressBar.Name = "progressBar";
this.progressBar.Size = new System.Drawing.Size(450, 19);
this.progressBar.TabIndex = 4;
//
// lblVersion
//
this.lblVersion.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblVersion.Location = new System.Drawing.Point(10, 113);
this.lblVersion.Name = "lblVersion";
this.lblVersion.Size = new System.Drawing.Size(445, 15);
this.lblVersion.TabIndex = 5;
this.lblVersion.Text = "label1";
this.lblVersion.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// bgWork
//
this.bgWork.WorkerReportsProgress = true;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 185);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(35, 13);
this.label1.TabIndex = 6;
this.label1.Text = "label1";
//
// FrmSplashScreen
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage")));
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
this.ClientSize = new System.Drawing.Size(465, 207);
this.ControlBox = false;
this.Controls.Add(this.label1);
this.Controls.Add(this.lblVersion);
this.Controls.Add(this.progressBar);
this.Controls.Add(this.lblStatus);
this.DoubleBuffered = true;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "FrmSplashScreen";
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "frmSplashScreen";
this.Shown += new System.EventHandler(this.FrmSplashScreenShown);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label lblStatus;
private System.Windows.Forms.Timer timer1;
private System.Windows.Forms.ProgressBar progressBar;
private System.Windows.Forms.Label lblVersion;
private System.ComponentModel.BackgroundWorker bgWork;
private System.Windows.Forms.Label label1;
}
}

View File

@@ -0,0 +1,159 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.ComponentModel;
using System.ServiceModel;
using System.Threading;
using System.Windows.Forms;
using ROMVault2.Properties;
using ROMVault2.RVRef;
using ROMVault2.RvDB;
namespace ROMVault2
{
public partial class FrmSplashScreen : Form
{
private double _opacityIncrement = 0.05;
public FrmSplashScreen()
{
InitializeComponent();
lblVersion.Text = @"Version " + Program.Version + @"." + Program.SubVersion + Resources.FixFiles_FixZip_Colon + Application.StartupPath;
Opacity = 0;
timer1.Interval = 50;
label1.Text = @"Registered to : " + Settings.Username + @" Contact Email (" + Settings.EMail + @")";
bgWork.DoWork += StartUpCode;
bgWork.ProgressChanged += BgwProgressChanged;
bgWork.RunWorkerCompleted += BgwRunWorkerCompleted;
}
private void FrmSplashScreenShown(object sender, EventArgs e)
{
bgWork.RunWorkerAsync(SynchronizationContext.Current);
timer1.Start();
}
private void StartUpCode(object sender, DoWorkEventArgs e)
{
BasicHttpBinding b = new BasicHttpBinding { SendTimeout = new TimeSpan(0, 0, 20), ReceiveTimeout = new TimeSpan(0, 0, 20) };
EndpointAddress ep = new EndpointAddress(@"http://services.romvault.com/Service1.svc");
Service1Client s = new Service1Client(b, ep);
if (string.IsNullOrEmpty(Settings.Username) || string.IsNullOrEmpty(Settings.EMail))
{
FrmRegistration freg = new FrmRegistration();
freg.ShowDialog();
freg.Dispose();
}
bool isNetworkAvailable = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();
string r = "OK";
try
{
if (isNetworkAvailable)
r = s.SendUser1(Settings.Username, Settings.EMail, Program.Version, Program.SubVersion);
}
catch (Exception)
{
r = "OK";
}
if (r != "OK")
{
Program.ErrorMessage=Resources.Program_Main_You_are_not_Authorised_to_use_this_program;
return;
}
// normal check ends
string thisV = Program.Version + "." + Program.SubVersion.ToString("0000");
string v = thisV;
try
{
if (isNetworkAvailable)
v = s.GetLatestVersion1(Program.Version, Program.SubVersion);
}
catch (Exception)
{
v = thisV;
}
if (String.Compare(v, thisV, StringComparison.Ordinal) > 0)
{
Program.URL = s.GetUpdateLink1(Program.Version, Program.SubVersion);
Program.ErrorMessage=Resources.Program_Main_There_is_a_new_release_download_now_from + Program.URL;
return;
}
s.Close();
RepairStatus.InitStatusCheck();
Settings.SetDefaults();
DB.Read(sender,e);
}
private void BgwProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (e.UserState == null)
{
if (e.ProgressPercentage >= progressBar.Minimum && e.ProgressPercentage <= progressBar.Maximum)
progressBar.Value = e.ProgressPercentage;
return;
}
bgwSetRange bgwSr = e.UserState as bgwSetRange;
if (bgwSr != null)
{
progressBar.Minimum = 0;
progressBar.Maximum = bgwSr.MaxVal;
progressBar.Value = 0;
return;
}
bgwText bgwT = e.UserState as bgwText;
if (bgwT != null)
{
lblStatus.Text = bgwT.Text;
}
}
private void BgwRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
_opacityIncrement = -0.1;
timer1.Start();
}
private void Timer1Tick(object sender, EventArgs e)
{
if (_opacityIncrement > 0)
{
if (Opacity < 1)
Opacity += _opacityIncrement;
else
timer1.Stop();
}
else
{
if (Opacity > 0)
Opacity += _opacityIncrement;
else
{
timer1.Stop();
Close();
}
}
}
}
}

View File

@@ -0,0 +1,587 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="timer1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="bgWork.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>104, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAdEAAABuCAYAAAB4KCmPAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAACH
DwAAjA8AAP1SAACBQAAAfXkAAOmLAAA85QAAGcxzPIV3AAAKOWlDQ1BQaG90b3Nob3AgSUNDIHByb2Zp
bGUAAEjHnZZ3VFTXFofPvXd6oc0wAlKG3rvAANJ7k15FYZgZYCgDDjM0sSGiAhFFRJoiSFDEgNFQJFZE
sRAUVLAHJAgoMRhFVCxvRtaLrqy89/Ly++Osb+2z97n77L3PWhcAkqcvl5cGSwGQyhPwgzyc6RGRUXTs
AIABHmCAKQBMVka6X7B7CBDJy82FniFyAl8EAfB6WLwCcNPQM4BOB/+fpFnpfIHomAARm7M5GSwRF4g4
JUuQLrbPipgalyxmGCVmvihBEcuJOWGRDT77LLKjmNmpPLaIxTmns1PZYu4V8bZMIUfEiK+ICzO5nCwR
3xKxRoowlSviN+LYVA4zAwAUSWwXcFiJIjYRMYkfEuQi4uUA4EgJX3HcVyzgZAvEl3JJS8/hcxMSBXQd
li7d1NqaQffkZKVwBALDACYrmcln013SUtOZvBwAFu/8WTLi2tJFRbY0tba0NDQzMv2qUP91829K3NtF
ehn4uWcQrf+L7a/80hoAYMyJarPziy2uCoDOLQDI3fti0zgAgKSobx3Xv7oPTTwviQJBuo2xcVZWlhGX
wzISF/QP/U+Hv6GvvmckPu6P8tBdOfFMYYqALq4bKy0lTcinZ6QzWRy64Z+H+B8H/nUeBkGceA6fwxNF
hImmjMtLELWbx+YKuGk8Opf3n5r4D8P+pMW5FonS+BFQY4yA1HUqQH7tBygKESDR+8Vd/6NvvvgwIH55
4SqTi3P/7zf9Z8Gl4iWDm/A5ziUohM4S8jMX98TPEqABAUgCKpAHykAd6ABDYAasgC1wBG7AG/iDEBAJ
VgMWSASpgA+yQB7YBApBMdgJ9oBqUAcaQTNoBcdBJzgFzoNL4Bq4AW6D+2AUTIBnYBa8BgsQBGEhMkSB
5CEVSBPSh8wgBmQPuUG+UBAUCcVCCRAPEkJ50GaoGCqDqqF6qBn6HjoJnYeuQIPQXWgMmoZ+h97BCEyC
qbASrAUbwwzYCfaBQ+BVcAK8Bs6FC+AdcCXcAB+FO+Dz8DX4NjwKP4PnEIAQERqiihgiDMQF8UeikHiE
j6xHipAKpAFpRbqRPuQmMorMIG9RGBQFRUcZomxRnqhQFAu1BrUeVYKqRh1GdaB6UTdRY6hZ1Ec0Ga2I
1kfboL3QEegEdBa6EF2BbkK3oy+ib6Mn0K8xGAwNo42xwnhiIjFJmLWYEsw+TBvmHGYQM46Zw2Kx8lh9
rB3WH8vECrCF2CrsUexZ7BB2AvsGR8Sp4Mxw7rgoHA+Xj6vAHcGdwQ3hJnELeCm8Jt4G749n43PwpfhG
fDf+On4Cv0CQJmgT7AghhCTCJkIloZVwkfCA8JJIJKoRrYmBRC5xI7GSeIx4mThGfEuSIemRXEjRJCFp
B+kQ6RzpLuklmUzWIjuSo8gC8g5yM/kC+RH5jQRFwkjCS4ItsUGiRqJDYkjiuSReUlPSSXK1ZK5kheQJ
yeuSM1J4KS0pFymm1HqpGqmTUiNSc9IUaVNpf+lU6RLpI9JXpKdksDJaMm4ybJkCmYMyF2TGKQhFneJC
YVE2UxopFykTVAxVm+pFTaIWU7+jDlBnZWVkl8mGyWbL1sielh2lITQtmhcthVZKO04bpr1borTEaQln
yfYlrUuGlszLLZVzlOPIFcm1yd2WeydPl3eTT5bfJd8p/1ABpaCnEKiQpbBf4aLCzFLqUtulrKVFS48v
vacIK+opBimuVTyo2K84p6Ss5KGUrlSldEFpRpmm7KicpFyufEZ5WoWiYq/CVSlXOavylC5Ld6Kn0Cvp
vfRZVUVVT1Whar3qgOqCmrZaqFq+WpvaQ3WCOkM9Xr1cvUd9VkNFw08jT6NF454mXpOhmai5V7NPc15L
Wytca6tWp9aUtpy2l3audov2Ax2yjoPOGp0GnVu6GF2GbrLuPt0berCehV6iXo3edX1Y31Kfq79Pf9AA
bWBtwDNoMBgxJBk6GWYathiOGdGMfI3yjTqNnhtrGEcZ7zLuM/5oYmGSYtJoct9UxtTbNN+02/R3Mz0z
llmN2S1zsrm7+QbzLvMXy/SXcZbtX3bHgmLhZ7HVosfig6WVJd+y1XLaSsMq1qrWaoRBZQQwShiXrdHW
ztYbrE9Zv7WxtBHYHLf5zdbQNtn2iO3Ucu3lnOWNy8ft1OyYdvV2o/Z0+1j7A/ajDqoOTIcGh8eO6o5s
xybHSSddpySno07PnU2c+c7tzvMuNi7rXM65Iq4erkWuA24ybqFu1W6P3NXcE9xb3Gc9LDzWepzzRHv6
eO7yHPFS8mJ5NXvNelt5r/Pu9SH5BPtU+zz21fPl+3b7wX7efrv9HqzQXMFb0ekP/L38d/s/DNAOWBPw
YyAmMCCwJvBJkGlQXlBfMCU4JvhI8OsQ55DSkPuhOqHC0J4wybDosOaw+XDX8LLw0QjjiHUR1yIVIrmR
XVHYqLCopqi5lW4r96yciLaILoweXqW9KnvVldUKq1NWn46RjGHGnIhFx4bHHol9z/RnNjDn4rziauNm
WS6svaxnbEd2OXuaY8cp40zG28WXxU8l2CXsTphOdEisSJzhunCruS+SPJPqkuaT/ZMPJX9KCU9pS8Wl
xqae5Mnwknm9acpp2WmD6frphemja2zW7Fkzy/fhN2VAGasyugRU0c9Uv1BHuEU4lmmfWZP5Jiss60S2
dDYvuz9HL2d7zmSue+63a1FrWWt78lTzNuWNrXNaV78eWh+3vmeD+oaCDRMbPTYe3kTYlLzpp3yT/LL8
V5vDN3cXKBVsLBjf4rGlpVCikF84stV2a9021DbutoHt5turtn8sYhddLTYprih+X8IqufqN6TeV33za
Eb9joNSydP9OzE7ezuFdDrsOl0mX5ZaN7/bb3VFOLy8qf7UnZs+VimUVdXsJe4V7Ryt9K7uqNKp2Vr2v
Tqy+XeNc01arWLu9dn4fe9/Qfsf9rXVKdcV17w5wD9yp96jvaNBqqDiIOZh58EljWGPft4xvm5sUmoqb
PhziHRo9HHS4t9mqufmI4pHSFrhF2DJ9NProje9cv+tqNWytb6O1FR8Dx4THnn4f+/3wcZ/jPScYJ1p/
0Pyhtp3SXtQBdeR0zHYmdo52RXYNnvQ+2dNt293+o9GPh06pnqo5LXu69AzhTMGZT2dzz86dSz83cz7h
/HhPTM/9CxEXbvUG9g5c9Ll4+ZL7pQt9Tn1nL9tdPnXF5srJq4yrndcsr3X0W/S3/2TxU/uA5UDHdavr
XTesb3QPLh88M+QwdP6m681Lt7xuXbu94vbgcOjwnZHokdE77DtTd1PuvriXeW/h/sYH6AdFD6UeVjxS
fNTws+7PbaOWo6fHXMf6Hwc/vj/OGn/2S8Yv7ycKnpCfVEyqTDZPmU2dmnafvvF05dOJZ+nPFmYKf5X+
tfa5zvMffnP8rX82YnbiBf/Fp99LXsq/PPRq2aueuYC5R69TXy/MF72Rf3P4LeNt37vwd5MLWe+x7ys/
6H7o/ujz8cGn1E+f/gUDmPP8usTo0wAAAAlwSFlzAAALDQAACw0B7QfALAAAABp0RVh0U29mdHdhcmUA
UGFpbnQuTkVUIHYzLjUuMTAw9HKhAABf0UlEQVR4Xu29B7gV1bn/T6xgiYBUpUnvHQ69c+i9gzQpUgVB
QVEBEVCsYEdFRcWOirEmGjXGqImFaBITvdfEe70/780t8Zf8c/PLzc2z/u9nnDX73cMus/aZfTgcZz/P
++zZe9as9bb1ft+1Zs2aKlWST6KBRAOJBhINJBpINJBoINFAooFEA4kGEg0kGkg0kGgg0UCigUQDiQYS
DSQaSDSQaCDRQKKBRAOJBhINJBpINJBoINFAooFEA4kGEg0kGkg0kGgg0UCigUQDiQYSDSQaSDSQaCDR
QKKBRAOJBhINJBpINJBoINFAooFEA4kGEg0kGkg0kGgg0UCigUQDiQYSDSQaSDSQaCBWDRhjqiSU6CDx
gcQHEh9IfKAy+0CswKkrq8xKS2RLgkLiA4kPJD6Q+AA+ULRP4mDl72BizN5CVwq9KvSVEBZ2pX+Taw4K
rRE6KYuDDPPLUNa1flse/uATfuE7mblIZm8SH0h84JjzgQREj0GnzWC0fvLfh2UAtGxA+EkGIF1chHZo
H/6RI/InSdTKP1FLdJ7oPPGBdB+IHLBcCyaKLl5nC9nioiKBmgVWRqT687cit4c8kT6JjxXPxxLdJrpN
fCCaD0QKVoUUKsQAhbRTma6JqjMl81sa0KpVq2amTZtmdu7cae6//35z8OBB89hjj5kDBw6Y/fv3m337
9pm9e/ea2267zezZs8fccMMNZteuXWbHjh1m27ZtZvPmzWbNmjVm4sSJemT6jrRxgtBxQv1te7Vq1fLK
0d6UKVPMpEmTzIQJE8y4cePMmDFj8tKwYcNMr169TNOmTc0JJ5wQHgkj13d8ymriqPpKykULBomeEj0l
PuDuA0XDoEKMUTRmjpGKo+rMF+cRDaAA0uOPP25effVV8/LLL5vnn3/eHDp0qCAgXbZsmTnuuOM0sF0v
bS0X+ty22bx5czN79mwzc+bMgoHUgu2QIUNM7dq1w0D6mLR1fC4wjaqvpJx7YEh0lugs8YFoPlA0ePFX
Lc2WBt4s8vRfoQtbMl13WHh9XegZoa1Ca4UGCVUvmqJUxVGdVi6ZqnW6adMm884775i33nrLvPHGG7EA
aUlJSVa9nnTSSd6oc+7cubEBKYDaoUOHcJtzRM4ThRgFMzJN+0TVV1IuWjBI9JToKfEBdx8oJjYAoHEC
3NGu62OR51YfwIqptyh1ByPCpUuXmsOHD5v33nsvViC98MILTbt27Y7Q+amnnmpKS0vNokWLzIIFC2IH
Uka4ym++kOPThU4WsqPSQD9Jh3fv8InOEp0lPhCvD0QJ2IWWOZZGoK4A/SdRykNCfQtVThmuG2NBpm7d
uuajjz4yH3/8cVGAdP369WbGjBmmd+/e3ihx0KBBHmguX77cAN7FANJRo0aZqlWranvMFXm/mwlIk2AQ
bzBI9JnoM/EBdx8oQyzPe2kQCJtNvNwcC9Rw8BJzVr+5pl7JdFOz9QBzRrOeplqtxua4E9OCehhwGaGO
EfmqlJXyavSbArstiG7YsMF8+umn5pNPPikakLLYiOnijRs3GkB17dq1ZtWqVUUF0tatW2sdHxB56/sj
Up5bDaZ1kw7v3uETnSU6S3wgXh+IGLcLKhYEwuYTrzDHOjUcvNTU6jDCnHxGvWyj1icZmYqcVQqliFp+
z4Loc889Zz7//PNKB6T9+/fXOv5M5G0tVEfoFCFWCntAmgSDeINBos9En4kPuPtAxLhdULEgELaYdIWp
THTOiAtM9eYl2UaoqwnyIm8VV4qo5a8tiDIC/eKLLyodkI4cOVKD6F9FXnY0aipUQ4j7owmIHoObhCQB
2j1AJzqr+DqLGLcLKhYEwpaTN5vKSM3HbTRnthmYaWTKdnbtCfYid5WoFFHLQXtfffWV+fLLLyslkNpE
wf8eJd8dhOr5o1FW6yYj0QRIEx9IfOCo+0DEuF1QsSDYt5qy2VRmajpqjTmldpMwmP6vaG2AP2r6jshf
JR9F1HLQzu9//3tTWYE0BKIz5HeJUGMhVusypXvUO08ySqj4o4TERomNiu0DEeN2QcWCYN96yhbzbaC6
ndKmIZEfIB0k5D3nKDqokosiajnQ63/+53+aygqkIRA9z9djC/lmSpdnRxMQTUYhiQ8kPnDUfSBi3C6o
WBDs20zdar4tdM7wZeb49NW8AOlgIe85R9FDlWwUUcuBXr/++mtTWYE0BKIr5HepEAuMzhTy3i5T7Awz
qT8ZxSQ+kPhAPh+IGLcLKhYE+7bTrjTfJmo6fHkYSH8lGqwm5K0sFV1UyUQRtRzo9Y9//KOprEAaAtE1
8pv7ou2EWKXL4qIjQDSi/pJiiQYSDSQaOCY0EAT7dtOvNN82alZ6BJA+KFYLHtEQfVQJU0SrBnr985//
bCorkIZA9EL5zSYTLC5KQDSioyTFEg0kGji2NRAE+/YztplvIzUomRxebDRTA6nopIqmiOYO6vzLX/5i
KiuQhkB0nfweK9QxAdGIXpIUSzRwdDVQ6L7p7HTHLmXJRwfBDjOvMt9WqtWqjwbS34heuKcXTO2KXqpY
iug1QX1//etfTWUF0hCIrlcgWleOvenc5JNoINFAhdRAHPum8zrEb/0nCPadZm0331ZqP/Vyc/xJadsG
stLUbhrgLTYS3VSBIn4Cvf7tb38zlRVIExCN6A1JsUQDFU8Dce2b/q0fkQbBvvPsHebbTPU6DA1vY9dA
/J5N1b29YEU3VaCIn6Cuv//976ayAmkhIFrWvYsr2/WiQxZjPSv0XyF9Ztu6Mvw/wXB2MfQi9fYS2i/0
jwXwhjzINaoYvCV1lm0fcG1P1z3Ta3cerX3wbqmLxZj2VYjfKaZtIsbfci0WKKPLuTvNt5k6ztgcHo0S
3JiWDBYaiX6iGifQqyy9NpUVSAsBUddtFitzeR9Ao4JlvnLz49SVD6D52ox6flScvCV1uW9XGtaZ7ruu
273W6TJG2/0+qes0IW7fBGBaLBtFDcDlWS5QRre5V5tvO53ZrJt2jtfEEJuE1grxDOT5QksjUtpItLIC
aQhEn5DfvMt1m9BFvs6i6uvbWu5fChjhZQOu/4nom1F1/XaMvP08Zt6iypCUyx6zAj9y3e61bpex2gff
9fs7cXKl0BKh7gCr3UpVjsuygGm23pK1PMExaluBMrrPu8bESa1GLM2ZpZ5er6nJRnXb9DNndRpmqCNO
nvLV1XzwvKiZdeRyTOUyEq2MQBpjkI2sz8rYJvfj2eO5lewa5kpVa9Qvuu6ajrzAmS/kqYy2qowyufpc
3a5pIJrLzh+Kvt6IQWc3C4+yJeuWqLhWruUCBfSYv8vESa1Hnh9bJ6rVvLuhvjj5y1RX11lXxsazdRwW
FVVWII2hc8Su72OVp/pdxxW0Y1idDsOKqsOqNc6qkHwdq3auiHy77lSHrx4FOdqyi1xF/ATKKFlwrYmT
2oxcFrui67Xtb7rP3hYrn2GZTz6tRsB3r16dzZjRg8zkySPMjOljzOxZ48yc2ePzknYwHm8pNpC+8sor
5o477jC33nqr2bNnj3ngwQfNwYMHzWOPPWYOHDhg9u/fb/bt22f27t1rbrvtNq/MDTfcYHbt2mV27Nhh
tm3bZgp5sbeWs2uXdmbQwBJPX1NEX7Nmjs2rpyi6rMxl+vTuGvjaqXWbFrRjWPPRa9P62cQJw830aaM9
/Uf117COzz479T7eOh2GF8QX8lj/6FXS2UyeVGqmTR1lZs6I3o8qs+2Ptmy677ruVFe/WwpE69Q50+v3
o0cNNJMmDjdTp4ww7du3NKeeWi3NL2s07e7sR1yj+Fwux2kLmCoKoKYc/bzrTK8Yqe3o5UHdZ55Z3QOh
JYunmzUXzDcXrV9kzp0zwcybO9HMPXeCmTMHYBrndXxoyJDeprcAWAPVma0yT615lulx7lWx8qrl/m79
ZgHfa9csMM8+c6d5+yePm09+9ZL57T++Zv75ix/lJe2gbLQQJ5B++OGH5uZbbjGjRo82zVu0MFW+852s
VKduXdO1a1ezaNEic/PNN8cOpFrOKy5fae679xrz/ZfuMx++f8j842ev5tVTFF1W5jL/8OkraYGm5ZgL
C9rw5LS6KZ+9eud68/7Pnjaf/PJFzwb/9Ls3nOwQ5qnNpEudeUIO7RtPPXmbee2HD5WJr8rsB0dDNm0f
1012zuo+PrBvly5tzW23bDGHnrnDvP3W4+ZXv3jRi5Of/eYHXly37dRs1t3Zj7hG8blGjk8VsguYvPcV
V4RPwGSfRdebOKn9mBSI1q5d05y/dKbZdOkyc+2uDZ7S77lrh7n3nqvNvrt3esd37d1u7rxjm7nj9ivN
7bcJ3brVK3fFFStNSUmntE5Zv13/WHnVclO3NdyE8UPN44/tMT96/WHzi4+eF+f4YaSgpB2ULf/iANL9
Dzxghg0fbqpWkwwvB3DmOgfozpkzxxuNxjEiTUA0f0KVL0BOnZJ6q1DtNv0L2vCkXqfSwGe7d+/gARaJ
zG8++b753eevO4Ho7psuC+oCnAvZgAU5rG/06NHB3Lvvai/IvvnGI+bnH37PC7Bf/NaNr3x6TM67+aLu
u642PrvHhMC+HTu0MjfesMkcfOJW8+MfPWJ++fELwWDjmqsvSgNR13ZCIHqp8Mx2ojx2CJB6z+9XKBDt
u/gGEye1H7MiUGDdurXM+nXnmeuv2+iNVlD4C8/f441aXnpxn3nxhX3e7+e/d5dHzz17l/neob3eKPDp
p273yq9ceW4akHafeXms/FrZG3UdEbQzZHAv8+D+68yrP9hvDn/wbOTMXjsom8+XBUhfevll07uP7KiU
AzhPOvlk061794Bq16mTs3yt2rXNwvPOKzOQJiDqFrgyBfqnDt4W+NtJp9U0nWbLpieO1H5qCviwyZOP
32J+8uPHvID2+T+4jUaHD+sb8NOg5wRnXuAdOaxvLJg/2QDMjzx8k/nhKw+YDz84ZD799fcTEI0wo1XM
xED3XVd/wy/s9e3btfAGRnawkQ1Ez2zew9mXuEbxyUP6vGaRxw55XzGvWqxYINp/6Y0mTuo4bmWggHr1
ahum+/beeZUHimTKP33noPngvWc8YvrpvZ8+ZX727kHvf+jdt58077z9hDeV+tabj5o3Xjtghso0r1Vq
424jYuXXyk69to0BA3p4I2WAHh7JoKNMj2kH5TVohQDp559/biZPmZIRDAHMa6+91nz00Ufeqt9sH+p4
QEawU6dNM8efcMIRdTVs1Mhs3Lix4HukCYiWHUQJlCSZVpetRq00XebIM9uOdHq95kEdy5fN9hI/ACuq
z8IHPq5t2nHaFc58NB96XlDHKadUNesuXGh2XXOxOfDgDd/wJCPkZCQaj9+UBWS1nV19rWHJRGcQrdW8
p7MvcY3ik8fnSoSaCbEta9UKB6IDz99t4qRO41cFCqhfv7bZduUa88D+a73RJ4DJPUbuv0B0KrJTiCko
6Ne/etkrAzHP/vHPn/Ome61Sq5/VPFZ+rexNuqem1/r27eZNLzM6BtjhK8o0lHZQXsjtCqQ/e+89A8CF
R5/bt2/36ir08+ijj5qzGzRIq/fEk04y8+fPLwhIExCNJxguOm9qKuFsN7Cg57Ub95qUNsXGTA5JqMu9
/Cu3XhDUUaNxh4L4qNUiFfg6yAKT1avneSD68EM3mtdefdBpRqcsIJFcm9s3dd913R9A+1rUkSh+4dqO
9iXh934h3lfcXqi+EJvgsEvSUf8EnWbQ8j0mTuo8YXVQ91n165id29d905FkFPrR4ee8aSYcnZFdmAAq
S9zT4UY19yNff+2hoM6qp9eMlV8re5Meo4I2+vTpam69efM3N839xUVR7jFpB/3qq6+MC5A+9fTT5rTT
T08DunXr15vPPvusUOw84jpW6Z5cVfYKVlPEpSNGOANpAqLxgKie0j3hpGoFPcrVZdbWtFHknTLrw718
ks+oU7otW54T1NFs4BxnPuAB/q1fsFKbkSj3zJhi5p7oN9N90dYWJEAYj39l0qPuu66PDjbpnXrzVVQQ
rd2yxNmfuEbx+ZgcTxLqJsSWrOySxH3Ro/5J3f9bcbMZEiN1nZjKanOBaNSOYoFWGz9Ofm1d5ygQZYXw
nt2Xe1PQrDxjxaMriH755ZcmKpACbhrYvnPcceb555+PDTx1RT/96U9NF1m5q9vj90033RT58ZejCaIA
z6WXyLPDPTqmgYflif85T7moPpbtnmW+dgCKhw/c6M2qFNqWBrAWg881JQvlkTNHqtkkpYvZstqdWR9u
l0SZPtVTuQBhtzlXOrd/Th+5/SD3ZKHTTz/VnLdwqrn8shXeokE7m8MMU64+ZO2KznPpXfuetjm2sNeW
1faF2vJYuE7rz9XPtJ2jgmidViXO/sQ1is+n5ZjXVDKl21iI+6IVC0SHrbzFxEndJq2JNBJ1cThGpNr4
cfJr66rdNBWIxo8bam66cZN56slbvYUagGiUx1w0j1988YWJAqRPPPlk2n3Lps2ambfffrsoAKornXOu
LNhSI9L+AwZEHpFGAdFbZCSfDegyBUIdEFmQov2DGQFWs1atenJG4MxWH/ccCa7cI4zib4AhU5uF8M3C
HG5bRGlHl9FTqWee08n0Pu96Z2o5eG7aLZTw41m57ufH0T58Wxv0lCRmxfI5ZueO9d79UBYVhRfnWcBE
Z2ecIbMvPgDH/Y0d8UMSBVe7hMuXxZ+51qX9Yraldezqa037pm4/hEGURUasEA/bsG6rXs7+zDWOvuC9
jKG8h6YBk8NX32ripO6T4wdRVoBZpdY4u0Ws/FrZqde2QcC2IMriJvsMVL6OoA3P4p58QPrBBx+Yaqec
EoAZq3H/9Kc/FR1AbQNbtspUoALSWbNnRwLSfCBKEHDsBEeU796tvTedrh8FKbROwJepxWz2Y5pxy+bU
bYhC2+G6hQumRAbtTIt6SuZud159zjUnnJyaTmUNAQvy7O2TXCCqR8Kths4rqG2trymTS83FFy02N++5
wpsN0P2H//RiqrLo2fXaQpMcbIRNXdsLl6eOfPGjPNrSfLk+ldGs37RADxpES4f3y6qfeq17OfsU1xSo
77XlCaQBkyMuuN3EST2mpB64jmM6F8ciy7FKrdOsU6z8Wtl1ECKTZjREELAjUdfp3E8//dTkAtL/+I//
MK3btAlArEXLlubw4cPlBqC2oRUrZTW1D6QnnHiiueyyy/ICaT4QLWagPK1WQ9Ow81DTZth8M2DpTUcQ
/3O+6nfPPKIjspnHh+8/kxbMAPxs/FLPOT3HZmyngzwPzfkaZ7c8oh2ej+ZeYJSgSRn9eEm29jLJqv+r
3bRzwAc7Fr380r3eCCzXYyWMEq0tTzj5lIxy5msXfm0drMZfvGial5Cwup1H2FhMCA/sapMvMKJPSy56
sLaw1+ZqBzBjjUVU22gd5eM/33nqytVuebSlecxn2/D5Fv2nHwGiV21LDZoyyV+/TW9nv+KafLrMcZ7V
u+XyCZgctfYOEyeVTF0X+3Ruq1aphQ8dS+fHyi+yD19+Y8DziQIkTAGSNXv3RAtcWPTJJ5+YXEB60UXy
QLIaBXKv8mh9epbIPQifFzZmyLchQy4Qff2HDwa6rCZANmiZLFxzoJYDZmTsQGe17WNKZm92qqvT2BXm
9NoN0+oD4D5472lZ6PagtyVduDPWaNDKtBu+0KmdfguvNvCn6zrppBPlGbqbg8VzuYInz1Dba+HXRV+2
LDzbOlgV/8zT/qI4/1ZEptEofm6vgf9C2tX67devu1m9aq6X9PJ8qF1M+PijqZkk2sMvGnUZ5hG6K6Td
KNc0LRlnajdLJRdWVmwDyEcBUr1xQCE60n6xc8c677YQiyftWg/NQ3m0pX00ig51Gd037UiUHedsndjT
tc44ytNnlVwj5VhvE1g0QA0aHX3hnSZO6jUtXhBduiQVVE+UbLl0xU2x8ovs3candlk6++y63nQUuyZx
b4nHBVgU4fqIy8cff2yyAel78igLGyVY4GKv26P5ef/999MAfd68eTmB1AVEXReBtR40Mw2M6jTrYnqf
u6VMi9+a9U5tQwbvgweVGAKploPA3n7EwjK103n8SplWlel5/x4fbfCMJLMY+Z4z1vd7C5VXt32dbHBi
QSzbNoB6KhfeXW3VY9rFgazHH3+cmSvbeW7csDS1HRwJqIA4/1mdNJZA69pOWcsPWHTNEUkO/Nxw3SV5
k5wwsLnyokF065YLvMflsAdgGvaJ8mhL+7yrLLpvZgLRo2FbZKiZDqITREYeg7HbBBYfRMeu32vipN4z
1sc2EtUAivFb9hkXK69W7nO6DQ147ib34i7ZeL73bKpdWch0VL4gSEapHZSp2WxAOn/BggC0GAVWhA8b
2VtQZ+9dfmcbkUYH0Vpm+Cq55+5AbQbP8vRIwtRx5CKna3O10009ehUefTbpOjy2dkqmb/B4t22cK/uI
ZguaehSi7/0Wyk+Ddqldh9i6kunUbFO6+vEa+HWxkS0Ln1bOZs0aGforz4XbvZRZIUzfuWRjCkQLla0Q
/sLXYJtq301tcAHvd+29KmeSo4EN/bryoW2yUfTAIje7v3E4uSqPtrTvu8pi+yZ1ZALRo2Xbmg3TRqKz
hL/aQqziBUiL9gmcf/xFd5s4qe+MVHZa6D1RVsXqKVyM1rB9n1j51DKfckbq/hkrc9lliekee18p6u4v
2kEZbWYC0g9kI3k2OrCA9ZOf/KQiYKjHQ7368o5Kf1p3+YoVWd/+EhlEz6hlRqyRe+4O1G7obHNmo9Zm
yLLrna6L0kbLvqkdV5Dhu3Uamd6zLom9HerUOmLjDnwo0+jDAqkGtWoF6A35u09KPV7GlK59RMsujNOJ
oJ7KPad7aUE60MnCsKF9vJdMMLqzW8HZZ1UvlaTU6qPQtqLYN0oZ/Aq7W35q1arh7ZJmbZNrdNigfT9n
PXGNbYupbp7hZfembzbDSH9uNg1Ei9SW9sso+tJl6Jv2+kwgerRsS7xQci2T46ZC7LfLM6VF+wSNTtxw
j4mT+s3KDqLcI+K5OjqZJhYiXLh2obwyaaSh84dHCo3a942VRy2v5rdatarehvlXbVtb5r1z33nnHZMJ
SK/YLCtXfaCqKKNQi+K7d+8OeOvQsWPWt79EBdFTBAxcbxVwf9r1Gpfy9Vt28/yLb5frXMs26pDajL1f
v27eStl8QKoXOPWcsqYg/k6smhoFb5V+xZQum7+Hp3TL2laXMUtS93Hl2VD2yuVFEyQM7JoEMNldkzSI
NusxoiC5XPWfqzw+hm9aP2a7REbMgJq9X2mTGw1s2NSVD+0H80VH3CJiw3b8gUeqNGiXR1u677rK0n7Y
nJwgerRsW6uRLNBMPSa1SY67CzURqlE0BNWKnLxxn4mTBsxOraQNg6Hrb29Kb+isWPkLy3pWiy6BAdq0
aR4sjHhMFkPot7hEWYSg5XvrrbdMJiDVGx088cQTFWYUCiM8XmMB/rjjjze33357RiB1AdE4bxXEUdeQ
xTtMm/6Ti3JbQPM3YuVNackgySNvBCJwZrtHqkeHjTr2L4jHZj1Te0AzOtQrZO19fT3qBUwK0Sv8WT/o
1Km1AYh2XHWh96zsK9//Zv9eCxJsgmDLwl8h7cV9Ta+p6e9jffedJ737lblGh4XYROtpmjw6x7Oz6CfT
NHsaiBZg/yht6b7rqtOOw1MvA8k0Ej1atq3VOA1Ed4mMQ4Ta+KPRouFo4NRTLr3PxEkD5qRPZbkCJ+Xp
2M17lJpRK66PlbewnMMWpfbkpV1eKs2iIh57CK9udAXRN954w4SB9Mc//nHaxgr/+7//W6FAFGb0m2NW
r16d8cXeUUH01Oq1zYSL7/7WUpNOA4J+tuz8Wd4+zNwPy7Ydn37EgRHl6NV7nHU3cN7lQZtsZBB+VpOR
j96zt0XJSOc24EuPeO02fzxbnf5qrG+mKzWIFtJesXyotgq+TEUzYv9mRJpa9KOBDXu68qJ9YOzYwebu
u7abF5672/OF8C5O5dGW7ruusnQqTW3qkQlEj5ZttR1FvluExgp1EmKv3aJ9go427bL7TZw0aG52EK1e
t5Gp3bj1EdSiZ6lpN2Ci6TFusRm++KpY+cklG7xYpzrnnIbeM26br1gVPOOW7zm7MLBqB3311VdNGEh3
75Gl/v5ULmBVET+3yIu/LY+lpaXmwIEDRwCpC4hOkpmObyv1nJBa9d21a7tvXgkm98MI1NlGo3rFbJcR
8wrSHcmLtdEW8efwrkF6JfDg+Zud24AvW7/d5o91BGzzB0DwVib9TlMNoi17jXJur1j+o+3DTktsDMF9
XEbQdtSeBmydBzrz3kSusboaUdo/WPWf6dG58mhL911XvWq7ZwLRo2XbOk3a6lmfu0XGKUJM6bLXbtE+
QaMzLt9vvo3UpTQ1v49jjRwxwHvzRPgZt2yPB2QamWoHfVneBxoG0hWyWMcC1GWXX14RMdSw0Mny2KpV
K8PjN2EgdQHRqTLT8W2l8RfeGvQznj9mdiPf+z71y7EJDoXorlWv0UG7Q4f2TgO2J+UdvdZ+Neo1Kah+
HbQAn5Ur5pird17kTVXyxpbwPVgNovCWS6YOg6cZysBbtlmsk6qe6pWBhi7cUpAM8KDtw+NITH17swXe
op9vRqMa2Jp2HuTcFtdYOYYN65N6/pw9uaUdvYlLebSlderqW11Hzc95TzSfbV3bi1o+BKL3iowzhHoK
NSwagmpFztr8oPm20ajzd5iT1AKMDvKWdnYyYWHE7bdd6d389zLFHA+q5wNRNpAPA+mo0RLc/JEo7/us
iB9euWZ55K0yBw8ePAJIo4LoaTVqlylBG7PyetOmzxhDPeGAyv+li64sU/02eSxmOzXqp8CAxz/0+z4z
PXvMKChttHDR7c4yohdbx4knnuBNsTLK4k0qegs7dOiaQKMrzR+7I9lt/lgNTJIQXg2sQTRTm/xX95x2
WUEzG5ja//GPQXM2OMuC7No+JALsZkQSYEejGtiadR3k3AbXFAKixWpL69LV9t1HpzbnsCPRfDsWlVWO
fLbPcJ6FReU7Ep2z5SHzbaLpl9xl9HTXaaedambOGOONQukwwUuE/RcbR9lkwQKqNuihQ4e8N7FoIOWl
2hagGKVW1I/eSQk5wkAaHUTrFJSgjViyzTRqm/Zi3qwBtu/U1QW1QeJYHu1oOZYsnu6tXM33vk+9DWCn
oTMKkq9m/dQuX0y1WvDWU7nI75pAt+2b2uavYcP6BpnsNn/2JfbhrQY1iHI9bfYYe15kG0cNpIXI07zr
4MC35p47Ie1+JaNRDaKUddWXrt9lJFqstsoygMJm9vqoe+eWVY6otvfL/UC+VwmV7z3RuVceMN8Wmnnp
3aZmvcaBI3xHRoUDB/T0AgGBhg0W7Cj0m2za7f2H2uAATxhI27SVuXt/JPruu+9WVAw1Z1SvHvD5+OOP
e3JoIHUB0XO3HjAu1H9a6lnHKB3opGqnmukb73JqA37Kq50W3Yak1h/I6kz7DCUrdbP5l94GsOZZ5zjL
hnzt+qW2Y+slr/Zj45Abr7804KXQek+rUSc1VTykj7lA3QJhFMejG+FbIHo1cD6b8txmx46tTevWTQ3H
+crr843blTjrSutp7JjBwftPrX2ukdGpbQNbuvgyZbX9XUC0WG1pfbnKUjJuUUYQ5SmGb97i0v4Ie5VV
joj2/1LKPS20XmieUPmuzp237WHzbaCZm+5JA1CMU1LSycyfN8mbjmJlIY+18Fwdr27imb4o27XpaV1t
cO4lhoG0efPmATh9KJsuVNRP7ToSKH2wB0QZUWsgjQqip0vAdfWtXuMXp3XEs8+qawb072GYNmThFw+s
z5w5xpx5pgC9/2wY15S1nQYN6nnbATIaIanK1M7AGWuc22nfPwVmvO2CR0DsqDDX/XY9YhyzbIdzu5Mu
lGd+ff0wpcuG+CNHplYLdx0+y7nO4fM3BXXCH32H3b1uv3Vr6haIup+o+0amfYotf40bn23YbjNiwMxa
rhB/0/YZUdoveD6cR3SwjwbRlt2HOOuMa6xcLiBarLa0jsvSZzK9TxR9ETcZkNh2yiqH1PNToTuErhXa
InSJ0EU+YAKa0Fqh84XmCI0SKt/nRBdsf9RUdhq/atcR99W6dGlr2JKNpe3cC9l//7WG6ShWFmbaTcT1
ERcW44SBtH17ydR8cHrzzTcrKoam7evLdDSkgTQyiNasYxbueNSJ+kxMPcTfsEF971VovOQZO22Wzrnr
mou9xRn6rSAdBox3agOedDuNZFqSjT5oZ+2aBbG2A29WX0PlLTL27SZ25Xe27ST1YyiFyIeMZ57dNGhb
P4MKP1PX3+ysMy1LmzbNgo1J7r9vl/nBy/d7K49zvQjce0+m/87Jzp3beC8ACO9hnAtIaT9MhcihfTJs
n3vu2pG2XaIG0VY9hjrrjGsKAdFitaX1W5a+mQlEeXQL0u+oLascwu+PhK7ygXKBfE8TGi/ElK2l0XI8
XKi/UBeh8t2x6Lydj5nKTP2nrpBFRKemZa8AKCMbRhvb5QFxAhv3qt6WFXNM45BRhXcucQXR/fv3e6ta
NZDqZzCfeuqpCgmif/3rXwOgZ3tCHtPh/q0G0uggWtcsvvpxJ+o3KbXP6jlNGnjAtkFmCrg3tffOq7wd
r1jAwoP9lo+zm3dwagOeoraTtmVdh97O7XQaOCHgc+DAnt6OPs89e5e3CpTHQLLdc9dToCfLlLWrHinf
Y2RqBTpTumXRF/XBhwYEdhnjPa1PyE5kb77xiNd3sj0Da/sPb9BZtTL10H4YNGkDnUETV11TkNwuugrb
h4WF1j48x3n1ztRe4K17DnPmh2sKAdFitaX17aKncJ/JBKLcnuA+MjHVtlNWOaQe7nMy2uSl26VCvYQ6
C3VU1F6O2VyhuRArcst371xXRR4r5edtud80btsjDTy5B9qzZ0czZ/Z4D0BZLcmzbQRlggCr8vJtzZYL
TLWD7tu3z3u+UgPppMmTA4C69tprKySIfvTRRwGPzWT6mQ0jwkAaFUS/W7OuWbrrSSfqPzm1u03z5o29
kSGjz3v3Xe09IsIjFCQ7t8pbdgJQaNHRqQ14Kq92Og9K7dc7YEAPc6uMxnjZeJRX7OlnRofNWe8s48yN
t2Wc+uw56lznumjf6ptnQ1nle9mm5V5iY1/UEN48INxX7r3nasOr6MLAWUtGzOjJ1VfiKJ9mH7ltkLbR
ikxN79yRkrtNyXBnHrmmEBAtVlta9676030mG4gysxKnzoTfF4WYqmW02U2omRCbKNRVxD65AGdNoTOE
yvctLq6KPBbKD5q+yrDgRDsMq3C5tzZP7uMwNUi2BICS8b/x2gFvm7Jvtv068hVFUUah4be47N2719sy
TwOpfk500eLFFRJEH3300bTNFti6MAykkUH0zLpm+XVPOdHAKcsCu7Vq1dRcftkKb/RGouNt3u2/BYOt
0ywf3y1iO3qRTwMBa1d5ugyeFPDZX963GbynNsNzgmE/09NizTr2cW4bXuE5DFrnbXvAuS7at/V07tTG
8OL6ndvXmYceuD64xxveC1bLwwreMB/UOXXNdc68uNogV/mwffbsvjzYuJ9H3DQgtO1V6swr1xQCosVq
S9vAVY+6b2YGUf/ZWrUYq6xyCL/PCS0QGiTU0gdLC5K8pUXTSfL7RKHyfZ/osmsPmspC45dtM7VkNWO4
s7ZqeY53z4v7TBetX+TdA+XeB4HZAihZtOtq3Fw7FvEasTCQ3nST7Kfq3xNt1LhxhQRR3t5iebzkkku8
TfTDQOoCoitvfMa40KBp0r6/IIb7biQ7LMbhnpt9tRaJDpt4axB1aYOyUdt5+KHUC9sbtuzkJAvtdB0i
sw++PLy0ms0USNx4npIgrR+2D/sT903ttSdXO80s3vGQc/u9x6Z2F6Ku5p36OtdBu9rm3Mtcv+68b2SR
Ny7ZZ1CzJaBM+errSXrGL7vSmQ9XG0cpH7YPCwyRydpHg2i73qXOPHNNISBarLa0HaLoR5fRfSYbiOLD
+rGgssoh/D4rxIKhPkJNhHjF2fFCR/0TGHb59TJSqAS0aPtDRwAoo0/uBTF9ywbZbKbAq5oYXfAoix3Z
WAAt5D5ottW5e2SLv0xAWqu2bBzgAykAVdE+emUu9215nVsYSKOC6Bln1jMX7H7WiYZMT63sa9e2uTeV
+8jDN3kPwbMlm010CNyWj2K2wz1Y2w4g6ipPt6FTUiDat5u3CtwCj92UINdMh57SRTeu7Z+/8+E0ACuk
jr7jUjvV1KtX20tGWeRFIvrC8/eY9376VNo2f1oepnC1v6BDeHKVo1jl89lHg2j7PiOc+eaaQkC0WG1p
W7jqVPfNqCBaVjmOCRBdeYOMFCoJzVi/O23xQxNZOs8yfKZvmRrjfhRBke29yDS5B2rf3FBWAA1P595w
ww0mE5COHDkyANE1a9dWKAx98cUXA97OadrUfPLJJ96LxcNA6gKiF978nHGhYTNXBUEnV0cNg6hLG5SN
2o4G0UatOjvJQjs9hk0tE4jqbQALaR8eWnZJvdNy+TWPOstQt6E8mhWMprt56wkYbaCbbK9as0CqX7lG
Pa52Knb5fPbRINqhz0hn/rmmEBAtVlu677rqNmqf0SPRsspxTIDo6psOmcpEw2avSct8Bw/u5a3k5P4n
25/xjB4rI1lJqN/YkO1Rg6j3Q8MgumvXLpMJSK+8UrZk80eifLPNXkX56B2V1q9fbz799NOMQBoZRGvV
M+tvfd6Jhs9K3TuLDKJFbEeDaGMBUVd5eg4vG4iGtwFcvHWfMw9Wp4CpK//nbpCXJvgAevzxx3nP0W64
eImXkHpvOuLebpbtMXUCcIbYaOW1jzm3n4nf/hMWGvRqqeopp3k80oarfPnso0G0Y9+RzvVzTSEgWqy2
dN911VXUvqlBtKxyHBMgumbPs6ayUZdBqWfzcJqVsqSeKTSyZu4z0el5jKUsi4jy7Z27Y8cOkw1IW8rG
7hZIt2/fXiEwVI9Cq1arZj6QzSA+//zzjEAaFUSrS1DbcPuLTjRidmrHoqggWsx20kC0dRcnWZC9pHRa
mUai+BnPylqdU5+rTi+4/gnv+gmLNzlfq/lv1qyRWbJkhjerwy2Rl1+6N+N7MTONQrGrK9+2PDw0Ft1r
v8t0XIgf5LOPBtFO/UY5y8A1hYBosdrSenO1R9S+qUG0rHIcEyDqOqQ/Vso3aNEhcN7jjjvO3C0jUbuR
AgDquhtRlBGpdtBt27aZbEB64YXyHJUajVaELQDbtpMNwH2elixZYr788kvzxRdfZATS6CBa31xy58tO
NHJOaiYhOogWrx0Nok3adHGSBdl7jZheZhDVz4xWr+UuK3x07j/arL3xoDP/tGftPVS2+ePWCOsK7Evr
uU+d6dnQOHieuOSyvMCpfbEQ3eSzjwZRdOjqz7p+Vmenrf7N8RaXQtrimnyArfXlKkvUvqlBtKxyHBMg
uk6m2+Kk6WuuieT4I+eui7XdsAwrr0t/OLxliybBuxzjHoFm2oB+8+bNJheQduzUKQAtplGP5gc+LYDW
qFnT/Eamcb/66qusQBoZRGvXN5vu/oETjZq71vmeaPUitqNB9Jw2XZ1kQfbeI2eUGUTxL31vcda6Xc58
rNvztPM1tGNtbbf5Y3EejxyxOcm7bz+Z9townWjqTefRgasfTDr/iqxxhD11ecymW7f2hlexWR4L8YN8
9tEg2mXAGGc5dP1HgGhodbYGn0La4hoXEHW1SdS+GaccxwSIXnTbCyZOmrE21fFyTb+wM8n8TbfG2nZY
DurXPLBKl6ncfLuqRBl15pvO3bRpk8kFpFfJNO5JJ58cgNeGjRuPCo4+/bQ8RqFGxbt37/bu0/7+97/P
CqRRQbSGgNsV+15xojHzUrudRB2JFrOdNBBt29VJFmTvM2pmLCCqt+3rOnCMMx+udqA87Vhbt23T3Cw7
f5a3voBHjnhOl2d2sz0bymbu9topy69w5rd+45bB9aeeWs108bcJZKEgK+3RB4C+dk1q5XAhfpDPPhpE
C9G79ueO8srF8HOo2d4nWkhb2l7Z9ulN67tF6psaRMsqxzEBohvukHtWMdKsdddGGolizDoNmpo1Nz4Z
a/thWUbPT+04Qps8d1jWTRWygax20I0CivmA9NxzZfszBWDXXXdduQLpSy+9lNb++AkTzB//+Efz9ddf
5wRSFxDdct8PjQuNnb/OeSRK8HRpg7JR29Eg2rRtN+d2+o6eFQuI/vCVB1KjwlNPd+bDVT8bbz1kqko7
1tZjRg/ygItHdNjMnud0eT9ptmerGzU6K7j2gmsPOPOrfYy2eV3h+Utnmo0blnpADhixWPB6mVq2ZQvx
g3z20SDabdBYZzmWbrkz4I+XJoSfQ2VWzMYTDT6FtMU1LiNRV5+I2mfilOOYAFHXefF85Wevuy7NaWZM
H+O9FYN7Kazqmzd3omH7PWvsDvIwcr46y3qeNnSnvP/eXWkrcwsdeebabIHVrVGAtFevXmlAtmXr1nIB
Uvb01QDOFn//+m//Zv785z/nBdLoIHqWuXL/6040bmEq6Yk+Ei1eO2kg2q6bkyzI3m/M7FhAFF/Tz4xO
X7nVmRcXW2g7sM0fexizexTAZbf5IxnNtlnEGWekAPiS27/nzKv2MWIIo0+eTWXFLy+LYKX9C8/d7S1w
SoGoux/ks89tanvJdj0HOcuBzqupZGTWzLHe87V2gwqeUcfHePZWv7mn+6Bxzm1xjQuIuvgDZaP2TQ2i
hcihbSLysHfuuUIVd7OFS+/6vomT5lx0fWBI9skke2TahffN4ZA40FJZ4ac7ydiFF8fKQ1ge7gfVbdgs
aJMOTmYf9wIjLdNaeQY0CpDuuflm00693QVgGztunPnv//7vooEpI14NoGc3aGB+J4uI2Hz+L3/5S14g
jQqiNeucZbY/8IYTTViYen9jVBAtZjsaRJsJiLrKM2BsfCCqtwFsLwHdlReX8shq7cx9x5Ur5ng7ffHS
evoOrwvM9So37SMu7dqy+vr+sl0nCThbJrLxBm9b4r4so1NdrhA/yGcftjW0bRRif+TRbWh+cx1zjave
egx2A1HX+qP2zbL2mZmr5DFA/7Eq+f690DYFomz9N0Noi9Cbfjm+2aC+XD8Bk5fJ4oc4ae7FNwR1sxiC
7cGuv26jlzF62aPscPL9l+5LW7bPc16LN++NlY+wTKuuecjY58lQPM+PsmMM90fj2Ggh/JzoqlWrTFQg
5T5k124StNTUbouWLb23p8T5YbXtzFkyvajaYVXuZ599Zv7+97+bv/3tb5GA1AVEdz70pnGhiedd7Dyd
S/B0aYOyUdvRAaF5++7O7Qwcl3qTSr8CdizSsx16G0BscMXeF5z5iaKni26UWYpUEDOMnnjnLiDGqltG
UXa3pWzPV+vro7QZLoOuowKOLTdixjJnfeSzzxuyX7OtvxA/s3KdfY481qZ0mu2YcrNWb3OWg3Z6Dkk9
2hflnqirXcqrz+DXevQeRW9+mbXliaKBQa+4RxZ+xEjzLk5tk8YWYbyglTc9sE8tz2my0QHvHYR47swq
qJ6MFDfccihWXsJyad5olymiQt8dmm9h0fLly40LkLJF4KRJslm5AjiO2dXo17/+dZmwlFEtGz+cdrpM
san6S0eMMH/4wx88AOUTFUhdQPSah39sXGjy4g0FgahLG5SN2k4YRF3byRek9T2xKLcVhg/rG+hn1Kzl
TrqNyjv1Whs3lHetcjuGDeTD70LNte+vvie6YffjznxyTVTgAXBX79jn3Ab6iGIf7e9RdZipHHrtUJJa
cGXrhX/4KFQG25YriLrKErXPMM1uZcOGru1Qfs6aqyIlHRkAtmp5AWnA4OZ7XzVx0vyNKRCtX7+297ox
VvMx+mSPTUCLaSBW9T0i9wKOl2c4rSI69R0RKy+Z5Bo4IbWaj3a3b78wtvuj2qBLly41hQDpMgHfk6tW
PQJMp06bZg4dOuSNFKN+ePE3G8pXO+WUI+pjNTBTt9THCNQFSF1A9NpHf2JcaMqSjQWBqEsblI3ajgbR
Fh16OMlCO4PGp96dWdaRKCCb9laZpq2d+YmipwZSr7Vx/349zOrV87zbMXYP448OP5dzKhc+9ercc9du
L5jP0bNXGPQeDpaMCtHtBTvvLbjuqPbpIKtqbftlbS+K/gstUzI09e7aKCNR13ai9hl2g7P6YkTp2o4t
j651/7F1duw1xPt/yWV7vLpD/jFCyrFB/Xd8KhqmBkJuve81EyctuGR3UPdZ9et4r0viTRiMQul8TJ/a
jJupoJtuuDStg0xcfEms/GSSrXXX1F6ibMSw/75rvfeIlnUDBt3RFy1aZAoFUu5Z9uzZ8wjgs6PIniUl
Zun553ujS94UownQHDJ0qKl55pkZr+/QoYNhVS6rcFlEVAiQRgXRM+ueba5/7G0nmloAiBaznTCIusoz
eMLcwL/jAFH6jl6Asvbq+5z0m49/6rP2ZZs/Xh3IiljWM+j3oOZ71lo/J4oO8rV7tM5HsQ+LfqxOKrIs
vYal3l0bBURddR61b+Kjeibi0pufLKr9QyA6TmxVTYjXohX1bS+BU7iu0MpXfuGlqb02o4Ao9yMXL0pt
jcZ9y+VX7XNemZaPL33+0jufN/UapTbVbtq0obdcnxFyWe6PanBZsGCBKQuQAow8Z9ojB5iGp35z/e7Y
saO59957vec/eQ6Ux1gKBVIXEL3xiXeNC007P5VURV1YBIi6tEHZqO1oEG3ZsadzO0Mmpl5FFheI6qBO
/a6y5yqv+W0ut1tYGMhs0v337fJmk3gdHQkn/STX9LPesYjRSJw8xllXFPtoWQrxtTj5zVVXb0cQdeUr
ap/BLyZOGBZgDNe5tuVSnn6pYtJ0OT5T6DQh3jVatE/Q6FWyeixOWrQpOoiibEajjABbtmwS8FRfAO6y
O1+Ila+wjCu370tbaDR+/NBgI4ZCgVSDy9y5c00cQMqLvW+WFbyzZs827WUV73HHH591hBoGUR5bOV9G
rOyLy6IitvJjJ6KyAqkLiN508KfGhaYvKwxEXdqgbNR2wiDq2s7QSfGDaDiou/KUq/wpp6UeTRk2tI9s
ZrDA2+bv8cf2eK8OZKou6mYlaY/kiF3j5DOuuqLaR+8YtXzLrRVSlt7DUy+AjzISddVhlD5DgnXnHfJe
Z9lVysYJQM61LZfyIRBdLO02FqoldGrREFQHwe0P/sjESYsuuzlQ3imnVPO25RoypLcZN3aItyKXlX7s
HBQmFkzo50e79h8VK1+ZZJyyNP1lwZ06tTYzpo82s2eNy8hjJr71f1qvswX04gTS/fv3mwMHDpgHH3zQ
XCNviFmxcqW3EGn0mDFm7NixZtz48WaCbJawYcMGc8cdd5jXXnvNe40ZrzPjbSxsJh8XkGo5u3ZpZwYN
LDE8ED9l8gjPzvY8Wfuep37mRDOWpWxSs8YZpqSkkyGYjx83VF6sPiqwzYTxqUy3mO0MFd+18rSSYOAq
z7BJ6l2cdWub3r27mNLh/Qz8T5+Wkiefb4XPV6sm98391Z4rtt7mzFcmORZelHr354knnmB4mX2Xzm0N
29WNHDHATJo4XHiO3j/69O6aigWnfddsvuOZWPh0tUGu8lHtw25DVt8Nm7UpuhxXP/Cqcxt9SlMg2uDs
uqZvn66mtLSfNyq0dtN911WPufrm5MmlkuS3NOwupduI20cz8Uy/VG1eJMedfSCtUS4g6rrMOV/5JZfd
UuiqqiOum3r+poKWeufjUZ/vOzK1QXgm4xf638yZM02xgJSNEg4ePOgtNHr++efNyy+/7D0O88Ybb5i3
3nrLvPPOO96LtHkPaDGANKpOagmI3vL0e040c3l6YhOlrfJqp1Wnnk6yIPvwyekL2aLI41qmb+lkZ74y
2aVLn1Ri4spDlPKAj6s/RC2/4foHTXnaB7tG5c21HHUXYlOuiWIHW8aVrwL65t904uHaXtTy2F3JvV2O
Bwq1FqpTLiB6tSwnjpOWXpG+X62LUcNluT96wdX3x8pfJlmbts3/miVXOabJatrKCqRRdVGr3tnm1kPv
O9GsFW5v7oCX8mqnVacSJ1mQffiUBU6BLapudblTZJR37YHXnHnTtuH6Qtp2vQYdlpXXsE9NmPfNO2gL
8YOy2AdfdfXvXOU33PiQaSSJBrL0HTHZuW6ucbGHK+8OffM/hA82QLhHKADSQmSKwiM+peTeLcejhToK
1S8XEN31yFsmTjp/cxqI/rcI8ZHQ20I/FHpJ6DmhZ3PQ9+TcH61Szmrcwly57+VYeQzLS/3V/Bf7+u3+
X/l+0ecVfnLxq88FxpwyZYqprEAa6qi/lN/vCr0u9LJv5yCo3f7sB8aFZq+8XHeIr6W+w0JvCb3q28Ta
4xXLB8HTpQ3KOrSD73o8tZbO6tpOaTqI/rvU84HQj4XgHx9z8a+wHwb9BHlcedPlQ/r4i/D1j0LY9qdC
bwh9X+j5Avn9UPtMo+ZtzCU3HigTv/C+7a7veTYpix8UYJ9/1rJwfVn0zrXXPyzbQ4YAkN+u9Ybq+Ffh
833lay/4tgv05Vp/nj5D/XcLMRK8XOhSoXVC+7W+sBd2c207V3ntA9LWnUKThboJNRAq2idQZKHP8GS7
btnm23QQJCO5T+hqoYuFzheaLzQnB7FPIob4u1V+d3mbRNx8huu7cFdqg2+/XYL2IqF5QvCUi2d7LpCd
+5WVFUh1p5DjA0LX+51mhW9nH0QbmDu+96ETzUkH0d9JfbZjrpfjJb490PeFlo9a9YraDr77DYh2LnGS
BdlLpy7U/eEXUs8dQmxjBv9anij+FS5DXQXzpm2DbMquv5bjQ0L7hGzfXSbHCxz6guaV/oOfpI2U0M0N
j7zhrNNLb3rY9Bs55YhRVyF+UIB9kOVTLQvtLtl4rbMcGfwjkAn5XPtOSCcka7cLbRVaK0Qsm6v5dq3f
oW/OlHamCU0QKhV6MpPtr7r7e84yZuI55Lv4LCt0ewo1FCraJzCW67NC+cov33K7du5/EwmuE1ojNEto
lBDz1WwmnIv6ynmANKhr5oorivqsEXLRRsjYN8jvIUL9heApH9/B9SzyqaxAGtLRLfKbBIlkY6xvX0Zc
TlNLWcq/Lv9fJbRciE5Jh8QW1g7l0c6gmGRBHwDTViGSySlCw0Py5POv8Pk4edP2ekr4AqA3Cy0N8Rql
H2SSo5/UAyD/T1if3foNNyMEUDftftjc+dzhI+jGR3/knYeYuo7RHuG6otoHWRiZH8GL5TOTHPy3Zvte
Tw5kLqIc1P2Ybz9WqzIyGyYE3z+Pqd3XpZ5MfbO3/F8i1F2os1BboWZCV2ZqlwTE6mz7Pc9ltL/W5ZJL
rgvKt0lP/Kw+L5N2pvrtl89I9IbH3zFx0oqtd2jn+D8iDEN7srehQl2EWgg1yUPnyPmmQmQVXn08a7b+
ugdj5TWT3D0GpW9qLW0vFGrjOwJ85eI9kH2cbCJfWYE01Bl2yO/zhEb6jssG0SRNZQ0STEftFFotNEmI
ANDBt4O1QXm1w8ixrPIwerFBZ7wcE2zaheTJ1y8ynY+DNy0b07d7hDYJLRBiB5gefh+gTxbCI9fQdwim
3K9iWris+rTX/5PUFUy5l6FeF/tYWUge2SA9Dlnwd6b5mQUoa30fSx34Bckamw/0ErJgVuw+01jaaiQE
gHFPsrZQdaHThQDyJ2KQL5t+mD1EPvpXZ799+SrOJ2DixiflYfgYaeW2NBD9Uthn2gqhmKNGwTwIi0Lz
0Xd95X9ilX52k5Zmpyz9jpPfcF3UTzvK0H+QY4IIzx3hDPCVjffgujHy6EllBdJQJyDYMkoEFAiS6An9
AKw/CZWNEhxIvLhXuFUIAKVuAJTVdnRKlq1r/R8L7bAO4AohprtJCNAVyWRd36fy9YV855mqe6cAXYcT
XvTODBBT5zbxJXFhWox+m8v38/HIea6v6ctNcsq91ig+ES7ztVxHXGCa8Daha4UIztzHda0PfyvEPmf4
OgEw0NnhAtqGV0AYPXAv70YhwO8hoc8KqE/LwuzNBCFGhfgaK1Xhubz6Js9oniLEhgcnKmITBGasnhaK
aybpK6mLxIz7sPgVYE3SUD6rc10eao1SdtW21EtoRQiyxJVCZLNk3QjFlkxsxxSFTpByg4X+1zpUz8Fj
i/rgLjJuvvNQ+C0C3DSn88M7DgFfmfhPA9HKCqTWFv432bjN/M7yO47VDXpCZwRgsncSKab0uV/GPTYS
LK7XRABfJURnAHAGCDETAIASAOx2Xlr/5dkOgYFEgYSB+y5jhLjXRNBiIUVYHv6jDywQIqgx1dlKCAAl
oOBPUfpCrjLIT7AiSDICAPgGCTGtBcCSjKDXMG9hvVOO8lzH9e2Fzvbrpf5sfh+Vf65HXjYJh1dsSoJE
8COofi6UCQT/n/wPQDJSe0RolxCjehIT9MuUM7eLGOUOFCJJYdqZ2S+mMucLYZ9M/laofZAFX8QfiA2A
Kbc0AMNfZZED2f5FiJEzwM2UOVPcTHVeIoTf40v0p0FCACAJPPIw9Y9d6BeUy+VryGtnO5gZIu4CamH7
YdPqQgxuOgsRp9EjI9i1QoX2zePkWug7iuTQ+w+d0Y/xf8Cd6eZ7hEgkooAq+sMP3hR6XIj1GFuFLhLC
d23iwKwJdinaJ3BU1wdu85VffdVe3QkAUZwXB2AkQTA9SeqoEpV8I+AUQb1zVm9xfhA5H9/h8yE5aJuO
i/EJAjhHps8RIFoZgVTbQo4JzmSWLCmnY9Ax7Qc90XEt8ACknYQIcGSLACrXagKU6MyDhAggdgRK0KXu
TLov73YAPwITHbWLEPdp8XGCeCZ5uJdLMtBdiMBRT8gmBNl8Sakx0iEBygIpyQx6Q3/oEX2i1zBv+fRO
PVbv1B/HB3mpi35EYCcmEMRJsgELdDVFCDBZIkQCskZorU8APQkYYMICFoImYAngAPrNhZoI4WvogMQN
++BvcdsHWUgg0DujbOxK+/gE9ka/M4QW+DzDu5UDmZANGZEVmbklQlJBH8FP7LQo8pBIYk/qRUeZ7Ml/
dt0ActvZjmxxC95JcgEbbEAfJslDn3H1Takq+FjbA6T0IZJRa3umnLER9gTIsS9gbnVGAkSsIXng2OqP
MuDDNCH8HD8gcbBJqm4/1uMg2N8sD4THSRdsvysviEp7VaKSSG0Vf5Mce3Vzf3SrLJOOk+9MdY2auTSc
FTMdByAADJmCX0YQrWxAau3gf+cCUZzWZp90GgImIyVGcQQFgh4dVxOjKAIqHaGJEIGpuhCdPZvey6sd
HTQJTLWFmOokcOaSh6klAhoBA/Al4DIayyUPMrl8bCJhR3kEEdqjXdpHr2Fdh/VeHnwikx2h2BkE7Au/
AB+2J9kg0RoiBCgQ0AFACKAhyAMmBMzOQoAlslIHgEB9NYTQdbHtY30CYLBJAaN39I5+4dGCOLxbOZAJ
2ZARWZEZ2UnMGKEjh50+R5Yo9sTGmWwIyAOY4ZjFb5vM0J7tm+gzzr4p1QUfnUQRS7GVlY12SUAAVOyL
nQHGcPJDsmD1Rxn0y6wQ8qM/6kN3OqHXPMRyHAT7W56RHWVipDU78oOotFfFhXzj4wS/EPJ4b3BOy1j5
zqaDjiWDNJAyrYwB7ZR02CmzgmhlAlJrA/87H4jqIEOnsffFyEIJcji8Jv4DnADc6kKAL52BgGuniDJ1
gvJsx06fIg8jNQIQPEeRh0Br5bFgEkun9vuJ5Y124A09ZuMtm965LsxnXDzqesI2w97okGAOoJJIkZwA
LgR1CJAg2JKIAZwADjLiV/YeHICGjgvxt0LsY4HB6h6fxSdIABlNwis8azk4RjbAFlmRGdnRQfheIrJE
safuO1FsCN9MpesYB4jF3TelyrSP9Xtiup0Sh1/axZ7YFZ21EsLe2F0ngTbRRn+UATjRs/UFElzbx8Jt
x/Y7UFqUHSFcykQBUamviiuJ5Ch+oDb44PGznXf1cJGFstfJc2wN0t9K/xvf0TFSOKjnBNHKAqShTpcL
RHXnZNqFTkOguVvVwf0QdElmacsz4qdzkSW/4v/PPTF8gA5jy21UPcJ2zPDsQfg3wSxTGYKJvo8T7mx7
s1y3Sf4HjJBBEzLYdv7LL4M8yG9lysYr9/gyfdBBpmvgjdGK1QFyIA/tah4uC/H4qjpv7YDeuQVjr7N6
z8QP+tflbBltI87zO9tHB1R7vxQQssmJDegABMRvm2ARLC3g6CTLgpr1NwuqYRvp39bfwvXkYP2IUxpM
qY9kGx6r+zzbZEbLgt0s4AEKVp/0F21P+EI/VhYA+jpVnuueFMLG+KP1tVw+zejXtve6HF8lxJSq7oeZ
dBaHrlCetr1OTLXOwva3ukOXnLMzD2FfyDTydrFl3rJBR7zt0AcmTlq7I/VWc+Ei4z1Raa9KIeQrfb52
nPM33Rgr/5l0sWn3o+GFRo8ID2S+OJMG0rwgWhmANNRxs4EoetEB/zX5TcCjg+vgfp/8JmgywrflL/DL
ol8b6H8rx3QUMnhbbrNfzk6L0iZBhP/3q3KH5Hib0JVCZP1bhD5U5zk3MVSX/Aw+dHYN/JTX9X8uv+nc
dmaC7zBQIpPNjgHYK3x+rCyHFY+DMvCCbLRDeXQBD28oGW6UY/RF2yy4sPWiX83rQfmNvggyGkT/IL+Z
htQ6t23ZzB4e7CfTKGa8LyOJhbZ9J/nNNDNt5vqEg6oGDR3MLUBQXy6QyNNc0U5r8LNADs9hQNJgRDlG
peE+kGnKH+DVCdVW+Y1vY0OuZ/SW71YBPOpkabb85j4qU8yWhzVynOv2VZwKjKqzbIlPuftC4OC3P/uh
bMEUH1248x7deTKCqLRXpRASi9lM715raO6Pbr/nhVhlyKSPeWu3abk4JlAQ/LWzRgLRYx1IQwEyG4ji
7GGdjfM7u/6foM49xRmqPEGB6RmyzNf9//9Zvpm6YeGDvR7gaCxEkLdTQwQYpoJYfGLLXetf10W+7f3W
J9R57sEwZQSIMG0WDvbYGDCy9cEDpMHiFvlNwOFasuSw7C/Lf0w32SwbvpmWsuUAeupkdGAXU1GfBS4C
7u/88u/6ZbUuHpP/AHKdjDBCReYSoVtVW+f5fLwe4pORjR6JwNuXPj+M/uDBfpCTZEXL+ZL8Jkmywdye
414gI6ewTvitZxP0aF8nAhzbzw8y1GNH4rYMI3mbqOmEjXL2c02oHtqwI2aut7xqnmibBSzv+eepG+Cx
H3Rnz3E95+2sgh6dU8aCIGW4jtiWST8kJmF/1EB3vc8Di47wHfoE92KrC+HXYX0hN5/hGdr7RQ4eLG/w
zkfPQtDnIFuGc2E/4hwyoz8+Wh/waO1kbZDLPn4VR/crMJbr1k/5yq+7Oj+ISh1VCiVRG87GKDDIxBo0
bRXL9lH5ZBsyYU7YyecIHzpT+9o60ogRIwxgmYuOxedIf/vb32od/E3kzQai2Cisr+flP8BQ/89oiiC7
Uv1/lxz3FQJcf+L//2/yDQhPUeUOyPEAIe4nAdpMn3HcW2irKkeABFSnChGAuAZQs3wwMpwgRPABLABN
/WEURVu2/Co5ZroNMPqt//+/yDeLWPCHy1XZP6vjIT5/8Ai4acB7W36jg1lClCNhqK54IWEjKYWHXwmt
FnpI1f2UHBPQd6j/LpTjeUILheDZ8n+/HBOsrG7t//8q/5HUaPv8u/xGN/ADD/aDvneGynKdBmtbD6Pw
rkLbhbYKMWoiabDnz5VjAFqP9p+R36+rMozcaVOP4veo83YkrgHmQ78t28598pskiWlP+x/82OMfqjbs
f4flPz2S/4P81skDbeAfPVU9r4V4x876NgJ1oAPbBr9JrrTu3pHfTLHjC5yzyTrxT/sNddDeo0JM4XOO
5Apfpl7O46O7VXv75Jik8Tn13/tyjO1fUP+RrMEDgHhY/Y+faz9BH9jQyjPfb5//twohq76eZDLbbRUS
S10314fto2dEqhhjspJcW7RP0EmybU9V6P/rrtmnO2DGkajUXaUsJFrBkQYq5ZqhAnCF8uxyXcsO3bV8
3B8l6NqpqiAL7devX14QPRZHpLx2Ten993K8Tmis32kYCRHo+KAXW/b/aVvJ8f+nfn8gxwuEdGbLKJHA
3VmIjkw9/ykEcC1W1xIEAFWmwQBQ7MCIBzDZosoBmBuEyILxG4LM99V5OjngxRSplo9j+CLwMtKz5yi3
VghgJoja/6mXAHHY/w8AfVOdf1COGQkThPgeoc79XI4BXxKz/kKA3BlCdhRSXY4ZFYb54zcJJSCDznQA
AkRJcuAT3dlrmWomkbD++pcM9Vrw/1rOAVyMcuDBftA3I9dsNtbJA6MKwI2kg2AfloGZAnznAXVushxr
4GfEhW4ZcYVHKdT3ll9HMEslv7Epo3DbHrpBR/Y3/OMrelobu1ykysCDHlVRRychQI56SAqx5zP+76/l
u58QQGLbuVOOSezsbxIefv9U/ddSjulHtgy+jc3wBZIu9G1n4vCN/6vKan3iR0OFblDn6aOAvJaTOnTC
RVJDP9DgbnlAfp2wUB9y2naZgUBG3Q9Iui4TCidqlMHHtV0+kd+3C5FETFf12FG25hvw1TM0CYgWCqa+
Q2lHNcsv3110IL3psR+bU2QKWRmazKm6EOAROFrr1q0jgeixBqQbN27Ush8WmQnUZL/oQYOontL8Bzn3
V6UzRp+2nl/KMYFKZ/ffk98EQDr+z/yyf5BvgpsOrIABI602fsciWydrb+zzZdtgumiNEMGFTkgHZ1Rs
zxNMAGNA1gYSvgHLiUJMUWpwojyjO66Bf+r5byGmpHUQYHqMUc//+GW+kG+CJ0HxLCECuOXhYzm2Iwnk
scmZzbr5zWiX8l8L/U5dS6IBr/SHR9T/gA36Ajg0eDDqRb8EXOr7o5CeIQCs4dWeIwEhQYAH+yGQ6UD9
a9Uu19GGle02Od4aOq+Ti/vlHCCtR4hb5DdB2NZBAkIw1+BBEmDBGlnwF8CUa/4khD508vC6/NZT8NqX
7TF60eCyO1QHvsuoy059MkMyWCgTWNg6X5Tz+Jb9jezMOvxI/ce0LUmGLcM5dEAygc8ys4Mv4OMkE/CA
PJlk2Cr/w7c9x0zAEiHA2/5Hv9EjX/oDPqRnFywPlKWf22ttAmGTYb4/9M9jd/qBTmY4T7Jsr8fPJ6rf
ADjJHrbKlMhqGZlNQn6brB81ENUOnMkIcf33Y994TEmQadEJTxSK42OzsvuUMeLiO2o9n0vbBDzAg6BC
R/CurVq1qhk1alSlAtJf/vKXpl69elo3T4usa4RGCZHBZwPRz+ScBRuu14CUD0RtcP6DXJcPRPEJRm5M
OwJyllcCBIHAJjz4oQ4oBFZGSs2FzhYiaHXxyYLuM6o+yiMzfk2wph2mWAmMe1W5TH60QM43FsJfAFNb
hiDEiA8ggD+CJUETmfhoEAXgmPoEuO31++WYwKqDF9PYgDpTewRRW5akgrYsEACiFnwoAyD8H78856KA
KFOhNlHC3sGsjBwDog+p9gne/Gf5YcQzUUgnNnfIb6ZodZmt6jc+xO+v/f9ok+D9mv8bcGVkT8C2dcDT
zer3p3IM39DrQsxYADiatwPym1G+rQMwwP5cy3/MkCwS0iCBfm2dfN8vxOhN17FdfuuR6Gr5TV+yZQBr
eGd0il+SHGoQJaGAD/QEaX3vlt+M7Gxdt/h1Wd3w/1oh7SsA2SVCOnGxPJBYTBLSswvUwfnwLAajUur+
yG8fAEV//K/5YXbE/gaP4Bl5+Lb/Y9OwfQBa+jFJhdc3jtZ07mzFaFTAcC2Hcq8WmivElEQzoepCcYEo
+kOJKJPpLFf+4ii/Rdol2BIMcXJkA1i9ups3bx4ZRI+FEemyZcu0zgAPpuEIxgAQYEOgPwnDyEePRAk4
TJ/SsQALPVoikDNaYorH1k8Ap+MCfDrw5ANRv2mPB12fHdmSyDHli62YMrZ1M2XLKJXzjFIHCpEQTRAa
JASwUYcuD3969PGw/Ia/r/xyBByA6X2h36hrmc60I2eSDi3fUvkN4MFf+KNB9J/kJGCtk2GCOaMWyAa7
/5JjkgmmF21QA3gBMYK6TWwY3TEKpAwjOo7/1ecNEL1YKN9IFCBEVq5/wf+2stGensYF8HVQJVAyCtNT
7PfIb6bzbB1M6d2kftPG/UL2VgGJBSAEGNhrkEMDMbwRk6x+vpZjeGFal/qJWciqweUx+a2BBR1dKWRB
9A9yDPiQsNh28Qva3eeXA1S3qvPUwWjXjui4jjYYjdk64JV+ge24RcHIyw4cGBWStCHfVUJ7hDQgozfd
Hn5IQvHvfv3wDEDrxAb+l/tthnmgf5MwMqLWMQB7ad/mHDMG1G0TNHSNLuj39lpbxv5m9MqsBvICrrns
Q7LRS4j+cPRAFOSWD0BajBHpv0i9OBEBFqNMFGKqprEQgEeGHecHRZ7hG047ZRwgmakOOi0OTIdmGtPK
Vl2OcXQ9bWM6dOhQKYD0iiuOeE0cQYcOTPAbJNRCqIaQTZI0iKIvghXBieBIcLG6JaAwggOw9P9a9/8h
5xgdEGQom822gCGffCCa6XpGdmT8TYVKhABVsn06LInSsznafUDO7RS6S5UBoLhPxH/UbdtEFqZ0CQJM
ExcKotTLqMoGRuphdAbfBNHwCIHzJD73CTFltlbIBrqv5Rj7oH9L9GOuAWDRez4QJaBzLfXzrUdGgGiu
abrX5Tyx4hWlD67Zon4DtIxUfq/+03YksSB4A2h6hK7LHPb5IOHJ5kPIer86T8AncNvygAGA94n/H4AE
nyRQjJwy1UvCsFWdgw94ZSRnywNyzCSE5Vss/5FUeYAhH0ajjJaz8Y/e4Yd+oqfUdXnsAz9aD8g5Uwiw
tAmUvQbbMNNETNf1kGD8SP2HbxMX14bqDvNKu5vVdegBvY8WGiy0O4d8JO34IvHlqIOo8OB9ADWMxGiK
LHi4ENMiS4QwFsK5EFkSGQUZMFnxQCEyb7KpU/32bNtxfaNMgjdyMF/eVojRL4GZ0QxOsFaI7NtFFl2W
a6kD5wQ4mJsnYHUWaihUXQgQxcn1SMvUqVPHDB06NDKYVqRVu0899ZTp27dvuBOQ9TNFRMDCVwCdxr7+
bZKEkzNaIntlmo5slEBKAKIDAcIkW4wc6BgkJEw9AswEzGeE7hcCiGiHzJ1gxgiTTsjUG+WeEmLqChCb
KHSKT/gd4Ea2DOAwcmSkyXlGEgRp2qYDUwa+SATw0yZ+WUalHAOsBHDaok1GFgQd6sUPCIDUuUsI3qiX
tpGfoHKN0GtCJHlci6z4zFl+GUZVAGC+kShyMuKjDjJ3giXgx0gDfZKkMM08V+gKIUCJETc6hOgL8Am/
BGfAHdugA0Yz2IfrOM//PxYi0cb3M4Eo/YBAik6QFRvBE9ejH+qlDoIvNkY/8ESdnIPwAUapnN8txIif
+tAZ8Qdwxj7olSQJQn6uJYC/7tfBfwATPNG+tZMGc65B/g1CjD6xB+1zLUCHDzFdyPXYEF6xH3ZBj/CB
nbgevXMNesefGUHxP/y+K/S6f57fxMM1fp3WZ4kt+CD25D94Z2BD+7Ze2mJGhOSUfkWcO17oDCESPmLt
/ULojyQPf8RH0B3nAHb0hhxPC2Er/sNOyEhf4zor5xQ5xs6AqeZhovym78ALfvEzoZ8LYWOSJn4fFsLW
JHDoi8EECTOy8f/rQtgdfZMQoyt4QveMiBcJMSABrOkf+FEm+8z3y5GEVhgQxSjVhGoKEQgBUhQJQNAh
xxZAI+UaMgqCK4AGQFcXsiAjh7F+UCbgRf2MdgFSAmJXIcCUxIAspxBZwtegE3TTV6izUDOhOkKnCQHk
nmHlQ2ALwOeEE04wzZo1M7169TKlpaV5AfVoAumjjz5qdu3aZWbNmmWqVasWBlCyTTrrdiE6PProIAT4
AFDYgU8toX5Ca4UIznQaAHCcEMkVSRYdBaID4S+lQiQ8BCU6OwGRNgAwggzXkymTHFEfwYBgxG9GjK2F
AKbqQgAftqMc1wJ2BB4SLcpQD9fS6QmsBBB8lWuRgz7BNz5FEKNfwDOyQASKc4XgF/4IkgA1wWOtENOG
BGX+J8CSCBC4twqRLOCfAKnVEUFtgVB7IXwp/IEH+hNJHDpDLsoDPvCPLjhGFxP9ctRJMIVPdAcv8Ao/
2AHbcQ31kUQAslxvk0/0Rt20SdvwYD/ohiSDgMu11EHijZ4JtgACbXM9bXLO2hY9wC9EMkAZQB0bWH7Q
F8kAhKyAO2DOeY4BCnSMLaiD47VCJHVhn+U3oyuCNzLhU9RJHfACf9QNf+gAPuCX/62e0R/H6BQ9Uo5r
+I2vIi9+jC7wKfjCv9AdfoMNkBHfRlckhOiOb+qgLvoFtNa/niSCWIOf4I/EFsCUvoU/0l8mCuFP1E09
6BQ+4Q/AgQfavFiI+pAJHpEVX+U6Kyd26+G3GeYBcMMH6JMkFoxmbxZCFmIB4E0ihW3wAXyLutEDOuYb
faMb6yvoCztjE3TRRghZ6cvYOZN9sG8nIXyxwoAojBD8TxUCSAE8gIGARIfGWK6Ewulg5wgBaNWF6HQ2
m5LD2D82SyPoEShxtDhkCcsOYBBsCYIkHXWFyAyrhuSDH5w1U4c+Vv87LPIAoDZg0Vl6CwFYODW6t0kE
Nu8iRPAgaNkRK3pDf4OECC6cmyjUWYjOQbJDACO40JFW+ccEUxIi7ME3HZBgQZCgHoIPddIRSWoaCQ3w
z9GZSaTooNWFmgiN8Ou2gEQggl8yXPxUf/Bd+AZcCKB0evgDjAhG1E8Asgkb/BCwCDgEuoH+tVYWeCWz
P9tvEx0BytRPO7QX/pAc4nsEG3QGYA/y66c99IDeCF7wQQJB+7QJj5AN6PCErARMAin1EXS5jn4Pb32E
AA5kpE3ahgf7wdZN/PaQn7bQMeWQgbqRE7mw1UT/NzxiNxs86SPokrJcj5/QJvXZBHaBXw/8UI5zgA51
MDIFPJAfIAN09gsdEmIUxOjnNSGCPmCLT2ErgBK5uQ5b8T+gY/ngG7nQLXbBLzUfJCHojDrwTdqFsAs+
slYIfSM7MlGeOimPfJTDVnyjI+oYJISvoG+uhyd0QCxF98cJaRDlevwWvVhbUzftkORjT/oo9VCfJWTi
WhI4+LJy0jb275aBBxsHuY7kCLCkPtq2YI09Fvj1UgcjStrmf2yOrek7/If+JwnBN+1TL3hB/wN/+J3J
PtSJPojx3ueoLCzy74laHiz4AKRkOzBHQASECEaAhAtxDYQyqvv1WYDBCWyQte3H+Z1PlkLkCcseVT6b
NRKsP8bWxzD9p/D+PaE9QmSUBB06uu106CScJPGbJINgPFiIqRqSGvwLvwB46cSco8NxDl0TwAkAdCKC
FwGPoM/11FdPiCA9yD9PwCDQUIYMltEmvof/EhAIJPBJQsj/jPJI7AjyXEeAswBM56wuFAZRAAPe4BO+
CABcA28jhZCRtpoIkUAOEgIQyNzhmfaom/8tn8gLP1pH1E87tBf+oE+SAJKWIX7dyIouaAe+qLurkE2C
0Qf8oUeIY8qie2xG2/ymPmRoIkRCiI1IQuw52qRtDe7Ei9pCBNdBQugZ2yET1yMzQM05kpnOflkL8OgQ
AOebPoI9sBE8A0bYjOshrqEe+KEeeEVebEAdELaET/RPHQAqARvgZJTEKJTAT3vUSTlbD0DC9bTb0z+H
v8EDbaNTEjyO8Vf8k//4bXWH7OiVcvxHfdSLzvFz2sS+g/x2aJuytn/wjY9gO9rmOoDb2gWdEj+PF8KH
sQd1wiP6o6xNoEhSzxLCx0hqaBNe8AHKoEf8ponPg5UTH8b/uC7MA3zRJnrDt6lvmF8OnXFM3fALGJIg
ktDSNu1ae2MzymJvq2PK4Ef4ExiED+LbmeyDzPhW0EcqAogKPx6wWQAigJzkMwmjZSE6GvVheNsG7RXz
E5YFHsoiQ65r0VMu+eCFMnQAHInO/L7Qn4QqMqj+Rfj7Z6F3hB4TukboSqGLhRhJ0BEIjHQoHBr5kFMn
SOjFBlM6pQVafCHTOWZC0DXX0JEJSAQVghPBnuBMECchqy5EnQQCOipE2SZCdETKQSSDdGYLWFxr29DX
62vpxAQr/YFn6kMGAgTBxrbJb/6Hb4IbfFI3AcfyYtsksCEL35S3SSs6DOsoxEKazqibZMICngXEJv7/
jFog/uc/5LMyWjtYnqiH+qwdsQ2ELJnOWb7QEfwjI7wjU3Uh/AB96XPYAL1AtINttQ4t3/Y8/Fh9wK+1
IX5BGb6tXNiBuqiTuuEZECHIMwrfIkTiB6DOFQJAKAev1p7ohjqwJedog3PwQNscI6flA1ktX1Z32AKd
4XNcBwhQJz5KGZt8W9+gHeq0trc84Rf830QI4CKZoU7sZWMb9qG/UI7ztGFBnHqwvY1b1RU/lKHeTP6K
bLRj+06YB5sc1fTlQVfIQjmrK5vkIgP16LatveGVctjQXmfrwWdsfECXmeyj44gUqRgjUY+R5FMUDdjE
BIfGsXFwOiwduVSIDHqh0HIhRndrhdYJra8ABB/wA1/LfD7hF77hHzl0h7WJklWkld0mZDa46iQn2zmC
BDqjUwF84Wv1edvp+eYakiZ4sVNfNphwjZ0J4byt315vr800W6JlgR97DfxxnZU9X5s6ObU88p1JD1aP
YX1aebjGJnBWH5yzurKjFitnmNewfbQcuc5pfmhDJ6nwYe2b6RznbXn40bqHb85pHfFb12+T8kz2t34C
uAByjHJGCDECIuljZMdIkHM2UdJ+YPVjk4hwu+FkXPMZ9gEto+XL1mvtZ/0tbE/tQzbps3rVPoGetY41
/zaZDZex9UXxV6tjzYMFOC2Dtqn2v3x9xtrb1oXOdN/TsRPZMsnn6eOojURzNZycy74XYz7dhCOfH1Rs
ZyVDs6MDRnFMaTCis1MhzPczDVRRCH5G+fzBJ/zCdxNfDuTRASSD+MlfiQbKVQN2lsPONNjRoJ3NABTC
Mw3lymDSWLwaiAtE/3+ObSjivQ8j+wAAAABJRU5ErkJggg==
</value>
</data>
</root>

56
ROMVault2/rvImages.cs Normal file
View File

@@ -0,0 +1,56 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System.Collections.Generic;
using System.Drawing;
namespace ROMVault2
{
public static class rvImages
{
private static List<string> names;
private static List<Bitmap> images;
public static Bitmap GetBitmap(string bitmapName)
{
object bmObj = rvImages1.ResourceManager.GetObject(bitmapName);
Bitmap bm = null;
if (bmObj != null)
bm = (Bitmap)bmObj;
return bm;
}
public static Bitmap TickBoxDisabled
{
get { return GetBitmap("TickBoxDisabled"); }
}
public static Bitmap TickBoxTicked
{
get { return GetBitmap("TickBoxTicked"); }
}
public static Bitmap TickBoxUnTicked
{
get { return GetBitmap("TickBoxUnTicked"); }
}
public static Bitmap ExpandBoxMinus
{
get { return GetBitmap("ExpandBoxMinus"); }
}
public static Bitmap ExpandBoxPlus
{
get { return GetBitmap("ExpandBoxPlus"); }
}
public static Bitmap romvaultTZ
{
get { return GetBitmap("romvaultTZ"); }
}
}
}

743
ROMVault2/rvImages1.Designer.cs generated Normal file
View File

@@ -0,0 +1,743 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.34011
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ROMVault2 {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class rvImages1 {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal rvImages1() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ROMVault2.rvImages1", typeof(rvImages1).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap DirDirCorrect {
get {
object obj = ResourceManager.GetObject("DirDirCorrect", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap DirDirCorrectBadCase {
get {
object obj = ResourceManager.GetObject("DirDirCorrectBadCase", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap DirDirMissing {
get {
object obj = ResourceManager.GetObject("DirDirMissing", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap DirDirUnknown {
get {
object obj = ResourceManager.GetObject("DirDirUnknown", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap DirectoryTree1 {
get {
object obj = ResourceManager.GetObject("DirectoryTree1", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap DirectoryTree2 {
get {
object obj = ResourceManager.GetObject("DirectoryTree2", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap DirectoryTree3 {
get {
object obj = ResourceManager.GetObject("DirectoryTree3", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap DirectoryTree4 {
get {
object obj = ResourceManager.GetObject("DirectoryTree4", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap ExpandBoxMinus {
get {
object obj = ResourceManager.GetObject("ExpandBoxMinus", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap ExpandBoxPlus {
get {
object obj = ResourceManager.GetObject("ExpandBoxPlus", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap G_CanBeFixed {
get {
object obj = ResourceManager.GetObject("G_CanBeFixed", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap G_Correct {
get {
object obj = ResourceManager.GetObject("G_Correct", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap G_Corrupt {
get {
object obj = ResourceManager.GetObject("G_Corrupt", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap G_CorruptCanBeFixed {
get {
object obj = ResourceManager.GetObject("G_CorruptCanBeFixed", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap G_Delete {
get {
object obj = ResourceManager.GetObject("G_Delete", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap G_DirCorrupt {
get {
object obj = ResourceManager.GetObject("G_DirCorrupt", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap G_Ignore {
get {
object obj = ResourceManager.GetObject("G_Ignore", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap G_InToSort {
get {
object obj = ResourceManager.GetObject("G_InToSort", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap G_Missing {
get {
object obj = ResourceManager.GetObject("G_Missing", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap G_MoveToSort {
get {
object obj = ResourceManager.GetObject("G_MoveToSort", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap G_NeededForFix {
get {
object obj = ResourceManager.GetObject("G_NeededForFix", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap G_NotCollected {
get {
object obj = ResourceManager.GetObject("G_NotCollected", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap G_Rename {
get {
object obj = ResourceManager.GetObject("G_Rename", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap G_Unknown {
get {
object obj = ResourceManager.GetObject("G_Unknown", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap G_UnNeeded {
get {
object obj = ResourceManager.GetObject("G_UnNeeded", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap G_UnScanned {
get {
object obj = ResourceManager.GetObject("G_UnScanned", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_InDatBad_NotCollected {
get {
object obj = ResourceManager.GetObject("R_InDatBad_NotCollected", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_InDatCollect_CanBeFixed {
get {
object obj = ResourceManager.GetObject("R_InDatCollect_CanBeFixed", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_InDatCollect_Correct {
get {
object obj = ResourceManager.GetObject("R_InDatCollect_Correct", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_InDatCollect_Corrupt {
get {
object obj = ResourceManager.GetObject("R_InDatCollect_Corrupt", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_InDatCollect_CorruptCanBeFixed {
get {
object obj = ResourceManager.GetObject("R_InDatCollect_CorruptCanBeFixed", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_InDatCollect_Missing {
get {
object obj = ResourceManager.GetObject("R_InDatCollect_Missing", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_InDatCollect_MoveToCorrupt {
get {
object obj = ResourceManager.GetObject("R_InDatCollect_MoveToCorrupt", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_InDatCollect_UnScanned {
get {
object obj = ResourceManager.GetObject("R_InDatCollect_UnScanned", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_InDatMerged_Deleted {
get {
object obj = ResourceManager.GetObject("R_InDatMerged_Deleted", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_InDatMerged_NeededForFix {
get {
object obj = ResourceManager.GetObject("R_InDatMerged_NeededForFix", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_InDatMerged_NotCollected {
get {
object obj = ResourceManager.GetObject("R_InDatMerged_NotCollected", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_InDatMerged_UnNeeded {
get {
object obj = ResourceManager.GetObject("R_InDatMerged_UnNeeded", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_InToSort_Corrupt {
get {
object obj = ResourceManager.GetObject("R_InToSort_Corrupt", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_InToSort_Delete {
get {
object obj = ResourceManager.GetObject("R_InToSort_Delete", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_InToSort_Deleted {
get {
object obj = ResourceManager.GetObject("R_InToSort_Deleted", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_InToSort_InToSort {
get {
object obj = ResourceManager.GetObject("R_InToSort_InToSort", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_InToSort_MoveToCorrupt {
get {
object obj = ResourceManager.GetObject("R_InToSort_MoveToCorrupt", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_InToSort_NeededForFix {
get {
object obj = ResourceManager.GetObject("R_InToSort_NeededForFix", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_NotInDat_Corrupt {
get {
object obj = ResourceManager.GetObject("R_NotInDat_Corrupt", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_NotInDat_Delete {
get {
object obj = ResourceManager.GetObject("R_NotInDat_Delete", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_NotInDat_Deleted {
get {
object obj = ResourceManager.GetObject("R_NotInDat_Deleted", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_NotInDat_Ignore {
get {
object obj = ResourceManager.GetObject("R_NotInDat_Ignore", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_NotInDat_MoveToCorrupt {
get {
object obj = ResourceManager.GetObject("R_NotInDat_MoveToCorrupt", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_NotInDat_MoveToSort {
get {
object obj = ResourceManager.GetObject("R_NotInDat_MoveToSort", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_NotInDat_NeededForFix {
get {
object obj = ResourceManager.GetObject("R_NotInDat_NeededForFix", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_NotInDat_Rename {
get {
object obj = ResourceManager.GetObject("R_NotInDat_Rename", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_NotInDat_Unknown {
get {
object obj = ResourceManager.GetObject("R_NotInDat_Unknown", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap R_NotInDat_UnScanned {
get {
object obj = ResourceManager.GetObject("R_NotInDat_UnScanned", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap romvaultTZ {
get {
object obj = ResourceManager.GetObject("romvaultTZ", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap TickBoxDisabled {
get {
object obj = ResourceManager.GetObject("TickBoxDisabled", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap TickBoxTicked {
get {
object obj = ResourceManager.GetObject("TickBoxTicked", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap TickBoxUnTicked {
get {
object obj = ResourceManager.GetObject("TickBoxUnTicked", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Tree1 {
get {
object obj = ResourceManager.GetObject("Tree1", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Tree2 {
get {
object obj = ResourceManager.GetObject("Tree2", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Tree3 {
get {
object obj = ResourceManager.GetObject("Tree3", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Tree4 {
get {
object obj = ResourceManager.GetObject("Tree4", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap ZipDirCorrect {
get {
object obj = ResourceManager.GetObject("ZipDirCorrect", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap ZipDirCorrupt {
get {
object obj = ResourceManager.GetObject("ZipDirCorrupt", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap ZipDirInToSort {
get {
object obj = ResourceManager.GetObject("ZipDirInToSort", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap ZipDirMissing {
get {
object obj = ResourceManager.GetObject("ZipDirMissing", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap ZipDirUnknown {
get {
object obj = ResourceManager.GetObject("ZipDirUnknown", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap ZipTZ {
get {
object obj = ResourceManager.GetObject("ZipTZ", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}

3922
ROMVault2/rvImages1.resx Normal file

File diff suppressed because it is too large Load Diff

47
ROMVault2/rvTree.Designer.cs generated Normal file
View File

@@ -0,0 +1,47 @@
namespace ROMVault2
{
partial class RvTree
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// rvTree
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.DoubleBuffered = true;
this.Name = "RvTree";
this.Size = new System.Drawing.Size(455, 416);
this.ResumeLayout(false);
}
#endregion
}
}

452
ROMVault2/rvTree.cs Normal file
View File

@@ -0,0 +1,452 @@
/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using ROMVault2.RvDB;
namespace ROMVault2
{
public partial class RvTree : UserControl
{
public event MouseEventHandler RvSelected;
private RvDir _lTree;
private RvDir _lSelected;
public RvTree()
{
InitializeComponent();
}
#region "Setup"
private int _yPos;
public void Setup(ref RvDir dirTree)
{
_lSelected = null;
_lTree = dirTree;
SetupInt();
}
private void SetupInt()
{
_yPos = 0;
int treeCount = _lTree.ChildCount;
if (treeCount >= 1)
{
for (int i = 0; i < treeCount - 1; i++)
SetupTree((RvDir)_lTree.Child(i), "├");
SetupTree((RvDir)_lTree.Child(treeCount - 1), "└");
}
AutoScrollMinSize = new Size(500, _yPos);
Refresh();
}
private void SetupTree(RvDir pTree, string pTreeBranches)
{
int nodeDepth = pTreeBranches.Length - 1;
pTree.Tree.TreeBranches = pTreeBranches;
pTree.Tree.RTree = new Rectangle(0, _yPos - 8, nodeDepth * 18, 16);
pTree.Tree.RExpand = new Rectangle(5 + nodeDepth * 18, _yPos + 4, 9, 9);
pTree.Tree.RChecked = new Rectangle(20 + nodeDepth * 18, _yPos + 2, 13, 13);
pTree.Tree.RIcon = new Rectangle(35 + nodeDepth * 18, _yPos, 16, 16);
pTree.Tree.RText = new Rectangle(51 + nodeDepth * 18, _yPos, 500, 16);
pTreeBranches = pTreeBranches.Replace("├", "│");
pTreeBranches = pTreeBranches.Replace("└", " ");
_yPos = _yPos + 16;
bool found = false;
int last = 0;
for (int i = 0; i < pTree.ChildCount; i++)
{
RvBase t = pTree.Child(i);
if (t is RvDir)
if (((RvDir)t).Tree != null)
{
found = true;
if (pTree.Tree.TreeExpanded)
last = i;
}
}
if (!found)
pTree.Tree.RExpand = new Rectangle(0, 0, 0, 0);
for (int i = 0; i < pTree.ChildCount; i++)
{
RvBase t = pTree.Child(i);
if (t is RvDir)
if (((RvDir)t).Tree != null)
{
if (pTree.Tree.TreeExpanded)
{
if (i != last)
SetupTree((RvDir)pTree.Child(i), pTreeBranches + "├");
else
SetupTree((RvDir)pTree.Child(i), pTreeBranches + "└");
}
}
}
}
#endregion
#region "Paint"
private int _hScroll;
private int _vScroll;
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
_hScroll = HorizontalScroll.Value;
_vScroll = VerticalScroll.Value;
Rectangle t = new Rectangle(e.ClipRectangle.Left + _hScroll, e.ClipRectangle.Top + _vScroll, e.ClipRectangle.Width, e.ClipRectangle.Height);
g.FillRectangle(Brushes.White, e.ClipRectangle);
if (_lTree != null)
for (int i = 0; i < _lTree.ChildCount; i++)
{
RvBase tBase = _lTree.Child(i);
if (tBase is RvDir)
{
RvDir tDir = (RvDir)tBase;
if (tDir.Tree != null)
PaintTree(tDir, g, t);
}
}
}
private void PaintTree(RvDir pTree, Graphics g, Rectangle t)
{
int y = pTree.Tree.RTree.Top - _vScroll;
if (pTree.Tree.RTree.IntersectsWith(t))
{
Pen p = new Pen(Brushes.Gray, 1) { DashStyle = DashStyle.Dot };
string lTree = pTree.Tree.TreeBranches;
for (int j = 0; j < lTree.Length; j++)
{
int x = j * 18 - _hScroll;
string cTree = lTree.Substring(j, 1);
switch (cTree)
{
case "│":
g.DrawLine(p, x + 9, y, x + 9, y + 16);
break;
case "├":
case "└":
g.DrawLine(p, x + 9, y, x + 9, y + 16);
g.DrawLine(p, x + 9, y + 16, x + 27, y + 16);
break;
}
}
}
if (!pTree.Tree.RExpand.IsEmpty)
if (pTree.Tree.RExpand.IntersectsWith(t))
{
g.DrawImage(pTree.Tree.TreeExpanded ? rvImages.ExpandBoxMinus : rvImages.ExpandBoxPlus, RSub(pTree.Tree.RExpand, _hScroll, _vScroll));
}
if (pTree.Tree.RChecked.IntersectsWith(t))
{
switch (pTree.Tree.Checked)
{
case RvTreeRow.TreeSelect.Disabled:
g.DrawImage(rvImages.TickBoxDisabled, RSub(pTree.Tree.RChecked, _hScroll, _vScroll));
break;
case RvTreeRow.TreeSelect.UnSelected:
g.DrawImage(rvImages.TickBoxUnTicked, RSub(pTree.Tree.RChecked, _hScroll, _vScroll));
break;
case RvTreeRow.TreeSelect.Selected:
g.DrawImage(rvImages.TickBoxTicked, RSub(pTree.Tree.RChecked, _hScroll, _vScroll));
break;
}
}
if (pTree.Tree.RIcon.IntersectsWith(t))
{
int icon = 2;
if (pTree.DirStatus.HasInToSort())
{
icon = 4;
}
else if (!pTree.DirStatus.HasCorrect())
{
icon = 1;
}
else if (!pTree.DirStatus.HasMissing())
{
icon = 3;
}
Bitmap bm;
if (pTree.Dat == null && pTree.DirDatCount != 1) // Directory above DAT's in Tree
bm = rvImages.GetBitmap("DirectoryTree" + icon);
else if (pTree.Dat == null && pTree.DirDatCount == 1) // Directory that contains DAT's
bm = rvImages.GetBitmap("Tree" + icon);
else if (pTree.Dat != null && pTree.DirDatCount == 0) // Directories made by a DAT
bm = rvImages.GetBitmap("Tree" + icon);
else
{
ReportError.SendAndShow("Unknown Tree settings in DisplayTree.");
bm = null;
}
if (bm != null)
{
g.DrawImage(bm, RSub(pTree.Tree.RIcon, _hScroll, _vScroll));
}
}
Rectangle recBackGround = new Rectangle(pTree.Tree.RText.X, pTree.Tree.RText.Y, Width - pTree.Tree.RText.X + _hScroll, pTree.Tree.RText.Height);
if (recBackGround.IntersectsWith(t))
{
string thistxt;
if (pTree.Dat == null && pTree.DirDatCount != 1) // Directory above DAT's in Tree
thistxt = pTree.Name;
else if (pTree.Dat == null && pTree.DirDatCount == 1) // Directory that contains DAT's
thistxt = pTree.Name + ": " + pTree.DirDat(0).GetData(RvDat.DatData.Description) + " ( Have:" + pTree.DirStatus.CountCorrect() + " \\ Missing: " + pTree.DirStatus.CountMissing() + " )";
// pTree.Parent.DirDatCount>1: This should probably be a test like parent contains Dat
else if (pTree.Dat != null && pTree.Dat.AutoAddDirectory && pTree.Parent.DirDatCount > 1)
thistxt = pTree.Name + ": " + pTree.Dat.GetData(RvDat.DatData.Description) + " ( Have:" + pTree.DirStatus.CountCorrect() + " \\ Missing: " + pTree.DirStatus.CountMissing() + " )";
else if (pTree.Dat != null && pTree.DirDatCount == 0) // Directories made by a DAT
thistxt = pTree.Name + " ( Have:" + pTree.DirStatus.CountCorrect() + " \\ Missing: " + pTree.DirStatus.CountMissing() + " )";
else
{
ReportError.SendAndShow("Unknown Tree settings in DisplayTree.");
thistxt = "";
}
if (_lSelected != null && pTree.TreeFullName == _lSelected.TreeFullName)
{
g.FillRectangle(new SolidBrush(Color.FromArgb(51, 153, 255)), RSub(recBackGround, _hScroll, _vScroll));
g.DrawString(thistxt, new Font("Microsoft Sans Serif", 8), Brushes.White, pTree.Tree.RText.Left - _hScroll, pTree.Tree.RText.Top + 1 - _vScroll);
}
else
{
g.DrawString(thistxt, new Font("Microsoft Sans Serif", 8), Brushes.Black, pTree.Tree.RText.Left - _hScroll, pTree.Tree.RText.Top + 1 - _vScroll);
}
}
if (pTree.Tree.TreeExpanded)
for (int i = 0; i < pTree.ChildCount; i++)
{
RvBase tBase = pTree.Child(i);
if (tBase is RvDir)
{
RvDir tDir = (RvDir)tBase;
if (tDir.Tree != null)
PaintTree(tDir, g, t);
}
}
}
private static Rectangle RSub(Rectangle r, int h, int v)
{
Rectangle ret = new Rectangle(r.Left - h, r.Top - v, r.Width, r.Height);
return ret;
}
#endregion
#region"Mouse Events"
private bool _mousehit;
protected override void OnMouseDown(MouseEventArgs mevent)
{
int x = mevent.X + HorizontalScroll.Value;
int y = mevent.Y + VerticalScroll.Value;
if (_lTree != null)
for (int i = 0; i < _lTree.ChildCount; i++)
{
RvDir tDir = (RvDir)_lTree.Child(i);
if (tDir.Tree != null)
if (CheckMouseDown(tDir, x, y, mevent))
break;
}
if (!_mousehit) return;
SetupInt();
base.OnMouseDown(mevent);
}
public void SetSelected(RvDir selected)
{
bool found = false;
RvDir t = selected;
while (t != null)
{
if (t.Tree != null)
{
if (!found)
{
_lSelected = t;
found = true;
}
else
t.Tree.TreeExpanded = true;
}
t = t.Parent;
}
SetupInt();
}
public RvDir GetSelected()
{
return _lSelected;
}
private bool CheckMouseDown(RvDir pTree, int x, int y, MouseEventArgs mevent)
{
if (pTree.Tree.RChecked.Contains(x, y))
{
if (pTree.Tree.Checked == RvTreeRow.TreeSelect.Disabled)
return true;
_mousehit = true;
SetChecked(pTree, pTree.Tree.Checked == RvTreeRow.TreeSelect.Selected ? RvTreeRow.TreeSelect.UnSelected : RvTreeRow.TreeSelect.Selected);
return true;
}
if (pTree.Tree.RExpand.Contains(x, y))
{
_mousehit = true;
SetExpanded(pTree, mevent.Button == MouseButtons.Right);
return true;
}
if (pTree.Tree.RText.Contains(x, y))
{
_mousehit = true;
if (RvSelected != null)
RvSelected(pTree, mevent);
_lSelected = pTree;
return true;
}
if (pTree.Tree.TreeExpanded)
for (int i = 0; i < pTree.ChildCount; i++)
{
RvBase rBase = pTree.Child(i);
if (rBase is RvDir)
{
RvDir rDir = (RvDir)rBase;
if (rDir.Tree != null)
if (CheckMouseDown(rDir, x, y, mevent))
return true;
}
}
return false;
}
private static void SetChecked(RvDir pTree, RvTreeRow.TreeSelect nSelection)
{
pTree.Tree.Checked = nSelection;
for (int i = 0; i < pTree.ChildCount; i++)
{
RvBase b = pTree.Child(i);
if (b is RvDir)
{
RvDir d = (RvDir)b;
if (d.Tree != null)
{
SetChecked(d, nSelection);
}
}
}
}
private static void SetExpanded(RvDir pTree, bool rightClick)
{
if (!rightClick)
{
pTree.Tree.TreeExpanded = !pTree.Tree.TreeExpanded;
return;
}
// Find the value of the first child node.
for (int i = 0; i < pTree.ChildCount; i++)
{
RvBase b = pTree.Child(i);
if (b is RvDir)
{
RvDir d = (RvDir)b;
if (d.Tree != null)
{
//Recusivly Set All Child Nodes to this value
SetExpandedRecurse(pTree, !d.Tree.TreeExpanded);
break;
}
}
}
}
private static void SetExpandedRecurse(RvDir pTree, bool expanded)
{
for (int i = 0; i < pTree.ChildCount; i++)
{
RvBase b = pTree.Child(i);
if (b is RvDir)
{
RvDir d = (RvDir)b;
if (d.Tree != null)
{
d.Tree.TreeExpanded = expanded;
SetExpandedRecurse(d, expanded);
}
}
}
}
#endregion
public RvBase Selected
{
get
{
return _lSelected;
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More