X-Git-Url: https://git.jtryba.com/browse/friidump.git/blobdiff_plain/8972240b0bb13e52c39c651cb66bac8e56b7eb57..65dc0f212cc166a0192080f0ffb9467459a5e201:/libfriidump/xbox_ref_bridge.c?ds=inline diff --git a/libfriidump/xbox_ref_bridge.c b/libfriidump/xbox_ref_bridge.c index a120c28..663805d 100644 --- a/libfriidump/xbox_ref_bridge.c +++ b/libfriidump/xbox_ref_bridge.c @@ -1,18 +1,40 @@ #include "xbox_ref_bridge.h" +#include + +void xbox_ref_dump_result_init(xbox_ref_dump_result *result) +{ + if (result) + memset(result, 0, sizeof(*result)); +} + #ifdef WIN32 #define WIN32_LEAN_AND_MEAN #define _WIN32_WINNT 0x0500 #include #include #include -#include #include "xbox_ref/utils.h" #include "xbox_ref/unlock.h" #include "xbox_ref/xbox_ref_log.h" #define printf xbox_ref_printf +#define XBOX_REF_LOCKED_VIDEO_VIEW_MAX_SECTORS 200000U + +static BOOL xbox_ref_capacity_is_game_view(uint32_t sectors) +{ + return sectors > XBOX_REF_LOCKED_VIDEO_VIEW_MAX_SECTORS; +} + +static uint32_t xbox_ref_refresh_ready_capacity(HANDLE hDevice) +{ + RefreshVolume(hDevice); + Sleep(2000); + EnsureDriveReady(hDevice, 30000); + return GetTotalSectors(hDevice); +} + static char xbox_ref_drive_letter_from_device(const char *device) { if (!device || !device[0]) return 0; @@ -21,7 +43,7 @@ static char xbox_ref_drive_letter_from_device(const char *device) return device[0]; } -static int xbox_ref_gdr8050l_dump_core(HANDLE hDevice, const char *device, const char *filename, char mode, BOOL ownsHandle) +static int xbox_ref_gdr8050l_dump_core(HANDLE hDevice, const char *device, const char *filename, char mode, BOOL ownsHandle, xbox_ref_dump_result *result) { char driveLetter; XboxGameInfo game; @@ -35,12 +57,19 @@ static int xbox_ref_gdr8050l_dump_core(HANDLE hDevice, const char *device, const BOOL volumeLocked = FALSE; BOOL ok = FALSE; + xbox_ref_dump_result_init(result); + if (result) { + result->attempted = 1; + result->mode = mode; + } + filenameOverride = (filename && filename[0]); if (mode != '1' && mode != '2') { xbox_ref_log_open_for_target(filename, 0); printf("[XBOX-REF] Fatal: unsupported Xbox reference dump mode '%c'.\n", mode); - xbox_ref_log_close(); + if (ownsHandle) + xbox_ref_log_close(); return 1; } @@ -48,7 +77,8 @@ static int xbox_ref_gdr8050l_dump_core(HANDLE hDevice, const char *device, const if (!driveLetter) { xbox_ref_log_open_for_target(filename, 0); printf("[XBOX-REF] Fatal: could not parse drive letter from device '%s'.\n", device ? device : "(null)"); - xbox_ref_log_close(); + if (ownsHandle) + xbox_ref_log_close(); return 1; } @@ -62,18 +92,47 @@ static int xbox_ref_gdr8050l_dump_core(HANDLE hDevice, const char *device, const goto cleanup; } - printf("Opening drive %c: for Atomic Handshake...\n", driveLetter); - EnsureDriveReady(hDevice, 30000); - UnlockDrive(hDevice); + { + uint32_t entrySectors; + uint32_t verifiedSectors; + BOOL preparedAfterHandshake = FALSE; - AutomateTrayCycle(hDevice); + printf("Opening drive %c: for state-aware Xbox handshake...\n", driveLetter); + if (!EnsureDriveReady(hDevice, 30000)) { + printf("[XBOX-REF] Fatal: drive did not become ready before Xbox state preparation.\n"); + goto cleanup; + } - printf("Re-applying 8050L Handshake after Media Change...\n"); - UnlockDrive(hDevice); + entrySectors = GetTotalSectors(hDevice); + printf("[XBOX-REF] Entry READ CAPACITY: %u sectors.\n", entrySectors); - RefreshVolume(hDevice); - Sleep(2000); - EnsureDriveReady(hDevice, 30000); + if (xbox_ref_capacity_is_game_view(entrySectors)) { + printf("[XBOX-REF] Entry state already exposes the Xbox game view; skipping the redundant initial handshake and tray cycle.\n"); + } else { + printf("[XBOX-REF] Entry state appears locked/video; attempting the full handshake directly without a media transition.\n"); + UnlockDrive(hDevice); + verifiedSectors = xbox_ref_refresh_ready_capacity(hDevice); + preparedAfterHandshake = TRUE; + printf("[XBOX-REF] Direct-handshake READ CAPACITY: %u sectors.\n", verifiedSectors); + + if (!xbox_ref_capacity_is_game_view(verifiedSectors)) { + printf("[XBOX-REF][WARN] Direct handshake did not expose the Xbox game view; performing one tray-cycle recovery and retry.\n"); + AutomateTrayCycle(hDevice); + printf("[XBOX-REF] Re-applying the full handshake after recovery media change.\n"); + UnlockDrive(hDevice); + verifiedSectors = xbox_ref_refresh_ready_capacity(hDevice); + printf("[XBOX-REF] Recovery-handshake READ CAPACITY: %u sectors.\n", verifiedSectors); + + if (!xbox_ref_capacity_is_game_view(verifiedSectors)) { + printf("[XBOX-REF] Fatal: Xbox game view was not established after direct and recovery handshakes.\n"); + goto cleanup; + } + } + } + + if (!preparedAfterHandshake) + xbox_ref_refresh_ready_capacity(hDevice); + } printf("Setting drive to maximum performance mode...\n"); SetDriveSpeedMax(hDevice); @@ -96,6 +155,17 @@ static int xbox_ref_gdr8050l_dump_core(HANDLE hDevice, const char *device, const isDualLayer = isDualLayerBool ? TRUE : FALSE; GetMediaID(hDevice, mediaId); + if (result) { + if (game.Success && game.TitleName[0]) { + strncpy(result->title, game.TitleName, sizeof(result->title) - 1); + result->title[sizeof(result->title) - 1] = '\0'; + } + if (mediaId[0]) { + strncpy(result->media_id, mediaId, sizeof(result->media_id) - 1); + result->media_id[sizeof(result->media_id) - 1] = '\0'; + } + } + if (game.Success) { char titleCopy[sizeof(game.TitleName)]; memset(titleCopy, 0, sizeof(titleCopy)); @@ -132,6 +202,11 @@ static int xbox_ref_gdr8050l_dump_core(HANDLE hDevice, const char *device, const } } + if (result && finalFilename[0]) { + strncpy(result->output_path, finalFilename, sizeof(result->output_path) - 1); + result->output_path[sizeof(result->output_path) - 1] = '\0'; + } + if (totalSectors != (uint32_t)(REDUMP_SECTORS)) { printf("[WARNING] Unlocked drive-reported sectors: %u does not match expected Xbox game-view sectors: %u\n", totalSectors, (uint32_t)(REDUMP_SECTORS)); printf("-Homebrew games may have different sizes.\n\n"); @@ -143,8 +218,7 @@ static int xbox_ref_gdr8050l_dump_core(HANDLE hDevice, const char *device, const } printf("Starting dump with copied DumpXboxGameDisc() mode %c...\n", mode); - DumpXboxGameDisc(hDevice, finalFilename, mode, totalSectors, isDualLayerBool, FALSE); - ok = TRUE; + ok = DumpXboxGameDisc(hDevice, finalFilename, mode, totalSectors, isDualLayerBool, FALSE, result); cleanup: if (volumeLocked) @@ -156,17 +230,23 @@ cleanup: } else { printf("[XBOX-REF] Returning to FriiDump; final STOP UNIT cleanup will use the same handle.\n"); } - printf("[XBOX-REF] Log file complete: %s\n", xbox_ref_log_path() ? xbox_ref_log_path() : "(unavailable)"); - xbox_ref_log_close(); + if (ownsHandle) { + printf("[XBOX-REF] Log file complete: %s\n", xbox_ref_log_path() ? xbox_ref_log_path() : "(unavailable)"); + xbox_ref_log_close(); + } else if (ok) { + printf("[XBOX-REF] Returning finalized output evidence to FriiDump's shared Redump verifier.\n"); + } else { + printf("[XBOX-REF] No completed output evidence is available for shared Redump verification.\n"); + } return ok ? 0 : 1; } -int xbox_ref_gdr8050l_dump_with_handle(void *native_handle, const char *device, const char *filename, char mode) +int xbox_ref_gdr8050l_dump_with_handle(void *native_handle, const char *device, const char *filename, char mode, xbox_ref_dump_result *result) { - return xbox_ref_gdr8050l_dump_core((HANDLE)native_handle, device, filename, mode, FALSE); + return xbox_ref_gdr8050l_dump_core((HANDLE)native_handle, device, filename, mode, FALSE, result); } -int xbox_ref_gdr8050l_dump(const char *device, const char *filename, char mode) +int xbox_ref_gdr8050l_dump(const char *device, const char *filename, char mode, xbox_ref_dump_result *result) { char driveLetter; HANDLE hDevice; @@ -187,16 +267,16 @@ int xbox_ref_gdr8050l_dump(const char *device, const char *filename, char mode) return 1; } - return xbox_ref_gdr8050l_dump_core(hDevice, device, filename, mode, TRUE); + return xbox_ref_gdr8050l_dump_core(hDevice, device, filename, mode, TRUE, result); } #else -int xbox_ref_gdr8050l_dump_with_handle(void *native_handle, const char *device, const char *filename, char mode) +int xbox_ref_gdr8050l_dump_with_handle(void *native_handle, const char *device, const char *filename, char mode, xbox_ref_dump_result *result) { - (void)native_handle; (void)device; (void)filename; (void)mode; return 1; + (void)native_handle; (void)device; (void)filename; (void)mode; xbox_ref_dump_result_init(result); return 1; } -int xbox_ref_gdr8050l_dump(const char *device, const char *filename, char mode) +int xbox_ref_gdr8050l_dump(const char *device, const char *filename, char mode, xbox_ref_dump_result *result) { - (void)device; (void)filename; (void)mode; return 1; + (void)device; (void)filename; (void)mode; xbox_ref_dump_result_init(result); return 1; } #endif