From e8c5bc119e1dcf68de811fd4c4e52a9e1d0c9bae Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 18 Oct 2016 01:06:31 -0400 Subject: [PATCH] Implemented support for "iterated" data pages. Fixes initial load of jv12mi36.dll (Java 1.3 that ships with OS/2 Warp 4.52). --- lx_loader.c | 48 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/lx_loader.c b/lx_loader.c index d414535..51832e5 100644 --- a/lx_loader.c +++ b/lx_loader.c @@ -304,10 +304,43 @@ static int decompressExePack2(uint8 *dst, const uint32 dstlen, const uint8 *src, #undef DSTAVAIL // pad out the rest of the page with zeroes. - memset(dst + dOf, '\0', dstlen - dOf); + if ((dstlen - dOf) > 0) + memset(dst + dOf, '\0', dstlen - dOf); + return 1; } // decompressExePack2 +static int decompressIterated(uint8 *dst, uint32 dstlen, const uint8 *src, uint32 srclen) +{ + while (srclen) { + if (srclen < 4) + return 0; + const uint16 iterations = *((uint16 *) src); src += 2; + const uint16 len = *((uint16 *) src); src += 2; + srclen -= 4; + if (dstlen < (iterations * len)) + return 0; + else if (srclen < len) + return 0; + + for (uint16 i = 0; i < iterations; i++) { + memcpy(dst, src, len); + dst += len; + dstlen -= len; + } // for + + src += len; + srclen -= len; + } // while + + // pad out the rest of the page with zeroes. + if (dstlen > 0) + memset(dst, '\0', dstlen); + + return 1; +} // decompressIterated + + static void missingEntryPointCalled(const char *module, const char *entry) { void ***ebp = NULL; @@ -987,10 +1020,15 @@ static LxModule *loadLxModule(const char *fname, uint8 *exe, uint32 exelen, int } break; - //case 0x01: // FIXME: write me ... iterated, this is exepack1, I think. - // src = origexe + lx->object_iter_pages_offset + (objpage->page_data_offset << lx->page_offset_shift); - // memcpy(dst, src, objpage->data_size); - // break; + case 0x01: // iterated data. + // LX format docs say object_iter_pages_offset must be zero or equal to data_pages_offset for OS/2 2.0. So just use data_pages_offset here. + //src = origexe + lx->object_iter_pages_offset + (objpage->page_data_offset << lx->page_offset_shift); + src = origexe + lx->data_pages_offset + (objpage->page_data_offset << lx->page_offset_shift); + if (!decompressIterated(dst, lx->page_size, src, objpage->data_size)) { + fprintf(stderr, "Failed to decompress iterated object page (corrupt file or bug).\n"); + goto loadlx_failed; + } // if + break; case 0x02: // INVALID, just zero it out. case 0x03: // ZEROFILL, just zero it out.