1
0
mirror of synced 2024-11-14 09:47:40 +01:00

A bunch of user-friendly things

This commit is contained in:
Bottersnike 2023-03-13 21:49:07 +00:00
parent aef9cb26cb
commit 38ccd51217
No known key found for this signature in database
94 changed files with 3334 additions and 985 deletions

View File

@ -34,6 +34,7 @@ clean:
dist: dist:
@-mkdir $(DIST_DIR) > NUL 2>&1 @-mkdir $(DIST_DIR) > NUL 2>&1
@-mkdir $(DIST_DIR)\util > 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 > NUL 2>&1
@-mkdir $(DIST_DIR)\Execute\Z > NUL 2>&1 @-mkdir $(DIST_DIR)\Execute\Z > NUL 2>&1
@-mkdir $(DIST_DIR)\Execute\S > 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/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.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\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\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\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\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/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" @copy /Y "src/micetools/miceboot\TrueCrypt.cmd" "$(DIST_DIR)/Execute/TrueCrypt.cmd"
@xcopy /E /H /C /R /Q /Y src\system "$(DIST_DIR)\system/*" @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_Gateway;
uint32_t m_PrimaryDns; uint32_t m_PrimaryDns;
uint32_t m_SecondaryDns; uint32_t m_SecondaryDns;
} AM_SYSDATA_NETWORK_IF; } AM_SYSDATA_NETWORK_IF, *PAM_SYSDATA_NETWORK_IF;
typedef struct { typedef struct {
uint64_t m_TimeStamp; uint64_t m_TimeStamp;
@ -28,17 +28,17 @@ typedef struct {
uint8_t CreditRate; uint8_t CreditRate;
uint8_t Cost[8]; uint8_t Cost[8];
uint8_t Rsv0F; uint8_t Rsv0F;
} AM_CREDIT_CONFIG; } AM_CREDIT_CONFIG, *PAM_CREDIT_CONFIG;
typedef struct { typedef struct {
uint8_t Credit; uint8_t Credit;
uint8_t Remain; uint8_t Remain;
} AM_CREDIT_PDATA; } AM_CREDIT_PDATA, *PAM_CREDIT_PDATA;
typedef struct { typedef struct {
AM_CREDIT_PDATA Player[4]; AM_CREDIT_PDATA Player[4];
uint8_t Rsv08[8]; uint8_t Rsv08[8];
} AM_CREDIT_DATA; } AM_CREDIT_DATA, *PAM_CREDIT_DATA;
typedef struct { typedef struct {
uint32_t CoinChute[4]; uint32_t CoinChute[4];
@ -46,7 +46,7 @@ typedef struct {
uint32_t CoinCredit; uint32_t CoinCredit;
uint32_t ServiceCredit; uint32_t ServiceCredit;
uint32_t TotalCredit; uint32_t TotalCredit;
} AM_CREDIT_BOOKKEEPING; } AM_CREDIT_BOOKKEEPING, *PAM_CREDIT_BOOKKEEPING;
typedef struct { typedef struct {
uint8_t m_month; uint8_t m_month;
@ -61,7 +61,7 @@ typedef struct {
uint32_t m_Crc; uint32_t m_Crc;
uint8_t Rsv04[4]; uint8_t Rsv04[4];
AM_SYSDATA_NETWORK_IF m_Eth; AM_SYSDATA_NETWORK_IF m_Eth;
} AM_SYSDATAwH_NETWORK; } AM_SYSDATAwH_NETWORK, *PAM_SYSDATAwH_NETWORK;
typedef struct { typedef struct {
uint32_t m_Crc; uint32_t m_Crc;
@ -70,14 +70,14 @@ typedef struct {
uint8_t m_Rental; uint8_t m_Rental;
uint8_t Rsv0F; uint8_t Rsv0F;
char m_strSerialId[17]; char m_strSerialId[17];
} AM_SYSDATAwH_STATIC; } AM_SYSDATAwH_STATIC, *PAM_SYSDATAwH_STATIC;
typedef struct { typedef struct {
uint32_t m_Crc; uint32_t m_Crc;
uint8_t Rsv04[4]; uint8_t Rsv04[4];
AM_CREDIT_CONFIG m_Config; AM_CREDIT_CONFIG m_Config;
uint8_t Rsv18[8]; 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_ETH0;
typedef AM_SYSDATAwH_NETWORK AM_SYSDATAwH_NETWORK_ETH1; typedef AM_SYSDATAwH_NETWORK AM_SYSDATAwH_NETWORK_ETH1;
@ -88,7 +88,7 @@ typedef struct {
char m_GameId[4]; char m_GameId[4];
uint8_t m_Region; uint8_t m_Region;
uint8_t Rsv0D[3]; uint8_t Rsv0D[3];
} AM_SYSDATAwH_HISTORY; } AM_SYSDATAwH_HISTORY, *PAM_SYSDATAwH_HISTORY;
typedef struct { typedef struct {
uint32_t m_Crc; uint32_t m_Crc;
@ -97,7 +97,7 @@ typedef struct {
uint8_t m_LogNum; uint8_t m_LogNum;
uint8_t Rsv0a[22]; uint8_t Rsv0a[22];
ERROR_LOG_BODY m_Body[15]; ERROR_LOG_BODY m_Body[15];
} AM_SYSDATAwH_ERROR_LOG; } AM_SYSDATAwH_ERROR_LOG, *PAM_SYSDATAwH_ERROR_LOG;
typedef struct { typedef struct {
uint32_t m_Crc; uint32_t m_Crc;
@ -105,7 +105,7 @@ typedef struct {
AM_CREDIT_DATA m_CreditData; AM_CREDIT_DATA m_CreditData;
AM_CREDIT_BOOKKEEPING m_Bookkeeping; AM_CREDIT_BOOKKEEPING m_Bookkeeping;
uint8_t Rsv38[456]; uint8_t Rsv38[456];
} AM_SYSDATAwH_BACKUP; } AM_SYSDATAwH_BACKUP, *PAM_SYSDATAwH_BACKUP;
typedef struct { typedef struct {
uint32_t m_Crc; uint32_t m_Crc;
@ -115,7 +115,7 @@ typedef struct {
uint32_t m_Bias; uint32_t m_Bias;
uint32_t m_ServerBias; uint32_t m_ServerBias;
uint8_t Rsv20[480]; uint8_t Rsv20[480];
} AM_SYSDATAwH_TIMEZONE; } AM_SYSDATAwH_TIMEZONE, *PAM_SYSDATAwH_TIMEZONE;
typedef struct { typedef struct {
uint32_t m_Crc; uint32_t m_Crc;
@ -123,21 +123,21 @@ typedef struct {
uint32_t m_Caution; uint32_t m_Caution;
uint32_t m_Peak; uint32_t m_Peak;
uint8_t Rsv10[496]; uint8_t Rsv10[496];
} AM_SYSDATAwH_HM_PEAK; } AM_SYSDATAwH_HM_PEAK, *PAM_SYSDATAwH_HM_PEAK;
typedef struct { typedef struct {
uint32_t m_Crc; uint32_t m_Crc;
uint8_t Rsv04[4]; uint8_t Rsv04[4];
uint8_t m_MountSleepS; uint8_t m_MountSleepS;
uint8_t Rsv09[55]; uint8_t Rsv09[55];
} AM_SYSDATAwH_ALPB_DEV_CONFIG; } AM_SYSDATAwH_ALPB_DEV_CONFIG, *PAM_SYSDATAwH_ALPB_DEV_CONFIG;
typedef struct { typedef struct {
uint32_t m_Crc; uint32_t m_Crc;
uint32_t m_Uk1; uint32_t m_Uk1;
uint32_t m_Uk2; uint32_t m_Uk2;
uint32_t m_Uk3; uint32_t m_Uk3;
} AM_SYSDATAwH_ALPB_CARD_ID; } AM_SYSDATAwH_ALPB_CARD_ID, *PAM_SYSDATAwH_ALPB_CARD_ID;
typedef struct { typedef struct {
uint32_t m_Crc; uint32_t m_Crc;
@ -148,7 +148,7 @@ typedef struct {
uint32_t m_Uk5; uint32_t m_Uk5;
uint32_t m_Uk6; uint32_t m_Uk6;
uint32_t m_Uk7; uint32_t m_Uk7;
} AM_SYSDATAwH_ALPB_COMPUTER_NAME; } AM_SYSDATAwH_ALPB_COMPUTER_NAME, *PAM_SYSDATAwH_ALPB_COMPUTER_NAME;
#pragma pack(pop) #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); comdev_read(com, &one_byte, 1);
if (one_byte != COMIO_SYNC) { if (one_byte != COMIO_SYNC) {
log_error("com", "Garbage on JVS: %02x", one_byte); log_error(plfComm, "Garbage on JVS: %02x", one_byte);
continue; continue;
} }
break; 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); 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 = 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) { 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->in);
ringbuf_purge(&com_device->out); ringbuf_purge(&com_device->out);
com_device->event = CreateEventW(NULL, TRUE, FALSE, com_device->com->wName); com_device->event = CreateEventW(NULL, TRUE, FALSE, com_device->com->wName);
com_device->thread = INVALID_HANDLE_VALUE;
hook_file(file); hook_file(file);
return com_device; 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/com.h"
#include "hooks/files.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; com_hook_t* com;
file_hook_t* file; file_hook_t* file;
@ -11,7 +16,9 @@ typedef struct com_device {
ring_buffer_t out; ring_buffer_t out;
HANDLE event; HANDLE event;
HANDLE thread; HANDLE thread;
} com_device_t; FnComDeviceThread* thread_worker;
};
com_device_t* com_devices[NUM_COM_PORTS];
typedef struct { typedef struct {
BYTE frame_length; BYTE frame_length;
@ -36,8 +43,6 @@ typedef struct {
#define COMIO_STATUS_OK 0 #define COMIO_STATUS_OK 0
#define COMIO_STATUS_NG 1 #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_blocking(com_device_t* com, unsigned char* buffer, short bytes);
short comdev_read(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); 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); 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 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 "../lib/mice/mice.h"
#include "./util/_util.h" #include "./util/_util.h"
void mice_got_game_id(char game_id[4]);
extern WCHAR exeName[MAX_PATH + 1]; extern WCHAR exeName[MAX_PATH + 1];
extern DWORD imageOffset; extern DWORD imageOffset;

View File

@ -1,15 +1,73 @@
#include "_devices.h" #include "_devices.h"
#include "smb_pca9535.h"
#include "smb_at24c64an.h" #include "smb_at24c64an.h"
#include "smb_ds28cn01.h"
#include "smb_ds2460.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() { void install_devices() {
install_led_bd(); install_led_bd();
install_touch_bd(); install_touch_bd();
install_aime_bd(); install_aime_bd();
start_devices();
smbus_install(/* 0x20 */ PCA9535_ADDRESS, &smbus_PCA9535_write, &smbus_PCA9535_read); smbus_install(/* 0x20 */ PCA9535_ADDRESS, &smbus_PCA9535_write, &smbus_PCA9535_read);
// mxkN2CmdWriteData(byte addr,byte *data,ushort nbytes,ushort *nbytesOut) // 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_write;
smbus_callback_t smbus_N2_read; smbus_callback_t smbus_N2_read;
void start_devices();
void register_device(const char* name, FnComDeviceThread* thread);
void install_devices(); void install_devices();

View File

@ -73,9 +73,11 @@ typedef struct rs232c_recv_head {
BYTE op; BYTE op;
} rs232c_recv_head_t; } rs232c_recv_head_t;
#define log_level log_misc
BYTE extra[0xff]; BYTE extra[0xff];
static DWORD WINAPI led_bd_thread(com_device_t* dev) { 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) { while (1) {
rs232c_recv_head_t head; 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, (unsigned char*)&head, sizeof head);
comdev_read(dev, extra, head.length); 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) { switch (head.op) {
case 0x01: 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); comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x01\x01\x18", 8);
// syn dst src len sts op. rep chk // syn dst src len sts op. rep chk
break; break;
case 0x10: 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); comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x10\x01\x27", 8);
// syn dst src len sts op. rep chk // syn dst src len sts op. rep chk
break; break;
@ -106,13 +108,13 @@ static DWORD WINAPI led_bd_thread(com_device_t* dev) {
COLOURS[extra[0]][1] = extra[2]; COLOURS[extra[0]][1] = extra[2];
COLOURS[extra[0]][2] = extra[3]; 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]); extra[3]);
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x31\x01\x48", 8); comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x31\x01\x48", 8);
// syn dst src len sts op. rep chk // syn dst src len sts op. rep chk
break; break;
case 0x32: 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]); extra[2], extra[3], extra[4], extra[5], extra[6], extra[7]);
for (unsigned char i = extra[2] - 1; i < extra[1]; i++) { 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 // syn dst src len sts op. rep chk
break; break;
case 0x33: 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]); 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); comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x33\x01\x4a", 8);
// syn dst src len sts op. rep chk // syn dst src len sts op. rep chk
@ -135,7 +137,7 @@ static DWORD WINAPI led_bd_thread(com_device_t* dev) {
break; break;
case 0x39: 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); comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x39\x01\x50", 8);
// syn dst src len sts op. rep chk // 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]; COLOURS[9][2] = extra[0];
break; break;
case 0x3b: 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); comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x3b\x01\x52", 8);
// syn dst src len sts op. rep chk // syn dst src len sts op. rep chk
break; break;
case 0x3c: 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); comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x3c\x01\x53", 8);
// syn dst src len sts op. rep chk // syn dst src len sts op. rep chk
break; break;
case 0x3f: 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]); extra[2], extra[3], extra[4], extra[5], extra[6]);
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x3f\x01\x56", 8); comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x3f\x01\x56", 8);
// syn dst src len sts op. rep chk // syn dst src len sts op. rep chk
@ -163,20 +165,20 @@ static DWORD WINAPI led_bd_thread(com_device_t* dev) {
case 0x7c: case 0x7c:
// extra[0] goes from 0 to 7 // extra[0] goes from 0 to 7
// Could this be some sort of calibration for the buttons? // 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); comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x04\x01\x7c\x01\x00\x94", 9);
// \/ causes 7b to be used // \/ causes 7b to be used
// comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x04\x01\x7c\x01\x10\xa4", 9); // comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x04\x01\x7c\x01\x10\xa4", 9);
// syn dst src len sts op. rep --- chk // syn dst src len sts op. rep --- chk
break; break;
case 0x7b: 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); comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x7b\x01\x92", 8);
// syn dst src len sts op. rep chk // syn dst src len sts op. rep chk
break; break;
default: 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; break;
} }
} }
@ -214,19 +216,7 @@ void __stdcall led_overlay(unsigned int hookType, IDirect3DDevice9* dev) {
} }
void install_led_bd() { void install_led_bd() {
register_device("mailed", led_bd_thread);
// register_gui_hook(&led_overlay); // 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; BOOL touch_is_enabled = false;
BYTE thresh = 0x00; // Lazy caching of single value BYTE thresh = 0x00; // Lazy caching of single value
DWORD WINAPI touch_bd_thread(com_device_t* dev) { 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) { while (1) {
if (touch_is_enabled && !comdev_available(dev)) { 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 (read_one(dev) != '{') continue;
while (comdev_available(dev) < 5) { while (comdev_available(dev) < 5) {
log_info("touch", "<. .>"); log_info(plfMaiTouch, "<. .>");
Sleep(50); Sleep(50);
} }
BYTE command[5]; BYTE command[5];
@ -40,20 +40,20 @@ DWORD WINAPI touch_bd_thread(com_device_t* dev) {
if (memcmp(command, "HALT}", 5) == 0) { if (memcmp(command, "HALT}", 5) == 0) {
if (touch_is_enabled) if (touch_is_enabled)
log_info("touch", "Touchscreen left active mode"); log_info(plfMaiTouch, "Touchscreen left active mode");
else else
log_misc("touch", "Touchscreen not in active mode"); log_misc(plfMaiTouch, "Touchscreen not in active mode");
touch_is_enabled = false; touch_is_enabled = false;
} else if (memcmp(command, "STAT}", 5) == 0) { } else if (memcmp(command, "STAT}", 5) == 0) {
if (!touch_is_enabled) if (!touch_is_enabled)
log_info("touch", "Touchscreen entered active mode"); log_info(plfMaiTouch, "Touchscreen entered active mode");
else else
log_misc("touch", "Touchscreen already in active mode"); log_misc(plfMaiTouch, "Touchscreen already in active mode");
touch_is_enabled = true; touch_is_enabled = true;
} else if (command[2] == 'k' && command[4] == '}') { } else if (command[2] == 'k' && command[4] == '}') {
BYTE sensor = get_touch_id(command[1]); 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 // Sensor == '@': failed
// ( <L/R> <sensor> <> <> ) // ( <L/R> <sensor> <> <> )
response[1] = command[0]; response[1] = command[0];
@ -65,7 +65,7 @@ DWORD WINAPI touch_bd_thread(com_device_t* dev) {
BYTE sensor = get_touch_id(command[1]); BYTE sensor = get_touch_id(command[1]);
// { <L/R> <sensor> t h } // { <L/R> <sensor> t h }
log_misc("touch", "th-command recieved: %d", sensor); log_misc(plfMaiTouch, "th-command recieved: %d", sensor);
// Sensor == '@': failed // Sensor == '@': failed
// ( <L/R> <sensor> <> <threshold> ) // ( <L/R> <sensor> <> <threshold> )
@ -75,23 +75,9 @@ DWORD WINAPI touch_bd_thread(com_device_t* dev) {
comdev_write(dev, response, 6); comdev_write(dev, response, 6);
} else { } else {
log_error("touch", "Unhandled: {%.*s", 5, command); log_error(plfMaiTouch, "Unhandled: {%.*s", 5, command);
} }
} }
} }
void install_touch_bd() { void install_touch_bd() { register_device("maitouch", touch_bd_thread); }
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);
}

View File

@ -217,14 +217,14 @@ BYTE BANA_KEY[6];
DWORD WINAPI aime_bd_thread(com_device_t* dev) { DWORD WINAPI aime_bd_thread(com_device_t* dev) {
static int fwNumBytes = 0; 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; bool radio = false;
while (1) { while (1) {
comio_recv_head_t req; comio_recv_head_t req;
unsigned char sum = comio_next_req(dev, &req, extra); 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) { if (req.dst == 0x00 || req.dst == 0x01) {
// Aime readers // Aime readers
@ -249,7 +249,7 @@ DWORD WINAPI aime_bd_thread(com_device_t* dev) {
memcpy(AIME_KEY, extra, sizeof AIME_KEY); memcpy(AIME_KEY, extra, sizeof AIME_KEY);
comio_reply(dev, &req, COMIO_STATUS_OK, 0, NULL); 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]); AIME_KEY[1], AIME_KEY[2], AIME_KEY[3], AIME_KEY[4], AIME_KEY[5]);
} }
break; break;
@ -260,7 +260,7 @@ DWORD WINAPI aime_bd_thread(com_device_t* dev) {
memcpy(BANA_KEY, extra, sizeof BANA_KEY); memcpy(BANA_KEY, extra, sizeof BANA_KEY);
comio_reply(dev, &req, COMIO_STATUS_OK, 0, NULL); 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]); BANA_KEY[1], BANA_KEY[2], BANA_KEY[3], BANA_KEY[4], BANA_KEY[5]);
} }
break; break;
@ -294,7 +294,7 @@ DWORD WINAPI aime_bd_thread(com_device_t* dev) {
case TN32Op_Unknown61: case TN32Op_Unknown61:
// null-terminated line of the firmware hex! // null-terminated line of the firmware hex!
comio_reply(dev, &req, COMIO_STATUS_OK, 0, NULL); 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; break;
case TN32Op_Unknown63: case TN32Op_Unknown63:
// req.length == 0; start binary firmware update? // 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"); comio_reply(dev, &req, COMIO_STATUS_OK, 9, (BYTE*)"15084\xff\x10\x00\x12");
break; break;
case LedSetColour: 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( printf(
"\033[48;2;%d;%d;%dm " "\033[48;2;%d;%d;%dm "
" \033[0m", " \033[0m",
@ -384,17 +384,5 @@ void install_aime_bd() {
OpcodeNames[LedGetInfo] = "LedGetInfo"; OpcodeNames[LedGetInfo] = "LedGetInfo";
OpcodeNames[LedSetColour] = "LedSetColour"; OpcodeNames[LedSetColour] = "LedSetColour";
char* text = MiceConfig.devices.aime_bd; register_device("aime_tn32msec", aime_bd_thread);
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);
} }

View File

@ -2,39 +2,16 @@
#include "../../maiBackupStructs.h" #include "../../maiBackupStructs.h"
#include "_devices.h" #include "_devices.h"
#define EEPROM_DUMP L"dev/eeprom.bin" #define EEPROM_PATH L"dev/eeprom.bin"
#include "../../sysconf.h" #include "../../sysconf.h"
// 8192 x 8 (64kbit) of eeprom // 8192 x 8 (64kbit) of eeprom
BYTE EEPROM_DATA[0x2000]; #define EEPROM_SIZE 0x2000
void eeprom_dump() { LPBYTE EEPROM_DATA = NULL;
HANDLE dump = HANDLE EEPROM_FILE = INVALID_HANDLE_VALUE;
_CreateFileW(EEPROM_DUMP, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL); HANDLE EEPROM_FILE_MAPPING = INVALID_HANDLE_VALUE;
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);
}
#define fix_crc(block) \ #define fix_crc(block) \
do { \ do { \
@ -72,19 +49,9 @@ void set_eeprom_static_config() {
} }
void build_eeprom() { void build_eeprom() {
if (FileExists(EEPROM_DUMP)) { log_info(plfEeprom, "Building default EEPROM file");
eeprom_restore();
// Our network and static config always gets priority
set_eeprom_static_config();
set_eeprom_network_config();
eeprom_dump(); memset(EEPROM_DATA, 0xff, EEPROM_SIZE);
return;
}
log_info("eeprom", "Building default EEPROM file");
memset(EEPROM_DATA, 0xff, sizeof EEPROM_DATA);
set_eeprom_static_config(); set_eeprom_static_config();
@ -102,22 +69,10 @@ void build_eeprom() {
set_eeprom_network_config(); 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 }; AM_SYSDATAwH_ALPB_CARD_ID CardInfo = { 0 };
fix_crc(CardInfo); fix_crc(CardInfo);
memcpy(&EEPROM_DATA[AM_SYSDATAwH_ALPB_CARD_ID_REG] + (sizeof History), &CardInfo, memcpy(&EEPROM_DATA[AM_SYSDATAwH_ALPB_CARD_ID_REG], &CardInfo, sizeof CardInfo);
sizeof CardInfo); memcpy(&EEPROM_DATA[AM_SYSDATAwH_ALPB_CARD_ID_DUP], &CardInfo, sizeof CardInfo);
memcpy(&EEPROM_DATA[AM_SYSDATAwH_ALPB_CARD_ID_DUP] + (sizeof History), &CardInfo,
sizeof CardInfo);
AM_SYSDATAwH_ALPB_COMPUTER_NAME CompuerName = { 0 }; AM_SYSDATAwH_ALPB_COMPUTER_NAME CompuerName = { 0 };
fix_crc(CompuerName); 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_REG], &DevConfig, sizeof DevConfig);
memcpy(&EEPROM_DATA[AM_SYSDATAwH_ALPB_DEV_CONFIG_DUP], &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() { void ensure_valid_eeprom() {
static BOOL built = false; if (!EEPROM_DATA) {
if (built) { BOOL isNew = !FileExists(EEPROM_PATH);
eeprom_restore();
return;
}
build_eeprom();
built = true;
}
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) { void eeprom_read(WORD addr, BYTE* data, BYTE length) {
ensure_valid_eeprom(); ensure_valid_eeprom();
if (addr >= sizeof EEPROM_DATA) return; if (addr >= EEPROM_SIZE) return;
if (length + addr > sizeof EEPROM_DATA) length = (sizeof EEPROM_DATA - addr) & 0xff; 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) { void eeprom_write(WORD addr, BYTE* data, BYTE length) {
ensure_valid_eeprom(); ensure_valid_eeprom();
if (addr >= sizeof EEPROM_DATA) return; if (addr >= EEPROM_SIZE) return;
if (length + addr > sizeof EEPROM_DATA) length = (sizeof EEPROM_DATA - addr) & 0xff; if (length + addr > EEPROM_SIZE) length = (EEPROM_SIZE - addr) & 0xff;
memcpy(&EEPROM_DATA[addr], data, length); // TODO: Do any games write this as anything other than a complete block?
eeprom_dump(); 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) { BOOL smbus_AT24C64AN_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
switch (cmd) { switch (cmd) {
case ICH9_CMD_BLOCK: { 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); eeprom_write(code, data, dlen);
return TRUE; return TRUE;
} }
default: default:
log_error("eeprom", "Unsupported write mode: %01x, %02x", cmd, code); log_error(plfEeprom, "Unsupported write mode: %01x, %02x", cmd, code);
return FALSE; return FALSE;
} }
} }
@ -180,12 +169,12 @@ BOOL smbus_AT24C64AN_read(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
data[0] = 0x00; data[0] = 0x00;
return TRUE; return TRUE;
case ICH9_CMD_BLOCK: { 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); eeprom_read(code, data, dlen);
return TRUE; return TRUE;
} }
default: default:
log_error("eeprom", "Unsupported read mode: %01x, %02x", cmd, code); log_error(plfEeprom, "Unsupported read mode: %01x, %02x", cmd, code);
return FALSE; 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], ComputeDallasSha(INPUT_BUFFER, (long*)&COMPUTED_MAC[0], (long*)&COMPUTED_MAC[4],
(long*)&COMPUTED_MAC[8], (long*)&COMPUTED_MAC[12], (long*)&COMPUTED_MAC[8], (long*)&COMPUTED_MAC[12],
(long*)&COMPUTED_MAC[16]); (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 * | 0x04 -> DS2460_CMD_COMPUTE_TO_MAC_BUFFER
*/ */
if (!(data[0] & DS2460_CMD_COMPUTE)) { if (!(data[0] & DS2460_CMD_COMPUTE)) {
log_error("ds2460", "Unknown command: %02x", data[0]); log_error(plfDS2460, "Unknown command: %02x", data[0]);
return FALSE; return FALSE;
} }
BYTE numSecret = (data[0] >> 3) & 3; 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]); ds2460_update_mac(gpSha, SECRETS[numSecret]);
return TRUE; return TRUE;
default: default:
log_error("ds2460", "Unknown write command: %02x", code); log_error(plfDS2460, "Unknown write command: %02x", code);
return FALSE; return FALSE;
} }
case ICH9_CMD_BLOCK: { 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, memcpy_s(&INPUT_BUFFER[offset + 1], DS2460_INPUT_BUFFER_SIZE - (offset + 1), data,
dlen); dlen);
log_info("ds2460", "Block write, %d @ %04x: ", dlen + 1, offset); log_info(plfDS2460, "Block write, %d @ %04x", dlen + 1, offset);
return TRUE; return TRUE;
} }
default: default:
log_error("ds2460", "Unsupported write mode: %01x (%02x)", cmd, code); log_error(plfDS2460, "Unsupported write mode: %01x (%02x)", cmd, code);
return FALSE; return FALSE;
} }
} }
@ -135,10 +140,10 @@ BOOL smbus_ds2460_read(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
return TRUE; return TRUE;
} }
log_error("smx-exio", "Unknown read command: %02x", code); log_error(plfDS2460, "Unknown read command: %02x", code);
return FALSE; return FALSE;
default: default:
log_error("ds2460", "Unsupported read mode: %01x (%02x)", cmd, code); log_error(plfDS2460, "Unsupported read mode: %01x (%02x)", cmd, code);
return FALSE; 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_write;
smbus_callback_t smbus_ds2460_read; 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 page = command & 3;
BYTE upper = command & 0xf0; BYTE upper = command & 0xf0;
if (upper == 0xD0) { if (upper == DS28CN01_COMPUTE_1) {
log_warning("ds28cn01", "Computing for: authentication (flag = 1)"); log_warning(plfDS28CN01, "Computing for: authentication (flag = 1)");
} else if (upper == 0xE0) { } else if (upper == DS28CN01_COMPUTE_2) {
log_warning("ds28cn01", "Computing for: ds.compute (flag = 0)"); log_warning(plfDS28CN01, "Computing for: ds.compute (flag = 0)");
} else { } else {
log_error("ds28cn01", "Unknown A9"); log_error(plfDS28CN01, "Unknown A9");
return FALSE; return FALSE;
} }
if (dlen != 7) { 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; return FALSE;
} }
@ -132,7 +132,7 @@ BOOL smbus_ds28cn01_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
// dlen++; // dlen++;
// char* challenge_s = malloc(dlen * 3 + 1); // char* challenge_s = malloc(dlen * 3 + 1);
// if (challenge_s == NULL) { // if (challenge_s == NULL) {
// log_info("ds28cn01", "Challenge: (buffer failed)"); // log_info(plfDS28CN01, "Challenge: (buffer failed)");
// return TRUE; // 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]); // sprintf_s(challenge_s + i * 3, 4, "%02x ", data[i]);
// } // }
// challenge_s[dlen * 3 + 1] = '\0'; // challenge_s[dlen * 3 + 1] = '\0';
// log_info("ds28cn01", "Challenge: %s", challenge_s); // log_info(plfDS28CN01, "Challenge: %s", challenge_s);
// free(challenge_s); // free(challenge_s);
return TRUE; return TRUE;
} }
log_error("ds28cn01", "Unknown write command: %04x", code); log_error(plfDS28CN01, "Unknown write command: %04x", code);
} }
case ICH9_CMD_I2C_READ: { case ICH9_CMD_I2C_READ: {
switch (code) { 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]; for (int i = 0; i < dlen; i++) data[i] = COMPUTED_MAC[i];
return TRUE; return TRUE;
default: default:
log_error("ds28cn01", "Unknown I2C read command: %04x", code); log_error(plfDS28CN01, "Unknown I2C read command: %04x", code);
} }
} }
default: default:
log_error("ds28cn01", "Unsupported write mode: %01x (%04x)", cmd, code); log_error(plfDS28CN01, "Unsupported write mode: %01x (%04x)", cmd, code);
return FALSE; return FALSE;
} }
} }
@ -191,10 +191,10 @@ BOOL smbus_ds28cn01_read(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
return TRUE; return TRUE;
} }
log_error("ds28cn01", "Unknown read command: %04x", code); log_error(plfDS28CN01, "Unknown read command: %04x", code);
return FALSE; return FALSE;
default: default:
log_error("ds28cn01", "Unsupported read mode: %01x (%04x)", cmd, code); log_error(plfDS28CN01, "Unsupported read mode: %01x (%04x)", cmd, code);
return FALSE; 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_write;
smbus_callback_t smbus_ds28cn01_read; smbus_callback_t smbus_ds28cn01_read;
@ -18,6 +18,9 @@ smbus_callback_t smbus_ds28cn01_read;
#define DS28CN01_REG_STATUS 0xA8 #define DS28CN01_REG_STATUS 0xA8
#define DS28CN01_REG_MAC 0xB0 #define DS28CN01_REG_MAC 0xB0
#define DS28CN01_COMPUTE_1 0xD0
#define DS28CN01_COMPUTE_2 0xE0
// Flags // Flags
#define DS28CN01_STATUS_FLAG_BUSY 2 #define DS28CN01_STATUS_FLAG_BUSY 2

View File

@ -1,3 +1,5 @@
#include "smb_n2.h"
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/hmac.h> #include <openssl/hmac.h>
#include <openssl/rand.h> #include <openssl/rand.h>
@ -6,57 +8,10 @@
#include "../../sysconf.h" #include "../../sysconf.h"
#include "_devices.h" #include "_devices.h"
#define N2_TAG_OFFSET 0 LOG_FACILITY _lf = {
#define N2_PARAMSIZE_OFFSET 2 .m_name = "smb-n2",
#define N2_COMMAND_OFFSET 4 };
#define N2_TAG_SIZE 2 PLOG_FACILITY plf = &_lf;
#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
#define N2_IO_BUFFER 0x1000 #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); RAND_bytes(n2_session_nonce, sizeof n2_session_nonce);
memcpy(dataOut, 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; return N2_SUCCESS;
} }
WORD n2_set_auth_key(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) { WORD n2_set_auth_key(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
*nOut = 0; *nOut = 0;
log_misc("smb-n2", "Auth key set"); log_misc(plf, "Auth key set");
BYTE pt[32]; BYTE pt[32];
mxkCryptDecryptAes128CBC(n2_enc_key.key, n2_enc_key.iv, dataIn, pt, sizeof pt); 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) { WORD n2_set_enc_key(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
*nOut = 0; *nOut = 0;
log_misc("smb-n2", "Enc key set"); log_misc(plf, "Enc key set");
BYTE pt[32]; BYTE pt[32];
mxkCryptDecryptAes128CBC(n2_enc_key.key, n2_enc_key.iv, dataIn, pt, sizeof pt); 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) { WORD n2_get_auth_level(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
*nOut = 1; *nOut = 1;
dataOut[0] = 3; // TODO: ? dataOut[0] = 3; // TODO: ?
log_misc("smb-n2", "Auth level get"); log_misc(plf, "Auth level get");
return N2_SUCCESS; return N2_SUCCESS;
} }
WORD n2_get_error_code(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) { WORD n2_get_error_code(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
*nOut = 2; *nOut = 2;
((PWORD)dataOut)[0] = fix_endian(n2_error_code); ((PWORD)dataOut)[0] = fix_endian(n2_error_code);
log_misc("smb-n2", "Error get"); log_misc(plf, "Error get");
return N2_SUCCESS; return N2_SUCCESS;
} }
WORD n2_read_keychip_id(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) { 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, mxkCryptEncryptAes128CBC(n2_enc_key.key, n2_enc_key.iv, dataOut + 2, (LPBYTE)&n2_keychip_info,
nbytes); nbytes);
log_misc("smb-n2", "Read keychip ID: %08x", nbytes); log_misc(plf, "Read keychip ID: %08x", nbytes);
return N2_SUCCESS; return N2_SUCCESS;
} }
WORD n2_get_version(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) { 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) { void do_n2_command(WORD tag, WORD paramSize, WORD command, LPBYTE data) {
n2_install_commands(); 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); 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]; BYTE auth_key[20];
memcpy(auth_key, n2_auth_key, sizeof auth_key); 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_DigestFinal_ex(ctx, n2_out_buffer + N2_HEADER_SIZE + bodyLength, &outlen);
EVP_MD_CTX_destroy(ctx); EVP_MD_CTX_destroy(ctx);
// At this point: packet = header | data | SHA(header | command | data)
if (tag == N2_TAG_RQU_AUTH_COMMAND) { if (tag == N2_TAG_RQU_AUTH_COMMAND) {
BYTE crypto_buffer[N2_CHECKSUM_SIZE]; BYTE crypto_buffer[N2_CHECKSUM_SIZE];
// Calculate a new SHA1 of the packet, including the SHA1 we just appeneded // Calculate a new SHA1 of the packet, including the SHA1 we just appeneded
// crypto_buffer = SHA1(header | command | data)
ctx = EVP_MD_CTX_create(); ctx = EVP_MD_CTX_create();
EVP_DigestInit(ctx, EVP_sha1()); EVP_DigestInit(ctx, EVP_sha1());
EVP_DigestUpdate(ctx, n2_out_buffer, N2_HEADER_SIZE); 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_CTX_init(&hmac_ctx);
HMAC_Init_ex(&hmac_ctx, auth_key, sizeof auth_key, EVP_sha1(), NULL); 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); 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); HMAC_Update(&hmac_ctx, n2_out_buffer + N2_HEADER_SIZE + bodyLength, N2_CHECKSUM_SIZE);
// Request nonce // Request nonce
HMAC_Update(&hmac_ctx, n2_in_buffer + paramSize - N2_AUTH_SIZE - N2_CHECKSUM_SIZE, 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; 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; return FALSE;
} }
case ICH9_CMD_I2C_READ: { 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; 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; 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; return FALSE;
} }
BOOL smbus_N2_read(ich9_cmd_t cmd, WORD code, BYTE nbytes, BYTE* data) { 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; 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]; config[1] = data[0];
return TRUE; return TRUE;
default: default:
log_error("pca9535", "Unknown write command: %02x", code); log_error(plfPCA9535, "Unknown write command: %02x", code);
return FALSE; return FALSE;
} }
default: default:
log_error("pca9535", "Unsupported write mode: %01x (%02x)", cmd, code); log_error(plfPCA9535, "Unsupported write mode: %01x (%02x)", cmd, code);
return FALSE; return FALSE;
} }
} }
@ -167,11 +167,11 @@ BOOL smbus_PCA9535_read(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
return TRUE; return TRUE;
default: default:
log_error("pca9535", "Unknown read command: %02x", code); log_error(plfPCA9535, "Unknown read command: %02x", code);
return FALSE; return FALSE;
} }
default: default:
log_error("pca9535", "Unsupported read mode: %01x (%02x)", cmd, code); log_error(plfPCA9535, "Unsupported read mode: %01x (%02x)", cmd, code);
return FALSE; return FALSE;
} }
} }

View File

@ -1,3 +1,5 @@
#include <signal.h>
#include "common.h" #include "common.h"
#include "devices/_devices.h" #include "devices/_devices.h"
#include "drivers/mx.h" #include "drivers/mx.h"
@ -15,7 +17,7 @@ DWORD GetImageBase(void) {
HANDLE hObject = HANDLE hObject =
_CreateFileW(sModulePath, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); _CreateFileW(sModulePath, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hObject == INVALID_HANDLE_VALUE) { 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; return 0;
} }
@ -24,11 +26,11 @@ DWORD GetImageBase(void) {
_SetFilePointer(hObject, 0, NULL, FILE_BEGIN); _SetFilePointer(hObject, 0, NULL, FILE_BEGIN);
_ReadFile(hObject, &dosHeader, sizeof dosHeader, &nRead, NULL); _ReadFile(hObject, &dosHeader, sizeof dosHeader, &nRead, NULL);
if (nRead != sizeof dosHeader) { 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; return 0;
} }
if (dosHeader.e_magic != IMAGE_DOS_SIGNATURE) { 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; return 0;
} }
@ -36,11 +38,11 @@ DWORD GetImageBase(void) {
_SetFilePointer(hObject, dosHeader.e_lfanew, NULL, FILE_BEGIN); _SetFilePointer(hObject, dosHeader.e_lfanew, NULL, FILE_BEGIN);
_ReadFile(hObject, &ntHeaders32, sizeof ntHeaders32, &nRead, NULL); _ReadFile(hObject, &ntHeaders32, sizeof ntHeaders32, &nRead, NULL);
if (nRead != sizeof ntHeaders32) { 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; return 0;
} }
if (ntHeaders32.Signature != IMAGE_NT_SIGNATURE) { 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; return 0;
} }
@ -53,7 +55,7 @@ void apply_patches(HMODULE hModule) {
DWORD imageBase = GetImageBase(); DWORD imageBase = GetImageBase();
if (imageBase == 0) { 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; return;
} }
imageOffset = (DWORD)hModule - imageBase; imageOffset = (DWORD)hModule - imageBase;
@ -62,13 +64,13 @@ void apply_patches(HMODULE hModule) {
WideCharToMultiByte(CP_ACP, 0, exeName, -1, exeNameC, sizeof exeNameC, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, exeName, -1, exeNameC, sizeof exeNameC, NULL, NULL);
if (!load_patches(MiceConfig.mice.patches_file, exeNameC)) { 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; return;
} }
patch_t* patch = patch_list->next; patch_t* patch = patch_list->next;
if (patch == NULL) { 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) { while (patch) {
DWORD oldProt; DWORD oldProt;
@ -76,7 +78,7 @@ void apply_patches(HMODULE hModule) {
PAGE_EXECUTE_READWRITE, &oldProt); PAGE_EXECUTE_READWRITE, &oldProt);
if (memcmp(patch->match, (void*)((DWORD)patch->address + imageOffset), patch->count) != 0) { 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, VirtualProtect((void*)((DWORD)patch->address + imageOffset), patch->count, oldProt,
&oldProt); &oldProt);
patch = patch->next; patch = patch->next;
@ -84,7 +86,7 @@ void apply_patches(HMODULE hModule) {
} }
memcpy((void*)((DWORD)patch->address + imageOffset), patch->replace, patch->count); 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->name);
patch = patch->next; patch = patch->next;
@ -93,10 +95,11 @@ void apply_patches(HMODULE hModule) {
void prebind_hooks() { void prebind_hooks() {
hook_all(); hook_all();
init_com_devices();
install_devices(); install_devices();
// TODO: Figure out why we're needing to call this manually (medium priority) // TODO: Figure out why we're needing to call this manually (medium priority)
if (wcscmp(exeName, L"ALLNetProc.exe") == 0) { 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 // OPENSSL_add_all_algorithms_noconf
((void (*)(void))(0x00459770))(); ((void (*)(void))(0x00459770))();
@ -111,7 +114,7 @@ void init_injection(HMODULE hModule) {
// We're in a new context now, so need to reconfigure // We're in a new context now, so need to reconfigure
setup_logging(); 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); if (MiceConfig.mice.apply_patches) apply_patches(hModule);
@ -132,7 +135,7 @@ void init_injection(HMODULE hModule) {
if (MiceConfig.drivers.platform) { if (MiceConfig.drivers.platform) {
if (!add_fake_device(&PLATFORM_GUID, L"\\\\.\\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, ...) { void tea_hook_test(char* fmt, ...) {
va_list argp; va_list argp;
va_start(argp, fmt); va_start(argp, fmt);
vlog_game("tea", fmt, argp); vlog_game(plfTea, fmt, argp);
va_end(argp); va_end(argp);
} }
int mxkMain(); 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) { 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) { 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(); spawn_pcp_processes();
// if (wcscmp(exeName, L"RingGame.exe") == 0) { // 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); // 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) { LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
switch (dwIoControlCode) { switch (dwIoControlCode) {
case IOCTL_COLUMBA_READ: 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); lpInBuffer, nInBufferSize, nOutBufferSize);
AM_COLUMBA_REQUEST* request = (AM_COLUMBA_REQUEST*)lpInBuffer; 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 == 1 ? "byte"
: request->m_elementSize == 2 ? "short" : request->m_elementSize == 2 ? "short"
: request->m_elementSize == 4 ? "long" : 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); memcpy(lpOutBuffer, dmi_table, dmi_size);
if (lpBytesReturned) *lpBytesReturned = 0x10000; if (lpBytesReturned) *lpBytesReturned = 0x10000;
} else { } else {
log_error("columba", "Request to unmapped memory location: %08x", log_error(plfColumba, "Request to unmapped memory location: %08x",
request->m_physAddr); request->m_physAddr);
return FALSE; return FALSE;
} }
@ -49,7 +49,7 @@ BOOL WINAPI columba_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode,
break; break;
default: default:
// Observed: IOCTL_KSEC_RNG_REKEY // Observed: IOCTL_KSEC_RNG_REKEY
log_warning("columba", "unhandled 0x%08x", dwIoControlCode); log_warning(plfColumba, "unhandled 0x%08x", dwIoControlCode);
return FALSE; return FALSE;
} }

View File

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

View File

@ -113,7 +113,7 @@ unsigned char jvs_exchange(jvs_board_t* board, unsigned char* inData, short inCo
unsigned char cmd; unsigned char cmd;
jvs_read(cmd); jvs_read(cmd);
// log_info("mxjvs", "CMD: %02x", cmd); // log_info(plfMxJvs, "CMD: %02x", cmd);
switch (cmd) { switch (cmd) {
case JVS_CMD_RESET: 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 (i == 0) {
if (!!(gpio_value & 0x80) != coin_solenoid) { if (!!(gpio_value & 0x80) != coin_solenoid) {
coin_solenoid = !!(gpio_value & 0x80); coin_solenoid = !!(gpio_value & 0x80);
log_info("mxjvs", "Coin solenoid: %s", log_info(plfMxJvs, "Coin solenoid: %s",
coin_solenoid ? "Locked" : "Unlocked"); 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; break;
@ -266,7 +266,7 @@ unsigned char jvs_exchange(jvs_board_t* board, unsigned char* inData, short inCo
break; break;
default: default:
log_error("mxjvs", "Unknown command: 0x%02x", cmd); log_error(plfMxJvs, "Unknown command: 0x%02x", cmd);
return JVS_STATUS_UKCOM; 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 // JVS frame is 4 bytes in total
if (inCount < 4) { 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); jvs_send_status(JVS_STATUS_UNKNOWN, outData, outCount);
free(inData); free(inData);
return; return;
} }
// This isn't a JVS packet // This isn't a JVS packet
if (inData[0] != JVS_SYNC) { 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); jvs_send_status(JVS_STATUS_UNKNOWN, outData, outCount);
free(inData); free(inData);
return; return;
@ -322,7 +322,7 @@ void mxjvs_handle(unsigned char* paddedIn, short inCount, unsigned char* outData
bool escape = false; bool escape = false;
for (int i = 1; i < inCount - 1; i++) sum += inData[i]; for (int i = 1; i < inCount - 1; i++) sum += inData[i];
if (sum != inData[inCount - 1]) { 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]); inData[inCount - 1]);
jvs_send_status(JVS_STATUS_SUM, outData, outCount); jvs_send_status(JVS_STATUS_SUM, outData, outCount);
return; return;
@ -334,8 +334,8 @@ void mxjvs_handle(unsigned char* paddedIn, short inCount, unsigned char* outData
return; return;
unsigned char* response = malloc(maxOut); unsigned char* response = malloc(maxOut);
unsigned char packetSize; unsigned char packetSize = 0;
unsigned char status; unsigned char status = JVS_STATUS_UNKNOWN;
if (destination == 0xff) { if (destination == 0xff) {
for (int i = 0; i < MiceConfig.keys.board_count; i++) { for (int i = 0; i < MiceConfig.keys.board_count; i++) {
jvs_board_t* board = &jvs_boards[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); free(response);
} else { } 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); free(response);
jvs_send_status(status, outData, outCount); 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) { LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
switch (dwIoControlCode) { switch (dwIoControlCode) {
case IOCTL_MXJVS_EXCHANGE: case IOCTL_MXJVS_EXCHANGE:
log_trace("mxjvs", log_trace(plfMxJvs,
"DeviceIoControl(<mxjvs>, <exchange>, 0x%p, 0x%x, -, " "DeviceIoControl(<mxjvs>, <exchange>, 0x%p, 0x%x, -, "
"0x%x, -, -)", "0x%x, -, -)",
lpInBuffer, nInBufferSize, nOutBufferSize); lpInBuffer, nInBufferSize, nOutBufferSize);
@ -386,7 +386,7 @@ BOOL WINAPI mxjvs_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LP
break; break;
default: default:
log_warning("mxjvs", "unhandled 0x%08x", dwIoControlCode); log_warning(plfMxJvs, "unhandled 0x%08x", dwIoControlCode);
return FALSE; return FALSE;
} }
@ -406,7 +406,7 @@ BOOL mxjvs_GetCommModemStatus(void* com, LPDWORD lpModelStat) {
BOOL mxjvs_SetCommState(void* com, LPDCB lpDCB) { BOOL mxjvs_SetCommState(void* com, LPDCB lpDCB) {
char PARITY[] = { 'N', 'O', 'E', 'M', 'S' }; char PARITY[] = { 'N', 'O', 'E', 'M', 'S' };
char* STOP[] = { "1", "1.5", "2" }; 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]); PARITY[lpDCB->Parity], STOP[lpDCB->StopBits]);
return TRUE; 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, BOOL WINAPI mxparallel_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOID lpInBuffer,
DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize,
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) { 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); dwIoControlCode, lpInBuffer, nInBufferSize, nOutBufferSize);
switch (dwIoControlCode) { switch (dwIoControlCode) {
@ -68,7 +68,7 @@ BOOL WINAPI mxparallel_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCod
return TRUE; return TRUE;
case IOCTL_MXPARALLEL_WRITE_CTRL_PORT: case IOCTL_MXPARALLEL_WRITE_CTRL_PORT:
parallel_ctrl = ((LPBYTE)lpInBuffer)[0]; parallel_ctrl = ((LPBYTE)lpInBuffer)[0];
// log_warning("mxparallel", "Write ctrl %08x", parallel_ctrl); // log_warning(plfMxParallel, "Write ctrl %08x", parallel_ctrl);
outLen(0); outLen(0);
return TRUE; return TRUE;
@ -231,37 +231,37 @@ void mxparallel_process_packet(BYTE* request) {
switch (request[0]) { switch (request[0]) {
// We're pretending to be the keychip, so S and R are swapped for us! // We're pretending to be the keychip, so S and R are swapped for us!
case SetKeyS: case SetKeyS:
log_info("mxparallel", "SetKeyS"); log_info(plfMxParallel, "SetKeyS");
micexkRecvPacket(request); micexkRecvPacket(request);
mxkSetKeyR(request); mxkSetKeyR(request);
micexkSendPacket(response); micexkSendPacket(response);
break; break;
case SetKeyR: case SetKeyR:
log_info("mxparallel", "SetKeyR"); log_info(plfMxParallel, "SetKeyR");
micexkRecvPacket(request); micexkRecvPacket(request);
mxkSetKeyS(request); mxkSetKeyS(request);
micexkSendPacket(response); micexkSendPacket(response);
break; break;
case Encrypt: case Encrypt:
log_info("mxparallel", "Encrypt"); log_info(plfMxParallel, "Encrypt");
micexkRecvPacket(request); micexkRecvPacket(request);
micexkSendPacket(request); micexkSendPacket(request);
break; break;
case Decrypt: case Decrypt:
log_info("mxparallel", "Decrypt"); log_info(plfMxParallel, "Decrypt");
micexkRecvPacket(request); micexkRecvPacket(request);
micexkSendPacket(request); micexkSendPacket(request);
break; break;
case SetIV: case SetIV:
log_info("mxparallel", "SetIV"); log_info(plfMxParallel, "SetIV");
ZeroMemory(kc_aes_iv, sizeof kc_aes_iv); ZeroMemory(kc_aes_iv, sizeof kc_aes_iv);
micexkSendPacket(response); micexkSendPacket(response);
break; break;
case GetAppBootInfo: case GetAppBootInfo:
log_info("mxparallel", "GetAppBootInfo"); log_info(plfMxParallel, "GetAppBootInfo");
if (request[1] != 0x00) { 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); APPBOOT.crc = amiCrc32RCalc(sizeof APPBOOT - 4, (unsigned char*)&APPBOOT + 4, 0);
@ -271,7 +271,7 @@ void mxparallel_process_packet(BYTE* request) {
break; break;
case KcGetVersion: case KcGetVersion:
log_info("mxparallel", "GetVersion"); log_info(plfMxParallel, "GetVersion");
response[0] = 0x01; response[0] = 0x01;
response[1] = 0x04; response[1] = 0x04;
micexkSendPacket(response); micexkSendPacket(response);
@ -280,18 +280,18 @@ void mxparallel_process_packet(BYTE* request) {
case FlashRead: { case FlashRead: {
uint32_t addr = request[1] | (request[2] << 8) | (request[3] << 16); uint32_t addr = request[1] | (request[2] << 8) | (request[3] << 16);
uint32_t nbytes = request[4] | (request[5] << 8) | (request[6] << 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) if (addr + nbytes <= sizeof flash)
micexkTransportSend(&flash[addr], nbytes); micexkTransportSend(&flash[addr], nbytes);
else else
log_error("mxparallel", "Flash read would exceed storage!"); log_error(plfMxParallel, "Flash read would exceed storage!");
break; break;
} }
case FlashErase: { case FlashErase: {
uint32_t addr = request[1] | (request[2] << 8) | (request[3] << 16); 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); micexkSendPacket(response);
break; break;
@ -299,12 +299,12 @@ void mxparallel_process_packet(BYTE* request) {
case FlashWrite: { case FlashWrite: {
uint32_t addr = request[1] | (request[2] << 8) | (request[3] << 16); uint32_t addr = request[1] | (request[2] << 8) | (request[3] << 16);
uint32_t nbytes = request[4] | (request[5] << 8) | (request[6] << 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) if (addr + nbytes <= sizeof flash)
micexkTransportRecv(&flash[addr], nbytes); micexkTransportRecv(&flash[addr], nbytes);
else else
log_error("mxparallel", "Flash write would exceed storage!"); log_error(plfMxParallel, "Flash write would exceed storage!");
micexkSendPacket(response); micexkSendPacket(response);
dump_nv_storage(); dump_nv_storage();
@ -315,12 +315,12 @@ void mxparallel_process_packet(BYTE* request) {
case EepromWrite: { case EepromWrite: {
// TODO: What is this? Appears to be some sort of EEPROM write // TODO: What is this? Appears to be some sort of EEPROM write
uint8_t offset = request[1]; uint8_t offset = request[1];
log_info("mxparallel", "EepromWrite: %02x", offset); log_info(plfMxParallel, "EepromWrite: %02x", offset);
if (offset * 16 + 16 <= sizeof eeprom) { if (offset * 16 + 16 <= sizeof eeprom) {
micexkRecvPacket(&eeprom[offset * 16]); micexkRecvPacket(&eeprom[offset * 16]);
} else { } else {
log_error("mxparallel", "EEPROM write would exceed storage!"); log_error(plfMxParallel, "EEPROM write would exceed storage!");
} }
micexkSendPacket(response); micexkSendPacket(response);
dump_nv_storage(); dump_nv_storage();
@ -329,12 +329,12 @@ void mxparallel_process_packet(BYTE* request) {
case EepromRead: { case EepromRead: {
// TODO: What is this? Appears to be some sort of EEPROM read // TODO: What is this? Appears to be some sort of EEPROM read
uint8_t offset = request[1]; uint8_t offset = request[1];
log_info("mxparallel", "EepromRead: %02x", offset); log_info(plfMxParallel, "EepromRead: %02x", offset);
if (offset * 16 + 16 <= sizeof eeprom) { if (offset * 16 + 16 <= sizeof eeprom) {
micexkSendPacket(&eeprom[offset * 16]); micexkSendPacket(&eeprom[offset * 16]);
} else { } else {
log_error("mxparallel", "EEPROM read would exceed storage!"); log_error(plfMxParallel, "EEPROM read would exceed storage!");
} }
break; break;
} }
@ -344,7 +344,7 @@ void mxparallel_process_packet(BYTE* request) {
// TODO: What is this? Appears to be some sort of memory write // TODO: What is this? Appears to be some sort of memory write
uint16_t addr = request[1] | (request[2] << 8); uint16_t addr = request[1] | (request[2] << 8);
uint8_t blocks = request[3]; 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) { if (addr + blocks * 16 <= sizeof nvram) {
for (byte i = 0; i < blocks; i++) { for (byte i = 0; i < blocks; i++) {
@ -352,7 +352,7 @@ void mxparallel_process_packet(BYTE* request) {
} }
micexkSendPacket(response); micexkSendPacket(response);
} else { } else {
log_error("mxparallel", "NVRAM write would exceed storage!"); log_error(plfMxParallel, "NVRAM write would exceed storage!");
} }
dump_nv_storage(); dump_nv_storage();
break; break;
@ -361,26 +361,26 @@ void mxparallel_process_packet(BYTE* request) {
// TODO: What is this? Appears to be some sort of memory read // TODO: What is this? Appears to be some sort of memory read
uint16_t addr = request[1] | (request[2] << 8); uint16_t addr = request[1] | (request[2] << 8);
uint8_t blocks = request[3]; 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) { if (addr + blocks * 16 <= sizeof nvram) {
for (byte i = 0; i < blocks; i++) { for (byte i = 0; i < blocks; i++) {
micexkSendPacket(&(nvram[addr + (i * 16)])); micexkSendPacket(&(nvram[addr + (i * 16)]));
} }
} else { } else {
log_error("mxparallel", "NVRAM read would exceed storage!"); log_error(plfMxParallel, "NVRAM read would exceed storage!");
} }
break; break;
} }
case AddPlayCount: case AddPlayCount:
log_info("mxparallel", "AddPlayCount"); log_info(plfMxParallel, "AddPlayCount");
BILLING_PLAYCOUNT++; BILLING_PLAYCOUNT++;
micexkSendPacket(response); micexkSendPacket(response);
break; break;
case SetMainId: case SetMainId:
log_info("mxparallel", "SetMainId"); log_info(plfMxParallel, "SetMainId");
// micexkRecvPacket(_MAIN_ID); // micexkRecvPacket(_MAIN_ID);
micexkRecvPacket(request); micexkRecvPacket(request);
@ -388,27 +388,27 @@ void mxparallel_process_packet(BYTE* request) {
micexkSendPacket(response); micexkSendPacket(response);
break; break;
case GetMainId: case GetMainId:
log_info("mxparallel", "GetMainId"); log_info(plfMxParallel, "GetMainId");
micexkSendPacket(_MAIN_ID); micexkSendPacket(_MAIN_ID);
break; break;
case SetKeyId: case SetKeyId:
log_info("mxparallel", "SetKeyId"); log_info(plfMxParallel, "SetKeyId");
micexkRecvPacket(KEYCHIP_ID); micexkRecvPacket(KEYCHIP_ID);
micexkSendPacket(response); micexkSendPacket(response);
break; break;
case GetKeyId: case GetKeyId:
log_info("mxparallel", "GetKeyId"); log_info(plfMxParallel, "GetKeyId");
micexkSendPacket(KEYCHIP_ID); micexkSendPacket(KEYCHIP_ID);
break; break;
case GetPlayCounter: case GetPlayCounter:
log_info("mxparallel", "GetPlayCounter"); log_info(plfMxParallel, "GetPlayCounter");
((uint32_t*)response)[0] = BILLING_PLAYCOUNT; ((uint32_t*)response)[0] = BILLING_PLAYCOUNT;
micexkSendPacket(response); micexkSendPacket(response);
break; break;
default: default:
log_error("mxparallel", "Unhandled opcode: %d", request[0]); log_error(plfMxParallel, "Unhandled opcode: %d", request[0]);
for (byte i = 0; i < 16; i++) { for (byte i = 0; i < 16; i++) {
printf("%02x ", request[i]); printf("%02x ", request[i]);
} }
@ -419,7 +419,7 @@ void mxparallel_process_packet(BYTE* request) {
} }
DWORD WINAPI mxparallel_thread(LPVOID _) { DWORD WINAPI mxparallel_thread(LPVOID _) {
log_info("mxparallel", "Parallel device thread spawned"); log_info(plfMxParallel, "Parallel device thread spawned");
clearBusy; clearBusy;
clearAck; clearAck;

View File

@ -55,12 +55,12 @@ BOOL handle_smbus(BYTE command, WORD v_addr, WORD command_code, BYTE nbytes, BYT
break; 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); v_addr, command, smb_cmd, command_code);
smbus_callback_t* callback = smbus_devices[p_addr]; smbus_callback_t* callback = smbus_devices[p_addr];
if (callback == NULL) { 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 FALSE;
} }
return (*callback)(smb_cmd, command_code, nbytes, data); return (*callback)(smb_cmd, command_code, nbytes, data);
@ -74,7 +74,7 @@ BOOL WINAPI mxsmbus_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode,
switch (dwIoControlCode) { switch (dwIoControlCode) {
case IOCTL_MXSMBUS_GET_VERSION: case IOCTL_MXSMBUS_GET_VERSION:
log_misc("mxsmbus", log_misc(plfMxSmbus,
"DeviceIoControl(<mxsmbus>, <get version>, 0x%p, 0x%x, " "DeviceIoControl(<mxsmbus>, <get version>, 0x%p, 0x%x, "
"-, 0x%x, -, -)", "-, 0x%x, -, -)",
lpInBuffer, nInBufferSize, nOutBufferSize); lpInBuffer, nInBufferSize, nOutBufferSize);
@ -115,7 +115,7 @@ BOOL WINAPI mxsmbus_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode,
}; };
} }
default: default:
log_warning("mxsmbus", "unhandled 0x%08x", dwIoControlCode); log_warning(plfMxSmbus, "unhandled 0x%08x", dwIoControlCode);
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
@ -128,6 +128,6 @@ void setup_mxsmbus() {
hook_file(mxsmbus); hook_file(mxsmbus);
if (!add_fake_device(&MXSMBUS_GUID, L"\\\\.\\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 "../../maiBackupStructs.h"
#include "mx.h" #include "mx.h"
#define SRAM_DUMP L"dev/sram.bin" #define SRAM_PATH L"dev/sram.bin"
#define SRAM_SIZE 1024 * 2084 #define SRAM_SIZE 1024 * 2084
LPBYTE SRAM; LPBYTE SRAM_DATA = NULL;
HANDLE SRAM_FILE = INVALID_HANDLE_VALUE;
void sram_dump() { HANDLE SRAM_FILE_MAPPING = INVALID_HANDLE_VALUE;
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);
}
#define ADDR_BACKUP 0x0000 #define ADDR_BACKUP 0x0000
#define ADDR_HM_PEAK 0x0200 #define ADDR_HM_PEAK 0x0200
@ -33,43 +14,53 @@ void sram_restore() {
#define ADDR_ERROR_LOG 0x0600 #define ADDR_ERROR_LOG 0x0600
#define ADDR_DUP 0x1000 #define ADDR_DUP 0x1000
#define fix_crc(block) \ #define fix_crc(block) \
do { \ do { \
(block).m_Crc = amiCrc32RCalc(sizeof(block) - 4, (BYTE*)(&(block)) + 4, 0); \ (block).m_Crc = amiCrc32RCalc(sizeof(block) - 4, (BYTE*)(&(block)) + 4, 0); \
} while (0) } while (0)
int build_sram() { int build_sram() {
static BOOL built = false; log_info(plfMxSram, "Building default SRAM file");
if (built) return 0;
built = true;
log_info("mxsram", "Building default SRAM file"); memset(SRAM_DATA, 0xff, SRAM_SIZE);
AM_SYSDATAwH_BACKUP Backup = { 0 }; AM_SYSDATAwH_BACKUP Backup = { 0 };
fix_crc(Backup); fix_crc(Backup);
memcpy(SRAM + ADDR_BACKUP, (unsigned char*)&Backup, sizeof Backup); memcpy(SRAM_DATA + ADDR_BACKUP, (unsigned char*)&Backup, sizeof Backup);
memcpy(SRAM + ADDR_BACKUP + ADDR_DUP, (unsigned char*)&Backup, sizeof Backup); memcpy(SRAM_DATA + ADDR_BACKUP + ADDR_DUP, (unsigned char*)&Backup, sizeof Backup);
AM_SYSDATAwH_HM_PEAK HmPeak = { 0 }; AM_SYSDATAwH_HM_PEAK HmPeak = { 0 };
fix_crc(HmPeak); fix_crc(HmPeak);
memcpy(SRAM + ADDR_HM_PEAK, (unsigned char*)&HmPeak, sizeof HmPeak); memcpy(SRAM_DATA + 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 + ADDR_DUP, (unsigned char*)&HmPeak, sizeof HmPeak);
AM_SYSDATAwH_TIMEZONE Timezone = { 0 }; AM_SYSDATAwH_TIMEZONE Timezone = { 0 };
fix_crc(Timezone); fix_crc(Timezone);
memcpy(SRAM + ADDR_TIMEZONE, (unsigned char*)&Timezone, sizeof Timezone); memcpy(SRAM_DATA + ADDR_TIMEZONE, (unsigned char*)&Timezone, sizeof Timezone);
memcpy(SRAM + ADDR_TIMEZONE + ADDR_DUP, (unsigned char*)&Timezone, sizeof Timezone); memcpy(SRAM_DATA + ADDR_TIMEZONE + ADDR_DUP, (unsigned char*)&Timezone, sizeof Timezone);
AM_SYSDATAwH_ERROR_LOG ErrorLog = { 0 }; AM_SYSDATAwH_ERROR_LOG ErrorLog = { 0 };
fix_crc(ErrorLog); fix_crc(ErrorLog);
memcpy(SRAM + ADDR_ERROR_LOG, (unsigned char*)&ErrorLog, sizeof ErrorLog); memcpy(SRAM_DATA + ADDR_ERROR_LOG, (unsigned char*)&ErrorLog, sizeof ErrorLog);
memcpy(SRAM + ADDR_ERROR_LOG + ADDR_DUP, (unsigned char*)&ErrorLog, sizeof ErrorLog); memcpy(SRAM_DATA + ADDR_ERROR_LOG + ADDR_DUP, (unsigned char*)&ErrorLog, sizeof ErrorLog);
sram_dump();
return 1; 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, BOOL WINAPI mxsram_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOID lpInBuffer,
DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize,
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) { LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
@ -78,7 +69,7 @@ BOOL WINAPI mxsram_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
switch (dwIoControlCode) { switch (dwIoControlCode) {
case IOCTL_MXSRAM_PING: // Get version case IOCTL_MXSRAM_PING: // Get version
log_info("mxsram", log_info(plfMxSram,
"DeviceIoControl(<mxsram>, <ping>, 0x%p, 0x%x, -, 0x%x, " "DeviceIoControl(<mxsram>, <ping>, 0x%p, 0x%x, -, 0x%x, "
"-, -)", "-, -)",
lpInBuffer, nInBufferSize, nOutBufferSize); lpInBuffer, nInBufferSize, nOutBufferSize);
@ -87,7 +78,7 @@ BOOL WINAPI mxsram_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
if (lpBytesReturned) *lpBytesReturned = 4; if (lpBytesReturned) *lpBytesReturned = 4;
break; break;
case IOCTL_DISK_GET_DRIVE_GEOMETRY: case IOCTL_DISK_GET_DRIVE_GEOMETRY:
log_info("mxsram", log_info(plfMxSram,
"DeviceIoControl(<mxsram>, <get drive geom>, 0x%p, " "DeviceIoControl(<mxsram>, <get drive geom>, 0x%p, "
"0x%x, -, 0x%x, -, -)", "0x%x, -, 0x%x, -, -)",
lpInBuffer, nInBufferSize, nOutBufferSize); lpInBuffer, nInBufferSize, nOutBufferSize);
@ -102,10 +93,10 @@ BOOL WINAPI mxsram_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
if (lpBytesReturned) *lpBytesReturned = sizeof(DISK_GEOMETRY); if (lpBytesReturned) *lpBytesReturned = sizeof(DISK_GEOMETRY);
break; break;
case IOCTL_DISK_GET_LENGTH_INFO: 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; return FALSE;
case IOCTL_MXSRAM_GET_SECTOR_SIZE: case IOCTL_MXSRAM_GET_SECTOR_SIZE:
log_info("mxsram", log_info(plfMxSram,
"DeviceIoControl(<mxsram>, <get sector size>, 0x%p, " "DeviceIoControl(<mxsram>, <get sector size>, 0x%p, "
"0x%x, -, 0x%x, -, -)", "0x%x, -, 0x%x, -, -)",
lpInBuffer, nInBufferSize, nOutBufferSize); lpInBuffer, nInBufferSize, nOutBufferSize);
@ -114,7 +105,7 @@ BOOL WINAPI mxsram_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
if (lpBytesReturned) *lpBytesReturned = 4; if (lpBytesReturned) *lpBytesReturned = 4;
break; break;
default: default:
log_warning("mxsram", "unhandled 0x%08x", dwIoControlCode); log_warning(plfMxSram, "unhandled 0x%08x", dwIoControlCode);
return FALSE; 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, BOOL mxsram_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped) { 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); ctx->m_Pointer.LowPart);
if (ctx->m_Pointer.LowPart + nNumberOfBytesToWrite >= SRAM_SIZE) { if (ctx->m_Pointer.LowPart + nNumberOfBytesToWrite >= SRAM_SIZE) {
nNumberOfBytesToWrite = SRAM_SIZE - ctx->m_Pointer.LowPart; nNumberOfBytesToWrite = SRAM_SIZE - ctx->m_Pointer.LowPart;
} }
memcpy(SRAM + ctx->m_Pointer.LowPart, lpBuffer, nNumberOfBytesToWrite); ensure_valid_sram();
sram_dump(); memcpy(SRAM_DATA + ctx->m_Pointer.LowPart, lpBuffer, nNumberOfBytesToWrite);
*lpNumberOfBytesWritten = nNumberOfBytesToWrite; *lpNumberOfBytesWritten = nNumberOfBytesToWrite;
return TRUE; return TRUE;
} }
BOOL mxsram_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, BOOL mxsram_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) { 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); ctx->m_Pointer.LowPart);
if (ctx->m_Pointer.LowPart + nNumberOfBytesToRead >= SRAM_SIZE) { if (ctx->m_Pointer.LowPart + nNumberOfBytesToRead >= SRAM_SIZE) {
nNumberOfBytesToRead = SRAM_SIZE - ctx->m_Pointer.LowPart; nNumberOfBytesToRead = SRAM_SIZE - ctx->m_Pointer.LowPart;
} }
sram_restore(); ensure_valid_sram();
memcpy((LPVOID)lpBuffer, SRAM + ctx->m_Pointer.LowPart, nNumberOfBytesToRead); memcpy((LPVOID)lpBuffer, SRAM_DATA + ctx->m_Pointer.LowPart, nNumberOfBytesToRead);
*lpNumberOfBytesRead = nNumberOfBytesToRead; *lpNumberOfBytesRead = nNumberOfBytesToRead;
return TRUE; return TRUE;
} }
void setup_mxsram() { 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"); file_hook_t* mxsram = new_file_hook(L"\\\\.\\mxsram");
mxsram->DeviceIoControl = &mxsram_DeviceIoControl; mxsram->DeviceIoControl = &mxsram_DeviceIoControl;
mxsram->ReadFile = &mxsram_ReadFile; mxsram->ReadFile = &mxsram_ReadFile;

View File

@ -96,7 +96,7 @@ BYTE hwmon_read(superio_packet* packet) {
return w83791d_vbat_monitor_control; return w83791d_vbat_monitor_control;
default: 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; return 0xff;
} }
} break; } break;
@ -124,7 +124,7 @@ BYTE hwmon_read(superio_packet* packet) {
return W83791D_ENTITY_SYSTEM; return W83791D_ENTITY_SYSTEM;
default: default:
log_error("mxsuperio", "Unknown HM b1 register: 0x%02x", reg); log_error(plfMxSuperio, "Unknown HM b1 register: 0x%02x", reg);
exit(1); exit(1);
} }
} break; } break;
@ -140,12 +140,12 @@ BYTE hwmon_read(superio_packet* packet) {
return 0xff; return 0xff;
default: default:
log_error("mxsuperio", "Unknown HM b5 register: 0x%02x", reg); log_error(plfMxSuperio, "Unknown HM b5 register: 0x%02x", reg);
return 0xff; return 0xff;
} }
} break; } break;
default: default:
log_error("mxsuperio", "Unknown HM bank: 0x%02x", w83791d_bank); log_error(plfMxSuperio, "Unknown HM bank: 0x%02x", w83791d_bank);
exit(1); exit(1);
} }
} }
@ -197,7 +197,7 @@ void hwmon_write(superio_packet* packet) {
w83791d_vbat_monitor_control = packet->data; w83791d_vbat_monitor_control = packet->data;
break; break;
default: 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); // exit(1);
} }
break; break;
@ -229,7 +229,7 @@ void hwmon_write(superio_packet* packet) {
break; break;
default: 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); exit(1);
} }
} break; } break;
@ -246,12 +246,12 @@ void hwmon_write(superio_packet* packet) {
break; break;
default: default:
log_error("mxsuperio", "Unknown HM b5 register: 0x%02x", packet->reg); log_error(plfMxSuperio, "Unknown HM b5 register: 0x%02x", packet->reg);
return; return;
} }
} break; } break;
default: default:
log_error("mxsuperio", "Unknown HM bank: 0x%02x", w83791d_bank); log_error(plfMxSuperio, "Unknown HM bank: 0x%02x", w83791d_bank);
exit(1); exit(1);
} }
} }
@ -291,7 +291,7 @@ BOOL WINAPI mxsuperio_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode
// //
} }
W83627UHG_processed: 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); packet->device, packet->reg, packet->data);
break; break;
} }
@ -299,7 +299,7 @@ BOOL WINAPI mxsuperio_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode
superio_lpc_packet* packet = (superio_lpc_packet*)(lpInBuffer); superio_lpc_packet* packet = (superio_lpc_packet*)(lpInBuffer);
if (lpBytesReturned) *lpBytesReturned = sizeof *packet; 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); packet->device, packet->reg, packet->data);
// TODO: Are there any writes we need to process? // TODO: Are there any writes we need to process?
@ -319,13 +319,13 @@ BOOL WINAPI mxsuperio_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode
} else { } else {
lpc_out->data = 0xff; 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); lpc_packet->index, lpc_packet->reg, lpc_out->data);
if (lpBytesReturned) *lpBytesReturned = sizeof *lpc_out; if (lpBytesReturned) *lpBytesReturned = sizeof *lpc_out;
} break; } break;
case IOCTL_MXSUPERIO_HWMONITOR_LPC_WRITE: { 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); lpc_packet->index, lpc_packet->reg, lpc_packet->data);
if (lpc_packet->index == LPC_CONFIGURATION) { if (lpc_packet->index == LPC_CONFIGURATION) {
@ -334,7 +334,7 @@ BOOL WINAPI mxsuperio_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode
if (lpBytesReturned) *lpBytesReturned = 0; if (lpBytesReturned) *lpBytesReturned = 0;
} break; } break;
default: default:
log_warning("mxsuperio", "unhandled 0x%08x", dwIoControlCode); log_warning(plfMxSuperio, "unhandled 0x%08x", dwIoControlCode);
return FALSE; 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; if (igIsKeyPressed_Bool(open_key, false)) editor.Open = !editor.Open;
// TODO: Less hacky :) // TODO: Less hacky :)
extern LPBYTE SRAM; extern LPBYTE SRAM_DATA;
if (editor.Open) MemoryEditor_DrawWindow(&editor, "SRAM Editor", SRAM, 1024 * 1024, 0x0000); if (editor.Open)
MemoryEditor_DrawWindow(&editor, "SRAM Editor", SRAM_DATA, 1024 * 1024, 0x0000);
} }
void igHelpMarker(const char* text) { void igHelpMarker(const char* text) {
@ -733,6 +734,7 @@ void AddSettingButton(int board, int id) {
if (igKeyBindPopup(name, &boundKey)) { if (igKeyBindPopup(name, &boundKey)) {
if (boundKey != -1) { if (boundKey != -1) {
jvsKeybindings[board].buttons[id * 2 + (currentlyBinding - 1)] = boundKey; jvsKeybindings[board].buttons[id * 2 + (currentlyBinding - 1)] = boundKey;
jvsKeybindings[board].notdefault = 1;
save_current_config(); save_current_config();
} }
currentlyBinding = 0; currentlyBinding = 0;
@ -890,7 +892,7 @@ void tab_main_keybinds() {
} }
void hud_control(ImGuiKey open_key) { void hud_control(ImGuiKey open_key) {
static bool isOpen = true; static bool isOpen = false;
static bool oldCursor; static bool oldCursor;
if (igIsKeyPressed_Bool(open_key, false)) { if (igIsKeyPressed_Bool(open_key, false)) {
isOpen = !isOpen; isOpen = !isOpen;
@ -938,7 +940,6 @@ void hud_control(ImGuiKey open_key) {
} }
void __stdcall hud_gui(unsigned int hookType, IDirect3DDevice9* dev) { void __stdcall hud_gui(unsigned int hookType, IDirect3DDevice9* dev) {
static bool showMenu = false;
ShowCursor(1); ShowCursor(1);
static bool initialized = false; 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) { BOOL WINAPI FakeGetCommState(HANDLE hFile, LPDCB lpDCB) {
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); 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); if (pHData == NULL || pHData->hook->com_hook == NULL) return TrueGetCommState(hFile, lpDCB);
com_hook_t* com_hook = pHData->hook->com_hook; com_hook_t* com_hook = pHData->hook->com_hook;
if (com_hook->GetCommState == NULL) { 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 FALSE;
} }
return com_hook->GetCommState(hFile, lpDCB); return com_hook->GetCommState(hFile, lpDCB);
} }
BOOL WINAPI FakeSetCommState(HANDLE hFile, LPDCB 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); open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
if (pHData == NULL || pHData->hook->com_hook == NULL) return TrueSetCommState(hFile, lpDCB); if (pHData == NULL || pHData->hook->com_hook == NULL) return TrueSetCommState(hFile, lpDCB);
com_hook_t* com_hook = pHData->hook->com_hook; com_hook_t* com_hook = pHData->hook->com_hook;
if (com_hook->SetCommState == NULL) { 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 FALSE;
} }
return com_hook->SetCommState(hFile, lpDCB); return com_hook->SetCommState(hFile, lpDCB);
} }
BOOL WINAPI FakeGetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) { 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); open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
if (pHData == NULL || pHData->hook->com_hook == NULL) 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; com_hook_t* com_hook = pHData->hook->com_hook;
if (com_hook->GetCommTimeouts == NULL) { 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 FALSE;
} }
return com_hook->GetCommTimeouts(hFile, lpCommTimeouts); return com_hook->GetCommTimeouts(hFile, lpCommTimeouts);
} }
BOOL WINAPI FakeSetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS 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); open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
if (pHData == NULL || pHData->hook->com_hook == NULL) 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; com_hook_t* com_hook = pHData->hook->com_hook;
if (com_hook->SetCommTimeouts == NULL) { 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 FALSE;
} }
return com_hook->SetCommTimeouts(hFile, lpCommTimeouts); return com_hook->SetCommTimeouts(hFile, lpCommTimeouts);
} }
BOOL WINAPI FakeSetupComm(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue) { 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); open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
if (pHData == NULL || pHData->hook->com_hook == NULL) 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; com_hook_t* com_hook = pHData->hook->com_hook;
if (com_hook->SetupComm == NULL) { 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 FALSE;
} }
return com_hook->SetupComm(hFile, dwInQueue, dwOutQueue); return com_hook->SetupComm(hFile, dwInQueue, dwOutQueue);
} }
BOOL WINAPI FakePurgeComm(HANDLE hFile, DWORD dwFlags) { 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); open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
if (pHData == NULL || pHData->hook->com_hook == NULL) return TruePurgeComm(hFile, dwFlags); if (pHData == NULL || pHData->hook->com_hook == NULL) return TruePurgeComm(hFile, dwFlags);
com_hook_t* com_hook = pHData->hook->com_hook; com_hook_t* com_hook = pHData->hook->com_hook;
if (com_hook->PurgeComm == NULL) { 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 FALSE;
} }
return com_hook->PurgeComm(hFile, dwFlags); return com_hook->PurgeComm(hFile, dwFlags);
} }
BOOL WINAPI FakeGetCommModemStatus(HANDLE hFile, LPDWORD lpModelStat) { 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); open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
if (pHData == NULL || pHData->hook->com_hook == NULL) 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; com_hook_t* com_hook = pHData->hook->com_hook;
if (com_hook->GetCommModemStatus == NULL) { 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 FALSE;
} }
return com_hook->GetCommModemStatus(hFile, lpModelStat); return com_hook->GetCommModemStatus(hFile, lpModelStat);
} }
BOOL WINAPI FakeWaitCommEvent(HANDLE hFile, LPDWORD lpEvtMask, LPOVERLAPPED lpOverlapped) { 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); open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
if (pHData == NULL || pHData->hook->com_hook == NULL) 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; com_hook_t* com_hook = pHData->hook->com_hook;
if (com_hook->WaitCommEvent == NULL) { 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 FALSE;
} }
return com_hook->WaitCommEvent(hFile, lpEvtMask, lpOverlapped); return com_hook->WaitCommEvent(hFile, lpEvtMask, lpOverlapped);
} }
BOOL WINAPI FakeClearCommError(HANDLE hFile, LPDWORD lpErrors, LPCOMSTAT lpStat) { 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); open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
if (pHData == NULL || pHData->hook->com_hook == NULL) 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; com_hook_t* com_hook = pHData->hook->com_hook;
if (com_hook->ClearCommError == NULL) { 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 FALSE;
} }
return com_hook->ClearCommError(hFile, lpErrors, lpStat); return com_hook->ClearCommError(hFile, lpErrors, lpStat);

View File

@ -49,21 +49,21 @@ BOOL ReadFunc_Original0(DWORD nOffset, LPVOID lpBuffer, DWORD nNumberOfBytesToRe
LPDWORD lpNumberOfBytesRead) { LPDWORD lpNumberOfBytesRead) {
*lpNumberOfBytesRead = 0; *lpNumberOfBytesRead = 0;
if (!_PathFileExistsA(ORIGINAL0_PATH)) { 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; return FALSE;
} }
HANDLE hFile = HANDLE hFile =
_CreateFileA(ORIGINAL0_PATH, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); _CreateFileA(ORIGINAL0_PATH, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) { 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; return FALSE;
} }
LARGE_INTEGER seekTo; LARGE_INTEGER seekTo;
seekTo.QuadPart = (LONGLONG)nOffset * (LONGLONG)SSD.m_BlockSize; seekTo.QuadPart = (LONGLONG)nOffset * (LONGLONG)SSD.m_BlockSize;
_SetFilePointerEx(hFile, seekTo, NULL, FILE_BEGIN); _SetFilePointerEx(hFile, seekTo, NULL, FILE_BEGIN);
BOOL ret = _ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, NULL); 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); _CloseHandle(hFile);
return ret; return ret;
} }
@ -74,14 +74,14 @@ BOOL WriteFunc_Original0(DWORD nOffset, LPCVOID lpBuffer, DWORD nNumberOfBytesTo
HANDLE hFile = HANDLE hFile =
_CreateFileA(ORIGINAL0_PATH, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL); _CreateFileA(ORIGINAL0_PATH, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) { 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; return FALSE;
} }
LARGE_INTEGER seekTo; LARGE_INTEGER seekTo;
seekTo.QuadPart = (LONGLONG)nOffset * (LONGLONG)SSD.m_BlockSize; seekTo.QuadPart = (LONGLONG)nOffset * (LONGLONG)SSD.m_BlockSize;
_SetFilePointerEx(hFile, seekTo, NULL, FILE_BEGIN); _SetFilePointerEx(hFile, seekTo, NULL, FILE_BEGIN);
BOOL ret = _WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, NULL); 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); _CloseHandle(hFile);
return ret; return ret;
} }
@ -90,21 +90,21 @@ BOOL ReadFunc_Patch0(DWORD nOffset, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead) { LPDWORD lpNumberOfBytesRead) {
*lpNumberOfBytesRead = 0; *lpNumberOfBytesRead = 0;
if (!_PathFileExistsA(PATCH0_PATH)) { 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; return FALSE;
} }
HANDLE hFile = HANDLE hFile =
_CreateFileA(PATCH0_PATH, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); _CreateFileA(PATCH0_PATH, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) { 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; return FALSE;
} }
LARGE_INTEGER seekTo; LARGE_INTEGER seekTo;
seekTo.QuadPart = (LONGLONG)nOffset * (LONGLONG)SSD.m_BlockSize; seekTo.QuadPart = (LONGLONG)nOffset * (LONGLONG)SSD.m_BlockSize;
_SetFilePointerEx(hFile, seekTo, NULL, FILE_BEGIN); _SetFilePointerEx(hFile, seekTo, NULL, FILE_BEGIN);
BOOL ret = _ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, NULL); 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); _CloseHandle(hFile);
return ret; return ret;
} }
@ -115,14 +115,14 @@ BOOL WriteFunc_Patch0(DWORD nOffset, LPCVOID lpBuffer, DWORD nNumberOfBytesToWri
HANDLE hFile = HANDLE hFile =
_CreateFileA(PATCH0_PATH, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL); _CreateFileA(PATCH0_PATH, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) { 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; return FALSE;
} }
LARGE_INTEGER seekTo; LARGE_INTEGER seekTo;
seekTo.QuadPart = (LONGLONG)nOffset * (LONGLONG)SSD.m_BlockSize; seekTo.QuadPart = (LONGLONG)nOffset * (LONGLONG)SSD.m_BlockSize;
_SetFilePointerEx(hFile, seekTo, NULL, FILE_BEGIN); _SetFilePointerEx(hFile, seekTo, NULL, FILE_BEGIN);
BOOL ret = _WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, NULL); 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); _CloseHandle(hFile);
return ret; return ret;
} }
@ -130,7 +130,7 @@ BOOL WriteFunc_Patch0(DWORD nOffset, LPCVOID lpBuffer, DWORD nNumberOfBytesToWri
BOOL WriteFunc_OS(DWORD nOffset, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, BOOL WriteFunc_OS(DWORD nOffset, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten) { LPDWORD lpNumberOfBytesWritten) {
*lpNumberOfBytesWritten = nNumberOfBytesToWrite; *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; return TRUE;
} }
BOOL ReadFunc_OSLogFiles(DWORD nOffset, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, BOOL ReadFunc_OSLogFiles(DWORD nOffset, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
@ -165,13 +165,13 @@ BOOL ReadFunc_OSLogFiles(DWORD nOffset, LPVOID lpBuffer, DWORD nNumberOfBytesToR
return TRUE; return TRUE;
} }
if (nOffset == 2048) { 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); ZeroMemory(lpBuffer, nNumberOfBytesToRead);
*lpNumberOfBytesRead = nNumberOfBytesToRead; *lpNumberOfBytesRead = nNumberOfBytesToRead;
return TRUE; return TRUE;
} }
if (nOffset == 2048 + 1024) { 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); ZeroMemory(lpBuffer, nNumberOfBytesToRead);
*lpNumberOfBytesRead = nNumberOfBytesToRead; *lpNumberOfBytesRead = nNumberOfBytesToRead;
return TRUE; 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, BOOL WINAPI c_drive_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOID lpInBuffer,
DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize,
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) { LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
log_trace("C", "DeviceIOControl %08x", dwIoControlCode); log_trace(plfDrive, "C:DeviceIOControl %08x", dwIoControlCode);
ZeroMemory(lpOutBuffer, nOutBufferSize); ZeroMemory(lpOutBuffer, nOutBufferSize);
switch (dwIoControlCode) { switch (dwIoControlCode) {
case IOCTL_STORAGE_GET_DEVICE_NUMBER: 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, BOOL WINAPI x_drive_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOID lpInBuffer,
DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize,
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) { LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
log_trace("X", "DeviceIOControl %08x", dwIoControlCode); log_trace(plfDrive, "X:DeviceIOControl %08x", dwIoControlCode);
ZeroMemory(lpOutBuffer, nOutBufferSize); ZeroMemory(lpOutBuffer, nOutBufferSize);
switch (dwIoControlCode) { switch (dwIoControlCode) {
case IOCTL_STORAGE_GET_DEVICE_NUMBER: 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; ((STORAGE_DEVICE_NUMBER*)lpOutBuffer)->DeviceNumber = 0;
return TRUE; return TRUE;
default: default:
log_warning("X", "Unhandled DeviceIOControl %08x", dwIoControlCode); log_warning(plfDrive, "X:Unhandled DeviceIOControl %08x", dwIoControlCode);
return FALSE; 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, BOOL WINAPI q_drive_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOID lpInBuffer,
DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize,
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) { LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
log_trace("Q", "DeviceIOControl %08x", dwIoControlCode); log_trace(plfDrive, "Q:DeviceIOControl %08x", dwIoControlCode);
ZeroMemory(lpOutBuffer, nOutBufferSize); ZeroMemory(lpOutBuffer, nOutBufferSize);
switch (dwIoControlCode) { switch (dwIoControlCode) {
case IOCTL_STORAGE_MEDIA_REMOVAL: 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; ((PDISK_GEOMETRY)lpOutBuffer)->BytesPerSector = ALPHA_DVD.m_BlockSize;
return TRUE; return TRUE;
default: default:
log_warning("Q", "Unhandled DeviceIOControl %08x", dwIoControlCode); log_warning(plfDrive, "Q:Unhandled DeviceIOControl %08x", dwIoControlCode);
return FALSE; 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) { disk_volume_t* getVolumeByPath(LPCSTR lpRootPathName, DWORD match) {
if (lpRootPathName == NULL) { if (lpRootPathName == NULL) {
log_error("file", "getVolumeByPath(NULL) unimplemented!"); log_error(plfDrive, "getVolumeByPath(NULL) unimplemented!");
return FALSE; return FALSE;
} }
@ -403,7 +403,7 @@ BOOL WINAPI volume_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) { LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
disk_volume_t* volume = (disk_volume_t*)ctx->m_HookData; disk_volume_t* volume = (disk_volume_t*)ctx->m_HookData;
if (volume == NULL) { 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; return FALSE;
} }
@ -435,7 +435,7 @@ BOOL WINAPI volume_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
if (queryIn->PropertyId != StorageDeviceProperty || if (queryIn->PropertyId != StorageDeviceProperty ||
queryIn->QueryType != PropertyStandardQuery) { 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); queryIn->QueryType);
return FALSE; return FALSE;
} }
@ -467,7 +467,7 @@ BOOL WINAPI volume_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
} }
return TRUE; return TRUE;
default: default:
log_error("drive", "Unimplemented IOCTL: %08x", dwIoControlCode); log_error(plfDrive, "Unimplemented IOCTL: %08x", dwIoControlCode);
return FALSE; return FALSE;
} }
} }
@ -481,7 +481,7 @@ void init_volume(disk_volume_t* vol) {
StringFromGUID2(&guid, volume_name + 10, MAX_PATH + 1 - 10); StringFromGUID2(&guid, volume_name + 10, MAX_PATH + 1 - 10);
file_hook_t* volume_hook = new_file_hook(volume_name); 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->DeviceIoControl = &volume_DeviceIoControl;
volume_hook->hook_data = (void*)vol; volume_hook->hook_data = (void*)vol;
@ -519,7 +519,7 @@ void init_pd(physical_disk_t* pd) {
pd->m_BlockSize = BLOCK_SIZE_CDROM; pd->m_BlockSize = BLOCK_SIZE_CDROM;
break; break;
default: 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; break;
} }
} }
@ -544,7 +544,7 @@ void init_pd(physical_disk_t* pd) {
pd->m_DriveNumber); pd->m_DriveNumber);
break; break;
default: 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); pd->m_DriveNumber, pd->m_DiskType);
break; break;
} }
@ -580,7 +580,7 @@ void init_pd(physical_disk_t* pd) {
DWORD extendedPartNo = 0; DWORD extendedPartNo = 0;
if (pd->m_Extended[0].m_Size) { if (pd->m_Extended[0].m_Size) {
if (partitionNumber == 5) { 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); exit(1);
} }
pd->m_Partitions[partitionNumber - 1].m_Filesystem = MBR_FS_EXT_LBA; 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, BOOL q_drive_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) { 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); 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, 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); OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) { 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; return FALSE;
} }
@ -688,7 +688,7 @@ BOOL q_drive_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytes
_ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped); _ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
_CloseHandle(hFile); _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; return TRUE;
} }
@ -744,11 +744,11 @@ void hook_drives() {
hFile = hFile =
_CreateFileA(SBR0_PATH, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); _CreateFileA(SBR0_PATH, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) { if (hFile == INVALID_HANDLE_VALUE) {
log_error("drive", "Failed to open %s", SBR0_PATH); log_error(plfDrive, "Failed to open %s", SBR0_PATH);
} else { } else {
_ReadFile(hFile, &SegaBootRecord0, sizeof SegaBootRecord0, &numberOfBytesRead, NULL); _ReadFile(hFile, &SegaBootRecord0, sizeof SegaBootRecord0, &numberOfBytesRead, NULL);
_CloseHandle(hFile); _CloseHandle(hFile);
log_info("drive", "Restored SBR0 from %s", SBR0_PATH); log_info(plfDrive, "Restored SBR0 from %s", SBR0_PATH);
} }
} else { } else {
// memcpy(&SegaBootRecord0, &SegaBootRecordDefault, sizeof SegaBootRecord0); // memcpy(&SegaBootRecord0, &SegaBootRecordDefault, sizeof SegaBootRecord0);
@ -758,11 +758,11 @@ void hook_drives() {
hFile = hFile =
_CreateFileA(SBR1_PATH, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); _CreateFileA(SBR1_PATH, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) { if (hFile == INVALID_HANDLE_VALUE) {
log_error("drive", "Failed to open %s", SBR1_PATH); log_error(plfDrive, "Failed to open %s", SBR1_PATH);
} else { } else {
_ReadFile(hFile, &SegaBootRecord1, sizeof SegaBootRecord1, &numberOfBytesRead, NULL); _ReadFile(hFile, &SegaBootRecord1, sizeof SegaBootRecord1, &numberOfBytesRead, NULL);
_CloseHandle(hFile); _CloseHandle(hFile);
log_info("drive", "Restored SBR1 from %s", SBR0_PATH); log_info(plfDrive, "Restored SBR1 from %s", SBR0_PATH);
} }
} else { } else {
memcpy(&SegaBootRecord1, &SegaBootRecord0, sizeof SegaBootRecord0); 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, BOOL WINAPI FakeGetVolumeNameForVolumeMountPointA(LPCSTR lpszVolumeMountPoint, LPSTR lpszVolumeName,
DWORD cchBufferLength) { DWORD cchBufferLength) {
log_trace("drive", "GetVolumeNameForVolumeMountPointA(%s)", lpszVolumeMountPoint); log_trace(plfDrive, "GetVolumeNameForVolumeMountPointA(%s)", lpszVolumeMountPoint);
disk_volume_t* volume = getVolumeByPath(lpszVolumeMountPoint, VOL_MATCH_PATH); disk_volume_t* volume = getVolumeByPath(lpszVolumeMountPoint, VOL_MATCH_PATH);
if (volume == NULL) { if (volume == NULL) {
@ -141,7 +141,7 @@ BOOL WINAPI FakeGetVolumeNameForVolumeMountPointA(LPCSTR lpszVolumeMountPoint, L
} }
BOOL WINAPI FakeGetVolumePathNamesForVolumeNameA(LPCSTR lpszVolumeName, LPCH lpszVolumePathNames, BOOL WINAPI FakeGetVolumePathNamesForVolumeNameA(LPCSTR lpszVolumeName, LPCH lpszVolumePathNames,
DWORD cchBufferLength, PDWORD lpcchReturnLength) { 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); disk_volume_t* volume = getVolumeByPath(lpszVolumeName, VOL_MATCH_GUID);
if (volume == NULL) { if (volume == NULL) {
@ -164,7 +164,7 @@ BOOL WINAPI FakeGetVolumePathNamesForVolumeNameA(LPCSTR lpszVolumeName, LPCH lps
return TRUE; return TRUE;
} }
BOOL WINAPI FakeDeleteVolumeMountPointA(LPCSTR lpszVolumeMountPoint) { 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); disk_volume_t* volume = getVolumeByPath(lpszVolumeMountPoint, VOL_MATCH_PATH);
if (volume == NULL) { if (volume == NULL) {
SetLastError(ERROR_FILE_NOT_FOUND); SetLastError(ERROR_FILE_NOT_FOUND);
@ -175,7 +175,7 @@ BOOL WINAPI FakeDeleteVolumeMountPointA(LPCSTR lpszVolumeMountPoint) {
return TRUE; return TRUE;
} }
BOOL WINAPI FakeSetVolumeMountPointA(LPCSTR lpszVolumeMountPoint, LPCSTR lpszVolumeName) { 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); disk_volume_t* volume = getVolumeByPath(lpszVolumeName, VOL_MATCH_GUID);
if (volume == NULL) { if (volume == NULL) {
SetLastError(ERROR_FILE_NOT_FOUND); SetLastError(ERROR_FILE_NOT_FOUND);
@ -186,12 +186,12 @@ BOOL WINAPI FakeSetVolumeMountPointA(LPCSTR lpszVolumeMountPoint, LPCSTR lpszVol
DWORD nScan; DWORD nScan;
if (sscanf_s(lpszVolumeMountPoint, "\\\\.\\%c:%n", &cMountPoint, 1, &nScan) == 1 && if (sscanf_s(lpszVolumeMountPoint, "\\\\.\\%c:%n", &cMountPoint, 1, &nScan) == 1 &&
nScan == 6) { 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; volume->m_MountPoint = cMountPoint;
return TRUE; return TRUE;
} }
if (sscanf_s(lpszVolumeMountPoint, "%c:\\%n", &cMountPoint, 1, &nScan) == 1 && nScan == 3) { 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; volume->m_MountPoint = cMountPoint;
return TRUE; return TRUE;
} }
@ -224,7 +224,7 @@ MCIERROR WINAPI Fake_mciSendStringA(LPCTSTR lpszCommand, LPTSTR lpszReturnString
return 0; return 0;
} }
if (strcmp(lpszCommand, "set cdaudio door open") == 0) { if (strcmp(lpszCommand, "set cdaudio door open") == 0) {
log_game("mci", "Cupholder opened!"); log_game(plfDrive, "mci:Cupholder opened!");
return 0; return 0;
} }
if (strcmp(lpszCommand, "status cdaudio media present") == 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) { LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
physical_disk_t* pd = (physical_disk_t*)ctx->m_HookData; physical_disk_t* pd = (physical_disk_t*)ctx->m_HookData;
if (pd == NULL) { 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; return FALSE;
} }
log_trace("drive", "DeviceIOControl %08x", dwIoControlCode); log_trace(plfDrive, "DeviceIOControl %08x", dwIoControlCode);
ZeroMemory(lpOutBuffer, nOutBufferSize); ZeroMemory(lpOutBuffer, nOutBufferSize);
switch (dwIoControlCode) { switch (dwIoControlCode) {
case IOCTL_ATA_PASS_THROUGH: case IOCTL_ATA_PASS_THROUGH:
@ -36,7 +36,7 @@ BOOL WINAPI pd_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOI
} }
if (command != 0xC1) { if (command != 0xC1) {
log_error("pd0", "Unimplemented ATA command: %02x", command); log_error(plfDrive, "PD0:Unimplemented ATA command: %02x", command);
return FALSE; 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! // as long as the ioctl succeeds! Saves us a lot of work here!
return TRUE; return TRUE;
} }
log_error("drive", "Unimeplemented ATA C1 command: %02x", data); log_error(plfDrive, "Unimeplemented ATA C1 command: %02x", data);
return FALSE; return FALSE;
case IOCTL_DISK_GET_LENGTH_INFO: case IOCTL_DISK_GET_LENGTH_INFO:
PGET_LENGTH_INFORMATION pLi = (PGET_LENGTH_INFORMATION)lpOutBuffer; 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; *lpBytesReturned = sizeof *pLi;
return TRUE; return TRUE;
} }
log_error("drive", "Unimplemented ioctl: %08x", dwIoControlCode); log_error(plfDrive, "Unimplemented ioctl: %08x", dwIoControlCode);
return FALSE; return FALSE;
} }
@ -78,11 +78,11 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) { LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) {
physical_disk_t* pd = (physical_disk_t*)ctx->m_HookData; physical_disk_t* pd = (physical_disk_t*)ctx->m_HookData;
if (pd == NULL) { 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; 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); ctx->m_Pointer.QuadPart);
// ! WARNING: This ReadFile implementation is currently limited to aligned // ! 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) { if (ptrLBA == 0) {
mbr_t* mbr = (mbr_t*)lpBuffer; mbr_t* mbr = (mbr_t*)lpBuffer;
if (nNumberOfBytesToRead < sizeof *mbr) { 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; return FALSE;
} }
@ -119,7 +119,7 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
} }
if (ptrLBA <= MBR_LBA_GAP) { if (ptrLBA <= MBR_LBA_GAP) {
// Read within the 63 extra tracks // Read within the 63 extra tracks
log_error("drive", "Read failed"); log_error(plfDrive, "Read failed");
return FALSE; 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; DWORD readOffset = ptrLBA - pd->m_Partitions[i].m_PhysicalLBA;
if (pd->m_Partitions[i].m_ReadFunc == NULL) { 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); pd->m_DriveNumber, pd->m_Partitions[i].m_PartitionNumber, readOffset);
return FALSE; return FALSE;
} }
BOOL ret = pd->m_Partitions[i].m_ReadFunc(readOffset, lpBuffer, nNumberOfBytesToRead, BOOL ret = pd->m_Partitions[i].m_ReadFunc(readOffset, lpBuffer, nNumberOfBytesToRead,
lpNumberOfBytesRead); lpNumberOfBytesRead);
if (!ret) { 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); pd->m_DriveNumber, pd->m_Partitions[i].m_PartitionNumber, readOffset);
return FALSE; 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); pd->m_Partitions[i].m_PartitionNumber, readOffset);
return TRUE; return TRUE;
} }
@ -157,7 +157,7 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
if (ptrLBA == headerLBA) { if (ptrLBA == headerLBA) {
mbr_t* mbr = (mbr_t*)lpBuffer; mbr_t* mbr = (mbr_t*)lpBuffer;
if (nNumberOfBytesToRead < sizeof *mbr) { 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; return FALSE;
} }
@ -188,7 +188,7 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
if (ptrLBA == headerLBA + SPD_OFFSET) { if (ptrLBA == headerLBA + SPD_OFFSET) {
spd_t* spd = (spd_t*)lpBuffer; spd_t* spd = (spd_t*)lpBuffer;
if (nNumberOfBytesToRead < sizeof *spd) { if (nNumberOfBytesToRead < sizeof *spd) {
log_error("drive", "Buffer too small for SPD!"); log_error(plfDrive, "Buffer too small for SPD!");
return FALSE; 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 // SEGA Boot Record 0 and 1. The two are a redundant copy of each other
if (ptrLBA == headerLBA + SBR0_OFFSET) { if (ptrLBA == headerLBA + SBR0_OFFSET) {
if (nNumberOfBytesToRead < sizeof SegaBootRecord0) { if (nNumberOfBytesToRead < sizeof SegaBootRecord0) {
log_error("drive", "Buffer too small for SBR0!"); log_error(plfDrive, "Buffer too small for SBR0!");
return FALSE; return FALSE;
} }
memcpy(lpBuffer, &SegaBootRecord0, sizeof SegaBootRecord0); 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 (ptrLBA == headerLBA + SBR1_OFFSET) {
if (nNumberOfBytesToRead < sizeof SegaBootRecord1) { if (nNumberOfBytesToRead < sizeof SegaBootRecord1) {
log_error("drive", "Buffer too small for SBR1!"); log_error(plfDrive, "Buffer too small for SBR1!");
return FALSE; return FALSE;
} }
memcpy(lpBuffer, &SegaBootRecord1, sizeof SegaBootRecord1); 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 && if (ptrLBA >= pd->m_Extended[i].m_PhysicalLBA - EXT_HEADER_GAP &&
ptrLBA < pd->m_Extended[i].m_PhysicalLBA) { ptrLBA < pd->m_Extended[i].m_PhysicalLBA) {
// Read within the 63 extra tracks // Read within the 63 extra tracks
log_error("drive", "Read failed"); log_error(plfDrive, "Read failed");
return FALSE; 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; DWORD readOffset = ptrLBA - pd->m_Extended[i].m_PhysicalLBA;
if (pd->m_Extended[i].m_ReadFunc == NULL) { 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); pd->m_DriveNumber, pd->m_Extended[i].m_PartitionNumber, readOffset);
return FALSE; return FALSE;
} }
BOOL ret = pd->m_Extended[i].m_ReadFunc(readOffset, lpBuffer, nNumberOfBytesToRead, BOOL ret = pd->m_Extended[i].m_ReadFunc(readOffset, lpBuffer, nNumberOfBytesToRead,
lpNumberOfBytesRead); lpNumberOfBytesRead);
if (!ret) { 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); pd->m_DriveNumber, pd->m_Extended[i].m_PartitionNumber, readOffset);
return FALSE; 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); pd->m_Extended[i].m_PartitionNumber, readOffset);
return TRUE; return TRUE;
} }
} }
log_error("drive", "Read failed"); log_error(plfDrive, "Read failed");
return FALSE; 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; physical_disk_t* pd = (physical_disk_t*)ctx->m_HookData;
if (pd == NULL) { 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; 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); ctx->m_Pointer.QuadPart);
// for (DWORD i = 0; i < nNumberOfBytesToWrite; i += 32) { // 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 // Writes to the MBR header or slack are blocked
if (ptrLBA <= MBR_LBA_GAP) { if (ptrLBA <= MBR_LBA_GAP) {
log_error("drive", "Write rejected"); log_error(plfDrive, "Write rejected");
return FALSE; 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; DWORD writeOffset = ptrLBA - pd->m_Partitions[i].m_PhysicalLBA;
if (pd->m_Partitions[i].m_WriteFunc == NULL) { 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", "Attempted write in %d/%d at block offset %08x; No write function",
pd->m_DriveNumber, pd->m_Partitions[i].m_PartitionNumber, writeOffset); pd->m_DriveNumber, pd->m_Partitions[i].m_PartitionNumber, writeOffset);
return FALSE; 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, BOOL ret = pd->m_Partitions[i].m_WriteFunc(writeOffset, lpBuffer, nNumberOfBytesToWrite,
lpNumberOfBytesWritten); lpNumberOfBytesWritten);
if (!ret) { 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); pd->m_DriveNumber, pd->m_Partitions[i].m_PartitionNumber, writeOffset);
return FALSE; 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); pd->m_Partitions[i].m_PartitionNumber, writeOffset);
return TRUE; return TRUE;
} }
@ -327,7 +327,7 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
// Extended header // Extended header
DWORD headerLBA = pd->m_Extended[i].m_PhysicalLBA - EXT_HEADER_GAP; DWORD headerLBA = pd->m_Extended[i].m_PhysicalLBA - EXT_HEADER_GAP;
if (ptrLBA == headerLBA) { if (ptrLBA == headerLBA) {
log_error("drive", "Write to extended header rejected"); log_error(plfDrive, "Write to extended header rejected");
return FALSE; return FALSE;
} }
@ -335,13 +335,13 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
// SEGA Partition Description // SEGA Partition Description
if (ptrLBA == headerLBA + SPD_OFFSET) { if (ptrLBA == headerLBA + SPD_OFFSET) {
if (nNumberOfBytesToWrite < sizeof(spd_t)) { if (nNumberOfBytesToWrite < sizeof(spd_t)) {
log_error("drive", "Buffer too small for SPD!"); log_error(plfDrive, "Buffer too small for SPD!");
return FALSE; return FALSE;
} }
HANDLE hFile = _CreateFileA(SPD_PATH, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, HANDLE hFile = _CreateFileA(SPD_PATH, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
OPEN_ALWAYS, 0, NULL); OPEN_ALWAYS, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) { 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; return FALSE;
} }
BOOL ret = _WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, BOOL ret = _WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite,
@ -352,13 +352,13 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
// SEGA Boot Records // SEGA Boot Records
if (ptrLBA == headerLBA + SBR0_OFFSET) { if (ptrLBA == headerLBA + SBR0_OFFSET) {
if (nNumberOfBytesToWrite < sizeof(sbr_t)) { if (nNumberOfBytesToWrite < sizeof(sbr_t)) {
log_error("drive", "Buffer too small for SBR!"); log_error(plfDrive, "Buffer too small for SBR!");
return FALSE; return FALSE;
} }
HANDLE hFile = _CreateFileA(SBR0_PATH, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, HANDLE hFile = _CreateFileA(SBR0_PATH, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
OPEN_ALWAYS, 0, NULL); OPEN_ALWAYS, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) { 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; return FALSE;
} }
BOOL ret = _WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, 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 (ptrLBA == headerLBA + SBR1_OFFSET) {
if (nNumberOfBytesToWrite < sizeof(sbr_t)) { if (nNumberOfBytesToWrite < sizeof(sbr_t)) {
log_error("drive", "Buffer too small for SBR!"); log_error(plfDrive, "Buffer too small for SBR!");
return FALSE; return FALSE;
} }
HANDLE hFile = _CreateFileA(SBR1_PATH, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, HANDLE hFile = _CreateFileA(SBR1_PATH, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
OPEN_ALWAYS, 0, NULL); OPEN_ALWAYS, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) { 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; return FALSE;
} }
BOOL ret = _WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, 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 && if (ptrLBA >= pd->m_Extended[i].m_PhysicalLBA - EXT_HEADER_GAP &&
ptrLBA < pd->m_Extended[i].m_PhysicalLBA) { ptrLBA < pd->m_Extended[i].m_PhysicalLBA) {
// Write within the 63 extra tracks // Write within the 63 extra tracks
log_error("drive", "Write failed"); log_error(plfDrive, "Write failed");
return FALSE; 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; DWORD writeOffset = ptrLBA - pd->m_Extended[i].m_PhysicalLBA;
if (pd->m_Extended[i].m_WriteFunc == NULL) { 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", "Attempted write in %d/%d at block offset %08x; No write function",
pd->m_DriveNumber, pd->m_Extended[i].m_PartitionNumber, writeOffset); pd->m_DriveNumber, pd->m_Extended[i].m_PartitionNumber, writeOffset);
return FALSE; 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, BOOL ret = pd->m_Extended[i].m_WriteFunc(writeOffset, lpBuffer, nNumberOfBytesToWrite,
lpNumberOfBytesWritten); lpNumberOfBytesWritten);
if (!ret) { 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); pd->m_DriveNumber, pd->m_Extended[i].m_PartitionNumber, writeOffset);
return FALSE; 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); pd->m_Extended[i].m_PartitionNumber, writeOffset);
return TRUE; 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++) { for (int i = 0; i < sizeof DRIVE_REDIRECT_TABLE / sizeof DRIVE_REDIRECT_TABLE[0]; i++) {
drive_redirect_t row = DRIVE_REDIRECT_TABLE[i]; drive_redirect_t row = DRIVE_REDIRECT_TABLE[i];
if (PathPrefix(path, row.drive)) { 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); size_t new_len = strlen(path) - strlen(row.drive) + strlen(row.path);
strcpy_s(_redirected_path, new_len + 1, 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]; for (; len > 0; len--) (dst++)[0] = (src++)[0];
dst[0] = 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); make_dirs(_redirected_path);
*redirected = _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); file_hook_t* found_fh = find_hook(lpFileName);
if (found_fh != NULL) { if (found_fh != NULL) {
HANDLE handle = open_hook(found_fh); 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; return handle;
} }
@ -194,11 +194,11 @@ HANDLE WINAPI FakeCreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD d
if (redirect_path_w(lpFileName, &redirected)) { if (redirect_path_w(lpFileName, &redirected)) {
handle = TrueCreateFileA(redirected, dwDesiredAccess, dwShareMode, lpSecurityAttributes, handle = TrueCreateFileA(redirected, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
log_misc(HOOKS_LOGGER, "CreateFileW(%s) -> 0x%p", redirected, handle); log_misc(plfHooks, "CreateFileW(%s) -> 0x%p", redirected, handle);
} else { } else {
handle = TrueCreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, handle = TrueCreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
log_misc(HOOKS_LOGGER, "CreateFileW(%ls) -> 0x%p", lpFileName, handle); log_misc(plfHooks, "CreateFileW(%ls) -> 0x%p", lpFileName, handle);
} }
return handle; return handle;
@ -213,25 +213,25 @@ HANDLE WINAPI FakeCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dw
file_hook_t* found_fh = find_hook(wideFileName); file_hook_t* found_fh = find_hook(wideFileName);
if (found_fh != NULL) { if (found_fh != NULL) {
HANDLE handle = open_hook(found_fh); 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; return handle;
} }
redirect_path(lpFileName, &lpFileName); redirect_path(lpFileName, &lpFileName);
HANDLE handle = TrueCreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, HANDLE handle = TrueCreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
log_misc(HOOKS_LOGGER, "CreateFileA(%s) -> 0x%p", lpFileName, handle); log_misc(plfHooks, "CreateFileA(%s) -> 0x%p", lpFileName, handle);
return handle; return handle;
} }
BOOL WINAPI FakePathFileExistsA(LPCSTR pszPath) { BOOL WINAPI FakePathFileExistsA(LPCSTR pszPath) {
log_misc(HOOKS_LOGGER, "PathFileExists(%s)", pszPath); log_misc(plfHooks, "PathFileExists(%s)", pszPath);
redirect_path(pszPath, &pszPath); redirect_path(pszPath, &pszPath);
BOOL ret = TruePathFileExistsA(pszPath); BOOL ret = TruePathFileExistsA(pszPath);
return ret; return ret;
} }
BOOL WINAPI FakePathFileExistsW(LPCWSTR pszPath) { BOOL WINAPI FakePathFileExistsW(LPCWSTR pszPath) {
log_misc(HOOKS_LOGGER, "PathFileExists(%ls)", pszPath); log_misc(plfHooks, "PathFileExists(%ls)", pszPath);
LPCSTR redirected; LPCSTR redirected;
if (redirect_path_w(pszPath, &redirected)) { if (redirect_path_w(pszPath, &redirected)) {
return TruePathFileExistsA(redirected); return TruePathFileExistsA(redirected);
@ -259,7 +259,7 @@ BOOL WINAPI FakeDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lp
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) { LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
open_hook_t* pHData = GetDataForHandle(hDevice, HDATA_FILE); open_hook_t* pHData = GetDataForHandle(hDevice, HDATA_FILE);
if (pHData == NULL) { 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); // dwIoControlCode, lpInBuffer, nInBufferSize, nOutBufferSize);
return TrueDeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, 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; file_hook_t* file_hook = pHData->hook;
if (!file_hook->DeviceIoControl) { 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; 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.HighPart = 0;
pHData->ctx.m_Pointer.LowPart = lDistanceToMove; pHData->ctx.m_Pointer.LowPart = lDistanceToMove;
} else if (dwMoveMethod == FILE_END) { } else if (dwMoveMethod == FILE_END) {
log_error("files", "FILE_END unimplemented"); log_error(plfFile, "FILE_END unimplemented");
return 0xFFFFFFFF; return 0xFFFFFFFF;
} else { } else {
if (lpDistanceToMoveHigh) pHData->ctx.m_Pointer.HighPart += *lpDistanceToMoveHigh; if (lpDistanceToMoveHigh) pHData->ctx.m_Pointer.HighPart += *lpDistanceToMoveHigh;
@ -314,7 +314,7 @@ BOOL WINAPI FakeSetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove,
if (dwMoveMethod == FILE_BEGIN) { if (dwMoveMethod == FILE_BEGIN) {
pHData->ctx.m_Pointer = liDistanceToMove; pHData->ctx.m_Pointer = liDistanceToMove;
} else if (dwMoveMethod == FILE_END) { } else if (dwMoveMethod == FILE_END) {
log_error("files", "FILE_END unimplemented"); log_error(plfFile, "FILE_END unimplemented");
return FALSE; return FALSE;
} else { } else {
pHData->ctx.m_Pointer.QuadPart += liDistanceToMove.QuadPart; 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; file_hook_t* file_hook = pHData->hook;
if (!file_hook->GetFileSizeEx) { 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 FALSE;
} }
return file_hook->GetFileSizeEx(&(pHData->ctx), lpFileSize); 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; file_hook_t* file_hook = pHData->hook;
if (!file_hook->WriteFile) { 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; return FALSE;
} }
BOOL ret = file_hook->WriteFile(&(pHData->ctx), lpBuffer, nNumberOfBytesToWrite, 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, return TrueReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead,
lpOverlapped); 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); open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
if (pHData == NULL) { if (pHData == NULL) {
@ -381,7 +381,7 @@ BOOL WINAPI FakeReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRe
file_hook_t* file_hook = pHData->hook; file_hook_t* file_hook = pHData->hook;
if (!file_hook->ReadFile) { 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; return FALSE;
} }
BOOL ret = file_hook->ReadFile(&(pHData->ctx), lpBuffer, nNumberOfBytesToRead, 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)) { 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) { if (res != S_OK) {
switch (res) { switch (res) {
case D3DERR_DEVICELOST: case D3DERR_DEVICELOST:
log_error("D3D9", "CreateDevice failed: Device lost"); log_error(plfD3D9, "CreateDevice failed: Device lost");
break; break;
case D3DERR_INVALIDCALL: case D3DERR_INVALIDCALL:
log_error("D3D9", "CreateDevice failed: Invalid call"); log_error(plfD3D9, "CreateDevice failed: Invalid call");
break; break;
case D3DERR_NOTAVAILABLE: case D3DERR_NOTAVAILABLE:
log_error("D3D9", "CreateDevice failed: Requested configuration not available"); log_error(plfD3D9, "CreateDevice failed: Requested configuration not available");
break; break;
case D3DERR_OUTOFVIDEOMEMORY: case D3DERR_OUTOFVIDEOMEMORY:
log_error("D3D9", "CreateDevice failed: VMem exhausted"); log_error(plfD3D9, "CreateDevice failed: VMem exhausted");
break; break;
default: default:
log_error("D3D9", "CreateDevice failed: %08x", res); log_error(plfD3D9, "CreateDevice failed: %08x", res);
break; break;
} }
} }

View File

@ -29,7 +29,7 @@ int WINAPIV Fakeprintf(const char* _Format, ...) {
va_list args; va_list args;
va_start(args, _Format); va_start(args, _Format);
int ret = vlog_game("printf", _Format, args); int ret = vlog_game(plfPrintf, _Format, args);
va_end(args); va_end(args);
return ret; return ret;
@ -45,7 +45,7 @@ int WINAPIV Fakefprintf(FILE* _File, const char* _Format, ...) {
va_list args; va_list args;
va_start(args, _Format); va_start(args, _Format);
int ret = vlog_game("fprintf", _Format, args); int ret = vlog_game(plfFprintf, _Format, args);
va_end(args); va_end(args);
return ret; return ret;
@ -55,13 +55,13 @@ int WINAPIV Fakefprintf_s(FILE* _Stream, const char* _Format, ...) {
va_list args; va_list args;
va_start(args, _Format); va_start(args, _Format);
int ret = vlog_game("fprintf_s", _Format, args); int ret = vlog_game(plfFprintf_s, _Format, args);
va_end(args); va_end(args);
return ret; return ret;
} }
int WINAPIV Fakevfprintf_s(FILE* _Stream, const char* _Format, va_list _ArgList) { 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) { HANDLE WINAPI FakeRegisterEventSourceA(LPCSTR lpUNCServerName, LPCSTR lpSourceName) {
return (HANDLE)0xDEADBEEF; return (HANDLE)0xDEADBEEF;
@ -74,21 +74,21 @@ BOOL WINAPI FakeReportEventA(HANDLE hEventLog, WORD wType, WORD wCategory, DWORD
case EVENTLOG_SUCCESS: case EVENTLOG_SUCCESS:
case EVENTLOG_AUDIT_SUCCESS: case EVENTLOG_AUDIT_SUCCESS:
for (int i = 0; i < wNumStrings; i++) for (int i = 0; i < wNumStrings; i++)
log_misc("evtlog", trim_string((char*)lpStrings[i])); log_misc(plfEvtlog, trim_string((char*)lpStrings[i]));
break; break;
case EVENTLOG_AUDIT_FAILURE: case EVENTLOG_AUDIT_FAILURE:
case EVENTLOG_ERROR_TYPE: case EVENTLOG_ERROR_TYPE:
for (int i = 0; i < wNumStrings; i++) for (int i = 0; i < wNumStrings; i++)
log_error("evtlog", trim_string((char*)lpStrings[i])); log_error(plfEvtlog, trim_string((char*)lpStrings[i]));
break; break;
case EVENTLOG_WARNING_TYPE: case EVENTLOG_WARNING_TYPE:
for (int i = 0; i < wNumStrings; i++) for (int i = 0; i < wNumStrings; i++)
log_warning("evtlog", trim_string((char*)lpStrings[i])); log_warning(plfEvtlog, trim_string((char*)lpStrings[i]));
break; break;
case EVENTLOG_INFORMATION_TYPE: case EVENTLOG_INFORMATION_TYPE:
default: default:
for (int i = 0; i < wNumStrings; i++) for (int i = 0; i < wNumStrings; i++)
log_info("evtlog", trim_string((char*)lpStrings[i])); log_info(plfEvtlog, trim_string((char*)lpStrings[i]));
break; break;
} }
return TRUE; 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); USHORT port = _byteswap_ushort(((SOCKADDR_IN*)name)->sin_port);
// Poorly exclude nxauth. TODO: better // Poorly exclude nxauth. TODO: better
if (port != 40190) { if (port != 40190) {
log_info("connect", "%hhu.%hhu.%hhu.%hhu:%hu", (addr >> 24) & 0xff, (addr >> 16) & 0xff, log_info(plfNetwork, "connect(%hhu.%hhu.%hhu.%hhu:%hu)", (addr >> 24) & 0xff,
(addr >> 8) & 0xff, addr & 0xff, port); (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff, port);
} }
return True_connect(s, name, namelen); 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) { int WINAPI Fake_bind(SOCKET s, const SOCKADDR* name, int namelen) {
ULONG addr = _byteswap_ulong(((SOCKADDR_IN*)name)->sin_addr.S_un.S_addr); ULONG addr = _byteswap_ulong(((SOCKADDR_IN*)name)->sin_addr.S_un.S_addr);
USHORT port = _byteswap_ushort(((SOCKADDR_IN*)name)->sin_port); 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); (addr >> 8) & 0xff, addr & 0xff, port);
return True_bind(s, name, namelen); 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_1 0xBB
#define MAC_PREFIX_2 0xC1 #define MAC_PREFIX_2 0xC1
DWORD WINAPI FakeGetIfTable(PMIB_IFTABLE pIfTable, PULONG pdwSize, BOOL bOrder) { 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; MIB_IFROW* row;
uint32_t nbytes; 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) { if (strcmp(pszName, INTERCEPT_DNS[i].name) == 0) {
printf("%08x\n", MiceConfig.network.naominet_jp); 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! // We only support replacing at most one address, but that's all we'll ever need to!
(*ppQueryResults) = &dummy_record; (*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); return TrueDnsQuery_A(pszName, wType, Options, pExtra, ppQueryResults, pReserved);
}; };
INT WSAAPI FakeWSAStringToAddressA(LPSTR AddressString, INT AddressFamily, INT WSAAPI FakeWSAStringToAddressA(LPSTR AddressString, INT AddressFamily,
LPWSAPROTOCOL_INFOA lpProtocolInfo, LPSOCKADDR lpAddress, LPWSAPROTOCOL_INFOA lpProtocolInfo, LPSOCKADDR lpAddress,
LPINT lpAddressLength) { 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++) { for (size_t i = 0; i < sizeof INTERCEPT_DNS / sizeof INTERCEPT_DNS[0]; i++) {
if (strcmp(AddressString, INTERCEPT_DNS[i].name) == 0) { 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); *INTERCEPT_DNS[i].address);
lpAddress->sa_family = AF_INET; lpAddress->sa_family = AF_INET;
@ -133,14 +134,64 @@ INT WSAAPI FakeWSAStringToAddressA(LPSTR AddressString, INT AddressFamily,
return ERROR_SUCCESS; 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, return TrueWSAStringToAddressA(AddressString, AddressFamily, lpProtocolInfo, lpAddress,
lpAddressLength); 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() { void hook_network() {
hook("Ws2_32.dll", "connect", Fake_connect, (void**)&True_connect); 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", "bind", Fake_bind, (void**)&True_bind);
hook("Ws2_32.dll", "sendto", Fake_sendto, (void**)&True_sendto);
hook("Ws2_32.dll", "WSAStringToAddressA", FakeWSAStringToAddressA, hook("Ws2_32.dll", "WSAStringToAddressA", FakeWSAStringToAddressA,
(void**)&TrueWSAStringToAddressA); (void**)&TrueWSAStringToAddressA);
hook("Iphlpapi.dll", "GetIfTable", FakeGetIfTable, (void**)&TrueGetIfTable); hook("Iphlpapi.dll", "GetIfTable", FakeGetIfTable, (void**)&TrueGetIfTable);

View File

@ -1,15 +1,19 @@
#pragma once #pragma once
#include "../common.h" #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_connect)(SOCKET s, const SOCKADDR* name, int namelen);
static int(WINAPI* True_bind)(SOCKET s, const SOCKADDR* addr, 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 DWORD(WINAPI* TrueGetIfTable)(PMIB_IFTABLE pIfTable, PULONG pdwSize, BOOL bOrder);
static DNS_STATUS(WINAPI* TrueDnsQuery_A)(PCSTR pszName, WORD wType, DWORD Options, PVOID pExtra, static DNS_STATUS(WINAPI* TrueDnsQuery_A)(PCSTR pszName, WORD wType, DWORD Options, PVOID pExtra,
PDNS_RECORDA* ppQueryResults, PVOID* pReserved); 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); LPSOCKADDR lpAddress, LPINT lpAddressLength);
void hook_network(); void hook_network();

View File

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

View File

@ -1,28 +1,28 @@
#include "registry.h" #include "registry.h"
LSTATUS WINAPI FakeRegCloseKey(HKEY hKey) { LSTATUS WINAPI FakeRegCloseKey(HKEY hKey) {
log_trace("registry", "RegCloseKey %08x", hKey); log_trace(plfRegistry, "RegCloseKey %08x", hKey);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
LSTATUS WINAPI FakeRegCreateKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass, LSTATUS WINAPI FakeRegCreateKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass,
DWORD dwOptions, REGSAM samDesired, DWORD dwOptions, REGSAM samDesired,
const LPSECURITY_ATTRIBUTES lpSecurityAttributes, const LPSECURITY_ATTRIBUTES lpSecurityAttributes,
PHKEY phkResult, LPDWORD lpdwDisposition) { PHKEY phkResult, LPDWORD lpdwDisposition) {
log_trace("registry", "RegCreateKeyExA %08x %s", hKey, lpSubKey); log_trace(plfRegistry, "RegCreateKeyExA %08x %s", hKey, lpSubKey);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
LSTATUS WINAPI FakeRegDeleteKeyA(HKEY hKey, LPCSTR lpSubKey) { 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; return ERROR_SUCCESS;
} }
LSTATUS WINAPI FakeRegDeleteKeyValueA(HKEY hKey, LPCSTR lpSubKey, LPCSTR lpValueName) { 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; return ERROR_SUCCESS;
} }
LSTATUS WINAPI FakeRegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcchName, LSTATUS WINAPI FakeRegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcchName,
LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcchClass, LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcchClass,
PFILETIME lpftLastWriteTime) { PFILETIME lpftLastWriteTime) {
log_trace("registry", "RegEnumKeyExA %08x[%d]", hKey, dwIndex); log_trace(plfRegistry, "RegEnumKeyExA %08x[%d]", hKey, dwIndex);
if (dwIndex == 0) { if (dwIndex == 0) {
strcpy(lpName, "Direct3D HAL"); strcpy(lpName, "Direct3D HAL");
return ERROR_SUCCESS; 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, LSTATUS WINAPI FakeRegEnumValueA(HKEY hKey, DWORD dwIndex, LPSTR lpValueName,
LPDWORD lpcchValueName, LPDWORD lpReserved, LPDWORD lpType, LPDWORD lpcchValueName, LPDWORD lpReserved, LPDWORD lpType,
LPBYTE lpData, LPDWORD lpcbData) { 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; 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) { 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); HDEVINFO res = TrueSetupDiGetClassDevsA(ClassGuid, Enumerator, hwndParent, Flags);
if (res != INVALID_HANDLE_VALUE && ClassGuid != NULL) { if (res != INVALID_HANDLE_VALUE && ClassGuid != NULL) {
FAKE_DEVICE* device = fake_devices; FAKE_DEVICE* device = fake_devices;
while (device != NULL) { while (device != NULL) {
if (memcmp(device->guid, ClassGuid, sizeof(*ClassGuid)) == 0) { 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->handle = res;
} }
device = device->next; device = device->next;
} }
} else { } else {
log_warning("setupapi", "upstream SetupDiGetClassDevsA failed: %d", GetLastError()); log_warning(plfSetupAPI, "upstream SetupDiGetClassDevsA failed: %d", GetLastError());
} }
return res; return res;
@ -38,12 +38,12 @@ HDEVINFO WINAPI FakeSetupDiGetClassDevsA(const GUID* ClassGuid, PCWSTR Enumerato
BOOL WINAPI FakeSetupDiEnumDeviceInterfaces(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, BOOL WINAPI FakeSetupDiEnumDeviceInterfaces(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData,
const GUID* InterfaceClassGuid, DWORD MemberIndex, const GUID* InterfaceClassGuid, DWORD MemberIndex,
PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData) { PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData) {
log_misc("setupapi", "SetupDiEnumDeviceInterfaces"); log_misc(plfSetupAPI, "SetupDiEnumDeviceInterfaces");
FAKE_DEVICE* device = fake_devices; FAKE_DEVICE* device = fake_devices;
if (DeviceInterfaceData) { if (DeviceInterfaceData) {
while (device != NULL) { while (device != NULL) {
if (device->handle == DeviceInfoSet) { 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); memcpy(&DeviceInterfaceData->InterfaceClassGuid, device->guid, sizeof *device->guid);
DeviceInterfaceData->Flags = SPINT_ACTIVE; DeviceInterfaceData->Flags = SPINT_ACTIVE;
DeviceInterfaceData->Reserved = (ULONG_PTR)device->path; DeviceInterfaceData->Reserved = (ULONG_PTR)device->path;
@ -55,7 +55,7 @@ BOOL WINAPI FakeSetupDiEnumDeviceInterfaces(HDEVINFO DeviceInfoSet, PSP_DEVINFO_
} }
// Fallback // Fallback
log_misc("setupapi", "device info fallthrough"); log_misc(plfSetupAPI, "device info fallthrough");
return TrueSetupDiEnumDeviceInterfaces(DeviceInfoSet, DeviceInfoData, InterfaceClassGuid, MemberIndex, return TrueSetupDiEnumDeviceInterfaces(DeviceInfoSet, DeviceInfoData, InterfaceClassGuid, MemberIndex,
DeviceInterfaceData); DeviceInterfaceData);
} }
@ -64,11 +64,11 @@ BOOL WINAPI FakeSetupDiGetDeviceInterfaceDetailA(HDEVINFO DeviceInfoSet, PSP_DEV
PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData, PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData,
DWORD DeviceInterfaceDetailDataSize, PDWORD RequiredSize, DWORD DeviceInterfaceDetailDataSize, PDWORD RequiredSize,
PSP_DEVINFO_DATA DeviceInfoData) { PSP_DEVINFO_DATA DeviceInfoData) {
log_misc("setupapi", "SetupDiGetDeviceInterfaceDetailA"); log_misc(plfSetupAPI, "SetupDiGetDeviceInterfaceDetailA");
FAKE_DEVICE* device = fake_devices; FAKE_DEVICE* device = fake_devices;
while (device != NULL) { while (device != NULL) {
if (device->handle == DeviceInfoSet && (ULONG_PTR)device->path == DeviceInterfaceData->Reserved) { 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; const WCHAR* res = (WCHAR*)DeviceInterfaceData->Reserved;
int new_len = (wcslen(res) + 1) * (sizeof *res); int new_len = (wcslen(res) + 1) * (sizeof *res);
@ -94,7 +94,7 @@ BOOL WINAPI FakeSetupDiGetDeviceInterfaceDetailA(HDEVINFO DeviceInfoSet, PSP_DEV
device = device->next; device = device->next;
} }
log_misc("setupapi", "TrueSetupDiGetDeviceInterfaceDetailA fallthrough"); log_misc(plfSetupAPI, "TrueSetupDiGetDeviceInterfaceDetailA fallthrough");
return TrueSetupDiGetDeviceInterfaceDetailA(DeviceInfoSet, DeviceInterfaceData, DeviceInterfaceDetailData, return TrueSetupDiGetDeviceInterfaceDetailA(DeviceInfoSet, DeviceInterfaceData, DeviceInterfaceDetailData,
DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData); DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
} }

View File

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

View File

@ -9,7 +9,7 @@ BOOL WINAPI Fake_SetLocalTime(const SYSTEMTIME* lpSystemTime) {
memcpy(&localTime, lpSystemTime, sizeof localTime); memcpy(&localTime, lpSystemTime, sizeof localTime);
ltCache = TRUE; 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->wYear, lpSystemTime->wMonth, lpSystemTime->wDay, lpSystemTime->wHour,
lpSystemTime->wMinute, lpSystemTime->wSecond, lpSystemTime->wMilliseconds); lpSystemTime->wMinute, lpSystemTime->wSecond, lpSystemTime->wMilliseconds);
return TRUE; return TRUE;
@ -18,20 +18,20 @@ BOOL WINAPI Fake_SetSystemTime(const SYSTEMTIME* lpSystemTime) {
memcpy(&systemTime, lpSystemTime, sizeof systemTime); memcpy(&systemTime, lpSystemTime, sizeof systemTime);
stCache = TRUE; 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->wYear, lpSystemTime->wMonth, lpSystemTime->wDay, lpSystemTime->wHour,
lpSystemTime->wMinute, lpSystemTime->wSecond, lpSystemTime->wMilliseconds); lpSystemTime->wMinute, lpSystemTime->wSecond, lpSystemTime->wMilliseconds);
return TRUE; return TRUE;
} }
BOOL WINAPI Fake_SetTimeZoneInformation(const TIME_ZONE_INFORMATION* lpTimeZoneInformation) { 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; return TRUE;
} }
// TODO: Store deltas instead // TODO: Store deltas instead
BOOL WINAPI Fake_GetLocalTime(SYSTEMTIME* lpSystemTime) { BOOL WINAPI Fake_GetLocalTime(SYSTEMTIME* lpSystemTime) {
log_trace("time", "GetLocalTime"); log_trace(plfTime, "GetLocalTime");
if (ltCache) { if (ltCache) {
memcpy(lpSystemTime, &localTime, sizeof localTime); memcpy(lpSystemTime, &localTime, sizeof localTime);
return TRUE; return TRUE;
@ -49,7 +49,7 @@ BOOL WINAPI Fake_GetLocalTime(SYSTEMTIME* lpSystemTime) {
return TrueGetLocalTime(lpSystemTime); return TrueGetLocalTime(lpSystemTime);
} }
BOOL WINAPI Fake_GetSystemTime(SYSTEMTIME* lpSystemTime) { BOOL WINAPI Fake_GetSystemTime(SYSTEMTIME* lpSystemTime) {
log_trace("time", "GetSystemTime"); log_trace(plfTime, "GetSystemTime");
if (stCache) { if (stCache) {
memcpy(lpSystemTime, &systemTime, sizeof systemTime); memcpy(lpSystemTime, &systemTime, sizeof systemTime);
return TRUE; return TRUE;

View File

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

View File

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

View File

@ -19,3 +19,4 @@ BOOL PathEqual(LPCSTR path1, LPCSTR path2);
BOOL PathPrefix(LPCSTR path, LPCSTR prefix); BOOL PathPrefix(LPCSTR path, LPCSTR prefix);
void make_dirs(const char* path); 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... // cmd BYTE PTR ds:0x...,0x...
len = 10; len = 10;
} else { } 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++) { for (int i = 0; i < 16; i++) {
printf("%02x ", ((LPBYTE)src)[i]); printf("%02x ", ((LPBYTE)src)[i]);
} }
puts(""); puts("");
log_error(HOOKS_LOGGER, "Unsafely defaulting to 5!"); log_error(plfHooks, "Unsafely defaulting to 5!");
len = 5; len = 5;
} }
@ -147,10 +147,10 @@ void* CreateHook32(PVOID src, PVOID dst) {
extern FARPROC (*TrueGetProcAddress)(HMODULE hModule, LPCSTR lpProcName); extern FARPROC (*TrueGetProcAddress)(HMODULE hModule, LPCSTR lpProcName);
void setup_hooks() { void setup_hooks() {
log_info(HOOKS_LOGGER, "attaching"); log_info(plfHooks, "attaching");
if (hook_list == NULL) { if (hook_list == NULL) {
log_warning(HOOKS_LOGGER, "No hooks to register!"); log_warning(plfHooks, "No hooks to register!");
return; return;
} }
function_hook_t* hook = hook_list; function_hook_t* hook = hook_list;
@ -159,7 +159,7 @@ void setup_hooks() {
HMODULE dll = LoadLibraryA(hook->dll); HMODULE dll = LoadLibraryA(hook->dll);
if (dll == NULL) { 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); GetLastError(), hook->name);
hook = hook->next; hook = hook->next;
continue; continue;
@ -169,16 +169,16 @@ void setup_hooks() {
// (TrueGetProcAddress ? TrueGetProcAddress : GetProcAddress)(dll, hook->name); // (TrueGetProcAddress ? TrueGetProcAddress : GetProcAddress)(dll, hook->name);
void* original = GetProcAddress(dll, hook->name); void* original = GetProcAddress(dll, hook->name);
if (original == NULL) { 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()); GetLastError());
} else { } else {
void* gateway = CreateHook32(original, hook->patch); void* gateway = CreateHook32(original, hook->patch);
if (hook->store != NULL) *hook->store = gateway; 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; hook = hook->next;
} while (hook != NULL); } 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/files.h"
#include "../hooks/logging.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 WCHAR exeName[MAX_PATH + 1];
extern DWORD imageOffset; extern DWORD imageOffset;
@ -32,7 +40,6 @@ char* log_prelude() {
} }
static HANDLE log_file = NULL; static HANDLE log_file = NULL;
VOID trace_hook(char* output);
CRITICAL_SECTION logger_lock; CRITICAL_SECTION logger_lock;
static char* log_colours[] = { static char* log_colours[] = {
@ -47,21 +54,21 @@ static char* log_colours[] = {
static const char* COLOR_RESET = "\033[0m"; static const char* COLOR_RESET = "\033[0m";
#define LOG_PREFIXES "!GEWIMT" #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) { void __stdcall amLogCallback(DWORD level, char* format) {
if (level == 0) if (level == 0)
log_game("amLog:E", format); log_game(plfAmLog, "E:%s", format);
else if (level == 0) else if (level == 0)
log_game("amLog:W", format); log_game(plfAmLog, "W:%s", format);
else else
log_game("amLog:I", format); log_game(plfAmLog, "I:%s", format);
} }
DWORD pLogcb; DWORD pLogcb;
DWORD* ppLogcb; DWORD* ppLogcb;
static char log_buf[1024]; 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 // TODO: These are all horrible bodges
if (wcscmp(exeName, L"mxnetwork.exe") == 0) { if (wcscmp(exeName, L"mxnetwork.exe") == 0) {
// *((DWORD*)(imageOffset + 0x004438e8)) = (DWORD)(&logcb); // *((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 col_len = strlen(log_colours[log_level]);
int log_len = snprintf(log_buf, _countof(log_buf), "%s%s%c:%s:", 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 += 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_len += snprintf(log_buf + log_len, _countof(log_buf) - log_len, "%s\n", COLOR_RESET);
log_buf[_countof(log_buf) - 1] = '\0'; 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); LeaveCriticalSection(&logger_lock);
return log_len; return log_len;
} }
int vlog_trace(const char* caller, const char* format, va_list args) { int vlog_trace(PLOG_FACILITY facility, const char* format, va_list args) {
return _do_log(LOG_TRACE, caller, format, 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_list args;
va_start(args, format); va_start(args, format);
int ret = vlog_trace(caller, format, args); int ret = vlog_trace(facility, format, args);
va_end(args); va_end(args);
return ret; return ret;
} }
int vlog_misc(const char* caller, const char* format, va_list args) { int vlog_misc(PLOG_FACILITY facility, const char* format, va_list args) {
return _do_log(LOG_MISC, caller, format, 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_list args;
va_start(args, format); va_start(args, format);
int ret = vlog_misc(caller, format, args); int ret = vlog_misc(facility, format, args);
va_end(args); va_end(args);
return ret; return ret;
} }
int vlog_info(const char* caller, const char* format, va_list args) { int vlog_info(PLOG_FACILITY facility, const char* format, va_list args) {
return _do_log(LOG_INFO, caller, format, 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_list args;
va_start(args, format); va_start(args, format);
int ret = vlog_info(caller, format, args); int ret = vlog_info(facility, format, args);
va_end(args); va_end(args);
return ret; return ret;
} }
int vlog_warning(const char* caller, const char* format, va_list args) { int vlog_warning(PLOG_FACILITY facility, const char* format, va_list args) {
return _do_log(LOG_WARNING, caller, format, 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_list args;
va_start(args, format); va_start(args, format);
int ret = vlog_warning(caller, format, args); int ret = vlog_warning(facility, format, args);
va_end(args); va_end(args);
return ret; return ret;
} }
int vlog_error(const char* caller, const char* format, va_list args) { int vlog_error(PLOG_FACILITY facility, const char* format, va_list args) {
return _do_log(LOG_ERROR, caller, format, 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_list args;
va_start(args, format); va_start(args, format);
int ret = vlog_error(caller, format, args); int ret = vlog_error(facility, format, args);
va_end(args); va_end(args);
return ret; return ret;
} }
int vlog_game(const char* caller, const char* format, va_list args) { int vlog_game(PLOG_FACILITY facility, const char* format, va_list args) {
return _do_log(LOG_GAME, caller, format, 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_list args;
va_start(args, format); va_start(args, format);
int ret = vlog_game(caller, format, args); int ret = vlog_game(facility, format, args);
va_end(args); va_end(args);
return ret; return ret;
} }
VOID trace_hook(char* output) {
output[strcspn(output, "\n")] = 0;
log_error("trace", output);
}
void setup_logging() { void setup_logging() {
// Force stdio even for GUI applications // Force stdio even for GUI applications
AttachConsole(ATTACH_PARENT_PROCESS); // AttachConsole(ATTACH_PARENT_PROCESS);
// Enable colour in CMD // Enable colour in CMD
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 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 name[MAX_PATH * sizeof(TCHAR)];
char Storage[sizeof(IMAGEHLP_SYMBOL64) + sizeof(name)]; 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); SymGetSymFromAddr64(process, (ULONG64)stack.AddrPC.Offset, &displacement, symbol);
UnDecorateSymbolName(symbol->Name, (PSTR)name, sizeof(name), UNDNAME_COMPLETE); 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.AddrPC.Offset, (ULONG64)stack.AddrStack.Offset,
(ULONG64)stack.AddrFrame.Offset, symbol->Name); (ULONG64)stack.AddrFrame.Offset, symbol->Name);

View File

@ -10,27 +10,33 @@
#define LOG_MISC 5 #define LOG_MISC 5
#define LOG_TRACE 6 #define LOG_TRACE 6
#define COMM_LOGGER "comm" typedef struct {
#define HOOKS_LOGGER "hooks" char* m_name;
#define BOOT_LOGGER "boot" } 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; extern CRITICAL_SECTION logger_lock;
int _log_trace(const char* caller, const char* format, ...); int _log_trace(PLOG_FACILITY facility, const char* format, ...);
int _log_misc(const char* caller, const char* format, ...); int _log_misc(PLOG_FACILITY facility, const char* format, ...);
int _log_info(const char* caller, const char* format, ...); int _log_info(PLOG_FACILITY facility, const char* format, ...);
int _log_warning(const char* caller, const char* format, ...); int _log_warning(PLOG_FACILITY facility, const char* format, ...);
int _log_error(const char* caller, const char* format, ...); int _log_error(PLOG_FACILITY facility, const char* format, ...);
int _log_game(const char* caller, 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_trace(PLOG_FACILITY facility, const char* format, va_list args);
int vlog_misc(const char* caller, const char* format, va_list args); int vlog_misc(PLOG_FACILITY facility, const char* format, va_list args);
int vlog_info(const char* caller, const char* format, va_list args); int vlog_info(PLOG_FACILITY facility, const char* format, va_list args);
int vlog_warning(const char* caller, const char* format, va_list args); int vlog_warning(PLOG_FACILITY facility, const char* format, va_list args);
int vlog_error(const char* caller, const char* format, va_list args); int vlog_error(PLOG_FACILITY facility, const char* format, va_list args);
int vlog_game(const char* caller, 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(); 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); _CreateFileA(path, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hObject == INVALID_HANDLE_VALUE) { 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; return hObject;
@ -152,3 +152,38 @@ void make_dirs(const char* path) {
} }
free(temp); 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 SOCKET_INVAL ((SOCKET)-1)
#define HANDLE_INVAL -1 #define HANDLE_INVAL -1
#define TIMEOUT_NONE ((DWORD)-1) #define TIMEOUT_NONE ((timeout_t)-1)
#define PCPT_CLOSED 0 #define PCPT_CLOSED 0
#define PCPT_LISTENING 1 #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_after_cb = NULL;
stream->binary_mode_before_data = NULL; stream->binary_mode_before_data = NULL;
stream->binary_mode_after_data = NULL; stream->binary_mode_after_data = NULL;
stream->before_cb = NULL;
ZERO(stream->recv_data); ZERO(stream->recv_data);
ZERO(stream->send_data); ZERO(stream->send_data);
return e_pcpa_ok; 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; 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_max = callbacks_max;
stream->callback_table = callback_table; stream->callback_table = callback_table;
@ -276,7 +277,7 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
case pcpa_state_none: case pcpa_state_none:
amiTimerGet(&time); amiTimerGet(&time);
ms = _amTimeDelta(time, time_start); ms = _amTimeDelta(time, time_start);
if (timeout_ms != -1) { if (timeout_ms != TIMEOUT_NONE) {
if (ms < (uint)timeout_ms) { if (ms < (uint)timeout_ms) {
timeout = timeout_ms - ms; timeout = timeout_ms - ms;
local_14 = timeout; local_14 = timeout;
@ -294,9 +295,10 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
if (eVar4 == e_pcpa_ok) { if (eVar4 == e_pcpa_ok) {
stream->state = 10; stream->state = 10;
amiTimerGet(&time); amiTimerGet(&time);
if (timeout_ms != -1) { if (timeout_ms != TIMEOUT_NONE &&
ms = _amTimeDelta(time, time_start); _amTimeDelta(time, time_start) >= timeout_ms) {
goto joined_r0x00454a58; stream->err = e_pcpa_to;
return stream->err;
} }
} else { } else {
stream->state = pcpa_state_none; stream->state = pcpa_state_none;
@ -311,7 +313,7 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
case 9: case 9:
amiTimerGet(&time); amiTimerGet(&time);
ms = _amTimeDelta(time, time_start); ms = _amTimeDelta(time, time_start);
if (timeout_ms != -1) { if (timeout_ms != TIMEOUT_NONE) {
if (ms < (uint)timeout_ms) { if (ms < (uint)timeout_ms) {
timeout = timeout_ms - ms; timeout = timeout_ms - ms;
local_14 = timeout; 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) { if (stream->binary_mode == binary_mode_none) {
stream->state = (stream->state != pcpa_state_wait_request) - 1 & 10; stream->state = (stream->state != pcpa_state_wait_request) - 1 & 10;
amiTimerGet(&time); amiTimerGet(&time);
if (timeout_ms != -1) { if (timeout_ms != TIMEOUT_NONE &&
ms = _amTimeDelta(time, time_start); _amTimeDelta(time, time_start) >= timeout_ms) {
joined_r0x00454a58: stream->err = e_pcpa_to;
if ((uint)timeout_ms <= ms) { return stream->err;
stream->err = e_pcpa_to;
return stream->err;
}
} }
} else { } else {
pcpaCloseBinary(stream); pcpaCloseBinary(stream);
@ -351,9 +350,10 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
stream->binary_mode_after_cb = NULL; stream->binary_mode_after_cb = NULL;
} }
amiTimerGet(&time); amiTimerGet(&time);
if (timeout_ms != -1) { if (timeout_ms != TIMEOUT_NONE &&
ms = _amTimeDelta(time, time_start); _amTimeDelta(time, time_start) >= timeout_ms) {
goto joined_r0x00454a58; stream->err = e_pcpa_to;
return stream->err;
} }
} }
} else { } else {
@ -378,9 +378,8 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
stream->binary_mode_before_cb = NULL; stream->binary_mode_before_cb = NULL;
} }
amiTimerGet(&time); amiTimerGet(&time);
ms = _amTimeDelta(time, time_start); if (timeout_ms != TIMEOUT_NONE) {
if (timeout_ms != -1) { if (_amTimeDelta(time, time_start) > timeout_ms) {
if (ms < (uint)timeout_ms) {
timeout = timeout_ms - ms; timeout = timeout_ms - ms;
local_14 = timeout; local_14 = timeout;
} else { } else {
@ -403,9 +402,10 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
if (stream->err == e_pcpa_ok) { if (stream->err == e_pcpa_ok) {
LAB_00454a1a: LAB_00454a1a:
amiTimerGet(&time); amiTimerGet(&time);
if (timeout_ms != -1) { if (timeout_ms != TIMEOUT_NONE &&
ms = _amTimeDelta(time, time_start); _amTimeDelta(time, time_start) >= timeout_ms) {
goto joined_r0x00454a58; stream->err = e_pcpa_to;
return stream->err;
} }
} else { } else {
PCP_LOG("error pcpaSendBinary\n"); PCP_LOG("error pcpaSendBinary\n");
@ -421,7 +421,7 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
} }
amiTimerGet(&time); amiTimerGet(&time);
ms = _amTimeDelta(time, time_start); ms = _amTimeDelta(time, time_start);
if (timeout_ms != -1) { if (timeout_ms != TIMEOUT_NONE) {
if (ms < (uint)timeout_ms) { if (ms < (uint)timeout_ms) {
timeout = timeout_ms - ms; timeout = timeout_ms - ms;
local_14 = timeout; local_14 = timeout;
@ -447,9 +447,9 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
} }
break; break;
case 10: 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); stream->before_cb(stream, stream->pcpp.sock.recv_buf);
}
if (stream->callback_table == NULL) { if (stream->callback_table == NULL) {
PCP_LOG("error Callback_table buffer isn\'t set\n"); 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: LAB_004547f1:
amiTimerGet(&time); amiTimerGet(&time);
ms = _amTimeDelta(time, time_start); ms = _amTimeDelta(time, time_start);
if (timeout_ms != -1) { if (timeout_ms != TIMEOUT_NONE) {
if (ms < (uint)timeout_ms) { if (ms < (uint)timeout_ms) {
local_14 = timeout_ms - ms; local_14 = timeout_ms - ms;
} else { } else {
@ -514,9 +514,9 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
} }
amiTimerGet(&time); amiTimerGet(&time);
timeout = local_14; timeout = local_14;
if (timeout_ms != TIMEOUT_NONE) { if (timeout_ms != TIMEOUT_NONE && _amTimeDelta(time, time_start) >= timeout_ms) {
ms = _amTimeDelta(time, time_start); stream->err = e_pcpa_to;
goto joined_r0x00454a58; return stream->err;
} }
} }
} while (stream->err == e_pcpa_ok); } while (stream->err == e_pcpa_ok);

View File

@ -11,7 +11,8 @@ typedef enum e_pcpa {
e_pcpa_cannot_open = -2, e_pcpa_cannot_open = -2,
e_pcpa_generic = -3, e_pcpa_generic = -3,
e_pcpa_param_invalid = -4, 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_cb_table_full = -9,
e_pcpa_stream_unset = -10, e_pcpa_stream_unset = -10,
e_pcpa_cb_table_unset = -11, 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; return sock->err = e_pcpt_not_open;
} }
// TODO: URGENT: Something in the FSM causes this condition to error out! // TODO: URGENT: Something in the FSM causes this condition to error out!
// if (sock->client_open != 0) { if (sock->client_open != 0) {
// PCP_LOG("error PCP already connected\n"); PCP_LOG("error PCP already connected\n");
// return sock->err = e_pcpt_already_connected; return sock->err = e_pcpt_already_connected;
// } }
sock->recv_buf = recv_buf; sock->recv_buf = recv_buf;
sock->recv_buf_count = recv_buf_len; 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++) { for (int board = 0; board < MiceConfig.keys.board_count; board++) {
i += snprintf(keybindBuffer + i, _countof(keybindBuffer) - i, "%d,", i += snprintf(keybindBuffer + i, _countof(keybindBuffer) - i, "%d,",
jvsKeybindings[board].test); 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++) { for (int n = 0; n < JVS_BUTTON_PAIR_COUNT * 2; n++) {
i += snprintf(keybindBuffer + i, _countof(keybindBuffer) - i, "%d,", i += snprintf(keybindBuffer + i, _countof(keybindBuffer) - i, "%d,",
jvsKeybindings[board].buttons[n]); jvsKeybindings[board].buttons[n]);
@ -228,13 +230,16 @@ void load_mice_config() {
if (state == 0) { if (state == 0) {
jvsKeybindings[board].test = val; jvsKeybindings[board].test = val;
state = 1; state = 1;
} else if (state == 1) {
jvsKeybindings[board].notdefault = val;
state = 2;
} else { } else {
if (state == 1) { if (state == 2) {
jvsKeybindings[board].buttons[n] = val; jvsKeybindings[board].buttons[n] = val;
state = 2; state = 3;
} else { } else {
jvsKeybindings[board].invert[n] = val; jvsKeybindings[board].invert[n] = val;
state = 1; state = 2;
if (n++ == JVS_BUTTON_PAIR_COUNT * 2) { if (n++ == JVS_BUTTON_PAIR_COUNT * 2) {
n = 0; n = 0;
state = 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, "") CFG_hex(network, mac, 6, 0A2F1D, "")
ENDSECTION(network) 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.") SECTION(drivers, "Enable or disable drivers. Disabling any is not recommended.")
CFG_bool(drivers, columba, true, "") CFG_bool(drivers, columba, true, "")
CFG_bool(drivers, mxsram, true, "") CFG_bool(drivers, mxsram, true, "")
@ -102,6 +96,18 @@ CFG_int(keys, board_count, 1, "")
CFG_str(keys, keys, 0, "") CFG_str(keys, keys, 0, "")
ENDSECTION(keys) 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_str
#undef CFG_int #undef CFG_int
#undef CFG_bool #undef CFG_bool

View File

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

View File

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

View File

@ -1,131 +1,234 @@
#include "mxk.h" #include "mxk.h"
BOOL mxkExchengeAesKey(HANDLE mxparallel) { unsigned int KEYCHIP_STATUS;
FILETIME filetime; unsigned char KEYCHIP_ERROR;
amtime_t now;
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_s[16];
unsigned char key_r[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]; unsigned char packet[16];
mxkPacketReqSetKeyS(packet); mxkPacketReqRandomBytes(key_s);
if (!mxkSendPacket(mxparallel, packet)) return FALSE; mxkPacketReqRandomBytes(key_r);
if (!mxkSendPacket(mxparallel, key_s)) return FALSE;
if (!mxkRecvPacket(mxparallel, packet)) return FALSE; if (mxkPacketReqSetKeyS(packet) != MXK_STATUS_OK) {
if (packet[0] != SetKeyS) return FALSE; 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); mxkSetKeyS(key_s);
mxkPacketReqSetKeyR(packet); if (mxkPacketReqSetKeyR(packet) != MXK_STATUS_OK) {
if (!mxkSendPacket(mxparallel, packet)) return FALSE; amiDebugLog("Error mxkPacketReqSetKeyR");
if (!mxkSendPacket(mxparallel, key_r)) return FALSE; 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); 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]; unsigned char packet[16];
mxkPacketReqGetVersion(packet); if (version == NULL || err == NULL) return MXK_STATUS_INVALID_PARAM;
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
if (!mxkRecvPacket(mxparallel, packet)) return FALSE;
*version = ((unsigned short*)packet)[0]; if (KEYCHIP_STATUS == 2) {
return TRUE; 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]; unsigned char packet[16];
mxkPacketReqSetMainId(packet); mxkPacketReqSetMainId(packet);
if (!mxkSendPacket(mxparallel, packet)) return FALSE; if (!mxkSendPacket(packet)) return FALSE;
if (!mxkSendPacket(mxparallel, main_id)) return FALSE; if (!mxkSendPacket(main_id)) return FALSE;
mxkRecvPacket(mxparallel, packet); mxkRecvPacket(packet);
return packet[0] != 0xff; return packet[0] != 0xff;
} }
BOOL mxkGetMainId(HANDLE mxparallel, unsigned char* main_id) { BOOL mxkGetMainId(unsigned char* main_id) {
unsigned char packet[16]; unsigned char packet[16];
mxkPacketReqGetMainId(packet); mxkPacketReqGetMainId(packet);
if (!mxkSendPacket(mxparallel, packet)) return FALSE; if (!mxkSendPacket(packet)) return FALSE;
if (!mxkRecvPacket(mxparallel, main_id)) return FALSE; if (!mxkRecvPacket(main_id)) return FALSE;
return TRUE; return TRUE;
} }
BOOL mxkGetKeyId(HANDLE mxparallel, unsigned char* key_id) { BOOL mxkGetKeyId(unsigned char* key_id) {
unsigned char packet[16]; unsigned char packet[16];
mxkPacketReqGetKeyId(packet); mxkPacketReqGetKeyId(packet);
if (!mxkSendPacket(mxparallel, packet)) return FALSE; if (!mxkSendPacket(packet)) return FALSE;
if (!mxkRecvPacket(mxparallel, key_id)) return FALSE; if (!mxkRecvPacket(key_id)) return FALSE;
return TRUE; return TRUE;
} }
BOOL mxkGetAppBootInfo(HANDLE mxparallel, appboot_t* appboot) {
unsigned char packet[16];
mxkPacketReqGetAppBootInfo(packet); BOOL mxkGetPlayCounter(DWORD* play_counter) {
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) {
unsigned char packet[16]; unsigned char packet[16];
mxkPacketReqGetPlayCounter(packet); mxkPacketReqGetPlayCounter(packet);
if (!mxkSendPacket(mxparallel, packet)) return FALSE; if (!mxkSendPacket(packet)) return FALSE;
if (!mxkRecvPacket(mxparallel, packet)) return FALSE; if (!mxkRecvPacket(packet)) return FALSE;
*play_counter = ((DWORD*)packet)[0]; *play_counter = ((DWORD*)packet)[0];
return TRUE; return TRUE;
} }
BOOL mxkFlashRead(HANDLE mxparallel, unsigned int address, unsigned int nbytes, BOOL mxkFlashRead(unsigned int address, unsigned int nbytes, unsigned char* buffer) {
unsigned char* buffer) {
unsigned char packet[16]; unsigned char packet[16];
mxkPacketReqFlashRead(packet, address, nbytes); mxkPacketReqFlashRead(packet, address, nbytes);
if (!mxkSendPacket(mxparallel, packet)) return FALSE; if (!mxkSendPacket(packet)) return FALSE;
for (size_t i = 0; i < nbytes; i += 0x100) { for (size_t i = 0; i < nbytes; i += 0x100) {
unsigned int rest = (nbytes - i) > 0x100 ? 0x100 : (nbytes - i); 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; return TRUE;
} }
BOOL mxkEepromRead(HANDLE mxparallel, unsigned char page, unsigned char* data) { BOOL mxkEepromRead(unsigned char page, unsigned char* data) {
unsigned char packet[16]; unsigned char packet[16];
mxkPacketReqEepromRead(packet, page); mxkPacketReqEepromRead(packet, page);
if (!mxkSendPacket(mxparallel, packet)) return FALSE; if (!mxkSendPacket(packet)) return FALSE;
if (!mxkRecvPacket(mxparallel, data)) return FALSE; if (!mxkRecvPacket(data)) return FALSE;
return TRUE; 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]; unsigned char packet[16];
mxkPacketReqNvramRead(packet, addr, blocks); mxkPacketReqNvramRead(packet, addr, blocks);
if (!mxkSendPacket(mxparallel, packet)) return FALSE; if (!mxkSendPacket(packet)) return FALSE;
for (size_t i = 0; i < blocks; i++) { 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; 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 #pragma once
#include <Windows.h> #include <Windows.h>
#include <stdbool.h>
#include "../ami/ami.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_PRIVKEY[917];
extern unsigned char BILLING_PUBKEY[162]; extern unsigned char BILLING_PUBKEY[162];
extern unsigned char BILLING_CACERT[817]; extern unsigned char BILLING_CACERT[817];
extern unsigned char KEYCHIP_ID[16]; extern unsigned char KEYCHIP_ID[16];
extern unsigned char MAIN_ID[16]; extern unsigned char MAIN_ID[16];
enum { MXK_STATUS mxkInit(void);
SetKeyS = 0, // mxkPacketReqSetKeyS [0] [... MXK_STATUS mxkExchengeAesKey(void);
SetKeyR = 1, // mxkPacketReqSetKeyR [1] [... MXK_STATUS mxkVersion(unsigned short* version, MXK_CACHE cache, unsigned char* err);
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 // MXK
BOOL mxkExchengeAesKey(HANDLE mxparallel); BOOL mxkSetMainId(const unsigned char* main_id);
BOOL mxkVersion(HANDLE mxparallel, unsigned short* version); BOOL mxkGetMainId(unsigned char* main_id);
BOOL mxkSetMainId(HANDLE mxparallel, const unsigned char* main_id); BOOL mxkGetKeyId(unsigned char* main_id);
BOOL mxkGetMainId(HANDLE mxparallel, unsigned char* main_id); BOOL mxkGetPlayCounter(DWORD* play_counter);
BOOL mxkGetKeyId(HANDLE mxparallel, unsigned char* main_id); BOOL mxkFlashRead(unsigned int address, unsigned int nbytes, unsigned char* buffer);
BOOL mxkGetAppBootInfo(HANDLE mxparallel, appboot_t* appboot); BOOL mxkEepromRead(unsigned char page, unsigned char* data);
BOOL mxkGetPlayCounter(HANDLE mxparallel, DWORD* play_counter); BOOL mxkNvramRead(unsigned short addr, unsigned char blocks, unsigned char* data);
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);

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/evp.h>
#include <openssl/pem.h> #include <openssl/pem.h>
#include <openssl/hmac.h>
#include "mxk.h" // 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,
unsigned char KEY_R[16] = { // 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, 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, 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[] = unsigned char BILLING_PRIVKEY[] =
("-----BEGIN PRIVATE KEY-----\n" ("-----BEGIN PRIVATE KEY-----\n"
@ -96,6 +102,48 @@ unsigned char BILLING_CACERT[] = {
0xca, 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 mxkSetKeyS(unsigned char* key_s) { memcpy(KEY_S, key_s, 16); }
void mxkSetKeyR(unsigned char* key_r) { memcpy(KEY_R, key_r, 16); } void mxkSetKeyR(unsigned char* key_r) { memcpy(KEY_R, key_r, 16); }
void mxkSwapKeys() { void mxkSwapKeys() {
@ -105,7 +153,13 @@ void mxkSwapKeys() {
memcpy(KEY_S, temp, 16); 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_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv, 1); 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]; unsigned char dump[16];
EVP_EncryptFinal_ex(ctx, dump, &outl); EVP_EncryptFinal_ex(ctx, dump, &outl);
EVP_CIPHER_CTX_free(ctx); 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_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv, 0); 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]; unsigned char dump[16];
EVP_EncryptFinal_ex(ctx, dump, &outl); EVP_EncryptFinal_ex(ctx, dump, &outl);
EVP_CIPHER_CTX_free(ctx); 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_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
EVP_CipherInit_ex(ctx, EVP_aes_128_ecb(), NULL, KEY_S, NULL, 1); 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; int outl;
EVP_EncryptUpdate(ctx, ct, &outl, pt, 16); EVP_EncryptUpdate(ctx, ct, &outl, pt, 16);
unsigned char dump[16]; unsigned char dump[16];
EVP_EncryptFinal_ex(ctx, dump, &outl); EVP_EncryptFinal_ex(ctx, dump, &outl);
EVP_CIPHER_CTX_free(ctx); 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_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
EVP_CipherInit_ex(ctx, EVP_aes_128_ecb(), NULL, KEY_R, NULL, 0); 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; int outl;
EVP_DecryptUpdate(ctx, pt, &outl, ct, 16); EVP_DecryptUpdate(ctx, pt, &outl, ct, 16);
unsigned char dump[16]; unsigned char dump[16];
EVP_EncryptFinal_ex(ctx, dump, &outl); EVP_EncryptFinal_ex(ctx, dump, &outl);
EVP_CIPHER_CTX_free(ctx); EVP_CIPHER_CTX_free(ctx);
return MXK_STATUS_OK;
} }
void mxkSign(void* buffer, size_t nbytes, unsigned char* signature) { void mxkSign(void* buffer, size_t nbytes, unsigned char* signature) {
@ -172,6 +258,8 @@ typedef struct {
} sign_payload_t; } sign_payload_t;
#pragma pack(pop) #pragma pack(pop)
// TODO: Move this all
unsigned char KEYCHIP_ID[16];
void mxkSignValue(unsigned int value, unsigned char* signature) { void mxkSignValue(unsigned int value, unsigned char* signature) {
sign_payload_t hash_data; sign_payload_t hash_data;
hash_data.value = value; 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); memcpy(hash_data.key_high, &KEYCHIP_ID[5], 7);
mxkSign(&hash_data, sizeof hash_data, signature); 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) { void inline _mxkPacketInjectJunk(unsigned char* packet, size_t i) {
FILETIME filetime; 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; packet[0] = SetKeyS;
_mxkPacketInjectJunk(packet, 1); _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; packet[0] = SetKeyR;
_mxkPacketInjectJunk(packet, 1); _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[0] = GetAppBootInfo;
packet[1] = 0; packet[1] = 0;
_mxkPacketInjectJunk(packet, 2); _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[0] = EepromRead;
packet[1] = page; packet[1] = page;
_mxkPacketInjectJunk(packet, 2); _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; packet[0] = KcGetVersion;
_mxkPacketInjectJunk(packet, 1); _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; packet[0] = SetMainId;
_mxkPacketInjectJunk(packet, 1); _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; packet[0] = GetMainId;
_mxkPacketInjectJunk(packet, 1); _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; packet[0] = GetKeyId;
_mxkPacketInjectJunk(packet, 1); _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; packet[0] = GetPlayCounter;
_mxkPacketInjectJunk(packet, 1); _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[0] = FlashRead;
packet[1] = address & 0xff; packet[1] = address & 0xff;
packet[2] = (address >> 8) & 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[5] = (nbytes >> 8) & 0xff;
packet[6] = (nbytes >> 16) & 0xff; packet[6] = (nbytes >> 16) & 0xff;
_mxkPacketInjectJunk(packet, 7); _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[0] = NvramRead;
packet[1] = addr & 0xff; packet[1] = addr & 0xff;
packet[2] = (addr >> 8) & 0xff; packet[2] = (addr >> 8) & 0xff;
packet[3] = blocks; packet[3] = blocks;
_mxkPacketInjectJunk(packet, 4); _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 "../mice/ioctl.h"
#include "mxk.h" #include "mxkCrypt.h"
// TODO: Don't use puts! // TODO: Don't use puts!
#include <stdio.h> #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; BOOL DO_SLEEP_0 = TRUE;
#define ReadStatus(mxparallel, status, nret) \ #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; BYTE status;
DWORD nbytes = 0; DWORD nbytes = 0;
ReadStatus(mxparallel, status, nbytes); if (!ReadStatus(mxkTransport.m_hParallel, status, nbytes)) {
status &= 0x80; amiDebugLog("Error mxkTransportWaitStrobeReady 1");
return MXK_TRANSPORT_STATUS_NG;
}
status &= PARALLEL_STATUS_BUSY;
if (status != 0) { if (status != 0) {
ReadStatus(mxparallel, status, nbytes); if (!ReadStatus(mxkTransport.m_hParallel, status, nbytes)) {
if ((status & 0x80) != 0) return FALSE; 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; BYTE status;
DWORD nbytes = 0; DWORD nbytes = 0;
ReadStatus(mxparallel, status, nbytes); if (!ReadStatus(mxkTransport.m_hParallel, status, nbytes)) {
status &= 0x80; amiDebugLog("Error mxkTransportWaitStrobeRelease 1");
return MXK_TRANSPORT_STATUS_NG;
}
status &= PARALLEL_STATUS_BUSY;
if (status == 0) { if (status == 0) {
ReadStatus(mxparallel, status, nbytes); if (!ReadStatus(mxkTransport.m_hParallel, status, nbytes)) {
if ((status & 0x80) == 0) return FALSE; 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; return TRUE;
} }
void mxkTransportCtrlPortInAndOut(HANDLE mxparallel, BYTE flag) { static BOOL mxkTransportCtrlPortInOrOut(BYTE flag) {
BYTE ctrl; BYTE ctrl;
DWORD nbytes = 0; 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,
ctrl &= flag; 1, &nbytes, NULL)) {
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_WRITE_CTRL_PORT, &ctrl, 1, NULL, 0, &nbytes, NULL); amiDebugLog("Error mxkTransportCtrlPortInOrOut 1");
} return FALSE;
}
void mxkTransportCtrlPortInOrOut(HANDLE mxparallel, BYTE flag) {
BYTE ctrl;
DWORD nbytes = 0;
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_READ_CTRL_PORT, NULL, 0, &ctrl, 1, &nbytes, NULL);
ctrl |= flag; 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; DWORD nret;
BYTE status; BYTE status;
MXK_TRANSPORT_STATUS err;
amtime_t start; amtime_t start;
amtime_t now; 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++) { for (size_t i = 0; i < nbytes; i++) {
amiTimerGet(&start); amiTimerGet(&start);
do { do {
ReadStatus(mxparallel, status, nret); if (!ReadStatus(mxkTransport.m_hParallel, status, nret)) {
status &= 0x40; amiDebugLog("Error mxkTransportSend 1");
return MXK_TRANSPORT_STATUS_SEND_NG;
}
status &= PARALLEL_STATUS_ACK;
if (status == 0) break; if (status == 0) break;
amiTimerGet(&now); amiTimerGet(&now);
if (DO_SLEEP_0) Sleep(0); if (DO_SLEEP_0) Sleep(0);
} while (amiTimerDiffUsec(&start, &now) < 1000000); } while (amiTimerDiffUsec(&start, &now) < 1000000);
if (status != 0) { if (status != 0) {
puts("SEND busy error"); amiDebugLog("SEND busy error");
return FALSE; 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); amiTimerGet(&now);
if (DO_SLEEP_0) Sleep(0); if (DO_SLEEP_0) Sleep(0);
if (amiTimerDiffUsec(&start, &now) > 999999) { if (amiTimerDiffUsec(&start, &now) > 999999) {
puts("SEND busy error"); amiDebugLog("state_busy != 0 // timeout?");
return FALSE; 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); if (!mxkTransportCtrlPortInAndOut(~PARALLEL_CONTROL_BIDI & 0xff)) {
mxkTransportCtrlPortInOrOut(mxparallel, 0x01); 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); amiTimerGet(&now);
if (DO_SLEEP_0) Sleep(0); if (DO_SLEEP_0) Sleep(0);
if (amiTimerDiffUsec(&start, &now) > 999999'000) { if (amiTimerDiffUsec(&start, &now) > 999999'000) {
puts("SEND end error"); amiDebugLog("RA1が1でエラー");
return FALSE; return MXK_TRANSPORT_STATUS_SEND_NG;
} }
} }
mxkTransportCtrlPortInOrOut(mxparallel, 0x20); if (!mxkTransportCtrlPortInOrOut(PARALLEL_CONTROL_BIDI)) {
mxkTransportCtrlPortInAndOut(mxparallel, 0xfe); 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; BYTE status;
DWORD nret; DWORD nret;
MXK_TRANSPORT_STATUS err;
amtime_t now; amtime_t now;
amtime_t start; 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++) { for (size_t i = 0; i < nbytes; i++) {
amiTimerGet(&start); amiTimerGet(&start);
do { do {
ReadStatus(mxparallel, status, nret); if (!ReadStatus(mxkTransport.m_hParallel, status, nret)) {
status &= 0x40; amiDebugLog("Error mxkTransportRecv 1");
return MXK_TRANSPORT_STATUS_RECV_NG;
}
status &= PARALLEL_STATUS_ACK;
if (status != 0) break; if (status != 0) break;
amiTimerGet(&now); amiTimerGet(&now);
if (DO_SLEEP_0 != 0) Sleep(0); if (DO_SLEEP_0 != 0) Sleep(0);
} while (amiTimerDiffUsec(&start, &now) < 1000000'000); } while (amiTimerDiffUsec(&start, &now) < 1000000);
if (status == 0) { if (status == 0) {
puts("RECV busy error 1"); amiDebugLog("RECV busy error 1");
return FALSE; 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); amiTimerGet(&now);
if (DO_SLEEP_0 != 0) Sleep(0); if (DO_SLEEP_0 != 0) Sleep(0);
if (amiTimerDiffUsec(&start, &now) > 999999'000) { if (amiTimerDiffUsec(&start, &now) > 999999) {
puts("RECV busy error 2"); amiDebugLog("RECV busy error 2");
return FALSE; return MXK_TRANSPORT_STATUS_RECV_NG;
} }
} }
mxkTransportCtrlPortInOrOut(mxparallel, 0x20); if (!mxkTransportCtrlPortInOrOut(PARALLEL_CONTROL_BIDI)) {
mxkTransportCtrlPortInOrOut(mxparallel, 0x01); 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); amiTimerGet(&now);
if (DO_SLEEP_0) Sleep(0); if (DO_SLEEP_0) Sleep(0);
if (amiTimerDiffUsec(&start, &now) > 999999) { if (amiTimerDiffUsec(&start, &now) > 999999) {
puts("RECV end error"); amiDebugLog("RECV end error");
return FALSE; 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) { static BOOL mxkTransportInitPic(void) {
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) {
BYTE flags = 0; BYTE flags = 0;
DWORD nbytes = 0; DWORD nbytes = 0;
Sleep(10); Sleep(10);
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_READ_FLAGS, NULL, 0, &flags, 1, &nbytes, NULL); if (!DeviceIoControl(mxkTransport.m_hParallel, IOCTL_MXPARALLEL_READ_FLAGS, NULL, 0, &flags, 1,
flags = flags & 0x1f | 0x20; &nbytes, NULL)) {
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_WRITE_FLAGS, &flags, 1, NULL, 0, &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); Sleep(10);
flags = 0x24; flags = PARALLEL_CONTROL_BIDI | PARALLEL_CONTROL_INITIALISE;
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_WRITE_CTRL_PORT, &flags, 1, NULL, 0, &nbytes, if (!DeviceIoControl(mxkTransport.m_hParallel, IOCTL_MXPARALLEL_WRITE_CTRL_PORT, &flags, 1,
NULL); NULL, 0, &nbytes, NULL)) {
amiDebugLog("Error KeychipInit 3");
return FALSE;
}
Sleep(10); Sleep(10);
mxkTransportCtrlPortInAndOut(mxparallel, 0xfb); if (!mxkTransportCtrlPortInAndOut(~PARALLEL_CONTROL_INITIALISE & 0xff)) {
amiDebugLog("Error KeychipInit 4");
return FALSE;
}
Sleep(10); Sleep(10);
mxkTransportCtrlPortInOrOut(mxparallel, 0x24); if (!mxkTransportCtrlPortInOrOut(PARALLEL_CONTROL_BIDI | PARALLEL_CONTROL_INITIALISE)) {
amiDebugLog("Error KeychipInit 5");
return FALSE;
}
Sleep(10); 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('lib')
subdir('system_dummy')
subdir('micepatch') subdir('micepatch')
subdir('micekeychip') subdir('micekeychip')
subdir('micemaster') subdir('micemaster')

View File

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

View File

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

View File

@ -43,7 +43,7 @@ typedef struct MX_MASTER_ {
bool m_kcReady; bool m_kcReady;
bool m_pcpaHasInit; bool m_pcpaHasInit;
appLauncher_t* m_appLauncher; appLauncher_t* m_appLauncher;
pcpa_cb_table_t m_pcpCallbacks[11]; pcpa_cb_table_t m_pcpCallbacks[MXM_NUM_CALLBACKS];
pcpa_t m_pcp; pcpa_t m_pcp;
} MX_MASTER; } 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/eeprom.c',
'micedump/kc_mxkeychip.c', 'micedump/kc_mxkeychip.c',
# 'micedump/kc_n2.c', # 'micedump/kc_n2.c',
# 'micedump/kc_pic.c', 'micedump/kc_pic.c',
'micedump/platform.c', 'micedump/platform.c',
'micedump/sram.c', 'micedump/sram.c',
# 'micedump/superio.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(); miceDumpSRAM();
else if (strcmp(argv[i], "dongle") == 0) else if (strcmp(argv[i], "dongle") == 0)
miceDumpKCMxkeychip(); miceDumpKCMxkeychip();
else if (strcmp(argv[i], "kcpic") == 0)
miceDumpKCPIC();
else else
printf("Unknown dump type: %s\n", argv[i]); printf("Unknown dump type: %s\n", argv[i]);
} }

View File

@ -1,8 +1,9 @@
#include <stdio.h>
#include <Windows.h> #include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
char path[MAX_PATH * 1000]; 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("%d", QueryDosDeviceA(NULL, path, sizeof path));
// printf(" %03x\n", GetLastError()); // printf(" %03x\n", GetLastError());
@ -17,33 +18,17 @@ int main(int argc, char** argv) {
DWORD volumeSerialNumber; DWORD volumeSerialNumber;
// Crackproof-style call // Crackproof-style call
BOOL ret = GetVolumeInformationA( BOOL ret = GetVolumeInformationA("C:\\", NULL, 0, &volumeSerialNumber, NULL, NULL, NULL, 0);
"C:\\", printf("volumeSerialNumber: %08x\n", volumeSerialNumber);
NULL,
0,
&volumeSerialNumber,
NULL,
NULL,
NULL,
0
);
printf("volumeSerialNumber: %08x\n");
// Exhaustive call // Exhaustive call
CHAR volumeNameBuffer[MAX_PATH]; CHAR volumeNameBuffer[MAX_PATH];
DWORD maximumComponentLength; DWORD maximumComponentLength;
DWORD fileSystemFlags; DWORD fileSystemFlags;
CHAR fileSystemName[MAX_PATH]; CHAR fileSystemName[MAX_PATH];
ret = GetVolumeInformationA( ret = GetVolumeInformationA("C:\\", volumeNameBuffer, sizeof volumeNameBuffer,
"C:\\", &volumeSerialNumber, &maximumComponentLength, &fileSystemFlags,
volumeNameBuffer, fileSystemName, sizeof fileSystemName);
sizeof volumeNameBuffer,
&volumeSerialNumber,
&maximumComponentLength,
&fileSystemFlags,
fileSystemName,
sizeof fileSystemName
);
printf("volumeNameBuffer: %s\n", volumeNameBuffer); printf("volumeNameBuffer: %s\n", volumeNameBuffer);
printf("volumeSerialNumber: %08x\n", volumeSerialNumber); printf("volumeSerialNumber: %08x\n", volumeSerialNumber);
@ -53,3 +38,43 @@ int main(int argc, char** argv) {
return 0; 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);
}