1
0
mirror of https://gitea.tendokyu.moe/Dniel97/segatools.git synced 2024-11-11 23:17:08 +01:00

Merge pull request 'Kemono Friends support / 32-bit CHC300 support' (#36) from Haruka/segatools:kemonofr into develop

Reviewed-on: https://gitea.tendokyu.moe/Dniel97/segatools/pulls/36
This commit is contained in:
Dniel97 2024-09-21 15:12:05 +00:00
commit bb773a63ce
34 changed files with 1433 additions and 163 deletions

View File

@ -219,6 +219,27 @@ $(BUILD_DIR_ZIP)/tokyo.zip:
$(V)strip $(BUILD_DIR_ZIP)/tokyo/*.{exe,dll} $(V)strip $(BUILD_DIR_ZIP)/tokyo/*.{exe,dll}
$(V)cd $(BUILD_DIR_ZIP)/tokyo ; zip -r ../tokyo.zip * $(V)cd $(BUILD_DIR_ZIP)/tokyo ; zip -r ../tokyo.zip *
$(BUILD_DIR_ZIP)/kemono.zip:
$(V)echo ... $@
$(V)mkdir -p $(BUILD_DIR_ZIP)/kemono
$(V)mkdir -p $(BUILD_DIR_ZIP)/kemono/DEVICE
$(V)cp $(DIST_DIR)/kemono/segatools.ini \
$(DIST_DIR)/kemono/start.bat \
$(BUILD_DIR_ZIP)/kemono
$(V)cp $(BUILD_DIR_32)/kemonohook/kemonohook.dll \
$(BUILD_DIR_ZIP)/kemono/kemonohook_x86.dll
$(V)cp $(BUILD_DIR_64)/kemonohook/kemonohook.dll \
$(BUILD_DIR_ZIP)/kemono/kemonohook_x64.dll
$(V)cp $(BUILD_DIR_32)/subprojects/capnhook/inject/inject.exe \
$(BUILD_DIR_ZIP)/kemono/inject_x86.exe
$(V)cp $(BUILD_DIR_64)/subprojects/capnhook/inject/inject.exe \
$(BUILD_DIR_ZIP)/kemono/inject_x64.exe
$(V)cp pki/billing.pub \
pki/ca.crt \
$(BUILD_DIR_ZIP)/kemono/DEVICE
for x in exe dll; do strip $(BUILD_DIR_ZIP)/kemono/*.$$x; done
$(V)cd $(BUILD_DIR_ZIP)/kemono ; zip -r ../kemono.zip *
$(BUILD_DIR_ZIP)/doc.zip: \ $(BUILD_DIR_ZIP)/doc.zip: \
$(DOC_DIR)/config \ $(DOC_DIR)/config \
$(DOC_DIR)/chunihook.md \ $(DOC_DIR)/chunihook.md \
@ -243,6 +264,7 @@ $(BUILD_DIR_ZIP)/segatools.zip: \
$(BUILD_DIR_ZIP)/cm.zip \ $(BUILD_DIR_ZIP)/cm.zip \
$(BUILD_DIR_ZIP)/tokyo.zip \ $(BUILD_DIR_ZIP)/tokyo.zip \
$(BUILD_DIR_ZIP)/fgo.zip \ $(BUILD_DIR_ZIP)/fgo.zip \
$(BUILD_DIR_ZIP)/kemono.zip \
CHANGELOG.md \ CHANGELOG.md \
README.md \ README.md \

View File

@ -30,6 +30,8 @@ Loaders and hardware emulators for SEGA games that run on the Nu and ALLS platfo
* SEGA World Drivers Championship 2019 * SEGA World Drivers Championship 2019
* WACCA * WACCA
* starting from WACCA * starting from WACCA
* Kemono Friends
* Kemono Friends 3: Planet Tours
## End-users ## End-users

View File

@ -199,7 +199,7 @@ struct led15093_resp_board_info {
char chip_num[5]; char chip_num[5];
uint8_t endcode; // Always 0xFF uint8_t endcode; // Always 0xFF
uint8_t fw_ver; uint8_t fw_ver;
uint8_t rx_buf; uint16_t rx_buf;
}; };
struct led15093_resp_protocol_ver { struct led15093_resp_protocol_ver {

View File

@ -11,10 +11,10 @@ enum {
SG_NFC_CMD_RADIO_OFF = 0x41, SG_NFC_CMD_RADIO_OFF = 0x41,
SG_NFC_CMD_POLL = 0x42, SG_NFC_CMD_POLL = 0x42,
SG_NFC_CMD_MIFARE_SELECT_TAG = 0x43, SG_NFC_CMD_MIFARE_SELECT_TAG = 0x43,
SG_NFC_CMD_MIFARE_SET_KEY_A = 0x50, SG_NFC_CMD_MIFARE_SET_KEY_AIME = 0x50,
SG_NFC_CMD_MIFARE_AUTHENTICATE_A = 0x51, SG_NFC_CMD_MIFARE_AUTHENTICATE_A = 0x51,
SG_NFC_CMD_MIFARE_READ_BLOCK = 0x52, SG_NFC_CMD_MIFARE_READ_BLOCK = 0x52,
SG_NFC_CMD_MIFARE_SET_KEY_B = 0x54, SG_NFC_CMD_MIFARE_SET_KEY_BANA = 0x54,
SG_NFC_CMD_MIFARE_AUTHENTICATE_B = 0x55, SG_NFC_CMD_MIFARE_AUTHENTICATE_B = 0x55,
SG_NFC_CMD_TO_UPDATE_MODE = 0x60, SG_NFC_CMD_TO_UPDATE_MODE = 0x60,
SG_NFC_CMD_SEND_HEX_DATA = 0x61, SG_NFC_CMD_SEND_HEX_DATA = 0x61,

View File

@ -189,7 +189,8 @@ static HRESULT sg_nfc_dispatch(
&req->felica_encap, &req->felica_encap,
&res->felica_encap); &res->felica_encap);
case SG_NFC_CMD_MIFARE_AUTHENTICATE: case SG_NFC_CMD_MIFARE_AUTHENTICATE_A:
case SG_NFC_CMD_MIFARE_AUTHENTICATE_B:
case SG_NFC_CMD_SEND_HEX_DATA: case SG_NFC_CMD_SEND_HEX_DATA:
return sg_nfc_cmd_send_hex_data(nfc, &req->simple, &res->simple); return sg_nfc_cmd_send_hex_data(nfc, &req->simple, &res->simple);

View File

@ -101,7 +101,7 @@ static DWORD CALLBACK cm_pre_startup(void)
There seems to be an issue with other DLL hooks if `LoadLibraryW` is There seems to be an issue with other DLL hooks if `LoadLibraryW` is
hooked earlier in the `cmhook` initialization. */ hooked earlier in the `cmhook` initialization. */
unity_hook_init(&cm_hook_cfg.unity, cm_hook_mod); unity_hook_init(&cm_hook_cfg.unity, cm_hook_mod, NULL);
/* Initialize debug helpers */ /* Initialize debug helpers */

147
dist/kemono/segatools.ini vendored Normal file
View File

@ -0,0 +1,147 @@
; -----------------------------------------------------------------------------
; Path settings
; -----------------------------------------------------------------------------
[vfs]
; Insert the path to the game AMFS directory here (contains ICF1 and ICF2)
amfs=
; Insert the path to the game Option directory here (contains Axxx directories)
option=
; Create an empty directory somewhere and insert the path here.
; This directory may be shared between multiple SEGA games.
; NOTE: This has nothing to do with Windows %APPDATA%.
appdata=
; -----------------------------------------------------------------------------
; Device settings
; -----------------------------------------------------------------------------
[aime]
; Enable Aime card reader assembly emulation. Disable to use a real SEGA Aime
; reader.
enable=1
aimePath=DEVICE\aime.txt
[vfd]
; Enable VFD emulation (currently just stubbed). Disable to use a real VFD
; GP1232A02A FUTABA assembly.
enable=1
; -----------------------------------------------------------------------------
; Network settings
; -----------------------------------------------------------------------------
[dns]
; Insert the hostname or IP address of the server you wish to use here.
; Note that 127.0.0.1, localhost etc are specifically rejected.
default=127.0.0.1
[netenv]
; Simulate an ideal LAN environment. This may interfere with head-to-head play.
; SEGA games are somewhat picky about its LAN environment, so leaving this
; setting enabled is recommended.
enable=1
; The final octet of the local host's IP address on the virtualized subnet (so,
; if the keychip subnet is `192.168.32.0` and this value is set to `11`, then the
; local host's virtualized LAN IP is `192.168.32.11`).
addrSuffix=11
; -----------------------------------------------------------------------------
; Board settings
; -----------------------------------------------------------------------------
[keychip]
; The /24 LAN subnet that the emulated keychip will tell the game to expect.
; If you disable netenv then you must set this to your LAN's IP subnet, and
; that subnet must start with 192.168.
subnet=192.168.179.0
[gpio]
; Emulated Nu DIP switch for Distribution Server setting.
;
; If multiple machines are present on the same LAN then set this to 1 on
; exactly one machine and set this to 0 on all others.
dipsw1=1
; Chassis Test button virtual-key code. Default is the 4 key.
test=0x34
; Chassis Service button virtual-key code. Default is the 5 key.
service=0x35
; -----------------------------------------------------------------------------
; Misc. hook settings
; -----------------------------------------------------------------------------
[unity]
; Enable Unity hook. This will allow you to run custom .NET code before the game
enable=1
; Path to a .NET DLL that should run before the game. Useful for loading
; modding frameworks such as BepInEx.
;
; NOTE: For Kemono Friends, BepInEx (or similar) should be installed to the main folder, not the "UnityApp" folder.
targetAssembly=
[printer]
; Sinfonia CHC-C300 printer emulation setting.
enable=1
; Change the printer serial number here.
serial_no="5A-A123"
; Insert the path to the image output directory here.
printerOutPath="DEVICE\print"
; -----------------------------------------------------------------------------
; LED settings
; -----------------------------------------------------------------------------
[led15093]
; 837-15093-06 LED board emulation setting.
enable=1
; -----------------------------------------------------------------------------
; Custom IO settings
; -----------------------------------------------------------------------------
[aimeio]
; To use a custom card reader IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
path=
[kemonoio]
; To use a custom Kemono IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
path=
; -----------------------------------------------------------------------------
; Input settings
; -----------------------------------------------------------------------------
; Keyboard bindings are specified as hexadecimal (prefixed with 0x) or decimal
; (not prefixed with 0x) virtual-key codes, a list of which can be found here:
;
; https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
;
; This is, admittedly, not the most user-friendly configuration method in the
; world. An improved solution will be provided later.
[io3]
; Test button virtual-key code. Default is the 1 key.
test=0x31
; Service button virtual-key code. Default is the 2 key.
service=0x32
; Keyboard button to increment coin counter. Default is the 3 key.
coin=0x33
; Analog lever (which is actually just four buttons, and not real analog input, default: Arrow keys)
left=0x25
right=0x27
up=0x26
down=0x28
; Controller face buttons (default A, S, D)
red=0x41
green=0x53
blue=0x44
; Menu confirmation key (default RETURN)
start=0x0D

12
dist/kemono/start.bat vendored Normal file
View File

@ -0,0 +1,12 @@
@echo off
pushd %~dp0
start "AM Daemon" /min inject_x64 -d -k kemonohook_x64.dll amdaemon.exe -c config.json
inject_x86 -d -k kemonohook_x86.dll UnityApp\Parade -screen-fullscreen 0 -popupwindow -screen-width 720 -screen-height 1280 -silent-crashes
taskkill /f /im amdaemon.exe > nul 2>&1
echo.
echo Game processes have terminated
pause

View File

@ -26,6 +26,7 @@
#include "hook/process.h" #include "hook/process.h"
#include "hooklib/dll.h"
#include "hooklib/dvd.h" #include "hooklib/dvd.h"
#include "hooklib/touch.h" #include "hooklib/touch.h"
#include "hooklib/printer.h" #include "hooklib/printer.h"
@ -65,6 +66,8 @@ static DWORD CALLBACK fgo_pre_startup(void)
/* Hook external DLL APIs */ /* Hook external DLL APIs */
printer_hook_init(&fgo_hook_cfg.printer, 4, fgo_hook_mod); printer_hook_init(&fgo_hook_cfg.printer, 4, fgo_hook_mod);
dll_hook_push(fgo_hook_mod, L"C330Ausb.dll");
dll_hook_push(fgo_hook_mod, L"C330AFWDLusb.dll");
/* Initialize emulation hooks */ /* Initialize emulation hooks */

View File

@ -44,7 +44,7 @@ EXPORTS
chcusb_selectPrinter chcusb_selectPrinter
chcusb_selectPrinterSN chcusb_selectPrinterSN
chcusb_getPrinterInfo chcusb_getPrinterInfo
chcusb_imageformat chcusb_imageformat=chcusb_imageformat_330
chcusb_setmtf chcusb_setmtf
chcusb_makeGamma chcusb_makeGamma
chcusb_setIcctable chcusb_setIcctable

View File

@ -11,6 +11,7 @@
#include "hooklib/printer.h" #include "hooklib/printer.h"
#include <assert.h>
#include <math.h> #include <math.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
@ -60,44 +61,45 @@ static uint8_t STATUS = 0;
/* C3XXFWDLusb API hooks */ /* C3XXFWDLusb API hooks */
int fwdlusb_open(uint16_t *rResult); int WINAPI fwdlusb_open(uint16_t *rResult);
void fwdlusb_close(); void WINAPI fwdlusb_close();
int fwdlusb_listupPrinter(uint8_t *rIdArray); int WINAPI fwdlusb_listupPrinter(uint8_t *rIdArray);
int fwdlusb_listupPrinterSN(uint64_t *rSerialArray); int WINAPI fwdlusb_listupPrinterSN(uint64_t *rSerialArray);
int fwdlusb_selectPrinter(uint8_t printerId, uint16_t *rResult); int WINAPI fwdlusb_selectPrinter(uint8_t printerId, uint16_t *rResult);
int fwdlusb_selectPrinterSN(uint64_t printerSN, uint16_t *rResult); int WINAPI fwdlusb_selectPrinterSN(uint64_t printerSN, uint16_t *rResult);
int fwdlusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen); int WINAPI fwdlusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen);
int fwdlusb_status(uint16_t *rResult); int WINAPI fwdlusb_status(uint16_t *rResult);
int fwdlusb_statusAll(uint8_t *idArray, uint16_t *rResultArray); int WINAPI fwdlusb_statusAll(uint8_t *idArray, uint16_t *rResultArray);
int fwdlusb_resetPrinter(uint16_t *rResult); int WINAPI fwdlusb_resetPrinter(uint16_t *rResult);
int fwdlusb_updateFirmware(uint8_t update, LPCSTR filename, uint16_t *rResult); int WINAPI fwdlusb_updateFirmware(uint8_t update, LPCSTR filename, uint16_t *rResult);
int fwdlusb_getFirmwareInfo(uint8_t update, LPCSTR filename, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult); int WINAPI fwdlusb_getFirmwareInfo(uint8_t update, LPCSTR filename, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult);
int fwdlusb_MakeThread(uint16_t maxCount); int WINAPI fwdlusb_MakeThread(uint16_t maxCount);
int fwdlusb_ReleaseThread(uint16_t *rResult); int WINAPI fwdlusb_ReleaseThread(uint16_t *rResult);
int fwdlusb_AttachThreadCount(uint16_t *rCount, uint16_t *rMaxCount); int WINAPI fwdlusb_AttachThreadCount(uint16_t *rCount, uint16_t *rMaxCount);
int fwdlusb_getErrorLog(uint16_t index, uint8_t *rData, uint16_t *rResult); int WINAPI fwdlusb_getErrorLog(uint16_t index, uint8_t *rData, uint16_t *rResult);
/* C3XXusb API hooks */ /* C3XXusb API hooks */
int chcusb_MakeThread(uint16_t maxCount); int WINAPI chcusb_MakeThread(uint16_t maxCount);
int chcusb_open(uint16_t *rResult); int WINAPI chcusb_open(uint16_t *rResult);
void chcusb_close(); __stdcall void chcusb_close();
int chcusb_ReleaseThread(uint16_t *rResult); int WINAPI chcusb_ReleaseThread(uint16_t *rResult);
int chcusb_listupPrinter(uint8_t *rIdArray); int WINAPI chcusb_listupPrinter(uint8_t *rIdArray);
int chcusb_listupPrinterSN(uint64_t *rSerialArray); int WINAPI chcusb_listupPrinterSN(uint64_t *rSerialArray);
int chcusb_selectPrinter(uint8_t printerId, uint16_t *rResult); int WINAPI chcusb_selectPrinter(uint8_t printerId, uint16_t *rResult);
int chcusb_selectPrinterSN(uint64_t printerSN, uint16_t *rResult); int WINAPI chcusb_selectPrinterSN(uint64_t printerSN, uint16_t *rResult);
int chcusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen); int WINAPI chcusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen);
int chcusb_imageformat( int WINAPI chcusb_imageformat(uint16_t format, uint16_t ncomp, uint16_t depth, uint16_t width, uint16_t height, uint8_t * image, uint16_t* rResult);
uint16_t format, int WINAPI chcusb_imageformat_330(
uint16_t ncomp, uint16_t format,
uint16_t depth, uint16_t ncomp,
uint16_t width, uint16_t depth,
uint16_t height, uint16_t width,
uint16_t *rResult); uint16_t height,
int chcusb_setmtf(int32_t *mtf); uint16_t *rResult);
int chcusb_makeGamma(uint16_t k, uint8_t *intoneR, uint8_t *intoneG, uint8_t *intoneB); int __thiscall chcusb_setmtf(int32_t *mtf);
int chcusb_setIcctable( int WINAPI chcusb_makeGamma(uint16_t k, uint8_t *intoneR, uint8_t *intoneG, uint8_t *intoneB);
int WINAPI chcusb_setIcctable(
LPCSTR icc1, LPCSTR icc1,
LPCSTR icc2, LPCSTR icc2,
uint16_t intents, uint16_t intents,
@ -108,40 +110,42 @@ int chcusb_setIcctable(
uint8_t *outtoneG, uint8_t *outtoneG,
uint8_t *outtoneB, uint8_t *outtoneB,
uint16_t *rResult); uint16_t *rResult);
int chcusb_copies(uint16_t copies, uint16_t *rResult); int WINAPI chcusb_copies(uint16_t copies, uint16_t *rResult);
int chcusb_status(uint16_t *rResult); int WINAPI chcusb_status(uint16_t *rResult);
int chcusb_statusAll(uint8_t *idArray, uint16_t *rResultArray); int WINAPI chcusb_statusAll(uint8_t *idArray, uint16_t *rResultArray);
int chcusb_startpage(uint16_t postCardState, uint16_t *pageId, uint16_t *rResult); int WINAPI chcusb_startpage(uint16_t postCardState, uint16_t *pageId, uint16_t *rResult);
int chcusb_endpage(uint16_t *rResult); int WINAPI chcusb_startpage_300(uint16_t postCardState, uint16_t *rResult);
int chcusb_write(uint8_t *data, uint32_t *writeSize, uint16_t *rResult); int WINAPI chcusb_endpage(uint16_t *rResult);
int chcusb_writeLaminate(uint8_t *data, uint32_t *writeSize, uint16_t *rResult); int WINAPI chcusb_write(uint8_t *data, uint32_t *writeSize, uint16_t *rResult);
int chcusb_writeHolo(uint8_t *data, uint32_t *writeSize, uint16_t *rResult); int WINAPI chcusb_writeLaminate(uint8_t *data, uint32_t *writeSize, uint16_t *rResult);
int chcusb_setPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult); int WINAPI chcusb_writeHolo(uint8_t *data, uint32_t *writeSize, uint16_t *rResult);
int chcusb_getGamma(LPCSTR filename, uint8_t *r, uint8_t *g, uint8_t *b, uint16_t *rResult); int WINAPI chcusb_setPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult);
int chcusb_getMtf(LPCSTR filename, int32_t *mtf, uint16_t *rResult); int WINAPI chcusb_getGamma(LPCSTR filename, uint8_t *r, uint8_t *g, uint8_t *b, uint16_t *rResult);
int chcusb_cancelCopies(uint16_t pageId, uint16_t *rResult); int WINAPI chcusb_getMtf(LPCSTR filename, int32_t *mtf, uint16_t *rResult);
int chcusb_setPrinterToneCurve(uint16_t type, uint16_t number, uint16_t *data, uint16_t *rResult); int WINAPI chcusb_cancelCopies(uint16_t pageId, uint16_t *rResult);
int chcusb_getPrinterToneCurve(uint16_t type, uint16_t number, uint16_t *data, uint16_t *rResult); int WINAPI chcusb_setPrinterToneCurve(uint16_t type, uint16_t number, uint16_t *data, uint16_t *rResult);
int chcusb_blinkLED(uint16_t *rResult); int WINAPI chcusb_getPrinterToneCurve(uint16_t type, uint16_t number, uint16_t *data, uint16_t *rResult);
int chcusb_resetPrinter(uint16_t *rResult); int WINAPI chcusb_blinkLED(uint16_t *rResult);
int chcusb_AttachThreadCount(uint16_t *rCount, uint16_t *rMaxCount); int WINAPI chcusb_resetPrinter(uint16_t *rResult);
int chcusb_getPrintIDStatus(uint16_t pageId, uint8_t *rBuffer, uint16_t *rResult); int WINAPI chcusb_AttachThreadCount(uint16_t *rCount, uint16_t *rMaxCount);
int chcusb_setPrintStandby(uint16_t position, uint16_t *rResult); int WINAPI chcusb_getPrintIDStatus(uint16_t pageId, uint8_t *rBuffer, uint16_t *rResult);
int chcusb_testCardFeed(uint16_t mode, uint16_t times, uint16_t *rResult); int WINAPI chcusb_setPrintStandby(uint16_t position, uint16_t *rResult);
int chcusb_exitCard(uint16_t *rResult); int WINAPI chcusb_setPrintStandby_300(uint16_t *rResult);
int chcusb_getCardRfidTID(uint8_t *rCardTID, uint16_t *rResult); int WINAPI chcusb_testCardFeed(uint16_t mode, uint16_t times, uint16_t *rResult);
int chcusb_commCardRfidReader(uint8_t *sendData, uint8_t *rRecvData, uint32_t sendSize, uint32_t *rRecvSize, uint16_t *rResult); int WINAPI chcusb_exitCard(uint16_t *rResult);
int chcusb_updateCardRfidReader(uint8_t *data, uint32_t size, uint16_t *rResult); int WINAPI chcusb_getCardRfidTID(uint8_t *rCardTID, uint16_t *rResult);
int chcusb_getErrorLog(uint16_t index, uint8_t *rData, uint16_t *rResult); int WINAPI chcusb_commCardRfidReader(uint8_t *sendData, uint8_t *rRecvData, uint32_t sendSize, uint32_t *rRecvSize, uint16_t *rResult);
int chcusb_getErrorStatus(uint16_t *rBuffer); int WINAPI chcusb_updateCardRfidReader(uint8_t *data, uint32_t size, uint16_t *rResult);
int chcusb_setCutList(uint8_t *rData, uint16_t *rResult); int WINAPI chcusb_getErrorLog(uint16_t index, uint8_t *rData, uint16_t *rResult);
int chcusb_setLaminatePattern(uint16_t index, uint8_t *rData, uint16_t *rResult); int WINAPI chcusb_getErrorStatus(uint16_t *rBuffer);
int chcusb_color_adjustment(LPCSTR filename, int32_t a2, int32_t a3, int16_t a4, int16_t a5, int64_t a6, int64_t a7, uint16_t *rResult); int WINAPI chcusb_setCutList(uint8_t *rData, uint16_t *rResult);
int chcusb_color_adjustmentEx(int32_t a1, int32_t a2, int32_t a3, int16_t a4, int16_t a5, int64_t a6, int64_t a7, uint16_t *rResult); int WINAPI chcusb_setLaminatePattern(uint16_t index, uint8_t *rData, uint16_t *rResult);
int chcusb_getEEPROM(uint8_t index, uint8_t *rData, uint16_t *rResult); int WINAPI chcusb_color_adjustment(LPCSTR filename, int32_t a2, int32_t a3, int16_t a4, int16_t a5, int64_t a6, int64_t a7, uint16_t *rResult);
int chcusb_setParameter(uint8_t a1, uint32_t a2, uint16_t *rResult); int WINAPI chcusb_color_adjustmentEx(int32_t a1, int32_t a2, int32_t a3, int16_t a4, int16_t a5, int64_t a6, int64_t a7, uint16_t *rResult);
int chcusb_getParameter(uint8_t a1, uint8_t *a2, uint16_t *rResult); int WINAPI chcusb_getEEPROM(uint8_t index, uint8_t *rData, uint16_t *rResult);
int chcusb_universal_command(int32_t a1, uint8_t a2, int32_t a3, uint8_t *a4, uint16_t *rResult); int WINAPI chcusb_setParameter(uint8_t a1, uint32_t a2, uint16_t *rResult);
int WINAPI chcusb_getParameter(uint8_t a1, uint8_t *a2, uint16_t *rResult);
int WINAPI chcusb_universal_command(int32_t a1, uint8_t a2, int32_t a3, uint8_t *a4, uint16_t *rResult);
/* PrintDLL API hooks */ /* PrintDLL API hooks */
@ -491,7 +495,7 @@ static const struct hook_symbol C300usb_hooks[] = {
}, { }, {
.name = "chcusb_startpage", .name = "chcusb_startpage",
.ordinal = 0x0011, .ordinal = 0x0011,
.patch = chcusb_startpage, .patch = chcusb_startpage_300,
.link = NULL .link = NULL
}, { }, {
.name = "chcusb_endpage", .name = "chcusb_endpage",
@ -561,7 +565,7 @@ static const struct hook_symbol C300usb_hooks[] = {
}, { }, {
.name = "chcusb_setPrintStandby", .name = "chcusb_setPrintStandby",
.ordinal = 0x001f, .ordinal = 0x001f,
.patch = chcusb_setPrintStandby, .patch = chcusb_setPrintStandby_300,
.link = NULL .link = NULL
}, { }, {
.name = "chcusb_testCardFeed", .name = "chcusb_testCardFeed",
@ -1619,7 +1623,7 @@ static HRESULT deck_frame_encode_byte(struct iobuf *dest, uint8_t byte) {
// C3XXFWDLusb stubs // C3XXFWDLusb stubs
int fwdlusb_open(uint16_t *rResult) { int WINAPI fwdlusb_open(uint16_t *rResult) {
dprintf("Printer: C3XXFWDLusb: %s\n", __func__); dprintf("Printer: C3XXFWDLusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
@ -1627,33 +1631,33 @@ int fwdlusb_open(uint16_t *rResult) {
void fwdlusb_close() {} void fwdlusb_close() {}
int fwdlusb_listupPrinter(uint8_t *rIdArray) { int WINAPI fwdlusb_listupPrinter(uint8_t *rIdArray) {
dprintf("Printer: C3XXFWDLusb: %s\n", __func__); dprintf("Printer: C3XXFWDLusb: %s\n", __func__);
memset(rIdArray, 0xFF, 0x80); memset(rIdArray, 0xFF, 0x80);
rIdArray[0] = idNumber; rIdArray[0] = idNumber;
return 1; return 1;
} }
int fwdlusb_listupPrinterSN(uint64_t *rSerialArray) { int WINAPI fwdlusb_listupPrinterSN(uint64_t *rSerialArray) {
dprintf("Printer: C3XXFWDLusb: %s\n", __func__); dprintf("Printer: C3XXFWDLusb: %s\n", __func__);
memset(rSerialArray, 0xFF, 0x400); memset(rSerialArray, 0xFF, 0x400);
rSerialArray[0] = serialNo; rSerialArray[0] = serialNo;
return 1; return 1;
} }
int fwdlusb_selectPrinter(uint8_t printerId, uint16_t *rResult) { int WINAPI fwdlusb_selectPrinter(uint8_t printerId, uint16_t *rResult) {
dprintf("Printer: C3XXFWDLusb: %s\n", __func__); dprintf("Printer: C3XXFWDLusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int fwdlusb_selectPrinterSN(uint64_t printerSN, uint16_t *rResult) { int WINAPI fwdlusb_selectPrinterSN(uint64_t printerSN, uint16_t *rResult) {
dprintf("Printer: C3XXFWDLusb: %s\n", __func__); dprintf("Printer: C3XXFWDLusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int fwdlusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen) { int WINAPI fwdlusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen) {
dprintf("Printer: C3XXFWDLusb: %s\n", __func__); dprintf("Printer: C3XXFWDLusb: %s\n", __func__);
switch (tagNumber) { switch (tagNumber) {
case 0: // getPaperInfo case 0: // getPaperInfo
@ -1664,6 +1668,7 @@ int fwdlusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen)
if (*rLen != 0x99) *rLen = 0x99; if (*rLen != 0x99) *rLen = 0x99;
if (rBuffer) { if (rBuffer) {
memset(rBuffer, 0, *rLen); memset(rBuffer, 0, *rLen);
rBuffer[0] = 4; // firmware count
// bootFirmware // bootFirmware
int i = 1; int i = 1;
memcpy(rBuffer + i, mainFirmware, sizeof(mainFirmware)); memcpy(rBuffer + i, mainFirmware, sizeof(mainFirmware));
@ -1734,13 +1739,13 @@ int fwdlusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen)
return 1; return 1;
} }
int fwdlusb_status(uint16_t *rResult) { int WINAPI fwdlusb_status(uint16_t *rResult) {
dprintf("Printer: C3XXFWDLusb: %s\n", __func__); dprintf("Printer: C3XXFWDLusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int fwdlusb_statusAll(uint8_t *idArray, uint16_t *rResultArray) { int WINAPI fwdlusb_statusAll(uint8_t *idArray, uint16_t *rResultArray) {
dprintf("Printer: C3XXFWDLusb: %s\n", __func__); dprintf("Printer: C3XXFWDLusb: %s\n", __func__);
for (int i = 0; *(uint8_t *)(idArray + i) != 255 && i < 128; ++i) { for (int i = 0; *(uint8_t *)(idArray + i) != 255 && i < 128; ++i) {
*(uint16_t *)(rResultArray + 2 * i) = 0; *(uint16_t *)(rResultArray + 2 * i) = 0;
@ -1749,13 +1754,13 @@ int fwdlusb_statusAll(uint8_t *idArray, uint16_t *rResultArray) {
return 1; return 1;
} }
int fwdlusb_resetPrinter(uint16_t *rResult) { int WINAPI fwdlusb_resetPrinter(uint16_t *rResult) {
dprintf("Printer: C3XXFWDLusb: %s\n", __func__); dprintf("Printer: C3XXFWDLusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int fwdlusb_getFirmwareVersion(uint8_t *buffer, int size) { int WINAPI fwdlusb_getFirmwareVersion(uint8_t *buffer, int size) {
int8_t a; int8_t a;
uint32_t b = 0; uint32_t b = 0;
for (int32_t i = 0; i < size; ++i) { for (int32_t i = 0; i < size; ++i) {
@ -1776,7 +1781,7 @@ int fwdlusb_getFirmwareVersion(uint8_t *buffer, int size) {
return b; return b;
} }
int fwdlusb_updateFirmware_main(uint8_t update, LPCSTR filename, uint16_t *rResult) { int WINAPI fwdlusb_updateFirmware_main(uint8_t update, LPCSTR filename, uint16_t *rResult) {
DWORD result; DWORD result;
HANDLE fwFile = NULL; HANDLE fwFile = NULL;
DWORD bytesWritten = 0; DWORD bytesWritten = 0;
@ -1825,7 +1830,7 @@ int fwdlusb_updateFirmware_main(uint8_t update, LPCSTR filename, uint16_t *rResu
return result; return result;
} }
int fwdlusb_updateFirmware_dsp(uint8_t update, LPCSTR filename, uint16_t *rResult) { int WINAPI fwdlusb_updateFirmware_dsp(uint8_t update, LPCSTR filename, uint16_t *rResult) {
DWORD result; DWORD result;
HANDLE fwFile = NULL; HANDLE fwFile = NULL;
DWORD bytesWritten = 0; DWORD bytesWritten = 0;
@ -1874,7 +1879,7 @@ int fwdlusb_updateFirmware_dsp(uint8_t update, LPCSTR filename, uint16_t *rResul
return result; return result;
} }
int fwdlusb_updateFirmware_param(uint8_t update, LPCSTR filename, uint16_t *rResult) { int WINAPI fwdlusb_updateFirmware_param(uint8_t update, LPCSTR filename, uint16_t *rResult) {
DWORD result; DWORD result;
HANDLE fwFile = NULL; HANDLE fwFile = NULL;
DWORD bytesWritten = 0; DWORD bytesWritten = 0;
@ -1923,7 +1928,7 @@ int fwdlusb_updateFirmware_param(uint8_t update, LPCSTR filename, uint16_t *rRes
return result; return result;
} }
int fwdlusb_updateFirmware(uint8_t update, LPCSTR filename, uint16_t *rResult) { int WINAPI fwdlusb_updateFirmware(uint8_t update, LPCSTR filename, uint16_t *rResult) {
dprintf("Printer: C3XXFWDLusb: %s\n", __func__); dprintf("Printer: C3XXFWDLusb: %s\n", __func__);
if (update == 1) { if (update == 1) {
return fwdlusb_updateFirmware_main(update, filename, rResult); return fwdlusb_updateFirmware_main(update, filename, rResult);
@ -1937,7 +1942,7 @@ int fwdlusb_updateFirmware(uint8_t update, LPCSTR filename, uint16_t *rResult) {
} }
} }
int fwdlusb_getFirmwareInfo_main(LPCSTR filename, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult) { int WINAPI fwdlusb_getFirmwareInfo_main(LPCSTR filename, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult) {
DWORD result; DWORD result;
if (filename) { if (filename) {
@ -1973,7 +1978,7 @@ int fwdlusb_getFirmwareInfo_main(LPCSTR filename, uint8_t *rBuffer, uint32_t *rL
return result; return result;
} }
int fwdlusb_getFirmwareInfo_dsp(LPCSTR filename, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult) { int WINAPI fwdlusb_getFirmwareInfo_dsp(LPCSTR filename, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult) {
DWORD result; DWORD result;
if (filename) { if (filename) {
@ -2009,7 +2014,7 @@ int fwdlusb_getFirmwareInfo_dsp(LPCSTR filename, uint8_t *rBuffer, uint32_t *rLe
return result; return result;
} }
int fwdlusb_getFirmwareInfo_param(LPCSTR filename, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult) { int WINAPI fwdlusb_getFirmwareInfo_param(LPCSTR filename, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult) {
DWORD result; DWORD result;
if (filename) { if (filename) {
@ -2045,7 +2050,7 @@ int fwdlusb_getFirmwareInfo_param(LPCSTR filename, uint8_t *rBuffer, uint32_t *r
return result; return result;
} }
int fwdlusb_getFirmwareInfo(uint8_t update, LPCSTR filename, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult) { int WINAPI fwdlusb_getFirmwareInfo(uint8_t update, LPCSTR filename, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult) {
dprintf("Printer: C3XXFWDLusb: %s(update: %d, filename: %s)\n", __func__, update, filename); dprintf("Printer: C3XXFWDLusb: %s(update: %d, filename: %s)\n", __func__, update, filename);
if (!rBuffer) { if (!rBuffer) {
*rLen = 38; *rLen = 38;
@ -2064,25 +2069,25 @@ int fwdlusb_getFirmwareInfo(uint8_t update, LPCSTR filename, uint8_t *rBuffer, u
} }
} }
int fwdlusb_MakeThread(uint16_t maxCount) { int WINAPI fwdlusb_MakeThread(uint16_t maxCount) {
dprintf("Printer: C3XXFWDLusb: %s\n", __func__); dprintf("Printer: C3XXFWDLusb: %s\n", __func__);
return 1; return 1;
} }
int fwdlusb_ReleaseThread(uint16_t *rResult) { int WINAPI fwdlusb_ReleaseThread(uint16_t *rResult) {
dprintf("Printer: C3XXFWDLusb: %s\n", __func__); dprintf("Printer: C3XXFWDLusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int fwdlusb_AttachThreadCount(uint16_t *rCount, uint16_t *rMaxCount) { int WINAPI fwdlusb_AttachThreadCount(uint16_t *rCount, uint16_t *rMaxCount) {
dprintf("Printer: C3XXFWDLusb: %s\n", __func__); dprintf("Printer: C3XXFWDLusb: %s\n", __func__);
*rCount = 0; *rCount = 0;
*rMaxCount = 1; *rMaxCount = 1;
return 1; return 1;
} }
int fwdlusb_getErrorLog(uint16_t index, uint8_t *rData, uint16_t *rResult) { int WINAPI fwdlusb_getErrorLog(uint16_t index, uint8_t *rData, uint16_t *rResult) {
dprintf("Printer: C3XXFWDLusb: %s\n", __func__); dprintf("Printer: C3XXFWDLusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
@ -2090,12 +2095,12 @@ int fwdlusb_getErrorLog(uint16_t index, uint8_t *rData, uint16_t *rResult) {
// C3XXusb stubs // C3XXusb stubs
int chcusb_MakeThread(uint16_t maxCount) { int WINAPI chcusb_MakeThread(uint16_t maxCount) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
return 1; return 1;
} }
int chcusb_open(uint16_t *rResult) { int WINAPI chcusb_open(uint16_t *rResult) {
// Seed random for card id generation // Seed random for card id generation
srand(time(NULL)); srand(time(NULL));
generate_rfid(); generate_rfid();
@ -2109,38 +2114,38 @@ void chcusb_close() {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
} }
int chcusb_ReleaseThread(uint16_t *rResult) { int WINAPI chcusb_ReleaseThread(uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
return 1; return 1;
} }
int chcusb_listupPrinter(uint8_t *rIdArray) { int WINAPI chcusb_listupPrinter(uint8_t *rIdArray) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
memset(rIdArray, 0xFF, 0x80); memset(rIdArray, 0xFF, 0x80);
rIdArray[0] = idNumber; rIdArray[0] = idNumber;
return 1; return 1;
} }
int chcusb_listupPrinterSN(uint64_t *rSerialArray) { int WINAPI chcusb_listupPrinterSN(uint64_t *rSerialArray) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
memset(rSerialArray, 0xFF, 0x400); memset(rSerialArray, 0xFF, 0x400);
rSerialArray[0] = serialNo; rSerialArray[0] = serialNo;
return 1; return 1;
} }
int chcusb_selectPrinter(uint8_t printerId, uint16_t *rResult) { int WINAPI chcusb_selectPrinter(uint8_t printerId, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int chcusb_selectPrinterSN(uint64_t printerSN, uint16_t *rResult) { int WINAPI chcusb_selectPrinterSN(uint64_t printerSN, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int chcusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen) { int WINAPI chcusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen) {
// dprintf("Printer: C3XXusb: %s\n", __func__); // dprintf("Printer: C3XXusb: %s\n", __func__);
switch (tagNumber) { switch (tagNumber) {
@ -2154,6 +2159,7 @@ int chcusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen)
if (*rLen != 0x99) *rLen = 0x99; if (*rLen != 0x99) *rLen = 0x99;
if (rBuffer) { if (rBuffer) {
memset(rBuffer, 0, *rLen); memset(rBuffer, 0, *rLen);
rBuffer[0] = 4; // firmware count
// bootFirmware // bootFirmware
int i = 1; int i = 1;
memcpy(rBuffer + i, mainFirmware, sizeof(mainFirmware)); memcpy(rBuffer + i, mainFirmware, sizeof(mainFirmware));
@ -2239,6 +2245,8 @@ int chcusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen)
*rLen = 1; *rLen = 1;
if (awaitingCardExit) if (awaitingCardExit)
*rBuffer = 0xF0; *rBuffer = 0xF0;
else if (STATUS == 1)
*rBuffer = 1;
else else
*rBuffer = 0; *rBuffer = 0;
break; break;
@ -2294,7 +2302,18 @@ int chcusb_getPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen)
return 1; return 1;
} }
int chcusb_imageformat( int WINAPI chcusb_imageformat(
uint16_t format,
uint16_t ncomp,
uint16_t depth,
uint16_t width,
uint16_t height,
uint8_t *image,
uint16_t *rResult) {
return chcusb_imageformat_330(format, ncomp, depth, width, height, rResult);
}
int WINAPI chcusb_imageformat_330(
uint16_t format, uint16_t format,
uint16_t ncomp, uint16_t ncomp,
uint16_t depth, uint16_t depth,
@ -2310,14 +2329,14 @@ int chcusb_imageformat(
return 1; return 1;
} }
int chcusb_setmtf(int32_t *mtf) { int __thiscall chcusb_setmtf(int32_t *mtf) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
memcpy(MTF, mtf, sizeof(MTF)); memcpy(MTF, mtf, sizeof(MTF));
return 1; return 1;
} }
int chcusb_makeGamma(uint16_t k, uint8_t *intoneR, uint8_t *intoneG, uint8_t *intoneB) { int WINAPI chcusb_makeGamma(uint16_t k, uint8_t *intoneR, uint8_t *intoneG, uint8_t *intoneB) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
uint8_t tone; uint8_t tone;
@ -2348,7 +2367,7 @@ int chcusb_makeGamma(uint16_t k, uint8_t *intoneR, uint8_t *intoneG, uint8_t *in
return 1; return 1;
} }
int chcusb_setIcctable( int WINAPI chcusb_setIcctable(
LPCSTR icc1, LPCSTR icc1,
LPCSTR icc2, LPCSTR icc2,
uint16_t intents, uint16_t intents,
@ -2361,32 +2380,34 @@ int chcusb_setIcctable(
uint16_t *rResult) { uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
for (int i = 0; i < 256; ++i) { if (intoneR != NULL && intoneG != NULL && intoneB != NULL && outtoneR != NULL && outtoneG != NULL && outtoneB != NULL) {
intoneR[i] = i; for (int i = 0; i < 256; ++i) {
intoneG[i] = i; intoneR[i] = i;
intoneB[i] = i; intoneG[i] = i;
outtoneR[i] = i; intoneB[i] = i;
outtoneG[i] = i; outtoneR[i] = i;
outtoneB[i] = i; outtoneG[i] = i;
outtoneB[i] = i;
}
} }
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int chcusb_copies(uint16_t copies, uint16_t *rResult) { int WINAPI chcusb_copies(uint16_t copies, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int chcusb_status(uint16_t *rResult) { int WINAPI chcusb_status(uint16_t *rResult) {
// dprintf("Printer: C3XXusb: %s\n", __func__); // dprintf("Printer: C3XXusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int chcusb_statusAll(uint8_t *idArray, uint16_t *rResultArray) { int WINAPI chcusb_statusAll(uint8_t *idArray, uint16_t *rResultArray) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
for (int i = 0; *(uint8_t *)(idArray + i) != 255 && i < 128; ++i) { for (int i = 0; *(uint8_t *)(idArray + i) != 255 && i < 128; ++i) {
@ -2396,7 +2417,7 @@ int chcusb_statusAll(uint8_t *idArray, uint16_t *rResultArray) {
return 1; return 1;
} }
int chcusb_startpage(uint16_t postCardState, uint16_t *pageId, uint16_t *rResult) { int WINAPI chcusb_startpage(uint16_t postCardState, uint16_t *pageId, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
STATUS = 2; STATUS = 2;
@ -2406,7 +2427,16 @@ int chcusb_startpage(uint16_t postCardState, uint16_t *pageId, uint16_t *rResult
return 1; return 1;
} }
int chcusb_endpage(uint16_t *rResult) { int WINAPI chcusb_startpage_300(uint16_t postCardState, uint16_t *rResult) {
dprintf("Printer: C300usb: %s\n", __func__);
STATUS = 2;
*rResult = 0;
return 1;
}
int WINAPI chcusb_endpage(uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
awaitingCardExit = true; awaitingCardExit = true;
@ -2415,7 +2445,7 @@ int chcusb_endpage(uint16_t *rResult) {
return 1; return 1;
} }
int chcusb_write(uint8_t *data, uint32_t *writeSize, uint16_t *rResult) { int WINAPI chcusb_write(uint8_t *data, uint32_t *writeSize, uint16_t *rResult) {
SYSTEMTIME t; SYSTEMTIME t;
GetLocalTime(&t); GetLocalTime(&t);
@ -2439,7 +2469,7 @@ int chcusb_write(uint8_t *data, uint32_t *writeSize, uint16_t *rResult) {
return 1; return 1;
} }
int chcusb_writeLaminate(uint8_t *data, uint32_t *writeSize, uint16_t *rResult) { int WINAPI chcusb_writeLaminate(uint8_t *data, uint32_t *writeSize, uint16_t *rResult) {
SYSTEMTIME t; SYSTEMTIME t;
GetLocalTime(&t); GetLocalTime(&t);
@ -2458,7 +2488,7 @@ int chcusb_writeLaminate(uint8_t *data, uint32_t *writeSize, uint16_t *rResult)
return 1; return 1;
} }
int chcusb_writeHolo(uint8_t *data, uint32_t *writeSize, uint16_t *rResult) { int WINAPI chcusb_writeHolo(uint8_t *data, uint32_t *writeSize, uint16_t *rResult) {
SYSTEMTIME t; SYSTEMTIME t;
GetLocalTime(&t); GetLocalTime(&t);
@ -2477,7 +2507,7 @@ int chcusb_writeHolo(uint8_t *data, uint32_t *writeSize, uint16_t *rResult) {
return 1; return 1;
} }
int chcusb_setPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult) { int WINAPI chcusb_setPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
switch (tagNumber) { switch (tagNumber) {
@ -2495,7 +2525,7 @@ int chcusb_setPrinterInfo(uint16_t tagNumber, uint8_t *rBuffer, uint32_t *rLen,
return 1; return 1;
} }
int chcusb_getGamma(LPCSTR filename, uint8_t *r, uint8_t *g, uint8_t *b, uint16_t *rResult) { int WINAPI chcusb_getGamma(LPCSTR filename, uint8_t *r, uint8_t *g, uint8_t *b, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
for (int i = 0; i < 256; ++i) { for (int i = 0; i < 256; ++i) {
@ -2508,7 +2538,7 @@ int chcusb_getGamma(LPCSTR filename, uint8_t *r, uint8_t *g, uint8_t *b, uint16_
return 1; return 1;
} }
int chcusb_getMtf(LPCSTR filename, int32_t *mtf, uint16_t *rResult) { int WINAPI chcusb_getMtf(LPCSTR filename, int32_t *mtf, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
HANDLE hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); HANDLE hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
@ -2545,13 +2575,13 @@ int chcusb_getMtf(LPCSTR filename, int32_t *mtf, uint16_t *rResult) {
return 1; return 1;
} }
int chcusb_cancelCopies(uint16_t pageId, uint16_t *rResult) { int WINAPI chcusb_cancelCopies(uint16_t pageId, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int chcusb_setPrinterToneCurve(uint16_t type, uint16_t number, uint16_t *data, uint16_t *rResult) { int WINAPI chcusb_setPrinterToneCurve(uint16_t type, uint16_t number, uint16_t *data, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
if ((type > 0 && type < 3) && (number > 0 && number < 3)) { if ((type > 0 && type < 3) && (number > 0 && number < 3)) {
CURVE[type][number] = *data; CURVE[type][number] = *data;
@ -2560,7 +2590,7 @@ int chcusb_setPrinterToneCurve(uint16_t type, uint16_t number, uint16_t *data, u
return 1; return 1;
} }
int chcusb_getPrinterToneCurve(uint16_t type, uint16_t number, uint16_t *data, uint16_t *rResult) { int WINAPI chcusb_getPrinterToneCurve(uint16_t type, uint16_t number, uint16_t *data, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
if ((type > 0 && type < 3) && (number > 0 && number < 3)) { if ((type > 0 && type < 3) && (number > 0 && number < 3)) {
*data = CURVE[type][number]; *data = CURVE[type][number];
@ -2569,26 +2599,26 @@ int chcusb_getPrinterToneCurve(uint16_t type, uint16_t number, uint16_t *data, u
return 1; return 1;
} }
int chcusb_blinkLED(uint16_t *rResult) { int WINAPI chcusb_blinkLED(uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int chcusb_resetPrinter(uint16_t *rResult) { int WINAPI chcusb_resetPrinter(uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int chcusb_AttachThreadCount(uint16_t *rCount, uint16_t *rMaxCount) { int WINAPI chcusb_AttachThreadCount(uint16_t *rCount, uint16_t *rMaxCount) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
*rCount = 0; *rCount = 0;
*rMaxCount = 1; *rMaxCount = 1;
return 1; return 1;
} }
int chcusb_getPrintIDStatus(uint16_t pageId, uint8_t *rBuffer, uint16_t *rResult) { int WINAPI chcusb_getPrintIDStatus(uint16_t pageId, uint8_t *rBuffer, uint16_t *rResult) {
// dprintf("Printer: C3XXusb: %s\n", __func__); // dprintf("Printer: C3XXusb: %s\n", __func__);
memset(rBuffer, 0, 8); memset(rBuffer, 0, 8);
@ -2606,7 +2636,7 @@ int chcusb_getPrintIDStatus(uint16_t pageId, uint8_t *rBuffer, uint16_t *rResult
return 1; return 1;
} }
int chcusb_setPrintStandby(uint16_t position, uint16_t *rResult) { int WINAPI chcusb_setPrintStandby(uint16_t position, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
if (STATUS == 0) if (STATUS == 0)
@ -2622,13 +2652,29 @@ int chcusb_setPrintStandby(uint16_t position, uint16_t *rResult) {
return 1; return 1;
} }
int chcusb_testCardFeed(uint16_t mode, uint16_t times, uint16_t *rResult) { int WINAPI chcusb_setPrintStandby_300(uint16_t *rResult) {
dprintf("Printer: C300usb: %s\n", __func__);
*rResult = 0;
if (awaitingCardExit){ // 300 does not use exitCard, so reset this for getPrinterInfo.
awaitingCardExit = false;
STATUS = 1;
}
if (STATUS == 0)
{
STATUS = 1;
}
return 1;
}
int WINAPI chcusb_testCardFeed(uint16_t mode, uint16_t times, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int chcusb_exitCard(uint16_t *rResult) { int WINAPI chcusb_exitCard(uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
awaitingCardExit = false; awaitingCardExit = false;
@ -2638,7 +2684,7 @@ int chcusb_exitCard(uint16_t *rResult) {
return 1; return 1;
} }
int chcusb_getCardRfidTID(uint8_t *rCardTID, uint16_t *rResult) { int WINAPI chcusb_getCardRfidTID(uint8_t *rCardTID, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
memcpy(rCardTID, cardRFID, sizeof(cardRFID)); memcpy(rCardTID, cardRFID, sizeof(cardRFID));
@ -2646,7 +2692,7 @@ int chcusb_getCardRfidTID(uint8_t *rCardTID, uint16_t *rResult) {
return 1; return 1;
} }
int chcusb_commCardRfidReader(uint8_t *sendData, uint8_t *rRecvData, uint32_t sendSize, uint32_t *rRecvSize, uint16_t *rResult) { int WINAPI chcusb_commCardRfidReader(uint8_t *sendData, uint8_t *rRecvData, uint32_t sendSize, uint32_t *rRecvSize, uint16_t *rResult) {
uint8_t off; uint8_t off;
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
@ -2709,67 +2755,67 @@ int chcusb_commCardRfidReader(uint8_t *sendData, uint8_t *rRecvData, uint32_t se
return 1; return 1;
} }
int chcusb_updateCardRfidReader(uint8_t *data, uint32_t size, uint16_t *rResult) { int WINAPI chcusb_updateCardRfidReader(uint8_t *data, uint32_t size, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int chcusb_getErrorLog(uint16_t index, uint8_t *rData, uint16_t *rResult) { int WINAPI chcusb_getErrorLog(uint16_t index, uint8_t *rData, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int chcusb_getErrorStatus(uint16_t *rBuffer) { int WINAPI chcusb_getErrorStatus(uint16_t *rBuffer) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
memset(rBuffer, 0, 0x80); memset(rBuffer, 0, 0x80);
return 1; return 1;
} }
int chcusb_setCutList(uint8_t *rData, uint16_t *rResult) { int WINAPI chcusb_setCutList(uint8_t *rData, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int chcusb_setLaminatePattern(uint16_t index, uint8_t *rData, uint16_t *rResult) { int WINAPI chcusb_setLaminatePattern(uint16_t index, uint8_t *rData, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int chcusb_color_adjustment(LPCSTR filename, int32_t a2, int32_t a3, int16_t a4, int16_t a5, int64_t a6, int64_t a7, uint16_t *rResult) { int WINAPI chcusb_color_adjustment(LPCSTR filename, int32_t a2, int32_t a3, int16_t a4, int16_t a5, int64_t a6, int64_t a7, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int chcusb_color_adjustmentEx(int32_t a1, int32_t a2, int32_t a3, int16_t a4, int16_t a5, int64_t a6, int64_t a7, uint16_t *rResult) { int WINAPI chcusb_color_adjustmentEx(int32_t a1, int32_t a2, int32_t a3, int16_t a4, int16_t a5, int64_t a6, int64_t a7, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int chcusb_getEEPROM(uint8_t index, uint8_t *rData, uint16_t *rResult) { int WINAPI chcusb_getEEPROM(uint8_t index, uint8_t *rData, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int chcusb_setParameter(uint8_t a1, uint32_t a2, uint16_t *rResult) { int WINAPI chcusb_setParameter(uint8_t a1, uint32_t a2, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int chcusb_getParameter(uint8_t a1, uint8_t *a2, uint16_t *rResult) { int WINAPI chcusb_getParameter(uint8_t a1, uint8_t *a2, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
} }
int chcusb_universal_command(int32_t a1, uint8_t a2, int32_t a3, uint8_t *a4, uint16_t *rResult) { int WINAPI chcusb_universal_command(int32_t a1, uint8_t a2, int32_t a3, uint8_t *a4, uint16_t *rResult) {
dprintf("Printer: C3XXusb: %s\n", __func__); dprintf("Printer: C3XXusb: %s\n", __func__);
*rResult = 0; *rResult = 0;
return 1; return 1;
@ -2960,7 +3006,7 @@ int CHCUSB_getPrinterToneCurve(const void *handle, uint16_t type, uint16_t numbe
int CHCUSB_imageformat(const void *handle, uint16_t format, uint16_t ncomp, uint16_t depth, uint16_t width, uint16_t height, uint8_t *inputImage, uint16_t *rResult) int CHCUSB_imageformat(const void *handle, uint16_t format, uint16_t ncomp, uint16_t depth, uint16_t width, uint16_t height, uint8_t *inputImage, uint16_t *rResult)
{ {
return chcusb_imageformat(format, ncomp, depth, width, height, rResult); return chcusb_imageformat(format, ncomp, depth, width, height, inputImage, rResult);
} }
int CHCUSB_init(LPCSTR dllpath) int CHCUSB_init(LPCSTR dllpath)
@ -3282,3 +3328,8 @@ DWORD WriteArrayToFile(LPCSTR lpOutputFilePath, LPVOID lpDataTemp, DWORD nDataSi
#endif #endif
} }
void printer_set_dimensions(int width, int height){
WIDTH = width;
HEIGHT = height;
}

View File

@ -2,6 +2,7 @@
#include <windows.h> #include <windows.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
struct printer_config { struct printer_config {
bool enable; bool enable;
@ -15,3 +16,8 @@ struct printer_config {
void printer_hook_init(const struct printer_config *cfg, int rfid_port_no, HINSTANCE self); void printer_hook_init(const struct printer_config *cfg, int rfid_port_no, HINSTANCE self);
void printer_hook_insert_hooks(HMODULE target); void printer_hook_insert_hooks(HMODULE target);
void printer_set_dimensions(int width, int height);
int WINAPI fwdlusb_updateFirmware_main(uint8_t update, LPCSTR filename, uint16_t *rResult);
int WINAPI fwdlusb_updateFirmware_dsp(uint8_t update, LPCSTR filename, uint16_t *rResult);
int WINAPI fwdlusb_updateFirmware_param(uint8_t update, LPCSTR filename, uint16_t *rResult);

105
kemonohook/config.c Normal file
View File

@ -0,0 +1,105 @@
#include <assert.h>
#include <stddef.h>
#include "amex/config.h"
#include "board/config.h"
#include "hooklib/config.h"
#include "hooklib/dvd.h"
#include "kemonohook/config.h"
#include "platform/config.h"
void kemono_dll_config_load(
struct kemono_dll_config *cfg,
const wchar_t *filename) {
assert(cfg != NULL);
assert(filename != NULL);
GetPrivateProfileStringW(
L"kemonoio",
L"path",
L"",
cfg->path,
_countof(cfg->path),
filename);
}
void led15093_config_load(struct led15093_config *cfg, const wchar_t *filename)
{
assert(cfg != NULL);
assert(filename != NULL);
wchar_t tmpstr[16];
memset(cfg->board_number, ' ', sizeof(cfg->board_number));
memset(cfg->chip_number, ' ', sizeof(cfg->chip_number));
memset(cfg->boot_chip_number, ' ', sizeof(cfg->boot_chip_number));
cfg->enable = GetPrivateProfileIntW(L"led15093", L"enable", 1, filename);
cfg->port_no = GetPrivateProfileIntW(L"led15093", L"portNo", 0, filename);
cfg->high_baudrate = GetPrivateProfileIntW(L"led15093", L"highBaud", 0, filename);
cfg->fw_ver = GetPrivateProfileIntW(L"led15093", L"fwVer", 0xA0, filename);
cfg->fw_sum = GetPrivateProfileIntW(L"led15093", L"fwSum", 0xAA53, filename);
GetPrivateProfileStringW(
L"led15093",
L"boardNumber",
L"15093-04",
tmpstr,
_countof(tmpstr),
filename);
size_t n = wcstombs(cfg->board_number, tmpstr, sizeof(cfg->board_number));
for (int i = n; i < sizeof(cfg->board_number); i++)
{
cfg->board_number[i] = ' ';
}
GetPrivateProfileStringW(
L"led15093",
L"chipNumber",
L"6704 ",
tmpstr,
_countof(tmpstr),
filename);
n = wcstombs(cfg->chip_number, tmpstr, sizeof(cfg->chip_number));
for (int i = n; i < sizeof(cfg->chip_number); i++)
{
cfg->chip_number[i] = ' ';
}
GetPrivateProfileStringW(
L"led15093",
L"bootChipNumber",
L"6704 ",
tmpstr,
_countof(tmpstr),
filename);
n = wcstombs(cfg->boot_chip_number, tmpstr, sizeof(cfg->boot_chip_number));
for (int i = n; i < sizeof(cfg->boot_chip_number); i++)
{
cfg->boot_chip_number[i] = ' ';
}
}
void kemono_hook_config_load(
struct kemono_hook_config *cfg,
const wchar_t *filename) {
assert(cfg != NULL);
assert(filename != NULL);
platform_config_load(&cfg->platform, filename);
aime_config_load(&cfg->aime, filename);
dvd_config_load(&cfg->dvd, filename);
vfd_config_load(&cfg->vfd, filename);
kemono_dll_config_load(&cfg->dll, filename);
unity_config_load(&cfg->unity, filename);
printer_config_load(&cfg->printer, filename);
amex_config_load(&cfg->amex, filename);
led15093_config_load(&cfg->led15093, filename);
}

36
kemonohook/config.h Normal file
View File

@ -0,0 +1,36 @@
#pragma once
#include <stddef.h>
#include "amex/amex.h"
#include "board/config.h"
#include "board/led15093.h"
#include "hooklib/dvd.h"
#include "kemonohook/kemono-dll.h"
#include "platform/config.h"
#include "unityhook/config.h"
struct kemono_hook_config {
struct platform_config platform;
struct aime_config aime;
struct dvd_config dvd;
struct vfd_config vfd;
struct kemono_dll_config dll;
struct unity_config unity;
struct printer_config printer;
struct amex_config amex;
struct led15093_config led15093;
};
void kemono_dll_config_load(
struct kemono_dll_config *cfg,
const wchar_t *filename);
void kemono_hook_config_load(
struct kemono_hook_config *cfg,
const wchar_t *filename);

137
kemonohook/dllmain.c Normal file
View File

@ -0,0 +1,137 @@
#include <windows.h>
#include "board/io4.h"
#include "board/sg-reader.h"
#include "board/vfd.h"
#include "hook/process.h"
#include "hook/table.h"
#include "hook/iohook.h"
#include "hooklib/printer.h"
#include "hooklib/serial.h"
#include "hooklib/spike.h"
#include "kemonohook/config.h"
#include "kemonohook/hooks.h"
#include "kemonohook/jvs.h"
#include "kemonohook/kemono-dll.h"
#include "platform/platform.h"
#include "unityhook/hook.h"
#include "util/dprintf.h"
static HMODULE kemono_hook_mod;
static process_entry_t kemono_startup;
static struct kemono_hook_config kemono_hook_cfg;
static DWORD CALLBACK kemono_pre_startup(void) {
HRESULT hr;
dprintf("--- Begin kemono_pre_startup ---\n");
/* Load config */
kemono_hook_config_load(&kemono_hook_cfg, L".\\segatools.ini");
/* Hook Win32 APIs */
dvd_hook_init(&kemono_hook_cfg.dvd, kemono_hook_mod);
serial_hook_init();
// 2.02 does not call printer update functions
uint16_t ret;
fwdlusb_updateFirmware_main(1, "UnityApp\\Parade_Data\\StreamingAssets\\Printer\\E0223100-014E-C300-MAINAPP.BIN", &ret);
if (ret != 0){
goto fail;
}
fwdlusb_updateFirmware_dsp(2, "UnityApp\\Parade_Data\\StreamingAssets\\Printer\\E0223200-0101-C300-DSPAPP.BIN", &ret);
if (ret != 0){
goto fail;
}
fwdlusb_updateFirmware_param(3, "UnityApp\\Parade_Data\\StreamingAssets\\Printer\\D0460700-0101-C300-PARAM.BIN", &ret);
if (ret != 0){
goto fail;
}
printer_hook_init(&kemono_hook_cfg.printer, 0, kemono_hook_mod);
printer_set_dimensions(720, 1028); // printer doesn't call setimageformat
/* Initialize emulation hooks */
hr = platform_hook_init(
&kemono_hook_cfg.platform,
"SDFL",
"AAW1",
kemono_hook_mod);
if (FAILED(hr)) {
goto fail;
}
hr = sg_reader_hook_init(&kemono_hook_cfg.aime, 1, 1, kemono_hook_mod);
if (FAILED(hr)) {
goto fail;
}
hr = kemono_dll_init(&kemono_hook_cfg.dll, kemono_hook_mod);
if (FAILED(hr)) {
goto fail;
}
hr = amex_hook_init(&kemono_hook_cfg.amex, kemono_jvs_init);
if (FAILED(hr)) {
goto fail;
}
hr = led15093_hook_init(&kemono_hook_cfg.led15093, kemono_dll.led_init, kemono_dll.led_set_leds, 10, 1, 1, 2);
if (FAILED(hr)) {
goto fail;
}
kemono_extra_hooks_init();
/* Initialize Unity native plugin DLL hooks
There seems to be an issue with other DLL hooks if `LoadLibraryW` is
hooked earlier in the `kemonohook` initialization. */
unity_hook_init(&kemono_hook_cfg.unity, kemono_hook_mod, kemono_extra_hooks_load);
/* Initialize debug helpers */
spike_hook_init(L".\\segatools.ini");
dprintf("--- End kemono_pre_startup ---\n");
/* Jump to EXE start address */
return kemono_startup();
fail:
ExitProcess(EXIT_FAILURE);
}
BOOL WINAPI DllMain(HMODULE mod, DWORD cause, void *ctx) {
HRESULT hr;
if (cause != DLL_PROCESS_ATTACH) {
return TRUE;
}
kemono_hook_mod = mod;
hr = process_hijack_startup(kemono_pre_startup, &kemono_startup);
if (!SUCCEEDED(hr)) {
dprintf("Failed to hijack process startup: %x\n", (int) hr);
}
return SUCCEEDED(hr);
}

65
kemonohook/hooks.c Normal file
View File

@ -0,0 +1,65 @@
#include "hook/iohook.h"
#include "hook/procaddr.h"
#include "hook/table.h"
#include "hooklib/serial.h"
#include "kemonohook/hooks.h"
#include "util/dprintf.h"
static BOOL WINAPI hook_GetVersionExW(LPOSVERSIONINFOW lpVersionInformation);
static int (WINAPI *next_GetVersionExW)(LPOSVERSIONINFOW lpVersionInformation);
static const struct hook_symbol kemono_kernel32_syms[] = {
{
.name = "GetVersionExW",
.patch = hook_GetVersionExW,
.link = (void **) &next_GetVersionExW,
}
};
void kemono_extra_hooks_init(){
HMODULE serialportapi = LoadLibraryA("Parade_Data/Plugins/SerialPortAPI.dll"); // HACK??
if (serialportapi != NULL){
iohook_apply_hooks(serialportapi);
serial_hook_apply_hooks(serialportapi);
dprintf("Kemono: Successfully pre-loaded SerialPortAPI\n");
}
}
void kemono_extra_hooks_load(HMODULE mod, const wchar_t* target_module) {
// Workaround for AmManager.checkTarget:Environment.GetEnvironmentVariable("USERNAME")
SetEnvironmentVariableA("USERNAME", "AppUser");
// Workaround for AmManager.checkTarget, expects OS version to be 6.2 or 6.3
hook_table_apply(
mod,
"kernel32.dll",
kemono_kernel32_syms,
_countof(kemono_kernel32_syms));
// needed for LED COM port
// FIXME: SerialPortAPI.dll seems to be loaded twice? this causes a crash
/*if (_wcsicmp(L"SerialPortAPI.dll", target_module) == 0) {
iohook_apply_hooks(mod);
serial_hook_apply_hooks(mod);
dprintf("Kemono: Loaded I/O hooks for serial port\n");
}*/
}
static BOOL WINAPI hook_GetVersionExW(LPOSVERSIONINFOW lpVersionInformation) {
int result = next_GetVersionExW(lpVersionInformation);
if (result) {
lpVersionInformation->dwMajorVersion = 6;
lpVersionInformation->dwMinorVersion = 2;
lpVersionInformation->dwBuildNumber = 0;
dprintf("Kemono: GetVersionExW hook hit\n");
}
return result;
}

5
kemonohook/hooks.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
void kemono_extra_hooks_init();
void kemono_extra_hooks_load(HMODULE mod, const wchar_t* target_module);

139
kemonohook/jvs.c Normal file
View File

@ -0,0 +1,139 @@
#include <windows.h>
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "amex/jvs.h"
#include "board/io3.h"
#include "kemonohook/kemono-dll.h"
#include "jvs/jvs-bus.h"
#include "util/dprintf.h"
struct kemono_jvs_ir_mask {
uint16_t p1;
uint16_t p2;
};
static void kemono_jvs_read_switches(void *ctx, struct io3_switch_state *out);
static void kemono_jvs_read_coin_counter(
void *ctx,
uint8_t slot_no,
uint16_t *out);
static void kemono_jvs_write_gpio(void *ctx, uint32_t state);
static const struct io3_ops kemono_jvs_io3_ops = {
.read_switches = kemono_jvs_read_switches,
.read_coin_counter = kemono_jvs_read_coin_counter,
.write_gpio = kemono_jvs_write_gpio
};
static struct io3 kemono_jvs_io3;
HRESULT kemono_jvs_init(struct jvs_node **out)
{
HRESULT hr;
assert(out != NULL);
assert(kemono_dll.init != NULL);
dprintf("JVS I/O: Starting IO backend\n");
hr = kemono_dll.init();
if (FAILED(hr)) {
dprintf("JVS I/O: Backend error, I/O disconnected: %x\n", (int) hr);
return hr;
}
io3_init(&kemono_jvs_io3, NULL, &kemono_jvs_io3_ops, NULL);
*out = io3_to_jvs_node(&kemono_jvs_io3);
return S_OK;
}
static void kemono_jvs_read_switches(void *ctx, struct io3_switch_state *out)
{
const struct kemono_jvs_ir_mask *masks;
uint16_t opbtn;
uint16_t pbtn;
size_t i;
assert(out != NULL);
assert(kemono_dll.poll != NULL);
opbtn = 0;
pbtn = 0;
kemono_dll.poll(&opbtn, &pbtn);
out->system = 0x00;
out->p1 = 0x0000;
out->p2 = 0x0000;
if (opbtn & KEMONO_IO_OPBTN_TEST) {
out->system |= 1 << 7;
}
if (opbtn & KEMONO_IO_OPBTN_SERVICE) {
out->p1 |= 1 << 14;
}
if (pbtn & KEMONO_IO_GAMEBTN_UP) {
out->p1 |= 1 << 13;
}
if (pbtn & KEMONO_IO_GAMEBTN_DOWN) {
out->p1 |= 1 << 12;
}
if (pbtn & KEMONO_IO_GAMEBTN_LEFT) {
out->p1 |= 1 << 11;
}
if (pbtn & KEMONO_IO_GAMEBTN_RIGHT) {
out->p1 |= 1 << 10;
}
if (pbtn & KEMONO_IO_GAMEBTN_R) {
out->p1 |= 1 << 9;
}
if (pbtn & KEMONO_IO_GAMEBTN_G) {
out->p1 |= 1 << 7;
}
if (pbtn & KEMONO_IO_GAMEBTN_B) {
out->p1 |= 1 << 8;
}
if (pbtn & KEMONO_IO_GAMEBTN_START) {
out->p1 |= 1 << 15;
}
}
static void kemono_jvs_read_coin_counter(
void *ctx,
uint8_t slot_no,
uint16_t *out)
{
assert(out != NULL);
assert(kemono_dll.jvs_read_coin_counter != NULL);
if (slot_no > 0) {
return;
}
kemono_dll.jvs_read_coin_counter(out);
}
static void kemono_jvs_write_gpio(void *ctx, uint32_t state){
kemono_dll.jvs_write_gpio(state);
}

7
kemonohook/jvs.h Normal file
View File

@ -0,0 +1,7 @@
#pragma once
#include <windows.h>
#include "jvs/jvs-bus.h"
HRESULT kemono_jvs_init(struct jvs_node **root);

119
kemonohook/kemono-dll.c Normal file
View File

@ -0,0 +1,119 @@
#include <windows.h>
#include <assert.h>
#include <stdlib.h>
#include "kemonohook/kemono-dll.h"
#include "util/dll-bind.h"
#include "util/dprintf.h"
const struct dll_bind_sym kemono_dll_syms[] = {
{
.sym = "kemono_io_init",
.off = offsetof(struct kemono_dll, init),
},
{
.sym = "kemono_io_poll",
.off = offsetof(struct kemono_dll, poll),
},
{
.sym = "kemono_io_jvs_read_coin_counter",
.off = offsetof(struct kemono_dll, jvs_read_coin_counter),
},
{
.sym = "kemono_io_led_init",
.off = offsetof(struct kemono_dll, led_init),
},
{
.sym = "kemono_io_led_set_colors",
.off = offsetof(struct kemono_dll, led_set_leds),
},
{
.sym = "kemono_io_jvs_write_gpio",
.off = offsetof(struct kemono_dll, jvs_write_gpio),
}
};
struct kemono_dll kemono_dll;
// Copypasta DLL binding and diagnostic message boilerplate.
// Not much of this lends itself to being easily factored out. Also there
// will be a lot of API-specific branching code here eventually as new API
// versions get defined, so even though these functions all look the same
// now this won't remain the case forever.
HRESULT kemono_dll_init(const struct kemono_dll_config *cfg, HINSTANCE self) {
uint16_t (*get_api_version)(void);
const struct dll_bind_sym *sym;
HINSTANCE owned;
HINSTANCE src;
HRESULT hr;
assert(cfg != NULL);
assert(self != NULL);
if (cfg->path[0] != L'\0') {
owned = LoadLibraryW(cfg->path);
if (owned == NULL) {
hr = HRESULT_FROM_WIN32(GetLastError());
dprintf("Kemono IO: Failed to load IO DLL: %lx: %S\n",
hr,
cfg->path);
goto end;
}
dprintf("Kemono IO: Using custom IO DLL: %S\n", cfg->path);
src = owned;
} else {
owned = NULL;
src = self;
}
get_api_version = (void *) GetProcAddress(src, "kemono_io_get_api_version");
if (get_api_version != NULL) {
kemono_dll.api_version = get_api_version();
} else {
kemono_dll.api_version = 0x0100;
dprintf("Custom IO DLL does not expose kemono_io_get_api_version, "
"assuming API version 1.0.\n"
"Please ask the developer to update their DLL.\n");
}
if (kemono_dll.api_version >= 0x0200) {
hr = E_NOTIMPL;
dprintf("Kemono IO: Custom IO DLL implements an unsupported "
"API version (%#04x). Please update Segatools.\n",
kemono_dll.api_version);
goto end;
}
sym = kemono_dll_syms;
hr = dll_bind(&kemono_dll, src, &sym, _countof(kemono_dll_syms));
if (FAILED(hr)) {
if (src != self) {
dprintf("Kemono IO: Custom IO DLL does not provide function "
"\"%s\". Please contact your IO DLL's developer for "
"further assistance.\n",
sym->sym);
goto end;
} else {
dprintf("Internal error: could not reflect \"%s\"\n", sym->sym);
}
}
owned = NULL;
end:
if (owned != NULL) {
FreeLibrary(owned);
}
return hr;
}

29
kemonohook/kemono-dll.h Normal file
View File

@ -0,0 +1,29 @@
#pragma once
#include <windows.h>
#include "kemonoio/kemonoio.h"
struct kemono_dll {
uint16_t api_version;
HRESULT (*init)(void);
HRESULT (*poll)(uint16_t *ops, uint16_t *player);
void (*jvs_read_coin_counter)(uint16_t *coins);
HRESULT (*led_init)(void);
void (*led_set_leds)(uint8_t board, uint8_t *rgb);
void (*jvs_write_gpio)(uint32_t state);
};
struct kemono_dll_config {
wchar_t path[MAX_PATH];
};
extern struct kemono_dll kemono_dll;
HRESULT kemono_dll_init(const struct kemono_dll_config *cfg, HINSTANCE self);

83
kemonohook/kemonohook.def Normal file
View File

@ -0,0 +1,83 @@
LIBRARY kemonohook
EXPORTS
aime_io_get_api_version
aime_io_init
aime_io_led_set_color
aime_io_nfc_get_aime_id
aime_io_nfc_get_felica_id
aime_io_nfc_poll
amDllVideoClose @2
amDllVideoGetVBiosVersion @4
amDllVideoOpen @1
amDllVideoSetResolution @3
kemono_io_get_api_version
kemono_io_jvs_read_coin_counter
kemono_io_init
kemono_io_poll
kemono_io_led_init
kemono_io_led_set_colors
kemono_io_jvs_write_gpio
fwdlusb_open
fwdlusb_close
fwdlusb_listupPrinter
fwdlusb_listupPrinterSN
fwdlusb_selectPrinter
fwdlusb_selectPrinterSN
fwdlusb_getPrinterInfo
fwdlusb_status
fwdlusb_statusAll
fwdlusb_resetPrinter
fwdlusb_updateFirmware
fwdlusb_getFirmwareInfo
fwdlusb_MakeThread
fwdlusb_ReleaseThread
fwdlusb_AttachThreadCount
fwdlusb_getErrorLog
chcusb_MakeThread
chcusb_open
chcusb_close
chcusb_ReleaseThread
chcusb_listupPrinter
chcusb_listupPrinterSN
chcusb_selectPrinter
chcusb_selectPrinterSN
chcusb_getPrinterInfo
chcusb_imageformat
chcusb_setmtf
chcusb_makeGamma
chcusb_setIcctable
chcusb_copies
chcusb_status
chcusb_statusAll
chcusb_startpage
chcusb_endpage
chcusb_write
chcusb_writeLaminate
chcusb_writeHolo
chcusb_setPrinterInfo
chcusb_getGamma
chcusb_getMtf
chcusb_cancelCopies
chcusb_setPrinterToneCurve
chcusb_getPrinterToneCurve
chcusb_blinkLED
chcusb_resetPrinter
chcusb_AttachThreadCount
chcusb_getPrintIDStatus
chcusb_setPrintStandby
chcusb_testCardFeed
chcusb_exitCard
chcusb_getCardRfidTID
chcusb_commCardRfidReader
chcusb_updateCardRfidReader
chcusb_getErrorLog
chcusb_getErrorStatus
chcusb_setCutList
chcusb_setLaminatePattern
chcusb_color_adjustment
chcusb_color_adjustmentEx
chcusb_getEEPROM
chcusb_setParameter
chcusb_getParameter
chcusb_universal_command

34
kemonohook/meson.build Normal file
View File

@ -0,0 +1,34 @@
shared_library(
'kemonohook',
name_prefix : '',
include_directories : inc,
implicit_include_directories : false,
vs_module_defs : 'kemonohook.def',
c_pch : '../precompiled.h',
dependencies : [
capnhook.get_variable('hook_dep'),
capnhook.get_variable('hooklib_dep'),
],
link_with : [
aimeio_lib,
amex_lib,
board_lib,
hooklib_lib,
jvs_lib,
kemonoio_lib,
platform_lib,
unityhook_lib,
util_lib,
],
sources : [
'config.c',
'config.h',
'dllmain.c',
'hooks.c',
'hooks.h',
'jvs.c',
'jvs.h',
'kemono-dll.c',
'kemono-dll.h',
],
)

28
kemonoio/config.c Normal file
View File

@ -0,0 +1,28 @@
#include <windows.h>
#include <assert.h>
#include <stddef.h>
#include <stdio.h>
#include "kemonoio/config.h"
void kemono_io_config_load(
struct kemono_io_config *cfg,
const wchar_t *filename) {
assert(cfg != NULL);
assert(filename != NULL);
cfg->vk_test = GetPrivateProfileIntW(L"io3", L"test", '1', filename);
cfg->vk_service = GetPrivateProfileIntW(L"io3", L"service", '2', filename);
cfg->vk_coin = GetPrivateProfileIntW(L"io3", L"coin", '3', filename);
cfg->vk_left = GetPrivateProfileIntW(L"io3", L"left", VK_LEFT, filename);
cfg->vk_right = GetPrivateProfileIntW(L"io3", L"right", VK_RIGHT, filename);
cfg->vk_up = GetPrivateProfileIntW(L"io3", L"up", VK_UP, filename);
cfg->vk_down = GetPrivateProfileIntW(L"io3", L"down", VK_DOWN, filename);
cfg->vk_red = GetPrivateProfileIntW(L"io3", L"red", 'A', filename);
cfg->vk_green = GetPrivateProfileIntW(L"io3", L"green", 'S', filename);
cfg->vk_blue = GetPrivateProfileIntW(L"io3", L"blue", 'D', filename);
cfg->vk_start = GetPrivateProfileIntW(L"io3", L"start", VK_RETURN, filename);
}

25
kemonoio/config.h Normal file
View File

@ -0,0 +1,25 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
struct kemono_io_config {
uint8_t vk_test;
uint8_t vk_service;
uint8_t vk_coin;
uint8_t vk_left;
uint8_t vk_right;
uint8_t vk_up;
uint8_t vk_down;
uint8_t vk_red;
uint8_t vk_green;
uint8_t vk_blue;
uint8_t vk_start;
};
void kemono_io_config_load(
struct kemono_io_config *cfg,
const wchar_t *filename);

109
kemonoio/kemonoio.c Normal file
View File

@ -0,0 +1,109 @@
#include <windows.h>
#include <limits.h>
#include <stdint.h>
#include <assert.h>
#include <util/dprintf.h>
#include "kemonoio/kemonoio.h"
#include "kemonoio/config.h"
static uint8_t kemono_opbtn;
static uint16_t kemono_pbtn;
static uint16_t kemono_io_coins;
static struct kemono_io_config kemono_io_cfg;
static bool kemono_io_coin;
uint16_t kemono_io_get_api_version(void) {
return 0x0100;
}
HRESULT kemono_io_init(void) {
kemono_io_config_load(&kemono_io_cfg, L".\\segatools.ini");
kemono_io_coins = 0;
return S_OK;
}
HRESULT kemono_io_poll(uint16_t *ops, uint16_t *player) {
kemono_opbtn = 0;
kemono_pbtn = 0;
if (GetAsyncKeyState(kemono_io_cfg.vk_test) & 0x8000) {
kemono_opbtn |= KEMONO_IO_OPBTN_TEST;
}
if (GetAsyncKeyState(kemono_io_cfg.vk_service) & 0x8000) {
kemono_opbtn |= KEMONO_IO_OPBTN_SERVICE;
}
if (kemono_io_cfg.vk_coin &&
(GetAsyncKeyState(kemono_io_cfg.vk_coin) & 0x8000)) {
if (!kemono_io_coin) {
kemono_io_coin = true;
kemono_io_coins++;
}
} else {
kemono_io_coin = false;
}
if (GetAsyncKeyState(kemono_io_cfg.vk_up)) {
kemono_pbtn |= KEMONO_IO_GAMEBTN_UP;
}
if (GetAsyncKeyState(kemono_io_cfg.vk_down)) {
kemono_pbtn |= KEMONO_IO_GAMEBTN_DOWN;
}
if (GetAsyncKeyState(kemono_io_cfg.vk_left)) {
kemono_pbtn |= KEMONO_IO_GAMEBTN_LEFT;
}
if (GetAsyncKeyState(kemono_io_cfg.vk_right)) {
kemono_pbtn |= KEMONO_IO_GAMEBTN_RIGHT;
}
if (GetAsyncKeyState(kemono_io_cfg.vk_red)) {
kemono_pbtn |= KEMONO_IO_GAMEBTN_R;
}
if (GetAsyncKeyState(kemono_io_cfg.vk_green)) {
kemono_pbtn |= KEMONO_IO_GAMEBTN_G;
}
if (GetAsyncKeyState(kemono_io_cfg.vk_blue)) {
kemono_pbtn |= KEMONO_IO_GAMEBTN_B;
}
if (GetAsyncKeyState(kemono_io_cfg.vk_start)) {
kemono_pbtn |= KEMONO_IO_GAMEBTN_START;
}
if (ops != NULL) {
*ops = kemono_opbtn;
}
if (player != NULL) {
*player = kemono_pbtn;
}
return S_OK;
}
void kemono_io_jvs_read_coin_counter(uint16_t *out) {
assert(out != NULL);
*out = kemono_io_coins;
}
HRESULT kemono_io_led_init(void) {
return S_OK;
}
void kemono_io_led_set_colors(uint8_t board, uint8_t *rgb) {
}
void kemono_io_jvs_write_gpio(uint32_t state){
}

81
kemonoio/kemonoio.h Normal file
View File

@ -0,0 +1,81 @@
#pragma once
#include <windows.h>
#include <stdint.h>
enum {
KEMONO_IO_OPBTN_TEST = 0x01,
KEMONO_IO_OPBTN_SERVICE = 0x02
};
enum {
KEMONO_IO_GAMEBTN_UP = 0x01,
KEMONO_IO_GAMEBTN_DOWN = 0x02,
KEMONO_IO_GAMEBTN_LEFT = 0x04,
KEMONO_IO_GAMEBTN_RIGHT = 0x08,
KEMONO_IO_GAMEBTN_R = 0x10,
KEMONO_IO_GAMEBTN_G = 0x20,
KEMONO_IO_GAMEBTN_B = 0x40,
KEMONO_IO_GAMEBTN_START = 0x80
};
/* Get the version of the Kemono IO API that this DLL supports. This
function should return a positive 16-bit integer, where the high byte is
the major version and the low byte is the minor version (as defined by the
Semantic Versioning standard).
The latest API version as of this writing is 0x0100. */
uint16_t kemono_io_get_api_version(void);
/* Initialize the IO DLL. This is the second function that will be called on
your DLL, after kemono_io_get_api_version.
All subsequent calls to this API may originate from arbitrary threads.
Minimum API version: 0x0100 */
HRESULT kemono_io_init(void);
/* Send any queued outputs (of which there are currently none, though this may
change in subsequent API versions) and retrieve any new inputs.
Minimum API version: 0x0100 */
HRESULT kemono_io_poll(uint16_t* ops, uint16_t* player);
/* Read the current state of the coin counter. This value should be incremented
for every coin detected by the coin acceptor mechanism. This count does not
need to persist beyond the lifetime of the process.
Minimum API version: 0x0100 */
void kemono_io_jvs_read_coin_counter(uint16_t *out);
/* Initialize LED emulation. This function will be called before any
other fgo_io_led_*() function calls.
All subsequent calls may originate from arbitrary threads and some may
overlap with each other. Ensuring synchronization inside your IO DLL is
your responsibility.
Minimum API version: 0x0100 */
HRESULT kemono_io_led_init(void);
/* Update the RGB LEDs.
The left side LED bar are indices 0 to 32.
The right side LED bar are indices 33 to 65.
Minimum API version: 0x0100 */
void kemono_io_led_set_colors(uint8_t board, uint8_t *rgb);
/* Update the button LEDs.
Button R: Bit 15
Button G: Bit 1
Button B: Bit 13
Start Button: Bit 11
Minimum API version: 0x0100 */
void kemono_io_jvs_write_gpio(uint32_t state);

13
kemonoio/meson.build Normal file
View File

@ -0,0 +1,13 @@
kemonoio_lib = static_library(
'kemonoio_lib',
name_prefix : '',
include_directories : inc,
implicit_include_directories : false,
c_pch : '../precompiled.h',
sources : [
'kemonoio.c',
'kemonoio.h',
'config.c',
'config.h',
],
)

View File

@ -102,7 +102,7 @@ static DWORD CALLBACK mai2_pre_startup(void)
There seems to be an issue with other DLL hooks if `LoadLibraryW` is There seems to be an issue with other DLL hooks if `LoadLibraryW` is
hooked earlier in the `mai2hook` initialization. */ hooked earlier in the `mai2hook` initialization. */
unity_hook_init(&mai2_hook_cfg.unity, mai2_hook_mod); unity_hook_init(&mai2_hook_cfg.unity, mai2_hook_mod, NULL);
/* Initialize debug helpers */ /* Initialize debug helpers */

View File

@ -110,6 +110,7 @@ subdir('mercuryio')
subdir('cxbio') subdir('cxbio')
subdir('tokyoio') subdir('tokyoio')
subdir('fgoio') subdir('fgoio')
subdir('kemonoio')
subdir('chunihook') subdir('chunihook')
subdir('divahook') subdir('divahook')
@ -126,3 +127,4 @@ subdir('mercuryhook')
subdir('cxbhook') subdir('cxbhook')
subdir('tokyohook') subdir('tokyohook')
subdir('fgohook') subdir('fgohook')
subdir('kemonohook')

View File

@ -110,7 +110,7 @@ static DWORD CALLBACK mu3_pre_startup(void)
There seems to be an issue with other DLL hooks if `LoadLibraryW` is There seems to be an issue with other DLL hooks if `LoadLibraryW` is
hooked earlier in the `mu3hook` initialization. */ hooked earlier in the `mu3hook` initialization. */
unity_hook_init(&mu3_hook_cfg.unity, mu3_hook_mod); unity_hook_init(&mu3_hook_cfg.unity, mu3_hook_mod, NULL);
/* Initialize debug helpers */ /* Initialize debug helpers */

View File

@ -34,11 +34,11 @@ static HRESULT vfs_path_hook_option(
static HRESULT vfs_reg_read_amfs(void *bytes, uint32_t *nbytes); static HRESULT vfs_reg_read_amfs(void *bytes, uint32_t *nbytes);
static HRESULT vfs_reg_read_appdata(void *bytes, uint32_t *nbytes); static HRESULT vfs_reg_read_appdata(void *bytes, uint32_t *nbytes);
static wchar_t* hook_System_getAppRootPath(); static __thiscall wchar_t* hook_System_getAppRootPath();
static wchar_t* (*next_System_getAppRootPath)(); static __thiscall wchar_t* (*next_System_getAppRootPath)();
static wchar_t* hook_AppImage_getOptionMountRootPath(); static __thiscall wchar_t* hook_AppImage_getOptionMountRootPath();
static wchar_t* (*next_AppImage_getOptionMountRootPath)(); static __thiscall wchar_t* (*next_AppImage_getOptionMountRootPath)();
static const struct hook_symbol amdaemon_syms[] = { static const struct hook_symbol amdaemon_syms[] = {
{ {
@ -510,7 +510,7 @@ static HRESULT vfs_reg_read_appdata(void *bytes, uint32_t *nbytes)
return reg_hook_read_wstr(bytes, nbytes, L"Y:\\"); return reg_hook_read_wstr(bytes, nbytes, L"Y:\\");
} }
static wchar_t* hook_System_getAppRootPath() static __thiscall wchar_t* hook_System_getAppRootPath()
{ {
wchar_t *path = malloc(sizeof(wchar_t) * MAX_PATH); wchar_t *path = malloc(sizeof(wchar_t) * MAX_PATH);
wcscpy_s(path, MAX_PATH, vfs_config.appdata); wcscpy_s(path, MAX_PATH, vfs_config.appdata);
@ -520,7 +520,7 @@ static wchar_t* hook_System_getAppRootPath()
return path; return path;
} }
static wchar_t* hook_AppImage_getOptionMountRootPath() static __thiscall wchar_t* hook_AppImage_getOptionMountRootPath()
{ {
wchar_t *path = malloc(sizeof(wchar_t) * MAX_PATH); wchar_t *path = malloc(sizeof(wchar_t) * MAX_PATH);
wcscpy_s(path, MAX_PATH, vfs_config.option); wcscpy_s(path, MAX_PATH, vfs_config.option);

View File

@ -39,6 +39,8 @@ static const size_t target_modules_len = _countof(target_modules);
static void dll_hook_insert_hooks(HMODULE target); static void dll_hook_insert_hooks(HMODULE target);
static unity_hook_callback_func hook_load_callback;
static HMODULE WINAPI hook_LoadLibraryW(const wchar_t *name); static HMODULE WINAPI hook_LoadLibraryW(const wchar_t *name);
static HMODULE (WINAPI *next_LoadLibraryW)(const wchar_t *name); static HMODULE (WINAPI *next_LoadLibraryW)(const wchar_t *name);
static HMODULE WINAPI hook_LoadLibraryExW(const wchar_t *name, HANDLE hFile, DWORD dwFlags); static HMODULE WINAPI hook_LoadLibraryExW(const wchar_t *name, HANDLE hFile, DWORD dwFlags);
@ -57,7 +59,7 @@ static const struct hook_symbol unity_kernel32_syms[] = {
}; };
void unity_hook_init(const struct unity_config *cfg, HINSTANCE self) { void unity_hook_init(const struct unity_config *cfg, HINSTANCE self, unity_hook_callback_func callback) {
assert(cfg != NULL); assert(cfg != NULL);
if (!cfg->enable) { if (!cfg->enable) {
@ -71,6 +73,8 @@ void unity_hook_init(const struct unity_config *cfg, HINSTANCE self) {
memcpy(&unity_config, cfg, sizeof(*cfg)); memcpy(&unity_config, cfg, sizeof(*cfg));
dll_hook_insert_hooks(NULL); dll_hook_insert_hooks(NULL);
hook_load_callback = callback;
unity_hook_initted = true; unity_hook_initted = true;
dprintf("Unity: Hook enabled.\n"); dprintf("Unity: Hook enabled.\n");
} }
@ -144,6 +148,9 @@ static HMODULE WINAPI hook_LoadLibraryW(const wchar_t *name)
reg_hook_insert_hooks(result); reg_hook_insert_hooks(result);
clock_hook_insert_hooks(result); clock_hook_insert_hooks(result);
proc_addr_insert_hooks(result); proc_addr_insert_hooks(result);
if (hook_load_callback != NULL){
hook_load_callback(result, target_module);
}
// Not needed? // Not needed?
// serial_hook_apply_hooks(result); // serial_hook_apply_hooks(result);

View File

@ -4,4 +4,6 @@
#include "config.h" #include "config.h"
void unity_hook_init(const struct unity_config *cfg, HINSTANCE self); typedef void (*unity_hook_callback_func)(HMODULE, const wchar_t*);
void unity_hook_init(const struct unity_config *cfg, HINSTANCE self, unity_hook_callback_func callback);