// ReSharper disable CppParameterNeverUsed // ReSharper disable CppParameterMayBeConstPtrOrRef #include "printer_cx.h" #include #include #include #include #include #include #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 = (uint8_t*)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; }