diff --git a/CHANGELIST.md b/CHANGELIST.md
index 7babfc10..f148260b 100644
--- a/CHANGELIST.md
+++ b/CHANGELIST.md
@@ -17,6 +17,7 @@
- Add tests around PS3 CFW helpers
- Enable test running on package and PR
- Fix missing test data
+- Add tests around Redumper helpers
### 3.2.4 (2024-11-24)
diff --git a/MPF.Processors.Test/RedumperTests.cs b/MPF.Processors.Test/RedumperTests.cs
index 78aea3ab..847df5a4 100644
--- a/MPF.Processors.Test/RedumperTests.cs
+++ b/MPF.Processors.Test/RedumperTests.cs
@@ -1,10 +1,12 @@
using System;
+using System.Collections.Generic;
using System.IO;
using SabreTools.RedumpLib.Data;
using Xunit;
namespace MPF.Processors.Test
{
+ // TODO: Add tests around remaining helper methods
public class RedumperTests
{
#region GetOutputFiles
@@ -164,5 +166,930 @@ namespace MPF.Processors.Test
}
#endregion
+
+ #region GetCuesheet
+
+ [Fact]
+ public void GetCuesheet_Empty_Null()
+ {
+ string log = string.Empty;
+ string? actual = Redumper.GetCuesheet(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetCuesheet_Invalid_Null()
+ {
+ string log = "INVALID";
+ string? actual = Redumper.GetCuesheet(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetCuesheet_Valid_Filled()
+ {
+ string? expected = "cuesheet";
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ string? actual = Redumper.GetCuesheet(log);
+ Assert.Equal(expected, actual);
+ }
+
+ #endregion
+
+ #region GetDatfile
+
+ [Fact]
+ public void GetDatfile_Empty_Null()
+ {
+ string log = string.Empty;
+ string? actual = Redumper.GetDatfile(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetDatfile_Invalid_Null()
+ {
+ string log = "INVALID";
+ string? actual = Redumper.GetDatfile(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetDatfile_Valid_Filled()
+ {
+ string? expected = "";
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ string? actual = Redumper.GetDatfile(log);
+ Assert.Equal(expected, actual);
+ }
+
+ #endregion
+
+ #region GetDiscType
+
+ [Fact]
+ public void GetDiscType_Empty_Null()
+ {
+ string log = string.Empty;
+ bool actual = Redumper.GetDiscType(log, out string? discTypeOrBookType);
+ Assert.False(actual);
+ }
+
+ [Fact]
+ public void GetDiscType_Invalid_Null()
+ {
+ string log = "INVALID";
+ bool actual = Redumper.GetDiscType(log, out string? discTypeOrBookType);
+ Assert.False(actual);
+ }
+
+ [Fact]
+ public void GetDiscType_Valid_Filled()
+ {
+ string? expected = "CD-ROM";
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ bool actual = Redumper.GetDiscType(log, out string? discTypeOrBookType);
+ Assert.True(actual);
+ Assert.Equal(expected, discTypeOrBookType);
+ }
+
+ #endregion
+
+ #region GetDVDProtection
+
+ [Fact]
+ public void GetDVDProtection_Empty_Null()
+ {
+ string log = string.Empty;
+ string? actual = Redumper.GetDVDProtection(log, includeAlways: true);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetDVDProtection_Invalid_Null()
+ {
+ string log = "INVALID";
+ string? actual = Redumper.GetDVDProtection(log, includeAlways: true);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetDVDProtection_ValidNotAlways_Filled()
+ {
+ string? expected = "FILE Title Key: No Title Key\nDecrypted Disc Key: No Key\n";
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ string? actual = Redumper.GetDVDProtection(log, includeAlways: false);
+ Assert.Equal(expected, actual);
+ }
+
+ [Fact]
+ public void GetDVDProtection_ValidAlways_Filled()
+ {
+ string? expected = "Region: 1 2 3 4 5 6 7 8\nCopyright Protection System Type: No\nFILE Title Key: No Title Key\nDecrypted Disc Key: No Key\n";
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ string? actual = Redumper.GetDVDProtection(log, includeAlways: true);
+ Assert.Equal(expected, actual);
+ }
+
+ #endregion
+
+ #region GetErrorCount
+
+ [Fact]
+ public void GetErrorCount_Empty_Null()
+ {
+ long expectedRedumpErrors = -1;
+ long expectedC2Errors = -1;
+ string log = string.Empty;
+ bool actual = Redumper.GetErrorCount(log, out long redumpErrors, out long c2Errors);
+
+ Assert.False(actual);
+ Assert.Equal(expectedRedumpErrors, redumpErrors);
+ Assert.Equal(expectedC2Errors, c2Errors);
+ }
+
+ [Fact]
+ public void GetErrorCount_Invalid_Null()
+ {
+ long expectedRedumpErrors = -1;
+ long expectedC2Errors = -1;
+ string log = "INVALID";
+ bool actual = Redumper.GetErrorCount(log, out long redumpErrors, out long c2Errors);
+
+ Assert.False(actual);
+ Assert.Equal(expectedRedumpErrors, redumpErrors);
+ Assert.Equal(expectedC2Errors, c2Errors);
+ }
+
+ [Fact]
+ public void GetErrorCount_Valid_Filled()
+ {
+ long expectedRedumpErrors = 12347;
+ long expectedC2Errors = 12346;
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ bool actual = Redumper.GetErrorCount(log, out long redumpErrors, out long c2Errors);
+
+ Assert.True(actual);
+ Assert.Equal(expectedRedumpErrors, redumpErrors);
+ Assert.Equal(expectedC2Errors, c2Errors);
+ }
+
+ #endregion
+
+ #region GetGDROMHeader
+
+ [Fact]
+ public void GetGDROMHeader_Empty_Null()
+ {
+ string log = string.Empty;
+ string? actual = Redumper.GetGDROMHeader(log,
+ out string? buildDate,
+ out string? serial,
+ out string? region,
+ out string? version);
+
+ Assert.Null(actual);
+ Assert.Null(buildDate);
+ Assert.Null(serial);
+ Assert.Null(region);
+ Assert.Null(version);
+ }
+
+ [Fact]
+ public void GetGDROMHeader_Invalid_Null()
+ {
+ string log = "INVALID";
+ string? actual = Redumper.GetGDROMHeader(log,
+ out string? buildDate,
+ out string? serial,
+ out string? region,
+ out string? version);
+
+ Assert.Null(actual);
+ Assert.Null(buildDate);
+ Assert.Null(serial);
+ Assert.Null(region);
+ Assert.Null(version);
+ }
+
+ [Fact]
+ public void GetGDROMHeader_Valid_Filled()
+ {
+ string? expected = "0000 line1\n0010 line2\n0020 line3\n0030 line4\n0040 line5\n0050 line6\n0060 line7\n0070 line8\n0080 line9\n0090 line0\n00A0 lineA";
+ string? expectedBuildDate = "date";
+ string? expectedSerial = "serial";
+ string? expectedRegion = "region";
+ string? expectedVersion = "version";
+
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ string? actual = Redumper.GetGDROMHeader(log,
+ out string? buildDate,
+ out string? serial,
+ out string? region,
+ out string? version);
+
+ Assert.Equal(expected, actual);
+ Assert.Equal(expectedBuildDate, buildDate);
+ Assert.Equal(expectedSerial, serial);
+ Assert.Equal(expectedRegion, region);
+ Assert.Equal(expectedVersion, version);
+ }
+
+ #endregion
+
+ #region GetHardwareInfo
+
+ [Fact]
+ public void GetHardwareInfo_Empty_Null()
+ {
+ string log = string.Empty;
+ bool actual = Redumper.GetHardwareInfo(log,
+ out string? manufacturer,
+ out string? model,
+ out string? firmware);
+
+ Assert.False(actual);
+ Assert.Null(manufacturer);
+ Assert.Null(model);
+ Assert.Null(firmware);
+ }
+
+ [Fact]
+ public void GetHardwareInfo_Invalid_Null()
+ {
+ string log = "INVALID";
+ bool actual = Redumper.GetHardwareInfo(log,
+ out string? manufacturer,
+ out string? model,
+ out string? firmware);
+
+ Assert.False(actual);
+ Assert.Null(manufacturer);
+ Assert.Null(model);
+ Assert.Null(firmware);
+ }
+
+ [Fact]
+ public void GetHardwareInfo_Valid_Filled()
+ {
+ string? expectedManufacturer = "manufacturer";
+ string? expectedModel = "model";
+ string? expectedFirmware = "revision (vendor)";
+
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ bool actual = Redumper.GetHardwareInfo(log,
+ out string? manufacturer,
+ out string? model,
+ out string? firmware);
+
+ Assert.True(actual);
+ Assert.Equal(expectedManufacturer, manufacturer);
+ Assert.Equal(expectedModel, model);
+ Assert.Equal(expectedFirmware, firmware);
+ }
+
+ #endregion
+
+ #region GetLayerbreaks
+
+ [Fact]
+ public void GetLayerbreaks_Empty_Null()
+ {
+ string log = string.Empty;
+ bool actual = Redumper.GetLayerbreaks(log,
+ out string? layerbreak1,
+ out string? layerbreak2,
+ out string? layerbreak3);
+
+ Assert.False(actual);
+ Assert.Null(layerbreak1);
+ Assert.Null(layerbreak2);
+ Assert.Null(layerbreak3);
+ }
+
+ [Fact]
+ public void GetLayerbreaks_Invalid_Null()
+ {
+ string log = "INVALID";
+ bool actual = Redumper.GetLayerbreaks(log,
+ out string? layerbreak1,
+ out string? layerbreak2,
+ out string? layerbreak3);
+
+ Assert.False(actual);
+ Assert.Null(layerbreak1);
+ Assert.Null(layerbreak2);
+ Assert.Null(layerbreak3);
+ }
+
+ [Fact]
+ public void GetLayerbreaks_Valid_Filled()
+ {
+ string? expectedLayerbreak1 = "12345";
+ string? expectedLayerbreak2 = "23456";
+ string? expectedLayerbreak3 = "34567";
+
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ bool actual = Redumper.GetLayerbreaks(log,
+ out string? layerbreak1,
+ out string? layerbreak2,
+ out string? layerbreak3);
+
+ Assert.True(actual);
+ Assert.Equal(expectedLayerbreak1, layerbreak1);
+ Assert.Equal(expectedLayerbreak2, layerbreak2);
+ Assert.Equal(expectedLayerbreak3, layerbreak3);
+ }
+
+ #endregion
+
+ #region GetMultisessionInformation
+
+ [Fact]
+ public void GetMultisessionInformation_Empty_Null()
+ {
+ string log = string.Empty;
+ string? actual = Redumper.GetMultisessionInformation(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetMultisessionInformation_Invalid_Null()
+ {
+ string log = "INVALID";
+ string? actual = Redumper.GetMultisessionInformation(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetMultisessionInformation_Valid_Filled()
+ {
+ string? expected = "Session 1: 0\nSession 2: 12345";
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ string? actual = Redumper.GetMultisessionInformation(log);
+ Assert.Equal(expected, actual);
+ }
+
+ #endregion
+
+ #region GetPlayStationAntiModchipDetected
+
+ [Fact]
+ public void GetPlayStationAntiModchipDetected_Empty_Null()
+ {
+ string log = string.Empty;
+ bool? actual = Redumper.GetPlayStationAntiModchipDetected(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetPlayStationAntiModchipDetected_Invalid_Null()
+ {
+ string log = "INVALID";
+ bool? actual = Redumper.GetPlayStationAntiModchipDetected(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetPlayStationAntiModchipDetected_Valid_Filled()
+ {
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ bool? actual = Redumper.GetPlayStationAntiModchipDetected(log);
+ Assert.True(actual);
+ }
+
+ #endregion
+
+ #region GetPlayStationEDCStatus
+
+ [Fact]
+ public void GetPlayStationEDCStatus_Empty_Null()
+ {
+ string log = string.Empty;
+ bool? actual = Redumper.GetPlayStationEDCStatus(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetPlayStationEDCStatus_Invalid_Null()
+ {
+ string log = "INVALID";
+ bool? actual = Redumper.GetPlayStationEDCStatus(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetPlayStationEDCStatus_Valid_Filled()
+ {
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ bool? actual = Redumper.GetPlayStationEDCStatus(log);
+ Assert.True(actual);
+ }
+
+ #endregion
+
+ #region GetPlayStationInfo
+
+ [Fact]
+ public void GetPlayStationInfo_Empty_Null()
+ {
+ string log = string.Empty;
+ bool actual = Redumper.GetPlayStationInfo(log,
+ out string? exeDate,
+ out string? serial,
+ out string? version);
+
+ Assert.False(actual);
+ Assert.Null(exeDate);
+ Assert.Null(serial);
+ Assert.Null(version);
+ }
+
+ [Fact]
+ public void GetPlayStationInfo_Invalid_Null()
+ {
+ string log = "INVALID";
+ bool actual = Redumper.GetPlayStationInfo(log,
+ out string? exeDate,
+ out string? serial,
+ out string? version);
+
+ Assert.False(actual);
+ Assert.Null(exeDate);
+ Assert.Null(serial);
+ Assert.Null(version);
+ }
+
+ [Fact]
+ public void GetPlayStationInfo_Valid_Filled()
+ {
+ string? expectedExeDate = "date";
+ string? expectedSerial = "serial";
+ string? expectedVersion = "version";
+
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ bool actual = Redumper.GetPlayStationInfo(log,
+ out string? exeDate,
+ out string? serial,
+ out string? version);
+
+ Assert.True(actual);
+ Assert.Equal(expectedExeDate, exeDate);
+ Assert.Equal(expectedSerial, serial);
+ Assert.Equal(expectedVersion, version);
+ }
+
+ #endregion
+
+ #region GetPlayStationLibCryptData
+
+ [Fact]
+ public void GetPlayStationLibCryptData_Empty_Null()
+ {
+ string log = string.Empty;
+ string? actual = Redumper.GetPlayStationLibCryptData(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetPlayStationLibCryptData_Invalid_Null()
+ {
+ string log = "INVALID";
+ string? actual = Redumper.GetPlayStationLibCryptData(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetPlayStationLibCryptData_Valid_Filled()
+ {
+ string? expected = "MSF: 00\nMSF: 01\nMSF: 02";
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ string? actual = Redumper.GetPlayStationLibCryptData(log);
+ Assert.Equal(expected, actual);
+ }
+
+ #endregion
+
+ #region GetPlayStationLibCryptStatus
+
+ [Fact]
+ public void GetPlayStationLibCryptStatus_Empty_Null()
+ {
+ string log = string.Empty;
+ bool? actual = Redumper.GetPlayStationLibCryptStatus(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetPlayStationLibCryptStatus_Invalid_Null()
+ {
+ string log = "INVALID";
+ bool? actual = Redumper.GetPlayStationLibCryptStatus(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetPlayStationLibCryptStatus_Valid_Filled()
+ {
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ bool? actual = Redumper.GetPlayStationLibCryptStatus(log);
+ Assert.True(actual);
+ }
+
+ #endregion
+
+ #region GetPVD
+
+ [Fact]
+ public void GetPVD_Empty_Null()
+ {
+ string log = string.Empty;
+ string? actual = Redumper.GetPVD(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetPVD_Invalid_Null()
+ {
+ string log = "INVALID";
+ string? actual = Redumper.GetPVD(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetPVD_Valid_Filled()
+ {
+ string? expected = "0320 TEST DATA\n0330 TEST DATA\n0340 TEST DATA\n0350 TEST DATA\n0360 TEST DATA\n0370 TEST DATA";
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ string? actual = Redumper.GetPVD(log);
+ Assert.Equal(expected, actual);
+ }
+
+ #endregion
+
+ #region GetRingNonZeroDataStart
+
+ [Fact]
+ public void GetRingNonZeroDataStart_Empty_Null()
+ {
+ string log = string.Empty;
+ string? actual = Redumper.GetRingNonZeroDataStart(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetRingNonZeroDataStart_Invalid_Null()
+ {
+ string log = "INVALID";
+ string? actual = Redumper.GetRingNonZeroDataStart(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetRingNonZeroDataStart_Valid_Filled()
+ {
+ string? expected = "12345";
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ string? actual = Redumper.GetRingNonZeroDataStart(log);
+ Assert.Equal(expected, actual);
+ }
+
+ #endregion
+
+ #region GetSaturnBuildInfo
+
+ [Fact]
+ public void GetSaturnBuildInfo_Null_Null()
+ {
+ string? segaHeader = null;
+ bool actual = Redumper.GetSaturnBuildInfo(segaHeader,
+ out string? buildDate,
+ out string? serial,
+ out string? version);
+
+ Assert.False(actual);
+ Assert.Null(buildDate);
+ Assert.Null(serial);
+ Assert.Null(version);
+ }
+
+ [Fact]
+ public void GetSaturnBuildInfo_Empty_Null()
+ {
+ string? segaHeader = string.Empty;
+ bool actual = Redumper.GetSaturnBuildInfo(segaHeader,
+ out string? buildDate,
+ out string? serial,
+ out string? version);
+
+ Assert.False(actual);
+ Assert.Null(buildDate);
+ Assert.Null(serial);
+ Assert.Null(version);
+ }
+
+ [Fact]
+ public void GetSaturnBuildInfo_Invalid_Null()
+ {
+ string? segaHeader = "INVALID";
+ bool actual = Redumper.GetSaturnBuildInfo(segaHeader,
+ out string? buildDate,
+ out string? serial,
+ out string? version);
+
+ Assert.False(actual);
+ Assert.Null(buildDate);
+ Assert.Null(serial);
+ Assert.Null(version);
+ }
+
+ [Fact]
+ public void GetSaturnBuildInfo_Valid_Filled()
+ {
+ string? expectedBuildDate = "1980-01-01";
+ string? expectedSerial = "serial";
+ string? expectedVersion = "ersio";
+
+ string? segaHeader = "LINE0\nLINE1\nLINE2XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXserial versio\nLINE3XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX19800101";
+ bool actual = Redumper.GetSaturnBuildInfo(segaHeader,
+ out string? buildDate,
+ out string? serial,
+ out string? version);
+
+ Assert.True(actual);
+ Assert.Equal(expectedBuildDate, buildDate);
+ Assert.Equal(expectedSerial, serial);
+ Assert.Equal(expectedVersion, version);
+ }
+
+ #endregion
+
+ #region GetSaturnHeader
+
+ [Fact]
+ public void GetSaturnHeader_Empty_Null()
+ {
+ string log = string.Empty;
+ string? actual = Redumper.GetSaturnHeader(log,
+ out string? buildDate,
+ out string? serial,
+ out string? region,
+ out string? version);
+
+ Assert.Null(actual);
+ Assert.Null(buildDate);
+ Assert.Null(serial);
+ Assert.Null(region);
+ Assert.Null(version);
+ }
+
+ [Fact]
+ public void GetSaturnHeader_Invalid_Null()
+ {
+ string log = "INVALID";
+ string? actual = Redumper.GetSaturnHeader(log,
+ out string? buildDate,
+ out string? serial,
+ out string? region,
+ out string? version);
+
+ Assert.Null(actual);
+ Assert.Null(buildDate);
+ Assert.Null(serial);
+ Assert.Null(region);
+ Assert.Null(version);
+ }
+
+ [Fact]
+ public void GetSaturnHeader_Valid_Filled()
+ {
+ string? expected = "0000 line1\n0010 line2\n0020 line3\n0030 line4\n0040 line5\n0050 line6\n0060 line7\n0070 line8\n0080 line9\n0090 line0\n00A0 lineA";
+ string? expectedBuildDate = "date";
+ string? expectedSerial = "serial";
+ string? expectedRegion = "region";
+ string? expectedVersion = "version";
+
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ string? actual = Redumper.GetSaturnHeader(log,
+ out string? buildDate,
+ out string? serial,
+ out string? region,
+ out string? version);
+
+ Assert.Equal(expected, actual);
+ Assert.Equal(expectedBuildDate, buildDate);
+ Assert.Equal(expectedSerial, serial);
+ Assert.Equal(expectedRegion, region);
+ Assert.Equal(expectedVersion, version);
+ }
+
+ #endregion
+
+ #region GetSecuROMData
+
+ [Fact]
+ public void GetSecuROMData_Empty_Null()
+ {
+ string log = string.Empty;
+ string? actual = Redumper.GetSecuROMData(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetSecuROMData_Invalid_Null()
+ {
+ string log = "INVALID";
+ string? actual = Redumper.GetSecuROMData(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetSecuROMData_Valid_Filled()
+ {
+ string? expected = "MSF: 00\nMSF: 01\nMSF: 02";
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ string? actual = Redumper.GetSecuROMData(log);
+ Assert.Equal(expected, actual);
+ }
+
+ #endregion
+
+ #region GetSegaCDHeader
+
+ [Fact]
+ public void GetSegaCDHeader_Empty_Null()
+ {
+ string log = string.Empty;
+ string? actual = Redumper.GetSegaCDHeader(log,
+ out string? buildDate,
+ out string? serial,
+ out string? region);
+
+ Assert.Null(actual);
+ Assert.Null(buildDate);
+ Assert.Null(serial);
+ Assert.Null(region);
+ }
+
+ [Fact]
+ public void GetSegaCDHeader_Invalid_Null()
+ {
+ string log = "INVALID";
+ string? actual = Redumper.GetSegaCDHeader(log,
+ out string? buildDate,
+ out string? serial,
+ out string? region);
+
+ Assert.Null(actual);
+ Assert.Null(buildDate);
+ Assert.Null(serial);
+ Assert.Null(region);
+ }
+
+ [Fact]
+ public void GetSegaCDHeader_Valid_Filled()
+ {
+ string? expected = "0100 line1\n0110 line2\n0120 line3\n0130 line4\n0140 line5\n0150 line6\n0160 line7\n0170 line8\n0180 line9\n0190 line0\n01A0 lineA";
+ string? expectedBuildDate = "date";
+ string? expectedSerial = "serial";
+ string? expectedRegion = "region";
+
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ string? actual = Redumper.GetSegaCDHeader(log,
+ out string? buildDate,
+ out string? serial,
+ out string? region);
+
+ Assert.Equal(expected, actual);
+ Assert.Equal(expectedBuildDate, buildDate);
+ Assert.Equal(expectedSerial, serial);
+ Assert.Equal(expectedRegion, region);
+ }
+
+ #endregion
+
+ #region GetUniversalHash
+
+ [Fact]
+ public void GetUniversalHash_Empty_Null()
+ {
+ string log = string.Empty;
+ string? actual = Redumper.GetUniversalHash(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetUniversalHash_Invalid_Null()
+ {
+ string log = "INVALID";
+ string? actual = Redumper.GetUniversalHash(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetUniversalHash_Valid_Filled()
+ {
+ string? expected = "da39a3ee5e6b4b0d3255bfef95601890afd80709";
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ string? actual = Redumper.GetUniversalHash(log);
+ Assert.Equal(expected, actual);
+ }
+
+ #endregion
+
+ #region GetVersion
+
+ [Fact]
+ public void GetVersion_Empty_Null()
+ {
+ string log = string.Empty;
+ string? actual = Redumper.GetVersion(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetVersion_Invalid_Null()
+ {
+ string log = "INVALID";
+ string? actual = Redumper.GetVersion(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetVersion_Valid_Filled()
+ {
+ string? expected = "v1980.01.01 build_00";
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ string? actual = Redumper.GetVersion(log);
+ Assert.Equal(expected, actual);
+ }
+
+ #endregion
+
+ #region GetVolumeLabels
+
+ [Fact]
+ public void GetVolumeLabels_Empty_Null()
+ {
+ string log = string.Empty;
+ bool actual = Redumper.GetVolumeLabels(log, out Dictionary> volLabels);
+
+ Assert.False(actual);
+ Assert.Empty(volLabels);
+ }
+
+ [Fact]
+ public void GetVolumeLabels_Invalid_Null()
+ {
+ string log = "INVALID";
+ bool actual = Redumper.GetVolumeLabels(log, out Dictionary> volLabels);
+
+ Assert.False(actual);
+ Assert.Empty(volLabels);
+ }
+
+ [Fact]
+ public void GetVolumeLabels_Valid_Filled()
+ {
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ bool actual = Redumper.GetVolumeLabels(log, out Dictionary> volLabels);
+
+ Assert.True(actual);
+ KeyValuePair> labelPair = Assert.Single(volLabels);
+ Assert.Equal("label", labelPair.Key);
+ string filesystem = Assert.Single(labelPair.Value);
+ Assert.Equal("ISO", filesystem);
+ }
+
+ #endregion
+
+ #region GetWriteOffset
+
+ [Fact]
+ public void GetWriteOffset_Empty_Null()
+ {
+ string log = string.Empty;
+ string? actual = Redumper.GetWriteOffset(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetWriteOffset_Invalid_Null()
+ {
+ string log = "INVALID";
+ string? actual = Redumper.GetWriteOffset(log);
+ Assert.Null(actual);
+ }
+
+ [Fact]
+ public void GetWriteOffset_Valid_Filled()
+ {
+ string? expected = "offset";
+ string log = Path.Combine(Environment.CurrentDirectory, "TestData", "Redumper", "CDROM", "test.log");
+ string? actual = Redumper.GetWriteOffset(log);
+ Assert.Equal(expected, actual);
+ }
+
+ #endregion
}
}
\ No newline at end of file
diff --git a/MPF.Processors.Test/TestData/Redumper/CDROM/test.log b/MPF.Processors.Test/TestData/Redumper/CDROM/test.log
index e98a0368..96e60df2 100644
--- a/MPF.Processors.Test/TestData/Redumper/CDROM/test.log
+++ b/MPF.Processors.Test/TestData/Redumper/CDROM/test.log
@@ -1,3 +1,7 @@
+DUMPING DATE (DateTime.Now)
+redumper v1980.01.01 build_00 [Jan 01 1980, 00:00:00]
+<< GetVersion (above) >>
+
<< GetCuesheet >>
CUE [
cuesheet
@@ -5,3 +9,138 @@ CUE [
<< GetDatfile >>
dat:
+
+<< GetDiscType >>
+current profile: CD-ROM
+
+<< GetDVDProtection >>
+copyright:
+ protection system type: none
+ region management information: 1 2 3 4 5 6 7 8
+ disc key: No Key
+ title keys:
+ FILE: none
+
+<< GetErrorCount >>
+C2: 12345
+REDUMP.ORG errors: 12345
+
+C2: 1
+REDUMP.ORG errors: 2
+
+<< GetGDROMHeader >>
+DC [
+ build date: date
+ version: version
+ serial: serial
+ region: region
+ header:
+ 0000 line1
+ 0010 line2
+ 0020 line3
+ 0030 line4
+ 0040 line5
+ 0050 line6
+ 0060 line7
+ 0070 line8
+ 0080 line9
+ 0090 line0
+ 00A0 lineA
+
+<< GetHardwareInfo >>
+drive path:
+ drive: manufacturer - model (revision level: revision, vendor specific: vendor)
+
+<< GetLayerbreaks >>
+layer break (layer: 0): 12345
+layer break (layer: 1): 23456
+layer break (layer: 2): 34567
+
+<< GetMultisessionInformation >>
+multisession:
+ session 1: 0
+ session 2: 12345
+
+<< GetPlayStationAntiModchipDetected >>
+<< GetPlayStationInfo >>
+<< GetPlayStationLibCryptData >>
+<< GetPlayStationLibCryptStatus >>
+PSX [
+ anti-modchip: yes
+ EXE: exe
+ EXE date: date
+ libcrypt: yes
+ MSF: 00
+ MSF: 01
+ MSF: 02
+ region: region
+ serial: serial
+ version: version
+
+<< GetPlayStationEDCStatus >>
+EDC: yes
+
+<< GetPVD >>
+PVD:
+0320 TEST DATA
+0330 TEST DATA
+0340 TEST DATA
+0350 TEST DATA
+0360 TEST DATA
+0370 TEST DATA
+
+<< GetRingNonZeroDataStart >>
+non-zero data sample range: [12345 23456]
+
+<< GetSaturnHeader >>
+SS [
+ build date: date
+ version: version
+ serial: serial
+ region: region
+ header:
+ 0000 line1
+ 0010 line2
+ 0020 line3
+ 0030 line4
+ 0040 line5
+ 0050 line6
+ 0060 line7
+ 0070 line8
+ 0080 line9
+ 0090 line0
+ 00A0 lineA
+
+<< GetSecuROMData >>
+SecuROM [
+ version: 0
+ MSF: 00
+ MSF: 01
+ MSF: 02
+
+<< GetSegaCDHeader >>
+MCD [
+ build date: date
+ serial: serial
+ region: region
+ header:
+ 0100 line1
+ 0110 line2
+ 0120 line3
+ 0130 line4
+ 0140 line5
+ 0150 line6
+ 0160 line7
+ 0170 line8
+ 0180 line9
+ 0190 line0
+ 01A0 lineA
+
+<< GetUniversalHash >>
+Universal Hash (SHA-1): da39a3ee5e6b4b0d3255bfef95601890afd80709
+
+<< GetVolumeLabels >>
+volume identifier: label
+
+<< GetWriteOffset >>
+disc write offset: offset
diff --git a/MPF.Processors.Test/UmdImageCreatorTests.cs b/MPF.Processors.Test/UmdImageCreatorTests.cs
index 56d4d438..21f10fb9 100644
--- a/MPF.Processors.Test/UmdImageCreatorTests.cs
+++ b/MPF.Processors.Test/UmdImageCreatorTests.cs
@@ -154,9 +154,10 @@ namespace MPF.Processors.Test
[Fact]
public void GetPVD_Valid_Filled()
{
+ string? expected = "0320 TEST DATA\n0330 TEST DATA\n0340 TEST DATA\n0350 TEST DATA\n0360 TEST DATA\n0370 TEST DATA\n";
string mainInfo = Path.Combine(Environment.CurrentDirectory, "TestData", "UmdImageCreator", "UMD", "test_mainInfo.txt");
string? actual = UmdImageCreator.GetPVD(mainInfo);
- Assert.NotNull(actual);
+ Assert.Equal(expected, actual);
}
#endregion
diff --git a/MPF.Processors/Redumper.cs b/MPF.Processors/Redumper.cs
index 9596c261..0da879ed 100644
--- a/MPF.Processors/Redumper.cs
+++ b/MPF.Processors/Redumper.cs
@@ -216,7 +216,7 @@ namespace MPF.Processors
RemoveHeader($"{basePath}.physical", $"{basePath}.pfi");
if (!File.Exists($"{basePath}.ss"))
ProcessingTool.CleanSS($"{basePath}.security", $"{basePath}.ss");
-
+
string xemidString = ProcessingTool.GetXeMID($"{basePath}.dmi");
var xemid = SabreTools.Serialization.Wrappers.XeMID.Create(xemidString);
if (xemid != null)
@@ -595,15 +595,15 @@ namespace MPF.Processors
// If the file doesn't exist, we can't copy
if (!File.Exists(inputFilename))
return false;
-
+
// If the output file already exists, don't overwrite
if (File.Exists(outputFilename))
return false;
-
+
try
{
using var inputStream = new FileStream(inputFilename, FileMode.Open, FileAccess.Read);
-
+
// If the header length is not valid, don't copy
if (headerLength < 1 || headerLength >= inputStream.Length)
return false;
@@ -639,15 +639,15 @@ namespace MPF.Processors
///
/// Log file location
/// Newline-delimited cuesheet if possible, null on error
- private static string? GetCuesheet(string log)
+ internal static string? GetCuesheet(string log)
{
// If the file doesn't exist, we can't get info from it
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
return null;
try
{
- // Fast forward to the dat line
+ // Fast forward to the cuesheet line
using var sr = File.OpenText(log);
while (!sr.EndOfStream && sr.ReadLine()?.TrimStart()?.StartsWith("CUE [") == false) ;
if (sr.EndOfStream)
@@ -675,7 +675,7 @@ namespace MPF.Processors
///
/// Log file location
/// Newline-delimited datfile if possible, null on error
- private static string? GetDatfile(string log)
+ internal static string? GetDatfile(string log)
{
// If the file doesn't exist, we can't get info from it
if (!File.Exists(log))
@@ -721,13 +721,13 @@ namespace MPF.Processors
///
/// Log file location
/// True if disc type info was set, false otherwise
- private static bool GetDiscType(string log, out string? discTypeOrBookType)
+ internal static bool GetDiscType(string log, out string? discTypeOrBookType)
{
// Set the default values
discTypeOrBookType = null;
// If the file doesn't exist, we can't get the info
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
return false;
try
@@ -765,10 +765,10 @@ namespace MPF.Processors
/// Log file location
/// Indicates whether region and protection type are always included
/// Formatted string representing the DVD protection, null on error
- private static string? GetDVDProtection(string log, bool includeAlways)
+ internal static string? GetDVDProtection(string log, bool includeAlways)
{
// If one of the files doesn't exist, we can't get info from them
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
return null;
// Setup all of the individual pieces
@@ -814,7 +814,7 @@ namespace MPF.Processors
else if (normalizedKey == "")
normalizedKey = "Error Retrieving Title Key";
- vobKeys += $"{match.Groups[1].Value} Title Key: {match.Groups[2].Value.Replace(':', ' ')}\n";
+ vobKeys += $"{match.Groups[1].Value} Title Key: {normalizedKey}\n";
}
else
{
@@ -865,10 +865,10 @@ namespace MPF.Processors
///
/// Log file location
/// True if error counts could be retrieved, false otherwise
- private static bool GetErrorCount(string log, out long redumpErrors, out long c2Errors)
+ internal static bool GetErrorCount(string log, out long redumpErrors, out long c2Errors)
{
// If the file doesn't exist, we can't get info from it
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
{
redumpErrors = -1; c2Errors = -1;
return false;
@@ -927,13 +927,13 @@ namespace MPF.Processors
///
/// Log file location
/// Header as a string if possible, null on error
- private static string? GetGDROMHeader(string log, out string? buildDate, out string? serial, out string? region, out string? version)
+ internal static string? GetGDROMHeader(string log, out string? buildDate, out string? serial, out string? region, out string? version)
{
// Set the default values
buildDate = null; serial = null; region = null; version = null;
// If the file doesn't exist, we can't get info from it
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
return null;
try
@@ -1000,13 +1000,13 @@ namespace MPF.Processors
///
/// Log file location
/// True if hardware info was set, false otherwise
- private static bool GetHardwareInfo(string log, out string? manufacturer, out string? model, out string? firmware)
+ internal static bool GetHardwareInfo(string log, out string? manufacturer, out string? model, out string? firmware)
{
// Set the default values
manufacturer = null; model = null; firmware = null;
// If the file doesn't exist, we can't get info from it
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
return false;
try
@@ -1048,13 +1048,13 @@ namespace MPF.Processors
///
/// Log file location
/// True if any layerbreaks were found, false otherwise
- private static bool GetLayerbreaks(string log, out string? layerbreak1, out string? layerbreak2, out string? layerbreak3)
+ internal static bool GetLayerbreaks(string log, out string? layerbreak1, out string? layerbreak2, out string? layerbreak3)
{
// Set the default values
layerbreak1 = null; layerbreak2 = null; layerbreak3 = null;
// If the file doesn't exist, we can't get info from it
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
return false;
try
@@ -1123,10 +1123,10 @@ namespace MPF.Processors
///
/// Log file location
/// Formatted multisession information, null on error
- private static string? GetMultisessionInformation(string log)
+ internal static string? GetMultisessionInformation(string log)
{
// If the file doesn't exist, we can't get info from it
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
return null;
try
@@ -1175,28 +1175,28 @@ namespace MPF.Processors
///
/// Log file location
/// Anti-modchip existence if possible, false on error
- private static bool? GetPlayStationAntiModchipDetected(string log)
+ internal static bool? GetPlayStationAntiModchipDetected(string log)
{
// If the file doesn't exist, we can't get info from it
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
return null;
try
{
// Check for the anti-modchip strings
using var sr = File.OpenText(log);
- var line = sr.ReadLine()?.Trim();
while (!sr.EndOfStream)
{
+ var line = sr.ReadLine()?.Trim();
+
+ // If we have a null line, just break
if (line == null)
- return false;
+ break;
if (line.StartsWith("anti-modchip: no"))
return false;
else if (line.StartsWith("anti-modchip: yes"))
return true;
-
- line = sr.ReadLine()?.Trim();
}
return false;
@@ -1213,28 +1213,28 @@ namespace MPF.Processors
///
/// Log file location
/// Status of PS1 EDC, if possible
- private static bool? GetPlayStationEDCStatus(string log)
+ internal static bool? GetPlayStationEDCStatus(string log)
{
// If the file doesn't exist, we can't get info from it
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
return null;
try
{
// Check for the EDC strings
using var sr = File.OpenText(log);
- var line = sr.ReadLine()?.Trim();
while (!sr.EndOfStream)
{
+ var line = sr.ReadLine()?.Trim();
+
+ // If we have a null line, just break
if (line == null)
- return false;
+ break;
if (line.Contains("EDC: no"))
return false;
else if (line.Contains("EDC: yes"))
return true;
-
- line = sr.ReadLine()?.Trim();
}
return false;
@@ -1251,13 +1251,13 @@ namespace MPF.Processors
///
/// Log file location
/// True if section found, null on error
- private static bool GetPlayStationInfo(string log, out string? exeDate, out string? serial, out string? version)
+ internal static bool GetPlayStationInfo(string log, out string? exeDate, out string? serial, out string? version)
{
// Set the default values
exeDate = null; serial = null; version = null;
// If the file doesn't exist, we can't get info from it
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
return false;
try
@@ -1296,7 +1296,7 @@ namespace MPF.Processors
{
exeDate = line.Substring("EXE date: ".Length).Trim();
}
- else if (line.StartsWith("libcrypt:"))
+ else if (line.StartsWith("libcrypt:") || line.StartsWith("MSF:"))
{
// Valid but skip
}
@@ -1332,10 +1332,10 @@ namespace MPF.Processors
///
/// Log file location
/// PS1 LibCrypt data, if possible
- private static string? GetPlayStationLibCryptData(string log)
+ internal static string? GetPlayStationLibCryptData(string log)
{
// If the file doesn't exist, we can't get info from it
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
return null;
try
@@ -1368,10 +1368,10 @@ namespace MPF.Processors
///
/// Log file location
/// Status of PS1 LibCrypt, if possible
- private static bool? GetPlayStationLibCryptStatus(string log)
+ internal static bool? GetPlayStationLibCryptStatus(string log)
{
// If the file doesn't exist, we can't get info from it
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
return null;
try
@@ -1406,10 +1406,10 @@ namespace MPF.Processors
///
/// Log file location
/// Newline-delimited PVD if possible, null on error
- private static string? GetPVD(string log)
+ internal static string? GetPVD(string log)
{
// If the file doesn't exist, we can't get info from it
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
return null;
try
@@ -1421,7 +1421,7 @@ namespace MPF.Processors
return null;
// Now that we're at the relevant entries, read each line in and concatenate
- string? pvdString = "", line = sr.ReadLine();
+ string? pvdString = string.Empty, line = sr.ReadLine();
while (line?.StartsWith("03") == true)
{
pvdString += line + "\n";
@@ -1442,10 +1442,10 @@ namespace MPF.Processors
///
/// Log file location
/// Non-zero dta start if possible, null on error
- private static string? GetRingNonZeroDataStart(string log)
+ internal static string? GetRingNonZeroDataStart(string log)
{
// If the file doesn't exist, we can't get info from it
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
return null;
try
@@ -1475,7 +1475,7 @@ namespace MPF.Processors
/// <String representing a formatter variant of the Saturn header
/// True on successful extraction of info, false otherwise
/// TODO: Remove when Redumper gets native reading support
- private static bool GetSaturnBuildInfo(string? segaHeader, out string? buildDate, out string? serial, out string? version)
+ internal static bool GetSaturnBuildInfo(string? segaHeader, out string? buildDate, out string? serial, out string? version)
{
buildDate = null; serial = null; version = null;
@@ -1507,13 +1507,13 @@ namespace MPF.Processors
///
/// Log file location
/// Header as a byte array if possible, null on error
- private static string? GetSaturnHeader(string log, out string? buildDate, out string? serial, out string? region, out string? version)
+ internal static string? GetSaturnHeader(string log, out string? buildDate, out string? serial, out string? region, out string? version)
{
// Set the default values
buildDate = null; serial = null; region = null; version = null;
// If the file doesn't exist, we can't get info from it
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
return null;
try
@@ -1587,14 +1587,14 @@ namespace MPF.Processors
}
///
- /// Get the header from a Saturn, if possible
+ /// Get the SecuROM data from the input file, if possible
///
/// Log file location
- /// Header as a byte array if possible, null on error
- private static string? GetSecuROMData(string log)
+ /// SecuROM data, if possible
+ internal static string? GetSecuROMData(string log)
{
// If the file doesn't exist, we can't get info from it
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
return null;
try
@@ -1635,13 +1635,13 @@ namespace MPF.Processors
///
/// Log file location
/// Header as a byte array if possible, null on error
- private static string? GetSegaCDHeader(string log, out string? buildDate, out string? serial, out string? region)
+ internal static string? GetSegaCDHeader(string log, out string? buildDate, out string? serial, out string? region)
{
// Set the default values
buildDate = null; serial = null; region = null;
// If the file doesn't exist, we can't get info from it
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
return null;
try
@@ -1704,10 +1704,10 @@ namespace MPF.Processors
///
/// Log file location
/// Universal hash if possible, null on error
- private static string? GetUniversalHash(string log)
+ internal static string? GetUniversalHash(string log)
{
// If the file doesn't exist, we can't get info from it
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
return null;
try
@@ -1736,10 +1736,10 @@ namespace MPF.Processors
///
/// Log file location
/// Version if possible, null on error
- private static string? GetVersion(string log)
+ internal static string? GetVersion(string log)
{
// If the file doesn't exist, we can't get info from it
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
return null;
// Samples:
@@ -1780,11 +1780,11 @@ namespace MPF.Processors
///
/// Log file location
/// Volume labels (by type), or null if none present
- private static bool GetVolumeLabels(string log, out Dictionary> volLabels)
+ internal static bool GetVolumeLabels(string log, out Dictionary> volLabels)
{
// If the file doesn't exist, can't get the volume labels
volLabels = [];
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
return false;
try
@@ -1834,10 +1834,10 @@ namespace MPF.Processors
///
/// Log file location
/// Sample write offset if possible, null on error
- private static string? GetWriteOffset(string log)
+ internal static string? GetWriteOffset(string log)
{
// If the file doesn't exist, we can't get info from it
- if (!File.Exists(log))
+ if (string.IsNullOrEmpty(log) || !File.Exists(log))
return null;
try