A bunch of user-friendly things

This commit is contained in:
Bottersnike 2023-03-13 21:49:07 +00:00
parent aef9cb26cb
commit 38ccd51217
Signed by: Bottersnike
SSH Key Fingerprint: SHA256:3g0ghwd4dNX1k1RX8qazbiT+3RIYn/daeBevHZVCiU0
94 changed files with 3334 additions and 985 deletions

View File

@ -34,6 +34,7 @@ clean:
dist:
@-mkdir $(DIST_DIR) > NUL 2>&1
@-mkdir $(DIST_DIR)\util > NUL 2>&1
@-mkdir $(DIST_DIR)\system_dummy > NUL 2>&1
@-mkdir $(DIST_DIR)\Execute > NUL 2>&1
@-mkdir $(DIST_DIR)\Execute\Z > NUL 2>&1
@-mkdir $(DIST_DIR)\Execute\S > NUL 2>&1
@ -54,12 +55,16 @@ dist:
# @copy /Y "$(BUILD_DIR)/src/micetools/micepatch\micepatch.exe" "$(DIST_DIR)/util/micepatch.exe"
@copy /Y "$(BUILD_DIR)/src/micetools/util\micedump.exe" "$(DIST_DIR)/util/micedump.exe"
@copy /Y "$(BUILD_DIR)/src/micetools/util\micedump.pdb" "$(DIST_DIR)/util/micedump.pdb"
@copy /Y "$(BUILD_DIR)/src/micetools/util\micetinker.exe" "$(DIST_DIR)/util/micetinker.exe"
@copy /Y "$(BUILD_DIR)/src/micetools/util\micemonitor.exe" "$(DIST_DIR)/util/micemonitor.exe"
@copy /Y "$(BUILD_DIR)/src/micetools/util\exio_test.exe" "$(DIST_DIR)/util/exio_test.exe"
@copy /Y "$(BUILD_DIR)/src/micetools/util\dongleDecrypt.exe" "$(DIST_DIR)/util/dongleDecrypt.exe"
@copy /Y "$(BUILD_DIR)/src/micetools/util\testBin.exe" "$(DIST_DIR)/util/testBin.exe"
@copy /Y "$(BUILD_DIR)/src/micetools/system_dummy\dummymaster\dummymaster.exe" "$(DIST_DIR)/system_dummy/dummymaster.exe"
@copy /Y "$(BUILD_DIR)/src/micetools/system_dummy\dummyinstaller\dummyinstaller.exe" "$(DIST_DIR)/system_dummy/dummyinstaller.exe"
@copy /Y "src/micetools/miceboot\TrueCrypt.cmd" "$(DIST_DIR)/Execute/TrueCrypt.cmd"
@xcopy /E /H /C /R /Q /Y src\system "$(DIST_DIR)\system/*"

View File

@ -9,7 +9,7 @@ typedef struct {
uint32_t m_Gateway;
uint32_t m_PrimaryDns;
uint32_t m_SecondaryDns;
} AM_SYSDATA_NETWORK_IF;
} AM_SYSDATA_NETWORK_IF, *PAM_SYSDATA_NETWORK_IF;
typedef struct {
uint64_t m_TimeStamp;
@ -28,17 +28,17 @@ typedef struct {
uint8_t CreditRate;
uint8_t Cost[8];
uint8_t Rsv0F;
} AM_CREDIT_CONFIG;
} AM_CREDIT_CONFIG, *PAM_CREDIT_CONFIG;
typedef struct {
uint8_t Credit;
uint8_t Remain;
} AM_CREDIT_PDATA;
} AM_CREDIT_PDATA, *PAM_CREDIT_PDATA;
typedef struct {
AM_CREDIT_PDATA Player[4];
uint8_t Rsv08[8];
} AM_CREDIT_DATA;
} AM_CREDIT_DATA, *PAM_CREDIT_DATA;
typedef struct {
uint32_t CoinChute[4];
@ -46,7 +46,7 @@ typedef struct {
uint32_t CoinCredit;
uint32_t ServiceCredit;
uint32_t TotalCredit;
} AM_CREDIT_BOOKKEEPING;
} AM_CREDIT_BOOKKEEPING, *PAM_CREDIT_BOOKKEEPING;
typedef struct {
uint8_t m_month;
@ -61,7 +61,7 @@ typedef struct {
uint32_t m_Crc;
uint8_t Rsv04[4];
AM_SYSDATA_NETWORK_IF m_Eth;
} AM_SYSDATAwH_NETWORK;
} AM_SYSDATAwH_NETWORK, *PAM_SYSDATAwH_NETWORK;
typedef struct {
uint32_t m_Crc;
@ -70,14 +70,14 @@ typedef struct {
uint8_t m_Rental;
uint8_t Rsv0F;
char m_strSerialId[17];
} AM_SYSDATAwH_STATIC;
} AM_SYSDATAwH_STATIC, *PAM_SYSDATAwH_STATIC;
typedef struct {
uint32_t m_Crc;
uint8_t Rsv04[4];
AM_CREDIT_CONFIG m_Config;
uint8_t Rsv18[8];
} AM_SYSDATAwH_CREDIT;
} AM_SYSDATAwH_CREDIT, *PAM_SYSDATAwH_CREDIT;
typedef AM_SYSDATAwH_NETWORK AM_SYSDATAwH_NETWORK_ETH0;
typedef AM_SYSDATAwH_NETWORK AM_SYSDATAwH_NETWORK_ETH1;
@ -88,7 +88,7 @@ typedef struct {
char m_GameId[4];
uint8_t m_Region;
uint8_t Rsv0D[3];
} AM_SYSDATAwH_HISTORY;
} AM_SYSDATAwH_HISTORY, *PAM_SYSDATAwH_HISTORY;
typedef struct {
uint32_t m_Crc;
@ -97,7 +97,7 @@ typedef struct {
uint8_t m_LogNum;
uint8_t Rsv0a[22];
ERROR_LOG_BODY m_Body[15];
} AM_SYSDATAwH_ERROR_LOG;
} AM_SYSDATAwH_ERROR_LOG, *PAM_SYSDATAwH_ERROR_LOG;
typedef struct {
uint32_t m_Crc;
@ -105,7 +105,7 @@ typedef struct {
AM_CREDIT_DATA m_CreditData;
AM_CREDIT_BOOKKEEPING m_Bookkeeping;
uint8_t Rsv38[456];
} AM_SYSDATAwH_BACKUP;
} AM_SYSDATAwH_BACKUP, *PAM_SYSDATAwH_BACKUP;
typedef struct {
uint32_t m_Crc;
@ -115,7 +115,7 @@ typedef struct {
uint32_t m_Bias;
uint32_t m_ServerBias;
uint8_t Rsv20[480];
} AM_SYSDATAwH_TIMEZONE;
} AM_SYSDATAwH_TIMEZONE, *PAM_SYSDATAwH_TIMEZONE;
typedef struct {
uint32_t m_Crc;
@ -123,21 +123,21 @@ typedef struct {
uint32_t m_Caution;
uint32_t m_Peak;
uint8_t Rsv10[496];
} AM_SYSDATAwH_HM_PEAK;
} AM_SYSDATAwH_HM_PEAK, *PAM_SYSDATAwH_HM_PEAK;
typedef struct {
uint32_t m_Crc;
uint8_t Rsv04[4];
uint8_t m_MountSleepS;
uint8_t Rsv09[55];
} AM_SYSDATAwH_ALPB_DEV_CONFIG;
} AM_SYSDATAwH_ALPB_DEV_CONFIG, *PAM_SYSDATAwH_ALPB_DEV_CONFIG;
typedef struct {
uint32_t m_Crc;
uint32_t m_Uk1;
uint32_t m_Uk2;
uint32_t m_Uk3;
} AM_SYSDATAwH_ALPB_CARD_ID;
} AM_SYSDATAwH_ALPB_CARD_ID, *PAM_SYSDATAwH_ALPB_CARD_ID;
typedef struct {
uint32_t m_Crc;
@ -148,7 +148,7 @@ typedef struct {
uint32_t m_Uk5;
uint32_t m_Uk6;
uint32_t m_Uk7;
} AM_SYSDATAwH_ALPB_COMPUTER_NAME;
} AM_SYSDATAwH_ALPB_COMPUTER_NAME, *PAM_SYSDATAwH_ALPB_COMPUTER_NAME;
#pragma pack(pop)

View File

@ -119,7 +119,7 @@ unsigned char comio_next_req(com_device_t* com, comio_recv_head_t* head, BYTE* d
}
comdev_read(com, &one_byte, 1);
if (one_byte != COMIO_SYNC) {
log_error("com", "Garbage on JVS: %02x", one_byte);
log_error(plfComm, "Garbage on JVS: %02x", one_byte);
continue;
}
break;
@ -158,8 +158,43 @@ void comio_reply(com_device_t* com, comio_recv_head_t* req, BYTE status, BYTE le
comio_write(com, &one_byte, 1);
}
void com_device_thread(com_device_t* com, FnComDeviceThread* thread) {
BOOL attach_com_device(BYTE port, FnComDeviceThread* thread) {
if (port < 1 || port > NUM_COM_PORTS) {
log_error(plfComm, "Requested COM%hhu but that is out of range!", port);
return FALSE;
}
com_device_t* com = com_devices[port - 1];
if (com->thread != INVALID_HANDLE_VALUE) {
// No need to change what's assigned!
if (com->thread_worker == thread) return TRUE;
log_warning(plfComm, "COM%hhu is already attached!", port);
TerminateThread(com->thread, (DWORD)-1);
}
com->thread = CreateThread(NULL, 0, thread, com, 0, NULL);
com->thread_worker = thread;
return TRUE;
}
void detach_com_device(BYTE port) {
// If the port is out of range, there's guaranteeably nothing attached
if (port < 1 || port > NUM_COM_PORTS)
return;
com_device_t* com = com_devices[port - 1];
if (!com->thread) return;
TerminateThread(com->thread, (DWORD)-1);
com->thread = INVALID_HANDLE_VALUE;
}
void detach_all_com_devices(void) {
for (int i = 0; i < NUM_COM_PORTS; i++) {
if (com_devices[i]->thread != INVALID_HANDLE_VALUE) {
TerminateThread(com_devices[i]->thread, (DWORD)-1);
com_devices[i]->thread = INVALID_HANDLE_VALUE;
}
}
}
com_device_t* new_com_device(BYTE port) {
@ -189,8 +224,15 @@ com_device_t* new_com_device(BYTE port) {
ringbuf_purge(&com_device->in);
ringbuf_purge(&com_device->out);
com_device->event = CreateEventW(NULL, TRUE, FALSE, com_device->com->wName);
com_device->thread = INVALID_HANDLE_VALUE;
hook_file(file);
return com_device;
}
void init_com_devices(void) {
for (BYTE i = 0; i < NUM_COM_PORTS; i++) {
com_devices[i] = new_com_device(i + 1);
}
}

View File

@ -3,7 +3,12 @@
#include "hooks/com.h"
#include "hooks/files.h"
typedef struct com_device {
#define NUM_COM_PORTS 8
typedef struct com_device com_device_t;
typedef DWORD(WINAPI FnComDeviceThread)(com_device_t* com);
struct com_device {
com_hook_t* com;
file_hook_t* file;
@ -11,7 +16,9 @@ typedef struct com_device {
ring_buffer_t out;
HANDLE event;
HANDLE thread;
} com_device_t;
FnComDeviceThread* thread_worker;
};
com_device_t* com_devices[NUM_COM_PORTS];
typedef struct {
BYTE frame_length;
@ -36,8 +43,6 @@ typedef struct {
#define COMIO_STATUS_OK 0
#define COMIO_STATUS_NG 1
typedef DWORD(WINAPI FnComDeviceThread)(com_device_t* com);
short comdev_read_blocking(com_device_t* com, unsigned char* buffer, short bytes);
short comdev_read(com_device_t* com, unsigned char* buffer, short bytes);
bool comdev_write(com_device_t* com, const unsigned char* buffer, short bytes);
@ -50,5 +55,8 @@ void comio_write(com_device_t* com, BYTE* data, BYTE len);
unsigned char comio_next_req(com_device_t* com, comio_recv_head_t* head, BYTE* data);
void comio_reply(com_device_t* com, comio_recv_head_t* req, BYTE status, BYTE len, BYTE* data);
void com_device_thread(com_device_t* com, FnComDeviceThread* thread);
com_device_t* new_com_device(BYTE port);
com_device_t* new_com_device(BYTE port);
BOOL attach_com_device(BYTE port, FnComDeviceThread* thread);
void detach_com_device(BYTE port);
void detach_all_com_devices(void);
void init_com_devices(void);

View File

@ -24,5 +24,7 @@
#include "../lib/mice/mice.h"
#include "./util/_util.h"
void mice_got_game_id(char game_id[4]);
extern WCHAR exeName[MAX_PATH + 1];
extern DWORD imageOffset;

View File

@ -1,15 +1,73 @@
#include "_devices.h"
#include "smb_pca9535.h"
#include "smb_at24c64an.h"
#include "smb_ds28cn01.h"
#include "smb_ds2460.h"
#include "smb_ds28cn01.h"
#include "smb_pca9535.h"
typedef struct _device_list {
const char* m_Name;
FnComDeviceThread* m_Thread;
struct _device_list* m_Next;
} device_list_t;
device_list_t device_list = { .m_Next = NULL };
#define _start_device_n(n) \
if (strcmp(MiceConfig.devices.com##n, name) == 0) attach_com_device(n, thread)
inline void start_device(const char* name, FnComDeviceThread* thread) {
_start_device_n(1);
_start_device_n(2);
_start_device_n(3);
_start_device_n(4);
_start_device_n(5);
_start_device_n(6);
_start_device_n(7);
_start_device_n(8);
}
#define _stop_if_unregistered(n) \
if (MiceConfig.devices.com##n[0] == '\0') detach_com_device(n)
inline void stop_old_devices() {
_stop_if_unregistered(1);
_stop_if_unregistered(2);
_stop_if_unregistered(3);
_stop_if_unregistered(4);
_stop_if_unregistered(5);
_stop_if_unregistered(6);
_stop_if_unregistered(7);
_stop_if_unregistered(8);
}
void start_devices() {
stop_old_devices();
device_list_t* device = &device_list;
while (device->m_Next) {
device = device->m_Next;
start_device(device->m_Name, device->m_Thread);
}
}
void register_device(const char* name, FnComDeviceThread* thread) {
device_list_t* tail = &device_list;
while (tail->m_Next) tail = tail->m_Next;
device_list_t* us = tail->m_Next = malloc(sizeof(device_list_t));
us->m_Name = name;
us->m_Thread = thread;
us->m_Next = NULL;
}
void install_devices() {
install_led_bd();
install_touch_bd();
install_aime_bd();
start_devices();
smbus_install(/* 0x20 */ PCA9535_ADDRESS, &smbus_PCA9535_write, &smbus_PCA9535_read);
// mxkN2CmdWriteData(byte addr,byte *data,ushort nbytes,ushort *nbytesOut)

View File

@ -10,4 +10,7 @@ void install_aime_bd();
smbus_callback_t smbus_N2_write;
smbus_callback_t smbus_N2_read;
void start_devices();
void register_device(const char* name, FnComDeviceThread* thread);
void install_devices();

View File

@ -73,9 +73,11 @@ typedef struct rs232c_recv_head {
BYTE op;
} rs232c_recv_head_t;
#define log_level log_misc
BYTE extra[0xff];
static DWORD WINAPI led_bd_thread(com_device_t* dev) {
log_info("led_bd", "%ls woke up", dev->com->wName);
log_info(plfMaiLED, "%ls woke up", dev->com->wName);
while (1) {
rs232c_recv_head_t head;
@ -86,17 +88,17 @@ static DWORD WINAPI led_bd_thread(com_device_t* dev) {
comdev_read(dev, (unsigned char*)&head, sizeof head);
comdev_read(dev, extra, head.length);
// log_info("led_bd", "Bound %02x->%02x", head.src, head.dst);
// log_info(plfMaiLED, "Bound %02x->%02x", head.src, head.dst);
switch (head.op) {
case 0x01:
log_trace("led_bd", "01");
log_level(plfMaiLED, "01");
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x01\x01\x18", 8);
// syn dst src len sts op. rep chk
break;
case 0x10:
log_trace("led_bd", "10");
log_level(plfMaiLED, "10");
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x10\x01\x27", 8);
// syn dst src len sts op. rep chk
break;
@ -106,13 +108,13 @@ static DWORD WINAPI led_bd_thread(com_device_t* dev) {
COLOURS[extra[0]][1] = extra[2];
COLOURS[extra[0]][2] = extra[3];
log_trace("led_bd", "31: %02x = (%02x %02x %02x)", extra[0], extra[1], extra[2],
log_level(plfMaiLED, "31: %02x = (%02x %02x %02x)", extra[0], extra[1], extra[2],
extra[3]);
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x31\x01\x48", 8);
// syn dst src len sts op. rep chk
break;
case 0x32:
log_trace("led_bd", "32: %02x %02x %02x %02x %02x %02x %02x", extra[0], extra[1],
log_level(plfMaiLED, "32: %02x %02x %02x %02x %02x %02x %02x", extra[0], extra[1],
extra[2], extra[3], extra[4], extra[5], extra[6], extra[7]);
for (unsigned char i = extra[2] - 1; i < extra[1]; i++) {
@ -125,7 +127,7 @@ static DWORD WINAPI led_bd_thread(com_device_t* dev) {
// syn dst src len sts op. rep chk
break;
case 0x33:
log_trace("led_bd", "33: %02x %02x %02x %02x %02x %02x %02x", extra[0], extra[1],
log_level(plfMaiLED, "33: %02x %02x %02x %02x %02x %02x %02x", extra[0], extra[1],
extra[2], extra[3], extra[4], extra[5], extra[6], extra[7]);
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x33\x01\x4a", 8);
// syn dst src len sts op. rep chk
@ -135,7 +137,7 @@ static DWORD WINAPI led_bd_thread(com_device_t* dev) {
break;
case 0x39:
log_trace("led_bd", "39: %02x %02x %02x", extra[0], extra[1], extra[2]);
log_level(plfMaiLED, "39: %02x %02x %02x", extra[0], extra[1], extra[2]);
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x39\x01\x50", 8);
// syn dst src len sts op. rep chk
@ -144,17 +146,17 @@ static DWORD WINAPI led_bd_thread(com_device_t* dev) {
COLOURS[9][2] = extra[0];
break;
case 0x3b:
log_trace("led_bd", "3b");
log_level(plfMaiLED, "3b");
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x3b\x01\x52", 8);
// syn dst src len sts op. rep chk
break;
case 0x3c:
log_trace("led_bd", "3c (I am %ls)", dev->com->wName);
log_level(plfMaiLED, "3c (I am %ls)", dev->com->wName);
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x3c\x01\x53", 8);
// syn dst src len sts op. rep chk
break;
case 0x3f:
log_trace("led_bd", "3f: %02x %02x %02x %02x %02x %02x", extra[0], extra[1],
log_level(plfMaiLED, "3f: %02x %02x %02x %02x %02x %02x", extra[0], extra[1],
extra[2], extra[3], extra[4], extra[5], extra[6]);
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x3f\x01\x56", 8);
// syn dst src len sts op. rep chk
@ -163,20 +165,20 @@ static DWORD WINAPI led_bd_thread(com_device_t* dev) {
case 0x7c:
// extra[0] goes from 0 to 7
// Could this be some sort of calibration for the buttons?
log_trace("led_bd", "7c: %02x", extra[0]);
log_level(plfMaiLED, "7c: %02x", extra[0]);
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x04\x01\x7c\x01\x00\x94", 9);
// \/ causes 7b to be used
// comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x04\x01\x7c\x01\x10\xa4", 9);
// syn dst src len sts op. rep --- chk
break;
case 0x7b:
log_trace("led_bd", "7b: %02x %02x %02x", extra[0], extra[1], extra[2]);
log_level(plfMaiLED, "7b: %02x %02x %02x", extra[0], extra[1], extra[2]);
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x7b\x01\x92", 8);
// syn dst src len sts op. rep chk
break;
default:
log_error("led_bd", "Unknown op %02x (%d)", head.op, head.length - 1);
log_error(plfMaiLED, "Unknown op %02x (%d)", head.op, head.length - 1);
break;
}
}
@ -214,19 +216,7 @@ void __stdcall led_overlay(unsigned int hookType, IDirect3DDevice9* dev) {
}
void install_led_bd() {
register_device("mailed", led_bd_thread);
// register_gui_hook(&led_overlay);
char* text = MiceConfig.devices.led_bd;
char* copy = (char*)malloc(strlen(text) + 1);
memcpy_s(copy, strlen(text) + 1, text, strlen(text) + 1);
char* next_token;
char* token = strtok_s(copy, ",", &next_token);
while (token != NULL) {
BYTE com_port = atoi(token) & 0xFF;
if (com_port) com_device_thread(new_com_device(com_port), led_bd_thread);
token = strtok_s(NULL, ",", &next_token);
}
free(copy);
}

View File

@ -18,7 +18,7 @@ static BYTE get_touch_id(BYTE id) {
BOOL touch_is_enabled = false;
BYTE thresh = 0x00; // Lazy caching of single value
DWORD WINAPI touch_bd_thread(com_device_t* dev) {
log_info("touch_bd", "%ls woke up", dev->com->wName);
log_info(plfMaiTouch, "%ls woke up", dev->com->wName);
while (1) {
if (touch_is_enabled && !comdev_available(dev)) {
@ -30,7 +30,7 @@ DWORD WINAPI touch_bd_thread(com_device_t* dev) {
while (read_one(dev) != '{') continue;
while (comdev_available(dev) < 5) {
log_info("touch", "<. .>");
log_info(plfMaiTouch, "<. .>");
Sleep(50);
}
BYTE command[5];
@ -40,20 +40,20 @@ DWORD WINAPI touch_bd_thread(com_device_t* dev) {
if (memcmp(command, "HALT}", 5) == 0) {
if (touch_is_enabled)
log_info("touch", "Touchscreen left active mode");
log_info(plfMaiTouch, "Touchscreen left active mode");
else
log_misc("touch", "Touchscreen not in active mode");
log_misc(plfMaiTouch, "Touchscreen not in active mode");
touch_is_enabled = false;
} else if (memcmp(command, "STAT}", 5) == 0) {
if (!touch_is_enabled)
log_info("touch", "Touchscreen entered active mode");
log_info(plfMaiTouch, "Touchscreen entered active mode");
else
log_misc("touch", "Touchscreen already in active mode");
log_misc(plfMaiTouch, "Touchscreen already in active mode");
touch_is_enabled = true;
} else if (command[2] == 'k' && command[4] == '}') {
BYTE sensor = get_touch_id(command[1]);
log_misc("touch", "k-command recieved: %d >=%d", sensor, command[3]);
log_misc(plfMaiTouch, "k-command recieved: %d >=%d", sensor, command[3]);
// Sensor == '@': failed
// ( <L/R> <sensor> <> <> )
response[1] = command[0];
@ -65,7 +65,7 @@ DWORD WINAPI touch_bd_thread(com_device_t* dev) {
BYTE sensor = get_touch_id(command[1]);
// { <L/R> <sensor> t h }
log_misc("touch", "th-command recieved: %d", sensor);
log_misc(plfMaiTouch, "th-command recieved: %d", sensor);
// Sensor == '@': failed
// ( <L/R> <sensor> <> <threshold> )
@ -75,23 +75,9 @@ DWORD WINAPI touch_bd_thread(com_device_t* dev) {
comdev_write(dev, response, 6);
} else {
log_error("touch", "Unhandled: {%.*s", 5, command);
log_error(plfMaiTouch, "Unhandled: {%.*s", 5, command);
}
}
}
void install_touch_bd() {
char* text = MiceConfig.devices.touch_bd;
char* copy = (char*)malloc(strlen(text) + 1);
memcpy_s(copy, strlen(text) + 1, text, strlen(text) + 1);
char* next_token;
char* token = strtok_s(copy, ",", &next_token);
while (token != NULL) {
BYTE com_port = atoi(token) & 0xFF;
if (com_port) com_device_thread(new_com_device(com_port), touch_bd_thread);
token = strtok_s(NULL, ",", &next_token);
}
free(copy);
}
void install_touch_bd() { register_device("maitouch", touch_bd_thread); }

View File

@ -217,14 +217,14 @@ BYTE BANA_KEY[6];
DWORD WINAPI aime_bd_thread(com_device_t* dev) {
static int fwNumBytes = 0;
log_info("aime_bd", "%ls woke up", dev->com->wName);
log_info(plfAime, "%ls woke up", dev->com->wName);
bool radio = false;
while (1) {
comio_recv_head_t req;
unsigned char sum = comio_next_req(dev, &req, extra);
log_info("aime_bd", "(%d) %02x(%d) = %s", req.dst, req.op, req.length, OpcodeNames[req.op]);
log_info(plfAime, "(%d) %02x(%d) = %s", req.dst, req.op, req.length, OpcodeNames[req.op]);
if (req.dst == 0x00 || req.dst == 0x01) {
// Aime readers
@ -249,7 +249,7 @@ DWORD WINAPI aime_bd_thread(com_device_t* dev) {
memcpy(AIME_KEY, extra, sizeof AIME_KEY);
comio_reply(dev, &req, COMIO_STATUS_OK, 0, NULL);
log_info("aime_bd", "Aime key: %02x %02x %02x %02x %02x %02x", AIME_KEY[0],
log_info(plfAime, "Aime key: %02x %02x %02x %02x %02x %02x", AIME_KEY[0],
AIME_KEY[1], AIME_KEY[2], AIME_KEY[3], AIME_KEY[4], AIME_KEY[5]);
}
break;
@ -260,7 +260,7 @@ DWORD WINAPI aime_bd_thread(com_device_t* dev) {
memcpy(BANA_KEY, extra, sizeof BANA_KEY);
comio_reply(dev, &req, COMIO_STATUS_OK, 0, NULL);
log_info("aime_bd", "Bana key: %02x %02x %02x %02x %02x %02x", BANA_KEY[0],
log_info(plfAime, "Bana key: %02x %02x %02x %02x %02x %02x", BANA_KEY[0],
BANA_KEY[1], BANA_KEY[2], BANA_KEY[3], BANA_KEY[4], BANA_KEY[5]);
}
break;
@ -294,7 +294,7 @@ DWORD WINAPI aime_bd_thread(com_device_t* dev) {
case TN32Op_Unknown61:
// null-terminated line of the firmware hex!
comio_reply(dev, &req, COMIO_STATUS_OK, 0, NULL);
log_info("aime_bd", "Recv firmware: %s", extra);
log_info(plfAime, "Recv firmware: %s", extra);
break;
case TN32Op_Unknown63:
// req.length == 0; start binary firmware update?
@ -344,7 +344,7 @@ DWORD WINAPI aime_bd_thread(com_device_t* dev) {
comio_reply(dev, &req, COMIO_STATUS_OK, 9, (BYTE*)"15084\xff\x10\x00\x12");
break;
case LedSetColour:
log_misc("nfc", "Set LED: #%02x%02x%02x", extra[0], extra[1], extra[2]);
log_misc(plfAime, "Set LED: #%02x%02x%02x", extra[0], extra[1], extra[2]);
printf(
"\033[48;2;%d;%d;%dm "
" \033[0m",
@ -384,17 +384,5 @@ void install_aime_bd() {
OpcodeNames[LedGetInfo] = "LedGetInfo";
OpcodeNames[LedSetColour] = "LedSetColour";
char* text = MiceConfig.devices.aime_bd;
char* copy = (char*)malloc(strlen(text) + 1);
memcpy_s(copy, strlen(text) + 1, text, strlen(text) + 1);
char* next_token;
char* token = strtok_s(copy, ",", &next_token);
while (token != NULL) {
BYTE com_port = atoi(token) & 0xFF;
if (com_port) com_device_thread(new_com_device(com_port), aime_bd_thread);
token = strtok_s(NULL, ",", &next_token);
}
free(copy);
register_device("aime_tn32msec", aime_bd_thread);
}

View File

@ -2,39 +2,16 @@
#include "../../maiBackupStructs.h"
#include "_devices.h"
#define EEPROM_DUMP L"dev/eeprom.bin"
#define EEPROM_PATH L"dev/eeprom.bin"
#include "../../sysconf.h"
// 8192 x 8 (64kbit) of eeprom
BYTE EEPROM_DATA[0x2000];
#define EEPROM_SIZE 0x2000
void eeprom_dump() {
HANDLE dump =
_CreateFileW(EEPROM_DUMP, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
if (dump == INVALID_HANDLE_VALUE) {
log_error("eeprom", "CreateFileA(EEPROM_DUMP) failed: %03x", GetLastError());
return;
} else {
log_info("eeprom", "Wrote eeprom to %ls", EEPROM_DUMP);
}
_WriteFile(dump, &EEPROM_DATA, sizeof EEPROM_DATA, NULL, NULL);
FlushFileBuffers(dump);
_CloseHandle(dump);
}
void eeprom_restore() {
HANDLE dump = _CreateFileW(EEPROM_DUMP, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (dump == INVALID_HANDLE_VALUE) {
// Make the file, even though it'll probably be empty
eeprom_dump();
return;
}
DWORD read;
if (!_ReadFile(dump, &EEPROM_DATA, sizeof EEPROM_DATA, &read, NULL))
log_error("eeprom", "failed to restore (%d)", GetLastError());
_CloseHandle(dump);
}
LPBYTE EEPROM_DATA = NULL;
HANDLE EEPROM_FILE = INVALID_HANDLE_VALUE;
HANDLE EEPROM_FILE_MAPPING = INVALID_HANDLE_VALUE;
#define fix_crc(block) \
do { \
@ -72,19 +49,9 @@ void set_eeprom_static_config() {
}
void build_eeprom() {
if (FileExists(EEPROM_DUMP)) {
eeprom_restore();
// Our network and static config always gets priority
set_eeprom_static_config();
set_eeprom_network_config();
log_info(plfEeprom, "Building default EEPROM file");
eeprom_dump();
return;
}
log_info("eeprom", "Building default EEPROM file");
memset(EEPROM_DATA, 0xff, sizeof EEPROM_DATA);
memset(EEPROM_DATA, 0xff, EEPROM_SIZE);
set_eeprom_static_config();
@ -102,22 +69,10 @@ void build_eeprom() {
set_eeprom_network_config();
AM_SYSDATAwH_HISTORY History = { 0 };
// TODO: Game ID here should be configurable.
History.m_GameId[0] = '-';
History.m_GameId[1] = '-';
History.m_GameId[2] = '-';
History.m_GameId[3] = '-';
History.m_Region = MiceConfig.sysconf.region & (1 | 2 | 4 | 8);
fix_crc(History);
memcpy(&EEPROM_DATA[AM_SYSDATAwH_HISTORY_REG], &History, sizeof History);
memcpy(&EEPROM_DATA[AM_SYSDATAwH_HISTORY_DUP], &History, sizeof History);
AM_SYSDATAwH_ALPB_CARD_ID CardInfo = { 0 };
fix_crc(CardInfo);
memcpy(&EEPROM_DATA[AM_SYSDATAwH_ALPB_CARD_ID_REG] + (sizeof History), &CardInfo,
sizeof CardInfo);
memcpy(&EEPROM_DATA[AM_SYSDATAwH_ALPB_CARD_ID_DUP] + (sizeof History), &CardInfo,
sizeof CardInfo);
memcpy(&EEPROM_DATA[AM_SYSDATAwH_ALPB_CARD_ID_REG], &CardInfo, sizeof CardInfo);
memcpy(&EEPROM_DATA[AM_SYSDATAwH_ALPB_CARD_ID_DUP], &CardInfo, sizeof CardInfo);
AM_SYSDATAwH_ALPB_COMPUTER_NAME CompuerName = { 0 };
fix_crc(CompuerName);
@ -129,47 +84,81 @@ void build_eeprom() {
memcpy(&EEPROM_DATA[AM_SYSDATAwH_ALPB_DEV_CONFIG_REG], &DevConfig, sizeof DevConfig);
memcpy(&EEPROM_DATA[AM_SYSDATAwH_ALPB_DEV_CONFIG_DUP], &DevConfig, sizeof DevConfig);
eeprom_dump();
// eeprom_dump();
}
AM_SYSDATAwH_HISTORY AmHistory = {
// By making the game ID "____" we ensure games overwrite this, letting us see what they write.
// This is currently the best way I have found to retrieve the game ID
.m_GameId = { '_', '_', '_', '_' },
};
/** Clobber EEPROM with our user settings */
void eeprom_fixup() {
set_eeprom_static_config();
set_eeprom_network_config();
AmHistory.m_Region = MiceConfig.sysconf.region & (1 | 2 | 4 | 8);
fix_crc(AmHistory);
memcpy(&EEPROM_DATA[AM_SYSDATAwH_HISTORY_REG], &AmHistory, sizeof AmHistory);
memcpy(&EEPROM_DATA[AM_SYSDATAwH_HISTORY_DUP], &AmHistory, sizeof AmHistory);
}
void ensure_valid_eeprom() {
static BOOL built = false;
if (built) {
eeprom_restore();
return;
}
build_eeprom();
built = true;
}
if (!EEPROM_DATA) {
BOOL isNew = !FileExists(EEPROM_PATH);
EEPROM_DATA =
open_mapped_file(EEPROM_PATH, EEPROM_SIZE, &EEPROM_FILE, &EEPROM_FILE_MAPPING);
if (EEPROM_DATA == NULL) {
log_error(plfEeprom, "EEPROM will be memory-backed and not syncronised!");
EEPROM_DATA = malloc(EEPROM_SIZE);
}
if (isNew) build_eeprom();
}
eeprom_fixup();
}
void eeprom_read(WORD addr, BYTE* data, BYTE length) {
ensure_valid_eeprom();
if (addr >= sizeof EEPROM_DATA) return;
if (length + addr > sizeof EEPROM_DATA) length = (sizeof EEPROM_DATA - addr) & 0xff;
if (addr >= EEPROM_SIZE) return;
if (length + addr > EEPROM_SIZE) length = (EEPROM_SIZE - addr) & 0xff;
memcpy(data, &EEPROM_DATA[addr], length);
memcpy(data, EEPROM_DATA + addr, length);
}
void eeprom_write(WORD addr, BYTE* data, BYTE length) {
ensure_valid_eeprom();
if (addr >= sizeof EEPROM_DATA) return;
if (length + addr > sizeof EEPROM_DATA) length = (sizeof EEPROM_DATA - addr) & 0xff;
if (addr >= EEPROM_SIZE) return;
if (length + addr > EEPROM_SIZE) length = (EEPROM_SIZE - addr) & 0xff;
memcpy(&EEPROM_DATA[addr], data, length);
eeprom_dump();
// TODO: Do any games write this as anything other than a complete block?
if (addr == AM_SYSDATAwH_HISTORY_REG && length == sizeof(AM_SYSDATAwH_HISTORY)) {
PAM_SYSDATAwH_HISTORY pHistory = (PAM_SYSDATAwH_HISTORY)data;
mice_got_game_id(pHistory->m_GameId);
} else if (addr >= 0x1000 && length > 8) {
char game_id[4];
game_id[0] = data[7];
game_id[1] = data[6];
game_id[2] = data[5];
game_id[3] = data[4];
mice_got_game_id(game_id);
}
memcpy(EEPROM_DATA + addr, data, length);
}
BOOL smbus_AT24C64AN_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
switch (cmd) {
case ICH9_CMD_BLOCK: {
log_misc("eeprom", "write %d bytes at 0x%03x", dlen, code);
log_misc(plfEeprom, "write %d bytes at 0x%03x", dlen, code);
eeprom_write(code, data, dlen);
return TRUE;
}
default:
log_error("eeprom", "Unsupported write mode: %01x, %02x", cmd, code);
log_error(plfEeprom, "Unsupported write mode: %01x, %02x", cmd, code);
return FALSE;
}
}
@ -180,12 +169,12 @@ BOOL smbus_AT24C64AN_read(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
data[0] = 0x00;
return TRUE;
case ICH9_CMD_BLOCK: {
log_misc("eeprom", "read %d bytes at 0x%03x", dlen, code);
log_misc(plfEeprom, "read %d bytes at 0x%03x", dlen, code);
eeprom_read(code, data, dlen);
return TRUE;
}
default:
log_error("eeprom", "Unsupported read mode: %01x, %02x", cmd, code);
log_error(plfEeprom, "Unsupported read mode: %01x, %02x", cmd, code);
return FALSE;
}
}

View File

@ -71,6 +71,11 @@ void ds2460_update_mac(bool gpSha, byte* secret) {
ComputeDallasSha(INPUT_BUFFER, (long*)&COMPUTED_MAC[0], (long*)&COMPUTED_MAC[4],
(long*)&COMPUTED_MAC[8], (long*)&COMPUTED_MAC[12],
(long*)&COMPUTED_MAC[16]);
puts("ds2460: SHA1 out buffer:");
for (int i = 0; i < 20; i++) {
printf("%02x", COMPUTED_MAC[i]);
}
puts("");
}
}
@ -86,7 +91,7 @@ BOOL smbus_ds2460_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
* | 0x04 -> DS2460_CMD_COMPUTE_TO_MAC_BUFFER
*/
if (!(data[0] & DS2460_CMD_COMPUTE)) {
log_error("ds2460", "Unknown command: %02x", data[0]);
log_error(plfDS2460, "Unknown command: %02x", data[0]);
return FALSE;
}
BYTE numSecret = (data[0] >> 3) & 3;
@ -99,7 +104,7 @@ BOOL smbus_ds2460_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
ds2460_update_mac(gpSha, SECRETS[numSecret]);
return TRUE;
default:
log_error("ds2460", "Unknown write command: %02x", code);
log_error(plfDS2460, "Unknown write command: %02x", code);
return FALSE;
}
case ICH9_CMD_BLOCK: {
@ -111,12 +116,12 @@ BOOL smbus_ds2460_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
memcpy_s(&INPUT_BUFFER[offset + 1], DS2460_INPUT_BUFFER_SIZE - (offset + 1), data,
dlen);
log_info("ds2460", "Block write, %d @ %04x: ", dlen + 1, offset);
log_info(plfDS2460, "Block write, %d @ %04x", dlen + 1, offset);
return TRUE;
}
default:
log_error("ds2460", "Unsupported write mode: %01x (%02x)", cmd, code);
log_error(plfDS2460, "Unsupported write mode: %01x (%02x)", cmd, code);
return FALSE;
}
}
@ -135,10 +140,10 @@ BOOL smbus_ds2460_read(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
return TRUE;
}
log_error("smx-exio", "Unknown read command: %02x", code);
log_error(plfDS2460, "Unknown read command: %02x", code);
return FALSE;
default:
log_error("ds2460", "Unsupported read mode: %01x (%02x)", cmd, code);
log_error(plfDS2460, "Unsupported read mode: %01x (%02x)", cmd, code);
return FALSE;
}
}

View File

@ -1,4 +1,4 @@
#include "smbus.h"
#include "../smbus.h"
smbus_callback_t smbus_ds2460_write;
smbus_callback_t smbus_ds2460_read;

View File

@ -97,17 +97,17 @@ BOOL smbus_ds28cn01_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
BYTE page = command & 3;
BYTE upper = command & 0xf0;
if (upper == 0xD0) {
log_warning("ds28cn01", "Computing for: authentication (flag = 1)");
} else if (upper == 0xE0) {
log_warning("ds28cn01", "Computing for: ds.compute (flag = 0)");
if (upper == DS28CN01_COMPUTE_1) {
log_warning(plfDS28CN01, "Computing for: authentication (flag = 1)");
} else if (upper == DS28CN01_COMPUTE_2) {
log_warning(plfDS28CN01, "Computing for: ds.compute (flag = 0)");
} else {
log_error("ds28cn01", "Unknown A9");
log_error(plfDS28CN01, "Unknown A9");
return FALSE;
}
if (dlen != 7) {
log_error("ds28cn01", "Expected challenge length of 7 (saw %d)!", dlen);
log_error(plfDS28CN01, "Expected challenge length of 7 (saw %d)!", dlen);
return FALSE;
}
@ -132,7 +132,7 @@ BOOL smbus_ds28cn01_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
// dlen++;
// char* challenge_s = malloc(dlen * 3 + 1);
// if (challenge_s == NULL) {
// log_info("ds28cn01", "Challenge: (buffer failed)");
// log_info(plfDS28CN01, "Challenge: (buffer failed)");
// return TRUE;
// }
@ -140,13 +140,13 @@ BOOL smbus_ds28cn01_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
// sprintf_s(challenge_s + i * 3, 4, "%02x ", data[i]);
// }
// challenge_s[dlen * 3 + 1] = '\0';
// log_info("ds28cn01", "Challenge: %s", challenge_s);
// log_info(plfDS28CN01, "Challenge: %s", challenge_s);
// free(challenge_s);
return TRUE;
}
log_error("ds28cn01", "Unknown write command: %04x", code);
log_error(plfDS28CN01, "Unknown write command: %04x", code);
}
case ICH9_CMD_I2C_READ: {
switch (code) {
@ -159,11 +159,11 @@ BOOL smbus_ds28cn01_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
for (int i = 0; i < dlen; i++) data[i] = COMPUTED_MAC[i];
return TRUE;
default:
log_error("ds28cn01", "Unknown I2C read command: %04x", code);
log_error(plfDS28CN01, "Unknown I2C read command: %04x", code);
}
}
default:
log_error("ds28cn01", "Unsupported write mode: %01x (%04x)", cmd, code);
log_error(plfDS28CN01, "Unsupported write mode: %01x (%04x)", cmd, code);
return FALSE;
}
}
@ -191,10 +191,10 @@ BOOL smbus_ds28cn01_read(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
return TRUE;
}
log_error("ds28cn01", "Unknown read command: %04x", code);
log_error(plfDS28CN01, "Unknown read command: %04x", code);
return FALSE;
default:
log_error("ds28cn01", "Unsupported read mode: %01x (%04x)", cmd, code);
log_error(plfDS28CN01, "Unsupported read mode: %01x (%04x)", cmd, code);
return FALSE;
}
}

View File

@ -1,4 +1,4 @@
#include "smbus.h"
#include "../smbus.h"
smbus_callback_t smbus_ds28cn01_write;
smbus_callback_t smbus_ds28cn01_read;
@ -18,6 +18,9 @@ smbus_callback_t smbus_ds28cn01_read;
#define DS28CN01_REG_STATUS 0xA8
#define DS28CN01_REG_MAC 0xB0
#define DS28CN01_COMPUTE_1 0xD0
#define DS28CN01_COMPUTE_2 0xE0
// Flags
#define DS28CN01_STATUS_FLAG_BUSY 2

View File

@ -1,3 +1,5 @@
#include "smb_n2.h"
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/rand.h>
@ -6,57 +8,10 @@
#include "../../sysconf.h"
#include "_devices.h"
#define N2_TAG_OFFSET 0
#define N2_PARAMSIZE_OFFSET 2
#define N2_COMMAND_OFFSET 4
#define N2_TAG_SIZE 2
#define N2_PARAMSIZE_SIZE 2
#define N2_COMMAND_SIZE 2
#define N2_CHECKSUM_SIZE 20
#define N2_AUTH_SIZE 20
#define N2_HEADER_SIZE (N2_TAG_SIZE + N2_PARAMSIZE_SIZE + N2_COMMAND_SIZE)
#define N2_TAG_RQU_COMMAND 0xC1
#define N2_TAG_RQU_AUTH_COMMAND 0xC2
#define N2_TAG_RSP_COMMAND 0xC3
#define N2_TAG_RSP_AUTH_COMMAND 0xC4
// TODO: Uncomment these if actually used, and adjust lazy +2 logic alongside
// #define N2_TAG_RQU_RSA_COMMAND 0xC5
// #define N2_TAG_RSP_RSA_COMMAND 0xC6
#define N2_ORD_ENABLE_SESSION 1
#define N2_ORD_DISABLE_SESSION 2
#define N2_ORD_SET_AUTH_KEY 3
#define N2_ORD_SET_ENC_KEY 4
// GAP!
#define N2_ORD_GET_AUTH_LEVEL 9
// GAP!
#define N2_ORD_GET_ERROR_CODE 11
#define N2_ORD_GET_VERSION 12
// GAP! (-> keychip info write?)
#define N2_ORD_READ_KEYCHIP_ID 14
// GAP! (-> gkey write?)
#define N2_ORD_ENCRYPT_WITH_GKEY 16 // keychip.encrypt
#define N2_ORD_DECRYPT_WITH_GKEY 17 // keychip.decrypt
#define N2_ORD_ADD_PLAY_COUNT 18
#define N2_ORD_READ_PLAY_COUNT 19
// GAP! (-> storage? is that still on pic?)
#define N2_ORD_GET_RANDOM_VALUE 24
#define N2_ORD_ENCRYPT_WITH_SKEY 25 // keychip.ssd.hostproof
#define N2_ORD_DECRYPT_WITH_SKEY 26
#define N2_SUCCESS 0
#define N2_INVALID_AUTH 1
#define N2_AUTHFAIL 2
#define N2_LV_ERROR 3
#define N2_BAD_PARAMETER 4
#define N2_EEP_WRITEFAIL 5
#define N2_BAD_TAG 6
#define N2_BAD_ORDINAL 7
#define N2_SUMFAIL 8
#define N2_EEPWRITE_DISABLE 9
#define N2_BAD_DATASIZE 10
#define N2_FAIL 11
LOG_FACILITY _lf = {
.m_name = "smb-n2",
};
PLOG_FACILITY plf = &_lf;
#define N2_IO_BUFFER 0x1000
@ -131,12 +86,12 @@ WORD n2_enable_session(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOu
RAND_bytes(n2_session_nonce, sizeof n2_session_nonce);
memcpy(dataOut, n2_session_nonce, sizeof n2_session_nonce);
log_misc("smb-n2", "Session open");
log_misc(plf, "Session open");
return N2_SUCCESS;
}
WORD n2_set_auth_key(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
*nOut = 0;
log_misc("smb-n2", "Auth key set");
log_misc(plf, "Auth key set");
BYTE pt[32];
mxkCryptDecryptAes128CBC(n2_enc_key.key, n2_enc_key.iv, dataIn, pt, sizeof pt);
@ -146,7 +101,7 @@ WORD n2_set_auth_key(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut)
}
WORD n2_set_enc_key(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
*nOut = 0;
log_misc("smb-n2", "Enc key set");
log_misc(plf, "Enc key set");
BYTE pt[32];
mxkCryptDecryptAes128CBC(n2_enc_key.key, n2_enc_key.iv, dataIn, pt, sizeof pt);
@ -158,13 +113,13 @@ WORD n2_set_enc_key(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut)
WORD n2_get_auth_level(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
*nOut = 1;
dataOut[0] = 3; // TODO: ?
log_misc("smb-n2", "Auth level get");
log_misc(plf, "Auth level get");
return N2_SUCCESS;
}
WORD n2_get_error_code(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
*nOut = 2;
((PWORD)dataOut)[0] = fix_endian(n2_error_code);
log_misc("smb-n2", "Error get");
log_misc(plf, "Error get");
return N2_SUCCESS;
}
WORD n2_read_keychip_id(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
@ -180,7 +135,7 @@ WORD n2_read_keychip_id(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nO
mxkCryptEncryptAes128CBC(n2_enc_key.key, n2_enc_key.iv, dataOut + 2, (LPBYTE)&n2_keychip_info,
nbytes);
log_misc("smb-n2", "Read keychip ID: %08x", nbytes);
log_misc(plf, "Read keychip ID: %08x", nbytes);
return N2_SUCCESS;
}
WORD n2_get_version(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
@ -288,11 +243,11 @@ void n2_install_commands() {
void do_n2_command(WORD tag, WORD paramSize, WORD command, LPBYTE data) {
n2_install_commands();
log_info("smb-n2", "Processing command: %04x/%04x (%d bytes)", tag, command, paramSize);
log_info(plf, "Processing command: %04x/%04x (%d bytes)", tag, command, paramSize);
ZeroMemory(n2_out_buffer, sizeof n2_out_buffer);
// We nede to sign with the old key, so need a copy
// We need to sign with the old key, so need a copy
BYTE auth_key[20];
memcpy(auth_key, n2_auth_key, sizeof auth_key);
@ -333,10 +288,13 @@ void do_n2_command(WORD tag, WORD paramSize, WORD command, LPBYTE data) {
EVP_DigestFinal_ex(ctx, n2_out_buffer + N2_HEADER_SIZE + bodyLength, &outlen);
EVP_MD_CTX_destroy(ctx);
// At this point: packet = header | data | SHA(header | command | data)
if (tag == N2_TAG_RQU_AUTH_COMMAND) {
BYTE crypto_buffer[N2_CHECKSUM_SIZE];
// Calculate a new SHA1 of the packet, including the SHA1 we just appeneded
// crypto_buffer = SHA1(header | command | data)
ctx = EVP_MD_CTX_create();
EVP_DigestInit(ctx, EVP_sha1());
EVP_DigestUpdate(ctx, n2_out_buffer, N2_HEADER_SIZE);
@ -350,9 +308,9 @@ void do_n2_command(WORD tag, WORD paramSize, WORD command, LPBYTE data) {
HMAC_CTX_init(&hmac_ctx);
HMAC_Init_ex(&hmac_ctx, auth_key, sizeof auth_key, EVP_sha1(), NULL);
// SHA1(header | data)
// SHA1(header | command | data)
HMAC_Update(&hmac_ctx, crypto_buffer, sizeof crypto_buffer);
// SHA1(header | auth | packet))
// SHA1(header | auth | data)
HMAC_Update(&hmac_ctx, n2_out_buffer + N2_HEADER_SIZE + bodyLength, N2_CHECKSUM_SIZE);
// Request nonce
HMAC_Update(&hmac_ctx, n2_in_buffer + paramSize - N2_AUTH_SIZE - N2_CHECKSUM_SIZE,
@ -398,7 +356,7 @@ BOOL smbus_N2_write(ich9_cmd_t cmd, WORD code, BYTE nbytes, LPBYTE data) {
return TRUE;
}
}
log_error("smb-n2", "Unsupported command code: %04x (%d bytes)", code, nbytes);
log_error(plf, "Unsupported command code: %04x (%d bytes)", code, nbytes);
return FALSE;
}
case ICH9_CMD_I2C_READ: {
@ -409,15 +367,15 @@ BOOL smbus_N2_write(ich9_cmd_t cmd, WORD code, BYTE nbytes, LPBYTE data) {
return TRUE;
}
}
log_error("smb-n2", "Unsupported i2c command code: %04x (%d bytes)", code, nbytes);
log_error(plf, "Unsupported i2c command code: %04x (%d bytes)", code, nbytes);
return FALSE;
}
}
log_error("smb-n2", "Unsupported write mode: %01x (%02x)", cmd, code);
log_error(plf, "Unsupported write mode: %01x (%02x)", cmd, code);
return FALSE;
}
BOOL smbus_N2_read(ich9_cmd_t cmd, WORD code, BYTE nbytes, BYTE* data) {
log_error("smb-n2", "Unsupported read mode: %01x (%02x)", cmd, code);
log_error(plf, "Unsupported read mode: %01x (%02x)", cmd, code);
return FALSE;
}

View File

@ -0,0 +1,48 @@
#define N2_TAG_OFFSET 0
#define N2_PARAMSIZE_OFFSET 2
#define N2_COMMAND_OFFSET 4
#define N2_TAG_SIZE 2
#define N2_PARAMSIZE_SIZE 2
#define N2_COMMAND_SIZE 2
#define N2_CHECKSUM_SIZE 20
#define N2_AUTH_SIZE 20
#define N2_HEADER_SIZE (N2_TAG_SIZE + N2_PARAMSIZE_SIZE + N2_COMMAND_SIZE)
#define N2_TAG_RQU_COMMAND 0xC1
#define N2_TAG_RQU_AUTH_COMMAND 0xC2
#define N2_TAG_RSP_COMMAND 0xC3
#define N2_TAG_RSP_AUTH_COMMAND 0xC4
#define N2_ORD_ENABLE_SESSION 1
#define N2_ORD_DISABLE_SESSION 2
#define N2_ORD_SET_AUTH_KEY 3
#define N2_ORD_SET_ENC_KEY 4
// GAP!
#define N2_ORD_GET_AUTH_LEVEL 9
// GAP!
#define N2_ORD_GET_ERROR_CODE 11
#define N2_ORD_GET_VERSION 12
// GAP! (-> keychip info write?)
#define N2_ORD_READ_KEYCHIP_ID 14
// GAP! (-> gkey write?)
#define N2_ORD_ENCRYPT_WITH_GKEY 16 // keychip.encrypt
#define N2_ORD_DECRYPT_WITH_GKEY 17 // keychip.decrypt
#define N2_ORD_ADD_PLAY_COUNT 18
#define N2_ORD_READ_PLAY_COUNT 19
// GAP! (-> storage? is that still on pic?)
#define N2_ORD_GET_RANDOM_VALUE 24
#define N2_ORD_ENCRYPT_WITH_SKEY 25 // keychip.ssd.hostproof
#define N2_ORD_DECRYPT_WITH_SKEY 26
#define N2_SUCCESS 0
#define N2_INVALID_AUTH 1
#define N2_AUTHFAIL 2
#define N2_LV_ERROR 3
#define N2_BAD_PARAMETER 4
#define N2_EEP_WRITEFAIL 5
#define N2_BAD_TAG 6
#define N2_BAD_ORDINAL 7
#define N2_SUMFAIL 8
#define N2_EEPWRITE_DISABLE 9
#define N2_BAD_DATASIZE 10
#define N2_FAIL 11

View File

@ -44,11 +44,11 @@ BOOL smbus_PCA9535_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
config[1] = data[0];
return TRUE;
default:
log_error("pca9535", "Unknown write command: %02x", code);
log_error(plfPCA9535, "Unknown write command: %02x", code);
return FALSE;
}
default:
log_error("pca9535", "Unsupported write mode: %01x (%02x)", cmd, code);
log_error(plfPCA9535, "Unsupported write mode: %01x (%02x)", cmd, code);
return FALSE;
}
}
@ -167,11 +167,11 @@ BOOL smbus_PCA9535_read(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
return TRUE;
default:
log_error("pca9535", "Unknown read command: %02x", code);
log_error(plfPCA9535, "Unknown read command: %02x", code);
return FALSE;
}
default:
log_error("pca9535", "Unsupported read mode: %01x (%02x)", cmd, code);
log_error(plfPCA9535, "Unsupported read mode: %01x (%02x)", cmd, code);
return FALSE;
}
}

View File

@ -1,3 +1,5 @@
#include <signal.h>
#include "common.h"
#include "devices/_devices.h"
#include "drivers/mx.h"
@ -15,7 +17,7 @@ DWORD GetImageBase(void) {
HANDLE hObject =
_CreateFileW(sModulePath, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hObject == INVALID_HANDLE_VALUE) {
log_error(BOOT_LOGGER, "Failed to open %ls %03x", sModulePath, GetLastError());
log_error(plfBoot, "Failed to open %ls %03x", sModulePath, GetLastError());
return 0;
}
@ -24,11 +26,11 @@ DWORD GetImageBase(void) {
_SetFilePointer(hObject, 0, NULL, FILE_BEGIN);
_ReadFile(hObject, &dosHeader, sizeof dosHeader, &nRead, NULL);
if (nRead != sizeof dosHeader) {
log_error(BOOT_LOGGER, "Failed to read DOS header %03x", GetLastError());
log_error(plfBoot, "Failed to read DOS header %03x", GetLastError());
return 0;
}
if (dosHeader.e_magic != IMAGE_DOS_SIGNATURE) {
log_error(BOOT_LOGGER, "Invalid DOS magic number: %04x", dosHeader.e_magic);
log_error(plfBoot, "Invalid DOS magic number: %04x", dosHeader.e_magic);
return 0;
}
@ -36,11 +38,11 @@ DWORD GetImageBase(void) {
_SetFilePointer(hObject, dosHeader.e_lfanew, NULL, FILE_BEGIN);
_ReadFile(hObject, &ntHeaders32, sizeof ntHeaders32, &nRead, NULL);
if (nRead != sizeof ntHeaders32) {
log_error(BOOT_LOGGER, "Failed to read NT header %03x", GetLastError());
log_error(plfBoot, "Failed to read NT header %03x", GetLastError());
return 0;
}
if (ntHeaders32.Signature != IMAGE_NT_SIGNATURE) {
log_error(BOOT_LOGGER, "Invalid NT signature: %08x", ntHeaders32.Signature);
log_error(plfBoot, "Invalid NT signature: %08x", ntHeaders32.Signature);
return 0;
}
@ -53,7 +55,7 @@ void apply_patches(HMODULE hModule) {
DWORD imageBase = GetImageBase();
if (imageBase == 0) {
log_error(BOOT_LOGGER, "Failed to locate image base. Patches will not be applied.");
log_error(plfBoot, "Failed to locate image base. Patches will not be applied.");
return;
}
imageOffset = (DWORD)hModule - imageBase;
@ -62,13 +64,13 @@ void apply_patches(HMODULE hModule) {
WideCharToMultiByte(CP_ACP, 0, exeName, -1, exeNameC, sizeof exeNameC, NULL, NULL);
if (!load_patches(MiceConfig.mice.patches_file, exeNameC)) {
log_error(BOOT_LOGGER, "Failed to load patches file %s", MiceConfig.mice.patches_file);
log_error(plfBoot, "Failed to load patches file %s", MiceConfig.mice.patches_file);
return;
}
patch_t* patch = patch_list->next;
if (patch == NULL) {
log_warning(BOOT_LOGGER, "No patches to apply. Did you forgot an amiDebug patch file?");
log_warning(plfBoot, "No patches to apply. Did you forgot an amiDebug patch file?");
}
while (patch) {
DWORD oldProt;
@ -76,7 +78,7 @@ void apply_patches(HMODULE hModule) {
PAGE_EXECUTE_READWRITE, &oldProt);
if (memcmp(patch->match, (void*)((DWORD)patch->address + imageOffset), patch->count) != 0) {
log_error(BOOT_LOGGER, "Patch %s failed! from-value missmatch", patch->name);
log_error(plfBoot, "Patch %s failed! from-value missmatch", patch->name);
VirtualProtect((void*)((DWORD)patch->address + imageOffset), patch->count, oldProt,
&oldProt);
patch = patch->next;
@ -84,7 +86,7 @@ void apply_patches(HMODULE hModule) {
}
memcpy((void*)((DWORD)patch->address + imageOffset), patch->replace, patch->count);
log_misc(BOOT_LOGGER, "Patched %d bytes at %08x (%s)", patch->count, patch->address,
log_misc(plfBoot, "Patched %d bytes at %08x (%s)", patch->count, patch->address,
patch->name);
patch = patch->next;
@ -93,10 +95,11 @@ void apply_patches(HMODULE hModule) {
void prebind_hooks() {
hook_all();
init_com_devices();
install_devices();
// TODO: Figure out why we're needing to call this manually (medium priority)
if (wcscmp(exeName, L"ALLNetProc.exe") == 0) {
log_warning(BOOT_LOGGER, "Making explicit call to OPENSSL_add_all_algorithms_noconf");
log_warning(plfBoot, "Making explicit call to OPENSSL_add_all_algorithms_noconf");
// OPENSSL_add_all_algorithms_noconf
((void (*)(void))(0x00459770))();
@ -111,7 +114,7 @@ void init_injection(HMODULE hModule) {
// We're in a new context now, so need to reconfigure
setup_logging();
log_info(BOOT_LOGGER, "Handover complete. Now executing within %ls", exeName);
log_info(plfBoot, "Handover complete. Now executing within %ls", exeName);
if (MiceConfig.mice.apply_patches) apply_patches(hModule);
@ -132,7 +135,7 @@ void init_injection(HMODULE hModule) {
if (MiceConfig.drivers.platform) {
if (!add_fake_device(&PLATFORM_GUID, L"\\\\.\\platform")) {
log_error("platform", "failed to install platform device");
log_error(plfPlatform, "failed to install platform device");
}
}
@ -144,14 +147,29 @@ void init_injection(HMODULE hModule) {
void tea_hook_test(char* fmt, ...) {
va_list argp;
va_start(argp, fmt);
vlog_game("tea", fmt, argp);
vlog_game(plfTea, fmt, argp);
va_end(argp);
}
int mxkMain();
DWORD WINAPI MxkThreadProc(LPVOID lpParameter) { mxkMain(); };
int miceDummyMaster(unsigned short textPort, unsigned short binaryPort, bool global);
int miceDummyInstaller(unsigned short textPort, unsigned short binaryPort, bool global);
DWORD WINAPI MxkThreadProc(LPVOID lpParameter) {
mxkMain();
return 0;
};
DWORD WINAPI MdMasterThreadProc(LPVOID lpParameter) {
miceDummyMaster(40100, 40101, false);
return 0;
};
DWORD WINAPI MdInstallerThreadProc(LPVOID lpParameter) {
miceDummyInstaller(40102, 40103, false);
return 0;
};
void spawn_pcp_processes(void) {
// CreateThread(NULL, 0, &MxkThreadProc, NULL, 0, NULL);
// CreateThread(NULL, 0, MxkThreadProc, NULL, 0, NULL);
// CreateThread(NULL, 0, MdMasterThreadProc, NULL, 0, NULL);
// CreateThread(NULL, 0, MdInstallerThreadProc, NULL, 0, NULL);
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
@ -171,7 +189,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
spawn_pcp_processes();
// if (wcscmp(exeName, L"RingGame.exe") == 0) {
// log_warning(BOOT_LOGGER, "Bodge hook goo!");
// log_warning(plfBoot, "Bodge hook goo!");
// CreateHook32((void*)(0x005f2580), &tea_hook_test);
// }

View File

@ -10,10 +10,10 @@ BOOL WINAPI columba_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode,
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
switch (dwIoControlCode) {
case IOCTL_COLUMBA_READ:
log_misc("columba", "DeviceIoControl(<columba>, <read>, 0x%p, 0x%x, -, 0x%x, -, -)",
log_misc(plfColumba, "DeviceIoControl(<columba>, <read>, 0x%p, 0x%x, -, 0x%x, -, -)",
lpInBuffer, nInBufferSize, nOutBufferSize);
AM_COLUMBA_REQUEST* request = (AM_COLUMBA_REQUEST*)lpInBuffer;
log_info("columba", "Physical read: 0x%04x %ss at %08X", request->m_elementCount,
log_info(plfColumba, "Physical read: 0x%04x %ss at %08X", request->m_elementCount,
request->m_elementSize == 1 ? "byte"
: request->m_elementSize == 2 ? "short"
: request->m_elementSize == 4 ? "long"
@ -41,7 +41,7 @@ BOOL WINAPI columba_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode,
memcpy(lpOutBuffer, dmi_table, dmi_size);
if (lpBytesReturned) *lpBytesReturned = 0x10000;
} else {
log_error("columba", "Request to unmapped memory location: %08x",
log_error(plfColumba, "Request to unmapped memory location: %08x",
request->m_physAddr);
return FALSE;
}
@ -49,7 +49,7 @@ BOOL WINAPI columba_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode,
break;
default:
// Observed: IOCTL_KSEC_RNG_REKEY
log_warning("columba", "unhandled 0x%08x", dwIoControlCode);
log_warning(plfColumba, "unhandled 0x%08x", dwIoControlCode);
return FALSE;
}

View File

@ -8,7 +8,7 @@ BOOL WINAPI mxhwreset_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode
if (lpBytesReturned) *lpBytesReturned = 0;
break;
default:
log_warning("mxhwreset", "unhandled 0x%08x", dwIoControlCode);
log_warning(plfMxHwreset, "unhandled 0x%08x", dwIoControlCode);
return FALSE;
}
return TRUE;

View File

@ -113,7 +113,7 @@ unsigned char jvs_exchange(jvs_board_t* board, unsigned char* inData, short inCo
unsigned char cmd;
jvs_read(cmd);
// log_info("mxjvs", "CMD: %02x", cmd);
// log_info(plfMxJvs, "CMD: %02x", cmd);
switch (cmd) {
case JVS_CMD_RESET:
@ -244,12 +244,12 @@ unsigned char jvs_exchange(jvs_board_t* board, unsigned char* inData, short inCo
if (i == 0) {
if (!!(gpio_value & 0x80) != coin_solenoid) {
coin_solenoid = !!(gpio_value & 0x80);
log_info("mxjvs", "Coin solenoid: %s",
log_info(plfMxJvs, "Coin solenoid: %s",
coin_solenoid ? "Locked" : "Unlocked");
}
}
// log_warning("mxjvs", "Unhandled GPIO write: *(%d) = %02x", i, gpio_value);
// log_warning(plfMxJvs, "Unhandled GPIO write: *(%d) = %02x", i, gpio_value);
}
break;
@ -266,7 +266,7 @@ unsigned char jvs_exchange(jvs_board_t* board, unsigned char* inData, short inCo
break;
default:
log_error("mxjvs", "Unknown command: 0x%02x", cmd);
log_error(plfMxJvs, "Unknown command: 0x%02x", cmd);
return JVS_STATUS_UKCOM;
}
}
@ -304,14 +304,14 @@ void mxjvs_handle(unsigned char* paddedIn, short inCount, unsigned char* outData
// JVS frame is 4 bytes in total
if (inCount < 4) {
log_error("mxjvs", "inCount impossibly small: %d", inCount);
log_error(plfMxJvs, "inCount impossibly small: %d", inCount);
jvs_send_status(JVS_STATUS_UNKNOWN, outData, outCount);
free(inData);
return;
}
// This isn't a JVS packet
if (inData[0] != JVS_SYNC) {
log_error("mxjvs", "SYNC missing. Saw 0x%02x", inData[0]);
log_error(plfMxJvs, "SYNC missing. Saw 0x%02x", inData[0]);
jvs_send_status(JVS_STATUS_UNKNOWN, outData, outCount);
free(inData);
return;
@ -322,7 +322,7 @@ void mxjvs_handle(unsigned char* paddedIn, short inCount, unsigned char* outData
bool escape = false;
for (int i = 1; i < inCount - 1; i++) sum += inData[i];
if (sum != inData[inCount - 1]) {
log_error("mxjvs", "Checksum failed. Computed 0x%02x, expected 0x%02x", sum,
log_error(plfMxJvs, "Checksum failed. Computed 0x%02x, expected 0x%02x", sum,
inData[inCount - 1]);
jvs_send_status(JVS_STATUS_SUM, outData, outCount);
return;
@ -334,8 +334,8 @@ void mxjvs_handle(unsigned char* paddedIn, short inCount, unsigned char* outData
return;
unsigned char* response = malloc(maxOut);
unsigned char packetSize;
unsigned char status;
unsigned char packetSize = 0;
unsigned char status = JVS_STATUS_UNKNOWN;
if (destination == 0xff) {
for (int i = 0; i < MiceConfig.keys.board_count; i++) {
jvs_board_t* board = &jvs_boards[i];
@ -365,7 +365,7 @@ void mxjvs_handle(unsigned char* paddedIn, short inCount, unsigned char* outData
free(response);
} else {
log_error("mxjvs", "JVS board %d returned status %d", destination, status);
log_error(plfMxJvs, "JVS board %d returned status %d", destination, status);
free(response);
jvs_send_status(status, outData, outCount);
}
@ -376,7 +376,7 @@ BOOL WINAPI mxjvs_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LP
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
switch (dwIoControlCode) {
case IOCTL_MXJVS_EXCHANGE:
log_trace("mxjvs",
log_trace(plfMxJvs,
"DeviceIoControl(<mxjvs>, <exchange>, 0x%p, 0x%x, -, "
"0x%x, -, -)",
lpInBuffer, nInBufferSize, nOutBufferSize);
@ -386,7 +386,7 @@ BOOL WINAPI mxjvs_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LP
break;
default:
log_warning("mxjvs", "unhandled 0x%08x", dwIoControlCode);
log_warning(plfMxJvs, "unhandled 0x%08x", dwIoControlCode);
return FALSE;
}
@ -406,7 +406,7 @@ BOOL mxjvs_GetCommModemStatus(void* com, LPDWORD lpModelStat) {
BOOL mxjvs_SetCommState(void* com, LPDCB lpDCB) {
char PARITY[] = { 'N', 'O', 'E', 'M', 'S' };
char* STOP[] = { "1", "1.5", "2" };
log_info("mxjvs", "Switching to %d baud (%d%c%s)", lpDCB->BaudRate, lpDCB->ByteSize,
log_info(plfMxJvs, "Switching to %d baud (%d%c%s)", lpDCB->BaudRate, lpDCB->ByteSize,
PARITY[lpDCB->Parity], STOP[lpDCB->StopBits]);
return TRUE;
}

View File

@ -49,7 +49,7 @@ uint32_t BILLING_PLAYCOUNT = 69420;
BOOL WINAPI mxparallel_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOID lpInBuffer,
DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize,
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
log_trace("mxparallel", "DeviceIoControl(<mxparallel>, 0x%08x, 0x%p, 0x%x, -, 0x%x, -, -)",
log_trace(plfMxParallel, "DeviceIoControl(<mxparallel>, 0x%08x, 0x%p, 0x%x, -, 0x%x, -, -)",
dwIoControlCode, lpInBuffer, nInBufferSize, nOutBufferSize);
switch (dwIoControlCode) {
@ -68,7 +68,7 @@ BOOL WINAPI mxparallel_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCod
return TRUE;
case IOCTL_MXPARALLEL_WRITE_CTRL_PORT:
parallel_ctrl = ((LPBYTE)lpInBuffer)[0];
// log_warning("mxparallel", "Write ctrl %08x", parallel_ctrl);
// log_warning(plfMxParallel, "Write ctrl %08x", parallel_ctrl);
outLen(0);
return TRUE;
@ -231,37 +231,37 @@ void mxparallel_process_packet(BYTE* request) {
switch (request[0]) {
// We're pretending to be the keychip, so S and R are swapped for us!
case SetKeyS:
log_info("mxparallel", "SetKeyS");
log_info(plfMxParallel, "SetKeyS");
micexkRecvPacket(request);
mxkSetKeyR(request);
micexkSendPacket(response);
break;
case SetKeyR:
log_info("mxparallel", "SetKeyR");
log_info(plfMxParallel, "SetKeyR");
micexkRecvPacket(request);
mxkSetKeyS(request);
micexkSendPacket(response);
break;
case Encrypt:
log_info("mxparallel", "Encrypt");
log_info(plfMxParallel, "Encrypt");
micexkRecvPacket(request);
micexkSendPacket(request);
break;
case Decrypt:
log_info("mxparallel", "Decrypt");
log_info(plfMxParallel, "Decrypt");
micexkRecvPacket(request);
micexkSendPacket(request);
break;
case SetIV:
log_info("mxparallel", "SetIV");
log_info(plfMxParallel, "SetIV");
ZeroMemory(kc_aes_iv, sizeof kc_aes_iv);
micexkSendPacket(response);
break;
case GetAppBootInfo:
log_info("mxparallel", "GetAppBootInfo");
log_info(plfMxParallel, "GetAppBootInfo");
if (request[1] != 0x00) {
log_warning("mxparallel", "GetAppBootInfo[%d] unexpected!", request[1]);
log_warning(plfMxParallel, "GetAppBootInfo[%d] unexpected!", request[1]);
}
APPBOOT.crc = amiCrc32RCalc(sizeof APPBOOT - 4, (unsigned char*)&APPBOOT + 4, 0);
@ -271,7 +271,7 @@ void mxparallel_process_packet(BYTE* request) {
break;
case KcGetVersion:
log_info("mxparallel", "GetVersion");
log_info(plfMxParallel, "GetVersion");
response[0] = 0x01;
response[1] = 0x04;
micexkSendPacket(response);
@ -280,18 +280,18 @@ void mxparallel_process_packet(BYTE* request) {
case FlashRead: {
uint32_t addr = request[1] | (request[2] << 8) | (request[3] << 16);
uint32_t nbytes = request[4] | (request[5] << 8) | (request[6] << 16);
log_info("mxparallel", "FlashRead: %06x/%06x", addr, nbytes);
log_info(plfMxParallel, "FlashRead: %06x/%06x", addr, nbytes);
if (addr + nbytes <= sizeof flash)
micexkTransportSend(&flash[addr], nbytes);
else
log_error("mxparallel", "Flash read would exceed storage!");
log_error(plfMxParallel, "Flash read would exceed storage!");
break;
}
case FlashErase: {
uint32_t addr = request[1] | (request[2] << 8) | (request[3] << 16);
log_info("mxparallel", "FlashErase: %06x", addr);
log_info(plfMxParallel, "FlashErase: %06x", addr);
micexkSendPacket(response);
break;
@ -299,12 +299,12 @@ void mxparallel_process_packet(BYTE* request) {
case FlashWrite: {
uint32_t addr = request[1] | (request[2] << 8) | (request[3] << 16);
uint32_t nbytes = request[4] | (request[5] << 8) | (request[6] << 16);
log_info("mxparallel", "FlashWrite: %06x/%06x", addr, nbytes);
log_info(plfMxParallel, "FlashWrite: %06x/%06x", addr, nbytes);
if (addr + nbytes <= sizeof flash)
micexkTransportRecv(&flash[addr], nbytes);
else
log_error("mxparallel", "Flash write would exceed storage!");
log_error(plfMxParallel, "Flash write would exceed storage!");
micexkSendPacket(response);
dump_nv_storage();
@ -315,12 +315,12 @@ void mxparallel_process_packet(BYTE* request) {
case EepromWrite: {
// TODO: What is this? Appears to be some sort of EEPROM write
uint8_t offset = request[1];
log_info("mxparallel", "EepromWrite: %02x", offset);
log_info(plfMxParallel, "EepromWrite: %02x", offset);
if (offset * 16 + 16 <= sizeof eeprom) {
micexkRecvPacket(&eeprom[offset * 16]);
} else {
log_error("mxparallel", "EEPROM write would exceed storage!");
log_error(plfMxParallel, "EEPROM write would exceed storage!");
}
micexkSendPacket(response);
dump_nv_storage();
@ -329,12 +329,12 @@ void mxparallel_process_packet(BYTE* request) {
case EepromRead: {
// TODO: What is this? Appears to be some sort of EEPROM read
uint8_t offset = request[1];
log_info("mxparallel", "EepromRead: %02x", offset);
log_info(plfMxParallel, "EepromRead: %02x", offset);
if (offset * 16 + 16 <= sizeof eeprom) {
micexkSendPacket(&eeprom[offset * 16]);
} else {
log_error("mxparallel", "EEPROM read would exceed storage!");
log_error(plfMxParallel, "EEPROM read would exceed storage!");
}
break;
}
@ -344,7 +344,7 @@ void mxparallel_process_packet(BYTE* request) {
// TODO: What is this? Appears to be some sort of memory write
uint16_t addr = request[1] | (request[2] << 8);
uint8_t blocks = request[3];
log_info("mxparallel", "NvramWrite: %04x (%02x)", addr, blocks);
log_info(plfMxParallel, "NvramWrite: %04x (%02x)", addr, blocks);
if (addr + blocks * 16 <= sizeof nvram) {
for (byte i = 0; i < blocks; i++) {
@ -352,7 +352,7 @@ void mxparallel_process_packet(BYTE* request) {
}
micexkSendPacket(response);
} else {
log_error("mxparallel", "NVRAM write would exceed storage!");
log_error(plfMxParallel, "NVRAM write would exceed storage!");
}
dump_nv_storage();
break;
@ -361,26 +361,26 @@ void mxparallel_process_packet(BYTE* request) {
// TODO: What is this? Appears to be some sort of memory read
uint16_t addr = request[1] | (request[2] << 8);
uint8_t blocks = request[3];
log_info("mxparallel", "NvramRead: %04x (%02x)", addr, blocks);
log_info(plfMxParallel, "NvramRead: %04x (%02x)", addr, blocks);
if (addr + blocks * 16 <= sizeof nvram) {
for (byte i = 0; i < blocks; i++) {
micexkSendPacket(&(nvram[addr + (i * 16)]));
}
} else {
log_error("mxparallel", "NVRAM read would exceed storage!");
log_error(plfMxParallel, "NVRAM read would exceed storage!");
}
break;
}
case AddPlayCount:
log_info("mxparallel", "AddPlayCount");
log_info(plfMxParallel, "AddPlayCount");
BILLING_PLAYCOUNT++;
micexkSendPacket(response);
break;
case SetMainId:
log_info("mxparallel", "SetMainId");
log_info(plfMxParallel, "SetMainId");
// micexkRecvPacket(_MAIN_ID);
micexkRecvPacket(request);
@ -388,27 +388,27 @@ void mxparallel_process_packet(BYTE* request) {
micexkSendPacket(response);
break;
case GetMainId:
log_info("mxparallel", "GetMainId");
log_info(plfMxParallel, "GetMainId");
micexkSendPacket(_MAIN_ID);
break;
case SetKeyId:
log_info("mxparallel", "SetKeyId");
log_info(plfMxParallel, "SetKeyId");
micexkRecvPacket(KEYCHIP_ID);
micexkSendPacket(response);
break;
case GetKeyId:
log_info("mxparallel", "GetKeyId");
log_info(plfMxParallel, "GetKeyId");
micexkSendPacket(KEYCHIP_ID);
break;
case GetPlayCounter:
log_info("mxparallel", "GetPlayCounter");
log_info(plfMxParallel, "GetPlayCounter");
((uint32_t*)response)[0] = BILLING_PLAYCOUNT;
micexkSendPacket(response);
break;
default:
log_error("mxparallel", "Unhandled opcode: %d", request[0]);
log_error(plfMxParallel, "Unhandled opcode: %d", request[0]);
for (byte i = 0; i < 16; i++) {
printf("%02x ", request[i]);
}
@ -419,7 +419,7 @@ void mxparallel_process_packet(BYTE* request) {
}
DWORD WINAPI mxparallel_thread(LPVOID _) {
log_info("mxparallel", "Parallel device thread spawned");
log_info(plfMxParallel, "Parallel device thread spawned");
clearBusy;
clearAck;

View File

@ -55,12 +55,12 @@ BOOL handle_smbus(BYTE command, WORD v_addr, WORD command_code, BYTE nbytes, BYT
break;
}
log_trace("smbus", "Making request to %02X (virtual: %04X/%04x, cmd: %01X, code: %04X)", p_addr,
log_trace(plfMxSmbus, "Making request to %02X (virtual: %04X/%04x, cmd: %01X, code: %04X)", p_addr,
v_addr, command, smb_cmd, command_code);
smbus_callback_t* callback = smbus_devices[p_addr];
if (callback == NULL) {
log_error("smbus", "Request to unregistered address: %02x", p_addr);
log_error(plfMxSmbus, "Request to unregistered address: %02x", p_addr);
return FALSE;
}
return (*callback)(smb_cmd, command_code, nbytes, data);
@ -74,7 +74,7 @@ BOOL WINAPI mxsmbus_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode,
switch (dwIoControlCode) {
case IOCTL_MXSMBUS_GET_VERSION:
log_misc("mxsmbus",
log_misc(plfMxSmbus,
"DeviceIoControl(<mxsmbus>, <get version>, 0x%p, 0x%x, "
"-, 0x%x, -, -)",
lpInBuffer, nInBufferSize, nOutBufferSize);
@ -115,7 +115,7 @@ BOOL WINAPI mxsmbus_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode,
};
}
default:
log_warning("mxsmbus", "unhandled 0x%08x", dwIoControlCode);
log_warning(plfMxSmbus, "unhandled 0x%08x", dwIoControlCode);
return FALSE;
}
return TRUE;
@ -128,6 +128,6 @@ void setup_mxsmbus() {
hook_file(mxsmbus);
if (!add_fake_device(&MXSMBUS_GUID, L"\\\\.\\mxsmbus")) {
log_error("mxsmbus", "failed to install mxsmbus device");
log_error(plfMxSmbus, "failed to install mxsmbus device");
}
}

View File

@ -2,30 +2,11 @@
#include "../../maiBackupStructs.h"
#include "mx.h"
#define SRAM_DUMP L"dev/sram.bin"
#define SRAM_PATH L"dev/sram.bin"
#define SRAM_SIZE 1024 * 2084
LPBYTE SRAM;
void sram_dump() {
HANDLE dump =
_CreateFileW(SRAM_DUMP, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
if (dump == INVALID_HANDLE_VALUE) {
log_error("sram", "CreateFileA(SRAM_DUMP) failed");
return;
}
_WriteFile(dump, SRAM, SRAM_SIZE, NULL, NULL);
_CloseHandle(dump);
}
void sram_restore() {
HANDLE dump = _CreateFileW(SRAM_DUMP, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (dump == INVALID_HANDLE_VALUE) return;
DWORD read;
if (!_ReadFile(dump, SRAM, SRAM_SIZE, &read, NULL))
log_error("sram", "failed to restore (%d)", GetLastError());
_CloseHandle(dump);
}
LPBYTE SRAM_DATA = NULL;
HANDLE SRAM_FILE = INVALID_HANDLE_VALUE;
HANDLE SRAM_FILE_MAPPING = INVALID_HANDLE_VALUE;
#define ADDR_BACKUP 0x0000
#define ADDR_HM_PEAK 0x0200
@ -33,43 +14,53 @@ void sram_restore() {
#define ADDR_ERROR_LOG 0x0600
#define ADDR_DUP 0x1000
#define fix_crc(block) \
do { \
#define fix_crc(block) \
do { \
(block).m_Crc = amiCrc32RCalc(sizeof(block) - 4, (BYTE*)(&(block)) + 4, 0); \
} while (0)
int build_sram() {
static BOOL built = false;
if (built) return 0;
built = true;
log_info(plfMxSram, "Building default SRAM file");
log_info("mxsram", "Building default SRAM file");
memset(SRAM_DATA, 0xff, SRAM_SIZE);
AM_SYSDATAwH_BACKUP Backup = { 0 };
fix_crc(Backup);
memcpy(SRAM + ADDR_BACKUP, (unsigned char*)&Backup, sizeof Backup);
memcpy(SRAM + ADDR_BACKUP + ADDR_DUP, (unsigned char*)&Backup, sizeof Backup);
memcpy(SRAM_DATA + ADDR_BACKUP, (unsigned char*)&Backup, sizeof Backup);
memcpy(SRAM_DATA + ADDR_BACKUP + ADDR_DUP, (unsigned char*)&Backup, sizeof Backup);
AM_SYSDATAwH_HM_PEAK HmPeak = { 0 };
fix_crc(HmPeak);
memcpy(SRAM + ADDR_HM_PEAK, (unsigned char*)&HmPeak, sizeof HmPeak);
memcpy(SRAM + ADDR_HM_PEAK + ADDR_DUP, (unsigned char*)&HmPeak, sizeof HmPeak);
memcpy(SRAM_DATA + ADDR_HM_PEAK, (unsigned char*)&HmPeak, sizeof HmPeak);
memcpy(SRAM_DATA + ADDR_HM_PEAK + ADDR_DUP, (unsigned char*)&HmPeak, sizeof HmPeak);
AM_SYSDATAwH_TIMEZONE Timezone = { 0 };
fix_crc(Timezone);
memcpy(SRAM + ADDR_TIMEZONE, (unsigned char*)&Timezone, sizeof Timezone);
memcpy(SRAM + ADDR_TIMEZONE + ADDR_DUP, (unsigned char*)&Timezone, sizeof Timezone);
memcpy(SRAM_DATA + ADDR_TIMEZONE, (unsigned char*)&Timezone, sizeof Timezone);
memcpy(SRAM_DATA + ADDR_TIMEZONE + ADDR_DUP, (unsigned char*)&Timezone, sizeof Timezone);
AM_SYSDATAwH_ERROR_LOG ErrorLog = { 0 };
fix_crc(ErrorLog);
memcpy(SRAM + ADDR_ERROR_LOG, (unsigned char*)&ErrorLog, sizeof ErrorLog);
memcpy(SRAM + ADDR_ERROR_LOG + ADDR_DUP, (unsigned char*)&ErrorLog, sizeof ErrorLog);
sram_dump();
memcpy(SRAM_DATA + ADDR_ERROR_LOG, (unsigned char*)&ErrorLog, sizeof ErrorLog);
memcpy(SRAM_DATA + ADDR_ERROR_LOG + ADDR_DUP, (unsigned char*)&ErrorLog, sizeof ErrorLog);
return 1;
}
void ensure_valid_sram() {
if (!SRAM_DATA) {
BOOL isNew = !FileExists(SRAM_PATH);
SRAM_DATA = open_mapped_file(SRAM_PATH, SRAM_SIZE, &SRAM_FILE, &SRAM_FILE_MAPPING);
if (SRAM_DATA == NULL) {
log_error(plfMxSram, "SRAM will be memory-backed and not syncronised!");
SRAM_DATA = malloc(SRAM_SIZE);
}
if (isNew) build_sram();
}
}
BOOL WINAPI mxsram_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOID lpInBuffer,
DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize,
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
@ -78,7 +69,7 @@ BOOL WINAPI mxsram_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
switch (dwIoControlCode) {
case IOCTL_MXSRAM_PING: // Get version
log_info("mxsram",
log_info(plfMxSram,
"DeviceIoControl(<mxsram>, <ping>, 0x%p, 0x%x, -, 0x%x, "
"-, -)",
lpInBuffer, nInBufferSize, nOutBufferSize);
@ -87,7 +78,7 @@ BOOL WINAPI mxsram_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
if (lpBytesReturned) *lpBytesReturned = 4;
break;
case IOCTL_DISK_GET_DRIVE_GEOMETRY:
log_info("mxsram",
log_info(plfMxSram,
"DeviceIoControl(<mxsram>, <get drive geom>, 0x%p, "
"0x%x, -, 0x%x, -, -)",
lpInBuffer, nInBufferSize, nOutBufferSize);
@ -102,10 +93,10 @@ BOOL WINAPI mxsram_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
if (lpBytesReturned) *lpBytesReturned = sizeof(DISK_GEOMETRY);
break;
case IOCTL_DISK_GET_LENGTH_INFO:
log_error("mxsram", "Unhandled IOCTL_DISK_GET_LENGTH_INFO");
log_error(plfMxSram, "Unhandled IOCTL_DISK_GET_LENGTH_INFO");
return FALSE;
case IOCTL_MXSRAM_GET_SECTOR_SIZE:
log_info("mxsram",
log_info(plfMxSram,
"DeviceIoControl(<mxsram>, <get sector size>, 0x%p, "
"0x%x, -, 0x%x, -, -)",
lpInBuffer, nInBufferSize, nOutBufferSize);
@ -114,7 +105,7 @@ BOOL WINAPI mxsram_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
if (lpBytesReturned) *lpBytesReturned = 4;
break;
default:
log_warning("mxsram", "unhandled 0x%08x", dwIoControlCode);
log_warning(plfMxSram, "unhandled 0x%08x", dwIoControlCode);
return FALSE;
}
@ -123,43 +114,31 @@ BOOL WINAPI mxsram_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
BOOL mxsram_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped) {
log_misc("mxsram", "sram write 0x%04x bytes at 0x%04x", nNumberOfBytesToWrite,
log_misc(plfMxSram, "sram write 0x%04x bytes at 0x%04x", nNumberOfBytesToWrite,
ctx->m_Pointer.LowPart);
if (ctx->m_Pointer.LowPart + nNumberOfBytesToWrite >= SRAM_SIZE) {
nNumberOfBytesToWrite = SRAM_SIZE - ctx->m_Pointer.LowPart;
}
memcpy(SRAM + ctx->m_Pointer.LowPart, lpBuffer, nNumberOfBytesToWrite);
sram_dump();
ensure_valid_sram();
memcpy(SRAM_DATA + ctx->m_Pointer.LowPart, lpBuffer, nNumberOfBytesToWrite);
*lpNumberOfBytesWritten = nNumberOfBytesToWrite;
return TRUE;
}
BOOL mxsram_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) {
log_misc("mxsram", "sram read 0x%04x bytes at 0x%04x", nNumberOfBytesToRead,
log_misc(plfMxSram, "sram read 0x%04x bytes at 0x%04x", nNumberOfBytesToRead,
ctx->m_Pointer.LowPart);
if (ctx->m_Pointer.LowPart + nNumberOfBytesToRead >= SRAM_SIZE) {
nNumberOfBytesToRead = SRAM_SIZE - ctx->m_Pointer.LowPart;
}
sram_restore();
memcpy((LPVOID)lpBuffer, SRAM + ctx->m_Pointer.LowPart, nNumberOfBytesToRead);
ensure_valid_sram();
memcpy((LPVOID)lpBuffer, SRAM_DATA + ctx->m_Pointer.LowPart, nNumberOfBytesToRead);
*lpNumberOfBytesRead = nNumberOfBytesToRead;
return TRUE;
}
void setup_mxsram() {
// Allocate 2MB of SRAM
SRAM = (LPBYTE)malloc(SRAM_SIZE);
if (!SRAM) {
log_error(BOOT_LOGGER, "unable to allocate 2MiB for SRAM");
exit(1);
}
memset(SRAM, 0xff, SRAM_SIZE);
if (FileExists(SRAM_DUMP))
sram_restore();
else
build_sram();
file_hook_t* mxsram = new_file_hook(L"\\\\.\\mxsram");
mxsram->DeviceIoControl = &mxsram_DeviceIoControl;
mxsram->ReadFile = &mxsram_ReadFile;

View File

@ -96,7 +96,7 @@ BYTE hwmon_read(superio_packet* packet) {
return w83791d_vbat_monitor_control;
default:
log_error("mxsuperio", "Unknown HM b0 register: read 0x%02x", reg);
log_error(plfMxSuperio, "Unknown HM b0 register: read 0x%02x", reg);
return 0xff;
}
} break;
@ -124,7 +124,7 @@ BYTE hwmon_read(superio_packet* packet) {
return W83791D_ENTITY_SYSTEM;
default:
log_error("mxsuperio", "Unknown HM b1 register: 0x%02x", reg);
log_error(plfMxSuperio, "Unknown HM b1 register: 0x%02x", reg);
exit(1);
}
} break;
@ -140,12 +140,12 @@ BYTE hwmon_read(superio_packet* packet) {
return 0xff;
default:
log_error("mxsuperio", "Unknown HM b5 register: 0x%02x", reg);
log_error(plfMxSuperio, "Unknown HM b5 register: 0x%02x", reg);
return 0xff;
}
} break;
default:
log_error("mxsuperio", "Unknown HM bank: 0x%02x", w83791d_bank);
log_error(plfMxSuperio, "Unknown HM bank: 0x%02x", w83791d_bank);
exit(1);
}
}
@ -197,7 +197,7 @@ void hwmon_write(superio_packet* packet) {
w83791d_vbat_monitor_control = packet->data;
break;
default:
log_error("mxsuperio", "Unknown HM b0 register: write 0x%02x", packet->reg);
log_error(plfMxSuperio, "Unknown HM b0 register: write 0x%02x", packet->reg);
// exit(1);
}
break;
@ -229,7 +229,7 @@ void hwmon_write(superio_packet* packet) {
break;
default:
log_error("mxsuperio", "Unknown HM b1 register: 0x%02x", packet->reg);
log_error(plfMxSuperio, "Unknown HM b1 register: 0x%02x", packet->reg);
exit(1);
}
} break;
@ -246,12 +246,12 @@ void hwmon_write(superio_packet* packet) {
break;
default:
log_error("mxsuperio", "Unknown HM b5 register: 0x%02x", packet->reg);
log_error(plfMxSuperio, "Unknown HM b5 register: 0x%02x", packet->reg);
return;
}
} break;
default:
log_error("mxsuperio", "Unknown HM bank: 0x%02x", w83791d_bank);
log_error(plfMxSuperio, "Unknown HM bank: 0x%02x", w83791d_bank);
exit(1);
}
}
@ -291,7 +291,7 @@ BOOL WINAPI mxsuperio_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode
//
}
W83627UHG_processed:
log_misc("mxsuperio", "read: chip:%d device:%d reg:%02x data:%02x", packet->chip,
log_misc(plfMxSuperio, "read: chip:%d device:%d reg:%02x data:%02x", packet->chip,
packet->device, packet->reg, packet->data);
break;
}
@ -299,7 +299,7 @@ BOOL WINAPI mxsuperio_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode
superio_lpc_packet* packet = (superio_lpc_packet*)(lpInBuffer);
if (lpBytesReturned) *lpBytesReturned = sizeof *packet;
log_misc("mxsuperio", "write: chip:%d device:%d reg:%02x data:%02x", packet->chip,
log_misc(plfMxSuperio, "write: chip:%d device:%d reg:%02x data:%02x", packet->chip,
packet->device, packet->reg, packet->data);
// TODO: Are there any writes we need to process?
@ -319,13 +319,13 @@ BOOL WINAPI mxsuperio_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode
} else {
lpc_out->data = 0xff;
}
log_misc("mxsuperio", "amHmLpcReadByte Index=0x%02x Reg=0x%02x Data=0x%02x",
log_misc(plfMxSuperio, "amHmLpcReadByte Index=0x%02x Reg=0x%02x Data=0x%02x",
lpc_packet->index, lpc_packet->reg, lpc_out->data);
if (lpBytesReturned) *lpBytesReturned = sizeof *lpc_out;
} break;
case IOCTL_MXSUPERIO_HWMONITOR_LPC_WRITE: {
log_misc("mxsuperio", "amHmLpcWriteByte Index=0x%02x Reg=0x%02x Data=0x%02b",
log_misc(plfMxSuperio, "amHmLpcWriteByte Index=0x%02x Reg=0x%02x Data=0x%02b",
lpc_packet->index, lpc_packet->reg, lpc_packet->data);
if (lpc_packet->index == LPC_CONFIGURATION) {
@ -334,7 +334,7 @@ BOOL WINAPI mxsuperio_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode
if (lpBytesReturned) *lpBytesReturned = 0;
} break;
default:
log_warning("mxsuperio", "unhandled 0x%08x", dwIoControlCode);
log_warning(plfMxSuperio, "unhandled 0x%08x", dwIoControlCode);
return FALSE;
}

102
src/micetools/dll/games.c Normal file
View File

@ -0,0 +1,102 @@
#include "common.h"
#include "devices/_devices.h"
#include "key_config.h"
#define IS_GAME(match) (strncmp(game_id, #match, 4) == 0)
void mice_got_game_id(char game_id[4]) {
static char last_game_id[4] = { '_', '_', '_', '_' };
if (memcmp(game_id, last_game_id, 4) == 0) return;
memcpy(last_game_id, game_id, 4);
if (!MiceConfig.devices.do_auto) return;
if (IS_GAME(SBRZ /* maimai */) || IS_GAME(SBXL /* maimai [PLUS] */) ||
IS_GAME(SBZF /* maimai GreeN [PLUS] */) || IS_GAME(SDBM /* maimai ORANGE [PLUS] */) ||
IS_GAME(SDCQ /* maimai PiNK [PLUS] */) || IS_GAME(SDDK /* maimai MURASAKi [PLUS] */) ||
IS_GAME(SDDZ /* maimai MiLK [PLUS] */) || IS_GAME(SDEY /* maimai FiNALE */) ||
IS_GAME(SBYC /* maimai china */)) {
log_info(plfBoot, "Detect game MaiMai");
MiceConfig.devices.com1 = "";
MiceConfig.devices.com2 = "aime_tn32msec";
MiceConfig.devices.com3 = "maitouch";
MiceConfig.devices.com4 = "";
MiceConfig.devices.com5 = "";
MiceConfig.devices.com6 = "mailed";
MiceConfig.devices.com7 = "";
MiceConfig.devices.com8 = "mailed";
if (MiceConfig.keys.board_count == 0) MiceConfig.keys.board_count = 1;
if (!jvsKeybindings[0].notdefault) {
// Zero and invert all buttons
memset(&jvsKeybindings[0].buttons[3 * 2], 0, 12 * 2);
memset(&jvsKeybindings[0].invert[3 * 2], 1, 12 * 2);
// Setup default keybinds
jvsKeybindings[0].buttons[6 * 2] = 'A'; // 1P1
jvsKeybindings[0].buttons[5 * 2] = 'Q'; // 1P2
jvsKeybindings[0].buttons[8 * 2] = 'W'; // 1P3
jvsKeybindings[0].buttons[9 * 2] = 'E'; // 1P4
jvsKeybindings[0].buttons[10 * 2] = 'D'; // 1P5
jvsKeybindings[0].buttons[11 * 2] = 'C'; // 1P6
jvsKeybindings[0].buttons[12 * 2] = 'X'; // 1P7
jvsKeybindings[0].buttons[13 * 2] = 'Z'; // 1P8
jvsKeybindings[0].buttons[6 * 2 + 1] = VK_NUMPAD4; // 2P1
jvsKeybindings[0].buttons[5 * 2 + 1] = VK_NUMPAD7; // 2P2
jvsKeybindings[0].buttons[8 * 2 + 1] = VK_NUMPAD8; // 2P3
jvsKeybindings[0].buttons[9 * 2 + 1] = VK_NUMPAD9; // 2P4
jvsKeybindings[0].buttons[10 * 2 + 1] = VK_NUMPAD6; // 2P5
jvsKeybindings[0].buttons[11 * 2 + 1] = VK_NUMPAD3; // 2P6
jvsKeybindings[0].buttons[12 * 2 + 1] = VK_NUMPAD2; // 2P7
jvsKeybindings[0].buttons[13 * 2 + 1] = VK_NUMPAD1; // 2P8
}
} else if (IS_GAME(SBYG /* APM2 */)) {
log_info(plfBoot, "Detect game APM2");
MiceConfig.devices.com1 = "";
MiceConfig.devices.com2 = "";
MiceConfig.devices.com3 = "";
MiceConfig.devices.com4 = "";
MiceConfig.devices.com5 = "";
MiceConfig.devices.com6 = "";
MiceConfig.devices.com7 = "";
MiceConfig.devices.com8 = "";
if (MiceConfig.keys.board_count == 0) MiceConfig.keys.board_count = 1;
if (!jvsKeybindings[0].notdefault) {
puts("!!");
// Zero all buttons
memset(&jvsKeybindings[0].buttons[3 * 2], 0, 12 * 2);
memset(&jvsKeybindings[0].invert[3 * 2], 0, 12 * 2);
jvsKeybindings[0].buttons[1 * 2] = VK_TAB;
jvsKeybindings[0].buttons[3 * 2] = VK_UP;
jvsKeybindings[0].buttons[4 * 2] = VK_DOWN;
jvsKeybindings[0].buttons[5 * 2] = VK_LEFT;
jvsKeybindings[0].buttons[6 * 2] = VK_RIGHT;
jvsKeybindings[0].buttons[7 * 2] = 'Q';
jvsKeybindings[0].buttons[8 * 2] = 'W';
jvsKeybindings[0].buttons[9 * 2] = 'E';
jvsKeybindings[0].buttons[10 * 2] = 'A';
jvsKeybindings[0].buttons[11 * 2] = 'S';
jvsKeybindings[0].buttons[12 * 2] = 'D';
// 2P is unbound by default, as a (nice) keymap with both
// will probably also involve changing 1P too.
}
} else {
log_warning(plfBoot, "Unknown game ID: %.4s", game_id);
return;
}
save_current_config();
start_devices();
}

View File

@ -157,8 +157,9 @@ void hud_sram(ImGuiKey open_key) {
if (igIsKeyPressed_Bool(open_key, false)) editor.Open = !editor.Open;
// TODO: Less hacky :)
extern LPBYTE SRAM;
if (editor.Open) MemoryEditor_DrawWindow(&editor, "SRAM Editor", SRAM, 1024 * 1024, 0x0000);
extern LPBYTE SRAM_DATA;
if (editor.Open)
MemoryEditor_DrawWindow(&editor, "SRAM Editor", SRAM_DATA, 1024 * 1024, 0x0000);
}
void igHelpMarker(const char* text) {
@ -733,6 +734,7 @@ void AddSettingButton(int board, int id) {
if (igKeyBindPopup(name, &boundKey)) {
if (boundKey != -1) {
jvsKeybindings[board].buttons[id * 2 + (currentlyBinding - 1)] = boundKey;
jvsKeybindings[board].notdefault = 1;
save_current_config();
}
currentlyBinding = 0;
@ -890,7 +892,7 @@ void tab_main_keybinds() {
}
void hud_control(ImGuiKey open_key) {
static bool isOpen = true;
static bool isOpen = false;
static bool oldCursor;
if (igIsKeyPressed_Bool(open_key, false)) {
isOpen = !isOpen;
@ -938,7 +940,6 @@ void hud_control(ImGuiKey open_key) {
}
void __stdcall hud_gui(unsigned int hookType, IDirect3DDevice9* dev) {
static bool showMenu = false;
ShowCursor(1);
static bool initialized = false;

View File

@ -28,34 +28,34 @@ com_hook_t* new_com_hook(BYTE port) {
BOOL WINAPI FakeGetCommState(HANDLE hFile, LPDCB lpDCB) {
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
log_misc(COMM_LOGGER, "GetCommState(0x%p, 0x%p) (%08x)", hFile, lpDCB, hook);
log_misc(plfComm, "GetCommState(0x%p, 0x%p) (%08x)", hFile, lpDCB, hook);
if (pHData == NULL || pHData->hook->com_hook == NULL) return TrueGetCommState(hFile, lpDCB);
com_hook_t* com_hook = pHData->hook->com_hook;
if (com_hook->GetCommState == NULL) {
log_error(COMM_LOGGER, "GetCommState(%ls) unimplemented", com_hook->wName);
log_error(plfComm, "GetCommState(%ls) unimplemented", com_hook->wName);
return FALSE;
}
return com_hook->GetCommState(hFile, lpDCB);
}
BOOL WINAPI FakeSetCommState(HANDLE hFile, LPDCB lpDCB) {
log_misc(COMM_LOGGER, "SetCommState(0x%p, 0x%p)", hFile, lpDCB);
log_misc(plfComm, "SetCommState(0x%p, 0x%p)", hFile, lpDCB);
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
if (pHData == NULL || pHData->hook->com_hook == NULL) return TrueSetCommState(hFile, lpDCB);
com_hook_t* com_hook = pHData->hook->com_hook;
if (com_hook->SetCommState == NULL) {
log_error(COMM_LOGGER, "SetCommState(%ls) unimplemented", com_hook->wName);
log_error(plfComm, "SetCommState(%ls) unimplemented", com_hook->wName);
return FALSE;
}
return com_hook->SetCommState(hFile, lpDCB);
}
BOOL WINAPI FakeGetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) {
log_misc(COMM_LOGGER, "GetCommTimeouts(0x%p, 0x%p)", hFile, lpCommTimeouts);
log_misc(plfComm, "GetCommTimeouts(0x%p, 0x%p)", hFile, lpCommTimeouts);
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
if (pHData == NULL || pHData->hook->com_hook == NULL)
@ -63,14 +63,14 @@ BOOL WINAPI FakeGetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) {
com_hook_t* com_hook = pHData->hook->com_hook;
if (com_hook->GetCommTimeouts == NULL) {
log_error(COMM_LOGGER, "GetCommTimeouts(%ls) unimplemented", com_hook->wName);
log_error(plfComm, "GetCommTimeouts(%ls) unimplemented", com_hook->wName);
return FALSE;
}
return com_hook->GetCommTimeouts(hFile, lpCommTimeouts);
}
BOOL WINAPI FakeSetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) {
log_misc(COMM_LOGGER, "SetCommTimeouts(0x%p, 0x%p)", hFile, lpCommTimeouts);
log_misc(plfComm, "SetCommTimeouts(0x%p, 0x%p)", hFile, lpCommTimeouts);
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
if (pHData == NULL || pHData->hook->com_hook == NULL)
@ -78,14 +78,14 @@ BOOL WINAPI FakeSetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) {
com_hook_t* com_hook = pHData->hook->com_hook;
if (com_hook->SetCommTimeouts == NULL) {
log_error(COMM_LOGGER, "SetCommTimeouts(%ls) unimplemented", com_hook->wName);
log_error(plfComm, "SetCommTimeouts(%ls) unimplemented", com_hook->wName);
return FALSE;
}
return com_hook->SetCommTimeouts(hFile, lpCommTimeouts);
}
BOOL WINAPI FakeSetupComm(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue) {
log_misc(COMM_LOGGER, "SetupCom(0x%p, 0x%08x, 0x%08x)", hFile, dwInQueue, dwOutQueue);
log_misc(plfComm, "SetupCom(0x%p, 0x%08x, 0x%08x)", hFile, dwInQueue, dwOutQueue);
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
if (pHData == NULL || pHData->hook->com_hook == NULL)
@ -93,28 +93,28 @@ BOOL WINAPI FakeSetupComm(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue) {
com_hook_t* com_hook = pHData->hook->com_hook;
if (com_hook->SetupComm == NULL) {
log_error(COMM_LOGGER, "SetupComm(%ls) unimplemented", com_hook->wName);
log_error(plfComm, "SetupComm(%ls) unimplemented", com_hook->wName);
return FALSE;
}
return com_hook->SetupComm(hFile, dwInQueue, dwOutQueue);
}
BOOL WINAPI FakePurgeComm(HANDLE hFile, DWORD dwFlags) {
log_misc(COMM_LOGGER, "PurgeComm(0x%p, 0x%08x)", hFile, dwFlags);
log_misc(plfComm, "PurgeComm(0x%p, 0x%08x)", hFile, dwFlags);
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
if (pHData == NULL || pHData->hook->com_hook == NULL) return TruePurgeComm(hFile, dwFlags);
com_hook_t* com_hook = pHData->hook->com_hook;
if (com_hook->PurgeComm == NULL) {
log_error(COMM_LOGGER, "PurgeComm(%ls) unimplemented", com_hook->wName);
log_error(plfComm, "PurgeComm(%ls) unimplemented", com_hook->wName);
return FALSE;
}
return com_hook->PurgeComm(hFile, dwFlags);
}
BOOL WINAPI FakeGetCommModemStatus(HANDLE hFile, LPDWORD lpModelStat) {
log_misc(COMM_LOGGER, "GetCommModemStatus(0x%p, 0x%p)", hFile, lpModelStat);
log_misc(plfComm, "GetCommModemStatus(0x%p, 0x%p)", hFile, lpModelStat);
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
if (pHData == NULL || pHData->hook->com_hook == NULL)
@ -122,14 +122,14 @@ BOOL WINAPI FakeGetCommModemStatus(HANDLE hFile, LPDWORD lpModelStat) {
com_hook_t* com_hook = pHData->hook->com_hook;
if (com_hook->GetCommModemStatus == NULL) {
log_error(COMM_LOGGER, "GetCommModemStatus(%ls) unimplemented", com_hook->wName);
log_error(plfComm, "GetCommModemStatus(%ls) unimplemented", com_hook->wName);
return FALSE;
}
return com_hook->GetCommModemStatus(hFile, lpModelStat);
}
BOOL WINAPI FakeWaitCommEvent(HANDLE hFile, LPDWORD lpEvtMask, LPOVERLAPPED lpOverlapped) {
log_misc(COMM_LOGGER, "WaitCommEvent(0x%p)", hFile);
log_misc(plfComm, "WaitCommEvent(0x%p)", hFile);
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
if (pHData == NULL || pHData->hook->com_hook == NULL)
@ -137,14 +137,14 @@ BOOL WINAPI FakeWaitCommEvent(HANDLE hFile, LPDWORD lpEvtMask, LPOVERLAPPED lpOv
com_hook_t* com_hook = pHData->hook->com_hook;
if (com_hook->WaitCommEvent == NULL) {
log_error(COMM_LOGGER, "WaitCommEvent(%ls) unimplemented", com_hook->wName);
log_error(plfComm, "WaitCommEvent(%ls) unimplemented", com_hook->wName);
return FALSE;
}
return com_hook->WaitCommEvent(hFile, lpEvtMask, lpOverlapped);
}
BOOL WINAPI FakeClearCommError(HANDLE hFile, LPDWORD lpErrors, LPCOMSTAT lpStat) {
log_trace(COMM_LOGGER, "ClearCommError(0x%p)", hFile);
log_trace(plfComm, "ClearCommError(0x%p)", hFile);
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
if (pHData == NULL || pHData->hook->com_hook == NULL)
@ -152,7 +152,7 @@ BOOL WINAPI FakeClearCommError(HANDLE hFile, LPDWORD lpErrors, LPCOMSTAT lpStat)
com_hook_t* com_hook = pHData->hook->com_hook;
if (com_hook->ClearCommError == NULL) {
log_error(COMM_LOGGER, "ClearCommError(%ls) unimplemented", com_hook->wName);
log_error(plfComm, "ClearCommError(%ls) unimplemented", com_hook->wName);
return FALSE;
}
return com_hook->ClearCommError(hFile, lpErrors, lpStat);

View File

@ -49,21 +49,21 @@ BOOL ReadFunc_Original0(DWORD nOffset, LPVOID lpBuffer, DWORD nNumberOfBytesToRe
LPDWORD lpNumberOfBytesRead) {
*lpNumberOfBytesRead = 0;
if (!_PathFileExistsA(ORIGINAL0_PATH)) {
log_error("drive", "Failed to open %s (does not exist)", ORIGINAL0_PATH);
log_error(plfDrive, "Failed to open %s (does not exist)", ORIGINAL0_PATH);
return FALSE;
}
HANDLE hFile =
_CreateFileA(ORIGINAL0_PATH, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
log_error("drive", "Failed to open %s", ORIGINAL0_PATH);
log_error(plfDrive, "Failed to open %s", ORIGINAL0_PATH);
return FALSE;
}
LARGE_INTEGER seekTo;
seekTo.QuadPart = (LONGLONG)nOffset * (LONGLONG)SSD.m_BlockSize;
_SetFilePointerEx(hFile, seekTo, NULL, FILE_BEGIN);
BOOL ret = _ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, NULL);
if (!ret) log_error("drive", "Failed to read to %s: %03x", ORIGINAL0_PATH, GetLastError());
if (!ret) log_error(plfDrive, "Failed to read to %s: %03x", ORIGINAL0_PATH, GetLastError());
_CloseHandle(hFile);
return ret;
}
@ -74,14 +74,14 @@ BOOL WriteFunc_Original0(DWORD nOffset, LPCVOID lpBuffer, DWORD nNumberOfBytesTo
HANDLE hFile =
_CreateFileA(ORIGINAL0_PATH, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
log_error("drive", "Failed to open %s", ORIGINAL0_PATH);
log_error(plfDrive, "Failed to open %s", ORIGINAL0_PATH);
return FALSE;
}
LARGE_INTEGER seekTo;
seekTo.QuadPart = (LONGLONG)nOffset * (LONGLONG)SSD.m_BlockSize;
_SetFilePointerEx(hFile, seekTo, NULL, FILE_BEGIN);
BOOL ret = _WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, NULL);
if (!ret) log_error("drive", "Failed to write to %s: %03x", ORIGINAL0_PATH, GetLastError());
if (!ret) log_error(plfDrive, "Failed to write to %s: %03x", ORIGINAL0_PATH, GetLastError());
_CloseHandle(hFile);
return ret;
}
@ -90,21 +90,21 @@ BOOL ReadFunc_Patch0(DWORD nOffset, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead) {
*lpNumberOfBytesRead = 0;
if (!_PathFileExistsA(PATCH0_PATH)) {
log_error("drive", "Failed to open %s (does not exist)", PATCH0_PATH);
log_error(plfDrive, "Failed to open %s (does not exist)", PATCH0_PATH);
return FALSE;
}
HANDLE hFile =
_CreateFileA(PATCH0_PATH, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
log_error("drive", "Failed to open %s", PATCH0_PATH);
log_error(plfDrive, "Failed to open %s", PATCH0_PATH);
return FALSE;
}
LARGE_INTEGER seekTo;
seekTo.QuadPart = (LONGLONG)nOffset * (LONGLONG)SSD.m_BlockSize;
_SetFilePointerEx(hFile, seekTo, NULL, FILE_BEGIN);
BOOL ret = _ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, NULL);
if (!ret) log_error("drive", "Failed to read to %s: %03x", PATCH0_PATH, GetLastError());
if (!ret) log_error(plfDrive, "Failed to read to %s: %03x", PATCH0_PATH, GetLastError());
_CloseHandle(hFile);
return ret;
}
@ -115,14 +115,14 @@ BOOL WriteFunc_Patch0(DWORD nOffset, LPCVOID lpBuffer, DWORD nNumberOfBytesToWri
HANDLE hFile =
_CreateFileA(PATCH0_PATH, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
log_error("drive", "Failed to open %s", PATCH0_PATH);
log_error(plfDrive, "Failed to open %s", PATCH0_PATH);
return FALSE;
}
LARGE_INTEGER seekTo;
seekTo.QuadPart = (LONGLONG)nOffset * (LONGLONG)SSD.m_BlockSize;
_SetFilePointerEx(hFile, seekTo, NULL, FILE_BEGIN);
BOOL ret = _WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, NULL);
if (!ret) log_error("drive", "Failed to write to %s: %03x", PATCH0_PATH, GetLastError());
if (!ret) log_error(plfDrive, "Failed to write to %s: %03x", PATCH0_PATH, GetLastError());
_CloseHandle(hFile);
return ret;
}
@ -130,7 +130,7 @@ BOOL WriteFunc_Patch0(DWORD nOffset, LPCVOID lpBuffer, DWORD nNumberOfBytesToWri
BOOL WriteFunc_OS(DWORD nOffset, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten) {
*lpNumberOfBytesWritten = nNumberOfBytesToWrite;
log_warning("drive", "%d bytes write in OS at %08x", nNumberOfBytesToWrite, nOffset);
log_warning(plfDrive, "%d bytes write in OS at %08x", nNumberOfBytesToWrite, nOffset);
return TRUE;
}
BOOL ReadFunc_OSLogFiles(DWORD nOffset, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
@ -165,13 +165,13 @@ BOOL ReadFunc_OSLogFiles(DWORD nOffset, LPVOID lpBuffer, DWORD nNumberOfBytesToR
return TRUE;
}
if (nOffset == 2048) {
log_warning("drive", "Requsted %d bytes of application log file", nNumberOfBytesToRead);
log_warning(plfDrive, "Requsted %d bytes of application log file", nNumberOfBytesToRead);
ZeroMemory(lpBuffer, nNumberOfBytesToRead);
*lpNumberOfBytesRead = nNumberOfBytesToRead;
return TRUE;
}
if (nOffset == 2048 + 1024) {
log_warning("drive", "Requsted %d bytes of system log file", nNumberOfBytesToRead);
log_warning(plfDrive, "Requsted %d bytes of system log file", nNumberOfBytesToRead);
ZeroMemory(lpBuffer, nNumberOfBytesToRead);
*lpNumberOfBytesRead = nNumberOfBytesToRead;
return TRUE;
@ -184,7 +184,7 @@ BOOL ReadFunc_OSLogFiles(DWORD nOffset, LPVOID lpBuffer, DWORD nNumberOfBytesToR
BOOL WINAPI c_drive_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOID lpInBuffer,
DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize,
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
log_trace("C", "DeviceIOControl %08x", dwIoControlCode);
log_trace(plfDrive, "C:DeviceIOControl %08x", dwIoControlCode);
ZeroMemory(lpOutBuffer, nOutBufferSize);
switch (dwIoControlCode) {
case IOCTL_STORAGE_GET_DEVICE_NUMBER:
@ -203,7 +203,7 @@ BOOL WINAPI c_drive_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode,
BOOL WINAPI x_drive_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOID lpInBuffer,
DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize,
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
log_trace("X", "DeviceIOControl %08x", dwIoControlCode);
log_trace(plfDrive, "X:DeviceIOControl %08x", dwIoControlCode);
ZeroMemory(lpOutBuffer, nOutBufferSize);
switch (dwIoControlCode) {
case IOCTL_STORAGE_GET_DEVICE_NUMBER:
@ -211,7 +211,7 @@ BOOL WINAPI x_drive_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode,
((STORAGE_DEVICE_NUMBER*)lpOutBuffer)->DeviceNumber = 0;
return TRUE;
default:
log_warning("X", "Unhandled DeviceIOControl %08x", dwIoControlCode);
log_warning(plfDrive, "X:Unhandled DeviceIOControl %08x", dwIoControlCode);
return FALSE;
}
}
@ -219,7 +219,7 @@ BOOL WINAPI x_drive_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode,
BOOL WINAPI q_drive_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOID lpInBuffer,
DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize,
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
log_trace("Q", "DeviceIOControl %08x", dwIoControlCode);
log_trace(plfDrive, "Q:DeviceIOControl %08x", dwIoControlCode);
ZeroMemory(lpOutBuffer, nOutBufferSize);
switch (dwIoControlCode) {
case IOCTL_STORAGE_MEDIA_REMOVAL:
@ -229,7 +229,7 @@ BOOL WINAPI q_drive_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode,
((PDISK_GEOMETRY)lpOutBuffer)->BytesPerSector = ALPHA_DVD.m_BlockSize;
return TRUE;
default:
log_warning("Q", "Unhandled DeviceIOControl %08x", dwIoControlCode);
log_warning(plfDrive, "Q:Unhandled DeviceIOControl %08x", dwIoControlCode);
return FALSE;
}
}
@ -380,7 +380,7 @@ inline static BOOL matchVolume(disk_volume_t* volume, LPCSTR lpRootPathName, DWO
disk_volume_t* getVolumeByPath(LPCSTR lpRootPathName, DWORD match) {
if (lpRootPathName == NULL) {
log_error("file", "getVolumeByPath(NULL) unimplemented!");
log_error(plfDrive, "getVolumeByPath(NULL) unimplemented!");
return FALSE;
}
@ -403,7 +403,7 @@ BOOL WINAPI volume_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
disk_volume_t* volume = (disk_volume_t*)ctx->m_HookData;
if (volume == NULL) {
log_error("drive", "ctx->m_HookData NULL; expected a volume!");
log_error(plfDrive, "ctx->m_HookData NULL; expected a volume!");
return FALSE;
}
@ -435,7 +435,7 @@ BOOL WINAPI volume_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
if (queryIn->PropertyId != StorageDeviceProperty ||
queryIn->QueryType != PropertyStandardQuery) {
log_error("drive", "Unimplemented storage query: %d/%d", queryIn->PropertyId,
log_error(plfDrive, "Unimplemented storage query: %d/%d", queryIn->PropertyId,
queryIn->QueryType);
return FALSE;
}
@ -467,7 +467,7 @@ BOOL WINAPI volume_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
}
return TRUE;
default:
log_error("drive", "Unimplemented IOCTL: %08x", dwIoControlCode);
log_error(plfDrive, "Unimplemented IOCTL: %08x", dwIoControlCode);
return FALSE;
}
}
@ -481,7 +481,7 @@ void init_volume(disk_volume_t* vol) {
StringFromGUID2(&guid, volume_name + 10, MAX_PATH + 1 - 10);
file_hook_t* volume_hook = new_file_hook(volume_name);
log_misc("disk", "Creating fake volume: %ls", volume_name);
log_misc(plfDrive, "Creating fake volume: %ls", volume_name);
volume_hook->DeviceIoControl = &volume_DeviceIoControl;
volume_hook->hook_data = (void*)vol;
@ -519,7 +519,7 @@ void init_pd(physical_disk_t* pd) {
pd->m_BlockSize = BLOCK_SIZE_CDROM;
break;
default:
log_error("disk", "Unable to guess block size for drive %d", pd->m_DriveNumber);
log_error(plfDrive, "Unable to guess block size for drive %d", pd->m_DriveNumber);
break;
}
}
@ -544,7 +544,7 @@ void init_pd(physical_disk_t* pd) {
pd->m_DriveNumber);
break;
default:
log_error("disk", "Unable to set DeviceName for drive %d (type: %d)",
log_error(plfDrive, "Unable to set DeviceName for drive %d (type: %d)",
pd->m_DriveNumber, pd->m_DiskType);
break;
}
@ -580,7 +580,7 @@ void init_pd(physical_disk_t* pd) {
DWORD extendedPartNo = 0;
if (pd->m_Extended[0].m_Size) {
if (partitionNumber == 5) {
log_error("drive", "Fatal: Too many paritions in drive %d!", pd->m_DriveNumber);
log_error(plfDrive, "Fatal: Too many paritions in drive %d!", pd->m_DriveNumber);
exit(1);
}
pd->m_Partitions[partitionNumber - 1].m_Filesystem = MBR_FS_EXT_LBA;
@ -660,7 +660,7 @@ void init_all_pd() {
BOOL q_drive_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) {
log_game("q", "CDROM read 0x%04x bytes at 0x%08x", nNumberOfBytesToRead,
log_game(plfDrive, "Q:CDROM read 0x%04x bytes at 0x%08x", nNumberOfBytesToRead,
ctx->m_Pointer.QuadPart);
/**
@ -680,7 +680,7 @@ BOOL q_drive_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytes
HANDLE hFile = _CreateFileA("H:\\Arcades\\Images\\ALLNet_Pras_Multi_Ver2\\DVR-0069A.iso", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
log_error("q", "READ FAILED. FILE FALLBACK FAILED. %d", GetLastError());
log_error(plfDrive, "Q:READ FAILED. FILE FALLBACK FAILED. %d", GetLastError());
return FALSE;
}
@ -688,7 +688,7 @@ BOOL q_drive_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytes
_ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
_CloseHandle(hFile);
log_warning("q", "READ FAILED. FILE FALLBACK (Read %d bytes).", *lpNumberOfBytesRead);
log_warning(plfDrive, "Q:READ FAILED. FILE FALLBACK (Read %d bytes).", *lpNumberOfBytesRead);
return TRUE;
}
@ -744,11 +744,11 @@ void hook_drives() {
hFile =
_CreateFileA(SBR0_PATH, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
log_error("drive", "Failed to open %s", SBR0_PATH);
log_error(plfDrive, "Failed to open %s", SBR0_PATH);
} else {
_ReadFile(hFile, &SegaBootRecord0, sizeof SegaBootRecord0, &numberOfBytesRead, NULL);
_CloseHandle(hFile);
log_info("drive", "Restored SBR0 from %s", SBR0_PATH);
log_info(plfDrive, "Restored SBR0 from %s", SBR0_PATH);
}
} else {
// memcpy(&SegaBootRecord0, &SegaBootRecordDefault, sizeof SegaBootRecord0);
@ -758,11 +758,11 @@ void hook_drives() {
hFile =
_CreateFileA(SBR1_PATH, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
log_error("drive", "Failed to open %s", SBR1_PATH);
log_error(plfDrive, "Failed to open %s", SBR1_PATH);
} else {
_ReadFile(hFile, &SegaBootRecord1, sizeof SegaBootRecord1, &numberOfBytesRead, NULL);
_CloseHandle(hFile);
log_info("drive", "Restored SBR1 from %s", SBR0_PATH);
log_info(plfDrive, "Restored SBR1 from %s", SBR0_PATH);
}
} else {
memcpy(&SegaBootRecord1, &SegaBootRecord0, sizeof SegaBootRecord0);

View File

@ -128,7 +128,7 @@ BOOL WINAPI FakeSetVolumeLabelA(LPCSTR lpRootPathName, LPCSTR lpVolumeName) {
}
BOOL WINAPI FakeGetVolumeNameForVolumeMountPointA(LPCSTR lpszVolumeMountPoint, LPSTR lpszVolumeName,
DWORD cchBufferLength) {
log_trace("drive", "GetVolumeNameForVolumeMountPointA(%s)", lpszVolumeMountPoint);
log_trace(plfDrive, "GetVolumeNameForVolumeMountPointA(%s)", lpszVolumeMountPoint);
disk_volume_t* volume = getVolumeByPath(lpszVolumeMountPoint, VOL_MATCH_PATH);
if (volume == NULL) {
@ -141,7 +141,7 @@ BOOL WINAPI FakeGetVolumeNameForVolumeMountPointA(LPCSTR lpszVolumeMountPoint, L
}
BOOL WINAPI FakeGetVolumePathNamesForVolumeNameA(LPCSTR lpszVolumeName, LPCH lpszVolumePathNames,
DWORD cchBufferLength, PDWORD lpcchReturnLength) {
log_trace("drive", "GetVolumeNameForVolumeMountPointA(%s)", lpszVolumeName);
log_trace(plfDrive, "GetVolumeNameForVolumeMountPointA(%s)", lpszVolumeName);
disk_volume_t* volume = getVolumeByPath(lpszVolumeName, VOL_MATCH_GUID);
if (volume == NULL) {
@ -164,7 +164,7 @@ BOOL WINAPI FakeGetVolumePathNamesForVolumeNameA(LPCSTR lpszVolumeName, LPCH lps
return TRUE;
}
BOOL WINAPI FakeDeleteVolumeMountPointA(LPCSTR lpszVolumeMountPoint) {
log_trace("drive", "DeleteVolumeMountPointA(%s)", lpszVolumeMountPoint);
log_trace(plfDrive, "DeleteVolumeMountPointA(%s)", lpszVolumeMountPoint);
disk_volume_t* volume = getVolumeByPath(lpszVolumeMountPoint, VOL_MATCH_PATH);
if (volume == NULL) {
SetLastError(ERROR_FILE_NOT_FOUND);
@ -175,7 +175,7 @@ BOOL WINAPI FakeDeleteVolumeMountPointA(LPCSTR lpszVolumeMountPoint) {
return TRUE;
}
BOOL WINAPI FakeSetVolumeMountPointA(LPCSTR lpszVolumeMountPoint, LPCSTR lpszVolumeName) {
log_trace("drive", "SetVolumeMountPointA(%s)", lpszVolumeMountPoint);
log_trace(plfDrive, "SetVolumeMountPointA(%s)", lpszVolumeMountPoint);
disk_volume_t* volume = getVolumeByPath(lpszVolumeName, VOL_MATCH_GUID);
if (volume == NULL) {
SetLastError(ERROR_FILE_NOT_FOUND);
@ -186,12 +186,12 @@ BOOL WINAPI FakeSetVolumeMountPointA(LPCSTR lpszVolumeMountPoint, LPCSTR lpszVol
DWORD nScan;
if (sscanf_s(lpszVolumeMountPoint, "\\\\.\\%c:%n", &cMountPoint, 1, &nScan) == 1 &&
nScan == 6) {
log_info("drive", "Mounting %s at %c:\\", volume->m_Name, cMountPoint);
log_info(plfDrive, "Mounting %s at %c:\\", volume->m_Name, cMountPoint);
volume->m_MountPoint = cMountPoint;
return TRUE;
}
if (sscanf_s(lpszVolumeMountPoint, "%c:\\%n", &cMountPoint, 1, &nScan) == 1 && nScan == 3) {
log_info("drive", "Mounting %s at %c:\\", volume->m_Name, cMountPoint);
log_info(plfDrive, "Mounting %s at %c:\\", volume->m_Name, cMountPoint);
volume->m_MountPoint = cMountPoint;
return TRUE;
}
@ -224,7 +224,7 @@ MCIERROR WINAPI Fake_mciSendStringA(LPCTSTR lpszCommand, LPTSTR lpszReturnString
return 0;
}
if (strcmp(lpszCommand, "set cdaudio door open") == 0) {
log_game("mci", "Cupholder opened!");
log_game(plfDrive, "mci:Cupholder opened!");
return 0;
}
if (strcmp(lpszCommand, "status cdaudio media present") == 0) {

View File

@ -5,11 +5,11 @@ BOOL WINAPI pd_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOI
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
physical_disk_t* pd = (physical_disk_t*)ctx->m_HookData;
if (pd == NULL) {
log_error("drive", "ioctl:ctx->m_HookData NULL; expected a physical drive!");
log_error(plfDrive, "ioctl:ctx->m_HookData NULL; expected a physical drive!");
return FALSE;
}
log_trace("drive", "DeviceIOControl %08x", dwIoControlCode);
log_trace(plfDrive, "DeviceIOControl %08x", dwIoControlCode);
ZeroMemory(lpOutBuffer, nOutBufferSize);
switch (dwIoControlCode) {
case IOCTL_ATA_PASS_THROUGH:
@ -36,7 +36,7 @@ BOOL WINAPI pd_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOI
}
if (command != 0xC1) {
log_error("pd0", "Unimplemented ATA command: %02x", command);
log_error(plfDrive, "PD0:Unimplemented ATA command: %02x", command);
return FALSE;
}
@ -62,7 +62,7 @@ BOOL WINAPI pd_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOI
// as long as the ioctl succeeds! Saves us a lot of work here!
return TRUE;
}
log_error("drive", "Unimeplemented ATA C1 command: %02x", data);
log_error(plfDrive, "Unimeplemented ATA C1 command: %02x", data);
return FALSE;
case IOCTL_DISK_GET_LENGTH_INFO:
PGET_LENGTH_INFORMATION pLi = (PGET_LENGTH_INFORMATION)lpOutBuffer;
@ -70,7 +70,7 @@ BOOL WINAPI pd_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOI
*lpBytesReturned = sizeof *pLi;
return TRUE;
}
log_error("drive", "Unimplemented ioctl: %08x", dwIoControlCode);
log_error(plfDrive, "Unimplemented ioctl: %08x", dwIoControlCode);
return FALSE;
}
@ -78,11 +78,11 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) {
physical_disk_t* pd = (physical_disk_t*)ctx->m_HookData;
if (pd == NULL) {
log_error("drive", "read:ctx->m_HookData NULL; expected a physical drive!");
log_error(plfDrive, "read:ctx->m_HookData NULL; expected a physical drive!");
return FALSE;
}
log_misc("drive", "PhysicalDrive%d: Read %d @ %llx", pd->m_DriveNumber, nNumberOfBytesToRead,
log_misc(plfDrive, "PhysicalDrive%d: Read %d @ %llx", pd->m_DriveNumber, nNumberOfBytesToRead,
ctx->m_Pointer.QuadPart);
// ! WARNING: This ReadFile implementation is currently limited to aligned
@ -95,7 +95,7 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
if (ptrLBA == 0) {
mbr_t* mbr = (mbr_t*)lpBuffer;
if (nNumberOfBytesToRead < sizeof *mbr) {
log_error("drive", "Buffer too small for master boot record!");
log_error(plfDrive, "Buffer too small for master boot record!");
return FALSE;
}
@ -119,7 +119,7 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
}
if (ptrLBA <= MBR_LBA_GAP) {
// Read within the 63 extra tracks
log_error("drive", "Read failed");
log_error(plfDrive, "Read failed");
return FALSE;
}
@ -132,19 +132,19 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
DWORD readOffset = ptrLBA - pd->m_Partitions[i].m_PhysicalLBA;
if (pd->m_Partitions[i].m_ReadFunc == NULL) {
log_error("disk", "Attempted read in %d/%d at block offset %08x; No read function",
log_error(plfDrive, "Attempted read in %d/%d at block offset %08x; No read function",
pd->m_DriveNumber, pd->m_Partitions[i].m_PartitionNumber, readOffset);
return FALSE;
}
BOOL ret = pd->m_Partitions[i].m_ReadFunc(readOffset, lpBuffer, nNumberOfBytesToRead,
lpNumberOfBytesRead);
if (!ret) {
log_error("disk", "Attempted read in %d/%d at block offset %08x; Read rejected",
log_error(plfDrive, "Attempted read in %d/%d at block offset %08x; Read rejected",
pd->m_DriveNumber, pd->m_Partitions[i].m_PartitionNumber, readOffset);
return FALSE;
}
log_misc("drive", "Read at %d/%d+%d", pd->m_DriveNumber,
log_misc(plfDrive, "Read at %d/%d+%d", pd->m_DriveNumber,
pd->m_Partitions[i].m_PartitionNumber, readOffset);
return TRUE;
}
@ -157,7 +157,7 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
if (ptrLBA == headerLBA) {
mbr_t* mbr = (mbr_t*)lpBuffer;
if (nNumberOfBytesToRead < sizeof *mbr) {
log_error("drive", "Buffer too small for an extended boot record!");
log_error(plfDrive, "Buffer too small for an extended boot record!");
return FALSE;
}
@ -188,7 +188,7 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
if (ptrLBA == headerLBA + SPD_OFFSET) {
spd_t* spd = (spd_t*)lpBuffer;
if (nNumberOfBytesToRead < sizeof *spd) {
log_error("drive", "Buffer too small for SPD!");
log_error(plfDrive, "Buffer too small for SPD!");
return FALSE;
}
@ -207,7 +207,7 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
// SEGA Boot Record 0 and 1. The two are a redundant copy of each other
if (ptrLBA == headerLBA + SBR0_OFFSET) {
if (nNumberOfBytesToRead < sizeof SegaBootRecord0) {
log_error("drive", "Buffer too small for SBR0!");
log_error(plfDrive, "Buffer too small for SBR0!");
return FALSE;
}
memcpy(lpBuffer, &SegaBootRecord0, sizeof SegaBootRecord0);
@ -216,7 +216,7 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
}
if (ptrLBA == headerLBA + SBR1_OFFSET) {
if (nNumberOfBytesToRead < sizeof SegaBootRecord1) {
log_error("drive", "Buffer too small for SBR1!");
log_error(plfDrive, "Buffer too small for SBR1!");
return FALSE;
}
memcpy(lpBuffer, &SegaBootRecord1, sizeof SegaBootRecord1);
@ -228,7 +228,7 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
if (ptrLBA >= pd->m_Extended[i].m_PhysicalLBA - EXT_HEADER_GAP &&
ptrLBA < pd->m_Extended[i].m_PhysicalLBA) {
// Read within the 63 extra tracks
log_error("drive", "Read failed");
log_error(plfDrive, "Read failed");
return FALSE;
}
@ -237,25 +237,25 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
DWORD readOffset = ptrLBA - pd->m_Extended[i].m_PhysicalLBA;
if (pd->m_Extended[i].m_ReadFunc == NULL) {
log_error("disk", "Attempted read in %d/%d at block offset %08x; No read function",
log_error(plfDrive, "Attempted read in %d/%d at block offset %08x; No read function",
pd->m_DriveNumber, pd->m_Extended[i].m_PartitionNumber, readOffset);
return FALSE;
}
BOOL ret = pd->m_Extended[i].m_ReadFunc(readOffset, lpBuffer, nNumberOfBytesToRead,
lpNumberOfBytesRead);
if (!ret) {
log_error("disk", "Attempted read in %d/%d at block offset %08x; Read rejected",
log_error(plfDrive, "Attempted read in %d/%d at block offset %08x; Read rejected",
pd->m_DriveNumber, pd->m_Extended[i].m_PartitionNumber, readOffset);
return FALSE;
}
log_misc("drive", "Read at %d/%d+%d", pd->m_DriveNumber,
log_misc(plfDrive, "Read at %d/%d+%d", pd->m_DriveNumber,
pd->m_Extended[i].m_PartitionNumber, readOffset);
return TRUE;
}
}
log_error("drive", "Read failed");
log_error(plfDrive, "Read failed");
return FALSE;
}
@ -265,11 +265,11 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
physical_disk_t* pd = (physical_disk_t*)ctx->m_HookData;
if (pd == NULL) {
log_error("drive", "write:ctx->m_HookData NULL; expected a physical drive!");
log_error(plfDrive, "write:ctx->m_HookData NULL; expected a physical drive!");
return FALSE;
}
log_misc("drive", "PhysicalDrive%d: Write %d @ %llx", pd->m_DriveNumber, nNumberOfBytesToWrite,
log_misc(plfDrive, "PhysicalDrive%d: Write %d @ %llx", pd->m_DriveNumber, nNumberOfBytesToWrite,
ctx->m_Pointer.QuadPart);
// for (DWORD i = 0; i < nNumberOfBytesToWrite; i += 32) {
@ -290,7 +290,7 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
// Writes to the MBR header or slack are blocked
if (ptrLBA <= MBR_LBA_GAP) {
log_error("drive", "Write rejected");
log_error(plfDrive, "Write rejected");
return FALSE;
}
@ -303,7 +303,7 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
DWORD writeOffset = ptrLBA - pd->m_Partitions[i].m_PhysicalLBA;
if (pd->m_Partitions[i].m_WriteFunc == NULL) {
log_error("disk",
log_error(plfDrive,
"Attempted write in %d/%d at block offset %08x; No write function",
pd->m_DriveNumber, pd->m_Partitions[i].m_PartitionNumber, writeOffset);
return FALSE;
@ -311,12 +311,12 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
BOOL ret = pd->m_Partitions[i].m_WriteFunc(writeOffset, lpBuffer, nNumberOfBytesToWrite,
lpNumberOfBytesWritten);
if (!ret) {
log_error("disk", "Attempted write in %d/%d at block offset %08x; Write rejected",
log_error(plfDrive, "Attempted write in %d/%d at block offset %08x; Write rejected",
pd->m_DriveNumber, pd->m_Partitions[i].m_PartitionNumber, writeOffset);
return FALSE;
}
log_misc("drive", "Write at %d/%d+%d", pd->m_DriveNumber,
log_misc(plfDrive, "Write at %d/%d+%d", pd->m_DriveNumber,
pd->m_Partitions[i].m_PartitionNumber, writeOffset);
return TRUE;
}
@ -327,7 +327,7 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
// Extended header
DWORD headerLBA = pd->m_Extended[i].m_PhysicalLBA - EXT_HEADER_GAP;
if (ptrLBA == headerLBA) {
log_error("drive", "Write to extended header rejected");
log_error(plfDrive, "Write to extended header rejected");
return FALSE;
}
@ -335,13 +335,13 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
// SEGA Partition Description
if (ptrLBA == headerLBA + SPD_OFFSET) {
if (nNumberOfBytesToWrite < sizeof(spd_t)) {
log_error("drive", "Buffer too small for SPD!");
log_error(plfDrive, "Buffer too small for SPD!");
return FALSE;
}
HANDLE hFile = _CreateFileA(SPD_PATH, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
OPEN_ALWAYS, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
log_error("drive", "Failed to open %s", SPD_PATH);
log_error(plfDrive, "Failed to open %s", SPD_PATH);
return FALSE;
}
BOOL ret = _WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite,
@ -352,13 +352,13 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
// SEGA Boot Records
if (ptrLBA == headerLBA + SBR0_OFFSET) {
if (nNumberOfBytesToWrite < sizeof(sbr_t)) {
log_error("drive", "Buffer too small for SBR!");
log_error(plfDrive, "Buffer too small for SBR!");
return FALSE;
}
HANDLE hFile = _CreateFileA(SBR0_PATH, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
OPEN_ALWAYS, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
log_error("drive", "Failed to open %s", SBR0_PATH);
log_error(plfDrive, "Failed to open %s", SBR0_PATH);
return FALSE;
}
BOOL ret = _WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite,
@ -368,13 +368,13 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
}
if (ptrLBA == headerLBA + SBR1_OFFSET) {
if (nNumberOfBytesToWrite < sizeof(sbr_t)) {
log_error("drive", "Buffer too small for SBR!");
log_error(plfDrive, "Buffer too small for SBR!");
return FALSE;
}
HANDLE hFile = _CreateFileA(SBR1_PATH, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
OPEN_ALWAYS, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
log_error("drive", "Failed to open %s", SBR1_PATH);
log_error(plfDrive, "Failed to open %s", SBR1_PATH);
return FALSE;
}
BOOL ret = _WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite,
@ -387,7 +387,7 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
if (ptrLBA >= pd->m_Extended[i].m_PhysicalLBA - EXT_HEADER_GAP &&
ptrLBA < pd->m_Extended[i].m_PhysicalLBA) {
// Write within the 63 extra tracks
log_error("drive", "Write failed");
log_error(plfDrive, "Write failed");
return FALSE;
}
@ -396,7 +396,7 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
DWORD writeOffset = ptrLBA - pd->m_Extended[i].m_PhysicalLBA;
if (pd->m_Extended[i].m_WriteFunc == NULL) {
log_error("disk",
log_error(plfDrive,
"Attempted write in %d/%d at block offset %08x; No write function",
pd->m_DriveNumber, pd->m_Extended[i].m_PartitionNumber, writeOffset);
return FALSE;
@ -404,14 +404,16 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
BOOL ret = pd->m_Extended[i].m_WriteFunc(writeOffset, lpBuffer, nNumberOfBytesToWrite,
lpNumberOfBytesWritten);
if (!ret) {
log_error("disk", "Attempted write in %d/%d at block offset %08x; Write rejected",
log_error(plfDrive, "Attempted write in %d/%d at block offset %08x; Write rejected",
pd->m_DriveNumber, pd->m_Extended[i].m_PartitionNumber, writeOffset);
return FALSE;
}
log_misc("drive", "Write at %d/%d+%d", pd->m_DriveNumber,
log_misc(plfDrive, "Write at %d/%d+%d", pd->m_DriveNumber,
pd->m_Extended[i].m_PartitionNumber, writeOffset);
return TRUE;
}
}
return FALSE;
}

View File

@ -133,7 +133,7 @@ BOOL redirect_path(LPCSTR path, LPCSTR* redirected) {
for (int i = 0; i < sizeof DRIVE_REDIRECT_TABLE / sizeof DRIVE_REDIRECT_TABLE[0]; i++) {
drive_redirect_t row = DRIVE_REDIRECT_TABLE[i];
if (PathPrefix(path, row.drive)) {
log_trace(HOOKS_LOGGER, "Redirecting '%s' to '%s'", path, row.path);
log_trace(plfHooks, "Redirecting '%s' to '%s'", path, row.path);
size_t new_len = strlen(path) - strlen(row.drive) + strlen(row.path);
strcpy_s(_redirected_path, new_len + 1, row.path);
@ -144,7 +144,7 @@ BOOL redirect_path(LPCSTR path, LPCSTR* redirected) {
for (; len > 0; len--) (dst++)[0] = (src++)[0];
dst[0] = 0;
log_trace(HOOKS_LOGGER, "New filename: '%s'", _redirected_path);
log_trace(plfHooks, "New filename: '%s'", _redirected_path);
make_dirs(_redirected_path);
*redirected = _redirected_path;
@ -184,7 +184,7 @@ HANDLE WINAPI FakeCreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD d
file_hook_t* found_fh = find_hook(lpFileName);
if (found_fh != NULL) {
HANDLE handle = open_hook(found_fh);
log_info(HOOKS_LOGGER, "CreateFileW(%ls) -> 0x%p", lpFileName, handle);
log_info(plfHooks, "CreateFileW(%ls) -> 0x%p", lpFileName, handle);
return handle;
}
@ -194,11 +194,11 @@ HANDLE WINAPI FakeCreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD d
if (redirect_path_w(lpFileName, &redirected)) {
handle = TrueCreateFileA(redirected, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
log_misc(HOOKS_LOGGER, "CreateFileW(%s) -> 0x%p", redirected, handle);
log_misc(plfHooks, "CreateFileW(%s) -> 0x%p", redirected, handle);
} else {
handle = TrueCreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
log_misc(HOOKS_LOGGER, "CreateFileW(%ls) -> 0x%p", lpFileName, handle);
log_misc(plfHooks, "CreateFileW(%ls) -> 0x%p", lpFileName, handle);
}
return handle;
@ -213,25 +213,25 @@ HANDLE WINAPI FakeCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dw
file_hook_t* found_fh = find_hook(wideFileName);
if (found_fh != NULL) {
HANDLE handle = open_hook(found_fh);
log_info(HOOKS_LOGGER, "CreateFileA(%s) -> 0x%p", lpFileName, handle);
log_info(plfHooks, "CreateFileA(%s) -> 0x%p", lpFileName, handle);
return handle;
}
redirect_path(lpFileName, &lpFileName);
HANDLE handle = TrueCreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
log_misc(HOOKS_LOGGER, "CreateFileA(%s) -> 0x%p", lpFileName, handle);
log_misc(plfHooks, "CreateFileA(%s) -> 0x%p", lpFileName, handle);
return handle;
}
BOOL WINAPI FakePathFileExistsA(LPCSTR pszPath) {
log_misc(HOOKS_LOGGER, "PathFileExists(%s)", pszPath);
log_misc(plfHooks, "PathFileExists(%s)", pszPath);
redirect_path(pszPath, &pszPath);
BOOL ret = TruePathFileExistsA(pszPath);
return ret;
}
BOOL WINAPI FakePathFileExistsW(LPCWSTR pszPath) {
log_misc(HOOKS_LOGGER, "PathFileExists(%ls)", pszPath);
log_misc(plfHooks, "PathFileExists(%ls)", pszPath);
LPCSTR redirected;
if (redirect_path_w(pszPath, &redirected)) {
return TruePathFileExistsA(redirected);
@ -259,7 +259,7 @@ BOOL WINAPI FakeDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lp
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
open_hook_t* pHData = GetDataForHandle(hDevice, HDATA_FILE);
if (pHData == NULL) {
// log_trace(HOOKS_LOGGER, "DeviceIoControl(0x%p, 0x%08x, 0x%p, 0x%x, -, 0x%x, 0, 0)", hDevice,
// log_trace(plfHooks, "DeviceIoControl(0x%p, 0x%08x, 0x%p, 0x%x, -, 0x%x, 0, 0)", hDevice,
// dwIoControlCode, lpInBuffer, nInBufferSize, nOutBufferSize);
return TrueDeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer,
@ -268,7 +268,7 @@ BOOL WINAPI FakeDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lp
file_hook_t* file_hook = pHData->hook;
if (!file_hook->DeviceIoControl) {
log_error(HOOKS_LOGGER, "DeviceIoControl(%ls) unimplemented", file_hook->filename);
log_error(plfHooks, "DeviceIoControl(%ls) unimplemented", file_hook->filename);
return FALSE;
}
@ -297,7 +297,7 @@ DWORD WINAPI FakeSetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDist
pHData->ctx.m_Pointer.HighPart = 0;
pHData->ctx.m_Pointer.LowPart = lDistanceToMove;
} else if (dwMoveMethod == FILE_END) {
log_error("files", "FILE_END unimplemented");
log_error(plfFile, "FILE_END unimplemented");
return 0xFFFFFFFF;
} else {
if (lpDistanceToMoveHigh) pHData->ctx.m_Pointer.HighPart += *lpDistanceToMoveHigh;
@ -314,7 +314,7 @@ BOOL WINAPI FakeSetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove,
if (dwMoveMethod == FILE_BEGIN) {
pHData->ctx.m_Pointer = liDistanceToMove;
} else if (dwMoveMethod == FILE_END) {
log_error("files", "FILE_END unimplemented");
log_error(plfFile, "FILE_END unimplemented");
return FALSE;
} else {
pHData->ctx.m_Pointer.QuadPart += liDistanceToMove.QuadPart;
@ -334,7 +334,7 @@ DWORD WINAPI FakeGetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize) {
}
file_hook_t* file_hook = pHData->hook;
if (!file_hook->GetFileSizeEx) {
log_error(HOOKS_LOGGER, "GetFileSizeEx(%ls) unimplemented", file_hook->filename);
log_error(plfHooks, "GetFileSizeEx(%ls) unimplemented", file_hook->filename);
return FALSE;
}
return file_hook->GetFileSizeEx(&(pHData->ctx), lpFileSize);
@ -355,7 +355,7 @@ DWORD WINAPI FakeWriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesT
file_hook_t* file_hook = pHData->hook;
if (!file_hook->WriteFile) {
log_error(HOOKS_LOGGER, "WriteFile(%ls) unimplemented", file_hook->filename);
log_error(plfHooks, "WriteFile(%ls) unimplemented", file_hook->filename);
return FALSE;
}
BOOL ret = file_hook->WriteFile(&(pHData->ctx), lpBuffer, nNumberOfBytesToWrite,
@ -370,7 +370,7 @@ BOOL WINAPI FakeReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRe
return TrueReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead,
lpOverlapped);
}
// log_misc(HOOKS_LOGGER, "ReadFile(%d) %d", hFile, nNumberOfBytesToRead);
// log_misc(plfHooks, "ReadFile(%d) %d", hFile, nNumberOfBytesToRead);
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
if (pHData == NULL) {
@ -381,7 +381,7 @@ BOOL WINAPI FakeReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRe
file_hook_t* file_hook = pHData->hook;
if (!file_hook->ReadFile) {
log_error(HOOKS_LOGGER, "ReadFile(%ls) unimplemented", file_hook->filename);
log_error(plfHooks, "ReadFile(%ls) unimplemented", file_hook->filename);
return FALSE;
}
BOOL ret = file_hook->ReadFile(&(pHData->ctx), lpBuffer, nNumberOfBytesToRead,

View File

@ -148,7 +148,7 @@ void post_win_create(HWND hWnd) {
}
if (hWnd && !SetWindowSubclass(hWnd, WndProc, (int)&WndProc, (DWORD_PTR)NULL)) {
log_error("gui", "failed to SetWindowSubclass(%d)", GetLastError());
log_error(plfGUI, "failed to SetWindowSubclass(%d)", GetLastError());
}
}
}
@ -282,19 +282,19 @@ HRESULT STDMETHODCALLTYPE FakeCreateDevice(IDirect3D9* this, UINT Adapter, D3DDE
if (res != S_OK) {
switch (res) {
case D3DERR_DEVICELOST:
log_error("D3D9", "CreateDevice failed: Device lost");
log_error(plfD3D9, "CreateDevice failed: Device lost");
break;
case D3DERR_INVALIDCALL:
log_error("D3D9", "CreateDevice failed: Invalid call");
log_error(plfD3D9, "CreateDevice failed: Invalid call");
break;
case D3DERR_NOTAVAILABLE:
log_error("D3D9", "CreateDevice failed: Requested configuration not available");
log_error(plfD3D9, "CreateDevice failed: Requested configuration not available");
break;
case D3DERR_OUTOFVIDEOMEMORY:
log_error("D3D9", "CreateDevice failed: VMem exhausted");
log_error(plfD3D9, "CreateDevice failed: VMem exhausted");
break;
default:
log_error("D3D9", "CreateDevice failed: %08x", res);
log_error(plfD3D9, "CreateDevice failed: %08x", res);
break;
}
}

View File

@ -29,7 +29,7 @@ int WINAPIV Fakeprintf(const char* _Format, ...) {
va_list args;
va_start(args, _Format);
int ret = vlog_game("printf", _Format, args);
int ret = vlog_game(plfPrintf, _Format, args);
va_end(args);
return ret;
@ -45,7 +45,7 @@ int WINAPIV Fakefprintf(FILE* _File, const char* _Format, ...) {
va_list args;
va_start(args, _Format);
int ret = vlog_game("fprintf", _Format, args);
int ret = vlog_game(plfFprintf, _Format, args);
va_end(args);
return ret;
@ -55,13 +55,13 @@ int WINAPIV Fakefprintf_s(FILE* _Stream, const char* _Format, ...) {
va_list args;
va_start(args, _Format);
int ret = vlog_game("fprintf_s", _Format, args);
int ret = vlog_game(plfFprintf_s, _Format, args);
va_end(args);
return ret;
}
int WINAPIV Fakevfprintf_s(FILE* _Stream, const char* _Format, va_list _ArgList) {
return vlog_game("vfprintf_s", _Format, _ArgList);
return vlog_game(plfVfprintf_s, _Format, _ArgList);
}
HANDLE WINAPI FakeRegisterEventSourceA(LPCSTR lpUNCServerName, LPCSTR lpSourceName) {
return (HANDLE)0xDEADBEEF;
@ -74,21 +74,21 @@ BOOL WINAPI FakeReportEventA(HANDLE hEventLog, WORD wType, WORD wCategory, DWORD
case EVENTLOG_SUCCESS:
case EVENTLOG_AUDIT_SUCCESS:
for (int i = 0; i < wNumStrings; i++)
log_misc("evtlog", trim_string((char*)lpStrings[i]));
log_misc(plfEvtlog, trim_string((char*)lpStrings[i]));
break;
case EVENTLOG_AUDIT_FAILURE:
case EVENTLOG_ERROR_TYPE:
for (int i = 0; i < wNumStrings; i++)
log_error("evtlog", trim_string((char*)lpStrings[i]));
log_error(plfEvtlog, trim_string((char*)lpStrings[i]));
break;
case EVENTLOG_WARNING_TYPE:
for (int i = 0; i < wNumStrings; i++)
log_warning("evtlog", trim_string((char*)lpStrings[i]));
log_warning(plfEvtlog, trim_string((char*)lpStrings[i]));
break;
case EVENTLOG_INFORMATION_TYPE:
default:
for (int i = 0; i < wNumStrings; i++)
log_info("evtlog", trim_string((char*)lpStrings[i]));
log_info(plfEvtlog, trim_string((char*)lpStrings[i]));
break;
}
return TRUE;

View File

@ -5,8 +5,8 @@ int WINAPI Fake_connect(SOCKET s, const SOCKADDR* name, int namelen) {
USHORT port = _byteswap_ushort(((SOCKADDR_IN*)name)->sin_port);
// Poorly exclude nxauth. TODO: better
if (port != 40190) {
log_info("connect", "%hhu.%hhu.%hhu.%hhu:%hu", (addr >> 24) & 0xff, (addr >> 16) & 0xff,
(addr >> 8) & 0xff, addr & 0xff, port);
log_info(plfNetwork, "connect(%hhu.%hhu.%hhu.%hhu:%hu)", (addr >> 24) & 0xff,
(addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff, port);
}
return True_connect(s, name, namelen);
}
@ -14,7 +14,7 @@ int WINAPI Fake_connect(SOCKET s, const SOCKADDR* name, int namelen) {
int WINAPI Fake_bind(SOCKET s, const SOCKADDR* name, int namelen) {
ULONG addr = _byteswap_ulong(((SOCKADDR_IN*)name)->sin_addr.S_un.S_addr);
USHORT port = _byteswap_ushort(((SOCKADDR_IN*)name)->sin_port);
log_info("bind", "%hhu.%hhu.%hhu.%hhu:%hu", (addr >> 24) & 0xff, (addr >> 16) & 0xff,
log_info(plfNetwork, "bind(%hhu.%hhu.%hhu.%hhu:%hu)", (addr >> 24) & 0xff, (addr >> 16) & 0xff,
(addr >> 8) & 0xff, addr & 0xff, port);
return True_bind(s, name, namelen);
}
@ -25,7 +25,7 @@ int WINAPI Fake_bind(SOCKET s, const SOCKADDR* name, int namelen) {
#define MAC_PREFIX_1 0xBB
#define MAC_PREFIX_2 0xC1
DWORD WINAPI FakeGetIfTable(PMIB_IFTABLE pIfTable, PULONG pdwSize, BOOL bOrder) {
log_info("network", "Injecting fake IfTable");
log_info(plfNetwork, "Injecting fake IfTable");
MIB_IFROW* row;
uint32_t nbytes;
@ -100,7 +100,8 @@ DNS_STATUS WINAPI FakeDnsQuery_A(PCSTR pszName, WORD wType, DWORD Options, PVOID
if (strcmp(pszName, INTERCEPT_DNS[i].name) == 0) {
printf("%08x\n", MiceConfig.network.naominet_jp);
log_info("dns", "Replacing %s with %08x", pszName, *INTERCEPT_DNS[i].address);
log_info(plfNetwork, "DNS Replacing %s with %08x", pszName,
*INTERCEPT_DNS[i].address);
// We only support replacing at most one address, but that's all we'll ever need to!
(*ppQueryResults) = &dummy_record;
@ -112,17 +113,17 @@ DNS_STATUS WINAPI FakeDnsQuery_A(PCSTR pszName, WORD wType, DWORD Options, PVOID
}
}
}
log_warning("dns", "DNS passthrough for %s", pszName);
log_warning(plfNetwork, "DNS passthrough for %s", pszName);
return TrueDnsQuery_A(pszName, wType, Options, pExtra, ppQueryResults, pReserved);
};
INT WSAAPI FakeWSAStringToAddressA(LPSTR AddressString, INT AddressFamily,
LPWSAPROTOCOL_INFOA lpProtocolInfo, LPSOCKADDR lpAddress,
LPINT lpAddressLength) {
log_misc("dns", "(WSA)DNS lookup for %s", AddressString);
log_misc(plfNetwork, "WSA DNS lookup for %s", AddressString);
for (size_t i = 0; i < sizeof INTERCEPT_DNS / sizeof INTERCEPT_DNS[0]; i++) {
if (strcmp(AddressString, INTERCEPT_DNS[i].name) == 0) {
log_info("dns", "(WSA)Replacing %s with %08x", AddressString,
log_info(plfNetwork, "WSA DNS Replacing %s with %08x", AddressString,
*INTERCEPT_DNS[i].address);
lpAddress->sa_family = AF_INET;
@ -133,14 +134,64 @@ INT WSAAPI FakeWSAStringToAddressA(LPSTR AddressString, INT AddressFamily,
return ERROR_SUCCESS;
}
}
log_warning("dns", "(WSA)DNS passthrough for %s", AddressString);
log_warning(plfNetwork, "WSA DNS passthrough for %s", AddressString);
return TrueWSAStringToAddressA(AddressString, AddressFamily, lpProtocolInfo, lpAddress,
lpAddressLength);
}
int __stdcall Fake_socket(int domain, int type, int protocol) {
int sock = True_socket(domain, type, protocol);
log_trace(plfNetwork, "Creating new socket: %d/%s/%d -> %d", domain,
type == 1 ? "SOCK_STREAM"
: type == 2 ? "SOCK_DGRAM"
: type == 3 ? "SOCK_RAW"
: type == 4 ? "SOCK_RDM"
: type == 5 ? "SOCK_SEQPACKET"
: "Unknown",
protocol, sock);
return sock;
}
static struct sockaddr pingSentTo;
static unsigned char pingInfo[4];
static struct sockaddr_in toLocalhost = {
.sin_addr = 0x0100007f,
.sin_family = AF_INET,
.sin_port = 24,
.sin_zero = 0,
};
int __stdcall Fake_sendto(SOCKET s, const char* buf, int len, int flags, const struct sockaddr* to,
int tolen) {
// Hardcoded ICMP4 ping "detection"
// TODO: Only do this if the socket is using the ICMP protocol
if (len == 8 && buf[0] == 0x08 && buf[1] == 0x00) {
uint32_t addr = ((struct sockaddr_in*)to)->sin_addr.S_un.S_addr;
memcpy(&pingSentTo, to, sizeof pingSentTo);
uint16_t seq = _byteswap_ushort(((uint16_t*)buf)[3]);
memcpy(pingInfo, buf + 4, 4);
memcpy(&toLocalhost, to, sizeof toLocalhost);
toLocalhost.sin_addr.S_un.S_addr = 0x0100007f; // 127.0.0.1
to = &toLocalhost;
log_warning(plfNetwork, "(probable) Ping to: %d.%d.%d.%d (%d). Redirecting to localhost",
addr & 0xff, (addr >> 8) & 0xff, (addr >> 16) & 0xff, addr >> 24,
((struct sockaddr_in*)to)->sin_port, seq);
}
return True_sendto(s, buf, len, flags, to, tolen);
}
void hook_network() {
hook("Ws2_32.dll", "connect", Fake_connect, (void**)&True_connect);
hook("Ws2_32.dll", "socket", Fake_socket, (void**)&True_socket);
hook("Ws2_32.dll", "bind", Fake_bind, (void**)&True_bind);
hook("Ws2_32.dll", "sendto", Fake_sendto, (void**)&True_sendto);
hook("Ws2_32.dll", "WSAStringToAddressA", FakeWSAStringToAddressA,
(void**)&TrueWSAStringToAddressA);
hook("Iphlpapi.dll", "GetIfTable", FakeGetIfTable, (void**)&TrueGetIfTable);

View File

@ -1,15 +1,19 @@
#pragma once
#include "../common.h"
static int(WINAPI* True_socket)(int domain, int type, int protocol);
static int(WINAPI* True_connect)(SOCKET s, const SOCKADDR* name, int namelen);
static int(WINAPI* True_bind)(SOCKET s, const SOCKADDR* addr, int namelen);
static int(WINAPI* True_sendto)(SOCKET s, const char* buf, int len, int flags,
const struct sockaddr* to, int tolen);
static DWORD(WINAPI* TrueGetIfTable)(PMIB_IFTABLE pIfTable, PULONG pdwSize, BOOL bOrder);
static DNS_STATUS(WINAPI* TrueDnsQuery_A)(PCSTR pszName, WORD wType, DWORD Options, PVOID pExtra,
PDNS_RECORDA* ppQueryResults, PVOID* pReserved);
static INT(WSAAPI* TrueWSAStringToAddressA)(LPSTR AddressString, INT AddressFamily, LPWSAPROTOCOL_INFOA lpProtocolInfo,
static INT(WSAAPI* TrueWSAStringToAddressA)(LPSTR AddressString, INT AddressFamily,
LPWSAPROTOCOL_INFOA lpProtocolInfo,
LPSOCKADDR lpAddress, LPINT lpAddressLength);
void hook_network();

View File

@ -14,7 +14,7 @@ BOOL WINAPI FakeCreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine,
DWORD dwCreationFlags, LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation) {
log_info("spawn", "CreateProcessA %s %s", lpApplicationName, lpCommandLine);
log_info(plfProcesses, "CreateProcessA %s %s", lpApplicationName, lpCommandLine);
return TrueCreateProcessA("mxAuthDisc.bat", "", lpProcessAttributes,
lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
@ -35,12 +35,12 @@ BOOL WINAPI FakeCreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine,
LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation) {
// #ifdef DISABLE_PROC_SPAWNING
// log_error("spawn", "CreateProcessW %ls %ls", lpApplicationName, lpCommandLine);
// log_error(plfProcesses, "CreateProcessW %ls %ls", lpApplicationName, lpCommandLine);
// return FALSE;
// #else
log_info("spawn", "CreateProcessW %ls %ls", lpApplicationName, lpCommandLine);
log_info(plfProcesses, "CreateProcessW %ls %ls", lpApplicationName, lpCommandLine);
// log_info("spawn", "CreateProcessW %ls", lpApplicationName);
// log_info(plfProcesses, "CreateProcessW %ls", lpApplicationName);
// lpProcessInformation->hThread = GetDummyHandle();
// return TRUE;
@ -66,7 +66,7 @@ BOOL WINAPI FakeCreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine,
return TRUE;
if (lpCommandLine != NULL) {
log_error("process", "!!");
log_error(plfProcesses, "!!");
return FALSE;
// WideCharToMultiByte(CP_ACP, 0, lpCommandLine, -1, commandLine, sizeof commandLine, NULL,
// NULL);

View File

@ -1,28 +1,28 @@
#include "registry.h"
LSTATUS WINAPI FakeRegCloseKey(HKEY hKey) {
log_trace("registry", "RegCloseKey %08x", hKey);
log_trace(plfRegistry, "RegCloseKey %08x", hKey);
return ERROR_SUCCESS;
}
LSTATUS WINAPI FakeRegCreateKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass,
DWORD dwOptions, REGSAM samDesired,
const LPSECURITY_ATTRIBUTES lpSecurityAttributes,
PHKEY phkResult, LPDWORD lpdwDisposition) {
log_trace("registry", "RegCreateKeyExA %08x %s", hKey, lpSubKey);
log_trace(plfRegistry, "RegCreateKeyExA %08x %s", hKey, lpSubKey);
return ERROR_SUCCESS;
}
LSTATUS WINAPI FakeRegDeleteKeyA(HKEY hKey, LPCSTR lpSubKey) {
log_trace("registry", "RegDeleteKeyA %08x %s", hKey, lpSubKey);
log_trace(plfRegistry, "RegDeleteKeyA %08x %s", hKey, lpSubKey);
return ERROR_SUCCESS;
}
LSTATUS WINAPI FakeRegDeleteKeyValueA(HKEY hKey, LPCSTR lpSubKey, LPCSTR lpValueName) {
log_trace("registry", "RegDeleteKeyValueA %08x %s %s", hKey, lpSubKey, lpValueName);
log_trace(plfRegistry, "RegDeleteKeyValueA %08x %s %s", hKey, lpSubKey, lpValueName);
return ERROR_SUCCESS;
}
LSTATUS WINAPI FakeRegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcchName,
LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcchClass,
PFILETIME lpftLastWriteTime) {
log_trace("registry", "RegEnumKeyExA %08x[%d]", hKey, dwIndex);
log_trace(plfRegistry, "RegEnumKeyExA %08x[%d]", hKey, dwIndex);
if (dwIndex == 0) {
strcpy(lpName, "Direct3D HAL");
return ERROR_SUCCESS;
@ -32,7 +32,7 @@ LSTATUS WINAPI FakeRegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD
LSTATUS WINAPI FakeRegEnumValueA(HKEY hKey, DWORD dwIndex, LPSTR lpValueName,
LPDWORD lpcchValueName, LPDWORD lpReserved, LPDWORD lpType,
LPBYTE lpData, LPDWORD lpcbData) {
log_trace("registry", "RegEnumValueA %08x %s", hKey, lpValueName);
log_trace(plfRegistry, "RegEnumValueA %08x %s", hKey, lpValueName);
return ERROR_NO_MORE_ITEMS;
}

View File

@ -16,20 +16,20 @@ BOOL add_fake_device(const GUID* guid, const WCHAR* path) {
}
HDEVINFO WINAPI FakeSetupDiGetClassDevsA(const GUID* ClassGuid, PCWSTR Enumerator, HWND hwndParent, DWORD Flags) {
log_misc("setupapi", "SetupDiGetClassDevsA(%p, %s, %d, %d)", ClassGuid, Enumerator, hwndParent, Flags);
log_misc(plfSetupAPI, "SetupDiGetClassDevsA(%p, %s, %d, %d)", ClassGuid, Enumerator, hwndParent, Flags);
HDEVINFO res = TrueSetupDiGetClassDevsA(ClassGuid, Enumerator, hwndParent, Flags);
if (res != INVALID_HANDLE_VALUE && ClassGuid != NULL) {
FAKE_DEVICE* device = fake_devices;
while (device != NULL) {
if (memcmp(device->guid, ClassGuid, sizeof(*ClassGuid)) == 0) {
log_misc("setupapi", "injecting %ls into class devs list", device->path);
log_misc(plfSetupAPI, "injecting %ls into class devs list", device->path);
device->handle = res;
}
device = device->next;
}
} else {
log_warning("setupapi", "upstream SetupDiGetClassDevsA failed: %d", GetLastError());
log_warning(plfSetupAPI, "upstream SetupDiGetClassDevsA failed: %d", GetLastError());
}
return res;
@ -38,12 +38,12 @@ HDEVINFO WINAPI FakeSetupDiGetClassDevsA(const GUID* ClassGuid, PCWSTR Enumerato
BOOL WINAPI FakeSetupDiEnumDeviceInterfaces(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData,
const GUID* InterfaceClassGuid, DWORD MemberIndex,
PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData) {
log_misc("setupapi", "SetupDiEnumDeviceInterfaces");
log_misc(plfSetupAPI, "SetupDiEnumDeviceInterfaces");
FAKE_DEVICE* device = fake_devices;
if (DeviceInterfaceData) {
while (device != NULL) {
if (device->handle == DeviceInfoSet) {
log_info("setupapi", "hooking fake device: %ls", device->path);
log_info(plfSetupAPI, "hooking fake device: %ls", device->path);
memcpy(&DeviceInterfaceData->InterfaceClassGuid, device->guid, sizeof *device->guid);
DeviceInterfaceData->Flags = SPINT_ACTIVE;
DeviceInterfaceData->Reserved = (ULONG_PTR)device->path;
@ -55,7 +55,7 @@ BOOL WINAPI FakeSetupDiEnumDeviceInterfaces(HDEVINFO DeviceInfoSet, PSP_DEVINFO_
}
// Fallback
log_misc("setupapi", "device info fallthrough");
log_misc(plfSetupAPI, "device info fallthrough");
return TrueSetupDiEnumDeviceInterfaces(DeviceInfoSet, DeviceInfoData, InterfaceClassGuid, MemberIndex,
DeviceInterfaceData);
}
@ -64,11 +64,11 @@ BOOL WINAPI FakeSetupDiGetDeviceInterfaceDetailA(HDEVINFO DeviceInfoSet, PSP_DEV
PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData,
DWORD DeviceInterfaceDetailDataSize, PDWORD RequiredSize,
PSP_DEVINFO_DATA DeviceInfoData) {
log_misc("setupapi", "SetupDiGetDeviceInterfaceDetailA");
log_misc(plfSetupAPI, "SetupDiGetDeviceInterfaceDetailA");
FAKE_DEVICE* device = fake_devices;
while (device != NULL) {
if (device->handle == DeviceInfoSet && (ULONG_PTR)device->path == DeviceInterfaceData->Reserved) {
log_info("setupapi", "Intercepted SetupDiGetDeviceInterfaceDetailA");
log_info(plfSetupAPI, "Intercepted SetupDiGetDeviceInterfaceDetailA");
const WCHAR* res = (WCHAR*)DeviceInterfaceData->Reserved;
int new_len = (wcslen(res) + 1) * (sizeof *res);
@ -94,7 +94,7 @@ BOOL WINAPI FakeSetupDiGetDeviceInterfaceDetailA(HDEVINFO DeviceInfoSet, PSP_DEV
device = device->next;
}
log_misc("setupapi", "TrueSetupDiGetDeviceInterfaceDetailA fallthrough");
log_misc(plfSetupAPI, "TrueSetupDiGetDeviceInterfaceDetailA fallthrough");
return TrueSetupDiGetDeviceInterfaceDetailA(DeviceInfoSet, DeviceInterfaceData, DeviceInterfaceDetailData,
DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
}

View File

@ -13,7 +13,7 @@ OSVERSIONINFOA OS_VERSION = {
WCHAR TEMP_PATH[] = L"C:\\DOCUME~1\\SYSTEM~1\\LOCALS~1\\Temp\\";
BOOL WINAPI FakeGetVersionExA(LPOSVERSIONINFOA lpVersionInformation) {
log_trace("system", "GetVersionExA");
log_trace(plfSystem, "GetVersionExA");
memcpy(lpVersionInformation, &OS_VERSION, sizeof OS_VERSION);
return TRUE;
}
@ -21,7 +21,7 @@ BOOL WINAPI FakeGetVolumeInformationW(LPCWSTR lpRootPathName, LPWSTR lpVolumeNam
DWORD nVolumeNameSize, LPDWORD lpVolumeSerialNumber,
LPDWORD lpMaximumComponentLength, LPDWORD lpFileSystemFlags,
LPWSTR lpFileSystemNameBuffer, DWORD nFileSystemNameSize) {
log_trace("system", "GetVolumeInformationW");
log_trace(plfSystem, "GetVolumeInformationW");
if (lpVolumeNameBuffer && nVolumeNameSize) lpVolumeNameBuffer[0] = '\0';
if (lpVolumeSerialNumber) *lpVolumeSerialNumber = 0x00144db0;
if (lpMaximumComponentLength) *lpMaximumComponentLength = 0xff;
@ -46,16 +46,16 @@ LONG WINAPI FakeChangeDisplaySettingsExA(LPCSTR lpszDeviceName, DEVMODEA* lpDevM
}
FARPROC FakeGetProcAddress(HMODULE hModule, LPCSTR lpProcName) {
log_trace("system", "GetProcAddress(%s)", lpProcName);
log_trace(plfSystem, "GetProcAddress(%s)", lpProcName);
return TrueGetProcAddress(hModule, lpProcName);
}
HMODULE FakeGetModuleHandleA(LPCSTR lpModuleName) {
log_trace("system", "GetModuleHandleA(%s)", lpModuleName);
log_trace(plfSystem, "GetModuleHandleA(%s)", lpModuleName);
return TrueGetModuleHandleA(lpModuleName);
}
LONG WINAPI FakeRtlGetVersion(PRTL_OSVERSIONINFOW lpVersionInformation) {
log_trace("system", "RtlGetVersion(%p)", lpVersionInformation);
log_trace(plfSystem, "RtlGetVersion(%p)", lpVersionInformation);
if (lpVersionInformation->dwOSVersionInfoSize >= sizeof (OSVERSIONINFOW)) {
lpVersionInformation->dwMajorVersion = OS_VERSION.dwMajorVersion;

View File

@ -9,7 +9,7 @@ BOOL WINAPI Fake_SetLocalTime(const SYSTEMTIME* lpSystemTime) {
memcpy(&localTime, lpSystemTime, sizeof localTime);
ltCache = TRUE;
log_info("time", "Not setting local time to: %04d-%02d-%02d %02d:%02d:%02d.%04d",
log_info(plfTime, "Not setting local time to: %04d-%02d-%02d %02d:%02d:%02d.%04d",
lpSystemTime->wYear, lpSystemTime->wMonth, lpSystemTime->wDay, lpSystemTime->wHour,
lpSystemTime->wMinute, lpSystemTime->wSecond, lpSystemTime->wMilliseconds);
return TRUE;
@ -18,20 +18,20 @@ BOOL WINAPI Fake_SetSystemTime(const SYSTEMTIME* lpSystemTime) {
memcpy(&systemTime, lpSystemTime, sizeof systemTime);
stCache = TRUE;
log_info("time", "Not setting system time to: %04d-%02d-%02d %02d:%02d:%02d.%04d",
log_info(plfTime, "Not setting system time to: %04d-%02d-%02d %02d:%02d:%02d.%04d",
lpSystemTime->wYear, lpSystemTime->wMonth, lpSystemTime->wDay, lpSystemTime->wHour,
lpSystemTime->wMinute, lpSystemTime->wSecond, lpSystemTime->wMilliseconds);
return TRUE;
}
BOOL WINAPI Fake_SetTimeZoneInformation(const TIME_ZONE_INFORMATION* lpTimeZoneInformation) {
log_info("time", "Not setting timezone to: %d", lpTimeZoneInformation->Bias);
log_info(plfTime, "Not setting timezone to: %d", lpTimeZoneInformation->Bias);
return TRUE;
}
// TODO: Store deltas instead
BOOL WINAPI Fake_GetLocalTime(SYSTEMTIME* lpSystemTime) {
log_trace("time", "GetLocalTime");
log_trace(plfTime, "GetLocalTime");
if (ltCache) {
memcpy(lpSystemTime, &localTime, sizeof localTime);
return TRUE;
@ -49,7 +49,7 @@ BOOL WINAPI Fake_GetLocalTime(SYSTEMTIME* lpSystemTime) {
return TrueGetLocalTime(lpSystemTime);
}
BOOL WINAPI Fake_GetSystemTime(SYSTEMTIME* lpSystemTime) {
log_trace("time", "GetSystemTime");
log_trace(plfTime, "GetSystemTime");
if (stCache) {
memcpy(lpSystemTime, &systemTime, sizeof systemTime);
return TRUE;

View File

@ -9,6 +9,7 @@ struct {
int buttons[JVS_BUTTON_PAIR_COUNT * 2];
bool invert[JVS_BUTTON_PAIR_COUNT * 2];
int test;
} jvsKeybindings[JVS_IO_MAX];
int notdefault;
} jvsKeybindings[JVS_IO_MAX] = { 0 };
int keySystemTest = 0;

View File

@ -19,6 +19,7 @@ shared_library(
gui_files,
'comdevice.c',
'games.c',
'dllmain.c',
],
@ -28,7 +29,11 @@ shared_library(
amiTimer,
amiMd5,
mxk,
# Madoka service emulation
mxklib,
dummymaster,
dummyinstaller,
],
include_directories: [
openssl_inc,

View File

@ -19,3 +19,4 @@ BOOL PathEqual(LPCSTR path1, LPCSTR path2);
BOOL PathPrefix(LPCSTR path, LPCSTR prefix);
void make_dirs(const char* path);
void* open_mapped_file(LPCWSTR path, DWORD size, HANDLE* file, HANDLE* file_mapping);

View File

@ -122,12 +122,12 @@ void* CreateHook32(PVOID src, PVOID dst) {
// cmd BYTE PTR ds:0x...,0x...
len = 10;
} else {
log_error(HOOKS_LOGGER, "Unable to identify gateway length! Function peek:");
log_error(plfHooks, "Unable to identify gateway length! Function peek:");
for (int i = 0; i < 16; i++) {
printf("%02x ", ((LPBYTE)src)[i]);
}
puts("");
log_error(HOOKS_LOGGER, "Unsafely defaulting to 5!");
log_error(plfHooks, "Unsafely defaulting to 5!");
len = 5;
}
@ -147,10 +147,10 @@ void* CreateHook32(PVOID src, PVOID dst) {
extern FARPROC (*TrueGetProcAddress)(HMODULE hModule, LPCSTR lpProcName);
void setup_hooks() {
log_info(HOOKS_LOGGER, "attaching");
log_info(plfHooks, "attaching");
if (hook_list == NULL) {
log_warning(HOOKS_LOGGER, "No hooks to register!");
log_warning(plfHooks, "No hooks to register!");
return;
}
function_hook_t* hook = hook_list;
@ -159,7 +159,7 @@ void setup_hooks() {
HMODULE dll = LoadLibraryA(hook->dll);
if (dll == NULL) {
log_error(HOOKS_LOGGER, "failed to load dll %s (%03x). %s skipped", hook->dll,
log_error(plfHooks, "failed to load dll %s (%03x). %s skipped", hook->dll,
GetLastError(), hook->name);
hook = hook->next;
continue;
@ -169,16 +169,16 @@ void setup_hooks() {
// (TrueGetProcAddress ? TrueGetProcAddress : GetProcAddress)(dll, hook->name);
void* original = GetProcAddress(dll, hook->name);
if (original == NULL) {
log_warning(HOOKS_LOGGER, "failed to get original %s (%03x)", hook->name,
log_warning(plfHooks, "failed to get original %s (%03x)", hook->name,
GetLastError());
} else {
void* gateway = CreateHook32(original, hook->patch);
if (hook->store != NULL) *hook->store = gateway;
log_misc(HOOKS_LOGGER, "hooked %s", hook->name);
log_misc(plfHooks, "hooked %s", hook->name);
}
hook = hook->next;
} while (hook != NULL);
log_info(HOOKS_LOGGER, "attach complete");
log_info(plfHooks, "attach complete");
}

View File

@ -11,6 +11,14 @@
#include "../hooks/files.h"
#include "../hooks/logging.h"
#define _LF(category, name, display) \
LOG_FACILITY lf##name = { \
.m_name = display, \
}; \
PLOG_FACILITY plf##name = &lf##name;
#include "log_facilities.def"
#undef _LF
extern WCHAR exeName[MAX_PATH + 1];
extern DWORD imageOffset;
@ -32,7 +40,6 @@ char* log_prelude() {
}
static HANDLE log_file = NULL;
VOID trace_hook(char* output);
CRITICAL_SECTION logger_lock;
static char* log_colours[] = {
@ -47,21 +54,21 @@ static char* log_colours[] = {
static const char* COLOR_RESET = "\033[0m";
#define LOG_PREFIXES "!GEWIMT"
void logcb(LPCSTR param_1) { log_game("amLog", param_1); }
void logcb(LPCSTR param_1) { log_game(plfAmLog, "%s", param_1); }
void __stdcall amLogCallback(DWORD level, char* format) {
if (level == 0)
log_game("amLog:E", format);
log_game(plfAmLog, "E:%s", format);
else if (level == 0)
log_game("amLog:W", format);
log_game(plfAmLog, "W:%s", format);
else
log_game("amLog:I", format);
log_game(plfAmLog, "I:%s", format);
}
DWORD pLogcb;
DWORD* ppLogcb;
static char log_buf[1024];
int _do_log(BYTE log_level, const char* caller, const char* format, va_list args) {
int _do_log(BYTE log_level, PLOG_FACILITY facility, const char* format, va_list args) {
// TODO: These are all horrible bodges
if (wcscmp(exeName, L"mxnetwork.exe") == 0) {
// *((DWORD*)(imageOffset + 0x004438e8)) = (DWORD)(&logcb);
@ -82,7 +89,7 @@ int _do_log(BYTE log_level, const char* caller, const char* format, va_list args
int col_len = strlen(log_colours[log_level]);
int log_len = snprintf(log_buf, _countof(log_buf), "%s%s%c:%s:", log_colours[log_level],
log_prelude(), prefix, caller);
log_prelude(), prefix, facility->m_name);
log_len += vsnprintf(log_buf + log_len, _countof(log_buf) - log_len, format, args);
log_len += snprintf(log_buf + log_len, _countof(log_buf) - log_len, "%s\n", COLOR_RESET);
log_buf[_countof(log_buf) - 1] = '\0';
@ -105,75 +112,70 @@ int _do_log(BYTE log_level, const char* caller, const char* format, va_list args
LeaveCriticalSection(&logger_lock);
return log_len;
}
int vlog_trace(const char* caller, const char* format, va_list args) {
return _do_log(LOG_TRACE, caller, format, args);
int vlog_trace(PLOG_FACILITY facility, const char* format, va_list args) {
return _do_log(LOG_TRACE, facility, format, args);
}
int _log_trace(const char* caller, const char* format, ...) {
int _log_trace(PLOG_FACILITY facility, const char* format, ...) {
va_list args;
va_start(args, format);
int ret = vlog_trace(caller, format, args);
int ret = vlog_trace(facility, format, args);
va_end(args);
return ret;
}
int vlog_misc(const char* caller, const char* format, va_list args) {
return _do_log(LOG_MISC, caller, format, args);
int vlog_misc(PLOG_FACILITY facility, const char* format, va_list args) {
return _do_log(LOG_MISC, facility, format, args);
}
int _log_misc(const char* caller, const char* format, ...) {
int _log_misc(PLOG_FACILITY facility, const char* format, ...) {
va_list args;
va_start(args, format);
int ret = vlog_misc(caller, format, args);
int ret = vlog_misc(facility, format, args);
va_end(args);
return ret;
}
int vlog_info(const char* caller, const char* format, va_list args) {
return _do_log(LOG_INFO, caller, format, args);
int vlog_info(PLOG_FACILITY facility, const char* format, va_list args) {
return _do_log(LOG_INFO, facility, format, args);
}
int _log_info(const char* caller, const char* format, ...) {
int _log_info(PLOG_FACILITY facility, const char* format, ...) {
va_list args;
va_start(args, format);
int ret = vlog_info(caller, format, args);
int ret = vlog_info(facility, format, args);
va_end(args);
return ret;
}
int vlog_warning(const char* caller, const char* format, va_list args) {
return _do_log(LOG_WARNING, caller, format, args);
int vlog_warning(PLOG_FACILITY facility, const char* format, va_list args) {
return _do_log(LOG_WARNING, facility, format, args);
}
int _log_warning(const char* caller, const char* format, ...) {
int _log_warning(PLOG_FACILITY facility, const char* format, ...) {
va_list args;
va_start(args, format);
int ret = vlog_warning(caller, format, args);
int ret = vlog_warning(facility, format, args);
va_end(args);
return ret;
}
int vlog_error(const char* caller, const char* format, va_list args) {
return _do_log(LOG_ERROR, caller, format, args);
int vlog_error(PLOG_FACILITY facility, const char* format, va_list args) {
return _do_log(LOG_ERROR, facility, format, args);
}
int _log_error(const char* caller, const char* format, ...) {
int _log_error(PLOG_FACILITY facility, const char* format, ...) {
va_list args;
va_start(args, format);
int ret = vlog_error(caller, format, args);
int ret = vlog_error(facility, format, args);
va_end(args);
return ret;
}
int vlog_game(const char* caller, const char* format, va_list args) {
return _do_log(LOG_GAME, caller, format, args);
int vlog_game(PLOG_FACILITY facility, const char* format, va_list args) {
return _do_log(LOG_GAME, facility, format, args);
}
int _log_game(const char* caller, const char* format, ...) {
int _log_game(PLOG_FACILITY facility, const char* format, ...) {
va_list args;
va_start(args, format);
int ret = vlog_game(caller, format, args);
int ret = vlog_game(facility, format, args);
va_end(args);
return ret;
}
VOID trace_hook(char* output) {
output[strcspn(output, "\n")] = 0;
log_error("trace", output);
}
void setup_logging() {
// Force stdio even for GUI applications
AttachConsole(ATTACH_PARENT_PROCESS);
// AttachConsole(ATTACH_PARENT_PROCESS);
// Enable colour in CMD
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
@ -190,7 +192,7 @@ void setup_logging() {
}
}
void log_stack(const char* caller) {
void log_stack(PLOG_FACILITY facility) {
char name[MAX_PATH * sizeof(TCHAR)];
char Storage[sizeof(IMAGEHLP_SYMBOL64) + sizeof(name)];
@ -220,7 +222,7 @@ void log_stack(const char* caller) {
SymGetSymFromAddr64(process, (ULONG64)stack.AddrPC.Offset, &displacement, symbol);
UnDecorateSymbolName(symbol->Name, (PSTR)name, sizeof(name), UNDNAME_COMPLETE);
log_error(caller, "%02u called from 0x%08X STACK=0x%08X FRAME=0x%08X %s\n", frame,
log_error(facility, "%02u called from 0x%08X STACK=0x%08X FRAME=0x%08X %s\n", frame,
(ULONG64)stack.AddrPC.Offset, (ULONG64)stack.AddrStack.Offset,
(ULONG64)stack.AddrFrame.Offset, symbol->Name);

View File

@ -10,27 +10,33 @@
#define LOG_MISC 5
#define LOG_TRACE 6
#define COMM_LOGGER "comm"
#define HOOKS_LOGGER "hooks"
#define BOOT_LOGGER "boot"
typedef struct {
char* m_name;
} LOG_FACILITY, *PLOG_FACILITY;
#define _LF(category, name, display) extern PLOG_FACILITY plf##name;
#include "log_facilities.def"
#undef _LF
extern PLOG_FACILITY plfNetwork;
extern CRITICAL_SECTION logger_lock;
int _log_trace(const char* caller, const char* format, ...);
int _log_misc(const char* caller, const char* format, ...);
int _log_info(const char* caller, const char* format, ...);
int _log_warning(const char* caller, const char* format, ...);
int _log_error(const char* caller, const char* format, ...);
int _log_game(const char* caller, const char* format, ...);
int _log_trace(PLOG_FACILITY facility, const char* format, ...);
int _log_misc(PLOG_FACILITY facility, const char* format, ...);
int _log_info(PLOG_FACILITY facility, const char* format, ...);
int _log_warning(PLOG_FACILITY facility, const char* format, ...);
int _log_error(PLOG_FACILITY facility, const char* format, ...);
int _log_game(PLOG_FACILITY facility, const char* format, ...);
int vlog_trace(const char* caller, const char* format, va_list args);
int vlog_misc(const char* caller, const char* format, va_list args);
int vlog_info(const char* caller, const char* format, va_list args);
int vlog_warning(const char* caller, const char* format, va_list args);
int vlog_error(const char* caller, const char* format, va_list args);
int vlog_game(const char* caller, const char* format, va_list args);
int vlog_trace(PLOG_FACILITY facility, const char* format, va_list args);
int vlog_misc(PLOG_FACILITY facility, const char* format, va_list args);
int vlog_info(PLOG_FACILITY facility, const char* format, va_list args);
int vlog_warning(PLOG_FACILITY facility, const char* format, va_list args);
int vlog_error(PLOG_FACILITY facility, const char* format, va_list args);
int vlog_game(PLOG_FACILITY facility, const char* format, va_list args);
void log_stack(const char* caller);
void log_stack(PLOG_FACILITY facility);
void setup_logging();

View File

@ -0,0 +1,40 @@
_LF(Internal, Boot, "boot")
_LF(Internal, Hooks, "hooks")
_LF(Internal, Misc, "misc")
_LF(Misc, Tea, "tea")
_LF(Misc, Printf, "printf")
_LF(Misc, Fprintf, "fprintf")
_LF(Misc, Fprintf_s, "fprintf_s")
_LF(Misc, Vfprintf_s, "vfprintf_s")
_LF(Misc, AmLog, "amLog")
_LF(Hooks, Processes, "processes")
_LF(Hooks, Registry, "registry")
_LF(Hooks, SetupAPI, "setupapi")
_LF(Hooks, System, "system")
_LF(Hooks, Time, "time")
_LF(Hooks, Drive, "drive")
_LF(Hooks, Network, "network")
_LF(Hooks, Comm, "comm")
_LF(Hooks, D3D9, "D3D9")
_LF(Hooks, File, "file")
_LF(Hooks, Evtlog, "evtlog")
_LF(Hooks, GUI, "gui")
_LF(Devices, Aime, "aime")
_LF(Devices, DS2460, "ds2460")
_LF(Devices, DS28CN01, "ds28cn01")
_LF(Devices, PCA9535, "pca9535")
_LF(Devices, Eeprom, "eeprom")
_LF(Devices, MaiTouch, "maitouch")
_LF(Devices, MaiLED, "mailed")
_LF(Drivers, Columba, "columba")
_LF(Drivers, MxJvs, "mxjvs")
_LF(Drivers, MxParallel, "mxparallel")
_LF(Drivers, MxSram, "mxsram")
_LF(Drivers, MxSuperio, "mxsuperio")
_LF(Drivers, MxSmbus, "mxsmbus")
_LF(Drivers, MxHwreset, "mxhwreset")
_LF(Drivers, Platform, "platform")

View File

@ -110,7 +110,7 @@ HANDLE GetDummyHandle() {
_CreateFileA(path, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hObject == INVALID_HANDLE_VALUE) {
log_error(HOOKS_LOGGER, "Failed to create dummy handle: %03x", GetLastError());
log_error(plfMisc, "Failed to create dummy handle: %03x", GetLastError());
}
return hObject;
@ -152,3 +152,38 @@ void make_dirs(const char* path) {
}
free(temp);
}
void* open_mapped_file(LPCWSTR path, DWORD size, HANDLE* file, HANDLE* file_mapping) {
make_dirs(path);
*file = _CreateFileW(path, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (*file == INVALID_HANDLE_VALUE) {
log_error(plfMisc, "Failed to CreateFileW(%ls): %d", path, GetLastError());
return NULL;
}
*file_mapping =
CreateFileMappingW(*file, NULL, PAGE_READWRITE, 0, size, NULL);
if (*file_mapping == INVALID_HANDLE_VALUE) {
CloseHandle(*file);
*file = INVALID_HANDLE_VALUE;
log_error(plfMisc, "Failed to CreateFileMappingW: %d", GetLastError());
return NULL;
}
SetLastError(0);
void* mapping = MapViewOfFile(*file_mapping, FILE_MAP_ALL_ACCESS, 0, 0, size);
if (mapping == NULL || GetLastError()) {
log_error(plfMisc, "Failed to MapViewOfFileEx: %d", GetLastError());
CloseHandle(*file);
CloseHandle(*file_mapping);
*file = INVALID_HANDLE_VALUE;
*file_mapping = INVALID_HANDLE_VALUE;
return NULL;
}
return mapping;
}

View File

@ -66,7 +66,7 @@ typedef enum binary_mode {
#define SOCKET_INVAL ((SOCKET)-1)
#define HANDLE_INVAL -1
#define TIMEOUT_NONE ((DWORD)-1)
#define TIMEOUT_NONE ((timeout_t)-1)
#define PCPT_CLOSED 0
#define PCPT_LISTENING 1

View File

@ -110,6 +110,7 @@ e_pcpa_t pcpaInitStream(pcpa_t *stream) {
stream->binary_mode_after_cb = NULL;
stream->binary_mode_before_data = NULL;
stream->binary_mode_after_data = NULL;
stream->before_cb = NULL;
ZERO(stream->recv_data);
ZERO(stream->send_data);
return e_pcpa_ok;
@ -222,7 +223,7 @@ e_pcpa_t pcpaSetCallbackFuncBuffer(pcpa_t *stream, pcpa_cb_table_t *callback_tab
return e_pcpa_stream_unset;
}
if (callback_table == NULL || callbacks_max == 0) return e_pcpa_timeout_closed;
if (callback_table == NULL || callbacks_max == 0) return e_pcpa_no_table_space;
stream->callback_max = callbacks_max;
stream->callback_table = callback_table;
@ -276,7 +277,7 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
case pcpa_state_none:
amiTimerGet(&time);
ms = _amTimeDelta(time, time_start);
if (timeout_ms != -1) {
if (timeout_ms != TIMEOUT_NONE) {
if (ms < (uint)timeout_ms) {
timeout = timeout_ms - ms;
local_14 = timeout;
@ -294,9 +295,10 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
if (eVar4 == e_pcpa_ok) {
stream->state = 10;
amiTimerGet(&time);
if (timeout_ms != -1) {
ms = _amTimeDelta(time, time_start);
goto joined_r0x00454a58;
if (timeout_ms != TIMEOUT_NONE &&
_amTimeDelta(time, time_start) >= timeout_ms) {
stream->err = e_pcpa_to;
return stream->err;
}
} else {
stream->state = pcpa_state_none;
@ -311,7 +313,7 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
case 9:
amiTimerGet(&time);
ms = _amTimeDelta(time, time_start);
if (timeout_ms != -1) {
if (timeout_ms != TIMEOUT_NONE) {
if (ms < (uint)timeout_ms) {
timeout = timeout_ms - ms;
local_14 = timeout;
@ -333,13 +335,10 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
if (stream->binary_mode == binary_mode_none) {
stream->state = (stream->state != pcpa_state_wait_request) - 1 & 10;
amiTimerGet(&time);
if (timeout_ms != -1) {
ms = _amTimeDelta(time, time_start);
joined_r0x00454a58:
if ((uint)timeout_ms <= ms) {
stream->err = e_pcpa_to;
return stream->err;
}
if (timeout_ms != TIMEOUT_NONE &&
_amTimeDelta(time, time_start) >= timeout_ms) {
stream->err = e_pcpa_to;
return stream->err;
}
} else {
pcpaCloseBinary(stream);
@ -351,9 +350,10 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
stream->binary_mode_after_cb = NULL;
}
amiTimerGet(&time);
if (timeout_ms != -1) {
ms = _amTimeDelta(time, time_start);
goto joined_r0x00454a58;
if (timeout_ms != TIMEOUT_NONE &&
_amTimeDelta(time, time_start) >= timeout_ms) {
stream->err = e_pcpa_to;
return stream->err;
}
}
} else {
@ -378,9 +378,8 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
stream->binary_mode_before_cb = NULL;
}
amiTimerGet(&time);
ms = _amTimeDelta(time, time_start);
if (timeout_ms != -1) {
if (ms < (uint)timeout_ms) {
if (timeout_ms != TIMEOUT_NONE) {
if (_amTimeDelta(time, time_start) > timeout_ms) {
timeout = timeout_ms - ms;
local_14 = timeout;
} else {
@ -403,9 +402,10 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
if (stream->err == e_pcpa_ok) {
LAB_00454a1a:
amiTimerGet(&time);
if (timeout_ms != -1) {
ms = _amTimeDelta(time, time_start);
goto joined_r0x00454a58;
if (timeout_ms != TIMEOUT_NONE &&
_amTimeDelta(time, time_start) >= timeout_ms) {
stream->err = e_pcpa_to;
return stream->err;
}
} else {
PCP_LOG("error pcpaSendBinary\n");
@ -421,7 +421,7 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
}
amiTimerGet(&time);
ms = _amTimeDelta(time, time_start);
if (timeout_ms != -1) {
if (timeout_ms != TIMEOUT_NONE) {
if (ms < (uint)timeout_ms) {
timeout = timeout_ms - ms;
local_14 = timeout;
@ -447,9 +447,9 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
}
break;
case 10:
if (stream->before_cb != NULL) {
// TODO: Figure out why recv_buf is empty at this point in the FSM
if (stream->before_cb != NULL)
stream->before_cb(stream, stream->pcpp.sock.recv_buf);
}
if (stream->callback_table == NULL) {
PCP_LOG("error Callback_table buffer isn\'t set\n");
@ -492,7 +492,7 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
LAB_004547f1:
amiTimerGet(&time);
ms = _amTimeDelta(time, time_start);
if (timeout_ms != -1) {
if (timeout_ms != TIMEOUT_NONE) {
if (ms < (uint)timeout_ms) {
local_14 = timeout_ms - ms;
} else {
@ -514,9 +514,9 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
}
amiTimerGet(&time);
timeout = local_14;
if (timeout_ms != TIMEOUT_NONE) {
ms = _amTimeDelta(time, time_start);
goto joined_r0x00454a58;
if (timeout_ms != TIMEOUT_NONE && _amTimeDelta(time, time_start) >= timeout_ms) {
stream->err = e_pcpa_to;
return stream->err;
}
}
} while (stream->err == e_pcpa_ok);

View File

@ -11,7 +11,8 @@ typedef enum e_pcpa {
e_pcpa_cannot_open = -2,
e_pcpa_generic = -3,
e_pcpa_param_invalid = -4,
e_pcpa_timeout_closed = -5, // TODO: This is wrong (see: pcpaSetCallbackFuncBuffer)
e_pcpa_timeout_closed = -5,
e_pcpa_no_table_space = -6,
e_pcpa_cb_table_full = -9,
e_pcpa_stream_unset = -10,
e_pcpa_cb_table_unset = -11,

View File

@ -480,10 +480,10 @@ e_pcpt_t pcptRecv(pcpt_t *sock, unsigned char *recv_buf, size_t *recv_buf_len,
return sock->err = e_pcpt_not_open;
}
// TODO: URGENT: Something in the FSM causes this condition to error out!
// if (sock->client_open != 0) {
// PCP_LOG("error PCP already connected\n");
// return sock->err = e_pcpt_already_connected;
// }
if (sock->client_open != 0) {
PCP_LOG("error PCP already connected\n");
return sock->err = e_pcpt_already_connected;
}
sock->recv_buf = recv_buf;
sock->recv_buf_count = recv_buf_len;

View File

@ -87,6 +87,8 @@ void save_current_config() {
for (int board = 0; board < MiceConfig.keys.board_count; board++) {
i += snprintf(keybindBuffer + i, _countof(keybindBuffer) - i, "%d,",
jvsKeybindings[board].test);
i += snprintf(keybindBuffer + i, _countof(keybindBuffer) - i, "%d,",
jvsKeybindings[board].notdefault);
for (int n = 0; n < JVS_BUTTON_PAIR_COUNT * 2; n++) {
i += snprintf(keybindBuffer + i, _countof(keybindBuffer) - i, "%d,",
jvsKeybindings[board].buttons[n]);
@ -228,13 +230,16 @@ void load_mice_config() {
if (state == 0) {
jvsKeybindings[board].test = val;
state = 1;
} else if (state == 1) {
jvsKeybindings[board].notdefault = val;
state = 2;
} else {
if (state == 1) {
if (state == 2) {
jvsKeybindings[board].buttons[n] = val;
state = 2;
state = 3;
} else {
jvsKeybindings[board].invert[n] = val;
state = 1;
state = 2;
if (n++ == JVS_BUTTON_PAIR_COUNT * 2) {
n = 0;
state = 0;

View File

@ -65,12 +65,6 @@ COMMENT("Second half of system mac address. The vendor prefix D8:BB:C1: will be
CFG_hex(network, mac, 6, 0A2F1D, "")
ENDSECTION(network)
SECTION(devices, "Specify COM ports for devices to attach, comma seperated")
CFG_str(devices, aime_bd, "2", "AIME reader board")
CFG_str(devices, touch_bd, "3", "maimai touch screen")
CFG_str(devices, led_bd, "5,6,7,8", "maimai led boards")
ENDSECTION(devices)
SECTION(drivers, "Enable or disable drivers. Disabling any is not recommended.")
CFG_bool(drivers, columba, true, "")
CFG_bool(drivers, mxsram, true, "")
@ -102,6 +96,18 @@ CFG_int(keys, board_count, 1, "")
CFG_str(keys, keys, 0, "")
ENDSECTION(keys)
SECTION(devices, "Register attached hardware devices")
CFG_bool(devices, do_auto, true, "When true, if the running game is identified, the following 8 values are overwritten")
CFG_str(devices, com1, "", "")
CFG_str(devices, com2, "", "")
CFG_str(devices, com3, "", "")
CFG_str(devices, com4, "", "")
CFG_str(devices, com5, "", "")
CFG_str(devices, com6, "", "")
CFG_str(devices, com7, "", "")
CFG_str(devices, com8, "", "")
ENDSECTION(devices)
#undef CFG_str
#undef CFG_int
#undef CFG_bool

View File

@ -1,3 +1,5 @@
#pragma once
#include <Windows.h>
#include <winioctl.h>

View File

@ -2,12 +2,20 @@ mxklib = static_library(
'mxk',
sources: [
'mxk.c',
'mxkAb.c',
'mxkDs.c',
'mxkN2.c',
'mxkCrypt.c',
'mxkSmbus.c',
'mxkPacket.c',
'mxkTransport.c',
],
include_directories: [
openssl_inc,
],
link_with: [
amiCrc,
amiDebug,
],
dependencies: [openssl_lib],
)

View File

@ -1,131 +1,234 @@
#include "mxk.h"
BOOL mxkExchengeAesKey(HANDLE mxparallel) {
FILETIME filetime;
amtime_t now;
unsigned int KEYCHIP_STATUS;
unsigned char KEYCHIP_ERROR;
static MXK_STATUS mxkPacketReqRandomBytes(unsigned char* packet) {
if (packet == NULL) return MXK_STATUS_INVALID_PARAM;
amtime_t now;
FILETIME filetime;
for (int i = 0; i < MXK_BLOCK_SIZE; i++) {
amiTimerGet(&now);
GetSystemTimeAsFileTime(&filetime);
packet[i] = (filetime.dwHighDateTime & 0xff) ^ (filetime.dwLowDateTime & 0xff) ^
(now.microseconds & 0xff);
}
return MXK_STATUS_OK;
}
MXK_STATUS mxkExchengeAesKey(void) {
unsigned char key_s[16];
unsigned char key_r[16];
size_t i;
for (i = 0; i < 16; i++) {
amiTimerGet(&now);
GetSystemTimeAsFileTime(&filetime);
key_s[i] = (filetime.dwHighDateTime & 0xff) ^ (filetime.dwLowDateTime & 0xff) ^
(now.microseconds & 0xff);
}
for (i = 0; i < 16; i++) {
amiTimerGet(&now);
GetSystemTimeAsFileTime(&filetime);
key_r[i] = (filetime.dwHighDateTime & 0xff) ^ (filetime.dwLowDateTime & 0xff) ^
(now.microseconds & 0xff);
}
unsigned char packet[16];
mxkPacketReqSetKeyS(packet);
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
if (!mxkSendPacket(mxparallel, key_s)) return FALSE;
if (!mxkRecvPacket(mxparallel, packet)) return FALSE;
if (packet[0] != SetKeyS) return FALSE;
mxkPacketReqRandomBytes(key_s);
mxkPacketReqRandomBytes(key_r);
if (mxkPacketReqSetKeyS(packet) != MXK_STATUS_OK) {
amiDebugLog("Error mxkPacketReqSetKeyS");
return MXK_STATUS_ERROR;
}
if (mxkSendPacket(packet) != MXK_STATUS_OK) {
amiDebugLog("Error mxkSendPacket Command KeyS");
return MXK_STATUS_ERROR;
}
if (mxkSendPacket(key_s) != MXK_STATUS_OK) {
amiDebugLog("Error mxkSendPacket KeyS");
return MXK_STATUS_ERROR;
}
if (mxkRecvPacket(packet) != MXK_STATUS_OK || packet[0] != SetKeyS) {
amiDebugLog("Error mxkRecvPacket KeyS");
return MXK_STATUS_ERROR;
}
mxkSetKeyS(key_s);
mxkPacketReqSetKeyR(packet);
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
if (!mxkSendPacket(mxparallel, key_r)) return FALSE;
if (mxkPacketReqSetKeyR(packet) != MXK_STATUS_OK) {
amiDebugLog("Error mxkPacketReqSetKeyR");
return MXK_STATUS_ERROR;
}
if (mxkSendPacket(packet) != MXK_STATUS_OK) {
amiDebugLog("Error mxkSendPacket Command SetKeyR");
return MXK_STATUS_ERROR;
}
if (mxkSendPacket(key_r) != MXK_STATUS_OK) {
amiDebugLog("Error mxkSendPacket KeyR");
return MXK_STATUS_ERROR;
}
mxkSetKeyR(key_r);
if (!mxkRecvPacket(mxparallel, packet)) return FALSE;
if (mxkRecvPacket(packet) != MXK_STATUS_OK) {
amiDebugLog("Error mxkRecvPacket KeyR");
return MXK_STATUS_ERROR;
}
return TRUE;
return MXK_STATUS_OK;
}
BOOL mxkVersion(HANDLE mxparallel, unsigned short* version) {
BOOL mxkVersionDirty;
unsigned short mxkVersionCache;
MXK_STATUS mxkVersion(unsigned short* version, MXK_CACHE cache, unsigned char* err) {
unsigned char packet[16];
mxkPacketReqGetVersion(packet);
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
if (!mxkRecvPacket(mxparallel, packet)) return FALSE;
if (version == NULL || err == NULL) return MXK_STATUS_INVALID_PARAM;
*version = ((unsigned short*)packet)[0];
return TRUE;
if (KEYCHIP_STATUS == 2) {
amiDebugLog("Error MXK_STATUS_ERROR!!");
*err = KEYCHIP_ERROR;
return MXK_STATUS_ERROR;
}
if (cache == MXK_CACHE_USE) {
if (!mxkVersionDirty) {
*version = mxkVersionCache;
return MXK_STATUS_OK;
}
} else {
mxkVersionDirty = true;
}
mxkPacketReqGetVersion(packet);
if (mxkSendPacket(packet) != MXK_STATUS_OK) {
amiDebugLog("Error mxkSendPacket!!");
goto error;
}
if (mxkRecvPacket(packet) != MXK_STATUS_OK) {
amiDebugLog("Error mxkRecvPacket!!");
goto error;
}
*version = mxkVersionCache = ((unsigned short*)packet)[0];
mxkVersionDirty = false;
return MXK_STATUS_OK;
error:
KEYCHIP_ERROR = 2;
KEYCHIP_STATUS = 2;
*err = 2;
return MXK_STATUS_ERROR;
}
BOOL mxkSetMainId(HANDLE mxparallel, const unsigned char* main_id) {
BOOL mxkSetMainId(const unsigned char* main_id) {
unsigned char packet[16];
mxkPacketReqSetMainId(packet);
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
if (!mxkSendPacket(mxparallel, main_id)) return FALSE;
if (!mxkSendPacket(packet)) return FALSE;
if (!mxkSendPacket(main_id)) return FALSE;
mxkRecvPacket(mxparallel, packet);
mxkRecvPacket(packet);
return packet[0] != 0xff;
}
BOOL mxkGetMainId(HANDLE mxparallel, unsigned char* main_id) {
BOOL mxkGetMainId(unsigned char* main_id) {
unsigned char packet[16];
mxkPacketReqGetMainId(packet);
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
if (!mxkRecvPacket(mxparallel, main_id)) return FALSE;
if (!mxkSendPacket(packet)) return FALSE;
if (!mxkRecvPacket(main_id)) return FALSE;
return TRUE;
}
BOOL mxkGetKeyId(HANDLE mxparallel, unsigned char* key_id) {
BOOL mxkGetKeyId(unsigned char* key_id) {
unsigned char packet[16];
mxkPacketReqGetKeyId(packet);
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
if (!mxkRecvPacket(mxparallel, key_id)) return FALSE;
if (!mxkSendPacket(packet)) return FALSE;
if (!mxkRecvPacket(key_id)) return FALSE;
return TRUE;
}
BOOL mxkGetAppBootInfo(HANDLE mxparallel, appboot_t* appboot) {
unsigned char packet[16];
mxkPacketReqGetAppBootInfo(packet);
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
for (int i = 0; i < sizeof *appboot; i += 16) {
if (!mxkRecvPacket(mxparallel, (unsigned char*)appboot + i)) return FALSE;
}
return TRUE;
}
BOOL mxkGetPlayCounter(HANDLE mxparallel, DWORD* play_counter) {
BOOL mxkGetPlayCounter(DWORD* play_counter) {
unsigned char packet[16];
mxkPacketReqGetPlayCounter(packet);
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
if (!mxkRecvPacket(mxparallel, packet)) return FALSE;
if (!mxkSendPacket(packet)) return FALSE;
if (!mxkRecvPacket(packet)) return FALSE;
*play_counter = ((DWORD*)packet)[0];
return TRUE;
}
BOOL mxkFlashRead(HANDLE mxparallel, unsigned int address, unsigned int nbytes,
unsigned char* buffer) {
BOOL mxkFlashRead(unsigned int address, unsigned int nbytes, unsigned char* buffer) {
unsigned char packet[16];
mxkPacketReqFlashRead(packet, address, nbytes);
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
if (!mxkSendPacket(packet)) return FALSE;
for (size_t i = 0; i < nbytes; i += 0x100) {
unsigned int rest = (nbytes - i) > 0x100 ? 0x100 : (nbytes - i);
if (!mxkTransportRecv(mxparallel, buffer + i, rest)) return FALSE;
if (!mxkTransportRecv(buffer + i, rest)) return FALSE;
}
return TRUE;
}
BOOL mxkEepromRead(HANDLE mxparallel, unsigned char page, unsigned char* data) {
BOOL mxkEepromRead(unsigned char page, unsigned char* data) {
unsigned char packet[16];
mxkPacketReqEepromRead(packet, page);
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
if (!mxkRecvPacket(mxparallel, data)) return FALSE;
if (!mxkSendPacket(packet)) return FALSE;
if (!mxkRecvPacket(data)) return FALSE;
return TRUE;
}
BOOL mxkNvramRead(HANDLE mxparallel, unsigned short addr, unsigned char blocks, unsigned char* data) {
BOOL mxkNvramRead(unsigned short addr, unsigned char blocks, unsigned char* data) {
unsigned char packet[16];
mxkPacketReqNvramRead(packet, addr, blocks);
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
if (!mxkSendPacket(packet)) return FALSE;
for (size_t i = 0; i < blocks; i++) {
if (!mxkRecvPacket(mxparallel, data + (i * 16))) return FALSE;
if (!mxkRecvPacket(data + (i * 16))) return FALSE;
}
return TRUE;
}
bool mxkValidString(const char* string, unsigned int length) {
for (int i = 0; i < length; i++) {
char c = string[i];
if (isalnum(c)) continue;
if (c != '.' && c != '_' && c != '-' && c != ':' && c != '@' && c != '%' && c != '/' &&
c != '\\')
return false;
}
return true;
}
MXK_STATUS mxkInit() {
mxkVersionDirty = true;
AppBoot.m_cacheDirty = true;
if (mxkTransportInit() != MXK_STATUS_OK) {
amiDebugLog("Error mxkTransportInit!!");
return MXK_STATUS_ERROR;
}
if (mxkCryptInit() != MXK_STATUS_OK) {
amiDebugLog("Error mxkCryptInit!!");
return MXK_STATUS_ERROR;
}
if (mxkExchengeAesKey() != MXK_STATUS_OK) {
amiDebugLog("Error mxkExchengeAesKey!!");
return MXK_STATUS_ERROR;
}
// TODO: N2
if (mxkSmbusInit() != MXK_STATUS_OK) {
amiDebugLog("Error mxkSmbusInit!!");
return MXK_STATUS_ERROR;
}
// TODO: SSD
// mxkSsdInit();
if (mxkAuthenticationDs() != MXK_STATUS_OK) {
amiDebugLog("Error mxkAuthenticationDs!!");
return MXK_STATUS_ERROR;
}
if (mxkGetAppBootInfo() != MXK_STATUS_OK) {
amiDebugLog("Error mxkGetAppBootInfo!!");
return MXK_STATUS_ERROR;
}
unsigned char system_flag;
unsigned char err;
if (mxkAbSystemFlag(MXK_CACHE_USE, &system_flag, &err) == MXK_STATUS_OK && system_flag & 1) {
// appboot_flash();
// eeprom_playcount();
}
// TODO:
mxkN2CmdSetDeviceInfo();
mxkN2Authentication();
return MXK_STATUS_OK;
}

View File

@ -1,113 +1,32 @@
#pragma once
#include <Windows.h>
#include <stdbool.h>
#include "../ami/ami.h"
#include "mxkAb.h"
#include "mxkCrypt.h"
#include "mxkDefs.h"
#include "mxkDs.h"
#include "mxkN2.h"
#include "mxkPacket.h"
#include "mxkSmbus.h"
#include "mxkTransport.h"
extern unsigned char KEY_R[16];
extern unsigned char KEY_S[16];
extern unsigned char BILLING_PRIVKEY[917];
extern unsigned char BILLING_PUBKEY[162];
extern unsigned char BILLING_CACERT[817];
extern unsigned char KEYCHIP_ID[16];
extern unsigned char MAIN_ID[16];
enum {
SetKeyS = 0, // mxkPacketReqSetKeyS [0] [...
SetKeyR = 1, // mxkPacketReqSetKeyR [1] [...
SetIV = 2, // mxkPacketReqSetIv [2] [...
Decrypt = 3, // mxkPacketReqDecrypt [3] [...
Encrypt = 4, // mxkPacketReqEncrypt [4] [...
GetAppBootInfo = 5, // mxkPacketReqGetAppBootInfo [5] [0] [...
EepromWrite = 6, // mxkPacketReqEepromWrite [6] [x] [...
EepromRead = 7, // mxkPacketReqEepromRead [7] [x] [...
NvramWrite = 8, // mxkPacketReqNvramWrite [8] [x] [x] [y] [...
NvramRead = 9, // mxkPacketReqNvramRead [9] [x] [x] [y] [...
AddPlayCount = 10, // mxkPacketReqAddPlayCount [10] [...
FlashRead = 11, // mxkPacketReqFlashRead [11] [x] [x] [x] [y] [y] [y] [...
FlashErase = 12, // mxkPacketReqFlashErase [12] [x] [x] [x] [...
KcCmd13 = 13, // mxkPacketReq-13 [13] [x] [x] [x] [...
FlashWrite = 14, // mxkPacketReqFlashWrite [14] [x] [x] [x] [y] [y] [y] [...
KcCmd15 = 15, //
KcCmd16 = 16, //
KcCmd17 = 17, //
KcCmd18 = 18, //
KcCmd19 = 19, //
KcGetVersion = 20, // mxkPacketReqGetVersion [20] [...
SetMainId = 21, // mxkPacketReqSetMainId [21] [...
GetMainId = 22, // mxkPacketReqGetMainId [22] [...
SetKeyId = 23, // mxkPacketReqSetKeyId [23] [...
GetKeyId = 24, // mxkPacketReqGetKeyId [24] [...
GetPlayCounter = 25, // mxkPacketReqGetPlayCounter [25] [...
};
// Structs
#pragma pack(push, 1)
typedef struct {
DWORD crc;
DWORD format;
char game_id[4];
BYTE region;
BYTE model_type;
BYTE system_flag;
BYTE _;
char platform_id[3];
BYTE dvd_flag;
DWORD network_addr;
BYTE __[216];
BYTE seed[16];
} appboot_t;
#pragma pack(pop)
// Crypt
void mxkSetKeyS(unsigned char* key_s);
void mxkSetKeyR(unsigned char* key_r);
void mxkSwapKeys();
void mxkCryptEncryptAes128CBC(const unsigned char* key, const unsigned char* iv, unsigned char* pt, const unsigned char* ct, size_t nbytes);
void mxkCryptDecryptAes128CBC(const unsigned char* key, const unsigned char* iv, const unsigned char* ct, unsigned char* pt, size_t nbytes);
void mxkCryptEncryptData(unsigned char* ct, const unsigned char* pt);
void mxkCryptDecryptData(const unsigned char* ct, unsigned char* pt);
void mxkSign(void* buffer, size_t nbytes, unsigned char* signature);
void mxkSignValue(unsigned int value, unsigned char* signature);
// Transport
static BOOL mxkTransportWaitStrobeReady(HANDLE mxparallel);
static BOOL mxkTransportWaitStrobeRelease(HANDLE mxparallel);
static void mxkTransportCtrlPortInAndOut(HANDLE mxparallel, BYTE flag);
static void mxkTransportCtrlPortInOrOut(HANDLE mxparallel, BYTE flag);
BOOL mxkTransportSend(HANDLE mxparallel, unsigned char* data, DWORD nbytes);
HRESULT mxkTransportRecv(HANDLE mxparallel, unsigned char* data, DWORD nbytes);
BOOL mxkSendPacket(HANDLE mxparallel, const unsigned char* packet);
BOOL mxkRecvPacket(HANDLE mxparallel, unsigned char* packet);
void mxkTransportInitPic(HANDLE mxparallel);
// MXK Packet
void mxkPacketReqSetKeyS(unsigned char* packet);
void mxkPacketReqSetKeyR(unsigned char* packet);
void mxkPacketReqGetAppBootInfo(unsigned char* packet);
void mxkPacketReqEepromRead(unsigned char* packet, unsigned char page);
void mxkPacketReqGetVersion(unsigned char* packet);
void mxkPacketReqSetMainId(unsigned char* packet);
void mxkPacketReqGetMainId(unsigned char* packet);
void mxkPacketReqGetKeyId(unsigned char* packet);
void mxkPacketReqGetPlayCounter(unsigned char* packet);
void mxkPacketReqFlashRead(unsigned char* packet, unsigned int address, unsigned int nbytes);
void mxkPacketReqNvramRead(unsigned char* packet, unsigned short addr, unsigned char blocks);
MXK_STATUS mxkInit(void);
MXK_STATUS mxkExchengeAesKey(void);
MXK_STATUS mxkVersion(unsigned short* version, MXK_CACHE cache, unsigned char* err);
// MXK
BOOL mxkExchengeAesKey(HANDLE mxparallel);
BOOL mxkVersion(HANDLE mxparallel, unsigned short* version);
BOOL mxkSetMainId(HANDLE mxparallel, const unsigned char* main_id);
BOOL mxkGetMainId(HANDLE mxparallel, unsigned char* main_id);
BOOL mxkGetKeyId(HANDLE mxparallel, unsigned char* main_id);
BOOL mxkGetAppBootInfo(HANDLE mxparallel, appboot_t* appboot);
BOOL mxkGetPlayCounter(HANDLE mxparallel, DWORD* play_counter);
BOOL mxkFlashRead(HANDLE mxparallel, unsigned int address, unsigned int nbytes,
unsigned char* buffer);
BOOL mxkEepromRead(HANDLE mxparallel, unsigned char page, unsigned char* data);
BOOL mxkNvramRead(HANDLE mxparallel, unsigned short addr, unsigned char blocks,
unsigned char* data);
BOOL mxkSetMainId(const unsigned char* main_id);
BOOL mxkGetMainId(unsigned char* main_id);
BOOL mxkGetKeyId(unsigned char* main_id);
BOOL mxkGetPlayCounter(DWORD* play_counter);
BOOL mxkFlashRead(unsigned int address, unsigned int nbytes, unsigned char* buffer);
BOOL mxkEepromRead(unsigned char page, unsigned char* data);
BOOL mxkNvramRead(unsigned short addr, unsigned char blocks, unsigned char* data);

View File

@ -0,0 +1,149 @@
#include "mxkAb.h"
#include "mxkPacket.h"
#include "mxkTransport.h"
APP_BOOT AppBoot;
MXK_STATUS mxkGetAppBootInfo(void) {
unsigned char packet[16];
MXK_STATUS status;
if (mxkPacketReqGetAppBootInfo(packet) != MXK_STATUS_OK) {
amiDebugLog("Error mxkPacketReqGetAppBootInfo");
return MXK_STATUS_ERROR;
}
status = mxkSendPacket(packet);
if (status != MXK_STATUS_OK) {
amiDebugLog("Error mxkSendPacket GetAppBootInfo");
return status;
}
appboot_t appBoot;
for (int i = 0; i < sizeof appBoot; i += 16) {
status = mxkRecvPacket((unsigned char*)(&appBoot) + i);
if (status != MXK_STATUS_OK) {
amiDebugLog("Error mxkRecvPacket AppBootInfo");
return status;
}
}
amiCrc32RInit();
if (amiCrc32RCalc(sizeof appBoot - 4, (unsigned char*)&appBoot + 4, 0) != appBoot.crc) {
amiDebugLog("Error CRC AppBootInfo");
return MXK_STATUS_ERROR;
}
memcpy(&AppBoot.m_Cache, &appBoot, sizeof appBoot);
AppBoot.m_cacheDirty = false;
return MXK_STATUS_OK;
}
MXK_STATUS mxkAbSystemFlag(MXK_CACHE cache, unsigned char* systemFlag, unsigned char* err) {
if (systemFlag == NULL || (err == NULL)) return MXK_STATUS_INVALID_PARAM;
if (KEYCHIP_STATUS == 2) {
*err = KEYCHIP_ERROR;
return MXK_STATUS_ERROR;
}
MXK_STATUS status;
*err = 0;
if (cache == MXK_CACHE_USE) {
if (AppBoot.m_cacheDirty != true) goto LAB_00401d7b;
} else {
AppBoot.m_cacheDirty = true;
}
if (!AppBoot.m_useFlash) {
// TODO: N2
// if (HAS_N2 == true) {
// status = mxkGetKeychipIdFromN2();
// if (status == 0) goto LAB_00401d7b;
// mxkN2GetErrorCode(status);
// if (0 < LOG_EN_MXK) {
// log("mxkAbSystemFlag", 0x338, "Error mxkGetKeychipIdFromN2!!\n");
// }
// goto LAB_00401d64;
// }
status = mxkGetAppBootInfo();
} else {
status = MXK_STATUS_ERROR;
// TODO: This
// status = appboot_flash();
}
if (status == MXK_STATUS_OK) {
LAB_00401d7b:
if (AppBoot.m_Cache.format != 1) {
*systemFlag = 0;
return MXK_STATUS_OK;
}
*systemFlag = AppBoot.m_Cache.system_flag;
return MXK_STATUS_OK;
}
// LAB_00401d64:
KEYCHIP_ERROR = 2;
KEYCHIP_STATUS = 2;
*err = 2;
return MXK_STATUS_ERROR;
}
MXK_STATUS mxkAbGameId(MXK_CACHE cache, char* gameId, unsigned char* err) {
if (gameId == NULL || (err == NULL)) return MXK_STATUS_INVALID_PARAM;
if (KEYCHIP_STATUS == 2) {
*err = KEYCHIP_ERROR;
return MXK_STATUS_ERROR;
}
*err = 0;
if (cache == false) {
if (AppBoot.m_cacheDirty != true) goto LAB_00401c7f;
} else {
AppBoot.m_cacheDirty = true;
}
MXK_STATUS status;
if (!AppBoot.m_useFlash) {
// if (HAS_N2 == true) {
// status = mxkGetKeychipIdFromN2();
// if (status == 0) goto LAB_00401c7f;
// mxkN2GetErrorCode(status);
// if (0 < LOG_EN_MXK) {
// log("mxkAbGameId", 0x2f5, "Error mxkGetKeychipIdFromN2!!\n");
// KEYCHIP_ERROR = 2;
// KEYCHIP_STATUS = 2;
// *err = 2;
// return 1;
// }
// goto LAB_00401c6a;
// }
status = MXK_STATUS_ERROR;
// TODO: This
status = mxkGetAppBootInfo();
} else {
// status = appboot_flash();
}
if (status == MXK_STATUS_OK) {
LAB_00401c7f:
if (AppBoot.m_Cache.format != 1) {
gameId[0] = '_';
gameId[1] = '_';
gameId[2] = '_';
gameId[3] = '_';
return MXK_STATUS_OK;
}
if (!mxkValidString(AppBoot.m_Cache.game_id, 4)) {
*err = 55;
return MXK_STATUS_ERROR;
}
memcpy(gameId, AppBoot.m_Cache.game_id, 4);
return MXK_STATUS_OK;
}
LAB_00401c6a:
KEYCHIP_ERROR = 2;
KEYCHIP_STATUS = 2;
*err = 2;
return MXK_STATUS_ERROR;
}

View File

@ -0,0 +1,35 @@
#pragma once
#include <Windows.h>
#include <stdbool.h>
#include "../ami/ami.h"
#include "mxkDefs.h"
#pragma pack(push, 1)
typedef struct {
DWORD crc;
DWORD format;
char game_id[4];
BYTE region;
BYTE model_type;
BYTE system_flag;
BYTE _;
char platform_id[3];
BYTE dvd_flag;
DWORD network_addr;
BYTE __[216];
BYTE seed[16];
} appboot_t;
#pragma pack(pop)
typedef struct {
bool m_useFlash;
bool m_cacheDirty;
appboot_t m_Cache;
} APP_BOOT;
extern APP_BOOT AppBoot;
MXK_STATUS mxkGetAppBootInfo(void);
MXK_STATUS mxkAbSystemFlag(MXK_CACHE cache, unsigned char* systemFlag, unsigned char* err);
MXK_STATUS mxkAbGameId(MXK_CACHE cache, char* gameId, unsigned char* err);

View File

@ -1,14 +1,20 @@
#include "mxkCrypt.h"
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/hmac.h>
#include "mxk.h"
unsigned char KEY_R[16] = {
// These three should be initialised to null, and populated by mxkCryptInit, but we already know
// their values and aren't trying to hide them from anyone! mxkCryptInit is still fully implemented,
// but is a no-op unless MXK_CRYPT_HAS_INIT is manually set to FALSE.
static unsigned char KEY_R[16] = {
0x75, 0x6f, 0x72, 0x61, 0x74, 0x6e, 0x65, 0x6b, 0x61, 0x6d, 0x69, 0x68, 0x73, 0x75, 0x6b, 0x75,
};
unsigned char KEY_S[16] = {
static unsigned char KEY_S[16] = {
0x66, 0x6E, 0x65, 0x6B, 0x65, 0x72, 0x61, 0x77, 0x64, 0x72, 0x61, 0x68, 0x61, 0x67, 0x65, 0x73,
};
static unsigned char TRACEDATA_DES_KEY[16] = { 0x4d, 0x77, 0xf1, 0x74, 0x8d, 0x6d, 0x10, 0x94 };
BOOL MXK_CRYPT_HAS_INIT = TRUE;
unsigned char BILLING_PRIVKEY[] =
("-----BEGIN PRIVATE KEY-----\n"
@ -96,6 +102,48 @@ unsigned char BILLING_CACERT[] = {
0xca,
};
MXK_STATUS mxkCryptInit(void) {
static unsigned char KEY_HIDDEN[4][16] = { { 0xd8, 0x4f, 0x03, 0x08, 0x48, 0x92, 0xcb, 0x4a,
0xfc, 0x47, 0x75, 0x2b, 0xf9, 0xb1, 0x4f, 0x97 },
{ 0xbe, 0x21, 0x66, 0x63, 0x2d, 0xe0, 0xaa, 0x3d,
0x98, 0x35, 0x14, 0x43, 0x98, 0xd6, 0x2a, 0xe4 },
{ 0x07, 0xca, 0x77, 0x01, 0x63, 0x2b, 0x36, 0x60,
0xb5, 0x2d, 0x8f, 0x77, 0x41, 0x4e, 0x18, 0x5a },
{ 0x72, 0xa5, 0x05, 0x60, 0x17, 0x45, 0x53, 0x0b,
0xd4, 0x40, 0xe6, 0x1f, 0x32, 0x3b, 0x73, 0x2f } };
if (MXK_CRYPT_HAS_INIT) return 0;
/**
* SEGA's loose attempt at hiding the real encryption keys
*
* static unsigned char KEY_R[16] = {
* 0x75, 0x6f, 0x72, 0x61, 0x74, 0x6e, 0x65, 0x6b,
* 0x61, 0x6d, 0x69, 0x68, 0x73, 0x75, 0x6b, 0x75,
* };
* static unsigned char KEY_S[16] = {
* 0x66, 0x6E, 0x65, 0x6B, 0x65, 0x72, 0x61, 0x77,
* 0x64, 0x72, 0x61, 0x68, 0x61, 0x67, 0x65, 0x73,
* };
*/
for (int i = 0; i < 16; i++) {
KEY_R[i] = KEY_HIDDEN[0][i] ^ KEY_HIDDEN[1][i];
KEY_S[i] = KEY_HIDDEN[2][i] ^ KEY_HIDDEN[3][i];
}
TRACEDATA_DES_KEY[0] = 0x4d;
TRACEDATA_DES_KEY[1] = 0x77;
TRACEDATA_DES_KEY[2] = 0xf1;
TRACEDATA_DES_KEY[3] = 0x74;
TRACEDATA_DES_KEY[4] = 0x8d;
TRACEDATA_DES_KEY[5] = 0x6d;
TRACEDATA_DES_KEY[6] = 0x10;
TRACEDATA_DES_KEY[7] = 0x94;
MXK_CRYPT_HAS_INIT = TRUE;
return 0;
}
void mxkSetKeyS(unsigned char* key_s) { memcpy(KEY_S, key_s, 16); }
void mxkSetKeyR(unsigned char* key_r) { memcpy(KEY_R, key_r, 16); }
void mxkSwapKeys() {
@ -105,7 +153,13 @@ void mxkSwapKeys() {
memcpy(KEY_S, temp, 16);
}
void mxkCryptEncryptAes128CBC(const unsigned char* key, const unsigned char* iv, unsigned char* ct, const unsigned char* pt, size_t nbytes) {
MXK_STATUS mxkCryptEncryptAes128CBC(const unsigned char* key, const unsigned char* iv,
unsigned char* ct, const unsigned char* pt, size_t nbytes) {
if (key == NULL || iv == NULL || ct == NULL || pt == NULL) {
amiDebugLog("Error: Invalid param.");
return MXK_STATUS_INVALID_PARAM;
}
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv, 1);
@ -114,9 +168,17 @@ void mxkCryptEncryptAes128CBC(const unsigned char* key, const unsigned char* iv,
unsigned char dump[16];
EVP_EncryptFinal_ex(ctx, dump, &outl);
EVP_CIPHER_CTX_free(ctx);
return MXK_STATUS_OK;
}
void mxkCryptDecryptAes128CBC(const unsigned char* key, const unsigned char* iv, const unsigned char* ct, unsigned char* pt, size_t nbytes) {
MXK_STATUS mxkCryptDecryptAes128CBC(const unsigned char* key, const unsigned char* iv,
const unsigned char* ct, unsigned char* pt, size_t nbytes) {
if (key == NULL || iv == NULL || ct == NULL || pt == NULL) {
amiDebugLog("Error: Invalid param.");
return MXK_STATUS_INVALID_PARAM;
}
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv, 0);
@ -125,28 +187,52 @@ void mxkCryptDecryptAes128CBC(const unsigned char* key, const unsigned char* iv,
unsigned char dump[16];
EVP_EncryptFinal_ex(ctx, dump, &outl);
EVP_CIPHER_CTX_free(ctx);
return MXK_STATUS_OK;
}
void mxkCryptEncryptData(unsigned char* ct, const unsigned char* pt) {
MXK_STATUS mxkCryptEncryptData(unsigned char* ct, const unsigned char* pt) {
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
EVP_CipherInit_ex(ctx, EVP_aes_128_ecb(), NULL, KEY_S, NULL, 1);
if (!MXK_CRYPT_HAS_INIT) {
amiDebugLog("Error no init!!!");
return MXK_STATUS_NO_INIT;
}
if (ct == NULL || pt == NULL) {
amiDebugLog("Error invalid param!!!");
return MXK_STATUS_INVALID_PARAM;
}
int outl;
EVP_EncryptUpdate(ctx, ct, &outl, pt, 16);
unsigned char dump[16];
EVP_EncryptFinal_ex(ctx, dump, &outl);
EVP_CIPHER_CTX_free(ctx);
return MXK_STATUS_OK;
}
void mxkCryptDecryptData(const unsigned char* ct, unsigned char* pt) {
MXK_STATUS mxkCryptDecryptData(const unsigned char* ct, unsigned char* pt) {
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
EVP_CipherInit_ex(ctx, EVP_aes_128_ecb(), NULL, KEY_R, NULL, 0);
if (!MXK_CRYPT_HAS_INIT) {
amiDebugLog("Error no init!!!");
return MXK_STATUS_NO_INIT;
}
if (ct == NULL || pt == NULL) {
amiDebugLog("Error invalid param!!!");
return MXK_STATUS_INVALID_PARAM;
}
int outl;
EVP_DecryptUpdate(ctx, pt, &outl, ct, 16);
unsigned char dump[16];
EVP_EncryptFinal_ex(ctx, dump, &outl);
EVP_CIPHER_CTX_free(ctx);
return MXK_STATUS_OK;
}
void mxkSign(void* buffer, size_t nbytes, unsigned char* signature) {
@ -172,6 +258,8 @@ typedef struct {
} sign_payload_t;
#pragma pack(pop)
// TODO: Move this all
unsigned char KEYCHIP_ID[16];
void mxkSignValue(unsigned int value, unsigned char* signature) {
sign_payload_t hash_data;
hash_data.value = value;
@ -179,3 +267,40 @@ void mxkSignValue(unsigned int value, unsigned char* signature) {
memcpy(hash_data.key_high, &KEYCHIP_ID[5], 7);
mxkSign(&hash_data, sizeof hash_data, signature);
}
int mxkCryptCalcHashWithHmacSha1(void* key, unsigned char* md, size_t* nbuffer,
unsigned char* buffer, size_t nin) {
if (key == NULL || buffer == NULL || md == NULL || nbuffer == NULL) {
amiDebugLog("Error: Invalid param.");
return 3;
}
if (*nbuffer < 20) {
amiDebugLog("Error: Datasize is too small.");
return 3;
}
// int len = 20;
// /* Load the openssl hasher */
// EVP_MD *md = FUN_00412e70();
// FUN_00415cd0(md, key, len, buffer, nin, md, nbuffer);
// return 0;
HMAC_CTX hmac_ctx;
HMAC_CTX_init(&hmac_ctx);
HMAC_Init_ex(&hmac_ctx, key, 20, EVP_sha1(), NULL);
HMAC_Update(&hmac_ctx, buffer, nin);
HMAC_Final(&hmac_ctx, md, nbuffer);
HMAC_CTX_cleanup(&hmac_ctx);
return 0;
}
void mxkCryptCalcHashWithSha1(unsigned char* data, size_t nbytes, unsigned char* sum) {
EVP_MD_CTX* ctx = EVP_MD_CTX_create();
EVP_DigestInit(ctx, EVP_sha1());
EVP_DigestUpdate(ctx, data, nbytes);
unsigned int outlen;
EVP_DigestFinal_ex(ctx, sum, &outlen);
EVP_MD_CTX_destroy(ctx);
}

View File

@ -0,0 +1,29 @@
#pragma once
#include <Windows.h>
#include "../ami/ami.h"
#include "mxkDefs.h"
void mxkSetKeyS(unsigned char* key_s);
void mxkSetKeyR(unsigned char* key_r);
void mxkSwapKeys();
MXK_STATUS mxkCryptInit(void);
int mxkCryptCalcHashWithHmacSha1(void* key, unsigned char* md, size_t* nbuffer,
unsigned char* buffer, size_t nin);
void mxkCryptCalcHashWithSha1(unsigned char* data, size_t nbytes, unsigned char* sum);
void mxkCryptCreateDigest(void);
void mxkCryptRsaSignVerify(void);
MXK_STATUS mxkCryptDecryptAes128CBC(const unsigned char* key, const unsigned char* iv,
const unsigned char* ct, unsigned char* pt, size_t nbytes);
MXK_STATUS mxkCryptEncryptAes128CBC(const unsigned char* key, const unsigned char* iv,
unsigned char* pt, const unsigned char* ct, size_t nbytes);
MXK_STATUS mxkCryptDecryptData(const unsigned char* ct, unsigned char* pt);
MXK_STATUS mxkCryptEncryptData(unsigned char* ct, const unsigned char* pt);
void mxkSign(void* buffer, size_t nbytes, unsigned char* signature);
void mxkSignValue(unsigned int value, unsigned char* signature);

View File

@ -0,0 +1,105 @@
#pragma once
#include <stdbool.h>
#define MXK_BLOCK_SIZE 16
// TODO: ??
extern unsigned int KEYCHIP_STATUS;
extern unsigned char KEYCHIP_ERROR;
enum {
SetKeyS = 0, // mxkPacketReqSetKeyS [0] [...
SetKeyR = 1, // mxkPacketReqSetKeyR [1] [...
SetIV = 2, // mxkPacketReqSetIv [2] [...
Decrypt = 3, // mxkPacketReqDecrypt [3] [...
Encrypt = 4, // mxkPacketReqEncrypt [4] [...
GetAppBootInfo = 5, // mxkPacketReqGetAppBootInfo [5] [0] [...
EepromWrite = 6, // mxkPacketReqEepromWrite [6] [x] [...
EepromRead = 7, // mxkPacketReqEepromRead [7] [x] [...
NvramWrite = 8, // mxkPacketReqNvramWrite [8] [x] [x] [y] [...
NvramRead = 9, // mxkPacketReqNvramRead [9] [x] [x] [y] [...
AddPlayCount = 10, // mxkPacketReqAddPlayCount [10] [...
FlashRead = 11, // mxkPacketReqFlashRead [11] [x] [x] [x] [y] [y] [y] [...
FlashErase = 12, // mxkPacketReqFlashErase [12] [x] [x] [x] [...
KcCmd13 = 13, // mxkPacketReq-13 [13] [x] [x] [x] [...
FlashWrite = 14, // mxkPacketReqFlashWrite [14] [x] [x] [x] [y] [y] [y] [...
KcCmd15 = 15, //
KcCmd16 = 16, //
KcCmd17 = 17, //
KcCmd18 = 18, //
KcCmd19 = 19, //
KcGetVersion = 20, // mxkPacketReqGetVersion [20] [...
SetMainId = 21, // mxkPacketReqSetMainId [21] [...
GetMainId = 22, // mxkPacketReqGetMainId [22] [...
SetKeyId = 23, // mxkPacketReqSetKeyId [23] [...
GetKeyId = 24, // mxkPacketReqGetKeyId [24] [...
GetPlayCounter = 25, // mxkPacketReqGetPlayCounter [25] [...
};
typedef enum {
MXK_CACHE_USE = 0,
MXK_CACHE_BUST = 1,
} MXK_CACHE;
typedef enum {
MXK_STATUS_INVALID_PARAM_1 = -1,
MXK_STATUS_OK = 0,
MXK_STATUS_ERROR = 1,
MXK_STATUS_NO_INIT = 2,
MXK_STATUS_INVALID_PARAM = 3,
// 5?
MXK_STATUS_CRYPT_NG = 4,
MXK_STATUS_SEND_NG = 6,
MXK_STATUS_RECV_NG = 7,
} MXK_STATUS;
typedef enum {
MXK_TRANSPORT_STATUS_OK = 0,
MXK_TRANSPORT_STATUS_BUSY = 1,
MXK_TRANSPORT_STATUS_NG = -1,
// -3?
MXK_TRANSPORT_STATUS_NO_INIT = -2,
MXK_TRANSPORT_STATUS_SEND_NG = -4,
MXK_TRANSPORT_STATUS_RECV_NG = -5,
} MXK_TRANSPORT_STATUS;
typedef enum {
PARALLEL_STATUS_IRQ = 0x04,
PARALLEL_STATUS_ERROR = 0x08,
PARALLEL_STATUS_SELECT_IN = 0x10,
PARALLEL_STATUS_PAPER_OUT = 0x20,
PARALLEL_STATUS_ACK = 0x40,
PARALLEL_STATUS_BUSY = 0x80,
} PARALLEL_STATUS;
typedef enum {
PARALLEL_CONTROL_STROBE = 0x01,
PARALLEL_CONTROL_AUTO_LF = 0x02,
PARALLEL_CONTROL_INITIALISE = 0x04,
PARALLEL_CONTROL_SELECT = 0x08,
PARALLEL_CONTROL_IRQACK = 0x10,
PARALLEL_CONTROL_BIDI = 0x20,
} PARALLEL_CONTROL;
typedef enum {
PARALLEL_EC_FIFO_EMPTY = 0x01,
PARALLEL_EC_FIFO_FULL = 0x02,
PARALLEL_EC_ECP_SERVICE = 0x04,
PARALLEL_EC_DMA_ENABLE = 0x08,
PARALLEL_EC_ECP_INTERRUPT = 0x10,
} PARALLEL_EXTENDED_CONTROL;
typedef enum {
PARALLEL_EC_MODE_STANDARD = 0x00,
PARALLEL_EC_MODE_BYTE,
PARALLEL_EC_MODE_PARALLEL_FIFO,
PARALLEL_EC_MODE_ECP_FIFO,
PARALLEL_EC_MODE_EPP,
PARALLEL_EC_MODE_RESERVED,
PARALLEL_EC_MODE_FIFO_TEST,
PARALLEL_EC_MODE_CONFIGURATION,
} PARALLEL_EXTENDED_CONTROL_MODE;
bool mxkValidString(const char* string, unsigned int length);

View File

@ -0,0 +1,269 @@
#include <Windows.h>
//
#include "../../dll/devices/smb_ds2460.h"
#include "../../dll/devices/smb_ds28cn01.h"
#include "../ami/ami.h"
#include "mxkDs.h"
#include "mxkSmbus.h"
// TODO: Better name
static unsigned int randomNumberFromTime(void) {
FILETIME fileTime;
amtime_t amTime;
amiTimerGet(&amTime);
GetSystemTimeAsFileTime(&fileTime);
return amTime.microseconds ^ fileTime.dwLowDateTime ^ fileTime.dwHighDateTime;
}
bool mxkDsExioWaitNotBusy(void) {
amtime_t start;
amtime_t now;
amiTimerGet(&start);
while (1) {
amiTimerGet(&now);
unsigned char val = 0;
if (mxkSmbusReadByte(SYS_DS_ADDRESS, &val, 0) == 0) return true;
if (amiTimerDiffUsec(&start, &now) > 1000000) return false;
Sleep(10);
}
}
int mxkDsExioRequestComputeMac(void) {
if (mxkSmbusRequestMutex() != 0) return -7;
if (mxkSmbusWriteByte(SYS_DS_ADDRESS, 0x5c, 0x94) != 0) return -9;
if (!mxkDsExioWaitNotBusy()) return -10;
return mxkSmbusReleaseMutex();
}
int INT_004ab34c = 1; // TODO: What?
int mxkDsKeychipComputeMac(unsigned char page, void *challenge, unsigned char *mac, int flag) {
if (INT_004ab34c == 0) return -3;
if (mac == NULL || challenge == NULL || page > 3) return -2;
unsigned char buffer[7];
unsigned char command_code = (flag ? DS28CN01_COMPUTE_1 : DS28CN01_COMPUTE_2) | (page & 3);
memcpy_s(buffer, sizeof buffer, challenge, 7);
if (mxkSmbusRequestMutex() != 0) return -7;
int error = 0;
int status = mxkSmbusI2CWriteCommand(command_code, buffer, sizeof buffer);
if (status == 0) {
Sleep(16);
status = mxkDsWaitNotBusy(&INT_004ab34c);
if (status == 0) {
if (!mxkSmbusI2CReadBlock(KC_DS_ADDRESS, DS28CN01_REG_MAC, mac, 20)) {
amiDebugLog("Error mxkSmbusI2CReadBlock()!!!");
error = -8;
}
} else {
error = status;
amiDebugLog("Error mxkDsKeychipBusy()!!! code:%d", status);
}
} else {
amiDebugLog("Error mxkSmbusI2CWriteCommand()!!!");
error = -9;
}
if (mxkSmbusReleaseMutex() != 0) {
amiDebugLog("ReleaseMutex Error(%d).\n", GetLastError());
return -5;
}
return error;
}
int mxkDsGetUniqueNumber(unsigned char *param_1) {
if (INT_004ab34c == 0) return -3;
if (param_1 == NULL) return -2;
if (mxkSmbusRequestMutex() != 0) return -7;
unsigned char cmd_code = 0xa0;
for (int i = 0; i < 8; i++) {
if (mxkSmbusReadByte(KC_DS_ADDRESS, &param_1[i], cmd_code) != 0) return -8;
cmd_code += 1;
}
return mxkSmbusReleaseMutex();
}
bool mxkDsMakeSha1InputForVerify(unsigned char page, dsShaPayload_t *payload,
unsigned char *challenge) {
if (payload == NULL || challenge == NULL) return false;
unsigned char uniqueId[8] = { 0 };
if (mxkDsGetUniqueNumber(uniqueId) != 0) {
amiDebugLog("Error mxkDsGetUniqueNumber()!!!");
return false;
}
unsigned char pageData[32] = { 0 };
if (mxkDsKeychipReadEeprom(pageData, page) != 0) {
amiDebugLog("Error mxkDsKeychipReadEeprom()!!!");
return false;
}
unsigned char random[20];
for (int i = 0; i < 17; i++) random[i] = randomNumberFromTime() & 0xff;
memcpy(payload->Unk0, random, 4);
memcpy(payload->m_EepromPage, pageData, sizeof pageData);
memcpy(payload->m_ChallengeLow, challenge, 4);
payload->m_Page = page & 3 | 0x40;
memcpy(payload->m_UniqueId, uniqueId, 7);
memcpy(payload->Unk30, random + 4, 4);
memcpy(payload->m_ChallengeHigh, challenge + 4, 3);
memcpy(payload->Unk37, random + 8, 9);
return true;
}
int mxkDsWaitNotBusy(int *param_1) {
if (param_1 == NULL) return -2;
amtime_t now;
amtime_t start;
amiTimerGet(&start);
amiTimerGet(&now);
unsigned char status;
while (1) {
if (mxkSmbusReadByte(KC_DS_ADDRESS, &status, 0xa8) != 0) return -8;
if ((status & 2) == 0) return 0;
if (amiTimerDiffUsec(&start, &now) > 1000000) return -10;
Sleep(10);
amiTimerGet(&now);
}
}
int mxkDsKeychipReadEeprom(unsigned char *pageData, unsigned char page) {
if (INT_004ab34c == 0) return -3;
if (pageData == NULL || page > 3) return -2;
if (mxkSmbusRequestMutex() != 0) return -7;
int err = 0;
unsigned char addr = (page << 5) & 0xff;
for (int i = 0; i < 32; i++) {
if (mxkSmbusReadByte(KC_DS_ADDRESS, &pageData[i], addr) != 0) {
err = -8;
break;
}
addr += 1;
}
if (mxkSmbusReleaseMutex() != 0) {
amiDebugLog("ReleaseMutex Error(%d).", GetLastError());
return -5;
}
return err;
}
int mxkDsExioWriteInputBuffer(dsShaPayload_t *buffer) {
if (INT_004ab34c == 0) return -3;
if (buffer == NULL) return -2;
if (mxkSmbusRequestMutex() != 0) return -7;
int error = 0;
unsigned char offset = 0;
for (int i = 0; i < 64;) {
unsigned char nbytes = (64 - i <= 8) ? 64 - offset : 8;
if (mxkSmbusI2CWriteBlock(SYS_DS_ADDRESS, offset, &((unsigned char *)buffer)[offset], nbytes) !=
0) {
error = -9;
break;
}
if (!mxkDsExioWaitNotBusy()) {
error = -10;
break;
}
offset += nbytes;
i = offset & 0xffff;
}
if (mxkSmbusReleaseMutex() != 0) {
amiDebugLog("ReleaseMutex Error(%d).", GetLastError());
error = -5;
}
return (int)error;
}
int mxkDsExioReadMacOutputBuffer(unsigned char *macBuffer) {
if (INT_004ab34c == 0) return -3;
if (macBuffer == NULL) return -2;
if (mxkSmbusRequestMutex() != 0) return -7;
unsigned char cmd_code = 0x40;
for (int offset = 0; offset < 20; offset++, cmd_code++) {
if (mxkSmbusReadByte(SYS_DS_ADDRESS, &macBuffer[offset], cmd_code) != 0) {
if (!mxkSmbusReleaseMutex()) return -5;
return -8;
}
}
return mxkSmbusReleaseMutex();
}
int mxkAuthenticationDs(void) {
FILETIME sysTime;
amtime_t amTime;
unsigned char randomMacChallenge[8];
unsigned char keychipMac[20];
unsigned char mezzanineMac[20];
dsShaPayload_t sha1_payload;
int e = 0;
for (int i = 0; i < 7; i++) {
amiTimerGet(&amTime);
GetSystemTimeAsFileTime(&sysTime);
randomMacChallenge[i] = (unsigned char)sysTime.dwHighDateTime ^
(unsigned char)sysTime.dwLowDateTime ^
(unsigned char)amTime.microseconds;
}
amiTimerGet(&amTime);
GetSystemTimeAsFileTime(&sysTime);
unsigned char page =
((unsigned char)sysTime.dwHighDateTime ^ (unsigned char)sysTime.dwLowDateTime ^
(unsigned char)amTime.microseconds) &
3;
if (mxkDsKeychipComputeMac(page, randomMacChallenge, keychipMac, 1) != 0) {
amiDebugLog("Error mxkDsKeychipComputeMac()!!!");
return 1;
}
if (mxkDsMakeSha1InputForVerify(page, &sha1_payload, randomMacChallenge) == 0) {
amiDebugLog("Error mxkDsMakeSha1InputForVerify()!!!");
return 1;
}
e = mxkDsExioWriteInputBuffer(&sha1_payload);
if (e != 0) {
amiDebugLog("Error mxkDsExioWriteInputBuffer()!!! code:%d", e);
return 1;
}
e = mxkDsExioRequestComputeMac();
if (e != 0) {
amiDebugLog("Error mxkDsExioRequestComputeMac()!!! code:%d", e);
return 1;
}
e = mxkDsExioReadMacOutputBuffer(mezzanineMac);
if (e != 0) {
amiDebugLog("Error mxkDsExioReadMacOutputBuffer()!!! code:%d", e);
return 1;
}
if (memcmp(keychipMac, mezzanineMac, sizeof keychipMac) == 0) return 0;
amiDebugLog("Error Mac Verify!!!");
return 1;
}

View File

@ -0,0 +1,26 @@
#pragma pack(push, 1)
typedef struct {
unsigned char Unk0[4];
unsigned char m_EepromPage[32];
unsigned char m_ChallengeLow[4];
unsigned char m_Page;
unsigned char m_UniqueId[7];
unsigned char Unk30[4];
unsigned char m_ChallengeHigh[3];
unsigned char Unk37[9];
} dsShaPayload_t;
#pragma pack(pop)
bool mxkDsExioWaitNotBusy(void);
int mxkDsExioRequestComputeMac(void);
int mxkDsExioWriteInputBuffer(dsShaPayload_t *buffer);
int mxkDsExioReadMacOutputBuffer(unsigned char *macBuffer);
int mxkDsWaitNotBusy(int *param_1);
int mxkDsKeychipComputeMac(unsigned char page, void *challenge, unsigned char *mac, int flag);
int mxkDsGetUniqueNumber(unsigned char *param_1);
bool mxkDsMakeSha1InputForVerify(unsigned char page, dsShaPayload_t *payload,
unsigned char *challenge);
int mxkDsKeychipReadEeprom(unsigned char *pageData, unsigned char page);
int mxkAuthenticationDs(void);

View File

@ -0,0 +1,313 @@
#include <Windows.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include "../../dll/devices/smb_n2.h"
#include "../ami/ami.h"
#include "mxkCrypt.h"
#include "mxkSmbus.h"
#define N2_ADDR 0x30
typedef struct {
unsigned char m_Key[16];
unsigned char m_IV[16];
} AESKey_t;
typedef struct {
unsigned short m_Tag;
unsigned short m_ParamSize;
unsigned short m_Command;
unsigned char m_Body[506];
} N2Packet_t;
BOOL MXK_HAS_INIT = FALSE;
BOOL MXK_N2_INIT = FALSE;
typedef struct {
unsigned char m_Addr;
unsigned char m_HmacKey[20];
AESKey_t m_AESKey;
unsigned char m_AuthKey[20];
unsigned char m_EncKey[16];
unsigned char Unk[16];
unsigned char m_HmacOut[20];
} N2DeviceInfo_t;
N2DeviceInfo_t N2DeviceInfo;
unsigned char N2_KEY_HMAC[2][20] = {
{ 0x2c, 0xf8, 0x3e, 0x5e, 0x51, 0xf0, 0x60, 0x1b, 0xf6, 0xb1,
0x49, 0x11, 0x3a, 0xaf, 0x36, 0xe1, 0x51, 0x1c, 0x16, 0x05 },
{ 0xba, 0x15, 0x0f, 0xec, 0x79, 0x81, 0x65, 0xbe, 0x55, 0x81,
0x1d, 0x1e, 0x1f, 0x11, 0xee, 0xb0, 0xf4, 0xd4, 0x20, 0x24 }
};
AESKey_t N2_KEY_AES[2] = { { { 0xd7, 0xf6, 0x86, 0xfb, 0x63, 0x44, 0xff, 0xa5, 0x60, 0x9d, 0x4e,
0xf0, 0x18, 0xe9, 0x45, 0xb4 },
{ 0x12, 0x6c, 0xb1, 0xdb, 0x9e, 0x00, 0x8c, 0xc6, 0xae, 0xa1, 0x73,
0xec, 0xe7, 0x2f, 0x5a, 0xc4 } },
{ { 0xa1, 0x1a, 0xc4, 0x4d, 0xcd, 0x48, 0x4f, 0xed, 0x70, 0xcc, 0x3f,
0x5d, 0x94, 0x5b, 0xbe, 0xb3 },
{ 0x9c, 0x5c, 0xba, 0x7f, 0xb0, 0x15, 0xc7, 0x69, 0xcb, 0xb4, 0x41,
0x19, 0x97, 0x2b, 0x45, 0x9f } } };
int mxkN2CmdInit(void) {
if (MXK_N2_INIT) {
amiDebugLog("Error: Already initialized.");
return -4;
}
ZeroMemory(&N2DeviceInfo, sizeof N2DeviceInfo);
MXK_N2_INIT = TRUE;
return 0;
}
int mxkN2CmdSetDeviceInfo(void) {
if (MXK_HAS_INIT) return -4;
if (mxkN2CmdInit() != 0) return -5;
unsigned char hmacKey[20];
AESKey_t aesKey;
for (int i = 0; i < sizeof hmacKey; i++) hmacKey[i] = N2_KEY_HMAC[0][i] ^ N2_KEY_HMAC[1][i];
for (int i = 0; i < sizeof aesKey.m_Key; i++)
aesKey.m_Key[i] = N2_KEY_AES[0].m_Key[i] ^ N2_KEY_AES[1].m_Key[i];
for (int i = 0; i < sizeof aesKey.m_IV; i++)
aesKey.m_IV[i] = N2_KEY_AES[0].m_IV[i] ^ N2_KEY_AES[1].m_IV[i];
N2DeviceInfo_t deviceInfo = { 0 };
deviceInfo.m_Addr = N2_ADDR;
memcpy(&deviceInfo.m_HmacKey, hmacKey, sizeof hmacKey);
memcpy(&deviceInfo.m_AESKey, &aesKey, sizeof aesKey);
if (!MXK_N2_INIT)
amiDebugLog("Error: Uninitialized.");
else
memcpy(&N2DeviceInfo, &deviceInfo, sizeof deviceInfo);
MXK_HAS_INIT = TRUE;
return 0;
}
// TODO: Better name
void _randomBytes(unsigned char *buf, int nbytes) {
FILETIME fileTime;
amtime_t amTime;
for (int i = 0; i < nbytes; i++) {
amiTimerGet(&amTime);
GetSystemTimeAsFileTime(&fileTime);
buf[i] = (amTime.microseconds ^ fileTime.dwLowDateTime ^ fileTime.dwHighDateTime) & 0xff;
}
}
void mxkN2GetPacketNonce(unsigned char *nonce) { _randomBytes(nonce, 20); }
int mxkN2UtilVCatenateData(unsigned char *out, size_t *count, unsigned int numStreams,
va_list args) {
if (out == NULL || count == NULL) {
amiDebugLog("Error: Invalid param.");
return -2;
}
size_t offset = 0;
size_t max = *count;
for (size_t i = 0; i < numStreams && i < max; i++) {
size_t n = va_arg(args, size_t);
unsigned char *b = va_arg(args, unsigned char *);
if (i + n > max) n = max - i;
memcpy(out + offset, b, i);
}
*count = offset;
return 0;
}
void mxkN2UtilCatenateData(unsigned char *concatinated, size_t *count, unsigned int numStreams,
...) {
va_list args;
va_start(args, numStreams);
mxkN2UtilVCatenateData(concatinated, count, numStreams, args);
va_end(args);
}
void mxkN2UtilSha1Many(unsigned char *sum, int numStreams, ...) {
va_list args;
va_start(args, numStreams);
unsigned char sumout[20];
unsigned char concatinated[0x200];
size_t size = sizeof concatinated;
mxkN2UtilVCatenateData(concatinated, &size, numStreams, args);
mxkCryptCalcHashWithSha1(concatinated, size, sumout);
memcpy_s(sum, 20, sumout, 20);
va_end(args);
}
int mxkN2UtilHmacPacket(void *val1, unsigned char *sha1, void *nonce, void *key,
unsigned char *hash_out) {
unsigned char hash[20];
unsigned char data_in[60];
size_t count = 60;
size_t nout = 20;
mxkN2UtilCatenateData(data_in, &count, 3, val1, 20, sha1, 20, nonce, 20);
int iVar1 = mxkCryptCalcHashWithHmacSha1(key, hash, &nout, data_in, count);
if (iVar1 != -2 && nout == 20) {
memcpy(hash_out, hash, 20);
return 0;
}
return -2;
}
int mxkN2CmdWriteData(unsigned char addr, unsigned char *data, unsigned short nbytes,
unsigned short *nbytesOut) {
unsigned int ptr_;
unsigned char nstep;
int status;
unsigned short position;
if (mxkSmbusRequestMutex() != 0) return -6;
status = 0;
position = 0;
if (nbytes != 0) {
do {
ptr_ = position;
if ((int)(nbytes - ptr_) < 5) {
nstep = (byte)(nbytes - ptr_);
if (nstep != 1) goto LAB_0040ae51;
status = mxkSmbusWriteByte(addr, 0xcc, data[ptr_]);
} else {
nstep = 4;
LAB_0040ae51:
status = mxkSmbusI2CWriteBlock(addr, 0xcc, data + ptr_, nstep);
}
if (status != 0) {
amiDebugLog("Error: Data write failed. Position %d. ErrorCode %d.\n", position,
status);
break;
}
position += nstep;
Sleep(0);
} while (position < nbytes);
}
*nbytesOut = position;
if (!mxkSmbusReleaseMutex()) return -6;
return 0;
}
int mxkN2CmdWriteCommand(unsigned char *param_1, unsigned char *packet, unsigned short tag,
unsigned short command, unsigned char *auth_key, unsigned char addr,
void *data, size_t nbytes) {
int iVar1;
unsigned short real_tag;
unsigned short paramsize;
N2Packet_t cmd;
if (data == NULL && nbytes != 0) return -2;
memset(&cmd, 0, 0x200);
paramsize = (tag == N2_TAG_RQU_COMMAND ? 20 : 0) + 0x14 + (nbytes & 0xffff) + 6;
real_tag = (tag != N2_TAG_RQU_COMMAND) + 0xc1;
cmd.m_Tag = real_tag * 0x100 | real_tag >> 8;
cmd.m_ParamSize = (unsigned short)paramsize << 8 | (unsigned short)paramsize >> 8;
cmd.m_Command = command << 8 | command >> 8;
if (data != NULL) memcpy_s(cmd.m_Body, sizeof cmd.m_Body, data, nbytes);
// SHA1(header | data)
unsigned char packet_sha[20];
mxkN2UtilSha1Many(packet_sha, 1, &cmd, nbytes + 6);
if (tag == N2_TAG_RQU_COMMAND) {
memcpy(cmd.m_Body, packet_sha, 20);
} else {
unsigned char nonce[20];
mxkN2GetPacketNonce(nonce);
memcpy(cmd.m_Body + nbytes, nonce, 20);
mxkN2UtilHmacPacket(packet_sha, param_1, nonce, auth_key, cmd.m_Body + nbytes + 20);
puts("Dodgy HMAC");
exit(1);
}
unsigned short nWrote;
iVar1 = mxkN2CmdWriteData(addr, (unsigned char *)&cmd, paramsize, &nWrote);
if (iVar1 == 0) {
iVar1 = 0;
} else {
amiDebugLog("Error: Data write failed. ErrorCode %d.", iVar1);
iVar1 = -8;
}
return iVar1;
}
int mxkN2CmdEnableSession(void) {
int ret;
unsigned char local_18[20];
if (!MXK_N2_INIT) {
amiDebugLog("Error: Uninitialized.");
return -3;
}
ret = mxkN2CmdWriteCommand(NULL, local_18, N2_TAG_RQU_COMMAND, N2_ORD_ENABLE_SESSION, NULL,
N2DeviceInfo.m_Addr, NULL, 0);
if (ret != 0) return ret;
Sleep(32);
// TODO: ASAP
// ret = mxkN2CmdReadResponce(local_18, NULL, N2_TAG_RQU_COMMAND, N2_ORD_ENABLE_SESSION, NULL,
// N2DeviceInfo.m_Addr, N2DeviceInfo.m_HmacOut, 20);
if (ret != 0) return ret;
Sleep(16);
return 0;
}
int mxkN2Authentication(void) {
// TODO: ASAP
// unsigned char auth_key[20];
// unsigned char enc_key[32];
if (!MXK_HAS_INIT) {
amiDebugLog("No Init Error!!");
return -3;
}
int ErrorCode;
ErrorCode = mxkN2CmdEnableSession();
if (ErrorCode != 0) {
// mxkN2GetErrorCode();
amiDebugLog("Error: mxkN2CmdEnableSession(). ErrorCode %d", ErrorCode);
return -5;
}
// _randomBytes(auth_key, sizeof auth_key);
// ErrorCode = mxkN2CmdSetAuthKey(auth_key);
// if (ErrorCode != 0) {
// mxkN2GetErrorCode();
// amiDebugLog("Error: mxkN2CmdSetAuthKey(). ErrorCode %d", ErrorCode);
// return -5;
// }
// _randomBytes(enc_key, sizeof enc_key);
// ErrorCode = mxkN2CmdSetEncKey(enc_key);
// if (ErrorCode != 0) {
// mxkN2GetErrorCode();
// amiDebugLog("Error: mxkN2CmdSetEncKey().ErrorCode %d", ErrorCode);
// return -5;
// }
// unsigned char auth_level;
// ErrorCode = mxkN2CmdGetAuthLevel(&auth_level);
// if (ErrorCode == 0 && auth_level == 3) return 0;
// mxkN2GetErrorCode();
// amiDebugLog("Error: mxkN2CmdGetAuthLevel().ErrorCode %d", ErrorCode);
return -5;
}

View File

@ -0,0 +1,25 @@
#pragma once
#include <varargs.h>
void _randomBytes(unsigned char *buf, int nbytes);
int mxkN2UtilVCatenateData(unsigned char *out, size_t *count, unsigned int numStreams,
va_list args);
void mxkN2UtilCatenateData(unsigned char *concatinated, size_t *count, unsigned int numStreams,
...);
void mxkN2UtilSha1Many(unsigned char *sum, int numStreams, ...);
int mxkN2UtilHmacPacket(void *val1, unsigned char *sha1, void *nonce, void *key,
unsigned char *hash_out);
int mxkN2CmdWriteCommand(unsigned char *param_1, unsigned char *packet, unsigned short tag,
unsigned short command, unsigned char *auth_key, unsigned char addr,
void *data, size_t nbytes);
int mxkN2CmdEnableSession(void);
int mxkN2CmdSetAuthKey(unsigned char* authKey);
int mxkN2CmdInit(void);
int mxkN2CmdSetDeviceInfo(void);
int mxkN2Authentication(void);

View File

@ -1,4 +1,8 @@
#include "mxk.h"
#include "mxkPacket.h"
#include <Windows.h>
#include "../ami/ami.h"
void inline _mxkPacketInjectJunk(unsigned char* packet, size_t i) {
FILETIME filetime;
@ -12,45 +16,64 @@ void inline _mxkPacketInjectJunk(unsigned char* packet, size_t i) {
}
}
void mxkPacketReqSetKeyS(unsigned char* packet) {
MXK_STATUS mxkPacketReqSetKeyS(unsigned char* packet) {
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
packet[0] = SetKeyS;
_mxkPacketInjectJunk(packet, 1);
return MXK_STATUS_OK;
}
void mxkPacketReqSetKeyR(unsigned char* packet) {
MXK_STATUS mxkPacketReqSetKeyR(unsigned char* packet) {
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
packet[0] = SetKeyR;
_mxkPacketInjectJunk(packet, 1);
return MXK_STATUS_OK;
}
void mxkPacketReqGetAppBootInfo(unsigned char* packet) {
MXK_STATUS mxkPacketReqGetAppBootInfo(unsigned char* packet) {
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
packet[0] = GetAppBootInfo;
packet[1] = 0;
_mxkPacketInjectJunk(packet, 2);
return MXK_STATUS_OK;
}
void mxkPacketReqEepromRead(unsigned char* packet, unsigned char page) {
MXK_STATUS mxkPacketReqEepromRead(unsigned char* packet, unsigned char page) {
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
packet[0] = EepromRead;
packet[1] = page;
_mxkPacketInjectJunk(packet, 2);
return MXK_STATUS_OK;
}
void mxkPacketReqGetVersion(unsigned char* packet) {
MXK_STATUS mxkPacketReqGetVersion(unsigned char* packet) {
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
packet[0] = KcGetVersion;
_mxkPacketInjectJunk(packet, 1);
return MXK_STATUS_OK;
}
void mxkPacketReqSetMainId(unsigned char* packet) {
MXK_STATUS mxkPacketReqSetMainId(unsigned char* packet) {
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
packet[0] = SetMainId;
_mxkPacketInjectJunk(packet, 1);
return MXK_STATUS_OK;
}
void mxkPacketReqGetMainId(unsigned char* packet) {
MXK_STATUS mxkPacketReqGetMainId(unsigned char* packet) {
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
packet[0] = GetMainId;
_mxkPacketInjectJunk(packet, 1);
return MXK_STATUS_OK;
}
void mxkPacketReqGetKeyId(unsigned char* packet) {
MXK_STATUS mxkPacketReqGetKeyId(unsigned char* packet) {
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
packet[0] = GetKeyId;
_mxkPacketInjectJunk(packet, 1);
return MXK_STATUS_OK;
}
void mxkPacketReqGetPlayCounter(unsigned char* packet) {
MXK_STATUS mxkPacketReqGetPlayCounter(unsigned char* packet) {
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
packet[0] = GetPlayCounter;
_mxkPacketInjectJunk(packet, 1);
return MXK_STATUS_OK;
}
void mxkPacketReqFlashRead(unsigned char* packet, unsigned int address, unsigned int nbytes) {
MXK_STATUS mxkPacketReqFlashRead(unsigned char* packet, unsigned int address, unsigned int nbytes) {
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
packet[0] = FlashRead;
packet[1] = address & 0xff;
packet[2] = (address >> 8) & 0xff;
@ -59,11 +82,14 @@ void mxkPacketReqFlashRead(unsigned char* packet, unsigned int address, unsigned
packet[5] = (nbytes >> 8) & 0xff;
packet[6] = (nbytes >> 16) & 0xff;
_mxkPacketInjectJunk(packet, 7);
return MXK_STATUS_OK;
}
void mxkPacketReqNvramRead(unsigned char* packet, unsigned short addr, unsigned char blocks) {
MXK_STATUS mxkPacketReqNvramRead(unsigned char* packet, unsigned short addr, unsigned char blocks) {
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
packet[0] = NvramRead;
packet[1] = addr & 0xff;
packet[2] = (addr >> 8) & 0xff;
packet[3] = blocks;
_mxkPacketInjectJunk(packet, 4);
return MXK_STATUS_OK;
}

View File

@ -0,0 +1,13 @@
#include "mxkDefs.h"
MXK_STATUS mxkPacketReqSetKeyS(unsigned char* packet);
MXK_STATUS mxkPacketReqSetKeyR(unsigned char* packet);
MXK_STATUS mxkPacketReqGetAppBootInfo(unsigned char* packet);
MXK_STATUS mxkPacketReqEepromRead(unsigned char* packet, unsigned char page);
MXK_STATUS mxkPacketReqGetVersion(unsigned char* packet);
MXK_STATUS mxkPacketReqSetMainId(unsigned char* packet);
MXK_STATUS mxkPacketReqGetMainId(unsigned char* packet);
MXK_STATUS mxkPacketReqGetKeyId(unsigned char* packet);
MXK_STATUS mxkPacketReqGetPlayCounter(unsigned char* packet);
MXK_STATUS mxkPacketReqFlashRead(unsigned char* packet, unsigned int address, unsigned int nbytes);
MXK_STATUS mxkPacketReqNvramRead(unsigned char* packet, unsigned short addr, unsigned char blocks);

View File

@ -0,0 +1,253 @@
#include <Windows.h>
//
#include <SetupAPI.h>
#include "../am/amEeprom.h"
#include "../ami/ami.h"
#include "../mice/ioctl.h"
#include "mxkSmbus.h"
#pragma pack(push, 1)
typedef struct {
unsigned char status;
unsigned char command;
unsigned short addr;
unsigned short command_code;
unsigned char nbytes;
unsigned char data[32];
} i2c_packet;
typedef struct {
unsigned char status;
unsigned char command;
unsigned char addr;
unsigned char command_code;
unsigned char nbytes;
unsigned char data[32];
} smb_packet;
#pragma pack(pop)
HANDLE N2_MUTEX;
HANDLE MXSMBUS = INVALID_HANDLE_VALUE;
int mxkSmbusInit(void) {
static BOOL hasInit;
if (hasInit) return -4;
N2_MUTEX = CreateMutexA(NULL, 0, NULL);
if (N2_MUTEX == NULL) {
amiDebugLog("CreateMutex Error(%ld).", GetLastError());
return -5;
}
int error;
MXSMBUS = mxkSmbusCreateDeviceFile();
if (MXSMBUS == INVALID_HANDLE_VALUE) {
amiDebugLog("mxkSmbusCreateDeviceFile Error.");
error = -5;
} else {
DWORD nBytesReturned;
unsigned int version;
BOOL succ = DeviceIoControl(MXSMBUS, IOCTL_MXSRAM_GET_VERSION, NULL, 0, &version,
sizeof version, &nBytesReturned, NULL);
if (!succ || nBytesReturned != sizeof version) {
error = -5;
amiDebugLog("mxkSmbusGetDriverVerision Error.");
} else {
if ((version & 0xffff) == 1) {
hasInit = 1;
return 0;
}
amiDebugLog(
"Unknown SMBUS Driver Protocol(0x%08x). Please Update SMBUS "
"Driver or User Program.",
version);
error = -6;
}
}
if (MXSMBUS != INVALID_HANDLE_VALUE) {
CloseHandle(MXSMBUS);
MXSMBUS = INVALID_HANDLE_VALUE;
}
if (N2_MUTEX == NULL) return error;
CloseHandle(N2_MUTEX);
N2_MUTEX = NULL;
return error;
}
int mxkSmbusI2CWriteBlock(unsigned char addr, unsigned char command, unsigned char *buffer,
unsigned char nbytes) {
i2c_packet packet;
packet.addr = addr;
packet.command_code = (command << 8) | buffer[0];
packet.nbytes = (nbytes - 1) & 0xff;
packet.status = 0;
packet.command = 8;
memcpy(packet.data, buffer + 1, packet.nbytes);
for (int tries = 0; tries < 5; tries++) {
DWORD bytesReturned;
BOOL success = DeviceIoControl(MXSMBUS, IOCTL_MXSMBUS_I2C, &packet, sizeof packet, &packet,
sizeof packet, &bytesReturned, NULL);
if (!success || bytesReturned != sizeof packet) {
return -9;
}
if (packet.status == 0) return 0;
if (packet.status != 24) return -9;
Sleep(16);
}
return -9;
}
int mxkSmbusRequestMutex(void) {
if (WaitForSingleObject(N2_MUTEX, 256) != WAIT_OBJECT_0) return -7;
return 0;
}
int mxkSmbusReleaseMutex(void) {
if (!ReleaseMutex(N2_MUTEX)) {
amiDebugLog("ReleaseMutex Error(%d).", GetLastError());
return -5;
}
return 0;
}
HANDLE mxkSmbusCreateDeviceFile(void) {
SP_DEVICE_INTERFACE_DATA interfaceData;
SP_DEVICE_INTERFACE_DETAIL_DATA_A interfaceDetail[204];
HDEVINFO DeviceInfoSet =
SetupDiGetClassDevsA(&MXSMBUS_GUID, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
if (DeviceInfoSet == INVALID_HANDLE_VALUE) {
amiDebugLog("SetupDiGetClassDevs Error(%ld).", GetLastError());
return INVALID_HANDLE_VALUE;
}
interfaceData.cbSize = 28;
BOOL s;
s = SetupDiEnumDeviceInterfaces(DeviceInfoSet, NULL, &MXSMBUS_GUID, 0, &interfaceData);
if (!s) {
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
amiDebugLog("SetupDiEnumDeviceInterfaces Error(%ld).", GetLastError());
return INVALID_HANDLE_VALUE;
}
interfaceDetail[0].cbSize = 5;
s = SetupDiGetDeviceInterfaceDetailA(DeviceInfoSet, &interfaceData, interfaceDetail,
sizeof interfaceDetail, NULL, NULL);
if (!s) {
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
amiDebugLog("SetupDiGetDeviceInterfaceDetailA Error(%ld).", GetLastError());
return INVALID_HANDLE_VALUE;
}
char fileName[260];
strcpy_s(fileName, sizeof fileName, interfaceDetail[0].DevicePath);
HANDLE device =
CreateFileA(fileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_SUPPORTS_GHOSTING, NULL);
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
return device;
}
int mxkSmbusReadByte(unsigned char addr, unsigned char *readByte, unsigned char cmd_code) {
if (readByte == NULL) return -2;
if (MXSMBUS == INVALID_HANDLE_VALUE) return -5;
smb_packet buffer;
buffer.command_code = cmd_code;
buffer.status = 0;
buffer.command = 5;
buffer.nbytes = 0;
buffer.data[0] = 0;
buffer.data[1] = 0;
buffer.addr = addr;
DWORD bytesReturned;
BOOL success = DeviceIoControl(MXSMBUS, IOCTL_MXSMBUS_REQUEST, &buffer, sizeof buffer, &buffer,
sizeof buffer, &bytesReturned, NULL);
if (success && buffer.status == 0 && bytesReturned == sizeof buffer) {
*readByte = buffer.data[0];
return 0;
}
return -8;
}
int mxkSmbusWriteByte(unsigned char v_addr, unsigned char command_code, unsigned char data) {
if (MXSMBUS == INVALID_HANDLE_VALUE) return -5;
smb_packet packet;
packet.command_code = command_code;
packet.data[0] = data;
packet.status = 0;
packet.command = 4;
packet.nbytes = 0;
packet.data[1] = 0xff;
packet.addr = v_addr;
DWORD bytesReturned;
BOOL success = DeviceIoControl(MXSMBUS, IOCTL_MXSMBUS_REQUEST, &packet, sizeof packet, &packet,
sizeof packet, &bytesReturned, NULL);
if (!success || bytesReturned != sizeof packet) {
amiDebugLog("DIO failed %03x\n", GetLastError());
return -9;
}
if (packet.status != 0) {
amiDebugLog("Packet status: %d\n", packet.status);
return -9;
}
return 0;
}
int mxkSmbusI2CWriteCommand(unsigned char command_code, unsigned char *buffer, size_t nbytes) {
if (buffer == NULL || nbytes - 1 > 31) return -2;
i2c_packet packet;
packet.addr = KC_DS_ADDRESS;
packet.nbytes = nbytes & 0xff;
packet.command_code = command_code | 0xa900;
packet.status = 0;
packet.command = 8;
memcpy(packet.data, buffer, nbytes & 0xff);
int tries = 0;
do {
DWORD nBytesReturned;
BOOL succ = DeviceIoControl(MXSMBUS, IOCTL_MXSMBUS_I2C, &packet, sizeof packet, &packet,
sizeof packet, &nBytesReturned, NULL);
if (!succ || nBytesReturned != sizeof packet) {
amiDebugLog("Failed!! %d", GetLastError());
return -9;
}
if (packet.status == 0) break;
if (packet.status != 0x18) return -9;
tries += 1;
Sleep(0x10);
} while (tries < 5);
return tries == 5 ? -9 : 0;
}
bool mxkSmbusI2CReadBlock(unsigned char smbAddress, unsigned char block, unsigned char *buffer,
unsigned char nbytes) {
DWORD nBytesReturned;
smb_packet packet;
packet.status = 0;
packet.command = 11;
packet.addr = smbAddress;
packet.command_code = block;
packet.nbytes = nbytes;
for (int tries = 0; tries < 5; tries++) {
BOOL succ = DeviceIoControl(MXSMBUS, IOCTL_MXSMBUS_REQUEST, &packet, sizeof packet, &packet,
sizeof packet, &nBytesReturned, NULL);
if (!succ || nBytesReturned != sizeof packet) return false;
if (packet.status == 0) {
memcpy(buffer, packet.data, nbytes);
return true;
}
if (packet.status != 24) return false;
Sleep(16);
}
return false;
}

View File

@ -0,0 +1,23 @@
#include <stdbool.h>
#include <stdint.h>
#include "../../dll/devices/smb_ds2460.h"
#include "../../dll/devices/smb_ds28cn01.h"
#define SYS_DS_ADDRESS DS2460_ADDRESS // 54
#define KC_DS_ADDRESS DS28CN01_ADDRESS // 55
int mxkSmbusI2CWriteCommand(unsigned char command_code, unsigned char *buffer, size_t nbytes);
int mxkSmbusI2CWriteBlock(unsigned char addr, unsigned char command, unsigned char *buffer,
unsigned char nbytes);
bool mxkSmbusI2CReadBlock(unsigned char smbAddress, unsigned char block, unsigned char *buffer,
unsigned char nbytes);
int mxkSmbusWriteByte(unsigned char v_addr, unsigned char command_code, unsigned char data);
int mxkSmbusReadByte(unsigned char addr, unsigned char *readByte, unsigned char cmd_code);
HANDLE mxkSmbusCreateDeviceFile(void);
int mxkSmbusInit(void);
int mxkSmbusRequestMutex(void);
int mxkSmbusReleaseMutex(void);

View File

@ -1,186 +1,374 @@
#include "mxkTransport.h"
#include "../mice/ioctl.h"
#include "mxk.h"
#include "mxkCrypt.h"
// TODO: Don't use puts!
#include <stdio.h>
static BOOL mxkTransportWaitStrobeReady(void);
static BOOL mxkTransportWaitStrobeRelease(void);
static BOOL mxkTransportCtrlPortInAndOut(BYTE flag);
static BOOL mxkTransportCtrlPortInOrOut(BYTE flag);
static BOOL mxkTransportInitPic(void);
static struct {
BOOL m_bParallelInit;
HANDLE m_hParallel;
} mxkTransport;
BOOL DO_SLEEP_0 = TRUE;
#define ReadStatus(mxparallel, status, nret) \
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_READ_STATUS, NULL, 0, &status, 1, &nret, NULL);
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_READ_STATUS, NULL, 0, &status, 1, &nret, NULL)
BOOL mxkTransportWaitStrobeReady(HANDLE mxparallel) {
static MXK_TRANSPORT_STATUS mxkTransportWaitStrobeReady(void) {
BYTE status;
DWORD nbytes = 0;
ReadStatus(mxparallel, status, nbytes);
status &= 0x80;
if (!ReadStatus(mxkTransport.m_hParallel, status, nbytes)) {
amiDebugLog("Error mxkTransportWaitStrobeReady 1");
return MXK_TRANSPORT_STATUS_NG;
}
status &= PARALLEL_STATUS_BUSY;
if (status != 0) {
ReadStatus(mxparallel, status, nbytes);
if ((status & 0x80) != 0) return FALSE;
if (!ReadStatus(mxkTransport.m_hParallel, status, nbytes)) {
amiDebugLog("Error mxkTransportWaitStrobeReady 2");
return MXK_TRANSPORT_STATUS_NG;
}
if ((status & PARALLEL_STATUS_BUSY) != 0) return MXK_TRANSPORT_STATUS_OK;
}
return TRUE;
return MXK_TRANSPORT_STATUS_BUSY;
}
BOOL mxkTransportWaitStrobeRelease(HANDLE mxparallel) {
static MXK_TRANSPORT_STATUS mxkTransportWaitStrobeRelease(void) {
BYTE status;
DWORD nbytes = 0;
ReadStatus(mxparallel, status, nbytes);
status &= 0x80;
if (!ReadStatus(mxkTransport.m_hParallel, status, nbytes)) {
amiDebugLog("Error mxkTransportWaitStrobeRelease 1");
return MXK_TRANSPORT_STATUS_NG;
}
status &= PARALLEL_STATUS_BUSY;
if (status == 0) {
ReadStatus(mxparallel, status, nbytes);
if ((status & 0x80) == 0) return FALSE;
if (!ReadStatus(mxkTransport.m_hParallel, status, nbytes)) {
amiDebugLog("Error mxkTransportWaitStrobeRelease 2");
return MXK_TRANSPORT_STATUS_NG;
}
if ((status & PARALLEL_STATUS_BUSY) == 0) return MXK_TRANSPORT_STATUS_OK;
}
return MXK_TRANSPORT_STATUS_BUSY;
}
static BOOL mxkTransportCtrlPortInAndOut(BYTE flag) {
BYTE ctrl;
DWORD nbytes = 0;
if (!DeviceIoControl(mxkTransport.m_hParallel, IOCTL_MXPARALLEL_READ_CTRL_PORT, NULL, 0, &ctrl,
1, &nbytes, NULL)) {
amiDebugLog("Error mxkTransportCtrlPortInAndOut 1");
return FALSE;
}
ctrl &= flag;
if (!DeviceIoControl(mxkTransport.m_hParallel, IOCTL_MXPARALLEL_WRITE_CTRL_PORT, &ctrl, 1, NULL,
0, &nbytes, NULL)) {
amiDebugLog("Error mxkTransportCtrlPortInAndOut 2");
return FALSE;
}
return TRUE;
}
void mxkTransportCtrlPortInAndOut(HANDLE mxparallel, BYTE flag) {
static BOOL mxkTransportCtrlPortInOrOut(BYTE flag) {
BYTE ctrl;
DWORD nbytes = 0;
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_READ_CTRL_PORT, NULL, 0, &ctrl, 1, &nbytes, NULL);
ctrl &= flag;
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_WRITE_CTRL_PORT, &ctrl, 1, NULL, 0, &nbytes, NULL);
}
void mxkTransportCtrlPortInOrOut(HANDLE mxparallel, BYTE flag) {
BYTE ctrl;
DWORD nbytes = 0;
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_READ_CTRL_PORT, NULL, 0, &ctrl, 1, &nbytes, NULL);
if (!DeviceIoControl(mxkTransport.m_hParallel, IOCTL_MXPARALLEL_READ_CTRL_PORT, NULL, 0, &ctrl,
1, &nbytes, NULL)) {
amiDebugLog("Error mxkTransportCtrlPortInOrOut 1");
return FALSE;
}
ctrl |= flag;
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_WRITE_CTRL_PORT, &ctrl, 1, NULL, 0, &nbytes, NULL);
if (!DeviceIoControl(mxkTransport.m_hParallel, IOCTL_MXPARALLEL_WRITE_CTRL_PORT, &ctrl, 1, NULL,
0, &nbytes, NULL)) {
amiDebugLog("Error mxkTransportCtrlPortInOrOut 2");
return FALSE;
}
return TRUE;
}
BOOL mxkTransportSend(HANDLE mxparallel, unsigned char *data, DWORD nbytes) {
MXK_TRANSPORT_STATUS mxkTransportSend(unsigned char *data, DWORD nbytes) {
DWORD nret;
BYTE status;
MXK_TRANSPORT_STATUS err;
amtime_t start;
amtime_t now;
if (!mxkTransport.m_bParallelInit) return MXK_TRANSPORT_STATUS_NO_INIT;
if (nbytes == 0) return MXK_TRANSPORT_STATUS_OK;
for (size_t i = 0; i < nbytes; i++) {
amiTimerGet(&start);
do {
ReadStatus(mxparallel, status, nret);
status &= 0x40;
if (!ReadStatus(mxkTransport.m_hParallel, status, nret)) {
amiDebugLog("Error mxkTransportSend 1");
return MXK_TRANSPORT_STATUS_SEND_NG;
}
status &= PARALLEL_STATUS_ACK;
if (status == 0) break;
amiTimerGet(&now);
if (DO_SLEEP_0) Sleep(0);
} while (amiTimerDiffUsec(&start, &now) < 1000000);
if (status != 0) {
puts("SEND busy error");
return FALSE;
amiDebugLog("SEND busy error");
return MXK_TRANSPORT_STATUS_SEND_NG;
}
while (mxkTransportWaitStrobeRelease(mxparallel)) {
while (1) {
err = mxkTransportWaitStrobeRelease();
if (err == MXK_TRANSPORT_STATUS_OK) break;
if (err == MXK_TRANSPORT_STATUS_NG) {
amiDebugLog("Error mxkTransportSend 2");
return MXK_TRANSPORT_STATUS_SEND_NG;
}
amiTimerGet(&now);
if (DO_SLEEP_0) Sleep(0);
if (amiTimerDiffUsec(&start, &now) > 999999) {
puts("SEND busy error");
return FALSE;
amiDebugLog("state_busy != 0 // timeout?");
return MXK_TRANSPORT_STATUS_SEND_NG;
}
}
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_WRITE_DATA, &data[i], 1, NULL, 0, &nret, NULL);
if (!DeviceIoControl(mxkTransport.m_hParallel, IOCTL_MXPARALLEL_WRITE_DATA, &data[i], 1,
NULL, 0, &nret, NULL)) {
amiDebugLog("Error mxkTransportSend 3");
return MXK_TRANSPORT_STATUS_SEND_NG;
}
mxkTransportCtrlPortInAndOut(mxparallel, 0xdf);
mxkTransportCtrlPortInOrOut(mxparallel, 0x01);
if (!mxkTransportCtrlPortInAndOut(~PARALLEL_CONTROL_BIDI & 0xff)) {
amiDebugLog("Error mxkTransportSend 4");
return MXK_TRANSPORT_STATUS_SEND_NG;
}
if (!mxkTransportCtrlPortInOrOut(PARALLEL_CONTROL_STROBE)) {
amiDebugLog("Error mxkTransportSend 5");
return MXK_TRANSPORT_STATUS_SEND_NG;
}
while (mxkTransportWaitStrobeReady(mxparallel)) {
while (1) {
err = mxkTransportWaitStrobeReady();
if (err == MXK_TRANSPORT_STATUS_OK) break;
if (err == MXK_TRANSPORT_STATUS_NG) {
amiDebugLog("Error mxkTransportSend 6");
return MXK_TRANSPORT_STATUS_SEND_NG;
}
amiTimerGet(&now);
if (DO_SLEEP_0) Sleep(0);
if (amiTimerDiffUsec(&start, &now) > 999999'000) {
puts("SEND end error");
return FALSE;
amiDebugLog("RA1が1でエラー");
return MXK_TRANSPORT_STATUS_SEND_NG;
}
}
mxkTransportCtrlPortInOrOut(mxparallel, 0x20);
mxkTransportCtrlPortInAndOut(mxparallel, 0xfe);
if (!mxkTransportCtrlPortInOrOut(PARALLEL_CONTROL_BIDI)) {
amiDebugLog("Error mxkTransportSend 7");
return MXK_TRANSPORT_STATUS_SEND_NG;
}
if (!mxkTransportCtrlPortInAndOut(~PARALLEL_CONTROL_STROBE & 0xff)) {
amiDebugLog("Error mxkTransportSend 8");
return MXK_TRANSPORT_STATUS_SEND_NG;
}
}
return TRUE;
return MXK_TRANSPORT_STATUS_OK;
}
HRESULT mxkTransportRecv(HANDLE mxparallel, unsigned char *data, DWORD nbytes) {
MXK_TRANSPORT_STATUS mxkTransportRecv(unsigned char *data, DWORD nbytes) {
BYTE status;
DWORD nret;
MXK_TRANSPORT_STATUS err;
amtime_t now;
amtime_t start;
if (!mxkTransport.m_bParallelInit) return MXK_TRANSPORT_STATUS_NO_INIT;
if (nbytes == 0) return MXK_TRANSPORT_STATUS_OK;
for (size_t i = 0; i < nbytes; i++) {
amiTimerGet(&start);
do {
ReadStatus(mxparallel, status, nret);
status &= 0x40;
if (!ReadStatus(mxkTransport.m_hParallel, status, nret)) {
amiDebugLog("Error mxkTransportRecv 1");
return MXK_TRANSPORT_STATUS_RECV_NG;
}
status &= PARALLEL_STATUS_ACK;
if (status != 0) break;
amiTimerGet(&now);
if (DO_SLEEP_0 != 0) Sleep(0);
} while (amiTimerDiffUsec(&start, &now) < 1000000'000);
} while (amiTimerDiffUsec(&start, &now) < 1000000);
if (status == 0) {
puts("RECV busy error 1");
return FALSE;
amiDebugLog("RECV busy error 1");
return MXK_TRANSPORT_STATUS_RECV_NG;
}
while (mxkTransportWaitStrobeReady(mxparallel)) {
while (1) {
err = mxkTransportWaitStrobeReady();
if (err == MXK_TRANSPORT_STATUS_OK) break;
if (err == MXK_TRANSPORT_STATUS_NG) {
amiDebugLog("Error mxkTransportRecv 2");
return MXK_TRANSPORT_STATUS_RECV_NG;
}
amiTimerGet(&now);
if (DO_SLEEP_0 != 0) Sleep(0);
if (amiTimerDiffUsec(&start, &now) > 999999'000) {
puts("RECV busy error 2");
return FALSE;
if (amiTimerDiffUsec(&start, &now) > 999999) {
amiDebugLog("RECV busy error 2");
return MXK_TRANSPORT_STATUS_RECV_NG;
}
}
mxkTransportCtrlPortInOrOut(mxparallel, 0x20);
mxkTransportCtrlPortInOrOut(mxparallel, 0x01);
if (!mxkTransportCtrlPortInOrOut(PARALLEL_CONTROL_BIDI)) {
amiDebugLog("Error mxkTransportRecv 3");
return MXK_TRANSPORT_STATUS_RECV_NG;
}
if (!mxkTransportCtrlPortInOrOut(PARALLEL_CONTROL_STROBE)) {
amiDebugLog("Error mxkTransportRecv 4");
return MXK_TRANSPORT_STATUS_RECV_NG;
}
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_READ_DATA, NULL, 0, &data[i], 1, &nret, NULL);
if (!DeviceIoControl(mxkTransport.m_hParallel, IOCTL_MXPARALLEL_READ_DATA, NULL, 0,
&data[i], 1, &nret, NULL)) {
amiDebugLog("Error mxkTransportRecv 5");
return MXK_TRANSPORT_STATUS_RECV_NG;
}
while (1) {
err = mxkTransportWaitStrobeRelease();
if (err == MXK_TRANSPORT_STATUS_OK) break;
if (err == MXK_TRANSPORT_STATUS_NG) {
amiDebugLog("Error mxkTransportRecv 6");
return MXK_TRANSPORT_STATUS_RECV_NG;
}
while (mxkTransportWaitStrobeRelease(mxparallel)) {
amiTimerGet(&now);
if (DO_SLEEP_0) Sleep(0);
if (amiTimerDiffUsec(&start, &now) > 999999) {
puts("RECV end error");
return FALSE;
amiDebugLog("RECV end error");
return MXK_TRANSPORT_STATUS_RECV_NG;
}
}
mxkTransportCtrlPortInAndOut(mxparallel, 0xfe);
if (!mxkTransportCtrlPortInAndOut(~PARALLEL_CONTROL_STROBE & 0xff)) {
amiDebugLog("Error mxkTransportRecv 7");
return MXK_TRANSPORT_STATUS_RECV_NG;
}
}
return TRUE;
return MXK_TRANSPORT_STATUS_OK;
}
BOOL mxkSendPacket(HANDLE mxparallel, const unsigned char *packet) {
unsigned char encrypted[16];
ZeroMemory(encrypted, 16);
mxkCryptEncryptData(encrypted, packet);
return mxkTransportSend(mxparallel, encrypted, 0x10);
}
BOOL mxkRecvPacket(HANDLE mxparallel, unsigned char *packet) {
unsigned char encrypted[16];
if (!mxkTransportRecv(mxparallel, encrypted, 0x10)) return FALSE;
mxkCryptDecryptData(encrypted, packet);
return TRUE;
}
void mxkTransportInitPic(HANDLE mxparallel) {
static BOOL mxkTransportInitPic(void) {
BYTE flags = 0;
DWORD nbytes = 0;
Sleep(10);
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_READ_FLAGS, NULL, 0, &flags, 1, &nbytes, NULL);
flags = flags & 0x1f | 0x20;
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_WRITE_FLAGS, &flags, 1, NULL, 0, &nbytes, NULL);
if (!DeviceIoControl(mxkTransport.m_hParallel, IOCTL_MXPARALLEL_READ_FLAGS, NULL, 0, &flags, 1,
&nbytes, NULL)) {
amiDebugLog("Error KeychipInit 1");
return FALSE;
}
flags = (flags & 0b11111) | (PARALLEL_EC_MODE_BYTE << 5);
if (!DeviceIoControl(mxkTransport.m_hParallel, IOCTL_MXPARALLEL_WRITE_FLAGS, &flags, 1, NULL, 0,
&nbytes, NULL)) {
amiDebugLog("Error KeychipInit 2");
return FALSE;
}
Sleep(10);
flags = 0x24;
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_WRITE_CTRL_PORT, &flags, 1, NULL, 0, &nbytes,
NULL);
flags = PARALLEL_CONTROL_BIDI | PARALLEL_CONTROL_INITIALISE;
if (!DeviceIoControl(mxkTransport.m_hParallel, IOCTL_MXPARALLEL_WRITE_CTRL_PORT, &flags, 1,
NULL, 0, &nbytes, NULL)) {
amiDebugLog("Error KeychipInit 3");
return FALSE;
}
Sleep(10);
mxkTransportCtrlPortInAndOut(mxparallel, 0xfb);
if (!mxkTransportCtrlPortInAndOut(~PARALLEL_CONTROL_INITIALISE & 0xff)) {
amiDebugLog("Error KeychipInit 4");
return FALSE;
}
Sleep(10);
mxkTransportCtrlPortInOrOut(mxparallel, 0x24);
if (!mxkTransportCtrlPortInOrOut(PARALLEL_CONTROL_BIDI | PARALLEL_CONTROL_INITIALISE)) {
amiDebugLog("Error KeychipInit 5");
return FALSE;
}
Sleep(10);
return TRUE;
}
MXK_TRANSPORT_STATUS mxkTransportInit(void) {
amtime_t start;
amtime_t now;
if (mxkTransport.m_bParallelInit) return 0;
amiTimerGet(&start);
do {
mxkTransport.m_hParallel =
CreateFileA("\\\\.\\mxparallel", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (mxkTransport.m_hParallel != INVALID_HANDLE_VALUE) break;
amiTimerGet(&now);
Sleep(500);
} while (amiTimerDiffSec(&start, &now) < 10);
if (mxkTransport.m_hParallel == INVALID_HANDLE_VALUE) {
amiDebugLog("Error Timeout CreateFile MxParallel");
return MXK_TRANSPORT_STATUS_NG;
}
if (!mxkTransportInitPic()) {
amiDebugLog("Error InitPic()");
return MXK_TRANSPORT_STATUS_NG;
}
DO_SLEEP_0 = 1;
mxkTransport.m_bParallelInit = 1;
return MXK_TRANSPORT_STATUS_OK;
}
MXK_STATUS mxkSendPacket(const unsigned char *packet) {
unsigned char encrypted[MXK_BLOCK_SIZE];
if (packet == NULL) {
amiDebugLog("Error invalid param!!!");
return MXK_STATUS_INVALID_PARAM;
}
ZeroMemory(encrypted, sizeof encrypted);
mxkCryptEncryptData(encrypted, packet);
if (0) { // TODO: if (mxkCryptEncryptData() != 0)
int err = 0;
amiDebugLog("Error mxkCryptEncryptData(), %d", err);
return MXK_STATUS_CRYPT_NG;
}
MXK_TRANSPORT_STATUS status = mxkTransportSend(encrypted, MXK_BLOCK_SIZE);
if (status != MXK_TRANSPORT_STATUS_OK) return MXK_STATUS_SEND_NG;
return MXK_STATUS_OK;
}
MXK_STATUS mxkRecvPacket(unsigned char *packet) {
unsigned char encrypted[MXK_BLOCK_SIZE];
if (packet == NULL) {
amiDebugLog("Error invalid param!!!");
return MXK_STATUS_INVALID_PARAM;
}
MXK_TRANSPORT_STATUS status = mxkTransportRecv(encrypted, MXK_BLOCK_SIZE);
if (status != MXK_TRANSPORT_STATUS_OK) {
amiDebugLog("Error mxkTransportRecv(), %d", status);
return MXK_STATUS_RECV_NG;
}
ZeroMemory(packet, MXK_BLOCK_SIZE);
mxkCryptDecryptData(encrypted, packet);
if (0) { // TODO: if (mxkCryptDecryptData() != 0)
int err = 0;
amiDebugLog("Error mxkCryptDecryptData(), %d", err);
return MXK_STATUS_CRYPT_NG;
}
return MXK_STATUS_OK;
}

View File

@ -0,0 +1,12 @@
#pragma once
#include <Windows.h>
#include "../ami/ami.h"
#include "mxkDefs.h"
MXK_TRANSPORT_STATUS mxkTransportSend(unsigned char* data, DWORD nbytes);
MXK_TRANSPORT_STATUS mxkTransportRecv(unsigned char* data, DWORD nbytes);
MXK_TRANSPORT_STATUS mxkTransportInit(void);
MXK_STATUS mxkSendPacket(const unsigned char* packet);
MXK_STATUS mxkRecvPacket(unsigned char* packet);

View File

@ -1,5 +1,6 @@
subdir('lib')
subdir('system_dummy')
subdir('micepatch')
subdir('micekeychip')
subdir('micemaster')

View File

@ -36,13 +36,12 @@ void log_callback(struct pcpa* stream, void* data) {
e_pcpa_t mxkPcpStreamInit() {
e_pcpa_t err;
PCP.before_cb = log_callback;
err = pcpaInitStream(&PCP);
if (err != e_pcpa_ok) {
printf("pcpaInitStream Error. Code:%d\n", err);
return err;
}
PCP.before_cb = log_callback;
err = pcpaSetCallbackFuncBuffer(
&PCP, CALLBACK_FUNCTION_BUFFER,

View File

@ -4,6 +4,8 @@ pcpa_callback mxkBinaryCallback;
extern byte BINARY_DATA[4096];
extern size_t BINARY_DATA_LEN;
#define MXM_NUM_CALLBACKS 11
#define MXMASTER "mxmaster."
#define FOREGROUND MXMASTER##"foreground."

View File

@ -43,7 +43,7 @@ typedef struct MX_MASTER_ {
bool m_kcReady;
bool m_pcpaHasInit;
appLauncher_t* m_appLauncher;
pcpa_cb_table_t m_pcpCallbacks[11];
pcpa_cb_table_t m_pcpCallbacks[MXM_NUM_CALLBACKS];
pcpa_t m_pcp;
} MX_MASTER;

View File

@ -0,0 +1,6 @@
# What?
These are bare-minimum implementations of the Madoka system services for
the purpose of getting games booted with minimal effort. They are
**not** usable substitutes for these services on a real system. See the
`mice*` versions for those.

View File

@ -0,0 +1,88 @@
#include "dummyinstaller.h"
#include "../../lib/ami/amiLog.h"
#include "../../lib/libpcp/libpcp.h"
typedef struct {
pcpa_t m_pcp;
pcpa_cb_table_t m_pcpCallbacks[1];
} mdi_t;
void mdiPcpRequest(pcpa_t* stream, void* mdi) {
char* request = pcpaGetCommand(stream, "request");
pcpaSetSendPacket(stream, "response", request);
if (strcmp(request, "check_appdata") == 0) {
pcpaAddSendPacket(stream, "result", "success");
} else if (strcmp(request, "query_appdata_status") == 0) {
pcpaAddSendPacket(stream, "result", "success");
pcpaAddSendPacket(stream, "status", "available");
pcpaAddSendPacket(stream, "id", "----");
} else {
pcpaAddSendPacket(stream, "result", "invalid_request");
// TODO: Remove this once enough has been implemented for most games?
pcpaPrint(stream);
}
}
void mdiBeforeCb(pcpa_t* stream, void* data) { }
e_pcpa_t mdiPcpStreamInit(mdi_t* mdi, unsigned short textPort, unsigned short binaryPort,
bool global) {
e_pcpa_t err;
err = pcpaInitStream(&mdi->m_pcp);
if (err != e_pcpa_ok) {
amiDebugLog("pcpaInitStream Error. Code:%d", err);
return err;
}
// mdi->m_pcp.before_cb = mdiBeforeCb;
err = pcpaSetCallbackFuncBuffer(&mdi->m_pcp, mdi->m_pcpCallbacks, 1);
if (err != e_pcpa_ok) {
amiDebugLog("pcpaSetCallBackFuncBuffer Error. Code:%d", err);
return err;
}
pcpaSetCallbackFunc(&mdi->m_pcp, "request", mdiPcpRequest, mdi);
err = pcpaOpenServerWithBinary(&mdi->m_pcp, global ? OPEN_MODE_GLOBAL : OPEN_MODE_LOCAL,
textPort, binaryPort, 300000);
if (err != e_pcpa_ok && err != e_pcpa_to) {
amiDebugLog("pcpaOpenServerWithBinary Error. Code %d", err);
return e_pcpa_not_open;
}
if (global)
amiDebugLog("Listening on 0.0.0.0:%d (:%d)", textPort, binaryPort);
else
amiDebugLog("Listening on 127.0.0.1:%d (:%d)", textPort, binaryPort);
return e_pcpa_ok;
}
void miceDummyInstaller(unsigned short textPort, unsigned short binaryPort, bool global) {
mdi_t* mdi = malloc(sizeof *mdi);
e_pcpa_t err;
WSADATA wsaData;
if (WSAStartup(2, &wsaData)) {
amiDebugLog("WSAStartup Error. Code %d", GetLastError());
return;
}
err = mdiPcpStreamInit(mdi, textPort, binaryPort, global);
if (err != e_pcpa_ok) {
amiDebugLog("mdiPcpStreamInit Error. Code %d", err);
return;
}
while (1) {
err = pcpaServer(&mdi->m_pcp, 16);
if (err == e_pcpa_to || err == e_pcpa_closed) err = e_pcpa_ok;
if (err != e_pcpa_ok) {
amiDebugLog("Error pcpaServer. Code %d", err);
pcpaClose(&mdi->m_pcp);
return;
}
}
}

View File

@ -0,0 +1,3 @@
#include <stdbool.h>
void miceDummyInstaller(unsigned short textPort, unsigned short binaryPort, bool global);

View File

@ -0,0 +1,3 @@
#include "dummyinstaller.h"
int main() { miceDummyInstaller(40102, 40103, false); }

View File

@ -0,0 +1,18 @@
dependencies = []
link_with = [libpcp, amiDebug]
sources = [
'dummyinstaller.c',
]
dummyinstaller = static_library(
'dummyinstaller',
sources: sources,
link_with: link_with,
)
executable(
'dummyinstaller',
win_subsystem: subsystem,
sources: ['main.c'] + sources,
link_with: link_with,
dependencies: dependencies,
)

View File

@ -0,0 +1,38 @@
#include "../../lib/libpcp/libpcp.h"
pcpa_callback mxkBinaryCallback;
extern byte BINARY_DATA[4096];
extern size_t BINARY_DATA_LEN;
#define MDM_NUM_CALLBACKS 11
#define MXMASTER "mxmaster."
#define FOREGROUND MXMASTER##"foreground."
// Misc
#define MXM_RECONNECT_USB MXMASTER##"reconnect.usb.device"
#define MXM_DEVELOP MXMASTER##"develop"
pcpa_callback mdmPcpReconnectUsbDevice;
pcpa_callback mdmPcpCheckDevelopMode;
// Logs
#define MXM_LOG_AVAILALBE MXMASTER##"logging_available"
#define MXM_OUTPUT_LOG MXMASTER##"output_log"
#define MXM_ERASE_LOG MXMASTER##"erase_log"
pcpa_callback mdmPcpLogAvailable;
pcpa_callback mdmPcpOutputLog;
pcpa_callback mdmPcpEraseLog;
// Foreground control
#define MXM_FG_CURRENT FOREGROUND##"current"
#define MXM_FG_NEXT FOREGROUND##"next"
#define MXM_FG_ACTIVE FOREGROUND##"active"
#define MXM_FG_FAULT FOREGROUND##"fault"
#define MXM_FG_GETCOUNT FOREGROUND##"getcount"
#define MXM_FG_SETCOUNT FOREGROUND##"setcount"
pcpa_callback mdmPcpCurrentFgprocess;
pcpa_callback mdmPcpNextFgprocess;
pcpa_callback mdmPcpActiveFgprocess;
pcpa_callback mdmPcpFaultFgprocess;
pcpa_callback mdmPcpGetStartCount;
pcpa_callback mdmPcpSetStartCount;

View File

@ -0,0 +1,123 @@
#include "dummymaster.h"
#include "../../lib/ami/amiLog.h"
#include "../../lib/libpcp/libpcp.h"
#include "callbacks.h"
typedef struct {
pcpa_t m_pcp;
pcpa_cb_table_t m_pcpCallbacks[MDM_NUM_CALLBACKS];
} mdm_t;
void mdmPcpReconnectUsbDevice(pcpa_t* stream, void* mdm) {
pcpaSetSendPacket(stream, MXM_RECONNECT_USB, "0");
}
void mdmPcpCheckDevelopMode(pcpa_t* stream, void* mdm) {
// TODO: Do we want to support the develop flag in dummymaster?
pcpaSetSendPacket(stream, MXM_DEVELOP, "0");
}
void mdmPcpLogAvailable(pcpa_t* stream, void* mdm) {
pcpaSetSendPacket(stream, MXM_LOG_AVAILALBE, "0");
}
void mdmPcpOutputLog(pcpa_t* stream, void* mdm) {
pcpaSetSendPacket(stream, MXM_OUTPUT_LOG, "0");
pcpaAddSendPacket(stream, "path", "");
}
void mdmPcpEraseLog(pcpa_t* stream, void* mdm) { pcpaSetSendPacket(stream, MXM_ERASE_LOG, "0"); }
void mdmPcpCurrentFgprocess(pcpa_t* stream, void* mdm) {
// TODO: Handle set
pcpaSetSendPacket(stream, MXM_FG_CURRENT, "0"); // mxMaster->m_current
}
void mdmPcpNextFgprocess(pcpa_t* stream, void* mdm) {
// TODO: Handle set, Handle receive if "size" present
pcpaSetSendPacket(stream, MXM_FG_NEXT, "0"); // mxMaster->m_current
// mxMaster->m_next
}
void mdmPcpActiveFgprocess(pcpa_t* stream, void* mdm) {
pcpaSetSendPacket(stream, MXM_FG_ACTIVE, "0");
}
void mdmPcpFaultFgprocess(pcpa_t* stream, void* mdm) {}
void mdmPcpGetStartCount(pcpa_t* stream, void* mdm) {
pcpaSetSendPacket(stream, MXM_FG_GETCOUNT, "1");
}
void mdmPcpSetStartCount(pcpa_t* stream, void* mdm) {
pcpaSetSendPacket(stream, MXM_FG_SETCOUNT, "0");
}
void mdmBeforeCb(pcpa_t* stream, void* data) {
amiDebugLog("in:%s", (char*)data);
}
e_pcpa_t mdmPcpStreamInit(mdm_t* mdm, unsigned short textPort, unsigned short binaryPort,
bool global) {
e_pcpa_t err;
err = pcpaInitStream(&mdm->m_pcp);
if (err != e_pcpa_ok) {
amiDebugLog("pcpaInitStream Error. Code:%d", err);
return err;
}
// mdm->m_pcp.before_cb = mdmBeforeCb;
err = pcpaSetCallbackFuncBuffer(&mdm->m_pcp, mdm->m_pcpCallbacks, MDM_NUM_CALLBACKS);
if (err != e_pcpa_ok) {
amiDebugLog("pcpaSetCallBackFuncBuffer Error. Code:%d", err);
return err;
}
// Misc
pcpaSetCallbackFunc(&mdm->m_pcp, MXM_RECONNECT_USB, mdmPcpReconnectUsbDevice, mdm);
pcpaSetCallbackFunc(&mdm->m_pcp, MXM_DEVELOP, mdmPcpCheckDevelopMode, mdm);
// Logs
pcpaSetCallbackFunc(&mdm->m_pcp, MXM_LOG_AVAILALBE, mdmPcpLogAvailable, mdm);
pcpaSetCallbackFunc(&mdm->m_pcp, MXM_OUTPUT_LOG, mdmPcpOutputLog, mdm);
pcpaSetCallbackFunc(&mdm->m_pcp, MXM_ERASE_LOG, mdmPcpEraseLog, mdm);
// Foreground control
pcpaSetCallbackFunc(&mdm->m_pcp, MXM_FG_CURRENT, mdmPcpCurrentFgprocess, mdm);
pcpaSetCallbackFunc(&mdm->m_pcp, MXM_FG_NEXT, mdmPcpNextFgprocess, mdm);
pcpaSetCallbackFunc(&mdm->m_pcp, MXM_FG_ACTIVE, mdmPcpActiveFgprocess, mdm);
pcpaSetCallbackFunc(&mdm->m_pcp, MXM_FG_FAULT, mdmPcpFaultFgprocess, mdm);
pcpaSetCallbackFunc(&mdm->m_pcp, MXM_FG_GETCOUNT, mdmPcpGetStartCount, mdm);
pcpaSetCallbackFunc(&mdm->m_pcp, MXM_FG_SETCOUNT, mdmPcpSetStartCount, mdm);
err = pcpaOpenServerWithBinary(&mdm->m_pcp, global ? OPEN_MODE_GLOBAL : OPEN_MODE_LOCAL,
textPort, binaryPort, 300000);
if (err != e_pcpa_ok && err != e_pcpa_to) {
amiDebugLog("pcpaOpenServerWithBinary Error. Code %d", err);
return e_pcpa_not_open;
}
if (global)
amiDebugLog("Listening on 0.0.0.0:%d (:%d)", textPort, binaryPort);
else
amiDebugLog("Listening on 127.0.0.1:%d (:%d)", textPort, binaryPort);
return e_pcpa_ok;
}
void miceDummyMaster(unsigned short textPort, unsigned short binaryPort, bool global) {
mdm_t* mdm = malloc(sizeof *mdm);
e_pcpa_t err;
WSADATA wsaData;
if (WSAStartup(2, &wsaData)) {
amiDebugLog("WSAStartup Error. Code %d", GetLastError());
return;
}
err = mdmPcpStreamInit(mdm, textPort, binaryPort, global);
if (err != e_pcpa_ok) {
amiDebugLog("mdmPcpStreamInit Error. Code %d", err);
return;
}
while (1) {
err = pcpaServer(&mdm->m_pcp, 16);
if (err == e_pcpa_to || err == e_pcpa_closed) err = e_pcpa_ok;
if (err != e_pcpa_ok) {
amiDebugLog("Error pcpaServer. Code %d", err);
pcpaClose(&mdm->m_pcp);
return;
}
}
}

View File

@ -0,0 +1,3 @@
#include <stdbool.h>
void miceDummyMaster(unsigned short textPort, unsigned short binaryPort, bool global);

View File

@ -0,0 +1,3 @@
#include "dummymaster.h"
int main() { miceDummyMaster(40100, 40101, false); }

View File

@ -0,0 +1,18 @@
dependencies = []
link_with = [libpcp, amiDebug]
sources = [
'dummymaster.c',
]
dummymaster = static_library(
'dummymaster',
sources: sources,
link_with: link_with,
)
executable(
'dummymaster',
win_subsystem: subsystem,
sources: ['main.c'] + sources,
link_with: link_with,
dependencies: dependencies,
)

View File

@ -0,0 +1,2 @@
subdir('dummymaster')
subdir('dummyinstaller')

View File

@ -7,7 +7,7 @@ executable(
'micedump/eeprom.c',
'micedump/kc_mxkeychip.c',
# 'micedump/kc_n2.c',
# 'micedump/kc_pic.c',
'micedump/kc_pic.c',
'micedump/platform.c',
'micedump/sram.c',
# 'micedump/superio.c',

View File

@ -0,0 +1,48 @@
#include <Windows.h>
#include <stdio.h>
#include "../lib/am/amDongle.h"
#include "../lib/am/amSerialId.h"
#include "../lib/mxk/mxk.h"
void miceDumpKCPIC() {
fprintf(stderr, "Dumping dongle using mxk\n");
MXK_STATUS status;
status = mxkInit();
if (status != MXK_STATUS_OK) {
amiDebugLog("Failed to mxkInit(): %d", status);
return;
}
/**
* The following sequence is required to avoid SBTR!
*
* amDongleSetupKeychip:
* keychip.appboot.systemflag=?&cache=0
* keychip.version=?&cache=0
*
* amlib_init_dongle:
* keychip.billing.keyid=?&cache=1
* keychip.appboot.gameid=?&cache=1
* keychip.appboot.systemflag=?&cache=1
* keychip.appboot.modeltype=?&cache=1
* keychip.appboot.region=?&cache=1
* keychip.appboot.networkaddr=?&cache=1
*/
unsigned char systemFlag;
unsigned char err;
mxkAbSystemFlag(MXK_CACHE_BUST, &systemFlag, &err);
printf("SystemFlag: %02x\n", systemFlag);
unsigned short version;
mxkVersion(&version, MXK_CACHE_BUST, &err);
printf("Version: %04x\n", version);
puts("Dongle woken!");
char gameId[4];
mxkAbGameId(MXK_CACHE_USE, gameId, &err);
printf(" Game ID: %.*s\n", 4, gameId);
}

View File

@ -15,6 +15,8 @@ int main(int argc, char** argv) {
miceDumpSRAM();
else if (strcmp(argv[i], "dongle") == 0)
miceDumpKCMxkeychip();
else if (strcmp(argv[i], "kcpic") == 0)
miceDumpKCPIC();
else
printf("Unknown dump type: %s\n", argv[i]);
}

View File

@ -1,8 +1,9 @@
#include <stdio.h>
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
char path[MAX_PATH * 1000];
int main(int argc, char** argv) {
int oldmain(int argc, char** argv) {
// printf("%d", QueryDosDeviceA(NULL, path, sizeof path));
// printf(" %03x\n", GetLastError());
@ -17,33 +18,17 @@ int main(int argc, char** argv) {
DWORD volumeSerialNumber;
// Crackproof-style call
BOOL ret = GetVolumeInformationA(
"C:\\",
NULL,
0,
&volumeSerialNumber,
NULL,
NULL,
NULL,
0
);
printf("volumeSerialNumber: %08x\n");
BOOL ret = GetVolumeInformationA("C:\\", NULL, 0, &volumeSerialNumber, NULL, NULL, NULL, 0);
printf("volumeSerialNumber: %08x\n", volumeSerialNumber);
// Exhaustive call
CHAR volumeNameBuffer[MAX_PATH];
DWORD maximumComponentLength;
DWORD fileSystemFlags;
CHAR fileSystemName[MAX_PATH];
ret = GetVolumeInformationA(
"C:\\",
volumeNameBuffer,
sizeof volumeNameBuffer,
&volumeSerialNumber,
&maximumComponentLength,
&fileSystemFlags,
fileSystemName,
sizeof fileSystemName
);
ret = GetVolumeInformationA("C:\\", volumeNameBuffer, sizeof volumeNameBuffer,
&volumeSerialNumber, &maximumComponentLength, &fileSystemFlags,
fileSystemName, sizeof fileSystemName);
printf("volumeNameBuffer: %s\n", volumeNameBuffer);
printf("volumeSerialNumber: %08x\n", volumeSerialNumber);
@ -52,4 +37,44 @@ int main(int argc, char** argv) {
printf("fileSystemName: %s\n", fileSystemName);
return 0;
}
}
#define RING
#ifdef RING
#define A2P \
"C:\\Documents and Settings\\All Users\\Application Data/boost_interprocess/ALLNetComA2P"
#else
#define A2P "G:\\MegaSync\\SDEY_1.99\\maimai\\dev\\c\\ProgramData/boost_interprocess/ALLNetComA2P"
#endif
int main(int argc, char** argv) {
unsigned char buf[1];
char buf2[4];
DWORD temp;
HANDLE hFile = CreateFileA(A2P, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
printf("Failed to open A2P %03x\n", GetLastError());
return -1;
}
SetFilePointer(hFile, 4, NULL, 0);
buf[0] = '\1';
WriteFile(hFile, buf, sizeof buf, &temp, NULL);
// buf[0] = '\2'; // game start
buf[0] = '\3'; // game test
SetFilePointer(hFile, 0, NULL, 0);
WriteFile(hFile, buf, sizeof buf, &temp, NULL);
SetFilePointer(hFile, 8, NULL, 0);
buf2[0] = '1';
buf2[0] = '.';
buf2[0] = '9';
buf2[0] = '9';
WriteFile(hFile, buf2, sizeof buf2, &temp, NULL);
CloseHandle(hFile);
}