From 8a3d1e80bbc3871f9f5b34e1778937105ff90040 Mon Sep 17 00:00:00 2001 From: Bottersnike Date: Tue, 28 Mar 2023 21:08:02 +0100 Subject: [PATCH] More intense service dummies --- Makefile | 2 + src/micetools/dll/devices/_devices.c | 1 + src/micetools/dll/devices/_devices.h | 1 + src/micetools/dll/devices/meson.build | 1 + .../dll/devices/ser_servo_838-15069.c | 82 +++ src/micetools/dll/dllmain.c | 23 - src/micetools/dll/drivers/columba.c | 6 +- src/micetools/dll/drivers/mxjvs.c | 242 +-------- src/micetools/dll/drivers/mxsram.c | 6 +- src/micetools/dll/games.c | 12 +- src/micetools/dll/hooks/drive/hooks.c | 20 +- src/micetools/dll/hooks/drive/irb.h | 2 + src/micetools/dll/hooks/drive/physicalDrive.c | 4 +- src/micetools/dll/hooks/logging.c | 1 + src/micetools/dll/hooks/network.c | 5 +- src/micetools/dll/hooks/setupapi.c | 4 +- src/micetools/dll/meson.build | 5 - src/micetools/dll/util/_util.h | 1 - src/micetools/dll/util/hook.c | 11 +- src/micetools/launcher/main.c | 102 ++-- src/micetools/launcher/meson.build | 8 + src/micetools/launcher/spawn.c | 63 +++ src/micetools/launcher/spawn.h | 22 + src/micetools/lib/libpcp/meson.build | 1 + src/micetools/lib/libpcp/pcp.h | 1 - src/micetools/lib/libpcp/pcpa.c | 94 ++-- src/micetools/lib/libpcp/pcpa.h | 2 +- src/micetools/lib/libpcp/pcpp.c | 132 ++--- src/micetools/lib/libpcp/pcpt.c | 46 +- src/micetools/lib/mice/config.def | 2 + src/micetools/{dll/util => lib/mice}/log.c | 473 +++++++++--------- src/micetools/{dll/util => lib/mice}/log.h | 160 +++--- .../{dll/util => lib/mice}/log_facilities.def | 1 + src/micetools/lib/mice/meson.build | 1 + src/micetools/lib/mice/mice.h | 3 +- src/micetools/lib/mxk/mxkAb.c | 2 +- .../micekeychip/callbacks/callbacks.h | 2 +- src/micetools/micekeychip/callbacks/crypto.c | 2 +- src/micetools/micekeychip/config.c | 87 ++++ src/micetools/micekeychip/config.def | 2 +- src/micetools/micekeychip/config.h | 3 + src/micetools/micekeychip/main.c | 101 ---- src/micetools/micekeychip/meson.build | 4 +- src/micetools/micekeychip/mxk.c | 47 +- src/micetools/micekeychip/mxk.h | 1 + .../dummykeychip/callbacks-crypto.c | 100 ++++ .../dummykeychip/callbacks-stub.c | 53 ++ .../system_dummy/dummykeychip/callbacks.h | 94 ++++ .../system_dummy/dummykeychip/dummykeychip.c | 118 +++++ .../system_dummy/dummykeychip/dummykeychip.h | 3 + .../system_dummy/dummykeychip/main.c | 3 + .../system_dummy/dummykeychip/meson.build | 22 + src/micetools/system_dummy/meson.build | 1 + src/micetools/util/meson.build | 10 + src/micetools/util/micegbdisk.c | 388 ++++++++++++++ 55 files changed, 1671 insertions(+), 912 deletions(-) create mode 100644 src/micetools/dll/devices/ser_servo_838-15069.c create mode 100644 src/micetools/launcher/spawn.c create mode 100644 src/micetools/launcher/spawn.h rename src/micetools/{dll/util => lib/mice}/log.c (83%) rename src/micetools/{dll/util => lib/mice}/log.h (96%) rename src/micetools/{dll/util => lib/mice}/log_facilities.def (96%) create mode 100644 src/micetools/micekeychip/config.c create mode 100644 src/micetools/system_dummy/dummykeychip/callbacks-crypto.c create mode 100644 src/micetools/system_dummy/dummykeychip/callbacks-stub.c create mode 100644 src/micetools/system_dummy/dummykeychip/callbacks.h create mode 100644 src/micetools/system_dummy/dummykeychip/dummykeychip.c create mode 100644 src/micetools/system_dummy/dummykeychip/dummykeychip.h create mode 100644 src/micetools/system_dummy/dummykeychip/main.c create mode 100644 src/micetools/system_dummy/dummykeychip/meson.build create mode 100644 src/micetools/util/micegbdisk.c diff --git a/Makefile b/Makefile index 56619cc..5ac5516 100644 --- a/Makefile +++ b/Makefile @@ -61,9 +61,11 @@ dist: @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/util\micegbdisk.exe" "$(DIST_DIR)/util/micegbdisk.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 "$(BUILD_DIR)/src/micetools/system_dummy\dummykeychip\dummykeychip.exe" "$(DIST_DIR)/system_dummy/dummykeychip.exe" @copy /Y "src/micetools/miceboot\TrueCrypt.cmd" "$(DIST_DIR)/Execute/TrueCrypt.cmd" diff --git a/src/micetools/dll/devices/_devices.c b/src/micetools/dll/devices/_devices.c index 2d3a748..0f18263 100644 --- a/src/micetools/dll/devices/_devices.c +++ b/src/micetools/dll/devices/_devices.c @@ -63,6 +63,7 @@ void install_devices() { install_led_bd(); install_touch_bd(); install_aime_bd(); + install_servo_15069(); start_devices(); diff --git a/src/micetools/dll/devices/_devices.h b/src/micetools/dll/devices/_devices.h index 5510f9b..23c803f 100644 --- a/src/micetools/dll/devices/_devices.h +++ b/src/micetools/dll/devices/_devices.h @@ -6,6 +6,7 @@ void install_led_bd(); void install_touch_bd(); void install_aime_bd(); +void install_servo_15069(); smbus_callback_t smbus_N2_write; smbus_callback_t smbus_N2_read; diff --git a/src/micetools/dll/devices/meson.build b/src/micetools/dll/devices/meson.build index e439f02..cd3cb92 100644 --- a/src/micetools/dll/devices/meson.build +++ b/src/micetools/dll/devices/meson.build @@ -5,6 +5,7 @@ devices_files = files( 'ser_led_bd.c', 'ser_maitouch.c', 'ser_tn32msec.c', + 'ser_servo_838-15069.c', # SMBus devices 'smb_pca9535.c', 'smb_ds2460.c', diff --git a/src/micetools/dll/devices/ser_servo_838-15069.c b/src/micetools/dll/devices/ser_servo_838-15069.c new file mode 100644 index 0000000..7a069ac --- /dev/null +++ b/src/micetools/dll/devices/ser_servo_838-15069.c @@ -0,0 +1,82 @@ +#include "../hooks/gui.h" +#include "_devices.h" + +#define SERVO_OK 0 +#define SERVO_NG 8 + +static DWORD WINAPI ser_servo_15069_thread(com_device_t* dev) { + log_game(plfServo15069, "%ls woke up", dev->com->wName); + + unsigned char data[4]; + unsigned char response; + + while (1) { + comdev_read_blocking(dev, data, 4); + + // Validate checksums! + if (!(data[0] & 0x80) || (data[3] & 0x80) || + (data[0] & 0x7f) != (data[1] ^ data[2] ^ data[3])) { + log_error(plfServo15069, "checksums failed: %02x %02x %02x %02x", data[0], data[1], + data[2], data[3]); + continue; + } + + log_game(plfServo15069, "read:%02x %02x %02x %02x", data[0], data[1], data[2], data[3]); + + /** + * Read 4 bytes: + * + * [0]=v1 | 0x80 + * [1]=v2 + * [2]=v3 + * [3]=(v1^v2^v3) & 0x7f + * + * v1&0x7f=[3]^v2^v3 + * v2=[1] + * v3=[2] + * + * High byte v1 unrecoverable! + */ + + /** + * Wake sequence in test mode: + * + * 0x7f: 0, 0 + * 0x01, 64, 16 + * 0x02, 4, 84 + * + */ + + switch (data[0] & 0x7f) { + case 0x7f: + response = SERVO_OK; + comdev_write(dev, &response, 1); + break; + case 1: + case 2: + log_warning(plfServo15069, "Not sure what %d is!", data[0] & 0x7f); + response = (data[0] & 7) | SERVO_OK; + comdev_write(dev, &response, 1); + break; + + default: + log_error(plfServo15069, "Unknown opcode: %02x", data[0] & 0x7f); + response = SERVO_NG; + comdev_write(dev, &response, 1); + break; + } + + /** + * Respond one byte, 8=high: + * [0] \ + * [1] => data + * [2] / + * [3] = status + * [4] \ + * [5] => data again + * [6] / + * [7] = X + */ + } +} +void install_servo_15069() { register_device("servo_15069", ser_servo_15069_thread); } diff --git a/src/micetools/dll/dllmain.c b/src/micetools/dll/dllmain.c index 28f11c3..ef0350e 100644 --- a/src/micetools/dll/dllmain.c +++ b/src/micetools/dll/dllmain.c @@ -152,27 +152,6 @@ void tea_hook_test(char* fmt, ...) { va_end(argp); } -int 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, MdMasterThreadProc, NULL, 0, NULL); - // CreateThread(NULL, 0, MdInstallerThreadProc, NULL, 0, NULL); -} - BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { if (ul_reason_for_call != DLL_PROCESS_ATTACH) return TRUE; @@ -187,8 +166,6 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv // *((DWORD*)(0x00407850)) = (DWORD)(&logcb); } - spawn_pcp_processes(); - // if (wcscmp(exeName, L"RingGame.exe") == 0) { // log_warning(plfBoot, "Bodge hook goo!"); // CreateHook32((void*)(0x005f2580), &tea_hook_test); diff --git a/src/micetools/dll/drivers/columba.c b/src/micetools/dll/drivers/columba.c index b7ee8fe..09e992e 100644 --- a/src/micetools/dll/drivers/columba.c +++ b/src/micetools/dll/drivers/columba.c @@ -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(plfColumba, "DeviceIoControl(, , 0x%p, 0x%x, -, 0x%x, -, -)", - lpInBuffer, nInBufferSize, nOutBufferSize); + log_trace(plfColumba, "DeviceIoControl(, , 0x%p, 0x%x, -, 0x%x, -, -)", + lpInBuffer, nInBufferSize, nOutBufferSize); AM_COLUMBA_REQUEST* request = (AM_COLUMBA_REQUEST*)lpInBuffer; - log_info(plfColumba, "Physical read: 0x%04x %ss at %08X", request->m_elementCount, + log_misc(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" diff --git a/src/micetools/dll/drivers/mxjvs.c b/src/micetools/dll/drivers/mxjvs.c index 13eec76..d357435 100644 --- a/src/micetools/dll/drivers/mxjvs.c +++ b/src/micetools/dll/drivers/mxjvs.c @@ -407,251 +407,11 @@ 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(plfMxJvs, "Switching to %d baud (%d%c%s)", lpDCB->BaudRate, lpDCB->ByteSize, + log_misc(plfMxJvs, "Switching to %d baud (%d%c%s)", lpDCB->BaudRate, lpDCB->ByteSize, PARITY[lpDCB->Parity], STOP[lpDCB->StopBits]); return TRUE; } -// jvs_board_t maimai_jvs_config[1] = { { -// .test_keybind = VK_OEM_4, // [{ -// .coin_keybinds = {'1', '2'}, -// .keybinds = { -// { -// 0, -// 0, -// 0, -// 'W', // *1P8 -// 'Q', // *1P7 -// 'A', // *1P6 -// 'Z', // *1P5 -// 'X', // *1P4 -// 'C', // *1P3 -// 0, -// 'E', // *1P1 -// 'D', // *1P2 -// 0, -// 0, -// '1', // *1P Service -// 0, - -// }, -// { -// 0, -// 0, -// 0, -// 'I', // *2P8 -// 'U', // *2P7 -// 'J', // *2P6 -// 'M', // *2P5 -// VK_OEM_COMMA, // *2P4 -// VK_OEM_PERIOD, // *2P3 -// 0, -// 'O', // *2P1 -// 'L', // *2P2 -// 0, -// 0, -// '2', // *2P Service -// 0, - -// }, -// }, -// .flags = { -// { -// JVS_FLAG_NC, -// JVS_FLAG_NC, -// JVS_FLAG_NC, -// JVS_FLAG_INVERT, -// JVS_FLAG_INVERT, -// JVS_FLAG_INVERT, -// JVS_FLAG_INVERT, -// JVS_FLAG_INVERT, -// JVS_FLAG_INVERT, -// JVS_FLAG_NC, -// JVS_FLAG_INVERT, -// JVS_FLAG_INVERT, -// JVS_FLAG_NC, -// JVS_FLAG_NC, -// JVS_FLAG_NONE, -// JVS_FLAG_NC, -// }, -// { - -// JVS_FLAG_NC, -// JVS_FLAG_NC, -// JVS_FLAG_NC, -// JVS_FLAG_INVERT, -// JVS_FLAG_INVERT, -// JVS_FLAG_INVERT, -// JVS_FLAG_INVERT, -// JVS_FLAG_INVERT, -// JVS_FLAG_INVERT, -// JVS_FLAG_NC, -// JVS_FLAG_INVERT, -// JVS_FLAG_INVERT, -// JVS_FLAG_NC, -// JVS_FLAG_NC, -// JVS_FLAG_NONE, -// JVS_FLAG_NC, -// }, -// }, -// .coin_counts = {0, 0}, -// .handler = &jvs_exchange, -// .id = JVS_837_14572_ID, -// } }; - -// jvs_board_t under_night_jvs_config[1] = { -// { -// .test_keybind = VK_OEM_4, // [{ -// .coin_keybinds = {'1', '2'}, -// .keybinds = { -// { -// 0, 0, 0, 0, 0, 0, -// 'A', // D (EXCs) -// 'R', // C (Heavy) -// 'E', // B (Middle) -// 'W', // A (Light) -// VK_RIGHT, // Right -// VK_LEFT, // Left -// VK_DOWN, // Down -// VK_UP, // Up -// VK_BACK, // Service -// VK_RETURN, // Start -// }, -// { -// 0, 0, 0, 0, 0, 0, -// 'J', // D (EXCs) -// 'P', // C (Heavy) -// 'O', // B (Middle) -// 'I', // A (Light) -// VK_NUMPAD6, // Right -// VK_NUMPAD4, // Left -// VK_NUMPAD2, // Down -// VK_NUMPAD8, // Up -// VK_BACK, // Service -// VK_RETURN, // Start -// }, -// }, -// .flags = { -// { -// JVS_FLAG_NC, -// JVS_FLAG_NC, -// JVS_FLAG_NC, -// JVS_FLAG_NC, -// JVS_FLAG_NC, -// JVS_FLAG_NC, -// JVS_FLAG_NONE, -// JVS_FLAG_NONE, -// JVS_FLAG_NONE, -// JVS_FLAG_NONE, -// JVS_FLAG_NONE, -// JVS_FLAG_NONE, -// JVS_FLAG_NONE, -// JVS_FLAG_NONE, -// JVS_FLAG_NONE, -// JVS_FLAG_NONE, -// }, -// { -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// JVS_FLAG_NC, -// JVS_FLAG_NC, -// JVS_FLAG_NC, -// JVS_FLAG_NC, -// JVS_FLAG_NC, -// JVS_FLAG_NC, -// JVS_FLAG_NONE, -// JVS_FLAG_NONE, -// JVS_FLAG_NONE, -// JVS_FLAG_NONE, -// JVS_FLAG_NONE, -// JVS_FLAG_NONE, -// JVS_FLAG_NONE, -// JVS_FLAG_NONE, -// JVS_FLAG_NONE, -// JVS_FLAG_NONE, -// }, -// }, -// .coin_counts = {0, 0}, -// .handler = &jvs_exchange, -// .id = JVS_837_14572_ID, -// }, -// // { -// // .test_keybind = VK_OEM_4, // [{ -// // .coin_keybinds = {0, 0}, -// // .keybinds = { -// // { -// // 0, 0, 0, 0, 0, 0, -// // 'J', // D (EXCs) -// // 'P', // C (Heavy) -// // 'O', // B (Middle) -// // 'I', // A (Light) -// // VK_NUMPAD6, // Right -// // VK_NUMPAD4, // Left -// // VK_NUMPAD2, // Down -// // VK_NUMPAD8, // Up -// // VK_BACK, // Service -// // VK_RETURN, // Start -// // }, -// // {0}, -// // }, -// // .flags = { -// // { -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NONE, -// // JVS_FLAG_NONE, -// // JVS_FLAG_NONE, -// // JVS_FLAG_NONE, -// // JVS_FLAG_NONE, -// // JVS_FLAG_NONE, -// // JVS_FLAG_NONE, -// // JVS_FLAG_NONE, -// // JVS_FLAG_NONE, -// // JVS_FLAG_NONE, -// // }, -// // { -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // JVS_FLAG_NC, -// // }, -// // }, -// // .coin_counts = {0, 0}, -// // .handler = &jvs_exchange, -// // .id = JVS_837_14572_ID, -// // }, -// }; - void init_jvs_boards() { for (int i = 0; i < _countof(jvs_boards); i++) { jvs_boards[i].num = i; diff --git a/src/micetools/dll/drivers/mxsram.c b/src/micetools/dll/drivers/mxsram.c index 7123292..c61e60a 100644 --- a/src/micetools/dll/drivers/mxsram.c +++ b/src/micetools/dll/drivers/mxsram.c @@ -70,7 +70,7 @@ BOOL WINAPI mxsram_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L switch (dwIoControlCode) { case IOCTL_MXSRAM_PING: // Get version - log_info(plfMxSram, + log_misc(plfMxSram, "DeviceIoControl(, , 0x%p, 0x%x, -, 0x%x, " "-, -)", lpInBuffer, nInBufferSize, nOutBufferSize); @@ -79,7 +79,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(plfMxSram, + log_misc(plfMxSram, "DeviceIoControl(, , 0x%p, " "0x%x, -, 0x%x, -, -)", lpInBuffer, nInBufferSize, nOutBufferSize); @@ -97,7 +97,7 @@ BOOL WINAPI mxsram_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, L log_error(plfMxSram, "Unhandled IOCTL_DISK_GET_LENGTH_INFO"); return FALSE; case IOCTL_MXSRAM_GET_SECTOR_SIZE: - log_info(plfMxSram, + log_misc(plfMxSram, "DeviceIoControl(, , 0x%p, " "0x%x, -, 0x%x, -, -)", lpInBuffer, nInBufferSize, nOutBufferSize); diff --git a/src/micetools/dll/games.c b/src/micetools/dll/games.c index 4a5b274..97c6955 100644 --- a/src/micetools/dll/games.c +++ b/src/micetools/dll/games.c @@ -91,8 +91,18 @@ void mice_got_game_id(char game_id[4]) { // 2P is unbound by default, as a (nice) keymap with both // will probably also involve changing 1P too. } + } else if (IS_GAME(SBVH /* Sega & Sonic All-Stars Racing Arcade */)) { + log_info(plfBoot, "Detect game Sega & Sonic All-Stars Racing Arcade"); + + MiceConfig.devices.com1 = "servo_15069"; + MiceConfig.devices.com2 = ""; + MiceConfig.devices.com3 = ""; + MiceConfig.devices.com5 = ""; + MiceConfig.devices.com6 = ""; + MiceConfig.devices.com7 = ""; + MiceConfig.devices.com8 = ""; } else { - log_warning(plfBoot, "Unknown game ID: %.4s", game_id); + if (game_id[0] != '\0') return log_warning(plfBoot, "Unknown game ID: %.4s", game_id); return; } diff --git a/src/micetools/dll/hooks/drive/hooks.c b/src/micetools/dll/hooks/drive/hooks.c index 2d5f2e4..e1db0a6 100644 --- a/src/micetools/dll/hooks/drive/hooks.c +++ b/src/micetools/dll/hooks/drive/hooks.c @@ -248,9 +248,13 @@ DWORD WINAPI FakeQueryDosDeviceW(LPCWSTR lpDeviceName, LPWSTR lpTargetPath, DWOR swprintf_s(lpTargetPath, ucchMax, L"\\Device\\%ls", volume->m_DeviceName); return ucchMax; } else { + // ! We cannot do this, because some programs lie in ucchMax!! + // ZeroMemory(lpTargetPath, ucchMax); + // TODO: This, properly!! - ZeroMemory(lpTargetPath, ucchMax); - swprintf_s(lpTargetPath, ucchMax, DUMMY_USB_RM); + size_t nbytes = swprintf_s(lpTargetPath, ucchMax, DUMMY_USB_RM); + lpTargetPath[nbytes] = '\0'; + lpTargetPath[nbytes + 1] = '\0'; } return 0; } @@ -292,14 +296,14 @@ UINT WINAPI FakeGetDriveTypeA(LPCSTR lpRootPathName) { disk_volume_t* volume = getVolumeByPath(lpRootPathName, VOL_MATCH_PATH | VOL_MATCH_DOS_DEVICE); if (volume == NULL) { // If we aren't faking this drive, check if we're allowing fall-through - // char gameDrive = char_lower(GetGamedataDrive()); - // if (strlen(lpRootPathName) >= 2 && char_lower(lpRootPathName[0]) == gameDrive && - // lpRootPathName[1] == ':') { - // return DRIVE_FIXED; - // } + char gameDrive = char_lower(GetGamedataDrive()); + if (strlen(lpRootPathName) >= 2 && char_lower(lpRootPathName[0]) == gameDrive && + lpRootPathName[1] == ':') { + return DRIVE_FIXED; + } + // SetLastError(ERROR_FILE_NOT_FOUND); // return DRIVE_NO_ROOT_DIR; - // We could do the above, but for now, we're just going to pass through to the real API. return TrueGetDriveTypeA(lpRootPathName); } diff --git a/src/micetools/dll/hooks/drive/irb.h b/src/micetools/dll/hooks/drive/irb.h index 28be014..8b0a86d 100644 --- a/src/micetools/dll/hooks/drive/irb.h +++ b/src/micetools/dll/hooks/drive/irb.h @@ -2,6 +2,7 @@ #include // Lifted from Irb.h +#pragma pack(push, 1) typedef struct _IDENTIFY_DEVICE_DATA { struct { USHORT Reserved1 : 1; @@ -373,3 +374,4 @@ typedef struct _IDENTIFY_DEVICE_DATA { USHORT Signature : 8; USHORT CheckSum : 8; } IDENTIFY_DEVICE_DATA, *PIDENTIFY_DEVICE_DATA; +#pragma pack(pop) diff --git a/src/micetools/dll/hooks/drive/physicalDrive.c b/src/micetools/dll/hooks/drive/physicalDrive.c index e6ed9c2..87da2bf 100644 --- a/src/micetools/dll/hooks/drive/physicalDrive.c +++ b/src/micetools/dll/hooks/drive/physicalDrive.c @@ -36,8 +36,8 @@ BOOL WINAPI pd_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOI } /** - * C1: Seen by mxkeychip - * C2: Seen by factorytest + * C1: ssd.hostproof; Used by mxkeychip + * C2: ssh.proof; Used by mxkeychip and factorytest */ if (command != 0xC1 && command != 0xC2) { diff --git a/src/micetools/dll/hooks/logging.c b/src/micetools/dll/hooks/logging.c index cde6405..39ae84d 100644 --- a/src/micetools/dll/hooks/logging.c +++ b/src/micetools/dll/hooks/logging.c @@ -1,5 +1,6 @@ #include "logging.h" +#include "../../lib/mice/mice.h" #include "../util/_util.h" char* trim_string(char* string) { diff --git a/src/micetools/dll/hooks/network.c b/src/micetools/dll/hooks/network.c index 7488a71..a6723bb 100644 --- a/src/micetools/dll/hooks/network.c +++ b/src/micetools/dll/hooks/network.c @@ -3,8 +3,9 @@ int WINAPI Fake_connect(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); - // Poorly exclude nxauth. TODO: better - if (port != 40190) { + // Poorly exclude nxauth and mxgcatcher. + // TODO: better + if (port != 40190 && port != 40110) { log_info(plfNetwork, "connect(%hhu.%hhu.%hhu.%hhu:%hu)", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff, port); } diff --git a/src/micetools/dll/hooks/setupapi.c b/src/micetools/dll/hooks/setupapi.c index 9443653..8c18d56 100644 --- a/src/micetools/dll/hooks/setupapi.c +++ b/src/micetools/dll/hooks/setupapi.c @@ -43,7 +43,7 @@ BOOL WINAPI FakeSetupDiEnumDeviceInterfaces(HDEVINFO DeviceInfoSet, PSP_DEVINFO_ if (DeviceInterfaceData) { while (device != NULL) { if (device->handle == DeviceInfoSet) { - log_info(plfSetupAPI, "hooking fake device: %ls", device->path); + log_misc(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; @@ -68,7 +68,7 @@ BOOL WINAPI FakeSetupDiGetDeviceInterfaceDetailA(HDEVINFO DeviceInfoSet, PSP_DEV FAKE_DEVICE* device = fake_devices; while (device != NULL) { if (device->handle == DeviceInfoSet && (ULONG_PTR)device->path == DeviceInterfaceData->Reserved) { - log_info(plfSetupAPI, "Intercepted SetupDiGetDeviceInterfaceDetailA"); + log_misc(plfSetupAPI, "Intercepted SetupDiGetDeviceInterfaceDetailA"); const WCHAR* res = (WCHAR*)DeviceInterfaceData->Reserved; int new_len = (wcslen(res) + 1) * (sizeof *res); diff --git a/src/micetools/dll/meson.build b/src/micetools/dll/meson.build index f242e4b..a22c57c 100644 --- a/src/micetools/dll/meson.build +++ b/src/micetools/dll/meson.build @@ -9,7 +9,6 @@ shared_library( vs_module_defs: 'mice.def', sources: [ 'util/misc.c', - 'util/log.c', 'util/hook.c', 'util/path.c', @@ -29,11 +28,7 @@ shared_library( amiTimer, amiMd5, mxk, - - # Madoka service emulation mxklib, - dummymaster, - dummyinstaller, ], include_directories: [ openssl_inc, diff --git a/src/micetools/dll/util/_util.h b/src/micetools/dll/util/_util.h index 6ece4b4..cba260b 100644 --- a/src/micetools/dll/util/_util.h +++ b/src/micetools/dll/util/_util.h @@ -1,7 +1,6 @@ #pragma once #include "hook.h" -#include "log.h" #define HDATA_FILE 0 #define HDATA_FIND_VOLUME 1 diff --git a/src/micetools/dll/util/hook.c b/src/micetools/dll/util/hook.c index 832f567..3729583 100644 --- a/src/micetools/dll/util/hook.c +++ b/src/micetools/dll/util/hook.c @@ -4,7 +4,7 @@ #include #include -#include "log.h" +#include "../../lib/mice/mice.h" function_hook_t* hook_list = NULL; @@ -104,19 +104,19 @@ void* CreateHook32(PVOID src, PVOID dst) { // push 0x... (dword) len = 5; } else if (bSrc[0] == 0x55 && bSrc[1] == 0x8B && bSrc[2] == 0xEC && bSrc[3] == 0x83 && - bSrc[4] == 0xE4) { + bSrc[4] == 0xE4) { // pusb ebp // mov ebp,esp // and esp,ffffff** len = 6; } else if (bSrc[0] == 0x55 && bSrc[1] == 0x8B && bSrc[2] == 0xEC && bSrc[3] == 0x8b && - bSrc[4] == 0x45) { + bSrc[4] == 0x45) { // pusb ebp // mov ebp,esp // mov eax,DWORD PTR [...] len = 6; } else if (bSrc[0] == 0x55 && bSrc[1] == 0x8B && bSrc[2] == 0xEC && bSrc[3] == 0x80 && - bSrc[4] == 0x3D) { + bSrc[4] == 0x3D) { // pusb ebp // mov ebp,esp // cmd BYTE PTR ds:0x...,0x... @@ -169,8 +169,7 @@ void setup_hooks() { // (TrueGetProcAddress ? TrueGetProcAddress : GetProcAddress)(dll, hook->name); void* original = GetProcAddress(dll, hook->name); if (original == NULL) { - log_warning(plfHooks, "failed to get original %s (%03x)", hook->name, - GetLastError()); + 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; diff --git a/src/micetools/launcher/main.c b/src/micetools/launcher/main.c index 569127b..ed19b15 100644 --- a/src/micetools/launcher/main.c +++ b/src/micetools/launcher/main.c @@ -3,29 +3,23 @@ #include "../lib/mice/mice.h" #include "locate.h" +#include "spawn.h" bool debug_wait = false; int boot_delay = 0; -bool gametest = false; -bool designviewer = false; -bool spriteviewer = false; -bool noisetest = false; char exe_name[MAX_PATH + 1] = ""; char commandline[MAX_PATH + 1] = ""; void print_help(char* exe) { - fprintf(stderr, "Usage: %s [-h] [-t] [-b executable.exe] [-d]\n", exe); - fprintf(stderr, " -h: Print this help message and exit\n"); - fprintf(stderr, " -b: Specify the game binary to use\n"); - fprintf(stderr, " -d: Wait for a debugger to attach when starting\n"); - fprintf(stderr, " -t: Start the game in test mode\n"); - fprintf(stderr, " -dv: Start the game in design viewer mode\n"); - fprintf(stderr, " -sv: Start the game in sprite viewer mode\n"); - fprintf(stderr, " -nt: Start the game in noisetest mode\n"); + log_info(plfBoot, "Usage: %s [-h] [-t] [-b executable.exe] [-d]", exe); + log_info(plfBoot, " -h: Print this help message and exit"); + log_info(plfBoot, " -b: Specify the game binary to use"); + log_info(plfBoot, " --mice-d: Wait for a debugger to attach when starting"); + log_info(plfBoot, " --mice.=: Set launcher options"); exit(0); } -void parse_cmdline(int argc, char* argv[]) { +bool parse_cmdline(int argc, char* argv[]) { for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "-h") == 0) { print_help(argv[0]); @@ -35,14 +29,44 @@ void parse_cmdline(int argc, char* argv[]) { memcpy(exe_name, val, strlen(val) + 1); } else if (strcmp(argv[i], "--mice-d") == 0) { debug_wait = true; - } else if (strcmp(argv[i], "-mice-t") == 0) { - gametest = true; - } else if (strcmp(argv[i], "-dv") == 0) { - designviewer = true; - } else if (strcmp(argv[i], "-sv") == 0) { - spriteviewer = true; - } else if (strcmp(argv[i], "-nt") == 0) { - noisetest = true; + } else if (strncmp(argv[i], "--mice.", strlen("--mice.")) == 0) { + char key[256]; + char value[256]; + key[0] = value[0] = '\0'; + + char* arg = argv[i] + strlen("--mice."); + int j = 0; + for (; j < _countof(key) - 2; j++) { + if (arg[j] == '\0') break; + if (arg[j] == '=') { + strcpy_s(value, _countof(value), arg + j + 1); + break; + } + key[j] = arg[j]; + } + key[j] = '\0'; + bool handled = false; + + for (j = 0; j < _countof(mxspawns); j++) { + if (strcmp(key, mxspawns[j].name) != 0) continue; + handled = true; + + if (strcmp(value, "no") == 0) + mxspawns[j].mode = SPAWN_NONE; + else if (strcmp(value, "mx") == 0) + mxspawns[j].mode |= SPAWN_REAL; + else if (strcmp(value, "md") == 0) + mxspawns[j].mode |= SPAWN_DUMMY; + else { + log_error(plfBoot, "Unknown spawn mode: %s=%s", key, value); + return false; + } + } + + if (!handled) { + log_error(plfBoot, "Unknown launcher config: %s=%s", key, value); + return false; + } } else { if (commandline[0] == 0) snprintf(commandline, sizeof commandline, "%s", argv[i]); @@ -50,18 +74,20 @@ void parse_cmdline(int argc, char* argv[]) { snprintf(commandline, sizeof commandline, "%s %s", commandline, argv[i]); } } + return true; } int main(int argc, char* argv[]) { load_mice_config(); + setup_logging(); + + log_info(plfBoot, "Micetools version: %s", MICE_VERSION); CHAR workDir[MAX_PATH + 1]; GetCurrentDirectory(MAX_PATH, workDir); - fprintf(stderr, "Work dir: %s\n", workDir); + log_info(plfBoot, "Current directory: %s", workDir); - fprintf(stderr, "Micetools version: %s\n", MICE_VERSION); - - parse_cmdline(argc, argv); + if (!parse_cmdline(argc, argv)) return 0; if (exe_name[0] == '\0' && MiceConfig.launcher.game_binary[0] != '\0') { snprintf(exe_name, sizeof exe_name, "%s", MiceConfig.launcher.game_binary); @@ -71,44 +97,36 @@ int main(int argc, char* argv[]) { if (exe_name[0] == '\0') { if (!locate_game(exe_name, MAX_PATH + 1)) { - fprintf(stderr, "Fatal: Failed to locate a game\n"); + log_error(plfBoot, "Fatal: Failed to locate a game"); return 0; } } else { DWORD dwAttrib = GetFileAttributes(exe_name); if (dwAttrib == INVALID_FILE_ATTRIBUTES || dwAttrib & FILE_ATTRIBUTE_DIRECTORY) { - fprintf(stderr, "Fatal: %s: no such file found\n", exe_name); + log_error(plfBoot, "Fatal: %s: no such file found", exe_name); return 0; } } - char* cmdline_mode = gametest ? ". gametest" - : designviewer ? ". designviewer" - : spriteviewer ? ". spriteviewer" - : noisetest ? ". noisetest" - : ""; - char cmdline[MAX_PATH + 1]; - if (commandline[0] == 0) - snprintf(cmdline, sizeof cmdline, "%s", cmdline_mode); - else - snprintf(cmdline, sizeof cmdline, "%s %s", cmdline_mode, commandline); - fprintf(stderr, "exec: %s %s\n", exe_name, cmdline); + spawn_pcp_processes(); + + log_info(plfBoot, "exec: %s %s", exe_name, commandline); char micepath[MAX_PATH + 1]; if (!locate_library(micepath, MAX_PATH + 1)) { - fprintf(stderr, "Fatal: Failed to locate micelib. Check your mice_dll setting!\n"); + log_error(plfBoot, "Fatal: Failed to locate micelib. Check your mice_dll setting!"); return 0; } char* extra_injections = MiceConfig.launcher.inject; HANDLE game_proc = - start_and_inject(exe_name, cmdline, micepath, debug_wait, boot_delay, extra_injections, 0); + start_and_inject(exe_name, commandline, micepath, debug_wait, boot_delay, extra_injections, 0); if (!game_proc) return -1; if (FAILED(WaitForSingleObject(game_proc, INFINITE))) { - fprintf(stderr, "Fatal: WaitForSingleObject failed: %03x\n", GetLastError()); + log_error(plfBoot, "Fatal: WaitForSingleObject failed: %03x", GetLastError()); } else { - fprintf(stderr, "Shutting down\n"); + log_info(plfBoot, "Shutting down"); CloseHandle(game_proc); } return 0; diff --git a/src/micetools/launcher/meson.build b/src/micetools/launcher/meson.build index 3ecbc54..7477e8b 100644 --- a/src/micetools/launcher/meson.build +++ b/src/micetools/launcher/meson.build @@ -4,10 +4,18 @@ executable( win_subsystem: subsystem, sources: [ 'locate.c', + 'spawn.c', 'main.c', rc, ], link_with: [ mice_lib, + mxklib, + + # Madoka service emulation + mxk, + dummykeychip, + dummymaster, + dummyinstaller, ], ) diff --git a/src/micetools/launcher/spawn.c b/src/micetools/launcher/spawn.c new file mode 100644 index 0000000..4b79eac --- /dev/null +++ b/src/micetools/launcher/spawn.c @@ -0,0 +1,63 @@ + +#include "spawn.h" + +#include "../lib/mice/mice.h" + +spawn_t mxspawns[3] = { + { "keychip", SPAWN_DUMMY, MdkThreadProc, MxkThreadProc }, + { "master", SPAWN_DUMMY, MdmThreadProc, NULL }, + { "installer", SPAWN_DUMMY, MdiThreadProc, NULL }, +}; + +int mxkMain(); +int miceDummyKeychip(unsigned short textPort, unsigned short binaryPort, bool global); +int miceDummyMaster(unsigned short textPort, unsigned short binaryPort, bool global); +int miceDummyInstaller(unsigned short textPort, unsigned short binaryPort, bool global); +DWORD WINAPI MdkThreadProc(LPVOID lpParameter) { + miceDummyKeychip(40106, 40107, false); + return 0; +}; +DWORD WINAPI MxkThreadProc(LPVOID lpParameter) { + mxkMain(); + return 0; +}; +DWORD WINAPI MdmThreadProc(LPVOID lpParameter) { + miceDummyMaster(40100, 40101, false); + return 0; +}; +DWORD WINAPI MdiThreadProc(LPVOID lpParameter) { + miceDummyInstaller(40102, 40103, false); + return 0; +}; + +static inline void spawn_one(spawn_t* spawn) { + if (spawn->mode == SPAWN_NONE) { + log_warning(plfBoot, "Not spawning %s", spawn->name); + return; + } + if (spawn->mode == SPAWN_BOTH) { + log_error(plfBoot, "Invalid spawn mode for %s! Only one of md or mx may be selected", + spawn->name); + return; + } + if (spawn->mode == SPAWN_REAL) { + if (spawn->real == NULL) { + log_error(plfBoot, "mx mode for %s is not supported yet", spawn->name); + return; + } + CreateThread(NULL, 0, spawn->real, NULL, 0, NULL); + } else if (spawn->mode == SPAWN_DUMMY) { + if (spawn->dummy == NULL) { + log_error(plfBoot, "md mode for %s is not supported yet", spawn->name); + return; + } + CreateThread(NULL, 0, spawn->dummy, NULL, 0, NULL); + } else { + log_error(plfBoot, "Unknown spawn mode %d for %s", spawn->mode, spawn->name); + return; + } +} + +void spawn_pcp_processes(void) { + for (int i = 0; i < _countof(mxspawns); i++) spawn_one(&(mxspawns[i])); +} diff --git a/src/micetools/launcher/spawn.h b/src/micetools/launcher/spawn.h new file mode 100644 index 0000000..d136497 --- /dev/null +++ b/src/micetools/launcher/spawn.h @@ -0,0 +1,22 @@ +#include + +typedef struct { + char* name; + int mode; + LPTHREAD_START_ROUTINE dummy; + LPTHREAD_START_ROUTINE real; +} spawn_t; + +#define SPAWN_NONE 0 +#define SPAWN_DUMMY 1 +#define SPAWN_REAL 2 +#define SPAWN_BOTH (SPAWN_DUMMY | SPAWN_REAL) + +extern spawn_t mxspawns[3]; + +DWORD WINAPI MxkThreadProc(LPVOID lpParameter); +DWORD WINAPI MdkThreadProc(LPVOID lpParameter); +DWORD WINAPI MdmThreadProc(LPVOID lpParameter); +DWORD WINAPI MdiThreadProc(LPVOID lpParameter); + +void spawn_pcp_processes(void); diff --git a/src/micetools/lib/libpcp/meson.build b/src/micetools/lib/libpcp/meson.build index ea7401a..d6f00d6 100644 --- a/src/micetools/lib/libpcp/meson.build +++ b/src/micetools/lib/libpcp/meson.build @@ -19,5 +19,6 @@ libpcp = static_library( ], link_with: [ amiTimer, + amiDebug, ], ) diff --git a/src/micetools/lib/libpcp/pcp.h b/src/micetools/lib/libpcp/pcp.h index d348aad..ba7204a 100644 --- a/src/micetools/lib/libpcp/pcp.h +++ b/src/micetools/lib/libpcp/pcp.h @@ -1,6 +1,5 @@ #pragma once -#define PCP_LOG(fmt, ...) printf("%s:%d:" fmt, __func__, __LINE__, ##__VA_ARGS__) #define ZERO(x) memset(&(x), 0, sizeof(x)) #define ZERO_BUF(x) memset((x), 0, sizeof(*x)) diff --git a/src/micetools/lib/libpcp/pcpa.c b/src/micetools/lib/libpcp/pcpa.c index e0ba2d8..a9ca27f 100644 --- a/src/micetools/lib/libpcp/pcpa.c +++ b/src/micetools/lib/libpcp/pcpa.c @@ -49,7 +49,7 @@ e_pcpa_t _pcpaGetErrorFromPcpp(e_pcpp_t err) { void pcpaCloseBinary(pcpa_t *stream) { if (stream == NULL) { - PCP_LOG("error PCPA stream isn't set\n"); + amiDebugLog("error PCPA stream isn't set"); return; } stream->binary_mode = binary_mode_none; @@ -59,7 +59,7 @@ void pcpaCloseBinary(pcpa_t *stream) { void pcpaClose(pcpa_t *stream) { if (stream == NULL) { - PCP_LOG("error PCPA stream isn\'t set\n"); + amiDebugLog("error PCPA stream isn't set"); return; } pcppClose(&stream->pcpp); @@ -83,11 +83,11 @@ void pcpaClose(pcpa_t *stream) { e_pcpa_t pcpaInitStream(pcpa_t *stream) { if (LIBPCP_VERSION == NULL) { - PCP_LOG("error PCPA version isn\'t set\n"); + amiDebugLog("error PCPA version isn't set"); return e_pcpa_generic; } if (stream == NULL) { - PCP_LOG("error PCPA stream isn\'t set\n"); + amiDebugLog("error PCPA stream isn't set"); return e_pcpa_stream_unset; } @@ -119,11 +119,11 @@ e_pcpa_t pcpaInitStream(pcpa_t *stream) { e_pcpa_t pcpaOpenClient(pcpa_t *stream, char *ipAddr, ushort port, uint param_4, timeout_t timeout) { if (stream == NULL) { - PCP_LOG("error PCPA stream isn\'t set\n"); + amiDebugLog("error PCPA stream isn't set"); return e_pcpa_stream_unset; } if (ipAddr == 0) { - PCP_LOG("error PCPA IpAddr isn\'t set\n"); + amiDebugLog("error PCPA IpAddr isn't set"); return e_pcpa_param_invalid; } @@ -141,7 +141,7 @@ e_pcpa_t pcpaOpenServerWithBinary(pcpa_t *stream, int open_mode, u_short port, u e_pcpa_t err; if (stream == NULL) { - PCP_LOG("error PCPA stream isn\'t set\n"); + amiDebugLog("error PCPA stream isn't set"); return e_pcpa_stream_unset; } @@ -149,29 +149,29 @@ e_pcpa_t pcpaOpenServerWithBinary(pcpa_t *stream, int open_mode, u_short port, u case 0: stream->err = err = _errP2A(pcppOpenServer(&stream->pcpp, 0, port, param_5)); if (err != e_pcpa_ok) { - PCP_LOG("error pcppOpenServer\n"); + amiDebugLog("error pcppOpenServer"); return err; } stream->err = err = _errP2A(pcppOpenBinaryServer(&stream->pcpp, 0, binary_port)); if (err != e_pcpa_ok) { - PCP_LOG("error pcppOpenBinaryServer\n"); + amiDebugLog("error pcppOpenBinaryServer"); return err; } break; case 1: stream->err = err = _errP2A(pcppOpenServer(&stream->pcpp, 1, port, param_5)); if (err != e_pcpa_ok) { - PCP_LOG("error pcppOpenServer\n"); + amiDebugLog("error pcppOpenServer"); return err; } stream->err = err = _errP2A(pcppOpenBinaryServer(&stream->pcpp, 1, binary_port)); if (err != e_pcpa_ok) { - PCP_LOG("error pcppOpenBinaryServer\n"); + amiDebugLog("error pcppOpenBinaryServer"); return err; } break; default: - PCP_LOG("error Open Mode isn\'t set\n"); + amiDebugLog("error Open Mode isn't set"); return stream->err = e_pcpa_generic; } @@ -181,27 +181,27 @@ e_pcpa_t pcpaOpenServerWithBinary(pcpa_t *stream, int open_mode, u_short port, u e_pcpa_t pcpaSetCallbackFunc(pcpa_t *stream, char *keyword, pcpa_callback *callback, void *data) { if (stream == NULL) { - PCP_LOG("error PCPA stream isn\'t set\n"); + amiDebugLog("error PCPA stream isn't set"); return e_pcpa_stream_unset; } if (keyword == NULL) { - PCP_LOG("error keyword isn\'t set\n"); + amiDebugLog("error keyword isn't set"); return e_pcpa_generic; } if (callback == NULL) { - PCP_LOG("error Callback func isn\'t set\n"); + amiDebugLog("error Callback func isn't set"); return e_pcpa_generic; } if (stream->callback_table == NULL) { - PCP_LOG("error Callback_table buffer isn\'t set\n"); + amiDebugLog("error Callback_table buffer isn't set"); return e_pcpa_cb_table_unset; } if (strnlen(keyword, PCP_KEYWORD_MAX + 1) > PCP_KEYWORD_MAX) { - PCP_LOG("error a keyword is too long\n"); + amiDebugLog("error a keyword is too long"); return e_pcpa_generic; } @@ -219,7 +219,7 @@ e_pcpa_t pcpaSetCallbackFunc(pcpa_t *stream, char *keyword, pcpa_callback *callb e_pcpa_t pcpaSetCallbackFuncBuffer(pcpa_t *stream, pcpa_cb_table_t *callback_table, uint callbacks_max) { if (stream == NULL) { - PCP_LOG("error PCPA stream isn\'t set\n"); + amiDebugLog("error PCPA stream isn't set"); return e_pcpa_stream_unset; } @@ -234,7 +234,7 @@ e_pcpa_t pcpaSetCallbackFuncBuffer(pcpa_t *stream, pcpa_cb_table_t *callback_tab pcp_send_data_t *pcpaSetSendPacket(pcpa_t *stream, char *keyword, char *value) { if (stream == NULL) { - PCP_LOG("error PCPA stream isn\'t set\n"); + amiDebugLog("error PCPA stream isn't set"); return NULL; } return pcppSetSendPacket(&stream->send_data, keyword, value); @@ -242,7 +242,7 @@ pcp_send_data_t *pcpaSetSendPacket(pcpa_t *stream, char *keyword, char *value) { char *pcpaGetCommand(pcpa_t *pcpa, char *command) { if (pcpa == NULL) { - PCP_LOG("error PCPA stream isn\'t set\n"); + amiDebugLog("error PCPA stream isn't set"); return NULL; } @@ -266,7 +266,7 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) { local_14 = timeout_ms; if (stream == NULL) { - PCP_LOG("error PCPA stream isn\'t set\n"); + amiDebugLog("error PCPA stream isn't set"); return e_pcpa_stream_unset; } amiTimerGet(&time_start); @@ -408,7 +408,7 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) { return stream->err; } } else { - PCP_LOG("error pcpaSendBinary\n"); + amiDebugLog("error pcpaSendBinary"); } } break; @@ -443,7 +443,7 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) { stream->binary_mode = binary_mode_none; stream->state = pcpa_state_none; if (stream->err == e_pcpa_ok) goto LAB_00454a1a; - PCP_LOG("error pcpaRecvBinary\n"); + amiDebugLog("error pcpaRecvBinary"); } break; case 10: @@ -452,7 +452,7 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) { stream->before_cb(stream, stream->pcpp.sock.recv_buf); if (stream->callback_table == NULL) { - PCP_LOG("error Callback_table buffer isn\'t set\n"); + amiDebugLog("error Callback_table buffer isn't set"); stream->err = e_pcpa_cb_table_unset; return stream->err; @@ -526,11 +526,11 @@ LAB_00454d84: e_pcpa_t pcpaRecvBinary(pcpa_t *stream, uint something) { if (stream == NULL) { - PCP_LOG("error PCPA stream isn\'t set\n"); + amiDebugLog("error PCPA stream isn't set"); return e_pcpa_stream_unset; } if (stream->recv_buffer == NULL) { - PCP_LOG("error Recv buffer isn\'t set\n"); + amiDebugLog("error Recv buffer isn't set"); pcpaCloseBinary(stream); pcpaClose(stream); return stream->err = e_pcpa_cb_table_full; @@ -547,11 +547,11 @@ e_pcpa_t pcpaRecvBinary(pcpa_t *stream, uint something) { e_pcpa_t pcpaSendBinary(pcpa_t *stream, uint param_2) { if (stream == NULL) { - PCP_LOG("error PCPA stream isn\'t set\n"); + amiDebugLog("error PCPA stream isn't set"); return e_pcpa_stream_unset; } if (stream->send_buffer == NULL) { - PCP_LOG("error Send buffer isn\'t set\n"); + amiDebugLog("error Send buffer isn't set"); stream->err = e_pcpa_cb_table_full; pcpaCloseBinary(stream); pcpaClose(stream); @@ -567,13 +567,13 @@ e_pcpa_t pcpaSendBinary(pcpa_t *stream, uint param_2) { return err; } -e_pcpa_t pcpaSetSendBinaryBuffer(pcpa_t *stream, unsigned char *send_buffer, size_t len) { +e_pcpa_t pcpaSetSendBinaryBuffer(pcpa_t *stream, const unsigned char *send_buffer, size_t len) { if (stream == NULL) { - PCP_LOG("error PCPA stream isn\'t set\n"); + amiDebugLog("error PCPA stream isn't set"); return e_pcpa_stream_unset; } if (send_buffer == NULL) { - PCP_LOG("error Send Buffer isn\'t set\n"); + amiDebugLog("error Send Buffer isn't set"); return e_pcpa_timeout_closed; } stream->send_buffer = send_buffer; @@ -584,11 +584,11 @@ e_pcpa_t pcpaSetSendBinaryBuffer(pcpa_t *stream, unsigned char *send_buffer, siz e_pcpa_t pcpaSetBeforeBinaryModeCallBackFunc(pcpa_t *stream, pcpa_callback *callback, void *data) { if (stream == NULL) { - PCP_LOG("error don\'t set stream\n"); + amiDebugLog("error don't set stream"); return e_pcpa_stream_unset; } if (callback == NULL) { - PCP_LOG("error Binary mode callback func isn\'t set\n"); + amiDebugLog("error Binary mode callback func isn't set"); return e_pcpa_generic; } stream->binary_mode_before_cb = callback; @@ -599,11 +599,11 @@ e_pcpa_t pcpaSetBeforeBinaryModeCallBackFunc(pcpa_t *stream, pcpa_callback *call e_pcpa_t pcpaSetAfterBinaryModeCallBackFunc(pcpa_t *stream, pcpa_callback *callback, void *data) { if (stream == NULL) { - PCP_LOG("error don\'t set stream\n"); + amiDebugLog("error don't set stream"); return e_pcpa_stream_unset; } if (callback == NULL) { - PCP_LOG("error Binary mode callback func isn\'t set\n"); + amiDebugLog("error Binary mode callback func isn't set"); return e_pcpa_generic; } stream->binary_mode_after_cb = callback; @@ -614,7 +614,7 @@ e_pcpa_t pcpaSetAfterBinaryModeCallBackFunc(pcpa_t *stream, pcpa_callback *callb e_pcpa_t pcpaSetBinaryMode(pcpa_t *stream, binary_mode_t binary_mode) { if (stream == NULL) { - PCP_LOG("error PCPA stream isn\'t set\n"); + amiDebugLog("error PCPA stream isn't set"); return e_pcpa_stream_unset; } if (pcppGetServerSocket(&stream->pcpp, 1) == HANDLE_INVAL) { @@ -627,11 +627,11 @@ e_pcpa_t pcpaSetBinaryMode(pcpa_t *stream, binary_mode_t binary_mode) { e_pcpa_t pcpaSetRecvBinaryBuffer(pcpa_t *stream, unsigned char *recv_buffer, size_t len) { if (stream == NULL) { - PCP_LOG("error PCPA stream isn\'t set\n"); + amiDebugLog("error PCPA stream isn't set"); return e_pcpa_stream_unset; } if (recv_buffer == NULL) { - PCP_LOG("error Recv Buffer isn\'t set\n"); + amiDebugLog("error Recv Buffer isn't set"); return e_pcpa_timeout_closed; } stream->recv_buffer = recv_buffer; @@ -642,7 +642,7 @@ e_pcpa_t pcpaSetRecvBinaryBuffer(pcpa_t *stream, unsigned char *recv_buffer, siz pcp_send_data_t *pcpaAddSendPacket(pcpa_t *stream, char *keyword, char *value) { if (stream == NULL) { - PCP_LOG("error PCPA stream isn\'t set\n"); + amiDebugLog("error PCPA stream isn't set"); return NULL; } return pcppAddSendPacket(&stream->send_data, keyword, value); @@ -650,7 +650,7 @@ pcp_send_data_t *pcpaAddSendPacket(pcpa_t *stream, char *keyword, char *value) { char *pcpaGetKeyword(pcpa_t *stream, uint keyword_num) { if (stream == NULL) { - PCP_LOG("error PCPA stream isn\'t set\n"); + amiDebugLog("error PCPA stream isn't set"); return NULL; } return pcppGetKeyword(&stream->recv_data, keyword_num); @@ -661,7 +661,7 @@ e_pcpa_t pcpaIsBusy(pcpa_t *pcpa, timeout_t timeout) { amtime_t start; if (pcpa == NULL) { - PCP_LOG("error PCPA stream isn\'t set\n"); + amiDebugLog("error PCPA stream isn't set"); return e_pcpa_stream_unset; } @@ -723,7 +723,7 @@ e_pcpa_t pcpaIsBusy(pcpa_t *pcpa, timeout_t timeout) { e_pcpa_t pcpaSendRequest(pcpa_t *stream, timeout_t timeout) { if (stream == NULL) { - PCP_LOG("error PCPA stream isn\'t set\n"); + amiDebugLog("error PCPA stream isn't set"); return e_pcpa_stream_unset; } @@ -732,7 +732,7 @@ e_pcpa_t pcpaSendRequest(pcpa_t *stream, timeout_t timeout) { _pcpaGetErrorFromPcpp(pcppSendRequestTable(&stream->pcpp, &stream->send_data, timeout)); stream->err = err; if (err != e_pcpa_to) { - if (err != e_pcpa_ok) PCP_LOG("Error : pcppSendRequestTable(%d)\n", err); + if (err != e_pcpa_ok) amiDebugLog("Error : pcppSendRequestTable(%d)", err); memset(&stream->send_data, 0, sizeof stream->send_data); stream->state = pcpa_state_none; } @@ -741,7 +741,7 @@ e_pcpa_t pcpaSendRequest(pcpa_t *stream, timeout_t timeout) { e_pcpa_t pcpaRecvResponse(pcpa_t *stream, timeout_t timeout) { if (stream == NULL) { - PCP_LOG("error PCPA stream isn\'t set\n"); + amiDebugLog("error PCPA stream isn't set"); return e_pcpa_stream_unset; } @@ -750,7 +750,7 @@ e_pcpa_t pcpaRecvResponse(pcpa_t *stream, timeout_t timeout) { _pcpaGetErrorFromPcpp(pcppRecvResponse(&stream->pcpp, &stream->recv_data, timeout)); stream->err = err; if (err != e_pcpa_to) { - if (err != e_pcpa_ok) PCP_LOG("Error : pcppRecvResponse(%d)\n", err); + if (err != e_pcpa_ok) amiDebugLog("Error : pcppRecvResponse(%d)", err); stream->state = pcpa_state_none; } return err; @@ -758,7 +758,7 @@ e_pcpa_t pcpaRecvResponse(pcpa_t *stream, timeout_t timeout) { e_pcpa_t pcpaOpenBinaryClient(pcpa_t *stream, ushort port, timeout_t timeout) { if (stream == NULL) { - PCP_LOG("error PCPA stream isn\'t set\n"); + amiDebugLog("error PCPA stream isn't set"); return e_pcpa_stream_unset; } @@ -777,7 +777,7 @@ e_pcpa_t pcpaOpenBinaryClient(pcpa_t *stream, ushort port, timeout_t timeout) { e_pcpa_t pcpaAccessClient(pcpa_t *stream, timeout_t timeout) { if (stream == NULL) { - PCP_LOG("error PCPA stream isn\'t set\n"); + amiDebugLog("error PCPA stream isn't set"); return e_pcpa_stream_unset; } diff --git a/src/micetools/lib/libpcp/pcpa.h b/src/micetools/lib/libpcp/pcpa.h index e945a1b..ad5fdfb 100644 --- a/src/micetools/lib/libpcp/pcpa.h +++ b/src/micetools/lib/libpcp/pcpa.h @@ -91,7 +91,7 @@ e_pcpa_t pcpaSetBinaryMode(pcpa_t* stream, binary_mode_t binary_mode); e_pcpa_t pcpaSetCallbackFunc(pcpa_t* stream, char* keyword, pcpa_callback* callback, void* data); e_pcpa_t pcpaSetCallbackFuncBuffer(pcpa_t* stream, pcpa_cb_table_t* callback_table, uint callbacks_max); e_pcpa_t pcpaSetRecvBinaryBuffer(pcpa_t* stream, unsigned char* recv_buffer, size_t len); -e_pcpa_t pcpaSetSendBinaryBuffer(pcpa_t* stream, unsigned char* send_buffer, size_t len); +e_pcpa_t pcpaSetSendBinaryBuffer(pcpa_t* stream, const unsigned char* send_buffer, size_t len); pcp_send_data_t* pcpaSetSendPacket(pcpa_t* stream, char* keyword, char* value); pcp_send_data_t *pcpaAddSendPacket(pcpa_t *stream, char *keyword, char *value); char* pcpaGetCommand(pcpa_t* pcpa, char* command); diff --git a/src/micetools/lib/libpcp/pcpp.c b/src/micetools/lib/libpcp/pcpp.c index 277c421..39913cd 100644 --- a/src/micetools/lib/libpcp/pcpp.c +++ b/src/micetools/lib/libpcp/pcpp.c @@ -55,7 +55,7 @@ e_pcpp_t _pcppGetErrorFromPcpt(int err) { bool pcppCheckPrompt(pcpp_t* stream) { if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return false; } @@ -85,7 +85,7 @@ e_pcpp_t pcppCheckRecvMsg(char* recv_data, size_t buf_len, int param_3) { bool bVar1 = true; if (recv_data == NULL) { - PCP_LOG("pointer error\n"); + amiDebugLog("pointer error"); return e_pcpp_param_invalid; } @@ -118,13 +118,13 @@ pcpp_char_type_t pcppCheckStr(char* recv_data, uint* found_at, int* is_qmark) { uint idx = 0; if (recv_data == NULL || is_qmark == NULL || found_at == NULL) { - PCP_LOG("pointer error\n"); + amiDebugLog("pointer error"); return pcpp_char_error; } *is_qmark = 0; if (*found_at == 0) { - PCP_LOG("stream exhausted\n"); + amiDebugLog("stream exhausted"); return pcpp_char_error; } @@ -170,7 +170,7 @@ pcpp_char_type_t pcppCheckStr(char* recv_data, uint* found_at, int* is_qmark) { void pcppClose(pcpp_t* stream) { if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return; } @@ -201,7 +201,7 @@ void pcppClose(pcpp_t* stream) { void pcppCloseBinary(pcpp_t* stream) { if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return; } @@ -225,7 +225,7 @@ e_pcpp_t pcppGetBlockingTime(uint param_1, timeout_t timeout, pcpp_t* stream, in amtime_t local_8; if (stream == NULL || blocking_time == NULL) { - PCP_LOG("pointer error\n"); + amiDebugLog("pointer error"); return 0; } @@ -261,7 +261,7 @@ e_pcpp_t pcppGetBlockingTime(uint param_1, timeout_t timeout, pcpp_t* stream, in char* pcppGetCommand(pcp_parse_data_t* recv_data, char* command) { if (recv_data == NULL || command == NULL) { - PCP_LOG("error Recv Data isn\'t set\n"); + amiDebugLog("error Recv Data isn't set"); return NULL; } @@ -276,12 +276,12 @@ char* pcppGetCommand(pcp_parse_data_t* recv_data, char* command) { char* pcppGetKeyword(pcp_parse_data_t* recvData, uint keywordNum) { if (recvData == NULL) { - PCP_LOG("error Recv Data isn\'t set\n"); + amiDebugLog("error Recv Data isn't set"); return NULL; } if ((keywordNum >= PCP_CMDS_MAX) && (keywordNum > recvData->cmd_count)) { - PCP_LOG("error keywordNum over\n"); + amiDebugLog("error keywordNum over"); return NULL; } return recvData->strings + recvData->keywords[keywordNum]; @@ -289,7 +289,7 @@ char* pcppGetKeyword(pcp_parse_data_t* recvData, uint keywordNum) { SOCKET pcppGetServerSocket(pcpp_t* stream, int which) { if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return SOCKET_INVAL; } @@ -305,7 +305,7 @@ SOCKET pcppGetServerSocket(pcpp_t* stream, int which) { e_pcpp_t pcppInitStream(pcpp_t* stream) { if (stream == NULL) { - PCP_LOG("error don\'t set stream\n"); + amiDebugLog("error don't set stream"); return e_pcpp_param_invalid; } @@ -353,11 +353,11 @@ e_pcpp_t pcppOpenClient(pcpp_t* stream, char* ipAddr, ushort port, uint param_4, amtime_t now; if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return e_pcpp_param_invalid; } if (ipAddr == NULL) { - PCP_LOG("error IpAddr isn\'t set\n"); + amiDebugLog("error IpAddr isn't set"); return e_pcpp_param_invalid; } @@ -375,7 +375,7 @@ e_pcpp_t pcppOpenClient(pcpp_t* stream, char* ipAddr, ushort port, uint param_4, return e_pcpp_to; } stream->err = e_pcpp_no_server; - PCP_LOG("error Time out error\n"); + amiDebugLog("error Time out error"); } if (stream->err == 0) { amiTimerGet(&now); @@ -398,13 +398,13 @@ e_pcpp_t pcppOpenClient(pcpp_t* stream, char* ipAddr, ushort port, uint param_4, pcptCloseDataSock(&stream->sock); pcppResetRead(stream); err = stream->err; - PCP_LOG("error pcppRecvPrompt error = %d\n", err); + amiDebugLog("error pcppRecvPrompt error = %d", err); } else { pcptCloseDataSock(&stream->sock); pcppResetRead(stream); stream->state = pcpp_state_none; err = stream->err; - PCP_LOG("error pcptOpenClient error = %d\n", err); + amiDebugLog("error pcptOpenClient error = %d", err); } LAB_00a16a90: return stream->err; @@ -412,7 +412,7 @@ LAB_00a16a90: e_pcpp_t pcppOpenBinaryServer(pcpp_t* stream, int open_mode, ushort port) { if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return e_pcpp_param_invalid; } @@ -421,7 +421,7 @@ e_pcpp_t pcppOpenBinaryServer(pcpp_t* stream, int open_mode, ushort port) { stream->last_active = _amTimeMs(time); stream->state = pcpp_state_none; if (open_mode != 0 && open_mode != 1) { - PCP_LOG("error Open Mode isn\'t set\n"); + amiDebugLog("error Open Mode isn't set"); stream->state = pcpp_state_none; return stream->err = e_pcpp_param_invalid; } @@ -429,7 +429,7 @@ e_pcpp_t pcppOpenBinaryServer(pcpp_t* stream, int open_mode, ushort port) { e_pcpp_t err = _errT2P(pcptOpenServer(&stream->data_sock, open_mode, port)); stream->err = err; if (err != e_pcpp_ok) { - PCP_LOG("error pcptOpenBinaryServer\n"); + amiDebugLog("error pcptOpenBinaryServer"); return err; } @@ -440,11 +440,11 @@ e_pcpp_t pcppOpenBinaryServer(pcpp_t* stream, int open_mode, ushort port) { e_pcpp_t pcppOpenBinaryClient(pcpp_t* stream, char* ipAddr, ushort port, timeout_t timeout) { if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return e_pcpp_param_invalid; } if (ipAddr == NULL) { - PCP_LOG("error IpAddr isn\'t set\n"); + amiDebugLog("error IpAddr isn't set"); return e_pcpp_param_invalid; } stream->state = pcpp_state_open_binary; @@ -478,12 +478,12 @@ e_pcpp_t pcppOpenBinaryClient(pcpp_t* stream, char* ipAddr, ushort port, timeout e_pcpp_t pcppOpenServer(pcpp_t* stream, int open_mode, u_short port, undefined4 param_4) { if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return e_pcpp_param_invalid; } stream->field_0xb8 = param_4; if (open_mode != 0 && open_mode != 1) { - PCP_LOG("error Open Mode isn\'t set\n"); + amiDebugLog("error Open Mode isn't set"); stream->err = e_pcpp_param_invalid; stream->state = pcpp_state_none; @@ -493,7 +493,7 @@ e_pcpp_t pcppOpenServer(pcpp_t* stream, int open_mode, u_short port, undefined4 e_pcpp_t err = _errT2P(pcptOpenServer(&stream->sock, open_mode, port)); stream->err = err; if (err != e_pcpp_ok) { - PCP_LOG("error pcppOpenServer error = %d\n", err); + amiDebugLog("error pcppOpenServer error = %d", err); return err; } stream->open = 1; @@ -506,7 +506,7 @@ e_pcpp_t pcppOpenServer(pcpp_t* stream, int open_mode, u_short port, undefined4 pcp_send_data_t* pcppSetSendPacket(pcp_send_data_t* send_data, char* keyword, char* value) { if (send_data == NULL || keyword == NULL) { - PCP_LOG("error Send Data isn\'t set\n"); + amiDebugLog("error Send Data isn't set"); return NULL; } @@ -533,7 +533,7 @@ pcp_send_data_t* pcppSetSendPacket(pcp_send_data_t* send_data, char* keyword, ch uint pcppRecvCheck(char* buf, int* offset) { if (buf == NULL || offset == NULL) { - PCP_LOG("pointer error\n"); + amiDebugLog("pointer error"); return 1; } @@ -591,11 +591,11 @@ uint pcppRecvCheck(char* buf, int* offset) { e_pcpp_t pcppSendResponseTable(pcpp_t* stream, pcp_send_data_t* data, timeout_t timeout_ms) { if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return e_pcpp_param_invalid; } if (data == NULL) { - PCP_LOG("error Response buffer isn\'t set\n"); + amiDebugLog("error Response buffer isn't set"); return e_pcpp_param_invalid; } @@ -610,16 +610,16 @@ e_pcpp_t pcppSendResponse(pcpp_t* stream, pcp_send_data_t* resp_buffer, size_t b amtime_t time; if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return e_pcpp_param_invalid; } if (resp_buffer == NULL) { - PCP_LOG("error Response buffer isn\'t set\n"); + amiDebugLog("error Response buffer isn't set"); return e_pcpp_param_invalid; } if (buf_len > PCP_BUF_MAX - 1) { - PCP_LOG("error Response buffer over\n"); + amiDebugLog("error Response buffer over"); return stream->err = e_pcpp_param_invalid; } @@ -629,7 +629,7 @@ e_pcpp_t pcppSendResponse(pcpp_t* stream, pcp_send_data_t* resp_buffer, size_t b if (err != e_pcpp_ok) { stream->state = pcpp_state_none; pcppResetRead(stream); - PCP_LOG("error Send message format error\n"); + amiDebugLog("error Send message format error"); printf("'%s'\n", resp_buffer->data); return stream->err; } @@ -668,11 +668,11 @@ e_pcpp_t pcppRecvRequest(pcpp_t* stream, pcp_parse_data_t* recv_data, timeout_t amtime_t now2; if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return e_pcpp_param_invalid; } if (recv_data == NULL) { - PCP_LOG("error Request buffer isn\'t set\n"); + amiDebugLog("error Request buffer isn't set"); return stream->err = e_pcpp_param_invalid; } @@ -727,7 +727,7 @@ e_pcpp_t pcppRecvRequestMain(pcpp_t* stream, bool* bReRecv, undefined4 timeout) char* recv_data; if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return e_pcpp_param_invalid; } @@ -759,7 +759,7 @@ e_pcpp_t pcppSendPrompt(pcpp_t* stream, uint param_2, timeout_t timeout_ms) { bool has_timeout = false; if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return e_pcpp_param_invalid; } @@ -785,7 +785,7 @@ LAB_00456133: err = stream->open ? -12 : -6; pcptCloseDataSock(&stream->sock); pcppResetRead(stream); - if (stream->open == 0) PCP_LOG("Error : Time out error\n"); + if (stream->open == 0) amiDebugLog("Error : Time out error"); } amiTimerGet(&now); stream->last_active = _amTimeMs(now); @@ -804,12 +804,12 @@ e_pcpp_t pcppRecvAllMsg(pcpp_t* stream, uint param_1, bool* bReRecv) { local_14 = param_1; if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return e_pcpp_param_invalid; } if (bReRecv == NULL) { - PCP_LOG("error bReRecv isn\'t set\n"); + amiDebugLog("error bReRecv isn't set"); return e_pcpp_param_invalid; } *bReRecv = false; @@ -864,17 +864,17 @@ e_pcpp_t pcppRecvAllMsg(pcpp_t* stream, uint param_1, bool* bReRecv) { pcp_parse_data_t* pcppChangeRequest(pcpp_t* stream, uint* lenout) { if (stream == NULL || lenout == NULL) { - PCP_LOG("pointer error\n"); + amiDebugLog("pointer error"); return NULL; } if (stream->recv_data_buffer == NULL) { - PCP_LOG("don\'t set recvData buffer\n"); + amiDebugLog("don't set recvData buffer"); return NULL; } if (stream->read_bytes_num > PCP_BUF_MAX) { - PCP_LOG("Buffer size error\n"); + amiDebugLog("Buffer size error"); return NULL; } @@ -917,7 +917,7 @@ pcp_parse_data_t* pcppChangeRequest(pcpp_t* stream, uint* lenout) { break; case PCP_CHAR_SEP: if (stream->recv_data_buffer->cmd_count > PCP_CMDS_MAX) { - PCP_LOG("Buffer size error\n"); + amiDebugLog("Buffer size error"); return NULL; } stream->recv_data_buffer->strings[string_idx] = PCP_CHAR_EOF; @@ -927,7 +927,7 @@ pcp_parse_data_t* pcppChangeRequest(pcpp_t* stream, uint* lenout) { break; case PCP_CHAR_EQU: if (stream->recv_data_buffer->cmd_count > PCP_CMDS_MAX) { - PCP_LOG("Buffer size error\n"); + amiDebugLog("Buffer size error"); return NULL; } stream->recv_data_buffer->strings[string_idx] = PCP_CHAR_EOF; @@ -953,7 +953,7 @@ int pcppRecvPrompt(pcpp_t* stream, undefined4 param_2, int param_3) { uint local_c = param_3; if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return e_pcpp_param_invalid; } @@ -995,12 +995,12 @@ int pcppRecvPrompt(pcpp_t* stream, undefined4 param_2, int param_3) { e_pcpp_t pcppSendRequestMain(pcpp_t* stream, undefined4 param_2, timeout_t timeout_ms) { if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return e_pcpp_param_invalid; } if (stream->resp_buffer == NULL) { - PCP_LOG("error Request buffer isn\'t set\n"); + amiDebugLog("error Request buffer isn't set"); return e_pcpp_param_invalid; } @@ -1037,11 +1037,11 @@ e_pcpp_t pcppRecvBinary(pcpp_t* stream, unsigned char* recv_buf, size_t buf_len, recvb_local = param_4; if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return e_pcpp_param_invalid; } if (recv_buf == NULL) { - PCP_LOG("error Recv Bninary Buffer isn\'t set\n"); + amiDebugLog("error Recv Bninary Buffer isn't set"); return e_pcpp_param_invalid; } stream->field_0x214 = 0; @@ -1160,11 +1160,11 @@ e_pcpp_t pcppSendBinary(pcpp_t* stream, unsigned char* send_binary_buffer, size_ local_14 = param_4; if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return e_pcpp_param_invalid; } if (send_binary_buffer == NULL) { - PCP_LOG("error Send Bninary Buffer isn\'t set\n"); + amiDebugLog("error Send Bninary Buffer isn't set"); return stream->err = e_pcpp_param_invalid; } amiTimerGet(&local_8); @@ -1266,7 +1266,7 @@ e_pcpp_t pcppIsBusy(pcpp_t* stream, timeout_t timeout) { local_1c = 0; local_24 = 0; if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return e_pcpp_param_invalid; } amiTimerGet(&local_18); @@ -1511,7 +1511,7 @@ e_pcpp_t pcppIsBusy(pcpp_t* stream, timeout_t timeout) { } stream->state = pcpp_state_none; pcppResetRead(stream); - PCP_LOG("error Response format error\n"); + amiDebugLog("error Response format error"); return stream->err; } if (iVar3 == 0) break; @@ -1824,7 +1824,7 @@ e_pcpp_t pcppIsBusy(pcpp_t* stream, timeout_t timeout) { if (eVar7 != e_pcpp_ok) { stream->state = pcpp_state_none; pcppResetRead(stream); - PCP_LOG("error Response format error\n"); + amiDebugLog("error Response format error"); return stream->err; } pcppChangeRequest(stream, &timeout); @@ -1884,7 +1884,7 @@ int pcpp_something(amtime_t* time, timeout_t timeout, pcpp_t* stream, pcpt_t* so pcp_send_data_t* pcppAddSendPacket(pcp_send_data_t* send_data, char* keyword, char* value) { if (send_data == NULL || keyword == NULL) { - PCP_LOG("error Send Data isn\'t set\n"); + amiDebugLog("error Send Data isn't set"); return NULL; } @@ -1913,12 +1913,12 @@ pcp_send_data_t* pcppAddSendPacket(pcp_send_data_t* send_data, char* keyword, ch e_pcpp_t pcppSendRequestTable(pcpp_t* stream, pcp_send_data_t* request_buffer, timeout_t timeout) { if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return e_pcpp_param_invalid; } if (request_buffer == NULL) { - PCP_LOG("error Request buffer isn\'t set\n"); + amiDebugLog("error Request buffer isn't set"); return e_pcpp_param_invalid; } @@ -1932,16 +1932,16 @@ e_pcpp_t pcppSendRequest(pcpp_t* stream, pcp_send_data_t* request_buffer, uint n amtime_t local_8; if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return e_pcpp_param_invalid; } if (request_buffer == NULL) { - PCP_LOG("error Request buffer isn\'t set\n"); + amiDebugLog("error Request buffer isn't set"); return e_pcpp_param_invalid; } if (0x100 < nbytes) { - PCP_LOG("error Request buffer over\n"); + amiDebugLog("error Request buffer over"); return (stream->err = e_pcpp_param_invalid); } @@ -1951,7 +1951,7 @@ e_pcpp_t pcppSendRequest(pcpp_t* stream, pcp_send_data_t* request_buffer, uint n if (pcpp_err != e_pcpp_ok) { stream->state = pcpp_state_none; pcppResetRead(stream); - PCP_LOG("error Message format error\n"); + amiDebugLog("error Message format error"); return stream->err; } @@ -1990,12 +1990,12 @@ e_pcpp_t pcppRecvResponse(pcpp_t* stream, pcp_parse_data_t* buffer, timeout_t ti amtime_t local_8; if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return -5; } if (buffer == NULL) { - PCP_LOG("error Response buffer isn\'t set\n"); + amiDebugLog("error Response buffer isn't set"); return -5; } @@ -2038,7 +2038,7 @@ e_pcpp_t pcppRecvResponse(pcpp_t* stream, pcp_parse_data_t* buffer, timeout_t ti } else { stream->state = pcpp_state_none; pcppResetRead(stream); - PCP_LOG("error Response format error\n"); + amiDebugLog("error Response format error"); return stream->err; } @@ -2047,7 +2047,7 @@ e_pcpp_t pcppRecvResponse(pcpp_t* stream, pcp_parse_data_t* buffer, timeout_t ti SOCKADDR* pcppGetSockAddr(pcpp_t* stream, bool is_data) { if (stream == NULL) { - PCP_LOG("error PCPP stream isn\'t set\n"); + amiDebugLog("error PCPP stream isn't set"); return NULL; } diff --git a/src/micetools/lib/libpcp/pcpt.c b/src/micetools/lib/libpcp/pcpt.c index e90ad87..f04e584 100644 --- a/src/micetools/lib/libpcp/pcpt.c +++ b/src/micetools/lib/libpcp/pcpt.c @@ -30,7 +30,7 @@ e_pcpt_t pcptInitStream(pcpt_t *sock) { SOCKET s; if (sock == NULL) { - PCP_LOG("error PCP stream isn\'t set\n"); + amiDebugLog("error PCP stream isn't set"); return e_pcpt_pointer_unset; } @@ -61,7 +61,7 @@ e_pcpt_t pcptInitStream(pcpt_t *sock) { void pcptClose(pcpt_t *sock) { if (sock == NULL) { - PCP_LOG("error PCP stream isn\'t set\n"); + amiDebugLog("error PCP stream isn't set"); return; } @@ -100,7 +100,7 @@ void pcptClose(pcpt_t *sock) { void pcptCloseDataSock(pcpt_t *sock) { if (sock == NULL) { - PCP_LOG("error PCP stream isn\'t set\n"); + amiDebugLog("error PCP stream isn't set"); return; } if (sock->field_0x58 != 0) { @@ -118,7 +118,7 @@ void pcptCloseDataSock(pcpt_t *sock) { e_pcpt_t pcptAcceptServer(pcpt_t *stream, timeout_t timeout_ms) { if (stream == NULL) { - PCP_LOG("error PCP stream isn\'t set\n"); + amiDebugLog("error PCP stream isn't set"); return e_pcpt_pointer_unset; } @@ -158,7 +158,7 @@ e_pcpt_t pcptCheckConnectAble(pcpt_t *stream, timeout_t timeout_ms) { amtime_t start; if (stream == NULL) { - PCP_LOG("error PCP stream isn\'t set\n"); + amiDebugLog("error PCP stream isn't set"); return e_pcpt_pointer_unset; } amiTimerGet(&start); @@ -228,7 +228,7 @@ e_pcpt_t pcptCheckEvent(HANDLE event, timeout_t timeout_ms, SOCKET socket, uint if (timeout_ms == TIMEOUT_NONE) wait_timeout = TIMEOUT_NONE; if (event == NULL) { - PCP_LOG("Error : EVENT HANDLE error\n"); + amiDebugLog("Error : EVENT HANDLE error"); return e_pcpt_pointer_unset; } @@ -261,7 +261,7 @@ e_pcpt_t pcptCheckEvent(HANDLE event, timeout_t timeout_ms, SOCKET socket, uint e_pcpt_t pcptOpenDataSockServer(pcpt_t *sock, timeout_t timeout_ms) { if (sock == NULL) { - PCP_LOG("error PCP stream isn\'t set\n"); + amiDebugLog("error PCP stream isn't set"); return e_pcpt_pointer_unset; } if (sock->open == PCPT_CONNECTED) return e_pcpt_already_open; @@ -280,7 +280,7 @@ e_pcpt_t pcptOpenServer(pcpt_t *stream, int open_mode, ushort port) { e_pcpt_t err; if (stream == NULL) { - PCP_LOG("error PCP stream isn\'t set\n"); + amiDebugLog("error PCP stream isn't set"); return e_pcpt_pointer_unset; } @@ -296,8 +296,10 @@ e_pcpt_t pcptOpenServer(pcpt_t *stream, int open_mode, ushort port) { if (s == SOCKET_INVAL) return stream->err = _errW2T(GetLastError()); - uint reuseaddr = 1; - if (FAILED(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&reuseaddr, 4))) { + uint exclusiveAddr = 1; + // ! Note: The real libpcp uses SO_REUSEADDR here. + // ! We deviate from this, and instead use SO_EXCLUSIVEADDRUSE, as this is the correct flag. + if (FAILED(setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (void *)&exclusiveAddr, 4))) { err = _errW2T(GetLastError()); closesocket(stream->server_sock); stream->server_sock = SOCKET_INVAL; @@ -349,7 +351,7 @@ e_pcpt_t pcptOpenClient(pcpt_t *stream, char *ipAddr, ushort port, timeout_t tim pcpt = stream; if ((stream == NULL) || (ipAddr == NULL)) { - PCP_LOG("error PCP stream isn\'t set\n"); + amiDebugLog("error PCP stream isn't set"); return e_pcpt_pointer_unset; } if (stream->client_sock != 0xffffffff) { @@ -471,17 +473,17 @@ e_pcpt_t pcptRecv(pcpt_t *sock, unsigned char *recv_buf, size_t *recv_buf_len, amtime_t start; if (sock == NULL || recv_buf == NULL || recv_buf_len == NULL) { - PCP_LOG("error PCP stream isn\'t set\n"); + amiDebugLog("error PCP stream isn't set"); return e_pcpt_pointer_unset; } if (sock->open == PCPT_CLOSED) { - PCP_LOG("error PCP not open\n"); + amiDebugLog("error PCP not open"); 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"); + amiDebugLog("error PCP already connected"); return sock->err = e_pcpt_already_connected; } @@ -540,16 +542,16 @@ e_pcpt_t pcptSend(pcpt_t *sock, unsigned char *send_buf, size_t *send_len, uint amtime_t start_time; if (sock == NULL || send_buf == NULL || send_len == NULL) { - PCP_LOG("error PCP stream isn\'t set\n"); + amiDebugLog("error PCP stream isn't set"); return e_pcpt_pointer_unset; } if (sock->open == PCPT_CLOSED) { - PCP_LOG("error PCP not open\n"); + amiDebugLog("error PCP not open"); return sock->err = e_pcpt_not_open; } if (sock->client_open != 0) { - PCP_LOG("error PCP already connected\n"); + amiDebugLog("error PCP already connected"); return sock->err = e_pcpt_already_connected; } @@ -600,12 +602,12 @@ e_pcpt_t pcptSendAllMsg(pcpt_t *sock, timeout_t timeout_ms) { amtime_t start; if (sock == NULL) { - PCP_LOG("error PCP stream isn\'t set\n"); + amiDebugLog("error PCP stream isn't set"); return e_pcpt_pointer_unset; } if (sock->send_buf == NULL || sock->send_buf_count == NULL) { - PCP_LOG("error send buffer isn\'t set\n"); + amiDebugLog("error send buffer isn't set"); return e_pcpt_pointer_unset; } @@ -662,7 +664,7 @@ e_pcpt_t pcptSendAllMsg(pcpt_t *sock, timeout_t timeout_ms) { void pcptSetConfig(pcpt_t *stream, uint config, uint value) { if (stream == NULL) { - PCP_LOG("error don\'t set stream\n"); + amiDebugLog("error don't set stream"); return; } @@ -701,7 +703,7 @@ e_pcpt_t pcptIsBusy(pcpt_t *sock, timeout_t timeout_ms) { timeout_ms_00 = timeout_ms; if (sock == NULL) { - PCP_LOG("error PCP stream isn\'t set\n"); + amiDebugLog("error PCP stream isn't set"); return e_pcpt_pointer_unset; } switch (sock->client_open) { @@ -872,7 +874,7 @@ e_pcpt_t pcptIsBusy(pcpt_t *sock, timeout_t timeout_ms) { sock->client_open = 0; if (eVar8 != e_pcpt_ok) goto LAB_0045997d; if (sock->recv_buf == NULL || sock->recv_buf_count == NULL) { - PCP_LOG("error Recv buffer isn\'t set\n"); + amiDebugLog("error Recv buffer isn't set"); return sock->err = e_pcpt_recv_unset; } size_t received = diff --git a/src/micetools/lib/mice/config.def b/src/micetools/lib/mice/config.def index a49955c..28cb874 100644 --- a/src/micetools/lib/mice/config.def +++ b/src/micetools/lib/mice/config.def @@ -12,8 +12,10 @@ COMMENT("The main config file for micetools") COMMENT("") SECTION(mice, "General mice settings") +COMMENT("Trace logging (6) is intensive, and should only be used when debugging") CFG_int(mice, log_level, 4, "1 = Game\n2 = Error\n3 = Warning\n4 = Info\n5 = Misc\n6 = Trace") CFG_bool(mice, log_to_file, false, "Also log out to log_file") +CFG_int(mice, file_log_level, 5, "1 = Game\n2 = Error\n3 = Warning\n4 = Info\n5 = Misc\n6 = Trace") CFG_str(mice, log_file, "log.txt", "The file to log to if log_to_file is enabled") CFG_bool(mice, apply_patches, true, "Load and apply patches from patches_file at runtime") CFG_str(mice, patches_file, "patches.index", "The file to read patches from") diff --git a/src/micetools/dll/util/log.c b/src/micetools/lib/mice/log.c similarity index 83% rename from src/micetools/dll/util/log.c rename to src/micetools/lib/mice/log.c index f1f0e51..6efb953 100644 --- a/src/micetools/dll/util/log.c +++ b/src/micetools/lib/mice/log.c @@ -1,234 +1,239 @@ -#include "log.h" - -#include -#include -#include -#include -#include -#pragma comment(lib, "DbgHelp.lib") - -#include "../../lib/mice/config.h" -#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; - -extern BOOL(WINAPI* TrueWriteFile)(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, - LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped); - -BOOL HAS_COLOUR = FALSE; - -char _log_prelude[64]; -char* log_prelude() { - time_t rawtime; - struct tm timeinfo; - - time(&rawtime); - localtime_s(&timeinfo, &rawtime); - - strftime(_log_prelude, sizeof _log_prelude, "[%Y/%m/%d %H:%M:%S] ", &timeinfo); - return _log_prelude; -} - -static HANDLE log_file = NULL; -CRITICAL_SECTION logger_lock; - -static char* log_colours[] = { - "", // Always - "\033[96m", // Game - "\033[91m", // Error - "\033[33m", // Warning - "\033[97m", // Info - "\033[90m", // Misc - "\033[90m", // Trace -}; -static const char* COLOR_RESET = "\033[0m"; -#define LOG_PREFIXES "!GEWIMT" - -void logcb(LPCSTR param_1) { log_game(plfAmLog, "%s", param_1); } -void __stdcall amLogCallback(DWORD level, char* format) { - if (level == 0) - log_game(plfAmLog, "E:%s", format); - else if (level == 0) - log_game(plfAmLog, "W:%s", format); - else - log_game(plfAmLog, "I:%s", format); -} - -DWORD pLogcb; -DWORD* ppLogcb; - -static char log_buf[1024]; -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); - *((DWORD*)(imageOffset + 0x004438e8)) = 0x00000000; - } - if (wcscmp(exeName, L"maimai_dump_.exe") == 0) { - *((DWORD*)(imageOffset + 0x00c820ec)) = 0x00000001; - pLogcb = (DWORD)(&amLogCallback); - ppLogcb = &pLogcb; - *((DWORD***)(imageOffset + 0x00c820F4)) = &ppLogcb; - // *((DWORD*)(imageOffset + 0x004438e8)) = (DWORD)(&logcb); - } - - char prefix = LOG_PREFIXES[log_level]; - - EnterCriticalSection(&logger_lock); - - 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, 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'; - - if (MiceConfig.mice.log_level >= log_level) { - HANDLE sout = GetStdHandle(STD_OUTPUT_HANDLE); - _WriteFile(sout, log_buf, log_len, NULL, NULL); - // FlushFileBuffers(sout); - } - - if (MiceConfig.mice.log_to_file) { - if (log_file && log_file != INVALID_HANDLE_VALUE) { - // Replace the colour reset with a newline, then skip the prefix when writing - log_buf[log_len - col_len] = '\n'; - log_buf[log_len - col_len + 1] = '\0'; - _WriteFile(log_file, log_buf + col_len, log_len - col_len - sizeof(COLOR_RESET), NULL, NULL); - } - } - - LeaveCriticalSection(&logger_lock); - return log_len; -} -int vlog_trace(PLOG_FACILITY facility, const char* format, va_list args) { - return _do_log(LOG_TRACE, facility, format, args); -} -int _log_trace(PLOG_FACILITY facility, const char* format, ...) { - va_list args; - va_start(args, format); - int ret = vlog_trace(facility, format, args); - va_end(args); - return ret; -} -int vlog_misc(PLOG_FACILITY facility, const char* format, va_list args) { - return _do_log(LOG_MISC, facility, format, args); -} -int _log_misc(PLOG_FACILITY facility, const char* format, ...) { - va_list args; - va_start(args, format); - int ret = vlog_misc(facility, format, args); - va_end(args); - return ret; -} -int vlog_info(PLOG_FACILITY facility, const char* format, va_list args) { - return _do_log(LOG_INFO, facility, format, args); -} -int _log_info(PLOG_FACILITY facility, const char* format, ...) { - va_list args; - va_start(args, format); - int ret = vlog_info(facility, format, args); - va_end(args); - return ret; -} -int vlog_warning(PLOG_FACILITY facility, const char* format, va_list args) { - return _do_log(LOG_WARNING, facility, format, args); -} -int _log_warning(PLOG_FACILITY facility, const char* format, ...) { - va_list args; - va_start(args, format); - int ret = vlog_warning(facility, format, args); - va_end(args); - return ret; -} -int vlog_error(PLOG_FACILITY facility, const char* format, va_list args) { - return _do_log(LOG_ERROR, facility, format, args); -} -int _log_error(PLOG_FACILITY facility, const char* format, ...) { - va_list args; - va_start(args, format); - int ret = vlog_error(facility, format, args); - va_end(args); - return ret; -} -int vlog_game(PLOG_FACILITY facility, const char* format, va_list args) { - return _do_log(LOG_GAME, facility, format, args); -} -int _log_game(PLOG_FACILITY facility, const char* format, ...) { - va_list args; - va_start(args, format); - int ret = vlog_game(facility, format, args); - va_end(args); - return ret; -} - -void setup_logging() { - // Force stdio even for GUI applications - // AttachConsole(ATTACH_PARENT_PROCESS); - - // Enable colour in CMD - HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); - DWORD dwMode = 0; - if (GetConsoleMode(hConsole, &dwMode)) - HAS_COLOUR = SetConsoleMode(hConsole, dwMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING); - - InitializeCriticalSection(&logger_lock); - - if (MiceConfig.mice.log_to_file) { - if (log_file == NULL && MiceConfig.mice.log_file[0] != '\0') - log_file = CreateFileA(MiceConfig.mice.log_file, GENERIC_WRITE, FILE_SHARE_READ, NULL, - CREATE_ALWAYS, 0, NULL); - } -} - -void log_stack(PLOG_FACILITY facility) { - char name[MAX_PATH * sizeof(TCHAR)]; - char Storage[sizeof(IMAGEHLP_SYMBOL64) + sizeof(name)]; - - IMAGEHLP_SYMBOL64* symbol = (IMAGEHLP_SYMBOL64*)Storage; - CONTEXT context; - RtlCaptureContext(&context); - - STACKFRAME64 stack = { 0 }; - stack.AddrPC.Offset = context.Eip; - stack.AddrPC.Mode = AddrModeFlat; - stack.AddrStack.Offset = context.Esp; - stack.AddrStack.Mode = AddrModeFlat; - stack.AddrFrame.Offset = context.Ebp; - stack.AddrFrame.Mode = AddrModeFlat; - - HANDLE process = GetCurrentProcess(); - HANDLE thread = GetCurrentThread(); - BOOL initres = SymInitialize(process, NULL, true); - for (ULONG frame = 0;; frame++) { - BOOL result = StackWalk64(IMAGE_FILE_MACHINE_I386, process, thread, &stack, &context, NULL, - SymFunctionTableAccess64, SymGetModuleBase64, NULL); - - symbol->SizeOfStruct = sizeof(Storage); - symbol->MaxNameLength = sizeof(name); - - DWORD64 displacement; - SymGetSymFromAddr64(process, (ULONG64)stack.AddrPC.Offset, &displacement, symbol); - UnDecorateSymbolName(symbol->Name, (PSTR)name, sizeof(name), UNDNAME_COMPLETE); - - log_error(facility, "%02u called from 0x%08X STACK=0x%08X FRAME=0x%08X %s", frame, - (ULONG64)stack.AddrPC.Offset, (ULONG64)stack.AddrStack.Offset, - (ULONG64)stack.AddrFrame.Offset, symbol->Name); - - if (result == FALSE) { - DWORD frameError = GetLastError(); - break; - } - } -} +#include "log.h" + +#include +#include +#include +#include +#include +#pragma comment(lib, "DbgHelp.lib") + +#include "config.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; + +extern BOOL(WINAPI* TrueWriteFile)(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, + LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped); + +BOOL HAS_COLOUR = FALSE; + +char _log_prelude[64]; +char* log_prelude() { + time_t rawtime; + struct tm timeinfo; + + time(&rawtime); + localtime_s(&timeinfo, &rawtime); + + strftime(_log_prelude, sizeof _log_prelude, "[%Y/%m/%d %H:%M:%S] ", &timeinfo); + return _log_prelude; +} + +static HANDLE log_file = INVALID_HANDLE_VALUE; +CRITICAL_SECTION logger_lock; + +static char* log_colours[] = { + "", // Always + "\033[96m", // Game + "\033[91m", // Error + "\033[33m", // Warning + "\033[97m", // Info + "\033[90m", // Misc + "\033[90m", // Trace +}; +static const char* COLOR_RESET = "\033[0m"; +#define LOG_PREFIXES "!GEWIMT" + +void logcb(LPCSTR param_1) { log_game(plfAmLog, "%s", param_1); } +void __stdcall amLogCallback(DWORD level, char* format) { + if (level == 0) + log_game(plfAmLog, "E:%s", format); + else if (level == 0) + log_game(plfAmLog, "W:%s", format); + else + log_game(plfAmLog, "I:%s", format); +} + +DWORD pLogcb; +DWORD* ppLogcb; + +static char log_buf[1024]; +int _do_log(BYTE log_level, PLOG_FACILITY facility, const char* format, va_list args) { + // Early-return if we have nothing to do + if (MiceConfig.mice.log_level < log_level && + (!MiceConfig.mice.log_to_file || MiceConfig.mice.file_log_level < log_level)) { + return 0; + } + + // TODO: These are all horrible bodges + // if (wcscmp(exeName, L"mxnetwork.exe") == 0) { + // // *((DWORD*)(imageOffset + 0x004438e8)) = (DWORD)(&logcb); + // *((DWORD*)(imageOffset + 0x004438e8)) = 0x00000000; + // } + // if (wcscmp(exeName, L"maimai_dump_.exe") == 0) { + // *((DWORD*)(imageOffset + 0x00c820ec)) = 0x00000001; + // pLogcb = (DWORD)(&amLogCallback); + // ppLogcb = &pLogcb; + // *((DWORD***)(imageOffset + 0x00c820F4)) = &ppLogcb; + // // *((DWORD*)(imageOffset + 0x004438e8)) = (DWORD)(&logcb); + // } + + char prefix = LOG_PREFIXES[log_level]; + + EnterCriticalSection(&logger_lock); + + 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, 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'; + + if (MiceConfig.mice.log_level >= log_level) { + HANDLE sout = GetStdHandle(STD_OUTPUT_HANDLE); + WriteFile(sout, log_buf, log_len, NULL, NULL); + // FlushFileBuffers(sout); + } + + if (MiceConfig.mice.log_to_file && MiceConfig.mice.file_log_level >= log_level) { + if (log_file && log_file != INVALID_HANDLE_VALUE) { + // Replace the colour reset with a newline, then skip the prefix when writing + log_buf[log_len - col_len] = '\n'; + log_buf[log_len - col_len + 1] = '\0'; + WriteFile(log_file, log_buf + col_len, log_len - col_len - sizeof(COLOR_RESET), NULL, + NULL); + } + } + + LeaveCriticalSection(&logger_lock); + return log_len; +} +int vlog_trace(PLOG_FACILITY facility, const char* format, va_list args) { + return _do_log(LOG_TRACE, facility, format, args); +} +int _log_trace(PLOG_FACILITY facility, const char* format, ...) { + va_list args; + va_start(args, format); + int ret = vlog_trace(facility, format, args); + va_end(args); + return ret; +} +int vlog_misc(PLOG_FACILITY facility, const char* format, va_list args) { + return _do_log(LOG_MISC, facility, format, args); +} +int _log_misc(PLOG_FACILITY facility, const char* format, ...) { + va_list args; + va_start(args, format); + int ret = vlog_misc(facility, format, args); + va_end(args); + return ret; +} +int vlog_info(PLOG_FACILITY facility, const char* format, va_list args) { + return _do_log(LOG_INFO, facility, format, args); +} +int _log_info(PLOG_FACILITY facility, const char* format, ...) { + va_list args; + va_start(args, format); + int ret = vlog_info(facility, format, args); + va_end(args); + return ret; +} +int vlog_warning(PLOG_FACILITY facility, const char* format, va_list args) { + return _do_log(LOG_WARNING, facility, format, args); +} +int _log_warning(PLOG_FACILITY facility, const char* format, ...) { + va_list args; + va_start(args, format); + int ret = vlog_warning(facility, format, args); + va_end(args); + return ret; +} +int vlog_error(PLOG_FACILITY facility, const char* format, va_list args) { + return _do_log(LOG_ERROR, facility, format, args); +} +int _log_error(PLOG_FACILITY facility, const char* format, ...) { + va_list args; + va_start(args, format); + int ret = vlog_error(facility, format, args); + va_end(args); + return ret; +} +int vlog_game(PLOG_FACILITY facility, const char* format, va_list args) { + return _do_log(LOG_GAME, facility, format, args); +} +int _log_game(PLOG_FACILITY facility, const char* format, ...) { + va_list args; + va_start(args, format); + int ret = vlog_game(facility, format, args); + va_end(args); + return ret; +} + +void setup_logging() { + // Force stdio even for GUI applications + // AttachConsole(ATTACH_PARENT_PROCESS); + + // Enable colour in CMD + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD dwMode = 0; + if (GetConsoleMode(hConsole, &dwMode)) + HAS_COLOUR = SetConsoleMode(hConsole, dwMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING); + + InitializeCriticalSection(&logger_lock); + + if (MiceConfig.mice.log_to_file) { + if (log_file == INVALID_HANDLE_VALUE && MiceConfig.mice.log_file[0] != '\0') + log_file = CreateFileA(MiceConfig.mice.log_file, GENERIC_WRITE, FILE_SHARE_READ, NULL, + CREATE_ALWAYS, 0, NULL); + } +} + +void log_stack(PLOG_FACILITY facility) { + char name[MAX_PATH * sizeof(TCHAR)]; + char Storage[sizeof(IMAGEHLP_SYMBOL64) + sizeof(name)]; + + IMAGEHLP_SYMBOL64* symbol = (IMAGEHLP_SYMBOL64*)Storage; + CONTEXT context; + RtlCaptureContext(&context); + + STACKFRAME64 stack = { 0 }; + stack.AddrPC.Offset = context.Eip; + stack.AddrPC.Mode = AddrModeFlat; + stack.AddrStack.Offset = context.Esp; + stack.AddrStack.Mode = AddrModeFlat; + stack.AddrFrame.Offset = context.Ebp; + stack.AddrFrame.Mode = AddrModeFlat; + + HANDLE process = GetCurrentProcess(); + HANDLE thread = GetCurrentThread(); + BOOL initres = SymInitialize(process, NULL, true); + for (ULONG frame = 0;; frame++) { + BOOL result = StackWalk64(IMAGE_FILE_MACHINE_I386, process, thread, &stack, &context, NULL, + SymFunctionTableAccess64, SymGetModuleBase64, NULL); + + symbol->SizeOfStruct = sizeof(Storage); + symbol->MaxNameLength = sizeof(name); + + DWORD64 displacement; + SymGetSymFromAddr64(process, (ULONG64)stack.AddrPC.Offset, &displacement, symbol); + UnDecorateSymbolName(symbol->Name, (PSTR)name, sizeof(name), UNDNAME_COMPLETE); + + log_error(facility, "%02u called from 0x%08X STACK=0x%08X FRAME=0x%08X %s", frame, + (ULONG64)stack.AddrPC.Offset, (ULONG64)stack.AddrStack.Offset, + (ULONG64)stack.AddrFrame.Offset, symbol->Name); + + if (result == FALSE) { + DWORD frameError = GetLastError(); + break; + } + } +} diff --git a/src/micetools/dll/util/log.h b/src/micetools/lib/mice/log.h similarity index 96% rename from src/micetools/dll/util/log.h rename to src/micetools/lib/mice/log.h index 7d1cc89..375d79b 100644 --- a/src/micetools/dll/util/log.h +++ b/src/micetools/lib/mice/log.h @@ -1,80 +1,80 @@ -#pragma once - -#include -#include - -#define LOG_GAME 1 -#define LOG_ERROR 2 -#define LOG_WARNING 3 -#define LOG_INFO 4 -#define LOG_MISC 5 -#define LOG_TRACE 6 - -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(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(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(PLOG_FACILITY facility); - -void setup_logging(); - -// Disable some logging entirely at build time for speed -#define COMPILE_LOG_LEVEL 6 - -#if COMPILE_LOG_LEVEL >= 6 -#define log_trace _log_trace -#else -#define log_trace(...) -#endif - -#if COMPILE_LOG_LEVEL >= 5 -#define log_misc _log_misc -#else -#define log_misc(...) -#endif - -#if COMPILE_LOG_LEVEL >= 4 -#define log_info _log_info -#else -#define log_info(...) -#endif - -#if COMPILE_LOG_LEVEL >= 3 -#define log_warning _log_warning -#else -#define log_warning(...) -#endif - -#if COMPILE_LOG_LEVEL >= 2 -#define log_error _log_error -#else -#define log_error(...) -#endif - -#if COMPILE_LOG_LEVEL >= 1 -#define log_game _log_game -#else -#define log_game(...) -#endif +#pragma once + +#include +#include + +#define LOG_GAME 1 +#define LOG_ERROR 2 +#define LOG_WARNING 3 +#define LOG_INFO 4 +#define LOG_MISC 5 +#define LOG_TRACE 6 + +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(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(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(PLOG_FACILITY facility); + +void setup_logging(); + +// Disable some logging entirely at build time for speed +#define COMPILE_LOG_LEVEL 6 + +#if COMPILE_LOG_LEVEL >= 6 +#define log_trace _log_trace +#else +#define log_trace(...) +#endif + +#if COMPILE_LOG_LEVEL >= 5 +#define log_misc _log_misc +#else +#define log_misc(...) +#endif + +#if COMPILE_LOG_LEVEL >= 4 +#define log_info _log_info +#else +#define log_info(...) +#endif + +#if COMPILE_LOG_LEVEL >= 3 +#define log_warning _log_warning +#else +#define log_warning(...) +#endif + +#if COMPILE_LOG_LEVEL >= 2 +#define log_error _log_error +#else +#define log_error(...) +#endif + +#if COMPILE_LOG_LEVEL >= 1 +#define log_game _log_game +#else +#define log_game(...) +#endif diff --git a/src/micetools/dll/util/log_facilities.def b/src/micetools/lib/mice/log_facilities.def similarity index 96% rename from src/micetools/dll/util/log_facilities.def rename to src/micetools/lib/mice/log_facilities.def index 7ac4c86..58bb624 100644 --- a/src/micetools/dll/util/log_facilities.def +++ b/src/micetools/lib/mice/log_facilities.def @@ -29,6 +29,7 @@ _LF(Devices, PCA9535, "pca9535") _LF(Devices, Eeprom, "eeprom") _LF(Devices, MaiTouch, "maitouch") _LF(Devices, MaiLED, "mailed") +_LF(Devices, Servo15069, "servo15069") _LF(Drivers, Columba, "columba") _LF(Drivers, MxJvs, "mxjvs") diff --git a/src/micetools/lib/mice/meson.build b/src/micetools/lib/mice/meson.build index ea3be91..7510a98 100644 --- a/src/micetools/lib/mice/meson.build +++ b/src/micetools/lib/mice/meson.build @@ -2,6 +2,7 @@ mice_lib = static_library( 'mice', sources: [ 'exe.c', + 'log.c', 'patch.c', 'ringbuf.c', 'config.c', diff --git a/src/micetools/lib/mice/mice.h b/src/micetools/lib/mice/mice.h index 9af4bb0..a74d37d 100644 --- a/src/micetools/lib/mice/mice.h +++ b/src/micetools/lib/mice/mice.h @@ -3,11 +3,12 @@ #include #include -#include "config.h" #include "../am/am.h" #include "../ami/ami.h" +#include "config.h" #include "exe.h" #include "ioctl.h" +#include "log.h" #include "patch.h" #include "ringbuf.h" #include "version_fallback.h" diff --git a/src/micetools/lib/mxk/mxkAb.c b/src/micetools/lib/mxk/mxkAb.c index c78c73b..ba622c5 100644 --- a/src/micetools/lib/mxk/mxkAb.c +++ b/src/micetools/lib/mxk/mxkAb.c @@ -103,7 +103,7 @@ MXK_STATUS mxkAbGameId(MXK_CACHE cache, char* gameId, unsigned char* err) { AppBoot.m_cacheDirty = true; } - MXK_STATUS status; + MXK_STATUS status = MXK_STATUS_ERROR; if (!AppBoot.m_useFlash) { // if (HAS_N2 == true) { // status = mxkGetKeychipIdFromN2(); diff --git a/src/micetools/micekeychip/callbacks/callbacks.h b/src/micetools/micekeychip/callbacks/callbacks.h index 6bbf560..31c62d7 100644 --- a/src/micetools/micekeychip/callbacks/callbacks.h +++ b/src/micetools/micekeychip/callbacks/callbacks.h @@ -25,7 +25,7 @@ pcpa_callback mxkPcpStatus; pcpa_callback mxkPcpDsCompute; pcpa_callback mxkPcpSsdProof; pcpa_callback mxkPcpSsdHostProof; -pcpa_callback mkxPcpEncrypt; +pcpa_callback mxkPcpEncrypt; pcpa_callback mxkPcpDecrypt; pcpa_callback mxkPcpSetIv; diff --git a/src/micetools/micekeychip/callbacks/crypto.c b/src/micetools/micekeychip/callbacks/crypto.c index 530fa8a..17ce534 100644 --- a/src/micetools/micekeychip/callbacks/crypto.c +++ b/src/micetools/micekeychip/callbacks/crypto.c @@ -3,7 +3,7 @@ void mxkPcpDsCompute(pcpa_t* stream, void* data) { pcpaSetSendPacket(stream, "code", "54"); } void mxkPcpSsdProof(pcpa_t* stream, void* data) { pcpaSetSendPacket(stream, "code", "54"); } void mxkPcpSsdHostProof(pcpa_t* stream, void* data) {} -void mkxPcpEncrypt(pcpa_t* stream, void* data) { +void mxkPcpEncrypt(pcpa_t* stream, void* data) { pcpaSetSendPacket(stream, KC_ENCRYPT, "B6787E941C3956EAC70095D6A91E635C"); } void mxkPcpDecrypt(pcpa_t* stream, void* data) { diff --git a/src/micetools/micekeychip/config.c b/src/micetools/micekeychip/config.c new file mode 100644 index 0000000..f77e84b --- /dev/null +++ b/src/micetools/micekeychip/config.c @@ -0,0 +1,87 @@ +#include "mxk.h" + +config_t Config = { +#define CFG_str(s, n, default, comment) .s##_##n = default, +#define CFG_bool(s, n, default, comment) .s##_##n = default, +#define CFG_int(s, n, default, comment) .s##_##n = default, +#define CFG_hex(s, n, precision, default, comment) .s##_##n = 0x##default, +#include "config.def" + ._keep_linter_happy = true +}; + +void mxkMakeDefaultConfig() { + FILE *config_file; + fopen_s(&config_file, CONFIG_PATH, "w"); + if (config_file == NULL) { + puts("Failed to create config file!"); + return; + }; + int first_section = true; + +#define CFG_str(s, n, default, comment) \ + if (strlen(comment) != 0) fprintf(config_file, "; %s\n", comment); \ + fprintf(config_file, "; (string) default = %s\n", default); \ + fprintf(config_file, "%s = %s\n", #n, default); + +#define CFG_bool(s, n, default, comment) \ + if (strlen(comment) != 0) fprintf(config_file, "; %s\n", comment); \ + fprintf(config_file, "; (bool) default = %s\n", default ? "true" : "false"); \ + fprintf(config_file, "%s = %s\n", #n, default ? "true" : "false"); + +#define CFG_int(s, n, default, comment) \ + if (strlen(comment) != 0) fprintf(config_file, "; %s\n", comment); \ + fprintf(config_file, "; (int) default = %d\n", default); \ + fprintf(config_file, "%s = %d\n", #n, default); + +#define CFG_hex(s, n, precision, default, comment) \ + if (strlen(comment) != 0) fprintf(config_file, "; %s\n", comment); \ + fprintf(config_file, "; (hex) default = %.*X\n", precision, 0x##default); \ + fprintf(config_file, "%s = %.*X\n", #n, precision, 0x##default); + +#define SECTION(s, comment) \ + if (!first_section) fprintf(config_file, "\n"); \ + first_section = false; \ + if (strlen(comment) != 0) fprintf(config_file, "; %s\n", comment); \ + fprintf(config_file, "[%s]\n", #s); + +#define HEADER(comment) \ + fprintf(config_file, "; %s\n", comment); \ + first_section = false; + +#include "config.def" + + fclose(config_file); +} + +static int handler(void *user, const char *section, const char *name, const char *value) { + config_t *cfg = (config_t *)user; + + char *end; + + if (false) + ; +#define CFG_str(s, n, default, comment) \ + else if (_stricmp(section, #s) == 0 && _stricmp(name, #n) == 0) cfg->s##_##n = _strdup(value); +#define CFG_bool(s, n, default, comment) \ + else if (_stricmp(section, #s) == 0 && _stricmp(name, #n) == 0) cfg->s##_##n = \ + strcmp(value, "true") == 0; +#define CFG_int(s, n, default, comment) \ + else if (_stricmp(section, #s) == 0 && _stricmp(name, #n) == 0) { \ + cfg->s##_##n = strtol(value, &end, 10); \ + if (end == value || *end != '\0' || errno == ERANGE) cfg->s##_##n = default; \ + } +#define CFG_hex(s, n, precision, default, comment) \ + else if (_stricmp(section, #s) == 0 && _stricmp(name, #n) == 0) { \ + cfg->s##_##n = strtol(value, &end, 16); \ + if (end == value || *end != '\0' || errno == ERANGE) cfg->s##_##n = 0x##default; \ + } + +#include "config.def" + + return 1; +} + +void mxkLoadConfig() { + if (ini_parse(CONFIG_PATH, handler, &Config) < 0) + printf("Can't load '%s', using defaults\n", CONFIG_PATH); +} diff --git a/src/micetools/micekeychip/config.def b/src/micetools/micekeychip/config.def index 0d4efca..2c5bbef 100644 --- a/src/micetools/micekeychip/config.def +++ b/src/micetools/micekeychip/config.def @@ -21,7 +21,7 @@ SECTION(appboot, "") CFG_str(appboot, gameid, "SDEY", "4-letter game ID this keychip is for") CFG_hex(appboot, systemflag, 2, 6C, "System flags") CFG_int(appboot, modeltype, 2, "System model this keychip is for") -CFG_int(appboot, formattype, 1, "Not totally sure about this") +CFG_int(appboot, formattype, 1, "") CFG_int(appboot, region, 1, "Region bitmask\n; 8 4 2 1\n; CN EX US JP") CFG_str(appboot, platformid, "AAS", "The platform this keychip is for. AAM=AMD, AAS=Nvidia") CFG_str(appboot, network, "192.168.103.0", "The subnet this keychip allows for networking. Must be 192.168.103.0 for network checks to pass") diff --git a/src/micetools/micekeychip/config.h b/src/micetools/micekeychip/config.h index 139bd57..85fa180 100644 --- a/src/micetools/micekeychip/config.h +++ b/src/micetools/micekeychip/config.h @@ -12,3 +12,6 @@ typedef struct config { } config_t; extern config_t Config; + +void mxkMakeDefaultConfig(); +void mxkLoadConfig(); diff --git a/src/micetools/micekeychip/main.c b/src/micetools/micekeychip/main.c index 87558a0..366f51c 100644 --- a/src/micetools/micekeychip/main.c +++ b/src/micetools/micekeychip/main.c @@ -1,106 +1,5 @@ #include "mxk.h" -config_t Config = { -#define CFG_str(s, n, default, comment) .s##_##n = default, -#define CFG_bool(s, n, default, comment) .s##_##n = default, -#define CFG_int(s, n, default, comment) .s##_##n = default, -#define CFG_hex(s, n, precision, default, comment) .s##_##n = 0x##default, -#include "config.def" - ._keep_linter_happy = true}; - -static void make_default_config() { - FILE *config_file; - fopen_s(&config_file, CONFIG_PATH, "w"); - if (config_file == NULL) { - puts("Failed to create config file!"); - return; - }; - int first_section = true; - -#define CFG_str(s, n, default, comment) \ - if (strlen(comment) != 0) fprintf(config_file, "; %s\n", comment); \ - fprintf(config_file, "; (string) default = %s\n", default); \ - fprintf(config_file, "%s = %s\n", #n, default); - -#define CFG_bool(s, n, default, comment) \ - if (strlen(comment) != 0) fprintf(config_file, "; %s\n", comment); \ - fprintf(config_file, "; (bool) default = %s\n", default ? "true" : "false"); \ - fprintf(config_file, "%s = %s\n", #n, default ? "true" : "false"); - -#define CFG_int(s, n, default, comment) \ - if (strlen(comment) != 0) fprintf(config_file, "; %s\n", comment); \ - fprintf(config_file, "; (int) default = %d\n", default); \ - fprintf(config_file, "%s = %d\n", #n, default); - -#define CFG_hex(s, n, precision, default, comment) \ - if (strlen(comment) != 0) fprintf(config_file, "; %s\n", comment); \ - fprintf(config_file, "; (hex) default = %.*X\n", precision, 0x##default); \ - fprintf(config_file, "%s = %.*X\n", #n, precision, 0x##default); - -#define SECTION(s, comment) \ - if (!first_section) fprintf(config_file, "\n"); \ - first_section = false; \ - if (strlen(comment) != 0) fprintf(config_file, "; %s\n", comment); \ - fprintf(config_file, "[%s]\n", #s); - -#define HEADER(comment) \ - fprintf(config_file, "; %s\n", comment); \ - first_section = false; - -#include "config.def" - - fclose(config_file); -} - -static int handler(void *user, const char *section, const char *name, const char *value) { - config_t *cfg = (config_t *)user; - - char *end; - - if (false) - ; -#define CFG_str(s, n, default, comment) \ - else if (_stricmp(section, #s) == 0 && _stricmp(name, #n) == 0) cfg->s##_##n = _strdup(value); -#define CFG_bool(s, n, default, comment) \ - else if (_stricmp(section, #s) == 0 && _stricmp(name, #n) == 0) cfg->s##_##n = strcmp(value, "true") == 0; -#define CFG_int(s, n, default, comment) \ - else if (_stricmp(section, #s) == 0 && _stricmp(name, #n) == 0) { \ - cfg->s##_##n = strtol(value, &end, 10); \ - if (end == value || *end != '\0' || errno == ERANGE) cfg->s##_##n = default; \ - } -#define CFG_hex(s, n, precision, default, comment) \ - else if (_stricmp(section, #s) == 0 && _stricmp(name, #n) == 0) { \ - cfg->s##_##n = strtol(value, &end, 16); \ - if (end == value || *end != '\0' || errno == ERANGE) cfg->s##_##n = 0x##default; \ - } - -#include "config.def" - - return 1; -} - -void load_config() { - if (ini_parse(CONFIG_PATH, handler, &Config) < 0) printf("Can't load '%s', using defaults\n", CONFIG_PATH); -} - -int mxkMain() { - DWORD dwAttrib = GetFileAttributes(CONFIG_PATH); - if (dwAttrib == INVALID_FILE_ATTRIBUTES || (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) make_default_config(); - - load_config(); - - int err = mxkInit(); - if (err != 0) { - PCP_LOG("Error mxkInit. Code %d\n", err); - return -1; - } - - while (1) { - err = mxkPcpServer(); - if (err != e_pcpp_ok) PCP_LOG("Server tick: %d\n", err); - } -} - int main() { return mxkMain(); } diff --git a/src/micetools/micekeychip/meson.build b/src/micetools/micekeychip/meson.build index dcb2e67..27eab29 100644 --- a/src/micetools/micekeychip/meson.build +++ b/src/micetools/micekeychip/meson.build @@ -4,8 +4,8 @@ link_with = [inih.get_variable('lib_inih'), libpcp] rc = import('windows').compile_resources('micekeychip.rc', depend_files: micekeychip_ico) sources = [ - 'main.c', 'mxk.c', + 'config.c', 'callbacks/appboot.c', 'callbacks/billing.c', 'callbacks/crypto.c', @@ -22,7 +22,7 @@ mxk = static_library( executable( 'micekeychip', win_subsystem: subsystem, - sources: sources, + sources: sources + ['main.c'], link_with: link_with, dependencies: dependencies, ) diff --git a/src/micetools/micekeychip/mxk.c b/src/micetools/micekeychip/mxk.c index d0305e4..d5a661c 100644 --- a/src/micetools/micekeychip/mxk.c +++ b/src/micetools/micekeychip/mxk.c @@ -7,7 +7,7 @@ pcpa_cb_table_t CALLBACK_FUNCTION_BUFFER[40]; byte BINARY_DATA[4096]; size_t BINARY_DATA_LEN; -void mxkBinaryCallback(pcpa_t* stream, void* data) { +void mxkBinaryCallback(pcpa_t *stream, void *data) { pcpaSetSendBinaryBuffer(stream, BINARY_DATA, BINARY_DATA_LEN); } @@ -24,11 +24,11 @@ int mxkInit() { return err; } -void log_callback(struct pcpa* stream, void* data) { - FILE* log_file; +void log_callback(struct pcpa *stream, void *data) { + FILE *log_file; fopen_s(&log_file, "pcp.log", "a"); if (log_file != NULL) { - fprintf(log_file, "%s\n", (char*)data); + fprintf(log_file, "%s\n", (char *)data); fclose(log_file); } } @@ -38,7 +38,7 @@ e_pcpa_t mxkPcpStreamInit() { err = pcpaInitStream(&PCP); if (err != e_pcpa_ok) { - printf("pcpaInitStream Error. Code:%d\n", err); + amiDebugLog("pcpaInitStream Error. Code:%d", err); return err; } PCP.before_cb = log_callback; @@ -47,7 +47,7 @@ e_pcpa_t mxkPcpStreamInit() { &PCP, CALLBACK_FUNCTION_BUFFER, (sizeof CALLBACK_FUNCTION_BUFFER) / (sizeof CALLBACK_FUNCTION_BUFFER[0])); if (err != e_pcpa_ok) { - printf("pcpaSetCallBackFuncBuffer Error. Code:%d\n", err); + amiDebugLog("pcpaSetCallBackFuncBuffer Error. Code:%d", err); return err; } @@ -58,7 +58,7 @@ e_pcpa_t mxkPcpStreamInit() { pcpaSetCallbackFunc(&PCP, DS_COMPUTE, mxkPcpDsCompute, NULL); pcpaSetCallbackFunc(&PCP, SSD_PROOF, mxkPcpSsdProof, NULL); pcpaSetCallbackFunc(&PCP, SSD_HOSTPROOF, mxkPcpSsdHostProof, NULL); - pcpaSetCallbackFunc(&PCP, KC_ENCRYPT, mkxPcpEncrypt, NULL); + pcpaSetCallbackFunc(&PCP, KC_ENCRYPT, mxkPcpEncrypt, NULL); pcpaSetCallbackFunc(&PCP, KC_DECRYPT, mxkPcpDecrypt, NULL); pcpaSetCallbackFunc(&PCP, KC_SETIV, mxkPcpSetIv, NULL); // Appboot @@ -100,12 +100,12 @@ e_pcpa_t mxkPcpStreamInit() { long text_port = Config.pcp_control_port; if (text_port > 0xffff) { - puts("PCP control port invalid"); + amiDebugLog("PCP control port invalid"); exit(-1); } long binary_port = Config.pcp_binary_port; if (binary_port > 0xffff) { - puts("PCP binary port invalid"); + amiDebugLog("PCP binary port invalid"); exit(-1); } int open_mode = Config.pcp_bind_global ? OPEN_MODE_GLOBAL : OPEN_MODE_LOCAL; @@ -113,13 +113,13 @@ e_pcpa_t mxkPcpStreamInit() { err = pcpaOpenServerWithBinary(&PCP, open_mode, text_port & 0xffff, binary_port & 0xffff, 300000); if (err != e_pcpa_ok && err != e_pcpa_to) { - printf("pcpaOpenServerWithBinary Error. Code %d\n", err); + amiDebugLog("pcpaOpenServerWithBinary Error. Code %d", err); return e_pcpa_not_open; } if (open_mode == OPEN_MODE_GLOBAL) - printf("Listening on 0.0.0.0:%d (:%d)\n", text_port & 0xffff, binary_port & 0xffff); + amiDebugLog("Listening on 0.0.0.0:%d (:%d)", text_port & 0xffff, binary_port & 0xffff); else - printf("Listening on 127.0.0.1:%d (:%d)\n", text_port & 0xffff, binary_port & 0xffff); + amiDebugLog("Listening on 127.0.0.1:%d (:%d)", text_port & 0xffff, binary_port & 0xffff); return e_pcpa_ok; } @@ -147,7 +147,7 @@ e_pcpa_t mxkPcpServer() { if (err == e_pcpa_to || err == e_pcpa_closed) err = e_pcpa_ok; if (err) { - printf("Error pcpaServer. Code %d\n", err); + amiDebugLog("Error pcpaServer. Code %d", err); pcpaClose(&PCP); SERVER_STATE = 1; } @@ -160,4 +160,23 @@ e_pcpa_t mxkPcpServer() { #endif return err; -} \ No newline at end of file +} + +int mxkMain(void) { + DWORD dwAttrib = GetFileAttributes(CONFIG_PATH); + if (dwAttrib == INVALID_FILE_ATTRIBUTES || (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) + mxkMakeDefaultConfig(); + + mxkLoadConfig(); + + int err = mxkInit(); + if (err != 0) { + amiDebugLog("Error mxkInit. Code %d", err); + return -1; + } + + while (1) { + err = mxkPcpServer(); + if (err != e_pcpp_ok) amiDebugLog("Server tick: %d", err); + } +} diff --git a/src/micetools/micekeychip/mxk.h b/src/micetools/micekeychip/mxk.h index fd8de74..0cb0db4 100644 --- a/src/micetools/micekeychip/mxk.h +++ b/src/micetools/micekeychip/mxk.h @@ -9,3 +9,4 @@ void mxkBinaryCallback(pcpa_t* stream, void* data); int mxkInit(); e_pcpa_t mxkPcpStreamInit(); e_pcpa_t mxkPcpServer(); +int mxkMain(void); diff --git a/src/micetools/system_dummy/dummykeychip/callbacks-crypto.c b/src/micetools/system_dummy/dummykeychip/callbacks-crypto.c new file mode 100644 index 0000000..7823c3b --- /dev/null +++ b/src/micetools/system_dummy/dummykeychip/callbacks-crypto.c @@ -0,0 +1,100 @@ +#include +#include + +#include "../../lib/util/hex.h" +#include "callbacks.h" + +// dummykeychip is not intended to be used in a production system. Therefore, we need only pick +// values here that will allow us to run game data. The only game I have observed requiring specific +// encryption and decryption results is Border Break, and as such those are the keys loaded here. If +// other games end up doing this, a more thorough alternative will be implemented. +static const unsigned char seed[16] = { 0xdb, 0x86, 0x37, 0x3a, 0x5a, 0x2e, 0x05, 0xb9, + 0x63, 0xc2, 0x82, 0xd7, 0x89, 0x12, 0x8d, 0x0d }; +static const unsigned char key[16] = { 0x6a, 0xcb, 0x8d, 0xc9, 0x00, 0x49, 0x92, 0x7a, + 0xea, 0xcf, 0x71, 0xc9, 0x74, 0x0b, 0x6f, 0xf9 }; +static const unsigned char iv[16] = { 0xa4, 0x7a, 0x66, 0x8e, 0xc0, 0xda, 0x67, 0x5e, + 0x10, 0xe3, 0xa3, 0xeb, 0xe5, 0x32, 0x8c, 0xf0 }; + +EVP_CIPHER_CTX* ctxEnc = NULL; +EVP_CIPHER_CTX* ctxDec = NULL; + +void mdkPcpAbSeed(pcpa_t* stream, void* data) { + pcpaSetBinaryMode(stream, binary_mode_send); + pcpaSetSendBinaryBuffer(stream, seed, 16); + pcpaSetSendPacket(stream, AB_SEED, "0"); + pcpaAddSendPacket(stream, "port", "40107"); + pcpaAddSendPacket(stream, "size", "16"); +} +void mdkPcpDsCompute(pcpa_t* stream, void* data) { + // TODO: We could, and maybe should, scan for %s_Table.dat files, and use one if we find it + pcpaSetSendPacket(stream, DS_COMPUTE, ""); + pcpaAddSendPacket(stream, "code", "54"); +} +void mdkPcpSsdProof(pcpa_t* stream, void* data) { + pcpaSetSendPacket(stream, SSD_PROOF, "0"); + pcpaAddSendPacket(stream, "code", "54"); +} +void mdkPcpSsdHostProof(pcpa_t* stream, void* data) { + pcpaSetSendPacket(stream, SSD_HOSTPROOF, "0"); + pcpaAddSendPacket(stream, "code", "54"); +} +void mdkPcpEncrypt(pcpa_t* stream, void* data) { + char* ptHex = pcpaGetCommand(stream, KC_ENCRYPT); + unsigned char pt[16]; + memset(pt, 0, sizeof(pt)); + hex_to_bin(ptHex, pt, strlen(ptHex) > 32 ? 32 : strlen(ptHex)); + + if (ctxEnc == NULL) { + ctxEnc = EVP_CIPHER_CTX_new(); + EVP_CipherInit_ex(ctxEnc, EVP_aes_128_cbc(), NULL, key, iv, 1); + } + + int outl; + unsigned char ct[16]; + memset(ct, 0, sizeof(ct)); + EVP_EncryptUpdate(ctxEnc, ct, &outl, pt, 16); + + char ctHex[33]; + bin_to_hex(ctHex, ct, 16); + + pcpaSetSendPacket(stream, KC_ENCRYPT, ctHex); +} + +unsigned char workingIv[16]; +void mdkPcpDecrypt(pcpa_t* stream, void* data) { + char* ctHex = pcpaGetCommand(stream, KC_DECRYPT); + unsigned char ct[16]; + memset(ct, 0, sizeof(ct)); + hex_to_bin(ctHex, ct, strlen(ctHex) > 32 ? 32 : strlen(ctHex)); + + if (ctxDec == NULL) { + ctxDec = EVP_CIPHER_CTX_new(); + memcpy(workingIv, iv, 16); + } else { + EVP_CIPHER_CTX_cleanup(ctxDec); + } + EVP_CipherInit_ex(ctxDec, EVP_aes_128_cbc(), NULL, key, workingIv, 0); + memcpy(workingIv, ct, 16); + + int outl = 0; + unsigned char pt[16]; + memset(pt, 0, sizeof(pt)); + EVP_DecryptUpdate(ctxDec, pt, &outl, ct, 16); + + char ptHex[33]; + bin_to_hex(ptHex, pt, 16); + + pcpaSetSendPacket(stream, KC_DECRYPT, ptHex); +} +void mdkPcpSetIv(pcpa_t* stream, void* data) { + if (ctxEnc != NULL) { + EVP_CIPHER_CTX_cleanup(ctxEnc); + } else { + ctxEnc = EVP_CIPHER_CTX_new(); + } + EVP_CipherInit_ex(ctxEnc, EVP_aes_128_cbc(), NULL, key, iv, 1); + + memcpy(workingIv, iv, 16); + + pcpaSetSendPacket(stream, KC_SETIV, "1"); +} \ No newline at end of file diff --git a/src/micetools/system_dummy/dummykeychip/callbacks-stub.c b/src/micetools/system_dummy/dummykeychip/callbacks-stub.c new file mode 100644 index 0000000..66e4953 --- /dev/null +++ b/src/micetools/system_dummy/dummykeychip/callbacks-stub.c @@ -0,0 +1,53 @@ +#include "callbacks.h" + +void mdkPcpVersion(pcpa_t* stream, void* data) { pcpaSetSendPacket(stream, KC_VERSION, "0104"); } + +void mdkPcpStatus(pcpa_t* stream, void* data) { pcpaSetSendPacket(stream, KC_STATUS, "available"); } + +void mdkPcpAbGameId(pcpa_t* stream, void* data) { + // TODO: Can we do better? + pcpaSetSendPacket(stream, AB_GAMEID, "----"); +} +void mdkPcpAbSystemFlag(pcpa_t* stream, void* data) { + // systemflag 24 = billing + allnet, which should suffice for everything + pcpaSetSendPacket(stream, AB_SYSTEMFLAG, "24"); +} +void mdkPcpAbModelType(pcpa_t* stream, void* data) { + // ST + pcpaSetSendPacket(stream, AB_MODELTYPE, "2"); +} +void mdkPcpAbFormatType(pcpa_t* stream, void* data) { + pcpaSetSendPacket(stream, AB_FORMATTYPE, "1"); +} +void mdkPcpAbRegion(pcpa_t* stream, void* data) { + // All regions + pcpaSetSendPacket(stream, AB_REGION, "FF"); +} +void mdkPcpAbPlatformId(pcpa_t* stream, void* data) { + // TODO: We _can_ do better here + pcpaSetSendPacket(stream, AB_PLATFORMID, "AAS"); +} +void mdkPcpAbNetworkAddress(pcpa_t* stream, void* data) { + pcpaSetSendPacket(stream, AB_NETWORKADDRESS, "192.168.103.0"); +} +void mdkPcpAbDvd(pcpa_t* stream, void* data) { + pcpaSetSendPacket(stream, AB_DVD, "01"); +} + +void mdkPcpPbKeyId(pcpa_t* stream, void* data) { + pcpaSetSendPacket(stream, BIL_KEYID, "A72E-01A00000000"); +} +void mdkPcpPbMainId(pcpa_t* stream, void* data) { + pcpaSetSendPacket(stream, BIL_MAINID, ""); +} +void mdkPcpPbPlayCount(pcpa_t* stream, void* data) { + pcpaSetSendPacket(stream, BIL_PLAYCOUNT, "00000000"); +} +void mdkPcpPbPlayLimit(pcpa_t* stream, void* data) { + // 8192 plays before checkin + pcpaSetSendPacket(stream, BIL_PLAYLIMIT, "00002000"); +} +void mdkPcpPbNearfull(pcpa_t* stream, void* data) { + // Accounting mode = 1, nearfull = 512 + pcpaSetSendPacket(stream, BIL_NEARFULL, "00010200"); +} diff --git a/src/micetools/system_dummy/dummykeychip/callbacks.h b/src/micetools/system_dummy/dummykeychip/callbacks.h new file mode 100644 index 0000000..d13e252 --- /dev/null +++ b/src/micetools/system_dummy/dummykeychip/callbacks.h @@ -0,0 +1,94 @@ +#include "../../lib/libpcp/libpcp.h" + +pcpa_callback mdkBinaryCallback; +extern byte BINARY_DATA[4096]; +extern size_t BINARY_DATA_LEN; + +#define KEYCHIP "keychip." +#define APPBOOT KEYCHIP##"appboot." +#define BILLING KEYCHIP##"billing." +#define TRACEDATA KEYCHIP##"tracedata." + +// Misc +#define KC_VERSION KEYCHIP##"version" +#define KC_STATUS KEYCHIP##"status" +pcpa_callback mdkPcpVersion; +pcpa_callback mdkPcpStatus; + +// Crypto +#define DS_COMPUTE KEYCHIP##"ds.compute" +#define SSD_PROOF KEYCHIP##"ssd.proof" +#define SSD_HOSTPROOF KEYCHIP##"ssd.hostproof" +#define KC_ENCRYPT KEYCHIP##"encrypt" +#define KC_DECRYPT KEYCHIP##"decrypt" +#define KC_SETIV KEYCHIP##"setiv" +pcpa_callback mdkPcpDsCompute; +pcpa_callback mdkPcpSsdProof; +pcpa_callback mdkPcpSsdHostProof; +pcpa_callback mdkPcpEncrypt; +pcpa_callback mdkPcpDecrypt; +pcpa_callback mdkPcpSetIv; + +// Appboot +#define AB_GAMEID APPBOOT##"gameid" +#define AB_SYSTEMFLAG APPBOOT##"systemflag" +#define AB_MODELTYPE APPBOOT##"modeltype" +#define AB_FORMATTYPE APPBOOT##"formattype" +#define AB_REGION APPBOOT##"region" +#define AB_PLATFORMID APPBOOT##"platformid" +#define AB_NETWORKADDRESS APPBOOT##"networkaddr" +#define AB_DVD APPBOOT##"dvdflag" +#define AB_SEED APPBOOT##"seed" +pcpa_callback mdkPcpAbGameId; +pcpa_callback mdkPcpAbSystemFlag; +pcpa_callback mdkPcpAbModelType; +pcpa_callback mdkPcpAbFormatType; +pcpa_callback mdkPcpAbRegion; +pcpa_callback mdkPcpAbPlatformId; +pcpa_callback mdkPcpAbNetworkAddress; +pcpa_callback mdkPcpAbDvd; +pcpa_callback mdkPcpAbSeed; + +// Billing +#define BIL_KEYID BILLING##"keyid" +#define BIL_MAINID BILLING##"mainid" +#define BIL_PLAYCOUNT BILLING##"playcount" +#define BIL_PLAYLIMIT BILLING##"playlimit" +#define BIL_NEARFULL BILLING##"nearfull" +#define BIL_SIGNATURE BILLING##"signaturepubkey" +#define BIL_CACERT BILLING##"cacertification" +pcpa_callback mdkPcpPbKeyId; +pcpa_callback mdkPcpPbMainId; +pcpa_callback mdkPcpPbPlayCount; +pcpa_callback mdkPcpPbPlayLimit; +pcpa_callback mdkPcpPbNearfull; +pcpa_callback mdkPcpPbSignaturePubKey; +pcpa_callback mdkPcpPbCaCertification; + +// Tracedata +#define TRA_RESTORE TRACEDATA##"restore" +#define TRA_PUT TRACEDATA##"put" +#define TRA_GET TRACEDATA##"get" +#define TRA_LOGICALERASE TRACEDATA##"logicalerase" +#define TRA_SECTOREERASE TRACEDATA##"sectorerase" +pcpa_callback mdkPcpTdRestore; +pcpa_callback mdkPcpTdPut; +pcpa_callback mdkPcpTdGet; +pcpa_callback mdkPcpTdLogicalErase; +pcpa_callback mdkPcpTdSectorErase; + +// Storage +#define KC_EEPROM KEYCHIP##"eeprom" +#define KC_NVRAM KEYCHIP##"nvram" +#define KC_NVRAM0 KC_NVRAM##"0" +#define KC_NVRAM1 KC_NVRAM##"1" +#define KC_NVRAM2 KC_NVRAM##"2" +#define KC_NVRAM3 KC_NVRAM##"3" +#define KC_NVRAM4 KC_NVRAM##"4" +#define KC_NVRAM5 KC_NVRAM##"5" +#define KC_NVRAM6 KC_NVRAM##"6" +#define KC_NVRAM7 KC_NVRAM##"7" +#define KC_NVRAM8 KC_NVRAM##"8" +#define KC_NVRAM9 KC_NVRAM##"9" +pcpa_callback mdkPcpEeprom; +pcpa_callback mdkPcpNvram; diff --git a/src/micetools/system_dummy/dummykeychip/dummykeychip.c b/src/micetools/system_dummy/dummykeychip/dummykeychip.c new file mode 100644 index 0000000..03431fc --- /dev/null +++ b/src/micetools/system_dummy/dummykeychip/dummykeychip.c @@ -0,0 +1,118 @@ +#include "dummykeychip.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[40]; +} mdk_t; + +void mdkBeforeCb(pcpa_t* stream, void* data) {} + +e_pcpa_t mdkPcpStreamInit(mdk_t* mdk, unsigned short textPort, unsigned short binaryPort, + bool global) { + e_pcpa_t err; + + err = pcpaInitStream(&mdk->m_pcp); + if (err != e_pcpa_ok) { + amiDebugLog("pcpaInitStream Error. Code:%d", err); + return err; + } + // mdk->m_pcp.before_cb = mdkBeforeCb; + + err = + pcpaSetCallbackFuncBuffer(&mdk->m_pcp, mdk->m_pcpCallbacks, _countof(mdk->m_pcpCallbacks)); + if (err != e_pcpa_ok) { + amiDebugLog("pcpaSetCallBackFuncBuffer Error. Code:%d", err); + return err; + } + + // Misc + pcpaSetCallbackFunc(&mdk->m_pcp, KC_VERSION, mdkPcpVersion, NULL); + pcpaSetCallbackFunc(&mdk->m_pcp, KC_STATUS, mdkPcpStatus, NULL); + // Crypto + pcpaSetCallbackFunc(&mdk->m_pcp, DS_COMPUTE, mdkPcpDsCompute, NULL); + pcpaSetCallbackFunc(&mdk->m_pcp, SSD_PROOF, mdkPcpSsdProof, NULL); + pcpaSetCallbackFunc(&mdk->m_pcp, SSD_HOSTPROOF, mdkPcpSsdHostProof, NULL); + pcpaSetCallbackFunc(&mdk->m_pcp, KC_ENCRYPT, mdkPcpEncrypt, NULL); + pcpaSetCallbackFunc(&mdk->m_pcp, KC_DECRYPT, mdkPcpDecrypt, NULL); + pcpaSetCallbackFunc(&mdk->m_pcp, KC_SETIV, mdkPcpSetIv, NULL); + // Appboot + pcpaSetCallbackFunc(&mdk->m_pcp, AB_GAMEID, mdkPcpAbGameId, NULL); + pcpaSetCallbackFunc(&mdk->m_pcp, AB_SYSTEMFLAG, mdkPcpAbSystemFlag, NULL); + pcpaSetCallbackFunc(&mdk->m_pcp, AB_MODELTYPE, mdkPcpAbModelType, NULL); + pcpaSetCallbackFunc(&mdk->m_pcp, AB_FORMATTYPE, mdkPcpAbFormatType, NULL); + pcpaSetCallbackFunc(&mdk->m_pcp, AB_REGION, mdkPcpAbRegion, NULL); + pcpaSetCallbackFunc(&mdk->m_pcp, AB_PLATFORMID, mdkPcpAbPlatformId, NULL); + pcpaSetCallbackFunc(&mdk->m_pcp, AB_NETWORKADDRESS, mdkPcpAbNetworkAddress, NULL); + pcpaSetCallbackFunc(&mdk->m_pcp, AB_DVD, mdkPcpAbDvd, NULL); + pcpaSetCallbackFunc(&mdk->m_pcp, AB_SEED, mdkPcpAbSeed, NULL); + // Billing + pcpaSetCallbackFunc(&mdk->m_pcp, BIL_KEYID, mdkPcpPbKeyId, NULL); + pcpaSetCallbackFunc(&mdk->m_pcp, BIL_MAINID, mdkPcpPbMainId, NULL); + pcpaSetCallbackFunc(&mdk->m_pcp, BIL_PLAYCOUNT, mdkPcpPbPlayCount, NULL); + pcpaSetCallbackFunc(&mdk->m_pcp, BIL_PLAYLIMIT, mdkPcpPbPlayLimit, NULL); + pcpaSetCallbackFunc(&mdk->m_pcp, BIL_NEARFULL, mdkPcpPbNearfull, NULL); + // pcpaSetCallbackFunc(&mdk->m_pcp, BIL_SIGNATURE, mdkPcpPbSignaturePubKey, NULL); + // pcpaSetCallbackFunc(&mdk->m_pcp, BIL_CACERT, mdkPcpPbCaCertification, NULL); + // Tracedata + // pcpaSetCallbackFunc(&mdk->m_pcp, TRA_RESTORE, mdkPcpTdRestore, NULL); + // pcpaSetCallbackFunc(&mdk->m_pcp, TRA_PUT, mdkPcpTdPut, NULL); + // pcpaSetCallbackFunc(&mdk->m_pcp, TRA_GET, mdkPcpTdGet, NULL); + // pcpaSetCallbackFunc(&mdk->m_pcp, TRA_LOGICALERASE, mdkPcpTdLogicalErase, NULL); + // pcpaSetCallbackFunc(&mdk->m_pcp, TRA_SECTOREERASE, mdkPcpTdSectorErase, NULL); + // Storage + // pcpaSetCallbackFunc(&mdk->m_pcp, KC_EEPROM, mdkPcpEeprom, NULL); + // pcpaSetCallbackFunc(&mdk->m_pcp, KC_NVRAM0, mdkPcpNvram, NULL); + // pcpaSetCallbackFunc(&mdk->m_pcp, KC_NVRAM1, mdkPcpNvram, NULL); + // pcpaSetCallbackFunc(&mdk->m_pcp, KC_NVRAM2, mdkPcpNvram, NULL); + // pcpaSetCallbackFunc(&mdk->m_pcp, KC_NVRAM3, mdkPcpNvram, NULL); + // pcpaSetCallbackFunc(&mdk->m_pcp, KC_NVRAM4, mdkPcpNvram, NULL); + // pcpaSetCallbackFunc(&mdk->m_pcp, KC_NVRAM5, mdkPcpNvram, NULL); + // pcpaSetCallbackFunc(&mdk->m_pcp, KC_NVRAM6, mdkPcpNvram, NULL); + // pcpaSetCallbackFunc(&mdk->m_pcp, KC_NVRAM7, mdkPcpNvram, NULL); + // pcpaSetCallbackFunc(&mdk->m_pcp, KC_NVRAM8, mdkPcpNvram, NULL); + // pcpaSetCallbackFunc(&mdk->m_pcp, KC_NVRAM9, mdkPcpNvram, NULL); + + err = pcpaOpenServerWithBinary(&mdk->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 miceDummyKeychip(unsigned short textPort, unsigned short binaryPort, bool global) { + mdk_t* mdk = malloc(sizeof *mdk); + e_pcpa_t err; + + WSADATA wsaData; + if (WSAStartup(2, &wsaData)) { + amiDebugLog("WSAStartup Error. Code %d", GetLastError()); + return; + } + + err = mdkPcpStreamInit(mdk, textPort, binaryPort, global); + if (err != e_pcpa_ok) { + amiDebugLog("mdkPcpStreamInit Error. Code %d", err); + return; + } + + while (1) { + err = pcpaServer(&mdk->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(&mdk->m_pcp); + return; + } + } +} diff --git a/src/micetools/system_dummy/dummykeychip/dummykeychip.h b/src/micetools/system_dummy/dummykeychip/dummykeychip.h new file mode 100644 index 0000000..4472716 --- /dev/null +++ b/src/micetools/system_dummy/dummykeychip/dummykeychip.h @@ -0,0 +1,3 @@ +#include + +void miceDummyKeychip(unsigned short textPort, unsigned short binaryPort, bool global); diff --git a/src/micetools/system_dummy/dummykeychip/main.c b/src/micetools/system_dummy/dummykeychip/main.c new file mode 100644 index 0000000..9cdae0c --- /dev/null +++ b/src/micetools/system_dummy/dummykeychip/main.c @@ -0,0 +1,3 @@ +#include "dummykeychip.h" + +int main() { miceDummyKeychip(40106, 40107, false); } diff --git a/src/micetools/system_dummy/dummykeychip/meson.build b/src/micetools/system_dummy/dummykeychip/meson.build new file mode 100644 index 0000000..97ed942 --- /dev/null +++ b/src/micetools/system_dummy/dummykeychip/meson.build @@ -0,0 +1,22 @@ +link_with = [libpcp, amiDebug, util_lib] +sources = [ + 'callbacks-stub.c', + 'callbacks-crypto.c', + 'dummykeychip.c', +] + +dummykeychip = static_library( + 'dummykeychip', + sources: sources, + link_with: link_with, + include_directories: [openssl_inc], + dependencies: [openssl_lib], +) +executable( + 'dummykeychip', + win_subsystem: subsystem, + sources: ['main.c'] + sources, + link_with: link_with, + include_directories: [openssl_inc], + dependencies: [openssl_lib], +) diff --git a/src/micetools/system_dummy/meson.build b/src/micetools/system_dummy/meson.build index fc20b45..656a6cd 100644 --- a/src/micetools/system_dummy/meson.build +++ b/src/micetools/system_dummy/meson.build @@ -1,2 +1,3 @@ +subdir('dummykeychip') subdir('dummymaster') subdir('dummyinstaller') diff --git a/src/micetools/util/meson.build b/src/micetools/util/meson.build index 5e6952b..1190d0a 100644 --- a/src/micetools/util/meson.build +++ b/src/micetools/util/meson.build @@ -71,3 +71,13 @@ executable( 'test.c', ], ) +executable( + 'micegbdisk', + win_subsystem: subsystem, + sources: [ + 'micegbdisk.c', + ], + link_with: [ + amiDebug, + ], +) diff --git a/src/micetools/util/micegbdisk.c b/src/micetools/util/micegbdisk.c new file mode 100644 index 0000000..2e8a6ed --- /dev/null +++ b/src/micetools/util/micegbdisk.c @@ -0,0 +1,388 @@ +#include +// +#include +#include +#define _CRT_RAND_S +#include +#include + +#include "../dll/hooks/drive/irb.h" +#include "../lib/ami/amiDebug.h" + +#define ATA_VENDOR_HOST_PROOF 0xC1 +#define ATA_VENDOR_PROOF_DEVICE 0xC2 +#define ATA_IDENTIFY_DEVICE 0xEC +#define ATA_SECURITY_UNLOCK 0xF2 +#define ATA_SECURITY_FREEZE_LOCK 0xF5 + +#pragma pack(push, 1) +typedef struct { + UCHAR bFeaturesReg; + UCHAR bSectorCountReg; + UCHAR bSectorNumberReg; + UCHAR bCylLowReg; + UCHAR bCylHighReg; + UCHAR bDriveHeadReg; + UCHAR bCommandReg; + UCHAR bReserved; +} ATA_TASK_FILE_OUT; +typedef struct { + UCHAR bErrorReg; + UCHAR bSectorCountReg; + UCHAR bSectorNumberReg; + UCHAR bCylLowReg; + UCHAR bCylHighReg; + UCHAR bDriveHeadReg; + UCHAR bStatusReg; + UCHAR bReserved; +} ATA_TASK_FILE_IN; +typedef struct _ATA_PASS_THROUGH_EX_512 { + ATA_PASS_THROUGH_EX Ata; + UCHAR Data[512]; +} ATA_PASS_THROUGH_EX_512, *PATA_PASS_THROUGH_EX_512; +typedef struct _ATA_PASS_THROUGH_EX_256 { + ATA_PASS_THROUGH_EX Ata; + UCHAR Data[256]; +} ATA_PASS_THROUGH_EX_256, *PATA_PASS_THROUGH_EX_256; +#pragma pack(pop) + +#define TASK_FILE_OUT(Ata) (*((ATA_TASK_FILE_OUT *)(void *)(&Ata.CurrentTaskFile))) +#define TASK_FILE_IN(Ata) (*((ATA_TASK_FILE_IN *)(void *)(&Ata.CurrentTaskFile))) + +typedef enum { + mseOk = 0, + mseNg = -1, + mseInvalidParam = -2, + mseNoInit = -3, + mseAlreadyInit = -4, + mseDiskError = -5, + mseAtaDeviceError = -6, +} mxk_ssd_err_t; + +HANDLE PD0_HANDLE = INVALID_HANDLE_VALUE; +BOOL PD0_HAS_INIT = FALSE; + +mxk_ssd_err_t mxkGetSystemDiskNumber(DWORD *disk) { + // TODO: This + if (disk != NULL) *disk = 1; + return mseOk; +} + +mxk_ssd_err_t mxkSsdInit(void) { + if (PD0_HAS_INIT) return mseAlreadyInit; + + DWORD disk; + mxk_ssd_err_t err = mxkGetSystemDiskNumber(&disk); + if (err != mseOk) return mseDiskError; + + char path[32] = { 0 }; + sprintf_s(path, sizeof path, "\\\\.\\PhysicalDrive%d", disk); + amiDebugLog("Using disk: %s", path); + PD0_HANDLE = CreateFileA(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, 0, NULL); + if (PD0_HANDLE == INVALID_HANDLE_VALUE) { + amiDebugLog("CreateFile Error : Error No = %d", GetLastError()); + return mseDiskError; + } + + PD0_HAS_INIT = TRUE; + return mseOk; +} +mxk_ssd_err_t mxkSsdExit(void) { + if (!PD0_HAS_INIT) return mseNoInit; + + if (PD0_HANDLE != INVALID_HANDLE_VALUE) CloseHandle(PD0_HANDLE); + PD0_HAS_INIT = FALSE; + return mseOk; +} + +mxk_ssd_err_t mxkAtaPioOutCommand(HANDLE hDrive, PATA_PASS_THROUGH_EX pAtaBuffer, UCHAR *data) { + ATA_PASS_THROUGH_EX response; + ATA_PASS_THROUGH_EX_512 request; + + ZeroMemory(&request, sizeof request); + memcpy(&request.Ata, pAtaBuffer, sizeof request.Ata); + + DWORD sendBytes; + if (data == NULL) { + sendBytes = sizeof request.Ata; + } else { + memcpy(request.Data, data, sizeof request.Data); + request.Ata.DataTransferLength = sizeof request.Data; + sendBytes = sizeof request; + } + + request.Ata.Length = sizeof request.Ata; + request.Ata.DataBufferOffset = sizeof request.Ata; + request.Ata.AtaFlags = ATA_FLAGS_DATA_OUT; + request.Ata.TimeOutValue = 35; + + DWORD dwBytesReturned = 0; + BOOL bResult = DeviceIoControl(hDrive, IOCTL_ATA_PASS_THROUGH, &request, sendBytes, &response, + sizeof response, &dwBytesReturned, NULL); + + memcpy(pAtaBuffer, &response, sizeof response); + + if (!bResult || (TASK_FILE_IN(response).bStatusReg & 1) != 0) { + amiDebugLog("Error DeviceIoControl() : %d/%02x:%02x", GetLastError(), + TASK_FILE_IN(response).bStatusReg, TASK_FILE_IN(response).bErrorReg); + return mseAtaDeviceError; + } + return mseOk; +} + +mxk_ssd_err_t mxkAtaPioInCommand(HANDLE hDrive, PATA_PASS_THROUGH_EX pAtaBuffer, UCHAR *dataOut) { + ATA_PASS_THROUGH_EX request; + ATA_PASS_THROUGH_EX_512 response; + + ZeroMemory(&response.Ata, sizeof response.Ata); + memcpy(&request, pAtaBuffer, sizeof request); + + request.Length = sizeof request; + request.DataBufferOffset = sizeof request; + request.AtaFlags = ATA_FLAGS_DATA_IN; + request.TimeOutValue = 5; + + DWORD dwBytesReturned = 0; + BOOL bResult = DeviceIoControl(hDrive, IOCTL_ATA_PASS_THROUGH, &request, sizeof request, + &response, sizeof response, &dwBytesReturned, NULL); + + memcpy(pAtaBuffer, &response, sizeof response.Ata); + + if (!bResult || (TASK_FILE_IN(response.Ata).bStatusReg & 1) != 0) { + amiDebugLog("Error DeviceIoControl() : %d", GetLastError()); + return mseAtaDeviceError; + } + + memcpy(dataOut, response.Data, sizeof response.Data); + return mseOk; +} + +mxk_ssd_err_t mxkSsdDeviceProofSet(UCHAR *data) { + ATA_PASS_THROUGH_EX request; + UCHAR localData[512]; + + if (!PD0_HAS_INIT) return mseNoInit; + if (data == NULL) return mseInvalidParam; + + ZeroMemory(&request, sizeof request); + memcpy(localData, data, 128); + + TASK_FILE_OUT(request).bCommandReg = ATA_VENDOR_PROOF_DEVICE; + TASK_FILE_OUT(request).bFeaturesReg = 17; + + return mxkAtaPioOutCommand(PD0_HANDLE, &request, localData); +} + +mxk_ssd_err_t mxkSsdDeviceProofGet(UCHAR *data) { + ATA_PASS_THROUGH_EX request; + UCHAR buffer[512]; + + if (!PD0_HAS_INIT) return mseNoInit; + if (data == NULL) return mseInvalidParam; + + ZeroMemory(&request, sizeof request); + TASK_FILE_OUT(request).bCommandReg = ATA_VENDOR_PROOF_DEVICE; + TASK_FILE_OUT(request).bFeaturesReg = 18; + request.DataTransferLength = sizeof buffer; + + mxk_ssd_err_t err = mxkAtaPioInCommand(PD0_HANDLE, &request, buffer); + if (err != 0) return err; + memcpy(data, buffer, 128); + return mseOk; +} + +#define SSD_PROOF_NBYTES 16 +int mxkSsdProofDevice(UCHAR *seed, UCHAR *response, UCHAR *code) { + UCHAR workBuf[128]; + + if (response == NULL || seed == NULL) { + if (code != NULL) *code = 54; + return 3; + } + if (code == NULL) return 3; + + *code = 0; + memcpy_s(workBuf, sizeof workBuf, seed, SSD_PROOF_NBYTES); + + unsigned int randVal; + for (int i = SSD_PROOF_NBYTES; i < sizeof workBuf; i++) { + rand_s(&randVal); + workBuf[i] = randVal & 0xFF; + } + + mxk_ssd_err_t err; + err = mxkSsdDeviceProofSet(workBuf); + if (err != mseOk) { + amiDebugLog("Error mxkSsdDeviceProofSet()!!! Code:%d", err); + *code = 2; + return 1; + } + + ZeroMemory(workBuf, sizeof workBuf); + err = mxkSsdDeviceProofGet(workBuf); + if (err != mseOk) { + amiDebugLog("Error mxkSsdDeviceProofGet()!!! Code:%d", err); + *code = 2; + return 1; + } + + memcpy_s(response, SSD_PROOF_NBYTES, workBuf, SSD_PROOF_NBYTES); + return 0; +} + +mxk_ssd_err_t mxkSsdSecurityUnlock(UCHAR *password, DWORD nPassword, BOOL userPassword) { + ATA_PASS_THROUGH_EX request; + UCHAR localData[512]; + + if (!PD0_HAS_INIT) return mseNoInit; + if (password == NULL) return mseInvalidParam; + + ZeroMemory(&request, sizeof request); + ZeroMemory(localData, sizeof localData); + if (userPassword) + localData[0] = 0x00; + else + localData[0] = 0x01; + memcpy_s(localData + 2, sizeof localData, password, nPassword); + + TASK_FILE_OUT(request).bCommandReg = ATA_SECURITY_UNLOCK; + + return mxkAtaPioOutCommand(PD0_HANDLE, &request, localData); +} + +mxk_ssd_err_t mxkSsdIdentify(PIDENTIFY_DEVICE_DATA response) { + if (!PD0_HAS_INIT) return mseNoInit; + if (response == NULL) return mseInvalidParam; + + ATA_PASS_THROUGH_EX_256 ata = { 0 }; + ata.Ata.Length = sizeof ata.Ata; + ata.Ata.AtaFlags = ATA_FLAGS_DATA_IN | ATA_FLAGS_DRDY_REQUIRED; + ata.Ata.DataTransferLength = sizeof ata.Data; + ata.Ata.DataBufferOffset = sizeof ata.Ata; + ata.Ata.TimeOutValue = 10; + ata.Ata.CurrentTaskFile[6] = ATA_IDENTIFY_DEVICE; + ata.Ata.CurrentTaskFile[7] = 0; + + DWORD dwBytesReturned = 0; + BOOL bResult = DeviceIoControl(PD0_HANDLE, IOCTL_ATA_PASS_THROUGH, &ata, sizeof(ata), &ata, + sizeof(ata), &dwBytesReturned, NULL); + + if (!bResult) { + amiDebugLog("Error DeviceIoControl() : %d", GetLastError()); + return mseAtaDeviceError; + } + + memcpy(response, ata.Data, sizeof ata.Data); + return mseOk; +} + +void printf_word_string(UCHAR *wordString, DWORD nShorts) { + while (nShorts--) { + printf("%c", wordString[1]); + printf("%c", wordString[0]); + wordString += 2; + } +} + +void printIdentity(PIDENTIFY_DEVICE_DATA identity) { + puts("[ Identification ]"); + printf("Serial number : "); + printf_word_string(identity->SerialNumber, 10); + printf("\nModel number : "); + printf_word_string(identity->ModelNumber, 20); + puts("\n[ Security ]"); + printf(" Supported : %s\n", identity->SecurityStatus.SecuritySupported ? "YES" : "NO"); + printf(" Enabled : %s\n", identity->SecurityStatus.SecurityEnabled ? "YES" : "NO"); + printf(" Frozen : %s\n", identity->SecurityStatus.SecurityFrozen ? "YES" : "NO"); + printf(" Locked : %s\n", identity->SecurityStatus.SecurityLocked ? "YES" : "NO"); + printf(" # Expired : %s\n", identity->SecurityStatus.SecurityCountExpired ? "YES" : "NO"); + printf(" Master Pass : %s\n", identity->SecurityStatus.SecurityLevel ? "Maximum" : "High"); +} + +int main(int argc, char **argv) { + puts("mice GBDisk utility tool."); + + printf("Opening drive\n"); + + mxk_ssd_err_t err; + err = mxkSsdInit(); + if (err != mseOk) { + printf("Failed to open SSD: %d\n", err); + return 1; + } + + puts("Requesting identity"); + IDENTIFY_DEVICE_DATA identity; + err = mxkSsdIdentify(&identity); + if (err != mseOk) { + printf("Failed to identify: %d\n", err); + mxkSsdExit(); + return 1; + } + printIdentity(&identity); + if (!identity.SecurityStatus.SecurityLocked) { + puts("Security is not enabled. Nothing to do!"); + mxkSsdExit(); + return 0; + } + if (identity.SecurityStatus.SecurityFrozen) { + puts("Security is frozen. We have no hope of unlocking this drive!"); + mxkSsdExit(); + return 2; + } + + puts("Sending security unlock"); + UCHAR password[32] = { + 0x72, 0x42, 0x52, 0x5A, 0xBA, 0x52, 0x6A, 0x5A, 0xEA, 0x72, 0x62, + 0x78, 0xCA, 0x42, 0xDA, 0x4A, 0x2A, 0x22, 0x3A, 0x2A, 0x0A, 0x22, + 0x1A, 0x2A, 0x6A, 0x02, 0x7A, 0x0A, 0x5C, 0xCE, 0x4A, 0x0A, + }; + err = mxkSsdSecurityUnlock(password, sizeof password, TRUE); + printf("Security unlock result: %d\n", err); + + mxkSsdExit(); + return 0; +} + +// int main() { +// HANDLE hDevice = CreateFile("\\\\.\\PhysicalDrive1", GENERIC_READ | GENERIC_WRITE, +// FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, +// NULL); +// if (hDevice == INVALID_HANDLE_VALUE) { +// printf("Error: could not open device\n"); +// return 1; +// } + +// ATA_PASS_THROUGH_EX_256 ata = { 0 }; +// ata.Ata.Length = sizeof ata.Ata; +// ata.Ata.AtaFlags = ATA_FLAGS_DATA_IN | ATA_FLAGS_DRDY_REQUIRED; +// ata.Ata.DataTransferLength = 256; +// ata.Ata.DataBufferOffset = sizeof ata.Ata; +// ata.Ata.TimeOutValue = 10; +// ata.Ata.CurrentTaskFile[6] = ATA_IDENTIFY_DEVICE; +// ata.Ata.CurrentTaskFile[7] = 0; + +// DWORD dwBytesReturned = 0; +// BOOL bResult = DeviceIoControl(hDevice, IOCTL_ATA_PASS_THROUGH, &ata, sizeof(ata), &ata, +// sizeof(ata), &dwBytesReturned, NULL); +// if (!bResult) { +// printf("Error: could not send IDENTIFY DEVICE request %d\n", GetLastError()); +// CloseHandle(hDevice); +// return 1; +// } + +// for (int i = 0; i < 256; i++) { +// printf(" %02x", ata.Data[i]); +// if (i % 32 == 31) { +// printf(" "); +// for (int j = i - 31; j <= i; j++) { +// if (10 <= ata.Data[j] && ata.Data[j] < 128) +// printf("%c", ata.Data[j]); +// else +// printf("."); +// } +// puts(""); +// } +// } +// } \ No newline at end of file