mirror of
https://github.com/GerbilSoft/rvthtool.git
synced 2025-06-19 03:55:37 -04:00
[rvthtool] Split the 'list-banks' and 'extract' commands into separate files.
This commit is contained in:
parent
4f4ec894ee
commit
04ef2623c2
@ -1,8 +1,16 @@
|
|||||||
PROJECT(rvthtool)
|
PROJECT(rvthtool)
|
||||||
|
|
||||||
# Sources and headers.
|
# Sources.
|
||||||
SET(rvthtool_SRCS main.c)
|
SET(rvthtool_SRCS
|
||||||
SET(rvthtool_H)
|
main.c
|
||||||
|
list-banks.c
|
||||||
|
extract.c
|
||||||
|
)
|
||||||
|
# Headers.
|
||||||
|
SET(rvthtool_H
|
||||||
|
list-banks.h
|
||||||
|
extract.h
|
||||||
|
)
|
||||||
|
|
||||||
#########################
|
#########################
|
||||||
# Build the executable. #
|
# Build the executable. #
|
||||||
|
103
src/rvthtool/extract.c
Normal file
103
src/rvthtool/extract.c
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* RVT-H Tool *
|
||||||
|
* extract.c: Extract a bank from an RVT-H disk image. *
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2018 by David Korth. *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify it *
|
||||||
|
* under the terms of the GNU General Public License as published by the *
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||||
|
* option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, but *
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "extract.h"
|
||||||
|
#include "librvth/rvth.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RVT-H progress callback.
|
||||||
|
* @param lba_processed LBAs processed.
|
||||||
|
* @param lba_total LBAs total.
|
||||||
|
* @return True to continue; false to abort.
|
||||||
|
*/
|
||||||
|
static bool progress_callback(uint32_t lba_processed, uint32_t lba_total)
|
||||||
|
{
|
||||||
|
#define MEGABYTE (1048576 / RVTH_BLOCK_SIZE)
|
||||||
|
printf("\r%4u MB / %4u MB processed...",
|
||||||
|
lba_processed / MEGABYTE,
|
||||||
|
lba_total / MEGABYTE);
|
||||||
|
fflush(stdout);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 'extract' command.
|
||||||
|
* @param rvth_filename RVT-H device or disk image filename.
|
||||||
|
* @param s_bank Bank number (as a string).
|
||||||
|
* @param gcm_filename Filename for the extracted GCM image.
|
||||||
|
* @return 0 on success; non-zero on error.
|
||||||
|
*/
|
||||||
|
int extract(const TCHAR *rvth_filename, const TCHAR *s_bank, const TCHAR *gcm_filename)
|
||||||
|
{
|
||||||
|
RvtH *rvth;
|
||||||
|
TCHAR *endptr;
|
||||||
|
unsigned int bank;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
// Open the disk image.
|
||||||
|
rvth = rvth_open(rvth_filename, &ret);
|
||||||
|
if (!rvth) {
|
||||||
|
fputs("*** ERROR opening RVT-H device '", stderr);
|
||||||
|
_fputts(rvth_filename, stderr);
|
||||||
|
fputs("': ", stderr);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "%s\n", strerror(-ret));
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "RVT-H error %d\n", ret);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the bank number.
|
||||||
|
bank = (unsigned int)_tcstoul(s_bank, &endptr, 10) - 1;
|
||||||
|
if (*endptr != 0 || bank > rvth_get_BankCount(rvth)) {
|
||||||
|
fputs("*** ERROR: Invalid bank number '", stderr);
|
||||||
|
_fputts(s_bank, stderr);
|
||||||
|
fputs("'.\n", stderr);
|
||||||
|
rvth_close(rvth);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Extracting Bank %u into '", bank+1);
|
||||||
|
_fputts(gcm_filename, stdout);
|
||||||
|
fputs("'...\n", stdout);
|
||||||
|
ret = rvth_extract(rvth, bank, gcm_filename, progress_callback);
|
||||||
|
printf("\n");
|
||||||
|
if (ret == 0) {
|
||||||
|
printf("Bank %u extracted to '", bank+1);
|
||||||
|
_fputts(gcm_filename, stdout);
|
||||||
|
fputs("' successfully.\n\n", stdout);
|
||||||
|
} else {
|
||||||
|
// TODO: Delete the gcm file?
|
||||||
|
fputs("*** ERROR: rvth_extract() failed: ", stderr);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "%s\n", strerror(-ret));
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "RVT-H error %d\n", ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rvth_close(rvth);
|
||||||
|
return 0;
|
||||||
|
}
|
43
src/rvthtool/extract.h
Normal file
43
src/rvthtool/extract.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* RVT-H Tool *
|
||||||
|
* extract.h: Extract a bank from an RVT-H disk image. *
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2018 by David Korth. *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify it *
|
||||||
|
* under the terms of the GNU General Public License as published by the *
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||||
|
* option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, but *
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __RVTHTOOL_RVTHTOOL_EXTRACT_H__
|
||||||
|
#define __RVTHTOOL_RVTHTOOL_EXTRACT_H__
|
||||||
|
|
||||||
|
#include "librvth/tcharx.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 'extract' command.
|
||||||
|
* @param rvth_filename RVT-H device or disk image filename.
|
||||||
|
* @param s_bank Bank number (as a string).
|
||||||
|
* @param gcm_filename Filename for the extracted GCM image.
|
||||||
|
* @return 0 on success; non-zero on error.
|
||||||
|
*/
|
||||||
|
int extract(const TCHAR *rvth_filename, const TCHAR *s_bank, const TCHAR *gcm_filename);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __RVTHTOOL_RVTHTOOL_EXTRACT_H__ */
|
188
src/rvthtool/list-banks.c
Normal file
188
src/rvthtool/list-banks.c
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* RVT-H Tool *
|
||||||
|
* list-banks.c: List banks in an RVT-H disk image. *
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2018 by David Korth. *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify it *
|
||||||
|
* under the terms of the GNU General Public License as published by the *
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||||
|
* option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, but *
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "list-banks.h"
|
||||||
|
#include "librvth/rvth.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print an RVT-H Bank Table.
|
||||||
|
* @param rvth [in] RVT-H disk image.
|
||||||
|
* @return 0 on success; non-zero on error.
|
||||||
|
*/
|
||||||
|
static int print_bank_table(const RvtH *rvth)
|
||||||
|
{
|
||||||
|
struct tm timestamp;
|
||||||
|
unsigned int i;
|
||||||
|
const unsigned int banks = rvth_get_BankCount(rvth);
|
||||||
|
|
||||||
|
// Print the entries.
|
||||||
|
for (i = 0; i < banks; i++) {
|
||||||
|
const char *s_type;
|
||||||
|
|
||||||
|
// TODO: Check the error code.
|
||||||
|
const RvtH_BankEntry *const entry = rvth_get_BankEntry(rvth, i, NULL);
|
||||||
|
if (!entry) {
|
||||||
|
printf("Bank %u: Empty\n\n", i+1);
|
||||||
|
continue;
|
||||||
|
} else if (entry->type == RVTH_BankType_Wii_DL_Bank2) {
|
||||||
|
// Bank 2 for DL images.
|
||||||
|
// We don't need to print this.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (entry->type) {
|
||||||
|
case RVTH_BankType_Empty:
|
||||||
|
// NOTE: Should not happen...
|
||||||
|
s_type = "Empty";
|
||||||
|
break;
|
||||||
|
case RVTH_BankType_Unknown:
|
||||||
|
// TODO: Print the bank type magic?
|
||||||
|
s_type = "Unknown";
|
||||||
|
break;
|
||||||
|
case RVTH_BankType_GCN:
|
||||||
|
s_type = "GameCube";
|
||||||
|
break;
|
||||||
|
case RVTH_BankType_Wii_SL:
|
||||||
|
s_type = "Wii (Single-Layer)";
|
||||||
|
break;
|
||||||
|
case RVTH_BankType_Wii_DL:
|
||||||
|
// TODO: Invalid for Bank 8; need to skip the next bank.
|
||||||
|
s_type = "Wii (Dual-Layer)";
|
||||||
|
break;
|
||||||
|
case RVTH_BankType_Wii_DL_Bank2:
|
||||||
|
// NOTE: Should not happen...
|
||||||
|
s_type = "Wii (Dual-Layer) (Bank 2)";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
s_type = "Unknown";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Bank %u: %s%s\n", i+1, s_type, (entry->is_deleted ? " [DELETED]" : ""));
|
||||||
|
if (entry->type <= RVTH_BankType_Unknown ||
|
||||||
|
entry->type >= RVTH_BankType_MAX)
|
||||||
|
{
|
||||||
|
// Cannot display any information for this type.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the timestamp.
|
||||||
|
// TODO: Reentrant gmtime() if available.
|
||||||
|
if (entry->timestamp != -1) {
|
||||||
|
timestamp = *gmtime(&entry->timestamp);
|
||||||
|
printf("- Timestamp: %04d/%02d/%02d %02d:%02d:%02d\n",
|
||||||
|
timestamp.tm_year + 1900, timestamp.tm_mon + 1, timestamp.tm_mday,
|
||||||
|
timestamp.tm_hour, timestamp.tm_min, timestamp.tm_sec);
|
||||||
|
} else {
|
||||||
|
printf("- Timestamp: Unknown\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// LBAs.
|
||||||
|
printf("- LBA start: 0x%08X\n", entry->lba_start);
|
||||||
|
printf("- LBA length: 0x%08X\n", entry->lba_len);
|
||||||
|
|
||||||
|
// Game ID.
|
||||||
|
printf("- Game ID: %.6s\n", entry->id6);
|
||||||
|
|
||||||
|
// Game title.
|
||||||
|
// rvth_open() has already trimmed the title.
|
||||||
|
printf("- Title: %.64s\n", entry->game_title);
|
||||||
|
|
||||||
|
// Wii encryption status.
|
||||||
|
if (entry->type == RVTH_BankType_Wii_SL ||
|
||||||
|
entry->type == RVTH_BankType_Wii_DL)
|
||||||
|
{
|
||||||
|
const char *crypto_type;
|
||||||
|
const char *sig_type;
|
||||||
|
|
||||||
|
switch (entry->crypto_type) {
|
||||||
|
default:
|
||||||
|
case RVTH_CryptoType_Unknown:
|
||||||
|
crypto_type = "Unknown";
|
||||||
|
break;
|
||||||
|
case RVTH_CryptoType_None:
|
||||||
|
crypto_type = "None";
|
||||||
|
break;
|
||||||
|
case RVTH_CryptoType_Debug:
|
||||||
|
crypto_type = "Debug";
|
||||||
|
break;
|
||||||
|
case RVTH_CryptoType_Retail:
|
||||||
|
crypto_type = "Retail";
|
||||||
|
break;
|
||||||
|
case RVTH_CryptoType_Korean:
|
||||||
|
crypto_type = "Korean";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (entry->sig_type) {
|
||||||
|
default:
|
||||||
|
case RVTH_SigType_Unknown:
|
||||||
|
sig_type = "Unknown";
|
||||||
|
break;
|
||||||
|
case RVTH_SigType_Debug:
|
||||||
|
sig_type = "Debug";
|
||||||
|
break;
|
||||||
|
case RVTH_SigType_Retail:
|
||||||
|
sig_type = "Retail";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("- Encryption: %s\n", crypto_type);
|
||||||
|
printf("- Signature: %s\n", sig_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 'list-banks' command.
|
||||||
|
* @param rvth_filename RVT-H device or disk image filename.
|
||||||
|
* @return 0 on success; non-zero on error.
|
||||||
|
*/
|
||||||
|
int list_banks(const TCHAR *rvth_filename)
|
||||||
|
{
|
||||||
|
RvtH *rvth;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
// Open the disk image.
|
||||||
|
rvth = rvth_open(rvth_filename, &ret);
|
||||||
|
if (!rvth) {
|
||||||
|
fputs("*** ERROR opening RVT-H device '", stderr);
|
||||||
|
_fputts(rvth_filename, stderr);
|
||||||
|
fputs("': ", stderr);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "%s\n", strerror(-ret));
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "RVT-H error %d\n", ret);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the bank table.
|
||||||
|
printf("RVT-H Bank Table:\n\n");
|
||||||
|
print_bank_table(rvth);
|
||||||
|
rvth_close(rvth);
|
||||||
|
return 0;
|
||||||
|
}
|
41
src/rvthtool/list-banks.h
Normal file
41
src/rvthtool/list-banks.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* RVT-H Tool *
|
||||||
|
* list-banks.h: List banks in an RVT-H disk image. *
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2018 by David Korth. *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify it *
|
||||||
|
* under the terms of the GNU General Public License as published by the *
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||||
|
* option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, but *
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __RVTHTOOL_RVTHTOOL_LIST_BANKS_H__
|
||||||
|
#define __RVTHTOOL_RVTHTOOL_LIST_BANKS_H__
|
||||||
|
|
||||||
|
#include "librvth/tcharx.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 'list-banks' command.
|
||||||
|
* @param rvth_filename RVT-H device or disk image filename.
|
||||||
|
* @return 0 on success; non-zero on error.
|
||||||
|
*/
|
||||||
|
int list_banks(const TCHAR *rvth_filename);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __RVTHTOOL_RVTHTOOL_LIST_BANKS_H__ */
|
@ -20,8 +20,6 @@
|
|||||||
|
|
||||||
#include "config.version.h"
|
#include "config.version.h"
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -29,253 +27,15 @@
|
|||||||
#include "librvth/byteswap.h"
|
#include "librvth/byteswap.h"
|
||||||
#include "librvth/rvth.h"
|
#include "librvth/rvth.h"
|
||||||
|
|
||||||
|
#include "list-banks.h"
|
||||||
|
#include "extract.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# define CDECL __cdecl
|
# define CDECL __cdecl
|
||||||
#else
|
#else
|
||||||
# define CDECL
|
# define CDECL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* Print an RVT-H Bank Table.
|
|
||||||
* @param rvth [in] RVT-H disk image.
|
|
||||||
* @return 0 on success; non-zero on error.
|
|
||||||
*/
|
|
||||||
static int print_bank_table(const RvtH *rvth)
|
|
||||||
{
|
|
||||||
struct tm timestamp;
|
|
||||||
unsigned int i;
|
|
||||||
const unsigned int banks = rvth_get_BankCount(rvth);
|
|
||||||
|
|
||||||
// Print the entries.
|
|
||||||
for (i = 0; i < banks; i++) {
|
|
||||||
const char *s_type;
|
|
||||||
|
|
||||||
// TODO: Check the error code.
|
|
||||||
const RvtH_BankEntry *const entry = rvth_get_BankEntry(rvth, i, NULL);
|
|
||||||
if (!entry) {
|
|
||||||
printf("Bank %u: Empty\n\n", i+1);
|
|
||||||
continue;
|
|
||||||
} else if (entry->type == RVTH_BankType_Wii_DL_Bank2) {
|
|
||||||
// Bank 2 for DL images.
|
|
||||||
// We don't need to print this.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (entry->type) {
|
|
||||||
case RVTH_BankType_Empty:
|
|
||||||
// NOTE: Should not happen...
|
|
||||||
s_type = "Empty";
|
|
||||||
break;
|
|
||||||
case RVTH_BankType_Unknown:
|
|
||||||
// TODO: Print the bank type magic?
|
|
||||||
s_type = "Unknown";
|
|
||||||
break;
|
|
||||||
case RVTH_BankType_GCN:
|
|
||||||
s_type = "GameCube";
|
|
||||||
break;
|
|
||||||
case RVTH_BankType_Wii_SL:
|
|
||||||
s_type = "Wii (Single-Layer)";
|
|
||||||
break;
|
|
||||||
case RVTH_BankType_Wii_DL:
|
|
||||||
// TODO: Invalid for Bank 8; need to skip the next bank.
|
|
||||||
s_type = "Wii (Dual-Layer)";
|
|
||||||
break;
|
|
||||||
case RVTH_BankType_Wii_DL_Bank2:
|
|
||||||
// NOTE: Should not happen...
|
|
||||||
s_type = "Wii (Dual-Layer) (Bank 2)";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
s_type = "Unknown";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Bank %u: %s%s\n", i+1, s_type, (entry->is_deleted ? " [DELETED]" : ""));
|
|
||||||
if (entry->type <= RVTH_BankType_Unknown ||
|
|
||||||
entry->type >= RVTH_BankType_MAX)
|
|
||||||
{
|
|
||||||
// Cannot display any information for this type.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print the timestamp.
|
|
||||||
// TODO: Reentrant gmtime() if available.
|
|
||||||
if (entry->timestamp != -1) {
|
|
||||||
timestamp = *gmtime(&entry->timestamp);
|
|
||||||
printf("- Timestamp: %04d/%02d/%02d %02d:%02d:%02d\n",
|
|
||||||
timestamp.tm_year + 1900, timestamp.tm_mon + 1, timestamp.tm_mday,
|
|
||||||
timestamp.tm_hour, timestamp.tm_min, timestamp.tm_sec);
|
|
||||||
} else {
|
|
||||||
printf("- Timestamp: Unknown\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// LBAs.
|
|
||||||
printf("- LBA start: 0x%08X\n", entry->lba_start);
|
|
||||||
printf("- LBA length: 0x%08X\n", entry->lba_len);
|
|
||||||
|
|
||||||
// Game ID.
|
|
||||||
printf("- Game ID: %.6s\n", entry->id6);
|
|
||||||
|
|
||||||
// Game title.
|
|
||||||
// rvth_open() has already trimmed the title.
|
|
||||||
printf("- Title: %.64s\n", entry->game_title);
|
|
||||||
|
|
||||||
// Wii encryption status.
|
|
||||||
if (entry->type == RVTH_BankType_Wii_SL ||
|
|
||||||
entry->type == RVTH_BankType_Wii_DL)
|
|
||||||
{
|
|
||||||
const char *crypto_type;
|
|
||||||
const char *sig_type;
|
|
||||||
|
|
||||||
switch (entry->crypto_type) {
|
|
||||||
default:
|
|
||||||
case RVTH_CryptoType_Unknown:
|
|
||||||
crypto_type = "Unknown";
|
|
||||||
break;
|
|
||||||
case RVTH_CryptoType_None:
|
|
||||||
crypto_type = "None";
|
|
||||||
break;
|
|
||||||
case RVTH_CryptoType_Debug:
|
|
||||||
crypto_type = "Debug";
|
|
||||||
break;
|
|
||||||
case RVTH_CryptoType_Retail:
|
|
||||||
crypto_type = "Retail";
|
|
||||||
break;
|
|
||||||
case RVTH_CryptoType_Korean:
|
|
||||||
crypto_type = "Korean";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (entry->sig_type) {
|
|
||||||
default:
|
|
||||||
case RVTH_SigType_Unknown:
|
|
||||||
sig_type = "Unknown";
|
|
||||||
break;
|
|
||||||
case RVTH_SigType_Debug:
|
|
||||||
sig_type = "Debug";
|
|
||||||
break;
|
|
||||||
case RVTH_SigType_Retail:
|
|
||||||
sig_type = "Retail";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("- Encryption: %s\n", crypto_type);
|
|
||||||
printf("- Signature: %s\n", sig_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RVT-H progress callback.
|
|
||||||
* @param lba_processed LBAs processed.
|
|
||||||
* @param lba_total LBAs total.
|
|
||||||
* @return True to continue; false to abort.
|
|
||||||
*/
|
|
||||||
static bool progress_callback(uint32_t lba_processed, uint32_t lba_total)
|
|
||||||
{
|
|
||||||
#define MEGABYTE (1048576 / RVTH_BLOCK_SIZE)
|
|
||||||
printf("\r%4u MB / %4u MB processed...",
|
|
||||||
lba_processed / MEGABYTE,
|
|
||||||
lba_total / MEGABYTE);
|
|
||||||
fflush(stdout);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 'list-banks' command.
|
|
||||||
* @param rvth_filename RVT-H device or disk image filename.
|
|
||||||
* @return 0 on success; non-zero on error.
|
|
||||||
*/
|
|
||||||
static int list_banks(const TCHAR *rvth_filename)
|
|
||||||
{
|
|
||||||
RvtH *rvth;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
// Open the disk image.
|
|
||||||
rvth = rvth_open(rvth_filename, &ret);
|
|
||||||
if (!rvth) {
|
|
||||||
fputs("*** ERROR opening RVT-H device '", stderr);
|
|
||||||
_fputts(rvth_filename, stderr);
|
|
||||||
fputs("': ", stderr);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "%s\n", strerror(-ret));
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "RVT-H error %d\n", ret);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print the bank table.
|
|
||||||
printf("RVT-H Bank Table:\n\n");
|
|
||||||
print_bank_table(rvth);
|
|
||||||
rvth_close(rvth);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 'extract' command.
|
|
||||||
* @param rvth_filename RVT-H device or disk image filename.
|
|
||||||
* @param s_bank Bank number (as a string).
|
|
||||||
* @param gcm_filename Filename for the extracted GCM image.
|
|
||||||
* @return 0 on success; non-zero on error.
|
|
||||||
*/
|
|
||||||
static int extract(const TCHAR *rvth_filename, const TCHAR *s_bank, const TCHAR *gcm_filename)
|
|
||||||
{
|
|
||||||
RvtH *rvth;
|
|
||||||
TCHAR *endptr;
|
|
||||||
unsigned int bank;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
// Open the disk image.
|
|
||||||
rvth = rvth_open(rvth_filename, &ret);
|
|
||||||
if (!rvth) {
|
|
||||||
fputs("*** ERROR opening RVT-H device '", stderr);
|
|
||||||
_fputts(rvth_filename, stderr);
|
|
||||||
fputs("': ", stderr);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "%s\n", strerror(-ret));
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "RVT-H error %d\n", ret);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate the bank number.
|
|
||||||
bank = (unsigned int)_tcstoul(s_bank, &endptr, 10) - 1;
|
|
||||||
if (*endptr != 0 || bank > rvth_get_BankCount(rvth)) {
|
|
||||||
fputs("*** ERROR: Invalid bank number '", stderr);
|
|
||||||
_fputts(s_bank, stderr);
|
|
||||||
fputs("'.\n", stderr);
|
|
||||||
rvth_close(rvth);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Extracting Bank %u into '", bank+1);
|
|
||||||
_fputts(gcm_filename, stdout);
|
|
||||||
fputs("'...\n", stdout);
|
|
||||||
ret = rvth_extract(rvth, bank, gcm_filename, progress_callback);
|
|
||||||
printf("\n");
|
|
||||||
if (ret == 0) {
|
|
||||||
printf("Bank %u extracted to '", bank+1);
|
|
||||||
_fputts(gcm_filename, stdout);
|
|
||||||
fputs("' successfully.\n\n", stdout);
|
|
||||||
} else {
|
|
||||||
// TODO: Delete the gcm file?
|
|
||||||
fputs("*** ERROR: rvth_extract() failed: ", stderr);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "%s\n", strerror(-ret));
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "RVT-H error %d\n", ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rvth_close(rvth);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CDECL _tmain(int argc, TCHAR *argv[])
|
int CDECL _tmain(int argc, TCHAR *argv[])
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
Loading…
Reference in New Issue
Block a user