Mercurial > msvpvf
changeset 88:af4ed765c1ac
*: add IUP GUI
a lot simpler than win32, but I assume there's more going on in
the background that I don't know about :)
author | Paper <paper@tflc.us> |
---|---|
date | Mon, 14 Jul 2025 02:39:24 -0400 |
parents | 2e819b84d7c0 |
children | 42a1f64eb4b5 |
files | LICENSE Makefile include/common.h src/common.c src/gui.c src/iup.c src/main.c |
diffstat | 7 files changed, 359 insertions(+), 96 deletions(-) [+] |
line wrap: on
line diff
--- a/LICENSE Mon Jul 15 01:35:03 2024 -0400 +++ b/LICENSE Mon Jul 14 02:39:24 2025 -0400 @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2022-2024, Paper. +Copyright (c) 2022-2025, Paper. All rights reserved. Redistribution and use in source and binary forms, with or without
--- a/Makefile Mon Jul 15 01:35:03 2024 -0400 +++ b/Makefile Mon Jul 14 02:39:24 2025 -0400 @@ -1,4 +1,4 @@ -_CFLAGS = -Wall -g -O2 -Iinclude $(CFLAGS) +_CFLAGS = -Iinclude $(CFLAGS) -I/usr/include/iup _LDFLAGS = $(LDFLAGS) .c.o: @@ -12,5 +12,8 @@ gui: src/gui.o src/common.o $(CC) -o $@ $^ -mwindows -lole32 -lshlwapi -luuid -lmsvcrt $(_LDFLAGS) +iup: src/iup.o src/common.o + $(CC) -o $@ $^ -liup $(_LDFLAGS) + clean: - rm -f src/main.o src/common.o src/gui.o msvpvf gui + $(RM) src/main.o src/iup.o src/common.o src/gui.o msvpvf gui iup
--- a/include/common.h Mon Jul 15 01:35:03 2024 -0400 +++ b/include/common.h Mon Jul 14 02:39:24 2025 -0400 @@ -3,11 +3,12 @@ #include <stdio.h> #include <stdint.h> +#include <stddef.h> /* size_t */ +#include <stdarg.h> -#ifndef ARRAYSIZE -#define ARRAYSIZE(x) \ +/* windows clobbers ARRAYSIZE() */ +#define ARRAY_SIZE(x) \ (sizeof(x)/sizeof((x)[0])) -#endif enum types { TYPES_UNKNOWN = 0, @@ -15,7 +16,18 @@ TYPES_VEG }; +extern const char *type_names[]; + int set_file_information(FILE* target, uint8_t version, enum types type); int get_file_information(FILE* input, uint8_t* version, enum types* type); +int copy_file(FILE *source, FILE *target); + +/* simple malloc -> memcpy (memdup ?) */ +char *str_ndup(const char *str, size_t sz); +/* str_ndup(str, strlen(str)) */ +char *str_dup(const char *str); + +char *msvpvf_vasprintf(const char *format, va_list ap); +char *msvpvf_asprintf(const char *format, ...); #endif /* msvpvf_common_h */
--- a/src/common.c Mon Jul 15 01:35:03 2024 -0400 +++ b/src/common.c Mon Jul 14 02:39:24 2025 -0400 @@ -1,12 +1,14 @@ #include "common.h" #include <string.h> +#include <stdlib.h> /* hardcoded magic values; stored at 0x18... */ static const uint8_t magic_veg[16] = {0xEF, 0x29, 0xC4, 0x46, 0x4A, 0x90, 0xD2, 0x11, 0x87, 0x22, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A}; static const uint8_t magic_vf[16] = {0xF6, 0x1B, 0x3C, 0x53, 0x35, 0xD6, 0xF3, 0x43, 0x8A, 0x90, 0x64, 0xB8, 0x87, 0x23, 0x1F, 0x7F}; -int set_file_information(FILE* target, uint8_t version, enum types type) { +int set_file_information(FILE *target, uint8_t version, enum types type) +{ const uint8_t* magic = (type == TYPES_VF) ? magic_vf : magic_veg; if (fseek(target, 0x46, SEEK_SET)) @@ -24,7 +26,8 @@ return 0; } -int get_file_information(FILE* input, uint8_t* version, enum types* type) { +int get_file_information(FILE *input, uint8_t *version, enum types *type) +{ uint8_t magic[16] = {0}; if (fseek(input, 0x46, SEEK_SET)) @@ -36,12 +39,12 @@ return -1; /* read the WHOLE magic, then memcmp */ - if (fread(magic, sizeof(*magic), ARRAYSIZE(magic), input) < ARRAYSIZE(magic)) + if (fread(magic, sizeof(*magic), ARRAY_SIZE(magic), input) < ARRAY_SIZE(magic)) return -1; - if (!memcmp(magic, magic_veg, ARRAYSIZE(magic))) { + if (!memcmp(magic, magic_veg, ARRAY_SIZE(magic))) { *type = TYPES_VEG; - } else if (!memcmp(magic, magic_vf, ARRAYSIZE(magic))) { + } else if (!memcmp(magic, magic_vf, ARRAY_SIZE(magic))) { *type = TYPES_VF; } else { *type = TYPES_UNKNOWN; @@ -49,3 +52,92 @@ return 0; } + +/* source needs read permissions, target needs write permissions, both must be in binary mode */ +int copy_file(FILE *source, FILE *target) +{ + char ch[4096]; + + while (!feof(source)) { + size_t b = fread(ch, 1, sizeof(ch), source); + if (b && (fwrite(ch, 1, b, target) < b)) + return -1; + } + + return 0; +} + +/* ------------------------------------------------------------------------ */ + +char *str_ndup(const char *str, size_t sz) +{ + char *x; + + x = malloc(sz + 1); + if (!x) + return NULL; + + memcpy(x, str, sz); + x[sz] = 0; + + return x; +} + +char *str_dup(const char *str) +{ + return str_ndup(str, strlen(str)); +} + +/* ------------------------------------------------------------------------ */ + +const char *type_names[] = { + [TYPES_VF] = "Movie Studio", + [TYPES_VEG] = "Vegas Pro", + [TYPES_UNKNOWN] = "Unknown", +}; + +/* ------------------------------------------------------------------------ */ + +char *msvpvf_vasprintf(const char *format, va_list ap) +{ + va_list ap2; + int needed_size; + char *output = NULL; + + va_copy(ap2, ap); + + needed_size = vsnprintf(NULL, 0, format, ap); + if (needed_size < 0) { + va_end(ap2); + return NULL; + } + + output = malloc((needed_size + 1) * sizeof(char)); + if (!output) { + va_end(ap2); + return NULL; + } + + needed_size = vsnprintf(output, needed_size + 1, format, ap2); + if (needed_size < 0) { + free(output); + va_end(ap2); + return NULL; + } + + va_end(ap2); + + return output; +} + +char *msvpvf_asprintf(const char *format, ...) +{ + char *x; + va_list ap; + + va_start(ap, format); + x = msvpvf_vasprintf(format, ap); + va_end(ap); + + return x; +}
--- a/src/gui.c Mon Jul 15 01:35:03 2024 -0400 +++ b/src/gui.c Mon Jul 14 02:39:24 2025 -0400 @@ -13,8 +13,6 @@ #include <stdint.h> #include <stdio.h> -#include <tchar.h> /* tchar versions of string.h functions */ - #include "common.h" /* make sure this is defined... */ @@ -34,13 +32,6 @@ VERSION }; -#if UNICODE -/* use COM when `UNICODE=1` to avoid file paths being cut off */ -#include <shobjidl.h> - -static const DWORD COM_INITFLAGS = (COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); -#endif - /* user-adjustable. set these values to whatever you want, the GUI will scale */ #define WINDOW_WIDTH 225U #define WINDOW_HEIGHT 200U @@ -120,7 +111,7 @@ IShellItem* result = NULL; if (SUCCEEDED(CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, &IID_IFileOpenDialog, (LPVOID*)&pfd))) { - pfd->lpVtbl->SetFileTypes(pfd, ARRAYSIZE(filters), filters); + pfd->lpVtbl->SetFileTypes(pfd, ARRAY_SIZE(filters), filters); pfd->lpVtbl->SetFileTypeIndex(pfd, 1); pfd->lpVtbl->Show(pfd, hWnd); @@ -196,8 +187,8 @@ IFileDialog* pfd = NULL; IShellItem* result = NULL; if (com_initialized && SUCCEEDED(CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER, &IID_IFileSaveDialog, (LPVOID*)&pfd))) { - pfd->lpVtbl->SetFileTypes(pfd, ARRAYSIZE(filters), filters); - pfd->lpVtbl->SetFileTypeIndex(pfd, (type == TYPES_UNKNOWN) ? ARRAYSIZE(filters) : type - TYPES_UNKNOWN); + pfd->lpVtbl->SetFileTypes(pfd, ARRAY_SIZE(filters), filters); + pfd->lpVtbl->SetFileTypeIndex(pfd, (type == TYPES_UNKNOWN) ? ARRAY_SIZE(filters) : type - TYPES_UNKNOWN); pfd->lpVtbl->SetFileName(pfd, output_template); pfd->lpVtbl->Show(pfd, hWnd); @@ -291,7 +282,7 @@ /* Type */ HWND listbox = CreateWindow(TEXT("Listbox"), NULL, WS_VISIBLE | WS_CHILD | LBS_STANDARD | LBS_NOTIFY, WINDOW_WIDTH * 5 / 18, WINDOW_HEIGHT * 11 / 40, WINDOW_WIDTH * 4 / 9, WINDOW_HEIGHT / 5, hWnd, (HMENU)LISTBOX, NULL, NULL); - for (size_t i = 0; i < ARRAYSIZE(types); i++) { + for (size_t i = 0; i < ARRAY_SIZE(types); i++) { LRESULT pos = SendMessage(listbox, LB_ADDSTRING, i, (LPARAM)type_to_string(types[i])); SendMessage(listbox, LB_SETITEMDATA, pos, types[i]); if (types[i] == type) @@ -375,6 +366,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR args, int ncmdshow) { WNDCLASS wc = {0}; + MSG msg = {0}; wc.hbrBackground = (HBRUSH)COLOR_WINDOW; wc.hCursor = LoadCursor(NULL, IDC_ARROW); @@ -386,8 +378,6 @@ CreateWindowEx(WS_EX_ACCEPTFILES, TEXT("msvpvf"), TEXT("Movie Studio / Vegas Pro version spoofer"), WS_OVERLAPPED | WS_VISIBLE | WS_MINIMIZEBOX | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInstance, NULL); - MSG msg = {0}; - while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iup.c Mon Jul 14 02:39:24 2025 -0400 @@ -0,0 +1,231 @@ +#include "common.h" + +#include <iup.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> + +struct msvpvf { + struct { + Ihandle *main; /* main window */ + Ihandle *program; /* listbox, which program (Vegas Pro/Movie Studio) */ + Ihandle *ver; /* which version */ + Ihandle *vbox; /* main window vbox */ + Ihandle *ofilebtn; /* open file button */ + Ihandle *sfilebtn; /* save file button */ + Ihandle *info; /* opened file info */ + Ihandle *about_button; /* about button */ + Ihandle *about; /* about dialog */ + Ihandle *about_text; /* about text */ + } dlg; + + /* XXX this should be FILE *, so we can't randomly lose the file */ + char *open_file; + + uint8_t version; + enum types type; +}; + +static int msvpvf_info_update(struct msvpvf *m) +{ + uint8_t ver; + enum types type; + char *a; + + if (!m) return -1; + + { + FILE *i; + + i = fopen(m->open_file, "rb"); + if (!i) return 0; + + get_file_information(i, &ver, &type); + fclose(i); + } + + a = msvpvf_asprintf("File version: %s %d", type_names[type], (int)ver); + if (!a) return 0; + IupSetStrAttribute(m->dlg.info, "VALUE", a); + free(a); + + return 1; +} + +static int open_file(Ihandle *ih) +{ + /* why is IupGetAttribute not void * */ + struct msvpvf *m = (struct msvpvf *)IupGetAttribute(ih, "msvpvf"); + const char *ofile; + Ihandle *dlg = IupFileDlg(); + + IupSetAttribute(dlg, "DIALOGTYPE", "OPEN"); + IupSetAttribute(dlg, "TITLE", "Vegas Pro / Movie Studio version spoofer"); + IupSetAttributes(dlg, "FILTER = \"*.veg;*.vf\", FILTERINFO = \"Project files\""); + + IupPopup(dlg, IUP_CURRENT, IUP_CURRENT); + + if (IupGetInt(dlg, "STATUS") != -1) { + m->open_file = str_dup(IupGetAttribute(dlg, "VALUE")); + if (!msvpvf_info_update(m)) + free(m->open_file); + } + + IupDestroy(dlg); + return 0; +} + +static int save_file(Ihandle *ih) +{ + struct msvpvf *m = (struct msvpvf *)IupGetAttribute(ih, "msvpvf"); + Ihandle *dlg; + + if (!m->open_file) + return 0; + + dlg = IupFileDlg(); + + IupSetAttribute(dlg, "DIALOGTYPE", "SAVE"); + IupSetAttribute(dlg, "TITLE", "Vegas Pro / Movie Studio version spoofer"); + /* FIXME add *.vf here */ + IupSetAttributes(dlg, "FILTER = \"*.veg;*.vf\", FILTERINFO = \"Project files\""); + IupSetAttribute(dlg, "EXTDEFAULT", (m->type == TYPES_VF ? "vf" : "veg")); + + IupPopup(dlg, IUP_CURRENT, IUP_CURRENT); + + if (IupGetInt(dlg, "STATUS") != -1) { + FILE *i, *o; + const char *sname; + + sname = IupGetAttribute(dlg, "VALUE"); + + i = fopen(m->open_file, "rb"); + o = fopen(sname, "wb"); + + if (i && o && (copy_file(i, o) >= 0)) + set_file_information(o, m->version, m->type); + + if (i) fclose(i); + if (o) fclose(o); + } + + IupDestroy(dlg); + return 0; +} + +static int type_cb(Ihandle *ih, char *text, int item, int state) +{ + struct msvpvf *m = (struct msvpvf *)IupGetAttribute(ih, "msvpvf"); + + switch (item) { + case 1: m->type = TYPES_VEG; break; + case 2: m->type = TYPES_VF; break; + default: abort(); + } + + return 0; +} + +static int ver_cb(Ihandle *ih) +{ + struct msvpvf *m = (struct msvpvf *)IupGetAttribute(ih, "msvpvf"); + + /* epic */ + m->version = IupGetIntId(ih, "SPINVALUE", 11); + + return 0; +} + +static int about_cb(Ihandle *ih) +{ + struct msvpvf *m = (struct msvpvf *)IupGetAttribute(ih, "msvpvf"); + + IupPopup(m->dlg.about, IUP_CURRENT, IUP_CURRENT); + + return 0; +} + +int main(int argc, char *argv[]) +{ + struct msvpvf msvpvf; + static const char about_text[] = { +#embed "../LICENSE" + , 0 /* nul terminate */ + }; + + IupOpen(&argc, &argv); + IupSetLanguage("ENGLISH"); + + // FIXME: use UTF-8 filenames on Windows + + msvpvf.dlg.ofilebtn = IupButton("Open File", NULL); + IupSetAttribute(msvpvf.dlg.ofilebtn, "msvpvf", (char *)&msvpvf); + IupSetCallback(msvpvf.dlg.ofilebtn, "ACTION", open_file); + + msvpvf.dlg.info = IupText(NULL); + IupSetAttribute(msvpvf.dlg.info, "READONLY", "YES"); + IupSetAttribute(msvpvf.dlg.info, "VISIBLECOLUMNS", "15"); + IupSetAttribute(msvpvf.dlg.info, "VALUE", "No file opened!"); + IupSetAttribute(msvpvf.dlg.info, "ALIGNMENT", "ACENTER"); + IupSetAttribute(msvpvf.dlg.info, "CANFOCUS", "NO"); + IupSetAttribute(msvpvf.dlg.info, "BORDER", "NO"); + + msvpvf.dlg.program = IupList(NULL); + IupSetAttribute(msvpvf.dlg.program, "msvpvf", (char *)&msvpvf); + IupSetAttribute(msvpvf.dlg.program, "ALIGNMENT", "ACENTER"); + IupSetAttribute(msvpvf.dlg.program, "1", "Vegas Pro"); + IupSetAttribute(msvpvf.dlg.program, "2", "Movie Studio"); + IupSetAttribute(msvpvf.dlg.program, "3", NULL); + IupSetAttribute(msvpvf.dlg.program, "VALUE", "1"); + IupSetAttribute(msvpvf.dlg.program, "EXPAND", "YES"); + IupSetCallback(msvpvf.dlg.program, "ACTION", (Icallback)type_cb); + msvpvf.type = TYPES_VEG; + + msvpvf.dlg.ver = IupText(NULL); + IupSetAttribute(msvpvf.dlg.ver, "msvpvf", (char *)&msvpvf); + IupSetAttribute(msvpvf.dlg.ver, "SPIN", "YES"); + IupSetAttribute(msvpvf.dlg.ver, "SPINMAX", "21"); + IupSetAttribute(msvpvf.dlg.ver, "SPINMIN", "8"); + IupSetAttribute(msvpvf.dlg.ver, "SPINVALUE", "11"); /* default */ + IupSetCallback(msvpvf.dlg.ver, "ACTION", ver_cb); + msvpvf.version = 11; + + msvpvf.dlg.sfilebtn = IupButton("Save File", NULL); + IupSetAttribute(msvpvf.dlg.sfilebtn, "msvpvf", (char *)&msvpvf); + IupSetCallback(msvpvf.dlg.sfilebtn, "ACTION", save_file); + + msvpvf.dlg.about_button = IupButton("About msvpvf", NULL); + IupSetAttribute(msvpvf.dlg.about_button, "msvpvf", (char *)&msvpvf); + IupSetCallback(msvpvf.dlg.about_button, "ACTION", about_cb); + + msvpvf.dlg.vbox = IupVbox(msvpvf.dlg.ofilebtn, msvpvf.dlg.info, msvpvf.dlg.program, msvpvf.dlg.ver, msvpvf.dlg.sfilebtn, msvpvf.dlg.about_button, NULL); + IupSetAttribute(msvpvf.dlg.vbox, "ALIGNMENT", "ACENTER"); + IupSetAttribute(msvpvf.dlg.vbox, "GAP", "10"); + IupSetAttribute(msvpvf.dlg.vbox, "MARGIN", "10x10"); + IupSetAttribute(msvpvf.dlg.vbox, "EXPAND", "YES"); + + msvpvf.dlg.main = IupDialog(msvpvf.dlg.vbox); + IupSetAttribute(msvpvf.dlg.main, "TITLE", "Vegas Pro / Movie Studio version spoofer"); + //IupSetAttribute(msvpvf.dlg.main, "MINSIZE", "225x200"); + + msvpvf.dlg.about_text = IupText(NULL); + IupSetAttribute(msvpvf.dlg.about_text, "READONLY", "YES"); + IupSetAttribute(msvpvf.dlg.about_text, "VALUE", about_text); + IupSetAttribute(msvpvf.dlg.about_text, "CANFOCUS", "NO"); + IupSetAttribute(msvpvf.dlg.about_text, "BORDER", "NO"); + IupSetAttribute(msvpvf.dlg.about_text, "MULTILINE", "YES"); + IupSetAttribute(msvpvf.dlg.about_text, "EXPAND", "YES"); + IupSetAttribute(msvpvf.dlg.about_text, "PADDING", "10x10"); + + msvpvf.dlg.about = IupDialog(msvpvf.dlg.about_text); + IupSetAttribute(msvpvf.dlg.about, "TITLE", "About Vegas Pro / Movie Studio version spoofer"); + IupSetAttribute(msvpvf.dlg.about, "MINSIZE", "500x300"); + + IupShowXY(msvpvf.dlg.main, IUP_CENTER, IUP_CENTER); + + IupMainLoop(); + + IupClose(); + + return 0; +}
--- a/src/main.c Mon Jul 15 01:35:03 2024 -0400 +++ b/src/main.c Mon Jul 14 02:39:24 2025 -0400 @@ -9,79 +9,14 @@ #include "common.h" -/* non-portable functions */ -static char* msvpvf_internal_strdup(const char* str) { - size_t len = strlen(str) + 1; - - char* copy = malloc(len); - if (!copy) - return NULL; - - memcpy(copy, str, len); - return copy; -} - -static char *msvpvf_internal_asnprintf(const char *format, ...) { - va_list args; - int needed_size; - char *output = NULL; - - va_start(args, format); - - needed_size = vsnprintf(NULL, 0, format, args); - if (needed_size < 0) - return NULL; - - va_end(args); - - output = malloc((needed_size + 1) * sizeof(char)); - if (!output) - return NULL; - - va_start(args, format); - - needed_size = vsnprintf(output, needed_size + 1, format, args); - if (needed_size < 0) { - free(output); - return NULL; - } - - va_end(args); - - return output; -} - -/* source needs read permissions, target needs write permissions, both must be in binary mode */ -static int copy_file(FILE* source, FILE* target) { - char ch[4096]; - - while (!feof(source)) { - size_t b = fread(ch, 1, sizeof(ch), source); - if (b) - fwrite(ch, 1, b, target); - } - - return 0; -} - -static const char* type_names[] = { - [TYPES_VF] = "Movie Studio", - [TYPES_VEG] = "Vegas Pro", - [TYPES_UNKNOWN] = "Unknown", -}; - -static const char* type_extensions[] = { +static const char *type_extensions[] = { [TYPES_VF] = "vf", [TYPES_VEG] = "veg", }; -#ifndef ARRAYSIZE -#define ARRAYSIZE(x) (sizeof(x) / sizeof((x)[0])) -#endif - static const char* help_text = "msvpvf help text\n" - "author: Paper <paper@paper.us.eu.org>\n" + "author: Paper <paper@tflc.us>\n" "usage: %s <input>... (arguments)\n" "\n" "arguments:\n" @@ -168,13 +103,13 @@ { /* open the output file... */ - char* basec = msvpvf_internal_strdup(input); + char* basec = str_dup(input); char* bname = basename(basec); int ext = strrchr(bname, '.') - bname; - char *output = msvpvf_internal_asnprintf("V%u_%.*s.%s", version, ext, bname, type_extensions[type]); + char *output = msvpvf_asprintf("V%u_%.*s.%s", version, ext, bname, type_extensions[type]); if (!output) { - fprintf(stderr, "[ERROR]: msvpvf_internal_asnprintf failed!\n"); + fprintf(stderr, "[ERROR]: msvpvf_asprintf failed!\n"); free(basec); free(output); fclose(input_file);