diff --git a/GNUmakefile b/GNUmakefile index be0bd9ba..c7ffdde3 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -25,7 +25,7 @@ toolchain_64 := x86_64-w64-mingw32- gitrev := $(shell git rev-parse HEAD) cppflags := -I src -I src/main -I src/test -DGITREV=$(gitrev) -cflags := -O2 -pipe -ffunction-sections -fdata-sections \ +cflags := -g -O2 -pipe -ffunction-sections -fdata-sections \ -Wall -std=c99 -DPSAPI_VERSION=1 cflags_release := -Werror ldflags := -Wl,--gc-sections -static-libgcc @@ -240,7 +240,6 @@ $$(dll_$1_$2_$3) $$(implib_$1_$2_$3): $$(obj_$1_$2_$3) $$(abslib_$1_$2_$3) \ $(V)$$(toolchain_$1)gcc -shared \ -o $$(dll_$1_$2_$3) -Wl,--out-implib,$$(implib_$1_$2_$3) \ -Wl,--start-group $$^ -Wl,--end-group $$(ldflags_$3) - $(V)$$(toolchain_$1)strip $$(dll_$1_$2_$3) $(V)$$(toolchain_$1)ranlib $$(implib_$1_$2_$3) endef @@ -257,7 +256,6 @@ $$(exe_$1_$2_$3): $$(obj_$1_$2_$3) $$(abslib_$1_$2_$3) $$(absdpl_$1_$2_$3) \ | $$(bindir_$1_$2) $(V)echo ... $$@ $(V)$$(toolchain_$1)gcc -o $$@ $$^ $$(ldflags_$3) - $(V)$$(toolchain_$1)strip $$@ endef diff --git a/Module.mk b/Module.mk index 4178a424..803bca7a 100644 --- a/Module.mk +++ b/Module.mk @@ -80,7 +80,7 @@ cflags += \ # Each AVS-dependent project should consume the earliest AVS import definition # that is still ABI-compatible with the real build its target links against. -avsvers_32 := 1700 1603 1601 1508 1403 1304 1101 1002 803 0 +avsvers_32 := 1700 1603 1601 1508 1403 1306 1304 1101 1002 803 0 avsvers_64 := 1700 1603 1601 1509 1508 imps += avs avs-ea3 @@ -91,6 +91,7 @@ include src/main/acioemu/Module.mk include src/main/aciomgr/Module.mk include src/main/aciotest/Module.mk include src/main/asio/Module.mk +include src/main/avs-util/Module.mk include src/main/bio2drv/Module.mk include src/main/bio2emu-iidx/Module.mk include src/main/bio2emu/Module.mk @@ -257,6 +258,7 @@ $(zipdir)/iidx-09-to-12.zip: \ build/bin/indep-32/iidxio.dll \ build/bin/indep-32/vefxio.dll \ build/bin/indep-32/inject.exe \ + dist/dwarfstack/32/dwarfstack.dll \ dist/iidx/config.bat \ dist/iidx/gamestart-09.bat \ dist/iidx/gamestart-10.bat \ @@ -282,6 +284,7 @@ $(zipdir)/iidx-13.zip: \ build/bin/indep-32/iidxio.dll \ build/bin/indep-32/vefxio.dll \ build/bin/indep-32/inject.exe \ + dist/dwarfstack/32/dwarfstack.dll \ dist/iidx/config.bat \ dist/iidx/gamestart-13.bat \ dist/iidx/iidxhook-13.conf \ @@ -298,6 +301,7 @@ $(zipdir)/iidx-14-to-17.zip: \ build/bin/indep-32/iidxio.dll \ build/bin/indep-32/vefxio.dll \ build/bin/indep-32/inject.exe \ + dist/dwarfstack/32/dwarfstack.dll \ dist/iidx/config.bat \ dist/iidx/gamestart-14.bat \ dist/iidx/gamestart-15.bat \ @@ -323,6 +327,10 @@ $(zipdir)/iidx-18.zip: \ dist/iidx/config.bat \ dist/iidx/gamestart-18.bat \ dist/iidx/iidxhook-18.conf \ + dist/iidx/launcher-18.xml \ + dist/shared/ea3-ident.xml \ + dist/shared/ea3-license.xml \ + dist/shared/ea3-service.xml \ dist/iidx/vefx.txt \ | $(zipdir)/ $(V)echo ... $@ @@ -335,6 +343,7 @@ $(zipdir)/iidx-18-cn.zip: \ build/bin/indep-32/iidxio.dll \ build/bin/indep-32/vefxio.dll \ build/bin/indep-32/inject.exe \ + dist/dwarfstack/32/dwarfstack.dll \ dist/iidx/config.bat \ dist/iidx/gamestart-18-cn.bat \ dist/iidx/iidxhook-18-cn.conf \ @@ -351,9 +360,14 @@ $(zipdir)/iidx-19.zip: \ build/bin/indep-32/geninput.dll \ build/bin/indep-32/iidxio.dll \ build/bin/indep-32/vefxio.dll \ + dist/dwarfstack/32/dwarfstack.dll \ dist/iidx/config.bat \ dist/iidx/gamestart-19.bat \ dist/iidx/iidxhook-19.conf \ + dist/iidx/launcher-19.xml \ + dist/shared/ea3-ident.xml \ + dist/shared/ea3-license.xml \ + dist/shared/ea3-service.xml \ dist/iidx/vefx.txt \ | $(zipdir)/ $(V)echo ... $@ @@ -367,9 +381,14 @@ $(zipdir)/iidx-20.zip: \ build/bin/indep-32/geninput.dll \ build/bin/indep-32/iidxio.dll \ build/bin/indep-32/vefxio.dll \ + dist/dwarfstack/32/dwarfstack.dll \ dist/iidx/config.bat \ dist/iidx/gamestart-20.bat \ dist/iidx/iidxhook-20.conf \ + dist/iidx/launcher-20.xml \ + dist/shared/ea3-ident.xml \ + dist/shared/ea3-license.xml \ + dist/shared/ea3-service.xml \ dist/iidx/vefx.txt \ | $(zipdir)/ $(V)echo ... $@ @@ -382,6 +401,7 @@ $(zipdir)/iidx-20-cn.zip: \ build/bin/indep-32/iidxio.dll \ build/bin/indep-32/vefxio.dll \ build/bin/indep-32/inject.exe \ + dist/dwarfstack/32/dwarfstack.dll \ dist/iidx/config.bat \ dist/iidx/gamestart-20-cn.bat \ dist/iidx/iidxhook-20-cn.conf \ @@ -398,6 +418,7 @@ $(zipdir)/iidx-21-to-24.zip: \ build/bin/indep-32/geninput.dll \ build/bin/indep-32/iidxio.dll \ build/bin/indep-32/vefxio.dll \ + dist/dwarfstack/32/dwarfstack.dll \ dist/iidx/config.bat \ dist/iidx/gamestart-21.bat \ dist/iidx/gamestart-22.bat \ @@ -407,6 +428,13 @@ $(zipdir)/iidx-21-to-24.zip: \ dist/iidx/iidxhook-22.conf \ dist/iidx/iidxhook-23.conf \ dist/iidx/iidxhook-24.conf \ + dist/iidx/launcher-21.xml \ + dist/iidx/launcher-22.xml \ + dist/iidx/launcher-23.xml \ + dist/iidx/launcher-24.xml \ + dist/shared/ea3-ident.xml \ + dist/shared/ea3-license.xml \ + dist/shared/ea3-service.xml \ dist/iidx/vefx.txt \ | $(zipdir)/ $(V)echo ... $@ @@ -420,11 +448,17 @@ $(zipdir)/iidx-25-to-26.zip: \ build/bin/indep-64/geninput.dll \ build/bin/indep-64/iidxio.dll \ build/bin/indep-64/vefxio.dll \ + dist/dwarfstack/64/dwarfstack.dll \ dist/iidx/config.bat \ dist/iidx/gamestart-25.bat \ dist/iidx/gamestart-26.bat \ dist/iidx/iidxhook-25.conf \ dist/iidx/iidxhook-26.conf \ + dist/iidx/launcher-25.xml \ + dist/iidx/launcher-26.xml \ + dist/shared/ea3-ident.xml \ + dist/shared/ea3-license.xml \ + dist/shared/ea3-service.xml \ dist/iidx/vefx.txt \ | $(zipdir)/ $(V)echo ... $@ @@ -438,6 +472,7 @@ $(zipdir)/iidx-27-to-30.zip: \ build/bin/indep-64/geninput.dll \ build/bin/indep-64/iidxio.dll \ build/bin/indep-64/vefxio.dll \ + dist/dwarfstack/64/dwarfstack.dll \ dist/iidx/config.bat \ dist/iidx/gamestart-27.bat \ dist/iidx/gamestart-28.bat \ @@ -447,6 +482,13 @@ $(zipdir)/iidx-27-to-30.zip: \ dist/iidx/iidxhook-28.conf \ dist/iidx/iidxhook-29.conf \ dist/iidx/iidxhook-30.conf \ + dist/iidx/launcher-27.xml \ + dist/iidx/launcher-28.xml \ + dist/iidx/launcher-29.xml \ + dist/iidx/launcher-30.xml \ + dist/shared/ea3-ident.xml \ + dist/shared/ea3-license.xml \ + dist/shared/ea3-service.xml \ dist/iidx/vefx.txt \ | $(zipdir)/ $(V)echo ... $@ @@ -485,6 +527,7 @@ $(zipdir)/jb-01.zip: \ build/bin/indep-32/eamio.dll \ build/bin/indep-32/geninput.dll \ build/bin/indep-32/jbio.dll \ + dist/dwarfstack/32/dwarfstack.dll \ dist/jb/config.bat \ dist/jb/gamestart-01.bat \ dist/jb/jbhook-01.conf \ @@ -499,6 +542,7 @@ $(zipdir)/jb-02.zip: \ build/bin/indep-32/eamio.dll \ build/bin/indep-32/geninput.dll \ build/bin/indep-32/jbio.dll \ + dist/dwarfstack/32/dwarfstack.dll \ dist/jb/config.bat \ dist/jb/gamestart-02.bat \ dist/jb/jbhook-02.conf \ @@ -513,8 +557,13 @@ $(zipdir)/jb-03.zip: \ build/bin/indep-32/eamio.dll \ build/bin/indep-32/geninput.dll \ build/bin/indep-32/jbio.dll \ + dist/dwarfstack/32/dwarfstack.dll \ dist/jb/config.bat \ dist/jb/gamestart-03.bat \ + dist/jb/launcher-03.xml \ + dist/shared/ea3-ident.xml \ + dist/shared/ea3-license.xml \ + dist/shared/ea3-service.xml \ | $(zipdir)/ $(V)echo ... $@ $(V)zip -j $@ $^ @@ -526,8 +575,13 @@ $(zipdir)/jb-04.zip: \ build/bin/indep-32/eamio.dll \ build/bin/indep-32/geninput.dll \ build/bin/indep-32/jbio.dll \ + dist/dwarfstack/32/dwarfstack.dll \ dist/jb/config.bat \ dist/jb/gamestart-03.bat \ + dist/jb/launcher-03.xml \ + dist/shared/ea3-ident.xml \ + dist/shared/ea3-license.xml \ + dist/shared/ea3-service.xml \ | $(zipdir)/ $(V)echo ... $@ $(V)zip -j $@ $^ @@ -539,8 +593,13 @@ $(zipdir)/jb-05-to-07.zip: \ build/bin/indep-32/eamio.dll \ build/bin/indep-32/geninput.dll \ build/bin/indep-32/jbio.dll \ + dist/dwarfstack/32/dwarfstack.dll \ dist/jb/config.bat \ dist/jb/gamestart-04.bat \ + dist/jb/launcher-04.xml \ + dist/shared/ea3-ident.xml \ + dist/shared/ea3-license.xml \ + dist/shared/ea3-service.xml \ | $(zipdir)/ $(V)echo ... $@ $(V)zip -j $@ $^ @@ -552,8 +611,13 @@ $(zipdir)/jb-08.zip: \ build/bin/indep-32/eamio.dll \ build/bin/indep-32/geninput.dll \ build/bin/indep-32/jbio.dll \ + dist/dwarfstack/32/dwarfstack.dll \ dist/jb/config.bat \ dist/jb/gamestart-04.bat \ + dist/jb/launcher-04.xml \ + dist/shared/ea3-ident.xml \ + dist/shared/ea3-license.xml \ + dist/shared/ea3-service.xml \ | $(zipdir)/ $(V)echo ... $@ $(V)zip -j $@ $^ @@ -576,8 +640,13 @@ $(zipdir)/sdvx-01-to-04.zip: \ build/bin/indep-32/eamio.dll \ build/bin/indep-32/geninput.dll \ build/bin/indep-32/sdvxio.dll \ + dist/dwarfstack/32/dwarfstack.dll \ dist/sdvx/config.bat \ dist/sdvx/gamestart.bat \ + dist/sdvx/launcher.xml \ + dist/shared/ea3-ident.xml \ + dist/shared/ea3-license.xml \ + dist/shared/ea3-service.xml \ | $(zipdir)/ $(V)echo ... $@ $(V)zip -j $@ $^ @@ -589,9 +658,14 @@ $(zipdir)/sdvx-05-to-06.zip: \ build/bin/indep-64/eamio.dll \ build/bin/indep-64/geninput.dll \ build/bin/indep-64/sdvxio.dll \ + dist/dwarfstack/64/dwarfstack.dll \ dist/sdvx5/config.bat \ dist/sdvx5/gamestart.bat \ dist/sdvx5/sdvxhook2.conf \ + dist/sdvx5/launcher.xml \ + dist/shared/ea3-ident.xml \ + dist/shared/ea3-license.xml \ + dist/shared/ea3-service.xml \ | $(zipdir)/ $(V)echo ... $@ $(V)zip -j $@ $^ @@ -603,9 +677,14 @@ $(zipdir)/sdvx-05-cn.zip: \ build/bin/indep-64/eamio.dll \ build/bin/indep-64/geninput.dll \ build/bin/indep-64/sdvxio.dll \ + dist/dwarfstack/64/dwarfstack.dll \ dist/sdvx5/config.bat \ dist/sdvx5/gamestart-cn.bat \ dist/sdvx5/sdvxhook2-cn.conf \ + dist/sdvx5/launcher-cn.xml \ + dist/shared/ea3-ident.xml \ + dist/shared/ea3-license.xml \ + dist/shared/ea3-service.xml \ | $(zipdir)/ $(V)echo ... $@ $(V)zip -j $@ $^ @@ -659,6 +738,7 @@ $(zipdir)/ddr-12-us.zip: \ build/bin/indep-32/ddrio-smx.dll \ build/bin/indep-32/eamio.dll \ build/bin/indep-32/geninput.dll \ + dist/dwarfstack/32/dwarfstack.dll \ dist/ddr/config.bat \ dist/ddr/gamestart-12-us.bat \ dist/ddr/gamestart-12-eu.bat \ @@ -678,29 +758,39 @@ $(zipdir)/ddr-12.zip: \ build/bin/indep-32/ddrio-smx.dll \ build/bin/indep-32/eamio.dll \ build/bin/indep-32/geninput.dll \ + dist/dwarfstack/32/dwarfstack.dll \ dist/ddr/config.bat \ dist/ddr/gamestart-12.bat \ + dist/ddr/launcher-12.xml \ + dist/shared/ea3-ident.xml \ + dist/shared/ea3-license.xml \ + dist/shared/ea3-service.xml \ | $(zipdir)/ $(V)echo ... $@ $(V)zip -j $@ $^ $(zipdir)/ddr-13.zip: \ - build/bin/avs2_1304-32/launcher.exe \ - build/bin/avs2_1304-32/ddrhook2.dll \ - build/bin/avs2_1304-32/unicorntail.dll \ + build/bin/avs2_1306-32/launcher.exe \ + build/bin/avs2_1306-32/ddrhook2.dll \ + build/bin/avs2_1306-32/unicorntail.dll \ build/bin/indep-32/config.exe \ build/bin/indep-32/ddrio.dll \ build/bin/indep-32/ddrio-mm.dll \ build/bin/indep-32/ddrio-smx.dll \ build/bin/indep-32/eamio.dll \ build/bin/indep-32/geninput.dll \ + dist/dwarfstack/32/dwarfstack.dll \ dist/ddr/config.bat \ dist/ddr/gamestart-13.bat \ + dist/ddr/launcher-13.xml \ + dist/shared/ea3-ident.xml \ + dist/shared/ea3-license.xml \ + dist/shared/ea3-service.xml \ | $(zipdir)/ $(V)echo ... $@ $(V)zip -j $@ $^ -$(zipdir)/ddr-14-to-16.zip: \ +$(zipdir)/ddr-14-to-18.zip: \ build/bin/avs2_1508-32/launcher.exe \ build/bin/avs2_1508-32/ddrhook2.dll \ build/bin/avs2_1508-32/unicorntail.dll \ @@ -708,15 +798,26 @@ $(zipdir)/ddr-14-to-16.zip: \ build/bin/indep-32/ddrio.dll \ build/bin/indep-32/eamio.dll \ build/bin/indep-32/geninput.dll \ + dist/dwarfstack/32/dwarfstack.dll \ dist/ddr/config.bat \ dist/ddr/gamestart-14.bat \ dist/ddr/gamestart-15.bat \ dist/ddr/gamestart-16.bat \ + dist/ddr/gamestart-17.bat \ + dist/ddr/gamestart-18.bat \ + dist/ddr/launcher-14.xml \ + dist/ddr/launcher-15.xml \ + dist/ddr/launcher-16.xml \ + dist/ddr/launcher-17.xml \ + dist/ddr/launcher-18.xml \ + dist/shared/ea3-ident.xml \ + dist/shared/ea3-license.xml \ + dist/shared/ea3-service.xml \ | $(zipdir)/ $(V)echo ... $@ $(V)zip -j $@ $^ -$(zipdir)/ddr-16-x64.zip: \ +$(zipdir)/ddr-16-to-18-x64.zip: \ build/bin/avs2_1603-64/launcher.exe \ build/bin/avs2_1603-64/ddrhook2.dll \ build/bin/avs2_1603-64/unicorntail.dll \ @@ -724,8 +825,17 @@ $(zipdir)/ddr-16-x64.zip: \ build/bin/indep-64/ddrio.dll \ build/bin/indep-64/eamio.dll \ build/bin/indep-64/geninput.dll \ + dist/dwarfstack/64/dwarfstack.dll \ dist/ddr/config.bat \ dist/ddr/gamestart-16.bat \ + dist/ddr/gamestart-17.bat \ + dist/ddr/gamestart-18.bat \ + dist/ddr/launcher-16.xml \ + dist/ddr/launcher-17.xml \ + dist/ddr/launcher-18.xml \ + dist/shared/ea3-ident.xml \ + dist/shared/ea3-license.xml \ + dist/shared/ea3-service.xml \ | $(zipdir)/ $(V)echo ... $@ $(V)zip -j $@ $^ @@ -761,9 +871,15 @@ $(zipdir)/bst.zip: \ build/bin/indep-64/config.exe \ build/bin/indep-64/eamio.dll \ build/bin/indep-64/geninput.dll \ + dist/dwarfstack/64/dwarfstack.dll \ dist/bst/config.bat \ dist/bst/gamestart1.bat \ dist/bst/gamestart2.bat \ + dist/bst/launcher-01.xml \ + dist/bst/launcher-02.xml \ + dist/shared/ea3-ident.xml \ + dist/shared/ea3-license.xml \ + dist/shared/ea3-service.xml \ | $(zipdir)/ $(V)echo ... $@ $(V)zip -j $@ $^ @@ -776,6 +892,7 @@ $(zipdir)/popn-15-to-18.zip: \ build/bin/indep-32/eamio.dll \ build/bin/indep-32/popnio.dll \ build/bin/indep-32/ezusb2-popn-shim.dll \ + dist/dwarfstack/32/dwarfstack.dll \ dist/popn/config.bat \ dist/popn/gamestart-15.bat \ dist/popn/gamestart-16.bat \ @@ -807,6 +924,7 @@ $(BUILDDIR)/tests.zip: \ build/bin/indep-32/iidxhook-util-config-gfx-test.exe \ build/bin/indep-32/iidxhook-util-config-misc-test.exe \ build/bin/indep-32/iidxhook-util-config-sec-test.exe \ + dist/dwarfstack/32/dwarfstack.dll \ build/bin/indep-32/inject.exe \ build/bin/indep-32/security-id-test.exe \ build/bin/indep-32/security-mcode-test.exe \ @@ -827,8 +945,8 @@ $(BUILDDIR)/bemanitools.zip: \ $(zipdir)/ddr-12.zip \ $(zipdir)/ddr-12-us.zip \ $(zipdir)/ddr-13.zip \ - $(zipdir)/ddr-14-to-16.zip \ - $(zipdir)/ddr-16-x64.zip \ + $(zipdir)/ddr-14-to-18.zip \ + $(zipdir)/ddr-16-to-18-x64.zip \ $(zipdir)/ddr-hwio-x86.zip \ $(zipdir)/ddr-hwio-x64.zip \ $(zipdir)/doc.zip \ diff --git a/README.md b/README.md index d320361e..cfe7b216 100644 --- a/README.md +++ b/README.md @@ -35,9 +35,12 @@ The following games are supported with their corresponding hook-libraries. * Dance Dance Revolution X (`ddr-11.zip`): [ddrhook1](doc/ddrhook/ddrhook1.md) * Dance Dance Revolution X2 (US/EU regions) (`ddr-12-us.zip`): [ddrhook1](doc/ddrhook/ddrhook1.md) * Dance Dance Revolution X2 (JP region) (`ddr-12.zip`): [ddrhook2](doc/ddrhook/ddrhook2.md) - * Dance Dance Revolution 2013 (`ddr-14-to-16.zip`): [ddrhook2](doc/ddrhook/ddrhook2.md) - * Dance Dance Revolution 2014 (`ddr-14-to-16.zip`): [ddrhook2](doc/ddrhook/ddrhook2.md) - * Dance Dance Revolution A (`ddr-14-to-16.zip`): [ddrhook2](doc/ddrhook/ddrhook2.md) + * Dance Dance Revolution X3 vs. 2ndMIX (`ddr-13.zip`): [ddrhook2](doc/ddrhook/ddrhook2.md) + * Dance Dance Revolution 2013 (`ddr-14-to-18.zip`): [ddrhook2](doc/ddrhook/ddrhook2.md) + * Dance Dance Revolution 2014 (`ddr-14-to-18.zip`): [ddrhook2](doc/ddrhook/ddrhook2.md) + * Dance Dance Revolution A (`ddr-14-to-18.zip`): [ddrhook2](doc/ddrhook/ddrhook2.md) + * Dance Dance Revolution A20 (`ddr-14-to-18.zip`): [ddrhook2](doc/ddrhook/ddrhook2.md) + * Dance Dance Revolution A20+ (`ddr-14-to-18.zip`): [ddrhook2](doc/ddrhook/ddrhook2.md) * [Beatmania IIDX](doc/iidxhook/README.md) * Beatmania IIDX 9th Style (`iidx-09-to-12.zip`): [iidxhook1](doc/iidxhook/iidxhook1.md) * Beatmania IIDX 10th Style (`iidx-09-to-12.zip`): [iidxhook1](doc/iidxhook/iidxhook1.md) diff --git a/dist/bst/gamestart1.bat b/dist/bst/gamestart1.bat index 5a3a9155..5bca8eb1 100644 --- a/dist/bst/gamestart1.bat +++ b/dist/bst/gamestart1.bat @@ -1,10 +1,34 @@ @echo off +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session + +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 +) + +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. cd /d %~dp0 -if not exist dev\nvram mkdir dev\nvram -if not exist dev\nvram\coin.xml copy prop\defaults\coin.xml dev\nvram\coin.xml -if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml -if not exist dev\raw mkdir dev\raw +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% -launcher -K bsthook.dll -E prop/ea3-config-1.xml beatstream1.dll %* +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-01.xml %* \ No newline at end of file diff --git a/dist/bst/gamestart2.bat b/dist/bst/gamestart2.bat index 8b6f53f8..55340c37 100644 --- a/dist/bst/gamestart2.bat +++ b/dist/bst/gamestart2.bat @@ -1,10 +1,34 @@ @echo off +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session + +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 +) + +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. cd /d %~dp0 -if not exist dev\nvram mkdir dev\nvram -if not exist dev\nvram\coin.xml copy prop\defaults\coin.xml dev\nvram\coin.xml -if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml -if not exist dev\raw mkdir dev\raw +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% -launcher -K bsthook.dll -E prop/ea3-config-2.xml beatstream2.dll %* +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-02.xml %* \ No newline at end of file diff --git a/dist/bst/launcher-01.xml b/dist/bst/launcher-01.xml new file mode 100644 index 00000000..b62630ef --- /dev/null +++ b/dist/bst/launcher-01.xml @@ -0,0 +1,75 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 16777216 + 16777216 + ∂ + + info + + + /dev/nvram/ea3-config.xml + + + beatstream1.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-server.xml + + + + bsthook.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/bst/launcher-02.xml b/dist/bst/launcher-02.xml new file mode 100644 index 00000000..fdad81d9 --- /dev/null +++ b/dist/bst/launcher-02.xml @@ -0,0 +1,75 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 16777216 + 16777216 + + + info + + + /dev/nvram/ea3-config.xml + + + beatstream2.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + bsthook.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/ddr/gamestart-12.bat b/dist/ddr/gamestart-12.bat index 7df3fa33..03daa9c3 100644 --- a/dist/ddr/gamestart-12.bat +++ b/dist/ddr/gamestart-12.bat @@ -1,11 +1,42 @@ @echo off +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session + +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 +) + +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. cd /d %~dp0 -if not exist conf\nvram mkdir conf\nvram -if not exist conf\raw mkdir conf\raw +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set COM_DIR=%CONTENT_DIR%\com +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Register video codecs, e.g. required for background videos +regsvr32 /s %COM_DIR%\k-clvsd.dll + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% -regsvr32 /s k-clvsd.dll -regsvr32 /s xactengine2_10.dll +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-13.xml %* -.\launcher.exe -K .\ddrhook2.dll .\ddr.dll %* +:: Unregister video codec to avoid conflicts with other/older video codecs crashing different +:: game versions, e.g. DDR X +regsvr32 /u /s %COM_DIR%\k-clvsd.dll \ No newline at end of file diff --git a/dist/ddr/gamestart-13.bat b/dist/ddr/gamestart-13.bat index 7df3fa33..03daa9c3 100644 --- a/dist/ddr/gamestart-13.bat +++ b/dist/ddr/gamestart-13.bat @@ -1,11 +1,42 @@ @echo off +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session + +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 +) + +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. cd /d %~dp0 -if not exist conf\nvram mkdir conf\nvram -if not exist conf\raw mkdir conf\raw +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set COM_DIR=%CONTENT_DIR%\com +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Register video codecs, e.g. required for background videos +regsvr32 /s %COM_DIR%\k-clvsd.dll + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% -regsvr32 /s k-clvsd.dll -regsvr32 /s xactengine2_10.dll +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-13.xml %* -.\launcher.exe -K .\ddrhook2.dll .\ddr.dll %* +:: Unregister video codec to avoid conflicts with other/older video codecs crashing different +:: game versions, e.g. DDR X +regsvr32 /u /s %COM_DIR%\k-clvsd.dll \ No newline at end of file diff --git a/dist/ddr/gamestart-14.bat b/dist/ddr/gamestart-14.bat index 2ad52121..2364f521 100644 --- a/dist/ddr/gamestart-14.bat +++ b/dist/ddr/gamestart-14.bat @@ -1,14 +1,44 @@ @echo off +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session + +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 +) + +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. cd /d %~dp0 -if not exist conf\nvram mkdir conf\nvram -if not exist conf\nvram\coin.xml copy prop\coin.xml conf\nvram\coin.xml -if not exist conf\nvram\eacoin.xml copy prop\eacoin.xml conf\nvram\eacoin.xml -if not exist conf\nvram\share-config.xml copy prop\share-config.xml conf\nvram\share-config.xml -if not exist conf\raw mkdir conf\raw +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set COM_DIR=%CONTENT_DIR%\com +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Register video codecs, e.g. required for background videos +regsvr32 /s %COM_DIR%\k-clvsd.dll +regsvr32 /s %COM_DIR%\xactengine2_10.dll + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% -regsvr32 /s k-clvsd.dll -regsvr32 /s xactengine2_10.dll +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-14.xml %* -.\launcher.exe -K .\ddrhook2.dll .\mdxja_945.dll %* +:: Unregister video codec to avoid conflicts with other/older video codecs crashing different +:: game versions, e.g. DDR X +regsvr32 /u /s %COM_DIR%\k-clvsd.dll +regsvr32 /u /s %COM_DIR%\xactengine2_10.dll \ No newline at end of file diff --git a/dist/ddr/gamestart-15.bat b/dist/ddr/gamestart-15.bat index 2ad52121..97301177 100644 --- a/dist/ddr/gamestart-15.bat +++ b/dist/ddr/gamestart-15.bat @@ -1,14 +1,44 @@ @echo off +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session + +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 +) + +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. cd /d %~dp0 -if not exist conf\nvram mkdir conf\nvram -if not exist conf\nvram\coin.xml copy prop\coin.xml conf\nvram\coin.xml -if not exist conf\nvram\eacoin.xml copy prop\eacoin.xml conf\nvram\eacoin.xml -if not exist conf\nvram\share-config.xml copy prop\share-config.xml conf\nvram\share-config.xml -if not exist conf\raw mkdir conf\raw +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set COM_DIR=%CONTENT_DIR%\com +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Register video codecs, e.g. required for background videos +regsvr32 /s %COM_DIR%\k-clvsd.dll +regsvr32 /s %COM_DIR%\xactengine2_10.dll + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% -regsvr32 /s k-clvsd.dll -regsvr32 /s xactengine2_10.dll +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-15.xml %* -.\launcher.exe -K .\ddrhook2.dll .\mdxja_945.dll %* +:: Unregister video codec to avoid conflicts with other/older video codecs crashing different +:: game versions, e.g. DDR X +regsvr32 /u /s %COM_DIR%\k-clvsd.dll +regsvr32 /u /s %COM_DIR%\xactengine2_10.dll \ No newline at end of file diff --git a/dist/ddr/gamestart-16.bat b/dist/ddr/gamestart-16.bat index d108118b..b176cb3a 100644 --- a/dist/ddr/gamestart-16.bat +++ b/dist/ddr/gamestart-16.bat @@ -1,15 +1,44 @@ @echo off +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session + +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 +) + +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. cd /d %~dp0 -if not exist conf\nvram mkdir conf\nvram -if not exist conf\nvram\ea3-config.xml copy prop\eamuse-config.xml conf\nvram\ea3-config.xml -if not exist conf\nvram\coin.xml copy prop\coin.xml conf\nvram\coin.xml -if not exist conf\nvram\eacoin.xml copy prop\eacoin.xml conf\nvram\eacoin.xml -if not exist conf\nvram\testmode-v.xml copy prop\testmode-v.xml conf\nvram\testmode-v.xml -if not exist conf\raw mkdir conf\raw +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set COM_DIR=%CONTENT_DIR%\com +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Register video codecs, e.g. required for background videos +regsvr32 /s %COM_DIR%\k-clvsd.dll +regsvr32 /s %COM_DIR%\xactengine2_10.dll + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% -regsvr32 /s com\k-clvsd.dll -regsvr32 /s com\xactengine2_10.dll +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-17.xml %* -.\launcher.exe -H 33554432 -K .\ddrhook2.dll .\arkmdxp3.dll %* +:: Unregister video codec to avoid conflicts with other/older video codecs crashing different +:: game versions, e.g. DDR X +regsvr32 /u /s %COM_DIR%\k-clvsd.dll +regsvr32 /u /s %COM_DIR%\xactengine2_10.dll \ No newline at end of file diff --git a/dist/ddr/gamestart-17.bat b/dist/ddr/gamestart-17.bat new file mode 100644 index 00000000..b176cb3a --- /dev/null +++ b/dist/ddr/gamestart-17.bat @@ -0,0 +1,44 @@ +@echo off + +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session + +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 +) + +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. +cd /d %~dp0 + +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set COM_DIR=%CONTENT_DIR%\com +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Register video codecs, e.g. required for background videos +regsvr32 /s %COM_DIR%\k-clvsd.dll +regsvr32 /s %COM_DIR%\xactengine2_10.dll + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% + +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-17.xml %* + +:: Unregister video codec to avoid conflicts with other/older video codecs crashing different +:: game versions, e.g. DDR X +regsvr32 /u /s %COM_DIR%\k-clvsd.dll +regsvr32 /u /s %COM_DIR%\xactengine2_10.dll \ No newline at end of file diff --git a/dist/ddr/gamestart-18.bat b/dist/ddr/gamestart-18.bat new file mode 100644 index 00000000..95a92ed0 --- /dev/null +++ b/dist/ddr/gamestart-18.bat @@ -0,0 +1,44 @@ +@echo off + +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session + +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 +) + +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. +cd /d %~dp0 + +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set COM_DIR=%CONTENT_DIR%\com +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Register video codecs, e.g. required for background videos +regsvr32 /s %COM_DIR%\k-clvsd.dll +regsvr32 /s %COM_DIR%\xactengine2_10.dll + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% + +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-18.xml %* + +:: Unregister video codec to avoid conflicts with other/older video codecs crashing different +:: game versions, e.g. DDR X +regsvr32 /u /s %COM_DIR%\k-clvsd.dll +regsvr32 /u /s %COM_DIR%\xactengine2_10.dll \ No newline at end of file diff --git a/dist/ddr/launcher-12.xml b/dist/ddr/launcher-12.xml new file mode 100644 index 00000000..54c0284b --- /dev/null +++ b/dist/ddr/launcher-12.xml @@ -0,0 +1,75 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 31457280 + 31457280 + + + info + + + /dev/nvram/ea3-config.xml + + + ddr.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + ddrhook2.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/ddr/launcher-13.xml b/dist/ddr/launcher-13.xml new file mode 100644 index 00000000..54c0284b --- /dev/null +++ b/dist/ddr/launcher-13.xml @@ -0,0 +1,75 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 31457280 + 31457280 + + + info + + + /dev/nvram/ea3-config.xml + + + ddr.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + ddrhook2.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/ddr/launcher-14.xml b/dist/ddr/launcher-14.xml new file mode 100644 index 00000000..9ae27ac3 --- /dev/null +++ b/dist/ddr/launcher-14.xml @@ -0,0 +1,75 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 31457280 + 31457280 + + + info + + + /dev/nvram/ea3-config.xml + + + mdxja_945.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + ddrhook2.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/ddr/launcher-15.xml b/dist/ddr/launcher-15.xml new file mode 100644 index 00000000..9ae27ac3 --- /dev/null +++ b/dist/ddr/launcher-15.xml @@ -0,0 +1,75 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 31457280 + 31457280 + + + info + + + /dev/nvram/ea3-config.xml + + + mdxja_945.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + ddrhook2.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/ddr/launcher-16.xml b/dist/ddr/launcher-16.xml new file mode 100644 index 00000000..cdf16d55 --- /dev/null +++ b/dist/ddr/launcher-16.xml @@ -0,0 +1,76 @@ + + + + bemanitools_local_fs + + + + + + + + + + + + prop/avs-config.xml + 33554432 + 1048576 + + + info + + + /dev/nvram/ea3-config.xml + + + arkmdxp3.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + ddrhook2.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/ddr/launcher-17.xml b/dist/ddr/launcher-17.xml new file mode 100644 index 00000000..cdf16d55 --- /dev/null +++ b/dist/ddr/launcher-17.xml @@ -0,0 +1,76 @@ + + + + bemanitools_local_fs + + + + + + + + + + + + prop/avs-config.xml + 33554432 + 1048576 + + + info + + + /dev/nvram/ea3-config.xml + + + arkmdxp3.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + ddrhook2.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/ddr/launcher-18.xml b/dist/ddr/launcher-18.xml new file mode 100644 index 00000000..cdf16d55 --- /dev/null +++ b/dist/ddr/launcher-18.xml @@ -0,0 +1,76 @@ + + + + bemanitools_local_fs + + + + + + + + + + + + prop/avs-config.xml + 33554432 + 1048576 + + + info + + + /dev/nvram/ea3-config.xml + + + arkmdxp3.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + ddrhook2.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/dwarfstack/32/dwarfstack.dll b/dist/dwarfstack/32/dwarfstack.dll new file mode 100644 index 00000000..74b9796d Binary files /dev/null and b/dist/dwarfstack/32/dwarfstack.dll differ diff --git a/dist/dwarfstack/64/dwarfstack.dll b/dist/dwarfstack/64/dwarfstack.dll new file mode 100644 index 00000000..8944c726 Binary files /dev/null and b/dist/dwarfstack/64/dwarfstack.dll differ diff --git a/dist/dwarfstack/readme.md b/dist/dwarfstack/readme.md new file mode 100644 index 00000000..c8ce1e3c --- /dev/null +++ b/dist/dwarfstack/readme.md @@ -0,0 +1 @@ +Version/release: https://github.com/ssbssa/dwarfstack/releases/tag/2.2 \ No newline at end of file diff --git a/dist/iidx/ea3-ident.xml b/dist/iidx/ea3-ident.xml new file mode 100644 index 00000000..e24a9b92 --- /dev/null +++ b/dist/iidx/ea3-ident.xml @@ -0,0 +1,10 @@ + + + + LDJ + J + A + A + 2022082400 + + \ No newline at end of file diff --git a/dist/iidx/eamuse-server.xml b/dist/iidx/eamuse-server.xml new file mode 100644 index 00000000..bc706444 --- /dev/null +++ b/dist/iidx/eamuse-server.xml @@ -0,0 +1,6 @@ + + + + http://localhost + + \ No newline at end of file diff --git a/dist/iidx/gamestart-18.bat b/dist/iidx/gamestart-18.bat index cce99b03..64398697 100755 --- a/dist/iidx/gamestart-18.bat +++ b/dist/iidx/gamestart-18.bat @@ -1,14 +1,34 @@ @echo off +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session + +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 +) + +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. cd /d %~dp0 -if not exist d mkdir d -if not exist e mkdir e -if not exist f mkdir f +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% -if not exist dev\nvram mkdir dev\nvram -if not exist dev\nvram\coin.xml copy prop\defaults\coin.xml dev\nvram\coin.xml -if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml -if not exist dev\raw mkdir dev\raw +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% -launcher -K iidxhook4.dll bm2dx.dll --config iidxhook-18.conf %* +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-18.xml --config iidxhook-18.conf %* \ No newline at end of file diff --git a/dist/iidx/gamestart-19.bat b/dist/iidx/gamestart-19.bat index 8bfd5803..9a1ac95a 100755 --- a/dist/iidx/gamestart-19.bat +++ b/dist/iidx/gamestart-19.bat @@ -1,14 +1,34 @@ @echo off +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session + +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 +) + +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. cd /d %~dp0 -if not exist d mkdir d -if not exist e mkdir e -if not exist f mkdir f +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% -if not exist dev\nvram mkdir dev\nvram -if not exist dev\nvram\coin.xml copy prop\defaults\coin.xml dev\nvram\coin.xml -if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml -if not exist dev\raw mkdir dev\raw +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% -launcher -K iidxhook5.dll bm2dx.dll --config iidxhook-19.conf %* +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-19.xml --config iidxhook-19.conf %* \ No newline at end of file diff --git a/dist/iidx/gamestart-20.bat b/dist/iidx/gamestart-20.bat index 2dac80ea..4a9d9f53 100755 --- a/dist/iidx/gamestart-20.bat +++ b/dist/iidx/gamestart-20.bat @@ -1,10 +1,34 @@ @echo off +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session + +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 +) + +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. cd /d %~dp0 -if not exist dev\nvram mkdir dev\nvram -if not exist dev\nvram\coin.xml copy prop\defaults\coin.xml dev\nvram\coin.xml -if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml -if not exist dev\raw mkdir dev\raw +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% -launcher -K iidxhook6.dll bm2dx.dll --config iidxhook-20.conf %* +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-20.xml --config iidxhook-20.conf %* \ No newline at end of file diff --git a/dist/iidx/gamestart-21.bat b/dist/iidx/gamestart-21.bat index b79d6416..6c7c91ca 100755 --- a/dist/iidx/gamestart-21.bat +++ b/dist/iidx/gamestart-21.bat @@ -1,10 +1,34 @@ @echo off +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session + +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 +) + +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. cd /d %~dp0 -if not exist dev\nvram mkdir dev\nvram -if not exist dev\nvram\coin.xml copy prop\defaults\coin.xml dev\nvram\coin.xml -if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml -if not exist dev\raw mkdir dev\raw +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% -launcher -K iidxhook7.dll bm2dx.dll --config iidxhook-21.conf %* +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-21.xml --config iidxhook-21.conf %* \ No newline at end of file diff --git a/dist/iidx/gamestart-22.bat b/dist/iidx/gamestart-22.bat index d10a945a..bf195d2a 100755 --- a/dist/iidx/gamestart-22.bat +++ b/dist/iidx/gamestart-22.bat @@ -1,10 +1,34 @@ @echo off +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session + +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 +) + +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. cd /d %~dp0 -if not exist dev\nvram mkdir dev\nvram -if not exist dev\nvram\coin.xml copy prop\defaults\coin.xml dev\nvram\coin.xml -if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml -if not exist dev\raw mkdir dev\raw +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% -launcher -K iidxhook7.dll bm2dx.dll --config iidxhook-22.conf %* +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-22.xml --config iidxhook-22.conf %* \ No newline at end of file diff --git a/dist/iidx/gamestart-23.bat b/dist/iidx/gamestart-23.bat index 656e1fe2..ec664375 100755 --- a/dist/iidx/gamestart-23.bat +++ b/dist/iidx/gamestart-23.bat @@ -1,10 +1,34 @@ @echo off +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session + +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 +) + +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. cd /d %~dp0 -if not exist dev\nvram mkdir dev\nvram -if not exist dev\nvram\coin.xml copy prop\defaults\coin.xml dev\nvram\coin.xml -if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml -if not exist dev\raw mkdir dev\raw +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% -launcher -K iidxhook7.dll bm2dx.dll --config iidxhook-23.conf %* +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-23.xml --config iidxhook-23.conf %* \ No newline at end of file diff --git a/dist/iidx/gamestart-24.bat b/dist/iidx/gamestart-24.bat index 283020c4..c9b5f5e9 100755 --- a/dist/iidx/gamestart-24.bat +++ b/dist/iidx/gamestart-24.bat @@ -1,10 +1,34 @@ @echo off +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session + +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 +) + +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. cd /d %~dp0 -if not exist dev\nvram mkdir dev\nvram -if not exist dev\nvram\coin.xml copy prop\defaults\coin.xml dev\nvram\coin.xml -if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml -if not exist dev\raw mkdir dev\raw +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% -launcher -K iidxhook7.dll bm2dx.dll --config iidxhook-24.conf %* +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-24.xml --config iidxhook-24.conf %* \ No newline at end of file diff --git a/dist/iidx/gamestart-25.bat b/dist/iidx/gamestart-25.bat index edff2940..67775e21 100644 --- a/dist/iidx/gamestart-25.bat +++ b/dist/iidx/gamestart-25.bat @@ -1,16 +1,34 @@ @echo off -cd /d %~dp0 -if not exist dev mkdir dev -if not exist dev\e mkdir dev\e -if not exist dev\g mkdir dev\g -if not exist dev\nvram mkdir dev\nvram -if not exist dev\raw mkdir dev\raw -if not exist dev\raw\log mkdir dev\raw\log -if not exist dev\raw\fscache mkdir dev\raw\fscache +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session -for /R prop\defaults %%D in (*.*) do ( - if not exist dev\nvram\%%~nxD copy /y prop\defaults\%%~nxD dev\nvram +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 ) -launcher -H 134217728 -K iidxhook8.dll bm2dx.dll --config iidxhook-25.conf %* +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. +cd /d %~dp0 + +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% + +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-25.xml --config iidxhook-25.conf %* \ No newline at end of file diff --git a/dist/iidx/gamestart-26.bat b/dist/iidx/gamestart-26.bat index d41b72b3..749f1205 100644 --- a/dist/iidx/gamestart-26.bat +++ b/dist/iidx/gamestart-26.bat @@ -1,16 +1,34 @@ @echo off -cd /d %~dp0 -if not exist dev mkdir dev -if not exist dev\e mkdir dev\e -if not exist dev\g mkdir dev\g -if not exist dev\nvram mkdir dev\nvram -if not exist dev\raw mkdir dev\raw -if not exist dev\raw\log mkdir dev\raw\log -if not exist dev\raw\fscache mkdir dev\raw\fscache +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session -for /R prop\defaults %%D in (*.*) do ( - if not exist dev\nvram\%%~nxD copy /y prop\defaults\%%~nxD dev\nvram +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 ) -launcher -H 134217728 -K iidxhook8.dll bm2dx.dll --config iidxhook-26.conf %* +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. +cd /d %~dp0 + +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% + +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-26.xml --config iidxhook-26.conf %* \ No newline at end of file diff --git a/dist/iidx/gamestart-27.bat b/dist/iidx/gamestart-27.bat index 04a39091..5b3b3782 100644 --- a/dist/iidx/gamestart-27.bat +++ b/dist/iidx/gamestart-27.bat @@ -1,16 +1,34 @@ @echo off -cd /d %~dp0 -if not exist dev mkdir dev -if not exist dev\e mkdir dev\e -if not exist dev\g mkdir dev\g -if not exist dev\nvram mkdir dev\nvram -if not exist dev\raw mkdir dev\raw -if not exist dev\raw\log mkdir dev\raw\log -if not exist dev\raw\fscache mkdir dev\raw\fscache +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session -for /R prop\defaults %%D in (*.*) do ( - if not exist dev\nvram\%%~nxD copy /y prop\defaults\%%~nxD dev\nvram +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 ) -launcher -H 134217728 -B iidxhook9.dll bm2dx.dll --config iidxhook-27.conf %* +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. +cd /d %~dp0 + +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% + +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-27.xml --config iidxhook-27.conf %* \ No newline at end of file diff --git a/dist/iidx/gamestart-28.bat b/dist/iidx/gamestart-28.bat index 1abb520d..3486de8f 100644 --- a/dist/iidx/gamestart-28.bat +++ b/dist/iidx/gamestart-28.bat @@ -1,16 +1,34 @@ @echo off -cd /d %~dp0 -if not exist dev mkdir dev -if not exist dev\e mkdir dev\e -if not exist dev\g mkdir dev\g -if not exist dev\nvram mkdir dev\nvram -if not exist dev\raw mkdir dev\raw -if not exist dev\raw\log mkdir dev\raw\log -if not exist dev\raw\fscache mkdir dev\raw\fscache +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session -for /R prop\defaults %%D in (*.*) do ( - if not exist dev\nvram\%%~nxD copy /y prop\defaults\%%~nxD dev\nvram +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 ) -launcher -H 134217728 -B iidxhook9.dll bm2dx.dll --config iidxhook-28.conf %* +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. +cd /d %~dp0 + +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% + +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-28.xml --config iidxhook-28.conf %* \ No newline at end of file diff --git a/dist/iidx/gamestart-29.bat b/dist/iidx/gamestart-29.bat index 1029b8c5..d4d7c1f7 100644 --- a/dist/iidx/gamestart-29.bat +++ b/dist/iidx/gamestart-29.bat @@ -1,16 +1,34 @@ @echo off -cd /d %~dp0 -if not exist dev mkdir dev -if not exist dev\e mkdir dev\e -if not exist dev\g mkdir dev\g -if not exist dev\nvram mkdir dev\nvram -if not exist dev\raw mkdir dev\raw -if not exist dev\raw\log mkdir dev\raw\log -if not exist dev\raw\fscache mkdir dev\raw\fscache +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session -for /R prop\defaults %%D in (*.*) do ( - if not exist dev\nvram\%%~nxD copy /y prop\defaults\%%~nxD dev\nvram +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 ) -launcher -H 134217728 -B iidxhook9.dll bm2dx.dll --config iidxhook-29.conf %* +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. +cd /d %~dp0 + +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% + +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-29.xml --config iidxhook-29.conf %* \ No newline at end of file diff --git a/dist/iidx/gamestart-30.bat b/dist/iidx/gamestart-30.bat index 776d7e84..3f960227 100644 --- a/dist/iidx/gamestart-30.bat +++ b/dist/iidx/gamestart-30.bat @@ -1,16 +1,34 @@ @echo off -cd /d %~dp0 -if not exist dev mkdir dev -if not exist dev\e mkdir dev\e -if not exist dev\g mkdir dev\g -if not exist dev\nvram mkdir dev\nvram -if not exist dev\raw mkdir dev\raw -if not exist dev\raw\log mkdir dev\raw\log -if not exist dev\raw\fscache mkdir dev\raw\fscache +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session -for /R prop\defaults %%D in (*.*) do ( - if not exist dev\nvram\%%~nxD copy /y prop\defaults\%%~nxD dev\nvram +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 ) -modules\launcher -H 134217728 -B iidxhook9.dll bm2dx.dll --config iidxhook-30.conf %* +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. +cd /d %~dp0 + +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% + +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-30.xml --config iidxhook-30.conf %* \ No newline at end of file diff --git a/dist/iidx/launcher-18.xml b/dist/iidx/launcher-18.xml new file mode 100644 index 00000000..74bf35e3 --- /dev/null +++ b/dist/iidx/launcher-18.xml @@ -0,0 +1,75 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 16777216 + 16777216 + + + info + + + /dev/nvram/ea3-config.xml + + + bm2dx.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + iidxhook4.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/iidx/launcher-19.xml b/dist/iidx/launcher-19.xml new file mode 100644 index 00000000..1749cfbd --- /dev/null +++ b/dist/iidx/launcher-19.xml @@ -0,0 +1,75 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 16777216 + 16777216 + + + info + + + /dev/nvram/ea3-config.xml + + + bm2dx.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + iidxhook5.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/iidx/launcher-20.xml b/dist/iidx/launcher-20.xml new file mode 100644 index 00000000..7af7ce4f --- /dev/null +++ b/dist/iidx/launcher-20.xml @@ -0,0 +1,75 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 16777216 + 16777216 + + + info + + + /dev/nvram/ea3-config.xml + + + bm2dx.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + iidxhook6.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/iidx/launcher-21.xml b/dist/iidx/launcher-21.xml new file mode 100644 index 00000000..502407b7 --- /dev/null +++ b/dist/iidx/launcher-21.xml @@ -0,0 +1,75 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 16777216 + 16777216 + + + info + + + /dev/nvram/ea3-config.xml + + + bm2dx.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + iidxhook7.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/iidx/launcher-22.xml b/dist/iidx/launcher-22.xml new file mode 100644 index 00000000..502407b7 --- /dev/null +++ b/dist/iidx/launcher-22.xml @@ -0,0 +1,75 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 16777216 + 16777216 + + + info + + + /dev/nvram/ea3-config.xml + + + bm2dx.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + iidxhook7.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/iidx/launcher-23.xml b/dist/iidx/launcher-23.xml new file mode 100644 index 00000000..502407b7 --- /dev/null +++ b/dist/iidx/launcher-23.xml @@ -0,0 +1,75 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 16777216 + 16777216 + + + info + + + /dev/nvram/ea3-config.xml + + + bm2dx.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + iidxhook7.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/iidx/launcher-24.xml b/dist/iidx/launcher-24.xml new file mode 100644 index 00000000..502407b7 --- /dev/null +++ b/dist/iidx/launcher-24.xml @@ -0,0 +1,75 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 16777216 + 16777216 + + + info + + + /dev/nvram/ea3-config.xml + + + bm2dx.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + iidxhook7.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/iidx/launcher-25.xml b/dist/iidx/launcher-25.xml new file mode 100644 index 00000000..733a8807 --- /dev/null +++ b/dist/iidx/launcher-25.xml @@ -0,0 +1,74 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 134217728 + + + info + + + /dev/nvram/ea3-config.xml + + + bm2dx.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + iidxhook8.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/iidx/launcher-26.xml b/dist/iidx/launcher-26.xml new file mode 100644 index 00000000..733a8807 --- /dev/null +++ b/dist/iidx/launcher-26.xml @@ -0,0 +1,74 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 134217728 + + + info + + + /dev/nvram/ea3-config.xml + + + bm2dx.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + iidxhook8.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/iidx/launcher-27.xml b/dist/iidx/launcher-27.xml new file mode 100644 index 00000000..f903fa68 --- /dev/null +++ b/dist/iidx/launcher-27.xml @@ -0,0 +1,74 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 134217728 + + + info + + + /dev/nvram/ea3-config.xml + + + bm2dx.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + iidxhook9.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/iidx/launcher-28.xml b/dist/iidx/launcher-28.xml new file mode 100644 index 00000000..f903fa68 --- /dev/null +++ b/dist/iidx/launcher-28.xml @@ -0,0 +1,74 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 134217728 + + + info + + + /dev/nvram/ea3-config.xml + + + bm2dx.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + iidxhook9.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/iidx/launcher-29.xml b/dist/iidx/launcher-29.xml new file mode 100644 index 00000000..f903fa68 --- /dev/null +++ b/dist/iidx/launcher-29.xml @@ -0,0 +1,74 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 134217728 + + + info + + + /dev/nvram/ea3-config.xml + + + bm2dx.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + iidxhook9.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/iidx/launcher-30.xml b/dist/iidx/launcher-30.xml new file mode 100644 index 00000000..f903fa68 --- /dev/null +++ b/dist/iidx/launcher-30.xml @@ -0,0 +1,74 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 134217728 + + + info + + + /dev/nvram/ea3-config.xml + + + bm2dx.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + iidxhook9.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/iidx/pcbid.xml b/dist/iidx/pcbid.xml new file mode 100644 index 00000000..bc50cdee --- /dev/null +++ b/dist/iidx/pcbid.xml @@ -0,0 +1,7 @@ + + + + 0101020304050607083F + 0101020304050607083F + + \ No newline at end of file diff --git a/dist/jb/ea3-ident.xml b/dist/jb/ea3-ident.xml new file mode 100644 index 00000000..e24a9b92 --- /dev/null +++ b/dist/jb/ea3-ident.xml @@ -0,0 +1,10 @@ + + + + LDJ + J + A + A + 2022082400 + + \ No newline at end of file diff --git a/dist/jb/eamuse-server.xml b/dist/jb/eamuse-server.xml new file mode 100644 index 00000000..bc706444 --- /dev/null +++ b/dist/jb/eamuse-server.xml @@ -0,0 +1,6 @@ + + + + http://localhost + + \ No newline at end of file diff --git a/dist/jb/gamestart-03.bat b/dist/jb/gamestart-03.bat index 76acc782..39e1b8fd 100644 --- a/dist/jb/gamestart-03.bat +++ b/dist/jb/gamestart-03.bat @@ -1,11 +1,34 @@ @echo off +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session + +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 +) + +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. cd /d %~dp0 -if not exist dev\nvram mkdir dev\nvram -if not exist dev\nvram\ea3-config.xml copy prop\ea3-config.xml dev\nvram\ea3-config.xml -if not exist dev\nvram\coin.xml copy prop\defaults\coin.xml dev\nvram\coin.xml -if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml -if not exist dev\raw mkdir dev\raw +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% -launcher -H 33554432 -K jbhook2.dll jubeat.dll -v +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-03.xml -v %* \ No newline at end of file diff --git a/dist/jb/gamestart-04.bat b/dist/jb/gamestart-04.bat index 245e314d..14d95e78 100644 --- a/dist/jb/gamestart-04.bat +++ b/dist/jb/gamestart-04.bat @@ -1,11 +1,34 @@ @echo off +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session + +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 +) + +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. cd /d %~dp0 -if not exist dev\nvram mkdir dev\nvram -if not exist dev\nvram\ea3-config.xml copy prop\ea3-config.xml dev\nvram\ea3-config.xml -if not exist dev\nvram\coin.xml copy prop\defaults\coin.xml dev\nvram\coin.xml -if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml -if not exist dev\raw mkdir dev\raw +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% -launcher -H 33554432 -K jbhook3.dll jubeat.dll +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-04.xml %* \ No newline at end of file diff --git a/dist/jb/launcher-03.xml b/dist/jb/launcher-03.xml new file mode 100644 index 00000000..095b2f62 --- /dev/null +++ b/dist/jb/launcher-03.xml @@ -0,0 +1,75 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 33554432 + 33554432 + + + info + + + /dev/nvram/ea3-config.xml + + + jubeat.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + jbhook2.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/jb/launcher-04.xml b/dist/jb/launcher-04.xml new file mode 100644 index 00000000..1c85a3c8 --- /dev/null +++ b/dist/jb/launcher-04.xml @@ -0,0 +1,75 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 33554432 + 33554432 + + + info + + + /dev/nvram/ea3-config.xml + + + jubeat.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + jbhook3.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/jb/pcbid.xml b/dist/jb/pcbid.xml new file mode 100644 index 00000000..bc50cdee --- /dev/null +++ b/dist/jb/pcbid.xml @@ -0,0 +1,7 @@ + + + + 0101020304050607083F + 0101020304050607083F + + \ No newline at end of file diff --git a/dist/sdvx/ea3-ident.xml b/dist/sdvx/ea3-ident.xml new file mode 100644 index 00000000..e24a9b92 --- /dev/null +++ b/dist/sdvx/ea3-ident.xml @@ -0,0 +1,10 @@ + + + + LDJ + J + A + A + 2022082400 + + \ No newline at end of file diff --git a/dist/sdvx/eamuse-server.xml b/dist/sdvx/eamuse-server.xml new file mode 100644 index 00000000..bc706444 --- /dev/null +++ b/dist/sdvx/eamuse-server.xml @@ -0,0 +1,6 @@ + + + + http://localhost + + \ No newline at end of file diff --git a/dist/sdvx/gamestart.bat b/dist/sdvx/gamestart.bat index a286325c..4e97b924 100644 --- a/dist/sdvx/gamestart.bat +++ b/dist/sdvx/gamestart.bat @@ -8,3 +8,38 @@ if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin if not exist dev\raw mkdir dev\raw launcher -K sdvxhook.dll soundvoltex.dll %* + +@echo off + +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session + +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 +) + +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. +cd /d %~dp0 + +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% + +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher.xml %* \ No newline at end of file diff --git a/dist/sdvx/launcher.xml b/dist/sdvx/launcher.xml new file mode 100644 index 00000000..4876ca76 --- /dev/null +++ b/dist/sdvx/launcher.xml @@ -0,0 +1,75 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 16777216 + 16777216 + + + info + + + /dev/nvram/ea3-config.xml + + + soundvoltex.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + sdvxhook.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/sdvx/pcbid.xml b/dist/sdvx/pcbid.xml new file mode 100644 index 00000000..bc50cdee --- /dev/null +++ b/dist/sdvx/pcbid.xml @@ -0,0 +1,7 @@ + + + + 0101020304050607083F + 0101020304050607083F + + \ No newline at end of file diff --git a/dist/sdvx5/ea3-ident.xml b/dist/sdvx5/ea3-ident.xml new file mode 100644 index 00000000..e24a9b92 --- /dev/null +++ b/dist/sdvx5/ea3-ident.xml @@ -0,0 +1,10 @@ + + + + LDJ + J + A + A + 2022082400 + + \ No newline at end of file diff --git a/dist/sdvx5/eamuse-server.xml b/dist/sdvx5/eamuse-server.xml new file mode 100644 index 00000000..bc706444 --- /dev/null +++ b/dist/sdvx5/eamuse-server.xml @@ -0,0 +1,6 @@ + + + + http://localhost + + \ No newline at end of file diff --git a/dist/sdvx5/gamestart-cn.bat b/dist/sdvx5/gamestart-cn.bat index 8435bd73..3976baf0 100644 --- a/dist/sdvx5/gamestart-cn.bat +++ b/dist/sdvx5/gamestart-cn.bat @@ -1,17 +1,34 @@ @echo off -cd /d %~dp0 -if not exist dev mkdir dev -if not exist dev\e mkdir dev\e -if not exist dev\g mkdir dev\g -if not exist dev\nvram mkdir dev\nvram -if not exist dev\raw mkdir dev\raw -if not exist dev\raw\c.dest echo $null >> dev\raw\c.dest -if not exist dev\raw\log mkdir dev\raw\log -if not exist dev\raw\fscache mkdir dev\raw\fscache +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session -for /R prop\defaults %%D in (*.*) do ( - if not exist dev\nvram\%%~nxD copy /y prop\defaults\%%~nxD dev\nvram +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 ) -launcher -H 268435456 -K sdvxhook2-cn.dll soundvoltex.dll --config sdvxhook2-cn.conf %* +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. +cd /d %~dp0 + +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% + +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher-cn.xml --config sdvxhook2-cn.conf %* \ No newline at end of file diff --git a/dist/sdvx5/gamestart.bat b/dist/sdvx5/gamestart.bat index c1b41ddd..9e77aaa2 100644 --- a/dist/sdvx5/gamestart.bat +++ b/dist/sdvx5/gamestart.bat @@ -1,16 +1,34 @@ @echo off -cd /d %~dp0 -if not exist dev mkdir dev -if not exist dev\e mkdir dev\e -if not exist dev\g mkdir dev\g -if not exist dev\nvram mkdir dev\nvram -if not exist dev\raw mkdir dev\raw -if not exist dev\raw\log mkdir dev\raw\log -if not exist dev\raw\fscache mkdir dev\raw\fscache +:: Game doesn't work properly when not run with administrator privileges +>nul 2>&1 net session -for /R prop\defaults %%D in (*.*) do ( - if not exist dev\nvram\%%~nxD copy /y prop\defaults\%%~nxD dev\nvram +if %errorlevel% neq 0 ( + echo This script requires administrative privileges. + echo Please run the script as an administrator. + pause + exit 1 ) -launcher -H 268435456 -K sdvxhook2.dll soundvoltex.dll --config sdvxhook2.conf %* +:: Script expects to be located in a subfolder "bemanitools" in the root folder +:: (contents/) next to the folders modules, data etc. +cd /d %~dp0 + +:: Script expects to be located in the root folder (contents/) next to the +:: folders modules, data etc. +set CONTENT_DIR=%CD%\.. +set BEMANITOOLS_DIR=%CONTENT_DIR%\bemanitools +set MODULES_DIR=%CONTENT_DIR%\modules + +:: Keep that data vanilla, no need to copy these around anymore +:: Just add them to the env PATH so launcher can find the libs and game executable +:: Remark: This also requires admin privileges to propage correctly to launcher +set PATH=^ +%MODULES_DIR%;^ +%BEMANITOOLS_DIR%;^ +%PATH% + +:: Current working dir is the game's root folder +cd /d %CONTENT_DIR% + +%BEMANITOOLS_DIR%\launcher %BEMANITOOLS_DIR%\launcher.xml --config sdvxhook2.conf %* \ No newline at end of file diff --git a/dist/sdvx5/launcher-cn.xml b/dist/sdvx5/launcher-cn.xml new file mode 100644 index 00000000..4ec2939f --- /dev/null +++ b/dist/sdvx5/launcher-cn.xml @@ -0,0 +1,74 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 268435456 + + + info + + + /dev/nvram/ea3-config.xml + + + soundvoltex.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + sdvxhook2-cn.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/sdvx5/launcher.xml b/dist/sdvx5/launcher.xml new file mode 100644 index 00000000..3ae97c1e --- /dev/null +++ b/dist/sdvx5/launcher.xml @@ -0,0 +1,74 @@ + + + + bemanitools_local_fs + + + + + + + + + + + prop/avs-config.xml + 268435456 + + + info + + + /dev/nvram/ea3-config.xml + + + soundvoltex.dll + + + + + + + + + bemanitools/ea3-ident.xml + bemanitools/ea3-license.xml + + + + + + + . + + + dev/nvram + fs + + + + dev/raw + fs + + + + + + + + bemanitools/ea3-service.xml + + + + sdvxhook2.dll + + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/dist/sdvx5/pcbid.xml b/dist/sdvx5/pcbid.xml new file mode 100644 index 00000000..bc50cdee --- /dev/null +++ b/dist/sdvx5/pcbid.xml @@ -0,0 +1,7 @@ + + + + 0101020304050607083F + 0101020304050607083F + + \ No newline at end of file diff --git a/dist/shared/ea3-ident.xml b/dist/shared/ea3-ident.xml new file mode 100644 index 00000000..ae4161ef --- /dev/null +++ b/dist/shared/ea3-ident.xml @@ -0,0 +1,11 @@ + + + + + 000 + A + A + A + 1969032100 + + \ No newline at end of file diff --git a/dist/shared/ea3-license.xml b/dist/shared/ea3-license.xml new file mode 100644 index 00000000..fef35346 --- /dev/null +++ b/dist/shared/ea3-license.xml @@ -0,0 +1,8 @@ + + + + + 0101020304050607083F + 0101020304050607083F + + \ No newline at end of file diff --git a/dist/shared/ea3-service.xml b/dist/shared/ea3-service.xml new file mode 100644 index 00000000..ffaaa437 --- /dev/null +++ b/dist/shared/ea3-service.xml @@ -0,0 +1,7 @@ + + + + + http://localhost + + \ No newline at end of file diff --git a/doc/ddrhook/ddrhook2.md b/doc/ddrhook/ddrhook2.md index 38c0f44d..0cfddcbe 100644 --- a/doc/ddrhook/ddrhook2.md +++ b/doc/ddrhook/ddrhook2.md @@ -9,6 +9,8 @@ The following games are supported by this hook library: * Dance Dance Revolution 2013 * Dance Dance Revolution 2014 * Dance Dance Revolution A +* Dance Dance Revolution A20 +* Dance Dance Revolution A20+ Note that different builds of the same hook library are required to run the different versions. See different distribution packages, e.g. `ddr-12.zip`, diff --git a/src/imports/avs.h b/src/imports/avs.h index ff48a33e..a2d439ec 100644 --- a/src/imports/avs.h +++ b/src/imports/avs.h @@ -4,6 +4,7 @@ #include #include #include +#include enum property_create_flag { PROPERTY_FLAG_READ = 0x1, @@ -26,18 +27,39 @@ enum property_node_traversal { }; enum property_type { - PROPERTY_TYPE_VOID = 1, - PROPERTY_TYPE_S8 = 2, - PROPERTY_TYPE_U8 = 3, - PROPERTY_TYPE_S16 = 4, - PROPERTY_TYPE_U16 = 5, - PROPERTY_TYPE_S32 = 6, - PROPERTY_TYPE_U32 = 7, - PROPERTY_TYPE_S64 = 8, - PROPERTY_TYPE_U64 = 9, - PROPERTY_TYPE_BIN = 10, - PROPERTY_TYPE_STR = 11, - PROPERTY_TYPE_BOOL = 52 + PROPERTY_TYPE_VOID = 0x01, + PROPERTY_TYPE_S8 = 0x02, + PROPERTY_TYPE_U8 = 0x03, + PROPERTY_TYPE_S16 = 0x04, + PROPERTY_TYPE_U16 = 0x05, + PROPERTY_TYPE_S32 = 0x06, + PROPERTY_TYPE_U32 = 0x07, + PROPERTY_TYPE_S64 = 0x08, + PROPERTY_TYPE_U64 = 0x09, + PROPERTY_TYPE_BIN = 0x0A, + PROPERTY_TYPE_STR = 0x0B, + PROPERTY_TYPE_IP4 = 0x0C, + PROPERTY_TYPE_TIME = 0x0D, + PROPERTY_TYPE_FLOAT = 0x0E, + PROPERTY_TYPE_DOUBLE = 0x0F, + PROPERTY_TYPE_4U8 = 0x25, + PROPERTY_TYPE_ATTR = 0x2E, + PROPERTY_TYPE_BOOL = 0x34, + + // Missing __type attribute + PROPERTY_TYPE_VOID_WITH_ATTRIBUTES = 0x40 | PROPERTY_TYPE_VOID, + PROPERTY_TYPE_ARRAY_S8 = 0x40 | PROPERTY_TYPE_S8, + PROPERTY_TYPE_ARRAY_U8 = 0x40 | PROPERTY_TYPE_U8, + PROPERTY_TYPE_ARRAY_S16 = 0x40 | PROPERTY_TYPE_S16, + PROPERTY_TYPE_ARRAY_U16 = 0x40 | PROPERTY_TYPE_U16, + PROPERTY_TYPE_ARRAY_S32 = 0x40 | PROPERTY_TYPE_S32, + PROPERTY_TYPE_ARRAY_U32 = 0x40 | PROPERTY_TYPE_U32, + PROPERTY_TYPE_ARRAY_S64 = 0x40 | PROPERTY_TYPE_S64, + PROPERTY_TYPE_ARRAY_U64 = 0x40 | PROPERTY_TYPE_U64, + PROPERTY_TYPE_ARRAY_TIME = 0x40 | PROPERTY_TYPE_TIME, + PROPERTY_TYPE_ARRAY_BOOL = 0x40 | PROPERTY_TYPE_BOOL, + + PROPERTY_TYPE_STR_WITH_ATTRIBUTES = 0x40 | PROPERTY_TYPE_STR, }; struct property; @@ -66,6 +88,7 @@ enum psmap_type { PSMAP_TYPE_STR = 10, PSMAP_TYPE_ATTR = 45, PSMAP_TYPE_BOOL = 50, + PSMAP_TYPE_TERMINATOR = 0xFF, }; #define PSMAP_FLAG_HAVE_DEFAULT 0x01 @@ -102,7 +125,7 @@ struct property_psmap { #define PSMAP_END \ { \ - 0xFF, 0, 0, 0, NULL, 0 \ + PSMAP_TYPE_TERMINATOR, 0, 0, 0, NULL, 0 \ } \ } \ ; @@ -160,6 +183,11 @@ void avs_boot( void avs_shutdown(void); +typedef uint32_t avs_desc; +typedef int avs_error; + +#define AVS_IS_ERROR(x) x < 0 + void log_body_fatal(const char *module, const char *fmt, ...); void log_body_info(const char *module, const char *fmt, ...); void log_body_misc(const char *module, const char *fmt, ...); @@ -187,6 +215,7 @@ int property_insert_read( uint32_t context); int property_mem_write(struct property *prop, void *bytes, int nbytes); void *property_desc_to_buffer(struct property *prop); +avs_error property_query_size(struct property *prop); void property_file_write(struct property *prop, const char *path); int property_set_flag(struct property *prop, int flags, int mask); void property_destroy(struct property *prop); @@ -203,8 +232,8 @@ int property_psmap_export( const struct property_psmap *psmap); struct property_node *property_node_clone( - struct property *new_parent, - int unk0, + struct property *parent_prop, + struct property_node *parent_node, struct property_node *src, bool deep); struct property_node *property_node_create( @@ -226,15 +255,73 @@ void property_node_remove(struct property_node *node); enum property_type property_node_type(struct property_node *node); struct property_node *property_node_traversal( struct property_node *node, enum property_node_traversal direction); -void property_node_datasize(struct property_node *node); +int property_node_datasize(struct property_node *node); +avs_error property_node_read(struct property_node *node, enum property_type type, void* data, uint32_t data_size); + +static inline void property_remove(struct property *prop, struct property_node *node, const char *path) +{ + struct property_node *cur = property_search(prop, node, path); + while (cur) { + struct property_node *next = property_node_traversal(node, TRAVERSE_NEXT_SEARCH_RESULT); + property_node_remove(cur); + cur = next; + } +} bool std_getenv(const char *key, char *val, uint32_t nbytes); void std_setenv(const char *key, const char *val); -void* avs_fs_open(const char* path, int mode, int flags); +struct avs_stat { + uint64_t st_atime; + uint64_t st_mtime; + uint64_t st_ctime; + uint32_t unk1; + uint32_t filesize; + struct stat padding; +}; + +#if AVS_VERSION <= 1306 +enum avs_file_mode { + AVS_FILE_READ = 0x00, + AVS_FILE_WRITE = 0x01, + AVS_FILE_READ_WRITE = 0x02, + AVS_FILE_CREATE = 0x10, + AVS_FILE_TRUNCATE = 0x20, + AVS_FILE_EXCLUSIVE = 0x80, +}; +#else +enum avs_file_mode { + AVS_FILE_READ = 0x01, + AVS_FILE_WRITE = 0x02, + AVS_FILE_CREATE = 0x10, + AVS_FILE_TRUNCATE = 0x20, + AVS_FILE_EXCLUSIVE = 0x80, +}; +#endif + +enum avs_file_flag { + AVS_FILE_FLAG_SHARE_READ = 0x124, + AVS_FILE_FLAG_SHARE_WRITE = 0x92, +}; + +enum avs_seek_origin { + AVS_SEEK_SET = 0, + AVS_SEEK_CUR = 1, + AVS_SEEK_END = 2, +}; + +avs_desc avs_fs_open(const char *path, uint16_t mode, int flags); +int avs_fs_close(avs_desc desc); +size_t avs_fs_read(avs_desc desc, char *buf, uint32_t sz); +int avs_fs_lseek(avs_desc desc, long pos, int whence); +int avs_fs_lstat(const char *path, struct avs_stat *st); +int avs_fs_copy(const char *src, const char *dest); int avs_fs_addfs(void *filesys_struct); int avs_fs_mount( const char *mountpoint, const char *fsroot, const char *fstype, void *data); +avs_desc avs_fs_opendir(const char *path); +const char* avs_fs_readdir(avs_desc dir); +void avs_fs_closedir(avs_desc dir); bool avs_is_active(); diff --git a/src/imports/dwarfstack.h b/src/imports/dwarfstack.h new file mode 100644 index 00000000..ba2d23c6 --- /dev/null +++ b/src/imports/dwarfstack.h @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2013-2019 Hannes Domani + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef __DWARFSTACK_H__ +#define __DWARFSTACK_H__ + +#include + + +#if defined(DWST_STATIC) +#define EXPORT +#elif defined(DWST_SHARED) +#define EXPORT __declspec(dllexport) +#else +#define EXPORT __declspec(dllimport) +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +// dwstCallback(): callback function +// addr: stack address +// filename: source file location +// lineno: line number +// funcname: function name +// context: user-provided pointer (callbackContext) +// columnno: column number +typedef void dwstCallback( + uint64_t addr,const char *filename,int lineno,const char *funcname, + void *context,int columnno ); + +typedef void dwstCallbackW( + uint64_t addr,const wchar_t *filename,int lineno,const char *funcname, + void *context,int columnno ); + +// special values for lineno: + +// DWST_BASE_ADDR: inform about the used image base address +// (important in case it's not the same as the preferred image base address) +// addr: used image base address +// filename: executable location +#define DWST_BASE_ADDR 0 + +// DWST_NO_DBG_SYM: no debug information available +// addr: stack address +// filename: executable location +#define DWST_NO_DBG_SYM -1 + +// DWST_NO_SRC_FILE: no source file information available +// addr: stack address +// filename: executable location +#define DWST_NO_SRC_FILE -2 + +// DWST_NOT_FOUND: no information available (invalid address?) +// addr: stack address +// filename: executable location +#define DWST_NOT_FOUND -3 + + +// dwstOfFile(): stack information of file +// name: executable location +// imageBase: used image base address +// addr: stack addresses +// count: number of addresses +// callbackFunc: callback function +// callbackContext: user-provided pointer (context) +// (for example see examples/addr2line/) +EXPORT int dwstOfFile( + const char *name,uint64_t imageBase, + uint64_t *addr,int count, + dwstCallback *callbackFunc,void *callbackContext ); + +EXPORT int dwstOfFileW( + const wchar_t *name,uint64_t imageBase, + uint64_t *addr,int count, + dwstCallbackW *callbackFunc,void *callbackContext ); + + +// dwstOfProcess(): stack information of current process +// addr: stack addresses +// count: number of addresses +// callbackFunc: callback function +// callbackContext: user-provided pointer (context) +EXPORT int dwstOfProcess( + uintptr_t *addr,int count, + dwstCallback *callbackFunc,void *callbackContext ); + +EXPORT int dwstOfProcessW( + uintptr_t *addr,int count, + dwstCallbackW *callbackFunc,void *callbackContext ); + + +// dwstOfLocation(): stack information of current location +// callbackFunc: callback function +// callbackContext: user-provided pointer (context) +// (for example see examples/location/) +EXPORT int dwstOfLocation( + dwstCallback *callbackFunc,void *callbackContext ); + +EXPORT int dwstOfLocationW( + dwstCallbackW *callbackFunc,void *callbackContext ); + + +// dwstOfException(): stack information of exception +// context: ContextRecord of exception +// callbackFunc: callback function +// callbackContext: user-provided pointer (context) +// (for example see examples/exception/) +EXPORT int dwstOfException( + void *context, + dwstCallback *callbackFunc,void *callbackContext ); + +EXPORT int dwstOfExceptionW( + void *context, + dwstCallbackW *callbackFunc,void *callbackContext ); + + +// dwstExceptionDialog(): show dialog on unhandled exception +// extraInfo: extra information shown in dialog +// (for example see examples/exception-dialog/) +EXPORT void dwstExceptionDialog( + const char *extraInfo ); + +EXPORT void dwstExceptionDialogW( + const wchar_t *extraInfo ); + + +#ifndef DWST_STATIC +// dwstDemangle(): demangle gcc style c++ symbols +// mangled: mangled name +// demangled: demangled name +// length: size of demangled buffer +EXPORT size_t dwstDemangle( + const char *mangled, + char *demangled,size_t length ); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/imports/import_32_0_avs.def b/src/imports/import_32_0_avs.def index cb2ea9d1..273e5be8 100644 --- a/src/imports/import_32_0_avs.def +++ b/src/imports/import_32_0_avs.def @@ -2,6 +2,12 @@ LIBRARY libavs-win32 EXPORTS avs_boot + avs_fs_close + avs_fs_copy + avs_fs_lseek + avs_fs_lstat + avs_fs_open + avs_fs_read avs_net_ctrl avs_shutdown avs_thread_create @@ -26,6 +32,7 @@ EXPORTS property_node_clone property_node_create property_node_name + property_node_read property_node_refer property_node_remove property_node_type diff --git a/src/imports/import_32_1002_avs.def b/src/imports/import_32_1002_avs.def index 6d1fd136..e2ff5ae5 100644 --- a/src/imports/import_32_1002_avs.def +++ b/src/imports/import_32_1002_avs.def @@ -2,6 +2,15 @@ LIBRARY libavs-win32 EXPORTS avs_boot + avs_fs_close + avs_fs_copy + avs_fs_lseek + avs_fs_lstat + avs_fs_open + avs_fs_read + avs_fs_opendir + avs_fs_readdir + avs_fs_closedir avs_net_ctrl avs_shutdown avs_thread_create @@ -27,11 +36,13 @@ EXPORTS property_node_create property_node_datasize property_node_name + property_node_read property_node_refer property_node_remove property_node_type property_node_traversal property_node_refdata + property_query_size property_psmap_export property_psmap_import std_getenv diff --git a/src/imports/import_32_1101_avs.def b/src/imports/import_32_1101_avs.def index cfc6f9b5..10c59e4f 100644 --- a/src/imports/import_32_1101_avs.def +++ b/src/imports/import_32_1101_avs.def @@ -2,6 +2,15 @@ LIBRARY libavs-win32 EXPORTS avs_boot @22 NONAME + avs_fs_close @60 NONAME + avs_fs_copy @63 NONAME + avs_fs_lseek @70 NONAME + avs_fs_lstat @71 NONAME + avs_fs_open @75 NONAME + avs_fs_read @77 NONAME + avs_fs_opendir @76 NONAME + avs_fs_readdir @78 NONAME + avs_fs_closedir @61 NONAME avs_net_ctrl @107 NONAME avs_shutdown @140 NONAME avs_thread_create @156 NONAME @@ -19,8 +28,15 @@ EXPORTS property_insert_read @255 NONAME property_node_create @266 NONAME property_node_datasize @267 NONAME + property_node_name @274 NONAME + property_node_read @276 NONAME property_node_refer @278 NONAME property_node_remove @279 NONAME + property_node_type @282 NONAME + property_node_clone @280 NONAME + property_node_traversal @282 NONAME + property_node_refdata @277 NONAME + property_query_size @290 NONAME property_psmap_import @288 NONAME property_psmap_export @287 NONAME property_read_query_memsize @291 NONAME diff --git a/src/imports/import_32_1304_avs.def b/src/imports/import_32_1304_avs.def index 489944a7..f83d5a5f 100644 --- a/src/imports/import_32_1304_avs.def +++ b/src/imports/import_32_1304_avs.def @@ -2,7 +2,15 @@ LIBRARY libavs-win32 EXPORTS avs_boot @237 NONAME + avs_fs_close @276 NONAME + avs_fs_copy @283 NONAME + avs_fs_lseek @16 NONAME + avs_fs_lstat @97 NONAME avs_fs_open @178 NONAME + avs_fs_read @306 NONAME + avs_fs_opendir @216 NONAME + avs_fs_readdir @130 NONAME + avs_fs_closedir @131 NONAME avs_net_ctrl @15 NONAME avs_shutdown @333 NONAME avs_thread_create @183 NONAME @@ -19,8 +27,15 @@ EXPORTS property_insert_read @23 NONAME property_node_create @316 NONAME property_node_datasize @249 NONAME + property_node_name @255 NONAME + property_node_read @2 NONAME property_node_refer @268 NONAME property_node_remove @129 NONAME + property_node_type @329 NONAME + property_node_clone @130 NONAME + property_node_traversal @93 NONAME + property_node_refdata @330 NONAME == XC058ba5000151 + property_query_size @250 NONAME == XC058ba5000101 property_psmap_import @102 NONAME property_psmap_export @110 NONAME property_read_query_memsize @100 NONAME diff --git a/src/imports/import_32_1306_avs-ea3.def b/src/imports/import_32_1306_avs-ea3.def new file mode 100644 index 00000000..2606209e --- /dev/null +++ b/src/imports/import_32_1306_avs-ea3.def @@ -0,0 +1,5 @@ +LIBRARY libavs-win32-ea3 + +EXPORTS + ea3_boot @94 NONAME + ea3_shutdown @97 NONAME diff --git a/src/imports/import_32_1306_avs.def b/src/imports/import_32_1306_avs.def new file mode 100644 index 00000000..f963ec88 --- /dev/null +++ b/src/imports/import_32_1306_avs.def @@ -0,0 +1,44 @@ +LIBRARY libavs-win32 + +EXPORTS + avs_boot @237 NONAME == XC058ba50000f4 + avs_fs_close @276 NONAME == XC058ba500011b + avs_fs_copy @283 NONAME == XC058ba5000122 + avs_fs_lseek @16 NONAME == XC058ba500000f + avs_fs_lstat @97 NONAME == XC058ba5000063 + avs_fs_open @178 NONAME == XC058ba50000b6 + avs_fs_read @306 NONAME == XC058ba5000139 + avs_fs_opendir @216 NONAME == XC058ba50000dd + avs_fs_readdir @130 NONAME == XC058ba5000086 + avs_fs_closedir @131 NONAME == XC058ba5000087 + avs_net_ctrl @15 NONAME == XC058ba500000e + avs_shutdown @333 NONAME == XC058ba5000154 + avs_thread_create @183 NONAME == XC058ba50000bb + avs_thread_destroy @76 NONAME == XC058ba500004e + avs_thread_exit @147 NONAME == XC058ba5000097 + avs_thread_join @92 NONAME == XC058ba500005e + log_body_misc @44 NONAME == XC058ba500002d + log_body_info @339 NONAME == XC058ba500015a + log_body_warning @219 NONAME == XC058ba50000e1 + log_body_fatal @128 NONAME == XC058ba5000084 + property_create @256 NONAME == XC058ba5000107 + property_desc_to_buffer @201 NONAME == XC058ba50000cd + property_destroy @264 NONAME == XC058ba500010f + property_insert_read @23 NONAME == XC058ba5000016 + property_node_create @316 NONAME == XC058ba5000143 + property_node_datasize @249 NONAME == XC058ba5000100 + property_node_name @255 NONAME == XC058ba5000106 + property_node_read @2 NONAME == XC058ba5000001 + property_node_refer @268 NONAME == XC058ba5000113 + property_node_remove @129 NONAME == XC058ba5000085 + property_node_type @329 NONAME == XC058ba5000150 + property_node_clone @252 NONAME == XC058ba5000103 + property_node_traversal @93 NONAME == XC058ba500005f + property_node_refdata @330 NONAME == XC058ba5000151 + property_query_size @250 NONAME == XC058ba5000101 + property_psmap_import @102 NONAME == XC058ba5000068 + property_psmap_export @110 NONAME == XC058ba5000071 + property_read_query_memsize @100 NONAME == XC058ba5000066 + property_search @244 NONAME == XC058ba50000fb + std_getenv @226 NONAME == XC058ba50000e8 + std_setenv @114 NONAME == XC058ba5000075 diff --git a/src/imports/import_32_1403_avs.def b/src/imports/import_32_1403_avs.def index 32d68b11..de171c12 100644 --- a/src/imports/import_32_1403_avs.def +++ b/src/imports/import_32_1403_avs.def @@ -2,6 +2,15 @@ LIBRARY libavs-win32 EXPORTS avs_boot @298 NONAME + avs_fs_close @573 NONAME == XC0bbe97000119 + avs_fs_copy @573 NONAME == XC0bbe97000120 + avs_fs_lseek @573 NONAME == + avs_fs_lstat @573 NONAME == XC0bbe9700005f + avs_fs_open @573 NONAME == XC0bbe970000b3 + avs_fs_read @573 NONAME == + avs_fs_opendir @573 NONAME == XC0bbe970000db + avs_fs_readdir @573 NONAME == + avs_fs_closedir @573 NONAME == avs_net_ctrl @100 NONAME avs_shutdown @299 NONAME avs_thread_create @6 NONAME @@ -15,7 +24,14 @@ EXPORTS property_desc_to_buffer @131 NONAME property_destroy @130 NONAME property_insert_read @133 NONAME + property_node_name @573 NONAME == + property_node_read @573 NONAME == property_node_remove @148 NONAME + property_node_type @573 NONAME == + property_node_clone @149 NONAME + property_node_traversal @151 NONAME + property_node_refdata @573 NONAME == + property_query_size @573 NONAME == property_psmap_import @163 NONAME property_psmap_export @164 NONAME property_read_query_memsize @161 NONAME diff --git a/src/imports/import_32_1508_avs.def b/src/imports/import_32_1508_avs.def index 05419ed7..d1625126 100644 --- a/src/imports/import_32_1508_avs.def +++ b/src/imports/import_32_1508_avs.def @@ -5,8 +5,13 @@ EXPORTS avs_fs_close @65 NONAME avs_fs_lseek @59 NONAME avs_fs_lseek64 @60 NONAME + avs_fs_lstat @79 NONAME avs_fs_open @58 NONAME avs_fs_read @61 NONAME + avs_fs_copy @81 NONAME + avs_fs_opendir @72 NONAME == XCd229cc0000f0 + avs_fs_readdir @73 NONAME == XCd229cc0000bb + avs_fs_closedir @74 NONAME == XCd229cc0000b8 avs_net_ctrl @98 NONAME avs_shutdown @286 NONAME avs_thread_create @6 NONAME @@ -22,8 +27,16 @@ EXPORTS property_destroy @128 NONAME property_insert_read @131 NONAME property_node_create @145 NONAME + property_node_name @150 NONAME + property_node_read @154 NONAME == XCd229cc0000f3 property_node_refer @158 NONAME property_node_remove @146 NONAME + property_node_type @151 NONAME == XCd229cc000071 + property_node_clone @147 NONAME + property_node_traversal @149 NONAME + property_node_refdata @148 NONAME == XCd229cc00009f + property_node_datasize @153 NONAME == XCd229cc000083 + property_query_size @142 NONAME == XCd229cc000032 property_psmap_export @162 NONAME property_psmap_import @161 NONAME property_read_query_memsize @159 NONAME diff --git a/src/imports/import_32_1601_avs.def b/src/imports/import_32_1601_avs.def index e260a8c6..74332d48 100644 --- a/src/imports/import_32_1601_avs.def +++ b/src/imports/import_32_1601_avs.def @@ -1,6 +1,15 @@ LIBRARY libavs-win32 EXPORTS + avs_fs_close @65 NONAME + avs_fs_copy @81 NONAME + avs_fs_lseek @59 NONAME + avs_fs_lstat @79 NONAME + avs_fs_open @58 NONAME + avs_fs_read @61 NONAME + avs_fs_opendir @72 NONAME == XCnbrep7000047 + avs_fs_readdir @73 NONAME == XCnbrep7000048 + avs_fs_closedir @74 NONAME == XCnbrep7000049 avs_thread_create @5 NONAME avs_thread_destroy @7 NONAME avs_thread_exit @11 NONAME @@ -12,7 +21,15 @@ EXPORTS property_insert_read @128 NONAME property_search @141 NONAME property_node_create @142 NONAME + property_node_name @147 NONAME == XCnbrep7000092 property_node_remove @143 NONAME + property_node_type @148 NONAME == XCnbrep7000093 + property_node_clone @144 NONAME + property_node_traversal @146 NONAME + property_node_refdata @145 NONAME == XCnbrep7000090 + property_node_datasize @150 NONAME == XCnbrep7000095 + property_node_read @151 NONAME == XCnbrep7000096 + property_query_size @139 NONAME == XCnbrep700008a property_node_refer @155 NONAME property_read_query_memsize @156 NONAME property_psmap_export @159 NONAME diff --git a/src/imports/import_32_1603_avs.def b/src/imports/import_32_1603_avs.def index 98f5fe7a..21f55c1e 100644 --- a/src/imports/import_32_1603_avs.def +++ b/src/imports/import_32_1603_avs.def @@ -1,6 +1,15 @@ LIBRARY libavs-win32 EXPORTS + avs_fs_close @86 NONAME == XCnbrep7000055 + avs_fs_copy @102 NONAME == XCnbrep7000065 + avs_fs_lseek @80 NONAME == XCnbrep700004f + avs_fs_lstat @100 NONAME == XCnbrep7000063 + avs_fs_open @79 NONAME == XCnbrep700004e + avs_fs_read @82 NONAME == XCnbrep7000051 + avs_fs_opendir @93 NONAME == XCnbrep700005c + avs_fs_readdir @94 NONAME == XCnbrep700005d + avs_fs_closedir @95 NONAME == XCnbrep700005e avs_thread_create @5 NONAME avs_thread_destroy @7 NONAME avs_thread_exit @11 NONAME @@ -12,7 +21,15 @@ EXPORTS property_insert_read @149 NONAME property_search @162 NONAME property_node_create @163 NONAME + property_node_name @168 NONAME == XCnbrep70000a7 property_node_remove @164 NONAME + property_node_type @169 NONAME == XCnbrep70000a8 + property_node_clone @165 NONAME + property_node_traversal @167 NONAME + property_node_refdata @166 NONAME == XCnbrep70000a5 + property_node_datasize @171 NONAME == XCnbrep70000aa + property_query_size @160 NONAME == XCnbrep700009f + property_node_read @172 NONAME == XCnbrep70000ab property_node_refer @176 NONAME property_read_query_memsize @177 NONAME property_psmap_import @179 NONAME diff --git a/src/imports/import_32_1700_avs.def b/src/imports/import_32_1700_avs.def index d8944d9b..7dc4eaa8 100644 --- a/src/imports/import_32_1700_avs.def +++ b/src/imports/import_32_1700_avs.def @@ -6,7 +6,16 @@ EXPORTS avs_thread_exit @11 NONAME avs_thread_join @12 NONAME avs_fs_addfs @73 NONAME + avs_fs_close @86 NONAME == XCgsqzn0000055 + avs_fs_copy @102 NONAME == XCgsqzn0000065 + avs_fs_lseek @80 NONAME == XCgsqzn000004f + avs_fs_lstat @100 NONAME == XCgsqzn0000063 avs_fs_mount @76 NONAME + avs_fs_open @79 NONAME == XCgsqzn000004e + avs_fs_read @82 NONAME == XCgsqzn0000051 + avs_fs_opendir @93 NONAME == XCgsqzn000005c + avs_fs_readdir @94 NONAME == XCgsqzn000005d + avs_fs_closedir @95 NONAME == XCgsqzn000005e avs_net_ctrl @119 NONAME property_create @145 NONAME property_destroy @146 NONAME @@ -14,7 +23,15 @@ EXPORTS property_insert_read @149 NONAME property_search @162 NONAME property_node_create @163 NONAME + property_node_name @168 NONAME == XCgsqzn00000a7 property_node_remove @164 NONAME + property_node_type @169 NONAME == XCgsqzn00000a8 + property_node_clone @165 NONAME + property_node_traversal @167 NONAME + property_node_refdata @166 NONAME == XCgsqzn00000a5 + property_node_datasize @171 NONAME == XCgsqzn00000aa + property_node_read @172 NONAME == XCgsqzn00000ab + property_query_size @160 NONAME == XCgsqzn000009f property_node_refer @176 NONAME property_read_query_memsize @177 NONAME property_psmap_import @179 NONAME diff --git a/src/imports/import_32_803_avs.def b/src/imports/import_32_803_avs.def index a7f59b51..37f2b3e6 100644 --- a/src/imports/import_32_803_avs.def +++ b/src/imports/import_32_803_avs.def @@ -2,6 +2,12 @@ LIBRARY libavs-win32 EXPORTS avs_boot + avs_fs_close + avs_fs_copy + avs_fs_lseek + avs_fs_lstat + avs_fs_open + avs_fs_read avs_net_ctrl avs_shutdown avs_thread_create @@ -27,6 +33,7 @@ EXPORTS property_node_create property_node_datasize property_node_name + property_node_read property_node_refer property_node_remove property_node_type diff --git a/src/imports/import_32_indep_dwarfstack.def b/src/imports/import_32_indep_dwarfstack.def new file mode 100644 index 00000000..71f1aaf5 --- /dev/null +++ b/src/imports/import_32_indep_dwarfstack.def @@ -0,0 +1,13 @@ +LIBRARY dwarfstack + +EXPORTS + dwstOfFile @ 441 + dwstOfFileW @ 443 + dwstOfProcess @ 446 + dwstOfProcessW @ 448 + dwstOfLocation @ 444 + dwstOfLocationW @ 445 + dwstOfException @ 438 + dwstOfExceptionW @ 440 + dwstExceptionDialog @ 436 + dwstExceptionDialogW @ 437 \ No newline at end of file diff --git a/src/imports/import_64_1508_avs.def b/src/imports/import_64_1508_avs.def index bc9fbf06..6aeaba1d 100644 --- a/src/imports/import_64_1508_avs.def +++ b/src/imports/import_64_1508_avs.def @@ -3,10 +3,15 @@ LIBRARY libavs-win64 EXPORTS avs_boot @285 NONAME avs_fs_close @65 NONAME + avs_fs_copy @81 NONAME avs_fs_lseek @59 NONAME avs_fs_lseek64 @60 NONAME + avs_fs_lstat @79 NONAME avs_fs_open @58 NONAME avs_fs_read @61 NONAME + avs_fs_opendir @72 NONAME == XCd229cc0000f0 + avs_fs_readdir @73 NONAME == XCd229cc0000bb + avs_fs_closedir @74 NONAME == XCd229cc0000b8 avs_net_ctrl @98 NONAME avs_shutdown @286 NONAME avs_thread_create @6 NONAME @@ -22,8 +27,16 @@ EXPORTS property_destroy @128 NONAME property_insert_read @131 NONAME property_node_create @145 NONAME + property_node_name @150 NONAME + property_node_read @154 NONAME == XCd229cc0000f3 property_node_refer @158 NONAME property_node_remove @146 NONAME + property_node_type @151 NONAME == XCd229cc000071 + property_node_clone @147 NONAME + property_node_traversal @149 NONAME + property_node_refdata @148 NONAME == XCd229cc00009f + property_node_datasize @153 NONAME == XCd229cc000083 + property_query_size @142 NONAME == XCd229cc000032 property_psmap_export @162 NONAME property_psmap_import @161 NONAME property_read_query_memsize @159 NONAME diff --git a/src/imports/import_64_1509_avs.def b/src/imports/import_64_1509_avs.def index ae6110a2..fde35d65 100644 --- a/src/imports/import_64_1509_avs.def +++ b/src/imports/import_64_1509_avs.def @@ -3,10 +3,15 @@ LIBRARY libavs-win64 EXPORTS avs_boot @285 NONAME avs_fs_close @65 NONAME + avs_fs_copy @81 NONAME avs_fs_lseek @59 NONAME avs_fs_lseek64 @60 NONAME + avs_fs_lstat @78 NONAME avs_fs_open @58 NONAME avs_fs_read @61 NONAME + avs_fs_opendir @573 NONAME == + avs_fs_readdir @573 NONAME == + avs_fs_closedir @573 NONAME == avs_net_ctrl @98 NONAME avs_shutdown @286 NONAME avs_thread_create @6 NONAME @@ -22,8 +27,16 @@ EXPORTS property_destroy @128 NONAME property_insert_read @131 NONAME property_node_create @145 NONAME + property_node_name @573 NONAME == + property_node_read @573 NONAME == + property_query_size @573 NONAME == property_node_refer @158 NONAME property_node_remove @146 NONAME + property_node_type @573 NONAME == + property_node_clone @147 NONAME + property_node_traversal @149 NONAME + property_node_refdata @573 NONAME == + property_node_datasize @573 NONAME == property_psmap_export @162 NONAME property_psmap_import @161 NONAME property_read_query_memsize @159 NONAME diff --git a/src/imports/import_64_1601_avs.def b/src/imports/import_64_1601_avs.def index 5bbe4528..418395f7 100644 --- a/src/imports/import_64_1601_avs.def +++ b/src/imports/import_64_1601_avs.def @@ -1,6 +1,15 @@ LIBRARY libavs-win64 EXPORTS + avs_fs_close @65 NONAME + avs_fs_copy @81 NONAME + avs_fs_lseek @59 NONAME + avs_fs_lstat @79 NONAME + avs_fs_open @58 NONAME + avs_fs_read @61 NONAME + avs_fs_opendir @72 NONAME == XCnbrep7000047 + avs_fs_readdir @73 NONAME == XCnbrep7000048 + avs_fs_closedir @74 NONAME == XCnbrep7000049 avs_thread_create @5 NONAME avs_thread_destroy @7 NONAME avs_thread_exit @11 NONAME @@ -12,7 +21,15 @@ EXPORTS property_insert_read @128 NONAME property_search @141 NONAME property_node_create @142 NONAME + property_node_name @147 NONAME == XCnbrep7000092 property_node_remove @143 NONAME + property_node_type @148 NONAME == XCnbrep7000093 + property_node_clone @144 NONAME + property_node_traversal @146 NONAME + property_node_refdata @145 NONAME == XCnbrep7000090 + property_node_datasize @150 NONAME == XCnbrep7000095 + property_node_read @151 NONAME == XCnbrep7000096 + property_query_size @139 NONAME == XCnbrep700008a property_node_refer @155 NONAME property_read_query_memsize @156 NONAME property_psmap_export @159 NONAME diff --git a/src/imports/import_64_1603_avs.def b/src/imports/import_64_1603_avs.def index 0355922f..b106ab1b 100644 --- a/src/imports/import_64_1603_avs.def +++ b/src/imports/import_64_1603_avs.def @@ -1,6 +1,15 @@ LIBRARY libavs-win64 EXPORTS + avs_fs_close @86 NONAME == XCnbrep7000055 + avs_fs_copy @102 NONAME == XCnbrep7000065 + avs_fs_lseek @80 NONAME == XCnbrep700004f + avs_fs_lstat @100 NONAME == XCnbrep7000063 + avs_fs_open @79 NONAME == XCnbrep700004e + avs_fs_read @82 NONAME == XCnbrep7000051 + avs_fs_opendir @93 NONAME == XCnbrep700005c + avs_fs_readdir @94 NONAME == XCnbrep700005d + avs_fs_closedir @95 NONAME == XCnbrep700005e avs_thread_create @5 NONAME avs_thread_destroy @7 NONAME avs_thread_exit @11 NONAME @@ -12,7 +21,15 @@ EXPORTS property_insert_read @149 NONAME property_search @162 NONAME property_node_create @163 NONAME + property_node_name @168 NONAME == XCnbrep70000a7 property_node_remove @164 NONAME + property_node_type @169 NONAME == XCnbrep70000a8 + property_node_clone @165 NONAME + property_node_traversal @167 NONAME + property_node_refdata @166 NONAME == XCnbrep70000a5 + property_node_datasize @171 NONAME == XCnbrep70000aa + property_node_read @172 NONAME == XCnbrep70000ab + property_query_size @160 NONAME == XCnbrep700009f property_node_refer @176 NONAME property_read_query_memsize @177 NONAME property_psmap_import @179 NONAME diff --git a/src/imports/import_64_1700_avs.def b/src/imports/import_64_1700_avs.def index fe8cc6e6..8cddba8a 100644 --- a/src/imports/import_64_1700_avs.def +++ b/src/imports/import_64_1700_avs.def @@ -6,7 +6,16 @@ EXPORTS avs_thread_exit @11 NONAME avs_thread_join @12 NONAME avs_fs_addfs @73 NONAME + avs_fs_close @86 NONAME == XCgsqzn0000055 + avs_fs_copy @102 NONAME == XCgsqzn0000065 + avs_fs_lseek @80 NONAME == XCgsqzn000004f + avs_fs_lstat @100 NONAME == XCgsqzn0000063 avs_fs_mount @76 NONAME + avs_fs_open @79 NONAME == XCgsqzn000004e + avs_fs_read @82 NONAME == XCgsqzn0000051 + avs_fs_opendir @93 NONAME == XCgsqzn000005c + avs_fs_readdir @94 NONAME == XCgsqzn000005d + avs_fs_closedir @95 NONAME == XCgsqzn000005e avs_net_ctrl @119 NONAME property_create @145 NONAME property_destroy @146 NONAME @@ -14,7 +23,15 @@ EXPORTS property_insert_read @149 NONAME property_search @162 NONAME property_node_create @163 NONAME + property_node_name @168 NONAME == XCgsqzn00000a7 property_node_remove @164 NONAME + property_node_type @169 NONAME == XCgsqzn00000a8 + property_node_clone @165 NONAME + property_node_traversal @167 NONAME + property_node_refdata @166 NONAME == XCgsqzn00000a5 + property_node_datasize @171 NONAME == XCgsqzn00000aa + property_node_read @172 NONAME == XCgsqzn00000ab + property_query_size @160 NONAME == XCgsqzn000009f property_node_refer @176 NONAME property_read_query_memsize @177 NONAME property_psmap_import @179 NONAME diff --git a/src/imports/import_64_indep_dwarfstack.def b/src/imports/import_64_indep_dwarfstack.def new file mode 100644 index 00000000..71f1aaf5 --- /dev/null +++ b/src/imports/import_64_indep_dwarfstack.def @@ -0,0 +1,13 @@ +LIBRARY dwarfstack + +EXPORTS + dwstOfFile @ 441 + dwstOfFileW @ 443 + dwstOfProcess @ 446 + dwstOfProcessW @ 448 + dwstOfLocation @ 444 + dwstOfLocationW @ 445 + dwstOfException @ 438 + dwstOfExceptionW @ 440 + dwstExceptionDialog @ 436 + dwstExceptionDialogW @ 437 \ No newline at end of file diff --git a/src/main/acioemu/icca.c b/src/main/acioemu/icca.c index 134b14fc..e7713e52 100644 --- a/src/main/acioemu/icca.c +++ b/src/main/acioemu/icca.c @@ -511,7 +511,7 @@ static void ac_io_emu_icca_cipher_set_key( resp.cmd.raw[0] = (reader_key >> 24) & 0xFF; resp.cmd.raw[1] = (reader_key >> 16) & 0xFF; resp.cmd.raw[2] = (reader_key >> 8) & 0xFF; - resp.cmd.raw[3] = (reader_key) &0xFF; + resp.cmd.raw[3] = (reader_key) & 0xFF; // so I looked these constants up, this isn't actually a secure key // generator it's actually Marsaglia's "KISS" algorithm with different diff --git a/src/main/aciotest/bi2a-iidx.c b/src/main/aciotest/bi2a-iidx.c index bd391cf8..01315675 100644 --- a/src/main/aciotest/bi2a-iidx.c +++ b/src/main/aciotest/bi2a-iidx.c @@ -29,81 +29,79 @@ bool aciotest_bi2a_iidx_handler_update( return false; } - - printf( - "|---------------------------------------|\n" - "| R Y G B Neons B G Y R |\n" - "| %d %d %d %d %d %d %d %d %d |\n" - "|---------------------------------------|\n" - "| NOW PLAYING: %c%c%c%c%c%c%c%c%c |\n" - "|---------------------------------------|\n" - "| Effect %d S1 S2 S3 S4 S5 Test %d|\n" - "|StartP1 %d %02d %02d %02d %02d %02d StartP2 %d|\n" - "| VEFX %d Service %d|\n" - "_________________________________________\n" - "| __ __ |\n" - "| / \\ _ / \\ |\n" - "| | %03d| %d %d %d |%d| %d %d %d | %03d| |\n" - "| \\___/ %d %d %d %d |_| %d %d %d %d \\___/ |\n" - "| |\n" - "|---------------------------------------|\n" - "|---------------------------------------|\n", - - pout.SPOTLIGHT2[0].l_state, - pout.SPOTLIGHT2[1].l_state, - pout.SPOTLIGHT2[2].l_state, - pout.SPOTLIGHT2[3].l_state, - pout.NEONLAMP.l_state, - pout.SPOTLIGHT1[0].l_state, - pout.SPOTLIGHT1[1].l_state, - pout.SPOTLIGHT1[2].l_state, - pout.SPOTLIGHT1[3].l_state, - - pout.SEG16[0], - pout.SEG16[1], - pout.SEG16[2], - pout.SEG16[3], - pout.SEG16[4], - pout.SEG16[5], - pout.SEG16[6], - pout.SEG16[7], - pout.SEG16[8], - - pin.PANEL.y_effect, - pin.SYSTEM.v_test, - - pin.PANEL.y_start1, - pin.SLIDER1.s_val, - pin.SLIDER2.s_val, - pin.SLIDER3.s_val, - pin.SLIDER4.s_val, - pin.SLIDER5.s_val, - pin.PANEL.y_start2, - - pin.PANEL.y_vefx, - pin.SYSTEM.v_service, - - pin.TURNTABLE1, - pin.P1SW2.b_val, - pin.P1SW4.b_val, - pin.P1SW6.b_val, - pin.SYSTEM.v_coin, - pin.P2SW2.b_val, - pin.P2SW4.b_val, - pin.P2SW6.b_val, - pin.TURNTABLE2, - - pin.P1SW1.b_val, - pin.P1SW3.b_val, - pin.P1SW5.b_val, - pin.P1SW7.b_val, - pin.P2SW1.b_val, - pin.P2SW3.b_val, - pin.P2SW5.b_val, - pin.P2SW7.b_val - - ); + "|---------------------------------------|\n" + "| R Y G B Neons B G Y R |\n" + "| %d %d %d %d %d %d %d %d %d |\n" + "|---------------------------------------|\n" + "| NOW PLAYING: %c%c%c%c%c%c%c%c%c |\n" + "|---------------------------------------|\n" + "| Effect %d S1 S2 S3 S4 S5 Test %d|\n" + "|StartP1 %d %02d %02d %02d %02d %02d StartP2 %d|\n" + "| VEFX %d Service %d|\n" + "_________________________________________\n" + "| __ __ |\n" + "| / \\ _ / \\ |\n" + "| | %03d| %d %d %d |%d| %d %d %d | %03d| |\n" + "| \\___/ %d %d %d %d |_| %d %d %d %d \\___/ |\n" + "| |\n" + "|---------------------------------------|\n" + "|---------------------------------------|\n", + + pout.SPOTLIGHT2[0].l_state, + pout.SPOTLIGHT2[1].l_state, + pout.SPOTLIGHT2[2].l_state, + pout.SPOTLIGHT2[3].l_state, + pout.NEONLAMP.l_state, + pout.SPOTLIGHT1[0].l_state, + pout.SPOTLIGHT1[1].l_state, + pout.SPOTLIGHT1[2].l_state, + pout.SPOTLIGHT1[3].l_state, + + pout.SEG16[0], + pout.SEG16[1], + pout.SEG16[2], + pout.SEG16[3], + pout.SEG16[4], + pout.SEG16[5], + pout.SEG16[6], + pout.SEG16[7], + pout.SEG16[8], + + pin.PANEL.y_effect, + pin.SYSTEM.v_test, + + pin.PANEL.y_start1, + pin.SLIDER1.s_val, + pin.SLIDER2.s_val, + pin.SLIDER3.s_val, + pin.SLIDER4.s_val, + pin.SLIDER5.s_val, + pin.PANEL.y_start2, + + pin.PANEL.y_vefx, + pin.SYSTEM.v_service, + + pin.TURNTABLE1, + pin.P1SW2.b_val, + pin.P1SW4.b_val, + pin.P1SW6.b_val, + pin.SYSTEM.v_coin, + pin.P2SW2.b_val, + pin.P2SW4.b_val, + pin.P2SW6.b_val, + pin.TURNTABLE2, + + pin.P1SW1.b_val, + pin.P1SW3.b_val, + pin.P1SW5.b_val, + pin.P1SW7.b_val, + pin.P2SW1.b_val, + pin.P2SW3.b_val, + pin.P2SW5.b_val, + pin.P2SW7.b_val + + ); return true; } diff --git a/src/main/aciotest/main.c b/src/main/aciotest/main.c index a0da1391..4a301c41 100644 --- a/src/main/aciotest/main.c +++ b/src/main/aciotest/main.c @@ -1,14 +1,14 @@ #include #include -#include #include +#include #include #include "aciodrv/device.h" -#include "aciotest/bi2a-sdvx.h" #include "aciotest/bi2a-iidx.h" +#include "aciotest/bi2a-sdvx.h" #include "aciotest/handler.h" #include "aciotest/icca.h" #include "aciotest/kfca.h" @@ -58,25 +58,23 @@ static bool aciotest_assign_handler( if (bi2a_mode == 255) { printf( "Unknown BI2A mode specified, please check your command.\n" - "Using bi2a-sdvx mode as default, press ENTER to continue\n" - ); + "Using bi2a-sdvx mode as default, press ENTER to continue\n"); bi2a_mode = 0; getchar(); } - switch (bi2a_mode) - { - case 0: - handler->init = aciotest_bi2a_sdvx_handler_init; - handler->update = aciotest_bi2a_sdvx_handler_update; - break; - case 1: - handler->init = aciotest_bi2a_iidx_handler_init; - handler->update = aciotest_bi2a_iidx_handler_update; - break; - - default: - break; + switch (bi2a_mode) { + case 0: + handler->init = aciotest_bi2a_sdvx_handler_init; + handler->update = aciotest_bi2a_sdvx_handler_update; + break; + case 1: + handler->init = aciotest_bi2a_iidx_handler_init; + handler->update = aciotest_bi2a_iidx_handler_update; + break; + + default: + break; } return true; } @@ -107,9 +105,9 @@ int main(int argc, char **argv) } if (argc == 4) { - if(!strcmp(argv[3],"bi2a-iidx")) { + if (!strcmp(argv[3], "bi2a-iidx")) { bi2a_mode = 1; - } else if(!strcmp(argv[3],"bi2a-sdvx")) { + } else if (!strcmp(argv[3], "bi2a-sdvx")) { bi2a_mode = 0; } } diff --git a/src/main/avs-util/Module.mk b/src/main/avs-util/Module.mk new file mode 100644 index 00000000..8db06918 --- /dev/null +++ b/src/main/avs-util/Module.mk @@ -0,0 +1,6 @@ +libs += avs-util + +libs_avs-util := \ + +src_avs-util := \ + error.c \ diff --git a/src/main/avs-util/error.c b/src/main/avs-util/error.c new file mode 100644 index 00000000..ab09c014 --- /dev/null +++ b/src/main/avs-util/error.c @@ -0,0 +1,99 @@ +#include "avs-util/error.h" + +#include "util/defs.h" + +struct avs_util_avs_error_str { + avs_error error; + const char *msg; +}; + +static const char *avs_util_error_unknown = "unknown error"; + +// Source: https://github.com/spicetools/spicetools +static const struct avs_util_avs_error_str AVS_UTIL_ERRORS[] = { + {0x80092000, "invalid type"}, + {0x80092001, "type cannot use as array"}, + {0x80092002, "invalid"}, + {0x80092003, "too large data size"}, + {0x80092004, "too small buffer size"}, + {0x80092005, "passcode 0 is not allowed"}, + {0x80092040, "invalid node name"}, + {0x80092041, "invalid attribute name"}, + {0x80092042, "reserved attribute name"}, + {0x80092043, "cannot find node/attribute"}, + {0x80092080, "cannot allocate node"}, + {0x80092081, "cannot allocate node value"}, + {0x80092082, "cannot allocate mdigest for finger-print"}, + {0x80092083, "cannot allocate nodename"}, + {0x800920C0, "node type differs"}, + {0x800920C1, "node type is VOID"}, + {0x800920C2, "node is array"}, + {0x800920C3, "node is not array"}, + {0x80092100, "node is create-disabled"}, + {0x80092101, "node is read-disabled"}, + {0x80092102, "node is write-disabled"}, + {0x80092103, "flag is already locked"}, + {0x80092104, "passcode differs"}, + {0x80092105, "insert_read() is applied to attribute"}, + {0x80092106, "part_write() is applied to attribute"}, + {0x80092107, "MODE_EXTEND flag differs"}, + {0x80092140, "root node already exists"}, + {0x80092141, "attribute cannot have children"}, + {0x80092142, "node/attribute already exists"}, + {0x80092143, "number of nodes exceeds 65535"}, + {0x80092144, "cannot interpret as number"}, + {0x80092145, "property is empty"}, + {0x80092180, "I/O error"}, + {0x80092181, "unexpected EOF"}, + {0x80092182, "unknown format"}, + {0x800921C0, "broken magic"}, + {0x800921C1, "broken metadata"}, + {0x800921C2, "broken databody"}, + {0x800921C3, "invalid type"}, + {0x800921C4, "too large data size"}, + {0x800921C5, "too long node/attribute name"}, + {0x800921C6, "attribute name is too long"}, + {0x800921C7, "node/attribute already exists"}, + {0x80092200, "invalid encoding"}, + {0x80092201, "invalid XML token"}, + {0x80092202, "XML syntax error"}, + {0x80092203, "start tag / end tag mismatch"}, + {0x80092204, "too large node data (__size mismatch)"}, + {0x80092205, "too deep node tree"}, + {0x80092206, "invalid type"}, + {0x80092207, "invalid size"}, + {0x80092208, "invalid count"}, + {0x80092209, "invalid value"}, + {0x8009220A, "invalid node name"}, + {0x8009220B, "invalid attribute name"}, + {0x8009220C, "reserved attribute name"}, + {0x8009220D, "node/attribute already exists"}, + {0x8009220E, "too many elements in node data"}, + {0x80092240, "JSON syntax error"}, + {0x80092241, "invalid JSON literal"}, + {0x80092242, "invalid JSON number"}, + {0x80092243, "invalid JSON string"}, + {0x80092244, "invalid JSON object name"}, + {0x80092245, "object name already exists"}, + {0x80092246, "too long JSON object name"}, + {0x80092247, "too deep JSON object/array nesting"}, + {0x80092248, "cannot convert JSON array to property"}, + {0x80092249, "cannot convert empty JSON object to property"}, + {0x8009224A, "root node already exists"}, + {0x8009224B, "cannot convert root node to TYPE_ARRAY"}, + {0x8009224C, "name represents reserved attribute"}, + {0x80092280, "finger-print differs"}, + {0x800922C0, "operation is not supported"}}; + +const char *avs_util_error_str(avs_error error) +{ + int i; + + for (i = 0; i < lengthof(AVS_UTIL_ERRORS); i++) { + if (error == AVS_UTIL_ERRORS[i].error) { + return AVS_UTIL_ERRORS[i].msg; + } + } + + return avs_util_error_unknown; +} \ No newline at end of file diff --git a/src/main/avs-util/error.h b/src/main/avs-util/error.h new file mode 100644 index 00000000..35988515 --- /dev/null +++ b/src/main/avs-util/error.h @@ -0,0 +1,8 @@ +#ifndef AVS_UTIL_ERROR_H +#define AVS_UTIL_ERROR_H + +#include "imports/avs.h" + +const char *avs_util_error_str(avs_error error); + +#endif \ No newline at end of file diff --git a/src/main/ddrio-async/ddrio.c b/src/main/ddrio-async/ddrio.c index 9b857fd6..fe81f68e 100644 --- a/src/main/ddrio-async/ddrio.c +++ b/src/main/ddrio-async/ddrio.c @@ -28,7 +28,8 @@ typedef uint32_t (*ddr_io_read_pad_t)(void); typedef void (*ddr_io_set_lights_extio_t)(uint32_t extio_lights); typedef void (*ddr_io_set_lights_p3io_t)(uint32_t p3io_lights); typedef void (*ddr_io_set_lights_hdxs_panel_t)(uint32_t hdxs_lights); -typedef void (*ddr_io_set_lights_hdxs_rgb_t)(uint8_t idx, uint8_t r, uint8_t g, uint8_t b); +typedef void (*ddr_io_set_lights_hdxs_rgb_t)( + uint8_t idx, uint8_t r, uint8_t g, uint8_t b); typedef void (*ddr_io_fini_t)(void); static HMODULE _child_ddr_io_module; @@ -66,10 +67,7 @@ static int _io_thread_proc(void *ctx) uint32_t local_tmp; - atomic_store_explicit( - &_io_thread_proc_running, - true, - memory_order_seq_cst); + atomic_store_explicit(&_io_thread_proc_running, true, memory_order_seq_cst); log_info("IO thread running"); @@ -85,18 +83,16 @@ static int _io_thread_proc(void *ctx) local_tmp = _child_ddr_io_read_pad(); atomic_store_explicit( - &_child_ddr_io_data_pad, - local_tmp, - memory_order_relaxed); + &_child_ddr_io_data_pad, local_tmp, memory_order_relaxed); - // Only update outputs when they change gives this loop a major performance boost - // The write calls on a p3io for the outputs are very expensive (~12 ms) as they - // are executed over the ACIO protocol compared to only the input read - // calls (~4 ms) which have a dedicated IOCTL call/endpoint + // Only update outputs when they change gives this loop a major + // performance boost The write calls on a p3io for the outputs are very + // expensive (~12 ms) as they are executed over the ACIO protocol + // compared to only the input read calls (~4 ms) which have a dedicated + // IOCTL call/endpoint local_tmp = atomic_load_explicit( - &_child_ddr_io_data_extio_lights, - memory_order_relaxed); + &_child_ddr_io_data_extio_lights, memory_order_relaxed); if (local_tmp != prev_child_ddr_io_data_extio_lights) { _child_ddr_io_set_lights_extio(local_tmp); @@ -104,9 +100,8 @@ static int _io_thread_proc(void *ctx) } local_tmp = atomic_load_explicit( - &_child_ddr_io_data_p3io_lights, - memory_order_relaxed); - + &_child_ddr_io_data_p3io_lights, memory_order_relaxed); + if (local_tmp != prev_child_ddr_io_data_p3io_lights) { _child_ddr_io_set_lights_p3io(local_tmp); prev_child_ddr_io_data_p3io_lights = local_tmp; @@ -121,22 +116,23 @@ static int _io_thread_proc(void *ctx) time_end = time_get_counter(); total_time = time_get_elapsed_us(time_end - time_start); - log_info("IO thread performance: total iterations %lld, avg. loop cycle time %f us", - loop_counter, ((double) total_time) / loop_counter); + log_info( + "IO thread performance: total iterations %lld, avg. loop cycle time %f " + "us", + loop_counter, + ((double) total_time) / loop_counter); atomic_store_explicit( - &_io_thread_proc_running, - false, - memory_order_seq_cst); + &_io_thread_proc_running, false, memory_order_seq_cst); log_info("IO thread shut down"); return 0; } -static void* _load_function(HMODULE module, const char* name) +static void *_load_function(HMODULE module, const char *name) { - void* ptr; + void *ptr; ptr = GetProcAddress(module, name); @@ -175,13 +171,19 @@ bool ddr_io_init( return false; } - _child_ddr_io_set_loggers = _load_function(_child_ddr_io_module, "ddr_io_set_loggers"); + _child_ddr_io_set_loggers = + _load_function(_child_ddr_io_module, "ddr_io_set_loggers"); _child_ddr_io_init = _load_function(_child_ddr_io_module, "ddr_io_init"); - _child_ddr_io_read_pad = _load_function(_child_ddr_io_module, "ddr_io_read_pad"); - _child_ddr_io_set_lights_extio = _load_function(_child_ddr_io_module, "ddr_io_set_lights_extio"); - _child_ddr_io_set_lights_p3io = _load_function(_child_ddr_io_module, "ddr_io_set_lights_p3io"); - _child_ddr_io_set_lights_hdxs_panel = _load_function(_child_ddr_io_module, "ddr_io_set_lights_hdxs_panel"); - _child_ddr_io_set_lights_hdxs_rgb = _load_function(_child_ddr_io_module, "ddr_io_set_lights_hdxs_rgb"); + _child_ddr_io_read_pad = + _load_function(_child_ddr_io_module, "ddr_io_read_pad"); + _child_ddr_io_set_lights_extio = + _load_function(_child_ddr_io_module, "ddr_io_set_lights_extio"); + _child_ddr_io_set_lights_p3io = + _load_function(_child_ddr_io_module, "ddr_io_set_lights_p3io"); + _child_ddr_io_set_lights_hdxs_panel = + _load_function(_child_ddr_io_module, "ddr_io_set_lights_hdxs_panel"); + _child_ddr_io_set_lights_hdxs_rgb = + _load_function(_child_ddr_io_module, "ddr_io_set_lights_hdxs_rgb"); _child_ddr_io_fini = _load_function(_child_ddr_io_module, "ddr_io_fini"); _child_ddr_io_set_loggers( @@ -199,10 +201,7 @@ bool ddr_io_init( return false; } - atomic_store_explicit( - &_io_thread_proc_loop, - true, - memory_order_seq_cst); + atomic_store_explicit(&_io_thread_proc_loop, true, memory_order_seq_cst); if (!thread_create(_io_thread_proc, NULL, 16384, 0)) { log_warning("Creating IO thread failed"); @@ -224,17 +223,13 @@ uint32_t ddr_io_read_pad(void) void ddr_io_set_lights_extio(uint32_t extio_lights) { atomic_store_explicit( - &_child_ddr_io_data_extio_lights, - extio_lights, - memory_order_relaxed); + &_child_ddr_io_data_extio_lights, extio_lights, memory_order_relaxed); } void ddr_io_set_lights_p3io(uint32_t p3io_lights) { atomic_store_explicit( - &_child_ddr_io_data_p3io_lights, - p3io_lights, - memory_order_relaxed); + &_child_ddr_io_data_p3io_lights, p3io_lights, memory_order_relaxed); } void ddr_io_set_lights_hdxs_panel(uint32_t lights) @@ -249,14 +244,12 @@ void ddr_io_set_lights_hdxs_rgb(uint8_t idx, uint8_t r, uint8_t g, uint8_t b) void ddr_io_fini(void) { - atomic_store_explicit( - &_io_thread_proc_loop, - false, - memory_order_seq_cst); + atomic_store_explicit(&_io_thread_proc_loop, false, memory_order_seq_cst); log_info("Shutting down IO thread and waiting for it to finish..."); - while (atomic_load_explicit(&_io_thread_proc_running, memory_order_seq_cst)) { + while ( + atomic_load_explicit(&_io_thread_proc_running, memory_order_seq_cst)) { Sleep(1); } diff --git a/src/main/geninput/hid-meta-out.c b/src/main/geninput/hid-meta-out.c index 94402835..4f87602a 100644 --- a/src/main/geninput/hid-meta-out.c +++ b/src/main/geninput/hid-meta-out.c @@ -50,8 +50,9 @@ bool hid_meta_out_init( caps_fail: /** * Still allow the device to be used as input. - * Useful for devices like the Sony DUALSHOCK 4, where it indicates it can receive outputs - * but it errors out when trying to initialize an output report. + * Useful for devices like the Sony DUALSHOCK 4, where it indicates it can + * receive outputs but it errors out when trying to initialize an output + * report. */ return true; } @@ -213,7 +214,7 @@ static bool hid_meta_out_init_arrays(struct hid_meta_out *meta) meta->nreports = 0; free(meta->reports); meta->reports = NULL; - + meta->nlights = 0; meta->nbuttons = 0; // Failed out before allocating memory diff --git a/src/main/inject/Module.mk b/src/main/inject/Module.mk index 549f1792..648ea7f3 100644 --- a/src/main/inject/Module.mk +++ b/src/main/inject/Module.mk @@ -1,11 +1,14 @@ exes += inject +imps += dwarfstack ldflags_inject := \ -mconsole \ -lpsapi \ + -ldbghelp \ libs_inject := \ util \ + dwarfstack \ src_inject := \ main.c \ diff --git a/src/main/inject/debugger.c b/src/main/inject/debugger.c index 724ed9ba..77d92444 100644 --- a/src/main/inject/debugger.c +++ b/src/main/inject/debugger.c @@ -11,10 +11,10 @@ #include "inject/debugger.h" #include "inject/logger.h" +#include "util/debug.h" #include "util/log.h" #include "util/mem.h" #include "util/proc.h" -#include "util/signal.h" #include "util/str.h" #define MM_ALLOCATION_GRANULARITY 0x10000 @@ -271,7 +271,7 @@ static uint32_t debugger_loop() "EXCEPTION_DEBUG_EVENT(pid %ld, tid %ld): x%s 0x%p", de.dwProcessId, de.dwThreadId, - signal_exception_code_to_str( + debug_exception_code_to_str( de.u.Exception.ExceptionRecord.ExceptionCode), de.u.Exception.ExceptionRecord.ExceptionAddress); diff --git a/src/main/inject/main.c b/src/main/inject/main.c index bfb6c1be..475e5ab9 100644 --- a/src/main/inject/main.c +++ b/src/main/inject/main.c @@ -16,6 +16,7 @@ #include "inject/version.h" #include "util/cmdline.h" +#include "util/debug.h" #include "util/log.h" #include "util/mem.h" #include "util/os.h" @@ -166,6 +167,7 @@ int main(int argc, char **argv) os_version_log(); + debug_init(); signal_exception_handler_init(); // Cleanup remote process on CTRL+C signal_register_shutdown_handler(signal_shutdown_handler); diff --git a/src/main/launcher/Module.mk b/src/main/launcher/Module.mk index c9dfd078..df84eba0 100644 --- a/src/main/launcher/Module.mk +++ b/src/main/launcher/Module.mk @@ -3,22 +3,35 @@ rc_launcher := launcher.rc ldflags_launcher := \ -mconsole \ + -ldbghelp \ deplibs_launcher := \ avs \ avs-ea3 \ libs_launcher := \ + avs-util \ hook \ util \ + dwarfstack \ src_launcher := \ - avs-context.c \ - ea3-config.c \ + avs-config.c \ + avs.c \ + bootstrap-config.c \ + bootstrap.c \ + debug.c \ + ea3-ident-config.c \ + eamuse-config.c \ + eamuse.c \ + hook.c \ + launcher-config.c \ + launcher.c \ + logger.c \ main.c \ module.c \ options.c \ - property.c \ + property-util.c \ stubs.c \ version.c \ diff --git a/src/main/launcher/avs-config.c b/src/main/launcher/avs-config.c new file mode 100644 index 00000000..879e1dc5 --- /dev/null +++ b/src/main/launcher/avs-config.c @@ -0,0 +1,361 @@ +#define LOG_MODULE "avs-config" + +#include + +#include "avs-util/error.h" + +#include "imports/avs.h" + +#include "launcher/avs-config.h" +#include "launcher/property-util.h" + +#include "util/log.h" +#include "util/str.h" + +#define AVS_CONFIG_ROOT_NODE "/config" + +struct property *avs_config_load(const char *filepath) +{ + struct property *property; + + log_assert(filepath); + + log_info("Loading from file path: %s", filepath); + + property = property_util_load(filepath); + + // Check if root node exists, call already errors if not + avs_config_root_get(property); + + return property; +} + +struct property_node *avs_config_root_get(struct property *property) +{ + struct property_node *node; + + log_assert(property); + + node = property_search(property, 0, AVS_CONFIG_ROOT_NODE); + + if (node == NULL) { + log_fatal("Root node " AVS_CONFIG_ROOT_NODE " in AVS config missing"); + } + + return node; +} + +void avs_config_fs_root_device_get( + struct property_node *node, char *buffer, size_t size) +{ + struct property_node *device_node; + avs_error error; + + log_assert(node); + + device_node = property_search(NULL, node, "fs/root/device"); + + if (device_node == NULL) { + log_fatal("Could not find node fs/root/device AVS config"); + } + + error = property_node_read(device_node, PROPERTY_TYPE_STR, buffer, size); + + if (AVS_IS_ERROR(error)) { + log_fatal( + "fs/root/device, property read failed: %s", + avs_util_error_str(error)); + } +} + +void avs_config_mode_product_set(struct property_node *node, bool enable) +{ + log_assert(node); + +#if AVS_VERSION <= 1306 + property_util_node_u8_replace(NULL, node, "mode/product", enable ? 1 : 0); +#else + property_util_node_bool_replace(NULL, node, "mode/product", enable); +#endif +} + +void avs_config_net_raw_set(struct property_node *node, bool enable) +{ + log_assert(node); + +#if AVS_VERSION <= 1306 + property_util_node_u8_replace(NULL, node, "net/enable_raw", enable ? 1 : 0); +#else + property_util_node_bool_replace(NULL, node, "net/enable_raw", enable); +#endif +} + +void avs_config_net_eaudp_set(struct property_node *node, bool enable) +{ + log_assert(node); + +#if AVS_VERSION <= 1306 + property_util_node_u8_replace( + NULL, node, "net/eaudp/enable", enable ? 1 : 0); +#else + property_util_node_bool_replace(NULL, node, "net/eaudp/enable", enable); +#endif +} + +void avs_config_sntp_ea_set(struct property_node *node, bool on) +{ + log_assert(node); + +#if AVS_VERSION <= 1306 + property_util_node_u8_replace(NULL, node, "sntp/ea_on", on ? 1 : 0); +#else + property_util_node_bool_replace(NULL, node, "sntp/ea_on", on); +#endif +} + +void avs_config_log_level_set(struct property_node *node, const char *level) +{ + log_assert(node); + log_assert(level); + +#if AVS_VERSION <= 1306 + uint32_t level_value; + + if (str_eq(level, "fatal")) { + level_value = 1; + } else if (str_eq(level, "warning")) { + level_value = 2; + } else if (str_eq(level, "info")) { + level_value = 3; + } else if (str_eq(level, "misc")) { + level_value = 4; + } else if (str_eq(level, "all")) { + level_value = 4; + } else if (str_eq(level, "disable")) { + level_value = 0; + } else if (str_eq(level, "default")) { + level_value = 4; + } else { + log_fatal("Unknown log level string %s", level); + } + + property_util_node_u32_replace(NULL, node, "log/level", level_value); +#else + property_util_node_str_replace(NULL, node, "log/level", level); +#endif +} + +void avs_config_log_name_set(struct property_node *node, const char *name) +{ + log_assert(node); + log_assert(name); + + property_util_node_str_replace(NULL, node, "log/name", name); +} + +void avs_config_log_file_set(struct property_node *node, const char *file) +{ + log_assert(node); + log_assert(file); + + property_util_node_str_replace(NULL, node, "log/file", file); +} + +void avs_config_log_buffer_size_set(struct property_node *node, uint32_t size) +{ + log_assert(node); + + property_util_node_u32_replace(NULL, node, "log/sz_buf", size); +} + +void avs_config_log_output_delay_set( + struct property_node *node, uint16_t delay_ms) +{ + log_assert(node); + + property_util_node_u16_replace(NULL, node, "log/output_delay", delay_ms); +} + +void avs_config_log_enable_console_set(struct property_node *node, bool enable) +{ + log_assert(node); + +#if AVS_VERSION <= 1306 + property_util_node_u8_replace( + NULL, node, "log/enable_console", enable ? 1 : 0); +#else + property_util_node_bool_replace(NULL, node, "log/enable_console", enable); +#endif +} + +void avs_config_log_enable_sci_set(struct property_node *node, bool enable) +{ + log_assert(node); + +#if AVS_VERSION <= 1306 + property_util_node_u8_replace( + NULL, node, "log/enable_netsci", enable ? 1 : 0); +#else + property_util_node_bool_replace(NULL, node, "log/enable_netsci", enable); +#endif +} + +void avs_config_log_enable_net_set(struct property_node *node, bool enable) +{ + log_assert(node); + +#if AVS_VERSION <= 1306 + property_util_node_u8_replace( + NULL, node, "log/enable_netlog", enable ? 1 : 0); +#else + property_util_node_bool_replace(NULL, node, "log/enable_netlog", enable); +#endif +} + +void avs_config_log_enable_file_set(struct property_node *node, bool enable) +{ + log_assert(node); + +#if AVS_VERSION <= 1306 + property_util_node_u8_replace( + NULL, node, "log/enable_file", enable ? 1 : 0); +#else + property_util_node_bool_replace(NULL, node, "log/enable_file", enable); +#endif +} + +void avs_config_log_rotate_set(struct property_node *node, bool rotate) +{ + log_assert(node); + +#if AVS_VERSION <= 1306 + property_util_node_u8_replace(NULL, node, "log/rotate", rotate ? 1 : 0); +#else + property_util_node_bool_replace(NULL, node, "log/rotate", rotate); +#endif +} + +void avs_config_log_append_set(struct property_node *node, bool append) +{ + log_assert(node); + +#if AVS_VERSION <= 1306 + property_util_node_u8_replace(NULL, node, "log/append", append ? 1 : 0); +#else + property_util_node_bool_replace(NULL, node, "log/append", append); +#endif +} + +void avs_config_log_count_set(struct property_node *node, uint16_t count) +{ + log_assert(node); + + property_util_node_u16_replace(NULL, node, "log/gen", count); +} + +void avs_config_set_log_level( + struct property_node *node, enum log_level loglevel) +{ + const char *str; + + log_assert(node); + + switch (loglevel) { + case LOG_LEVEL_FATAL: + str = "fatal"; + break; + + case LOG_LEVEL_WARNING: + str = "warn"; + break; + + case LOG_LEVEL_INFO: + str = "info"; + break; + + case LOG_LEVEL_MISC: + str = "misc"; + break; + + default: + log_fatal("Unsupported log level: %d", loglevel); + break; + } + + avs_config_log_level_set(node, str); +} + +void avs_config_local_fs_path_dev_nvram_and_raw_set( + struct property_node *node, const char *dev_nvram_raw_path) +{ + char path_dev_raw[MAX_PATH]; + char path_dev_nvram[MAX_PATH]; + + struct property_node *fs_node; + struct property_node *mounttable_node; + struct property_node *vfs_node; + + log_assert(node); + log_assert(dev_nvram_raw_path); + + str_cpy(path_dev_raw, sizeof(path_dev_raw), dev_nvram_raw_path); + str_cat(path_dev_raw, sizeof(path_dev_raw), "/dev/raw"); + + str_cpy(path_dev_nvram, sizeof(path_dev_nvram), dev_nvram_raw_path); + str_cat(path_dev_nvram, sizeof(path_dev_nvram), "/dev/nvram"); + + fs_node = property_search(NULL, node, "fs"); + + if (!fs_node) { + log_fatal("Cannot find 'fs' node in avs config"); + } + + // Check if "new" mounttable config is used for dev/nvram and dev/raw or + // legacy config + if (property_search(NULL, fs_node, "mounttable")) { + property_remove(NULL, fs_node, "mounttable"); + + mounttable_node = property_node_create( + NULL, fs_node, PROPERTY_TYPE_VOID, "mounttable"); + + vfs_node = property_node_create( + NULL, mounttable_node, PROPERTY_TYPE_VOID, "vfs"); + + property_node_create( + NULL, vfs_node, PROPERTY_TYPE_ATTR, "name", "boot"); + property_node_create( + NULL, vfs_node, PROPERTY_TYPE_ATTR, "fstype", "fs"); + property_node_create( + NULL, vfs_node, PROPERTY_TYPE_ATTR, "src", path_dev_raw); + property_node_create( + NULL, vfs_node, PROPERTY_TYPE_ATTR, "dest", "/dev/raw"); + property_node_create( + NULL, vfs_node, PROPERTY_TYPE_ATTR, "opt", "vf=1,posix=1"); + + vfs_node = property_node_create( + NULL, mounttable_node, PROPERTY_TYPE_VOID, "vfs"); + + property_node_create( + NULL, vfs_node, PROPERTY_TYPE_ATTR, "name", "boot"); + property_node_create( + NULL, vfs_node, PROPERTY_TYPE_ATTR, "fstype", "fs"); + property_node_create( + NULL, vfs_node, PROPERTY_TYPE_ATTR, "src", path_dev_nvram); + property_node_create( + NULL, vfs_node, PROPERTY_TYPE_ATTR, "dest", "/dev/nvram"); + property_node_create( + NULL, vfs_node, PROPERTY_TYPE_ATTR, "opt", "vf=1,posix=1"); + } else { + property_util_node_str_replace( + NULL, fs_node, "nvram/device", path_dev_raw); + property_util_node_str_replace(NULL, fs_node, "nvram/fstype", "fs"); + property_util_node_str_replace( + NULL, fs_node, "nvram/option", "vf=1,posix=1"); + + property_util_node_str_replace( + NULL, fs_node, "raw/device", path_dev_nvram); + property_util_node_str_replace(NULL, fs_node, "raw/fstype", "fs"); + property_util_node_str_replace( + NULL, fs_node, "raw/option", "vf=1,posix=1"); + } +} \ No newline at end of file diff --git a/src/main/launcher/avs-config.h b/src/main/launcher/avs-config.h new file mode 100644 index 00000000..8b964156 --- /dev/null +++ b/src/main/launcher/avs-config.h @@ -0,0 +1,39 @@ +#ifndef LAUNCHER_AVS_CONFIG_H +#define LAUNCHER_AVS_CONFIG_H + +#include "imports/avs.h" + +#include "launcher/bootstrap-config.h" + +#include "util/log.h" + +struct property *avs_config_load(const char *filepath); +struct property_node *avs_config_root_get(struct property *property); + +void avs_config_fs_root_device_get( + struct property_node *node, char *buffer, size_t size); + +void avs_config_mode_product_set(struct property_node *node, bool enable); +void avs_config_net_raw_set(struct property_node *node, bool enable); +void avs_config_net_eaudp_set(struct property_node *node, bool enable); +void avs_config_sntp_ea_set(struct property_node *node, bool on); +void avs_config_log_level_set(struct property_node *node, const char *level); +void avs_config_log_name_set(struct property_node *node, const char *name); +void avs_config_log_file_set(struct property_node *node, const char *file); +void avs_config_log_buffer_size_set(struct property_node *node, uint32_t size); +void avs_config_log_output_delay_set( + struct property_node *node, uint16_t delay_ms); +void avs_config_log_enable_console_set(struct property_node *node, bool enable); +void avs_config_log_enable_sci_set(struct property_node *node, bool enable); +void avs_config_log_enable_net_set(struct property_node *node, bool enable); +void avs_config_log_enable_file_set(struct property_node *node, bool enable); +void avs_config_log_rotate_set(struct property_node *node, bool rotate); +void avs_config_log_append_set(struct property_node *node, bool append); +void avs_config_log_count_set(struct property_node *node, uint16_t count); + +void avs_config_set_log_level( + struct property_node *node, enum log_level loglevel); +void avs_config_local_fs_path_dev_nvram_and_raw_set( + struct property_node *node, const char *dev_nvram_raw_path); + +#endif \ No newline at end of file diff --git a/src/main/launcher/avs-context.c b/src/main/launcher/avs-context.c deleted file mode 100644 index 1e391db1..00000000 --- a/src/main/launcher/avs-context.c +++ /dev/null @@ -1,72 +0,0 @@ -#include - -#include -#include -#include - -#include "imports/avs.h" - -#include "launcher/avs-context.h" - -#include "util/log.h" - -static void *avs_heap; - -#ifdef AVS_HAS_STD_HEAP -static void *std_heap; -#endif - -void avs_context_init( - struct property_node *config, - uint32_t avs_heap_size, - uint32_t std_heap_size, - avs_log_writer_t log_writer, - void *log_writer_ctx) -{ - avs_heap = VirtualAlloc( - NULL, avs_heap_size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - - if (avs_heap == NULL) { - log_fatal( - "Failed to VirtualAlloc %d byte AVS heap: %08x", - avs_heap_size, - (unsigned int) GetLastError()); - } - -#ifdef AVS_HAS_STD_HEAP - std_heap = VirtualAlloc( - NULL, std_heap_size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - - if (std_heap == NULL) { - log_fatal( - "Failed to VirtualAlloc %d byte \"std\" heap: %08x", - std_heap_size, - (unsigned int) GetLastError()); - } -#endif - -#ifdef AVS_HAS_STD_HEAP - avs_boot( - config, - std_heap, - std_heap_size, - avs_heap, - avs_heap_size, - log_writer, - log_writer_ctx); -#else - /* AVS v2.16.xx and I suppose onward uses a unified heap */ - avs_boot(config, avs_heap, avs_heap_size, NULL, log_writer, log_writer_ctx); -#endif -} - -void avs_context_fini(void) -{ - avs_shutdown(); - -#ifdef AVS_HAS_STD_HEAP - VirtualFree(std_heap, 0, MEM_RELEASE); -#endif - - VirtualFree(avs_heap, 0, MEM_RELEASE); -} diff --git a/src/main/launcher/avs-context.h b/src/main/launcher/avs-context.h deleted file mode 100644 index d4532eb4..00000000 --- a/src/main/launcher/avs-context.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef LAUNCHER_AVS_CONTEXT_H -#define LAUNCHER_AVS_CONTEXT_H - -#include - -#include "imports/avs.h" - -#if AVS_VERSION < 1600 -#define AVS_HAS_STD_HEAP -#endif - -void avs_context_init( - struct property_node *config, - uint32_t avs_heap_size, - uint32_t std_heap_size, - avs_log_writer_t log_writer, - void *log_writer_ctx); -void avs_context_fini(void); - -#endif diff --git a/src/main/launcher/avs.c b/src/main/launcher/avs.c new file mode 100644 index 00000000..16dcbd20 --- /dev/null +++ b/src/main/launcher/avs.c @@ -0,0 +1,307 @@ +#define LOG_MODULE "avs" + +#include + +#include +#include +#include + +#include "imports/avs.h" + +#include "launcher/avs-config.h" +#include "launcher/avs.h" +#include "launcher/logger.h" +#include "launcher/property-util.h" + +#include "util/codepage.h" +#include "util/fs.h" +#include "util/log.h" +#include "util/mem.h" +#include "util/str.h" + +#if AVS_VERSION < 1600 +#define AVS_HAS_STD_HEAP +#endif + +static void *avs_heap; + +#ifdef AVS_HAS_STD_HEAP +static void *std_heap; +#endif + +/* Gratuitous API changes orz */ +static AVS_LOG_WRITER(_avs_context_log_writer, chars, nchars, ctx) +{ + wchar_t *utf16; + char *utf8; + int utf16_len; + int utf8_len; + int result; + + /* Ignore existing NUL terminator */ + + nchars--; + + /* Transcode shit_jis to UTF-8 */ + + utf16_len = MultiByteToWideChar(CP_SHIFT_JIS, 0, chars, nchars, NULL, 0); + + if (utf16_len == 0) { + abort(); + } + + utf16 = xmalloc(sizeof(*utf16) * utf16_len); + result = + MultiByteToWideChar(CP_SHIFT_JIS, 0, chars, nchars, utf16, utf16_len); + + if (result == 0) { + abort(); + } + + utf8_len = + WideCharToMultiByte(CP_UTF8, 0, utf16, utf16_len, NULL, 0, NULL, NULL); + + if (utf8_len == 0) { + abort(); + } + + utf8 = xmalloc(utf8_len + 3); + result = WideCharToMultiByte( + CP_UTF8, 0, utf16, utf16_len, utf8, utf8_len, NULL, NULL); + + if (result == 0) { + abort(); + } + +#if AVS_VERSION >= 1500 + utf8[utf8_len + 0] = '\r'; + utf8[utf8_len + 1] = '\n'; + + utf8_len += 2; +#endif + + // Clean string terminate + utf8[utf8_len] = '\0'; + + // Write to launcher's dedicated logging backend + logger_log_avs_log_message(utf8, utf8_len); + + /* Clean up */ + + free(utf8); + free(utf16); +} + +void avs_fs_assert_root_device_exists(struct property_node *node) +{ + char root_device_path[PATH_MAX]; + char cwd_path[PATH_MAX]; + + avs_config_fs_root_device_get( + node, root_device_path, sizeof(root_device_path)); + getcwd(cwd_path, sizeof(cwd_path)); + + if (!path_exists(root_device_path)) { + log_fatal( + "Root device path '%s' does not exist in current working dir '%s'", + root_device_path, + cwd_path); + } +} + +void avs_fs_mountpoint_dir_create( + struct property_node *node, const char *folder_name) +{ + char fs_path[1024]; + char fs_type[255]; + char device_path[1024]; + struct property_node *fs_node; + int res; + + memset(fs_path, 0, sizeof(fs_path)); + memset(fs_type, 0, sizeof(fs_type)); + + str_cpy(fs_path, sizeof(fs_path), "/fs/"); + str_cat(fs_path, sizeof(fs_path), folder_name); + + fs_node = property_search(NULL, node, fs_path); + + if (!fs_node) { + log_warning( + "Could not find file system node %s in avs configuration", fs_path); + return; + } + + res = property_node_refer( + NULL, + fs_node, + "device", + PROPERTY_TYPE_STR, + device_path, + sizeof(device_path)); + + if (res < 0) { + log_fatal( + "Getting 'device' attribute from avs config entry %s failed", + fs_path); + } + + // 'fstype' attribute is optional and defaults to value 'fs' + if (!property_search(NULL, fs_node, "fstype")) { + if (path_exists(device_path)) { + // skip if exists already + return; + } + + log_misc("Creating avs directory %s", device_path); + + if (!path_mkdir(device_path)) { + log_fatal("Creating directory %s failed", device_path); + } + } else { + res = property_node_refer( + NULL, + fs_node, + "fstype", + PROPERTY_TYPE_STR, + fs_type, + sizeof(fs_type)); + + if (res < 0) { + log_fatal( + "Getting 'fstype' attribute from avs config entry %s failed", + fs_path); + } + + if (!strcmp(fs_type, "fs") || !strcmp(fs_type, "nvram")) { + if (path_exists(device_path)) { + // skip if exists already + return; + } + + log_misc("Creating avs directory %s", device_path); + + if (!path_mkdir(device_path)) { + log_fatal("Creating directory %s failed", device_path); + } + } else { + log_fatal( + "Cannot create folders for unsupported file system type %s of " + "path %s in avs config", + fs_type, + fs_path); + } + } +} + +void avs_init( + struct property_node *node, uint32_t avs_heap_size, uint32_t std_heap_size) +{ + log_assert(node); + log_assert(avs_heap_size > 0); + log_assert(std_heap_size > 0); + + log_info("init"); + + avs_heap = VirtualAlloc( + NULL, avs_heap_size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + + if (avs_heap == NULL) { + log_fatal( + "Failed to VirtualAlloc %d byte AVS heap: %08x", + avs_heap_size, + (unsigned int) GetLastError()); + } + +#ifdef AVS_HAS_STD_HEAP + std_heap = VirtualAlloc( + NULL, std_heap_size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + + if (std_heap == NULL) { + log_fatal( + "Failed to VirtualAlloc %d byte \"std\" heap: %08x", + std_heap_size, + (unsigned int) GetLastError()); + } +#endif + + log_info("Calling avs_boot"); + +#ifdef AVS_HAS_STD_HEAP + avs_boot( + node, + std_heap, + std_heap_size, + avs_heap, + avs_heap_size, + _avs_context_log_writer, + NULL); +#else + /* AVS v2.16.xx and I suppose onward uses a unified heap */ + avs_boot( + node, avs_heap, avs_heap_size, NULL, _avs_context_log_writer, NULL); +#endif + + log_misc("init done"); +} + +void avs_fs_file_copy(const char *src, const char *dst) +{ + struct avs_stat st; + + log_assert(src); + log_assert(dst); + + log_misc("Copying %s to %s...", src, dst); + + if (!avs_fs_lstat(src, &st)) { + log_fatal("File source %s does not exist or is not accessible", src); + } + + if (avs_fs_copy(src, dst) < 0) { + log_fatal("Failed copying file %s to %s", src, dst); + } +} + +void avs_fs_dir_log(const char *path) +{ + const char *name; + + log_assert(path); + + avs_desc dir = avs_fs_opendir(path); + + if (dir < 0) { + log_warning( + "Opening avs dir %s failed, skipping logging contents", path); + } + + log_misc("Contents of %s:", path); + + do { + name = avs_fs_readdir(dir); + + if (name == NULL) { + break; + } + + log_misc("%s", name); + } while (name != NULL); + + avs_fs_closedir(dir); +} + +void avs_fini(void) +{ + log_info("fini"); + + avs_shutdown(); + +#ifdef AVS_HAS_STD_HEAP + VirtualFree(std_heap, 0, MEM_RELEASE); +#endif + + VirtualFree(avs_heap, 0, MEM_RELEASE); + + log_misc("fini done"); +} diff --git a/src/main/launcher/avs.h b/src/main/launcher/avs.h new file mode 100644 index 00000000..a333f36f --- /dev/null +++ b/src/main/launcher/avs.h @@ -0,0 +1,17 @@ +#ifndef LAUNCHER_AVS_H +#define LAUNCHER_AVS_H + +#include + +#include "imports/avs.h" + +void avs_fs_assert_root_device_exists(struct property_node *node); +void avs_fs_mountpoint_dir_create( + struct property_node *node, const char *folder_name); +void avs_init( + struct property_node *node, uint32_t avs_heap_size, uint32_t std_heap_size); +void avs_fs_file_copy(const char *src, const char *dst); +void avs_fs_dir_log(const char *path); +void avs_fini(void); + +#endif diff --git a/src/main/launcher/bootstrap-config.c b/src/main/launcher/bootstrap-config.c new file mode 100644 index 00000000..fa7064e4 --- /dev/null +++ b/src/main/launcher/bootstrap-config.c @@ -0,0 +1,538 @@ +#define LOG_MODULE "bootstrap-config" + +#include + +#include "imports/avs.h" + +#include "launcher/avs-config.h" +#include "launcher/bootstrap-config.h" +#include "launcher/property-util.h" + +#include "util/defs.h" +#include "util/hex.h" +#include "util/log.h" +#include "util/str.h" + +// clang-format off +PSMAP_BEGIN(bootstrap_startup_boot_psmap) +PSMAP_REQUIRED(PSMAP_TYPE_STR, struct bootstrap_boot_config, config_file, + "boot/file") +PSMAP_REQUIRED(PSMAP_TYPE_U32, struct bootstrap_boot_config, avs_heap_size, + "boot/heap_avs") +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_boot_config, std_heap_size, + "boot/heap_std", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_boot_config, mount_table_selector, + "boot/mounttable_selector", "boot") +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_boot_config, watcher_enable, + "boot/watcher", 1) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_boot_config, timemachine_enable, + "boot/timemachine", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_boot_config, launch_config_file, + "boot/launch_path", "/dev/raw/launch.xml") +PSMAP_END + +PSMAP_BEGIN(bootstrap_startup_log_psmap) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_log_config, level, + "log/level", "all") +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_log_config, name, + "log/name", "") +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_log_config, file, + "log/file", "") +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_log_config, bufsz, + "log/sz_buf", 4096) +PSMAP_OPTIONAL(PSMAP_TYPE_U16, struct bootstrap_log_config, output_delay_ms, + "log/output_delay", 10) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_log_config, enable_console, + "log/enable_console", 1) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_log_config, enable_sci, + "log/enable_netsci", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_log_config, enable_net, + "log/enable_netlog", 1) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_log_config, enable_file, + "log/enable_file", 1) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_log_config, rotate, + "log/rotate", 1) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_log_config, append, + "log/append", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_U16, struct bootstrap_log_config, count, + "log/gen", 10) +PSMAP_END + +PSMAP_BEGIN(bootstrap_startup_minidump_psmap) +PSMAP_OPTIONAL(PSMAP_TYPE_U8, struct bootstrap_minidump_config, count, + "minidump/gen", 10) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_minidump_config, continue_, + "minidump/cont_debug", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_minidump_config, log, + "minidump/echo_log", 1) +PSMAP_OPTIONAL(PSMAP_TYPE_U8, struct bootstrap_minidump_config, type, + "minidump/dump_type", 2) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_minidump_config, path, + "minidump/path", "/dev/raw/minidump") +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_minidump_config, symbufsz, + "minidump/sz_symbuf", 32768) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_minidump_config, search_path, + "minidump/search", ".") +PSMAP_END + +PSMAP_BEGIN(bootstrap_startup_module_psmap) +PSMAP_REQUIRED(PSMAP_TYPE_STR, struct bootstrap_module_config, file, + "component/file") +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_module_config, load_type, + "component/load_type", "MEMORY") +PSMAP_END + +PSMAP_BEGIN(bootstrap_startup_dlm_psmap) +/* disabled until we implement PSMAP_TYPE_BIN + PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, ntdll_digest, + "dlml/ntdll/hash", "") + */ +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_dlm_config, size, + "dlml/ntdll/size", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_dlm_config, ift_table, + "dlml/ntdll/ift_table", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_dlm_config, ift_insert, + "dlml/ntdll/insert_ift", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_dlm_config, ift_remove, + "dlml/ntdll/remove_ift", 0) +PSMAP_END + +PSMAP_BEGIN(bootstrap_startup_shield_psmap) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_shield_config, enable, + "shield/enable", 1) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_shield_config, verbose, + "shield/verbose", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_shield_config, use_loadlibrary, + "shield/use_loadlibrary", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_shield_config, logger, + "shield/logger", "") +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_shield_config, sleep_min, + "shield/sleepmin", 10) +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_shield_config, sleep_blur, + "shield/sleepblur", 90) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_shield_config, whitelist_file, + "shield/whitelist", "prop/whitelist.csv") +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_shield_config, tick_sleep, + "shield/ticksleep", 100) +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_shield_config, tick_error, + "shield/tickerror", 1000) +PSMAP_OPTIONAL(PSMAP_TYPE_U8, struct bootstrap_shield_config, overwork_threshold, + "shield/overwork_threshold", 50) +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_shield_config, overwork_delay, + "shield/overwork_delay", 100) +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_shield_config, pause_delay, + "shield/pause_delay", 1000) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_shield_config, unlimited_key, + "shield/unlimited_key", "") +PSMAP_OPTIONAL(PSMAP_TYPE_U16, struct bootstrap_shield_config, killer_port, + "shield_killer/port", 5001) +PSMAP_END + +PSMAP_BEGIN(bootstrap_startup_dongle_psmap) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_dongle_config, license_cn, + "dongle/license", "") +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_dongle_config, account_cn, + "dongle/account", "") +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_dongle_config, driver_dll, + "dongle/pkcs11_driver", "eTPKCS11.dll") +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_dongle_config, disable_gc, + "dongle/disable_gc", 0) +PSMAP_END + +PSMAP_BEGIN(bootstrap_startup_drm_psmap) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_drm_config, dll, + "drm/dll", "") +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_drm_config, fstype, + "drm/fstype", "") +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_drm_config, device, + "drm/device", "") +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_drm_config, mount, + "drm/dst", "/") +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_drm_config, options, + "drm/option", "") +PSMAP_END + +PSMAP_BEGIN(bootstrap_startup_lte_psmap) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_lte_config, enable, + "lte/enable", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_lte_config, config_file, + "lte/file", "/dev/nvram/lte-config.xml") +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_lte_config, unlimited_key, + "lte/unlimited_key", "") +PSMAP_END + +PSMAP_BEGIN(bootstrap_startup_ssl_psmap) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_ssl_config, options, + "ssl/option", "") +PSMAP_END + +PSMAP_BEGIN(bootstrap_startup_esign_psmap) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_esign_config, enable, + "esign/enable", 0) +PSMAP_END + +PSMAP_BEGIN(bootstrap_startup_eamuse_psmap) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_eamuse_config, enable, + "eamuse/enable", 1) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_eamuse_config, sync, + "eamuse/sync", 1) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_eamuse_config, enable_model, + "eamuse/enable_model", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_eamuse_config, config_file, + "eamuse/file", "/dev/nvram/ea3-config.xml") +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_eamuse_config, updatecert_enable, + "eamuse/updatecert_enable", 1) +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_eamuse_config, updatecert_interval, + "eamuse/updatecert_interval", 0) +PSMAP_END + +PSMAP_BEGIN(bootstrap_psmap) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_config, release_code, "/release_code", "") +PSMAP_END +// clang-format on + +#define ROOT_NODE "/config" +#define MODULE_PATH_PREFIX "modules/" + +#define NODE_MISSING_FATAL(subnode) \ + log_fatal("%s/%s: Node missing", ROOT_NODE, subnode); +#define NODE_STARTUP_MISSING_FATAL(profile) \ + log_fatal("%s/startup/%s: Node missing", ROOT_NODE, profile); +#define NODE_PROFILE_MISSING_FATAL(profile, subnode) \ + log_fatal("%s/%s/%s: Node missing", ROOT_NODE, profile, subnode); +#define NODE_PROFILE_LOADING_FATAL(profile, subnode) \ + log_fatal("%s/startup/%s/%s: Node loading", ROOT_NODE, profile, subnode); + +#define DEFAULT_HEAP_SIZE 16777216 + +const char *const inherited_nodes[] = { + "develop", + "default", + "log", + "minidump", + "boot", + "drm", + "ssl", + "eamuse", + "shield", + "esign", + "dongle", + "lte", +}; + +static void _bootstrap_config_profile_node_verify( + struct property_node *node, const char *profile) +{ + struct property_node *profile_node; + + log_assert(node); + log_assert(profile); + + profile_node = property_search(NULL, node, profile); + + if (!profile_node) { + NODE_STARTUP_MISSING_FATAL(profile); + } +} + +static struct property_node * +_bootstrap_config_root_node_get(struct property *property) +{ + struct property_node *root_node; + + log_assert(property); + + root_node = property_search(property, NULL, ROOT_NODE); + + if (!root_node) { + NODE_MISSING_FATAL(""); + } + + return root_node; +} + +static struct property_node * +_bootstrap_config_startup_node_get(struct property_node *node) +{ + struct property_node *startup_node; + + log_assert(node); + + startup_node = property_search(NULL, node, "startup"); + + if (!startup_node) { + NODE_MISSING_FATAL("startup"); + } + + return startup_node; +} + +static void _bootstrap_config_inheritance_resolve( + struct property_node *startup_node, const char *profile_name) +{ + struct property_node *startup_parent_node; + struct property_node *startup_profile_node; + struct property_node *tmp_node; + + char inherit_name[64]; + avs_error error; + + startup_profile_node = property_search(NULL, startup_node, profile_name); + + if (!startup_profile_node) { + log_fatal(ROOT_NODE "/startup/%s: missing", profile_name); + } + + startup_parent_node = startup_profile_node; + + for (;;) { + error = property_node_refer( + NULL, + startup_parent_node, + "inherit@", + PROPERTY_TYPE_ATTR, + inherit_name, + sizeof(inherit_name)); + + if (AVS_IS_ERROR(error)) { + break; + } + + startup_parent_node = property_search(NULL, startup_node, inherit_name); + + if (!startup_parent_node) { + NODE_STARTUP_MISSING_FATAL(inherit_name); + } + + for (int i = 0; i < _countof(inherited_nodes); i++) { + if (property_search(NULL, startup_node, inherited_nodes[i])) { + continue; + } + + tmp_node = + property_search(NULL, startup_parent_node, inherited_nodes[i]); + + if (tmp_node) { + log_misc( + ROOT_NODE "/startup/%s: merging %s...", + inherit_name, + inherited_nodes[i]); + + property_node_clone(NULL, startup_profile_node, tmp_node, TRUE); + } + } + } +} + +static void _bootstrap_config_load_bootstrap_module_app_config( + struct property_node *profile_node, struct bootstrap_module_config *config) +{ + struct property_node *app_node; + + log_assert(profile_node); + log_assert(config); + + app_node = property_search(NULL, profile_node, "component/param"); + + config->app_config = property_util_clone(app_node); +} + +static void _bootstrap_config_load_bootstrap_default_files_config( + const char *profile_name, + struct property_node *profile_node, + struct bootstrap_default_file_config *config) +{ + int i; + int result; + struct property_node *child; + + log_assert(profile_node); + log_assert(config); + + child = property_search(NULL, profile_node, "default/file"); + i = 0; + + while (child) { + if (i >= DEFAULT_FILE_MAX) { + log_warning( + "Currently not supporting more than %d default files, skipping " + "remaining", + i); + break; + } + + result = property_node_refer( + NULL, + child, + "src@", + PROPERTY_TYPE_ATTR, + &config->file[i].src, + sizeof(config->file[i].src)); + + if (result < 0) { + log_fatal( + "Missing src attribute on default file node of profile %s", + profile_name); + } + + result = property_node_refer( + NULL, + child, + "dst@", + PROPERTY_TYPE_ATTR, + &config->file[i].dst, + sizeof(config->file[i].dst)); + + if (result < 0) { + log_fatal( + "Missing dst attribute on default file node of profile %s", + profile_name); + } + + child = property_node_traversal(child, TRAVERSE_NEXT_SEARCH_RESULT); + i++; + } +} + +static void _bootstrap_config_load_bootstrap( + struct property_node *startup_node, + const char *profile, + struct bootstrap_startup_config *config) +{ + struct property_node *profile_node; + + profile_node = property_search(NULL, startup_node, profile); + + if (!profile_node) { + NODE_PROFILE_LOADING_FATAL(profile, ""); + } + + _bootstrap_config_load_bootstrap_default_files_config( + profile, profile_node, &config->default_file); + + if (!property_psmap_import( + NULL, profile_node, &config->boot, bootstrap_startup_boot_psmap)) { + NODE_PROFILE_LOADING_FATAL(profile, "boot"); + } + + if (!property_psmap_import( + NULL, profile_node, &config->log, bootstrap_startup_log_psmap)) { + NODE_PROFILE_LOADING_FATAL(profile, "log"); + } + + if (!property_psmap_import( + NULL, + profile_node, + &config->minidump, + bootstrap_startup_minidump_psmap)) { + NODE_PROFILE_LOADING_FATAL(profile, "minidump"); + } + + if (!property_psmap_import( + NULL, + profile_node, + &config->module, + bootstrap_startup_module_psmap)) { + NODE_PROFILE_LOADING_FATAL(profile, "component"); + } + + _bootstrap_config_load_bootstrap_module_app_config( + profile_node, &config->module); + + if (!property_psmap_import( + NULL, + profile_node, + &config->dlm_ntdll, + bootstrap_startup_dlm_psmap)) { + NODE_PROFILE_LOADING_FATAL(profile, "dlm/ntdll"); + } + + if (!property_psmap_import( + NULL, + profile_node, + &config->shield, + bootstrap_startup_shield_psmap)) { + NODE_PROFILE_LOADING_FATAL(profile, "shield"); + } + + if (!property_psmap_import( + NULL, + profile_node, + &config->dongle, + bootstrap_startup_dongle_psmap)) { + NODE_PROFILE_LOADING_FATAL(profile, "dongle"); + } + + if (!property_psmap_import( + NULL, profile_node, &config->drm, bootstrap_startup_drm_psmap)) { + NODE_PROFILE_LOADING_FATAL(profile, "drm"); + } + + if (!property_psmap_import( + NULL, profile_node, &config->lte, bootstrap_startup_lte_psmap)) { + NODE_PROFILE_LOADING_FATAL(profile, "lte"); + } + + if (!property_psmap_import( + NULL, profile_node, &config->ssl, bootstrap_startup_ssl_psmap)) { + NODE_PROFILE_LOADING_FATAL(profile, "ssl"); + } + + if (!property_psmap_import( + NULL, + profile_node, + &config->esign, + bootstrap_startup_esign_psmap)) { + NODE_PROFILE_LOADING_FATAL(profile, "esign"); + } + + if (!property_psmap_import( + NULL, + profile_node, + &config->eamuse, + bootstrap_startup_eamuse_psmap)) { + NODE_PROFILE_LOADING_FATAL(profile, "eamuse"); + } +} + +void bootstrap_config_init(struct bootstrap_config *config) +{ + log_assert(config); + + memset(config, 0, sizeof(*config)); +} + +void bootstrap_config_load( + struct property *property, + const char *profile, + struct bootstrap_config *config) +{ + struct property_node *root_node; + struct property_node *startup_node; + + log_assert(property); + log_assert(profile); + log_assert(config); + + log_info(ROOT_NODE ": loading..."); + + root_node = _bootstrap_config_root_node_get(property); + + if (!property_psmap_import(NULL, root_node, config, bootstrap_psmap)) { + log_fatal(ROOT_NODE ": loading failed"); + } + + startup_node = _bootstrap_config_startup_node_get(root_node); + + _bootstrap_config_profile_node_verify(startup_node, profile); + + _bootstrap_config_inheritance_resolve(startup_node, profile); + + log_misc(ROOT_NODE "/startup/%s: loading merged result...", profile); + + property_util_node_log(startup_node); + + _bootstrap_config_load_bootstrap(startup_node, profile, &config->startup); + + log_misc("Loading finished"); +} \ No newline at end of file diff --git a/src/main/launcher/bootstrap-config.h b/src/main/launcher/bootstrap-config.h new file mode 100644 index 00000000..596bf93f --- /dev/null +++ b/src/main/launcher/bootstrap-config.h @@ -0,0 +1,139 @@ +#ifndef LAUNCHER_BOOTSTRAP_CONFIG_H +#define LAUNCHER_BOOTSTRAP_CONFIG_H + +#include +#include + +#include "imports/avs.h" + +// should be enough for a while +#define DEFAULT_FILE_MAX 16 + +struct bootstrap_startup_config { + struct bootstrap_default_file_config { + struct bootstrap_default_file { + char src[64]; + char dst[64]; + } file[DEFAULT_FILE_MAX]; + } default_file; + + struct bootstrap_boot_config { + char config_file[64]; + uint32_t avs_heap_size; + uint32_t std_heap_size; + char launch_config_file[64]; + char mount_table_selector[16]; + bool watcher_enable; + bool timemachine_enable; + } boot; + + struct bootstrap_log_config { + char level[8]; + char name[64]; + char file[64]; + uint32_t bufsz; + uint16_t output_delay_ms; + bool enable_console; + bool enable_sci; + bool enable_net; + bool enable_file; + bool rotate; + bool append; + uint16_t count; + } log; + + struct bootstrap_minidump_config { + uint8_t count; + bool continue_; + bool log; + uint8_t type; + char path[64]; + uint32_t symbufsz; + char search_path[64]; + } minidump; + + struct bootstrap_module_config { + char file[64]; + char load_type[64]; + struct property *app_config; + } module; + + struct bootstrap_dlm_config { + char digest[16]; + uint32_t size; + uint32_t ift_table; + uint32_t ift_insert; + uint32_t ift_remove; + }; + + struct bootstrap_dlm_config dlm_ntdll; + + struct bootstrap_shield_config { + bool enable; + bool verbose; + bool use_loadlibrary; + char logger[64]; + uint32_t sleep_min; + uint32_t sleep_blur; + uint32_t tick_sleep; + uint32_t tick_error; + uint8_t overwork_threshold; + uint32_t overwork_delay; + uint32_t pause_delay; + char whitelist_file[64]; + char unlimited_key[10]; + uint16_t killer_port; + } shield; + + struct bootstrap_dongle_config { + char license_cn[32]; + char account_cn[32]; + char driver_dll[16]; + bool disable_gc; + } dongle; + + struct bootstrap_drm_config { + char dll[64]; + char device[64]; + char mount[64]; + char fstype[64]; + char options[64]; + } drm; + + struct bootstrap_lte_config { + bool enable; + char config_file[64]; + char unlimited_key[10]; + } lte; + + struct bootstrap_ssl_config { + char options[64]; + } ssl; + + struct bootstrap_esign_config { + bool enable; + } esign; + + struct bootstrap_eamuse_config { + bool enable; + bool sync; + bool enable_model; + char config_file[64]; + bool updatecert_enable; + uint32_t updatecert_interval; + } eamuse; +}; + +struct bootstrap_config { + char release_code[16]; + struct bootstrap_startup_config startup; +}; + +void bootstrap_config_init(struct bootstrap_config *config); + +void bootstrap_config_load( + struct property *property, + const char *profile, + struct bootstrap_config *config); + +#endif /* LAUNCHER_BOOTSTRAP_CONFIG_H */ diff --git a/src/main/launcher/bootstrap.c b/src/main/launcher/bootstrap.c new file mode 100644 index 00000000..a9123786 --- /dev/null +++ b/src/main/launcher/bootstrap.c @@ -0,0 +1,294 @@ +#define LOG_MODULE "bootstrap" + +#include "launcher/avs-config.h" +#include "launcher/avs.h" +#include "launcher/bootstrap-config.h" +#include "launcher/ea3-ident-config.h" +#include "launcher/eamuse-config.h" +#include "launcher/eamuse.h" +#include "launcher/launcher-config.h" +#include "launcher/logger.h" +#include "launcher/module.h" +#include "launcher/property-util.h" + +#include "util/log.h" +#include "util/str.h" + +static bool _bootstrap_log_property_configs; +static struct module_context _bootstrap_module_context; + +static void _bootstrap_eamuse_ea3_ident_config_inject( + struct property_node *node, const struct ea3_ident_config *ea3_ident_config) +{ + eamuse_config_id_softid_set(node, ea3_ident_config->softid); + eamuse_config_id_hardid_set(node, ea3_ident_config->hardid); + eamuse_config_id_pcbid_set(node, ea3_ident_config->pcbid); + eamuse_config_soft_model_set(node, ea3_ident_config->model); + eamuse_config_soft_dest_set(node, ea3_ident_config->dest); + eamuse_config_soft_spec_set(node, ea3_ident_config->spec); + eamuse_config_soft_rev_set(node, ea3_ident_config->rev); + eamuse_config_soft_ext_set(node, ea3_ident_config->ext); +} + +static void +_bootstrap_avs_config_force_overrides_apply(struct property_node *node) +{ + log_assert(node); + + avs_config_mode_product_set(node, true); + avs_config_net_raw_set(node, true); + avs_config_net_eaudp_set(node, true); + avs_config_sntp_ea_set(node, true); +} + +static void _bootstrap_avs_config_log_overrides_apply( + struct property_node *node, const struct bootstrap_log_config *log_config) +{ + log_assert(node); + log_assert(log_config); + + avs_config_log_level_set(node, log_config->level); + avs_config_log_name_set(node, log_config->name); + avs_config_log_file_set(node, log_config->file); + avs_config_log_buffer_size_set(node, log_config->bufsz); + avs_config_log_output_delay_set(node, log_config->output_delay_ms); + avs_config_log_enable_console_set(node, log_config->enable_console); + avs_config_log_enable_sci_set(node, log_config->enable_sci); + avs_config_log_enable_net_set(node, log_config->enable_net); + avs_config_log_enable_file_set(node, log_config->enable_file); + avs_config_log_rotate_set(node, log_config->rotate); + avs_config_log_append_set(node, log_config->append); + avs_config_log_count_set(node, log_config->count); +} + +static enum logger_level _bootstrap_log_map_level(const char *level) +{ + if (str_eq(level, "fatal")) { + return LOGGER_LEVEL_FATAL; + } else if (str_eq(level, "warning")) { + return LOGGER_LEVEL_WARNING; + } else if (str_eq(level, "info")) { + return LOGGER_LEVEL_INFO; + } else if (str_eq(level, "misc")) { + return LOGGER_LEVEL_MISC; + } else if (str_eq(level, "all")) { + return LOGGER_LEVEL_ALL; + } else if (str_eq(level, "disable")) { + return LOGGER_LEVEL_OFF; + } else if (str_eq(level, "default")) { + return LOGGER_LEVEL_DEFAULT; + } else { + log_fatal("Unknown log level string %s", level); + } +} + +void bootstrap_init(bool log_property_configs) +{ + log_info("init"); + + _bootstrap_log_property_configs = log_property_configs; + + log_misc("init done"); +} + +void bootstrap_log_init(const struct bootstrap_log_config *config) +{ + enum logger_level level; + + log_assert(config); + + log_info("log init"); + + logger_init( + config->file, + config->enable_console, + config->enable_file, + config->rotate, + config->append, + config->count); + + level = _bootstrap_log_map_level(config->level); + logger_level_set(level); + + log_misc("log init done"); +} + +void bootstrap_default_files_create( + const struct bootstrap_default_file_config *config) +{ + log_assert(config); + + log_info("default files create"); + + for (int i = 0; i < DEFAULT_FILE_MAX; i++) { + if (strlen(config->file[i].src) > 0 && + strlen(config->file[i].dst) > 0) { + avs_fs_file_copy(config->file[i].src, config->file[i].dst); + } + } + + log_misc("default files create done"); +} + +void bootstrap_avs_init( + const struct bootstrap_boot_config *config, + const struct bootstrap_log_config *log_config, + struct property_node *override_node) +{ + struct property *property; + struct property_node *node; + + log_assert(config); + log_assert(log_config); + log_assert(override_node); + + log_info("avs init"); + + property = avs_config_load(config->config_file); + node = avs_config_root_get(property); + + property_util_node_merge(property, node, override_node); + + if (_bootstrap_log_property_configs) { + log_misc("avs-config"); + property_util_node_log(node); + } + + _bootstrap_avs_config_force_overrides_apply(node); + _bootstrap_avs_config_log_overrides_apply(node, log_config); + + avs_fs_assert_root_device_exists(node); + + log_misc("Creating AVS file system directories for nvram and raw..."); + + avs_fs_mountpoint_dir_create(node, "nvram"); + avs_fs_mountpoint_dir_create(node, "raw"); + + avs_init(node, config->avs_heap_size, config->std_heap_size); + + property_util_free(property); + + log_misc("avs init done"); +} + +void bootstrap_eamuse_init( + const struct bootstrap_eamuse_config *config, + const struct ea3_ident_config *ea3_ident_config, + struct property_node *override_node) +{ + struct property *property; + struct property_node *node; + + log_assert(config); + log_assert(ea3_ident_config); + log_assert(override_node); + + log_info("eamuse init"); + + if (config->enable) { + property = eamuse_config_avs_load(config->config_file); + node = eamuse_config_root_get(property); + + property_util_node_merge(property, node, override_node); + + _bootstrap_eamuse_ea3_ident_config_inject(node, ea3_ident_config); + + property_util_node_log(node); + + if (_bootstrap_log_property_configs) { + log_misc("eamuse-config"); + property_util_node_log(node); + } + + eamuse_init(node); + + property_util_free(property); + } else { + log_warning("Eamuse disabled"); + } + + log_misc("eamuse init done"); +} + +void bootstrap_module_init( + const struct bootstrap_module_config *module_config, + const struct array *iat_hook_dlls) +{ + log_assert(module_config); + log_assert(iat_hook_dlls); + + log_info("module init"); + + if (iat_hook_dlls->nitems > 0) { + log_info( + "Load game DLL with IAT hooks (%d): %s", + (uint32_t) iat_hook_dlls->nitems, + module_config->file); + + module_with_iat_hooks_init( + &_bootstrap_module_context, module_config->file, iat_hook_dlls); + } else { + log_info("Load game DLL: %s", module_config->file); + + module_init(&_bootstrap_module_context, module_config->file); + } + + log_misc("module init done"); +} + +void bootstrap_module_game_init( + const struct bootstrap_module_config *module_config, + struct ea3_ident_config *ea3_ident_config) +{ + struct property_node *node; + + log_assert(module_config); + log_assert(ea3_ident_config); + + log_info("module game init"); + + node = property_search(module_config->app_config, NULL, "/param"); + + if (!node) { + log_fatal("Missing param node on app-config"); + } + + if (_bootstrap_log_property_configs) { + log_misc("app-config"); + property_util_node_log(node); + } + + module_init_invoke(&_bootstrap_module_context, ea3_ident_config, node); + + log_misc("module game init done"); +} + +void bootstrap_module_game_run() +{ + log_info("module game run"); + + module_main_invoke(&_bootstrap_module_context); +} + +void bootstrap_module_game_fini() +{ + log_info("module game fini"); + + module_fini(&_bootstrap_module_context); +} + +void bootstrap_avs_fini() +{ + log_info("avs fini"); + + avs_fini(); +} + +void bootstrap_eamuse_fini(const struct bootstrap_eamuse_config *config) +{ + log_info("eamuse fini"); + + if (config->enable) { + eamuse_fini(); + } +} \ No newline at end of file diff --git a/src/main/launcher/bootstrap.h b/src/main/launcher/bootstrap.h new file mode 100644 index 00000000..9006bf7e --- /dev/null +++ b/src/main/launcher/bootstrap.h @@ -0,0 +1,32 @@ +#ifndef LAUNCHER_BOOTSTRAP_H +#define LAUNCHER_BOOTSTRAP_H + +#include "launcher/bootstrap-config.h" +#include "launcher/ea3-ident-config.h" + +#include "util/array.h" + +void bootstrap_init(bool log_property_configs); +void bootstrap_log_init(const struct bootstrap_log_config *config); +void bootstrap_default_files_create( + const struct bootstrap_default_file_config *config); +void bootstrap_avs_init( + const struct bootstrap_boot_config *config, + const struct bootstrap_log_config *log_config, + struct property_node *override_node); +void bootstrap_eamuse_init( + const struct bootstrap_eamuse_config *config, + const struct ea3_ident_config *ea3_ident_config, + struct property_node *override_node); +void bootstrap_module_init( + const struct bootstrap_module_config *module_config, + const struct array *iat_hook_dlls); +void bootstrap_module_game_init( + const struct bootstrap_module_config *module_config, + struct ea3_ident_config *ea3_ident_config); +void bootstrap_module_game_run(); +void bootstrap_module_game_fini(); +void bootstrap_avs_fini(); +void bootstrap_eamuse_fini(const struct bootstrap_eamuse_config *config); + +#endif \ No newline at end of file diff --git a/src/main/launcher/debug.c b/src/main/launcher/debug.c new file mode 100644 index 00000000..b8440af2 --- /dev/null +++ b/src/main/launcher/debug.c @@ -0,0 +1,33 @@ + +#define LOG_MODULE "debug" + +#include +#include + +#include "launcher/debug.h" + +#include "util/log.h" + +void debug_remote_debugger_trap() +{ + BOOL res; + + log_info("Waiting until debugger attaches to remote process..."); + + while (true) { + res = FALSE; + + if (!CheckRemoteDebuggerPresent(GetCurrentProcess(), &res)) { + log_fatal( + "CheckRemoteDebuggerPresent failed: %08x", + (unsigned int) GetLastError()); + } + + if (res) { + log_info("Debugger attached, resuming"); + break; + } + + Sleep(1000); + } +} \ No newline at end of file diff --git a/src/main/launcher/debug.h b/src/main/launcher/debug.h new file mode 100644 index 00000000..f57ca8ba --- /dev/null +++ b/src/main/launcher/debug.h @@ -0,0 +1,6 @@ +#ifndef LAUNCHER_DEBUG_H +#define LAUNCHER_DEBUG_H + +void debug_remote_debugger_trap(); + +#endif \ No newline at end of file diff --git a/src/main/launcher/ea3-config.c b/src/main/launcher/ea3-config.c deleted file mode 100644 index 684ba466..00000000 --- a/src/main/launcher/ea3-config.c +++ /dev/null @@ -1,190 +0,0 @@ -#include - -#include "imports/avs.h" - -#include "launcher/ea3-config.h" -#include "launcher/module.h" - -#include "util/defs.h" -#include "util/hex.h" -#include "util/log.h" -#include "util/str.h" - -PSMAP_BEGIN(ea3_ident_psmap) -PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct ea3_ident, softid, "/ea3/id/softid", "") -PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct ea3_ident, hardid, "/ea3/id/hardid", "") -PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct ea3_ident, pcbid, "/ea3/id/pcbid", "") -PSMAP_REQUIRED(PSMAP_TYPE_STR, struct ea3_ident, model, "/ea3/soft/model") -PSMAP_REQUIRED(PSMAP_TYPE_STR, struct ea3_ident, dest, "/ea3/soft/dest") -PSMAP_REQUIRED(PSMAP_TYPE_STR, struct ea3_ident, spec, "/ea3/soft/spec") -PSMAP_REQUIRED(PSMAP_TYPE_STR, struct ea3_ident, rev, "/ea3/soft/rev") -PSMAP_REQUIRED(PSMAP_TYPE_STR, struct ea3_ident, ext, "/ea3/soft/ext") -PSMAP_END - -void ea3_ident_init(struct ea3_ident *ident) -{ - memset(ident, 0, sizeof(*ident)); -} - -bool ea3_ident_from_property( - struct ea3_ident *ident, struct property *ea3_config) -{ - return property_psmap_import(ea3_config, NULL, ident, ea3_ident_psmap); -} - -void ea3_ident_hardid_from_ethernet(struct ea3_ident *ident) -{ - struct avs_net_interface netif; - int result; - - result = avs_net_ctrl(1, &netif, sizeof(netif)); - - if (result < 0) { - log_fatal( - "avs_net_ctrl call to get MAC address returned error: %d", result); - } - - ident->hardid[0] = '0'; - ident->hardid[1] = '1'; - ident->hardid[2] = '0'; - ident->hardid[3] = '0'; - - hex_encode_uc( - netif.mac_addr, - sizeof(netif.mac_addr), - ident->hardid + 4, - sizeof(ident->hardid) - 4); -} - -bool ea3_ident_invoke_module_init( - struct ea3_ident *ident, - const struct module_context *module, - struct property_node *app_config) -{ - char sidcode_short[17]; - char sidcode_long[21]; - char security_code[9]; - bool ok; - - /* Set up security env vars */ - - str_format( - security_code, - lengthof(security_code), - "G*%s%s%s%s", - ident->model, - ident->dest, - ident->spec, - ident->rev); - - std_setenv("/env/boot/version", "0.0.0"); - std_setenv("/env/profile/security_code", security_code); - std_setenv("/env/profile/system_id", ident->pcbid); - std_setenv("/env/profile/account_id", ident->pcbid); - std_setenv("/env/profile/license_id", ident->softid); - std_setenv("/env/profile/software_id", ident->softid); - std_setenv("/env/profile/hardware_id", ident->hardid); - - /* Set up the short sidcode string, let dll_entry_init mangle it */ - - str_format( - sidcode_short, - lengthof(sidcode_short), - "%s%s%s%s%s", - ident->model, - ident->dest, - ident->spec, - ident->rev, - ident->ext); - - /* Set up long-form sidcode env var */ - - str_format( - sidcode_long, - lengthof(sidcode_long), - "%s:%s:%s:%s:%s", - ident->model, - ident->dest, - ident->spec, - ident->rev, - ident->ext); - - /* Set this up beforehand, as certain games require it in dll_entry_init */ - - std_setenv("/env/profile/soft_id_code", sidcode_long); - - ok = module_context_invoke_init(module, sidcode_short, app_config); - - if (!ok) { - return false; - } - - /* Back-propagate sidcode, as some games modify it during init */ - - memcpy(ident->model, sidcode_short + 0, sizeof(ident->model) - 1); - ident->dest[0] = sidcode_short[3]; - ident->spec[0] = sidcode_short[4]; - ident->rev[0] = sidcode_short[5]; - memcpy(ident->ext, sidcode_short + 6, sizeof(ident->ext)); - - /* Set up long-form sidcode env var again */ - - str_format( - sidcode_long, - lengthof(sidcode_long), - "%s:%s:%s:%s:%s", - ident->model, - ident->dest, - ident->spec, - ident->rev, - ident->ext); - - std_setenv("/env/profile/soft_id_code", sidcode_long); - - return true; -} - -void ea3_ident_to_property( - const struct ea3_ident *ident, struct property *ea3_config) -{ - struct property_node *node; - int i; - - for (i = 0; ea3_ident_psmap[i].type != 0xFF; i++) { - node = property_search(ea3_config, 0, ea3_ident_psmap[i].path); - - if (node != NULL) { - property_node_remove(node); - } - } - - property_psmap_export(ea3_config, NULL, ident, ea3_ident_psmap); -} - -void ea3_ident_replace_property_bool( - struct property_node *node, const char *name, uint8_t val) -{ - struct property_node *tmp; - - tmp = property_search(NULL, node, name); - - if (tmp) { - property_node_remove(tmp); - } - - property_node_create(NULL, node, PROPERTY_TYPE_BOOL, name, val); -} - -void ea3_ident_replace_property_str( - struct property_node *node, const char *name, const char *val) -{ - struct property_node *tmp; - - tmp = property_search(NULL, node, name); - - if (tmp) { - property_node_remove(tmp); - } - - tmp = property_node_create(NULL, node, PROPERTY_TYPE_STR, name, val); -} diff --git a/src/main/launcher/ea3-config.h b/src/main/launcher/ea3-config.h deleted file mode 100644 index ada44008..00000000 --- a/src/main/launcher/ea3-config.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef LAUNCHER_EA3_CONFIG_H -#define LAUNCHER_EA3_CONFIG_H - -#include "imports/avs.h" - -#include "launcher/module.h" - -/* N.B. even though this might look like a Konami ABI, this is purely an - internal data structure. */ - -struct ea3_ident { - /* psmapped structure offset can't be zero for some stupid reason */ - - uint32_t dummy; - - /* Initialized from ea3-config.xml, then fed back from sidcode_short */ - - char model[4]; - char dest[4]; - char spec[4]; - char rev[4]; - char ext[11]; - - /* Initialized from ea3-config.xml (hardware_id defaults to MAC addr) */ - - char softid[24]; - char hardid[24]; - char pcbid[24]; -}; - -void ea3_ident_init(struct ea3_ident *ident); -bool ea3_ident_from_property( - struct ea3_ident *ident, struct property *ea3_config); -void ea3_ident_hardid_from_ethernet(struct ea3_ident *ident); -bool ea3_ident_invoke_module_init( - struct ea3_ident *ident, - const struct module_context *module, - struct property_node *app_config); -void ea3_ident_to_property( - const struct ea3_ident *ident, struct property *ea3_config); -void ea3_ident_replace_property_bool( - struct property_node *node, const char *name, uint8_t val); -void ea3_ident_replace_property_str( - struct property_node *node, const char *name, const char *val); - -#endif diff --git a/src/main/launcher/ea3-ident-config.c b/src/main/launcher/ea3-ident-config.c new file mode 100644 index 00000000..f0931f25 --- /dev/null +++ b/src/main/launcher/ea3-ident-config.c @@ -0,0 +1,103 @@ +#define LOG_MODULE "ea3-ident-config" + +#include + +#include "imports/avs.h" + +#include "launcher/ea3-ident-config.h" +#include "launcher/property-util.h" + +#include "util/defs.h" +#include "util/hex.h" +#include "util/log.h" +#include "util/str.h" + +#define ROOT_NODE "/ea3_conf" + +PSMAP_BEGIN(ea3_ident_config_psmap) +PSMAP_OPTIONAL( + PSMAP_TYPE_STR, struct ea3_ident_config, softid, "/id/softid", "") +PSMAP_OPTIONAL( + PSMAP_TYPE_STR, struct ea3_ident_config, hardid, "/id/hardid", "") +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct ea3_ident_config, pcbid, "/id/pcbid", "") +PSMAP_REQUIRED(PSMAP_TYPE_STR, struct ea3_ident_config, model, "/soft/model") +PSMAP_REQUIRED(PSMAP_TYPE_STR, struct ea3_ident_config, dest, "/soft/dest") +PSMAP_REQUIRED(PSMAP_TYPE_STR, struct ea3_ident_config, spec, "/soft/spec") +PSMAP_REQUIRED(PSMAP_TYPE_STR, struct ea3_ident_config, rev, "/soft/rev") +PSMAP_REQUIRED(PSMAP_TYPE_STR, struct ea3_ident_config, ext, "/soft/ext") +PSMAP_END + +void ea3_ident_config_init(struct ea3_ident_config *config) +{ + memset(config, 0, sizeof(*config)); +} + +void ea3_ident_config_from_file_load( + const char *path, struct ea3_ident_config *config) +{ + struct property *property; + + log_assert(path); + log_assert(config); + + log_info("Loading from file path: %s", path); + + property = property_util_load(path); + + ea3_ident_config_load(property, config); + + property_util_free(property); +} + +void ea3_ident_config_load( + struct property *property, struct ea3_ident_config *config) +{ + struct property_node *node; + + log_assert(property); + log_assert(config); + + node = property_search(property, NULL, ROOT_NODE); + + if (node == NULL) { + log_fatal("Root node '" ROOT_NODE "' missing"); + } + + if (!property_psmap_import( + property, node, config, ea3_ident_config_psmap)) { + log_fatal("Error reading config file"); + } +} + +bool ea3_ident_config_hardid_is_defined(struct ea3_ident_config *config) +{ + log_assert(config); + + return strlen(config->hardid) > 0; +} + +void ea3_ident_config_hardid_from_ethernet_set(struct ea3_ident_config *config) +{ + struct avs_net_interface netif; + int result; + + log_assert(config); + + result = avs_net_ctrl(1, &netif, sizeof(netif)); + + if (result < 0) { + log_fatal( + "avs_net_ctrl call to get MAC address returned error: %d", result); + } + + config->hardid[0] = '0'; + config->hardid[1] = '1'; + config->hardid[2] = '0'; + config->hardid[3] = '0'; + + hex_encode_uc( + netif.mac_addr, + sizeof(netif.mac_addr), + config->hardid + 4, + sizeof(config->hardid) - 4); +} \ No newline at end of file diff --git a/src/main/launcher/ea3-ident-config.h b/src/main/launcher/ea3-ident-config.h new file mode 100644 index 00000000..1a6dc7f2 --- /dev/null +++ b/src/main/launcher/ea3-ident-config.h @@ -0,0 +1,37 @@ +#ifndef LAUNCHER_EA3_IDENT_CONFIG_H +#define LAUNCHER_EA3_IDENT_CONFIG_H + +#include "imports/avs.h" + +/* N.B. even though this might look like a Konami ABI, this is purely an + internal data structure. */ + +struct ea3_ident_config { + /* psmapped structure offset can't be zero for some stupid reason */ + + uint32_t dummy; + + /* Initialized from ea3-config.xml, then fed back from sidcode_short */ + + char model[4]; + char dest[4]; + char spec[4]; + char rev[4]; + char ext[11]; + + /* Initialized from ea3-config.xml (hardware_id defaults to MAC addr) */ + + char softid[24]; + char hardid[24]; + char pcbid[24]; +}; + +void ea3_ident_config_init(struct ea3_ident_config *config); +void ea3_ident_config_from_file_load( + const char *path, struct ea3_ident_config *config); +void ea3_ident_config_load( + struct property *property, struct ea3_ident_config *config); +bool ea3_ident_config_hardid_is_defined(struct ea3_ident_config *config); +void ea3_ident_config_hardid_from_ethernet_set(struct ea3_ident_config *config); + +#endif diff --git a/src/main/launcher/eamuse-config.c b/src/main/launcher/eamuse-config.c new file mode 100644 index 00000000..9cc251b1 --- /dev/null +++ b/src/main/launcher/eamuse-config.c @@ -0,0 +1,125 @@ +#define LOG_MODULE "eamuse-config" + +#include + +#include "imports/avs.h" + +#include "launcher/ea3-ident-config.h" +#include "launcher/eamuse-config.h" +#include "launcher/property-util.h" + +#include "util/log.h" + +#define EAMUSE_CONFIG_ROOT_NODE "/ea3" + +struct property *eamuse_config_avs_load(const char *path) +{ + struct property *property; + + log_assert(path); + + log_misc("Loading from avs path: %s", path); + + property = property_util_avs_fs_load(path); + + // Check if root node exists, call already errors if not + eamuse_config_root_get(property); + + return property; +} + +struct property_node *eamuse_config_root_get(struct property *property) +{ + struct property_node *node; + + log_assert(property); + + node = property_search(property, 0, EAMUSE_CONFIG_ROOT_NODE); + + if (node == NULL) { + log_fatal("Root node " EAMUSE_CONFIG_ROOT_NODE + " in eamuse config missing"); + } + + return node; +} + +void eamuse_config_id_softid_set(struct property_node *node, const char *value) +{ + log_assert(node); + log_assert(value); + + property_util_node_str_replace(NULL, node, "id/softid", value); +} + +void eamuse_config_id_hardid_set(struct property_node *node, const char *value) +{ + log_assert(node); + log_assert(value); + + property_util_node_str_replace(NULL, node, "id/hardid", value); +} + +void eamuse_config_id_pcbid_set(struct property_node *node, const char *value) +{ + log_assert(node); + log_assert(value); + + property_util_node_str_replace(NULL, node, "id/pcbid", value); +} + +void eamuse_config_soft_model_set(struct property_node *node, const char *value) +{ + log_assert(node); + log_assert(value); + + property_util_node_str_replace(NULL, node, "soft/model", value); +} + +void eamuse_config_soft_dest_set(struct property_node *node, const char *value) +{ + log_assert(node); + log_assert(value); + + property_util_node_str_replace(NULL, node, "soft/dest", value); +} + +void eamuse_config_soft_spec_set(struct property_node *node, const char *value) +{ + log_assert(node); + log_assert(value); + + property_util_node_str_replace(NULL, node, "soft/spec", value); +} + +void eamuse_config_soft_rev_set(struct property_node *node, const char *value) +{ + log_assert(node); + log_assert(value); + + property_util_node_str_replace(NULL, node, "soft/rev", value); +} + +void eamuse_config_soft_ext_set(struct property_node *node, const char *value) +{ + log_assert(node); + log_assert(value); + + property_util_node_str_replace(NULL, node, "soft/ext", value); +} + +void eamuse_config_network_url_slash_set(struct property_node *node, bool value) +{ + log_assert(node); + + property_util_node_bool_replace(NULL, node, "network/url_slash", value); +} + +void eamuse_config_network_service_url_set( + struct property_node *node, const char *value) +{ + log_assert(node); + log_assert(value); + + property_util_node_str_replace(NULL, node, "network/services", value); +} \ No newline at end of file diff --git a/src/main/launcher/eamuse-config.h b/src/main/launcher/eamuse-config.h new file mode 100644 index 00000000..2cba227a --- /dev/null +++ b/src/main/launcher/eamuse-config.h @@ -0,0 +1,23 @@ +#ifndef LAUNCHER_EAMUSE_CONFIG_H +#define LAUNCHER_EAMUSE_CONFIG_H + +#include "imports/avs.h" + +struct property *eamuse_config_avs_load(const char *path); +struct property_node *eamuse_config_root_get(struct property *property); + +void eamuse_config_id_softid_set(struct property_node *node, const char *value); +void eamuse_config_id_hardid_set(struct property_node *node, const char *value); +void eamuse_config_id_pcbid_set(struct property_node *node, const char *value); +void eamuse_config_soft_model_set( + struct property_node *node, const char *value); +void eamuse_config_soft_dest_set(struct property_node *node, const char *value); +void eamuse_config_soft_spec_set(struct property_node *node, const char *value); +void eamuse_config_soft_rev_set(struct property_node *node, const char *value); +void eamuse_config_soft_ext_set(struct property_node *node, const char *value); +void eamuse_config_network_url_slash_set( + struct property_node *node, bool value); +void eamuse_config_network_service_url_set( + struct property_node *node, const char *value); + +#endif \ No newline at end of file diff --git a/src/main/launcher/eamuse.c b/src/main/launcher/eamuse.c new file mode 100644 index 00000000..e2fd159c --- /dev/null +++ b/src/main/launcher/eamuse.c @@ -0,0 +1,25 @@ +#define LOG_MODULE "eamuse" + +#include "imports/avs-ea3.h" + +#include "util/log.h" + +void eamuse_init(struct property_node *node) +{ + log_assert(node); + + log_info("init"); + + ea3_boot(node); + + log_misc("init done"); +} + +void eamuse_fini() +{ + log_info("fini"); + + ea3_shutdown(); + + log_misc("fini done"); +} \ No newline at end of file diff --git a/src/main/launcher/eamuse.h b/src/main/launcher/eamuse.h new file mode 100644 index 00000000..1cd1f7e7 --- /dev/null +++ b/src/main/launcher/eamuse.h @@ -0,0 +1,9 @@ +#ifndef LAUNCHER_EAMUSE_H +#define LAUNCHER_EAMUSE_H + +#include "imports/avs.h" + +void eamuse_init(struct property_node *node); +void eamuse_fini(); + +#endif \ No newline at end of file diff --git a/src/main/launcher/hook.c b/src/main/launcher/hook.c new file mode 100644 index 00000000..350106fa --- /dev/null +++ b/src/main/launcher/hook.c @@ -0,0 +1,34 @@ +#define LOG_MODULE "hook" + +#include + +#include "launcher/hook.h" + +#include "util/log.h" + +void hook_load_dll(const char *path) +{ + log_assert(path); + + log_info("Load hook dll: %s", path); + + if (LoadLibraryA(path) == NULL) { + LPSTR buffer; + + FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR) &buffer, + 0, + NULL); + + log_fatal("%s: Failed to load hook DLL: %s", path, buffer); + + LocalFree(buffer); + } + + log_misc("Load hook dll done"); +} \ No newline at end of file diff --git a/src/main/launcher/hook.h b/src/main/launcher/hook.h new file mode 100644 index 00000000..9d0c5d42 --- /dev/null +++ b/src/main/launcher/hook.h @@ -0,0 +1,6 @@ +#ifndef LAUNCHER_HOOK_H +#define LAUNCHER_HOOK_H + +void hook_load_dll(const char *path); + +#endif \ No newline at end of file diff --git a/src/main/launcher/launcher-config.c b/src/main/launcher/launcher-config.c new file mode 100644 index 00000000..aaecd3e4 --- /dev/null +++ b/src/main/launcher/launcher-config.c @@ -0,0 +1,371 @@ +#define LOG_MODULE "launcher-config" + +#include + +#include "imports/avs.h" + +#include "launcher/launcher-config.h" +#include "launcher/property-util.h" + +#include "util/log.h" +#include "util/mem.h" +#include "util/str.h" + +// clang-format off +PSMAP_BEGIN(launcher_debug_psmap) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct launcher_debug_config, remote_debugger, + "debug/remote_debugger", false) + PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct launcher_debug_config, log_property_configs, + "debug/log_property_configs", false) +PSMAP_END +// clang-format on + +#define ROOT_NODE "/launcher" +#define MAX_LAYER_CONFIG_NODES 8 + +#define NODE_MISSING_FATAL(subnode) \ + log_fatal("%s/%s: Node missing", ROOT_NODE, subnode); +#define NODE_LOADING_FATAL(subnode) \ + log_fatal("%s/%s: Node loading", ROOT_NODE, subnode); + +static struct property * +_launcher_config_layered_config_nodes_load(struct property_node *node) +{ + char kind[64]; + char file[MAX_PATH]; + int res; + int cnt; + + struct property_node *cur; + struct property *config_property[MAX_LAYER_CONFIG_NODES]; + struct property *merged_property; + + log_assert(node); + + cnt = 0; + cur = property_search(NULL, node, "config"); + + while (cur) { + if (cnt >= MAX_LAYER_CONFIG_NODES) { + log_fatal( + "Exceeding max supported config nodes for layering, max is %d", + MAX_LAYER_CONFIG_NODES); + } + + res = property_node_refer( + NULL, cur, "kind@", PROPERTY_TYPE_ATTR, kind, sizeof(kind)); + + if (res < 0) { + log_fatal("Failed reading 'kind' attribute value of config node"); + } + + if (!strcmp(kind, "file")) { + property_node_read(cur, PROPERTY_TYPE_STR, file, sizeof(file)); + + config_property[cnt] = property_util_load(file); + } else if (!strcmp(kind, "inline")) { + // The nested child is the actual root of the inline, not the outer + // node + cur = property_node_traversal(cur, TRAVERSE_FIRST_CHILD); + + config_property[cnt] = property_util_clone(cur); + } else { + log_fatal( + "Unsupported 'kind' attribute value '%s' of config node", kind); + } + + cnt++; + cur = property_node_traversal(cur, TRAVERSE_NEXT_SEARCH_RESULT); + } + + if (cnt == 0) { + return NULL; + } + + merged_property = + property_util_merge((struct property **) &config_property[0], cnt); + + for (int i = 0; i < cnt; i++) { + property_util_free(config_property[i]); + } + + return merged_property; +} + +static void _launcher_config_hook_dlls_parse( + struct property_node *node, + const char *node_path, + char dlls[LAUNCHER_CONFIG_MAX_HOOK_DLL][MAX_PATH]) +{ + int cnt; + struct property_node *cur; + + cnt = 0; + cur = property_search(NULL, node, node_path); + + while (cur) { + if (cnt >= LAUNCHER_CONFIG_MAX_HOOK_DLL) { + log_warning( + "Currently not supporting more than %d dlls, skipping " + "remaining", + cnt); + break; + } + + property_node_read(cur, PROPERTY_TYPE_STR, dlls[cnt], MAX_PATH); + + cnt++; + cur = property_node_traversal(cur, TRAVERSE_NEXT_SEARCH_RESULT); + } +} + +static void _launcher_config_bootstrap_load( + struct property_node *node, struct launcher_bootstrap_config *config) +{ + int res; + + log_assert(node); + log_assert(config); + + res = property_node_refer( + NULL, + node, + "selector", + PROPERTY_TYPE_STR, + config->selector, + sizeof(config->selector)); + + if (res < 0) { + NODE_MISSING_FATAL("bootstrap/selector"); + } + + config->property = _launcher_config_layered_config_nodes_load(node); + + if (config->property == NULL) { + NODE_MISSING_FATAL("bootstrap/config"); + } +} + +static void _launcher_config_hook_load( + struct property_node *node, struct launcher_hook_config *config) +{ + log_assert(node); + log_assert(config); + + _launcher_config_hook_dlls_parse(node, "hook_dlls/dll", config->hook_dlls); + _launcher_config_hook_dlls_parse( + node, "before_hook_dlls/dll", config->before_hook_dlls); + _launcher_config_hook_dlls_parse( + node, "iat_hook_dlls/dll", config->iat_hook_dlls); +} + +static void _launcher_config_debug_load( + struct property_node *node, struct launcher_debug_config *config) +{ + log_assert(node); + log_assert(config); + + if (!property_psmap_import(NULL, node, config, launcher_debug_psmap)) { + NODE_LOADING_FATAL("debug"); + } +} + +void launcher_config_init(struct launcher_config *config) +{ + log_assert(config); + + memset(config->bootstrap.selector, 0, sizeof(config->bootstrap.selector)); + config->bootstrap.property = NULL; + + config->avs.property = NULL; + + config->ea3_ident.property = NULL; + + config->eamuse.property = NULL; + + memset(config->hook.hook_dlls, 0, sizeof(config->hook.hook_dlls)); + memset( + config->hook.before_hook_dlls, + 0, + sizeof(config->hook.before_hook_dlls)); + memset(config->hook.iat_hook_dlls, 0, sizeof(config->hook.iat_hook_dlls)); + + config->debug.remote_debugger = false; + config->debug.log_property_configs = false; +} + +void launcher_config_load( + struct property *property, struct launcher_config *config) +{ + struct property_node *root_node; + struct property_node *node; + avs_error error; + + log_assert(property); + log_assert(config); + + root_node = property_search(property, NULL, ROOT_NODE); + + if (root_node == NULL) { + NODE_MISSING_FATAL(""); + } + + error = property_node_refer( + NULL, + root_node, + "version@", + PROPERTY_TYPE_ATTR, + &config->version, + sizeof(uint32_t)); + + if (AVS_IS_ERROR(error)) { + log_fatal("Missing version attribute on root node"); + } + + // if (config->version != 1) { + // log_fatal("Unsupported version of launcher configuration: %d", + // config->version); + // } + + node = property_search(NULL, root_node, "bootstrap"); + + if (node == NULL) { + NODE_MISSING_FATAL("bootstrap"); + } + + _launcher_config_bootstrap_load(node, &config->bootstrap); + + node = property_search(NULL, root_node, "avs"); + + if (node) { + config->avs.property = _launcher_config_layered_config_nodes_load(node); + } + + node = property_search(NULL, root_node, "ea3_ident"); + + if (node) { + config->ea3_ident.property = + _launcher_config_layered_config_nodes_load(node); + } + + node = property_search(NULL, root_node, "eamuse"); + + if (node) { + config->eamuse.property = + _launcher_config_layered_config_nodes_load(node); + } + + node = property_search(NULL, root_node, "hook"); + + if (node) { + _launcher_config_hook_load(node, &config->hook); + } + + _launcher_config_debug_load(root_node, &config->debug); +} + +bool launcher_config_add_hook_dll( + struct launcher_config *config, const char *path) +{ + int i; + + log_assert(config); + log_assert(path); + + i = 0; + + while (i < LAUNCHER_CONFIG_MAX_HOOK_DLL) { + if (strlen(config->hook.hook_dlls[i]) == 0) { + break; + } + + i++; + } + + if (i >= LAUNCHER_CONFIG_MAX_HOOK_DLL) { + return false; + } + + str_cpy(config->hook.hook_dlls[i], sizeof(config->hook.hook_dlls[i]), path); + + return true; +} + +bool launcher_config_add_before_hook_dll( + struct launcher_config *config, const char *path) +{ + int i; + + log_assert(config); + log_assert(path); + + i = 0; + + while (i < LAUNCHER_CONFIG_MAX_HOOK_DLL) { + if (strlen(config->hook.before_hook_dlls[i]) == 0) { + break; + } + + i++; + } + + if (i >= LAUNCHER_CONFIG_MAX_HOOK_DLL) { + return false; + } + + str_cpy( + config->hook.before_hook_dlls[i], + sizeof(config->hook.before_hook_dlls[i]), + path); + + return true; +} + +bool launcher_config_add_iat_hook_dll( + struct launcher_config *config, const char *path) +{ + int i; + + log_assert(config); + log_assert(path); + + i = 0; + + while (i < LAUNCHER_CONFIG_MAX_HOOK_DLL) { + if (strlen(config->hook.iat_hook_dlls[i]) == 0) { + break; + } + + i++; + } + + if (i >= LAUNCHER_CONFIG_MAX_HOOK_DLL) { + return false; + } + + str_cpy( + config->hook.iat_hook_dlls[i], + sizeof(config->hook.iat_hook_dlls[i]), + path); + + return true; +} + +void launcher_config_fini(struct launcher_config *config) +{ + log_assert(config); + + property_util_free(config->bootstrap.property); + + if (config->avs.property) { + property_util_free(config->avs.property); + } + + if (config->ea3_ident.property) { + property_util_free(config->ea3_ident.property); + } + + if (config->eamuse.property) { + property_util_free(config->eamuse.property); + } +} \ No newline at end of file diff --git a/src/main/launcher/launcher-config.h b/src/main/launcher/launcher-config.h new file mode 100644 index 00000000..7d6b8a6e --- /dev/null +++ b/src/main/launcher/launcher-config.h @@ -0,0 +1,56 @@ +#ifndef LAUNCHER_CONFIG_H +#define LAUNCHER_CONFIG_H + +#include + +#include "util/array.h" + +#define LAUNCHER_CONFIG_MAX_HOOK_DLL 16 + +struct launcher_config { + uint32_t version; + + struct launcher_bootstrap_config { + char selector[128]; + struct property *property; + } bootstrap; + + struct launcher_avs_config { + struct property *property; + } avs; + + struct launcher_ea3_ident_config { + struct property *property; + } ea3_ident; + + struct launcher_eamuse_config { + struct property *property; + } eamuse; + + struct launcher_hook_config { + char hook_dlls[LAUNCHER_CONFIG_MAX_HOOK_DLL][MAX_PATH]; + char before_hook_dlls[LAUNCHER_CONFIG_MAX_HOOK_DLL][MAX_PATH]; + char iat_hook_dlls[LAUNCHER_CONFIG_MAX_HOOK_DLL][MAX_PATH]; + } hook; + + struct launcher_debug_config { + bool remote_debugger; + bool log_property_configs; + } debug; +}; + +void launcher_config_init(struct launcher_config *config); + +void launcher_config_load( + struct property *property, struct launcher_config *config); + +bool launcher_config_add_hook_dll( + struct launcher_config *config, const char *path); +bool launcher_config_add_before_hook_dll( + struct launcher_config *config, const char *path); +bool launcher_config_add_iat_hook_dll( + struct launcher_config *config, const char *path); + +void launcher_config_fini(struct launcher_config *config); + +#endif \ No newline at end of file diff --git a/src/main/launcher/launcher.c b/src/main/launcher/launcher.c new file mode 100644 index 00000000..f77c28fd --- /dev/null +++ b/src/main/launcher/launcher.c @@ -0,0 +1,543 @@ +#define LOG_MODULE "launcher" + +#include + +#include +#include +#include +#include + +#include "imports/avs-ea3.h" +#include "imports/avs.h" + +#include "launcher/avs-config.h" +#include "launcher/avs.h" +#include "launcher/bootstrap-config.h" +#include "launcher/bootstrap.h" +#include "launcher/debug.h" +#include "launcher/ea3-ident-config.h" +#include "launcher/eamuse-config.h" +#include "launcher/eamuse.h" +#include "launcher/hook.h" +#include "launcher/launcher-config.h" +#include "launcher/logger.h" +#include "launcher/module.h" +#include "launcher/options.h" +#include "launcher/property-util.h" +#include "launcher/stubs.h" + +#include "util/debug.h" +#include "util/defs.h" +#include "util/fs.h" +#include "util/log.h" +#include "util/os.h" +#include "util/proc.h" +#include "util/signal.h" +#include "util/str.h" + +static void _launcher_signal_shutdown_handler() +{ + logger_finit(); + ExitProcess(EXIT_FAILURE); +} + +static void _launcher_logger_early_init(const struct options_log *options) +{ + log_assert(options); + + // Early logging pre AVS setup depend entirely on command args + // We don't even have the bootstrap configuration loaded at this point + logger_early_init(options->file_path); + + if (options->level) { + log_set_level(*(options->level)); + } +} + +static void _launcher_env_game_dir_verify() +{ + char cwd[MAX_PATH]; + char modules_dir[MAX_PATH]; + char prop_dir[MAX_PATH]; + + getcwd(cwd, sizeof(cwd)); + + log_info("Current working directory: %s", cwd); + + str_cpy(modules_dir, sizeof(modules_dir), cwd); + str_cpy(prop_dir, sizeof(prop_dir), cwd); + + str_cat(modules_dir, sizeof(modules_dir), "/modules"); + str_cat(prop_dir, sizeof(prop_dir), "/prop"); + + if (!path_exists(modules_dir)) { + log_fatal( + "Cannot find 'modules' directory in current working directory: %s", + cwd); + } + + if (!path_exists(prop_dir)) { + log_fatal( + "Cannot find 'prop' directory in current working directory: %s", + cwd); + } +} + +static void _launcher_bootstrap_config_options_override( + struct launcher_bootstrap_config *config, + const struct options_bootstrap *options) +{ + log_assert(config); + log_assert(options); + + if (options->config_path) { + log_misc( + "Command line override bootstrap configuration from file: %s", + options->config_path); + + property_util_free(config->property); + config->property = property_util_load(options->config_path); + } + + if (options->selector) { + log_misc( + "Command line override bootstrap selector: %s", options->selector); + + str_cpy(config->selector, sizeof(config->selector), options->selector); + } +} + +static void _launcher_ea3_ident_config_options_override( + struct ea3_ident_config *config, const struct options_eamuse *options) +{ + log_assert(config); + log_assert(options); + + if (options->softid) { + str_cpy(config->softid, sizeof(config->softid), options->softid); + } + + if (options->pcbid) { + str_cpy(config->pcbid, sizeof(config->pcbid), options->pcbid); + } +} + +static void _launcher_hook_config_options_override( + struct launcher_config *config, const struct options_hook *options) +{ + size_t i; + const char *dll; + + log_assert(config); + log_assert(options); + + for (i = 0; i < options->hook_dlls.nitems; i++) { + dll = *array_item(const char *, &options->hook_dlls, i); + + if (!launcher_config_add_hook_dll(config, dll)) { + log_warning( + "Adding override hook dll '%s' failed (max supported limit " + "exceeded), ignored", + dll); + } + } + + for (i = 0; i < options->before_hook_dlls.nitems; i++) { + dll = *array_item(const char *, &options->before_hook_dlls, i); + + if (!launcher_config_add_before_hook_dll(config, dll)) { + log_warning( + "Adding override before hook dll '%s' failed (max supported " + "limit exceeded), ignored", + dll); + } + } + + for (i = 0; i < options->iat_hook_dlls.nitems; i++) { + dll = *array_item(const char *, &options->iat_hook_dlls, i); + + if (!launcher_config_add_iat_hook_dll(config, dll)) { + log_warning( + "Adding override iat hook dll '%s' failed (max supported limit " + "exceeded), ignored", + dll); + } + } +} + +static void _launcher_debug_config_options_override( + struct launcher_debug_config *config, const struct options_debug *options) +{ + log_assert(config); + log_assert(options); + + if (options->remote_debugger) { + log_misc("Command line override, enable remote debugger"); + + config->remote_debugger = true; + } + + if (options->log_property_configs) { + log_misc("Command line override, log property configs"); + + config->log_property_configs = true; + } +} + +static void _launcher_config_options_override( + struct launcher_config *config, const struct options *options) +{ + log_assert(config); + log_assert(options); + + // Apply command line overrides on all launcher owned configuration + // parameters + _launcher_bootstrap_config_options_override( + &config->bootstrap, &options->bootstrap); + _launcher_hook_config_options_override(config, &options->hook); + _launcher_debug_config_options_override(&config->debug, &options->debug); +} + +static void +_launcher_config_full_resolved_log(const struct launcher_config *config) +{ + if (config->debug.log_property_configs) { + log_misc("launcher-config resolved properties"); + log_misc("bootstrap-config"); + property_util_log(config->bootstrap.property); + + log_misc("avs-config"); + property_util_log(config->avs.property); + + log_misc("ea3-ident-config"); + property_util_log(config->ea3_ident.property); + + log_misc("eamuse-config"); + property_util_log(config->eamuse.property); + } +} + +static void +_launcher_remote_debugger_trap(const struct launcher_debug_config *config) +{ + log_assert(config); + + /* If enabled, wait for a remote debugger to attach as early as possible. + Spawning launcher with a debugger crashes it for some reason + (e.g. on jubeat08). However, starting the launcher separately and + attaching a remote debugger works */ + + if (config->remote_debugger) { + debug_remote_debugger_trap(); + } +} + +static void _launcher_bootstrap_config_load( + const struct launcher_bootstrap_config *launcher_bootstrap_config, + struct bootstrap_config *config) +{ + bootstrap_config_init(config); + + bootstrap_config_load( + launcher_bootstrap_config->property, + launcher_bootstrap_config->selector, + config); +} + +static void _launcher_bootstrap_log_config_options_override( + struct bootstrap_log_config *config, const struct options_log *options) +{ + log_assert(config); + log_assert(options); + + if (options->level) { + log_misc( + "Command line override bootstrap log level: %d", *(options->level)); + + switch (*(options->level)) { + case LOG_LEVEL_FATAL: + str_cpy(config->level, sizeof(config->level), "fatal"); + break; + + case LOG_LEVEL_WARNING: + str_cpy(config->level, sizeof(config->level), "warn"); + break; + + case LOG_LEVEL_INFO: + str_cpy(config->level, sizeof(config->level), "info"); + break; + + case LOG_LEVEL_MISC: + str_cpy(config->level, sizeof(config->level), "misc"); + break; + + default: + log_assert(false); + } + } + + if (options->file_path) { + log_misc( + "Command line override bootstrap log file: %s", options->file_path); + str_cpy(config->file, sizeof(config->file), options->file_path); + } +} + +static void _launcher_bootstrap_log_config_verify( + const struct launcher_config *launcher_config, + const struct bootstrap_config *bootstrap_config) +{ + log_assert(launcher_config); + log_assert(bootstrap_config); + + if (!str_eq(bootstrap_config->startup.log.level, "misc")) { + if (launcher_config->debug.log_property_configs) { + log_warning( + "Logging of property configs enabled, but requires misc log " + "level, current log level: %s", + bootstrap_config->startup.log.level); + } + } +} + +static void +_launcher_before_hook_dlls_load(const struct launcher_hook_config *config) +{ + int i; + + log_assert(config); + + log_misc("Loading before hook dlls..."); + + for (i = 0; i < LAUNCHER_CONFIG_MAX_HOOK_DLL; i++) { + if (strlen(config->before_hook_dlls[i]) > 0) { + hook_load_dll(config->before_hook_dlls[i]); + } + } +} + +static void _launcher_ea3_ident_config_load( + const struct launcher_ea3_ident_config *launcher_config, + struct ea3_ident_config *config, + bool log_property_configs) +{ + log_assert(launcher_config); + log_assert(config); + + ea3_ident_config_init(config); + ea3_ident_config_load(launcher_config->property, config); + + if (log_property_configs) { + log_misc("Property ea3-ident-config"); + + property_util_log(launcher_config->property); + } + + if (!ea3_ident_config_hardid_is_defined(config)) { + log_misc( + "No no hardid defined in ea3-ident-config, derive from ethernet"); + + ea3_ident_config_hardid_from_ethernet_set(config); + } +} + +static void _launcher_bootstrap_module_init( + const struct bootstrap_module_config *module_config, + const struct launcher_hook_config *hook_config) +{ + int i; + struct array iat_hook_dlls; + + log_assert(module_config); + log_assert(hook_config); + + array_init(&iat_hook_dlls); + + for (i = 0; i < LAUNCHER_CONFIG_MAX_HOOK_DLL; i++) { + if (strlen(hook_config->before_hook_dlls[i]) > 0) { + *array_append(const char *, &iat_hook_dlls) = + (const char *) &hook_config->before_hook_dlls[i]; + } + } + + bootstrap_module_init(module_config, &iat_hook_dlls); + + array_fini(&iat_hook_dlls); +} + +static void _launcher_hook_dlls_load(const struct launcher_hook_config *config) +{ + int i; + + log_assert(config); + + log_misc("Loading hook dlls..."); + + for (i = 0; i < LAUNCHER_CONFIG_MAX_HOOK_DLL; i++) { + if (strlen(config->hook_dlls[i]) > 0) { + hook_load_dll(config->hook_dlls[i]); + } + } +} + +static void _launcher_dongle_stubs_init() +{ + stubs_init(); +} + +static void _launcher_debugger_break() +{ + /* Opportunity for breakpoint setup etc */ + if (IsDebuggerPresent()) { + DebugBreak(); + } +} + +void _launcher_init( + const struct options *options, + struct launcher_config *launcher_config, + struct bootstrap_config *bootstrap_config, + struct ea3_ident_config *ea3_ident_config) +{ + struct property *launcher_property; + + log_assert(options); + log_assert(launcher_config); + log_assert(bootstrap_config); + log_assert(ea3_ident_config); + + _launcher_logger_early_init(&options->log); + + debug_init(); + signal_exception_handler_init(_launcher_signal_shutdown_handler); + signal_register_shutdown_handler(&_launcher_signal_shutdown_handler); + + os_version_log(); + _launcher_env_game_dir_verify(); + + if (proc_is_running_as_admin_user()) { + log_warning( + "Not running as admin user. Launcher and games require elevated " + "privileges to run correctly"); + } + + launcher_config_init(launcher_config); + + if (options->launcher.config_path) { + log_info("Loading launcher configuration from file: %s", options->launcher.config_path); + + launcher_property = property_util_load(options->launcher.config_path); + launcher_config_load(launcher_property, launcher_config); + + _launcher_config_options_override(launcher_config, options); + + if (launcher_config->debug.log_property_configs) { + log_misc("launcher-config"); + property_util_log(launcher_property); + } + + property_util_free(launcher_property); + } else { + _launcher_config_options_override(launcher_config, options); + } + + // Not really fully resolved, but have an early debug dump because there are + // still several more steps that can fail before having the entire + // configuration resolved + _launcher_config_full_resolved_log(launcher_config); + + _launcher_remote_debugger_trap(&launcher_config->debug); + + _launcher_bootstrap_config_load( + &launcher_config->bootstrap, bootstrap_config); + _launcher_bootstrap_log_config_options_override( + &bootstrap_config->startup.log, &options->log); + _launcher_bootstrap_log_config_verify(launcher_config, bootstrap_config); + + bootstrap_init(launcher_config->debug.log_property_configs); + bootstrap_log_init(&bootstrap_config->startup.log); + + _launcher_before_hook_dlls_load(&launcher_config->hook); + + bootstrap_avs_init( + &bootstrap_config->startup.boot, + &bootstrap_config->startup.log, + avs_config_root_get(launcher_config->avs.property)); + bootstrap_default_files_create(&bootstrap_config->startup.default_file); + + _launcher_ea3_ident_config_load( + &launcher_config->ea3_ident, + ea3_ident_config, + launcher_config->debug.log_property_configs); + _launcher_ea3_ident_config_options_override( + ea3_ident_config, &options->eamuse); + + // Execute another one which is now actually final. No more configuration + // changes from this point on + _launcher_config_full_resolved_log(launcher_config); +} + +void _launcher_run( + const struct launcher_config *launcher_config, + const struct bootstrap_config *bootstrap_config, + struct ea3_ident_config *ea3_ident_config) +{ + log_assert(launcher_config); + log_assert(bootstrap_config); + log_assert(ea3_ident_config); + + _launcher_bootstrap_module_init( + &bootstrap_config->startup.module, &launcher_config->hook); + + _launcher_hook_dlls_load(&launcher_config->hook); + + _launcher_dongle_stubs_init(); + + _launcher_debugger_break(); + + bootstrap_module_game_init( + &bootstrap_config->startup.module, ea3_ident_config); + + bootstrap_eamuse_init( + &bootstrap_config->startup.eamuse, + ea3_ident_config, + eamuse_config_root_get(launcher_config->eamuse.property)); + + bootstrap_module_game_run(); +} + +void _launcher_fini( + struct launcher_config *launcher_config, + const struct bootstrap_config *bootstrap_config) +{ + log_assert(launcher_config); + log_assert(bootstrap_config); + + bootstrap_eamuse_fini(&bootstrap_config->startup.eamuse); + + bootstrap_avs_fini(); + + bootstrap_module_game_fini(); + + launcher_config_fini(launcher_config); + + log_info("Shutdown complete"); + + logger_finit(); +} + +void launcher_main(const struct options *options) +{ + struct launcher_config launcher_config; + struct bootstrap_config bootstrap_config; + struct ea3_ident_config ea3_ident_config; + + log_assert(options); + + _launcher_init( + options, &launcher_config, &bootstrap_config, &ea3_ident_config); + + _launcher_run(&launcher_config, &bootstrap_config, &ea3_ident_config); + + _launcher_fini(&launcher_config, &bootstrap_config); +} \ No newline at end of file diff --git a/src/main/launcher/launcher.h b/src/main/launcher/launcher.h new file mode 100644 index 00000000..da1995cc --- /dev/null +++ b/src/main/launcher/launcher.h @@ -0,0 +1,8 @@ +#ifndef LAUNCHER_LAUNCHER_H +#define LAUNCHER_LAUNCHER_H + +#include "launcher/options.h" + +void launcher_main(const struct options *options); + +#endif \ No newline at end of file diff --git a/src/main/launcher/logger.c b/src/main/launcher/logger.c new file mode 100644 index 00000000..f8ba8097 --- /dev/null +++ b/src/main/launcher/logger.c @@ -0,0 +1,365 @@ +#define LOG_MODULE "launcher-logger" + +#include +#include +#include +#include +#include +#include + +#include "launcher/logger.h" +#include "launcher/version.h" + +#include "util/fs.h" +#include "util/log.h" +#include "util/mem.h" + +static FILE *log_file; +static HANDLE log_mutex; + +static const char *logger_get_formatted_timestamp(void) +{ + static char buffer[64]; + time_t cur = 0; + struct tm *tm = NULL; + + cur = time(NULL); + tm = localtime(&cur); + + strftime(buffer, sizeof(buffer), "[%Y/%m/%d %H:%M:%S] ", tm); + + return buffer; +} + +static char logger_console_determine_color(const char *str) +{ + log_assert(str); + + /* Add some color to make spotting warnings/errors easier. + Based on debug output level identifier. */ + + /* Avoids colored output on strings like "Windows" */ + if (str[1] != ':') { + return 15; + } + + switch (str[0]) { + /* green */ + case 'M': + return 10; + /* blue */ + case 'I': + return 9; + /* yellow */ + case 'W': + return 14; + /* red */ + case 'F': + return 12; + /* default console color */ + default: + return 15; + } +} + +static size_t logger_msg_coloring_len(const char *str) +{ + // Expected format example: "I:boot: my log message" + + const char *ptr; + size_t len; + int colon_count; + + ptr = str; + len = 0; + colon_count = 0; + + while (true) { + // End of string = invalid log format + if (*ptr == '\0') { + return 0; + } + + if (*ptr == ':') { + colon_count++; + } + + if (colon_count == 2) { + // Skip current colon, next char is a space + return len + 1; + } + + len++; + ptr++; + } + + return 0; +} + +static void logger_console( + void *ctx, const char *chars, size_t nchars, const char *timestamp_str) +{ + char color; + size_t color_len; + // See "util/log.c", has to align + char buffer[65536]; + char tmp; + + color_len = logger_msg_coloring_len(chars); + + // Check if we could detect which part to color, otherwise just write the + // whole log message without any coloring logic + if (color_len > 0) { + color = logger_console_determine_color(chars); + + strcpy(buffer, chars); + + // Mask start of log message for coloring + tmp = buffer[color_len]; + buffer[color_len] = '\0'; + + printf("%s", timestamp_str); + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color); + printf("%s", buffer); + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15); + + // Write actual message non colored + buffer[color_len] = tmp; + printf("%s", buffer + color_len); + } else { + printf("%s", chars); + } +} + +static void logger_console_avs(const char *chars) +{ + char color; + size_t color_len; + // See "util/log.c", has to align + char buffer[65536]; + char tmp; + const char *timestamp; + const char *msg; + + static const size_t timestamp_len = strlen("[----/--/-- --:--:--]"); + + timestamp = chars; + msg = timestamp + timestamp_len + 1; // +1 is the space + + color_len = logger_msg_coloring_len(msg); + + // Check if we could detect which part to color, otherwise just write the + // whole log message without any coloring logic + if (color_len > 0) { + color = logger_console_determine_color(msg); + + strcpy(buffer, msg); + + // Mask start of log message for coloring + tmp = buffer[color_len]; + buffer[color_len] = '\0'; + + printf("%.21s ", timestamp); + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color); + printf("%s", buffer); + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15); + + // Write actual message non colored + buffer[color_len] = tmp; + printf("%s\n", buffer + color_len); + } else { + printf("%s\n", chars); + } +} + +static void logger_file( + void *ctx, const char *chars, size_t nchars, const char *timestamp_str) +{ + if (ctx) { + fwrite(timestamp_str, 1, strlen(timestamp_str), (FILE *) ctx); + fwrite(chars, 1, nchars, (FILE *) ctx); + fflush((FILE *) ctx); + } +} + +static void logger_file_avs(const char *chars, size_t len) +{ + if (log_file) { + fwrite(chars, 1, len, log_file); + fflush(log_file); + } +} + +static void logger_writer(void *ctx, const char *chars, size_t nchars) +{ + const char *timestamp_str; + + // Different threads logging the same destination, e.g. debugger thread, + // main thread + + WaitForSingleObject(log_mutex, INFINITE); + + timestamp_str = logger_get_formatted_timestamp(); + + logger_console(ctx, chars, nchars, timestamp_str); + logger_file(ctx, chars, nchars, timestamp_str); + + ReleaseMutex(log_mutex); +} + +static void logger_log_header() +{ + log_info( + "\n" + " .__ .__ \n" + " | | _____ __ __ ____ ____ | |__ ___________ \n" + " | | \\__ \\ | | \\/ \\_/ ___\\| | \\_/ __ \\_ __ \\ \n" + " | |__/ __ \\| | / | \\ \\___| Y \\ ___/| | \\/ \n" + " |____(____ /____/|___| /\\___ >___| /\\___ >__| \n" + " \\/ \\/ \\/ \\/ \\/ "); + + log_info( + "launcher build date %s, gitrev %s", + launcher_build_date, + launcher_gitrev); +} + +void logger_early_init(const char *log_file_path) +{ + if (log_file_path) { + log_file = fopen(log_file_path, "w+"); + } else { + log_file = NULL; + } + + log_to_writer(logger_writer, log_file); + + logger_log_header(); + + if (log_file_path) { + log_info("Log file: %s", log_file_path); + + if (!log_file) { + log_fatal( + "ERROR: Opening log file %s failed: %s", + log_file_path, + strerror(errno)); + } + } + + log_mutex = CreateMutex(NULL, FALSE, NULL); +} + +void logger_init( + const char *filename, + bool enable_console, + bool enable_file, + bool rotate_file, + bool append_file, + uint16_t count_file) +{ + // Remark: very basic implementation for now, logger needs a proper cleanup + // anyway before implementing more features such as rotation + + if (enable_file) { + if (log_file) { + // Log file stitching of early log output + fseek(log_file, 0, SEEK_END); + size_t file_size = ftell(log_file); + fseek(log_file, 0, SEEK_SET); + + void *buffer = xmalloc(file_size); + + fread(buffer, file_size, 1, log_file); + + fclose(log_file); + + log_file = fopen(filename, "w+"); + + fwrite(buffer, file_size, 1, log_file); + fflush(log_file); + free(buffer); + } + } else { + if (log_file) { + fclose(log_file); + log_file = NULL; + } + } +} + +void logger_level_set(enum logger_level level) +{ + enum log_level internal_level; + + switch (level) { + case LOGGER_LEVEL_OFF: + case LOGGER_LEVEL_FATAL: + internal_level = LOG_LEVEL_FATAL; + break; + + case LOGGER_LEVEL_WARNING: + internal_level = LOG_LEVEL_WARNING; + break; + + case LOGGER_LEVEL_DEFAULT: + case LOGGER_LEVEL_INFO: + internal_level = LOG_LEVEL_INFO; + break; + + case LOGGER_LEVEL_MISC: + case LOGGER_LEVEL_ALL: + internal_level = LOG_LEVEL_MISC; + break; + + default: + internal_level = LOG_LEVEL_FATAL; + log_assert(false); + } + + log_set_level(internal_level); +} + +void logger_log_avs_log_message(char *str, size_t len) +{ + bool use_crlf; + +#if AVS_VERSION >= 1500 + use_crlf = true; +#else + use_crlf = false; +#endif + + // Different threads logging the same destination, e.g. debugger thread, + // main thread + + WaitForSingleObject(log_mutex, INFINITE); + + // Write to file first, tokenizing trashes the string + logger_file_avs(str, len); + + // The character stream provided here can contain multiple lines as AVS + // manages buffered writes to the logger backend. We need to split them + // up for the logging backend to allow for further enhancements + + char *line = strtok(str, use_crlf ? "\r\n" : "\n"); + + while (line) { + logger_console_avs(line); + line = strtok(NULL, use_crlf ? "\r\n" : "\n"); + } + + ReleaseMutex(log_mutex); +} + +void logger_finit() +{ + log_misc("Logger finit"); + + if (log_file) { + fflush(log_file); + fclose(log_file); + } + + CloseHandle(log_mutex); +} \ No newline at end of file diff --git a/src/main/launcher/logger.h b/src/main/launcher/logger.h new file mode 100644 index 00000000..5b665b98 --- /dev/null +++ b/src/main/launcher/logger.h @@ -0,0 +1,42 @@ +#ifndef LAUNCHER_LOGGER_H +#define LAUNCHER_LOGGER_H + +#include +#include + +enum logger_level { + LOGGER_LEVEL_OFF = 0, + LOGGER_LEVEL_FATAL = 1, + LOGGER_LEVEL_WARNING = 2, + LOGGER_LEVEL_INFO = 3, + LOGGER_LEVEL_MISC = 4, + LOGGER_LEVEL_ALL = 5, + LOGGER_LEVEL_DEFAULT = 6 +}; + +void logger_early_init(const char *log_file_path); + +void logger_init( + const char *filename, + bool enable_console, + bool enable_file, + bool rotate_file, + bool append_file, + uint16_t count_file); + +void logger_level_set(enum logger_level level); + +/** + * Write a log message from AVS to the logging backend. + * + * @param str String to log + * @param len Total length of the log string + */ +void logger_log_avs_log_message(char *str, size_t len); + +/** + * Shutdown and cleanup the logging backend. + */ +void logger_finit(); + +#endif \ No newline at end of file diff --git a/src/main/launcher/main.c b/src/main/launcher/main.c index 70c5184d..4b1b68a0 100644 --- a/src/main/launcher/main.c +++ b/src/main/launcher/main.c @@ -1,338 +1,23 @@ -#include - -#include -#include -#include #include -#include "imports/avs-ea3.h" -#include "imports/avs.h" - -#include "launcher/avs-context.h" -#include "launcher/ea3-config.h" -#include "launcher/module.h" +#include "launcher/launcher.h" #include "launcher/options.h" -#include "launcher/property.h" -#include "launcher/stubs.h" -#include "launcher/version.h" - -#include "util/codepage.h" -#include "util/defs.h" -#include "util/fs.h" -#include "util/log.h" -#include "util/mem.h" -#include "util/os.h" -#include "util/str.h" - -/* Gratuitous API changes orz */ -static AVS_LOG_WRITER(log_callback, chars, nchars, ctx) -{ - wchar_t *utf16; - char *utf8; - int utf16_len; - int utf8_len; - int result; - DWORD nwritten; - HANDLE console; - HANDLE file; - - /* Ignore existing NUL terminator */ - - nchars--; - - /* Transcode shit_jis to UTF-8 */ - - utf16_len = MultiByteToWideChar(CP_SHIFT_JIS, 0, chars, nchars, NULL, 0); - - if (utf16_len == 0) { - abort(); - } - - utf16 = xmalloc(sizeof(*utf16) * utf16_len); - result = - MultiByteToWideChar(CP_SHIFT_JIS, 0, chars, nchars, utf16, utf16_len); - - if (result == 0) { - abort(); - } - - utf8_len = - WideCharToMultiByte(CP_UTF8, 0, utf16, utf16_len, NULL, 0, NULL, NULL); - - if (utf8_len == 0) { - abort(); - } - - utf8 = xmalloc(utf8_len + 2); - result = WideCharToMultiByte( - CP_UTF8, 0, utf16, utf16_len, utf8, utf8_len, NULL, NULL); - - if (result == 0) { - abort(); - } - -#if AVS_VERSION >= 1500 - utf8[utf8_len + 0] = '\r'; - utf8[utf8_len + 1] = '\n'; - - utf8_len += 2; -#endif - - /* Write to console and log file */ - - file = (HANDLE) ctx; - console = GetStdHandle(STD_OUTPUT_HANDLE); - - if (ctx != INVALID_HANDLE_VALUE) { - WriteFile(file, utf8, utf8_len, &nwritten, NULL); - } - - WriteFile(console, utf8, utf8_len, &nwritten, NULL); - - /* Clean up */ - - free(utf8); - free(utf16); -} - -static void load_hook_dlls(struct array *hook_dlls) -{ - const char *hook_dll; - - for (size_t i = 0; i < hook_dlls->nitems; i++) { - hook_dll = *array_item(char *, hook_dlls, i); - - if (LoadLibraryA(hook_dll) == NULL) { - LPSTR buffer; - - FormatMessageA( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR) &buffer, - 0, - NULL); - - log_fatal("%s: Failed to load hook DLL: %s", hook_dll, buffer); - - LocalFree(buffer); - } - } -} int main(int argc, const char **argv) { - bool ok; - HANDLE logfile; - - struct ea3_ident ea3; - struct module_context module; struct options options; - struct property *app_config; - struct property *avs_config; - struct property *ea3_config; - - struct property_node *app_config_root; - struct property_node *avs_config_root; - struct property_node *ea3_config_root; - - log_to_writer(log_writer_file, stdout); - log_info( - "launcher build date %s, gitrev %s", - launcher_build_date, - launcher_gitrev); - - /* Read command line */ - options_init(&options); if (!options_read_cmdline(&options, argc, argv)) { options_print_usage(); - return EXIT_FAILURE; - } - - /* If enabled, wait for a remote debugger to attach. Spawning launcher - with a debugger crashes it for some reason (e.g. on jubeat08). However, - starting the launcher separately and attaching a remote debugger works */ - - if (options.remote_debugger) { - log_info("Waiting until debugger attaches to remote process..."); - - while (true) { - BOOL res = FALSE; - if (!CheckRemoteDebuggerPresent(GetCurrentProcess(), &res)) { - log_fatal( - "CheckRemoteDebuggerPresent failed: %08x", - (unsigned int) GetLastError()); - } - - if (res) { - log_info("Debugger attached, resuming"); - break; - } - - Sleep(1000); - } - } - - /* Start up AVS */ - - if (options.logfile != NULL) { - logfile = CreateFileA( - options.logfile, - GENERIC_WRITE, - FILE_SHARE_READ, - NULL, - CREATE_ALWAYS, - 0, - NULL); - } else { - logfile = INVALID_HANDLE_VALUE; - } - - avs_config = boot_property_load(options.avs_config_path); - avs_config_root = property_search(avs_config, 0, "/config"); - - if (avs_config_root == NULL) { - log_fatal("%s: /config missing", options.avs_config_path); - } - - load_hook_dlls(&options.before_hook_dlls); - - avs_context_init( - avs_config_root, - options.avs_heap_size, - options.std_heap_size, - log_callback, - logfile); - - boot_property_free(avs_config); - - log_to_external( - log_body_misc, log_body_info, log_body_warning, log_body_fatal); - - os_version_log(); - - /* Load game DLL */ - - if (options.iat_hook_dlls.nitems > 0) { - module_context_init_with_iat_hooks( - &module, options.module, &options.iat_hook_dlls); - } else { - module_context_init(&module, options.module); + exit(EXIT_FAILURE); } - /* Load hook DLLs */ - - load_hook_dlls(&options.hook_dlls); - - /* Inject GetModuleHandle hooks */ - - stubs_init(); - - /* Prepare ea3 config */ - - ea3_config = boot_property_load(options.ea3_config_path); - ea3_config_root = property_search(ea3_config, 0, "/ea3"); - - if (ea3_config_root == NULL) { - log_fatal("%s: /ea3 missing", options.ea3_config_path); - } - - ea3_ident_init(&ea3); - - if (!ea3_ident_from_property(&ea3, ea3_config)) { - log_fatal( - "%s: Error reading IDs from config file", options.ea3_config_path); - } - - if (options.softid != NULL) { - str_cpy(ea3.softid, lengthof(ea3.softid), options.softid); - } - - if (options.pcbid != NULL) { - str_cpy(ea3.pcbid, lengthof(ea3.pcbid), options.pcbid); - } - - if (!ea3.hardid[0]) { - ea3_ident_hardid_from_ethernet(&ea3); - } - - /* Invoke dll_entry_init */ - - if (path_exists(options.app_config_path)) { - app_config = boot_property_load(options.app_config_path); - } else { - log_warning( - "%s: app config file missing, using empty", - options.app_config_path); - app_config = boot_property_load_cstring("dummy"); - } - - app_config_root = property_search(app_config, 0, "/param"); - - if (app_config_root == NULL) { - log_fatal("%s: /param missing", options.app_config_path); - } - - if (IsDebuggerPresent()) { - /* Opportunity for breakpoint setup etc */ - DebugBreak(); - } - - ok = ea3_ident_invoke_module_init(&ea3, &module, app_config_root); - - if (!ok) { - log_fatal("%s: dll_module_init() returned failure", options.module); - } - - boot_property_free(app_config); - - ea3_ident_to_property(&ea3, ea3_config); - - if (options.override_urlslash_enabled) { - log_info( - "Overriding url_slash to: %d", options.override_urlslash_value); - - ea3_ident_replace_property_bool( - ea3_config_root, - "/network/url_slash", - options.override_urlslash_value); - } - - if (options.override_service != NULL) { - log_info("Overriding service url to: %s", options.override_service); - - ea3_ident_replace_property_str( - ea3_config_root, "/network/services", options.override_service); - } - - /* Start up e-Amusement client */ - - ea3_boot(ea3_config_root); - boot_property_free(ea3_config); - - /* Run application */ - - module_context_invoke_main(&module); - - /* Shut down */ - - ea3_shutdown(); - - log_to_writer(log_writer_file, stdout); - avs_context_fini(); - - if (logfile != INVALID_HANDLE_VALUE) { - CloseHandle(logfile); - } + launcher_main(&options); - module_context_fini(&module); options_fini(&options); return EXIT_SUCCESS; -} +} \ No newline at end of file diff --git a/src/main/launcher/module.c b/src/main/launcher/module.c index b3beff26..0ad0d518 100644 --- a/src/main/launcher/module.c +++ b/src/main/launcher/module.c @@ -1,3 +1,5 @@ +#define LOG_MODULE "module" + #include #include "hook/pe.h" @@ -6,17 +8,21 @@ #include "imports/eapki.h" #include "launcher/module.h" +#include "launcher/property-util.h" #include "util/log.h" #include "util/str.h" #define MM_ALLOCATION_GRANULARITY 0x10000 -static bool module_replace_dll_iat(HMODULE hModule, struct array *iat_hook_dlls) +static bool +module_replace_dll_iat(HMODULE hModule, const struct array *iat_hook_dlls) { log_assert(hModule); log_assert(iat_hook_dlls); + log_misc("replace dll iat: %p", hModule); + if (iat_hook_dlls->nitems == 0) return true; @@ -127,11 +133,13 @@ static bool module_replace_dll_iat(HMODULE hModule, struct array *iat_hook_dlls) return false; } -void module_context_init(struct module_context *module, const char *path) +void module_init(struct module_context *module, const char *path) { log_assert(module != NULL); log_assert(path != NULL); + log_info("init: %s", path); + module->dll = LoadLibrary(path); if (module->dll == NULL) { @@ -159,16 +167,20 @@ void module_context_init(struct module_context *module, const char *path) } module->path = str_dup(path); + + log_misc("init done"); } -void module_context_init_with_iat_hooks( +void module_with_iat_hooks_init( struct module_context *module, const char *path, - struct array *iat_hook_dlls) + const struct array *iat_hook_dlls) { log_assert(module != NULL); log_assert(path != NULL); + log_info("init iat hooks: %s", path); + module->dll = LoadLibraryExA(path, NULL, DONT_RESOLVE_DLL_REFERENCES); if (module->dll == NULL) { @@ -211,16 +223,71 @@ void module_context_init_with_iat_hooks( module->path = str_dup(path); } -bool module_context_invoke_init( +void module_init_invoke( const struct module_context *module, - char *sidcode, - struct property_node *app_config) + struct ea3_ident_config *ea3_ident_config, + struct property_node *app_params_node) { + char sidcode_short[17]; + char sidcode_long[21]; + char security_code[9]; dll_entry_init_t init; + bool ok; - log_assert(module != NULL); - log_assert(sidcode != NULL); - log_assert(app_config != NULL); + log_info("init invoke"); + + /* Set up security env vars */ + + str_format( + security_code, + lengthof(security_code), + "G*%s%s%s%s", + ea3_ident_config->model, + ea3_ident_config->dest, + ea3_ident_config->spec, + ea3_ident_config->rev); + + log_misc("security code: %s", security_code); + + std_setenv("/env/boot/version", "0.0.0"); + std_setenv("/env/profile/security_code", security_code); + std_setenv("/env/profile/system_id", ea3_ident_config->pcbid); + std_setenv("/env/profile/account_id", ea3_ident_config->pcbid); + std_setenv("/env/profile/license_id", ea3_ident_config->softid); + std_setenv("/env/profile/software_id", ea3_ident_config->softid); + std_setenv("/env/profile/hardware_id", ea3_ident_config->hardid); + + /* Set up the short sidcode string, let dll_entry_init mangle it */ + + str_format( + sidcode_short, + lengthof(sidcode_short), + "%s%s%s%s%s", + ea3_ident_config->model, + ea3_ident_config->dest, + ea3_ident_config->spec, + ea3_ident_config->rev, + ea3_ident_config->ext); + + log_misc("sidcode short: %s", sidcode_short); + + /* Set up long-form sidcode env var */ + + str_format( + sidcode_long, + lengthof(sidcode_long), + "%s:%s:%s:%s:%s", + ea3_ident_config->model, + ea3_ident_config->dest, + ea3_ident_config->spec, + ea3_ident_config->rev, + ea3_ident_config->ext); + + log_misc("sidecode long: %s", sidcode_long); + + /* Set this up beforehand, as certain games require it in dll_entry_init */ + + std_setenv("/env/profile/soft_id_code", sidcode_long); init = (void *) GetProcAddress(module->dll, "dll_entry_init"); @@ -229,16 +296,67 @@ bool module_context_invoke_init( "%s: dll_entry_init not found. Is this a game DLL?", module->path); } - return init(sidcode, app_config); + log_info("Invoking game init..."); + + struct property *prop = + property_util_cstring_load("p3io"); + + struct property_node *prop_node = property_search(prop, NULL, "/param"); + + property_util_log(prop); + property_util_node_log(prop_node); + + ok = init(sidcode_short, prop_node); + + if (!ok) { + log_fatal("%s: dll_module_init() returned failure", module->path); + } else { + log_info("Game init done"); + } + + /* Back-propagate sidcode, as some games modify it during init */ + + memcpy( + ea3_ident_config->model, + sidcode_short + 0, + sizeof(ea3_ident_config->model) - 1); + ea3_ident_config->dest[0] = sidcode_short[3]; + ea3_ident_config->spec[0] = sidcode_short[4]; + ea3_ident_config->rev[0] = sidcode_short[5]; + memcpy( + ea3_ident_config->ext, + sidcode_short + 6, + sizeof(ea3_ident_config->ext)); + + /* Set up long-form sidcode env var again */ + + str_format( + sidcode_long, + lengthof(sidcode_long), + "%s:%s:%s:%s:%s", + ea3_ident_config->model, + ea3_ident_config->dest, + ea3_ident_config->spec, + ea3_ident_config->rev, + ea3_ident_config->ext); + + std_setenv("/env/profile/soft_id_code", sidcode_long); + + log_misc("back-propagated sidcode long: %s", sidcode_long); + + log_misc("init invoke done"); } -bool module_context_invoke_main(const struct module_context *module) +bool module_main_invoke(const struct module_context *module) { /* GCC warns if you call a variable "main" */ dll_entry_main_t main_; + bool result; log_assert(module != NULL); + log_info("main invoke"); + main_ = (void *) GetProcAddress(module->dll, "dll_entry_main"); if (main_ == NULL) { @@ -246,11 +364,19 @@ bool module_context_invoke_main(const struct module_context *module) "%s: dll_entry_main not found. Is this a game DLL?", module->path); } - return main_(); + log_info("Invoking game's main function..."); + + result = main_(); + + log_info("Main terminated, result: %d", result); + + return result; } -void module_context_fini(struct module_context *module) +void module_fini(struct module_context *module) { + log_info("fini"); + if (module == NULL) { return; } @@ -260,4 +386,6 @@ void module_context_fini(struct module_context *module) if (module->dll != NULL) { FreeLibrary(module->dll); } + + log_misc("fini done"); } diff --git a/src/main/launcher/module.h b/src/main/launcher/module.h index f2a851eb..ed9b7327 100644 --- a/src/main/launcher/module.h +++ b/src/main/launcher/module.h @@ -5,6 +5,8 @@ #include "imports/avs.h" +#include "launcher/ea3-ident-config.h" + #include "util/array.h" struct module_context { @@ -12,16 +14,16 @@ struct module_context { char *path; }; -void module_context_init(struct module_context *module, const char *path); -void module_context_init_with_iat_hooks( +void module_init(struct module_context *module, const char *path); +void module_with_iat_hooks_init( struct module_context *module, const char *path, - struct array *iat_hook_dlls); -bool module_context_invoke_init( + const struct array *iat_hook_dlls); +void module_init_invoke( const struct module_context *module, - char *sidcode, - struct property_node *app_config); -bool module_context_invoke_main(const struct module_context *module); -void module_context_fini(struct module_context *module); + struct ea3_ident_config *ea3_ident_config, + struct property_node *app_params_node); +bool module_main_invoke(const struct module_context *module); +void module_fini(struct module_context *module); #endif diff --git a/src/main/launcher/options.c b/src/main/launcher/options.c index 757555ec..8bbd6df4 100644 --- a/src/main/launcher/options.c +++ b/src/main/launcher/options.c @@ -1,3 +1,5 @@ +#define LOG_MODULE "options" + #include #include #include @@ -6,62 +8,42 @@ #include "launcher/options.h" -#include "util/array.h" -#include "util/log.h" +#include "util/mem.h" #include "util/str.h" -#define DEFAULT_HEAP_SIZE 16777216 - void options_init(struct options *options) { - options->std_heap_size = DEFAULT_HEAP_SIZE; - options->avs_heap_size = DEFAULT_HEAP_SIZE; - options->app_config_path = "prop/app-config.xml"; - options->avs_config_path = "prop/avs-config.xml"; - options->ea3_config_path = "prop/ea3-config.xml"; - options->softid = NULL; - options->pcbid = NULL; - options->module = NULL; - options->logfile = NULL; - options->remote_debugger = false; - array_init(&options->hook_dlls); - array_init(&options->before_hook_dlls); - array_init(&options->iat_hook_dlls); - - options->override_service = NULL; - options->override_urlslash_enabled = false; - options->override_urlslash_value = false; + memset(options, 0, sizeof(struct options)); + + array_init(&options->hook.hook_dlls); + array_init(&options->hook.before_hook_dlls); + array_init(&options->hook.iat_hook_dlls); } bool options_read_cmdline(struct options *options, int argc, const char **argv) { + bool got_launcher_config; + + got_launcher_config = false; + for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { - case 'A': - if (i + 1 >= argc) { - return false; - } - - options->app_config_path = argv[++i]; - - break; - - case 'E': + case 'T': if (i + 1 >= argc) { return false; } - options->ea3_config_path = argv[++i]; + options->bootstrap.config_path = argv[++i]; break; - case 'V': + case 'Z': if (i + 1 >= argc) { return false; } - options->avs_config_path = argv[++i]; + options->bootstrap.selector = argv[++i]; break; @@ -70,7 +52,7 @@ bool options_read_cmdline(struct options *options, int argc, const char **argv) return false; } - options->pcbid = argv[++i]; + options->eamuse.pcbid = argv[++i]; break; @@ -79,7 +61,7 @@ bool options_read_cmdline(struct options *options, int argc, const char **argv) return false; } - options->softid = argv[++i]; + options->eamuse.softid = argv[++i]; break; @@ -88,70 +70,63 @@ bool options_read_cmdline(struct options *options, int argc, const char **argv) return false; } - options->avs_heap_size = - (size_t) strtol(argv[++i], NULL, 0); - - if (options->avs_heap_size == 0) { - return false; - } + *array_append(const char *, &options->hook.hook_dlls) = + argv[++i]; break; -#ifdef AVS_HAS_STD_HEAP - case 'T': + case 'B': if (i + 1 >= argc) { return false; } - options->std_heap_size = - (size_t) strtol(argv[++i], NULL, 0); - - if (options->std_heap_size == 0) { - return false; - } + *array_append( + const char *, &options->hook.before_hook_dlls) = + argv[++i]; break; -#endif - case 'K': + case 'I': { if (i + 1 >= argc) { return false; } - *array_append(const char *, &options->hook_dlls) = - argv[++i]; + const char *dll = argv[++i]; + log_assert(strstr(dll, "=") != NULL); + + *array_append(const char *, &options->hook.iat_hook_dlls) = + dll; break; + } - case 'B': + case 'L': if (i + 1 >= argc) { return false; } - *array_append(const char *, &options->before_hook_dlls) = - argv[++i]; + long tmp = strtol(argv[++i], NULL, 0); - break; - - case 'I': { - if (i + 1 >= argc) { + if (tmp < LOG_LEVEL_FATAL || tmp > LOG_LEVEL_MISC) { return false; } - const char *dll = argv[++i]; - log_assert(strstr(dll, "=") != NULL); - - *array_append(const char *, &options->iat_hook_dlls) = dll; + options->log.level = xmalloc(sizeof(enum log_level)); + *(options->log.level) = (enum log_level) tmp; break; - } case 'Y': if (i + 1 >= argc) { return false; } - options->logfile = argv[++i]; + options->log.file_path = argv[++i]; + + break; + + case 'C': + options->debug.log_property_configs = true; break; @@ -160,7 +135,7 @@ bool options_read_cmdline(struct options *options, int argc, const char **argv) return false; } - options->override_service = argv[++i]; + options->eamuse.service_url = argv[++i]; break; @@ -169,22 +144,23 @@ bool options_read_cmdline(struct options *options, int argc, const char **argv) return false; } - options->override_urlslash_enabled = true; + options->eamuse.urlslash = xmalloc(sizeof(bool)); const char *urlslash_value = argv[++i]; - options->override_urlslash_value = false; + *(options->eamuse.urlslash) = false; + if (_stricmp(urlslash_value, "1") == 0) { - options->override_urlslash_value = true; + *(options->eamuse.urlslash) = true; } if (_stricmp(urlslash_value, "true") == 0) { - options->override_urlslash_value = true; + *(options->eamuse.urlslash) = true; } break; case 'D': - options->remote_debugger = true; + options->debug.remote_debugger = true; break; @@ -192,59 +168,71 @@ bool options_read_cmdline(struct options *options, int argc, const char **argv) break; } } else { - if (!options->module) { - options->module = argv[i]; + if (!got_launcher_config) { + options->launcher.config_path = argv[i]; + got_launcher_config = true; } } } - if (options->module) { - return true; - } else { - return false; - } + return got_launcher_config; } void options_print_usage(void) { fprintf( stderr, - "Usage: launcher.exe [launcher options...] [hooks " - "options...] \n" + "Usage:\n" + " launcher.exe [launcher options as overrides...] " + "[further options, e.g. for hook libraries to pick up...]\n" "\n" - " The following options can be specified before the app DLL " - "path:\n" + " The following options can be specified before the launcher.xml " + "configuration file:\n" "\n" - " -A [filename] App configuration file (default: " - "prop/app-config.xml)\n" - " -V [filename] AVS configuration file (default: " - "prop/avs-config.xml)\n" - " -E [filename] ea3 configuration file (default: " - "prop/ea3-config.xml)\n" - " -H [bytes] AVS heap size (default: 16777216)\n" -#ifdef AVS_HAS_STD_HEAP - " -T [bytes] 'std' heap size (default 16777216)\n" -#endif - " -P [pcbid] Specify PCBID (default: use ea3 config)\n" - " -R [pcbid] Specify Soft ID (default: use ea3 config)\n" - " -S [url] Specify service url (default: use ea3 config)\n" - " -U [0/1] Specify url_slash (default: use ea3 config)\n" - " -K [filename] Load hook DLL (can be specified multiple " + " Bootstrap\n" + " -T [filename] Bootstrap configuration file\n" + " -Z [selector] Bootstrap selector used in configuration\n" + "\n" + " Eamuse\n" + " -P [pcbid] Specify PCBID\n" + " -R [softid] Specify Soft ID\n" + " -S [url] Specify service url\n" + " -U [0/1] Specify url_slash enabled/disabled\n" + "\n" + " Hook\n" + " -H [filename] Load hook DLL (can be specified multiple " "times)\n" " -B [filename] Load pre-hook DLL loaded before avs boot " "(can be specified multiple times)\n" " -I [filename] Load pre-hook DLL that overrides IAT reference " - "before execution" - "(can be specified multiple times)\n" + "before execution (can be specified multiple times)\n" + "\n" + " Logging\n" + " -L [0/1/2/3] Log level for both console and file with " + "increasing verbosity (0 = fatal, 1 = warn, 2 = info, 3 = misc)\n" " -Y [filename] Log to a file in addition to the console\n" + "\n" + " Debug\n" " -D Halt the launcher before bootstrapping AVS " - "until a" - " remote debugger is attached\n"); + "until a remote debugger is attached\n" + " -C Log all loaded and final (property) " + "configuration that launcher uses for bootstrapping. IMPORTANT: DO NOT " + "ENABLE unless you know what you are doing. This prints sensitive data " + "and credentials to the console and logfile. BE CAUTIOUS not to share " + "this information before redaction."); } void options_fini(struct options *options) { - array_fini(&options->hook_dlls); - array_fini(&options->before_hook_dlls); - array_fini(&options->iat_hook_dlls); + array_fini(&options->hook.hook_dlls); + array_fini(&options->hook.before_hook_dlls); + array_fini(&options->hook.iat_hook_dlls); + + if (options->log.level) { + free(options->log.level); + } + + if (options->eamuse.urlslash) { + free(options->eamuse.urlslash); + } } diff --git a/src/main/launcher/options.h b/src/main/launcher/options.h index 13f1c0fb..9f80dfd0 100644 --- a/src/main/launcher/options.h +++ b/src/main/launcher/options.h @@ -5,24 +5,50 @@ #include #include "util/array.h" +#include "util/log.h" +#include "launcher/bootstrap-config.h" + +// Launcher options (cmd params) are limited to: +// - Options to run a (vanilla) game without additional launcher features, e.g. +// hooking +// - Options that are handy to have for development/debugging purpose, e.g. +// quickly switching on/off +// logging levels +// +// Everything else is driven by a composable configuration file (launcher.xml) struct options { - size_t std_heap_size; - size_t avs_heap_size; - const char *app_config_path; - const char *avs_config_path; - const char *ea3_config_path; - const char *softid; - const char *pcbid; - const char *module; - const char *logfile; - struct array hook_dlls; - struct array before_hook_dlls; - struct array iat_hook_dlls; - bool remote_debugger; - const char *override_service; - bool override_urlslash_enabled; - bool override_urlslash_value; + struct options_launcher { + const char *config_path; + } launcher; + + struct options_bootstrap { + const char *config_path; + const char *selector; + } bootstrap; + + struct options_log { + enum log_level *level; + const char *file_path; + } log; + + struct options_eamuse { + const char *softid; + const char *pcbid; + const char *service_url; + bool *urlslash; + } eamuse; + + struct options_hook { + struct array hook_dlls; + struct array before_hook_dlls; + struct array iat_hook_dlls; + } hook; + + struct options_debug { + bool remote_debugger; + bool log_property_configs; + } debug; }; void options_init(struct options *options); diff --git a/src/main/launcher/property-util.c b/src/main/launcher/property-util.c new file mode 100644 index 00000000..4c44b04a --- /dev/null +++ b/src/main/launcher/property-util.c @@ -0,0 +1,618 @@ +#define LOG_MODULE "property-util" + +#include + +#include +#include +#include +#include + +#include "avs-util/error.h" + +#include "imports/avs.h" + +#include "launcher/property-util.h" + +#include "util/log.h" +#include "util/mem.h" +#include "util/str.h" + +#define PROPERTY_STRUCTURE_META_SIZE 576 + +typedef void (*rewinder)(uint32_t context); + +struct cstring_read_handle { + const char *buffer; + size_t buffer_len; + size_t offset; +}; + +static struct property *property_util_do_load( + avs_reader_t reader, rewinder rewinder, uint32_t context, const char *name) +{ + struct property *prop; + void *buffer; + int nbytes; + + nbytes = property_read_query_memsize(reader, context, 0, 0); + + if (nbytes < 0) { + log_fatal("%s: Error querying configuration file", name); + } + + buffer = xmalloc(nbytes); + prop = property_create( + PROPERTY_FLAG_READ | PROPERTY_FLAG_WRITE | PROPERTY_FLAG_CREATE | + PROPERTY_FLAG_APPEND, + buffer, + nbytes); + rewinder(context); + + if (!property_insert_read(prop, 0, reader, context)) { + log_fatal("%s: Error reading configuration file", name); + } + + return prop; +} + +static int property_util_fread(uint32_t context, void *bytes, size_t nbytes) +{ + FILE *f; + + f = TlsGetValue(context); + + return fread(bytes, 1, nbytes, f); +} + +static void property_util_frewind(uint32_t context) +{ + FILE *f = TlsGetValue(context); + rewind(f); +} + +static void property_util_log_node_tree_rec( + struct property_node *parent_node, const char *parent_path) +{ + char cur_path[4096]; + // 256 found in AVS code as size used on property_node_name + char cur_node_name[256]; + + struct property_node *child_node; + enum property_type property_type; + + int8_t value_s8; + int16_t value_s16; + int32_t value_s32; + int64_t value_s64; + uint8_t value_u8; + uint16_t value_u16; + uint32_t value_u32; + uint64_t value_u64; + char value_str[4096]; + bool value_bool; + + avs_error error; + + // Carry on the full root path down the node tree + property_node_name(parent_node, cur_node_name, sizeof(cur_node_name)); + + str_cpy(cur_path, sizeof(cur_path), parent_path); + str_cat(cur_path, sizeof(cur_path), "/"); + str_cat(cur_path, sizeof(cur_path), cur_node_name); + + child_node = property_node_traversal(parent_node, TRAVERSE_FIRST_CHILD); + + // parent node is a leaf node, print all data of it + if (child_node == NULL) { + property_type = property_node_type(parent_node); + + switch (property_type) { + case PROPERTY_TYPE_VOID: + log_misc("%s: ", cur_path); + break; + + case PROPERTY_TYPE_S8: + property_node_read( + parent_node, property_type, &value_s8, sizeof(value_s8)); + log_misc("%s: %" PRId8, cur_path, value_s8); + break; + + case PROPERTY_TYPE_S16: + property_node_read( + parent_node, property_type, &value_s16, sizeof(value_s16)); + log_misc("%s: %" PRId16, cur_path, value_s16); + break; + + case PROPERTY_TYPE_S32: + property_node_read( + parent_node, property_type, &value_s32, sizeof(value_s32)); + log_misc("%s: %" PRId32, cur_path, value_s32); + break; + + case PROPERTY_TYPE_S64: + property_node_read( + parent_node, property_type, &value_s64, sizeof(value_s64)); + log_misc("%s: %" PRId64, cur_path, value_s64); + break; + + case PROPERTY_TYPE_U8: + property_node_read( + parent_node, property_type, &value_u8, sizeof(value_u8)); + log_misc("%s: %" PRIu8, cur_path, value_u8); + break; + + case PROPERTY_TYPE_U16: + property_node_read( + parent_node, property_type, &value_u16, sizeof(value_u16)); + log_misc("%s: %" PRIu16, cur_path, value_u16); + break; + + case PROPERTY_TYPE_U32: + property_node_read( + parent_node, property_type, &value_u32, sizeof(value_u32)); + log_misc("%s: %" PRIu32, cur_path, value_u32); + break; + + case PROPERTY_TYPE_U64: + property_node_read( + parent_node, property_type, &value_u64, sizeof(value_u64)); + log_misc("%s: %" PRIu64, cur_path, value_u64); + break; + + case PROPERTY_TYPE_STR: + property_node_read( + parent_node, property_type, value_str, sizeof(value_str)); + log_misc("%s: %s", cur_path, value_str); + + break; + + case PROPERTY_TYPE_BOOL: + property_node_read( + parent_node, + property_type, + &value_bool, + sizeof(value_bool)); + log_misc("%s: %d", cur_path, value_bool); + + break; + + case PROPERTY_TYPE_BIN: + log_misc("%s: ", cur_path); + break; + + case PROPERTY_TYPE_ATTR: + error = property_node_read( + parent_node, property_type, value_str, sizeof(value_str)); + + if (AVS_IS_ERROR(error)) { + log_fatal( + "%s, property read failed: %s", + cur_path, + avs_util_error_str(error)); + } + + log_misc("%s@: %s", cur_path, value_str); + + break; + + case PROPERTY_TYPE_VOID_WITH_ATTRIBUTES: + log_misc("%s: ", cur_path); + + child_node = + property_node_traversal(parent_node, TRAVERSE_FIRST_ATTR); + + while (child_node) { + property_util_log_node_tree_rec(child_node, cur_path); + + child_node = property_node_traversal( + child_node, TRAVERSE_NEXT_SIBLING); + } + + break; + + case PROPERTY_TYPE_STR_WITH_ATTRIBUTES: + error = property_node_read( + parent_node, property_type, value_str, sizeof(value_str)); + + if (AVS_IS_ERROR(error)) { + log_fatal( + "%s, property read failed: %s", + cur_path, + avs_util_error_str(error)); + } + + log_misc("%s: %s", cur_path, value_str); + + child_node = + property_node_traversal(parent_node, TRAVERSE_FIRST_ATTR); + + while (child_node) { + property_util_log_node_tree_rec(child_node, cur_path); + + child_node = property_node_traversal( + child_node, TRAVERSE_NEXT_SIBLING); + } + + break; + + default: + log_misc("%s: (%d)", cur_path, property_type); + break; + } + } else { + while (child_node) { + property_util_log_node_tree_rec(child_node, cur_path); + + child_node = + property_node_traversal(child_node, TRAVERSE_NEXT_SIBLING); + } + } +} + +static int +property_util_cstring_read(uint32_t context, void *bytes, size_t nbytes) +{ + int result = 0; + struct cstring_read_handle *h = TlsGetValue(context); + + if (h->offset < h->buffer_len) { + result = min(nbytes, h->buffer_len - h->offset); + memcpy(bytes, (const void *) (h->buffer + h->offset), result); + h->offset += result; + } + return result; +} + +static void property_util_cstring_rewind(uint32_t context) +{ + struct cstring_read_handle *h = TlsGetValue(context); + h->offset = 0; +} + +static int property_util_avs_read(uint32_t context, void *bytes, size_t nbytes) +{ + avs_desc desc = (avs_desc) context; + return avs_fs_read(desc, bytes, nbytes); +} + +static void property_util_avs_rewind(uint32_t context) +{ + avs_desc desc = (avs_desc) context; + avs_fs_lseek(desc, 0, AVS_SEEK_SET); +} + +void property_util_log(struct property *property) +{ + property_util_log_node_tree_rec(property_search(property, NULL, "/"), ""); +} + +void property_util_node_log(struct property_node *node) +{ + property_util_log_node_tree_rec(node, ""); +} + +struct property *property_util_load(const char *filename) +{ + FILE *f; + uint32_t f_keyhole; + struct property *prop; + + log_assert(filename); + + /* AVS callbacks are only given a 32-bit context parameter, even in 64-bit + builds of AVS. We allocate a 32-bit TLS key and pass the context in this + manner instead. Inefficient, but it works. */ + + f = fopen(filename, "r"); + + f_keyhole = TlsAlloc(); + TlsSetValue(f_keyhole, f); + + if (f == NULL) { + log_fatal("%s: Error opening configuration file", filename); + } + + prop = property_util_do_load( + property_util_fread, property_util_frewind, f_keyhole, filename); + + TlsFree(f_keyhole); + + fclose(f); + + return prop; +} + +struct property *property_util_avs_fs_load(const char *filename) +{ + avs_desc desc; + struct property *prop; + + log_assert(filename); + + desc = avs_fs_open(filename, AVS_FILE_READ, AVS_FILE_FLAG_SHARE_READ); + + if (!desc) { + log_fatal("%s: Error opening configuration file", filename); + } + + prop = property_util_do_load( + property_util_avs_read, property_util_avs_rewind, desc, filename); + + avs_fs_close(desc); + + return prop; +} + +struct property *property_util_cstring_load(const char *cstring) +{ + uint32_t s_keyhole; + struct property *prop; + + log_assert(cstring); + + // see above + struct cstring_read_handle read_handle; + read_handle.buffer = cstring; + read_handle.buffer_len = strlen(cstring); + read_handle.offset = 0; + + s_keyhole = TlsAlloc(); + TlsSetValue(s_keyhole, &read_handle); + + prop = property_util_do_load( + property_util_cstring_read, + property_util_cstring_rewind, + s_keyhole, + ""); + + TlsFree(s_keyhole); + + return prop; +} + +uint32_t property_util_property_query_real_size(struct property *property) +{ + avs_error size; + + log_assert(property); + + // Returns the size of the actual data in the property structure only + // Hence, using that size only, allocating another buffer for a copy + // of this might fail or copying the data will fail because the buffer + // is too small + size = property_query_size(property); + + if (AVS_IS_ERROR(size)) { + log_fatal( + "Querying property size failed: %s", avs_util_error_str(size)); + } + + // Hack: *2 to have enough space and not cut off data when cloning/copying + // property data because...reasons? I haven't figured this one out and + // there doesn't seem to be an actual API call for that to return the + // "true" size that allows the caller to figure out how much memory + // they have to allocate to create a copy of the property structure + // with property_create and + return (PROPERTY_STRUCTURE_META_SIZE + size) * 2; +} + +void property_util_node_u8_replace( + struct property *property, + struct property_node *node, + const char *name, + uint8_t val) +{ + struct property_node *tmp; + + log_assert(node); + log_assert(name); + + tmp = property_search(property, node, name); + + if (tmp) { + property_node_remove(tmp); + } + + property_node_create(property, node, PROPERTY_TYPE_U8, name, val); +} + +void property_util_node_u16_replace( + struct property *property, + struct property_node *node, + const char *name, + uint16_t val) +{ + struct property_node *tmp; + + log_assert(node); + log_assert(name); + + tmp = property_search(property, node, name); + + if (tmp) { + property_node_remove(tmp); + } + + property_node_create(property, node, PROPERTY_TYPE_U16, name, val); +} + +void property_util_node_u32_replace( + struct property *property, + struct property_node *node, + const char *name, + uint32_t val) +{ + struct property_node *tmp; + + log_assert(node); + log_assert(name); + + tmp = property_search(property, node, name); + + if (tmp) { + property_node_remove(tmp); + } + + property_node_create(property, node, PROPERTY_TYPE_U32, name, val); +} + +void property_util_node_str_replace( + struct property *property, + struct property_node *node, + const char *name, + const char *val) +{ + struct property_node *tmp; + + log_assert(node); + log_assert(name); + + tmp = property_search(property, node, name); + + if (tmp) { + property_node_remove(tmp); + } + + property_node_create(property, node, PROPERTY_TYPE_STR, name, val); +} + +void property_util_node_bool_replace( + struct property *property, + struct property_node *node, + const char *name, + bool val) +{ + struct property_node *tmp; + + log_assert(node); + log_assert(name); + + tmp = property_search(property, node, name); + + if (tmp) { + property_node_remove(tmp); + } + + property_node_create(property, node, PROPERTY_TYPE_BOOL, name, val); +} + +static void _property_util_node_merge_rec( + struct property *parent_property, + struct property_node *parent, + struct property_node *source) +{ + char name[256]; + struct property_node *child; + struct property_node *matching_child; + + log_assert(parent_property); + + if (!source) { + return; + } + + if (!parent) { + property_node_clone(parent_property, parent, source, true); + return; + } + + child = property_node_traversal(source, TRAVERSE_FIRST_CHILD); + + while (child) { + property_node_name(child, name, sizeof(name)); + + matching_child = property_search(parent_property, parent, name); + + if (!matching_child) { + property_node_clone(parent_property, parent, child, true); + } else { + _property_util_node_merge_rec( + parent_property, matching_child, child); + } + + child = property_node_traversal(child, TRAVERSE_NEXT_SIBLING); + } +} + +struct property *property_util_merge(struct property **properties, size_t count) +{ + uint32_t total_size; + void *buffer; + struct property *merged_property; + int i; + struct property_node *parent_node; + struct property_node *to_merge_node; + + log_assert(properties); + log_assert(count > 0); + + total_size = 0; + + for (int i = 0; i < count; i++) { + total_size += property_util_property_query_real_size(properties[i]); + } + + buffer = xmalloc(total_size); + + merged_property = property_create( + PROPERTY_FLAG_READ | PROPERTY_FLAG_WRITE | PROPERTY_FLAG_CREATE | + PROPERTY_FLAG_APPEND, + buffer, + total_size); + + for (i = 0; i < count; i++) { + parent_node = property_search(merged_property, NULL, "/"); + to_merge_node = property_search(properties[i], NULL, "/"); + + property_util_node_merge(merged_property, parent_node, to_merge_node); + } + + return merged_property; +} + +struct property *property_util_clone(struct property_node *node) +{ + struct property *property; + struct property_node *root_node; + uint32_t size; + void *buffer; + + if (!node) { + return NULL; + } + + // Hack: Is it even possible to get the size of a (sub-) node without + // the property? 256kb should be fine for now, even for larger + // configurations. Obviously, this scales horribly and wastes a lot of + // memory for most smaller sub-nodes + size = 1024 * 256; + + buffer = xmalloc(size); + property = property_create( + PROPERTY_FLAG_READ | PROPERTY_FLAG_WRITE | PROPERTY_FLAG_CREATE | + PROPERTY_FLAG_APPEND, + buffer, + size); + root_node = property_search(property, NULL, ""); + + property_node_clone(property, root_node, node, true); + + return property; +} + +void property_util_node_merge( + struct property *parent_property, + struct property_node *parent, + struct property_node *source) +{ + _property_util_node_merge_rec(parent_property, parent, source); +} + +void property_util_free(struct property *prop) +{ + void *buffer; + + buffer = property_desc_to_buffer(prop); + property_destroy(prop); + free(buffer); +} diff --git a/src/main/launcher/property-util.h b/src/main/launcher/property-util.h new file mode 100644 index 00000000..07649c26 --- /dev/null +++ b/src/main/launcher/property-util.h @@ -0,0 +1,46 @@ +#ifndef PROPERTY_UTIL_H +#define PROPERTY_UTIL_H + +#include "imports/avs.h" + +void property_util_log(struct property *property); +void property_util_node_log(struct property_node *node); +struct property *property_util_load(const char *filename); +struct property *property_util_avs_fs_load(const char *filename); +struct property *property_util_cstring_load(const char *cstring); +uint32_t property_util_property_query_real_size(struct property *property); +void property_util_node_u8_replace( + struct property *property, + struct property_node *node, + const char *name, + uint8_t val); +void property_util_node_u16_replace( + struct property *property, + struct property_node *node, + const char *name, + uint16_t val); +void property_util_node_u32_replace( + struct property *property, + struct property_node *node, + const char *name, + uint32_t val); +void property_util_node_str_replace( + struct property *property, + struct property_node *node, + const char *name, + const char *val); +void property_util_node_bool_replace( + struct property *property, + struct property_node *node, + const char *name, + bool val); +struct property *property_util_clone(struct property_node *node); +struct property * +property_util_merge(struct property **properties, size_t count); +void property_util_node_merge( + struct property *parent_property, + struct property_node *parent_node, + struct property_node *source_node); +void property_util_free(struct property *prop); + +#endif diff --git a/src/main/launcher/property.c b/src/main/launcher/property.c deleted file mode 100644 index 2f5ded94..00000000 --- a/src/main/launcher/property.c +++ /dev/null @@ -1,135 +0,0 @@ -#include - -#include -#include -#include - -#include "imports/avs.h" - -#include "launcher/property.h" - -#include "util/log.h" -#include "util/mem.h" - -static int boot_property_fread(uint32_t context, void *bytes, size_t nbytes) -{ - FILE *f; - - f = TlsGetValue(context); - - return fread(bytes, 1, nbytes, f); -} - -struct cstring_read_handle { - const char *buffer; - size_t buffer_len; - size_t offset; -}; - -static int -boot_property_cstring_read(uint32_t context, void *bytes, size_t nbytes) -{ - int result = 0; - struct cstring_read_handle *h = TlsGetValue(context); - - if (h->offset < h->buffer_len) { - result = min(nbytes, h->buffer_len - h->offset); - memcpy(bytes, (const void *) (h->buffer + h->offset), result); - h->offset += result; - } - return result; -} - -struct property *boot_property_load(const char *filename) -{ - struct property *prop; - void *buffer; - int nbytes; - FILE *f; - uint32_t f_keyhole; - - /* AVS callbacks are only given a 32-bit context parameter, even in 64-bit - builds of AVS. We allocate a 32-bit TLS key and pass the context in this - manner instead. Inefficient, but it works. */ - - f = fopen(filename, "r"); - - f_keyhole = TlsAlloc(); - TlsSetValue(f_keyhole, f); - - if (f == NULL) { - log_fatal("%s: Error opening configuration file", filename); - } - - nbytes = property_read_query_memsize(boot_property_fread, f_keyhole, 0, 0); - - if (nbytes < 0) { - log_fatal("%s: Error querying configuration file", filename); - } - - buffer = xmalloc(nbytes); - prop = property_create( - PROPERTY_FLAG_READ | PROPERTY_FLAG_WRITE | PROPERTY_FLAG_CREATE | - PROPERTY_FLAG_APPEND, - buffer, - nbytes); - rewind(f); - - if (!property_insert_read(prop, 0, boot_property_fread, f_keyhole)) { - log_fatal("%s: Error reading configuration file", filename); - } - - TlsFree(f_keyhole); - - fclose(f); - - return prop; -} -struct property *boot_property_load_cstring(const char *cstring) -{ - struct property *prop; - void *buffer; - int nbytes; - uint32_t s_keyhole; - - // see above - struct cstring_read_handle read_handle; - read_handle.buffer = cstring; - read_handle.buffer_len = strlen(cstring); - read_handle.offset = 0; - - s_keyhole = TlsAlloc(); - TlsSetValue(s_keyhole, &read_handle); - - nbytes = property_read_query_memsize( - boot_property_cstring_read, s_keyhole, 0, 0); - - if (nbytes < 0) { - log_fatal("Error querying configuration string"); - } - - buffer = xmalloc(nbytes); - prop = property_create( - PROPERTY_FLAG_READ | PROPERTY_FLAG_WRITE | PROPERTY_FLAG_CREATE | - PROPERTY_FLAG_APPEND, - buffer, - nbytes); - - read_handle.offset = 0; - if (!property_insert_read(prop, 0, boot_property_cstring_read, s_keyhole)) { - log_fatal("Error inserting configuration string"); - } - - TlsFree(s_keyhole); - - return prop; -} - -void boot_property_free(struct property *prop) -{ - void *buffer; - - buffer = property_desc_to_buffer(prop); - property_destroy(prop); - free(buffer); -} diff --git a/src/main/launcher/property.h b/src/main/launcher/property.h deleted file mode 100644 index c3f14d0e..00000000 --- a/src/main/launcher/property.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef LAUNCHER_PROPERTY_H -#define LAUNCHER_PROPERTY_H - -#include "imports/avs.h" - -struct property *boot_property_load(const char *filename); -struct property *boot_property_load_cstring(const char *cstring); -void boot_property_free(struct property *prop); - -#endif diff --git a/src/main/launcher/stubs.c b/src/main/launcher/stubs.c index a524273b..80cb18bf 100644 --- a/src/main/launcher/stubs.c +++ b/src/main/launcher/stubs.c @@ -1,3 +1,5 @@ +#define LOG_MODULE "stubs" + #include #include @@ -116,6 +118,8 @@ static void *STDCALL my_GetProcAddress(HMODULE dll, const char *name) void stubs_init(void) { + log_info("Init"); + hook_table_apply( NULL, "kernel32.dll", stub_hook_syms, lengthof(stub_hook_syms)); } diff --git a/src/main/p3ioemu/emu.c b/src/main/p3ioemu/emu.c index dbf2c8a5..6486d595 100644 --- a/src/main/p3ioemu/emu.c +++ b/src/main/p3ioemu/emu.c @@ -48,8 +48,8 @@ static void p3io_cmd_get_cab_type_or_dipsw( static void p3io_cmd_get_video_freq( const struct p3io_req_get_video_freq *req, struct p3io_resp_get_video_freq *resp); -static void -p3io_cmd_unknown_2b(const struct p3io_req_unknown_2b *req, struct p3io_resp_unknown_2b *resp); +static void p3io_cmd_unknown_2b( + const struct p3io_req_unknown_2b *req, struct p3io_resp_unknown_2b *resp); static void p3io_cmd_init(const struct p3io_req_init *req, struct p3io_resp_init *resp); static void p3io_cmd_get_coinstock( @@ -57,8 +57,9 @@ static void p3io_cmd_get_coinstock( static void p3io_cmd_set_coin_counter( const struct p3io_req_set_coin_counter *req, struct p3io_resp_set_coin_counter *resp); -static void -p3io_cmd_unknown(const struct p3io_req_unknown_generic *req, struct p3io_resp_unknown_generic *resp); +static void p3io_cmd_unknown( + const struct p3io_req_unknown_generic *req, + struct p3io_resp_unknown_generic *resp); void p3io_emu_init(const struct p3io_ops *ops, void *ctx) { @@ -518,8 +519,8 @@ static void p3io_cmd_get_video_freq( } } -static void -p3io_cmd_unknown_2b(const struct p3io_req_unknown_2b *req, struct p3io_resp_unknown_2b *resp) +static void p3io_cmd_unknown_2b( + const struct p3io_req_unknown_2b *req, struct p3io_resp_unknown_2b *resp) { log_misc("Unknown 2b"); @@ -573,10 +574,13 @@ static void p3io_cmd_set_coin_counter( resp->status = 0; } -static void -p3io_cmd_unknown(const struct p3io_req_unknown_generic *req, struct p3io_resp_unknown_generic *resp) +static void p3io_cmd_unknown( + const struct p3io_req_unknown_generic *req, + struct p3io_resp_unknown_generic *resp) { - log_warning("Unsupported P3IO command, sending default response (might not work/crash though): %02x", + log_warning( + "Unsupported P3IO command, sending default response (might not " + "work/crash though): %02x", req->hdr.cmd); p3io_resp_hdr_init(&resp->hdr, sizeof(*resp), &req->hdr); diff --git a/src/main/util/Module.mk b/src/main/util/Module.mk index ab8d4956..af7851ec 100644 --- a/src/main/util/Module.mk +++ b/src/main/util/Module.mk @@ -5,6 +5,7 @@ src_util := \ cmdline.c \ crc.c \ crypto.c \ + debug.c \ fs.c \ hex.c \ iobuf.c \ diff --git a/src/main/util/debug.c b/src/main/util/debug.c new file mode 100644 index 00000000..f07e401c --- /dev/null +++ b/src/main/util/debug.c @@ -0,0 +1,184 @@ +#define LOG_MODULE "util-debug" + +#include + +#include + +#include "imports/dwarfstack.h" + +#include "util/debug.h" +#include "util/log.h" + +#define EX_DESC(name) \ + case EXCEPTION_##name: \ + desc = " (" #name ")"; \ + break + +static void _debug_stacktrace_printer( + uint64_t addr, + const char *filename, + int lineno, + const char *funcname, + void *context, + int columnno) +{ + int *count; + const char *delim; + void *ptr; + char buffer[512]; + char *buffer_ptr; + + count = context; + delim = strrchr(filename, '/'); + + if (delim) { + filename = delim + 1; + } + + delim = strrchr(filename, '\\'); + + if (delim) { + filename = delim + 1; + } + + ptr = (void *) (uintptr_t) addr; + + switch (lineno) { + case DWST_BASE_ADDR: + log_exception_handler("base address: 0x%p (%s)", ptr, filename); + break; + + case DWST_NOT_FOUND: + case DWST_NO_DBG_SYM: + case DWST_NO_SRC_FILE: + log_exception_handler( + " stack %02d: 0x%p (%s)", (*count)++, ptr, filename); + break; + + default: + buffer_ptr = buffer; + memset(buffer, 0, sizeof(buffer)); + + if (ptr) { + buffer_ptr += sprintf( + buffer_ptr, " stack %02d: 0x%p", (*count)++, ptr); + } else { + buffer_ptr += sprintf( + buffer_ptr, + " %*s", + (int) sizeof(void *) * 2, + ""); + } + + buffer_ptr += sprintf(buffer_ptr, " (%s:%d", filename, lineno); + + if (columnno > 0) { + buffer_ptr += sprintf(buffer_ptr, ":%d", columnno); + } + + buffer_ptr += sprintf(buffer_ptr, ")"); + + if (funcname) { + buffer_ptr += sprintf(buffer_ptr, " [%s]", funcname); + } + + log_exception_handler(buffer); + + break; + } +} + +static LONG WINAPI _debug_unhandled_exception_filter(LPEXCEPTION_POINTERS ep) +{ + DWORD code; + const char *desc; + ULONG_PTR flag; + ULONG_PTR addr; + int count; + + log_exception_handler( + "=========================================================="); + log_exception_handler( + "The application has crashed due to an unhandled exception!"); + + code = ep->ExceptionRecord->ExceptionCode; + desc = debug_exception_code_to_str(code); + + log_exception_handler("code: 0x%08lX", code); + log_exception_handler("desc: %s", desc); + + if (code == EXCEPTION_ACCESS_VIOLATION && + ep->ExceptionRecord->NumberParameters == 2) { + flag = ep->ExceptionRecord->ExceptionInformation[0]; + addr = ep->ExceptionRecord->ExceptionInformation[1]; + + log_exception_handler( + "%s violation at 0x%p", + flag == 8 ? "data execution prevention" : + (flag ? "write access" : "read access"), + (void *) addr); + } + + log_exception_handler("stacktrace:"); + + count = 0; + + dwstOfException(ep->ContextRecord, &_debug_stacktrace_printer, &count); + + return EXCEPTION_EXECUTE_HANDLER; +} + +void debug_init() +{ + SetUnhandledExceptionFilter(_debug_unhandled_exception_filter); + + log_info("Initialized"); +} + +void debug_print_stacktrace() +{ + int count; + + count = 0; + + log_exception_handler( + "=========================================================="); + log_exception_handler("Debug stacktrace"); + + dwstOfLocation(&_debug_stacktrace_printer, &count); +} + +const char *debug_exception_code_to_str(DWORD code) +{ + const char *desc = ""; + + switch (code) { + EX_DESC(ACCESS_VIOLATION); + EX_DESC(ARRAY_BOUNDS_EXCEEDED); + EX_DESC(BREAKPOINT); + EX_DESC(DATATYPE_MISALIGNMENT); + EX_DESC(FLT_DENORMAL_OPERAND); + EX_DESC(FLT_DIVIDE_BY_ZERO); + EX_DESC(FLT_INEXACT_RESULT); + EX_DESC(FLT_INVALID_OPERATION); + EX_DESC(FLT_OVERFLOW); + EX_DESC(FLT_STACK_CHECK); + EX_DESC(FLT_UNDERFLOW); + EX_DESC(ILLEGAL_INSTRUCTION); + EX_DESC(IN_PAGE_ERROR); + EX_DESC(INT_DIVIDE_BY_ZERO); + EX_DESC(INT_OVERFLOW); + EX_DESC(INVALID_DISPOSITION); + EX_DESC(NONCONTINUABLE_EXCEPTION); + EX_DESC(PRIV_INSTRUCTION); + EX_DESC(SINGLE_STEP); + EX_DESC(STACK_OVERFLOW); + case DBG_CONTROL_C: + return "DBG_CONTROL_C"; + default: + log_warning("Unknown exception code: %lX", code); + return "Unknown"; + } + + return desc; +} \ No newline at end of file diff --git a/src/main/util/debug.h b/src/main/util/debug.h new file mode 100644 index 00000000..80519050 --- /dev/null +++ b/src/main/util/debug.h @@ -0,0 +1,10 @@ +#ifndef UTIL_DEBUG_H +#define UTIL_DEBUG_H + +#include + +void debug_init(); +void debug_print_stacktrace(); +const char *debug_exception_code_to_str(DWORD code); + +#endif \ No newline at end of file diff --git a/src/main/util/log.c b/src/main/util/log.c index 7da1d63a..bd643293 100644 --- a/src/main/util/log.c +++ b/src/main/util/log.c @@ -64,6 +64,15 @@ static void log_builtin_format( } } +void log_exception_handler(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + log_builtin_format(LOG_LEVEL_FATAL, LOG_MODULE, fmt, ap); + va_end(ap); +} + void log_assert_body(const char *file, int line, const char *function) { log_impl_fatal("assert", "%s:%d: function `%s'", file, line, function); diff --git a/src/main/util/log.h b/src/main/util/log.h index 47603fa1..e8a0bd0c 100644 --- a/src/main/util/log.h +++ b/src/main/util/log.h @@ -66,6 +66,7 @@ enum log_level { LOG_LEVEL_MISC = 3, }; +void log_exception_handler(const char *fmt, ...); void log_assert_body(const char *file, int line, const char *function); void log_to_external( log_formatter_t misc, diff --git a/src/main/util/proc.c b/src/main/util/proc.c index 19cec50d..84731133 100644 --- a/src/main/util/proc.c +++ b/src/main/util/proc.c @@ -1,7 +1,55 @@ +#define LOG_MODULE "util-proc" + #include +#include +#include #include +#include "util/log.h" + +bool proc_is_running_as_admin_user() +{ + SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_AUTHORITY; + PSID sid; + BOOL res; + BOOL is_admin; + + res = AllocateAndInitializeSid( + &authority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, + 0, + 0, + 0, + 0, + 0, + &sid); + + if (!res) { + log_warning( + "Failed to allocate memory for is admin check: %lX", + GetLastError()); + return false; + } + + is_admin = false; + + res = CheckTokenMembership(NULL, sid, &is_admin); + + if (!res) { + log_warning( + "Failed to check admin group membership: %lX", GetLastError()); + return false; + } + + FreeSid(sid); + + return is_admin; +} + void proc_terminate_current_process(uint32_t exit_code) { HANDLE hnd; diff --git a/src/main/util/proc.h b/src/main/util/proc.h index 3dc69062..be47a40d 100644 --- a/src/main/util/proc.h +++ b/src/main/util/proc.h @@ -1,5 +1,8 @@ #pragma once +#include #include +bool proc_is_running_as_admin_user(); + void proc_terminate_current_process(uint32_t exit_code); \ No newline at end of file diff --git a/src/main/util/signal.c b/src/main/util/signal.c index 4c15acd5..c35cb270 100644 --- a/src/main/util/signal.c +++ b/src/main/util/signal.c @@ -1,5 +1,4 @@ #include -#include #include "util/hex.h" #include "util/log.h" @@ -45,40 +44,9 @@ static BOOL WINAPI console_ctrl_handler(DWORD dwCtrlType) return FALSE; } -static LONG WINAPI -unhandled_exception_filter(struct _EXCEPTION_POINTERS *ExceptionInfo) -{ - // no exception info provided - if (ExceptionInfo != NULL) { - struct _EXCEPTION_RECORD *ExceptionRecord = - ExceptionInfo->ExceptionRecord; - - log_warning( - "Exception raised: %s", - signal_exception_code_to_str(ExceptionRecord->ExceptionCode)); - - struct _EXCEPTION_RECORD *record_cause = - ExceptionRecord->ExceptionRecord; - - while (record_cause != NULL) { - log_warning( - "Caused by: %s", - signal_exception_code_to_str(record_cause->ExceptionCode)); - record_cause = record_cause->ExceptionRecord; - } - - // TODO print stacktrace - - log_fatal("End exception handler"); - } - - return EXCEPTION_CONTINUE_SEARCH; -} - void signal_exception_handler_init() { SetConsoleCtrlHandler(console_ctrl_handler, TRUE); - SetUnhandledExceptionFilter(unhandled_exception_filter); log_info("Initialized"); } @@ -88,55 +56,4 @@ void signal_register_shutdown_handler(signal_shutdown_handler_t handler) shutdown_handler = handler; log_misc("Registered shutdown handler"); -} - -const char *signal_exception_code_to_str(DWORD code) -{ - switch (code) { - case EXCEPTION_ACCESS_VIOLATION: - return "EXCEPTION_ACCESS_VIOLATION"; - case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: - return "EXCEPTION_ARRAY_BOUNDS_EXCEEDED"; - case EXCEPTION_BREAKPOINT: - return "EXCEPTION_BREAKPOINT"; - case EXCEPTION_DATATYPE_MISALIGNMENT: - return "EXCEPTION_DATATYPE_MISALIGNMENT"; - case EXCEPTION_FLT_DENORMAL_OPERAND: - return "EXCEPTION_FLT_DENORMAL_OPERAND"; - case EXCEPTION_FLT_DIVIDE_BY_ZERO: - return "EXCEPTION_FLT_DIVIDE_BY_ZERO"; - case EXCEPTION_FLT_INEXACT_RESULT: - return "EXCEPTION_FLT_INEXACT_RESULT"; - case EXCEPTION_FLT_INVALID_OPERATION: - return "EXCEPTION_FLT_INVALID_OPERATION"; - case EXCEPTION_FLT_OVERFLOW: - return "EXCEPTION_FLT_OVERFLOW"; - case EXCEPTION_FLT_STACK_CHECK: - return "EXCEPTION_FLT_STACK_CHECK"; - case EXCEPTION_FLT_UNDERFLOW: - return "EXCEPTION_FLT_UNDERFLOW"; - case EXCEPTION_ILLEGAL_INSTRUCTION: - return "EXCEPTION_ILLEGAL_INSTRUCTION"; - case EXCEPTION_IN_PAGE_ERROR: - return "EXCEPTION_IN_PAGE_ERROR"; - case EXCEPTION_INT_DIVIDE_BY_ZERO: - return "EXCEPTION_INT_DIVIDE_BY_ZERO"; - case EXCEPTION_INT_OVERFLOW: - return "EXCEPTION_INT_OVERFLOW"; - case EXCEPTION_INVALID_DISPOSITION: - return "EXCEPTION_INVALID_DISPOSITION"; - case EXCEPTION_NONCONTINUABLE_EXCEPTION: - return "EXCEPTION_NONCONTINUABLE_EXCEPTION"; - case EXCEPTION_PRIV_INSTRUCTION: - return "EXCEPTION_PRIV_INSTRUCTION"; - case EXCEPTION_SINGLE_STEP: - return "EXCEPTION_SINGLE_STEP"; - case EXCEPTION_STACK_OVERFLOW: - return "EXCEPTION_STACK_OVERFLOW"; - case DBG_CONTROL_C: - return "DBG_CONTROL_C"; - default: - log_warning("Unknown exception code: %lX", code); - return "Unknown"; - } } \ No newline at end of file