ref: caba3c6ab89bf631a0c12eab72d51d0353e0f782
dir: /src/wisescript.c/
/* This file is part of REWise. * * REWise is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * REWise is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ #include <stddef.h> #include <string.h> #include <errno.h> #ifdef __linux__ #include <linux/limits.h> #elif defined(__CYGWIN__) || defined(_WIN32) || defined(_WIN64) || defined(__plan9__) #include <limits.h> #endif #ifdef __plan9__ #define NAME_MAX 512 #endif #include "wisescript.h" #include "reader.h" #include "print.h" static int WiseScriptSTOP = 0; REWError readWiseScriptHeader(FILE * fp, WiseScriptHeader * header) { // init struct header->logPath = NULL; header->font = NULL; REWError status; status = readBytesInto(fp, header->unknown_44, 44); if (status != REWERR_OK) { return status; } status = readString(fp, &header->logPath); if (status != REWERR_OK) { printError("Failed to read WiseScriptHeader logpath: %d\n", status); return status; } status = readString(fp, &header->font); if (status != REWERR_OK) { printError("Failed to read WiseScriptHeader font: %d\n", status); freeWiseScriptHeader(header); return status; } status = readBytesInto(fp, header->unknown_14, 14); if (status != REWERR_OK) { freeWiseScriptHeader(header); return status; } return REWERR_OK; } REWError readWiseScriptTexts(FILE * fp, WiseScriptTexts * texts) { REWError status; uint32_t i; // Init text pointers for (i = 0; i < 56; i++) { texts->installTexts[i] = NULL; } // Read the text strings for (i = 0; i < 56; i++) { status = readString(fp, &texts->installTexts[i]); if (status != REWERR_OK) { freeWiseScriptTexts(texts); return status; } } return REWERR_OK; } REWError readWiseScriptFileHeader(FILE * fp, WiseScriptFileHeader * data) { REWError status; // init struct data->destFile = NULL; data->fileText = NULL; status = readBytesInto(fp, data->unknown_2, 2); if (status != REWERR_OK) { return status; } status = readUInt32(fp, &data->deflateStart); if (status != REWERR_OK) { return status; } status = readUInt32(fp, &data->deflateEnd); if (status != REWERR_OK) { return status; } status = readUInt16(fp, &data->date); if (status != REWERR_OK) { return status; } status = readUInt16(fp, &data->time); if (status != REWERR_OK) { return status; } status = readUInt32(fp, &data->inflatedSize); if (status != REWERR_OK) { return status; } status = readBytesInto(fp, data->unknown_40, 20); if (status != REWERR_OK) { return status; } status = readUInt32(fp, &data->crc32); if (status != REWERR_OK) { return status; } status = readString(fp, &data->destFile); if (status != REWERR_OK) { printError("readWiseScriptFileHeader failed to read destFile: %d\n", status); return status; } // data->destFile is just 0x00 if (data->destFile == NULL) { printError("readWiseScriptFileHeader destFile is a empty string\n"); return REWERR_INVALDAT; } // parse filepath char * filePath = wiseScriptParsePath(data->destFile); if (filePath == NULL) { printError("readWiseScriptFileHeader invalid destFile\n"); freeWiseScriptFileHeader(data); return REWERR_INVALDAT; } free(data->destFile); data->destFile = filePath; status = readString(fp, &data->fileText); if (status != REWERR_OK) { printError("readWiseScriptFileHeader failed to read fileText: " "%d\n", status); freeWiseScriptFileHeader(data); return status; } status = readBytesInto(fp, &data->terminator, 1); if (status != REWERR_OK) { return status; } return REWERR_OK; } REWError readWiseScriptUnknown0x03(FILE * fp, WiseScriptUnknown0x03 * data) { REWError status; // init struct data->unknownString_1 = NULL; data->unknownString_2 = NULL; status = readBytesInto(fp, &data->unknown_1, 1); if (status != REWERR_OK) { return status; } status = readString(fp, &data->unknownString_1); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x03 failed to read unknownString_1: " "%d\n", status); return status; } status = readString(fp, &data->unknownString_2); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x03 failed to read unknownString_2: " "%d\n", status); freeWiseScriptUnknown0x03(data); return status; } return REWERR_OK; } REWError readWiseScriptUnknown0x04(FILE * fp, WiseScriptUnknown0x04 * data) { REWError status; // init struct data->dataString = NULL; status = readBytesInto(fp, &data->no, 1); if (status != REWERR_OK) { return status; } status = readString(fp, &data->dataString); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x04 failed to read dataString: " "%d\n", status); return status; } return REWERR_OK; } REWError readWiseScriptUnknown0x05(FILE * fp, WiseScriptUnknown0x05 * data) { REWError status; // init struct data->file = NULL; data->section = NULL; data->values = NULL; status = readString(fp, &data->file); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x05 failed to read file: " "%d\n", status); return status; } status = readString(fp, &data->section); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x05 failed to read section: " "%d\n", status); return status; } status = readString(fp, &data->values); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x05 failed to read values: " "%d\n", status); return status; } return REWERR_OK; } REWError readWiseScriptUnknown0x06(FILE * fp, WiseScriptUnknown0x06 * data) { REWError status; status = readBytesInto(fp, data->unknown, 6); if (status != REWERR_OK) { return status; } status = readUInt32(fp, &data->deflateStart); if (status != REWERR_OK) { return status; } status = readUInt32(fp, &data->deflateEnd); if (status != REWERR_OK) { return status; } status = readUInt32(fp, &data->inflatedSize); if (status != REWERR_OK) { return status; } status = readBytesInto(fp, &data->unknown1, 1); if (status != REWERR_OK) { return status; } return REWERR_OK; } REWError readWiseScriptUnknown0x07(FILE * fp, WiseScriptUnknown0x07 * data) { REWError status; // init struct data->unknownString_1 = NULL; data->unknownString_2 = NULL; data->unknownString_3 = NULL; status = readBytesInto(fp, &data->unknown_1, 1); if (status != REWERR_OK) { return status; } status = readString(fp, &data->unknownString_1); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x07 failed to read unknownString_1: " "%d\n", status); return status; } status = readString(fp, &data->unknownString_2); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x07 failed to read unknownString_2: " "%d\n", status); return status; } status = readString(fp, &data->unknownString_3); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x07 failed to read unknownString_3: " "%d\n", status); return status; } return REWERR_OK; } REWError readWiseScriptUnknown0x08(FILE * fp, WiseScriptUnknown0x08 * data) { REWError status; status = readBytesInto(fp, &data->unknown_1, 1); if (status != REWERR_OK) { return status; } return REWERR_OK; } REWError readWiseScriptUnknown0x09(FILE * fp, WiseScriptUnknown0x09 * data) { REWError status; // init struct data->unknownString_1 = NULL; data->unknownString_2 = NULL; data->unknownString_3 = NULL; data->unknownString_4 = NULL; data->unknownString_5 = NULL; data->unknown_2 = 0; status = readBytesInto(fp, &data->unknown_1, 1); if (status != REWERR_OK) { return status; } if (data->unknown_1 != 0x01 && data->unknown_1 != 0x20) { status = readBytesInto(fp, &data->unknown_2, 1); if (status != REWERR_OK) { return status; } } status = readString(fp, &data->unknownString_1); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x09 failed to read unknownString_1: " "%d\n", status); return status; } status = readString(fp, &data->unknownString_2); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x09 failed to read unknownString_2: " "%d\n", status); freeWiseScriptUnknown0x09(data); return status; } status = readString(fp, &data->unknownString_3); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x09 failed to read unknownString_3: " "%d\n", status); freeWiseScriptUnknown0x09(data); return status; } status = readString(fp, &data->unknownString_4); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x09 failed to read unknownString_4: " "%d\n", status); freeWiseScriptUnknown0x09(data); return status; } if (data->unknown_1 == 0x01 || data->unknown_1 == 0x20) { status = readString(fp, &data->unknownString_5); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x09 failed to read unknownString_5: " "%d\n", status); freeWiseScriptUnknown0x09(data); return status; } } return REWERR_OK; } REWError readWiseScriptUnknown0x0A(FILE * fp, WiseScriptUnknown0x0A * data) { REWError status; // init struct data->unknownString_1 = NULL; data->unknownString_2 = NULL; data->unknownString_3 = NULL; status = readBytesInto(fp, data->unknown_2, 2); if (status != REWERR_OK) { return status; } status = readString(fp, &data->unknownString_1); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x0A failed to read unknownString_1: " "%d\n", status); return status; } status = readString(fp, &data->unknownString_2); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x0A failed to read unknownString_2: " "%d\n", status); freeWiseScriptUnknown0x0A(data); return status; } status = readString(fp, &data->unknownString_3); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x0A failed to read unknownString_3: " "%d\n", status); freeWiseScriptUnknown0x0A(data); return status; } return REWERR_OK; } REWError readWiseScriptUnknown0x0B(FILE * fp, WiseScriptUnknown0x0B * data) { REWError status; // init struct data->unknownString_1 = NULL; status = readBytesInto(fp, &data->unknown_1, 1); if (status != REWERR_OK) { return status; } status = readString(fp, &data->unknownString_1); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x0B failed to read unknownString_1: " "%d\n", status); return status; } return REWERR_OK; } REWError readWiseScriptUnknown0x0C(FILE * fp, WiseScriptUnknown0x0C * data) { REWError status; // init struct data->unknownString_1 = NULL; data->unknownString_2 = NULL; status = readBytesInto(fp, &data->unknown_1, 1); if (status != REWERR_OK) { return status; } status = readString(fp, &data->unknownString_1); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x0C failed to read unknownString_1: " "%d\n", status); return status; } status = readString(fp, &data->unknownString_2); if (status != REWERR_OK) { freeWiseScriptUnknown0x0C(data); printError("readWiseScriptUnknown0x0C failed to read unknownString_2: " "%d\n", status); return status; } return REWERR_OK; } REWError readWiseScriptUnknown0x11(FILE * fp, WiseScriptUnknown0x11 * data) { REWError status; // init struct data->unknownString_1 = NULL; status = readString(fp, &data->unknownString_1); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x11 failed to read unknownString_1: " "%d\n", status); freeWiseScriptUnknown0x11(data); return status; } return REWERR_OK; } REWError readWiseScriptUnknown0x12(FILE * fp, WiseScriptUnknown0x12 * data) { REWError status; // init struct data->sourceFile = NULL; data->unknownString_1 = NULL; data->unknownString_2 = NULL; data->destFile = NULL; status = readBytesInto(fp, &data->unknown_1, 1); if (status != REWERR_OK) { return status; } status = readBytesInto(fp, data->unknown_41, 41); if (status != REWERR_OK) { return status; } status = readString(fp, &data->sourceFile); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x12 failed to read sourceFile: %d\n", status); return status; } status = readString(fp, &data->unknownString_1); if (status != REWERR_OK) { freeWiseScriptUnknown0x12(data); printError("readWiseScriptUnknown0x12 failed to read unknownString_1: " "%d\n", status); return status; } status = readString(fp, &data->unknownString_2); if (status != REWERR_OK) { freeWiseScriptUnknown0x12(data); printError("readWiseScriptUnknown0x12 failed to read unknownString_2: " "%d\n", status); return status; } status = readString(fp, &data->destFile); if (status != REWERR_OK) { freeWiseScriptUnknown0x12(data); printError("readWiseScriptUnknown0x12 failed to read destFile: %d\n", status); return status; } return REWERR_OK; } REWError readWiseScriptUnknown0x14(FILE * fp, WiseScriptUnknown0x14 * data) { REWError status; // init struct data->name = NULL; data->message = NULL; status = readUInt32(fp, &data->deflateStart); if (status != REWERR_OK) { return status; } status = readUInt32(fp, &data->deflateEnd); if (status != REWERR_OK) { return status; } status = readUInt32(fp, &data->inflatedSize); if (status != REWERR_OK) { return status; } status = readString(fp, &data->name); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x14 failed to read name: %d\n", status); return status; } status = readString(fp, &data->message); if (status != REWERR_OK) { freeWiseScriptUnknown0x14(data); printError("readWiseScriptUnknown0x14 failed to read message: %d\n", status); return status; } return REWERR_OK; } REWError readWiseScriptUnknown0x15(FILE * fp, WiseScriptUnknown0x15 * data) { REWError status; // init struct data->unknownString_1 = NULL; data->unknownString_2 = NULL; status = readBytesInto(fp, &data->unknown_1, 1); if (status != REWERR_OK) { return status; } status = readString(fp, &data->unknownString_1); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x15 failed to read unknownString_1: " "%d\n", status); return status; } status = readString(fp, &data->unknownString_2); if (status != REWERR_OK) { freeWiseScriptUnknown0x15(data); printError("readWiseScriptUnknown0x15 failed to read unknownString_2: " "%d\n", status); return status; } return REWERR_OK; } REWError readWiseScriptUnknown0x16(FILE * fp, WiseScriptUnknown0x16 * data) { REWError status; // init struct data->name = NULL; status = readString(fp, &data->name); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x16 failed to read name: " "%d\n", status); return status; } return REWERR_OK; } REWError readWiseScriptUnknown0x17(FILE * fp, WiseScriptUnknown0x17 * data) { REWError status; // init struct data->unknownString_1 = NULL; status = readBytesInto(fp, &data->unknown_1, 1); if (status != REWERR_OK) { return status; } status = readBytesInto(fp, data->unknown_4, 4); if (status != REWERR_OK) { return status; } status = readString(fp, &data->unknownString_1); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x17 failed to read unknownString_1: " "%d\n", status); return status; } return REWERR_OK; } REWError readWiseScriptUnknown0x1C(FILE * fp, WiseScriptUnknown0x1C * data) { REWError status; // init struct data->unknownString_1 = NULL; status = readString(fp, &data->unknownString_1); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x1C failed to read unknownString_1: " "%d\n", status); return status; } return REWERR_OK; } REWError readWiseScriptUnknown0x1E(FILE * fp, WiseScriptUnknown0x1E * data) { REWError status; status = readBytesInto(fp, data->unknown_2, 2); if (status != REWERR_OK) { return status; } return REWERR_OK; } REWError readWiseScriptUnknown0x23(FILE * fp, WiseScriptUnknown0x23 * data) { REWError status; // init struct data->unknownString_1 = NULL; data->unknownString_2 = NULL; status = readBytesInto(fp, &data->unknown_1, 1); if (status != REWERR_OK) { return status; } status = readString(fp, &data->unknownString_1); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x23 failed to read unknownString_1: " "%d\n", status); return status; } status = readString(fp, &data->unknownString_2); if (status != REWERR_OK) { printError("readWiseScriptUnknown0x23 failed to read unknownString_2: " "%d\n", status); freeWiseScriptUnknown0x23(data); return status; } return REWERR_OK; } void freeWiseScriptHeader(WiseScriptHeader * header) { if (header->logPath != NULL) { free(header->logPath); header->logPath = NULL; } if (header->font != NULL) { free(header->font); header->font = NULL; } } void freeWiseScriptTexts(WiseScriptTexts * texts) { for (uint32_t i = 0; i < 56; i++) { if (texts->installTexts[i] != NULL) { free(texts->installTexts[i]); texts->installTexts[i] = NULL; } } } void freeWiseScriptFileHeader(WiseScriptFileHeader * data) { if (data->destFile != NULL) { free(data->destFile); data->destFile = NULL; } if (data->fileText != NULL) { free(data->fileText); data->fileText = NULL; } } void freeWiseScriptUnknown0x03(WiseScriptUnknown0x03 * data) { if (data->unknownString_1 != NULL) { free(data->unknownString_1); data->unknownString_1 = NULL; } if (data->unknownString_2 != NULL) { free(data->unknownString_2); data->unknownString_2 = NULL; } } void freeWiseScriptUnknown0x04(WiseScriptUnknown0x04 * data) { if (data->dataString != NULL) { free(data->dataString); data->dataString = NULL; } } void freeWiseScriptUnknown0x05(WiseScriptUnknown0x05 * data) { if (data->file != NULL) { free(data->file); data->file = NULL; } if (data->section != NULL) { free(data->section); data->section = NULL; } if (data->values != NULL) { free(data->values); data->values = NULL; } } void freeWiseScriptUnknown0x07(WiseScriptUnknown0x07 * data) { if (data->unknownString_1 != NULL) { free(data->unknownString_1); data->unknownString_1 = NULL; } if (data->unknownString_2 != NULL) { free(data->unknownString_2); data->unknownString_2 = NULL; } if (data->unknownString_3 != NULL) { free(data->unknownString_3); data->unknownString_3 = NULL; } } void freeWiseScriptUnknown0x09(WiseScriptUnknown0x09 * data) { if (data->unknownString_1 != NULL) { free(data->unknownString_1); data->unknownString_1 = NULL; } if (data->unknownString_2 != NULL) { free(data->unknownString_2); data->unknownString_2 = NULL; } if (data->unknownString_3 != NULL) { free(data->unknownString_3); data->unknownString_3 = NULL; } if (data->unknownString_4 != NULL) { free(data->unknownString_4); data->unknownString_4 = NULL; } if (data->unknownString_5 != NULL) { free(data->unknownString_5); data->unknownString_5 = NULL; } } void freeWiseScriptUnknown0x0A(WiseScriptUnknown0x0A * data) { if (data->unknownString_1 != NULL) { free(data->unknownString_1); data->unknownString_1 = NULL; } if (data->unknownString_2 != NULL) { free(data->unknownString_2); data->unknownString_2 = NULL; } if (data->unknownString_3 != NULL) { free(data->unknownString_3); data->unknownString_3 = NULL; } } void freeWiseScriptUnknown0x0B(WiseScriptUnknown0x0B * data) { if (data->unknownString_1 != NULL) { free(data->unknownString_1); data->unknownString_1 = NULL; } } void freeWiseScriptUnknown0x0C(WiseScriptUnknown0x0C * data) { if (data->unknownString_1 != NULL) { free(data->unknownString_1); data->unknownString_1 = NULL; } if (data->unknownString_2 != NULL) { free(data->unknownString_2); data->unknownString_2 = NULL; } } void freeWiseScriptUnknown0x11(WiseScriptUnknown0x11 * data) { if (data->unknownString_1 != NULL) { free(data->unknownString_1); data->unknownString_1 = NULL; } } void freeWiseScriptUnknown0x12(WiseScriptUnknown0x12 * data) { if (data->sourceFile != NULL) { free(data->sourceFile); data->sourceFile = NULL; } if (data->unknownString_1 != NULL) { free(data->unknownString_1); data->unknownString_1 = NULL; } if (data->unknownString_2 != NULL) { free(data->unknownString_2); data->unknownString_2 = NULL; } if (data->destFile != NULL) { free(data->destFile); data->destFile = NULL; } } void freeWiseScriptUnknown0x14(WiseScriptUnknown0x14 * data) { if (data->name != NULL) { free(data->name); data->name = NULL; } if (data->message != NULL) { free(data->message); data->message = NULL; } } void freeWiseScriptUnknown0x15(WiseScriptUnknown0x15 * data) { if (data->unknownString_1 != NULL) { free(data->unknownString_1); data->unknownString_1 = NULL; } if (data->unknownString_2 != NULL) { free(data->unknownString_2); data->unknownString_2 = NULL; } } void freeWiseScriptUnknown0x16(WiseScriptUnknown0x16 * data) { if (data->name != NULL) { free(data->name); data->name = NULL; } } void freeWiseScriptUnknown0x17(WiseScriptUnknown0x17 * data) { if (data->unknownString_1 != NULL) { free(data->unknownString_1); data->unknownString_1 = NULL; } } void freeWiseScriptUnknown0x1C(WiseScriptUnknown0x1C * data) { if (data->unknownString_1 != NULL) { free(data->unknownString_1); data->unknownString_1 = NULL; } } void freeWiseScriptUnknown0x23(WiseScriptUnknown0x23 * data) { if (data->unknownString_1 != NULL) { free(data->unknownString_1); data->unknownString_1 = NULL; } if (data->unknownString_2 != NULL) { free(data->unknownString_2); data->unknownString_2 = NULL; } } // Debug prints // // https://www.doubleblak.com/m/blogPosts.php?id=7 // MS-Dos FileTime // DATE // ---- // bit 0 - 6 Year // bit 7 - 10 Month // bit 11 - 15 Day // // TIME // ---- // bit 0 - 4 Hour // bit 5 - 10 Minutes // bit 11 - 15 * 2 Seconds void printDatetime(uint16_t date, uint16_t time) { printf("%04d-%02d-%02d %02d:%02d:%02d", (date >> 9) + 1980, (date >> 5) & 0xf, date & 0x1f, (time >> 11), (time >> 5) & 0x3f, (time & 0x1f) * 2); } void printHex(unsigned char * value, uint32_t size) { for (uint32_t i=0; i < size; i++) { printf("%02X", value[i]); } } void printWiseScriptHeader(WiseScriptHeader * header) { printf("WiseScript Header\n-----------------\n"); for (int i = 0; i < 44; i++) { printf("%02X ", header->unknown_44[i]); } printf("\n"); printf("'%s': '%s'\n", header->font, header->logPath); printf("-----------------\n"); } void printWiseScriptTexts(WiseScriptTexts * texts) { printf("WiseScript Texts\n"); printf("----------------\n"); for (int i = 0; i < 56; i++) { printf("Text: \"%s\"\n", texts->installTexts[i]); } printf("----------------\n"); } void printWiseScriptFileHeader(WiseScriptFileHeader * data) { printf("0x00 0x%08X 0x%08X ", data->deflateStart, data->deflateEnd); printDatetime(data->date, data->time); printf(" % 11u ", data->inflatedSize); printHex(data->unknown_40, 20); printf(" %08X '%s' '%s' %d\n", data->crc32, data->destFile, data->fileText, data->terminator); } void printWiseScriptUnknown0x03(WiseScriptUnknown0x03 * data) { printf("0x03 0x%02X '%s' '%s'\n", data->unknown_1, data->unknownString_1, data->unknownString_2); } void printWiseScriptUnknown0x04(WiseScriptUnknown0x04 * data) { printf("0x04 0x%02X '%s'\n", data->no, data->dataString); } void printWiseScriptUnknown0x05(WiseScriptUnknown0x05 * data) { printf("0x05 '%s' '%s' '%s'\n", data->file, data->section, data->values); } void printWiseScriptUnknown0x06(WiseScriptUnknown0x06 * data) { printf("0x06 "); printHex(data->unknown, 6); printf(" 0x%08X 0x%08X % 11u %02X\n", data->deflateStart, data->deflateEnd, data->inflatedSize, data->unknown1); } void printWiseScriptUnknown0x07(WiseScriptUnknown0x07 * data) { printf("0x07 %02X '%s' '%s' '%s'\n", data->unknown_1, data->unknownString_1, data->unknownString_2, data->unknownString_3); } void printWiseScriptUnknown0x08(WiseScriptUnknown0x08 * data) { printf("0x08 %02X\n", data->unknown_1); } void printWiseScriptUnknown0x09(WiseScriptUnknown0x09 * data) { printf("0x09 %02X ", data->unknown_1); if (data->unknown_1 != 0x01 && data->unknown_1 != 0x20) { printf("%02X ", data->unknown_2); } printf("'%s' '%s' '%s' '%s'", data->unknownString_1, data->unknownString_2, data->unknownString_3, data->unknownString_4); if (data->unknown_1 == 0x01 || data->unknown_1 == 0x20) { printf(" '%s'", data->unknownString_5); } printf("\n"); } void printWiseScriptUnknown0x0A(WiseScriptUnknown0x0A * data) { printf("0x0A "); printHex(data->unknown_2, 2); printf(" '%s' '%s' '%s'\n", data->unknownString_1, data->unknownString_2, data->unknownString_3); } void printWiseScriptUnknown0x0B(WiseScriptUnknown0x0B * data) { printf("0x0B %02X '%s'\n", data->unknown_1, data->unknownString_1); } void printWiseScriptUnknown0x0C(WiseScriptUnknown0x0C * data) { printf("0x0B %02X '%s' '%s'\n", data->unknown_1, data->unknownString_1, data->unknownString_2); } void printWiseScriptUnknown0x11(WiseScriptUnknown0x11 * data) { printf("0x11 '%s'\n", data->unknownString_1); } void printWiseScriptUnknown0x12(WiseScriptUnknown0x12 * data) { printf("0x12 %02X ", data->unknown_1); printHex(data->unknown_41, 41); printf(" '%s' '%s' '%s' '%s'\n", data->sourceFile, data->unknownString_1, data->unknownString_2, data->destFile); } void printWiseScriptUnknown0x14(WiseScriptUnknown0x14 * data) { printf("0x14 0x%08X 0x%08X % 11u '%s' '%s'\n", data->deflateStart, data->deflateEnd, data->inflatedSize, data->name, data->message); } void printWiseScriptUnknown0x15(WiseScriptUnknown0x15 * data) { printf("0x15 %02X '%s' '%s'\n", data->unknown_1, data->unknownString_1, data->unknownString_2); } void printWiseScriptUnknown0x16(WiseScriptUnknown0x16 * data) { printf("0x16 '%s'\n", data->name); } void printWiseScriptUnknown0x17(WiseScriptUnknown0x17 * data) { printf("0x17 %02X ", data->unknown_1); printHex(data->unknown_4, 4); printf(" '%s'\n", data->unknownString_1); } void printWiseScriptUnknown0x1C(WiseScriptUnknown0x1C * data) { printf("0x1C '%s'\n", data->unknownString_1); } void printWiseScriptUnknown0x1E(WiseScriptUnknown0x1E * data) { printf("0x1E "); printHex(data->unknown_2, 2); printf("\n"); } void printWiseScriptUnknown0x23(WiseScriptUnknown0x23 * data) { printf("0x1C %02X '%s' '%s'\n", data->unknown_1, data->unknownString_1, data->unknownString_2); } void initWiseScriptCallbacks(WiseScriptCallbacks * callbacks) { callbacks->cb_header = NULL; callbacks->cb_texts = NULL; callbacks->cb_0x00 = NULL; callbacks->cb_0x03 = NULL; callbacks->cb_0x04 = NULL; callbacks->cb_0x05 = NULL; callbacks->cb_0x06 = NULL; callbacks->cb_0x07 = NULL; callbacks->cb_0x08 = NULL; callbacks->cb_0x09 = NULL; callbacks->cb_0x0A = NULL; callbacks->cb_0x0B = NULL; callbacks->cb_0x0C = NULL; callbacks->cb_0x0F = NULL; callbacks->cb_0x10 = NULL; callbacks->cb_0x11 = NULL; callbacks->cb_0x12 = NULL; callbacks->cb_0x14 = NULL; callbacks->cb_0x15 = NULL; callbacks->cb_0x16 = NULL; callbacks->cb_0x17 = NULL; callbacks->cb_0x1C = NULL; callbacks->cb_0x1E = NULL; callbacks->cb_0x23 = NULL; } REWError parseWiseScript(const char * filepath, WiseScriptCallbacks * callbacks) { FILE * fp; REWError status; unsigned char op; // check if file exists if (access(filepath, F_OK) != 0) { printError("parseWiseScript input file '%s' not found\n", filepath); printError("parseWiseScript errno: %s\n", strerror(errno)); return REWERR_ERRNO; } // open the file fp = fopen(filepath, "rb"); // failed to open the file if (fp == NULL) { printError("parseWiseScript failed to open file '%s'\n", filepath); printError("parseWiseScript errno: %s\n", strerror(errno)); return REWERR_ERRNO; } // Read the header { WiseScriptHeader header; status = readWiseScriptHeader(fp, &header); if (status != REWERR_OK) { printError("parseWiseScript failed to read header. %d\n", status); fclose(fp); return status; } // callback if (callbacks->cb_header != NULL) { (*callbacks->cb_header)(&header); } // cleanup freeWiseScriptHeader(&header); } // Read the texts { WiseScriptTexts texts; status = readWiseScriptTexts(fp, &texts); if (status != REWERR_OK) { printError("parseWiseScript failed to read texts. %d\n", status); fclose(fp); return status; } // callback if (callbacks->cb_texts != NULL) { (*callbacks->cb_texts)(&texts); } // cleanup freeWiseScriptTexts(&texts); } // Read operation and struct WiseScriptSTOP = 0; while (status == REWERR_OK && WiseScriptSTOP == 0) { int ch = fgetc(fp); op = (unsigned char)ch; if (ch == EOF) { break; } switch (op) { case 0x00: { WiseScriptFileHeader data; status = readWiseScriptFileHeader(fp, &data); if (status == REWERR_OK) { if (callbacks->cb_0x00 != NULL) { (*callbacks->cb_0x00)(&data); } freeWiseScriptFileHeader(&data); } } break; case 0x03: { WiseScriptUnknown0x03 data; status = readWiseScriptUnknown0x03(fp, &data); if (status == REWERR_OK) { if (callbacks->cb_0x03 != NULL) { (*callbacks->cb_0x03)(&data); } freeWiseScriptUnknown0x03(&data); } } break; case 0x04: { WiseScriptUnknown0x04 data; status = readWiseScriptUnknown0x04(fp, &data); if (status == REWERR_OK) { if (callbacks->cb_0x04 != NULL) { (*callbacks->cb_0x04)(&data); } freeWiseScriptUnknown0x04(&data); } } break; case 0x05: { WiseScriptUnknown0x05 data; status = readWiseScriptUnknown0x05(fp, &data); if (status == REWERR_OK) { if (callbacks->cb_0x05 != NULL) { (*callbacks->cb_0x05)(&data); } freeWiseScriptUnknown0x05(&data); } } break; case 0x06: { WiseScriptUnknown0x06 data; status = readWiseScriptUnknown0x06(fp, &data); if (status == REWERR_OK) { if (callbacks->cb_0x06 != NULL) { (*callbacks->cb_0x06)(&data); } } } break; case 0x07: { WiseScriptUnknown0x07 data; status = readWiseScriptUnknown0x07(fp, &data); if (status == REWERR_OK) { if (callbacks->cb_0x07 != NULL) { (*callbacks->cb_0x07)(&data); } freeWiseScriptUnknown0x07(&data); } } break; case 0x08: { WiseScriptUnknown0x08 data; status = readWiseScriptUnknown0x08(fp, &data); if (status == REWERR_OK) { if (callbacks->cb_0x08 != NULL) { (*callbacks->cb_0x08)(&data); } } } break; case 0x09: { WiseScriptUnknown0x09 data; status = readWiseScriptUnknown0x09(fp, &data); if (status == REWERR_OK) { if (callbacks->cb_0x09 != NULL) { (*callbacks->cb_0x09)(&data); } freeWiseScriptUnknown0x09(&data); } } break; case 0x0A: { WiseScriptUnknown0x0A data; status = readWiseScriptUnknown0x0A(fp, &data); if (status == REWERR_OK) { if (callbacks->cb_0x0A != NULL) { (*callbacks->cb_0x0A)(&data); } freeWiseScriptUnknown0x0A(&data); } } break; case 0x0B: { WiseScriptUnknown0x0B data; status = readWiseScriptUnknown0x0B(fp, &data); if (status == REWERR_OK) { if (callbacks->cb_0x0B != NULL) { (*callbacks->cb_0x0B)(&data); } freeWiseScriptUnknown0x0B(&data); } } break; case 0x0C: { WiseScriptUnknown0x0C data; status = readWiseScriptUnknown0x0C(fp, &data); if (status == REWERR_OK) { if (callbacks->cb_0x0C != NULL) { (*callbacks->cb_0x0C)(&data); } freeWiseScriptUnknown0x0C(&data); } } break; case 0x0F: // Start form data? if (callbacks->cb_0x0F != NULL) { (*callbacks->cb_0x0F)(); } break; case 0x10: // end form data? if (callbacks->cb_0x10 != NULL) { (*callbacks->cb_0x10)(); } break; case 0x11: { WiseScriptUnknown0x11 data; status = readWiseScriptUnknown0x11(fp, &data); if (status == REWERR_OK) { if (callbacks->cb_0x11 != NULL) { (*callbacks->cb_0x11)(&data); } freeWiseScriptUnknown0x11(&data); } } break; case 0x12: { WiseScriptUnknown0x12 data; status = readWiseScriptUnknown0x12(fp, &data); if (status == REWERR_OK) { if (callbacks->cb_0x12 != NULL) { (*callbacks->cb_0x12)(&data); } freeWiseScriptUnknown0x12(&data); } } break; case 0x14: { WiseScriptUnknown0x14 data; status = readWiseScriptUnknown0x14(fp, &data); if (status == REWERR_OK) { if (callbacks->cb_0x14 != NULL) { (*callbacks->cb_0x14)(&data); } freeWiseScriptUnknown0x14(&data); } } break; case 0x15: { WiseScriptUnknown0x15 data; status = readWiseScriptUnknown0x15(fp, &data); if (status == REWERR_OK) { if (callbacks->cb_0x15 != NULL) { (*callbacks->cb_0x15)(&data); } freeWiseScriptUnknown0x15(&data); } } break; case 0x16: { WiseScriptUnknown0x16 data; status = readWiseScriptUnknown0x16(fp, &data); if (status == REWERR_OK) { if (callbacks->cb_0x16 != NULL) { (*callbacks->cb_0x16)(&data); } freeWiseScriptUnknown0x16(&data); } } break; case 0x17: { WiseScriptUnknown0x17 data; status = readWiseScriptUnknown0x17(fp, &data); if (status == REWERR_OK) { if (callbacks->cb_0x17 != NULL) { (*callbacks->cb_0x17)(&data); } freeWiseScriptUnknown0x17(&data); } } break; // skip tailing zeros case 0x18: ch = 0x00; while (ch != EOF && ch == 0x00) { ch = fgetc(fp); } if (ch != EOF) { fseek(fp, -1, SEEK_CUR); } break; case 0x1B: case 0x0D: case 0x24: // TODO Skip? Only seen in RTCW case 0x25: // TODO Skip? Only seen in RTCW // Skip this byte break; case 0x1C: { WiseScriptUnknown0x1C data; status = readWiseScriptUnknown0x1C(fp, &data); if (status == REWERR_OK) { if (callbacks->cb_0x1C != NULL) { (*callbacks->cb_0x1C)(&data); } freeWiseScriptUnknown0x1C(&data); } } break; case 0x1E: { WiseScriptUnknown0x1E data; status = readWiseScriptUnknown0x1E(fp, &data); if (status == REWERR_OK && callbacks->cb_0x1E != NULL) { (*callbacks->cb_0x1E)(&data); } } break; case 0x23: { WiseScriptUnknown0x23 data; status = readWiseScriptUnknown0x23(fp, &data); if (status == REWERR_OK) { if (callbacks->cb_0x23 != NULL) { (*callbacks->cb_0x23)(&data); } freeWiseScriptUnknown0x23(&data); } } break; default: printError("parseWiseScript unknown OP: %02X at 0x%08X\n", ch, ftell(fp)); status = REWERR_NOOPT; break; } } fclose(fp); if (status != REWERR_OK) { printError("parseWiseScript OP 0x%02X failed\n", op); } return status; } void stopWiseScriptParse(void) { WiseScriptSTOP = 1; } static WiseScriptParsedInfo WISESCRIPT_PARSED_INFO = { .totalInflatedSize = 0, .inflatedSize0x00 = 0, .inflatedSize0x06 = 0, .inflatedSize0x14 = 0, .inflateStartOffset = 0 }; void updateParsedInfo0x00(WiseScriptFileHeader * data) { if (data->deflateEnd > WISESCRIPT_PARSED_INFO.inflateStartOffset ) { WISESCRIPT_PARSED_INFO.inflateStartOffset = data->deflateEnd; } WISESCRIPT_PARSED_INFO.totalInflatedSize += data->inflatedSize; WISESCRIPT_PARSED_INFO.inflatedSize0x00 += data->inflatedSize; } void updateParsedInfo0x06(WiseScriptUnknown0x06 * data) { if (data->deflateEnd > WISESCRIPT_PARSED_INFO.inflateStartOffset ) { WISESCRIPT_PARSED_INFO.inflateStartOffset = data->deflateEnd; } WISESCRIPT_PARSED_INFO.totalInflatedSize += data->inflatedSize; WISESCRIPT_PARSED_INFO.inflatedSize0x06 += data->inflatedSize; } void updateParsedInfo0x14(WiseScriptUnknown0x14 * data) { if (data->deflateEnd > WISESCRIPT_PARSED_INFO.inflateStartOffset ) { WISESCRIPT_PARSED_INFO.inflateStartOffset = data->deflateEnd; } WISESCRIPT_PARSED_INFO.totalInflatedSize += data->inflatedSize; WISESCRIPT_PARSED_INFO.inflatedSize0x14 += data->inflatedSize; } WiseScriptParsedInfo * wiseScriptGetParsedInfo(const char * filepath) { WiseScriptCallbacks callbacks; REWError status; initWiseScriptCallbacks(&callbacks); callbacks.cb_0x00 = &updateParsedInfo0x00; callbacks.cb_0x06 = &updateParsedInfo0x06; callbacks.cb_0x14 = &updateParsedInfo0x14; WISESCRIPT_PARSED_INFO.totalInflatedSize = 0; WISESCRIPT_PARSED_INFO.inflateStartOffset = 0; status = parseWiseScript(filepath, &callbacks); if (status != REWERR_OK) { printError("wiseScriptGetDeflateEnd parsing failed\n"); return NULL; } return &WISESCRIPT_PARSED_INFO; } REWError wiseScriptDebugPrint(const char * filepath) { WiseScriptCallbacks callbacks; initWiseScriptCallbacks(&callbacks); callbacks.cb_header = &printWiseScriptHeader; callbacks.cb_texts = &printWiseScriptTexts; callbacks.cb_0x00 = &printWiseScriptFileHeader; callbacks.cb_0x03 = &printWiseScriptUnknown0x03; callbacks.cb_0x04 = &printWiseScriptUnknown0x04; callbacks.cb_0x05 = &printWiseScriptUnknown0x05; callbacks.cb_0x06 = &printWiseScriptUnknown0x06; callbacks.cb_0x07 = &printWiseScriptUnknown0x07; callbacks.cb_0x08 = &printWiseScriptUnknown0x08; callbacks.cb_0x09 = &printWiseScriptUnknown0x09; callbacks.cb_0x0A = &printWiseScriptUnknown0x0A; callbacks.cb_0x0B = &printWiseScriptUnknown0x0B; callbacks.cb_0x0C = &printWiseScriptUnknown0x0C; callbacks.cb_0x11 = &printWiseScriptUnknown0x11; callbacks.cb_0x12 = &printWiseScriptUnknown0x12; callbacks.cb_0x14 = &printWiseScriptUnknown0x14; callbacks.cb_0x15 = &printWiseScriptUnknown0x15; callbacks.cb_0x16 = &printWiseScriptUnknown0x16; callbacks.cb_0x17 = &printWiseScriptUnknown0x17; callbacks.cb_0x1C = &printWiseScriptUnknown0x1C; callbacks.cb_0x1E = &printWiseScriptUnknown0x1E; callbacks.cb_0x23 = &printWiseScriptUnknown0x23; return parseWiseScript(filepath, &callbacks); } // Must be a valid pointer to a \0 terminated string. char * wiseScriptParsePath(char * path) { char * pathCopy; char * section; char newPath[PATH_MAX]; char * returnPath; uint32_t strSize = 0; // Basic verification that this string may be a valid path do { unsigned char ch = path[strSize]; if (ch == 0x00) { break; } // It contains a illegal character if (ch < 0x20 || ch > 0x7E || ch == '/') { printError("wiseScriptParsePath path contains an illegal character " "0x%02X\n", ch); return NULL; } strSize++; // Path is to long if (strSize > WIN_PATH_MAX) { printError("wiseScriptParsePath path is larger then WIN_PATH_MAX\n"); return NULL; } } while (1); // Check that the path starts with '%' if (path[0] != 0x25) { printError("wiseScriptParsePath path does not start with '%'\n"); return NULL; } // Duplicate the path for the use with strtok pathCopy = strdup(path); if (pathCopy == NULL) { printError("wiseScriptParsePath errno: %s\n", strerror(errno)); return NULL; } newPath[0] = 0x00; section = strtok(pathCopy, "\\"); do { size_t sectionLen = strlen(section); // Strip '%' from variables if (section[0] == 0x25 && section[sectionLen - 1] == 0x25) { section[sectionLen - 1] = 0x00; section++; if (section[0] == 0x00) { printError("wiseScriptParsePath empty path component.\n"); free(pathCopy); return NULL; } } if (sectionLen > NAME_MAX) { printError("wiseScriptParsePath path component name exceeds NAME_MAX\n"); free(pathCopy); return NULL; } // Don't allow a path section to start with '..' if (sectionLen >= 2) { if (section[0] == '.' && section[1] == '.') { printError("wiseScriptParsePath path component starts with '..'." " Symbolic paths are not allowed! Path: '%s'\n", path); free(pathCopy); return NULL; } } strcat(newPath, "/"); strcat(newPath, section); } while ((section = strtok(NULL, "\\"))); free(pathCopy); returnPath = strdup(newPath + 1); // +1 to remove the first character '/' if (returnPath == NULL) { printError("wiseScriptParsePath errno: %s\n", strerror(errno)); return NULL; } return returnPath; }