]> FriiDump Source - friidump.git/blobdiff - libfriidump/dumper.c
FriiDump 0.5.3.15: close XGD1 geometry and lead-in capture
[friidump.git] / libfriidump / dumper.c
index 23d99be9ce760361451644f39ceddc3fd1a3b7f6..52795358a73672c06b41832b54d2be56a0a88dee 100644 (file)
@@ -54,6 +54,7 @@ struct dumper_s {
        multihash hash_raw;
        multihash hash_iso;
        multihash hash_xiso;
+       xbox_ref_dump_result xbox_ref_result;
        
        progress_func progress;
        void *progress_data;
@@ -320,6 +321,10 @@ static void xbox_write_redump_metadata (dumper *dmp, xbox_redump_metadata *meta)
        fprintf (json, "    \"pregame_padding_sector_count\": %u,\n", XBOX_XGD1_GAME_OUTPUT_START_LBA - XBOX_XGD1_VIDEO_L0_SECTORS);
        fprintf (json, "    \"game_output_start_lba\": %u,\n", XBOX_XGD1_GAME_OUTPUT_START_LBA);
        fprintf (json, "    \"game_leadin_sector_count\": %u,\n", XBOX_XISO_LEADIN_SECTORS);
+       fprintf (json, "    \"game_leadin_unlocked_source_start_lba\": %u,\n",
+               (meta -> game_source_lba >= XBOX_XISO_LEADIN_SECTORS) ?
+               meta -> game_source_lba - XBOX_XISO_LEADIN_SECTORS : 0);
+       fprintf (json, "    \"game_leadin_source_policy\": \"drive_read10_with_per_sector_zero_fallback\",\n");
        fprintf (json, "    \"game_unlocked_source_start_lba\": %u,\n", meta -> game_source_lba);
        fprintf (json, "    \"game_unlocked_source_sector_count\": %u,\n", meta -> game_source_sectors);
        fprintf (json, "    \"postgame_padding_start_lba\": %u,\n", XBOX_XGD1_GAME_OUTPUT_START_LBA + XBOX_XGD1_UNLOCKED_GAME_VIEW_SECTORS);
@@ -338,8 +343,13 @@ static void xbox_write_redump_metadata (dumper *dmp, xbox_redump_metadata *meta)
        fprintf (json, "  },\n");
        fprintf (json, "  \"lead_in_capture\": {\n");
        fprintf (json, "    \"game_leadin_attempted\": true,\n");
+       fprintf (json, "    \"unlocked_source_start_lba\": %u,\n",
+               (meta -> game_source_lba >= XBOX_XISO_LEADIN_SECTORS) ?
+               meta -> game_source_lba - XBOX_XISO_LEADIN_SECTORS : 0);
+       fprintf (json, "    \"sector_count\": %u,\n", XBOX_XISO_LEADIN_SECTORS);
        fprintf (json, "    \"readable_sectors\": %u,\n", meta -> game_leadin_read_sectors);
-       fprintf (json, "    \"zero_filled_sectors\": %u\n", meta -> game_leadin_zero_sectors);
+       fprintf (json, "    \"zero_filled_sectors\": %u,\n", meta -> game_leadin_zero_sectors);
+       fprintf (json, "    \"physical_geometry_evidence\": \"friidump_0.5.3.13_cache_aligned_raw_id_probe\"\n");
        fprintf (json, "  },\n");
        fprintf (json, "  \"dvd_structures\": {\n");
        fprintf (json, "    \"pfi\": "); if (pfi_leaf) xbox_json_string (json, pfi_leaf); else fprintf (json, "null"); fprintf (json, ",\n");
@@ -347,7 +357,8 @@ static void xbox_write_redump_metadata (dumper *dmp, xbox_redump_metadata *meta)
        fprintf (json, "  },\n");
        fprintf (json, "  \"notes\": [\n");
        fprintf (json, "    \"PFI and DMI are stored as separate binary READ DVD STRUCTURE captures because they are not READ(10) user-data sectors.\",\n");
-       fprintf (json, "    \"Pregame and postgame padding are zero-filled unless a future workflow proves readable source sectors for those ranges.\"\n");
+       fprintf (json, "    \"The 32-sector game lead-in is captured from unlocked source LBA 0..31; only unreadable lead-in sectors use zero-fill fallback.\",\n");
+       fprintf (json, "    \"Pregame and postgame padding retain zero-filled placeholder content; their physical locations are resolved but their inaccessible bytes are not.\"\n");
        fprintf (json, "  ]\n");
        fprintf (json, "}\n");
        fclose (json);
@@ -936,7 +947,7 @@ static int dumper_dump_xbox_redump_iso (dumper *dmp, u_int32_t *current_sector)
                if (current_sector)
                        *current_sector = 0;
                xbox_ref_log_fprintf (stderr, "[XBOX] Dispatching GDR-8050L -i directly to copied original dumper code using FriiDump's existing drive HANDLE.\n");
-               ref_status = xbox_ref_gdr8050l_dump_with_handle (disc_get_native_handle (dmp -> dsk), disc_get_device (dmp -> dsk), dmp -> outfile_iso, '1');
+               ref_status = xbox_ref_gdr8050l_dump_with_handle (disc_get_native_handle (dmp -> dsk), disc_get_device (dmp -> dsk), dmp -> outfile_iso, '1', &(dmp -> xbox_ref_result));
                return ref_status == 0;
        }
 #endif
@@ -1063,21 +1074,19 @@ static int dumper_dump_xbox_redump_iso (dumper *dmp, u_int32_t *current_sector)
        if (game_source_lba != XBOX_XISO_STANDARD_GAME_LBA && disc_is_xbox_challenge_drive (dmp -> dsk))
                warning ("Xbox XDVDFS was detected at LBA %u, not the expected GDR-8050L game-view LBA 32", game_source_lba);
 
-       if (disc_is_xbox_challenge_drive (dmp -> dsk)) {
-               /* Match the original GDR-8050L dumper's option-1 redump path: the
-                * 32-sector XISO/game lead-in area is synthetic zero-fill, and the real
-                * XDVDFS data begins at unlocked source LBA 32. */
-               xbox_ref_log_fprintf (stderr, "[XBOX] Writing 32-sector game lead-in as zero-fill for GDR-8050L redump flow.\n");
-               meta.game_leadin_zero_sectors += XBOX_XISO_LEADIN_SECTORS;
-               if (current_sector) *current_sector = XBOX_XGD1_GAME_OUTPUT_START_LBA;
-               if (!xbox_write_zero_iso_range (dmp, XBOX_XISO_LEADIN_SECTORS, XBOX_XGD1_GAME_OUTPUT_START_LBA, meta.output_sectors, "GAME-XISO-LEADIN"))
-                       goto cleanup;
-       } else {
-               if (!xbox_write_leadin_iso_range (dmp,
-                               (game_source_lba >= XBOX_XISO_LEADIN_SECTORS) ? game_source_lba - XBOX_XISO_LEADIN_SECTORS : 0,
-                               XBOX_XGD1_GAME_OUTPUT_START_LBA, meta.output_sectors, &meta, "redump game", true, current_sector))
-                       goto cleanup;
-       }
+       /* FriiDump 0.5.3.13 cache-aligned raw-ID validation proved that the
+        * unlocked GDR-8050L view exposes source LBA 0..31 as the physical
+        * game-region lead-in immediately preceding the XDVDFS header at LBA 32.
+        * Read those sectors from the drive; retain the existing per-sector
+        * zero-fill fallback only for genuinely unreadable sectors. */
+       xbox_ref_log_fprintf (stderr,
+               "[XBOX] Capturing 32-sector game lead-in from unlocked source LBA %u..%u.\n",
+               (game_source_lba >= XBOX_XISO_LEADIN_SECTORS) ? game_source_lba - XBOX_XISO_LEADIN_SECTORS : 0,
+               (game_source_lba >= XBOX_XISO_LEADIN_SECTORS) ? game_source_lba - 1 : XBOX_XISO_LEADIN_SECTORS - 1);
+       if (!xbox_write_leadin_iso_range (dmp,
+                       (game_source_lba >= XBOX_XISO_LEADIN_SECTORS) ? game_source_lba - XBOX_XISO_LEADIN_SECTORS : 0,
+                       XBOX_XGD1_GAME_OUTPUT_START_LBA, meta.output_sectors, &meta, "redump game", true, current_sector))
+               goto cleanup;
 
        if (!xbox_dump_read10_iso_range (dmp, game_source_lba, XBOX_XGD1_GAME_SOURCE_SECTORS,
                        XBOX_XGD1_GAME_OUTPUT_START_LBA + XBOX_XISO_LEADIN_SECTORS, meta.output_sectors, "GAME-XDVDFS", true, current_sector))
@@ -1258,7 +1267,7 @@ int dumper_dump_xiso (dumper *dmp, u_int32_t *current_sector) {
                if (current_sector)
                        *current_sector = 0;
                xbox_ref_log_fprintf (stderr, "[XBOX] Dispatching GDR-8050L -X directly to copied original dumper code using FriiDump's existing drive HANDLE.\n");
-               ref_status = xbox_ref_gdr8050l_dump_with_handle (disc_get_native_handle (dmp -> dsk), disc_get_device (dmp -> dsk), dmp -> outfile_xiso, '2');
+               ref_status = xbox_ref_gdr8050l_dump_with_handle (disc_get_native_handle (dmp -> dsk), disc_get_device (dmp -> dsk), dmp -> outfile_xiso, '2', &(dmp -> xbox_ref_result));
                return ref_status == 0;
        }
 #endif
@@ -1369,6 +1378,7 @@ dumper *dumper_new (disc *d) {
        dmp = (dumper *) malloc (sizeof (dumper));
        memset (dmp, 0, sizeof (dumper));
        dmp -> dsk = d;
+       xbox_ref_dump_result_init (&(dmp -> xbox_ref_result));
        dumper_set_hashing (dmp, true);
        dumper_set_flushing (dmp, true);
 
@@ -1487,3 +1497,11 @@ char *dumper_get_raw_sha2 (dumper *dmp) {
 char *dumper_get_xiso_sha2 (dumper *dmp) {
        return ((dmp -> hash_xiso).sha2_s);
 }
+
+
+bool dumper_get_xbox_reference_result (dumper *dmp, xbox_ref_dump_result *result) {
+       if (!dmp || !result || !(dmp -> xbox_ref_result).attempted)
+               return false;
+       *result = dmp -> xbox_ref_result;
+       return true;
+}