return false;
}
+static bool hlds_product_has (const char *product_id, const char *needle) {
+ return product_id && needle && strstr (product_id, needle) != NULL;
+}
+
+static bool hlds_product_has_any (
+ const char *product_id,
+ const char **needles,
+ size_t count
+) {
+ size_t i;
+ for (i = 0; i < count; i++) {
+ if (hlds_product_has (product_id, needles[i]))
+ return true;
+ }
+ return false;
+}
+
static bool dvd_is_hlds_gcc4243_4244_drive (dvd_drive *dvd) {
static const char *names[] = {
"GCC-4243N", "GCC4243N", "GCC4243",
{ "GCC-4242N", "0J06", 22, 0x80000000U, 1, 8, "GCC-4242N 0J06 promoted E7 parser profile", "error_prone_supported_profile_hardening", "GCC_424x", "HL;IT;RPC;RPC_JCS3;RPC_SUFFIX", "stage5b_0066", 0x824U, 0x90038621U, "capable but error-prone; conservative Method 8 one-window validation profile" },
{ "GCC-4243N", "0000", 3, 0x80000000U, 5, 8, "GCC-4243N 0000 promoted E7 parser profile", "known_supported_profile_hardening", "GCC_424x", "HL;IT;RPC;RPC_JCS3;RPC_SUFFIX", "stage5b_0069", 0x884U, 0x90037929U, "known-supported GCC_424x profile hardening target" },
{ "GCC-4243N", "1.08", 3, 0x80000000U, 5, 8, "GCC-4243N 1.08 promoted E7 parser profile", "known_supported_profile_hardening", "GCC_424x", "HL;IT;RPC;RPC_JCS3;RPC_SUFFIX", "stage5b_0071", 0x880U, 0x90036813U, "known-supported GCC_424x profile hardening target" },
+ { "GCC4243", "A102", 3, 0x80000000U, 5, 8, "GCC-4243N A102 promoted E7 parser profile", "known_supported_profile_hardening", "GCC_424x", "HL;IT;RPC;RPC_JCS3;RPC_SUFFIX", "hybrid_identity_v3:stage5b_0439", 0x880U, 0x9003731dU, "Live INQUIRY alias for GCC4243/A102; analyzer-derived exact parser metadata; read-only profile hardening target; not yet live-validated with the exact profile" },
+ { "GCC-4243N", "A102", 3, 0x80000000U, 5, 8, "GCC-4243N A102 promoted E7 parser profile", "known_supported_profile_hardening", "GCC_424x", "HL;IT;RPC;RPC_JCS3;RPC_SUFFIX", "hybrid_identity_v3:stage5b_0439", 0x880U, 0x9003731dU, "Canonical model alias for GCC-4243N A102; analyzer-derived exact parser metadata; read-only profile hardening target; not yet live-validated with the exact profile" },
{ "GCC-4244N", "1.03", 3, 0x80000000U, 5, 8, "GCC-4244N 1.03 promoted E7 parser profile", "known_supported_profile_hardening", "GCC_424x", "HL;IT;RPC;RPC_JCS3;RPC_SUFFIX", "stage5b_0073", 0x88cU, 0x90037d06U, "P1 owned GCC_424x profile hardening target" },
{ "GCC-4244N", "103", 3, 0x80000000U, 5, 8, "GCC-4244N 103 promoted E7 parser profile", "known_supported_profile_hardening", "GCC_424x", "HL;IT;RPC;RPC_JCS3;RPC_SUFFIX", "stage5b_0076", 0x894U, 0x900386fbU, "P1 owned GCC_424x profile hardening target" },
+ { "GCC4244", "B101", 3, 0x80000000U, 5, 8, "GCC-4244N B101 promoted E7 parser profile", "known_supported_profile_hardening", "GCC_424x", "HL;IT;RPC;RPC_JCS3;RPC_SUFFIX", "hybrid_identity_v3:stage5b_0426", 0x894U, 0x900386d2U, "Live INQUIRY alias for GCC4244/B101; legacy Type3 fallback completed a Redump-matching GameCube dump; exact parser metadata is analyzer-derived and is the regression oracle for A102 hardening" },
+ { "GCC-4244N", "B101", 3, 0x80000000U, 5, 8, "GCC-4244N B101 promoted E7 parser profile", "known_supported_profile_hardening", "GCC_424x", "HL;IT;RPC;RPC_JCS3;RPC_SUFFIX", "hybrid_identity_v3:stage5b_0426", 0x894U, 0x900386d2U, "Canonical model alias for GCC-4244N B101; legacy Type3 fallback completed a Redump-matching GameCube dump; exact parser metadata is analyzer-derived and is the regression oracle for A102 hardening" },
{ "GCC4244", "B103", 3, 0x80000000U, 5, 8, "GCC-4244N B103 promoted E7 parser profile", "known_supported_profile_hardening_live_validated", "GCC_424x", "HL;IT;RPC;RPC_JCS3;RPC_SUFFIX", "promoted_parser_signature_v23", 0x894U, 0x900386fbU, "Live INQUIRY alias for HL-DT-ST CDRW/DVD GCC4244 B103; case label B101; exact Stage5B parser signature recovered; media preflight, seed retrieval, full GameCube dump, STOP UNIT, and Redump hash match validated" },
{ "GCC-4244N", "B103", 3, 0x80000000U, 5, 8, "GCC-4244N B103 promoted E7 parser profile", "known_supported_profile_hardening_live_validated", "GCC_424x", "HL;IT;RPC;RPC_JCS3;RPC_SUFFIX", "promoted_parser_signature_v23", 0x894U, 0x900386fbU, "B103 shares the promoted parser signature gate/CDB with 103/104; live GCC4244/B103 hardware completed a Redump-matching GameCube dump" },
{ "GCC-4244N", "104", 3, 0x80000000U, 5, 8, "GCC-4244N 104 promoted E7 parser profile", "known_supported_profile_hardening", "GCC_424x", "HL;IT;RPC;RPC_JCS3;RPC_SUFFIX", "stage5b_0078", 0x894U, 0x900386fbU, "P1 owned GCC_424x profile hardening target" },
{ "GDR-3120L", "0046", 4, 0x80000000U, 5, 8, "GDR-3120L 0046 experimental GC/Wii E7 parser profile", "experimental_gc_wii_candidate", "GDR_3120x", "HL;IT;RPC;RPC_JD4_SPACE;RPC_SUFFIX", "stage5b_0355", 0x5b8U, 0x90025bceU, "historically Xbox/reference; allow read-only GC/Wii Method 8 experiment, not proven support until dump validates" },
- { "GDR-8050L", "0L23", 44, 0x80000000U, 1, 8, "GDR-8050L 0L23 donor/modified-firmware E7 parser profile", "donor_reference_modified_firmware_only", "GDR_8050x", "HL;IT;RPC;RPC_JD4_SPACE;RPC_SUFFIX", "stage5b_0099", 0x5d0U, 0x90026160U, "stock firmware is Xbox-only here; GC/Wii 0xE7 path requires modified firmware with memdump support" },
+ { "GDR-8050L", "0012", 44, 0x80000000U, 1, 8, "GDR-8050L 0012 hybrid cross-flash E7 parser profile", "hybrid_crossflash_modified_firmware_only", "GDR_8050x", "HL;IT;RPC;RPC_JD4_SPACE;RPC_SUFFIX", "hybrid_identity_v3:gdr8050l_0012", 0x5d0U, 0x90026160U, "Operating identity is GDR-8050L 0012 on GDR-8163B physical hardware; package compatibility identity is GDR-8163B 0L23; GC/Wii 0xE7 access requires modified firmware; native GDR-8050L hardware is not owned" },
{ "GDR-8082N", "0120", 4, 0x80000000U, 5, 9, "GDR-8082N 0120 promoted E7 parser profile", "known_supported_profile_hardening", "GDR_808x", "HL;IT;RPC;RPC_SUFFIX", "stage5b_0103", 0x638U, 0x900282daU, "known-supported reference profile" },
{ "GDR-8083N", "0K04", 4, 0x80000000U, 5, 9, "GDR-8083N 0K04 promoted E7 parser profile", "known_supported_profile_hardening", "GDR_808x", "HL;IT;RPC;RPC_SUFFIX", "stage5b_0104", 0x638U, 0x900291fcU, "known-supported reference profile" },
{ "GDR-8161B", "0102", 4, 0x80000000U, 5, 9, "GDR-8161B 0102 promoted E7 parser profile", "known_supported_profile_hardening", "GDR_816x", "IT;RPC;RPC_SUFFIX", "stage5b_0109", 0x5a8U, 0x90025010U, "known-supported reference profile" },
dst[j] = 0;
}
-static bool hlds_model_matches (dvd_drive *dvd, const char *model) {
+static bool hlds_model_matches_value (const char *product_id, const char *model) {
char prod_norm[64];
char model_norm[64];
- if (!dvd || !dvd -> prod_id || !model)
+ if (!product_id || !model)
return false;
- hlds_normalize_model (dvd -> prod_id, prod_norm, sizeof (prod_norm));
+ hlds_normalize_model (product_id, prod_norm, sizeof (prod_norm));
hlds_normalize_model (model, model_norm, sizeof (model_norm));
return prod_norm[0] && model_norm[0] && strstr (prod_norm, model_norm) != NULL;
}
-static bool hlds_revision_matches (dvd_drive *dvd, const char *revision) {
+static bool hlds_revision_matches_value (const char *actual, const char *expected) {
const unsigned char *a;
const unsigned char *b;
- if (!revision || !revision[0])
+ if (!expected || !expected[0])
return true;
- if (!dvd || !dvd -> prod_rev)
+ if (!actual)
return false;
- a = (const unsigned char *) dvd -> prod_rev;
- b = (const unsigned char *) revision;
+ a = (const unsigned char *) actual;
+ b = (const unsigned char *) expected;
while (*a && *b) {
if (toupper (*a) != toupper (*b))
return false;
return *a == 0 && *b == 0;
}
-static const hlds_e7_profile_desc *dvd_find_hlds_e7_profile (dvd_drive *dvd) {
+static const hlds_e7_profile_desc *hlds_find_e7_profile_for_identity (
+ const char *vendor,
+ const char *product_id,
+ const char *revision
+) {
const hlds_e7_profile_desc *p;
- if (!dvd_is_hlds_drive (dvd))
+ if (!vendor || strcmp (vendor, "HL-DT-ST") != 0)
return NULL;
for (p = hlds_e7_profiles; p -> model; p++) {
- if (hlds_model_matches (dvd, p -> model) && hlds_revision_matches (dvd, p -> firmware))
+ if (
+ hlds_model_matches_value (product_id, p -> model) &&
+ hlds_revision_matches_value (revision, p -> firmware)
+ )
return p;
}
return NULL;
}
-static u_int32_t dvd_hlds_e7_detect_type (dvd_drive *dvd) {
- const hlds_e7_profile_desc *profile = dvd_find_hlds_e7_profile (dvd);
+static const hlds_e7_profile_desc *dvd_find_hlds_e7_profile (dvd_drive *dvd) {
+ if (!dvd)
+ return NULL;
+ return hlds_find_e7_profile_for_identity (
+ dvd -> vendor,
+ dvd -> prod_id,
+ dvd -> prod_rev
+ );
+}
+
+bool dvd_lookup_hlds_e7_profile (
+ const char *vendor,
+ const char *product_id,
+ const char *revision,
+ dvd_hlds_e7_profile_info *out
+) {
+ const hlds_e7_profile_desc *p;
+ if (out)
+ memset (out, 0, sizeof (*out));
+ p = hlds_find_e7_profile_for_identity (vendor, product_id, revision);
+ if (!p)
+ return false;
+ if (out) {
+ out -> type = p -> type;
+ out -> cache_base = p -> cache_base;
+ out -> mem_blocks = p -> mem_blocks;
+ out -> preferred_method = p -> preferred_method;
+ out -> label = p -> label;
+ out -> support_tier = p -> support_tier;
+ out -> family = p -> family;
+ out -> tokens = p -> tokens;
+ out -> record_id = p -> record_id;
+ out -> static_cdb_base = p -> static_cdb_base;
+ out -> static_gate = p -> static_gate;
+ out -> notes = p -> notes;
+ }
+ return true;
+}
+
+u_int32_t dvd_detect_hlds_e7_type_for_identity (
+ const char *vendor,
+ const char *product_id,
+ const char *revision
+) {
+ const hlds_e7_profile_desc *profile =
+ hlds_find_e7_profile_for_identity (vendor, product_id, revision);
static const char *type1[] = {
"GCC-4160N", "GCC4160N", "GCC4160",
"GCC-4240N", "GCC4240N", "GCC4240"
"GDR3120L", "GDR-3120L"
};
- if (!dvd_is_hlds_drive (dvd))
+ if (!vendor || strcmp (vendor, "HL-DT-ST") != 0)
return 0;
if (profile)
return profile -> type;
- if (dvd_prod_has_any (dvd, type1, sizeof (type1) / sizeof (type1[0])))
+ if (hlds_product_has_any (product_id, type1, sizeof (type1) / sizeof (type1[0])))
return 1;
- if (dvd_prod_has_any (dvd, type2_1, sizeof (type2_1) / sizeof (type2_1[0])))
+ if (hlds_product_has_any (product_id, type2_1, sizeof (type2_1) / sizeof (type2_1[0])))
return 21;
- if (dvd_prod_has_any (dvd, type2_2, sizeof (type2_2) / sizeof (type2_2[0])))
+ if (hlds_product_has_any (product_id, type2_2, sizeof (type2_2) / sizeof (type2_2[0])))
return 22;
- if (dvd_prod_has_any (dvd, gdr8081n, sizeof (gdr8081n) / sizeof (gdr8081n[0])))
+ if (hlds_product_has_any (product_id, gdr8081n, sizeof (gdr8081n) / sizeof (gdr8081n[0])))
return 81;
- if (dvd_prod_has_any (dvd, type3, sizeof (type3) / sizeof (type3[0])))
+ if (hlds_product_has_any (product_id, type3, sizeof (type3) / sizeof (type3[0])))
return 3;
- if (dvd_is_hlds_gdr8050l_drive (dvd))
+ if (hlds_product_has (product_id, "GDR8050L") || hlds_product_has (product_id, "GDR-8050L"))
return 44;
- if (dvd_prod_has_any (dvd, type4, sizeof (type4) / sizeof (type4[0])))
+ if (hlds_product_has_any (product_id, type4, sizeof (type4) / sizeof (type4[0])))
return 4;
/* DIC labels GSA-4163B as an Xbox swap candidate, not a normal 0xE7
* Nintendo-disc cache dump profile, so keep it out of the profile layer. */
return 0;
}
+static u_int32_t dvd_hlds_e7_detect_type (dvd_drive *dvd) {
+ if (!dvd)
+ return 0;
+ return dvd_detect_hlds_e7_type_for_identity (
+ dvd -> vendor,
+ dvd -> prod_id,
+ dvd -> prod_rev
+ );
+}
+
static bool dvd_is_hlds_gc_wii_drive (dvd_drive *dvd) {
return dvd_hlds_e7_detect_type (dvd) != 0;
}