fixing unicode output on Windows

This commit is contained in:
Martins Mozeiko
2017-11-12 15:48:57 -08:00
parent dcec2ea31e
commit ffdb0e8ada
8 changed files with 175 additions and 106 deletions
+45 -45
View File
@@ -25,10 +25,9 @@ static const uint8_t pkg_vita_4[] = { 0xaf, 0x07, 0xfd, 0x59, 0x65, 0x25, 0x27,
// https://github.com/TheOfficialFloW/VitaShell/blob/1.74/sfo.h#L29
static void parse_sfo_content(const uint8_t* sfo, uint32_t sfo_size, char* category, char* title, char* content, char* min_version, char* pkg_version)
{
if (get32le(sfo) != 0x46535000)
{
fatal("ERROR: incorrect sfo signature\n");
sys_error("ERROR: incorrect sfo signature\n");
}
uint32_t keys = get32le(sfo + 8);
@@ -44,7 +43,7 @@ static void parse_sfo_content(const uint8_t* sfo, uint32_t sfo_size, char* categ
{
if (i * 16 + 20 + 2 > sfo_size)
{
fatal("ERROR: sfo information is too small\n");
sys_error("ERROR: sfo information is too small\n");
}
char* key = (char*)sfo + keys + get16le(sfo + i * 16 + 20);
@@ -79,7 +78,7 @@ static void parse_sfo_content(const uint8_t* sfo, uint32_t sfo_size, char* categ
if (title_index < 0)
{
fatal("ERROR: cannot find title from sfo file, pkg is probably corrupted\n");
sys_error("ERROR: cannot find title from sfo file, pkg is probably corrupted\n");
}
char* value = (char*)sfo + values + get32le(sfo + title_index * 16 + 20 + 12);
@@ -168,11 +167,11 @@ static void parse_sfo(sys_file f, uint64_t sfo_offset, uint32_t sfo_size, char*
uint8_t sfo[16 * 1024];
if (sfo_size < 16)
{
fatal("ERROR: sfo information is too small\n");
sys_error("ERROR: sfo information is too small\n");
}
if (sfo_size > sizeof(sfo))
{
fatal("ERROR: sfo information is too big, pkg file is probably corrupted\n");
sys_error("ERROR: sfo information is too big, pkg file is probably corrupted\n");
}
sys_read(f, sfo_offset, sfo, sfo_size);
@@ -200,7 +199,7 @@ static void find_psp_sfo(const aes128_key* key, const aes128_key* ps3_key, const
if (pkg_size < enc_offset + name_offset + name_size ||
pkg_size < enc_offset + data_offset + data_size)
{
fatal("ERROR: pkg file is too short, possibly corrupted\n");
sys_error("ERROR: pkg file is too short, possibly corrupted\n");
}
const aes128_key* item_key = psp_type == 0x90 ? key : ps3_key;
@@ -215,11 +214,11 @@ static void find_psp_sfo(const aes128_key* key, const aes128_key* ps3_key, const
uint8_t sfo[16 * 1024];
if (data_size < 16)
{
fatal("ERROR: sfo information is too small\n");
sys_error("ERROR: sfo information is too small\n");
}
if (data_size > sizeof(sfo))
{
fatal("ERROR: sfo information is too big, pkg file is probably corrupted\n");
sys_error("ERROR: sfo information is too big, pkg file is probably corrupted\n");
}
sys_read(pkg, enc_offset + data_offset, sfo, (uint32_t)data_size);
@@ -272,7 +271,8 @@ typedef enum {
int main(int argc, char* argv[])
{
printf("pkg2zip v1.8\n");
sys_output_init();
sys_output("pkg2zip v1.8\n");
int zipped = 1;
int cso = 5;
@@ -309,10 +309,10 @@ int main(int argc, char* argv[])
if (pkg_arg == NULL)
{
fprintf(stderr, "ERROR: no pkg file specified\n");
fatal("Usage: %s [-x] [-c[N]] file.pkg [zRIF]\n", argv[0]);
sys_error("Usage: %s [-x] [-c[N]] file.pkg [zRIF]\n", argv[0]);
}
printf("[*] loading...\n");
sys_output("[*] loading...\n");
uint64_t pkg_size;
sys_file pkg = sys_open(pkg_arg, &pkg_size);
@@ -322,7 +322,7 @@ int main(int argc, char* argv[])
if (get32be(pkg_header) != 0x7f504b47 || get32be(pkg_header + PKG_HEADER_SIZE) != 0x7F657874)
{
fatal("ERROR: not a pkg file\n");
sys_error("ERROR: not a pkg file\n");
}
// http://www.psdevwiki.com/ps3/PKG_files
@@ -337,11 +337,11 @@ int main(int argc, char* argv[])
if (pkg_size < total_size)
{
fatal("ERROR: pkg file is too small\n");
sys_error("ERROR: pkg file is too small\n");
}
if (pkg_size < enc_offset + item_count * 32)
{
fatal("ERROR: pkg file is too small\n");
sys_error("ERROR: pkg file is too small\n");
}
uint32_t content_type = 0;
@@ -402,7 +402,7 @@ int main(int argc, char* argv[])
}
else
{
fatal("ERROR: unsupported content type 0x%x", content_type);
sys_error("ERROR: unsupported content type 0x%x", content_type);
}
aes128_key ps3_key;
@@ -476,7 +476,7 @@ int main(int argc, char* argv[])
const char* rif_contentid = (char*)rif + (type == PKG_TYPE_VITA_PSM ? 0x50 : 0x10);
if (strncmp(rif_contentid, content, 0x30) != 0)
{
fatal("ERROR: zRIF content id '%s' doesn't match pkg '%s'\n", rif_contentid, content);
sys_error("ERROR: zRIF content id '%s' doesn't match pkg '%s'\n", rif_contentid, content);
}
}
}
@@ -496,42 +496,42 @@ int main(int argc, char* argv[])
type_str = content_type == 0xe ? "PSP-Go" : content_type == 0xf ? "PSP-Mini" : "PSP-NeoGeo";
}
snprintf(root, sizeof(root), "%s [%.9s] [%s]%s", title, id, type_str, ext);
printf("[*] unpacking %s\n", type_str);
sys_output("[*] unpacking %s\n", type_str);
}
else if (type == PKG_TYPE_PSX)
{
snprintf(root, sizeof(root), "%s [%.9s] [PSX]%s", title, id, ext);
printf("[*] unpacking PSX\n");
sys_output("[*] unpacking PSX\n");
}
else if (type == PKG_TYPE_VITA_DLC)
{
snprintf(root, sizeof(root), "%s [%.9s] [%s] [DLC-%s]%s", title, id, get_region(id), id2, ext);
printf("[*] unpacking DLC\n");
sys_output("[*] unpacking DLC\n");
}
else if (type == PKG_TYPE_VITA_PATCH)
{
snprintf(root, sizeof(root), "%s [%.9s] [%s] [PATCH] [v%s]%s", title, id, get_region(id), pkg_version, ext);
printf("[*] unpacking PATCH\n");
sys_output("[*] unpacking PATCH\n");
}
else if (type == PKG_TYPE_VITA_PSM)
{
snprintf(root, sizeof(root), "%.9s [%s]%s", id, get_region(id), ext);
printf("[*] unpacking PSM\n");
sys_output("[*] unpacking PSM\n");
}
else if (type == PKG_TYPE_VITA_APP)
{
snprintf(root, sizeof(root), "%s [%.9s] [%s]%s", title, id, get_region(id), ext);
printf("[*] unpacking APP\n");
sys_output("[*] unpacking APP\n");
}
else
{
assert(0);
fatal("ERROR: unsupported type\n");
sys_error("ERROR: unsupported type\n");
}
if (zipped)
{
printf("[*] creating '%s' archive\n", root);
sys_output("[*] creating '%s' archive\n", root);
}
out_begin(root, zipped);
@@ -603,10 +603,10 @@ int main(int argc, char* argv[])
else
{
assert(0);
fatal("ERROR: unsupported type\n");
sys_error("ERROR: unsupported type\n");
}
printf("[*] decrypting...\n");
sys_output("[*] decrypting...\n");
char path[1024];
int sce_sys_package_created = 0;
@@ -631,12 +631,12 @@ int main(int argc, char* argv[])
if (pkg_size < enc_offset + name_offset + name_size ||
pkg_size < enc_offset + data_offset + data_size)
{
fatal("ERROR: pkg file is too short, possibly corrupted\n");
sys_error("ERROR: pkg file is too short, possibly corrupted\n");
}
if (name_size >= ZIP_MAX_FILENAME)
{
fatal("ERROR: pkg file contains file with very long name\n");
sys_error("ERROR: pkg file contains file with very long name\n");
}
const aes128_key* item_key;
@@ -654,7 +654,7 @@ int main(int argc, char* argv[])
aes128_ctr_xor(item_key, iv, name_offset / 16, (uint8_t*)name, name_size);
name[name_size] = 0;
printf("[%u/%u] %s\n", item_index + 1, item_count, name);
sys_output("[%u/%u] %s\n", item_index + 1, item_count, name);
if (flags == 4 || flags == 18)
{
@@ -770,12 +770,12 @@ int main(int argc, char* argv[])
{
if (!sce_sys_package_created)
{
printf("[*] creating sce_sys/package\n");
sys_output("[*] creating sce_sys/package\n");
snprintf(path, sizeof(path), "%s/sce_sys/package", root);
out_add_folder(path);
}
printf("[*] creating sce_sys/package/head.bin\n");
sys_output("[*] creating sce_sys/package/head.bin\n");
snprintf(path, sizeof(path), "%s/sce_sys/package/head.bin", root);
out_begin_file(path, 0);
@@ -792,7 +792,7 @@ int main(int argc, char* argv[])
}
out_end_file();
printf("[*] creating sce_sys/package/tail.bin\n");
sys_output("[*] creating sce_sys/package/tail.bin\n");
snprintf(path, sizeof(path), "%s/sce_sys/package/tail.bin", root);
out_begin_file(path, 0);
@@ -807,7 +807,7 @@ int main(int argc, char* argv[])
}
out_end_file();
printf("[*] creating sce_sys/package/stat.bin\n");
sys_output("[*] creating sce_sys/package/stat.bin\n");
snprintf(path, sizeof(path), "%s/sce_sys/package/stat.bin", root);
uint8_t stat[768] = { 0 };
@@ -820,16 +820,16 @@ int main(int argc, char* argv[])
{
if (type == PKG_TYPE_VITA_PSM)
{
printf("[*] creating RO/License\n");
sys_output("[*] creating RO/License\n");
snprintf(path, sizeof(path), "%s/RO/License", root);
out_add_folder(path);
printf("[*] creating RO/License/FAKE.rif\n");
sys_output("[*] creating RO/License/FAKE.rif\n");
snprintf(path, sizeof(path), "%s/RO/License/FAKE.rif", root);
}
else
{
printf("[*] creating sce_sys/package/work.bin\n");
sys_output("[*] creating sce_sys/package/work.bin\n");
snprintf(path, sizeof(path), "%s/sce_sys/package/work.bin", root);
}
@@ -840,29 +840,29 @@ int main(int argc, char* argv[])
if (type == PKG_TYPE_VITA_PSM)
{
printf("[*] creating RW\n");
sys_output("[*] creating RW\n");
snprintf(path, sizeof(path), "%s/RW", root);
out_add_folder(path);
printf("[*] creating RW/Documents\n");
sys_output("[*] creating RW/Documents\n");
snprintf(path, sizeof(path), "%s/RW/Documents", root);
out_add_folder(path);
printf("[*] creating RW/Temp\n");
sys_output("[*] creating RW/Temp\n");
snprintf(path, sizeof(path), "%s/RW/Temp", root);
out_add_folder(path);
printf("[*] creating RW/System\n");
sys_output("[*] creating RW/System\n");
snprintf(path, sizeof(path), "%s/RW/System", root);
out_add_folder(path);
printf("[*] creating RW/System/content_id\n");
sys_output("[*] creating RW/System/content_id\n");
snprintf(path, sizeof(path), "%s/RW/System/content_id", root);
out_begin_file(path, 0);
out_write(pkg_header + 0x30, 0x30);
out_end_file();
printf("[*] creating RW/System/pm.dat\n");
sys_output("[*] creating RW/System/pm.dat\n");
snprintf(path, sizeof(path), "%s/RW/System/pm.dat", root);
uint8_t pm[1 << 16] = { 0 };
@@ -875,8 +875,8 @@ int main(int argc, char* argv[])
if (type == PKG_TYPE_VITA_APP || type == PKG_TYPE_VITA_PATCH)
{
printf("[*] minimum fw version required: %s\n", min_version);
sys_output("[*] minimum fw version required: %s\n", min_version);
}
printf("[*] done!\n");
sys_output("[*] done!\n");
}
+16 -16
View File
@@ -50,7 +50,7 @@ static void rc_init(lzrc_decode* rc, void* out, int out_len, const void* in, int
{
if (in_len < 5)
{
fatal("ERROR: internal error - lzrc input underflow! pkg may be corrupted?\n");
sys_error("ERROR: internal error - lzrc input underflow! pkg may be corrupted?\n");
}
rc->input = in;
@@ -199,7 +199,7 @@ static int lzrc_decompress(void* out, int out_len, const void* in, int in_len)
if (rc.out_ptr == rc.out_len)
{
fatal("ERROR: internal error - lzrc output overflow! pkg may be corrupted?\n");
sys_error("ERROR: internal error - lzrc output overflow! pkg may be corrupted?\n");
}
rc.output[rc.out_ptr++] = (uint8_t)byte;
last_byte = (uint8_t)byte;
@@ -261,12 +261,12 @@ static int lzrc_decompress(void* out, int out_len, const void* in, int in_len)
// copy match bytes
if (match_dist > rc.out_ptr)
{
fatal("ERROR: internal error - lzrc match_dist out of range! pkg may be corrupted?\n");
sys_error("ERROR: internal error - lzrc match_dist out of range! pkg may be corrupted?\n");
}
if (rc.out_ptr + match_len + 1 > rc.out_len)
{
fatal("ERROR: internal error - lzrc output overflow! pkg may be corrupted?\n");
sys_error("ERROR: internal error - lzrc output overflow! pkg may be corrupted?\n");
}
const uint8_t* match_src = rc.output + rc.out_ptr - match_dist;
@@ -315,7 +315,7 @@ void unpack_psp_eboot(const char* path, const aes128_key* pkg_key, const uint8_t
{
if (item_size < 0x28)
{
fatal("ERROR: eboot.pbp file is to short!\n");
sys_error("ERROR: eboot.pbp file is to short!\n");
}
uint8_t eboot_header[0x28];
@@ -324,13 +324,13 @@ void unpack_psp_eboot(const char* path, const aes128_key* pkg_key, const uint8_t
if (memcmp(eboot_header, "\x00PBP", 4) != 0)
{
fatal("ERROR: wrong eboot.pbp header signature!\n");
sys_error("ERROR: wrong eboot.pbp header signature!\n");
}
uint32_t psar_offset = get32le(eboot_header + 0x24);
if (psar_offset + 256 > item_size)
{
fatal("ERROR: eboot.pbp file is to short!\n");
sys_error("ERROR: eboot.pbp file is to short!\n");
}
assert(psar_offset % 16 == 0);
@@ -340,13 +340,13 @@ void unpack_psp_eboot(const char* path, const aes128_key* pkg_key, const uint8_t
if (memcmp(psar_header, "NPUMDIMG", 8) != 0)
{
fatal("ERROR: wrong data.psar header signature!\n");
sys_error("ERROR: wrong data.psar header signature!\n");
}
uint32_t iso_block = get32le(psar_header + 0x0c);
if (iso_block > 16)
{
fatal("ERROR: unsupported data.psar block size %u, max %u supported!\b", iso_block, 16);
sys_error("ERROR: unsupported data.psar block size %u, max %u supported!\b", iso_block, 16);
}
uint8_t mac[16];
@@ -366,7 +366,7 @@ void unpack_psp_eboot(const char* path, const aes128_key* pkg_key, const uint8_t
if (iso_table + block_count * 32 > item_size)
{
fatal("ERROR: offset table in data.psar file is too large!\n");
sys_error("ERROR: offset table in data.psar file is too large!\n");
}
mz_uint cso_compress_flags = 0;
@@ -411,7 +411,7 @@ void unpack_psp_eboot(const char* path, const aes128_key* pkg_key, const uint8_t
if (psar_offset + block_size > item_size)
{
fatal("ERROR: iso block size/offset is to large!\n");
sys_error("ERROR: iso block size/offset is to large!\n");
}
uint8_t PKG_ALIGN(16) data[16 * ISO_SECTOR_SIZE];
@@ -466,7 +466,7 @@ void unpack_psp_eboot(const char* path, const aes128_key* pkg_key, const uint8_t
out_size = lzrc_decompress(uncompressed, sizeof(uncompressed), data, block_size);
if (out_size != iso_block * ISO_SECTOR_SIZE)
{
fatal("ERROR: internal error - lzrc decompression failed! pkg may be corrupted?\n");
sys_error("ERROR: internal error - lzrc decompression failed! pkg may be corrupted?\n");
}
if (cso)
{
@@ -541,7 +541,7 @@ void unpack_psp_key(const char* path, const aes128_key* pkg_key, const uint8_t*
{
if (item_size < 0x90 + 0xa0)
{
fatal("ERROR: PSP-KEY.EDAT file is to short!\n");
sys_error("ERROR: PSP-KEY.EDAT file is to short!\n");
}
uint8_t key_header[0xa0];
@@ -550,14 +550,14 @@ void unpack_psp_key(const char* path, const aes128_key* pkg_key, const uint8_t*
if (memcmp(key_header, "\x00PGD", 4) != 0)
{
fatal("ERROR: wrong PSP-KEY.EDAT header signature!\n");
sys_error("ERROR: wrong PSP-KEY.EDAT header signature!\n");
}
uint32_t key_index = get32le(key_header + 4);
uint32_t drm_type = get32le(key_header + 8);
if (key_index != 1 || drm_type != 1)
{
fatal("ERROR: unsupported PSP-KEY.EDAT file, key/drm type is wrong!\n");
sys_error("ERROR: unsupported PSP-KEY.EDAT file, key/drm type is wrong!\n");
}
uint8_t mac[16];
@@ -573,7 +573,7 @@ void unpack_psp_key(const char* path, const aes128_key* pkg_key, const uint8_t*
if (data_size != 0x10 || data_offset != 0x90)
{
fatal("ERROR: unsupported PSP-KEY.EDAT file, data/offset is wrong!\n");
sys_error("ERROR: unsupported PSP-KEY.EDAT file, data/offset is wrong!\n");
}
init_psp_decrypt(&psp_key, psp_iv, 0, mac, key_header, 0x70, 0x30);
+96 -16
View File
@@ -11,6 +11,64 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
static HANDLE gStdout;
static int gStdoutRedirected;
void sys_output_init(void)
{
SetConsoleOutputCP(CP_UTF8);
gStdout = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD mode;
gStdoutRedirected = !GetConsoleMode(gStdout, &mode);
}
void sys_output(const char* msg, ...)
{
char buffer[1024];
va_list arg;
va_start(arg, msg);
vsnprintf(buffer, sizeof(buffer), msg, arg);
va_end(arg);
if (!gStdoutRedirected)
{
WCHAR wbuffer[sizeof(buffer)];
int wcount = MultiByteToWideChar(CP_UTF8, 0, buffer, -1, wbuffer, sizeof(buffer));
DWORD written;
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wbuffer, wcount, &written, NULL);
return;
}
fputs(buffer, stdout);
}
void sys_error(const char* msg, ...)
{
char buffer[1024];
va_list arg;
va_start(arg, msg);
vsnprintf(buffer, sizeof(buffer), msg, arg);
va_end(arg);
DWORD mode;
if (GetConsoleMode(GetStdHandle(STD_ERROR_HANDLE), &mode))
{
WCHAR wbuffer[sizeof(buffer)];
int wcount = MultiByteToWideChar(CP_UTF8, 0, buffer, -1, wbuffer, sizeof(buffer));
DWORD written;
WriteConsoleW(GetStdHandle(STD_ERROR_HANDLE), wbuffer, wcount, &written, NULL);
exit(EXIT_FAILURE);
}
fputs(buffer, stderr);
exit(EXIT_FAILURE);
}
static void sys_mkdir_real(const char* path)
{
WCHAR wpath[MAX_PATH];
@@ -20,7 +78,7 @@ static void sys_mkdir_real(const char* path)
{
if (GetLastError() != ERROR_ALREADY_EXISTS)
{
fatal("ERROR: cannot create '%s' folder\n", path);
sys_error("ERROR: cannot create '%s' folder\n", path);
}
}
}
@@ -33,13 +91,13 @@ sys_file sys_open(const char* fname, uint64_t* size)
HANDLE handle = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (handle == INVALID_HANDLE_VALUE)
{
fatal("ERROR: cannot open '%s' file\n", fname);
sys_error("ERROR: cannot open '%s' file\n", fname);
}
LARGE_INTEGER sz;
if (!GetFileSizeEx(handle, &sz))
{
fatal("ERROR: cannot get size of '%s' file\n", fname);
sys_error("ERROR: cannot get size of '%s' file\n", fname);
}
*size = sz.QuadPart;
@@ -54,7 +112,7 @@ sys_file sys_create(const char* fname)
HANDLE handle = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if (handle == INVALID_HANDLE_VALUE)
{
fatal("ERROR: cannot create '%s' file\n", fname);
sys_error("ERROR: cannot create '%s' file\n", fname);
}
return handle;
@@ -64,7 +122,7 @@ void sys_close(sys_file file)
{
if (!CloseHandle(file))
{
fatal("ERROR: failed to close file\n");
sys_error("ERROR: failed to close file\n");
}
}
@@ -77,7 +135,7 @@ void sys_read(sys_file file, uint64_t offset, void* buffer, uint32_t size)
ov.OffsetHigh = (uint32_t)(offset >> 32);
if (!ReadFile(file, buffer, size, &read, &ov) || read != size)
{
fatal("ERROR: failed to read %u bytes from file\n", size);
sys_error("ERROR: failed to read %u bytes from file\n", size);
}
}
@@ -90,7 +148,7 @@ void sys_write(sys_file file, uint64_t offset, const void* buffer, uint32_t size
ov.OffsetHigh = (uint32_t)(offset >> 32);
if (!WriteFile(file, buffer, size, &written, &ov) || written != size)
{
fatal("ERROR: failed to write %u bytes to file\n", size);
sys_error("ERROR: failed to write %u bytes to file\n", size);
}
}
@@ -103,13 +161,35 @@ void sys_write(sys_file file, uint64_t offset, const void* buffer, uint32_t size
#include <unistd.h>
#include <sys/stat.h>
void sys_output_init(void)
{
}
void sys_output(const char* msg, ...)
{
va_list arg;
va_start(arg, msg);
vfprintf(stdout, msg, arg);
va_end(arg);
}
void sys_error(const char* msg, ...)
{
va_list arg;
va_start(arg, msg);
vfprintf(stderr, msg, arg);
va_end(arg);
exit(EXIT_FAILURE);
}
static void sys_mkdir_real(const char* path)
{
if (mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0)
{
if (errno != EEXIST)
{
fatal("ERROR: cannot create '%s' folder\n", path);
sys_error("ERROR: cannot create '%s' folder\n", path);
}
}
}
@@ -119,13 +199,13 @@ sys_file sys_open(const char* fname, uint64_t* size)
int fd = open(fname, O_RDONLY);
if (fd < 0)
{
fatal("ERROR: cannot open '%s' file\n", fname);
error("ERROR: cannot open '%s' file\n", fname);
}
struct stat st;
if (fstat(fd, &st) != 0)
{
fatal("ERROR: cannot get size of '%s' file\n", fname);
sys_error("ERROR: cannot get size of '%s' file\n", fname);
}
*size = st.st_size;
@@ -137,7 +217,7 @@ sys_file sys_create(const char* fname)
int fd = open(fname, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd < 0)
{
fatal("ERROR: cannot create '%s' file\n", fname);
sys_error("ERROR: cannot create '%s' file\n", fname);
}
return (void*)(intptr_t)fd;
@@ -147,7 +227,7 @@ void sys_close(sys_file file)
{
if (close((int)(intptr_t)file) != 0)
{
fatal("ERROR: failed to close file\n");
sys_error("ERROR: failed to close file\n");
}
}
@@ -156,7 +236,7 @@ void sys_read(sys_file file, uint64_t offset, void* buffer, uint32_t size)
ssize_t read = pread((int)(intptr_t)file, buffer, size, offset);
if (read < 0 || read != (ssize_t)size)
{
fatal("ERROR: failed to read %u bytes from file\n", size);
sys_error("ERROR: failed to read %u bytes from file\n", size);
}
}
@@ -165,7 +245,7 @@ void sys_write(sys_file file, uint64_t offset, const void* buffer, uint32_t size
ssize_t wrote = pwrite((int)(intptr_t)file, buffer, size, offset);
if (wrote < 0 || wrote != (ssize_t)size)
{
fatal("ERROR: failed to read %u bytes from file\n", size);
sys_error("ERROR: failed to read %u bytes from file\n", size);
}
}
@@ -201,12 +281,12 @@ void* sys_realloc(void* ptr, size_t size)
}
else
{
fatal("ERROR: internal error, wrong sys_realloc usage\n");
sys_error("ERROR: internal error, wrong sys_realloc usage\n");
}
if (!result)
{
fatal("ERROR: out of memory\n");
sys_error("ERROR: out of memory\n");
}
return result;
+6 -2
View File
@@ -1,7 +1,11 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
#include "pkg2zip_utils.h"
// correctly outputs utf8 string
void sys_output_init(void);
void sys_output(const char* msg, ...);
void NORETURN sys_error(const char* msg, ...);
typedef void* sys_file;
-15
View File
@@ -1,15 +0,0 @@
#include "pkg2zip_utils.h"
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
void fatal(const char* msg, ...)
{
va_list args;
va_start(args, msg);
vfprintf(stderr, msg, args);
va_end(args);
exit(EXIT_FAILURE);
}
-2
View File
@@ -11,8 +11,6 @@
# define PKG_ALIGN(x) __attribute__((aligned(x)))
#endif
void NORETURN fatal(const char* msg, ...);
static inline uint32_t min32(uint32_t a, uint32_t b)
{
return a < b ? a : b;
+4 -3
View File
@@ -4,6 +4,7 @@
#endif
#include "pkg2zip_zip.h"
#include "pkg2zip_out.h"
#include "pkg2zip_crc32.h"
#include "pkg2zip_utils.h"
@@ -73,7 +74,7 @@ void zip_add_folder(zip* z, const char* name)
size_t name_length = strlen(name) + 1;
if (name_length > ZIP_MAX_FILENAME)
{
fatal("ERROR: dirname too long\n");
sys_error("ERROR: dirname too long\n");
}
zip_file* f = zip_new_file(z);
@@ -113,7 +114,7 @@ uint64_t zip_begin_file(zip* z, const char* name, int compress)
size_t name_length = strlen(name);
if (name_length > ZIP_MAX_FILENAME)
{
fatal("ERROR: filename too long\n");
sys_error("ERROR: filename too long\n");
}
zip_file* f = zip_new_file(z);
@@ -411,7 +412,7 @@ void zip_write_file_at(zip* z, uint64_t offset, const void* data, uint32_t size)
{
if (z->current->compress)
{
fatal("ERROR: cannot write at specific offset for compressed files\n");
sys_error("ERROR: cannot write at specific offset for compressed files\n");
}
sys_write(z->file, z->current->offset + offset, data, size);
+8 -7
View File
@@ -1,5 +1,6 @@
#include "pkg2zip_zrif.h"
#include "pkg2zip_utils.h"
#include "pkg2zip_sys.h"
#include "miniz_tdef.h"
#include "puff.h"
@@ -106,17 +107,17 @@ static uint32_t zlib_inflate(const uint8_t* in, uint32_t inlen, uint8_t* out, ui
{
if (inlen < 2 + 4)
{
fatal("ERROR: zRIF length too short\n");
sys_error("ERROR: zRIF length too short\n");
}
if (((in[0] << 8) + in[1]) % 31 != 0)
{
fatal("ERROR: zRIF header is corrupted\n");
sys_error("ERROR: zRIF header is corrupted\n");
}
if ((in[0] & 0xf) != ZLIB_DEFLATE_METHOD)
{
fatal("ERROR: only deflate method supported in zRIF\n");
sys_error("ERROR: only deflate method supported in zRIF\n");
}
unsigned long slen = inlen - 4;
@@ -132,7 +133,7 @@ static uint32_t zlib_inflate(const uint8_t* in, uint32_t inlen, uint8_t* out, ui
if (get32be(in + 2) != ZLIB_DICTIONARY_ID_ZRIF)
{
fatal("ERROR: zRIF uses unknown dictionary\n");
sys_error("ERROR: zRIF uses unknown dictionary\n");
}
in += 6;
@@ -146,13 +147,13 @@ static uint32_t zlib_inflate(const uint8_t* in, uint32_t inlen, uint8_t* out, ui
if (puff(dictlen, out, &dlen, in, &slen) != 0)
{
fatal("ERROR: failed to uncompress zRIF\n");
sys_error("ERROR: failed to uncompress zRIF\n");
}
memmove(out, out + dictlen, dlen);
if (mz_adler32(MZ_ADLER32_INIT, out, dlen) != get32be(in + slen))
{
fatal("ERROR: zRIF is corrupted, wrong checksum\n");
sys_error("ERROR: zRIF is corrupted, wrong checksum\n");
}
return dlen;
@@ -167,7 +168,7 @@ void zrif_decode(const char* str, uint8_t* rif, uint32_t rif_size)
len = zlib_inflate(raw, len, out, sizeof(out));
if (len != rif_size)
{
fatal("ERROR: wrong size of zRIF, is it corrupted?\n");
sys_error("ERROR: wrong size of zRIF, is it corrupted?\n");
}
memcpy(rif, out, rif_size);