Compare commits

...

6 Commits

Author SHA1 Message Date
GaryOderNichts dfce0c4601 Update Dockerfile and workflow 2024-04-02 17:12:49 +02:00
GaryOderNichts 0d19b3dca7 Bump version to 2.0 2024-04-02 16:49:57 +02:00
GaryOderNichts 720ed1bb30 Add DRC/DRH information 2024-04-02 16:49:57 +02:00
David Korth 6d5b19a8a6 SubmitScreen.cpp: Zero an unused OTP area before hashing.
This should normally be zero anyway, but zero it again just in case.
2023-07-05 10:30:43 +02:00
David Korth a6efca8a74 SubmitScreen.cpp: Mention IDs; consolidate model and serial number to one line. 2023-07-05 10:30:33 +02:00
GaryOderNichts 0143b2e867 Update for latest libraries 2023-04-17 22:40:54 +02:00
11 changed files with 217 additions and 45 deletions

View File

@ -4,13 +4,13 @@ on: [push, pull_request]
jobs:
build-binary:
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Build binary
run: |
docker run --rm -v ${PWD}:/project garyodernichts/wiiuident_builder make
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: WiiUIdent
path: |

View File

@ -1,32 +1,17 @@
FROM ghcr.io/wiiu-env/devkitppc:20230326
FROM ghcr.io/wiiu-env/devkitppc:20231112
COPY --from=ghcr.io/wiiu-env/libmocha:20220903 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/libmocha:20231127 /artifacts $DEVKITPRO
# build and install latest wut
WORKDIR /
# Build latest wut
RUN \
mkdir wut && \
cd wut && \
git init . && \
git remote add origin https://github.com/devkitPro/wut.git && \
git fetch --depth 1 origin 451a1828f7646053b59ebacd813135e0300c67e8 && \
git fetch --depth 1 origin 682f8eb48a79796e653eb711c001ba47355f351c && \
git checkout FETCH_HEAD
WORKDIR /wut
RUN make -j$(nproc)
RUN make install
# build and install latest sdl
WORKDIR /
RUN \
mkdir SDL && \
cd SDL && \
git init . && \
git remote add origin https://github.com/GaryOderNichts/SDL.git && \
git fetch --depth 1 origin 687746c8c9514b5d48d5f9665a1d5fa36c5e5547 && \
git checkout FETCH_HEAD
WORKDIR /SDL
RUN /opt/devkitpro/portlibs/wiiu/bin/powerpc-eabi-cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$DEVKITPRO/portlibs/wiiu
RUN cmake --build build
RUN cmake --install build
WORKDIR /project

View File

@ -16,7 +16,7 @@ TOPDIR ?= $(CURDIR)
APP_NAME := WiiUIdent
APP_SHORTNAME := WiiUIdent
APP_AUTHOR := GaryOderNichts
APP_VERSION := 1.1
APP_VERSION := 2.0
DATABASE_URL := wiiu.gerbilsoft.com
include $(DEVKITPRO)/wut/share/wut_rules
@ -56,7 +56,7 @@ CXXFLAGS := $(CFLAGS) -std=gnu++20
ASFLAGS := $(ARCH)
LDFLAGS = $(ARCH) $(RPXSPECS) -Wl,-Map,$(notdir $*.map)
LIBS := -lcurl -lmbedtls -lmbedcrypto -lmbedx509 -lSDL2 -lSDL2_ttf -lfreetype -lpng -lbz2 -lz -lmocha -lwut
LIBS := -lcurl -lmbedtls -lmbedcrypto -lmbedx509 -lSDL2 -lSDL2_ttf -lfreetype -lharfbuzz -lfreetype -lpng -lbz2 -lz -lmocha -lwut
#-------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level

View File

@ -32,6 +32,12 @@ WiiUIdent currently displays:
- Production Date (MLC only)
- Size
- CID/CSD
- DRC/DRH information
- Running Version
- Active Version
- Board Version
- Region
- Ext IDs
## System Database
WiiUIdent comes with an option to optionally upload system information to a database. This allows collecting various statistics about Wii U consoles.
@ -51,7 +57,8 @@ The database is publicly accessible but personally identifying information will
For building you need:
- [wut](https://github.com/devkitPro/wut)
- [libmocha](https://github.com/wiiu-env/libmocha)
- [SDL2 v2.22](https://github.com/GaryOderNichts/SDL/tree/wiiu-sdl2-2.0.22)
- [wiiu-sdl2](https://github.com/GaryOderNichts/SDL/tree/wiiu-sdl2-2.26)
- wiiu-sdl2_ttf
- wiiu-curl
- wiiu-mbedtls

View File

@ -106,9 +106,6 @@ bool Init()
return false;
}
// FIXME Probably SDL bug? If we don't draw before FC_LoadFont_RW our viewport shrinks
Gfx::DrawRectFilled(0, 0, 0, 0, COLOR_BLACK);
if (!FC_LoadFont_RW(monospaceFont, renderer, SDL_RWFromMem((void*)ter_u32b_bdf, ter_u32b_bdf_size), 1, 32, Gfx::COLOR_BLACK, TTF_STYLE_NORMAL)) {
FC_FreeFont(monospaceFont);
return false;

View File

@ -0,0 +1,170 @@
#include "DRXInfoScreen.hpp"
#include "Utils.hpp"
#include <span>
#include <nsysccr/cdc.h>
#include <nsysccr/cfg.h>
namespace {
bool GetEepromValue(uint32_t offset, std::span<uint8_t> value)
{
uint8_t data[value.size() + 2];
if (CCRCFGGetCachedEeprom(0, offset, data, value.size() + 2) != 0) {
return false;
}
uint16_t crc = (uint16_t) data[value.size() + 1] << 8 | data[value.size()];
if (CCRCDCCalcCRC16(data, value.size()) != crc) {
return false;
}
std::copy(data, data + value.size(), value.begin());
return true;
}
// from gamepad firmare @0x000b2990
const char* kBoardMainVersions[] = {
"DK1",
"DK1 / EP / DK2",
"DP1",
"DP2",
"DK3",
"DK4",
"PreDP3 / DP3",
"DK5",
"DP4",
"DKMP",
"DP5",
"MASS",
"DKMP2",
"DRC-I",
"DKTVMP",
};
// from gamepad firmare @0x000b29cc
const char* kBoardSubVersions[] = {
"DK1 / EP / DK2",
"DP1 / DK3",
"DK4",
"DP3",
"DK5",
"DP4",
"DKMP",
"DP5",
"MASS",
"DKMP2",
"DRC-I",
"DKTVMP"
};
// from gamepad firmare @0x000b29fc
const char* kRegionStrings[] = {
"JAPAN",
"AMERICA",
"EUROPE",
"CHINA",
"SOUTH KOREA",
"TAIWAN",
"AUSTRALIA",
};
}
DRXInfoScreen::DRXInfoScreen()
{
CCRCDCSoftwareVersion softwareVersion;
if (CCRCDCSoftwareGetVersion(CCR_CDC_DESTINATION_DRC0, &softwareVersion) == 0) {
uint32_t v = softwareVersion.runningVersion;
mDRCList.push_back({"Running Version:", Utils::sprintf("%d.%d.%d", v >> 24 & 0xff, v >> 16 & 0xff, v & 0xffff)});
mDRCList.push_back({"", {Utils::sprintf("(0x%08x)", v), true}});
v = softwareVersion.activeVersion;
mDRCList.push_back({"Active Version:", Utils::sprintf("%d.%d.%d", v >> 24 & 0xff, v >> 16 & 0xff, v & 0xffff)});
mDRCList.push_back({"", {Utils::sprintf("(0x%08x)", v), true}});
} else {
mDRCList.push_back({"CCRCDCSoftwareGetVersion failed", ""});
}
uint8_t boardInfo;
if (GetEepromValue(0x100, std::span(std::addressof(boardInfo), 1))) {
uint8_t mainVersion = boardInfo & 0xf;
uint8_t subVersion = boardInfo >> 4;
mDRCList.push_back({"Board Version:", Utils::sprintf("%d.%d (0x%02x)", mainVersion, subVersion, boardInfo)});
mDRCList.push_back({"", Utils::sprintf("(%s / %s)",
mainVersion < 0xf ? kBoardMainVersions[mainVersion] : "UNKNOWN",
subVersion < 0xc ? kBoardSubVersions[subVersion] : "UNKNOWN")});
} else {
mDRCList.push_back({"GetEepromValue failed", ""});
}
uint8_t region;
if (GetEepromValue(0x103, std::span(std::addressof(region), 1))) {
mDRCList.push_back({"Region:", Utils::sprintf("%s (0x%02x)",
region < 0x7 ? kRegionStrings[region] : "UNKNOWN", region)});
} else {
mDRCList.push_back({"GetRegion failed", ""});
}
if (CCRCDCSoftwareGetVersion(CCR_CDC_DESTINATION_DRH, &softwareVersion) == 0) {
uint32_t v = softwareVersion.runningVersion;
mDRHList.push_back({"Running Version:", Utils::sprintf("%d.%d.%d", v >> 24 & 0xff, v >> 16 & 0xff, v & 0xffff)});
mDRHList.push_back({"", {Utils::sprintf("(0x%08x)", v), true}});
v = softwareVersion.activeVersion;
mDRHList.push_back({"Active Version:", Utils::sprintf("%d.%d.%d", v >> 24 & 0xff, v >> 16 & 0xff, v & 0xffff)});
mDRHList.push_back({"", {Utils::sprintf("(0x%08x)", v), true}});
} else {
mDRHList.push_back({"CCRCDCSoftwareGetVersion failed", ""});
}
uint32_t extId;
if (CCRCDCSoftwareGetExtId(CCR_CDC_DESTINATION_DRC0, CCR_CDC_EXT_LANGUAGE, &extId) == 0) {
mExtIdList.push_back({"Language:", {Utils::sprintf("0x%08x", extId), true}});
mExtIdList.push_back({"", Utils::sprintf("(version: %04d bank: %02d)", extId >> 8 & 0xffff, extId >> 24)});
} else {
mExtIdList.push_back({"CCRCDCSoftwareGetExtId(CCR_CDC_EXT_LANGUAGE) failed", ""});
}
if (CCRCDCSoftwareGetExtId(CCR_CDC_DESTINATION_DRC0, CCR_CDC_EXT_RC_DATABASE, &extId) == 0) {
mExtIdList.push_back({"RC Database:", {Utils::sprintf("0x%08x", extId), true}});
} else {
mExtIdList.push_back({"CCRCDCSoftwareGetExtId(CCR_CDC_EXT_RC_DATABASE) failed", ""});
}
for (int i = CCR_CDC_EXT_UNK2; i <= CCR_CDC_EXT_UNK4; i++) {
if (CCRCDCSoftwareGetExtId(CCR_CDC_DESTINATION_DRC0, (CCRCDCExt) i, &extId) == 0) {
mExtIdList.push_back({Utils::sprintf("ID %d:", i), {Utils::sprintf("0x%08x", extId), true}});
} else {
mExtIdList.push_back({Utils::sprintf("CCRCDCSoftwareGetExtId(%d) failed", i), ""});
}
}
}
DRXInfoScreen::~DRXInfoScreen()
{
}
void DRXInfoScreen::Draw()
{
DrawTopBar("DRC/DRH Information");
int yOff = 128;
yOff = DrawHeader(32, yOff, 896, 0xf11b, "DRC Info");
yOff = DrawList(32, yOff, 896, mDRCList);
yOff = DrawHeader(32, yOff, 896, 0xf0cb, "DRC Ext IDs");
yOff = DrawList(32, yOff, 896, mExtIdList);
yOff = 128;
yOff = DrawHeader(992, yOff, 896, 0xf2db, "DRH Info");
yOff = DrawList(992, yOff, 896, mDRHList);
DrawBottomBar(nullptr, "\ue044 Exit", "\ue001 Back");
}
bool DRXInfoScreen::Update(VPADStatus& input)
{
if (input.trigger & VPAD_BUTTON_B) {
return false;
}
return true;
}

View File

@ -0,0 +1,20 @@
#pragma once
#include "Screen.hpp"
class DRXInfoScreen : public Screen
{
public:
DRXInfoScreen();
virtual ~DRXInfoScreen();
void Draw();
bool Update(VPADStatus& input);
private:
ScreenList mDRCList;
ScreenList mExtIdList;
ScreenList mDRHList;
};

View File

@ -8,20 +8,6 @@
#include <coreinit/mcp.h>
#include <coreinit/bsp.h>
extern "C"
{
typedef struct {
uint32_t major;
uint32_t minor;
uint32_t patch;
char region;
} MCPSystemVersion;
MCPError MCP_GetSystemVersion(int32_t handle, MCPSystemVersion* systemVersion);
}
namespace
{

View File

@ -1,6 +1,7 @@
#include "MenuScreen.hpp"
#include "Gfx.hpp"
#include "AboutScreen.hpp"
#include "DRXInfoScreen.hpp"
#include "GeneralScreen.hpp"
#include "StorageScreen.hpp"
#include "SubmitScreen.hpp"
@ -11,6 +12,7 @@ MenuScreen::MenuScreen()
: entries({
{ MENU_ID_GENERAL, { 0xf085, "General System Information" }},
{ MENU_ID_STORAGE, { 0xf7c2, "Storage Information" }},
{ MENU_ID_DRX, { 0xf11b, "DRC/DRH Information" }},
{ MENU_ID_SUBMIT, { 0xf0ee, "Submit System Information" }},
// { MENU_ID_TITLE, { 0xf022, "Title Information" }},
{ MENU_ID_ABOUT, { 0xf05a, "About WiiUIdent" }},
@ -76,6 +78,9 @@ bool MenuScreen::Update(VPADStatus& input)
case MENU_ID_STORAGE:
subscreen = std::make_unique<StorageScreen>();
break;
case MENU_ID_DRX:
subscreen = std::make_unique<DRXInfoScreen>();
break;
case MENU_ID_SUBMIT:
subscreen = std::make_unique<SubmitScreen>();
break;

View File

@ -20,6 +20,7 @@ private:
enum MenuID {
MENU_ID_GENERAL,
MENU_ID_STORAGE,
MENU_ID_DRX,
MENU_ID_SUBMIT,
MENU_ID_ABOUT,

View File

@ -81,14 +81,14 @@ const char desc[] =
"but personally identifying information will be kept confidential.\n"
"\n"
"Information that will be submitted:\n"
"\uff65 System model\n"
"\uff65 System serial number (excluding the last 3 digits)\n"
"\uff65 System model and serial number (excluding the last 3 digits)\n"
"\uff65 Manufacturing date\n"
"\uff65 Region information\n"
"\uff65 Security level (keyset), sataDevice, consoleType, BSP revision\n"
"\uff65 boardType, boardRevision, bootSource, ddr3Size, ddr3Speed, ddr3Vendor\n"
"\uff65 MLC manufacturer, revision, name, size, and CID\n"
"\uff65 Device certificate and SHA-256 hash of OTP (to prevent duplicates)\n"
"\uff64 MS, CA, NG, and NG key IDs\n"
"\n"
"Do you want to submit your console's system data?\n";
}
@ -174,7 +174,7 @@ size_t SubmitScreen::CurlWriteCallback(void* contents, size_t size, size_t nmemb
void SubmitScreen::SubmitSystemData()
{
const auto& otp = OTP::Get();
auto otp = OTP::Get();
const auto& seeprom = SEEPROM::Get();
WUT_ALIGNAS(0x40) MCPSysProdSettings sysProd{};
int32_t mcpHandle = MCP_Open();
@ -259,6 +259,7 @@ void SubmitScreen::SubmitSystemData()
// is fully contained within the MLC CID.
}
memset(&otp.miscBank, 0, 0x40);
if (Utils::SHA256(&otp, sizeof(otp), pd->otp_sha256, sizeof(pd->otp_sha256)) != 0) {
error = "Failed to hash otp data";
return;