Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Copy-X Light detection with additional folder check. #332

Merged
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 34 additions & 20 deletions BinaryObjectScanner/Protection/CopyX.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
{
// Previous check 'Tivola Ring Protect' removed because it was found to actually be copy-x.
// The checks were for ZDAT/webmast.dxx and ZDAT/webmast.dxx, for Redump IDs 81628 and 116418.

// https://web.archive.org/web/20011016234742/http://www.optimal-online.de:80/product/copy_x.htm
// There are four kinds of copy-X; Light, Profesisonal, audio, and Trial Maker.
// Audio is for Audio CDs. Might be scannable, might not. Samples needed to confirm.
Expand All @@ -37,14 +37,15 @@
// Both Light and Professional have a directory at the end of the image. The files within this directory are
// intersected by the physical ring.
// This file is usually called ZDAT, but not always. At least one instance of Light calls it ZDATA. At least one
// instance of Professional calls it System.
// instance of Light calls it System.
// Seemingly it can be anything. It doesn't help that most known samples are specifically from one company's
// games, Tivola. Still, most use ZDAT.

// Professional:
// All instances of professional contain a disc check, performed via optgraph.dll.
// All instances of professional contain in the directory at the end of the image 3 files. gov_[something].x64,
// iofile.x64, and sound.x64.
// All instances of professional contain in a directory usually (but not always, German Emergency 2 Deluxe has a
// Videos folder as well, which isn't involved in rings/protection) at the end of the image, 3 files:
// gov_[something].x64, iofile.x64, and sound.x64. So far, they have always been in a directory called "System".
// Due to gov's minor name variance, sound.x64 sometimes being intersected by a ring at the start, and
// iofile.x64 being referenced directly in optgraph.x64, only iofile.x64 is being checked for now.
// TODO: optgraph.dll also contains DRM to prevent kernel debugger SoftICE from being used, via a process called
Expand All @@ -53,9 +54,10 @@
// It has none here since it wouldn't be necessary.

// Light:
// All instances of light contain 1 or more files in the directory at the end of the image. They all consist of
// either 0x00, or some data that matches between entries (and also is present in the 3 Professional files),
// except for the parts with the rings running through them.
// All instances of light contain 1 or more files in the directory usually (but not always; Kenny's Adventure has
// uses a System folder, and then has a non-protection Xtras folder on the disc as well) at the end of the image.
// They all consist of either 0x00, or some data that matches between entries (and also is present in the 3
// Professional files), except for the parts with the rings running through them.
// TODO: Check the last directory alphabetically and not just ZDAT*

/// <inheritdoc/>
Expand Down Expand Up @@ -114,22 +116,33 @@
// Excludes files with .x64 extension to avoid flagging Professional files.
// Sorts list of files in ZDAT* so just the first file gets pulled, later ones have a chance of the ring
// intersecting the start of the file.
var fileList = files.Where(f => !f.EndsWith(".x64", StringComparison.OrdinalIgnoreCase))
.Where(f =>

string[] dirs = ["ZDAT", "System/", "System\\"];//Kenny's Adventure uses System instead of ZDAT.
List<string>? lightFiles = null;
// TODO: Compensate for the check being run a directory or more higher
var fileList = files.Where(f => !f.EndsWith(".x64", StringComparison.OrdinalIgnoreCase));
{
foreach (var dir in dirs)
{
// TODO: Compensate for the check being run a directory or more higher
f = f.Remove(0, path.Length);
f = f.TrimStart('/', '\\');
return f.StartsWith("ZDAT", StringComparison.OrdinalIgnoreCase);
})
.OrderBy(f => f)
.ToList();

if (fileList.Count > 0)
lightFiles = fileList.Where(f =>
{
f = f.Remove(0, path.Length);
f = f.TrimStart('/', '\\');
return f.StartsWith(dir, StringComparison.OrdinalIgnoreCase);
})
.OrderBy(f => f)
.ToList();
if (lightFiles.Any())
{
break;
}
}
}
if (lightFiles.Count > 0)

Check warning on line 141 in BinaryObjectScanner/Protection/CopyX.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
{
try
{
using var stream = File.OpenRead(fileList[0]);
using var stream = File.OpenRead(lightFiles[0]);
byte[] block = stream.ReadBytes(1024);

var matchers = new List<ContentMatchSet>
Expand All @@ -153,7 +166,7 @@
], "copy-X [Check disc for physical ring]"),
};

var match = MatchUtil.GetFirstMatch(fileList[0], block, matchers, false);
var match = MatchUtil.GetFirstMatch(lightFiles[0], block, matchers, false);
if (!string.IsNullOrEmpty(match))
protections.Enqueue(match!);
}
Expand Down Expand Up @@ -184,6 +197,7 @@

// Seemingly comorbid file
// Check commented out until implementation can be decided
// At least one disc seen online calls it mov_05.x64
// new(new FilePathMatch("gov_*.x64"), "copy-X [Check disc for physical ring]"),
};
return MatchUtil.GetFirstMatch(path, matchers, any: true);
Expand Down
Loading