@shockpkg/dir-projector
Version:
Package for creating Shockwave Director projectors
1 lines • 9.83 kB
Source Map (JSON)
{"version":3,"sources":["patcher.ts"],"names":["fse","patchHexToBytes","str","replace","match","map","s","length","Error","test","parseInt","patchWindowsS3dInstalledDisplayDriversSizePatches","find","join","patchDataOnce","data","candidates","name","foundOffset","foundPatch","patch","end","i","found","j","b","patchFileOnce","file","readFile","writeFile","patchWindowsS3dInstalledDisplayDriversSize"],"mappings":"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","sourcesContent":["import fse from 'fs-extra';\n\ninterface IPatcherPatch {\n\n\t/**\n\t * The bytes to find.\n\t */\n\tfind: (number | null)[];\n\n\t/**\n\t * The bytes replaced with.\n\t */\n\treplace: (number | null)[];\n}\n\n/**\n * Converts a hex string into a series of byte values, with unknowns being null.\n *\n * @param str Hex string.\n * @returns Bytes and null values.\n */\nfunction patchHexToBytes(str: string) {\n\treturn (str.replace(/[\\s\\r\\n]/g, '').match(/.{1,2}/g) || []).map(s => {\n\t\tif (s.length !== 2) {\n\t\t\tthrow new Error('Internal error');\n\t\t}\n\t\treturn /[0-9A-F]{2}/i.test(s) ? parseInt(s, 16) : null;\n\t});\n}\n\n/* eslint-disable no-multi-spaces */\n/* eslint-disable line-comment-position */\n/* eslint-disable no-inline-comments */\n// A list of patch candidates, made to be partially position independant.\n// Basically these patches just increase the temporary buffer sizes.\n// Enough to provide amply room for anything that should be in the registry.\n// Sizes 0x10000 for ASCII, and 0x20000 for WCHAR.\n// Not enough room to calculate the correct size, and use it directly.\nconst patchWindowsS3dInstalledDisplayDriversSizePatches: IPatcherPatch[] = [\n\t// director-8.5.0 - director-11.0.0-hotfix-1:\n\t{\n\t\tfind: patchHexToBytes([\n\t\t\t'FF 15 -- -- -- --', // call DWORD PTR ds:-- -- -- --\n\t\t\t'BE 04 01 00 00', // mov esi, 0x104\n\t\t\t'56', // push esi\n\t\t\t'E8 -- -- -- --' // call -- -- -- --\n\t\t].join(' ')),\n\t\treplace: patchHexToBytes([\n\t\t\t'FF 15 -- -- -- --', // call DWORD PTR ds:-- -- -- --\n\t\t\t// Change:\n\t\t\t'BE 00 00 01 00', // mov esi, 0x10000\n\t\t\t'56', // push esi\n\t\t\t'E8 -- -- -- --' // call -- -- -- --\n\t\t].join(' '))\n\t},\n\t// director-11.0.0-hotfix-3 - director-11.5.0:\n\t{\n\t\tfind: patchHexToBytes([\n\t\t\t'FF 15 -- -- -- --', // call DWORD PTR ds:-- -- -- --\n\t\t\t'BF 04 01 00 00', // mov edi, 0x104\n\t\t\t'57', // push edi\n\t\t\t'E8 -- -- -- --' // call -- -- -- --\n\t\t].join(' ')),\n\t\treplace: patchHexToBytes([\n\t\t\t'FF 15 -- -- -- --', // call DWORD PTR ds:-- -- -- --\n\t\t\t// Change:\n\t\t\t'BF 00 00 01 00', // mov edi, 0x10000\n\t\t\t'57', // push edi\n\t\t\t'E8 -- -- -- --' // call -- -- -- --\n\t\t].join(' '))\n\t},\n\t// director-11.5.8 - director-11.5.9:\n\t{\n\t\tfind: patchHexToBytes([\n\t\t\t'68 -- -- -- --', // push -- -- -- --\n\t\t\t'57', // push edi\n\t\t\t'FF D6', // call esi\n\t\t\t'68 08 02 00 00', // push 0x208\n\t\t\t'E8 -- -- -- --' // call -- -- -- --\n\t\t].join(' ')),\n\t\treplace: patchHexToBytes([\n\t\t\t'68 -- -- -- --', // push -- -- -- --\n\t\t\t'57', // push edi\n\t\t\t'FF D6', // call esi\n\t\t\t// Change:\n\t\t\t'68 00 00 02 00', // push 0x20000\n\t\t\t'E8 -- -- -- --' // call -- -- -- --\n\t\t].join(' '))\n\t},\n\t// director-12.0.0:\n\t{\n\t\tfind: patchHexToBytes([\n\t\t\t'68 -- -- -- --', // push -- -- -- --\n\t\t\t'53', // push ebx\n\t\t\t'FF D7', // call edi\n\t\t\t'68 08 02 00 00', // push 0x208\n\t\t\t'E8 -- -- -- --' // call -- -- -- --\n\t\t].join(' ')),\n\t\treplace: patchHexToBytes([\n\t\t\t'68 -- -- -- --', // push -- -- -- --\n\t\t\t'53', // push ebx\n\t\t\t'FF D7', // call edi\n\t\t\t// Change:\n\t\t\t'68 00 00 02 00', // push 0x20000\n\t\t\t'E8 -- -- -- --' // call -- -- -- --\n\t\t].join(' '))\n\t}\n];\n/* eslint-enable no-multi-spaces */\n/* eslint-enable line-comment-position */\n/* eslint-enable no-inline-comments */\n\n/**\n * Patch data buffer once.\n *\n * @param data Data buffer.\n * @param candidates Patch candidates.\n * @param name Patch name.\n */\nfunction patchDataOnce(\n\tdata: Buffer,\n\tcandidates: IPatcherPatch[],\n\tname: string\n) {\n\t// Search the buffer for patch candidates.\n\tlet foundOffset = -1;\n\tlet foundPatch: (number | null)[] = [];\n\tfor (const patch of candidates) {\n\t\tconst {find, replace} = patch;\n\t\tif (replace.length !== find.length) {\n\t\t\tthrow new Error('Internal error');\n\t\t}\n\n\t\tconst end = data.length - find.length;\n\t\tfor (let i = 0; i < end; i++) {\n\t\t\tlet found = true;\n\t\t\tfor (let j = 0; j < find.length; j++) {\n\t\t\t\tconst b = find[j];\n\t\t\t\tif (b !== null && data[i + j] !== b) {\n\t\t\t\t\tfound = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!found) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (foundOffset !== -1) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Multiple patch candidates found for: ${name}`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Remember patch to apply.\n\t\t\tfoundOffset = i;\n\t\t\tfoundPatch = replace;\n\t\t}\n\t}\n\tif (foundOffset === -1) {\n\t\tthrow new Error(`No patch candidates found for: ${name}`);\n\t}\n\n\t// Apply the patch to the buffer, and write to file.\n\tfor (let i = 0; i < foundPatch.length; i++) {\n\t\tconst b = foundPatch[i];\n\t\tif (b !== null) {\n\t\t\tdata[foundOffset + i] = b;\n\t\t}\n\t}\n}\n\n/**\n * Patch a file once.\n *\n * @param file File path.\n * @param candidates Patch candidates.\n * @param name Patch name.\n */\nasync function patchFileOnce(\n\tfile: string,\n\tcandidates: IPatcherPatch[],\n\tname: string\n) {\n\tconst data = await fse.readFile(file);\n\tpatchDataOnce(data, candidates, name);\n\tawait fse.writeFile(file, data);\n}\n\n/**\n * Patch Windows Shockwave 3D InstalledDisplayDrivers size.\n *\n * @param file File path.\n */\nexport async function patchWindowsS3dInstalledDisplayDriversSize(\n\tfile: string\n) {\n\tawait patchFileOnce(\n\t\tfile,\n\t\tpatchWindowsS3dInstalledDisplayDriversSizePatches,\n\t\t'Windows Shockwave 3D InstalledDisplayDrivers Size'\n\t);\n}\n"],"file":"patcher.mjs","sourceRoot":"../src"}