diff options
author | Takamichi Horikawa <myon@myon98.net> | 2021-12-05 13:20:53 +0900 |
---|---|---|
committer | Takamichi Horikawa <myon@myon98.net> | 2021-12-05 13:24:22 +0900 |
commit | b43099221e2af2dfca8100b3fdf59d89c122f9d9 (patch) | |
tree | 66c8bc20d57663a9915fd1afaa3224369bfb353b /main.c |
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 91 |
1 files changed, 91 insertions, 0 deletions
@@ -0,0 +1,91 @@ +#include <windows.h> +#include <stdio.h> + +BOOL WINAPI VirtualCopy(LPVOID lpvDest, LPVOID lpvSrc, DWORD cbSize, DWORD fdwProtect); + +enum { + PAGESIZE = 0x10000, +}; + +static BOOL writefile(const void *p, unsigned size, const wchar_t *fname) +{ + FILE *f = 0; + const char *pb = p; + BOOL ret = FALSE; + + f = _wfopen(fname, L"wb"); + if (!f) { + wprintf(L"\nError: fopen failed! Aborting.\n"); + goto cleanup; + } + while (size) { + const unsigned wsize = (size < PAGESIZE) ? size : PAGESIZE; + if (fwrite(pb, 1, wsize, f) != wsize) { + wprintf(L"\nError: fwrite failed! Aborting.\n"); + goto cleanup; + } + wprintf(L"."); + fflush(stdout); + pb += wsize; + size -= wsize; + } + ret = TRUE; +cleanup: + if (f) fclose(f); + return ret; +} + + +struct data { + unsigned addr; + unsigned size; + const wchar_t *name; +}; + +const struct data roms[] = { + {0x00000000, 0x02000000, L"rom.dat"}, // 0x0000_0000 - 0x01ff_ffff + {0x0c000000, 0x00400000, L"flash.dat"}, // 0x0c00_0000 - 0x0c3f_ffff + {0, 0, 0}, +}; + +int wmain(int argc, wchar_t **argv) +{ + wchar_t fname[MAX_PATH]; + wchar_t *pathend; + const struct data *i; + + if (!GetModuleFileName(0, fname, MAX_PATH)) { + wprintf(L"Error: Cannot get executable file path! Aborting.\n"); + goto end; + } + pathend = wcsrchr(fname, L'\\'); + if (!pathend) { + wprintf(L"Error: Cannot get directory to write rom files! Aborting\n"); + goto end; + } + for (i = roms; i->name; i++) { + void *p; + + /* too lazy to check string length */ + pathend[1] = 0; + wcscat(fname, i->name); + wprintf(L"Dumping %ls", fname); + fflush(stdout); + p = VirtualAlloc(0, i->size, MEM_RESERVE, PAGE_NOACCESS); + if (!p) { + wprintf(L"\nError: VirtualAlloc failed! Aborting.\n"); + goto end; + } + if (!VirtualCopy(p, (void *)(i->addr >> 8), i->size, PAGE_READONLY | PAGE_PHYSICAL)) { + wprintf(L"\nError: VirtualCopy failed! Aborting.\n"); + goto end; + } + if (!writefile(p, i->size, fname)) return 1; + wprintf(L"OK!\n"); + } +end: + wprintf(L"Press enter to continue...\n"); + getwchar(); + return 0; +} + |