Files
segatools/common/hooklib/printer_cx.c
2025-09-30 12:14:00 +02:00

919 lines
28 KiB
C

// ReSharper disable CppParameterNeverUsed
// ReSharper disable CppParameterMayBeConstPtrOrRef
#include "printer_cx.h"
#include <assert.h>
#include <stdio.h>
#include <stdint.h>
#include <windows.h>
#include <wtypes.h>
#include "imageutil.h"
#include "hook/procaddr.h"
#include "hook/table.h"
#include "util/dprintf.h"
#pragma region prototypes
static int __stdcall hook_CXCMD_Retransfer();
static bool __stdcall hook_CXCMD_CheckIfConnected(int* pSlotId, int* pId);
static int __stdcall hook_CXCMD_xImageOut();
static int __stdcall hook_CXCMD_MoveCard(int slotId, int id, int dest, int flip, int filmInit, int immed);
static int __stdcall hook_CXCMD_xWriteMagData();
static int __stdcall hook_CXCMD_SecurityPrint(int slotId, int id, int color, int bufferIndex, int immed);
static int __stdcall hook_CXCMD_ScanPrinterNext();
static int __stdcall hook_CXCMD_Print(int slotId, int id, int color, int bufferIndex, int immed);
static int __stdcall hook_CXCMD_RezeroUnit(int slotId, int id, int action);
static int __stdcall hook_CXCMD_WriteMagData();
static int __stdcall hook_CXCMD_LogSense(int iSlot, int iID, int iPage, uint8_t* pbyBuffer);
static int __stdcall hook_CXCMD_StandardInquiry(int iSlot, int iID, uint8_t* pbyBuffer);
static int __stdcall hook_CXCMD_ModeSense(int iSlot, int iID, int iPC, int iPage, uint8_t* pbyBuffer);
static int __stdcall hook_CXCMD_UpdateFirmware(int iSlot, int iID, char* pFile, int iDataID);
static int __stdcall hook_CXCMD_ModeSelect(int iSlot, int iID, int iSp, int iPage, uint8_t* pbyData);
static int __stdcall hook_CXCMD_GetPrintingStatus();
static int __stdcall hook_CXCMD_SendDiagnostic(int iSlot, int iID, int iTestMode, int iTestPatten, int iTestCount);
static int __stdcall hook_CXCMD_RetransferAndTurn(int slotId, int id, int immed);
static int __stdcall hook_CXCMD_LogSelect(int iSlot, int iID, int iMod);
static int __stdcall hook_CXCMD_ReadPosition(int slotId, int id, uint8_t* buffer);
static int __stdcall hook_CXCMD_SecurityLock();
static int __stdcall hook_CXCMD_SetPrintingStatus();
static int __stdcall hook_CXCMD_xReadISOMagData();
static int __stdcall hook_CXCMD_WriteISO3TrackMagData();
static int __stdcall hook_CXCMD_PasswordSet();
static int __stdcall hook_CXCMD_GetPrinterStatus();
static int __stdcall hook_CXCMD_WriteProjectCode();
static int __stdcall hook_CXCMD_LoadCard(int slotId, int id, int dest, int flip, int filmInit, int immed);
static int __stdcall hook_CXCMD_ReadMagData();
static int __stdcall hook_CXCMD_ScanPrinter(int* pSlotId, int* pId);
static int __stdcall hook_CXCMD_xWriteISOMagData();
static int __stdcall hook_CXCMD_ICControl();
static int __stdcall hook_CXCMD_ImageOut(int slotId, int id, uint8_t* plane, int length, int color, int bufferIndex);
static int __stdcall hook_CXCMD_ReadBuffer(int iSlot, int iID, int iMode, int iBufferID, uint8_t* pbyData, int iOffset,
int iLength);
static int __stdcall hook_CXCMD_xReadMagData();
static int __stdcall hook_CXCMD_WriteBuffer(int iSlot, int iID, int iMode, int iBufferID, uint8_t* pbyData, int iOffset,
int iLength);
static int __stdcall hook_CXCMD_DefineLUT(int slotId, int id, int color, int length, uint8_t* buffer);
static int __stdcall hook_CXCMD_ReadISO3TrackMagData();
static int __stdcall hook_CXCMD_TestUnitReady(int slotId, int id);
static int __stdcall hook_CXCMD_RetransferAndEject(int slotId, int id, int immed);
static bool __stdcall hook_Lut24_Exchange(const wchar_t* pFile, uint8_t* y, uint8_t* m, uint8_t* c, int sizeY, int sizeM,
int sizeC);
static bool __stdcall hook_Wdata_create(uint8_t* pbyRdata, uint8_t* pbyGdata, uint8_t* pbyBdata, int iWidth,
int iHeight, bool bPortrait, int iAlgorithim, uint8_t* pbyWdata);
static int __cdecl hook_init_accesscodekey(BSTR fileName);
static int __cdecl hook_accesscodekeyoverwriteheader(void* context, BSTR header, int headerLen, BSTR accessheaderkey, int headerkeylen);
#pragma endregion
#pragma region hooktables
static const struct hook_symbol hook_pcp_syms[] = {
{
.name = "CXCMD_Retransfer",
.patch = hook_CXCMD_Retransfer,
.ordinal = 19,
},
{
.name = "CXCMD_CheckIfConnected",
.patch = hook_CXCMD_CheckIfConnected,
.ordinal = 1,
},
{
.name = "CXCMD_xImageOut",
.patch = hook_CXCMD_xImageOut,
.ordinal = 36,
},
{
.name = "CXCMD_MoveCard",
.patch = hook_CXCMD_MoveCard,
.ordinal = 12,
},
{
.name = "CXCMD_xWriteMagData",
.patch = hook_CXCMD_xWriteMagData,
.ordinal = 40,
},
{
.name = "CXCMD_SecurityPrint",
.patch = hook_CXCMD_SecurityPrint,
.ordinal = 26,
},
{
.name = "CXCMD_ScanPrinterNext",
.patch = hook_CXCMD_ScanPrinterNext,
.ordinal = 24,
},
{
.name = "CXCMD_Print",
.patch = hook_CXCMD_Print,
.ordinal = 14,
},
{
.name = "CXCMD_RezeroUnit",
.patch = hook_CXCMD_RezeroUnit,
.ordinal = 22,
},
{
.name = "CXCMD_WriteMagData",
.patch = hook_CXCMD_WriteMagData,
.ordinal = 34,
},
{
.name = "CXCMD_LogSense",
.patch = hook_CXCMD_LogSense,
.ordinal = 9,
},
{
.name = "CXCMD_StandardInquiry",
.patch = hook_CXCMD_StandardInquiry,
.ordinal = 29,
},
{
.name = "CXCMD_ModeSense",
.patch = hook_CXCMD_ModeSense,
.ordinal = 11,
},
{
.name = "CXCMD_UpdateFirmware",
.patch = hook_CXCMD_UpdateFirmware,
.ordinal = 31,
},
{
.name = "CXCMD_ModeSelect",
.patch = hook_CXCMD_ModeSelect,
.ordinal = 10,
},
{
.name = "CXCMD_GetPrintingStatus",
.patch = hook_CXCMD_GetPrintingStatus,
.ordinal = 4,
},
{
.name = "CXCMD_SendDiagnostic",
.patch = hook_CXCMD_SendDiagnostic,
.ordinal = 27,
},
{
.name = "CXCMD_RetransferAndTurn",
.patch = hook_CXCMD_RetransferAndTurn,
.ordinal = 21,
},
{
.name = "CXCMD_LogSelect",
.patch = hook_CXCMD_LogSelect,
.ordinal = 8,
},
{
.name = "CXCMD_ReadPosition",
.patch = hook_CXCMD_ReadPosition,
.ordinal = 18,
},
{
.name = "CXCMD_SecurityLock",
.patch = hook_CXCMD_SecurityLock,
.ordinal = 25,
},
{
.name = "CXCMD_SetPrintingStatus",
.patch = hook_CXCMD_SetPrintingStatus,
.ordinal = 28,
},
{
.name = "CXCMD_xReadISOMagData",
.patch = hook_CXCMD_xReadISOMagData,
.ordinal = 37,
},
{
.name = "CXCMD_WriteISO3TrackMagData",
.patch = hook_CXCMD_WriteISO3TrackMagData,
.ordinal = 33,
},
{
.name = "CXCMD_PasswordSet",
.patch = hook_CXCMD_PasswordSet,
.ordinal = 13,
},
{
.name = "CXCMD_GetPrinterStatus",
.patch = hook_CXCMD_GetPrinterStatus,
.ordinal = 3,
},
{
.name = "CXCMD_WriteProjectCode",
.patch = hook_CXCMD_WriteProjectCode,
.ordinal = 35,
},
{
.name = "CXCMD_LoadCard",
.patch = hook_CXCMD_LoadCard,
.ordinal = 7,
},
{
.name = "CXCMD_ReadMagData",
.patch = hook_CXCMD_ReadMagData,
.ordinal = 17,
},
{
.name = "CXCMD_ScanPrinter",
.patch = hook_CXCMD_ScanPrinter,
.ordinal = 23,
},
{
.name = "CXCMD_xWriteISOMagData",
.patch = hook_CXCMD_xWriteISOMagData,
.ordinal = 39,
},
{
.name = "CXCMD_ICControl",
.patch = hook_CXCMD_ICControl,
.ordinal = 5,
},
{
.name = "CXCMD_ImageOut",
.patch = hook_CXCMD_ImageOut,
.ordinal = 6,
},
{
.name = "CXCMD_ReadBuffer",
.patch = hook_CXCMD_ReadBuffer,
.ordinal = 15,
},
{
.name = "CXCMD_xReadMagData",
.patch = hook_CXCMD_xReadMagData,
.ordinal = 38,
},
{
.name = "CXCMD_WriteBuffer",
.patch = hook_CXCMD_WriteBuffer,
.ordinal = 32,
},
{
.name = "CXCMD_DefineLUT",
.patch = hook_CXCMD_DefineLUT,
.ordinal = 2,
},
{
.name = "CXCMD_ReadISO3TrackMagData",
.patch = hook_CXCMD_ReadISO3TrackMagData,
.ordinal = 16,
},
{
.name = "CXCMD_TestUnitReady",
.patch = hook_CXCMD_TestUnitReady,
.ordinal = 30,
},
{
.name = "CXCMD_RetransferAndEject",
.patch = hook_CXCMD_RetransferAndEject,
.ordinal = 20,
},
};
static const struct hook_symbol hook_lut_syms[] = {
{
.name = "Lut24_Exchange",
.patch = hook_Lut24_Exchange,
.ordinal = 1,
},
};
static const struct hook_symbol hook_wdata_syms[] = {
{
.name = "Wdata_create",
.patch = hook_Wdata_create,
.ordinal = 1,
},
};
static const struct hook_symbol hook_ac_syms[] = {
{
.name = "init_accesscodekey",
.patch = hook_init_accesscodekey,
},{
.name = "accesscodekeyoverwriteheader",
.patch = hook_accesscodekeyoverwriteheader,
},
};
#pragma endregion
static void write_int(uint8_t* data, int index, int value) {
data[index] = value >> 24;
data[index + 1] = value >> 16;
data[index + 2] = value >> 8;
data[index + 3] = value;
}
static void write_short(uint8_t* data, int index, short value) {
data[index] = value >> 8;
data[index + 1] = value;
}
static struct printer_cx_config printer_config;
static wchar_t printer_out_path[MAX_PATH];
static struct printer_cx_data printer_data;
#define HEIGHT 664
#define WIDTH 1036
#define IMAGE_BUFFER_SIZE WIDTH * HEIGHT
static uint8_t back_buffer[4][IMAGE_BUFFER_SIZE];
static uint8_t front_buffer[4][IMAGE_BUFFER_SIZE];
static uint64_t current_card_id;
DWORD load_printer_data() {
DWORD bytesRead = 0;
HANDLE hSave = CreateFileW(printer_config.printer_data_path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hSave != INVALID_HANDLE_VALUE) {
if (!ReadFile(hSave, &printer_data, sizeof(printer_data), &bytesRead, NULL)){
CloseHandle(hSave);
return GetLastError();
}
CloseHandle(hSave);
if (bytesRead != sizeof(printer_data)){
return -1;
}
if (printer_data.version != PRINTER_DATA_VERSION) {
return -2;
}
return 0;
} else {
return GetLastError();
}
}
DWORD save_printer_data() {
DWORD bytesWritten = 0;
HANDLE hSave = CreateFileW(printer_config.printer_data_path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hSave != NULL) {
if (!WriteFile(hSave, &printer_data, sizeof(printer_data), &bytesWritten, NULL)){
CloseHandle(hSave);
dprintf("CX7000: Failed writing data: %lx\n", GetLastError());
return GetLastError();
}
CloseHandle(hSave);
return 0;
} else {
dprintf("CX7000: Failed opening data file for writing: %lx\n", GetLastError());
return GetLastError();
}
}
void printer_cx_hook_init(const struct printer_cx_config* cfg, HINSTANCE self) {
assert(cfg != NULL);
if (!cfg->enable) {
return;
}
memcpy(&printer_config, cfg, sizeof(*cfg));
printer_cx_hook_insert_hooks(NULL);
CreateDirectoryW(cfg->printer_out_path, NULL);
memcpy(printer_out_path, cfg->printer_out_path, MAX_PATH);
if (load_printer_data() != 0) {
memset(&printer_data, 0, sizeof(printer_data));
printer_data.version = PRINTER_DATA_VERSION;
if (save_printer_data() == 0) {
dprintf("CX7000: Printer data initialized.\n");
}
}
dprintf("CX7000: hook enabled.\n");
}
void printer_cx_hook_insert_hooks(HMODULE target) {
hook_table_apply(target, "PCP21CT64.dll", hook_pcp_syms, _countof(hook_pcp_syms));
hook_table_apply(target, "LUT24EXG64.dll", hook_lut_syms, _countof(hook_lut_syms));
hook_table_apply(target, "WCREATE64.dll", hook_wdata_syms, _countof(hook_wdata_syms));
hook_table_apply(target, "accesscode_dll.dll", hook_ac_syms, _countof(hook_ac_syms));
/* Unity workaround */
proc_addr_table_push(target, "PCP21CT64.dll", hook_pcp_syms, _countof(hook_pcp_syms));
proc_addr_table_push(target, "LUT24EXG64.dll", hook_lut_syms, _countof(hook_lut_syms));
proc_addr_table_push(target, "WCREATE64.dll", hook_wdata_syms, _countof(hook_wdata_syms));
proc_addr_table_push(target, "accesscode_dll.dll", hook_ac_syms, _countof(hook_ac_syms));
}
static int __stdcall hook_CXCMD_Retransfer() {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static bool __stdcall hook_CXCMD_CheckIfConnected(int* pSlotId, int* pId) {
dprintf("CX7000: %s\n", __func__);
return printer_config.enable;
}
static int __stdcall hook_CXCMD_xImageOut() {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_MoveCard(int slotId, int id, int dest, int flip, int filmInit, int immed) {
dprintf("CX7000: %s(%d, %d, %d, %d)\n", __func__, dest, flip, filmInit, immed);
return CX_OK;
}
static int __stdcall hook_CXCMD_xWriteMagData() {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_SecurityPrint(int slotId, int id, int color, int bufferIndex, int immed) {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_ScanPrinterNext() {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_ImageOut(int slotId, int id, uint8_t* plane, int length, int color, int bufferIndex) {
dprintf("CX7000: %s\n", __func__);
assert(color >= 0 && color <= 3);
assert(bufferIndex >= 0 && bufferIndex <= 1);
assert(length == IMAGE_BUFFER_SIZE);
// colorIndex: 0 = w, 1 = c, 2 = m, 3 = y
// bufferIndex: 0 = back, 1 = front
if (bufferIndex == 0) {
memcpy(back_buffer[color], plane, length);
} else {
memcpy(front_buffer[color], plane, length);
}
return CX_OK;
}
static int __stdcall hook_CXCMD_Print(int slotId, int id, int color, int bufferIndex, int immed) {
dprintf("CX7000: %s(%d, %d, %d)\n", __func__, color, bufferIndex, immed);
assert(bufferIndex >= 0 && bufferIndex <= 1);
SYSTEMTIME t;
GetLocalTime(&t);
// color: 1 = back, 3 = front
// bufferIndex: 0 = back, 1 = front
wchar_t dumpPath[MAX_PATH];
uint8_t metadata[5];
metadata[0] = current_card_id >> 32;
write_int(metadata, 1, (int32_t)current_card_id);
swprintf_s(
dumpPath, MAX_PATH,
L"%s\\CX7000_%04d%02d%02d_%02d%02d%02d_%s.bmp",
printer_out_path, t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond, bufferIndex == 0 ? L"back" : L"front");
// convert image from seperate CMY arrays to one RGB array
int size = IMAGE_BUFFER_SIZE * 3;
uint8_t* raw_image = malloc(size);
for (int i = 0; i < IMAGE_BUFFER_SIZE; i++) {
// 0 is "white" and we don't really care about that
raw_image[i * 3] = 0xFF - (bufferIndex == 0 ? back_buffer : front_buffer)[1][i];
raw_image[i * 3 + 1] = 0xFF - (bufferIndex == 0 ? back_buffer : front_buffer)[2][i];
raw_image[i * 3 + 2] = 0xFF - (bufferIndex == 0 ? back_buffer : front_buffer)[3][i];
}
dprintf("CX7000: Saving %s image to %ls\n", bufferIndex == 0 ? "back" : "front", dumpPath);
int ret = WriteDataToBitmapFile(dumpPath, 24, WIDTH, HEIGHT, raw_image, size, metadata, 5, false);
free(raw_image);
if (ret < 0) {
dprintf("CX7000: WriteDataToBitmapFile returned %d\n", ret);
return CX_ERROR_FATAL_3301;
}
return CX_OK;
}
static int __stdcall hook_CXCMD_RezeroUnit(int slotId, int id, int action) {
dprintf("CX7000: %s\n", __func__);
return CX_OK;
}
static int __stdcall hook_CXCMD_WriteMagData() {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_LogSense(int iSlot, int iID, int iPage, uint8_t* pbyBuffer) {
dprintf("CX7000: %s\n", __func__);
const int size = 108;
memset(pbyBuffer, 0, size);
if (iPage == 56) {
dprintf("CX7000: MediumQuantity\n");
write_int(pbyBuffer, 8, (int)printer_data.print_counter); // total count
write_int(pbyBuffer, 16, 22); // free count
write_int(pbyBuffer, 24, 33); // head count
write_int(pbyBuffer, 32, (int)printer_data.print_counter_since_clean); // cleaning count
write_int(pbyBuffer, 40, 55); // error count
write_int(pbyBuffer, 48, 66); // cru cleaning count
return CX_OK;
} else if (iPage == 57) {
dprintf("CX7000: Miscellaneous\n");
write_int(pbyBuffer, 16, 234); // re transfer hr power on time
write_int(pbyBuffer, 24, 456); // remedy hr power on time
write_int(pbyBuffer, 40, 789); // unresettable re transfer hr power on time
write_int(pbyBuffer, 48, 1023); // unresettable remedy hr power on time
return CX_OK;
}
dprintf("CX7000: Unknown LogSense\n");
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_StandardInquiry(int iSlot, int iID, uint8_t* pbyBuffer) {
const int size = 96;
dprintf("CX7000: %s\n", __func__);
memset(pbyBuffer, 0, size);
memcpy(pbyBuffer + 32, printer_config.printer_firm_version, 8);
memcpy(pbyBuffer + 50, printer_config.printer_camera_version, 8);
memcpy(pbyBuffer + 71, printer_config.printer_config_version, 8);
memcpy(pbyBuffer + 79, printer_config.printer_table_version, 8);
//memcpy(pbyBuffer + 58, printer_config.thermal_head_info, 13); // unused
return CX_OK;
}
static int __stdcall hook_CXCMD_ModeSense(int iSlot, int iID, int iPC, int iPage, uint8_t* pbyBuffer) {
dprintf("CX7000: %s(%d, %d)\n", __func__, iPC, iPage);
const int size = 104;
memset(pbyBuffer, 0, size);
if (iPC == 1 && iPage == 40) { // GetMediaInfo
pbyBuffer[51] = 10; // film count (10=100%)
pbyBuffer[52] = 50; // ink count (50=100%)
return CX_OK;
} else if (iPC == 1 && iPage == 35) { // ReadInkInfo
pbyBuffer[6] = 0; // "b"
write_short(pbyBuffer, 8, 50); // Remain
return CX_OK;
}
dprintf("CX7000: Unknown ModeSense\n");
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_UpdateFirmware(int iSlot, int iID, char* pFile, int iDataID) {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // intentionally not implemented
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_ModeSelect(int iSlot, int iID, int iSp, int iPage, uint8_t* pbyData) {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_GetPrintingStatus() {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_SendDiagnostic(int iSlot, int iID, int iTestMode, int iTestPatten, int iTestCount) {
dprintf("CX7000: %s(%d, %d, %d)\n", __func__, iTestMode, iTestPatten, iTestCount);
if (iTestMode == 19) {
dprintf("CX7000: Printer Front Buttons Enabled: %d\n", iTestPatten);
return CX_OK;
} else if (iTestMode == 17) {
dprintf("CX7000: Printer was cleaned (haha)\n");
printer_data.print_counter_since_clean = 0;
save_printer_data();
return CX_OK;
} else if (iTestMode == 18) {
dprintf("CX7000: Transport Mode enabled\n");
printer_data.is_transport = true;
save_printer_data();
return CX_OK;
} else if (iTestMode == 20) {
dprintf("CX7000: Transport Mode disabled\n");
printer_data.is_transport = false;
save_printer_data();
return CX_OK;
}
dprintf("CX7000: Unknown SendDiagnostic\n");
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_RetransferAndTurn(int slotId, int id, int immed) {
dprintf("CX7000: %s\n", __func__);
return CX_OK;
}
static int __stdcall hook_CXCMD_LogSelect(int iSlot, int iID, int iMod) {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_ReadPosition(int slotId, int id, uint8_t* buffer) {
dprintf("CX7000: %s\n", __func__);
const int size = 8;
memset(buffer, 0, size);
buffer[0] = 1 << 2; // IsExist (0 means YES!)
buffer[7] = 0; // position (of card; 0 = printer, 1 = "IR")
return CX_OK;
}
static int __stdcall hook_CXCMD_SecurityLock() {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_SetPrintingStatus() {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_xReadISOMagData() {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_WriteISO3TrackMagData() {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_PasswordSet() {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_GetPrinterStatus() {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_WriteProjectCode() {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_LoadCard(int slotId, int id, int dest, int flip, int filmInit, int immed) {
dprintf("CX7000: %s(%d, %d, %d, %d)\n", __func__, dest, flip, filmInit, immed);
return CX_OK;
}
static int __stdcall hook_CXCMD_ReadMagData() {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_ScanPrinter(int* pSlotId, int* pId) {
dprintf("CX7000: %s\n", __func__);
if (!printer_config.enable) {
return CX_ERROR_NOT_CONNECTED_6804;
}
*pSlotId = 1;
*pId = 1;
return CX_OK;
}
static int __stdcall hook_CXCMD_xWriteISOMagData() {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_ICControl() {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_ReadBuffer(int iSlot, int iID, int iMode, int iBufferID, uint8_t* pbyData, int iOffset,
int iLength) {
dprintf("CX7000: %s(%d, %d, %d)\n", __func__, iMode, iBufferID, iLength);
memset(pbyData, 0, iLength);
if (iMode == 2 && iBufferID == 87 && iLength == 10) {
dprintf("CX7000: ReadCondition\n");
pbyData[0] = printer_data.is_transport; // transport mode
pbyData[1] = 0; // head white ink level, unused
pbyData[2] = 0; // main white ink level, unused
pbyData[3] = 0; // total white ink level, unused
return CX_OK;
} else if (iMode == 2 && iBufferID == 112 && iLength == 6) {
dprintf("CX7000: GetMacAddress\n");
pbyData[0] = 0x12; // displays in test menu, else ununused?
pbyData[1] = 0x34;
pbyData[2] = 0x56;
pbyData[3] = 0x78;
pbyData[4] = 0x9A;
pbyData[5] = 0xBC;
return CX_OK;
} else if (iMode == 2 && iBufferID == 82 && iLength == 4) {
dprintf("CX7000: GetCleaningWaitCount\n");
// seemingly unused
write_short(pbyData, 0, 0);
return CX_OK;
} else if (iMode == 2 && iBufferID == 85 && iLength == 10) {
dprintf("CX7000: GetSensorInfo\n");
pbyData[0] = 244; // retransfer heat roller thermistor; must be over 243
pbyData[1] = 0; // main pwb thermistor; unused
pbyData[2] = 0; // thermal head thermistor; unused
pbyData[3] = 0; // heater cover thermistor; unused
return CX_OK;
} else if (iMode == 2 && iBufferID == 88 && iLength == 16) {
dprintf("CX7000: ReadErrorStatus\n");
pbyData[1] = 0; // is door open?
//pbyData[2...] = // any of the error codes that fit in a byte (from CX_ERROR_FATAL_3301 to CX_ERROR_PRINT_INTERRUPT_6805_3)
return CX_OK;
} else if (iMode == 2 && iBufferID == 224 && iLength == 10) {
dprintf("CX7000: ReadCode\n");
printer_data.print_counter_since_clean++;
current_card_id = ++printer_data.print_counter;
dprintf("CX7000: Generated new card ID: %lld\n", current_card_id);
save_printer_data();
pbyData[0] = current_card_id >> 32; // MSB of card id
write_int(pbyData, 1, (int32_t)current_card_id); // lower 4 bytes of card id
pbyData[5] = 0x0; // Direction (1 = rotate image by 180 degrees)
pbyData[6] = 0x1; // CheckCode (0 = error)
return CX_OK;
} else if (iMode == 2 && iBufferID == 144 && iLength == 260) {
dprintf("CX7000: ReadErrorLog\n");
write_int(pbyData, 0, 0); // LogCount
/*for (int i = 0; false; i++) { // list of error ids
write_int(pbyData, i + 4, 0);
}*/
return CX_OK;
}
dprintf("CX7000: Unknown ReadBuffer\n");
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_xReadMagData() {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_WriteBuffer(int iSlot, int iID, int iMode, int iBufferID, uint8_t* pbyData, int iOffset, // NOLINT(*-non-const-parameter)
int iLength) {
dprintf("CX7000: %s(%d, %d, %d, %d)\n", __func__, iMode, iBufferID, iOffset, iLength);
if (iMode == 2 && iBufferID == 82 && iLength == 4) {
int val = pbyData[0] << 8 | pbyData[1];
dprintf("CX7000: Set cleaning limit: %d\n", val);
return CX_OK;
}
dprintf("CX7000: Unknown WriteBuffer\n");
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_DefineLUT(int slotId, int id, int color, int length, uint8_t* buffer) {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_ReadISO3TrackMagData() {
dprintf("CX7000: %s\n", __func__);
dprintf("CX7000: Unimplemented\n"); // unused
return CX_ERROR_USB_COM_3201;
}
static int __stdcall hook_CXCMD_TestUnitReady(int slotId, int id) {
dprintf("CX7000: %s\n", __func__);
if (!printer_config.enable) {
return CX_ERROR_NOT_CONNECTED_6804;
}
return CX_OK;
}
static int __stdcall hook_CXCMD_RetransferAndEject(int slotId, int id, int immed) {
dprintf("CX7000: %s\n", __func__);
return CX_OK;
}
static bool __stdcall hook_Lut24_Exchange(const wchar_t* pFile, uint8_t* y, uint8_t* m, uint8_t* c, int sizeY, int sizeM,
int sizeC) {
dprintf("CX7000: %s(%ls)\n", __func__, pFile);
// stub?
return true;
}
static bool __stdcall hook_Wdata_create(uint8_t* pbyRdata, uint8_t* pbyGdata, uint8_t* pbyBdata, int iWidth,
int iHeight, bool bPortrait, int iAlgorithim, uint8_t* pbyWdata) {
dprintf("CX7000: %s(%d, %d, %d)\n", __func__, iHeight, bPortrait, iAlgorithim);
// stub?
return true;
}
// TODO: these two only exist while we have no decrypted dump of accesscode_dll
static int __cdecl hook_init_accesscodekey(BSTR fileName) {
dprintf("AccesscodeKey: Init\n");
return 0;
}
static int __cdecl hook_accesscodekeyoverwriteheader(void* context, BSTR header, int headerLen, BSTR accessheaderkey, int headerkeylen) {
dprintf("AccesscodeKey: Overwrite Header\n");
return 0;
}