A bunch of user-friendly things
This commit is contained in:
parent
aef9cb26cb
commit
38ccd51217
5
Makefile
5
Makefile
@ -34,6 +34,7 @@ clean:
|
||||
dist:
|
||||
@-mkdir $(DIST_DIR) > NUL 2>&1
|
||||
@-mkdir $(DIST_DIR)\util > NUL 2>&1
|
||||
@-mkdir $(DIST_DIR)\system_dummy > NUL 2>&1
|
||||
@-mkdir $(DIST_DIR)\Execute > NUL 2>&1
|
||||
@-mkdir $(DIST_DIR)\Execute\Z > NUL 2>&1
|
||||
@-mkdir $(DIST_DIR)\Execute\S > NUL 2>&1
|
||||
@ -54,12 +55,16 @@ dist:
|
||||
|
||||
# @copy /Y "$(BUILD_DIR)/src/micetools/micepatch\micepatch.exe" "$(DIST_DIR)/util/micepatch.exe"
|
||||
@copy /Y "$(BUILD_DIR)/src/micetools/util\micedump.exe" "$(DIST_DIR)/util/micedump.exe"
|
||||
@copy /Y "$(BUILD_DIR)/src/micetools/util\micedump.pdb" "$(DIST_DIR)/util/micedump.pdb"
|
||||
@copy /Y "$(BUILD_DIR)/src/micetools/util\micetinker.exe" "$(DIST_DIR)/util/micetinker.exe"
|
||||
@copy /Y "$(BUILD_DIR)/src/micetools/util\micemonitor.exe" "$(DIST_DIR)/util/micemonitor.exe"
|
||||
@copy /Y "$(BUILD_DIR)/src/micetools/util\exio_test.exe" "$(DIST_DIR)/util/exio_test.exe"
|
||||
@copy /Y "$(BUILD_DIR)/src/micetools/util\dongleDecrypt.exe" "$(DIST_DIR)/util/dongleDecrypt.exe"
|
||||
@copy /Y "$(BUILD_DIR)/src/micetools/util\testBin.exe" "$(DIST_DIR)/util/testBin.exe"
|
||||
|
||||
@copy /Y "$(BUILD_DIR)/src/micetools/system_dummy\dummymaster\dummymaster.exe" "$(DIST_DIR)/system_dummy/dummymaster.exe"
|
||||
@copy /Y "$(BUILD_DIR)/src/micetools/system_dummy\dummyinstaller\dummyinstaller.exe" "$(DIST_DIR)/system_dummy/dummyinstaller.exe"
|
||||
|
||||
@copy /Y "src/micetools/miceboot\TrueCrypt.cmd" "$(DIST_DIR)/Execute/TrueCrypt.cmd"
|
||||
|
||||
@xcopy /E /H /C /R /Q /Y src\system "$(DIST_DIR)\system/*"
|
||||
|
@ -9,7 +9,7 @@ typedef struct {
|
||||
uint32_t m_Gateway;
|
||||
uint32_t m_PrimaryDns;
|
||||
uint32_t m_SecondaryDns;
|
||||
} AM_SYSDATA_NETWORK_IF;
|
||||
} AM_SYSDATA_NETWORK_IF, *PAM_SYSDATA_NETWORK_IF;
|
||||
|
||||
typedef struct {
|
||||
uint64_t m_TimeStamp;
|
||||
@ -28,17 +28,17 @@ typedef struct {
|
||||
uint8_t CreditRate;
|
||||
uint8_t Cost[8];
|
||||
uint8_t Rsv0F;
|
||||
} AM_CREDIT_CONFIG;
|
||||
} AM_CREDIT_CONFIG, *PAM_CREDIT_CONFIG;
|
||||
|
||||
typedef struct {
|
||||
uint8_t Credit;
|
||||
uint8_t Remain;
|
||||
} AM_CREDIT_PDATA;
|
||||
} AM_CREDIT_PDATA, *PAM_CREDIT_PDATA;
|
||||
|
||||
typedef struct {
|
||||
AM_CREDIT_PDATA Player[4];
|
||||
uint8_t Rsv08[8];
|
||||
} AM_CREDIT_DATA;
|
||||
} AM_CREDIT_DATA, *PAM_CREDIT_DATA;
|
||||
|
||||
typedef struct {
|
||||
uint32_t CoinChute[4];
|
||||
@ -46,7 +46,7 @@ typedef struct {
|
||||
uint32_t CoinCredit;
|
||||
uint32_t ServiceCredit;
|
||||
uint32_t TotalCredit;
|
||||
} AM_CREDIT_BOOKKEEPING;
|
||||
} AM_CREDIT_BOOKKEEPING, *PAM_CREDIT_BOOKKEEPING;
|
||||
|
||||
typedef struct {
|
||||
uint8_t m_month;
|
||||
@ -61,7 +61,7 @@ typedef struct {
|
||||
uint32_t m_Crc;
|
||||
uint8_t Rsv04[4];
|
||||
AM_SYSDATA_NETWORK_IF m_Eth;
|
||||
} AM_SYSDATAwH_NETWORK;
|
||||
} AM_SYSDATAwH_NETWORK, *PAM_SYSDATAwH_NETWORK;
|
||||
|
||||
typedef struct {
|
||||
uint32_t m_Crc;
|
||||
@ -70,14 +70,14 @@ typedef struct {
|
||||
uint8_t m_Rental;
|
||||
uint8_t Rsv0F;
|
||||
char m_strSerialId[17];
|
||||
} AM_SYSDATAwH_STATIC;
|
||||
} AM_SYSDATAwH_STATIC, *PAM_SYSDATAwH_STATIC;
|
||||
|
||||
typedef struct {
|
||||
uint32_t m_Crc;
|
||||
uint8_t Rsv04[4];
|
||||
AM_CREDIT_CONFIG m_Config;
|
||||
uint8_t Rsv18[8];
|
||||
} AM_SYSDATAwH_CREDIT;
|
||||
} AM_SYSDATAwH_CREDIT, *PAM_SYSDATAwH_CREDIT;
|
||||
|
||||
typedef AM_SYSDATAwH_NETWORK AM_SYSDATAwH_NETWORK_ETH0;
|
||||
typedef AM_SYSDATAwH_NETWORK AM_SYSDATAwH_NETWORK_ETH1;
|
||||
@ -88,7 +88,7 @@ typedef struct {
|
||||
char m_GameId[4];
|
||||
uint8_t m_Region;
|
||||
uint8_t Rsv0D[3];
|
||||
} AM_SYSDATAwH_HISTORY;
|
||||
} AM_SYSDATAwH_HISTORY, *PAM_SYSDATAwH_HISTORY;
|
||||
|
||||
typedef struct {
|
||||
uint32_t m_Crc;
|
||||
@ -97,7 +97,7 @@ typedef struct {
|
||||
uint8_t m_LogNum;
|
||||
uint8_t Rsv0a[22];
|
||||
ERROR_LOG_BODY m_Body[15];
|
||||
} AM_SYSDATAwH_ERROR_LOG;
|
||||
} AM_SYSDATAwH_ERROR_LOG, *PAM_SYSDATAwH_ERROR_LOG;
|
||||
|
||||
typedef struct {
|
||||
uint32_t m_Crc;
|
||||
@ -105,7 +105,7 @@ typedef struct {
|
||||
AM_CREDIT_DATA m_CreditData;
|
||||
AM_CREDIT_BOOKKEEPING m_Bookkeeping;
|
||||
uint8_t Rsv38[456];
|
||||
} AM_SYSDATAwH_BACKUP;
|
||||
} AM_SYSDATAwH_BACKUP, *PAM_SYSDATAwH_BACKUP;
|
||||
|
||||
typedef struct {
|
||||
uint32_t m_Crc;
|
||||
@ -115,7 +115,7 @@ typedef struct {
|
||||
uint32_t m_Bias;
|
||||
uint32_t m_ServerBias;
|
||||
uint8_t Rsv20[480];
|
||||
} AM_SYSDATAwH_TIMEZONE;
|
||||
} AM_SYSDATAwH_TIMEZONE, *PAM_SYSDATAwH_TIMEZONE;
|
||||
|
||||
typedef struct {
|
||||
uint32_t m_Crc;
|
||||
@ -123,21 +123,21 @@ typedef struct {
|
||||
uint32_t m_Caution;
|
||||
uint32_t m_Peak;
|
||||
uint8_t Rsv10[496];
|
||||
} AM_SYSDATAwH_HM_PEAK;
|
||||
} AM_SYSDATAwH_HM_PEAK, *PAM_SYSDATAwH_HM_PEAK;
|
||||
|
||||
typedef struct {
|
||||
uint32_t m_Crc;
|
||||
uint8_t Rsv04[4];
|
||||
uint8_t m_MountSleepS;
|
||||
uint8_t Rsv09[55];
|
||||
} AM_SYSDATAwH_ALPB_DEV_CONFIG;
|
||||
} AM_SYSDATAwH_ALPB_DEV_CONFIG, *PAM_SYSDATAwH_ALPB_DEV_CONFIG;
|
||||
|
||||
typedef struct {
|
||||
uint32_t m_Crc;
|
||||
uint32_t m_Uk1;
|
||||
uint32_t m_Uk2;
|
||||
uint32_t m_Uk3;
|
||||
} AM_SYSDATAwH_ALPB_CARD_ID;
|
||||
} AM_SYSDATAwH_ALPB_CARD_ID, *PAM_SYSDATAwH_ALPB_CARD_ID;
|
||||
|
||||
typedef struct {
|
||||
uint32_t m_Crc;
|
||||
@ -148,7 +148,7 @@ typedef struct {
|
||||
uint32_t m_Uk5;
|
||||
uint32_t m_Uk6;
|
||||
uint32_t m_Uk7;
|
||||
} AM_SYSDATAwH_ALPB_COMPUTER_NAME;
|
||||
} AM_SYSDATAwH_ALPB_COMPUTER_NAME, *PAM_SYSDATAwH_ALPB_COMPUTER_NAME;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
|
@ -119,7 +119,7 @@ unsigned char comio_next_req(com_device_t* com, comio_recv_head_t* head, BYTE* d
|
||||
}
|
||||
comdev_read(com, &one_byte, 1);
|
||||
if (one_byte != COMIO_SYNC) {
|
||||
log_error("com", "Garbage on JVS: %02x", one_byte);
|
||||
log_error(plfComm, "Garbage on JVS: %02x", one_byte);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
@ -158,8 +158,43 @@ void comio_reply(com_device_t* com, comio_recv_head_t* req, BYTE status, BYTE le
|
||||
comio_write(com, &one_byte, 1);
|
||||
}
|
||||
|
||||
void com_device_thread(com_device_t* com, FnComDeviceThread* thread) {
|
||||
BOOL attach_com_device(BYTE port, FnComDeviceThread* thread) {
|
||||
if (port < 1 || port > NUM_COM_PORTS) {
|
||||
log_error(plfComm, "Requested COM%hhu but that is out of range!", port);
|
||||
return FALSE;
|
||||
}
|
||||
com_device_t* com = com_devices[port - 1];
|
||||
if (com->thread != INVALID_HANDLE_VALUE) {
|
||||
// No need to change what's assigned!
|
||||
if (com->thread_worker == thread) return TRUE;
|
||||
|
||||
log_warning(plfComm, "COM%hhu is already attached!", port);
|
||||
TerminateThread(com->thread, (DWORD)-1);
|
||||
}
|
||||
|
||||
com->thread = CreateThread(NULL, 0, thread, com, 0, NULL);
|
||||
com->thread_worker = thread;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
void detach_com_device(BYTE port) {
|
||||
// If the port is out of range, there's guaranteeably nothing attached
|
||||
if (port < 1 || port > NUM_COM_PORTS)
|
||||
return;
|
||||
|
||||
com_device_t* com = com_devices[port - 1];
|
||||
if (!com->thread) return;
|
||||
|
||||
TerminateThread(com->thread, (DWORD)-1);
|
||||
com->thread = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
void detach_all_com_devices(void) {
|
||||
for (int i = 0; i < NUM_COM_PORTS; i++) {
|
||||
if (com_devices[i]->thread != INVALID_HANDLE_VALUE) {
|
||||
TerminateThread(com_devices[i]->thread, (DWORD)-1);
|
||||
com_devices[i]->thread = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
com_device_t* new_com_device(BYTE port) {
|
||||
@ -189,8 +224,15 @@ com_device_t* new_com_device(BYTE port) {
|
||||
ringbuf_purge(&com_device->in);
|
||||
ringbuf_purge(&com_device->out);
|
||||
com_device->event = CreateEventW(NULL, TRUE, FALSE, com_device->com->wName);
|
||||
com_device->thread = INVALID_HANDLE_VALUE;
|
||||
|
||||
hook_file(file);
|
||||
|
||||
return com_device;
|
||||
}
|
||||
|
||||
void init_com_devices(void) {
|
||||
for (BYTE i = 0; i < NUM_COM_PORTS; i++) {
|
||||
com_devices[i] = new_com_device(i + 1);
|
||||
}
|
||||
}
|
@ -3,7 +3,12 @@
|
||||
#include "hooks/com.h"
|
||||
#include "hooks/files.h"
|
||||
|
||||
typedef struct com_device {
|
||||
#define NUM_COM_PORTS 8
|
||||
|
||||
typedef struct com_device com_device_t;
|
||||
typedef DWORD(WINAPI FnComDeviceThread)(com_device_t* com);
|
||||
|
||||
struct com_device {
|
||||
com_hook_t* com;
|
||||
file_hook_t* file;
|
||||
|
||||
@ -11,7 +16,9 @@ typedef struct com_device {
|
||||
ring_buffer_t out;
|
||||
HANDLE event;
|
||||
HANDLE thread;
|
||||
} com_device_t;
|
||||
FnComDeviceThread* thread_worker;
|
||||
};
|
||||
com_device_t* com_devices[NUM_COM_PORTS];
|
||||
|
||||
typedef struct {
|
||||
BYTE frame_length;
|
||||
@ -36,8 +43,6 @@ typedef struct {
|
||||
#define COMIO_STATUS_OK 0
|
||||
#define COMIO_STATUS_NG 1
|
||||
|
||||
typedef DWORD(WINAPI FnComDeviceThread)(com_device_t* com);
|
||||
|
||||
short comdev_read_blocking(com_device_t* com, unsigned char* buffer, short bytes);
|
||||
short comdev_read(com_device_t* com, unsigned char* buffer, short bytes);
|
||||
bool comdev_write(com_device_t* com, const unsigned char* buffer, short bytes);
|
||||
@ -50,5 +55,8 @@ void comio_write(com_device_t* com, BYTE* data, BYTE len);
|
||||
unsigned char comio_next_req(com_device_t* com, comio_recv_head_t* head, BYTE* data);
|
||||
void comio_reply(com_device_t* com, comio_recv_head_t* req, BYTE status, BYTE len, BYTE* data);
|
||||
|
||||
void com_device_thread(com_device_t* com, FnComDeviceThread* thread);
|
||||
com_device_t* new_com_device(BYTE port);
|
||||
com_device_t* new_com_device(BYTE port);
|
||||
BOOL attach_com_device(BYTE port, FnComDeviceThread* thread);
|
||||
void detach_com_device(BYTE port);
|
||||
void detach_all_com_devices(void);
|
||||
void init_com_devices(void);
|
||||
|
@ -24,5 +24,7 @@
|
||||
#include "../lib/mice/mice.h"
|
||||
#include "./util/_util.h"
|
||||
|
||||
void mice_got_game_id(char game_id[4]);
|
||||
|
||||
extern WCHAR exeName[MAX_PATH + 1];
|
||||
extern DWORD imageOffset;
|
||||
|
@ -1,15 +1,73 @@
|
||||
#include "_devices.h"
|
||||
|
||||
#include "smb_pca9535.h"
|
||||
#include "smb_at24c64an.h"
|
||||
#include "smb_ds28cn01.h"
|
||||
#include "smb_ds2460.h"
|
||||
#include "smb_ds28cn01.h"
|
||||
#include "smb_pca9535.h"
|
||||
|
||||
typedef struct _device_list {
|
||||
const char* m_Name;
|
||||
FnComDeviceThread* m_Thread;
|
||||
struct _device_list* m_Next;
|
||||
} device_list_t;
|
||||
device_list_t device_list = { .m_Next = NULL };
|
||||
|
||||
#define _start_device_n(n) \
|
||||
if (strcmp(MiceConfig.devices.com##n, name) == 0) attach_com_device(n, thread)
|
||||
|
||||
inline void start_device(const char* name, FnComDeviceThread* thread) {
|
||||
_start_device_n(1);
|
||||
_start_device_n(2);
|
||||
_start_device_n(3);
|
||||
_start_device_n(4);
|
||||
_start_device_n(5);
|
||||
_start_device_n(6);
|
||||
_start_device_n(7);
|
||||
_start_device_n(8);
|
||||
}
|
||||
|
||||
#define _stop_if_unregistered(n) \
|
||||
if (MiceConfig.devices.com##n[0] == '\0') detach_com_device(n)
|
||||
|
||||
inline void stop_old_devices() {
|
||||
_stop_if_unregistered(1);
|
||||
_stop_if_unregistered(2);
|
||||
_stop_if_unregistered(3);
|
||||
_stop_if_unregistered(4);
|
||||
_stop_if_unregistered(5);
|
||||
_stop_if_unregistered(6);
|
||||
_stop_if_unregistered(7);
|
||||
_stop_if_unregistered(8);
|
||||
}
|
||||
|
||||
void start_devices() {
|
||||
stop_old_devices();
|
||||
|
||||
device_list_t* device = &device_list;
|
||||
while (device->m_Next) {
|
||||
device = device->m_Next;
|
||||
start_device(device->m_Name, device->m_Thread);
|
||||
}
|
||||
}
|
||||
|
||||
void register_device(const char* name, FnComDeviceThread* thread) {
|
||||
device_list_t* tail = &device_list;
|
||||
while (tail->m_Next) tail = tail->m_Next;
|
||||
|
||||
device_list_t* us = tail->m_Next = malloc(sizeof(device_list_t));
|
||||
|
||||
us->m_Name = name;
|
||||
us->m_Thread = thread;
|
||||
us->m_Next = NULL;
|
||||
}
|
||||
|
||||
void install_devices() {
|
||||
install_led_bd();
|
||||
install_touch_bd();
|
||||
install_aime_bd();
|
||||
|
||||
start_devices();
|
||||
|
||||
smbus_install(/* 0x20 */ PCA9535_ADDRESS, &smbus_PCA9535_write, &smbus_PCA9535_read);
|
||||
|
||||
// mxkN2CmdWriteData(byte addr,byte *data,ushort nbytes,ushort *nbytesOut)
|
||||
|
@ -10,4 +10,7 @@ void install_aime_bd();
|
||||
smbus_callback_t smbus_N2_write;
|
||||
smbus_callback_t smbus_N2_read;
|
||||
|
||||
void start_devices();
|
||||
void register_device(const char* name, FnComDeviceThread* thread);
|
||||
|
||||
void install_devices();
|
||||
|
@ -73,9 +73,11 @@ typedef struct rs232c_recv_head {
|
||||
BYTE op;
|
||||
} rs232c_recv_head_t;
|
||||
|
||||
#define log_level log_misc
|
||||
|
||||
BYTE extra[0xff];
|
||||
static DWORD WINAPI led_bd_thread(com_device_t* dev) {
|
||||
log_info("led_bd", "%ls woke up", dev->com->wName);
|
||||
log_info(plfMaiLED, "%ls woke up", dev->com->wName);
|
||||
|
||||
while (1) {
|
||||
rs232c_recv_head_t head;
|
||||
@ -86,17 +88,17 @@ static DWORD WINAPI led_bd_thread(com_device_t* dev) {
|
||||
comdev_read(dev, (unsigned char*)&head, sizeof head);
|
||||
comdev_read(dev, extra, head.length);
|
||||
|
||||
// log_info("led_bd", "Bound %02x->%02x", head.src, head.dst);
|
||||
// log_info(plfMaiLED, "Bound %02x->%02x", head.src, head.dst);
|
||||
|
||||
switch (head.op) {
|
||||
case 0x01:
|
||||
log_trace("led_bd", "01");
|
||||
log_level(plfMaiLED, "01");
|
||||
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x01\x01\x18", 8);
|
||||
// syn dst src len sts op. rep chk
|
||||
break;
|
||||
|
||||
case 0x10:
|
||||
log_trace("led_bd", "10");
|
||||
log_level(plfMaiLED, "10");
|
||||
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x10\x01\x27", 8);
|
||||
// syn dst src len sts op. rep chk
|
||||
break;
|
||||
@ -106,13 +108,13 @@ static DWORD WINAPI led_bd_thread(com_device_t* dev) {
|
||||
COLOURS[extra[0]][1] = extra[2];
|
||||
COLOURS[extra[0]][2] = extra[3];
|
||||
|
||||
log_trace("led_bd", "31: %02x = (%02x %02x %02x)", extra[0], extra[1], extra[2],
|
||||
log_level(plfMaiLED, "31: %02x = (%02x %02x %02x)", extra[0], extra[1], extra[2],
|
||||
extra[3]);
|
||||
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x31\x01\x48", 8);
|
||||
// syn dst src len sts op. rep chk
|
||||
break;
|
||||
case 0x32:
|
||||
log_trace("led_bd", "32: %02x %02x %02x %02x %02x %02x %02x", extra[0], extra[1],
|
||||
log_level(plfMaiLED, "32: %02x %02x %02x %02x %02x %02x %02x", extra[0], extra[1],
|
||||
extra[2], extra[3], extra[4], extra[5], extra[6], extra[7]);
|
||||
|
||||
for (unsigned char i = extra[2] - 1; i < extra[1]; i++) {
|
||||
@ -125,7 +127,7 @@ static DWORD WINAPI led_bd_thread(com_device_t* dev) {
|
||||
// syn dst src len sts op. rep chk
|
||||
break;
|
||||
case 0x33:
|
||||
log_trace("led_bd", "33: %02x %02x %02x %02x %02x %02x %02x", extra[0], extra[1],
|
||||
log_level(plfMaiLED, "33: %02x %02x %02x %02x %02x %02x %02x", extra[0], extra[1],
|
||||
extra[2], extra[3], extra[4], extra[5], extra[6], extra[7]);
|
||||
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x33\x01\x4a", 8);
|
||||
// syn dst src len sts op. rep chk
|
||||
@ -135,7 +137,7 @@ static DWORD WINAPI led_bd_thread(com_device_t* dev) {
|
||||
break;
|
||||
|
||||
case 0x39:
|
||||
log_trace("led_bd", "39: %02x %02x %02x", extra[0], extra[1], extra[2]);
|
||||
log_level(plfMaiLED, "39: %02x %02x %02x", extra[0], extra[1], extra[2]);
|
||||
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x39\x01\x50", 8);
|
||||
// syn dst src len sts op. rep chk
|
||||
|
||||
@ -144,17 +146,17 @@ static DWORD WINAPI led_bd_thread(com_device_t* dev) {
|
||||
COLOURS[9][2] = extra[0];
|
||||
break;
|
||||
case 0x3b:
|
||||
log_trace("led_bd", "3b");
|
||||
log_level(plfMaiLED, "3b");
|
||||
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x3b\x01\x52", 8);
|
||||
// syn dst src len sts op. rep chk
|
||||
break;
|
||||
case 0x3c:
|
||||
log_trace("led_bd", "3c (I am %ls)", dev->com->wName);
|
||||
log_level(plfMaiLED, "3c (I am %ls)", dev->com->wName);
|
||||
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x3c\x01\x53", 8);
|
||||
// syn dst src len sts op. rep chk
|
||||
break;
|
||||
case 0x3f:
|
||||
log_trace("led_bd", "3f: %02x %02x %02x %02x %02x %02x", extra[0], extra[1],
|
||||
log_level(plfMaiLED, "3f: %02x %02x %02x %02x %02x %02x", extra[0], extra[1],
|
||||
extra[2], extra[3], extra[4], extra[5], extra[6]);
|
||||
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x3f\x01\x56", 8);
|
||||
// syn dst src len sts op. rep chk
|
||||
@ -163,20 +165,20 @@ static DWORD WINAPI led_bd_thread(com_device_t* dev) {
|
||||
case 0x7c:
|
||||
// extra[0] goes from 0 to 7
|
||||
// Could this be some sort of calibration for the buttons?
|
||||
log_trace("led_bd", "7c: %02x", extra[0]);
|
||||
log_level(plfMaiLED, "7c: %02x", extra[0]);
|
||||
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x04\x01\x7c\x01\x00\x94", 9);
|
||||
// \/ causes 7b to be used
|
||||
// comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x04\x01\x7c\x01\x10\xa4", 9);
|
||||
// syn dst src len sts op. rep --- chk
|
||||
break;
|
||||
case 0x7b:
|
||||
log_trace("led_bd", "7b: %02x %02x %02x", extra[0], extra[1], extra[2]);
|
||||
log_level(plfMaiLED, "7b: %02x %02x %02x", extra[0], extra[1], extra[2]);
|
||||
comdev_write(dev, (unsigned char*)"\xe0\x01\x11\x03\x01\x7b\x01\x92", 8);
|
||||
// syn dst src len sts op. rep chk
|
||||
break;
|
||||
|
||||
default:
|
||||
log_error("led_bd", "Unknown op %02x (%d)", head.op, head.length - 1);
|
||||
log_error(plfMaiLED, "Unknown op %02x (%d)", head.op, head.length - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -214,19 +216,7 @@ void __stdcall led_overlay(unsigned int hookType, IDirect3DDevice9* dev) {
|
||||
}
|
||||
|
||||
void install_led_bd() {
|
||||
register_device("mailed", led_bd_thread);
|
||||
|
||||
// register_gui_hook(&led_overlay);
|
||||
|
||||
char* text = MiceConfig.devices.led_bd;
|
||||
char* copy = (char*)malloc(strlen(text) + 1);
|
||||
memcpy_s(copy, strlen(text) + 1, text, strlen(text) + 1);
|
||||
|
||||
char* next_token;
|
||||
char* token = strtok_s(copy, ",", &next_token);
|
||||
while (token != NULL) {
|
||||
BYTE com_port = atoi(token) & 0xFF;
|
||||
if (com_port) com_device_thread(new_com_device(com_port), led_bd_thread);
|
||||
token = strtok_s(NULL, ",", &next_token);
|
||||
}
|
||||
|
||||
free(copy);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ static BYTE get_touch_id(BYTE id) {
|
||||
BOOL touch_is_enabled = false;
|
||||
BYTE thresh = 0x00; // Lazy caching of single value
|
||||
DWORD WINAPI touch_bd_thread(com_device_t* dev) {
|
||||
log_info("touch_bd", "%ls woke up", dev->com->wName);
|
||||
log_info(plfMaiTouch, "%ls woke up", dev->com->wName);
|
||||
|
||||
while (1) {
|
||||
if (touch_is_enabled && !comdev_available(dev)) {
|
||||
@ -30,7 +30,7 @@ DWORD WINAPI touch_bd_thread(com_device_t* dev) {
|
||||
|
||||
while (read_one(dev) != '{') continue;
|
||||
while (comdev_available(dev) < 5) {
|
||||
log_info("touch", "<. .>");
|
||||
log_info(plfMaiTouch, "<. .>");
|
||||
Sleep(50);
|
||||
}
|
||||
BYTE command[5];
|
||||
@ -40,20 +40,20 @@ DWORD WINAPI touch_bd_thread(com_device_t* dev) {
|
||||
|
||||
if (memcmp(command, "HALT}", 5) == 0) {
|
||||
if (touch_is_enabled)
|
||||
log_info("touch", "Touchscreen left active mode");
|
||||
log_info(plfMaiTouch, "Touchscreen left active mode");
|
||||
else
|
||||
log_misc("touch", "Touchscreen not in active mode");
|
||||
log_misc(plfMaiTouch, "Touchscreen not in active mode");
|
||||
touch_is_enabled = false;
|
||||
} else if (memcmp(command, "STAT}", 5) == 0) {
|
||||
if (!touch_is_enabled)
|
||||
log_info("touch", "Touchscreen entered active mode");
|
||||
log_info(plfMaiTouch, "Touchscreen entered active mode");
|
||||
else
|
||||
log_misc("touch", "Touchscreen already in active mode");
|
||||
log_misc(plfMaiTouch, "Touchscreen already in active mode");
|
||||
touch_is_enabled = true;
|
||||
} else if (command[2] == 'k' && command[4] == '}') {
|
||||
BYTE sensor = get_touch_id(command[1]);
|
||||
|
||||
log_misc("touch", "k-command recieved: %d >=%d", sensor, command[3]);
|
||||
log_misc(plfMaiTouch, "k-command recieved: %d >=%d", sensor, command[3]);
|
||||
// Sensor == '@': failed
|
||||
// ( <L/R> <sensor> <> <> )
|
||||
response[1] = command[0];
|
||||
@ -65,7 +65,7 @@ DWORD WINAPI touch_bd_thread(com_device_t* dev) {
|
||||
BYTE sensor = get_touch_id(command[1]);
|
||||
|
||||
// { <L/R> <sensor> t h }
|
||||
log_misc("touch", "th-command recieved: %d", sensor);
|
||||
log_misc(plfMaiTouch, "th-command recieved: %d", sensor);
|
||||
|
||||
// Sensor == '@': failed
|
||||
// ( <L/R> <sensor> <> <threshold> )
|
||||
@ -75,23 +75,9 @@ DWORD WINAPI touch_bd_thread(com_device_t* dev) {
|
||||
|
||||
comdev_write(dev, response, 6);
|
||||
} else {
|
||||
log_error("touch", "Unhandled: {%.*s", 5, command);
|
||||
log_error(plfMaiTouch, "Unhandled: {%.*s", 5, command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void install_touch_bd() {
|
||||
char* text = MiceConfig.devices.touch_bd;
|
||||
char* copy = (char*)malloc(strlen(text) + 1);
|
||||
memcpy_s(copy, strlen(text) + 1, text, strlen(text) + 1);
|
||||
|
||||
char* next_token;
|
||||
char* token = strtok_s(copy, ",", &next_token);
|
||||
while (token != NULL) {
|
||||
BYTE com_port = atoi(token) & 0xFF;
|
||||
if (com_port) com_device_thread(new_com_device(com_port), touch_bd_thread);
|
||||
token = strtok_s(NULL, ",", &next_token);
|
||||
}
|
||||
|
||||
free(copy);
|
||||
}
|
||||
void install_touch_bd() { register_device("maitouch", touch_bd_thread); }
|
||||
|
@ -217,14 +217,14 @@ BYTE BANA_KEY[6];
|
||||
DWORD WINAPI aime_bd_thread(com_device_t* dev) {
|
||||
static int fwNumBytes = 0;
|
||||
|
||||
log_info("aime_bd", "%ls woke up", dev->com->wName);
|
||||
log_info(plfAime, "%ls woke up", dev->com->wName);
|
||||
bool radio = false;
|
||||
|
||||
while (1) {
|
||||
comio_recv_head_t req;
|
||||
unsigned char sum = comio_next_req(dev, &req, extra);
|
||||
|
||||
log_info("aime_bd", "(%d) %02x(%d) = %s", req.dst, req.op, req.length, OpcodeNames[req.op]);
|
||||
log_info(plfAime, "(%d) %02x(%d) = %s", req.dst, req.op, req.length, OpcodeNames[req.op]);
|
||||
|
||||
if (req.dst == 0x00 || req.dst == 0x01) {
|
||||
// Aime readers
|
||||
@ -249,7 +249,7 @@ DWORD WINAPI aime_bd_thread(com_device_t* dev) {
|
||||
memcpy(AIME_KEY, extra, sizeof AIME_KEY);
|
||||
comio_reply(dev, &req, COMIO_STATUS_OK, 0, NULL);
|
||||
|
||||
log_info("aime_bd", "Aime key: %02x %02x %02x %02x %02x %02x", AIME_KEY[0],
|
||||
log_info(plfAime, "Aime key: %02x %02x %02x %02x %02x %02x", AIME_KEY[0],
|
||||
AIME_KEY[1], AIME_KEY[2], AIME_KEY[3], AIME_KEY[4], AIME_KEY[5]);
|
||||
}
|
||||
break;
|
||||
@ -260,7 +260,7 @@ DWORD WINAPI aime_bd_thread(com_device_t* dev) {
|
||||
memcpy(BANA_KEY, extra, sizeof BANA_KEY);
|
||||
comio_reply(dev, &req, COMIO_STATUS_OK, 0, NULL);
|
||||
|
||||
log_info("aime_bd", "Bana key: %02x %02x %02x %02x %02x %02x", BANA_KEY[0],
|
||||
log_info(plfAime, "Bana key: %02x %02x %02x %02x %02x %02x", BANA_KEY[0],
|
||||
BANA_KEY[1], BANA_KEY[2], BANA_KEY[3], BANA_KEY[4], BANA_KEY[5]);
|
||||
}
|
||||
break;
|
||||
@ -294,7 +294,7 @@ DWORD WINAPI aime_bd_thread(com_device_t* dev) {
|
||||
case TN32Op_Unknown61:
|
||||
// null-terminated line of the firmware hex!
|
||||
comio_reply(dev, &req, COMIO_STATUS_OK, 0, NULL);
|
||||
log_info("aime_bd", "Recv firmware: %s", extra);
|
||||
log_info(plfAime, "Recv firmware: %s", extra);
|
||||
break;
|
||||
case TN32Op_Unknown63:
|
||||
// req.length == 0; start binary firmware update?
|
||||
@ -344,7 +344,7 @@ DWORD WINAPI aime_bd_thread(com_device_t* dev) {
|
||||
comio_reply(dev, &req, COMIO_STATUS_OK, 9, (BYTE*)"15084\xff\x10\x00\x12");
|
||||
break;
|
||||
case LedSetColour:
|
||||
log_misc("nfc", "Set LED: #%02x%02x%02x", extra[0], extra[1], extra[2]);
|
||||
log_misc(plfAime, "Set LED: #%02x%02x%02x", extra[0], extra[1], extra[2]);
|
||||
printf(
|
||||
"\033[48;2;%d;%d;%dm "
|
||||
" \033[0m",
|
||||
@ -384,17 +384,5 @@ void install_aime_bd() {
|
||||
OpcodeNames[LedGetInfo] = "LedGetInfo";
|
||||
OpcodeNames[LedSetColour] = "LedSetColour";
|
||||
|
||||
char* text = MiceConfig.devices.aime_bd;
|
||||
char* copy = (char*)malloc(strlen(text) + 1);
|
||||
memcpy_s(copy, strlen(text) + 1, text, strlen(text) + 1);
|
||||
|
||||
char* next_token;
|
||||
char* token = strtok_s(copy, ",", &next_token);
|
||||
while (token != NULL) {
|
||||
BYTE com_port = atoi(token) & 0xFF;
|
||||
if (com_port) com_device_thread(new_com_device(com_port), aime_bd_thread);
|
||||
token = strtok_s(NULL, ",", &next_token);
|
||||
}
|
||||
|
||||
free(copy);
|
||||
register_device("aime_tn32msec", aime_bd_thread);
|
||||
}
|
||||
|
@ -2,39 +2,16 @@
|
||||
#include "../../maiBackupStructs.h"
|
||||
#include "_devices.h"
|
||||
|
||||
#define EEPROM_DUMP L"dev/eeprom.bin"
|
||||
#define EEPROM_PATH L"dev/eeprom.bin"
|
||||
|
||||
#include "../../sysconf.h"
|
||||
|
||||
// 8192 x 8 (64kbit) of eeprom
|
||||
BYTE EEPROM_DATA[0x2000];
|
||||
#define EEPROM_SIZE 0x2000
|
||||
|
||||
void eeprom_dump() {
|
||||
HANDLE dump =
|
||||
_CreateFileW(EEPROM_DUMP, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
|
||||
if (dump == INVALID_HANDLE_VALUE) {
|
||||
log_error("eeprom", "CreateFileA(EEPROM_DUMP) failed: %03x", GetLastError());
|
||||
return;
|
||||
} else {
|
||||
log_info("eeprom", "Wrote eeprom to %ls", EEPROM_DUMP);
|
||||
}
|
||||
_WriteFile(dump, &EEPROM_DATA, sizeof EEPROM_DATA, NULL, NULL);
|
||||
FlushFileBuffers(dump);
|
||||
_CloseHandle(dump);
|
||||
}
|
||||
void eeprom_restore() {
|
||||
HANDLE dump = _CreateFileW(EEPROM_DUMP, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (dump == INVALID_HANDLE_VALUE) {
|
||||
// Make the file, even though it'll probably be empty
|
||||
eeprom_dump();
|
||||
return;
|
||||
}
|
||||
DWORD read;
|
||||
if (!_ReadFile(dump, &EEPROM_DATA, sizeof EEPROM_DATA, &read, NULL))
|
||||
log_error("eeprom", "failed to restore (%d)", GetLastError());
|
||||
_CloseHandle(dump);
|
||||
}
|
||||
LPBYTE EEPROM_DATA = NULL;
|
||||
HANDLE EEPROM_FILE = INVALID_HANDLE_VALUE;
|
||||
HANDLE EEPROM_FILE_MAPPING = INVALID_HANDLE_VALUE;
|
||||
|
||||
#define fix_crc(block) \
|
||||
do { \
|
||||
@ -72,19 +49,9 @@ void set_eeprom_static_config() {
|
||||
}
|
||||
|
||||
void build_eeprom() {
|
||||
if (FileExists(EEPROM_DUMP)) {
|
||||
eeprom_restore();
|
||||
// Our network and static config always gets priority
|
||||
set_eeprom_static_config();
|
||||
set_eeprom_network_config();
|
||||
log_info(plfEeprom, "Building default EEPROM file");
|
||||
|
||||
eeprom_dump();
|
||||
return;
|
||||
}
|
||||
|
||||
log_info("eeprom", "Building default EEPROM file");
|
||||
|
||||
memset(EEPROM_DATA, 0xff, sizeof EEPROM_DATA);
|
||||
memset(EEPROM_DATA, 0xff, EEPROM_SIZE);
|
||||
|
||||
set_eeprom_static_config();
|
||||
|
||||
@ -102,22 +69,10 @@ void build_eeprom() {
|
||||
|
||||
set_eeprom_network_config();
|
||||
|
||||
AM_SYSDATAwH_HISTORY History = { 0 };
|
||||
// TODO: Game ID here should be configurable.
|
||||
History.m_GameId[0] = '-';
|
||||
History.m_GameId[1] = '-';
|
||||
History.m_GameId[2] = '-';
|
||||
History.m_GameId[3] = '-';
|
||||
History.m_Region = MiceConfig.sysconf.region & (1 | 2 | 4 | 8);
|
||||
fix_crc(History);
|
||||
memcpy(&EEPROM_DATA[AM_SYSDATAwH_HISTORY_REG], &History, sizeof History);
|
||||
memcpy(&EEPROM_DATA[AM_SYSDATAwH_HISTORY_DUP], &History, sizeof History);
|
||||
AM_SYSDATAwH_ALPB_CARD_ID CardInfo = { 0 };
|
||||
fix_crc(CardInfo);
|
||||
memcpy(&EEPROM_DATA[AM_SYSDATAwH_ALPB_CARD_ID_REG] + (sizeof History), &CardInfo,
|
||||
sizeof CardInfo);
|
||||
memcpy(&EEPROM_DATA[AM_SYSDATAwH_ALPB_CARD_ID_DUP] + (sizeof History), &CardInfo,
|
||||
sizeof CardInfo);
|
||||
memcpy(&EEPROM_DATA[AM_SYSDATAwH_ALPB_CARD_ID_REG], &CardInfo, sizeof CardInfo);
|
||||
memcpy(&EEPROM_DATA[AM_SYSDATAwH_ALPB_CARD_ID_DUP], &CardInfo, sizeof CardInfo);
|
||||
|
||||
AM_SYSDATAwH_ALPB_COMPUTER_NAME CompuerName = { 0 };
|
||||
fix_crc(CompuerName);
|
||||
@ -129,47 +84,81 @@ void build_eeprom() {
|
||||
memcpy(&EEPROM_DATA[AM_SYSDATAwH_ALPB_DEV_CONFIG_REG], &DevConfig, sizeof DevConfig);
|
||||
memcpy(&EEPROM_DATA[AM_SYSDATAwH_ALPB_DEV_CONFIG_DUP], &DevConfig, sizeof DevConfig);
|
||||
|
||||
eeprom_dump();
|
||||
// eeprom_dump();
|
||||
}
|
||||
|
||||
AM_SYSDATAwH_HISTORY AmHistory = {
|
||||
// By making the game ID "____" we ensure games overwrite this, letting us see what they write.
|
||||
// This is currently the best way I have found to retrieve the game ID
|
||||
.m_GameId = { '_', '_', '_', '_' },
|
||||
};
|
||||
/** Clobber EEPROM with our user settings */
|
||||
void eeprom_fixup() {
|
||||
set_eeprom_static_config();
|
||||
set_eeprom_network_config();
|
||||
|
||||
AmHistory.m_Region = MiceConfig.sysconf.region & (1 | 2 | 4 | 8);
|
||||
fix_crc(AmHistory);
|
||||
memcpy(&EEPROM_DATA[AM_SYSDATAwH_HISTORY_REG], &AmHistory, sizeof AmHistory);
|
||||
memcpy(&EEPROM_DATA[AM_SYSDATAwH_HISTORY_DUP], &AmHistory, sizeof AmHistory);
|
||||
}
|
||||
|
||||
void ensure_valid_eeprom() {
|
||||
static BOOL built = false;
|
||||
if (built) {
|
||||
eeprom_restore();
|
||||
return;
|
||||
}
|
||||
build_eeprom();
|
||||
built = true;
|
||||
}
|
||||
if (!EEPROM_DATA) {
|
||||
BOOL isNew = !FileExists(EEPROM_PATH);
|
||||
|
||||
EEPROM_DATA =
|
||||
open_mapped_file(EEPROM_PATH, EEPROM_SIZE, &EEPROM_FILE, &EEPROM_FILE_MAPPING);
|
||||
if (EEPROM_DATA == NULL) {
|
||||
log_error(plfEeprom, "EEPROM will be memory-backed and not syncronised!");
|
||||
EEPROM_DATA = malloc(EEPROM_SIZE);
|
||||
}
|
||||
|
||||
if (isNew) build_eeprom();
|
||||
}
|
||||
eeprom_fixup();
|
||||
}
|
||||
|
||||
void eeprom_read(WORD addr, BYTE* data, BYTE length) {
|
||||
ensure_valid_eeprom();
|
||||
|
||||
if (addr >= sizeof EEPROM_DATA) return;
|
||||
if (length + addr > sizeof EEPROM_DATA) length = (sizeof EEPROM_DATA - addr) & 0xff;
|
||||
if (addr >= EEPROM_SIZE) return;
|
||||
if (length + addr > EEPROM_SIZE) length = (EEPROM_SIZE - addr) & 0xff;
|
||||
|
||||
memcpy(data, &EEPROM_DATA[addr], length);
|
||||
memcpy(data, EEPROM_DATA + addr, length);
|
||||
}
|
||||
void eeprom_write(WORD addr, BYTE* data, BYTE length) {
|
||||
ensure_valid_eeprom();
|
||||
|
||||
if (addr >= sizeof EEPROM_DATA) return;
|
||||
if (length + addr > sizeof EEPROM_DATA) length = (sizeof EEPROM_DATA - addr) & 0xff;
|
||||
if (addr >= EEPROM_SIZE) return;
|
||||
if (length + addr > EEPROM_SIZE) length = (EEPROM_SIZE - addr) & 0xff;
|
||||
|
||||
memcpy(&EEPROM_DATA[addr], data, length);
|
||||
eeprom_dump();
|
||||
// TODO: Do any games write this as anything other than a complete block?
|
||||
if (addr == AM_SYSDATAwH_HISTORY_REG && length == sizeof(AM_SYSDATAwH_HISTORY)) {
|
||||
PAM_SYSDATAwH_HISTORY pHistory = (PAM_SYSDATAwH_HISTORY)data;
|
||||
|
||||
mice_got_game_id(pHistory->m_GameId);
|
||||
} else if (addr >= 0x1000 && length > 8) {
|
||||
char game_id[4];
|
||||
game_id[0] = data[7];
|
||||
game_id[1] = data[6];
|
||||
game_id[2] = data[5];
|
||||
game_id[3] = data[4];
|
||||
mice_got_game_id(game_id);
|
||||
}
|
||||
|
||||
memcpy(EEPROM_DATA + addr, data, length);
|
||||
}
|
||||
|
||||
BOOL smbus_AT24C64AN_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
|
||||
switch (cmd) {
|
||||
case ICH9_CMD_BLOCK: {
|
||||
log_misc("eeprom", "write %d bytes at 0x%03x", dlen, code);
|
||||
log_misc(plfEeprom, "write %d bytes at 0x%03x", dlen, code);
|
||||
eeprom_write(code, data, dlen);
|
||||
return TRUE;
|
||||
}
|
||||
default:
|
||||
log_error("eeprom", "Unsupported write mode: %01x, %02x", cmd, code);
|
||||
log_error(plfEeprom, "Unsupported write mode: %01x, %02x", cmd, code);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@ -180,12 +169,12 @@ BOOL smbus_AT24C64AN_read(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
|
||||
data[0] = 0x00;
|
||||
return TRUE;
|
||||
case ICH9_CMD_BLOCK: {
|
||||
log_misc("eeprom", "read %d bytes at 0x%03x", dlen, code);
|
||||
log_misc(plfEeprom, "read %d bytes at 0x%03x", dlen, code);
|
||||
eeprom_read(code, data, dlen);
|
||||
return TRUE;
|
||||
}
|
||||
default:
|
||||
log_error("eeprom", "Unsupported read mode: %01x, %02x", cmd, code);
|
||||
log_error(plfEeprom, "Unsupported read mode: %01x, %02x", cmd, code);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,11 @@ void ds2460_update_mac(bool gpSha, byte* secret) {
|
||||
ComputeDallasSha(INPUT_BUFFER, (long*)&COMPUTED_MAC[0], (long*)&COMPUTED_MAC[4],
|
||||
(long*)&COMPUTED_MAC[8], (long*)&COMPUTED_MAC[12],
|
||||
(long*)&COMPUTED_MAC[16]);
|
||||
puts("ds2460: SHA1 out buffer:");
|
||||
for (int i = 0; i < 20; i++) {
|
||||
printf("%02x", COMPUTED_MAC[i]);
|
||||
}
|
||||
puts("");
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,7 +91,7 @@ BOOL smbus_ds2460_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
|
||||
* | 0x04 -> DS2460_CMD_COMPUTE_TO_MAC_BUFFER
|
||||
*/
|
||||
if (!(data[0] & DS2460_CMD_COMPUTE)) {
|
||||
log_error("ds2460", "Unknown command: %02x", data[0]);
|
||||
log_error(plfDS2460, "Unknown command: %02x", data[0]);
|
||||
return FALSE;
|
||||
}
|
||||
BYTE numSecret = (data[0] >> 3) & 3;
|
||||
@ -99,7 +104,7 @@ BOOL smbus_ds2460_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
|
||||
ds2460_update_mac(gpSha, SECRETS[numSecret]);
|
||||
return TRUE;
|
||||
default:
|
||||
log_error("ds2460", "Unknown write command: %02x", code);
|
||||
log_error(plfDS2460, "Unknown write command: %02x", code);
|
||||
return FALSE;
|
||||
}
|
||||
case ICH9_CMD_BLOCK: {
|
||||
@ -111,12 +116,12 @@ BOOL smbus_ds2460_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
|
||||
memcpy_s(&INPUT_BUFFER[offset + 1], DS2460_INPUT_BUFFER_SIZE - (offset + 1), data,
|
||||
dlen);
|
||||
|
||||
log_info("ds2460", "Block write, %d @ %04x: ", dlen + 1, offset);
|
||||
log_info(plfDS2460, "Block write, %d @ %04x", dlen + 1, offset);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
default:
|
||||
log_error("ds2460", "Unsupported write mode: %01x (%02x)", cmd, code);
|
||||
log_error(plfDS2460, "Unsupported write mode: %01x (%02x)", cmd, code);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@ -135,10 +140,10 @@ BOOL smbus_ds2460_read(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
log_error("smx-exio", "Unknown read command: %02x", code);
|
||||
log_error(plfDS2460, "Unknown read command: %02x", code);
|
||||
return FALSE;
|
||||
default:
|
||||
log_error("ds2460", "Unsupported read mode: %01x (%02x)", cmd, code);
|
||||
log_error(plfDS2460, "Unsupported read mode: %01x (%02x)", cmd, code);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "smbus.h"
|
||||
#include "../smbus.h"
|
||||
|
||||
smbus_callback_t smbus_ds2460_write;
|
||||
smbus_callback_t smbus_ds2460_read;
|
||||
|
@ -97,17 +97,17 @@ BOOL smbus_ds28cn01_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
|
||||
BYTE page = command & 3;
|
||||
BYTE upper = command & 0xf0;
|
||||
|
||||
if (upper == 0xD0) {
|
||||
log_warning("ds28cn01", "Computing for: authentication (flag = 1)");
|
||||
} else if (upper == 0xE0) {
|
||||
log_warning("ds28cn01", "Computing for: ds.compute (flag = 0)");
|
||||
if (upper == DS28CN01_COMPUTE_1) {
|
||||
log_warning(plfDS28CN01, "Computing for: authentication (flag = 1)");
|
||||
} else if (upper == DS28CN01_COMPUTE_2) {
|
||||
log_warning(plfDS28CN01, "Computing for: ds.compute (flag = 0)");
|
||||
} else {
|
||||
log_error("ds28cn01", "Unknown A9");
|
||||
log_error(plfDS28CN01, "Unknown A9");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (dlen != 7) {
|
||||
log_error("ds28cn01", "Expected challenge length of 7 (saw %d)!", dlen);
|
||||
log_error(plfDS28CN01, "Expected challenge length of 7 (saw %d)!", dlen);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -132,7 +132,7 @@ BOOL smbus_ds28cn01_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
|
||||
// dlen++;
|
||||
// char* challenge_s = malloc(dlen * 3 + 1);
|
||||
// if (challenge_s == NULL) {
|
||||
// log_info("ds28cn01", "Challenge: (buffer failed)");
|
||||
// log_info(plfDS28CN01, "Challenge: (buffer failed)");
|
||||
// return TRUE;
|
||||
// }
|
||||
|
||||
@ -140,13 +140,13 @@ BOOL smbus_ds28cn01_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
|
||||
// sprintf_s(challenge_s + i * 3, 4, "%02x ", data[i]);
|
||||
// }
|
||||
// challenge_s[dlen * 3 + 1] = '\0';
|
||||
// log_info("ds28cn01", "Challenge: %s", challenge_s);
|
||||
// log_info(plfDS28CN01, "Challenge: %s", challenge_s);
|
||||
// free(challenge_s);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
log_error("ds28cn01", "Unknown write command: %04x", code);
|
||||
log_error(plfDS28CN01, "Unknown write command: %04x", code);
|
||||
}
|
||||
case ICH9_CMD_I2C_READ: {
|
||||
switch (code) {
|
||||
@ -159,11 +159,11 @@ BOOL smbus_ds28cn01_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
|
||||
for (int i = 0; i < dlen; i++) data[i] = COMPUTED_MAC[i];
|
||||
return TRUE;
|
||||
default:
|
||||
log_error("ds28cn01", "Unknown I2C read command: %04x", code);
|
||||
log_error(plfDS28CN01, "Unknown I2C read command: %04x", code);
|
||||
}
|
||||
}
|
||||
default:
|
||||
log_error("ds28cn01", "Unsupported write mode: %01x (%04x)", cmd, code);
|
||||
log_error(plfDS28CN01, "Unsupported write mode: %01x (%04x)", cmd, code);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@ -191,10 +191,10 @@ BOOL smbus_ds28cn01_read(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
log_error("ds28cn01", "Unknown read command: %04x", code);
|
||||
log_error(plfDS28CN01, "Unknown read command: %04x", code);
|
||||
return FALSE;
|
||||
default:
|
||||
log_error("ds28cn01", "Unsupported read mode: %01x (%04x)", cmd, code);
|
||||
log_error(plfDS28CN01, "Unsupported read mode: %01x (%04x)", cmd, code);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "smbus.h"
|
||||
#include "../smbus.h"
|
||||
|
||||
smbus_callback_t smbus_ds28cn01_write;
|
||||
smbus_callback_t smbus_ds28cn01_read;
|
||||
@ -18,6 +18,9 @@ smbus_callback_t smbus_ds28cn01_read;
|
||||
#define DS28CN01_REG_STATUS 0xA8
|
||||
#define DS28CN01_REG_MAC 0xB0
|
||||
|
||||
#define DS28CN01_COMPUTE_1 0xD0
|
||||
#define DS28CN01_COMPUTE_2 0xE0
|
||||
|
||||
// Flags
|
||||
#define DS28CN01_STATUS_FLAG_BUSY 2
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include "smb_n2.h"
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/rand.h>
|
||||
@ -6,57 +8,10 @@
|
||||
#include "../../sysconf.h"
|
||||
#include "_devices.h"
|
||||
|
||||
#define N2_TAG_OFFSET 0
|
||||
#define N2_PARAMSIZE_OFFSET 2
|
||||
#define N2_COMMAND_OFFSET 4
|
||||
#define N2_TAG_SIZE 2
|
||||
#define N2_PARAMSIZE_SIZE 2
|
||||
#define N2_COMMAND_SIZE 2
|
||||
#define N2_CHECKSUM_SIZE 20
|
||||
#define N2_AUTH_SIZE 20
|
||||
#define N2_HEADER_SIZE (N2_TAG_SIZE + N2_PARAMSIZE_SIZE + N2_COMMAND_SIZE)
|
||||
|
||||
#define N2_TAG_RQU_COMMAND 0xC1
|
||||
#define N2_TAG_RQU_AUTH_COMMAND 0xC2
|
||||
#define N2_TAG_RSP_COMMAND 0xC3
|
||||
#define N2_TAG_RSP_AUTH_COMMAND 0xC4
|
||||
// TODO: Uncomment these if actually used, and adjust lazy +2 logic alongside
|
||||
// #define N2_TAG_RQU_RSA_COMMAND 0xC5
|
||||
// #define N2_TAG_RSP_RSA_COMMAND 0xC6
|
||||
|
||||
#define N2_ORD_ENABLE_SESSION 1
|
||||
#define N2_ORD_DISABLE_SESSION 2
|
||||
#define N2_ORD_SET_AUTH_KEY 3
|
||||
#define N2_ORD_SET_ENC_KEY 4
|
||||
// GAP!
|
||||
#define N2_ORD_GET_AUTH_LEVEL 9
|
||||
// GAP!
|
||||
#define N2_ORD_GET_ERROR_CODE 11
|
||||
#define N2_ORD_GET_VERSION 12
|
||||
// GAP! (-> keychip info write?)
|
||||
#define N2_ORD_READ_KEYCHIP_ID 14
|
||||
// GAP! (-> gkey write?)
|
||||
#define N2_ORD_ENCRYPT_WITH_GKEY 16 // keychip.encrypt
|
||||
#define N2_ORD_DECRYPT_WITH_GKEY 17 // keychip.decrypt
|
||||
#define N2_ORD_ADD_PLAY_COUNT 18
|
||||
#define N2_ORD_READ_PLAY_COUNT 19
|
||||
// GAP! (-> storage? is that still on pic?)
|
||||
#define N2_ORD_GET_RANDOM_VALUE 24
|
||||
#define N2_ORD_ENCRYPT_WITH_SKEY 25 // keychip.ssd.hostproof
|
||||
#define N2_ORD_DECRYPT_WITH_SKEY 26
|
||||
|
||||
#define N2_SUCCESS 0
|
||||
#define N2_INVALID_AUTH 1
|
||||
#define N2_AUTHFAIL 2
|
||||
#define N2_LV_ERROR 3
|
||||
#define N2_BAD_PARAMETER 4
|
||||
#define N2_EEP_WRITEFAIL 5
|
||||
#define N2_BAD_TAG 6
|
||||
#define N2_BAD_ORDINAL 7
|
||||
#define N2_SUMFAIL 8
|
||||
#define N2_EEPWRITE_DISABLE 9
|
||||
#define N2_BAD_DATASIZE 10
|
||||
#define N2_FAIL 11
|
||||
LOG_FACILITY _lf = {
|
||||
.m_name = "smb-n2",
|
||||
};
|
||||
PLOG_FACILITY plf = &_lf;
|
||||
|
||||
#define N2_IO_BUFFER 0x1000
|
||||
|
||||
@ -131,12 +86,12 @@ WORD n2_enable_session(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOu
|
||||
RAND_bytes(n2_session_nonce, sizeof n2_session_nonce);
|
||||
memcpy(dataOut, n2_session_nonce, sizeof n2_session_nonce);
|
||||
|
||||
log_misc("smb-n2", "Session open");
|
||||
log_misc(plf, "Session open");
|
||||
return N2_SUCCESS;
|
||||
}
|
||||
WORD n2_set_auth_key(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
|
||||
*nOut = 0;
|
||||
log_misc("smb-n2", "Auth key set");
|
||||
log_misc(plf, "Auth key set");
|
||||
|
||||
BYTE pt[32];
|
||||
mxkCryptDecryptAes128CBC(n2_enc_key.key, n2_enc_key.iv, dataIn, pt, sizeof pt);
|
||||
@ -146,7 +101,7 @@ WORD n2_set_auth_key(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut)
|
||||
}
|
||||
WORD n2_set_enc_key(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
|
||||
*nOut = 0;
|
||||
log_misc("smb-n2", "Enc key set");
|
||||
log_misc(plf, "Enc key set");
|
||||
|
||||
BYTE pt[32];
|
||||
mxkCryptDecryptAes128CBC(n2_enc_key.key, n2_enc_key.iv, dataIn, pt, sizeof pt);
|
||||
@ -158,13 +113,13 @@ WORD n2_set_enc_key(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut)
|
||||
WORD n2_get_auth_level(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
|
||||
*nOut = 1;
|
||||
dataOut[0] = 3; // TODO: ?
|
||||
log_misc("smb-n2", "Auth level get");
|
||||
log_misc(plf, "Auth level get");
|
||||
return N2_SUCCESS;
|
||||
}
|
||||
WORD n2_get_error_code(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
|
||||
*nOut = 2;
|
||||
((PWORD)dataOut)[0] = fix_endian(n2_error_code);
|
||||
log_misc("smb-n2", "Error get");
|
||||
log_misc(plf, "Error get");
|
||||
return N2_SUCCESS;
|
||||
}
|
||||
WORD n2_read_keychip_id(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
|
||||
@ -180,7 +135,7 @@ WORD n2_read_keychip_id(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nO
|
||||
mxkCryptEncryptAes128CBC(n2_enc_key.key, n2_enc_key.iv, dataOut + 2, (LPBYTE)&n2_keychip_info,
|
||||
nbytes);
|
||||
|
||||
log_misc("smb-n2", "Read keychip ID: %08x", nbytes);
|
||||
log_misc(plf, "Read keychip ID: %08x", nbytes);
|
||||
return N2_SUCCESS;
|
||||
}
|
||||
WORD n2_get_version(WORD paramSize, LPBYTE dataIn, LPBYTE dataOut, LPWORD nOut) {
|
||||
@ -288,11 +243,11 @@ void n2_install_commands() {
|
||||
void do_n2_command(WORD tag, WORD paramSize, WORD command, LPBYTE data) {
|
||||
n2_install_commands();
|
||||
|
||||
log_info("smb-n2", "Processing command: %04x/%04x (%d bytes)", tag, command, paramSize);
|
||||
log_info(plf, "Processing command: %04x/%04x (%d bytes)", tag, command, paramSize);
|
||||
|
||||
ZeroMemory(n2_out_buffer, sizeof n2_out_buffer);
|
||||
|
||||
// We nede to sign with the old key, so need a copy
|
||||
// We need to sign with the old key, so need a copy
|
||||
BYTE auth_key[20];
|
||||
memcpy(auth_key, n2_auth_key, sizeof auth_key);
|
||||
|
||||
@ -333,10 +288,13 @@ void do_n2_command(WORD tag, WORD paramSize, WORD command, LPBYTE data) {
|
||||
EVP_DigestFinal_ex(ctx, n2_out_buffer + N2_HEADER_SIZE + bodyLength, &outlen);
|
||||
EVP_MD_CTX_destroy(ctx);
|
||||
|
||||
// At this point: packet = header | data | SHA(header | command | data)
|
||||
|
||||
if (tag == N2_TAG_RQU_AUTH_COMMAND) {
|
||||
BYTE crypto_buffer[N2_CHECKSUM_SIZE];
|
||||
|
||||
// Calculate a new SHA1 of the packet, including the SHA1 we just appeneded
|
||||
// crypto_buffer = SHA1(header | command | data)
|
||||
ctx = EVP_MD_CTX_create();
|
||||
EVP_DigestInit(ctx, EVP_sha1());
|
||||
EVP_DigestUpdate(ctx, n2_out_buffer, N2_HEADER_SIZE);
|
||||
@ -350,9 +308,9 @@ void do_n2_command(WORD tag, WORD paramSize, WORD command, LPBYTE data) {
|
||||
HMAC_CTX_init(&hmac_ctx);
|
||||
HMAC_Init_ex(&hmac_ctx, auth_key, sizeof auth_key, EVP_sha1(), NULL);
|
||||
|
||||
// SHA1(header | data)
|
||||
// SHA1(header | command | data)
|
||||
HMAC_Update(&hmac_ctx, crypto_buffer, sizeof crypto_buffer);
|
||||
// SHA1(header | auth | packet))
|
||||
// SHA1(header | auth | data)
|
||||
HMAC_Update(&hmac_ctx, n2_out_buffer + N2_HEADER_SIZE + bodyLength, N2_CHECKSUM_SIZE);
|
||||
// Request nonce
|
||||
HMAC_Update(&hmac_ctx, n2_in_buffer + paramSize - N2_AUTH_SIZE - N2_CHECKSUM_SIZE,
|
||||
@ -398,7 +356,7 @@ BOOL smbus_N2_write(ich9_cmd_t cmd, WORD code, BYTE nbytes, LPBYTE data) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
log_error("smb-n2", "Unsupported command code: %04x (%d bytes)", code, nbytes);
|
||||
log_error(plf, "Unsupported command code: %04x (%d bytes)", code, nbytes);
|
||||
return FALSE;
|
||||
}
|
||||
case ICH9_CMD_I2C_READ: {
|
||||
@ -409,15 +367,15 @@ BOOL smbus_N2_write(ich9_cmd_t cmd, WORD code, BYTE nbytes, LPBYTE data) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
log_error("smb-n2", "Unsupported i2c command code: %04x (%d bytes)", code, nbytes);
|
||||
log_error(plf, "Unsupported i2c command code: %04x (%d bytes)", code, nbytes);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
log_error("smb-n2", "Unsupported write mode: %01x (%02x)", cmd, code);
|
||||
log_error(plf, "Unsupported write mode: %01x (%02x)", cmd, code);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL smbus_N2_read(ich9_cmd_t cmd, WORD code, BYTE nbytes, BYTE* data) {
|
||||
log_error("smb-n2", "Unsupported read mode: %01x (%02x)", cmd, code);
|
||||
log_error(plf, "Unsupported read mode: %01x (%02x)", cmd, code);
|
||||
return FALSE;
|
||||
}
|
||||
|
48
src/micetools/dll/devices/smb_n2.h
Normal file
48
src/micetools/dll/devices/smb_n2.h
Normal 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
|
@ -44,11 +44,11 @@ BOOL smbus_PCA9535_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
|
||||
config[1] = data[0];
|
||||
return TRUE;
|
||||
default:
|
||||
log_error("pca9535", "Unknown write command: %02x", code);
|
||||
log_error(plfPCA9535, "Unknown write command: %02x", code);
|
||||
return FALSE;
|
||||
}
|
||||
default:
|
||||
log_error("pca9535", "Unsupported write mode: %01x (%02x)", cmd, code);
|
||||
log_error(plfPCA9535, "Unsupported write mode: %01x (%02x)", cmd, code);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@ -167,11 +167,11 @@ BOOL smbus_PCA9535_read(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
log_error("pca9535", "Unknown read command: %02x", code);
|
||||
log_error(plfPCA9535, "Unknown read command: %02x", code);
|
||||
return FALSE;
|
||||
}
|
||||
default:
|
||||
log_error("pca9535", "Unsupported read mode: %01x (%02x)", cmd, code);
|
||||
log_error(plfPCA9535, "Unsupported read mode: %01x (%02x)", cmd, code);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include <signal.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "devices/_devices.h"
|
||||
#include "drivers/mx.h"
|
||||
@ -15,7 +17,7 @@ DWORD GetImageBase(void) {
|
||||
HANDLE hObject =
|
||||
_CreateFileW(sModulePath, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hObject == INVALID_HANDLE_VALUE) {
|
||||
log_error(BOOT_LOGGER, "Failed to open %ls %03x", sModulePath, GetLastError());
|
||||
log_error(plfBoot, "Failed to open %ls %03x", sModulePath, GetLastError());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -24,11 +26,11 @@ DWORD GetImageBase(void) {
|
||||
_SetFilePointer(hObject, 0, NULL, FILE_BEGIN);
|
||||
_ReadFile(hObject, &dosHeader, sizeof dosHeader, &nRead, NULL);
|
||||
if (nRead != sizeof dosHeader) {
|
||||
log_error(BOOT_LOGGER, "Failed to read DOS header %03x", GetLastError());
|
||||
log_error(plfBoot, "Failed to read DOS header %03x", GetLastError());
|
||||
return 0;
|
||||
}
|
||||
if (dosHeader.e_magic != IMAGE_DOS_SIGNATURE) {
|
||||
log_error(BOOT_LOGGER, "Invalid DOS magic number: %04x", dosHeader.e_magic);
|
||||
log_error(plfBoot, "Invalid DOS magic number: %04x", dosHeader.e_magic);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -36,11 +38,11 @@ DWORD GetImageBase(void) {
|
||||
_SetFilePointer(hObject, dosHeader.e_lfanew, NULL, FILE_BEGIN);
|
||||
_ReadFile(hObject, &ntHeaders32, sizeof ntHeaders32, &nRead, NULL);
|
||||
if (nRead != sizeof ntHeaders32) {
|
||||
log_error(BOOT_LOGGER, "Failed to read NT header %03x", GetLastError());
|
||||
log_error(plfBoot, "Failed to read NT header %03x", GetLastError());
|
||||
return 0;
|
||||
}
|
||||
if (ntHeaders32.Signature != IMAGE_NT_SIGNATURE) {
|
||||
log_error(BOOT_LOGGER, "Invalid NT signature: %08x", ntHeaders32.Signature);
|
||||
log_error(plfBoot, "Invalid NT signature: %08x", ntHeaders32.Signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -53,7 +55,7 @@ void apply_patches(HMODULE hModule) {
|
||||
|
||||
DWORD imageBase = GetImageBase();
|
||||
if (imageBase == 0) {
|
||||
log_error(BOOT_LOGGER, "Failed to locate image base. Patches will not be applied.");
|
||||
log_error(plfBoot, "Failed to locate image base. Patches will not be applied.");
|
||||
return;
|
||||
}
|
||||
imageOffset = (DWORD)hModule - imageBase;
|
||||
@ -62,13 +64,13 @@ void apply_patches(HMODULE hModule) {
|
||||
WideCharToMultiByte(CP_ACP, 0, exeName, -1, exeNameC, sizeof exeNameC, NULL, NULL);
|
||||
|
||||
if (!load_patches(MiceConfig.mice.patches_file, exeNameC)) {
|
||||
log_error(BOOT_LOGGER, "Failed to load patches file %s", MiceConfig.mice.patches_file);
|
||||
log_error(plfBoot, "Failed to load patches file %s", MiceConfig.mice.patches_file);
|
||||
return;
|
||||
}
|
||||
|
||||
patch_t* patch = patch_list->next;
|
||||
if (patch == NULL) {
|
||||
log_warning(BOOT_LOGGER, "No patches to apply. Did you forgot an amiDebug patch file?");
|
||||
log_warning(plfBoot, "No patches to apply. Did you forgot an amiDebug patch file?");
|
||||
}
|
||||
while (patch) {
|
||||
DWORD oldProt;
|
||||
@ -76,7 +78,7 @@ void apply_patches(HMODULE hModule) {
|
||||
PAGE_EXECUTE_READWRITE, &oldProt);
|
||||
|
||||
if (memcmp(patch->match, (void*)((DWORD)patch->address + imageOffset), patch->count) != 0) {
|
||||
log_error(BOOT_LOGGER, "Patch %s failed! from-value missmatch", patch->name);
|
||||
log_error(plfBoot, "Patch %s failed! from-value missmatch", patch->name);
|
||||
VirtualProtect((void*)((DWORD)patch->address + imageOffset), patch->count, oldProt,
|
||||
&oldProt);
|
||||
patch = patch->next;
|
||||
@ -84,7 +86,7 @@ void apply_patches(HMODULE hModule) {
|
||||
}
|
||||
|
||||
memcpy((void*)((DWORD)patch->address + imageOffset), patch->replace, patch->count);
|
||||
log_misc(BOOT_LOGGER, "Patched %d bytes at %08x (%s)", patch->count, patch->address,
|
||||
log_misc(plfBoot, "Patched %d bytes at %08x (%s)", patch->count, patch->address,
|
||||
patch->name);
|
||||
|
||||
patch = patch->next;
|
||||
@ -93,10 +95,11 @@ void apply_patches(HMODULE hModule) {
|
||||
|
||||
void prebind_hooks() {
|
||||
hook_all();
|
||||
init_com_devices();
|
||||
install_devices();
|
||||
// TODO: Figure out why we're needing to call this manually (medium priority)
|
||||
if (wcscmp(exeName, L"ALLNetProc.exe") == 0) {
|
||||
log_warning(BOOT_LOGGER, "Making explicit call to OPENSSL_add_all_algorithms_noconf");
|
||||
log_warning(plfBoot, "Making explicit call to OPENSSL_add_all_algorithms_noconf");
|
||||
|
||||
// OPENSSL_add_all_algorithms_noconf
|
||||
((void (*)(void))(0x00459770))();
|
||||
@ -111,7 +114,7 @@ void init_injection(HMODULE hModule) {
|
||||
|
||||
// We're in a new context now, so need to reconfigure
|
||||
setup_logging();
|
||||
log_info(BOOT_LOGGER, "Handover complete. Now executing within %ls", exeName);
|
||||
log_info(plfBoot, "Handover complete. Now executing within %ls", exeName);
|
||||
|
||||
if (MiceConfig.mice.apply_patches) apply_patches(hModule);
|
||||
|
||||
@ -132,7 +135,7 @@ void init_injection(HMODULE hModule) {
|
||||
|
||||
if (MiceConfig.drivers.platform) {
|
||||
if (!add_fake_device(&PLATFORM_GUID, L"\\\\.\\platform")) {
|
||||
log_error("platform", "failed to install platform device");
|
||||
log_error(plfPlatform, "failed to install platform device");
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,14 +147,29 @@ void init_injection(HMODULE hModule) {
|
||||
void tea_hook_test(char* fmt, ...) {
|
||||
va_list argp;
|
||||
va_start(argp, fmt);
|
||||
vlog_game("tea", fmt, argp);
|
||||
vlog_game(plfTea, fmt, argp);
|
||||
va_end(argp);
|
||||
}
|
||||
|
||||
int mxkMain();
|
||||
DWORD WINAPI MxkThreadProc(LPVOID lpParameter) { mxkMain(); };
|
||||
int miceDummyMaster(unsigned short textPort, unsigned short binaryPort, bool global);
|
||||
int miceDummyInstaller(unsigned short textPort, unsigned short binaryPort, bool global);
|
||||
DWORD WINAPI MxkThreadProc(LPVOID lpParameter) {
|
||||
mxkMain();
|
||||
return 0;
|
||||
};
|
||||
DWORD WINAPI MdMasterThreadProc(LPVOID lpParameter) {
|
||||
miceDummyMaster(40100, 40101, false);
|
||||
return 0;
|
||||
};
|
||||
DWORD WINAPI MdInstallerThreadProc(LPVOID lpParameter) {
|
||||
miceDummyInstaller(40102, 40103, false);
|
||||
return 0;
|
||||
};
|
||||
void spawn_pcp_processes(void) {
|
||||
// CreateThread(NULL, 0, &MxkThreadProc, NULL, 0, NULL);
|
||||
// CreateThread(NULL, 0, MxkThreadProc, NULL, 0, NULL);
|
||||
// CreateThread(NULL, 0, MdMasterThreadProc, NULL, 0, NULL);
|
||||
// CreateThread(NULL, 0, MdInstallerThreadProc, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
|
||||
@ -171,7 +189,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
||||
spawn_pcp_processes();
|
||||
|
||||
// if (wcscmp(exeName, L"RingGame.exe") == 0) {
|
||||
// log_warning(BOOT_LOGGER, "Bodge hook goo!");
|
||||
// log_warning(plfBoot, "Bodge hook goo!");
|
||||
// CreateHook32((void*)(0x005f2580), &tea_hook_test);
|
||||
// }
|
||||
|
||||
|
@ -10,10 +10,10 @@ BOOL WINAPI columba_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode,
|
||||
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
|
||||
switch (dwIoControlCode) {
|
||||
case IOCTL_COLUMBA_READ:
|
||||
log_misc("columba", "DeviceIoControl(<columba>, <read>, 0x%p, 0x%x, -, 0x%x, -, -)",
|
||||
log_misc(plfColumba, "DeviceIoControl(<columba>, <read>, 0x%p, 0x%x, -, 0x%x, -, -)",
|
||||
lpInBuffer, nInBufferSize, nOutBufferSize);
|
||||
AM_COLUMBA_REQUEST* request = (AM_COLUMBA_REQUEST*)lpInBuffer;
|
||||
log_info("columba", "Physical read: 0x%04x %ss at %08X", request->m_elementCount,
|
||||
log_info(plfColumba, "Physical read: 0x%04x %ss at %08X", request->m_elementCount,
|
||||
request->m_elementSize == 1 ? "byte"
|
||||
: request->m_elementSize == 2 ? "short"
|
||||
: request->m_elementSize == 4 ? "long"
|
||||
@ -41,7 +41,7 @@ BOOL WINAPI columba_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode,
|
||||
memcpy(lpOutBuffer, dmi_table, dmi_size);
|
||||
if (lpBytesReturned) *lpBytesReturned = 0x10000;
|
||||
} else {
|
||||
log_error("columba", "Request to unmapped memory location: %08x",
|
||||
log_error(plfColumba, "Request to unmapped memory location: %08x",
|
||||
request->m_physAddr);
|
||||
return FALSE;
|
||||
}
|
||||
@ -49,7 +49,7 @@ BOOL WINAPI columba_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode,
|
||||
break;
|
||||
default:
|
||||
// Observed: IOCTL_KSEC_RNG_REKEY
|
||||
log_warning("columba", "unhandled 0x%08x", dwIoControlCode);
|
||||
log_warning(plfColumba, "unhandled 0x%08x", dwIoControlCode);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ BOOL WINAPI mxhwreset_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode
|
||||
if (lpBytesReturned) *lpBytesReturned = 0;
|
||||
break;
|
||||
default:
|
||||
log_warning("mxhwreset", "unhandled 0x%08x", dwIoControlCode);
|
||||
log_warning(plfMxHwreset, "unhandled 0x%08x", dwIoControlCode);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
|
@ -113,7 +113,7 @@ unsigned char jvs_exchange(jvs_board_t* board, unsigned char* inData, short inCo
|
||||
unsigned char cmd;
|
||||
jvs_read(cmd);
|
||||
|
||||
// log_info("mxjvs", "CMD: %02x", cmd);
|
||||
// log_info(plfMxJvs, "CMD: %02x", cmd);
|
||||
|
||||
switch (cmd) {
|
||||
case JVS_CMD_RESET:
|
||||
@ -244,12 +244,12 @@ unsigned char jvs_exchange(jvs_board_t* board, unsigned char* inData, short inCo
|
||||
if (i == 0) {
|
||||
if (!!(gpio_value & 0x80) != coin_solenoid) {
|
||||
coin_solenoid = !!(gpio_value & 0x80);
|
||||
log_info("mxjvs", "Coin solenoid: %s",
|
||||
log_info(plfMxJvs, "Coin solenoid: %s",
|
||||
coin_solenoid ? "Locked" : "Unlocked");
|
||||
}
|
||||
}
|
||||
|
||||
// log_warning("mxjvs", "Unhandled GPIO write: *(%d) = %02x", i, gpio_value);
|
||||
// log_warning(plfMxJvs, "Unhandled GPIO write: *(%d) = %02x", i, gpio_value);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -266,7 +266,7 @@ unsigned char jvs_exchange(jvs_board_t* board, unsigned char* inData, short inCo
|
||||
break;
|
||||
|
||||
default:
|
||||
log_error("mxjvs", "Unknown command: 0x%02x", cmd);
|
||||
log_error(plfMxJvs, "Unknown command: 0x%02x", cmd);
|
||||
return JVS_STATUS_UKCOM;
|
||||
}
|
||||
}
|
||||
@ -304,14 +304,14 @@ void mxjvs_handle(unsigned char* paddedIn, short inCount, unsigned char* outData
|
||||
|
||||
// JVS frame is 4 bytes in total
|
||||
if (inCount < 4) {
|
||||
log_error("mxjvs", "inCount impossibly small: %d", inCount);
|
||||
log_error(plfMxJvs, "inCount impossibly small: %d", inCount);
|
||||
jvs_send_status(JVS_STATUS_UNKNOWN, outData, outCount);
|
||||
free(inData);
|
||||
return;
|
||||
}
|
||||
// This isn't a JVS packet
|
||||
if (inData[0] != JVS_SYNC) {
|
||||
log_error("mxjvs", "SYNC missing. Saw 0x%02x", inData[0]);
|
||||
log_error(plfMxJvs, "SYNC missing. Saw 0x%02x", inData[0]);
|
||||
jvs_send_status(JVS_STATUS_UNKNOWN, outData, outCount);
|
||||
free(inData);
|
||||
return;
|
||||
@ -322,7 +322,7 @@ void mxjvs_handle(unsigned char* paddedIn, short inCount, unsigned char* outData
|
||||
bool escape = false;
|
||||
for (int i = 1; i < inCount - 1; i++) sum += inData[i];
|
||||
if (sum != inData[inCount - 1]) {
|
||||
log_error("mxjvs", "Checksum failed. Computed 0x%02x, expected 0x%02x", sum,
|
||||
log_error(plfMxJvs, "Checksum failed. Computed 0x%02x, expected 0x%02x", sum,
|
||||
inData[inCount - 1]);
|
||||
jvs_send_status(JVS_STATUS_SUM, outData, outCount);
|
||||
return;
|
||||
@ -334,8 +334,8 @@ void mxjvs_handle(unsigned char* paddedIn, short inCount, unsigned char* outData
|
||||
return;
|
||||
|
||||
unsigned char* response = malloc(maxOut);
|
||||
unsigned char packetSize;
|
||||
unsigned char status;
|
||||
unsigned char packetSize = 0;
|
||||
unsigned char status = JVS_STATUS_UNKNOWN;
|
||||
if (destination == 0xff) {
|
||||
for (int i = 0; i < MiceConfig.keys.board_count; i++) {
|
||||
jvs_board_t* board = &jvs_boards[i];
|
||||
@ -365,7 +365,7 @@ void mxjvs_handle(unsigned char* paddedIn, short inCount, unsigned char* outData
|
||||
|
||||
free(response);
|
||||
} else {
|
||||
log_error("mxjvs", "JVS board %d returned status %d", destination, status);
|
||||
log_error(plfMxJvs, "JVS board %d returned status %d", destination, status);
|
||||
free(response);
|
||||
jvs_send_status(status, outData, outCount);
|
||||
}
|
||||
@ -376,7 +376,7 @@ BOOL WINAPI mxjvs_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LP
|
||||
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
|
||||
switch (dwIoControlCode) {
|
||||
case IOCTL_MXJVS_EXCHANGE:
|
||||
log_trace("mxjvs",
|
||||
log_trace(plfMxJvs,
|
||||
"DeviceIoControl(<mxjvs>, <exchange>, 0x%p, 0x%x, -, "
|
||||
"0x%x, -, -)",
|
||||
lpInBuffer, nInBufferSize, nOutBufferSize);
|
||||
@ -386,7 +386,7 @@ BOOL WINAPI mxjvs_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LP
|
||||
|
||||
break;
|
||||
default:
|
||||
log_warning("mxjvs", "unhandled 0x%08x", dwIoControlCode);
|
||||
log_warning(plfMxJvs, "unhandled 0x%08x", dwIoControlCode);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -406,7 +406,7 @@ BOOL mxjvs_GetCommModemStatus(void* com, LPDWORD lpModelStat) {
|
||||
BOOL mxjvs_SetCommState(void* com, LPDCB lpDCB) {
|
||||
char PARITY[] = { 'N', 'O', 'E', 'M', 'S' };
|
||||
char* STOP[] = { "1", "1.5", "2" };
|
||||
log_info("mxjvs", "Switching to %d baud (%d%c%s)", lpDCB->BaudRate, lpDCB->ByteSize,
|
||||
log_info(plfMxJvs, "Switching to %d baud (%d%c%s)", lpDCB->BaudRate, lpDCB->ByteSize,
|
||||
PARITY[lpDCB->Parity], STOP[lpDCB->StopBits]);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ uint32_t BILLING_PLAYCOUNT = 69420;
|
||||
BOOL WINAPI mxparallel_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOID lpInBuffer,
|
||||
DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize,
|
||||
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
|
||||
log_trace("mxparallel", "DeviceIoControl(<mxparallel>, 0x%08x, 0x%p, 0x%x, -, 0x%x, -, -)",
|
||||
log_trace(plfMxParallel, "DeviceIoControl(<mxparallel>, 0x%08x, 0x%p, 0x%x, -, 0x%x, -, -)",
|
||||
dwIoControlCode, lpInBuffer, nInBufferSize, nOutBufferSize);
|
||||
|
||||
switch (dwIoControlCode) {
|
||||
@ -68,7 +68,7 @@ BOOL WINAPI mxparallel_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCod
|
||||
return TRUE;
|
||||
case IOCTL_MXPARALLEL_WRITE_CTRL_PORT:
|
||||
parallel_ctrl = ((LPBYTE)lpInBuffer)[0];
|
||||
// log_warning("mxparallel", "Write ctrl %08x", parallel_ctrl);
|
||||
// log_warning(plfMxParallel, "Write ctrl %08x", parallel_ctrl);
|
||||
outLen(0);
|
||||
return TRUE;
|
||||
|
||||
@ -231,37 +231,37 @@ void mxparallel_process_packet(BYTE* request) {
|
||||
switch (request[0]) {
|
||||
// We're pretending to be the keychip, so S and R are swapped for us!
|
||||
case SetKeyS:
|
||||
log_info("mxparallel", "SetKeyS");
|
||||
log_info(plfMxParallel, "SetKeyS");
|
||||
micexkRecvPacket(request);
|
||||
mxkSetKeyR(request);
|
||||
micexkSendPacket(response);
|
||||
break;
|
||||
case SetKeyR:
|
||||
log_info("mxparallel", "SetKeyR");
|
||||
log_info(plfMxParallel, "SetKeyR");
|
||||
micexkRecvPacket(request);
|
||||
mxkSetKeyS(request);
|
||||
micexkSendPacket(response);
|
||||
break;
|
||||
|
||||
case Encrypt:
|
||||
log_info("mxparallel", "Encrypt");
|
||||
log_info(plfMxParallel, "Encrypt");
|
||||
micexkRecvPacket(request);
|
||||
micexkSendPacket(request);
|
||||
break;
|
||||
case Decrypt:
|
||||
log_info("mxparallel", "Decrypt");
|
||||
log_info(plfMxParallel, "Decrypt");
|
||||
micexkRecvPacket(request);
|
||||
micexkSendPacket(request);
|
||||
break;
|
||||
case SetIV:
|
||||
log_info("mxparallel", "SetIV");
|
||||
log_info(plfMxParallel, "SetIV");
|
||||
ZeroMemory(kc_aes_iv, sizeof kc_aes_iv);
|
||||
micexkSendPacket(response);
|
||||
break;
|
||||
case GetAppBootInfo:
|
||||
log_info("mxparallel", "GetAppBootInfo");
|
||||
log_info(plfMxParallel, "GetAppBootInfo");
|
||||
if (request[1] != 0x00) {
|
||||
log_warning("mxparallel", "GetAppBootInfo[%d] unexpected!", request[1]);
|
||||
log_warning(plfMxParallel, "GetAppBootInfo[%d] unexpected!", request[1]);
|
||||
}
|
||||
|
||||
APPBOOT.crc = amiCrc32RCalc(sizeof APPBOOT - 4, (unsigned char*)&APPBOOT + 4, 0);
|
||||
@ -271,7 +271,7 @@ void mxparallel_process_packet(BYTE* request) {
|
||||
break;
|
||||
|
||||
case KcGetVersion:
|
||||
log_info("mxparallel", "GetVersion");
|
||||
log_info(plfMxParallel, "GetVersion");
|
||||
response[0] = 0x01;
|
||||
response[1] = 0x04;
|
||||
micexkSendPacket(response);
|
||||
@ -280,18 +280,18 @@ void mxparallel_process_packet(BYTE* request) {
|
||||
case FlashRead: {
|
||||
uint32_t addr = request[1] | (request[2] << 8) | (request[3] << 16);
|
||||
uint32_t nbytes = request[4] | (request[5] << 8) | (request[6] << 16);
|
||||
log_info("mxparallel", "FlashRead: %06x/%06x", addr, nbytes);
|
||||
log_info(plfMxParallel, "FlashRead: %06x/%06x", addr, nbytes);
|
||||
|
||||
if (addr + nbytes <= sizeof flash)
|
||||
micexkTransportSend(&flash[addr], nbytes);
|
||||
else
|
||||
log_error("mxparallel", "Flash read would exceed storage!");
|
||||
log_error(plfMxParallel, "Flash read would exceed storage!");
|
||||
|
||||
break;
|
||||
}
|
||||
case FlashErase: {
|
||||
uint32_t addr = request[1] | (request[2] << 8) | (request[3] << 16);
|
||||
log_info("mxparallel", "FlashErase: %06x", addr);
|
||||
log_info(plfMxParallel, "FlashErase: %06x", addr);
|
||||
|
||||
micexkSendPacket(response);
|
||||
break;
|
||||
@ -299,12 +299,12 @@ void mxparallel_process_packet(BYTE* request) {
|
||||
case FlashWrite: {
|
||||
uint32_t addr = request[1] | (request[2] << 8) | (request[3] << 16);
|
||||
uint32_t nbytes = request[4] | (request[5] << 8) | (request[6] << 16);
|
||||
log_info("mxparallel", "FlashWrite: %06x/%06x", addr, nbytes);
|
||||
log_info(plfMxParallel, "FlashWrite: %06x/%06x", addr, nbytes);
|
||||
|
||||
if (addr + nbytes <= sizeof flash)
|
||||
micexkTransportRecv(&flash[addr], nbytes);
|
||||
else
|
||||
log_error("mxparallel", "Flash write would exceed storage!");
|
||||
log_error(plfMxParallel, "Flash write would exceed storage!");
|
||||
|
||||
micexkSendPacket(response);
|
||||
dump_nv_storage();
|
||||
@ -315,12 +315,12 @@ void mxparallel_process_packet(BYTE* request) {
|
||||
case EepromWrite: {
|
||||
// TODO: What is this? Appears to be some sort of EEPROM write
|
||||
uint8_t offset = request[1];
|
||||
log_info("mxparallel", "EepromWrite: %02x", offset);
|
||||
log_info(plfMxParallel, "EepromWrite: %02x", offset);
|
||||
|
||||
if (offset * 16 + 16 <= sizeof eeprom) {
|
||||
micexkRecvPacket(&eeprom[offset * 16]);
|
||||
} else {
|
||||
log_error("mxparallel", "EEPROM write would exceed storage!");
|
||||
log_error(plfMxParallel, "EEPROM write would exceed storage!");
|
||||
}
|
||||
micexkSendPacket(response);
|
||||
dump_nv_storage();
|
||||
@ -329,12 +329,12 @@ void mxparallel_process_packet(BYTE* request) {
|
||||
case EepromRead: {
|
||||
// TODO: What is this? Appears to be some sort of EEPROM read
|
||||
uint8_t offset = request[1];
|
||||
log_info("mxparallel", "EepromRead: %02x", offset);
|
||||
log_info(plfMxParallel, "EepromRead: %02x", offset);
|
||||
|
||||
if (offset * 16 + 16 <= sizeof eeprom) {
|
||||
micexkSendPacket(&eeprom[offset * 16]);
|
||||
} else {
|
||||
log_error("mxparallel", "EEPROM read would exceed storage!");
|
||||
log_error(plfMxParallel, "EEPROM read would exceed storage!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -344,7 +344,7 @@ void mxparallel_process_packet(BYTE* request) {
|
||||
// TODO: What is this? Appears to be some sort of memory write
|
||||
uint16_t addr = request[1] | (request[2] << 8);
|
||||
uint8_t blocks = request[3];
|
||||
log_info("mxparallel", "NvramWrite: %04x (%02x)", addr, blocks);
|
||||
log_info(plfMxParallel, "NvramWrite: %04x (%02x)", addr, blocks);
|
||||
|
||||
if (addr + blocks * 16 <= sizeof nvram) {
|
||||
for (byte i = 0; i < blocks; i++) {
|
||||
@ -352,7 +352,7 @@ void mxparallel_process_packet(BYTE* request) {
|
||||
}
|
||||
micexkSendPacket(response);
|
||||
} else {
|
||||
log_error("mxparallel", "NVRAM write would exceed storage!");
|
||||
log_error(plfMxParallel, "NVRAM write would exceed storage!");
|
||||
}
|
||||
dump_nv_storage();
|
||||
break;
|
||||
@ -361,26 +361,26 @@ void mxparallel_process_packet(BYTE* request) {
|
||||
// TODO: What is this? Appears to be some sort of memory read
|
||||
uint16_t addr = request[1] | (request[2] << 8);
|
||||
uint8_t blocks = request[3];
|
||||
log_info("mxparallel", "NvramRead: %04x (%02x)", addr, blocks);
|
||||
log_info(plfMxParallel, "NvramRead: %04x (%02x)", addr, blocks);
|
||||
|
||||
if (addr + blocks * 16 <= sizeof nvram) {
|
||||
for (byte i = 0; i < blocks; i++) {
|
||||
micexkSendPacket(&(nvram[addr + (i * 16)]));
|
||||
}
|
||||
} else {
|
||||
log_error("mxparallel", "NVRAM read would exceed storage!");
|
||||
log_error(plfMxParallel, "NVRAM read would exceed storage!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case AddPlayCount:
|
||||
log_info("mxparallel", "AddPlayCount");
|
||||
log_info(plfMxParallel, "AddPlayCount");
|
||||
BILLING_PLAYCOUNT++;
|
||||
micexkSendPacket(response);
|
||||
break;
|
||||
|
||||
case SetMainId:
|
||||
log_info("mxparallel", "SetMainId");
|
||||
log_info(plfMxParallel, "SetMainId");
|
||||
|
||||
// micexkRecvPacket(_MAIN_ID);
|
||||
micexkRecvPacket(request);
|
||||
@ -388,27 +388,27 @@ void mxparallel_process_packet(BYTE* request) {
|
||||
micexkSendPacket(response);
|
||||
break;
|
||||
case GetMainId:
|
||||
log_info("mxparallel", "GetMainId");
|
||||
log_info(plfMxParallel, "GetMainId");
|
||||
micexkSendPacket(_MAIN_ID);
|
||||
break;
|
||||
case SetKeyId:
|
||||
log_info("mxparallel", "SetKeyId");
|
||||
log_info(plfMxParallel, "SetKeyId");
|
||||
micexkRecvPacket(KEYCHIP_ID);
|
||||
micexkSendPacket(response);
|
||||
break;
|
||||
case GetKeyId:
|
||||
log_info("mxparallel", "GetKeyId");
|
||||
log_info(plfMxParallel, "GetKeyId");
|
||||
micexkSendPacket(KEYCHIP_ID);
|
||||
break;
|
||||
|
||||
case GetPlayCounter:
|
||||
log_info("mxparallel", "GetPlayCounter");
|
||||
log_info(plfMxParallel, "GetPlayCounter");
|
||||
((uint32_t*)response)[0] = BILLING_PLAYCOUNT;
|
||||
micexkSendPacket(response);
|
||||
break;
|
||||
|
||||
default:
|
||||
log_error("mxparallel", "Unhandled opcode: %d", request[0]);
|
||||
log_error(plfMxParallel, "Unhandled opcode: %d", request[0]);
|
||||
for (byte i = 0; i < 16; i++) {
|
||||
printf("%02x ", request[i]);
|
||||
}
|
||||
@ -419,7 +419,7 @@ void mxparallel_process_packet(BYTE* request) {
|
||||
}
|
||||
|
||||
DWORD WINAPI mxparallel_thread(LPVOID _) {
|
||||
log_info("mxparallel", "Parallel device thread spawned");
|
||||
log_info(plfMxParallel, "Parallel device thread spawned");
|
||||
clearBusy;
|
||||
clearAck;
|
||||
|
||||
|
@ -55,12 +55,12 @@ BOOL handle_smbus(BYTE command, WORD v_addr, WORD command_code, BYTE nbytes, BYT
|
||||
break;
|
||||
}
|
||||
|
||||
log_trace("smbus", "Making request to %02X (virtual: %04X/%04x, cmd: %01X, code: %04X)", p_addr,
|
||||
log_trace(plfMxSmbus, "Making request to %02X (virtual: %04X/%04x, cmd: %01X, code: %04X)", p_addr,
|
||||
v_addr, command, smb_cmd, command_code);
|
||||
|
||||
smbus_callback_t* callback = smbus_devices[p_addr];
|
||||
if (callback == NULL) {
|
||||
log_error("smbus", "Request to unregistered address: %02x", p_addr);
|
||||
log_error(plfMxSmbus, "Request to unregistered address: %02x", p_addr);
|
||||
return FALSE;
|
||||
}
|
||||
return (*callback)(smb_cmd, command_code, nbytes, data);
|
||||
@ -74,7 +74,7 @@ BOOL WINAPI mxsmbus_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode,
|
||||
|
||||
switch (dwIoControlCode) {
|
||||
case IOCTL_MXSMBUS_GET_VERSION:
|
||||
log_misc("mxsmbus",
|
||||
log_misc(plfMxSmbus,
|
||||
"DeviceIoControl(<mxsmbus>, <get version>, 0x%p, 0x%x, "
|
||||
"-, 0x%x, -, -)",
|
||||
lpInBuffer, nInBufferSize, nOutBufferSize);
|
||||
@ -115,7 +115,7 @@ BOOL WINAPI mxsmbus_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode,
|
||||
};
|
||||
}
|
||||
default:
|
||||
log_warning("mxsmbus", "unhandled 0x%08x", dwIoControlCode);
|
||||
log_warning(plfMxSmbus, "unhandled 0x%08x", dwIoControlCode);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
@ -128,6 +128,6 @@ void setup_mxsmbus() {
|
||||
hook_file(mxsmbus);
|
||||
|
||||
if (!add_fake_device(&MXSMBUS_GUID, L"\\\\.\\mxsmbus")) {
|
||||
log_error("mxsmbus", "failed to install mxsmbus device");
|
||||
log_error(plfMxSmbus, "failed to install mxsmbus device");
|
||||
}
|
||||
}
|
||||
|
@ -2,30 +2,11 @@
|
||||
#include "../../maiBackupStructs.h"
|
||||
#include "mx.h"
|
||||
|
||||
#define SRAM_DUMP L"dev/sram.bin"
|
||||
#define SRAM_PATH L"dev/sram.bin"
|
||||
#define SRAM_SIZE 1024 * 2084
|
||||
LPBYTE SRAM;
|
||||
|
||||
void sram_dump() {
|
||||
HANDLE dump =
|
||||
_CreateFileW(SRAM_DUMP, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
|
||||
if (dump == INVALID_HANDLE_VALUE) {
|
||||
log_error("sram", "CreateFileA(SRAM_DUMP) failed");
|
||||
return;
|
||||
}
|
||||
_WriteFile(dump, SRAM, SRAM_SIZE, NULL, NULL);
|
||||
_CloseHandle(dump);
|
||||
}
|
||||
|
||||
void sram_restore() {
|
||||
HANDLE dump = _CreateFileW(SRAM_DUMP, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (dump == INVALID_HANDLE_VALUE) return;
|
||||
DWORD read;
|
||||
if (!_ReadFile(dump, SRAM, SRAM_SIZE, &read, NULL))
|
||||
log_error("sram", "failed to restore (%d)", GetLastError());
|
||||
_CloseHandle(dump);
|
||||
}
|
||||
LPBYTE SRAM_DATA = NULL;
|
||||
HANDLE SRAM_FILE = INVALID_HANDLE_VALUE;
|
||||
HANDLE SRAM_FILE_MAPPING = INVALID_HANDLE_VALUE;
|
||||
|
||||
#define ADDR_BACKUP 0x0000
|
||||
#define ADDR_HM_PEAK 0x0200
|
||||
@ -33,43 +14,53 @@ void sram_restore() {
|
||||
#define ADDR_ERROR_LOG 0x0600
|
||||
#define ADDR_DUP 0x1000
|
||||
|
||||
#define fix_crc(block) \
|
||||
do { \
|
||||
#define fix_crc(block) \
|
||||
do { \
|
||||
(block).m_Crc = amiCrc32RCalc(sizeof(block) - 4, (BYTE*)(&(block)) + 4, 0); \
|
||||
} while (0)
|
||||
|
||||
int build_sram() {
|
||||
static BOOL built = false;
|
||||
if (built) return 0;
|
||||
built = true;
|
||||
log_info(plfMxSram, "Building default SRAM file");
|
||||
|
||||
log_info("mxsram", "Building default SRAM file");
|
||||
memset(SRAM_DATA, 0xff, SRAM_SIZE);
|
||||
|
||||
AM_SYSDATAwH_BACKUP Backup = { 0 };
|
||||
fix_crc(Backup);
|
||||
memcpy(SRAM + ADDR_BACKUP, (unsigned char*)&Backup, sizeof Backup);
|
||||
memcpy(SRAM + ADDR_BACKUP + ADDR_DUP, (unsigned char*)&Backup, sizeof Backup);
|
||||
memcpy(SRAM_DATA + ADDR_BACKUP, (unsigned char*)&Backup, sizeof Backup);
|
||||
memcpy(SRAM_DATA + ADDR_BACKUP + ADDR_DUP, (unsigned char*)&Backup, sizeof Backup);
|
||||
|
||||
AM_SYSDATAwH_HM_PEAK HmPeak = { 0 };
|
||||
fix_crc(HmPeak);
|
||||
memcpy(SRAM + ADDR_HM_PEAK, (unsigned char*)&HmPeak, sizeof HmPeak);
|
||||
memcpy(SRAM + ADDR_HM_PEAK + ADDR_DUP, (unsigned char*)&HmPeak, sizeof HmPeak);
|
||||
memcpy(SRAM_DATA + ADDR_HM_PEAK, (unsigned char*)&HmPeak, sizeof HmPeak);
|
||||
memcpy(SRAM_DATA + ADDR_HM_PEAK + ADDR_DUP, (unsigned char*)&HmPeak, sizeof HmPeak);
|
||||
|
||||
AM_SYSDATAwH_TIMEZONE Timezone = { 0 };
|
||||
fix_crc(Timezone);
|
||||
memcpy(SRAM + ADDR_TIMEZONE, (unsigned char*)&Timezone, sizeof Timezone);
|
||||
memcpy(SRAM + ADDR_TIMEZONE + ADDR_DUP, (unsigned char*)&Timezone, sizeof Timezone);
|
||||
memcpy(SRAM_DATA + ADDR_TIMEZONE, (unsigned char*)&Timezone, sizeof Timezone);
|
||||
memcpy(SRAM_DATA + ADDR_TIMEZONE + ADDR_DUP, (unsigned char*)&Timezone, sizeof Timezone);
|
||||
|
||||
AM_SYSDATAwH_ERROR_LOG ErrorLog = { 0 };
|
||||
fix_crc(ErrorLog);
|
||||
memcpy(SRAM + ADDR_ERROR_LOG, (unsigned char*)&ErrorLog, sizeof ErrorLog);
|
||||
memcpy(SRAM + ADDR_ERROR_LOG + ADDR_DUP, (unsigned char*)&ErrorLog, sizeof ErrorLog);
|
||||
|
||||
sram_dump();
|
||||
memcpy(SRAM_DATA + ADDR_ERROR_LOG, (unsigned char*)&ErrorLog, sizeof ErrorLog);
|
||||
memcpy(SRAM_DATA + ADDR_ERROR_LOG + ADDR_DUP, (unsigned char*)&ErrorLog, sizeof ErrorLog);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ensure_valid_sram() {
|
||||
if (!SRAM_DATA) {
|
||||
BOOL isNew = !FileExists(SRAM_PATH);
|
||||
|
||||
SRAM_DATA = open_mapped_file(SRAM_PATH, SRAM_SIZE, &SRAM_FILE, &SRAM_FILE_MAPPING);
|
||||
if (SRAM_DATA == NULL) {
|
||||
log_error(plfMxSram, "SRAM will be memory-backed and not syncronised!");
|
||||
SRAM_DATA = malloc(SRAM_SIZE);
|
||||
}
|
||||
|
||||
if (isNew) build_sram();
|
||||
}
|
||||
}
|
||||
|
||||
BOOL WINAPI mxsram_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOID lpInBuffer,
|
||||
DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize,
|
||||
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
|
||||
@ -78,7 +69,7 @@ BOOL WINAPI mxsram_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
|
||||
|
||||
switch (dwIoControlCode) {
|
||||
case IOCTL_MXSRAM_PING: // Get version
|
||||
log_info("mxsram",
|
||||
log_info(plfMxSram,
|
||||
"DeviceIoControl(<mxsram>, <ping>, 0x%p, 0x%x, -, 0x%x, "
|
||||
"-, -)",
|
||||
lpInBuffer, nInBufferSize, nOutBufferSize);
|
||||
@ -87,7 +78,7 @@ BOOL WINAPI mxsram_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
|
||||
if (lpBytesReturned) *lpBytesReturned = 4;
|
||||
break;
|
||||
case IOCTL_DISK_GET_DRIVE_GEOMETRY:
|
||||
log_info("mxsram",
|
||||
log_info(plfMxSram,
|
||||
"DeviceIoControl(<mxsram>, <get drive geom>, 0x%p, "
|
||||
"0x%x, -, 0x%x, -, -)",
|
||||
lpInBuffer, nInBufferSize, nOutBufferSize);
|
||||
@ -102,10 +93,10 @@ BOOL WINAPI mxsram_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
|
||||
if (lpBytesReturned) *lpBytesReturned = sizeof(DISK_GEOMETRY);
|
||||
break;
|
||||
case IOCTL_DISK_GET_LENGTH_INFO:
|
||||
log_error("mxsram", "Unhandled IOCTL_DISK_GET_LENGTH_INFO");
|
||||
log_error(plfMxSram, "Unhandled IOCTL_DISK_GET_LENGTH_INFO");
|
||||
return FALSE;
|
||||
case IOCTL_MXSRAM_GET_SECTOR_SIZE:
|
||||
log_info("mxsram",
|
||||
log_info(plfMxSram,
|
||||
"DeviceIoControl(<mxsram>, <get sector size>, 0x%p, "
|
||||
"0x%x, -, 0x%x, -, -)",
|
||||
lpInBuffer, nInBufferSize, nOutBufferSize);
|
||||
@ -114,7 +105,7 @@ BOOL WINAPI mxsram_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
|
||||
if (lpBytesReturned) *lpBytesReturned = 4;
|
||||
break;
|
||||
default:
|
||||
log_warning("mxsram", "unhandled 0x%08x", dwIoControlCode);
|
||||
log_warning(plfMxSram, "unhandled 0x%08x", dwIoControlCode);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -123,43 +114,31 @@ BOOL WINAPI mxsram_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
|
||||
|
||||
BOOL mxsram_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
|
||||
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped) {
|
||||
log_misc("mxsram", "sram write 0x%04x bytes at 0x%04x", nNumberOfBytesToWrite,
|
||||
log_misc(plfMxSram, "sram write 0x%04x bytes at 0x%04x", nNumberOfBytesToWrite,
|
||||
ctx->m_Pointer.LowPart);
|
||||
if (ctx->m_Pointer.LowPart + nNumberOfBytesToWrite >= SRAM_SIZE) {
|
||||
nNumberOfBytesToWrite = SRAM_SIZE - ctx->m_Pointer.LowPart;
|
||||
}
|
||||
memcpy(SRAM + ctx->m_Pointer.LowPart, lpBuffer, nNumberOfBytesToWrite);
|
||||
sram_dump();
|
||||
ensure_valid_sram();
|
||||
memcpy(SRAM_DATA + ctx->m_Pointer.LowPart, lpBuffer, nNumberOfBytesToWrite);
|
||||
*lpNumberOfBytesWritten = nNumberOfBytesToWrite;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL mxsram_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
||||
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) {
|
||||
log_misc("mxsram", "sram read 0x%04x bytes at 0x%04x", nNumberOfBytesToRead,
|
||||
log_misc(plfMxSram, "sram read 0x%04x bytes at 0x%04x", nNumberOfBytesToRead,
|
||||
ctx->m_Pointer.LowPart);
|
||||
if (ctx->m_Pointer.LowPart + nNumberOfBytesToRead >= SRAM_SIZE) {
|
||||
nNumberOfBytesToRead = SRAM_SIZE - ctx->m_Pointer.LowPart;
|
||||
}
|
||||
sram_restore();
|
||||
memcpy((LPVOID)lpBuffer, SRAM + ctx->m_Pointer.LowPart, nNumberOfBytesToRead);
|
||||
ensure_valid_sram();
|
||||
memcpy((LPVOID)lpBuffer, SRAM_DATA + ctx->m_Pointer.LowPart, nNumberOfBytesToRead);
|
||||
*lpNumberOfBytesRead = nNumberOfBytesToRead;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void setup_mxsram() {
|
||||
// Allocate 2MB of SRAM
|
||||
SRAM = (LPBYTE)malloc(SRAM_SIZE);
|
||||
if (!SRAM) {
|
||||
log_error(BOOT_LOGGER, "unable to allocate 2MiB for SRAM");
|
||||
exit(1);
|
||||
}
|
||||
memset(SRAM, 0xff, SRAM_SIZE);
|
||||
if (FileExists(SRAM_DUMP))
|
||||
sram_restore();
|
||||
else
|
||||
build_sram();
|
||||
|
||||
file_hook_t* mxsram = new_file_hook(L"\\\\.\\mxsram");
|
||||
mxsram->DeviceIoControl = &mxsram_DeviceIoControl;
|
||||
mxsram->ReadFile = &mxsram_ReadFile;
|
||||
|
@ -96,7 +96,7 @@ BYTE hwmon_read(superio_packet* packet) {
|
||||
return w83791d_vbat_monitor_control;
|
||||
|
||||
default:
|
||||
log_error("mxsuperio", "Unknown HM b0 register: read 0x%02x", reg);
|
||||
log_error(plfMxSuperio, "Unknown HM b0 register: read 0x%02x", reg);
|
||||
return 0xff;
|
||||
}
|
||||
} break;
|
||||
@ -124,7 +124,7 @@ BYTE hwmon_read(superio_packet* packet) {
|
||||
return W83791D_ENTITY_SYSTEM;
|
||||
|
||||
default:
|
||||
log_error("mxsuperio", "Unknown HM b1 register: 0x%02x", reg);
|
||||
log_error(plfMxSuperio, "Unknown HM b1 register: 0x%02x", reg);
|
||||
exit(1);
|
||||
}
|
||||
} break;
|
||||
@ -140,12 +140,12 @@ BYTE hwmon_read(superio_packet* packet) {
|
||||
return 0xff;
|
||||
|
||||
default:
|
||||
log_error("mxsuperio", "Unknown HM b5 register: 0x%02x", reg);
|
||||
log_error(plfMxSuperio, "Unknown HM b5 register: 0x%02x", reg);
|
||||
return 0xff;
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
log_error("mxsuperio", "Unknown HM bank: 0x%02x", w83791d_bank);
|
||||
log_error(plfMxSuperio, "Unknown HM bank: 0x%02x", w83791d_bank);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@ -197,7 +197,7 @@ void hwmon_write(superio_packet* packet) {
|
||||
w83791d_vbat_monitor_control = packet->data;
|
||||
break;
|
||||
default:
|
||||
log_error("mxsuperio", "Unknown HM b0 register: write 0x%02x", packet->reg);
|
||||
log_error(plfMxSuperio, "Unknown HM b0 register: write 0x%02x", packet->reg);
|
||||
// exit(1);
|
||||
}
|
||||
break;
|
||||
@ -229,7 +229,7 @@ void hwmon_write(superio_packet* packet) {
|
||||
break;
|
||||
|
||||
default:
|
||||
log_error("mxsuperio", "Unknown HM b1 register: 0x%02x", packet->reg);
|
||||
log_error(plfMxSuperio, "Unknown HM b1 register: 0x%02x", packet->reg);
|
||||
exit(1);
|
||||
}
|
||||
} break;
|
||||
@ -246,12 +246,12 @@ void hwmon_write(superio_packet* packet) {
|
||||
break;
|
||||
|
||||
default:
|
||||
log_error("mxsuperio", "Unknown HM b5 register: 0x%02x", packet->reg);
|
||||
log_error(plfMxSuperio, "Unknown HM b5 register: 0x%02x", packet->reg);
|
||||
return;
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
log_error("mxsuperio", "Unknown HM bank: 0x%02x", w83791d_bank);
|
||||
log_error(plfMxSuperio, "Unknown HM bank: 0x%02x", w83791d_bank);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@ -291,7 +291,7 @@ BOOL WINAPI mxsuperio_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode
|
||||
//
|
||||
}
|
||||
W83627UHG_processed:
|
||||
log_misc("mxsuperio", "read: chip:%d device:%d reg:%02x data:%02x", packet->chip,
|
||||
log_misc(plfMxSuperio, "read: chip:%d device:%d reg:%02x data:%02x", packet->chip,
|
||||
packet->device, packet->reg, packet->data);
|
||||
break;
|
||||
}
|
||||
@ -299,7 +299,7 @@ BOOL WINAPI mxsuperio_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode
|
||||
superio_lpc_packet* packet = (superio_lpc_packet*)(lpInBuffer);
|
||||
if (lpBytesReturned) *lpBytesReturned = sizeof *packet;
|
||||
|
||||
log_misc("mxsuperio", "write: chip:%d device:%d reg:%02x data:%02x", packet->chip,
|
||||
log_misc(plfMxSuperio, "write: chip:%d device:%d reg:%02x data:%02x", packet->chip,
|
||||
packet->device, packet->reg, packet->data);
|
||||
|
||||
// TODO: Are there any writes we need to process?
|
||||
@ -319,13 +319,13 @@ BOOL WINAPI mxsuperio_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode
|
||||
} else {
|
||||
lpc_out->data = 0xff;
|
||||
}
|
||||
log_misc("mxsuperio", "amHmLpcReadByte Index=0x%02x Reg=0x%02x Data=0x%02x",
|
||||
log_misc(plfMxSuperio, "amHmLpcReadByte Index=0x%02x Reg=0x%02x Data=0x%02x",
|
||||
lpc_packet->index, lpc_packet->reg, lpc_out->data);
|
||||
|
||||
if (lpBytesReturned) *lpBytesReturned = sizeof *lpc_out;
|
||||
} break;
|
||||
case IOCTL_MXSUPERIO_HWMONITOR_LPC_WRITE: {
|
||||
log_misc("mxsuperio", "amHmLpcWriteByte Index=0x%02x Reg=0x%02x Data=0x%02b",
|
||||
log_misc(plfMxSuperio, "amHmLpcWriteByte Index=0x%02x Reg=0x%02x Data=0x%02b",
|
||||
lpc_packet->index, lpc_packet->reg, lpc_packet->data);
|
||||
|
||||
if (lpc_packet->index == LPC_CONFIGURATION) {
|
||||
@ -334,7 +334,7 @@ BOOL WINAPI mxsuperio_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode
|
||||
if (lpBytesReturned) *lpBytesReturned = 0;
|
||||
} break;
|
||||
default:
|
||||
log_warning("mxsuperio", "unhandled 0x%08x", dwIoControlCode);
|
||||
log_warning(plfMxSuperio, "unhandled 0x%08x", dwIoControlCode);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
102
src/micetools/dll/games.c
Normal file
102
src/micetools/dll/games.c
Normal 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();
|
||||
}
|
@ -157,8 +157,9 @@ void hud_sram(ImGuiKey open_key) {
|
||||
if (igIsKeyPressed_Bool(open_key, false)) editor.Open = !editor.Open;
|
||||
|
||||
// TODO: Less hacky :)
|
||||
extern LPBYTE SRAM;
|
||||
if (editor.Open) MemoryEditor_DrawWindow(&editor, "SRAM Editor", SRAM, 1024 * 1024, 0x0000);
|
||||
extern LPBYTE SRAM_DATA;
|
||||
if (editor.Open)
|
||||
MemoryEditor_DrawWindow(&editor, "SRAM Editor", SRAM_DATA, 1024 * 1024, 0x0000);
|
||||
}
|
||||
|
||||
void igHelpMarker(const char* text) {
|
||||
@ -733,6 +734,7 @@ void AddSettingButton(int board, int id) {
|
||||
if (igKeyBindPopup(name, &boundKey)) {
|
||||
if (boundKey != -1) {
|
||||
jvsKeybindings[board].buttons[id * 2 + (currentlyBinding - 1)] = boundKey;
|
||||
jvsKeybindings[board].notdefault = 1;
|
||||
save_current_config();
|
||||
}
|
||||
currentlyBinding = 0;
|
||||
@ -890,7 +892,7 @@ void tab_main_keybinds() {
|
||||
}
|
||||
|
||||
void hud_control(ImGuiKey open_key) {
|
||||
static bool isOpen = true;
|
||||
static bool isOpen = false;
|
||||
static bool oldCursor;
|
||||
if (igIsKeyPressed_Bool(open_key, false)) {
|
||||
isOpen = !isOpen;
|
||||
@ -938,7 +940,6 @@ void hud_control(ImGuiKey open_key) {
|
||||
}
|
||||
|
||||
void __stdcall hud_gui(unsigned int hookType, IDirect3DDevice9* dev) {
|
||||
static bool showMenu = false;
|
||||
ShowCursor(1);
|
||||
|
||||
static bool initialized = false;
|
||||
|
@ -28,34 +28,34 @@ com_hook_t* new_com_hook(BYTE port) {
|
||||
|
||||
BOOL WINAPI FakeGetCommState(HANDLE hFile, LPDCB lpDCB) {
|
||||
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
|
||||
log_misc(COMM_LOGGER, "GetCommState(0x%p, 0x%p) (%08x)", hFile, lpDCB, hook);
|
||||
log_misc(plfComm, "GetCommState(0x%p, 0x%p) (%08x)", hFile, lpDCB, hook);
|
||||
|
||||
if (pHData == NULL || pHData->hook->com_hook == NULL) return TrueGetCommState(hFile, lpDCB);
|
||||
com_hook_t* com_hook = pHData->hook->com_hook;
|
||||
|
||||
if (com_hook->GetCommState == NULL) {
|
||||
log_error(COMM_LOGGER, "GetCommState(%ls) unimplemented", com_hook->wName);
|
||||
log_error(plfComm, "GetCommState(%ls) unimplemented", com_hook->wName);
|
||||
return FALSE;
|
||||
}
|
||||
return com_hook->GetCommState(hFile, lpDCB);
|
||||
}
|
||||
|
||||
BOOL WINAPI FakeSetCommState(HANDLE hFile, LPDCB lpDCB) {
|
||||
log_misc(COMM_LOGGER, "SetCommState(0x%p, 0x%p)", hFile, lpDCB);
|
||||
log_misc(plfComm, "SetCommState(0x%p, 0x%p)", hFile, lpDCB);
|
||||
|
||||
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
|
||||
if (pHData == NULL || pHData->hook->com_hook == NULL) return TrueSetCommState(hFile, lpDCB);
|
||||
|
||||
com_hook_t* com_hook = pHData->hook->com_hook;
|
||||
if (com_hook->SetCommState == NULL) {
|
||||
log_error(COMM_LOGGER, "SetCommState(%ls) unimplemented", com_hook->wName);
|
||||
log_error(plfComm, "SetCommState(%ls) unimplemented", com_hook->wName);
|
||||
return FALSE;
|
||||
}
|
||||
return com_hook->SetCommState(hFile, lpDCB);
|
||||
}
|
||||
|
||||
BOOL WINAPI FakeGetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) {
|
||||
log_misc(COMM_LOGGER, "GetCommTimeouts(0x%p, 0x%p)", hFile, lpCommTimeouts);
|
||||
log_misc(plfComm, "GetCommTimeouts(0x%p, 0x%p)", hFile, lpCommTimeouts);
|
||||
|
||||
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
|
||||
if (pHData == NULL || pHData->hook->com_hook == NULL)
|
||||
@ -63,14 +63,14 @@ BOOL WINAPI FakeGetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) {
|
||||
|
||||
com_hook_t* com_hook = pHData->hook->com_hook;
|
||||
if (com_hook->GetCommTimeouts == NULL) {
|
||||
log_error(COMM_LOGGER, "GetCommTimeouts(%ls) unimplemented", com_hook->wName);
|
||||
log_error(plfComm, "GetCommTimeouts(%ls) unimplemented", com_hook->wName);
|
||||
return FALSE;
|
||||
}
|
||||
return com_hook->GetCommTimeouts(hFile, lpCommTimeouts);
|
||||
}
|
||||
|
||||
BOOL WINAPI FakeSetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) {
|
||||
log_misc(COMM_LOGGER, "SetCommTimeouts(0x%p, 0x%p)", hFile, lpCommTimeouts);
|
||||
log_misc(plfComm, "SetCommTimeouts(0x%p, 0x%p)", hFile, lpCommTimeouts);
|
||||
|
||||
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
|
||||
if (pHData == NULL || pHData->hook->com_hook == NULL)
|
||||
@ -78,14 +78,14 @@ BOOL WINAPI FakeSetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) {
|
||||
|
||||
com_hook_t* com_hook = pHData->hook->com_hook;
|
||||
if (com_hook->SetCommTimeouts == NULL) {
|
||||
log_error(COMM_LOGGER, "SetCommTimeouts(%ls) unimplemented", com_hook->wName);
|
||||
log_error(plfComm, "SetCommTimeouts(%ls) unimplemented", com_hook->wName);
|
||||
return FALSE;
|
||||
}
|
||||
return com_hook->SetCommTimeouts(hFile, lpCommTimeouts);
|
||||
}
|
||||
|
||||
BOOL WINAPI FakeSetupComm(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue) {
|
||||
log_misc(COMM_LOGGER, "SetupCom(0x%p, 0x%08x, 0x%08x)", hFile, dwInQueue, dwOutQueue);
|
||||
log_misc(plfComm, "SetupCom(0x%p, 0x%08x, 0x%08x)", hFile, dwInQueue, dwOutQueue);
|
||||
|
||||
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
|
||||
if (pHData == NULL || pHData->hook->com_hook == NULL)
|
||||
@ -93,28 +93,28 @@ BOOL WINAPI FakeSetupComm(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue) {
|
||||
|
||||
com_hook_t* com_hook = pHData->hook->com_hook;
|
||||
if (com_hook->SetupComm == NULL) {
|
||||
log_error(COMM_LOGGER, "SetupComm(%ls) unimplemented", com_hook->wName);
|
||||
log_error(plfComm, "SetupComm(%ls) unimplemented", com_hook->wName);
|
||||
return FALSE;
|
||||
}
|
||||
return com_hook->SetupComm(hFile, dwInQueue, dwOutQueue);
|
||||
}
|
||||
|
||||
BOOL WINAPI FakePurgeComm(HANDLE hFile, DWORD dwFlags) {
|
||||
log_misc(COMM_LOGGER, "PurgeComm(0x%p, 0x%08x)", hFile, dwFlags);
|
||||
log_misc(plfComm, "PurgeComm(0x%p, 0x%08x)", hFile, dwFlags);
|
||||
|
||||
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
|
||||
if (pHData == NULL || pHData->hook->com_hook == NULL) return TruePurgeComm(hFile, dwFlags);
|
||||
|
||||
com_hook_t* com_hook = pHData->hook->com_hook;
|
||||
if (com_hook->PurgeComm == NULL) {
|
||||
log_error(COMM_LOGGER, "PurgeComm(%ls) unimplemented", com_hook->wName);
|
||||
log_error(plfComm, "PurgeComm(%ls) unimplemented", com_hook->wName);
|
||||
return FALSE;
|
||||
}
|
||||
return com_hook->PurgeComm(hFile, dwFlags);
|
||||
}
|
||||
|
||||
BOOL WINAPI FakeGetCommModemStatus(HANDLE hFile, LPDWORD lpModelStat) {
|
||||
log_misc(COMM_LOGGER, "GetCommModemStatus(0x%p, 0x%p)", hFile, lpModelStat);
|
||||
log_misc(plfComm, "GetCommModemStatus(0x%p, 0x%p)", hFile, lpModelStat);
|
||||
|
||||
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
|
||||
if (pHData == NULL || pHData->hook->com_hook == NULL)
|
||||
@ -122,14 +122,14 @@ BOOL WINAPI FakeGetCommModemStatus(HANDLE hFile, LPDWORD lpModelStat) {
|
||||
|
||||
com_hook_t* com_hook = pHData->hook->com_hook;
|
||||
if (com_hook->GetCommModemStatus == NULL) {
|
||||
log_error(COMM_LOGGER, "GetCommModemStatus(%ls) unimplemented", com_hook->wName);
|
||||
log_error(plfComm, "GetCommModemStatus(%ls) unimplemented", com_hook->wName);
|
||||
return FALSE;
|
||||
}
|
||||
return com_hook->GetCommModemStatus(hFile, lpModelStat);
|
||||
}
|
||||
|
||||
BOOL WINAPI FakeWaitCommEvent(HANDLE hFile, LPDWORD lpEvtMask, LPOVERLAPPED lpOverlapped) {
|
||||
log_misc(COMM_LOGGER, "WaitCommEvent(0x%p)", hFile);
|
||||
log_misc(plfComm, "WaitCommEvent(0x%p)", hFile);
|
||||
|
||||
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
|
||||
if (pHData == NULL || pHData->hook->com_hook == NULL)
|
||||
@ -137,14 +137,14 @@ BOOL WINAPI FakeWaitCommEvent(HANDLE hFile, LPDWORD lpEvtMask, LPOVERLAPPED lpOv
|
||||
|
||||
com_hook_t* com_hook = pHData->hook->com_hook;
|
||||
if (com_hook->WaitCommEvent == NULL) {
|
||||
log_error(COMM_LOGGER, "WaitCommEvent(%ls) unimplemented", com_hook->wName);
|
||||
log_error(plfComm, "WaitCommEvent(%ls) unimplemented", com_hook->wName);
|
||||
return FALSE;
|
||||
}
|
||||
return com_hook->WaitCommEvent(hFile, lpEvtMask, lpOverlapped);
|
||||
}
|
||||
|
||||
BOOL WINAPI FakeClearCommError(HANDLE hFile, LPDWORD lpErrors, LPCOMSTAT lpStat) {
|
||||
log_trace(COMM_LOGGER, "ClearCommError(0x%p)", hFile);
|
||||
log_trace(plfComm, "ClearCommError(0x%p)", hFile);
|
||||
|
||||
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
|
||||
if (pHData == NULL || pHData->hook->com_hook == NULL)
|
||||
@ -152,7 +152,7 @@ BOOL WINAPI FakeClearCommError(HANDLE hFile, LPDWORD lpErrors, LPCOMSTAT lpStat)
|
||||
|
||||
com_hook_t* com_hook = pHData->hook->com_hook;
|
||||
if (com_hook->ClearCommError == NULL) {
|
||||
log_error(COMM_LOGGER, "ClearCommError(%ls) unimplemented", com_hook->wName);
|
||||
log_error(plfComm, "ClearCommError(%ls) unimplemented", com_hook->wName);
|
||||
return FALSE;
|
||||
}
|
||||
return com_hook->ClearCommError(hFile, lpErrors, lpStat);
|
||||
|
@ -49,21 +49,21 @@ BOOL ReadFunc_Original0(DWORD nOffset, LPVOID lpBuffer, DWORD nNumberOfBytesToRe
|
||||
LPDWORD lpNumberOfBytesRead) {
|
||||
*lpNumberOfBytesRead = 0;
|
||||
if (!_PathFileExistsA(ORIGINAL0_PATH)) {
|
||||
log_error("drive", "Failed to open %s (does not exist)", ORIGINAL0_PATH);
|
||||
log_error(plfDrive, "Failed to open %s (does not exist)", ORIGINAL0_PATH);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HANDLE hFile =
|
||||
_CreateFileA(ORIGINAL0_PATH, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
log_error("drive", "Failed to open %s", ORIGINAL0_PATH);
|
||||
log_error(plfDrive, "Failed to open %s", ORIGINAL0_PATH);
|
||||
return FALSE;
|
||||
}
|
||||
LARGE_INTEGER seekTo;
|
||||
seekTo.QuadPart = (LONGLONG)nOffset * (LONGLONG)SSD.m_BlockSize;
|
||||
_SetFilePointerEx(hFile, seekTo, NULL, FILE_BEGIN);
|
||||
BOOL ret = _ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, NULL);
|
||||
if (!ret) log_error("drive", "Failed to read to %s: %03x", ORIGINAL0_PATH, GetLastError());
|
||||
if (!ret) log_error(plfDrive, "Failed to read to %s: %03x", ORIGINAL0_PATH, GetLastError());
|
||||
_CloseHandle(hFile);
|
||||
return ret;
|
||||
}
|
||||
@ -74,14 +74,14 @@ BOOL WriteFunc_Original0(DWORD nOffset, LPCVOID lpBuffer, DWORD nNumberOfBytesTo
|
||||
HANDLE hFile =
|
||||
_CreateFileA(ORIGINAL0_PATH, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
log_error("drive", "Failed to open %s", ORIGINAL0_PATH);
|
||||
log_error(plfDrive, "Failed to open %s", ORIGINAL0_PATH);
|
||||
return FALSE;
|
||||
}
|
||||
LARGE_INTEGER seekTo;
|
||||
seekTo.QuadPart = (LONGLONG)nOffset * (LONGLONG)SSD.m_BlockSize;
|
||||
_SetFilePointerEx(hFile, seekTo, NULL, FILE_BEGIN);
|
||||
BOOL ret = _WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, NULL);
|
||||
if (!ret) log_error("drive", "Failed to write to %s: %03x", ORIGINAL0_PATH, GetLastError());
|
||||
if (!ret) log_error(plfDrive, "Failed to write to %s: %03x", ORIGINAL0_PATH, GetLastError());
|
||||
_CloseHandle(hFile);
|
||||
return ret;
|
||||
}
|
||||
@ -90,21 +90,21 @@ BOOL ReadFunc_Patch0(DWORD nOffset, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
||||
LPDWORD lpNumberOfBytesRead) {
|
||||
*lpNumberOfBytesRead = 0;
|
||||
if (!_PathFileExistsA(PATCH0_PATH)) {
|
||||
log_error("drive", "Failed to open %s (does not exist)", PATCH0_PATH);
|
||||
log_error(plfDrive, "Failed to open %s (does not exist)", PATCH0_PATH);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HANDLE hFile =
|
||||
_CreateFileA(PATCH0_PATH, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
log_error("drive", "Failed to open %s", PATCH0_PATH);
|
||||
log_error(plfDrive, "Failed to open %s", PATCH0_PATH);
|
||||
return FALSE;
|
||||
}
|
||||
LARGE_INTEGER seekTo;
|
||||
seekTo.QuadPart = (LONGLONG)nOffset * (LONGLONG)SSD.m_BlockSize;
|
||||
_SetFilePointerEx(hFile, seekTo, NULL, FILE_BEGIN);
|
||||
BOOL ret = _ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, NULL);
|
||||
if (!ret) log_error("drive", "Failed to read to %s: %03x", PATCH0_PATH, GetLastError());
|
||||
if (!ret) log_error(plfDrive, "Failed to read to %s: %03x", PATCH0_PATH, GetLastError());
|
||||
_CloseHandle(hFile);
|
||||
return ret;
|
||||
}
|
||||
@ -115,14 +115,14 @@ BOOL WriteFunc_Patch0(DWORD nOffset, LPCVOID lpBuffer, DWORD nNumberOfBytesToWri
|
||||
HANDLE hFile =
|
||||
_CreateFileA(PATCH0_PATH, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
log_error("drive", "Failed to open %s", PATCH0_PATH);
|
||||
log_error(plfDrive, "Failed to open %s", PATCH0_PATH);
|
||||
return FALSE;
|
||||
}
|
||||
LARGE_INTEGER seekTo;
|
||||
seekTo.QuadPart = (LONGLONG)nOffset * (LONGLONG)SSD.m_BlockSize;
|
||||
_SetFilePointerEx(hFile, seekTo, NULL, FILE_BEGIN);
|
||||
BOOL ret = _WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, NULL);
|
||||
if (!ret) log_error("drive", "Failed to write to %s: %03x", PATCH0_PATH, GetLastError());
|
||||
if (!ret) log_error(plfDrive, "Failed to write to %s: %03x", PATCH0_PATH, GetLastError());
|
||||
_CloseHandle(hFile);
|
||||
return ret;
|
||||
}
|
||||
@ -130,7 +130,7 @@ BOOL WriteFunc_Patch0(DWORD nOffset, LPCVOID lpBuffer, DWORD nNumberOfBytesToWri
|
||||
BOOL WriteFunc_OS(DWORD nOffset, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
|
||||
LPDWORD lpNumberOfBytesWritten) {
|
||||
*lpNumberOfBytesWritten = nNumberOfBytesToWrite;
|
||||
log_warning("drive", "%d bytes write in OS at %08x", nNumberOfBytesToWrite, nOffset);
|
||||
log_warning(plfDrive, "%d bytes write in OS at %08x", nNumberOfBytesToWrite, nOffset);
|
||||
return TRUE;
|
||||
}
|
||||
BOOL ReadFunc_OSLogFiles(DWORD nOffset, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
||||
@ -165,13 +165,13 @@ BOOL ReadFunc_OSLogFiles(DWORD nOffset, LPVOID lpBuffer, DWORD nNumberOfBytesToR
|
||||
return TRUE;
|
||||
}
|
||||
if (nOffset == 2048) {
|
||||
log_warning("drive", "Requsted %d bytes of application log file", nNumberOfBytesToRead);
|
||||
log_warning(plfDrive, "Requsted %d bytes of application log file", nNumberOfBytesToRead);
|
||||
ZeroMemory(lpBuffer, nNumberOfBytesToRead);
|
||||
*lpNumberOfBytesRead = nNumberOfBytesToRead;
|
||||
return TRUE;
|
||||
}
|
||||
if (nOffset == 2048 + 1024) {
|
||||
log_warning("drive", "Requsted %d bytes of system log file", nNumberOfBytesToRead);
|
||||
log_warning(plfDrive, "Requsted %d bytes of system log file", nNumberOfBytesToRead);
|
||||
ZeroMemory(lpBuffer, nNumberOfBytesToRead);
|
||||
*lpNumberOfBytesRead = nNumberOfBytesToRead;
|
||||
return TRUE;
|
||||
@ -184,7 +184,7 @@ BOOL ReadFunc_OSLogFiles(DWORD nOffset, LPVOID lpBuffer, DWORD nNumberOfBytesToR
|
||||
BOOL WINAPI c_drive_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOID lpInBuffer,
|
||||
DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize,
|
||||
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
|
||||
log_trace("C", "DeviceIOControl %08x", dwIoControlCode);
|
||||
log_trace(plfDrive, "C:DeviceIOControl %08x", dwIoControlCode);
|
||||
ZeroMemory(lpOutBuffer, nOutBufferSize);
|
||||
switch (dwIoControlCode) {
|
||||
case IOCTL_STORAGE_GET_DEVICE_NUMBER:
|
||||
@ -203,7 +203,7 @@ BOOL WINAPI c_drive_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode,
|
||||
BOOL WINAPI x_drive_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOID lpInBuffer,
|
||||
DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize,
|
||||
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
|
||||
log_trace("X", "DeviceIOControl %08x", dwIoControlCode);
|
||||
log_trace(plfDrive, "X:DeviceIOControl %08x", dwIoControlCode);
|
||||
ZeroMemory(lpOutBuffer, nOutBufferSize);
|
||||
switch (dwIoControlCode) {
|
||||
case IOCTL_STORAGE_GET_DEVICE_NUMBER:
|
||||
@ -211,7 +211,7 @@ BOOL WINAPI x_drive_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode,
|
||||
((STORAGE_DEVICE_NUMBER*)lpOutBuffer)->DeviceNumber = 0;
|
||||
return TRUE;
|
||||
default:
|
||||
log_warning("X", "Unhandled DeviceIOControl %08x", dwIoControlCode);
|
||||
log_warning(plfDrive, "X:Unhandled DeviceIOControl %08x", dwIoControlCode);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@ -219,7 +219,7 @@ BOOL WINAPI x_drive_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode,
|
||||
BOOL WINAPI q_drive_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOID lpInBuffer,
|
||||
DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize,
|
||||
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
|
||||
log_trace("Q", "DeviceIOControl %08x", dwIoControlCode);
|
||||
log_trace(plfDrive, "Q:DeviceIOControl %08x", dwIoControlCode);
|
||||
ZeroMemory(lpOutBuffer, nOutBufferSize);
|
||||
switch (dwIoControlCode) {
|
||||
case IOCTL_STORAGE_MEDIA_REMOVAL:
|
||||
@ -229,7 +229,7 @@ BOOL WINAPI q_drive_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode,
|
||||
((PDISK_GEOMETRY)lpOutBuffer)->BytesPerSector = ALPHA_DVD.m_BlockSize;
|
||||
return TRUE;
|
||||
default:
|
||||
log_warning("Q", "Unhandled DeviceIOControl %08x", dwIoControlCode);
|
||||
log_warning(plfDrive, "Q:Unhandled DeviceIOControl %08x", dwIoControlCode);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@ -380,7 +380,7 @@ inline static BOOL matchVolume(disk_volume_t* volume, LPCSTR lpRootPathName, DWO
|
||||
|
||||
disk_volume_t* getVolumeByPath(LPCSTR lpRootPathName, DWORD match) {
|
||||
if (lpRootPathName == NULL) {
|
||||
log_error("file", "getVolumeByPath(NULL) unimplemented!");
|
||||
log_error(plfDrive, "getVolumeByPath(NULL) unimplemented!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -403,7 +403,7 @@ BOOL WINAPI volume_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
|
||||
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
|
||||
disk_volume_t* volume = (disk_volume_t*)ctx->m_HookData;
|
||||
if (volume == NULL) {
|
||||
log_error("drive", "ctx->m_HookData NULL; expected a volume!");
|
||||
log_error(plfDrive, "ctx->m_HookData NULL; expected a volume!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -435,7 +435,7 @@ BOOL WINAPI volume_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
|
||||
|
||||
if (queryIn->PropertyId != StorageDeviceProperty ||
|
||||
queryIn->QueryType != PropertyStandardQuery) {
|
||||
log_error("drive", "Unimplemented storage query: %d/%d", queryIn->PropertyId,
|
||||
log_error(plfDrive, "Unimplemented storage query: %d/%d", queryIn->PropertyId,
|
||||
queryIn->QueryType);
|
||||
return FALSE;
|
||||
}
|
||||
@ -467,7 +467,7 @@ BOOL WINAPI volume_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L
|
||||
}
|
||||
return TRUE;
|
||||
default:
|
||||
log_error("drive", "Unimplemented IOCTL: %08x", dwIoControlCode);
|
||||
log_error(plfDrive, "Unimplemented IOCTL: %08x", dwIoControlCode);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@ -481,7 +481,7 @@ void init_volume(disk_volume_t* vol) {
|
||||
StringFromGUID2(&guid, volume_name + 10, MAX_PATH + 1 - 10);
|
||||
|
||||
file_hook_t* volume_hook = new_file_hook(volume_name);
|
||||
log_misc("disk", "Creating fake volume: %ls", volume_name);
|
||||
log_misc(plfDrive, "Creating fake volume: %ls", volume_name);
|
||||
|
||||
volume_hook->DeviceIoControl = &volume_DeviceIoControl;
|
||||
volume_hook->hook_data = (void*)vol;
|
||||
@ -519,7 +519,7 @@ void init_pd(physical_disk_t* pd) {
|
||||
pd->m_BlockSize = BLOCK_SIZE_CDROM;
|
||||
break;
|
||||
default:
|
||||
log_error("disk", "Unable to guess block size for drive %d", pd->m_DriveNumber);
|
||||
log_error(plfDrive, "Unable to guess block size for drive %d", pd->m_DriveNumber);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -544,7 +544,7 @@ void init_pd(physical_disk_t* pd) {
|
||||
pd->m_DriveNumber);
|
||||
break;
|
||||
default:
|
||||
log_error("disk", "Unable to set DeviceName for drive %d (type: %d)",
|
||||
log_error(plfDrive, "Unable to set DeviceName for drive %d (type: %d)",
|
||||
pd->m_DriveNumber, pd->m_DiskType);
|
||||
break;
|
||||
}
|
||||
@ -580,7 +580,7 @@ void init_pd(physical_disk_t* pd) {
|
||||
DWORD extendedPartNo = 0;
|
||||
if (pd->m_Extended[0].m_Size) {
|
||||
if (partitionNumber == 5) {
|
||||
log_error("drive", "Fatal: Too many paritions in drive %d!", pd->m_DriveNumber);
|
||||
log_error(plfDrive, "Fatal: Too many paritions in drive %d!", pd->m_DriveNumber);
|
||||
exit(1);
|
||||
}
|
||||
pd->m_Partitions[partitionNumber - 1].m_Filesystem = MBR_FS_EXT_LBA;
|
||||
@ -660,7 +660,7 @@ void init_all_pd() {
|
||||
|
||||
BOOL q_drive_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
||||
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) {
|
||||
log_game("q", "CDROM read 0x%04x bytes at 0x%08x", nNumberOfBytesToRead,
|
||||
log_game(plfDrive, "Q:CDROM read 0x%04x bytes at 0x%08x", nNumberOfBytesToRead,
|
||||
ctx->m_Pointer.QuadPart);
|
||||
|
||||
/**
|
||||
@ -680,7 +680,7 @@ BOOL q_drive_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytes
|
||||
HANDLE hFile = _CreateFileA("H:\\Arcades\\Images\\ALLNet_Pras_Multi_Ver2\\DVR-0069A.iso", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
log_error("q", "READ FAILED. FILE FALLBACK FAILED. %d", GetLastError());
|
||||
log_error(plfDrive, "Q:READ FAILED. FILE FALLBACK FAILED. %d", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -688,7 +688,7 @@ BOOL q_drive_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytes
|
||||
_ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
|
||||
_CloseHandle(hFile);
|
||||
|
||||
log_warning("q", "READ FAILED. FILE FALLBACK (Read %d bytes).", *lpNumberOfBytesRead);
|
||||
log_warning(plfDrive, "Q:READ FAILED. FILE FALLBACK (Read %d bytes).", *lpNumberOfBytesRead);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -744,11 +744,11 @@ void hook_drives() {
|
||||
hFile =
|
||||
_CreateFileA(SBR0_PATH, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
log_error("drive", "Failed to open %s", SBR0_PATH);
|
||||
log_error(plfDrive, "Failed to open %s", SBR0_PATH);
|
||||
} else {
|
||||
_ReadFile(hFile, &SegaBootRecord0, sizeof SegaBootRecord0, &numberOfBytesRead, NULL);
|
||||
_CloseHandle(hFile);
|
||||
log_info("drive", "Restored SBR0 from %s", SBR0_PATH);
|
||||
log_info(plfDrive, "Restored SBR0 from %s", SBR0_PATH);
|
||||
}
|
||||
} else {
|
||||
// memcpy(&SegaBootRecord0, &SegaBootRecordDefault, sizeof SegaBootRecord0);
|
||||
@ -758,11 +758,11 @@ void hook_drives() {
|
||||
hFile =
|
||||
_CreateFileA(SBR1_PATH, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
log_error("drive", "Failed to open %s", SBR1_PATH);
|
||||
log_error(plfDrive, "Failed to open %s", SBR1_PATH);
|
||||
} else {
|
||||
_ReadFile(hFile, &SegaBootRecord1, sizeof SegaBootRecord1, &numberOfBytesRead, NULL);
|
||||
_CloseHandle(hFile);
|
||||
log_info("drive", "Restored SBR1 from %s", SBR0_PATH);
|
||||
log_info(plfDrive, "Restored SBR1 from %s", SBR0_PATH);
|
||||
}
|
||||
} else {
|
||||
memcpy(&SegaBootRecord1, &SegaBootRecord0, sizeof SegaBootRecord0);
|
||||
|
@ -128,7 +128,7 @@ BOOL WINAPI FakeSetVolumeLabelA(LPCSTR lpRootPathName, LPCSTR lpVolumeName) {
|
||||
}
|
||||
BOOL WINAPI FakeGetVolumeNameForVolumeMountPointA(LPCSTR lpszVolumeMountPoint, LPSTR lpszVolumeName,
|
||||
DWORD cchBufferLength) {
|
||||
log_trace("drive", "GetVolumeNameForVolumeMountPointA(%s)", lpszVolumeMountPoint);
|
||||
log_trace(plfDrive, "GetVolumeNameForVolumeMountPointA(%s)", lpszVolumeMountPoint);
|
||||
|
||||
disk_volume_t* volume = getVolumeByPath(lpszVolumeMountPoint, VOL_MATCH_PATH);
|
||||
if (volume == NULL) {
|
||||
@ -141,7 +141,7 @@ BOOL WINAPI FakeGetVolumeNameForVolumeMountPointA(LPCSTR lpszVolumeMountPoint, L
|
||||
}
|
||||
BOOL WINAPI FakeGetVolumePathNamesForVolumeNameA(LPCSTR lpszVolumeName, LPCH lpszVolumePathNames,
|
||||
DWORD cchBufferLength, PDWORD lpcchReturnLength) {
|
||||
log_trace("drive", "GetVolumeNameForVolumeMountPointA(%s)", lpszVolumeName);
|
||||
log_trace(plfDrive, "GetVolumeNameForVolumeMountPointA(%s)", lpszVolumeName);
|
||||
|
||||
disk_volume_t* volume = getVolumeByPath(lpszVolumeName, VOL_MATCH_GUID);
|
||||
if (volume == NULL) {
|
||||
@ -164,7 +164,7 @@ BOOL WINAPI FakeGetVolumePathNamesForVolumeNameA(LPCSTR lpszVolumeName, LPCH lps
|
||||
return TRUE;
|
||||
}
|
||||
BOOL WINAPI FakeDeleteVolumeMountPointA(LPCSTR lpszVolumeMountPoint) {
|
||||
log_trace("drive", "DeleteVolumeMountPointA(%s)", lpszVolumeMountPoint);
|
||||
log_trace(plfDrive, "DeleteVolumeMountPointA(%s)", lpszVolumeMountPoint);
|
||||
disk_volume_t* volume = getVolumeByPath(lpszVolumeMountPoint, VOL_MATCH_PATH);
|
||||
if (volume == NULL) {
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
@ -175,7 +175,7 @@ BOOL WINAPI FakeDeleteVolumeMountPointA(LPCSTR lpszVolumeMountPoint) {
|
||||
return TRUE;
|
||||
}
|
||||
BOOL WINAPI FakeSetVolumeMountPointA(LPCSTR lpszVolumeMountPoint, LPCSTR lpszVolumeName) {
|
||||
log_trace("drive", "SetVolumeMountPointA(%s)", lpszVolumeMountPoint);
|
||||
log_trace(plfDrive, "SetVolumeMountPointA(%s)", lpszVolumeMountPoint);
|
||||
disk_volume_t* volume = getVolumeByPath(lpszVolumeName, VOL_MATCH_GUID);
|
||||
if (volume == NULL) {
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
@ -186,12 +186,12 @@ BOOL WINAPI FakeSetVolumeMountPointA(LPCSTR lpszVolumeMountPoint, LPCSTR lpszVol
|
||||
DWORD nScan;
|
||||
if (sscanf_s(lpszVolumeMountPoint, "\\\\.\\%c:%n", &cMountPoint, 1, &nScan) == 1 &&
|
||||
nScan == 6) {
|
||||
log_info("drive", "Mounting %s at %c:\\", volume->m_Name, cMountPoint);
|
||||
log_info(plfDrive, "Mounting %s at %c:\\", volume->m_Name, cMountPoint);
|
||||
volume->m_MountPoint = cMountPoint;
|
||||
return TRUE;
|
||||
}
|
||||
if (sscanf_s(lpszVolumeMountPoint, "%c:\\%n", &cMountPoint, 1, &nScan) == 1 && nScan == 3) {
|
||||
log_info("drive", "Mounting %s at %c:\\", volume->m_Name, cMountPoint);
|
||||
log_info(plfDrive, "Mounting %s at %c:\\", volume->m_Name, cMountPoint);
|
||||
volume->m_MountPoint = cMountPoint;
|
||||
return TRUE;
|
||||
}
|
||||
@ -224,7 +224,7 @@ MCIERROR WINAPI Fake_mciSendStringA(LPCTSTR lpszCommand, LPTSTR lpszReturnString
|
||||
return 0;
|
||||
}
|
||||
if (strcmp(lpszCommand, "set cdaudio door open") == 0) {
|
||||
log_game("mci", "Cupholder opened!");
|
||||
log_game(plfDrive, "mci:Cupholder opened!");
|
||||
return 0;
|
||||
}
|
||||
if (strcmp(lpszCommand, "status cdaudio media present") == 0) {
|
||||
|
@ -5,11 +5,11 @@ BOOL WINAPI pd_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOI
|
||||
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
|
||||
physical_disk_t* pd = (physical_disk_t*)ctx->m_HookData;
|
||||
if (pd == NULL) {
|
||||
log_error("drive", "ioctl:ctx->m_HookData NULL; expected a physical drive!");
|
||||
log_error(plfDrive, "ioctl:ctx->m_HookData NULL; expected a physical drive!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
log_trace("drive", "DeviceIOControl %08x", dwIoControlCode);
|
||||
log_trace(plfDrive, "DeviceIOControl %08x", dwIoControlCode);
|
||||
ZeroMemory(lpOutBuffer, nOutBufferSize);
|
||||
switch (dwIoControlCode) {
|
||||
case IOCTL_ATA_PASS_THROUGH:
|
||||
@ -36,7 +36,7 @@ BOOL WINAPI pd_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOI
|
||||
}
|
||||
|
||||
if (command != 0xC1) {
|
||||
log_error("pd0", "Unimplemented ATA command: %02x", command);
|
||||
log_error(plfDrive, "PD0:Unimplemented ATA command: %02x", command);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@ -62,7 +62,7 @@ BOOL WINAPI pd_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOI
|
||||
// as long as the ioctl succeeds! Saves us a lot of work here!
|
||||
return TRUE;
|
||||
}
|
||||
log_error("drive", "Unimeplemented ATA C1 command: %02x", data);
|
||||
log_error(plfDrive, "Unimeplemented ATA C1 command: %02x", data);
|
||||
return FALSE;
|
||||
case IOCTL_DISK_GET_LENGTH_INFO:
|
||||
PGET_LENGTH_INFORMATION pLi = (PGET_LENGTH_INFORMATION)lpOutBuffer;
|
||||
@ -70,7 +70,7 @@ BOOL WINAPI pd_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOI
|
||||
*lpBytesReturned = sizeof *pLi;
|
||||
return TRUE;
|
||||
}
|
||||
log_error("drive", "Unimplemented ioctl: %08x", dwIoControlCode);
|
||||
log_error(plfDrive, "Unimplemented ioctl: %08x", dwIoControlCode);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -78,11 +78,11 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
|
||||
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) {
|
||||
physical_disk_t* pd = (physical_disk_t*)ctx->m_HookData;
|
||||
if (pd == NULL) {
|
||||
log_error("drive", "read:ctx->m_HookData NULL; expected a physical drive!");
|
||||
log_error(plfDrive, "read:ctx->m_HookData NULL; expected a physical drive!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
log_misc("drive", "PhysicalDrive%d: Read %d @ %llx", pd->m_DriveNumber, nNumberOfBytesToRead,
|
||||
log_misc(plfDrive, "PhysicalDrive%d: Read %d @ %llx", pd->m_DriveNumber, nNumberOfBytesToRead,
|
||||
ctx->m_Pointer.QuadPart);
|
||||
|
||||
// ! WARNING: This ReadFile implementation is currently limited to aligned
|
||||
@ -95,7 +95,7 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
|
||||
if (ptrLBA == 0) {
|
||||
mbr_t* mbr = (mbr_t*)lpBuffer;
|
||||
if (nNumberOfBytesToRead < sizeof *mbr) {
|
||||
log_error("drive", "Buffer too small for master boot record!");
|
||||
log_error(plfDrive, "Buffer too small for master boot record!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -119,7 +119,7 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
|
||||
}
|
||||
if (ptrLBA <= MBR_LBA_GAP) {
|
||||
// Read within the 63 extra tracks
|
||||
log_error("drive", "Read failed");
|
||||
log_error(plfDrive, "Read failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -132,19 +132,19 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
|
||||
DWORD readOffset = ptrLBA - pd->m_Partitions[i].m_PhysicalLBA;
|
||||
|
||||
if (pd->m_Partitions[i].m_ReadFunc == NULL) {
|
||||
log_error("disk", "Attempted read in %d/%d at block offset %08x; No read function",
|
||||
log_error(plfDrive, "Attempted read in %d/%d at block offset %08x; No read function",
|
||||
pd->m_DriveNumber, pd->m_Partitions[i].m_PartitionNumber, readOffset);
|
||||
return FALSE;
|
||||
}
|
||||
BOOL ret = pd->m_Partitions[i].m_ReadFunc(readOffset, lpBuffer, nNumberOfBytesToRead,
|
||||
lpNumberOfBytesRead);
|
||||
if (!ret) {
|
||||
log_error("disk", "Attempted read in %d/%d at block offset %08x; Read rejected",
|
||||
log_error(plfDrive, "Attempted read in %d/%d at block offset %08x; Read rejected",
|
||||
pd->m_DriveNumber, pd->m_Partitions[i].m_PartitionNumber, readOffset);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
log_misc("drive", "Read at %d/%d+%d", pd->m_DriveNumber,
|
||||
log_misc(plfDrive, "Read at %d/%d+%d", pd->m_DriveNumber,
|
||||
pd->m_Partitions[i].m_PartitionNumber, readOffset);
|
||||
return TRUE;
|
||||
}
|
||||
@ -157,7 +157,7 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
|
||||
if (ptrLBA == headerLBA) {
|
||||
mbr_t* mbr = (mbr_t*)lpBuffer;
|
||||
if (nNumberOfBytesToRead < sizeof *mbr) {
|
||||
log_error("drive", "Buffer too small for an extended boot record!");
|
||||
log_error(plfDrive, "Buffer too small for an extended boot record!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -188,7 +188,7 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
|
||||
if (ptrLBA == headerLBA + SPD_OFFSET) {
|
||||
spd_t* spd = (spd_t*)lpBuffer;
|
||||
if (nNumberOfBytesToRead < sizeof *spd) {
|
||||
log_error("drive", "Buffer too small for SPD!");
|
||||
log_error(plfDrive, "Buffer too small for SPD!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -207,7 +207,7 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
|
||||
// SEGA Boot Record 0 and 1. The two are a redundant copy of each other
|
||||
if (ptrLBA == headerLBA + SBR0_OFFSET) {
|
||||
if (nNumberOfBytesToRead < sizeof SegaBootRecord0) {
|
||||
log_error("drive", "Buffer too small for SBR0!");
|
||||
log_error(plfDrive, "Buffer too small for SBR0!");
|
||||
return FALSE;
|
||||
}
|
||||
memcpy(lpBuffer, &SegaBootRecord0, sizeof SegaBootRecord0);
|
||||
@ -216,7 +216,7 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
|
||||
}
|
||||
if (ptrLBA == headerLBA + SBR1_OFFSET) {
|
||||
if (nNumberOfBytesToRead < sizeof SegaBootRecord1) {
|
||||
log_error("drive", "Buffer too small for SBR1!");
|
||||
log_error(plfDrive, "Buffer too small for SBR1!");
|
||||
return FALSE;
|
||||
}
|
||||
memcpy(lpBuffer, &SegaBootRecord1, sizeof SegaBootRecord1);
|
||||
@ -228,7 +228,7 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
|
||||
if (ptrLBA >= pd->m_Extended[i].m_PhysicalLBA - EXT_HEADER_GAP &&
|
||||
ptrLBA < pd->m_Extended[i].m_PhysicalLBA) {
|
||||
// Read within the 63 extra tracks
|
||||
log_error("drive", "Read failed");
|
||||
log_error(plfDrive, "Read failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -237,25 +237,25 @@ BOOL pd_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRea
|
||||
DWORD readOffset = ptrLBA - pd->m_Extended[i].m_PhysicalLBA;
|
||||
|
||||
if (pd->m_Extended[i].m_ReadFunc == NULL) {
|
||||
log_error("disk", "Attempted read in %d/%d at block offset %08x; No read function",
|
||||
log_error(plfDrive, "Attempted read in %d/%d at block offset %08x; No read function",
|
||||
pd->m_DriveNumber, pd->m_Extended[i].m_PartitionNumber, readOffset);
|
||||
return FALSE;
|
||||
}
|
||||
BOOL ret = pd->m_Extended[i].m_ReadFunc(readOffset, lpBuffer, nNumberOfBytesToRead,
|
||||
lpNumberOfBytesRead);
|
||||
if (!ret) {
|
||||
log_error("disk", "Attempted read in %d/%d at block offset %08x; Read rejected",
|
||||
log_error(plfDrive, "Attempted read in %d/%d at block offset %08x; Read rejected",
|
||||
pd->m_DriveNumber, pd->m_Extended[i].m_PartitionNumber, readOffset);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
log_misc("drive", "Read at %d/%d+%d", pd->m_DriveNumber,
|
||||
log_misc(plfDrive, "Read at %d/%d+%d", pd->m_DriveNumber,
|
||||
pd->m_Extended[i].m_PartitionNumber, readOffset);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
log_error("drive", "Read failed");
|
||||
log_error(plfDrive, "Read failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -265,11 +265,11 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
|
||||
|
||||
physical_disk_t* pd = (physical_disk_t*)ctx->m_HookData;
|
||||
if (pd == NULL) {
|
||||
log_error("drive", "write:ctx->m_HookData NULL; expected a physical drive!");
|
||||
log_error(plfDrive, "write:ctx->m_HookData NULL; expected a physical drive!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
log_misc("drive", "PhysicalDrive%d: Write %d @ %llx", pd->m_DriveNumber, nNumberOfBytesToWrite,
|
||||
log_misc(plfDrive, "PhysicalDrive%d: Write %d @ %llx", pd->m_DriveNumber, nNumberOfBytesToWrite,
|
||||
ctx->m_Pointer.QuadPart);
|
||||
|
||||
// for (DWORD i = 0; i < nNumberOfBytesToWrite; i += 32) {
|
||||
@ -290,7 +290,7 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
|
||||
|
||||
// Writes to the MBR header or slack are blocked
|
||||
if (ptrLBA <= MBR_LBA_GAP) {
|
||||
log_error("drive", "Write rejected");
|
||||
log_error(plfDrive, "Write rejected");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -303,7 +303,7 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
|
||||
DWORD writeOffset = ptrLBA - pd->m_Partitions[i].m_PhysicalLBA;
|
||||
|
||||
if (pd->m_Partitions[i].m_WriteFunc == NULL) {
|
||||
log_error("disk",
|
||||
log_error(plfDrive,
|
||||
"Attempted write in %d/%d at block offset %08x; No write function",
|
||||
pd->m_DriveNumber, pd->m_Partitions[i].m_PartitionNumber, writeOffset);
|
||||
return FALSE;
|
||||
@ -311,12 +311,12 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
|
||||
BOOL ret = pd->m_Partitions[i].m_WriteFunc(writeOffset, lpBuffer, nNumberOfBytesToWrite,
|
||||
lpNumberOfBytesWritten);
|
||||
if (!ret) {
|
||||
log_error("disk", "Attempted write in %d/%d at block offset %08x; Write rejected",
|
||||
log_error(plfDrive, "Attempted write in %d/%d at block offset %08x; Write rejected",
|
||||
pd->m_DriveNumber, pd->m_Partitions[i].m_PartitionNumber, writeOffset);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
log_misc("drive", "Write at %d/%d+%d", pd->m_DriveNumber,
|
||||
log_misc(plfDrive, "Write at %d/%d+%d", pd->m_DriveNumber,
|
||||
pd->m_Partitions[i].m_PartitionNumber, writeOffset);
|
||||
return TRUE;
|
||||
}
|
||||
@ -327,7 +327,7 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
|
||||
// Extended header
|
||||
DWORD headerLBA = pd->m_Extended[i].m_PhysicalLBA - EXT_HEADER_GAP;
|
||||
if (ptrLBA == headerLBA) {
|
||||
log_error("drive", "Write to extended header rejected");
|
||||
log_error(plfDrive, "Write to extended header rejected");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -335,13 +335,13 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
|
||||
// SEGA Partition Description
|
||||
if (ptrLBA == headerLBA + SPD_OFFSET) {
|
||||
if (nNumberOfBytesToWrite < sizeof(spd_t)) {
|
||||
log_error("drive", "Buffer too small for SPD!");
|
||||
log_error(plfDrive, "Buffer too small for SPD!");
|
||||
return FALSE;
|
||||
}
|
||||
HANDLE hFile = _CreateFileA(SPD_PATH, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
|
||||
OPEN_ALWAYS, 0, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
log_error("drive", "Failed to open %s", SPD_PATH);
|
||||
log_error(plfDrive, "Failed to open %s", SPD_PATH);
|
||||
return FALSE;
|
||||
}
|
||||
BOOL ret = _WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite,
|
||||
@ -352,13 +352,13 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
|
||||
// SEGA Boot Records
|
||||
if (ptrLBA == headerLBA + SBR0_OFFSET) {
|
||||
if (nNumberOfBytesToWrite < sizeof(sbr_t)) {
|
||||
log_error("drive", "Buffer too small for SBR!");
|
||||
log_error(plfDrive, "Buffer too small for SBR!");
|
||||
return FALSE;
|
||||
}
|
||||
HANDLE hFile = _CreateFileA(SBR0_PATH, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
|
||||
OPEN_ALWAYS, 0, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
log_error("drive", "Failed to open %s", SBR0_PATH);
|
||||
log_error(plfDrive, "Failed to open %s", SBR0_PATH);
|
||||
return FALSE;
|
||||
}
|
||||
BOOL ret = _WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite,
|
||||
@ -368,13 +368,13 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
|
||||
}
|
||||
if (ptrLBA == headerLBA + SBR1_OFFSET) {
|
||||
if (nNumberOfBytesToWrite < sizeof(sbr_t)) {
|
||||
log_error("drive", "Buffer too small for SBR!");
|
||||
log_error(plfDrive, "Buffer too small for SBR!");
|
||||
return FALSE;
|
||||
}
|
||||
HANDLE hFile = _CreateFileA(SBR1_PATH, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
|
||||
OPEN_ALWAYS, 0, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
log_error("drive", "Failed to open %s", SBR1_PATH);
|
||||
log_error(plfDrive, "Failed to open %s", SBR1_PATH);
|
||||
return FALSE;
|
||||
}
|
||||
BOOL ret = _WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite,
|
||||
@ -387,7 +387,7 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
|
||||
if (ptrLBA >= pd->m_Extended[i].m_PhysicalLBA - EXT_HEADER_GAP &&
|
||||
ptrLBA < pd->m_Extended[i].m_PhysicalLBA) {
|
||||
// Write within the 63 extra tracks
|
||||
log_error("drive", "Write failed");
|
||||
log_error(plfDrive, "Write failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -396,7 +396,7 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
|
||||
DWORD writeOffset = ptrLBA - pd->m_Extended[i].m_PhysicalLBA;
|
||||
|
||||
if (pd->m_Extended[i].m_WriteFunc == NULL) {
|
||||
log_error("disk",
|
||||
log_error(plfDrive,
|
||||
"Attempted write in %d/%d at block offset %08x; No write function",
|
||||
pd->m_DriveNumber, pd->m_Extended[i].m_PartitionNumber, writeOffset);
|
||||
return FALSE;
|
||||
@ -404,14 +404,16 @@ BOOL pd_WriteFile(file_context_t* ctx, LPCVOID lpBuffer, DWORD nNumberOfBytesToW
|
||||
BOOL ret = pd->m_Extended[i].m_WriteFunc(writeOffset, lpBuffer, nNumberOfBytesToWrite,
|
||||
lpNumberOfBytesWritten);
|
||||
if (!ret) {
|
||||
log_error("disk", "Attempted write in %d/%d at block offset %08x; Write rejected",
|
||||
log_error(plfDrive, "Attempted write in %d/%d at block offset %08x; Write rejected",
|
||||
pd->m_DriveNumber, pd->m_Extended[i].m_PartitionNumber, writeOffset);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
log_misc("drive", "Write at %d/%d+%d", pd->m_DriveNumber,
|
||||
log_misc(plfDrive, "Write at %d/%d+%d", pd->m_DriveNumber,
|
||||
pd->m_Extended[i].m_PartitionNumber, writeOffset);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ BOOL redirect_path(LPCSTR path, LPCSTR* redirected) {
|
||||
for (int i = 0; i < sizeof DRIVE_REDIRECT_TABLE / sizeof DRIVE_REDIRECT_TABLE[0]; i++) {
|
||||
drive_redirect_t row = DRIVE_REDIRECT_TABLE[i];
|
||||
if (PathPrefix(path, row.drive)) {
|
||||
log_trace(HOOKS_LOGGER, "Redirecting '%s' to '%s'", path, row.path);
|
||||
log_trace(plfHooks, "Redirecting '%s' to '%s'", path, row.path);
|
||||
|
||||
size_t new_len = strlen(path) - strlen(row.drive) + strlen(row.path);
|
||||
strcpy_s(_redirected_path, new_len + 1, row.path);
|
||||
@ -144,7 +144,7 @@ BOOL redirect_path(LPCSTR path, LPCSTR* redirected) {
|
||||
|
||||
for (; len > 0; len--) (dst++)[0] = (src++)[0];
|
||||
dst[0] = 0;
|
||||
log_trace(HOOKS_LOGGER, "New filename: '%s'", _redirected_path);
|
||||
log_trace(plfHooks, "New filename: '%s'", _redirected_path);
|
||||
|
||||
make_dirs(_redirected_path);
|
||||
*redirected = _redirected_path;
|
||||
@ -184,7 +184,7 @@ HANDLE WINAPI FakeCreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD d
|
||||
file_hook_t* found_fh = find_hook(lpFileName);
|
||||
if (found_fh != NULL) {
|
||||
HANDLE handle = open_hook(found_fh);
|
||||
log_info(HOOKS_LOGGER, "CreateFileW(%ls) -> 0x%p", lpFileName, handle);
|
||||
log_info(plfHooks, "CreateFileW(%ls) -> 0x%p", lpFileName, handle);
|
||||
return handle;
|
||||
}
|
||||
|
||||
@ -194,11 +194,11 @@ HANDLE WINAPI FakeCreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD d
|
||||
if (redirect_path_w(lpFileName, &redirected)) {
|
||||
handle = TrueCreateFileA(redirected, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
|
||||
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
|
||||
log_misc(HOOKS_LOGGER, "CreateFileW(%s) -> 0x%p", redirected, handle);
|
||||
log_misc(plfHooks, "CreateFileW(%s) -> 0x%p", redirected, handle);
|
||||
} else {
|
||||
handle = TrueCreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
|
||||
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
|
||||
log_misc(HOOKS_LOGGER, "CreateFileW(%ls) -> 0x%p", lpFileName, handle);
|
||||
log_misc(plfHooks, "CreateFileW(%ls) -> 0x%p", lpFileName, handle);
|
||||
}
|
||||
|
||||
return handle;
|
||||
@ -213,25 +213,25 @@ HANDLE WINAPI FakeCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dw
|
||||
file_hook_t* found_fh = find_hook(wideFileName);
|
||||
if (found_fh != NULL) {
|
||||
HANDLE handle = open_hook(found_fh);
|
||||
log_info(HOOKS_LOGGER, "CreateFileA(%s) -> 0x%p", lpFileName, handle);
|
||||
log_info(plfHooks, "CreateFileA(%s) -> 0x%p", lpFileName, handle);
|
||||
return handle;
|
||||
}
|
||||
|
||||
redirect_path(lpFileName, &lpFileName);
|
||||
HANDLE handle = TrueCreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
|
||||
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
|
||||
log_misc(HOOKS_LOGGER, "CreateFileA(%s) -> 0x%p", lpFileName, handle);
|
||||
log_misc(plfHooks, "CreateFileA(%s) -> 0x%p", lpFileName, handle);
|
||||
return handle;
|
||||
}
|
||||
|
||||
BOOL WINAPI FakePathFileExistsA(LPCSTR pszPath) {
|
||||
log_misc(HOOKS_LOGGER, "PathFileExists(%s)", pszPath);
|
||||
log_misc(plfHooks, "PathFileExists(%s)", pszPath);
|
||||
redirect_path(pszPath, &pszPath);
|
||||
BOOL ret = TruePathFileExistsA(pszPath);
|
||||
return ret;
|
||||
}
|
||||
BOOL WINAPI FakePathFileExistsW(LPCWSTR pszPath) {
|
||||
log_misc(HOOKS_LOGGER, "PathFileExists(%ls)", pszPath);
|
||||
log_misc(plfHooks, "PathFileExists(%ls)", pszPath);
|
||||
LPCSTR redirected;
|
||||
if (redirect_path_w(pszPath, &redirected)) {
|
||||
return TruePathFileExistsA(redirected);
|
||||
@ -259,7 +259,7 @@ BOOL WINAPI FakeDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lp
|
||||
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
|
||||
open_hook_t* pHData = GetDataForHandle(hDevice, HDATA_FILE);
|
||||
if (pHData == NULL) {
|
||||
// log_trace(HOOKS_LOGGER, "DeviceIoControl(0x%p, 0x%08x, 0x%p, 0x%x, -, 0x%x, 0, 0)", hDevice,
|
||||
// log_trace(plfHooks, "DeviceIoControl(0x%p, 0x%08x, 0x%p, 0x%x, -, 0x%x, 0, 0)", hDevice,
|
||||
// dwIoControlCode, lpInBuffer, nInBufferSize, nOutBufferSize);
|
||||
|
||||
return TrueDeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer,
|
||||
@ -268,7 +268,7 @@ BOOL WINAPI FakeDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lp
|
||||
|
||||
file_hook_t* file_hook = pHData->hook;
|
||||
if (!file_hook->DeviceIoControl) {
|
||||
log_error(HOOKS_LOGGER, "DeviceIoControl(%ls) unimplemented", file_hook->filename);
|
||||
log_error(plfHooks, "DeviceIoControl(%ls) unimplemented", file_hook->filename);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -297,7 +297,7 @@ DWORD WINAPI FakeSetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDist
|
||||
pHData->ctx.m_Pointer.HighPart = 0;
|
||||
pHData->ctx.m_Pointer.LowPart = lDistanceToMove;
|
||||
} else if (dwMoveMethod == FILE_END) {
|
||||
log_error("files", "FILE_END unimplemented");
|
||||
log_error(plfFile, "FILE_END unimplemented");
|
||||
return 0xFFFFFFFF;
|
||||
} else {
|
||||
if (lpDistanceToMoveHigh) pHData->ctx.m_Pointer.HighPart += *lpDistanceToMoveHigh;
|
||||
@ -314,7 +314,7 @@ BOOL WINAPI FakeSetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove,
|
||||
if (dwMoveMethod == FILE_BEGIN) {
|
||||
pHData->ctx.m_Pointer = liDistanceToMove;
|
||||
} else if (dwMoveMethod == FILE_END) {
|
||||
log_error("files", "FILE_END unimplemented");
|
||||
log_error(plfFile, "FILE_END unimplemented");
|
||||
return FALSE;
|
||||
} else {
|
||||
pHData->ctx.m_Pointer.QuadPart += liDistanceToMove.QuadPart;
|
||||
@ -334,7 +334,7 @@ DWORD WINAPI FakeGetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize) {
|
||||
}
|
||||
file_hook_t* file_hook = pHData->hook;
|
||||
if (!file_hook->GetFileSizeEx) {
|
||||
log_error(HOOKS_LOGGER, "GetFileSizeEx(%ls) unimplemented", file_hook->filename);
|
||||
log_error(plfHooks, "GetFileSizeEx(%ls) unimplemented", file_hook->filename);
|
||||
return FALSE;
|
||||
}
|
||||
return file_hook->GetFileSizeEx(&(pHData->ctx), lpFileSize);
|
||||
@ -355,7 +355,7 @@ DWORD WINAPI FakeWriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesT
|
||||
|
||||
file_hook_t* file_hook = pHData->hook;
|
||||
if (!file_hook->WriteFile) {
|
||||
log_error(HOOKS_LOGGER, "WriteFile(%ls) unimplemented", file_hook->filename);
|
||||
log_error(plfHooks, "WriteFile(%ls) unimplemented", file_hook->filename);
|
||||
return FALSE;
|
||||
}
|
||||
BOOL ret = file_hook->WriteFile(&(pHData->ctx), lpBuffer, nNumberOfBytesToWrite,
|
||||
@ -370,7 +370,7 @@ BOOL WINAPI FakeReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRe
|
||||
return TrueReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead,
|
||||
lpOverlapped);
|
||||
}
|
||||
// log_misc(HOOKS_LOGGER, "ReadFile(%d) %d", hFile, nNumberOfBytesToRead);
|
||||
// log_misc(plfHooks, "ReadFile(%d) %d", hFile, nNumberOfBytesToRead);
|
||||
|
||||
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
|
||||
if (pHData == NULL) {
|
||||
@ -381,7 +381,7 @@ BOOL WINAPI FakeReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRe
|
||||
file_hook_t* file_hook = pHData->hook;
|
||||
|
||||
if (!file_hook->ReadFile) {
|
||||
log_error(HOOKS_LOGGER, "ReadFile(%ls) unimplemented", file_hook->filename);
|
||||
log_error(plfHooks, "ReadFile(%ls) unimplemented", file_hook->filename);
|
||||
return FALSE;
|
||||
}
|
||||
BOOL ret = file_hook->ReadFile(&(pHData->ctx), lpBuffer, nNumberOfBytesToRead,
|
||||
|
@ -148,7 +148,7 @@ void post_win_create(HWND hWnd) {
|
||||
}
|
||||
|
||||
if (hWnd && !SetWindowSubclass(hWnd, WndProc, (int)&WndProc, (DWORD_PTR)NULL)) {
|
||||
log_error("gui", "failed to SetWindowSubclass(%d)", GetLastError());
|
||||
log_error(plfGUI, "failed to SetWindowSubclass(%d)", GetLastError());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -282,19 +282,19 @@ HRESULT STDMETHODCALLTYPE FakeCreateDevice(IDirect3D9* this, UINT Adapter, D3DDE
|
||||
if (res != S_OK) {
|
||||
switch (res) {
|
||||
case D3DERR_DEVICELOST:
|
||||
log_error("D3D9", "CreateDevice failed: Device lost");
|
||||
log_error(plfD3D9, "CreateDevice failed: Device lost");
|
||||
break;
|
||||
case D3DERR_INVALIDCALL:
|
||||
log_error("D3D9", "CreateDevice failed: Invalid call");
|
||||
log_error(plfD3D9, "CreateDevice failed: Invalid call");
|
||||
break;
|
||||
case D3DERR_NOTAVAILABLE:
|
||||
log_error("D3D9", "CreateDevice failed: Requested configuration not available");
|
||||
log_error(plfD3D9, "CreateDevice failed: Requested configuration not available");
|
||||
break;
|
||||
case D3DERR_OUTOFVIDEOMEMORY:
|
||||
log_error("D3D9", "CreateDevice failed: VMem exhausted");
|
||||
log_error(plfD3D9, "CreateDevice failed: VMem exhausted");
|
||||
break;
|
||||
default:
|
||||
log_error("D3D9", "CreateDevice failed: %08x", res);
|
||||
log_error(plfD3D9, "CreateDevice failed: %08x", res);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ int WINAPIV Fakeprintf(const char* _Format, ...) {
|
||||
va_list args;
|
||||
va_start(args, _Format);
|
||||
|
||||
int ret = vlog_game("printf", _Format, args);
|
||||
int ret = vlog_game(plfPrintf, _Format, args);
|
||||
|
||||
va_end(args);
|
||||
return ret;
|
||||
@ -45,7 +45,7 @@ int WINAPIV Fakefprintf(FILE* _File, const char* _Format, ...) {
|
||||
va_list args;
|
||||
va_start(args, _Format);
|
||||
|
||||
int ret = vlog_game("fprintf", _Format, args);
|
||||
int ret = vlog_game(plfFprintf, _Format, args);
|
||||
|
||||
va_end(args);
|
||||
return ret;
|
||||
@ -55,13 +55,13 @@ int WINAPIV Fakefprintf_s(FILE* _Stream, const char* _Format, ...) {
|
||||
va_list args;
|
||||
va_start(args, _Format);
|
||||
|
||||
int ret = vlog_game("fprintf_s", _Format, args);
|
||||
int ret = vlog_game(plfFprintf_s, _Format, args);
|
||||
|
||||
va_end(args);
|
||||
return ret;
|
||||
}
|
||||
int WINAPIV Fakevfprintf_s(FILE* _Stream, const char* _Format, va_list _ArgList) {
|
||||
return vlog_game("vfprintf_s", _Format, _ArgList);
|
||||
return vlog_game(plfVfprintf_s, _Format, _ArgList);
|
||||
}
|
||||
HANDLE WINAPI FakeRegisterEventSourceA(LPCSTR lpUNCServerName, LPCSTR lpSourceName) {
|
||||
return (HANDLE)0xDEADBEEF;
|
||||
@ -74,21 +74,21 @@ BOOL WINAPI FakeReportEventA(HANDLE hEventLog, WORD wType, WORD wCategory, DWORD
|
||||
case EVENTLOG_SUCCESS:
|
||||
case EVENTLOG_AUDIT_SUCCESS:
|
||||
for (int i = 0; i < wNumStrings; i++)
|
||||
log_misc("evtlog", trim_string((char*)lpStrings[i]));
|
||||
log_misc(plfEvtlog, trim_string((char*)lpStrings[i]));
|
||||
break;
|
||||
case EVENTLOG_AUDIT_FAILURE:
|
||||
case EVENTLOG_ERROR_TYPE:
|
||||
for (int i = 0; i < wNumStrings; i++)
|
||||
log_error("evtlog", trim_string((char*)lpStrings[i]));
|
||||
log_error(plfEvtlog, trim_string((char*)lpStrings[i]));
|
||||
break;
|
||||
case EVENTLOG_WARNING_TYPE:
|
||||
for (int i = 0; i < wNumStrings; i++)
|
||||
log_warning("evtlog", trim_string((char*)lpStrings[i]));
|
||||
log_warning(plfEvtlog, trim_string((char*)lpStrings[i]));
|
||||
break;
|
||||
case EVENTLOG_INFORMATION_TYPE:
|
||||
default:
|
||||
for (int i = 0; i < wNumStrings; i++)
|
||||
log_info("evtlog", trim_string((char*)lpStrings[i]));
|
||||
log_info(plfEvtlog, trim_string((char*)lpStrings[i]));
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
|
@ -5,8 +5,8 @@ int WINAPI Fake_connect(SOCKET s, const SOCKADDR* name, int namelen) {
|
||||
USHORT port = _byteswap_ushort(((SOCKADDR_IN*)name)->sin_port);
|
||||
// Poorly exclude nxauth. TODO: better
|
||||
if (port != 40190) {
|
||||
log_info("connect", "%hhu.%hhu.%hhu.%hhu:%hu", (addr >> 24) & 0xff, (addr >> 16) & 0xff,
|
||||
(addr >> 8) & 0xff, addr & 0xff, port);
|
||||
log_info(plfNetwork, "connect(%hhu.%hhu.%hhu.%hhu:%hu)", (addr >> 24) & 0xff,
|
||||
(addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff, port);
|
||||
}
|
||||
return True_connect(s, name, namelen);
|
||||
}
|
||||
@ -14,7 +14,7 @@ int WINAPI Fake_connect(SOCKET s, const SOCKADDR* name, int namelen) {
|
||||
int WINAPI Fake_bind(SOCKET s, const SOCKADDR* name, int namelen) {
|
||||
ULONG addr = _byteswap_ulong(((SOCKADDR_IN*)name)->sin_addr.S_un.S_addr);
|
||||
USHORT port = _byteswap_ushort(((SOCKADDR_IN*)name)->sin_port);
|
||||
log_info("bind", "%hhu.%hhu.%hhu.%hhu:%hu", (addr >> 24) & 0xff, (addr >> 16) & 0xff,
|
||||
log_info(plfNetwork, "bind(%hhu.%hhu.%hhu.%hhu:%hu)", (addr >> 24) & 0xff, (addr >> 16) & 0xff,
|
||||
(addr >> 8) & 0xff, addr & 0xff, port);
|
||||
return True_bind(s, name, namelen);
|
||||
}
|
||||
@ -25,7 +25,7 @@ int WINAPI Fake_bind(SOCKET s, const SOCKADDR* name, int namelen) {
|
||||
#define MAC_PREFIX_1 0xBB
|
||||
#define MAC_PREFIX_2 0xC1
|
||||
DWORD WINAPI FakeGetIfTable(PMIB_IFTABLE pIfTable, PULONG pdwSize, BOOL bOrder) {
|
||||
log_info("network", "Injecting fake IfTable");
|
||||
log_info(plfNetwork, "Injecting fake IfTable");
|
||||
|
||||
MIB_IFROW* row;
|
||||
uint32_t nbytes;
|
||||
@ -100,7 +100,8 @@ DNS_STATUS WINAPI FakeDnsQuery_A(PCSTR pszName, WORD wType, DWORD Options, PVOID
|
||||
if (strcmp(pszName, INTERCEPT_DNS[i].name) == 0) {
|
||||
printf("%08x\n", MiceConfig.network.naominet_jp);
|
||||
|
||||
log_info("dns", "Replacing %s with %08x", pszName, *INTERCEPT_DNS[i].address);
|
||||
log_info(plfNetwork, "DNS Replacing %s with %08x", pszName,
|
||||
*INTERCEPT_DNS[i].address);
|
||||
|
||||
// We only support replacing at most one address, but that's all we'll ever need to!
|
||||
(*ppQueryResults) = &dummy_record;
|
||||
@ -112,17 +113,17 @@ DNS_STATUS WINAPI FakeDnsQuery_A(PCSTR pszName, WORD wType, DWORD Options, PVOID
|
||||
}
|
||||
}
|
||||
}
|
||||
log_warning("dns", "DNS passthrough for %s", pszName);
|
||||
log_warning(plfNetwork, "DNS passthrough for %s", pszName);
|
||||
return TrueDnsQuery_A(pszName, wType, Options, pExtra, ppQueryResults, pReserved);
|
||||
};
|
||||
|
||||
INT WSAAPI FakeWSAStringToAddressA(LPSTR AddressString, INT AddressFamily,
|
||||
LPWSAPROTOCOL_INFOA lpProtocolInfo, LPSOCKADDR lpAddress,
|
||||
LPINT lpAddressLength) {
|
||||
log_misc("dns", "(WSA)DNS lookup for %s", AddressString);
|
||||
log_misc(plfNetwork, "WSA DNS lookup for %s", AddressString);
|
||||
for (size_t i = 0; i < sizeof INTERCEPT_DNS / sizeof INTERCEPT_DNS[0]; i++) {
|
||||
if (strcmp(AddressString, INTERCEPT_DNS[i].name) == 0) {
|
||||
log_info("dns", "(WSA)Replacing %s with %08x", AddressString,
|
||||
log_info(plfNetwork, "WSA DNS Replacing %s with %08x", AddressString,
|
||||
*INTERCEPT_DNS[i].address);
|
||||
|
||||
lpAddress->sa_family = AF_INET;
|
||||
@ -133,14 +134,64 @@ INT WSAAPI FakeWSAStringToAddressA(LPSTR AddressString, INT AddressFamily,
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
log_warning("dns", "(WSA)DNS passthrough for %s", AddressString);
|
||||
log_warning(plfNetwork, "WSA DNS passthrough for %s", AddressString);
|
||||
return TrueWSAStringToAddressA(AddressString, AddressFamily, lpProtocolInfo, lpAddress,
|
||||
lpAddressLength);
|
||||
}
|
||||
|
||||
int __stdcall Fake_socket(int domain, int type, int protocol) {
|
||||
int sock = True_socket(domain, type, protocol);
|
||||
log_trace(plfNetwork, "Creating new socket: %d/%s/%d -> %d", domain,
|
||||
type == 1 ? "SOCK_STREAM"
|
||||
: type == 2 ? "SOCK_DGRAM"
|
||||
: type == 3 ? "SOCK_RAW"
|
||||
: type == 4 ? "SOCK_RDM"
|
||||
: type == 5 ? "SOCK_SEQPACKET"
|
||||
: "Unknown",
|
||||
protocol, sock);
|
||||
return sock;
|
||||
}
|
||||
|
||||
static struct sockaddr pingSentTo;
|
||||
static unsigned char pingInfo[4];
|
||||
|
||||
static struct sockaddr_in toLocalhost = {
|
||||
.sin_addr = 0x0100007f,
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = 24,
|
||||
.sin_zero = 0,
|
||||
};
|
||||
|
||||
int __stdcall Fake_sendto(SOCKET s, const char* buf, int len, int flags, const struct sockaddr* to,
|
||||
int tolen) {
|
||||
// Hardcoded ICMP4 ping "detection"
|
||||
// TODO: Only do this if the socket is using the ICMP protocol
|
||||
if (len == 8 && buf[0] == 0x08 && buf[1] == 0x00) {
|
||||
uint32_t addr = ((struct sockaddr_in*)to)->sin_addr.S_un.S_addr;
|
||||
|
||||
memcpy(&pingSentTo, to, sizeof pingSentTo);
|
||||
|
||||
uint16_t seq = _byteswap_ushort(((uint16_t*)buf)[3]);
|
||||
|
||||
memcpy(pingInfo, buf + 4, 4);
|
||||
|
||||
memcpy(&toLocalhost, to, sizeof toLocalhost);
|
||||
toLocalhost.sin_addr.S_un.S_addr = 0x0100007f; // 127.0.0.1
|
||||
to = &toLocalhost;
|
||||
|
||||
log_warning(plfNetwork, "(probable) Ping to: %d.%d.%d.%d (%d). Redirecting to localhost",
|
||||
addr & 0xff, (addr >> 8) & 0xff, (addr >> 16) & 0xff, addr >> 24,
|
||||
((struct sockaddr_in*)to)->sin_port, seq);
|
||||
}
|
||||
|
||||
return True_sendto(s, buf, len, flags, to, tolen);
|
||||
}
|
||||
|
||||
void hook_network() {
|
||||
hook("Ws2_32.dll", "connect", Fake_connect, (void**)&True_connect);
|
||||
hook("Ws2_32.dll", "socket", Fake_socket, (void**)&True_socket);
|
||||
hook("Ws2_32.dll", "bind", Fake_bind, (void**)&True_bind);
|
||||
hook("Ws2_32.dll", "sendto", Fake_sendto, (void**)&True_sendto);
|
||||
hook("Ws2_32.dll", "WSAStringToAddressA", FakeWSAStringToAddressA,
|
||||
(void**)&TrueWSAStringToAddressA);
|
||||
hook("Iphlpapi.dll", "GetIfTable", FakeGetIfTable, (void**)&TrueGetIfTable);
|
||||
|
@ -1,15 +1,19 @@
|
||||
#pragma once
|
||||
#include "../common.h"
|
||||
|
||||
static int(WINAPI* True_socket)(int domain, int type, int protocol);
|
||||
static int(WINAPI* True_connect)(SOCKET s, const SOCKADDR* name, int namelen);
|
||||
static int(WINAPI* True_bind)(SOCKET s, const SOCKADDR* addr, int namelen);
|
||||
static int(WINAPI* True_sendto)(SOCKET s, const char* buf, int len, int flags,
|
||||
const struct sockaddr* to, int tolen);
|
||||
|
||||
static DWORD(WINAPI* TrueGetIfTable)(PMIB_IFTABLE pIfTable, PULONG pdwSize, BOOL bOrder);
|
||||
|
||||
static DNS_STATUS(WINAPI* TrueDnsQuery_A)(PCSTR pszName, WORD wType, DWORD Options, PVOID pExtra,
|
||||
PDNS_RECORDA* ppQueryResults, PVOID* pReserved);
|
||||
|
||||
static INT(WSAAPI* TrueWSAStringToAddressA)(LPSTR AddressString, INT AddressFamily, LPWSAPROTOCOL_INFOA lpProtocolInfo,
|
||||
static INT(WSAAPI* TrueWSAStringToAddressA)(LPSTR AddressString, INT AddressFamily,
|
||||
LPWSAPROTOCOL_INFOA lpProtocolInfo,
|
||||
LPSOCKADDR lpAddress, LPINT lpAddressLength);
|
||||
|
||||
void hook_network();
|
||||
|
@ -14,7 +14,7 @@ BOOL WINAPI FakeCreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine,
|
||||
DWORD dwCreationFlags, LPVOID lpEnvironment,
|
||||
LPCSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo,
|
||||
LPPROCESS_INFORMATION lpProcessInformation) {
|
||||
log_info("spawn", "CreateProcessA %s %s", lpApplicationName, lpCommandLine);
|
||||
log_info(plfProcesses, "CreateProcessA %s %s", lpApplicationName, lpCommandLine);
|
||||
|
||||
return TrueCreateProcessA("mxAuthDisc.bat", "", lpProcessAttributes,
|
||||
lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
|
||||
@ -35,12 +35,12 @@ BOOL WINAPI FakeCreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine,
|
||||
LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo,
|
||||
LPPROCESS_INFORMATION lpProcessInformation) {
|
||||
// #ifdef DISABLE_PROC_SPAWNING
|
||||
// log_error("spawn", "CreateProcessW %ls %ls", lpApplicationName, lpCommandLine);
|
||||
// log_error(plfProcesses, "CreateProcessW %ls %ls", lpApplicationName, lpCommandLine);
|
||||
// return FALSE;
|
||||
// #else
|
||||
log_info("spawn", "CreateProcessW %ls %ls", lpApplicationName, lpCommandLine);
|
||||
log_info(plfProcesses, "CreateProcessW %ls %ls", lpApplicationName, lpCommandLine);
|
||||
|
||||
// log_info("spawn", "CreateProcessW %ls", lpApplicationName);
|
||||
// log_info(plfProcesses, "CreateProcessW %ls", lpApplicationName);
|
||||
|
||||
// lpProcessInformation->hThread = GetDummyHandle();
|
||||
// return TRUE;
|
||||
@ -66,7 +66,7 @@ BOOL WINAPI FakeCreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine,
|
||||
return TRUE;
|
||||
|
||||
if (lpCommandLine != NULL) {
|
||||
log_error("process", "!!");
|
||||
log_error(plfProcesses, "!!");
|
||||
return FALSE;
|
||||
// WideCharToMultiByte(CP_ACP, 0, lpCommandLine, -1, commandLine, sizeof commandLine, NULL,
|
||||
// NULL);
|
||||
|
@ -1,28 +1,28 @@
|
||||
#include "registry.h"
|
||||
|
||||
LSTATUS WINAPI FakeRegCloseKey(HKEY hKey) {
|
||||
log_trace("registry", "RegCloseKey %08x", hKey);
|
||||
log_trace(plfRegistry, "RegCloseKey %08x", hKey);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
LSTATUS WINAPI FakeRegCreateKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass,
|
||||
DWORD dwOptions, REGSAM samDesired,
|
||||
const LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||
PHKEY phkResult, LPDWORD lpdwDisposition) {
|
||||
log_trace("registry", "RegCreateKeyExA %08x %s", hKey, lpSubKey);
|
||||
log_trace(plfRegistry, "RegCreateKeyExA %08x %s", hKey, lpSubKey);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
LSTATUS WINAPI FakeRegDeleteKeyA(HKEY hKey, LPCSTR lpSubKey) {
|
||||
log_trace("registry", "RegDeleteKeyA %08x %s", hKey, lpSubKey);
|
||||
log_trace(plfRegistry, "RegDeleteKeyA %08x %s", hKey, lpSubKey);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
LSTATUS WINAPI FakeRegDeleteKeyValueA(HKEY hKey, LPCSTR lpSubKey, LPCSTR lpValueName) {
|
||||
log_trace("registry", "RegDeleteKeyValueA %08x %s %s", hKey, lpSubKey, lpValueName);
|
||||
log_trace(plfRegistry, "RegDeleteKeyValueA %08x %s %s", hKey, lpSubKey, lpValueName);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
LSTATUS WINAPI FakeRegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcchName,
|
||||
LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcchClass,
|
||||
PFILETIME lpftLastWriteTime) {
|
||||
log_trace("registry", "RegEnumKeyExA %08x[%d]", hKey, dwIndex);
|
||||
log_trace(plfRegistry, "RegEnumKeyExA %08x[%d]", hKey, dwIndex);
|
||||
if (dwIndex == 0) {
|
||||
strcpy(lpName, "Direct3D HAL");
|
||||
return ERROR_SUCCESS;
|
||||
@ -32,7 +32,7 @@ LSTATUS WINAPI FakeRegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD
|
||||
LSTATUS WINAPI FakeRegEnumValueA(HKEY hKey, DWORD dwIndex, LPSTR lpValueName,
|
||||
LPDWORD lpcchValueName, LPDWORD lpReserved, LPDWORD lpType,
|
||||
LPBYTE lpData, LPDWORD lpcbData) {
|
||||
log_trace("registry", "RegEnumValueA %08x %s", hKey, lpValueName);
|
||||
log_trace(plfRegistry, "RegEnumValueA %08x %s", hKey, lpValueName);
|
||||
return ERROR_NO_MORE_ITEMS;
|
||||
}
|
||||
|
||||
|
@ -16,20 +16,20 @@ BOOL add_fake_device(const GUID* guid, const WCHAR* path) {
|
||||
}
|
||||
|
||||
HDEVINFO WINAPI FakeSetupDiGetClassDevsA(const GUID* ClassGuid, PCWSTR Enumerator, HWND hwndParent, DWORD Flags) {
|
||||
log_misc("setupapi", "SetupDiGetClassDevsA(%p, %s, %d, %d)", ClassGuid, Enumerator, hwndParent, Flags);
|
||||
log_misc(plfSetupAPI, "SetupDiGetClassDevsA(%p, %s, %d, %d)", ClassGuid, Enumerator, hwndParent, Flags);
|
||||
HDEVINFO res = TrueSetupDiGetClassDevsA(ClassGuid, Enumerator, hwndParent, Flags);
|
||||
|
||||
if (res != INVALID_HANDLE_VALUE && ClassGuid != NULL) {
|
||||
FAKE_DEVICE* device = fake_devices;
|
||||
while (device != NULL) {
|
||||
if (memcmp(device->guid, ClassGuid, sizeof(*ClassGuid)) == 0) {
|
||||
log_misc("setupapi", "injecting %ls into class devs list", device->path);
|
||||
log_misc(plfSetupAPI, "injecting %ls into class devs list", device->path);
|
||||
device->handle = res;
|
||||
}
|
||||
device = device->next;
|
||||
}
|
||||
} else {
|
||||
log_warning("setupapi", "upstream SetupDiGetClassDevsA failed: %d", GetLastError());
|
||||
log_warning(plfSetupAPI, "upstream SetupDiGetClassDevsA failed: %d", GetLastError());
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -38,12 +38,12 @@ HDEVINFO WINAPI FakeSetupDiGetClassDevsA(const GUID* ClassGuid, PCWSTR Enumerato
|
||||
BOOL WINAPI FakeSetupDiEnumDeviceInterfaces(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData,
|
||||
const GUID* InterfaceClassGuid, DWORD MemberIndex,
|
||||
PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData) {
|
||||
log_misc("setupapi", "SetupDiEnumDeviceInterfaces");
|
||||
log_misc(plfSetupAPI, "SetupDiEnumDeviceInterfaces");
|
||||
FAKE_DEVICE* device = fake_devices;
|
||||
if (DeviceInterfaceData) {
|
||||
while (device != NULL) {
|
||||
if (device->handle == DeviceInfoSet) {
|
||||
log_info("setupapi", "hooking fake device: %ls", device->path);
|
||||
log_info(plfSetupAPI, "hooking fake device: %ls", device->path);
|
||||
memcpy(&DeviceInterfaceData->InterfaceClassGuid, device->guid, sizeof *device->guid);
|
||||
DeviceInterfaceData->Flags = SPINT_ACTIVE;
|
||||
DeviceInterfaceData->Reserved = (ULONG_PTR)device->path;
|
||||
@ -55,7 +55,7 @@ BOOL WINAPI FakeSetupDiEnumDeviceInterfaces(HDEVINFO DeviceInfoSet, PSP_DEVINFO_
|
||||
}
|
||||
|
||||
// Fallback
|
||||
log_misc("setupapi", "device info fallthrough");
|
||||
log_misc(plfSetupAPI, "device info fallthrough");
|
||||
return TrueSetupDiEnumDeviceInterfaces(DeviceInfoSet, DeviceInfoData, InterfaceClassGuid, MemberIndex,
|
||||
DeviceInterfaceData);
|
||||
}
|
||||
@ -64,11 +64,11 @@ BOOL WINAPI FakeSetupDiGetDeviceInterfaceDetailA(HDEVINFO DeviceInfoSet, PSP_DEV
|
||||
PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData,
|
||||
DWORD DeviceInterfaceDetailDataSize, PDWORD RequiredSize,
|
||||
PSP_DEVINFO_DATA DeviceInfoData) {
|
||||
log_misc("setupapi", "SetupDiGetDeviceInterfaceDetailA");
|
||||
log_misc(plfSetupAPI, "SetupDiGetDeviceInterfaceDetailA");
|
||||
FAKE_DEVICE* device = fake_devices;
|
||||
while (device != NULL) {
|
||||
if (device->handle == DeviceInfoSet && (ULONG_PTR)device->path == DeviceInterfaceData->Reserved) {
|
||||
log_info("setupapi", "Intercepted SetupDiGetDeviceInterfaceDetailA");
|
||||
log_info(plfSetupAPI, "Intercepted SetupDiGetDeviceInterfaceDetailA");
|
||||
|
||||
const WCHAR* res = (WCHAR*)DeviceInterfaceData->Reserved;
|
||||
int new_len = (wcslen(res) + 1) * (sizeof *res);
|
||||
@ -94,7 +94,7 @@ BOOL WINAPI FakeSetupDiGetDeviceInterfaceDetailA(HDEVINFO DeviceInfoSet, PSP_DEV
|
||||
device = device->next;
|
||||
}
|
||||
|
||||
log_misc("setupapi", "TrueSetupDiGetDeviceInterfaceDetailA fallthrough");
|
||||
log_misc(plfSetupAPI, "TrueSetupDiGetDeviceInterfaceDetailA fallthrough");
|
||||
return TrueSetupDiGetDeviceInterfaceDetailA(DeviceInfoSet, DeviceInterfaceData, DeviceInterfaceDetailData,
|
||||
DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ OSVERSIONINFOA OS_VERSION = {
|
||||
WCHAR TEMP_PATH[] = L"C:\\DOCUME~1\\SYSTEM~1\\LOCALS~1\\Temp\\";
|
||||
|
||||
BOOL WINAPI FakeGetVersionExA(LPOSVERSIONINFOA lpVersionInformation) {
|
||||
log_trace("system", "GetVersionExA");
|
||||
log_trace(plfSystem, "GetVersionExA");
|
||||
memcpy(lpVersionInformation, &OS_VERSION, sizeof OS_VERSION);
|
||||
return TRUE;
|
||||
}
|
||||
@ -21,7 +21,7 @@ BOOL WINAPI FakeGetVolumeInformationW(LPCWSTR lpRootPathName, LPWSTR lpVolumeNam
|
||||
DWORD nVolumeNameSize, LPDWORD lpVolumeSerialNumber,
|
||||
LPDWORD lpMaximumComponentLength, LPDWORD lpFileSystemFlags,
|
||||
LPWSTR lpFileSystemNameBuffer, DWORD nFileSystemNameSize) {
|
||||
log_trace("system", "GetVolumeInformationW");
|
||||
log_trace(plfSystem, "GetVolumeInformationW");
|
||||
if (lpVolumeNameBuffer && nVolumeNameSize) lpVolumeNameBuffer[0] = '\0';
|
||||
if (lpVolumeSerialNumber) *lpVolumeSerialNumber = 0x00144db0;
|
||||
if (lpMaximumComponentLength) *lpMaximumComponentLength = 0xff;
|
||||
@ -46,16 +46,16 @@ LONG WINAPI FakeChangeDisplaySettingsExA(LPCSTR lpszDeviceName, DEVMODEA* lpDevM
|
||||
}
|
||||
|
||||
FARPROC FakeGetProcAddress(HMODULE hModule, LPCSTR lpProcName) {
|
||||
log_trace("system", "GetProcAddress(%s)", lpProcName);
|
||||
log_trace(plfSystem, "GetProcAddress(%s)", lpProcName);
|
||||
return TrueGetProcAddress(hModule, lpProcName);
|
||||
}
|
||||
HMODULE FakeGetModuleHandleA(LPCSTR lpModuleName) {
|
||||
log_trace("system", "GetModuleHandleA(%s)", lpModuleName);
|
||||
log_trace(plfSystem, "GetModuleHandleA(%s)", lpModuleName);
|
||||
return TrueGetModuleHandleA(lpModuleName);
|
||||
}
|
||||
|
||||
LONG WINAPI FakeRtlGetVersion(PRTL_OSVERSIONINFOW lpVersionInformation) {
|
||||
log_trace("system", "RtlGetVersion(%p)", lpVersionInformation);
|
||||
log_trace(plfSystem, "RtlGetVersion(%p)", lpVersionInformation);
|
||||
|
||||
if (lpVersionInformation->dwOSVersionInfoSize >= sizeof (OSVERSIONINFOW)) {
|
||||
lpVersionInformation->dwMajorVersion = OS_VERSION.dwMajorVersion;
|
||||
|
@ -9,7 +9,7 @@ BOOL WINAPI Fake_SetLocalTime(const SYSTEMTIME* lpSystemTime) {
|
||||
memcpy(&localTime, lpSystemTime, sizeof localTime);
|
||||
ltCache = TRUE;
|
||||
|
||||
log_info("time", "Not setting local time to: %04d-%02d-%02d %02d:%02d:%02d.%04d",
|
||||
log_info(plfTime, "Not setting local time to: %04d-%02d-%02d %02d:%02d:%02d.%04d",
|
||||
lpSystemTime->wYear, lpSystemTime->wMonth, lpSystemTime->wDay, lpSystemTime->wHour,
|
||||
lpSystemTime->wMinute, lpSystemTime->wSecond, lpSystemTime->wMilliseconds);
|
||||
return TRUE;
|
||||
@ -18,20 +18,20 @@ BOOL WINAPI Fake_SetSystemTime(const SYSTEMTIME* lpSystemTime) {
|
||||
memcpy(&systemTime, lpSystemTime, sizeof systemTime);
|
||||
stCache = TRUE;
|
||||
|
||||
log_info("time", "Not setting system time to: %04d-%02d-%02d %02d:%02d:%02d.%04d",
|
||||
log_info(plfTime, "Not setting system time to: %04d-%02d-%02d %02d:%02d:%02d.%04d",
|
||||
lpSystemTime->wYear, lpSystemTime->wMonth, lpSystemTime->wDay, lpSystemTime->wHour,
|
||||
lpSystemTime->wMinute, lpSystemTime->wSecond, lpSystemTime->wMilliseconds);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WINAPI Fake_SetTimeZoneInformation(const TIME_ZONE_INFORMATION* lpTimeZoneInformation) {
|
||||
log_info("time", "Not setting timezone to: %d", lpTimeZoneInformation->Bias);
|
||||
log_info(plfTime, "Not setting timezone to: %d", lpTimeZoneInformation->Bias);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// TODO: Store deltas instead
|
||||
BOOL WINAPI Fake_GetLocalTime(SYSTEMTIME* lpSystemTime) {
|
||||
log_trace("time", "GetLocalTime");
|
||||
log_trace(plfTime, "GetLocalTime");
|
||||
if (ltCache) {
|
||||
memcpy(lpSystemTime, &localTime, sizeof localTime);
|
||||
return TRUE;
|
||||
@ -49,7 +49,7 @@ BOOL WINAPI Fake_GetLocalTime(SYSTEMTIME* lpSystemTime) {
|
||||
return TrueGetLocalTime(lpSystemTime);
|
||||
}
|
||||
BOOL WINAPI Fake_GetSystemTime(SYSTEMTIME* lpSystemTime) {
|
||||
log_trace("time", "GetSystemTime");
|
||||
log_trace(plfTime, "GetSystemTime");
|
||||
if (stCache) {
|
||||
memcpy(lpSystemTime, &systemTime, sizeof systemTime);
|
||||
return TRUE;
|
||||
|
@ -9,6 +9,7 @@ struct {
|
||||
int buttons[JVS_BUTTON_PAIR_COUNT * 2];
|
||||
bool invert[JVS_BUTTON_PAIR_COUNT * 2];
|
||||
int test;
|
||||
} jvsKeybindings[JVS_IO_MAX];
|
||||
int notdefault;
|
||||
} jvsKeybindings[JVS_IO_MAX] = { 0 };
|
||||
|
||||
int keySystemTest = 0;
|
||||
|
@ -19,6 +19,7 @@ shared_library(
|
||||
gui_files,
|
||||
|
||||
'comdevice.c',
|
||||
'games.c',
|
||||
|
||||
'dllmain.c',
|
||||
],
|
||||
@ -28,7 +29,11 @@ shared_library(
|
||||
amiTimer,
|
||||
amiMd5,
|
||||
mxk,
|
||||
|
||||
# Madoka service emulation
|
||||
mxklib,
|
||||
dummymaster,
|
||||
dummyinstaller,
|
||||
],
|
||||
include_directories: [
|
||||
openssl_inc,
|
||||
|
@ -19,3 +19,4 @@ BOOL PathEqual(LPCSTR path1, LPCSTR path2);
|
||||
BOOL PathPrefix(LPCSTR path, LPCSTR prefix);
|
||||
|
||||
void make_dirs(const char* path);
|
||||
void* open_mapped_file(LPCWSTR path, DWORD size, HANDLE* file, HANDLE* file_mapping);
|
||||
|
@ -122,12 +122,12 @@ void* CreateHook32(PVOID src, PVOID dst) {
|
||||
// cmd BYTE PTR ds:0x...,0x...
|
||||
len = 10;
|
||||
} else {
|
||||
log_error(HOOKS_LOGGER, "Unable to identify gateway length! Function peek:");
|
||||
log_error(plfHooks, "Unable to identify gateway length! Function peek:");
|
||||
for (int i = 0; i < 16; i++) {
|
||||
printf("%02x ", ((LPBYTE)src)[i]);
|
||||
}
|
||||
puts("");
|
||||
log_error(HOOKS_LOGGER, "Unsafely defaulting to 5!");
|
||||
log_error(plfHooks, "Unsafely defaulting to 5!");
|
||||
len = 5;
|
||||
}
|
||||
|
||||
@ -147,10 +147,10 @@ void* CreateHook32(PVOID src, PVOID dst) {
|
||||
extern FARPROC (*TrueGetProcAddress)(HMODULE hModule, LPCSTR lpProcName);
|
||||
|
||||
void setup_hooks() {
|
||||
log_info(HOOKS_LOGGER, "attaching");
|
||||
log_info(plfHooks, "attaching");
|
||||
|
||||
if (hook_list == NULL) {
|
||||
log_warning(HOOKS_LOGGER, "No hooks to register!");
|
||||
log_warning(plfHooks, "No hooks to register!");
|
||||
return;
|
||||
}
|
||||
function_hook_t* hook = hook_list;
|
||||
@ -159,7 +159,7 @@ void setup_hooks() {
|
||||
|
||||
HMODULE dll = LoadLibraryA(hook->dll);
|
||||
if (dll == NULL) {
|
||||
log_error(HOOKS_LOGGER, "failed to load dll %s (%03x). %s skipped", hook->dll,
|
||||
log_error(plfHooks, "failed to load dll %s (%03x). %s skipped", hook->dll,
|
||||
GetLastError(), hook->name);
|
||||
hook = hook->next;
|
||||
continue;
|
||||
@ -169,16 +169,16 @@ void setup_hooks() {
|
||||
// (TrueGetProcAddress ? TrueGetProcAddress : GetProcAddress)(dll, hook->name);
|
||||
void* original = GetProcAddress(dll, hook->name);
|
||||
if (original == NULL) {
|
||||
log_warning(HOOKS_LOGGER, "failed to get original %s (%03x)", hook->name,
|
||||
log_warning(plfHooks, "failed to get original %s (%03x)", hook->name,
|
||||
GetLastError());
|
||||
} else {
|
||||
void* gateway = CreateHook32(original, hook->patch);
|
||||
if (hook->store != NULL) *hook->store = gateway;
|
||||
log_misc(HOOKS_LOGGER, "hooked %s", hook->name);
|
||||
log_misc(plfHooks, "hooked %s", hook->name);
|
||||
}
|
||||
|
||||
hook = hook->next;
|
||||
} while (hook != NULL);
|
||||
|
||||
log_info(HOOKS_LOGGER, "attach complete");
|
||||
log_info(plfHooks, "attach complete");
|
||||
}
|
||||
|
@ -11,6 +11,14 @@
|
||||
#include "../hooks/files.h"
|
||||
#include "../hooks/logging.h"
|
||||
|
||||
#define _LF(category, name, display) \
|
||||
LOG_FACILITY lf##name = { \
|
||||
.m_name = display, \
|
||||
}; \
|
||||
PLOG_FACILITY plf##name = &lf##name;
|
||||
#include "log_facilities.def"
|
||||
#undef _LF
|
||||
|
||||
extern WCHAR exeName[MAX_PATH + 1];
|
||||
extern DWORD imageOffset;
|
||||
|
||||
@ -32,7 +40,6 @@ char* log_prelude() {
|
||||
}
|
||||
|
||||
static HANDLE log_file = NULL;
|
||||
VOID trace_hook(char* output);
|
||||
CRITICAL_SECTION logger_lock;
|
||||
|
||||
static char* log_colours[] = {
|
||||
@ -47,21 +54,21 @@ static char* log_colours[] = {
|
||||
static const char* COLOR_RESET = "\033[0m";
|
||||
#define LOG_PREFIXES "!GEWIMT"
|
||||
|
||||
void logcb(LPCSTR param_1) { log_game("amLog", param_1); }
|
||||
void logcb(LPCSTR param_1) { log_game(plfAmLog, "%s", param_1); }
|
||||
void __stdcall amLogCallback(DWORD level, char* format) {
|
||||
if (level == 0)
|
||||
log_game("amLog:E", format);
|
||||
log_game(plfAmLog, "E:%s", format);
|
||||
else if (level == 0)
|
||||
log_game("amLog:W", format);
|
||||
log_game(plfAmLog, "W:%s", format);
|
||||
else
|
||||
log_game("amLog:I", format);
|
||||
log_game(plfAmLog, "I:%s", format);
|
||||
}
|
||||
|
||||
DWORD pLogcb;
|
||||
DWORD* ppLogcb;
|
||||
|
||||
static char log_buf[1024];
|
||||
int _do_log(BYTE log_level, const char* caller, const char* format, va_list args) {
|
||||
int _do_log(BYTE log_level, PLOG_FACILITY facility, const char* format, va_list args) {
|
||||
// TODO: These are all horrible bodges
|
||||
if (wcscmp(exeName, L"mxnetwork.exe") == 0) {
|
||||
// *((DWORD*)(imageOffset + 0x004438e8)) = (DWORD)(&logcb);
|
||||
@ -82,7 +89,7 @@ int _do_log(BYTE log_level, const char* caller, const char* format, va_list args
|
||||
int col_len = strlen(log_colours[log_level]);
|
||||
|
||||
int log_len = snprintf(log_buf, _countof(log_buf), "%s%s%c:%s:", log_colours[log_level],
|
||||
log_prelude(), prefix, caller);
|
||||
log_prelude(), prefix, facility->m_name);
|
||||
log_len += vsnprintf(log_buf + log_len, _countof(log_buf) - log_len, format, args);
|
||||
log_len += snprintf(log_buf + log_len, _countof(log_buf) - log_len, "%s\n", COLOR_RESET);
|
||||
log_buf[_countof(log_buf) - 1] = '\0';
|
||||
@ -105,75 +112,70 @@ int _do_log(BYTE log_level, const char* caller, const char* format, va_list args
|
||||
LeaveCriticalSection(&logger_lock);
|
||||
return log_len;
|
||||
}
|
||||
int vlog_trace(const char* caller, const char* format, va_list args) {
|
||||
return _do_log(LOG_TRACE, caller, format, args);
|
||||
int vlog_trace(PLOG_FACILITY facility, const char* format, va_list args) {
|
||||
return _do_log(LOG_TRACE, facility, format, args);
|
||||
}
|
||||
int _log_trace(const char* caller, const char* format, ...) {
|
||||
int _log_trace(PLOG_FACILITY facility, const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int ret = vlog_trace(caller, format, args);
|
||||
int ret = vlog_trace(facility, format, args);
|
||||
va_end(args);
|
||||
return ret;
|
||||
}
|
||||
int vlog_misc(const char* caller, const char* format, va_list args) {
|
||||
return _do_log(LOG_MISC, caller, format, args);
|
||||
int vlog_misc(PLOG_FACILITY facility, const char* format, va_list args) {
|
||||
return _do_log(LOG_MISC, facility, format, args);
|
||||
}
|
||||
int _log_misc(const char* caller, const char* format, ...) {
|
||||
int _log_misc(PLOG_FACILITY facility, const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int ret = vlog_misc(caller, format, args);
|
||||
int ret = vlog_misc(facility, format, args);
|
||||
va_end(args);
|
||||
return ret;
|
||||
}
|
||||
int vlog_info(const char* caller, const char* format, va_list args) {
|
||||
return _do_log(LOG_INFO, caller, format, args);
|
||||
int vlog_info(PLOG_FACILITY facility, const char* format, va_list args) {
|
||||
return _do_log(LOG_INFO, facility, format, args);
|
||||
}
|
||||
int _log_info(const char* caller, const char* format, ...) {
|
||||
int _log_info(PLOG_FACILITY facility, const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int ret = vlog_info(caller, format, args);
|
||||
int ret = vlog_info(facility, format, args);
|
||||
va_end(args);
|
||||
return ret;
|
||||
}
|
||||
int vlog_warning(const char* caller, const char* format, va_list args) {
|
||||
return _do_log(LOG_WARNING, caller, format, args);
|
||||
int vlog_warning(PLOG_FACILITY facility, const char* format, va_list args) {
|
||||
return _do_log(LOG_WARNING, facility, format, args);
|
||||
}
|
||||
int _log_warning(const char* caller, const char* format, ...) {
|
||||
int _log_warning(PLOG_FACILITY facility, const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int ret = vlog_warning(caller, format, args);
|
||||
int ret = vlog_warning(facility, format, args);
|
||||
va_end(args);
|
||||
return ret;
|
||||
}
|
||||
int vlog_error(const char* caller, const char* format, va_list args) {
|
||||
return _do_log(LOG_ERROR, caller, format, args);
|
||||
int vlog_error(PLOG_FACILITY facility, const char* format, va_list args) {
|
||||
return _do_log(LOG_ERROR, facility, format, args);
|
||||
}
|
||||
int _log_error(const char* caller, const char* format, ...) {
|
||||
int _log_error(PLOG_FACILITY facility, const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int ret = vlog_error(caller, format, args);
|
||||
int ret = vlog_error(facility, format, args);
|
||||
va_end(args);
|
||||
return ret;
|
||||
}
|
||||
int vlog_game(const char* caller, const char* format, va_list args) {
|
||||
return _do_log(LOG_GAME, caller, format, args);
|
||||
int vlog_game(PLOG_FACILITY facility, const char* format, va_list args) {
|
||||
return _do_log(LOG_GAME, facility, format, args);
|
||||
}
|
||||
int _log_game(const char* caller, const char* format, ...) {
|
||||
int _log_game(PLOG_FACILITY facility, const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int ret = vlog_game(caller, format, args);
|
||||
int ret = vlog_game(facility, format, args);
|
||||
va_end(args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
VOID trace_hook(char* output) {
|
||||
output[strcspn(output, "\n")] = 0;
|
||||
log_error("trace", output);
|
||||
}
|
||||
|
||||
void setup_logging() {
|
||||
// Force stdio even for GUI applications
|
||||
AttachConsole(ATTACH_PARENT_PROCESS);
|
||||
// AttachConsole(ATTACH_PARENT_PROCESS);
|
||||
|
||||
// Enable colour in CMD
|
||||
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
@ -190,7 +192,7 @@ void setup_logging() {
|
||||
}
|
||||
}
|
||||
|
||||
void log_stack(const char* caller) {
|
||||
void log_stack(PLOG_FACILITY facility) {
|
||||
char name[MAX_PATH * sizeof(TCHAR)];
|
||||
char Storage[sizeof(IMAGEHLP_SYMBOL64) + sizeof(name)];
|
||||
|
||||
@ -220,7 +222,7 @@ void log_stack(const char* caller) {
|
||||
SymGetSymFromAddr64(process, (ULONG64)stack.AddrPC.Offset, &displacement, symbol);
|
||||
UnDecorateSymbolName(symbol->Name, (PSTR)name, sizeof(name), UNDNAME_COMPLETE);
|
||||
|
||||
log_error(caller, "%02u called from 0x%08X STACK=0x%08X FRAME=0x%08X %s\n", frame,
|
||||
log_error(facility, "%02u called from 0x%08X STACK=0x%08X FRAME=0x%08X %s\n", frame,
|
||||
(ULONG64)stack.AddrPC.Offset, (ULONG64)stack.AddrStack.Offset,
|
||||
(ULONG64)stack.AddrFrame.Offset, symbol->Name);
|
||||
|
||||
|
@ -10,27 +10,33 @@
|
||||
#define LOG_MISC 5
|
||||
#define LOG_TRACE 6
|
||||
|
||||
#define COMM_LOGGER "comm"
|
||||
#define HOOKS_LOGGER "hooks"
|
||||
#define BOOT_LOGGER "boot"
|
||||
typedef struct {
|
||||
char* m_name;
|
||||
} LOG_FACILITY, *PLOG_FACILITY;
|
||||
|
||||
#define _LF(category, name, display) extern PLOG_FACILITY plf##name;
|
||||
#include "log_facilities.def"
|
||||
#undef _LF
|
||||
|
||||
extern PLOG_FACILITY plfNetwork;
|
||||
|
||||
extern CRITICAL_SECTION logger_lock;
|
||||
|
||||
int _log_trace(const char* caller, const char* format, ...);
|
||||
int _log_misc(const char* caller, const char* format, ...);
|
||||
int _log_info(const char* caller, const char* format, ...);
|
||||
int _log_warning(const char* caller, const char* format, ...);
|
||||
int _log_error(const char* caller, const char* format, ...);
|
||||
int _log_game(const char* caller, const char* format, ...);
|
||||
int _log_trace(PLOG_FACILITY facility, const char* format, ...);
|
||||
int _log_misc(PLOG_FACILITY facility, const char* format, ...);
|
||||
int _log_info(PLOG_FACILITY facility, const char* format, ...);
|
||||
int _log_warning(PLOG_FACILITY facility, const char* format, ...);
|
||||
int _log_error(PLOG_FACILITY facility, const char* format, ...);
|
||||
int _log_game(PLOG_FACILITY facility, const char* format, ...);
|
||||
|
||||
int vlog_trace(const char* caller, const char* format, va_list args);
|
||||
int vlog_misc(const char* caller, const char* format, va_list args);
|
||||
int vlog_info(const char* caller, const char* format, va_list args);
|
||||
int vlog_warning(const char* caller, const char* format, va_list args);
|
||||
int vlog_error(const char* caller, const char* format, va_list args);
|
||||
int vlog_game(const char* caller, const char* format, va_list args);
|
||||
int vlog_trace(PLOG_FACILITY facility, const char* format, va_list args);
|
||||
int vlog_misc(PLOG_FACILITY facility, const char* format, va_list args);
|
||||
int vlog_info(PLOG_FACILITY facility, const char* format, va_list args);
|
||||
int vlog_warning(PLOG_FACILITY facility, const char* format, va_list args);
|
||||
int vlog_error(PLOG_FACILITY facility, const char* format, va_list args);
|
||||
int vlog_game(PLOG_FACILITY facility, const char* format, va_list args);
|
||||
|
||||
void log_stack(const char* caller);
|
||||
void log_stack(PLOG_FACILITY facility);
|
||||
|
||||
void setup_logging();
|
||||
|
||||
|
40
src/micetools/dll/util/log_facilities.def
Normal file
40
src/micetools/dll/util/log_facilities.def
Normal 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")
|
@ -110,7 +110,7 @@ HANDLE GetDummyHandle() {
|
||||
_CreateFileA(path, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
|
||||
if (hObject == INVALID_HANDLE_VALUE) {
|
||||
log_error(HOOKS_LOGGER, "Failed to create dummy handle: %03x", GetLastError());
|
||||
log_error(plfMisc, "Failed to create dummy handle: %03x", GetLastError());
|
||||
}
|
||||
|
||||
return hObject;
|
||||
@ -152,3 +152,38 @@ void make_dirs(const char* path) {
|
||||
}
|
||||
free(temp);
|
||||
}
|
||||
|
||||
void* open_mapped_file(LPCWSTR path, DWORD size, HANDLE* file, HANDLE* file_mapping) {
|
||||
make_dirs(path);
|
||||
*file = _CreateFileW(path, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
|
||||
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (*file == INVALID_HANDLE_VALUE) {
|
||||
log_error(plfMisc, "Failed to CreateFileW(%ls): %d", path, GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*file_mapping =
|
||||
CreateFileMappingW(*file, NULL, PAGE_READWRITE, 0, size, NULL);
|
||||
|
||||
if (*file_mapping == INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(*file);
|
||||
*file = INVALID_HANDLE_VALUE;
|
||||
|
||||
log_error(plfMisc, "Failed to CreateFileMappingW: %d", GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SetLastError(0);
|
||||
void* mapping = MapViewOfFile(*file_mapping, FILE_MAP_ALL_ACCESS, 0, 0, size);
|
||||
if (mapping == NULL || GetLastError()) {
|
||||
log_error(plfMisc, "Failed to MapViewOfFileEx: %d", GetLastError());
|
||||
CloseHandle(*file);
|
||||
CloseHandle(*file_mapping);
|
||||
*file = INVALID_HANDLE_VALUE;
|
||||
*file_mapping = INVALID_HANDLE_VALUE;
|
||||
return NULL;
|
||||
}
|
||||
return mapping;
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ typedef enum binary_mode {
|
||||
|
||||
#define SOCKET_INVAL ((SOCKET)-1)
|
||||
#define HANDLE_INVAL -1
|
||||
#define TIMEOUT_NONE ((DWORD)-1)
|
||||
#define TIMEOUT_NONE ((timeout_t)-1)
|
||||
|
||||
#define PCPT_CLOSED 0
|
||||
#define PCPT_LISTENING 1
|
||||
|
@ -110,6 +110,7 @@ e_pcpa_t pcpaInitStream(pcpa_t *stream) {
|
||||
stream->binary_mode_after_cb = NULL;
|
||||
stream->binary_mode_before_data = NULL;
|
||||
stream->binary_mode_after_data = NULL;
|
||||
stream->before_cb = NULL;
|
||||
ZERO(stream->recv_data);
|
||||
ZERO(stream->send_data);
|
||||
return e_pcpa_ok;
|
||||
@ -222,7 +223,7 @@ e_pcpa_t pcpaSetCallbackFuncBuffer(pcpa_t *stream, pcpa_cb_table_t *callback_tab
|
||||
return e_pcpa_stream_unset;
|
||||
}
|
||||
|
||||
if (callback_table == NULL || callbacks_max == 0) return e_pcpa_timeout_closed;
|
||||
if (callback_table == NULL || callbacks_max == 0) return e_pcpa_no_table_space;
|
||||
|
||||
stream->callback_max = callbacks_max;
|
||||
stream->callback_table = callback_table;
|
||||
@ -276,7 +277,7 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
|
||||
case pcpa_state_none:
|
||||
amiTimerGet(&time);
|
||||
ms = _amTimeDelta(time, time_start);
|
||||
if (timeout_ms != -1) {
|
||||
if (timeout_ms != TIMEOUT_NONE) {
|
||||
if (ms < (uint)timeout_ms) {
|
||||
timeout = timeout_ms - ms;
|
||||
local_14 = timeout;
|
||||
@ -294,9 +295,10 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
|
||||
if (eVar4 == e_pcpa_ok) {
|
||||
stream->state = 10;
|
||||
amiTimerGet(&time);
|
||||
if (timeout_ms != -1) {
|
||||
ms = _amTimeDelta(time, time_start);
|
||||
goto joined_r0x00454a58;
|
||||
if (timeout_ms != TIMEOUT_NONE &&
|
||||
_amTimeDelta(time, time_start) >= timeout_ms) {
|
||||
stream->err = e_pcpa_to;
|
||||
return stream->err;
|
||||
}
|
||||
} else {
|
||||
stream->state = pcpa_state_none;
|
||||
@ -311,7 +313,7 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
|
||||
case 9:
|
||||
amiTimerGet(&time);
|
||||
ms = _amTimeDelta(time, time_start);
|
||||
if (timeout_ms != -1) {
|
||||
if (timeout_ms != TIMEOUT_NONE) {
|
||||
if (ms < (uint)timeout_ms) {
|
||||
timeout = timeout_ms - ms;
|
||||
local_14 = timeout;
|
||||
@ -333,13 +335,10 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
|
||||
if (stream->binary_mode == binary_mode_none) {
|
||||
stream->state = (stream->state != pcpa_state_wait_request) - 1 & 10;
|
||||
amiTimerGet(&time);
|
||||
if (timeout_ms != -1) {
|
||||
ms = _amTimeDelta(time, time_start);
|
||||
joined_r0x00454a58:
|
||||
if ((uint)timeout_ms <= ms) {
|
||||
stream->err = e_pcpa_to;
|
||||
return stream->err;
|
||||
}
|
||||
if (timeout_ms != TIMEOUT_NONE &&
|
||||
_amTimeDelta(time, time_start) >= timeout_ms) {
|
||||
stream->err = e_pcpa_to;
|
||||
return stream->err;
|
||||
}
|
||||
} else {
|
||||
pcpaCloseBinary(stream);
|
||||
@ -351,9 +350,10 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
|
||||
stream->binary_mode_after_cb = NULL;
|
||||
}
|
||||
amiTimerGet(&time);
|
||||
if (timeout_ms != -1) {
|
||||
ms = _amTimeDelta(time, time_start);
|
||||
goto joined_r0x00454a58;
|
||||
if (timeout_ms != TIMEOUT_NONE &&
|
||||
_amTimeDelta(time, time_start) >= timeout_ms) {
|
||||
stream->err = e_pcpa_to;
|
||||
return stream->err;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -378,9 +378,8 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
|
||||
stream->binary_mode_before_cb = NULL;
|
||||
}
|
||||
amiTimerGet(&time);
|
||||
ms = _amTimeDelta(time, time_start);
|
||||
if (timeout_ms != -1) {
|
||||
if (ms < (uint)timeout_ms) {
|
||||
if (timeout_ms != TIMEOUT_NONE) {
|
||||
if (_amTimeDelta(time, time_start) > timeout_ms) {
|
||||
timeout = timeout_ms - ms;
|
||||
local_14 = timeout;
|
||||
} else {
|
||||
@ -403,9 +402,10 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
|
||||
if (stream->err == e_pcpa_ok) {
|
||||
LAB_00454a1a:
|
||||
amiTimerGet(&time);
|
||||
if (timeout_ms != -1) {
|
||||
ms = _amTimeDelta(time, time_start);
|
||||
goto joined_r0x00454a58;
|
||||
if (timeout_ms != TIMEOUT_NONE &&
|
||||
_amTimeDelta(time, time_start) >= timeout_ms) {
|
||||
stream->err = e_pcpa_to;
|
||||
return stream->err;
|
||||
}
|
||||
} else {
|
||||
PCP_LOG("error pcpaSendBinary\n");
|
||||
@ -421,7 +421,7 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
|
||||
}
|
||||
amiTimerGet(&time);
|
||||
ms = _amTimeDelta(time, time_start);
|
||||
if (timeout_ms != -1) {
|
||||
if (timeout_ms != TIMEOUT_NONE) {
|
||||
if (ms < (uint)timeout_ms) {
|
||||
timeout = timeout_ms - ms;
|
||||
local_14 = timeout;
|
||||
@ -447,9 +447,9 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
if (stream->before_cb != NULL) {
|
||||
// TODO: Figure out why recv_buf is empty at this point in the FSM
|
||||
if (stream->before_cb != NULL)
|
||||
stream->before_cb(stream, stream->pcpp.sock.recv_buf);
|
||||
}
|
||||
|
||||
if (stream->callback_table == NULL) {
|
||||
PCP_LOG("error Callback_table buffer isn\'t set\n");
|
||||
@ -492,7 +492,7 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
|
||||
LAB_004547f1:
|
||||
amiTimerGet(&time);
|
||||
ms = _amTimeDelta(time, time_start);
|
||||
if (timeout_ms != -1) {
|
||||
if (timeout_ms != TIMEOUT_NONE) {
|
||||
if (ms < (uint)timeout_ms) {
|
||||
local_14 = timeout_ms - ms;
|
||||
} else {
|
||||
@ -514,9 +514,9 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
|
||||
}
|
||||
amiTimerGet(&time);
|
||||
timeout = local_14;
|
||||
if (timeout_ms != TIMEOUT_NONE) {
|
||||
ms = _amTimeDelta(time, time_start);
|
||||
goto joined_r0x00454a58;
|
||||
if (timeout_ms != TIMEOUT_NONE && _amTimeDelta(time, time_start) >= timeout_ms) {
|
||||
stream->err = e_pcpa_to;
|
||||
return stream->err;
|
||||
}
|
||||
}
|
||||
} while (stream->err == e_pcpa_ok);
|
||||
|
@ -11,7 +11,8 @@ typedef enum e_pcpa {
|
||||
e_pcpa_cannot_open = -2,
|
||||
e_pcpa_generic = -3,
|
||||
e_pcpa_param_invalid = -4,
|
||||
e_pcpa_timeout_closed = -5, // TODO: This is wrong (see: pcpaSetCallbackFuncBuffer)
|
||||
e_pcpa_timeout_closed = -5,
|
||||
e_pcpa_no_table_space = -6,
|
||||
e_pcpa_cb_table_full = -9,
|
||||
e_pcpa_stream_unset = -10,
|
||||
e_pcpa_cb_table_unset = -11,
|
||||
|
@ -480,10 +480,10 @@ e_pcpt_t pcptRecv(pcpt_t *sock, unsigned char *recv_buf, size_t *recv_buf_len,
|
||||
return sock->err = e_pcpt_not_open;
|
||||
}
|
||||
// TODO: URGENT: Something in the FSM causes this condition to error out!
|
||||
// if (sock->client_open != 0) {
|
||||
// PCP_LOG("error PCP already connected\n");
|
||||
// return sock->err = e_pcpt_already_connected;
|
||||
// }
|
||||
if (sock->client_open != 0) {
|
||||
PCP_LOG("error PCP already connected\n");
|
||||
return sock->err = e_pcpt_already_connected;
|
||||
}
|
||||
|
||||
sock->recv_buf = recv_buf;
|
||||
sock->recv_buf_count = recv_buf_len;
|
||||
|
@ -87,6 +87,8 @@ void save_current_config() {
|
||||
for (int board = 0; board < MiceConfig.keys.board_count; board++) {
|
||||
i += snprintf(keybindBuffer + i, _countof(keybindBuffer) - i, "%d,",
|
||||
jvsKeybindings[board].test);
|
||||
i += snprintf(keybindBuffer + i, _countof(keybindBuffer) - i, "%d,",
|
||||
jvsKeybindings[board].notdefault);
|
||||
for (int n = 0; n < JVS_BUTTON_PAIR_COUNT * 2; n++) {
|
||||
i += snprintf(keybindBuffer + i, _countof(keybindBuffer) - i, "%d,",
|
||||
jvsKeybindings[board].buttons[n]);
|
||||
@ -228,13 +230,16 @@ void load_mice_config() {
|
||||
if (state == 0) {
|
||||
jvsKeybindings[board].test = val;
|
||||
state = 1;
|
||||
} else if (state == 1) {
|
||||
jvsKeybindings[board].notdefault = val;
|
||||
state = 2;
|
||||
} else {
|
||||
if (state == 1) {
|
||||
if (state == 2) {
|
||||
jvsKeybindings[board].buttons[n] = val;
|
||||
state = 2;
|
||||
state = 3;
|
||||
} else {
|
||||
jvsKeybindings[board].invert[n] = val;
|
||||
state = 1;
|
||||
state = 2;
|
||||
if (n++ == JVS_BUTTON_PAIR_COUNT * 2) {
|
||||
n = 0;
|
||||
state = 0;
|
||||
|
@ -65,12 +65,6 @@ COMMENT("Second half of system mac address. The vendor prefix D8:BB:C1: will be
|
||||
CFG_hex(network, mac, 6, 0A2F1D, "")
|
||||
ENDSECTION(network)
|
||||
|
||||
SECTION(devices, "Specify COM ports for devices to attach, comma seperated")
|
||||
CFG_str(devices, aime_bd, "2", "AIME reader board")
|
||||
CFG_str(devices, touch_bd, "3", "maimai touch screen")
|
||||
CFG_str(devices, led_bd, "5,6,7,8", "maimai led boards")
|
||||
ENDSECTION(devices)
|
||||
|
||||
SECTION(drivers, "Enable or disable drivers. Disabling any is not recommended.")
|
||||
CFG_bool(drivers, columba, true, "")
|
||||
CFG_bool(drivers, mxsram, true, "")
|
||||
@ -102,6 +96,18 @@ CFG_int(keys, board_count, 1, "")
|
||||
CFG_str(keys, keys, 0, "")
|
||||
ENDSECTION(keys)
|
||||
|
||||
SECTION(devices, "Register attached hardware devices")
|
||||
CFG_bool(devices, do_auto, true, "When true, if the running game is identified, the following 8 values are overwritten")
|
||||
CFG_str(devices, com1, "", "")
|
||||
CFG_str(devices, com2, "", "")
|
||||
CFG_str(devices, com3, "", "")
|
||||
CFG_str(devices, com4, "", "")
|
||||
CFG_str(devices, com5, "", "")
|
||||
CFG_str(devices, com6, "", "")
|
||||
CFG_str(devices, com7, "", "")
|
||||
CFG_str(devices, com8, "", "")
|
||||
ENDSECTION(devices)
|
||||
|
||||
#undef CFG_str
|
||||
#undef CFG_int
|
||||
#undef CFG_bool
|
||||
|
@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
#include <winioctl.h>
|
||||
|
||||
|
@ -2,12 +2,20 @@ mxklib = static_library(
|
||||
'mxk',
|
||||
sources: [
|
||||
'mxk.c',
|
||||
'mxkAb.c',
|
||||
'mxkDs.c',
|
||||
'mxkN2.c',
|
||||
'mxkCrypt.c',
|
||||
'mxkSmbus.c',
|
||||
'mxkPacket.c',
|
||||
'mxkTransport.c',
|
||||
],
|
||||
include_directories: [
|
||||
openssl_inc,
|
||||
],
|
||||
link_with: [
|
||||
amiCrc,
|
||||
amiDebug,
|
||||
],
|
||||
dependencies: [openssl_lib],
|
||||
)
|
||||
|
@ -1,131 +1,234 @@
|
||||
#include "mxk.h"
|
||||
|
||||
BOOL mxkExchengeAesKey(HANDLE mxparallel) {
|
||||
FILETIME filetime;
|
||||
amtime_t now;
|
||||
unsigned int KEYCHIP_STATUS;
|
||||
unsigned char KEYCHIP_ERROR;
|
||||
|
||||
static MXK_STATUS mxkPacketReqRandomBytes(unsigned char* packet) {
|
||||
if (packet == NULL) return MXK_STATUS_INVALID_PARAM;
|
||||
|
||||
amtime_t now;
|
||||
FILETIME filetime;
|
||||
for (int i = 0; i < MXK_BLOCK_SIZE; i++) {
|
||||
amiTimerGet(&now);
|
||||
GetSystemTimeAsFileTime(&filetime);
|
||||
packet[i] = (filetime.dwHighDateTime & 0xff) ^ (filetime.dwLowDateTime & 0xff) ^
|
||||
(now.microseconds & 0xff);
|
||||
}
|
||||
return MXK_STATUS_OK;
|
||||
}
|
||||
|
||||
MXK_STATUS mxkExchengeAesKey(void) {
|
||||
unsigned char key_s[16];
|
||||
unsigned char key_r[16];
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < 16; i++) {
|
||||
amiTimerGet(&now);
|
||||
GetSystemTimeAsFileTime(&filetime);
|
||||
key_s[i] = (filetime.dwHighDateTime & 0xff) ^ (filetime.dwLowDateTime & 0xff) ^
|
||||
(now.microseconds & 0xff);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
amiTimerGet(&now);
|
||||
GetSystemTimeAsFileTime(&filetime);
|
||||
key_r[i] = (filetime.dwHighDateTime & 0xff) ^ (filetime.dwLowDateTime & 0xff) ^
|
||||
(now.microseconds & 0xff);
|
||||
}
|
||||
|
||||
unsigned char packet[16];
|
||||
|
||||
mxkPacketReqSetKeyS(packet);
|
||||
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
|
||||
if (!mxkSendPacket(mxparallel, key_s)) return FALSE;
|
||||
if (!mxkRecvPacket(mxparallel, packet)) return FALSE;
|
||||
if (packet[0] != SetKeyS) return FALSE;
|
||||
mxkPacketReqRandomBytes(key_s);
|
||||
mxkPacketReqRandomBytes(key_r);
|
||||
|
||||
if (mxkPacketReqSetKeyS(packet) != MXK_STATUS_OK) {
|
||||
amiDebugLog("Error mxkPacketReqSetKeyS");
|
||||
return MXK_STATUS_ERROR;
|
||||
}
|
||||
if (mxkSendPacket(packet) != MXK_STATUS_OK) {
|
||||
amiDebugLog("Error mxkSendPacket Command KeyS");
|
||||
return MXK_STATUS_ERROR;
|
||||
}
|
||||
if (mxkSendPacket(key_s) != MXK_STATUS_OK) {
|
||||
amiDebugLog("Error mxkSendPacket KeyS");
|
||||
return MXK_STATUS_ERROR;
|
||||
}
|
||||
if (mxkRecvPacket(packet) != MXK_STATUS_OK || packet[0] != SetKeyS) {
|
||||
amiDebugLog("Error mxkRecvPacket KeyS");
|
||||
return MXK_STATUS_ERROR;
|
||||
}
|
||||
mxkSetKeyS(key_s);
|
||||
|
||||
mxkPacketReqSetKeyR(packet);
|
||||
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
|
||||
if (!mxkSendPacket(mxparallel, key_r)) return FALSE;
|
||||
if (mxkPacketReqSetKeyR(packet) != MXK_STATUS_OK) {
|
||||
amiDebugLog("Error mxkPacketReqSetKeyR");
|
||||
return MXK_STATUS_ERROR;
|
||||
}
|
||||
if (mxkSendPacket(packet) != MXK_STATUS_OK) {
|
||||
amiDebugLog("Error mxkSendPacket Command SetKeyR");
|
||||
return MXK_STATUS_ERROR;
|
||||
}
|
||||
if (mxkSendPacket(key_r) != MXK_STATUS_OK) {
|
||||
amiDebugLog("Error mxkSendPacket KeyR");
|
||||
return MXK_STATUS_ERROR;
|
||||
}
|
||||
mxkSetKeyR(key_r);
|
||||
if (!mxkRecvPacket(mxparallel, packet)) return FALSE;
|
||||
if (mxkRecvPacket(packet) != MXK_STATUS_OK) {
|
||||
amiDebugLog("Error mxkRecvPacket KeyR");
|
||||
return MXK_STATUS_ERROR;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return MXK_STATUS_OK;
|
||||
}
|
||||
|
||||
BOOL mxkVersion(HANDLE mxparallel, unsigned short* version) {
|
||||
BOOL mxkVersionDirty;
|
||||
unsigned short mxkVersionCache;
|
||||
MXK_STATUS mxkVersion(unsigned short* version, MXK_CACHE cache, unsigned char* err) {
|
||||
unsigned char packet[16];
|
||||
|
||||
mxkPacketReqGetVersion(packet);
|
||||
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
|
||||
if (!mxkRecvPacket(mxparallel, packet)) return FALSE;
|
||||
if (version == NULL || err == NULL) return MXK_STATUS_INVALID_PARAM;
|
||||
|
||||
*version = ((unsigned short*)packet)[0];
|
||||
return TRUE;
|
||||
if (KEYCHIP_STATUS == 2) {
|
||||
amiDebugLog("Error MXK_STATUS_ERROR!!");
|
||||
*err = KEYCHIP_ERROR;
|
||||
return MXK_STATUS_ERROR;
|
||||
}
|
||||
|
||||
if (cache == MXK_CACHE_USE) {
|
||||
if (!mxkVersionDirty) {
|
||||
*version = mxkVersionCache;
|
||||
return MXK_STATUS_OK;
|
||||
}
|
||||
} else {
|
||||
mxkVersionDirty = true;
|
||||
}
|
||||
|
||||
mxkPacketReqGetVersion(packet);
|
||||
if (mxkSendPacket(packet) != MXK_STATUS_OK) {
|
||||
amiDebugLog("Error mxkSendPacket!!");
|
||||
goto error;
|
||||
}
|
||||
if (mxkRecvPacket(packet) != MXK_STATUS_OK) {
|
||||
amiDebugLog("Error mxkRecvPacket!!");
|
||||
goto error;
|
||||
}
|
||||
|
||||
*version = mxkVersionCache = ((unsigned short*)packet)[0];
|
||||
mxkVersionDirty = false;
|
||||
return MXK_STATUS_OK;
|
||||
|
||||
error:
|
||||
KEYCHIP_ERROR = 2;
|
||||
KEYCHIP_STATUS = 2;
|
||||
*err = 2;
|
||||
return MXK_STATUS_ERROR;
|
||||
}
|
||||
|
||||
BOOL mxkSetMainId(HANDLE mxparallel, const unsigned char* main_id) {
|
||||
BOOL mxkSetMainId(const unsigned char* main_id) {
|
||||
unsigned char packet[16];
|
||||
|
||||
mxkPacketReqSetMainId(packet);
|
||||
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
|
||||
if (!mxkSendPacket(mxparallel, main_id)) return FALSE;
|
||||
if (!mxkSendPacket(packet)) return FALSE;
|
||||
if (!mxkSendPacket(main_id)) return FALSE;
|
||||
|
||||
mxkRecvPacket(mxparallel, packet);
|
||||
mxkRecvPacket(packet);
|
||||
|
||||
return packet[0] != 0xff;
|
||||
}
|
||||
BOOL mxkGetMainId(HANDLE mxparallel, unsigned char* main_id) {
|
||||
BOOL mxkGetMainId(unsigned char* main_id) {
|
||||
unsigned char packet[16];
|
||||
|
||||
mxkPacketReqGetMainId(packet);
|
||||
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
|
||||
if (!mxkRecvPacket(mxparallel, main_id)) return FALSE;
|
||||
if (!mxkSendPacket(packet)) return FALSE;
|
||||
if (!mxkRecvPacket(main_id)) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
BOOL mxkGetKeyId(HANDLE mxparallel, unsigned char* key_id) {
|
||||
BOOL mxkGetKeyId(unsigned char* key_id) {
|
||||
unsigned char packet[16];
|
||||
|
||||
mxkPacketReqGetKeyId(packet);
|
||||
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
|
||||
if (!mxkRecvPacket(mxparallel, key_id)) return FALSE;
|
||||
if (!mxkSendPacket(packet)) return FALSE;
|
||||
if (!mxkRecvPacket(key_id)) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
BOOL mxkGetAppBootInfo(HANDLE mxparallel, appboot_t* appboot) {
|
||||
unsigned char packet[16];
|
||||
|
||||
mxkPacketReqGetAppBootInfo(packet);
|
||||
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
|
||||
for (int i = 0; i < sizeof *appboot; i += 16) {
|
||||
if (!mxkRecvPacket(mxparallel, (unsigned char*)appboot + i)) return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
BOOL mxkGetPlayCounter(HANDLE mxparallel, DWORD* play_counter) {
|
||||
BOOL mxkGetPlayCounter(DWORD* play_counter) {
|
||||
unsigned char packet[16];
|
||||
|
||||
mxkPacketReqGetPlayCounter(packet);
|
||||
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
|
||||
if (!mxkRecvPacket(mxparallel, packet)) return FALSE;
|
||||
if (!mxkSendPacket(packet)) return FALSE;
|
||||
if (!mxkRecvPacket(packet)) return FALSE;
|
||||
|
||||
*play_counter = ((DWORD*)packet)[0];
|
||||
return TRUE;
|
||||
}
|
||||
BOOL mxkFlashRead(HANDLE mxparallel, unsigned int address, unsigned int nbytes,
|
||||
unsigned char* buffer) {
|
||||
BOOL mxkFlashRead(unsigned int address, unsigned int nbytes, unsigned char* buffer) {
|
||||
unsigned char packet[16];
|
||||
mxkPacketReqFlashRead(packet, address, nbytes);
|
||||
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
|
||||
if (!mxkSendPacket(packet)) return FALSE;
|
||||
|
||||
for (size_t i = 0; i < nbytes; i += 0x100) {
|
||||
unsigned int rest = (nbytes - i) > 0x100 ? 0x100 : (nbytes - i);
|
||||
if (!mxkTransportRecv(mxparallel, buffer + i, rest)) return FALSE;
|
||||
if (!mxkTransportRecv(buffer + i, rest)) return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
BOOL mxkEepromRead(HANDLE mxparallel, unsigned char page, unsigned char* data) {
|
||||
BOOL mxkEepromRead(unsigned char page, unsigned char* data) {
|
||||
unsigned char packet[16];
|
||||
mxkPacketReqEepromRead(packet, page);
|
||||
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
|
||||
if (!mxkRecvPacket(mxparallel, data)) return FALSE;
|
||||
if (!mxkSendPacket(packet)) return FALSE;
|
||||
if (!mxkRecvPacket(data)) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
BOOL mxkNvramRead(HANDLE mxparallel, unsigned short addr, unsigned char blocks, unsigned char* data) {
|
||||
BOOL mxkNvramRead(unsigned short addr, unsigned char blocks, unsigned char* data) {
|
||||
unsigned char packet[16];
|
||||
mxkPacketReqNvramRead(packet, addr, blocks);
|
||||
if (!mxkSendPacket(mxparallel, packet)) return FALSE;
|
||||
if (!mxkSendPacket(packet)) return FALSE;
|
||||
|
||||
for (size_t i = 0; i < blocks; i++) {
|
||||
if (!mxkRecvPacket(mxparallel, data + (i * 16))) return FALSE;
|
||||
if (!mxkRecvPacket(data + (i * 16))) return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool mxkValidString(const char* string, unsigned int length) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
char c = string[i];
|
||||
if (isalnum(c)) continue;
|
||||
if (c != '.' && c != '_' && c != '-' && c != ':' && c != '@' && c != '%' && c != '/' &&
|
||||
c != '\\')
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MXK_STATUS mxkInit() {
|
||||
mxkVersionDirty = true;
|
||||
AppBoot.m_cacheDirty = true;
|
||||
|
||||
if (mxkTransportInit() != MXK_STATUS_OK) {
|
||||
amiDebugLog("Error mxkTransportInit!!");
|
||||
return MXK_STATUS_ERROR;
|
||||
}
|
||||
if (mxkCryptInit() != MXK_STATUS_OK) {
|
||||
amiDebugLog("Error mxkCryptInit!!");
|
||||
return MXK_STATUS_ERROR;
|
||||
}
|
||||
if (mxkExchengeAesKey() != MXK_STATUS_OK) {
|
||||
amiDebugLog("Error mxkExchengeAesKey!!");
|
||||
return MXK_STATUS_ERROR;
|
||||
}
|
||||
// TODO: N2
|
||||
if (mxkSmbusInit() != MXK_STATUS_OK) {
|
||||
amiDebugLog("Error mxkSmbusInit!!");
|
||||
return MXK_STATUS_ERROR;
|
||||
}
|
||||
// TODO: SSD
|
||||
// mxkSsdInit();
|
||||
if (mxkAuthenticationDs() != MXK_STATUS_OK) {
|
||||
amiDebugLog("Error mxkAuthenticationDs!!");
|
||||
return MXK_STATUS_ERROR;
|
||||
}
|
||||
if (mxkGetAppBootInfo() != MXK_STATUS_OK) {
|
||||
amiDebugLog("Error mxkGetAppBootInfo!!");
|
||||
return MXK_STATUS_ERROR;
|
||||
}
|
||||
|
||||
unsigned char system_flag;
|
||||
unsigned char err;
|
||||
if (mxkAbSystemFlag(MXK_CACHE_USE, &system_flag, &err) == MXK_STATUS_OK && system_flag & 1) {
|
||||
// appboot_flash();
|
||||
// eeprom_playcount();
|
||||
}
|
||||
|
||||
// TODO:
|
||||
mxkN2CmdSetDeviceInfo();
|
||||
mxkN2Authentication();
|
||||
|
||||
return MXK_STATUS_OK;
|
||||
}
|
||||
|
@ -1,113 +1,32 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "../ami/ami.h"
|
||||
#include "mxkAb.h"
|
||||
#include "mxkCrypt.h"
|
||||
#include "mxkDefs.h"
|
||||
#include "mxkDs.h"
|
||||
#include "mxkN2.h"
|
||||
#include "mxkPacket.h"
|
||||
#include "mxkSmbus.h"
|
||||
#include "mxkTransport.h"
|
||||
|
||||
extern unsigned char KEY_R[16];
|
||||
extern unsigned char KEY_S[16];
|
||||
extern unsigned char BILLING_PRIVKEY[917];
|
||||
extern unsigned char BILLING_PUBKEY[162];
|
||||
extern unsigned char BILLING_CACERT[817];
|
||||
extern unsigned char KEYCHIP_ID[16];
|
||||
extern unsigned char MAIN_ID[16];
|
||||
|
||||
enum {
|
||||
SetKeyS = 0, // mxkPacketReqSetKeyS [0] [...
|
||||
SetKeyR = 1, // mxkPacketReqSetKeyR [1] [...
|
||||
SetIV = 2, // mxkPacketReqSetIv [2] [...
|
||||
Decrypt = 3, // mxkPacketReqDecrypt [3] [...
|
||||
Encrypt = 4, // mxkPacketReqEncrypt [4] [...
|
||||
GetAppBootInfo = 5, // mxkPacketReqGetAppBootInfo [5] [0] [...
|
||||
EepromWrite = 6, // mxkPacketReqEepromWrite [6] [x] [...
|
||||
EepromRead = 7, // mxkPacketReqEepromRead [7] [x] [...
|
||||
NvramWrite = 8, // mxkPacketReqNvramWrite [8] [x] [x] [y] [...
|
||||
NvramRead = 9, // mxkPacketReqNvramRead [9] [x] [x] [y] [...
|
||||
AddPlayCount = 10, // mxkPacketReqAddPlayCount [10] [...
|
||||
FlashRead = 11, // mxkPacketReqFlashRead [11] [x] [x] [x] [y] [y] [y] [...
|
||||
FlashErase = 12, // mxkPacketReqFlashErase [12] [x] [x] [x] [...
|
||||
KcCmd13 = 13, // mxkPacketReq-13 [13] [x] [x] [x] [...
|
||||
FlashWrite = 14, // mxkPacketReqFlashWrite [14] [x] [x] [x] [y] [y] [y] [...
|
||||
KcCmd15 = 15, //
|
||||
KcCmd16 = 16, //
|
||||
KcCmd17 = 17, //
|
||||
KcCmd18 = 18, //
|
||||
KcCmd19 = 19, //
|
||||
KcGetVersion = 20, // mxkPacketReqGetVersion [20] [...
|
||||
SetMainId = 21, // mxkPacketReqSetMainId [21] [...
|
||||
GetMainId = 22, // mxkPacketReqGetMainId [22] [...
|
||||
SetKeyId = 23, // mxkPacketReqSetKeyId [23] [...
|
||||
GetKeyId = 24, // mxkPacketReqGetKeyId [24] [...
|
||||
GetPlayCounter = 25, // mxkPacketReqGetPlayCounter [25] [...
|
||||
};
|
||||
|
||||
// Structs
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
DWORD crc;
|
||||
DWORD format;
|
||||
char game_id[4];
|
||||
BYTE region;
|
||||
BYTE model_type;
|
||||
BYTE system_flag;
|
||||
BYTE _;
|
||||
char platform_id[3];
|
||||
BYTE dvd_flag;
|
||||
DWORD network_addr;
|
||||
BYTE __[216];
|
||||
BYTE seed[16];
|
||||
} appboot_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
// Crypt
|
||||
void mxkSetKeyS(unsigned char* key_s);
|
||||
void mxkSetKeyR(unsigned char* key_r);
|
||||
void mxkSwapKeys();
|
||||
|
||||
void mxkCryptEncryptAes128CBC(const unsigned char* key, const unsigned char* iv, unsigned char* pt, const unsigned char* ct, size_t nbytes);
|
||||
void mxkCryptDecryptAes128CBC(const unsigned char* key, const unsigned char* iv, const unsigned char* ct, unsigned char* pt, size_t nbytes);
|
||||
|
||||
void mxkCryptEncryptData(unsigned char* ct, const unsigned char* pt);
|
||||
void mxkCryptDecryptData(const unsigned char* ct, unsigned char* pt);
|
||||
|
||||
void mxkSign(void* buffer, size_t nbytes, unsigned char* signature);
|
||||
void mxkSignValue(unsigned int value, unsigned char* signature);
|
||||
|
||||
// Transport
|
||||
static BOOL mxkTransportWaitStrobeReady(HANDLE mxparallel);
|
||||
static BOOL mxkTransportWaitStrobeRelease(HANDLE mxparallel);
|
||||
static void mxkTransportCtrlPortInAndOut(HANDLE mxparallel, BYTE flag);
|
||||
static void mxkTransportCtrlPortInOrOut(HANDLE mxparallel, BYTE flag);
|
||||
|
||||
BOOL mxkTransportSend(HANDLE mxparallel, unsigned char* data, DWORD nbytes);
|
||||
HRESULT mxkTransportRecv(HANDLE mxparallel, unsigned char* data, DWORD nbytes);
|
||||
|
||||
BOOL mxkSendPacket(HANDLE mxparallel, const unsigned char* packet);
|
||||
BOOL mxkRecvPacket(HANDLE mxparallel, unsigned char* packet);
|
||||
void mxkTransportInitPic(HANDLE mxparallel);
|
||||
|
||||
// MXK Packet
|
||||
void mxkPacketReqSetKeyS(unsigned char* packet);
|
||||
void mxkPacketReqSetKeyR(unsigned char* packet);
|
||||
void mxkPacketReqGetAppBootInfo(unsigned char* packet);
|
||||
void mxkPacketReqEepromRead(unsigned char* packet, unsigned char page);
|
||||
void mxkPacketReqGetVersion(unsigned char* packet);
|
||||
void mxkPacketReqSetMainId(unsigned char* packet);
|
||||
void mxkPacketReqGetMainId(unsigned char* packet);
|
||||
void mxkPacketReqGetKeyId(unsigned char* packet);
|
||||
void mxkPacketReqGetPlayCounter(unsigned char* packet);
|
||||
void mxkPacketReqFlashRead(unsigned char* packet, unsigned int address, unsigned int nbytes);
|
||||
void mxkPacketReqNvramRead(unsigned char* packet, unsigned short addr, unsigned char blocks);
|
||||
MXK_STATUS mxkInit(void);
|
||||
MXK_STATUS mxkExchengeAesKey(void);
|
||||
MXK_STATUS mxkVersion(unsigned short* version, MXK_CACHE cache, unsigned char* err);
|
||||
|
||||
// MXK
|
||||
BOOL mxkExchengeAesKey(HANDLE mxparallel);
|
||||
BOOL mxkVersion(HANDLE mxparallel, unsigned short* version);
|
||||
BOOL mxkSetMainId(HANDLE mxparallel, const unsigned char* main_id);
|
||||
BOOL mxkGetMainId(HANDLE mxparallel, unsigned char* main_id);
|
||||
BOOL mxkGetKeyId(HANDLE mxparallel, unsigned char* main_id);
|
||||
BOOL mxkGetAppBootInfo(HANDLE mxparallel, appboot_t* appboot);
|
||||
BOOL mxkGetPlayCounter(HANDLE mxparallel, DWORD* play_counter);
|
||||
BOOL mxkFlashRead(HANDLE mxparallel, unsigned int address, unsigned int nbytes,
|
||||
unsigned char* buffer);
|
||||
BOOL mxkEepromRead(HANDLE mxparallel, unsigned char page, unsigned char* data);
|
||||
BOOL mxkNvramRead(HANDLE mxparallel, unsigned short addr, unsigned char blocks,
|
||||
unsigned char* data);
|
||||
BOOL mxkSetMainId(const unsigned char* main_id);
|
||||
BOOL mxkGetMainId(unsigned char* main_id);
|
||||
BOOL mxkGetKeyId(unsigned char* main_id);
|
||||
BOOL mxkGetPlayCounter(DWORD* play_counter);
|
||||
BOOL mxkFlashRead(unsigned int address, unsigned int nbytes, unsigned char* buffer);
|
||||
BOOL mxkEepromRead(unsigned char page, unsigned char* data);
|
||||
BOOL mxkNvramRead(unsigned short addr, unsigned char blocks, unsigned char* data);
|
||||
|
149
src/micetools/lib/mxk/mxkAb.c
Normal file
149
src/micetools/lib/mxk/mxkAb.c
Normal 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;
|
||||
}
|
35
src/micetools/lib/mxk/mxkAb.h
Normal file
35
src/micetools/lib/mxk/mxkAb.h
Normal 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);
|
@ -1,14 +1,20 @@
|
||||
#include "mxkCrypt.h"
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
#include "mxk.h"
|
||||
|
||||
unsigned char KEY_R[16] = {
|
||||
// These three should be initialised to null, and populated by mxkCryptInit, but we already know
|
||||
// their values and aren't trying to hide them from anyone! mxkCryptInit is still fully implemented,
|
||||
// but is a no-op unless MXK_CRYPT_HAS_INIT is manually set to FALSE.
|
||||
static unsigned char KEY_R[16] = {
|
||||
0x75, 0x6f, 0x72, 0x61, 0x74, 0x6e, 0x65, 0x6b, 0x61, 0x6d, 0x69, 0x68, 0x73, 0x75, 0x6b, 0x75,
|
||||
};
|
||||
unsigned char KEY_S[16] = {
|
||||
static unsigned char KEY_S[16] = {
|
||||
0x66, 0x6E, 0x65, 0x6B, 0x65, 0x72, 0x61, 0x77, 0x64, 0x72, 0x61, 0x68, 0x61, 0x67, 0x65, 0x73,
|
||||
};
|
||||
static unsigned char TRACEDATA_DES_KEY[16] = { 0x4d, 0x77, 0xf1, 0x74, 0x8d, 0x6d, 0x10, 0x94 };
|
||||
BOOL MXK_CRYPT_HAS_INIT = TRUE;
|
||||
|
||||
unsigned char BILLING_PRIVKEY[] =
|
||||
("-----BEGIN PRIVATE KEY-----\n"
|
||||
@ -96,6 +102,48 @@ unsigned char BILLING_CACERT[] = {
|
||||
0xca,
|
||||
};
|
||||
|
||||
MXK_STATUS mxkCryptInit(void) {
|
||||
static unsigned char KEY_HIDDEN[4][16] = { { 0xd8, 0x4f, 0x03, 0x08, 0x48, 0x92, 0xcb, 0x4a,
|
||||
0xfc, 0x47, 0x75, 0x2b, 0xf9, 0xb1, 0x4f, 0x97 },
|
||||
{ 0xbe, 0x21, 0x66, 0x63, 0x2d, 0xe0, 0xaa, 0x3d,
|
||||
0x98, 0x35, 0x14, 0x43, 0x98, 0xd6, 0x2a, 0xe4 },
|
||||
{ 0x07, 0xca, 0x77, 0x01, 0x63, 0x2b, 0x36, 0x60,
|
||||
0xb5, 0x2d, 0x8f, 0x77, 0x41, 0x4e, 0x18, 0x5a },
|
||||
{ 0x72, 0xa5, 0x05, 0x60, 0x17, 0x45, 0x53, 0x0b,
|
||||
0xd4, 0x40, 0xe6, 0x1f, 0x32, 0x3b, 0x73, 0x2f } };
|
||||
|
||||
if (MXK_CRYPT_HAS_INIT) return 0;
|
||||
|
||||
/**
|
||||
* SEGA's loose attempt at hiding the real encryption keys
|
||||
*
|
||||
* static unsigned char KEY_R[16] = {
|
||||
* 0x75, 0x6f, 0x72, 0x61, 0x74, 0x6e, 0x65, 0x6b,
|
||||
* 0x61, 0x6d, 0x69, 0x68, 0x73, 0x75, 0x6b, 0x75,
|
||||
* };
|
||||
* static unsigned char KEY_S[16] = {
|
||||
* 0x66, 0x6E, 0x65, 0x6B, 0x65, 0x72, 0x61, 0x77,
|
||||
* 0x64, 0x72, 0x61, 0x68, 0x61, 0x67, 0x65, 0x73,
|
||||
* };
|
||||
*/
|
||||
for (int i = 0; i < 16; i++) {
|
||||
KEY_R[i] = KEY_HIDDEN[0][i] ^ KEY_HIDDEN[1][i];
|
||||
KEY_S[i] = KEY_HIDDEN[2][i] ^ KEY_HIDDEN[3][i];
|
||||
}
|
||||
|
||||
TRACEDATA_DES_KEY[0] = 0x4d;
|
||||
TRACEDATA_DES_KEY[1] = 0x77;
|
||||
TRACEDATA_DES_KEY[2] = 0xf1;
|
||||
TRACEDATA_DES_KEY[3] = 0x74;
|
||||
TRACEDATA_DES_KEY[4] = 0x8d;
|
||||
TRACEDATA_DES_KEY[5] = 0x6d;
|
||||
TRACEDATA_DES_KEY[6] = 0x10;
|
||||
TRACEDATA_DES_KEY[7] = 0x94;
|
||||
|
||||
MXK_CRYPT_HAS_INIT = TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mxkSetKeyS(unsigned char* key_s) { memcpy(KEY_S, key_s, 16); }
|
||||
void mxkSetKeyR(unsigned char* key_r) { memcpy(KEY_R, key_r, 16); }
|
||||
void mxkSwapKeys() {
|
||||
@ -105,7 +153,13 @@ void mxkSwapKeys() {
|
||||
memcpy(KEY_S, temp, 16);
|
||||
}
|
||||
|
||||
void mxkCryptEncryptAes128CBC(const unsigned char* key, const unsigned char* iv, unsigned char* ct, const unsigned char* pt, size_t nbytes) {
|
||||
MXK_STATUS mxkCryptEncryptAes128CBC(const unsigned char* key, const unsigned char* iv,
|
||||
unsigned char* ct, const unsigned char* pt, size_t nbytes) {
|
||||
if (key == NULL || iv == NULL || ct == NULL || pt == NULL) {
|
||||
amiDebugLog("Error: Invalid param.");
|
||||
return MXK_STATUS_INVALID_PARAM;
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
|
||||
EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv, 1);
|
||||
|
||||
@ -114,9 +168,17 @@ void mxkCryptEncryptAes128CBC(const unsigned char* key, const unsigned char* iv,
|
||||
unsigned char dump[16];
|
||||
EVP_EncryptFinal_ex(ctx, dump, &outl);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
return MXK_STATUS_OK;
|
||||
}
|
||||
|
||||
void mxkCryptDecryptAes128CBC(const unsigned char* key, const unsigned char* iv, const unsigned char* ct, unsigned char* pt, size_t nbytes) {
|
||||
MXK_STATUS mxkCryptDecryptAes128CBC(const unsigned char* key, const unsigned char* iv,
|
||||
const unsigned char* ct, unsigned char* pt, size_t nbytes) {
|
||||
if (key == NULL || iv == NULL || ct == NULL || pt == NULL) {
|
||||
amiDebugLog("Error: Invalid param.");
|
||||
return MXK_STATUS_INVALID_PARAM;
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
|
||||
EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv, 0);
|
||||
|
||||
@ -125,28 +187,52 @@ void mxkCryptDecryptAes128CBC(const unsigned char* key, const unsigned char* iv,
|
||||
unsigned char dump[16];
|
||||
EVP_EncryptFinal_ex(ctx, dump, &outl);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
return MXK_STATUS_OK;
|
||||
}
|
||||
|
||||
void mxkCryptEncryptData(unsigned char* ct, const unsigned char* pt) {
|
||||
MXK_STATUS mxkCryptEncryptData(unsigned char* ct, const unsigned char* pt) {
|
||||
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
|
||||
EVP_CipherInit_ex(ctx, EVP_aes_128_ecb(), NULL, KEY_S, NULL, 1);
|
||||
|
||||
if (!MXK_CRYPT_HAS_INIT) {
|
||||
amiDebugLog("Error no init!!!");
|
||||
return MXK_STATUS_NO_INIT;
|
||||
}
|
||||
if (ct == NULL || pt == NULL) {
|
||||
amiDebugLog("Error invalid param!!!");
|
||||
return MXK_STATUS_INVALID_PARAM;
|
||||
}
|
||||
|
||||
int outl;
|
||||
EVP_EncryptUpdate(ctx, ct, &outl, pt, 16);
|
||||
unsigned char dump[16];
|
||||
EVP_EncryptFinal_ex(ctx, dump, &outl);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
return MXK_STATUS_OK;
|
||||
}
|
||||
|
||||
void mxkCryptDecryptData(const unsigned char* ct, unsigned char* pt) {
|
||||
MXK_STATUS mxkCryptDecryptData(const unsigned char* ct, unsigned char* pt) {
|
||||
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
|
||||
EVP_CipherInit_ex(ctx, EVP_aes_128_ecb(), NULL, KEY_R, NULL, 0);
|
||||
|
||||
if (!MXK_CRYPT_HAS_INIT) {
|
||||
amiDebugLog("Error no init!!!");
|
||||
return MXK_STATUS_NO_INIT;
|
||||
}
|
||||
if (ct == NULL || pt == NULL) {
|
||||
amiDebugLog("Error invalid param!!!");
|
||||
return MXK_STATUS_INVALID_PARAM;
|
||||
}
|
||||
|
||||
int outl;
|
||||
EVP_DecryptUpdate(ctx, pt, &outl, ct, 16);
|
||||
unsigned char dump[16];
|
||||
EVP_EncryptFinal_ex(ctx, dump, &outl);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
return MXK_STATUS_OK;
|
||||
}
|
||||
|
||||
void mxkSign(void* buffer, size_t nbytes, unsigned char* signature) {
|
||||
@ -172,6 +258,8 @@ typedef struct {
|
||||
} sign_payload_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
// TODO: Move this all
|
||||
unsigned char KEYCHIP_ID[16];
|
||||
void mxkSignValue(unsigned int value, unsigned char* signature) {
|
||||
sign_payload_t hash_data;
|
||||
hash_data.value = value;
|
||||
@ -179,3 +267,40 @@ void mxkSignValue(unsigned int value, unsigned char* signature) {
|
||||
memcpy(hash_data.key_high, &KEYCHIP_ID[5], 7);
|
||||
mxkSign(&hash_data, sizeof hash_data, signature);
|
||||
}
|
||||
|
||||
int mxkCryptCalcHashWithHmacSha1(void* key, unsigned char* md, size_t* nbuffer,
|
||||
unsigned char* buffer, size_t nin) {
|
||||
if (key == NULL || buffer == NULL || md == NULL || nbuffer == NULL) {
|
||||
amiDebugLog("Error: Invalid param.");
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (*nbuffer < 20) {
|
||||
amiDebugLog("Error: Datasize is too small.");
|
||||
return 3;
|
||||
}
|
||||
|
||||
// int len = 20;
|
||||
// /* Load the openssl hasher */
|
||||
// EVP_MD *md = FUN_00412e70();
|
||||
// FUN_00415cd0(md, key, len, buffer, nin, md, nbuffer);
|
||||
// return 0;
|
||||
|
||||
HMAC_CTX hmac_ctx;
|
||||
HMAC_CTX_init(&hmac_ctx);
|
||||
HMAC_Init_ex(&hmac_ctx, key, 20, EVP_sha1(), NULL);
|
||||
HMAC_Update(&hmac_ctx, buffer, nin);
|
||||
HMAC_Final(&hmac_ctx, md, nbuffer);
|
||||
HMAC_CTX_cleanup(&hmac_ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mxkCryptCalcHashWithSha1(unsigned char* data, size_t nbytes, unsigned char* sum) {
|
||||
EVP_MD_CTX* ctx = EVP_MD_CTX_create();
|
||||
EVP_DigestInit(ctx, EVP_sha1());
|
||||
EVP_DigestUpdate(ctx, data, nbytes);
|
||||
unsigned int outlen;
|
||||
EVP_DigestFinal_ex(ctx, sum, &outlen);
|
||||
EVP_MD_CTX_destroy(ctx);
|
||||
}
|
29
src/micetools/lib/mxk/mxkCrypt.h
Normal file
29
src/micetools/lib/mxk/mxkCrypt.h
Normal 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);
|
105
src/micetools/lib/mxk/mxkDefs.h
Normal file
105
src/micetools/lib/mxk/mxkDefs.h
Normal 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);
|
269
src/micetools/lib/mxk/mxkDs.c
Normal file
269
src/micetools/lib/mxk/mxkDs.c
Normal 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, ¶m_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;
|
||||
}
|
26
src/micetools/lib/mxk/mxkDs.h
Normal file
26
src/micetools/lib/mxk/mxkDs.h
Normal 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);
|
313
src/micetools/lib/mxk/mxkN2.c
Normal file
313
src/micetools/lib/mxk/mxkN2.c
Normal 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;
|
||||
}
|
25
src/micetools/lib/mxk/mxkN2.h
Normal file
25
src/micetools/lib/mxk/mxkN2.h
Normal 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);
|
@ -1,4 +1,8 @@
|
||||
#include "mxk.h"
|
||||
#include "mxkPacket.h"
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#include "../ami/ami.h"
|
||||
|
||||
void inline _mxkPacketInjectJunk(unsigned char* packet, size_t i) {
|
||||
FILETIME filetime;
|
||||
@ -12,45 +16,64 @@ void inline _mxkPacketInjectJunk(unsigned char* packet, size_t i) {
|
||||
}
|
||||
}
|
||||
|
||||
void mxkPacketReqSetKeyS(unsigned char* packet) {
|
||||
MXK_STATUS mxkPacketReqSetKeyS(unsigned char* packet) {
|
||||
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
|
||||
packet[0] = SetKeyS;
|
||||
_mxkPacketInjectJunk(packet, 1);
|
||||
return MXK_STATUS_OK;
|
||||
}
|
||||
void mxkPacketReqSetKeyR(unsigned char* packet) {
|
||||
MXK_STATUS mxkPacketReqSetKeyR(unsigned char* packet) {
|
||||
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
|
||||
packet[0] = SetKeyR;
|
||||
_mxkPacketInjectJunk(packet, 1);
|
||||
return MXK_STATUS_OK;
|
||||
}
|
||||
void mxkPacketReqGetAppBootInfo(unsigned char* packet) {
|
||||
MXK_STATUS mxkPacketReqGetAppBootInfo(unsigned char* packet) {
|
||||
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
|
||||
packet[0] = GetAppBootInfo;
|
||||
packet[1] = 0;
|
||||
_mxkPacketInjectJunk(packet, 2);
|
||||
return MXK_STATUS_OK;
|
||||
}
|
||||
void mxkPacketReqEepromRead(unsigned char* packet, unsigned char page) {
|
||||
MXK_STATUS mxkPacketReqEepromRead(unsigned char* packet, unsigned char page) {
|
||||
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
|
||||
packet[0] = EepromRead;
|
||||
packet[1] = page;
|
||||
_mxkPacketInjectJunk(packet, 2);
|
||||
return MXK_STATUS_OK;
|
||||
}
|
||||
void mxkPacketReqGetVersion(unsigned char* packet) {
|
||||
MXK_STATUS mxkPacketReqGetVersion(unsigned char* packet) {
|
||||
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
|
||||
packet[0] = KcGetVersion;
|
||||
_mxkPacketInjectJunk(packet, 1);
|
||||
return MXK_STATUS_OK;
|
||||
}
|
||||
void mxkPacketReqSetMainId(unsigned char* packet) {
|
||||
MXK_STATUS mxkPacketReqSetMainId(unsigned char* packet) {
|
||||
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
|
||||
packet[0] = SetMainId;
|
||||
_mxkPacketInjectJunk(packet, 1);
|
||||
return MXK_STATUS_OK;
|
||||
}
|
||||
void mxkPacketReqGetMainId(unsigned char* packet) {
|
||||
MXK_STATUS mxkPacketReqGetMainId(unsigned char* packet) {
|
||||
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
|
||||
packet[0] = GetMainId;
|
||||
_mxkPacketInjectJunk(packet, 1);
|
||||
return MXK_STATUS_OK;
|
||||
}
|
||||
void mxkPacketReqGetKeyId(unsigned char* packet) {
|
||||
MXK_STATUS mxkPacketReqGetKeyId(unsigned char* packet) {
|
||||
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
|
||||
packet[0] = GetKeyId;
|
||||
_mxkPacketInjectJunk(packet, 1);
|
||||
return MXK_STATUS_OK;
|
||||
}
|
||||
void mxkPacketReqGetPlayCounter(unsigned char* packet) {
|
||||
MXK_STATUS mxkPacketReqGetPlayCounter(unsigned char* packet) {
|
||||
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
|
||||
packet[0] = GetPlayCounter;
|
||||
_mxkPacketInjectJunk(packet, 1);
|
||||
return MXK_STATUS_OK;
|
||||
}
|
||||
void mxkPacketReqFlashRead(unsigned char* packet, unsigned int address, unsigned int nbytes) {
|
||||
MXK_STATUS mxkPacketReqFlashRead(unsigned char* packet, unsigned int address, unsigned int nbytes) {
|
||||
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
|
||||
packet[0] = FlashRead;
|
||||
packet[1] = address & 0xff;
|
||||
packet[2] = (address >> 8) & 0xff;
|
||||
@ -59,11 +82,14 @@ void mxkPacketReqFlashRead(unsigned char* packet, unsigned int address, unsigned
|
||||
packet[5] = (nbytes >> 8) & 0xff;
|
||||
packet[6] = (nbytes >> 16) & 0xff;
|
||||
_mxkPacketInjectJunk(packet, 7);
|
||||
return MXK_STATUS_OK;
|
||||
}
|
||||
void mxkPacketReqNvramRead(unsigned char* packet, unsigned short addr, unsigned char blocks) {
|
||||
MXK_STATUS mxkPacketReqNvramRead(unsigned char* packet, unsigned short addr, unsigned char blocks) {
|
||||
if (packet == NULL) return MXK_STATUS_INVALID_PARAM_1;
|
||||
packet[0] = NvramRead;
|
||||
packet[1] = addr & 0xff;
|
||||
packet[2] = (addr >> 8) & 0xff;
|
||||
packet[3] = blocks;
|
||||
_mxkPacketInjectJunk(packet, 4);
|
||||
return MXK_STATUS_OK;
|
||||
}
|
||||
|
13
src/micetools/lib/mxk/mxkPacket.h
Normal file
13
src/micetools/lib/mxk/mxkPacket.h
Normal 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);
|
253
src/micetools/lib/mxk/mxkSmbus.c
Normal file
253
src/micetools/lib/mxk/mxkSmbus.c
Normal 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;
|
||||
}
|
23
src/micetools/lib/mxk/mxkSmbus.h
Normal file
23
src/micetools/lib/mxk/mxkSmbus.h
Normal 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);
|
@ -1,186 +1,374 @@
|
||||
#include "mxkTransport.h"
|
||||
|
||||
#include "../mice/ioctl.h"
|
||||
#include "mxk.h"
|
||||
#include "mxkCrypt.h"
|
||||
|
||||
// TODO: Don't use puts!
|
||||
#include <stdio.h>
|
||||
|
||||
static BOOL mxkTransportWaitStrobeReady(void);
|
||||
static BOOL mxkTransportWaitStrobeRelease(void);
|
||||
static BOOL mxkTransportCtrlPortInAndOut(BYTE flag);
|
||||
static BOOL mxkTransportCtrlPortInOrOut(BYTE flag);
|
||||
static BOOL mxkTransportInitPic(void);
|
||||
|
||||
static struct {
|
||||
BOOL m_bParallelInit;
|
||||
HANDLE m_hParallel;
|
||||
} mxkTransport;
|
||||
|
||||
BOOL DO_SLEEP_0 = TRUE;
|
||||
|
||||
|
||||
#define ReadStatus(mxparallel, status, nret) \
|
||||
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_READ_STATUS, NULL, 0, &status, 1, &nret, NULL);
|
||||
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_READ_STATUS, NULL, 0, &status, 1, &nret, NULL)
|
||||
|
||||
BOOL mxkTransportWaitStrobeReady(HANDLE mxparallel) {
|
||||
static MXK_TRANSPORT_STATUS mxkTransportWaitStrobeReady(void) {
|
||||
BYTE status;
|
||||
DWORD nbytes = 0;
|
||||
|
||||
ReadStatus(mxparallel, status, nbytes);
|
||||
status &= 0x80;
|
||||
if (!ReadStatus(mxkTransport.m_hParallel, status, nbytes)) {
|
||||
amiDebugLog("Error mxkTransportWaitStrobeReady 1");
|
||||
return MXK_TRANSPORT_STATUS_NG;
|
||||
}
|
||||
status &= PARALLEL_STATUS_BUSY;
|
||||
if (status != 0) {
|
||||
ReadStatus(mxparallel, status, nbytes);
|
||||
if ((status & 0x80) != 0) return FALSE;
|
||||
if (!ReadStatus(mxkTransport.m_hParallel, status, nbytes)) {
|
||||
amiDebugLog("Error mxkTransportWaitStrobeReady 2");
|
||||
return MXK_TRANSPORT_STATUS_NG;
|
||||
}
|
||||
if ((status & PARALLEL_STATUS_BUSY) != 0) return MXK_TRANSPORT_STATUS_OK;
|
||||
}
|
||||
return TRUE;
|
||||
return MXK_TRANSPORT_STATUS_BUSY;
|
||||
}
|
||||
|
||||
BOOL mxkTransportWaitStrobeRelease(HANDLE mxparallel) {
|
||||
static MXK_TRANSPORT_STATUS mxkTransportWaitStrobeRelease(void) {
|
||||
BYTE status;
|
||||
DWORD nbytes = 0;
|
||||
|
||||
ReadStatus(mxparallel, status, nbytes);
|
||||
status &= 0x80;
|
||||
if (!ReadStatus(mxkTransport.m_hParallel, status, nbytes)) {
|
||||
amiDebugLog("Error mxkTransportWaitStrobeRelease 1");
|
||||
return MXK_TRANSPORT_STATUS_NG;
|
||||
}
|
||||
status &= PARALLEL_STATUS_BUSY;
|
||||
if (status == 0) {
|
||||
ReadStatus(mxparallel, status, nbytes);
|
||||
if ((status & 0x80) == 0) return FALSE;
|
||||
if (!ReadStatus(mxkTransport.m_hParallel, status, nbytes)) {
|
||||
amiDebugLog("Error mxkTransportWaitStrobeRelease 2");
|
||||
return MXK_TRANSPORT_STATUS_NG;
|
||||
}
|
||||
if ((status & PARALLEL_STATUS_BUSY) == 0) return MXK_TRANSPORT_STATUS_OK;
|
||||
}
|
||||
return MXK_TRANSPORT_STATUS_BUSY;
|
||||
}
|
||||
|
||||
static BOOL mxkTransportCtrlPortInAndOut(BYTE flag) {
|
||||
BYTE ctrl;
|
||||
DWORD nbytes = 0;
|
||||
if (!DeviceIoControl(mxkTransport.m_hParallel, IOCTL_MXPARALLEL_READ_CTRL_PORT, NULL, 0, &ctrl,
|
||||
1, &nbytes, NULL)) {
|
||||
amiDebugLog("Error mxkTransportCtrlPortInAndOut 1");
|
||||
return FALSE;
|
||||
}
|
||||
ctrl &= flag;
|
||||
if (!DeviceIoControl(mxkTransport.m_hParallel, IOCTL_MXPARALLEL_WRITE_CTRL_PORT, &ctrl, 1, NULL,
|
||||
0, &nbytes, NULL)) {
|
||||
amiDebugLog("Error mxkTransportCtrlPortInAndOut 2");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void mxkTransportCtrlPortInAndOut(HANDLE mxparallel, BYTE flag) {
|
||||
static BOOL mxkTransportCtrlPortInOrOut(BYTE flag) {
|
||||
BYTE ctrl;
|
||||
DWORD nbytes = 0;
|
||||
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_READ_CTRL_PORT, NULL, 0, &ctrl, 1, &nbytes, NULL);
|
||||
ctrl &= flag;
|
||||
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_WRITE_CTRL_PORT, &ctrl, 1, NULL, 0, &nbytes, NULL);
|
||||
}
|
||||
|
||||
void mxkTransportCtrlPortInOrOut(HANDLE mxparallel, BYTE flag) {
|
||||
BYTE ctrl;
|
||||
DWORD nbytes = 0;
|
||||
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_READ_CTRL_PORT, NULL, 0, &ctrl, 1, &nbytes, NULL);
|
||||
if (!DeviceIoControl(mxkTransport.m_hParallel, IOCTL_MXPARALLEL_READ_CTRL_PORT, NULL, 0, &ctrl,
|
||||
1, &nbytes, NULL)) {
|
||||
amiDebugLog("Error mxkTransportCtrlPortInOrOut 1");
|
||||
return FALSE;
|
||||
}
|
||||
ctrl |= flag;
|
||||
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_WRITE_CTRL_PORT, &ctrl, 1, NULL, 0, &nbytes, NULL);
|
||||
if (!DeviceIoControl(mxkTransport.m_hParallel, IOCTL_MXPARALLEL_WRITE_CTRL_PORT, &ctrl, 1, NULL,
|
||||
0, &nbytes, NULL)) {
|
||||
amiDebugLog("Error mxkTransportCtrlPortInOrOut 2");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL mxkTransportSend(HANDLE mxparallel, unsigned char *data, DWORD nbytes) {
|
||||
MXK_TRANSPORT_STATUS mxkTransportSend(unsigned char *data, DWORD nbytes) {
|
||||
DWORD nret;
|
||||
BYTE status;
|
||||
MXK_TRANSPORT_STATUS err;
|
||||
|
||||
amtime_t start;
|
||||
amtime_t now;
|
||||
|
||||
if (!mxkTransport.m_bParallelInit) return MXK_TRANSPORT_STATUS_NO_INIT;
|
||||
if (nbytes == 0) return MXK_TRANSPORT_STATUS_OK;
|
||||
|
||||
for (size_t i = 0; i < nbytes; i++) {
|
||||
amiTimerGet(&start);
|
||||
do {
|
||||
ReadStatus(mxparallel, status, nret);
|
||||
status &= 0x40;
|
||||
if (!ReadStatus(mxkTransport.m_hParallel, status, nret)) {
|
||||
amiDebugLog("Error mxkTransportSend 1");
|
||||
return MXK_TRANSPORT_STATUS_SEND_NG;
|
||||
}
|
||||
status &= PARALLEL_STATUS_ACK;
|
||||
if (status == 0) break;
|
||||
amiTimerGet(&now);
|
||||
if (DO_SLEEP_0) Sleep(0);
|
||||
} while (amiTimerDiffUsec(&start, &now) < 1000000);
|
||||
|
||||
if (status != 0) {
|
||||
puts("SEND busy error");
|
||||
return FALSE;
|
||||
amiDebugLog("SEND busy error");
|
||||
return MXK_TRANSPORT_STATUS_SEND_NG;
|
||||
}
|
||||
|
||||
while (mxkTransportWaitStrobeRelease(mxparallel)) {
|
||||
while (1) {
|
||||
err = mxkTransportWaitStrobeRelease();
|
||||
if (err == MXK_TRANSPORT_STATUS_OK) break;
|
||||
if (err == MXK_TRANSPORT_STATUS_NG) {
|
||||
amiDebugLog("Error mxkTransportSend 2");
|
||||
return MXK_TRANSPORT_STATUS_SEND_NG;
|
||||
}
|
||||
amiTimerGet(&now);
|
||||
if (DO_SLEEP_0) Sleep(0);
|
||||
if (amiTimerDiffUsec(&start, &now) > 999999) {
|
||||
puts("SEND busy error");
|
||||
return FALSE;
|
||||
amiDebugLog("state_busy != 0 // timeout?");
|
||||
return MXK_TRANSPORT_STATUS_SEND_NG;
|
||||
}
|
||||
}
|
||||
|
||||
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_WRITE_DATA, &data[i], 1, NULL, 0, &nret, NULL);
|
||||
if (!DeviceIoControl(mxkTransport.m_hParallel, IOCTL_MXPARALLEL_WRITE_DATA, &data[i], 1,
|
||||
NULL, 0, &nret, NULL)) {
|
||||
amiDebugLog("Error mxkTransportSend 3");
|
||||
return MXK_TRANSPORT_STATUS_SEND_NG;
|
||||
}
|
||||
|
||||
mxkTransportCtrlPortInAndOut(mxparallel, 0xdf);
|
||||
mxkTransportCtrlPortInOrOut(mxparallel, 0x01);
|
||||
if (!mxkTransportCtrlPortInAndOut(~PARALLEL_CONTROL_BIDI & 0xff)) {
|
||||
amiDebugLog("Error mxkTransportSend 4");
|
||||
return MXK_TRANSPORT_STATUS_SEND_NG;
|
||||
}
|
||||
if (!mxkTransportCtrlPortInOrOut(PARALLEL_CONTROL_STROBE)) {
|
||||
amiDebugLog("Error mxkTransportSend 5");
|
||||
return MXK_TRANSPORT_STATUS_SEND_NG;
|
||||
}
|
||||
|
||||
while (mxkTransportWaitStrobeReady(mxparallel)) {
|
||||
while (1) {
|
||||
err = mxkTransportWaitStrobeReady();
|
||||
if (err == MXK_TRANSPORT_STATUS_OK) break;
|
||||
if (err == MXK_TRANSPORT_STATUS_NG) {
|
||||
amiDebugLog("Error mxkTransportSend 6");
|
||||
return MXK_TRANSPORT_STATUS_SEND_NG;
|
||||
}
|
||||
amiTimerGet(&now);
|
||||
if (DO_SLEEP_0) Sleep(0);
|
||||
if (amiTimerDiffUsec(&start, &now) > 999999'000) {
|
||||
puts("SEND end error");
|
||||
return FALSE;
|
||||
amiDebugLog("RA1が1でエラー");
|
||||
return MXK_TRANSPORT_STATUS_SEND_NG;
|
||||
}
|
||||
}
|
||||
|
||||
mxkTransportCtrlPortInOrOut(mxparallel, 0x20);
|
||||
mxkTransportCtrlPortInAndOut(mxparallel, 0xfe);
|
||||
if (!mxkTransportCtrlPortInOrOut(PARALLEL_CONTROL_BIDI)) {
|
||||
amiDebugLog("Error mxkTransportSend 7");
|
||||
return MXK_TRANSPORT_STATUS_SEND_NG;
|
||||
}
|
||||
if (!mxkTransportCtrlPortInAndOut(~PARALLEL_CONTROL_STROBE & 0xff)) {
|
||||
amiDebugLog("Error mxkTransportSend 8");
|
||||
return MXK_TRANSPORT_STATUS_SEND_NG;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
return MXK_TRANSPORT_STATUS_OK;
|
||||
}
|
||||
|
||||
HRESULT mxkTransportRecv(HANDLE mxparallel, unsigned char *data, DWORD nbytes) {
|
||||
MXK_TRANSPORT_STATUS mxkTransportRecv(unsigned char *data, DWORD nbytes) {
|
||||
BYTE status;
|
||||
DWORD nret;
|
||||
MXK_TRANSPORT_STATUS err;
|
||||
|
||||
amtime_t now;
|
||||
amtime_t start;
|
||||
|
||||
if (!mxkTransport.m_bParallelInit) return MXK_TRANSPORT_STATUS_NO_INIT;
|
||||
if (nbytes == 0) return MXK_TRANSPORT_STATUS_OK;
|
||||
|
||||
for (size_t i = 0; i < nbytes; i++) {
|
||||
amiTimerGet(&start);
|
||||
do {
|
||||
ReadStatus(mxparallel, status, nret);
|
||||
status &= 0x40;
|
||||
if (!ReadStatus(mxkTransport.m_hParallel, status, nret)) {
|
||||
amiDebugLog("Error mxkTransportRecv 1");
|
||||
return MXK_TRANSPORT_STATUS_RECV_NG;
|
||||
}
|
||||
status &= PARALLEL_STATUS_ACK;
|
||||
if (status != 0) break;
|
||||
amiTimerGet(&now);
|
||||
if (DO_SLEEP_0 != 0) Sleep(0);
|
||||
} while (amiTimerDiffUsec(&start, &now) < 1000000'000);
|
||||
} while (amiTimerDiffUsec(&start, &now) < 1000000);
|
||||
|
||||
if (status == 0) {
|
||||
puts("RECV busy error 1");
|
||||
return FALSE;
|
||||
amiDebugLog("RECV busy error 1");
|
||||
return MXK_TRANSPORT_STATUS_RECV_NG;
|
||||
}
|
||||
|
||||
while (mxkTransportWaitStrobeReady(mxparallel)) {
|
||||
while (1) {
|
||||
err = mxkTransportWaitStrobeReady();
|
||||
if (err == MXK_TRANSPORT_STATUS_OK) break;
|
||||
if (err == MXK_TRANSPORT_STATUS_NG) {
|
||||
amiDebugLog("Error mxkTransportRecv 2");
|
||||
return MXK_TRANSPORT_STATUS_RECV_NG;
|
||||
}
|
||||
amiTimerGet(&now);
|
||||
if (DO_SLEEP_0 != 0) Sleep(0);
|
||||
|
||||
if (amiTimerDiffUsec(&start, &now) > 999999'000) {
|
||||
puts("RECV busy error 2");
|
||||
return FALSE;
|
||||
if (amiTimerDiffUsec(&start, &now) > 999999) {
|
||||
amiDebugLog("RECV busy error 2");
|
||||
return MXK_TRANSPORT_STATUS_RECV_NG;
|
||||
}
|
||||
}
|
||||
|
||||
mxkTransportCtrlPortInOrOut(mxparallel, 0x20);
|
||||
mxkTransportCtrlPortInOrOut(mxparallel, 0x01);
|
||||
if (!mxkTransportCtrlPortInOrOut(PARALLEL_CONTROL_BIDI)) {
|
||||
amiDebugLog("Error mxkTransportRecv 3");
|
||||
return MXK_TRANSPORT_STATUS_RECV_NG;
|
||||
}
|
||||
if (!mxkTransportCtrlPortInOrOut(PARALLEL_CONTROL_STROBE)) {
|
||||
amiDebugLog("Error mxkTransportRecv 4");
|
||||
return MXK_TRANSPORT_STATUS_RECV_NG;
|
||||
}
|
||||
|
||||
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_READ_DATA, NULL, 0, &data[i], 1, &nret, NULL);
|
||||
if (!DeviceIoControl(mxkTransport.m_hParallel, IOCTL_MXPARALLEL_READ_DATA, NULL, 0,
|
||||
&data[i], 1, &nret, NULL)) {
|
||||
amiDebugLog("Error mxkTransportRecv 5");
|
||||
return MXK_TRANSPORT_STATUS_RECV_NG;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
err = mxkTransportWaitStrobeRelease();
|
||||
if (err == MXK_TRANSPORT_STATUS_OK) break;
|
||||
if (err == MXK_TRANSPORT_STATUS_NG) {
|
||||
amiDebugLog("Error mxkTransportRecv 6");
|
||||
return MXK_TRANSPORT_STATUS_RECV_NG;
|
||||
}
|
||||
|
||||
while (mxkTransportWaitStrobeRelease(mxparallel)) {
|
||||
amiTimerGet(&now);
|
||||
if (DO_SLEEP_0) Sleep(0);
|
||||
if (amiTimerDiffUsec(&start, &now) > 999999) {
|
||||
puts("RECV end error");
|
||||
return FALSE;
|
||||
amiDebugLog("RECV end error");
|
||||
return MXK_TRANSPORT_STATUS_RECV_NG;
|
||||
}
|
||||
}
|
||||
mxkTransportCtrlPortInAndOut(mxparallel, 0xfe);
|
||||
if (!mxkTransportCtrlPortInAndOut(~PARALLEL_CONTROL_STROBE & 0xff)) {
|
||||
amiDebugLog("Error mxkTransportRecv 7");
|
||||
return MXK_TRANSPORT_STATUS_RECV_NG;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
return MXK_TRANSPORT_STATUS_OK;
|
||||
}
|
||||
|
||||
BOOL mxkSendPacket(HANDLE mxparallel, const unsigned char *packet) {
|
||||
unsigned char encrypted[16];
|
||||
ZeroMemory(encrypted, 16);
|
||||
mxkCryptEncryptData(encrypted, packet);
|
||||
return mxkTransportSend(mxparallel, encrypted, 0x10);
|
||||
}
|
||||
|
||||
BOOL mxkRecvPacket(HANDLE mxparallel, unsigned char *packet) {
|
||||
unsigned char encrypted[16];
|
||||
if (!mxkTransportRecv(mxparallel, encrypted, 0x10)) return FALSE;
|
||||
mxkCryptDecryptData(encrypted, packet);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void mxkTransportInitPic(HANDLE mxparallel) {
|
||||
static BOOL mxkTransportInitPic(void) {
|
||||
BYTE flags = 0;
|
||||
DWORD nbytes = 0;
|
||||
Sleep(10);
|
||||
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_READ_FLAGS, NULL, 0, &flags, 1, &nbytes, NULL);
|
||||
flags = flags & 0x1f | 0x20;
|
||||
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_WRITE_FLAGS, &flags, 1, NULL, 0, &nbytes, NULL);
|
||||
if (!DeviceIoControl(mxkTransport.m_hParallel, IOCTL_MXPARALLEL_READ_FLAGS, NULL, 0, &flags, 1,
|
||||
&nbytes, NULL)) {
|
||||
amiDebugLog("Error KeychipInit 1");
|
||||
return FALSE;
|
||||
}
|
||||
flags = (flags & 0b11111) | (PARALLEL_EC_MODE_BYTE << 5);
|
||||
if (!DeviceIoControl(mxkTransport.m_hParallel, IOCTL_MXPARALLEL_WRITE_FLAGS, &flags, 1, NULL, 0,
|
||||
&nbytes, NULL)) {
|
||||
amiDebugLog("Error KeychipInit 2");
|
||||
return FALSE;
|
||||
}
|
||||
Sleep(10);
|
||||
flags = 0x24;
|
||||
DeviceIoControl(mxparallel, IOCTL_MXPARALLEL_WRITE_CTRL_PORT, &flags, 1, NULL, 0, &nbytes,
|
||||
NULL);
|
||||
flags = PARALLEL_CONTROL_BIDI | PARALLEL_CONTROL_INITIALISE;
|
||||
if (!DeviceIoControl(mxkTransport.m_hParallel, IOCTL_MXPARALLEL_WRITE_CTRL_PORT, &flags, 1,
|
||||
NULL, 0, &nbytes, NULL)) {
|
||||
amiDebugLog("Error KeychipInit 3");
|
||||
return FALSE;
|
||||
}
|
||||
Sleep(10);
|
||||
mxkTransportCtrlPortInAndOut(mxparallel, 0xfb);
|
||||
if (!mxkTransportCtrlPortInAndOut(~PARALLEL_CONTROL_INITIALISE & 0xff)) {
|
||||
amiDebugLog("Error KeychipInit 4");
|
||||
return FALSE;
|
||||
}
|
||||
Sleep(10);
|
||||
mxkTransportCtrlPortInOrOut(mxparallel, 0x24);
|
||||
if (!mxkTransportCtrlPortInOrOut(PARALLEL_CONTROL_BIDI | PARALLEL_CONTROL_INITIALISE)) {
|
||||
amiDebugLog("Error KeychipInit 5");
|
||||
return FALSE;
|
||||
}
|
||||
Sleep(10);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
MXK_TRANSPORT_STATUS mxkTransportInit(void) {
|
||||
amtime_t start;
|
||||
amtime_t now;
|
||||
|
||||
if (mxkTransport.m_bParallelInit) return 0;
|
||||
|
||||
amiTimerGet(&start);
|
||||
do {
|
||||
mxkTransport.m_hParallel =
|
||||
CreateFileA("\\\\.\\mxparallel", GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (mxkTransport.m_hParallel != INVALID_HANDLE_VALUE) break;
|
||||
amiTimerGet(&now);
|
||||
Sleep(500);
|
||||
} while (amiTimerDiffSec(&start, &now) < 10);
|
||||
|
||||
if (mxkTransport.m_hParallel == INVALID_HANDLE_VALUE) {
|
||||
amiDebugLog("Error Timeout CreateFile MxParallel");
|
||||
return MXK_TRANSPORT_STATUS_NG;
|
||||
}
|
||||
|
||||
if (!mxkTransportInitPic()) {
|
||||
amiDebugLog("Error InitPic()");
|
||||
return MXK_TRANSPORT_STATUS_NG;
|
||||
}
|
||||
DO_SLEEP_0 = 1;
|
||||
mxkTransport.m_bParallelInit = 1;
|
||||
return MXK_TRANSPORT_STATUS_OK;
|
||||
}
|
||||
|
||||
MXK_STATUS mxkSendPacket(const unsigned char *packet) {
|
||||
unsigned char encrypted[MXK_BLOCK_SIZE];
|
||||
|
||||
if (packet == NULL) {
|
||||
amiDebugLog("Error invalid param!!!");
|
||||
return MXK_STATUS_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ZeroMemory(encrypted, sizeof encrypted);
|
||||
mxkCryptEncryptData(encrypted, packet);
|
||||
if (0) { // TODO: if (mxkCryptEncryptData() != 0)
|
||||
int err = 0;
|
||||
amiDebugLog("Error mxkCryptEncryptData(), %d", err);
|
||||
return MXK_STATUS_CRYPT_NG;
|
||||
}
|
||||
MXK_TRANSPORT_STATUS status = mxkTransportSend(encrypted, MXK_BLOCK_SIZE);
|
||||
if (status != MXK_TRANSPORT_STATUS_OK) return MXK_STATUS_SEND_NG;
|
||||
return MXK_STATUS_OK;
|
||||
}
|
||||
|
||||
MXK_STATUS mxkRecvPacket(unsigned char *packet) {
|
||||
unsigned char encrypted[MXK_BLOCK_SIZE];
|
||||
|
||||
if (packet == NULL) {
|
||||
amiDebugLog("Error invalid param!!!");
|
||||
return MXK_STATUS_INVALID_PARAM;
|
||||
}
|
||||
|
||||
MXK_TRANSPORT_STATUS status = mxkTransportRecv(encrypted, MXK_BLOCK_SIZE);
|
||||
if (status != MXK_TRANSPORT_STATUS_OK) {
|
||||
amiDebugLog("Error mxkTransportRecv(), %d", status);
|
||||
return MXK_STATUS_RECV_NG;
|
||||
}
|
||||
|
||||
ZeroMemory(packet, MXK_BLOCK_SIZE);
|
||||
mxkCryptDecryptData(encrypted, packet);
|
||||
if (0) { // TODO: if (mxkCryptDecryptData() != 0)
|
||||
int err = 0;
|
||||
amiDebugLog("Error mxkCryptDecryptData(), %d", err);
|
||||
return MXK_STATUS_CRYPT_NG;
|
||||
}
|
||||
return MXK_STATUS_OK;
|
||||
}
|
||||
|
12
src/micetools/lib/mxk/mxkTransport.h
Normal file
12
src/micetools/lib/mxk/mxkTransport.h
Normal 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);
|
@ -1,5 +1,6 @@
|
||||
subdir('lib')
|
||||
|
||||
subdir('system_dummy')
|
||||
subdir('micepatch')
|
||||
subdir('micekeychip')
|
||||
subdir('micemaster')
|
||||
|
@ -36,13 +36,12 @@ void log_callback(struct pcpa* stream, void* data) {
|
||||
e_pcpa_t mxkPcpStreamInit() {
|
||||
e_pcpa_t err;
|
||||
|
||||
PCP.before_cb = log_callback;
|
||||
|
||||
err = pcpaInitStream(&PCP);
|
||||
if (err != e_pcpa_ok) {
|
||||
printf("pcpaInitStream Error. Code:%d\n", err);
|
||||
return err;
|
||||
}
|
||||
PCP.before_cb = log_callback;
|
||||
|
||||
err = pcpaSetCallbackFuncBuffer(
|
||||
&PCP, CALLBACK_FUNCTION_BUFFER,
|
||||
|
@ -4,6 +4,8 @@ pcpa_callback mxkBinaryCallback;
|
||||
extern byte BINARY_DATA[4096];
|
||||
extern size_t BINARY_DATA_LEN;
|
||||
|
||||
#define MXM_NUM_CALLBACKS 11
|
||||
|
||||
#define MXMASTER "mxmaster."
|
||||
#define FOREGROUND MXMASTER##"foreground."
|
||||
|
||||
|
@ -43,7 +43,7 @@ typedef struct MX_MASTER_ {
|
||||
bool m_kcReady;
|
||||
bool m_pcpaHasInit;
|
||||
appLauncher_t* m_appLauncher;
|
||||
pcpa_cb_table_t m_pcpCallbacks[11];
|
||||
pcpa_cb_table_t m_pcpCallbacks[MXM_NUM_CALLBACKS];
|
||||
pcpa_t m_pcp;
|
||||
|
||||
} MX_MASTER;
|
||||
|
6
src/micetools/system_dummy/README.md
Normal file
6
src/micetools/system_dummy/README.md
Normal 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.
|
88
src/micetools/system_dummy/dummyinstaller/dummyinstaller.c
Normal file
88
src/micetools/system_dummy/dummyinstaller/dummyinstaller.c
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
void miceDummyInstaller(unsigned short textPort, unsigned short binaryPort, bool global);
|
3
src/micetools/system_dummy/dummyinstaller/main.c
Normal file
3
src/micetools/system_dummy/dummyinstaller/main.c
Normal file
@ -0,0 +1,3 @@
|
||||
#include "dummyinstaller.h"
|
||||
|
||||
int main() { miceDummyInstaller(40102, 40103, false); }
|
18
src/micetools/system_dummy/dummyinstaller/meson.build
Normal file
18
src/micetools/system_dummy/dummyinstaller/meson.build
Normal 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,
|
||||
)
|
38
src/micetools/system_dummy/dummymaster/callbacks.h
Normal file
38
src/micetools/system_dummy/dummymaster/callbacks.h
Normal 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;
|
123
src/micetools/system_dummy/dummymaster/dummymaster.c
Normal file
123
src/micetools/system_dummy/dummymaster/dummymaster.c
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
3
src/micetools/system_dummy/dummymaster/dummymaster.h
Normal file
3
src/micetools/system_dummy/dummymaster/dummymaster.h
Normal file
@ -0,0 +1,3 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
void miceDummyMaster(unsigned short textPort, unsigned short binaryPort, bool global);
|
3
src/micetools/system_dummy/dummymaster/main.c
Normal file
3
src/micetools/system_dummy/dummymaster/main.c
Normal file
@ -0,0 +1,3 @@
|
||||
#include "dummymaster.h"
|
||||
|
||||
int main() { miceDummyMaster(40100, 40101, false); }
|
18
src/micetools/system_dummy/dummymaster/meson.build
Normal file
18
src/micetools/system_dummy/dummymaster/meson.build
Normal 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,
|
||||
)
|
2
src/micetools/system_dummy/meson.build
Normal file
2
src/micetools/system_dummy/meson.build
Normal file
@ -0,0 +1,2 @@
|
||||
subdir('dummymaster')
|
||||
subdir('dummyinstaller')
|
@ -7,7 +7,7 @@ executable(
|
||||
'micedump/eeprom.c',
|
||||
'micedump/kc_mxkeychip.c',
|
||||
# 'micedump/kc_n2.c',
|
||||
# 'micedump/kc_pic.c',
|
||||
'micedump/kc_pic.c',
|
||||
'micedump/platform.c',
|
||||
'micedump/sram.c',
|
||||
# 'micedump/superio.c',
|
||||
|
@ -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);
|
||||
}
|
@ -15,6 +15,8 @@ int main(int argc, char** argv) {
|
||||
miceDumpSRAM();
|
||||
else if (strcmp(argv[i], "dongle") == 0)
|
||||
miceDumpKCMxkeychip();
|
||||
else if (strcmp(argv[i], "kcpic") == 0)
|
||||
miceDumpKCPIC();
|
||||
else
|
||||
printf("Unknown dump type: %s\n", argv[i]);
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
#include <stdio.h>
|
||||
#include <Windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
char path[MAX_PATH * 1000];
|
||||
int main(int argc, char** argv) {
|
||||
int oldmain(int argc, char** argv) {
|
||||
// printf("%d", QueryDosDeviceA(NULL, path, sizeof path));
|
||||
// printf(" %03x\n", GetLastError());
|
||||
|
||||
@ -17,33 +18,17 @@ int main(int argc, char** argv) {
|
||||
DWORD volumeSerialNumber;
|
||||
|
||||
// Crackproof-style call
|
||||
BOOL ret = GetVolumeInformationA(
|
||||
"C:\\",
|
||||
NULL,
|
||||
0,
|
||||
&volumeSerialNumber,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0
|
||||
);
|
||||
printf("volumeSerialNumber: %08x\n");
|
||||
BOOL ret = GetVolumeInformationA("C:\\", NULL, 0, &volumeSerialNumber, NULL, NULL, NULL, 0);
|
||||
printf("volumeSerialNumber: %08x\n", volumeSerialNumber);
|
||||
|
||||
// Exhaustive call
|
||||
CHAR volumeNameBuffer[MAX_PATH];
|
||||
DWORD maximumComponentLength;
|
||||
DWORD fileSystemFlags;
|
||||
CHAR fileSystemName[MAX_PATH];
|
||||
ret = GetVolumeInformationA(
|
||||
"C:\\",
|
||||
volumeNameBuffer,
|
||||
sizeof volumeNameBuffer,
|
||||
&volumeSerialNumber,
|
||||
&maximumComponentLength,
|
||||
&fileSystemFlags,
|
||||
fileSystemName,
|
||||
sizeof fileSystemName
|
||||
);
|
||||
ret = GetVolumeInformationA("C:\\", volumeNameBuffer, sizeof volumeNameBuffer,
|
||||
&volumeSerialNumber, &maximumComponentLength, &fileSystemFlags,
|
||||
fileSystemName, sizeof fileSystemName);
|
||||
|
||||
printf("volumeNameBuffer: %s\n", volumeNameBuffer);
|
||||
printf("volumeSerialNumber: %08x\n", volumeSerialNumber);
|
||||
@ -52,4 +37,44 @@ int main(int argc, char** argv) {
|
||||
printf("fileSystemName: %s\n", fileSystemName);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#define RING
|
||||
|
||||
#ifdef RING
|
||||
#define A2P \
|
||||
"C:\\Documents and Settings\\All Users\\Application Data/boost_interprocess/ALLNetComA2P"
|
||||
#else
|
||||
#define A2P "G:\\MegaSync\\SDEY_1.99\\maimai\\dev\\c\\ProgramData/boost_interprocess/ALLNetComA2P"
|
||||
#endif
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
unsigned char buf[1];
|
||||
char buf2[4];
|
||||
DWORD temp;
|
||||
|
||||
HANDLE hFile = CreateFileA(A2P, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
printf("Failed to open A2P %03x\n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
SetFilePointer(hFile, 4, NULL, 0);
|
||||
buf[0] = '\1';
|
||||
WriteFile(hFile, buf, sizeof buf, &temp, NULL);
|
||||
|
||||
// buf[0] = '\2'; // game start
|
||||
buf[0] = '\3'; // game test
|
||||
SetFilePointer(hFile, 0, NULL, 0);
|
||||
WriteFile(hFile, buf, sizeof buf, &temp, NULL);
|
||||
|
||||
SetFilePointer(hFile, 8, NULL, 0);
|
||||
buf2[0] = '1';
|
||||
buf2[0] = '.';
|
||||
buf2[0] = '9';
|
||||
buf2[0] = '9';
|
||||
WriteFile(hFile, buf2, sizeof buf2, &temp, NULL);
|
||||
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user