From eafb2909d1ef5396f47d261525cd36ef4fa54d4e Mon Sep 17 00:00:00 2001 From: icex2 Date: Fri, 19 Mar 2021 15:52:34 +0100 Subject: [PATCH] Appl new code style on whole code base Use a similar code style to bemanitools though reduce indentation to 2 spaces. Also some other tweaks to be more similar to google style. --- src/api/ptapi/io/piubtn.h | 61 +- src/api/ptapi/io/piuio.h | 126 +- src/api/ptapi/io/x11-input-hook.h | 38 +- src/imports/cmocka/cmocka.c | 5150 +++++++++-------- src/imports/cmocka/cmocka.h | 1052 ++-- src/imports/cmocka/cmocka_private.h | 122 +- src/imports/fmodex/fmod.h | 4598 ++++++++++----- src/imports/fmodex/fmod_codec.h | 316 +- src/imports/fmodex/fmod_dsp.h | 998 ++-- src/imports/fmodex/fmod_errors.h | 382 +- src/imports/fmodex/fmod_memoryinfo.h | 325 +- src/imports/fmodex/fmod_output.h | 168 +- src/imports/fmodex/fmodlinux.h | 26 +- src/main/asset/f2/lib/usb-rank.c | 54 +- src/main/asset/f2/lib/usb-rank.h | 12 +- src/main/asset/f2/lib/usb-save.c | 51 +- src/main/asset/f2/lib/usb-save.h | 146 +- src/main/asset/f2/lib/util.c | 130 +- src/main/asset/f2/lib/util.h | 12 +- src/main/asset/fex/lib/usb-rank.c | 27 +- src/main/asset/fex/lib/usb-rank.h | 18 +- src/main/asset/fex/lib/usb-save.c | 535 +- src/main/asset/fex/lib/usb-save.h | 304 +- src/main/asset/fex/lib/util.c | 128 +- src/main/asset/fex/lib/util.h | 12 +- src/main/asset/fex/tool/usb-profile.c | 260 +- src/main/asset/game-version.h | 60 +- src/main/asset/nx/lib/settings.c | 97 +- src/main/asset/nx/lib/settings.h | 136 +- src/main/asset/nx/lib/util.c | 45 +- src/main/asset/nx/lib/util.h | 6 +- src/main/asset/nx/tool/settings.c | 127 +- src/main/asset/nx2/lib/usb-rank.c | 121 +- src/main/asset/nx2/lib/usb-rank.h | 37 +- src/main/asset/nx2/lib/usb-save.c | 631 +- src/main/asset/nx2/lib/usb-save.h | 168 +- src/main/asset/nx2/lib/util.c | 134 +- src/main/asset/nx2/lib/util.h | 12 +- src/main/asset/nx2/tool/usb-profile.c | 260 +- src/main/asset/nxa/lib/usb-rank.c | 133 +- src/main/asset/nxa/lib/usb-rank.h | 42 +- src/main/asset/nxa/lib/usb-save.c | 791 +-- src/main/asset/nxa/lib/usb-save.h | 433 +- src/main/asset/nxa/lib/util.c | 134 +- src/main/asset/nxa/lib/util.h | 12 +- src/main/asset/nxa/tool/usb-profile.c | 260 +- src/main/asset/x2/lib/settings.c | 114 +- src/main/asset/x2/lib/settings.h | 103 +- src/main/asset/zero/lib/settings.c | 89 +- src/main/asset/zero/lib/settings.h | 122 +- src/main/capnhook/hook/filehook.c | 989 ++-- src/main/capnhook/hook/filehook.h | 51 +- src/main/capnhook/hook/fshook.c | 541 +- src/main/capnhook/hook/fshook.h | 36 +- src/main/capnhook/hook/iobuf.c | 274 +- src/main/capnhook/hook/iobuf.h | 36 +- src/main/capnhook/hook/iohook.c | 637 +- src/main/capnhook/hook/iohook.h | 49 +- src/main/capnhook/hook/lib-main.h | 103 +- src/main/capnhook/hook/lib.c | 243 +- src/main/capnhook/hook/lib.h | 45 +- src/main/capnhook/hook/result.c | 180 +- src/main/capnhook/hook/result.h | 45 +- src/main/capnhook/hook/sig.c | 58 +- src/main/capnhook/hook/usbhook.c | 831 +-- src/main/capnhook/hook/usbhook.h | 53 +- src/main/capnhook/hooklib/filehook-mon.c | 126 +- src/main/capnhook/hooklib/filehook-mon.h | 3 +- src/main/capnhook/hooklib/fileopen-mon.c | 148 +- src/main/capnhook/hooklib/fileopen-mon.h | 9 +- src/main/capnhook/hooklib/fshook-mon.c | 92 +- src/main/capnhook/hooklib/fshook-mon.h | 3 +- src/main/capnhook/hooklib/iohook-mon.c | 135 +- src/main/capnhook/hooklib/redir.c | 356 +- src/main/capnhook/hooklib/redir.h | 23 +- src/main/capnhook/hooklib/usb-emu.c | 653 ++- src/main/capnhook/hooklib/usb-emu.h | 23 +- src/main/capnhook/hooklib/usb-init-fix.c | 90 +- src/main/capnhook/hooklib/usbhook-mon.c | 116 +- src/main/crypt/aes.c | 40 +- src/main/crypt/aes.h | 28 +- src/main/crypt/lib/md5.c | 280 +- src/main/crypt/lib/md5.h | 9 +- src/main/crypt/lib/rijndael.c | 2076 ++++--- src/main/crypt/lib/rijndael.h | 28 +- src/main/crypt/md5.c | 10 +- src/main/crypt/md5.h | 2 +- src/main/hook/core/options.c | 29 +- src/main/hook/core/options.h | 11 +- src/main/hook/core/piu-utils.c | 170 +- src/main/hook/core/piu-utils.h | 22 +- src/main/hook/exc/eeprom.c | 136 +- src/main/hook/exc/eeprom.h | 3 +- src/main/hook/exc/io.c | 818 +-- src/main/hook/exc/io.h | 4 +- src/main/hook/exc/lockchip.c | 42 +- src/main/hook/exc/lockchip.h | 2 +- src/main/hook/exc/main.c | 286 +- src/main/hook/exc/mempatch.c | 15 +- src/main/hook/exc/mempatch.h | 39 +- src/main/hook/exc/options.c | 103 +- src/main/hook/exc/options.h | 71 +- src/main/hook/f2/main.c | 237 +- src/main/hook/f2/options.c | 110 +- src/main/hook/f2/options.h | 76 +- src/main/hook/fex/main.c | 235 +- src/main/hook/fex/options.c | 114 +- src/main/hook/fex/options.h | 77 +- src/main/hook/fst/main.c | 235 +- src/main/hook/fst/options.c | 116 +- src/main/hook/fst/options.h | 77 +- src/main/hook/mk3/1st-2nd-fs-fix.c | 45 +- src/main/hook/mk3/1st-2nd-fs-fix.h | 8 +- src/main/hook/mk3/config.c | 163 +- src/main/hook/mk3/config.h | 9 +- src/main/hook/mk3/fmodex.c | 206 +- src/main/hook/mk3/fmodex.h | 14 +- src/main/hook/mk3/main.c | 285 +- src/main/hook/mk3/ogl-fix.c | 40 +- src/main/hook/mk3/options.c | 125 +- src/main/hook/mk3/options.h | 81 +- src/main/hook/nx/main.c | 309 +- src/main/hook/nx/options.c | 98 +- src/main/hook/nx/options.h | 70 +- src/main/hook/nx/unlock.c | 97 +- src/main/hook/nx/unlock.h | 3 +- src/main/hook/nx2/main.c | 375 +- src/main/hook/nx2/options.c | 135 +- src/main/hook/nx2/options.h | 81 +- src/main/hook/nx2/profile-gen.c | 98 +- src/main/hook/nxa/main.c | 354 +- src/main/hook/nxa/options.c | 114 +- src/main/hook/nxa/options.h | 77 +- src/main/hook/nxa/profile-gen.c | 174 +- src/main/hook/patch/amixer-block.c | 48 +- src/main/hook/patch/asound-fix.c | 236 +- src/main/hook/patch/asound-fix.h | 23 +- src/main/hook/patch/blacklist-url.c | 60 +- src/main/hook/patch/blacklist-url.h | 2 +- src/main/hook/patch/block-keyboard-grab.c | 41 +- src/main/hook/patch/block-keyboard-grab.h | 4 +- src/main/hook/patch/gfx.c | 180 +- src/main/hook/patch/hasp.c | 95 +- src/main/hook/patch/hasp.h | 2 +- src/main/hook/patch/hasp2.c | 27 +- src/main/hook/patch/hasp2.h | 5 +- src/main/hook/patch/hdd-check.c | 378 +- src/main/hook/patch/hdd-check.h | 2 +- src/main/hook/patch/hook-mon.c | 43 +- src/main/hook/patch/hook-mon.h | 10 +- src/main/hook/patch/main-loop.c | 332 +- src/main/hook/patch/main-loop.h | 23 +- src/main/hook/patch/microdog34.c | 81 +- src/main/hook/patch/microdog34.h | 2 +- src/main/hook/patch/microdog40.c | 28 +- src/main/hook/patch/microdog40.h | 2 +- src/main/hook/patch/mounts.c | 135 +- src/main/hook/patch/net-profile.c | 914 +-- src/main/hook/patch/net-profile.h | 20 +- src/main/hook/patch/network.c | 118 +- src/main/hook/patch/network.h | 3 +- src/main/hook/patch/piubtn.c | 374 +- src/main/hook/patch/piubtn.h | 8 +- src/main/hook/patch/piuio-exit.c | 129 +- src/main/hook/patch/piuio-exit.h | 3 +- src/main/hook/patch/piuio-khack.c | 190 +- src/main/hook/patch/piuio.c | 541 +- src/main/hook/patch/piuio.h | 2 +- src/main/hook/patch/ram-wipe.c | 17 +- src/main/hook/patch/redir.c | 8 +- src/main/hook/patch/redir.h | 2 +- src/main/hook/patch/sigsegv.c | 48 +- src/main/hook/patch/sound.c | 77 +- src/main/hook/patch/sound.h | 2 +- src/main/hook/patch/usb-emu.c | 4 +- src/main/hook/patch/usb-init-fix.c | 4 +- src/main/hook/patch/usb-mnt.c | 29 +- src/main/hook/patch/usb-unlock.c | 72 +- src/main/hook/patch/usbfs.c | 215 +- src/main/hook/patch/x11-event-loop.c | 413 +- src/main/hook/patch/x11-event-loop.h | 13 +- src/main/hook/pri/main.c | 292 +- src/main/hook/pri/options.c | 102 +- src/main/hook/pri/options.h | 75 +- src/main/hook/pri/usb-updates.c | 26 +- src/main/hook/pro/main.c | 302 +- src/main/hook/pro/options.c | 120 +- src/main/hook/pro/options.h | 69 +- src/main/hook/pro2/main.c | 240 +- src/main/hook/pro2/options.c | 87 +- src/main/hook/pro2/options.h | 57 +- src/main/hook/propatch/usb-fix.c | 276 +- src/main/hook/propatch/usb-fix.h | 3 +- src/main/hook/x2/main.c | 256 +- src/main/hook/x2/ogl-fix.c | 37 +- src/main/hook/x2/options.c | 98 +- src/main/hook/x2/options.h | 70 +- src/main/hook/x2/unlock.c | 97 +- src/main/hook/x2/unlock.h | 3 +- src/main/hook/zero/main.c | 258 +- src/main/hook/zero/options.c | 102 +- src/main/hook/zero/options.h | 71 +- src/main/hook/zero/unlock.c | 98 +- src/main/io/piubtn/defs.h | 16 +- src/main/io/piubtn/device.c | 108 +- src/main/io/piubtn/device.h | 4 +- src/main/io/piuio/defs.h | 16 +- src/main/io/piuio/device.c | 108 +- src/main/io/piuio/device.h | 4 +- src/main/io/util/joystick-util.c | 53 +- src/main/io/util/joystick-util.h | 13 +- src/main/io/util/joystick.c | 194 +- src/main/io/util/joystick.h | 23 +- src/main/io/util/usb.c | 243 +- src/main/io/util/usb_.h | 16 +- src/main/ptapi/io/piubtn/joystick-conf/main.c | 372 +- .../io/piubtn/joystick-util/joystick-conf.c | 165 +- .../io/piubtn/joystick-util/joystick-conf.h | 59 +- src/main/ptapi/io/piubtn/joystick/joystick.c | 228 +- src/main/ptapi/io/piubtn/keyboard-conf/main.c | 197 +- .../io/piubtn/keyboard-util/keyboard-conf.c | 61 +- .../io/piubtn/keyboard-util/keyboard-conf.h | 34 +- src/main/ptapi/io/piubtn/keyboard/keyboard.c | 126 +- src/main/ptapi/io/piubtn/null/null.c | 23 +- src/main/ptapi/io/piubtn/real/piubtn.c | 135 +- src/main/ptapi/io/piubtn/test/main.c | 149 +- src/main/ptapi/io/piubtn/util/lib.c | 43 +- src/main/ptapi/io/piubtn/util/lib.h | 3 +- src/main/ptapi/io/piuio/joystick-conf/main.c | 371 +- .../io/piuio/joystick-util/joystick-conf.c | 210 +- .../io/piuio/joystick-util/joystick-conf.h | 73 +- src/main/ptapi/io/piuio/joystick/joystick.c | 262 +- src/main/ptapi/io/piuio/keyboard-conf/main.c | 213 +- .../io/piuio/keyboard-util/keyboard-conf.c | 76 +- .../io/piuio/keyboard-util/keyboard-conf.h | 48 +- src/main/ptapi/io/piuio/keyboard/keyboard.c | 173 +- src/main/ptapi/io/piuio/null/null.c | 34 +- src/main/ptapi/io/piuio/real/piuio.c | 215 +- src/main/ptapi/io/piuio/test/main.c | 282 +- src/main/ptapi/io/piuio/util/lib.c | 55 +- src/main/ptapi/io/piuio/util/lib.h | 3 +- src/main/pumpnet/client/main.c | 143 +- src/main/pumpnet/lib/http.c | 435 +- src/main/pumpnet/lib/http.h | 18 +- src/main/pumpnet/lib/profile-token.c | 54 +- src/main/pumpnet/lib/profile-token.h | 2 +- src/main/pumpnet/lib/protocol.h | 40 +- src/main/pumpnet/lib/pumpnet.c | 508 +- src/main/pumpnet/lib/pumpnet.h | 28 +- src/main/sec/hasp/lib/asn1.c | 921 +-- src/main/sec/hasp/lib/asn1.h | 91 +- src/main/sec/hasp/lib/const.h | 126 +- src/main/sec/hasp/lib/handler.c | 135 +- src/main/sec/hasp/lib/handler.h | 39 +- src/main/sec/hasp/lib/object.c | 1 - src/main/sec/hasp/lib/object.h | 2 - src/main/sec/hasp/lib/object/client-id-req.c | 69 +- src/main/sec/hasp/lib/object/client-id-req.h | 22 +- src/main/sec/hasp/lib/object/client-id-resp.c | 49 +- src/main/sec/hasp/lib/object/client-id-resp.h | 18 +- src/main/sec/hasp/lib/object/login-req.c | 198 +- src/main/sec/hasp/lib/object/login-req.h | 49 +- src/main/sec/hasp/lib/server.c | 214 +- src/main/sec/hasp/lib/server.h | 2 +- src/main/sec/hasp/lib/util.c | 4 +- src/main/sec/hasp/old/hasp.c | 94 +- src/main/sec/hasp/old/hasp.h | 10 +- src/main/sec/hasp/server/main.c | 6 +- src/main/sec/lockchip/lockchip-defs.h | 100 +- src/main/sec/lockchip/lockchip.c | 83 +- src/main/sec/lockchip/lockchip.h | 2 +- src/main/sec/microdog34/microdog34.c | 728 +-- src/main/sec/microdog34/microdog34.h | 24 +- src/main/sec/microdog40/main.c | 60 +- src/main/sec/microdog40/microdog40.c | 583 +- src/main/sec/microdog40/microdog40.h | 91 +- src/main/sec/microdog40/microdog40d.c | 163 +- src/main/sec/microdog40/microdog40d.h | 2 +- src/main/util/adler32.c | 19 +- src/main/util/adler32.h | 3 +- src/main/util/array.c | 60 +- src/main/util/array.h | 25 +- src/main/util/base64.c | 42 +- src/main/util/base64.h | 6 +- src/main/util/defs.h | 5 +- src/main/util/fs.c | 291 +- src/main/util/fs.h | 17 +- src/main/util/glibc.c | 5 +- src/main/util/hex.c | 83 +- src/main/util/hex.h | 12 +- src/main/util/iobuf.c | 23 +- src/main/util/iobuf.h | 16 +- src/main/util/list.c | 133 +- src/main/util/list.h | 22 +- src/main/util/log.c | 250 +- src/main/util/log.h | 62 +- src/main/util/mem.c | 119 +- src/main/util/mem.h | 36 +- src/main/util/net.c | 50 +- src/main/util/net.h | 5 +- src/main/util/options.c | 1294 +++-- src/main/util/options.h | 103 +- src/main/util/patch.c | 75 +- src/main/util/patch.h | 21 +- src/main/util/proc.c | 275 +- src/main/util/proc.h | 18 +- src/main/util/rand.c | 26 +- src/main/util/sock-tcp.c | 221 +- src/main/util/sock-tcp.h | 18 +- src/main/util/str.c | 360 +- src/main/util/str.h | 26 +- src/main/util/sys-info.c | 20 +- src/main/util/test.c | 250 +- src/main/util/test.h | 118 +- src/main/util/time.c | 74 +- src/main/util/time.h | 18 +- src/test/capnhook/hook/lib/main.c | 73 +- src/test/hook/propatch/usb-fix/main.c | 150 +- src/test/test-util/mem.c | 38 +- src/test/test-util/mem.h | 3 +- src/test/util/mem/main.c | 51 +- src/test/util/str/main.c | 105 +- 322 files changed, 30291 insertions(+), 25084 deletions(-) diff --git a/src/api/ptapi/io/piubtn.h b/src/api/ptapi/io/piubtn.h index 62d8e60..37c074b 100644 --- a/src/api/ptapi/io/piubtn.h +++ b/src/api/ptapi/io/piubtn.h @@ -12,41 +12,44 @@ * Button inputs of a single player */ struct ptapi_io_piubtn_inputs { - bool start; - bool back; - bool left; - bool right; + bool start; + bool back; + bool left; + bool right; }; /** * Button light outputs of a single player */ struct ptapi_io_piubtn_outputs { - bool start; - bool back; - bool left; - bool right; + bool start; + bool back; + bool left; + bool right; }; -typedef const char* (*ptapi_io_piubtn_ident_t)(void); +typedef const char *(*ptapi_io_piubtn_ident_t)(void); typedef bool (*ptapi_io_piubtn_open_t)(void); typedef void (*ptapi_io_piubtn_close_t)(void); typedef bool (*ptapi_io_piubtn_recv_t)(void); typedef bool (*ptapi_io_piubtn_send_t)(void); -typedef void (*ptapi_io_piubtn_get_input_t)(uint8_t player, struct ptapi_io_piubtn_inputs* inputs); -typedef void (*ptapi_io_piubtn_set_output_t)(uint8_t player, const struct ptapi_io_piubtn_outputs* outputs); +typedef void (*ptapi_io_piubtn_get_input_t)( + uint8_t player, struct ptapi_io_piubtn_inputs *inputs); +typedef void (*ptapi_io_piubtn_set_output_t)( + uint8_t player, const struct ptapi_io_piubtn_outputs *outputs); /** - * API functions in a struct to make them easier to handle and have less boilerplate + * API functions in a struct to make them easier to handle and have less + * boilerplate */ struct ptapi_io_piubtn_api { - ptapi_io_piubtn_ident_t ident; - ptapi_io_piubtn_open_t open; - ptapi_io_piubtn_close_t close; - ptapi_io_piubtn_recv_t recv; - ptapi_io_piubtn_send_t send; - ptapi_io_piubtn_get_input_t get_input; - ptapi_io_piubtn_set_output_t set_output; + ptapi_io_piubtn_ident_t ident; + ptapi_io_piubtn_open_t open; + ptapi_io_piubtn_close_t close; + ptapi_io_piubtn_recv_t recv; + ptapi_io_piubtn_send_t send; + ptapi_io_piubtn_get_input_t get_input; + ptapi_io_piubtn_set_output_t set_output; }; /** @@ -54,15 +57,16 @@ struct ptapi_io_piubtn_api { * * @return Identifier string for your implementation (e.g. "my-custom-btnio") */ -const char* ptapi_io_piubtn_ident(void); +const char *ptapi_io_piubtn_ident(void); /** * Open the piubtn device * - * Open any file handles, spawn threads and/or initialize your device or emulation code to be ready to accept further - * commands. + * Open any file handles, spawn threads and/or initialize your device or + * emulation code to be ready to accept further commands. * - * @return True if opening/initializing your implementation was sucessful, false on failure + * @return True if opening/initializing your implementation was sucessful, false + * on failure */ bool ptapi_io_piubtn_open(void); @@ -89,10 +93,12 @@ bool ptapi_io_piubtn_send(void); * Get buffered button input data * * @param player Player id (0, 1) - * @param inputs Pointer to buffer to copy inputs to. Every time this is invoked, this buffer is nulled. If you do not - * write any data to this, all inputs remain un-triggered. + * @param inputs Pointer to buffer to copy inputs to. Every time this is + * invoked, this buffer is nulled. If you do not write any data to this, all + * inputs remain un-triggered. */ -void ptapi_io_piubtn_get_input(uint8_t player, struct ptapi_io_piubtn_inputs* inputs); +void ptapi_io_piubtn_get_input( + uint8_t player, struct ptapi_io_piubtn_inputs *inputs); /** * Set button light outputs (i.e. buffer them) @@ -100,6 +106,7 @@ void ptapi_io_piubtn_get_input(uint8_t player, struct ptapi_io_piubtn_inputs* in * @param player Player id (0, 1) * @param outputs Pointer to output data to copy to your private buffers. */ -void ptapi_io_piubtn_set_output(uint8_t player, const struct ptapi_io_piubtn_outputs* outputs); +void ptapi_io_piubtn_set_output( + uint8_t player, const struct ptapi_io_piubtn_outputs *outputs); #endif \ No newline at end of file diff --git a/src/api/ptapi/io/piuio.h b/src/api/ptapi/io/piuio.h index 95964cd..14f13ca 100644 --- a/src/api/ptapi/io/piuio.h +++ b/src/api/ptapi/io/piuio.h @@ -12,81 +12,87 @@ * Enum for pad input sensor groups (four sensors per button/panel) */ enum ptapi_io_piuio_sensor_group { - PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT = 0, - PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT = 1, - PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN = 2, - PTAPI_IO_PIUIO_SENSOR_GROUP_UP = 3, - PTAPI_IO_PIUIO_SENSOR_GROUP_NUM = 4, + PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT = 0, + PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT = 1, + PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN = 2, + PTAPI_IO_PIUIO_SENSOR_GROUP_UP = 3, + PTAPI_IO_PIUIO_SENSOR_GROUP_NUM = 4, }; /** * Inputs of all arrows of a single pad (per sensor group) */ struct ptapi_io_piuio_pad_inputs { - bool lu; - bool ru; - bool cn; - bool ld; - bool rd; + bool lu; + bool ru; + bool cn; + bool ld; + bool rd; }; /** * System/operator inputs */ struct ptapi_io_piuio_sys_inputs { - bool test; - bool service; - bool clear; - bool coin; - bool coin2; + bool test; + bool service; + bool clear; + bool coin; + bool coin2; }; /** * Pad light outputs */ struct ptapi_io_piuio_pad_outputs { - bool lu; - bool ru; - bool cn; - bool ld; - bool rd; + bool lu; + bool ru; + bool cn; + bool ld; + bool rd; }; /** * Cabinet light outputs */ struct ptapi_io_piuio_cab_outputs { - bool bass; - bool halo_r2; - bool halo_r1; - bool halo_l2; - bool halo_l1; + bool bass; + bool halo_r2; + bool halo_r1; + bool halo_l2; + bool halo_l1; }; -typedef const char* (*ptapi_io_piuio_ident_t)(void); +typedef const char *(*ptapi_io_piuio_ident_t)(void); typedef bool (*ptapi_io_piuio_open_t)(void); typedef void (*ptapi_io_piuio_close_t)(void); typedef bool (*ptapi_io_piuio_recv_t)(void); typedef bool (*ptapi_io_piuio_send_t)(void); -typedef void (*ptapi_io_piuio_get_input_pad_t)(uint8_t player, enum ptapi_io_piuio_sensor_group sensor_group, - struct ptapi_io_piuio_pad_inputs* inputs); -typedef void (*ptapi_io_piuio_get_input_sys_t)(struct ptapi_io_piuio_sys_inputs* inputs); -typedef void (*ptapi_io_piuio_set_output_pad_t)(uint8_t player, struct ptapi_io_piuio_pad_outputs* outputs); -typedef void (*ptapi_io_piuio_set_output_cab_t)(const struct ptapi_io_piuio_cab_outputs* outputs); +typedef void (*ptapi_io_piuio_get_input_pad_t)( + uint8_t player, + enum ptapi_io_piuio_sensor_group sensor_group, + struct ptapi_io_piuio_pad_inputs *inputs); +typedef void (*ptapi_io_piuio_get_input_sys_t)( + struct ptapi_io_piuio_sys_inputs *inputs); +typedef void (*ptapi_io_piuio_set_output_pad_t)( + uint8_t player, struct ptapi_io_piuio_pad_outputs *outputs); +typedef void (*ptapi_io_piuio_set_output_cab_t)( + const struct ptapi_io_piuio_cab_outputs *outputs); /** - * API functions in a struct to make them easier to handle and have less boilerplate + * API functions in a struct to make them easier to handle and have less + * boilerplate */ struct ptapi_io_piuio_api { - ptapi_io_piuio_ident_t ident; - ptapi_io_piuio_open_t open; - ptapi_io_piuio_close_t close; - ptapi_io_piuio_recv_t recv; - ptapi_io_piuio_send_t send; - ptapi_io_piuio_get_input_pad_t get_input_pad; - ptapi_io_piuio_get_input_sys_t get_input_sys; - ptapi_io_piuio_set_output_pad_t set_output_pad; - ptapi_io_piuio_set_output_cab_t set_output_cab; + ptapi_io_piuio_ident_t ident; + ptapi_io_piuio_open_t open; + ptapi_io_piuio_close_t close; + ptapi_io_piuio_recv_t recv; + ptapi_io_piuio_send_t send; + ptapi_io_piuio_get_input_pad_t get_input_pad; + ptapi_io_piuio_get_input_sys_t get_input_sys; + ptapi_io_piuio_set_output_pad_t set_output_pad; + ptapi_io_piuio_set_output_cab_t set_output_cab; }; /** @@ -94,15 +100,16 @@ struct ptapi_io_piuio_api { * * @return Identifier string for your implementation (e.g. "my-custom-io") */ -const char* ptapi_io_piuio_ident(void); +const char *ptapi_io_piuio_ident(void); /** * Open the piuio device * - * Open any file handles, spawn threads and/or initialize your device or emulation code to be ready to accept further - * commands. + * Open any file handles, spawn threads and/or initialize your device or + * emulation code to be ready to accept further commands. * - * @return True if opening/initializing your implementation was sucessful, false on failure + * @return True if opening/initializing your implementation was sucessful, false + * on failure */ bool ptapi_io_piuio_open(void); @@ -112,8 +119,9 @@ bool ptapi_io_piuio_open(void); void ptapi_io_piuio_close(void); /** - * Get _ALL_ readable data from your device in this single recv call. If you have to address single sensores like the - * real piuio, you have to do this on a single call to this function. + * Get _ALL_ readable data from your device in this single recv call. If you + * have to address single sensores like the real piuio, you have to do this on a + * single call to this function. * * @return True on success, false on error */ @@ -131,19 +139,23 @@ bool ptapi_io_piuio_send(void); * * @param player Player id (0, 1) * @param sensor_group Sensor group states to get - * @param inputs Pointer to buffer to copy inputs of the selected sensor group to. Every time this is invoked, this - * buffer is nulled. If you do not write any data to this, all inputs remain un-triggered. + * @param inputs Pointer to buffer to copy inputs of the selected sensor group + * to. Every time this is invoked, this buffer is nulled. If you do not write + * any data to this, all inputs remain un-triggered. */ -void ptapi_io_piuio_get_input_pad(uint8_t player, enum ptapi_io_piuio_sensor_group sensor_group, - struct ptapi_io_piuio_pad_inputs* inputs); +void ptapi_io_piuio_get_input_pad( + uint8_t player, + enum ptapi_io_piuio_sensor_group sensor_group, + struct ptapi_io_piuio_pad_inputs *inputs); /** * Get buffered system (test, service, clear, coin) inputs * - * @param inputs Pointer to buffer to copy inputs to. Every time this is invoked, this buffer is nulled. If you do not - * write any data to this, all inputs remain un-triggered. + * @param inputs Pointer to buffer to copy inputs to. Every time this is + * invoked, this buffer is nulled. If you do not write any data to this, all + * inputs remain un-triggered. */ -void ptapi_io_piuio_get_input_sys(struct ptapi_io_piuio_sys_inputs* inputs); +void ptapi_io_piuio_get_input_sys(struct ptapi_io_piuio_sys_inputs *inputs); /** * Set pad light outputs (i.e. buffer them) @@ -151,13 +163,15 @@ void ptapi_io_piuio_get_input_sys(struct ptapi_io_piuio_sys_inputs* inputs); * @param player Player id (0, 1) * @param outputs Pointer to output data to copy to your private buffers. */ -void ptapi_io_piuio_set_output_pad(uint8_t player, const struct ptapi_io_piuio_pad_outputs* outputs); +void ptapi_io_piuio_set_output_pad( + uint8_t player, const struct ptapi_io_piuio_pad_outputs *outputs); /** * Set cabinet light outputs (i.e. buffer them) * * @param outputs Pointer to output data to copy to your private buffers. */ -void ptapi_io_piuio_set_output_cab(const struct ptapi_io_piuio_cab_outputs* outputs); +void ptapi_io_piuio_set_output_cab( + const struct ptapi_io_piuio_cab_outputs *outputs); #endif \ No newline at end of file diff --git a/src/api/ptapi/io/x11-input-hook.h b/src/api/ptapi/io/x11-input-hook.h index 2a4d02a..b8088ab 100644 --- a/src/api/ptapi/io/x11-input-hook.h +++ b/src/api/ptapi/io/x11-input-hook.h @@ -1,6 +1,7 @@ /** - * Pumptools hooks into the X11 event dispatch loop to grab different events and exposes - * keyboard input events. This allows external modules to react to these inputs. + * Pumptools hooks into the X11 event dispatch loop to grab different events and + * exposes keyboard input events. This allows external modules to react to these + * inputs. */ #ifndef PTAPI_IO_X11_INPUT_HOOK_H #define PTAPI_IO_X11_INPUT_HOOK_H @@ -12,28 +13,31 @@ * Set functions you do not use to NULL. */ struct ptapi_io_x11_input_hook_handler { - /** - * Dispatch the key press event - * - * @param key Key pressed - */ - void (*dispatch_key_press)(KeySym key); + /** + * Dispatch the key press event + * + * @param key Key pressed + */ + void (*dispatch_key_press)(KeySym key); - /** - * Dispatch the key release event - * - * @param key Key released - */ - void (*dispatch_key_release)(KeySym key); + /** + * Dispatch the key release event + * + * @param key Key released + */ + void (*dispatch_key_release)(KeySym key); }; -typedef const struct ptapi_io_x11_input_hook_handler* (*ptapi_io_x11_input_handler_hook_t)(void); +typedef const struct ptapi_io_x11_input_hook_handler *( + *ptapi_io_x11_input_handler_hook_t)(void); /** * Get an input hook handler to receive keyboard inputs from the X11 event loop. * - * @return Either a valid handler structure with dispatch functions or NULL if unused. + * @return Either a valid handler structure with dispatch functions or NULL if + * unused. */ -const struct ptapi_io_x11_input_hook_handler* ptapi_io_x11_input_handler_hook(void); +const struct ptapi_io_x11_input_hook_handler * +ptapi_io_x11_input_handler_hook(void); #endif diff --git a/src/imports/cmocka/cmocka.c b/src/imports/cmocka/cmocka.c index e0d7cc4..cb2832d 100644 --- a/src/imports/cmocka/cmocka.c +++ b/src/imports/cmocka/cmocka.c @@ -33,15 +33,15 @@ #include #endif -#include +#include #include #include #include +#include #include #include #include #include -#include /* * This allows to add a platform specific header file. Some embedded platforms @@ -54,7 +54,7 @@ * #define _UINTPTR_T_DEFINED 1 */ #ifdef CMOCKA_PLATFORM_INCLUDE -# include "cmocka_platform.h" +#include "cmocka_platform.h" #endif /* CMOCKA_PLATFORM_INCLUDE */ #include @@ -74,11 +74,11 @@ #define SOURCE_LOCATION_FORMAT "%s:%u" #if defined(HAVE_GCC_THREAD_LOCAL_STORAGE) -# define CMOCKA_THREAD __thread +#define CMOCKA_THREAD __thread #elif defined(HAVE_MSVC_THREAD_LOCAL_STORAGE) -# define CMOCKA_THREAD __declspec(thread) +#define CMOCKA_THREAD __declspec(thread) #else -# define CMOCKA_THREAD +#define CMOCKA_THREAD #endif #ifdef HAVE_CLOCK_REALTIME @@ -88,83 +88,82 @@ #endif #ifndef MAX -#define MAX(a,b) ((a) < (b) ? (b) : (a)) +#define MAX(a, b) ((a) < (b) ? (b) : (a)) #endif /** * POSIX has sigsetjmp/siglongjmp, while Windows only has setjmp/longjmp. */ #ifdef HAVE_SIGLONGJMP -# define cm_jmp_buf sigjmp_buf -# define cm_setjmp(env) sigsetjmp(env, 1) -# define cm_longjmp(env, val) siglongjmp(env, val) +#define cm_jmp_buf sigjmp_buf +#define cm_setjmp(env) sigsetjmp(env, 1) +#define cm_longjmp(env, val) siglongjmp(env, val) #else -# define cm_jmp_buf jmp_buf -# define cm_setjmp(env) setjmp(env) -# define cm_longjmp(env, val) longjmp(env, val) +#define cm_jmp_buf jmp_buf +#define cm_setjmp(env) setjmp(env) +#define cm_longjmp(env, val) longjmp(env, val) #endif - /* * Declare and initialize the pointer member of ValuePointer variable name * with ptr. */ #define declare_initialize_value_pointer_pointer(name, ptr) \ - ValuePointer name ; \ - name.value = 0; \ - name.x.pointer = (void*)(ptr) + ValuePointer name; \ + name.value = 0; \ + name.x.pointer = (void *) (ptr) /* * Declare and initialize the value member of ValuePointer variable name * with val. */ #define declare_initialize_value_pointer_value(name, val) \ - ValuePointer name ; \ - name.value = val + ValuePointer name; \ + name.value = val /* Cast a LargestIntegralType to pointer_type via a ValuePointer. */ #define cast_largest_integral_type_to_pointer( \ - pointer_type, largest_integral_type) \ - ((pointer_type)((ValuePointer*)&(largest_integral_type))->x.pointer) + pointer_type, largest_integral_type) \ + ((pointer_type)((ValuePointer *) &(largest_integral_type))->x.pointer) /* Used to cast LargetIntegralType to void* and vice versa. */ typedef union ValuePointer { - LargestIntegralType value; - struct { + LargestIntegralType value; + struct { #if defined(WORDS_BIGENDIAN) && (WORDS_SIZEOF_VOID_P == 4) - unsigned int padding; + unsigned int padding; #endif - void *pointer; - } x; + void *pointer; + } x; } ValuePointer; /* Doubly linked list node. */ typedef struct ListNode { - const void *value; - int refcount; - struct ListNode *next; - struct ListNode *prev; + const void *value; + int refcount; + struct ListNode *next; + struct ListNode *prev; } ListNode; /* Debug information for malloc(). */ struct MallocBlockInfoData { - void* block; /* Address of the block returned by malloc(). */ - size_t allocated_size; /* Total size of the allocated block. */ - size_t size; /* Request block size. */ - SourceLocation location; /* Where the block was allocated. */ - ListNode node; /* Node within list of all allocated blocks. */ + void *block; /* Address of the block returned by malloc(). */ + size_t allocated_size; /* Total size of the allocated block. */ + size_t size; /* Request block size. */ + SourceLocation location; /* Where the block was allocated. */ + ListNode node; /* Node within list of all allocated blocks. */ }; typedef union { - struct MallocBlockInfoData *data; - char *ptr; + struct MallocBlockInfoData *data; + char *ptr; } MallocBlockInfo; /* State of each test. */ typedef struct TestState { - const ListNode *check_point; /* Check point of the test if there's a */ - /* setup function. */ - void *state; /* State associated with the test. */ + const ListNode *check_point; /* Check point of the test if there's a */ + /* setup function. */ + void *state; /* State associated with the test. */ } TestState; /* Determines whether two values are the same. */ @@ -172,8 +171,8 @@ typedef int (*EqualityFunction)(const void *left, const void *right); /* Value of a symbol and the place it was declared. */ typedef struct SymbolValue { - SourceLocation location; - LargestIntegralType value; + SourceLocation location; + LargestIntegralType value; } SymbolValue; /* @@ -182,14 +181,14 @@ typedef struct SymbolValue { * SourceLocation as its' first member. */ typedef struct SymbolMapValue { - const char *symbol_name; - ListNode symbol_values_list_head; + const char *symbol_name; + ListNode symbol_values_list_head; } SymbolMapValue; /* Where a particular ordering was located and its symbol name */ typedef struct FuncOrderingValue { - SourceLocation location; - const char * function; + SourceLocation location; + const char *function; } FuncOrderingValue; /* Used by list_free() to deallocate values referenced by list nodes. */ @@ -197,65 +196,75 @@ typedef void (*CleanupListValue)(const void *value, void *cleanup_value_data); /* Structure used to check the range of integer types.a */ typedef struct CheckIntegerRange { - CheckParameterEvent event; - LargestIntegralType minimum; - LargestIntegralType maximum; + CheckParameterEvent event; + LargestIntegralType minimum; + LargestIntegralType maximum; } CheckIntegerRange; /* Structure used to check whether an integer value is in a set. */ typedef struct CheckIntegerSet { - CheckParameterEvent event; - const LargestIntegralType *set; - size_t size_of_set; + CheckParameterEvent event; + const LargestIntegralType *set; + size_t size_of_set; } CheckIntegerSet; /* Used to check whether a parameter matches the area of memory referenced by * this structure. */ typedef struct CheckMemoryData { - CheckParameterEvent event; - const void *memory; - size_t size; + CheckParameterEvent event; + const void *memory; + size_t size; } CheckMemoryData; -static ListNode* list_initialize(ListNode * const node); -static ListNode* list_add(ListNode * const head, ListNode *new_node); -static ListNode* list_add_value(ListNode * const head, const void *value, - const int count); -static ListNode* list_remove( - ListNode * const node, const CleanupListValue cleanup_value, - void * const cleanup_value_data); +static ListNode *list_initialize(ListNode *const node); +static ListNode *list_add(ListNode *const head, ListNode *new_node); +static ListNode * +list_add_value(ListNode *const head, const void *value, const int count); +static ListNode *list_remove( + ListNode *const node, + const CleanupListValue cleanup_value, + void *const cleanup_value_data); static void list_remove_free( - ListNode * const node, const CleanupListValue cleanup_value, - void * const cleanup_value_data); -static int list_empty(const ListNode * const head); + ListNode *const node, + const CleanupListValue cleanup_value, + void *const cleanup_value_data); +static int list_empty(const ListNode *const head); static int list_find( - ListNode * const head, const void *value, - const EqualityFunction equal_func, ListNode **output); -static int list_first(ListNode * const head, ListNode **output); -static ListNode* list_free( - ListNode * const head, const CleanupListValue cleanup_value, - void * const cleanup_value_data); + ListNode *const head, + const void *value, + const EqualityFunction equal_func, + ListNode **output); +static int list_first(ListNode *const head, ListNode **output); +static ListNode *list_free( + ListNode *const head, + const CleanupListValue cleanup_value, + void *const cleanup_value_data); static void add_symbol_value( - ListNode * const symbol_map_head, const char * const symbol_names[], - const size_t number_of_symbol_names, const void* value, const int count); + ListNode *const symbol_map_head, + const char *const symbol_names[], + const size_t number_of_symbol_names, + const void *value, + const int count); static int get_symbol_value( - ListNode * const symbol_map_head, const char * const symbol_names[], - const size_t number_of_symbol_names, void **output); + ListNode *const symbol_map_head, + const char *const symbol_names[], + const size_t number_of_symbol_names, + void **output); static void free_value(const void *value, void *cleanup_value_data); -static void free_symbol_map_value( - const void *value, void *cleanup_value_data); -static void remove_always_return_values(ListNode * const map_head, - const size_t number_of_symbol_names); +static void free_symbol_map_value(const void *value, void *cleanup_value_data); +static void remove_always_return_values( + ListNode *const map_head, const size_t number_of_symbol_names); -static size_t check_for_leftover_values_list(const ListNode * head, - const char * const error_message); +static size_t check_for_leftover_values_list( + const ListNode *head, const char *const error_message); static size_t check_for_leftover_values( - const ListNode * const map_head, const char * const error_message, + const ListNode *const map_head, + const char *const error_message, const size_t number_of_symbol_names); -static void remove_always_return_values_from_list(ListNode * const map_head); +static void remove_always_return_values_from_list(ListNode *const map_head); /* * This must be called at the beginning of a test to initialize some data @@ -271,7 +280,8 @@ static enum cm_message_output cm_get_output(void); static int cm_error_message_enabled = 1; static CMOCKA_THREAD char *cm_error_message; -void cm_print_error(const char * const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); +void cm_print_error(const char *const format, ...) + CMOCKA_PRINTF_ATTRIBUTE(1, 2); /* * Keeps track of the calling context returned by setenv() so that the fail() @@ -329,8 +339,7 @@ static const int exception_signals[] = { /* Default signal functions that should be restored after a test is complete. */ typedef void (*SignalFunction)(int signal); -static SignalFunction default_signal_functions[ - ARRAY_SIZE(exception_signals)]; +static SignalFunction default_signal_functions[ARRAY_SIZE(exception_signals)]; #else /* _WIN32 */ @@ -339,11 +348,14 @@ static LPTOP_LEVEL_EXCEPTION_FILTER previous_exception_filter; /* Fatal exceptions. */ typedef struct ExceptionCodeInfo { - DWORD code; - const char* description; + DWORD code; + const char *description; } ExceptionCodeInfo; -#define EXCEPTION_CODE_INFO(exception_code) {exception_code, #exception_code} +#define EXCEPTION_CODE_INFO(exception_code) \ + { \ + exception_code, #exception_code \ + } static const ExceptionCodeInfo exception_codes[] = { EXCEPTION_CODE_INFO(EXCEPTION_ACCESS_VIOLATION), @@ -370,408 +382,423 @@ static const ExceptionCodeInfo exception_codes[] = { #endif /* !_WIN32 */ enum CMUnitTestStatus { - CM_TEST_NOT_STARTED, - CM_TEST_PASSED, - CM_TEST_FAILED, - CM_TEST_ERROR, - CM_TEST_SKIPPED, + CM_TEST_NOT_STARTED, + CM_TEST_PASSED, + CM_TEST_FAILED, + CM_TEST_ERROR, + CM_TEST_SKIPPED, }; struct CMUnitTestState { - const ListNode *check_point; /* Check point of the test if there's a setup function. */ - const struct CMUnitTest *test; /* Point to array element in the tests we get passed */ - void *state; /* State associated with the test */ - const char *error_message; /* The error messages by the test */ - enum CMUnitTestStatus status; /* PASSED, FAILED, ABORT ... */ - double runtime; /* Time calculations */ + const ListNode + *check_point; /* Check point of the test if there's a setup function. */ + const struct CMUnitTest + *test; /* Point to array element in the tests we get passed */ + void *state; /* State associated with the test */ + const char *error_message; /* The error messages by the test */ + enum CMUnitTestStatus status; /* PASSED, FAILED, ABORT ... */ + double runtime; /* Time calculations */ }; /* Exit the currently executing test. */ static void exit_test(const int quit_application) { - const char *env = getenv("CMOCKA_TEST_ABORT"); - int abort_test = 0; + const char *env = getenv("CMOCKA_TEST_ABORT"); + int abort_test = 0; - if (env != NULL && strlen(env) == 1) { - abort_test = (env[0] == '1'); - } + if (env != NULL && strlen(env) == 1) { + abort_test = (env[0] == '1'); + } - if (global_skip_test == 0 && - abort_test == 1) { - print_error("%s", cm_error_message); - abort(); - } else if (global_running_test) { - cm_longjmp(global_run_test_env, 1); - } else if (quit_application) { - exit(-1); - } + if (global_skip_test == 0 && abort_test == 1) { + print_error("%s", cm_error_message); + abort(); + } else if (global_running_test) { + cm_longjmp(global_run_test_env, 1); + } else if (quit_application) { + exit(-1); + } } -void _skip(const char * const file, const int line) +void _skip(const char *const file, const int line) { - cm_print_error(SOURCE_LOCATION_FORMAT ": Skipped!\n", file, line); - global_skip_test = 1; - exit_test(1); + cm_print_error(SOURCE_LOCATION_FORMAT ": Skipped!\n", file, line); + global_skip_test = 1; + exit_test(1); } /* Initialize a SourceLocation structure. */ -static void initialize_source_location(SourceLocation * const location) { - assert_non_null(location); - location->file = NULL; - location->line = 0; +static void initialize_source_location(SourceLocation *const location) +{ + assert_non_null(location); + location->file = NULL; + location->line = 0; } - /* Determine whether a source location is currently set. */ -static int source_location_is_set(const SourceLocation * const location) { - assert_non_null(location); - return location->file && location->line; +static int source_location_is_set(const SourceLocation *const location) +{ + assert_non_null(location); + return location->file && location->line; } - /* Set a source location. */ static void set_source_location( - SourceLocation * const location, const char * const file, - const int line) { - assert_non_null(location); - location->file = file; - location->line = line; + SourceLocation *const location, const char *const file, const int line) +{ + assert_non_null(location); + location->file = file; + location->line = line; } - -static int c_strreplace(char *src, - size_t src_len, - const char *pattern, - const char *repl, - int *str_replaced) +static int c_strreplace( + char *src, + size_t src_len, + const char *pattern, + const char *repl, + int *str_replaced) { - char *p = NULL; + char *p = NULL; - p = strstr(src, pattern); - if (p == NULL) { - return -1; + p = strstr(src, pattern); + if (p == NULL) { + return -1; + } + + do { + size_t of = p - src; + size_t l = strlen(src); + size_t pl = strlen(pattern); + size_t rl = strlen(repl); + + /* overflow check */ + if (src_len <= l + MAX(pl, rl) + 1) { + return -1; } - do { - size_t of = p - src; - size_t l = strlen(src); - size_t pl = strlen(pattern); - size_t rl = strlen(repl); + if (rl != pl) { + memmove(src + of + rl, src + of + pl, l - of - pl + 1); + } - /* overflow check */ - if (src_len <= l + MAX(pl, rl) + 1) { - return -1; - } + memcpy(src + of, repl, rl); - if (rl != pl) { - memmove(src + of + rl, src + of + pl, l - of - pl + 1); - } + if (str_replaced != NULL) { + *str_replaced = 1; + } + p = strstr(src, pattern); + } while (p != NULL); - memcpy(src + of, repl, rl); - - if (str_replaced != NULL) { - *str_replaced = 1; - } - p = strstr(src, pattern); - } while (p != NULL); - - return 0; + return 0; } static int c_strmatch(const char *str, const char *pattern) { - int ok; - - if (str == NULL || pattern == NULL) { - return 0; - } - - for (;;) { - /* Check if pattern is done */ - if (*pattern == '\0') { - /* If string is at the end, we're good */ - if (*str == '\0') { - return 1; - } - - return 0; - } - - if (*pattern == '*') { - /* Move on */ - pattern++; - - /* If we are at the end, everything is fine */ - if (*pattern == '\0') { - return 1; - } - - /* Try to match each position */ - for (; *str != '\0'; str++) { - ok = c_strmatch(str, pattern); - if (ok) { - return 1; - } - } - - /* No match */ - return 0; - } - - /* If we are at the end, leave */ - if (*str == '\0') { - return 0; - } - - /* Check if we have a single wildcard or matching char */ - if (*pattern != '?' && *str != *pattern) { - return 0; - } - - /* Move string and pattern */ - str++; - pattern++; - } + int ok; + if (str == NULL || pattern == NULL) { return 0; + } + + for (;;) { + /* Check if pattern is done */ + if (*pattern == '\0') { + /* If string is at the end, we're good */ + if (*str == '\0') { + return 1; + } + + return 0; + } + + if (*pattern == '*') { + /* Move on */ + pattern++; + + /* If we are at the end, everything is fine */ + if (*pattern == '\0') { + return 1; + } + + /* Try to match each position */ + for (; *str != '\0'; str++) { + ok = c_strmatch(str, pattern); + if (ok) { + return 1; + } + } + + /* No match */ + return 0; + } + + /* If we are at the end, leave */ + if (*str == '\0') { + return 0; + } + + /* Check if we have a single wildcard or matching char */ + if (*pattern != '?' && *str != *pattern) { + return 0; + } + + /* Move string and pattern */ + str++; + pattern++; + } + + return 0; } /* Create function results and expected parameter lists. */ -void initialize_testing(const char *test_name) { - (void)test_name; - list_initialize(&global_function_result_map_head); - initialize_source_location(&global_last_mock_value_location); - list_initialize(&global_function_parameter_map_head); - initialize_source_location(&global_last_parameter_location); - list_initialize(&global_call_ordering_head); - initialize_source_location(&global_last_parameter_location); +void initialize_testing(const char *test_name) +{ + (void) test_name; + list_initialize(&global_function_result_map_head); + initialize_source_location(&global_last_mock_value_location); + list_initialize(&global_function_parameter_map_head); + initialize_source_location(&global_last_parameter_location); + list_initialize(&global_call_ordering_head); + initialize_source_location(&global_last_parameter_location); } +static void fail_if_leftover_values(const char *test_name) +{ + int error_occurred = 0; + (void) test_name; + remove_always_return_values(&global_function_result_map_head, 1); + if (check_for_leftover_values( + &global_function_result_map_head, + "%s() has remaining non-returned values.\n", + 1)) { + error_occurred = 1; + } -static void fail_if_leftover_values(const char *test_name) { - int error_occurred = 0; - (void)test_name; - remove_always_return_values(&global_function_result_map_head, 1); - if (check_for_leftover_values( - &global_function_result_map_head, - "%s() has remaining non-returned values.\n", 1)) { - error_occurred = 1; - } + remove_always_return_values(&global_function_parameter_map_head, 2); + if (check_for_leftover_values( + &global_function_parameter_map_head, + "'%s' parameter still has values that haven't been checked.\n", + 2)) { + error_occurred = 1; + } - remove_always_return_values(&global_function_parameter_map_head, 2); - if (check_for_leftover_values( - &global_function_parameter_map_head, - "'%s' parameter still has values that haven't been checked.\n", - 2)) { - error_occurred = 1; - } - - remove_always_return_values_from_list(&global_call_ordering_head); - if (check_for_leftover_values_list(&global_call_ordering_head, - "%s function was expected to be called but was not.\n")) { - error_occurred = 1; - } - if (error_occurred) { - exit_test(1); - } + remove_always_return_values_from_list(&global_call_ordering_head); + if (check_for_leftover_values_list( + &global_call_ordering_head, + "%s function was expected to be called but was not.\n")) { + error_occurred = 1; + } + if (error_occurred) { + exit_test(1); + } } - -static void teardown_testing(const char *test_name) { - (void)test_name; - list_free(&global_function_result_map_head, free_symbol_map_value, - (void*)0); - initialize_source_location(&global_last_mock_value_location); - list_free(&global_function_parameter_map_head, free_symbol_map_value, - (void*)1); - initialize_source_location(&global_last_parameter_location); - list_free(&global_call_ordering_head, free_value, - (void*)0); - initialize_source_location(&global_last_call_ordering_location); +static void teardown_testing(const char *test_name) +{ + (void) test_name; + list_free( + &global_function_result_map_head, free_symbol_map_value, (void *) 0); + initialize_source_location(&global_last_mock_value_location); + list_free( + &global_function_parameter_map_head, free_symbol_map_value, (void *) 1); + initialize_source_location(&global_last_parameter_location); + list_free(&global_call_ordering_head, free_value, (void *) 0); + initialize_source_location(&global_last_call_ordering_location); } /* Initialize a list node. */ -static ListNode* list_initialize(ListNode * const node) { - node->value = NULL; - node->next = node; - node->prev = node; - node->refcount = 1; - return node; +static ListNode *list_initialize(ListNode *const node) +{ + node->value = NULL; + node->next = node; + node->prev = node; + node->refcount = 1; + return node; } - /* * Adds a value at the tail of a given list. * The node referencing the value is allocated from the heap. */ -static ListNode* list_add_value(ListNode * const head, const void *value, - const int refcount) { - ListNode * const new_node = (ListNode*)malloc(sizeof(ListNode)); - assert_non_null(head); - assert_non_null(value); - new_node->value = value; - new_node->refcount = refcount; - return list_add(head, new_node); +static ListNode * +list_add_value(ListNode *const head, const void *value, const int refcount) +{ + ListNode *const new_node = (ListNode *) malloc(sizeof(ListNode)); + assert_non_null(head); + assert_non_null(value); + new_node->value = value; + new_node->refcount = refcount; + return list_add(head, new_node); } - /* Add new_node to the end of the list. */ -static ListNode* list_add(ListNode * const head, ListNode *new_node) { - assert_non_null(head); - assert_non_null(new_node); - new_node->next = head; - new_node->prev = head->prev; - head->prev->next = new_node; - head->prev = new_node; - return new_node; +static ListNode *list_add(ListNode *const head, ListNode *new_node) +{ + assert_non_null(head); + assert_non_null(new_node); + new_node->next = head; + new_node->prev = head->prev; + head->prev->next = new_node; + head->prev = new_node; + return new_node; } - /* Remove a node from a list. */ -static ListNode* list_remove( - ListNode * const node, const CleanupListValue cleanup_value, - void * const cleanup_value_data) { - assert_non_null(node); - node->prev->next = node->next; - node->next->prev = node->prev; - if (cleanup_value) { - cleanup_value(node->value, cleanup_value_data); - } - return node; +static ListNode *list_remove( + ListNode *const node, + const CleanupListValue cleanup_value, + void *const cleanup_value_data) +{ + assert_non_null(node); + node->prev->next = node->next; + node->next->prev = node->prev; + if (cleanup_value) { + cleanup_value(node->value, cleanup_value_data); + } + return node; } - /* Remove a list node from a list and free the node. */ static void list_remove_free( - ListNode * const node, const CleanupListValue cleanup_value, - void * const cleanup_value_data) { - assert_non_null(node); - free(list_remove(node, cleanup_value, cleanup_value_data)); + ListNode *const node, + const CleanupListValue cleanup_value, + void *const cleanup_value_data) +{ + assert_non_null(node); + free(list_remove(node, cleanup_value, cleanup_value_data)); } - /* * Frees memory kept by a linked list The cleanup_value function is called for * every "value" field of nodes in the list, except for the head. In addition * to each list value, cleanup_value_data is passed to each call to * cleanup_value. The head of the list is not deallocated. */ -static ListNode* list_free( - ListNode * const head, const CleanupListValue cleanup_value, - void * const cleanup_value_data) { - assert_non_null(head); - while (!list_empty(head)) { - list_remove_free(head->next, cleanup_value, cleanup_value_data); - } - return head; +static ListNode *list_free( + ListNode *const head, + const CleanupListValue cleanup_value, + void *const cleanup_value_data) +{ + assert_non_null(head); + while (!list_empty(head)) { + list_remove_free(head->next, cleanup_value, cleanup_value_data); + } + return head; } - /* Determine whether a list is empty. */ -static int list_empty(const ListNode * const head) { - assert_non_null(head); - return head->next == head; +static int list_empty(const ListNode *const head) +{ + assert_non_null(head); + return head->next == head; } - /* * Find a value in the list using the equal_func to compare each node with the * value. */ -static int list_find(ListNode * const head, const void *value, - const EqualityFunction equal_func, ListNode **output) { - ListNode *current; - assert_non_null(head); - for (current = head->next; current != head; current = current->next) { - if (equal_func(current->value, value)) { - *output = current; - return 1; - } +static int list_find( + ListNode *const head, + const void *value, + const EqualityFunction equal_func, + ListNode **output) +{ + ListNode *current; + assert_non_null(head); + for (current = head->next; current != head; current = current->next) { + if (equal_func(current->value, value)) { + *output = current; + return 1; } - return 0; + } + return 0; } /* Returns the first node of a list */ -static int list_first(ListNode * const head, ListNode **output) { - ListNode *target_node = NULL; - assert_non_null(head); - if (list_empty(head)) { - return 0; - } - target_node = head->next; - *output = target_node; - return 1; +static int list_first(ListNode *const head, ListNode **output) +{ + ListNode *target_node = NULL; + assert_non_null(head); + if (list_empty(head)) { + return 0; + } + target_node = head->next; + *output = target_node; + return 1; } - /* Deallocate a value referenced by a list. */ -static void free_value(const void *value, void *cleanup_value_data) { - (void)cleanup_value_data; - assert_non_null(value); - free((void*)value); +static void free_value(const void *value, void *cleanup_value_data) +{ + (void) cleanup_value_data; + assert_non_null(value); + free((void *) value); } - /* Releases memory associated to a symbol_map_value. */ -static void free_symbol_map_value(const void *value, - void *cleanup_value_data) { - SymbolMapValue * const map_value = (SymbolMapValue*)value; - const LargestIntegralType children = cast_ptr_to_largest_integral_type(cleanup_value_data); - assert_non_null(value); - list_free(&map_value->symbol_values_list_head, - children ? free_symbol_map_value : free_value, - (void *) ((uintptr_t)children - 1)); - free(map_value); +static void free_symbol_map_value(const void *value, void *cleanup_value_data) +{ + SymbolMapValue *const map_value = (SymbolMapValue *) value; + const LargestIntegralType children = + cast_ptr_to_largest_integral_type(cleanup_value_data); + assert_non_null(value); + list_free( + &map_value->symbol_values_list_head, + children ? free_symbol_map_value : free_value, + (void *) ((uintptr_t) children - 1)); + free(map_value); } - /* * Determine whether a symbol name referenced by a symbol_map_value matches the * specified function name. */ -static int symbol_names_match(const void *map_value, const void *symbol) { - return !strcmp(((SymbolMapValue*)map_value)->symbol_name, - (const char*)symbol); +static int symbol_names_match(const void *map_value, const void *symbol) +{ + return !strcmp( + ((SymbolMapValue *) map_value)->symbol_name, (const char *) symbol); } /* * Adds a value to the queue of values associated with the given hierarchy of * symbols. It's assumed value is allocated from the heap. */ -static void add_symbol_value(ListNode * const symbol_map_head, - const char * const symbol_names[], - const size_t number_of_symbol_names, - const void* value, const int refcount) { - const char* symbol_name; - ListNode *target_node; - SymbolMapValue *target_map_value; - assert_non_null(symbol_map_head); - assert_non_null(symbol_names); - assert_true(number_of_symbol_names); - symbol_name = symbol_names[0]; +static void add_symbol_value( + ListNode *const symbol_map_head, + const char *const symbol_names[], + const size_t number_of_symbol_names, + const void *value, + const int refcount) +{ + const char *symbol_name; + ListNode *target_node; + SymbolMapValue *target_map_value; + assert_non_null(symbol_map_head); + assert_non_null(symbol_names); + assert_true(number_of_symbol_names); + symbol_name = symbol_names[0]; - if (!list_find(symbol_map_head, symbol_name, symbol_names_match, - &target_node)) { - SymbolMapValue * const new_symbol_map_value = - (SymbolMapValue*)malloc(sizeof(*new_symbol_map_value)); - new_symbol_map_value->symbol_name = symbol_name; - list_initialize(&new_symbol_map_value->symbol_values_list_head); - target_node = list_add_value(symbol_map_head, new_symbol_map_value, - 1); - } + if (!list_find( + symbol_map_head, symbol_name, symbol_names_match, &target_node)) { + SymbolMapValue *const new_symbol_map_value = + (SymbolMapValue *) malloc(sizeof(*new_symbol_map_value)); + new_symbol_map_value->symbol_name = symbol_name; + list_initialize(&new_symbol_map_value->symbol_values_list_head); + target_node = list_add_value(symbol_map_head, new_symbol_map_value, 1); + } - target_map_value = (SymbolMapValue*)target_node->value; - if (number_of_symbol_names == 1) { - list_add_value(&target_map_value->symbol_values_list_head, - value, refcount); - } else { - add_symbol_value(&target_map_value->symbol_values_list_head, - &symbol_names[1], number_of_symbol_names - 1, value, - refcount); - } + target_map_value = (SymbolMapValue *) target_node->value; + if (number_of_symbol_names == 1) { + list_add_value(&target_map_value->symbol_values_list_head, value, refcount); + } else { + add_symbol_value( + &target_map_value->symbol_values_list_head, + &symbol_names[1], + number_of_symbol_names - 1, + value, + refcount); + } } - /* * Gets the next value associated with the given hierarchy of symbols. * The value is returned as an output parameter with the function returning the @@ -779,54 +806,56 @@ static void add_symbol_value(ListNode * const symbol_map_head, * a return value of 1 indicates the node was just removed from the list. */ static int get_symbol_value( - ListNode * const head, const char * const symbol_names[], - const size_t number_of_symbol_names, void **output) { - const char* symbol_name = NULL; - ListNode *target_node = NULL; - assert_non_null(head); - assert_non_null(symbol_names); - assert_true(number_of_symbol_names); - assert_non_null(output); - symbol_name = symbol_names[0]; + ListNode *const head, + const char *const symbol_names[], + const size_t number_of_symbol_names, + void **output) +{ + const char *symbol_name = NULL; + ListNode *target_node = NULL; + assert_non_null(head); + assert_non_null(symbol_names); + assert_true(number_of_symbol_names); + assert_non_null(output); + symbol_name = symbol_names[0]; - if (list_find(head, symbol_name, symbol_names_match, &target_node)) { - SymbolMapValue *map_value = NULL; - ListNode *child_list = NULL; - int return_value = 0; - assert_non_null(target_node); - assert_non_null(target_node->value); + if (list_find(head, symbol_name, symbol_names_match, &target_node)) { + SymbolMapValue *map_value = NULL; + ListNode *child_list = NULL; + int return_value = 0; + assert_non_null(target_node); + assert_non_null(target_node->value); - map_value = (SymbolMapValue*)target_node->value; - child_list = &map_value->symbol_values_list_head; + map_value = (SymbolMapValue *) target_node->value; + child_list = &map_value->symbol_values_list_head; - if (number_of_symbol_names == 1) { - ListNode *value_node = NULL; - return_value = list_first(child_list, &value_node); - assert_true(return_value); - /* Add a check to silence clang analyzer */ - if (return_value == 0) { - goto out; - } - *output = (void*) value_node->value; - return_value = value_node->refcount; - if (value_node->refcount - 1 == 0) { - list_remove_free(value_node, NULL, NULL); - } else if (value_node->refcount > WILL_RETURN_ONCE) { - --value_node->refcount; - } - } else { - return_value = get_symbol_value( - child_list, &symbol_names[1], number_of_symbol_names - 1, - output); - } - if (list_empty(child_list)) { - list_remove_free(target_node, free_symbol_map_value, (void*)0); - } - return return_value; + if (number_of_symbol_names == 1) { + ListNode *value_node = NULL; + return_value = list_first(child_list, &value_node); + assert_true(return_value); + /* Add a check to silence clang analyzer */ + if (return_value == 0) { + goto out; + } + *output = (void *) value_node->value; + return_value = value_node->refcount; + if (value_node->refcount - 1 == 0) { + list_remove_free(value_node, NULL, NULL); + } else if (value_node->refcount > WILL_RETURN_ONCE) { + --value_node->refcount; + } + } else { + return_value = get_symbol_value( + child_list, &symbol_names[1], number_of_symbol_names - 1, output); } + if (list_empty(child_list)) { + list_remove_free(target_node, free_symbol_map_value, (void *) 0); + } + return return_value; + } out: - cm_print_error("No entries for symbol %s.\n", symbol_name); - return 0; + cm_print_error("No entries for symbol %s.\n", symbol_name); + return 0; } /** @@ -835,19 +864,18 @@ out: * least once). */ -static void remove_always_return_values_from_list(ListNode * const map_head) +static void remove_always_return_values_from_list(ListNode *const map_head) { - ListNode * current = NULL; - ListNode * next = NULL; - assert_non_null(map_head); + ListNode *current = NULL; + ListNode *next = NULL; + assert_non_null(map_head); - for (current = map_head->next, next = current->next; - current != map_head; - current = next, next = current->next) { - if (current->refcount < -1) { - list_remove_free(current, free_value, NULL); - } + for (current = map_head->next, next = current->next; current != map_head; + current = next, next = current->next) { + if (current->refcount < -1) { + list_remove_free(current, free_value, NULL); } + } } /* @@ -855,57 +883,57 @@ static void remove_always_return_values_from_list(ListNode * const map_head) * in each branch that has a refcount < -1 (i.e should always be returned * and has been returned at least once). */ -static void remove_always_return_values(ListNode * const map_head, - const size_t number_of_symbol_names) { - ListNode *current; - assert_non_null(map_head); - assert_true(number_of_symbol_names); - current = map_head->next; - while (current != map_head) { - SymbolMapValue * const value = (SymbolMapValue*)current->value; - ListNode * const next = current->next; - ListNode *child_list; - assert_non_null(value); - child_list = &value->symbol_values_list_head; +static void remove_always_return_values( + ListNode *const map_head, const size_t number_of_symbol_names) +{ + ListNode *current; + assert_non_null(map_head); + assert_true(number_of_symbol_names); + current = map_head->next; + while (current != map_head) { + SymbolMapValue *const value = (SymbolMapValue *) current->value; + ListNode *const next = current->next; + ListNode *child_list; + assert_non_null(value); + child_list = &value->symbol_values_list_head; - if (!list_empty(child_list)) { - if (number_of_symbol_names == 1) { - ListNode * const child_node = child_list->next; - /* If this item has been returned more than once, free it. */ - if (child_node->refcount < -1) { - list_remove_free(child_node, free_value, NULL); - } - } else { - remove_always_return_values(child_list, - number_of_symbol_names - 1); - } + if (!list_empty(child_list)) { + if (number_of_symbol_names == 1) { + ListNode *const child_node = child_list->next; + /* If this item has been returned more than once, free it. */ + if (child_node->refcount < -1) { + list_remove_free(child_node, free_value, NULL); } - - if (list_empty(child_list)) { - list_remove_free(current, free_value, NULL); - } - current = next; + } else { + remove_always_return_values(child_list, number_of_symbol_names - 1); + } } + + if (list_empty(child_list)) { + list_remove_free(current, free_value, NULL); + } + current = next; + } } -static size_t check_for_leftover_values_list(const ListNode * head, - const char * const error_message) +static size_t check_for_leftover_values_list( + const ListNode *head, const char *const error_message) { - ListNode *child_node; - size_t leftover_count = 0; - if (!list_empty(head)) - { - for (child_node = head->next; child_node != head; - child_node = child_node->next, ++leftover_count) { - const FuncOrderingValue *const o = - (const FuncOrderingValue*) child_node->value; - cm_print_error(error_message, "%s", o->function); - cm_print_error(SOURCE_LOCATION_FORMAT - ": note: remaining item was declared here\n", - o->location.file, o->location.line); - } + ListNode *child_node; + size_t leftover_count = 0; + if (!list_empty(head)) { + for (child_node = head->next; child_node != head; + child_node = child_node->next, ++leftover_count) { + const FuncOrderingValue *const o = + (const FuncOrderingValue *) child_node->value; + cm_print_error(error_message, "%s", o->function); + cm_print_error( + SOURCE_LOCATION_FORMAT ": note: remaining item was declared here\n", + o->location.file, + o->location.line); } - return leftover_count; + } + return leftover_count; } /* @@ -913,167 +941,183 @@ static size_t check_for_leftover_values_list(const ListNode * head, * retrieved through execution, and fail the test if that is the case. */ static size_t check_for_leftover_values( - const ListNode * const map_head, const char * const error_message, - const size_t number_of_symbol_names) { - const ListNode *current; - size_t symbols_with_leftover_values = 0; - assert_non_null(map_head); - assert_true(number_of_symbol_names); + const ListNode *const map_head, + const char *const error_message, + const size_t number_of_symbol_names) +{ + const ListNode *current; + size_t symbols_with_leftover_values = 0; + assert_non_null(map_head); + assert_true(number_of_symbol_names); - for (current = map_head->next; current != map_head; - current = current->next) { - const SymbolMapValue * const value = - (SymbolMapValue*)current->value; - const ListNode *child_list; - assert_non_null(value); - child_list = &value->symbol_values_list_head; + for (current = map_head->next; current != map_head; current = current->next) { + const SymbolMapValue *const value = (SymbolMapValue *) current->value; + const ListNode *child_list; + assert_non_null(value); + child_list = &value->symbol_values_list_head; - if (!list_empty(child_list)) { - if (number_of_symbol_names == 1) { - const ListNode *child_node; - cm_print_error(error_message, "%s", value->symbol_name); + if (!list_empty(child_list)) { + if (number_of_symbol_names == 1) { + const ListNode *child_node; + cm_print_error(error_message, "%s", value->symbol_name); - for (child_node = child_list->next; child_node != child_list; - child_node = child_node->next) { - const SourceLocation * const location = - (const SourceLocation*)child_node->value; - cm_print_error(SOURCE_LOCATION_FORMAT - ": note: remaining item was declared here\n", - location->file, location->line); - } - } else { - cm_print_error("%s: ", value->symbol_name); - check_for_leftover_values(child_list, error_message, - number_of_symbol_names - 1); - } - symbols_with_leftover_values ++; + for (child_node = child_list->next; child_node != child_list; + child_node = child_node->next) { + const SourceLocation *const location = + (const SourceLocation *) child_node->value; + cm_print_error( + SOURCE_LOCATION_FORMAT + ": note: remaining item was declared here\n", + location->file, + location->line); } + } else { + cm_print_error("%s: ", value->symbol_name); + check_for_leftover_values( + child_list, error_message, number_of_symbol_names - 1); + } + symbols_with_leftover_values++; } - return symbols_with_leftover_values; + } + return symbols_with_leftover_values; } - /* Get the next return value for the specified mock function. */ -LargestIntegralType _mock(const char * const function, const char* const file, - const int line) { - void *result; - const int rc = get_symbol_value(&global_function_result_map_head, - &function, 1, &result); - if (rc) { - SymbolValue * const symbol = (SymbolValue*)result; - const LargestIntegralType value = symbol->value; - global_last_mock_value_location = symbol->location; - if (rc == 1) { - free(symbol); - } - return value; - } else { - cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value " - "to mock function %s\n", file, line, function); - if (source_location_is_set(&global_last_mock_value_location)) { - cm_print_error(SOURCE_LOCATION_FORMAT - ": note: Previously returned mock value was declared here\n", - global_last_mock_value_location.file, - global_last_mock_value_location.line); - } else { - cm_print_error("There were no previously returned mock values for " - "this test.\n"); - } - exit_test(1); +LargestIntegralType +_mock(const char *const function, const char *const file, const int line) +{ + void *result; + const int rc = + get_symbol_value(&global_function_result_map_head, &function, 1, &result); + if (rc) { + SymbolValue *const symbol = (SymbolValue *) result; + const LargestIntegralType value = symbol->value; + global_last_mock_value_location = symbol->location; + if (rc == 1) { + free(symbol); } - return 0; + return value; + } else { + cm_print_error( + SOURCE_LOCATION_FORMAT + ": error: Could not get value " + "to mock function %s\n", + file, + line, + function); + if (source_location_is_set(&global_last_mock_value_location)) { + cm_print_error( + SOURCE_LOCATION_FORMAT + ": note: Previously returned mock value was declared here\n", + global_last_mock_value_location.file, + global_last_mock_value_location.line); + } else { + cm_print_error( + "There were no previously returned mock values for " + "this test.\n"); + } + exit_test(1); + } + return 0; } /* Ensure that function is being called in proper order */ -void _function_called(const char *const function, - const char *const file, - const int line) +void _function_called( + const char *const function, const char *const file, const int line) { - ListNode *first_value_node = NULL; - ListNode *value_node = NULL; - int rc; + ListNode *first_value_node = NULL; + ListNode *value_node = NULL; + int rc; - rc = list_first(&global_call_ordering_head, &value_node); - first_value_node = value_node; - if (rc) { - FuncOrderingValue *expected_call; - int cmp; + rc = list_first(&global_call_ordering_head, &value_node); + first_value_node = value_node; + if (rc) { + FuncOrderingValue *expected_call; + int cmp; - expected_call = (FuncOrderingValue *)value_node->value; + expected_call = (FuncOrderingValue *) value_node->value; + + cmp = strcmp(expected_call->function, function); + if (value_node->refcount < -1) { + /* + * Search through value nodes until either function is found or + * encounter a non-zero refcount greater than -2 + */ + if (cmp != 0) { + value_node = value_node->next; + expected_call = (FuncOrderingValue *) value_node->value; cmp = strcmp(expected_call->function, function); - if (value_node->refcount < -1) { - /* - * Search through value nodes until either function is found or - * encounter a non-zero refcount greater than -2 - */ - if (cmp != 0) { - value_node = value_node->next; - expected_call = (FuncOrderingValue *)value_node->value; - - cmp = strcmp(expected_call->function, function); - while (value_node->refcount < -1 && - cmp != 0 && - value_node != first_value_node->prev) { - value_node = value_node->next; - if (value_node == NULL) { - break; - } - expected_call = (FuncOrderingValue *)value_node->value; - if (expected_call == NULL) { - continue; - } - cmp = strcmp(expected_call->function, function); - } - - if (expected_call == NULL || value_node == first_value_node->prev) { - cm_print_error(SOURCE_LOCATION_FORMAT - ": error: No expected mock calls matching " - "called() invocation in %s", - file, line, - function); - exit_test(1); - } - } + while (value_node->refcount < -1 && cmp != 0 && + value_node != first_value_node->prev) { + value_node = value_node->next; + if (value_node == NULL) { + break; + } + expected_call = (FuncOrderingValue *) value_node->value; + if (expected_call == NULL) { + continue; + } + cmp = strcmp(expected_call->function, function); } - if (cmp == 0) { - if (value_node->refcount > -2 && --value_node->refcount == 0) { - list_remove_free(value_node, free_value, NULL); - } - } else { - cm_print_error(SOURCE_LOCATION_FORMAT - ": error: Expected call to %s but received called() " - "in %s\n", - file, line, - expected_call->function, - function); - exit_test(1); + if (expected_call == NULL || value_node == first_value_node->prev) { + cm_print_error( + SOURCE_LOCATION_FORMAT + ": error: No expected mock calls matching " + "called() invocation in %s", + file, + line, + function); + exit_test(1); } - } else { - cm_print_error(SOURCE_LOCATION_FORMAT - ": error: No mock calls expected but called() was " - "invoked in %s\n", - file, line, - function); - exit_test(1); + } } + + if (cmp == 0) { + if (value_node->refcount > -2 && --value_node->refcount == 0) { + list_remove_free(value_node, free_value, NULL); + } + } else { + cm_print_error( + SOURCE_LOCATION_FORMAT + ": error: Expected call to %s but received called() " + "in %s\n", + file, + line, + expected_call->function, + function); + exit_test(1); + } + } else { + cm_print_error( + SOURCE_LOCATION_FORMAT + ": error: No mock calls expected but called() was " + "invoked in %s\n", + file, + line, + function); + exit_test(1); + } } /* Add a return value for the specified mock function name. */ -void _will_return(const char * const function_name, const char * const file, - const int line, const LargestIntegralType value, - const int count) { - SymbolValue * const return_value = - (SymbolValue*)malloc(sizeof(*return_value)); - assert_true(count != 0); - return_value->value = value; - set_source_location(&return_value->location, file, line); - add_symbol_value(&global_function_result_map_head, &function_name, 1, - return_value, count); +void _will_return( + const char *const function_name, + const char *const file, + const int line, + const LargestIntegralType value, + const int count) +{ + SymbolValue *const return_value = + (SymbolValue *) malloc(sizeof(*return_value)); + assert_true(count != 0); + return_value->value = value; + set_source_location(&return_value->location, file, line); + add_symbol_value( + &global_function_result_map_head, &function_name, 1, return_value, count); } - /* * Add a custom parameter checking function. If the event parameter is NULL * the event structure is allocated internally by this function. If event @@ -1081,20 +1125,24 @@ void _will_return(const char * const function_name, const char * const file, * be deallocated by the caller. */ void _expect_check( - const char* const function, const char* const parameter, - const char* const file, const int line, - const CheckParameterValue check_function, - const LargestIntegralType check_data, - CheckParameterEvent * const event, const int count) { - CheckParameterEvent * const check = - event ? event : (CheckParameterEvent*)malloc(sizeof(*check)); - const char* symbols[] = {function, parameter}; - check->parameter_name = parameter; - check->check_value = check_function; - check->check_value_data = check_data; - set_source_location(&check->location, file, line); - add_symbol_value(&global_function_parameter_map_head, symbols, 2, check, - count); + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const CheckParameterValue check_function, + const LargestIntegralType check_data, + CheckParameterEvent *const event, + const int count) +{ + CheckParameterEvent *const check = + event ? event : (CheckParameterEvent *) malloc(sizeof(*check)); + const char *symbols[] = {function, parameter}; + check->parameter_name = parameter; + check->check_value = check_function; + check->check_value_data = check_data; + set_source_location(&check->location, file, line); + add_symbol_value( + &global_function_parameter_map_head, symbols, 2, check, count); } /* @@ -1104,107 +1152,114 @@ void _expect_check( */ void _expect_function_call( - const char * const function_name, - const char * const file, + const char *const function_name, + const char *const file, const int line, const int count) { - FuncOrderingValue *ordering; + FuncOrderingValue *ordering; - assert_non_null(function_name); - assert_non_null(file); - assert_true(count != 0); + assert_non_null(function_name); + assert_non_null(file); + assert_true(count != 0); - ordering = (FuncOrderingValue *)malloc(sizeof(*ordering)); + ordering = (FuncOrderingValue *) malloc(sizeof(*ordering)); - set_source_location(&ordering->location, file, line); - ordering->function = function_name; + set_source_location(&ordering->location, file, line); + ordering->function = function_name; - list_add_value(&global_call_ordering_head, ordering, count); + list_add_value(&global_call_ordering_head, ordering, count); } /* Returns 1 if the specified float values are equal, else returns 0. */ -static int float_compare(const float left, - const float right, - const float epsilon) { - float absLeft; - float absRight; - float largest; - float relDiff; +static int +float_compare(const float left, const float right, const float epsilon) +{ + float absLeft; + float absRight; + float largest; + float relDiff; - float diff = left - right; - diff = (diff >= 0.f) ? diff : -diff; + float diff = left - right; + diff = (diff >= 0.f) ? diff : -diff; - // Check if the numbers are really close -- needed - // when comparing numbers near zero. - if (diff <= epsilon) { - return 1; - } - - absLeft = (left >= 0.f) ? left : -left; - absRight = (right >= 0.f) ? right : -right; - - largest = (absRight > absLeft) ? absRight : absLeft; - relDiff = largest * FLT_EPSILON; - - if (diff > relDiff) { - return 0; - } + // Check if the numbers are really close -- needed + // when comparing numbers near zero. + if (diff <= epsilon) { return 1; + } + + absLeft = (left >= 0.f) ? left : -left; + absRight = (right >= 0.f) ? right : -right; + + largest = (absRight > absLeft) ? absRight : absLeft; + relDiff = largest * FLT_EPSILON; + + if (diff > relDiff) { + return 0; + } + return 1; } -/* Returns 1 if the specified float values are equal. If the values are not equal - * an error is displayed and 0 is returned. */ -static int float_values_equal_display_error(const float left, - const float right, - const float epsilon) { - const int equal = float_compare(left, right, epsilon); - if (!equal) { - cm_print_error(FloatPrintfFormat " != " - FloatPrintfFormat "\n", left, right); - } - return equal; +/* Returns 1 if the specified float values are equal. If the values are not + * equal an error is displayed and 0 is returned. */ +static int float_values_equal_display_error( + const float left, const float right, const float epsilon) +{ + const int equal = float_compare(left, right, epsilon); + if (!equal) { + cm_print_error( + FloatPrintfFormat " != " FloatPrintfFormat "\n", left, right); + } + return equal; } -/* Returns 1 if the specified float values are different. If the values are equal - * an error is displayed and 0 is returned. */ -static int float_values_not_equal_display_error(const float left, - const float right, - const float epsilon) { - const int not_equal = (float_compare(left, right, epsilon) == 0); - if (!not_equal) { - cm_print_error(FloatPrintfFormat " == " - FloatPrintfFormat "\n", left, right); - } - return not_equal; +/* Returns 1 if the specified float values are different. If the values are + * equal an error is displayed and 0 is returned. */ +static int float_values_not_equal_display_error( + const float left, const float right, const float epsilon) +{ + const int not_equal = (float_compare(left, right, epsilon) == 0); + if (!not_equal) { + cm_print_error( + FloatPrintfFormat " == " FloatPrintfFormat "\n", left, right); + } + return not_equal; } /* Returns 1 if the specified values are equal. If the values are not equal * an error is displayed and 0 is returned. */ -static int values_equal_display_error(const LargestIntegralType left, - const LargestIntegralType right) { - const int equal = left == right; - if (!equal) { - cm_print_error(LargestIntegralTypePrintfFormat " != " - LargestIntegralTypePrintfFormat "\n", left, right); - } - return equal; +static int values_equal_display_error( + const LargestIntegralType left, const LargestIntegralType right) +{ + const int equal = left == right; + if (!equal) { + cm_print_error( + LargestIntegralTypePrintfFormat " != " LargestIntegralTypePrintfFormat + "\n", + left, + right); + } + return equal; } /* * Returns 1 if the specified values are not equal. If the values are equal * an error is displayed and 0 is returned. */ -static int values_not_equal_display_error(const LargestIntegralType left, - const LargestIntegralType right) { - const int not_equal = left != right; - if (!not_equal) { - cm_print_error(LargestIntegralTypePrintfFormat " == " - LargestIntegralTypePrintfFormat "\n", left, right); - } - return not_equal; +static int values_not_equal_display_error( + const LargestIntegralType left, const LargestIntegralType right) +{ + const int not_equal = left != right; + if (!not_equal) { + cm_print_error( + LargestIntegralTypePrintfFormat " == " LargestIntegralTypePrintfFormat + "\n", + left, + right); + } + return not_equal; } - /* * Determine whether value is contained within check_integer_set. * If invert is 0 and the value is in the set 1 is returned, otherwise 0 is @@ -1213,1489 +1268,1688 @@ static int values_not_equal_display_error(const LargestIntegralType left, * displayed. */ static int value_in_set_display_error( - const LargestIntegralType value, - const CheckIntegerSet * const check_integer_set, const int invert) { - int succeeded = invert; - assert_non_null(check_integer_set); - { - const LargestIntegralType * const set = check_integer_set->set; - const size_t size_of_set = check_integer_set->size_of_set; - size_t i; - for (i = 0; i < size_of_set; i++) { - if (set[i] == value) { - /* If invert = 0 and item is found, succeeded = 1. */ - /* If invert = 1 and item is found, succeeded = 0. */ - succeeded = !succeeded; - break; - } - } - if (succeeded) { - return 1; - } - cm_print_error(LargestIntegralTypePrintfFormatDecimal - " is %sin the set (", - value, invert ? "" : "not "); - for (i = 0; i < size_of_set; i++) { - cm_print_error(LargestIntegralTypePrintfFormat ", ", set[i]); - } - cm_print_error(")\n"); + const LargestIntegralType value, + const CheckIntegerSet *const check_integer_set, + const int invert) +{ + int succeeded = invert; + assert_non_null(check_integer_set); + { + const LargestIntegralType *const set = check_integer_set->set; + const size_t size_of_set = check_integer_set->size_of_set; + size_t i; + for (i = 0; i < size_of_set; i++) { + if (set[i] == value) { + /* If invert = 0 and item is found, succeeded = 1. */ + /* If invert = 1 and item is found, succeeded = 0. */ + succeeded = !succeeded; + break; + } } - return 0; + if (succeeded) { + return 1; + } + cm_print_error( + LargestIntegralTypePrintfFormatDecimal " is %sin the set (", + value, + invert ? "" : "not "); + for (i = 0; i < size_of_set; i++) { + cm_print_error(LargestIntegralTypePrintfFormat ", ", set[i]); + } + cm_print_error(")\n"); + } + return 0; } - /* * Determine whether a value is within the specified range. If the value is * within the specified range 1 is returned. If the value isn't within the * specified range an error is displayed and 0 is returned. */ static int integer_in_range_display_error( - const LargestIntegralType value, const LargestIntegralType range_min, - const LargestIntegralType range_max) { - if (value >= range_min && value <= range_max) { - return 1; - } - cm_print_error(LargestIntegralTypePrintfFormatDecimal - " is not within the range " - LargestIntegralTypePrintfFormatDecimal "-" - LargestIntegralTypePrintfFormatDecimal "\n", - value, range_min, range_max); - return 0; + const LargestIntegralType value, + const LargestIntegralType range_min, + const LargestIntegralType range_max) +{ + if (value >= range_min && value <= range_max) { + return 1; + } + cm_print_error( + LargestIntegralTypePrintfFormatDecimal + " is not within the range " LargestIntegralTypePrintfFormatDecimal + "-" LargestIntegralTypePrintfFormatDecimal "\n", + value, + range_min, + range_max); + return 0; } - /* * Determine whether a value is within the specified range. If the value * is not within the range 1 is returned. If the value is within the * specified range an error is displayed and zero is returned. */ static int integer_not_in_range_display_error( - const LargestIntegralType value, const LargestIntegralType range_min, - const LargestIntegralType range_max) { - if (value < range_min || value > range_max) { - return 1; - } - cm_print_error(LargestIntegralTypePrintfFormatDecimal - " is within the range " - LargestIntegralTypePrintfFormatDecimal "-" - LargestIntegralTypePrintfFormatDecimal "\n", - value, range_min, range_max); - return 0; + const LargestIntegralType value, + const LargestIntegralType range_min, + const LargestIntegralType range_max) +{ + if (value < range_min || value > range_max) { + return 1; + } + cm_print_error( + LargestIntegralTypePrintfFormatDecimal + " is within the range " LargestIntegralTypePrintfFormatDecimal + "-" LargestIntegralTypePrintfFormatDecimal "\n", + value, + range_min, + range_max); + return 0; } - /* * Determine whether the specified strings are equal. If the strings are equal * 1 is returned. If they're not equal an error is displayed and 0 is * returned. */ -static int string_equal_display_error( - const char * const left, const char * const right) { - if (strcmp(left, right) == 0) { - return 1; - } - cm_print_error("\"%s\" != \"%s\"\n", left, right); - return 0; +static int +string_equal_display_error(const char *const left, const char *const right) +{ + if (strcmp(left, right) == 0) { + return 1; + } + cm_print_error("\"%s\" != \"%s\"\n", left, right); + return 0; } - /* * Determine whether the specified strings are equal. If the strings are not * equal 1 is returned. If they're not equal an error is displayed and 0 is * returned */ -static int string_not_equal_display_error( - const char * const left, const char * const right) { - if (strcmp(left, right) != 0) { - return 1; - } - cm_print_error("\"%s\" == \"%s\"\n", left, right); - return 0; +static int +string_not_equal_display_error(const char *const left, const char *const right) +{ + if (strcmp(left, right) != 0) { + return 1; + } + cm_print_error("\"%s\" == \"%s\"\n", left, right); + return 0; } - /* * Determine whether the specified areas of memory are equal. If they're equal * 1 is returned otherwise an error is displayed and 0 is returned. */ -static int memory_equal_display_error(const char* const a, const char* const b, - const size_t size) { - size_t differences = 0; - size_t i; - for (i = 0; i < size; i++) { - const char l = a[i]; - const char r = b[i]; - if (l != r) { - if (differences < 16) { - cm_print_error("difference at offset %" PRIdS " 0x%02x 0x%02x\n", - i, l, r); - } - differences ++; - } +static int memory_equal_display_error( + const char *const a, const char *const b, const size_t size) +{ + size_t differences = 0; + size_t i; + for (i = 0; i < size; i++) { + const char l = a[i]; + const char r = b[i]; + if (l != r) { + if (differences < 16) { + cm_print_error( + "difference at offset %" PRIdS " 0x%02x 0x%02x\n", i, l, r); + } + differences++; } - if (differences > 0) { - if (differences >= 16) { - cm_print_error("...\n"); - } - cm_print_error("%"PRIdS " bytes of %p and %p differ\n", - differences, (void *)a, (void *)b); - return 0; + } + if (differences > 0) { + if (differences >= 16) { + cm_print_error("...\n"); } - return 1; + cm_print_error( + "%" PRIdS " bytes of %p and %p differ\n", + differences, + (void *) a, + (void *) b); + return 0; + } + return 1; } - /* * Determine whether the specified areas of memory are not equal. If they're * not equal 1 is returned otherwise an error is displayed and 0 is * returned. */ static int memory_not_equal_display_error( - const char* const a, const char* const b, const size_t size) { - size_t same = 0; - size_t i; - for (i = 0; i < size; i++) { - const char l = a[i]; - const char r = b[i]; - if (l == r) { - same ++; - } + const char *const a, const char *const b, const size_t size) +{ + size_t same = 0; + size_t i; + for (i = 0; i < size; i++) { + const char l = a[i]; + const char r = b[i]; + if (l == r) { + same++; } - if (same == size) { - cm_print_error("%"PRIdS "bytes of %p and %p the same\n", - same, (void *)a, (void *)b); - return 0; - } - return 1; + } + if (same == size) { + cm_print_error( + "%" PRIdS "bytes of %p and %p the same\n", + same, + (void *) a, + (void *) b); + return 0; + } + return 1; } - /* CheckParameterValue callback to check whether a value is within a set. */ -static int check_in_set(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - return value_in_set_display_error(value, - cast_largest_integral_type_to_pointer(CheckIntegerSet*, - check_value_data), 0); +static int check_in_set( + const LargestIntegralType value, const LargestIntegralType check_value_data) +{ + return value_in_set_display_error( + value, + cast_largest_integral_type_to_pointer( + CheckIntegerSet *, check_value_data), + 0); } - /* CheckParameterValue callback to check whether a value isn't within a set. */ -static int check_not_in_set(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - return value_in_set_display_error(value, - cast_largest_integral_type_to_pointer(CheckIntegerSet*, - check_value_data), 1); +static int check_not_in_set( + const LargestIntegralType value, const LargestIntegralType check_value_data) +{ + return value_in_set_display_error( + value, + cast_largest_integral_type_to_pointer( + CheckIntegerSet *, check_value_data), + 1); } - /* Create the callback data for check_in_set() or check_not_in_set() and * register a check event. */ static void expect_set( - const char* const function, const char* const parameter, - const char* const file, const int line, - const LargestIntegralType values[], const size_t number_of_values, - const CheckParameterValue check_function, const int count) { - CheckIntegerSet * const check_integer_set = - (CheckIntegerSet*)malloc(sizeof(*check_integer_set) + - (sizeof(values[0]) * number_of_values)); - LargestIntegralType * const set = (LargestIntegralType*)( - check_integer_set + 1); - declare_initialize_value_pointer_pointer(check_data, check_integer_set); - assert_non_null(values); - assert_true(number_of_values); - memcpy(set, values, number_of_values * sizeof(values[0])); - check_integer_set->set = set; - check_integer_set->size_of_set = number_of_values; - _expect_check( - function, parameter, file, line, check_function, - check_data.value, &check_integer_set->event, count); + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const LargestIntegralType values[], + const size_t number_of_values, + const CheckParameterValue check_function, + const int count) +{ + CheckIntegerSet *const check_integer_set = (CheckIntegerSet *) malloc( + sizeof(*check_integer_set) + (sizeof(values[0]) * number_of_values)); + LargestIntegralType *const set = + (LargestIntegralType *) (check_integer_set + 1); + declare_initialize_value_pointer_pointer(check_data, check_integer_set); + assert_non_null(values); + assert_true(number_of_values); + memcpy(set, values, number_of_values * sizeof(values[0])); + check_integer_set->set = set; + check_integer_set->size_of_set = number_of_values; + _expect_check( + function, + parameter, + file, + line, + check_function, + check_data.value, + &check_integer_set->event, + count); } - /* Add an event to check whether a value is in a set. */ void _expect_in_set( - const char* const function, const char* const parameter, - const char* const file, const int line, - const LargestIntegralType values[], const size_t number_of_values, - const int count) { - expect_set(function, parameter, file, line, values, number_of_values, - check_in_set, count); + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const LargestIntegralType values[], + const size_t number_of_values, + const int count) +{ + expect_set( + function, + parameter, + file, + line, + values, + number_of_values, + check_in_set, + count); } - /* Add an event to check whether a value isn't in a set. */ void _expect_not_in_set( - const char* const function, const char* const parameter, - const char* const file, const int line, - const LargestIntegralType values[], const size_t number_of_values, - const int count) { - expect_set(function, parameter, file, line, values, number_of_values, - check_not_in_set, count); + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const LargestIntegralType values[], + const size_t number_of_values, + const int count) +{ + expect_set( + function, + parameter, + file, + line, + values, + number_of_values, + check_not_in_set, + count); } - /* CheckParameterValue callback to check whether a value is within a range. */ -static int check_in_range(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - CheckIntegerRange * const check_integer_range = - cast_largest_integral_type_to_pointer(CheckIntegerRange*, - check_value_data); - assert_non_null(check_integer_range); - return integer_in_range_display_error(value, check_integer_range->minimum, - check_integer_range->maximum); +static int check_in_range( + const LargestIntegralType value, const LargestIntegralType check_value_data) +{ + CheckIntegerRange *const check_integer_range = + cast_largest_integral_type_to_pointer( + CheckIntegerRange *, check_value_data); + assert_non_null(check_integer_range); + return integer_in_range_display_error( + value, check_integer_range->minimum, check_integer_range->maximum); } - -/* CheckParameterValue callback to check whether a value is not within a range. */ -static int check_not_in_range(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - CheckIntegerRange * const check_integer_range = - cast_largest_integral_type_to_pointer(CheckIntegerRange*, - check_value_data); - assert_non_null(check_integer_range); - return integer_not_in_range_display_error( - value, check_integer_range->minimum, check_integer_range->maximum); +/* CheckParameterValue callback to check whether a value is not within a range. + */ +static int check_not_in_range( + const LargestIntegralType value, const LargestIntegralType check_value_data) +{ + CheckIntegerRange *const check_integer_range = + cast_largest_integral_type_to_pointer( + CheckIntegerRange *, check_value_data); + assert_non_null(check_integer_range); + return integer_not_in_range_display_error( + value, check_integer_range->minimum, check_integer_range->maximum); } - /* Create the callback data for check_in_range() or check_not_in_range() and * register a check event. */ static void expect_range( - const char* const function, const char* const parameter, - const char* const file, const int line, - const LargestIntegralType minimum, const LargestIntegralType maximum, - const CheckParameterValue check_function, const int count) { - CheckIntegerRange * const check_integer_range = - (CheckIntegerRange*)malloc(sizeof(*check_integer_range)); - declare_initialize_value_pointer_pointer(check_data, check_integer_range); - check_integer_range->minimum = minimum; - check_integer_range->maximum = maximum; - _expect_check(function, parameter, file, line, check_function, - check_data.value, &check_integer_range->event, count); + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const LargestIntegralType minimum, + const LargestIntegralType maximum, + const CheckParameterValue check_function, + const int count) +{ + CheckIntegerRange *const check_integer_range = + (CheckIntegerRange *) malloc(sizeof(*check_integer_range)); + declare_initialize_value_pointer_pointer(check_data, check_integer_range); + check_integer_range->minimum = minimum; + check_integer_range->maximum = maximum; + _expect_check( + function, + parameter, + file, + line, + check_function, + check_data.value, + &check_integer_range->event, + count); } - /* Add an event to determine whether a parameter is within a range. */ void _expect_in_range( - const char* const function, const char* const parameter, - const char* const file, const int line, - const LargestIntegralType minimum, const LargestIntegralType maximum, - const int count) { - expect_range(function, parameter, file, line, minimum, maximum, - check_in_range, count); + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const LargestIntegralType minimum, + const LargestIntegralType maximum, + const int count) +{ + expect_range( + function, parameter, file, line, minimum, maximum, check_in_range, count); } - /* Add an event to determine whether a parameter is not within a range. */ void _expect_not_in_range( - const char* const function, const char* const parameter, - const char* const file, const int line, - const LargestIntegralType minimum, const LargestIntegralType maximum, - const int count) { - expect_range(function, parameter, file, line, minimum, maximum, - check_not_in_range, count); + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const LargestIntegralType minimum, + const LargestIntegralType maximum, + const int count) +{ + expect_range( + function, + parameter, + file, + line, + minimum, + maximum, + check_not_in_range, + count); } - /* CheckParameterValue callback to check whether a value is equal to an * expected value. */ -static int check_value(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - return values_equal_display_error(value, check_value_data); +static int check_value( + const LargestIntegralType value, const LargestIntegralType check_value_data) +{ + return values_equal_display_error(value, check_value_data); } - /* Add an event to check a parameter equals an expected value. */ void _expect_value( - const char* const function, const char* const parameter, - const char* const file, const int line, - const LargestIntegralType value, const int count) { - _expect_check(function, parameter, file, line, check_value, value, NULL, - count); + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const LargestIntegralType value, + const int count) +{ + _expect_check( + function, parameter, file, line, check_value, value, NULL, count); } - /* CheckParameterValue callback to check whether a value is not equal to an * expected value. */ -static int check_not_value(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - return values_not_equal_display_error(value, check_value_data); +static int check_not_value( + const LargestIntegralType value, const LargestIntegralType check_value_data) +{ + return values_not_equal_display_error(value, check_value_data); } - /* Add an event to check a parameter is not equal to an expected value. */ void _expect_not_value( - const char* const function, const char* const parameter, - const char* const file, const int line, - const LargestIntegralType value, const int count) { - _expect_check(function, parameter, file, line, check_not_value, value, - NULL, count); + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const LargestIntegralType value, + const int count) +{ + _expect_check( + function, parameter, file, line, check_not_value, value, NULL, count); } - /* CheckParameterValue callback to check whether a parameter equals a string. */ -static int check_string(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - return string_equal_display_error( - cast_largest_integral_type_to_pointer(char*, value), - cast_largest_integral_type_to_pointer(char*, check_value_data)); +static int check_string( + const LargestIntegralType value, const LargestIntegralType check_value_data) +{ + return string_equal_display_error( + cast_largest_integral_type_to_pointer(char *, value), + cast_largest_integral_type_to_pointer(char *, check_value_data)); } - /* Add an event to check whether a parameter is equal to a string. */ void _expect_string( - const char* const function, const char* const parameter, - const char* const file, const int line, const char* string, - const int count) { - declare_initialize_value_pointer_pointer(string_pointer, - discard_const(string)); - _expect_check(function, parameter, file, line, check_string, - string_pointer.value, NULL, count); + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const char *string, + const int count) +{ + declare_initialize_value_pointer_pointer( + string_pointer, discard_const(string)); + _expect_check( + function, + parameter, + file, + line, + check_string, + string_pointer.value, + NULL, + count); } - /* CheckParameterValue callback to check whether a parameter is not equals to * a string. */ -static int check_not_string(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - return string_not_equal_display_error( - cast_largest_integral_type_to_pointer(char*, value), - cast_largest_integral_type_to_pointer(char*, check_value_data)); +static int check_not_string( + const LargestIntegralType value, const LargestIntegralType check_value_data) +{ + return string_not_equal_display_error( + cast_largest_integral_type_to_pointer(char *, value), + cast_largest_integral_type_to_pointer(char *, check_value_data)); } - /* Add an event to check whether a parameter is not equal to a string. */ void _expect_not_string( - const char* const function, const char* const parameter, - const char* const file, const int line, const char* string, - const int count) { - declare_initialize_value_pointer_pointer(string_pointer, - discard_const(string)); - _expect_check(function, parameter, file, line, check_not_string, - string_pointer.value, NULL, count); + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const char *string, + const int count) +{ + declare_initialize_value_pointer_pointer( + string_pointer, discard_const(string)); + _expect_check( + function, + parameter, + file, + line, + check_not_string, + string_pointer.value, + NULL, + count); } /* CheckParameterValue callback to check whether a parameter equals an area of * memory. */ -static int check_memory(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - CheckMemoryData * const check = cast_largest_integral_type_to_pointer( - CheckMemoryData*, check_value_data); - assert_non_null(check); - return memory_equal_display_error( - cast_largest_integral_type_to_pointer(const char*, value), - (const char*)check->memory, check->size); +static int check_memory( + const LargestIntegralType value, const LargestIntegralType check_value_data) +{ + CheckMemoryData *const check = cast_largest_integral_type_to_pointer( + CheckMemoryData *, check_value_data); + assert_non_null(check); + return memory_equal_display_error( + cast_largest_integral_type_to_pointer(const char *, value), + (const char *) check->memory, + check->size); } - /* Create the callback data for check_memory() or check_not_memory() and * register a check event. */ static void expect_memory_setup( - const char* const function, const char* const parameter, - const char* const file, const int line, - const void * const memory, const size_t size, - const CheckParameterValue check_function, const int count) { - CheckMemoryData * const check_data = - (CheckMemoryData*)malloc(sizeof(*check_data) + size); - void * const mem = (void*)(check_data + 1); - declare_initialize_value_pointer_pointer(check_data_pointer, check_data); - assert_non_null(memory); - assert_true(size); - memcpy(mem, memory, size); - check_data->memory = mem; - check_data->size = size; - _expect_check(function, parameter, file, line, check_function, - check_data_pointer.value, &check_data->event, count); + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const void *const memory, + const size_t size, + const CheckParameterValue check_function, + const int count) +{ + CheckMemoryData *const check_data = + (CheckMemoryData *) malloc(sizeof(*check_data) + size); + void *const mem = (void *) (check_data + 1); + declare_initialize_value_pointer_pointer(check_data_pointer, check_data); + assert_non_null(memory); + assert_true(size); + memcpy(mem, memory, size); + check_data->memory = mem; + check_data->size = size; + _expect_check( + function, + parameter, + file, + line, + check_function, + check_data_pointer.value, + &check_data->event, + count); } - /* Add an event to check whether a parameter matches an area of memory. */ void _expect_memory( - const char* const function, const char* const parameter, - const char* const file, const int line, const void* const memory, - const size_t size, const int count) { - expect_memory_setup(function, parameter, file, line, memory, size, - check_memory, count); + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const void *const memory, + const size_t size, + const int count) +{ + expect_memory_setup( + function, parameter, file, line, memory, size, check_memory, count); } - /* CheckParameterValue callback to check whether a parameter is not equal to * an area of memory. */ -static int check_not_memory(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - CheckMemoryData * const check = cast_largest_integral_type_to_pointer( - CheckMemoryData*, check_value_data); - assert_non_null(check); - return memory_not_equal_display_error( - cast_largest_integral_type_to_pointer(const char*, value), - (const char*)check->memory, - check->size); +static int check_not_memory( + const LargestIntegralType value, const LargestIntegralType check_value_data) +{ + CheckMemoryData *const check = cast_largest_integral_type_to_pointer( + CheckMemoryData *, check_value_data); + assert_non_null(check); + return memory_not_equal_display_error( + cast_largest_integral_type_to_pointer(const char *, value), + (const char *) check->memory, + check->size); } - /* Add an event to check whether a parameter doesn't match an area of memory. */ void _expect_not_memory( - const char* const function, const char* const parameter, - const char* const file, const int line, const void* const memory, - const size_t size, const int count) { - expect_memory_setup(function, parameter, file, line, memory, size, - check_not_memory, count); + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const void *const memory, + const size_t size, + const int count) +{ + expect_memory_setup( + function, parameter, file, line, memory, size, check_not_memory, count); } - /* CheckParameterValue callback that always returns 1. */ -static int check_any(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - (void)value; - (void)check_value_data; - return 1; +static int check_any( + const LargestIntegralType value, const LargestIntegralType check_value_data) +{ + (void) value; + (void) check_value_data; + return 1; } - /* Add an event to allow any value for a parameter. */ void _expect_any( - const char* const function, const char* const parameter, - const char* const file, const int line, const int count) { - _expect_check(function, parameter, file, line, check_any, 0, NULL, - count); + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const int count) +{ + _expect_check(function, parameter, file, line, check_any, 0, NULL, count); } - void _check_expected( - const char * const function_name, const char * const parameter_name, - const char* file, const int line, const LargestIntegralType value) { - void *result = NULL; - const char* symbols[] = {function_name, parameter_name}; - const int rc = get_symbol_value(&global_function_parameter_map_head, - symbols, 2, &result); - if (rc) { - CheckParameterEvent * const check = (CheckParameterEvent*)result; - int check_succeeded; - global_last_parameter_location = check->location; - check_succeeded = check->check_value(value, check->check_value_data); - if (rc == 1) { - free(check); - } - if (!check_succeeded) { - cm_print_error(SOURCE_LOCATION_FORMAT - ": error: Check of parameter %s, function %s failed\n" - SOURCE_LOCATION_FORMAT - ": note: Expected parameter declared here\n", - file, line, - parameter_name, function_name, - global_last_parameter_location.file, - global_last_parameter_location.line); - _fail(file, line); - } - } else { - cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value " - "to check parameter %s of function %s\n", file, line, - parameter_name, function_name); - if (source_location_is_set(&global_last_parameter_location)) { - cm_print_error(SOURCE_LOCATION_FORMAT - ": note: Previously declared parameter value was declared here\n", - global_last_parameter_location.file, - global_last_parameter_location.line); - } else { - cm_print_error("There were no previously declared parameter values " - "for this test.\n"); - } - exit_test(1); + const char *const function_name, + const char *const parameter_name, + const char *file, + const int line, + const LargestIntegralType value) +{ + void *result = NULL; + const char *symbols[] = {function_name, parameter_name}; + const int rc = get_symbol_value( + &global_function_parameter_map_head, symbols, 2, &result); + if (rc) { + CheckParameterEvent *const check = (CheckParameterEvent *) result; + int check_succeeded; + global_last_parameter_location = check->location; + check_succeeded = check->check_value(value, check->check_value_data); + if (rc == 1) { + free(check); } + if (!check_succeeded) { + cm_print_error( + SOURCE_LOCATION_FORMAT + ": error: Check of parameter %s, function %s " + "failed\n" SOURCE_LOCATION_FORMAT + ": note: Expected parameter declared here\n", + file, + line, + parameter_name, + function_name, + global_last_parameter_location.file, + global_last_parameter_location.line); + _fail(file, line); + } + } else { + cm_print_error( + SOURCE_LOCATION_FORMAT + ": error: Could not get value " + "to check parameter %s of function %s\n", + file, + line, + parameter_name, + function_name); + if (source_location_is_set(&global_last_parameter_location)) { + cm_print_error( + SOURCE_LOCATION_FORMAT + ": note: Previously declared parameter value was declared here\n", + global_last_parameter_location.file, + global_last_parameter_location.line); + } else { + cm_print_error( + "There were no previously declared parameter values " + "for this test.\n"); + } + exit_test(1); + } } - /* Replacement for assert. */ -void mock_assert(const int result, const char* const expression, - const char* const file, const int line) { - if (!result) { - if (global_expecting_assert) { - global_last_failed_assert = expression; - longjmp(global_expect_assert_env, result); - } else { - cm_print_error("ASSERT: %s\n", expression); - _fail(file, line); - } - } -} - - -void _assert_true(const LargestIntegralType result, - const char * const expression, - const char * const file, const int line) { - if (!result) { - cm_print_error("%s\n", expression); - _fail(file, line); - } -} - -void _assert_return_code(const LargestIntegralType result, - size_t rlen, - const LargestIntegralType error, - const char * const expression, - const char * const file, - const int line) +void mock_assert( + const int result, + const char *const expression, + const char *const file, + const int line) { - LargestIntegralType valmax; + if (!result) { + if (global_expecting_assert) { + global_last_failed_assert = expression; + longjmp(global_expect_assert_env, result); + } else { + cm_print_error("ASSERT: %s\n", expression); + _fail(file, line); + } + } +} +void _assert_true( + const LargestIntegralType result, + const char *const expression, + const char *const file, + const int line) +{ + if (!result) { + cm_print_error("%s\n", expression); + _fail(file, line); + } +} - switch (rlen) { +void _assert_return_code( + const LargestIntegralType result, + size_t rlen, + const LargestIntegralType error, + const char *const expression, + const char *const file, + const int line) +{ + LargestIntegralType valmax; + + switch (rlen) { case 1: - valmax = 255; - break; + valmax = 255; + break; case 2: - valmax = 32767; - break; + valmax = 32767; + break; case 4: - valmax = 2147483647; - break; + valmax = 2147483647; + break; case 8: default: - if (rlen > sizeof(valmax)) { - valmax = 2147483647; - } else { - valmax = 9223372036854775807L; - } - break; - } + if (rlen > sizeof(valmax)) { + valmax = 2147483647; + } else { + valmax = 9223372036854775807L; + } + break; + } - if (result > valmax - 1) { - if (error > 0) { - cm_print_error("%s < 0, errno(" - LargestIntegralTypePrintfFormatDecimal "): %s\n", - expression, error, strerror((int)error)); - } else { - cm_print_error("%s < 0\n", expression); - } - _fail(file, line); + if (result > valmax - 1) { + if (error > 0) { + cm_print_error( + "%s < 0, errno(" LargestIntegralTypePrintfFormatDecimal "): %s\n", + expression, + error, + strerror((int) error)); + } else { + cm_print_error("%s < 0\n", expression); } + _fail(file, line); + } } -void _assert_float_equal(const float a, - const float b, - const float epsilon, - const char * const file, - const int line) { - if (!float_values_equal_display_error(a, b, epsilon)) { - _fail(file, line); - } +void _assert_float_equal( + const float a, + const float b, + const float epsilon, + const char *const file, + const int line) +{ + if (!float_values_equal_display_error(a, b, epsilon)) { + _fail(file, line); + } } -void _assert_float_not_equal(const float a, - const float b, - const float epsilon, - const char * const file, - const int line) { - if (!float_values_not_equal_display_error(a, b, epsilon)) { - _fail(file, line); - } +void _assert_float_not_equal( + const float a, + const float b, + const float epsilon, + const char *const file, + const int line) +{ + if (!float_values_not_equal_display_error(a, b, epsilon)) { + _fail(file, line); + } } void _assert_int_equal( - const LargestIntegralType a, const LargestIntegralType b, - const char * const file, const int line) { - if (!values_equal_display_error(a, b)) { - _fail(file, line); - } + const LargestIntegralType a, + const LargestIntegralType b, + const char *const file, + const int line) +{ + if (!values_equal_display_error(a, b)) { + _fail(file, line); + } } - void _assert_int_not_equal( - const LargestIntegralType a, const LargestIntegralType b, - const char * const file, const int line) { - if (!values_not_equal_display_error(a, b)) { - _fail(file, line); - } + const LargestIntegralType a, + const LargestIntegralType b, + const char *const file, + const int line) +{ + if (!values_not_equal_display_error(a, b)) { + _fail(file, line); + } } - -void _assert_string_equal(const char * const a, const char * const b, - const char * const file, const int line) { - if (!string_equal_display_error(a, b)) { - _fail(file, line); - } +void _assert_string_equal( + const char *const a, + const char *const b, + const char *const file, + const int line) +{ + if (!string_equal_display_error(a, b)) { + _fail(file, line); + } } - -void _assert_string_not_equal(const char * const a, const char * const b, - const char *file, const int line) { - if (!string_not_equal_display_error(a, b)) { - _fail(file, line); - } +void _assert_string_not_equal( + const char *const a, const char *const b, const char *file, const int line) +{ + if (!string_not_equal_display_error(a, b)) { + _fail(file, line); + } } - -void _assert_memory_equal(const void * const a, const void * const b, - const size_t size, const char* const file, - const int line) { - if (!memory_equal_display_error((const char*)a, (const char*)b, size)) { - _fail(file, line); - } +void _assert_memory_equal( + const void *const a, + const void *const b, + const size_t size, + const char *const file, + const int line) +{ + if (!memory_equal_display_error((const char *) a, (const char *) b, size)) { + _fail(file, line); + } } - -void _assert_memory_not_equal(const void * const a, const void * const b, - const size_t size, const char* const file, - const int line) { - if (!memory_not_equal_display_error((const char*)a, (const char*)b, - size)) { - _fail(file, line); - } +void _assert_memory_not_equal( + const void *const a, + const void *const b, + const size_t size, + const char *const file, + const int line) +{ + if (!memory_not_equal_display_error( + (const char *) a, (const char *) b, size)) { + _fail(file, line); + } } - void _assert_in_range( - const LargestIntegralType value, const LargestIntegralType minimum, - const LargestIntegralType maximum, const char* const file, - const int line) { - if (!integer_in_range_display_error(value, minimum, maximum)) { - _fail(file, line); - } + const LargestIntegralType value, + const LargestIntegralType minimum, + const LargestIntegralType maximum, + const char *const file, + const int line) +{ + if (!integer_in_range_display_error(value, minimum, maximum)) { + _fail(file, line); + } } void _assert_not_in_range( - const LargestIntegralType value, const LargestIntegralType minimum, - const LargestIntegralType maximum, const char* const file, - const int line) { - if (!integer_not_in_range_display_error(value, minimum, maximum)) { - _fail(file, line); - } + const LargestIntegralType value, + const LargestIntegralType minimum, + const LargestIntegralType maximum, + const char *const file, + const int line) +{ + if (!integer_not_in_range_display_error(value, minimum, maximum)) { + _fail(file, line); + } } -void _assert_in_set(const LargestIntegralType value, - const LargestIntegralType values[], - const size_t number_of_values, const char* const file, - const int line) { - CheckIntegerSet check_integer_set; - check_integer_set.set = values; - check_integer_set.size_of_set = number_of_values; - if (!value_in_set_display_error(value, &check_integer_set, 0)) { - _fail(file, line); - } +void _assert_in_set( + const LargestIntegralType value, + const LargestIntegralType values[], + const size_t number_of_values, + const char *const file, + const int line) +{ + CheckIntegerSet check_integer_set; + check_integer_set.set = values; + check_integer_set.size_of_set = number_of_values; + if (!value_in_set_display_error(value, &check_integer_set, 0)) { + _fail(file, line); + } } -void _assert_not_in_set(const LargestIntegralType value, - const LargestIntegralType values[], - const size_t number_of_values, const char* const file, - const int line) { - CheckIntegerSet check_integer_set; - check_integer_set.set = values; - check_integer_set.size_of_set = number_of_values; - if (!value_in_set_display_error(value, &check_integer_set, 1)) { - _fail(file, line); - } +void _assert_not_in_set( + const LargestIntegralType value, + const LargestIntegralType values[], + const size_t number_of_values, + const char *const file, + const int line) +{ + CheckIntegerSet check_integer_set; + check_integer_set.set = values; + check_integer_set.size_of_set = number_of_values; + if (!value_in_set_display_error(value, &check_integer_set, 1)) { + _fail(file, line); + } } - /* Get the list of allocated blocks. */ -static ListNode* get_allocated_blocks_list(void) { - /* If it initialized, initialize the list of allocated blocks. */ - if (!global_allocated_blocks.value) { - list_initialize(&global_allocated_blocks); - global_allocated_blocks.value = (void*)1; - } - return &global_allocated_blocks; +static ListNode *get_allocated_blocks_list(void) +{ + /* If it initialized, initialize the list of allocated blocks. */ + if (!global_allocated_blocks.value) { + list_initialize(&global_allocated_blocks); + global_allocated_blocks.value = (void *) 1; + } + return &global_allocated_blocks; } static void *libc_calloc(size_t nmemb, size_t size) { #undef calloc - return calloc(nmemb, size); + return calloc(nmemb, size); #define calloc test_calloc } static void libc_free(void *ptr) { #undef free - free(ptr); + free(ptr); #define free test_free } static void *libc_realloc(void *ptr, size_t size) { #undef realloc - return realloc(ptr, size); + return realloc(ptr, size); #define realloc test_realloc } -static void vcm_print_error(const char* const format, - va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0); +static void vcm_print_error(const char *const format, va_list args) + CMOCKA_PRINTF_ATTRIBUTE(1, 0); /* It's important to use the libc malloc and free here otherwise * the automatic free of leaked blocks can reap the error messages */ -static void vcm_print_error(const char* const format, va_list args) +static void vcm_print_error(const char *const format, va_list args) { - char buffer[1024]; - size_t msg_len = 0; - va_list ap; - int len; - va_copy(ap, args); + char buffer[1024]; + size_t msg_len = 0; + va_list ap; + int len; + va_copy(ap, args); - len = vsnprintf(buffer, sizeof(buffer), format, args); - if (len < 0) { - /* TODO */ - goto end; - } + len = vsnprintf(buffer, sizeof(buffer), format, args); + if (len < 0) { + /* TODO */ + goto end; + } + if (cm_error_message == NULL) { + /* CREATE MESSAGE */ + + cm_error_message = libc_calloc(1, len + 1); if (cm_error_message == NULL) { - /* CREATE MESSAGE */ - - cm_error_message = libc_calloc(1, len + 1); - if (cm_error_message == NULL) { - /* TODO */ - goto end; - } - } else { - /* APPEND MESSAGE */ - char *tmp; - - msg_len = strlen(cm_error_message); - tmp = libc_realloc(cm_error_message, msg_len + len + 1); - if (tmp == NULL) { - goto end; - } - cm_error_message = tmp; + /* TODO */ + goto end; } + } else { + /* APPEND MESSAGE */ + char *tmp; - if (((size_t)len) < sizeof(buffer)) { - /* Use len + 1 to also copy '\0' */ - memcpy(cm_error_message + msg_len, buffer, len + 1); - } else { - vsnprintf(cm_error_message + msg_len, len, format, ap); + msg_len = strlen(cm_error_message); + tmp = libc_realloc(cm_error_message, msg_len + len + 1); + if (tmp == NULL) { + goto end; } + cm_error_message = tmp; + } + + if (((size_t) len) < sizeof(buffer)) { + /* Use len + 1 to also copy '\0' */ + memcpy(cm_error_message + msg_len, buffer, len + 1); + } else { + vsnprintf(cm_error_message + msg_len, len, format, ap); + } end: - va_end(ap); - + va_end(ap); } static void vcm_free_error(char *err_msg) { - libc_free(err_msg); + libc_free(err_msg); } /* Use the real malloc in this function. */ #undef malloc -void* _test_malloc(const size_t size, const char* file, const int line) { - char *ptr = NULL; - MallocBlockInfo block_info; - ListNode * const block_list = get_allocated_blocks_list(); - size_t allocate_size; - char *block = NULL; +void *_test_malloc(const size_t size, const char *file, const int line) +{ + char *ptr = NULL; + MallocBlockInfo block_info; + ListNode *const block_list = get_allocated_blocks_list(); + size_t allocate_size; + char *block = NULL; - allocate_size = size + (MALLOC_GUARD_SIZE * 2) + - sizeof(struct MallocBlockInfoData) + MALLOC_ALIGNMENT; - assert_true(allocate_size > size); + allocate_size = size + (MALLOC_GUARD_SIZE * 2) + + sizeof(struct MallocBlockInfoData) + MALLOC_ALIGNMENT; + assert_true(allocate_size > size); - block = (char *)malloc(allocate_size); - assert_non_null(block); + block = (char *) malloc(allocate_size); + assert_non_null(block); - /* Calculate the returned address. */ - ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE + - sizeof(struct MallocBlockInfoData) + - MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1)); + /* Calculate the returned address. */ + ptr = + (char + *) (((size_t) block + MALLOC_GUARD_SIZE + sizeof(struct MallocBlockInfoData) + MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1)); - /* Initialize the guard blocks. */ - memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE); - memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE); - memset(ptr, MALLOC_ALLOC_PATTERN, size); + /* Initialize the guard blocks. */ + memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE); + memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE); + memset(ptr, MALLOC_ALLOC_PATTERN, size); - block_info.ptr = ptr - (MALLOC_GUARD_SIZE + - sizeof(struct MallocBlockInfoData)); - set_source_location(&block_info.data->location, file, line); - block_info.data->allocated_size = allocate_size; - block_info.data->size = size; - block_info.data->block = block; - block_info.data->node.value = block_info.ptr; - list_add(block_list, &block_info.data->node); - return ptr; + block_info.ptr = + ptr - (MALLOC_GUARD_SIZE + sizeof(struct MallocBlockInfoData)); + set_source_location(&block_info.data->location, file, line); + block_info.data->allocated_size = allocate_size; + block_info.data->size = size; + block_info.data->block = block; + block_info.data->node.value = block_info.ptr; + list_add(block_list, &block_info.data->node); + return ptr; } #define malloc test_malloc - -void* _test_calloc(const size_t number_of_elements, const size_t size, - const char* file, const int line) { - void* const ptr = _test_malloc(number_of_elements * size, file, line); - if (ptr) { - memset(ptr, 0, number_of_elements * size); - } - return ptr; +void *_test_calloc( + const size_t number_of_elements, + const size_t size, + const char *file, + const int line) +{ + void *const ptr = _test_malloc(number_of_elements * size, file, line); + if (ptr) { + memset(ptr, 0, number_of_elements * size); + } + return ptr; } #define calloc test_calloc - /* Use the real free in this function. */ #undef free -void _test_free(void* const ptr, const char* file, const int line) { - unsigned int i; - char *block = discard_const_p(char, ptr); - MallocBlockInfo block_info; +void _test_free(void *const ptr, const char *file, const int line) +{ + unsigned int i; + char *block = discard_const_p(char, ptr); + MallocBlockInfo block_info; - if (ptr == NULL) { - return; - } + if (ptr == NULL) { + return; + } - _assert_true(cast_ptr_to_largest_integral_type(ptr), "ptr", file, line); - block_info.ptr = block - (MALLOC_GUARD_SIZE + - sizeof(struct MallocBlockInfoData)); - /* Check the guard blocks. */ - { - char *guards[2] = {block - MALLOC_GUARD_SIZE, - block + block_info.data->size}; - for (i = 0; i < ARRAY_SIZE(guards); i++) { - unsigned int j; - char * const guard = guards[i]; - for (j = 0; j < MALLOC_GUARD_SIZE; j++) { - const char diff = guard[j] - MALLOC_GUARD_PATTERN; - if (diff) { - cm_print_error(SOURCE_LOCATION_FORMAT - ": error: Guard block of %p size=%lu is corrupt\n" - SOURCE_LOCATION_FORMAT ": note: allocated here at %p\n", - file, - line, - ptr, - (unsigned long)block_info.data->size, - block_info.data->location.file, - block_info.data->location.line, - (void *)&guard[j]); - _fail(file, line); - } - } + _assert_true(cast_ptr_to_largest_integral_type(ptr), "ptr", file, line); + block_info.ptr = + block - (MALLOC_GUARD_SIZE + sizeof(struct MallocBlockInfoData)); + /* Check the guard blocks. */ + { + char *guards[2] = { + block - MALLOC_GUARD_SIZE, block + block_info.data->size}; + for (i = 0; i < ARRAY_SIZE(guards); i++) { + unsigned int j; + char *const guard = guards[i]; + for (j = 0; j < MALLOC_GUARD_SIZE; j++) { + const char diff = guard[j] - MALLOC_GUARD_PATTERN; + if (diff) { + cm_print_error( + SOURCE_LOCATION_FORMAT + ": error: Guard block of %p size=%lu is " + "corrupt\n" SOURCE_LOCATION_FORMAT + ": note: allocated here at %p\n", + file, + line, + ptr, + (unsigned long) block_info.data->size, + block_info.data->location.file, + block_info.data->location.line, + (void *) &guard[j]); + _fail(file, line); } + } } - list_remove(&block_info.data->node, NULL, NULL); + } + list_remove(&block_info.data->node, NULL, NULL); - block = discard_const_p(char, block_info.data->block); - memset(block, MALLOC_FREE_PATTERN, block_info.data->allocated_size); - free(block); + block = discard_const_p(char, block_info.data->block); + memset(block, MALLOC_FREE_PATTERN, block_info.data->allocated_size); + free(block); } #define free test_free #undef realloc -void *_test_realloc(void *ptr, - const size_t size, - const char *file, - const int line) +void * +_test_realloc(void *ptr, const size_t size, const char *file, const int line) { - MallocBlockInfo block_info; - char *block = ptr; - size_t block_size = size; - void *new_block; + MallocBlockInfo block_info; + char *block = ptr; + size_t block_size = size; + void *new_block; - if (ptr == NULL) { - return _test_malloc(size, file, line); - } + if (ptr == NULL) { + return _test_malloc(size, file, line); + } - if (size == 0) { - _test_free(ptr, file, line); - return NULL; - } - - block_info.ptr = block - (MALLOC_GUARD_SIZE + - sizeof(struct MallocBlockInfoData)); - - new_block = _test_malloc(size, file, line); - if (new_block == NULL) { - return NULL; - } - - if (block_info.data->size < size) { - block_size = block_info.data->size; - } - - memcpy(new_block, ptr, block_size); - - /* Free previous memory */ + if (size == 0) { _test_free(ptr, file, line); + return NULL; + } - return new_block; + block_info.ptr = + block - (MALLOC_GUARD_SIZE + sizeof(struct MallocBlockInfoData)); + + new_block = _test_malloc(size, file, line); + if (new_block == NULL) { + return NULL; + } + + if (block_info.data->size < size) { + block_size = block_info.data->size; + } + + memcpy(new_block, ptr, block_size); + + /* Free previous memory */ + _test_free(ptr, file, line); + + return new_block; } #define realloc test_realloc /* Crudely checkpoint the current heap state. */ -static const ListNode* check_point_allocated_blocks(void) { - return get_allocated_blocks_list()->prev; +static const ListNode *check_point_allocated_blocks(void) +{ + return get_allocated_blocks_list()->prev; } - /* Display the blocks allocated after the specified check point. This * function returns the number of blocks displayed. */ -static size_t display_allocated_blocks(const ListNode * const check_point) { - const ListNode * const head = get_allocated_blocks_list(); - const ListNode *node; - size_t allocated_blocks = 0; - assert_non_null(check_point); - assert_non_null(check_point->next); +static size_t display_allocated_blocks(const ListNode *const check_point) +{ + const ListNode *const head = get_allocated_blocks_list(); + const ListNode *node; + size_t allocated_blocks = 0; + assert_non_null(check_point); + assert_non_null(check_point->next); - for (node = check_point->next; node != head; node = node->next) { - const MallocBlockInfo block_info = { - .ptr = discard_const(node->value), - }; - assert_non_null(block_info.ptr); + for (node = check_point->next; node != head; node = node->next) { + const MallocBlockInfo block_info = { + .ptr = discard_const(node->value), + }; + assert_non_null(block_info.ptr); - if (allocated_blocks == 0) { - cm_print_error("Blocks allocated...\n"); - } - cm_print_error(SOURCE_LOCATION_FORMAT ": note: block %p allocated here\n", - block_info.data->location.file, - block_info.data->location.line, - block_info.data->block); - allocated_blocks++; + if (allocated_blocks == 0) { + cm_print_error("Blocks allocated...\n"); } - return allocated_blocks; + cm_print_error( + SOURCE_LOCATION_FORMAT ": note: block %p allocated here\n", + block_info.data->location.file, + block_info.data->location.line, + block_info.data->block); + allocated_blocks++; + } + return allocated_blocks; } - /* Free all blocks allocated after the specified check point. */ -static void free_allocated_blocks(const ListNode * const check_point) { - const ListNode * const head = get_allocated_blocks_list(); - const ListNode *node; - assert_non_null(check_point); +static void free_allocated_blocks(const ListNode *const check_point) +{ + const ListNode *const head = get_allocated_blocks_list(); + const ListNode *node; + assert_non_null(check_point); - node = check_point->next; - assert_non_null(node); + node = check_point->next; + assert_non_null(node); - while (node != head) { - const MallocBlockInfo block_info = { - .ptr = discard_const(node->value), - }; - node = node->next; - free(discard_const_p(char, block_info.data) + - sizeof(struct MallocBlockInfoData) + - MALLOC_GUARD_SIZE); - } + while (node != head) { + const MallocBlockInfo block_info = { + .ptr = discard_const(node->value), + }; + node = node->next; + free( + discard_const_p(char, block_info.data) + + sizeof(struct MallocBlockInfoData) + MALLOC_GUARD_SIZE); + } } - /* Fail if any any blocks are allocated after the specified check point. */ -static void fail_if_blocks_allocated(const ListNode * const check_point, - const char * const test_name) { - const size_t allocated_blocks = display_allocated_blocks(check_point); - if (allocated_blocks > 0) { - free_allocated_blocks(check_point); - cm_print_error("ERROR: %s leaked %zu block(s)\n", test_name, - allocated_blocks); - exit_test(1); - } -} - - -void _fail(const char * const file, const int line) { - enum cm_message_output output = cm_get_output(); - - switch(output) { - case CM_OUTPUT_STDOUT: - cm_print_error("[ LINE ] --- " SOURCE_LOCATION_FORMAT ": error: Failure!", file, line); - break; - default: - cm_print_error(SOURCE_LOCATION_FORMAT ": error: Failure!", file, line); - break; - } +static void fail_if_blocks_allocated( + const ListNode *const check_point, const char *const test_name) +{ + const size_t allocated_blocks = display_allocated_blocks(check_point); + if (allocated_blocks > 0) { + free_allocated_blocks(check_point); + cm_print_error( + "ERROR: %s leaked %zu block(s)\n", test_name, allocated_blocks); exit_test(1); + } } +void _fail(const char *const file, const int line) +{ + enum cm_message_output output = cm_get_output(); + + switch (output) { + case CM_OUTPUT_STDOUT: + cm_print_error( + "[ LINE ] --- " SOURCE_LOCATION_FORMAT ": error: Failure!", + file, + line); + break; + default: + cm_print_error(SOURCE_LOCATION_FORMAT ": error: Failure!", file, line); + break; + } + exit_test(1); +} #ifndef _WIN32 -static void exception_handler(int sig) { - const char *sig_strerror = ""; +static void exception_handler(int sig) +{ + const char *sig_strerror = ""; #ifdef HAVE_STRSIGNAL - sig_strerror = strsignal(sig); + sig_strerror = strsignal(sig); #endif - cm_print_error("Test failed with exception: %s(%d)", - sig_strerror, sig); - exit_test(1); + cm_print_error("Test failed with exception: %s(%d)", sig_strerror, sig); + exit_test(1); } #else /* _WIN32 */ -static LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) { - EXCEPTION_RECORD * const exception_record = - exception_pointers->ExceptionRecord; - const DWORD code = exception_record->ExceptionCode; - unsigned int i; - for (i = 0; i < ARRAY_SIZE(exception_codes); i++) { - const ExceptionCodeInfo * const code_info = &exception_codes[i]; - if (code == code_info->code) { - static int shown_debug_message = 0; - fflush(stdout); - cm_print_error("%s occurred at %p.\n", code_info->description, - exception_record->ExceptionAddress); - if (!shown_debug_message) { - cm_print_error( - "\n" - "To debug in Visual Studio...\n" - "1. Select menu item File->Open Project\n" - "2. Change 'Files of type' to 'Executable Files'\n" - "3. Open this executable.\n" - "4. Select menu item Debug->Start\n" - "\n" - "Alternatively, set the environment variable \n" - "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n" - "then click 'Debug' in the popup dialog box.\n" - "\n"); - shown_debug_message = 1; - } - exit_test(0); - return EXCEPTION_EXECUTE_HANDLER; - } +static LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) +{ + EXCEPTION_RECORD *const exception_record = + exception_pointers->ExceptionRecord; + const DWORD code = exception_record->ExceptionCode; + unsigned int i; + for (i = 0; i < ARRAY_SIZE(exception_codes); i++) { + const ExceptionCodeInfo *const code_info = &exception_codes[i]; + if (code == code_info->code) { + static int shown_debug_message = 0; + fflush(stdout); + cm_print_error( + "%s occurred at %p.\n", + code_info->description, + exception_record->ExceptionAddress); + if (!shown_debug_message) { + cm_print_error( + "\n" + "To debug in Visual Studio...\n" + "1. Select menu item File->Open Project\n" + "2. Change 'Files of type' to 'Executable Files'\n" + "3. Open this executable.\n" + "4. Select menu item Debug->Start\n" + "\n" + "Alternatively, set the environment variable \n" + "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n" + "then click 'Debug' in the popup dialog box.\n" + "\n"); + shown_debug_message = 1; + } + exit_test(0); + return EXCEPTION_EXECUTE_HANDLER; } - return EXCEPTION_CONTINUE_SEARCH; + } + return EXCEPTION_CONTINUE_SEARCH; } #endif /* !_WIN32 */ -void cm_print_error(const char * const format, ...) +void cm_print_error(const char *const format, ...) { - va_list args; - va_start(args, format); - if (cm_error_message_enabled) { - vcm_print_error(format, args); - } else { - vprint_error(format, args); - } - va_end(args); + va_list args; + va_start(args, format); + if (cm_error_message_enabled) { + vcm_print_error(format, args); + } else { + vprint_error(format, args); + } + va_end(args); } /* Standard output and error print methods. */ -void vprint_message(const char* const format, va_list args) { - char buffer[1024]; - vsnprintf(buffer, sizeof(buffer), format, args); - printf("%s", buffer); - fflush(stdout); +void vprint_message(const char *const format, va_list args) +{ + char buffer[1024]; + vsnprintf(buffer, sizeof(buffer), format, args); + printf("%s", buffer); + fflush(stdout); #ifdef _WIN32 - OutputDebugString(buffer); + OutputDebugString(buffer); #endif /* _WIN32 */ } - -void vprint_error(const char* const format, va_list args) { - char buffer[1024]; - vsnprintf(buffer, sizeof(buffer), format, args); - fprintf(stderr, "%s", buffer); - fflush(stderr); +void vprint_error(const char *const format, va_list args) +{ + char buffer[1024]; + vsnprintf(buffer, sizeof(buffer), format, args); + fprintf(stderr, "%s", buffer); + fflush(stderr); #ifdef _WIN32 - OutputDebugString(buffer); + OutputDebugString(buffer); #endif /* _WIN32 */ } - -void print_message(const char* const format, ...) { - va_list args; - va_start(args, format); - vprint_message(format, args); - va_end(args); +void print_message(const char *const format, ...) +{ + va_list args; + va_start(args, format); + vprint_message(format, args); + va_end(args); } - -void print_error(const char* const format, ...) { - va_list args; - va_start(args, format); - vprint_error(format, args); - va_end(args); +void print_error(const char *const format, ...) +{ + va_list args; + va_start(args, format); + vprint_error(format, args); + va_end(args); } /* New formatter */ static enum cm_message_output cm_get_output(void) { - enum cm_message_output output = global_msg_output; - char *env; + enum cm_message_output output = global_msg_output; + char *env; - env = getenv("CMOCKA_MESSAGE_OUTPUT"); - if (env != NULL) { - if (strcasecmp(env, "STDOUT") == 0) { - output = CM_OUTPUT_STDOUT; - } else if (strcasecmp(env, "SUBUNIT") == 0) { - output = CM_OUTPUT_SUBUNIT; - } else if (strcasecmp(env, "TAP") == 0) { - output = CM_OUTPUT_TAP; - } else if (strcasecmp(env, "XML") == 0) { - output = CM_OUTPUT_XML; - } + env = getenv("CMOCKA_MESSAGE_OUTPUT"); + if (env != NULL) { + if (strcasecmp(env, "STDOUT") == 0) { + output = CM_OUTPUT_STDOUT; + } else if (strcasecmp(env, "SUBUNIT") == 0) { + output = CM_OUTPUT_SUBUNIT; + } else if (strcasecmp(env, "TAP") == 0) { + output = CM_OUTPUT_TAP; + } else if (strcasecmp(env, "XML") == 0) { + output = CM_OUTPUT_XML; } + } - return output; + return output; } enum cm_printf_type { - PRINTF_TEST_START, - PRINTF_TEST_SUCCESS, - PRINTF_TEST_FAILURE, - PRINTF_TEST_ERROR, - PRINTF_TEST_SKIPPED, + PRINTF_TEST_START, + PRINTF_TEST_SUCCESS, + PRINTF_TEST_FAILURE, + PRINTF_TEST_ERROR, + PRINTF_TEST_SKIPPED, }; static int xml_printed; static int file_append; -static void cmprintf_group_finish_xml(const char *group_name, - size_t total_executed, - size_t total_failed, - size_t total_errors, - size_t total_skipped, - double total_runtime, - struct CMUnitTestState *cm_tests) +static void cmprintf_group_finish_xml( + const char *group_name, + size_t total_executed, + size_t total_failed, + size_t total_errors, + size_t total_skipped, + double total_runtime, + struct CMUnitTestState *cm_tests) { - FILE *fp = stdout; - int file_opened = 0; - int multiple_files = 0; - char *env; - size_t i; + FILE *fp = stdout; + int file_opened = 0; + int multiple_files = 0; + char *env; + size_t i; - env = getenv("CMOCKA_XML_FILE"); - if (env != NULL) { - char buf[1024]; - int rc; + env = getenv("CMOCKA_XML_FILE"); + if (env != NULL) { + char buf[1024]; + int rc; - snprintf(buf, sizeof(buf), "%s", env); + snprintf(buf, sizeof(buf), "%s", env); - rc = c_strreplace(buf, sizeof(buf), "%g", group_name, &multiple_files); - if (rc < 0) { - snprintf(buf, sizeof(buf), "%s", env); - } + rc = c_strreplace(buf, sizeof(buf), "%g", group_name, &multiple_files); + if (rc < 0) { + snprintf(buf, sizeof(buf), "%s", env); + } - fp = fopen(buf, "r"); - if (fp == NULL) { - fp = fopen(buf, "w"); - if (fp != NULL) { - file_append = 1; - file_opened = 1; - } else { - fp = stderr; - } + fp = fopen(buf, "r"); + if (fp == NULL) { + fp = fopen(buf, "w"); + if (fp != NULL) { + file_append = 1; + file_opened = 1; + } else { + fp = stderr; + } + } else { + fclose(fp); + if (file_append) { + fp = fopen(buf, "a"); + if (fp != NULL) { + file_opened = 1; + xml_printed = 1; } else { - fclose(fp); - if (file_append) { - fp = fopen(buf, "a"); - if (fp != NULL) { - file_opened = 1; - xml_printed = 1; - } else { - fp = stderr; - } - } else { - fp = stderr; - } + fp = stderr; } + } else { + fp = stderr; + } } + } - if (!xml_printed || (file_opened && !file_append)) { - fprintf(fp, "\n"); - if (!file_opened) { - xml_printed = 1; + if (!xml_printed || (file_opened && !file_append)) { + fprintf(fp, "\n"); + if (!file_opened) { + xml_printed = 1; + } + } + + fprintf(fp, "\n"); + fprintf( + fp, + " \n", + group_name, + total_runtime, /* seconds */ + (unsigned) total_executed, + (unsigned) total_failed, + (unsigned) total_errors, + (unsigned) total_skipped); + + for (i = 0; i < total_executed; i++) { + struct CMUnitTestState *cmtest = &cm_tests[i]; + + fprintf( + fp, + " \n", + cmtest->test->name, + cmtest->runtime); + + switch (cmtest->status) { + case CM_TEST_ERROR: + case CM_TEST_FAILED: + if (cmtest->error_message != NULL) { + fprintf( + fp, + " \n", + cmtest->error_message); + } else { + fprintf(fp, " \n"); } + break; + case CM_TEST_SKIPPED: + fprintf(fp, " \n"); + break; + + case CM_TEST_PASSED: + case CM_TEST_NOT_STARTED: + break; } - fprintf(fp, "\n"); - fprintf(fp, " \n", - group_name, - total_runtime, /* seconds */ - (unsigned)total_executed, - (unsigned)total_failed, - (unsigned)total_errors, - (unsigned)total_skipped); + fprintf(fp, " \n"); + } - for (i = 0; i < total_executed; i++) { - struct CMUnitTestState *cmtest = &cm_tests[i]; + fprintf(fp, " \n"); + fprintf(fp, "\n"); - fprintf(fp, " \n", - cmtest->test->name, cmtest->runtime); - - switch (cmtest->status) { - case CM_TEST_ERROR: - case CM_TEST_FAILED: - if (cmtest->error_message != NULL) { - fprintf(fp, " \n", - cmtest->error_message); - } else { - fprintf(fp, " \n"); - } - break; - case CM_TEST_SKIPPED: - fprintf(fp, " \n"); - break; - - case CM_TEST_PASSED: - case CM_TEST_NOT_STARTED: - break; - } - - fprintf(fp, " \n"); - } - - fprintf(fp, " \n"); - fprintf(fp, "\n"); - - if (file_opened) { - fclose(fp); - } + if (file_opened) { + fclose(fp); + } } static void cmprintf_group_start_standard(const size_t num_tests) { - print_message("[==========] Running %u test(s).\n", - (unsigned)num_tests); + print_message("[==========] Running %u test(s).\n", (unsigned) num_tests); } -static void cmprintf_group_finish_standard(size_t total_executed, - size_t total_passed, - size_t total_failed, - size_t total_errors, - size_t total_skipped, - struct CMUnitTestState *cm_tests) +static void cmprintf_group_finish_standard( + size_t total_executed, + size_t total_passed, + size_t total_failed, + size_t total_errors, + size_t total_skipped, + struct CMUnitTestState *cm_tests) { - size_t i; + size_t i; - print_message("[==========] %u test(s) run.\n", (unsigned)total_executed); - print_error("[ PASSED ] %u test(s).\n", - (unsigned)(total_passed)); + print_message("[==========] %u test(s) run.\n", (unsigned) total_executed); + print_error("[ PASSED ] %u test(s).\n", (unsigned) (total_passed)); - if (total_skipped) { - print_error("[ SKIPPED ] %"PRIdS " test(s), listed below:\n", total_skipped); - for (i = 0; i < total_executed; i++) { - struct CMUnitTestState *cmtest = &cm_tests[i]; + if (total_skipped) { + print_error( + "[ SKIPPED ] %" PRIdS " test(s), listed below:\n", total_skipped); + for (i = 0; i < total_executed; i++) { + struct CMUnitTestState *cmtest = &cm_tests[i]; - if (cmtest->status == CM_TEST_SKIPPED) { - print_error("[ SKIPPED ] %s\n", cmtest->test->name); - } - } - print_error("\n %u SKIPPED TEST(S)\n", (unsigned)(total_skipped)); + if (cmtest->status == CM_TEST_SKIPPED) { + print_error("[ SKIPPED ] %s\n", cmtest->test->name); + } } + print_error("\n %u SKIPPED TEST(S)\n", (unsigned) (total_skipped)); + } - if (total_failed) { - print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed); - for (i = 0; i < total_executed; i++) { - struct CMUnitTestState *cmtest = &cm_tests[i]; + if (total_failed) { + print_error( + "[ FAILED ] %" PRIdS " test(s), listed below:\n", total_failed); + for (i = 0; i < total_executed; i++) { + struct CMUnitTestState *cmtest = &cm_tests[i]; - if (cmtest->status == CM_TEST_FAILED) { - print_error("[ FAILED ] %s\n", cmtest->test->name); - } - } - print_error("\n %u FAILED TEST(S)\n", - (unsigned)(total_failed + total_errors)); + if (cmtest->status == CM_TEST_FAILED) { + print_error("[ FAILED ] %s\n", cmtest->test->name); + } } + print_error( + "\n %u FAILED TEST(S)\n", (unsigned) (total_failed + total_errors)); + } } -static void cmprintf_standard(enum cm_printf_type type, - const char *test_name, - const char *error_message) +static void cmprintf_standard( + enum cm_printf_type type, const char *test_name, const char *error_message) { - switch (type) { + switch (type) { case PRINTF_TEST_START: - print_message("[ RUN ] %s\n", test_name); - break; + print_message("[ RUN ] %s\n", test_name); + break; case PRINTF_TEST_SUCCESS: - print_message("[ OK ] %s\n", test_name); - break; + print_message("[ OK ] %s\n", test_name); + break; case PRINTF_TEST_FAILURE: - if (error_message != NULL) { - print_error("[ ERROR ] --- %s\n", error_message); - } - print_message("[ FAILED ] %s\n", test_name); - break; + if (error_message != NULL) { + print_error("[ ERROR ] --- %s\n", error_message); + } + print_message("[ FAILED ] %s\n", test_name); + break; case PRINTF_TEST_SKIPPED: - print_message("[ SKIPPED ] %s\n", test_name); - break; + print_message("[ SKIPPED ] %s\n", test_name); + break; case PRINTF_TEST_ERROR: - if (error_message != NULL) { - print_error("%s\n", error_message); - } - print_error("[ ERROR ] %s\n", test_name); - break; - } + if (error_message != NULL) { + print_error("%s\n", error_message); + } + print_error("[ ERROR ] %s\n", test_name); + break; + } } static void cmprintf_group_start_tap(const size_t num_tests) { - print_message("1..%u\n", (unsigned)num_tests); + print_message("1..%u\n", (unsigned) num_tests); } -static void cmprintf_group_finish_tap(const char *group_name, - size_t total_executed, - size_t total_passed, - size_t total_skipped) +static void cmprintf_group_finish_tap( + const char *group_name, + size_t total_executed, + size_t total_passed, + size_t total_skipped) { - const char *status = "not ok"; - if (total_passed + total_skipped == total_executed) { - status = "ok"; - } - print_message("# %s - %s\n", status, group_name); + const char *status = "not ok"; + if (total_passed + total_skipped == total_executed) { + status = "ok"; + } + print_message("# %s - %s\n", status, group_name); } -static void cmprintf_tap(enum cm_printf_type type, - uint32_t test_number, - const char *test_name, - const char *error_message) +static void cmprintf_tap( + enum cm_printf_type type, + uint32_t test_number, + const char *test_name, + const char *error_message) { - switch (type) { + switch (type) { case PRINTF_TEST_START: - break; + break; case PRINTF_TEST_SUCCESS: - print_message("ok %u - %s\n", (unsigned)test_number, test_name); - break; + print_message("ok %u - %s\n", (unsigned) test_number, test_name); + break; case PRINTF_TEST_FAILURE: - print_message("not ok %u - %s\n", (unsigned)test_number, test_name); - if (error_message != NULL) { - char *msg; - char *p; + print_message("not ok %u - %s\n", (unsigned) test_number, test_name); + if (error_message != NULL) { + char *msg; + char *p; - msg = strdup(error_message); - if (msg == NULL) { - return; - } - p = msg; - - while (p[0] != '\0') { - char *q = p; - - p = strchr(q, '\n'); - if (p != NULL) { - p[0] = '\0'; - } - - print_message("# %s\n", q); - - if (p == NULL) { - break; - } - p++; - } - libc_free(msg); + msg = strdup(error_message); + if (msg == NULL) { + return; } - break; + p = msg; + + while (p[0] != '\0') { + char *q = p; + + p = strchr(q, '\n'); + if (p != NULL) { + p[0] = '\0'; + } + + print_message("# %s\n", q); + + if (p == NULL) { + break; + } + p++; + } + libc_free(msg); + } + break; case PRINTF_TEST_SKIPPED: - print_message("not ok %u # SKIP %s\n", (unsigned)test_number, test_name); - break; + print_message("not ok %u # SKIP %s\n", (unsigned) test_number, test_name); + break; case PRINTF_TEST_ERROR: - print_message("not ok %u - %s %s\n", - (unsigned)test_number, test_name, error_message); - break; - } + print_message( + "not ok %u - %s %s\n", + (unsigned) test_number, + test_name, + error_message); + break; + } } -static void cmprintf_subunit(enum cm_printf_type type, - const char *test_name, - const char *error_message) +static void cmprintf_subunit( + enum cm_printf_type type, const char *test_name, const char *error_message) { - switch (type) { + switch (type) { case PRINTF_TEST_START: - print_message("test: %s\n", test_name); - break; + print_message("test: %s\n", test_name); + break; case PRINTF_TEST_SUCCESS: - print_message("success: %s\n", test_name); - break; + print_message("success: %s\n", test_name); + break; case PRINTF_TEST_FAILURE: - print_message("failure: %s", test_name); - if (error_message != NULL) { - print_message(" [\n%s\n]\n", error_message); - } - break; + print_message("failure: %s", test_name); + if (error_message != NULL) { + print_message(" [\n%s\n]\n", error_message); + } + break; case PRINTF_TEST_SKIPPED: - print_message("skip: %s\n", test_name); - break; + print_message("skip: %s\n", test_name); + break; case PRINTF_TEST_ERROR: - print_message("error: %s [ %s ]\n", test_name, error_message); - break; - } + print_message("error: %s [ %s ]\n", test_name, error_message); + break; + } } static void cmprintf_group_start(const size_t num_tests) { - enum cm_message_output output; + enum cm_message_output output; - output = cm_get_output(); + output = cm_get_output(); - switch (output) { + switch (output) { case CM_OUTPUT_STDOUT: - cmprintf_group_start_standard(num_tests); - break; + cmprintf_group_start_standard(num_tests); + break; case CM_OUTPUT_SUBUNIT: - break; + break; case CM_OUTPUT_TAP: - cmprintf_group_start_tap(num_tests); - break; + cmprintf_group_start_tap(num_tests); + break; case CM_OUTPUT_XML: - break; - } + break; + } } -static void cmprintf_group_finish(const char *group_name, - size_t total_executed, - size_t total_passed, - size_t total_failed, - size_t total_errors, - size_t total_skipped, - double total_runtime, - struct CMUnitTestState *cm_tests) +static void cmprintf_group_finish( + const char *group_name, + size_t total_executed, + size_t total_passed, + size_t total_failed, + size_t total_errors, + size_t total_skipped, + double total_runtime, + struct CMUnitTestState *cm_tests) { - enum cm_message_output output; + enum cm_message_output output; - output = cm_get_output(); + output = cm_get_output(); - switch (output) { + switch (output) { case CM_OUTPUT_STDOUT: - cmprintf_group_finish_standard(total_executed, - total_passed, - total_failed, - total_errors, - total_skipped, - cm_tests); - break; + cmprintf_group_finish_standard( + total_executed, + total_passed, + total_failed, + total_errors, + total_skipped, + cm_tests); + break; case CM_OUTPUT_SUBUNIT: - break; + break; case CM_OUTPUT_TAP: - cmprintf_group_finish_tap(group_name, total_executed, total_passed, total_skipped); - break; + cmprintf_group_finish_tap( + group_name, total_executed, total_passed, total_skipped); + break; case CM_OUTPUT_XML: - cmprintf_group_finish_xml(group_name, - total_executed, - total_failed, - total_errors, - total_skipped, - total_runtime, - cm_tests); - break; - } + cmprintf_group_finish_xml( + group_name, + total_executed, + total_failed, + total_errors, + total_skipped, + total_runtime, + cm_tests); + break; + } } -static void cmprintf(enum cm_printf_type type, - size_t test_number, - const char *test_name, - const char *error_message) +static void cmprintf( + enum cm_printf_type type, + size_t test_number, + const char *test_name, + const char *error_message) { - enum cm_message_output output; + enum cm_message_output output; - output = cm_get_output(); + output = cm_get_output(); - switch (output) { + switch (output) { case CM_OUTPUT_STDOUT: - cmprintf_standard(type, test_name, error_message); - break; + cmprintf_standard(type, test_name, error_message); + break; case CM_OUTPUT_SUBUNIT: - cmprintf_subunit(type, test_name, error_message); - break; + cmprintf_subunit(type, test_name, error_message); + break; case CM_OUTPUT_TAP: - cmprintf_tap(type, test_number, test_name, error_message); - break; + cmprintf_tap(type, test_number, test_name, error_message); + break; case CM_OUTPUT_XML: - break; - } + break; + } } void cmocka_set_message_output(enum cm_message_output output) { - global_msg_output = output; + global_msg_output = output; } void cmocka_set_test_filter(const char *pattern) { - global_test_filter_pattern = pattern; + global_test_filter_pattern = pattern; } void cmocka_set_skip_filter(const char *pattern) { - global_skip_filter_pattern = pattern; + global_skip_filter_pattern = pattern; } /**************************************************************************** @@ -2703,431 +2957,430 @@ void cmocka_set_skip_filter(const char *pattern) ****************************************************************************/ #ifdef HAVE_STRUCT_TIMESPEC -static struct timespec cm_tspecdiff(struct timespec time1, - struct timespec time0) +static struct timespec +cm_tspecdiff(struct timespec time1, struct timespec time0) { - struct timespec ret; - int xsec = 0; - int sign = 1; + struct timespec ret; + int xsec = 0; + int sign = 1; - if (time0.tv_nsec > time1.tv_nsec) { - xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1)); - time0.tv_nsec -= (long int) (1E9 * xsec); - time0.tv_sec += xsec; - } + if (time0.tv_nsec > time1.tv_nsec) { + xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1)); + time0.tv_nsec -= (long int) (1E9 * xsec); + time0.tv_sec += xsec; + } - if ((time1.tv_nsec - time0.tv_nsec) > 1E9) { - xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9); - time0.tv_nsec += (long int) (1E9 * xsec); - time0.tv_sec -= xsec; - } + if ((time1.tv_nsec - time0.tv_nsec) > 1E9) { + xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9); + time0.tv_nsec += (long int) (1E9 * xsec); + time0.tv_sec -= xsec; + } - ret.tv_sec = time1.tv_sec - time0.tv_sec; - ret.tv_nsec = time1.tv_nsec - time0.tv_nsec; + ret.tv_sec = time1.tv_sec - time0.tv_sec; + ret.tv_nsec = time1.tv_nsec - time0.tv_nsec; - if (time1.tv_sec < time0.tv_sec) { - sign = -1; - } + if (time1.tv_sec < time0.tv_sec) { + sign = -1; + } - ret.tv_sec = ret.tv_sec * sign; + ret.tv_sec = ret.tv_sec * sign; - return ret; + return ret; } static double cm_secdiff(struct timespec clock1, struct timespec clock0) { - double ret; - struct timespec diff; + double ret; + struct timespec diff; - diff = cm_tspecdiff(clock1, clock0); + diff = cm_tspecdiff(clock1, clock0); - ret = diff.tv_sec; - ret += (double) diff.tv_nsec / (double) 1E9; + ret = diff.tv_sec; + ret += (double) diff.tv_nsec / (double) 1E9; - return ret; + return ret; } #endif /* HAVE_STRUCT_TIMESPEC */ /**************************************************************************** * CMOCKA TEST RUNNER ****************************************************************************/ -static int cmocka_run_one_test_or_fixture(const char *function_name, - CMUnitTestFunction test_func, - CMFixtureFunction setup_func, - CMFixtureFunction teardown_func, - void ** const volatile state, - const void *const heap_check_point) +static int cmocka_run_one_test_or_fixture( + const char *function_name, + CMUnitTestFunction test_func, + CMFixtureFunction setup_func, + CMFixtureFunction teardown_func, + void **const volatile state, + const void *const heap_check_point) { - const ListNode * const volatile check_point = (const ListNode*) - (heap_check_point != NULL ? - heap_check_point : check_point_allocated_blocks()); - int handle_exceptions = 1; - void *current_state = NULL; - int rc = 0; + const ListNode *const volatile check_point = + (const ListNode + *) (heap_check_point != NULL ? heap_check_point : check_point_allocated_blocks()); + int handle_exceptions = 1; + void *current_state = NULL; + int rc = 0; - /* FIXME check only one test or fixture is set */ + /* FIXME check only one test or fixture is set */ - /* Detect if we should handle exceptions */ + /* Detect if we should handle exceptions */ #ifdef _WIN32 - handle_exceptions = !IsDebuggerPresent(); + handle_exceptions = !IsDebuggerPresent(); #endif /* _WIN32 */ #ifdef UNIT_TESTING_DEBUG - handle_exceptions = 0; + handle_exceptions = 0; #endif /* UNIT_TESTING_DEBUG */ - - if (handle_exceptions) { + if (handle_exceptions) { #ifndef _WIN32 - unsigned int i; - for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { - default_signal_functions[i] = signal( - exception_signals[i], exception_handler); - } -#else /* _WIN32 */ - previous_exception_filter = SetUnhandledExceptionFilter( - exception_filter); -#endif /* !_WIN32 */ + unsigned int i; + for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { + default_signal_functions[i] = + signal(exception_signals[i], exception_handler); } +#else /* _WIN32 */ + previous_exception_filter = SetUnhandledExceptionFilter(exception_filter); +#endif /* !_WIN32 */ + } - /* Init the test structure */ - initialize_testing(function_name); + /* Init the test structure */ + initialize_testing(function_name); - global_running_test = 1; + global_running_test = 1; - if (cm_setjmp(global_run_test_env) == 0) { - if (test_func != NULL) { - test_func(state != NULL ? state : ¤t_state); + if (cm_setjmp(global_run_test_env) == 0) { + if (test_func != NULL) { + test_func(state != NULL ? state : ¤t_state); - fail_if_blocks_allocated(check_point, function_name); - rc = 0; - } else if (setup_func != NULL) { - rc = setup_func(state != NULL ? state : ¤t_state); + fail_if_blocks_allocated(check_point, function_name); + rc = 0; + } else if (setup_func != NULL) { + rc = setup_func(state != NULL ? state : ¤t_state); - /* - * For setup we can ignore any allocated blocks. We just need to - * ensure they're deallocated on tear down. - */ - } else if (teardown_func != NULL) { - rc = teardown_func(state != NULL ? state : ¤t_state); + /* + * For setup we can ignore any allocated blocks. We just need to + * ensure they're deallocated on tear down. + */ + } else if (teardown_func != NULL) { + rc = teardown_func(state != NULL ? state : ¤t_state); - fail_if_blocks_allocated(check_point, function_name); - } else { - /* ERROR */ - } - fail_if_leftover_values(function_name); - global_running_test = 0; + fail_if_blocks_allocated(check_point, function_name); } else { - /* TEST FAILED */ - global_running_test = 0; - rc = -1; + /* ERROR */ } - teardown_testing(function_name); + fail_if_leftover_values(function_name); + global_running_test = 0; + } else { + /* TEST FAILED */ + global_running_test = 0; + rc = -1; + } + teardown_testing(function_name); - if (handle_exceptions) { + if (handle_exceptions) { #ifndef _WIN32 - unsigned int i; - for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { - signal(exception_signals[i], default_signal_functions[i]); - } -#else /* _WIN32 */ - if (previous_exception_filter) { - SetUnhandledExceptionFilter(previous_exception_filter); - previous_exception_filter = NULL; - } -#endif /* !_WIN32 */ + unsigned int i; + for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { + signal(exception_signals[i], default_signal_functions[i]); } +#else /* _WIN32 */ + if (previous_exception_filter) { + SetUnhandledExceptionFilter(previous_exception_filter); + previous_exception_filter = NULL; + } +#endif /* !_WIN32 */ + } - return rc; + return rc; } -static int cmocka_run_group_fixture(const char *function_name, - CMFixtureFunction setup_func, - CMFixtureFunction teardown_func, - void **state, - const void *const heap_check_point) +static int cmocka_run_group_fixture( + const char *function_name, + CMFixtureFunction setup_func, + CMFixtureFunction teardown_func, + void **state, + const void *const heap_check_point) { - int rc; + int rc; - if (setup_func != NULL) { - rc = cmocka_run_one_test_or_fixture(function_name, - NULL, - setup_func, - NULL, - state, - heap_check_point); - } else { - rc = cmocka_run_one_test_or_fixture(function_name, - NULL, - NULL, - teardown_func, - state, - heap_check_point); - } + if (setup_func != NULL) { + rc = cmocka_run_one_test_or_fixture( + function_name, NULL, setup_func, NULL, state, heap_check_point); + } else { + rc = cmocka_run_one_test_or_fixture( + function_name, NULL, NULL, teardown_func, state, heap_check_point); + } - return rc; + return rc; } static int cmocka_run_one_tests(struct CMUnitTestState *test_state) { #ifdef HAVE_STRUCT_TIMESPEC - struct timespec start = { - .tv_sec = 0, - .tv_nsec = 0, - }; - struct timespec finish = { - .tv_sec = 0, - .tv_nsec = 0, - }; + struct timespec start = { + .tv_sec = 0, + .tv_nsec = 0, + }; + struct timespec finish = { + .tv_sec = 0, + .tv_nsec = 0, + }; #endif - int rc = 0; + int rc = 0; - /* Run setup */ - if (test_state->test->setup_func != NULL) { - /* Setup the memory check point, it will be evaluated on teardown */ - test_state->check_point = check_point_allocated_blocks(); + /* Run setup */ + if (test_state->test->setup_func != NULL) { + /* Setup the memory check point, it will be evaluated on teardown */ + test_state->check_point = check_point_allocated_blocks(); - rc = cmocka_run_one_test_or_fixture(test_state->test->name, - NULL, - test_state->test->setup_func, - NULL, - &test_state->state, - test_state->check_point); - if (rc != 0) { - test_state->status = CM_TEST_ERROR; - cm_print_error("Test setup failed"); - } + rc = cmocka_run_one_test_or_fixture( + test_state->test->name, + NULL, + test_state->test->setup_func, + NULL, + &test_state->state, + test_state->check_point); + if (rc != 0) { + test_state->status = CM_TEST_ERROR; + cm_print_error("Test setup failed"); } + } - /* Run test */ + /* Run test */ #ifdef HAVE_STRUCT_TIMESPEC - CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &start); + CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &start); #endif + if (rc == 0) { + rc = cmocka_run_one_test_or_fixture( + test_state->test->name, + test_state->test->test_func, + NULL, + NULL, + &test_state->state, + NULL); if (rc == 0) { - rc = cmocka_run_one_test_or_fixture(test_state->test->name, - test_state->test->test_func, - NULL, - NULL, - &test_state->state, - NULL); - if (rc == 0) { - test_state->status = CM_TEST_PASSED; - } else { - if (global_skip_test) { - test_state->status = CM_TEST_SKIPPED; - global_skip_test = 0; /* Do not skip the next test */ - } else { - test_state->status = CM_TEST_FAILED; - } - } - rc = 0; + test_state->status = CM_TEST_PASSED; + } else { + if (global_skip_test) { + test_state->status = CM_TEST_SKIPPED; + global_skip_test = 0; /* Do not skip the next test */ + } else { + test_state->status = CM_TEST_FAILED; + } } + rc = 0; + } - test_state->runtime = 0.0; + test_state->runtime = 0.0; #ifdef HAVE_STRUCT_TIMESPEC - CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &finish); - test_state->runtime = cm_secdiff(finish, start); + CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &finish); + test_state->runtime = cm_secdiff(finish, start); #endif - /* Run teardown */ - if (rc == 0 && test_state->test->teardown_func != NULL) { - rc = cmocka_run_one_test_or_fixture(test_state->test->name, - NULL, - NULL, - test_state->test->teardown_func, - &test_state->state, - test_state->check_point); - if (rc != 0) { - test_state->status = CM_TEST_ERROR; - cm_print_error("Test teardown failed"); - } + /* Run teardown */ + if (rc == 0 && test_state->test->teardown_func != NULL) { + rc = cmocka_run_one_test_or_fixture( + test_state->test->name, + NULL, + NULL, + test_state->test->teardown_func, + &test_state->state, + test_state->check_point); + if (rc != 0) { + test_state->status = CM_TEST_ERROR; + cm_print_error("Test teardown failed"); } + } - test_state->error_message = cm_error_message; - cm_error_message = NULL; + test_state->error_message = cm_error_message; + cm_error_message = NULL; - return rc; + return rc; } -int _cmocka_run_group_tests(const char *group_name, - const struct CMUnitTest * const tests, - const size_t num_tests, - CMFixtureFunction group_setup, - CMFixtureFunction group_teardown) +int _cmocka_run_group_tests( + const char *group_name, + const struct CMUnitTest *const tests, + const size_t num_tests, + CMFixtureFunction group_setup, + CMFixtureFunction group_teardown) { - struct CMUnitTestState *cm_tests; - const ListNode *group_check_point = check_point_allocated_blocks(); - void *group_state = NULL; - size_t total_tests = 0; - size_t total_failed = 0; - size_t total_passed = 0; - size_t total_executed = 0; - size_t total_errors = 0; - size_t total_skipped = 0; - double total_runtime = 0; - size_t i; - int rc; + struct CMUnitTestState *cm_tests; + const ListNode *group_check_point = check_point_allocated_blocks(); + void *group_state = NULL; + size_t total_tests = 0; + size_t total_failed = 0; + size_t total_passed = 0; + size_t total_executed = 0; + size_t total_errors = 0; + size_t total_skipped = 0; + double total_runtime = 0; + size_t i; + int rc; - /* Make sure LargestIntegralType is at least the size of a pointer. */ - assert_true(sizeof(LargestIntegralType) >= sizeof(void*)); + /* Make sure LargestIntegralType is at least the size of a pointer. */ + assert_true(sizeof(LargestIntegralType) >= sizeof(void *)); - cm_tests = libc_calloc(1, sizeof(struct CMUnitTestState) * num_tests); - if (cm_tests == NULL) { - return -1; - } + cm_tests = libc_calloc(1, sizeof(struct CMUnitTestState) * num_tests); + if (cm_tests == NULL) { + return -1; + } - /* Setup cmocka test array */ - for (i = 0; i < num_tests; i++) { - if (tests[i].name != NULL && - (tests[i].test_func != NULL - || tests[i].setup_func != NULL - || tests[i].teardown_func != NULL)) { - if (global_test_filter_pattern != NULL) { - int match; + /* Setup cmocka test array */ + for (i = 0; i < num_tests; i++) { + if (tests[i].name != NULL && + (tests[i].test_func != NULL || tests[i].setup_func != NULL || + tests[i].teardown_func != NULL)) { + if (global_test_filter_pattern != NULL) { + int match; - match = c_strmatch(tests[i].name, global_test_filter_pattern); - if (!match) { - continue; - } - } - if (global_skip_filter_pattern != NULL) { - int match; - - match = c_strmatch(tests[i].name, global_skip_filter_pattern); - if (match) { - continue; - } - } - cm_tests[total_tests] = (struct CMUnitTestState) { - .test = &tests[i], - .status = CM_TEST_NOT_STARTED, - .state = NULL, - }; - total_tests++; + match = c_strmatch(tests[i].name, global_test_filter_pattern); + if (!match) { + continue; } - } + } + if (global_skip_filter_pattern != NULL) { + int match; - cmprintf_group_start(total_tests); - - rc = 0; - - /* Run group setup */ - if (group_setup != NULL) { - rc = cmocka_run_group_fixture("cmocka_group_setup", - group_setup, - NULL, - &group_state, - group_check_point); - } - - if (rc == 0) { - /* Execute tests */ - for (i = 0; i < total_tests; i++) { - struct CMUnitTestState *cmtest = &cm_tests[i]; - size_t test_number = i + 1; - - cmprintf(PRINTF_TEST_START, test_number, cmtest->test->name, NULL); - - if (group_state != NULL) { - cmtest->state = group_state; - } else if (cmtest->test->initial_state != NULL) { - cmtest->state = cmtest->test->initial_state; - } - - rc = cmocka_run_one_tests(cmtest); - total_executed++; - total_runtime += cmtest->runtime; - if (rc == 0) { - switch (cmtest->status) { - case CM_TEST_PASSED: - cmprintf(PRINTF_TEST_SUCCESS, - test_number, - cmtest->test->name, - cmtest->error_message); - total_passed++; - break; - case CM_TEST_SKIPPED: - cmprintf(PRINTF_TEST_SKIPPED, - test_number, - cmtest->test->name, - cmtest->error_message); - total_skipped++; - break; - case CM_TEST_FAILED: - cmprintf(PRINTF_TEST_FAILURE, - test_number, - cmtest->test->name, - cmtest->error_message); - total_failed++; - break; - default: - cmprintf(PRINTF_TEST_ERROR, - test_number, - cmtest->test->name, - "Internal cmocka error"); - total_errors++; - break; - } - } else { - char err_msg[2048] = {0}; - - snprintf(err_msg, sizeof(err_msg), - "Could not run test: %s", - cmtest->error_message); - - cmprintf(PRINTF_TEST_ERROR, - test_number, - cmtest->test->name, - err_msg); - total_errors++; - } + match = c_strmatch(tests[i].name, global_skip_filter_pattern); + if (match) { + continue; } - } else { - if (cm_error_message != NULL) { - print_error("[ ERROR ] --- %s\n", cm_error_message); - vcm_free_error(cm_error_message); - cm_error_message = NULL; - } - cmprintf(PRINTF_TEST_ERROR, 0, - group_name, "[ FAILED ] GROUP SETUP"); - total_errors++; + } + cm_tests[total_tests] = (struct CMUnitTestState){ + .test = &tests[i], + .status = CM_TEST_NOT_STARTED, + .state = NULL, + }; + total_tests++; } + } - /* Run group teardown */ - if (group_teardown != NULL) { - rc = cmocka_run_group_fixture("cmocka_group_teardown", - NULL, - group_teardown, - &group_state, - group_check_point); - if (rc != 0) { - if (cm_error_message != NULL) { - print_error("[ ERROR ] --- %s\n", cm_error_message); - vcm_free_error(cm_error_message); - cm_error_message = NULL; - } - cmprintf(PRINTF_TEST_ERROR, 0, - group_name, "[ FAILED ] GROUP TEARDOWN"); - } - } + cmprintf_group_start(total_tests); - cmprintf_group_finish(group_name, - total_executed, - total_passed, - total_failed, - total_errors, - total_skipped, - total_runtime, - cm_tests); + rc = 0; + /* Run group setup */ + if (group_setup != NULL) { + rc = cmocka_run_group_fixture( + "cmocka_group_setup", + group_setup, + NULL, + &group_state, + group_check_point); + } + + if (rc == 0) { + /* Execute tests */ for (i = 0; i < total_tests; i++) { - vcm_free_error(discard_const_p(char, cm_tests[i].error_message)); - } - libc_free(cm_tests); - fail_if_blocks_allocated(group_check_point, "cmocka_group_tests"); + struct CMUnitTestState *cmtest = &cm_tests[i]; + size_t test_number = i + 1; - return total_failed + total_errors; + cmprintf(PRINTF_TEST_START, test_number, cmtest->test->name, NULL); + + if (group_state != NULL) { + cmtest->state = group_state; + } else if (cmtest->test->initial_state != NULL) { + cmtest->state = cmtest->test->initial_state; + } + + rc = cmocka_run_one_tests(cmtest); + total_executed++; + total_runtime += cmtest->runtime; + if (rc == 0) { + switch (cmtest->status) { + case CM_TEST_PASSED: + cmprintf( + PRINTF_TEST_SUCCESS, + test_number, + cmtest->test->name, + cmtest->error_message); + total_passed++; + break; + case CM_TEST_SKIPPED: + cmprintf( + PRINTF_TEST_SKIPPED, + test_number, + cmtest->test->name, + cmtest->error_message); + total_skipped++; + break; + case CM_TEST_FAILED: + cmprintf( + PRINTF_TEST_FAILURE, + test_number, + cmtest->test->name, + cmtest->error_message); + total_failed++; + break; + default: + cmprintf( + PRINTF_TEST_ERROR, + test_number, + cmtest->test->name, + "Internal cmocka error"); + total_errors++; + break; + } + } else { + char err_msg[2048] = {0}; + + snprintf( + err_msg, + sizeof(err_msg), + "Could not run test: %s", + cmtest->error_message); + + cmprintf(PRINTF_TEST_ERROR, test_number, cmtest->test->name, err_msg); + total_errors++; + } + } + } else { + if (cm_error_message != NULL) { + print_error("[ ERROR ] --- %s\n", cm_error_message); + vcm_free_error(cm_error_message); + cm_error_message = NULL; + } + cmprintf(PRINTF_TEST_ERROR, 0, group_name, "[ FAILED ] GROUP SETUP"); + total_errors++; + } + + /* Run group teardown */ + if (group_teardown != NULL) { + rc = cmocka_run_group_fixture( + "cmocka_group_teardown", + NULL, + group_teardown, + &group_state, + group_check_point); + if (rc != 0) { + if (cm_error_message != NULL) { + print_error("[ ERROR ] --- %s\n", cm_error_message); + vcm_free_error(cm_error_message); + cm_error_message = NULL; + } + cmprintf(PRINTF_TEST_ERROR, 0, group_name, "[ FAILED ] GROUP TEARDOWN"); + } + } + + cmprintf_group_finish( + group_name, + total_executed, + total_passed, + total_failed, + total_errors, + total_skipped, + total_runtime, + cm_tests); + + for (i = 0; i < total_tests; i++) { + vcm_free_error(discard_const_p(char, cm_tests[i].error_message)); + } + libc_free(cm_tests); + fail_if_blocks_allocated(group_check_point, "cmocka_group_tests"); + + return total_failed + total_errors; } /**************************************************************************** @@ -3135,388 +3388,405 @@ int _cmocka_run_group_tests(const char *group_name, ****************************************************************************/ int _run_test( - const char * const function_name, const UnitTestFunction Function, - void ** const volatile state, const UnitTestFunctionType function_type, - const void* const heap_check_point) { - const ListNode * const volatile check_point = (const ListNode*) - (heap_check_point ? - heap_check_point : check_point_allocated_blocks()); - void *current_state = NULL; - volatile int rc = 1; - int handle_exceptions = 1; + const char *const function_name, + const UnitTestFunction Function, + void **const volatile state, + const UnitTestFunctionType function_type, + const void *const heap_check_point) +{ + const ListNode *const volatile check_point = + (const ListNode + *) (heap_check_point ? heap_check_point : check_point_allocated_blocks()); + void *current_state = NULL; + volatile int rc = 1; + int handle_exceptions = 1; #ifdef _WIN32 - handle_exceptions = !IsDebuggerPresent(); + handle_exceptions = !IsDebuggerPresent(); #endif /* _WIN32 */ #ifdef UNIT_TESTING_DEBUG - handle_exceptions = 0; + handle_exceptions = 0; #endif /* UNIT_TESTING_DEBUG */ - cm_error_message_enabled = 0; + cm_error_message_enabled = 0; - if (handle_exceptions) { + if (handle_exceptions) { #ifndef _WIN32 - unsigned int i; - for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { - default_signal_functions[i] = signal( - exception_signals[i], exception_handler); - } -#else /* _WIN32 */ - previous_exception_filter = SetUnhandledExceptionFilter( - exception_filter); -#endif /* !_WIN32 */ + unsigned int i; + for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { + default_signal_functions[i] = + signal(exception_signals[i], exception_handler); } +#else /* _WIN32 */ + previous_exception_filter = SetUnhandledExceptionFilter(exception_filter); +#endif /* !_WIN32 */ + } + + if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) { + print_message("[ RUN ] %s\n", function_name); + } + initialize_testing(function_name); + global_running_test = 1; + if (cm_setjmp(global_run_test_env) == 0) { + Function(state ? state : ¤t_state); + fail_if_leftover_values(function_name); + + /* If this is a setup function then ignore any allocated blocks + * only ensure they're deallocated on tear down. */ + if (function_type != UNIT_TEST_FUNCTION_TYPE_SETUP) { + fail_if_blocks_allocated(check_point, function_name); + } + + global_running_test = 0; if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) { - print_message("[ RUN ] %s\n", function_name); + print_message("[ OK ] %s\n", function_name); } - initialize_testing(function_name); - global_running_test = 1; - if (cm_setjmp(global_run_test_env) == 0) { - Function(state ? state : ¤t_state); - fail_if_leftover_values(function_name); + rc = 0; + } else { + global_running_test = 0; + print_message("[ FAILED ] %s\n", function_name); + } + teardown_testing(function_name); - /* If this is a setup function then ignore any allocated blocks - * only ensure they're deallocated on tear down. */ - if (function_type != UNIT_TEST_FUNCTION_TYPE_SETUP) { - fail_if_blocks_allocated(check_point, function_name); - } - - global_running_test = 0; - - if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) { - print_message("[ OK ] %s\n", function_name); - } - rc = 0; - } else { - global_running_test = 0; - print_message("[ FAILED ] %s\n", function_name); - } - teardown_testing(function_name); - - if (handle_exceptions) { + if (handle_exceptions) { #ifndef _WIN32 - unsigned int i; - for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { - signal(exception_signals[i], default_signal_functions[i]); - } + unsigned int i; + for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { + signal(exception_signals[i], default_signal_functions[i]); + } #else /* _WIN32 */ - if (previous_exception_filter) { - SetUnhandledExceptionFilter(previous_exception_filter); - previous_exception_filter = NULL; - } + if (previous_exception_filter) { + SetUnhandledExceptionFilter(previous_exception_filter); + previous_exception_filter = NULL; + } #endif /* !_WIN32 */ - } + } - return rc; + return rc; } - -int _run_tests(const UnitTest * const tests, const size_t number_of_tests) { - /* Whether to execute the next test. */ - int run_next_test = 1; - /* Whether the previous test failed. */ - int previous_test_failed = 0; - /* Whether the previous setup failed. */ - int previous_setup_failed = 0; - /* Check point of the heap state. */ - const ListNode * const check_point = check_point_allocated_blocks(); - /* Current test being executed. */ - size_t current_test = 0; - /* Number of tests executed. */ - size_t tests_executed = 0; - /* Number of failed tests. */ - size_t total_failed = 0; - /* Number of setup functions. */ - size_t setups = 0; - /* Number of teardown functions. */ - size_t teardowns = 0; - size_t i; - /* - * A stack of test states. A state is pushed on the stack - * when a test setup occurs and popped on tear down. - */ - TestState* test_states = - (TestState*)malloc(number_of_tests * sizeof(*test_states)); - /* The number of test states which should be 0 at the end */ - long number_of_test_states = 0; - /* Names of the tests that failed. */ - const char** failed_names = (const char**)malloc(number_of_tests * - sizeof(*failed_names)); - void **current_state = NULL; - - /* Count setup and teardown functions */ - for (i = 0; i < number_of_tests; i++) { - const UnitTest * const test = &tests[i]; - - if (test->function_type == UNIT_TEST_FUNCTION_TYPE_SETUP) { - setups++; - } - - if (test->function_type == UNIT_TEST_FUNCTION_TYPE_TEARDOWN) { - teardowns++; - } - } - - print_message("[==========] Running %"PRIdS " test(s).\n", - number_of_tests - setups - teardowns); - - /* Make sure LargestIntegralType is at least the size of a pointer. */ - assert_true(sizeof(LargestIntegralType) >= sizeof(void*)); - - while (current_test < number_of_tests) { - const ListNode *test_check_point = NULL; - TestState *current_TestState; - const UnitTest * const test = &tests[current_test++]; - if (!test->function) { - continue; - } - - switch (test->function_type) { - case UNIT_TEST_FUNCTION_TYPE_TEST: - if (! previous_setup_failed) { - run_next_test = 1; - } - break; - case UNIT_TEST_FUNCTION_TYPE_SETUP: { - /* Checkpoint the heap before the setup. */ - current_TestState = &test_states[number_of_test_states++]; - current_TestState->check_point = check_point_allocated_blocks(); - test_check_point = current_TestState->check_point; - current_state = ¤t_TestState->state; - *current_state = NULL; - run_next_test = 1; - break; - } - case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: - /* Check the heap based on the last setup checkpoint. */ - assert_true(number_of_test_states); - current_TestState = &test_states[--number_of_test_states]; - test_check_point = current_TestState->check_point; - current_state = ¤t_TestState->state; - break; - default: - print_error("Invalid unit test function type %d\n", - test->function_type); - exit_test(1); - break; - } - - if (run_next_test) { - int failed = _run_test(test->name, test->function, current_state, - test->function_type, test_check_point); - if (failed) { - failed_names[total_failed] = test->name; - } - - switch (test->function_type) { - case UNIT_TEST_FUNCTION_TYPE_TEST: - previous_test_failed = failed; - total_failed += failed; - tests_executed ++; - break; - - case UNIT_TEST_FUNCTION_TYPE_SETUP: - if (failed) { - total_failed ++; - tests_executed ++; - /* Skip forward until the next test or setup function. */ - run_next_test = 0; - previous_setup_failed = 1; - } - previous_test_failed = 0; - break; - - case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: - /* If this test failed. */ - if (failed && !previous_test_failed) { - total_failed ++; - } - break; - default: -#ifndef _HPUX - assert_null("BUG: shouldn't be here!"); -#endif - break; - } - } - } - - print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed); - print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed); - - if (total_failed > 0) { - print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed); - for (i = 0; i < total_failed; i++) { - print_error("[ FAILED ] %s\n", failed_names[i]); - } - } else { - print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed); - } - - if (number_of_test_states != 0) { - print_error("[ ERROR ] Mismatched number of setup %"PRIdS " and " - "teardown %"PRIdS " functions\n", setups, teardowns); - total_failed = (size_t)-1; - } - - free(test_states); - free((void*)failed_names); - - fail_if_blocks_allocated(check_point, "run_tests"); - return (int)total_failed; -} - -int _run_group_tests(const UnitTest * const tests, const size_t number_of_tests) +int _run_tests(const UnitTest *const tests, const size_t number_of_tests) { - UnitTestFunction setup = NULL; - const char *setup_name; - size_t num_setups = 0; - UnitTestFunction teardown = NULL; - const char *teardown_name = NULL; - size_t num_teardowns = 0; - size_t current_test = 0; - size_t i; + /* Whether to execute the next test. */ + int run_next_test = 1; + /* Whether the previous test failed. */ + int previous_test_failed = 0; + /* Whether the previous setup failed. */ + int previous_setup_failed = 0; + /* Check point of the heap state. */ + const ListNode *const check_point = check_point_allocated_blocks(); + /* Current test being executed. */ + size_t current_test = 0; + /* Number of tests executed. */ + size_t tests_executed = 0; + /* Number of failed tests. */ + size_t total_failed = 0; + /* Number of setup functions. */ + size_t setups = 0; + /* Number of teardown functions. */ + size_t teardowns = 0; + size_t i; + /* + * A stack of test states. A state is pushed on the stack + * when a test setup occurs and popped on tear down. + */ + TestState *test_states = + (TestState *) malloc(number_of_tests * sizeof(*test_states)); + /* The number of test states which should be 0 at the end */ + long number_of_test_states = 0; + /* Names of the tests that failed. */ + const char **failed_names = + (const char **) malloc(number_of_tests * sizeof(*failed_names)); + void **current_state = NULL; - /* Number of tests executed. */ - size_t tests_executed = 0; - /* Number of failed tests. */ - size_t total_failed = 0; - /* Check point of the heap state. */ - const ListNode * const check_point = check_point_allocated_blocks(); - const char **failed_names = NULL; - void **current_state = NULL; - TestState group_state = { - .check_point = NULL, - }; + /* Count setup and teardown functions */ + for (i = 0; i < number_of_tests; i++) { + const UnitTest *const test = &tests[i]; - if (number_of_tests == 0) { - return -1; + if (test->function_type == UNIT_TEST_FUNCTION_TYPE_SETUP) { + setups++; } - failed_names = (const char **)malloc(number_of_tests * - sizeof(*failed_names)); - if (failed_names == NULL) { - return -2; + if (test->function_type == UNIT_TEST_FUNCTION_TYPE_TEARDOWN) { + teardowns++; + } + } + + print_message( + "[==========] Running %" PRIdS " test(s).\n", + number_of_tests - setups - teardowns); + + /* Make sure LargestIntegralType is at least the size of a pointer. */ + assert_true(sizeof(LargestIntegralType) >= sizeof(void *)); + + while (current_test < number_of_tests) { + const ListNode *test_check_point = NULL; + TestState *current_TestState; + const UnitTest *const test = &tests[current_test++]; + if (!test->function) { + continue; } - /* Find setup and teardown function */ - for (i = 0; i < number_of_tests; i++) { - const UnitTest * const test = &tests[i]; - - if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP) { - if (setup == NULL) { - setup = test->function; - setup_name = test->name; - num_setups = 1; - } else { - print_error("[ ERROR ] More than one group setup function detected\n"); - exit_test(1); - } + switch (test->function_type) { + case UNIT_TEST_FUNCTION_TYPE_TEST: + if (!previous_setup_failed) { + run_next_test = 1; } - - if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN) { - if (teardown == NULL) { - teardown = test->function; - teardown_name = test->name; - num_teardowns = 1; - } else { - print_error("[ ERROR ] More than one group teardown function detected\n"); - exit_test(1); - } - } - } - - print_message("[==========] Running %"PRIdS " test(s).\n", - number_of_tests - num_setups - num_teardowns); - - if (setup != NULL) { - int failed; - - group_state.check_point = check_point_allocated_blocks(); - current_state = &group_state.state; + break; + case UNIT_TEST_FUNCTION_TYPE_SETUP: { + /* Checkpoint the heap before the setup. */ + current_TestState = &test_states[number_of_test_states++]; + current_TestState->check_point = check_point_allocated_blocks(); + test_check_point = current_TestState->check_point; + current_state = ¤t_TestState->state; *current_state = NULL; - failed = _run_test(setup_name, - setup, - current_state, - UNIT_TEST_FUNCTION_TYPE_SETUP, - group_state.check_point); - if (failed) { - failed_names[total_failed] = setup_name; - } - - total_failed += failed; - tests_executed++; + run_next_test = 1; + break; + } + case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: + /* Check the heap based on the last setup checkpoint. */ + assert_true(number_of_test_states); + current_TestState = &test_states[--number_of_test_states]; + test_check_point = current_TestState->check_point; + current_state = ¤t_TestState->state; + break; + default: + print_error( + "Invalid unit test function type %d\n", test->function_type); + exit_test(1); + break; } - while (current_test < number_of_tests) { - int run_test = 0; - const UnitTest * const test = &tests[current_test++]; - if (test->function == NULL) { - continue; - } + if (run_next_test) { + int failed = _run_test( + test->name, + test->function, + current_state, + test->function_type, + test_check_point); + if (failed) { + failed_names[total_failed] = test->name; + } - switch (test->function_type) { + switch (test->function_type) { case UNIT_TEST_FUNCTION_TYPE_TEST: - run_test = 1; - break; + previous_test_failed = failed; + total_failed += failed; + tests_executed++; + break; + case UNIT_TEST_FUNCTION_TYPE_SETUP: - case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: - case UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP: - case UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN: - break; - default: - print_error("Invalid unit test function type %d\n", - test->function_type); - break; - } - - if (run_test) { - int failed; - - failed = _run_test(test->name, - test->function, - current_state, - test->function_type, - NULL); - if (failed) { - failed_names[total_failed] = test->name; - } - - total_failed += failed; + if (failed) { + total_failed++; tests_executed++; - } + /* Skip forward until the next test or setup function. */ + run_next_test = 0; + previous_setup_failed = 1; + } + previous_test_failed = 0; + break; + + case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: + /* If this test failed. */ + if (failed && !previous_test_failed) { + total_failed++; + } + break; + default: +#ifndef _HPUX + assert_null("BUG: shouldn't be here!"); +#endif + break; + } } + } - if (teardown != NULL) { - int failed; + print_message("[==========] %" PRIdS " test(s) run.\n", tests_executed); + print_error( + "[ PASSED ] %" PRIdS " test(s).\n", tests_executed - total_failed); - failed = _run_test(teardown_name, - teardown, - current_state, - UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN, - group_state.check_point); - if (failed) { - failed_names[total_failed] = teardown_name; - } - - total_failed += failed; - tests_executed++; + if (total_failed > 0) { + print_error( + "[ FAILED ] %" PRIdS " test(s), listed below:\n", total_failed); + for (i = 0; i < total_failed; i++) { + print_error("[ FAILED ] %s\n", failed_names[i]); } + } else { + print_error("\n %" PRIdS " FAILED TEST(S)\n", total_failed); + } - print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed); - print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed); + if (number_of_test_states != 0) { + print_error( + "[ ERROR ] Mismatched number of setup %" PRIdS + " and " + "teardown %" PRIdS " functions\n", + setups, + teardowns); + total_failed = (size_t) -1; + } - if (total_failed) { - print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed); - for (i = 0; i < total_failed; i++) { - print_error("[ FAILED ] %s\n", failed_names[i]); - } - } else { - print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed); - } + free(test_states); + free((void *) failed_names); - free((void*)failed_names); - fail_if_blocks_allocated(check_point, "run_group_tests"); + fail_if_blocks_allocated(check_point, "run_tests"); + return (int) total_failed; +} - return (int)total_failed; +int _run_group_tests(const UnitTest *const tests, const size_t number_of_tests) +{ + UnitTestFunction setup = NULL; + const char *setup_name; + size_t num_setups = 0; + UnitTestFunction teardown = NULL; + const char *teardown_name = NULL; + size_t num_teardowns = 0; + size_t current_test = 0; + size_t i; + + /* Number of tests executed. */ + size_t tests_executed = 0; + /* Number of failed tests. */ + size_t total_failed = 0; + /* Check point of the heap state. */ + const ListNode *const check_point = check_point_allocated_blocks(); + const char **failed_names = NULL; + void **current_state = NULL; + TestState group_state = { + .check_point = NULL, + }; + + if (number_of_tests == 0) { + return -1; + } + + failed_names = + (const char **) malloc(number_of_tests * sizeof(*failed_names)); + if (failed_names == NULL) { + return -2; + } + + /* Find setup and teardown function */ + for (i = 0; i < number_of_tests; i++) { + const UnitTest *const test = &tests[i]; + + if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP) { + if (setup == NULL) { + setup = test->function; + setup_name = test->name; + num_setups = 1; + } else { + print_error( + "[ ERROR ] More than one group setup function detected\n"); + exit_test(1); + } + } + + if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN) { + if (teardown == NULL) { + teardown = test->function; + teardown_name = test->name; + num_teardowns = 1; + } else { + print_error( + "[ ERROR ] More than one group teardown function detected\n"); + exit_test(1); + } + } + } + + print_message( + "[==========] Running %" PRIdS " test(s).\n", + number_of_tests - num_setups - num_teardowns); + + if (setup != NULL) { + int failed; + + group_state.check_point = check_point_allocated_blocks(); + current_state = &group_state.state; + *current_state = NULL; + failed = _run_test( + setup_name, + setup, + current_state, + UNIT_TEST_FUNCTION_TYPE_SETUP, + group_state.check_point); + if (failed) { + failed_names[total_failed] = setup_name; + } + + total_failed += failed; + tests_executed++; + } + + while (current_test < number_of_tests) { + int run_test = 0; + const UnitTest *const test = &tests[current_test++]; + if (test->function == NULL) { + continue; + } + + switch (test->function_type) { + case UNIT_TEST_FUNCTION_TYPE_TEST: + run_test = 1; + break; + case UNIT_TEST_FUNCTION_TYPE_SETUP: + case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: + case UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP: + case UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN: + break; + default: + print_error( + "Invalid unit test function type %d\n", test->function_type); + break; + } + + if (run_test) { + int failed; + + failed = _run_test( + test->name, test->function, current_state, test->function_type, NULL); + if (failed) { + failed_names[total_failed] = test->name; + } + + total_failed += failed; + tests_executed++; + } + } + + if (teardown != NULL) { + int failed; + + failed = _run_test( + teardown_name, + teardown, + current_state, + UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN, + group_state.check_point); + if (failed) { + failed_names[total_failed] = teardown_name; + } + + total_failed += failed; + tests_executed++; + } + + print_message("[==========] %" PRIdS " test(s) run.\n", tests_executed); + print_error( + "[ PASSED ] %" PRIdS " test(s).\n", tests_executed - total_failed); + + if (total_failed) { + print_error( + "[ FAILED ] %" PRIdS " test(s), listed below:\n", total_failed); + for (i = 0; i < total_failed; i++) { + print_error("[ FAILED ] %s\n", failed_names[i]); + } + } else { + print_error("\n %" PRIdS " FAILED TEST(S)\n", total_failed); + } + + free((void *) failed_names); + fail_if_blocks_allocated(check_point, "run_group_tests"); + + return (int) total_failed; } diff --git a/src/imports/cmocka/cmocka.h b/src/imports/cmocka/cmocka.h index 5dd6d62..4d2f4f9 100644 --- a/src/imports/cmocka/cmocka.h +++ b/src/imports/cmocka/cmocka.h @@ -17,31 +17,31 @@ #ifndef CMOCKA_H_ #define CMOCKA_H_ +#include #include #include -#include #include #ifdef _WIN32 -# ifdef _MSC_VER +#ifdef _MSC_VER #define __func__ __FUNCTION__ -# ifndef inline +#ifndef inline #define inline __inline -# endif /* inline */ +#endif /* inline */ -# if _MSC_VER < 1500 -# ifdef __cplusplus +#if _MSC_VER < 1500 +#ifdef __cplusplus extern "C" { -# endif /* __cplusplus */ +#endif /* __cplusplus */ int __stdcall IsDebuggerPresent(); -# ifdef __cplusplus +#ifdef __cplusplus } /* extern "C" */ -# endif /* __cplusplus */ -# endif /* _MSC_VER < 1500 */ -# endif /* _MSC_VER */ -#endif /* _WIN32 */ +#endif /* __cplusplus */ +#endif /* _MSC_VER < 1500 */ +#endif /* _MSC_VER */ +#endif /* _WIN32 */ /** * @defgroup cmocka The CMocka API @@ -63,11 +63,12 @@ int __stdcall IsDebuggerPresent(); /* If __WORDSIZE is not set, try to figure it out and default to 32 bit. */ #ifndef __WORDSIZE -# if (defined(__x86_64__) && !defined(__ILP32__)) || defined(__sparc_v9__) || defined(__sparcv9) -# define __WORDSIZE 64 -# else -# define __WORDSIZE 32 -# endif +#if (defined(__x86_64__) && !defined(__ILP32__)) || defined(__sparc_v9__) || \ + defined(__sparcv9) +#define __WORDSIZE 64 +#else +#define __WORDSIZE 32 +#endif #endif #ifdef DOXYGEN @@ -78,95 +79,93 @@ int __stdcall IsDebuggerPresent(); typedef uintmax_t LargestIntegralType; #else /* DOXGEN */ #ifndef LargestIntegralType -# if __WORDSIZE == 64 && !defined(_WIN64) -# define LargestIntegralType unsigned long int -# else -# define LargestIntegralType unsigned long long int -# endif +#if __WORDSIZE == 64 && !defined(_WIN64) +#define LargestIntegralType unsigned long int +#else +#define LargestIntegralType unsigned long long int +#endif #endif /* LargestIntegralType */ #endif /* DOXYGEN */ /* Printf format used to display LargestIntegralType as a hexidecimal. */ #ifndef LargestIntegralTypePrintfFormat -# ifdef _WIN32 -# define LargestIntegralTypePrintfFormat "0x%I64x" -# else -# if __WORDSIZE == 64 -# define LargestIntegralTypePrintfFormat "%#lx" -# else -# define LargestIntegralTypePrintfFormat "%#llx" -# endif -# endif /* _WIN32 */ +#ifdef _WIN32 +#define LargestIntegralTypePrintfFormat "0x%I64x" +#else +#if __WORDSIZE == 64 +#define LargestIntegralTypePrintfFormat "%#lx" +#else +#define LargestIntegralTypePrintfFormat "%#llx" +#endif +#endif /* _WIN32 */ #endif /* LargestIntegralTypePrintfFormat */ /* Printf format used to display LargestIntegralType as a decimal. */ #ifndef LargestIntegralTypePrintfFormatDecimal -# ifdef _WIN32 -# define LargestIntegralTypePrintfFormatDecimal "%I64u" -# else -# if __WORDSIZE == 64 -# define LargestIntegralTypePrintfFormatDecimal "%lu" -# else -# define LargestIntegralTypePrintfFormatDecimal "%llu" -# endif -# endif /* _WIN32 */ +#ifdef _WIN32 +#define LargestIntegralTypePrintfFormatDecimal "%I64u" +#else +#if __WORDSIZE == 64 +#define LargestIntegralTypePrintfFormatDecimal "%lu" +#else +#define LargestIntegralTypePrintfFormatDecimal "%llu" +#endif +#endif /* _WIN32 */ #endif /* LargestIntegralTypePrintfFormat */ #ifndef FloatPrintfFormat -# define FloatPrintfFormat "%f" +#define FloatPrintfFormat "%f" #endif /* FloatPrintfFormat */ /* Perform an unsigned cast to LargestIntegralType. */ -#define cast_to_largest_integral_type(value) \ - ((LargestIntegralType)(value)) +#define cast_to_largest_integral_type(value) ((LargestIntegralType)(value)) /* Smallest integral type capable of holding a pointer. */ #if !defined(_UINTPTR_T) && !defined(_UINTPTR_T_DEFINED) -# if defined(_WIN32) - /* WIN32 is an ILP32 platform */ - typedef unsigned int uintptr_t; -# elif defined(_WIN64) - typedef unsigned long int uintptr_t; -# else /* _WIN32 */ +#if defined(_WIN32) +/* WIN32 is an ILP32 platform */ +typedef unsigned int uintptr_t; +#elif defined(_WIN64) +typedef unsigned long int uintptr_t; +#else /* _WIN32 */ /* ILP32 and LP64 platforms */ -# ifdef __WORDSIZE /* glibc */ -# if __WORDSIZE == 64 - typedef unsigned long int uintptr_t; -# else - typedef unsigned int uintptr_t; -# endif /* __WORDSIZE == 64 */ -# else /* __WORDSIZE */ -# if defined(_LP64) || defined(_I32LPx) - typedef unsigned long int uintptr_t; -# else - typedef unsigned int uintptr_t; -# endif -# endif /* __WORDSIZE */ -# endif /* _WIN32 */ +#ifdef __WORDSIZE /* glibc */ +#if __WORDSIZE == 64 +typedef unsigned long int uintptr_t; +#else +typedef unsigned int uintptr_t; +#endif /* __WORDSIZE == 64 */ +#else /* __WORDSIZE */ +#if defined(_LP64) || defined(_I32LPx) +typedef unsigned long int uintptr_t; +#else +typedef unsigned int uintptr_t; +#endif +#endif /* __WORDSIZE */ +#endif /* _WIN32 */ -# define _UINTPTR_T -# define _UINTPTR_T_DEFINED +#define _UINTPTR_T +#define _UINTPTR_T_DEFINED #endif /* !defined(_UINTPTR_T) || !defined(_UINTPTR_T_DEFINED) */ /* Perform an unsigned cast to uintptr_t. */ -#define cast_to_pointer_integral_type(value) \ - ((uintptr_t)((size_t)(value))) +#define cast_to_pointer_integral_type(value) ((uintptr_t)((size_t)(value))) /* Perform a cast of a pointer to LargestIntegralType */ #define cast_ptr_to_largest_integral_type(value) \ -cast_to_largest_integral_type(cast_to_pointer_integral_type(value)) + cast_to_largest_integral_type(cast_to_pointer_integral_type(value)) /* GCC have printf type attribute check. */ #ifdef __GNUC__ -#define CMOCKA_PRINTF_ATTRIBUTE(a,b) \ - __attribute__ ((__format__ (__printf__, a, b))) +#define CMOCKA_PRINTF_ATTRIBUTE(a, b) \ + __attribute__((__format__(__printf__, a, b))) #else -#define CMOCKA_PRINTF_ATTRIBUTE(a,b) +#define CMOCKA_PRINTF_ATTRIBUTE(a, b) #endif /* __GNUC__ */ #if defined(__GNUC__) -#define CMOCKA_DEPRECATED __attribute__ ((deprecated)) +#define CMOCKA_DEPRECATED __attribute__((deprecated)) #elif defined(_MSC_VER) #define CMOCKA_DEPRECATED __declspec(deprecated) #else @@ -219,7 +218,8 @@ cast_to_largest_integral_type(cast_to_pointer_integral_type(value)) * @endcode * * For a complete example please take a look - * here. + * here. * * @{ */ @@ -287,10 +287,9 @@ LargestIntegralType mock(void); */ type mock_ptr_type(#type); #else -#define mock_ptr_type(type) ((type) (uintptr_t) mock()) +#define mock_ptr_type(type) ((type)(uintptr_t) mock()) #endif - #ifdef DOXYGEN /** * @brief Store a value to be returned by mock() later. @@ -319,8 +318,8 @@ type mock_ptr_type(#type); void will_return(#function, LargestIntegralType value); #else #define will_return(function, value) \ - _will_return(#function, __FILE__, __LINE__, \ - cast_to_largest_integral_type(value), 1) + _will_return( \ + #function, __FILE__, __LINE__, cast_to_largest_integral_type(value), 1) #endif #ifdef DOXYGEN @@ -331,19 +330,22 @@ void will_return(#function, LargestIntegralType value); * * @param[in] value The value to be returned by mock(). * - * @param[in] count The parameter indicates the number of times the value should - * be returned by mock(). If count is set to -1, the value - * will always be returned but must be returned at least once. - * If count is set to -2, the value will always be returned - * by mock(), but is not required to be returned. + * @param[in] count The parameter indicates the number of times the value + * should be returned by mock(). If count is set to -1, the value will always be + * returned but must be returned at least once. If count is set to -2, the value + * will always be returned by mock(), but is not required to be returned. * * @see mock() */ void will_return_count(#function, LargestIntegralType value, int count); #else #define will_return_count(function, value, count) \ - _will_return(#function, __FILE__, __LINE__, \ - cast_to_largest_integral_type(value), count) + _will_return( \ + #function, \ + __FILE__, \ + __LINE__, \ + cast_to_largest_integral_type(value), \ + count) #endif #ifdef DOXYGEN @@ -365,7 +367,7 @@ void will_return_count(#function, LargestIntegralType value, int count); void will_return_always(#function, LargestIntegralType value); #else #define will_return_always(function, value) \ - will_return_count(function, (value), WILL_RETURN_ALWAYS) + will_return_count(function, (value), WILL_RETURN_ALWAYS) #endif #ifdef DOXYGEN @@ -393,7 +395,7 @@ void will_return_always(#function, LargestIntegralType value); void will_return_maybe(#function, LargestIntegralType value); #else #define will_return_maybe(function, value) \ - will_return_count(function, (value), WILL_RETURN_ONCE) + will_return_count(function, (value), WILL_RETURN_ONCE) #endif /** @} */ @@ -436,7 +438,8 @@ void will_return_maybe(#function, LargestIntegralType value); * @endcode * * For a complete example please take a look - * here + * here * * @{ */ @@ -464,11 +467,19 @@ void will_return_maybe(#function, LargestIntegralType value); * * @param[in] check_data The data to pass to the check function. */ -void expect_check(#function, #parameter, #check_function, const void *check_data); +void expect_check( + #function, #parameter, #check_function, const void *check_data); #else #define expect_check(function, parameter, check_function, check_data) \ - _expect_check(#function, #parameter, __FILE__, __LINE__, check_function, \ - cast_to_largest_integral_type(check_data), NULL, 1) + _expect_check( \ + #function, \ + #parameter, \ + __FILE__, \ + __LINE__, \ + check_function, \ + cast_to_largest_integral_type(check_data), \ + NULL, \ + 1) #endif #ifdef DOXYGEN @@ -489,7 +500,7 @@ void expect_check(#function, #parameter, #check_function, const void *check_data void expect_in_set(#function, #parameter, LargestIntegralType value_array[]); #else #define expect_in_set(function, parameter, value_array) \ - expect_in_set_count(function, parameter, value_array, 1) + expect_in_set_count(function, parameter, value_array, 1) #endif #ifdef DOXYGEN @@ -511,11 +522,18 @@ void expect_in_set(#function, #parameter, LargestIntegralType value_array[]); * * @see check_expected(). */ -void expect_in_set_count(#function, #parameter, LargestIntegralType value_array[], size_t count); +void expect_in_set_count( + #function, #parameter, LargestIntegralType value_array[], size_t count); #else #define expect_in_set_count(function, parameter, value_array, count) \ - _expect_in_set(#function, #parameter, __FILE__, __LINE__, value_array, \ - sizeof(value_array) / sizeof((value_array)[0]), count) + _expect_in_set( \ + #function, \ + #parameter, \ + __FILE__, \ + __LINE__, \ + value_array, \ + sizeof(value_array) / sizeof((value_array)[0]), \ + count) #endif #ifdef DOXYGEN @@ -533,10 +551,11 @@ void expect_in_set_count(#function, #parameter, LargestIntegralType value_array[ * * @see check_expected(). */ -void expect_not_in_set(#function, #parameter, LargestIntegralType value_array[]); +void expect_not_in_set( + #function, #parameter, LargestIntegralType value_array[]); #else #define expect_not_in_set(function, parameter, value_array) \ - expect_not_in_set_count(function, parameter, value_array, 1) + expect_not_in_set_count(function, parameter, value_array, 1) #endif #ifdef DOXYGEN @@ -558,15 +577,20 @@ void expect_not_in_set(#function, #parameter, LargestIntegralType value_array[]) * * @see check_expected(). */ -void expect_not_in_set_count(#function, #parameter, LargestIntegralType value_array[], size_t count); +void expect_not_in_set_count( + #function, #parameter, LargestIntegralType value_array[], size_t count); #else #define expect_not_in_set_count(function, parameter, value_array, count) \ - _expect_not_in_set( \ - #function, #parameter, __FILE__, __LINE__, value_array, \ - sizeof(value_array) / sizeof((value_array)[0]), count) + _expect_not_in_set( \ + #function, \ + #parameter, \ + __FILE__, \ + __LINE__, \ + value_array, \ + sizeof(value_array) / sizeof((value_array)[0]), \ + count) #endif - #ifdef DOXYGEN /** * @brief Add an event to check a parameter is inside a numerical range. @@ -584,10 +608,14 @@ void expect_not_in_set_count(#function, #parameter, LargestIntegralType value_ar * * @see check_expected(). */ -void expect_in_range(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum); +void expect_in_range( + #function, + #parameter, + LargestIntegralType minimum, + LargestIntegralType maximum); #else #define expect_in_range(function, parameter, minimum, maximum) \ - expect_in_range_count(function, parameter, minimum, maximum, 1) + expect_in_range_count(function, parameter, minimum, maximum, 1) #endif #ifdef DOXYGEN @@ -611,11 +639,16 @@ void expect_in_range(#function, #parameter, LargestIntegralType minimum, Largest * * @see check_expected(). */ -void expect_in_range_count(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum, size_t count); +void expect_in_range_count( + #function, + #parameter, + LargestIntegralType minimum, + LargestIntegralType maximum, + size_t count); #else #define expect_in_range_count(function, parameter, minimum, maximum, count) \ - _expect_in_range(#function, #parameter, __FILE__, __LINE__, minimum, \ - maximum, count) + _expect_in_range( \ + #function, #parameter, __FILE__, __LINE__, minimum, maximum, count) #endif #ifdef DOXYGEN @@ -635,10 +668,14 @@ void expect_in_range_count(#function, #parameter, LargestIntegralType minimum, L * * @see check_expected(). */ -void expect_not_in_range(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum); +void expect_not_in_range( + #function, + #parameter, + LargestIntegralType minimum, + LargestIntegralType maximum); #else #define expect_not_in_range(function, parameter, minimum, maximum) \ - expect_not_in_range_count(function, parameter, minimum, maximum, 1) + expect_not_in_range_count(function, parameter, minimum, maximum, 1) #endif #ifdef DOXYGEN @@ -662,12 +699,17 @@ void expect_not_in_range(#function, #parameter, LargestIntegralType minimum, Lar * * @see check_expected(). */ -void expect_not_in_range_count(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum, size_t count); +void expect_not_in_range_count( + #function, + #parameter, + LargestIntegralType minimum, + LargestIntegralType maximum, + size_t count); #else -#define expect_not_in_range_count(function, parameter, minimum, maximum, \ - count) \ - _expect_not_in_range(#function, #parameter, __FILE__, __LINE__, \ - minimum, maximum, count) +#define expect_not_in_range_count( \ + function, parameter, minimum, maximum, count) \ + _expect_not_in_range( \ + #function, #parameter, __FILE__, __LINE__, minimum, maximum, count) #endif #ifdef DOXYGEN @@ -687,7 +729,7 @@ void expect_not_in_range_count(#function, #parameter, LargestIntegralType minimu void expect_value(#function, #parameter, LargestIntegralType value); #else #define expect_value(function, parameter, value) \ - expect_value_count(function, parameter, value, 1) + expect_value_count(function, parameter, value, 1) #endif #ifdef DOXYGEN @@ -708,11 +750,17 @@ void expect_value(#function, #parameter, LargestIntegralType value); * * @see check_expected(). */ -void expect_value_count(#function, #parameter, LargestIntegralType value, size_t count); +void expect_value_count( + #function, #parameter, LargestIntegralType value, size_t count); #else #define expect_value_count(function, parameter, value, count) \ - _expect_value(#function, #parameter, __FILE__, __LINE__, \ - cast_to_largest_integral_type(value), count) + _expect_value( \ + #function, \ + #parameter, \ + __FILE__, \ + __LINE__, \ + cast_to_largest_integral_type(value), \ + count) #endif #ifdef DOXYGEN @@ -732,7 +780,7 @@ void expect_value_count(#function, #parameter, LargestIntegralType value, size_t void expect_not_value(#function, #parameter, LargestIntegralType value); #else #define expect_not_value(function, parameter, value) \ - expect_not_value_count(function, parameter, value, 1) + expect_not_value_count(function, parameter, value, 1) #endif #ifdef DOXYGEN @@ -753,11 +801,17 @@ void expect_not_value(#function, #parameter, LargestIntegralType value); * * @see check_expected(). */ -void expect_not_value_count(#function, #parameter, LargestIntegralType value, size_t count); +void expect_not_value_count( + #function, #parameter, LargestIntegralType value, size_t count); #else #define expect_not_value_count(function, parameter, value, count) \ - _expect_not_value(#function, #parameter, __FILE__, __LINE__, \ - cast_to_largest_integral_type(value), count) + _expect_not_value( \ + #function, \ + #parameter, \ + __FILE__, \ + __LINE__, \ + cast_to_largest_integral_type(value), \ + count) #endif #ifdef DOXYGEN @@ -778,7 +832,7 @@ void expect_not_value_count(#function, #parameter, LargestIntegralType value, si void expect_string(#function, #parameter, const char *string); #else #define expect_string(function, parameter, string) \ - expect_string_count(function, parameter, string, 1) + expect_string_count(function, parameter, string, 1) #endif #ifdef DOXYGEN @@ -800,11 +854,17 @@ void expect_string(#function, #parameter, const char *string); * * @see check_expected(). */ -void expect_string_count(#function, #parameter, const char *string, size_t count); +void expect_string_count( + #function, #parameter, const char *string, size_t count); #else #define expect_string_count(function, parameter, string, count) \ - _expect_string(#function, #parameter, __FILE__, __LINE__, \ - (const char*)(string), count) + _expect_string( \ + #function, \ + #parameter, \ + __FILE__, \ + __LINE__, \ + (const char *) (string), \ + count) #endif #ifdef DOXYGEN @@ -825,7 +885,7 @@ void expect_string_count(#function, #parameter, const char *string, size_t count void expect_not_string(#function, #parameter, const char *string); #else #define expect_not_string(function, parameter, string) \ - expect_not_string_count(function, parameter, string, 1) + expect_not_string_count(function, parameter, string, 1) #endif #ifdef DOXYGEN @@ -847,11 +907,17 @@ void expect_not_string(#function, #parameter, const char *string); * * @see check_expected(). */ -void expect_not_string_count(#function, #parameter, const char *string, size_t count); +void expect_not_string_count( + #function, #parameter, const char *string, size_t count); #else #define expect_not_string_count(function, parameter, string, count) \ - _expect_not_string(#function, #parameter, __FILE__, __LINE__, \ - (const char*)(string), count) + _expect_not_string( \ + #function, \ + #parameter, \ + __FILE__, \ + __LINE__, \ + (const char *) (string), \ + count) #endif #ifdef DOXYGEN @@ -873,7 +939,7 @@ void expect_not_string_count(#function, #parameter, const char *string, size_t c void expect_memory(#function, #parameter, void *memory, size_t size); #else #define expect_memory(function, parameter, memory, size) \ - expect_memory_count(function, parameter, memory, size, 1) + expect_memory_count(function, parameter, memory, size, 1) #endif #ifdef DOXYGEN @@ -897,11 +963,18 @@ void expect_memory(#function, #parameter, void *memory, size_t size); * * @see check_expected(). */ -void expect_memory_count(#function, #parameter, void *memory, size_t size, size_t count); +void expect_memory_count( + #function, #parameter, void *memory, size_t size, size_t count); #else #define expect_memory_count(function, parameter, memory, size, count) \ - _expect_memory(#function, #parameter, __FILE__, __LINE__, \ - (const void*)(memory), size, count) + _expect_memory( \ + #function, \ + #parameter, \ + __FILE__, \ + __LINE__, \ + (const void *) (memory), \ + size, \ + count) #endif #ifdef DOXYGEN @@ -924,7 +997,7 @@ void expect_memory_count(#function, #parameter, void *memory, size_t size, size_ void expect_not_memory(#function, #parameter, void *memory, size_t size); #else #define expect_not_memory(function, parameter, memory, size) \ - expect_not_memory_count(function, parameter, memory, size, 1) + expect_not_memory_count(function, parameter, memory, size, 1) #endif #ifdef DOXYGEN @@ -948,14 +1021,20 @@ void expect_not_memory(#function, #parameter, void *memory, size_t size); * * @see check_expected(). */ -void expect_not_memory_count(#function, #parameter, void *memory, size_t size, size_t count); +void expect_not_memory_count( + #function, #parameter, void *memory, size_t size, size_t count); #else #define expect_not_memory_count(function, parameter, memory, size, count) \ - _expect_not_memory(#function, #parameter, __FILE__, __LINE__, \ - (const void*)(memory), size, count) + _expect_not_memory( \ + #function, \ + #parameter, \ + __FILE__, \ + __LINE__, \ + (const void *) (memory), \ + size, \ + count) #endif - #ifdef DOXYGEN /** * @brief Add an event to check if a parameter (of any value) has been passed. @@ -970,13 +1049,13 @@ void expect_not_memory_count(#function, #parameter, void *memory, size_t size, s */ void expect_any(#function, #parameter); #else -#define expect_any(function, parameter) \ - expect_any_count(function, parameter, 1) +#define expect_any(function, parameter) expect_any_count(function, parameter, 1) #endif #ifdef DOXYGEN /** - * @brief Add an event to always check if a parameter (of any value) has been passed. + * @brief Add an event to always check if a parameter (of any value) has been + * passed. * * The event is triggered by calling check_expected() in the mocked function. * @@ -989,7 +1068,7 @@ void expect_any(#function, #parameter); void expect_any_always(#function, #parameter); #else #define expect_any_always(function, parameter) \ - expect_any_count(function, parameter, WILL_RETURN_ALWAYS) + expect_any_count(function, parameter, WILL_RETURN_ALWAYS) #endif #ifdef DOXYGEN @@ -1012,7 +1091,7 @@ void expect_any_always(#function, #parameter); void expect_any_count(#function, #parameter, size_t count); #else #define expect_any_count(function, parameter, count) \ - _expect_any(#function, #parameter, __FILE__, __LINE__, count) + _expect_any(#function, #parameter, __FILE__, __LINE__, count) #endif #ifdef DOXYGEN @@ -1029,8 +1108,12 @@ void expect_any_count(#function, #parameter, size_t count); void check_expected(#parameter); #else #define check_expected(parameter) \ - _check_expected(__func__, #parameter, __FILE__, __LINE__, \ - cast_to_largest_integral_type(parameter)) + _check_expected( \ + __func__, \ + #parameter, \ + __FILE__, \ + __LINE__, \ + cast_to_largest_integral_type(parameter)) #endif #ifdef DOXYGEN @@ -1047,8 +1130,12 @@ void check_expected(#parameter); void check_expected_ptr(#parameter); #else #define check_expected_ptr(parameter) \ - _check_expected(__func__, #parameter, __FILE__, __LINE__, \ - cast_ptr_to_largest_integral_type(parameter)) + _check_expected( \ + __func__, \ + #parameter, \ + __FILE__, \ + __LINE__, \ + cast_ptr_to_largest_integral_type(parameter)) #endif /** @} */ @@ -1087,8 +1174,8 @@ void check_expected_ptr(#parameter); */ void assert_true(scalar expression); #else -#define assert_true(c) _assert_true(cast_to_largest_integral_type(c), #c, \ - __FILE__, __LINE__) +#define assert_true(c) \ + _assert_true(cast_to_largest_integral_type(c), #c, __FILE__, __LINE__) #endif #ifdef DOXYGEN @@ -1105,8 +1192,8 @@ void assert_true(scalar expression); */ void assert_false(scalar expression); #else -#define assert_false(c) _assert_true(!(cast_to_largest_integral_type(c)), #c, \ - __FILE__, __LINE__) +#define assert_false(c) \ + _assert_true(!(cast_to_largest_integral_type(c)), #c, __FILE__, __LINE__) #endif #ifdef DOXYGEN @@ -1124,11 +1211,14 @@ void assert_false(scalar expression); */ void assert_return_code(int rc, int error); #else -#define assert_return_code(rc, error) \ - _assert_return_code(cast_to_largest_integral_type(rc), \ - sizeof(rc), \ - cast_to_largest_integral_type(error), \ - #rc, __FILE__, __LINE__) +#define assert_return_code(rc, error) \ + _assert_return_code( \ + cast_to_largest_integral_type(rc), \ + sizeof(rc), \ + cast_to_largest_integral_type(error), \ + #rc, \ + __FILE__, \ + __LINE__) #endif #ifdef DOXYGEN @@ -1144,8 +1234,8 @@ void assert_return_code(int rc, int error); */ void assert_non_null(void *pointer); #else -#define assert_non_null(c) _assert_true(cast_ptr_to_largest_integral_type(c), #c, \ - __FILE__, __LINE__) +#define assert_non_null(c) \ + _assert_true(cast_ptr_to_largest_integral_type(c), #c, __FILE__, __LINE__) #endif #ifdef DOXYGEN @@ -1161,8 +1251,8 @@ void assert_non_null(void *pointer); */ void assert_null(void *pointer); #else -#define assert_null(c) _assert_true(!(cast_ptr_to_largest_integral_type(c)), #c, \ -__FILE__, __LINE__) +#define assert_null(c) \ + _assert_true(!(cast_ptr_to_largest_integral_type(c)), #c, __FILE__, __LINE__) #endif #ifdef DOXYGEN @@ -1178,10 +1268,12 @@ __FILE__, __LINE__) */ void assert_ptr_equal(void *a, void *b); #else -#define assert_ptr_equal(a, b) \ - _assert_int_equal(cast_ptr_to_largest_integral_type(a), \ - cast_ptr_to_largest_integral_type(b), \ - __FILE__, __LINE__) +#define assert_ptr_equal(a, b) \ + _assert_int_equal( \ + cast_ptr_to_largest_integral_type(a), \ + cast_ptr_to_largest_integral_type(b), \ + __FILE__, \ + __LINE__) #endif #ifdef DOXYGEN @@ -1197,10 +1289,12 @@ void assert_ptr_equal(void *a, void *b); */ void assert_ptr_not_equal(void *a, void *b); #else -#define assert_ptr_not_equal(a, b) \ - _assert_int_not_equal(cast_ptr_to_largest_integral_type(a), \ - cast_ptr_to_largest_integral_type(b), \ - __FILE__, __LINE__) +#define assert_ptr_not_equal(a, b) \ + _assert_int_not_equal( \ + cast_ptr_to_largest_integral_type(a), \ + cast_ptr_to_largest_integral_type(b), \ + __FILE__, \ + __LINE__) #endif #ifdef DOXYGEN @@ -1216,10 +1310,12 @@ void assert_ptr_not_equal(void *a, void *b); */ void assert_int_equal(int a, int b); #else -#define assert_int_equal(a, b) \ - _assert_int_equal(cast_to_largest_integral_type(a), \ - cast_to_largest_integral_type(b), \ - __FILE__, __LINE__) +#define assert_int_equal(a, b) \ + _assert_int_equal( \ + cast_to_largest_integral_type(a), \ + cast_to_largest_integral_type(b), \ + __FILE__, \ + __LINE__) #endif #ifdef DOXYGEN @@ -1237,10 +1333,12 @@ void assert_int_equal(int a, int b); */ void assert_int_not_equal(int a, int b); #else -#define assert_int_not_equal(a, b) \ - _assert_int_not_equal(cast_to_largest_integral_type(a), \ - cast_to_largest_integral_type(b), \ - __FILE__, __LINE__) +#define assert_int_not_equal(a, b) \ + _assert_int_not_equal( \ + cast_to_largest_integral_type(a), \ + cast_to_largest_integral_type(b), \ + __FILE__, \ + __LINE__) #endif #ifdef DOXYGEN @@ -1259,10 +1357,7 @@ void assert_int_not_equal(int a, int b); void assert_float_equal(float a, float b, float epsilon); #else #define assert_float_equal(a, b, epsilon) \ - _assert_float_equal((float)a, \ - (float)b, \ - (float)epsilon, \ - __FILE__, __LINE__) + _assert_float_equal((float) a, (float) b, (float) epsilon, __FILE__, __LINE__) #endif #ifdef DOXYGEN @@ -1281,13 +1376,10 @@ void assert_float_equal(float a, float b, float epsilon); void assert_float_not_equal(float a, float b, float epsilon); #else #define assert_float_not_equal(a, b, epsilon) \ - _assert_float_not_equal((float)a, \ - (float)b, \ - (float)epsilon, \ - __FILE__, __LINE__) + _assert_float_not_equal( \ + (float) a, (float) b, (float) epsilon, __FILE__, __LINE__) #endif - #ifdef DOXYGEN /** * @brief Assert that the two given strings are equal. @@ -1302,8 +1394,8 @@ void assert_float_not_equal(float a, float b, float epsilon); void assert_string_equal(const char *a, const char *b); #else #define assert_string_equal(a, b) \ - _assert_string_equal((const char*)(a), (const char*)(b), __FILE__, \ - __LINE__) + _assert_string_equal( \ + (const char *) (a), (const char *) (b), __FILE__, __LINE__) #endif #ifdef DOXYGEN @@ -1320,8 +1412,8 @@ void assert_string_equal(const char *a, const char *b); void assert_string_not_equal(const char *a, const char *b); #else #define assert_string_not_equal(a, b) \ - _assert_string_not_equal((const char*)(a), (const char*)(b), __FILE__, \ - __LINE__) + _assert_string_not_equal( \ + (const char *) (a), (const char *) (b), __FILE__, __LINE__) #endif #ifdef DOXYGEN @@ -1342,8 +1434,8 @@ void assert_string_not_equal(const char *a, const char *b); void assert_memory_equal(const void *a, const void *b, size_t size); #else #define assert_memory_equal(a, b, size) \ - _assert_memory_equal((const void*)(a), (const void*)(b), size, __FILE__, \ - __LINE__) + _assert_memory_equal( \ + (const void *) (a), (const void *) (b), size, __FILE__, __LINE__) #endif #ifdef DOXYGEN @@ -1364,8 +1456,8 @@ void assert_memory_equal(const void *a, const void *b, size_t size); void assert_memory_not_equal(const void *a, const void *b, size_t size); #else #define assert_memory_not_equal(a, b, size) \ - _assert_memory_not_equal((const void*)(a), (const void*)(b), size, \ - __FILE__, __LINE__) + _assert_memory_not_equal( \ + (const void *) (a), (const void *) (b), size, __FILE__, __LINE__) #endif #ifdef DOXYGEN @@ -1382,13 +1474,18 @@ void assert_memory_not_equal(const void *a, const void *b, size_t size); * * @param[in] maximum The maximum value allowed. */ -void assert_in_range(LargestIntegralType value, LargestIntegralType minimum, LargestIntegralType maximum); +void assert_in_range( + LargestIntegralType value, + LargestIntegralType minimum, + LargestIntegralType maximum); #else #define assert_in_range(value, minimum, maximum) \ - _assert_in_range( \ - cast_to_largest_integral_type(value), \ - cast_to_largest_integral_type(minimum), \ - cast_to_largest_integral_type(maximum), __FILE__, __LINE__) + _assert_in_range( \ + cast_to_largest_integral_type(value), \ + cast_to_largest_integral_type(minimum), \ + cast_to_largest_integral_type(maximum), \ + __FILE__, \ + __LINE__) #endif #ifdef DOXYGEN @@ -1405,13 +1502,18 @@ void assert_in_range(LargestIntegralType value, LargestIntegralType minimum, Lar * * @param[in] maximum The maximum value to compare. */ -void assert_not_in_range(LargestIntegralType value, LargestIntegralType minimum, LargestIntegralType maximum); +void assert_not_in_range( + LargestIntegralType value, + LargestIntegralType minimum, + LargestIntegralType maximum); #else #define assert_not_in_range(value, minimum, maximum) \ - _assert_not_in_range( \ - cast_to_largest_integral_type(value), \ - cast_to_largest_integral_type(minimum), \ - cast_to_largest_integral_type(maximum), __FILE__, __LINE__) + _assert_not_in_range( \ + cast_to_largest_integral_type(value), \ + cast_to_largest_integral_type(minimum), \ + cast_to_largest_integral_type(maximum), \ + __FILE__, \ + __LINE__) #endif #ifdef DOXYGEN @@ -1427,10 +1529,11 @@ void assert_not_in_range(LargestIntegralType value, LargestIntegralType minimum, * * @param[in] count The size of the values array. */ -void assert_in_set(LargestIntegralType value, LargestIntegralType values[], size_t count); +void assert_in_set( + LargestIntegralType value, LargestIntegralType values[], size_t count); #else #define assert_in_set(value, values, number_of_values) \ - _assert_in_set(value, values, number_of_values, __FILE__, __LINE__) + _assert_in_set(value, values, number_of_values, __FILE__, __LINE__) #endif #ifdef DOXYGEN @@ -1446,10 +1549,11 @@ void assert_in_set(LargestIntegralType value, LargestIntegralType values[], size * * @param[in] count The size of the values array. */ -void assert_not_in_set(LargestIntegralType value, LargestIntegralType values[], size_t count); +void assert_not_in_set( + LargestIntegralType value, LargestIntegralType values[], size_t count); #else #define assert_not_in_set(value, values, number_of_values) \ - _assert_not_in_set(value, values, number_of_values, __FILE__, __LINE__) + _assert_not_in_set(value, values, number_of_values, __FILE__, __LINE__) #endif /** @} */ @@ -1538,7 +1642,7 @@ void function_called(void); void expect_function_calls(#function, const int times); #else #define expect_function_calls(function, times) \ - _expect_function_call(#function, __FILE__, __LINE__, times) + _expect_function_call(#function, __FILE__, __LINE__, times) #endif #ifdef DOXYGEN @@ -1553,7 +1657,7 @@ void expect_function_calls(#function, const int times); void expect_function_call(#function); #else #define expect_function_call(function) \ - _expect_function_call(#function, __FILE__, __LINE__, 1) + _expect_function_call(#function, __FILE__, __LINE__, 1) #endif #ifdef DOXYGEN @@ -1567,7 +1671,7 @@ void expect_function_call(#function); void expect_function_call_any(#function); #else #define expect_function_call_any(function) \ - _expect_function_call(#function, __FILE__, __LINE__, -1) + _expect_function_call(#function, __FILE__, __LINE__, -1) #endif #ifdef DOXYGEN @@ -1581,7 +1685,7 @@ void expect_function_call_any(#function); void ignore_function_calls(#function); #else #define ignore_function_calls(function) \ - _expect_function_call(#function, __FILE__, __LINE__, -2) + _expect_function_call(#function, __FILE__, __LINE__, -2) #endif /** @} */ @@ -1647,10 +1751,11 @@ void skip(void); */ void fail_msg(const char *msg, ...); #else -#define fail_msg(msg, ...) do { \ +#define fail_msg(msg, ...) \ + do { \ print_error("ERROR: " msg "\n", ##__VA_ARGS__); \ - fail(); \ -} while (0) + fail(); \ + } while (0) #endif #ifdef DOXYGEN @@ -1678,53 +1783,64 @@ int run_test(#function); #define run_test(f) _run_test(#f, f, NULL, UNIT_TEST_FUNCTION_TYPE_TEST, NULL) #endif -static inline void _unit_test_dummy(void **state) { - (void)state; +static inline void _unit_test_dummy(void **state) +{ + (void) state; } /** Initializes a UnitTest structure. * * @deprecated This function was deprecated in favor of cmocka_unit_test */ -#define unit_test(f) { #f, f, UNIT_TEST_FUNCTION_TYPE_TEST } +#define unit_test(f) \ + { \ +#f, f, UNIT_TEST_FUNCTION_TYPE_TEST \ + } -#define _unit_test_setup(test, setup) \ - { #test "_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_SETUP } +#define _unit_test_setup(test, setup) \ + { \ +#test "_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_SETUP \ + } /** Initializes a UnitTest structure with a setup function. * * @deprecated This function was deprecated in favor of cmocka_unit_test_setup */ -#define unit_test_setup(test, setup) \ - _unit_test_setup(test, setup), \ - unit_test(test), \ - _unit_test_teardown(test, _unit_test_dummy) +#define unit_test_setup(test, setup) \ + _unit_test_setup(test, setup), unit_test(test), \ + _unit_test_teardown(test, _unit_test_dummy) -#define _unit_test_teardown(test, teardown) \ - { #test "_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_TEARDOWN } +#define _unit_test_teardown(test, teardown) \ + { \ +#test "_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_TEARDOWN \ + } /** Initializes a UnitTest structure with a teardown function. * - * @deprecated This function was deprecated in favor of cmocka_unit_test_teardown + * @deprecated This function was deprecated in favor of + * cmocka_unit_test_teardown */ -#define unit_test_teardown(test, teardown) \ - _unit_test_setup(test, _unit_test_dummy), \ - unit_test(test), \ - _unit_test_teardown(test, teardown) +#define unit_test_teardown(test, teardown) \ + _unit_test_setup(test, _unit_test_dummy), unit_test(test), \ + _unit_test_teardown(test, teardown) /** Initializes a UnitTest structure for a group setup function. * * @deprecated This function was deprecated in favor of cmocka_run_group_tests */ -#define group_test_setup(setup) \ - { "group_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP } +#define group_test_setup(setup) \ + { \ + "group_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP \ + } /** Initializes a UnitTest structure for a group teardown function. * * @deprecated This function was deprecated in favor of cmocka_run_group_tests */ -#define group_test_teardown(teardown) \ - { "group_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN } +#define group_test_teardown(teardown) \ + { \ + "group_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN \ + } /** * Initialize an array of UnitTest structures with a setup function for a test @@ -1734,25 +1850,35 @@ static inline void _unit_test_dummy(void **state) { * cmocka_unit_test_setup_teardown */ #define unit_test_setup_teardown(test, setup, teardown) \ - _unit_test_setup(test, setup), \ - unit_test(test), \ - _unit_test_teardown(test, teardown) - + _unit_test_setup(test, setup), unit_test(test), \ + _unit_test_teardown(test, teardown) /** Initializes a CMUnitTest structure. */ -#define cmocka_unit_test(f) { #f, f, NULL, NULL, NULL } +#define cmocka_unit_test(f) \ + { \ +#f, f, NULL, NULL, NULL \ + } /** Initializes a CMUnitTest structure with a setup function. */ -#define cmocka_unit_test_setup(f, setup) { #f, f, setup, NULL, NULL } +#define cmocka_unit_test_setup(f, setup) \ + { \ +#f, f, setup, NULL, NULL \ + } /** Initializes a CMUnitTest structure with a teardown function. */ -#define cmocka_unit_test_teardown(f, teardown) { #f, f, NULL, teardown, NULL } +#define cmocka_unit_test_teardown(f, teardown) \ + { \ +#f, f, NULL, teardown, NULL \ + } /** * Initialize an array of CMUnitTest structures with a setup function for a test * and a teardown function. Either setup or teardown can be NULL. */ -#define cmocka_unit_test_setup_teardown(f, setup, teardown) { #f, f, setup, teardown, NULL } +#define cmocka_unit_test_setup_teardown(f, setup, teardown) \ + { \ +#f, f, setup, teardown, NULL \ + } /** * Initialize a CMUnitTest structure with given initial state. It will be passed @@ -1761,7 +1887,10 @@ static inline void _unit_test_dummy(void **state) { * @note If the group setup function initialized the state already, it won't be * overridden by the initial state defined here. */ -#define cmocka_unit_test_prestate(f, state) { #f, f, NULL, NULL, state } +#define cmocka_unit_test_prestate(f, state) \ + { \ +#f, f, NULL, NULL, state \ + } /** * Initialize a CMUnitTest structure with given initial state, setup and @@ -1770,10 +1899,14 @@ static inline void _unit_test_dummy(void **state) { * @note If the group setup function initialized the state already, it won't be * overridden by the initial state defined here. */ -#define cmocka_unit_test_prestate_setup_teardown(f, setup, teardown, state) { #f, f, setup, teardown, state } +#define cmocka_unit_test_prestate_setup_teardown(f, setup, teardown, state) \ + { \ +#f, f, setup, teardown, state \ + } #define run_tests(tests) _run_tests(tests, sizeof(tests) / sizeof((tests)[0])) -#define run_group_tests(tests) _run_group_tests(tests, sizeof(tests) / sizeof((tests)[0])) +#define run_group_tests(tests) \ + _run_group_tests(tests, sizeof(tests) / sizeof((tests)[0])) #ifdef DOXYGEN /** @@ -1832,12 +1965,18 @@ static inline void _unit_test_dummy(void **state) { * @see cmocka_unit_test_teardown * @see cmocka_unit_test_setup_teardown */ -int cmocka_run_group_tests(const struct CMUnitTest group_tests[], - CMFixtureFunction group_setup, - CMFixtureFunction group_teardown); +int cmocka_run_group_tests( + const struct CMUnitTest group_tests[], + CMFixtureFunction group_setup, + CMFixtureFunction group_teardown); #else -# define cmocka_run_group_tests(group_tests, group_setup, group_teardown) \ - _cmocka_run_group_tests(#group_tests, group_tests, sizeof(group_tests) / sizeof((group_tests)[0]), group_setup, group_teardown) +#define cmocka_run_group_tests(group_tests, group_setup, group_teardown) \ + _cmocka_run_group_tests( \ + #group_tests, \ + group_tests, \ + sizeof(group_tests) / sizeof((group_tests)[0]), \ + group_setup, \ + group_teardown) #endif #ifdef DOXYGEN @@ -1900,13 +2039,20 @@ int cmocka_run_group_tests(const struct CMUnitTest group_tests[], * @see cmocka_unit_test_teardown * @see cmocka_unit_test_setup_teardown */ -int cmocka_run_group_tests_name(const char *group_name, - const struct CMUnitTest group_tests[], - CMFixtureFunction group_setup, - CMFixtureFunction group_teardown); +int cmocka_run_group_tests_name( + const char *group_name, + const struct CMUnitTest group_tests[], + CMFixtureFunction group_setup, + CMFixtureFunction group_teardown); #else -# define cmocka_run_group_tests_name(group_name, group_tests, group_setup, group_teardown) \ - _cmocka_run_group_tests(group_name, group_tests, sizeof(group_tests) / sizeof((group_tests)[0]), group_setup, group_teardown) +#define cmocka_run_group_tests_name( \ + group_name, group_tests, group_setup, group_teardown) \ + _cmocka_run_group_tests( \ + group_name, \ + group_tests, \ + sizeof(group_tests) / sizeof((group_tests)[0]), \ + group_setup, \ + group_teardown) #endif /** @} */ @@ -1944,7 +2090,8 @@ int cmocka_run_group_tests_name(const char *group_name, * * @code * #ifdef UNIT_TESTING - * extern void* _test_malloc(const size_t size, const char* file, const int line); + * extern void* _test_malloc(const size_t size, const char* file, const int + * line); * * #define malloc(size) _test_malloc(size, __FILE__, __LINE__) * #endif @@ -2020,7 +2167,6 @@ void test_free(void *ptr); /** @} */ - /** * @defgroup cmocka_mock_assert Standard Assertions * @ingroup cmocka @@ -2071,8 +2217,11 @@ void test_free(void *ptr); * @see assert(3) * @see expect_assert_failure */ -void mock_assert(const int result, const char* const expression, - const char * const file, const int line); +void mock_assert( + const int result, + const char *const expression, + const char *const file, + const int line); #ifdef DOXYGEN /** @@ -2099,20 +2248,20 @@ void mock_assert(const int result, const char* const expression, */ void expect_assert_failure(function fn_call); #else -#define expect_assert_failure(function_call) \ - { \ - const int result = setjmp(global_expect_assert_env); \ - global_expecting_assert = 1; \ - if (result) { \ - print_message("Expected assertion %s occurred\n", \ - global_last_failed_assert); \ - global_expecting_assert = 0; \ - } else { \ - function_call ; \ - global_expecting_assert = 0; \ - print_error("Expected assert in %s\n", #function_call); \ - _fail(__FILE__, __LINE__); \ - } \ +#define expect_assert_failure(function_call) \ + { \ + const int result = setjmp(global_expect_assert_env); \ + global_expecting_assert = 1; \ + if (result) { \ + print_message( \ + "Expected assertion %s occurred\n", global_last_failed_assert); \ + global_expecting_assert = 0; \ + } else { \ + function_call; \ + global_expecting_assert = 0; \ + print_error("Expected assert in %s\n", #function_call); \ + _fail(__FILE__, __LINE__); \ + } \ } #endif @@ -2122,16 +2271,17 @@ void expect_assert_failure(function fn_call); typedef void (*UnitTestFunction)(void **state); /* Function that determines whether a function parameter value is correct. */ -typedef int (*CheckParameterValue)(const LargestIntegralType value, - const LargestIntegralType check_value_data); +typedef int (*CheckParameterValue)( + const LargestIntegralType value, + const LargestIntegralType check_value_data); /* Type of the unit test function. */ typedef enum UnitTestFunctionType { - UNIT_TEST_FUNCTION_TYPE_TEST = 0, - UNIT_TEST_FUNCTION_TYPE_SETUP, - UNIT_TEST_FUNCTION_TYPE_TEARDOWN, - UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP, - UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN, + UNIT_TEST_FUNCTION_TYPE_TEST = 0, + UNIT_TEST_FUNCTION_TYPE_SETUP, + UNIT_TEST_FUNCTION_TYPE_TEARDOWN, + UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP, + UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN, } UnitTestFunctionType; /* @@ -2140,16 +2290,16 @@ typedef enum UnitTestFunctionType { * possible to specify NULL function pointers. */ typedef struct UnitTest { - const char* name; - UnitTestFunction function; - UnitTestFunctionType function_type; + const char *name; + UnitTestFunction function; + UnitTestFunctionType function_type; } UnitTest; typedef struct GroupTest { - UnitTestFunction setup; - UnitTestFunction teardown; - const UnitTest *tests; - const size_t number_of_tests; + UnitTestFunction setup; + UnitTestFunction teardown; + const UnitTest *tests; + const size_t number_of_tests; } GroupTest; /* Function prototype for test functions. */ @@ -2159,191 +2309,280 @@ typedef void (*CMUnitTestFunction)(void **state); typedef int (*CMFixtureFunction)(void **state); struct CMUnitTest { - const char *name; - CMUnitTestFunction test_func; - CMFixtureFunction setup_func; - CMFixtureFunction teardown_func; - void *initial_state; + const char *name; + CMUnitTestFunction test_func; + CMFixtureFunction setup_func; + CMFixtureFunction teardown_func; + void *initial_state; }; /* Location within some source code. */ typedef struct SourceLocation { - const char* file; - int line; + const char *file; + int line; } SourceLocation; /* Event that's called to check a parameter value. */ typedef struct CheckParameterEvent { - SourceLocation location; - const char *parameter_name; - CheckParameterValue check_value; - LargestIntegralType check_value_data; + SourceLocation location; + const char *parameter_name; + CheckParameterValue check_value; + LargestIntegralType check_value_data; } CheckParameterEvent; /* Used by expect_assert_failure() and mock_assert(). */ extern int global_expecting_assert; extern jmp_buf global_expect_assert_env; -extern const char * global_last_failed_assert; +extern const char *global_last_failed_assert; /* Retrieves a value for the given function, as set by "will_return". */ -LargestIntegralType _mock(const char * const function, const char* const file, - const int line); +LargestIntegralType +_mock(const char *const function, const char *const file, const int line); void _expect_function_call( - const char * const function_name, - const char * const file, + const char *const function_name, + const char *const file, const int line, const int count); -void _function_called(const char * const function, const char* const file, - const int line); +void _function_called( + const char *const function, const char *const file, const int line); void _expect_check( - const char* const function, const char* const parameter, - const char* const file, const int line, + const char *const function, + const char *const parameter, + const char *const file, + const int line, const CheckParameterValue check_function, - const LargestIntegralType check_data, CheckParameterEvent * const event, + const LargestIntegralType check_data, + CheckParameterEvent *const event, const int count); void _expect_in_set( - const char* const function, const char* const parameter, - const char* const file, const int line, const LargestIntegralType values[], - const size_t number_of_values, const int count); + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const LargestIntegralType values[], + const size_t number_of_values, + const int count); void _expect_not_in_set( - const char* const function, const char* const parameter, - const char* const file, const int line, const LargestIntegralType values[], - const size_t number_of_values, const int count); + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const LargestIntegralType values[], + const size_t number_of_values, + const int count); void _expect_in_range( - const char* const function, const char* const parameter, - const char* const file, const int line, + const char *const function, + const char *const parameter, + const char *const file, + const int line, const LargestIntegralType minimum, - const LargestIntegralType maximum, const int count); + const LargestIntegralType maximum, + const int count); void _expect_not_in_range( - const char* const function, const char* const parameter, - const char* const file, const int line, + const char *const function, + const char *const parameter, + const char *const file, + const int line, const LargestIntegralType minimum, - const LargestIntegralType maximum, const int count); + const LargestIntegralType maximum, + const int count); void _expect_value( - const char* const function, const char* const parameter, - const char* const file, const int line, const LargestIntegralType value, + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const LargestIntegralType value, const int count); void _expect_not_value( - const char* const function, const char* const parameter, - const char* const file, const int line, const LargestIntegralType value, + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const LargestIntegralType value, const int count); void _expect_string( - const char* const function, const char* const parameter, - const char* const file, const int line, const char* string, + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const char *string, const int count); void _expect_not_string( - const char* const function, const char* const parameter, - const char* const file, const int line, const char* string, + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const char *string, const int count); void _expect_memory( - const char* const function, const char* const parameter, - const char* const file, const int line, const void* const memory, - const size_t size, const int count); + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const void *const memory, + const size_t size, + const int count); void _expect_not_memory( - const char* const function, const char* const parameter, - const char* const file, const int line, const void* const memory, - const size_t size, const int count); + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const void *const memory, + const size_t size, + const int count); void _expect_any( - const char* const function, const char* const parameter, - const char* const file, const int line, const int count); + const char *const function, + const char *const parameter, + const char *const file, + const int line, + const int count); void _check_expected( - const char * const function_name, const char * const parameter_name, - const char* file, const int line, const LargestIntegralType value); + const char *const function_name, + const char *const parameter_name, + const char *file, + const int line, + const LargestIntegralType value); -void _will_return(const char * const function_name, const char * const file, - const int line, const LargestIntegralType value, - const int count); -void _assert_true(const LargestIntegralType result, - const char* const expression, - const char * const file, const int line); -void _assert_return_code(const LargestIntegralType result, - size_t rlen, - const LargestIntegralType error, - const char * const expression, - const char * const file, - const int line); -void _assert_float_equal(const float a, const float n, - const float epsilon, const char* const file, - const int line); -void _assert_float_not_equal(const float a, const float n, - const float epsilon, const char* const file, - const int line); +void _will_return( + const char *const function_name, + const char *const file, + const int line, + const LargestIntegralType value, + const int count); +void _assert_true( + const LargestIntegralType result, + const char *const expression, + const char *const file, + const int line); +void _assert_return_code( + const LargestIntegralType result, + size_t rlen, + const LargestIntegralType error, + const char *const expression, + const char *const file, + const int line); +void _assert_float_equal( + const float a, + const float n, + const float epsilon, + const char *const file, + const int line); +void _assert_float_not_equal( + const float a, + const float n, + const float epsilon, + const char *const file, + const int line); void _assert_int_equal( - const LargestIntegralType a, const LargestIntegralType b, - const char * const file, const int line); + const LargestIntegralType a, + const LargestIntegralType b, + const char *const file, + const int line); void _assert_int_not_equal( - const LargestIntegralType a, const LargestIntegralType b, - const char * const file, const int line); -void _assert_string_equal(const char * const a, const char * const b, - const char * const file, const int line); -void _assert_string_not_equal(const char * const a, const char * const b, - const char *file, const int line); -void _assert_memory_equal(const void * const a, const void * const b, - const size_t size, const char* const file, - const int line); -void _assert_memory_not_equal(const void * const a, const void * const b, - const size_t size, const char* const file, - const int line); + const LargestIntegralType a, + const LargestIntegralType b, + const char *const file, + const int line); +void _assert_string_equal( + const char *const a, + const char *const b, + const char *const file, + const int line); +void _assert_string_not_equal( + const char *const a, const char *const b, const char *file, const int line); +void _assert_memory_equal( + const void *const a, + const void *const b, + const size_t size, + const char *const file, + const int line); +void _assert_memory_not_equal( + const void *const a, + const void *const b, + const size_t size, + const char *const file, + const int line); void _assert_in_range( - const LargestIntegralType value, const LargestIntegralType minimum, - const LargestIntegralType maximum, const char* const file, const int line); + const LargestIntegralType value, + const LargestIntegralType minimum, + const LargestIntegralType maximum, + const char *const file, + const int line); void _assert_not_in_range( - const LargestIntegralType value, const LargestIntegralType minimum, - const LargestIntegralType maximum, const char* const file, const int line); + const LargestIntegralType value, + const LargestIntegralType minimum, + const LargestIntegralType maximum, + const char *const file, + const int line); void _assert_in_set( - const LargestIntegralType value, const LargestIntegralType values[], - const size_t number_of_values, const char* const file, const int line); + const LargestIntegralType value, + const LargestIntegralType values[], + const size_t number_of_values, + const char *const file, + const int line); void _assert_not_in_set( - const LargestIntegralType value, const LargestIntegralType values[], - const size_t number_of_values, const char* const file, const int line); + const LargestIntegralType value, + const LargestIntegralType values[], + const size_t number_of_values, + const char *const file, + const int line); -void* _test_malloc(const size_t size, const char* file, const int line); -void* _test_realloc(void *ptr, const size_t size, const char* file, const int line); -void* _test_calloc(const size_t number_of_elements, const size_t size, - const char* file, const int line); -void _test_free(void* const ptr, const char* file, const int line); +void *_test_malloc(const size_t size, const char *file, const int line); +void * +_test_realloc(void *ptr, const size_t size, const char *file, const int line); +void *_test_calloc( + const size_t number_of_elements, + const size_t size, + const char *file, + const int line); +void _test_free(void *const ptr, const char *file, const int line); -void _fail(const char * const file, const int line); +void _fail(const char *const file, const int line); -void _skip(const char * const file, const int line); +void _skip(const char *const file, const int line); int _run_test( - const char * const function_name, const UnitTestFunction Function, - void ** const volatile state, const UnitTestFunctionType function_type, - const void* const heap_check_point); -CMOCKA_DEPRECATED int _run_tests(const UnitTest * const tests, - const size_t number_of_tests); -CMOCKA_DEPRECATED int _run_group_tests(const UnitTest * const tests, - const size_t number_of_tests); + const char *const function_name, + const UnitTestFunction Function, + void **const volatile state, + const UnitTestFunctionType function_type, + const void *const heap_check_point); +CMOCKA_DEPRECATED int +_run_tests(const UnitTest *const tests, const size_t number_of_tests); +CMOCKA_DEPRECATED int +_run_group_tests(const UnitTest *const tests, const size_t number_of_tests); /* Test runner */ -int _cmocka_run_group_tests(const char *group_name, - const struct CMUnitTest * const tests, - const size_t num_tests, - CMFixtureFunction group_setup, - CMFixtureFunction group_teardown); +int _cmocka_run_group_tests( + const char *group_name, + const struct CMUnitTest *const tests, + const size_t num_tests, + CMFixtureFunction group_setup, + CMFixtureFunction group_teardown); /* Standard output and error print methods. */ -void print_message(const char* const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); -void print_error(const char* const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); -void vprint_message(const char* const format, va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0); -void vprint_error(const char* const format, va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0); +void print_message(const char *const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); +void print_error(const char *const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); +void vprint_message(const char *const format, va_list args) + CMOCKA_PRINTF_ATTRIBUTE(1, 0); +void vprint_error(const char *const format, va_list args) + CMOCKA_PRINTF_ATTRIBUTE(1, 0); enum cm_message_output { - CM_OUTPUT_STDOUT, - CM_OUTPUT_SUBUNIT, - CM_OUTPUT_TAP, - CM_OUTPUT_XML, + CM_OUTPUT_STDOUT, + CM_OUTPUT_SUBUNIT, + CM_OUTPUT_TAP, + CM_OUTPUT_XML, }; /** @@ -2359,7 +2598,6 @@ enum cm_message_output { */ void cmocka_set_message_output(enum cm_message_output output); - /** * @brief Set a pattern to only run the test matching the pattern. * diff --git a/src/imports/cmocka/cmocka_private.h b/src/imports/cmocka/cmocka_private.h index d20d841..a2f8b52 100644 --- a/src/imports/cmocka/cmocka_private.h +++ b/src/imports/cmocka/cmocka_private.h @@ -26,47 +26,47 @@ #ifdef _WIN32 #include -# ifdef _MSC_VER -# include /* _snprintf */ +#ifdef _MSC_VER +#include /* _snprintf */ -# undef inline -# define inline __inline +#undef inline +#define inline __inline -# ifndef va_copy -# define va_copy(dest, src) (dest = src) -# endif +#ifndef va_copy +#define va_copy(dest, src) (dest = src) +#endif -# define strcasecmp _stricmp -# define strncasecmp _strnicmp +#define strcasecmp _stricmp +#define strncasecmp _strnicmp -# if defined(HAVE__SNPRINTF_S) -# undef snprintf -# define snprintf(d, n, ...) _snprintf_s((d), (n), _TRUNCATE, __VA_ARGS__) -# else /* HAVE__SNPRINTF_S */ -# if defined(HAVE__SNPRINTF) -# undef snprintf -# define snprintf _snprintf -# else /* HAVE__SNPRINTF */ -# if !defined(HAVE_SNPRINTF) -# error "no snprintf compatible function found" -# endif /* HAVE_SNPRINTF */ -# endif /* HAVE__SNPRINTF */ -# endif /* HAVE__SNPRINTF_S */ +#if defined(HAVE__SNPRINTF_S) +#undef snprintf +#define snprintf(d, n, ...) _snprintf_s((d), (n), _TRUNCATE, __VA_ARGS__) +#else /* HAVE__SNPRINTF_S */ +#if defined(HAVE__SNPRINTF) +#undef snprintf +#define snprintf _snprintf +#else /* HAVE__SNPRINTF */ +#if !defined(HAVE_SNPRINTF) +#error "no snprintf compatible function found" +#endif /* HAVE_SNPRINTF */ +#endif /* HAVE__SNPRINTF */ +#endif /* HAVE__SNPRINTF_S */ -# if defined(HAVE__VSNPRINTF_S) -# undef vsnprintf -# define vsnprintf(s, n, f, v) _vsnprintf_s((s), (n), _TRUNCATE, (f), (v)) -# else /* HAVE__VSNPRINTF_S */ -# if defined(HAVE__VSNPRINTF) -# undef vsnprintf -# define vsnprintf _vsnprintf -# else -# if !defined(HAVE_VSNPRINTF) -# error "No vsnprintf compatible function found" -# endif /* HAVE_VSNPRINTF */ -# endif /* HAVE__VSNPRINTF */ -# endif /* HAVE__VSNPRINTF_S */ -# endif /* _MSC_VER */ +#if defined(HAVE__VSNPRINTF_S) +#undef vsnprintf +#define vsnprintf(s, n, f, v) _vsnprintf_s((s), (n), _TRUNCATE, (f), (v)) +#else /* HAVE__VSNPRINTF_S */ +#if defined(HAVE__VSNPRINTF) +#undef vsnprintf +#define vsnprintf _vsnprintf +#else +#if !defined(HAVE_VSNPRINTF) +#error "No vsnprintf compatible function found" +#endif /* HAVE_VSNPRINTF */ +#endif /* HAVE__VSNPRINTF */ +#endif /* HAVE__VSNPRINTF_S */ +#endif /* _MSC_VER */ /* * Backwards compatibility with headers shipped with Visual Studio 2005 and @@ -75,15 +75,15 @@ WINBASEAPI BOOL WINAPI IsDebuggerPresent(VOID); #ifndef PRIdS -# define PRIdS "Id" +#define PRIdS "Id" #endif #ifndef PRIu64 -# define PRIu64 "I64u" +#define PRIu64 "I64u" #endif #ifndef PRIuMAX -# define PRIuMAX PRIu64 +#define PRIuMAX PRIu64 #endif #ifndef PRIxMAX @@ -97,23 +97,23 @@ WINBASEAPI BOOL WINAPI IsDebuggerPresent(VOID); #else /* _WIN32 */ #ifndef __PRI64_PREFIX -# if __WORDSIZE == 64 -# define __PRI64_PREFIX "l" -# else -# define __PRI64_PREFIX "ll" -# endif +#if __WORDSIZE == 64 +#define __PRI64_PREFIX "l" +#else +#define __PRI64_PREFIX "ll" +#endif #endif #ifndef PRIdS -# define PRIdS "zd" +#define PRIdS "zd" #endif #ifndef PRIu64 -# define PRIu64 __PRI64_PREFIX "u" +#define PRIu64 __PRI64_PREFIX "u" #endif #ifndef PRIuMAX -# define PRIuMAX __PRI64_PREFIX "u" +#define PRIuMAX __PRI64_PREFIX "u" #endif #ifndef PRIxMAX @@ -127,19 +127,33 @@ WINBASEAPI BOOL WINAPI IsDebuggerPresent(VOID); #endif /* _WIN32 */ /** Free memory space */ -#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0) +#define SAFE_FREE(x) \ + do { \ + if ((x) != NULL) { \ + free(x); \ + x = NULL; \ + } \ + } while (0) /** Zero a structure */ -#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x)) +#define ZERO_STRUCT(x) memset((char *) &(x), 0, sizeof(x)) /** Zero a structure given a pointer to the structure */ -#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0) +#define ZERO_STRUCTP(x) \ + do { \ + if ((x) != NULL) \ + memset((char *) (x), 0, sizeof(*(x))); \ + } while (0) /** Get the size of an array */ -#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) /** Overwrite the complete string with 'X' */ -#define BURN_STRING(x) do { if ((x) != NULL) memset((x), 'X', strlen((x))); } while(0) +#define BURN_STRING(x) \ + do { \ + if ((x) != NULL) \ + memset((x), 'X', strlen((x))); \ + } while (0) /** * This is a hack to fix warnings. The idea is to use this everywhere that we @@ -153,11 +167,11 @@ WINBASEAPI BOOL WINAPI IsDebuggerPresent(VOID); * Also, please call this via the discard_const_p() macro interface, as that * makes the return type safe. */ -#define discard_const(ptr) ((void *)((uintptr_t)(ptr))) +#define discard_const(ptr) ((void *) ((uintptr_t)(ptr))) /** * Type-safe version of discard_const */ -#define discard_const_p(type, ptr) ((type *)discard_const(ptr)) +#define discard_const_p(type, ptr) ((type *) discard_const(ptr)) #endif /* CMOCKA_PRIVATE_H_ */ diff --git a/src/imports/fmodex/fmod.h b/src/imports/fmodex/fmod.h index 2c80462..98947fb 100644 --- a/src/imports/fmodex/fmod.h +++ b/src/imports/fmodex/fmod.h @@ -1,57 +1,65 @@ /*$ preserve start $*/ -/* ============================================================================================ */ -/* FMOD Ex - Main C/C++ header file. Copyright (c), Firelight Technologies Pty, Ltd. 2004-2016. */ +/* ============================================================================================ + */ +/* FMOD Ex - Main C/C++ header file. Copyright (c), Firelight Technologies Pty, + * Ltd. 2004-2016. */ /* */ -/* This header is the base header for all other FMOD headers. If you are programming in C */ -/* use this exclusively, or if you are programming C++ use this in conjunction with FMOD.HPP */ +/* This header is the base header for all other FMOD headers. If you are + * programming in C */ +/* use this exclusively, or if you are programming C++ use this in conjunction + * with FMOD.HPP */ /* */ -/* ============================================================================================ */ +/* ============================================================================================ + */ #ifndef _FMOD_H #define _FMOD_H /* FMOD version number. Check this against FMOD::System::getVersion. - 0xaaaabbcc -> aaaa = major version number. bb = minor version number. cc = development version number. + 0xaaaabbcc -> aaaa = major version number. bb = minor version number. cc = + development version number. */ -#define FMOD_VERSION 0x00044464 +#define FMOD_VERSION 0x00044464 /* Compiler specific settings. */ #if defined(__CYGWIN32__) - #define F_CDECL __cdecl - #define F_STDCALL __stdcall - #define F_DECLSPEC __declspec - #define F_DLLEXPORT ( dllexport ) +#define F_CDECL __cdecl +#define F_STDCALL __stdcall +#define F_DECLSPEC __declspec +#define F_DLLEXPORT (dllexport) #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) - #define F_CDECL _cdecl - #define F_STDCALL _stdcall - #define F_DECLSPEC __declspec - #define F_DLLEXPORT ( dllexport ) -#elif defined(__MACH__) || defined(__ANDROID__) || defined(__linux__) || defined(__QNX__) - #define F_CDECL - #define F_STDCALL - #define F_DECLSPEC - #define F_DLLEXPORT __attribute__ ((visibility("default"))) +#define F_CDECL _cdecl +#define F_STDCALL _stdcall +#define F_DECLSPEC __declspec +#define F_DLLEXPORT (dllexport) +#elif defined(__MACH__) || defined(__ANDROID__) || defined(__linux__) || \ + defined(__QNX__) +#define F_CDECL +#define F_STDCALL +#define F_DECLSPEC +#define F_DLLEXPORT __attribute__((visibility("default"))) #else - #define F_CDECL - #define F_STDCALL - #define F_DECLSPEC - #define F_DLLEXPORT +#define F_CDECL +#define F_STDCALL +#define F_DECLSPEC +#define F_DLLEXPORT #endif #ifdef DLL_EXPORTS - #if defined(__MACH__) || defined(__ANDROID__) || defined(__linux__) || defined(__QNX__) - #define F_API __attribute__ ((visibility("default"))) - #else - #define F_API __declspec(dllexport) F_STDCALL - #endif +#if defined(__MACH__) || defined(__ANDROID__) || defined(__linux__) || \ + defined(__QNX__) +#define F_API __attribute__((visibility("default"))) #else - #define F_API F_STDCALL +#define F_API __declspec(dllexport) F_STDCALL +#endif +#else +#define F_API F_STDCALL #endif #define F_CALLBACK F_STDCALL @@ -60,161 +68,272 @@ FMOD types. */ -typedef int FMOD_BOOL; -typedef struct FMOD_SYSTEM FMOD_SYSTEM; -typedef struct FMOD_SOUND FMOD_SOUND; -typedef struct FMOD_CHANNEL FMOD_CHANNEL; -typedef struct FMOD_CHANNELGROUP FMOD_CHANNELGROUP; -typedef struct FMOD_SOUNDGROUP FMOD_SOUNDGROUP; -typedef struct FMOD_REVERB FMOD_REVERB; -typedef struct FMOD_DSP FMOD_DSP; +typedef int FMOD_BOOL; +typedef struct FMOD_SYSTEM FMOD_SYSTEM; +typedef struct FMOD_SOUND FMOD_SOUND; +typedef struct FMOD_CHANNEL FMOD_CHANNEL; +typedef struct FMOD_CHANNELGROUP FMOD_CHANNELGROUP; +typedef struct FMOD_SOUNDGROUP FMOD_SOUNDGROUP; +typedef struct FMOD_REVERB FMOD_REVERB; +typedef struct FMOD_DSP FMOD_DSP; typedef struct FMOD_DSPCONNECTION FMOD_DSPCONNECTION; -typedef struct FMOD_POLYGON FMOD_POLYGON; -typedef struct FMOD_GEOMETRY FMOD_GEOMETRY; -typedef struct FMOD_SYNCPOINT FMOD_SYNCPOINT; +typedef struct FMOD_POLYGON FMOD_POLYGON; +typedef struct FMOD_GEOMETRY FMOD_GEOMETRY; +typedef struct FMOD_SYNCPOINT FMOD_SYNCPOINT; typedef struct FMOD_ASYNCREADINFO FMOD_ASYNCREADINFO; -typedef unsigned int FMOD_MODE; -typedef unsigned int FMOD_TIMEUNIT; -typedef unsigned int FMOD_INITFLAGS; -typedef unsigned int FMOD_CAPS; -typedef unsigned int FMOD_DEBUGLEVEL; -typedef unsigned int FMOD_MEMORY_TYPE; +typedef unsigned int FMOD_MODE; +typedef unsigned int FMOD_TIMEUNIT; +typedef unsigned int FMOD_INITFLAGS; +typedef unsigned int FMOD_CAPS; +typedef unsigned int FMOD_DEBUGLEVEL; +typedef unsigned int FMOD_MEMORY_TYPE; /*$ fmod result start $*/ /* [ENUM] [ - [DESCRIPTION] + [DESCRIPTION] error codes. Returned from every function. [REMARKS] [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] ] */ -typedef enum -{ - FMOD_OK, /* No errors. */ - FMOD_ERR_ALREADYLOCKED, /* Tried to call lock a second time before unlock was called. */ - FMOD_ERR_BADCOMMAND, /* Tried to call a function on a data type that does not allow this type of functionality (ie calling Sound::lock on a streaming sound). */ - FMOD_ERR_CDDA_DRIVERS, /* Neither NTSCSI nor ASPI could be initialised. */ - FMOD_ERR_CDDA_INIT, /* An error occurred while initialising the CDDA subsystem. */ - FMOD_ERR_CDDA_INVALID_DEVICE, /* Couldn't find the specified device. */ - FMOD_ERR_CDDA_NOAUDIO, /* No audio tracks on the specified disc. */ - FMOD_ERR_CDDA_NODEVICES, /* No CD/DVD devices were found. */ - FMOD_ERR_CDDA_NODISC, /* No disc present in the specified drive. */ - FMOD_ERR_CDDA_READ, /* A CDDA read error occurred. */ - FMOD_ERR_CHANNEL_ALLOC, /* Error trying to allocate a channel. */ - FMOD_ERR_CHANNEL_STOLEN, /* The specified channel has been reused to play another sound. */ - FMOD_ERR_COM, /* A Win32 COM related error occured. COM failed to initialize or a QueryInterface failed meaning a Windows codec or driver was not installed properly. */ - FMOD_ERR_DMA, /* DMA Failure. See debug output for more information. */ - FMOD_ERR_DSP_CONNECTION, /* DSP connection error. Connection possibly caused a cyclic dependancy. Or tried to connect a tree too many units deep (more than 128). */ - FMOD_ERR_DSP_FORMAT, /* DSP Format error. A DSP unit may have attempted to connect to this network with the wrong format. */ - FMOD_ERR_DSP_NOTFOUND, /* DSP connection error. Couldn't find the DSP unit specified. */ - FMOD_ERR_DSP_RUNNING, /* DSP error. Cannot perform this operation while the network is in the middle of running. This will most likely happen if a connection or disconnection is attempted in a DSP callback. */ - FMOD_ERR_DSP_TOOMANYCONNECTIONS,/* DSP connection error. The unit being connected to or disconnected should only have 1 input or output. */ - FMOD_ERR_FILE_BAD, /* Error loading file. */ - FMOD_ERR_FILE_COULDNOTSEEK, /* Couldn't perform seek operation. This is a limitation of the medium (ie netstreams) or the file format. */ - FMOD_ERR_FILE_DISKEJECTED, /* Media was ejected while reading. */ - FMOD_ERR_FILE_EOF, /* End of file unexpectedly reached while trying to read essential data (truncated data?). */ - FMOD_ERR_FILE_NOTFOUND, /* File not found. */ - FMOD_ERR_FILE_UNWANTED, /* Unwanted file access occured. */ - FMOD_ERR_FORMAT, /* Unsupported file or audio format. */ - FMOD_ERR_HTTP, /* A HTTP error occurred. This is a catch-all for HTTP errors not listed elsewhere. */ - FMOD_ERR_HTTP_ACCESS, /* The specified resource requires authentication or is forbidden. */ - FMOD_ERR_HTTP_PROXY_AUTH, /* Proxy authentication is required to access the specified resource. */ - FMOD_ERR_HTTP_SERVER_ERROR, /* A HTTP server error occurred. */ - FMOD_ERR_HTTP_TIMEOUT, /* The HTTP request timed out. */ - FMOD_ERR_INITIALIZATION, /* FMOD was not initialized correctly to support this function. */ - FMOD_ERR_INITIALIZED, /* Cannot call this command after System::init. */ - FMOD_ERR_INTERNAL, /* An error occured that wasn't supposed to. Contact support. */ - FMOD_ERR_INVALID_ADDRESS, /* On Xbox 360, this memory address passed to FMOD must be physical, (ie allocated with XPhysicalAlloc.) */ - FMOD_ERR_INVALID_FLOAT, /* Value passed in was a NaN, Inf or denormalized float. */ - FMOD_ERR_INVALID_HANDLE, /* An invalid object handle was used. */ - FMOD_ERR_INVALID_PARAM, /* An invalid parameter was passed to this function. */ - FMOD_ERR_INVALID_POSITION, /* An invalid seek position was passed to this function. */ - FMOD_ERR_INVALID_SPEAKER, /* An invalid speaker was passed to this function based on the current speaker mode. */ - FMOD_ERR_INVALID_SYNCPOINT, /* The syncpoint did not come from this sound handle. */ - FMOD_ERR_INVALID_VECTOR, /* The vectors passed in are not unit length, or perpendicular. */ - FMOD_ERR_MAXAUDIBLE, /* Reached maximum audible playback count for this sound's soundgroup. */ - FMOD_ERR_MEMORY, /* Not enough memory or resources. */ - FMOD_ERR_MEMORY_CANTPOINT, /* Can't use FMOD_OPENMEMORY_POINT on non PCM source data, or non mp3/xma/adpcm data if FMOD_CREATECOMPRESSEDSAMPLE was used. */ - FMOD_ERR_MEMORY_SRAM, /* Not enough memory or resources on console sound ram. */ - FMOD_ERR_NEEDS2D, /* Tried to call a command on a 3d sound when the command was meant for 2d sound. */ - FMOD_ERR_NEEDS3D, /* Tried to call a command on a 2d sound when the command was meant for 3d sound. */ - FMOD_ERR_NEEDSHARDWARE, /* Tried to use a feature that requires hardware support. (ie trying to play a GCADPCM compressed sound in software on Wii). */ - FMOD_ERR_NEEDSSOFTWARE, /* Tried to use a feature that requires the software engine. Software engine has either been turned off, or command was executed on a hardware channel which does not support this feature. */ - FMOD_ERR_NET_CONNECT, /* Couldn't connect to the specified host. */ - FMOD_ERR_NET_SOCKET_ERROR, /* A socket error occurred. This is a catch-all for socket-related errors not listed elsewhere. */ - FMOD_ERR_NET_URL, /* The specified URL couldn't be resolved. */ - FMOD_ERR_NET_WOULD_BLOCK, /* Operation on a non-blocking socket could not complete immediately. */ - FMOD_ERR_NOTREADY, /* Operation could not be performed because specified sound/DSP connection is not ready. */ - FMOD_ERR_OUTPUT_ALLOCATED, /* Error initializing output device, but more specifically, the output device is already in use and cannot be reused. */ - FMOD_ERR_OUTPUT_CREATEBUFFER, /* Error creating hardware sound buffer. */ - FMOD_ERR_OUTPUT_DRIVERCALL, /* A call to a standard soundcard driver failed, which could possibly mean a bug in the driver or resources were missing or exhausted. */ - FMOD_ERR_OUTPUT_ENUMERATION, /* Error enumerating the available driver list. List may be inconsistent due to a recent device addition or removal. */ - FMOD_ERR_OUTPUT_FORMAT, /* Soundcard does not support the minimum features needed for this soundsystem (16bit stereo output). */ - FMOD_ERR_OUTPUT_INIT, /* Error initializing output device. */ - FMOD_ERR_OUTPUT_NOHARDWARE, /* FMOD_HARDWARE was specified but the sound card does not have the resources necessary to play it. */ - FMOD_ERR_OUTPUT_NOSOFTWARE, /* Attempted to create a software sound but no software channels were specified in System::init. */ - FMOD_ERR_PAN, /* Panning only works with mono or stereo sound sources. */ - FMOD_ERR_PLUGIN, /* An unspecified error has been returned from a 3rd party plugin. */ - FMOD_ERR_PLUGIN_INSTANCES, /* The number of allowed instances of a plugin has been exceeded. */ - FMOD_ERR_PLUGIN_MISSING, /* A requested output, dsp unit type or codec was not available. */ - FMOD_ERR_PLUGIN_RESOURCE, /* A resource that the plugin requires cannot be found. (ie the DLS file for MIDI playback or other DLLs that it needs to load) */ - FMOD_ERR_PRELOADED, /* The specified sound is still in use by the event system, call EventSystem::unloadFSB before trying to release it. */ - FMOD_ERR_PROGRAMMERSOUND, /* The specified sound is still in use by the event system, wait for the event which is using it finish with it. */ - FMOD_ERR_RECORD, /* An error occured trying to initialize the recording device. */ - FMOD_ERR_REVERB_INSTANCE, /* Specified instance in FMOD_REVERB_PROPERTIES couldn't be set. Most likely because it is an invalid instance number or the reverb doesnt exist. */ - FMOD_ERR_SUBSOUND_ALLOCATED, /* This subsound is already being used by another sound, you cannot have more than one parent to a sound. Null out the other parent's entry first. */ - FMOD_ERR_SUBSOUND_CANTMOVE, /* Shared subsounds cannot be replaced or moved from their parent stream, such as when the parent stream is an FSB file. */ - FMOD_ERR_SUBSOUND_MODE, /* The subsound's mode bits do not match with the parent sound's mode bits. See documentation for function that it was called with. */ - FMOD_ERR_SUBSOUNDS, /* The error occured because the sound referenced contains subsounds when it shouldn't have, or it doesn't contain subsounds when it should have. The operation may also not be able to be performed on a parent sound, or a parent sound was played without setting up a sentence first. */ - FMOD_ERR_TAGNOTFOUND, /* The specified tag could not be found or there are no tags. */ - FMOD_ERR_TOOMANYCHANNELS, /* The sound created exceeds the allowable input channel count. This can be increased using the maxinputchannels parameter in System::setSoftwareFormat. */ - FMOD_ERR_UNIMPLEMENTED, /* Something in FMOD hasn't been implemented when it should be! contact support! */ - FMOD_ERR_UNINITIALIZED, /* This command failed because System::init or System::setDriver was not called. */ - FMOD_ERR_UNSUPPORTED, /* A command issued was not supported by this object. Possibly a plugin without certain callbacks specified. */ - FMOD_ERR_UPDATE, /* An error caused by System::update occured. */ - FMOD_ERR_VERSION, /* The version number of this file format is not supported. */ +typedef enum { + FMOD_OK, /* No errors. */ + FMOD_ERR_ALREADYLOCKED, /* Tried to call lock a second time before unlock was + called. */ + FMOD_ERR_BADCOMMAND, /* Tried to call a function on a data type that does not + allow this type of functionality (ie calling + Sound::lock on a streaming sound). */ + FMOD_ERR_CDDA_DRIVERS, /* Neither NTSCSI nor ASPI could be initialised. */ + FMOD_ERR_CDDA_INIT, /* An error occurred while initialising the CDDA + subsystem. */ + FMOD_ERR_CDDA_INVALID_DEVICE, /* Couldn't find the specified device. */ + FMOD_ERR_CDDA_NOAUDIO, /* No audio tracks on the specified disc. */ + FMOD_ERR_CDDA_NODEVICES, /* No CD/DVD devices were found. */ + FMOD_ERR_CDDA_NODISC, /* No disc present in the specified drive. */ + FMOD_ERR_CDDA_READ, /* A CDDA read error occurred. */ + FMOD_ERR_CHANNEL_ALLOC, /* Error trying to allocate a channel. */ + FMOD_ERR_CHANNEL_STOLEN, /* The specified channel has been reused to play + another sound. */ + FMOD_ERR_COM, /* A Win32 COM related error occured. COM failed to initialize + or a QueryInterface failed meaning a Windows codec or driver + was not installed properly. */ + FMOD_ERR_DMA, /* DMA Failure. See debug output for more information. */ + FMOD_ERR_DSP_CONNECTION, /* DSP connection error. Connection possibly caused + a cyclic dependancy. Or tried to connect a tree + too many units deep (more than 128). */ + FMOD_ERR_DSP_FORMAT, /* DSP Format error. A DSP unit may have attempted to + connect to this network with the wrong format. */ + FMOD_ERR_DSP_NOTFOUND, /* DSP connection error. Couldn't find the DSP unit + specified. */ + FMOD_ERR_DSP_RUNNING, /* DSP error. Cannot perform this operation while the + network is in the middle of running. This will most + likely happen if a connection or disconnection is + attempted in a DSP callback. */ + FMOD_ERR_DSP_TOOMANYCONNECTIONS, /* DSP connection error. The unit being + connected to or disconnected should only + have 1 input or output. */ + FMOD_ERR_FILE_BAD, /* Error loading file. */ + FMOD_ERR_FILE_COULDNOTSEEK, /* Couldn't perform seek operation. This is a + limitation of the medium (ie netstreams) or the + file format. */ + FMOD_ERR_FILE_DISKEJECTED, /* Media was ejected while reading. */ + FMOD_ERR_FILE_EOF, /* End of file unexpectedly reached while trying to read + essential data (truncated data?). */ + FMOD_ERR_FILE_NOTFOUND, /* File not found. */ + FMOD_ERR_FILE_UNWANTED, /* Unwanted file access occured. */ + FMOD_ERR_FORMAT, /* Unsupported file or audio format. */ + FMOD_ERR_HTTP, /* A HTTP error occurred. This is a catch-all for HTTP errors + not listed elsewhere. */ + FMOD_ERR_HTTP_ACCESS, /* The specified resource requires authentication or is + forbidden. */ + FMOD_ERR_HTTP_PROXY_AUTH, /* Proxy authentication is required to access the + specified resource. */ + FMOD_ERR_HTTP_SERVER_ERROR, /* A HTTP server error occurred. */ + FMOD_ERR_HTTP_TIMEOUT, /* The HTTP request timed out. */ + FMOD_ERR_INITIALIZATION, /* FMOD was not initialized correctly to support this + function. */ + FMOD_ERR_INITIALIZED, /* Cannot call this command after System::init. */ + FMOD_ERR_INTERNAL, /* An error occured that wasn't supposed to. Contact + support. */ + FMOD_ERR_INVALID_ADDRESS, /* On Xbox 360, this memory address passed to FMOD + must be physical, (ie allocated with + XPhysicalAlloc.) */ + FMOD_ERR_INVALID_FLOAT, /* Value passed in was a NaN, Inf or denormalized + float. */ + FMOD_ERR_INVALID_HANDLE, /* An invalid object handle was used. */ + FMOD_ERR_INVALID_PARAM, /* An invalid parameter was passed to this function. + */ + FMOD_ERR_INVALID_POSITION, /* An invalid seek position was passed to this + function. */ + FMOD_ERR_INVALID_SPEAKER, /* An invalid speaker was passed to this function + based on the current speaker mode. */ + FMOD_ERR_INVALID_SYNCPOINT, /* The syncpoint did not come from this sound + handle. */ + FMOD_ERR_INVALID_VECTOR, /* The vectors passed in are not unit length, or + perpendicular. */ + FMOD_ERR_MAXAUDIBLE, /* Reached maximum audible playback count for this + sound's soundgroup. */ + FMOD_ERR_MEMORY, /* Not enough memory or resources. */ + FMOD_ERR_MEMORY_CANTPOINT, /* Can't use FMOD_OPENMEMORY_POINT on non PCM + source data, or non mp3/xma/adpcm data if + FMOD_CREATECOMPRESSEDSAMPLE was used. */ + FMOD_ERR_MEMORY_SRAM, /* Not enough memory or resources on console sound ram. + */ + FMOD_ERR_NEEDS2D, /* Tried to call a command on a 3d sound when the command + was meant for 2d sound. */ + FMOD_ERR_NEEDS3D, /* Tried to call a command on a 2d sound when the command + was meant for 3d sound. */ + FMOD_ERR_NEEDSHARDWARE, /* Tried to use a feature that requires hardware + support. (ie trying to play a GCADPCM compressed + sound in software on Wii). */ + FMOD_ERR_NEEDSSOFTWARE, /* Tried to use a feature that requires the software + engine. Software engine has either been turned + off, or command was executed on a hardware channel + which does not support this feature. */ + FMOD_ERR_NET_CONNECT, /* Couldn't connect to the specified host. */ + FMOD_ERR_NET_SOCKET_ERROR, /* A socket error occurred. This is a catch-all + for socket-related errors not listed elsewhere. + */ + FMOD_ERR_NET_URL, /* The specified URL couldn't be resolved. */ + FMOD_ERR_NET_WOULD_BLOCK, /* Operation on a non-blocking socket could not + complete immediately. */ + FMOD_ERR_NOTREADY, /* Operation could not be performed because specified + sound/DSP connection is not ready. */ + FMOD_ERR_OUTPUT_ALLOCATED, /* Error initializing output device, but more + specifically, the output device is already in + use and cannot be reused. */ + FMOD_ERR_OUTPUT_CREATEBUFFER, /* Error creating hardware sound buffer. */ + FMOD_ERR_OUTPUT_DRIVERCALL, /* A call to a standard soundcard driver failed, + which could possibly mean a bug in the driver + or resources were missing or exhausted. */ + FMOD_ERR_OUTPUT_ENUMERATION, /* Error enumerating the available driver list. + List may be inconsistent due to a recent + device addition or removal. */ + FMOD_ERR_OUTPUT_FORMAT, /* Soundcard does not support the minimum features + needed for this soundsystem (16bit stereo output). + */ + FMOD_ERR_OUTPUT_INIT, /* Error initializing output device. */ + FMOD_ERR_OUTPUT_NOHARDWARE, /* FMOD_HARDWARE was specified but the sound card + does not have the resources necessary to play + it. */ + FMOD_ERR_OUTPUT_NOSOFTWARE, /* Attempted to create a software sound but no + software channels were specified in + System::init. */ + FMOD_ERR_PAN, /* Panning only works with mono or stereo sound sources. */ + FMOD_ERR_PLUGIN, /* An unspecified error has been returned from a 3rd party + plugin. */ + FMOD_ERR_PLUGIN_INSTANCES, /* The number of allowed instances of a plugin has + been exceeded. */ + FMOD_ERR_PLUGIN_MISSING, /* A requested output, dsp unit type or codec was not + available. */ + FMOD_ERR_PLUGIN_RESOURCE, /* A resource that the plugin requires cannot be + found. (ie the DLS file for MIDI playback or + other DLLs that it needs to load) */ + FMOD_ERR_PRELOADED, /* The specified sound is still in use by the event + system, call EventSystem::unloadFSB before trying to + release it. */ + FMOD_ERR_PROGRAMMERSOUND, /* The specified sound is still in use by the event + system, wait for the event which is using it + finish with it. */ + FMOD_ERR_RECORD, /* An error occured trying to initialize the recording + device. */ + FMOD_ERR_REVERB_INSTANCE, /* Specified instance in FMOD_REVERB_PROPERTIES + couldn't be set. Most likely because it is an + invalid instance number or the reverb doesnt + exist. */ + FMOD_ERR_SUBSOUND_ALLOCATED, /* This subsound is already being used by another + sound, you cannot have more than one parent to + a sound. Null out the other parent's entry + first. */ + FMOD_ERR_SUBSOUND_CANTMOVE, /* Shared subsounds cannot be replaced or moved + from their parent stream, such as when the + parent stream is an FSB file. */ + FMOD_ERR_SUBSOUND_MODE, /* The subsound's mode bits do not match with the + parent sound's mode bits. See documentation for + function that it was called with. */ + FMOD_ERR_SUBSOUNDS, /* The error occured because the sound referenced contains + subsounds when it shouldn't have, or it doesn't contain + subsounds when it should have. The operation may also + not be able to be performed on a parent sound, or a + parent sound was played without setting up a sentence + first. */ + FMOD_ERR_TAGNOTFOUND, /* The specified tag could not be found or there are no + tags. */ + FMOD_ERR_TOOMANYCHANNELS, /* The sound created exceeds the allowable input + channel count. This can be increased using the + maxinputchannels parameter in + System::setSoftwareFormat. */ + FMOD_ERR_UNIMPLEMENTED, /* Something in FMOD hasn't been implemented when it + should be! contact support! */ + FMOD_ERR_UNINITIALIZED, /* This command failed because System::init or + System::setDriver was not called. */ + FMOD_ERR_UNSUPPORTED, /* A command issued was not supported by this object. + Possibly a plugin without certain callbacks + specified. */ + FMOD_ERR_UPDATE, /* An error caused by System::update occured. */ + FMOD_ERR_VERSION, /* The version number of this file format is not supported. + */ - FMOD_ERR_EVENT_FAILED, /* An Event failed to be retrieved, most likely due to 'just fail' being specified as the max playbacks behavior. */ - FMOD_ERR_EVENT_INFOONLY, /* Can't execute this command on an EVENT_INFOONLY event. */ - FMOD_ERR_EVENT_INTERNAL, /* An error occured that wasn't supposed to. See debug log for reason. */ - FMOD_ERR_EVENT_MAXSTREAMS, /* Event failed because 'Max streams' was hit when FMOD_EVENT_INIT_FAIL_ON_MAXSTREAMS was specified. */ - FMOD_ERR_EVENT_MISMATCH, /* FSB mismatches the FEV it was compiled with, the stream/sample mode it was meant to be created with was different, or the FEV was built for a different platform. */ - FMOD_ERR_EVENT_NAMECONFLICT, /* A category with the same name already exists. */ - FMOD_ERR_EVENT_NOTFOUND, /* The requested event, event group, event category or event property could not be found. */ - FMOD_ERR_EVENT_NEEDSSIMPLE, /* Tried to call a function on a complex event that's only supported by simple events. */ - FMOD_ERR_EVENT_GUIDCONFLICT, /* An event with the same GUID already exists. */ - FMOD_ERR_EVENT_ALREADY_LOADED, /* The specified project or bank has already been loaded. Having multiple copies of the same project loaded simultaneously is forbidden. */ + FMOD_ERR_EVENT_FAILED, /* An Event failed to be retrieved, most likely due to + 'just fail' being specified as the max playbacks + behavior. */ + FMOD_ERR_EVENT_INFOONLY, /* Can't execute this command on an EVENT_INFOONLY + event. */ + FMOD_ERR_EVENT_INTERNAL, /* An error occured that wasn't supposed to. See + debug log for reason. */ + FMOD_ERR_EVENT_MAXSTREAMS, /* Event failed because 'Max streams' was hit when + FMOD_EVENT_INIT_FAIL_ON_MAXSTREAMS was + specified. */ + FMOD_ERR_EVENT_MISMATCH, /* FSB mismatches the FEV it was compiled with, the + stream/sample mode it was meant to be created with + was different, or the FEV was built for a + different platform. */ + FMOD_ERR_EVENT_NAMECONFLICT, /* A category with the same name already exists. + */ + FMOD_ERR_EVENT_NOTFOUND, /* The requested event, event group, event category + or event property could not be found. */ + FMOD_ERR_EVENT_NEEDSSIMPLE, /* Tried to call a function on a complex event + that's only supported by simple events. */ + FMOD_ERR_EVENT_GUIDCONFLICT, /* An event with the same GUID already exists. */ + FMOD_ERR_EVENT_ALREADY_LOADED, /* The specified project or bank has already + been loaded. Having multiple copies of the + same project loaded simultaneously is + forbidden. */ - FMOD_ERR_MUSIC_UNINITIALIZED, /* Music system is not initialized probably because no music data is loaded. */ - FMOD_ERR_MUSIC_NOTFOUND, /* The requested music entity could not be found. */ - FMOD_ERR_MUSIC_NOCALLBACK, /* The music callback is required, but it has not been set. */ + FMOD_ERR_MUSIC_UNINITIALIZED, /* Music system is not initialized probably + because no music data is loaded. */ + FMOD_ERR_MUSIC_NOTFOUND, /* The requested music entity could not be found. */ + FMOD_ERR_MUSIC_NOCALLBACK, /* The music callback is required, but it has not + been set. */ - FMOD_RESULT_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ + FMOD_RESULT_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ } FMOD_RESULT; /*$ fmod result end $*/ - /* -[STRUCTURE] +[STRUCTURE] [ - [DESCRIPTION] + [DESCRIPTION] Structure describing a point in 3D space. [REMARKS] FMOD uses a left handed co-ordinate system by default.
- To use a right handed co-ordinate system specify FMOD_INIT_3D_RIGHTHANDED from FMOD_INITFLAGS in System::init. + To use a right handed co-ordinate system specify FMOD_INIT_3D_RIGHTHANDED +from FMOD_INITFLAGS in System::init. [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] System::set3DListenerAttributes System::get3DListenerAttributes Channel::set3DAttributes @@ -235,110 +354,135 @@ typedef enum FMOD_INITFLAGS ] */ -typedef struct -{ - float x; /* X co-ordinate in 3D space. */ - float y; /* Y co-ordinate in 3D space. */ - float z; /* Z co-ordinate in 3D space. */ +typedef struct { + float x; /* X co-ordinate in 3D space. */ + float y; /* Y co-ordinate in 3D space. */ + float z; /* Z co-ordinate in 3D space. */ } FMOD_VECTOR; /* -[STRUCTURE] +[STRUCTURE] [ - [DESCRIPTION] + [DESCRIPTION] Structure describing a globally unique identifier. [REMARKS] [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] System::getDriverInfo ] */ -typedef struct -{ - unsigned int Data1; /* Specifies the first 8 hexadecimal digits of the GUID */ - unsigned short Data2; /* Specifies the first group of 4 hexadecimal digits. */ - unsigned short Data3; /* Specifies the second group of 4 hexadecimal digits. */ - unsigned char Data4[8]; /* Array of 8 bytes. The first 2 bytes contain the third group of 4 hexadecimal digits. The remaining 6 bytes contain the final 12 hexadecimal digits. */ +typedef struct { + unsigned int Data1; /* Specifies the first 8 hexadecimal digits of the GUID */ + unsigned short + Data2; /* Specifies the first group of 4 hexadecimal digits. */ + unsigned short + Data3; /* Specifies the second group of 4 hexadecimal digits. */ + unsigned char Data4[8]; /* Array of 8 bytes. The first 2 bytes contain the + third group of 4 hexadecimal digits. The remaining + 6 bytes contain the final 12 hexadecimal digits. */ } FMOD_GUID; /* -[STRUCTURE] +[STRUCTURE] [ [DESCRIPTION] - Structure that is passed into FMOD_FILE_ASYNCREADCALLBACK. Use the information in this structure to perform + Structure that is passed into FMOD_FILE_ASYNCREADCALLBACK. Use the +information in this structure to perform [REMARKS] - Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
- Members marked with [w] mean the variable can be written to. The user can set the value.
-
- Instructions: write to 'buffer', and 'bytesread' BEFORE setting 'result'.
- As soon as result is set, FMOD will asynchronously continue internally using the data provided in this structure.
-
- Set 'result' to the result expected from a normal file read callback.
- If the read was successful, set it to FMOD_OK.
- If it read some data but hit the end of the file, set it to FMOD_ERR_FILE_EOF.
- If a bad error occurred, return FMOD_ERR_FILE_BAD
- If a disk was ejected, return FMOD_ERR_FILE_DISKEJECTED.
+ Members marked with [r] mean the variable is modified by FMOD and is for +reading purposes only. Do not change this value.
Members marked with [w] +mean the variable can be written to. The user can set the value.

+ Instructions: write to 'buffer', and 'bytesread' BEFORE setting +'result'.
As soon as result is set, FMOD will asynchronously continue +internally using the data provided in this structure.

Set 'result' to +the result expected from a normal file read callback.
If the read was +successful, set it to FMOD_OK.
If it read some data but hit the end of the +file, set it to FMOD_ERR_FILE_EOF.
If a bad error occurred, return +FMOD_ERR_FILE_BAD
If a disk was ejected, return +FMOD_ERR_FILE_DISKEJECTED.
[PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] FMOD_FILE_ASYNCREADCALLBACK FMOD_FILE_ASYNCCANCELCALLBACK ] */ -struct FMOD_ASYNCREADINFO -{ - void *handle; /* [r] The file handle that was filled out in the open callback. */ - unsigned int offset; /* [r] Seek position, make sure you read from this file offset. */ - unsigned int sizebytes; /* [r] how many bytes requested for read. */ - int priority; /* [r] 0 = low importance. 100 = extremely important (ie 'must read now or stuttering may occur') */ +struct FMOD_ASYNCREADINFO { + void *handle; /* [r] The file handle that was filled out in the open callback. + */ + unsigned int + offset; /* [r] Seek position, make sure you read from this file offset. */ + unsigned int sizebytes; /* [r] how many bytes requested for read. */ + int priority; /* [r] 0 = low importance. 100 = extremely important (ie 'must + read now or stuttering may occur') */ - void *buffer; /* [w] Buffer to read file data into. */ - unsigned int bytesread; /* [w] Fill this in before setting result code to tell FMOD how many bytes were read. */ - FMOD_RESULT result; /* [r/w] Result code, FMOD_OK tells the system it is ready to consume the data. Set this last! Default value = FMOD_ERR_NOTREADY. */ + void *buffer; /* [w] Buffer to read file data into. */ + unsigned int bytesread; /* [w] Fill this in before setting result code to tell + FMOD how many bytes were read. */ + FMOD_RESULT result; /* [r/w] Result code, FMOD_OK tells the system it is ready + to consume the data. Set this last! Default value = + FMOD_ERR_NOTREADY. */ - void *userdata; /* [r] User data pointer. */ + void *userdata; /* [r] User data pointer. */ - const void (*done)(FMOD_ASYNCREADINFO *info, FMOD_RESULT result); /* FMOD file system wake up function. Use instead of 'result' with FMOD_INIT_ASYNCREAD_FAST to get semaphore based performance improvement. Call this when user file read is finished. Pass result of file read as a parameter. */ + const void (*done)( + FMOD_ASYNCREADINFO *info, + FMOD_RESULT result); /* FMOD file system wake up function. Use instead of + 'result' with FMOD_INIT_ASYNCREAD_FAST to get + semaphore based performance improvement. Call + this when user file read is finished. Pass result + of file read as a parameter. */ }; - /* [ENUM] [ - [DESCRIPTION] - These output types are used with System::setOutput / System::getOutput, to choose which output method to use. - + [DESCRIPTION] + These output types are used with System::setOutput / System::getOutput, to +choose which output method to use. + [REMARKS] - To pass information to the driver when initializing fmod use the extradriverdata parameter in System::init for the following reasons.
-
  • FMOD_OUTPUTTYPE_WAVWRITER - extradriverdata is a pointer to a char * filename that the wav writer will output to. -
  • FMOD_OUTPUTTYPE_WAVWRITER_NRT - extradriverdata is a pointer to a char * filename that the wav writer will output to. -
  • FMOD_OUTPUTTYPE_DSOUND - extradriverdata is a pointer to a HWND so that FMOD can set the focus on the audio for a particular window. -
  • FMOD_OUTPUTTYPE_PS3 - extradriverdata is a pointer to a FMOD_PS3_EXTRADRIVERDATA struct. This can be found in fmodps3.h. -
  • FMOD_OUTPUTTYPE_GC - extradriverdata is a pointer to a FMOD_GC_INFO struct. This can be found in fmodgc.h. -
  • FMOD_OUTPUTTYPE_WII - extradriverdata is a pointer to a FMOD_WII_INFO struct. This can be found in fmodwii.h. -
  • FMOD_OUTPUTTYPE_ALSA - extradriverdata is a pointer to a FMOD_LINUX_EXTRADRIVERDATA struct. This can be found in fmodlinux.h.
    -
  • FMOD_OUTPUTTYPE_PULSEAUDIO - extradriverdata is a const char * representing the name of the application to appear in PulseAudio mixer GUIs.
    + To pass information to the driver when initializing fmod use the +extradriverdata parameter in System::init for the following reasons.
    +
  • FMOD_OUTPUTTYPE_WAVWRITER - extradriverdata is a pointer to a char * +filename that the wav writer will output to.
  • FMOD_OUTPUTTYPE_WAVWRITER_NRT - +extradriverdata is a pointer to a char * filename that the wav writer will +output to.
  • FMOD_OUTPUTTYPE_DSOUND - extradriverdata is a pointer to a HWND +so that FMOD can set the focus on the audio for a particular window. +
  • FMOD_OUTPUTTYPE_PS3 - extradriverdata is a pointer to a +FMOD_PS3_EXTRADRIVERDATA struct. This can be found in fmodps3.h. +
  • FMOD_OUTPUTTYPE_GC - extradriverdata is a pointer to a FMOD_GC_INFO +struct. This can be found in fmodgc.h.
  • FMOD_OUTPUTTYPE_WII - extradriverdata +is a pointer to a FMOD_WII_INFO struct. This can be found in fmodwii.h. +
  • FMOD_OUTPUTTYPE_ALSA - extradriverdata is a pointer to a +FMOD_LINUX_EXTRADRIVERDATA struct. This can be found in fmodlinux.h.
    +
  • FMOD_OUTPUTTYPE_PULSEAUDIO - extradriverdata is a const char * +representing the name of the application to appear in PulseAudio mixer GUIs.

    - Currently these are the only FMOD drivers that take extra information. Other unknown plugins may have different requirements. -

    - Note! If FMOD_OUTPUTTYPE_WAVWRITER_NRT or FMOD_OUTPUTTYPE_NOSOUND_NRT are used, and if the System::update function is being called - very quickly (ie for a non realtime decode) it may be being called too quickly for the FMOD streamer thread to respond to. - The result will be a skipping/stuttering output in the captured audio.
    -
    - To remedy this, disable the FMOD Ex streamer thread, and use FMOD_INIT_STREAM_FROM_UPDATE to avoid skipping in the output stream, - as it will lock the mixer and the streamer together in the same thread. + Currently these are the only FMOD drivers that take extra information. Other +unknown plugins may have different requirements.

    Note! If +FMOD_OUTPUTTYPE_WAVWRITER_NRT or FMOD_OUTPUTTYPE_NOSOUND_NRT are used, and if +the System::update function is being called very quickly (ie for a non realtime +decode) it may be being called too quickly for the FMOD streamer thread to +respond to. The result will be a skipping/stuttering output in the captured +audio.

    To remedy this, disable the FMOD Ex streamer thread, and use +FMOD_INIT_STREAM_FROM_UPDATE to avoid skipping in the output stream, as it will +lock the mixer and the streamer together in the same thread. [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] System::setOutput System::getOutput System::setSoftwareFormat @@ -348,172 +492,256 @@ struct FMOD_ASYNCREADINFO FMOD_INITFLAGS ] */ -typedef enum -{ - FMOD_OUTPUTTYPE_AUTODETECT, /* Picks the best output mode for the platform. This is the default. */ - - FMOD_OUTPUTTYPE_UNKNOWN, /* All - 3rd party plugin, unknown. This is for use with System::getOutput only. */ - FMOD_OUTPUTTYPE_NOSOUND, /* All - All calls in this mode succeed but make no sound. */ - FMOD_OUTPUTTYPE_WAVWRITER, /* All - Writes output to fmodoutput.wav by default. Use the 'extradriverdata' parameter in System::init, by simply passing the filename as a string, to set the wav filename. */ - FMOD_OUTPUTTYPE_NOSOUND_NRT, /* All - Non-realtime version of FMOD_OUTPUTTYPE_NOSOUND. User can drive mixer with System::update at whatever rate they want. */ - FMOD_OUTPUTTYPE_WAVWRITER_NRT, /* All - Non-realtime version of FMOD_OUTPUTTYPE_WAVWRITER. User can drive mixer with System::update at whatever rate they want. */ - - FMOD_OUTPUTTYPE_DSOUND, /* Win32/Win64 - DirectSound output. (Default on Windows XP and below) */ - FMOD_OUTPUTTYPE_WINMM, /* Win32/Win64 - Windows Multimedia output. */ - FMOD_OUTPUTTYPE_WASAPI, /* Win32 - Windows Audio Session API. (Default on Windows Vista and above) */ - FMOD_OUTPUTTYPE_ASIO, /* Win32 - Low latency ASIO 2.0 driver. */ - FMOD_OUTPUTTYPE_OSS, /* Linux/Linux64 - Open Sound System output. (Default on Linux, third preference) */ - FMOD_OUTPUTTYPE_ALSA, /* Linux/Linux64 - Advanced Linux Sound Architecture output. (Default on Linux, second preference if available) */ - FMOD_OUTPUTTYPE_ESD, /* Linux/Linux64 - Enlightment Sound Daemon output. */ - FMOD_OUTPUTTYPE_PULSEAUDIO, /* Linux/Linux64 - PulseAudio output. (Default on Linux, first preference if available) */ - FMOD_OUTPUTTYPE_COREAUDIO, /* Mac - Macintosh CoreAudio output. (Default on Mac) */ - FMOD_OUTPUTTYPE_XBOX360, /* Xbox 360 - Native Xbox360 output. (Default on Xbox 360) */ - FMOD_OUTPUTTYPE_PSP, /* PSP - Native PSP output. (Default on PSP) */ - FMOD_OUTPUTTYPE_PS3, /* PS3 - Native PS3 output. (Default on PS3) */ - FMOD_OUTPUTTYPE_NGP, /* NGP - Native NGP output. (Default on NGP) */ - FMOD_OUTPUTTYPE_WII, /* Wii - Native Wii output. (Default on Wii) */ - FMOD_OUTPUTTYPE_3DS, /* 3DS - Native 3DS output (Default on 3DS) */ - FMOD_OUTPUTTYPE_AUDIOTRACK, /* Android - Java Audio Track output. (Default on Android 2.2 and below) */ - FMOD_OUTPUTTYPE_OPENSL, /* Android - OpenSL ES output. (Default on Android 2.3 and above) */ - FMOD_OUTPUTTYPE_NACL, /* Native Client - Native Client output. (Default on Native Client) */ - FMOD_OUTPUTTYPE_WIIU, /* Wii U - Native Wii U output. (Default on Wii U) */ - FMOD_OUTPUTTYPE_ASOUND, /* BlackBerry - Native BlackBerry asound output. (Default on BlackBerry) */ - FMOD_OUTPUTTYPE_AUDIOOUT, /* Orbis - Audio Out output. (Default on Orbis) */ - FMOD_OUTPUTTYPE_XAUDIO, /* Durango - XAudio2 output. */ +typedef enum { + FMOD_OUTPUTTYPE_AUTODETECT, /* Picks the best output mode for the platform. + This is the default. */ - FMOD_OUTPUTTYPE_MAX, /* Maximum number of output types supported. */ - FMOD_OUTPUTTYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ + FMOD_OUTPUTTYPE_UNKNOWN, /* All - 3rd party plugin, unknown. This + is for use with System::getOutput only. */ + FMOD_OUTPUTTYPE_NOSOUND, /* All - All calls in this mode succeed + but make no sound. */ + FMOD_OUTPUTTYPE_WAVWRITER, /* All - Writes output to + fmodoutput.wav by default. Use the + 'extradriverdata' parameter in System::init, by + simply passing the filename as a string, to set + the wav filename. */ + FMOD_OUTPUTTYPE_NOSOUND_NRT, /* All - Non-realtime version of + FMOD_OUTPUTTYPE_NOSOUND. User can drive mixer + with System::update at whatever rate they + want. */ + FMOD_OUTPUTTYPE_WAVWRITER_NRT, /* All - Non-realtime version of + FMOD_OUTPUTTYPE_WAVWRITER. User can drive + mixer with System::update at whatever rate + they want. */ + + FMOD_OUTPUTTYPE_DSOUND, /* Win32/Win64 - DirectSound output. (Default on + Windows XP and below) */ + FMOD_OUTPUTTYPE_WINMM, /* Win32/Win64 - Windows Multimedia output. */ + FMOD_OUTPUTTYPE_WASAPI, /* Win32 - Windows Audio Session API. + (Default on Windows Vista and above) */ + FMOD_OUTPUTTYPE_ASIO, /* Win32 - Low latency ASIO 2.0 driver. */ + FMOD_OUTPUTTYPE_OSS, /* Linux/Linux64 - Open Sound System output. (Default + on Linux, third preference) */ + FMOD_OUTPUTTYPE_ALSA, /* Linux/Linux64 - Advanced Linux Sound Architecture + output. (Default on Linux, second preference if + available) */ + FMOD_OUTPUTTYPE_ESD, /* Linux/Linux64 - Enlightment Sound Daemon output. */ + FMOD_OUTPUTTYPE_PULSEAUDIO, /* Linux/Linux64 - PulseAudio output. (Default + on Linux, first preference if available) */ + FMOD_OUTPUTTYPE_COREAUDIO, /* Mac - Macintosh CoreAudio output. + (Default on Mac) */ + FMOD_OUTPUTTYPE_XBOX360, /* Xbox 360 - Native Xbox360 output. + (Default on Xbox 360) */ + FMOD_OUTPUTTYPE_PSP, /* PSP - Native PSP output. (Default on + PSP) */ + FMOD_OUTPUTTYPE_PS3, /* PS3 - Native PS3 output. (Default on + PS3) */ + FMOD_OUTPUTTYPE_NGP, /* NGP - Native NGP output. (Default on + NGP) */ + FMOD_OUTPUTTYPE_WII, /* Wii - Native Wii output. (Default on Wii) */ + FMOD_OUTPUTTYPE_3DS, /* 3DS - Native 3DS output (Default on 3DS) + */ + FMOD_OUTPUTTYPE_AUDIOTRACK, /* Android - Java Audio Track output. + (Default on Android 2.2 and below) */ + FMOD_OUTPUTTYPE_OPENSL, /* Android - OpenSL ES output. (Default on + Android 2.3 and above) */ + FMOD_OUTPUTTYPE_NACL, /* Native Client - Native Client output. (Default on + Native Client) */ + FMOD_OUTPUTTYPE_WIIU, /* Wii U - Native Wii U output. (Default on + Wii U) */ + FMOD_OUTPUTTYPE_ASOUND, /* BlackBerry - Native BlackBerry asound output. + (Default on BlackBerry) */ + FMOD_OUTPUTTYPE_AUDIOOUT, /* Orbis - Audio Out output. (Default on + Orbis) */ + FMOD_OUTPUTTYPE_XAUDIO, /* Durango - XAudio2 output. */ + + FMOD_OUTPUTTYPE_MAX, /* Maximum number of output types supported. */ + FMOD_OUTPUTTYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ } FMOD_OUTPUTTYPE; - /* -[DEFINE] +[DEFINE] [ [NAME] FMOD_CAPS - [DESCRIPTION] - Bit fields to use with System::getDriverCaps to determine the capabilities of a card / output device. + [DESCRIPTION] + Bit fields to use with System::getDriverCaps to determine the capabilities +of a card / output device. [REMARKS] - It is important to check FMOD_CAPS_HARDWARE_EMULATED on windows machines, to then adjust System::setDSPBufferSize to (1024, 10) to compensate for the higher latency. + It is important to check FMOD_CAPS_HARDWARE_EMULATED on windows machines, to +then adjust System::setDSPBufferSize to (1024, 10) to compensate for the higher +latency. [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] System::getDriverCaps System::setDSPBufferSize ] */ -#define FMOD_CAPS_NONE 0x00000000 /* Device has no special capabilities. */ -#define FMOD_CAPS_HARDWARE 0x00000001 /* Device supports hardware mixing. */ -#define FMOD_CAPS_HARDWARE_EMULATED 0x00000002 /* User has device set to 'Hardware acceleration = off' in control panel, and now extra 200ms latency is incurred. */ -#define FMOD_CAPS_OUTPUT_MULTICHANNEL 0x00000004 /* Device can do multichannel output, ie greater than 2 channels. */ -#define FMOD_CAPS_OUTPUT_FORMAT_PCM8 0x00000008 /* Device can output to 8bit integer PCM. */ -#define FMOD_CAPS_OUTPUT_FORMAT_PCM16 0x00000010 /* Device can output to 16bit integer PCM. */ -#define FMOD_CAPS_OUTPUT_FORMAT_PCM24 0x00000020 /* Device can output to 24bit integer PCM. */ -#define FMOD_CAPS_OUTPUT_FORMAT_PCM32 0x00000040 /* Device can output to 32bit integer PCM. */ -#define FMOD_CAPS_OUTPUT_FORMAT_PCMFLOAT 0x00000080 /* Device can output to 32bit floating point PCM. */ -#define FMOD_CAPS_REVERB_LIMITED 0x00002000 /* Device supports some form of limited hardware reverb, maybe parameterless and only selectable by environment. */ -#define FMOD_CAPS_LOOPBACK 0x00004000 /* Device is a loopback recording device */ +#define FMOD_CAPS_NONE 0x00000000 /* Device has no special capabilities. */ +#define FMOD_CAPS_HARDWARE 0x00000001 /* Device supports hardware mixing. */ +#define FMOD_CAPS_HARDWARE_EMULATED \ + 0x00000002 /* User has device set to 'Hardware acceleration = off' in \ + control panel, and now extra 200ms latency is incurred. */ +#define FMOD_CAPS_OUTPUT_MULTICHANNEL \ + 0x00000004 /* Device can do multichannel output, ie greater than 2 channels. \ + */ +#define FMOD_CAPS_OUTPUT_FORMAT_PCM8 \ + 0x00000008 /* Device can output to 8bit integer PCM. */ +#define FMOD_CAPS_OUTPUT_FORMAT_PCM16 \ + 0x00000010 /* Device can output to 16bit integer PCM. */ +#define FMOD_CAPS_OUTPUT_FORMAT_PCM24 \ + 0x00000020 /* Device can output to 24bit integer PCM. */ +#define FMOD_CAPS_OUTPUT_FORMAT_PCM32 \ + 0x00000040 /* Device can output to 32bit integer PCM. */ +#define FMOD_CAPS_OUTPUT_FORMAT_PCMFLOAT \ + 0x00000080 /* Device can output to 32bit floating point PCM. */ +#define FMOD_CAPS_REVERB_LIMITED \ + 0x00002000 /* Device supports some form of limited hardware reverb, maybe \ + parameterless and only selectable by environment. */ +#define FMOD_CAPS_LOOPBACK \ + 0x00004000 /* Device is a loopback recording device */ /* [DEFINE_END] */ /* -[DEFINE] +[DEFINE] [ [NAME] FMOD_DEBUGLEVEL - [DESCRIPTION] - Bit fields to use with FMOD::Debug_SetLevel / FMOD::Debug_GetLevel to control the level of tty debug output with logging versions of FMOD (fmodL). + [DESCRIPTION] + Bit fields to use with FMOD::Debug_SetLevel / FMOD::Debug_GetLevel to +control the level of tty debug output with logging versions of FMOD (fmodL). [REMARKS] [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] - Debug_SetLevel + Debug_SetLevel Debug_GetLevel ] */ -#define FMOD_DEBUG_LEVEL_NONE 0x00000000 -#define FMOD_DEBUG_LEVEL_LOG 0x00000001 /* Will display generic logging messages. */ -#define FMOD_DEBUG_LEVEL_ERROR 0x00000002 /* Will display errors. */ -#define FMOD_DEBUG_LEVEL_WARNING 0x00000004 /* Will display warnings that are not fatal. */ -#define FMOD_DEBUG_LEVEL_HINT 0x00000008 /* Will hint to you if there is something possibly better you could be doing. */ -#define FMOD_DEBUG_LEVEL_ALL 0x000000FF -#define FMOD_DEBUG_TYPE_MEMORY 0x00000100 /* Show FMOD memory related logging messages. */ -#define FMOD_DEBUG_TYPE_THREAD 0x00000200 /* Show FMOD thread related logging messages. */ -#define FMOD_DEBUG_TYPE_FILE 0x00000400 /* Show FMOD file system related logging messages. */ -#define FMOD_DEBUG_TYPE_NET 0x00000800 /* Show FMOD network related logging messages. */ -#define FMOD_DEBUG_TYPE_EVENT 0x00001000 /* Show FMOD Event related logging messages. */ -#define FMOD_DEBUG_TYPE_ALL 0x0000FFFF -#define FMOD_DEBUG_DISPLAY_TIMESTAMPS 0x01000000 /* Display the timestamp of the log entry in milliseconds. */ -#define FMOD_DEBUG_DISPLAY_LINENUMBERS 0x02000000 /* Display the FMOD Ex source code line numbers, for debugging purposes. */ -#define FMOD_DEBUG_DISPLAY_COMPRESS 0x04000000 /* If a message is repeated more than 5 times it will stop displaying it and instead display the number of times the message was logged. */ -#define FMOD_DEBUG_DISPLAY_THREAD 0x08000000 /* Display the thread ID of the calling function that caused this log entry to appear. */ -#define FMOD_DEBUG_DISPLAY_ALL 0x0F000000 -#define FMOD_DEBUG_ALL 0xFFFFFFFF +#define FMOD_DEBUG_LEVEL_NONE 0x00000000 +#define FMOD_DEBUG_LEVEL_LOG \ + 0x00000001 /* Will display generic logging messages. */ +#define FMOD_DEBUG_LEVEL_ERROR 0x00000002 /* Will display errors. */ +#define FMOD_DEBUG_LEVEL_WARNING \ + 0x00000004 /* Will display warnings that are not fatal. */ +#define FMOD_DEBUG_LEVEL_HINT \ + 0x00000008 /* Will hint to you if there is something possibly better you \ + could be doing. */ +#define FMOD_DEBUG_LEVEL_ALL 0x000000FF +#define FMOD_DEBUG_TYPE_MEMORY \ + 0x00000100 /* Show FMOD memory related logging messages. */ +#define FMOD_DEBUG_TYPE_THREAD \ + 0x00000200 /* Show FMOD thread related logging messages. */ +#define FMOD_DEBUG_TYPE_FILE \ + 0x00000400 /* Show FMOD file system related logging messages. */ +#define FMOD_DEBUG_TYPE_NET \ + 0x00000800 /* Show FMOD network related logging messages. */ +#define FMOD_DEBUG_TYPE_EVENT \ + 0x00001000 /* Show FMOD Event related logging messages. */ +#define FMOD_DEBUG_TYPE_ALL 0x0000FFFF +#define FMOD_DEBUG_DISPLAY_TIMESTAMPS \ + 0x01000000 /* Display the timestamp of the log entry in milliseconds. */ +#define FMOD_DEBUG_DISPLAY_LINENUMBERS \ + 0x02000000 /* Display the FMOD Ex source code line numbers, for debugging \ + purposes. */ +#define FMOD_DEBUG_DISPLAY_COMPRESS \ + 0x04000000 /* If a message is repeated more than 5 times it will stop \ + displaying it and instead display the number of times the \ + message was logged. */ +#define FMOD_DEBUG_DISPLAY_THREAD \ + 0x08000000 /* Display the thread ID of the calling function that caused this \ + log entry to appear. */ +#define FMOD_DEBUG_DISPLAY_ALL 0x0F000000 +#define FMOD_DEBUG_ALL 0xFFFFFFFF /* [DEFINE_END] */ - /* -[DEFINE] +[DEFINE] [ [NAME] FMOD_MEMORY_TYPE - [DESCRIPTION] - Bit fields for memory allocation type being passed into FMOD memory callbacks. + [DESCRIPTION] + Bit fields for memory allocation type being passed into FMOD memory +callbacks. [REMARKS] - Remember this is a bitfield. You may get more than 1 bit set (ie physical + persistent) so do not simply switch on the types! You must check each bit individually or clear out the bits that you do not want within the callback.
    - Bits can be excluded if you want during Memory_Initialize so that you never get them. + Remember this is a bitfield. You may get more than 1 bit set (ie physical + +persistent) so do not simply switch on the types! You must check each bit +individually or clear out the bits that you do not want within the callback.
    + Bits can be excluded if you want during Memory_Initialize so that you never +get them. [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] FMOD_MEMORY_ALLOCCALLBACK FMOD_MEMORY_REALLOCCALLBACK FMOD_MEMORY_FREECALLBACK Memory_Initialize - + ] */ -#define FMOD_MEMORY_NORMAL 0x00000000 /* Standard memory. */ -#define FMOD_MEMORY_STREAM_FILE 0x00000001 /* Stream file buffer, size controllable with System::setStreamBufferSize. */ -#define FMOD_MEMORY_STREAM_DECODE 0x00000002 /* Stream decode buffer, size controllable with FMOD_CREATESOUNDEXINFO::decodebuffersize. */ -#define FMOD_MEMORY_SAMPLEDATA 0x00000004 /* Sample data buffer. Raw audio data, usually PCM/MPEG/ADPCM/XMA data. */ -#define FMOD_MEMORY_DSP_OUTPUTBUFFER 0x00000008 /* DSP memory block allocated when more than 1 output exists on a DSP node. */ -#define FMOD_MEMORY_XBOX360_PHYSICAL 0x00100000 /* Requires XPhysicalAlloc / XPhysicalFree. */ -#define FMOD_MEMORY_PERSISTENT 0x00200000 /* Persistent memory. Memory will be freed when System::release is called. */ -#define FMOD_MEMORY_SECONDARY 0x00400000 /* Secondary memory. Allocation should be in secondary memory. For example RSX on the PS3. */ -#define FMOD_MEMORY_ALL 0xFFFFFFFF +#define FMOD_MEMORY_NORMAL 0x00000000 /* Standard memory. */ +#define FMOD_MEMORY_STREAM_FILE \ + 0x00000001 /* Stream file buffer, size controllable with \ + System::setStreamBufferSize. */ +#define FMOD_MEMORY_STREAM_DECODE \ + 0x00000002 /* Stream decode buffer, size controllable with \ + FMOD_CREATESOUNDEXINFO::decodebuffersize. */ +#define FMOD_MEMORY_SAMPLEDATA \ + 0x00000004 /* Sample data buffer. Raw audio data, usually \ + PCM/MPEG/ADPCM/XMA data. */ +#define FMOD_MEMORY_DSP_OUTPUTBUFFER \ + 0x00000008 /* DSP memory block allocated when more than 1 output exists on a \ + DSP node. */ +#define FMOD_MEMORY_XBOX360_PHYSICAL \ + 0x00100000 /* Requires XPhysicalAlloc / XPhysicalFree. */ +#define FMOD_MEMORY_PERSISTENT \ + 0x00200000 /* Persistent memory. Memory will be freed when System::release \ + is called. */ +#define FMOD_MEMORY_SECONDARY \ + 0x00400000 /* Secondary memory. Allocation should be in secondary memory. \ + For example RSX on the PS3. */ +#define FMOD_MEMORY_ALL 0xFFFFFFFF /* [DEFINE_END] */ - /* [ENUM] [ - [DESCRIPTION] - These are speaker types defined for use with the System::setSpeakerMode or System::getSpeakerMode command. + [DESCRIPTION] + These are speaker types defined for use with the System::setSpeakerMode or +System::getSpeakerMode command. [REMARKS] - These are important notes on speaker modes in regards to sounds created with FMOD_SOFTWARE.
    - Note below the phrase 'sound channels' is used. These are the subchannels inside a sound, they are not related and - have nothing to do with the FMOD class "Channel".
    - For example a mono sound has 1 sound channel, a stereo sound has 2 sound channels, and an AC3 or 6 channel wav file have 6 "sound channels".
    -
    - FMOD_SPEAKERMODE_RAW
    + These are important notes on speaker modes in regards to sounds created with +FMOD_SOFTWARE.
    Note below the phrase 'sound channels' is used. These are +the subchannels inside a sound, they are not related and have nothing to do with +the FMOD class "Channel".
    For example a mono sound has 1 sound channel, a +stereo sound has 2 sound channels, and an AC3 or 6 channel wav file have 6 +"sound channels".

    FMOD_SPEAKERMODE_RAW
    ---------------------
    - This mode is for output devices that are not specifically mono/stereo/quad/surround/5.1 or 7.1, but are multichannel.
    - Use System::setSoftwareFormat to specify the number of speakers you want to address, otherwise it will default to 2 (stereo).
    - Sound channels map to speakers sequentially, so a mono sound maps to output speaker 0, stereo sound maps to output speaker 0 & 1.
    - The user assumes knowledge of the speaker order. FMOD_SPEAKER enumerations may not apply, so raw channel indices should be used.
    - Multichannel sounds map input channels to output channels 1:1.
    + This mode is for output devices that are not specifically +mono/stereo/quad/surround/5.1 or 7.1, but are multichannel.
    Use +System::setSoftwareFormat to specify the number of speakers you want to address, +otherwise it will default to 2 (stereo).
    Sound channels map to speakers +sequentially, so a mono sound maps to output speaker 0, stereo sound maps to +output speaker 0 & 1.
    The user assumes knowledge of the speaker order. +FMOD_SPEAKER enumerations may not apply, so raw channel indices should be +used.
    Multichannel sounds map input channels to output channels 1:1.
    Channel::setPan and Channel::setSpeakerMix do not work.
    Speaker levels must be manually set with Channel::setSpeakerLevels.

    @@ -521,93 +749,98 @@ typedef enum ---------------------
    This mode is for a 1 speaker arrangement.
    Panning does not work in this speaker mode.
    - Mono, stereo and multichannel sounds have each sound channel played on the one speaker unity.
    - Mix behavior for multichannel sounds can be set with Channel::setSpeakerLevels.
    - Channel::setSpeakerMix does not work.
    -
    + Mono, stereo and multichannel sounds have each sound channel played on the +one speaker unity.
    Mix behavior for multichannel sounds can be set with +Channel::setSpeakerLevels.
    Channel::setSpeakerMix does not work.

    FMOD_SPEAKERMODE_STEREO
    -----------------------
    - This mode is for 2 speaker arrangements that have a left and right speaker.
    -
  • Mono sounds default to an even distribution between left and right. They can be panned with Channel::setPan.
    -
  • Stereo sounds default to the middle, or full left in the left speaker and full right in the right speaker. -
  • They can be cross faded with Channel::setPan.
    -
  • Multichannel sounds have each sound channel played on each speaker at unity.
    -
  • Mix behavior for multichannel sounds can be set with Channel::setSpeakerLevels.
    -
  • Channel::setSpeakerMix works but only front left and right parameters are used, the rest are ignored.
    -
    - FMOD_SPEAKERMODE_QUAD
    + This mode is for 2 speaker arrangements that have a left and right +speaker.
  • Mono sounds default to an even distribution between left and +right. They can be panned with Channel::setPan.
  • Stereo sounds default +to the middle, or full left in the left speaker and full right in the right +speaker.
  • They can be cross faded with Channel::setPan.
  • Multichannel +sounds have each sound channel played on each speaker at unity.
  • Mix +behavior for multichannel sounds can be set with Channel::setSpeakerLevels.
    +
  • Channel::setSpeakerMix works but only front left and right parameters +are used, the rest are ignored.

    FMOD_SPEAKERMODE_QUAD
    ------------------------
    - This mode is for 4 speaker arrangements that have a front left, front right, rear left and a rear right speaker.
    -
  • Mono sounds default to an even distribution between front left and front right. They can be panned with Channel::setPan.
    -
  • Stereo sounds default to the left sound channel played on the front left, and the right sound channel played on the front right.
    + This mode is for 4 speaker arrangements that have a front left, front right, +rear left and a rear right speaker.
  • Mono sounds default to an even +distribution between front left and front right. They can be panned with +Channel::setPan.
  • Stereo sounds default to the left sound channel played +on the front left, and the right sound channel played on the front right.
  • They can be cross faded with Channel::setPan.
    -
  • Multichannel sounds default to all of their sound channels being played on each speaker in order of input.
    -
  • Mix behavior for multichannel sounds can be set with Channel::setSpeakerLevels.
    -
  • Channel::setSpeakerMix works but side left, side right, center and lfe are ignored.
    -
    +
  • Multichannel sounds default to all of their sound channels being played +on each speaker in order of input.
  • Mix behavior for multichannel sounds +can be set with Channel::setSpeakerLevels.
  • Channel::setSpeakerMix works +but side left, side right, center and lfe are ignored.

    FMOD_SPEAKERMODE_SURROUND
    ------------------------
    - This mode is for 5 speaker arrangements that have a left/right/center/rear left/rear right.
    -
  • Mono sounds default to the center speaker. They can be panned with Channel::setPan.
    -
  • Stereo sounds default to the left sound channel played on the front left, and the right sound channel played on the front right. -
  • They can be cross faded with Channel::setPan.
    -
  • Multichannel sounds default to all of their sound channels being played on each speaker in order of input. -
  • Mix behavior for multichannel sounds can be set with Channel::setSpeakerLevels.
    -
  • Channel::setSpeakerMix works but side left / side right are ignored.
    -
    - FMOD_SPEAKERMODE_5POINT1
    + This mode is for 5 speaker arrangements that have a left/right/center/rear +left/rear right.
  • Mono sounds default to the center speaker. They can be +panned with Channel::setPan.
  • Stereo sounds default to the left sound +channel played on the front left, and the right sound channel played on the +front right.
  • They can be cross faded with Channel::setPan.
    +
  • Multichannel sounds default to all of their sound channels being played +on each speaker in order of input.
  • Mix behavior for multichannel sounds can +be set with Channel::setSpeakerLevels.
  • Channel::setSpeakerMix works but +side left / side right are ignored.

    FMOD_SPEAKERMODE_5POINT1
    ------------------------
    - This mode is for 5.1 speaker arrangements that have a left/right/center/rear left/rear right and a subwoofer speaker.
    -
  • Mono sounds default to the center speaker. They can be panned with Channel::setPan.
    -
  • Stereo sounds default to the left sound channel played on the front left, and the right sound channel played on the front right. -
  • They can be cross faded with Channel::setPan.
    -
  • Multichannel sounds default to all of their sound channels being played on each speaker in order of input. -
  • Mix behavior for multichannel sounds can be set with Channel::setSpeakerLevels.
    + This mode is for 5.1 speaker arrangements that have a left/right/center/rear +left/rear right and a subwoofer speaker.
  • Mono sounds default to the +center speaker. They can be panned with Channel::setPan.
  • Stereo sounds +default to the left sound channel played on the front left, and the right sound +channel played on the front right.
  • They can be cross faded with +Channel::setPan.
  • Multichannel sounds default to all of their sound +channels being played on each speaker in order of input.
  • Mix behavior for +multichannel sounds can be set with Channel::setSpeakerLevels.
  • Channel::setSpeakerMix works but side left / side right are ignored.

    FMOD_SPEAKERMODE_7POINT1
    ------------------------
    - This mode is for 7.1 speaker arrangements that have a left/right/center/rear left/rear right/side left/side right - and a subwoofer speaker.
    -
  • Mono sounds default to the center speaker. They can be panned with Channel::setPan.
    -
  • Stereo sounds default to the left sound channel played on the front left, and the right sound channel played on the front right. + This mode is for 7.1 speaker arrangements that have a left/right/center/rear +left/rear right/side left/side right and a subwoofer speaker.
  • Mono +sounds default to the center speaker. They can be panned with +Channel::setPan.
  • Stereo sounds default to the left sound channel played +on the front left, and the right sound channel played on the front right.
  • They can be cross faded with Channel::setPan.
    -
  • Multichannel sounds default to all of their sound channels being played on each speaker in order of input. -
  • Mix behavior for multichannel sounds can be set with Channel::setSpeakerLevels.
    -
  • Channel::setSpeakerMix works and every parameter is used to set the balance of a sound in any speaker.
    -
    +
  • Multichannel sounds default to all of their sound channels being played +on each speaker in order of input.
  • Mix behavior for multichannel sounds can +be set with Channel::setSpeakerLevels.
  • Channel::setSpeakerMix works and +every parameter is used to set the balance of a sound in any speaker.

    FMOD_SPEAKERMODE_SRS5_1_MATRIX
    ------------------------------------------------------
    - This mode is for mono, stereo, 5.1 and 6.1 speaker arrangements, as it is backwards and forwards compatible with - stereo, but to get a surround effect a SRS 5.1, Prologic or Prologic 2 hardware decoder / amplifier is needed or - a compatible SRS equipped device (e.g., laptop, TV, etc.) or accessory (e.g., headphone).
    + This mode is for mono, stereo, 5.1 and 6.1 speaker arrangements, as it is +backwards and forwards compatible with stereo, but to get a surround effect a +SRS 5.1, Prologic or Prologic 2 hardware decoder / amplifier is needed or a +compatible SRS equipped device (e.g., laptop, TV, etc.) or accessory (e.g., +headphone).
    Pan behavior is the same as FMOD_SPEAKERMODE_5POINT1.

    + If this function is called the numoutputchannels setting in +System::setSoftwareFormat is overwritten.

    Output rate must be 44100, +48000 or 96000 for this to work otherwise FMOD_ERR_OUTPUT_INIT will be +returned.

    FMOD_SPEAKERMODE_DOLBY5_1_MATRIX
    + ------------------------------------------------------
    + This mode is for 5.1 speaker arrangements using a stereo signal, to get a +surround effect a Dolby Pro Logic II hardware decoder / amplifier is needed.
    Pan behavior is the same as FMOD_SPEAKERMODE_5POINT1.

    - If this function is called the numoutputchannels setting in System::setSoftwareFormat is overwritten.
    -
    - Output rate must be 44100, 48000 or 96000 for this to work otherwise FMOD_ERR_OUTPUT_INIT will be returned.
    -
    - FMOD_SPEAKERMODE_DOLBY5_1_MATRIX
    + If this function is called the numoutputchannels setting in +System::setSoftwareFormat is overwritten.

    Output rate must be 32000, +44100 or 48000 for this to work otherwise FMOD_ERR_OUTPUT_INIT will be +returned.

    FMOD_SPEAKERMODE_MYEARS
    ------------------------------------------------------
    - This mode is for 5.1 speaker arrangements using a stereo signal, to get a surround effect a Dolby Pro Logic II - hardware decoder / amplifier is needed.
    - Pan behavior is the same as FMOD_SPEAKERMODE_5POINT1.
    -
    - If this function is called the numoutputchannels setting in System::setSoftwareFormat is overwritten.
    -
    - Output rate must be 32000, 44100 or 48000 for this to work otherwise FMOD_ERR_OUTPUT_INIT will be returned.
    -
    - FMOD_SPEAKERMODE_MYEARS
    - ------------------------------------------------------
    - This mode is for headphones. This will attempt to load a MyEars profile (see myears.net.au) and use it to generate - surround sound on headphones using a personalized HRTF algorithm, for realistic 3d sound.
    - Pan behavior is the same as FMOD_SPEAKERMODE_7POINT1.
    - MyEars speaker mode will automatically be set if the speakermode is FMOD_SPEAKERMODE_STEREO and the MyEars profile exists.
    - If this mode is set explicitly, FMOD_INIT_DISABLE_MYEARS_AUTODETECT has no effect.
    - If this mode is set explicitly and the MyEars profile does not exist, FMOD_ERR_OUTPUT_DRIVERCALL will be returned. + This mode is for headphones. This will attempt to load a MyEars profile +(see myears.net.au) and use it to generate surround sound on headphones using a +personalized HRTF algorithm, for realistic 3d sound.
    Pan behavior is the +same as FMOD_SPEAKERMODE_7POINT1.
    MyEars speaker mode will automatically be +set if the speakermode is FMOD_SPEAKERMODE_STEREO and the MyEars profile +exists.
    If this mode is set explicitly, FMOD_INIT_DISABLE_MYEARS_AUTODETECT +has no effect.
    If this mode is set explicitly and the MyEars profile does +not exist, FMOD_ERR_OUTPUT_DRIVERCALL will be returned. [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] System::setSpeakerMode @@ -617,43 +850,66 @@ typedef enum Channel::setSpeakerLevels ] */ -typedef enum -{ - FMOD_SPEAKERMODE_RAW, /* There is no specific speakermode. Sound channels are mapped in order of input to output. Use System::setSoftwareFormat to specify speaker count. See remarks for more information. */ - FMOD_SPEAKERMODE_MONO, /* The speakers are monaural. */ - FMOD_SPEAKERMODE_STEREO, /* The speakers are stereo (DEFAULT). */ - FMOD_SPEAKERMODE_QUAD, /* 4 speaker setup. This includes front left, front right, rear left, rear right. */ - FMOD_SPEAKERMODE_SURROUND, /* 5 speaker setup. This includes front left, front right, center, rear left, rear right. */ - FMOD_SPEAKERMODE_5POINT1, /* 5.1 speaker setup. This includes front left, front right, center, rear left, rear right and a subwoofer. */ - FMOD_SPEAKERMODE_7POINT1, /* 7.1 speaker setup. This includes front left, front right, center, rear left, rear right, side left, side right and a subwoofer. */ - - FMOD_SPEAKERMODE_SRS5_1_MATRIX, /* Stereo compatible output, embedded with surround information. SRS 5.1/Prologic/Prologic2 decoders will split the signal into a 5.1 speaker set-up or SRS virtual surround will decode into a 2-speaker/headphone setup. See remarks about limitations.*/ - FMOD_SPEAKERMODE_DOLBY5_1_MATRIX, /* Stereo compatible output, embedded with surround information. Dolby Pro Logic II decoders will split the signal into a 5.1 speaker set-up. */ - FMOD_SPEAKERMODE_MYEARS, /* Stereo output, but data is encoded using personalized HRTF algorithms. See myears.net.au */ +typedef enum { + FMOD_SPEAKERMODE_RAW, /* There is no specific speakermode. Sound channels are + mapped in order of input to output. Use + System::setSoftwareFormat to specify speaker count. + See remarks for more information. */ + FMOD_SPEAKERMODE_MONO, /* The speakers are monaural. */ + FMOD_SPEAKERMODE_STEREO, /* The speakers are stereo (DEFAULT). */ + FMOD_SPEAKERMODE_QUAD, /* 4 speaker setup. This includes front left, front + right, rear left, rear right. */ + FMOD_SPEAKERMODE_SURROUND, /* 5 speaker setup. This includes front left, + front right, center, rear left, rear right. */ + FMOD_SPEAKERMODE_5POINT1, /* 5.1 speaker setup. This includes front left, + front right, center, rear left, rear right and a + subwoofer. */ + FMOD_SPEAKERMODE_7POINT1, /* 7.1 speaker setup. This includes front left, + front right, center, rear left, rear right, side + left, side right and a subwoofer. */ - FMOD_SPEAKERMODE_MAX, /* Maximum number of speaker modes supported. */ - FMOD_SPEAKERMODE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ + FMOD_SPEAKERMODE_SRS5_1_MATRIX, /* Stereo compatible output, embedded with + surround information. + SRS 5.1/Prologic/Prologic2 decoders will + split the signal into a 5.1 speaker set-up + or SRS virtual surround will decode into a + 2-speaker/headphone setup. See remarks + about limitations.*/ + FMOD_SPEAKERMODE_DOLBY5_1_MATRIX, /* Stereo compatible output, embedded with + surround information. Dolby Pro Logic II + decoders will split the signal into a 5.1 + speaker set-up. */ + FMOD_SPEAKERMODE_MYEARS, /* Stereo output, but data is encoded using + personalized HRTF algorithms. See myears.net.au + */ + + FMOD_SPEAKERMODE_MAX, /* Maximum number of speaker modes supported. */ + FMOD_SPEAKERMODE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ } FMOD_SPEAKERMODE; - /* [ENUM] [ - [DESCRIPTION] - These are speaker types defined for use with the Channel::setSpeakerLevels command. - It can also be used for speaker placement in the System::set3DSpeakerPosition command. + [DESCRIPTION] + These are speaker types defined for use with the Channel::setSpeakerLevels +command. It can also be used for speaker placement in the +System::set3DSpeakerPosition command. [REMARKS] - If you are using FMOD_SPEAKERMODE_RAW and speaker assignments are meaningless, just cast a raw integer value to this type.
    - For example (FMOD_SPEAKER)7 would use the 7th speaker (also the same as FMOD_SPEAKER_SIDE_RIGHT).
    - Values higher than this can be used if an output system has more than 8 speaker types / output channels. 15 is the current maximum.
    -
    - NOTE: On Playstation 3 in 7.1, the extra 2 speakers are not side left/side right, they are 'surround back left'/'surround back right' which - locate the speakers behind the listener instead of to the sides like on PC. FMOD_SPEAKER_SBL/FMOD_SPEAKER_SBR are provided to make it - clearer what speaker is being addressed on that platform. + If you are using FMOD_SPEAKERMODE_RAW and speaker assignments are +meaningless, just cast a raw integer value to this type.
    For example +(FMOD_SPEAKER)7 would use the 7th speaker (also the same as +FMOD_SPEAKER_SIDE_RIGHT).
    Values higher than this can be used if an output +system has more than 8 speaker types / output channels. 15 is the current +maximum.

    NOTE: On Playstation 3 in 7.1, the extra 2 speakers are not +side left/side right, they are 'surround back left'/'surround back right' which + locate the speakers behind the listener instead of to the sides like on PC. +FMOD_SPEAKER_SBL/FMOD_SPEAKER_SBR are provided to make it clearer what speaker +is being addressed on that platform. [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] FMOD_SPEAKERMODE @@ -663,37 +919,46 @@ typedef enum System::get3DSpeakerPosition ] */ -typedef enum -{ - FMOD_SPEAKER_FRONT_LEFT, - FMOD_SPEAKER_FRONT_RIGHT, - FMOD_SPEAKER_FRONT_CENTER, - FMOD_SPEAKER_LOW_FREQUENCY, - FMOD_SPEAKER_BACK_LEFT, - FMOD_SPEAKER_BACK_RIGHT, - FMOD_SPEAKER_SIDE_LEFT, - FMOD_SPEAKER_SIDE_RIGHT, - - FMOD_SPEAKER_MAX, /* Maximum number of speaker types supported. */ - FMOD_SPEAKER_MONO = FMOD_SPEAKER_FRONT_LEFT, /* For use with FMOD_SPEAKERMODE_MONO and Channel::SetSpeakerLevels. Mapped to same value as FMOD_SPEAKER_FRONT_LEFT. */ - FMOD_SPEAKER_NULL = 65535, /* A non speaker. Use this with ASIO mapping to ignore a speaker. */ - FMOD_SPEAKER_SBL = FMOD_SPEAKER_SIDE_LEFT, /* For use with FMOD_SPEAKERMODE_7POINT1 on PS3 where the extra speakers are surround back inside of side speakers. */ - FMOD_SPEAKER_SBR = FMOD_SPEAKER_SIDE_RIGHT, /* For use with FMOD_SPEAKERMODE_7POINT1 on PS3 where the extra speakers are surround back inside of side speakers. */ - FMOD_SPEAKER_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ -} FMOD_SPEAKER; +typedef enum { + FMOD_SPEAKER_FRONT_LEFT, + FMOD_SPEAKER_FRONT_RIGHT, + FMOD_SPEAKER_FRONT_CENTER, + FMOD_SPEAKER_LOW_FREQUENCY, + FMOD_SPEAKER_BACK_LEFT, + FMOD_SPEAKER_BACK_RIGHT, + FMOD_SPEAKER_SIDE_LEFT, + FMOD_SPEAKER_SIDE_RIGHT, + FMOD_SPEAKER_MAX, /* Maximum number of speaker types supported. */ + FMOD_SPEAKER_MONO = + FMOD_SPEAKER_FRONT_LEFT, /* For use with FMOD_SPEAKERMODE_MONO and + Channel::SetSpeakerLevels. Mapped to same + value as FMOD_SPEAKER_FRONT_LEFT. */ + FMOD_SPEAKER_NULL = 65535, /* A non speaker. Use this with ASIO mapping to + ignore a speaker. */ + FMOD_SPEAKER_SBL = + FMOD_SPEAKER_SIDE_LEFT, /* For use with FMOD_SPEAKERMODE_7POINT1 on PS3 + where the extra speakers are surround back + inside of side speakers. */ + FMOD_SPEAKER_SBR = + FMOD_SPEAKER_SIDE_RIGHT, /* For use with FMOD_SPEAKERMODE_7POINT1 on PS3 + where the extra speakers are surround back + inside of side speakers. */ + FMOD_SPEAKER_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ +} FMOD_SPEAKER; /* [ENUM] [ - [DESCRIPTION] - These are plugin types defined for use with the System::getNumPlugins, + [DESCRIPTION] + These are plugin types defined for use with the System::getNumPlugins, System::getPluginInfo and System::unloadPlugin functions. [REMARKS] [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] System::getNumPlugins @@ -701,187 +966,275 @@ typedef enum System::unloadPlugin ] */ -typedef enum -{ - FMOD_PLUGINTYPE_OUTPUT, /* The plugin type is an output module. FMOD mixed audio will play through one of these devices */ - FMOD_PLUGINTYPE_CODEC, /* The plugin type is a file format codec. FMOD will use these codecs to load file formats for playback. */ - FMOD_PLUGINTYPE_DSP, /* The plugin type is a DSP unit. FMOD will use these plugins as part of its DSP network to apply effects to output or generate sound in realtime. */ +typedef enum { + FMOD_PLUGINTYPE_OUTPUT, /* The plugin type is an output module. FMOD mixed + audio will play through one of these devices */ + FMOD_PLUGINTYPE_CODEC, /* The plugin type is a file format codec. FMOD will + use these codecs to load file formats for playback. + */ + FMOD_PLUGINTYPE_DSP, /* The plugin type is a DSP unit. FMOD will use these + plugins as part of its DSP network to apply effects to + output or generate sound in realtime. */ - FMOD_PLUGINTYPE_MAX, /* Maximum number of plugin types supported. */ - FMOD_PLUGINTYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ + FMOD_PLUGINTYPE_MAX, /* Maximum number of plugin types supported. */ + FMOD_PLUGINTYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ } FMOD_PLUGINTYPE; - /* [DEFINE] [ [NAME] FMOD_INITFLAGS - [DESCRIPTION] - Initialization flags. Use them with System::init in the flags parameter to change various behavior. + [DESCRIPTION] + Initialization flags. Use them with System::init in the flags parameter to +change various behavior. [REMARKS] - Use System::setAdvancedSettings to adjust settings for some of the features that are enabled by these flags. + Use System::setAdvancedSettings to adjust settings for some of the features +that are enabled by these flags. [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] System::init - System::update + System::update System::setAdvancedSettings Channel::set3DOcclusion ] */ -#define FMOD_INIT_NORMAL 0x00000000 /* All platforms - Initialize normally */ -#define FMOD_INIT_STREAM_FROM_UPDATE 0x00000001 /* All platforms - No stream thread is created internally. Streams are driven from System::update. Mainly used with non-realtime outputs. */ -#define FMOD_INIT_3D_RIGHTHANDED 0x00000002 /* All platforms - FMOD will treat +X as right, +Y as up and +Z as backwards (towards you). */ -#define FMOD_INIT_SOFTWARE_DISABLE 0x00000004 /* All platforms - Disable software mixer to save memory. Anything created with FMOD_SOFTWARE will fail and DSP will not work. */ -#define FMOD_INIT_OCCLUSION_LOWPASS 0x00000008 /* All platforms - All FMOD_SOFTWARE (and FMOD_HARDWARE on 3DS and NGP) with FMOD_3D based voices will add a software lowpass filter effect into the DSP chain which is automatically used when Channel::set3DOcclusion is used or the geometry API. */ -#define FMOD_INIT_HRTF_LOWPASS 0x00000010 /* All platforms - All FMOD_SOFTWARE (and FMOD_HARDWARE on 3DS and NGP) with FMOD_3D based voices will add a software lowpass filter effect into the DSP chain which causes sounds to sound duller when the sound goes behind the listener. Use System::setAdvancedSettings to adjust cutoff frequency. */ -#define FMOD_INIT_DISTANCE_FILTERING 0x00000200 /* All platforms - All FMOD_SOFTWARE with FMOD_3D based voices will add a software lowpass and highpass filter effect into the DSP chain which will act as a distance-automated bandpass filter. Use System::setAdvancedSettings to adjust the center frequency. */ -#define FMOD_INIT_REVERB_PREALLOCBUFFERS 0x00000040 /* All platforms - FMOD Software reverb will preallocate enough buffers for reverb per channel, rather than allocating them and freeing them at runtime. */ -#define FMOD_INIT_ENABLE_PROFILE 0x00000020 /* All platforms - Enable TCP/IP based host which allows FMOD Designer or FMOD Profiler to connect to it, and view memory, CPU and the DSP network graph in real-time. */ -#define FMOD_INIT_VOL0_BECOMES_VIRTUAL 0x00000080 /* All platforms - Any sounds that are 0 volume will go virtual and not be processed except for having their positions updated virtually. Use System::setAdvancedSettings to adjust what volume besides zero to switch to virtual at. */ -#define FMOD_INIT_WASAPI_EXCLUSIVE 0x00000100 /* Win32 Vista only - for WASAPI output - Enable exclusive access to hardware, lower latency at the expense of excluding other applications from accessing the audio hardware. */ -#define FMOD_INIT_PS3_PREFERDTS 0x00800000 /* PS3 only - Prefer DTS over Dolby Digital if both are supported. Note: 8 and 6 channel LPCM is always preferred over both DTS and Dolby Digital. */ -#define FMOD_INIT_PS3_FORCE2CHLPCM 0x01000000 /* PS3 only - Force PS3 system output mode to 2 channel LPCM. */ -#define FMOD_INIT_DISABLEDOLBY 0x00100000 /* Wii / 3DS - Disable Dolby Pro Logic surround. Speakermode will be set to STEREO even if user has selected surround in the system settings. */ -#define FMOD_INIT_SYSTEM_MUSICMUTENOTPAUSE 0x00200000 /* Xbox 360 / PS3 - The "music" channelgroup which by default pauses when custom 360 dashboard / PS3 BGM music is played, can be changed to mute (therefore continues playing) instead of pausing, by using this flag. */ -#define FMOD_INIT_SYNCMIXERWITHUPDATE 0x00400000 /* Win32/Wii/PS3/Xbox/Xbox 360 - FMOD Mixer thread is woken up to do a mix when System::update is called rather than waking periodically on its own timer. */ -#define FMOD_INIT_GEOMETRY_USECLOSEST 0x04000000 /* All platforms - With the geometry engine, only process the closest polygon rather than accumulating all polygons the sound to listener line intersects. */ -#define FMOD_INIT_DISABLE_MYEARS_AUTODETECT 0x08000000 /* Win32 - Disables automatic setting of FMOD_SPEAKERMODE_STEREO to FMOD_SPEAKERMODE_MYEARS if the MyEars profile exists on the PC. MyEars is HRTF 7.1 downmixing through headphones. */ -#define FMOD_INIT_PS3_DISABLEDTS 0x10000000 /* PS3 only - Disable DTS output mode selection */ -#define FMOD_INIT_PS3_DISABLEDOLBYDIGITAL 0x20000000 /* PS3 only - Disable Dolby Digital output mode selection */ -#define FMOD_INIT_7POINT1_DOLBYMAPPING 0x40000000 /* PS3/PS4 only - FMOD uses the WAVEFORMATEX Microsoft 7.1 speaker mapping where the last 2 pairs of speakers are 'rears' then 'sides', but on PS3/PS4 these are mapped to 'surrounds' and 'backs'. Use this flag to swap fmod's last 2 pair of speakers on PS3/PS4 to avoid needing to do a special case for these platforms. */ -#define FMOD_INIT_ASYNCREAD_FAST 0x80000000 /* All platforms - Rather than setting FMOD_ASYNCREADINFO::result, call FMOD_ASYNCREADINFO::done to enable a semaphore based wait inside fmod, rather than the older method which can incur up to 10ms delay per read. */ +#define FMOD_INIT_NORMAL 0x00000000 /* All platforms - Initialize normally */ +#define FMOD_INIT_STREAM_FROM_UPDATE \ + 0x00000001 /* All platforms - No stream thread is created internally. \ + Streams are driven from System::update. Mainly used with \ + non-realtime outputs. */ +#define FMOD_INIT_3D_RIGHTHANDED \ + 0x00000002 /* All platforms - FMOD will treat +X as right, +Y as up and +Z \ + as backwards (towards you). */ +#define FMOD_INIT_SOFTWARE_DISABLE \ + 0x00000004 /* All platforms - Disable software mixer to save memory. \ + Anything created with FMOD_SOFTWARE will fail and DSP will not \ + work. */ +#define FMOD_INIT_OCCLUSION_LOWPASS \ + 0x00000008 /* All platforms - All FMOD_SOFTWARE (and FMOD_HARDWARE on 3DS \ + and NGP) with FMOD_3D based voices will add a software lowpass \ + filter effect into the DSP chain which is automatically used \ + when Channel::set3DOcclusion is used or the geometry API. */ +#define FMOD_INIT_HRTF_LOWPASS \ + 0x00000010 /* All platforms - All FMOD_SOFTWARE (and FMOD_HARDWARE on 3DS \ + and NGP) with FMOD_3D based voices will add a software lowpass \ + filter effect into the DSP chain which causes sounds to sound \ + duller when the sound goes behind the listener. Use \ + System::setAdvancedSettings to adjust cutoff frequency. */ +#define FMOD_INIT_DISTANCE_FILTERING \ + 0x00000200 /* All platforms - All FMOD_SOFTWARE with FMOD_3D based voices \ + will add a software lowpass and highpass filter effect into \ + the DSP chain which will act as a distance-automated bandpass \ + filter. Use System::setAdvancedSettings to adjust the center \ + frequency. */ +#define FMOD_INIT_REVERB_PREALLOCBUFFERS \ + 0x00000040 /* All platforms - FMOD Software reverb will preallocate enough \ + buffers for reverb per channel, rather than allocating them \ + and freeing them at runtime. */ +#define FMOD_INIT_ENABLE_PROFILE \ + 0x00000020 /* All platforms - Enable TCP/IP based host which allows FMOD \ + Designer or FMOD Profiler to connect to it, and view memory, \ + CPU and the DSP network graph in real-time. */ +#define FMOD_INIT_VOL0_BECOMES_VIRTUAL \ + 0x00000080 /* All platforms - Any sounds that are 0 volume will go virtual \ + and not be processed except for having their positions updated \ + virtually. Use System::setAdvancedSettings to adjust what \ + volume besides zero to switch to virtual at. */ +#define FMOD_INIT_WASAPI_EXCLUSIVE \ + 0x00000100 /* Win32 Vista only - for WASAPI output - Enable exclusive access \ + to hardware, lower latency at the expense of excluding other \ + applications from accessing the audio hardware. */ +#define FMOD_INIT_PS3_PREFERDTS \ + 0x00800000 /* PS3 only - Prefer DTS over Dolby Digital if both are \ + supported. Note: 8 and 6 channel LPCM is always preferred over \ + both DTS and Dolby Digital. */ +#define FMOD_INIT_PS3_FORCE2CHLPCM \ + 0x01000000 /* PS3 only - Force PS3 system output mode to 2 channel LPCM. */ +#define FMOD_INIT_DISABLEDOLBY \ + 0x00100000 /* Wii / 3DS - Disable Dolby Pro Logic surround. Speakermode will \ + be set to STEREO even if user has selected surround in the \ + system settings. */ +#define FMOD_INIT_SYSTEM_MUSICMUTENOTPAUSE \ + 0x00200000 /* Xbox 360 / PS3 - The "music" channelgroup which by default \ + pauses when custom 360 dashboard / PS3 BGM music is played, \ + can be changed to mute (therefore continues playing) instead \ + of pausing, by using this flag. */ +#define FMOD_INIT_SYNCMIXERWITHUPDATE \ + 0x00400000 /* Win32/Wii/PS3/Xbox/Xbox 360 - FMOD Mixer thread is woken up to \ + do a mix when System::update is called rather than waking \ + periodically on its own timer. */ +#define FMOD_INIT_GEOMETRY_USECLOSEST \ + 0x04000000 /* All platforms - With the geometry engine, only process the \ + closest polygon rather than accumulating all polygons the \ + sound to listener line intersects. */ +#define FMOD_INIT_DISABLE_MYEARS_AUTODETECT \ + 0x08000000 /* Win32 - Disables automatic setting of FMOD_SPEAKERMODE_STEREO \ + to FMOD_SPEAKERMODE_MYEARS if the MyEars profile exists on the \ + PC. MyEars is HRTF 7.1 downmixing through headphones. */ +#define FMOD_INIT_PS3_DISABLEDTS \ + 0x10000000 /* PS3 only - Disable DTS output mode selection */ +#define FMOD_INIT_PS3_DISABLEDOLBYDIGITAL \ + 0x20000000 /* PS3 only - Disable Dolby Digital output mode selection */ +#define FMOD_INIT_7POINT1_DOLBYMAPPING \ + 0x40000000 /* PS3/PS4 only - FMOD uses the WAVEFORMATEX Microsoft 7.1 \ + speaker mapping where the last 2 pairs of speakers are 'rears' \ + then 'sides', but on PS3/PS4 these are mapped to 'surrounds' \ + and 'backs'. Use this flag to swap fmod's last 2 pair of \ + speakers on PS3/PS4 to avoid needing to do a special case for \ + these platforms. */ +#define FMOD_INIT_ASYNCREAD_FAST \ + 0x80000000 /* All platforms - Rather than setting \ + FMOD_ASYNCREADINFO::result, call FMOD_ASYNCREADINFO::done to \ + enable a semaphore based wait inside fmod, rather than the \ + older method which can incur up to 10ms delay per read. */ /* [DEFINE_END] */ - /* [ENUM] [ - [DESCRIPTION] + [DESCRIPTION] These definitions describe the type of song being played. [REMARKS] [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] Sound::getFormat ] */ -typedef enum -{ - FMOD_SOUND_TYPE_UNKNOWN, /* 3rd party / unknown plugin format. */ - FMOD_SOUND_TYPE_AIFF, /* AIFF. */ - FMOD_SOUND_TYPE_ASF, /* Microsoft Advanced Systems Format (ie WMA/ASF/WMV). */ - FMOD_SOUND_TYPE_AT3, /* Sony ATRAC 3 format */ - FMOD_SOUND_TYPE_CDDA, /* Digital CD audio. */ - FMOD_SOUND_TYPE_DLS, /* Sound font / downloadable sound bank. */ - FMOD_SOUND_TYPE_FLAC, /* FLAC lossless codec. */ - FMOD_SOUND_TYPE_FSB, /* FMOD Sample Bank. */ - FMOD_SOUND_TYPE_GCADPCM, /* Nintendo GameCube/Wii ADPCM */ - FMOD_SOUND_TYPE_IT, /* Impulse Tracker. */ - FMOD_SOUND_TYPE_MIDI, /* MIDI. extracodecdata is a pointer to an FMOD_MIDI_EXTRACODECDATA structure. */ - FMOD_SOUND_TYPE_MOD, /* Protracker / Fasttracker MOD. */ - FMOD_SOUND_TYPE_MPEG, /* MP2/MP3 MPEG. */ - FMOD_SOUND_TYPE_OGGVORBIS, /* Ogg vorbis. */ - FMOD_SOUND_TYPE_PLAYLIST, /* Information only from ASX/PLS/M3U/WAX playlists */ - FMOD_SOUND_TYPE_RAW, /* Raw PCM data. */ - FMOD_SOUND_TYPE_S3M, /* ScreamTracker 3. */ - FMOD_SOUND_TYPE_SF2, /* Sound font 2 format. */ - FMOD_SOUND_TYPE_USER, /* User created sound. */ - FMOD_SOUND_TYPE_WAV, /* Microsoft WAV. */ - FMOD_SOUND_TYPE_XM, /* FastTracker 2 XM. */ - FMOD_SOUND_TYPE_XMA, /* Xbox360 XMA */ - FMOD_SOUND_TYPE_VAG, /* PlayStation Portable ADPCM VAG format. */ - FMOD_SOUND_TYPE_AUDIOQUEUE, /* iPhone hardware decoder, supports AAC, ALAC and MP3. extracodecdata is a pointer to an FMOD_AUDIOQUEUE_EXTRACODECDATA structure. */ - FMOD_SOUND_TYPE_XWMA, /* Xbox360 XWMA */ - FMOD_SOUND_TYPE_BCWAV, /* 3DS BCWAV container format for DSP ADPCM and PCM */ - FMOD_SOUND_TYPE_AT9, /* NGP ATRAC 9 format */ - FMOD_SOUND_TYPE_VORBIS, /* Raw vorbis */ - FMOD_SOUND_TYPE_MEDIA_FOUNDATION,/* Microsoft Media Foundation wrappers, supports ASF/WMA */ +typedef enum { + FMOD_SOUND_TYPE_UNKNOWN, /* 3rd party / unknown plugin format. */ + FMOD_SOUND_TYPE_AIFF, /* AIFF. */ + FMOD_SOUND_TYPE_ASF, /* Microsoft Advanced Systems Format (ie WMA/ASF/WMV). */ + FMOD_SOUND_TYPE_AT3, /* Sony ATRAC 3 format */ + FMOD_SOUND_TYPE_CDDA, /* Digital CD audio. */ + FMOD_SOUND_TYPE_DLS, /* Sound font / downloadable sound bank. */ + FMOD_SOUND_TYPE_FLAC, /* FLAC lossless codec. */ + FMOD_SOUND_TYPE_FSB, /* FMOD Sample Bank. */ + FMOD_SOUND_TYPE_GCADPCM, /* Nintendo GameCube/Wii ADPCM */ + FMOD_SOUND_TYPE_IT, /* Impulse Tracker. */ + FMOD_SOUND_TYPE_MIDI, /* MIDI. extracodecdata is a pointer to an + FMOD_MIDI_EXTRACODECDATA structure. */ + FMOD_SOUND_TYPE_MOD, /* Protracker / Fasttracker MOD. */ + FMOD_SOUND_TYPE_MPEG, /* MP2/MP3 MPEG. */ + FMOD_SOUND_TYPE_OGGVORBIS, /* Ogg vorbis. */ + FMOD_SOUND_TYPE_PLAYLIST, /* Information only from ASX/PLS/M3U/WAX playlists + */ + FMOD_SOUND_TYPE_RAW, /* Raw PCM data. */ + FMOD_SOUND_TYPE_S3M, /* ScreamTracker 3. */ + FMOD_SOUND_TYPE_SF2, /* Sound font 2 format. */ + FMOD_SOUND_TYPE_USER, /* User created sound. */ + FMOD_SOUND_TYPE_WAV, /* Microsoft WAV. */ + FMOD_SOUND_TYPE_XM, /* FastTracker 2 XM. */ + FMOD_SOUND_TYPE_XMA, /* Xbox360 XMA */ + FMOD_SOUND_TYPE_VAG, /* PlayStation Portable ADPCM VAG format. */ + FMOD_SOUND_TYPE_AUDIOQUEUE, /* iPhone hardware decoder, supports AAC, ALAC and + MP3. extracodecdata is a pointer to an + FMOD_AUDIOQUEUE_EXTRACODECDATA structure. */ + FMOD_SOUND_TYPE_XWMA, /* Xbox360 XWMA */ + FMOD_SOUND_TYPE_BCWAV, /* 3DS BCWAV container format for DSP ADPCM and PCM */ + FMOD_SOUND_TYPE_AT9, /* NGP ATRAC 9 format */ + FMOD_SOUND_TYPE_VORBIS, /* Raw vorbis */ + FMOD_SOUND_TYPE_MEDIA_FOUNDATION, /* Microsoft Media Foundation wrappers, + supports ASF/WMA */ - FMOD_SOUND_TYPE_MAX, /* Maximum number of sound types supported. */ - FMOD_SOUND_TYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ + FMOD_SOUND_TYPE_MAX, /* Maximum number of sound types supported. */ + FMOD_SOUND_TYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ } FMOD_SOUND_TYPE; - /* [ENUM] [ - [DESCRIPTION] - These definitions describe the native format of the hardware or software buffer that will be used. + [DESCRIPTION] + These definitions describe the native format of the hardware or software +buffer that will be used. [REMARKS] - This is the format the native hardware or software buffer will be or is created in. + This is the format the native hardware or software buffer will be or is +created in. [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] System::createSound Sound::getFormat ] */ -typedef enum -{ - FMOD_SOUND_FORMAT_NONE, /* Unitialized / unknown. */ - FMOD_SOUND_FORMAT_PCM8, /* 8bit integer PCM data. */ - FMOD_SOUND_FORMAT_PCM16, /* 16bit integer PCM data. */ - FMOD_SOUND_FORMAT_PCM24, /* 24bit integer PCM data. */ - FMOD_SOUND_FORMAT_PCM32, /* 32bit integer PCM data. */ - FMOD_SOUND_FORMAT_PCMFLOAT, /* 32bit floating point PCM data. */ - FMOD_SOUND_FORMAT_GCADPCM, /* Compressed Nintendo 3DS/Wii DSP data. */ - FMOD_SOUND_FORMAT_IMAADPCM, /* Compressed IMA ADPCM data. */ - FMOD_SOUND_FORMAT_VAG, /* Compressed PlayStation Portable ADPCM data. */ - FMOD_SOUND_FORMAT_HEVAG, /* Compressed PSVita ADPCM data. */ - FMOD_SOUND_FORMAT_XMA, /* Compressed Xbox360 XMA data. */ - FMOD_SOUND_FORMAT_MPEG, /* Compressed MPEG layer 2 or 3 data. */ - FMOD_SOUND_FORMAT_CELT, /* Compressed CELT data. */ - FMOD_SOUND_FORMAT_AT9, /* Compressed PSVita ATRAC9 data. */ - FMOD_SOUND_FORMAT_XWMA, /* Compressed Xbox360 xWMA data. */ - FMOD_SOUND_FORMAT_VORBIS, /* Compressed Vorbis data. */ +typedef enum { + FMOD_SOUND_FORMAT_NONE, /* Unitialized / unknown. */ + FMOD_SOUND_FORMAT_PCM8, /* 8bit integer PCM data. */ + FMOD_SOUND_FORMAT_PCM16, /* 16bit integer PCM data. */ + FMOD_SOUND_FORMAT_PCM24, /* 24bit integer PCM data. */ + FMOD_SOUND_FORMAT_PCM32, /* 32bit integer PCM data. */ + FMOD_SOUND_FORMAT_PCMFLOAT, /* 32bit floating point PCM data. */ + FMOD_SOUND_FORMAT_GCADPCM, /* Compressed Nintendo 3DS/Wii DSP data. */ + FMOD_SOUND_FORMAT_IMAADPCM, /* Compressed IMA ADPCM data. */ + FMOD_SOUND_FORMAT_VAG, /* Compressed PlayStation Portable ADPCM data. */ + FMOD_SOUND_FORMAT_HEVAG, /* Compressed PSVita ADPCM data. */ + FMOD_SOUND_FORMAT_XMA, /* Compressed Xbox360 XMA data. */ + FMOD_SOUND_FORMAT_MPEG, /* Compressed MPEG layer 2 or 3 data. */ + FMOD_SOUND_FORMAT_CELT, /* Compressed CELT data. */ + FMOD_SOUND_FORMAT_AT9, /* Compressed PSVita ATRAC9 data. */ + FMOD_SOUND_FORMAT_XWMA, /* Compressed Xbox360 xWMA data. */ + FMOD_SOUND_FORMAT_VORBIS, /* Compressed Vorbis data. */ - FMOD_SOUND_FORMAT_MAX, /* Maximum number of sound formats supported. */ - FMOD_SOUND_FORMAT_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ + FMOD_SOUND_FORMAT_MAX, /* Maximum number of sound formats supported. */ + FMOD_SOUND_FORMAT_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ } FMOD_SOUND_FORMAT; - /* [DEFINE] [ - [NAME] + [NAME] FMOD_MODE - [DESCRIPTION] - Sound description bitfields, bitwise OR them together for loading and describing sounds. + [DESCRIPTION] + Sound description bitfields, bitwise OR them together for loading and +describing sounds. [REMARKS] - By default a sound will open as a static sound that is decompressed fully into memory to PCM. (ie equivalent of FMOD_CREATESAMPLE)
    - To have a sound stream instead, use FMOD_CREATESTREAM, or use the wrapper function System::createStream.
    - Some opening modes (ie FMOD_OPENUSER, FMOD_OPENMEMORY, FMOD_OPENMEMORY_POINT, FMOD_OPENRAW) will need extra information.
    - This can be provided using the FMOD_CREATESOUNDEXINFO structure. -
    - Specifying FMOD_OPENMEMORY_POINT will POINT to your memory rather allocating its own sound buffers and duplicating it internally.
    - This means you cannot free the memory while FMOD is using it, until after Sound::release is called. - With FMOD_OPENMEMORY_POINT, for PCM formats, only WAV, FSB, and RAW are supported. For compressed formats, only those formats supported by FMOD_CREATECOMPRESSEDSAMPLE are supported.
    - With FMOD_OPENMEMORY_POINT and FMOD_OPENRAW or PCM, if using them together, note that you must pad the data on each side by 16 bytes. This is so fmod can modify the ends of the data for looping/interpolation/mixing purposes. If a wav file, you will need to insert silence, and then reset loop points to stop the playback from playing that silence.
    - With FMOD_OPENMEMORY_POINT, For Wii/PSP FMOD_HARDWARE supports this flag for the GCADPCM/VAG formats. On other platforms FMOD_SOFTWARE must be used.
    -
    - Xbox 360 memory On Xbox 360 Specifying FMOD_OPENMEMORY_POINT to a virtual memory address will cause FMOD_ERR_INVALID_ADDRESS - to be returned. Use physical memory only for this functionality.
    -
    - FMOD_LOWMEM is used on a sound if you want to minimize the memory overhead, by having FMOD not allocate memory for certain - features that are not likely to be used in a game environment. These are :
    - 1. Sound::getName functionality is removed. 256 bytes per sound is saved.
    + By default a sound will open as a static sound that is decompressed fully +into memory to PCM. (ie equivalent of FMOD_CREATESAMPLE)
    To have a sound +stream instead, use FMOD_CREATESTREAM, or use the wrapper function +System::createStream.
    Some opening modes (ie FMOD_OPENUSER, FMOD_OPENMEMORY, +FMOD_OPENMEMORY_POINT, FMOD_OPENRAW) will need extra information.
    This can +be provided using the FMOD_CREATESOUNDEXINFO structure.
    Specifying +FMOD_OPENMEMORY_POINT will POINT to your memory rather allocating its own sound +buffers and duplicating it internally.
    This means you cannot free the +memory while FMOD is using it, until after Sound::release is called. + With FMOD_OPENMEMORY_POINT, for PCM formats, only WAV, FSB, and RAW are +supported. For compressed formats, only those formats supported by +FMOD_CREATECOMPRESSEDSAMPLE are supported.
    With FMOD_OPENMEMORY_POINT and +FMOD_OPENRAW or PCM, if using them together, note that you must pad the data on +each side by 16 bytes. This is so fmod can modify the ends of the data for +looping/interpolation/mixing purposes. If a wav file, you will need to insert +silence, and then reset loop points to stop the playback from playing that +silence.
    With FMOD_OPENMEMORY_POINT, For Wii/PSP FMOD_HARDWARE supports this +flag for the GCADPCM/VAG formats. On other platforms FMOD_SOFTWARE must be +used.

    Xbox 360 memory On Xbox 360 Specifying +FMOD_OPENMEMORY_POINT to a virtual memory address will cause +FMOD_ERR_INVALID_ADDRESS to be returned. Use physical memory only for this +functionality.

    FMOD_LOWMEM is used on a sound if you want to minimize +the memory overhead, by having FMOD not allocate memory for certain features +that are not likely to be used in a game environment. These are :
    + 1. Sound::getName functionality is removed. 256 bytes per sound is +saved.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] System::createSound @@ -895,91 +1248,209 @@ typedef enum Sound::getOpenState ] */ -#define FMOD_DEFAULT 0x00000000 /* Default for all modes listed below. FMOD_LOOP_OFF, FMOD_2D, FMOD_HARDWARE */ -#define FMOD_LOOP_OFF 0x00000001 /* For non looping sounds. (DEFAULT). Overrides FMOD_LOOP_NORMAL / FMOD_LOOP_BIDI. */ -#define FMOD_LOOP_NORMAL 0x00000002 /* For forward looping sounds. */ -#define FMOD_LOOP_BIDI 0x00000004 /* For bidirectional looping sounds. (only works on software mixed static sounds). */ -#define FMOD_2D 0x00000008 /* Ignores any 3d processing. (DEFAULT). */ -#define FMOD_3D 0x00000010 /* Makes the sound positionable in 3D. Overrides FMOD_2D. */ -#define FMOD_HARDWARE 0x00000020 /* Attempts to make sounds use hardware acceleration. (DEFAULT). Note on platforms that don't support FMOD_HARDWARE (only 3DS, PS Vita, PSP, Wii and Wii U support FMOD_HARDWARE), this will be internally treated as FMOD_SOFTWARE. */ -#define FMOD_SOFTWARE 0x00000040 /* Makes the sound be mixed by the FMOD CPU based software mixer. Overrides FMOD_HARDWARE. Use this for FFT, DSP, compressed sample support, 2D multi-speaker support and other software related features. */ -#define FMOD_CREATESTREAM 0x00000080 /* Decompress at runtime, streaming from the source provided (ie from disk). Overrides FMOD_CREATESAMPLE and FMOD_CREATECOMPRESSEDSAMPLE. Note a stream can only be played once at a time due to a stream only having 1 stream buffer and file handle. Open multiple streams to have them play concurrently. */ -#define FMOD_CREATESAMPLE 0x00000100 /* Decompress at loadtime, decompressing or decoding whole file into memory as the target sample format (ie PCM). Fastest for FMOD_SOFTWARE based playback and most flexible. */ -#define FMOD_CREATECOMPRESSEDSAMPLE 0x00000200 /* Load MP2/MP3/IMAADPCM/CELT/Vorbis/AT9 or XMA into memory and leave it compressed. CELT/Vorbis/AT9 encoding only supported in the FSB file format. During playback the FMOD software mixer will decode it in realtime as a 'compressed sample'. Can only be used in combination with FMOD_SOFTWARE. Overrides FMOD_CREATESAMPLE. If the sound data is not one of the supported formats, it will behave as if it was created with FMOD_CREATESAMPLE and decode the sound into PCM. */ -#define FMOD_OPENUSER 0x00000400 /* Opens a user created static sample or stream. Use FMOD_CREATESOUNDEXINFO to specify format and/or read callbacks. If a user created 'sample' is created with no read callback, the sample will be empty. Use Sound::lock and Sound::unlock to place sound data into the sound if this is the case. */ -#define FMOD_OPENMEMORY 0x00000800 /* "name_or_data" will be interpreted as a pointer to memory instead of filename for creating sounds. Use FMOD_CREATESOUNDEXINFO to specify length. If used with FMOD_CREATESAMPLE or FMOD_CREATECOMPRESSEDSAMPLE, FMOD duplicates the memory into its own buffers. Your own buffer can be freed after open. If used with FMOD_CREATESTREAM, FMOD will stream out of the buffer whose pointer you passed in. In this case, your own buffer should not be freed until you have finished with and released the stream.*/ -#define FMOD_OPENMEMORY_POINT 0x10000000 /* "name_or_data" will be interpreted as a pointer to memory instead of filename for creating sounds. Use FMOD_CREATESOUNDEXINFO to specify length. This differs to FMOD_OPENMEMORY in that it uses the memory as is, without duplicating the memory into its own buffers. For Wii/PSP FMOD_HARDWARE supports this flag for the GCADPCM/VAG formats. On other platforms FMOD_SOFTWARE must be used, as sound hardware on the other platforms (ie PC) cannot access main ram. Cannot be freed after open, only after Sound::release. Will not work if the data is compressed and FMOD_CREATECOMPRESSEDSAMPLE is not used. */ -#define FMOD_OPENRAW 0x00001000 /* Will ignore file format and treat as raw pcm. Use FMOD_CREATESOUNDEXINFO to specify format. Requires at least defaultfrequency, numchannels and format to be specified before it will open. Must be little endian data. */ -#define FMOD_OPENONLY 0x00002000 /* Just open the file, dont prebuffer or read. Good for fast opens for info, or when sound::readData is to be used. */ -#define FMOD_ACCURATETIME 0x00004000 /* For System::createSound - for accurate Sound::getLength/Channel::setPosition on VBR MP3, and MOD/S3M/XM/IT/MIDI files. Scans file first, so takes longer to open. FMOD_OPENONLY does not affect this. */ -#define FMOD_MPEGSEARCH 0x00008000 /* For corrupted / bad MP3 files. This will search all the way through the file until it hits a valid MPEG header. Normally only searches for 4k. */ -#define FMOD_NONBLOCKING 0x00010000 /* For opening sounds and getting streamed subsounds (seeking) asyncronously. Use Sound::getOpenState to poll the state of the sound as it opens or retrieves the subsound in the background. */ -#define FMOD_UNIQUE 0x00020000 /* Unique sound, can only be played one at a time */ -#define FMOD_3D_HEADRELATIVE 0x00040000 /* Make the sound's position, velocity and orientation relative to the listener. */ -#define FMOD_3D_WORLDRELATIVE 0x00080000 /* Make the sound's position, velocity and orientation absolute (relative to the world). (DEFAULT) */ -#define FMOD_3D_INVERSEROLLOFF 0x00100000 /* This sound will follow the inverse rolloff model where mindistance = full volume, maxdistance = where sound stops attenuating, and rolloff is fixed according to the global rolloff factor. (DEFAULT) */ -#define FMOD_3D_LINEARROLLOFF 0x00200000 /* This sound will follow a linear rolloff model where mindistance = full volume, maxdistance = silence. Rolloffscale is ignored. */ -#define FMOD_3D_LINEARSQUAREROLLOFF 0x00400000 /* This sound will follow a linear-square rolloff model where mindistance = full volume, maxdistance = silence. Rolloffscale is ignored. */ -#define FMOD_3D_CUSTOMROLLOFF 0x04000000 /* This sound will follow a rolloff model defined by Sound::set3DCustomRolloff / Channel::set3DCustomRolloff. */ -#define FMOD_3D_IGNOREGEOMETRY 0x40000000 /* Is not affect by geometry occlusion. If not specified in Sound::setMode, or Channel::setMode, the flag is cleared and it is affected by geometry again. */ -#define FMOD_UNICODE 0x01000000 /* Filename is double-byte unicode. */ -#define FMOD_IGNORETAGS 0x02000000 /* Skips id3v2/asf/etc tag checks when opening a sound, to reduce seek/read overhead when opening files (helps with CD performance). */ -#define FMOD_LOWMEM 0x08000000 /* Removes some features from samples to give a lower memory overhead, like Sound::getName. See remarks. */ -#define FMOD_LOADSECONDARYRAM 0x20000000 /* Load sound into the secondary RAM of supported platform. On PS3, sounds will be loaded into RSX/VRAM. */ -#define FMOD_VIRTUAL_PLAYFROMSTART 0x80000000 /* For sounds that start virtual (due to being quiet or low importance), instead of swapping back to audible, and playing at the correct offset according to time, this flag makes the sound play from the start. */ +#define FMOD_DEFAULT \ + 0x00000000 /* Default for all modes listed below. FMOD_LOOP_OFF, FMOD_2D, \ + FMOD_HARDWARE */ +#define FMOD_LOOP_OFF \ + 0x00000001 /* For non looping sounds. (DEFAULT). Overrides FMOD_LOOP_NORMAL \ + / FMOD_LOOP_BIDI. */ +#define FMOD_LOOP_NORMAL 0x00000002 /* For forward looping sounds. */ +#define FMOD_LOOP_BIDI \ + 0x00000004 /* For bidirectional looping sounds. (only works on software \ + mixed static sounds). */ +#define FMOD_2D 0x00000008 /* Ignores any 3d processing. (DEFAULT). */ +#define FMOD_3D \ + 0x00000010 /* Makes the sound positionable in 3D. Overrides FMOD_2D. */ +#define FMOD_HARDWARE \ + 0x00000020 /* Attempts to make sounds use hardware acceleration. (DEFAULT). \ + Note on platforms that don't support FMOD_HARDWARE (only 3DS, \ + PS Vita, PSP, Wii and Wii U support FMOD_HARDWARE), this will \ + be internally treated as FMOD_SOFTWARE. */ +#define FMOD_SOFTWARE \ + 0x00000040 /* Makes the sound be mixed by the FMOD CPU based software mixer. \ + Overrides FMOD_HARDWARE. Use this for FFT, DSP, compressed \ + sample support, 2D multi-speaker support and other software \ + related features. */ +#define FMOD_CREATESTREAM \ + 0x00000080 /* Decompress at runtime, streaming from the source provided (ie \ + from disk). Overrides FMOD_CREATESAMPLE and \ + FMOD_CREATECOMPRESSEDSAMPLE. Note a stream can only be played \ + once at a time due to a stream only having 1 stream buffer and \ + file handle. Open multiple streams to have them play \ + concurrently. */ +#define FMOD_CREATESAMPLE \ + 0x00000100 /* Decompress at loadtime, decompressing or decoding whole file \ + into memory as the target sample format (ie PCM). Fastest for \ + FMOD_SOFTWARE based playback and most flexible. */ +#define FMOD_CREATECOMPRESSEDSAMPLE \ + 0x00000200 /* Load MP2/MP3/IMAADPCM/CELT/Vorbis/AT9 or XMA into memory and \ + leave it compressed. CELT/Vorbis/AT9 encoding only supported \ + in the FSB file format. During playback the FMOD software \ + mixer will decode it in realtime as a 'compressed sample'. \ + Can only be used in combination with FMOD_SOFTWARE. Overrides \ + FMOD_CREATESAMPLE. If the sound data is not one of the \ + supported formats, it will behave as if it was created with \ + FMOD_CREATESAMPLE and decode the sound into PCM. */ +#define FMOD_OPENUSER \ + 0x00000400 /* Opens a user created static sample or stream. Use \ + FMOD_CREATESOUNDEXINFO to specify format and/or read \ + callbacks. If a user created 'sample' is created with no read \ + callback, the sample will be empty. Use Sound::lock and \ + Sound::unlock to place sound data into the sound if this is \ + the case. */ +#define FMOD_OPENMEMORY \ + 0x00000800 /* "name_or_data" will be interpreted as a pointer to memory \ + instead of filename for creating sounds. Use \ + FMOD_CREATESOUNDEXINFO to specify length. If used with \ + FMOD_CREATESAMPLE or FMOD_CREATECOMPRESSEDSAMPLE, FMOD \ + duplicates the memory into its own buffers. Your own buffer \ + can be freed after open. If used with FMOD_CREATESTREAM, FMOD \ + will stream out of the buffer whose pointer you passed in. In \ + this case, your own buffer should not be freed until you have \ + finished with and released the stream.*/ +#define FMOD_OPENMEMORY_POINT \ + 0x10000000 /* "name_or_data" will be interpreted as a pointer to memory \ + instead of filename for creating sounds. Use \ + FMOD_CREATESOUNDEXINFO to specify length. This differs to \ + FMOD_OPENMEMORY in that it uses the memory as is, without \ + duplicating the memory into its own buffers. For Wii/PSP \ + FMOD_HARDWARE supports this flag for the GCADPCM/VAG formats. \ + On other platforms FMOD_SOFTWARE must be used, as sound \ + hardware on the other platforms (ie PC) cannot access main \ + ram. Cannot be freed after open, only after Sound::release. \ + Will not work if the data is compressed and \ + FMOD_CREATECOMPRESSEDSAMPLE is not used. */ +#define FMOD_OPENRAW \ + 0x00001000 /* Will ignore file format and treat as raw pcm. Use \ + FMOD_CREATESOUNDEXINFO to specify format. Requires at least \ + defaultfrequency, numchannels and format to be specified \ + before it will open. Must be little endian data. */ +#define FMOD_OPENONLY \ + 0x00002000 /* Just open the file, dont prebuffer or read. Good for fast \ + opens for info, or when sound::readData is to be used. */ +#define FMOD_ACCURATETIME \ + 0x00004000 /* For System::createSound - for accurate \ + Sound::getLength/Channel::setPosition on VBR MP3, and \ + MOD/S3M/XM/IT/MIDI files. Scans file first, so takes longer \ + to open. FMOD_OPENONLY does not affect this. */ +#define FMOD_MPEGSEARCH \ + 0x00008000 /* For corrupted / bad MP3 files. This will search all the way \ + through the file until it hits a valid MPEG header. Normally \ + only searches for 4k. */ +#define FMOD_NONBLOCKING \ + 0x00010000 /* For opening sounds and getting streamed subsounds (seeking) \ + asyncronously. Use Sound::getOpenState to poll the state of \ + the sound as it opens or retrieves the subsound in the \ + background. */ +#define FMOD_UNIQUE \ + 0x00020000 /* Unique sound, can only be played one at a time */ +#define FMOD_3D_HEADRELATIVE \ + 0x00040000 /* Make the sound's position, velocity and orientation relative \ + to the listener. */ +#define FMOD_3D_WORLDRELATIVE \ + 0x00080000 /* Make the sound's position, velocity and orientation absolute \ + (relative to the world). (DEFAULT) */ +#define FMOD_3D_INVERSEROLLOFF \ + 0x00100000 /* This sound will follow the inverse rolloff model where \ + mindistance = full volume, maxdistance = where sound stops \ + attenuating, and rolloff is fixed according to the global \ + rolloff factor. (DEFAULT) */ +#define FMOD_3D_LINEARROLLOFF \ + 0x00200000 /* This sound will follow a linear rolloff model where \ + mindistance = full volume, maxdistance = silence. \ + Rolloffscale is ignored. */ +#define FMOD_3D_LINEARSQUAREROLLOFF \ + 0x00400000 /* This sound will follow a linear-square rolloff model where \ + mindistance = full volume, maxdistance = silence. \ + Rolloffscale is ignored. */ +#define FMOD_3D_CUSTOMROLLOFF \ + 0x04000000 /* This sound will follow a rolloff model defined by \ + Sound::set3DCustomRolloff / Channel::set3DCustomRolloff. */ +#define FMOD_3D_IGNOREGEOMETRY \ + 0x40000000 /* Is not affect by geometry occlusion. If not specified in \ + Sound::setMode, or Channel::setMode, the flag is cleared and \ + it is affected by geometry again. */ +#define FMOD_UNICODE 0x01000000 /* Filename is double-byte unicode. */ +#define FMOD_IGNORETAGS \ + 0x02000000 /* Skips id3v2/asf/etc tag checks when opening a sound, to reduce \ + seek/read overhead when opening files (helps with CD \ + performance). */ +#define FMOD_LOWMEM \ + 0x08000000 /* Removes some features from samples to give a lower memory \ + overhead, like Sound::getName. See remarks. */ +#define FMOD_LOADSECONDARYRAM \ + 0x20000000 /* Load sound into the secondary RAM of supported platform. On \ + PS3, sounds will be loaded into RSX/VRAM. */ +#define FMOD_VIRTUAL_PLAYFROMSTART \ + 0x80000000 /* For sounds that start virtual (due to being quiet or low \ + importance), instead of swapping back to audible, and playing \ + at the correct offset according to time, this flag makes the \ + sound play from the start. */ /* [DEFINE_END] */ - /* [ENUM] [ - [DESCRIPTION] - These values describe what state a sound is in after FMOD_NONBLOCKING has been used to open it. + [DESCRIPTION] + These values describe what state a sound is in after FMOD_NONBLOCKING has +been used to open it. [REMARKS] - With streams, if you are using FMOD_NONBLOCKING, note that if the user calls Sound::getSubSound, a stream will go into FMOD_OPENSTATE_SEEKING state and sound related commands will return FMOD_ERR_NOTREADY.
    - With streams, if you are using FMOD_NONBLOCKING, note that if the user calls Channel::getPosition, a stream will go into FMOD_OPENSTATE_SETPOSITION state and sound related commands will return FMOD_ERR_NOTREADY.
    + With streams, if you are using FMOD_NONBLOCKING, note that if the user calls +Sound::getSubSound, a stream will go into FMOD_OPENSTATE_SEEKING state and sound +related commands will return FMOD_ERR_NOTREADY.
    With streams, if you are +using FMOD_NONBLOCKING, note that if the user calls Channel::getPosition, a +stream will go into FMOD_OPENSTATE_SETPOSITION state and sound related commands +will return FMOD_ERR_NOTREADY.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] Sound::getOpenState FMOD_MODE ] */ -typedef enum -{ - FMOD_OPENSTATE_READY = 0, /* Opened and ready to play. */ - FMOD_OPENSTATE_LOADING, /* Initial load in progress. */ - FMOD_OPENSTATE_ERROR, /* Failed to open - file not found, out of memory etc. See return value of Sound::getOpenState for what happened. */ - FMOD_OPENSTATE_CONNECTING, /* Connecting to remote host (internet sounds only). */ - FMOD_OPENSTATE_BUFFERING, /* Buffering data. */ - FMOD_OPENSTATE_SEEKING, /* Seeking to subsound and re-flushing stream buffer. */ - FMOD_OPENSTATE_PLAYING, /* Ready and playing, but not possible to release at this time without stalling the main thread. */ - FMOD_OPENSTATE_SETPOSITION, /* Seeking within a stream to a different position. */ +typedef enum { + FMOD_OPENSTATE_READY = 0, /* Opened and ready to play. */ + FMOD_OPENSTATE_LOADING, /* Initial load in progress. */ + FMOD_OPENSTATE_ERROR, /* Failed to open - file not found, out of memory etc. + See return value of Sound::getOpenState for what + happened. */ + FMOD_OPENSTATE_CONNECTING, /* Connecting to remote host (internet sounds + only). */ + FMOD_OPENSTATE_BUFFERING, /* Buffering data. */ + FMOD_OPENSTATE_SEEKING, /* Seeking to subsound and re-flushing stream buffer. + */ + FMOD_OPENSTATE_PLAYING, /* Ready and playing, but not possible to release at + this time without stalling the main thread. */ + FMOD_OPENSTATE_SETPOSITION, /* Seeking within a stream to a different + position. */ - FMOD_OPENSTATE_MAX, /* Maximum number of open state types. */ - FMOD_OPENSTATE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ + FMOD_OPENSTATE_MAX, /* Maximum number of open state types. */ + FMOD_OPENSTATE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ } FMOD_OPENSTATE; - /* [ENUM] [ - [DESCRIPTION] - These flags are used with SoundGroup::setMaxAudibleBehavior to determine what happens when more sounds - are played than are specified with SoundGroup::setMaxAudible. + [DESCRIPTION] + These flags are used with SoundGroup::setMaxAudibleBehavior to determine +what happens when more sounds are played than are specified with +SoundGroup::setMaxAudible. [REMARKS] - When using FMOD_SOUNDGROUP_BEHAVIOR_MUTE, SoundGroup::setMuteFadeSpeed can be used to stop a sudden transition. - Instead, the time specified will be used to cross fade between the sounds that go silent and the ones that become audible. + When using FMOD_SOUNDGROUP_BEHAVIOR_MUTE, SoundGroup::setMuteFadeSpeed can +be used to stop a sudden transition. Instead, the time specified will be used to +cross fade between the sounds that go silent and the ones that become audible. [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] SoundGroup::setMaxAudibleBehavior SoundGroup::getMaxAudibleBehavior SoundGroup::setMaxAudible @@ -988,129 +1459,205 @@ typedef enum SoundGroup::getMuteFadeSpeed ] */ -typedef enum -{ - FMOD_SOUNDGROUP_BEHAVIOR_FAIL, /* Any sound played that puts the sound count over the SoundGroup::setMaxAudible setting, will simply fail during System::playSound. */ - FMOD_SOUNDGROUP_BEHAVIOR_MUTE, /* Any sound played that puts the sound count over the SoundGroup::setMaxAudible setting, will be silent, then if another sound in the group stops the sound that was silent before becomes audible again. */ - FMOD_SOUNDGROUP_BEHAVIOR_STEALLOWEST, /* Any sound played that puts the sound count over the SoundGroup::setMaxAudible setting, will steal the quietest / least important sound playing in the group. */ +typedef enum { + FMOD_SOUNDGROUP_BEHAVIOR_FAIL, /* Any sound played that puts the sound count + over the SoundGroup::setMaxAudible setting, + will simply fail during System::playSound. + */ + FMOD_SOUNDGROUP_BEHAVIOR_MUTE, /* Any sound played that puts the sound count + over the SoundGroup::setMaxAudible setting, + will be silent, then if another sound in the + group stops the sound that was silent before + becomes audible again. */ + FMOD_SOUNDGROUP_BEHAVIOR_STEALLOWEST, /* Any sound played that puts the sound + count over the + SoundGroup::setMaxAudible setting, + will steal the quietest / least + important sound playing in the group. + */ - FMOD_SOUNDGROUP_BEHAVIOR_MAX, /* Maximum number of open state types. */ - FMOD_SOUNDGROUP_BEHAVIOR_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ + FMOD_SOUNDGROUP_BEHAVIOR_MAX, /* Maximum number of open state types. */ + FMOD_SOUNDGROUP_BEHAVIOR_FORCEINT = + 65536 /* Makes sure this enum is signed 32bit. */ } FMOD_SOUNDGROUP_BEHAVIOR; - /* [ENUM] [ - [DESCRIPTION] + [DESCRIPTION] These callback types are used with Channel::setCallback. [REMARKS] - Each callback has commanddata parameters passed as int unique to the type of callback.
    - See reference to FMOD_CHANNEL_CALLBACK to determine what they might mean for each type of callback.
    -
    - Note! Currently the user must call System::update for these callbacks to trigger! + Each callback has commanddata parameters passed as int unique to the type of +callback.
    See reference to FMOD_CHANNEL_CALLBACK to determine what they +might mean for each type of callback.

    Note! Currently the user +must call System::update for these callbacks to trigger! [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] Channel::setCallback FMOD_CHANNEL_CALLBACK System::update ] */ -typedef enum -{ - FMOD_CHANNEL_CALLBACKTYPE_END, /* Called when a sound ends. */ - FMOD_CHANNEL_CALLBACKTYPE_VIRTUALVOICE, /* Called when a voice is swapped out or swapped in. */ - FMOD_CHANNEL_CALLBACKTYPE_SYNCPOINT, /* Called when a syncpoint is encountered. Can be from wav file markers. */ - FMOD_CHANNEL_CALLBACKTYPE_OCCLUSION, /* Called when the channel has its geometry occlusion value calculated. Can be used to clamp or change the value. */ +typedef enum { + FMOD_CHANNEL_CALLBACKTYPE_END, /* Called when a sound ends. */ + FMOD_CHANNEL_CALLBACKTYPE_VIRTUALVOICE, /* Called when a voice is swapped out + or swapped in. */ + FMOD_CHANNEL_CALLBACKTYPE_SYNCPOINT, /* Called when a syncpoint is + encountered. Can be from wav file + markers. */ + FMOD_CHANNEL_CALLBACKTYPE_OCCLUSION, /* Called when the channel has its + geometry occlusion value calculated. + Can be used to clamp or change the + value. */ - FMOD_CHANNEL_CALLBACKTYPE_MAX, /* Maximum number of callback types supported. */ - FMOD_CHANNEL_CALLBACKTYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ + FMOD_CHANNEL_CALLBACKTYPE_MAX, /* Maximum number of callback types supported. + */ + FMOD_CHANNEL_CALLBACKTYPE_FORCEINT = + 65536 /* Makes sure this enum is signed 32bit. */ } FMOD_CHANNEL_CALLBACKTYPE; - /* [ENUM] [ - [DESCRIPTION] + [DESCRIPTION] These callback types are used with System::setCallback. [REMARKS] - Each callback has commanddata parameters passed as void* unique to the type of callback.
    - See reference to FMOD_SYSTEM_CALLBACK to determine what they might mean for each type of callback.
    -
    - Note! Using FMOD_SYSTEM_CALLBACKTYPE_DEVICELISTCHANGED (on Mac only) requires the application to be running an event loop which will allow external changes to device list to be detected by FMOD. -
    - Note! The 'system' object pointer will be null for FMOD_SYSTEM_CALLBACKTYPE_MEMORYALLOCATIONFAILED callback. + Each callback has commanddata parameters passed as void* unique to the type +of callback.
    See reference to FMOD_SYSTEM_CALLBACK to determine what they +might mean for each type of callback.

    Note! Using +FMOD_SYSTEM_CALLBACKTYPE_DEVICELISTCHANGED (on Mac only) requires the +application to be running an event loop which will allow external changes to +device list to be detected by FMOD.
    Note! The 'system' object +pointer will be null for FMOD_SYSTEM_CALLBACKTYPE_MEMORYALLOCATIONFAILED +callback. [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] System::setCallback FMOD_SYSTEM_CALLBACK System::update DSP::addInput ] */ -typedef enum -{ - FMOD_SYSTEM_CALLBACKTYPE_DEVICELISTCHANGED, /* Called from System::update when the enumerated list of devices has changed. */ - FMOD_SYSTEM_CALLBACKTYPE_DEVICELOST, /* Called from System::update when an output device has been lost due to control panel parameter changes and FMOD cannot automatically recover. */ - FMOD_SYSTEM_CALLBACKTYPE_MEMORYALLOCATIONFAILED, /* Called directly when a memory allocation fails somewhere in FMOD. (NOTE - 'system' will be NULL in this callback type.)*/ - FMOD_SYSTEM_CALLBACKTYPE_THREADCREATED, /* Called directly when a thread is created. */ - FMOD_SYSTEM_CALLBACKTYPE_BADDSPCONNECTION, /* Called when a bad connection was made with DSP::addInput. Usually called from mixer thread because that is where the connections are made. */ - FMOD_SYSTEM_CALLBACKTYPE_BADDSPLEVEL, /* Called when too many effects were added exceeding the maximum tree depth of 128. This is most likely caused by accidentally adding too many DSP effects. Usually called from mixer thread because that is where the connections are made. */ - FMOD_SYSTEM_CALLBACKTYPE_THREADDESTROYED, /* Called directly when a thread is destroyed. */ +typedef enum { + FMOD_SYSTEM_CALLBACKTYPE_DEVICELISTCHANGED, /* Called from System::update when + the enumerated list of devices + has changed. */ + FMOD_SYSTEM_CALLBACKTYPE_DEVICELOST, /* Called from System::update when an + output device has been lost due to + control panel parameter changes and + FMOD cannot automatically recover. */ + FMOD_SYSTEM_CALLBACKTYPE_MEMORYALLOCATIONFAILED, /* Called directly when a + memory allocation fails + somewhere in FMOD. (NOTE + - 'system' will be NULL in + this callback type.)*/ + FMOD_SYSTEM_CALLBACKTYPE_THREADCREATED, /* Called directly when a thread is + created. */ + FMOD_SYSTEM_CALLBACKTYPE_BADDSPCONNECTION, /* Called when a bad connection was + made with DSP::addInput. Usually + called from mixer thread because + that is where the connections + are made. */ + FMOD_SYSTEM_CALLBACKTYPE_BADDSPLEVEL, /* Called when too many effects were + added exceeding the maximum tree + depth of 128. This is most likely + caused by accidentally adding too + many DSP effects. Usually called from + mixer thread because that is where + the connections are made. */ + FMOD_SYSTEM_CALLBACKTYPE_THREADDESTROYED, /* Called directly when a thread is + destroyed. */ - FMOD_SYSTEM_CALLBACKTYPE_MAX, /* Maximum number of callback types supported. */ - FMOD_SYSTEM_CALLBACKTYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ + FMOD_SYSTEM_CALLBACKTYPE_MAX, /* Maximum number of callback types supported. + */ + FMOD_SYSTEM_CALLBACKTYPE_FORCEINT = + 65536 /* Makes sure this enum is signed 32bit. */ } FMOD_SYSTEM_CALLBACKTYPE; - -/* +/* FMOD Callbacks */ -typedef FMOD_RESULT (F_CALLBACK *FMOD_SYSTEM_CALLBACK) (FMOD_SYSTEM *system, FMOD_SYSTEM_CALLBACKTYPE type, void *commanddata1, void *commanddata2); +typedef FMOD_RESULT(F_CALLBACK *FMOD_SYSTEM_CALLBACK)( + FMOD_SYSTEM *system, + FMOD_SYSTEM_CALLBACKTYPE type, + void *commanddata1, + void *commanddata2); -typedef FMOD_RESULT (F_CALLBACK *FMOD_CHANNEL_CALLBACK) (FMOD_CHANNEL *channel, FMOD_CHANNEL_CALLBACKTYPE type, void *commanddata1, void *commanddata2); +typedef FMOD_RESULT(F_CALLBACK *FMOD_CHANNEL_CALLBACK)( + FMOD_CHANNEL *channel, + FMOD_CHANNEL_CALLBACKTYPE type, + void *commanddata1, + void *commanddata2); -typedef FMOD_RESULT (F_CALLBACK *FMOD_SOUND_NONBLOCKCALLBACK)(FMOD_SOUND *sound, FMOD_RESULT result); -typedef FMOD_RESULT (F_CALLBACK *FMOD_SOUND_PCMREADCALLBACK)(FMOD_SOUND *sound, void *data, unsigned int datalen); -typedef FMOD_RESULT (F_CALLBACK *FMOD_SOUND_PCMSETPOSCALLBACK)(FMOD_SOUND *sound, int subsound, unsigned int position, FMOD_TIMEUNIT postype); +typedef FMOD_RESULT(F_CALLBACK *FMOD_SOUND_NONBLOCKCALLBACK)( + FMOD_SOUND *sound, FMOD_RESULT result); +typedef FMOD_RESULT(F_CALLBACK *FMOD_SOUND_PCMREADCALLBACK)( + FMOD_SOUND *sound, void *data, unsigned int datalen); +typedef FMOD_RESULT(F_CALLBACK *FMOD_SOUND_PCMSETPOSCALLBACK)( + FMOD_SOUND *sound, + int subsound, + unsigned int position, + FMOD_TIMEUNIT postype); -typedef FMOD_RESULT (F_CALLBACK *FMOD_FILE_OPENCALLBACK) (const char *name, int unicode, unsigned int *filesize, void **handle, void **userdata); -typedef FMOD_RESULT (F_CALLBACK *FMOD_FILE_CLOSECALLBACK) (void *handle, void *userdata); -typedef FMOD_RESULT (F_CALLBACK *FMOD_FILE_READCALLBACK) (void *handle, void *buffer, unsigned int sizebytes, unsigned int *bytesread, void *userdata); -typedef FMOD_RESULT (F_CALLBACK *FMOD_FILE_SEEKCALLBACK) (void *handle, unsigned int pos, void *userdata); -typedef FMOD_RESULT (F_CALLBACK *FMOD_FILE_ASYNCREADCALLBACK)(FMOD_ASYNCREADINFO *info, void *userdata); -typedef FMOD_RESULT (F_CALLBACK *FMOD_FILE_ASYNCCANCELCALLBACK)(void *handle, void *userdata); +typedef FMOD_RESULT(F_CALLBACK *FMOD_FILE_OPENCALLBACK)( + const char *name, + int unicode, + unsigned int *filesize, + void **handle, + void **userdata); +typedef FMOD_RESULT(F_CALLBACK *FMOD_FILE_CLOSECALLBACK)( + void *handle, void *userdata); +typedef FMOD_RESULT(F_CALLBACK *FMOD_FILE_READCALLBACK)( + void *handle, + void *buffer, + unsigned int sizebytes, + unsigned int *bytesread, + void *userdata); +typedef FMOD_RESULT(F_CALLBACK *FMOD_FILE_SEEKCALLBACK)( + void *handle, unsigned int pos, void *userdata); +typedef FMOD_RESULT(F_CALLBACK *FMOD_FILE_ASYNCREADCALLBACK)( + FMOD_ASYNCREADINFO *info, void *userdata); +typedef FMOD_RESULT(F_CALLBACK *FMOD_FILE_ASYNCCANCELCALLBACK)( + void *handle, void *userdata); -typedef void * (F_CALLBACK *FMOD_MEMORY_ALLOCCALLBACK) (unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr); -typedef void * (F_CALLBACK *FMOD_MEMORY_REALLOCCALLBACK)(void *ptr, unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr); -typedef void (F_CALLBACK *FMOD_MEMORY_FREECALLBACK) (void *ptr, FMOD_MEMORY_TYPE type, const char *sourcestr); - -typedef float (F_CALLBACK *FMOD_3D_ROLLOFFCALLBACK) (FMOD_CHANNEL *channel, float distance); +typedef void *(F_CALLBACK *FMOD_MEMORY_ALLOCCALLBACK)( + unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr); +typedef void *(F_CALLBACK *FMOD_MEMORY_REALLOCCALLBACK)( + void *ptr, unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr); +typedef void(F_CALLBACK *FMOD_MEMORY_FREECALLBACK)( + void *ptr, FMOD_MEMORY_TYPE type, const char *sourcestr); +typedef float(F_CALLBACK *FMOD_3D_ROLLOFFCALLBACK)( + FMOD_CHANNEL *channel, float distance); /* [ENUM] [ - [DESCRIPTION] - List of windowing methods used in spectrum analysis to reduce leakage / transient signals intefering with the analysis.
    - This is a problem with analysis of continuous signals that only have a small portion of the signal sample (the fft window size).
    - Windowing the signal with a curve or triangle tapers the sides of the fft window to help alleviate this problem. + [DESCRIPTION] + List of windowing methods used in spectrum analysis to reduce leakage / +transient signals intefering with the analysis.
    This is a problem with +analysis of continuous signals that only have a small portion of the signal +sample (the fft window size).
    Windowing the signal with a curve or triangle +tapers the sides of the fft window to help alleviate this problem. [REMARKS] - Cyclic signals such as a sine wave that repeat their cycle in a multiple of the window size do not need windowing.
    - I.e. If the sine wave repeats every 1024, 512, 256 etc samples and the FMOD fft window is 1024, then the signal would not need windowing.
    - Not windowing is the same as FMOD_DSP_FFT_WINDOW_RECT, which is the default.
    - If the cycle of the signal (ie the sine wave) is not a multiple of the window size, it will cause frequency abnormalities, so a different windowing method is needed.
    - -
    + Cyclic signals such as a sine wave that repeat their cycle in a multiple of +the window size do not need windowing.
    I.e. If the sine wave repeats every +1024, 512, 256 etc samples and the FMOD fft window is 1024, then the signal +would not need windowing.
    Not windowing is the same as +FMOD_DSP_FFT_WINDOW_RECT, which is the default.
    If the cycle of the signal +(ie the sine wave) is not a multiple of the window size, it will cause frequency +abnormalities, so a different windowing method is needed.

    FMOD_DSP_FFT_WINDOW_RECT.


    @@ -1129,359 +1676,422 @@ typedef float (F_CALLBACK *FMOD_3D_ROLLOFFCALLBACK) (FMOD_CHANNEL *chan FMOD_DSP_FFT_WINDOW_BLACKMANHARRIS.
    - - [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [PLATFORMS] + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android + + [SEE_ALSO] System::getSpectrum Channel::getSpectrum ] */ -typedef enum -{ - FMOD_DSP_FFT_WINDOW_RECT, /* w[n] = 1.0 */ - FMOD_DSP_FFT_WINDOW_TRIANGLE, /* w[n] = TRI(2n/N) */ - FMOD_DSP_FFT_WINDOW_HAMMING, /* w[n] = 0.54 - (0.46 * COS(n/N) ) */ - FMOD_DSP_FFT_WINDOW_HANNING, /* w[n] = 0.5 * (1.0 - COS(n/N) ) */ - FMOD_DSP_FFT_WINDOW_BLACKMAN, /* w[n] = 0.42 - (0.5 * COS(n/N) ) + (0.08 * COS(2.0 * n/N) ) */ - FMOD_DSP_FFT_WINDOW_BLACKMANHARRIS, /* w[n] = 0.35875 - (0.48829 * COS(1.0 * n/N)) + (0.14128 * COS(2.0 * n/N)) - (0.01168 * COS(3.0 * n/N)) */ - - FMOD_DSP_FFT_WINDOW_MAX, /* Maximum number of FFT window types supported. */ - FMOD_DSP_FFT_WINDOW_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ -} FMOD_DSP_FFT_WINDOW; +typedef enum { + FMOD_DSP_FFT_WINDOW_RECT, /* w[n] = 1.0 */ + FMOD_DSP_FFT_WINDOW_TRIANGLE, /* w[n] = TRI(2n/N) */ + FMOD_DSP_FFT_WINDOW_HAMMING, /* w[n] = 0.54 - (0.46 * COS(n/N) ) */ + FMOD_DSP_FFT_WINDOW_HANNING, /* w[n] = 0.5 * (1.0 - COS(n/N) ) */ + FMOD_DSP_FFT_WINDOW_BLACKMAN, /* w[n] = 0.42 - (0.5 * COS(n/N) ) + (0.08 * + COS(2.0 * n/N) ) */ + FMOD_DSP_FFT_WINDOW_BLACKMANHARRIS, /* w[n] = 0.35875 - (0.48829 * COS(1.0 * + n/N)) + (0.14128 * COS(2.0 * n/N)) - + (0.01168 * COS(3.0 * n/N)) */ + FMOD_DSP_FFT_WINDOW_MAX, /* Maximum number of FFT window types supported. */ + FMOD_DSP_FFT_WINDOW_FORCEINT = + 65536 /* Makes sure this enum is signed 32bit. */ +} FMOD_DSP_FFT_WINDOW; /* [ENUM] [ - [DESCRIPTION] - List of interpolation types that the FMOD Ex software mixer supports. + [DESCRIPTION] + List of interpolation types that the FMOD Ex software mixer supports. [REMARKS] The default resampler type is FMOD_DSP_RESAMPLER_LINEAR.
    - Use System::setSoftwareFormat to tell FMOD the resampling quality you require for FMOD_SOFTWARE based sounds. + Use System::setSoftwareFormat to tell FMOD the resampling quality you +require for FMOD_SOFTWARE based sounds. [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] System::setSoftwareFormat System::getSoftwareFormat ] */ -typedef enum -{ - FMOD_DSP_RESAMPLER_NOINTERP, /* No interpolation. High frequency aliasing hiss will be audible depending on the sample rate of the sound. */ - FMOD_DSP_RESAMPLER_LINEAR, /* Linear interpolation (default method). Fast and good quality, causes very slight lowpass effect on low frequency sounds. */ - FMOD_DSP_RESAMPLER_CUBIC, /* Cubic interpolation. Slower than linear interpolation but better quality. */ - FMOD_DSP_RESAMPLER_SPLINE, /* 5 point spline interpolation. Slowest resampling method but best quality. */ +typedef enum { + FMOD_DSP_RESAMPLER_NOINTERP, /* No interpolation. High frequency aliasing + hiss will be audible depending on the sample + rate of the sound. */ + FMOD_DSP_RESAMPLER_LINEAR, /* Linear interpolation (default method). Fast and + good quality, causes very slight lowpass effect + on low frequency sounds. */ + FMOD_DSP_RESAMPLER_CUBIC, /* Cubic interpolation. Slower than linear + interpolation but better quality. */ + FMOD_DSP_RESAMPLER_SPLINE, /* 5 point spline interpolation. Slowest + resampling method but best quality. */ - FMOD_DSP_RESAMPLER_MAX, /* Maximum number of resample methods supported. */ - FMOD_DSP_RESAMPLER_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ + FMOD_DSP_RESAMPLER_MAX, /* Maximum number of resample methods supported. */ + FMOD_DSP_RESAMPLER_FORCEINT = + 65536 /* Makes sure this enum is signed 32bit. */ } FMOD_DSP_RESAMPLER; - /* [ENUM] [ - [DESCRIPTION] - List of tag types that could be stored within a sound. These include id3 tags, metadata from netstreams and vorbis/asf data. + [DESCRIPTION] + List of tag types that could be stored within a sound. These include id3 +tags, metadata from netstreams and vorbis/asf data. [REMARKS] [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] Sound::getTag ] */ -typedef enum -{ - FMOD_TAGTYPE_UNKNOWN = 0, - FMOD_TAGTYPE_ID3V1, - FMOD_TAGTYPE_ID3V2, - FMOD_TAGTYPE_VORBISCOMMENT, - FMOD_TAGTYPE_SHOUTCAST, - FMOD_TAGTYPE_ICECAST, - FMOD_TAGTYPE_ASF, - FMOD_TAGTYPE_MIDI, - FMOD_TAGTYPE_PLAYLIST, - FMOD_TAGTYPE_FMOD, - FMOD_TAGTYPE_USER, +typedef enum { + FMOD_TAGTYPE_UNKNOWN = 0, + FMOD_TAGTYPE_ID3V1, + FMOD_TAGTYPE_ID3V2, + FMOD_TAGTYPE_VORBISCOMMENT, + FMOD_TAGTYPE_SHOUTCAST, + FMOD_TAGTYPE_ICECAST, + FMOD_TAGTYPE_ASF, + FMOD_TAGTYPE_MIDI, + FMOD_TAGTYPE_PLAYLIST, + FMOD_TAGTYPE_FMOD, + FMOD_TAGTYPE_USER, - FMOD_TAGTYPE_MAX, /* Maximum number of tag types supported. */ - FMOD_TAGTYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ + FMOD_TAGTYPE_MAX, /* Maximum number of tag types supported. */ + FMOD_TAGTYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ } FMOD_TAGTYPE; - /* [ENUM] [ - [DESCRIPTION] + [DESCRIPTION] List of data types that can be returned by Sound::getTag [REMARKS] [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] Sound::getTag ] */ -typedef enum -{ - FMOD_TAGDATATYPE_BINARY = 0, - FMOD_TAGDATATYPE_INT, - FMOD_TAGDATATYPE_FLOAT, - FMOD_TAGDATATYPE_STRING, - FMOD_TAGDATATYPE_STRING_UTF16, - FMOD_TAGDATATYPE_STRING_UTF16BE, - FMOD_TAGDATATYPE_STRING_UTF8, - FMOD_TAGDATATYPE_CDTOC, +typedef enum { + FMOD_TAGDATATYPE_BINARY = 0, + FMOD_TAGDATATYPE_INT, + FMOD_TAGDATATYPE_FLOAT, + FMOD_TAGDATATYPE_STRING, + FMOD_TAGDATATYPE_STRING_UTF16, + FMOD_TAGDATATYPE_STRING_UTF16BE, + FMOD_TAGDATATYPE_STRING_UTF8, + FMOD_TAGDATATYPE_CDTOC, - FMOD_TAGDATATYPE_MAX, /* Maximum number of tag datatypes supported. */ - FMOD_TAGDATATYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ + FMOD_TAGDATATYPE_MAX, /* Maximum number of tag datatypes supported. */ + FMOD_TAGDATATYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ } FMOD_TAGDATATYPE; - /* [ENUM] [ - [DESCRIPTION] + [DESCRIPTION] Types of delay that can be used with Channel::setDelay / Channel::getDelay. [REMARKS] - If you haven't called Channel::setDelay yet, if you call Channel::getDelay with FMOD_DELAYTYPE_DSPCLOCK_START it will return the - equivalent global DSP clock value to determine when a channel started, so that you can use it for other channels to sync against.
    -
    - Use System::getDSPClock to also get the current dspclock time, a base for future calls to Channel::setDelay.
    -
    - Use FMOD_64BIT_ADD or FMOD_64BIT_SUB to add a hi/lo combination together and cope with wraparound. -
    - If FMOD_DELAYTYPE_END_MS is specified, the value is not treated as a 64 bit number, just the delayhi value is used and it is treated as milliseconds. + If you haven't called Channel::setDelay yet, if you call Channel::getDelay +with FMOD_DELAYTYPE_DSPCLOCK_START it will return the equivalent global DSP +clock value to determine when a channel started, so that you can use it for +other channels to sync against.

    Use System::getDSPClock to also get the +current dspclock time, a base for future calls to Channel::setDelay.

    + Use FMOD_64BIT_ADD or FMOD_64BIT_SUB to add a hi/lo combination together and +cope with wraparound.
    If FMOD_DELAYTYPE_END_MS is specified, the value is +not treated as a 64 bit number, just the delayhi value is used and it is treated +as milliseconds. [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] Channel::setDelay Channel::getDelay System::getDSPClock ] */ -typedef enum -{ - FMOD_DELAYTYPE_END_MS, /* Delay at the end of the sound in milliseconds. Use delayhi only. Channel::isPlaying will remain true until this delay has passed even though the sound itself has stopped playing.*/ - FMOD_DELAYTYPE_DSPCLOCK_START, /* Time the sound started if Channel::getDelay is used, or if Channel::setDelay is used, the sound will delay playing until this exact tick. */ - FMOD_DELAYTYPE_DSPCLOCK_END, /* Time the sound should end. If this is non-zero, the channel will go silent at this exact tick. */ - FMOD_DELAYTYPE_DSPCLOCK_PAUSE, /* Time the sound should pause. If this is non-zero, the channel will pause at this exact tick. */ +typedef enum { + FMOD_DELAYTYPE_END_MS, /* Delay at the end of the sound in milliseconds. Use + delayhi only. Channel::isPlaying will remain true + until this delay has passed even though the sound + itself has stopped playing.*/ + FMOD_DELAYTYPE_DSPCLOCK_START, /* Time the sound started if Channel::getDelay + is used, or if Channel::setDelay is used, + the sound will delay playing until this + exact tick. */ + FMOD_DELAYTYPE_DSPCLOCK_END, /* Time the sound should end. If this is + non-zero, the channel will go silent at this + exact tick. */ + FMOD_DELAYTYPE_DSPCLOCK_PAUSE, /* Time the sound should pause. If this is + non-zero, the channel will pause at this + exact tick. */ - FMOD_DELAYTYPE_MAX, /* Maximum number of tag datatypes supported. */ - FMOD_DELAYTYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ + FMOD_DELAYTYPE_MAX, /* Maximum number of tag datatypes supported. */ + FMOD_DELAYTYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ } FMOD_DELAYTYPE; - -#define FMOD_64BIT_ADD(_hi1, _lo1, _hi2, _lo2) _hi1 += ((_hi2) + ((((_lo1) + (_lo2)) < (_lo1)) ? 1 : 0)); (_lo1) += (_lo2); -#define FMOD_64BIT_SUB(_hi1, _lo1, _hi2, _lo2) _hi1 -= ((_hi2) + ((((_lo1) - (_lo2)) > (_lo1)) ? 1 : 0)); (_lo1) -= (_lo2); - +#define FMOD_64BIT_ADD(_hi1, _lo1, _hi2, _lo2) \ + _hi1 += ((_hi2) + ((((_lo1) + (_lo2)) < (_lo1)) ? 1 : 0)); \ + (_lo1) += (_lo2); +#define FMOD_64BIT_SUB(_hi1, _lo1, _hi2, _lo2) \ + _hi1 -= ((_hi2) + ((((_lo1) - (_lo2)) > (_lo1)) ? 1 : 0)); \ + (_lo1) -= (_lo2); /* -[STRUCTURE] +[STRUCTURE] [ - [DESCRIPTION] + [DESCRIPTION] Structure describing a piece of tag data. [REMARKS] - Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
    - Members marked with [w] mean the variable can be written to. The user can set the value.
    + Members marked with [r] mean the variable is modified by FMOD and is for +reading purposes only. Do not change this value.
    Members marked with [w] +mean the variable can be written to. The user can set the value.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] Sound::getTag FMOD_TAGTYPE FMOD_TAGDATATYPE ] */ -typedef struct FMOD_TAG -{ - FMOD_TAGTYPE type; /* [r] The type of this tag. */ - FMOD_TAGDATATYPE datatype; /* [r] The type of data that this tag contains */ - char *name; /* [r] The name of this tag i.e. "TITLE", "ARTIST" etc. */ - void *data; /* [r] Pointer to the tag data - its format is determined by the datatype member */ - unsigned int datalen; /* [r] Length of the data contained in this tag */ - FMOD_BOOL updated; /* [r] True if this tag has been updated since last being accessed with Sound::getTag */ +typedef struct FMOD_TAG { + FMOD_TAGTYPE type; /* [r] The type of this tag. */ + FMOD_TAGDATATYPE datatype; /* [r] The type of data that this tag contains */ + char *name; /* [r] The name of this tag i.e. "TITLE", "ARTIST" etc. */ + void *data; /* [r] Pointer to the tag data - its format is determined by the + datatype member */ + unsigned int datalen; /* [r] Length of the data contained in this tag */ + FMOD_BOOL updated; /* [r] True if this tag has been updated since last being + accessed with Sound::getTag */ } FMOD_TAG; - /* -[STRUCTURE] +[STRUCTURE] [ - [DESCRIPTION] + [DESCRIPTION] Structure describing a CD/DVD table of contents [REMARKS] - Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
    - Members marked with [w] mean the variable can be written to. The user can set the value.
    + Members marked with [r] mean the variable is modified by FMOD and is for +reading purposes only. Do not change this value.
    Members marked with [w] +mean the variable can be written to. The user can set the value.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] Sound::getTag ] */ -typedef struct FMOD_CDTOC -{ - int numtracks; /* [r] The number of tracks on the CD */ - int min[100]; /* [r] The start offset of each track in minutes */ - int sec[100]; /* [r] The start offset of each track in seconds */ - int frame[100]; /* [r] The start offset of each track in frames */ +typedef struct FMOD_CDTOC { + int numtracks; /* [r] The number of tracks on the CD */ + int min[100]; /* [r] The start offset of each track in minutes */ + int sec[100]; /* [r] The start offset of each track in seconds */ + int frame[100]; /* [r] The start offset of each track in frames */ } FMOD_CDTOC; - /* [DEFINE] [ [NAME] FMOD_TIMEUNIT - [DESCRIPTION] - List of time types that can be returned by Sound::getLength and used with Channel::setPosition or Channel::getPosition. + [DESCRIPTION] + List of time types that can be returned by Sound::getLength and used with +Channel::setPosition or Channel::getPosition. [REMARKS] - FMOD_TIMEUNIT_SENTENCE_MS, FMOD_TIMEUNIT_SENTENCE_PCM, FMOD_TIMEUNIT_SENTENCE_PCMBYTES, FMOD_TIMEUNIT_SENTENCE and FMOD_TIMEUNIT_SENTENCE_SUBSOUND are only supported by Channel functions. - Do not combine flags except FMOD_TIMEUNIT_BUFFERED. + FMOD_TIMEUNIT_SENTENCE_MS, FMOD_TIMEUNIT_SENTENCE_PCM, +FMOD_TIMEUNIT_SENTENCE_PCMBYTES, FMOD_TIMEUNIT_SENTENCE and +FMOD_TIMEUNIT_SENTENCE_SUBSOUND are only supported by Channel functions. Do not +combine flags except FMOD_TIMEUNIT_BUFFERED. [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] Sound::getLength Channel::setPosition Channel::getPosition ] */ -#define FMOD_TIMEUNIT_MS 0x00000001 /* Milliseconds. */ -#define FMOD_TIMEUNIT_PCM 0x00000002 /* PCM samples, related to milliseconds * samplerate / 1000. */ -#define FMOD_TIMEUNIT_PCMBYTES 0x00000004 /* Bytes, related to PCM samples * channels * datawidth (ie 16bit = 2 bytes). */ -#define FMOD_TIMEUNIT_RAWBYTES 0x00000008 /* Raw file bytes of (compressed) sound data (does not include headers). Only used by Sound::getLength and Channel::getPosition. */ -#define FMOD_TIMEUNIT_PCMFRACTION 0x00000010 /* Fractions of 1 PCM sample. Unsigned int range 0 to 0xFFFFFFFF. Used for sub-sample granularity for DSP purposes. */ -#define FMOD_TIMEUNIT_MODORDER 0x00000100 /* MOD/S3M/XM/IT. Order in a sequenced module format. Use Sound::getFormat to determine the PCM format being decoded to. */ -#define FMOD_TIMEUNIT_MODROW 0x00000200 /* MOD/S3M/XM/IT. Current row in a sequenced module format. Sound::getLength will return the number of rows in the currently playing or seeked to pattern. */ -#define FMOD_TIMEUNIT_MODPATTERN 0x00000400 /* MOD/S3M/XM/IT. Current pattern in a sequenced module format. Sound::getLength will return the number of patterns in the song and Channel::getPosition will return the currently playing pattern. */ -#define FMOD_TIMEUNIT_SENTENCE_MS 0x00010000 /* Currently playing subsound in a sentence time in milliseconds. */ -#define FMOD_TIMEUNIT_SENTENCE_PCM 0x00020000 /* Currently playing subsound in a sentence time in PCM Samples, related to milliseconds * samplerate / 1000. */ -#define FMOD_TIMEUNIT_SENTENCE_PCMBYTES 0x00040000 /* Currently playing subsound in a sentence time in bytes, related to PCM samples * channels * datawidth (ie 16bit = 2 bytes). */ -#define FMOD_TIMEUNIT_SENTENCE 0x00080000 /* Currently playing sentence index according to the channel. */ -#define FMOD_TIMEUNIT_SENTENCE_SUBSOUND 0x00100000 /* Currently playing subsound index in a sentence. */ -#define FMOD_TIMEUNIT_BUFFERED 0x10000000 /* Time value as seen by buffered stream. This is always ahead of audible time, and is only used for processing. */ +#define FMOD_TIMEUNIT_MS 0x00000001 /* Milliseconds. */ +#define FMOD_TIMEUNIT_PCM \ + 0x00000002 /* PCM samples, related to milliseconds * samplerate / 1000. */ +#define FMOD_TIMEUNIT_PCMBYTES \ + 0x00000004 /* Bytes, related to PCM samples * channels * datawidth (ie 16bit \ + = 2 bytes). */ +#define FMOD_TIMEUNIT_RAWBYTES \ + 0x00000008 /* Raw file bytes of (compressed) sound data (does not include \ + headers). Only used by Sound::getLength and \ + Channel::getPosition. */ +#define FMOD_TIMEUNIT_PCMFRACTION \ + 0x00000010 /* Fractions of 1 PCM sample. Unsigned int range 0 to \ + 0xFFFFFFFF. Used for sub-sample granularity for DSP purposes. \ + */ +#define FMOD_TIMEUNIT_MODORDER \ + 0x00000100 /* MOD/S3M/XM/IT. Order in a sequenced module format. Use \ + Sound::getFormat to determine the PCM format being decoded to. \ + */ +#define FMOD_TIMEUNIT_MODROW \ + 0x00000200 /* MOD/S3M/XM/IT. Current row in a sequenced module format. \ + Sound::getLength will return the number of rows in the \ + currently playing or seeked to pattern. */ +#define FMOD_TIMEUNIT_MODPATTERN \ + 0x00000400 /* MOD/S3M/XM/IT. Current pattern in a sequenced module format. \ + Sound::getLength will return the number of patterns in the \ + song and Channel::getPosition will return the currently \ + playing pattern. */ +#define FMOD_TIMEUNIT_SENTENCE_MS \ + 0x00010000 /* Currently playing subsound in a sentence time in milliseconds. \ + */ +#define FMOD_TIMEUNIT_SENTENCE_PCM \ + 0x00020000 /* Currently playing subsound in a sentence time in PCM Samples, \ + related to milliseconds * samplerate / 1000. */ +#define FMOD_TIMEUNIT_SENTENCE_PCMBYTES \ + 0x00040000 /* Currently playing subsound in a sentence time in bytes, \ + related to PCM samples * channels * datawidth (ie 16bit = 2 \ + bytes). */ +#define FMOD_TIMEUNIT_SENTENCE \ + 0x00080000 /* Currently playing sentence index according to the channel. */ +#define FMOD_TIMEUNIT_SENTENCE_SUBSOUND \ + 0x00100000 /* Currently playing subsound index in a sentence. */ +#define FMOD_TIMEUNIT_BUFFERED \ + 0x10000000 /* Time value as seen by buffered stream. This is always ahead \ + of audible time, and is only used for processing. */ /* [DEFINE_END] */ - /* [ENUM] [ [DESCRIPTION] - When creating a multichannel sound, FMOD will pan them to their default speaker locations, for example a 6 channel sound will default to one channel per 5.1 output speaker.
    - Another example is a stereo sound. It will default to left = front left, right = front right.
    -
    - This is for sounds that are not 'default'. For example you might have a sound that is 6 channels but actually made up of 3 stereo pairs, that should all be located in front left, front right only. + When creating a multichannel sound, FMOD will pan them to their default +speaker locations, for example a 6 channel sound will default to one channel +per 5.1 output speaker.
    Another example is a stereo sound. It will default +to left = front left, right = front right.

    This is for sounds that are +not 'default'. For example you might have a sound that is 6 channels but +actually made up of 3 stereo pairs, that should all be located in front left, +front right only. [REMARKS] For full flexibility of speaker assignments, use Channel::setSpeakerLevels. [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] FMOD_CREATESOUNDEXINFO Channel::setSpeakerLevels ] */ -typedef enum -{ - FMOD_SPEAKERMAPTYPE_DEFAULT, /* This is the default, and just means FMOD decides which speakers it puts the source channels. */ - FMOD_SPEAKERMAPTYPE_ALLMONO, /* This means the sound is made up of all mono sounds. All voices will be panned to the front center by default in this case. */ - FMOD_SPEAKERMAPTYPE_ALLSTEREO, /* This means the sound is made up of all stereo sounds. All voices will be panned to front left and front right alternating every second channel. */ - FMOD_SPEAKERMAPTYPE_51_PROTOOLS /* Map a 5.1 sound to use protools L C R Ls Rs LFE mapping. Will return an error if not a 6 channel sound. */ +typedef enum { + FMOD_SPEAKERMAPTYPE_DEFAULT, /* This is the default, and just means FMOD + decides which speakers it puts the source + channels. */ + FMOD_SPEAKERMAPTYPE_ALLMONO, /* This means the sound is made up of all mono + sounds. All voices will be panned to the + front center by default in this case. */ + FMOD_SPEAKERMAPTYPE_ALLSTEREO, /* This means the sound is made up of all + stereo sounds. All voices will be panned to + front left and front right alternating every + second channel. */ + FMOD_SPEAKERMAPTYPE_51_PROTOOLS /* Map a 5.1 sound to use protools L C R Ls Rs + LFE mapping. Will return an error if not a + 6 channel sound. */ } FMOD_SPEAKERMAPTYPE; - /* -[STRUCTURE] +[STRUCTURE] [ [DESCRIPTION] - Use this structure with System::createSound when more control is needed over loading.
    - The possible reasons to use this with System::createSound are:
    + Use this structure with System::createSound when more control is needed over +loading.
    The possible reasons to use this with System::createSound are:
  • Loading a file from memory. -
  • Loading a file from within another larger (possibly wad/pak) file, by giving the loader an offset and length. -
  • To create a user created / non file based sound. -
  • To specify a starting subsound to seek to within a multi-sample sounds (ie FSB/DLS/SF2) when created as a stream. -
  • To specify which subsounds to load for multi-sample sounds (ie FSB/DLS/SF2) so that memory is saved and only a subset is actually loaded/read from disk. -
  • To specify 'piggyback' read and seek callbacks for capture of sound data as fmod reads and decodes it. Useful for ripping decoded PCM data from sounds as they are loaded / played. -
  • To specify a MIDI DLS/SF2 sample set file to load when opening a MIDI file. - See below on what members to fill for each of the above types of sound you want to create. +
  • Loading a file from within another larger (possibly wad/pak) file, by +giving the loader an offset and length.
  • To create a user created / non file +based sound.
  • To specify a starting subsound to seek to within a multi-sample +sounds (ie FSB/DLS/SF2) when created as a stream.
  • To specify which subsounds +to load for multi-sample sounds (ie FSB/DLS/SF2) so that memory is saved and +only a subset is actually loaded/read from disk.
  • To specify 'piggyback' read +and seek callbacks for capture of sound data as fmod reads and decodes it. +Useful for ripping decoded PCM data from sounds as they are loaded / played. +
  • To specify a MIDI DLS/SF2 sample set file to load when opening a MIDI +file. See below on what members to fill for each of the above types of sound you +want to create. [REMARKS] - This structure is optional! Specify 0 or NULL in System::createSound if you don't need it!
    -
    - Loading a file from memory.
    -
  • Create the sound using the FMOD_OPENMEMORY flag.
    -
  • Mandatory. Specify 'length' for the size of the memory block in bytes. -
  • Other flags are optional. -
    -
    - Loading a file from within another larger (possibly wad/pak) file, by giving the loader an offset and length.
    -
  • Mandatory. Specify 'fileoffset' and 'length'. -
  • Other flags are optional. -
    -
    - To create a user created / non file based sound.
    -
  • Create the sound using the FMOD_OPENUSER flag. -
  • Mandatory. Specify 'defaultfrequency, 'numchannels' and 'format'. -
  • Other flags are optional. -
    -
    - To specify a starting subsound to seek to and flush with, within a multi-sample stream (ie FSB/DLS/SF2).
    -
    -
  • Mandatory. Specify 'initialsubsound'. -
    -
    - To specify which subsounds to load for multi-sample sounds (ie FSB/DLS/SF2) so that memory is saved and only a subset is actually loaded/read from disk.
    -
    -
  • Mandatory. Specify 'inclusionlist' and 'inclusionlistnum'. -
    -
    - To specify 'piggyback' read and seek callbacks for capture of sound data as fmod reads and decodes it. Useful for ripping decoded PCM data from sounds as they are loaded / played.
    -
    + This structure is optional! Specify 0 or NULL in System::createSound if you +don't need it!

    Loading a file from memory.
  • Create the +sound using the FMOD_OPENMEMORY flag.
  • Mandatory. Specify 'length' for +the size of the memory block in bytes.
  • Other flags are optional.

    + Loading a file from within another larger (possibly wad/pak) file, by +giving the loader an offset and length.
  • Mandatory. Specify +'fileoffset' and 'length'.
  • Other flags are optional.

    To create +a user created / non file based sound.
  • Create the sound using the +FMOD_OPENUSER flag.
  • Mandatory. Specify 'defaultfrequency, 'numchannels' and +'format'.
  • Other flags are optional.

    To specify a starting +subsound to seek to and flush with, within a multi-sample stream (ie +FSB/DLS/SF2).

  • Mandatory. Specify 'initialsubsound'.

    + To specify which subsounds to load for multi-sample sounds (ie +FSB/DLS/SF2) so that memory is saved and only a subset is actually loaded/read +from disk.

  • Mandatory. Specify 'inclusionlist' and +'inclusionlistnum'.

    To specify 'piggyback' read and seek callbacks +for capture of sound data as fmod reads and decodes it. Useful for ripping +decoded PCM data from sounds as they are loaded / played.

  • Mandatory. Specify 'pcmreadcallback' and 'pcmseekcallback'.

    - To specify a MIDI DLS/SF2 sample set file to load when opening a MIDI file.
    -
    -
  • Mandatory. Specify 'dlsname'. -
    -
    - Setting the 'decodebuffersize' is for cpu intensive codecs that may be causing stuttering, not file intensive codecs (ie those from CD or netstreams) which are normally - altered with System::setStreamBufferSize. As an example of cpu intensive codecs, an mp3 file will take more cpu to decode than a PCM wav file.
    - If you have a stuttering effect, then it is using more cpu than the decode buffer playback rate can keep up with. Increasing the decode buffersize will most likely solve this problem.
    -
    -
    - FSB codec. If inclusionlist and numsubsounds are used together, this will trigger a special mode where subsounds are shuffled down to save memory. (useful for large FSB - files where you only want to load 1 sound). There will be no gaps, ie no null subsounds. As an example, if there are 10,000 subsounds and there is an inclusionlist with only 1 entry, - and numsubsounds = 1, then subsound 0 will be that entry, and there will only be the memory allocated for 1 subsound. Previously there would still be 10,000 subsound pointers and other - associated codec entries allocated along with it multiplied by 10,000.
    -
    - Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
    - Members marked with [w] mean the variable can be written to. The user can set the value.
    + To specify a MIDI DLS/SF2 sample set file to load when opening a MIDI +file.

  • Mandatory. Specify 'dlsname'.

    Setting the +'decodebuffersize' is for cpu intensive codecs that may be causing stuttering, +not file intensive codecs (ie those from CD or netstreams) which are normally + altered with System::setStreamBufferSize. As an example of cpu intensive +codecs, an mp3 file will take more cpu to decode than a PCM wav file.
    If you +have a stuttering effect, then it is using more cpu than the decode buffer +playback rate can keep up with. Increasing the decode buffersize will most +likely solve this problem.


    FSB codec. If inclusionlist and +numsubsounds are used together, this will trigger a special mode where subsounds +are shuffled down to save memory. (useful for large FSB files where you only +want to load 1 sound). There will be no gaps, ie no null subsounds. As an +example, if there are 10,000 subsounds and there is an inclusionlist with only 1 +entry, and numsubsounds = 1, then subsound 0 will be that entry, and there will +only be the memory allocated for 1 subsound. Previously there would still be +10,000 subsound pointers and other associated codec entries allocated along with +it multiplied by 10,000.

    Members marked with [r] mean the variable is +modified by FMOD and is for reading purposes only. Do not change this +value.
    Members marked with [w] mean the variable can be written to. The +user can set the value.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] System::createSound @@ -1492,66 +2102,182 @@ typedef enum FMOD_SPEAKERMAPTYPE ] */ -typedef struct FMOD_CREATESOUNDEXINFO -{ - int cbsize; /* [w] Size of this structure. This is used so the structure can be expanded in the future and still work on older versions of FMOD Ex. */ - unsigned int length; /* [w] Optional. Specify 0 to ignore. Size in bytes of file to load, or sound to create (in this case only if FMOD_OPENUSER is used). Required if loading from memory. If 0 is specified, then it will use the size of the file (unless loading from memory then an error will be returned). */ - unsigned int fileoffset; /* [w] Optional. Specify 0 to ignore. Offset from start of the file to start loading from. This is useful for loading files from inside big data files. */ - int numchannels; /* [w] Optional. Specify 0 to ignore. Number of channels in a sound mandatory if FMOD_OPENUSER or FMOD_OPENRAW is used. */ - int defaultfrequency; /* [w] Optional. Specify 0 to ignore. Default frequency of sound in a sound mandatory if FMOD_OPENUSER or FMOD_OPENRAW is used. Other formats use the frequency determined by the file format. */ - FMOD_SOUND_FORMAT format; /* [w] Optional. Specify 0 or FMOD_SOUND_FORMAT_NONE to ignore. Format of the sound mandatory if FMOD_OPENUSER or FMOD_OPENRAW is used. Other formats use the format determined by the file format. */ - unsigned int decodebuffersize; /* [w] Optional. Specify 0 to ignore. For streams. This determines the size of the double buffer (in PCM samples) that a stream uses. Use this for user created streams if you want to determine the size of the callback buffer passed to you. Specify 0 to use FMOD's default size which is currently equivalent to 400ms of the sound format created/loaded. */ - int initialsubsound; /* [w] Optional. Specify 0 to ignore. In a multi-sample file format such as .FSB/.DLS/.SF2, specify the initial subsound to seek to, only if FMOD_CREATESTREAM is used. */ - int numsubsounds; /* [w] Optional. Specify 0 to ignore or have no subsounds. In a sound created with FMOD_OPENUSER, specify the number of subsounds that are accessable with Sound::getSubSound. If not created with FMOD_OPENUSER, this will limit the number of subsounds loaded within a multi-subsound file. If using FSB, then if FMOD_CREATESOUNDEXINFO::inclusionlist is used, this will shuffle subsounds down so that there are not any gaps. It will mean that the indices of the sounds will be different. */ - int *inclusionlist; /* [w] Optional. Specify 0 to ignore. In a multi-sample format such as .FSB/.DLS/.SF2 it may be desirable to specify only a subset of sounds to be loaded out of the whole file. This is an array of subsound indices to load into memory when created. */ - int inclusionlistnum; /* [w] Optional. Specify 0 to ignore. This is the number of integers contained within the inclusionlist array. */ - FMOD_SOUND_PCMREADCALLBACK pcmreadcallback; /* [w] Optional. Specify 0 to ignore. Callback to 'piggyback' on FMOD's read functions and accept or even write PCM data while FMOD is opening the sound. Used for user sounds created with FMOD_OPENUSER or for capturing decoded data as FMOD reads it. */ - FMOD_SOUND_PCMSETPOSCALLBACK pcmsetposcallback; /* [w] Optional. Specify 0 to ignore. Callback for when the user calls a seeking function such as Channel::setTime or Channel::setPosition within a multi-sample sound, and for when it is opened.*/ - FMOD_SOUND_NONBLOCKCALLBACK nonblockcallback; /* [w] Optional. Specify 0 to ignore. Callback for successful completion, or error while loading a sound that used the FMOD_NONBLOCKING flag. Also called duing seeking, when setPosition is called or a stream is restarted. */ - const char *dlsname; /* [w] Optional. Specify 0 to ignore. Filename for a DLS or SF2 sample set when loading a MIDI file. If not specified, on Windows it will attempt to open /windows/system32/drivers/gm.dls or /windows/system32/drivers/etc/gm.dls, on Mac it will attempt to load /System/Library/Components/CoreAudio.component/Contents/Resources/gs_instruments.dls, otherwise the MIDI will fail to open. Current DLS support is for level 1 of the specification. */ - const char *encryptionkey; /* [w] Optional. Specify 0 to ignore. Key for encrypted FSB file. Without this key an encrypted FSB file will not load. */ - int maxpolyphony; /* [w] Optional. Specify 0 to ignore. For sequenced formats with dynamic channel allocation such as .MID and .IT, this specifies the maximum voice count allowed while playing. .IT defaults to 64. .MID defaults to 32. */ - void *userdata; /* [w] Optional. Specify 0 to ignore. This is user data to be attached to the sound during creation. Access via Sound::getUserData. Note: This is not passed to FMOD_FILE_OPENCALLBACK, that is a different userdata that is file specific. */ - FMOD_SOUND_TYPE suggestedsoundtype; /* [w] Optional. Specify 0 or FMOD_SOUND_TYPE_UNKNOWN to ignore. Instead of scanning all codec types, use this to speed up loading by making it jump straight to this codec. */ - FMOD_FILE_OPENCALLBACK useropen; /* [w] Optional. Specify 0 to ignore. Callback for opening this file. */ - FMOD_FILE_CLOSECALLBACK userclose; /* [w] Optional. Specify 0 to ignore. Callback for closing this file. */ - FMOD_FILE_READCALLBACK userread; /* [w] Optional. Specify 0 to ignore. Callback for reading from this file. */ - FMOD_FILE_SEEKCALLBACK userseek; /* [w] Optional. Specify 0 to ignore. Callback for seeking within this file. */ - FMOD_FILE_ASYNCREADCALLBACK userasyncread; /* [w] Optional. Specify 0 to ignore. Callback for seeking within this file. */ - FMOD_FILE_ASYNCCANCELCALLBACK userasynccancel; /* [w] Optional. Specify 0 to ignore. Callback for seeking within this file. */ - FMOD_SPEAKERMAPTYPE speakermap; /* [w] Optional. Specify 0 to ignore. Use this to differ the way fmod maps multichannel sounds to speakers. See FMOD_SPEAKERMAPTYPE for more. */ - FMOD_SOUNDGROUP *initialsoundgroup; /* [w] Optional. Specify 0 to ignore. Specify a sound group if required, to put sound in as it is created. */ - unsigned int initialseekposition;/* [w] Optional. Specify 0 to ignore. For streams. Specify an initial position to seek the stream to. */ - FMOD_TIMEUNIT initialseekpostype; /* [w] Optional. Specify 0 to ignore. For streams. Specify the time unit for the position set in initialseekposition. */ - int ignoresetfilesystem;/* [w] Optional. Specify 0 to ignore. Set to 1 to use fmod's built in file system. Ignores setFileSystem callbacks and also FMOD_CREATESOUNEXINFO file callbacks. Useful for specific cases where you don't want to use your own file system but want to use fmod's file system (ie net streaming). */ - int cddaforceaspi; /* [w] Optional. Specify 0 to ignore. For CDDA sounds only - if non-zero use ASPI instead of NTSCSI to access the specified CD/DVD device. */ - unsigned int audioqueuepolicy; /* [w] Optional. Specify 0 or FMOD_AUDIOQUEUE_CODECPOLICY_DEFAULT to ignore. Policy used to determine whether hardware or software is used for decoding, see FMOD_AUDIOQUEUE_CODECPOLICY for options (iOS >= 3.0 required, otherwise only hardware is available) */ - unsigned int minmidigranularity; /* [w] Optional. Specify 0 to ignore. Allows you to set a minimum desired MIDI mixer granularity. Values smaller than 512 give greater than default accuracy at the cost of more CPU and vice versa. Specify 0 for default (512 samples). */ - int nonblockthreadid; /* [w] Optional. Specify 0 to ignore. Specifies a thread index to execute non blocking load on. Allows for up to 5 threads to be used for loading at once. This is to avoid one load blocking another. Maximum value = 4. */ +typedef struct FMOD_CREATESOUNDEXINFO { + int cbsize; /* [w] Size of this structure. This is used so the structure can + be expanded in the future and still work on older versions of + FMOD Ex. */ + unsigned int + length; /* [w] Optional. Specify 0 to ignore. Size in bytes of file to + load, or sound to create (in this case only if FMOD_OPENUSER is + used). Required if loading from memory. If 0 is specified, + then it will use the size of the file (unless loading from + memory then an error will be returned). */ + unsigned int + fileoffset; /* [w] Optional. Specify 0 to ignore. Offset from start of the + file to start loading from. This is useful for loading + files from inside big data files. */ + int numchannels; /* [w] Optional. Specify 0 to ignore. Number of channels in a + sound mandatory if FMOD_OPENUSER or FMOD_OPENRAW is used. + */ + int defaultfrequency; /* [w] Optional. Specify 0 to ignore. Default frequency + of sound in a sound mandatory if FMOD_OPENUSER or + FMOD_OPENRAW is used. Other formats use the + frequency determined by the file format. */ + FMOD_SOUND_FORMAT + format; /* [w] Optional. Specify 0 or FMOD_SOUND_FORMAT_NONE to ignore. + Format of the sound mandatory if FMOD_OPENUSER or FMOD_OPENRAW + is used. Other formats use the format determined by the file + format. */ + unsigned int + decodebuffersize; /* [w] Optional. Specify 0 to ignore. For streams. This + determines the size of the double buffer (in PCM + samples) that a stream uses. Use this for user + created streams if you want to determine the size of + the callback buffer passed to you. Specify 0 to use + FMOD's default size which is currently equivalent to + 400ms of the sound format created/loaded. */ + int initialsubsound; /* [w] Optional. Specify 0 to ignore. In a multi-sample + file format such as .FSB/.DLS/.SF2, specify the + initial subsound to seek to, only if FMOD_CREATESTREAM + is used. */ + int numsubsounds; /* [w] Optional. Specify 0 to ignore or have no subsounds. + In a sound created with FMOD_OPENUSER, specify the number + of subsounds that are accessable with Sound::getSubSound. + If not created with FMOD_OPENUSER, this will limit the + number of subsounds loaded within a multi-subsound file. + If using FSB, then if + FMOD_CREATESOUNDEXINFO::inclusionlist is used, this will + shuffle subsounds down so that there are not any gaps. + It will mean that the indices of the sounds will be + different. */ + int *inclusionlist; /* [w] Optional. Specify 0 to ignore. In a multi-sample + format such as .FSB/.DLS/.SF2 it may be desirable to + specify only a subset of sounds to be loaded out of the + whole file. This is an array of subsound indices to + load into memory when created. */ + int inclusionlistnum; /* [w] Optional. Specify 0 to ignore. This is the number + of integers contained within the inclusionlist array. + */ + FMOD_SOUND_PCMREADCALLBACK + pcmreadcallback; /* [w] Optional. Specify 0 to ignore. Callback to + 'piggyback' on FMOD's read functions and accept or + even write PCM data while FMOD is opening the sound. + Used for user sounds created with FMOD_OPENUSER or for + capturing decoded data as FMOD reads it. */ + FMOD_SOUND_PCMSETPOSCALLBACK + pcmsetposcallback; /* [w] Optional. Specify 0 to ignore. Callback for when + the user calls a seeking function such as + Channel::setTime or Channel::setPosition within a + multi-sample sound, and for when it is opened.*/ + FMOD_SOUND_NONBLOCKCALLBACK + nonblockcallback; /* [w] Optional. Specify 0 to ignore. Callback for + successful completion, or error while loading a sound + that used the FMOD_NONBLOCKING flag. Also called + duing seeking, when setPosition is called or a stream + is restarted. */ + const char *dlsname; /* [w] Optional. Specify 0 to ignore. Filename for a DLS + or SF2 sample set when loading a MIDI file. If not + specified, on Windows it will attempt to open + /windows/system32/drivers/gm.dls or + /windows/system32/drivers/etc/gm.dls, on Mac it will + attempt to load + /System/Library/Components/CoreAudio.component/Contents/Resources/gs_instruments.dls, + otherwise the MIDI will fail to open. Current DLS + support is for level 1 of the specification. */ + const char *encryptionkey; /* [w] Optional. Specify 0 to ignore. Key for + encrypted FSB file. Without this key an + encrypted FSB file will not load. */ + int maxpolyphony; /* [w] Optional. Specify 0 to ignore. For sequenced formats + with dynamic channel allocation such as .MID and .IT, + this specifies the maximum voice count allowed while + playing. .IT defaults to 64. .MID defaults to 32. */ + void *userdata; /* [w] Optional. Specify 0 to ignore. This is user data to be + attached to the sound during creation. Access via + Sound::getUserData. Note: This is not passed to + FMOD_FILE_OPENCALLBACK, that is a different userdata that + is file specific. */ + FMOD_SOUND_TYPE + suggestedsoundtype; /* [w] Optional. Specify 0 or FMOD_SOUND_TYPE_UNKNOWN + to ignore. Instead of scanning all codec types, + use this to speed up loading by making it jump + straight to this codec. */ + FMOD_FILE_OPENCALLBACK useropen; /* [w] Optional. Specify 0 to ignore. + Callback for opening this file. */ + FMOD_FILE_CLOSECALLBACK userclose; /* [w] Optional. Specify 0 to ignore. + Callback for closing this file. */ + FMOD_FILE_READCALLBACK userread; /* [w] Optional. Specify 0 to ignore. + Callback for reading from this file. */ + FMOD_FILE_SEEKCALLBACK userseek; /* [w] Optional. Specify 0 to ignore. + Callback for seeking within this file. */ + FMOD_FILE_ASYNCREADCALLBACK + userasyncread; /* [w] Optional. Specify 0 to ignore. Callback for seeking + within this file. */ + FMOD_FILE_ASYNCCANCELCALLBACK + userasynccancel; /* [w] Optional. Specify 0 to ignore. Callback for + seeking within this file. */ + FMOD_SPEAKERMAPTYPE + speakermap; /* [w] Optional. Specify 0 to ignore. Use this to differ the + way fmod maps multichannel sounds to speakers. See + FMOD_SPEAKERMAPTYPE for more. */ + FMOD_SOUNDGROUP *initialsoundgroup; /* [w] Optional. Specify 0 to ignore. + Specify a sound group if required, to + put sound in as it is created. */ + unsigned int initialseekposition; /* [w] Optional. Specify 0 to ignore. For + streams. Specify an initial position to + seek the stream to. */ + FMOD_TIMEUNIT initialseekpostype; /* [w] Optional. Specify 0 to ignore. For + streams. Specify the time unit for the + position set in initialseekposition. */ + int ignoresetfilesystem; /* [w] Optional. Specify 0 to ignore. Set to 1 to use + fmod's built in file system. Ignores setFileSystem + callbacks and also FMOD_CREATESOUNEXINFO file + callbacks. Useful for specific cases where you + don't want to use your own file system but want to + use fmod's file system (ie net streaming). */ + int cddaforceaspi; /* [w] Optional. Specify 0 to ignore. For CDDA sounds only + - if non-zero use ASPI instead of NTSCSI to access the + specified CD/DVD device. */ + unsigned int + audioqueuepolicy; /* [w] Optional. Specify 0 or + FMOD_AUDIOQUEUE_CODECPOLICY_DEFAULT to ignore. Policy + used to determine whether hardware or software is + used for decoding, see FMOD_AUDIOQUEUE_CODECPOLICY + for options (iOS >= 3.0 required, otherwise only + hardware is available) */ + unsigned int + minmidigranularity; /* [w] Optional. Specify 0 to ignore. Allows you to + set a minimum desired MIDI mixer granularity. + Values smaller than 512 give greater than default + accuracy at the cost of more CPU and vice versa. + Specify 0 for default (512 samples). */ + int nonblockthreadid; /* [w] Optional. Specify 0 to ignore. Specifies a thread + index to execute non blocking load on. Allows for up + to 5 threads to be used for loading at once. This is + to avoid one load blocking another. Maximum value + = 4. */ } FMOD_CREATESOUNDEXINFO; - /* -[STRUCTURE] +[STRUCTURE] [ [DESCRIPTION] Structure defining a reverb environment.
    [REMARKS] - Note the default reverb properties are the same as the FMOD_PRESET_GENERIC preset.
    - Note that integer values that typically range from -10,000 to 1000 are represented in - decibels, and are of a logarithmic scale, not linear, wheras float values are always linear.
    -
    - The numerical values listed below are the maximum, minimum and default values for each variable respectively.
    -
    - SUPPORTED next to each parameter means the platform the parameter can be set on. Some platforms support all parameters and some don't.
    - WII means Nintendo Wii hardware reverb (must use FMOD_HARDWARE).
    - PSP means Playstation Portable hardware reverb (must use FMOD_HARDWARE).
    - SFX means FMOD SFX software reverb. This works on any platform that uses FMOD_SOFTWARE for loading sounds.
    - --- means unsupported/deprecated. Will either be removed or supported by SFX in the future. -
    - Nintendo Wii Notes:
    - This structure supports only limited parameters, and maps them to the Wii hardware reverb as follows.
    + Note the default reverb properties are the same as the FMOD_PRESET_GENERIC +preset.
    Note that integer values that typically range from -10,000 to 1000 +are represented in decibels, and are of a logarithmic scale, not linear, wheras +float values are always linear.

    The numerical values listed below are +the maximum, minimum and default values for each variable respectively.

    + SUPPORTED next to each parameter means the platform the parameter can +be set on. Some platforms support all parameters and some don't.
    WII means +Nintendo Wii hardware reverb (must use FMOD_HARDWARE).
    PSP means +Playstation Portable hardware reverb (must use FMOD_HARDWARE).
    SFX means +FMOD SFX software reverb. This works on any platform that uses FMOD_SOFTWARE +for loading sounds.
    + --- means unsupported/deprecated. Will either be removed or supported by +SFX in the future.
    Nintendo Wii Notes:
    This structure supports only +limited parameters, and maps them to the Wii hardware reverb as follows.
    DecayTime = 'time'
    ReverbDelay = 'predelay'
    ModulationDepth = 'damping'
    @@ -1559,12 +2285,15 @@ typedef struct FMOD_CREATESOUNDEXINFO EnvDiffusion = 'crosstalk'
    Room = 'mix'

    - Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
    - Members marked with [w] mean the variable can be written to. The user can set the value.
    - Members marked with [r/w] are either read or write depending on if you are using System::setReverbProperties (w) or System::getReverbProperties (r). + Members marked with [r] mean the variable is modified by FMOD and is for +reading purposes only. Do not change this value.
    Members marked with [w] +mean the variable can be written to. The user can set the value.
    Members +marked with [r/w] are either read or write depending on if you are using +System::setReverbProperties (w) or System::getReverbProperties (r). [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] System::setReverbProperties @@ -1573,35 +2302,57 @@ typedef struct FMOD_CREATESOUNDEXINFO FMOD_REVERB_FLAGS ] */ -typedef struct FMOD_REVERB_PROPERTIES -{ /* MIN MAX DEFAULT DESCRIPTION */ - int Instance; /* [w] 0 3 0 Environment Instance. (SUPPORTED:SFX(4 instances) and Wii (3 instances)) */ - int Environment; /* [r/w] -1 25 -1 Sets all listener properties. -1 = OFF. (SUPPORTED:SFX(-1 only)/PSP) */ - float EnvDiffusion; /* [r/w] 0.0 1.0 1.0 Environment diffusion (SUPPORTED:WII) */ - int Room; /* [r/w] -10000 0 -1000 Room effect level (at mid frequencies) (SUPPORTED:SFX/WII/PSP) */ - int RoomHF; /* [r/w] -10000 0 -100 Relative room effect level at high frequencies (SUPPORTED:SFX) */ - int RoomLF; /* [r/w] -10000 0 0 Relative room effect level at low frequencies (SUPPORTED:SFX) */ - float DecayTime; /* [r/w] 0.1 20.0 1.49 Reverberation decay time at mid frequencies (SUPPORTED:SFX/WII) */ - float DecayHFRatio; /* [r/w] 0.1 2.0 0.83 High-frequency to mid-frequency decay time ratio (SUPPORTED:SFX) */ - float DecayLFRatio; /* [r/w] 0.1 2.0 1.0 Low-frequency to mid-frequency decay time ratio (SUPPORTED:---) */ - int Reflections; /* [r/w] -10000 1000 -2602 Early reflections level relative to room effect (SUPPORTED:SFX/WII) */ - float ReflectionsDelay; /* [r/w] 0.0 0.3 0.007 Initial reflection delay time (SUPPORTED:SFX) */ - int Reverb; /* [r/w] -10000 2000 200 Late reverberation level relative to room effect (SUPPORTED:SFX) */ - float ReverbDelay; /* [r/w] 0.0 0.1 0.011 Late reverberation delay time relative to initial reflection (SUPPORTED:SFX/WII) */ - float ModulationTime; /* [r/w] 0.04 4.0 0.25 Modulation time (SUPPORTED:---) */ - float ModulationDepth; /* [r/w] 0.0 1.0 0.0 Modulation depth (SUPPORTED:WII) */ - float HFReference; /* [r/w] 20.0 20000.0 5000.0 Reference high frequency (hz) (SUPPORTED:SFX) */ - float LFReference; /* [r/w] 20.0 1000.0 250.0 Reference low frequency (hz) (SUPPORTED:SFX) */ - float Diffusion; /* [r/w] 0.0 100.0 100.0 Value that controls the echo density in the late reverberation decay. (SUPPORTED:SFX) */ - float Density; /* [r/w] 0.0 100.0 100.0 Value that controls the modal density in the late reverberation decay (SUPPORTED:SFX) */ - unsigned int Flags; /* [r/w] FMOD_REVERB_FLAGS - modifies the behavior of above properties (SUPPORTED:WII) */ +typedef struct FMOD_REVERB_PROPERTIES { /* MIN MAX DEFAULT + DESCRIPTION */ + int Instance; /* [w] 0 3 0 Environment Instance. + (SUPPORTED:SFX(4 instances) and Wii (3 instances)) */ + int Environment; /* [r/w] -1 25 -1 Sets all listener properties. + -1 = OFF. (SUPPORTED:SFX(-1 + only)/PSP) */ + float EnvDiffusion; /* [r/w] 0.0 1.0 1.0 Environment diffusion + (SUPPORTED:WII) */ + int Room; /* [r/w] -10000 0 -1000 Room effect level (at mid + frequencies) (SUPPORTED:SFX/WII/PSP) */ + int RoomHF; /* [r/w] -10000 0 -100 Relative room effect level at high + frequencies (SUPPORTED:SFX) */ + int RoomLF; /* [r/w] -10000 0 0 Relative room effect level at low + frequencies (SUPPORTED:SFX) */ + float DecayTime; /* [r/w] 0.1 20.0 1.49 Reverberation decay time at + mid frequencies (SUPPORTED:SFX/WII) */ + float DecayHFRatio; /* [r/w] 0.1 2.0 0.83 High-frequency to + mid-frequency decay time ratio (SUPPORTED:SFX) */ + float DecayLFRatio; /* [r/w] 0.1 2.0 1.0 Low-frequency to + mid-frequency decay time ratio (SUPPORTED:---) */ + int Reflections; /* [r/w] -10000 1000 -2602 Early reflections level + relative to room effect (SUPPORTED:SFX/WII) */ + float ReflectionsDelay; /* [r/w] 0.0 0.3 0.007 Initial reflection + delay time (SUPPORTED:SFX) */ + int Reverb; /* [r/w] -10000 2000 200 Late reverberation level relative + to room effect (SUPPORTED:SFX) */ + float + ReverbDelay; /* [r/w] 0.0 0.1 0.011 Late reverberation delay time + relative to initial reflection (SUPPORTED:SFX/WII) */ + float ModulationTime; /* [r/w] 0.04 4.0 0.25 Modulation time + (SUPPORTED:---) */ + float ModulationDepth; /* [r/w] 0.0 1.0 0.0 Modulation depth + (SUPPORTED:WII) */ + float HFReference; /* [r/w] 20.0 20000.0 5000.0 Reference high frequency + (hz) (SUPPORTED:SFX) */ + float LFReference; /* [r/w] 20.0 1000.0 250.0 Reference low frequency + (hz) (SUPPORTED:SFX) */ + float + Diffusion; /* [r/w] 0.0 100.0 100.0 Value that controls the echo + density in the late reverberation decay. (SUPPORTED:SFX) */ + float Density; /* [r/w] 0.0 100.0 100.0 Value that controls the modal + density in the late reverberation decay (SUPPORTED:SFX) */ + unsigned int Flags; /* [r/w] FMOD_REVERB_FLAGS - modifies the behavior of + above properties (SUPPORTED:WII) */ } FMOD_REVERB_PROPERTIES; - /* -[DEFINE] +[DEFINE] [ - [NAME] + [NAME] FMOD_REVERB_FLAGS [DESCRIPTION] @@ -1610,131 +2361,281 @@ typedef struct FMOD_REVERB_PROPERTIES [REMARKS] [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] FMOD_REVERB_PROPERTIES ] */ -#define FMOD_REVERB_FLAGS_HIGHQUALITYREVERB 0x00000400 /* Wii. Use high quality reverb */ -#define FMOD_REVERB_FLAGS_HIGHQUALITYDPL2REVERB 0x00000800 /* Wii. Use high quality DPL2 reverb */ -#define FMOD_REVERB_FLAGS_HARDWAREONLY 0x00001000 /* Don't create an SFX reverb for FMOD_SOFTWARE channels, hardware reverb only */ -#define FMOD_REVERB_FLAGS_DEFAULT 0x00000000 +#define FMOD_REVERB_FLAGS_HIGHQUALITYREVERB \ + 0x00000400 /* Wii. Use high quality reverb */ +#define FMOD_REVERB_FLAGS_HIGHQUALITYDPL2REVERB \ + 0x00000800 /* Wii. Use high quality DPL2 reverb */ +#define FMOD_REVERB_FLAGS_HARDWAREONLY \ + 0x00001000 /* Don't create an SFX reverb for FMOD_SOFTWARE channels, \ + hardware reverb only */ +#define FMOD_REVERB_FLAGS_DEFAULT 0x00000000 /* [DEFINE_END] */ - /* -[DEFINE] +[DEFINE] [ - [NAME] + [NAME] FMOD_REVERB_PRESETS - [DESCRIPTION] + [DESCRIPTION] A set of predefined environment PARAMETERS.
    - These are used to initialize an FMOD_REVERB_PROPERTIES structure statically.
    - i.e.
    - FMOD_REVERB_PROPERTIES prop = FMOD_PRESET_GENERIC; + These are used to initialize an FMOD_REVERB_PROPERTIES structure +statically.
    i.e.
    FMOD_REVERB_PROPERTIES prop = FMOD_PRESET_GENERIC; [REMARKS] [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] System::setReverbProperties ] */ -/* Inst Env Diffus Room RoomHF RmLF DecTm DecHF DecLF Refl RefDel Revb RevDel ModTm ModDp HFRef LFRef Diffus Densty FLAGS */ -#define FMOD_PRESET_OFF { 0, -1, 1.00f, -10000, -10000, 0, 1.00f, 1.00f, 1.0f, -2602, 0.007f, 200, 0.011f, 0.25f, 0.000f, 5000.0f, 250.0f, 0.0f, 0.0f, 0x33f } -#define FMOD_PRESET_GENERIC { 0, 0, 1.00f, -1000, -100, 0, 1.49f, 0.83f, 1.0f, -2602, 0.007f, 200, 0.011f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f } -#define FMOD_PRESET_PADDEDCELL { 0, 1, 1.00f, -1000, -6000, 0, 0.17f, 0.10f, 1.0f, -1204, 0.001f, 207, 0.002f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f } -#define FMOD_PRESET_ROOM { 0, 2, 1.00f, -1000, -454, 0, 0.40f, 0.83f, 1.0f, -1646, 0.002f, 53, 0.003f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f } -#define FMOD_PRESET_BATHROOM { 0, 3, 1.00f, -1000, -1200, 0, 1.49f, 0.54f, 1.0f, -370, 0.007f, 1030, 0.011f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 60.0f, 0x3f } -#define FMOD_PRESET_LIVINGROOM { 0, 4, 1.00f, -1000, -6000, 0, 0.50f, 0.10f, 1.0f, -1376, 0.003f, -1104, 0.004f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f } -#define FMOD_PRESET_STONEROOM { 0, 5, 1.00f, -1000, -300, 0, 2.31f, 0.64f, 1.0f, -711, 0.012f, 83, 0.017f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f } -#define FMOD_PRESET_AUDITORIUM { 0, 6, 1.00f, -1000, -476, 0, 4.32f, 0.59f, 1.0f, -789, 0.020f, -289, 0.030f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f } -#define FMOD_PRESET_CONCERTHALL { 0, 7, 1.00f, -1000, -500, 0, 3.92f, 0.70f, 1.0f, -1230, 0.020f, -2, 0.029f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f } -#define FMOD_PRESET_CAVE { 0, 8, 1.00f, -1000, 0, 0, 2.91f, 1.30f, 1.0f, -602, 0.015f, -302, 0.022f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x1f } -#define FMOD_PRESET_ARENA { 0, 9, 1.00f, -1000, -698, 0, 7.24f, 0.33f, 1.0f, -1166, 0.020f, 16, 0.030f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f } -#define FMOD_PRESET_HANGAR { 0, 10, 1.00f, -1000, -1000, 0, 10.05f, 0.23f, 1.0f, -602, 0.020f, 198, 0.030f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f } -#define FMOD_PRESET_CARPETTEDHALLWAY { 0, 11, 1.00f, -1000, -4000, 0, 0.30f, 0.10f, 1.0f, -1831, 0.002f, -1630, 0.030f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f } -#define FMOD_PRESET_HALLWAY { 0, 12, 1.00f, -1000, -300, 0, 1.49f, 0.59f, 1.0f, -1219, 0.007f, 441, 0.011f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f } -#define FMOD_PRESET_STONECORRIDOR { 0, 13, 1.00f, -1000, -237, 0, 2.70f, 0.79f, 1.0f, -1214, 0.013f, 395, 0.020f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f } -#define FMOD_PRESET_ALLEY { 0, 14, 0.30f, -1000, -270, 0, 1.49f, 0.86f, 1.0f, -1204, 0.007f, -4, 0.011f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f } -#define FMOD_PRESET_FOREST { 0, 15, 0.30f, -1000, -3300, 0, 1.49f, 0.54f, 1.0f, -2560, 0.162f, -229, 0.088f, 0.25f, 0.000f, 5000.0f, 250.0f, 79.0f, 100.0f, 0x3f } -#define FMOD_PRESET_CITY { 0, 16, 0.50f, -1000, -800, 0, 1.49f, 0.67f, 1.0f, -2273, 0.007f, -1691, 0.011f, 0.25f, 0.000f, 5000.0f, 250.0f, 50.0f, 100.0f, 0x3f } -#define FMOD_PRESET_MOUNTAINS { 0, 17, 0.27f, -1000, -2500, 0, 1.49f, 0.21f, 1.0f, -2780, 0.300f, -1434, 0.100f, 0.25f, 0.000f, 5000.0f, 250.0f, 27.0f, 100.0f, 0x1f } -#define FMOD_PRESET_QUARRY { 0, 18, 1.00f, -1000, -1000, 0, 1.49f, 0.83f, 1.0f, -10000, 0.061f, 500, 0.025f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f } -#define FMOD_PRESET_PLAIN { 0, 19, 0.21f, -1000, -2000, 0, 1.49f, 0.50f, 1.0f, -2466, 0.179f, -1926, 0.100f, 0.25f, 0.000f, 5000.0f, 250.0f, 21.0f, 100.0f, 0x3f } -#define FMOD_PRESET_PARKINGLOT { 0, 20, 1.00f, -1000, 0, 0, 1.65f, 1.50f, 1.0f, -1363, 0.008f, -1153, 0.012f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x1f } -#define FMOD_PRESET_SEWERPIPE { 0, 21, 0.80f, -1000, -1000, 0, 2.81f, 0.14f, 1.0f, 429, 0.014f, 1023, 0.021f, 0.25f, 0.000f, 5000.0f, 250.0f, 80.0f, 60.0f, 0x3f } -#define FMOD_PRESET_UNDERWATER { 0, 22, 1.00f, -1000, -4000, 0, 1.49f, 0.10f, 1.0f, -449, 0.007f, 1700, 0.011f, 1.18f, 0.348f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f } +/* Inst Env Diffus Room RoomHF RmLF + * DecTm DecHF DecLF Refl RefDel Revb RevDel ModTm ModDp HFRef + * LFRef Diffus Densty FLAGS */ +#define FMOD_PRESET_OFF \ + { \ + 0, -1, 1.00f, -10000, -10000, 0, 1.00f, 1.00f, 1.0f, -2602, 0.007f, 200, \ + 0.011f, 0.25f, 0.000f, 5000.0f, 250.0f, 0.0f, 0.0f, 0x33f \ + } +#define FMOD_PRESET_GENERIC \ + { \ + 0, 0, 1.00f, -1000, -100, 0, 1.49f, 0.83f, 1.0f, -2602, 0.007f, 200, \ + 0.011f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f \ + } +#define FMOD_PRESET_PADDEDCELL \ + { \ + 0, 1, 1.00f, -1000, -6000, 0, 0.17f, 0.10f, 1.0f, -1204, 0.001f, 207, \ + 0.002f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f \ + } +#define FMOD_PRESET_ROOM \ + { \ + 0, 2, 1.00f, -1000, -454, 0, 0.40f, 0.83f, 1.0f, -1646, 0.002f, 53, \ + 0.003f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f \ + } +#define FMOD_PRESET_BATHROOM \ + { \ + 0, 3, 1.00f, -1000, -1200, 0, 1.49f, 0.54f, 1.0f, -370, 0.007f, 1030, \ + 0.011f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 60.0f, 0x3f \ + } +#define FMOD_PRESET_LIVINGROOM \ + { \ + 0, 4, 1.00f, -1000, -6000, 0, 0.50f, 0.10f, 1.0f, -1376, 0.003f, -1104, \ + 0.004f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f \ + } +#define FMOD_PRESET_STONEROOM \ + { \ + 0, 5, 1.00f, -1000, -300, 0, 2.31f, 0.64f, 1.0f, -711, 0.012f, 83, 0.017f, \ + 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f \ + } +#define FMOD_PRESET_AUDITORIUM \ + { \ + 0, 6, 1.00f, -1000, -476, 0, 4.32f, 0.59f, 1.0f, -789, 0.020f, -289, \ + 0.030f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f \ + } +#define FMOD_PRESET_CONCERTHALL \ + { \ + 0, 7, 1.00f, -1000, -500, 0, 3.92f, 0.70f, 1.0f, -1230, 0.020f, -2, \ + 0.029f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f \ + } +#define FMOD_PRESET_CAVE \ + { \ + 0, 8, 1.00f, -1000, 0, 0, 2.91f, 1.30f, 1.0f, -602, 0.015f, -302, 0.022f, \ + 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x1f \ + } +#define FMOD_PRESET_ARENA \ + { \ + 0, 9, 1.00f, -1000, -698, 0, 7.24f, 0.33f, 1.0f, -1166, 0.020f, 16, \ + 0.030f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f \ + } +#define FMOD_PRESET_HANGAR \ + { \ + 0, 10, 1.00f, -1000, -1000, 0, 10.05f, 0.23f, 1.0f, -602, 0.020f, 198, \ + 0.030f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f \ + } +#define FMOD_PRESET_CARPETTEDHALLWAY \ + { \ + 0, 11, 1.00f, -1000, -4000, 0, 0.30f, 0.10f, 1.0f, -1831, 0.002f, -1630, \ + 0.030f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f \ + } +#define FMOD_PRESET_HALLWAY \ + { \ + 0, 12, 1.00f, -1000, -300, 0, 1.49f, 0.59f, 1.0f, -1219, 0.007f, 441, \ + 0.011f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f \ + } +#define FMOD_PRESET_STONECORRIDOR \ + { \ + 0, 13, 1.00f, -1000, -237, 0, 2.70f, 0.79f, 1.0f, -1214, 0.013f, 395, \ + 0.020f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f \ + } +#define FMOD_PRESET_ALLEY \ + { \ + 0, 14, 0.30f, -1000, -270, 0, 1.49f, 0.86f, 1.0f, -1204, 0.007f, -4, \ + 0.011f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f \ + } +#define FMOD_PRESET_FOREST \ + { \ + 0, 15, 0.30f, -1000, -3300, 0, 1.49f, 0.54f, 1.0f, -2560, 0.162f, -229, \ + 0.088f, 0.25f, 0.000f, 5000.0f, 250.0f, 79.0f, 100.0f, 0x3f \ + } +#define FMOD_PRESET_CITY \ + { \ + 0, 16, 0.50f, -1000, -800, 0, 1.49f, 0.67f, 1.0f, -2273, 0.007f, -1691, \ + 0.011f, 0.25f, 0.000f, 5000.0f, 250.0f, 50.0f, 100.0f, 0x3f \ + } +#define FMOD_PRESET_MOUNTAINS \ + { \ + 0, 17, 0.27f, -1000, -2500, 0, 1.49f, 0.21f, 1.0f, -2780, 0.300f, -1434, \ + 0.100f, 0.25f, 0.000f, 5000.0f, 250.0f, 27.0f, 100.0f, 0x1f \ + } +#define FMOD_PRESET_QUARRY \ + { \ + 0, 18, 1.00f, -1000, -1000, 0, 1.49f, 0.83f, 1.0f, -10000, 0.061f, 500, \ + 0.025f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f \ + } +#define FMOD_PRESET_PLAIN \ + { \ + 0, 19, 0.21f, -1000, -2000, 0, 1.49f, 0.50f, 1.0f, -2466, 0.179f, -1926, \ + 0.100f, 0.25f, 0.000f, 5000.0f, 250.0f, 21.0f, 100.0f, 0x3f \ + } +#define FMOD_PRESET_PARKINGLOT \ + { \ + 0, 20, 1.00f, -1000, 0, 0, 1.65f, 1.50f, 1.0f, -1363, 0.008f, -1153, \ + 0.012f, 0.25f, 0.000f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x1f \ + } +#define FMOD_PRESET_SEWERPIPE \ + { \ + 0, 21, 0.80f, -1000, -1000, 0, 2.81f, 0.14f, 1.0f, 429, 0.014f, 1023, \ + 0.021f, 0.25f, 0.000f, 5000.0f, 250.0f, 80.0f, 60.0f, 0x3f \ + } +#define FMOD_PRESET_UNDERWATER \ + { \ + 0, 22, 1.00f, -1000, -4000, 0, 1.49f, 0.10f, 1.0f, -449, 0.007f, 1700, \ + 0.011f, 1.18f, 0.348f, 5000.0f, 250.0f, 100.0f, 100.0f, 0x3f \ + } /* PlayStation Portable Only presets */ -#define FMOD_PRESET_PSP_ROOM { 0, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0.000f, 0, 0.000f, 0.00f, 0.000f, 0000.0f, 0.0f, 0.0f, 0.0f, 0x31f } -#define FMOD_PRESET_PSP_STUDIO_A { 0, 2, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0.000f, 0, 0.000f, 0.00f, 0.000f, 0000.0f, 0.0f, 0.0f, 0.0f, 0x31f } -#define FMOD_PRESET_PSP_STUDIO_B { 0, 3, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0.000f, 0, 0.000f, 0.00f, 0.000f, 0000.0f, 0.0f, 0.0f, 0.0f, 0x31f } -#define FMOD_PRESET_PSP_STUDIO_C { 0, 4, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0.000f, 0, 0.000f, 0.00f, 0.000f, 0000.0f, 0.0f, 0.0f, 0.0f, 0x31f } -#define FMOD_PRESET_PSP_HALL { 0, 5, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0.000f, 0, 0.000f, 0.00f, 0.000f, 0000.0f, 0.0f, 0.0f, 0.0f, 0x31f } -#define FMOD_PRESET_PSP_SPACE { 0, 6, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0.000f, 0, 0.000f, 0.00f, 0.000f, 0000.0f, 0.0f, 0.0f, 0.0f, 0x31f } -#define FMOD_PRESET_PSP_ECHO { 0, 7, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0.000f, 0, 0.000f, 0.00f, 0.000f, 0000.0f, 0.0f, 0.0f, 0.0f, 0x31f } -#define FMOD_PRESET_PSP_DELAY { 0, 8, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0.000f, 0, 0.000f, 0.00f, 0.000f, 0000.0f, 0.0f, 0.0f, 0.0f, 0x31f } -#define FMOD_PRESET_PSP_PIPE { 0, 9, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0.000f, 0, 0.000f, 0.00f, 0.000f, 0000.0f, 0.0f, 0.0f, 0.0f, 0x31f } +#define FMOD_PRESET_PSP_ROOM \ + { \ + 0, 1, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0.000f, 0, 0.000f, 0.00f, 0.000f, \ + 0000.0f, 0.0f, 0.0f, 0.0f, 0x31f \ + } +#define FMOD_PRESET_PSP_STUDIO_A \ + { \ + 0, 2, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0.000f, 0, 0.000f, 0.00f, 0.000f, \ + 0000.0f, 0.0f, 0.0f, 0.0f, 0x31f \ + } +#define FMOD_PRESET_PSP_STUDIO_B \ + { \ + 0, 3, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0.000f, 0, 0.000f, 0.00f, 0.000f, \ + 0000.0f, 0.0f, 0.0f, 0.0f, 0x31f \ + } +#define FMOD_PRESET_PSP_STUDIO_C \ + { \ + 0, 4, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0.000f, 0, 0.000f, 0.00f, 0.000f, \ + 0000.0f, 0.0f, 0.0f, 0.0f, 0x31f \ + } +#define FMOD_PRESET_PSP_HALL \ + { \ + 0, 5, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0.000f, 0, 0.000f, 0.00f, 0.000f, \ + 0000.0f, 0.0f, 0.0f, 0.0f, 0x31f \ + } +#define FMOD_PRESET_PSP_SPACE \ + { \ + 0, 6, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0.000f, 0, 0.000f, 0.00f, 0.000f, \ + 0000.0f, 0.0f, 0.0f, 0.0f, 0x31f \ + } +#define FMOD_PRESET_PSP_ECHO \ + { \ + 0, 7, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0.000f, 0, 0.000f, 0.00f, 0.000f, \ + 0000.0f, 0.0f, 0.0f, 0.0f, 0x31f \ + } +#define FMOD_PRESET_PSP_DELAY \ + { \ + 0, 8, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0.000f, 0, 0.000f, 0.00f, 0.000f, \ + 0000.0f, 0.0f, 0.0f, 0.0f, 0x31f \ + } +#define FMOD_PRESET_PSP_PIPE \ + { \ + 0, 9, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f, 0, 0.000f, 0, 0.000f, 0.00f, 0.000f, \ + 0000.0f, 0.0f, 0.0f, 0.0f, 0x31f \ + } /* [DEFINE_END] */ - /* -[STRUCTURE] +[STRUCTURE] [ [DESCRIPTION] - Structure defining the properties for a reverb source, related to a FMOD channel.
    -
    - Note the default reverb properties are the same as the FMOD_PRESET_GENERIC preset.
    - Note that integer values that typically range from -10,000 to 1000 are represented in - decibels, and are of a logarithmic scale, not linear, wheras float values are typically linear.
    - PORTABILITY: Each member has the platform it supports in braces ie (win32/wii).
    -
    - The numerical values listed below are the maximum, minimum and default values for each variable respectively.
    + Structure defining the properties for a reverb source, related to a FMOD +channel.

    Note the default reverb properties are the same as the +FMOD_PRESET_GENERIC preset.
    Note that integer values that typically range +from -10,000 to 1000 are represented in decibels, and are of a logarithmic +scale, not linear, wheras float values are typically linear.
    PORTABILITY: +Each member has the platform it supports in braces ie (win32/wii).

    The +numerical values listed below are the maximum, minimum and default values for +each variable respectively.
    [REMARKS] - SUPPORTED next to each parameter means the platform the parameter can be set on. Some platforms support all parameters and some don't.
    - WII means Nintendo Wii hardware reverb (must use FMOD_HARDWARE).
    - PSP means Playstation Portable hardware reverb (must use FMOD_HARDWARE).
    - SFX means FMOD SFX software reverb. This works on any platform that uses FMOD_SOFTWARE for loading sounds.
    - --- means unsupported/deprecated. Will either be removed or supported by SFX in the future. -
    -
    - 'ConnectionPoint' Parameter. This parameter is for the FMOD software reverb only (known as SFX in the list above).
    - By default the dsp network connection for a channel and its reverb is between the 'SFX Reverb' unit, and the channel's wavetable/resampler/dspcodec/oscillator unit (the unit below the channel DSP head). NULL can be used for this parameter to make it use this default behaviour.
    - This parameter allows the user to connect the SFX reverb to somewhere else internally, for example the channel DSP head, or a related channelgroup. The event system uses this so that it can have the output of an event going to the reverb, instead of just the output of the event's channels (thereby ignoring event effects/submixes etc).
    - Do not use if you are unaware of DSP network connection issues. Leave it at the default of NULL instead.
    -
    - Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
    - Members marked with [w] mean the variable can be written to. The user can set the value.
    - Members marked with [r/w] are either read or write depending on if you are using Channel::setReverbProperties (w) or Channel::getReverbProperties (r). + SUPPORTED next to each parameter means the platform the parameter can +be set on. Some platforms support all parameters and some don't.
    WII means +Nintendo Wii hardware reverb (must use FMOD_HARDWARE).
    PSP means +Playstation Portable hardware reverb (must use FMOD_HARDWARE).
    SFX means +FMOD SFX software reverb. This works on any platform that uses FMOD_SOFTWARE +for loading sounds.
    + --- means unsupported/deprecated. Will either be removed or supported by +SFX in the future.

    'ConnectionPoint' Parameter. This parameter +is for the FMOD software reverb only (known as SFX in the list above).
    By +default the dsp network connection for a channel and its reverb is between the +'SFX Reverb' unit, and the channel's wavetable/resampler/dspcodec/oscillator +unit (the unit below the channel DSP head). NULL can be used for this parameter +to make it use this default behaviour.
    This parameter allows the user to +connect the SFX reverb to somewhere else internally, for example the channel DSP +head, or a related channelgroup. The event system uses this so that it can have +the output of an event going to the reverb, instead of just the output of the +event's channels (thereby ignoring event effects/submixes etc).
    Do not use +if you are unaware of DSP network connection issues. Leave it at the default of +NULL instead.

    Members marked with [r] mean the variable is modified by +FMOD and is for reading purposes only. Do not change this value.
    Members +marked with [w] mean the variable can be written to. The user can set the +value.
    Members marked with [r/w] are either read or write depending on if +you are using Channel::setReverbProperties (w) or Channel::getReverbProperties +(r). [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] Channel::setReverbProperties Channel::getReverbProperties - FMOD_REVERB_CHANNELFLAGS + FMOD_REVERB_CHANNELFLAGS ] */ -typedef struct FMOD_REVERB_CHANNELPROPERTIES -{ /* MIN MAX DEFAULT DESCRIPTION */ - int Direct; /* [r/w] -10000 1000 0 Direct path level (SUPPORTED:SFX) */ - int Room; /* [r/w] -10000 1000 0 Room effect level (SUPPORTED:SFX) */ - unsigned int Flags; /* [r/w] FMOD_REVERB_CHANNELFLAGS - modifies the behavior of properties (SUPPORTED:SFX) */ - FMOD_DSP *ConnectionPoint; /* [r/w] See remarks. DSP network location to connect reverb for this channel. (SUPPORTED:SFX).*/ +typedef struct FMOD_REVERB_CHANNELPROPERTIES { /* MIN MAX DEFAULT + DESCRIPTION */ + int Direct; /* [r/w] -10000 1000 0 Direct path level (SUPPORTED:SFX) + */ + int Room; /* [r/w] -10000 1000 0 Room effect level (SUPPORTED:SFX) */ + unsigned int Flags; /* [r/w] FMOD_REVERB_CHANNELFLAGS - modifies the behavior + of properties (SUPPORTED:SFX) */ + FMOD_DSP + *ConnectionPoint; /* [r/w] See remarks. DSP network location to + connect reverb for this channel. (SUPPORTED:SFX).*/ } FMOD_REVERB_CHANNELPROPERTIES; - /* -[DEFINE] +[DEFINE] [ - [NAME] + [NAME] FMOD_REVERB_CHANNELFLAGS [DESCRIPTION] @@ -1742,50 +2643,68 @@ typedef struct FMOD_REVERB_CHANNELPROPERTIES [REMARKS] For SFX Reverb, there is support for multiple reverb environments.
    - Use FMOD_REVERB_CHANNELFLAGS_ENVIRONMENT0 to FMOD_REVERB_CHANNELFLAGS_ENVIRONMENT3 in the flags member - of FMOD_REVERB_CHANNELPROPERTIES to specify which environment instance(s) to target.
    - - If you do not specify any instance the first reverb instance will be used.
    - - If you specify more than one instance with getReverbProperties, the first instance will be used.
    - - If you specify more than one instance with setReverbProperties, it will set more than 1 instance at once.
    + Use FMOD_REVERB_CHANNELFLAGS_ENVIRONMENT0 to +FMOD_REVERB_CHANNELFLAGS_ENVIRONMENT3 in the flags member of +FMOD_REVERB_CHANNELPROPERTIES to specify which environment instance(s) to +target.
    + - If you do not specify any instance the first reverb instance will be +used.
    + - If you specify more than one instance with getReverbProperties, the first +instance will be used.
    + - If you specify more than one instance with setReverbProperties, it will +set more than 1 instance at once.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] FMOD_REVERB_CHANNELPROPERTIES ] */ -#define FMOD_REVERB_CHANNELFLAGS_INSTANCE0 0x00000010 /* SFX/Wii. Specify channel to target reverb instance 0. Default target. */ -#define FMOD_REVERB_CHANNELFLAGS_INSTANCE1 0x00000020 /* SFX/Wii. Specify channel to target reverb instance 1. */ -#define FMOD_REVERB_CHANNELFLAGS_INSTANCE2 0x00000040 /* SFX/Wii. Specify channel to target reverb instance 2. */ -#define FMOD_REVERB_CHANNELFLAGS_INSTANCE3 0x00000080 /* SFX. Specify channel to target reverb instance 3. */ +#define FMOD_REVERB_CHANNELFLAGS_INSTANCE0 \ + 0x00000010 /* SFX/Wii. Specify channel to target reverb instance 0. Default \ + target. */ +#define FMOD_REVERB_CHANNELFLAGS_INSTANCE1 \ + 0x00000020 /* SFX/Wii. Specify channel to target reverb instance 1. */ +#define FMOD_REVERB_CHANNELFLAGS_INSTANCE2 \ + 0x00000040 /* SFX/Wii. Specify channel to target reverb instance 2. */ +#define FMOD_REVERB_CHANNELFLAGS_INSTANCE3 \ + 0x00000080 /* SFX. Specify channel to target reverb instance 3. */ -#define FMOD_REVERB_CHANNELFLAGS_DEFAULT FMOD_REVERB_CHANNELFLAGS_INSTANCE0 +#define FMOD_REVERB_CHANNELFLAGS_DEFAULT FMOD_REVERB_CHANNELFLAGS_INSTANCE0 /* [DEFINE_END] */ - /* -[STRUCTURE] +[STRUCTURE] [ [DESCRIPTION] - Settings for advanced features like configuring memory and cpu usage for the FMOD_CREATECOMPRESSEDSAMPLE feature. + Settings for advanced features like configuring memory and cpu usage for the +FMOD_CREATECOMPRESSEDSAMPLE feature. [REMARKS] - maxMPEGcodecs / maxADPCMcodecs / maxXMAcodecs will determine the maximum cpu usage of playing realtime samples. Use this to lower potential excess cpu usage and also control memory usage.
    -
    - maxPCMcodecs is for use with PS3 only. It will determine the maximum number of PCM voices that can be played at once. This includes streams of any format and all sounds created - *without* the FMOD_CREATECOMPRESSEDSAMPLE flag. -
    - Memory will be allocated for codecs 'up front' (during System::init) if these values are specified as non zero. If any are zero, it allocates memory for the codec whenever a file of the type in question is loaded. So if maxMPEGcodecs is 0 for example, it will allocate memory for the mpeg codecs the first time an mp3 is loaded or an mp3 based .FSB file is loaded.
    -
    - Due to inefficient encoding techniques on certain .wav based ADPCM files, FMOD can can need an extra 29720 bytes per codec. This means for lowest memory consumption. Use FSB as it uses an optimal/small ADPCM block size.
    -
    - Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
    - Members marked with [w] mean the variable can be written to. The user can set the value.
    - Members marked with [r/w] are either read or write depending on if you are using System::setAdvancedSettings (w) or System::getAdvancedSettings (r). + maxMPEGcodecs / maxADPCMcodecs / maxXMAcodecs will determine the maximum cpu +usage of playing realtime samples. Use this to lower potential excess cpu usage +and also control memory usage.

    maxPCMcodecs is for use with PS3 only. +It will determine the maximum number of PCM voices that can be played at once. +This includes streams of any format and all sounds created *without* the +FMOD_CREATECOMPRESSEDSAMPLE flag.
    Memory will be allocated for codecs 'up +front' (during System::init) if these values are specified as non zero. If any +are zero, it allocates memory for the codec whenever a file of the type in +question is loaded. So if maxMPEGcodecs is 0 for example, it will allocate +memory for the mpeg codecs the first time an mp3 is loaded or an mp3 based .FSB +file is loaded.

    Due to inefficient encoding techniques on certain .wav +based ADPCM files, FMOD can can need an extra 29720 bytes per codec. This means +for lowest memory consumption. Use FSB as it uses an optimal/small ADPCM block +size.

    Members marked with [r] mean the variable is modified by FMOD and +is for reading purposes only. Do not change this value.
    Members marked with +[w] mean the variable can be written to. The user can set the value.
    + Members marked with [r/w] are either read or write depending on if you are +using System::setAdvancedSettings (w) or System::getAdvancedSettings (r). [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] System::setAdvancedSettings @@ -1794,38 +2713,134 @@ typedef struct FMOD_REVERB_CHANNELPROPERTIES FMOD_MODE ] */ -typedef struct FMOD_ADVANCEDSETTINGS -{ - int cbsize; /* [w] Size of this structure. Use sizeof(FMOD_ADVANCEDSETTINGS) NOTE: This must be set before calling System::getAdvancedSettings! */ - int maxMPEGcodecs; /* [r/w] Optional. Specify 0 to ignore. For use with FMOD_CREATECOMPRESSEDSAMPLE only. Mpeg codecs consume 21,684 bytes per instance and this number will determine how many mpeg channels can be played simultaneously. Default = 32. */ - int maxADPCMcodecs; /* [r/w] Optional. Specify 0 to ignore. For use with FMOD_CREATECOMPRESSEDSAMPLE only. ADPCM codecs consume 2,136 bytes per instance and this number will determine how many ADPCM channels can be played simultaneously. Default = 32. */ - int maxXMAcodecs; /* [r/w] Optional. Specify 0 to ignore. For use with FMOD_CREATECOMPRESSEDSAMPLE only. XMA codecs consume 14,836 bytes per instance and this number will determine how many XMA channels can be played simultaneously. Default = 32. */ - int maxCELTcodecs; /* [r/w] Optional. Specify 0 to ignore. For use with FMOD_CREATECOMPRESSEDSAMPLE only. CELT codecs consume 11,500 bytes per instance and this number will determine how many CELT channels can be played simultaneously. Default = 32. */ - int maxVORBIScodecs; /* [r/w] Optional. Specify 0 to ignore. For use with FMOD_CREATECOMPRESSEDSAMPLE only. Vorbis codecs consume 12,000 bytes per instance and this number will determine how many Vorbis channels can be played simultaneously. Default = 32. */ - int maxAT9Codecs; /* [r/w] Optional. Specify 0 to ignore. For use with FMOD_CREATECOMPRESSEDSAMPLE only. AT9 codecs consume 8,720 bytes per instance and this number will determine how many AT9 channels can be played simultaneously. Default = 32. */ - int maxPCMcodecs; /* [r/w] Optional. Specify 0 to ignore. For use with PS3 only. PCM codecs consume 12,672 bytes per instance and this number will determine how many streams and PCM voices can be played simultaneously. Default = 16. */ - int ASIONumChannels; /* [r/w] Optional. Specify 0 to ignore. Number of channels available on the ASIO device. */ - char **ASIOChannelList; /* [r/w] Optional. Specify 0 to ignore. Pointer to an array of strings (number of entries defined by ASIONumChannels) with ASIO channel names. */ - FMOD_SPEAKER *ASIOSpeakerList; /* [r/w] Optional. Specify 0 to ignore. Pointer to a list of speakers that the ASIO channels map to. This can be called after System::init to remap ASIO output. */ - int max3DReverbDSPs; /* [r/w] Optional. Specify 0 to ignore. The max number of 3d reverb DSP's in the system. (NOTE: CURRENTLY DISABLED / UNUSED) */ - float HRTFMinAngle; /* [r/w] Optional. For use with FMOD_INIT_HRTF_LOWPASS. The angle range (0-360) of a 3D sound in relation to the listener, at which the HRTF function begins to have an effect. 0 = in front of the listener. 180 = from 90 degrees to the left of the listener to 90 degrees to the right. 360 = behind the listener. Default = 180.0. */ - float HRTFMaxAngle; /* [r/w] Optional. For use with FMOD_INIT_HRTF_LOWPASS. The angle range (0-360) of a 3D sound in relation to the listener, at which the HRTF function has maximum effect. 0 = front of the listener. 180 = from 90 degrees to the left of the listener to 90 degrees to the right. 360 = behind the listener. Default = 360.0. */ - float HRTFFreq; /* [r/w] Optional. Specify 0 to ignore. For use with FMOD_INIT_HRTF_LOWPASS. The cutoff frequency of the HRTF's lowpass filter function when at maximum effect. (i.e. at HRTFMaxAngle). Default = 4000.0. */ - float vol0virtualvol; /* [r/w] Optional. Specify 0 to ignore. For use with FMOD_INIT_VOL0_BECOMES_VIRTUAL. If this flag is used, and the volume is 0.0, then the sound will become virtual. Use this value to raise the threshold to a different point where a sound goes virtual. */ - int eventqueuesize; /* [r/w] Optional. Specify 0 to ignore. For use with FMOD Event system only. Specifies the number of slots available for simultaneous non blocking loads, across all threads. Default = 32. */ - unsigned int defaultDecodeBufferSize; /* [r/w] Optional. Specify 0 to ignore. For streams. This determines the default size of the double buffer (in milliseconds) that a stream uses. Default = 400ms */ - char *debugLogFilename; /* [r/w] Optional. Specify 0 to ignore. Gives fmod's logging system a path/filename. Normally the log is placed in the same directory as the executable and called fmod.log. When using System::getAdvancedSettings, provide at least 256 bytes of memory to copy into. */ - unsigned short profileport; /* [r/w] Optional. Specify 0 to ignore. For use with FMOD_INIT_ENABLE_PROFILE. Specify the port to listen on for connections by the profiler application. */ - unsigned int geometryMaxFadeTime; /* [r/w] Optional. Specify 0 to ignore. The maximum time in miliseconds it takes for a channel to fade to the new level when its occlusion changes. */ - unsigned int maxSpectrumWaveDataBuffers; /* [r/w] Optional. Specify 0 to ignore. Tells System::init to allocate a pool of wavedata/spectrum buffers to prevent memory fragmentation, any additional buffers will be allocated normally. */ - unsigned int musicSystemCacheDelay; /* [r/w] Optional. Specify 0 to ignore. The delay the music system should allow for loading a sample from disk (in milliseconds). Default = 400 ms. */ - float distanceFilterCenterFreq; /* [r/w] Optional. Specify 0 to ignore. For use with FMOD_INIT_DISTANCE_FILTERING. The default center frequency in Hz for the distance filtering effect. Default = 1500.0. */ - unsigned int stackSizeStream; /* [r/w] Optional. Specify 0 to ignore. Specify the stack size for the FMOD Stream thread in bytes. Useful for custom codecs that use excess stack. Default 49,152 (48kb) */ - unsigned int stackSizeNonBlocking; /* [r/w] Optional. Specify 0 to ignore. Specify the stack size for the FMOD_NONBLOCKING loading thread. Useful for custom codecs that use excess stack. Default 65,536 (64kb) */ - unsigned int stackSizeMixer; /* [r/w] Optional. Specify 0 to ignore. Specify the stack size for the FMOD mixer thread. Useful for custom dsps that use excess stack. Default 49,152 (48kb) */ +typedef struct FMOD_ADVANCEDSETTINGS { + int cbsize; /* [w] Size of this structure. Use + sizeof(FMOD_ADVANCEDSETTINGS) NOTE: This must be set before + calling System::getAdvancedSettings! */ + int maxMPEGcodecs; /* [r/w] Optional. Specify 0 to ignore. For use with + FMOD_CREATECOMPRESSEDSAMPLE only. Mpeg codecs consume + 21,684 bytes per instance and this number will determine + how many mpeg channels can be played simultaneously. + Default = 32. */ + int maxADPCMcodecs; /* [r/w] Optional. Specify 0 to ignore. For use with + FMOD_CREATECOMPRESSEDSAMPLE only. ADPCM codecs consume + 2,136 bytes per instance and this number will determine + how many ADPCM channels can be played simultaneously. + Default = 32. */ + int maxXMAcodecs; /* [r/w] Optional. Specify 0 to ignore. For use with + FMOD_CREATECOMPRESSEDSAMPLE only. XMA codecs consume + 14,836 bytes per instance and this number will determine + how many XMA channels can be played simultaneously. + Default = 32. */ + int maxCELTcodecs; /* [r/w] Optional. Specify 0 to ignore. For use with + FMOD_CREATECOMPRESSEDSAMPLE only. CELT codecs consume + 11,500 bytes per instance and this number will determine + how many CELT channels can be played simultaneously. + Default = 32. */ + int maxVORBIScodecs; /* [r/w] Optional. Specify 0 to ignore. For use with + FMOD_CREATECOMPRESSEDSAMPLE only. Vorbis codecs + consume 12,000 bytes per instance and this number will + determine how many Vorbis channels can be played + simultaneously. Default = 32. */ + int maxAT9Codecs; /* [r/w] Optional. Specify 0 to ignore. For use with + FMOD_CREATECOMPRESSEDSAMPLE only. AT9 codecs consume + 8,720 bytes per instance and this number will determine + how many AT9 channels can be played simultaneously. + Default = 32. */ + int maxPCMcodecs; /* [r/w] Optional. Specify 0 to ignore. For use with PS3 + only. PCM codecs consume + 12,672 bytes per instance and this number will determine + how many streams and PCM voices can be played + simultaneously. Default = 16. */ + int ASIONumChannels; /* [r/w] Optional. Specify 0 to ignore. Number of + channels available on the ASIO device. */ + char **ASIOChannelList; /* [r/w] Optional. Specify 0 to ignore. Pointer to an + array of strings (number of entries defined by + ASIONumChannels) with ASIO channel names. */ + FMOD_SPEAKER * + ASIOSpeakerList; /* [r/w] Optional. Specify 0 to ignore. Pointer to a list + of speakers that the ASIO channels map to. This can + be called after System::init to remap ASIO output. */ + int max3DReverbDSPs; /* [r/w] Optional. Specify 0 to ignore. The max number of + 3d reverb DSP's in the system. (NOTE: CURRENTLY + DISABLED / UNUSED) */ + float HRTFMinAngle; /* [r/w] Optional. For use with + FMOD_INIT_HRTF_LOWPASS. The angle range (0-360) of a + 3D sound in relation to the listener, at which the HRTF + function begins to have an effect. 0 = in front of the + listener. 180 = from 90 degrees to the left of the + listener to 90 degrees to the right. 360 = behind the + listener. Default = 180.0. */ + float HRTFMaxAngle; /* [r/w] Optional. For use with + FMOD_INIT_HRTF_LOWPASS. The angle range (0-360) of a + 3D sound in relation to the listener, at which the HRTF + function has maximum effect. 0 = front of the listener. + 180 = from 90 degrees to the left of the listener to 90 + degrees to the right. 360 = behind the listener. + Default = 360.0. */ + float HRTFFreq; /* [r/w] Optional. Specify 0 to ignore. For use with + FMOD_INIT_HRTF_LOWPASS. The cutoff frequency of the HRTF's + lowpass filter function when at maximum effect. (i.e. at + HRTFMaxAngle). Default = 4000.0. */ + float + vol0virtualvol; /* [r/w] Optional. Specify 0 to ignore. For use with + FMOD_INIT_VOL0_BECOMES_VIRTUAL. If this flag is used, + and the volume is 0.0, then the sound will become + virtual. Use this value to raise the threshold to a + different point where a sound goes virtual. */ + int eventqueuesize; /* [r/w] Optional. Specify 0 to ignore. For use with FMOD + Event system only. Specifies the number of slots + available for simultaneous non blocking loads, across + all threads. Default = 32. */ + unsigned int + defaultDecodeBufferSize; /* [r/w] Optional. Specify 0 to ignore. For + streams. This determines the default size of + the double buffer (in milliseconds) that a + stream uses. Default = 400ms */ + char *debugLogFilename; /* [r/w] Optional. Specify 0 to ignore. Gives fmod's + logging system a path/filename. Normally the log + is placed in the same directory as the executable + and called fmod.log. When using + System::getAdvancedSettings, provide at least 256 + bytes of memory to copy into. */ + unsigned short + profileport; /* [r/w] Optional. Specify 0 to ignore. For use with + FMOD_INIT_ENABLE_PROFILE. Specify the port to listen on + for connections by the profiler application. */ + unsigned int + geometryMaxFadeTime; /* [r/w] Optional. Specify 0 to ignore. The maximum + time in miliseconds it takes for a channel to fade + to the new level when its occlusion changes. */ + unsigned int + maxSpectrumWaveDataBuffers; /* [r/w] Optional. Specify 0 to ignore. Tells + System::init to allocate a pool of + wavedata/spectrum buffers to prevent memory + fragmentation, any additional buffers will + be allocated normally. */ + unsigned int musicSystemCacheDelay; /* [r/w] Optional. Specify 0 to ignore. + The delay the music system should allow + for loading a sample from disk (in + milliseconds). Default = 400 ms. */ + float distanceFilterCenterFreq; /* [r/w] Optional. Specify 0 to ignore. For + use with FMOD_INIT_DISTANCE_FILTERING. The + default center frequency in Hz for the + distance filtering effect. Default = + 1500.0. */ + unsigned int stackSizeStream; /* [r/w] Optional. Specify 0 to ignore. Specify + the stack size for the FMOD Stream thread in + bytes. Useful for custom codecs that use + excess stack. Default 49,152 (48kb) */ + unsigned int + stackSizeNonBlocking; /* [r/w] Optional. Specify 0 to ignore. Specify the + stack size for the FMOD_NONBLOCKING loading + thread. Useful for custom codecs that use excess + stack. Default 65,536 (64kb) */ + unsigned int + stackSizeMixer; /* [r/w] Optional. Specify 0 to ignore. Specify the stack + size for the FMOD mixer thread. Useful for custom dsps + that use excess stack. Default 49,152 (48kb) */ } FMOD_ADVANCEDSETTINGS; - /* [ENUM] [ @@ -1836,7 +2851,8 @@ typedef struct FMOD_ADVANCEDSETTINGS To get 'all' of the channels, use System::getMasterChannelGroup. [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] System::playSound @@ -1845,42 +2861,52 @@ typedef struct FMOD_ADVANCEDSETTINGS System::getMasterChannelGroup ] */ -typedef enum -{ - FMOD_CHANNEL_FREE = -1, /* For a channel index, FMOD chooses a free voice using the priority system. */ - FMOD_CHANNEL_REUSE = -2 /* For a channel index, re-use the channel handle that was passed in. */ +typedef enum { + FMOD_CHANNEL_FREE = -1, /* For a channel index, FMOD chooses a free voice + using the priority system. */ + FMOD_CHANNEL_REUSE = -2 /* For a channel index, re-use the channel handle that + was passed in. */ } FMOD_CHANNELINDEX; #include "fmod_codec.h" #include "fmod_dsp.h" #include "fmod_memoryinfo.h" -/* ========================================================================================== */ -/* FUNCTION PROTOTYPES */ -/* ========================================================================================== */ +/* ========================================================================================== + */ +/* FUNCTION PROTOTYPES */ +/* ========================================================================================== + */ #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif /* FMOD global system functions (optional). */ -FMOD_RESULT F_API FMOD_Memory_Initialize (void *poolmem, int poollen, FMOD_MEMORY_ALLOCCALLBACK useralloc, FMOD_MEMORY_REALLOCCALLBACK userrealloc, FMOD_MEMORY_FREECALLBACK userfree, FMOD_MEMORY_TYPE memtypeflags); -FMOD_RESULT F_API FMOD_Memory_GetStats (int *currentalloced, int *maxalloced, FMOD_BOOL blocking); -FMOD_RESULT F_API FMOD_Debug_SetLevel (FMOD_DEBUGLEVEL level); -FMOD_RESULT F_API FMOD_Debug_GetLevel (FMOD_DEBUGLEVEL *level); -FMOD_RESULT F_API FMOD_File_SetDiskBusy (int busy); -FMOD_RESULT F_API FMOD_File_GetDiskBusy (int *busy); +FMOD_RESULT F_API FMOD_Memory_Initialize( + void *poolmem, + int poollen, + FMOD_MEMORY_ALLOCCALLBACK useralloc, + FMOD_MEMORY_REALLOCCALLBACK userrealloc, + FMOD_MEMORY_FREECALLBACK userfree, + FMOD_MEMORY_TYPE memtypeflags); +FMOD_RESULT F_API +FMOD_Memory_GetStats(int *currentalloced, int *maxalloced, FMOD_BOOL blocking); +FMOD_RESULT F_API FMOD_Debug_SetLevel(FMOD_DEBUGLEVEL level); +FMOD_RESULT F_API FMOD_Debug_GetLevel(FMOD_DEBUGLEVEL *level); +FMOD_RESULT F_API FMOD_File_SetDiskBusy(int busy); +FMOD_RESULT F_API FMOD_File_GetDiskBusy(int *busy); /* - FMOD System factory functions. Use this to create an FMOD System Instance. below you will see FMOD_System_Init/Close to get started. + FMOD System factory functions. Use this to create an FMOD System Instance. + below you will see FMOD_System_Init/Close to get started. */ -FMOD_RESULT F_API FMOD_System_Create (FMOD_SYSTEM **system); -FMOD_RESULT F_API FMOD_System_Release (FMOD_SYSTEM *system); +FMOD_RESULT F_API FMOD_System_Create(FMOD_SYSTEM **system); +FMOD_RESULT F_API FMOD_System_Release(FMOD_SYSTEM *system); /*$ preserve end $*/ @@ -1892,602 +2918,1200 @@ FMOD_RESULT F_API FMOD_System_Release (FMOD_SYSTEM *system); Pre-init functions. */ -FMOD_RESULT F_API FMOD_System_SetOutput (FMOD_SYSTEM *system, FMOD_OUTPUTTYPE output); -FMOD_RESULT F_API FMOD_System_GetOutput (FMOD_SYSTEM *system, FMOD_OUTPUTTYPE *output); -FMOD_RESULT F_API FMOD_System_GetNumDrivers (FMOD_SYSTEM *system, int *numdrivers); -FMOD_RESULT F_API FMOD_System_GetDriverInfo (FMOD_SYSTEM *system, int id, char *name, int namelen, FMOD_GUID *guid); -FMOD_RESULT F_API FMOD_System_GetDriverInfoW (FMOD_SYSTEM *system, int id, short *name, int namelen, FMOD_GUID *guid); -FMOD_RESULT F_API FMOD_System_GetDriverCaps (FMOD_SYSTEM *system, int id, FMOD_CAPS *caps, int *controlpaneloutputrate, FMOD_SPEAKERMODE *controlpanelspeakermode); -FMOD_RESULT F_API FMOD_System_SetDriver (FMOD_SYSTEM *system, int driver); -FMOD_RESULT F_API FMOD_System_GetDriver (FMOD_SYSTEM *system, int *driver); -FMOD_RESULT F_API FMOD_System_SetHardwareChannels (FMOD_SYSTEM *system, int numhardwarechannels); -FMOD_RESULT F_API FMOD_System_SetSoftwareChannels (FMOD_SYSTEM *system, int numsoftwarechannels); -FMOD_RESULT F_API FMOD_System_GetSoftwareChannels (FMOD_SYSTEM *system, int *numsoftwarechannels); -FMOD_RESULT F_API FMOD_System_SetSoftwareFormat (FMOD_SYSTEM *system, int samplerate, FMOD_SOUND_FORMAT format, int numoutputchannels, int maxinputchannels, FMOD_DSP_RESAMPLER resamplemethod); -FMOD_RESULT F_API FMOD_System_GetSoftwareFormat (FMOD_SYSTEM *system, int *samplerate, FMOD_SOUND_FORMAT *format, int *numoutputchannels, int *maxinputchannels, FMOD_DSP_RESAMPLER *resamplemethod, int *bits); -FMOD_RESULT F_API FMOD_System_SetDSPBufferSize (FMOD_SYSTEM *system, unsigned int bufferlength, int numbuffers); -FMOD_RESULT F_API FMOD_System_GetDSPBufferSize (FMOD_SYSTEM *system, unsigned int *bufferlength, int *numbuffers); -FMOD_RESULT F_API FMOD_System_SetFileSystem (FMOD_SYSTEM *system, FMOD_FILE_OPENCALLBACK useropen, FMOD_FILE_CLOSECALLBACK userclose, FMOD_FILE_READCALLBACK userread, FMOD_FILE_SEEKCALLBACK userseek, FMOD_FILE_ASYNCREADCALLBACK userasyncread, FMOD_FILE_ASYNCCANCELCALLBACK userasynccancel, int blockalign); -FMOD_RESULT F_API FMOD_System_AttachFileSystem (FMOD_SYSTEM *system, FMOD_FILE_OPENCALLBACK useropen, FMOD_FILE_CLOSECALLBACK userclose, FMOD_FILE_READCALLBACK userread, FMOD_FILE_SEEKCALLBACK userseek); -FMOD_RESULT F_API FMOD_System_SetAdvancedSettings (FMOD_SYSTEM *system, FMOD_ADVANCEDSETTINGS *settings); -FMOD_RESULT F_API FMOD_System_GetAdvancedSettings (FMOD_SYSTEM *system, FMOD_ADVANCEDSETTINGS *settings); -FMOD_RESULT F_API FMOD_System_SetSpeakerMode (FMOD_SYSTEM *system, FMOD_SPEAKERMODE speakermode); -FMOD_RESULT F_API FMOD_System_GetSpeakerMode (FMOD_SYSTEM *system, FMOD_SPEAKERMODE *speakermode); -FMOD_RESULT F_API FMOD_System_SetCallback (FMOD_SYSTEM *system, FMOD_SYSTEM_CALLBACK callback); +FMOD_RESULT F_API +FMOD_System_SetOutput(FMOD_SYSTEM *system, FMOD_OUTPUTTYPE output); +FMOD_RESULT F_API +FMOD_System_GetOutput(FMOD_SYSTEM *system, FMOD_OUTPUTTYPE *output); +FMOD_RESULT F_API +FMOD_System_GetNumDrivers(FMOD_SYSTEM *system, int *numdrivers); +FMOD_RESULT F_API FMOD_System_GetDriverInfo( + FMOD_SYSTEM *system, int id, char *name, int namelen, FMOD_GUID *guid); +FMOD_RESULT F_API FMOD_System_GetDriverInfoW( + FMOD_SYSTEM *system, int id, short *name, int namelen, FMOD_GUID *guid); +FMOD_RESULT F_API FMOD_System_GetDriverCaps( + FMOD_SYSTEM *system, + int id, + FMOD_CAPS *caps, + int *controlpaneloutputrate, + FMOD_SPEAKERMODE *controlpanelspeakermode); +FMOD_RESULT F_API FMOD_System_SetDriver(FMOD_SYSTEM *system, int driver); +FMOD_RESULT F_API FMOD_System_GetDriver(FMOD_SYSTEM *system, int *driver); +FMOD_RESULT F_API +FMOD_System_SetHardwareChannels(FMOD_SYSTEM *system, int numhardwarechannels); +FMOD_RESULT F_API +FMOD_System_SetSoftwareChannels(FMOD_SYSTEM *system, int numsoftwarechannels); +FMOD_RESULT F_API +FMOD_System_GetSoftwareChannels(FMOD_SYSTEM *system, int *numsoftwarechannels); +FMOD_RESULT F_API FMOD_System_SetSoftwareFormat( + FMOD_SYSTEM *system, + int samplerate, + FMOD_SOUND_FORMAT format, + int numoutputchannels, + int maxinputchannels, + FMOD_DSP_RESAMPLER resamplemethod); +FMOD_RESULT F_API FMOD_System_GetSoftwareFormat( + FMOD_SYSTEM *system, + int *samplerate, + FMOD_SOUND_FORMAT *format, + int *numoutputchannels, + int *maxinputchannels, + FMOD_DSP_RESAMPLER *resamplemethod, + int *bits); +FMOD_RESULT F_API FMOD_System_SetDSPBufferSize( + FMOD_SYSTEM *system, unsigned int bufferlength, int numbuffers); +FMOD_RESULT F_API FMOD_System_GetDSPBufferSize( + FMOD_SYSTEM *system, unsigned int *bufferlength, int *numbuffers); +FMOD_RESULT F_API FMOD_System_SetFileSystem( + FMOD_SYSTEM *system, + FMOD_FILE_OPENCALLBACK useropen, + FMOD_FILE_CLOSECALLBACK userclose, + FMOD_FILE_READCALLBACK userread, + FMOD_FILE_SEEKCALLBACK userseek, + FMOD_FILE_ASYNCREADCALLBACK userasyncread, + FMOD_FILE_ASYNCCANCELCALLBACK userasynccancel, + int blockalign); +FMOD_RESULT F_API FMOD_System_AttachFileSystem( + FMOD_SYSTEM *system, + FMOD_FILE_OPENCALLBACK useropen, + FMOD_FILE_CLOSECALLBACK userclose, + FMOD_FILE_READCALLBACK userread, + FMOD_FILE_SEEKCALLBACK userseek); +FMOD_RESULT F_API FMOD_System_SetAdvancedSettings( + FMOD_SYSTEM *system, FMOD_ADVANCEDSETTINGS *settings); +FMOD_RESULT F_API FMOD_System_GetAdvancedSettings( + FMOD_SYSTEM *system, FMOD_ADVANCEDSETTINGS *settings); +FMOD_RESULT F_API +FMOD_System_SetSpeakerMode(FMOD_SYSTEM *system, FMOD_SPEAKERMODE speakermode); +FMOD_RESULT F_API +FMOD_System_GetSpeakerMode(FMOD_SYSTEM *system, FMOD_SPEAKERMODE *speakermode); +FMOD_RESULT F_API +FMOD_System_SetCallback(FMOD_SYSTEM *system, FMOD_SYSTEM_CALLBACK callback); /* - Plug-in support + Plug-in support */ -FMOD_RESULT F_API FMOD_System_SetPluginPath (FMOD_SYSTEM *system, const char *path); -FMOD_RESULT F_API FMOD_System_LoadPlugin (FMOD_SYSTEM *system, const char *filename, unsigned int *handle, unsigned int priority); -FMOD_RESULT F_API FMOD_System_UnloadPlugin (FMOD_SYSTEM *system, unsigned int handle); -FMOD_RESULT F_API FMOD_System_GetNumPlugins (FMOD_SYSTEM *system, FMOD_PLUGINTYPE plugintype, int *numplugins); -FMOD_RESULT F_API FMOD_System_GetPluginHandle (FMOD_SYSTEM *system, FMOD_PLUGINTYPE plugintype, int index, unsigned int *handle); -FMOD_RESULT F_API FMOD_System_GetPluginInfo (FMOD_SYSTEM *system, unsigned int handle, FMOD_PLUGINTYPE *plugintype, char *name, int namelen, unsigned int *version); -FMOD_RESULT F_API FMOD_System_SetOutputByPlugin (FMOD_SYSTEM *system, unsigned int handle); -FMOD_RESULT F_API FMOD_System_GetOutputByPlugin (FMOD_SYSTEM *system, unsigned int *handle); -FMOD_RESULT F_API FMOD_System_CreateDSPByPlugin (FMOD_SYSTEM *system, unsigned int handle, FMOD_DSP **dsp); -FMOD_RESULT F_API FMOD_System_RegisterCodec (FMOD_SYSTEM *system, FMOD_CODEC_DESCRIPTION *description, unsigned int *handle, unsigned int priority); -FMOD_RESULT F_API FMOD_System_RegisterDSP (FMOD_SYSTEM *system, FMOD_DSP_DESCRIPTION *description, unsigned int *handle); +FMOD_RESULT F_API +FMOD_System_SetPluginPath(FMOD_SYSTEM *system, const char *path); +FMOD_RESULT F_API FMOD_System_LoadPlugin( + FMOD_SYSTEM *system, + const char *filename, + unsigned int *handle, + unsigned int priority); +FMOD_RESULT F_API +FMOD_System_UnloadPlugin(FMOD_SYSTEM *system, unsigned int handle); +FMOD_RESULT F_API FMOD_System_GetNumPlugins( + FMOD_SYSTEM *system, FMOD_PLUGINTYPE plugintype, int *numplugins); +FMOD_RESULT F_API FMOD_System_GetPluginHandle( + FMOD_SYSTEM *system, + FMOD_PLUGINTYPE plugintype, + int index, + unsigned int *handle); +FMOD_RESULT F_API FMOD_System_GetPluginInfo( + FMOD_SYSTEM *system, + unsigned int handle, + FMOD_PLUGINTYPE *plugintype, + char *name, + int namelen, + unsigned int *version); +FMOD_RESULT F_API +FMOD_System_SetOutputByPlugin(FMOD_SYSTEM *system, unsigned int handle); +FMOD_RESULT F_API +FMOD_System_GetOutputByPlugin(FMOD_SYSTEM *system, unsigned int *handle); +FMOD_RESULT F_API FMOD_System_CreateDSPByPlugin( + FMOD_SYSTEM *system, unsigned int handle, FMOD_DSP **dsp); +FMOD_RESULT F_API FMOD_System_RegisterCodec( + FMOD_SYSTEM *system, + FMOD_CODEC_DESCRIPTION *description, + unsigned int *handle, + unsigned int priority); +FMOD_RESULT F_API FMOD_System_RegisterDSP( + FMOD_SYSTEM *system, + FMOD_DSP_DESCRIPTION *description, + unsigned int *handle); /* - Init/Close + Init/Close */ -FMOD_RESULT F_API FMOD_System_Init (FMOD_SYSTEM *system, int maxchannels, FMOD_INITFLAGS flags, void *extradriverdata); -FMOD_RESULT F_API FMOD_System_Close (FMOD_SYSTEM *system); +FMOD_RESULT F_API FMOD_System_Init( + FMOD_SYSTEM *system, + int maxchannels, + FMOD_INITFLAGS flags, + void *extradriverdata); +FMOD_RESULT F_API FMOD_System_Close(FMOD_SYSTEM *system); /* - General post-init system functions + General post-init system functions */ -FMOD_RESULT F_API FMOD_System_Update (FMOD_SYSTEM *system); +FMOD_RESULT F_API FMOD_System_Update(FMOD_SYSTEM *system); -FMOD_RESULT F_API FMOD_System_Set3DSettings (FMOD_SYSTEM *system, float dopplerscale, float distancefactor, float rolloffscale); -FMOD_RESULT F_API FMOD_System_Get3DSettings (FMOD_SYSTEM *system, float *dopplerscale, float *distancefactor, float *rolloffscale); -FMOD_RESULT F_API FMOD_System_Set3DNumListeners (FMOD_SYSTEM *system, int numlisteners); -FMOD_RESULT F_API FMOD_System_Get3DNumListeners (FMOD_SYSTEM *system, int *numlisteners); -FMOD_RESULT F_API FMOD_System_Set3DListenerAttributes(FMOD_SYSTEM *system, int listener, const FMOD_VECTOR *pos, const FMOD_VECTOR *vel, const FMOD_VECTOR *forward, const FMOD_VECTOR *up); -FMOD_RESULT F_API FMOD_System_Get3DListenerAttributes(FMOD_SYSTEM *system, int listener, FMOD_VECTOR *pos, FMOD_VECTOR *vel, FMOD_VECTOR *forward, FMOD_VECTOR *up); -FMOD_RESULT F_API FMOD_System_Set3DRolloffCallback (FMOD_SYSTEM *system, FMOD_3D_ROLLOFFCALLBACK callback); -FMOD_RESULT F_API FMOD_System_Set3DSpeakerPosition (FMOD_SYSTEM *system, FMOD_SPEAKER speaker, float x, float y, FMOD_BOOL active); -FMOD_RESULT F_API FMOD_System_Get3DSpeakerPosition (FMOD_SYSTEM *system, FMOD_SPEAKER speaker, float *x, float *y, FMOD_BOOL *active); +FMOD_RESULT F_API FMOD_System_Set3DSettings( + FMOD_SYSTEM *system, + float dopplerscale, + float distancefactor, + float rolloffscale); +FMOD_RESULT F_API FMOD_System_Get3DSettings( + FMOD_SYSTEM *system, + float *dopplerscale, + float *distancefactor, + float *rolloffscale); +FMOD_RESULT F_API +FMOD_System_Set3DNumListeners(FMOD_SYSTEM *system, int numlisteners); +FMOD_RESULT F_API +FMOD_System_Get3DNumListeners(FMOD_SYSTEM *system, int *numlisteners); +FMOD_RESULT F_API FMOD_System_Set3DListenerAttributes( + FMOD_SYSTEM *system, + int listener, + const FMOD_VECTOR *pos, + const FMOD_VECTOR *vel, + const FMOD_VECTOR *forward, + const FMOD_VECTOR *up); +FMOD_RESULT F_API FMOD_System_Get3DListenerAttributes( + FMOD_SYSTEM *system, + int listener, + FMOD_VECTOR *pos, + FMOD_VECTOR *vel, + FMOD_VECTOR *forward, + FMOD_VECTOR *up); +FMOD_RESULT F_API FMOD_System_Set3DRolloffCallback( + FMOD_SYSTEM *system, FMOD_3D_ROLLOFFCALLBACK callback); +FMOD_RESULT F_API FMOD_System_Set3DSpeakerPosition( + FMOD_SYSTEM *system, + FMOD_SPEAKER speaker, + float x, + float y, + FMOD_BOOL active); +FMOD_RESULT F_API FMOD_System_Get3DSpeakerPosition( + FMOD_SYSTEM *system, + FMOD_SPEAKER speaker, + float *x, + float *y, + FMOD_BOOL *active); -FMOD_RESULT F_API FMOD_System_SetStreamBufferSize (FMOD_SYSTEM *system, unsigned int filebuffersize, FMOD_TIMEUNIT filebuffersizetype); -FMOD_RESULT F_API FMOD_System_GetStreamBufferSize (FMOD_SYSTEM *system, unsigned int *filebuffersize, FMOD_TIMEUNIT *filebuffersizetype); +FMOD_RESULT F_API FMOD_System_SetStreamBufferSize( + FMOD_SYSTEM *system, + unsigned int filebuffersize, + FMOD_TIMEUNIT filebuffersizetype); +FMOD_RESULT F_API FMOD_System_GetStreamBufferSize( + FMOD_SYSTEM *system, + unsigned int *filebuffersize, + FMOD_TIMEUNIT *filebuffersizetype); /* - System information functions. + System information functions. */ -FMOD_RESULT F_API FMOD_System_GetVersion (FMOD_SYSTEM *system, unsigned int *version); -FMOD_RESULT F_API FMOD_System_GetOutputHandle (FMOD_SYSTEM *system, void **handle); -FMOD_RESULT F_API FMOD_System_GetChannelsPlaying (FMOD_SYSTEM *system, int *channels); -FMOD_RESULT F_API FMOD_System_GetHardwareChannels (FMOD_SYSTEM *system, int *numhardwarechannels); -FMOD_RESULT F_API FMOD_System_GetCPUUsage (FMOD_SYSTEM *system, float *dsp, float *stream, float *geometry, float *update, float *total); -FMOD_RESULT F_API FMOD_System_GetSoundRAM (FMOD_SYSTEM *system, int *currentalloced, int *maxalloced, int *total); -FMOD_RESULT F_API FMOD_System_GetNumCDROMDrives (FMOD_SYSTEM *system, int *numdrives); -FMOD_RESULT F_API FMOD_System_GetCDROMDriveName (FMOD_SYSTEM *system, int drive, char *drivename, int drivenamelen, char *scsiname, int scsinamelen, char *devicename, int devicenamelen); -FMOD_RESULT F_API FMOD_System_GetSpectrum (FMOD_SYSTEM *system, float *spectrumarray, int numvalues, int channeloffset, FMOD_DSP_FFT_WINDOW windowtype); -FMOD_RESULT F_API FMOD_System_GetWaveData (FMOD_SYSTEM *system, float *wavearray, int numvalues, int channeloffset); +FMOD_RESULT F_API +FMOD_System_GetVersion(FMOD_SYSTEM *system, unsigned int *version); +FMOD_RESULT F_API +FMOD_System_GetOutputHandle(FMOD_SYSTEM *system, void **handle); +FMOD_RESULT F_API +FMOD_System_GetChannelsPlaying(FMOD_SYSTEM *system, int *channels); +FMOD_RESULT F_API +FMOD_System_GetHardwareChannels(FMOD_SYSTEM *system, int *numhardwarechannels); +FMOD_RESULT F_API FMOD_System_GetCPUUsage( + FMOD_SYSTEM *system, + float *dsp, + float *stream, + float *geometry, + float *update, + float *total); +FMOD_RESULT F_API FMOD_System_GetSoundRAM( + FMOD_SYSTEM *system, int *currentalloced, int *maxalloced, int *total); +FMOD_RESULT F_API +FMOD_System_GetNumCDROMDrives(FMOD_SYSTEM *system, int *numdrives); +FMOD_RESULT F_API FMOD_System_GetCDROMDriveName( + FMOD_SYSTEM *system, + int drive, + char *drivename, + int drivenamelen, + char *scsiname, + int scsinamelen, + char *devicename, + int devicenamelen); +FMOD_RESULT F_API FMOD_System_GetSpectrum( + FMOD_SYSTEM *system, + float *spectrumarray, + int numvalues, + int channeloffset, + FMOD_DSP_FFT_WINDOW windowtype); +FMOD_RESULT F_API FMOD_System_GetWaveData( + FMOD_SYSTEM *system, float *wavearray, int numvalues, int channeloffset); /* - Sound/DSP/Channel/FX creation and retrieval. + Sound/DSP/Channel/FX creation and retrieval. */ -FMOD_RESULT F_API FMOD_System_CreateSound (FMOD_SYSTEM *system, const char *name_or_data, FMOD_MODE mode, FMOD_CREATESOUNDEXINFO *exinfo, FMOD_SOUND **sound); -FMOD_RESULT F_API FMOD_System_CreateStream (FMOD_SYSTEM *system, const char *name_or_data, FMOD_MODE mode, FMOD_CREATESOUNDEXINFO *exinfo, FMOD_SOUND **sound); -FMOD_RESULT F_API FMOD_System_CreateDSP (FMOD_SYSTEM *system, FMOD_DSP_DESCRIPTION *description, FMOD_DSP **dsp); -FMOD_RESULT F_API FMOD_System_CreateDSPByType (FMOD_SYSTEM *system, FMOD_DSP_TYPE type, FMOD_DSP **dsp); -FMOD_RESULT F_API FMOD_System_CreateChannelGroup (FMOD_SYSTEM *system, const char *name, FMOD_CHANNELGROUP **channelgroup); -FMOD_RESULT F_API FMOD_System_CreateSoundGroup (FMOD_SYSTEM *system, const char *name, FMOD_SOUNDGROUP **soundgroup); -FMOD_RESULT F_API FMOD_System_CreateReverb (FMOD_SYSTEM *system, FMOD_REVERB **reverb); +FMOD_RESULT F_API FMOD_System_CreateSound( + FMOD_SYSTEM *system, + const char *name_or_data, + FMOD_MODE mode, + FMOD_CREATESOUNDEXINFO *exinfo, + FMOD_SOUND **sound); +FMOD_RESULT F_API FMOD_System_CreateStream( + FMOD_SYSTEM *system, + const char *name_or_data, + FMOD_MODE mode, + FMOD_CREATESOUNDEXINFO *exinfo, + FMOD_SOUND **sound); +FMOD_RESULT F_API FMOD_System_CreateDSP( + FMOD_SYSTEM *system, FMOD_DSP_DESCRIPTION *description, FMOD_DSP **dsp); +FMOD_RESULT F_API FMOD_System_CreateDSPByType( + FMOD_SYSTEM *system, FMOD_DSP_TYPE type, FMOD_DSP **dsp); +FMOD_RESULT F_API FMOD_System_CreateChannelGroup( + FMOD_SYSTEM *system, const char *name, FMOD_CHANNELGROUP **channelgroup); +FMOD_RESULT F_API FMOD_System_CreateSoundGroup( + FMOD_SYSTEM *system, const char *name, FMOD_SOUNDGROUP **soundgroup); +FMOD_RESULT F_API +FMOD_System_CreateReverb(FMOD_SYSTEM *system, FMOD_REVERB **reverb); -FMOD_RESULT F_API FMOD_System_PlaySound (FMOD_SYSTEM *system, FMOD_CHANNELINDEX channelid, FMOD_SOUND *sound, FMOD_BOOL paused, FMOD_CHANNEL **channel); -FMOD_RESULT F_API FMOD_System_PlayDSP (FMOD_SYSTEM *system, FMOD_CHANNELINDEX channelid, FMOD_DSP *dsp, FMOD_BOOL paused, FMOD_CHANNEL **channel); -FMOD_RESULT F_API FMOD_System_GetChannel (FMOD_SYSTEM *system, int channelid, FMOD_CHANNEL **channel); -FMOD_RESULT F_API FMOD_System_GetMasterChannelGroup (FMOD_SYSTEM *system, FMOD_CHANNELGROUP **channelgroup); -FMOD_RESULT F_API FMOD_System_GetMasterSoundGroup (FMOD_SYSTEM *system, FMOD_SOUNDGROUP **soundgroup); +FMOD_RESULT F_API FMOD_System_PlaySound( + FMOD_SYSTEM *system, + FMOD_CHANNELINDEX channelid, + FMOD_SOUND *sound, + FMOD_BOOL paused, + FMOD_CHANNEL **channel); +FMOD_RESULT F_API FMOD_System_PlayDSP( + FMOD_SYSTEM *system, + FMOD_CHANNELINDEX channelid, + FMOD_DSP *dsp, + FMOD_BOOL paused, + FMOD_CHANNEL **channel); +FMOD_RESULT F_API FMOD_System_GetChannel( + FMOD_SYSTEM *system, int channelid, FMOD_CHANNEL **channel); +FMOD_RESULT F_API FMOD_System_GetMasterChannelGroup( + FMOD_SYSTEM *system, FMOD_CHANNELGROUP **channelgroup); +FMOD_RESULT F_API FMOD_System_GetMasterSoundGroup( + FMOD_SYSTEM *system, FMOD_SOUNDGROUP **soundgroup); /* - Reverb API + Reverb API */ -FMOD_RESULT F_API FMOD_System_SetReverbProperties (FMOD_SYSTEM *system, const FMOD_REVERB_PROPERTIES *prop); -FMOD_RESULT F_API FMOD_System_GetReverbProperties (FMOD_SYSTEM *system, FMOD_REVERB_PROPERTIES *prop); -FMOD_RESULT F_API FMOD_System_SetReverbAmbientProperties(FMOD_SYSTEM *system, FMOD_REVERB_PROPERTIES *prop); -FMOD_RESULT F_API FMOD_System_GetReverbAmbientProperties(FMOD_SYSTEM *system, FMOD_REVERB_PROPERTIES *prop); +FMOD_RESULT F_API FMOD_System_SetReverbProperties( + FMOD_SYSTEM *system, const FMOD_REVERB_PROPERTIES *prop); +FMOD_RESULT F_API FMOD_System_GetReverbProperties( + FMOD_SYSTEM *system, FMOD_REVERB_PROPERTIES *prop); +FMOD_RESULT F_API FMOD_System_SetReverbAmbientProperties( + FMOD_SYSTEM *system, FMOD_REVERB_PROPERTIES *prop); +FMOD_RESULT F_API FMOD_System_GetReverbAmbientProperties( + FMOD_SYSTEM *system, FMOD_REVERB_PROPERTIES *prop); /* System level DSP access. */ -FMOD_RESULT F_API FMOD_System_GetDSPHead (FMOD_SYSTEM *system, FMOD_DSP **dsp); -FMOD_RESULT F_API FMOD_System_AddDSP (FMOD_SYSTEM *system, FMOD_DSP *dsp, FMOD_DSPCONNECTION **connection); -FMOD_RESULT F_API FMOD_System_LockDSP (FMOD_SYSTEM *system); -FMOD_RESULT F_API FMOD_System_UnlockDSP (FMOD_SYSTEM *system); -FMOD_RESULT F_API FMOD_System_GetDSPClock (FMOD_SYSTEM *system, unsigned int *hi, unsigned int *lo); +FMOD_RESULT F_API FMOD_System_GetDSPHead(FMOD_SYSTEM *system, FMOD_DSP **dsp); +FMOD_RESULT F_API FMOD_System_AddDSP( + FMOD_SYSTEM *system, FMOD_DSP *dsp, FMOD_DSPCONNECTION **connection); +FMOD_RESULT F_API FMOD_System_LockDSP(FMOD_SYSTEM *system); +FMOD_RESULT F_API FMOD_System_UnlockDSP(FMOD_SYSTEM *system); +FMOD_RESULT F_API FMOD_System_GetDSPClock( + FMOD_SYSTEM *system, unsigned int *hi, unsigned int *lo); /* Recording API. */ -FMOD_RESULT F_API FMOD_System_GetRecordNumDrivers (FMOD_SYSTEM *system, int *numdrivers); -FMOD_RESULT F_API FMOD_System_GetRecordDriverInfo (FMOD_SYSTEM *system, int id, char *name, int namelen, FMOD_GUID *guid); -FMOD_RESULT F_API FMOD_System_GetRecordDriverInfoW (FMOD_SYSTEM *system, int id, short *name, int namelen, FMOD_GUID *guid); -FMOD_RESULT F_API FMOD_System_GetRecordDriverCaps (FMOD_SYSTEM *system, int id, FMOD_CAPS *caps, int *minfrequency, int *maxfrequency); -FMOD_RESULT F_API FMOD_System_GetRecordPosition (FMOD_SYSTEM *system, int id, unsigned int *position); +FMOD_RESULT F_API +FMOD_System_GetRecordNumDrivers(FMOD_SYSTEM *system, int *numdrivers); +FMOD_RESULT F_API FMOD_System_GetRecordDriverInfo( + FMOD_SYSTEM *system, int id, char *name, int namelen, FMOD_GUID *guid); +FMOD_RESULT F_API FMOD_System_GetRecordDriverInfoW( + FMOD_SYSTEM *system, int id, short *name, int namelen, FMOD_GUID *guid); +FMOD_RESULT F_API FMOD_System_GetRecordDriverCaps( + FMOD_SYSTEM *system, + int id, + FMOD_CAPS *caps, + int *minfrequency, + int *maxfrequency); +FMOD_RESULT F_API FMOD_System_GetRecordPosition( + FMOD_SYSTEM *system, int id, unsigned int *position); -FMOD_RESULT F_API FMOD_System_RecordStart (FMOD_SYSTEM *system, int id, FMOD_SOUND *sound, FMOD_BOOL loop); -FMOD_RESULT F_API FMOD_System_RecordStop (FMOD_SYSTEM *system, int id); -FMOD_RESULT F_API FMOD_System_IsRecording (FMOD_SYSTEM *system, int id, FMOD_BOOL *recording); +FMOD_RESULT F_API FMOD_System_RecordStart( + FMOD_SYSTEM *system, int id, FMOD_SOUND *sound, FMOD_BOOL loop); +FMOD_RESULT F_API FMOD_System_RecordStop(FMOD_SYSTEM *system, int id); +FMOD_RESULT F_API +FMOD_System_IsRecording(FMOD_SYSTEM *system, int id, FMOD_BOOL *recording); /* Geometry API. */ -FMOD_RESULT F_API FMOD_System_CreateGeometry (FMOD_SYSTEM *system, int maxpolygons, int maxvertices, FMOD_GEOMETRY **geometry); -FMOD_RESULT F_API FMOD_System_SetGeometrySettings (FMOD_SYSTEM *system, float maxworldsize); -FMOD_RESULT F_API FMOD_System_GetGeometrySettings (FMOD_SYSTEM *system, float *maxworldsize); -FMOD_RESULT F_API FMOD_System_LoadGeometry (FMOD_SYSTEM *system, const void *data, int datasize, FMOD_GEOMETRY **geometry); -FMOD_RESULT F_API FMOD_System_GetGeometryOcclusion (FMOD_SYSTEM *system, const FMOD_VECTOR *listener, const FMOD_VECTOR *source, float *direct, float *reverb); +FMOD_RESULT F_API FMOD_System_CreateGeometry( + FMOD_SYSTEM *system, + int maxpolygons, + int maxvertices, + FMOD_GEOMETRY **geometry); +FMOD_RESULT F_API +FMOD_System_SetGeometrySettings(FMOD_SYSTEM *system, float maxworldsize); +FMOD_RESULT F_API +FMOD_System_GetGeometrySettings(FMOD_SYSTEM *system, float *maxworldsize); +FMOD_RESULT F_API FMOD_System_LoadGeometry( + FMOD_SYSTEM *system, + const void *data, + int datasize, + FMOD_GEOMETRY **geometry); +FMOD_RESULT F_API FMOD_System_GetGeometryOcclusion( + FMOD_SYSTEM *system, + const FMOD_VECTOR *listener, + const FMOD_VECTOR *source, + float *direct, + float *reverb); /* Network functions. */ -FMOD_RESULT F_API FMOD_System_SetNetworkProxy (FMOD_SYSTEM *system, const char *proxy); -FMOD_RESULT F_API FMOD_System_GetNetworkProxy (FMOD_SYSTEM *system, char *proxy, int proxylen); -FMOD_RESULT F_API FMOD_System_SetNetworkTimeout (FMOD_SYSTEM *system, int timeout); -FMOD_RESULT F_API FMOD_System_GetNetworkTimeout (FMOD_SYSTEM *system, int *timeout); +FMOD_RESULT F_API +FMOD_System_SetNetworkProxy(FMOD_SYSTEM *system, const char *proxy); +FMOD_RESULT F_API +FMOD_System_GetNetworkProxy(FMOD_SYSTEM *system, char *proxy, int proxylen); +FMOD_RESULT F_API +FMOD_System_SetNetworkTimeout(FMOD_SYSTEM *system, int timeout); +FMOD_RESULT F_API +FMOD_System_GetNetworkTimeout(FMOD_SYSTEM *system, int *timeout); /* Userdata set/get. */ -FMOD_RESULT F_API FMOD_System_SetUserData (FMOD_SYSTEM *system, void *userdata); -FMOD_RESULT F_API FMOD_System_GetUserData (FMOD_SYSTEM *system, void **userdata); +FMOD_RESULT F_API FMOD_System_SetUserData(FMOD_SYSTEM *system, void *userdata); +FMOD_RESULT F_API FMOD_System_GetUserData(FMOD_SYSTEM *system, void **userdata); -FMOD_RESULT F_API FMOD_System_GetMemoryInfo (FMOD_SYSTEM *system, unsigned int memorybits, unsigned int event_memorybits, unsigned int *memoryused, FMOD_MEMORY_USAGE_DETAILS *memoryused_details); +FMOD_RESULT F_API FMOD_System_GetMemoryInfo( + FMOD_SYSTEM *system, + unsigned int memorybits, + unsigned int event_memorybits, + unsigned int *memoryused, + FMOD_MEMORY_USAGE_DETAILS *memoryused_details); /* 'Sound' API */ -FMOD_RESULT F_API FMOD_Sound_Release (FMOD_SOUND *sound); -FMOD_RESULT F_API FMOD_Sound_GetSystemObject (FMOD_SOUND *sound, FMOD_SYSTEM **system); +FMOD_RESULT F_API FMOD_Sound_Release(FMOD_SOUND *sound); +FMOD_RESULT F_API +FMOD_Sound_GetSystemObject(FMOD_SOUND *sound, FMOD_SYSTEM **system); /* - Standard sound manipulation functions. + Standard sound manipulation functions. */ -FMOD_RESULT F_API FMOD_Sound_Lock (FMOD_SOUND *sound, unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2); -FMOD_RESULT F_API FMOD_Sound_Unlock (FMOD_SOUND *sound, void *ptr1, void *ptr2, unsigned int len1, unsigned int len2); -FMOD_RESULT F_API FMOD_Sound_SetDefaults (FMOD_SOUND *sound, float frequency, float volume, float pan, int priority); -FMOD_RESULT F_API FMOD_Sound_GetDefaults (FMOD_SOUND *sound, float *frequency, float *volume, float *pan, int *priority); -FMOD_RESULT F_API FMOD_Sound_SetVariations (FMOD_SOUND *sound, float frequencyvar, float volumevar, float panvar); -FMOD_RESULT F_API FMOD_Sound_GetVariations (FMOD_SOUND *sound, float *frequencyvar, float *volumevar, float *panvar); -FMOD_RESULT F_API FMOD_Sound_Set3DMinMaxDistance (FMOD_SOUND *sound, float min, float max); -FMOD_RESULT F_API FMOD_Sound_Get3DMinMaxDistance (FMOD_SOUND *sound, float *min, float *max); -FMOD_RESULT F_API FMOD_Sound_Set3DConeSettings (FMOD_SOUND *sound, float insideconeangle, float outsideconeangle, float outsidevolume); -FMOD_RESULT F_API FMOD_Sound_Get3DConeSettings (FMOD_SOUND *sound, float *insideconeangle, float *outsideconeangle, float *outsidevolume); -FMOD_RESULT F_API FMOD_Sound_Set3DCustomRolloff (FMOD_SOUND *sound, FMOD_VECTOR *points, int numpoints); -FMOD_RESULT F_API FMOD_Sound_Get3DCustomRolloff (FMOD_SOUND *sound, FMOD_VECTOR **points, int *numpoints); -FMOD_RESULT F_API FMOD_Sound_SetSubSound (FMOD_SOUND *sound, int index, FMOD_SOUND *subsound); -FMOD_RESULT F_API FMOD_Sound_GetSubSound (FMOD_SOUND *sound, int index, FMOD_SOUND **subsound); -FMOD_RESULT F_API FMOD_Sound_GetSubSoundParent (FMOD_SOUND *sound, FMOD_SOUND **parentsound); -FMOD_RESULT F_API FMOD_Sound_SetSubSoundSentence (FMOD_SOUND *sound, int *subsoundlist, int numsubsounds); -FMOD_RESULT F_API FMOD_Sound_GetName (FMOD_SOUND *sound, char *name, int namelen); -FMOD_RESULT F_API FMOD_Sound_GetLength (FMOD_SOUND *sound, unsigned int *length, FMOD_TIMEUNIT lengthtype); -FMOD_RESULT F_API FMOD_Sound_GetFormat (FMOD_SOUND *sound, FMOD_SOUND_TYPE *type, FMOD_SOUND_FORMAT *format, int *channels, int *bits); -FMOD_RESULT F_API FMOD_Sound_GetNumSubSounds (FMOD_SOUND *sound, int *numsubsounds); -FMOD_RESULT F_API FMOD_Sound_GetNumTags (FMOD_SOUND *sound, int *numtags, int *numtagsupdated); -FMOD_RESULT F_API FMOD_Sound_GetTag (FMOD_SOUND *sound, const char *name, int index, FMOD_TAG *tag); -FMOD_RESULT F_API FMOD_Sound_GetOpenState (FMOD_SOUND *sound, FMOD_OPENSTATE *openstate, unsigned int *percentbuffered, FMOD_BOOL *starving, FMOD_BOOL *diskbusy); -FMOD_RESULT F_API FMOD_Sound_ReadData (FMOD_SOUND *sound, void *buffer, unsigned int lenbytes, unsigned int *read); -FMOD_RESULT F_API FMOD_Sound_SeekData (FMOD_SOUND *sound, unsigned int pcm); +FMOD_RESULT F_API FMOD_Sound_Lock( + FMOD_SOUND *sound, + unsigned int offset, + unsigned int length, + void **ptr1, + void **ptr2, + unsigned int *len1, + unsigned int *len2); +FMOD_RESULT F_API FMOD_Sound_Unlock( + FMOD_SOUND *sound, + void *ptr1, + void *ptr2, + unsigned int len1, + unsigned int len2); +FMOD_RESULT F_API FMOD_Sound_SetDefaults( + FMOD_SOUND *sound, float frequency, float volume, float pan, int priority); +FMOD_RESULT F_API FMOD_Sound_GetDefaults( + FMOD_SOUND *sound, + float *frequency, + float *volume, + float *pan, + int *priority); +FMOD_RESULT F_API FMOD_Sound_SetVariations( + FMOD_SOUND *sound, float frequencyvar, float volumevar, float panvar); +FMOD_RESULT F_API FMOD_Sound_GetVariations( + FMOD_SOUND *sound, float *frequencyvar, float *volumevar, float *panvar); +FMOD_RESULT F_API +FMOD_Sound_Set3DMinMaxDistance(FMOD_SOUND *sound, float min, float max); +FMOD_RESULT F_API +FMOD_Sound_Get3DMinMaxDistance(FMOD_SOUND *sound, float *min, float *max); +FMOD_RESULT F_API FMOD_Sound_Set3DConeSettings( + FMOD_SOUND *sound, + float insideconeangle, + float outsideconeangle, + float outsidevolume); +FMOD_RESULT F_API FMOD_Sound_Get3DConeSettings( + FMOD_SOUND *sound, + float *insideconeangle, + float *outsideconeangle, + float *outsidevolume); +FMOD_RESULT F_API FMOD_Sound_Set3DCustomRolloff( + FMOD_SOUND *sound, FMOD_VECTOR *points, int numpoints); +FMOD_RESULT F_API FMOD_Sound_Get3DCustomRolloff( + FMOD_SOUND *sound, FMOD_VECTOR **points, int *numpoints); +FMOD_RESULT F_API +FMOD_Sound_SetSubSound(FMOD_SOUND *sound, int index, FMOD_SOUND *subsound); +FMOD_RESULT F_API +FMOD_Sound_GetSubSound(FMOD_SOUND *sound, int index, FMOD_SOUND **subsound); +FMOD_RESULT F_API +FMOD_Sound_GetSubSoundParent(FMOD_SOUND *sound, FMOD_SOUND **parentsound); +FMOD_RESULT F_API FMOD_Sound_SetSubSoundSentence( + FMOD_SOUND *sound, int *subsoundlist, int numsubsounds); +FMOD_RESULT F_API +FMOD_Sound_GetName(FMOD_SOUND *sound, char *name, int namelen); +FMOD_RESULT F_API FMOD_Sound_GetLength( + FMOD_SOUND *sound, unsigned int *length, FMOD_TIMEUNIT lengthtype); +FMOD_RESULT F_API FMOD_Sound_GetFormat( + FMOD_SOUND *sound, + FMOD_SOUND_TYPE *type, + FMOD_SOUND_FORMAT *format, + int *channels, + int *bits); +FMOD_RESULT F_API +FMOD_Sound_GetNumSubSounds(FMOD_SOUND *sound, int *numsubsounds); +FMOD_RESULT F_API +FMOD_Sound_GetNumTags(FMOD_SOUND *sound, int *numtags, int *numtagsupdated); +FMOD_RESULT F_API FMOD_Sound_GetTag( + FMOD_SOUND *sound, const char *name, int index, FMOD_TAG *tag); +FMOD_RESULT F_API FMOD_Sound_GetOpenState( + FMOD_SOUND *sound, + FMOD_OPENSTATE *openstate, + unsigned int *percentbuffered, + FMOD_BOOL *starving, + FMOD_BOOL *diskbusy); +FMOD_RESULT F_API FMOD_Sound_ReadData( + FMOD_SOUND *sound, void *buffer, unsigned int lenbytes, unsigned int *read); +FMOD_RESULT F_API FMOD_Sound_SeekData(FMOD_SOUND *sound, unsigned int pcm); -FMOD_RESULT F_API FMOD_Sound_SetSoundGroup (FMOD_SOUND *sound, FMOD_SOUNDGROUP *soundgroup); -FMOD_RESULT F_API FMOD_Sound_GetSoundGroup (FMOD_SOUND *sound, FMOD_SOUNDGROUP **soundgroup); +FMOD_RESULT F_API +FMOD_Sound_SetSoundGroup(FMOD_SOUND *sound, FMOD_SOUNDGROUP *soundgroup); +FMOD_RESULT F_API +FMOD_Sound_GetSoundGroup(FMOD_SOUND *sound, FMOD_SOUNDGROUP **soundgroup); /* - Synchronization point API. These points can come from markers embedded in wav files, and can also generate channel callbacks. + Synchronization point API. These points can come from markers embedded in + wav files, and can also generate channel callbacks. */ -FMOD_RESULT F_API FMOD_Sound_GetNumSyncPoints (FMOD_SOUND *sound, int *numsyncpoints); -FMOD_RESULT F_API FMOD_Sound_GetSyncPoint (FMOD_SOUND *sound, int index, FMOD_SYNCPOINT **point); -FMOD_RESULT F_API FMOD_Sound_GetSyncPointInfo (FMOD_SOUND *sound, FMOD_SYNCPOINT *point, char *name, int namelen, unsigned int *offset, FMOD_TIMEUNIT offsettype); -FMOD_RESULT F_API FMOD_Sound_AddSyncPoint (FMOD_SOUND *sound, unsigned int offset, FMOD_TIMEUNIT offsettype, const char *name, FMOD_SYNCPOINT **point); -FMOD_RESULT F_API FMOD_Sound_DeleteSyncPoint (FMOD_SOUND *sound, FMOD_SYNCPOINT *point); +FMOD_RESULT F_API +FMOD_Sound_GetNumSyncPoints(FMOD_SOUND *sound, int *numsyncpoints); +FMOD_RESULT F_API +FMOD_Sound_GetSyncPoint(FMOD_SOUND *sound, int index, FMOD_SYNCPOINT **point); +FMOD_RESULT F_API FMOD_Sound_GetSyncPointInfo( + FMOD_SOUND *sound, + FMOD_SYNCPOINT *point, + char *name, + int namelen, + unsigned int *offset, + FMOD_TIMEUNIT offsettype); +FMOD_RESULT F_API FMOD_Sound_AddSyncPoint( + FMOD_SOUND *sound, + unsigned int offset, + FMOD_TIMEUNIT offsettype, + const char *name, + FMOD_SYNCPOINT **point); +FMOD_RESULT F_API +FMOD_Sound_DeleteSyncPoint(FMOD_SOUND *sound, FMOD_SYNCPOINT *point); /* - Functions also in Channel class but here they are the 'default' to save having to change it in Channel all the time. + Functions also in Channel class but here they are the 'default' to save + having to change it in Channel all the time. */ -FMOD_RESULT F_API FMOD_Sound_SetMode (FMOD_SOUND *sound, FMOD_MODE mode); -FMOD_RESULT F_API FMOD_Sound_GetMode (FMOD_SOUND *sound, FMOD_MODE *mode); -FMOD_RESULT F_API FMOD_Sound_SetLoopCount (FMOD_SOUND *sound, int loopcount); -FMOD_RESULT F_API FMOD_Sound_GetLoopCount (FMOD_SOUND *sound, int *loopcount); -FMOD_RESULT F_API FMOD_Sound_SetLoopPoints (FMOD_SOUND *sound, unsigned int loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int loopend, FMOD_TIMEUNIT loopendtype); -FMOD_RESULT F_API FMOD_Sound_GetLoopPoints (FMOD_SOUND *sound, unsigned int *loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int *loopend, FMOD_TIMEUNIT loopendtype); +FMOD_RESULT F_API FMOD_Sound_SetMode(FMOD_SOUND *sound, FMOD_MODE mode); +FMOD_RESULT F_API FMOD_Sound_GetMode(FMOD_SOUND *sound, FMOD_MODE *mode); +FMOD_RESULT F_API FMOD_Sound_SetLoopCount(FMOD_SOUND *sound, int loopcount); +FMOD_RESULT F_API FMOD_Sound_GetLoopCount(FMOD_SOUND *sound, int *loopcount); +FMOD_RESULT F_API FMOD_Sound_SetLoopPoints( + FMOD_SOUND *sound, + unsigned int loopstart, + FMOD_TIMEUNIT loopstarttype, + unsigned int loopend, + FMOD_TIMEUNIT loopendtype); +FMOD_RESULT F_API FMOD_Sound_GetLoopPoints( + FMOD_SOUND *sound, + unsigned int *loopstart, + FMOD_TIMEUNIT loopstarttype, + unsigned int *loopend, + FMOD_TIMEUNIT loopendtype); /* For MOD/S3M/XM/IT/MID sequenced formats only. */ -FMOD_RESULT F_API FMOD_Sound_GetMusicNumChannels (FMOD_SOUND *sound, int *numchannels); -FMOD_RESULT F_API FMOD_Sound_SetMusicChannelVolume (FMOD_SOUND *sound, int channel, float volume); -FMOD_RESULT F_API FMOD_Sound_GetMusicChannelVolume (FMOD_SOUND *sound, int channel, float *volume); -FMOD_RESULT F_API FMOD_Sound_SetMusicSpeed (FMOD_SOUND *sound, float speed); -FMOD_RESULT F_API FMOD_Sound_GetMusicSpeed (FMOD_SOUND *sound, float *speed); +FMOD_RESULT F_API +FMOD_Sound_GetMusicNumChannels(FMOD_SOUND *sound, int *numchannels); +FMOD_RESULT F_API +FMOD_Sound_SetMusicChannelVolume(FMOD_SOUND *sound, int channel, float volume); +FMOD_RESULT F_API +FMOD_Sound_GetMusicChannelVolume(FMOD_SOUND *sound, int channel, float *volume); +FMOD_RESULT F_API FMOD_Sound_SetMusicSpeed(FMOD_SOUND *sound, float speed); +FMOD_RESULT F_API FMOD_Sound_GetMusicSpeed(FMOD_SOUND *sound, float *speed); /* Userdata set/get. */ -FMOD_RESULT F_API FMOD_Sound_SetUserData (FMOD_SOUND *sound, void *userdata); -FMOD_RESULT F_API FMOD_Sound_GetUserData (FMOD_SOUND *sound, void **userdata); +FMOD_RESULT F_API FMOD_Sound_SetUserData(FMOD_SOUND *sound, void *userdata); +FMOD_RESULT F_API FMOD_Sound_GetUserData(FMOD_SOUND *sound, void **userdata); -FMOD_RESULT F_API FMOD_Sound_GetMemoryInfo (FMOD_SOUND *sound, unsigned int memorybits, unsigned int event_memorybits, unsigned int *memoryused, FMOD_MEMORY_USAGE_DETAILS *memoryused_details); +FMOD_RESULT F_API FMOD_Sound_GetMemoryInfo( + FMOD_SOUND *sound, + unsigned int memorybits, + unsigned int event_memorybits, + unsigned int *memoryused, + FMOD_MEMORY_USAGE_DETAILS *memoryused_details); /* 'Channel' API */ -FMOD_RESULT F_API FMOD_Channel_GetSystemObject (FMOD_CHANNEL *channel, FMOD_SYSTEM **system); +FMOD_RESULT F_API +FMOD_Channel_GetSystemObject(FMOD_CHANNEL *channel, FMOD_SYSTEM **system); -FMOD_RESULT F_API FMOD_Channel_Stop (FMOD_CHANNEL *channel); -FMOD_RESULT F_API FMOD_Channel_SetPaused (FMOD_CHANNEL *channel, FMOD_BOOL paused); -FMOD_RESULT F_API FMOD_Channel_GetPaused (FMOD_CHANNEL *channel, FMOD_BOOL *paused); -FMOD_RESULT F_API FMOD_Channel_SetVolume (FMOD_CHANNEL *channel, float volume); -FMOD_RESULT F_API FMOD_Channel_GetVolume (FMOD_CHANNEL *channel, float *volume); -FMOD_RESULT F_API FMOD_Channel_SetFrequency (FMOD_CHANNEL *channel, float frequency); -FMOD_RESULT F_API FMOD_Channel_GetFrequency (FMOD_CHANNEL *channel, float *frequency); -FMOD_RESULT F_API FMOD_Channel_SetPan (FMOD_CHANNEL *channel, float pan); -FMOD_RESULT F_API FMOD_Channel_GetPan (FMOD_CHANNEL *channel, float *pan); -FMOD_RESULT F_API FMOD_Channel_SetDelay (FMOD_CHANNEL *channel, FMOD_DELAYTYPE delaytype, unsigned int delayhi, unsigned int delaylo); -FMOD_RESULT F_API FMOD_Channel_GetDelay (FMOD_CHANNEL *channel, FMOD_DELAYTYPE delaytype, unsigned int *delayhi, unsigned int *delaylo); -FMOD_RESULT F_API FMOD_Channel_SetSpeakerMix (FMOD_CHANNEL *channel, float frontleft, float frontright, float center, float lfe, float backleft, float backright, float sideleft, float sideright); -FMOD_RESULT F_API FMOD_Channel_GetSpeakerMix (FMOD_CHANNEL *channel, float *frontleft, float *frontright, float *center, float *lfe, float *backleft, float *backright, float *sideleft, float *sideright); -FMOD_RESULT F_API FMOD_Channel_SetSpeakerLevels (FMOD_CHANNEL *channel, FMOD_SPEAKER speaker, float *levels, int numlevels); -FMOD_RESULT F_API FMOD_Channel_GetSpeakerLevels (FMOD_CHANNEL *channel, FMOD_SPEAKER speaker, float *levels, int numlevels); -FMOD_RESULT F_API FMOD_Channel_SetInputChannelMix (FMOD_CHANNEL *channel, float *levels, int numlevels); -FMOD_RESULT F_API FMOD_Channel_GetInputChannelMix (FMOD_CHANNEL *channel, float *levels, int numlevels); -FMOD_RESULT F_API FMOD_Channel_SetMute (FMOD_CHANNEL *channel, FMOD_BOOL mute); -FMOD_RESULT F_API FMOD_Channel_GetMute (FMOD_CHANNEL *channel, FMOD_BOOL *mute); -FMOD_RESULT F_API FMOD_Channel_SetPriority (FMOD_CHANNEL *channel, int priority); -FMOD_RESULT F_API FMOD_Channel_GetPriority (FMOD_CHANNEL *channel, int *priority); -FMOD_RESULT F_API FMOD_Channel_SetPosition (FMOD_CHANNEL *channel, unsigned int position, FMOD_TIMEUNIT postype); -FMOD_RESULT F_API FMOD_Channel_GetPosition (FMOD_CHANNEL *channel, unsigned int *position, FMOD_TIMEUNIT postype); -FMOD_RESULT F_API FMOD_Channel_SetReverbProperties (FMOD_CHANNEL *channel, const FMOD_REVERB_CHANNELPROPERTIES *prop); -FMOD_RESULT F_API FMOD_Channel_GetReverbProperties (FMOD_CHANNEL *channel, FMOD_REVERB_CHANNELPROPERTIES *prop); -FMOD_RESULT F_API FMOD_Channel_SetLowPassGain (FMOD_CHANNEL *channel, float gain); -FMOD_RESULT F_API FMOD_Channel_GetLowPassGain (FMOD_CHANNEL *channel, float *gain); +FMOD_RESULT F_API FMOD_Channel_Stop(FMOD_CHANNEL *channel); +FMOD_RESULT F_API +FMOD_Channel_SetPaused(FMOD_CHANNEL *channel, FMOD_BOOL paused); +FMOD_RESULT F_API +FMOD_Channel_GetPaused(FMOD_CHANNEL *channel, FMOD_BOOL *paused); +FMOD_RESULT F_API FMOD_Channel_SetVolume(FMOD_CHANNEL *channel, float volume); +FMOD_RESULT F_API FMOD_Channel_GetVolume(FMOD_CHANNEL *channel, float *volume); +FMOD_RESULT F_API +FMOD_Channel_SetFrequency(FMOD_CHANNEL *channel, float frequency); +FMOD_RESULT F_API +FMOD_Channel_GetFrequency(FMOD_CHANNEL *channel, float *frequency); +FMOD_RESULT F_API FMOD_Channel_SetPan(FMOD_CHANNEL *channel, float pan); +FMOD_RESULT F_API FMOD_Channel_GetPan(FMOD_CHANNEL *channel, float *pan); +FMOD_RESULT F_API FMOD_Channel_SetDelay( + FMOD_CHANNEL *channel, + FMOD_DELAYTYPE delaytype, + unsigned int delayhi, + unsigned int delaylo); +FMOD_RESULT F_API FMOD_Channel_GetDelay( + FMOD_CHANNEL *channel, + FMOD_DELAYTYPE delaytype, + unsigned int *delayhi, + unsigned int *delaylo); +FMOD_RESULT F_API FMOD_Channel_SetSpeakerMix( + FMOD_CHANNEL *channel, + float frontleft, + float frontright, + float center, + float lfe, + float backleft, + float backright, + float sideleft, + float sideright); +FMOD_RESULT F_API FMOD_Channel_GetSpeakerMix( + FMOD_CHANNEL *channel, + float *frontleft, + float *frontright, + float *center, + float *lfe, + float *backleft, + float *backright, + float *sideleft, + float *sideright); +FMOD_RESULT F_API FMOD_Channel_SetSpeakerLevels( + FMOD_CHANNEL *channel, FMOD_SPEAKER speaker, float *levels, int numlevels); +FMOD_RESULT F_API FMOD_Channel_GetSpeakerLevels( + FMOD_CHANNEL *channel, FMOD_SPEAKER speaker, float *levels, int numlevels); +FMOD_RESULT F_API FMOD_Channel_SetInputChannelMix( + FMOD_CHANNEL *channel, float *levels, int numlevels); +FMOD_RESULT F_API FMOD_Channel_GetInputChannelMix( + FMOD_CHANNEL *channel, float *levels, int numlevels); +FMOD_RESULT F_API FMOD_Channel_SetMute(FMOD_CHANNEL *channel, FMOD_BOOL mute); +FMOD_RESULT F_API FMOD_Channel_GetMute(FMOD_CHANNEL *channel, FMOD_BOOL *mute); +FMOD_RESULT F_API FMOD_Channel_SetPriority(FMOD_CHANNEL *channel, int priority); +FMOD_RESULT F_API +FMOD_Channel_GetPriority(FMOD_CHANNEL *channel, int *priority); +FMOD_RESULT F_API FMOD_Channel_SetPosition( + FMOD_CHANNEL *channel, unsigned int position, FMOD_TIMEUNIT postype); +FMOD_RESULT F_API FMOD_Channel_GetPosition( + FMOD_CHANNEL *channel, unsigned int *position, FMOD_TIMEUNIT postype); +FMOD_RESULT F_API FMOD_Channel_SetReverbProperties( + FMOD_CHANNEL *channel, const FMOD_REVERB_CHANNELPROPERTIES *prop); +FMOD_RESULT F_API FMOD_Channel_GetReverbProperties( + FMOD_CHANNEL *channel, FMOD_REVERB_CHANNELPROPERTIES *prop); +FMOD_RESULT F_API +FMOD_Channel_SetLowPassGain(FMOD_CHANNEL *channel, float gain); +FMOD_RESULT F_API +FMOD_Channel_GetLowPassGain(FMOD_CHANNEL *channel, float *gain); -FMOD_RESULT F_API FMOD_Channel_SetChannelGroup (FMOD_CHANNEL *channel, FMOD_CHANNELGROUP *channelgroup); -FMOD_RESULT F_API FMOD_Channel_GetChannelGroup (FMOD_CHANNEL *channel, FMOD_CHANNELGROUP **channelgroup); -FMOD_RESULT F_API FMOD_Channel_SetCallback (FMOD_CHANNEL *channel, FMOD_CHANNEL_CALLBACK callback); +FMOD_RESULT F_API FMOD_Channel_SetChannelGroup( + FMOD_CHANNEL *channel, FMOD_CHANNELGROUP *channelgroup); +FMOD_RESULT F_API FMOD_Channel_GetChannelGroup( + FMOD_CHANNEL *channel, FMOD_CHANNELGROUP **channelgroup); +FMOD_RESULT F_API +FMOD_Channel_SetCallback(FMOD_CHANNEL *channel, FMOD_CHANNEL_CALLBACK callback); /* 3D functionality. */ -FMOD_RESULT F_API FMOD_Channel_Set3DAttributes (FMOD_CHANNEL *channel, const FMOD_VECTOR *pos, const FMOD_VECTOR *vel); -FMOD_RESULT F_API FMOD_Channel_Get3DAttributes (FMOD_CHANNEL *channel, FMOD_VECTOR *pos, FMOD_VECTOR *vel); -FMOD_RESULT F_API FMOD_Channel_Set3DMinMaxDistance (FMOD_CHANNEL *channel, float mindistance, float maxdistance); -FMOD_RESULT F_API FMOD_Channel_Get3DMinMaxDistance (FMOD_CHANNEL *channel, float *mindistance, float *maxdistance); -FMOD_RESULT F_API FMOD_Channel_Set3DConeSettings (FMOD_CHANNEL *channel, float insideconeangle, float outsideconeangle, float outsidevolume); -FMOD_RESULT F_API FMOD_Channel_Get3DConeSettings (FMOD_CHANNEL *channel, float *insideconeangle, float *outsideconeangle, float *outsidevolume); -FMOD_RESULT F_API FMOD_Channel_Set3DConeOrientation (FMOD_CHANNEL *channel, FMOD_VECTOR *orientation); -FMOD_RESULT F_API FMOD_Channel_Get3DConeOrientation (FMOD_CHANNEL *channel, FMOD_VECTOR *orientation); -FMOD_RESULT F_API FMOD_Channel_Set3DCustomRolloff (FMOD_CHANNEL *channel, FMOD_VECTOR *points, int numpoints); -FMOD_RESULT F_API FMOD_Channel_Get3DCustomRolloff (FMOD_CHANNEL *channel, FMOD_VECTOR **points, int *numpoints); -FMOD_RESULT F_API FMOD_Channel_Set3DOcclusion (FMOD_CHANNEL *channel, float directocclusion, float reverbocclusion); -FMOD_RESULT F_API FMOD_Channel_Get3DOcclusion (FMOD_CHANNEL *channel, float *directocclusion, float *reverbocclusion); -FMOD_RESULT F_API FMOD_Channel_Set3DSpread (FMOD_CHANNEL *channel, float angle); -FMOD_RESULT F_API FMOD_Channel_Get3DSpread (FMOD_CHANNEL *channel, float *angle); -FMOD_RESULT F_API FMOD_Channel_Set3DPanLevel (FMOD_CHANNEL *channel, float level); -FMOD_RESULT F_API FMOD_Channel_Get3DPanLevel (FMOD_CHANNEL *channel, float *level); -FMOD_RESULT F_API FMOD_Channel_Set3DDopplerLevel (FMOD_CHANNEL *channel, float level); -FMOD_RESULT F_API FMOD_Channel_Get3DDopplerLevel (FMOD_CHANNEL *channel, float *level); -FMOD_RESULT F_API FMOD_Channel_Set3DDistanceFilter (FMOD_CHANNEL *channel, FMOD_BOOL custom, float customLevel, float centerFreq); -FMOD_RESULT F_API FMOD_Channel_Get3DDistanceFilter (FMOD_CHANNEL *channel, FMOD_BOOL *custom, float *customLevel, float *centerFreq); +FMOD_RESULT F_API FMOD_Channel_Set3DAttributes( + FMOD_CHANNEL *channel, const FMOD_VECTOR *pos, const FMOD_VECTOR *vel); +FMOD_RESULT F_API FMOD_Channel_Get3DAttributes( + FMOD_CHANNEL *channel, FMOD_VECTOR *pos, FMOD_VECTOR *vel); +FMOD_RESULT F_API FMOD_Channel_Set3DMinMaxDistance( + FMOD_CHANNEL *channel, float mindistance, float maxdistance); +FMOD_RESULT F_API FMOD_Channel_Get3DMinMaxDistance( + FMOD_CHANNEL *channel, float *mindistance, float *maxdistance); +FMOD_RESULT F_API FMOD_Channel_Set3DConeSettings( + FMOD_CHANNEL *channel, + float insideconeangle, + float outsideconeangle, + float outsidevolume); +FMOD_RESULT F_API FMOD_Channel_Get3DConeSettings( + FMOD_CHANNEL *channel, + float *insideconeangle, + float *outsideconeangle, + float *outsidevolume); +FMOD_RESULT F_API FMOD_Channel_Set3DConeOrientation( + FMOD_CHANNEL *channel, FMOD_VECTOR *orientation); +FMOD_RESULT F_API FMOD_Channel_Get3DConeOrientation( + FMOD_CHANNEL *channel, FMOD_VECTOR *orientation); +FMOD_RESULT F_API FMOD_Channel_Set3DCustomRolloff( + FMOD_CHANNEL *channel, FMOD_VECTOR *points, int numpoints); +FMOD_RESULT F_API FMOD_Channel_Get3DCustomRolloff( + FMOD_CHANNEL *channel, FMOD_VECTOR **points, int *numpoints); +FMOD_RESULT F_API FMOD_Channel_Set3DOcclusion( + FMOD_CHANNEL *channel, float directocclusion, float reverbocclusion); +FMOD_RESULT F_API FMOD_Channel_Get3DOcclusion( + FMOD_CHANNEL *channel, float *directocclusion, float *reverbocclusion); +FMOD_RESULT F_API FMOD_Channel_Set3DSpread(FMOD_CHANNEL *channel, float angle); +FMOD_RESULT F_API FMOD_Channel_Get3DSpread(FMOD_CHANNEL *channel, float *angle); +FMOD_RESULT F_API +FMOD_Channel_Set3DPanLevel(FMOD_CHANNEL *channel, float level); +FMOD_RESULT F_API +FMOD_Channel_Get3DPanLevel(FMOD_CHANNEL *channel, float *level); +FMOD_RESULT F_API +FMOD_Channel_Set3DDopplerLevel(FMOD_CHANNEL *channel, float level); +FMOD_RESULT F_API +FMOD_Channel_Get3DDopplerLevel(FMOD_CHANNEL *channel, float *level); +FMOD_RESULT F_API FMOD_Channel_Set3DDistanceFilter( + FMOD_CHANNEL *channel, + FMOD_BOOL custom, + float customLevel, + float centerFreq); +FMOD_RESULT F_API FMOD_Channel_Get3DDistanceFilter( + FMOD_CHANNEL *channel, + FMOD_BOOL *custom, + float *customLevel, + float *centerFreq); /* - DSP functionality only for channels playing sounds created with FMOD_SOFTWARE. + DSP functionality only for channels playing sounds created with + FMOD_SOFTWARE. */ -FMOD_RESULT F_API FMOD_Channel_GetDSPHead (FMOD_CHANNEL *channel, FMOD_DSP **dsp); -FMOD_RESULT F_API FMOD_Channel_AddDSP (FMOD_CHANNEL *channel, FMOD_DSP *dsp, FMOD_DSPCONNECTION **connection); +FMOD_RESULT F_API +FMOD_Channel_GetDSPHead(FMOD_CHANNEL *channel, FMOD_DSP **dsp); +FMOD_RESULT F_API FMOD_Channel_AddDSP( + FMOD_CHANNEL *channel, FMOD_DSP *dsp, FMOD_DSPCONNECTION **connection); /* Information only functions. */ -FMOD_RESULT F_API FMOD_Channel_IsPlaying (FMOD_CHANNEL *channel, FMOD_BOOL *isplaying); -FMOD_RESULT F_API FMOD_Channel_IsVirtual (FMOD_CHANNEL *channel, FMOD_BOOL *isvirtual); -FMOD_RESULT F_API FMOD_Channel_GetAudibility (FMOD_CHANNEL *channel, float *audibility); -FMOD_RESULT F_API FMOD_Channel_GetCurrentSound (FMOD_CHANNEL *channel, FMOD_SOUND **sound); -FMOD_RESULT F_API FMOD_Channel_GetSpectrum (FMOD_CHANNEL *channel, float *spectrumarray, int numvalues, int channeloffset, FMOD_DSP_FFT_WINDOW windowtype); -FMOD_RESULT F_API FMOD_Channel_GetWaveData (FMOD_CHANNEL *channel, float *wavearray, int numvalues, int channeloffset); -FMOD_RESULT F_API FMOD_Channel_GetIndex (FMOD_CHANNEL *channel, int *index); +FMOD_RESULT F_API +FMOD_Channel_IsPlaying(FMOD_CHANNEL *channel, FMOD_BOOL *isplaying); +FMOD_RESULT F_API +FMOD_Channel_IsVirtual(FMOD_CHANNEL *channel, FMOD_BOOL *isvirtual); +FMOD_RESULT F_API +FMOD_Channel_GetAudibility(FMOD_CHANNEL *channel, float *audibility); +FMOD_RESULT F_API +FMOD_Channel_GetCurrentSound(FMOD_CHANNEL *channel, FMOD_SOUND **sound); +FMOD_RESULT F_API FMOD_Channel_GetSpectrum( + FMOD_CHANNEL *channel, + float *spectrumarray, + int numvalues, + int channeloffset, + FMOD_DSP_FFT_WINDOW windowtype); +FMOD_RESULT F_API FMOD_Channel_GetWaveData( + FMOD_CHANNEL *channel, float *wavearray, int numvalues, int channeloffset); +FMOD_RESULT F_API FMOD_Channel_GetIndex(FMOD_CHANNEL *channel, int *index); /* Functions also found in Sound class but here they can be set per channel. */ -FMOD_RESULT F_API FMOD_Channel_SetMode (FMOD_CHANNEL *channel, FMOD_MODE mode); -FMOD_RESULT F_API FMOD_Channel_GetMode (FMOD_CHANNEL *channel, FMOD_MODE *mode); -FMOD_RESULT F_API FMOD_Channel_SetLoopCount (FMOD_CHANNEL *channel, int loopcount); -FMOD_RESULT F_API FMOD_Channel_GetLoopCount (FMOD_CHANNEL *channel, int *loopcount); -FMOD_RESULT F_API FMOD_Channel_SetLoopPoints (FMOD_CHANNEL *channel, unsigned int loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int loopend, FMOD_TIMEUNIT loopendtype); -FMOD_RESULT F_API FMOD_Channel_GetLoopPoints (FMOD_CHANNEL *channel, unsigned int *loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int *loopend, FMOD_TIMEUNIT loopendtype); +FMOD_RESULT F_API FMOD_Channel_SetMode(FMOD_CHANNEL *channel, FMOD_MODE mode); +FMOD_RESULT F_API FMOD_Channel_GetMode(FMOD_CHANNEL *channel, FMOD_MODE *mode); +FMOD_RESULT F_API +FMOD_Channel_SetLoopCount(FMOD_CHANNEL *channel, int loopcount); +FMOD_RESULT F_API +FMOD_Channel_GetLoopCount(FMOD_CHANNEL *channel, int *loopcount); +FMOD_RESULT F_API FMOD_Channel_SetLoopPoints( + FMOD_CHANNEL *channel, + unsigned int loopstart, + FMOD_TIMEUNIT loopstarttype, + unsigned int loopend, + FMOD_TIMEUNIT loopendtype); +FMOD_RESULT F_API FMOD_Channel_GetLoopPoints( + FMOD_CHANNEL *channel, + unsigned int *loopstart, + FMOD_TIMEUNIT loopstarttype, + unsigned int *loopend, + FMOD_TIMEUNIT loopendtype); /* - Userdata set/get. + Userdata set/get. */ -FMOD_RESULT F_API FMOD_Channel_SetUserData (FMOD_CHANNEL *channel, void *userdata); -FMOD_RESULT F_API FMOD_Channel_GetUserData (FMOD_CHANNEL *channel, void **userdata); +FMOD_RESULT F_API +FMOD_Channel_SetUserData(FMOD_CHANNEL *channel, void *userdata); +FMOD_RESULT F_API +FMOD_Channel_GetUserData(FMOD_CHANNEL *channel, void **userdata); -FMOD_RESULT F_API FMOD_Channel_GetMemoryInfo (FMOD_CHANNEL *channel, unsigned int memorybits, unsigned int event_memorybits, unsigned int *memoryused, FMOD_MEMORY_USAGE_DETAILS *memoryused_details); +FMOD_RESULT F_API FMOD_Channel_GetMemoryInfo( + FMOD_CHANNEL *channel, + unsigned int memorybits, + unsigned int event_memorybits, + unsigned int *memoryused, + FMOD_MEMORY_USAGE_DETAILS *memoryused_details); /* 'ChannelGroup' API */ -FMOD_RESULT F_API FMOD_ChannelGroup_Release (FMOD_CHANNELGROUP *channelgroup); -FMOD_RESULT F_API FMOD_ChannelGroup_GetSystemObject (FMOD_CHANNELGROUP *channelgroup, FMOD_SYSTEM **system); +FMOD_RESULT F_API FMOD_ChannelGroup_Release(FMOD_CHANNELGROUP *channelgroup); +FMOD_RESULT F_API FMOD_ChannelGroup_GetSystemObject( + FMOD_CHANNELGROUP *channelgroup, FMOD_SYSTEM **system); /* - Channelgroup scale values. (changes attributes relative to the channels, doesn't overwrite them) + Channelgroup scale values. (changes attributes relative to the channels, + doesn't overwrite them) */ -FMOD_RESULT F_API FMOD_ChannelGroup_SetVolume (FMOD_CHANNELGROUP *channelgroup, float volume); -FMOD_RESULT F_API FMOD_ChannelGroup_GetVolume (FMOD_CHANNELGROUP *channelgroup, float *volume); -FMOD_RESULT F_API FMOD_ChannelGroup_SetPitch (FMOD_CHANNELGROUP *channelgroup, float pitch); -FMOD_RESULT F_API FMOD_ChannelGroup_GetPitch (FMOD_CHANNELGROUP *channelgroup, float *pitch); -FMOD_RESULT F_API FMOD_ChannelGroup_Set3DOcclusion (FMOD_CHANNELGROUP *channelgroup, float directocclusion, float reverbocclusion); -FMOD_RESULT F_API FMOD_ChannelGroup_Get3DOcclusion (FMOD_CHANNELGROUP *channelgroup, float *directocclusion, float *reverbocclusion); -FMOD_RESULT F_API FMOD_ChannelGroup_SetPaused (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL paused); -FMOD_RESULT F_API FMOD_ChannelGroup_GetPaused (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL *paused); -FMOD_RESULT F_API FMOD_ChannelGroup_SetMute (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL mute); -FMOD_RESULT F_API FMOD_ChannelGroup_GetMute (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL *mute); +FMOD_RESULT F_API +FMOD_ChannelGroup_SetVolume(FMOD_CHANNELGROUP *channelgroup, float volume); +FMOD_RESULT F_API +FMOD_ChannelGroup_GetVolume(FMOD_CHANNELGROUP *channelgroup, float *volume); +FMOD_RESULT F_API +FMOD_ChannelGroup_SetPitch(FMOD_CHANNELGROUP *channelgroup, float pitch); +FMOD_RESULT F_API +FMOD_ChannelGroup_GetPitch(FMOD_CHANNELGROUP *channelgroup, float *pitch); +FMOD_RESULT F_API FMOD_ChannelGroup_Set3DOcclusion( + FMOD_CHANNELGROUP *channelgroup, + float directocclusion, + float reverbocclusion); +FMOD_RESULT F_API FMOD_ChannelGroup_Get3DOcclusion( + FMOD_CHANNELGROUP *channelgroup, + float *directocclusion, + float *reverbocclusion); +FMOD_RESULT F_API +FMOD_ChannelGroup_SetPaused(FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL paused); +FMOD_RESULT F_API +FMOD_ChannelGroup_GetPaused(FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL *paused); +FMOD_RESULT F_API +FMOD_ChannelGroup_SetMute(FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL mute); +FMOD_RESULT F_API +FMOD_ChannelGroup_GetMute(FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL *mute); /* - Channelgroup override values. (recursively overwrites whatever settings the channels had) + Channelgroup override values. (recursively overwrites whatever settings + the channels had) */ -FMOD_RESULT F_API FMOD_ChannelGroup_Stop (FMOD_CHANNELGROUP *channelgroup); -FMOD_RESULT F_API FMOD_ChannelGroup_OverrideVolume (FMOD_CHANNELGROUP *channelgroup, float volume); -FMOD_RESULT F_API FMOD_ChannelGroup_OverrideFrequency(FMOD_CHANNELGROUP *channelgroup, float frequency); -FMOD_RESULT F_API FMOD_ChannelGroup_OverridePan (FMOD_CHANNELGROUP *channelgroup, float pan); -FMOD_RESULT F_API FMOD_ChannelGroup_OverrideReverbProperties(FMOD_CHANNELGROUP *channelgroup, const FMOD_REVERB_CHANNELPROPERTIES *prop); -FMOD_RESULT F_API FMOD_ChannelGroup_Override3DAttributes(FMOD_CHANNELGROUP *channelgroup, const FMOD_VECTOR *pos, const FMOD_VECTOR *vel); -FMOD_RESULT F_API FMOD_ChannelGroup_OverrideSpeakerMix(FMOD_CHANNELGROUP *channelgroup, float frontleft, float frontright, float center, float lfe, float backleft, float backright, float sideleft, float sideright); +FMOD_RESULT F_API FMOD_ChannelGroup_Stop(FMOD_CHANNELGROUP *channelgroup); +FMOD_RESULT F_API +FMOD_ChannelGroup_OverrideVolume(FMOD_CHANNELGROUP *channelgroup, float volume); +FMOD_RESULT F_API FMOD_ChannelGroup_OverrideFrequency( + FMOD_CHANNELGROUP *channelgroup, float frequency); +FMOD_RESULT F_API +FMOD_ChannelGroup_OverridePan(FMOD_CHANNELGROUP *channelgroup, float pan); +FMOD_RESULT F_API FMOD_ChannelGroup_OverrideReverbProperties( + FMOD_CHANNELGROUP *channelgroup, const FMOD_REVERB_CHANNELPROPERTIES *prop); +FMOD_RESULT F_API FMOD_ChannelGroup_Override3DAttributes( + FMOD_CHANNELGROUP *channelgroup, + const FMOD_VECTOR *pos, + const FMOD_VECTOR *vel); +FMOD_RESULT F_API FMOD_ChannelGroup_OverrideSpeakerMix( + FMOD_CHANNELGROUP *channelgroup, + float frontleft, + float frontright, + float center, + float lfe, + float backleft, + float backright, + float sideleft, + float sideright); /* Nested channel groups. */ -FMOD_RESULT F_API FMOD_ChannelGroup_AddGroup (FMOD_CHANNELGROUP *channelgroup, FMOD_CHANNELGROUP *group); -FMOD_RESULT F_API FMOD_ChannelGroup_GetNumGroups (FMOD_CHANNELGROUP *channelgroup, int *numgroups); -FMOD_RESULT F_API FMOD_ChannelGroup_GetGroup (FMOD_CHANNELGROUP *channelgroup, int index, FMOD_CHANNELGROUP **group); -FMOD_RESULT F_API FMOD_ChannelGroup_GetParentGroup (FMOD_CHANNELGROUP *channelgroup, FMOD_CHANNELGROUP **group); +FMOD_RESULT F_API FMOD_ChannelGroup_AddGroup( + FMOD_CHANNELGROUP *channelgroup, FMOD_CHANNELGROUP *group); +FMOD_RESULT F_API +FMOD_ChannelGroup_GetNumGroups(FMOD_CHANNELGROUP *channelgroup, int *numgroups); +FMOD_RESULT F_API FMOD_ChannelGroup_GetGroup( + FMOD_CHANNELGROUP *channelgroup, int index, FMOD_CHANNELGROUP **group); +FMOD_RESULT F_API FMOD_ChannelGroup_GetParentGroup( + FMOD_CHANNELGROUP *channelgroup, FMOD_CHANNELGROUP **group); /* - DSP functionality only for channel groups playing sounds created with FMOD_SOFTWARE. + DSP functionality only for channel groups playing sounds created with + FMOD_SOFTWARE. */ -FMOD_RESULT F_API FMOD_ChannelGroup_GetDSPHead (FMOD_CHANNELGROUP *channelgroup, FMOD_DSP **dsp); -FMOD_RESULT F_API FMOD_ChannelGroup_AddDSP (FMOD_CHANNELGROUP *channelgroup, FMOD_DSP *dsp, FMOD_DSPCONNECTION **connection); +FMOD_RESULT F_API +FMOD_ChannelGroup_GetDSPHead(FMOD_CHANNELGROUP *channelgroup, FMOD_DSP **dsp); +FMOD_RESULT F_API FMOD_ChannelGroup_AddDSP( + FMOD_CHANNELGROUP *channelgroup, + FMOD_DSP *dsp, + FMOD_DSPCONNECTION **connection); /* Information only functions. */ -FMOD_RESULT F_API FMOD_ChannelGroup_GetName (FMOD_CHANNELGROUP *channelgroup, char *name, int namelen); -FMOD_RESULT F_API FMOD_ChannelGroup_GetNumChannels (FMOD_CHANNELGROUP *channelgroup, int *numchannels); -FMOD_RESULT F_API FMOD_ChannelGroup_GetChannel (FMOD_CHANNELGROUP *channelgroup, int index, FMOD_CHANNEL **channel); -FMOD_RESULT F_API FMOD_ChannelGroup_GetSpectrum (FMOD_CHANNELGROUP *channelgroup, float *spectrumarray, int numvalues, int channeloffset, FMOD_DSP_FFT_WINDOW windowtype); -FMOD_RESULT F_API FMOD_ChannelGroup_GetWaveData (FMOD_CHANNELGROUP *channelgroup, float *wavearray, int numvalues, int channeloffset); +FMOD_RESULT F_API FMOD_ChannelGroup_GetName( + FMOD_CHANNELGROUP *channelgroup, char *name, int namelen); +FMOD_RESULT F_API FMOD_ChannelGroup_GetNumChannels( + FMOD_CHANNELGROUP *channelgroup, int *numchannels); +FMOD_RESULT F_API FMOD_ChannelGroup_GetChannel( + FMOD_CHANNELGROUP *channelgroup, int index, FMOD_CHANNEL **channel); +FMOD_RESULT F_API FMOD_ChannelGroup_GetSpectrum( + FMOD_CHANNELGROUP *channelgroup, + float *spectrumarray, + int numvalues, + int channeloffset, + FMOD_DSP_FFT_WINDOW windowtype); +FMOD_RESULT F_API FMOD_ChannelGroup_GetWaveData( + FMOD_CHANNELGROUP *channelgroup, + float *wavearray, + int numvalues, + int channeloffset); /* Userdata set/get. */ -FMOD_RESULT F_API FMOD_ChannelGroup_SetUserData (FMOD_CHANNELGROUP *channelgroup, void *userdata); -FMOD_RESULT F_API FMOD_ChannelGroup_GetUserData (FMOD_CHANNELGROUP *channelgroup, void **userdata); +FMOD_RESULT F_API +FMOD_ChannelGroup_SetUserData(FMOD_CHANNELGROUP *channelgroup, void *userdata); +FMOD_RESULT F_API +FMOD_ChannelGroup_GetUserData(FMOD_CHANNELGROUP *channelgroup, void **userdata); -FMOD_RESULT F_API FMOD_ChannelGroup_GetMemoryInfo (FMOD_CHANNELGROUP *channelgroup, unsigned int memorybits, unsigned int event_memorybits, unsigned int *memoryused, FMOD_MEMORY_USAGE_DETAILS *memoryused_details); +FMOD_RESULT F_API FMOD_ChannelGroup_GetMemoryInfo( + FMOD_CHANNELGROUP *channelgroup, + unsigned int memorybits, + unsigned int event_memorybits, + unsigned int *memoryused, + FMOD_MEMORY_USAGE_DETAILS *memoryused_details); /* 'SoundGroup' API */ -FMOD_RESULT F_API FMOD_SoundGroup_Release (FMOD_SOUNDGROUP *soundgroup); -FMOD_RESULT F_API FMOD_SoundGroup_GetSystemObject (FMOD_SOUNDGROUP *soundgroup, FMOD_SYSTEM **system); +FMOD_RESULT F_API FMOD_SoundGroup_Release(FMOD_SOUNDGROUP *soundgroup); +FMOD_RESULT F_API FMOD_SoundGroup_GetSystemObject( + FMOD_SOUNDGROUP *soundgroup, FMOD_SYSTEM **system); /* SoundGroup control functions. */ -FMOD_RESULT F_API FMOD_SoundGroup_SetMaxAudible (FMOD_SOUNDGROUP *soundgroup, int maxaudible); -FMOD_RESULT F_API FMOD_SoundGroup_GetMaxAudible (FMOD_SOUNDGROUP *soundgroup, int *maxaudible); -FMOD_RESULT F_API FMOD_SoundGroup_SetMaxAudibleBehavior(FMOD_SOUNDGROUP *soundgroup, FMOD_SOUNDGROUP_BEHAVIOR behavior); -FMOD_RESULT F_API FMOD_SoundGroup_GetMaxAudibleBehavior(FMOD_SOUNDGROUP *soundgroup, FMOD_SOUNDGROUP_BEHAVIOR *behavior); -FMOD_RESULT F_API FMOD_SoundGroup_SetMuteFadeSpeed (FMOD_SOUNDGROUP *soundgroup, float speed); -FMOD_RESULT F_API FMOD_SoundGroup_GetMuteFadeSpeed (FMOD_SOUNDGROUP *soundgroup, float *speed); -FMOD_RESULT F_API FMOD_SoundGroup_SetVolume (FMOD_SOUNDGROUP *soundgroup, float volume); -FMOD_RESULT F_API FMOD_SoundGroup_GetVolume (FMOD_SOUNDGROUP *soundgroup, float *volume); -FMOD_RESULT F_API FMOD_SoundGroup_Stop (FMOD_SOUNDGROUP *soundgroup); +FMOD_RESULT F_API +FMOD_SoundGroup_SetMaxAudible(FMOD_SOUNDGROUP *soundgroup, int maxaudible); +FMOD_RESULT F_API +FMOD_SoundGroup_GetMaxAudible(FMOD_SOUNDGROUP *soundgroup, int *maxaudible); +FMOD_RESULT F_API FMOD_SoundGroup_SetMaxAudibleBehavior( + FMOD_SOUNDGROUP *soundgroup, FMOD_SOUNDGROUP_BEHAVIOR behavior); +FMOD_RESULT F_API FMOD_SoundGroup_GetMaxAudibleBehavior( + FMOD_SOUNDGROUP *soundgroup, FMOD_SOUNDGROUP_BEHAVIOR *behavior); +FMOD_RESULT F_API +FMOD_SoundGroup_SetMuteFadeSpeed(FMOD_SOUNDGROUP *soundgroup, float speed); +FMOD_RESULT F_API +FMOD_SoundGroup_GetMuteFadeSpeed(FMOD_SOUNDGROUP *soundgroup, float *speed); +FMOD_RESULT F_API +FMOD_SoundGroup_SetVolume(FMOD_SOUNDGROUP *soundgroup, float volume); +FMOD_RESULT F_API +FMOD_SoundGroup_GetVolume(FMOD_SOUNDGROUP *soundgroup, float *volume); +FMOD_RESULT F_API FMOD_SoundGroup_Stop(FMOD_SOUNDGROUP *soundgroup); /* Information only functions. */ -FMOD_RESULT F_API FMOD_SoundGroup_GetName (FMOD_SOUNDGROUP *soundgroup, char *name, int namelen); -FMOD_RESULT F_API FMOD_SoundGroup_GetNumSounds (FMOD_SOUNDGROUP *soundgroup, int *numsounds); -FMOD_RESULT F_API FMOD_SoundGroup_GetSound (FMOD_SOUNDGROUP *soundgroup, int index, FMOD_SOUND **sound); -FMOD_RESULT F_API FMOD_SoundGroup_GetNumPlaying (FMOD_SOUNDGROUP *soundgroup, int *numplaying); +FMOD_RESULT F_API +FMOD_SoundGroup_GetName(FMOD_SOUNDGROUP *soundgroup, char *name, int namelen); +FMOD_RESULT F_API +FMOD_SoundGroup_GetNumSounds(FMOD_SOUNDGROUP *soundgroup, int *numsounds); +FMOD_RESULT F_API FMOD_SoundGroup_GetSound( + FMOD_SOUNDGROUP *soundgroup, int index, FMOD_SOUND **sound); +FMOD_RESULT F_API +FMOD_SoundGroup_GetNumPlaying(FMOD_SOUNDGROUP *soundgroup, int *numplaying); /* Userdata set/get. */ -FMOD_RESULT F_API FMOD_SoundGroup_SetUserData (FMOD_SOUNDGROUP *soundgroup, void *userdata); -FMOD_RESULT F_API FMOD_SoundGroup_GetUserData (FMOD_SOUNDGROUP *soundgroup, void **userdata); +FMOD_RESULT F_API +FMOD_SoundGroup_SetUserData(FMOD_SOUNDGROUP *soundgroup, void *userdata); +FMOD_RESULT F_API +FMOD_SoundGroup_GetUserData(FMOD_SOUNDGROUP *soundgroup, void **userdata); -FMOD_RESULT F_API FMOD_SoundGroup_GetMemoryInfo (FMOD_SOUNDGROUP *soundgroup, unsigned int memorybits, unsigned int event_memorybits, unsigned int *memoryused, FMOD_MEMORY_USAGE_DETAILS *memoryused_details); +FMOD_RESULT F_API FMOD_SoundGroup_GetMemoryInfo( + FMOD_SOUNDGROUP *soundgroup, + unsigned int memorybits, + unsigned int event_memorybits, + unsigned int *memoryused, + FMOD_MEMORY_USAGE_DETAILS *memoryused_details); /* 'DSP' API */ -FMOD_RESULT F_API FMOD_DSP_Release (FMOD_DSP *dsp); -FMOD_RESULT F_API FMOD_DSP_GetSystemObject (FMOD_DSP *dsp, FMOD_SYSTEM **system); +FMOD_RESULT F_API FMOD_DSP_Release(FMOD_DSP *dsp); +FMOD_RESULT F_API FMOD_DSP_GetSystemObject(FMOD_DSP *dsp, FMOD_SYSTEM **system); /* Connection / disconnection / input and output enumeration. */ -FMOD_RESULT F_API FMOD_DSP_AddInput (FMOD_DSP *dsp, FMOD_DSP *target, FMOD_DSPCONNECTION **connection); -FMOD_RESULT F_API FMOD_DSP_DisconnectFrom (FMOD_DSP *dsp, FMOD_DSP *target); -FMOD_RESULT F_API FMOD_DSP_DisconnectAll (FMOD_DSP *dsp, FMOD_BOOL inputs, FMOD_BOOL outputs); -FMOD_RESULT F_API FMOD_DSP_Remove (FMOD_DSP *dsp); -FMOD_RESULT F_API FMOD_DSP_GetNumInputs (FMOD_DSP *dsp, int *numinputs); -FMOD_RESULT F_API FMOD_DSP_GetNumOutputs (FMOD_DSP *dsp, int *numoutputs); -FMOD_RESULT F_API FMOD_DSP_GetInput (FMOD_DSP *dsp, int index, FMOD_DSP **input, FMOD_DSPCONNECTION **inputconnection); -FMOD_RESULT F_API FMOD_DSP_GetOutput (FMOD_DSP *dsp, int index, FMOD_DSP **output, FMOD_DSPCONNECTION **outputconnection); +FMOD_RESULT F_API FMOD_DSP_AddInput( + FMOD_DSP *dsp, FMOD_DSP *target, FMOD_DSPCONNECTION **connection); +FMOD_RESULT F_API FMOD_DSP_DisconnectFrom(FMOD_DSP *dsp, FMOD_DSP *target); +FMOD_RESULT F_API +FMOD_DSP_DisconnectAll(FMOD_DSP *dsp, FMOD_BOOL inputs, FMOD_BOOL outputs); +FMOD_RESULT F_API FMOD_DSP_Remove(FMOD_DSP *dsp); +FMOD_RESULT F_API FMOD_DSP_GetNumInputs(FMOD_DSP *dsp, int *numinputs); +FMOD_RESULT F_API FMOD_DSP_GetNumOutputs(FMOD_DSP *dsp, int *numoutputs); +FMOD_RESULT F_API FMOD_DSP_GetInput( + FMOD_DSP *dsp, + int index, + FMOD_DSP **input, + FMOD_DSPCONNECTION **inputconnection); +FMOD_RESULT F_API FMOD_DSP_GetOutput( + FMOD_DSP *dsp, + int index, + FMOD_DSP **output, + FMOD_DSPCONNECTION **outputconnection); /* DSP unit control. */ -FMOD_RESULT F_API FMOD_DSP_SetActive (FMOD_DSP *dsp, FMOD_BOOL active); -FMOD_RESULT F_API FMOD_DSP_GetActive (FMOD_DSP *dsp, FMOD_BOOL *active); -FMOD_RESULT F_API FMOD_DSP_SetBypass (FMOD_DSP *dsp, FMOD_BOOL bypass); -FMOD_RESULT F_API FMOD_DSP_GetBypass (FMOD_DSP *dsp, FMOD_BOOL *bypass); -FMOD_RESULT F_API FMOD_DSP_SetSpeakerActive (FMOD_DSP *dsp, FMOD_SPEAKER speaker, FMOD_BOOL active); -FMOD_RESULT F_API FMOD_DSP_GetSpeakerActive (FMOD_DSP *dsp, FMOD_SPEAKER speaker, FMOD_BOOL *active); -FMOD_RESULT F_API FMOD_DSP_Reset (FMOD_DSP *dsp); +FMOD_RESULT F_API FMOD_DSP_SetActive(FMOD_DSP *dsp, FMOD_BOOL active); +FMOD_RESULT F_API FMOD_DSP_GetActive(FMOD_DSP *dsp, FMOD_BOOL *active); +FMOD_RESULT F_API FMOD_DSP_SetBypass(FMOD_DSP *dsp, FMOD_BOOL bypass); +FMOD_RESULT F_API FMOD_DSP_GetBypass(FMOD_DSP *dsp, FMOD_BOOL *bypass); +FMOD_RESULT F_API FMOD_DSP_SetSpeakerActive( + FMOD_DSP *dsp, FMOD_SPEAKER speaker, FMOD_BOOL active); +FMOD_RESULT F_API FMOD_DSP_GetSpeakerActive( + FMOD_DSP *dsp, FMOD_SPEAKER speaker, FMOD_BOOL *active); +FMOD_RESULT F_API FMOD_DSP_Reset(FMOD_DSP *dsp); /* DSP parameter control. */ -FMOD_RESULT F_API FMOD_DSP_SetParameter (FMOD_DSP *dsp, int index, float value); -FMOD_RESULT F_API FMOD_DSP_GetParameter (FMOD_DSP *dsp, int index, float *value, char *valuestr, int valuestrlen); -FMOD_RESULT F_API FMOD_DSP_GetNumParameters (FMOD_DSP *dsp, int *numparams); -FMOD_RESULT F_API FMOD_DSP_GetParameterInfo (FMOD_DSP *dsp, int index, char *name, char *label, char *description, int descriptionlen, float *min, float *max); -FMOD_RESULT F_API FMOD_DSP_ShowConfigDialog (FMOD_DSP *dsp, void *hwnd, FMOD_BOOL show); +FMOD_RESULT F_API FMOD_DSP_SetParameter(FMOD_DSP *dsp, int index, float value); +FMOD_RESULT F_API FMOD_DSP_GetParameter( + FMOD_DSP *dsp, int index, float *value, char *valuestr, int valuestrlen); +FMOD_RESULT F_API FMOD_DSP_GetNumParameters(FMOD_DSP *dsp, int *numparams); +FMOD_RESULT F_API FMOD_DSP_GetParameterInfo( + FMOD_DSP *dsp, + int index, + char *name, + char *label, + char *description, + int descriptionlen, + float *min, + float *max); +FMOD_RESULT F_API +FMOD_DSP_ShowConfigDialog(FMOD_DSP *dsp, void *hwnd, FMOD_BOOL show); /* - DSP attributes. + DSP attributes. */ -FMOD_RESULT F_API FMOD_DSP_GetInfo (FMOD_DSP *dsp, char *name, unsigned int *version, int *channels, int *configwidth, int *configheight); -FMOD_RESULT F_API FMOD_DSP_GetType (FMOD_DSP *dsp, FMOD_DSP_TYPE *type); -FMOD_RESULT F_API FMOD_DSP_SetDefaults (FMOD_DSP *dsp, float frequency, float volume, float pan, int priority); -FMOD_RESULT F_API FMOD_DSP_GetDefaults (FMOD_DSP *dsp, float *frequency, float *volume, float *pan, int *priority); +FMOD_RESULT F_API FMOD_DSP_GetInfo( + FMOD_DSP *dsp, + char *name, + unsigned int *version, + int *channels, + int *configwidth, + int *configheight); +FMOD_RESULT F_API FMOD_DSP_GetType(FMOD_DSP *dsp, FMOD_DSP_TYPE *type); +FMOD_RESULT F_API FMOD_DSP_SetDefaults( + FMOD_DSP *dsp, float frequency, float volume, float pan, int priority); +FMOD_RESULT F_API FMOD_DSP_GetDefaults( + FMOD_DSP *dsp, float *frequency, float *volume, float *pan, int *priority); /* Userdata set/get. */ -FMOD_RESULT F_API FMOD_DSP_SetUserData (FMOD_DSP *dsp, void *userdata); -FMOD_RESULT F_API FMOD_DSP_GetUserData (FMOD_DSP *dsp, void **userdata); +FMOD_RESULT F_API FMOD_DSP_SetUserData(FMOD_DSP *dsp, void *userdata); +FMOD_RESULT F_API FMOD_DSP_GetUserData(FMOD_DSP *dsp, void **userdata); -FMOD_RESULT F_API FMOD_DSP_GetMemoryInfo (FMOD_DSP *dsp, unsigned int memorybits, unsigned int event_memorybits, unsigned int *memoryused, FMOD_MEMORY_USAGE_DETAILS *memoryused_details); +FMOD_RESULT F_API FMOD_DSP_GetMemoryInfo( + FMOD_DSP *dsp, + unsigned int memorybits, + unsigned int event_memorybits, + unsigned int *memoryused, + FMOD_MEMORY_USAGE_DETAILS *memoryused_details); /* 'DSPConnection' API */ -FMOD_RESULT F_API FMOD_DSPConnection_GetInput (FMOD_DSPCONNECTION *dspconnection, FMOD_DSP **input); -FMOD_RESULT F_API FMOD_DSPConnection_GetOutput (FMOD_DSPCONNECTION *dspconnection, FMOD_DSP **output); -FMOD_RESULT F_API FMOD_DSPConnection_SetMix (FMOD_DSPCONNECTION *dspconnection, float volume); -FMOD_RESULT F_API FMOD_DSPConnection_GetMix (FMOD_DSPCONNECTION *dspconnection, float *volume); -FMOD_RESULT F_API FMOD_DSPConnection_SetLevels (FMOD_DSPCONNECTION *dspconnection, FMOD_SPEAKER speaker, float *levels, int numlevels); -FMOD_RESULT F_API FMOD_DSPConnection_GetLevels (FMOD_DSPCONNECTION *dspconnection, FMOD_SPEAKER speaker, float *levels, int numlevels); +FMOD_RESULT F_API FMOD_DSPConnection_GetInput( + FMOD_DSPCONNECTION *dspconnection, FMOD_DSP **input); +FMOD_RESULT F_API FMOD_DSPConnection_GetOutput( + FMOD_DSPCONNECTION *dspconnection, FMOD_DSP **output); +FMOD_RESULT F_API +FMOD_DSPConnection_SetMix(FMOD_DSPCONNECTION *dspconnection, float volume); +FMOD_RESULT F_API +FMOD_DSPConnection_GetMix(FMOD_DSPCONNECTION *dspconnection, float *volume); +FMOD_RESULT F_API FMOD_DSPConnection_SetLevels( + FMOD_DSPCONNECTION *dspconnection, + FMOD_SPEAKER speaker, + float *levels, + int numlevels); +FMOD_RESULT F_API FMOD_DSPConnection_GetLevels( + FMOD_DSPCONNECTION *dspconnection, + FMOD_SPEAKER speaker, + float *levels, + int numlevels); /* Userdata set/get. */ -FMOD_RESULT F_API FMOD_DSPConnection_SetUserData (FMOD_DSPCONNECTION *dspconnection, void *userdata); -FMOD_RESULT F_API FMOD_DSPConnection_GetUserData (FMOD_DSPCONNECTION *dspconnection, void **userdata); +FMOD_RESULT F_API FMOD_DSPConnection_SetUserData( + FMOD_DSPCONNECTION *dspconnection, void *userdata); +FMOD_RESULT F_API FMOD_DSPConnection_GetUserData( + FMOD_DSPCONNECTION *dspconnection, void **userdata); -FMOD_RESULT F_API FMOD_DSPConnection_GetMemoryInfo (FMOD_DSPCONNECTION *dspconnection, unsigned int memorybits, unsigned int event_memorybits, unsigned int *memoryused, FMOD_MEMORY_USAGE_DETAILS *memoryused_details); +FMOD_RESULT F_API FMOD_DSPConnection_GetMemoryInfo( + FMOD_DSPCONNECTION *dspconnection, + unsigned int memorybits, + unsigned int event_memorybits, + unsigned int *memoryused, + FMOD_MEMORY_USAGE_DETAILS *memoryused_details); /* 'Geometry' API */ -FMOD_RESULT F_API FMOD_Geometry_Release (FMOD_GEOMETRY *geometry); +FMOD_RESULT F_API FMOD_Geometry_Release(FMOD_GEOMETRY *geometry); /* Polygon manipulation. */ -FMOD_RESULT F_API FMOD_Geometry_AddPolygon (FMOD_GEOMETRY *geometry, float directocclusion, float reverbocclusion, FMOD_BOOL doublesided, int numvertices, const FMOD_VECTOR *vertices, int *polygonindex); -FMOD_RESULT F_API FMOD_Geometry_GetNumPolygons (FMOD_GEOMETRY *geometry, int *numpolygons); -FMOD_RESULT F_API FMOD_Geometry_GetMaxPolygons (FMOD_GEOMETRY *geometry, int *maxpolygons, int *maxvertices); -FMOD_RESULT F_API FMOD_Geometry_GetPolygonNumVertices(FMOD_GEOMETRY *geometry, int index, int *numvertices); -FMOD_RESULT F_API FMOD_Geometry_SetPolygonVertex (FMOD_GEOMETRY *geometry, int index, int vertexindex, const FMOD_VECTOR *vertex); -FMOD_RESULT F_API FMOD_Geometry_GetPolygonVertex (FMOD_GEOMETRY *geometry, int index, int vertexindex, FMOD_VECTOR *vertex); -FMOD_RESULT F_API FMOD_Geometry_SetPolygonAttributes (FMOD_GEOMETRY *geometry, int index, float directocclusion, float reverbocclusion, FMOD_BOOL doublesided); -FMOD_RESULT F_API FMOD_Geometry_GetPolygonAttributes (FMOD_GEOMETRY *geometry, int index, float *directocclusion, float *reverbocclusion, FMOD_BOOL *doublesided); +FMOD_RESULT F_API FMOD_Geometry_AddPolygon( + FMOD_GEOMETRY *geometry, + float directocclusion, + float reverbocclusion, + FMOD_BOOL doublesided, + int numvertices, + const FMOD_VECTOR *vertices, + int *polygonindex); +FMOD_RESULT F_API +FMOD_Geometry_GetNumPolygons(FMOD_GEOMETRY *geometry, int *numpolygons); +FMOD_RESULT F_API FMOD_Geometry_GetMaxPolygons( + FMOD_GEOMETRY *geometry, int *maxpolygons, int *maxvertices); +FMOD_RESULT F_API FMOD_Geometry_GetPolygonNumVertices( + FMOD_GEOMETRY *geometry, int index, int *numvertices); +FMOD_RESULT F_API FMOD_Geometry_SetPolygonVertex( + FMOD_GEOMETRY *geometry, + int index, + int vertexindex, + const FMOD_VECTOR *vertex); +FMOD_RESULT F_API FMOD_Geometry_GetPolygonVertex( + FMOD_GEOMETRY *geometry, int index, int vertexindex, FMOD_VECTOR *vertex); +FMOD_RESULT F_API FMOD_Geometry_SetPolygonAttributes( + FMOD_GEOMETRY *geometry, + int index, + float directocclusion, + float reverbocclusion, + FMOD_BOOL doublesided); +FMOD_RESULT F_API FMOD_Geometry_GetPolygonAttributes( + FMOD_GEOMETRY *geometry, + int index, + float *directocclusion, + float *reverbocclusion, + FMOD_BOOL *doublesided); /* Object manipulation. */ -FMOD_RESULT F_API FMOD_Geometry_SetActive (FMOD_GEOMETRY *geometry, FMOD_BOOL active); -FMOD_RESULT F_API FMOD_Geometry_GetActive (FMOD_GEOMETRY *geometry, FMOD_BOOL *active); -FMOD_RESULT F_API FMOD_Geometry_SetRotation (FMOD_GEOMETRY *geometry, const FMOD_VECTOR *forward, const FMOD_VECTOR *up); -FMOD_RESULT F_API FMOD_Geometry_GetRotation (FMOD_GEOMETRY *geometry, FMOD_VECTOR *forward, FMOD_VECTOR *up); -FMOD_RESULT F_API FMOD_Geometry_SetPosition (FMOD_GEOMETRY *geometry, const FMOD_VECTOR *position); -FMOD_RESULT F_API FMOD_Geometry_GetPosition (FMOD_GEOMETRY *geometry, FMOD_VECTOR *position); -FMOD_RESULT F_API FMOD_Geometry_SetScale (FMOD_GEOMETRY *geometry, const FMOD_VECTOR *scale); -FMOD_RESULT F_API FMOD_Geometry_GetScale (FMOD_GEOMETRY *geometry, FMOD_VECTOR *scale); -FMOD_RESULT F_API FMOD_Geometry_Save (FMOD_GEOMETRY *geometry, void *data, int *datasize); +FMOD_RESULT F_API +FMOD_Geometry_SetActive(FMOD_GEOMETRY *geometry, FMOD_BOOL active); +FMOD_RESULT F_API +FMOD_Geometry_GetActive(FMOD_GEOMETRY *geometry, FMOD_BOOL *active); +FMOD_RESULT F_API FMOD_Geometry_SetRotation( + FMOD_GEOMETRY *geometry, const FMOD_VECTOR *forward, const FMOD_VECTOR *up); +FMOD_RESULT F_API FMOD_Geometry_GetRotation( + FMOD_GEOMETRY *geometry, FMOD_VECTOR *forward, FMOD_VECTOR *up); +FMOD_RESULT F_API +FMOD_Geometry_SetPosition(FMOD_GEOMETRY *geometry, const FMOD_VECTOR *position); +FMOD_RESULT F_API +FMOD_Geometry_GetPosition(FMOD_GEOMETRY *geometry, FMOD_VECTOR *position); +FMOD_RESULT F_API +FMOD_Geometry_SetScale(FMOD_GEOMETRY *geometry, const FMOD_VECTOR *scale); +FMOD_RESULT F_API +FMOD_Geometry_GetScale(FMOD_GEOMETRY *geometry, FMOD_VECTOR *scale); +FMOD_RESULT F_API +FMOD_Geometry_Save(FMOD_GEOMETRY *geometry, void *data, int *datasize); /* Userdata set/get. */ -FMOD_RESULT F_API FMOD_Geometry_SetUserData (FMOD_GEOMETRY *geometry, void *userdata); -FMOD_RESULT F_API FMOD_Geometry_GetUserData (FMOD_GEOMETRY *geometry, void **userdata); +FMOD_RESULT F_API +FMOD_Geometry_SetUserData(FMOD_GEOMETRY *geometry, void *userdata); +FMOD_RESULT F_API +FMOD_Geometry_GetUserData(FMOD_GEOMETRY *geometry, void **userdata); -FMOD_RESULT F_API FMOD_Geometry_GetMemoryInfo (FMOD_GEOMETRY *geometry, unsigned int memorybits, unsigned int event_memorybits, unsigned int *memoryused, FMOD_MEMORY_USAGE_DETAILS *memoryused_details); +FMOD_RESULT F_API FMOD_Geometry_GetMemoryInfo( + FMOD_GEOMETRY *geometry, + unsigned int memorybits, + unsigned int event_memorybits, + unsigned int *memoryused, + FMOD_MEMORY_USAGE_DETAILS *memoryused_details); /* 'Reverb' API */ -FMOD_RESULT F_API FMOD_Reverb_Release (FMOD_REVERB *reverb); +FMOD_RESULT F_API FMOD_Reverb_Release(FMOD_REVERB *reverb); /* Reverb manipulation. */ -FMOD_RESULT F_API FMOD_Reverb_Set3DAttributes (FMOD_REVERB *reverb, const FMOD_VECTOR *position, float mindistance, float maxdistance); -FMOD_RESULT F_API FMOD_Reverb_Get3DAttributes (FMOD_REVERB *reverb, FMOD_VECTOR *position, float *mindistance, float *maxdistance); -FMOD_RESULT F_API FMOD_Reverb_SetProperties (FMOD_REVERB *reverb, const FMOD_REVERB_PROPERTIES *properties); -FMOD_RESULT F_API FMOD_Reverb_GetProperties (FMOD_REVERB *reverb, FMOD_REVERB_PROPERTIES *properties); -FMOD_RESULT F_API FMOD_Reverb_SetActive (FMOD_REVERB *reverb, FMOD_BOOL active); -FMOD_RESULT F_API FMOD_Reverb_GetActive (FMOD_REVERB *reverb, FMOD_BOOL *active); +FMOD_RESULT F_API FMOD_Reverb_Set3DAttributes( + FMOD_REVERB *reverb, + const FMOD_VECTOR *position, + float mindistance, + float maxdistance); +FMOD_RESULT F_API FMOD_Reverb_Get3DAttributes( + FMOD_REVERB *reverb, + FMOD_VECTOR *position, + float *mindistance, + float *maxdistance); +FMOD_RESULT F_API FMOD_Reverb_SetProperties( + FMOD_REVERB *reverb, const FMOD_REVERB_PROPERTIES *properties); +FMOD_RESULT F_API FMOD_Reverb_GetProperties( + FMOD_REVERB *reverb, FMOD_REVERB_PROPERTIES *properties); +FMOD_RESULT F_API FMOD_Reverb_SetActive(FMOD_REVERB *reverb, FMOD_BOOL active); +FMOD_RESULT F_API FMOD_Reverb_GetActive(FMOD_REVERB *reverb, FMOD_BOOL *active); /* Userdata set/get. */ -FMOD_RESULT F_API FMOD_Reverb_SetUserData (FMOD_REVERB *reverb, void *userdata); -FMOD_RESULT F_API FMOD_Reverb_GetUserData (FMOD_REVERB *reverb, void **userdata); +FMOD_RESULT F_API FMOD_Reverb_SetUserData(FMOD_REVERB *reverb, void *userdata); +FMOD_RESULT F_API FMOD_Reverb_GetUserData(FMOD_REVERB *reverb, void **userdata); -FMOD_RESULT F_API FMOD_Reverb_GetMemoryInfo (FMOD_REVERB *reverb, unsigned int memorybits, unsigned int event_memorybits, unsigned int *memoryused, FMOD_MEMORY_USAGE_DETAILS *memoryused_details); +FMOD_RESULT F_API FMOD_Reverb_GetMemoryInfo( + FMOD_REVERB *reverb, + unsigned int memorybits, + unsigned int event_memorybits, + unsigned int *memoryused, + FMOD_MEMORY_USAGE_DETAILS *memoryused_details); /*$ preserve start $*/ #ifdef __cplusplus diff --git a/src/imports/fmodex/fmod_codec.h b/src/imports/fmodex/fmod_codec.h index cd6c282..f9cd632 100644 --- a/src/imports/fmodex/fmod_codec.h +++ b/src/imports/fmodex/fmod_codec.h @@ -1,11 +1,17 @@ -/* ==================================================================================================== */ -/* FMOD Ex - codec development header file. Copyright (c), Firelight Technologies Pty, Ltd. 2004-2016. */ +/* ==================================================================================================== + */ +/* FMOD Ex - codec development header file. Copyright (c), Firelight + * Technologies Pty, Ltd. 2004-2016. */ /* */ -/* Use this header if you are wanting to develop your own file format plugin to use with */ -/* FMOD's codec system. With this header you can make your own fileformat plugin that FMOD */ -/* can register and use. See the documentation and examples on how to make a working plugin. */ +/* Use this header if you are wanting to develop your own file format plugin to + * use with */ +/* FMOD's codec system. With this header you can make your own fileformat + * plugin that FMOD */ +/* can register and use. See the documentation and examples on how to make a + * working plugin. */ /* */ -/* ==================================================================================================== */ +/* ==================================================================================================== + */ #ifndef _FMOD_CODEC_H #define _FMOD_CODEC_H @@ -15,145 +21,261 @@ typedef struct FMOD_CODEC_WAVEFORMAT FMOD_CODEC_WAVEFORMAT; /* Codec callbacks -*/ -typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_OPENCALLBACK) (FMOD_CODEC_STATE *codec_state, FMOD_MODE usermode, FMOD_CREATESOUNDEXINFO *userexinfo); -typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_CLOSECALLBACK) (FMOD_CODEC_STATE *codec_state); -typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_READCALLBACK) (FMOD_CODEC_STATE *codec_state, void *buffer, unsigned int sizebytes, unsigned int *bytesread); -typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_GETLENGTHCALLBACK) (FMOD_CODEC_STATE *codec_state, unsigned int *length, FMOD_TIMEUNIT lengthtype); -typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_SETPOSITIONCALLBACK) (FMOD_CODEC_STATE *codec_state, int subsound, unsigned int position, FMOD_TIMEUNIT postype); -typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_GETPOSITIONCALLBACK) (FMOD_CODEC_STATE *codec_state, unsigned int *position, FMOD_TIMEUNIT postype); -typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_SOUNDCREATECALLBACK) (FMOD_CODEC_STATE *codec_state, int subsound, FMOD_SOUND *sound); -typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_METADATACALLBACK) (FMOD_CODEC_STATE *codec_state, FMOD_TAGTYPE tagtype, char *name, void *data, unsigned int datalen, FMOD_TAGDATATYPE datatype, int unique); -typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_GETWAVEFORMAT) (FMOD_CODEC_STATE *codec_state, int index, FMOD_CODEC_WAVEFORMAT *waveformat); - +*/ +typedef FMOD_RESULT(F_CALLBACK *FMOD_CODEC_OPENCALLBACK)( + FMOD_CODEC_STATE *codec_state, + FMOD_MODE usermode, + FMOD_CREATESOUNDEXINFO *userexinfo); +typedef FMOD_RESULT(F_CALLBACK *FMOD_CODEC_CLOSECALLBACK)( + FMOD_CODEC_STATE *codec_state); +typedef FMOD_RESULT(F_CALLBACK *FMOD_CODEC_READCALLBACK)( + FMOD_CODEC_STATE *codec_state, + void *buffer, + unsigned int sizebytes, + unsigned int *bytesread); +typedef FMOD_RESULT(F_CALLBACK *FMOD_CODEC_GETLENGTHCALLBACK)( + FMOD_CODEC_STATE *codec_state, + unsigned int *length, + FMOD_TIMEUNIT lengthtype); +typedef FMOD_RESULT(F_CALLBACK *FMOD_CODEC_SETPOSITIONCALLBACK)( + FMOD_CODEC_STATE *codec_state, + int subsound, + unsigned int position, + FMOD_TIMEUNIT postype); +typedef FMOD_RESULT(F_CALLBACK *FMOD_CODEC_GETPOSITIONCALLBACK)( + FMOD_CODEC_STATE *codec_state, + unsigned int *position, + FMOD_TIMEUNIT postype); +typedef FMOD_RESULT(F_CALLBACK *FMOD_CODEC_SOUNDCREATECALLBACK)( + FMOD_CODEC_STATE *codec_state, int subsound, FMOD_SOUND *sound); +typedef FMOD_RESULT(F_CALLBACK *FMOD_CODEC_METADATACALLBACK)( + FMOD_CODEC_STATE *codec_state, + FMOD_TAGTYPE tagtype, + char *name, + void *data, + unsigned int datalen, + FMOD_TAGDATATYPE datatype, + int unique); +typedef FMOD_RESULT(F_CALLBACK *FMOD_CODEC_GETWAVEFORMAT)( + FMOD_CODEC_STATE *codec_state, + int index, + FMOD_CODEC_WAVEFORMAT *waveformat); /* -[STRUCTURE] +[STRUCTURE] [ [DESCRIPTION] - When creating a codec, declare one of these and provide the relevant callbacks and name for FMOD to use when it opens and reads a file. + When creating a codec, declare one of these and provide the relevant +callbacks and name for FMOD to use when it opens and reads a file. [REMARKS] - Members marked with [in] mean the variable can be written to. The user can set the value.
    - Members marked with [out] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
    + Members marked with [in] mean the variable can be written to. The user can +set the value.
    Members marked with [out] mean the variable is modified by +FMOD and is for reading purposes only. Do not change this value.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] FMOD_CODEC_STATE ] */ -typedef struct FMOD_CODEC_DESCRIPTION -{ - const char *name; /* [in] Name of the codec. */ - unsigned int version; /* [in] Plugin writer's version number. */ - int defaultasstream; /* [in] Tells FMOD to open the file as a stream when calling System::createSound, and not a static sample. Should normally be 0 (FALSE), because generally the user wants to decode the file into memory when using System::createSound. Mainly used for formats that decode for a very long time, or could use large amounts of memory when decoded. Usually sequenced formats such as mod/s3m/xm/it/midi fall into this category. It is mainly to stop users that don't know what they're doing from getting FMOD_ERR_MEMORY returned from createSound when they should have in fact called System::createStream or used FMOD_CREATESTREAM in System::createSound. */ - FMOD_TIMEUNIT timeunits; /* [in] When setposition codec is called, only these time formats will be passed to the codec. Use bitwise OR to accumulate different types. */ - FMOD_CODEC_OPENCALLBACK open; /* [in] Open callback for the codec for when FMOD tries to open a sound using this codec. */ - FMOD_CODEC_CLOSECALLBACK close; /* [in] Close callback for the codec for when FMOD tries to close a sound using this codec. */ - FMOD_CODEC_READCALLBACK read; /* [in] Read callback for the codec for when FMOD tries to read some data from the file to the destination format (specified in the open callback). */ - FMOD_CODEC_GETLENGTHCALLBACK getlength; /* [in] Callback to return the length of the song in whatever format required when Sound::getLength is called. */ - FMOD_CODEC_SETPOSITIONCALLBACK setposition; /* [in] Seek callback for the codec for when FMOD tries to seek within the file with Channel::setPosition. */ - FMOD_CODEC_GETPOSITIONCALLBACK getposition; /* [in] Tell callback for the codec for when FMOD tries to get the current position within the with Channel::getPosition. */ - FMOD_CODEC_SOUNDCREATECALLBACK soundcreate; /* [in] Sound creation callback for the codec when FMOD finishes creating the sound. (So the codec can set more parameters for the related created sound, ie loop points/mode or 3D attributes etc). */ - FMOD_CODEC_GETWAVEFORMAT getwaveformat; /* [in] Callback to tell FMOD about the waveformat of a particular subsound. This is to save memory, rather than saving 1000 FMOD_CODEC_WAVEFORMAT structures in the codec, the codec might have a more optimal way of storing this information. */ +typedef struct FMOD_CODEC_DESCRIPTION { + const char *name; /* [in] Name of the codec. */ + unsigned int version; /* [in] Plugin writer's version number. */ + int defaultasstream; /* [in] Tells FMOD to open the file as a stream when + calling System::createSound, and not a static sample. + Should normally be 0 (FALSE), because generally the + user wants to decode the file into memory when using + System::createSound. Mainly used for formats that + decode for a very long time, or could use large + amounts of memory when decoded. Usually sequenced + formats such as mod/s3m/xm/it/midi fall into this + category. It is mainly to stop users that don't know + what they're doing from getting FMOD_ERR_MEMORY + returned from createSound when they should have in + fact called System::createStream or used + FMOD_CREATESTREAM in System::createSound. */ + FMOD_TIMEUNIT timeunits; /* [in] When setposition codec is called, only these + time formats will be passed to the codec. Use + bitwise OR to accumulate different types. */ + FMOD_CODEC_OPENCALLBACK + open; /* [in] Open callback for the codec for when FMOD tries to open a + sound using this codec. */ + FMOD_CODEC_CLOSECALLBACK + close; /* [in] Close callback for the codec for when FMOD tries to close a + sound using this codec. */ + FMOD_CODEC_READCALLBACK + read; /* [in] Read callback for the codec for when FMOD tries to read some + data from the file to the destination format (specified in the + open callback). */ + FMOD_CODEC_GETLENGTHCALLBACK + getlength; /* [in] Callback to return the length of the song in whatever + format required when Sound::getLength is called. */ + FMOD_CODEC_SETPOSITIONCALLBACK + setposition; /* [in] Seek callback for the codec for when FMOD tries to + seek within the file with Channel::setPosition. */ + FMOD_CODEC_GETPOSITIONCALLBACK + getposition; /* [in] Tell callback for the codec for when FMOD tries to + get the current position within the with + Channel::getPosition. */ + FMOD_CODEC_SOUNDCREATECALLBACK + soundcreate; /* [in] Sound creation callback for the codec when FMOD + finishes creating the sound. (So the codec can set more + parameters for the related created sound, ie loop + points/mode or 3D attributes etc). */ + FMOD_CODEC_GETWAVEFORMAT + getwaveformat; /* [in] Callback to tell FMOD about the waveformat of a + particular subsound. This is to save memory, rather + than saving 1000 FMOD_CODEC_WAVEFORMAT structures in the + codec, the codec might have a more optimal way of + storing this information. */ } FMOD_CODEC_DESCRIPTION; - /* -[STRUCTURE] +[STRUCTURE] [ [DESCRIPTION] Set these values marked 'in' to tell fmod what sort of sound to create.
    - The format, channels and frequency tell FMOD what sort of hardware buffer to create when you initialize your code. So if you wrote an MP3 codec that decoded to stereo 16bit integer PCM, you would specify FMOD_SOUND_FORMAT_PCM16, and channels would be equal to 2.
    - Members marked as 'out' are set by fmod. Do not modify these. Simply specify 0 for these values when declaring the structure, FMOD will fill in the values for you after creation with the correct function pointers.
    + The format, channels and frequency tell FMOD what sort of hardware buffer to +create when you initialize your code. So if you wrote an MP3 codec that decoded +to stereo 16bit integer PCM, you would specify FMOD_SOUND_FORMAT_PCM16, and +channels would be equal to 2.
    Members marked as 'out' are set by fmod. Do +not modify these. Simply specify 0 for these values when declaring the +structure, FMOD will fill in the values for you after creation with the correct +function pointers.
    [REMARKS] - Members marked with [in] mean the variable can be written to. The user can set the value.
    - Members marked with [out] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
    -
    - An FMOD file might be from disk, memory or network, however the file may be opened by the user.
    -
    - 'numsubsounds' should be 0 if the file is a normal single sound stream or sound. Examples of this would be .WAV, .WMA, .MP3, .AIFF.
    - 'numsubsounds' should be 1+ if the file is a container format, and does not contain wav data itself. Examples of these types would be CDDA (multiple CD tracks), FSB (contains multiple sounds), MIDI/MOD/S3M/XM/IT (contain instruments).
    - The arrays of format, channel, frequency, length and blockalign should point to arrays of information based on how many subsounds are in the format. If the number of subsounds is 0 then it should point to 1 of each attribute, the same as if the number of subsounds was 1. If subsounds was 100 for example, each pointer should point to an array of 100 of each attribute.
    - When a sound has 1 or more subsounds, you must play the individual sounds specified by first obtaining the subsound with Sound::getSubSound. - + Members marked with [in] mean the variable can be written to. The user can +set the value.
    Members marked with [out] mean the variable is modified by +FMOD and is for reading purposes only. Do not change this value.

    An +FMOD file might be from disk, memory or network, however the file may be opened +by the user.

    'numsubsounds' should be 0 if the file is a normal single +sound stream or sound. Examples of this would be .WAV, .WMA, .MP3, .AIFF.
    + 'numsubsounds' should be 1+ if the file is a container format, and does not +contain wav data itself. Examples of these types would be CDDA (multiple CD +tracks), FSB (contains multiple sounds), MIDI/MOD/S3M/XM/IT (contain +instruments).
    The arrays of format, channel, frequency, length and +blockalign should point to arrays of information based on how many subsounds are +in the format. If the number of subsounds is 0 then it should point to 1 of +each attribute, the same as if the number of subsounds was 1. If subsounds was +100 for example, each pointer should point to an array of 100 of each +attribute.
    When a sound has 1 or more subsounds, you must play the +individual sounds specified by first obtaining the subsound with +Sound::getSubSound. + [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] FMOD_SOUND_FORMAT - FMOD_FILE_READCALLBACK - FMOD_FILE_SEEKCALLBACK + FMOD_FILE_READCALLBACK + FMOD_FILE_SEEKCALLBACK FMOD_CODEC_METADATACALLBACK Sound::getSubSound Sound::getNumSubSounds ] */ -struct FMOD_CODEC_WAVEFORMAT -{ - char name[256]; /* [in] Name of sound.*/ - FMOD_SOUND_FORMAT format; /* [in] Format for (decompressed) codec output, ie FMOD_SOUND_FORMAT_PCM8, FMOD_SOUND_FORMAT_PCM16.*/ - int channels; /* [in] Number of channels used by codec, ie mono = 1, stereo = 2. */ - int frequency; /* [in] Default frequency in hz of the codec, ie 44100. */ - unsigned int lengthbytes; /* [in] Length in bytes of the source data. */ - unsigned int lengthpcm; /* [in] Length in decompressed, PCM samples of the file, ie length in seconds * frequency. Used for Sound::getLength and for memory allocation of static decompressed sample data. */ - int blockalign; /* [in] Blockalign in decompressed, PCM samples of the optimal decode chunk size for this format. The codec read callback will be called in multiples of this value. */ - int loopstart; /* [in] Loopstart in decompressed, PCM samples of file. */ - int loopend; /* [in] Loopend in decompressed, PCM samples of file. */ - FMOD_MODE mode; /* [in] Mode to determine whether the sound should by default load as looping, non looping, 2d or 3d. */ - unsigned int channelmask; /* [in] Microsoft speaker channel mask, as defined for WAVEFORMATEXTENSIBLE and is found in ksmedia.h. Leave at 0 to play in natural speaker order. */ +struct FMOD_CODEC_WAVEFORMAT { + char name[256]; /* [in] Name of sound.*/ + FMOD_SOUND_FORMAT + format; /* [in] Format for (decompressed) codec output, ie + FMOD_SOUND_FORMAT_PCM8, FMOD_SOUND_FORMAT_PCM16.*/ + int channels; /* [in] Number of channels used by codec, ie mono = 1, stereo + = 2. */ + int frequency; /* [in] Default frequency in hz of the codec, ie 44100. */ + unsigned int lengthbytes; /* [in] Length in bytes of the source data. */ + unsigned int lengthpcm; /* [in] Length in decompressed, PCM samples of the + file, ie length in seconds * frequency. Used for + Sound::getLength and for memory allocation of + static decompressed sample data. */ + int blockalign; /* [in] Blockalign in decompressed, PCM samples of the optimal + decode chunk size for this format. The codec read callback + will be called in multiples of this value. */ + int loopstart; /* [in] Loopstart in decompressed, PCM samples of file. */ + int loopend; /* [in] Loopend in decompressed, PCM samples of file. */ + FMOD_MODE mode; /* [in] Mode to determine whether the sound should by default + load as looping, non looping, 2d or 3d. */ + unsigned int + channelmask; /* [in] Microsoft speaker channel mask, as defined for + WAVEFORMATEXTENSIBLE and is found in ksmedia.h. Leave at + 0 to play in natural speaker order. */ }; - /* -[STRUCTURE] +[STRUCTURE] [ [DESCRIPTION] Codec plugin structure that is passed into each callback.

    - Set these numsubsounds and waveformat members when called in FMOD_CODEC_OPENCALLBACK to tell fmod what sort of sound to create.
    -
    - The format, channels and frequency tell FMOD what sort of hardware buffer to create when you initialize your code. So if you wrote an MP3 codec that decoded to stereo 16bit integer PCM, you would specify FMOD_SOUND_FORMAT_PCM16, and channels would be equal to 2.
    + Set these numsubsounds and waveformat members when called in +FMOD_CODEC_OPENCALLBACK to tell fmod what sort of sound to create.

    The +format, channels and frequency tell FMOD what sort of hardware buffer to create +when you initialize your code. So if you wrote an MP3 codec that decoded to +stereo 16bit integer PCM, you would specify FMOD_SOUND_FORMAT_PCM16, and +channels would be equal to 2.
    [REMARKS] - Members marked with [in] mean the variable can be written to. The user can set the value.
    - Members marked with [out] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
    -
    - An FMOD file might be from disk, memory or internet, however the file may be opened by the user.
    -
    - 'numsubsounds' should be 0 if the file is a normal single sound stream or sound. Examples of this would be .WAV, .WMA, .MP3, .AIFF.
    - 'numsubsounds' should be 1+ if the file is a container format, and does not contain wav data itself. Examples of these types would be CDDA (multiple CD tracks), FSB (contains multiple sounds), DLS (contain instruments).
    - The arrays of format, channel, frequency, length and blockalign should point to arrays of information based on how many subsounds are in the format. If the number of subsounds is 0 then it should point to 1 of each attribute, the same as if the number of subsounds was 1. If subsounds was 100 for example, each pointer should point to an array of 100 of each attribute.
    - When a sound has 1 or more subsounds, you must play the individual sounds specified by first obtaining the subsound with Sound::getSubSound. - + Members marked with [in] mean the variable can be written to. The user can +set the value.
    Members marked with [out] mean the variable is modified by +FMOD and is for reading purposes only. Do not change this value.

    An +FMOD file might be from disk, memory or internet, however the file may be opened +by the user.

    'numsubsounds' should be 0 if the file is a normal single +sound stream or sound. Examples of this would be .WAV, .WMA, .MP3, .AIFF.
    + 'numsubsounds' should be 1+ if the file is a container format, and does not +contain wav data itself. Examples of these types would be CDDA (multiple CD +tracks), FSB (contains multiple sounds), DLS (contain instruments).
    The +arrays of format, channel, frequency, length and blockalign should point to +arrays of information based on how many subsounds are in the format. If the +number of subsounds is 0 then it should point to 1 of each attribute, the same +as if the number of subsounds was 1. If subsounds was 100 for example, each +pointer should point to an array of 100 of each attribute.
    When a sound has +1 or more subsounds, you must play the individual sounds specified by first +obtaining the subsound with Sound::getSubSound. + [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] FMOD_SOUND_FORMAT - FMOD_FILE_READCALLBACK - FMOD_FILE_SEEKCALLBACK + FMOD_FILE_READCALLBACK + FMOD_FILE_SEEKCALLBACK FMOD_CODEC_METADATACALLBACK Sound::getSubSound Sound::getNumSubSounds ] */ -struct FMOD_CODEC_STATE -{ - int numsubsounds; /* [in] Number of 'subsounds' in this sound. Anything other than 0 makes it a 'container' format (ie CDDA/DLS/FSB etc which contain 1 or more su bsounds). For most normal, single sound codec such as WAV/AIFF/MP3, this should be 0 as they are not a container for subsounds, they are the sound by itself. */ - FMOD_CODEC_WAVEFORMAT *waveformat; /* [in] Pointer to an array of format structures containing information about each sample. Can be 0 or NULL if FMOD_CODEC_GETWAVEFORMAT callback is preferred. The number of entries here must equal the number of subsounds defined in the subsound parameter. If numsubsounds = 0 then there should be 1 instance of this structure. */ - void *plugindata; /* [in] Plugin writer created data the codec author wants to attach to this object. */ - - void *filehandle; /* [out] This will return an internal FMOD file handle to use with the callbacks provided. */ - unsigned int filesize; /* [out] This will contain the size of the file in bytes. */ - FMOD_FILE_READCALLBACK fileread; /* [out] This will return a callable FMOD file function to use from codec. */ - FMOD_FILE_SEEKCALLBACK fileseek; /* [out] This will return a callable FMOD file function to use from codec. */ - FMOD_CODEC_METADATACALLBACK metadata; /* [out] This will return a callable FMOD metadata function to use from codec. */ +struct FMOD_CODEC_STATE { + int numsubsounds; /* [in] Number of 'subsounds' in this sound. Anything other + than 0 makes it a 'container' format (ie CDDA/DLS/FSB etc + which contain 1 or more su bsounds). For most normal, + single sound codec such as WAV/AIFF/MP3, this should be 0 + as they are not a container for subsounds, they are the + sound by itself. */ + FMOD_CODEC_WAVEFORMAT + *waveformat; /* [in] Pointer to an array of format structures containing + information about each sample. Can be 0 or NULL if + FMOD_CODEC_GETWAVEFORMAT callback is preferred. The + number of entries here must equal the number of subsounds + defined in the subsound parameter. If numsubsounds = 0 + then there should be 1 instance of this structure. */ + void *plugindata; /* [in] Plugin writer created data the codec author wants to + attach to this object. */ + + void *filehandle; /* [out] This will return an internal FMOD file handle to + use with the callbacks provided. */ + unsigned int + filesize; /* [out] This will contain the size of the file in bytes. */ + FMOD_FILE_READCALLBACK fileread; /* [out] This will return a callable FMOD + file function to use from codec. */ + FMOD_FILE_SEEKCALLBACK fileseek; /* [out] This will return a callable FMOD + file function to use from codec. */ + FMOD_CODEC_METADATACALLBACK + metadata; /* [out] This will return a callable FMOD metadata function to + use from codec. */ }; #endif - - diff --git a/src/imports/fmodex/fmod_dsp.h b/src/imports/fmodex/fmod_dsp.h index 0779c32..c3509a5 100644 --- a/src/imports/fmodex/fmod_dsp.h +++ b/src/imports/fmodex/fmod_dsp.h @@ -1,183 +1,271 @@ -/* ========================================================================================== */ -/* FMOD Ex - DSP header file. Copyright (c), Firelight Technologies Pty, Ltd. 2004-2016. */ +/* ========================================================================================== + */ +/* FMOD Ex - DSP header file. Copyright (c), Firelight Technologies Pty, Ltd. + * 2004-2016. */ /* */ -/* Use this header if you are interested in delving deeper into the FMOD software mixing / */ -/* DSP engine. In this header you can find parameter structures for FMOD system reigstered */ -/* DSP effects and generators. */ -/* Also use this header if you are wanting to develop your own DSP plugin to use with FMOD's */ -/* dsp system. With this header you can make your own DSP plugin that FMOD can */ -/* register and use. See the documentation and examples on how to make a working plugin. */ +/* Use this header if you are interested in delving deeper into the FMOD + * software mixing / */ +/* DSP engine. In this header you can find parameter structures for FMOD system + * reigstered */ +/* DSP effects and generators. */ +/* Also use this header if you are wanting to develop your own DSP plugin to use + * with FMOD's */ +/* dsp system. With this header you can make your own DSP plugin that FMOD can + */ +/* register and use. See the documentation and examples on how to make a + * working plugin. */ /* */ -/* ========================================================================================== */ +/* ========================================================================================== + */ #ifndef _FMOD_DSP_H #define _FMOD_DSP_H typedef struct FMOD_DSP_STATE FMOD_DSP_STATE; -/* +/* DSP callbacks */ -typedef FMOD_RESULT (F_CALLBACK *FMOD_DSP_CREATECALLBACK) (FMOD_DSP_STATE *dsp_state); -typedef FMOD_RESULT (F_CALLBACK *FMOD_DSP_RELEASECALLBACK) (FMOD_DSP_STATE *dsp_state); -typedef FMOD_RESULT (F_CALLBACK *FMOD_DSP_RESETCALLBACK) (FMOD_DSP_STATE *dsp_state); -typedef FMOD_RESULT (F_CALLBACK *FMOD_DSP_READCALLBACK) (FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels); -typedef FMOD_RESULT (F_CALLBACK *FMOD_DSP_SETPOSITIONCALLBACK)(FMOD_DSP_STATE *dsp_state, unsigned int pos); -typedef FMOD_RESULT (F_CALLBACK *FMOD_DSP_SETPARAMCALLBACK) (FMOD_DSP_STATE *dsp_state, int index, float value); -typedef FMOD_RESULT (F_CALLBACK *FMOD_DSP_GETPARAMCALLBACK) (FMOD_DSP_STATE *dsp_state, int index, float *value, char *valuestr); -typedef FMOD_RESULT (F_CALLBACK *FMOD_DSP_DIALOGCALLBACK) (FMOD_DSP_STATE *dsp_state, void *hwnd, int show); +typedef FMOD_RESULT(F_CALLBACK *FMOD_DSP_CREATECALLBACK)( + FMOD_DSP_STATE *dsp_state); +typedef FMOD_RESULT(F_CALLBACK *FMOD_DSP_RELEASECALLBACK)( + FMOD_DSP_STATE *dsp_state); +typedef FMOD_RESULT(F_CALLBACK *FMOD_DSP_RESETCALLBACK)( + FMOD_DSP_STATE *dsp_state); +typedef FMOD_RESULT(F_CALLBACK *FMOD_DSP_READCALLBACK)( + FMOD_DSP_STATE *dsp_state, + float *inbuffer, + float *outbuffer, + unsigned int length, + int inchannels, + int outchannels); +typedef FMOD_RESULT(F_CALLBACK *FMOD_DSP_SETPOSITIONCALLBACK)( + FMOD_DSP_STATE *dsp_state, unsigned int pos); +typedef FMOD_RESULT(F_CALLBACK *FMOD_DSP_SETPARAMCALLBACK)( + FMOD_DSP_STATE *dsp_state, int index, float value); +typedef FMOD_RESULT(F_CALLBACK *FMOD_DSP_GETPARAMCALLBACK)( + FMOD_DSP_STATE *dsp_state, int index, float *value, char *valuestr); +typedef FMOD_RESULT(F_CALLBACK *FMOD_DSP_DIALOGCALLBACK)( + FMOD_DSP_STATE *dsp_state, void *hwnd, int show); /* [ENUM] [ - [DESCRIPTION] - These definitions can be used for creating FMOD defined special effects or DSP units. + [DESCRIPTION] + These definitions can be used for creating FMOD defined special effects or +DSP units. [REMARKS] - To get them to be active, first create the unit, then add it somewhere into the DSP network, either at the front of the network near the soundcard unit to affect the global output (by using System::getDSPHead), or on a single channel (using Channel::getDSPHead). + To get them to be active, first create the unit, then add it somewhere into +the DSP network, either at the front of the network near the soundcard unit to +affect the global output (by using System::getDSPHead), or on a single channel +(using Channel::getDSPHead). [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] System::createDSPByType ] */ -typedef enum -{ - FMOD_DSP_TYPE_UNKNOWN, /* This unit was created via a non FMOD plugin so has an unknown purpose. */ - FMOD_DSP_TYPE_MIXER, /* This unit does nothing but take inputs and mix them together then feed the result to the soundcard unit. */ - FMOD_DSP_TYPE_OSCILLATOR, /* This unit generates sine/square/saw/triangle or noise tones. */ - FMOD_DSP_TYPE_LOWPASS, /* This unit filters sound using a high quality, resonant lowpass filter algorithm but consumes more CPU time. */ - FMOD_DSP_TYPE_ITLOWPASS, /* This unit filters sound using a resonant lowpass filter algorithm that is used in Impulse Tracker, but with limited cutoff range (0 to 8060hz). */ - FMOD_DSP_TYPE_HIGHPASS, /* This unit filters sound using a resonant highpass filter algorithm. */ - FMOD_DSP_TYPE_ECHO, /* This unit produces an echo on the sound and fades out at the desired rate. */ - FMOD_DSP_TYPE_FLANGE, /* This unit produces a flange effect on the sound. */ - FMOD_DSP_TYPE_DISTORTION, /* This unit distorts the sound. */ - FMOD_DSP_TYPE_NORMALIZE, /* This unit normalizes or amplifies the sound to a certain level. */ - FMOD_DSP_TYPE_PARAMEQ, /* This unit attenuates or amplifies a selected frequency range. */ - FMOD_DSP_TYPE_PITCHSHIFT, /* This unit bends the pitch of a sound without changing the speed of playback. */ - FMOD_DSP_TYPE_CHORUS, /* This unit produces a chorus effect on the sound. */ - FMOD_DSP_TYPE_VSTPLUGIN, /* This unit allows the use of Steinberg VST plugins */ - FMOD_DSP_TYPE_WINAMPPLUGIN, /* This unit allows the use of Nullsoft Winamp plugins */ - FMOD_DSP_TYPE_ITECHO, /* This unit produces an echo on the sound and fades out at the desired rate as is used in Impulse Tracker. */ - FMOD_DSP_TYPE_COMPRESSOR, /* This unit implements dynamic compression (linked multichannel, wideband) */ - FMOD_DSP_TYPE_SFXREVERB, /* This unit implements SFX reverb */ - FMOD_DSP_TYPE_LOWPASS_SIMPLE, /* This unit filters sound using a simple lowpass with no resonance, but has flexible cutoff and is fast. */ - FMOD_DSP_TYPE_DELAY, /* This unit produces different delays on individual channels of the sound. */ - FMOD_DSP_TYPE_TREMOLO, /* This unit produces a tremolo / chopper effect on the sound. */ - FMOD_DSP_TYPE_LADSPAPLUGIN, /* This unit allows the use of LADSPA standard plugins. */ - FMOD_DSP_TYPE_HIGHPASS_SIMPLE, /* This unit filters sound using a simple highpass with no resonance, but has flexible cutoff and is fast. */ - FMOD_DSP_TYPE_HARDWARE = 1000, /* Offset that platform specific FMOD_HARDWARE DSPs will start at. */ - FMOD_DSP_TYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ +typedef enum { + FMOD_DSP_TYPE_UNKNOWN, /* This unit was created via a non FMOD plugin so has + an unknown purpose. */ + FMOD_DSP_TYPE_MIXER, /* This unit does nothing but take inputs and mix them + together then feed the result to the soundcard unit. + */ + FMOD_DSP_TYPE_OSCILLATOR, /* This unit generates sine/square/saw/triangle or + noise tones. */ + FMOD_DSP_TYPE_LOWPASS, /* This unit filters sound using a high quality, + resonant lowpass filter algorithm but consumes more + CPU time. */ + FMOD_DSP_TYPE_ITLOWPASS, /* This unit filters sound using a resonant lowpass + filter algorithm that is used in Impulse Tracker, + but with limited cutoff range (0 to 8060hz). */ + FMOD_DSP_TYPE_HIGHPASS, /* This unit filters sound using a resonant highpass + filter algorithm. */ + FMOD_DSP_TYPE_ECHO, /* This unit produces an echo on the sound and fades out + at the desired rate. */ + FMOD_DSP_TYPE_FLANGE, /* This unit produces a flange effect on the sound. */ + FMOD_DSP_TYPE_DISTORTION, /* This unit distorts the sound. */ + FMOD_DSP_TYPE_NORMALIZE, /* This unit normalizes or amplifies the sound to a + certain level. */ + FMOD_DSP_TYPE_PARAMEQ, /* This unit attenuates or amplifies a selected + frequency range. */ + FMOD_DSP_TYPE_PITCHSHIFT, /* This unit bends the pitch of a sound without + changing the speed of playback. */ + FMOD_DSP_TYPE_CHORUS, /* This unit produces a chorus effect on the sound. */ + FMOD_DSP_TYPE_VSTPLUGIN, /* This unit allows the use of Steinberg VST plugins + */ + FMOD_DSP_TYPE_WINAMPPLUGIN, /* This unit allows the use of Nullsoft Winamp + plugins */ + FMOD_DSP_TYPE_ITECHO, /* This unit produces an echo on the sound and fades out + at the desired rate as is used in Impulse Tracker. */ + FMOD_DSP_TYPE_COMPRESSOR, /* This unit implements dynamic compression (linked + multichannel, wideband) */ + FMOD_DSP_TYPE_SFXREVERB, /* This unit implements SFX reverb */ + FMOD_DSP_TYPE_LOWPASS_SIMPLE, /* This unit filters sound using a simple + lowpass with no resonance, but has flexible + cutoff and is fast. */ + FMOD_DSP_TYPE_DELAY, /* This unit produces different delays on individual + channels of the sound. */ + FMOD_DSP_TYPE_TREMOLO, /* This unit produces a tremolo / chopper effect on the + sound. */ + FMOD_DSP_TYPE_LADSPAPLUGIN, /* This unit allows the use of LADSPA standard + plugins. */ + FMOD_DSP_TYPE_HIGHPASS_SIMPLE, /* This unit filters sound using a simple + highpass with no resonance, but has flexible + cutoff and is fast. */ + FMOD_DSP_TYPE_HARDWARE = 1000, /* Offset that platform specific FMOD_HARDWARE + DSPs will start at. */ + FMOD_DSP_TYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ } FMOD_DSP_TYPE; - /* -[STRUCTURE] +[STRUCTURE] [ [DESCRIPTION] Structure to define a parameter for a DSP unit. [REMARKS] - Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
    - Members marked with [w] mean the variable can be written to. The user can set the value.
    + Members marked with [r] mean the variable is modified by FMOD and is for +reading purposes only. Do not change this value.
    Members marked with [w] +mean the variable can be written to. The user can set the value.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] System::createDSP DSP::setParameter ] */ -typedef struct FMOD_DSP_PARAMETERDESC -{ - float min; /* [w] Minimum value of the parameter (ie 100.0). */ - float max; /* [w] Maximum value of the parameter (ie 22050.0). */ - float defaultval; /* [w] Default value of parameter. */ - char name[16]; /* [w] Name of the parameter to be displayed (ie "Cutoff frequency"). */ - char label[16]; /* [w] Short string to be put next to value to denote the unit type (ie "hz"). */ - const char *description; /* [w] Description of the parameter to be displayed as a help item / tooltip for this parameter. */ +typedef struct FMOD_DSP_PARAMETERDESC { + float min; /* [w] Minimum value of the parameter (ie 100.0). */ + float max; /* [w] Maximum value of the parameter (ie 22050.0). */ + float defaultval; /* [w] Default value of parameter. */ + char name[16]; /* [w] Name of the parameter to be displayed (ie "Cutoff + frequency"). */ + char label[16]; /* [w] Short string to be put next to value to denote the unit + type (ie "hz"). */ + const char *description; /* [w] Description of the parameter to be displayed + as a help item / tooltip for this parameter. */ } FMOD_DSP_PARAMETERDESC; - /* -[STRUCTURE] +[STRUCTURE] [ [DESCRIPTION] - When creating a DSP unit, declare one of these and provide the relevant callbacks and name for FMOD to use when it creates and uses a DSP unit of this type. + When creating a DSP unit, declare one of these and provide the relevant +callbacks and name for FMOD to use when it creates and uses a DSP unit of this +type. [REMARKS]
    - Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
    - Members marked with [w] mean the variable can be written to. The user can set the value.
    -
    - IMPORTANT: The 'paramdesc' member should point to static memory, as FMOD references the data internally using the pointer provided. Do not store these parameter description structures on the stack, or in heap memory that is freed while FMOD is using it.
    -
    - There are 2 different ways to change a parameter in this architecture.
    - One is to use DSP::setParameter / DSP::getParameter. This is platform independant and is dynamic, so new unknown plugins can have their parameters enumerated and used.
    - The other is to use DSP::showConfigDialog. This is platform specific and requires a GUI, and will display a dialog box to configure the plugin.
    + Members marked with [r] mean the variable is modified by FMOD and is for +reading purposes only. Do not change this value.
    Members marked with [w] +mean the variable can be written to. The user can set the value.

    + IMPORTANT: The 'paramdesc' member should point to static memory, as FMOD +references the data internally using the pointer provided. Do not store these +parameter description structures on the stack, or in heap memory that is freed +while FMOD is using it.

    There are 2 different ways to change a +parameter in this architecture.
    One is to use DSP::setParameter / +DSP::getParameter. This is platform independant and is dynamic, so new unknown +plugins can have their parameters enumerated and used.
    The other is to use +DSP::showConfigDialog. This is platform specific and requires a GUI, and will +display a dialog box to configure the plugin.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] System::createDSP FMOD_DSP_STATE ] */ -typedef struct FMOD_DSP_DESCRIPTION -{ - char name[32]; /* [w] Name of the unit to be displayed in the network. */ - unsigned int version; /* [w] Plugin writer's version number. */ - int channels; /* [w] Number of channels. Use 0 to process whatever number of channels is currently in the network. >0 would be mostly used if the unit is a unit that only generates sound. */ - FMOD_DSP_CREATECALLBACK create; /* [w] Create callback. This is called when DSP unit is created. Can be null. */ - FMOD_DSP_RELEASECALLBACK release; /* [w] Release callback. This is called just before the unit is freed so the user can do any cleanup needed for the unit. Can be null. */ - FMOD_DSP_RESETCALLBACK reset; /* [w] Reset callback. This is called by the user to reset any history buffers that may need resetting for a filter, when it is to be used or re-used for the first time to its initial clean state. Use to avoid clicks or artifacts. */ - FMOD_DSP_READCALLBACK read; /* [w] Read callback. Processing is done here. Can be null. */ - FMOD_DSP_SETPOSITIONCALLBACK setposition; /* [w] Set position callback. This is called if the unit wants to update its position info but not process data, or reset a cursor position internally if it is reading data from a certain source. Can be null. */ +typedef struct FMOD_DSP_DESCRIPTION { + char name[32]; /* [w] Name of the unit to be displayed in the network. */ + unsigned int version; /* [w] Plugin writer's version number. */ + int channels; /* [w] Number of channels. Use 0 to process whatever number of + channels is currently in the network. >0 would be mostly + used if the unit is a unit that only generates sound. */ + FMOD_DSP_CREATECALLBACK create; /* [w] Create callback. This is called when + DSP unit is created. Can be null. */ + FMOD_DSP_RELEASECALLBACK + release; /* [w] Release callback. This is called just before the unit is + freed so the user can do any cleanup needed for the unit. Can + be null. */ + FMOD_DSP_RESETCALLBACK + reset; /* [w] Reset callback. This is called by the user to reset any + history buffers that may need resetting for a filter, when it is + to be used or re-used for the first time to its initial clean + state. Use to avoid clicks or artifacts. */ + FMOD_DSP_READCALLBACK + read; /* [w] Read callback. Processing is done here. Can be null. */ + FMOD_DSP_SETPOSITIONCALLBACK + setposition; /* [w] Set position callback. This is called if the unit + wants to update its position info but not process data, or + reset a cursor position internally if it is reading data + from a certain source. Can be null. */ - int numparameters; /* [w] Number of parameters used in this filter. The user finds this with DSP::getNumParameters */ - FMOD_DSP_PARAMETERDESC *paramdesc; /* [w] Variable number of parameter structures. */ - FMOD_DSP_SETPARAMCALLBACK setparameter; /* [w] This is called when the user calls DSP::setParameter. Can be null. */ - FMOD_DSP_GETPARAMCALLBACK getparameter; /* [w] This is called when the user calls DSP::getParameter. Can be null. */ - FMOD_DSP_DIALOGCALLBACK config; /* [w] This is called when the user calls DSP::showConfigDialog. Can be used to display a dialog to configure the filter. Can be null. */ - int configwidth; /* [w] Width of config dialog graphic if there is one. 0 otherwise.*/ - int configheight; /* [w] Height of config dialog graphic if there is one. 0 otherwise.*/ - void *userdata; /* [w] Optional. Specify 0 to ignore. This is user data to be attached to the DSP unit during creation. Access via DSP::getUserData. */ + int numparameters; /* [w] Number of parameters used in this filter. The user + finds this with DSP::getNumParameters */ + FMOD_DSP_PARAMETERDESC + *paramdesc; /* [w] Variable number of parameter structures. */ + FMOD_DSP_SETPARAMCALLBACK + setparameter; /* [w] This is called when the user calls DSP::setParameter. + Can be null. */ + FMOD_DSP_GETPARAMCALLBACK + getparameter; /* [w] This is called when the user calls DSP::getParameter. + Can be null. */ + FMOD_DSP_DIALOGCALLBACK + config; /* [w] This is called when the user calls DSP::showConfigDialog. + Can be used to display a dialog to configure the filter. Can + be null. */ + int configwidth; /* [w] Width of config dialog graphic if there is one. 0 + otherwise.*/ + int configheight; /* [w] Height of config dialog graphic if there is one. 0 + otherwise.*/ + void *userdata; /* [w] Optional. Specify 0 to ignore. This is user data to be + attached to the DSP unit during creation. Access via + DSP::getUserData. */ } FMOD_DSP_DESCRIPTION; - /* -[STRUCTURE] +[STRUCTURE] [ [DESCRIPTION] DSP plugin structure that is passed into each callback. [REMARKS] - Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
    - Members marked with [w] mean the variable can be written to. The user can set the value.
    + Members marked with [r] mean the variable is modified by FMOD and is for +reading purposes only. Do not change this value.
    Members marked with [w] +mean the variable can be written to. The user can set the value.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] FMOD_DSP_DESCRIPTION ] */ -struct FMOD_DSP_STATE -{ - FMOD_DSP *instance; /* [r] Handle to the DSP hand the user created. Not to be modified. C++ users cast to FMOD::DSP to use. */ - void *plugindata; /* [w] Plugin writer created data the output author wants to attach to this object. */ - unsigned short speakermask; /* [w] Specifies which speakers the DSP effect is active on */ +struct FMOD_DSP_STATE { + FMOD_DSP *instance; /* [r] Handle to the DSP hand the user created. Not to be + modified. C++ users cast to FMOD::DSP to use. */ + void *plugindata; /* [w] Plugin writer created data the output author wants to + attach to this object. */ + unsigned short speakermask; /* [w] Specifies which speakers the DSP effect is + active on */ }; - /* =================================================================================================== - FMOD built in effect parameters. + FMOD built in effect parameters. Use DSP::setParameter with these enums for the 'index' parameter. =================================================================================================== @@ -185,490 +273,594 @@ struct FMOD_DSP_STATE /* [ENUM] -[ - [DESCRIPTION] +[ + [DESCRIPTION] Parameter types for the FMOD_DSP_TYPE_OSCILLATOR filter. [REMARKS] [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] DSP::setParameter DSP::getParameter FMOD_DSP_TYPE ] */ -typedef enum -{ - FMOD_DSP_OSCILLATOR_TYPE, /* Waveform type. 0 = sine. 1 = square. 2 = sawup. 3 = sawdown. 4 = triangle. 5 = noise. */ - FMOD_DSP_OSCILLATOR_RATE /* Frequency of the sinewave in hz. 1.0 to 22000.0. Default = 220.0. */ +typedef enum { + FMOD_DSP_OSCILLATOR_TYPE, /* Waveform type. 0 = sine. 1 = square. 2 = sawup. + 3 = sawdown. 4 = triangle. 5 = noise. */ + FMOD_DSP_OSCILLATOR_RATE /* Frequency of the sinewave in hz. 1.0 to 22000.0. + Default = 220.0. */ } FMOD_DSP_OSCILLATOR; - /* [ENUM] -[ - [DESCRIPTION] +[ + [DESCRIPTION] Parameter types for the FMOD_DSP_TYPE_LOWPASS filter. [REMARKS] [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] DSP::setParameter DSP::getParameter FMOD_DSP_TYPE ] */ -typedef enum -{ - FMOD_DSP_LOWPASS_CUTOFF, /* Lowpass cutoff frequency in hz. 10.0 to 22000.0. Default = 5000.0. */ - FMOD_DSP_LOWPASS_RESONANCE /* Lowpass resonance Q value. 1.0 to 10.0. Default = 1.0. */ +typedef enum { + FMOD_DSP_LOWPASS_CUTOFF, /* Lowpass cutoff frequency in hz. 10.0 to 22000.0. + Default = 5000.0. */ + FMOD_DSP_LOWPASS_RESONANCE /* Lowpass resonance Q value. 1.0 to 10.0. Default + = 1.0. */ } FMOD_DSP_LOWPASS; - /* [ENUM] -[ - [DESCRIPTION] +[ + [DESCRIPTION] Parameter types for the FMOD_DSP_TYPE_ITLOWPASS filter.
    - This is different to the default FMOD_DSP_TYPE_ITLOWPASS filter in that it uses a different quality algorithm and is - the filter used to produce the correct sounding playback in .IT files.
    - FMOD Ex's .IT playback uses this filter.
    + This is different to the default FMOD_DSP_TYPE_ITLOWPASS filter in that it +uses a different quality algorithm and is the filter used to produce the correct +sounding playback in .IT files.
    FMOD Ex's .IT playback uses this filter.
    [REMARKS] - Note! This filter actually has a limited cutoff frequency below the specified maximum, due to its limited design, - so for a more open range filter use FMOD_DSP_LOWPASS or if you don't mind not having resonance, + Note! This filter actually has a limited cutoff frequency below the +specified maximum, due to its limited design, so for a more open range filter +use FMOD_DSP_LOWPASS or if you don't mind not having resonance, FMOD_DSP_LOWPASS_SIMPLE.
    The effective maximum cutoff is about 8060hz. [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] DSP::setParameter DSP::getParameter FMOD_DSP_TYPE ] */ -typedef enum -{ - FMOD_DSP_ITLOWPASS_CUTOFF, /* Lowpass cutoff frequency in hz. 1.0 to 22000.0. Default = 5000.0/ */ - FMOD_DSP_ITLOWPASS_RESONANCE /* Lowpass resonance Q value. 0.0 to 127.0. Default = 1.0. */ +typedef enum { + FMOD_DSP_ITLOWPASS_CUTOFF, /* Lowpass cutoff frequency in hz. 1.0 to 22000.0. + Default = 5000.0/ */ + FMOD_DSP_ITLOWPASS_RESONANCE /* Lowpass resonance Q value. 0.0 to 127.0. + Default = 1.0. */ } FMOD_DSP_ITLOWPASS; - /* [ENUM] -[ - [DESCRIPTION] +[ + [DESCRIPTION] Parameter types for the FMOD_DSP_TYPE_HIGHPASS filter. [REMARKS] [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] DSP::setParameter DSP::getParameter FMOD_DSP_TYPE ] */ -typedef enum -{ - FMOD_DSP_HIGHPASS_CUTOFF, /* Highpass cutoff frequency in hz. 1.0 to output 22000.0. Default = 5000.0. */ - FMOD_DSP_HIGHPASS_RESONANCE /* Highpass resonance Q value. 1.0 to 10.0. Default = 1.0. */ +typedef enum { + FMOD_DSP_HIGHPASS_CUTOFF, /* Highpass cutoff frequency in hz. 1.0 to output + 22000.0. Default = 5000.0. */ + FMOD_DSP_HIGHPASS_RESONANCE /* Highpass resonance Q value. 1.0 to 10.0. + Default = 1.0. */ } FMOD_DSP_HIGHPASS; - /* [ENUM] -[ - [DESCRIPTION] +[ + [DESCRIPTION] Parameter types for the FMOD_DSP_TYPE_ECHO filter. [REMARKS] - Note. Every time the delay is changed, the plugin re-allocates the echo buffer. This means the echo will dissapear at that time while it refills its new buffer.
    - Larger echo delays result in larger amounts of memory allocated.
    -
    - 'maxchannels' also dictates the amount of memory allocated. By default, the maxchannels value is 0. If FMOD is set to stereo, the echo unit will allocate enough memory for 2 channels. If it is 5.1, it will allocate enough memory for a 6 channel echo, etc.
    - If the echo effect is only ever applied to the global mix (ie it was added with System::addDSP), then 0 is the value to set as it will be enough to handle all speaker modes.
    - When the echo is added to a channel (ie Channel::addDSP) then the channel count that comes in could be anything from 1 to 8 possibly. It is only in this case where you might want to increase the channel count above the output's channel count.
    - If a channel echo is set to a lower number than the sound's channel count that is coming in, it will not echo the sound.
    + Note. Every time the delay is changed, the plugin re-allocates the echo +buffer. This means the echo will dissapear at that time while it refills its +new buffer.
    Larger echo delays result in larger amounts of memory +allocated.

    + 'maxchannels' also dictates the amount of memory allocated. By +default, the maxchannels value is 0. If FMOD is set to stereo, the echo unit +will allocate enough memory for 2 channels. If it is 5.1, it will allocate +enough memory for a 6 channel echo, etc.
    If the echo effect is only ever +applied to the global mix (ie it was added with System::addDSP), then 0 is the +value to set as it will be enough to handle all speaker modes.
    When the echo +is added to a channel (ie Channel::addDSP) then the channel count that comes in +could be anything from 1 to 8 possibly. It is only in this case where you might +want to increase the channel count above the output's channel count.
    If a +channel echo is set to a lower number than the sound's channel count that is +coming in, it will not echo the sound.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] DSP::setParameter DSP::getParameter FMOD_DSP_TYPE ] */ -typedef enum -{ - FMOD_DSP_ECHO_DELAY, /* Echo delay in ms. 10 to 5000. Default = 500. */ - FMOD_DSP_ECHO_DECAYRATIO, /* Echo decay per delay. 0 to 1. 1.0 = No decay, 0.0 = total decay (ie simple 1 line delay). Default = 0.5. */ - FMOD_DSP_ECHO_MAXCHANNELS, /* Maximum channels supported. 0 to 16. 0 = same as fmod's default output polyphony, 1 = mono, 2 = stereo etc. See remarks for more. Default = 0. It is suggested to leave at 0! */ - FMOD_DSP_ECHO_DRYMIX, /* Volume of original signal to pass to output. 0.0 to 1.0. Default = 1.0. */ - FMOD_DSP_ECHO_WETMIX /* Volume of echo signal to pass to output. 0.0 to 1.0. Default = 1.0. */ +typedef enum { + FMOD_DSP_ECHO_DELAY, /* Echo delay in ms. 10 to 5000. Default = 500. */ + FMOD_DSP_ECHO_DECAYRATIO, /* Echo decay per delay. 0 to 1. 1.0 = No decay, + 0.0 = total decay (ie simple 1 line delay). + Default = 0.5. */ + FMOD_DSP_ECHO_MAXCHANNELS, /* Maximum channels supported. 0 to 16. 0 = same + as fmod's default output polyphony, 1 = mono, 2 + = stereo etc. See remarks for more. Default = + 0. It is suggested to leave at 0! */ + FMOD_DSP_ECHO_DRYMIX, /* Volume of original signal to pass to output. 0.0 + to 1.0. Default = 1.0. */ + FMOD_DSP_ECHO_WETMIX /* Volume of echo signal to pass to output. 0.0 to 1.0. + Default = 1.0. */ } FMOD_DSP_ECHO; - /* [ENUM] -[ - [DESCRIPTION] +[ + [DESCRIPTION] Parameter types for the FMOD_DSP_TYPE_DELAY filter. [REMARKS] - Note. Every time MaxDelay is changed, the plugin re-allocates the delay buffer. This means the delay will dissapear at that time while it refills its new buffer.
    - A larger MaxDelay results in larger amounts of memory allocated.
    - Channel delays above MaxDelay will be clipped to MaxDelay and the delay buffer will not be resized.
    -
    + Note. Every time MaxDelay is changed, the plugin re-allocates the delay +buffer. This means the delay will dissapear at that time while it refills its +new buffer.
    A larger MaxDelay results in larger amounts of memory +allocated.
    Channel delays above MaxDelay will be clipped to MaxDelay and the +delay buffer will not be resized.

    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] DSP::setParameter DSP::getParameter FMOD_DSP_TYPE ] */ -typedef enum -{ - FMOD_DSP_DELAY_CH0, /* Channel #0 Delay in ms. 0 to 10000. Default = 0. */ - FMOD_DSP_DELAY_CH1, /* Channel #1 Delay in ms. 0 to 10000. Default = 0. */ - FMOD_DSP_DELAY_CH2, /* Channel #2 Delay in ms. 0 to 10000. Default = 0. */ - FMOD_DSP_DELAY_CH3, /* Channel #3 Delay in ms. 0 to 10000. Default = 0. */ - FMOD_DSP_DELAY_CH4, /* Channel #4 Delay in ms. 0 to 10000. Default = 0. */ - FMOD_DSP_DELAY_CH5, /* Channel #5 Delay in ms. 0 to 10000. Default = 0. */ - FMOD_DSP_DELAY_CH6, /* Channel #6 Delay in ms. 0 to 10000. Default = 0. */ - FMOD_DSP_DELAY_CH7, /* Channel #7 Delay in ms. 0 to 10000. Default = 0. */ - FMOD_DSP_DELAY_CH8, /* Channel #8 Delay in ms. 0 to 10000. Default = 0. */ - FMOD_DSP_DELAY_CH9, /* Channel #9 Delay in ms. 0 to 10000. Default = 0. */ - FMOD_DSP_DELAY_CH10, /* Channel #10 Delay in ms. 0 to 10000. Default = 0. */ - FMOD_DSP_DELAY_CH11, /* Channel #11 Delay in ms. 0 to 10000. Default = 0. */ - FMOD_DSP_DELAY_CH12, /* Channel #12 Delay in ms. 0 to 10000. Default = 0. */ - FMOD_DSP_DELAY_CH13, /* Channel #13 Delay in ms. 0 to 10000. Default = 0. */ - FMOD_DSP_DELAY_CH14, /* Channel #14 Delay in ms. 0 to 10000. Default = 0. */ - FMOD_DSP_DELAY_CH15, /* Channel #15 Delay in ms. 0 to 10000. Default = 0. */ - FMOD_DSP_DELAY_MAXDELAY /* Maximum delay in ms. 0 to 10000. Default = 10. */ +typedef enum { + FMOD_DSP_DELAY_CH0, /* Channel #0 Delay in ms. 0 to 10000. Default = 0. */ + FMOD_DSP_DELAY_CH1, /* Channel #1 Delay in ms. 0 to 10000. Default = 0. */ + FMOD_DSP_DELAY_CH2, /* Channel #2 Delay in ms. 0 to 10000. Default = 0. */ + FMOD_DSP_DELAY_CH3, /* Channel #3 Delay in ms. 0 to 10000. Default = 0. */ + FMOD_DSP_DELAY_CH4, /* Channel #4 Delay in ms. 0 to 10000. Default = 0. */ + FMOD_DSP_DELAY_CH5, /* Channel #5 Delay in ms. 0 to 10000. Default = 0. */ + FMOD_DSP_DELAY_CH6, /* Channel #6 Delay in ms. 0 to 10000. Default = 0. */ + FMOD_DSP_DELAY_CH7, /* Channel #7 Delay in ms. 0 to 10000. Default = 0. */ + FMOD_DSP_DELAY_CH8, /* Channel #8 Delay in ms. 0 to 10000. Default = 0. */ + FMOD_DSP_DELAY_CH9, /* Channel #9 Delay in ms. 0 to 10000. Default = 0. */ + FMOD_DSP_DELAY_CH10, /* Channel #10 Delay in ms. 0 to 10000. Default = 0. + */ + FMOD_DSP_DELAY_CH11, /* Channel #11 Delay in ms. 0 to 10000. Default = 0. + */ + FMOD_DSP_DELAY_CH12, /* Channel #12 Delay in ms. 0 to 10000. Default = 0. + */ + FMOD_DSP_DELAY_CH13, /* Channel #13 Delay in ms. 0 to 10000. Default = 0. + */ + FMOD_DSP_DELAY_CH14, /* Channel #14 Delay in ms. 0 to 10000. Default = 0. + */ + FMOD_DSP_DELAY_CH15, /* Channel #15 Delay in ms. 0 to 10000. Default = 0. + */ + FMOD_DSP_DELAY_MAXDELAY /* Maximum delay in ms. 0 to 10000. Default = 10. + */ } FMOD_DSP_DELAY; - /* [ENUM] -[ - [DESCRIPTION] +[ + [DESCRIPTION] Parameter types for the FMOD_DSP_TYPE_FLANGE filter. [REMARKS] - Flange is an effect where the signal is played twice at the same time, and one copy slides back and forth creating a whooshing or flanging effect.
    - As there are 2 copies of the same signal, by default each signal is given 50% mix, so that the total is not louder than the original unaffected signal.
    -
    - Flange depth is a percentage of a 10ms shift from the original signal. Anything above 10ms is not considered flange because to the ear it begins to 'echo' so 10ms is the highest value possible.
    + Flange is an effect where the signal is played twice at the same time, and +one copy slides back and forth creating a whooshing or flanging effect.
    As +there are 2 copies of the same signal, by default each signal is given 50% mix, +so that the total is not louder than the original unaffected signal.

    + Flange depth is a percentage of a 10ms shift from the original signal. +Anything above 10ms is not considered flange because to the ear it begins to +'echo' so 10ms is the highest value possible.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] DSP::setParameter DSP::getParameter FMOD_DSP_TYPE ] */ -typedef enum -{ - FMOD_DSP_FLANGE_DRYMIX, /* Volume of original signal to pass to output. 0.0 to 1.0. Default = 0.45. */ - FMOD_DSP_FLANGE_WETMIX, /* Volume of flange signal to pass to output. 0.0 to 1.0. Default = 0.55. */ - FMOD_DSP_FLANGE_DEPTH, /* Flange depth (percentage of 40ms delay). 0.01 to 1.0. Default = 1.0. */ - FMOD_DSP_FLANGE_RATE /* Flange speed in hz. 0.0 to 20.0. Default = 0.1. */ +typedef enum { + FMOD_DSP_FLANGE_DRYMIX, /* Volume of original signal to pass to output. 0.0 + to 1.0. Default = 0.45. */ + FMOD_DSP_FLANGE_WETMIX, /* Volume of flange signal to pass to output. 0.0 + to 1.0. Default = 0.55. */ + FMOD_DSP_FLANGE_DEPTH, /* Flange depth (percentage of 40ms delay). 0.01 + to 1.0. Default = 1.0. */ + FMOD_DSP_FLANGE_RATE /* Flange speed in hz. 0.0 to 20.0. Default = 0.1. */ } FMOD_DSP_FLANGE; - /* [ENUM] -[ - [DESCRIPTION] +[ + [DESCRIPTION] Parameter types for the FMOD_DSP_TYPE_TREMOLO filter. [REMARKS] - The tremolo effect varies the amplitude of a sound. Depending on the settings, this unit can produce a tremolo, chopper or auto-pan effect.
    -
    - The shape of the LFO (low freq. oscillator) can morphed between sine, triangle and sawtooth waves using the FMOD_DSP_TREMOLO_SHAPE and FMOD_DSP_TREMOLO_SKEW parameters.
    - FMOD_DSP_TREMOLO_DUTY and FMOD_DSP_TREMOLO_SQUARE are useful for a chopper-type effect where the first controls the on-time duration and second controls the flatness of the envelope.
    - FMOD_DSP_TREMOLO_SPREAD varies the LFO phase between channels to get an auto-pan effect. This works best with a sine shape LFO.
    - The LFO can be synchronized using the FMOD_DSP_TREMOLO_PHASE parameter which sets its instantaneous phase.
    + The tremolo effect varies the amplitude of a sound. Depending on the +settings, this unit can produce a tremolo, chopper or auto-pan effect.

    + The shape of the LFO (low freq. oscillator) can morphed between sine, +triangle and sawtooth waves using the FMOD_DSP_TREMOLO_SHAPE and +FMOD_DSP_TREMOLO_SKEW parameters.
    FMOD_DSP_TREMOLO_DUTY and +FMOD_DSP_TREMOLO_SQUARE are useful for a chopper-type effect where the first +controls the on-time duration and second controls the flatness of the +envelope.
    FMOD_DSP_TREMOLO_SPREAD varies the LFO phase between channels to +get an auto-pan effect. This works best with a sine shape LFO.
    The LFO can +be synchronized using the FMOD_DSP_TREMOLO_PHASE parameter which sets its +instantaneous phase.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] DSP::setParameter DSP::getParameter FMOD_DSP_TYPE ] */ -typedef enum -{ - FMOD_DSP_TREMOLO_FREQUENCY, /* LFO frequency in Hz. 0.1 to 20. Default = 4. */ - FMOD_DSP_TREMOLO_DEPTH, /* Tremolo depth. 0 to 1. Default = 0. */ - FMOD_DSP_TREMOLO_SHAPE, /* LFO shape morph between triangle and sine. 0 to 1. Default = 0. */ - FMOD_DSP_TREMOLO_SKEW, /* Time-skewing of LFO cycle. -1 to 1. Default = 0. */ - FMOD_DSP_TREMOLO_DUTY, /* LFO on-time. 0 to 1. Default = 0.5. */ - FMOD_DSP_TREMOLO_SQUARE, /* Flatness of the LFO shape. 0 to 1. Default = 0. */ - FMOD_DSP_TREMOLO_PHASE, /* Instantaneous LFO phase. 0 to 1. Default = 0. */ - FMOD_DSP_TREMOLO_SPREAD /* Rotation / auto-pan effect. -1 to 1. Default = 0. */ +typedef enum { + FMOD_DSP_TREMOLO_FREQUENCY, /* LFO frequency in Hz. 0.1 to 20. Default = 4. + */ + FMOD_DSP_TREMOLO_DEPTH, /* Tremolo depth. 0 to 1. Default = 0. */ + FMOD_DSP_TREMOLO_SHAPE, /* LFO shape morph between triangle and sine. 0 to 1. + Default = 0. */ + FMOD_DSP_TREMOLO_SKEW, /* Time-skewing of LFO cycle. -1 to 1. Default = 0. + */ + FMOD_DSP_TREMOLO_DUTY, /* LFO on-time. 0 to 1. Default = 0.5. */ + FMOD_DSP_TREMOLO_SQUARE, /* Flatness of the LFO shape. 0 to 1. Default = 0. + */ + FMOD_DSP_TREMOLO_PHASE, /* Instantaneous LFO phase. 0 to 1. Default = 0. */ + FMOD_DSP_TREMOLO_SPREAD /* Rotation / auto-pan effect. -1 to 1. Default = 0. + */ } FMOD_DSP_TREMOLO; - /* [ENUM] -[ - [DESCRIPTION] +[ + [DESCRIPTION] Parameter types for the FMOD_DSP_TYPE_DISTORTION filter. [REMARKS] [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] DSP::setParameter DSP::getParameter FMOD_DSP_TYPE ] */ -typedef enum -{ - FMOD_DSP_DISTORTION_LEVEL /* Distortion value. 0.0 to 1.0. Default = 0.5. */ +typedef enum { + FMOD_DSP_DISTORTION_LEVEL /* Distortion value. 0.0 to 1.0. Default = 0.5. */ } FMOD_DSP_DISTORTION; - /* [ENUM] -[ - [DESCRIPTION] +[ + [DESCRIPTION] Parameter types for the FMOD_DSP_TYPE_NORMALIZE filter. [REMARKS] - Normalize amplifies the sound based on the maximum peaks within the signal.
    - For example if the maximum peaks in the signal were 50% of the bandwidth, it would scale the whole sound by 2.
    - The lower threshold value makes the normalizer ignores peaks below a certain point, to avoid over-amplification if a loud signal suddenly came in, and also to avoid amplifying to maximum things like background hiss.
    -
    - Because FMOD is a realtime audio processor, it doesn't have the luxury of knowing the peak for the whole sound (ie it can't see into the future), so it has to process data as it comes in.
    - To avoid very sudden changes in volume level based on small samples of new data, fmod fades towards the desired amplification which makes for smooth gain control. The fadetime parameter can control this.
    + Normalize amplifies the sound based on the maximum peaks within the +signal.
    For example if the maximum peaks in the signal were 50% of the +bandwidth, it would scale the whole sound by 2.
    The lower threshold value +makes the normalizer ignores peaks below a certain point, to avoid +over-amplification if a loud signal suddenly came in, and also to avoid +amplifying to maximum things like background hiss.

    Because FMOD is a +realtime audio processor, it doesn't have the luxury of knowing the peak for the +whole sound (ie it can't see into the future), so it has to process data as it +comes in.
    To avoid very sudden changes in volume level based on small +samples of new data, fmod fades towards the desired amplification which makes +for smooth gain control. The fadetime parameter can control this.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] DSP::setParameter DSP::getParameter FMOD_DSP_TYPE ] */ -typedef enum -{ - FMOD_DSP_NORMALIZE_FADETIME, /* Time to ramp the silence to full in ms. 0.0 to 20000.0. Default = 5000.0. */ - FMOD_DSP_NORMALIZE_THRESHHOLD, /* Lower volume range threshold to ignore. 0.0 to 1.0. Default = 0.1. Raise higher to stop amplification of very quiet signals. */ - FMOD_DSP_NORMALIZE_MAXAMP /* Maximum amplification allowed. 1.0 to 100000.0. Default = 20.0. 1.0 = no amplifaction, higher values allow more boost. */ +typedef enum { + FMOD_DSP_NORMALIZE_FADETIME, /* Time to ramp the silence to full in ms. 0.0 + to 20000.0. Default = 5000.0. */ + FMOD_DSP_NORMALIZE_THRESHHOLD, /* Lower volume range threshold to ignore. 0.0 + to 1.0. Default = 0.1. Raise higher to + stop amplification of very quiet signals. */ + FMOD_DSP_NORMALIZE_MAXAMP /* Maximum amplification allowed. 1.0 to 100000.0. + Default = 20.0. 1.0 = no amplifaction, higher + values allow more boost. */ } FMOD_DSP_NORMALIZE; - /* [ENUM] -[ - [DESCRIPTION] +[ + [DESCRIPTION] Parameter types for the FMOD_DSP_TYPE_PARAMEQ filter. [REMARKS] - Parametric EQ is a bandpass filter that attenuates or amplifies a selected frequency and its neighbouring frequencies.
    -
    - To create a multi-band EQ create multiple FMOD_DSP_TYPE_PARAMEQ units and set each unit to different frequencies, for example 1000hz, 2000hz, 4000hz, 8000hz, 16000hz with a range of 1 octave each.
    -
    - When a frequency has its gain set to 1.0, the sound will be unaffected and represents the original signal exactly.
    + Parametric EQ is a bandpass filter that attenuates or amplifies a selected +frequency and its neighbouring frequencies.

    To create a multi-band EQ +create multiple FMOD_DSP_TYPE_PARAMEQ units and set each unit to different +frequencies, for example 1000hz, 2000hz, 4000hz, 8000hz, 16000hz with a range of +1 octave each.

    When a frequency has its gain set to 1.0, the sound will +be unaffected and represents the original signal exactly.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] DSP::setParameter DSP::getParameter FMOD_DSP_TYPE ] */ -typedef enum -{ - FMOD_DSP_PARAMEQ_CENTER, /* Frequency center. 20.0 to 22000.0. Default = 8000.0. */ - FMOD_DSP_PARAMEQ_BANDWIDTH, /* Octave range around the center frequency to filter. 0.2 to 5.0. Default = 1.0. */ - FMOD_DSP_PARAMEQ_GAIN /* Frequency Gain. 0.05 to 3.0. Default = 1.0. */ +typedef enum { + FMOD_DSP_PARAMEQ_CENTER, /* Frequency center. 20.0 to 22000.0. Default = + 8000.0. */ + FMOD_DSP_PARAMEQ_BANDWIDTH, /* Octave range around the center frequency to + filter. 0.2 to 5.0. Default = 1.0. */ + FMOD_DSP_PARAMEQ_GAIN /* Frequency Gain. 0.05 to 3.0. Default = 1.0. */ } FMOD_DSP_PARAMEQ; - - /* [ENUM] -[ - [DESCRIPTION] +[ + [DESCRIPTION] Parameter types for the FMOD_DSP_TYPE_PITCHSHIFT filter. [REMARKS] - This pitch shifting unit can be used to change the pitch of a sound without speeding it up or slowing it down.
    - It can also be used for time stretching or scaling, for example if the pitch was doubled, and the frequency of the sound was halved, the pitch of the sound would sound correct but it would be twice as slow.
    -
    - Warning! This filter is very computationally expensive! Similar to a vocoder, it requires several overlapping FFT and IFFT's to produce smooth output, and can require around 440mhz for 1 stereo 48khz signal using the default settings.
    - Reducing the signal to mono will half the cpu usage.
    - Reducing this will lower audio quality, but what settings to use are largely dependant on the sound being played. A noisy polyphonic signal will need higher fft size compared to a speaking voice for example.
    -
    - This pitch shifter is based on the pitch shifter code at http://www.dspdimension.com, written by Stephan M. Bernsee.
    - The original code is COPYRIGHT 1999-2003 Stephan M. Bernsee .
    -
    - 'maxchannels' dictates the amount of memory allocated. By default, the maxchannels value is 0. If FMOD is set to stereo, the pitch shift unit will allocate enough memory for 2 channels. If it is 5.1, it will allocate enough memory for a 6 channel pitch shift, etc.
    - If the pitch shift effect is only ever applied to the global mix (ie it was added with System::addDSP), then 0 is the value to set as it will be enough to handle all speaker modes.
    - When the pitch shift is added to a channel (ie Channel::addDSP) then the channel count that comes in could be anything from 1 to 8 possibly. It is only in this case where you might want to increase the channel count above the output's channel count.
    - If a channel pitch shift is set to a lower number than the sound's channel count that is coming in, it will not pitch shift the sound.
    + This pitch shifting unit can be used to change the pitch of a sound without +speeding it up or slowing it down.
    It can also be used for time stretching +or scaling, for example if the pitch was doubled, and the frequency of the sound +was halved, the pitch of the sound would sound correct but it would be twice as +slow.

    Warning! This filter is very computationally expensive! +Similar to a vocoder, it requires several overlapping FFT and IFFT's to produce +smooth output, and can require around 440mhz for 1 stereo 48khz signal using the +default settings.
    Reducing the signal to mono will half the cpu usage.
    + Reducing this will lower audio quality, but what settings to use are largely +dependant on the sound being played. A noisy polyphonic signal will need higher +fft size compared to a speaking voice for example.

    This pitch shifter +is based on the pitch shifter code at http://www.dspdimension.com, written by +Stephan M. Bernsee.
    The original code is COPYRIGHT 1999-2003 Stephan M. +Bernsee .

    + 'maxchannels' dictates the amount of memory allocated. By default, +the maxchannels value is 0. If FMOD is set to stereo, the pitch shift unit will +allocate enough memory for 2 channels. If it is 5.1, it will allocate enough +memory for a 6 channel pitch shift, etc.
    If the pitch shift effect is only +ever applied to the global mix (ie it was added with System::addDSP), then 0 is +the value to set as it will be enough to handle all speaker modes.
    When the +pitch shift is added to a channel (ie Channel::addDSP) then the channel count +that comes in could be anything from 1 to 8 possibly. It is only in this case +where you might want to increase the channel count above the output's channel +count.
    If a channel pitch shift is set to a lower number than the sound's +channel count that is coming in, it will not pitch shift the sound.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] DSP::setParameter DSP::getParameter FMOD_DSP_TYPE ] */ -typedef enum -{ - FMOD_DSP_PITCHSHIFT_PITCH, /* Pitch value. 0.5 to 2.0. Default = 1.0. 0.5 = one octave down, 2.0 = one octave up. 1.0 does not change the pitch. */ - FMOD_DSP_PITCHSHIFT_FFTSIZE, /* FFT window size. 256, 512, 1024, 2048, 4096. Default = 1024. Increase this to reduce 'smearing'. This effect is a warbling sound similar to when an mp3 is encoded at very low bitrates. */ - FMOD_DSP_PITCHSHIFT_OVERLAP, /* Removed. Do not use. FMOD now uses 4 overlaps and cannot be changed. */ - FMOD_DSP_PITCHSHIFT_MAXCHANNELS /* Maximum channels supported. 0 to 16. 0 = same as fmod's default output polyphony, 1 = mono, 2 = stereo etc. See remarks for more. Default = 0. It is suggested to leave at 0! */ +typedef enum { + FMOD_DSP_PITCHSHIFT_PITCH, /* Pitch value. 0.5 to 2.0. Default = 1.0. 0.5 = + one octave down, 2.0 = one octave up. 1.0 does + not change the pitch. */ + FMOD_DSP_PITCHSHIFT_FFTSIZE, /* FFT window size. 256, 512, 1024, 2048, 4096. + Default = 1024. Increase this to reduce + 'smearing'. This effect is a warbling sound + similar to when an mp3 is encoded at very low + bitrates. */ + FMOD_DSP_PITCHSHIFT_OVERLAP, /* Removed. Do not use. FMOD now uses 4 + overlaps and cannot be changed. */ + FMOD_DSP_PITCHSHIFT_MAXCHANNELS /* Maximum channels supported. 0 to 16. 0 = + same as fmod's default output polyphony, 1 + = mono, 2 = stereo etc. See remarks for + more. Default = 0. It is suggested to + leave at 0! */ } FMOD_DSP_PITCHSHIFT; - - /* [ENUM] -[ - [DESCRIPTION] +[ + [DESCRIPTION] Parameter types for the FMOD_DSP_TYPE_CHORUS filter. [REMARKS] - Chrous is an effect where the sound is more 'spacious' due to 1 to 3 versions of the sound being played along side the original signal but with the pitch of each copy modulating on a sine wave.
    + Chrous is an effect where the sound is more 'spacious' due to 1 to 3 +versions of the sound being played along side the original signal but with the +pitch of each copy modulating on a sine wave.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] DSP::setParameter DSP::getParameter FMOD_DSP_TYPE ] */ -typedef enum -{ - FMOD_DSP_CHORUS_DRYMIX, /* Volume of original signal to pass to output. 0.0 to 1.0. Default = 0.5. */ - FMOD_DSP_CHORUS_WETMIX1, /* Volume of 1st chorus tap. 0.0 to 1.0. Default = 0.5. */ - FMOD_DSP_CHORUS_WETMIX2, /* Volume of 2nd chorus tap. This tap is 90 degrees out of phase of the first tap. 0.0 to 1.0. Default = 0.5. */ - FMOD_DSP_CHORUS_WETMIX3, /* Volume of 3rd chorus tap. This tap is 90 degrees out of phase of the second tap. 0.0 to 1.0. Default = 0.5. */ - FMOD_DSP_CHORUS_DELAY, /* Chorus delay in ms. 0.1 to 100.0. Default = 40.0 ms. */ - FMOD_DSP_CHORUS_RATE, /* Chorus modulation rate in hz. 0.0 to 20.0. Default = 0.8 hz. */ - FMOD_DSP_CHORUS_DEPTH /* Chorus modulation depth. 0.0 to 1.0. Default = 0.03. */ +typedef enum { + FMOD_DSP_CHORUS_DRYMIX, /* Volume of original signal to pass to output. 0.0 + to 1.0. Default = 0.5. */ + FMOD_DSP_CHORUS_WETMIX1, /* Volume of 1st chorus tap. 0.0 to 1.0. Default = + 0.5. */ + FMOD_DSP_CHORUS_WETMIX2, /* Volume of 2nd chorus tap. This tap is 90 degrees + out of phase of the first tap. 0.0 to 1.0. + Default = 0.5. */ + FMOD_DSP_CHORUS_WETMIX3, /* Volume of 3rd chorus tap. This tap is 90 degrees + out of phase of the second tap. 0.0 to 1.0. + Default = 0.5. */ + FMOD_DSP_CHORUS_DELAY, /* Chorus delay in ms. 0.1 to 100.0. Default = 40.0 + ms. */ + FMOD_DSP_CHORUS_RATE, /* Chorus modulation rate in hz. 0.0 to 20.0. Default + = 0.8 hz. */ + FMOD_DSP_CHORUS_DEPTH /* Chorus modulation depth. 0.0 to 1.0. Default = + 0.03. */ } FMOD_DSP_CHORUS; - /* [ENUM] -[ - [DESCRIPTION] +[ + [DESCRIPTION] Parameter types for the FMOD_DSP_TYPE_ITECHO filter.
    - This is effectively a software based echo filter that emulates the DirectX DMO echo effect. Impulse tracker files can support this, and FMOD will produce the effect on ANY platform, not just those that support DirectX effects!
    + This is effectively a software based echo filter that emulates the DirectX +DMO echo effect. Impulse tracker files can support this, and FMOD will produce +the effect on ANY platform, not just those that support DirectX effects!
    [REMARKS] - Note. Every time the delay is changed, the plugin re-allocates the echo buffer. This means the echo will dissapear at that time while it refills its new buffer.
    - Larger echo delays result in larger amounts of memory allocated.
    -
    - As this is a stereo filter made mainly for IT playback, it is targeted for stereo signals.
    - With mono signals only the FMOD_DSP_ITECHO_LEFTDELAY is used.
    - For multichannel signals (>2) there will be no echo on those channels.
    + Note. Every time the delay is changed, the plugin re-allocates the echo +buffer. This means the echo will dissapear at that time while it refills its +new buffer.
    Larger echo delays result in larger amounts of memory +allocated.

    As this is a stereo filter made mainly for IT playback, it +is targeted for stereo signals.
    With mono signals only the +FMOD_DSP_ITECHO_LEFTDELAY is used.
    For multichannel signals (>2) there will +be no echo on those channels.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] DSP::SetParameter DSP::GetParameter FMOD_DSP_TYPE System::addDSP ] */ -typedef enum -{ - FMOD_DSP_ITECHO_WETDRYMIX, /* Ratio of wet (processed) signal to dry (unprocessed) signal. Must be in the range from 0.0 through 100.0 (all wet). The default value is 50. */ - FMOD_DSP_ITECHO_FEEDBACK, /* Percentage of output fed back into input, in the range from 0.0 through 100.0. The default value is 50. */ - FMOD_DSP_ITECHO_LEFTDELAY, /* Delay for left channel, in milliseconds, in the range from 1.0 through 2000.0. The default value is 500 ms. */ - FMOD_DSP_ITECHO_RIGHTDELAY, /* Delay for right channel, in milliseconds, in the range from 1.0 through 2000.0. The default value is 500 ms. */ - FMOD_DSP_ITECHO_PANDELAY /* Value that specifies whether to swap left and right delays with each successive echo. The default value is zero, meaning no swap. Possible values are defined as 0.0 (equivalent to FALSE) and 1.0 (equivalent to TRUE). CURRENTLY NOT SUPPORTED. */ +typedef enum { + FMOD_DSP_ITECHO_WETDRYMIX, /* Ratio of wet (processed) signal to dry + (unprocessed) signal. Must be in the range from + 0.0 through 100.0 (all wet). The default value + is 50. */ + FMOD_DSP_ITECHO_FEEDBACK, /* Percentage of output fed back into input, in the + range from 0.0 through 100.0. The default value + is 50. */ + FMOD_DSP_ITECHO_LEFTDELAY, /* Delay for left channel, in milliseconds, in the + range from 1.0 through 2000.0. The default value + is 500 ms. */ + FMOD_DSP_ITECHO_RIGHTDELAY, /* Delay for right channel, in milliseconds, in + the range from 1.0 through 2000.0. The default + value is 500 ms. */ + FMOD_DSP_ITECHO_PANDELAY /* Value that specifies whether to swap left and + right delays with each successive echo. The + default value is zero, meaning no swap. Possible + values are defined as 0.0 (equivalent to FALSE) + and 1.0 (equivalent to TRUE). CURRENTLY NOT + SUPPORTED. */ } FMOD_DSP_ITECHO; /* [ENUM] -[ - [DESCRIPTION] +[ + [DESCRIPTION] Parameter types for the FMOD_DSP_TYPE_COMPRESSOR unit. - This is a simple linked multichannel software limiter that is uniform across the whole spectrum.
    + This is a simple linked multichannel software limiter that is uniform across +the whole spectrum.
    [REMARKS] The limiter is not guaranteed to catch every peak above the threshold level, because it cannot apply gain reduction instantaneously - the time delay is - determined by the attack time. However setting the attack time too short will - distort the sound, so it is a compromise. High level peaks can be avoided by - using a short attack time - but not too short, and setting the threshold a few - decibels below the critical level. -
    + determined by the attack time. However setting the attack time too short +will distort the sound, so it is a compromise. High level peaks can be avoided +by using a short attack time - but not too short, and setting the threshold a +few decibels below the critical level.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] DSP::SetParameter DSP::GetParameter FMOD_DSP_TYPE System::addDSP ] */ -typedef enum -{ - FMOD_DSP_COMPRESSOR_THRESHOLD, /* Threshold level (dB) in the range from -60 through 0. The default value is 0. */ - FMOD_DSP_COMPRESSOR_ATTACK, /* Gain reduction attack time (milliseconds), in the range from 10 through 200. The default value is 50. */ - FMOD_DSP_COMPRESSOR_RELEASE, /* Gain reduction release time (milliseconds), in the range from 20 through 1000. The default value is 50. */ - FMOD_DSP_COMPRESSOR_GAINMAKEUP /* Make-up gain (dB) applied after limiting, in the range from 0 through 30. The default value is 0. */ +typedef enum { + FMOD_DSP_COMPRESSOR_THRESHOLD, /* Threshold level (dB) in the range from -60 + through 0. The default value is 0. */ + FMOD_DSP_COMPRESSOR_ATTACK, /* Gain reduction attack time (milliseconds), in + the range from 10 through 200. The default + value is 50. */ + FMOD_DSP_COMPRESSOR_RELEASE, /* Gain reduction release time (milliseconds), in + the range from 20 through 1000. The default + value is 50. */ + FMOD_DSP_COMPRESSOR_GAINMAKEUP /* Make-up gain (dB) applied after limiting, in + the range from 0 through 30. The default + value is 0. */ } FMOD_DSP_COMPRESSOR; /* [ENUM] -[ - [DESCRIPTION] +[ + [DESCRIPTION] Parameter types for the FMOD_DSP_TYPE_SFXREVERB unit.
    - + [REMARKS] This is a high quality I3DL2 based reverb.
    - On top of the I3DL2 property set, "Dry Level" is also included to allow the dry mix to be changed.
    -
    - These properties can be set with presets in FMOD_REVERB_PRESETS. + On top of the I3DL2 property set, "Dry Level" is also included to allow the +dry mix to be changed.

    These properties can be set with presets in +FMOD_REVERB_PRESETS. [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] DSP::SetParameter DSP::GetParameter FMOD_DSP_TYPE @@ -676,71 +868,103 @@ typedef enum FMOD_REVERB_PRESETS ] */ -typedef enum -{ - FMOD_DSP_SFXREVERB_DRYLEVEL, /* Dry Level : Mix level of dry signal in output in mB. Ranges from -10000.0 to 0.0. Default is 0. */ - FMOD_DSP_SFXREVERB_ROOM, /* Room : Room effect level at low frequencies in mB. Ranges from -10000.0 to 0.0. Default is -10000.0. */ - FMOD_DSP_SFXREVERB_ROOMHF, /* Room HF : Room effect high-frequency level re. low frequency level in mB. Ranges from -10000.0 to 0.0. Default is 0.0. */ - FMOD_DSP_SFXREVERB_DECAYTIME, /* Decay Time : Reverberation decay time at low-frequencies in seconds. Ranges from 0.1 to 20.0. Default is 1.0. */ - FMOD_DSP_SFXREVERB_DECAYHFRATIO, /* Decay HF Ratio : High-frequency to low-frequency decay time ratio. Ranges from 0.1 to 2.0. Default is 0.5. */ - FMOD_DSP_SFXREVERB_REFLECTIONSLEVEL, /* Reflections : Early reflections level relative to room effect in mB. Ranges from -10000.0 to 1000.0. Default is -10000.0. */ - FMOD_DSP_SFXREVERB_REFLECTIONSDELAY, /* Reflect Delay : Delay time of first reflection in seconds. Ranges from 0.0 to 0.3. Default is 0.02. */ - FMOD_DSP_SFXREVERB_REVERBLEVEL, /* Reverb : Late reverberation level relative to room effect in mB. Ranges from -10000.0 to 2000.0. Default is 0.0. */ - FMOD_DSP_SFXREVERB_REVERBDELAY, /* Reverb Delay : Late reverberation delay time relative to first reflection in seconds. Ranges from 0.0 to 0.1. Default is 0.04. */ - FMOD_DSP_SFXREVERB_DIFFUSION, /* Diffusion : Reverberation diffusion (echo density) in percent. Ranges from 0.0 to 100.0. Default is 100.0. */ - FMOD_DSP_SFXREVERB_DENSITY, /* Density : Reverberation density (modal density) in percent. Ranges from 0.0 to 100.0. Default is 100.0. */ - FMOD_DSP_SFXREVERB_HFREFERENCE, /* HF Reference : Reference high frequency in Hz. Ranges from 20.0 to 20000.0. Default is 5000.0. */ - FMOD_DSP_SFXREVERB_ROOMLF, /* Room LF : Room effect low-frequency level in mB. Ranges from -10000.0 to 0.0. Default is 0.0. */ - FMOD_DSP_SFXREVERB_LFREFERENCE /* LF Reference : Reference low-frequency in Hz. Ranges from 20.0 to 1000.0. Default is 250.0. */ +typedef enum { + FMOD_DSP_SFXREVERB_DRYLEVEL, /* Dry Level : Mix level of dry signal in + output in mB. Ranges from -10000.0 to 0.0. + Default is 0. */ + FMOD_DSP_SFXREVERB_ROOM, /* Room : Room effect level at low + frequencies in mB. Ranges from -10000.0 to 0.0. + Default is -10000.0. */ + FMOD_DSP_SFXREVERB_ROOMHF, /* Room HF : Room effect high-frequency + level re. low frequency level in mB. Ranges + from -10000.0 to 0.0. Default is 0.0. */ + FMOD_DSP_SFXREVERB_DECAYTIME, /* Decay Time : Reverberation decay time at + low-frequencies in seconds. Ranges from 0.1 + to 20.0. Default is 1.0. */ + FMOD_DSP_SFXREVERB_DECAYHFRATIO, /* Decay HF Ratio : High-frequency to + low-frequency decay time ratio. Ranges + from 0.1 to 2.0. Default is 0.5. */ + FMOD_DSP_SFXREVERB_REFLECTIONSLEVEL, /* Reflections : Early reflections + level relative to room effect in mB. + Ranges from -10000.0 to 1000.0. + Default is -10000.0. */ + FMOD_DSP_SFXREVERB_REFLECTIONSDELAY, /* Reflect Delay : Delay time of first + reflection in seconds. Ranges from + 0.0 to 0.3. Default is 0.02. */ + FMOD_DSP_SFXREVERB_REVERBLEVEL, /* Reverb : Late reverberation level + relative to room effect in mB. Ranges from + -10000.0 to 2000.0. Default is 0.0. */ + FMOD_DSP_SFXREVERB_REVERBDELAY, /* Reverb Delay : Late reverberation delay + time relative to first reflection in + seconds. Ranges from 0.0 to 0.1. Default + is 0.04. */ + FMOD_DSP_SFXREVERB_DIFFUSION, /* Diffusion : Reverberation diffusion + (echo density) in percent. Ranges from 0.0 + to 100.0. Default is 100.0. */ + FMOD_DSP_SFXREVERB_DENSITY, /* Density : Reverberation density (modal + density) in percent. Ranges from 0.0 to 100.0. + Default is 100.0. */ + FMOD_DSP_SFXREVERB_HFREFERENCE, /* HF Reference : Reference high frequency + in Hz. Ranges from 20.0 to 20000.0. + Default is 5000.0. */ + FMOD_DSP_SFXREVERB_ROOMLF, /* Room LF : Room effect low-frequency level + in mB. Ranges from -10000.0 to 0.0. Default is + 0.0. */ + FMOD_DSP_SFXREVERB_LFREFERENCE /* LF Reference : Reference low-frequency in + Hz. Ranges from 20.0 to 1000.0. Default is + 250.0. */ } FMOD_DSP_SFXREVERB; /* [ENUM] -[ - [DESCRIPTION] +[ + [DESCRIPTION] Parameter types for the FMOD_DSP_TYPE_LOWPASS_SIMPLE filter.
    - This is a very simple low pass filter, based on two single-pole RC time-constant modules. - The emphasis is on speed rather than accuracy, so this should not be used for task requiring critical filtering.
    + This is a very simple low pass filter, based on two single-pole RC +time-constant modules. The emphasis is on speed rather than accuracy, so this +should not be used for task requiring critical filtering.
    [REMARKS] [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] DSP::setParameter DSP::getParameter FMOD_DSP_TYPE ] */ -typedef enum -{ - FMOD_DSP_LOWPASS_SIMPLE_CUTOFF /* Lowpass cutoff frequency in hz. 10.0 to 22000.0. Default = 5000.0 */ +typedef enum { + FMOD_DSP_LOWPASS_SIMPLE_CUTOFF /* Lowpass cutoff frequency in hz. 10.0 to + 22000.0. Default = 5000.0 */ } FMOD_DSP_LOWPASS_SIMPLE; /* [ENUM] -[ - [DESCRIPTION] +[ + [DESCRIPTION] Parameter types for the FMOD_DSP_TYPE_HIGHPASS_SIMPLE filter.
    This is a very simple single-order high pass filter. - The emphasis is on speed rather than accuracy, so this should not be used for task requiring critical filtering.
    + The emphasis is on speed rather than accuracy, so this should not be used +for task requiring critical filtering.
    [REMARKS] [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android - [SEE_ALSO] + [SEE_ALSO] DSP::setParameter DSP::getParameter FMOD_DSP_TYPE ] */ -typedef enum -{ - FMOD_DSP_HIGHPASS_SIMPLE_CUTOFF /* Highpass cutoff frequency in hz. 10.0 to 22000.0. Default = 1000.0 */ +typedef enum { + FMOD_DSP_HIGHPASS_SIMPLE_CUTOFF /* Highpass cutoff frequency in hz. 10.0 to + 22000.0. Default = 1000.0 */ } FMOD_DSP_HIGHPASS_SIMPLE; #endif - diff --git a/src/imports/fmodex/fmod_errors.h b/src/imports/fmodex/fmod_errors.h index 36c8a6f..de21914 100644 --- a/src/imports/fmodex/fmod_errors.h +++ b/src/imports/fmodex/fmod_errors.h @@ -1,126 +1,290 @@ /*$ preserve start $*/ -/* ============================================================================================== */ -/* FMOD Ex - Error string header file. Copyright (c), Firelight Technologies Pty, Ltd. 2004-2016. */ +/* ============================================================================================== + */ +/* FMOD Ex - Error string header file. Copyright (c), Firelight Technologies + * Pty, Ltd. 2004-2016. */ /* */ -/* Use this header if you want to store or display a string version / english explanation of */ -/* the FMOD error codes. */ +/* Use this header if you want to store or display a string version / english + * explanation of */ +/* the FMOD error codes. */ /* */ -/* ============================================================================================== */ +/* ============================================================================================== + */ #ifndef _FMOD_ERRORS_H #define _FMOD_ERRORS_H #include "fmod.h" -#ifdef __GNUC__ -static const char *FMOD_ErrorString(FMOD_RESULT errcode) __attribute__((unused)); +#ifdef __GNUC__ +static const char *FMOD_ErrorString(FMOD_RESULT errcode) + __attribute__((unused)); #endif static const char *FMOD_ErrorString(FMOD_RESULT errcode) { - switch (errcode) - { -/*$ preserve end $*/ - case FMOD_ERR_ALREADYLOCKED: return "Tried to call lock a second time before unlock was called. "; - case FMOD_ERR_BADCOMMAND: return "Tried to call a function on a data type that does not allow this type of functionality (ie calling Sound::lock on a streaming sound). "; - case FMOD_ERR_CDDA_DRIVERS: return "Neither NTSCSI nor ASPI could be initialised. "; - case FMOD_ERR_CDDA_INIT: return "An error occurred while initialising the CDDA subsystem. "; - case FMOD_ERR_CDDA_INVALID_DEVICE: return "Couldn't find the specified device. "; - case FMOD_ERR_CDDA_NOAUDIO: return "No audio tracks on the specified disc. "; - case FMOD_ERR_CDDA_NODEVICES: return "No CD/DVD devices were found. "; - case FMOD_ERR_CDDA_NODISC: return "No disc present in the specified drive. "; - case FMOD_ERR_CDDA_READ: return "A CDDA read error occurred. "; - case FMOD_ERR_CHANNEL_ALLOC: return "Error trying to allocate a channel. "; - case FMOD_ERR_CHANNEL_STOLEN: return "The specified channel has been reused to play another sound. "; - case FMOD_ERR_COM: return "A Win32 COM related error occured. COM failed to initialize or a QueryInterface failed meaning a Windows codec or driver was not installed properly. "; - case FMOD_ERR_DMA: return "DMA Failure. See debug output for more information. "; - case FMOD_ERR_DSP_CONNECTION: return "DSP connection error. Connection possibly caused a cyclic dependancy. Or tried to connect a tree too many units deep (more than 128). "; - case FMOD_ERR_DSP_FORMAT: return "DSP Format error. A DSP unit may have attempted to connect to this network with the wrong format. "; - case FMOD_ERR_DSP_NOTFOUND: return "DSP connection error. Couldn't find the DSP unit specified. "; - case FMOD_ERR_DSP_RUNNING: return "DSP error. Cannot perform this operation while the network is in the middle of running. This will most likely happen if a connection or disconnection is attempted in a DSP callback. "; - case FMOD_ERR_DSP_TOOMANYCONNECTIONS: return "DSP connection error. The unit being connected to or disconnected should only have 1 input or output. "; - case FMOD_ERR_EVENT_ALREADY_LOADED: return "The specified project or bank has already been loaded. Having multiple copies of the same project loaded simultaneously is forbidden. "; - case FMOD_ERR_EVENT_FAILED: return "An Event failed to be retrieved, most likely due to 'just fail' being specified as the max playbacks behavior. "; - case FMOD_ERR_EVENT_GUIDCONFLICT: return "An event with the same GUID already exists. "; - case FMOD_ERR_EVENT_INFOONLY: return "Can't execute this command on an EVENT_INFOONLY event. "; - case FMOD_ERR_EVENT_INTERNAL: return "An error occured that wasn't supposed to. See debug log for reason. "; - case FMOD_ERR_EVENT_MAXSTREAMS: return "Event failed because 'Max streams' was hit when FMOD_EVENT_INIT_FAIL_ON_MAXSTREAMS was specified. "; - case FMOD_ERR_EVENT_MISMATCH: return "FSB mismatches the FEV it was compiled with, the stream/sample mode it was meant to be created with was different, or the FEV was built for a different platform. "; - case FMOD_ERR_EVENT_NAMECONFLICT: return "A category with the same name already exists. "; - case FMOD_ERR_EVENT_NEEDSSIMPLE: return "Tried to call a function on a complex event that's only supported by simple events. "; - case FMOD_ERR_EVENT_NOTFOUND: return "The requested event, event group, event category or event property could not be found. "; - case FMOD_ERR_FILE_BAD: return "Error loading file. "; - case FMOD_ERR_FILE_COULDNOTSEEK: return "Couldn't perform seek operation. This is a limitation of the medium (ie netstreams) or the file format. "; - case FMOD_ERR_FILE_DISKEJECTED: return "Media was ejected while reading. "; - case FMOD_ERR_FILE_EOF: return "End of file unexpectedly reached while trying to read essential data (truncated data?). "; - case FMOD_ERR_FILE_NOTFOUND: return "File not found. "; - case FMOD_ERR_FILE_UNWANTED: return "Unwanted file access occured. "; - case FMOD_ERR_FORMAT: return "Unsupported file or audio format. "; - case FMOD_ERR_HTTP: return "A HTTP error occurred. This is a catch-all for HTTP errors not listed elsewhere. "; - case FMOD_ERR_HTTP_ACCESS: return "The specified resource requires authentication or is forbidden. "; - case FMOD_ERR_HTTP_PROXY_AUTH: return "Proxy authentication is required to access the specified resource. "; - case FMOD_ERR_HTTP_SERVER_ERROR: return "A HTTP server error occurred. "; - case FMOD_ERR_HTTP_TIMEOUT: return "The HTTP request timed out. "; - case FMOD_ERR_INITIALIZATION: return "FMOD was not initialized correctly to support this function. "; - case FMOD_ERR_INITIALIZED: return "Cannot call this command after System::init. "; - case FMOD_ERR_INTERNAL: return "An error occured that wasn't supposed to. Contact support. "; - case FMOD_ERR_INVALID_ADDRESS: return "On Xbox 360, this memory address passed to FMOD must be physical, (ie allocated with XPhysicalAlloc.) "; - case FMOD_ERR_INVALID_FLOAT: return "Value passed in was a NaN, Inf or denormalized float. "; - case FMOD_ERR_INVALID_HANDLE: return "An invalid object handle was used. "; - case FMOD_ERR_INVALID_PARAM: return "An invalid parameter was passed to this function. "; - case FMOD_ERR_INVALID_POSITION: return "An invalid seek position was passed to this function. "; - case FMOD_ERR_INVALID_SPEAKER: return "An invalid speaker was passed to this function based on the current speaker mode. "; - case FMOD_ERR_INVALID_SYNCPOINT: return "The syncpoint did not come from this sound handle. "; - case FMOD_ERR_INVALID_VECTOR: return "The vectors passed in are not unit length, or perpendicular. "; - case FMOD_ERR_MAXAUDIBLE: return "Reached maximum audible playback count for this sound's soundgroup. "; - case FMOD_ERR_MEMORY: return "Not enough memory or resources. "; - case FMOD_ERR_MEMORY_CANTPOINT: return "Can't use FMOD_OPENMEMORY_POINT on non PCM source data, or non mp3/xma/adpcm data if FMOD_CREATECOMPRESSEDSAMPLE was used. "; - case FMOD_ERR_MEMORY_SRAM: return "Not enough memory or resources on console sound ram. "; - case FMOD_ERR_MUSIC_NOCALLBACK: return "The music callback is required, but it has not been set. "; - case FMOD_ERR_MUSIC_NOTFOUND: return "The requested music entity could not be found. "; - case FMOD_ERR_MUSIC_UNINITIALIZED: return "Music system is not initialized probably because no music data is loaded. "; - case FMOD_ERR_NEEDS2D: return "Tried to call a command on a 3d sound when the command was meant for 2d sound. "; - case FMOD_ERR_NEEDS3D: return "Tried to call a command on a 2d sound when the command was meant for 3d sound. "; - case FMOD_ERR_NEEDSHARDWARE: return "Tried to use a feature that requires hardware support. (ie trying to play a GCADPCM compressed sound in software on Wii). "; - case FMOD_ERR_NEEDSSOFTWARE: return "Tried to use a feature that requires the software engine. Software engine has either been turned off, or command was executed on a hardware channel which does not support this feature. "; - case FMOD_ERR_NET_CONNECT: return "Couldn't connect to the specified host. "; - case FMOD_ERR_NET_SOCKET_ERROR: return "A socket error occurred. This is a catch-all for socket-related errors not listed elsewhere. "; - case FMOD_ERR_NET_URL: return "The specified URL couldn't be resolved. "; - case FMOD_ERR_NET_WOULD_BLOCK: return "Operation on a non-blocking socket could not complete immediately. "; - case FMOD_ERR_NOTREADY: return "Operation could not be performed because specified sound/DSP connection is not ready. "; - case FMOD_ERR_OUTPUT_ALLOCATED: return "Error initializing output device, but more specifically, the output device is already in use and cannot be reused. "; - case FMOD_ERR_OUTPUT_CREATEBUFFER: return "Error creating hardware sound buffer. "; - case FMOD_ERR_OUTPUT_DRIVERCALL: return "A call to a standard soundcard driver failed, which could possibly mean a bug in the driver or resources were missing or exhausted. "; - case FMOD_ERR_OUTPUT_ENUMERATION: return "Error enumerating the available driver list. List may be inconsistent due to a recent device addition or removal. "; - case FMOD_ERR_OUTPUT_FORMAT: return "Soundcard does not support the minimum features needed for this soundsystem (16bit stereo output). "; - case FMOD_ERR_OUTPUT_INIT: return "Error initializing output device. "; - case FMOD_ERR_OUTPUT_NOHARDWARE: return "FMOD_HARDWARE was specified but the sound card does not have the resources necessary to play it. "; - case FMOD_ERR_OUTPUT_NOSOFTWARE: return "Attempted to create a software sound but no software channels were specified in System::init. "; - case FMOD_ERR_PAN: return "Panning only works with mono or stereo sound sources. "; - case FMOD_ERR_PLUGIN: return "An unspecified error has been returned from a 3rd party plugin. "; - case FMOD_ERR_PLUGIN_INSTANCES: return "The number of allowed instances of a plugin has been exceeded. "; - case FMOD_ERR_PLUGIN_MISSING: return "A requested output, dsp unit type or codec was not available. "; - case FMOD_ERR_PLUGIN_RESOURCE: return "A resource that the plugin requires cannot be found. (ie the DLS file for MIDI playback or other DLLs that it needs to load) "; - case FMOD_ERR_PRELOADED: return "The specified sound is still in use by the event system, call EventSystem::unloadFSB before trying to release it. "; - case FMOD_ERR_PROGRAMMERSOUND: return "The specified sound is still in use by the event system, wait for the event which is using it finish with it. "; - case FMOD_ERR_RECORD: return "An error occured trying to initialize the recording device. "; - case FMOD_ERR_REVERB_INSTANCE: return "Specified instance in FMOD_REVERB_PROPERTIES couldn't be set. Most likely because it is an invalid instance number or the reverb doesnt exist. "; - case FMOD_ERR_SUBSOUNDS: return "The error occured because the sound referenced contains subsounds when it shouldn't have, or it doesn't contain subsounds when it should have. The operation may also not be able to be performed on a parent sound, or a parent sound was played without setting up a sentence first. "; - case FMOD_ERR_SUBSOUND_ALLOCATED: return "This subsound is already being used by another sound, you cannot have more than one parent to a sound. Null out the other parent's entry first. "; - case FMOD_ERR_SUBSOUND_CANTMOVE: return "Shared subsounds cannot be replaced or moved from their parent stream, such as when the parent stream is an FSB file. "; - case FMOD_ERR_SUBSOUND_MODE: return "The subsound's mode bits do not match with the parent sound's mode bits. See documentation for function that it was called with. "; - case FMOD_ERR_TAGNOTFOUND: return "The specified tag could not be found or there are no tags. "; - case FMOD_ERR_TOOMANYCHANNELS: return "The sound created exceeds the allowable input channel count. This can be increased using the maxinputchannels parameter in System::setSoftwareFormat. "; - case FMOD_ERR_UNIMPLEMENTED: return "Something in FMOD hasn't been implemented when it should be! contact support! "; - case FMOD_ERR_UNINITIALIZED: return "This command failed because System::init or System::setDriver was not called. "; - case FMOD_ERR_UNSUPPORTED: return "A command issued was not supported by this object. Possibly a plugin without certain callbacks specified. "; - case FMOD_ERR_UPDATE: return "An error caused by System::update occured. "; - case FMOD_ERR_VERSION: return "The version number of this file format is not supported. "; - case FMOD_OK: return "No errors."; - default : return "Unknown error."; -/*$ preserve start $*/ - }; + switch (errcode) { + /*$ preserve end $*/ + case FMOD_ERR_ALREADYLOCKED: + return "Tried to call lock a second time before unlock was called. "; + case FMOD_ERR_BADCOMMAND: + return "Tried to call a function on a data type that does not allow this " + "type of functionality (ie calling Sound::lock on a streaming " + "sound). "; + case FMOD_ERR_CDDA_DRIVERS: + return "Neither NTSCSI nor ASPI could be initialised. "; + case FMOD_ERR_CDDA_INIT: + return "An error occurred while initialising the CDDA subsystem. "; + case FMOD_ERR_CDDA_INVALID_DEVICE: + return "Couldn't find the specified device. "; + case FMOD_ERR_CDDA_NOAUDIO: + return "No audio tracks on the specified disc. "; + case FMOD_ERR_CDDA_NODEVICES: + return "No CD/DVD devices were found. "; + case FMOD_ERR_CDDA_NODISC: + return "No disc present in the specified drive. "; + case FMOD_ERR_CDDA_READ: + return "A CDDA read error occurred. "; + case FMOD_ERR_CHANNEL_ALLOC: + return "Error trying to allocate a channel. "; + case FMOD_ERR_CHANNEL_STOLEN: + return "The specified channel has been reused to play another sound. "; + case FMOD_ERR_COM: + return "A Win32 COM related error occured. COM failed to initialize or a " + "QueryInterface failed meaning a Windows codec or driver was not " + "installed properly. "; + case FMOD_ERR_DMA: + return "DMA Failure. See debug output for more information. "; + case FMOD_ERR_DSP_CONNECTION: + return "DSP connection error. Connection possibly caused a cyclic " + "dependancy. Or tried to connect a tree too many units deep " + "(more than 128). "; + case FMOD_ERR_DSP_FORMAT: + return "DSP Format error. A DSP unit may have attempted to connect to " + "this network with the wrong format. "; + case FMOD_ERR_DSP_NOTFOUND: + return "DSP connection error. Couldn't find the DSP unit specified. "; + case FMOD_ERR_DSP_RUNNING: + return "DSP error. Cannot perform this operation while the network is " + "in the middle of running. This will most likely happen if a " + "connection or disconnection is attempted in a DSP callback. "; + case FMOD_ERR_DSP_TOOMANYCONNECTIONS: + return "DSP connection error. The unit being connected to or " + "disconnected should only have 1 input or output. "; + case FMOD_ERR_EVENT_ALREADY_LOADED: + return "The specified project or bank has already been loaded. Having " + "multiple copies of the same project loaded simultaneously is " + "forbidden. "; + case FMOD_ERR_EVENT_FAILED: + return "An Event failed to be retrieved, most likely due to 'just fail' " + "being specified as the max playbacks behavior. "; + case FMOD_ERR_EVENT_GUIDCONFLICT: + return "An event with the same GUID already exists. "; + case FMOD_ERR_EVENT_INFOONLY: + return "Can't execute this command on an EVENT_INFOONLY event. "; + case FMOD_ERR_EVENT_INTERNAL: + return "An error occured that wasn't supposed to. See debug log for " + "reason. "; + case FMOD_ERR_EVENT_MAXSTREAMS: + return "Event failed because 'Max streams' was hit when " + "FMOD_EVENT_INIT_FAIL_ON_MAXSTREAMS was specified. "; + case FMOD_ERR_EVENT_MISMATCH: + return "FSB mismatches the FEV it was compiled with, the stream/sample " + "mode it was meant to be created with was different, or the FEV " + "was built for a different platform. "; + case FMOD_ERR_EVENT_NAMECONFLICT: + return "A category with the same name already exists. "; + case FMOD_ERR_EVENT_NEEDSSIMPLE: + return "Tried to call a function on a complex event that's only " + "supported by simple events. "; + case FMOD_ERR_EVENT_NOTFOUND: + return "The requested event, event group, event category or event " + "property could not be found. "; + case FMOD_ERR_FILE_BAD: + return "Error loading file. "; + case FMOD_ERR_FILE_COULDNOTSEEK: + return "Couldn't perform seek operation. This is a limitation of the " + "medium (ie netstreams) or the file format. "; + case FMOD_ERR_FILE_DISKEJECTED: + return "Media was ejected while reading. "; + case FMOD_ERR_FILE_EOF: + return "End of file unexpectedly reached while trying to read essential " + "data (truncated data?). "; + case FMOD_ERR_FILE_NOTFOUND: + return "File not found. "; + case FMOD_ERR_FILE_UNWANTED: + return "Unwanted file access occured. "; + case FMOD_ERR_FORMAT: + return "Unsupported file or audio format. "; + case FMOD_ERR_HTTP: + return "A HTTP error occurred. This is a catch-all for HTTP errors not " + "listed elsewhere. "; + case FMOD_ERR_HTTP_ACCESS: + return "The specified resource requires authentication or is forbidden. "; + case FMOD_ERR_HTTP_PROXY_AUTH: + return "Proxy authentication is required to access the specified " + "resource. "; + case FMOD_ERR_HTTP_SERVER_ERROR: + return "A HTTP server error occurred. "; + case FMOD_ERR_HTTP_TIMEOUT: + return "The HTTP request timed out. "; + case FMOD_ERR_INITIALIZATION: + return "FMOD was not initialized correctly to support this function. "; + case FMOD_ERR_INITIALIZED: + return "Cannot call this command after System::init. "; + case FMOD_ERR_INTERNAL: + return "An error occured that wasn't supposed to. Contact support. "; + case FMOD_ERR_INVALID_ADDRESS: + return "On Xbox 360, this memory address passed to FMOD must be " + "physical, (ie allocated with XPhysicalAlloc.) "; + case FMOD_ERR_INVALID_FLOAT: + return "Value passed in was a NaN, Inf or denormalized float. "; + case FMOD_ERR_INVALID_HANDLE: + return "An invalid object handle was used. "; + case FMOD_ERR_INVALID_PARAM: + return "An invalid parameter was passed to this function. "; + case FMOD_ERR_INVALID_POSITION: + return "An invalid seek position was passed to this function. "; + case FMOD_ERR_INVALID_SPEAKER: + return "An invalid speaker was passed to this function based on the " + "current speaker mode. "; + case FMOD_ERR_INVALID_SYNCPOINT: + return "The syncpoint did not come from this sound handle. "; + case FMOD_ERR_INVALID_VECTOR: + return "The vectors passed in are not unit length, or perpendicular. "; + case FMOD_ERR_MAXAUDIBLE: + return "Reached maximum audible playback count for this sound's " + "soundgroup. "; + case FMOD_ERR_MEMORY: + return "Not enough memory or resources. "; + case FMOD_ERR_MEMORY_CANTPOINT: + return "Can't use FMOD_OPENMEMORY_POINT on non PCM source data, or non " + "mp3/xma/adpcm data if FMOD_CREATECOMPRESSEDSAMPLE was used. "; + case FMOD_ERR_MEMORY_SRAM: + return "Not enough memory or resources on console sound ram. "; + case FMOD_ERR_MUSIC_NOCALLBACK: + return "The music callback is required, but it has not been set. "; + case FMOD_ERR_MUSIC_NOTFOUND: + return "The requested music entity could not be found. "; + case FMOD_ERR_MUSIC_UNINITIALIZED: + return "Music system is not initialized probably because no music data " + "is loaded. "; + case FMOD_ERR_NEEDS2D: + return "Tried to call a command on a 3d sound when the command was meant " + "for 2d sound. "; + case FMOD_ERR_NEEDS3D: + return "Tried to call a command on a 2d sound when the command was meant " + "for 3d sound. "; + case FMOD_ERR_NEEDSHARDWARE: + return "Tried to use a feature that requires hardware support. (ie " + "trying to play a GCADPCM compressed sound in software on Wii). "; + case FMOD_ERR_NEEDSSOFTWARE: + return "Tried to use a feature that requires the software engine. " + "Software engine has either been turned off, or command was " + "executed on a hardware channel which does not support this " + "feature. "; + case FMOD_ERR_NET_CONNECT: + return "Couldn't connect to the specified host. "; + case FMOD_ERR_NET_SOCKET_ERROR: + return "A socket error occurred. This is a catch-all for socket-related " + "errors not listed elsewhere. "; + case FMOD_ERR_NET_URL: + return "The specified URL couldn't be resolved. "; + case FMOD_ERR_NET_WOULD_BLOCK: + return "Operation on a non-blocking socket could not complete " + "immediately. "; + case FMOD_ERR_NOTREADY: + return "Operation could not be performed because specified sound/DSP " + "connection is not ready. "; + case FMOD_ERR_OUTPUT_ALLOCATED: + return "Error initializing output device, but more specifically, the " + "output device is already in use and cannot be reused. "; + case FMOD_ERR_OUTPUT_CREATEBUFFER: + return "Error creating hardware sound buffer. "; + case FMOD_ERR_OUTPUT_DRIVERCALL: + return "A call to a standard soundcard driver failed, which could " + "possibly mean a bug in the driver or resources were missing or " + "exhausted. "; + case FMOD_ERR_OUTPUT_ENUMERATION: + return "Error enumerating the available driver list. List may be " + "inconsistent due to a recent device addition or removal. "; + case FMOD_ERR_OUTPUT_FORMAT: + return "Soundcard does not support the minimum features needed for this " + "soundsystem (16bit stereo output). "; + case FMOD_ERR_OUTPUT_INIT: + return "Error initializing output device. "; + case FMOD_ERR_OUTPUT_NOHARDWARE: + return "FMOD_HARDWARE was specified but the sound card does not have the " + "resources necessary to play it. "; + case FMOD_ERR_OUTPUT_NOSOFTWARE: + return "Attempted to create a software sound but no software channels " + "were specified in System::init. "; + case FMOD_ERR_PAN: + return "Panning only works with mono or stereo sound sources. "; + case FMOD_ERR_PLUGIN: + return "An unspecified error has been returned from a 3rd party plugin. "; + case FMOD_ERR_PLUGIN_INSTANCES: + return "The number of allowed instances of a plugin has been exceeded. "; + case FMOD_ERR_PLUGIN_MISSING: + return "A requested output, dsp unit type or codec was not available. "; + case FMOD_ERR_PLUGIN_RESOURCE: + return "A resource that the plugin requires cannot be found. (ie the DLS " + "file for MIDI playback or other DLLs that it needs to load) "; + case FMOD_ERR_PRELOADED: + return "The specified sound is still in use by the event system, call " + "EventSystem::unloadFSB before trying to release it. "; + case FMOD_ERR_PROGRAMMERSOUND: + return "The specified sound is still in use by the event system, wait " + "for the event which is using it finish with it. "; + case FMOD_ERR_RECORD: + return "An error occured trying to initialize the recording device. "; + case FMOD_ERR_REVERB_INSTANCE: + return "Specified instance in FMOD_REVERB_PROPERTIES couldn't be set. " + "Most likely because it is an invalid instance number or the " + "reverb doesnt exist. "; + case FMOD_ERR_SUBSOUNDS: + return "The error occured because the sound referenced contains " + "subsounds when it shouldn't have, or it doesn't contain " + "subsounds when it should have. The operation may also not be " + "able to be performed on a parent sound, or a parent sound was " + "played without setting up a sentence first. "; + case FMOD_ERR_SUBSOUND_ALLOCATED: + return "This subsound is already being used by another sound, you cannot " + "have more than one parent to a sound. Null out the other " + "parent's entry first. "; + case FMOD_ERR_SUBSOUND_CANTMOVE: + return "Shared subsounds cannot be replaced or moved from their parent " + "stream, such as when the parent stream is an FSB file. "; + case FMOD_ERR_SUBSOUND_MODE: + return "The subsound's mode bits do not match with the parent sound's " + "mode bits. See documentation for function that it was called " + "with. "; + case FMOD_ERR_TAGNOTFOUND: + return "The specified tag could not be found or there are no tags. "; + case FMOD_ERR_TOOMANYCHANNELS: + return "The sound created exceeds the allowable input channel count. " + "This can be increased using the maxinputchannels parameter in " + "System::setSoftwareFormat. "; + case FMOD_ERR_UNIMPLEMENTED: + return "Something in FMOD hasn't been implemented when it should be! " + "contact support! "; + case FMOD_ERR_UNINITIALIZED: + return "This command failed because System::init or System::setDriver " + "was not called. "; + case FMOD_ERR_UNSUPPORTED: + return "A command issued was not supported by this object. Possibly a " + "plugin without certain callbacks specified. "; + case FMOD_ERR_UPDATE: + return "An error caused by System::update occured. "; + case FMOD_ERR_VERSION: + return "The version number of this file format is not supported. "; + case FMOD_OK: + return "No errors."; + default: + return "Unknown error."; + /*$ preserve start $*/ + }; } #endif diff --git a/src/imports/fmodex/fmod_memoryinfo.h b/src/imports/fmodex/fmod_memoryinfo.h index 0a40a28..2cb2da9 100644 --- a/src/imports/fmodex/fmod_memoryinfo.h +++ b/src/imports/fmodex/fmod_memoryinfo.h @@ -1,10 +1,14 @@ -/* ============================================================================================= */ -/* FMOD Ex - Memory info header file. Copyright (c), Firelight Technologies Pty, Ltd. 2008-2016. */ +/* ============================================================================================= + */ +/* FMOD Ex - Memory info header file. Copyright (c), Firelight Technologies Pty, + * Ltd. 2008-2016. */ /* */ -/* Use this header if you are interested in getting detailed information on FMOD's memory */ -/* usage. See the documentation for more details. */ +/* Use this header if you are interested in getting detailed information on + * FMOD's memory */ +/* usage. See the documentation for more details. */ /* */ -/* ============================================================================================= */ +/* ============================================================================================= + */ #ifndef _FMOD_MEMORYINFO_H #define _FMOD_MEMORYINFO_H @@ -13,79 +17,85 @@ [STRUCTURE] [ [DESCRIPTION] - Structure to be filled with detailed memory usage information of an FMOD object + Structure to be filled with detailed memory usage information of an FMOD +object [REMARKS] - Every public FMOD class has a getMemoryInfo function which can be used to get detailed information on what memory resources are associated with the object in question. - On return from getMemoryInfo, each member of this structure will hold the amount of memory used for its type in bytes.
    -
    - Members marked with [in] mean the user sets the value before passing it to the function.
    - Members marked with [out] mean FMOD sets the value to be used after the function exits.
    + Every public FMOD class has a getMemoryInfo function which can be used to +get detailed information on what memory resources are associated with the object +in question. On return from getMemoryInfo, each member of this structure will +hold the amount of memory used for its type in bytes.

    Members marked +with [in] mean the user sets the value before passing it to the function.
    + Members marked with [out] mean FMOD sets the value to be used after the +function exits.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] System::getMemoryInfo EventSystem::getMemoryInfo - FMOD_MEMBITS + FMOD_MEMBITS FMOD_EVENT_MEMBITS ] */ -typedef struct FMOD_MEMORY_USAGE_DETAILS -{ - unsigned int other; /* [out] Memory not accounted for by other types */ - unsigned int string; /* [out] String data */ - unsigned int system; /* [out] System object and various internals */ - unsigned int plugins; /* [out] Plugin objects and internals */ - unsigned int output; /* [out] Output module object and internals */ - unsigned int channel; /* [out] Channel related memory */ - unsigned int channelgroup; /* [out] ChannelGroup objects and internals */ - unsigned int codec; /* [out] Codecs allocated for streaming */ - unsigned int file; /* [out] File buffers and structures */ - unsigned int sound; /* [out] Sound objects and internals */ - unsigned int secondaryram; /* [out] Sound data stored in secondary RAM */ - unsigned int soundgroup; /* [out] SoundGroup objects and internals */ - unsigned int streambuffer; /* [out] Stream buffer memory */ - unsigned int dspconnection; /* [out] DSPConnection objects and internals */ - unsigned int dsp; /* [out] DSP implementation objects */ - unsigned int dspcodec; /* [out] Realtime file format decoding DSP objects */ - unsigned int profile; /* [out] Profiler memory footprint. */ - unsigned int recordbuffer; /* [out] Buffer used to store recorded data from microphone */ - unsigned int reverb; /* [out] Reverb implementation objects */ - unsigned int reverbchannelprops; /* [out] Reverb channel properties structs */ - unsigned int geometry; /* [out] Geometry objects and internals */ - unsigned int syncpoint; /* [out] Sync point memory. */ - unsigned int eventsystem; /* [out] EventSystem and various internals */ - unsigned int musicsystem; /* [out] MusicSystem and various internals */ - unsigned int fev; /* [out] Definition of objects contained in all loaded projects e.g. events, groups, categories */ - unsigned int memoryfsb; /* [out] Data loaded with preloadFSB */ - unsigned int eventproject; /* [out] EventProject objects and internals */ - unsigned int eventgroupi; /* [out] EventGroup objects and internals */ - unsigned int soundbankclass; /* [out] Objects used to manage wave banks */ - unsigned int soundbanklist; /* [out] Data used to manage lists of wave bank usage */ - unsigned int streaminstance; /* [out] Stream objects and internals */ - unsigned int sounddefclass; /* [out] Sound definition objects */ - unsigned int sounddefdefclass; /* [out] Sound definition static data objects */ - unsigned int sounddefpool; /* [out] Sound definition pool data */ - unsigned int reverbdef; /* [out] Reverb definition objects */ - unsigned int eventreverb; /* [out] Reverb objects */ - unsigned int userproperty; /* [out] User property objects */ - unsigned int eventinstance; /* [out] Event instance base objects */ - unsigned int eventinstance_complex; /* [out] Complex event instance objects */ - unsigned int eventinstance_simple; /* [out] Simple event instance objects */ - unsigned int eventinstance_layer; /* [out] Event layer instance objects */ - unsigned int eventinstance_sound; /* [out] Event sound instance objects */ - unsigned int eventenvelope; /* [out] Event envelope objects */ - unsigned int eventenvelopedef; /* [out] Event envelope definition objects */ - unsigned int eventparameter; /* [out] Event parameter objects */ - unsigned int eventcategory; /* [out] Event category objects */ - unsigned int eventenvelopepoint; /* [out] Event envelope point objects */ - unsigned int eventinstancepool; /* [out] Event instance pool memory */ +typedef struct FMOD_MEMORY_USAGE_DETAILS { + unsigned int other; /* [out] Memory not accounted for by other types */ + unsigned int string; /* [out] String data */ + unsigned int system; /* [out] System object and various internals */ + unsigned int plugins; /* [out] Plugin objects and internals */ + unsigned int output; /* [out] Output module object and internals */ + unsigned int channel; /* [out] Channel related memory */ + unsigned int channelgroup; /* [out] ChannelGroup objects and internals */ + unsigned int codec; /* [out] Codecs allocated for streaming */ + unsigned int file; /* [out] File buffers and structures */ + unsigned int sound; /* [out] Sound objects and internals */ + unsigned int secondaryram; /* [out] Sound data stored in secondary RAM */ + unsigned int soundgroup; /* [out] SoundGroup objects and internals */ + unsigned int streambuffer; /* [out] Stream buffer memory */ + unsigned int dspconnection; /* [out] DSPConnection objects and internals */ + unsigned int dsp; /* [out] DSP implementation objects */ + unsigned int dspcodec; /* [out] Realtime file format decoding DSP objects */ + unsigned int profile; /* [out] Profiler memory footprint. */ + unsigned int recordbuffer; /* [out] Buffer used to store recorded data from + microphone */ + unsigned int reverb; /* [out] Reverb implementation objects */ + unsigned int reverbchannelprops; /* [out] Reverb channel properties structs */ + unsigned int geometry; /* [out] Geometry objects and internals */ + unsigned int syncpoint; /* [out] Sync point memory. */ + unsigned int eventsystem; /* [out] EventSystem and various internals */ + unsigned int musicsystem; /* [out] MusicSystem and various internals */ + unsigned int fev; /* [out] Definition of objects contained in all loaded + projects e.g. events, groups, categories */ + unsigned int memoryfsb; /* [out] Data loaded with preloadFSB */ + unsigned int eventproject; /* [out] EventProject objects and internals */ + unsigned int eventgroupi; /* [out] EventGroup objects and internals */ + unsigned int soundbankclass; /* [out] Objects used to manage wave banks */ + unsigned int + soundbanklist; /* [out] Data used to manage lists of wave bank usage */ + unsigned int streaminstance; /* [out] Stream objects and internals */ + unsigned int sounddefclass; /* [out] Sound definition objects */ + unsigned int + sounddefdefclass; /* [out] Sound definition static data objects */ + unsigned int sounddefpool; /* [out] Sound definition pool data */ + unsigned int reverbdef; /* [out] Reverb definition objects */ + unsigned int eventreverb; /* [out] Reverb objects */ + unsigned int userproperty; /* [out] User property objects */ + unsigned int eventinstance; /* [out] Event instance base objects */ + unsigned int eventinstance_complex; /* [out] Complex event instance objects */ + unsigned int eventinstance_simple; /* [out] Simple event instance objects */ + unsigned int eventinstance_layer; /* [out] Event layer instance objects */ + unsigned int eventinstance_sound; /* [out] Event sound instance objects */ + unsigned int eventenvelope; /* [out] Event envelope objects */ + unsigned int eventenvelopedef; /* [out] Event envelope definition objects */ + unsigned int eventparameter; /* [out] Event parameter objects */ + unsigned int eventcategory; /* [out] Event category objects */ + unsigned int eventenvelopepoint; /* [out] Event envelope point objects */ + unsigned int eventinstancepool; /* [out] Event instance pool memory */ } FMOD_MEMORY_USAGE_DETAILS; - /* [DEFINE] [ @@ -93,48 +103,62 @@ typedef struct FMOD_MEMORY_USAGE_DETAILS FMOD_MEMBITS [DESCRIPTION] - Bitfield used to request specific memory usage information from the getMemoryInfo function of every public FMOD Ex class. - Use with the "memorybits" parameter of getMemoryInfo to get information on FMOD Ex memory usage. + Bitfield used to request specific memory usage information from the +getMemoryInfo function of every public FMOD Ex class. Use with the "memorybits" +parameter of getMemoryInfo to get information on FMOD Ex memory usage. [REMARKS] - Every public FMOD class has a getMemoryInfo function which can be used to get detailed information on what memory resources are associated with the object in question. - The FMOD_MEMBITS defines can be OR'd together to specify precisely what memory usage you'd like to get information on. See System::getMemoryInfo for an example. + Every public FMOD class has a getMemoryInfo function which can be used to +get detailed information on what memory resources are associated with the object +in question. The FMOD_MEMBITS defines can be OR'd together to specify precisely +what memory usage you'd like to get information on. See System::getMemoryInfo +for an example. [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] FMOD_EVENT_MEMBITS System::getMemoryInfo ] */ -#define FMOD_MEMBITS_OTHER 0x00000001 /* Memory not accounted for by other types */ -#define FMOD_MEMBITS_STRING 0x00000002 /* String data */ +#define FMOD_MEMBITS_OTHER \ + 0x00000001 /* Memory not accounted for by other types */ +#define FMOD_MEMBITS_STRING 0x00000002 /* String data */ -#define FMOD_MEMBITS_SYSTEM 0x00000004 /* System object and various internals */ -#define FMOD_MEMBITS_PLUGINS 0x00000008 /* Plugin objects and internals */ -#define FMOD_MEMBITS_OUTPUT 0x00000010 /* Output module object and internals */ -#define FMOD_MEMBITS_CHANNEL 0x00000020 /* Channel related memory */ -#define FMOD_MEMBITS_CHANNELGROUP 0x00000040 /* ChannelGroup objects and internals */ -#define FMOD_MEMBITS_CODEC 0x00000080 /* Codecs allocated for streaming */ -#define FMOD_MEMBITS_FILE 0x00000100 /* Codecs allocated for streaming */ -#define FMOD_MEMBITS_SOUND 0x00000200 /* Sound objects and internals */ -#define FMOD_MEMBITS_SOUND_SECONDARYRAM 0x00000400 /* Sound data stored in secondary RAM */ -#define FMOD_MEMBITS_SOUNDGROUP 0x00000800 /* SoundGroup objects and internals */ -#define FMOD_MEMBITS_STREAMBUFFER 0x00001000 /* Stream buffer memory */ -#define FMOD_MEMBITS_DSPCONNECTION 0x00002000 /* DSPConnection objects and internals */ -#define FMOD_MEMBITS_DSP 0x00004000 /* DSP implementation objects */ -#define FMOD_MEMBITS_DSPCODEC 0x00008000 /* Realtime file format decoding DSP objects */ -#define FMOD_MEMBITS_PROFILE 0x00010000 /* Profiler memory footprint. */ -#define FMOD_MEMBITS_RECORDBUFFER 0x00020000 /* Buffer used to store recorded data from microphone */ -#define FMOD_MEMBITS_REVERB 0x00040000 /* Reverb implementation objects */ -#define FMOD_MEMBITS_REVERBCHANNELPROPS 0x00080000 /* Reverb channel properties structs */ -#define FMOD_MEMBITS_GEOMETRY 0x00100000 /* Geometry objects and internals */ -#define FMOD_MEMBITS_SYNCPOINT 0x00200000 /* Sync point memory. */ -#define FMOD_MEMBITS_ALL 0xffffffff /* All memory used by FMOD Ex */ +#define FMOD_MEMBITS_SYSTEM 0x00000004 /* System object and various internals \ + */ +#define FMOD_MEMBITS_PLUGINS 0x00000008 /* Plugin objects and internals */ +#define FMOD_MEMBITS_OUTPUT 0x00000010 /* Output module object and internals \ + */ +#define FMOD_MEMBITS_CHANNEL 0x00000020 /* Channel related memory */ +#define FMOD_MEMBITS_CHANNELGROUP \ + 0x00000040 /* ChannelGroup objects and internals */ +#define FMOD_MEMBITS_CODEC 0x00000080 /* Codecs allocated for streaming */ +#define FMOD_MEMBITS_FILE 0x00000100 /* Codecs allocated for streaming */ +#define FMOD_MEMBITS_SOUND 0x00000200 /* Sound objects and internals */ +#define FMOD_MEMBITS_SOUND_SECONDARYRAM \ + 0x00000400 /* Sound data stored in secondary RAM */ +#define FMOD_MEMBITS_SOUNDGROUP \ + 0x00000800 /* SoundGroup objects and internals */ +#define FMOD_MEMBITS_STREAMBUFFER 0x00001000 /* Stream buffer memory */ +#define FMOD_MEMBITS_DSPCONNECTION \ + 0x00002000 /* DSPConnection objects and internals */ +#define FMOD_MEMBITS_DSP 0x00004000 /* DSP implementation objects */ +#define FMOD_MEMBITS_DSPCODEC \ + 0x00008000 /* Realtime file format decoding DSP objects */ +#define FMOD_MEMBITS_PROFILE 0x00010000 /* Profiler memory footprint. */ +#define FMOD_MEMBITS_RECORDBUFFER \ + 0x00020000 /* Buffer used to store recorded data from microphone */ +#define FMOD_MEMBITS_REVERB 0x00040000 /* Reverb implementation objects */ +#define FMOD_MEMBITS_REVERBCHANNELPROPS \ + 0x00080000 /* Reverb channel properties structs */ +#define FMOD_MEMBITS_GEOMETRY 0x00100000 /* Geometry objects and internals */ +#define FMOD_MEMBITS_SYNCPOINT 0x00200000 /* Sync point memory. */ +#define FMOD_MEMBITS_ALL 0xffffffff /* All memory used by FMOD Ex */ /* [DEFINE_END] */ - /* [DEFINE] [ @@ -142,60 +166,93 @@ typedef struct FMOD_MEMORY_USAGE_DETAILS FMOD_EVENT_MEMBITS [DESCRIPTION] - Bitfield used to request specific memory usage information from the getMemoryInfo function of every public FMOD Event System class. - Use with the "event_memorybits" parameter of getMemoryInfo to get information on FMOD Event System memory usage. + Bitfield used to request specific memory usage information from the +getMemoryInfo function of every public FMOD Event System class. Use with the +"event_memorybits" parameter of getMemoryInfo to get information on FMOD Event +System memory usage. [REMARKS] - Every public FMOD Event System class has a getMemoryInfo function which can be used to get detailed information on what memory resources are associated with the object in question. - The FMOD_EVENT_MEMBITS defines can be OR'd together to specify precisely what memory usage you'd like to get information on. See EventSystem::getMemoryInfo for an example. + Every public FMOD Event System class has a getMemoryInfo function which can +be used to get detailed information on what memory resources are associated with +the object in question. The FMOD_EVENT_MEMBITS defines can be OR'd together to +specify precisely what memory usage you'd like to get information on. See +EventSystem::getMemoryInfo for an example. [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] FMOD_MEMBITS System::getMemoryInfo ] -*/ -#define FMOD_EVENT_MEMBITS_EVENTSYSTEM 0x00000001 /* EventSystem and various internals */ -#define FMOD_EVENT_MEMBITS_MUSICSYSTEM 0x00000002 /* MusicSystem and various internals */ -#define FMOD_EVENT_MEMBITS_FEV 0x00000004 /* Definition of objects contained in all loaded projects e.g. events, groups, categories */ -#define FMOD_EVENT_MEMBITS_MEMORYFSB 0x00000008 /* Data loaded with preloadFSB */ -#define FMOD_EVENT_MEMBITS_EVENTPROJECT 0x00000010 /* EventProject objects and internals */ -#define FMOD_EVENT_MEMBITS_EVENTGROUPI 0x00000020 /* EventGroup objects and internals */ -#define FMOD_EVENT_MEMBITS_SOUNDBANKCLASS 0x00000040 /* Objects used to manage wave banks */ -#define FMOD_EVENT_MEMBITS_SOUNDBANKLIST 0x00000080 /* Data used to manage lists of wave bank usage */ -#define FMOD_EVENT_MEMBITS_STREAMINSTANCE 0x00000100 /* Stream objects and internals */ -#define FMOD_EVENT_MEMBITS_SOUNDDEFCLASS 0x00000200 /* Sound definition objects */ -#define FMOD_EVENT_MEMBITS_SOUNDDEFDEFCLASS 0x00000400 /* Sound definition static data objects */ -#define FMOD_EVENT_MEMBITS_SOUNDDEFPOOL 0x00000800 /* Sound definition pool data */ -#define FMOD_EVENT_MEMBITS_REVERBDEF 0x00001000 /* Reverb definition objects */ -#define FMOD_EVENT_MEMBITS_EVENTREVERB 0x00002000 /* Reverb objects */ -#define FMOD_EVENT_MEMBITS_USERPROPERTY 0x00004000 /* User property objects */ -#define FMOD_EVENT_MEMBITS_EVENTINSTANCE 0x00008000 /* Event instance base objects */ -#define FMOD_EVENT_MEMBITS_EVENTINSTANCE_COMPLEX 0x00010000 /* Complex event instance objects */ -#define FMOD_EVENT_MEMBITS_EVENTINSTANCE_SIMPLE 0x00020000 /* Simple event instance objects */ -#define FMOD_EVENT_MEMBITS_EVENTINSTANCE_LAYER 0x00040000 /* Event layer instance objects */ -#define FMOD_EVENT_MEMBITS_EVENTINSTANCE_SOUND 0x00080000 /* Event sound instance objects */ -#define FMOD_EVENT_MEMBITS_EVENTENVELOPE 0x00100000 /* Event envelope objects */ -#define FMOD_EVENT_MEMBITS_EVENTENVELOPEDEF 0x00200000 /* Event envelope definition objects */ -#define FMOD_EVENT_MEMBITS_EVENTPARAMETER 0x00400000 /* Event parameter objects */ -#define FMOD_EVENT_MEMBITS_EVENTCATEGORY 0x00800000 /* Event category objects */ -#define FMOD_EVENT_MEMBITS_EVENTENVELOPEPOINT 0x01000000 /* Event envelope point object+s */ -#define FMOD_EVENT_MEMBITS_EVENTINSTANCEPOOL 0x02000000 /* Event instance pool data */ -#define FMOD_EVENT_MEMBITS_ALL 0xffffffff /* All memory used by FMOD Event System */ +*/ +#define FMOD_EVENT_MEMBITS_EVENTSYSTEM \ + 0x00000001 /* EventSystem and various internals */ +#define FMOD_EVENT_MEMBITS_MUSICSYSTEM \ + 0x00000002 /* MusicSystem and various internals */ +#define FMOD_EVENT_MEMBITS_FEV \ + 0x00000004 /* Definition of objects contained in all loaded projects e.g. \ + events, groups, categories */ +#define FMOD_EVENT_MEMBITS_MEMORYFSB \ + 0x00000008 /* Data loaded with preloadFSB */ +#define FMOD_EVENT_MEMBITS_EVENTPROJECT \ + 0x00000010 /* EventProject objects and internals */ +#define FMOD_EVENT_MEMBITS_EVENTGROUPI \ + 0x00000020 /* EventGroup objects and internals */ +#define FMOD_EVENT_MEMBITS_SOUNDBANKCLASS \ + 0x00000040 /* Objects used to manage wave banks */ +#define FMOD_EVENT_MEMBITS_SOUNDBANKLIST \ + 0x00000080 /* Data used to manage lists of wave bank usage */ +#define FMOD_EVENT_MEMBITS_STREAMINSTANCE \ + 0x00000100 /* Stream objects and internals */ +#define FMOD_EVENT_MEMBITS_SOUNDDEFCLASS \ + 0x00000200 /* Sound definition objects */ +#define FMOD_EVENT_MEMBITS_SOUNDDEFDEFCLASS \ + 0x00000400 /* Sound definition static data objects */ +#define FMOD_EVENT_MEMBITS_SOUNDDEFPOOL \ + 0x00000800 /* Sound definition pool data */ +#define FMOD_EVENT_MEMBITS_REVERBDEF 0x00001000 /* Reverb definition objects \ + */ +#define FMOD_EVENT_MEMBITS_EVENTREVERB 0x00002000 /* Reverb objects */ +#define FMOD_EVENT_MEMBITS_USERPROPERTY 0x00004000 /* User property objects */ +#define FMOD_EVENT_MEMBITS_EVENTINSTANCE \ + 0x00008000 /* Event instance base objects */ +#define FMOD_EVENT_MEMBITS_EVENTINSTANCE_COMPLEX \ + 0x00010000 /* Complex event instance objects */ +#define FMOD_EVENT_MEMBITS_EVENTINSTANCE_SIMPLE \ + 0x00020000 /* Simple event instance objects */ +#define FMOD_EVENT_MEMBITS_EVENTINSTANCE_LAYER \ + 0x00040000 /* Event layer instance objects */ +#define FMOD_EVENT_MEMBITS_EVENTINSTANCE_SOUND \ + 0x00080000 /* Event sound instance objects */ +#define FMOD_EVENT_MEMBITS_EVENTENVELOPE 0x00100000 /* Event envelope objects \ + */ +#define FMOD_EVENT_MEMBITS_EVENTENVELOPEDEF \ + 0x00200000 /* Event envelope definition objects */ +#define FMOD_EVENT_MEMBITS_EVENTPARAMETER \ + 0x00400000 /* Event parameter objects */ +#define FMOD_EVENT_MEMBITS_EVENTCATEGORY 0x00800000 /* Event category objects \ + */ +#define FMOD_EVENT_MEMBITS_EVENTENVELOPEPOINT \ + 0x01000000 /* Event envelope point object+s */ +#define FMOD_EVENT_MEMBITS_EVENTINSTANCEPOOL \ + 0x02000000 /* Event instance pool data */ +#define FMOD_EVENT_MEMBITS_ALL \ + 0xffffffff /* All memory used by FMOD Event System */ /* All event instance memory */ -#define FMOD_EVENT_MEMBITS_EVENTINSTANCE_GROUP (FMOD_EVENT_MEMBITS_EVENTINSTANCE | \ - FMOD_EVENT_MEMBITS_EVENTINSTANCE_COMPLEX | \ - FMOD_EVENT_MEMBITS_EVENTINSTANCE_SIMPLE | \ - FMOD_EVENT_MEMBITS_EVENTINSTANCE_LAYER | \ - FMOD_EVENT_MEMBITS_EVENTINSTANCE_SOUND) +#define FMOD_EVENT_MEMBITS_EVENTINSTANCE_GROUP \ + (FMOD_EVENT_MEMBITS_EVENTINSTANCE | \ + FMOD_EVENT_MEMBITS_EVENTINSTANCE_COMPLEX | \ + FMOD_EVENT_MEMBITS_EVENTINSTANCE_SIMPLE | \ + FMOD_EVENT_MEMBITS_EVENTINSTANCE_LAYER | \ + FMOD_EVENT_MEMBITS_EVENTINSTANCE_SOUND) /* All sound definition memory */ -#define FMOD_EVENT_MEMBITS_SOUNDDEF_GROUP (FMOD_EVENT_MEMBITS_SOUNDDEFCLASS | \ - FMOD_EVENT_MEMBITS_SOUNDDEFDEFCLASS | \ - FMOD_EVENT_MEMBITS_SOUNDDEFPOOL) +#define FMOD_EVENT_MEMBITS_SOUNDDEF_GROUP \ + (FMOD_EVENT_MEMBITS_SOUNDDEFCLASS | FMOD_EVENT_MEMBITS_SOUNDDEFDEFCLASS | \ + FMOD_EVENT_MEMBITS_SOUNDDEFPOOL) /* [DEFINE_END] */ #endif diff --git a/src/imports/fmodex/fmod_output.h b/src/imports/fmodex/fmod_output.h index 33748a7..8af39ed 100644 --- a/src/imports/fmodex/fmod_output.h +++ b/src/imports/fmodex/fmod_output.h @@ -1,11 +1,17 @@ -/* ==================================================================================================== */ -/* FMOD Ex - output development header file. Copyright (c), Firelight Technologies Pty, Ltd. 2004-2016. */ +/* ==================================================================================================== + */ +/* FMOD Ex - output development header file. Copyright (c), Firelight + * Technologies Pty, Ltd. 2004-2016. */ /* */ -/* Use this header if you are wanting to develop your own output plugin to use with */ -/* FMOD's output system. With this header you can make your own output plugin that FMOD */ -/* can register and use. See the documentation and examples on how to make a working plugin. */ +/* Use this header if you are wanting to develop your own output plugin to use + * with */ +/* FMOD's output system. With this header you can make your own output plugin + * that FMOD */ +/* can register and use. See the documentation and examples on how to make a + * working plugin. */ /* */ -/* ==================================================================================================== */ +/* ==================================================================================================== + */ #ifndef _FMOD_OUTPUT_H #define _FMOD_OUTPUT_H @@ -16,78 +22,140 @@ typedef struct FMOD_OUTPUT_STATE FMOD_OUTPUT_STATE; /* Output callbacks -*/ -typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_GETNUMDRIVERSCALLBACK)(FMOD_OUTPUT_STATE *output_state, int *numdrivers); -typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_GETDRIVERNAMECALLBACK)(FMOD_OUTPUT_STATE *output_state, int id, char *name, int namelen); -typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_GETDRIVERCAPSCALLBACK)(FMOD_OUTPUT_STATE *output_state, int id, FMOD_CAPS *caps); -typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_INITCALLBACK) (FMOD_OUTPUT_STATE *output_state, int selecteddriver, FMOD_INITFLAGS flags, int *outputrate, int outputchannels, FMOD_SOUND_FORMAT *outputformat, int dspbufferlength, int dspnumbuffers, void *extradriverdata); -typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_CLOSECALLBACK) (FMOD_OUTPUT_STATE *output_state); -typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_UPDATECALLBACK) (FMOD_OUTPUT_STATE *output_state); -typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_GETHANDLECALLBACK) (FMOD_OUTPUT_STATE *output_state, void **handle); -typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_GETPOSITIONCALLBACK) (FMOD_OUTPUT_STATE *output_state, unsigned int *pcm); -typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_LOCKCALLBACK) (FMOD_OUTPUT_STATE *output_state, unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2); -typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_UNLOCKCALLBACK) (FMOD_OUTPUT_STATE *output_state, void *ptr1, void *ptr2, unsigned int len1, unsigned int len2); -typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_READFROMMIXER) (FMOD_OUTPUT_STATE *output_state, void *buffer, unsigned int length); - +*/ +typedef FMOD_RESULT(F_CALLBACK *FMOD_OUTPUT_GETNUMDRIVERSCALLBACK)( + FMOD_OUTPUT_STATE *output_state, int *numdrivers); +typedef FMOD_RESULT(F_CALLBACK *FMOD_OUTPUT_GETDRIVERNAMECALLBACK)( + FMOD_OUTPUT_STATE *output_state, int id, char *name, int namelen); +typedef FMOD_RESULT(F_CALLBACK *FMOD_OUTPUT_GETDRIVERCAPSCALLBACK)( + FMOD_OUTPUT_STATE *output_state, int id, FMOD_CAPS *caps); +typedef FMOD_RESULT(F_CALLBACK *FMOD_OUTPUT_INITCALLBACK)( + FMOD_OUTPUT_STATE *output_state, + int selecteddriver, + FMOD_INITFLAGS flags, + int *outputrate, + int outputchannels, + FMOD_SOUND_FORMAT *outputformat, + int dspbufferlength, + int dspnumbuffers, + void *extradriverdata); +typedef FMOD_RESULT(F_CALLBACK *FMOD_OUTPUT_CLOSECALLBACK)( + FMOD_OUTPUT_STATE *output_state); +typedef FMOD_RESULT(F_CALLBACK *FMOD_OUTPUT_UPDATECALLBACK)( + FMOD_OUTPUT_STATE *output_state); +typedef FMOD_RESULT(F_CALLBACK *FMOD_OUTPUT_GETHANDLECALLBACK)( + FMOD_OUTPUT_STATE *output_state, void **handle); +typedef FMOD_RESULT(F_CALLBACK *FMOD_OUTPUT_GETPOSITIONCALLBACK)( + FMOD_OUTPUT_STATE *output_state, unsigned int *pcm); +typedef FMOD_RESULT(F_CALLBACK *FMOD_OUTPUT_LOCKCALLBACK)( + FMOD_OUTPUT_STATE *output_state, + unsigned int offset, + unsigned int length, + void **ptr1, + void **ptr2, + unsigned int *len1, + unsigned int *len2); +typedef FMOD_RESULT(F_CALLBACK *FMOD_OUTPUT_UNLOCKCALLBACK)( + FMOD_OUTPUT_STATE *output_state, + void *ptr1, + void *ptr2, + unsigned int len1, + unsigned int len2); +typedef FMOD_RESULT(F_CALLBACK *FMOD_OUTPUT_READFROMMIXER)( + FMOD_OUTPUT_STATE *output_state, void *buffer, unsigned int length); /* -[STRUCTURE] +[STRUCTURE] [ [DESCRIPTION] - When creating an output, declare one of these and provide the relevant callbacks and name for FMOD to use when it opens and reads a file of this type. + When creating an output, declare one of these and provide the relevant +callbacks and name for FMOD to use when it opens and reads a file of this type. [REMARKS] - Members marked with [in] mean the variable can be written to. The user can set the value.
    - Members marked with [out] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
    + Members marked with [in] mean the variable can be written to. The user can +set the value.
    Members marked with [out] mean the variable is modified by +FMOD and is for reading purposes only. Do not change this value.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] FMOD_OUTPUT_STATE ] */ -typedef struct FMOD_OUTPUT_DESCRIPTION -{ - const char *name; /* [in] Name of the output. */ - unsigned int version; /* [in] Plugin writer's version number. */ - int polling; /* [in] If TRUE (non zero), this tells FMOD to start a thread and call getposition / lock / unlock for feeding data. If 0, the output is probably callback based, so all the plugin needs to do is call readfrommixer to the appropriate pointer. */ - FMOD_OUTPUT_GETNUMDRIVERSCALLBACK getnumdrivers; /* [in] For sound device enumeration. This callback is to give System::getNumDrivers somthing to return. */ - FMOD_OUTPUT_GETDRIVERNAMECALLBACK getdrivername; /* [in] For sound device enumeration. This callback is to give System::getDriverName somthing to return. */ - FMOD_OUTPUT_GETDRIVERCAPSCALLBACK getdrivercaps; /* [in] For sound device enumeration. This callback is to give System::getDriverCaps somthing to return. */ - FMOD_OUTPUT_INITCALLBACK init; /* [in] Initialization function for the output device. This is called from System::init. */ - FMOD_OUTPUT_CLOSECALLBACK close; /* [in] Cleanup / close down function for the output device. This is called from System::close. */ - FMOD_OUTPUT_UPDATECALLBACK update; /* [in] Update function that is called once a frame by the user. This is called from System::update. */ - FMOD_OUTPUT_GETHANDLECALLBACK gethandle; /* [in] This is called from System::getOutputHandle. This is just to return a pointer to the internal system device object that the system may be using.*/ - FMOD_OUTPUT_GETPOSITIONCALLBACK getposition; /* [in] This is called from the FMOD software mixer thread if 'polling' = true. This returns a position value in samples so that FMOD knows where and when to fill its buffer. */ - FMOD_OUTPUT_LOCKCALLBACK lock; /* [in] This is called from the FMOD software mixer thread if 'polling' = true. This function provides a pointer to data that FMOD can write to when software mixing. */ - FMOD_OUTPUT_UNLOCKCALLBACK unlock; /* [in] This is called from the FMOD software mixer thread if 'polling' = true. This optional function accepts the data that has been mixed and copies it or does whatever it needs to before sending it to the hardware. */ +typedef struct FMOD_OUTPUT_DESCRIPTION { + const char *name; /* [in] Name of the output. */ + unsigned int version; /* [in] Plugin writer's version number. */ + int polling; /* [in] If TRUE (non zero), this tells FMOD to start a thread and + call getposition / lock / unlock for feeding data. If 0, the + output is probably callback based, so all the plugin needs to + do is call readfrommixer to the appropriate pointer. */ + FMOD_OUTPUT_GETNUMDRIVERSCALLBACK + getnumdrivers; /* [in] For sound device enumeration. This callback is to + give System::getNumDrivers somthing to return. */ + FMOD_OUTPUT_GETDRIVERNAMECALLBACK + getdrivername; /* [in] For sound device enumeration. This callback is to + give System::getDriverName somthing to return. */ + FMOD_OUTPUT_GETDRIVERCAPSCALLBACK + getdrivercaps; /* [in] For sound device enumeration. This callback is to + give System::getDriverCaps somthing to return. */ + FMOD_OUTPUT_INITCALLBACK + init; /* [in] Initialization function for the output device. This is + called from System::init. */ + FMOD_OUTPUT_CLOSECALLBACK + close; /* [in] Cleanup / close down function for the output device. This + is called from System::close. */ + FMOD_OUTPUT_UPDATECALLBACK + update; /* [in] Update function that is called once a frame by the user. + This is called from System::update. */ + FMOD_OUTPUT_GETHANDLECALLBACK + gethandle; /* [in] This is called from System::getOutputHandle. This is + just to return a pointer to the internal system device + object that the system may be using.*/ + FMOD_OUTPUT_GETPOSITIONCALLBACK + getposition; /* [in] This is called from the FMOD software mixer thread if + 'polling' = true. This returns a position value in + samples so that FMOD knows where and when to fill its + buffer. */ + FMOD_OUTPUT_LOCKCALLBACK + lock; /* [in] This is called from the FMOD software mixer thread if + 'polling' = true. This function provides a pointer to data that + FMOD can write to when software mixing. */ + FMOD_OUTPUT_UNLOCKCALLBACK + unlock; /* [in] This is called from the FMOD software mixer thread if + 'polling' = true. This optional function accepts the data that + has been mixed and copies it or does whatever it needs to + before sending it to the hardware. */ } FMOD_OUTPUT_DESCRIPTION; - /* -[STRUCTURE] +[STRUCTURE] [ [DESCRIPTION] Output plugin structure that is passed into each callback. [REMARKS] - Members marked with [in] mean the variable can be written to. The user can set the value.
    - Members marked with [out] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
    + Members marked with [in] mean the variable can be written to. The user can +set the value.
    Members marked with [out] mean the variable is modified by +FMOD and is for reading purposes only. Do not change this value.
    [PLATFORMS] - Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android + Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, +PlayStation 3, Wii, iPhone, 3GS, NGP, Android [SEE_ALSO] FMOD_OUTPUT_DESCRIPTION ] */ -struct FMOD_OUTPUT_STATE -{ - void *plugindata; /* [in] Plugin writer created data the output author wants to attach to this object. */ - FMOD_OUTPUT_READFROMMIXER readfrommixer; /* [out] Function to update mixer and write the result to the provided pointer. Used from callback based output only. Polling based output uses lock/unlock/getposition. */ +struct FMOD_OUTPUT_STATE { + void *plugindata; /* [in] Plugin writer created data the output author wants + to attach to this object. */ + FMOD_OUTPUT_READFROMMIXER + readfrommixer; /* [out] Function to update mixer and write the result to + the provided pointer. Used from callback based output + only. Polling based output uses + lock/unlock/getposition. */ }; #endif - - diff --git a/src/imports/fmodex/fmodlinux.h b/src/imports/fmodex/fmodlinux.h index 22bfc6a..03978b4 100644 --- a/src/imports/fmodex/fmodlinux.h +++ b/src/imports/fmodex/fmodlinux.h @@ -1,19 +1,21 @@ -/* =========================================================================================== */ -/* FMOD Linux Specific header file. Copyright (c), Firelight Technologies Pty, Ltd. 2005-2016. */ -/* =========================================================================================== */ +/* =========================================================================================== + */ +/* FMOD Linux Specific header file. Copyright (c), Firelight Technologies Pty, + * Ltd. 2005-2016. */ +/* =========================================================================================== + */ #ifndef _FMODLINUX_H #define _FMODLINUX_H #include "fmod.h" - /* -[STRUCTURE] +[STRUCTURE] [ [DESCRIPTION] - Use this structure with System::init to set the information required for linux - initialisation. + Use this structure with System::init to set the information required for +linux initialisation. Pass this structure in as the "extradriverdata" parameter in System::init. @@ -26,11 +28,11 @@ System::init ] */ -typedef struct FMOD_LINUX_EXTRADRIVERDATA -{ - const char *output_driver_arguments; /* ALSA Only - Arguments to apply to the selected output driver */ - const char *record_driver_arguments; /* ALSA Only - Arguments to apply to the selected input (record) driver */ +typedef struct FMOD_LINUX_EXTRADRIVERDATA { + const char *output_driver_arguments; /* ALSA Only - Arguments to apply to the + selected output driver */ + const char *record_driver_arguments; /* ALSA Only - Arguments to apply to the + selected input (record) driver */ } FMOD_LINUX_EXTRADRIVERDATA; #endif - diff --git a/src/main/asset/f2/lib/usb-rank.c b/src/main/asset/f2/lib/usb-rank.c index ebb90d7..5cd5258 100644 --- a/src/main/asset/f2/lib/usb-rank.c +++ b/src/main/asset/f2/lib/usb-rank.c @@ -4,46 +4,46 @@ #define ENC_DEC_INIT_SEED 0xEBADA1 -struct asset_f2_usb_rank* asset_f2_usb_rank_new(void) +struct asset_f2_usb_rank *asset_f2_usb_rank_new(void) { - // TODO - return malloc(sizeof(struct asset_f2_usb_rank)); + // TODO + return malloc(sizeof(struct asset_f2_usb_rank)); } -void asset_f2_usb_rank_finalize(struct asset_f2_usb_rank* rank) +void asset_f2_usb_rank_finalize(struct asset_f2_usb_rank *rank) { - /* don't include the checksum field */ - /* - rank->header.adler32 = util_adler32_calc(rank->header.adler_seed, - &rank->header.adler_seed, - sizeof(struct f2_profile_rank) - sizeof(uint32_t)); - */ + /* don't include the checksum field */ + /* + rank->header.adler32 = util_adler32_calc(rank->header.adler_seed, + &rank->header.adler_seed, + sizeof(struct f2_profile_rank) - sizeof(uint32_t)); + */ } -char* asset_f2_usb_rank_to_string(const struct asset_f2_usb_rank* rank) +char *asset_f2_usb_rank_to_string(const struct asset_f2_usb_rank *rank) { - // TODO - return ""; + // TODO + return ""; } -void asset_f2_usb_rank_decrypt(uint8_t* buf, size_t len) +void asset_f2_usb_rank_decrypt(uint8_t *buf, size_t len) { - uint32_t seed = ENC_DEC_INIT_SEED; + uint32_t seed = ENC_DEC_INIT_SEED; - for (int i = 0; i < len; i++){ - uint8_t smbuff = buf[i]; - buf[i] ^= (seed >> 8) & 0xff ; - seed = 0x68993 * (smbuff + seed) + 0x4FDCF; - } + for (int i = 0; i < len; i++) { + uint8_t smbuff = buf[i]; + buf[i] ^= (seed >> 8) & 0xff; + seed = 0x68993 * (smbuff + seed) + 0x4FDCF; + } } -void asset_f2_usb_rank_encrypt(uint8_t* buf, size_t len) +void asset_f2_usb_rank_encrypt(uint8_t *buf, size_t len) { - uint32_t seed = ENC_DEC_INIT_SEED; + uint32_t seed = ENC_DEC_INIT_SEED; - for (size_t i = 0; i < len; i++){ - uint8_t smbuff = buf[i] ^ ((seed >> 8) & 0xff); - buf[i] = smbuff ; - seed = 0x68993 * (smbuff + seed) + 0x4FDCF; - } + for (size_t i = 0; i < len; i++) { + uint8_t smbuff = buf[i] ^ ((seed >> 8) & 0xff); + buf[i] = smbuff; + seed = 0x68993 * (smbuff + seed) + 0x4FDCF; + } } \ No newline at end of file diff --git a/src/main/asset/f2/lib/usb-rank.h b/src/main/asset/f2/lib/usb-rank.h index 9eb279c..b34afd1 100644 --- a/src/main/asset/f2/lib/usb-rank.h +++ b/src/main/asset/f2/lib/usb-rank.h @@ -4,18 +4,18 @@ #include struct asset_f2_usb_rank { - // TODO + // TODO } __attribute__((__packed__)); -struct asset_f2_usb_rank* asset_f2_usb_rank_new(void); +struct asset_f2_usb_rank *asset_f2_usb_rank_new(void); // update checksum and prepare profile to get encrypted -void asset_f2_usb_rank_finalize(struct asset_f2_usb_rank* rank); +void asset_f2_usb_rank_finalize(struct asset_f2_usb_rank *rank); -char* asset_f2_usb_rank_to_string(const struct asset_f2_usb_rank* rank); +char *asset_f2_usb_rank_to_string(const struct asset_f2_usb_rank *rank); -void asset_f2_usb_rank_decrypt(uint8_t* buf, size_t len); +void asset_f2_usb_rank_decrypt(uint8_t *buf, size_t len); -void asset_f2_usb_rank_encrypt(uint8_t* buf, size_t len); +void asset_f2_usb_rank_encrypt(uint8_t *buf, size_t len); #endif \ No newline at end of file diff --git a/src/main/asset/f2/lib/usb-save.c b/src/main/asset/f2/lib/usb-save.c index 5fd8b5e..2eb35ca 100644 --- a/src/main/asset/f2/lib/usb-save.c +++ b/src/main/asset/f2/lib/usb-save.c @@ -4,44 +4,45 @@ #define ENC_DEC_INIT_SEED 0xEBADA1 -struct asset_f2_usb_save* asset_f2_usb_save_new(void) +struct asset_f2_usb_save *asset_f2_usb_save_new(void) { - // TODO - return malloc(sizeof(struct asset_f2_usb_save)); + // TODO + return malloc(sizeof(struct asset_f2_usb_save)); } -void asset_f2_usb_save_finalize(struct asset_f2_usb_save* save) +void asset_f2_usb_save_finalize(struct asset_f2_usb_save *save) { - /* don't include the checksum field */ - save->header.adler32 = util_adler32_calc(save->header.adler_seed, - &save->header.adler_seed, - sizeof(struct asset_f2_usb_save) - sizeof(uint32_t)); + /* don't include the checksum field */ + save->header.adler32 = util_adler32_calc( + save->header.adler_seed, + &save->header.adler_seed, + sizeof(struct asset_f2_usb_save) - sizeof(uint32_t)); } -char* asset_f2_usb_save_to_string(const struct asset_f2_usb_save* save) +char *asset_f2_usb_save_to_string(const struct asset_f2_usb_save *save) { - // TODO - return ""; + // TODO + return ""; } -void asset_f2_usb_save_decrypt(uint8_t* buf, size_t len) +void asset_f2_usb_save_decrypt(uint8_t *buf, size_t len) { - uint32_t seed = ENC_DEC_INIT_SEED; + uint32_t seed = ENC_DEC_INIT_SEED; - for (int i = 0; i < len; i++){ - uint8_t smbuff = buf[i]; - buf[i] ^= (seed >> 8) & 0xff ; - seed = 0x68993 * (smbuff + seed) + 0x4FDCF; - } + for (int i = 0; i < len; i++) { + uint8_t smbuff = buf[i]; + buf[i] ^= (seed >> 8) & 0xff; + seed = 0x68993 * (smbuff + seed) + 0x4FDCF; + } } -void asset_f2_usb_save_encrypt(uint8_t* buf, size_t len) +void asset_f2_usb_save_encrypt(uint8_t *buf, size_t len) { - uint32_t seed = ENC_DEC_INIT_SEED; + uint32_t seed = ENC_DEC_INIT_SEED; - for (size_t i = 0; i < len; i++){ - uint8_t smbuff = buf[i] ^ (seed >> 8) & 0xff; - buf[i] = smbuff ; - seed = 0x68993 * (smbuff + seed) + 0x4FDCF; - } + for (size_t i = 0; i < len; i++) { + uint8_t smbuff = buf[i] ^ (seed >> 8) & 0xff; + buf[i] = smbuff; + seed = 0x68993 * (smbuff + seed) + 0x4FDCF; + } } \ No newline at end of file diff --git a/src/main/asset/f2/lib/usb-save.h b/src/main/asset/f2/lib/usb-save.h index 0bc84fc..235dc0b 100644 --- a/src/main/asset/f2/lib/usb-save.h +++ b/src/main/asset/f2/lib/usb-save.h @@ -5,101 +5,101 @@ #include struct asset_f2_usb_save_machine_stats { - uint32_t beginner_mode_play_count; - uint32_t maniac_mode_play_count; - uint32_t unkn; - uint32_t unkn2; - uint32_t battle_mode_play_count; - uint32_t mission_zone_play_count; - uint32_t skill_zone_play_count; - uint32_t coop_mission_play_count; + uint32_t beginner_mode_play_count; + uint32_t maniac_mode_play_count; + uint32_t unkn; + uint32_t unkn2; + uint32_t battle_mode_play_count; + uint32_t mission_zone_play_count; + uint32_t skill_zone_play_count; + uint32_t coop_mission_play_count; } __attribute__((__packed__)); struct asset_f2_usb_save_machine_info { - /* NULL terminated */ - char version[8]; - /* NULL terminated */ - char cpu[128]; - /* NULL terminated */ - char motherboard[128]; - /* NULL terminated */ - char gfxcard[128]; - /* NULL terminated */ - char hdd[32]; - uint32_t total_ram_bytes; - uint32_t haspkey_id; + /* NULL terminated */ + char version[8]; + /* NULL terminated */ + char cpu[128]; + /* NULL terminated */ + char motherboard[128]; + /* NULL terminated */ + char gfxcard[128]; + /* NULL terminated */ + char hdd[32]; + uint32_t total_ram_bytes; + uint32_t haspkey_id; } __attribute__((__packed__)); struct asset_f2_usb_save_header { - uint32_t adler32; - uint32_t adler_seed; - /* NULL terminated */ - char player_id[8]; - uint32_t region; - uint32_t avatar_id; - uint32_t level; - float total_calories; - float total_v02; - uint64_t num_running_steps; - uint64_t num_games_played; - uint64_t exp; - uint64_t arcade_score; - uint32_t num_missions_completed; - uint32_t num_coop_missions_completed; - uint32_t battle_count_wins; - uint32_t battle_count_loses; - uint32_t battle_count_draws; - /* TODO: modifier stuff? */ - uint64_t unlock; - uint32_t unlock_seed; + uint32_t adler32; + uint32_t adler_seed; + /* NULL terminated */ + char player_id[8]; + uint32_t region; + uint32_t avatar_id; + uint32_t level; + float total_calories; + float total_v02; + uint64_t num_running_steps; + uint64_t num_games_played; + uint64_t exp; + uint64_t arcade_score; + uint32_t num_missions_completed; + uint32_t num_coop_missions_completed; + uint32_t battle_count_wins; + uint32_t battle_count_loses; + uint32_t battle_count_draws; + /* TODO: modifier stuff? */ + uint64_t unlock; + uint32_t unlock_seed; } __attribute__((__packed__)); struct asset_f2_usb_save_machine_highscore_entry { - uint32_t song_id; - uint8_t difficulty; - uint8_t mode; - uint8_t grade; - uint8_t clear_state; - uint32_t score_total; - uint32_t play_count; - uint32_t unkn; - /* NULL terminated */ - char player_id[8]; - uint32_t unkn2; - uint32_t null_padding; + uint32_t song_id; + uint8_t difficulty; + uint8_t mode; + uint8_t grade; + uint8_t clear_state; + uint32_t score_total; + uint32_t play_count; + uint32_t unkn; + /* NULL terminated */ + char player_id[8]; + uint32_t unkn2; + uint32_t null_padding; } __attribute__((__packed__)); struct asset_f2_usb_save_highscore_entry { - uint32_t song_id; - uint8_t difficulty; - uint8_t mode; - uint8_t grade; - uint8_t clear_and_unlock_state; - uint32_t score_total; - uint32_t play_count; - uint32_t null_padding; + uint32_t song_id; + uint8_t difficulty; + uint8_t mode; + uint8_t grade; + uint8_t clear_and_unlock_state; + uint32_t score_total; + uint32_t play_count; + uint32_t null_padding; } __attribute__((__packed__)); struct asset_f2_usb_save { - /* start offset: 0x00 */ - struct asset_f2_usb_save_header header; - /* start offset: 0x120 */ - struct asset_f2_usb_save_machine_info machine_info; - struct asset_f2_usb_save_machine_stats machine_stats; - /* start offset: 0x2F0 */ + /* start offset: 0x00 */ + struct asset_f2_usb_save_header header; + /* start offset: 0x120 */ + struct asset_f2_usb_save_machine_info machine_info; + struct asset_f2_usb_save_machine_stats machine_stats; + /* start offset: 0x2F0 */ - // TODO continue + // TODO continue } __attribute__((__packed__)); -struct asset_f2_usb_save* asset_f2_usb_save_new(void); +struct asset_f2_usb_save *asset_f2_usb_save_new(void); // update checksum and prepare profile to get encrypted -void asset_f2_usb_save_finalize(struct asset_f2_usb_save* save); +void asset_f2_usb_save_finalize(struct asset_f2_usb_save *save); -char* asset_f2_usb_save_to_string(const struct asset_f2_usb_save* save); +char *asset_f2_usb_save_to_string(const struct asset_f2_usb_save *save); -void asset_f2_usb_save_decrypt(uint8_t* buf, size_t len); +void asset_f2_usb_save_decrypt(uint8_t *buf, size_t len); -void asset_f2_usb_save_encrypt(uint8_t* buf, size_t len); +void asset_f2_usb_save_encrypt(uint8_t *buf, size_t len); #endif \ No newline at end of file diff --git a/src/main/asset/f2/lib/util.c b/src/main/asset/f2/lib/util.c index 3d69017..9621e1b 100644 --- a/src/main/asset/f2/lib/util.c +++ b/src/main/asset/f2/lib/util.c @@ -7,90 +7,100 @@ #include "util.h" -struct asset_f2_usb_rank* asset_f2_util_rank_usb_load_from_file(const char* path, bool encrypted) +struct asset_f2_usb_rank * +asset_f2_util_rank_usb_load_from_file(const char *path, bool encrypted) { - struct asset_f2_usb_rank* rank; - size_t size; + struct asset_f2_usb_rank *rank; + size_t size; - if (!util_file_load(path, (void**) &rank, &size, false)) { - log_error("Loading f2 rank file %s failed", path); - return NULL; - } + if (!util_file_load(path, (void **) &rank, &size, false)) { + log_error("Loading f2 rank file %s failed", path); + return NULL; + } - if (size != sizeof(struct asset_f2_usb_rank)) { - log_error("Invalid size of f2 rank file %s: %d != %d", path, size, - sizeof(struct asset_f2_usb_rank)); - free(rank); - return NULL; - } + if (size != sizeof(struct asset_f2_usb_rank)) { + log_error( + "Invalid size of f2 rank file %s: %d != %d", + path, + size, + sizeof(struct asset_f2_usb_rank)); + free(rank); + return NULL; + } - if (encrypted) { - asset_f2_usb_rank_decrypt((uint8_t*) rank, size); - } + if (encrypted) { + asset_f2_usb_rank_decrypt((uint8_t *) rank, size); + } - return rank; + return rank; } -bool asset_f2_util_rank_usb_save_to_file(const char* path, const struct asset_f2_usb_rank* rank, bool encrypt) +bool asset_f2_util_rank_usb_save_to_file( + const char *path, const struct asset_f2_usb_rank *rank, bool encrypt) { - struct asset_f2_usb_rank rank_enc; + struct asset_f2_usb_rank rank_enc; - memcpy(&rank_enc, rank, sizeof(struct asset_f2_usb_rank)); + memcpy(&rank_enc, rank, sizeof(struct asset_f2_usb_rank)); - if (encrypt) { - asset_f2_usb_rank_encrypt((uint8_t*) &rank_enc, - sizeof(struct asset_f2_usb_rank)); - } + if (encrypt) { + asset_f2_usb_rank_encrypt( + (uint8_t *) &rank_enc, sizeof(struct asset_f2_usb_rank)); + } - if (!util_file_save(path, (void**) &rank_enc, - sizeof(struct asset_f2_usb_rank))) { - log_error("Storing f2 rank data to %s failed", path); - return false; - } + if (!util_file_save( + path, (void **) &rank_enc, sizeof(struct asset_f2_usb_rank))) { + log_error("Storing f2 rank data to %s failed", path); + return false; + } - return true; + return true; } -struct asset_f2_usb_save* asset_f2_util_usb_save_load_from_file(const char* path, bool encrypted) +struct asset_f2_usb_save * +asset_f2_util_usb_save_load_from_file(const char *path, bool encrypted) { - struct asset_f2_usb_save* save; - size_t size; + struct asset_f2_usb_save *save; + size_t size; - if (!util_file_load(path, (void**) &save, &size, false)) { - log_error("Loading f2 save file %s failed", path); - return NULL; - } + if (!util_file_load(path, (void **) &save, &size, false)) { + log_error("Loading f2 save file %s failed", path); + return NULL; + } - if (size != sizeof(struct asset_f2_usb_save)) { - log_error("Invalid size of f2 save file %s: %d != %d", path, size, - sizeof(struct asset_f2_usb_save)); - free(save); - return NULL; - } + if (size != sizeof(struct asset_f2_usb_save)) { + log_error( + "Invalid size of f2 save file %s: %d != %d", + path, + size, + sizeof(struct asset_f2_usb_save)); + free(save); + return NULL; + } - if (encrypted) { - asset_f2_usb_save_decrypt((uint8_t*) save, size); - } + if (encrypted) { + asset_f2_usb_save_decrypt((uint8_t *) save, size); + } - return save; + return save; } -bool asset_f2_util_usb_save_save_to_file(const char* path, const struct asset_f2_usb_save* save, bool encrypt) +bool asset_f2_util_usb_save_save_to_file( + const char *path, const struct asset_f2_usb_save *save, bool encrypt) { - struct asset_f2_usb_save save_enc; + struct asset_f2_usb_save save_enc; - memcpy(&save_enc, save, sizeof(struct asset_f2_usb_save)); + memcpy(&save_enc, save, sizeof(struct asset_f2_usb_save)); - if (encrypt) { - asset_f2_usb_save_encrypt((uint8_t*) &save_enc, - sizeof(struct asset_f2_usb_save)); - } + if (encrypt) { + asset_f2_usb_save_encrypt( + (uint8_t *) &save_enc, sizeof(struct asset_f2_usb_save)); + } - if (!util_file_save(path, (const void*) &save_enc, - sizeof(struct asset_f2_usb_save))) { - log_error("Storing f2 save data to %s failed", path); - return false; - } + if (!util_file_save( + path, (const void *) &save_enc, sizeof(struct asset_f2_usb_save))) { + log_error("Storing f2 save data to %s failed", path); + return false; + } - return true; + return true; } \ No newline at end of file diff --git a/src/main/asset/f2/lib/util.h b/src/main/asset/f2/lib/util.h index 7870793..e1a5520 100644 --- a/src/main/asset/f2/lib/util.h +++ b/src/main/asset/f2/lib/util.h @@ -7,15 +7,19 @@ #include "usb-save.h" // load from file and decrypt, returns decrypted struct -struct asset_f2_usb_rank* asset_f2_util_usb_rank_load_from_file(const char* path, bool encrypted); +struct asset_f2_usb_rank * +asset_f2_util_usb_rank_load_from_file(const char *path, bool encrypted); // takes decrypted rank data, encrypts it and writes it to file -bool asset_f2_util_usb_rank_save_to_file(const char* path, const struct asset_f2_usb_rank* rank, bool encrypt); +bool asset_f2_util_usb_rank_save_to_file( + const char *path, const struct asset_f2_usb_rank *rank, bool encrypt); // load from file and decrypt, returns decrypted struct -struct asset_f2_usb_save* asset_f2_util_usb_save_load_from_file(const char* path, bool encrypted); +struct asset_f2_usb_save * +asset_f2_util_usb_save_load_from_file(const char *path, bool encrypted); // takes decrypted save data, encrypts it and writes it to file -bool asset_f2_util_usb_save_save_to_file(const char* path, const struct asset_f2_usb_save* save, bool encrypt); +bool asset_f2_util_usb_save_save_to_file( + const char *path, const struct asset_f2_usb_save *save, bool encrypt); #endif \ No newline at end of file diff --git a/src/main/asset/fex/lib/usb-rank.c b/src/main/asset/fex/lib/usb-rank.c index 4d0515c..3664658 100644 --- a/src/main/asset/fex/lib/usb-rank.c +++ b/src/main/asset/fex/lib/usb-rank.c @@ -2,31 +2,30 @@ #include "usb-rank.h" -struct asset_fex_usb_rank* asset_fex_usb_rank_new(void) +struct asset_fex_usb_rank *asset_fex_usb_rank_new(void) { - return malloc(sizeof(struct asset_fex_usb_rank)); + return malloc(sizeof(struct asset_fex_usb_rank)); } -void asset_fex_usb_rank_finalize(struct asset_fex_usb_rank* rank) +void asset_fex_usb_rank_finalize(struct asset_fex_usb_rank *rank) { - } -char* asset_fex_usb_rank_to_string(const struct asset_fex_usb_rank* rank) +char *asset_fex_usb_rank_to_string(const struct asset_fex_usb_rank *rank) { - return malloc(0); + return malloc(0); } -void asset_fex_usb_rank_decrypt(uint8_t* buf, size_t len) +void asset_fex_usb_rank_decrypt(uint8_t *buf, size_t len) { - for (size_t a = len - 1; a > 0; --a) { - buf[a] = (buf[a] ^ buf[a - 1]) + ((a * 1234567) >> 8); - } + for (size_t a = len - 1; a > 0; --a) { + buf[a] = (buf[a] ^ buf[a - 1]) + ((a * 1234567) >> 8); + } } -void asset_fex_usb_rank_encrypt(uint8_t* buf, size_t len) +void asset_fex_usb_rank_encrypt(uint8_t *buf, size_t len) { - for (size_t a = 1; a < len; ++a) { - buf[a] = (buf[a] - ((a * 1234567) >> 8)) ^ buf[a - 1]; - } + for (size_t a = 1; a < len; ++a) { + buf[a] = (buf[a] - ((a * 1234567) >> 8)) ^ buf[a - 1]; + } } \ No newline at end of file diff --git a/src/main/asset/fex/lib/usb-rank.h b/src/main/asset/fex/lib/usb-rank.h index 3154275..cc958bd 100644 --- a/src/main/asset/fex/lib/usb-rank.h +++ b/src/main/asset/fex/lib/usb-rank.h @@ -5,24 +5,24 @@ #include struct asset_fex_usb_rank_header { - uint32_t adler32; - /* NULL terminated */ - char player_id[8]; + uint32_t adler32; + /* NULL terminated */ + char player_id[8]; } __attribute__((__packed__)); struct asset_fex_usb_rank { - struct asset_fex_usb_rank_header header; + struct asset_fex_usb_rank_header header; } __attribute__((__packed__)); -struct asset_fex_usb_rank* asset_fex_usb_rank_new(void); +struct asset_fex_usb_rank *asset_fex_usb_rank_new(void); // update checksum and prepare profile to get encrypted -void asset_fex_usb_rank_finalize(struct asset_fex_usb_rank* rank); +void asset_fex_usb_rank_finalize(struct asset_fex_usb_rank *rank); -char* asset_fex_usb_rank_to_string(const struct asset_fex_usb_rank* rank); +char *asset_fex_usb_rank_to_string(const struct asset_fex_usb_rank *rank); -void asset_fex_usb_rank_decrypt(uint8_t* buf, size_t len); +void asset_fex_usb_rank_decrypt(uint8_t *buf, size_t len); -void asset_fex_usb_rank_encrypt(uint8_t* buf, size_t len); +void asset_fex_usb_rank_encrypt(uint8_t *buf, size_t len); #endif \ No newline at end of file diff --git a/src/main/asset/fex/lib/usb-save.c b/src/main/asset/fex/lib/usb-save.c index 9d4007a..44edc1e 100644 --- a/src/main/asset/fex/lib/usb-save.c +++ b/src/main/asset/fex/lib/usb-save.c @@ -7,333 +7,312 @@ #include "usb-save.h" -static char* fex_profile_save_header_to_string( - const struct asset_fex_usb_save_header* header) +static char *fex_profile_save_header_to_string( + const struct asset_fex_usb_save_header *header) { - char* buffer; + char *buffer; - buffer = (char*) util_xmalloc(256); - memset(buffer, 0, 256); + buffer = (char *) util_xmalloc(256); + memset(buffer, 0, 256); - util_str_format(buffer, 256, - "-------------- header --------------\n" - "adler32: %X\n" - "usb_serial: %s\n" - "dongle_serial: %X\n", - header->adler32, - header->usb_serial, - header->dongle_serial); + util_str_format( + buffer, + 256, + "-------------- header --------------\n" + "adler32: %X\n" + "usb_serial: %s\n" + "dongle_serial: %X\n", + header->adler32, + header->usb_serial, + header->dongle_serial); - return buffer; + return buffer; } -static char* fex_profile_save_player_to_string( - const struct asset_fex_usb_save_player* player) +static char *fex_profile_save_player_to_string( + const struct asset_fex_usb_save_player *player) { - char* buffer; + char *buffer; - buffer = (char*) util_xmalloc(1024); - memset(buffer, 0, 1024); + buffer = (char *) util_xmalloc(1024); + memset(buffer, 0, 1024); - util_str_format(buffer, 1024, - "-------------- player --------------\n" - "unkn: %X\n" - "unkn2: %X\n" - "avatar_id: %d\n" - "player_lvl: %d\n" - "unkn3: %X\n" - "player_id: %s\n" - "unkn4: %X\n" - "unkn5: %X\n" - "unkn6: %X\n" - "unkn7: %X\n" - "unkn8: %X\n" - "unkn9: %X\n" - "unkn10: %X\n" - "unkn11: %X\n" - "unkn12: %X\n" - "unkn13: %X\n" - "unkn14: %X\n" - "unkn15: %X\n" - "total_step: %d\n" - "play_count: %d\n" - "exp: %d\n" - "num_quest_world_passed: %d\n" - "unkn16: %X\n" - "arcade_score: %d\n" - "num_battle_wins: %d\n" - "num_battle_loss: %d\n" - "num_battle_draw: %d\n", - player->unkn, - player->unkn2, - player->avatar_id, - player->player_lvl, - player->unkn3, - player->player_id, - player->unkn4, - player->unkn5, - player->unkn6, - player->unkn7, - player->unkn8, - player->unkn9, - player->unkn10, - player->unkn11, - player->unkn12, - player->unkn13, - player->unkn14, - player->unkn15, - player->total_step, - player->play_count, - player->exp, - player->num_quest_world_passed, - player->unkn16, - player->arcade_score, - player->num_battle_wins, - player->num_battle_loss, - player->num_battle_draw); + util_str_format( + buffer, + 1024, + "-------------- player --------------\n" + "unkn: %X\n" + "unkn2: %X\n" + "avatar_id: %d\n" + "player_lvl: %d\n" + "unkn3: %X\n" + "player_id: %s\n" + "unkn4: %X\n" + "unkn5: %X\n" + "unkn6: %X\n" + "unkn7: %X\n" + "unkn8: %X\n" + "unkn9: %X\n" + "unkn10: %X\n" + "unkn11: %X\n" + "unkn12: %X\n" + "unkn13: %X\n" + "unkn14: %X\n" + "unkn15: %X\n" + "total_step: %d\n" + "play_count: %d\n" + "exp: %d\n" + "num_quest_world_passed: %d\n" + "unkn16: %X\n" + "arcade_score: %d\n" + "num_battle_wins: %d\n" + "num_battle_loss: %d\n" + "num_battle_draw: %d\n", + player->unkn, + player->unkn2, + player->avatar_id, + player->player_lvl, + player->unkn3, + player->player_id, + player->unkn4, + player->unkn5, + player->unkn6, + player->unkn7, + player->unkn8, + player->unkn9, + player->unkn10, + player->unkn11, + player->unkn12, + player->unkn13, + player->unkn14, + player->unkn15, + player->total_step, + player->play_count, + player->exp, + player->num_quest_world_passed, + player->unkn16, + player->arcade_score, + player->num_battle_wins, + player->num_battle_loss, + player->num_battle_draw); - return buffer; + return buffer; } -static char* fex_profile_save_mods_to_string( - const struct asset_fex_usb_save_player_mods* mods) +static char *fex_profile_save_mods_to_string( + const struct asset_fex_usb_save_player_mods *mods) { - char* buffer; + char *buffer; - buffer = (char*) util_xmalloc(128); - memset(buffer, 0, 128); + buffer = (char *) util_xmalloc(128); + memset(buffer, 0, 128); - util_str_format(buffer, 128, - "-------------- modifiers --------------\n" - "modifiers: %X\n" - "half_speed_mod: %X\n" - "noteskin: %X\n", - mods->modifiers, - mods->half_speed_mod, - mods->noteskin); + util_str_format( + buffer, + 128, + "-------------- modifiers --------------\n" + "modifiers: %X\n" + "half_speed_mod: %X\n" + "noteskin: %X\n", + mods->modifiers, + mods->half_speed_mod, + mods->noteskin); - return buffer; + return buffer; } -static char* fex_profile_save_mod_unlocks_to_string( - const struct asset_fex_usb_save_mod_unlocks* unlocks) +static char *fex_profile_save_mod_unlocks_to_string( + const struct asset_fex_usb_save_mod_unlocks *unlocks) { - char* merged; - char* buffer; - char* tmp; - const size_t buf_size = 512; + char *merged; + char *buffer; + char *tmp; + const size_t buf_size = 512; - merged = (char*) util_xmalloc(buf_size); - memset(merged, 0, buf_size); + merged = (char *) util_xmalloc(buf_size); + memset(merged, 0, buf_size); - buffer = (char*) util_xmalloc(buf_size); - memset(buffer, 0, buf_size); + buffer = (char *) util_xmalloc(buf_size); + memset(buffer, 0, buf_size); - util_str_format(buffer, buf_size, - "-------------- mod unlocks --------------\n" ); + util_str_format( + buffer, buf_size, "-------------- mod unlocks --------------\n"); + + tmp = util_str_merge(merged, buffer); + free(merged); + merged = tmp; + + for (uint32_t i = 0; i < 0x12; i++) { + util_str_format(buffer, buf_size, "unkn0[%d]: %d\n", i, unlocks->unkn0[i]); tmp = util_str_merge(merged, buffer); + free(merged); merged = tmp; + } - for (uint32_t i = 0; i < 0x12; i++) { - util_str_format(buffer, buf_size, - "unkn0[%d]: %d\n", - i, - unlocks->unkn0[i]); + util_str_format(buffer, buf_size, "display_va: %d\n", unlocks->display_va); - tmp = util_str_merge(merged, buffer); + tmp = util_str_merge(merged, buffer); + free(merged); + merged = tmp; - free(merged); - merged = tmp; - } - - util_str_format(buffer, buf_size, - "display_va: %d\n", - unlocks->display_va); + for (uint32_t i = 0; i < 0x0D; i++) { + util_str_format(buffer, buf_size, "unkn1[%d]: %d\n", i, unlocks->unkn1[i]); tmp = util_str_merge(merged, buffer); + free(merged); merged = tmp; + } - for (uint32_t i = 0; i < 0x0D; i++) { - util_str_format(buffer, buf_size, - "unkn1[%d]: %d\n", - i, - unlocks->unkn1[i]); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < 0x10; i++) { - util_str_format(buffer, buf_size, - "noteskins[%d]: %d\n", - i, - unlocks->noteskins[i]); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < 0x04; i++) { - util_str_format(buffer, buf_size, - "unkn2[%d]: %d\n", - i, - unlocks->unkn2[i]); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < 0x03; i++) { - util_str_format(buffer, buf_size, - "path[%d]: %d\n", - i, - unlocks->path[i]); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < 0x06; i++) { - util_str_format(buffer, buf_size, - "unkn3[%d]: %d\n", - i, - unlocks->unkn3[i]); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - util_str_format(buffer, buf_size, - "xj: %d\n", - unlocks->xj); + for (uint32_t i = 0; i < 0x10; i++) { + util_str_format( + buffer, buf_size, "noteskins[%d]: %d\n", i, unlocks->noteskins[i]); tmp = util_str_merge(merged, buffer); + free(merged); merged = tmp; + } - for (uint32_t i = 0; i < 0x02; i++) { - util_str_format(buffer, buf_size, - "system[%d]: %d\n", - i, - unlocks->system[i]); + for (uint32_t i = 0; i < 0x04; i++) { + util_str_format(buffer, buf_size, "unkn2[%d]: %d\n", i, unlocks->unkn2[i]); - tmp = util_str_merge(merged, buffer); + tmp = util_str_merge(merged, buffer); - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < 0x08; i++) { - util_str_format(buffer, buf_size, - "rush[%d]: %d\n", - i, - unlocks->rush[i]); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < 0x1A; i++) { - util_str_format(buffer, buf_size, - "unkn4[%d]: %d\n", - i, - unlocks->unkn4[i]); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - return merged; -} - -static char* fex_profile_save_mission_state_to_string( - const struct asset_fex_usb_save_mission_state* state) -{ - char* buffer; - - buffer = (char*) util_xmalloc(128); - memset(buffer, 0, 128); - - util_str_format(buffer, 128, - "-------------- mission state --------------\n" - "quest_world_location: %X\n" - "skill_up_zone_location: %X\n", - state->quest_world_location, - state->skill_up_zone_location); - - return buffer; -} - -struct asset_fex_usb_save* asset_fex_usb_save_new(void) -{ - return malloc(sizeof(struct asset_fex_usb_save)); -} - -void asset_fex_usb_save_finalize(struct asset_fex_usb_save* save) -{ - -} - -char* asset_fex_usb_save_to_string(const struct asset_fex_usb_save* save) -{ - char* header; - char* player; - char* mods; - char* unlocks; - char* mission_state; - char* merged; - char* merged2; - - header = fex_profile_save_header_to_string(&save->header); - player = fex_profile_save_player_to_string(&save->player); - mods = fex_profile_save_mods_to_string(&save->mods); - unlocks = fex_profile_save_mod_unlocks_to_string(&save->mod_unlocks); - mission_state = fex_profile_save_mission_state_to_string(&save->mission_state); - - merged = util_str_merge(header, player); - merged2 = util_str_merge(merged, mods); free(merged); - merged = util_str_merge(merged2, unlocks); - free(merged2); - merged2 = util_str_merge(merged, mission_state); + merged = tmp; + } + + for (uint32_t i = 0; i < 0x03; i++) { + util_str_format(buffer, buf_size, "path[%d]: %d\n", i, unlocks->path[i]); + + tmp = util_str_merge(merged, buffer); + free(merged); + merged = tmp; + } - free(header); - free(player); - free(mods); - free(unlocks); - free(mission_state); + for (uint32_t i = 0; i < 0x06; i++) { + util_str_format(buffer, buf_size, "unkn3[%d]: %d\n", i, unlocks->unkn3[i]); - return merged2; + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; + } + + util_str_format(buffer, buf_size, "xj: %d\n", unlocks->xj); + + tmp = util_str_merge(merged, buffer); + free(merged); + merged = tmp; + + for (uint32_t i = 0; i < 0x02; i++) { + util_str_format( + buffer, buf_size, "system[%d]: %d\n", i, unlocks->system[i]); + + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; + } + + for (uint32_t i = 0; i < 0x08; i++) { + util_str_format(buffer, buf_size, "rush[%d]: %d\n", i, unlocks->rush[i]); + + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; + } + + for (uint32_t i = 0; i < 0x1A; i++) { + util_str_format(buffer, buf_size, "unkn4[%d]: %d\n", i, unlocks->unkn4[i]); + + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; + } + + return merged; } -void asset_fex_usb_save_decrypt(uint8_t* buf, size_t len) +static char *fex_profile_save_mission_state_to_string( + const struct asset_fex_usb_save_mission_state *state) { - for (size_t a = len - 1; a > 0; --a) { - buf[a] = (buf[a] ^ buf[a - 1]) + ((a * 1234567) >> 8); - } + char *buffer; + + buffer = (char *) util_xmalloc(128); + memset(buffer, 0, 128); + + util_str_format( + buffer, + 128, + "-------------- mission state --------------\n" + "quest_world_location: %X\n" + "skill_up_zone_location: %X\n", + state->quest_world_location, + state->skill_up_zone_location); + + return buffer; } -void asset_fex_usb_save_encrypt(uint8_t* buf, size_t len) +struct asset_fex_usb_save *asset_fex_usb_save_new(void) { - for (size_t a = 1; a < len; ++a) { - buf[a] = (buf[a] - ((a * 1234567) >> 8)) ^ buf[a - 1]; - } + return malloc(sizeof(struct asset_fex_usb_save)); +} + +void asset_fex_usb_save_finalize(struct asset_fex_usb_save *save) +{ +} + +char *asset_fex_usb_save_to_string(const struct asset_fex_usb_save *save) +{ + char *header; + char *player; + char *mods; + char *unlocks; + char *mission_state; + char *merged; + char *merged2; + + header = fex_profile_save_header_to_string(&save->header); + player = fex_profile_save_player_to_string(&save->player); + mods = fex_profile_save_mods_to_string(&save->mods); + unlocks = fex_profile_save_mod_unlocks_to_string(&save->mod_unlocks); + mission_state = + fex_profile_save_mission_state_to_string(&save->mission_state); + + merged = util_str_merge(header, player); + merged2 = util_str_merge(merged, mods); + free(merged); + merged = util_str_merge(merged2, unlocks); + free(merged2); + merged2 = util_str_merge(merged, mission_state); + free(merged); + + free(header); + free(player); + free(mods); + free(unlocks); + free(mission_state); + + return merged2; +} + +void asset_fex_usb_save_decrypt(uint8_t *buf, size_t len) +{ + for (size_t a = len - 1; a > 0; --a) { + buf[a] = (buf[a] ^ buf[a - 1]) + ((a * 1234567) >> 8); + } +} + +void asset_fex_usb_save_encrypt(uint8_t *buf, size_t len) +{ + for (size_t a = 1; a < len; ++a) { + buf[a] = (buf[a] - ((a * 1234567) >> 8)) ^ buf[a - 1]; + } } \ No newline at end of file diff --git a/src/main/asset/fex/lib/usb-save.h b/src/main/asset/fex/lib/usb-save.h index fd509ef..c481ebd 100644 --- a/src/main/asset/fex/lib/usb-save.h +++ b/src/main/asset/fex/lib/usb-save.h @@ -5,187 +5,187 @@ #include enum asset_fex_usb_save_noteskins { - ASSET_FEX_USB_SAVE_SKIN_DEFAULT = 0x00, - ASSET_FEX_USB_SAVE_SKIN_HANAFUDA = 0x01, - ASSET_FEX_USB_SAVE_SKIN_CLASSIC = 0x02, - ASSET_FEX_USB_SAVE_SKIN_CANDY = 0x03, - ASSET_FEX_USB_SAVE_SKIN_PORING = 0x04, - ASSET_FEX_USB_SAVE_SKIN_MUSICAL_NOTES = 0x05, - ASSET_FEX_USB_SAVE_SKIN_CANON_D = 0x06, - ASSET_FEX_USB_SAVE_SKIN_PLAYING_CARDS = 0x07, - ASSET_FEX_USB_SAVE_SKIN_NX = 0x08, - ASSET_FEX_USB_SAVE_SKIN_DIGNITY = 0x09, - ASSET_FEX_USB_SAVE_SKIN_HORSE_HEAD = 0x0A, - ASSET_FEX_USB_SAVE_SKIN_DOG = 0x0B, - ASSET_FEX_USB_SAVE_SKIN_GIRL = 0x0C, - ASSET_FEX_USB_SAVE_SKIN_FIRE = 0x0D, - ASSET_FEX_USB_SAVE_SKIN_ICE = 0x0E, - ASSET_FEX_USB_SAVE_SKIN_WIND = 0x0F, - ASSET_FEX_USB_SAVE_SKIN_RED_DP = 0x10, - ASSET_FEX_USB_SAVE_SKIN_BLUE_DP = 0x11, - ASSET_FEX_USB_SAVE_SKIN_YELLOW_DP = 0x12, - ASSET_FEX_USB_SAVE_SKIN_NXA = 0x13, - ASSET_FEX_USB_SAVE_SKIN_NX2 = 0x14, - ASSET_FEX_USB_SAVE_SKIN_ELECTRIC_FIESTA = 0x15, - ASSET_FEX_USB_SAVE_SKIN_DRUM = 0x16, - ASSET_FEX_USB_SAVE_SKIN_BULLET = 0x17, - ASSET_FEX_USB_SAVE_SKIN_BLUE_DRUM = 0x18, - ASSET_FEX_USB_SAVE_SKIN_RED_DRUM = 0x19, - ASSET_FEX_USB_SAVE_SKIN_YELLOW_DRUM = 0x1A, - ASSET_FEX_USB_SAVE_SKIN_WORLD_CUP = 0x1B, - ASSET_FEX_USB_SAVE_SKIN_PREX3 = 0x1C, - ASSET_FEX_USB_SAVE_SKIN_FIESTA_BASIC = 0x1D, + ASSET_FEX_USB_SAVE_SKIN_DEFAULT = 0x00, + ASSET_FEX_USB_SAVE_SKIN_HANAFUDA = 0x01, + ASSET_FEX_USB_SAVE_SKIN_CLASSIC = 0x02, + ASSET_FEX_USB_SAVE_SKIN_CANDY = 0x03, + ASSET_FEX_USB_SAVE_SKIN_PORING = 0x04, + ASSET_FEX_USB_SAVE_SKIN_MUSICAL_NOTES = 0x05, + ASSET_FEX_USB_SAVE_SKIN_CANON_D = 0x06, + ASSET_FEX_USB_SAVE_SKIN_PLAYING_CARDS = 0x07, + ASSET_FEX_USB_SAVE_SKIN_NX = 0x08, + ASSET_FEX_USB_SAVE_SKIN_DIGNITY = 0x09, + ASSET_FEX_USB_SAVE_SKIN_HORSE_HEAD = 0x0A, + ASSET_FEX_USB_SAVE_SKIN_DOG = 0x0B, + ASSET_FEX_USB_SAVE_SKIN_GIRL = 0x0C, + ASSET_FEX_USB_SAVE_SKIN_FIRE = 0x0D, + ASSET_FEX_USB_SAVE_SKIN_ICE = 0x0E, + ASSET_FEX_USB_SAVE_SKIN_WIND = 0x0F, + ASSET_FEX_USB_SAVE_SKIN_RED_DP = 0x10, + ASSET_FEX_USB_SAVE_SKIN_BLUE_DP = 0x11, + ASSET_FEX_USB_SAVE_SKIN_YELLOW_DP = 0x12, + ASSET_FEX_USB_SAVE_SKIN_NXA = 0x13, + ASSET_FEX_USB_SAVE_SKIN_NX2 = 0x14, + ASSET_FEX_USB_SAVE_SKIN_ELECTRIC_FIESTA = 0x15, + ASSET_FEX_USB_SAVE_SKIN_DRUM = 0x16, + ASSET_FEX_USB_SAVE_SKIN_BULLET = 0x17, + ASSET_FEX_USB_SAVE_SKIN_BLUE_DRUM = 0x18, + ASSET_FEX_USB_SAVE_SKIN_RED_DRUM = 0x19, + ASSET_FEX_USB_SAVE_SKIN_YELLOW_DRUM = 0x1A, + ASSET_FEX_USB_SAVE_SKIN_WORLD_CUP = 0x1B, + ASSET_FEX_USB_SAVE_SKIN_PREX3 = 0x1C, + ASSET_FEX_USB_SAVE_SKIN_FIESTA_BASIC = 0x1D, }; struct asset_fex_usb_save_header { - /* 0x00 */ - uint32_t adler32; - /* 0x04: NULL terminated */ - char usb_serial[0x40]; - /* 0x44: Deprecated from old games */ - uint32_t dongle_serial; + /* 0x00 */ + uint32_t adler32; + /* 0x04: NULL terminated */ + char usb_serial[0x40]; + /* 0x44: Deprecated from old games */ + uint32_t dongle_serial; } __attribute__((__packed__)); struct asset_fex_usb_save_player { - /* 0x48 */ - uint32_t unkn; - /* 0x4C */ - uint32_t unkn2; - /* 0x50 */ - uint8_t avatar_id; - /* 0x51: Range: 0x00 - 0x21 */ - uint8_t player_lvl; - /* 0x52: PumBi sets it to 0xC4 */ - uint16_t unkn3; - /* 0x54: NULL terminated */ - char player_id[8]; - /* 0x5C */ - uint32_t unkn4; - /* 0x60 */ - uint32_t unkn5; - /* 0x64: Each time you save, it inc. by 6... */ - uint32_t unkn6; - /* 0x68 */ - uint32_t unkn7; - /* 0x6C */ - uint32_t unkn8; - /* 0x70 */ - uint32_t unkn9; - /* 0x74 */ - uint32_t unkn10; - /* 0x78 */ - uint32_t unkn11; - /* 0x7C */ - uint32_t unkn12; - /* 0x80 */ - uint32_t unkn13; - /* 0x84 */ - uint32_t unkn14; - /* 0x88 */ - uint32_t unkn15; - /* 0x8C */ - uint32_t total_step; - /* 0x90 */ - uint32_t play_count; - /* 0x94 */ - uint32_t exp; - /* 0x98 */ - uint32_t num_quest_world_passed; - /* 0x9C */ - uint32_t unkn16; - /* 0xA0 */ - uint32_t arcade_score; - /* 0xA8 */ - uint32_t num_battle_wins; - /* 0xAC */ - uint32_t num_battle_loss; - /* 0xB0 */ - uint32_t num_battle_draw; + /* 0x48 */ + uint32_t unkn; + /* 0x4C */ + uint32_t unkn2; + /* 0x50 */ + uint8_t avatar_id; + /* 0x51: Range: 0x00 - 0x21 */ + uint8_t player_lvl; + /* 0x52: PumBi sets it to 0xC4 */ + uint16_t unkn3; + /* 0x54: NULL terminated */ + char player_id[8]; + /* 0x5C */ + uint32_t unkn4; + /* 0x60 */ + uint32_t unkn5; + /* 0x64: Each time you save, it inc. by 6... */ + uint32_t unkn6; + /* 0x68 */ + uint32_t unkn7; + /* 0x6C */ + uint32_t unkn8; + /* 0x70 */ + uint32_t unkn9; + /* 0x74 */ + uint32_t unkn10; + /* 0x78 */ + uint32_t unkn11; + /* 0x7C */ + uint32_t unkn12; + /* 0x80 */ + uint32_t unkn13; + /* 0x84 */ + uint32_t unkn14; + /* 0x88 */ + uint32_t unkn15; + /* 0x8C */ + uint32_t total_step; + /* 0x90 */ + uint32_t play_count; + /* 0x94 */ + uint32_t exp; + /* 0x98 */ + uint32_t num_quest_world_passed; + /* 0x9C */ + uint32_t unkn16; + /* 0xA0 */ + uint32_t arcade_score; + /* 0xA8 */ + uint32_t num_battle_wins; + /* 0xAC */ + uint32_t num_battle_loss; + /* 0xB0 */ + uint32_t num_battle_draw; } __attribute__((__packed__)); struct asset_fex_usb_save_player_mods { - /* 0xB4: The first set of saved modifiers (see MOD_1 below) */ - uint32_t modifiers; - /* 0xB8: If the +0.5x mod is enabled (boolean) */ - uint32_t half_speed_mod; - /* 0xBC: Which noteskin is currently selected (see NOTE_S below) */ - uint32_t noteskin; + /* 0xB4: The first set of saved modifiers (see MOD_1 below) */ + uint32_t modifiers; + /* 0xB8: If the +0.5x mod is enabled (boolean) */ + uint32_t half_speed_mod; + /* 0xBC: Which noteskin is currently selected (see NOTE_S below) */ + uint32_t noteskin; } __attribute__((__packed__)); struct asset_fex_usb_save_mod_unlocks { - /* 0xC0: Unknown Unlocks Area */ - uint8_t unkn0[0x12]; - /* 0xD2: Boolean for unlocking VA Mod. */ - uint8_t display_va; - /* 0xD3: Unknown Unlocks Area */ - uint8_t unkn1[0x0D]; - /* 0xE0: Array of bools - Which Noteskins are Unlocked. */ - uint8_t noteskins[0x10]; - /* 0xF0: Unknown Unlocks Area */ - uint8_t unkn2[0x04]; - /* 0xF4: Array of bools - Which Path Mods are Unlocked. */ - uint8_t path[0x03]; - /* 0xF7: Unknown Unlocks Area */ - uint8_t unkn3[0x06]; - /* 0xFE: Boolean for unlocking XJ */ - uint8_t xj; - /* 0x100: Array of bools - Which System Mods are Unlocked. */ - uint8_t system[0x02]; - /* 0x102: Array of bools - Which Rush/NOT Modes are Unlocked. */ - uint8_t rush[0x08]; - /* 0x10A: Unknown Unlocks Area */ - uint8_t unkn4[0x1A]; + /* 0xC0: Unknown Unlocks Area */ + uint8_t unkn0[0x12]; + /* 0xD2: Boolean for unlocking VA Mod. */ + uint8_t display_va; + /* 0xD3: Unknown Unlocks Area */ + uint8_t unkn1[0x0D]; + /* 0xE0: Array of bools - Which Noteskins are Unlocked. */ + uint8_t noteskins[0x10]; + /* 0xF0: Unknown Unlocks Area */ + uint8_t unkn2[0x04]; + /* 0xF4: Array of bools - Which Path Mods are Unlocked. */ + uint8_t path[0x03]; + /* 0xF7: Unknown Unlocks Area */ + uint8_t unkn3[0x06]; + /* 0xFE: Boolean for unlocking XJ */ + uint8_t xj; + /* 0x100: Array of bools - Which System Mods are Unlocked. */ + uint8_t system[0x02]; + /* 0x102: Array of bools - Which Rush/NOT Modes are Unlocked. */ + uint8_t rush[0x08]; + /* 0x10A: Unknown Unlocks Area */ + uint8_t unkn4[0x1A]; } __attribute__((__packed__)); struct asset_fex_usb_save_mission_state { - /* 0x124 */ - uint32_t quest_world_location; - /* 0x128 */ - uint32_t skill_up_zone_location; + /* 0x124 */ + uint32_t quest_world_location; + /* 0x128 */ + uint32_t skill_up_zone_location; } __attribute__((__packed__)); struct asset_fex_usb_save { - struct asset_fex_usb_save_header header; - struct asset_fex_usb_save_player player; - struct asset_fex_usb_save_player_mods mods; - struct asset_fex_usb_save_mod_unlocks mod_unlocks; - struct asset_fex_usb_save_mission_state mission_state; + struct asset_fex_usb_save_header header; + struct asset_fex_usb_save_player player; + struct asset_fex_usb_save_player_mods mods; + struct asset_fex_usb_save_mod_unlocks mod_unlocks; + struct asset_fex_usb_save_mission_state mission_state; - /* Not verified, yet. just notes from old tools */ + /* Not verified, yet. just notes from old tools */ - /* 0x17AD (0x0A): Quest world inventory */ - /* 0x17B7: ??? */ - /* 0x17B8 (0x1C): Quest world warp unlocks */ + /* 0x17AD (0x0A): Quest world inventory */ + /* 0x17B7: ??? */ + /* 0x17B8 (0x1C): Quest world warp unlocks */ - /* 0x17AC (0x11): QW inventory */ + /* 0x17AC (0x11): QW inventory */ - /* 0x17D4 or 0x17D5 ? (0x14): favorites channel */ - /* 0x2E48 - 0x1A5EF: step chart blacklist */ - /* 0x2E48 - 0x1A5EF: step chart unlocks = blacklist */ + /* 0x17D4 or 0x17D5 ? (0x14): favorites channel */ + /* 0x2E48 - 0x1A5EF: step chart blacklist */ + /* 0x2E48 - 0x1A5EF: step chart unlocks = blacklist */ - /* pumbi stepcharts */ - /* 0x6047: pumbi stepchart 1009 Level S15 */ - /* 0x6083 */ - /* 0x60AB */ - /* 0x647F */ - /* 0x64BB */ - /* 0x64CF */ - /* 0x650B */ - /* 0x6533 */ - /* 0x655B */ - /* 0x65AB */ - /* 0x660F */ + /* pumbi stepcharts */ + /* 0x6047: pumbi stepchart 1009 Level S15 */ + /* 0x6083 */ + /* 0x60AB */ + /* 0x647F */ + /* 0x64BB */ + /* 0x64CF */ + /* 0x650B */ + /* 0x6533 */ + /* 0x655B */ + /* 0x65AB */ + /* 0x660F */ } __attribute__((__packed__)); -struct asset_fex_usb_save* asset_fex_usb_save_new(void); +struct asset_fex_usb_save *asset_fex_usb_save_new(void); // update checksum and prepare profile to get encrypted -void asset_fex_usb_save_finalize(struct asset_fex_usb_save* save); +void asset_fex_usb_save_finalize(struct asset_fex_usb_save *save); -char* asset_fex_usb_save_to_string(const struct asset_fex_usb_save* save); +char *asset_fex_usb_save_to_string(const struct asset_fex_usb_save *save); -void asset_fex_usb_save_decrypt(uint8_t* buf, size_t len); +void asset_fex_usb_save_decrypt(uint8_t *buf, size_t len); -void asset_fex_usb_save_encrypt(uint8_t* buf, size_t len); +void asset_fex_usb_save_encrypt(uint8_t *buf, size_t len); #endif diff --git a/src/main/asset/fex/lib/util.c b/src/main/asset/fex/lib/util.c index c61ac46..d712746 100644 --- a/src/main/asset/fex/lib/util.c +++ b/src/main/asset/fex/lib/util.c @@ -7,94 +7,94 @@ #include "util.h" -struct asset_fex_usb_rank* asset_fex_usb_rank_load_from_file(const char* path, - bool encrypted) +struct asset_fex_usb_rank * +asset_fex_usb_rank_load_from_file(const char *path, bool encrypted) { - struct asset_fex_usb_rank* rank; - size_t size; + struct asset_fex_usb_rank *rank; + size_t size; - if (!util_file_load(path, (void**) &rank, &size, false)) { - log_error("Loading fex rank file %s failed", path); - return NULL; - } + if (!util_file_load(path, (void **) &rank, &size, false)) { + log_error("Loading fex rank file %s failed", path); + return NULL; + } - // if (size != sizeof(struct fex_profile_rank)) { - // log_error("Invalid size of fex rank file %s: %d != %d", path, size, - // sizeof(struct fex_profile_rank)); - // free(rank); - // return NULL; - // } + // if (size != sizeof(struct fex_profile_rank)) { + // log_error("Invalid size of fex rank file %s: %d != %d", path, size, + // sizeof(struct fex_profile_rank)); + // free(rank); + // return NULL; + // } - if (encrypted) { - asset_fex_usb_rank_decrypt((uint8_t*) rank, size); - } + if (encrypted) { + asset_fex_usb_rank_decrypt((uint8_t *) rank, size); + } - return rank; + return rank; } -bool asset_fex_usb_rank_save_to_file(const char* path, - const struct asset_fex_usb_rank* rank, bool encrypt) +bool asset_fex_usb_rank_save_to_file( + const char *path, const struct asset_fex_usb_rank *rank, bool encrypt) { - struct asset_fex_usb_rank rank_enc; + struct asset_fex_usb_rank rank_enc; - memcpy(&rank_enc, rank, sizeof(struct asset_fex_usb_rank)); + memcpy(&rank_enc, rank, sizeof(struct asset_fex_usb_rank)); - if (encrypt) { - asset_fex_usb_rank_encrypt((uint8_t*) &rank_enc, - sizeof(struct asset_fex_usb_rank)); - } + if (encrypt) { + asset_fex_usb_rank_encrypt( + (uint8_t *) &rank_enc, sizeof(struct asset_fex_usb_rank)); + } - if (!util_file_save(path, (void**) &rank_enc, - sizeof(struct asset_fex_usb_rank))) { - log_error("Storing fex rank data to %s failed", path); - return false; - } + if (!util_file_save( + path, (void **) &rank_enc, sizeof(struct asset_fex_usb_rank))) { + log_error("Storing fex rank data to %s failed", path); + return false; + } - return true; + return true; } -struct asset_fex_usb_save* asset_fex_usb_save_load_from_file(const char* path, - bool encrypted) +struct asset_fex_usb_save * +asset_fex_usb_save_load_from_file(const char *path, bool encrypted) { - struct asset_fex_usb_save* save; - size_t size; + struct asset_fex_usb_save *save; + size_t size; - if (!util_file_load(path, (void**) &save, &size, false)) { - log_error("Loading fex save file %s failed", path); - return NULL; - } + if (!util_file_load(path, (void **) &save, &size, false)) { + log_error("Loading fex save file %s failed", path); + return NULL; + } - // if (size != sizeof(struct fex_profile_save)) { - // log_error("Invalid size of fex save file %s: %d != %d", path, size, - // sizeof(struct fex_profile_save)); - // free(save); - // return NULL; - // } + // if (size != sizeof(struct fex_profile_save)) { + // log_error("Invalid size of fex save file %s: %d != %d", path, size, + // sizeof(struct fex_profile_save)); + // free(save); + // return NULL; + // } - if (encrypted) { - asset_fex_usb_save_decrypt((uint8_t*) save, size); - } + if (encrypted) { + asset_fex_usb_save_decrypt((uint8_t *) save, size); + } - return save; + return save; } -bool asset_fex_usb_save_save_to_file(const char* path, - const struct asset_fex_usb_save* save, bool encrypt) +bool asset_fex_usb_save_save_to_file( + const char *path, const struct asset_fex_usb_save *save, bool encrypt) { - struct asset_fex_usb_save save_enc; + struct asset_fex_usb_save save_enc; - memcpy(&save_enc, save, sizeof(struct asset_fex_usb_save)); + memcpy(&save_enc, save, sizeof(struct asset_fex_usb_save)); - if (encrypt) { - asset_fex_usb_save_encrypt((uint8_t*) &save_enc, - sizeof(struct asset_fex_usb_save)); - } + if (encrypt) { + asset_fex_usb_save_encrypt( + (uint8_t *) &save_enc, sizeof(struct asset_fex_usb_save)); + } - if (!util_file_save(path, (const void*) &save_enc, - sizeof(struct asset_fex_usb_save))) { - log_error("Storing fex save data to %s failed", path); - return false; - } + if (!util_file_save( + path, (const void *) &save_enc, sizeof(struct asset_fex_usb_save))) { + log_error("Storing fex save data to %s failed", path); + return false; + } - return true; + return true; } \ No newline at end of file diff --git a/src/main/asset/fex/lib/util.h b/src/main/asset/fex/lib/util.h index be9cbb2..0b7ceaa 100644 --- a/src/main/asset/fex/lib/util.h +++ b/src/main/asset/fex/lib/util.h @@ -7,15 +7,19 @@ #include "usb-save.h" // load from file and decrypt, returns decrypted struct -struct asset_fex_usb_rank* asset_fex_usb_rank_load_from_file(const char* path, bool encrypted); +struct asset_fex_usb_rank * +asset_fex_usb_rank_load_from_file(const char *path, bool encrypted); // takes decrypted rank data, encrypts it and writes it to file -bool asset_fex_usb_rank_save_to_file(const char* path, const struct asset_fex_usb_rank* rank, bool encrypt); +bool asset_fex_usb_rank_save_to_file( + const char *path, const struct asset_fex_usb_rank *rank, bool encrypt); // load from file and decrypt, returns decrypted struct -struct asset_fex_usb_save* asset_fex_usb_save_load_from_file(const char* path, bool encrypted); +struct asset_fex_usb_save * +asset_fex_usb_save_load_from_file(const char *path, bool encrypted); // takes decrypted save data, encrypts it and writes it to file -bool asset_fex_usb_save_save_to_file(const char* path, const struct asset_fex_usb_save* save, bool encrypt); +bool asset_fex_usb_save_save_to_file( + const char *path, const struct asset_fex_usb_save *save, bool encrypt); #endif \ No newline at end of file diff --git a/src/main/asset/fex/tool/usb-profile.c b/src/main/asset/fex/tool/usb-profile.c index 7ffa44d..3cec545 100644 --- a/src/main/asset/fex/tool/usb-profile.c +++ b/src/main/asset/fex/tool/usb-profile.c @@ -9,146 +9,150 @@ #include "util/str.h" -int main(int argc, char** argv) +int main(int argc, char **argv) { - int ret; - char* rank_path; - char* save_path; + int ret; + char *rank_path; + char *save_path; - if (argc < 3) { - printf("Usage: %s [cmd: new, dec, enc, dump] " - "[path containing fiestaex_rank.bin fiestaex_save.bin]\n", argv[0]); - return -1; + if (argc < 3) { + printf( + "Usage: %s [cmd: new, dec, enc, dump] " + "[path containing fiestaex_rank.bin fiestaex_save.bin]\n", + argv[0]); + return -1; + } + + ret = 0; + + rank_path = util_str_merge(argv[2], "fiestaex_rank.bin"); + save_path = util_str_merge(argv[2], "fiestaex_save.bin"); + + if (!strcmp(argv[1], "new")) { + struct asset_fex_usb_rank *rank = asset_fex_usb_rank_new(); + struct asset_fex_usb_save *save = asset_fex_usb_save_new(); + + asset_fex_usb_rank_finalize(rank); + asset_fex_usb_save_finalize(save); + + if (!asset_fex_usb_rank_save_to_file(rank_path, rank, true)) { + fprintf(stderr, "Creating rank file %s failed\n", rank_path); + ret = -2; } - ret = 0; + if (!asset_fex_usb_save_save_to_file(save_path, save, true)) { + fprintf(stderr, "Creating save file %s failed\n", save_path); + ret = -3; + } - rank_path = util_str_merge(argv[2], "fiestaex_rank.bin"); - save_path = util_str_merge(argv[2], "fiestaex_save.bin"); + free(rank); + free(save); + } else { + struct asset_fex_usb_rank *rank; + struct asset_fex_usb_save *save; + bool encrypted; - if (!strcmp(argv[1], "new")) { - struct asset_fex_usb_rank* rank = asset_fex_usb_rank_new(); - struct asset_fex_usb_save* save = asset_fex_usb_save_new(); + if (!strcmp(argv[1], "enc")) { + char *tmp; - asset_fex_usb_rank_finalize(rank); - asset_fex_usb_save_finalize(save); + encrypted = false; - if (!asset_fex_usb_rank_save_to_file(rank_path, rank, true)) { - fprintf(stderr, "Creating rank file %s failed\n", rank_path); - ret = -2; - } + tmp = util_str_merge(rank_path, ".dec"); + free(rank_path); + rank_path = tmp; - if (!asset_fex_usb_save_save_to_file(save_path, save, true)) { - fprintf(stderr, "Creating save file %s failed\n", save_path); - ret = -3; - } - - free(rank); - free(save); + tmp = util_str_merge(save_path, ".dec"); + free(save_path); + save_path = tmp; } else { - struct asset_fex_usb_rank* rank; - struct asset_fex_usb_save* save; - bool encrypted; - - if (!strcmp(argv[1], "enc")) { - char* tmp; - - encrypted = false; - - tmp = util_str_merge(rank_path, ".dec"); - free(rank_path); - rank_path = tmp; - - tmp = util_str_merge(save_path, ".dec"); - free(save_path); - save_path = tmp; - } else { - encrypted = true; - } - - rank = asset_fex_usb_rank_load_from_file(rank_path, encrypted); - save = asset_fex_usb_save_load_from_file(save_path, encrypted); - - if (!rank) { - fprintf(stderr, "Loading %s failed", rank_path); - ret = -4; - goto cleanup; - } - - if (!save) { - fprintf(stderr, "Loading %s failed", save_path); - ret = -5; - free(rank); - goto cleanup; - } - - if (!strcmp(argv[1], "dec")) { - char* rank_path_dec; - char* save_path_dec; - - rank_path_dec = util_str_merge(rank_path, ".dec"); - save_path_dec = util_str_merge(save_path, ".dec"); - - if (!asset_fex_usb_rank_save_to_file(rank_path_dec, rank, false)) { - fprintf(stderr, "Saving decrypted rank file to %s failed\n", - rank_path_dec); - ret = -6; - } - - if (!asset_fex_usb_save_save_to_file(save_path_dec, save, false)) { - fprintf(stderr, "Saving decrypted save file to %s failed\n", - save_path_dec); - ret = -7; - } - - free(rank_path_dec); - free(save_path_dec); - } else if (!strcmp(argv[1], "enc")) { - char* rank_path_enc; - char* save_path_enc; - - rank_path_enc = util_str_merge(rank_path, ".enc"); - save_path_enc = util_str_merge(save_path, ".enc"); - - if (!asset_fex_usb_rank_save_to_file(rank_path_enc, rank, true)) { - fprintf(stderr, "Saving encrypted rank file to %s failed\n", - rank_path_enc); - ret = -6; - } - - if (!asset_fex_usb_save_save_to_file(save_path_enc, save, true)) { - fprintf(stderr, "Saving encrypted save file to %s failed\n", - save_path_enc); - ret = -7; - } - - free(rank_path_enc); - free(save_path_enc); - } else if (!strcmp(argv[1], "dump")) { - char* rank_str; - char* save_str; - - rank_str = asset_fex_usb_rank_to_string(rank); - save_str = asset_fex_usb_save_to_string(save); - - printf("----------------- rank -----------------\n" - "%s----------------- save -----------------\n%s", - rank_str, save_str); - - free(rank_str); - free(save_str); - } else { - fprintf(stderr, "Unknown command %s\n", argv[1]); - ret = -4; - } - - free(rank); - free(save); + encrypted = true; } + rank = asset_fex_usb_rank_load_from_file(rank_path, encrypted); + save = asset_fex_usb_save_load_from_file(save_path, encrypted); + + if (!rank) { + fprintf(stderr, "Loading %s failed", rank_path); + ret = -4; + goto cleanup; + } + + if (!save) { + fprintf(stderr, "Loading %s failed", save_path); + ret = -5; + free(rank); + goto cleanup; + } + + if (!strcmp(argv[1], "dec")) { + char *rank_path_dec; + char *save_path_dec; + + rank_path_dec = util_str_merge(rank_path, ".dec"); + save_path_dec = util_str_merge(save_path, ".dec"); + + if (!asset_fex_usb_rank_save_to_file(rank_path_dec, rank, false)) { + fprintf( + stderr, "Saving decrypted rank file to %s failed\n", rank_path_dec); + ret = -6; + } + + if (!asset_fex_usb_save_save_to_file(save_path_dec, save, false)) { + fprintf( + stderr, "Saving decrypted save file to %s failed\n", save_path_dec); + ret = -7; + } + + free(rank_path_dec); + free(save_path_dec); + } else if (!strcmp(argv[1], "enc")) { + char *rank_path_enc; + char *save_path_enc; + + rank_path_enc = util_str_merge(rank_path, ".enc"); + save_path_enc = util_str_merge(save_path, ".enc"); + + if (!asset_fex_usb_rank_save_to_file(rank_path_enc, rank, true)) { + fprintf( + stderr, "Saving encrypted rank file to %s failed\n", rank_path_enc); + ret = -6; + } + + if (!asset_fex_usb_save_save_to_file(save_path_enc, save, true)) { + fprintf( + stderr, "Saving encrypted save file to %s failed\n", save_path_enc); + ret = -7; + } + + free(rank_path_enc); + free(save_path_enc); + } else if (!strcmp(argv[1], "dump")) { + char *rank_str; + char *save_str; + + rank_str = asset_fex_usb_rank_to_string(rank); + save_str = asset_fex_usb_save_to_string(save); + + printf( + "----------------- rank -----------------\n" + "%s----------------- save -----------------\n%s", + rank_str, + save_str); + + free(rank_str); + free(save_str); + } else { + fprintf(stderr, "Unknown command %s\n", argv[1]); + ret = -4; + } + + free(rank); + free(save); + } + cleanup: - free(rank_path); - free(save_path); + free(rank_path); + free(save_path); - return ret; + return ret; } \ No newline at end of file diff --git a/src/main/asset/game-version.h b/src/main/asset/game-version.h index c6ff8df..ebb55d6 100644 --- a/src/main/asset/game-version.h +++ b/src/main/asset/game-version.h @@ -3,36 +3,36 @@ /* Note: Version IDs must be sync with server code */ enum asset_game_version { - ASSET_GAME_VERSION_INVALID = 0, - ASSET_GAME_VERSION_FIRST = 1, - ASSET_GAME_VERSION_SECOND = 2, - ASSET_GAME_VERSION_OBG = 3, - ASSET_GAME_VERSION_OBG_SE = 4, - ASSET_GAME_VERSION_THE_COLLECTION = 5, - ASSET_GAME_VERSION_PERFECT_COLLECTION = 6, - ASSET_GAME_VERSION_EXTRA = 7, - ASSET_GAME_VERSION_PREMIERE_1 = 8, - ASSET_GAME_VERSION_PREX_1 = 9, - ASSET_GAME_VERSION_REBIRTH = 10, - ASSET_GAME_VERSION_PREMIERE_2 = 11, - ASSET_GAME_VERSION_PREX_2 = 12, - ASSET_GAME_VERSION_PREMIERE_3 = 13, - ASSET_GAME_VERSION_PREX_3 = 14, - ASSET_GAME_VERSION_EXCEED = 15, - ASSET_GAME_VERSION_EXCEED_2 = 16, - ASSET_GAME_VERSION_ZERO = 17, - ASSET_GAME_VERSION_NX = 18, - ASSET_GAME_VERSION_PRO = 19, - ASSET_GAME_VERSION_NX2 = 20, - ASSET_GAME_VERSION_NXA = 21, - ASSET_GAME_VERSION_FIESTA = 22, - ASSET_GAME_VERSION_PRO2 = 23, - ASSET_GAME_VERSION_FIESTA_EX = 24, - ASSET_GAME_VERSION_FIESTA_2 = 25, - ASSET_GAME_VERSION_INFINITY = 26, - ASSET_GAME_VERSION_PRIME = 27, - ASSET_GAME_VERSION_PRIME_2 = 28, - ASSET_GAME_VERSION_XX = 29 + ASSET_GAME_VERSION_INVALID = 0, + ASSET_GAME_VERSION_FIRST = 1, + ASSET_GAME_VERSION_SECOND = 2, + ASSET_GAME_VERSION_OBG = 3, + ASSET_GAME_VERSION_OBG_SE = 4, + ASSET_GAME_VERSION_THE_COLLECTION = 5, + ASSET_GAME_VERSION_PERFECT_COLLECTION = 6, + ASSET_GAME_VERSION_EXTRA = 7, + ASSET_GAME_VERSION_PREMIERE_1 = 8, + ASSET_GAME_VERSION_PREX_1 = 9, + ASSET_GAME_VERSION_REBIRTH = 10, + ASSET_GAME_VERSION_PREMIERE_2 = 11, + ASSET_GAME_VERSION_PREX_2 = 12, + ASSET_GAME_VERSION_PREMIERE_3 = 13, + ASSET_GAME_VERSION_PREX_3 = 14, + ASSET_GAME_VERSION_EXCEED = 15, + ASSET_GAME_VERSION_EXCEED_2 = 16, + ASSET_GAME_VERSION_ZERO = 17, + ASSET_GAME_VERSION_NX = 18, + ASSET_GAME_VERSION_PRO = 19, + ASSET_GAME_VERSION_NX2 = 20, + ASSET_GAME_VERSION_NXA = 21, + ASSET_GAME_VERSION_FIESTA = 22, + ASSET_GAME_VERSION_PRO2 = 23, + ASSET_GAME_VERSION_FIESTA_EX = 24, + ASSET_GAME_VERSION_FIESTA_2 = 25, + ASSET_GAME_VERSION_INFINITY = 26, + ASSET_GAME_VERSION_PRIME = 27, + ASSET_GAME_VERSION_PRIME_2 = 28, + ASSET_GAME_VERSION_XX = 29 }; #endif diff --git a/src/main/asset/nx/lib/settings.c b/src/main/asset/nx/lib/settings.c index f4ddbba..e861657 100644 --- a/src/main/asset/nx/lib/settings.c +++ b/src/main/asset/nx/lib/settings.c @@ -5,64 +5,69 @@ #include "util/adler32.h" #include "util/mem.h" -struct asset_nx_settings* asset_nx_settings_new(void) +struct asset_nx_settings *asset_nx_settings_new(void) { - struct asset_nx_settings* settings; + struct asset_nx_settings *settings; - settings = util_xmalloc(sizeof(struct asset_nx_settings)); + settings = util_xmalloc(sizeof(struct asset_nx_settings)); - memset(settings->ff_pad, 0xFF, sizeof(settings->ff_pad)); - memcpy(settings->ident, "NX10", 4); - /* Updated using finalize */ - settings->adler32 = 0; - settings->total_uptime = 0; - settings->language = ASSET_NX_SETTINGS_LANG_ENG; - memset(settings->song_play_count, 0, sizeof(uint32_t) * ASSET_NX_SETTINGS_MAX_SONGS); - settings->game_option_default_station = ASSET_NX_SETTINGS_STATION_TRAIN; - settings->game_mode = ASSET_NX_SETTINGS_GAME_MODE_NORMAL; - settings->game_level = ASSET_NX_SETTINGS_LEVEL_NORMAL; - settings->game_stage_break = ASSET_NX_SETTINGS_STAGE_BREAK_2ND; - settings->game_demo_sound = 1; - settings->game_show_help = 1; - settings->game_mercy_ticket = 0; - settings->game_score_per_ticket = 0; - settings->coin_limit = 0; - settings->coin1_setting = 1; - settings->coin2_setting = 1; - memset(settings->unknown_unlock_flags, 0, ASSET_NX_SETTINGS_NUM_UNLOCK_FLAGS); - settings->unkn2 = 0x2A; - settings->unkn3 = 0; - settings->bookkeeping_coin1_total = 0; - settings->bookkeeping_coin2_total = 0; - settings->bookkeeping_service_total = 0; - settings->bookkeeping_play_total = 0; - settings->bookkeeping_faep21_play_count = 0; - settings->bookkeeping_ticket_1 = 0; - settings->bookkeeping_ticket_2 = 0; - settings->region = 0xFF; - memset(settings->censor_table, 0, ASSET_NX_SETTINGS_MAX_SONGS); + memset(settings->ff_pad, 0xFF, sizeof(settings->ff_pad)); + memcpy(settings->ident, "NX10", 4); + /* Updated using finalize */ + settings->adler32 = 0; + settings->total_uptime = 0; + settings->language = ASSET_NX_SETTINGS_LANG_ENG; + memset( + settings->song_play_count, + 0, + sizeof(uint32_t) * ASSET_NX_SETTINGS_MAX_SONGS); + settings->game_option_default_station = ASSET_NX_SETTINGS_STATION_TRAIN; + settings->game_mode = ASSET_NX_SETTINGS_GAME_MODE_NORMAL; + settings->game_level = ASSET_NX_SETTINGS_LEVEL_NORMAL; + settings->game_stage_break = ASSET_NX_SETTINGS_STAGE_BREAK_2ND; + settings->game_demo_sound = 1; + settings->game_show_help = 1; + settings->game_mercy_ticket = 0; + settings->game_score_per_ticket = 0; + settings->coin_limit = 0; + settings->coin1_setting = 1; + settings->coin2_setting = 1; + memset(settings->unknown_unlock_flags, 0, ASSET_NX_SETTINGS_NUM_UNLOCK_FLAGS); + settings->unkn2 = 0x2A; + settings->unkn3 = 0; + settings->bookkeeping_coin1_total = 0; + settings->bookkeeping_coin2_total = 0; + settings->bookkeeping_service_total = 0; + settings->bookkeeping_play_total = 0; + settings->bookkeeping_faep21_play_count = 0; + settings->bookkeeping_ticket_1 = 0; + settings->bookkeeping_ticket_2 = 0; + settings->region = 0xFF; + memset(settings->censor_table, 0, ASSET_NX_SETTINGS_MAX_SONGS); - return settings; + return settings; } -void asset_nx_settings_finalize(struct asset_nx_settings* settings) +void asset_nx_settings_finalize(struct asset_nx_settings *settings) { - /* Seems odd, but they just checksum the game settings part...*/ - settings->adler32 = util_adler32_calc(1, (const uint8_t*) &settings->game_mode, 8); + /* Seems odd, but they just checksum the game settings part...*/ + settings->adler32 = + util_adler32_calc(1, (const uint8_t *) &settings->game_mode, 8); } -void asset_nx_settings_unlock_all(struct asset_nx_settings* settings) +void asset_nx_settings_unlock_all(struct asset_nx_settings *settings) { - /* FAEP 2-1 must be played at least 100 times to unlock FAEP 2-2 */ - settings->bookkeeping_faep21_play_count = 100; + /* FAEP 2-1 must be played at least 100 times to unlock FAEP 2-2 */ + settings->bookkeeping_faep21_play_count = 100; - /* To unlock all world tour missions and special zone songs, set this to 20k. - The first 10k unlock only the first half of the missions while another 10k unlocks the second half (wtf) */ - settings->bookkeeping_play_total = 20000; + /* To unlock all world tour missions and special zone songs, set this to 20k. + The first 10k unlock only the first half of the missions while another 10k + unlocks the second half (wtf) */ + settings->bookkeeping_play_total = 20000; } -char* asset_nx_settings_to_string(const struct asset_nx_settings* settings) +char *asset_nx_settings_to_string(const struct asset_nx_settings *settings) { - // TODO - return ""; + // TODO + return ""; } \ No newline at end of file diff --git a/src/main/asset/nx/lib/settings.h b/src/main/asset/nx/lib/settings.h index 12c2ffb..a3e736a 100644 --- a/src/main/asset/nx/lib/settings.h +++ b/src/main/asset/nx/lib/settings.h @@ -8,94 +8,96 @@ #define ASSET_NX_SETTINGS_NUM_UNLOCK_FLAGS 59 enum asset_nx_settings_language { - ASSET_NX_SETTINGS_LANG_KOR = 0, - ASSET_NX_SETTINGS_LANG_ENG = 1, - ASSET_NX_SETTINGS_LANG_SP = 2, - ASSET_NX_SETTINGS_LANG_CH = 3, + ASSET_NX_SETTINGS_LANG_KOR = 0, + ASSET_NX_SETTINGS_LANG_ENG = 1, + ASSET_NX_SETTINGS_LANG_SP = 2, + ASSET_NX_SETTINGS_LANG_CH = 3, }; enum asset_nx_settings_station { - ASSET_NX_SETTINGS_STATION_TRAIN = 0, - ASSET_NX_SETTINGS_STATION_ARCADE = 1, - ASSET_NX_SETTINGS_STATION_WORLD = 2, - ASSET_NX_SETTINGS_STATION_SPECIAL = 3, + ASSET_NX_SETTINGS_STATION_TRAIN = 0, + ASSET_NX_SETTINGS_STATION_ARCADE = 1, + ASSET_NX_SETTINGS_STATION_WORLD = 2, + ASSET_NX_SETTINGS_STATION_SPECIAL = 3, }; enum asset_nx_settings_game_mode { - ASSET_NX_SETTINGS_GAME_MODE_NORMAL = 0, - ASSET_NX_SETTINGS_GAME_MODE_EVENT = 1, + ASSET_NX_SETTINGS_GAME_MODE_NORMAL = 0, + ASSET_NX_SETTINGS_GAME_MODE_EVENT = 1, }; enum asset_nx_settings_level { - ASSET_NX_SETTINGS_LEVEL_EASY = 0, - ASSET_NX_SETTINGS_LEVEL_NORMAL = 1, - ASSET_NX_SETTINGS_LEVEL_HARD = 2, + ASSET_NX_SETTINGS_LEVEL_EASY = 0, + ASSET_NX_SETTINGS_LEVEL_NORMAL = 1, + ASSET_NX_SETTINGS_LEVEL_HARD = 2, }; enum asset_nx_settings_stage_break { - ASSET_NX_SETTINGS_STAGE_BREAK_OFF = 0, - ASSET_NX_SETTINGS_STAGE_BREAK_1ST = 1, - ASSET_NX_SETTINGS_STAGE_BREAK_2ND = 2, - ASSET_NX_SETTINGS_STAGE_BREAK_3RD = 3, - ASSET_NX_SETTINGS_STAGE_BREAK_4TH = 4, + ASSET_NX_SETTINGS_STAGE_BREAK_OFF = 0, + ASSET_NX_SETTINGS_STAGE_BREAK_1ST = 1, + ASSET_NX_SETTINGS_STAGE_BREAK_2ND = 2, + ASSET_NX_SETTINGS_STAGE_BREAK_3RD = 3, + ASSET_NX_SETTINGS_STAGE_BREAK_4TH = 4, }; struct asset_nx_settings { - /* Padding to fill up to 4k EEPROM legacy size */ - uint8_t ff_pad[0xB9D]; - /* NX10 */ - char ident[4]; - uint32_t adler32; - uint32_t total_uptime; - uint8_t language; - uint32_t song_play_count[ASSET_NX_SETTINGS_MAX_SONGS]; - uint32_t game_option_default_station; - uint8_t game_mode; - uint8_t game_level; - uint8_t game_stage_break; - /* 0 off, 1 on */ - uint8_t game_demo_sound; - /* 0 off, 1 on */ - uint8_t game_show_help; - /* 0 off, 1 on */ - uint8_t game_mercy_ticket; - /* 0 off, 1 - 6 for score */ - uint8_t game_score_per_ticket; - /* 0 none */ - uint8_t coin_limit; // 0 none - /* 0 freeplay */ - uint8_t coin1_setting; - /* 0 freeplay */ - uint8_t coin2_setting; - /* Unlock flags for world tour missions? setting them to 1 doesn't unlock anything. - 64 missions total, 55 unlock flags, 0 = locked, 1 = unlocked */ - uint8_t unknown_unlock_flags[ASSET_NX_SETTINGS_NUM_UNLOCK_FLAGS]; - /* Default value 0x2A */ - uint32_t unkn2; - uint32_t unkn3; - uint32_t bookkeeping_coin1_total; - uint32_t bookkeeping_coin2_total; - uint32_t bookkeeping_service_total; - uint32_t bookkeeping_play_total; - /* Separate counter for FAEP 2-1 play counts. Once this hits 100, FAEP 2-2 is unlocked in arcade station */ - uint32_t bookkeeping_faep21_play_count; - uint32_t bookkeeping_ticket_1; - uint32_t bookkeeping_ticket_2; - /* FF -> not used, censoring globally disabled. unused feature though */ - uint8_t region; - /* 0 = censoring of song off */ - uint8_t censor_table[ASSET_NX_SETTINGS_MAX_SONGS]; + /* Padding to fill up to 4k EEPROM legacy size */ + uint8_t ff_pad[0xB9D]; + /* NX10 */ + char ident[4]; + uint32_t adler32; + uint32_t total_uptime; + uint8_t language; + uint32_t song_play_count[ASSET_NX_SETTINGS_MAX_SONGS]; + uint32_t game_option_default_station; + uint8_t game_mode; + uint8_t game_level; + uint8_t game_stage_break; + /* 0 off, 1 on */ + uint8_t game_demo_sound; + /* 0 off, 1 on */ + uint8_t game_show_help; + /* 0 off, 1 on */ + uint8_t game_mercy_ticket; + /* 0 off, 1 - 6 for score */ + uint8_t game_score_per_ticket; + /* 0 none */ + uint8_t coin_limit; // 0 none + /* 0 freeplay */ + uint8_t coin1_setting; + /* 0 freeplay */ + uint8_t coin2_setting; + /* Unlock flags for world tour missions? setting them to 1 doesn't unlock + anything. 64 missions total, 55 unlock flags, 0 = locked, 1 = unlocked */ + uint8_t unknown_unlock_flags[ASSET_NX_SETTINGS_NUM_UNLOCK_FLAGS]; + /* Default value 0x2A */ + uint32_t unkn2; + uint32_t unkn3; + uint32_t bookkeeping_coin1_total; + uint32_t bookkeeping_coin2_total; + uint32_t bookkeeping_service_total; + uint32_t bookkeeping_play_total; + /* Separate counter for FAEP 2-1 play counts. Once this hits 100, FAEP 2-2 is + * unlocked in arcade station */ + uint32_t bookkeeping_faep21_play_count; + uint32_t bookkeeping_ticket_1; + uint32_t bookkeeping_ticket_2; + /* FF -> not used, censoring globally disabled. unused feature though */ + uint8_t region; + /* 0 = censoring of song off */ + uint8_t censor_table[ASSET_NX_SETTINGS_MAX_SONGS]; } __attribute__((__packed__)); -struct asset_nx_settings* asset_nx_settings_new(void); +struct asset_nx_settings *asset_nx_settings_new(void); // update checksum -void asset_nx_settings_finalize(struct asset_nx_settings* settings); +void asset_nx_settings_finalize(struct asset_nx_settings *settings); // unlocks FAEP 2-2 by setting the play count to 100 -// and sets all missions cleared to unlock special stage songs and other missions -void asset_nx_settings_unlock_all(struct asset_nx_settings* settings); +// and sets all missions cleared to unlock special stage songs and other +// missions +void asset_nx_settings_unlock_all(struct asset_nx_settings *settings); -char* asset_nx_settings_to_string(const struct asset_nx_settings* settings); +char *asset_nx_settings_to_string(const struct asset_nx_settings *settings); #endif diff --git a/src/main/asset/nx/lib/util.c b/src/main/asset/nx/lib/util.c index 28b8062..31376ca 100644 --- a/src/main/asset/nx/lib/util.c +++ b/src/main/asset/nx/lib/util.c @@ -5,31 +5,38 @@ #include "util/fs.h" #include "util/log.h" -struct asset_nx_settings* asset_nx_util_load_settings_from_file(const char* path) +struct asset_nx_settings * +asset_nx_util_load_settings_from_file(const char *path) { - struct asset_nx_settings* settings; - size_t size; + struct asset_nx_settings *settings; + size_t size; - if (!util_file_load(path, (void**) &settings, &size, false)) { - log_error("Loading nx setting file %s failed", path); - return NULL; - } + if (!util_file_load(path, (void **) &settings, &size, false)) { + log_error("Loading nx setting file %s failed", path); + return NULL; + } - if (size != sizeof(struct asset_nx_settings)) { - log_error("Invalid size of nx setting file %s: %d != %d", path, size, sizeof(struct asset_nx_settings)); - free(settings); - return NULL; - } + if (size != sizeof(struct asset_nx_settings)) { + log_error( + "Invalid size of nx setting file %s: %d != %d", + path, + size, + sizeof(struct asset_nx_settings)); + free(settings); + return NULL; + } - return settings; + return settings; } -bool asset_nx_util_save_settings_to_file(const char* path, const struct asset_nx_settings* settings) +bool asset_nx_util_save_settings_to_file( + const char *path, const struct asset_nx_settings *settings) { - if (!util_file_save(path, (void**) settings, sizeof(struct asset_nx_settings))) { - log_error("Storing nx settings data to %s failed", path); - return false; - } + if (!util_file_save( + path, (void **) settings, sizeof(struct asset_nx_settings))) { + log_error("Storing nx settings data to %s failed", path); + return false; + } - return true; + return true; } \ No newline at end of file diff --git a/src/main/asset/nx/lib/util.h b/src/main/asset/nx/lib/util.h index 37342b9..48c617b 100644 --- a/src/main/asset/nx/lib/util.h +++ b/src/main/asset/nx/lib/util.h @@ -5,8 +5,10 @@ #include "asset/nx/lib/settings.h" -struct asset_nx_settings* asset_nx_util_load_settings_from_file(const char* path); +struct asset_nx_settings * +asset_nx_util_load_settings_from_file(const char *path); -bool asset_nx_util_save_settings_to_file(const char* path, const struct asset_nx_settings* settings); +bool asset_nx_util_save_settings_to_file( + const char *path, const struct asset_nx_settings *settings); #endif diff --git a/src/main/asset/nx/tool/settings.c b/src/main/asset/nx/tool/settings.c index d32709e..668019f 100644 --- a/src/main/asset/nx/tool/settings.c +++ b/src/main/asset/nx/tool/settings.c @@ -8,81 +8,84 @@ #include "asset/nx/lib/settings.h" #include "asset/nx/lib/util.h" -static int main_settings(char* cmd, char* file); +static int main_settings(char *cmd, char *file); -int main(int argc, char** argv) +int main(int argc, char **argv) { - int ret; - char* cmd; - char* type; - char* file; + int ret; + char *cmd; + char *type; + char *file; - if (argc < 4) { - printf("Usage: %s [cmd: new, dump, unlock] [type: ini, mrank, rank] [file]\n", argv[0]); - return -1; - } + if (argc < 4) { + printf( + "Usage: %s [cmd: new, dump, unlock] [type: ini, mrank, rank] [file]\n", + argv[0]); + return -1; + } - cmd = argv[1]; - type = argv[2]; - file = argv[3]; + cmd = argv[1]; + type = argv[2]; + file = argv[3]; - if (!strcmp(type, "ini")) { - ret = main_settings(cmd, file); - } else { - fprintf(stderr, "Unknown file type %s\n", type); - ret = -1; - } + if (!strcmp(type, "ini")) { + ret = main_settings(cmd, file); + } else { + fprintf(stderr, "Unknown file type %s\n", type); + ret = -1; + } - return ret; + return ret; } -static int main_settings(char* cmd, char* file) +static int main_settings(char *cmd, char *file) { - int ret; + int ret; - ret = 0; + ret = 0; - if (!strcmp(cmd, "new")) { - struct asset_nx_settings* settings = asset_nx_settings_new(); + if (!strcmp(cmd, "new")) { + struct asset_nx_settings *settings = asset_nx_settings_new(); - asset_nx_settings_finalize(settings); + asset_nx_settings_finalize(settings); - if (!asset_nx_util_save_settings_to_file(file, settings)) { - fprintf(stderr, "Creating nx settings file %s failed\n", file); - ret = -1; - } - - free(settings); - } else { - struct asset_nx_settings* settings = asset_nx_util_load_settings_from_file(file); - - if (!settings) { - fprintf(stderr, "Loading %s failed", file); - ret = -1; - } - - if (!strcmp(cmd, "dump")) { - char* str = asset_nx_settings_to_string(settings); - - printf("----------------- settings -----------------\n%s\n", str); - - free(str); - } else if (!strcmp(cmd, "unlock")) { - asset_nx_settings_unlock_all(settings); - - asset_nx_settings_finalize(settings); - - if (!asset_nx_util_save_settings_to_file(file, settings)) { - fprintf(stderr, "Saving nx settings file %s failed\n", file); - ret = -1; - } - } else { - fprintf(stderr, "Unknown command %s\n", cmd); - ret = -1; - } - - free(settings); + if (!asset_nx_util_save_settings_to_file(file, settings)) { + fprintf(stderr, "Creating nx settings file %s failed\n", file); + ret = -1; } - return ret; + free(settings); + } else { + struct asset_nx_settings *settings = + asset_nx_util_load_settings_from_file(file); + + if (!settings) { + fprintf(stderr, "Loading %s failed", file); + ret = -1; + } + + if (!strcmp(cmd, "dump")) { + char *str = asset_nx_settings_to_string(settings); + + printf("----------------- settings -----------------\n%s\n", str); + + free(str); + } else if (!strcmp(cmd, "unlock")) { + asset_nx_settings_unlock_all(settings); + + asset_nx_settings_finalize(settings); + + if (!asset_nx_util_save_settings_to_file(file, settings)) { + fprintf(stderr, "Saving nx settings file %s failed\n", file); + ret = -1; + } + } else { + fprintf(stderr, "Unknown command %s\n", cmd); + ret = -1; + } + + free(settings); + } + + return ret; } \ No newline at end of file diff --git a/src/main/asset/nx2/lib/usb-rank.c b/src/main/asset/nx2/lib/usb-rank.c index d11c50c..75a43c3 100644 --- a/src/main/asset/nx2/lib/usb-rank.c +++ b/src/main/asset/nx2/lib/usb-rank.c @@ -6,88 +6,93 @@ #include "usb-rank.h" -struct asset_nx2_usb_rank* asset_nx2_usb_rank_new(void) +struct asset_nx2_usb_rank *asset_nx2_usb_rank_new(void) { - struct asset_nx2_usb_rank* rank; + struct asset_nx2_usb_rank *rank; - rank = (struct asset_nx2_usb_rank*) - util_xmalloc(sizeof(struct asset_nx2_usb_rank)); + rank = (struct asset_nx2_usb_rank *) util_xmalloc( + sizeof(struct asset_nx2_usb_rank)); - memset(rank, 0, sizeof(struct asset_nx2_usb_rank)); + memset(rank, 0, sizeof(struct asset_nx2_usb_rank)); - return rank; + return rank; } -void asset_nx2_usb_rank_finalize(struct asset_nx2_usb_rank* rank) +void asset_nx2_usb_rank_finalize(struct asset_nx2_usb_rank *rank) { - rank->adler32 = util_adler32_calc(1, ((const uint8_t*) rank) + 4, - sizeof(struct asset_nx2_usb_rank) - 4); + rank->adler32 = util_adler32_calc( + 1, ((const uint8_t *) rank) + 4, sizeof(struct asset_nx2_usb_rank) - 4); } -char* asset_nx2_usb_rank_to_string(const struct asset_nx2_usb_rank* rank) +char *asset_nx2_usb_rank_to_string(const struct asset_nx2_usb_rank *rank) { - char* buffer; - char* buffer2; - char* merged; + char *buffer; + char *buffer2; + char *merged; - buffer = (char*) util_xmalloc(128); - memset(buffer, 0, 128); + buffer = (char *) util_xmalloc(128); + memset(buffer, 0, 128); - util_str_format(buffer, 128, - "adler32: 0x%X\n" - "num_rankings: %d\n" - "ranking entries:\n", - rank->adler32, - rank->num_rankings); + util_str_format( + buffer, + 128, + "adler32: 0x%X\n" + "num_rankings: %d\n" + "ranking entries:\n", + rank->adler32, + rank->num_rankings); - for (uint32_t i = 0; i < ASSET_NX2_USB_RANK_MAX_RANK_ENTRIES; i++) { + for (uint32_t i = 0; i < ASSET_NX2_USB_RANK_MAX_RANK_ENTRIES; i++) { - for (uint32_t j = 0; j < ASSET_NX2_USB_RANK_MAX_STAGES; j++) { - buffer2 = (char*) util_xmalloc(512); - memset(buffer2, 0, 512); + for (uint32_t j = 0; j < ASSET_NX2_USB_RANK_MAX_STAGES; j++) { + buffer2 = (char *) util_xmalloc(512); + memset(buffer2, 0, 512); - util_str_format(buffer2, 512, - "%d/%d:\n" - "game_mode: %d\n" - "play_order: %d\n" - "play_score: %d\n" - "grade: %d\n" - "mileage: %d\n" - "play_time: %f\n" - "kcal: %f\n" - "v02: %f\n", - i, j, - rank->entries[i][j].game_mode, - rank->entries[i][j].play_order, - rank->entries[i][j].play_score, - rank->entries[i][j].grade, - rank->entries[i][j].mileage, - rank->entries[i][j].play_time, - rank->entries[i][j].kcal, - rank->entries[i][j].v02); + util_str_format( + buffer2, + 512, + "%d/%d:\n" + "game_mode: %d\n" + "play_order: %d\n" + "play_score: %d\n" + "grade: %d\n" + "mileage: %d\n" + "play_time: %f\n" + "kcal: %f\n" + "v02: %f\n", + i, + j, + rank->entries[i][j].game_mode, + rank->entries[i][j].play_order, + rank->entries[i][j].play_score, + rank->entries[i][j].grade, + rank->entries[i][j].mileage, + rank->entries[i][j].play_time, + rank->entries[i][j].kcal, + rank->entries[i][j].v02); - merged = util_str_merge(buffer, buffer2); + merged = util_str_merge(buffer, buffer2); - free(buffer); - free(buffer2); + free(buffer); + free(buffer2); - buffer = merged; - } + buffer = merged; } + } - return buffer; + return buffer; } -void asset_nx2_usb_rank_decrypt(uint8_t* buf, size_t len) +void asset_nx2_usb_rank_decrypt(uint8_t *buf, size_t len) { - for (size_t a = len - 1; a > 0; --a) { - buf[a] = (buf[a] ^ buf[a - 1]) + ((a * 1234567) >> 8); - } + for (size_t a = len - 1; a > 0; --a) { + buf[a] = (buf[a] ^ buf[a - 1]) + ((a * 1234567) >> 8); + } } -void asset_nx2_usb_rank_encrypt(uint8_t* buf, size_t len) +void asset_nx2_usb_rank_encrypt(uint8_t *buf, size_t len) { - for (size_t a = 1; a < len; ++a) { - buf[a] = (buf[a] - ((a * 1234567) >> 8)) ^ buf[a - 1]; - } + for (size_t a = 1; a < len; ++a) { + buf[a] = (buf[a] - ((a * 1234567) >> 8)) ^ buf[a - 1]; + } } \ No newline at end of file diff --git a/src/main/asset/nx2/lib/usb-rank.h b/src/main/asset/nx2/lib/usb-rank.h index a06da6c..461dff8 100644 --- a/src/main/asset/nx2/lib/usb-rank.h +++ b/src/main/asset/nx2/lib/usb-rank.h @@ -7,36 +7,37 @@ #define ASSET_NX2_USB_RANK_SIZE 12296 enum asset_nx2_usb_rank_sizes { - ASSET_NX2_USB_RANK_MAX_STAGES = 3, - ASSET_NX2_USB_RANK_MAX_RANK_ENTRIES = 128, + ASSET_NX2_USB_RANK_MAX_STAGES = 3, + ASSET_NX2_USB_RANK_MAX_RANK_ENTRIES = 128, }; struct asset_nx2_usb_rank_entry { - int32_t game_mode; - int32_t play_order; - int32_t play_score; - int32_t grade; - int32_t mileage; - float play_time; - float kcal; - float v02; + int32_t game_mode; + int32_t play_order; + int32_t play_score; + int32_t grade; + int32_t mileage; + float play_time; + float kcal; + float v02; } __attribute__((__packed__)); struct asset_nx2_usb_rank { - uint32_t adler32; - uint32_t num_rankings; - struct asset_nx2_usb_rank_entry entries[ASSET_NX2_USB_RANK_MAX_RANK_ENTRIES][ASSET_NX2_USB_RANK_MAX_STAGES]; + uint32_t adler32; + uint32_t num_rankings; + struct asset_nx2_usb_rank_entry entries[ASSET_NX2_USB_RANK_MAX_RANK_ENTRIES] + [ASSET_NX2_USB_RANK_MAX_STAGES]; } __attribute__((__packed__)); -struct asset_nx2_usb_rank* asset_nx2_usb_rank_new(void); +struct asset_nx2_usb_rank *asset_nx2_usb_rank_new(void); // update checksum and prepare profile to get encrypted -void asset_nx2_usb_rank_finalize(struct asset_nx2_usb_rank* rank); +void asset_nx2_usb_rank_finalize(struct asset_nx2_usb_rank *rank); -char* asset_nx2_usb_rank_to_string(const struct asset_nx2_usb_rank* rank); +char *asset_nx2_usb_rank_to_string(const struct asset_nx2_usb_rank *rank); -void asset_nx2_usb_rank_decrypt(uint8_t* buf, size_t len); +void asset_nx2_usb_rank_decrypt(uint8_t *buf, size_t len); -void asset_nx2_usb_rank_encrypt(uint8_t* buf, size_t len); +void asset_nx2_usb_rank_encrypt(uint8_t *buf, size_t len); #endif \ No newline at end of file diff --git a/src/main/asset/nx2/lib/usb-save.c b/src/main/asset/nx2/lib/usb-save.c index 0588f43..5a85f46 100644 --- a/src/main/asset/nx2/lib/usb-save.c +++ b/src/main/asset/nx2/lib/usb-save.c @@ -8,363 +8,392 @@ #include "usb-save.h" -static char* asset_nx2_usb_save_time_to_string( - const struct asset_nx2_usb_save_time* time) +static char * +asset_nx2_usb_save_time_to_string(const struct asset_nx2_usb_save_time *time) { - char* buffer; + char *buffer; - buffer = (char*) util_xmalloc(128); - memset(buffer, 0, 128); + buffer = (char *) util_xmalloc(128); + memset(buffer, 0, 128); - util_str_format(buffer, 128, - "year: %d\n" - "month: %d\n" - "day: %d\n" - "hour: %d\n" - "min: %d\n" - "ms: %d\n", - time->year, - time->month, - time->day, - time->hour, - time->min, - time->ms); + util_str_format( + buffer, + 128, + "year: %d\n" + "month: %d\n" + "day: %d\n" + "hour: %d\n" + "min: %d\n" + "ms: %d\n", + time->year, + time->month, + time->day, + time->hour, + time->min, + time->ms); - return buffer; + return buffer; } -static char* asset_nx2_usb_save_review_to_string( - const struct asset_nx2_usb_save_review* review) +static char *asset_nx2_usb_save_review_to_string( + const struct asset_nx2_usb_save_review *review) { - char* buffer; - char* land; - char* mission; + char *buffer; + char *land; + char *mission; - buffer = (char*) util_xmalloc(1024); - memset(buffer, 0, 1024); + buffer = (char *) util_xmalloc(1024); + memset(buffer, 0, 1024); - land = util_str_buffer((const uint8_t*) review->worldmax_current_land, - ASSET_NX2_USB_SAVE_WORLDMAX_LOC_MAX); - mission = util_str_buffer((const uint8_t*) review->worldmax_current_mission, - ASSET_NX2_USB_SAVE_WORLDMAX_LOC_MAX); + land = util_str_buffer( + (const uint8_t *) review->worldmax_current_land, + ASSET_NX2_USB_SAVE_WORLDMAX_LOC_MAX); + mission = util_str_buffer( + (const uint8_t *) review->worldmax_current_mission, + ASSET_NX2_USB_SAVE_WORLDMAX_LOC_MAX); - util_str_format(buffer, 1024, - ">>> review:\n" - "player_id: %s\n" - "mileage: %d\n" - "reward_count: %d\n" - "worldmax_count: %d\n" - "play_count: %d\n" - "worldmax_current_land: %s\n" - "worldmax_current_mission: %s\n" - "kcal: %d\n" - "v02: %d\n", - review->player_id, - review->mileage, - review->reward_count, - review->worldmax_count, - review->play_count, - land, - mission, - review->kcal, - review->v02); + util_str_format( + buffer, + 1024, + ">>> review:\n" + "player_id: %s\n" + "mileage: %d\n" + "reward_count: %d\n" + "worldmax_count: %d\n" + "play_count: %d\n" + "worldmax_current_land: %s\n" + "worldmax_current_mission: %s\n" + "kcal: %d\n" + "v02: %d\n", + review->player_id, + review->mileage, + review->reward_count, + review->worldmax_count, + review->play_count, + land, + mission, + review->kcal, + review->v02); - free(land); - free(mission); + free(land); + free(mission); - return buffer; + return buffer; } -static char* asset_nx2_usb_save_stats_to_string( - const struct asset_nx2_usb_save_stats* stats) +static char * +asset_nx2_usb_save_stats_to_string(const struct asset_nx2_usb_save_stats *stats) { - char* merged; - char* buffer; - char* timestamp; - char* tmp; - const size_t buf_size = 512; + char *merged; + char *buffer; + char *timestamp; + char *tmp; + const size_t buf_size = 512; - merged = (char*) util_xmalloc(buf_size); - memset(merged, 0, buf_size); + merged = (char *) util_xmalloc(buf_size); + memset(merged, 0, buf_size); - buffer = (char*) util_xmalloc(buf_size); - memset(buffer, 0, buf_size); + buffer = (char *) util_xmalloc(buf_size); + memset(buffer, 0, buf_size); - timestamp = asset_nx2_usb_save_time_to_string(&stats->timestamp); + timestamp = asset_nx2_usb_save_time_to_string(&stats->timestamp); - util_str_format(merged, buf_size, - ">>> stats:\n" - "adler32: 0x%X\n" - "usb_serial: %s\n" - "timestamp: %s" - "avatar_id: %d\n" - "rank: %d\n" - "country_id: %d\n" - "player_id: %s\n" - "mileage: %d\n" - "play_count: %d\n" - "kcal: %d\n" - "v02: %d\n" - "worldmax_map_position: 0x%X\n" - "reward_count: %d\n" - "worldmax_count: %d\n", - stats->adler32, - stats->usb_serial, - timestamp, - stats->avatar_id, - stats->rank, - stats->country_id, - stats->player_id, - stats->mileage, - stats->play_count, - stats->kcal, - stats->v02, - stats->worldmax_map_position, - stats->reward_count, - stats->worldmax_count); + util_str_format( + merged, + buf_size, + ">>> stats:\n" + "adler32: 0x%X\n" + "usb_serial: %s\n" + "timestamp: %s" + "avatar_id: %d\n" + "rank: %d\n" + "country_id: %d\n" + "player_id: %s\n" + "mileage: %d\n" + "play_count: %d\n" + "kcal: %d\n" + "v02: %d\n" + "worldmax_map_position: 0x%X\n" + "reward_count: %d\n" + "worldmax_count: %d\n", + stats->adler32, + stats->usb_serial, + timestamp, + stats->avatar_id, + stats->rank, + stats->country_id, + stats->player_id, + stats->mileage, + stats->play_count, + stats->kcal, + stats->v02, + stats->worldmax_map_position, + stats->reward_count, + stats->worldmax_count); - free(timestamp); + free(timestamp); - tmp = util_str_merge(merged, "song_unlocks:\n"); + tmp = util_str_merge(merged, "song_unlocks:\n"); + + free(merged); + merged = tmp; + + for (uint32_t i = 0; i < ASSET_NX2_USB_SAVE_SONG_MAX; i++) { + + util_str_format( + buffer, + buf_size, + "song slot: %d\n" + "mode: 0x%X\n" + "unused: 0x%X\n" + "song: %d\n" + "reveal: %d\n", + i, + stats->song_unlocks[i].mode, + stats->song_unlocks[i].unused, + stats->song_unlocks[i].song, + stats->song_unlocks[i].reveal); + + tmp = util_str_merge(merged, buffer); free(merged); merged = tmp; + } - for (uint32_t i = 0; i < ASSET_NX2_USB_SAVE_SONG_MAX; i++) { + for (uint32_t i = 0; i < ASSET_NX2_USB_SAVE_MISSION_MAX; i++) { - util_str_format(buffer, buf_size, - "song slot: %d\n" - "mode: 0x%X\n" - "unused: 0x%X\n" - "song: %d\n" - "reveal: %d\n", - i, - stats->song_unlocks[i].mode, - stats->song_unlocks[i].unused, - stats->song_unlocks[i].song, - stats->song_unlocks[i].reveal); + util_str_format( + buffer, + buf_size, + "mission slot: %d\n" + "clear_flags_directions: 0x%X\n" + "clear_flag_mission: %d\n" + "unused: 0x%X\n", + i, + stats->worldmax_mission_unlocks[i].clear_flags_directions, + stats->worldmax_mission_unlocks[i].clear_flag_mission, + stats->worldmax_mission_unlocks[i].unused); - tmp = util_str_merge(merged, buffer); + tmp = util_str_merge(merged, buffer); - free(merged); - merged = tmp; + free(merged); + merged = tmp; + } + + for (uint32_t i = 0; i < ASSET_NX2_USB_SAVE_MISSION_MAX; i++) { + + util_str_format( + buffer, + buf_size, + "worldmax_high_score %d: %d\n", + i, + stats->worldmax_high_score[i]); + + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; + } + + for (uint32_t i = 0; i < ASSET_NX2_USB_SAVE_MISSION_MAX; i++) { + + util_str_format( + buffer, + buf_size, + "worldmax_challenge %d: %d\n", + i, + stats->worldmax_challenge[i]); + + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; + } + + for (uint32_t i = 0; i < ASSET_NX2_USB_SAVE_BARRICADE_MAX; i++) { + + util_str_format( + buffer, + buf_size, + "worldmax_barricade %d:\n" + "flag_open: %d\n" + "unused: 0x%X\n", + i, + stats->worldmax_barricade[i].flag_open, + stats->worldmax_barricade[i].unused); + + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; + } + + for (uint32_t i = 0; i < ASSET_NX2_USB_SAVE_EVENT_MAX; i++) { + + util_str_format( + buffer, + buf_size, + "worldmax_event %d:\n" + "flag_cleared: %d\n" + "unused: 0x%X\n", + i, + stats->worldmax_event[i].flag_cleared, + stats->worldmax_event[i].unused); + + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; + } + + for (uint32_t i = 0; i < ASSET_NX2_USB_SAVE_WARP_MAX; i++) { + + util_str_format( + buffer, + buf_size, + "worldmax_warp %d:\n" + "direction_clear: 0x%X\n" + "clear: %d\n", + "unused: 0x%X\n", + i, + stats->worldmax_warp[i].direction_clear, + stats->worldmax_warp[i].clear, + stats->worldmax_warp[i].unused); + + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; + } + + for (uint32_t i = 0; i < ASSET_NX2_USB_SAVE_WORLDMAX_LOC_MAX; i++) { + + util_str_format( + buffer, + buf_size, + "worldmax_current_land %d: %d\n", + i, + stats->worldmax_current_land[i]); + + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; + } + + for (uint32_t i = 0; i < ASSET_NX2_USB_SAVE_WORLDMAX_LOC_MAX; i++) { + + util_str_format( + buffer, + buf_size, + "worldmax_current_mission %d: %d\n", + i, + stats->worldmax_current_mission[i]); + + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; + } + + for (uint32_t i = 0; i < ASSET_NX2_USB_SAVE_SONG_MAX; i++) { + + for (uint32_t j = 0; j < ASSET_NX2_USB_SAVE_NUM_MODES; j++) { + util_str_format( + buffer, + buf_size, + "song_scores %d/%d:\n" + "score: %d\n" + "player_id: %s\n", + i, + j, + stats->song_scores[i][j].score, + stats->song_scores[i][j].player_id); + + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; } + } - for (uint32_t i = 0; i < ASSET_NX2_USB_SAVE_MISSION_MAX; i++) { + free(buffer); - util_str_format(buffer, buf_size, - "mission slot: %d\n" - "clear_flags_directions: 0x%X\n" - "clear_flag_mission: %d\n" - "unused: 0x%X\n", - i, - stats->worldmax_mission_unlocks[i].clear_flags_directions, - stats->worldmax_mission_unlocks[i].clear_flag_mission, - stats->worldmax_mission_unlocks[i].unused); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < ASSET_NX2_USB_SAVE_MISSION_MAX; i++) { - - util_str_format(buffer, buf_size, - "worldmax_high_score %d: %d\n", - i, - stats->worldmax_high_score[i]); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < ASSET_NX2_USB_SAVE_MISSION_MAX; i++) { - - util_str_format(buffer, buf_size, - "worldmax_challenge %d: %d\n", - i, - stats->worldmax_challenge[i]); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < ASSET_NX2_USB_SAVE_BARRICADE_MAX; i++) { - - util_str_format(buffer, buf_size, - "worldmax_barricade %d:\n" - "flag_open: %d\n" - "unused: 0x%X\n", - i, - stats->worldmax_barricade[i].flag_open, - stats->worldmax_barricade[i].unused); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < ASSET_NX2_USB_SAVE_EVENT_MAX; i++) { - - util_str_format(buffer, buf_size, - "worldmax_event %d:\n" - "flag_cleared: %d\n" - "unused: 0x%X\n", - i, - stats->worldmax_event[i].flag_cleared, - stats->worldmax_event[i].unused); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < ASSET_NX2_USB_SAVE_WARP_MAX; i++) { - - util_str_format(buffer, buf_size, - "worldmax_warp %d:\n" - "direction_clear: 0x%X\n" - "clear: %d\n", - "unused: 0x%X\n", - i, - stats->worldmax_warp[i].direction_clear, - stats->worldmax_warp[i].clear, - stats->worldmax_warp[i].unused); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < ASSET_NX2_USB_SAVE_WORLDMAX_LOC_MAX; i++) { - - util_str_format(buffer, buf_size, - "worldmax_current_land %d: %d\n", - i, - stats->worldmax_current_land[i]); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < ASSET_NX2_USB_SAVE_WORLDMAX_LOC_MAX; i++) { - - util_str_format(buffer, buf_size, - "worldmax_current_mission %d: %d\n", - i, - stats->worldmax_current_mission[i]); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < ASSET_NX2_USB_SAVE_SONG_MAX; i++) { - - for (uint32_t j = 0; j < ASSET_NX2_USB_SAVE_NUM_MODES; j++) { - util_str_format(buffer, buf_size, - "song_scores %d/%d:\n" - "score: %d\n" - "player_id: %s\n", - i, - j, - stats->song_scores[i][j].score, - stats->song_scores[i][j].player_id); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - } - - free(buffer); - - return merged; + return merged; } -struct asset_nx2_usb_save* asset_nx2_usb_save_new(void) +struct asset_nx2_usb_save *asset_nx2_usb_save_new(void) { - struct asset_nx2_usb_save* save; - char name[10]; + struct asset_nx2_usb_save *save; + char name[10]; - save = (struct asset_nx2_usb_save*) util_xmalloc( - sizeof(struct asset_nx2_usb_save)); + save = (struct asset_nx2_usb_save *) util_xmalloc( + sizeof(struct asset_nx2_usb_save)); - memset(save, 0, sizeof(struct asset_nx2_usb_save)); + memset(save, 0, sizeof(struct asset_nx2_usb_save)); - sprintf(name, "NX%06d", rand() % 1000000); - strcpy(save->review.player_id, name); - strcpy(save->stats.player_id, name); + sprintf(name, "NX%06d", rand() % 1000000); + strcpy(save->review.player_id, name); + strcpy(save->stats.player_id, name); - /* default world map position */ - save->stats.worldmax_map_position = 0xEF001; + /* default world map position */ + save->stats.worldmax_map_position = 0xEF001; - /* nx2 release date as default timestamp */ - save->stats.timestamp.year = 2008; - save->stats.timestamp.month = 1; - save->stats.timestamp.day = 21; - save->stats.timestamp.hour = 0; - save->stats.timestamp.min = 0; - save->stats.timestamp.ms = 0; + /* nx2 release date as default timestamp */ + save->stats.timestamp.year = 2008; + save->stats.timestamp.month = 1; + save->stats.timestamp.day = 21; + save->stats.timestamp.hour = 0; + save->stats.timestamp.min = 0; + save->stats.timestamp.ms = 0; - return save; + return save; } -void asset_nx2_usb_save_finalize(struct asset_nx2_usb_save* save) +void asset_nx2_usb_save_finalize(struct asset_nx2_usb_save *save) { - /* checksum update */ - save->stats.adler32 = util_adler32_calc(1, - ((const uint8_t*) &save->stats) + 4, - sizeof(struct asset_nx2_usb_save_stats) - 4); + /* checksum update */ + save->stats.adler32 = util_adler32_calc( + 1, + ((const uint8_t *) &save->stats) + 4, + sizeof(struct asset_nx2_usb_save_stats) - 4); } -char* asset_nx2_usb_save_to_string(const struct asset_nx2_usb_save* save) +char *asset_nx2_usb_save_to_string(const struct asset_nx2_usb_save *save) { - char* review; - char* stats; - char* merged; + char *review; + char *stats; + char *merged; - review = asset_nx2_usb_save_review_to_string(&save->review); - stats = asset_nx2_usb_save_stats_to_string(&save->stats); + review = asset_nx2_usb_save_review_to_string(&save->review); + stats = asset_nx2_usb_save_stats_to_string(&save->stats); - merged = util_str_merge(review, stats); + merged = util_str_merge(review, stats); - free(review); - free(stats); + free(review); + free(stats); - return merged; + return merged; } -void asset_nx2_usb_save_decrypt(uint8_t* buf, size_t len) +void asset_nx2_usb_save_decrypt(uint8_t *buf, size_t len) { - /* skip non encrypted review area */ - buf += sizeof(struct asset_nx2_usb_save_review); - len -= sizeof(struct asset_nx2_usb_save_review); + /* skip non encrypted review area */ + buf += sizeof(struct asset_nx2_usb_save_review); + len -= sizeof(struct asset_nx2_usb_save_review); - for (size_t a = len - 1; a > 0; --a) { - buf[a] = (buf[a] ^ buf[a - 1]) + ((a * 1234567) >> 8); - } + for (size_t a = len - 1; a > 0; --a) { + buf[a] = (buf[a] ^ buf[a - 1]) + ((a * 1234567) >> 8); + } } -void asset_nx2_usb_save_encrypt(uint8_t* buf, size_t len) +void asset_nx2_usb_save_encrypt(uint8_t *buf, size_t len) { - /* skip non encrypted review area */ - buf += sizeof(struct asset_nx2_usb_save_review); - len -= sizeof(struct asset_nx2_usb_save_review); + /* skip non encrypted review area */ + buf += sizeof(struct asset_nx2_usb_save_review); + len -= sizeof(struct asset_nx2_usb_save_review); - for (size_t a = 1; a < len; ++a) { - buf[a] = (buf[a] - ((a * 1234567) >> 8)) ^ buf[a - 1]; - } + for (size_t a = 1; a < len; ++a) { + buf[a] = (buf[a] - ((a * 1234567) >> 8)) ^ buf[a - 1]; + } } \ No newline at end of file diff --git a/src/main/asset/nx2/lib/usb-save.h b/src/main/asset/nx2/lib/usb-save.h index 01e71b9..44cc579 100644 --- a/src/main/asset/nx2/lib/usb-save.h +++ b/src/main/asset/nx2/lib/usb-save.h @@ -7,116 +7,116 @@ #define ASSET_NX2_USB_SAVE_SIZE 30780 enum asset_nx2_usb_save_limits { - ASSET_NX2_USB_SAVE_SERIAL_ID_MAX = 64, - ASSET_NX2_USB_SAVE_PLAYER_ID_MAX = 12, - ASSET_NX2_USB_SAVE_WORLDMAX_LOC_MAX = 128, - ASSET_NX2_USB_SAVE_SONG_MAX = 256, - ASSET_NX2_USB_SAVE_MISSION_MAX = 1024, - ASSET_NX2_USB_SAVE_BARRICADE_MAX = 16, - ASSET_NX2_USB_SAVE_EVENT_MAX = 128, - ASSET_NX2_USB_SAVE_WARP_MAX = 8, - ASSET_NX2_USB_SAVE_NUM_MODES = 5, + ASSET_NX2_USB_SAVE_SERIAL_ID_MAX = 64, + ASSET_NX2_USB_SAVE_PLAYER_ID_MAX = 12, + ASSET_NX2_USB_SAVE_WORLDMAX_LOC_MAX = 128, + ASSET_NX2_USB_SAVE_SONG_MAX = 256, + ASSET_NX2_USB_SAVE_MISSION_MAX = 1024, + ASSET_NX2_USB_SAVE_BARRICADE_MAX = 16, + ASSET_NX2_USB_SAVE_EVENT_MAX = 128, + ASSET_NX2_USB_SAVE_WARP_MAX = 8, + ASSET_NX2_USB_SAVE_NUM_MODES = 5, }; struct asset_nx2_usb_save_time { - int16_t year; - uint8_t month; - uint8_t day; - uint8_t hour; - uint8_t min; - uint16_t ms; + int16_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t min; + uint16_t ms; } __attribute__((__packed__)); struct asset_nx2_usb_save_review { - char player_id[ASSET_NX2_USB_SAVE_PLAYER_ID_MAX]; - int32_t mileage; - int32_t reward_count; - int32_t worldmax_count; - int32_t play_count; - char worldmax_current_land[ASSET_NX2_USB_SAVE_WORLDMAX_LOC_MAX]; - char worldmax_current_mission[ASSET_NX2_USB_SAVE_WORLDMAX_LOC_MAX]; - int32_t kcal; - int32_t v02; + char player_id[ASSET_NX2_USB_SAVE_PLAYER_ID_MAX]; + int32_t mileage; + int32_t reward_count; + int32_t worldmax_count; + int32_t play_count; + char worldmax_current_land[ASSET_NX2_USB_SAVE_WORLDMAX_LOC_MAX]; + char worldmax_current_mission[ASSET_NX2_USB_SAVE_WORLDMAX_LOC_MAX]; + int32_t kcal; + int32_t v02; } __attribute__((__packed__)); struct asset_nx2_usb_save_stats { - uint32_t adler32; - char usb_serial[ASSET_NX2_USB_SAVE_SERIAL_ID_MAX]; - struct asset_nx2_usb_save_time timestamp; - int32_t avatar_id; - int32_t rank; - int32_t country_id; - char player_id[ASSET_NX2_USB_SAVE_PLAYER_ID_MAX]; - int32_t mileage; - int32_t play_count; - int32_t kcal; - int32_t v02; - int32_t worldmax_map_position; - int32_t reward_count; - int32_t worldmax_count; + uint32_t adler32; + char usb_serial[ASSET_NX2_USB_SAVE_SERIAL_ID_MAX]; + struct asset_nx2_usb_save_time timestamp; + int32_t avatar_id; + int32_t rank; + int32_t country_id; + char player_id[ASSET_NX2_USB_SAVE_PLAYER_ID_MAX]; + int32_t mileage; + int32_t play_count; + int32_t kcal; + int32_t v02; + int32_t worldmax_map_position; + int32_t reward_count; + int32_t worldmax_count; - struct { - /* bits 0-4 for modes/stepcharts */ - uint8_t mode : 5; - /* unused bit */ - uint8_t unused : 1; - /* bit 6 song itself */ - uint8_t song : 1; - /* bit 7 reveal flag */ - uint8_t reveal : 1; - } song_unlocks[ASSET_NX2_USB_SAVE_SONG_MAX] __attribute__((__packed__)); + struct { + /* bits 0-4 for modes/stepcharts */ + uint8_t mode : 5; + /* unused bit */ + uint8_t unused : 1; + /* bit 6 song itself */ + uint8_t song : 1; + /* bit 7 reveal flag */ + uint8_t reveal : 1; + } song_unlocks[ASSET_NX2_USB_SAVE_SONG_MAX] __attribute__((__packed__)); - struct { - uint8_t clear_flags_directions : 4; - uint8_t clear_flag_mission : 1; - uint8_t unused : 3; - } worldmax_mission_unlocks[ASSET_NX2_USB_SAVE_MISSION_MAX] - __attribute__((__packed__)); + struct { + uint8_t clear_flags_directions : 4; + uint8_t clear_flag_mission : 1; + uint8_t unused : 3; + } worldmax_mission_unlocks[ASSET_NX2_USB_SAVE_MISSION_MAX] + __attribute__((__packed__)); - int32_t worldmax_high_score[ASSET_NX2_USB_SAVE_MISSION_MAX]; - int32_t worldmax_challenge[ASSET_NX2_USB_SAVE_MISSION_MAX]; + int32_t worldmax_high_score[ASSET_NX2_USB_SAVE_MISSION_MAX]; + int32_t worldmax_challenge[ASSET_NX2_USB_SAVE_MISSION_MAX]; - struct { - uint8_t flag_open : 1; - uint8_t unused : 7; - } worldmax_barricade[ASSET_NX2_USB_SAVE_BARRICADE_MAX] - __attribute__((__packed__)); + struct { + uint8_t flag_open : 1; + uint8_t unused : 7; + } worldmax_barricade[ASSET_NX2_USB_SAVE_BARRICADE_MAX] + __attribute__((__packed__)); - struct { - uint8_t flag_cleared : 1; - uint8_t unused : 7; - } worldmax_event[ASSET_NX2_USB_SAVE_EVENT_MAX] __attribute__((__packed__)); + struct { + uint8_t flag_cleared : 1; + uint8_t unused : 7; + } worldmax_event[ASSET_NX2_USB_SAVE_EVENT_MAX] __attribute__((__packed__)); - struct { - uint8_t direction_clear : 4; - uint8_t clear : 1; - uint8_t unused : 3; - } worldmax_warp[ASSET_NX2_USB_SAVE_WARP_MAX] __attribute__((__packed__)); + struct { + uint8_t direction_clear : 4; + uint8_t clear : 1; + uint8_t unused : 3; + } worldmax_warp[ASSET_NX2_USB_SAVE_WARP_MAX] __attribute__((__packed__)); - char worldmax_current_land[ASSET_NX2_USB_SAVE_WORLDMAX_LOC_MAX]; - char worldmax_current_mission[ASSET_NX2_USB_SAVE_WORLDMAX_LOC_MAX]; + char worldmax_current_land[ASSET_NX2_USB_SAVE_WORLDMAX_LOC_MAX]; + char worldmax_current_mission[ASSET_NX2_USB_SAVE_WORLDMAX_LOC_MAX]; - struct { - int32_t score; - char player_id[ASSET_NX2_USB_SAVE_PLAYER_ID_MAX]; - } song_scores[ASSET_NX2_USB_SAVE_SONG_MAX][ASSET_NX2_USB_SAVE_NUM_MODES] - __attribute__((__packed__)); + struct { + int32_t score; + char player_id[ASSET_NX2_USB_SAVE_PLAYER_ID_MAX]; + } song_scores[ASSET_NX2_USB_SAVE_SONG_MAX][ASSET_NX2_USB_SAVE_NUM_MODES] + __attribute__((__packed__)); } __attribute__((__packed__)); struct asset_nx2_usb_save { - struct asset_nx2_usb_save_review review; - struct asset_nx2_usb_save_stats stats; + struct asset_nx2_usb_save_review review; + struct asset_nx2_usb_save_stats stats; } __attribute__((__packed__)); -struct asset_nx2_usb_save* asset_nx2_usb_save_new(void); +struct asset_nx2_usb_save *asset_nx2_usb_save_new(void); // update checksum and prepare profile to get encrypted -void asset_nx2_usb_save_finalize(struct asset_nx2_usb_save* save); +void asset_nx2_usb_save_finalize(struct asset_nx2_usb_save *save); -char* asset_nx2_usb_save_to_string(const struct asset_nx2_usb_save* save); +char *asset_nx2_usb_save_to_string(const struct asset_nx2_usb_save *save); -void asset_nx2_usb_save_decrypt(uint8_t* buf, size_t len); +void asset_nx2_usb_save_decrypt(uint8_t *buf, size_t len); -void asset_nx2_usb_save_encrypt(uint8_t* buf, size_t len); +void asset_nx2_usb_save_encrypt(uint8_t *buf, size_t len); #endif \ No newline at end of file diff --git a/src/main/asset/nx2/lib/util.c b/src/main/asset/nx2/lib/util.c index ca8b04f..cfadc1b 100644 --- a/src/main/asset/nx2/lib/util.c +++ b/src/main/asset/nx2/lib/util.c @@ -7,94 +7,100 @@ #include "util.h" -struct asset_nx2_usb_rank* asset_nx2_usb_rank_load_from_file(const char* path, - bool encrypted) +struct asset_nx2_usb_rank * +asset_nx2_usb_rank_load_from_file(const char *path, bool encrypted) { - struct asset_nx2_usb_rank* rank; - size_t size; + struct asset_nx2_usb_rank *rank; + size_t size; - if (!util_file_load(path, (void**) &rank, &size, false)) { - log_error("Loading nx2 rank file %s failed", path); - return NULL; - } + if (!util_file_load(path, (void **) &rank, &size, false)) { + log_error("Loading nx2 rank file %s failed", path); + return NULL; + } - if (size != sizeof(struct asset_nx2_usb_rank)) { - log_error("Invalid size of nx2 rank file %s: %d != %d", path, size, - sizeof(struct asset_nx2_usb_rank)); - free(rank); - return NULL; - } + if (size != sizeof(struct asset_nx2_usb_rank)) { + log_error( + "Invalid size of nx2 rank file %s: %d != %d", + path, + size, + sizeof(struct asset_nx2_usb_rank)); + free(rank); + return NULL; + } - if (encrypted) { - asset_nx2_usb_rank_decrypt((uint8_t*) rank, size); - } + if (encrypted) { + asset_nx2_usb_rank_decrypt((uint8_t *) rank, size); + } - return rank; + return rank; } -bool asset_nx2_usb_rank_save_to_file(const char* path, - const struct asset_nx2_usb_rank* rank, bool encrypt) +bool asset_nx2_usb_rank_save_to_file( + const char *path, const struct asset_nx2_usb_rank *rank, bool encrypt) { - struct asset_nx2_usb_rank rank_enc; + struct asset_nx2_usb_rank rank_enc; - memcpy(&rank_enc, rank, sizeof(struct asset_nx2_usb_rank)); + memcpy(&rank_enc, rank, sizeof(struct asset_nx2_usb_rank)); - if (encrypt) { - asset_nx2_usb_rank_encrypt((uint8_t*) &rank_enc, - sizeof(struct asset_nx2_usb_rank)); - } + if (encrypt) { + asset_nx2_usb_rank_encrypt( + (uint8_t *) &rank_enc, sizeof(struct asset_nx2_usb_rank)); + } - if (!util_file_save(path, (void**) &rank_enc, - sizeof(struct asset_nx2_usb_rank))) { - log_error("Storing nx2 rank data to %s failed", path); - return false; - } + if (!util_file_save( + path, (void **) &rank_enc, sizeof(struct asset_nx2_usb_rank))) { + log_error("Storing nx2 rank data to %s failed", path); + return false; + } - return true; + return true; } -struct asset_nx2_usb_save* asset_nx2_usb_save_load_from_file(const char* path, - bool encrypted) +struct asset_nx2_usb_save * +asset_nx2_usb_save_load_from_file(const char *path, bool encrypted) { - struct asset_nx2_usb_save* save; - size_t size; + struct asset_nx2_usb_save *save; + size_t size; - if (!util_file_load(path, (void**) &save, &size, false)) { - log_error("Loading nx2 save file %s failed", path); - return NULL; - } + if (!util_file_load(path, (void **) &save, &size, false)) { + log_error("Loading nx2 save file %s failed", path); + return NULL; + } - if (size != sizeof(struct asset_nx2_usb_save)) { - log_error("Invalid size of nx2 save file %s: %d != %d", path, size, - sizeof(struct asset_nx2_usb_save)); - free(save); - return NULL; - } + if (size != sizeof(struct asset_nx2_usb_save)) { + log_error( + "Invalid size of nx2 save file %s: %d != %d", + path, + size, + sizeof(struct asset_nx2_usb_save)); + free(save); + return NULL; + } - if (encrypted) { - asset_nx2_usb_save_decrypt((uint8_t*) save, size); - } + if (encrypted) { + asset_nx2_usb_save_decrypt((uint8_t *) save, size); + } - return save; + return save; } -bool asset_nx2_usb_save_save_to_file(const char* path, - const struct asset_nx2_usb_save* save, bool encrypt) +bool asset_nx2_usb_save_save_to_file( + const char *path, const struct asset_nx2_usb_save *save, bool encrypt) { - struct asset_nx2_usb_save save_enc; + struct asset_nx2_usb_save save_enc; - memcpy(&save_enc, save, sizeof(struct asset_nx2_usb_save)); + memcpy(&save_enc, save, sizeof(struct asset_nx2_usb_save)); - if (encrypt) { - asset_nx2_usb_save_encrypt((uint8_t*) &save_enc, - sizeof(struct asset_nx2_usb_save)); - } + if (encrypt) { + asset_nx2_usb_save_encrypt( + (uint8_t *) &save_enc, sizeof(struct asset_nx2_usb_save)); + } - if (!util_file_save(path, (const void*) &save_enc, - sizeof(struct asset_nx2_usb_save))) { - log_error("Storing nx2 save data to %s failed", path); - return false; - } + if (!util_file_save( + path, (const void *) &save_enc, sizeof(struct asset_nx2_usb_save))) { + log_error("Storing nx2 save data to %s failed", path); + return false; + } - return true; + return true; } \ No newline at end of file diff --git a/src/main/asset/nx2/lib/util.h b/src/main/asset/nx2/lib/util.h index 1a42d6d..caa1812 100644 --- a/src/main/asset/nx2/lib/util.h +++ b/src/main/asset/nx2/lib/util.h @@ -7,15 +7,19 @@ #include "usb-save.h" // load from file and decrypt, returns decrypted struct -struct asset_nx2_usb_rank* asset_nx2_usb_rank_load_from_file(const char* path, bool encrypted); +struct asset_nx2_usb_rank * +asset_nx2_usb_rank_load_from_file(const char *path, bool encrypted); // takes decrypted rank data, encrypts it and writes it to file -bool asset_nx2_usb_rank_save_to_file(const char* path, const struct asset_nx2_usb_rank* rank, bool encrypt); +bool asset_nx2_usb_rank_save_to_file( + const char *path, const struct asset_nx2_usb_rank *rank, bool encrypt); // load from file and decrypt, returns decrypted struct -struct asset_nx2_usb_save* asset_nx2_usb_save_load_from_file(const char* path, bool encrypted); +struct asset_nx2_usb_save * +asset_nx2_usb_save_load_from_file(const char *path, bool encrypted); // takes decrypted save data, encrypts it and writes it to file -bool asset_nx2_usb_save_save_to_file(const char* path, const struct asset_nx2_usb_save* save, bool encrypt); +bool asset_nx2_usb_save_save_to_file( + const char *path, const struct asset_nx2_usb_save *save, bool encrypt); #endif \ No newline at end of file diff --git a/src/main/asset/nx2/tool/usb-profile.c b/src/main/asset/nx2/tool/usb-profile.c index ba54629..77c206a 100644 --- a/src/main/asset/nx2/tool/usb-profile.c +++ b/src/main/asset/nx2/tool/usb-profile.c @@ -9,146 +9,150 @@ #include "util/str.h" -int main(int argc, char** argv) +int main(int argc, char **argv) { - int ret; - char* rank_path; - char* save_path; + int ret; + char *rank_path; + char *save_path; - if (argc < 3) { - printf("Usage: %s [cmd: new, dec, enc, dump] " - "[path containing nx2rank.bin nx2save.bin]\n", argv[0]); - return -1; + if (argc < 3) { + printf( + "Usage: %s [cmd: new, dec, enc, dump] " + "[path containing nx2rank.bin nx2save.bin]\n", + argv[0]); + return -1; + } + + ret = 0; + + rank_path = util_str_merge(argv[2], "nx2rank.bin"); + save_path = util_str_merge(argv[2], "nx2save.bin"); + + if (!strcmp(argv[1], "new")) { + struct asset_nx2_usb_rank *rank = asset_nx2_usb_rank_new(); + struct asset_nx2_usb_save *save = asset_nx2_usb_save_new(); + + asset_nx2_usb_rank_finalize(rank); + asset_nx2_usb_save_finalize(save); + + if (!asset_nx2_usb_rank_save_to_file(rank_path, rank, true)) { + fprintf(stderr, "Creating rank file %s failed\n", rank_path); + ret = -2; } - ret = 0; + if (!asset_nx2_usb_save_save_to_file(save_path, save, true)) { + fprintf(stderr, "Creating save file %s failed\n", save_path); + ret = -3; + } - rank_path = util_str_merge(argv[2], "nx2rank.bin"); - save_path = util_str_merge(argv[2], "nx2save.bin"); + free(rank); + free(save); + } else { + struct asset_nx2_usb_rank *rank; + struct asset_nx2_usb_save *save; + bool encrypted; - if (!strcmp(argv[1], "new")) { - struct asset_nx2_usb_rank* rank = asset_nx2_usb_rank_new(); - struct asset_nx2_usb_save* save = asset_nx2_usb_save_new(); + if (!strcmp(argv[1], "enc")) { + char *tmp; - asset_nx2_usb_rank_finalize(rank); - asset_nx2_usb_save_finalize(save); + encrypted = false; - if (!asset_nx2_usb_rank_save_to_file(rank_path, rank, true)) { - fprintf(stderr, "Creating rank file %s failed\n", rank_path); - ret = -2; - } + tmp = util_str_merge(rank_path, ".dec"); + free(rank_path); + rank_path = tmp; - if (!asset_nx2_usb_save_save_to_file(save_path, save, true)) { - fprintf(stderr, "Creating save file %s failed\n", save_path); - ret = -3; - } - - free(rank); - free(save); + tmp = util_str_merge(save_path, ".dec"); + free(save_path); + save_path = tmp; } else { - struct asset_nx2_usb_rank* rank; - struct asset_nx2_usb_save* save; - bool encrypted; - - if (!strcmp(argv[1], "enc")) { - char* tmp; - - encrypted = false; - - tmp = util_str_merge(rank_path, ".dec"); - free(rank_path); - rank_path = tmp; - - tmp = util_str_merge(save_path, ".dec"); - free(save_path); - save_path = tmp; - } else { - encrypted = true; - } - - rank = asset_nx2_usb_rank_load_from_file(rank_path, encrypted); - save = asset_nx2_usb_save_load_from_file(save_path, encrypted); - - if (!rank) { - fprintf(stderr, "Loading %s failed", rank_path); - ret = -4; - goto cleanup; - } - - if (!save) { - fprintf(stderr, "Loading %s failed", save_path); - ret = -5; - free(rank); - goto cleanup; - } - - if (!strcmp(argv[1], "dec")) { - char* rank_path_dec; - char* save_path_dec; - - rank_path_dec = util_str_merge(rank_path, ".dec"); - save_path_dec = util_str_merge(save_path, ".dec"); - - if (!asset_nx2_usb_rank_save_to_file(rank_path_dec, rank, false)) { - fprintf(stderr, "Saving decrypted rank file to %s failed\n", - rank_path_dec); - ret = -6; - } - - if (!asset_nx2_usb_save_save_to_file(save_path_dec, save, false)) { - fprintf(stderr, "Saving decrypted save file to %s failed\n", - save_path_dec); - ret = -7; - } - - free(rank_path_dec); - free(save_path_dec); - } else if (!strcmp(argv[1], "enc")) { - char* rank_path_enc; - char* save_path_enc; - - rank_path_enc = util_str_merge(rank_path, ".enc"); - save_path_enc = util_str_merge(save_path, ".enc"); - - if (!asset_nx2_usb_rank_save_to_file(rank_path_enc, rank, true)) { - fprintf(stderr, "Saving encrypted rank file to %s failed\n", - rank_path_enc); - ret = -6; - } - - if (!asset_nx2_usb_save_save_to_file(save_path_enc, save, true)) { - fprintf(stderr, "Saving encrypted save file to %s failed\n", - save_path_enc); - ret = -7; - } - - free(rank_path_enc); - free(save_path_enc); - } else if (!strcmp(argv[1], "dump")) { - char* rank_str; - char* save_str; - - rank_str = asset_nx2_usb_rank_to_string(rank); - save_str = asset_nx2_usb_save_to_string(save); - - printf("----------------- rank -----------------\n" - "%s----------------- save -----------------\n%s", - rank_str, save_str); - - free(rank_str); - free(save_str); - } else { - fprintf(stderr, "Unknown command %s\n", argv[1]); - ret = -4; - } - - free(rank); - free(save); + encrypted = true; } + rank = asset_nx2_usb_rank_load_from_file(rank_path, encrypted); + save = asset_nx2_usb_save_load_from_file(save_path, encrypted); + + if (!rank) { + fprintf(stderr, "Loading %s failed", rank_path); + ret = -4; + goto cleanup; + } + + if (!save) { + fprintf(stderr, "Loading %s failed", save_path); + ret = -5; + free(rank); + goto cleanup; + } + + if (!strcmp(argv[1], "dec")) { + char *rank_path_dec; + char *save_path_dec; + + rank_path_dec = util_str_merge(rank_path, ".dec"); + save_path_dec = util_str_merge(save_path, ".dec"); + + if (!asset_nx2_usb_rank_save_to_file(rank_path_dec, rank, false)) { + fprintf( + stderr, "Saving decrypted rank file to %s failed\n", rank_path_dec); + ret = -6; + } + + if (!asset_nx2_usb_save_save_to_file(save_path_dec, save, false)) { + fprintf( + stderr, "Saving decrypted save file to %s failed\n", save_path_dec); + ret = -7; + } + + free(rank_path_dec); + free(save_path_dec); + } else if (!strcmp(argv[1], "enc")) { + char *rank_path_enc; + char *save_path_enc; + + rank_path_enc = util_str_merge(rank_path, ".enc"); + save_path_enc = util_str_merge(save_path, ".enc"); + + if (!asset_nx2_usb_rank_save_to_file(rank_path_enc, rank, true)) { + fprintf( + stderr, "Saving encrypted rank file to %s failed\n", rank_path_enc); + ret = -6; + } + + if (!asset_nx2_usb_save_save_to_file(save_path_enc, save, true)) { + fprintf( + stderr, "Saving encrypted save file to %s failed\n", save_path_enc); + ret = -7; + } + + free(rank_path_enc); + free(save_path_enc); + } else if (!strcmp(argv[1], "dump")) { + char *rank_str; + char *save_str; + + rank_str = asset_nx2_usb_rank_to_string(rank); + save_str = asset_nx2_usb_save_to_string(save); + + printf( + "----------------- rank -----------------\n" + "%s----------------- save -----------------\n%s", + rank_str, + save_str); + + free(rank_str); + free(save_str); + } else { + fprintf(stderr, "Unknown command %s\n", argv[1]); + ret = -4; + } + + free(rank); + free(save); + } + cleanup: - free(rank_path); - free(save_path); + free(rank_path); + free(save_path); - return ret; + return ret; } \ No newline at end of file diff --git a/src/main/asset/nxa/lib/usb-rank.c b/src/main/asset/nxa/lib/usb-rank.c index 2f17ce2..f0da648 100644 --- a/src/main/asset/nxa/lib/usb-rank.c +++ b/src/main/asset/nxa/lib/usb-rank.c @@ -8,96 +8,101 @@ #include "usb-rank.h" -struct asset_nxa_usb_rank* asset_nxa_usb_rank_new(void) +struct asset_nxa_usb_rank *asset_nxa_usb_rank_new(void) { - struct asset_nxa_usb_rank* rank; + struct asset_nxa_usb_rank *rank; - rank = (struct asset_nxa_usb_rank*) - util_xmalloc(sizeof(struct asset_nxa_usb_rank)); + rank = (struct asset_nxa_usb_rank *) util_xmalloc( + sizeof(struct asset_nxa_usb_rank)); - memset(rank, 0, sizeof(struct asset_nxa_usb_rank)); + memset(rank, 0, sizeof(struct asset_nxa_usb_rank)); - return rank; + return rank; } -void asset_nxa_usb_rank_finalize(struct asset_nxa_usb_rank* rank) +void asset_nxa_usb_rank_finalize(struct asset_nxa_usb_rank *rank) { - rank->adler32 = util_adler32_calc(1, ((const uint8_t*) rank) + 4, - sizeof(struct asset_nxa_usb_rank) - 4); + rank->adler32 = util_adler32_calc( + 1, ((const uint8_t *) rank) + 4, sizeof(struct asset_nxa_usb_rank) - 4); } -char* asset_nxa_usb_rank_to_string(const struct asset_nxa_usb_rank* rank) +char *asset_nxa_usb_rank_to_string(const struct asset_nxa_usb_rank *rank) { - char* buffer; - char* buffer2; - char* merged; - char* usb_ser; + char *buffer; + char *buffer2; + char *merged; + char *usb_ser; - buffer = (char*) util_xmalloc(512); - memset(buffer, 0, 512); + buffer = (char *) util_xmalloc(512); + memset(buffer, 0, 512); - usb_ser = util_str_buffer((const uint8_t*) rank->usb_serial, - ASSET_NXA_USB_RANK_USB_SERIAL_LEN); + usb_ser = util_str_buffer( + (const uint8_t *) rank->usb_serial, ASSET_NXA_USB_RANK_USB_SERIAL_LEN); - util_str_format(buffer, 512, - "adler32: 0x%X\n" - // "usb_serial: %s\n", - "num_rankings: %d\n" - "ranking entries:\n", - rank->adler32, - // usb_ser, - rank->num_rankings); + util_str_format( + buffer, + 512, + "adler32: 0x%X\n" + // "usb_serial: %s\n", + "num_rankings: %d\n" + "ranking entries:\n", + rank->adler32, + // usb_ser, + rank->num_rankings); - for (uint32_t i = 0; i < ASSET_NXA_USB_RANK_MAX_RANK_ENTRIES; i++) { + for (uint32_t i = 0; i < ASSET_NXA_USB_RANK_MAX_RANK_ENTRIES; i++) { - for (uint32_t j = 0; j < ASSET_NXA_USB_RANK_MAX_STAGES; j++) { - buffer2 = (char*) util_xmalloc(512); - memset(buffer2, 0, 512); + for (uint32_t j = 0; j < ASSET_NXA_USB_RANK_MAX_STAGES; j++) { + buffer2 = (char *) util_xmalloc(512); + memset(buffer2, 0, 512); - util_str_format(buffer2, 512, - "%d/%d:\n" - "game_mode: %d\n" - "play_order: %d\n" - "play_score: %d\n" - "grade: %d\n" - "mileage: %d\n" - "play_time: %f\n" - "kcal: %f\n" - "v02: %f\n", - i, j, - rank->entries[i][j].game_mode, - rank->entries[i][j].play_order, - rank->entries[i][j].play_score, - rank->entries[i][j].grade, - rank->entries[i][j].mileage, - rank->entries[i][j].play_time, - rank->entries[i][j].kcal, - rank->entries[i][j].v02); + util_str_format( + buffer2, + 512, + "%d/%d:\n" + "game_mode: %d\n" + "play_order: %d\n" + "play_score: %d\n" + "grade: %d\n" + "mileage: %d\n" + "play_time: %f\n" + "kcal: %f\n" + "v02: %f\n", + i, + j, + rank->entries[i][j].game_mode, + rank->entries[i][j].play_order, + rank->entries[i][j].play_score, + rank->entries[i][j].grade, + rank->entries[i][j].mileage, + rank->entries[i][j].play_time, + rank->entries[i][j].kcal, + rank->entries[i][j].v02); - merged = util_str_merge(buffer, buffer2); + merged = util_str_merge(buffer, buffer2); - free(buffer); - free(buffer2); + free(buffer); + free(buffer2); - buffer = merged; - } + buffer = merged; } + } - free(usb_ser); + free(usb_ser); - return buffer; + return buffer; } -void asset_nxa_usb_rank_decrypt(uint8_t* buf, size_t len) +void asset_nxa_usb_rank_decrypt(uint8_t *buf, size_t len) { - for (size_t a = len - 1; a > 0; --a) { - buf[a] = (buf[a] ^ buf[a - 1]) + ((a * 1234567) >> 8); - } + for (size_t a = len - 1; a > 0; --a) { + buf[a] = (buf[a] ^ buf[a - 1]) + ((a * 1234567) >> 8); + } } -void asset_nxa_usb_rank_encrypt(uint8_t* buf, size_t len) +void asset_nxa_usb_rank_encrypt(uint8_t *buf, size_t len) { - for (size_t a = 1; a < len; ++a) { - buf[a] = (buf[a] - ((a * 1234567) >> 8)) ^ buf[a - 1]; - } + for (size_t a = 1; a < len; ++a) { + buf[a] = (buf[a] - ((a * 1234567) >> 8)) ^ buf[a - 1]; + } } \ No newline at end of file diff --git a/src/main/asset/nxa/lib/usb-rank.h b/src/main/asset/nxa/lib/usb-rank.h index 58d2b96..45019f1 100644 --- a/src/main/asset/nxa/lib/usb-rank.h +++ b/src/main/asset/nxa/lib/usb-rank.h @@ -5,39 +5,39 @@ #include enum asset_nxa_usb_rank_sizes { - ASSET_NXA_USB_RANK_MAX_STAGES = 3, - ASSET_NXA_USB_RANK_MAX_RANK_ENTRIES = 256, - ASSET_NXA_USB_RANK_USB_SERIAL_LEN = 64, + ASSET_NXA_USB_RANK_MAX_STAGES = 3, + ASSET_NXA_USB_RANK_MAX_RANK_ENTRIES = 256, + ASSET_NXA_USB_RANK_USB_SERIAL_LEN = 64, }; struct asset_nxa_usb_rank_entry { - int32_t game_mode; - int32_t play_order; - int32_t play_score; - int32_t grade; - int32_t mileage; - float play_time; - float kcal; - float v02; + int32_t game_mode; + int32_t play_order; + int32_t play_score; + int32_t grade; + int32_t mileage; + float play_time; + float kcal; + float v02; } __attribute__((__packed__)); struct asset_nxa_usb_rank { - uint32_t adler32; - char usb_serial[ASSET_NXA_USB_RANK_USB_SERIAL_LEN]; - uint32_t num_rankings; - struct asset_nxa_usb_rank_entry - entries[ASSET_NXA_USB_RANK_MAX_RANK_ENTRIES][ASSET_NXA_USB_RANK_MAX_STAGES]; + uint32_t adler32; + char usb_serial[ASSET_NXA_USB_RANK_USB_SERIAL_LEN]; + uint32_t num_rankings; + struct asset_nxa_usb_rank_entry entries[ASSET_NXA_USB_RANK_MAX_RANK_ENTRIES] + [ASSET_NXA_USB_RANK_MAX_STAGES]; } __attribute__((__packed__)); -struct asset_nxa_usb_rank* asset_nxa_usb_rank_new(void); +struct asset_nxa_usb_rank *asset_nxa_usb_rank_new(void); // update checksum and prepare profile to get encrypted -void asset_nxa_usb_rank_finalize(struct asset_nxa_usb_rank* rank); +void asset_nxa_usb_rank_finalize(struct asset_nxa_usb_rank *rank); -char* asset_nxa_usb_rank_to_string(const struct asset_nxa_usb_rank* rank); +char *asset_nxa_usb_rank_to_string(const struct asset_nxa_usb_rank *rank); -void asset_nxa_usb_rank_decrypt(uint8_t* buf, size_t len); +void asset_nxa_usb_rank_decrypt(uint8_t *buf, size_t len); -void asset_nxa_usb_rank_encrypt(uint8_t* buf, size_t len); +void asset_nxa_usb_rank_encrypt(uint8_t *buf, size_t len); #endif \ No newline at end of file diff --git a/src/main/asset/nxa/lib/usb-save.c b/src/main/asset/nxa/lib/usb-save.c index 3376128..bc13a09 100644 --- a/src/main/asset/nxa/lib/usb-save.c +++ b/src/main/asset/nxa/lib/usb-save.c @@ -8,450 +8,479 @@ #include "usb-save.h" -static char* asset_nxa_usb_save_time_to_string( - const struct asset_nxa_usb_save_time* time) +static char * +asset_nxa_usb_save_time_to_string(const struct asset_nxa_usb_save_time *time) { - char* buffer; + char *buffer; - buffer = (char*) util_xmalloc(128); - memset(buffer, 0, 128); + buffer = (char *) util_xmalloc(128); + memset(buffer, 0, 128); - util_str_format(buffer, 128, - "year: %d\n" - "month: %d\n" - "day: %d\n" - "hour: %d\n" - "min: %d\n" - "ms: %d\n", - time->year, - time->month, - time->day, - time->hour, - time->min, - time->ms); + util_str_format( + buffer, + 128, + "year: %d\n" + "month: %d\n" + "day: %d\n" + "hour: %d\n" + "min: %d\n" + "ms: %d\n", + time->year, + time->month, + time->day, + time->hour, + time->min, + time->ms); - return buffer; + return buffer; } -static char* asset_nxa_usb_save_review_to_string( - const struct asset_nxa_usb_save_review* review) +static char *asset_nxa_usb_save_review_to_string( + const struct asset_nxa_usb_save_review *review) { - char* buffer; - char* land; - char* mission; - char* timestamp; + char *buffer; + char *land; + char *mission; + char *timestamp; - buffer = (char*) util_xmalloc(1024); - memset(buffer, 0, 1024); + buffer = (char *) util_xmalloc(1024); + memset(buffer, 0, 1024); - land = util_str_buffer((const uint8_t*) review->worldmax_current_land, - ASSET_NXA_USB_SAVE_WORLDMAX_LOC_MAX); - mission = util_str_buffer((const uint8_t*) review->worldmax_current_mission, - ASSET_NXA_USB_SAVE_WORLDMAX_LOC_MAX); - timestamp = asset_nxa_usb_save_time_to_string(&review->timestamp); + land = util_str_buffer( + (const uint8_t *) review->worldmax_current_land, + ASSET_NXA_USB_SAVE_WORLDMAX_LOC_MAX); + mission = util_str_buffer( + (const uint8_t *) review->worldmax_current_mission, + ASSET_NXA_USB_SAVE_WORLDMAX_LOC_MAX); + timestamp = asset_nxa_usb_save_time_to_string(&review->timestamp); - util_str_format(buffer, 1024, - ">>> review:\n" - "player_id: %s\n" - "mileage: %d\n" - "reward_count: %d\n" - "worldmax_count: %d\n" - "play_count: %d\n" - "worldmax_current_land: %s\n" - "worldmax_current_mission: %s\n" - "kcal: %d\n" - "v02: %d\n", - "timestamp: \n%s", - "running_step: %d\n", - "play_time_minutes: %f\n", - "total_completion_percentage: %f\n", - "arcade_percentage: %f\n", - "brain_shower_percentage: %f\n", - "special_percentage: %f\n", - review->player_id, - review->mileage, - review->reward_count, - review->worldmax_count, - review->play_count, - land, - mission, - review->kcal, - review->v02, - timestamp, - review->running_step, - review->play_time_minutes, - review->total_completion_percentage, - review->arcade_percentage, - review->brain_shower_percentage, - review->special_percentage); + util_str_format( + buffer, + 1024, + ">>> review:\n" + "player_id: %s\n" + "mileage: %d\n" + "reward_count: %d\n" + "worldmax_count: %d\n" + "play_count: %d\n" + "worldmax_current_land: %s\n" + "worldmax_current_mission: %s\n" + "kcal: %d\n" + "v02: %d\n", + "timestamp: \n%s", + "running_step: %d\n", + "play_time_minutes: %f\n", + "total_completion_percentage: %f\n", + "arcade_percentage: %f\n", + "brain_shower_percentage: %f\n", + "special_percentage: %f\n", + review->player_id, + review->mileage, + review->reward_count, + review->worldmax_count, + review->play_count, + land, + mission, + review->kcal, + review->v02, + timestamp, + review->running_step, + review->play_time_minutes, + review->total_completion_percentage, + review->arcade_percentage, + review->brain_shower_percentage, + review->special_percentage); - free(land); - free(mission); - free(timestamp); + free(land); + free(mission); + free(timestamp); - return buffer; + return buffer; } -static char* asset_nxa_usb_save_stats_to_string( - const struct asset_nxa_usb_save_stats* stats) +static char * +asset_nxa_usb_save_stats_to_string(const struct asset_nxa_usb_save_stats *stats) { - char* merged; - char* buffer; - char* timestamp; - char* tmp; - char* tmp2; - const size_t buf_size = 16384; + char *merged; + char *buffer; + char *timestamp; + char *tmp; + char *tmp2; + const size_t buf_size = 16384; - merged = (char*) util_xmalloc(buf_size); - memset(merged, 0, buf_size); + merged = (char *) util_xmalloc(buf_size); + memset(merged, 0, buf_size); - buffer = (char*) util_xmalloc(buf_size); - memset(buffer, 0, buf_size); + buffer = (char *) util_xmalloc(buf_size); + memset(buffer, 0, buf_size); - timestamp = asset_nxa_usb_save_time_to_string(&stats->timestamp); + timestamp = asset_nxa_usb_save_time_to_string(&stats->timestamp); - util_str_format(merged, buf_size, - ">>> stats:\n" - "adler32: 0x%X\n" - "usb_serial: %s\n" - "timestamp: %s" - "avatar_id: %d\n" - "rank: %d\n" - "country_id: %d\n" - "player_id: %s\n" - "mileage: %d\n" - "play_count: %d\n" - "kcal: %d\n" - "v02: %d\n" - "worldmax_map_position: 0x%X\n" - "reward_count: %d\n" - "worldmax_count: %d\n", - stats->adler32, - stats->usb_serial, - timestamp, - stats->avatar_id, - stats->rank, - stats->country_id, - stats->player_id, - stats->mileage, - stats->play_count, - stats->kcal, - stats->v02, - stats->worldmax_map_position, - stats->reward_count, - stats->worldmax_count); + util_str_format( + merged, + buf_size, + ">>> stats:\n" + "adler32: 0x%X\n" + "usb_serial: %s\n" + "timestamp: %s" + "avatar_id: %d\n" + "rank: %d\n" + "country_id: %d\n" + "player_id: %s\n" + "mileage: %d\n" + "play_count: %d\n" + "kcal: %d\n" + "v02: %d\n" + "worldmax_map_position: 0x%X\n" + "reward_count: %d\n" + "worldmax_count: %d\n", + stats->adler32, + stats->usb_serial, + timestamp, + stats->avatar_id, + stats->rank, + stats->country_id, + stats->player_id, + stats->mileage, + stats->play_count, + stats->kcal, + stats->v02, + stats->worldmax_map_position, + stats->reward_count, + stats->worldmax_count); - free(timestamp); + free(timestamp); - tmp = util_str_merge(merged, "song_unlocks:\n"); + tmp = util_str_merge(merged, "song_unlocks:\n"); - free(merged); - merged = tmp; + free(merged); + merged = tmp; - for (uint32_t i = 0; i < ASSET_NXA_USB_SAVE_SONG_MAX; i++) { + for (uint32_t i = 0; i < ASSET_NXA_USB_SAVE_SONG_MAX; i++) { - util_str_format(buffer, buf_size, - "song slot: %d\n" - "mode: 0x%X\n" - "unused: 0x%X\n" - "song: %d\n" - "reveal: %d\n", - i, - stats->song_unlocks[i].mode, - stats->song_unlocks[i].unused, - stats->song_unlocks[i].song, - stats->song_unlocks[i].reveal); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < ASSET_NXA_USB_SAVE_MISSION_MAX; i++) { - - util_str_format(buffer, buf_size, - "mission slot: %d\n" - "clear_flags_directions: 0x%X\n" - "clear_flag_mission: %d\n" - "unused: 0x%X\n", - i, - stats->worldmax_mission_unlocks[i].clear_flags_directions, - stats->worldmax_mission_unlocks[i].clear_flag_mission, - stats->worldmax_mission_unlocks[i].unused); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < ASSET_NXA_USB_SAVE_MISSION_MAX; i++) { - - util_str_format(buffer, buf_size, - "worldmax_high_score %d: %d\n", - i, - stats->worldmax_high_score[i]); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < ASSET_NXA_USB_SAVE_MISSION_MAX; i++) { - - util_str_format(buffer, buf_size, - "worldmax_challenge %d: %d\n", - i, - stats->worldmax_challenge[i]); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < ASSET_NXA_USB_SAVE_BARRICADE_MAX; i++) { - - util_str_format(buffer, buf_size, - "worldmax_barricade %d:\n" - "flag_open: %d\n" - "unused: 0x%X\n", - i, - stats->worldmax_barricade[i].flag_open, - stats->worldmax_barricade[i].unused); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < ASSET_NXA_USB_SAVE_EVENT_MAX; i++) { - - util_str_format(buffer, buf_size, - "worldmax_event %d:\n" - "flag_cleared: %d\n" - "unused: 0x%X\n", - i, - stats->worldmax_event[i].flag_cleared, - stats->worldmax_event[i].unused); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < ASSET_NXA_USB_SAVE_WARP_MAX; i++) { - - util_str_format(buffer, buf_size, - "worldmax_warp %d:\n" - "direction_clear: 0x%X\n" - "clear: %d\n", - "unused: 0x%X\n", - i, - stats->worldmax_warp[i].direction_clear, - stats->worldmax_warp[i].clear, - stats->worldmax_warp[i].unused); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < ASSET_NXA_USB_SAVE_WORLDMAX_LOC_MAX; i++) { - - util_str_format(buffer, buf_size, - "worldmax_current_land %d: %d\n", - i, - stats->worldmax_current_land[i]); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < ASSET_NXA_USB_SAVE_WORLDMAX_LOC_MAX; i++) { - - util_str_format(buffer, buf_size, - "worldmax_current_mission %d: %d\n", - i, - stats->worldmax_current_mission[i]); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - - for (uint32_t i = 0; i < ASSET_NXA_USB_SAVE_SONG_MAX; i++) { - - for (uint32_t j = 0; j < ASSET_NXA_USB_SAVE_NUM_MODES; j++) { - util_str_format(buffer, buf_size, - "song_scores %d/%d:\n" - "score: %d\n" - "player_id: %s\n", - i, - j, - stats->song_scores[i][j].score, - stats->song_scores[i][j].player_id); - - tmp = util_str_merge(merged, buffer); - - free(merged); - merged = tmp; - } - } - - /* ------------- */ - util_str_format(buffer, buf_size, - "security_dongle_mfgid 0x%X\n" - "unlock_signal: 0x%X\n" - "running_steps: %d\n" - "total_play_time_min: %f\n" - "total_completion_percentage: %f\n" - "arcade_completion_percentage: %f\n" - "brain_shower_completion_percentage: %f\n" - "special_stage_completion_percentage: %f\n", - stats->security_dongle_mfgid, - stats->unlock_signal, - stats->running_steps, - stats->total_play_time_min, - stats->total_completion_percentage, - stats->arcade_completion_percentage, - stats->brain_shower_completion_percentage, - stats->special_stage_completion_percentage); + util_str_format( + buffer, + buf_size, + "song slot: %d\n" + "mode: 0x%X\n" + "unused: 0x%X\n" + "song: %d\n" + "reveal: %d\n", + i, + stats->song_unlocks[i].mode, + stats->song_unlocks[i].unused, + stats->song_unlocks[i].song, + stats->song_unlocks[i].reveal); tmp = util_str_merge(merged, buffer); free(merged); merged = tmp; + } - /* ------------- */ - tmp2 = util_str_buffer(stats->unkn_some_map_scores_to_song_ids, - 4096); + for (uint32_t i = 0; i < ASSET_NXA_USB_SAVE_MISSION_MAX; i++) { - util_str_format(buffer, buf_size, - "unkn_some_map_scores_to_song_ids: %s\n", - tmp2); - - tmp = util_str_merge(merged, buffer); - - free(tmp2); - free(merged); - merged = tmp; - - /* ------------- */ - tmp2 = util_str_buffer(stats->unkn2, sizeof(stats->unkn2)); - - util_str_format(buffer, buf_size, - "unkn2: %s\n", - tmp2); - - tmp = util_str_merge(merged, buffer); - - free(tmp2); - free(merged); - merged = tmp; - - /* ------------- */ - util_str_format(buffer, buf_size, - "break_item_slot 0x%X\n" - "func_item_slot: 0x%X\n" - "bga_item_slot: 0x%X\n" - "time_item_slot: 0x%X\n" - "unknown: 0x%X\n", - stats->break_item_slot, - stats->func_item_slot, - stats->bga_item_slot, - stats->time_item_slot, - stats->unknown); + util_str_format( + buffer, + buf_size, + "mission slot: %d\n" + "clear_flags_directions: 0x%X\n" + "clear_flag_mission: %d\n" + "unused: 0x%X\n", + i, + stats->worldmax_mission_unlocks[i].clear_flags_directions, + stats->worldmax_mission_unlocks[i].clear_flag_mission, + stats->worldmax_mission_unlocks[i].unused); tmp = util_str_merge(merged, buffer); free(merged); merged = tmp; + } - free(buffer); + for (uint32_t i = 0; i < ASSET_NXA_USB_SAVE_MISSION_MAX; i++) { - return merged; + util_str_format( + buffer, + buf_size, + "worldmax_high_score %d: %d\n", + i, + stats->worldmax_high_score[i]); + + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; + } + + for (uint32_t i = 0; i < ASSET_NXA_USB_SAVE_MISSION_MAX; i++) { + + util_str_format( + buffer, + buf_size, + "worldmax_challenge %d: %d\n", + i, + stats->worldmax_challenge[i]); + + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; + } + + for (uint32_t i = 0; i < ASSET_NXA_USB_SAVE_BARRICADE_MAX; i++) { + + util_str_format( + buffer, + buf_size, + "worldmax_barricade %d:\n" + "flag_open: %d\n" + "unused: 0x%X\n", + i, + stats->worldmax_barricade[i].flag_open, + stats->worldmax_barricade[i].unused); + + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; + } + + for (uint32_t i = 0; i < ASSET_NXA_USB_SAVE_EVENT_MAX; i++) { + + util_str_format( + buffer, + buf_size, + "worldmax_event %d:\n" + "flag_cleared: %d\n" + "unused: 0x%X\n", + i, + stats->worldmax_event[i].flag_cleared, + stats->worldmax_event[i].unused); + + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; + } + + for (uint32_t i = 0; i < ASSET_NXA_USB_SAVE_WARP_MAX; i++) { + + util_str_format( + buffer, + buf_size, + "worldmax_warp %d:\n" + "direction_clear: 0x%X\n" + "clear: %d\n", + "unused: 0x%X\n", + i, + stats->worldmax_warp[i].direction_clear, + stats->worldmax_warp[i].clear, + stats->worldmax_warp[i].unused); + + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; + } + + for (uint32_t i = 0; i < ASSET_NXA_USB_SAVE_WORLDMAX_LOC_MAX; i++) { + + util_str_format( + buffer, + buf_size, + "worldmax_current_land %d: %d\n", + i, + stats->worldmax_current_land[i]); + + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; + } + + for (uint32_t i = 0; i < ASSET_NXA_USB_SAVE_WORLDMAX_LOC_MAX; i++) { + + util_str_format( + buffer, + buf_size, + "worldmax_current_mission %d: %d\n", + i, + stats->worldmax_current_mission[i]); + + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; + } + + for (uint32_t i = 0; i < ASSET_NXA_USB_SAVE_SONG_MAX; i++) { + + for (uint32_t j = 0; j < ASSET_NXA_USB_SAVE_NUM_MODES; j++) { + util_str_format( + buffer, + buf_size, + "song_scores %d/%d:\n" + "score: %d\n" + "player_id: %s\n", + i, + j, + stats->song_scores[i][j].score, + stats->song_scores[i][j].player_id); + + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; + } + } + + /* ------------- */ + util_str_format( + buffer, + buf_size, + "security_dongle_mfgid 0x%X\n" + "unlock_signal: 0x%X\n" + "running_steps: %d\n" + "total_play_time_min: %f\n" + "total_completion_percentage: %f\n" + "arcade_completion_percentage: %f\n" + "brain_shower_completion_percentage: %f\n" + "special_stage_completion_percentage: %f\n", + stats->security_dongle_mfgid, + stats->unlock_signal, + stats->running_steps, + stats->total_play_time_min, + stats->total_completion_percentage, + stats->arcade_completion_percentage, + stats->brain_shower_completion_percentage, + stats->special_stage_completion_percentage); + + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; + + /* ------------- */ + tmp2 = util_str_buffer(stats->unkn_some_map_scores_to_song_ids, 4096); + + util_str_format( + buffer, buf_size, "unkn_some_map_scores_to_song_ids: %s\n", tmp2); + + tmp = util_str_merge(merged, buffer); + + free(tmp2); + free(merged); + merged = tmp; + + /* ------------- */ + tmp2 = util_str_buffer(stats->unkn2, sizeof(stats->unkn2)); + + util_str_format(buffer, buf_size, "unkn2: %s\n", tmp2); + + tmp = util_str_merge(merged, buffer); + + free(tmp2); + free(merged); + merged = tmp; + + /* ------------- */ + util_str_format( + buffer, + buf_size, + "break_item_slot 0x%X\n" + "func_item_slot: 0x%X\n" + "bga_item_slot: 0x%X\n" + "time_item_slot: 0x%X\n" + "unknown: 0x%X\n", + stats->break_item_slot, + stats->func_item_slot, + stats->bga_item_slot, + stats->time_item_slot, + stats->unknown); + + tmp = util_str_merge(merged, buffer); + + free(merged); + merged = tmp; + + free(buffer); + + return merged; } -struct asset_nxa_usb_save* asset_nxa_usb_save_new(void) +struct asset_nxa_usb_save *asset_nxa_usb_save_new(void) { - struct asset_nxa_usb_save* save; - char name[10]; + struct asset_nxa_usb_save *save; + char name[10]; - save = (struct asset_nxa_usb_save*) util_xmalloc( - sizeof(struct asset_nxa_usb_save)); + save = (struct asset_nxa_usb_save *) util_xmalloc( + sizeof(struct asset_nxa_usb_save)); - memset(save, 0, sizeof(struct asset_nxa_usb_save)); + memset(save, 0, sizeof(struct asset_nxa_usb_save)); - sprintf(name, "NX%06d", rand() % 1000000); - strcpy(save->review.player_id, name); - strcpy(save->stats.player_id, name); + sprintf(name, "NX%06d", rand() % 1000000); + strcpy(save->review.player_id, name); + strcpy(save->stats.player_id, name); - /* default world map position */ - save->stats.worldmax_map_position = 0xEF001; + /* default world map position */ + save->stats.worldmax_map_position = 0xEF001; - /* nxa release date as default timestamp */ - save->stats.timestamp.year = 2008; - save->stats.timestamp.month = 12; - save->stats.timestamp.day = 26; - save->stats.timestamp.hour = 0; - save->stats.timestamp.min = 0; - save->stats.timestamp.ms = 0; + /* nxa release date as default timestamp */ + save->stats.timestamp.year = 2008; + save->stats.timestamp.month = 12; + save->stats.timestamp.day = 26; + save->stats.timestamp.hour = 0; + save->stats.timestamp.min = 0; + save->stats.timestamp.ms = 0; - return save; + return save; } -void asset_nxa_usb_save_finalize(struct asset_nxa_usb_save* save) +void asset_nxa_usb_save_finalize(struct asset_nxa_usb_save *save) { - /* checksum update, expected size for area to checksum: 90540 */ - save->stats.adler32 = util_adler32_calc(1, - ((const uint8_t*) &save->stats) + 4, - sizeof(struct asset_nxa_usb_save_stats) - 4); + /* checksum update, expected size for area to checksum: 90540 */ + save->stats.adler32 = util_adler32_calc( + 1, + ((const uint8_t *) &save->stats) + 4, + sizeof(struct asset_nxa_usb_save_stats) - 4); } -char* asset_nxa_usb_save_to_string(const struct asset_nxa_usb_save* save) +char *asset_nxa_usb_save_to_string(const struct asset_nxa_usb_save *save) { - char* review; - char* stats; - char* merged; + char *review; + char *stats; + char *merged; - review = asset_nxa_usb_save_review_to_string(&save->review); - stats = asset_nxa_usb_save_stats_to_string(&save->stats); + review = asset_nxa_usb_save_review_to_string(&save->review); + stats = asset_nxa_usb_save_stats_to_string(&save->stats); - merged = util_str_merge(review, stats); + merged = util_str_merge(review, stats); - free(review); - free(stats); + free(review); + free(stats); - return merged; + return merged; } -void asset_nxa_usb_save_decrypt(uint8_t* buf, size_t len) +void asset_nxa_usb_save_decrypt(uint8_t *buf, size_t len) { - /* skip non encrypted review area */ - buf += sizeof(struct asset_nxa_usb_save_review); - len -= sizeof(struct asset_nxa_usb_save_review); + /* skip non encrypted review area */ + buf += sizeof(struct asset_nxa_usb_save_review); + len -= sizeof(struct asset_nxa_usb_save_review); - for (size_t a = len - 1; a > 0; --a) { - buf[a] = (buf[a] ^ buf[a - 1]) + ((a * 1234567) >> 8); - } + for (size_t a = len - 1; a > 0; --a) { + buf[a] = (buf[a] ^ buf[a - 1]) + ((a * 1234567) >> 8); + } } -void asset_nxa_usb_save_encrypt(uint8_t* buf, size_t len) +void asset_nxa_usb_save_encrypt(uint8_t *buf, size_t len) { - /* skip non encrypted review area */ - buf += sizeof(struct asset_nxa_usb_save_review); - len -= sizeof(struct asset_nxa_usb_save_review); + /* skip non encrypted review area */ + buf += sizeof(struct asset_nxa_usb_save_review); + len -= sizeof(struct asset_nxa_usb_save_review); - for (size_t a = 1; a < len; ++a) { - buf[a] = (buf[a] - ((a * 1234567) >> 8)) ^ buf[a - 1]; - } + for (size_t a = 1; a < len; ++a) { + buf[a] = (buf[a] - ((a * 1234567) >> 8)) ^ buf[a - 1]; + } } \ No newline at end of file diff --git a/src/main/asset/nxa/lib/usb-save.h b/src/main/asset/nxa/lib/usb-save.h index 6b04118..aaeb550 100644 --- a/src/main/asset/nxa/lib/usb-save.h +++ b/src/main/asset/nxa/lib/usb-save.h @@ -5,271 +5,272 @@ #include enum asset_nxa_usb_save_limits { - ASSET_NXA_USB_SAVE_SERIAL_ID_MAX = 64, - ASSET_NXA_USB_SAVE_PLAYER_ID_MAX = 12, - ASSET_NXA_USB_SAVE_WORLDMAX_LOC_MAX = 128, - ASSET_NXA_USB_SAVE_SONG_MAX = 256, - ASSET_NXA_USB_SAVE_MISSION_MAX = 1024, - ASSET_NXA_USB_SAVE_BARRICADE_MAX = 16, - ASSET_NXA_USB_SAVE_EVENT_MAX = 128, - ASSET_NXA_USB_SAVE_WARP_MAX = 8, - ASSET_NXA_USB_SAVE_NUM_MODES = 5, + ASSET_NXA_USB_SAVE_SERIAL_ID_MAX = 64, + ASSET_NXA_USB_SAVE_PLAYER_ID_MAX = 12, + ASSET_NXA_USB_SAVE_WORLDMAX_LOC_MAX = 128, + ASSET_NXA_USB_SAVE_SONG_MAX = 256, + ASSET_NXA_USB_SAVE_MISSION_MAX = 1024, + ASSET_NXA_USB_SAVE_BARRICADE_MAX = 16, + ASSET_NXA_USB_SAVE_EVENT_MAX = 128, + ASSET_NXA_USB_SAVE_WARP_MAX = 8, + ASSET_NXA_USB_SAVE_NUM_MODES = 5, }; struct asset_nxa_usb_save_time { - int16_t year; - uint8_t month; - uint8_t day; - uint8_t hour; - uint8_t min; - uint16_t ms; + int16_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t min; + uint16_t ms; } __attribute__((__packed__)); /* Not encrypted and read only, offset 0x00 to 0x144 (excl) */ struct asset_nxa_usb_save_review { - /* 0x00, 12 byte char array: max char length is 8 which gets displayed - ingame */ - char player_id[ASSET_NXA_USB_SAVE_PLAYER_ID_MAX]; - /* 0x0C, 4 byte int */ - uint32_t mileage; - /* 0x10, 4 byte int: achieved reward count, max 65 */ - uint32_t reward_count; - /* 0x14, 4 byte int: successful mission count, max 634 */ - uint32_t worldmax_count; - /* 0x18, 4 byte int */ - uint32_t play_count; - /* 0x1C, 128 byte char array */ - char worldmax_current_land[ASSET_NXA_USB_SAVE_WORLDMAX_LOC_MAX]; - /* 0x9C, 128 byte char array */ - char worldmax_current_mission[ASSET_NXA_USB_SAVE_WORLDMAX_LOC_MAX]; - /* 0x11C, 4 byte int */ - uint32_t kcal; - /* 0x120, 4 byte int */ - uint32_t v02; - /* 0x124, 8 byte */ - struct asset_nxa_usb_save_time timestamp; - /* 0x12C, 4 byte int */ - uint32_t running_step; - /* 0x130, 4 byte float */ - float play_time_minutes; - /* 0x134, 4 byte float */ - float total_completion_percentage; - /* 0x138, 4 byte float */ - float arcade_percentage; - /* 0x13C, 4 byte float */ - float brain_shower_percentage; - /* 0x140, 4 byte float */ - float special_percentage; + /* 0x00, 12 byte char array: max char length is 8 which gets displayed + ingame */ + char player_id[ASSET_NXA_USB_SAVE_PLAYER_ID_MAX]; + /* 0x0C, 4 byte int */ + uint32_t mileage; + /* 0x10, 4 byte int: achieved reward count, max 65 */ + uint32_t reward_count; + /* 0x14, 4 byte int: successful mission count, max 634 */ + uint32_t worldmax_count; + /* 0x18, 4 byte int */ + uint32_t play_count; + /* 0x1C, 128 byte char array */ + char worldmax_current_land[ASSET_NXA_USB_SAVE_WORLDMAX_LOC_MAX]; + /* 0x9C, 128 byte char array */ + char worldmax_current_mission[ASSET_NXA_USB_SAVE_WORLDMAX_LOC_MAX]; + /* 0x11C, 4 byte int */ + uint32_t kcal; + /* 0x120, 4 byte int */ + uint32_t v02; + /* 0x124, 8 byte */ + struct asset_nxa_usb_save_time timestamp; + /* 0x12C, 4 byte int */ + uint32_t running_step; + /* 0x130, 4 byte float */ + float play_time_minutes; + /* 0x134, 4 byte float */ + float total_completion_percentage; + /* 0x138, 4 byte float */ + float arcade_percentage; + /* 0x13C, 4 byte float */ + float brain_shower_percentage; + /* 0x140, 4 byte float */ + float special_percentage; } __attribute__((__packed__)); struct asset_nxa_usb_save_stats { - /* 0x144, 4 byte int */ - uint32_t adler32; - /* 0x148, 64 byte */ - char usb_serial[ASSET_NXA_USB_SAVE_SERIAL_ID_MAX]; - /* 0x188, 8 byte */ - struct asset_nxa_usb_save_time timestamp; - /* 0x190, 4 byte int */ - int32_t avatar_id; - /* 0x194, 4 byte int: setting this non null will give you a trophy */ - int32_t rank; - /* 0x198, 4 byte int: seems unused */ - int32_t country_id; - /* 0x19C, 12 byte char array */ - char player_id[ASSET_NXA_USB_SAVE_PLAYER_ID_MAX]; - /* 0x1A8, 4 byte int */ - int32_t mileage; - /* 0x1AD, 4 byte int */ - int32_t play_count; - /* 0x1B0, 4 byte int */ - int32_t kcal; - /* 0x1B4, 4 byte int */ - int32_t v02; - /* 0x1B8, 4 byte int */ - int32_t worldmax_map_position; - /* 0x1BC, 4 byte int: achieved reward count, max 65 */ - int32_t reward_count; - /* 0x1C0, 4 byte int: successful mission count, max 634 */ - int32_t worldmax_count; + /* 0x144, 4 byte int */ + uint32_t adler32; + /* 0x148, 64 byte */ + char usb_serial[ASSET_NXA_USB_SAVE_SERIAL_ID_MAX]; + /* 0x188, 8 byte */ + struct asset_nxa_usb_save_time timestamp; + /* 0x190, 4 byte int */ + int32_t avatar_id; + /* 0x194, 4 byte int: setting this non null will give you a trophy */ + int32_t rank; + /* 0x198, 4 byte int: seems unused */ + int32_t country_id; + /* 0x19C, 12 byte char array */ + char player_id[ASSET_NXA_USB_SAVE_PLAYER_ID_MAX]; + /* 0x1A8, 4 byte int */ + int32_t mileage; + /* 0x1AD, 4 byte int */ + int32_t play_count; + /* 0x1B0, 4 byte int */ + int32_t kcal; + /* 0x1B4, 4 byte int */ + int32_t v02; + /* 0x1B8, 4 byte int */ + int32_t worldmax_map_position; + /* 0x1BC, 4 byte int: achieved reward count, max 65 */ + int32_t reward_count; + /* 0x1C0, 4 byte int: successful mission count, max 634 */ + int32_t worldmax_count; - /* 0x1C4, 256 bytes */ - struct { - /* bits 0-4 for modes/stepcharts */ - uint8_t mode : 5; - /* unused bit */ - uint8_t unused : 1; - /* bit 6 song itself */ - uint8_t song : 1; - /* bit 7 reveal flag */ - uint8_t reveal : 1; - } song_unlocks[ASSET_NXA_USB_SAVE_SONG_MAX] __attribute__((__packed__)); + /* 0x1C4, 256 bytes */ + struct { + /* bits 0-4 for modes/stepcharts */ + uint8_t mode : 5; + /* unused bit */ + uint8_t unused : 1; + /* bit 6 song itself */ + uint8_t song : 1; + /* bit 7 reveal flag */ + uint8_t reveal : 1; + } song_unlocks[ASSET_NXA_USB_SAVE_SONG_MAX] __attribute__((__packed__)); - /* 0x2C4, 1024 bytes */ - struct { - uint8_t clear_flags_directions : 4; - uint8_t clear_flag_mission : 1; - uint8_t unused : 3; - } worldmax_mission_unlocks[ASSET_NXA_USB_SAVE_MISSION_MAX] - __attribute__((__packed__)); + /* 0x2C4, 1024 bytes */ + struct { + uint8_t clear_flags_directions : 4; + uint8_t clear_flag_mission : 1; + uint8_t unused : 3; + } worldmax_mission_unlocks[ASSET_NXA_USB_SAVE_MISSION_MAX] + __attribute__((__packed__)); - /* 0x6C4, 4 byte int * 1024: high score for each mission */ - int32_t worldmax_high_score[ASSET_NXA_USB_SAVE_MISSION_MAX]; + /* 0x6C4, 4 byte int * 1024: high score for each mission */ + int32_t worldmax_high_score[ASSET_NXA_USB_SAVE_MISSION_MAX]; - /* 0x16C4, 4 byte int * 1024 */ - int32_t worldmax_challenge[ASSET_NXA_USB_SAVE_MISSION_MAX]; + /* 0x16C4, 4 byte int * 1024 */ + int32_t worldmax_challenge[ASSET_NXA_USB_SAVE_MISSION_MAX]; - /* 0x26C4, 16 bytes - 0x00 for barricade clear and 0x01 for block */ - struct { - uint8_t flag_open : 1; - uint8_t unused : 7; - } worldmax_barricade[ASSET_NXA_USB_SAVE_BARRICADE_MAX] - __attribute__((__packed__)); + /* 0x26C4, 16 bytes + 0x00 for barricade clear and 0x01 for block */ + struct { + uint8_t flag_open : 1; + uint8_t unused : 7; + } worldmax_barricade[ASSET_NXA_USB_SAVE_BARRICADE_MAX] + __attribute__((__packed__)); - /* 0x26D4, 128 bytes - 0x00 for event clear and 0x01 for not cleared */ - struct { - uint8_t flag_cleared : 1; - uint8_t unused : 7; - } worldmax_event[ASSET_NXA_USB_SAVE_EVENT_MAX] __attribute__((__packed__)); + /* 0x26D4, 128 bytes + 0x00 for event clear and 0x01 for not cleared */ + struct { + uint8_t flag_cleared : 1; + uint8_t unused : 7; + } worldmax_event[ASSET_NXA_USB_SAVE_EVENT_MAX] __attribute__((__packed__)); - /* 0x2754, 8 bytes - bit 0~3: clear bit for each direction bit:4 clear */ - struct { - uint8_t direction_clear : 4; - uint8_t clear : 1; - uint8_t unused : 3; - } worldmax_warp[ASSET_NXA_USB_SAVE_WARP_MAX] __attribute__((__packed__)); + /* 0x2754, 8 bytes + bit 0~3: clear bit for each direction bit:4 clear */ + struct { + uint8_t direction_clear : 4; + uint8_t clear : 1; + uint8_t unused : 3; + } worldmax_warp[ASSET_NXA_USB_SAVE_WARP_MAX] __attribute__((__packed__)); - /* 0x275C, 128 byte char array */ - char worldmax_current_land[ASSET_NXA_USB_SAVE_WORLDMAX_LOC_MAX]; + /* 0x275C, 128 byte char array */ + char worldmax_current_land[ASSET_NXA_USB_SAVE_WORLDMAX_LOC_MAX]; - /* 0x27DC, 128 byte char array */ - char worldmax_current_mission[ASSET_NXA_USB_SAVE_WORLDMAX_LOC_MAX]; + /* 0x27DC, 128 byte char array */ + char worldmax_current_mission[ASSET_NXA_USB_SAVE_WORLDMAX_LOC_MAX]; - /* 0x285C */ - struct { - int32_t score; - char player_id[ASSET_NXA_USB_SAVE_PLAYER_ID_MAX]; - } song_scores[ASSET_NXA_USB_SAVE_SONG_MAX][ASSET_NXA_USB_SAVE_NUM_MODES] - __attribute__((__packed__)); + /* 0x285C */ + struct { + int32_t score; + char player_id[ASSET_NXA_USB_SAVE_PLAYER_ID_MAX]; + } song_scores[ASSET_NXA_USB_SAVE_SONG_MAX][ASSET_NXA_USB_SAVE_NUM_MODES] + __attribute__((__packed__)); - /* 0x785C, 4 byte int */ - uint32_t security_dongle_mfgid; + /* 0x785C, 4 byte int */ + uint32_t security_dongle_mfgid; - /* 0x7860, 4 byte int: <=3 Tells game to unlock new song */ - uint32_t unlock_signal; + /* 0x7860, 4 byte int: <=3 Tells game to unlock new song */ + uint32_t unlock_signal; - /* 0x7864, 4 byte int */ - uint32_t running_steps; + /* 0x7864, 4 byte int */ + uint32_t running_steps; - /* 0x7868, 4 byte float */ - float total_play_time_min; + /* 0x7868, 4 byte float */ + float total_play_time_min; - /* 0x786C, 4 byte float */ - float total_completion_percentage; + /* 0x786C, 4 byte float */ + float total_completion_percentage; - /* 0x7870, 4 byte float */ - float arcade_completion_percentage; + /* 0x7870, 4 byte float */ + float arcade_completion_percentage; - /* 0x7874, 4 byte float */ - float brain_shower_completion_percentage; + /* 0x7874, 4 byte float */ + float brain_shower_completion_percentage; - /* 0x7878, 4 byte float */ - float special_stage_completion_percentage; + /* 0x7878, 4 byte float */ + float special_stage_completion_percentage; - /* 0x787C TODO unknown - 0x787C, 1 byte char * 4096 - Used by GetSongIndex - - Assuming Maps Scores to Song IDs */ - uint8_t unkn_some_map_scores_to_song_ids[4096]; + /* 0x787C TODO unknown + 0x787C, 1 byte char * 4096 - Used by GetSongIndex - + Assuming Maps Scores to Song IDs */ + uint8_t unkn_some_map_scores_to_song_ids[4096]; - /* 0x887C TODO unknown - 0x887C, 1 byte char * 576 - Song Locks/Unlocks - 0x40 Unlocks (Special Zone, etc.) - 0x8A70 , 1 byte char * 36 - WorldMax Keys and various other events for completion - 0x8A9C, 8 byte char* - A Worldmax ID (Perhaps one to mark progress in Space) - 0x8AA4, 1 byte char * 24 - More WorldMax Event Switches */ - uint8_t unkn2[576]; + /* 0x887C TODO unknown + 0x887C, 1 byte char * 576 - Song Locks/Unlocks - 0x40 Unlocks (Special + Zone, etc.) 0x8A70 , 1 byte char * 36 - WorldMax Keys and various other + events for completion 0x8A9C, 8 byte char* - A Worldmax ID (Perhaps one to + mark progress in Space) 0x8AA4, 1 byte char * 24 - More WorldMax Event + Switches */ + uint8_t unkn2[576]; - /* 0x8ABC, 4 byte int: possible values - 0x1 - grey - 0x2 - red - 0x3 - yellow - 0x4 - green - 0x5 - Dark Green - 0x6 - aqua - 0x7 - blue - 0x8 - purple - 0x9 - pink - 0xA - light grey - 0xB - Black - 0xC - Orange - */ - uint32_t break_item_slot; + /* 0x8ABC, 4 byte int: possible values + 0x1 - grey + 0x2 - red + 0x3 - yellow + 0x4 - green + 0x5 - Dark Green + 0x6 - aqua + 0x7 - blue + 0x8 - purple + 0x9 - pink + 0xA - light grey + 0xB - Black + 0xC - Orange + */ + uint32_t break_item_slot; - /* 0x8AC0, 4 byte int - 0x1 - Shield - 0x2 - PermaShield - 0x3 - Line Searcher - 0x4 - Perma Line Searcher - 0x5 - Life Up - 0x6 - Perma Life Up - 0x7 - Lucky - 0x8 - Perma Lucky - 0x9 - Portal Pass - */ - uint32_t func_item_slot; + /* 0x8AC0, 4 byte int + 0x1 - Shield + 0x2 - PermaShield + 0x3 - Line Searcher + 0x4 - Perma Line Searcher + 0x5 - Life Up + 0x6 - Perma Life Up + 0x7 - Lucky + 0x8 - Perma Lucky + 0x9 - Portal Pass + */ + uint32_t func_item_slot; - /* 0x8AC4, 4 byte int - 0x1 - BGA OFF - 0x2 - Perma BGA OFF - */ - uint32_t bga_item_slot; + /* 0x8AC4, 4 byte int + 0x1 - BGA OFF + 0x2 - Perma BGA OFF + */ + uint32_t bga_item_slot; - /* 0x8AC4, 4 byte int - 0x1 - 10+ - 0x2 - 20+ - 0x3 - 30+ - */ - uint32_t time_item_slot; + /* 0x8AC4, 4 byte int + 0x1 - 10+ + 0x2 - 20+ + 0x3 - 30+ + */ + uint32_t time_item_slot; - /* 0x8AC8, 4 byte int */ - uint32_t unknown; + /* 0x8AC8, 4 byte int */ + uint32_t unknown; - /* 0x8ACC, unknown stuff: More WorldMax Event Switches (Unused)? */ - uint8_t unknown2[12]; + /* 0x8ACC, unknown stuff: More WorldMax Event Switches (Unused)? */ + uint8_t unknown2[12]; - /* 0x8AD8, 4 byte float - Unknown What this Does (Unused) */ - float unknown3; + /* 0x8AD8, 4 byte float - Unknown What this Does (Unused) */ + float unknown3; - /* 0x8ADC, totally unknown stuff, just nulls */ - uint8_t unknown4[0x7F8]; + /* 0x8ADC, totally unknown stuff, just nulls */ + uint8_t unknown4[0x7F8]; - /* 0x92D4 */ - uint8_t unknown5[0xD01C]; + /* 0x92D4 */ + uint8_t unknown5[0xD01C]; - /* TODO missing switches for dark/light world stuff - 0x8ACC, 1 byte char - More WorldMax Event Switches (Unused) - 0x8AD8 , 4 byte float - Unknown What this Does (Unused) - 0x92D4, High Score Table [See Below] - 0x132D0, 5216 bytes - Unknown Table (Unused) - 0x162D0, 24 bytes - Unknown Footer (Unused by Game - Most Likely PumBI) - */ + /* TODO missing switches for dark/light world stuff + 0x8ACC, 1 byte char - More WorldMax Event Switches (Unused) + 0x8AD8 , 4 byte float - Unknown What this Does (Unused) + 0x92D4, High Score Table [See Below] + 0x132D0, 5216 bytes - Unknown Table (Unused) + 0x162D0, 24 bytes - Unknown Footer (Unused by Game - Most Likely PumBI) + */ } __attribute__((__packed__)); struct asset_nxa_usb_save { - struct asset_nxa_usb_save_review review; - struct asset_nxa_usb_save_stats stats; + struct asset_nxa_usb_save_review review; + struct asset_nxa_usb_save_stats stats; } __attribute__((__packed__)); -struct asset_nxa_usb_save* asset_nxa_usb_save_new(void); +struct asset_nxa_usb_save *asset_nxa_usb_save_new(void); /* update checksum and prepare profile to get encrypted */ -void asset_nxa_usb_save_finalize(struct asset_nxa_usb_save* save); +void asset_nxa_usb_save_finalize(struct asset_nxa_usb_save *save); -char* asset_nxa_usb_save_to_string(const struct asset_nxa_usb_save* save); +char *asset_nxa_usb_save_to_string(const struct asset_nxa_usb_save *save); -void asset_nxa_usb_save_decrypt(uint8_t* buf, size_t len); +void asset_nxa_usb_save_decrypt(uint8_t *buf, size_t len); -void asset_nxa_usb_save_encrypt(uint8_t* buf, size_t len); +void asset_nxa_usb_save_encrypt(uint8_t *buf, size_t len); #endif \ No newline at end of file diff --git a/src/main/asset/nxa/lib/util.c b/src/main/asset/nxa/lib/util.c index 0f1c485..63b4723 100644 --- a/src/main/asset/nxa/lib/util.c +++ b/src/main/asset/nxa/lib/util.c @@ -7,94 +7,100 @@ #include "util.h" -struct asset_nxa_usb_rank* asset_nxa_usb_rank_load_from_file(const char* path, - bool encrypted) +struct asset_nxa_usb_rank * +asset_nxa_usb_rank_load_from_file(const char *path, bool encrypted) { - struct asset_nxa_usb_rank* rank; - size_t size; + struct asset_nxa_usb_rank *rank; + size_t size; - if (!util_file_load(path, (void**) &rank, &size, false)) { - log_error("Loading nxa rank file %s failed", path); - return NULL; - } + if (!util_file_load(path, (void **) &rank, &size, false)) { + log_error("Loading nxa rank file %s failed", path); + return NULL; + } - if (size != sizeof(struct asset_nxa_usb_rank)) { - log_error("Invalid size of nxa rank file %s: %d != %d", path, size, - sizeof(struct asset_nxa_usb_rank)); - free(rank); - return NULL; - } + if (size != sizeof(struct asset_nxa_usb_rank)) { + log_error( + "Invalid size of nxa rank file %s: %d != %d", + path, + size, + sizeof(struct asset_nxa_usb_rank)); + free(rank); + return NULL; + } - if (encrypted) { - asset_nxa_usb_rank_decrypt((uint8_t*) rank, size); - } + if (encrypted) { + asset_nxa_usb_rank_decrypt((uint8_t *) rank, size); + } - return rank; + return rank; } -bool asset_nxa_usb_rank_save_to_file(const char* path, - const struct asset_nxa_usb_rank* rank, bool encrypt) +bool asset_nxa_usb_rank_save_to_file( + const char *path, const struct asset_nxa_usb_rank *rank, bool encrypt) { - struct asset_nxa_usb_rank rank_enc; + struct asset_nxa_usb_rank rank_enc; - memcpy(&rank_enc, rank, sizeof(struct asset_nxa_usb_rank)); + memcpy(&rank_enc, rank, sizeof(struct asset_nxa_usb_rank)); - if (encrypt) { - asset_nxa_usb_rank_encrypt((uint8_t*) &rank_enc, - sizeof(struct asset_nxa_usb_rank)); - } + if (encrypt) { + asset_nxa_usb_rank_encrypt( + (uint8_t *) &rank_enc, sizeof(struct asset_nxa_usb_rank)); + } - if (!util_file_save(path, (void**) &rank_enc, - sizeof(struct asset_nxa_usb_rank))) { - log_error("Storing nxa rank data to %s failed", path); - return false; - } + if (!util_file_save( + path, (void **) &rank_enc, sizeof(struct asset_nxa_usb_rank))) { + log_error("Storing nxa rank data to %s failed", path); + return false; + } - return true; + return true; } -struct asset_nxa_usb_save* asset_nxa_usb_save_load_from_file(const char* path, - bool encrypted) +struct asset_nxa_usb_save * +asset_nxa_usb_save_load_from_file(const char *path, bool encrypted) { - struct asset_nxa_usb_save* save; - size_t size; + struct asset_nxa_usb_save *save; + size_t size; - if (!util_file_load(path, (void**) &save, &size, false)) { - log_error("Loading nxa save file %s failed", path); - return NULL; - } + if (!util_file_load(path, (void **) &save, &size, false)) { + log_error("Loading nxa save file %s failed", path); + return NULL; + } - if (size != sizeof(struct asset_nxa_usb_save)) { - log_error("Invalid size of nxa save file %s: %d != %d", path, size, - sizeof(struct asset_nxa_usb_save)); - free(save); - return NULL; - } + if (size != sizeof(struct asset_nxa_usb_save)) { + log_error( + "Invalid size of nxa save file %s: %d != %d", + path, + size, + sizeof(struct asset_nxa_usb_save)); + free(save); + return NULL; + } - if (encrypted) { - asset_nxa_usb_save_decrypt((uint8_t*) save, size); - } + if (encrypted) { + asset_nxa_usb_save_decrypt((uint8_t *) save, size); + } - return save; + return save; } -bool asset_nxa_usb_save_save_to_file(const char* path, - const struct asset_nxa_usb_save* save, bool encrypt) +bool asset_nxa_usb_save_save_to_file( + const char *path, const struct asset_nxa_usb_save *save, bool encrypt) { - struct asset_nxa_usb_save save_enc; + struct asset_nxa_usb_save save_enc; - memcpy(&save_enc, save, sizeof(struct asset_nxa_usb_save)); + memcpy(&save_enc, save, sizeof(struct asset_nxa_usb_save)); - if (encrypt) { - asset_nxa_usb_save_encrypt((uint8_t*) &save_enc, - sizeof(struct asset_nxa_usb_save)); - } + if (encrypt) { + asset_nxa_usb_save_encrypt( + (uint8_t *) &save_enc, sizeof(struct asset_nxa_usb_save)); + } - if (!util_file_save(path, (const void*) &save_enc, - sizeof(struct asset_nxa_usb_save))) { - log_error("Storing nxa save data to %s failed", path); - return false; - } + if (!util_file_save( + path, (const void *) &save_enc, sizeof(struct asset_nxa_usb_save))) { + log_error("Storing nxa save data to %s failed", path); + return false; + } - return true; + return true; } \ No newline at end of file diff --git a/src/main/asset/nxa/lib/util.h b/src/main/asset/nxa/lib/util.h index 15ccd9c..6c3693d 100644 --- a/src/main/asset/nxa/lib/util.h +++ b/src/main/asset/nxa/lib/util.h @@ -7,15 +7,19 @@ #include "usb-save.h" // load from file and decrypt, returns decrypted struct -struct asset_nxa_usb_rank* asset_nxa_usb_rank_load_from_file(const char* path, bool encrypted); +struct asset_nxa_usb_rank * +asset_nxa_usb_rank_load_from_file(const char *path, bool encrypted); // takes decrypted rank data, encrypts it and writes it to file -bool asset_nxa_usb_rank_save_to_file(const char* path, const struct asset_nxa_usb_rank* rank, bool encrypt); +bool asset_nxa_usb_rank_save_to_file( + const char *path, const struct asset_nxa_usb_rank *rank, bool encrypt); // load from file and decrypt, returns decrypted struct -struct asset_nxa_usb_save* asset_nxa_usb_save_load_from_file(const char* path, bool encrypted); +struct asset_nxa_usb_save * +asset_nxa_usb_save_load_from_file(const char *path, bool encrypted); // takes decrypted save data, encrypts it and writes it to file -bool asset_nxa_usb_save_save_to_file(const char* path, const struct asset_nxa_usb_save* save, bool encrypt); +bool asset_nxa_usb_save_save_to_file( + const char *path, const struct asset_nxa_usb_save *save, bool encrypt); #endif \ No newline at end of file diff --git a/src/main/asset/nxa/tool/usb-profile.c b/src/main/asset/nxa/tool/usb-profile.c index 0cf75ae..3bde7c6 100644 --- a/src/main/asset/nxa/tool/usb-profile.c +++ b/src/main/asset/nxa/tool/usb-profile.c @@ -9,146 +9,150 @@ #include "util/str.h" -int main(int argc, char** argv) +int main(int argc, char **argv) { - int ret; - char* rank_path; - char* save_path; + int ret; + char *rank_path; + char *save_path; - if (argc < 3) { - printf("Usage: %s [cmd: new, dec, enc, dump] " - "[path containing nxarank.bin nxasave.bin]\n", argv[0]); - return -1; + if (argc < 3) { + printf( + "Usage: %s [cmd: new, dec, enc, dump] " + "[path containing nxarank.bin nxasave.bin]\n", + argv[0]); + return -1; + } + + ret = 0; + + rank_path = util_str_merge(argv[2], "nxarank.bin"); + save_path = util_str_merge(argv[2], "nxasave.bin"); + + if (!strcmp(argv[1], "new")) { + struct asset_nxa_usb_rank *rank = asset_nxa_usb_rank_new(); + struct asset_nxa_usb_save *save = asset_nxa_usb_save_new(); + + asset_nxa_usb_rank_finalize(rank); + asset_nxa_usb_save_finalize(save); + + if (!asset_nxa_usb_rank_save_to_file(rank_path, rank, true)) { + fprintf(stderr, "Creating rank file %s failed\n", rank_path); + ret = -2; } - ret = 0; + if (!asset_nxa_usb_save_save_to_file(save_path, save, true)) { + fprintf(stderr, "Creating save file %s failed\n", save_path); + ret = -3; + } - rank_path = util_str_merge(argv[2], "nxarank.bin"); - save_path = util_str_merge(argv[2], "nxasave.bin"); + free(rank); + free(save); + } else { + struct asset_nxa_usb_rank *rank; + struct asset_nxa_usb_save *save; + bool encrypted; - if (!strcmp(argv[1], "new")) { - struct asset_nxa_usb_rank* rank = asset_nxa_usb_rank_new(); - struct asset_nxa_usb_save* save = asset_nxa_usb_save_new(); + if (!strcmp(argv[1], "enc")) { + char *tmp; - asset_nxa_usb_rank_finalize(rank); - asset_nxa_usb_save_finalize(save); + encrypted = false; - if (!asset_nxa_usb_rank_save_to_file(rank_path, rank, true)) { - fprintf(stderr, "Creating rank file %s failed\n", rank_path); - ret = -2; - } + tmp = util_str_merge(rank_path, ".dec"); + free(rank_path); + rank_path = tmp; - if (!asset_nxa_usb_save_save_to_file(save_path, save, true)) { - fprintf(stderr, "Creating save file %s failed\n", save_path); - ret = -3; - } - - free(rank); - free(save); + tmp = util_str_merge(save_path, ".dec"); + free(save_path); + save_path = tmp; } else { - struct asset_nxa_usb_rank* rank; - struct asset_nxa_usb_save* save; - bool encrypted; - - if (!strcmp(argv[1], "enc")) { - char* tmp; - - encrypted = false; - - tmp = util_str_merge(rank_path, ".dec"); - free(rank_path); - rank_path = tmp; - - tmp = util_str_merge(save_path, ".dec"); - free(save_path); - save_path = tmp; - } else { - encrypted = true; - } - - rank = asset_nxa_usb_rank_load_from_file(rank_path, encrypted); - save = asset_nxa_usb_save_load_from_file(save_path, encrypted); - - if (!rank) { - fprintf(stderr, "Loading %s failed", rank_path); - ret = -4; - goto cleanup; - } - - if (!save) { - fprintf(stderr, "Loading %s failed", save_path); - ret = -5; - free(rank); - goto cleanup; - } - - if (!strcmp(argv[1], "dec")) { - char* rank_path_dec; - char* save_path_dec; - - rank_path_dec = util_str_merge(rank_path, ".dec"); - save_path_dec = util_str_merge(save_path, ".dec"); - - if (!asset_nxa_usb_rank_save_to_file(rank_path_dec, rank, false)) { - fprintf(stderr, "Saving decrypted rank file to %s failed\n", - rank_path_dec); - ret = -6; - } - - if (!asset_nxa_usb_save_save_to_file(save_path_dec, save, false)) { - fprintf(stderr, "Saving decrypted save file to %s failed\n", - save_path_dec); - ret = -7; - } - - free(rank_path_dec); - free(save_path_dec); - } else if (!strcmp(argv[1], "enc")) { - char* rank_path_enc; - char* save_path_enc; - - rank_path_enc = util_str_merge(rank_path, ".enc"); - save_path_enc = util_str_merge(save_path, ".enc"); - - if (!asset_nxa_usb_rank_save_to_file(rank_path_enc, rank, true)) { - fprintf(stderr, "Saving encrypted rank file to %s failed\n", - rank_path_enc); - ret = -6; - } - - if (!asset_nxa_usb_save_save_to_file(save_path_enc, save, true)) { - fprintf(stderr, "Saving encrypted save file to %s failed\n", - save_path_enc); - ret = -7; - } - - free(rank_path_enc); - free(save_path_enc); - } else if (!strcmp(argv[1], "dump")) { - char* rank_str; - char* save_str; - - rank_str = asset_nxa_usb_rank_to_string(rank); - save_str = asset_nxa_usb_save_to_string(save); - - printf("----------------- rank -----------------\n" - "%s----------------- save -----------------\n%s", - rank_str, save_str); - - free(rank_str); - free(save_str); - } else { - fprintf(stderr, "Unknown command %s\n", argv[1]); - ret = -4; - } - - free(rank); - free(save); + encrypted = true; } + rank = asset_nxa_usb_rank_load_from_file(rank_path, encrypted); + save = asset_nxa_usb_save_load_from_file(save_path, encrypted); + + if (!rank) { + fprintf(stderr, "Loading %s failed", rank_path); + ret = -4; + goto cleanup; + } + + if (!save) { + fprintf(stderr, "Loading %s failed", save_path); + ret = -5; + free(rank); + goto cleanup; + } + + if (!strcmp(argv[1], "dec")) { + char *rank_path_dec; + char *save_path_dec; + + rank_path_dec = util_str_merge(rank_path, ".dec"); + save_path_dec = util_str_merge(save_path, ".dec"); + + if (!asset_nxa_usb_rank_save_to_file(rank_path_dec, rank, false)) { + fprintf( + stderr, "Saving decrypted rank file to %s failed\n", rank_path_dec); + ret = -6; + } + + if (!asset_nxa_usb_save_save_to_file(save_path_dec, save, false)) { + fprintf( + stderr, "Saving decrypted save file to %s failed\n", save_path_dec); + ret = -7; + } + + free(rank_path_dec); + free(save_path_dec); + } else if (!strcmp(argv[1], "enc")) { + char *rank_path_enc; + char *save_path_enc; + + rank_path_enc = util_str_merge(rank_path, ".enc"); + save_path_enc = util_str_merge(save_path, ".enc"); + + if (!asset_nxa_usb_rank_save_to_file(rank_path_enc, rank, true)) { + fprintf( + stderr, "Saving encrypted rank file to %s failed\n", rank_path_enc); + ret = -6; + } + + if (!asset_nxa_usb_save_save_to_file(save_path_enc, save, true)) { + fprintf( + stderr, "Saving encrypted save file to %s failed\n", save_path_enc); + ret = -7; + } + + free(rank_path_enc); + free(save_path_enc); + } else if (!strcmp(argv[1], "dump")) { + char *rank_str; + char *save_str; + + rank_str = asset_nxa_usb_rank_to_string(rank); + save_str = asset_nxa_usb_save_to_string(save); + + printf( + "----------------- rank -----------------\n" + "%s----------------- save -----------------\n%s", + rank_str, + save_str); + + free(rank_str); + free(save_str); + } else { + fprintf(stderr, "Unknown command %s\n", argv[1]); + ret = -4; + } + + free(rank); + free(save); + } + cleanup: - free(rank_path); - free(save_path); + free(rank_path); + free(save_path); - return ret; + return ret; } \ No newline at end of file diff --git a/src/main/asset/x2/lib/settings.c b/src/main/asset/x2/lib/settings.c index 978b919..144eea7 100644 --- a/src/main/asset/x2/lib/settings.c +++ b/src/main/asset/x2/lib/settings.c @@ -5,83 +5,71 @@ #include "util/adler32.h" #include "util/mem.h" -static const char* _asset_x2_settings_defaut_high_score_names[] = { - "MKII", - "YAHP", - "KANN", - "ZINY", - "PIAH", - "AHN ", - "PIYO", - "HIKO", - "HALO", - "BAJI", - "YUTE", - "SS ", - "SIHO", - "AZKI", - "JUNE", - "GOON", - "ARI*", - "TAMA", - "YSMA", - "PIU " -}; +static const char *_asset_x2_settings_defaut_high_score_names[] = { + "MKII", "YAHP", "KANN", "ZINY", "PIAH", "AHN ", "PIYO", + "HIKO", "HALO", "BAJI", "YUTE", "SS ", "SIHO", "AZKI", + "JUNE", "GOON", "ARI*", "TAMA", "YSMA", "PIU "}; -struct asset_x2_settings* asset_x2_settings_new(void) +struct asset_x2_settings *asset_x2_settings_new(void) { - struct asset_x2_settings* settings; + struct asset_x2_settings *settings; - settings = util_xmalloc(sizeof(struct asset_x2_settings)); + settings = util_xmalloc(sizeof(struct asset_x2_settings)); - memset(settings->ff_pad, 0xFF, sizeof(settings->ff_pad)); - memset(settings->unkn, 0, sizeof(settings->unkn)); - settings->unlock_canond_full = 0; - settings->total_uptime = 0; - settings->unkn69 = 0x69; - memset(settings->song_blacklist, 0, ASSET_X2_SETTINGS_MAX_SONGS); - memset(settings->unkn3, 0, sizeof(settings->unkn3)); - memcpy(settings->ident, "EX02", 4); - /* Updated using finalize */ - settings->adler32 = 0; - memset(settings->song_play_count, 0, sizeof(uint16_t) * ASSET_X2_SETTINGS_MAX_SONGS); - settings->padding = 0; + memset(settings->ff_pad, 0xFF, sizeof(settings->ff_pad)); + memset(settings->unkn, 0, sizeof(settings->unkn)); + settings->unlock_canond_full = 0; + settings->total_uptime = 0; + settings->unkn69 = 0x69; + memset(settings->song_blacklist, 0, ASSET_X2_SETTINGS_MAX_SONGS); + memset(settings->unkn3, 0, sizeof(settings->unkn3)); + memcpy(settings->ident, "EX02", 4); + /* Updated using finalize */ + settings->adler32 = 0; + memset( + settings->song_play_count, + 0, + sizeof(uint16_t) * ASSET_X2_SETTINGS_MAX_SONGS); + settings->padding = 0; - for (uint8_t i = 0; i < ASSET_X2_SETTINGS_HIGH_SCORE_COUNT; i++) { - settings->high_score_scores[i] = 10000u - (500u * i); - memcpy(&settings->high_score_names[i], &_asset_x2_settings_defaut_high_score_names[i], - ASSET_X2_SETTINGS_HIGH_SCORE_NAME_LEN); - } + for (uint8_t i = 0; i < ASSET_X2_SETTINGS_HIGH_SCORE_COUNT; i++) { + settings->high_score_scores[i] = 10000u - (500u * i); + memcpy( + &settings->high_score_names[i], + &_asset_x2_settings_defaut_high_score_names[i], + ASSET_X2_SETTINGS_HIGH_SCORE_NAME_LEN); + } - settings->coin_limit = 0; - settings->game_mode = ASSET_X2_SETTINGS_GAME_MODE_NORMAL; - settings->game_level = ASSET_X2_SETTINGS_LEVEL_NORMAL; - settings->game_stage_break = ASSET_X2_SETTINGS_STAGE_BREAK_2ND; - settings->language = ASSET_X2_SETTINGS_LANG_ENG; - settings->game_demo_sound = 1; - settings->game_show_help = 1; - settings->coin1_setting = 1; - settings->coin2_setting = 1; - settings->bookkeeping_coin1_total = 0; - settings->bookkeeping_coin2_total = 0; - settings->bookkeeping_service_total = 0; + settings->coin_limit = 0; + settings->game_mode = ASSET_X2_SETTINGS_GAME_MODE_NORMAL; + settings->game_level = ASSET_X2_SETTINGS_LEVEL_NORMAL; + settings->game_stage_break = ASSET_X2_SETTINGS_STAGE_BREAK_2ND; + settings->language = ASSET_X2_SETTINGS_LANG_ENG; + settings->game_demo_sound = 1; + settings->game_show_help = 1; + settings->coin1_setting = 1; + settings->coin2_setting = 1; + settings->bookkeeping_coin1_total = 0; + settings->bookkeeping_coin2_total = 0; + settings->bookkeeping_service_total = 0; - return settings; + return settings; } -void asset_x2_settings_finalize(struct asset_x2_settings* settings) +void asset_x2_settings_finalize(struct asset_x2_settings *settings) { - /* Seems odd, but they just checksum the game settings part...*/ - settings->adler32 = util_adler32_calc(1, (const uint8_t*) &settings->game_mode, 8); + /* Seems odd, but they just checksum the game settings part...*/ + settings->adler32 = + util_adler32_calc(1, (const uint8_t *) &settings->game_mode, 8); } -void asset_x2_settings_unlock_all(struct asset_x2_settings* settings) +void asset_x2_settings_unlock_all(struct asset_x2_settings *settings) { - settings->unlock_canond_full = 1; + settings->unlock_canond_full = 1; } -char* asset_x2_settings_to_string(const struct asset_x2_settings* settings) +char *asset_x2_settings_to_string(const struct asset_x2_settings *settings) { - // TODO - return ""; + // TODO + return ""; } \ No newline at end of file diff --git a/src/main/asset/x2/lib/settings.h b/src/main/asset/x2/lib/settings.h index 6fad54d..3c3214f 100644 --- a/src/main/asset/x2/lib/settings.h +++ b/src/main/asset/x2/lib/settings.h @@ -9,74 +9,75 @@ #define ASSET_X2_SETTINGS_HIGH_SCORE_NAME_LEN 4 enum asset_x2_settings_language { - ASSET_X2_SETTINGS_LANG_KOR = 0, - ASSET_X2_SETTINGS_LANG_ENG = 1, - ASSET_X2_SETTINGS_LANG_SP = 2, - ASSET_X2_SETTINGS_LANG_CH = 3, + ASSET_X2_SETTINGS_LANG_KOR = 0, + ASSET_X2_SETTINGS_LANG_ENG = 1, + ASSET_X2_SETTINGS_LANG_SP = 2, + ASSET_X2_SETTINGS_LANG_CH = 3, }; enum asset_x2_settings_game_mode { - ASSET_X2_SETTINGS_GAME_MODE_NORMAL = 0, - ASSET_X2_SETTINGS_GAME_MODE_EVENT = 1, + ASSET_X2_SETTINGS_GAME_MODE_NORMAL = 0, + ASSET_X2_SETTINGS_GAME_MODE_EVENT = 1, }; enum asset_x2_settings_level { - ASSET_X2_SETTINGS_LEVEL_EASY = 0, - ASSET_X2_SETTINGS_LEVEL_NORMAL = 1, - ASSET_X2_SETTINGS_LEVEL_HARD = 2, + ASSET_X2_SETTINGS_LEVEL_EASY = 0, + ASSET_X2_SETTINGS_LEVEL_NORMAL = 1, + ASSET_X2_SETTINGS_LEVEL_HARD = 2, }; enum asset_x2_settings_stage_break { - ASSET_X2_SETTINGS_STAGE_BREAK_OFF = 0, - ASSET_X2_SETTINGS_STAGE_BREAK_1ST = 1, - ASSET_X2_SETTINGS_STAGE_BREAK_2ND = 2, - ASSET_X2_SETTINGS_STAGE_BREAK_3RD = 3, - ASSET_X2_SETTINGS_STAGE_BREAK_4TH = 4, + ASSET_X2_SETTINGS_STAGE_BREAK_OFF = 0, + ASSET_X2_SETTINGS_STAGE_BREAK_1ST = 1, + ASSET_X2_SETTINGS_STAGE_BREAK_2ND = 2, + ASSET_X2_SETTINGS_STAGE_BREAK_3RD = 3, + ASSET_X2_SETTINGS_STAGE_BREAK_4TH = 4, }; struct asset_x2_settings { - /* Padding to fill up to 4k EEPROM legacy size */ - uint8_t ff_pad[0x51B]; - uint8_t unkn[10]; - uint8_t unlock_canond_full; - uint32_t total_uptime; - uint8_t unkn69; - uint8_t song_blacklist[ASSET_X2_SETTINGS_MAX_SONGS]; - uint8_t unkn3[0x75]; - /* EX02 */ - char ident[4]; - uint32_t adler32; - uint16_t song_play_count[ASSET_X2_SETTINGS_MAX_SONGS]; - uint16_t padding; - uint32_t high_score_scores[ASSET_X2_SETTINGS_HIGH_SCORE_COUNT]; - /* 20 names a 4 chars for the default high score list */ - char high_score_names[ASSET_X2_SETTINGS_HIGH_SCORE_COUNT][ASSET_X2_SETTINGS_HIGH_SCORE_NAME_LEN]; - /* 0 none */ - uint8_t coin_limit; - uint8_t game_mode; - uint8_t game_level; - uint8_t game_stage_break; - uint8_t language; - /* 0 off, 1 on */ - uint8_t game_demo_sound; - /* 0 off, 1 on */ - uint8_t game_show_help; - /* 0 freeplay */ - uint8_t coin1_setting; - /* 0 freeplay */ - uint8_t coin2_setting; - uint32_t bookkeeping_coin1_total; - uint32_t bookkeeping_coin2_total; - uint32_t bookkeeping_service_total; + /* Padding to fill up to 4k EEPROM legacy size */ + uint8_t ff_pad[0x51B]; + uint8_t unkn[10]; + uint8_t unlock_canond_full; + uint32_t total_uptime; + uint8_t unkn69; + uint8_t song_blacklist[ASSET_X2_SETTINGS_MAX_SONGS]; + uint8_t unkn3[0x75]; + /* EX02 */ + char ident[4]; + uint32_t adler32; + uint16_t song_play_count[ASSET_X2_SETTINGS_MAX_SONGS]; + uint16_t padding; + uint32_t high_score_scores[ASSET_X2_SETTINGS_HIGH_SCORE_COUNT]; + /* 20 names a 4 chars for the default high score list */ + char high_score_names[ASSET_X2_SETTINGS_HIGH_SCORE_COUNT] + [ASSET_X2_SETTINGS_HIGH_SCORE_NAME_LEN]; + /* 0 none */ + uint8_t coin_limit; + uint8_t game_mode; + uint8_t game_level; + uint8_t game_stage_break; + uint8_t language; + /* 0 off, 1 on */ + uint8_t game_demo_sound; + /* 0 off, 1 on */ + uint8_t game_show_help; + /* 0 freeplay */ + uint8_t coin1_setting; + /* 0 freeplay */ + uint8_t coin2_setting; + uint32_t bookkeeping_coin1_total; + uint32_t bookkeeping_coin2_total; + uint32_t bookkeeping_service_total; } __attribute__((__packed__)); -struct asset_x2_settings* asset_x2_settings_new(void); +struct asset_x2_settings *asset_x2_settings_new(void); // update checksum -void asset_x2_settings_finalize(struct asset_x2_settings* settings); +void asset_x2_settings_finalize(struct asset_x2_settings *settings); -void asset_x2_settings_unlock_all(struct asset_x2_settings* settings); +void asset_x2_settings_unlock_all(struct asset_x2_settings *settings); -char* asset_x2_settings_to_string(const struct asset_x2_settings* settings); +char *asset_x2_settings_to_string(const struct asset_x2_settings *settings); #endif diff --git a/src/main/asset/zero/lib/settings.c b/src/main/asset/zero/lib/settings.c index 049d4c3..4d3f0f8 100644 --- a/src/main/asset/zero/lib/settings.c +++ b/src/main/asset/zero/lib/settings.c @@ -5,58 +5,65 @@ #include "util/adler32.h" #include "util/mem.h" -struct asset_zero_settings* asset_zero_settings_new(void) +struct asset_zero_settings *asset_zero_settings_new(void) { - struct asset_zero_settings* settings; + struct asset_zero_settings *settings; - settings = util_xmalloc(sizeof(struct asset_zero_settings)); + settings = util_xmalloc(sizeof(struct asset_zero_settings)); - memset(settings->ff_pad, 0xFF, sizeof(settings->ff_pad)); - memcpy(settings->ident, "ZERO", 4); - /* Updated using finalize */ - settings->adler32 = 0; - settings->total_uptime = 0; - settings->language = ASSET_ZERO_SETTINGS_LANG_ENG; - memset(settings->song_play_count, 0, sizeof(uint32_t) * ASSET_ZERO_SETTINGS_MAX_SONGS); - settings->game_option_default_station = ASSET_ZERO_SETTINGS_STATION_EASY; - settings->game_mode = ASSET_ZERO_SETTINGS_GAME_MODE_NORMAL; - settings->game_level = ASSET_ZERO_SETTINGS_LEVEL_NORMAL; - settings->game_stage_break = ASSET_ZERO_SETTINGS_STAGE_BREAK_2ND; - settings->game_demo_sound = 1; - settings->game_show_help = 1; - settings->game_mercy_ticket = 0; - settings->game_score_per_ticket = 0; - settings->coin_limit = 0; - settings->coin1_setting = 1; - settings->coin2_setting = 1; - memset(settings->mission_unlock_flags, 0, ASSET_ZERO_SETTINGS_NUM_UNLOCK_FLAGS); - settings->unkn2 = 0x2A; - settings->unkn3 = 0; - settings->bookkeeping_coin1_total = 0; - settings->bookkeeping_coin2_total = 0; - settings->bookkeeping_service_total = 0; - settings->bookkeeping_ticket_1 = 0; - settings->bookkeeping_ticket_2 = 0; - settings->region = 0xFF; - memset(settings->censor_table, 0, ASSET_ZERO_SETTINGS_MAX_SONGS); + memset(settings->ff_pad, 0xFF, sizeof(settings->ff_pad)); + memcpy(settings->ident, "ZERO", 4); + /* Updated using finalize */ + settings->adler32 = 0; + settings->total_uptime = 0; + settings->language = ASSET_ZERO_SETTINGS_LANG_ENG; + memset( + settings->song_play_count, + 0, + sizeof(uint32_t) * ASSET_ZERO_SETTINGS_MAX_SONGS); + settings->game_option_default_station = ASSET_ZERO_SETTINGS_STATION_EASY; + settings->game_mode = ASSET_ZERO_SETTINGS_GAME_MODE_NORMAL; + settings->game_level = ASSET_ZERO_SETTINGS_LEVEL_NORMAL; + settings->game_stage_break = ASSET_ZERO_SETTINGS_STAGE_BREAK_2ND; + settings->game_demo_sound = 1; + settings->game_show_help = 1; + settings->game_mercy_ticket = 0; + settings->game_score_per_ticket = 0; + settings->coin_limit = 0; + settings->coin1_setting = 1; + settings->coin2_setting = 1; + memset( + settings->mission_unlock_flags, 0, ASSET_ZERO_SETTINGS_NUM_UNLOCK_FLAGS); + settings->unkn2 = 0x2A; + settings->unkn3 = 0; + settings->bookkeeping_coin1_total = 0; + settings->bookkeeping_coin2_total = 0; + settings->bookkeeping_service_total = 0; + settings->bookkeeping_ticket_1 = 0; + settings->bookkeeping_ticket_2 = 0; + settings->region = 0xFF; + memset(settings->censor_table, 0, ASSET_ZERO_SETTINGS_MAX_SONGS); - return settings; + return settings; } -void asset_zero_settings_finalize(struct asset_zero_settings* settings) +void asset_zero_settings_finalize(struct asset_zero_settings *settings) { - /* Seems odd, but they just checksum the game settings part...*/ - settings->adler32 = util_adler32_calc(1, (const uint8_t*) &settings->game_mode, 8); + /* Seems odd, but they just checksum the game settings part...*/ + settings->adler32 = + util_adler32_calc(1, (const uint8_t *) &settings->game_mode, 8); } -void asset_zero_settings_unlock_all(struct asset_zero_settings* settings) +void asset_zero_settings_unlock_all(struct asset_zero_settings *settings) { - /* Mark all missions cleared to unlock all missions and content locked by some missions */ - memset(settings->mission_unlock_flags, 1, ASSET_ZERO_SETTINGS_NUM_UNLOCK_FLAGS); + /* Mark all missions cleared to unlock all missions and content locked by some + * missions */ + memset( + settings->mission_unlock_flags, 1, ASSET_ZERO_SETTINGS_NUM_UNLOCK_FLAGS); } -char* asset_zero_settings_to_string(const struct asset_zero_settings* settings) +char *asset_zero_settings_to_string(const struct asset_zero_settings *settings) { - // TODO - return ""; + // TODO + return ""; } \ No newline at end of file diff --git a/src/main/asset/zero/lib/settings.h b/src/main/asset/zero/lib/settings.h index b675902..e24db7f 100644 --- a/src/main/asset/zero/lib/settings.h +++ b/src/main/asset/zero/lib/settings.h @@ -8,88 +8,88 @@ #define ASSET_ZERO_SETTINGS_NUM_UNLOCK_FLAGS 59 enum asset_zero_settings_language { - ASSET_ZERO_SETTINGS_LANG_KOR = 0, - ASSET_ZERO_SETTINGS_LANG_ENG = 1, - ASSET_ZERO_SETTINGS_LANG_SP = 2, - ASSET_ZERO_SETTINGS_LANG_CH = 3, + ASSET_ZERO_SETTINGS_LANG_KOR = 0, + ASSET_ZERO_SETTINGS_LANG_ENG = 1, + ASSET_ZERO_SETTINGS_LANG_SP = 2, + ASSET_ZERO_SETTINGS_LANG_CH = 3, }; enum asset_zero_settings_station { - ASSET_ZERO_SETTINGS_STATION_EASY = 0, - ASSET_ZERO_SETTINGS_STATION_ARCADE = 1, - ASSET_ZERO_SETTINGS_STATION_REMIX = 2, + ASSET_ZERO_SETTINGS_STATION_EASY = 0, + ASSET_ZERO_SETTINGS_STATION_ARCADE = 1, + ASSET_ZERO_SETTINGS_STATION_REMIX = 2, }; enum asset_zero_settings_game_mode { - ASSET_ZERO_SETTINGS_GAME_MODE_NORMAL = 0, - ASSET_ZERO_SETTINGS_GAME_MODE_EVENT = 1, + ASSET_ZERO_SETTINGS_GAME_MODE_NORMAL = 0, + ASSET_ZERO_SETTINGS_GAME_MODE_EVENT = 1, }; enum asset_zero_settings_level { - ASSET_ZERO_SETTINGS_LEVEL_EASY = 0, - ASSET_ZERO_SETTINGS_LEVEL_NORMAL = 1, - ASSET_ZERO_SETTINGS_LEVEL_HARD = 2, + ASSET_ZERO_SETTINGS_LEVEL_EASY = 0, + ASSET_ZERO_SETTINGS_LEVEL_NORMAL = 1, + ASSET_ZERO_SETTINGS_LEVEL_HARD = 2, }; enum asset_zero_settings_stage_break { - ASSET_ZERO_SETTINGS_STAGE_BREAK_OFF = 0, - ASSET_ZERO_SETTINGS_STAGE_BREAK_1ST = 1, - ASSET_ZERO_SETTINGS_STAGE_BREAK_2ND = 2, - ASSET_ZERO_SETTINGS_STAGE_BREAK_3RD = 3, - ASSET_ZERO_SETTINGS_STAGE_BREAK_4TH = 4, + ASSET_ZERO_SETTINGS_STAGE_BREAK_OFF = 0, + ASSET_ZERO_SETTINGS_STAGE_BREAK_1ST = 1, + ASSET_ZERO_SETTINGS_STAGE_BREAK_2ND = 2, + ASSET_ZERO_SETTINGS_STAGE_BREAK_3RD = 3, + ASSET_ZERO_SETTINGS_STAGE_BREAK_4TH = 4, }; struct asset_zero_settings { - /* Padding to fill up to 4k EEPROM legacy size */ - uint8_t ff_pad[0xBA4]; - /* ZERO */ - char ident[4]; - uint32_t adler32; - uint32_t total_uptime; - uint8_t language; - uint32_t song_play_count[ASSET_ZERO_SETTINGS_MAX_SONGS]; - uint32_t game_option_default_station; - uint8_t game_mode; - uint8_t game_level; - uint8_t game_stage_break; - /* 0 off, 1 on */ - uint8_t game_demo_sound; - /* 0 off, 1 on */ - uint8_t game_show_help; - /* 0 off, 1 on */ - uint8_t game_mercy_ticket; - /* 0 off, 1 - 6 for score */ - uint8_t game_score_per_ticket; - /* 0 none */ - uint8_t coin_limit; // 0 none - /* 0 freeplay */ - uint8_t coin1_setting; - /* 0 freeplay */ - uint8_t coin2_setting; - /* Unlock flags for missions (total of 30) */ - uint8_t mission_unlock_flags[ASSET_ZERO_SETTINGS_NUM_UNLOCK_FLAGS]; - /* Default value 0x2A */ - uint32_t unkn2; - uint32_t unkn3; - uint32_t bookkeeping_coin1_total; - uint32_t bookkeeping_coin2_total; - uint32_t bookkeeping_service_total; - uint32_t bookkeeping_ticket_1; - uint32_t bookkeeping_ticket_2; - /* FF -> not used, censoring globally disabled. unused feature though */ - uint8_t region; - /* 0 = censoring of song off */ - uint8_t censor_table[ASSET_ZERO_SETTINGS_MAX_SONGS]; + /* Padding to fill up to 4k EEPROM legacy size */ + uint8_t ff_pad[0xBA4]; + /* ZERO */ + char ident[4]; + uint32_t adler32; + uint32_t total_uptime; + uint8_t language; + uint32_t song_play_count[ASSET_ZERO_SETTINGS_MAX_SONGS]; + uint32_t game_option_default_station; + uint8_t game_mode; + uint8_t game_level; + uint8_t game_stage_break; + /* 0 off, 1 on */ + uint8_t game_demo_sound; + /* 0 off, 1 on */ + uint8_t game_show_help; + /* 0 off, 1 on */ + uint8_t game_mercy_ticket; + /* 0 off, 1 - 6 for score */ + uint8_t game_score_per_ticket; + /* 0 none */ + uint8_t coin_limit; // 0 none + /* 0 freeplay */ + uint8_t coin1_setting; + /* 0 freeplay */ + uint8_t coin2_setting; + /* Unlock flags for missions (total of 30) */ + uint8_t mission_unlock_flags[ASSET_ZERO_SETTINGS_NUM_UNLOCK_FLAGS]; + /* Default value 0x2A */ + uint32_t unkn2; + uint32_t unkn3; + uint32_t bookkeeping_coin1_total; + uint32_t bookkeeping_coin2_total; + uint32_t bookkeeping_service_total; + uint32_t bookkeeping_ticket_1; + uint32_t bookkeeping_ticket_2; + /* FF -> not used, censoring globally disabled. unused feature though */ + uint8_t region; + /* 0 = censoring of song off */ + uint8_t censor_table[ASSET_ZERO_SETTINGS_MAX_SONGS]; } __attribute__((__packed__)); -struct asset_zero_settings* asset_zero_settings_new(void); +struct asset_zero_settings *asset_zero_settings_new(void); // update checksum -void asset_zero_settings_finalize(struct asset_zero_settings* settings); +void asset_zero_settings_finalize(struct asset_zero_settings *settings); // sets all missions cleared to unlock special stage songs and other missions -void asset_zero_settings_unlock_all(struct asset_zero_settings* settings); +void asset_zero_settings_unlock_all(struct asset_zero_settings *settings); -char* asset_zero_settings_to_string(const struct asset_zero_settings* settings); +char *asset_zero_settings_to_string(const struct asset_zero_settings *settings); #endif diff --git a/src/main/capnhook/hook/filehook.c b/src/main/capnhook/hook/filehook.c index 7d47b9a..f23acc0 100644 --- a/src/main/capnhook/hook/filehook.c +++ b/src/main/capnhook/hook/filehook.c @@ -12,38 +12,54 @@ #include "util/time.h" -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Real funcs typedefs */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ -typedef FILE* (*cnh_filehook_fopen_t)(const char* filename, const char* mode); -typedef int (*cnh_filehook_fclose_t)(FILE* stream); -typedef size_t (*cnh_filehook_fread_t)(void* ptr, size_t size, size_t nmemb, FILE* stream); -typedef size_t (*cnh_filehook_fwrite_t)(const void* ptr, size_t size, size_t nmemb, FILE* stream); -typedef char* (*cnh_filehook_fgets_t)(char* s, int size, FILE* stream); -typedef int (*cnh_filehook_fseek_t)(FILE* stream, long offset, int whence); -typedef long (*cnh_filehook_ftell_t)(FILE* stream); -typedef int (*cnh_filehook_feof_t)(FILE* stream); +typedef FILE *(*cnh_filehook_fopen_t)(const char *filename, const char *mode); +typedef int (*cnh_filehook_fclose_t)(FILE *stream); +typedef size_t (*cnh_filehook_fread_t)( + void *ptr, size_t size, size_t nmemb, FILE *stream); +typedef size_t (*cnh_filehook_fwrite_t)( + const void *ptr, size_t size, size_t nmemb, FILE *stream); +typedef char *(*cnh_filehook_fgets_t)(char *s, int size, FILE *stream); +typedef int (*cnh_filehook_fseek_t)(FILE *stream, long offset, int whence); +typedef long (*cnh_filehook_ftell_t)(FILE *stream); +typedef int (*cnh_filehook_feof_t)(FILE *stream); -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Private helpers */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ static void _cnh_filehook_init(void); static enum cnh_result _cnh_filehook_invoke_real(struct cnh_filehook_irp *irp); -static enum cnh_result _cnh_filehook_invoke_real_fopen(struct cnh_filehook_irp *irp); -static enum cnh_result _cnh_filehook_invoke_real_fclose(struct cnh_filehook_irp *irp); -static enum cnh_result _cnh_filehook_invoke_real_fread(struct cnh_filehook_irp *irp); -static enum cnh_result _cnh_filehook_invoke_real_fwrite(struct cnh_filehook_irp *irp); -static enum cnh_result _cnh_filehook_invoke_real_fgets(struct cnh_filehook_irp *irp); -static enum cnh_result _cnh_filehook_invoke_real_fseek(struct cnh_filehook_irp *irp); -static enum cnh_result _cnh_filehook_invoke_real_ftell(struct cnh_filehook_irp *irp); -static enum cnh_result _cnh_filehook_invoke_real_feof(struct cnh_filehook_irp *irp); +static enum cnh_result +_cnh_filehook_invoke_real_fopen(struct cnh_filehook_irp *irp); +static enum cnh_result +_cnh_filehook_invoke_real_fclose(struct cnh_filehook_irp *irp); +static enum cnh_result +_cnh_filehook_invoke_real_fread(struct cnh_filehook_irp *irp); +static enum cnh_result +_cnh_filehook_invoke_real_fwrite(struct cnh_filehook_irp *irp); +static enum cnh_result +_cnh_filehook_invoke_real_fgets(struct cnh_filehook_irp *irp); +static enum cnh_result +_cnh_filehook_invoke_real_fseek(struct cnh_filehook_irp *irp); +static enum cnh_result +_cnh_filehook_invoke_real_ftell(struct cnh_filehook_irp *irp); +static enum cnh_result +_cnh_filehook_invoke_real_feof(struct cnh_filehook_irp *irp); -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Private state */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ static cnh_filehook_fopen_t _cnh_filehook_real_fopen; static cnh_filehook_fclose_t _cnh_filehook_real_fclose; @@ -71,592 +87,637 @@ static pthread_mutex_t _cnh_filehook_lock; static cnh_filehook_fn_t *_cnh_filehook_handlers; static size_t _cnh_filehook_nhandlers; -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Public module functions */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ enum cnh_result cnh_filehook_push_handler(cnh_filehook_fn_t fn) { - cnh_filehook_fn_t *new_array; - size_t new_size; - enum cnh_result result; + cnh_filehook_fn_t *new_array; + size_t new_size; + enum cnh_result result; - assert(fn != NULL); + assert(fn != NULL); - _cnh_filehook_init(); - pthread_mutex_lock(&_cnh_filehook_lock); + _cnh_filehook_init(); + pthread_mutex_lock(&_cnh_filehook_lock); - new_size = _cnh_filehook_nhandlers + 1; - new_array = realloc(_cnh_filehook_handlers, new_size * sizeof(cnh_filehook_fn_t)); + new_size = _cnh_filehook_nhandlers + 1; + new_array = + realloc(_cnh_filehook_handlers, new_size * sizeof(cnh_filehook_fn_t)); - if (new_array != NULL) { - _cnh_filehook_handlers = new_array; - _cnh_filehook_handlers[_cnh_filehook_nhandlers++] = fn; - result = CNH_RESULT_SUCCESS; - } else { - result = CNH_RESULT_OUT_OF_MEMORY; - } + if (new_array != NULL) { + _cnh_filehook_handlers = new_array; + _cnh_filehook_handlers[_cnh_filehook_nhandlers++] = fn; + result = CNH_RESULT_SUCCESS; + } else { + result = CNH_RESULT_OUT_OF_MEMORY; + } - pthread_mutex_unlock(&_cnh_filehook_lock); + pthread_mutex_unlock(&_cnh_filehook_lock); - return result; + return result; } enum cnh_result cnh_filehook_invoke_next(struct cnh_filehook_irp *irp) { - cnh_filehook_fn_t handler; - enum cnh_result result; + cnh_filehook_fn_t handler; + enum cnh_result result; - assert(irp != NULL); - assert(_cnh_filehook_initted > 0); + assert(irp != NULL); + assert(_cnh_filehook_initted > 0); - pthread_mutex_lock(&_cnh_filehook_lock); + pthread_mutex_lock(&_cnh_filehook_lock); - assert(irp->next_handler <= _cnh_filehook_nhandlers); + assert(irp->next_handler <= _cnh_filehook_nhandlers); - if (irp->next_handler < _cnh_filehook_nhandlers) { - handler = _cnh_filehook_handlers[irp->next_handler]; - irp->next_handler++; - } else { - handler = _cnh_filehook_invoke_real; - irp->next_handler = (size_t) -1; - } + if (irp->next_handler < _cnh_filehook_nhandlers) { + handler = _cnh_filehook_handlers[irp->next_handler]; + irp->next_handler++; + } else { + handler = _cnh_filehook_invoke_real; + irp->next_handler = (size_t) -1; + } - pthread_mutex_unlock(&_cnh_filehook_lock); + pthread_mutex_unlock(&_cnh_filehook_lock); - result = handler(irp); + result = handler(irp); - if (result != CNH_RESULT_SUCCESS) { - irp->next_handler = (size_t) -1; - } + if (result != CNH_RESULT_SUCCESS) { + irp->next_handler = (size_t) -1; + } - return result; + return result; } -FILE* cnh_filehook_open_dummy_file_handle() +FILE *cnh_filehook_open_dummy_file_handle() { - _cnh_filehook_init(); + _cnh_filehook_init(); - /* We need to return some sort of valid FD to the - caller, since we're simulating a device that - doesn't exist. Open an FD on /dev/null. */ + /* We need to return some sort of valid FD to the + caller, since we're simulating a device that + doesn't exist. Open an FD on /dev/null. */ - return _cnh_filehook_real_fopen("/dev/null", "r"); + return _cnh_filehook_real_fopen("/dev/null", "r"); } -void cnh_filehook_close_dummy_file_handle(FILE* file) +void cnh_filehook_close_dummy_file_handle(FILE *file) { - _cnh_filehook_init(); + _cnh_filehook_init(); - /* Avoid hooking pipeline when using dummy handles */ - _cnh_filehook_real_fclose(file); + /* Avoid hooking pipeline when using dummy handles */ + _cnh_filehook_real_fclose(file); } -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Hooked functions */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ -FILE* fopen(const char* filename, const char* mode) +FILE *fopen(const char *filename, const char *mode) { - struct cnh_filehook_irp irp; - enum cnh_result result; + struct cnh_filehook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_filehook_init(); + /* Ensure module is initialized */ + _cnh_filehook_init(); - if (filename == NULL || mode == NULL) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - return NULL; - } + if (filename == NULL || mode == NULL) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + return NULL; + } - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_FILEHOOK_IRP_OP_OPEN; - irp.file = NULL; - irp.open_filename = filename; - irp.open_mode = mode; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_FILEHOOK_IRP_OP_OPEN; + irp.file = NULL; + irp.open_filename = filename; + irp.open_mode = mode; - result = cnh_filehook_invoke_next(&irp); + result = cnh_filehook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return NULL; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + return NULL; + } - errno = 0; + errno = 0; - return irp.file; + return irp.file; } -int fclose(FILE* stream) +int fclose(FILE *stream) { - struct cnh_filehook_irp irp; - enum cnh_result result; + struct cnh_filehook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_filehook_init(); + /* Ensure module is initialized */ + _cnh_filehook_init(); - if (stream == NULL) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - return EOF; - } + if (stream == NULL) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + return EOF; + } - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_FILEHOOK_IRP_OP_CLOSE; - irp.file = stream; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_FILEHOOK_IRP_OP_CLOSE; + irp.file = stream; - result = cnh_filehook_invoke_next(&irp); + result = cnh_filehook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return EOF; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + return EOF; + } - errno = 0; + errno = 0; + return 0; +} + +size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + struct cnh_filehook_irp irp; + enum cnh_result result; + + /* Ensure module is initialized */ + _cnh_filehook_init(); + + if (ptr == NULL || stream == NULL) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); return 0; -} + } -size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream) -{ - struct cnh_filehook_irp irp; - enum cnh_result result; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_FILEHOOK_IRP_OP_READ; + irp.file = stream; + irp.read.bytes = ptr; + irp.read.nbytes = size * nmemb; + irp.read.pos = 0; + /* To ensure we don't mess up any calls that are just passed through, we have + to drag along the original size and nmemb parameters and apply them to the + real call at the end of the chain if the iobuffer was not modified */ + irp.orig_read_write_size = size; + irp.orig_read_write_nmemb = nmemb; - /* Ensure module is initialized */ - _cnh_filehook_init(); - - if (ptr == NULL || stream == NULL) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - return 0; - } - - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_FILEHOOK_IRP_OP_READ; - irp.file = stream; - irp.read.bytes = ptr; - irp.read.nbytes = size * nmemb; - irp.read.pos = 0; - /* To ensure we don't mess up any calls that are just passed through, we have to drag along the original size - and nmemb parameters and apply them to the real call at the end of the chain if the iobuffer was not - modified */ - irp.orig_read_write_size = size; - irp.orig_read_write_nmemb = nmemb; - - result = cnh_filehook_invoke_next(&irp); - - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return 0; - } - - errno = 0; - - return irp.read.pos / size; -} - -size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream) -{ - struct cnh_filehook_irp irp; - enum cnh_result result; - - /* Ensure module is initialized */ - _cnh_filehook_init(); - - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_FILEHOOK_IRP_OP_WRITE; - irp.file = stream; - irp.write.bytes = ptr; - irp.write.nbytes = size * nmemb; - irp.write.pos = 0; - /* To ensure we don't mess up any calls that are just passed through, we have to drag along the original size - and nmemb parameters and apply them to the real call at the end of the chain if the iobuffer was not - modified */ - irp.orig_read_write_size = size; - irp.orig_read_write_nmemb = nmemb; - - result = cnh_filehook_invoke_next(&irp); - - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return 0; - } - - errno = 0; - - return irp.write.pos / size; -} - -char* fgets(char* s, int size, FILE* stream) -{ - struct cnh_filehook_irp irp; - enum cnh_result result; - - /* Ensure module is initialized */ - _cnh_filehook_init(); - - if (s == NULL || stream == NULL) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - return NULL; - } - - /* Redirect this to fread */ - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_FILEHOOK_IRP_OP_FGETS; - irp.file = stream; - irp.read.bytes = (uint8_t*) s; - irp.read.nbytes = (size_t) size; - irp.read.pos = 0; - - result = cnh_filehook_invoke_next(&irp); - - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return NULL; - } - - errno = 0; - - return (char*) irp.read.bytes; -} - -int fseek(FILE* stream, long offset, int whence) -{ - struct cnh_filehook_irp irp; - enum cnh_result result; - - /* Ensure module is initialized */ - _cnh_filehook_init(); - - if (stream == NULL) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - return -1; - } - - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_FILEHOOK_IRP_OP_SEEK; - irp.file = stream; - irp.seek_origin = whence; - irp.seek_offset = offset; - - result = cnh_filehook_invoke_next(&irp); - - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return -1; - } - - errno = 0; + result = cnh_filehook_invoke_next(&irp); + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); return 0; + } + + errno = 0; + + return irp.read.pos / size; } -void rewind(FILE* stream) +size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { - struct cnh_filehook_irp irp; - enum cnh_result result; + struct cnh_filehook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_filehook_init(); + /* Ensure module is initialized */ + _cnh_filehook_init(); - if (stream == NULL) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - return; - } + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_FILEHOOK_IRP_OP_WRITE; + irp.file = stream; + irp.write.bytes = ptr; + irp.write.nbytes = size * nmemb; + irp.write.pos = 0; + /* To ensure we don't mess up any calls that are just passed through, we have + to drag along the original size and nmemb parameters and apply them to the + real call at the end of the chain if the iobuffer was not modified */ + irp.orig_read_write_size = size; + irp.orig_read_write_nmemb = nmemb; - /* Seek to beginning */ - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_FILEHOOK_IRP_OP_SEEK; - irp.file = stream; - irp.seek_origin = SEEK_SET; - irp.seek_offset = 0; + result = cnh_filehook_invoke_next(&irp); - result = cnh_filehook_invoke_next(&irp); + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + return 0; + } - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return; - } + errno = 0; + + return irp.write.pos / size; } -long ftell(FILE* stream) +char *fgets(char *s, int size, FILE *stream) { - struct cnh_filehook_irp irp; - enum cnh_result result; + struct cnh_filehook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_filehook_init(); + /* Ensure module is initialized */ + _cnh_filehook_init(); - if (stream == NULL) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - return -1; - } + if (s == NULL || stream == NULL) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + return NULL; + } - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_FILEHOOK_IRP_OP_TELL; - irp.file = stream; - /* Return value */ - irp.tell_offset = 0; + /* Redirect this to fread */ + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_FILEHOOK_IRP_OP_FGETS; + irp.file = stream; + irp.read.bytes = (uint8_t *) s; + irp.read.nbytes = (size_t) size; + irp.read.pos = 0; - result = cnh_filehook_invoke_next(&irp); + result = cnh_filehook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return -1; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + return NULL; + } - errno = 0; + errno = 0; - return (long) irp.tell_offset; + return (char *) irp.read.bytes; } -int feof(FILE* stream) +int fseek(FILE *stream, long offset, int whence) { - struct cnh_filehook_irp irp; - enum cnh_result result; + struct cnh_filehook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_filehook_init(); + /* Ensure module is initialized */ + _cnh_filehook_init(); - if (stream == NULL) { - /* Must be EBADF according to man pages */ - errno = EBADF; - return -1; - } + if (stream == NULL) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + return -1; + } - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_FILEHOOK_IRP_OP_EOF; - irp.file = stream; - /* Return value */ - irp.eof = false; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_FILEHOOK_IRP_OP_SEEK; + irp.file = stream; + irp.seek_origin = whence; + irp.seek_offset = offset; - result = cnh_filehook_invoke_next(&irp); + result = cnh_filehook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - /* Function is never supposed to fail and EBADF is the only allowed error code */ - errno = EBADF; - return -1; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + return -1; + } - errno = 0; + errno = 0; - return irp.eof ? 1 : 0; + return 0; } -/* ------------------------------------------------------------------------------------------------------------------ */ +void rewind(FILE *stream) +{ + struct cnh_filehook_irp irp; + enum cnh_result result; + + /* Ensure module is initialized */ + _cnh_filehook_init(); + + if (stream == NULL) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + return; + } + + /* Seek to beginning */ + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_FILEHOOK_IRP_OP_SEEK; + irp.file = stream; + irp.seek_origin = SEEK_SET; + irp.seek_offset = 0; + + result = cnh_filehook_invoke_next(&irp); + + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + return; + } +} + +long ftell(FILE *stream) +{ + struct cnh_filehook_irp irp; + enum cnh_result result; + + /* Ensure module is initialized */ + _cnh_filehook_init(); + + if (stream == NULL) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + return -1; + } + + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_FILEHOOK_IRP_OP_TELL; + irp.file = stream; + /* Return value */ + irp.tell_offset = 0; + + result = cnh_filehook_invoke_next(&irp); + + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + return -1; + } + + errno = 0; + + return (long) irp.tell_offset; +} + +int feof(FILE *stream) +{ + struct cnh_filehook_irp irp; + enum cnh_result result; + + /* Ensure module is initialized */ + _cnh_filehook_init(); + + if (stream == NULL) { + /* Must be EBADF according to man pages */ + errno = EBADF; + return -1; + } + + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_FILEHOOK_IRP_OP_EOF; + irp.file = stream; + /* Return value */ + irp.eof = false; + + result = cnh_filehook_invoke_next(&irp); + + if (result != CNH_RESULT_SUCCESS) { + /* Function is never supposed to fail and EBADF is the only allowed error + * code */ + errno = EBADF; + return -1; + } + + errno = 0; + + return irp.eof ? 1 : 0; +} + +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Helper functions */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ static void _cnh_filehook_init(void) { - int expected; + int expected; - if (atomic_load(&_cnh_filehook_initted) > 0) { - return; + if (atomic_load(&_cnh_filehook_initted) > 0) { + return; + } + + expected = 0; + + if (!atomic_compare_exchange_strong( + &_cnh_filehook_init_in_progress, &expected, 1)) { + while (atomic_load(&_cnh_filehook_init_in_progress) > 1) { + util_time_sleep_us(100); } - expected = 0; + return; + } - if (!atomic_compare_exchange_strong(&_cnh_filehook_init_in_progress, &expected, 1)) { - while (atomic_load(&_cnh_filehook_init_in_progress) > 1) { - util_time_sleep_us(100); - } - - return; - } - - /* Check again to ensure the current thread yielded between the init'd check and setting init in progress */ - if (atomic_load(&_cnh_filehook_initted) > 0) { - /* Revert init in progress, because nothing to do anymore */ - atomic_store(&_cnh_filehook_init_in_progress, 0); - return; - } - - _cnh_filehook_real_fopen = (cnh_filehook_fopen_t) cnh_lib_get_func_addr("fopen"); - _cnh_filehook_real_fclose = (cnh_filehook_fclose_t) cnh_lib_get_func_addr("fclose"); - _cnh_filehook_real_fread = (cnh_filehook_fread_t) cnh_lib_get_func_addr("fread"); - _cnh_filehook_real_fwrite = (cnh_filehook_fwrite_t) cnh_lib_get_func_addr("fwrite"); - _cnh_filehook_real_fgets = (cnh_filehook_fgets_t) cnh_lib_get_func_addr("fgets"); - _cnh_filehook_real_fseek = (cnh_filehook_fseek_t) cnh_lib_get_func_addr("fseek"); - _cnh_filehook_real_ftell = (cnh_filehook_ftell_t) cnh_lib_get_func_addr("ftell"); - _cnh_filehook_real_feof = (cnh_filehook_feof_t) cnh_lib_get_func_addr("feof"); - - pthread_mutex_init(&_cnh_filehook_lock, NULL); - - atomic_store(&_cnh_filehook_initted, 1); + /* Check again to ensure the current thread yielded between the init'd check + * and setting init in progress */ + if (atomic_load(&_cnh_filehook_initted) > 0) { + /* Revert init in progress, because nothing to do anymore */ atomic_store(&_cnh_filehook_init_in_progress, 0); + return; + } + + _cnh_filehook_real_fopen = + (cnh_filehook_fopen_t) cnh_lib_get_func_addr("fopen"); + _cnh_filehook_real_fclose = + (cnh_filehook_fclose_t) cnh_lib_get_func_addr("fclose"); + _cnh_filehook_real_fread = + (cnh_filehook_fread_t) cnh_lib_get_func_addr("fread"); + _cnh_filehook_real_fwrite = + (cnh_filehook_fwrite_t) cnh_lib_get_func_addr("fwrite"); + _cnh_filehook_real_fgets = + (cnh_filehook_fgets_t) cnh_lib_get_func_addr("fgets"); + _cnh_filehook_real_fseek = + (cnh_filehook_fseek_t) cnh_lib_get_func_addr("fseek"); + _cnh_filehook_real_ftell = + (cnh_filehook_ftell_t) cnh_lib_get_func_addr("ftell"); + _cnh_filehook_real_feof = (cnh_filehook_feof_t) cnh_lib_get_func_addr("feof"); + + pthread_mutex_init(&_cnh_filehook_lock, NULL); + + atomic_store(&_cnh_filehook_initted, 1); + atomic_store(&_cnh_filehook_init_in_progress, 0); } static enum cnh_result _cnh_filehook_invoke_real(struct cnh_filehook_irp *irp) { - cnh_filehook_fn_t handler; + cnh_filehook_fn_t handler; - assert(irp != NULL); - assert(irp->op < _countof(_cnh_filehook_real_handlers)); + assert(irp != NULL); + assert(irp->op < _countof(_cnh_filehook_real_handlers)); - handler = _cnh_filehook_real_handlers[irp->op]; + handler = _cnh_filehook_real_handlers[irp->op]; - assert(handler != NULL); + assert(handler != NULL); - return handler(irp); + return handler(irp); } -static enum cnh_result _cnh_filehook_invoke_real_fopen(struct cnh_filehook_irp *irp) +static enum cnh_result +_cnh_filehook_invoke_real_fopen(struct cnh_filehook_irp *irp) { - FILE* file; + FILE *file; - assert(irp != NULL); + assert(irp != NULL); - file = _cnh_filehook_real_fopen(irp->open_filename, irp->open_mode); + file = _cnh_filehook_real_fopen(irp->open_filename, irp->open_mode); - if (!file) { - return cnh_errno_to_result(errno); + if (!file) { + return cnh_errno_to_result(errno); + } + + irp->file = file; + + return CNH_RESULT_SUCCESS; +} + +static enum cnh_result +_cnh_filehook_invoke_real_fclose(struct cnh_filehook_irp *irp) +{ + int res; + + assert(irp != NULL); + + res = _cnh_filehook_real_fclose(irp->file); + + if (res == EOF) { + return cnh_errno_to_result(errno); + } + + return CNH_RESULT_SUCCESS; +} + +static enum cnh_result +_cnh_filehook_invoke_real_fread(struct cnh_filehook_irp *irp) +{ + size_t read; + + assert(irp != NULL); + + /* Check if any previous hook modified the buffer and use original parameters + otherwise to ensure the original call is correctly applied to the real + function */ + if (irp->read.pos != 0 || + irp->read.nbytes != + irp->orig_read_write_nmemb * irp->orig_read_write_size) { + read = _cnh_filehook_real_fread( + &irp->read.bytes[irp->read.pos], + irp->read.nbytes - irp->read.pos, + 1, + irp->file); + + if (read < 1 && ferror(irp->file) != 0) { + return cnh_errno_to_result(errno); } - irp->file = file; + irp->read.pos += irp->read.nbytes - irp->read.pos; + } else { + read = _cnh_filehook_real_fread( + irp->read.bytes, + irp->orig_read_write_size, + irp->orig_read_write_nmemb, + irp->file); - return CNH_RESULT_SUCCESS; -} - -static enum cnh_result _cnh_filehook_invoke_real_fclose(struct cnh_filehook_irp *irp) -{ - int res; - - assert(irp != NULL); - - res = _cnh_filehook_real_fclose(irp->file); - - if (res == EOF) { - return cnh_errno_to_result(errno); + if (read < 1 && ferror(irp->file) != 0) { + return cnh_errno_to_result(errno); } - return CNH_RESULT_SUCCESS; + irp->read.pos = read * irp->orig_read_write_size; + } + + return CNH_RESULT_SUCCESS; } -static enum cnh_result _cnh_filehook_invoke_real_fread(struct cnh_filehook_irp *irp) +static enum cnh_result +_cnh_filehook_invoke_real_fwrite(struct cnh_filehook_irp *irp) { - size_t read; + size_t written; - assert(irp != NULL); + assert(irp != NULL); - /* Check if any previous hook modified the buffer and use original parameters otherwise to ensure the original - call is correctly applied to the real function */ - if (irp->read.pos != 0 || irp->read.nbytes != irp->orig_read_write_nmemb * irp->orig_read_write_size) { - read = _cnh_filehook_real_fread(&irp->read.bytes[irp->read.pos], irp->read.nbytes - irp->read.pos, 1, - irp->file); + /* Check if any previous hook modified the buffer and use original parameters + otherwise to ensure the original call is correctly applied to the real + function */ + if (irp->write.pos != 0 || + irp->write.nbytes != + irp->orig_read_write_nmemb * irp->orig_read_write_size) { + written = _cnh_filehook_real_fwrite( + &irp->write.bytes[irp->write.pos], + irp->write.nbytes - irp->write.pos, + 1, + irp->file); - if (read < 1 && ferror(irp->file) != 0) { - return cnh_errno_to_result(errno); - } + if (written < 1 && ferror(irp->file) != 0) { + return cnh_errno_to_result(errno); + } - irp->read.pos += irp->read.nbytes - irp->read.pos; + irp->write.pos += irp->write.nbytes - irp->write.pos; + } else { + written = _cnh_filehook_real_fwrite( + irp->write.bytes, + irp->orig_read_write_size, + irp->orig_read_write_nmemb, + irp->file); + + if (written < 1 && ferror(irp->file) != 0) { + return cnh_errno_to_result(errno); + } + + irp->write.pos += written * irp->orig_read_write_size; + } + + return CNH_RESULT_SUCCESS; +} + +static enum cnh_result +_cnh_filehook_invoke_real_fgets(struct cnh_filehook_irp *irp) +{ + char *res; + + res = _cnh_filehook_real_fgets( + (char *) irp->read.bytes, irp->read.nbytes, irp->file); + + if (res == NULL) { + /* eof */ + if (errno == 0) { + irp->read.bytes = NULL; + return CNH_RESULT_SUCCESS; } else { - read = _cnh_filehook_real_fread(irp->read.bytes, irp->orig_read_write_size, irp->orig_read_write_nmemb, - irp->file); - - if (read < 1 && ferror(irp->file) != 0) { - return cnh_errno_to_result(errno); - } - - irp->read.pos = read * irp->orig_read_write_size; + return cnh_errno_to_result(errno); } - + } else { return CNH_RESULT_SUCCESS; + } } -static enum cnh_result _cnh_filehook_invoke_real_fwrite(struct cnh_filehook_irp *irp) +static enum cnh_result +_cnh_filehook_invoke_real_fseek(struct cnh_filehook_irp *irp) { - size_t written; + int res; - assert(irp != NULL); + assert(irp != NULL); - /* Check if any previous hook modified the buffer and use original parameters otherwise to ensure the original - call is correctly applied to the real function */ - if (irp->write.pos != 0 || irp->write.nbytes != irp->orig_read_write_nmemb * irp->orig_read_write_size) { - written = _cnh_filehook_real_fwrite(&irp->write.bytes[irp->write.pos], irp->write.nbytes - irp->write.pos, 1, - irp->file); + res = _cnh_filehook_real_fseek( + irp->file, (long) irp->seek_offset, irp->seek_origin); - if (written < 1 && ferror(irp->file) != 0) { - return cnh_errno_to_result(errno); - } + if (res != 0) { + return cnh_errno_to_result(errno); + } - irp->write.pos += irp->write.nbytes - irp->write.pos; - } else { - written = _cnh_filehook_real_fwrite(irp->write.bytes, irp->orig_read_write_size, irp->orig_read_write_nmemb, - irp->file); - - if (written < 1 && ferror(irp->file) != 0) { - return cnh_errno_to_result(errno); - } - - irp->write.pos += written * irp->orig_read_write_size; - } - - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } -static enum cnh_result _cnh_filehook_invoke_real_fgets(struct cnh_filehook_irp *irp) +static enum cnh_result +_cnh_filehook_invoke_real_ftell(struct cnh_filehook_irp *irp) { - char* res; + long res; - res = _cnh_filehook_real_fgets((char*) irp->read.bytes, irp->read.nbytes, irp->file); + assert(irp != NULL); - if (res == NULL) { - /* eof */ - if (errno == 0) { - irp->read.bytes = NULL; - return CNH_RESULT_SUCCESS; - } else { - return cnh_errno_to_result(errno); - } - } else { - return CNH_RESULT_SUCCESS; - } + res = _cnh_filehook_real_ftell(irp->file); + + if (res < 0) { + return cnh_errno_to_result(errno); + } + + irp->tell_offset = (uint64_t) res; + + return CNH_RESULT_SUCCESS; } -static enum cnh_result _cnh_filehook_invoke_real_fseek(struct cnh_filehook_irp *irp) +static enum cnh_result +_cnh_filehook_invoke_real_feof(struct cnh_filehook_irp *irp) { - int res; + int res; - assert(irp != NULL); + assert(irp != NULL); - res = _cnh_filehook_real_fseek(irp->file, (long) irp->seek_offset, irp->seek_origin); + res = _cnh_filehook_real_feof(irp->file); - if (res != 0) { - return cnh_errno_to_result(errno); - } + if (res < 0) { + return cnh_errno_to_result(errno); + } - return CNH_RESULT_SUCCESS; -} + irp->eof = res > 0; -static enum cnh_result _cnh_filehook_invoke_real_ftell(struct cnh_filehook_irp *irp) -{ - long res; - - assert(irp != NULL); - - res = _cnh_filehook_real_ftell(irp->file); - - if (res < 0) { - return cnh_errno_to_result(errno); - } - - irp->tell_offset = (uint64_t) res; - - return CNH_RESULT_SUCCESS; -} - -static enum cnh_result _cnh_filehook_invoke_real_feof(struct cnh_filehook_irp *irp) -{ - int res; - - assert(irp != NULL); - - res = _cnh_filehook_real_feof(irp->file); - - if (res < 0) { - return cnh_errno_to_result(errno); - } - - irp->eof = res > 0; - - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } \ No newline at end of file diff --git a/src/main/capnhook/hook/filehook.h b/src/main/capnhook/hook/filehook.h index 94233c8..0b1ef3b 100644 --- a/src/main/capnhook/hook/filehook.h +++ b/src/main/capnhook/hook/filehook.h @@ -18,33 +18,33 @@ * Available operations to hook */ enum cnh_filehook_irp_op { - CNH_FILEHOOK_IRP_OP_OPEN = 0, - CNH_FILEHOOK_IRP_OP_CLOSE = 1, - CNH_FILEHOOK_IRP_OP_READ = 2, - CNH_FILEHOOK_IRP_OP_WRITE = 3, - CNH_FILEHOOK_IRP_OP_FGETS = 4, - CNH_FILEHOOK_IRP_OP_SEEK = 5, - CNH_FILEHOOK_IRP_OP_TELL = 6, - CNH_FILEHOOK_IRP_OP_EOF = 7, + CNH_FILEHOOK_IRP_OP_OPEN = 0, + CNH_FILEHOOK_IRP_OP_CLOSE = 1, + CNH_FILEHOOK_IRP_OP_READ = 2, + CNH_FILEHOOK_IRP_OP_WRITE = 3, + CNH_FILEHOOK_IRP_OP_FGETS = 4, + CNH_FILEHOOK_IRP_OP_SEEK = 5, + CNH_FILEHOOK_IRP_OP_TELL = 6, + CNH_FILEHOOK_IRP_OP_EOF = 7, }; /** * I/O request packet */ struct cnh_filehook_irp { - enum cnh_filehook_irp_op op; - size_t next_handler; - FILE* file; - const char *open_filename; - const char* open_mode; - struct cnh_iobuf read; - struct cnh_const_iobuf write; - size_t orig_read_write_size; - size_t orig_read_write_nmemb; - int seek_origin; - int64_t seek_offset; - uint64_t tell_offset; - bool eof; + enum cnh_filehook_irp_op op; + size_t next_handler; + FILE *file; + const char *open_filename; + const char *open_mode; + struct cnh_iobuf read; + struct cnh_const_iobuf write; + size_t orig_read_write_size; + size_t orig_read_write_nmemb; + int seek_origin; + int64_t seek_offset; + uint64_t tell_offset; + bool eof; }; /** @@ -77,14 +77,15 @@ enum cnh_result cnh_filehook_invoke_next(struct cnh_filehook_irp *irp); * * @return Actual file handle instance pointing to a dummy endpoint. */ -FILE* cnh_filehook_open_dummy_file_handle(); +FILE *cnh_filehook_open_dummy_file_handle(); /** - * Close a dummy file handle. Make sure to free your previously allocated handles - * to avoid resource leaks. Do not free them using the real close function. + * Close a dummy file handle. Make sure to free your previously allocated + * handles to avoid resource leaks. Do not free them using the real close + * function. * * @param file Dummy file handle to free */ -void cnh_filehook_close_dummy_file_handle(FILE* file); +void cnh_filehook_close_dummy_file_handle(FILE *file); #endif diff --git a/src/main/capnhook/hook/fshook.c b/src/main/capnhook/hook/fshook.c index 7e01bf5..1afa642 100644 --- a/src/main/capnhook/hook/fshook.c +++ b/src/main/capnhook/hook/fshook.c @@ -3,8 +3,8 @@ #include #include #include -#include #include +#include #include #include @@ -14,34 +14,48 @@ #include "util/time.h" -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Real funcs typedefs */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ -typedef DIR* (*cnh_fshook_opendir_t)(const char* name); -typedef int (*cnh_fshook_lxstat_t)(int version, const char* file, struct stat* buf); -typedef int (*cnh_fshook_xstat_t)(int version, const char* file, struct stat* buf); -typedef int (*cnh_fshook_rename_t)(const char* old, const char* new); -typedef int (*cnh_fshook_remove_t)(const char* pathname); -typedef int (*cnh_fshook_access_t)(const char* path, int amode); +typedef DIR *(*cnh_fshook_opendir_t)(const char *name); +typedef int (*cnh_fshook_lxstat_t)( + int version, const char *file, struct stat *buf); +typedef int (*cnh_fshook_xstat_t)( + int version, const char *file, struct stat *buf); +typedef int (*cnh_fshook_rename_t)(const char *old, const char *new); +typedef int (*cnh_fshook_remove_t)(const char *pathname); +typedef int (*cnh_fshook_access_t)(const char *path, int amode); -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Private helpers */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ static void _cnh_fshook_init(void); static enum cnh_result _cnh_fshook_invoke_real(struct cnh_fshook_irp *irp); -static enum cnh_result _cnh_fshook_invoke_real_opendir(struct cnh_fshook_irp *irp); -static enum cnh_result _cnh_fshook_invoke_real_lxstat(struct cnh_fshook_irp *irp); -static enum cnh_result _cnh_fshook_invoke_real_xstat(struct cnh_fshook_irp *irp); -static enum cnh_result _cnh_fshook_invoke_real_rename(struct cnh_fshook_irp *irp); -static enum cnh_result _cnh_fshook_invoke_real_remove(struct cnh_fshook_irp *irp); -static enum cnh_result _cnh_fshook_invoke_real_access(struct cnh_fshook_irp *irp); +static enum cnh_result +_cnh_fshook_invoke_real_opendir(struct cnh_fshook_irp *irp); +static enum cnh_result +_cnh_fshook_invoke_real_lxstat(struct cnh_fshook_irp *irp); +static enum cnh_result +_cnh_fshook_invoke_real_xstat(struct cnh_fshook_irp *irp); +static enum cnh_result +_cnh_fshook_invoke_real_rename(struct cnh_fshook_irp *irp); +static enum cnh_result +_cnh_fshook_invoke_real_remove(struct cnh_fshook_irp *irp); +static enum cnh_result +_cnh_fshook_invoke_real_access(struct cnh_fshook_irp *irp); -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Private state */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ static cnh_fshook_opendir_t _cnh_fshook_real_opendir; static cnh_fshook_lxstat_t _cnh_fshook_real_lxstat; @@ -65,383 +79,404 @@ static pthread_mutex_t _cnh_fshook_lock; static cnh_fshook_fn_t *_cnh_fshook_handlers; static size_t _cnh_fshook_nhandlers; -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Public module functions */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ enum cnh_result cnh_fshook_push_handler(cnh_fshook_fn_t fn) { - cnh_fshook_fn_t *new_array; - size_t new_size; - enum cnh_result result; + cnh_fshook_fn_t *new_array; + size_t new_size; + enum cnh_result result; - assert(fn != NULL); + assert(fn != NULL); - _cnh_fshook_init(); + _cnh_fshook_init(); - pthread_mutex_lock(&_cnh_fshook_lock); + pthread_mutex_lock(&_cnh_fshook_lock); - new_size = _cnh_fshook_nhandlers + 1; - new_array = realloc(_cnh_fshook_handlers, new_size * sizeof(cnh_fshook_fn_t)); + new_size = _cnh_fshook_nhandlers + 1; + new_array = realloc(_cnh_fshook_handlers, new_size * sizeof(cnh_fshook_fn_t)); - if (new_array != NULL) { - _cnh_fshook_handlers = new_array; - _cnh_fshook_handlers[_cnh_fshook_nhandlers++] = fn; - result = CNH_RESULT_SUCCESS; - } else { - result = CNH_RESULT_OUT_OF_MEMORY; - } + if (new_array != NULL) { + _cnh_fshook_handlers = new_array; + _cnh_fshook_handlers[_cnh_fshook_nhandlers++] = fn; + result = CNH_RESULT_SUCCESS; + } else { + result = CNH_RESULT_OUT_OF_MEMORY; + } - pthread_mutex_unlock(&_cnh_fshook_lock); + pthread_mutex_unlock(&_cnh_fshook_lock); - return result; + return result; } enum cnh_result cnh_fshook_invoke_next(struct cnh_fshook_irp *irp) { - cnh_fshook_fn_t handler; - enum cnh_result result; + cnh_fshook_fn_t handler; + enum cnh_result result; - assert(irp != NULL); - assert(_cnh_fshook_initted > 0); + assert(irp != NULL); + assert(_cnh_fshook_initted > 0); - pthread_mutex_lock(&_cnh_fshook_lock); + pthread_mutex_lock(&_cnh_fshook_lock); - assert(irp->next_handler <= _cnh_fshook_nhandlers); + assert(irp->next_handler <= _cnh_fshook_nhandlers); - if (irp->next_handler < _cnh_fshook_nhandlers) { - handler = _cnh_fshook_handlers[irp->next_handler]; - irp->next_handler++; - } else { - handler = _cnh_fshook_invoke_real; - irp->next_handler = (size_t) -1; - } + if (irp->next_handler < _cnh_fshook_nhandlers) { + handler = _cnh_fshook_handlers[irp->next_handler]; + irp->next_handler++; + } else { + handler = _cnh_fshook_invoke_real; + irp->next_handler = (size_t) -1; + } - pthread_mutex_unlock(&_cnh_fshook_lock); + pthread_mutex_unlock(&_cnh_fshook_lock); - result = handler(irp); + result = handler(irp); - if (result != CNH_RESULT_SUCCESS) { - irp->next_handler = (size_t) -1; - } + if (result != CNH_RESULT_SUCCESS) { + irp->next_handler = (size_t) -1; + } - return result; + return result; } -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Hooked functions */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ -DIR* opendir(const char* name) +DIR *opendir(const char *name) { - struct cnh_fshook_irp irp; - enum cnh_result result; + struct cnh_fshook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_fshook_init(); + /* Ensure module is initialized */ + _cnh_fshook_init(); - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_FSHOOK_IRP_OP_DIR_OPEN; - irp.opendir_name = name; - irp.opendir_ret = NULL; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_FSHOOK_IRP_OP_DIR_OPEN; + irp.opendir_name = name; + irp.opendir_ret = NULL; - result = cnh_fshook_invoke_next(&irp); + result = cnh_fshook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return NULL; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + return NULL; + } - errno = 0; + errno = 0; - return irp.opendir_ret; + return irp.opendir_ret; } -int __lxstat(int version, const char* file, struct stat* buf) +int __lxstat(int version, const char *file, struct stat *buf) { - struct cnh_fshook_irp irp; - enum cnh_result result; + struct cnh_fshook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_fshook_init(); + /* Ensure module is initialized */ + _cnh_fshook_init(); - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_FSHOOK_IRP_OP_LXSTAT; - irp.xstat_version = version; - irp.xstat_file = file; - irp.xstat_buf = buf; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_FSHOOK_IRP_OP_LXSTAT; + irp.xstat_version = version; + irp.xstat_file = file; + irp.xstat_buf = buf; - result = cnh_fshook_invoke_next(&irp); + result = cnh_fshook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return -1; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + return -1; + } - errno = 0; + errno = 0; - return 0; + return 0; } -int __xstat(int version, const char* file, struct stat* buf) +int __xstat(int version, const char *file, struct stat *buf) { - struct cnh_fshook_irp irp; - enum cnh_result result; + struct cnh_fshook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_fshook_init(); + /* Ensure module is initialized */ + _cnh_fshook_init(); - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_FSHOOK_IRP_OP_XSTAT; - irp.xstat_version = version; - irp.xstat_file = file; - irp.xstat_buf = buf; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_FSHOOK_IRP_OP_XSTAT; + irp.xstat_version = version; + irp.xstat_file = file; + irp.xstat_buf = buf; - result = cnh_fshook_invoke_next(&irp); + result = cnh_fshook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return -1; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + return -1; + } - errno = 0; + errno = 0; - return 0; + return 0; } -int rename(const char* old, const char* new) +int rename(const char *old, const char *new) { - struct cnh_fshook_irp irp; - enum cnh_result result; + struct cnh_fshook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_fshook_init(); + /* Ensure module is initialized */ + _cnh_fshook_init(); - if (old == NULL || new == NULL) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - return -1; - } + if (old == NULL || new == NULL) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + return -1; + } - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_FSHOOK_IRP_OP_RENAME; - irp.rename_old = old; - irp.rename_new = new; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_FSHOOK_IRP_OP_RENAME; + irp.rename_old = old; + irp.rename_new = new; - result = cnh_fshook_invoke_next(&irp); + result = cnh_fshook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return -1; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + return -1; + } - errno = 0; + errno = 0; - return 0; + return 0; } -int remove(const char* pathname) +int remove(const char *pathname) { - struct cnh_fshook_irp irp; - enum cnh_result result; + struct cnh_fshook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_fshook_init(); + /* Ensure module is initialized */ + _cnh_fshook_init(); - if (pathname == NULL) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - return -1; - } + if (pathname == NULL) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + return -1; + } - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_FSHOOK_IRP_OP_REMOVE; - irp.remove_pathname = pathname; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_FSHOOK_IRP_OP_REMOVE; + irp.remove_pathname = pathname; - result = cnh_fshook_invoke_next(&irp); + result = cnh_fshook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return -1; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + return -1; + } - errno = 0; + errno = 0; - return 0; + return 0; } -int access(const char* path, int amode) +int access(const char *path, int amode) { - struct cnh_fshook_irp irp; - enum cnh_result result; + struct cnh_fshook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_fshook_init(); + /* Ensure module is initialized */ + _cnh_fshook_init(); - if (path == NULL) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - return -1; - } + if (path == NULL) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + return -1; + } - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_FSHOOK_IRP_OP_ACCESS; - irp.access_path = path; - irp.access_amode = amode; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_FSHOOK_IRP_OP_ACCESS; + irp.access_path = path; + irp.access_amode = amode; - result = cnh_fshook_invoke_next(&irp); + result = cnh_fshook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return -1; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + return -1; + } - errno = 0; + errno = 0; - return 0; + return 0; } -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Helper functions */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ static void _cnh_fshook_init(void) { - int expected; + int expected; - if (atomic_load(&_cnh_fshook_initted) > 0) { - return; + if (atomic_load(&_cnh_fshook_initted) > 0) { + return; + } + + expected = 0; + + if (!atomic_compare_exchange_strong( + &_cnh_fshook_init_in_progress, &expected, 1)) { + while (atomic_load(&_cnh_fshook_init_in_progress) > 1) { + util_time_sleep_us(100); } - expected = 0; + return; + } - if (!atomic_compare_exchange_strong(&_cnh_fshook_init_in_progress, &expected, 1)) { - while (atomic_load(&_cnh_fshook_init_in_progress) > 1) { - util_time_sleep_us(100); - } - - return; - } - - /* Check again to ensure the current thread yielded between the init'd check and setting init in progress */ - if (atomic_load(&_cnh_fshook_initted) > 0) { - /* Revert init in progress, because nothing to do anymore */ - atomic_store(&_cnh_fshook_init_in_progress, 0); - return; - } - - _cnh_fshook_real_opendir = (cnh_fshook_opendir_t) cnh_lib_get_func_addr("opendir"); - _cnh_fshook_real_lxstat = (cnh_fshook_lxstat_t) cnh_lib_get_func_addr("__lxstat"); - _cnh_fshook_real_xstat = (cnh_fshook_xstat_t) cnh_lib_get_func_addr("__xstat"); - _cnh_fshook_real_rename = (cnh_fshook_rename_t) cnh_lib_get_func_addr("rename"); - _cnh_fshook_real_remove = (cnh_fshook_remove_t) cnh_lib_get_func_addr("remove"); - _cnh_fshook_real_access = (cnh_fshook_access_t) cnh_lib_get_func_addr("access"); - - pthread_mutex_init(&_cnh_fshook_lock, NULL); - - atomic_store(&_cnh_fshook_initted, 1); + /* Check again to ensure the current thread yielded between the init'd check + * and setting init in progress */ + if (atomic_load(&_cnh_fshook_initted) > 0) { + /* Revert init in progress, because nothing to do anymore */ atomic_store(&_cnh_fshook_init_in_progress, 0); + return; + } + + _cnh_fshook_real_opendir = + (cnh_fshook_opendir_t) cnh_lib_get_func_addr("opendir"); + _cnh_fshook_real_lxstat = + (cnh_fshook_lxstat_t) cnh_lib_get_func_addr("__lxstat"); + _cnh_fshook_real_xstat = + (cnh_fshook_xstat_t) cnh_lib_get_func_addr("__xstat"); + _cnh_fshook_real_rename = + (cnh_fshook_rename_t) cnh_lib_get_func_addr("rename"); + _cnh_fshook_real_remove = + (cnh_fshook_remove_t) cnh_lib_get_func_addr("remove"); + _cnh_fshook_real_access = + (cnh_fshook_access_t) cnh_lib_get_func_addr("access"); + + pthread_mutex_init(&_cnh_fshook_lock, NULL); + + atomic_store(&_cnh_fshook_initted, 1); + atomic_store(&_cnh_fshook_init_in_progress, 0); } static enum cnh_result _cnh_fshook_invoke_real(struct cnh_fshook_irp *irp) { - cnh_fshook_fn_t handler; + cnh_fshook_fn_t handler; - assert(irp != NULL); - assert(irp->op < _countof(_cnh_fshook_real_handlers)); + assert(irp != NULL); + assert(irp->op < _countof(_cnh_fshook_real_handlers)); - handler = _cnh_fshook_real_handlers[irp->op]; + handler = _cnh_fshook_real_handlers[irp->op]; - assert(handler != NULL); + assert(handler != NULL); - return handler(irp); + return handler(irp); } -static enum cnh_result _cnh_fshook_invoke_real_opendir(struct cnh_fshook_irp *irp) +static enum cnh_result +_cnh_fshook_invoke_real_opendir(struct cnh_fshook_irp *irp) { - DIR* dir; + DIR *dir; - assert(irp != NULL); + assert(irp != NULL); - dir = _cnh_fshook_real_opendir(irp->opendir_name); + dir = _cnh_fshook_real_opendir(irp->opendir_name); - if (dir == NULL) { - return cnh_errno_to_result(errno); - } + if (dir == NULL) { + return cnh_errno_to_result(errno); + } - irp->opendir_ret = dir; + irp->opendir_ret = dir; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } -static enum cnh_result _cnh_fshook_invoke_real_lxstat(struct cnh_fshook_irp *irp) +static enum cnh_result +_cnh_fshook_invoke_real_lxstat(struct cnh_fshook_irp *irp) { - int res; + int res; - assert(irp != NULL); + assert(irp != NULL); - res = _cnh_fshook_real_lxstat(irp->xstat_version, irp->xstat_file, irp->xstat_buf); + res = _cnh_fshook_real_lxstat( + irp->xstat_version, irp->xstat_file, irp->xstat_buf); - if (res != 0) { - return cnh_errno_to_result(errno); - } + if (res != 0) { + return cnh_errno_to_result(errno); + } - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } static enum cnh_result _cnh_fshook_invoke_real_xstat(struct cnh_fshook_irp *irp) { - int res; + int res; - assert(irp != NULL); + assert(irp != NULL); - res = _cnh_fshook_real_xstat(irp->xstat_version, irp->xstat_file, irp->xstat_buf); + res = _cnh_fshook_real_xstat( + irp->xstat_version, irp->xstat_file, irp->xstat_buf); - if (res != 0) { - return cnh_errno_to_result(errno); - } + if (res != 0) { + return cnh_errno_to_result(errno); + } - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } -static enum cnh_result _cnh_fshook_invoke_real_rename(struct cnh_fshook_irp *irp) +static enum cnh_result +_cnh_fshook_invoke_real_rename(struct cnh_fshook_irp *irp) { - int res; + int res; - assert(irp != NULL); + assert(irp != NULL); - res = _cnh_fshook_real_rename(irp->rename_old, irp->rename_new); + res = _cnh_fshook_real_rename(irp->rename_old, irp->rename_new); - if (res != 0) { - return cnh_errno_to_result(errno); - } + if (res != 0) { + return cnh_errno_to_result(errno); + } - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } -static enum cnh_result _cnh_fshook_invoke_real_remove(struct cnh_fshook_irp *irp) +static enum cnh_result +_cnh_fshook_invoke_real_remove(struct cnh_fshook_irp *irp) { - int res; + int res; - assert(irp != NULL); + assert(irp != NULL); - res = _cnh_fshook_real_remove(irp->remove_pathname); + res = _cnh_fshook_real_remove(irp->remove_pathname); - if (res != 0) { - return cnh_errno_to_result(errno); - } + if (res != 0) { + return cnh_errno_to_result(errno); + } - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } -static enum cnh_result _cnh_fshook_invoke_real_access(struct cnh_fshook_irp *irp) +static enum cnh_result +_cnh_fshook_invoke_real_access(struct cnh_fshook_irp *irp) { - int res; + int res; - assert(irp != NULL); + assert(irp != NULL); - res = _cnh_fshook_real_access(irp->access_path, irp->access_amode); + res = _cnh_fshook_real_access(irp->access_path, irp->access_amode); - if (res != 0) { - return cnh_errno_to_result(errno); - } + if (res != 0) { + return cnh_errno_to_result(errno); + } - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } \ No newline at end of file diff --git a/src/main/capnhook/hook/fshook.h b/src/main/capnhook/hook/fshook.h index 4b3c85c..4dc82fa 100644 --- a/src/main/capnhook/hook/fshook.h +++ b/src/main/capnhook/hook/fshook.h @@ -19,30 +19,30 @@ * Available operations to hook */ enum cnh_fshook_irp_op { - CNH_FSHOOK_IRP_OP_DIR_OPEN = 0, - CNH_FSHOOK_IRP_OP_LXSTAT = 1, - CNH_FSHOOK_IRP_OP_XSTAT = 2, - CNH_FSHOOK_IRP_OP_RENAME = 3, - CNH_FSHOOK_IRP_OP_REMOVE = 4, - CNH_FSHOOK_IRP_OP_ACCESS = 5, + CNH_FSHOOK_IRP_OP_DIR_OPEN = 0, + CNH_FSHOOK_IRP_OP_LXSTAT = 1, + CNH_FSHOOK_IRP_OP_XSTAT = 2, + CNH_FSHOOK_IRP_OP_RENAME = 3, + CNH_FSHOOK_IRP_OP_REMOVE = 4, + CNH_FSHOOK_IRP_OP_ACCESS = 5, }; /** * I/O request packet */ struct cnh_fshook_irp { - enum cnh_fshook_irp_op op; - size_t next_handler; - const char* opendir_name; - DIR* opendir_ret; - int xstat_version; - const char* xstat_file; - struct stat* xstat_buf; - const char* rename_old; - const char* rename_new; - const char* remove_pathname; - const char* access_path; - int access_amode; + enum cnh_fshook_irp_op op; + size_t next_handler; + const char *opendir_name; + DIR *opendir_ret; + int xstat_version; + const char *xstat_file; + struct stat *xstat_buf; + const char *rename_old; + const char *rename_new; + const char *remove_pathname; + const char *access_path; + int access_amode; }; /** diff --git a/src/main/capnhook/hook/iobuf.c b/src/main/capnhook/hook/iobuf.c index fdfc9d3..a67cb1c 100644 --- a/src/main/capnhook/hook/iobuf.c +++ b/src/main/capnhook/hook/iobuf.c @@ -5,249 +5,251 @@ void cnh_iobuf_flip(struct cnh_const_iobuf *child, struct cnh_iobuf *parent) { - assert(child != NULL); - assert(parent != NULL); + assert(child != NULL); + assert(parent != NULL); - child->bytes = parent->bytes; - child->pos = 0; - child->nbytes = parent->pos; + child->bytes = parent->bytes; + child->pos = 0; + child->nbytes = parent->pos; } size_t cnh_iobuf_move(struct cnh_iobuf *dest, struct cnh_const_iobuf *src) { - size_t dest_avail; - size_t src_avail; - size_t chunksz; + size_t dest_avail; + size_t src_avail; + size_t chunksz; - assert(dest != NULL); - assert(dest->bytes != NULL || dest->nbytes == 0); - assert(dest->pos <= dest->nbytes); + assert(dest != NULL); + assert(dest->bytes != NULL || dest->nbytes == 0); + assert(dest->pos <= dest->nbytes); - assert(src != NULL); - assert(src->bytes != NULL || src->nbytes == 0); - assert(src->pos <= src->nbytes); + assert(src != NULL); + assert(src->bytes != NULL || src->nbytes == 0); + assert(src->pos <= src->nbytes); - dest_avail = dest->nbytes - dest->pos; - src_avail = src->nbytes - src->pos; - chunksz = dest_avail < src_avail ? dest_avail : src_avail; + dest_avail = dest->nbytes - dest->pos; + src_avail = src->nbytes - src->pos; + chunksz = dest_avail < src_avail ? dest_avail : src_avail; - memcpy(&dest->bytes[dest->pos], &src->bytes[src->pos], chunksz); + memcpy(&dest->bytes[dest->pos], &src->bytes[src->pos], chunksz); - dest->pos += chunksz; - src->pos += chunksz; + dest->pos += chunksz; + src->pos += chunksz; - return chunksz; + return chunksz; } size_t cnh_iobuf_shift(struct cnh_iobuf *dest, struct cnh_iobuf *src) { - struct cnh_const_iobuf span; + struct cnh_const_iobuf span; - assert(dest != NULL); - assert(src != NULL); + assert(dest != NULL); + assert(src != NULL); - cnh_iobuf_flip(&span, src); - cnh_iobuf_move(dest, &span); + cnh_iobuf_flip(&span, src); + cnh_iobuf_move(dest, &span); - memmove(src->bytes, &src->bytes[span.pos], span.nbytes - span.pos); - src->pos -= span.pos; + memmove(src->bytes, &src->bytes[span.pos], span.nbytes - span.pos); + src->pos -= span.pos; - return span.pos; + return span.pos; } -enum cnh_result cnh_iobuf_read(struct cnh_const_iobuf *src, void *bytes, size_t nbytes) +enum cnh_result +cnh_iobuf_read(struct cnh_const_iobuf *src, void *bytes, size_t nbytes) { - assert(src != NULL); - assert(bytes != NULL || nbytes == 0); + assert(src != NULL); + assert(bytes != NULL || nbytes == 0); - if (src->pos + nbytes > src->nbytes) { - return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; - } + if (src->pos + nbytes > src->nbytes) { + return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; + } - memcpy(bytes, &src->bytes[src->pos], nbytes); - src->pos += nbytes; + memcpy(bytes, &src->bytes[src->pos], nbytes); + src->pos += nbytes; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } enum cnh_result cnh_iobuf_read_8(struct cnh_const_iobuf *src, uint8_t *out) { - assert(src != NULL); - assert(out != NULL); + assert(src != NULL); + assert(out != NULL); - if (src->pos + sizeof(uint8_t) > src->nbytes) { - return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; - } + if (src->pos + sizeof(uint8_t) > src->nbytes) { + return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; + } - *out = src->bytes[src->pos++]; + *out = src->bytes[src->pos++]; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } enum cnh_result cnh_iobuf_read_be16(struct cnh_const_iobuf *src, uint16_t *out) { - uint16_t value; + uint16_t value; - assert(src != NULL); - assert(out != NULL); + assert(src != NULL); + assert(out != NULL); - if (src->pos + sizeof(uint16_t) > src->nbytes) { - return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; - } + if (src->pos + sizeof(uint16_t) > src->nbytes) { + return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; + } - value = src->bytes[src->pos++] << 8; - value |= src->bytes[src->pos++]; + value = src->bytes[src->pos++] << 8; + value |= src->bytes[src->pos++]; - *out = value; + *out = value; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } enum cnh_result cnh_iobuf_read_be32(struct cnh_const_iobuf *src, uint32_t *out) { - uint32_t value; + uint32_t value; - assert(src != NULL); - assert(out != NULL); + assert(src != NULL); + assert(out != NULL); - if (src->pos + sizeof(uint32_t) > src->nbytes) { - return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; - } + if (src->pos + sizeof(uint32_t) > src->nbytes) { + return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; + } - value = src->bytes[src->pos++] << 24; - value |= src->bytes[src->pos++] << 16; - value |= src->bytes[src->pos++] << 8; - value |= src->bytes[src->pos++]; + value = src->bytes[src->pos++] << 24; + value |= src->bytes[src->pos++] << 16; + value |= src->bytes[src->pos++] << 8; + value |= src->bytes[src->pos++]; - *out = value; + *out = value; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } enum cnh_result cnh_iobuf_read_le16(struct cnh_const_iobuf *src, uint16_t *out) { - uint16_t value; + uint16_t value; - assert(src != NULL); - assert(out != NULL); + assert(src != NULL); + assert(out != NULL); - if (src->pos + sizeof(uint16_t) > src->nbytes) { - return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; - } + if (src->pos + sizeof(uint16_t) > src->nbytes) { + return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; + } - value = src->bytes[src->pos++]; - value |= src->bytes[src->pos++] << 8; + value = src->bytes[src->pos++]; + value |= src->bytes[src->pos++] << 8; - *out = value; + *out = value; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } enum cnh_result cnh_iobuf_read_le32(struct cnh_const_iobuf *src, uint32_t *out) { - uint32_t value; + uint32_t value; - assert(src != NULL); - assert(out != NULL); + assert(src != NULL); + assert(out != NULL); - if (src->pos + sizeof(uint32_t) > src->nbytes) { - return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; - } + if (src->pos + sizeof(uint32_t) > src->nbytes) { + return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; + } - value = src->bytes[src->pos++]; - value |= src->bytes[src->pos++] << 8; - value |= src->bytes[src->pos++] << 16; - value |= src->bytes[src->pos++] << 24; + value = src->bytes[src->pos++]; + value |= src->bytes[src->pos++] << 8; + value |= src->bytes[src->pos++] << 16; + value |= src->bytes[src->pos++] << 24; - *out = value; + *out = value; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } -enum cnh_result cnh_iobuf_write(struct cnh_iobuf *dest, const void *bytes, size_t nbytes) +enum cnh_result +cnh_iobuf_write(struct cnh_iobuf *dest, const void *bytes, size_t nbytes) { - assert(dest != NULL); - assert(bytes != NULL || nbytes == 0); + assert(dest != NULL); + assert(bytes != NULL || nbytes == 0); - if (dest->pos + nbytes > dest->nbytes) { - return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; - } + if (dest->pos + nbytes > dest->nbytes) { + return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; + } - memcpy(&dest->bytes[dest->pos], bytes, nbytes); - dest->pos += nbytes; + memcpy(&dest->bytes[dest->pos], bytes, nbytes); + dest->pos += nbytes; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } enum cnh_result cnh_iobuf_write_8(struct cnh_iobuf *dest, uint8_t value) { - assert(dest != NULL); + assert(dest != NULL); - if (dest->pos + sizeof(uint8_t) > dest->nbytes) { - return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; - } + if (dest->pos + sizeof(uint8_t) > dest->nbytes) { + return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; + } - dest->bytes[dest->pos++] = value; + dest->bytes[dest->pos++] = value; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } enum cnh_result cnh_iobuf_write_be16(struct cnh_iobuf *dest, uint16_t value) { - assert(dest != NULL); + assert(dest != NULL); - if (dest->pos + sizeof(uint16_t) > dest->nbytes) { - return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; - } + if (dest->pos + sizeof(uint16_t) > dest->nbytes) { + return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; + } - dest->bytes[dest->pos++] = (uint8_t) (value >> 8); - dest->bytes[dest->pos++] = (uint8_t) value; + dest->bytes[dest->pos++] = (uint8_t)(value >> 8); + dest->bytes[dest->pos++] = (uint8_t) value; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } enum cnh_result cnh_iobuf_write_be32(struct cnh_iobuf *dest, uint32_t value) { - assert(dest != NULL); + assert(dest != NULL); - if (dest->pos + sizeof(uint32_t) > dest->nbytes) { - return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; - } + if (dest->pos + sizeof(uint32_t) > dest->nbytes) { + return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; + } - dest->bytes[dest->pos++] = (uint8_t) (value >> 24); - dest->bytes[dest->pos++] = (uint8_t) (value >> 16); - dest->bytes[dest->pos++] = (uint8_t) (value >> 8); - dest->bytes[dest->pos++] = (uint8_t) value; + dest->bytes[dest->pos++] = (uint8_t)(value >> 24); + dest->bytes[dest->pos++] = (uint8_t)(value >> 16); + dest->bytes[dest->pos++] = (uint8_t)(value >> 8); + dest->bytes[dest->pos++] = (uint8_t) value; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } enum cnh_result cnh_iobuf_write_le16(struct cnh_iobuf *dest, uint16_t value) { - assert(dest != NULL); + assert(dest != NULL); - if (dest->pos + sizeof(uint16_t) > dest->nbytes) { - return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; - } + if (dest->pos + sizeof(uint16_t) > dest->nbytes) { + return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; + } - dest->bytes[dest->pos++] = (uint8_t) value; - dest->bytes[dest->pos++] = (uint8_t) (value >> 8); + dest->bytes[dest->pos++] = (uint8_t) value; + dest->bytes[dest->pos++] = (uint8_t)(value >> 8); - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } enum cnh_result cnh_iobuf_write_le32(struct cnh_iobuf *dest, uint32_t value) { - assert(dest != NULL); + assert(dest != NULL); - if (dest->pos + sizeof(uint32_t) > dest->nbytes) { - return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; - } + if (dest->pos + sizeof(uint32_t) > dest->nbytes) { + return CNH_RESULT_ERROR_INSUFFICIENT_BUFFER; + } - dest->bytes[dest->pos++] = (uint8_t) value; - dest->bytes[dest->pos++] = (uint8_t) (value >> 8); - dest->bytes[dest->pos++] = (uint8_t) (value >> 16); - dest->bytes[dest->pos++] = (uint8_t) (value >> 24); + dest->bytes[dest->pos++] = (uint8_t) value; + dest->bytes[dest->pos++] = (uint8_t)(value >> 8); + dest->bytes[dest->pos++] = (uint8_t)(value >> 16); + dest->bytes[dest->pos++] = (uint8_t)(value >> 24); - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } diff --git a/src/main/capnhook/hook/iobuf.h b/src/main/capnhook/hook/iobuf.h index 0f2e459..ab4d963 100644 --- a/src/main/capnhook/hook/iobuf.h +++ b/src/main/capnhook/hook/iobuf.h @@ -16,18 +16,18 @@ * I/O buffer */ struct cnh_iobuf { - uint8_t *bytes; - size_t nbytes; - size_t pos; + uint8_t *bytes; + size_t nbytes; + size_t pos; }; /** * I/O buffer */ struct cnh_const_iobuf { - const uint8_t *bytes; - size_t nbytes; - size_t pos; + const uint8_t *bytes; + size_t nbytes; + size_t pos; }; /** @@ -39,10 +39,12 @@ struct cnh_const_iobuf { void cnh_iobuf_flip(struct cnh_const_iobuf *child, struct cnh_iobuf *parent); /** - * Move the contents currently enclosed by pos and end of an I/O buffer to a destination. + * Move the contents currently enclosed by pos and end of an I/O buffer to a + * destination. * * @param dest Destination buffer to move the source to, starting at current pos - * @param src Source to move to the destination, starting at current pos up to end of the buffer + * @param src Source to move to the destination, starting at current pos up to + * end of the buffer * @return Number of bytes copied to destination */ size_t cnh_iobuf_move(struct cnh_iobuf *dest, struct cnh_const_iobuf *src); @@ -57,7 +59,8 @@ size_t cnh_iobuf_shift(struct cnh_iobuf *dest, struct cnh_iobuf *src); * @param nbytes Number of bytes to read * @return Result of operation */ -enum cnh_result cnh_iobuf_read(struct cnh_const_iobuf *src, void *bytes, size_t nbytes); +enum cnh_result +cnh_iobuf_read(struct cnh_const_iobuf *src, void *bytes, size_t nbytes); /** * Read a byte from an I/O buffer @@ -75,7 +78,8 @@ enum cnh_result cnh_iobuf_read_8(struct cnh_const_iobuf *src, uint8_t *value); * @param value Pointer to variable to read the data into * @return Result of operation */ -enum cnh_result cnh_iobuf_read_be16(struct cnh_const_iobuf *src, uint16_t *value); +enum cnh_result +cnh_iobuf_read_be16(struct cnh_const_iobuf *src, uint16_t *value); /** * Read a 4 byte value, big endian byte order, from an I/O buffer @@ -84,7 +88,8 @@ enum cnh_result cnh_iobuf_read_be16(struct cnh_const_iobuf *src, uint16_t *value * @param value Pointer to variable to read the data into * @return Result of operation */ -enum cnh_result cnh_iobuf_read_be32(struct cnh_const_iobuf *src, uint32_t *value); +enum cnh_result +cnh_iobuf_read_be32(struct cnh_const_iobuf *src, uint32_t *value); /** * Read a 2 byte value, little endian byte order, from an I/O buffer @@ -93,7 +98,8 @@ enum cnh_result cnh_iobuf_read_be32(struct cnh_const_iobuf *src, uint32_t *value * @param value Pointer to variable to read the data into * @return Result of operation */ -enum cnh_result cnh_iobuf_read_le16(struct cnh_const_iobuf *src, uint16_t *value); +enum cnh_result +cnh_iobuf_read_le16(struct cnh_const_iobuf *src, uint16_t *value); /** * Read a 4 byte value, little endian byte order, from an I/O buffer @@ -102,7 +108,8 @@ enum cnh_result cnh_iobuf_read_le16(struct cnh_const_iobuf *src, uint16_t *value * @param value Pointer to variable to read the data into * @return Result of operation */ -enum cnh_result cnh_iobuf_read_le32(struct cnh_const_iobuf *src, uint32_t *value); +enum cnh_result +cnh_iobuf_read_le32(struct cnh_const_iobuf *src, uint32_t *value); /** * Write data to an I/O buffer @@ -112,7 +119,8 @@ enum cnh_result cnh_iobuf_read_le32(struct cnh_const_iobuf *src, uint32_t *value * @param nbytes Number of bytes to write * @return Result of operation */ -enum cnh_result cnh_iobuf_write(struct cnh_iobuf *dest, const void *bytes, size_t nbytes); +enum cnh_result +cnh_iobuf_write(struct cnh_iobuf *dest, const void *bytes, size_t nbytes); /** * Write a byte to an I/O buffer diff --git a/src/main/capnhook/hook/iohook.c b/src/main/capnhook/hook/iohook.c index faa87cc..fa05e22 100644 --- a/src/main/capnhook/hook/iohook.c +++ b/src/main/capnhook/hook/iohook.c @@ -15,36 +15,46 @@ #define INVALID_FILE_DEVICE (-1) -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Real funcs typedefs */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ -typedef int (*cnh_iohook_open_t)(const char* path, int oflag); -typedef FILE* (*cnh_iohook_fdopen_t)(int fd, const char* mode); -typedef ssize_t (*cnh_iohook_write_t)(int fd, const void* buf, size_t count); -typedef ssize_t (*cnh_iohook_read_t)(int fd, void* buf, size_t count); +typedef int (*cnh_iohook_open_t)(const char *path, int oflag); +typedef FILE *(*cnh_iohook_fdopen_t)(int fd, const char *mode); +typedef ssize_t (*cnh_iohook_write_t)(int fd, const void *buf, size_t count); +typedef ssize_t (*cnh_iohook_read_t)(int fd, void *buf, size_t count); typedef off_t (*cnh_iohook_lseek_t)(int fildes, off_t offset, int whence); -typedef int (*cnh_iohook_ioctl_t)(int fd, int request, void* data); +typedef int (*cnh_iohook_ioctl_t)(int fd, int request, void *data); typedef int (*cnh_iohook_close_t)(int fd); -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Private helpers */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ static void _cnh_iohook_init(void); static enum cnh_result _cnh_iohook_invoke_real(struct cnh_iohook_irp *irp); static enum cnh_result _cnh_iohook_invoke_real_open(struct cnh_iohook_irp *irp); -static enum cnh_result _cnh_iohook_invoke_real_fdopen(struct cnh_iohook_irp *irp); -static enum cnh_result _cnh_iohook_invoke_real_close(struct cnh_iohook_irp *irp); +static enum cnh_result +_cnh_iohook_invoke_real_fdopen(struct cnh_iohook_irp *irp); +static enum cnh_result +_cnh_iohook_invoke_real_close(struct cnh_iohook_irp *irp); static enum cnh_result _cnh_iohook_invoke_real_read(struct cnh_iohook_irp *irp); -static enum cnh_result _cnh_iohook_invoke_real_write(struct cnh_iohook_irp *irp); +static enum cnh_result +_cnh_iohook_invoke_real_write(struct cnh_iohook_irp *irp); static enum cnh_result _cnh_iohook_invoke_real_seek(struct cnh_iohook_irp *irp); -static enum cnh_result _cnh_iohook_invoke_real_ioctl(struct cnh_iohook_irp *irp); +static enum cnh_result +_cnh_iohook_invoke_real_ioctl(struct cnh_iohook_irp *irp); -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Private state */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ static cnh_iohook_open_t _cnh_iohook_real_open; static cnh_iohook_fdopen_t _cnh_iohook_real_fdopen; @@ -70,483 +80,500 @@ static pthread_mutex_t _cnh_iohook_lock; static cnh_iohook_fn_t *_cnh_iohook_handlers; static size_t _cnh_iohook_nhandlers; -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Public module functions */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ enum cnh_result cnh_iohook_push_handler(cnh_iohook_fn_t fn) { - cnh_iohook_fn_t *new_array; - size_t new_size; - enum cnh_result result; + cnh_iohook_fn_t *new_array; + size_t new_size; + enum cnh_result result; - assert(fn != NULL); + assert(fn != NULL); - _cnh_iohook_init(); - pthread_mutex_lock(&_cnh_iohook_lock); + _cnh_iohook_init(); + pthread_mutex_lock(&_cnh_iohook_lock); - new_size = _cnh_iohook_nhandlers + 1; - new_array = realloc(_cnh_iohook_handlers, new_size * sizeof(cnh_iohook_fn_t)); + new_size = _cnh_iohook_nhandlers + 1; + new_array = realloc(_cnh_iohook_handlers, new_size * sizeof(cnh_iohook_fn_t)); - if (new_array != NULL) { - _cnh_iohook_handlers = new_array; - _cnh_iohook_handlers[_cnh_iohook_nhandlers++] = fn; - result = CNH_RESULT_SUCCESS; - } else { - result = CNH_RESULT_OUT_OF_MEMORY; - } + if (new_array != NULL) { + _cnh_iohook_handlers = new_array; + _cnh_iohook_handlers[_cnh_iohook_nhandlers++] = fn; + result = CNH_RESULT_SUCCESS; + } else { + result = CNH_RESULT_OUT_OF_MEMORY; + } - pthread_mutex_unlock(&_cnh_iohook_lock); + pthread_mutex_unlock(&_cnh_iohook_lock); - return result; + return result; } enum cnh_result cnh_iohook_invoke_next(struct cnh_iohook_irp *irp) { - cnh_iohook_fn_t handler; - enum cnh_result result; + cnh_iohook_fn_t handler; + enum cnh_result result; - assert(irp != NULL); - assert(_cnh_iohook_initted > 0); + assert(irp != NULL); + assert(_cnh_iohook_initted > 0); - pthread_mutex_lock(&_cnh_iohook_lock); + pthread_mutex_lock(&_cnh_iohook_lock); - assert(irp->next_handler <= _cnh_iohook_nhandlers); + assert(irp->next_handler <= _cnh_iohook_nhandlers); - if (irp->next_handler < _cnh_iohook_nhandlers) { - handler = _cnh_iohook_handlers[irp->next_handler]; - irp->next_handler++; - } else { - handler = _cnh_iohook_invoke_real; - irp->next_handler = (size_t) -1; - } + if (irp->next_handler < _cnh_iohook_nhandlers) { + handler = _cnh_iohook_handlers[irp->next_handler]; + irp->next_handler++; + } else { + handler = _cnh_iohook_invoke_real; + irp->next_handler = (size_t) -1; + } - pthread_mutex_unlock(&_cnh_iohook_lock); + pthread_mutex_unlock(&_cnh_iohook_lock); - result = handler(irp); + result = handler(irp); - if (result != CNH_RESULT_SUCCESS) { - irp->next_handler = (size_t) -1; - } + if (result != CNH_RESULT_SUCCESS) { + irp->next_handler = (size_t) -1; + } - return result; + return result; } int cnh_iohook_open_dummy_fd() { - _cnh_iohook_init(); + _cnh_iohook_init(); - /* We need to return some sort of valid FD to the - caller, since we're simulating a device that - doesn't exist. Open an FD on /dev/null. */ + /* We need to return some sort of valid FD to the + caller, since we're simulating a device that + doesn't exist. Open an FD on /dev/null. */ - /* Open read only */ - return _cnh_iohook_real_open("/dev/null", 0); + /* Open read only */ + return _cnh_iohook_real_open("/dev/null", 0); } void cnh_iohook_close_dummy_fd(int fd) { - _cnh_iohook_init(); + _cnh_iohook_init(); - /* Avoid hooking pipeline when using dummy handles */ - _cnh_iohook_real_close(fd); + /* Avoid hooking pipeline when using dummy handles */ + _cnh_iohook_real_close(fd); } -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Hooked functions */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ -int open(const char* path, int oflag) +int open(const char *path, int oflag) { - struct cnh_iohook_irp irp; - enum cnh_result result; + struct cnh_iohook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_iohook_init(); + /* Ensure module is initialized */ + _cnh_iohook_init(); - if (path == NULL) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - return INVALID_FILE_DEVICE; - } + if (path == NULL) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + return INVALID_FILE_DEVICE; + } - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_IOHOOK_IRP_OP_OPEN; - irp.fd = INVALID_FILE_DEVICE; - irp.open_filename = path; - irp.open_flags = oflag; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_IOHOOK_IRP_OP_OPEN; + irp.fd = INVALID_FILE_DEVICE; + irp.open_filename = path; + irp.open_flags = oflag; - result = cnh_iohook_invoke_next(&irp); + result = cnh_iohook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return INVALID_FILE_DEVICE; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + return INVALID_FILE_DEVICE; + } - errno = 0; + errno = 0; - return irp.fd; + return irp.fd; } -FILE* fdopen(int fd, const char* mode) +FILE *fdopen(int fd, const char *mode) { - struct cnh_iohook_irp irp; - enum cnh_result result; + struct cnh_iohook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_iohook_init(); + /* Ensure module is initialized */ + _cnh_iohook_init(); - if (fd == -1 || mode == NULL) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - return NULL; - } + if (fd == -1 || mode == NULL) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + return NULL; + } - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_IOHOOK_IRP_OP_FDOPEN; - irp.fdopen_fd = fd; - irp.fdopen_mode = mode; - irp.fdopen_res = NULL; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_IOHOOK_IRP_OP_FDOPEN; + irp.fdopen_fd = fd; + irp.fdopen_mode = mode; + irp.fdopen_res = NULL; - result = cnh_iohook_invoke_next(&irp); + result = cnh_iohook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return NULL; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + return NULL; + } - errno = 0; + errno = 0; - return irp.fdopen_res; + return irp.fdopen_res; } int close(int fd) { - struct cnh_iohook_irp irp; - enum cnh_result result; + struct cnh_iohook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_iohook_init(); + /* Ensure module is initialized */ + _cnh_iohook_init(); - if (fd == INVALID_FILE_DEVICE) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - return -1; - } + if (fd == INVALID_FILE_DEVICE) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + return -1; + } - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_IOHOOK_IRP_OP_CLOSE; - irp.fd = fd; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_IOHOOK_IRP_OP_CLOSE; + irp.fd = fd; - result = cnh_iohook_invoke_next(&irp); + result = cnh_iohook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return -1; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + return -1; + } - errno = 0; + errno = 0; - return 0; + return 0; } -ssize_t read(int fd, void* buf, size_t count) +ssize_t read(int fd, void *buf, size_t count) { - struct cnh_iohook_irp irp; - enum cnh_result result; + struct cnh_iohook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_iohook_init(); + /* Ensure module is initialized */ + _cnh_iohook_init(); - if (fd == INVALID_FILE_DEVICE || buf == NULL) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - return -1; - } + if (fd == INVALID_FILE_DEVICE || buf == NULL) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + return -1; + } - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_IOHOOK_IRP_OP_READ; - irp.fd = fd; - irp.read.bytes = buf; - irp.read.nbytes = count; - irp.read.pos = 0; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_IOHOOK_IRP_OP_READ; + irp.fd = fd; + irp.read.bytes = buf; + irp.read.nbytes = count; + irp.read.pos = 0; - result = cnh_iohook_invoke_next(&irp); + result = cnh_iohook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return -1; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + return -1; + } - assert(irp.read.pos <= irp.read.nbytes); + assert(irp.read.pos <= irp.read.nbytes); - errno = 0; + errno = 0; - return irp.read.pos; + return irp.read.pos; } -ssize_t write(int fd, const void* buf, size_t count) +ssize_t write(int fd, const void *buf, size_t count) { - struct cnh_iohook_irp irp; - enum cnh_result result; + struct cnh_iohook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_iohook_init(); + /* Ensure module is initialized */ + _cnh_iohook_init(); - if (fd == INVALID_FILE_DEVICE || buf == NULL) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - return -1; - } + if (fd == INVALID_FILE_DEVICE || buf == NULL) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + return -1; + } - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_IOHOOK_IRP_OP_WRITE; - irp.fd = fd; - irp.write.bytes = buf; - irp.write.nbytes = count; - irp.write.pos = 0; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_IOHOOK_IRP_OP_WRITE; + irp.fd = fd; + irp.write.bytes = buf; + irp.write.nbytes = count; + irp.write.pos = 0; - result = cnh_iohook_invoke_next(&irp); + result = cnh_iohook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return -1; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + return -1; + } - assert(irp.write.pos <= irp.write.nbytes); + assert(irp.write.pos <= irp.write.nbytes); - errno = 0; + errno = 0; - return irp.write.pos; + return irp.write.pos; } off_t lseek(int fd, off_t offset, int whence) { - struct cnh_iohook_irp irp; - enum cnh_result result; + struct cnh_iohook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_iohook_init(); + /* Ensure module is initialized */ + _cnh_iohook_init(); - if (fd == INVALID_FILE_DEVICE) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - return -1; - } + if (fd == INVALID_FILE_DEVICE) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + return -1; + } - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_IOHOOK_IRP_OP_SEEK; - irp.fd = fd; - irp.seek_origin = whence; - irp.seek_offset = offset; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_IOHOOK_IRP_OP_SEEK; + irp.fd = fd; + irp.seek_origin = whence; + irp.seek_offset = offset; - result = cnh_iohook_invoke_next(&irp); + result = cnh_iohook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return -1; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + return -1; + } - errno = 0; + errno = 0; - return (off_t) irp.seek_pos; + return (off_t) irp.seek_pos; } -int ioctl(int fd, int request, void* data) +int ioctl(int fd, int request, void *data) { - struct cnh_iohook_irp irp; - enum cnh_result result; + struct cnh_iohook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_iohook_init(); + /* Ensure module is initialized */ + _cnh_iohook_init(); - if (fd == INVALID_FILE_DEVICE) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - return -1; - } + if (fd == INVALID_FILE_DEVICE) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + return -1; + } - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_IOHOOK_IRP_OP_IOCTL; - irp.fd = fd; - irp.ioctl_req = request; - irp.ioctl.bytes = data; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_IOHOOK_IRP_OP_IOCTL; + irp.fd = fd; + irp.ioctl_req = request; + irp.ioctl.bytes = data; - result = cnh_iohook_invoke_next(&irp); + result = cnh_iohook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return -1; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + return -1; + } - errno = 0; + errno = 0; - return irp.ioctl.pos; + return irp.ioctl.pos; } -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Helper functions */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ static void _cnh_iohook_init(void) { - int expected; + int expected; - if (atomic_load(&_cnh_iohook_initted) > 0) { - return; + if (atomic_load(&_cnh_iohook_initted) > 0) { + return; + } + + expected = 0; + + if (!atomic_compare_exchange_strong( + &_cnh_iohook_init_in_progress, &expected, 1)) { + while (atomic_load(&_cnh_iohook_init_in_progress) > 1) { + util_time_sleep_us(100); } - expected = 0; + return; + } - if (!atomic_compare_exchange_strong(&_cnh_iohook_init_in_progress, &expected, 1)) { - while (atomic_load(&_cnh_iohook_init_in_progress) > 1) { - util_time_sleep_us(100); - } - - return; - } - - /* Check again to ensure the current thread yielded between the init'd check and setting init in progress */ - if (atomic_load(&_cnh_iohook_initted) > 0) { - /* Revert init in progress, because nothing to do anymore */ - atomic_store(&_cnh_iohook_init_in_progress, 0); - return; - } - - _cnh_iohook_real_open = (cnh_iohook_open_t) cnh_lib_get_func_addr("open"); - _cnh_iohook_real_fdopen = (cnh_iohook_fdopen_t) cnh_lib_get_func_addr("fdopen"); - _cnh_iohook_real_close = (cnh_iohook_close_t) cnh_lib_get_func_addr("close"); - _cnh_iohook_real_read = (cnh_iohook_read_t) cnh_lib_get_func_addr("read"); - _cnh_iohook_real_write = (cnh_iohook_write_t) cnh_lib_get_func_addr("write"); - _cnh_iohook_real_lseek = (cnh_iohook_lseek_t) cnh_lib_get_func_addr("lseek"); - _cnh_iohook_real_ioctl = (cnh_iohook_ioctl_t) cnh_lib_get_func_addr("ioctl"); - - pthread_mutex_init(&_cnh_iohook_lock, NULL); - - atomic_store(&_cnh_iohook_initted, 1); + /* Check again to ensure the current thread yielded between the init'd check + * and setting init in progress */ + if (atomic_load(&_cnh_iohook_initted) > 0) { + /* Revert init in progress, because nothing to do anymore */ atomic_store(&_cnh_iohook_init_in_progress, 0); + return; + } + + _cnh_iohook_real_open = (cnh_iohook_open_t) cnh_lib_get_func_addr("open"); + _cnh_iohook_real_fdopen = + (cnh_iohook_fdopen_t) cnh_lib_get_func_addr("fdopen"); + _cnh_iohook_real_close = (cnh_iohook_close_t) cnh_lib_get_func_addr("close"); + _cnh_iohook_real_read = (cnh_iohook_read_t) cnh_lib_get_func_addr("read"); + _cnh_iohook_real_write = (cnh_iohook_write_t) cnh_lib_get_func_addr("write"); + _cnh_iohook_real_lseek = (cnh_iohook_lseek_t) cnh_lib_get_func_addr("lseek"); + _cnh_iohook_real_ioctl = (cnh_iohook_ioctl_t) cnh_lib_get_func_addr("ioctl"); + + pthread_mutex_init(&_cnh_iohook_lock, NULL); + + atomic_store(&_cnh_iohook_initted, 1); + atomic_store(&_cnh_iohook_init_in_progress, 0); } static enum cnh_result _cnh_iohook_invoke_real(struct cnh_iohook_irp *irp) { - cnh_iohook_fn_t handler; + cnh_iohook_fn_t handler; - assert(irp != NULL); - assert(irp->op < _countof(_cnh_iohook_real_handlers)); + assert(irp != NULL); + assert(irp->op < _countof(_cnh_iohook_real_handlers)); - handler = _cnh_iohook_real_handlers[irp->op]; + handler = _cnh_iohook_real_handlers[irp->op]; - assert(handler != NULL); + assert(handler != NULL); - return handler(irp); + return handler(irp); } static enum cnh_result _cnh_iohook_invoke_real_open(struct cnh_iohook_irp *irp) { - int fd; + int fd; - assert(irp != NULL); + assert(irp != NULL); - fd = _cnh_iohook_real_open(irp->open_filename, irp->open_flags); + fd = _cnh_iohook_real_open(irp->open_filename, irp->open_flags); - if (fd == INVALID_FILE_DEVICE) { - return cnh_errno_to_result(errno); - } + if (fd == INVALID_FILE_DEVICE) { + return cnh_errno_to_result(errno); + } - irp->fd = fd; + irp->fd = fd; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } -static enum cnh_result _cnh_iohook_invoke_real_fdopen(struct cnh_iohook_irp *irp) +static enum cnh_result +_cnh_iohook_invoke_real_fdopen(struct cnh_iohook_irp *irp) { - FILE* file; + FILE *file; - assert(irp != NULL); + assert(irp != NULL); - file = _cnh_iohook_real_fdopen(irp->fdopen_fd, irp->fdopen_mode); + file = _cnh_iohook_real_fdopen(irp->fdopen_fd, irp->fdopen_mode); - if (file == NULL) { - return cnh_errno_to_result(errno); - } + if (file == NULL) { + return cnh_errno_to_result(errno); + } - irp->fdopen_res = file; + irp->fdopen_res = file; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } static enum cnh_result _cnh_iohook_invoke_real_close(struct cnh_iohook_irp *irp) { - int ok; + int ok; - assert(irp != NULL); + assert(irp != NULL); - ok = _cnh_iohook_real_close(irp->fd); + ok = _cnh_iohook_real_close(irp->fd); - if (ok < 0) { - return cnh_errno_to_result(errno); - } + if (ok < 0) { + return cnh_errno_to_result(errno); + } - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } static enum cnh_result _cnh_iohook_invoke_real_read(struct cnh_iohook_irp *irp) { - ssize_t read; + ssize_t read; - assert(irp != NULL); + assert(irp != NULL); - read = _cnh_iohook_real_read(irp->fd, &irp->read.bytes[irp->read.pos], irp->read.nbytes - irp->read.pos); + read = _cnh_iohook_real_read( + irp->fd, + &irp->read.bytes[irp->read.pos], + irp->read.nbytes - irp->read.pos); - if (read < 0) { - return cnh_errno_to_result(errno); - } + if (read < 0) { + return cnh_errno_to_result(errno); + } - irp->read.pos += read; + irp->read.pos += read; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } static enum cnh_result _cnh_iohook_invoke_real_write(struct cnh_iohook_irp *irp) { - ssize_t written; + ssize_t written; - assert(irp != NULL); + assert(irp != NULL); - written = _cnh_iohook_real_write(irp->fd, &irp->write.bytes[irp->write.pos], irp->write.nbytes - irp->write.pos); + written = _cnh_iohook_real_write( + irp->fd, + &irp->write.bytes[irp->write.pos], + irp->write.nbytes - irp->write.pos); - if (written < 0) { - return cnh_errno_to_result(errno); - } + if (written < 0) { + return cnh_errno_to_result(errno); + } - irp->write.pos += written; + irp->write.pos += written; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } static enum cnh_result _cnh_iohook_invoke_real_seek(struct cnh_iohook_irp *irp) { - off_t result; + off_t result; - assert(irp != NULL); + assert(irp != NULL); - result = _cnh_iohook_real_lseek(irp->fd, (off_t) irp->seek_offset, irp->seek_origin); + result = _cnh_iohook_real_lseek( + irp->fd, (off_t) irp->seek_offset, irp->seek_origin); - if (result < 0) { - return cnh_errno_to_result(errno); - } + if (result < 0) { + return cnh_errno_to_result(errno); + } - irp->seek_pos = result; + irp->seek_pos = result; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } static enum cnh_result _cnh_iohook_invoke_real_ioctl(struct cnh_iohook_irp *irp) { - int result; + int result; - assert(irp != NULL); + assert(irp != NULL); - result = _cnh_iohook_real_ioctl(irp->fd, irp->ioctl_req, irp->ioctl.bytes); + result = _cnh_iohook_real_ioctl(irp->fd, irp->ioctl_req, irp->ioctl.bytes); - if (result < 0) { - return cnh_errno_to_result(errno); - } + if (result < 0) { + return cnh_errno_to_result(errno); + } - irp->ioctl.pos = (size_t) result; + irp->ioctl.pos = (size_t) result; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } \ No newline at end of file diff --git a/src/main/capnhook/hook/iohook.h b/src/main/capnhook/hook/iohook.h index 83d7eea..57845e1 100644 --- a/src/main/capnhook/hook/iohook.h +++ b/src/main/capnhook/hook/iohook.h @@ -17,34 +17,34 @@ * Available operations to hook */ enum cnh_iohook_irp_op { - CNH_IOHOOK_IRP_OP_OPEN = 0, - CNH_IOHOOK_IRP_OP_FDOPEN = 1, - CNH_IOHOOK_IRP_OP_CLOSE = 2, - CNH_IOHOOK_IRP_OP_READ = 3, - CNH_IOHOOK_IRP_OP_WRITE = 4, - CNH_IOHOOK_IRP_OP_SEEK = 5, - CNH_IOHOOK_IRP_OP_IOCTL = 6, + CNH_IOHOOK_IRP_OP_OPEN = 0, + CNH_IOHOOK_IRP_OP_FDOPEN = 1, + CNH_IOHOOK_IRP_OP_CLOSE = 2, + CNH_IOHOOK_IRP_OP_READ = 3, + CNH_IOHOOK_IRP_OP_WRITE = 4, + CNH_IOHOOK_IRP_OP_SEEK = 5, + CNH_IOHOOK_IRP_OP_IOCTL = 6, }; /** * I/O request packet */ struct cnh_iohook_irp { - enum cnh_iohook_irp_op op; - size_t next_handler; - int fd; - const char *open_filename; - int open_flags; - int fdopen_fd; - const char* fdopen_mode; - FILE* fdopen_res; - struct cnh_iobuf read; - struct cnh_const_iobuf write; - int seek_origin; - int64_t seek_offset; - uint64_t seek_pos; - int ioctl_req; - struct cnh_iobuf ioctl; + enum cnh_iohook_irp_op op; + size_t next_handler; + int fd; + const char *open_filename; + int open_flags; + int fdopen_fd; + const char *fdopen_mode; + FILE *fdopen_res; + struct cnh_iobuf read; + struct cnh_const_iobuf write; + int seek_origin; + int64_t seek_offset; + uint64_t seek_pos; + int ioctl_req; + struct cnh_iobuf ioctl; }; /** @@ -80,8 +80,9 @@ enum cnh_result cnh_iohook_invoke_next(struct cnh_iohook_irp *irp); int cnh_iohook_open_dummy_fd(); /** - * Close a dummy file handle. Make sure to free your previously allocated handles - * to avoid resource leaks. Do not free them using the real close function. + * Close a dummy file handle. Make sure to free your previously allocated + * handles to avoid resource leaks. Do not free them using the real close + * function. * * @param file Dummy file handle to free */ diff --git a/src/main/capnhook/hook/lib-main.h b/src/main/capnhook/hook/lib-main.h index 74f4965..845bfdd 100644 --- a/src/main/capnhook/hook/lib-main.h +++ b/src/main/capnhook/hook/lib-main.h @@ -6,52 +6,77 @@ #define CNH_LIB_MAIN_H #include -#include #include +#include #include #include "util/log.h" -#define LIB_MAIN_CONSTRUCTOR(func) __attribute__((constructor)) void lib_constructor() { func(); } +#define LIB_MAIN_CONSTRUCTOR(func) \ + __attribute__((constructor)) void lib_constructor() \ + { \ + func(); \ + } -#define LIB_MAIN_DESTRUCTOR(func) __attribute__((destructor)) void lib_destructor() { func(); } +#define LIB_MAIN_DESTRUCTOR(func) \ + __attribute__((destructor)) void lib_destructor() \ + { \ + func(); \ + } -#define LIB_MAIN_TRAP_MAIN(func_before_main, func_after_main) \ -typedef int (*func_libc_start_main_t)(int *(main) (int, char * *, char * *), int argc, char * * ubp_av, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end)); \ -typedef int* (*func_main_t)(int, char**, char**); \ -typedef void (*func_init_t)(void); \ -static func_main_t orig_main; \ -static func_init_t orig_init; \ -static bool trapped; \ -\ -int* trap_main(int argc, char** argv, char** envp) \ -{ \ - log_debug("Trap before main (%s): argc %d", argv[0], argc); \ - func_before_main(argc, argv); \ - log_debug("Calling orig_init"); \ - orig_init(); \ - log_debug("Calling real main (%s): argc %d", argv[0], argc); \ - int* ret = orig_main(argc, argv, envp); \ - log_debug("Calling cleanup after main (%s): ret %d", argv[0], ret); \ - func_after_main(); \ - return ret; \ -} \ -\ -void dummy_init(void) {} \ -\ -int __libc_start_main(int *(main) (int, char * *, char * *), int argc, char * * ubp_av, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end)) \ -{ \ - func_libc_start_main_t start = (func_libc_start_main_t) dlsym(RTLD_NEXT, "__libc_start_main"); \ - if (start == NULL) { \ - printf("ERROR finding orig func __libc_start_main\n"); \ - } \ - orig_main = main; \ - main = trap_main; \ - orig_init = init; \ - init = dummy_init; \ - trapped = true; \ - return (*start)(main, argc, ubp_av, init, fini, rtld_fini, stack_end); \ -} +#define LIB_MAIN_TRAP_MAIN(func_before_main, func_after_main) \ + typedef int (*func_libc_start_main_t)( \ + int *(main)(int, char **, char **), \ + int argc, \ + char **ubp_av, \ + void (*init)(void), \ + void (*fini)(void), \ + void (*rtld_fini)(void), \ + void(*stack_end)); \ + typedef int *(*func_main_t)(int, char **, char **); \ + typedef void (*func_init_t)(void); \ + static func_main_t orig_main; \ + static func_init_t orig_init; \ + static bool trapped; \ + \ + int *trap_main(int argc, char **argv, char **envp) \ + { \ + log_debug("Trap before main (%s): argc %d", argv[0], argc); \ + func_before_main(argc, argv); \ + log_debug("Calling orig_init"); \ + orig_init(); \ + log_debug("Calling real main (%s): argc %d", argv[0], argc); \ + int *ret = orig_main(argc, argv, envp); \ + log_debug("Calling cleanup after main (%s): ret %d", argv[0], ret); \ + func_after_main(); \ + return ret; \ + } \ + \ + void dummy_init(void) \ + { \ + } \ + \ + int __libc_start_main( \ + int *(main)(int, char **, char **), \ + int argc, \ + char **ubp_av, \ + void (*init)(void), \ + void (*fini)(void), \ + void (*rtld_fini)(void), \ + void(*stack_end)) \ + { \ + func_libc_start_main_t start = \ + (func_libc_start_main_t) dlsym(RTLD_NEXT, "__libc_start_main"); \ + if (start == NULL) { \ + printf("ERROR finding orig func __libc_start_main\n"); \ + } \ + orig_main = main; \ + main = trap_main; \ + orig_init = init; \ + init = dummy_init; \ + trapped = true; \ + return (*start)(main, argc, ubp_av, init, fini, rtld_fini, stack_end); \ + } #endif \ No newline at end of file diff --git a/src/main/capnhook/hook/lib.c b/src/main/capnhook/hook/lib.c index 9ce9435..5c82e06 100644 --- a/src/main/capnhook/hook/lib.c +++ b/src/main/capnhook/hook/lib.c @@ -8,172 +8,179 @@ #include "util/mem.h" #include "util/rand.h" -typedef void* (*cnh_lib_load_t)(const char* lib); -typedef void* (*cnh_lib_get_func_addr_handle_t)(void* lib_handle, const char* func_name); -typedef void (*cnh_lib_unload_t)(void* handle); -typedef void* (*cnh_lib_get_func_addr_t)(const char* func_name); +typedef void *(*cnh_lib_load_t)(const char *lib); +typedef void *(*cnh_lib_get_func_addr_handle_t)( + void *lib_handle, const char *func_name); +typedef void (*cnh_lib_unload_t)(void *handle); +typedef void *(*cnh_lib_get_func_addr_t)(const char *func_name); -static void* _cnh_lib_load(const char* lib); -static void* _cnh_lib_get_func_addr_handle(void* lib_handle, const char* func_name); -static void _cnh_lib_unload(void* handle); -static void* _cnh_lib_get_func_addr(const char* func_name); +static void *_cnh_lib_load(const char *lib); +static void * +_cnh_lib_get_func_addr_handle(void *lib_handle, const char *func_name); +static void _cnh_lib_unload(void *handle); +static void *_cnh_lib_get_func_addr(const char *func_name); -static void* _cnh_lib_load_test(const char* lib); -static void* _cnh_lib_get_func_addr_handle_test(void* lib_handle, const char* func_name); -static void _cnh_lib_unload_test(void* handle); -static void* _cnh_lib_get_func_addr_test(const char* func_name); +static void *_cnh_lib_load_test(const char *lib); +static void * +_cnh_lib_get_func_addr_handle_test(void *lib_handle, const char *func_name); +static void _cnh_lib_unload_test(void *handle); +static void *_cnh_lib_get_func_addr_test(const char *func_name); struct cnh_lib_interface { - cnh_lib_load_t load; - cnh_lib_get_func_addr_handle_t get_func_addr_handle; - cnh_lib_unload_t unload; - cnh_lib_get_func_addr_t get_func_addr; + cnh_lib_load_t load; + cnh_lib_get_func_addr_handle_t get_func_addr_handle; + cnh_lib_unload_t unload; + cnh_lib_get_func_addr_t get_func_addr; }; static struct cnh_lib_interface _cnh_lib_interface = { - .load = _cnh_lib_load, - .get_func_addr_handle = _cnh_lib_get_func_addr_handle, - .unload = _cnh_lib_unload, - .get_func_addr = _cnh_lib_get_func_addr, + .load = _cnh_lib_load, + .get_func_addr_handle = _cnh_lib_get_func_addr_handle, + .unload = _cnh_lib_unload, + .get_func_addr = _cnh_lib_get_func_addr, }; -static struct cnh_lib_unit_test_func_mocks* _cnh_lib_func_mocks; +static struct cnh_lib_unit_test_func_mocks *_cnh_lib_func_mocks; size_t _cnh_lib_func_mocks_cnt; -static void* _cnh_lib_load(const char* lib) +static void *_cnh_lib_load(const char *lib) { - void* so = dlopen(lib, RTLD_NOW); + void *so = dlopen(lib, RTLD_NOW); - if (so == NULL) { - log_warn("Failed to open library %s: %s", lib, dlerror()); - } else { - log_debug("Opened lib %s, handle %p", lib, so); - } + if (so == NULL) { + log_warn("Failed to open library %s: %s", lib, dlerror()); + } else { + log_debug("Opened lib %s, handle %p", lib, so); + } - return so; + return so; } -static void* _cnh_lib_get_func_addr_handle(void* lib_handle, const char* func_name) +static void * +_cnh_lib_get_func_addr_handle(void *lib_handle, const char *func_name) { - void* ret = dlsym(lib_handle, func_name); + void *ret = dlsym(lib_handle, func_name); - if (ret == NULL) { - log_warn("Could not find func %s in library %p", func_name, lib_handle); + if (ret == NULL) { + log_warn("Could not find func %s in library %p", func_name, lib_handle); + } + + return ret; +} + +static void _cnh_lib_unload(void *handle) +{ + dlclose(handle); + log_debug("Closed lib handle %p", handle); +} + +static void *_cnh_lib_get_func_addr(const char *func_name) +{ + void *ret = dlsym(RTLD_NEXT, func_name); + + if (ret == NULL) { + log_warn("Could not find func %s", func_name); + } + + return ret; +} + +static void *_cnh_lib_load_test(const char *lib) +{ + log_warn("Loading lib %s not supported in test", lib); + + if (sizeof(void *) == 4) { + return (void *) util_rand_gen_32(); + } else { + log_die_illegal_state(); + } +} + +static void * +_cnh_lib_get_func_addr_handle_test(void *lib_handle, const char *func_name) +{ + return _cnh_lib_get_func_addr_test(func_name); +} + +static void _cnh_lib_unload_test(void *handle) +{ + log_warn("Unloading lib %p not supported in test", handle); +} + +static void *_cnh_lib_get_func_addr_test(const char *func_name) +{ + for (size_t i = 0; i < _cnh_lib_func_mocks_cnt; i++) { + if (!strcmp(_cnh_lib_func_mocks[i].name, func_name)) { + return _cnh_lib_func_mocks->func; } + } - return ret; + log_warn("Could not find func %s", func_name); + + return NULL; } -static void _cnh_lib_unload(void* handle) +struct cnh_lib_unit_test_func_mocks *cnh_lib_allocate_func_mocks(size_t count) { - dlclose(handle); - log_debug("Closed lib handle %p", handle); + log_assert(count >= 0); + + struct cnh_lib_unit_test_func_mocks *func_mocks; + + func_mocks = + util_xmalloc(sizeof(struct cnh_lib_unit_test_func_mocks) * count); + + memset(func_mocks, 0, sizeof(struct cnh_lib_unit_test_func_mocks) * count); + + return func_mocks; } -static void* _cnh_lib_get_func_addr(const char* func_name) +void cnh_lib_init_unit_test( + struct cnh_lib_unit_test_func_mocks *func_mocks, size_t func_mocks_cnt) { - void* ret = dlsym(RTLD_NEXT, func_name); + log_warn("Setting up %d unit test func mocks", func_mocks_cnt); - if (ret == NULL) { - log_warn("Could not find func %s", func_name); - } + _cnh_lib_func_mocks = func_mocks; + _cnh_lib_func_mocks_cnt = func_mocks_cnt; - return ret; -} - -static void* _cnh_lib_load_test(const char* lib) -{ - log_warn("Loading lib %s not supported in test", lib); - - if (sizeof(void*) == 4) { - return (void*) util_rand_gen_32(); - } else { - log_die_illegal_state(); - } -} - -static void* _cnh_lib_get_func_addr_handle_test(void* lib_handle, const char* func_name) -{ - return _cnh_lib_get_func_addr_test(func_name); -} - -static void _cnh_lib_unload_test(void* handle) -{ - log_warn("Unloading lib %p not supported in test", handle); -} - -static void* _cnh_lib_get_func_addr_test(const char* func_name) -{ - for (size_t i = 0; i < _cnh_lib_func_mocks_cnt; i++) { - if (!strcmp(_cnh_lib_func_mocks[i].name, func_name)) { - return _cnh_lib_func_mocks->func; - } - } - - log_warn("Could not find func %s", func_name); - - return NULL; -} - -struct cnh_lib_unit_test_func_mocks* cnh_lib_allocate_func_mocks(size_t count) -{ - log_assert(count >= 0); - - struct cnh_lib_unit_test_func_mocks* func_mocks; - - func_mocks = util_xmalloc(sizeof(struct cnh_lib_unit_test_func_mocks) * count); - - memset(func_mocks, 0, sizeof(struct cnh_lib_unit_test_func_mocks) * count); - - return func_mocks; -} - -void cnh_lib_init_unit_test(struct cnh_lib_unit_test_func_mocks* func_mocks, size_t func_mocks_cnt) -{ - log_warn("Setting up %d unit test func mocks", func_mocks_cnt); - - _cnh_lib_func_mocks = func_mocks; - _cnh_lib_func_mocks_cnt = func_mocks_cnt; - - _cnh_lib_interface.load = _cnh_lib_load_test; - _cnh_lib_interface.get_func_addr_handle = _cnh_lib_get_func_addr_handle_test; - _cnh_lib_interface.unload = _cnh_lib_unload_test; - _cnh_lib_interface.get_func_addr = _cnh_lib_get_func_addr_test; + _cnh_lib_interface.load = _cnh_lib_load_test; + _cnh_lib_interface.get_func_addr_handle = _cnh_lib_get_func_addr_handle_test; + _cnh_lib_interface.unload = _cnh_lib_unload_test; + _cnh_lib_interface.get_func_addr = _cnh_lib_get_func_addr_test; } void cnh_lib_init() { - log_warn("Setting up real interface"); + log_warn("Setting up real interface"); - _cnh_lib_interface.load = _cnh_lib_load; - _cnh_lib_interface.get_func_addr_handle = _cnh_lib_get_func_addr_handle; - _cnh_lib_interface.unload = _cnh_lib_unload; - _cnh_lib_interface.get_func_addr = _cnh_lib_get_func_addr; + _cnh_lib_interface.load = _cnh_lib_load; + _cnh_lib_interface.get_func_addr_handle = _cnh_lib_get_func_addr_handle; + _cnh_lib_interface.unload = _cnh_lib_unload; + _cnh_lib_interface.get_func_addr = _cnh_lib_get_func_addr; } void cnh_lib_shutdown_unit_test() { - log_assert(_cnh_lib_func_mocks); + log_assert(_cnh_lib_func_mocks); - util_xfree((void**) &_cnh_lib_func_mocks); + util_xfree((void **) &_cnh_lib_func_mocks); } -void* cnh_lib_load(const char* lib) +void *cnh_lib_load(const char *lib) { - return _cnh_lib_interface.load(lib); + return _cnh_lib_interface.load(lib); } -void* cnh_lib_get_func_addr_handle(void* lib_handle, const char* func_name) +void *cnh_lib_get_func_addr_handle(void *lib_handle, const char *func_name) { - return _cnh_lib_interface.get_func_addr_handle(lib_handle, func_name); + return _cnh_lib_interface.get_func_addr_handle(lib_handle, func_name); } -void cnh_lib_unload(void* handle) +void cnh_lib_unload(void *handle) { - _cnh_lib_interface.unload(handle); + _cnh_lib_interface.unload(handle); } -void* cnh_lib_get_func_addr(const char* func_name) +void *cnh_lib_get_func_addr(const char *func_name) { - return _cnh_lib_interface.get_func_addr(func_name); + return _cnh_lib_interface.get_func_addr(func_name); } \ No newline at end of file diff --git a/src/main/capnhook/hook/lib.h b/src/main/capnhook/hook/lib.h index f314d5c..b756840 100644 --- a/src/main/capnhook/hook/lib.h +++ b/src/main/capnhook/hook/lib.h @@ -7,38 +7,45 @@ #include /** - * Provide a mock function key'd by it's name and pointing to your actual mock implementation. + * Provide a mock function key'd by it's name and pointing to your actual mock + * implementation. */ struct cnh_lib_unit_test_func_mocks { - const char* name; - void* func; + const char *name; + void *func; }; /** - * Allocate memory for a list of mock functions to pass to cnh_lib_init_unit_test. + * Allocate memory for a list of mock functions to pass to + * cnh_lib_init_unit_test. * * @param count The size of the list. * @return Allocated memory with the specified number of entries. */ -struct cnh_lib_unit_test_func_mocks* cnh_lib_allocate_func_mocks(size_t count); +struct cnh_lib_unit_test_func_mocks *cnh_lib_allocate_func_mocks(size_t count); /** - * Initialize this module when using it in a unit-test. This allows you to add function mocks that are returned on the - * various calls to get function pointers from real library functions. Use this to mock them to test various patching - * modules. + * Initialize this module when using it in a unit-test. This allows you to add + * function mocks that are returned on the various calls to get function + * pointers from real library functions. Use this to mock them to test various + * patching modules. * - * Use the cnh_lib_allocate_func_mocks function to allocate a list that you can fill in. + * Use the cnh_lib_allocate_func_mocks function to allocate a list that you can + * fill in. * - * @param func_mocks A list of functions mocks with function names and pointers to the test mocks you set up. Ensure - * that the function signatures match, otherwise things might crash when getting called. The module - * will cleanup the memory allocated of this for you. + * @param func_mocks A list of functions mocks with function names and pointers + * to the test mocks you set up. Ensure that the function signatures match, + * otherwise things might crash when getting called. The module will cleanup the + * memory allocated of this for you. * @param func_mocks_cnt The length of the list of func_mocks. */ -void cnh_lib_init_unit_test(struct cnh_lib_unit_test_func_mocks* func_mocks, size_t func_mocks_cnt); +void cnh_lib_init_unit_test( + struct cnh_lib_unit_test_func_mocks *func_mocks, size_t func_mocks_cnt); /** - * Optional, used for unit testing. Switch to the default backend that utilizes loading real libraries and getting real - * function pointers from them. This is enabled by default. + * Optional, used for unit testing. Switch to the default backend that utilizes + * loading real libraries and getting real function pointers from them. This is + * enabled by default. */ void cnh_lib_init(); @@ -53,7 +60,7 @@ void cnh_lib_shutdown_unit_test(); * @param lib Path to library file to load * @return Pointer to a handle on success, NULL on failure */ -void* cnh_lib_load(const char* lib); +void *cnh_lib_load(const char *lib); /** * Get the address of a function from a library @@ -62,14 +69,14 @@ void* cnh_lib_load(const char* lib); * @param func_name Name of the function to get * @return Function ptr on success, false on error (function not found) */ -void*cnh_lib_get_func_addr_handle(void* lib_handle, const char* func_name); +void *cnh_lib_get_func_addr_handle(void *lib_handle, const char *func_name); /** * Unload a loaded dynamic library * * @param handle Handle of the loaded lib to unload */ -void cnh_lib_unload(void* handle); +void cnh_lib_unload(void *handle); /** * Get the adress of a function (from a dynamic library) @@ -79,6 +86,6 @@ void cnh_lib_unload(void* handle); * @param func_name Name of the function * @return Valid ptr to function on success, false on error (not found) */ -void* cnh_lib_get_func_addr(const char* func_name); +void *cnh_lib_get_func_addr(const char *func_name); #endif \ No newline at end of file diff --git a/src/main/capnhook/hook/result.c b/src/main/capnhook/hook/result.c index b1a80ff..db9d3a6 100644 --- a/src/main/capnhook/hook/result.c +++ b/src/main/capnhook/hook/result.c @@ -8,96 +8,100 @@ int cnh_result_to_errno(enum cnh_result result) { - switch (result) { - case CNH_RESULT_SUCCESS: - return 0; - case CNH_RESULT_ERROR_INSUFFICIENT_BUFFER: - return EIO; - case CNH_RESULT_INVALID_PARAMETER: - return EINVAL; - case CNH_RESULT_OUT_OF_MEMORY: - return ENOMEM; - case CNH_RESULT_REPEAT_OPERATION: - return EAGAIN; - case CNH_RESULT_NO_SUCH_FILE_OR_DIR: - return ENOENT; - case CNH_RESULT_NOT_TTY: - return ENOTTY; - case CNH_RESULT_BUSY: - return EBUSY; - case CNH_RESULT_IS_A_DIRECTORY: - return EISDIR; - case CNH_RESULT_PERMISSION_DENIED: - return EACCES; - case CNH_RESULT_DIRECTORY_NOT_EMPTY: - return ENOTEMPTY; - case CNH_RESULT_OPERATION_NOT_PERMITTED: - return EPERM; - case CNH_RESULT_NO_SUCH_DEVICE: - return ENODEV; - case CNH_RESULT_BAD_FILE_NUMBER: - return EBADF; - case CNH_RESULT_FILE_DESCRIPTOR_IN_BAD_STATE: - return EBADFD; - case CNH_RESULT_VALUE_TOO_LARGE_FOR_DEFINED_DATATYPE: - return EOVERFLOW; - case CNH_RESULT_NO_SUCH_DEVICE_OR_ADDRESS: - return ENXIO; - case CNH_RESULT_BROKEN_PIPE: - return EPIPE; - case CNH_RESULT_TIMER_EXPIRED: - return ETIME; - case CNH_RESULT_NO_DATA_AVAILABLE: - return ENODATA; - default: - log_warn("Unhandled other error %d to errno convert might cause bugs", result); - return EIO; - } + switch (result) { + case CNH_RESULT_SUCCESS: + return 0; + case CNH_RESULT_ERROR_INSUFFICIENT_BUFFER: + return EIO; + case CNH_RESULT_INVALID_PARAMETER: + return EINVAL; + case CNH_RESULT_OUT_OF_MEMORY: + return ENOMEM; + case CNH_RESULT_REPEAT_OPERATION: + return EAGAIN; + case CNH_RESULT_NO_SUCH_FILE_OR_DIR: + return ENOENT; + case CNH_RESULT_NOT_TTY: + return ENOTTY; + case CNH_RESULT_BUSY: + return EBUSY; + case CNH_RESULT_IS_A_DIRECTORY: + return EISDIR; + case CNH_RESULT_PERMISSION_DENIED: + return EACCES; + case CNH_RESULT_DIRECTORY_NOT_EMPTY: + return ENOTEMPTY; + case CNH_RESULT_OPERATION_NOT_PERMITTED: + return EPERM; + case CNH_RESULT_NO_SUCH_DEVICE: + return ENODEV; + case CNH_RESULT_BAD_FILE_NUMBER: + return EBADF; + case CNH_RESULT_FILE_DESCRIPTOR_IN_BAD_STATE: + return EBADFD; + case CNH_RESULT_VALUE_TOO_LARGE_FOR_DEFINED_DATATYPE: + return EOVERFLOW; + case CNH_RESULT_NO_SUCH_DEVICE_OR_ADDRESS: + return ENXIO; + case CNH_RESULT_BROKEN_PIPE: + return EPIPE; + case CNH_RESULT_TIMER_EXPIRED: + return ETIME; + case CNH_RESULT_NO_DATA_AVAILABLE: + return ENODATA; + default: + log_warn( + "Unhandled other error %d to errno convert might cause bugs", result); + return EIO; + } } enum cnh_result cnh_errno_to_result(int errn) { - switch (errn) { - case 0: - return CNH_RESULT_SUCCESS; - case EINVAL: - return CNH_RESULT_INVALID_PARAMETER; - case ENOMEM: - return CNH_RESULT_OUT_OF_MEMORY; - case EAGAIN: - return CNH_RESULT_REPEAT_OPERATION; - case ENOENT: - return CNH_RESULT_NO_SUCH_FILE_OR_DIR; - case ENOTTY: - return CNH_RESULT_NOT_TTY; - case EBUSY: - return CNH_RESULT_BUSY; - case EISDIR: - return CNH_RESULT_IS_A_DIRECTORY; - case EACCES: - return CNH_RESULT_PERMISSION_DENIED; - case ENOTEMPTY: - return CNH_RESULT_DIRECTORY_NOT_EMPTY; - case EPERM: - return CNH_RESULT_OPERATION_NOT_PERMITTED; - case ENODEV: - return CNH_RESULT_NO_SUCH_DEVICE; - case EBADF: - return CNH_RESULT_BAD_FILE_NUMBER; - case EBADFD: - return CNH_RESULT_FILE_DESCRIPTOR_IN_BAD_STATE; - case EOVERFLOW: - return CNH_RESULT_VALUE_TOO_LARGE_FOR_DEFINED_DATATYPE; - case ENXIO: - return CNH_RESULT_NO_SUCH_DEVICE_OR_ADDRESS; - case EPIPE: - return CNH_RESULT_BROKEN_PIPE; - case ETIME: - return CNH_RESULT_TIMER_EXPIRED; - case ENODATA: - return CNH_RESULT_NO_DATA_AVAILABLE; - default: - log_warn("Unhandled errno to general error convert might cause bugs, errno: %d", errn); - return CNH_RESULT_OTHER_ERROR; - } + switch (errn) { + case 0: + return CNH_RESULT_SUCCESS; + case EINVAL: + return CNH_RESULT_INVALID_PARAMETER; + case ENOMEM: + return CNH_RESULT_OUT_OF_MEMORY; + case EAGAIN: + return CNH_RESULT_REPEAT_OPERATION; + case ENOENT: + return CNH_RESULT_NO_SUCH_FILE_OR_DIR; + case ENOTTY: + return CNH_RESULT_NOT_TTY; + case EBUSY: + return CNH_RESULT_BUSY; + case EISDIR: + return CNH_RESULT_IS_A_DIRECTORY; + case EACCES: + return CNH_RESULT_PERMISSION_DENIED; + case ENOTEMPTY: + return CNH_RESULT_DIRECTORY_NOT_EMPTY; + case EPERM: + return CNH_RESULT_OPERATION_NOT_PERMITTED; + case ENODEV: + return CNH_RESULT_NO_SUCH_DEVICE; + case EBADF: + return CNH_RESULT_BAD_FILE_NUMBER; + case EBADFD: + return CNH_RESULT_FILE_DESCRIPTOR_IN_BAD_STATE; + case EOVERFLOW: + return CNH_RESULT_VALUE_TOO_LARGE_FOR_DEFINED_DATATYPE; + case ENXIO: + return CNH_RESULT_NO_SUCH_DEVICE_OR_ADDRESS; + case EPIPE: + return CNH_RESULT_BROKEN_PIPE; + case ETIME: + return CNH_RESULT_TIMER_EXPIRED; + case ENODATA: + return CNH_RESULT_NO_DATA_AVAILABLE; + default: + log_warn( + "Unhandled errno to general error convert might cause bugs, errno: " + "%d", + errn); + return CNH_RESULT_OTHER_ERROR; + } } \ No newline at end of file diff --git a/src/main/capnhook/hook/result.h b/src/main/capnhook/hook/result.h index 77a74e4..cd218d9 100644 --- a/src/main/capnhook/hook/result.h +++ b/src/main/capnhook/hook/result.h @@ -1,5 +1,6 @@ /** - * Results for returning errors on hook modules, converting them to errno and vice versa + * Results for returning errors on hook modules, converting them to errno and + * vice versa * * Based on original capnhook code for windows by decafcode: * https://github.com/decafcode/capnhook @@ -11,27 +12,27 @@ * Result values for hook functions */ enum cnh_result { - CNH_RESULT_SUCCESS = 0, - CNH_RESULT_ERROR_INSUFFICIENT_BUFFER = 1, - CNH_RESULT_INVALID_PARAMETER = 2, - CNH_RESULT_OUT_OF_MEMORY = 3, - CNH_RESULT_REPEAT_OPERATION = 4, - CNH_RESULT_NO_SUCH_FILE_OR_DIR = 5, - CNH_RESULT_OTHER_ERROR = 6, - CNH_RESULT_NOT_TTY = 7, - CNH_RESULT_BUSY = 8, - CNH_RESULT_IS_A_DIRECTORY = 9, - CNH_RESULT_PERMISSION_DENIED = 10, - CNH_RESULT_DIRECTORY_NOT_EMPTY = 11, - CNH_RESULT_OPERATION_NOT_PERMITTED = 12, - CNH_RESULT_NO_SUCH_DEVICE = 13, - CNH_RESULT_BAD_FILE_NUMBER = 14, - CNH_RESULT_FILE_DESCRIPTOR_IN_BAD_STATE = 15, - CNH_RESULT_VALUE_TOO_LARGE_FOR_DEFINED_DATATYPE = 16, - CNH_RESULT_NO_SUCH_DEVICE_OR_ADDRESS = 17, - CNH_RESULT_BROKEN_PIPE = 18, - CNH_RESULT_TIMER_EXPIRED = 19, - CNH_RESULT_NO_DATA_AVAILABLE = 20, + CNH_RESULT_SUCCESS = 0, + CNH_RESULT_ERROR_INSUFFICIENT_BUFFER = 1, + CNH_RESULT_INVALID_PARAMETER = 2, + CNH_RESULT_OUT_OF_MEMORY = 3, + CNH_RESULT_REPEAT_OPERATION = 4, + CNH_RESULT_NO_SUCH_FILE_OR_DIR = 5, + CNH_RESULT_OTHER_ERROR = 6, + CNH_RESULT_NOT_TTY = 7, + CNH_RESULT_BUSY = 8, + CNH_RESULT_IS_A_DIRECTORY = 9, + CNH_RESULT_PERMISSION_DENIED = 10, + CNH_RESULT_DIRECTORY_NOT_EMPTY = 11, + CNH_RESULT_OPERATION_NOT_PERMITTED = 12, + CNH_RESULT_NO_SUCH_DEVICE = 13, + CNH_RESULT_BAD_FILE_NUMBER = 14, + CNH_RESULT_FILE_DESCRIPTOR_IN_BAD_STATE = 15, + CNH_RESULT_VALUE_TOO_LARGE_FOR_DEFINED_DATATYPE = 16, + CNH_RESULT_NO_SUCH_DEVICE_OR_ADDRESS = 17, + CNH_RESULT_BROKEN_PIPE = 18, + CNH_RESULT_TIMER_EXPIRED = 19, + CNH_RESULT_NO_DATA_AVAILABLE = 20, }; /** diff --git a/src/main/capnhook/hook/sig.c b/src/main/capnhook/hook/sig.c index f149b17..44094e6 100644 --- a/src/main/capnhook/hook/sig.c +++ b/src/main/capnhook/hook/sig.c @@ -1,11 +1,12 @@ #define LOG_MODULE "cnh-sig" -#include "capnhook/hook/lib.h" #include "capnhook/hook/sig.h" +#include "capnhook/hook/lib.h" #include "util/log.h" -typedef int (*cnh_sig_handler_sigaction_t) (int sig, const struct sigaction* act, struct sigaction* oact); +typedef int (*cnh_sig_handler_sigaction_t)( + int sig, const struct sigaction *act, struct sigaction *oact); static void _cnh_signal_handler(int sig); @@ -16,43 +17,48 @@ static __sighandler_t _cnh_signal_orig_handlers[32]; void cnh_sig_install(int sig, cnh_sig_handler_t handler) { - if (sig < 0 || sig >= 32) { - log_die("Can't register handler for invalid signal number %d", sig); - } + if (sig < 0 || sig >= 32) { + log_die("Can't register handler for invalid signal number %d", sig); + } - /* Ensure that the application does not install it's own handler */ - _cnh_signal_handlers[sig] = handler; + /* Ensure that the application does not install it's own handler */ + _cnh_signal_handlers[sig] = handler; - /* Install a little detour as our signal handler */ - signal(sig, _cnh_signal_handler); + /* Install a little detour as our signal handler */ + signal(sig, _cnh_signal_handler); - log_info("Installed signal handler %p for %d", handler, sig); + log_info("Installed signal handler %p for %d", handler, sig); } -int sigaction(int sig, const struct sigaction* act, struct sigaction* oact) +int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { - if (_cnh_signal_handlers[sig]) { - log_info("Enforce own signal handler on signal: %d", sig); + if (_cnh_signal_handlers[sig]) { + log_info("Enforce own signal handler on signal: %d", sig); - /* save the original handler, we might need it */ - _cnh_signal_orig_handlers[sig] = ((struct sigaction*) act)->sa_handler; + /* save the original handler, we might need it */ + _cnh_signal_orig_handlers[sig] = ((struct sigaction *) act)->sa_handler; - /* swap */ - ((struct sigaction*) act)->sa_handler = (__sighandler_t) _cnh_signal_handler; + /* swap */ + ((struct sigaction *) act)->sa_handler = + (__sighandler_t) _cnh_signal_handler; - log_debug("Original handler %p for signal %d", _cnh_signal_orig_handlers[sig], sig); - } + log_debug( + "Original handler %p for signal %d", + _cnh_signal_orig_handlers[sig], + sig); + } - if (!_cnh_sig_handler_real_sigaction) { - _cnh_sig_handler_real_sigaction = (cnh_sig_handler_sigaction_t) cnh_lib_get_func_addr("sigaction"); - } + if (!_cnh_sig_handler_real_sigaction) { + _cnh_sig_handler_real_sigaction = + (cnh_sig_handler_sigaction_t) cnh_lib_get_func_addr("sigaction"); + } - return _cnh_sig_handler_real_sigaction(sig, act, oact); + return _cnh_sig_handler_real_sigaction(sig, act, oact); } static void _cnh_signal_handler(int sig) { - if (_cnh_signal_handlers[sig]) { - _cnh_signal_handlers[sig](sig, _cnh_signal_orig_handlers[sig]); - } + if (_cnh_signal_handlers[sig]) { + _cnh_signal_handlers[sig](sig, _cnh_signal_orig_handlers[sig]); + } } \ No newline at end of file diff --git a/src/main/capnhook/hook/usbhook.c b/src/main/capnhook/hook/usbhook.c index a7aa9e0..6d1ea94 100644 --- a/src/main/capnhook/hook/usbhook.c +++ b/src/main/capnhook/hook/usbhook.c @@ -14,44 +14,71 @@ #include "util/time.h" -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Real funcs typedefs */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ typedef int (*cnh_usbhook_usb_init_t)(void); typedef int (*cnh_usbhook_usb_find_devices_t)(void); typedef int (*cnh_usbhook_usb_find_busses_t)(void); -typedef usb_dev_handle* (*cnh_usbhook_usb_open_t)(struct usb_device* dev); -typedef int (*cnh_usbhook_usb_close_t)(usb_dev_handle* dev); -typedef int (*cnh_usbhook_usb_reset_t)(usb_dev_handle* dev); -typedef int (*cnh_usbhook_usb_set_altinterface_t)(usb_dev_handle* dev, int interface); -typedef int (*cnh_usbhook_usb_set_configuration_t)(usb_dev_handle* dev, int configuration); -typedef int (*cnh_usbhook_usb_claim_interface_t)(usb_dev_handle* dev, int interface); -typedef int (*cnh_usbhook_usb_control_msg_t)(usb_dev_handle* dev, int requesttype, int request, int value, int index, - char* bytes, int nbytes, int timeout); +typedef usb_dev_handle *(*cnh_usbhook_usb_open_t)(struct usb_device *dev); +typedef int (*cnh_usbhook_usb_close_t)(usb_dev_handle *dev); +typedef int (*cnh_usbhook_usb_reset_t)(usb_dev_handle *dev); +typedef int (*cnh_usbhook_usb_set_altinterface_t)( + usb_dev_handle *dev, int interface); +typedef int (*cnh_usbhook_usb_set_configuration_t)( + usb_dev_handle *dev, int configuration); +typedef int (*cnh_usbhook_usb_claim_interface_t)( + usb_dev_handle *dev, int interface); +typedef int (*cnh_usbhook_usb_control_msg_t)( + usb_dev_handle *dev, + int requesttype, + int request, + int value, + int index, + char *bytes, + int nbytes, + int timeout); -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Private helpers */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ static void _cnh_usbhook_init(void); -static enum cnh_result _cnh_usbhook_invoke_next_reset_advance(struct cnh_usbhook_irp *irp, bool reset_next_handler_advance); +static enum cnh_result _cnh_usbhook_invoke_next_reset_advance( + struct cnh_usbhook_irp *irp, bool reset_next_handler_advance); -static enum cnh_result _cnh_usbhook_invoke_real(struct cnh_usbhook_irp* irp); -static enum cnh_result _cnh_usbhook_invoke_real_init(struct cnh_usbhook_irp* irp); -static enum cnh_result _cnh_usbhook_invoke_real_find_busses(struct cnh_usbhook_irp* irp); -static enum cnh_result _cnh_usbhook_invoke_real_find_devices(struct cnh_usbhook_irp* irp); -static enum cnh_result _cnh_usbhook_invoke_real_open(struct cnh_usbhook_irp* irp); -static enum cnh_result _cnh_usbhook_invoke_real_close(struct cnh_usbhook_irp* irp); -static enum cnh_result _cnh_usbhook_invoke_real_reset(struct cnh_usbhook_irp* irp); -static enum cnh_result _cnh_usbhook_invoke_real_set_altinterface(struct cnh_usbhook_irp* irp); -static enum cnh_result _cnh_usbhook_invoke_real_set_configuration(struct cnh_usbhook_irp* irp); -static enum cnh_result _cnh_usbhook_invoke_real_claim_interface(struct cnh_usbhook_irp* irp); -static enum cnh_result _cnh_usbhook_invoke_real_ctrl_msg(struct cnh_usbhook_irp* irp); +static enum cnh_result _cnh_usbhook_invoke_real(struct cnh_usbhook_irp *irp); +static enum cnh_result +_cnh_usbhook_invoke_real_init(struct cnh_usbhook_irp *irp); +static enum cnh_result +_cnh_usbhook_invoke_real_find_busses(struct cnh_usbhook_irp *irp); +static enum cnh_result +_cnh_usbhook_invoke_real_find_devices(struct cnh_usbhook_irp *irp); +static enum cnh_result +_cnh_usbhook_invoke_real_open(struct cnh_usbhook_irp *irp); +static enum cnh_result +_cnh_usbhook_invoke_real_close(struct cnh_usbhook_irp *irp); +static enum cnh_result +_cnh_usbhook_invoke_real_reset(struct cnh_usbhook_irp *irp); +static enum cnh_result +_cnh_usbhook_invoke_real_set_altinterface(struct cnh_usbhook_irp *irp); +static enum cnh_result +_cnh_usbhook_invoke_real_set_configuration(struct cnh_usbhook_irp *irp); +static enum cnh_result +_cnh_usbhook_invoke_real_claim_interface(struct cnh_usbhook_irp *irp); +static enum cnh_result +_cnh_usbhook_invoke_real_ctrl_msg(struct cnh_usbhook_irp *irp); -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Private state */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ static cnh_usbhook_usb_init_t _cnh_usbhook_real_init; static cnh_usbhook_usb_find_devices_t _cnh_usbhook_real_find_devices; @@ -66,14 +93,17 @@ static cnh_usbhook_usb_control_msg_t _cnh_usbhook_real_control_msg; static const cnh_usbhook_fn_t _cnh_usbhook_real_handlers[10] = { [CNH_USBHOOK_IRP_OP_INIT] = _cnh_usbhook_invoke_real_init, - [CNH_USBHOOK_IRP_OP_FIND_BUSSES ]= _cnh_usbhook_invoke_real_find_busses, + [CNH_USBHOOK_IRP_OP_FIND_BUSSES] = _cnh_usbhook_invoke_real_find_busses, [CNH_USBHOOK_IRP_OP_FIND_DEVICES] = _cnh_usbhook_invoke_real_find_devices, [CNH_USBHOOK_IRP_OP_OPEN] = _cnh_usbhook_invoke_real_open, [CNH_USBHOOK_IRP_OP_CLOSE] = _cnh_usbhook_invoke_real_close, [CNH_USBHOOK_IRP_OP_RESET] = _cnh_usbhook_invoke_real_reset, - [CNH_USBHOOK_IRP_OP_SET_ALTINTERFACE] = _cnh_usbhook_invoke_real_set_altinterface, - [CNH_USBHOOK_IRP_OP_SET_CONFIGURATION] = _cnh_usbhook_invoke_real_set_configuration, - [CNH_USBHOOK_IRP_OP_CLAIM_INTERFACE] = _cnh_usbhook_invoke_real_claim_interface, + [CNH_USBHOOK_IRP_OP_SET_ALTINTERFACE] = + _cnh_usbhook_invoke_real_set_altinterface, + [CNH_USBHOOK_IRP_OP_SET_CONFIGURATION] = + _cnh_usbhook_invoke_real_set_configuration, + [CNH_USBHOOK_IRP_OP_CLAIM_INTERFACE] = + _cnh_usbhook_invoke_real_claim_interface, [CNH_USBHOOK_IRP_OP_CTRL_MSG] = _cnh_usbhook_invoke_real_ctrl_msg, }; @@ -83,561 +113,608 @@ static pthread_mutex_t _cnh_usbhook_lock; static cnh_usbhook_fn_t *_cnh_usbhook_handlers; static size_t _cnh_usbhook_nhandlers; -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Public module functions */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ enum cnh_result cnh_usbhook_push_handler(cnh_usbhook_fn_t fn) { - cnh_usbhook_fn_t *new_array; - size_t new_size; - enum cnh_result result; + cnh_usbhook_fn_t *new_array; + size_t new_size; + enum cnh_result result; - assert(fn != NULL); + assert(fn != NULL); - _cnh_usbhook_init(); - pthread_mutex_lock(&_cnh_usbhook_lock); + _cnh_usbhook_init(); + pthread_mutex_lock(&_cnh_usbhook_lock); - new_size = _cnh_usbhook_nhandlers + 1; - new_array = realloc(_cnh_usbhook_handlers, new_size * sizeof(cnh_usbhook_fn_t)); + new_size = _cnh_usbhook_nhandlers + 1; + new_array = + realloc(_cnh_usbhook_handlers, new_size * sizeof(cnh_usbhook_fn_t)); - if (new_array != NULL) { - _cnh_usbhook_handlers = new_array; - _cnh_usbhook_handlers[_cnh_usbhook_nhandlers++] = fn; - result = CNH_RESULT_SUCCESS; - } else { - result = CNH_RESULT_OUT_OF_MEMORY; - } + if (new_array != NULL) { + _cnh_usbhook_handlers = new_array; + _cnh_usbhook_handlers[_cnh_usbhook_nhandlers++] = fn; + result = CNH_RESULT_SUCCESS; + } else { + result = CNH_RESULT_OUT_OF_MEMORY; + } - pthread_mutex_unlock(&_cnh_usbhook_lock); + pthread_mutex_unlock(&_cnh_usbhook_lock); - return result; + return result; } enum cnh_result cnh_usbhook_invoke_next(struct cnh_usbhook_irp *irp) { - return _cnh_usbhook_invoke_next_reset_advance(irp, false); + return _cnh_usbhook_invoke_next_reset_advance(irp, false); } -enum cnh_result cnh_usbhook_invoke_next_reset_advance(struct cnh_usbhook_irp *irp) +enum cnh_result +cnh_usbhook_invoke_next_reset_advance(struct cnh_usbhook_irp *irp) { - return _cnh_usbhook_invoke_next_reset_advance(irp, true); + return _cnh_usbhook_invoke_next_reset_advance(irp, true); } -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Hooked functions */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ void usb_init(void) { - struct cnh_usbhook_irp irp; + struct cnh_usbhook_irp irp; - /* Ensure module is initialized */ - _cnh_usbhook_init(); + /* Ensure module is initialized */ + _cnh_usbhook_init(); - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_USBHOOK_IRP_OP_INIT; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_USBHOOK_IRP_OP_INIT; - cnh_usbhook_invoke_next(&irp); + cnh_usbhook_invoke_next(&irp); - /* No return value, results ignored */ + /* No return value, results ignored */ } int usb_find_busses(void) { - struct cnh_usbhook_irp irp; + struct cnh_usbhook_irp irp; - /* Ensure module is initialized */ - _cnh_usbhook_init(); + /* Ensure module is initialized */ + _cnh_usbhook_init(); - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_USBHOOK_IRP_OP_FIND_BUSSES; - irp.find_busses_res_num_busses = 0; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_USBHOOK_IRP_OP_FIND_BUSSES; + irp.find_busses_res_num_busses = 0; - cnh_usbhook_invoke_next(&irp); + cnh_usbhook_invoke_next(&irp); - /* No errors processed */ + /* No errors processed */ - return irp.find_busses_res_num_busses; + return irp.find_busses_res_num_busses; } int usb_find_devices(void) { - struct cnh_usbhook_irp irp; + struct cnh_usbhook_irp irp; - /* Ensure module is initialized */ - _cnh_usbhook_init(); + /* Ensure module is initialized */ + _cnh_usbhook_init(); - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_USBHOOK_IRP_OP_FIND_DEVICES; - irp.find_devices_res_num_devices = 0; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_USBHOOK_IRP_OP_FIND_DEVICES; + irp.find_devices_res_num_devices = 0; - cnh_usbhook_invoke_next(&irp); + cnh_usbhook_invoke_next(&irp); - /* No errors processed */ + /* No errors processed */ - return irp.find_devices_res_num_devices; + return irp.find_devices_res_num_devices; } -usb_dev_handle* usb_open(struct usb_device* dev) +usb_dev_handle *usb_open(struct usb_device *dev) { - struct cnh_usbhook_irp irp; - enum cnh_result result; + struct cnh_usbhook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_usbhook_init(); + /* Ensure module is initialized */ + _cnh_usbhook_init(); - if (dev == NULL) { - /* No errno is set here (from libusbcompat impl) */ - return NULL; - } + if (dev == NULL) { + /* No errno is set here (from libusbcompat impl) */ + return NULL; + } - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_USBHOOK_IRP_OP_OPEN; - irp.open_usb_dev = dev; - irp.handle = NULL; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_USBHOOK_IRP_OP_OPEN; + irp.open_usb_dev = dev; + irp.handle = NULL; - result = cnh_usbhook_invoke_next(&irp); + result = cnh_usbhook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - return NULL; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + return NULL; + } - return irp.handle; + return irp.handle; } -int usb_close(usb_dev_handle* dev) +int usb_close(usb_dev_handle *dev) { - struct cnh_usbhook_irp irp; - enum cnh_result result; + struct cnh_usbhook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_usbhook_init(); + /* Ensure module is initialized */ + _cnh_usbhook_init(); - if (dev == NULL) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - /* Always return negative errno on errors */ - return -errno; - } + if (dev == NULL) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + /* Always return negative errno on errors */ + return -errno; + } - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_USBHOOK_IRP_OP_CLOSE; - irp.handle = dev; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_USBHOOK_IRP_OP_CLOSE; + irp.handle = dev; - result = cnh_usbhook_invoke_next(&irp); + result = cnh_usbhook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - /* Always return negative errno on errors */ - return -errno; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + /* Always return negative errno on errors */ + return -errno; + } - return 0; + return 0; } -int usb_reset(usb_dev_handle* dev) +int usb_reset(usb_dev_handle *dev) { - struct cnh_usbhook_irp irp; - enum cnh_result result; + struct cnh_usbhook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_usbhook_init(); + /* Ensure module is initialized */ + _cnh_usbhook_init(); - if (dev == NULL) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - /* Always return negative errno on errors */ - return -errno; - } + if (dev == NULL) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + /* Always return negative errno on errors */ + return -errno; + } - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_USBHOOK_IRP_OP_RESET; - irp.handle = dev; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_USBHOOK_IRP_OP_RESET; + irp.handle = dev; - result = cnh_usbhook_invoke_next(&irp); + result = cnh_usbhook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - /* Always return negative errno on errors */ - return -errno; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + /* Always return negative errno on errors */ + return -errno; + } - return 0; + return 0; } -int usb_set_altinterface(usb_dev_handle* dev, int interface) +int usb_set_altinterface(usb_dev_handle *dev, int interface) { - struct cnh_usbhook_irp irp; - enum cnh_result result; + struct cnh_usbhook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_usbhook_init(); + /* Ensure module is initialized */ + _cnh_usbhook_init(); - if (dev == NULL) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - /* Always return negative errno on errors */ - return -errno; - } + if (dev == NULL) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + /* Always return negative errno on errors */ + return -errno; + } - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_USBHOOK_IRP_OP_SET_ALTINTERFACE; - irp.handle = dev; - irp.set_altinterface = interface; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_USBHOOK_IRP_OP_SET_ALTINTERFACE; + irp.handle = dev; + irp.set_altinterface = interface; - result = cnh_usbhook_invoke_next(&irp); + result = cnh_usbhook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - /* Always return negative errno on errors */ - return -errno; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + /* Always return negative errno on errors */ + return -errno; + } - return 0; + return 0; } -int usb_set_configuration(usb_dev_handle* dev, int configuration) +int usb_set_configuration(usb_dev_handle *dev, int configuration) { - struct cnh_usbhook_irp irp; - enum cnh_result result; + struct cnh_usbhook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_usbhook_init(); + /* Ensure module is initialized */ + _cnh_usbhook_init(); - if (dev == NULL) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - /* Always return negative errno on errors */ - return -errno; - } + if (dev == NULL) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + /* Always return negative errno on errors */ + return -errno; + } - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_USBHOOK_IRP_OP_SET_CONFIGURATION; - irp.handle = dev; - irp.set_configuration = configuration; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_USBHOOK_IRP_OP_SET_CONFIGURATION; + irp.handle = dev; + irp.set_configuration = configuration; - result = cnh_usbhook_invoke_next(&irp); + result = cnh_usbhook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - /* Always return negative errno on errors */ - return -errno; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + /* Always return negative errno on errors */ + return -errno; + } - return 0; + return 0; } -int usb_claim_interface(usb_dev_handle* dev, int interface) +int usb_claim_interface(usb_dev_handle *dev, int interface) { - struct cnh_usbhook_irp irp; - enum cnh_result result; + struct cnh_usbhook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_usbhook_init(); + /* Ensure module is initialized */ + _cnh_usbhook_init(); - if (dev == NULL) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - /* Always return negative errno on errors */ - return -errno; - } + if (dev == NULL) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + /* Always return negative errno on errors */ + return -errno; + } - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_USBHOOK_IRP_OP_CLAIM_INTERFACE; - irp.handle = dev; - irp.claim_interface = interface; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_USBHOOK_IRP_OP_CLAIM_INTERFACE; + irp.handle = dev; + irp.claim_interface = interface; - result = cnh_usbhook_invoke_next(&irp); + result = cnh_usbhook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - /* Always return negative errno on errors */ - return -errno; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + /* Always return negative errno on errors */ + return -errno; + } - return 0; + return 0; } -int usb_control_msg(usb_dev_handle* dev, int requesttype, int request, int value, int index, char* bytes, int nbytes, - int timeout) +int usb_control_msg( + usb_dev_handle *dev, + int requesttype, + int request, + int value, + int index, + char *bytes, + int nbytes, + int timeout) { - struct cnh_usbhook_irp irp; - enum cnh_result result; + struct cnh_usbhook_irp irp; + enum cnh_result result; - /* Ensure module is initialized */ - _cnh_usbhook_init(); + /* Ensure module is initialized */ + _cnh_usbhook_init(); - if (dev == NULL || bytes == NULL) { - errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); - /* Always return negative errno on errors */ - return -errno; - } + if (dev == NULL || bytes == NULL) { + errno = cnh_result_to_errno(CNH_RESULT_INVALID_PARAMETER); + /* Always return negative errno on errors */ + return -errno; + } - memset(&irp, 0, sizeof(irp)); - irp.op = CNH_USBHOOK_IRP_OP_CTRL_MSG; - irp.handle = dev; - irp.ctrl_req_type = requesttype; - irp.ctrl_req = request; - irp.ctrl_value = value; - irp.ctrl_index = index; - irp.ctrl_buffer.bytes = (uint8_t*) bytes; - irp.ctrl_buffer.nbytes = (size_t) nbytes; - irp.ctrl_buffer.pos = 0; - irp.ctrl_timeout = timeout; + memset(&irp, 0, sizeof(irp)); + irp.op = CNH_USBHOOK_IRP_OP_CTRL_MSG; + irp.handle = dev; + irp.ctrl_req_type = requesttype; + irp.ctrl_req = request; + irp.ctrl_value = value; + irp.ctrl_index = index; + irp.ctrl_buffer.bytes = (uint8_t *) bytes; + irp.ctrl_buffer.nbytes = (size_t) nbytes; + irp.ctrl_buffer.pos = 0; + irp.ctrl_timeout = timeout; - result = cnh_usbhook_invoke_next(&irp); + result = cnh_usbhook_invoke_next(&irp); - if (result != CNH_RESULT_SUCCESS) { - errno = cnh_result_to_errno(result); - /* Always return negative errno on errors */ - return -errno; - } + if (result != CNH_RESULT_SUCCESS) { + errno = cnh_result_to_errno(result); + /* Always return negative errno on errors */ + return -errno; + } - return irp.ctrl_buffer.pos; + return irp.ctrl_buffer.pos; } -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Helper functions */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ static void _cnh_usbhook_init(void) { - int expected; + int expected; - if (atomic_load(&_cnh_usbhook_initted) > 0) { - return; + if (atomic_load(&_cnh_usbhook_initted) > 0) { + return; + } + + expected = 0; + + if (!atomic_compare_exchange_strong( + &_cnh_usbhook_init_in_progress, &expected, 1)) { + while (atomic_load(&_cnh_usbhook_init_in_progress) > 1) { + util_time_sleep_us(100); } - expected = 0; + return; + } - if (!atomic_compare_exchange_strong(&_cnh_usbhook_init_in_progress, &expected, 1)) { - while (atomic_load(&_cnh_usbhook_init_in_progress) > 1) { - util_time_sleep_us(100); - } - - return; - } - - /* Check again to ensure the current thread yielded between the init'd check and setting init in progress */ - if (atomic_load(&_cnh_usbhook_initted) > 0) { - /* Revert init in progress, because nothing to do anymore */ - atomic_store(&_cnh_usbhook_init_in_progress, 0); - return; - } - - _cnh_usbhook_real_init = (cnh_usbhook_usb_init_t) cnh_lib_get_func_addr("usb_init"); - _cnh_usbhook_real_find_devices = (cnh_usbhook_usb_find_devices_t) cnh_lib_get_func_addr("usb_find_devices"); - _cnh_usbhook_real_find_busses = (cnh_usbhook_usb_find_busses_t) cnh_lib_get_func_addr("usb_find_busses"); - _cnh_usbhook_real_open = (cnh_usbhook_usb_open_t) cnh_lib_get_func_addr("usb_open"); - _cnh_usbhook_real_close = (cnh_usbhook_usb_close_t) cnh_lib_get_func_addr("usb_close"); - _cnh_usbhook_real_reset = (cnh_usbhook_usb_reset_t) cnh_lib_get_func_addr("usb_reset"); - _cnh_usbhook_real_set_altinterface = - (cnh_usbhook_usb_set_altinterface_t) cnh_lib_get_func_addr("usb_set_altinterface"); - _cnh_usbhook_real_set_configuration = - (cnh_usbhook_usb_set_configuration_t) cnh_lib_get_func_addr("usb_set_configuration"); - _cnh_usbhook_real_claim_interface = - (cnh_usbhook_usb_claim_interface_t) cnh_lib_get_func_addr("usb_claim_interface"); - _cnh_usbhook_real_control_msg = (cnh_usbhook_usb_control_msg_t) cnh_lib_get_func_addr("usb_control_msg"); - - pthread_mutex_init(&_cnh_usbhook_lock, NULL); - - atomic_store(&_cnh_usbhook_initted, 1); + /* Check again to ensure the current thread yielded between the init'd check + * and setting init in progress */ + if (atomic_load(&_cnh_usbhook_initted) > 0) { + /* Revert init in progress, because nothing to do anymore */ atomic_store(&_cnh_usbhook_init_in_progress, 0); + return; + } + + _cnh_usbhook_real_init = + (cnh_usbhook_usb_init_t) cnh_lib_get_func_addr("usb_init"); + _cnh_usbhook_real_find_devices = + (cnh_usbhook_usb_find_devices_t) cnh_lib_get_func_addr( + "usb_find_devices"); + _cnh_usbhook_real_find_busses = + (cnh_usbhook_usb_find_busses_t) cnh_lib_get_func_addr("usb_find_busses"); + _cnh_usbhook_real_open = + (cnh_usbhook_usb_open_t) cnh_lib_get_func_addr("usb_open"); + _cnh_usbhook_real_close = + (cnh_usbhook_usb_close_t) cnh_lib_get_func_addr("usb_close"); + _cnh_usbhook_real_reset = + (cnh_usbhook_usb_reset_t) cnh_lib_get_func_addr("usb_reset"); + _cnh_usbhook_real_set_altinterface = + (cnh_usbhook_usb_set_altinterface_t) cnh_lib_get_func_addr( + "usb_set_altinterface"); + _cnh_usbhook_real_set_configuration = + (cnh_usbhook_usb_set_configuration_t) cnh_lib_get_func_addr( + "usb_set_configuration"); + _cnh_usbhook_real_claim_interface = + (cnh_usbhook_usb_claim_interface_t) cnh_lib_get_func_addr( + "usb_claim_interface"); + _cnh_usbhook_real_control_msg = + (cnh_usbhook_usb_control_msg_t) cnh_lib_get_func_addr("usb_control_msg"); + + pthread_mutex_init(&_cnh_usbhook_lock, NULL); + + atomic_store(&_cnh_usbhook_initted, 1); + atomic_store(&_cnh_usbhook_init_in_progress, 0); } -static enum cnh_result _cnh_usbhook_invoke_next_reset_advance(struct cnh_usbhook_irp *irp, bool reset_next_handler_advance) +static enum cnh_result _cnh_usbhook_invoke_next_reset_advance( + struct cnh_usbhook_irp *irp, bool reset_next_handler_advance) { - cnh_usbhook_fn_t handler; - enum cnh_result result; - size_t cur_next_handler; + cnh_usbhook_fn_t handler; + enum cnh_result result; + size_t cur_next_handler; - assert(irp != NULL); - assert(_cnh_usbhook_initted > 0); + assert(irp != NULL); + assert(_cnh_usbhook_initted > 0); - cur_next_handler = irp->next_handler; + cur_next_handler = irp->next_handler; - pthread_mutex_lock(&_cnh_usbhook_lock); + pthread_mutex_lock(&_cnh_usbhook_lock); - assert(irp->next_handler <= _cnh_usbhook_nhandlers); + assert(irp->next_handler <= _cnh_usbhook_nhandlers); - if (irp->next_handler < _cnh_usbhook_nhandlers) { - handler = _cnh_usbhook_handlers[irp->next_handler]; - irp->next_handler++; - } else { - handler = _cnh_usbhook_invoke_real; - irp->next_handler = (size_t) -1; - } + if (irp->next_handler < _cnh_usbhook_nhandlers) { + handler = _cnh_usbhook_handlers[irp->next_handler]; + irp->next_handler++; + } else { + handler = _cnh_usbhook_invoke_real; + irp->next_handler = (size_t) -1; + } - pthread_mutex_unlock(&_cnh_usbhook_lock); + pthread_mutex_unlock(&_cnh_usbhook_lock); - result = handler(irp); + result = handler(irp); - if (result != CNH_RESULT_SUCCESS) { - irp->next_handler = (size_t) -1; - } + if (result != CNH_RESULT_SUCCESS) { + irp->next_handler = (size_t) -1; + } - if (reset_next_handler_advance) { - irp->next_handler = cur_next_handler; - } + if (reset_next_handler_advance) { + irp->next_handler = cur_next_handler; + } - return result; + return result; } -static enum cnh_result _cnh_usbhook_invoke_real(struct cnh_usbhook_irp* irp) +static enum cnh_result _cnh_usbhook_invoke_real(struct cnh_usbhook_irp *irp) { - cnh_usbhook_fn_t handler; + cnh_usbhook_fn_t handler; - assert(irp != NULL); - assert(irp->op < _countof(_cnh_usbhook_real_handlers)); + assert(irp != NULL); + assert(irp->op < _countof(_cnh_usbhook_real_handlers)); - handler = _cnh_usbhook_real_handlers[irp->op]; + handler = _cnh_usbhook_real_handlers[irp->op]; - assert(handler != NULL); + assert(handler != NULL); - return handler(irp); + return handler(irp); } -static enum cnh_result _cnh_usbhook_invoke_real_init(struct cnh_usbhook_irp* irp) +static enum cnh_result +_cnh_usbhook_invoke_real_init(struct cnh_usbhook_irp *irp) { - assert(irp != NULL); + assert(irp != NULL); - _cnh_usbhook_real_init(); + _cnh_usbhook_real_init(); - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } -static enum cnh_result _cnh_usbhook_invoke_real_find_busses(struct cnh_usbhook_irp* irp) +static enum cnh_result +_cnh_usbhook_invoke_real_find_busses(struct cnh_usbhook_irp *irp) { - int res; + int res; - assert(irp != NULL); + assert(irp != NULL); - res = _cnh_usbhook_real_find_busses(); + res = _cnh_usbhook_real_find_busses(); - irp->find_busses_res_num_busses = res; + irp->find_busses_res_num_busses = res; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } -static enum cnh_result _cnh_usbhook_invoke_real_find_devices(struct cnh_usbhook_irp* irp) +static enum cnh_result +_cnh_usbhook_invoke_real_find_devices(struct cnh_usbhook_irp *irp) { - int res; + int res; - assert(irp != NULL); + assert(irp != NULL); - res = _cnh_usbhook_real_find_devices(); + res = _cnh_usbhook_real_find_devices(); - irp->find_devices_res_num_devices = res; + irp->find_devices_res_num_devices = res; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } -static enum cnh_result _cnh_usbhook_invoke_real_open(struct cnh_usbhook_irp* irp) +static enum cnh_result +_cnh_usbhook_invoke_real_open(struct cnh_usbhook_irp *irp) { - usb_dev_handle* res; + usb_dev_handle *res; - assert(irp != NULL); + assert(irp != NULL); - res = _cnh_usbhook_real_open(irp->open_usb_dev); + res = _cnh_usbhook_real_open(irp->open_usb_dev); - if (res == NULL) { - irp->handle = NULL; - return cnh_errno_to_result(errno); - } + if (res == NULL) { + irp->handle = NULL; + return cnh_errno_to_result(errno); + } - irp->handle = res; + irp->handle = res; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } -static enum cnh_result _cnh_usbhook_invoke_real_close(struct cnh_usbhook_irp* irp) +static enum cnh_result +_cnh_usbhook_invoke_real_close(struct cnh_usbhook_irp *irp) { - int res; + int res; - assert(irp != NULL); + assert(irp != NULL); - res = _cnh_usbhook_real_close(irp->handle); + res = _cnh_usbhook_real_close(irp->handle); - if (res < 0) { - return cnh_errno_to_result(res); - } + if (res < 0) { + return cnh_errno_to_result(res); + } - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } -static enum cnh_result _cnh_usbhook_invoke_real_reset(struct cnh_usbhook_irp* irp) +static enum cnh_result +_cnh_usbhook_invoke_real_reset(struct cnh_usbhook_irp *irp) { - int res; + int res; - assert(irp != NULL); + assert(irp != NULL); - res = _cnh_usbhook_real_reset(irp->handle); + res = _cnh_usbhook_real_reset(irp->handle); - if (res < 0) { - return cnh_errno_to_result(res); - } + if (res < 0) { + return cnh_errno_to_result(res); + } - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } -static enum cnh_result _cnh_usbhook_invoke_real_set_altinterface(struct cnh_usbhook_irp* irp) +static enum cnh_result +_cnh_usbhook_invoke_real_set_altinterface(struct cnh_usbhook_irp *irp) { - int res; + int res; - assert(irp != NULL); + assert(irp != NULL); - res = _cnh_usbhook_real_set_altinterface(irp->handle, irp->set_altinterface); + res = _cnh_usbhook_real_set_altinterface(irp->handle, irp->set_altinterface); - if (res < 0) { - return cnh_errno_to_result(res); - } + if (res < 0) { + return cnh_errno_to_result(res); + } - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } -static enum cnh_result _cnh_usbhook_invoke_real_set_configuration(struct cnh_usbhook_irp* irp) +static enum cnh_result +_cnh_usbhook_invoke_real_set_configuration(struct cnh_usbhook_irp *irp) { - int res; + int res; - assert(irp != NULL); + assert(irp != NULL); - res = _cnh_usbhook_real_set_configuration(irp->handle, irp->set_configuration); + res = + _cnh_usbhook_real_set_configuration(irp->handle, irp->set_configuration); - if (res < 0) { - return cnh_errno_to_result(res); - } + if (res < 0) { + return cnh_errno_to_result(res); + } - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } -static enum cnh_result _cnh_usbhook_invoke_real_claim_interface(struct cnh_usbhook_irp* irp) +static enum cnh_result +_cnh_usbhook_invoke_real_claim_interface(struct cnh_usbhook_irp *irp) { - int res; + int res; - assert(irp != NULL); + assert(irp != NULL); - res = _cnh_usbhook_real_claim_interface(irp->handle, irp->claim_interface); + res = _cnh_usbhook_real_claim_interface(irp->handle, irp->claim_interface); - if (res < 0) { - return cnh_errno_to_result(res); - } + if (res < 0) { + return cnh_errno_to_result(res); + } - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } -static enum cnh_result _cnh_usbhook_invoke_real_ctrl_msg(struct cnh_usbhook_irp* irp) +static enum cnh_result +_cnh_usbhook_invoke_real_ctrl_msg(struct cnh_usbhook_irp *irp) { - int res; + int res; - assert(irp != NULL); + assert(irp != NULL); - res = _cnh_usbhook_real_control_msg(irp->handle, irp->ctrl_req_type, irp->ctrl_req, irp->ctrl_value, - irp->ctrl_index, (char*) irp->ctrl_buffer.bytes, irp->ctrl_buffer.nbytes, irp->ctrl_timeout); + res = _cnh_usbhook_real_control_msg( + irp->handle, + irp->ctrl_req_type, + irp->ctrl_req, + irp->ctrl_value, + irp->ctrl_index, + (char *) irp->ctrl_buffer.bytes, + irp->ctrl_buffer.nbytes, + irp->ctrl_timeout); - irp->ctrl_buffer.pos = 0; + irp->ctrl_buffer.pos = 0; - if (res < 0) { - return cnh_errno_to_result(res); - } + if (res < 0) { + return cnh_errno_to_result(res); + } - irp->ctrl_buffer.pos = (size_t) res; + irp->ctrl_buffer.pos = (size_t) res; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } \ No newline at end of file diff --git a/src/main/capnhook/hook/usbhook.h b/src/main/capnhook/hook/usbhook.h index 94700f4..2067b79 100644 --- a/src/main/capnhook/hook/usbhook.h +++ b/src/main/capnhook/hook/usbhook.h @@ -15,37 +15,37 @@ * Available operations to hook */ enum cnh_usbhook_irp_op { - CNH_USBHOOK_IRP_OP_INIT = 0, - CNH_USBHOOK_IRP_OP_FIND_BUSSES = 1, - CNH_USBHOOK_IRP_OP_FIND_DEVICES = 2, - CNH_USBHOOK_IRP_OP_OPEN = 3, - CNH_USBHOOK_IRP_OP_CLOSE = 4, - CNH_USBHOOK_IRP_OP_RESET = 5, - CNH_USBHOOK_IRP_OP_SET_ALTINTERFACE = 6, - CNH_USBHOOK_IRP_OP_SET_CONFIGURATION = 7, - CNH_USBHOOK_IRP_OP_CLAIM_INTERFACE = 8, - CNH_USBHOOK_IRP_OP_CTRL_MSG = 9 + CNH_USBHOOK_IRP_OP_INIT = 0, + CNH_USBHOOK_IRP_OP_FIND_BUSSES = 1, + CNH_USBHOOK_IRP_OP_FIND_DEVICES = 2, + CNH_USBHOOK_IRP_OP_OPEN = 3, + CNH_USBHOOK_IRP_OP_CLOSE = 4, + CNH_USBHOOK_IRP_OP_RESET = 5, + CNH_USBHOOK_IRP_OP_SET_ALTINTERFACE = 6, + CNH_USBHOOK_IRP_OP_SET_CONFIGURATION = 7, + CNH_USBHOOK_IRP_OP_CLAIM_INTERFACE = 8, + CNH_USBHOOK_IRP_OP_CTRL_MSG = 9 }; /** * I/O request packet */ struct cnh_usbhook_irp { - enum cnh_usbhook_irp_op op; - size_t next_handler; - int find_busses_res_num_busses; - int find_devices_res_num_devices; - struct usb_device* open_usb_dev; - usb_dev_handle* handle; - int set_altinterface; - int set_configuration; - int claim_interface; - int ctrl_req_type; - int ctrl_req; - int ctrl_value; - int ctrl_index; - struct cnh_iobuf ctrl_buffer; - int ctrl_timeout; + enum cnh_usbhook_irp_op op; + size_t next_handler; + int find_busses_res_num_busses; + int find_devices_res_num_devices; + struct usb_device *open_usb_dev; + usb_dev_handle *handle; + int set_altinterface; + int set_configuration; + int claim_interface; + int ctrl_req_type; + int ctrl_req; + int ctrl_value; + int ctrl_index; + struct cnh_iobuf ctrl_buffer; + int ctrl_timeout; }; /** @@ -90,6 +90,7 @@ enum cnh_result cnh_usbhook_invoke_next(struct cnh_usbhook_irp *irp); * @param irp I/O request package to dispatch * @return Result of the following function dispatching the request package */ -enum cnh_result cnh_usbhook_invoke_next_reset_advance(struct cnh_usbhook_irp *irp); +enum cnh_result +cnh_usbhook_invoke_next_reset_advance(struct cnh_usbhook_irp *irp); #endif diff --git a/src/main/capnhook/hooklib/filehook-mon.c b/src/main/capnhook/hooklib/filehook-mon.c index 63aec36..fe41a77 100644 --- a/src/main/capnhook/hooklib/filehook-mon.c +++ b/src/main/capnhook/hooklib/filehook-mon.c @@ -4,54 +4,96 @@ #include "util/log.h" -static const char* _cnh_filehook_mon_str_empty = ""; -static const char* _cnh_filehook_mon_irp_op_str[] = { - "fopen", - "fclose", - "fread", - "fwrite", - "fgets", - "fseek", - "ftell", - "feof" -}; +static const char *_cnh_filehook_mon_str_empty = ""; +static const char *_cnh_filehook_mon_irp_op_str[] = { + "fopen", "fclose", "fread", "fwrite", "fgets", "fseek", "ftell", "feof"}; enum cnh_result cnh_filehook_mon(struct cnh_filehook_irp *irp) { - enum cnh_result result; + enum cnh_result result; - /* Skip writes to log file because this results in infinite recursion */ - if (irp->file == util_log_get_file_handle()) { - return cnh_filehook_invoke_next(irp); - } + /* Skip writes to log file because this results in infinite recursion */ + if (irp->file == util_log_get_file_handle()) { + return cnh_filehook_invoke_next(irp); + } - log_debug("[before][%s] next_handler %d, file %p, open_filename %s, open_mode %s, read(bytes %p, nbytes %d, pos %d)" - ", write(bytes %p, nbytes %d, pos %d), orig_read_write_size %d, orig_read_write_nmemb %d, seek_origin %d, " - "seek_offset %d, tell_offset %llu, eof %d", _cnh_filehook_mon_irp_op_str[irp->op], irp->next_handler, - irp->file, irp->open_filename ? irp->open_filename : _cnh_filehook_mon_str_empty, - irp->open_mode ? irp->open_mode : _cnh_filehook_mon_str_empty, irp->read.bytes, irp->read.nbytes, - irp->read.pos, irp->write.bytes, irp->write.nbytes, irp->write.pos, irp->orig_read_write_size, - irp->orig_read_write_nmemb, irp->seek_origin, irp->seek_offset, irp->tell_offset, irp->eof); + log_debug( + "[before][%s] next_handler %d, file %p, open_filename %s, open_mode %s, " + "read(bytes %p, nbytes %d, pos %d)" + ", write(bytes %p, nbytes %d, pos %d), orig_read_write_size %d, " + "orig_read_write_nmemb %d, seek_origin %d, " + "seek_offset %d, tell_offset %llu, eof %d", + _cnh_filehook_mon_irp_op_str[irp->op], + irp->next_handler, + irp->file, + irp->open_filename ? irp->open_filename : _cnh_filehook_mon_str_empty, + irp->open_mode ? irp->open_mode : _cnh_filehook_mon_str_empty, + irp->read.bytes, + irp->read.nbytes, + irp->read.pos, + irp->write.bytes, + irp->write.nbytes, + irp->write.pos, + irp->orig_read_write_size, + irp->orig_read_write_nmemb, + irp->seek_origin, + irp->seek_offset, + irp->tell_offset, + irp->eof); - result = cnh_filehook_invoke_next(irp); + result = cnh_filehook_invoke_next(irp); - if (result != CNH_RESULT_SUCCESS) { - log_error("[after][%s] result %d, next_handler %d, file %p, open_filename %s, open_mode %s, read(bytes %p, " - "nbytes %d, pos %d), write(bytes %p, nbytes %d, pos %d), orig_read_write_size %d, orig_read_write_nmemb %d," - " seek_origin %d, seek_offset %d, tell_offset %llu, eof %d", _cnh_filehook_mon_irp_op_str[irp->op], - result, irp->next_handler, irp->file, irp->open_filename ? irp->open_filename : _cnh_filehook_mon_str_empty, - irp->open_mode ? irp->open_mode : _cnh_filehook_mon_str_empty, irp->read.bytes, irp->read.nbytes, - irp->read.pos, irp->write.bytes, irp->write.nbytes, irp->write.pos, irp->orig_read_write_size, - irp->orig_read_write_nmemb, irp->seek_origin, irp->seek_offset, irp->tell_offset, irp->eof); - } else { - log_debug("[after][%s] result %d, next_handler %d, file %p, open_filename %s, open_mode %s, read(bytes %p, " - "nbytes %d, pos %d), write(bytes %p, nbytes %d, pos %d), orig_read_write_size %d, orig_read_write_nmemb %d," - " seek_origin %d, seek_offset %d, tell_offset %llu, eof %d", _cnh_filehook_mon_irp_op_str[irp->op], - result, irp->next_handler, irp->file, irp->open_filename ? irp->open_filename : _cnh_filehook_mon_str_empty, - irp->open_mode ? irp->open_mode : _cnh_filehook_mon_str_empty, irp->read.bytes, irp->read.nbytes, - irp->read.pos, irp->write.bytes, irp->write.nbytes, irp->write.pos, irp->orig_read_write_size, - irp->orig_read_write_nmemb, irp->seek_origin, irp->seek_offset, irp->tell_offset, irp->eof); - } + if (result != CNH_RESULT_SUCCESS) { + log_error( + "[after][%s] result %d, next_handler %d, file %p, open_filename %s, " + "open_mode %s, read(bytes %p, " + "nbytes %d, pos %d), write(bytes %p, nbytes %d, pos %d), " + "orig_read_write_size %d, orig_read_write_nmemb %d," + " seek_origin %d, seek_offset %d, tell_offset %llu, eof %d", + _cnh_filehook_mon_irp_op_str[irp->op], + result, + irp->next_handler, + irp->file, + irp->open_filename ? irp->open_filename : _cnh_filehook_mon_str_empty, + irp->open_mode ? irp->open_mode : _cnh_filehook_mon_str_empty, + irp->read.bytes, + irp->read.nbytes, + irp->read.pos, + irp->write.bytes, + irp->write.nbytes, + irp->write.pos, + irp->orig_read_write_size, + irp->orig_read_write_nmemb, + irp->seek_origin, + irp->seek_offset, + irp->tell_offset, + irp->eof); + } else { + log_debug( + "[after][%s] result %d, next_handler %d, file %p, open_filename %s, " + "open_mode %s, read(bytes %p, " + "nbytes %d, pos %d), write(bytes %p, nbytes %d, pos %d), " + "orig_read_write_size %d, orig_read_write_nmemb %d," + " seek_origin %d, seek_offset %d, tell_offset %llu, eof %d", + _cnh_filehook_mon_irp_op_str[irp->op], + result, + irp->next_handler, + irp->file, + irp->open_filename ? irp->open_filename : _cnh_filehook_mon_str_empty, + irp->open_mode ? irp->open_mode : _cnh_filehook_mon_str_empty, + irp->read.bytes, + irp->read.nbytes, + irp->read.pos, + irp->write.bytes, + irp->write.nbytes, + irp->write.pos, + irp->orig_read_write_size, + irp->orig_read_write_nmemb, + irp->seek_origin, + irp->seek_offset, + irp->tell_offset, + irp->eof); + } - return result; + return result; } \ No newline at end of file diff --git a/src/main/capnhook/hooklib/filehook-mon.h b/src/main/capnhook/hooklib/filehook-mon.h index 1299dee..72d3381 100644 --- a/src/main/capnhook/hooklib/filehook-mon.h +++ b/src/main/capnhook/hooklib/filehook-mon.h @@ -1,5 +1,6 @@ /** - * Hook implementation to monitor file related calls, e.g. fopen, fread, fwrite etc. + * Hook implementation to monitor file related calls, e.g. fopen, fread, fwrite + * etc. */ #ifndef CAPNHOOK_FILEHOOK_MON_H #define CAPNHOOK_FILEHOOK_MON_H diff --git a/src/main/capnhook/hooklib/fileopen-mon.c b/src/main/capnhook/hooklib/fileopen-mon.c index 53cb574..f7a3a67 100644 --- a/src/main/capnhook/hooklib/fileopen-mon.c +++ b/src/main/capnhook/hooklib/fileopen-mon.c @@ -6,91 +6,105 @@ enum cnh_result cnh_fileopen_mon_filehook(struct cnh_filehook_irp *irp) { - enum cnh_result result; + enum cnh_result result; - if (irp->op == CNH_FILEHOOK_IRP_OP_OPEN) { - log_debug("[before][fopen]: %s %s", irp->open_filename, irp->open_mode); + if (irp->op == CNH_FILEHOOK_IRP_OP_OPEN) { + log_debug("[before][fopen]: %s %s", irp->open_filename, irp->open_mode); - result = cnh_filehook_invoke_next(irp); + result = cnh_filehook_invoke_next(irp); - log_debug("[after][fopen]: %s %s -> %d (%d)", irp->open_filename, irp->open_mode, irp->file, result); - } else { - result = cnh_filehook_invoke_next(irp); - } + log_debug( + "[after][fopen]: %s %s -> %d (%d)", + irp->open_filename, + irp->open_mode, + irp->file, + result); + } else { + result = cnh_filehook_invoke_next(irp); + } - return result; + return result; } enum cnh_result cnh_fileopen_mon_fshook(struct cnh_fshook_irp *irp) { - enum cnh_result result; + enum cnh_result result; - switch (irp->op) { - case CNH_FSHOOK_IRP_OP_DIR_OPEN: - log_debug("[before][diropen]: %s", irp->opendir_name); - break; - case CNH_FSHOOK_IRP_OP_LXSTAT: - log_debug("[before][lxstat]: %s", irp->xstat_file); - break; - case CNH_FSHOOK_IRP_OP_XSTAT: - log_debug("[before][xstat]: %s", irp->xstat_file); - break; - case CNH_FSHOOK_IRP_OP_RENAME: - log_debug("[before][rename]: %s %s", irp->rename_old, irp->rename_new); - break; - case CNH_FSHOOK_IRP_OP_REMOVE: - log_debug("[before][remove]: %s", irp->remove_pathname); - break; - case CNH_FSHOOK_IRP_OP_ACCESS: - log_debug("[before][access]: %s", irp->access_path); - break; - default: - log_die("Unhandled case: %d", irp->op); - break; - } + switch (irp->op) { + case CNH_FSHOOK_IRP_OP_DIR_OPEN: + log_debug("[before][diropen]: %s", irp->opendir_name); + break; + case CNH_FSHOOK_IRP_OP_LXSTAT: + log_debug("[before][lxstat]: %s", irp->xstat_file); + break; + case CNH_FSHOOK_IRP_OP_XSTAT: + log_debug("[before][xstat]: %s", irp->xstat_file); + break; + case CNH_FSHOOK_IRP_OP_RENAME: + log_debug("[before][rename]: %s %s", irp->rename_old, irp->rename_new); + break; + case CNH_FSHOOK_IRP_OP_REMOVE: + log_debug("[before][remove]: %s", irp->remove_pathname); + break; + case CNH_FSHOOK_IRP_OP_ACCESS: + log_debug("[before][access]: %s", irp->access_path); + break; + default: + log_die("Unhandled case: %d", irp->op); + break; + } - result = cnh_fshook_invoke_next(irp); + result = cnh_fshook_invoke_next(irp); - switch (irp->op) { - case CNH_FSHOOK_IRP_OP_DIR_OPEN: - log_debug("[after][diropen]: %s -> %d", irp->opendir_name, result); - break; - case CNH_FSHOOK_IRP_OP_LXSTAT: - log_debug("[after][lxstat]: %s -> %d", irp->xstat_file, result); - break; - case CNH_FSHOOK_IRP_OP_XSTAT: - log_debug("[after][xstat]: %s -> %d", irp->xstat_file, result); - break; - case CNH_FSHOOK_IRP_OP_RENAME: - log_debug("[after][rename]: %s %s -> %d", irp->rename_old, irp->rename_new, result); - break; - case CNH_FSHOOK_IRP_OP_REMOVE: - log_debug("[after][remove]: %s -> %d", irp->remove_pathname, result); - break; - case CNH_FSHOOK_IRP_OP_ACCESS: - log_debug("[after][access]: %s -> %d", irp->access_path, result); - break; - default: - log_die("Unhandled case: %d", irp->op); - break; - } + switch (irp->op) { + case CNH_FSHOOK_IRP_OP_DIR_OPEN: + log_debug("[after][diropen]: %s -> %d", irp->opendir_name, result); + break; + case CNH_FSHOOK_IRP_OP_LXSTAT: + log_debug("[after][lxstat]: %s -> %d", irp->xstat_file, result); + break; + case CNH_FSHOOK_IRP_OP_XSTAT: + log_debug("[after][xstat]: %s -> %d", irp->xstat_file, result); + break; + case CNH_FSHOOK_IRP_OP_RENAME: + log_debug( + "[after][rename]: %s %s -> %d", + irp->rename_old, + irp->rename_new, + result); + break; + case CNH_FSHOOK_IRP_OP_REMOVE: + log_debug("[after][remove]: %s -> %d", irp->remove_pathname, result); + break; + case CNH_FSHOOK_IRP_OP_ACCESS: + log_debug("[after][access]: %s -> %d", irp->access_path, result); + break; + default: + log_die("Unhandled case: %d", irp->op); + break; + } - return result; + return result; } enum cnh_result cnh_fileopen_mon_iohook(struct cnh_iohook_irp *irp) { - enum cnh_result result; + enum cnh_result result; - if (irp->op == CNH_IOHOOK_IRP_OP_OPEN) { - log_debug("[before][open]: %s %d", irp->open_filename, irp->open_flags); + if (irp->op == CNH_IOHOOK_IRP_OP_OPEN) { + log_debug("[before][open]: %s %d", irp->open_filename, irp->open_flags); - result = cnh_iohook_invoke_next(irp); + result = cnh_iohook_invoke_next(irp); - log_debug("[after][open]: %s %d -> %d (%d)", irp->open_filename, irp->open_flags, irp->fd, result); - } else { - result = cnh_iohook_invoke_next(irp); - } + log_debug( + "[after][open]: %s %d -> %d (%d)", + irp->open_filename, + irp->open_flags, + irp->fd, + result); + } else { + result = cnh_iohook_invoke_next(irp); + } - return result; + return result; } \ No newline at end of file diff --git a/src/main/capnhook/hooklib/fileopen-mon.h b/src/main/capnhook/hooklib/fileopen-mon.h index bebc145..edabb2d 100644 --- a/src/main/capnhook/hooklib/fileopen-mon.h +++ b/src/main/capnhook/hooklib/fileopen-mon.h @@ -9,7 +9,8 @@ #include "capnhook/hook/iohook.h" /** - * Hook function to add to the hook module for monitoring open file calls on file operations + * Hook function to add to the hook module for monitoring open file calls on + * file operations * * @param irp I/O request package of hook module received * @return Result of operation @@ -17,7 +18,8 @@ enum cnh_result cnh_fileopen_mon_filehook(struct cnh_filehook_irp *irp); /** - * Hook function to add to the hook module for monitoring open file calls on file system related operations + * Hook function to add to the hook module for monitoring open file calls on + * file system related operations * * @param irp I/O request package of hook module received * @return Result of operation @@ -25,7 +27,8 @@ enum cnh_result cnh_fileopen_mon_filehook(struct cnh_filehook_irp *irp); enum cnh_result cnh_fileopen_mon_fshook(struct cnh_fshook_irp *irp); /** - * Hook function to add to the hook module for monitoring open file/device calls on I/O operations + * Hook function to add to the hook module for monitoring open file/device calls + * on I/O operations * * @param irp I/O request package of hook module received * @return Result of operation diff --git a/src/main/capnhook/hooklib/fshook-mon.c b/src/main/capnhook/hooklib/fshook-mon.c index 26b30a2..7f8a363 100644 --- a/src/main/capnhook/hooklib/fshook-mon.c +++ b/src/main/capnhook/hooklib/fshook-mon.c @@ -4,40 +4,74 @@ #include "util/log.h" -static const char* _cnh_fshook_mon_irp_op_str[] = { - "diropen", - "lxstat", - "xstat", - "rename", - "remove", - "access" -}; +static const char *_cnh_fshook_mon_irp_op_str[] = { + "diropen", "lxstat", "xstat", "rename", "remove", "access"}; enum cnh_result cnh_fshook_mon(struct cnh_fshook_irp *irp) { - enum cnh_result result; + enum cnh_result result; - log_debug("[before][%s] next_handler %d, opendir_name %s, opendir_ret %p, xstat_version %d, xstat_file %s, " - "xstat_buf %p, rename_old %s, rename_new %s, remove_pathname %s, access_path %s, access_amode %d", - _cnh_fshook_mon_irp_op_str[irp->op], irp->next_handler, irp->opendir_name, irp->opendir_ret, - irp->xstat_version, irp->xstat_file, irp->xstat_buf, irp->rename_old, irp->rename_new, irp->remove_pathname, - irp->access_path, irp->access_amode); + log_debug( + "[before][%s] next_handler %d, opendir_name %s, opendir_ret %p, " + "xstat_version %d, xstat_file %s, " + "xstat_buf %p, rename_old %s, rename_new %s, remove_pathname %s, " + "access_path %s, access_amode %d", + _cnh_fshook_mon_irp_op_str[irp->op], + irp->next_handler, + irp->opendir_name, + irp->opendir_ret, + irp->xstat_version, + irp->xstat_file, + irp->xstat_buf, + irp->rename_old, + irp->rename_new, + irp->remove_pathname, + irp->access_path, + irp->access_amode); - result = cnh_fshook_invoke_next(irp); + result = cnh_fshook_invoke_next(irp); - if (result != CNH_RESULT_SUCCESS) { - log_error("[before][%s] result %d, next_handler %d, opendir_name %s, opendir_ret %p, xstat_version %d, " - "xstat_file %s, xstat_buf %p, rename_old %s, rename_new %s, remove_pathname %s, access_path %s, " - "access_amode %d", _cnh_fshook_mon_irp_op_str[irp->op], result, irp->next_handler, irp->opendir_name, - irp->opendir_ret, irp->xstat_version, irp->xstat_file, irp->xstat_buf, irp->rename_old, irp->rename_new, - irp->remove_pathname, irp->access_path, irp->access_amode); - } else { - log_debug("[before][%s] result %d, next_handler %d, opendir_name %s, opendir_ret %p, xstat_version %d, " - "xstat_file %s, xstat_buf %p, rename_old %s, rename_new %s, remove_pathname %s, access_path %s, " - "access_amode %d", _cnh_fshook_mon_irp_op_str[irp->op], result, irp->next_handler, irp->opendir_name, - irp->opendir_ret, irp->xstat_version, irp->xstat_file, irp->xstat_buf, irp->rename_old, irp->rename_new, - irp->remove_pathname, irp->access_path, irp->access_amode); - } + if (result != CNH_RESULT_SUCCESS) { + log_error( + "[before][%s] result %d, next_handler %d, opendir_name %s, opendir_ret " + "%p, xstat_version %d, " + "xstat_file %s, xstat_buf %p, rename_old %s, rename_new %s, " + "remove_pathname %s, access_path %s, " + "access_amode %d", + _cnh_fshook_mon_irp_op_str[irp->op], + result, + irp->next_handler, + irp->opendir_name, + irp->opendir_ret, + irp->xstat_version, + irp->xstat_file, + irp->xstat_buf, + irp->rename_old, + irp->rename_new, + irp->remove_pathname, + irp->access_path, + irp->access_amode); + } else { + log_debug( + "[before][%s] result %d, next_handler %d, opendir_name %s, opendir_ret " + "%p, xstat_version %d, " + "xstat_file %s, xstat_buf %p, rename_old %s, rename_new %s, " + "remove_pathname %s, access_path %s, " + "access_amode %d", + _cnh_fshook_mon_irp_op_str[irp->op], + result, + irp->next_handler, + irp->opendir_name, + irp->opendir_ret, + irp->xstat_version, + irp->xstat_file, + irp->xstat_buf, + irp->rename_old, + irp->rename_new, + irp->remove_pathname, + irp->access_path, + irp->access_amode); + } - return result; + return result; } \ No newline at end of file diff --git a/src/main/capnhook/hooklib/fshook-mon.h b/src/main/capnhook/hooklib/fshook-mon.h index 5a5e8e2..b4fe3e7 100644 --- a/src/main/capnhook/hooklib/fshook-mon.h +++ b/src/main/capnhook/hooklib/fshook-mon.h @@ -7,7 +7,8 @@ #include "capnhook/hook/fshook.h" /** - * Hook function to add to the hook module for monitoring file system related calls + * Hook function to add to the hook module for monitoring file system related + * calls * * @param irp I/O request package of hook module received * @return Result of operation diff --git a/src/main/capnhook/hooklib/iohook-mon.c b/src/main/capnhook/hooklib/iohook-mon.c index 9b617a7..fca290a 100644 --- a/src/main/capnhook/hooklib/iohook-mon.c +++ b/src/main/capnhook/hooklib/iohook-mon.c @@ -4,51 +4,106 @@ #include "util/log.h" -static const char* _cnh_iohook_mon_str_empty = ""; -static const char* _cnh_iohook_mon_irp_op_str[] = { - "open", - "fdopen", - "close", - "read", - "write", - "seek", - "ioctl" -}; +static const char *_cnh_iohook_mon_str_empty = ""; +static const char *_cnh_iohook_mon_irp_op_str[] = { + "open", "fdopen", "close", "read", "write", "seek", "ioctl"}; enum cnh_result cnh_iohook_mon(struct cnh_iohook_irp *irp) { - enum cnh_result result; + enum cnh_result result; - log_debug("[before][%s] next_handler %d, fd %d, open_filename %s, open_flags %d, fdopen_fd %d, fdopen_mode %s, " - "fdopen_res %p, read(bytes %p, nbytes %d, pos %d), write(bytes %p, nbytes %d, pos %d), seek_origin %d, " - "seek_offset %d, seek_pos %llu, ioctl_req %d, ioctl(bytes %p, nbytes %d, pos %d)", - _cnh_iohook_mon_irp_op_str[irp->op], irp->next_handler, irp->fd, - irp->open_filename ? irp->open_filename : _cnh_iohook_mon_str_empty, irp->open_flags, irp->fdopen_fd, - irp->fdopen_mode ? irp->fdopen_mode : _cnh_iohook_mon_str_empty, irp->fdopen_res, irp->read.bytes, - irp->read.nbytes, irp->read.pos, irp->write.bytes, irp->write.nbytes, irp->write.pos, irp->seek_origin, - irp->seek_offset, irp->seek_pos, irp->ioctl_req, irp->ioctl.bytes, irp->ioctl.nbytes, irp->ioctl.pos); + log_debug( + "[before][%s] next_handler %d, fd %d, open_filename %s, open_flags %d, " + "fdopen_fd %d, fdopen_mode %s, " + "fdopen_res %p, read(bytes %p, nbytes %d, pos %d), write(bytes %p, " + "nbytes %d, pos %d), seek_origin %d, " + "seek_offset %d, seek_pos %llu, ioctl_req %d, ioctl(bytes %p, nbytes %d, " + "pos %d)", + _cnh_iohook_mon_irp_op_str[irp->op], + irp->next_handler, + irp->fd, + irp->open_filename ? irp->open_filename : _cnh_iohook_mon_str_empty, + irp->open_flags, + irp->fdopen_fd, + irp->fdopen_mode ? irp->fdopen_mode : _cnh_iohook_mon_str_empty, + irp->fdopen_res, + irp->read.bytes, + irp->read.nbytes, + irp->read.pos, + irp->write.bytes, + irp->write.nbytes, + irp->write.pos, + irp->seek_origin, + irp->seek_offset, + irp->seek_pos, + irp->ioctl_req, + irp->ioctl.bytes, + irp->ioctl.nbytes, + irp->ioctl.pos); - result = cnh_iohook_invoke_next(irp); + result = cnh_iohook_invoke_next(irp); - if (result != CNH_RESULT_SUCCESS) { - log_error("[after][%s] next_handler %d, res: %d, fd %d, open_filename %s, open_flags %d, fdopen_fd %d, " - "fdopen_mode %s, fdopen_res %p, read(bytes %p, nbytes %d, pos %d), write(bytes %p, nbytes %d, pos %d), " - "seek_origin %d, seek_offset %d, seek_pos %llu, ioctl_req %d, ioctl(bytes %p, nbytes %d, pos %d)", - _cnh_iohook_mon_irp_op_str[irp->op], irp->next_handler, result, irp->fd, - irp->open_filename ? irp->open_filename : _cnh_iohook_mon_str_empty, irp->open_flags, irp->fdopen_fd, - irp->fdopen_mode ? irp->fdopen_mode : _cnh_iohook_mon_str_empty, irp->fdopen_res, irp->read.bytes, - irp->read.nbytes, irp->read.pos, irp->write.bytes, irp->write.nbytes, irp->write.pos, irp->seek_origin, - irp->seek_offset, irp->seek_pos, irp->ioctl_req, irp->ioctl.bytes, irp->ioctl.nbytes, irp->ioctl.pos); - } else { - log_debug("[after][%s] next_handler %d, res %d, fd %d, open_filename %s, open_flags %d, fdopen_fd %d, " - "fdopen_mode %s, fdopen_res %p, read(bytes %p, nbytes %d, pos %d), write(bytes %p, nbytes %d, pos %d), " - "seek_origin %d, seek_offset %d, seek_pos %llu, ioctl_req %d, ioctl(bytes %p, nbytes %d, pos %d)", - _cnh_iohook_mon_irp_op_str[irp->op], irp->next_handler, result, irp->fd, - irp->open_filename ? irp->open_filename : _cnh_iohook_mon_str_empty, irp->open_flags, irp->fdopen_fd, - irp->fdopen_mode ? irp->fdopen_mode : _cnh_iohook_mon_str_empty, irp->fdopen_res, irp->read.bytes, - irp->read.nbytes, irp->read.pos, irp->write.bytes, irp->write.nbytes, irp->write.pos, irp->seek_origin, - irp->seek_offset, irp->seek_pos, irp->ioctl_req, irp->ioctl.bytes, irp->ioctl.nbytes, irp->ioctl.pos); - } + if (result != CNH_RESULT_SUCCESS) { + log_error( + "[after][%s] next_handler %d, res: %d, fd %d, open_filename %s, " + "open_flags %d, fdopen_fd %d, " + "fdopen_mode %s, fdopen_res %p, read(bytes %p, nbytes %d, pos %d), " + "write(bytes %p, nbytes %d, pos %d), " + "seek_origin %d, seek_offset %d, seek_pos %llu, ioctl_req %d, " + "ioctl(bytes %p, nbytes %d, pos %d)", + _cnh_iohook_mon_irp_op_str[irp->op], + irp->next_handler, + result, + irp->fd, + irp->open_filename ? irp->open_filename : _cnh_iohook_mon_str_empty, + irp->open_flags, + irp->fdopen_fd, + irp->fdopen_mode ? irp->fdopen_mode : _cnh_iohook_mon_str_empty, + irp->fdopen_res, + irp->read.bytes, + irp->read.nbytes, + irp->read.pos, + irp->write.bytes, + irp->write.nbytes, + irp->write.pos, + irp->seek_origin, + irp->seek_offset, + irp->seek_pos, + irp->ioctl_req, + irp->ioctl.bytes, + irp->ioctl.nbytes, + irp->ioctl.pos); + } else { + log_debug( + "[after][%s] next_handler %d, res %d, fd %d, open_filename %s, " + "open_flags %d, fdopen_fd %d, " + "fdopen_mode %s, fdopen_res %p, read(bytes %p, nbytes %d, pos %d), " + "write(bytes %p, nbytes %d, pos %d), " + "seek_origin %d, seek_offset %d, seek_pos %llu, ioctl_req %d, " + "ioctl(bytes %p, nbytes %d, pos %d)", + _cnh_iohook_mon_irp_op_str[irp->op], + irp->next_handler, + result, + irp->fd, + irp->open_filename ? irp->open_filename : _cnh_iohook_mon_str_empty, + irp->open_flags, + irp->fdopen_fd, + irp->fdopen_mode ? irp->fdopen_mode : _cnh_iohook_mon_str_empty, + irp->fdopen_res, + irp->read.bytes, + irp->read.nbytes, + irp->read.pos, + irp->write.bytes, + irp->write.nbytes, + irp->write.pos, + irp->seek_origin, + irp->seek_offset, + irp->seek_pos, + irp->ioctl_req, + irp->ioctl.bytes, + irp->ioctl.nbytes, + irp->ioctl.pos); + } - return result; + return result; } \ No newline at end of file diff --git a/src/main/capnhook/hooklib/redir.c b/src/main/capnhook/hooklib/redir.c index 258d6d3..c345b66 100644 --- a/src/main/capnhook/hooklib/redir.c +++ b/src/main/capnhook/hooklib/redir.c @@ -4,17 +4,19 @@ #include #include -#include "capnhook/hook/fshook.h" #include "capnhook/hook/filehook.h" +#include "capnhook/hook/fshook.h" #include "capnhook/hook/iohook.h" #include "util/log.h" #include "util/str.h" #include "util/time.h" -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Hooks to fshook module */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ static enum cnh_result _cnh_redir_fshook_diropen(struct cnh_fshook_irp *irp); static enum cnh_result _cnh_redir_fshook_lxstat(struct cnh_fshook_irp *irp); @@ -32,11 +34,14 @@ static const cnh_fshook_fn_t _cnh_redir_fshook_handlers[6] = { [CNH_FSHOOK_IRP_OP_ACCESS] = _cnh_redir_fshook_access, }; -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Hooks to filehook module */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ -static enum cnh_result _cnh_redir_filehook_default(struct cnh_filehook_irp *irp); +static enum cnh_result +_cnh_redir_filehook_default(struct cnh_filehook_irp *irp); static enum cnh_result _cnh_redir_filehook_fopen(struct cnh_filehook_irp *irp); static const cnh_filehook_fn_t _cnh_redir_filehook_handlers[8] = { @@ -50,9 +55,11 @@ static const cnh_filehook_fn_t _cnh_redir_filehook_handlers[8] = { [CNH_FILEHOOK_IRP_OP_EOF] = _cnh_redir_filehook_default, }; -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Hooks to iohook module */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ static enum cnh_result _cnh_redir_iohook_default(struct cnh_iohook_irp *irp); static enum cnh_result _cnh_redir_iohook_open(struct cnh_iohook_irp *irp); @@ -67,305 +74,320 @@ static const cnh_iohook_fn_t _cnh_redir_iohook_handlers[7] = { [CNH_IOHOOK_IRP_OP_IOCTL] = _cnh_redir_iohook_default, }; -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Private state */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ struct cnh_redir_redir { - char* src; - char* dest; + char *src; + char *dest; }; static atomic_int _cnh_redir_initted = ATOMIC_VAR_INIT(0); static atomic_int _cnh_redir_init_in_progress = ATOMIC_VAR_INIT(0); static pthread_mutex_t _cnh_redir_lock; -static struct cnh_redir_redir* _cnh_redir_redirs; +static struct cnh_redir_redir *_cnh_redir_redirs; static size_t _cnh_redir_nredirs; static void _cnh_redir_init(); -static char* _cnh_redir_check(const char* src); +static char *_cnh_redir_check(const char *src); -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Public module functions */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ -void cnh_redir_add(const char* src, const char* dest) +void cnh_redir_add(const char *src, const char *dest) { - struct cnh_redir_redir *new_array; - size_t new_size; + struct cnh_redir_redir *new_array; + size_t new_size; - assert(src != NULL); - assert(dest != NULL); + assert(src != NULL); + assert(dest != NULL); - /* Ensure module is initialized */ - _cnh_redir_init(); + /* Ensure module is initialized */ + _cnh_redir_init(); - pthread_mutex_lock(&_cnh_redir_lock); + pthread_mutex_lock(&_cnh_redir_lock); - new_size = _cnh_redir_nredirs + 1; - new_array = realloc(_cnh_redir_redirs, new_size * sizeof(struct cnh_redir_redir)); + new_size = _cnh_redir_nredirs + 1; + new_array = + realloc(_cnh_redir_redirs, new_size * sizeof(struct cnh_redir_redir)); - if (new_array != NULL) { - _cnh_redir_redirs = new_array; - } + if (new_array != NULL) { + _cnh_redir_redirs = new_array; + } - _cnh_redir_redirs[_cnh_redir_nredirs].src = util_str_dup(src); - _cnh_redir_redirs[_cnh_redir_nredirs].dest = util_str_dup(dest); + _cnh_redir_redirs[_cnh_redir_nredirs].src = util_str_dup(src); + _cnh_redir_redirs[_cnh_redir_nredirs].dest = util_str_dup(dest); - _cnh_redir_nredirs++; + _cnh_redir_nredirs++; - pthread_mutex_unlock(&_cnh_redir_lock); + pthread_mutex_unlock(&_cnh_redir_lock); - log_info("Added path redirect %s -> %s", src, dest); + log_info("Added path redirect %s -> %s", src, dest); } -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Hooks to fshook module */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ -enum cnh_result cnh_redir_fshook(struct cnh_fshook_irp* irp) +enum cnh_result cnh_redir_fshook(struct cnh_fshook_irp *irp) { - cnh_fshook_fn_t handler; + cnh_fshook_fn_t handler; - handler = _cnh_redir_fshook_handlers[irp->op]; + handler = _cnh_redir_fshook_handlers[irp->op]; - assert(handler != NULL); + assert(handler != NULL); - return handler(irp); + return handler(irp); } static enum cnh_result _cnh_redir_fshook_diropen(struct cnh_fshook_irp *irp) { - char* res; + char *res; - /* Ensure module is initialized */ - _cnh_redir_init(); + /* Ensure module is initialized */ + _cnh_redir_init(); - res = _cnh_redir_check(irp->opendir_name); + res = _cnh_redir_check(irp->opendir_name); - if (res != NULL) { - irp->opendir_name = res; - } + if (res != NULL) { + irp->opendir_name = res; + } - return cnh_fshook_invoke_next(irp); + return cnh_fshook_invoke_next(irp); } static enum cnh_result _cnh_redir_fshook_lxstat(struct cnh_fshook_irp *irp) { - char* res; + char *res; - /* Ensure module is initialized */ - _cnh_redir_init(); + /* Ensure module is initialized */ + _cnh_redir_init(); - res = _cnh_redir_check(irp->xstat_file); + res = _cnh_redir_check(irp->xstat_file); - if (res != NULL) { - irp->xstat_file = res; - } + if (res != NULL) { + irp->xstat_file = res; + } - return cnh_fshook_invoke_next(irp); + return cnh_fshook_invoke_next(irp); } static enum cnh_result _cnh_redir_fshook_xstat(struct cnh_fshook_irp *irp) { - char* res; + char *res; - /* Ensure module is initialized */ - _cnh_redir_init(); + /* Ensure module is initialized */ + _cnh_redir_init(); - res = _cnh_redir_check(irp->xstat_file); + res = _cnh_redir_check(irp->xstat_file); - if (res != NULL) { - irp->xstat_file = res; - } + if (res != NULL) { + irp->xstat_file = res; + } - return cnh_fshook_invoke_next(irp); + return cnh_fshook_invoke_next(irp); } static enum cnh_result _cnh_redir_fshook_rename(struct cnh_fshook_irp *irp) { - char* res_old; - char* res_new; + char *res_old; + char *res_new; - /* Ensure module is initialized */ - _cnh_redir_init(); + /* Ensure module is initialized */ + _cnh_redir_init(); - res_old = _cnh_redir_check(irp->rename_old); - res_new = _cnh_redir_check(irp->rename_old); + res_old = _cnh_redir_check(irp->rename_old); + res_new = _cnh_redir_check(irp->rename_old); - if (res_old != NULL) { - irp->rename_old = res_old; - } + if (res_old != NULL) { + irp->rename_old = res_old; + } - if (res_new != NULL) { - irp->rename_new = res_new; - } + if (res_new != NULL) { + irp->rename_new = res_new; + } - return cnh_fshook_invoke_next(irp); + return cnh_fshook_invoke_next(irp); } static enum cnh_result _cnh_redir_fshook_remove(struct cnh_fshook_irp *irp) { - char* res; + char *res; - /* Ensure module is initialized */ - _cnh_redir_init(); + /* Ensure module is initialized */ + _cnh_redir_init(); - res = _cnh_redir_check(irp->remove_pathname); + res = _cnh_redir_check(irp->remove_pathname); - if (res != NULL) { - irp->remove_pathname = res; - } + if (res != NULL) { + irp->remove_pathname = res; + } - return cnh_fshook_invoke_next(irp); + return cnh_fshook_invoke_next(irp); } static enum cnh_result _cnh_redir_fshook_access(struct cnh_fshook_irp *irp) { - char* res; + char *res; - /* Ensure module is initialized */ - _cnh_redir_init(); + /* Ensure module is initialized */ + _cnh_redir_init(); - res = _cnh_redir_check(irp->access_path); + res = _cnh_redir_check(irp->access_path); - if (res != NULL) { - irp->access_path = res; - } + if (res != NULL) { + irp->access_path = res; + } - return cnh_fshook_invoke_next(irp); + return cnh_fshook_invoke_next(irp); } -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Hooks to iohook module */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ -enum cnh_result cnh_redir_iohook(struct cnh_iohook_irp* irp) +enum cnh_result cnh_redir_iohook(struct cnh_iohook_irp *irp) { - cnh_iohook_fn_t handler; + cnh_iohook_fn_t handler; - handler = _cnh_redir_iohook_handlers[irp->op]; + handler = _cnh_redir_iohook_handlers[irp->op]; - assert(handler != NULL); + assert(handler != NULL); - return handler(irp); + return handler(irp); } static enum cnh_result _cnh_redir_iohook_default(struct cnh_iohook_irp *irp) { - return cnh_iohook_invoke_next(irp); + return cnh_iohook_invoke_next(irp); } static enum cnh_result _cnh_redir_iohook_open(struct cnh_iohook_irp *irp) { - char* res; + char *res; - /* Ensure module is initialized */ - _cnh_redir_init(); + /* Ensure module is initialized */ + _cnh_redir_init(); - res = _cnh_redir_check(irp->open_filename); + res = _cnh_redir_check(irp->open_filename); - if (res != NULL) { - irp->open_filename = res; - } + if (res != NULL) { + irp->open_filename = res; + } - return cnh_iohook_invoke_next(irp); + return cnh_iohook_invoke_next(irp); } -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Hooks to filehook module */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ -enum cnh_result cnh_redir_filehook(struct cnh_filehook_irp* irp) +enum cnh_result cnh_redir_filehook(struct cnh_filehook_irp *irp) { - cnh_filehook_fn_t handler; + cnh_filehook_fn_t handler; - handler = _cnh_redir_filehook_handlers[irp->op]; + handler = _cnh_redir_filehook_handlers[irp->op]; - assert(handler != NULL); + assert(handler != NULL); - return handler(irp); + return handler(irp); } static enum cnh_result _cnh_redir_filehook_default(struct cnh_filehook_irp *irp) { - return cnh_filehook_invoke_next(irp); + return cnh_filehook_invoke_next(irp); } static enum cnh_result _cnh_redir_filehook_fopen(struct cnh_filehook_irp *irp) { - char* res; + char *res; - /* Ensure module is initialized */ - _cnh_redir_init(); + /* Ensure module is initialized */ + _cnh_redir_init(); - res = _cnh_redir_check(irp->open_filename); + res = _cnh_redir_check(irp->open_filename); - if (res != NULL) { - irp->open_filename = res; - } + if (res != NULL) { + irp->open_filename = res; + } - return cnh_filehook_invoke_next(irp); + return cnh_filehook_invoke_next(irp); } -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Helper functions */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ static void _cnh_redir_init() { - int expected; + int expected; - if (atomic_load(&_cnh_redir_initted) > 0) { - return; + if (atomic_load(&_cnh_redir_initted) > 0) { + return; + } + + expected = 0; + + if (!atomic_compare_exchange_strong( + &_cnh_redir_init_in_progress, &expected, 1)) { + while (atomic_load(&_cnh_redir_init_in_progress) > 1) { + util_time_sleep_us(100); } - expected = 0; + return; + } - if (!atomic_compare_exchange_strong(&_cnh_redir_init_in_progress, &expected, 1)) { - while (atomic_load(&_cnh_redir_init_in_progress) > 1) { - util_time_sleep_us(100); - } - - return; - } - - /* Check again to ensure the current thread yielded between the init'd check and setting init in progress */ - if (atomic_load(&_cnh_redir_initted) > 0) { - /* Revert init in progress, because nothing to do anymore */ - atomic_store(&_cnh_redir_init_in_progress, 0); - return; - } - - pthread_mutex_init(&_cnh_redir_lock, NULL); - - atomic_store(&_cnh_redir_initted, 1); + /* Check again to ensure the current thread yielded between the init'd check + * and setting init in progress */ + if (atomic_load(&_cnh_redir_initted) > 0) { + /* Revert init in progress, because nothing to do anymore */ atomic_store(&_cnh_redir_init_in_progress, 0); + return; + } + + pthread_mutex_init(&_cnh_redir_lock, NULL); + + atomic_store(&_cnh_redir_initted, 1); + atomic_store(&_cnh_redir_init_in_progress, 0); } -static char* _cnh_redir_check(const char* src) +static char *_cnh_redir_check(const char *src) { - const char* redir_src; - const char* redir_dest; - char* res; + const char *redir_src; + const char *redir_dest; + char *res; - res = NULL; + res = NULL; - pthread_mutex_lock(&_cnh_redir_lock); + pthread_mutex_lock(&_cnh_redir_lock); - for (size_t i = 0; i < _cnh_redir_nredirs; i++) { - redir_src = _cnh_redir_redirs[i].src; - redir_dest = _cnh_redir_redirs[i].dest; + for (size_t i = 0; i < _cnh_redir_nredirs; i++) { + redir_src = _cnh_redir_redirs[i].src; + redir_dest = _cnh_redir_redirs[i].dest; - if (strncmp(src, redir_src, strlen(redir_src)) == 0) { - // FIXME memory leak - res = util_str_merge(redir_dest, &src[strlen(redir_src)]); - log_debug("Redirect %s -> %s", src, res); - break; - } + if (strncmp(src, redir_src, strlen(redir_src)) == 0) { + // FIXME memory leak + res = util_str_merge(redir_dest, &src[strlen(redir_src)]); + log_debug("Redirect %s -> %s", src, res); + break; } + } - pthread_mutex_unlock(&_cnh_redir_lock); + pthread_mutex_unlock(&_cnh_redir_lock); - return res; + return res; } \ No newline at end of file diff --git a/src/main/capnhook/hooklib/redir.h b/src/main/capnhook/hooklib/redir.h index ce55dbd..cb24d5b 100644 --- a/src/main/capnhook/hooklib/redir.h +++ b/src/main/capnhook/hooklib/redir.h @@ -1,29 +1,32 @@ /** - * Hook implementation to redirect files/paths passed as parameters on various file, file system and I/O calls + * Hook implementation to redirect files/paths passed as parameters on various + * file, file system and I/O calls */ #ifndef CAPNHOOK_REDIR_H #define CAPNHOOK_REDIR_H -#include "capnhook/hook/fshook.h" #include "capnhook/hook/filehook.h" +#include "capnhook/hook/fshook.h" #include "capnhook/hook/iohook.h" /** * Add a new path/file redirect to the module * - * @param src Source path/file to redirect. This does not have to match the full path. - * Postfix, e.g. just the filename is sufficient as well - * @param dest Destination to redirect the original path to. Recommended to use absolute paths here. + * @param src Source path/file to redirect. This does not have to match the full + * path. Postfix, e.g. just the filename is sufficient as well + * @param dest Destination to redirect the original path to. Recommended to use + * absolute paths here. */ -void cnh_redir_add(const char* src, const char* dest); +void cnh_redir_add(const char *src, const char *dest); /** - * Hook function to add to the hook module for redirecting file system related calls + * Hook function to add to the hook module for redirecting file system related + * calls * * @param irp I/O request package of hook module received * @return Result of operation */ -enum cnh_result cnh_redir_fshook(struct cnh_fshook_irp* irp); +enum cnh_result cnh_redir_fshook(struct cnh_fshook_irp *irp); /** * Hook function to add to the hook module for redirecting I/O calls @@ -31,7 +34,7 @@ enum cnh_result cnh_redir_fshook(struct cnh_fshook_irp* irp); * @param irp I/O request package of hook module received * @return Result of operation */ -enum cnh_result cnh_redir_iohook(struct cnh_iohook_irp* irp); +enum cnh_result cnh_redir_iohook(struct cnh_iohook_irp *irp); /** * Hook function to add to the hook module for redirecting file related calls @@ -39,6 +42,6 @@ enum cnh_result cnh_redir_iohook(struct cnh_iohook_irp* irp); * @param irp I/O request package of hook module received * @return Result of operation */ -enum cnh_result cnh_redir_filehook(struct cnh_filehook_irp* irp); +enum cnh_result cnh_redir_filehook(struct cnh_filehook_irp *irp); #endif \ No newline at end of file diff --git a/src/main/capnhook/hooklib/usb-emu.c b/src/main/capnhook/hooklib/usb-emu.c index aca314f..29356a5 100644 --- a/src/main/capnhook/hooklib/usb-emu.c +++ b/src/main/capnhook/hooklib/usb-emu.c @@ -10,24 +10,32 @@ #include "util/log.h" #include "util/time.h" -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Private helpers */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ static void _cnh_usb_emu_init(void); -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Hooks to usbhook module */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ -static enum cnh_result _cnh_usb_emu_usbhook_default(struct cnh_usbhook_irp *irp); +static enum cnh_result +_cnh_usb_emu_usbhook_default(struct cnh_usbhook_irp *irp); static enum cnh_result _cnh_usb_emu_usbhook_noop(struct cnh_usbhook_irp *irp); -static enum cnh_result _cnh_usb_emu_usbhook_find_busses(struct cnh_usbhook_irp *irp); -static enum cnh_result _cnh_usb_emu_usbhook_find_devices(struct cnh_usbhook_irp *irp); +static enum cnh_result +_cnh_usb_emu_usbhook_find_busses(struct cnh_usbhook_irp *irp); +static enum cnh_result +_cnh_usb_emu_usbhook_find_devices(struct cnh_usbhook_irp *irp); static enum cnh_result _cnh_usb_emu_usbhook_open(struct cnh_usbhook_irp *irp); static enum cnh_result _cnh_usb_emu_usbhook_close(struct cnh_usbhook_irp *irp); static enum cnh_result _cnh_usb_emu_usbhook_reset(struct cnh_usbhook_irp *irp); -static enum cnh_result _cnh_usb_emu_usbhook_ctrl_msg(struct cnh_usbhook_irp *irp); +static enum cnh_result +_cnh_usb_emu_usbhook_ctrl_msg(struct cnh_usbhook_irp *irp); static const cnh_usbhook_fn_t _cnh_usb_emu_usb_handlers[10] = { [CNH_USBHOOK_IRP_OP_INIT] = _cnh_usb_emu_usbhook_default, @@ -42,19 +50,21 @@ static const cnh_usbhook_fn_t _cnh_usb_emu_usb_handlers[10] = { [CNH_USBHOOK_IRP_OP_CTRL_MSG] = _cnh_usb_emu_usbhook_ctrl_msg, }; -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Private state */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ struct usb_dev_handle { - struct cnh_usb_emu_virtdev* virtdev; + struct cnh_usb_emu_virtdev *virtdev; }; struct cnh_usb_emu_virtdev { - const struct cnh_usb_emu_virtdev_ep* ep; - bool real_dev_avail; - bool enumerated; - struct usb_dev_handle usb_dev_handle; + const struct cnh_usb_emu_virtdev_ep *ep; + bool real_dev_avail; + bool enumerated; + struct usb_dev_handle usb_dev_handle; }; static atomic_int _cnh_usb_emu_initted = ATOMIC_VAR_INIT(0); @@ -63,432 +73,475 @@ static pthread_mutex_t _cnh_usb_emu_virtdevs_lock; static struct cnh_usb_emu_virtdev *_cnh_usb_emu_virtdevs; static size_t _cnh_usb_emu_nvirtdevs; -static struct cnh_usb_emu_virtdev* _cnh_usb_emu_get_virtdev(uint16_t vid, uint16_t pid); -static struct cnh_usb_emu_virtdev* _cnh_usb_emu_get_virtdev_by_handle(usb_dev_handle* handle); -static struct usb_device* _cnh_usb_emu_create_fakedev(uint16_t vid, uint16_t pid); +static struct cnh_usb_emu_virtdev * +_cnh_usb_emu_get_virtdev(uint16_t vid, uint16_t pid); +static struct cnh_usb_emu_virtdev * +_cnh_usb_emu_get_virtdev_by_handle(usb_dev_handle *handle); +static struct usb_device * +_cnh_usb_emu_create_fakedev(uint16_t vid, uint16_t pid); -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Public module functions */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ -void cnh_usb_emu_add_virtdevep(const struct cnh_usb_emu_virtdev_ep* virtdevep) +void cnh_usb_emu_add_virtdevep(const struct cnh_usb_emu_virtdev_ep *virtdevep) { - struct cnh_usb_emu_virtdev *new_array; - size_t new_size; + struct cnh_usb_emu_virtdev *new_array; + size_t new_size; - assert(virtdevep->enumerate); - assert(virtdevep->open); - assert(virtdevep->reset); - assert(virtdevep->control_msg); - assert(virtdevep->close); + assert(virtdevep->enumerate); + assert(virtdevep->open); + assert(virtdevep->reset); + assert(virtdevep->control_msg); + assert(virtdevep->close); - /* Ensure initialized */ - _cnh_usb_emu_init(); + /* Ensure initialized */ + _cnh_usb_emu_init(); - pthread_mutex_lock(&_cnh_usb_emu_virtdevs_lock); + pthread_mutex_lock(&_cnh_usb_emu_virtdevs_lock); - new_size = _cnh_usb_emu_nvirtdevs + 1; - new_array = realloc(_cnh_usb_emu_virtdevs, new_size * sizeof(struct cnh_usb_emu_virtdev)); + new_size = _cnh_usb_emu_nvirtdevs + 1; + new_array = realloc( + _cnh_usb_emu_virtdevs, new_size * sizeof(struct cnh_usb_emu_virtdev)); - if (new_array != NULL) { - _cnh_usb_emu_virtdevs = new_array; + if (new_array != NULL) { + _cnh_usb_emu_virtdevs = new_array; - _cnh_usb_emu_virtdevs[_cnh_usb_emu_nvirtdevs].enumerated = false; - _cnh_usb_emu_virtdevs[_cnh_usb_emu_nvirtdevs].real_dev_avail = false; - _cnh_usb_emu_virtdevs[_cnh_usb_emu_nvirtdevs].ep = virtdevep; - _cnh_usb_emu_virtdevs[_cnh_usb_emu_nvirtdevs].usb_dev_handle.virtdev = &_cnh_usb_emu_virtdevs[_cnh_usb_emu_nvirtdevs]; - _cnh_usb_emu_nvirtdevs++; - } else { - log_die("Out of memory"); - } + _cnh_usb_emu_virtdevs[_cnh_usb_emu_nvirtdevs].enumerated = false; + _cnh_usb_emu_virtdevs[_cnh_usb_emu_nvirtdevs].real_dev_avail = false; + _cnh_usb_emu_virtdevs[_cnh_usb_emu_nvirtdevs].ep = virtdevep; + _cnh_usb_emu_virtdevs[_cnh_usb_emu_nvirtdevs].usb_dev_handle.virtdev = + &_cnh_usb_emu_virtdevs[_cnh_usb_emu_nvirtdevs]; + _cnh_usb_emu_nvirtdevs++; + } else { + log_die("Out of memory"); + } - pthread_mutex_unlock(&_cnh_usb_emu_virtdevs_lock); + pthread_mutex_unlock(&_cnh_usb_emu_virtdevs_lock); } enum cnh_result cnh_usb_emu(struct cnh_usbhook_irp *irp) { - cnh_usbhook_fn_t handler; + cnh_usbhook_fn_t handler; - /* Ensure initialized */ - _cnh_usb_emu_init(); + /* Ensure initialized */ + _cnh_usb_emu_init(); - handler = _cnh_usb_emu_usb_handlers[irp->op]; + handler = _cnh_usb_emu_usb_handlers[irp->op]; - assert(handler != NULL); + assert(handler != NULL); - return handler(irp); + return handler(irp); } -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Hooked functions to usbhook module */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ static enum cnh_result _cnh_usb_emu_usbhook_default(struct cnh_usbhook_irp *irp) { - return cnh_usbhook_invoke_next(irp); + return cnh_usbhook_invoke_next(irp); } static enum cnh_result _cnh_usb_emu_usbhook_noop(struct cnh_usbhook_irp *irp) { - struct cnh_usb_emu_virtdev* virtdev; + struct cnh_usb_emu_virtdev *virtdev; - assert(irp->handle); + assert(irp->handle); - virtdev = _cnh_usb_emu_get_virtdev_by_handle(irp->handle); + virtdev = _cnh_usb_emu_get_virtdev_by_handle(irp->handle); - /* Not a virtual device handle, probably real handle from libusb */ - if (virtdev == NULL) { - return cnh_usbhook_invoke_next(irp); - } + /* Not a virtual device handle, probably real handle from libusb */ + if (virtdev == NULL) { + return cnh_usbhook_invoke_next(irp); + } - /* No-op */ + /* No-op */ - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } -static enum cnh_result _cnh_usb_emu_usbhook_find_busses(struct cnh_usbhook_irp *irp) +static enum cnh_result +_cnh_usb_emu_usbhook_find_busses(struct cnh_usbhook_irp *irp) { - enum cnh_result result; + enum cnh_result result; - result = cnh_usbhook_invoke_next(irp); + result = cnh_usbhook_invoke_next(irp); - // inject another custom bus for virtual devices - if (result == CNH_RESULT_SUCCESS) { - log_debug("Injecting usb bus for virtual devices"); - irp->find_busses_res_num_busses++; - } + // inject another custom bus for virtual devices + if (result == CNH_RESULT_SUCCESS) { + log_debug("Injecting usb bus for virtual devices"); + irp->find_busses_res_num_busses++; + } - return result; + return result; } -static enum cnh_result _cnh_usb_emu_usbhook_find_devices(struct cnh_usbhook_irp *irp) +static enum cnh_result +_cnh_usb_emu_usbhook_find_devices(struct cnh_usbhook_irp *irp) { - enum cnh_result result; - struct usb_bus* it; - int fakedev_count; + enum cnh_result result; + struct usb_bus *it; + int fakedev_count; - fakedev_count = 0; + fakedev_count = 0; - /* first, populate the list with real devices */ - result = cnh_usbhook_invoke_next(irp); + /* first, populate the list with real devices */ + result = cnh_usbhook_invoke_next(irp); - /* Iterate to the end of the list and add our stuff keeping real devices */ - it = usb_get_busses(); + /* Iterate to the end of the list and add our stuff keeping real devices */ + it = usb_get_busses(); - /* Iterate all busses */ - do { - /* First, iterate all devices on each bus and check for all real - devices connected which are also part of our hook list */ - if (it != NULL) { - /* Iterate devices on the current bus */ - struct usb_device* dev = it->devices; + /* Iterate all busses */ + do { + /* First, iterate all devices on each bus and check for all real + devices connected which are also part of our hook list */ + if (it != NULL) { + /* Iterate devices on the current bus */ + struct usb_device *dev = it->devices; - while (dev != NULL) { - struct cnh_usb_emu_virtdev* virt_dev = _cnh_usb_emu_get_virtdev((uint16_t) dev->descriptor.idVendor, - (uint16_t) dev->descriptor.idProduct); + while (dev != NULL) { + struct cnh_usb_emu_virtdev *virt_dev = _cnh_usb_emu_get_virtdev( + (uint16_t) dev->descriptor.idVendor, + (uint16_t) dev->descriptor.idProduct); - /* Real device connected for a hook */ - if (virt_dev) { - log_debug("Detected real %04X:%04X device for virtual one", dev->descriptor.idVendor, - dev->descriptor.idProduct); - virt_dev->real_dev_avail = true; - } + /* Real device connected for a hook */ + if (virt_dev) { + log_debug( + "Detected real %04X:%04X device for virtual one", + dev->descriptor.idVendor, + dev->descriptor.idProduct); + virt_dev->real_dev_avail = true; + } - dev = dev->next; - } - } + dev = dev->next; + } + } - /* it == NULL, nothing found on current bus which is our last bus - we added on usb_find_busses. We put our fakedevs on that bus */ - if (it == NULL || it->next == NULL) { - struct usb_bus* fakebus; - struct usb_device* fakebus_dev_tail; + /* it == NULL, nothing found on current bus which is our last bus + we added on usb_find_busses. We put our fakedevs on that bus */ + if (it == NULL || it->next == NULL) { + struct usb_bus *fakebus; + struct usb_device *fakebus_dev_tail; - /* Create an additional bus for our fakedevs */ - fakebus = (struct usb_bus*) util_xmalloc(sizeof(struct usb_bus)); - memset(fakebus, 0, sizeof(struct usb_bus)); + /* Create an additional bus for our fakedevs */ + fakebus = (struct usb_bus *) util_xmalloc(sizeof(struct usb_bus)); + memset(fakebus, 0, sizeof(struct usb_bus)); - /* Make sure to modify the linked list correctly. If we fuck up, - this works fine until Fiesta where they started to iterate - everything in a different manner (-> crash) */ - if (it == NULL) { - usb_busses = fakebus; - /* Bus empty, no prev bus */ - fakebus->prev = NULL; - } else { - /* Append at end of bus chain */ - it->next = fakebus; - /* Keep doubly linked list intact */ - fakebus->prev = it->next; - } + /* Make sure to modify the linked list correctly. If we fuck up, + this works fine until Fiesta where they started to iterate + everything in a different manner (-> crash) */ + if (it == NULL) { + usb_busses = fakebus; + /* Bus empty, no prev bus */ + fakebus->prev = NULL; + } else { + /* Append at end of bus chain */ + it->next = fakebus; + /* Keep doubly linked list intact */ + fakebus->prev = it->next; + } - fakebus_dev_tail = NULL; + fakebus_dev_tail = NULL; - pthread_mutex_lock(&_cnh_usb_emu_virtdevs_lock); + pthread_mutex_lock(&_cnh_usb_emu_virtdevs_lock); - for (size_t i = 0; i < _cnh_usb_emu_nvirtdevs; i++) { - struct cnh_usb_emu_virtdev* virtdev = &_cnh_usb_emu_virtdevs[i]; + for (size_t i = 0; i < _cnh_usb_emu_nvirtdevs; i++) { + struct cnh_usb_emu_virtdev *virtdev = &_cnh_usb_emu_virtdevs[i]; - virtdev->enumerated = virtdev->ep->enumerate(virtdev->real_dev_avail); + virtdev->enumerated = virtdev->ep->enumerate(virtdev->real_dev_avail); - if (virtdev->enumerated) { - if (virtdev->real_dev_avail) { - /* Suppress real device and detour everything to - our hook */ - log_debug("Suppressing real device %04X:%04X", virtdev->ep->vid, virtdev->ep->pid); - } else { - /* Create a fakedev and add it to the bus */ - struct usb_device* fakedev; + if (virtdev->enumerated) { + if (virtdev->real_dev_avail) { + /* Suppress real device and detour everything to + our hook */ + log_debug( + "Suppressing real device %04X:%04X", + virtdev->ep->vid, + virtdev->ep->pid); + } else { + /* Create a fakedev and add it to the bus */ + struct usb_device *fakedev; - { - /* Print this once. Pump Pro calls this - function every second */ - static int counter = 0; + { + /* Print this once. Pump Pro calls this + function every second */ + static int counter = 0; - if (counter++ == 0) { - log_info("Injecting fake usb device %04X:%04X into bus", virtdev->ep->vid, - virtdev->ep->pid); - } else { - counter = 1; - } - } - - fakedev = _cnh_usb_emu_create_fakedev(virtdev->ep->vid, virtdev->ep->pid); - - /* Append to linked list */ - if (!fakebus->devices) { - /* Set root on bus */ - fakebus->devices = fakedev; - } - - /* Cur element */ - fakedev->prev = fakebus_dev_tail; - fakedev->next = NULL; - - /* Update prev element's next */ - if (fakebus_dev_tail) { - fakebus_dev_tail->next = fakedev; - } - - /* tail update */ - fakebus_dev_tail = fakedev; - - fakedev_count++; - } - } else { - log_debug("Reject enumerate hook for %04X:%04X", virtdev->ep->vid, virtdev->ep->pid); - } + if (counter++ == 0) { + log_info( + "Injecting fake usb device %04X:%04X into bus", + virtdev->ep->vid, + virtdev->ep->pid); + } else { + counter = 1; + } } - pthread_mutex_unlock(&_cnh_usb_emu_virtdevs_lock); + fakedev = + _cnh_usb_emu_create_fakedev(virtdev->ep->vid, virtdev->ep->pid); - break; - } - /* End of if block which handles fakedevs and hooking */ + /* Append to linked list */ + if (!fakebus->devices) { + /* Set root on bus */ + fakebus->devices = fakedev; + } - it = it->next; - } - while (it != NULL); + /* Cur element */ + fakedev->prev = fakebus_dev_tail; + fakedev->next = NULL; - { - /* Print this once. Pump Pro calls this - function every second */ - static int counter = 0; + /* Update prev element's next */ + if (fakebus_dev_tail) { + fakebus_dev_tail->next = fakedev; + } - if (counter++ == 0) { - log_info("Added %d fakedevs to usb bus", fakedev_count); + /* tail update */ + fakebus_dev_tail = fakedev; + + fakedev_count++; + } } else { - counter = 1; + log_debug( + "Reject enumerate hook for %04X:%04X", + virtdev->ep->vid, + virtdev->ep->pid); } - } + } - /* include our fakedev count as well */ - return result + fakedev_count; + pthread_mutex_unlock(&_cnh_usb_emu_virtdevs_lock); + + break; + } + /* End of if block which handles fakedevs and hooking */ + + it = it->next; + } while (it != NULL); + + { + /* Print this once. Pump Pro calls this + function every second */ + static int counter = 0; + + if (counter++ == 0) { + log_info("Added %d fakedevs to usb bus", fakedev_count); + } else { + counter = 1; + } + } + + /* include our fakedev count as well */ + return result + fakedev_count; } static enum cnh_result _cnh_usb_emu_usbhook_open(struct cnh_usbhook_irp *irp) { - struct cnh_usb_emu_virtdev* virtdev; - enum cnh_result result; + struct cnh_usb_emu_virtdev *virtdev; + enum cnh_result result; - virtdev = _cnh_usb_emu_get_virtdev((uint16_t) irp->open_usb_dev->descriptor.idVendor, - (uint16_t) irp->open_usb_dev->descriptor.idProduct); + virtdev = _cnh_usb_emu_get_virtdev( + (uint16_t) irp->open_usb_dev->descriptor.idVendor, + (uint16_t) irp->open_usb_dev->descriptor.idProduct); - if (virtdev == NULL) { - return cnh_usbhook_invoke_next(irp); - } + if (virtdev == NULL) { + return cnh_usbhook_invoke_next(irp); + } - if (!virtdev->enumerated) { - log_debug("Virtdev %04X:%04X not enumerated, skipping open", virtdev->ep->vid, virtdev->ep->pid); - return cnh_usbhook_invoke_next(irp); - } + if (!virtdev->enumerated) { + log_debug( + "Virtdev %04X:%04X not enumerated, skipping open", + virtdev->ep->vid, + virtdev->ep->pid); + return cnh_usbhook_invoke_next(irp); + } - result = virtdev->ep->open(); + result = virtdev->ep->open(); - if (result == CNH_RESULT_SUCCESS) { - /* Return handle, use virtual device as fake handle */ - irp->handle = &virtdev->usb_dev_handle; - } + if (result == CNH_RESULT_SUCCESS) { + /* Return handle, use virtual device as fake handle */ + irp->handle = &virtdev->usb_dev_handle; + } - return result; + return result; } static enum cnh_result _cnh_usb_emu_usbhook_close(struct cnh_usbhook_irp *irp) { - struct cnh_usb_emu_virtdev* virtdev; + struct cnh_usb_emu_virtdev *virtdev; - assert(irp->handle); + assert(irp->handle); - virtdev = _cnh_usb_emu_get_virtdev_by_handle(irp->handle); + virtdev = _cnh_usb_emu_get_virtdev_by_handle(irp->handle); - /* Not a virtual device handle, probably real handle from libusb */ - if (virtdev == NULL) { - return cnh_usbhook_invoke_next(irp); - } + /* Not a virtual device handle, probably real handle from libusb */ + if (virtdev == NULL) { + return cnh_usbhook_invoke_next(irp); + } - virtdev->ep->close(); + virtdev->ep->close(); - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } static enum cnh_result _cnh_usb_emu_usbhook_reset(struct cnh_usbhook_irp *irp) { - struct cnh_usb_emu_virtdev* virtdev; + struct cnh_usb_emu_virtdev *virtdev; - assert(irp->handle); + assert(irp->handle); - virtdev = _cnh_usb_emu_get_virtdev_by_handle(irp->handle); + virtdev = _cnh_usb_emu_get_virtdev_by_handle(irp->handle); - /* Not a virtual device handle, probably real handle from libusb */ - if (virtdev == NULL) { - return cnh_usbhook_invoke_next(irp); - } + /* Not a virtual device handle, probably real handle from libusb */ + if (virtdev == NULL) { + return cnh_usbhook_invoke_next(irp); + } - return virtdev->ep->reset(); + return virtdev->ep->reset(); } -static enum cnh_result _cnh_usb_emu_usbhook_ctrl_msg(struct cnh_usbhook_irp *irp) +static enum cnh_result +_cnh_usb_emu_usbhook_ctrl_msg(struct cnh_usbhook_irp *irp) { - struct cnh_usb_emu_virtdev* virtdev; + struct cnh_usb_emu_virtdev *virtdev; - assert(irp->handle); + assert(irp->handle); - virtdev = _cnh_usb_emu_get_virtdev_by_handle(irp->handle); + virtdev = _cnh_usb_emu_get_virtdev_by_handle(irp->handle); - /* Not a virtual device handle, probably real handle from libusb */ - if (virtdev == NULL) { - return cnh_usbhook_invoke_next(irp); - } + /* Not a virtual device handle, probably real handle from libusb */ + if (virtdev == NULL) { + return cnh_usbhook_invoke_next(irp); + } - return virtdev->ep->control_msg(irp->ctrl_req_type, irp->ctrl_req, irp->ctrl_value, irp->ctrl_index, - &irp->ctrl_buffer, irp->ctrl_timeout); + return virtdev->ep->control_msg( + irp->ctrl_req_type, + irp->ctrl_req, + irp->ctrl_value, + irp->ctrl_index, + &irp->ctrl_buffer, + irp->ctrl_timeout); } -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ /* Helper functions */ -/* ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------------------------------------ + */ void _cnh_usb_emu_init(void) { - int expected; + int expected; - if (atomic_load(&_cnh_usb_emu_initted) > 0) { - return; + if (atomic_load(&_cnh_usb_emu_initted) > 0) { + return; + } + + expected = 0; + + if (!atomic_compare_exchange_strong( + &_cnh_usb_emu_init_in_progress, &expected, 1)) { + while (atomic_load(&_cnh_usb_emu_init_in_progress) > 1) { + util_time_sleep_us(100); } - expected = 0; + return; + } - if (!atomic_compare_exchange_strong(&_cnh_usb_emu_init_in_progress, &expected, 1)) { - while (atomic_load(&_cnh_usb_emu_init_in_progress) > 1) { - util_time_sleep_us(100); - } - - return; - } - - /* Check again to ensure the current thread yielded between the init'd check and setting init in progress */ - if (atomic_load(&_cnh_usb_emu_initted) > 0) { - /* Revert init in progress, because nothing to do anymore */ - atomic_store(&_cnh_usb_emu_init_in_progress, 0); - return; - } - - pthread_mutex_init(&_cnh_usb_emu_virtdevs_lock, NULL); - - atomic_store(&_cnh_usb_emu_initted, 1); + /* Check again to ensure the current thread yielded between the init'd check + * and setting init in progress */ + if (atomic_load(&_cnh_usb_emu_initted) > 0) { + /* Revert init in progress, because nothing to do anymore */ atomic_store(&_cnh_usb_emu_init_in_progress, 0); + return; + } + + pthread_mutex_init(&_cnh_usb_emu_virtdevs_lock, NULL); + + atomic_store(&_cnh_usb_emu_initted, 1); + atomic_store(&_cnh_usb_emu_init_in_progress, 0); } -static struct cnh_usb_emu_virtdev* _cnh_usb_emu_get_virtdev(uint16_t vid, uint16_t pid) +static struct cnh_usb_emu_virtdev * +_cnh_usb_emu_get_virtdev(uint16_t vid, uint16_t pid) { - struct cnh_usb_emu_virtdev* virtdev; - struct cnh_usb_emu_virtdev* tmp; + struct cnh_usb_emu_virtdev *virtdev; + struct cnh_usb_emu_virtdev *tmp; - virtdev = NULL; + virtdev = NULL; - pthread_mutex_lock(&_cnh_usb_emu_virtdevs_lock); + pthread_mutex_lock(&_cnh_usb_emu_virtdevs_lock); - for (size_t i = 0; i < _cnh_usb_emu_nvirtdevs; i++) { - tmp = &_cnh_usb_emu_virtdevs[i]; + for (size_t i = 0; i < _cnh_usb_emu_nvirtdevs; i++) { + tmp = &_cnh_usb_emu_virtdevs[i]; - if (tmp->ep->vid == vid && tmp->ep->pid == pid) { - virtdev = tmp; - break; - } + if (tmp->ep->vid == vid && tmp->ep->pid == pid) { + virtdev = tmp; + break; } + } - pthread_mutex_unlock(&_cnh_usb_emu_virtdevs_lock); + pthread_mutex_unlock(&_cnh_usb_emu_virtdevs_lock); - return virtdev; + return virtdev; } -static struct cnh_usb_emu_virtdev* _cnh_usb_emu_get_virtdev_by_handle(usb_dev_handle* handle) +static struct cnh_usb_emu_virtdev * +_cnh_usb_emu_get_virtdev_by_handle(usb_dev_handle *handle) { - struct cnh_usb_emu_virtdev* virtdev; - struct cnh_usb_emu_virtdev* tmp; + struct cnh_usb_emu_virtdev *virtdev; + struct cnh_usb_emu_virtdev *tmp; - virtdev = NULL; + virtdev = NULL; - pthread_mutex_lock(&_cnh_usb_emu_virtdevs_lock); + pthread_mutex_lock(&_cnh_usb_emu_virtdevs_lock); - for (size_t i = 0; i < _cnh_usb_emu_nvirtdevs; i++) { - tmp = &_cnh_usb_emu_virtdevs[i]; + for (size_t i = 0; i < _cnh_usb_emu_nvirtdevs; i++) { + tmp = &_cnh_usb_emu_virtdevs[i]; - if (tmp == handle->virtdev) { - virtdev = tmp; - break; - } + if (tmp == handle->virtdev) { + virtdev = tmp; + break; } + } - pthread_mutex_unlock(&_cnh_usb_emu_virtdevs_lock); + pthread_mutex_unlock(&_cnh_usb_emu_virtdevs_lock); - return virtdev; + return virtdev; } -static struct usb_device* _cnh_usb_emu_create_fakedev(uint16_t vid, uint16_t pid) +static struct usb_device * +_cnh_usb_emu_create_fakedev(uint16_t vid, uint16_t pid) { - struct usb_device* fakedev = (struct usb_device*) util_xmalloc(sizeof(struct usb_device)); - memset(fakedev, 0, sizeof(struct usb_device)); + struct usb_device *fakedev = + (struct usb_device *) util_xmalloc(sizeof(struct usb_device)); + memset(fakedev, 0, sizeof(struct usb_device)); - /* Populate fakedev */ - fakedev->descriptor.idVendor = vid; - fakedev->descriptor.idProduct = pid; + /* Populate fakedev */ + fakedev->descriptor.idVendor = vid; + fakedev->descriptor.idProduct = pid; - /* Mark as fakedev */ - fakedev->descriptor.bcdDevice = 0xBEEF; + /* Mark as fakedev */ + fakedev->descriptor.bcdDevice = 0xBEEF; - fakedev->config = (struct usb_config_descriptor*) util_xmalloc( - sizeof(struct usb_config_descriptor)); - memset(fakedev->config, 0, sizeof(struct usb_config_descriptor)); + fakedev->config = (struct usb_config_descriptor *) util_xmalloc( + sizeof(struct usb_config_descriptor)); + memset(fakedev->config, 0, sizeof(struct usb_config_descriptor)); - fakedev->config->interface = (struct usb_interface*) util_xmalloc( - sizeof(struct usb_interface)); - memset(fakedev->config->interface, 0, sizeof(struct usb_interface)); + fakedev->config->interface = + (struct usb_interface *) util_xmalloc(sizeof(struct usb_interface)); + memset(fakedev->config->interface, 0, sizeof(struct usb_interface)); - fakedev->config->interface->altsetting = (struct usb_interface_descriptor*) - util_xmalloc(sizeof(struct usb_interface_descriptor)); - memset(fakedev->config->interface->altsetting, 0, - sizeof(struct usb_interface_descriptor)); + fakedev->config->interface->altsetting = + (struct usb_interface_descriptor *) util_xmalloc( + sizeof(struct usb_interface_descriptor)); + memset( + fakedev->config->interface->altsetting, + 0, + sizeof(struct usb_interface_descriptor)); - return fakedev; + return fakedev; } \ No newline at end of file diff --git a/src/main/capnhook/hooklib/usb-emu.h b/src/main/capnhook/hooklib/usb-emu.h index a980567..5c19b0a 100644 --- a/src/main/capnhook/hooklib/usb-emu.h +++ b/src/main/capnhook/hooklib/usb-emu.h @@ -14,14 +14,19 @@ * Virtual device endpoint */ struct cnh_usb_emu_virtdev_ep { - uint16_t pid; - uint16_t vid; - bool (*enumerate)(bool real_exists); - enum cnh_result (*open)(void); - enum cnh_result (*reset)(void); - enum cnh_result (*control_msg)(int request_type, int request, int value, int index, struct cnh_iobuf* buffer, - int timeout); - void (*close)(void); + uint16_t pid; + uint16_t vid; + bool (*enumerate)(bool real_exists); + enum cnh_result (*open)(void); + enum cnh_result (*reset)(void); + enum cnh_result (*control_msg)( + int request_type, + int request, + int value, + int index, + struct cnh_iobuf *buffer, + int timeout); + void (*close)(void); }; /** @@ -29,7 +34,7 @@ struct cnh_usb_emu_virtdev_ep { * * @param virtdevep Virtual device endpoint to add */ -void cnh_usb_emu_add_virtdevep(const struct cnh_usb_emu_virtdev_ep* virtdevep); +void cnh_usb_emu_add_virtdevep(const struct cnh_usb_emu_virtdev_ep *virtdevep); /** * Hook function to add to the hook module for emulating usb devices diff --git a/src/main/capnhook/hooklib/usb-init-fix.c b/src/main/capnhook/hooklib/usb-init-fix.c index eb1b176..3195c40 100644 --- a/src/main/capnhook/hooklib/usb-init-fix.c +++ b/src/main/capnhook/hooklib/usb-init-fix.c @@ -4,9 +4,9 @@ #include "util/log.h" -static enum cnh_result _cnh_usb_init_fix_default(struct cnh_usbhook_irp* irp); -static enum cnh_result _cnh_usb_init_fix_init(struct cnh_usbhook_irp* irp); -static enum cnh_result _cnh_usbio_emu_find_busses(struct cnh_usbhook_irp* irp); +static enum cnh_result _cnh_usb_init_fix_default(struct cnh_usbhook_irp *irp); +static enum cnh_result _cnh_usb_init_fix_init(struct cnh_usbhook_irp *irp); +static enum cnh_result _cnh_usbio_emu_find_busses(struct cnh_usbhook_irp *irp); static const cnh_usbhook_fn_t _hook_usb_init_fix_handlers[10] = { [CNH_USBHOOK_IRP_OP_INIT] = _cnh_usb_init_fix_init, @@ -25,56 +25,56 @@ static int _cnh_usb_init_fix_init_count = 0; enum cnh_result cnh_usb_init_fix(struct cnh_usbhook_irp *irp) { - cnh_usbhook_fn_t handler; + cnh_usbhook_fn_t handler; - handler = _hook_usb_init_fix_handlers[irp->op]; + handler = _hook_usb_init_fix_handlers[irp->op]; - assert(handler != NULL); + assert(handler != NULL); - return handler(irp); + return handler(irp); } -static enum cnh_result _cnh_usb_init_fix_default(struct cnh_usbhook_irp* irp) +static enum cnh_result _cnh_usb_init_fix_default(struct cnh_usbhook_irp *irp) { + return cnh_usbhook_invoke_next(irp); +} + +static enum cnh_result _cnh_usb_init_fix_init(struct cnh_usbhook_irp *irp) +{ + /* On NXA, one programmer/multiple programmers had the bright idea to call + usb_init twice for reasons... + This breaks stuff in the usb-0.1 backend resulting in usb_find_busses + not even finding native devices anymore. + Make sure we call the real usb_init ONCE ONLY to fix that fuck up */ + _cnh_usb_init_fix_init_count++; + + if (_cnh_usb_init_fix_init_count <= 1) { return cnh_usbhook_invoke_next(irp); -} - -static enum cnh_result _cnh_usb_init_fix_init(struct cnh_usbhook_irp* irp) -{ - /* On NXA, one programmer/multiple programmers had the bright idea to call - usb_init twice for reasons... - This breaks stuff in the usb-0.1 backend resulting in usb_find_busses - not even finding native devices anymore. - Make sure we call the real usb_init ONCE ONLY to fix that fuck up */ - _cnh_usb_init_fix_init_count++; - - if (_cnh_usb_init_fix_init_count <= 1) { - return cnh_usbhook_invoke_next(irp); + } else { + /* Pump Pro is even worse and calls usb_init approx. every second... + avoid overflow of counter if we really leave this running forever. + Furthermore, this avoids printing the log message below with ever + init call */ + if (_cnh_usb_init_fix_init_count > 2) { + _cnh_usb_init_fix_init_count = 2; } else { - /* Pump Pro is even worse and calls usb_init approx. every second... - avoid overflow of counter if we really leave this running forever. - Furthermore, this avoids printing the log message below with ever - init call */ - if (_cnh_usb_init_fix_init_count > 2) { - _cnh_usb_init_fix_init_count = 2; - } else { - log_info("usb_init called multiple times, blocking further calls..."); - } - - return CNH_RESULT_SUCCESS; - } -} - -static enum cnh_result _cnh_usbio_emu_find_busses(struct cnh_usbhook_irp* irp) -{ - enum cnh_result result; - - /* Fixes quirks with usb_init called multiple times on NXA */ - if (_cnh_usb_init_fix_init_count <= 1) { - result = cnh_usbhook_invoke_next(irp); - } else { - result = CNH_RESULT_SUCCESS; + log_info("usb_init called multiple times, blocking further calls..."); } - return result; + return CNH_RESULT_SUCCESS; + } +} + +static enum cnh_result _cnh_usbio_emu_find_busses(struct cnh_usbhook_irp *irp) +{ + enum cnh_result result; + + /* Fixes quirks with usb_init called multiple times on NXA */ + if (_cnh_usb_init_fix_init_count <= 1) { + result = cnh_usbhook_invoke_next(irp); + } else { + result = CNH_RESULT_SUCCESS; + } + + return result; } \ No newline at end of file diff --git a/src/main/capnhook/hooklib/usbhook-mon.c b/src/main/capnhook/hooklib/usbhook-mon.c index a87b748..089bc01 100644 --- a/src/main/capnhook/hooklib/usbhook-mon.c +++ b/src/main/capnhook/hooklib/usbhook-mon.c @@ -4,7 +4,7 @@ #include "util/log.h" -static const char* _cnh_usbhook_mon_irp_op_str[] = { +static const char *_cnh_usbhook_mon_irp_op_str[] = { "init", "find_busses", "find_devices", @@ -14,42 +14,94 @@ static const char* _cnh_usbhook_mon_irp_op_str[] = { "set_altinterface", "set_configuration", "claim_interface", - "ctrl_msg" -}; + "ctrl_msg"}; enum cnh_result cnh_usbhook_mon(struct cnh_usbhook_irp *irp) { - enum cnh_result result; + enum cnh_result result; - log_debug("[before][%s] next_handler %d, find_busses_res_num_busses %d, find_devices_res_num_devices %d, " - "open_usb_dev %p, handle %p, set_altinterface %d, set_configuration %d, claim_interface %d, ctrl_req_type %d, " - "ctrl_req %d, ctrl_value %d, ctrl_index %d, ctrl_buffer(bytes %p, nbytes %d, pos %d), ctrl_timeout %d", - _cnh_usbhook_mon_irp_op_str[irp->op], irp->next_handler, irp->find_busses_res_num_busses, - irp->find_devices_res_num_devices, irp->open_usb_dev, irp->handle, irp->set_altinterface, - irp->set_configuration, irp->claim_interface, irp->ctrl_req_type, irp->ctrl_req, irp->ctrl_value, - irp->ctrl_index, irp->ctrl_buffer.bytes, irp->ctrl_buffer.nbytes, irp->ctrl_buffer.pos, irp->ctrl_timeout); + log_debug( + "[before][%s] next_handler %d, find_busses_res_num_busses %d, " + "find_devices_res_num_devices %d, " + "open_usb_dev %p, handle %p, set_altinterface %d, set_configuration %d, " + "claim_interface %d, ctrl_req_type %d, " + "ctrl_req %d, ctrl_value %d, ctrl_index %d, ctrl_buffer(bytes %p, nbytes " + "%d, pos %d), ctrl_timeout %d", + _cnh_usbhook_mon_irp_op_str[irp->op], + irp->next_handler, + irp->find_busses_res_num_busses, + irp->find_devices_res_num_devices, + irp->open_usb_dev, + irp->handle, + irp->set_altinterface, + irp->set_configuration, + irp->claim_interface, + irp->ctrl_req_type, + irp->ctrl_req, + irp->ctrl_value, + irp->ctrl_index, + irp->ctrl_buffer.bytes, + irp->ctrl_buffer.nbytes, + irp->ctrl_buffer.pos, + irp->ctrl_timeout); - result = cnh_usbhook_invoke_next(irp); + result = cnh_usbhook_invoke_next(irp); - if (result != CNH_RESULT_SUCCESS) { - log_error("[after][%s] result %d, next_handler %d, find_busses_res_num_busses %d, " - "find_devices_res_num_devices %d, open_usb_dev %p, handle %p, set_altinterface %d, set_configuration %d, " - "claim_interface %d, ctrl_req_type %d, ctrl_req %d, ctrl_value %d, ctrl_index %d, ctrl_buffer(bytes %p, " - "nbytes %d, pos %d), ctrl_timeout %d", _cnh_usbhook_mon_irp_op_str[irp->op], result, irp->next_handler, - irp->find_busses_res_num_busses, irp->find_devices_res_num_devices, irp->open_usb_dev, irp->handle, - irp->set_altinterface, irp->set_configuration, irp->claim_interface, irp->ctrl_req_type, irp->ctrl_req, - irp->ctrl_value, irp->ctrl_index, irp->ctrl_buffer.bytes, irp->ctrl_buffer.nbytes, irp->ctrl_buffer.pos, - irp->ctrl_timeout); - } else { - log_debug("[after][%s] result %d, next_handler %d, find_busses_res_num_busses %d, " - "find_devices_res_num_devices %d, open_usb_dev %p, handle %p, set_altinterface %d, set_configuration %d, " - "claim_interface %d, ctrl_req_type %d, ctrl_req %d, ctrl_value %d, ctrl_index %d, ctrl_buffer(bytes %p, " - "nbytes %d, pos %d), ctrl_timeout %d", _cnh_usbhook_mon_irp_op_str[irp->op], result, irp->next_handler, - irp->find_busses_res_num_busses, irp->find_devices_res_num_devices, irp->open_usb_dev, irp->handle, - irp->set_altinterface, irp->set_configuration, irp->claim_interface, irp->ctrl_req_type, irp->ctrl_req, - irp->ctrl_value, irp->ctrl_index, irp->ctrl_buffer.bytes, irp->ctrl_buffer.nbytes, irp->ctrl_buffer.pos, - irp->ctrl_timeout); - } + if (result != CNH_RESULT_SUCCESS) { + log_error( + "[after][%s] result %d, next_handler %d, find_busses_res_num_busses " + "%d, " + "find_devices_res_num_devices %d, open_usb_dev %p, handle %p, " + "set_altinterface %d, set_configuration %d, " + "claim_interface %d, ctrl_req_type %d, ctrl_req %d, ctrl_value %d, " + "ctrl_index %d, ctrl_buffer(bytes %p, " + "nbytes %d, pos %d), ctrl_timeout %d", + _cnh_usbhook_mon_irp_op_str[irp->op], + result, + irp->next_handler, + irp->find_busses_res_num_busses, + irp->find_devices_res_num_devices, + irp->open_usb_dev, + irp->handle, + irp->set_altinterface, + irp->set_configuration, + irp->claim_interface, + irp->ctrl_req_type, + irp->ctrl_req, + irp->ctrl_value, + irp->ctrl_index, + irp->ctrl_buffer.bytes, + irp->ctrl_buffer.nbytes, + irp->ctrl_buffer.pos, + irp->ctrl_timeout); + } else { + log_debug( + "[after][%s] result %d, next_handler %d, find_busses_res_num_busses " + "%d, " + "find_devices_res_num_devices %d, open_usb_dev %p, handle %p, " + "set_altinterface %d, set_configuration %d, " + "claim_interface %d, ctrl_req_type %d, ctrl_req %d, ctrl_value %d, " + "ctrl_index %d, ctrl_buffer(bytes %p, " + "nbytes %d, pos %d), ctrl_timeout %d", + _cnh_usbhook_mon_irp_op_str[irp->op], + result, + irp->next_handler, + irp->find_busses_res_num_busses, + irp->find_devices_res_num_devices, + irp->open_usb_dev, + irp->handle, + irp->set_altinterface, + irp->set_configuration, + irp->claim_interface, + irp->ctrl_req_type, + irp->ctrl_req, + irp->ctrl_value, + irp->ctrl_index, + irp->ctrl_buffer.bytes, + irp->ctrl_buffer.nbytes, + irp->ctrl_buffer.pos, + irp->ctrl_timeout); + } - return result; + return result; } \ No newline at end of file diff --git a/src/main/crypt/aes.c b/src/main/crypt/aes.c index a20301c..46ee8f5 100644 --- a/src/main/crypt/aes.c +++ b/src/main/crypt/aes.c @@ -4,26 +4,34 @@ #include "aes.h" -void crypt_aes_enc(uint8_t* key, enum crypt_aes_key_length key_len, - uint8_t* out, const uint8_t* in, size_t nbytes) +void crypt_aes_enc( + uint8_t *key, + enum crypt_aes_key_length key_len, + uint8_t *out, + const uint8_t *in, + size_t nbytes) { - unsigned long rk[RKLENGTH(128)]; - int nrounds; + unsigned long rk[RKLENGTH(128)]; + int nrounds; - nrounds = rijndaelSetupEncrypt(rk, key, key_len * 8); - for (size_t i = 0; i < nbytes / key_len; i++) { - rijndaelEncrypt(rk, nrounds, &in[i * key_len], &out[i * key_len]); - } + nrounds = rijndaelSetupEncrypt(rk, key, key_len * 8); + for (size_t i = 0; i < nbytes / key_len; i++) { + rijndaelEncrypt(rk, nrounds, &in[i * key_len], &out[i * key_len]); + } } -void crypt_aes_dec(uint8_t* key, enum crypt_aes_key_length key_len, - uint8_t* out, const uint8_t* in, size_t nbytes) +void crypt_aes_dec( + uint8_t *key, + enum crypt_aes_key_length key_len, + uint8_t *out, + const uint8_t *in, + size_t nbytes) { - unsigned long rk[RKLENGTH(128)]; - int nrounds; + unsigned long rk[RKLENGTH(128)]; + int nrounds; - nrounds = rijndaelSetupDecrypt(rk, key, key_len * 8); - for (size_t i = 0; i < nbytes / key_len; i++) { - rijndaelDecrypt(rk, nrounds, &in[i * key_len], &out[i * key_len]); - } + nrounds = rijndaelSetupDecrypt(rk, key, key_len * 8); + for (size_t i = 0; i < nbytes / key_len; i++) { + rijndaelDecrypt(rk, nrounds, &in[i * key_len], &out[i * key_len]); + } } \ No newline at end of file diff --git a/src/main/crypt/aes.h b/src/main/crypt/aes.h index cb3c782..902a8e4 100644 --- a/src/main/crypt/aes.h +++ b/src/main/crypt/aes.h @@ -8,12 +8,12 @@ * AES enc/dec key lengths */ enum crypt_aes_key_length { - /* 128 bit */ - CRYPT_AES_KEY_LENGTH_16_BYTES = 16, - /* 192 bit */ - CRYPT_AES_KEY_LENGTH_24_BYTES = 24, - /* 256 bit */ - CRYPT_AES_KEY_LENGTH_32_BYTES = 32, + /* 128 bit */ + CRYPT_AES_KEY_LENGTH_16_BYTES = 16, + /* 192 bit */ + CRYPT_AES_KEY_LENGTH_24_BYTES = 24, + /* 256 bit */ + CRYPT_AES_KEY_LENGTH_32_BYTES = 32, }; /** @@ -25,8 +25,12 @@ enum crypt_aes_key_length { * @param in Input buffer to encrypt * @param nbytes Number of bytes of input buffer to encrypt */ -void crypt_aes_enc(uint8_t* key, enum crypt_aes_key_length key_len, - uint8_t* out, const uint8_t* in, size_t nbytes); +void crypt_aes_enc( + uint8_t *key, + enum crypt_aes_key_length key_len, + uint8_t *out, + const uint8_t *in, + size_t nbytes); /** * Decrypt data @@ -37,7 +41,11 @@ void crypt_aes_enc(uint8_t* key, enum crypt_aes_key_length key_len, * @param in Input buffer to decrypt * @param nbytes Number of bytes of input buffer to decrypt */ -void crypt_aes_dec(uint8_t* key, enum crypt_aes_key_length key_len, - uint8_t* out, const uint8_t* in, size_t nbytes); +void crypt_aes_dec( + uint8_t *key, + enum crypt_aes_key_length key_len, + uint8_t *out, + const uint8_t *in, + size_t nbytes); #endif \ No newline at end of file diff --git a/src/main/crypt/lib/md5.c b/src/main/crypt/lib/md5.c index a8565de..2f0d6df 100644 --- a/src/main/crypt/lib/md5.c +++ b/src/main/crypt/lib/md5.c @@ -42,17 +42,16 @@ documentation and/or software. #define S43 15 #define S44 21 -static void MD5Transform (uint32_t [4], unsigned char [64]); +static void MD5Transform(uint32_t[4], unsigned char[64]); static void Encode(unsigned char *, uint32_t *, unsigned int); static void Decode(uint32_t *, unsigned char *, unsigned int); static void MD5_memcpy(uint8_t *, uint8_t *, unsigned int); static void MD5_memset(uint8_t *, int, unsigned int); static unsigned char PADDING[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* F, G, H and I are basic MD5 functions. */ @@ -63,40 +62,43 @@ static unsigned char PADDING[64] = { /* ROTATE_LEFT rotates x left n bits. */ -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. Rotation is separate from addition to prevent recomputation. */ -#define FF(a, b, c, d, x, s, ac) { \ - (a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ +#define FF(a, b, c, d, x, s, ac) \ + { \ + (a) += F((b), (c), (d)) + (x) + (uint32_t)(ac); \ + (a) = ROTATE_LEFT((a), (s)); \ + (a) += (b); \ } -#define GG(a, b, c, d, x, s, ac) { \ - (a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ +#define GG(a, b, c, d, x, s, ac) \ + { \ + (a) += G((b), (c), (d)) + (x) + (uint32_t)(ac); \ + (a) = ROTATE_LEFT((a), (s)); \ + (a) += (b); \ } -#define HH(a, b, c, d, x, s, ac) { \ - (a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ +#define HH(a, b, c, d, x, s, ac) \ + { \ + (a) += H((b), (c), (d)) + (x) + (uint32_t)(ac); \ + (a) = ROTATE_LEFT((a), (s)); \ + (a) += (b); \ } -#define II(a, b, c, d, x, s, ac) { \ - (a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ +#define II(a, b, c, d, x, s, ac) \ + { \ + (a) += I((b), (c), (d)) + (x) + (uint32_t)(ac); \ + (a) = ROTATE_LEFT((a), (s)); \ + (a) += (b); \ } /* MD5 initialization. Begins an MD5 operation, writing a new context. */ -void MD5Init (context) -MD5_CTX *context; /* context */ +void MD5Init(context) MD5_CTX *context; /* context */ { context->count[0] = context->count[1] = 0; /* Load magic initialization constants. -*/ + */ context->state[0] = 0x67452301; context->state[1] = 0xefcdab89; context->state[2] = 0x98badcfe; @@ -107,158 +109,152 @@ MD5_CTX *context; /* context */ operation, processing another message block, and updating the context. */ -void MD5Update (context, input, inputLen) -MD5_CTX *context; /* context */ -unsigned char *input; /* input block */ -unsigned int inputLen; /* length of input block */ +void MD5Update(context, input, inputLen) MD5_CTX *context; /* context */ +unsigned char *input; /* input block */ +unsigned int inputLen; /* length of input block */ { unsigned int i, index, partLen; /* Compute number of bytes mod 64 */ - index = (unsigned int)((context->count[0] >> 3) & 0x3F); + index = (unsigned int) ((context->count[0] >> 3) & 0x3F); /* Update number of bits */ - if ((context->count[0] += ((uint32_t)inputLen << 3)) + if ((context->count[0] += ((uint32_t) inputLen << 3)) - < ((uint32_t)inputLen << 3)) - context->count[1]++; - context->count[1] += ((uint32_t)inputLen >> 29); + < ((uint32_t) inputLen << 3)) + context->count[1]++; + context->count[1] += ((uint32_t) inputLen >> 29); partLen = 64 - index; /* Transform as many times as possible. -*/ + */ if (inputLen >= partLen) { - MD5_memcpy - ((uint8_t *)&context->buffer[index], (uint8_t *)input, partLen); - MD5Transform (context->state, context->buffer); + MD5_memcpy((uint8_t *) &context->buffer[index], (uint8_t *) input, partLen); + MD5Transform(context->state, context->buffer); - for (i = partLen; i + 63 < inputLen; i += 64) - MD5Transform (context->state, &input[i]); + for (i = partLen; i + 63 < inputLen; i += 64) + MD5Transform(context->state, &input[i]); - index = 0; - } - else - i = 0; + index = 0; + } else + i = 0; /* Buffer remaining input */ - MD5_memcpy - ((uint8_t *)&context->buffer[index], (uint8_t *)&input[i], - inputLen-i); + MD5_memcpy( + (uint8_t *) &context->buffer[index], (uint8_t *) &input[i], inputLen - i); } /* MD5 finalization. Ends an MD5 message-digest operation, writing the the message digest and zeroizing the context. */ -void MD5Final (digest, context) -unsigned char digest[16]; /* message digest */ -MD5_CTX *context; /* context */ +void MD5Final(digest, context) unsigned char digest[16]; /* message digest */ +MD5_CTX *context; /* context */ { unsigned char bits[8]; unsigned int index, padLen; /* Save number of bits */ - Encode (bits, context->count, 8); + Encode(bits, context->count, 8); /* Pad out to 56 mod 64. -*/ - index = (unsigned int)((context->count[0] >> 3) & 0x3f); + */ + index = (unsigned int) ((context->count[0] >> 3) & 0x3f); padLen = (index < 56) ? (56 - index) : (120 - index); - MD5Update (context, PADDING, padLen); + MD5Update(context, PADDING, padLen); /* Append length (before padding) */ - MD5Update (context, bits, 8); + MD5Update(context, bits, 8); /* Store state in digest */ - Encode (digest, context->state, 16); + Encode(digest, context->state, 16); /* Zeroize sensitive information. -*/ - MD5_memset ((uint8_t *)context, 0, sizeof (*context)); + */ + MD5_memset((uint8_t *) context, 0, sizeof(*context)); } /* MD5 basic transformation. Transforms state based on block. */ -static void MD5Transform (state, block) -uint32_t state[4]; +static void MD5Transform(state, block) uint32_t state[4]; unsigned char block[64]; { uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16]; - Decode (x, block, 64); + Decode(x, block, 64); /* Round 1 */ - FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ - FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ - FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ - FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ - FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ - FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ - FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ - FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ - FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ - FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ - FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ - FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ - FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ - FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ - FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ - FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */ + FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */ + FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */ + FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */ + FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */ + FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */ + FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */ + FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */ + FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */ + FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */ + FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ - /* Round 2 */ - GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ - GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ - GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ - GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ - GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ - GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ - GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ - GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ - GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ - GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ - GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + /* Round 2 */ + GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */ + GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */ + GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */ + GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */ + GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */ + GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */ + GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */ - GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ - GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ - GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ - GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ - GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */ + GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */ + GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */ + GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ /* Round 3 */ - HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ - HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ - HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ - HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ - HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ - HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ - HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ - HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ - HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ - HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ - HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ - HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ - HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ - HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ - HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ - HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */ + HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */ + HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */ + HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */ + HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */ + HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */ + HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */ + HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */ + HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */ + HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */ /* Round 4 */ - II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ - II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ - II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ - II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ - II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ - II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ - II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ - II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ - II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ - II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ - II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ - II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ - II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ - II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ - II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ - II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */ + II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */ + II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */ + II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */ + II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */ + II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */ + II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */ + II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */ + II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */ + II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */ state[0] += a; state[1] += b; @@ -268,66 +264,62 @@ unsigned char block[64]; /* Zeroize sensitive information. */ - MD5_memset ((uint8_t *)x, 0, sizeof (x)); + MD5_memset((uint8_t *) x, 0, sizeof(x)); } /* Encodes input (uint32_t) into output (unsigned char). Assumes len is a multiple of 4. */ -static void Encode (output, input, len) -unsigned char *output; +static void Encode(output, input, len) unsigned char *output; uint32_t *input; unsigned int len; { unsigned int i, j; for (i = 0, j = 0; j < len; i++, j += 4) { - output[j] = (unsigned char)(input[i] & 0xff); - output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); - output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); - output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); + output[j] = (unsigned char) (input[i] & 0xff); + output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff); + output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff); + output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff); } } /* Decodes input (unsigned char) into output (uint32_t). Assumes len is a multiple of 4. */ -static void Decode (output, input, len) -uint32_t *output; +static void Decode(output, input, len) uint32_t *output; unsigned char *input; unsigned int len; { unsigned int i, j; for (i = 0, j = 0; j < len; i++, j += 4) - output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) | - (((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24); + output[i] = ((uint32_t) input[j]) | (((uint32_t) input[j + 1]) << 8) | + (((uint32_t) input[j + 2]) << 16) | (((uint32_t) input[j + 3]) << 24); } /* Note: Replace "for loop" with standard memcpy if possible. */ -static void MD5_memcpy (output, input, len) -uint8_t * output; -uint8_t * input; +static void MD5_memcpy(output, input, len) uint8_t *output; +uint8_t *input; unsigned int len; { unsigned int i; for (i = 0; i < len; i++) - output[i] = input[i]; + output[i] = input[i]; } /* Note: Replace "for loop" with standard memset if possible. */ -static void MD5_memset (output, value, len) -uint8_t * output; +static void MD5_memset(output, value, len) uint8_t *output; int value; unsigned int len; { unsigned int i; for (i = 0; i < len; i++) - ((char *)output)[i] = (char)value; + ((char *) output)[i] = (char) value; } \ No newline at end of file diff --git a/src/main/crypt/lib/md5.h b/src/main/crypt/lib/md5.h index 5cf313f..4e294a4 100644 --- a/src/main/crypt/lib/md5.h +++ b/src/main/crypt/lib/md5.h @@ -24,12 +24,11 @@ documentation and/or software. /* MD5 context. */ typedef struct { - uint32_t state[4]; /* state (ABCD) */ - uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */ - unsigned char buffer[64]; /* input buffer */ + uint32_t state[4]; /* state (ABCD) */ + uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ } MD5_CTX; void MD5Init(MD5_CTX *); void MD5Update(MD5_CTX *, unsigned char *, unsigned int); -void MD5Final(unsigned char [16], MD5_CTX *); - +void MD5Final(unsigned char[16], MD5_CTX *); diff --git a/src/main/crypt/lib/rijndael.c b/src/main/crypt/lib/rijndael.c index 5a1ecda..a050ede 100644 --- a/src/main/crypt/lib/rijndael.c +++ b/src/main/crypt/lib/rijndael.c @@ -5,703 +5,581 @@ typedef unsigned long u32; typedef unsigned char u8; -static const u32 Te0[256] = -{ - 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, - 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, - 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, - 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, - 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, - 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, - 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, - 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, - 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, - 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, - 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, - 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, - 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, - 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, - 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, - 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, - 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, - 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, - 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, - 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, - 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, - 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, - 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, - 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, - 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, - 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, - 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, - 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, - 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, - 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, - 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, - 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, - 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, - 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, - 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, - 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, - 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, - 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, - 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, - 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, - 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, - 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, - 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, - 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, - 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, - 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, - 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, - 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, - 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, - 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, - 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, - 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, - 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, - 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, - 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, - 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, - 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, - 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, - 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, - 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, - 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, - 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, - 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, - 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, +static const u32 Te0[256] = { + 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, 0xfff2f20dU, + 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, 0x60303050U, 0x02010103U, + 0xce6767a9U, 0x562b2b7dU, 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, + 0xec76769aU, 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, + 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, 0x41adadecU, + 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, 0x239c9cbfU, 0x53a4a4f7U, + 0xe4727296U, 0x9bc0c05bU, 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, + 0x4c26266aU, 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, + 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, 0xe2717193U, + 0xabd8d873U, 0x62313153U, 0x2a15153fU, 0x0804040cU, 0x95c7c752U, + 0x46232365U, 0x9dc3c35eU, 0x30181828U, 0x379696a1U, 0x0a05050fU, + 0x2f9a9ab5U, 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, + 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, 0x1209091bU, + 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, 0x361b1b2dU, 0xdc6e6eb2U, + 0xb45a5aeeU, 0x5ba0a0fbU, 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, + 0x7db3b3ceU, 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, + 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, 0x40202060U, + 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, 0xd46a6abeU, 0x8dcbcb46U, + 0x67bebed9U, 0x7239394bU, 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, + 0x85cfcf4aU, 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, + 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, 0x8a4545cfU, + 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, 0xa05050f0U, 0x783c3c44U, + 0x259f9fbaU, 0x4ba8a8e3U, 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, + 0x058f8f8aU, 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, + 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, 0x20101030U, + 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, 0x81cdcd4cU, 0x180c0c14U, + 0x26131335U, 0xc3ecec2fU, 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, + 0x2e171739U, 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, + 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, 0xc06060a0U, + 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, 0x44222266U, 0x542a2a7eU, + 0x3b9090abU, 0x0b888883U, 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, + 0x2814143cU, 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, + 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, 0x924949dbU, + 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, 0x9fc2c25dU, 0xbdd3d36eU, + 0x43acacefU, 0xc46262a6U, 0x399191a8U, 0x319595a4U, 0xd3e4e437U, + 0xf279798bU, 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, + 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, 0xd86c6cb4U, + 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, 0xca6565afU, 0xf47a7a8eU, + 0x47aeaee9U, 0x10080818U, 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, + 0x5c2e2e72U, 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, + 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, 0x964b4bddU, + 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, 0xe0707090U, 0x7c3e3e42U, + 0x71b5b5c4U, 0xcc6666aaU, 0x904848d8U, 0x06030305U, 0xf7f6f601U, + 0x1c0e0e12U, 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, + 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, 0xd9e1e138U, + 0xebf8f813U, 0x2b9898b3U, 0x22111133U, 0xd26969bbU, 0xa9d9d970U, + 0x078e8e89U, 0x339494a7U, 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, + 0xc9e9e920U, 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, + 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, 0x65bfbfdaU, + 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, 0x824141c3U, 0x299999b0U, + 0x5a2d2d77U, 0x1e0f0f11U, 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, + 0x2c16163aU, }; -static const u32 Te1[256] = -{ - 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, - 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, - 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, - 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, - 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, - 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, - 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, - 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, - 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, - 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, - 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, - 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, - 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, - 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, - 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, - 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, - 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, - 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, - 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, - 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, - 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, - 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, - 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, - 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, - 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, - 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, - 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, - 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, - 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, - 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, - 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, - 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, - 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, - 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, - 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, - 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, - 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, - 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, - 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, - 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, - 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, - 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, - 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, - 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, - 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, - 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, - 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, - 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, - 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, - 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, - 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, - 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, - 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, - 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, - 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, - 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, - 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, - 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, - 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, - 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, - 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, - 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, - 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, - 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, +static const u32 Te1[256] = { + 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, 0x0dfff2f2U, + 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, 0x50603030U, 0x03020101U, + 0xa9ce6767U, 0x7d562b2bU, 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, + 0x9aec7676U, 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, + 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, 0xec41adadU, + 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, 0xbf239c9cU, 0xf753a4a4U, + 0x96e47272U, 0x5b9bc0c0U, 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, + 0x6a4c2626U, 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, + 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, 0x93e27171U, + 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, 0x0c080404U, 0x5295c7c7U, + 0x65462323U, 0x5e9dc3c3U, 0x28301818U, 0xa1379696U, 0x0f0a0505U, + 0xb52f9a9aU, 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, + 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, 0x1b120909U, + 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, 0x2d361b1bU, 0xb2dc6e6eU, + 0xeeb45a5aU, 0xfb5ba0a0U, 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, + 0xce7db3b3U, 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, + 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, 0x60402020U, + 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, 0xbed46a6aU, 0x468dcbcbU, + 0xd967bebeU, 0x4b723939U, 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, + 0x4a85cfcfU, 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, + 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, 0xcf8a4545U, + 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, 0xf0a05050U, 0x44783c3cU, + 0xba259f9fU, 0xe34ba8a8U, 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, + 0x8a058f8fU, 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, + 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, 0x30201010U, + 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, 0x4c81cdcdU, 0x14180c0cU, + 0x35261313U, 0x2fc3ececU, 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, + 0x392e1717U, 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, + 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, 0xa0c06060U, + 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, 0x66442222U, 0x7e542a2aU, + 0xab3b9090U, 0x830b8888U, 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, + 0x3c281414U, 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, + 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, 0xdb924949U, + 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, 0x5d9fc2c2U, 0x6ebdd3d3U, + 0xef43acacU, 0xa6c46262U, 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, + 0x8bf27979U, 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, + 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, 0xb4d86c6cU, + 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, 0xafca6565U, 0x8ef47a7aU, + 0xe947aeaeU, 0x18100808U, 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, + 0x725c2e2eU, 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, + 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, 0xdd964b4bU, + 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, 0x90e07070U, 0x427c3e3eU, + 0xc471b5b5U, 0xaacc6666U, 0xd8904848U, 0x05060303U, 0x01f7f6f6U, + 0x121c0e0eU, 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, + 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, 0x38d9e1e1U, + 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, 0xbbd26969U, 0x70a9d9d9U, + 0x89078e8eU, 0xa7339494U, 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, + 0x20c9e9e9U, 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, + 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, 0xda65bfbfU, + 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, 0xc3824141U, 0xb0299999U, + 0x775a2d2dU, 0x111e0f0fU, 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, + 0x3a2c1616U, }; -static const u32 Te2[256] = -{ - 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, - 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, - 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, - 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, - 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, - 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, - 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, - 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, - 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, - 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, - 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, - 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, - 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, - 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, - 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, - 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, - 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, - 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, - 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, - 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, - 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, - 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, - 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, - 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, - 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, - 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, - 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, - 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, - 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, - 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, - 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, - 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, - 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, - 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, - 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, - 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, - 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, - 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, - 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, - 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, - 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, - 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, - 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, - 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, - 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, - 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, - 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, - 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, - 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, - 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, - 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, - 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, - 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, - 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, - 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, - 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, - 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, - 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, - 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, - 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, - 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, - 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, - 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, - 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, +static const u32 Te2[256] = { + 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, 0xf20dfff2U, + 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, 0x30506030U, 0x01030201U, + 0x67a9ce67U, 0x2b7d562bU, 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, + 0x769aec76U, 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, + 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, 0xadec41adU, + 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, 0x9cbf239cU, 0xa4f753a4U, + 0x7296e472U, 0xc05b9bc0U, 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, + 0x266a4c26U, 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, + 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, 0x7193e271U, + 0xd873abd8U, 0x31536231U, 0x153f2a15U, 0x040c0804U, 0xc75295c7U, + 0x23654623U, 0xc35e9dc3U, 0x18283018U, 0x96a13796U, 0x050f0a05U, + 0x9ab52f9aU, 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, + 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, 0x091b1209U, + 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, 0x1b2d361bU, 0x6eb2dc6eU, + 0x5aeeb45aU, 0xa0fb5ba0U, 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, + 0xb3ce7db3U, 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, + 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, 0x20604020U, + 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, 0x6abed46aU, 0xcb468dcbU, + 0xbed967beU, 0x394b7239U, 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, + 0xcf4a85cfU, 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, + 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, 0x45cf8a45U, + 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, 0x50f0a050U, 0x3c44783cU, + 0x9fba259fU, 0xa8e34ba8U, 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, + 0x8f8a058fU, 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, + 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, 0x10302010U, + 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, 0xcd4c81cdU, 0x0c14180cU, + 0x13352613U, 0xec2fc3ecU, 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, + 0x17392e17U, 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, + 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, 0x60a0c060U, + 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, 0x22664422U, 0x2a7e542aU, + 0x90ab3b90U, 0x88830b88U, 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, + 0x143c2814U, 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, + 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, 0x49db9249U, + 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, 0xc25d9fc2U, 0xd36ebdd3U, + 0xacef43acU, 0x62a6c462U, 0x91a83991U, 0x95a43195U, 0xe437d3e4U, + 0x798bf279U, 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, + 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, 0x6cb4d86cU, + 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, 0x65afca65U, 0x7a8ef47aU, + 0xaee947aeU, 0x08181008U, 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, + 0x2e725c2eU, 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, + 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, 0x4bdd964bU, + 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, 0x7090e070U, 0x3e427c3eU, + 0xb5c471b5U, 0x66aacc66U, 0x48d89048U, 0x03050603U, 0xf601f7f6U, + 0x0e121c0eU, 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, + 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, 0xe138d9e1U, + 0xf813ebf8U, 0x98b32b98U, 0x11332211U, 0x69bbd269U, 0xd970a9d9U, + 0x8e89078eU, 0x94a73394U, 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, + 0xe920c9e9U, 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, + 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, 0xbfda65bfU, + 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, 0x41c38241U, 0x99b02999U, + 0x2d775a2dU, 0x0f111e0fU, 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, + 0x163a2c16U, }; -static const u32 Te3[256] = -{ - 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, - 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, - 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, - 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, - 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, - 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, - 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, - 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, - 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, - 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, - 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, - 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, - 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, - 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, - 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, - 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, - 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, - 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, - 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, - 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, - 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, - 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, - 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, - 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, - 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, - 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, - 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, - 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, - 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, - 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, - 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, - 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, - 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, - 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, - 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, - 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, - 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, - 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, - 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, - 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, - 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, - 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, - 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, - 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, - 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, - 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, - 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, - 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, - 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, - 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, - 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, - 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, - 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, - 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, - 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, - 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, - 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, - 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, - 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, - 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, - 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, - 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, - 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, - 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, +static const u32 Te3[256] = { + 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, 0xf2f20dffU, + 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, 0x30305060U, 0x01010302U, + 0x6767a9ceU, 0x2b2b7d56U, 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, + 0x76769aecU, 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, + 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, 0xadadec41U, + 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, 0x9c9cbf23U, 0xa4a4f753U, + 0x727296e4U, 0xc0c05b9bU, 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, + 0x26266a4cU, 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, + 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, 0x717193e2U, + 0xd8d873abU, 0x31315362U, 0x15153f2aU, 0x04040c08U, 0xc7c75295U, + 0x23236546U, 0xc3c35e9dU, 0x18182830U, 0x9696a137U, 0x05050f0aU, + 0x9a9ab52fU, 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, + 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, 0x09091b12U, + 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, 0x1b1b2d36U, 0x6e6eb2dcU, + 0x5a5aeeb4U, 0xa0a0fb5bU, 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, + 0xb3b3ce7dU, 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, + 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, 0x20206040U, + 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, 0x6a6abed4U, 0xcbcb468dU, + 0xbebed967U, 0x39394b72U, 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, + 0xcfcf4a85U, 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, + 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, 0x4545cf8aU, + 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, 0x5050f0a0U, 0x3c3c4478U, + 0x9f9fba25U, 0xa8a8e34bU, 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, + 0x8f8f8a05U, 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, + 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, 0x10103020U, + 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, 0xcdcd4c81U, 0x0c0c1418U, + 0x13133526U, 0xecec2fc3U, 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, + 0x1717392eU, 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, + 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, 0x6060a0c0U, + 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, 0x22226644U, 0x2a2a7e54U, + 0x9090ab3bU, 0x8888830bU, 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, + 0x14143c28U, 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, + 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, 0x4949db92U, + 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, 0xc2c25d9fU, 0xd3d36ebdU, + 0xacacef43U, 0x6262a6c4U, 0x9191a839U, 0x9595a431U, 0xe4e437d3U, + 0x79798bf2U, 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, + 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, 0x6c6cb4d8U, + 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, 0x6565afcaU, 0x7a7a8ef4U, + 0xaeaee947U, 0x08081810U, 0xbabad56fU, 0x787888f0U, 0x25256f4aU, + 0x2e2e725cU, 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, + 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, 0x4b4bdd96U, + 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, 0x707090e0U, 0x3e3e427cU, + 0xb5b5c471U, 0x6666aaccU, 0x4848d890U, 0x03030506U, 0xf6f601f7U, + 0x0e0e121cU, 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, + 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, 0xe1e138d9U, + 0xf8f813ebU, 0x9898b32bU, 0x11113322U, 0x6969bbd2U, 0xd9d970a9U, + 0x8e8e8907U, 0x9494a733U, 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, + 0xe9e920c9U, 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, + 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, 0xbfbfda65U, + 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, 0x4141c382U, 0x9999b029U, + 0x2d2d775aU, 0x0f0f111eU, 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, + 0x16163a2cU, }; -static const u32 Te4[256] = -{ - 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, - 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, - 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, - 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, - 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, - 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, - 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, - 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, - 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, - 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, - 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, - 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, - 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, - 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, - 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, - 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, - 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, - 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, - 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, - 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, - 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, - 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, - 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, - 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, - 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, - 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, - 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, - 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, - 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, - 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, - 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, - 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, - 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, - 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, - 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, - 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, - 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, - 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, - 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, - 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, - 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, - 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, - 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, - 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, - 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, - 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, - 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, - 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, - 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, - 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, - 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, - 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, - 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, - 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, - 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, - 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, - 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, - 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, - 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, - 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, - 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, - 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, - 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, - 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, +static const u32 Te4[256] = { + 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, 0xf2f2f2f2U, + 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, 0x30303030U, 0x01010101U, + 0x67676767U, 0x2b2b2b2bU, 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, + 0x76767676U, 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, + 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, 0xadadadadU, + 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, 0x9c9c9c9cU, 0xa4a4a4a4U, + 0x72727272U, 0xc0c0c0c0U, 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, + 0x26262626U, 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, + 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, 0x71717171U, + 0xd8d8d8d8U, 0x31313131U, 0x15151515U, 0x04040404U, 0xc7c7c7c7U, + 0x23232323U, 0xc3c3c3c3U, 0x18181818U, 0x96969696U, 0x05050505U, + 0x9a9a9a9aU, 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, + 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, 0x09090909U, + 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, 0x1b1b1b1bU, 0x6e6e6e6eU, + 0x5a5a5a5aU, 0xa0a0a0a0U, 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, + 0xb3b3b3b3U, 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, + 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, 0x20202020U, + 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, 0x6a6a6a6aU, 0xcbcbcbcbU, + 0xbebebebeU, 0x39393939U, 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, + 0xcfcfcfcfU, 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, + 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, 0x45454545U, + 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, 0x50505050U, 0x3c3c3c3cU, + 0x9f9f9f9fU, 0xa8a8a8a8U, 0x51515151U, 0xa3a3a3a3U, 0x40404040U, + 0x8f8f8f8fU, 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, + 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, 0x10101010U, + 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, 0xcdcdcdcdU, 0x0c0c0c0cU, + 0x13131313U, 0xececececU, 0x5f5f5f5fU, 0x97979797U, 0x44444444U, + 0x17171717U, 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, + 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, 0x60606060U, + 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, 0x22222222U, 0x2a2a2a2aU, + 0x90909090U, 0x88888888U, 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, + 0x14141414U, 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, + 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, 0x49494949U, + 0x06060606U, 0x24242424U, 0x5c5c5c5cU, 0xc2c2c2c2U, 0xd3d3d3d3U, + 0xacacacacU, 0x62626262U, 0x91919191U, 0x95959595U, 0xe4e4e4e4U, + 0x79797979U, 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, + 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, 0x6c6c6c6cU, + 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, 0x65656565U, 0x7a7a7a7aU, + 0xaeaeaeaeU, 0x08080808U, 0xbabababaU, 0x78787878U, 0x25252525U, + 0x2e2e2e2eU, 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, + 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, 0x4b4b4b4bU, + 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, 0x70707070U, 0x3e3e3e3eU, + 0xb5b5b5b5U, 0x66666666U, 0x48484848U, 0x03030303U, 0xf6f6f6f6U, + 0x0e0e0e0eU, 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, + 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, 0xe1e1e1e1U, + 0xf8f8f8f8U, 0x98989898U, 0x11111111U, 0x69696969U, 0xd9d9d9d9U, + 0x8e8e8e8eU, 0x94949494U, 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, + 0xe9e9e9e9U, 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, + 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, 0xbfbfbfbfU, + 0xe6e6e6e6U, 0x42424242U, 0x68686868U, 0x41414141U, 0x99999999U, + 0x2d2d2d2dU, 0x0f0f0f0fU, 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, + 0x16161616U, }; -static const u32 Td0[256] = -{ - 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, - 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, - 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, - 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, - 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, - 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, - 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, - 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, - 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, - 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, - 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, - 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, - 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, - 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, - 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, - 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, - 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, - 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, - 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, - 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, - 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, - 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, - 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, - 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, - 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, - 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, - 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, - 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, - 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, - 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, - 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, - 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, - 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, - 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, - 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, - 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, - 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, - 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, - 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, - 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, - 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, - 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, - 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, - 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, - 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, - 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, - 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, - 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, - 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, - 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, - 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, - 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, - 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, - 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, - 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, - 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, - 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, - 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, - 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, - 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, - 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, - 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, - 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, - 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, +static const u32 Td0[256] = { + 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, 0x3bab6bcbU, + 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, 0x2030fa55U, 0xad766df6U, + 0x88cc7691U, 0xf5024c25U, 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, + 0xb562a38fU, 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, + 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, 0x038f5fe7U, + 0x15929c95U, 0xbf6d7aebU, 0x955259daU, 0xd4be832dU, 0x587421d3U, + 0x49e06929U, 0x8ec9c844U, 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, + 0x27b971ddU, 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, + 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, 0xb16477e0U, + 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, 0x70486858U, 0x8f45fd19U, + 0x94de6c87U, 0x527bf8b7U, 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, + 0x6655ab2aU, 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, + 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, 0x8acf1c2bU, + 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, 0x65daf4cdU, 0x0605bed5U, + 0xd134621fU, 0xc4a6fe8aU, 0x342e539dU, 0xa2f355a0U, 0x058ae132U, + 0xa4f6eb75U, 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, + 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, 0x91548db5U, + 0x71c45d05U, 0x0406d46fU, 0x605015ffU, 0x1998fb24U, 0xd6bde997U, + 0x894043ccU, 0x67d99e77U, 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, + 0x79c8eedbU, 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, + 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, 0xfd0efffbU, + 0x0f853856U, 0x3daed51eU, 0x362d3927U, 0x0a0fd964U, 0x685ca621U, + 0x9b5b54d1U, 0x24362e3aU, 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, + 0x1b9b919eU, 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, + 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, 0x0e090d0bU, + 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, 0x57f11985U, 0xaf75074cU, + 0xee99ddbbU, 0xa37f60fdU, 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, + 0x5bfb7e34U, 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, + 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, 0x854a247dU, + 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, 0x1d9e2f4bU, 0xdcb230f3U, + 0x0d8652ecU, 0x77c1e3d0U, 0x2bb3166cU, 0xa970b999U, 0x119448faU, + 0x47e96422U, 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, + 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, 0xa6f581cfU, + 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, 0x2c3a9de4U, 0x5078920dU, + 0x6a5fcc9bU, 0x547e4662U, 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, + 0x82c3aff5U, 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, + 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, 0xcd267809U, + 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, 0xe6956e65U, 0xaaffe67eU, + 0x21bccf08U, 0xef15e8e6U, 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, + 0x29b07cd6U, 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, + 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, 0xf104984aU, + 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, 0x764dd68dU, 0x43efb04dU, + 0xccaa4d54U, 0xe49604dfU, 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, + 0x4665517fU, 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, + 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, 0x9ad7618cU, + 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, 0xcea927eeU, 0xb761c935U, + 0xe11ce5edU, 0x7a47b13cU, 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, + 0x73c737bfU, 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, + 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, 0x161dc372U, + 0xbce2250cU, 0x283c498bU, 0xff0d9541U, 0x39a80171U, 0x080cb3deU, + 0xd8b4e49cU, 0x6456c190U, 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, + 0xd0b85742U, }; -static const u32 Td1[256] = -{ - 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, - 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, - 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, - 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, - 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, - 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, - 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, - 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, - 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, - 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, - 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, - 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, - 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, - 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, - 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, - 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, - 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, - 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, - 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, - 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, - 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, - 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, - 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, - 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, - 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, - 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, - 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, - 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, - 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, - 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, - 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, - 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, - 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, - 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, - 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, - 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, - 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, - 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, - 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, - 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, - 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, - 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, - 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, - 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, - 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, - 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, - 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, - 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, - 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, - 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, - 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, - 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, - 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, - 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, - 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, - 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, - 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, - 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, - 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, - 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, - 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, - 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, - 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, - 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, +static const u32 Td1[256] = { + 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, 0xcb3bab6bU, + 0xf11f9d45U, 0xabacfa58U, 0x934be303U, 0x552030faU, 0xf6ad766dU, + 0x9188cc76U, 0x25f5024cU, 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, + 0x8fb562a3U, 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, + 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, 0xe7038f5fU, + 0x9515929cU, 0xebbf6d7aU, 0xda955259U, 0x2dd4be83U, 0xd3587421U, + 0x2949e069U, 0x448ec9c8U, 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, + 0xdd27b971U, 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, + 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, 0xe0b16477U, + 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, 0x58704868U, 0x198f45fdU, + 0x8794de6cU, 0xb7527bf8U, 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, + 0x2a6655abU, 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, + 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, 0x2b8acf1cU, + 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, 0xcd65daf4U, 0xd50605beU, + 0x1fd13462U, 0x8ac4a6feU, 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, + 0x75a4f6ebU, 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, + 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, 0xb591548dU, + 0x0571c45dU, 0x6f0406d4U, 0xff605015U, 0x241998fbU, 0x97d6bde9U, + 0xcc894043U, 0x7767d99eU, 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, + 0xdb79c8eeU, 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, + 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, 0xfbfd0effU, + 0x560f8538U, 0x1e3daed5U, 0x27362d39U, 0x640a0fd9U, 0x21685ca6U, + 0xd19b5b54U, 0x3a24362eU, 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, + 0x9e1b9b91U, 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, + 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, 0x0b0e090dU, + 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, 0x8557f119U, 0x4caf7507U, + 0xbbee99ddU, 0xfda37f60U, 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, + 0x345bfb7eU, 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, + 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, 0x7d854a24U, + 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, 0x4b1d9e2fU, 0xf3dcb230U, + 0xec0d8652U, 0xd077c1e3U, 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, + 0x2247e964U, 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, + 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, 0xcfa6f581U, + 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, 0xe42c3a9dU, 0x0d507892U, + 0x9b6a5fccU, 0x62547e46U, 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, + 0xf582c3afU, 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, + 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, 0x09cd2678U, + 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, 0x65e6956eU, 0x7eaaffe6U, + 0x0821bccfU, 0xe6ef15e8U, 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, + 0xd629b07cU, 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, + 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, 0x4af10498U, + 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, 0x8d764dd6U, 0x4d43efb0U, + 0x54ccaa4dU, 0xdfe49604U, 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, + 0x7f466551U, 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, + 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, 0x8c9ad761U, + 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, 0xeecea927U, 0x35b761c9U, + 0xede11ce5U, 0x3c7a47b1U, 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, + 0xbf73c737U, 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, + 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, 0x72161dc3U, + 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, 0x7139a801U, 0xde080cb3U, + 0x9cd8b4e4U, 0x906456c1U, 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, + 0x42d0b857U, }; -static const u32 Td2[256] = -{ - 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, - 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, - 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, - 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, - 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, - 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, - 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, - 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, - 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, - 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, - 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, - 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, - 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, - 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, - 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, - 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, - 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, - 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, - 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, - 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, - 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, - 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, - 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, - 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, - 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, - 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, - 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, - 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, - 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, - 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, - 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, - 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, - 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, - 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, - 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, - 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, - 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, - 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, - 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, - 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, - 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, - 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, - 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, - 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, - 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, - 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, - 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, - 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, - 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, - 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, - 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, - 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, - 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, - 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, - 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, - 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, - 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, - 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, - 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, - 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, - 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, - 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, - 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, - 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, +static const u32 Td2[256] = { + 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, 0x6bcb3babU, + 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, 0xfa552030U, 0x6df6ad76U, + 0x769188ccU, 0x4c25f502U, 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, + 0xa38fb562U, 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, + 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, 0x5fe7038fU, + 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, 0x832dd4beU, 0x21d35874U, + 0x692949e0U, 0xc8448ec9U, 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, + 0x71dd27b9U, 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, + 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, 0x77e0b164U, + 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, 0x68587048U, 0xfd198f45U, + 0x6c8794deU, 0xf8b7527bU, 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, + 0xab2a6655U, 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, + 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, 0x1c2b8acfU, + 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, 0xf4cd65daU, 0xbed50605U, + 0x621fd134U, 0xfe8ac4a6U, 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, + 0xeb75a4f6U, 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, + 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, 0x8db59154U, + 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, 0xfb241998U, 0xe997d6bdU, + 0x43cc8940U, 0x9e7767d9U, 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, + 0xeedb79c8U, 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, + 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, 0xfffbfd0eU, + 0x38560f85U, 0xd51e3daeU, 0x3927362dU, 0xd9640a0fU, 0xa621685cU, + 0x54d19b5bU, 0x2e3a2436U, 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, + 0x919e1b9bU, 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, + 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, 0x0d0b0e09U, + 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, 0x198557f1U, 0x074caf75U, + 0xddbbee99U, 0x60fda37fU, 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, + 0x7e345bfbU, 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, + 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, 0x247d854aU, + 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, 0x2f4b1d9eU, 0x30f3dcb2U, + 0x52ec0d86U, 0xe3d077c1U, 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, + 0x642247e9U, 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, + 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, 0x81cfa6f5U, + 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, 0x9de42c3aU, 0x920d5078U, + 0xcc9b6a5fU, 0x4662547eU, 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, + 0xaff582c3U, 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, + 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, 0x7809cd26U, + 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, 0x6e65e695U, 0xe67eaaffU, + 0xcf0821bcU, 0xe8e6ef15U, 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, + 0x7cd629b0U, 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, + 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, 0x984af104U, + 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, 0xd68d764dU, 0xb04d43efU, + 0x4d54ccaaU, 0x04dfe496U, 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, + 0x517f4665U, 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, + 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, 0x618c9ad7U, + 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, 0x27eecea9U, 0xc935b761U, + 0xe5ede11cU, 0xb13c7a47U, 0xdf599cd2U, 0x733f55f2U, 0xce791814U, + 0x37bf73c7U, 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, + 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, 0xc372161dU, + 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, 0x017139a8U, 0xb3de080cU, + 0xe49cd8b4U, 0xc1906456U, 0x84617bcbU, 0xb670d532U, 0x5c74486cU, + 0x5742d0b8U, }; -static const u32 Td3[256] = -{ - 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, - 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, - 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, - 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, - 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, - 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, - 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, - 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, - 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, - 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, - 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, - 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, - 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, - 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, - 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, - 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, - 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, - 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, - 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, - 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, - 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, - 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, - 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, - 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, - 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, - 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, - 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, - 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, - 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, - 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, - 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, - 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, - 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, - 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, - 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, - 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, - 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, - 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, - 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, - 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, - 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, - 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, - 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, - 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, - 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, - 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, - 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, - 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, - 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, - 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, - 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, - 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, - 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, - 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, - 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, - 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, - 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, - 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, - 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, - 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, - 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, - 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, - 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, - 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, +static const u32 Td3[256] = { + 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, 0xab6bcb3bU, + 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, 0x30fa5520U, 0x766df6adU, + 0xcc769188U, 0x024c25f5U, 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, + 0x62a38fb5U, 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, + 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, 0x8f5fe703U, + 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, 0xbe832dd4U, 0x7421d358U, + 0xe0692949U, 0xc9c8448eU, 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, + 0xb971dd27U, 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, + 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, 0x6477e0b1U, + 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, 0x48685870U, 0x45fd198fU, + 0xde6c8794U, 0x7bf8b752U, 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, + 0x55ab2a66U, 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, + 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, 0xcf1c2b8aU, + 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, 0xdaf4cd65U, 0x05bed506U, + 0x34621fd1U, 0xa6fe8ac4U, 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, + 0xf6eb75a4U, 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, + 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, 0x548db591U, + 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, 0x98fb2419U, 0xbde997d6U, + 0x4043cc89U, 0xd99e7767U, 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, + 0xc8eedb79U, 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, + 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, 0x0efffbfdU, + 0x8538560fU, 0xaed51e3dU, 0x2d392736U, 0x0fd9640aU, 0x5ca62168U, + 0x5b54d19bU, 0x362e3a24U, 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, + 0x9b919e1bU, 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, + 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, 0x090d0b0eU, + 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, 0xf1198557U, 0x75074cafU, + 0x99ddbbeeU, 0x7f60fda3U, 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, + 0xfb7e345bU, 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, + 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, 0x4a247d85U, + 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, 0x9e2f4b1dU, 0xb230f3dcU, + 0x8652ec0dU, 0xc1e3d077U, 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, + 0xe9642247U, 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, + 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, 0xf581cfa6U, + 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, 0x3a9de42cU, 0x78920d50U, + 0x5fcc9b6aU, 0x7e466254U, 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, + 0xc3aff582U, 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, + 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, 0x267809cdU, + 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, 0x956e65e6U, 0xffe67eaaU, + 0xbccf0821U, 0x15e8e6efU, 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, + 0xb07cd629U, 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, + 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, 0x04984af1U, + 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, 0x4dd68d76U, 0xefb04d43U, + 0xaa4d54ccU, 0x9604dfe4U, 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, + 0x65517f46U, 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, + 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, 0xd7618c9aU, + 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, 0xa927eeceU, 0x61c935b7U, + 0x1ce5ede1U, 0x47b13c7aU, 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, + 0xc737bf73U, 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, + 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, 0x1dc37216U, + 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, 0xa8017139U, 0x0cb3de08U, + 0xb4e49cd8U, 0x56c19064U, 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, + 0xb85742d0U, }; -static const u32 Td4[256] = -{ - 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, - 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, - 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, - 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU, - 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, - 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, - 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, - 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU, - 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, - 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, - 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, - 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, - 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, - 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U, - 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, - 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, - 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, - 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U, - 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, - 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, - 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, - 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, - 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, - 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U, - 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, - 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, - 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, - 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U, - 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, - 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, - 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, - 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, - 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, - 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU, - 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, - 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, - 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, - 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U, - 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, - 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, - 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, - 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U, - 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, - 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU, - 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, - 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, - 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, - 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U, - 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, - 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, - 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, - 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU, - 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, - 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU, - 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, - 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, - 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, - 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U, - 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, - 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, - 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, - 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, - 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, - 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, +static const u32 Td4[256] = { + 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, 0x30303030U, + 0x36363636U, 0xa5a5a5a5U, 0x38383838U, 0xbfbfbfbfU, 0x40404040U, + 0xa3a3a3a3U, 0x9e9e9e9eU, 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, + 0xfbfbfbfbU, 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, + 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, 0x34343434U, + 0x8e8e8e8eU, 0x43434343U, 0x44444444U, 0xc4c4c4c4U, 0xdedededeU, + 0xe9e9e9e9U, 0xcbcbcbcbU, 0x54545454U, 0x7b7b7b7bU, 0x94949494U, + 0x32323232U, 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, + 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, 0x42424242U, + 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, 0x08080808U, 0x2e2e2e2eU, + 0xa1a1a1a1U, 0x66666666U, 0x28282828U, 0xd9d9d9d9U, 0x24242424U, + 0xb2b2b2b2U, 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, + 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, 0x72727272U, + 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, 0x86868686U, 0x68686868U, + 0x98989898U, 0x16161616U, 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, + 0xccccccccU, 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, + 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, 0xfdfdfdfdU, + 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, 0x5e5e5e5eU, 0x15151515U, + 0x46464646U, 0x57575757U, 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, + 0x84848484U, 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, + 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, 0xf7f7f7f7U, + 0xe4e4e4e4U, 0x58585858U, 0x05050505U, 0xb8b8b8b8U, 0xb3b3b3b3U, + 0x45454545U, 0x06060606U, 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, + 0x8f8f8f8fU, 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, + 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, 0x01010101U, + 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, 0x3a3a3a3aU, 0x91919191U, + 0x11111111U, 0x41414141U, 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, + 0xeaeaeaeaU, 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, + 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, 0x96969696U, + 0xacacacacU, 0x74747474U, 0x22222222U, 0xe7e7e7e7U, 0xadadadadU, + 0x35353535U, 0x85858585U, 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, + 0xe8e8e8e8U, 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, + 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, 0x1d1d1d1dU, + 0x29292929U, 0xc5c5c5c5U, 0x89898989U, 0x6f6f6f6fU, 0xb7b7b7b7U, + 0x62626262U, 0x0e0e0e0eU, 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, + 0x1b1b1b1bU, 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, + 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, 0x9a9a9a9aU, + 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, 0x78787878U, 0xcdcdcdcdU, + 0x5a5a5a5aU, 0xf4f4f4f4U, 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, + 0x33333333U, 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, + 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, 0x27272727U, + 0x80808080U, 0xececececU, 0x5f5f5f5fU, 0x60606060U, 0x51515151U, + 0x7f7f7f7fU, 0xa9a9a9a9U, 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, + 0x0d0d0d0dU, 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, + 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, 0xa0a0a0a0U, + 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, 0xaeaeaeaeU, 0x2a2a2a2aU, + 0xf5f5f5f5U, 0xb0b0b0b0U, 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, + 0x3c3c3c3cU, 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, + 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, 0xbabababaU, + 0x77777777U, 0xd6d6d6d6U, 0x26262626U, 0xe1e1e1e1U, 0x69696969U, + 0x14141414U, 0x63636363U, 0x55555555U, 0x21212121U, 0x0c0c0c0cU, + 0x7d7d7d7dU, }; -static const u32 rcon[] = -{ - 0x01000000, 0x02000000, 0x04000000, 0x08000000, - 0x10000000, 0x20000000, 0x40000000, 0x80000000, - 0x1B000000, 0x36000000, - /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +static const u32 rcon[] = { + 0x01000000, + 0x02000000, + 0x04000000, + 0x08000000, + 0x10000000, + 0x20000000, + 0x40000000, + 0x80000000, + 0x1B000000, + 0x36000000, + /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ }; -#define GETU32(plaintext) (((u32)(plaintext)[0] << 24) ^ \ - ((u32)(plaintext)[1] << 16) ^ \ - ((u32)(plaintext)[2] << 8) ^ \ - ((u32)(plaintext)[3])) +#define GETU32(plaintext) \ + (((u32)(plaintext)[0] << 24) ^ ((u32)(plaintext)[1] << 16) ^ \ + ((u32)(plaintext)[2] << 8) ^ ((u32)(plaintext)[3])) -#define PUTU32(ciphertext, st) { (ciphertext)[0] = (u8)((st) >> 24); \ - (ciphertext)[1] = (u8)((st) >> 16); \ - (ciphertext)[2] = (u8)((st) >> 8); \ - (ciphertext)[3] = (u8)(st); } +#define PUTU32(ciphertext, st) \ + { \ + (ciphertext)[0] = (u8)((st) >> 24); \ + (ciphertext)[1] = (u8)((st) >> 16); \ + (ciphertext)[2] = (u8)((st) >> 8); \ + (ciphertext)[3] = (u8)(st); \ + } /** * Expand the cipher key into the encryption key schedule. @@ -713,21 +591,17 @@ int rijndaelSetupEncrypt(u32 *rk, const u8 *key, int keybits) int i = 0; u32 temp; - rk[0] = GETU32(key ); - rk[1] = GETU32(key + 4); - rk[2] = GETU32(key + 8); + rk[0] = GETU32(key); + rk[1] = GETU32(key + 4); + rk[2] = GETU32(key + 8); rk[3] = GETU32(key + 12); - if (keybits == 128) - { - for (;;) - { - temp = rk[3]; - rk[4] = rk[0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; + if (keybits == 128) { + for (;;) { + temp = rk[3]; + rk[4] = rk[0] ^ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te4[(temp) &0xff] & 0x0000ff00) ^ (Te4[(temp >> 24)] & 0x000000ff) ^ + rcon[i]; rk[5] = rk[1] ^ rk[4]; rk[6] = rk[2] ^ rk[5]; rk[7] = rk[3] ^ rk[6]; @@ -738,54 +612,45 @@ int rijndaelSetupEncrypt(u32 *rk, const u8 *key, int keybits) } rk[4] = GETU32(key + 16); rk[5] = GETU32(key + 20); - if (keybits == 192) - { - for (;;) - { - temp = rk[ 5]; - rk[ 6] = rk[ 0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[ 7] = rk[ 1] ^ rk[ 6]; - rk[ 8] = rk[ 2] ^ rk[ 7]; - rk[ 9] = rk[ 3] ^ rk[ 8]; + if (keybits == 192) { + for (;;) { + temp = rk[5]; + rk[6] = rk[0] ^ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te4[(temp) &0xff] & 0x0000ff00) ^ (Te4[(temp >> 24)] & 0x000000ff) ^ + rcon[i]; + rk[7] = rk[1] ^ rk[6]; + rk[8] = rk[2] ^ rk[7]; + rk[9] = rk[3] ^ rk[8]; if (++i == 8) return 12; - rk[10] = rk[ 4] ^ rk[ 9]; - rk[11] = rk[ 5] ^ rk[10]; + rk[10] = rk[4] ^ rk[9]; + rk[11] = rk[5] ^ rk[10]; rk += 6; } } rk[6] = GETU32(key + 24); rk[7] = GETU32(key + 28); - if (keybits == 256) - { - for (;;) - { - temp = rk[ 7]; - rk[ 8] = rk[ 0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[ 9] = rk[ 1] ^ rk[ 8]; - rk[10] = rk[ 2] ^ rk[ 9]; - rk[11] = rk[ 3] ^ rk[10]; + if (keybits == 256) { + for (;;) { + temp = rk[7]; + rk[8] = rk[0] ^ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te4[(temp) &0xff] & 0x0000ff00) ^ (Te4[(temp >> 24)] & 0x000000ff) ^ + rcon[i]; + rk[9] = rk[1] ^ rk[8]; + rk[10] = rk[2] ^ rk[9]; + rk[11] = rk[3] ^ rk[10]; if (++i == 7) return 14; temp = rk[11]; - rk[12] = rk[ 4] ^ - (Te4[(temp >> 24) ] & 0xff000000) ^ - (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(temp ) & 0xff] & 0x000000ff); - rk[13] = rk[ 5] ^ rk[12]; - rk[14] = rk[ 6] ^ rk[13]; - rk[15] = rk[ 7] ^ rk[14]; + rk[12] = rk[4] ^ (Te4[(temp >> 24)] & 0xff000000) ^ + (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^ + (Te4[(temp) &0xff] & 0x000000ff); + rk[13] = rk[5] ^ rk[12]; + rk[14] = rk[6] ^ rk[13]; + rk[15] = rk[7] ^ rk[14]; rk += 8; } } @@ -805,404 +670,411 @@ int rijndaelSetupDecrypt(u32 *rk, const u8 *key, int keybits) /* expand the cipher key: */ nrounds = rijndaelSetupEncrypt(rk, key, keybits); /* invert the order of the round keys: */ - for (i = 0, j = 4*nrounds; i < j; i += 4, j -= 4) - { - temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; - temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; - temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; - temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; + for (i = 0, j = 4 * nrounds; i < j; i += 4, j -= 4) { + temp = rk[i]; + rk[i] = rk[j]; + rk[j] = temp; + temp = rk[i + 1]; + rk[i + 1] = rk[j + 1]; + rk[j + 1] = temp; + temp = rk[i + 2]; + rk[i + 2] = rk[j + 2]; + rk[j + 2] = temp; + temp = rk[i + 3]; + rk[i + 3] = rk[j + 3]; + rk[j + 3] = temp; } - /* apply the inverse MixColumn transform to all round keys but the first and the last: */ - for (i = 1; i < nrounds; i++) - { + /* apply the inverse MixColumn transform to all round keys but the first and + * the last: */ + for (i = 1; i < nrounds; i++) { rk += 4; - rk[0] = - Td0[Te4[(rk[0] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[0] ) & 0xff] & 0xff]; - rk[1] = - Td0[Te4[(rk[1] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[1] ) & 0xff] & 0xff]; - rk[2] = - Td0[Te4[(rk[2] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[2] ) & 0xff] & 0xff]; - rk[3] = - Td0[Te4[(rk[3] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[3] ) & 0xff] & 0xff]; + rk[0] = Td0[Te4[(rk[0] >> 24)] & 0xff] ^ + Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^ Td3[Te4[(rk[0]) & 0xff] & 0xff]; + rk[1] = Td0[Te4[(rk[1] >> 24)] & 0xff] ^ + Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^ Td3[Te4[(rk[1]) & 0xff] & 0xff]; + rk[2] = Td0[Te4[(rk[2] >> 24)] & 0xff] ^ + Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^ Td3[Te4[(rk[2]) & 0xff] & 0xff]; + rk[3] = Td0[Te4[(rk[3] >> 24)] & 0xff] ^ + Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^ + Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^ Td3[Te4[(rk[3]) & 0xff] & 0xff]; } return nrounds; } -void rijndaelEncrypt(const u32 *rk, int nrounds, const u8 plaintext[16], - u8 ciphertext[16]) +void rijndaelEncrypt( + const u32 *rk, int nrounds, const u8 plaintext[16], u8 ciphertext[16]) { u32 s0, s1, s2, s3, t0, t1, t2, t3; - #ifndef FULL_UNROLL - int r; - #endif /* ?FULL_UNROLL */ +#ifndef FULL_UNROLL + int r; +#endif /* ?FULL_UNROLL */ /* * map byte array block to cipher state * and add initial round key: - */ - s0 = GETU32(plaintext ) ^ rk[0]; - s1 = GETU32(plaintext + 4) ^ rk[1]; - s2 = GETU32(plaintext + 8) ^ rk[2]; + */ + s0 = GETU32(plaintext) ^ rk[0]; + s1 = GETU32(plaintext + 4) ^ rk[1]; + s2 = GETU32(plaintext + 8) ^ rk[2]; s3 = GETU32(plaintext + 12) ^ rk[3]; - #ifdef FULL_UNROLL - /* round 1: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7]; - /* round 2: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11]; - /* round 3: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15]; - /* round 4: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19]; - /* round 5: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23]; - /* round 6: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27]; - /* round 7: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31]; - /* round 8: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35]; - /* round 9: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39]; - if (nrounds > 10) - { - /* round 10: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43]; - /* round 11: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47]; - if (nrounds > 12) - { - /* round 12: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51]; - /* round 13: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55]; - } +#ifdef FULL_UNROLL + /* round 1: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ + Te3[s3 & 0xff] ^ rk[4]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ + Te3[s0 & 0xff] ^ rk[5]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ + Te3[s1 & 0xff] ^ rk[6]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ + Te3[s2 & 0xff] ^ rk[7]; + /* round 2: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ + Te3[t3 & 0xff] ^ rk[8]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ + Te3[t0 & 0xff] ^ rk[9]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ + Te3[t1 & 0xff] ^ rk[10]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ + Te3[t2 & 0xff] ^ rk[11]; + /* round 3: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ + Te3[s3 & 0xff] ^ rk[12]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ + Te3[s0 & 0xff] ^ rk[13]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ + Te3[s1 & 0xff] ^ rk[14]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ + Te3[s2 & 0xff] ^ rk[15]; + /* round 4: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ + Te3[t3 & 0xff] ^ rk[16]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ + Te3[t0 & 0xff] ^ rk[17]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ + Te3[t1 & 0xff] ^ rk[18]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ + Te3[t2 & 0xff] ^ rk[19]; + /* round 5: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ + Te3[s3 & 0xff] ^ rk[20]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ + Te3[s0 & 0xff] ^ rk[21]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ + Te3[s1 & 0xff] ^ rk[22]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ + Te3[s2 & 0xff] ^ rk[23]; + /* round 6: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ + Te3[t3 & 0xff] ^ rk[24]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ + Te3[t0 & 0xff] ^ rk[25]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ + Te3[t1 & 0xff] ^ rk[26]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ + Te3[t2 & 0xff] ^ rk[27]; + /* round 7: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ + Te3[s3 & 0xff] ^ rk[28]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ + Te3[s0 & 0xff] ^ rk[29]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ + Te3[s1 & 0xff] ^ rk[30]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ + Te3[s2 & 0xff] ^ rk[31]; + /* round 8: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ + Te3[t3 & 0xff] ^ rk[32]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ + Te3[t0 & 0xff] ^ rk[33]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ + Te3[t1 & 0xff] ^ rk[34]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ + Te3[t2 & 0xff] ^ rk[35]; + /* round 9: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ + Te3[s3 & 0xff] ^ rk[36]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ + Te3[s0 & 0xff] ^ rk[37]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ + Te3[s1 & 0xff] ^ rk[38]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ + Te3[s2 & 0xff] ^ rk[39]; + if (nrounds > 10) { + /* round 10: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ + Te3[t3 & 0xff] ^ rk[40]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ + Te3[t0 & 0xff] ^ rk[41]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ + Te3[t1 & 0xff] ^ rk[42]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ + Te3[t2 & 0xff] ^ rk[43]; + /* round 11: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ + Te3[s3 & 0xff] ^ rk[44]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ + Te3[s0 & 0xff] ^ rk[45]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ + Te3[s1 & 0xff] ^ rk[46]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ + Te3[s2 & 0xff] ^ rk[47]; + if (nrounds > 12) { + /* round 12: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ + Te3[t3 & 0xff] ^ rk[48]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ + Te3[t0 & 0xff] ^ rk[49]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ + Te3[t1 & 0xff] ^ rk[50]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ + Te3[t2 & 0xff] ^ rk[51]; + /* round 13: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ + Te3[s3 & 0xff] ^ rk[52]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ + Te3[s0 & 0xff] ^ rk[53]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ + Te3[s1 & 0xff] ^ rk[54]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ + Te3[s2 & 0xff] ^ rk[55]; } - rk += nrounds << 2; - #else /* !FULL_UNROLL */ - /* - * nrounds - 1 full rounds: - */ - r = nrounds >> 1; - for (;;) - { - t0 = - Te0[(s0 >> 24) ] ^ - Te1[(s1 >> 16) & 0xff] ^ - Te2[(s2 >> 8) & 0xff] ^ - Te3[(s3 ) & 0xff] ^ - rk[4]; - t1 = - Te0[(s1 >> 24) ] ^ - Te1[(s2 >> 16) & 0xff] ^ - Te2[(s3 >> 8) & 0xff] ^ - Te3[(s0 ) & 0xff] ^ - rk[5]; - t2 = - Te0[(s2 >> 24) ] ^ - Te1[(s3 >> 16) & 0xff] ^ - Te2[(s0 >> 8) & 0xff] ^ - Te3[(s1 ) & 0xff] ^ - rk[6]; - t3 = - Te0[(s3 >> 24) ] ^ - Te1[(s0 >> 16) & 0xff] ^ - Te2[(s1 >> 8) & 0xff] ^ - Te3[(s2 ) & 0xff] ^ - rk[7]; - rk += 8; - if (--r == 0) - break; - s0 = - Te0[(t0 >> 24) ] ^ - Te1[(t1 >> 16) & 0xff] ^ - Te2[(t2 >> 8) & 0xff] ^ - Te3[(t3 ) & 0xff] ^ - rk[0]; - s1 = - Te0[(t1 >> 24) ] ^ - Te1[(t2 >> 16) & 0xff] ^ - Te2[(t3 >> 8) & 0xff] ^ - Te3[(t0 ) & 0xff] ^ - rk[1]; - s2 = - Te0[(t2 >> 24) ] ^ - Te1[(t3 >> 16) & 0xff] ^ - Te2[(t0 >> 8) & 0xff] ^ - Te3[(t1 ) & 0xff] ^ - rk[2]; - s3 = - Te0[(t3 >> 24) ] ^ - Te1[(t0 >> 16) & 0xff] ^ - Te2[(t1 >> 8) & 0xff] ^ - Te3[(t2 ) & 0xff] ^ - rk[3]; - } - #endif /* ?FULL_UNROLL */ + } + rk += nrounds << 2; +#else /* !FULL_UNROLL */ /* - * apply last round and - * map cipher state to byte array block: - */ - s0 = - (Te4[(t0 >> 24) ] & 0xff000000) ^ - (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t3 ) & 0xff] & 0x000000ff) ^ - rk[0]; - PUTU32(ciphertext , s0); - s1 = - (Te4[(t1 >> 24) ] & 0xff000000) ^ - (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t0 ) & 0xff] & 0x000000ff) ^ - rk[1]; - PUTU32(ciphertext + 4, s1); - s2 = - (Te4[(t2 >> 24) ] & 0xff000000) ^ - (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t1 ) & 0xff] & 0x000000ff) ^ - rk[2]; - PUTU32(ciphertext + 8, s2); - s3 = - (Te4[(t3 >> 24) ] & 0xff000000) ^ - (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t2 ) & 0xff] & 0x000000ff) ^ - rk[3]; + * nrounds - 1 full rounds: + */ + r = nrounds >> 1; + for (;;) { + t0 = Te0[(s0 >> 24)] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ + Te3[(s3) &0xff] ^ rk[4]; + t1 = Te0[(s1 >> 24)] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ + Te3[(s0) &0xff] ^ rk[5]; + t2 = Te0[(s2 >> 24)] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ + Te3[(s1) &0xff] ^ rk[6]; + t3 = Te0[(s3 >> 24)] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ + Te3[(s2) &0xff] ^ rk[7]; + rk += 8; + if (--r == 0) + break; + s0 = Te0[(t0 >> 24)] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ + Te3[(t3) &0xff] ^ rk[0]; + s1 = Te0[(t1 >> 24)] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ + Te3[(t0) &0xff] ^ rk[1]; + s2 = Te0[(t2 >> 24)] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ + Te3[(t1) &0xff] ^ rk[2]; + s3 = Te0[(t3 >> 24)] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ + Te3[(t2) &0xff] ^ rk[3]; + } +#endif /* ?FULL_UNROLL */ + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = (Te4[(t0 >> 24)] & 0xff000000) ^ (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ (Te4[(t3) &0xff] & 0x000000ff) ^ + rk[0]; + PUTU32(ciphertext, s0); + s1 = (Te4[(t1 >> 24)] & 0xff000000) ^ (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ (Te4[(t0) &0xff] & 0x000000ff) ^ + rk[1]; + PUTU32(ciphertext + 4, s1); + s2 = (Te4[(t2 >> 24)] & 0xff000000) ^ (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ (Te4[(t1) &0xff] & 0x000000ff) ^ + rk[2]; + PUTU32(ciphertext + 8, s2); + s3 = (Te4[(t3 >> 24)] & 0xff000000) ^ (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ + (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ (Te4[(t2) &0xff] & 0x000000ff) ^ + rk[3]; PUTU32(ciphertext + 12, s3); } -void rijndaelDecrypt(const u32 *rk, int nrounds, const u8 ciphertext[16], - u8 plaintext[16]) +void rijndaelDecrypt( + const u32 *rk, int nrounds, const u8 ciphertext[16], u8 plaintext[16]) { u32 s0, s1, s2, s3, t0, t1, t2, t3; - #ifndef FULL_UNROLL - int r; - #endif /* ?FULL_UNROLL */ +#ifndef FULL_UNROLL + int r; +#endif /* ?FULL_UNROLL */ /* - * map byte array block to cipher state - * and add initial round key: - */ - s0 = GETU32(ciphertext ) ^ rk[0]; - s1 = GETU32(ciphertext + 4) ^ rk[1]; - s2 = GETU32(ciphertext + 8) ^ rk[2]; - s3 = GETU32(ciphertext + 12) ^ rk[3]; - #ifdef FULL_UNROLL - /* round 1: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7]; - /* round 2: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11]; - /* round 3: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15]; - /* round 4: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19]; - /* round 5: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23]; - /* round 6: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27]; - /* round 7: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31]; - /* round 8: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35]; - /* round 9: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39]; - if (nrounds > 10) - { - /* round 10: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43]; - /* round 11: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47]; - if (nrounds > 12) - { - /* round 12: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51]; - /* round 13: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55]; - } + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(ciphertext) ^ rk[0]; + s1 = GETU32(ciphertext + 4) ^ rk[1]; + s2 = GETU32(ciphertext + 8) ^ rk[2]; + s3 = GETU32(ciphertext + 12) ^ rk[3]; +#ifdef FULL_UNROLL + /* round 1: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ + Td3[s1 & 0xff] ^ rk[4]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ + Td3[s2 & 0xff] ^ rk[5]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ + Td3[s3 & 0xff] ^ rk[6]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ + Td3[s0 & 0xff] ^ rk[7]; + /* round 2: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ + Td3[t1 & 0xff] ^ rk[8]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ + Td3[t2 & 0xff] ^ rk[9]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ + Td3[t3 & 0xff] ^ rk[10]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ + Td3[t0 & 0xff] ^ rk[11]; + /* round 3: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ + Td3[s1 & 0xff] ^ rk[12]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ + Td3[s2 & 0xff] ^ rk[13]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ + Td3[s3 & 0xff] ^ rk[14]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ + Td3[s0 & 0xff] ^ rk[15]; + /* round 4: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ + Td3[t1 & 0xff] ^ rk[16]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ + Td3[t2 & 0xff] ^ rk[17]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ + Td3[t3 & 0xff] ^ rk[18]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ + Td3[t0 & 0xff] ^ rk[19]; + /* round 5: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ + Td3[s1 & 0xff] ^ rk[20]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ + Td3[s2 & 0xff] ^ rk[21]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ + Td3[s3 & 0xff] ^ rk[22]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ + Td3[s0 & 0xff] ^ rk[23]; + /* round 6: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ + Td3[t1 & 0xff] ^ rk[24]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ + Td3[t2 & 0xff] ^ rk[25]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ + Td3[t3 & 0xff] ^ rk[26]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ + Td3[t0 & 0xff] ^ rk[27]; + /* round 7: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ + Td3[s1 & 0xff] ^ rk[28]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ + Td3[s2 & 0xff] ^ rk[29]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ + Td3[s3 & 0xff] ^ rk[30]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ + Td3[s0 & 0xff] ^ rk[31]; + /* round 8: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ + Td3[t1 & 0xff] ^ rk[32]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ + Td3[t2 & 0xff] ^ rk[33]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ + Td3[t3 & 0xff] ^ rk[34]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ + Td3[t0 & 0xff] ^ rk[35]; + /* round 9: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ + Td3[s1 & 0xff] ^ rk[36]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ + Td3[s2 & 0xff] ^ rk[37]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ + Td3[s3 & 0xff] ^ rk[38]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ + Td3[s0 & 0xff] ^ rk[39]; + if (nrounds > 10) { + /* round 10: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ + Td3[t1 & 0xff] ^ rk[40]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ + Td3[t2 & 0xff] ^ rk[41]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ + Td3[t3 & 0xff] ^ rk[42]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ + Td3[t0 & 0xff] ^ rk[43]; + /* round 11: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ + Td3[s1 & 0xff] ^ rk[44]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ + Td3[s2 & 0xff] ^ rk[45]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ + Td3[s3 & 0xff] ^ rk[46]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ + Td3[s0 & 0xff] ^ rk[47]; + if (nrounds > 12) { + /* round 12: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ + Td3[t1 & 0xff] ^ rk[48]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ + Td3[t2 & 0xff] ^ rk[49]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ + Td3[t3 & 0xff] ^ rk[50]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ + Td3[t0 & 0xff] ^ rk[51]; + /* round 13: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ + Td3[s1 & 0xff] ^ rk[52]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ + Td3[s2 & 0xff] ^ rk[53]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ + Td3[s3 & 0xff] ^ rk[54]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ + Td3[s0 & 0xff] ^ rk[55]; } - rk += nrounds << 2; - #else /* !FULL_UNROLL */ - /* - * nrounds - 1 full rounds: - */ - r = nrounds >> 1; - for (;;) - { - t0 = - Td0[(s0 >> 24) ] ^ - Td1[(s3 >> 16) & 0xff] ^ - Td2[(s2 >> 8) & 0xff] ^ - Td3[(s1 ) & 0xff] ^ - rk[4]; - t1 = - Td0[(s1 >> 24) ] ^ - Td1[(s0 >> 16) & 0xff] ^ - Td2[(s3 >> 8) & 0xff] ^ - Td3[(s2 ) & 0xff] ^ - rk[5]; - t2 = - Td0[(s2 >> 24) ] ^ - Td1[(s1 >> 16) & 0xff] ^ - Td2[(s0 >> 8) & 0xff] ^ - Td3[(s3 ) & 0xff] ^ - rk[6]; - t3 = - Td0[(s3 >> 24) ] ^ - Td1[(s2 >> 16) & 0xff] ^ - Td2[(s1 >> 8) & 0xff] ^ - Td3[(s0 ) & 0xff] ^ - rk[7]; - rk += 8; - if (--r == 0) - break; - s0 = - Td0[(t0 >> 24) ] ^ - Td1[(t3 >> 16) & 0xff] ^ - Td2[(t2 >> 8) & 0xff] ^ - Td3[(t1 ) & 0xff] ^ - rk[0]; - s1 = - Td0[(t1 >> 24) ] ^ - Td1[(t0 >> 16) & 0xff] ^ - Td2[(t3 >> 8) & 0xff] ^ - Td3[(t2 ) & 0xff] ^ - rk[1]; - s2 = - Td0[(t2 >> 24) ] ^ - Td1[(t1 >> 16) & 0xff] ^ - Td2[(t0 >> 8) & 0xff] ^ - Td3[(t3 ) & 0xff] ^ - rk[2]; - s3 = - Td0[(t3 >> 24) ] ^ - Td1[(t2 >> 16) & 0xff] ^ - Td2[(t1 >> 8) & 0xff] ^ - Td3[(t0 ) & 0xff] ^ - rk[3]; - } - #endif /* ?FULL_UNROLL */ + } + rk += nrounds << 2; +#else /* !FULL_UNROLL */ /* - * apply last round and - * map cipher state to byte array block: - */ - s0 = - (Td4[(t0 >> 24) ] & 0xff000000) ^ - (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t1 ) & 0xff] & 0x000000ff) ^ - rk[0]; - PUTU32(plaintext , s0); - s1 = - (Td4[(t1 >> 24) ] & 0xff000000) ^ - (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t2 ) & 0xff] & 0x000000ff) ^ - rk[1]; - PUTU32(plaintext + 4, s1); - s2 = - (Td4[(t2 >> 24) ] & 0xff000000) ^ - (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t3 ) & 0xff] & 0x000000ff) ^ - rk[2]; - PUTU32(plaintext + 8, s2); - s3 = - (Td4[(t3 >> 24) ] & 0xff000000) ^ - (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t0 ) & 0xff] & 0x000000ff) ^ - rk[3]; + * nrounds - 1 full rounds: + */ + r = nrounds >> 1; + for (;;) { + t0 = Td0[(s0 >> 24)] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ + Td3[(s1) &0xff] ^ rk[4]; + t1 = Td0[(s1 >> 24)] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ + Td3[(s2) &0xff] ^ rk[5]; + t2 = Td0[(s2 >> 24)] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ + Td3[(s3) &0xff] ^ rk[6]; + t3 = Td0[(s3 >> 24)] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ + Td3[(s0) &0xff] ^ rk[7]; + rk += 8; + if (--r == 0) + break; + s0 = Td0[(t0 >> 24)] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ + Td3[(t1) &0xff] ^ rk[0]; + s1 = Td0[(t1 >> 24)] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ + Td3[(t2) &0xff] ^ rk[1]; + s2 = Td0[(t2 >> 24)] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ + Td3[(t3) &0xff] ^ rk[2]; + s3 = Td0[(t3 >> 24)] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ + Td3[(t0) &0xff] ^ rk[3]; + } +#endif /* ?FULL_UNROLL */ + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = (Td4[(t0 >> 24)] & 0xff000000) ^ (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[(t1) &0xff] & 0x000000ff) ^ + rk[0]; + PUTU32(plaintext, s0); + s1 = (Td4[(t1 >> 24)] & 0xff000000) ^ (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[(t2) &0xff] & 0x000000ff) ^ + rk[1]; + PUTU32(plaintext + 4, s1); + s2 = (Td4[(t2 >> 24)] & 0xff000000) ^ (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[(t3) &0xff] & 0x000000ff) ^ + rk[2]; + PUTU32(plaintext + 8, s2); + s3 = (Td4[(t3 >> 24)] & 0xff000000) ^ (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[(t0) &0xff] & 0x000000ff) ^ + rk[3]; PUTU32(plaintext + 12, s3); } - - diff --git a/src/main/crypt/lib/rijndael.h b/src/main/crypt/lib/rijndael.h index 9394a5b..81ccc64 100644 --- a/src/main/crypt/lib/rijndael.h +++ b/src/main/crypt/lib/rijndael.h @@ -1,17 +1,23 @@ #ifndef H__RIJNDAEL #define H__RIJNDAEL -int rijndaelSetupEncrypt(unsigned long *rk, const unsigned char *key, - int keybits); -int rijndaelSetupDecrypt(unsigned long *rk, const unsigned char *key, - int keybits); -void rijndaelEncrypt(const unsigned long *rk, int nrounds, - const unsigned char plaintext[16], unsigned char ciphertext[16]); -void rijndaelDecrypt(const unsigned long *rk, int nrounds, - const unsigned char ciphertext[16], unsigned char plaintext[16]); +int rijndaelSetupEncrypt( + unsigned long *rk, const unsigned char *key, int keybits); +int rijndaelSetupDecrypt( + unsigned long *rk, const unsigned char *key, int keybits); +void rijndaelEncrypt( + const unsigned long *rk, + int nrounds, + const unsigned char plaintext[16], + unsigned char ciphertext[16]); +void rijndaelDecrypt( + const unsigned long *rk, + int nrounds, + const unsigned char ciphertext[16], + unsigned char plaintext[16]); -#define KEYLENGTH(keybits) ((keybits)/8) -#define RKLENGTH(keybits) ((keybits)/8+28) -#define NROUNDS(keybits) ((keybits)/32+6) +#define KEYLENGTH(keybits) ((keybits) / 8) +#define RKLENGTH(keybits) ((keybits) / 8 + 28) +#define NROUNDS(keybits) ((keybits) / 32 + 6) #endif diff --git a/src/main/crypt/md5.c b/src/main/crypt/md5.c index 418c03a..9aa229a 100644 --- a/src/main/crypt/md5.c +++ b/src/main/crypt/md5.c @@ -4,11 +4,11 @@ #include "md5.h" -void crypt_md5_hash(uint8_t* out, const uint8_t* in, size_t nbytes) +void crypt_md5_hash(uint8_t *out, const uint8_t *in, size_t nbytes) { - MD5_CTX ctx; + MD5_CTX ctx; - MD5Init(&ctx); - MD5Update(&ctx, (unsigned char*) in, (unsigned int) nbytes); - MD5Final(out, &ctx); + MD5Init(&ctx); + MD5Update(&ctx, (unsigned char *) in, (unsigned int) nbytes); + MD5Final(out, &ctx); } \ No newline at end of file diff --git a/src/main/crypt/md5.h b/src/main/crypt/md5.h index dbdf982..e9b520b 100644 --- a/src/main/crypt/md5.h +++ b/src/main/crypt/md5.h @@ -11,6 +11,6 @@ * @param in Input buffer to hash * @param nbytes Number of bytes of input buffer to process */ -void crypt_md5_hash(uint8_t* out, const uint8_t* in, size_t nbytes); +void crypt_md5_hash(uint8_t *out, const uint8_t *in, size_t nbytes); #endif \ No newline at end of file diff --git a/src/main/hook/core/options.c b/src/main/hook/core/options.c index 4b4d8b8..1618fd1 100644 --- a/src/main/hook/core/options.c +++ b/src/main/hook/core/options.c @@ -27,24 +27,25 @@ const struct util_options_defs hook_core_options_defs = { // Just use something because this is not relevant/required here .usage_param = '\r', .defs = hook_core_options_def, - .ndefs = lengthof(hook_core_options_def) -}; + .ndefs = lengthof(hook_core_options_def)}; -void hook_core_options_init(int argc, char** argv, struct hook_core_options* options) +void hook_core_options_init( + int argc, char **argv, struct hook_core_options *options) { - log_assert(argv); - log_assert(options); + log_assert(argv); + log_assert(options); - struct util_options_opts* options_opt; + struct util_options_opts *options_opt; - util_options_init(argc, argv); - options_opt = util_options_get(&hook_core_options_defs); + util_options_init(argc, argv); + options_opt = util_options_get(&hook_core_options_defs); - if (!options_opt) { - return; - } + if (!options_opt) { + return; + } - options->log.file = util_options_get_str(options_opt, HOOK_CORE_OPTIONS_STR_PATCH_UTIL_LOG_FILE); - options->log.level = - (enum util_log_level) util_options_get_int(options_opt, HOOK_CORE_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); + options->log.file = util_options_get_str( + options_opt, HOOK_CORE_OPTIONS_STR_PATCH_UTIL_LOG_FILE); + options->log.level = (enum util_log_level) util_options_get_int( + options_opt, HOOK_CORE_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); } \ No newline at end of file diff --git a/src/main/hook/core/options.h b/src/main/hook/core/options.h index f610765..02203b8 100644 --- a/src/main/hook/core/options.h +++ b/src/main/hook/core/options.h @@ -4,12 +4,13 @@ #include "util/log.h" struct hook_core_options { - struct log { - const char* file; - enum util_log_level level; - } log; + struct log { + const char *file; + enum util_log_level level; + } log; }; -void hook_core_options_init(int argc, char** argv, struct hook_core_options* options); +void hook_core_options_init( + int argc, char **argv, struct hook_core_options *options); #endif diff --git a/src/main/hook/core/piu-utils.c b/src/main/hook/core/piu-utils.c index 44069d0..a429ce1 100644 --- a/src/main/hook/core/piu-utils.c +++ b/src/main/hook/core/piu-utils.c @@ -13,121 +13,131 @@ #include "util/str.h" #include "util/sys-info.h" -static void hook_core_piu_log_application_args(int argc, char** argv) +static void hook_core_piu_log_application_args(int argc, char **argv) { - const char* sep = "\n"; - char* str = util_str_dup(""); - char* tmp; + const char *sep = "\n"; + char *str = util_str_dup(""); + char *tmp; - for (int i = 0; i < argc; i++) { - if (strlen(str) > 0) { - tmp = util_str_merge(str, sep); - free(str); - str = tmp; - } - - tmp = util_str_merge(str, argv[i]); - free(str); - str = tmp; + for (int i = 0; i < argc; i++) { + if (strlen(str) > 0) { + tmp = util_str_merge(str, sep); + free(str); + str = tmp; } - log_info("Application arguments (%d):\n%s", argc, str); + tmp = util_str_merge(str, argv[i]); free(str); + str = tmp; + } + + log_info("Application arguments (%d):\n%s", argc, str); + free(str); } -void hook_core_piu_log_init(int argc, char** argv) +void hook_core_piu_log_init(int argc, char **argv) { - struct hook_core_options options; + struct hook_core_options options; - hook_core_options_init(argc, argv, &options); + hook_core_options_init(argc, argv, &options); - util_log_set_file(options.log.file, false); - util_log_set_level(options.log.level); + util_log_set_file(options.log.file, false); + util_log_set_level(options.log.level); } -void hook_core_piu_log_info(int argc, char** argv) +void hook_core_piu_log_info(int argc, char **argv) { - log_info("\n" - " _ _ \n" - " _ __ _ _ _ __ ___ _ __ | |_ ___ ___ | |___ \n" - " | '_ \\| | | | '_ ` _ \\| '_ \\| __/ _ \\ / _ \\| / __|\n" - " | |_) | |_| | | | | | | |_) | || (_) | (_) | \\__ \\\n" - " | .__/ \\__,_|_| |_| |_| .__/ \\__\\___/ \\___/|_|___/\n" - " |_| |_| "); + log_info( + "\n" + " _ _ \n" + " _ __ _ _ _ __ ___ _ __ | |_ ___ ___ | |___ \n" + " | '_ \\| | | | '_ ` _ \\| '_ \\| __/ _ \\ / _ \\| / __|\n" + " | |_) | |_| | | | | | | |_) | || (_) | (_) | \\__ \\\n" + " | .__/ \\__,_|_| |_| |_| .__/ \\__\\___/ \\___/|_|___/\n" + " |_| |_| "); - log_info("Pumptools build " __DATE__ " " __TIME__ " gitrev %s", STRINGIFY(GITREV)); + log_info( + "Pumptools build " __DATE__ " " __TIME__ " gitrev %s", STRINGIFY(GITREV)); - util_sys_info_log(); - util_proc_log_info(); - util_glibc_info_log(); - hook_core_piu_log_application_args(argc, argv); + util_sys_info_log(); + util_proc_log_info(); + util_glibc_info_log(); + hook_core_piu_log_application_args(argc, argv); } -char* hook_core_piu_utils_get_and_verify_game_data_path(int argc, char** argv) +char *hook_core_piu_utils_get_and_verify_game_data_path(int argc, char **argv) { - if (argc < 2) { - log_error("Missing game data path, usage for piu (stock args): piu (e.g. piu ./game)"); - exit(0); - } + if (argc < 2) { + log_error( + "Missing game data path, usage for piu (stock args): piu " + "(e.g. piu ./game)"); + exit(0); + } - char* game_data_path = util_str_dup(argv[1]); + char *game_data_path = util_str_dup(argv[1]); - log_info("Game data path: %s", game_data_path); + log_info("Game data path: %s", game_data_path); - /* remove trailing / for the hook. however, the game crashes without it */ - if (util_str_ends_with(game_data_path, "/")) { - game_data_path[strlen(game_data_path) - 1] = '\0'; - } else { - log_error("Game data path '%s' does not end with a trailing /, exiting because the game is going to " - "crash anyway!", game_data_path); - exit(0); - } + /* remove trailing / for the hook. however, the game crashes without it */ + if (util_str_ends_with(game_data_path, "/")) { + game_data_path[strlen(game_data_path) - 1] = '\0'; + } else { + log_error( + "Game data path '%s' does not end with a trailing /, exiting because " + "the game is going to " + "crash anyway!", + game_data_path); + exit(0); + } - /* depending on the version, the game also just crashes if the game folder or files within it were not found */ - if (!util_fs_path_exists(game_data_path)) { - log_error("Game data path '%s' does not exist, exiting", game_data_path); - exit(0); - } + /* depending on the version, the game also just crashes if the game folder or + * files within it were not found */ + if (!util_fs_path_exists(game_data_path)) { + log_error("Game data path '%s' does not exist, exiting", game_data_path); + exit(0); + } - return game_data_path; + return game_data_path; } void hook_core_piu_utils_verify_root_user() { - log_info("Verifying process is running as root user."); + log_info("Verifying process is running as root user."); - if (!util_proc_is_running_as_root()) { - log_error("Process not running as root which is required for the game to work correctly."); - //exit(0); - } + if (!util_proc_is_running_as_root()) { + log_error( + "Process not running as root which is required for the game to work " + "correctly."); + // exit(0); + } } void hook_core_piu_utils_fix_locale() { - log_info("Fixing locale settings."); + log_info("Fixing locale settings."); - if (setenv("LC_ALL", "C", 1) != 0) { - log_warn("Setting locale LC_ALL failed."); - } + if (setenv("LC_ALL", "C", 1) != 0) { + log_warn("Setting locale LC_ALL failed."); + } - if (unsetenv("LANGUAGE") != 0) { - log_warn("Unsetting LANGUAGE env var failed."); - } + if (unsetenv("LANGUAGE") != 0) { + log_warn("Unsetting LANGUAGE env var failed."); + } } -bool hook_core_piu_block_non_piu_process_recursion(int argc, char** argv) +bool hook_core_piu_block_non_piu_process_recursion(int argc, char **argv) { - /* Sanity check for arguments. If further child processes are started - from the current process, and using LD_PRELOAD on the current process, - all children are also getting the preloaded library. This causes - multiple calls to the trap main function and just crashes our - application at some point. - The executable file is required to contain the "piu" substring to make - this work properly */ - if (!strstr(argv[0], "piu")) { - log_warn("Not attaching to non piu process %s", argv[0]); - return true; - } else { - return false; - } + /* Sanity check for arguments. If further child processes are started + from the current process, and using LD_PRELOAD on the current process, + all children are also getting the preloaded library. This causes + multiple calls to the trap main function and just crashes our + application at some point. + The executable file is required to contain the "piu" substring to make + this work properly */ + if (!strstr(argv[0], "piu")) { + log_warn("Not attaching to non piu process %s", argv[0]); + return true; + } else { + return false; + } } \ No newline at end of file diff --git a/src/main/hook/core/piu-utils.h b/src/main/hook/core/piu-utils.h index 3608c09..05789c9 100644 --- a/src/main/hook/core/piu-utils.h +++ b/src/main/hook/core/piu-utils.h @@ -2,14 +2,15 @@ #define HOOK_CORE_PIU_UTILS_H /** - * Initialize the logging system as early as possible to allow recording everything to a log file as well. + * Initialize the logging system as early as possible to allow recording + * everything to a log file as well. */ -void hook_core_piu_log_init(int argc, char** argv); +void hook_core_piu_log_init(int argc, char **argv); /** * Log process and system relevant information. */ -void hook_core_piu_log_info(int argc, char** argv); +void hook_core_piu_log_info(int argc, char **argv); /** * Check and verify the game data path argument passed to the game via argv @@ -19,9 +20,10 @@ void hook_core_piu_log_info(int argc, char** argv); * * @param argc Argc from piu main * @param argv Argv from piu main - * @return New string with game data path extracted from argv (caller has to free) + * @return New string with game data path extracted from argv (caller has to + * free) */ -char* hook_core_piu_utils_get_and_verify_game_data_path(int argc, char** argv); +char *hook_core_piu_utils_get_and_verify_game_data_path(int argc, char **argv); /** * Verify that the current process is running as root user because the game @@ -38,16 +40,16 @@ void hook_core_piu_utils_fix_locale(); /** * If further child processes are started from the current process, and using - * LD_PRELOAD on the current process, all children are also getting the preloaded - * library. This causes multiple calls to the trap main function and just crashes our - * application at some point. The executable file is required to contain the "piu" - * substring to make this work properly. + * LD_PRELOAD on the current process, all children are also getting the + * preloaded library. This causes multiple calls to the trap main function and + * just crashes our application at some point. The executable file is required + * to contain the "piu" substring to make this work properly. * * @param argc Argc from piu main * @param argv Argv from piu main * @return True if we have to block this call by another process, * false if the process calling this is the piu process. */ -bool hook_core_piu_block_non_piu_process_recursion(int argc, char** argv); +bool hook_core_piu_block_non_piu_process_recursion(int argc, char **argv); #endif diff --git a/src/main/hook/exc/eeprom.c b/src/main/hook/exc/eeprom.c index 460d0f6..55ca259 100644 --- a/src/main/hook/exc/eeprom.c +++ b/src/main/hook/exc/eeprom.c @@ -10,89 +10,101 @@ #include "util/log.h" #include "util/patch.h" -static int32_t exchook_eeprom_read(uint8_t* buffer, int32_t len); -static int32_t exchook_eeprom_write(const uint8_t* buffer, int32_t len); +static int32_t exchook_eeprom_read(uint8_t *buffer, int32_t len); +static int32_t exchook_eeprom_write(const uint8_t *buffer, int32_t len); -static char* exchook_eeprom_file; +static char *exchook_eeprom_file; static uint8_t exchook_eeprom_buffer[8192]; -void exchook_eeprom_init(const struct exchook_mempatch_table* patch_table, const char* eeprom_file) +void exchook_eeprom_init( + const struct exchook_mempatch_table *patch_table, const char *eeprom_file) { - void* buffer; - size_t len; + void *buffer; + size_t len; + + exchook_eeprom_file = util_fs_get_abs_path(eeprom_file); + + /* EEPROM file does not exist, create new */ + if (!exchook_eeprom_file) { + memset(exchook_eeprom_buffer, 0xFF, sizeof(exchook_eeprom_buffer)); + + FILE *file = fopen(eeprom_file, "wb+"); + + if (file == NULL) { + log_error( + "Creating new eeprom file %s failed: %s", + eeprom_file, + strerror(errno)); + } + + fwrite(exchook_eeprom_buffer, sizeof(exchook_eeprom_buffer), 1, file); + fclose(file); exchook_eeprom_file = util_fs_get_abs_path(eeprom_file); + len = (size_t) -1; + } else { + if (util_file_load(exchook_eeprom_file, &buffer, &len, false)) { + if (len > sizeof(exchook_eeprom_buffer)) { + log_error( + "Contents of %s eeprom file exceed the max eeprom buffer " + " size of %d bytes", + eeprom_file, + sizeof(exchook_eeprom_buffer)); + free(buffer); + return; + } - /* EEPROM file does not exist, create new */ - if (!exchook_eeprom_file) { - memset(exchook_eeprom_buffer, 0xFF, sizeof(exchook_eeprom_buffer)); - - FILE* file = fopen(eeprom_file, "wb+"); - - if (file == NULL) { - log_error("Creating new eeprom file %s failed: %s", eeprom_file, strerror(errno)); - } - - fwrite(exchook_eeprom_buffer, sizeof(exchook_eeprom_buffer), 1, file); - fclose(file); - - exchook_eeprom_file = util_fs_get_abs_path(eeprom_file); - len = (size_t) -1; + /* copy read contents */ + memcpy(exchook_eeprom_buffer, buffer, len); + free(buffer); } else { - if (util_file_load(exchook_eeprom_file, &buffer, &len, false)) { - if (len > sizeof(exchook_eeprom_buffer)) { - log_error("Contents of %s eeprom file exceed the max eeprom buffer " - " size of %d bytes", eeprom_file, - sizeof(exchook_eeprom_buffer)); - free(buffer); - return; - } - - /* copy read contents */ - memcpy(exchook_eeprom_buffer, buffer, len); - free(buffer); - } else { - log_error("Loading eeprom file %s failed", exchook_eeprom_file); - } + log_error("Loading eeprom file %s failed", exchook_eeprom_file); } + } - log_assert(exchook_eeprom_file); + log_assert(exchook_eeprom_file); - /* Hook eeprom */ - util_patch_function(patch_table->addr_eeprom_read, exchook_eeprom_read); - util_patch_function(patch_table->addr_eeprom_write, exchook_eeprom_write); + /* Hook eeprom */ + util_patch_function(patch_table->addr_eeprom_read, exchook_eeprom_read); + util_patch_function(patch_table->addr_eeprom_write, exchook_eeprom_write); - log_info("Initizlied (%s), eeprom file %s", len == -1 ? "new" : "loaded", eeprom_file); + log_info( + "Initizlied (%s), eeprom file %s", + len == -1 ? "new" : "loaded", + eeprom_file); } -static int32_t exchook_eeprom_read(uint8_t* buffer, int32_t len) +static int32_t exchook_eeprom_read(uint8_t *buffer, int32_t len) { - if (len > sizeof(exchook_eeprom_buffer)) { - log_error("Eeprom read %d exceeds buffer size %d", len, - sizeof(exchook_eeprom_buffer)); - return 0; - } + if (len > sizeof(exchook_eeprom_buffer)) { + log_error( + "Eeprom read %d exceeds buffer size %d", + len, + sizeof(exchook_eeprom_buffer)); + return 0; + } - memcpy(buffer, exchook_eeprom_buffer, len); + memcpy(buffer, exchook_eeprom_buffer, len); - return len; + return len; } -static int32_t exchook_eeprom_write(const uint8_t* buffer, int32_t len) +static int32_t exchook_eeprom_write(const uint8_t *buffer, int32_t len) { - if (len > sizeof(exchook_eeprom_buffer)) { - log_error("Eeprom write %d exceeds buffer size %d", len, - sizeof(exchook_eeprom_buffer)); - return 0; - } + if (len > sizeof(exchook_eeprom_buffer)) { + log_error( + "Eeprom write %d exceeds buffer size %d", + len, + sizeof(exchook_eeprom_buffer)); + return 0; + } - memcpy(exchook_eeprom_buffer, buffer, len); + memcpy(exchook_eeprom_buffer, buffer, len); - /* Write back to file */ - if (!util_file_save(exchook_eeprom_file, exchook_eeprom_buffer, len)) { - log_error("Storing eeprom contents to file %s failed", - exchook_eeprom_file); - } + /* Write back to file */ + if (!util_file_save(exchook_eeprom_file, exchook_eeprom_buffer, len)) { + log_error("Storing eeprom contents to file %s failed", exchook_eeprom_file); + } - return len; + return len; } \ No newline at end of file diff --git a/src/main/hook/exc/eeprom.h b/src/main/hook/exc/eeprom.h index e7f0955..b5394c2 100644 --- a/src/main/hook/exc/eeprom.h +++ b/src/main/hook/exc/eeprom.h @@ -14,6 +14,7 @@ * @param eeprom_file Path to existing eeprom file to read from and new eeprom * file to store to */ -void exchook_eeprom_init(const struct exchook_mempatch_table* patch_table, const char* eeprom_file); +void exchook_eeprom_init( + const struct exchook_mempatch_table *patch_table, const char *eeprom_file); #endif \ No newline at end of file diff --git a/src/main/hook/exc/io.c b/src/main/hook/exc/io.c index e0b1a4a..c076143 100644 --- a/src/main/hook/exc/io.c +++ b/src/main/hook/exc/io.c @@ -11,54 +11,53 @@ #include "util/patch.h" /* Taken from ioarcade.hpp nx2 src dump */ -#define GI_P1_1 0x00000001 -#define GI_P1_3 0x00000002 -#define GI_P1_5 0x00000004 -#define GI_P1_7 0x00000008 -#define GI_P1_9 0x00000010 +#define GI_P1_1 0x00000001 +#define GI_P1_3 0x00000002 +#define GI_P1_5 0x00000004 +#define GI_P1_7 0x00000008 +#define GI_P1_9 0x00000010 -#define GI_P2_1 0x00000100 -#define GI_P2_3 0x00000200 -#define GI_P2_5 0x00000400 -#define GI_P2_7 0x00000800 -#define GI_P2_9 0x00001000 +#define GI_P2_1 0x00000100 +#define GI_P2_3 0x00000200 +#define GI_P2_5 0x00000400 +#define GI_P2_7 0x00000800 +#define GI_P2_9 0x00001000 -#define GI_TEST 0x00010000 -#define GI_SERVICE 0x00020000 -#define GI_CLEAR 0x00040000 +#define GI_TEST 0x00010000 +#define GI_SERVICE 0x00020000 +#define GI_CLEAR 0x00040000 -#define GI_COIN 0x00100000 -#define GI_COIN2 0x00200000 +#define GI_COIN 0x00100000 +#define GI_COIN2 0x00200000 struct exchook_io_sensores { - uint32_t lu : 4; - uint32_t ru : 4; - uint32_t cn : 4; - uint32_t ld : 4; - uint32_t rd : 4; - uint32_t padding : 12; + uint32_t lu : 4; + uint32_t ru : 4; + uint32_t cn : 4; + uint32_t ld : 4; + uint32_t rd : 4; + uint32_t padding : 12; }; -static const uint8_t exchook_io_sensor_mappings[] = { - 1, 2, 3, 0 -}; +static const uint8_t exchook_io_sensor_mappings[] = {1, 2, 3, 0}; static struct ptapi_io_piuio_api exchook_piuio_api; -static uint16_t exchook_io_check(void* obj); -static int32_t exchook_io_light_all(void* obj, uint8_t on); -static int32_t exchook_io_light_neon(void* obj, uint8_t on); -static int32_t exchook_io_light_halogan(void* obj, uint8_t on, uint16_t light_id); -static int32_t exchook_io_light_p1_ccfl(void* obj, uint8_t on, uint16_t cmd); -static int32_t exchook_io_light_p2_ccfl(void* obj, uint8_t on, uint16_t cmd); -static int32_t exchook_io_input(void* obj); -static int32_t exchook_io_coin_input(void* obj); -static int32_t exchook_io_coin_input_2(void* obj); -static int32_t exchook_io_coin_counter_2(void* obj); +static uint16_t exchook_io_check(void *obj); +static int32_t exchook_io_light_all(void *obj, uint8_t on); +static int32_t exchook_io_light_neon(void *obj, uint8_t on); +static int32_t +exchook_io_light_halogan(void *obj, uint8_t on, uint16_t light_id); +static int32_t exchook_io_light_p1_ccfl(void *obj, uint8_t on, uint16_t cmd); +static int32_t exchook_io_light_p2_ccfl(void *obj, uint8_t on, uint16_t cmd); +static int32_t exchook_io_input(void *obj); +static int32_t exchook_io_coin_input(void *obj); +static int32_t exchook_io_coin_input_2(void *obj); +static int32_t exchook_io_coin_counter_2(void *obj); -static uint32_t* exchook_io_game_input_stat; -static uint32_t* exchook_io_game_input_down; -static uint32_t* exchook_io_game_input_up; +static uint32_t *exchook_io_game_input_stat; +static uint32_t *exchook_io_game_input_down; +static uint32_t *exchook_io_game_input_up; static uint32_t exchook_io_game_input_stat_prev; @@ -72,434 +71,443 @@ static struct ptapi_io_piuio_cab_outputs exchook_io_out_cab; static bool exchook_io_exit_on_service_test; -void exchook_io_init(const struct exchook_mempatch_table* patch_table, const char* piuio_lib_path, - bool exit_on_service_test) +void exchook_io_init( + const struct exchook_mempatch_table *patch_table, + const char *piuio_lib_path, + bool exit_on_service_test) { - if (!piuio_lib_path) { - log_error("NULL piuio (emu) lib path. Check that you have set-up and configured a piuio API implementation " - "correctly."); - return; - } + if (!piuio_lib_path) { + log_error( + "NULL piuio (emu) lib path. Check that you have set-up and configured " + "a piuio API implementation " + "correctly."); + return; + } - /* Load piuio library funcs */ - log_info("Loading piuio api implementation %s", piuio_lib_path); + /* Load piuio library funcs */ + log_info("Loading piuio api implementation %s", piuio_lib_path); - if (!ptapi_io_piuio_util_lib_load(piuio_lib_path, &exchook_piuio_api)) { - log_error("Loading piuio API from file %s failed", piuio_lib_path); - return; - } + if (!ptapi_io_piuio_util_lib_load(piuio_lib_path, &exchook_piuio_api)) { + log_error("Loading piuio API from file %s failed", piuio_lib_path); + return; + } - exchook_io_exit_on_service_test = exit_on_service_test; + exchook_io_exit_on_service_test = exit_on_service_test; - log_info("Service + Test exit %d", exchook_io_exit_on_service_test); + log_info("Service + Test exit %d", exchook_io_exit_on_service_test); - /* Hook MK5IO engine calls */ - /* Why so many functions you might ask? Because the MK5 IO code is a pile - of shit created by a monkey */ + /* Hook MK5IO engine calls */ + /* Why so many functions you might ask? Because the MK5 IO code is a pile + of shit created by a monkey */ - util_patch_function(patch_table->addr_io_check, exchook_io_check); - util_patch_function(patch_table->addr_io_light_all, exchook_io_light_all); - util_patch_function(patch_table->addr_io_light_neon, exchook_io_light_neon); - util_patch_function(patch_table->addr_io_light_halogan, exchook_io_light_halogan); - util_patch_function(patch_table->addr_io_light_p1_ccfl, exchook_io_light_p1_ccfl); - util_patch_function(patch_table->addr_io_light_p2_ccfl, exchook_io_light_p2_ccfl); - util_patch_function(patch_table->addr_io_input, exchook_io_input); - util_patch_function(patch_table->addr_io_coin_input, exchook_io_coin_input); - util_patch_function(patch_table->addr_io_coin_input_2, exchook_io_coin_input_2); - util_patch_function(patch_table->addr_io_coin_counter_2, exchook_io_coin_counter_2); + util_patch_function(patch_table->addr_io_check, exchook_io_check); + util_patch_function(patch_table->addr_io_light_all, exchook_io_light_all); + util_patch_function(patch_table->addr_io_light_neon, exchook_io_light_neon); + util_patch_function( + patch_table->addr_io_light_halogan, exchook_io_light_halogan); + util_patch_function( + patch_table->addr_io_light_p1_ccfl, exchook_io_light_p1_ccfl); + util_patch_function( + patch_table->addr_io_light_p2_ccfl, exchook_io_light_p2_ccfl); + util_patch_function(patch_table->addr_io_input, exchook_io_input); + util_patch_function(patch_table->addr_io_coin_input, exchook_io_coin_input); + util_patch_function( + patch_table->addr_io_coin_input_2, exchook_io_coin_input_2); + util_patch_function( + patch_table->addr_io_coin_counter_2, exchook_io_coin_counter_2); - exchook_io_game_input_stat = ((uint32_t*) patch_table->addr_io_game_input_stat); - exchook_io_game_input_down = ((uint32_t*) patch_table->addr_io_game_input_down); - exchook_io_game_input_up = ((uint32_t*) patch_table->addr_io_game_input_up); + exchook_io_game_input_stat = + ((uint32_t *) patch_table->addr_io_game_input_stat); + exchook_io_game_input_down = + ((uint32_t *) patch_table->addr_io_game_input_down); + exchook_io_game_input_up = ((uint32_t *) patch_table->addr_io_game_input_up); - /* there is an io init method but obviously requires another address to be - hooked...just init our backend here */ - if (!exchook_piuio_api.open()) { - log_error("Opening io failed"); - return; - } + /* there is an io init method but obviously requires another address to be + hooked...just init our backend here */ + if (!exchook_piuio_api.open()) { + log_error("Opening io failed"); + return; + } - log_info("Initialized"); + log_info("Initialized"); } void exchook_io_shutdown(void) { - } /* check? why can't you just call it get_fucking_inputs... */ -static uint16_t exchook_io_check(void* obj) +static uint16_t exchook_io_check(void *obj) { - struct ptapi_io_piuio_pad_inputs p1_pad_in; - struct ptapi_io_piuio_pad_inputs p2_pad_in; + struct ptapi_io_piuio_pad_inputs p1_pad_in; + struct ptapi_io_piuio_pad_inputs p2_pad_in; - /* Sensor states are expected to be returned using the object */ - struct exchook_io_sensores* sensores_p1 = - (struct exchook_io_sensores*) obj; - struct exchook_io_sensores* sensores_p2 = - (struct exchook_io_sensores*) (((uint32_t*) obj) + 1); + /* Sensor states are expected to be returned using the object */ + struct exchook_io_sensores *sensores_p1 = (struct exchook_io_sensores *) obj; + struct exchook_io_sensores *sensores_p2 = + (struct exchook_io_sensores *) (((uint32_t *) obj) + 1); - /* execute polling here */ + /* execute polling here */ - /* might delay output for a frame but whatever */ - if (!exchook_piuio_api.send()) { - log_error("Piuio send failed"); - } + /* might delay output for a frame but whatever */ + if (!exchook_piuio_api.send()) { + log_error("Piuio send failed"); + } - if (!exchook_piuio_api.recv()) { - log_error("Piuio receive failed"); - } + if (!exchook_piuio_api.recv()) { + log_error("Piuio receive failed"); + } - /* MK5 inputs state reset */ - exchook_io_sensores_p1.lu = 0; - exchook_io_sensores_p1.ru = 0; - exchook_io_sensores_p1.cn = 0; - exchook_io_sensores_p1.ld = 0; - exchook_io_sensores_p1.rd = 0; + /* MK5 inputs state reset */ + exchook_io_sensores_p1.lu = 0; + exchook_io_sensores_p1.ru = 0; + exchook_io_sensores_p1.cn = 0; + exchook_io_sensores_p1.ld = 0; + exchook_io_sensores_p1.rd = 0; - exchook_io_sensores_p2.lu = 0; - exchook_io_sensores_p2.ru = 0; - exchook_io_sensores_p2.cn = 0; - exchook_io_sensores_p2.ld = 0; - exchook_io_sensores_p2.rd = 0; + exchook_io_sensores_p2.lu = 0; + exchook_io_sensores_p2.ru = 0; + exchook_io_sensores_p2.cn = 0; + exchook_io_sensores_p2.ld = 0; + exchook_io_sensores_p2.rd = 0; - // State reset - memset(&p1_pad_in, 0, sizeof(struct ptapi_io_piuio_pad_inputs)); - memset(&p2_pad_in, 0, sizeof(struct ptapi_io_piuio_pad_inputs)); + // State reset + memset(&p1_pad_in, 0, sizeof(struct ptapi_io_piuio_pad_inputs)); + memset(&p2_pad_in, 0, sizeof(struct ptapi_io_piuio_pad_inputs)); - /* cycle all sensores */ - for (uint8_t i = 0; i < 4; i++) { - exchook_piuio_api.get_input_pad(0, i, &p1_pad_in); - exchook_piuio_api.get_input_pad(1, i, &p2_pad_in); + /* cycle all sensores */ + for (uint8_t i = 0; i < 4; i++) { + exchook_piuio_api.get_input_pad(0, i, &p1_pad_in); + exchook_piuio_api.get_input_pad(1, i, &p2_pad_in); - /* process inputs */ - - /* Player 1 */ - if (p1_pad_in.lu) { - exchook_io_sensores_p1.lu |= (1 << exchook_io_sensor_mappings[i]); - } - - if (p1_pad_in.ru) { - exchook_io_sensores_p1.ru |= (1 << exchook_io_sensor_mappings[i]); - } - - if (p1_pad_in.cn) { - exchook_io_sensores_p1.cn |= (1 << exchook_io_sensor_mappings[i]); - } - - if (p1_pad_in.ld) { - exchook_io_sensores_p1.ld |= (1 << exchook_io_sensor_mappings[i]); - } - - if (p1_pad_in.rd) { - exchook_io_sensores_p1.rd |= (1 << exchook_io_sensor_mappings[i]); - } - - /* Player 2 */ - if (p2_pad_in.lu) { - exchook_io_sensores_p2.lu |= (1 << exchook_io_sensor_mappings[i]); - } - - if (p2_pad_in.ru) { - exchook_io_sensores_p2.ru |= (1 << exchook_io_sensor_mappings[i]); - } - - if (p2_pad_in.cn) { - exchook_io_sensores_p2.cn |= (1 << exchook_io_sensor_mappings[i]); - } - - if (p2_pad_in.ld) { - exchook_io_sensores_p2.ld |= (1 << exchook_io_sensor_mappings[i]); - } - - if (p2_pad_in.rd) { - exchook_io_sensores_p2.rd |= (1 << exchook_io_sensor_mappings[i]); - } - } - - memcpy(sensores_p1, &exchook_io_sensores_p1, sizeof(exchook_io_sensores_p1)); - memcpy(sensores_p2, &exchook_io_sensores_p2, sizeof(exchook_io_sensores_p2)); - - return 0; -} - -static int32_t exchook_io_light_all(void* obj, uint8_t on) -{ - if (on) { - memset(&exchook_io_out_pad_p1, 1, sizeof(exchook_io_out_pad_p1)); - memset(&exchook_io_out_pad_p2, 1, sizeof(exchook_io_out_pad_p2)); - memset(&exchook_io_out_cab, 1, sizeof(exchook_io_out_cab)); - } else { - memset(&exchook_io_out_pad_p1, 0, sizeof(exchook_io_out_pad_p1)); - memset(&exchook_io_out_pad_p2, 0, sizeof(exchook_io_out_pad_p2)); - memset(&exchook_io_out_cab, 0, sizeof(exchook_io_out_cab)); - } - - exchook_piuio_api.set_output_pad(0, &exchook_io_out_pad_p1); - exchook_piuio_api.set_output_pad(1, &exchook_io_out_pad_p2); - exchook_piuio_api.set_output_cab(&exchook_io_out_cab); - - return 0; -} - -static int32_t exchook_io_light_neon(void* obj, uint8_t on) -{ - if (on) { - exchook_io_out_cab.bass = true; - } else { - exchook_io_out_cab.bass = false; - } - - exchook_piuio_api.set_output_cab(&exchook_io_out_cab); - - return 0; -} - -static int32_t exchook_io_light_halogan(void* obj, uint8_t on, uint16_t light_id) -{ - if (light_id & 0x0400) { - exchook_io_out_cab.halo_l1 = on; - } - - if (light_id & 0x0200) { - exchook_io_out_cab.halo_l2 = on; - } - - if (light_id & 0x0100) { - exchook_io_out_cab.halo_r1 = on; - } - - if (light_id & 0x0080) { - exchook_io_out_cab.halo_r2 = on; - } - - exchook_piuio_api.set_output_cab(&exchook_io_out_cab); - - return 0; -} - -static int32_t exchook_io_light_p1_ccfl(void* obj, uint8_t on, uint16_t cmd) -{ - if (cmd & 0x0004) { - exchook_io_out_pad_p1.lu = on; - } - - if (cmd & 0x0008) { - exchook_io_out_pad_p1.ru = on; - } - - if (cmd & 0x0010) { - exchook_io_out_pad_p1.cn = on; - } - - if (cmd & 0x0020) { - exchook_io_out_pad_p1.ld = on; - } - - if (cmd & 0x040) { - exchook_io_out_pad_p1.rd = on; - } - - return 0; -} - -static int32_t exchook_io_light_p2_ccfl(void* obj, uint8_t on, uint16_t cmd) -{ - if (cmd & 0x0004) { - exchook_io_out_pad_p2.lu = on; - } - - if (cmd & 0x0008) { - exchook_io_out_pad_p2.ru = on; - } - - if (cmd & 0x0010) { - exchook_io_out_pad_p2.cn = on; - } - - if (cmd & 0x0020) { - exchook_io_out_pad_p2.ld = on; - } - - if (cmd & 0x040) { - exchook_io_out_pad_p2.rd = on; - } - - return 0; -} - -static int32_t exchook_io_input(void* obj) -{ - uint32_t stat; - uint32_t stat_down; - uint32_t stat_up; - - struct ptapi_io_piuio_sys_inputs sys_in; - - memset(&sys_in, 0, sizeof(struct ptapi_io_piuio_sys_inputs)); - - exchook_piuio_api.get_input_sys(&sys_in); - - /* For game loaders and stuff */ - if (exchook_io_exit_on_service_test) { - if (sys_in.test && sys_in.service) { - log_info("Exit on service + test enabled and hit, bye"); - exit(0); - } - } - - /* process final input states for the game as well as service, test, clear - and coin which can't be handled in the check function */ - - stat = 0; - stat_down = 0; - stat_up = 0; + /* process inputs */ /* Player 1 */ - if (exchook_io_sensores_p1.lu) { - stat |= GI_P1_7; + if (p1_pad_in.lu) { + exchook_io_sensores_p1.lu |= (1 << exchook_io_sensor_mappings[i]); } - if (exchook_io_sensores_p1.ru) { - stat |= GI_P1_9; + if (p1_pad_in.ru) { + exchook_io_sensores_p1.ru |= (1 << exchook_io_sensor_mappings[i]); } - if (exchook_io_sensores_p1.cn) { - stat |= GI_P1_5; + if (p1_pad_in.cn) { + exchook_io_sensores_p1.cn |= (1 << exchook_io_sensor_mappings[i]); } - if (exchook_io_sensores_p1.ld) { - stat |= GI_P1_1; + if (p1_pad_in.ld) { + exchook_io_sensores_p1.ld |= (1 << exchook_io_sensor_mappings[i]); } - if (exchook_io_sensores_p1.rd) { - stat |= GI_P1_3; + if (p1_pad_in.rd) { + exchook_io_sensores_p1.rd |= (1 << exchook_io_sensor_mappings[i]); } - /* Player 2 */ - if (exchook_io_sensores_p2.lu) { - stat |= GI_P2_7; + /* Player 2 */ + if (p2_pad_in.lu) { + exchook_io_sensores_p2.lu |= (1 << exchook_io_sensor_mappings[i]); } - if (exchook_io_sensores_p2.ru) { - stat |= GI_P2_9; + if (p2_pad_in.ru) { + exchook_io_sensores_p2.ru |= (1 << exchook_io_sensor_mappings[i]); } - if (exchook_io_sensores_p2.cn) { - stat |= GI_P2_5; + if (p2_pad_in.cn) { + exchook_io_sensores_p2.cn |= (1 << exchook_io_sensor_mappings[i]); } - if (exchook_io_sensores_p2.ld) { - stat |= GI_P2_1; + if (p2_pad_in.ld) { + exchook_io_sensores_p2.ld |= (1 << exchook_io_sensor_mappings[i]); } - if (exchook_io_sensores_p2.rd) { - stat |= GI_P2_3; + if (p2_pad_in.rd) { + exchook_io_sensores_p2.rd |= (1 << exchook_io_sensor_mappings[i]); } + } - /* Sys */ - if (sys_in.test) { - stat |= GI_TEST; - } + memcpy(sensores_p1, &exchook_io_sensores_p1, sizeof(exchook_io_sensores_p1)); + memcpy(sensores_p2, &exchook_io_sensores_p2, sizeof(exchook_io_sensores_p2)); - if (sys_in.service) { - stat |= GI_SERVICE; - } - - /* Taken from source but doesn't seem to work (on some versions?) */ - if (sys_in.clear) { - stat |= GI_CLEAR; - } - - if (sys_in.coin) { - stat |= GI_COIN; - } - - if (sys_in.coin2) { - stat |= GI_COIN2; - } - - /* iterate bits for up and down events */ - for (uint8_t i = 0; i < 32; i++) { - - if (!(exchook_io_game_input_stat_prev & (1 << i)) && - (stat & (1 << i))) { - /* New push down */ - stat_down |= (1 << i); - } else if ((exchook_io_game_input_stat_prev & (1 << i)) && - !(stat & (1 << i))) { - /* New release */ - stat_up |= (1 << i); - } - } - - /* Extremely bad IO subsystem design */ - *exchook_io_game_input_stat |= stat; - *exchook_io_game_input_down |= stat_down; - *exchook_io_game_input_up = stat_up; - - /* swap for next iterateion */ - exchook_io_game_input_stat_prev = *exchook_io_game_input_stat; - - /* Welp, the game expects us to do output setting if a button is pressed - here...fuck that mess. Merge (i.e. |= not =) with other states set - by the game */ - - memset(&exchook_io_out_pad_press_p1, 0, sizeof(exchook_io_out_pad_press_p1)); - memset(&exchook_io_out_pad_press_p2, 0, sizeof(exchook_io_out_pad_press_p2)); - - /* Player 1 */ - exchook_io_out_pad_press_p1.lu |= exchook_io_sensores_p1.lu; - exchook_io_out_pad_press_p1.ru |= exchook_io_sensores_p1.ru; - exchook_io_out_pad_press_p1.cn |= exchook_io_sensores_p1.cn; - exchook_io_out_pad_press_p1.ld |= exchook_io_sensores_p1.ld; - exchook_io_out_pad_press_p1.rd |= exchook_io_sensores_p1.rd; - - /* Player 2 */ - exchook_io_out_pad_press_p2.lu |= exchook_io_sensores_p2.lu; - exchook_io_out_pad_press_p2.ru |= exchook_io_sensores_p2.ru; - exchook_io_out_pad_press_p2.cn |= exchook_io_sensores_p2.cn; - exchook_io_out_pad_press_p2.ld |= exchook_io_sensores_p2.ld; - exchook_io_out_pad_press_p2.rd |= exchook_io_sensores_p2.rd; - - /* merge */ - /* Player 1 */ - exchook_io_out_pad_press_p1.lu |= exchook_io_out_pad_p1.lu; - exchook_io_out_pad_press_p1.ru |= exchook_io_out_pad_p1.ru; - exchook_io_out_pad_press_p1.cn |= exchook_io_out_pad_p1.cn; - exchook_io_out_pad_press_p1.ld |= exchook_io_out_pad_p1.ld; - exchook_io_out_pad_press_p1.rd |= exchook_io_out_pad_p1.rd; - - /* Player 2 */ - exchook_io_out_pad_press_p2.lu |= exchook_io_out_pad_p2.lu; - exchook_io_out_pad_press_p2.ru |= exchook_io_out_pad_p2.ru; - exchook_io_out_pad_press_p2.cn |= exchook_io_out_pad_p2.cn; - exchook_io_out_pad_press_p2.ld |= exchook_io_out_pad_p2.ld; - exchook_io_out_pad_press_p2.rd |= exchook_io_out_pad_p2.rd; - - exchook_piuio_api.set_output_pad(0, &exchook_io_out_pad_press_p1); - exchook_piuio_api.set_output_pad(1, &exchook_io_out_pad_press_p2); - - return 0; + return 0; } -static int32_t exchook_io_coin_input(void* obj) +static int32_t exchook_io_light_all(void *obj, uint8_t on) { - /* Stub */ + if (on) { + memset(&exchook_io_out_pad_p1, 1, sizeof(exchook_io_out_pad_p1)); + memset(&exchook_io_out_pad_p2, 1, sizeof(exchook_io_out_pad_p2)); + memset(&exchook_io_out_cab, 1, sizeof(exchook_io_out_cab)); + } else { + memset(&exchook_io_out_pad_p1, 0, sizeof(exchook_io_out_pad_p1)); + memset(&exchook_io_out_pad_p2, 0, sizeof(exchook_io_out_pad_p2)); + memset(&exchook_io_out_cab, 0, sizeof(exchook_io_out_cab)); + } - return 0; + exchook_piuio_api.set_output_pad(0, &exchook_io_out_pad_p1); + exchook_piuio_api.set_output_pad(1, &exchook_io_out_pad_p2); + exchook_piuio_api.set_output_cab(&exchook_io_out_cab); + + return 0; } -static int32_t exchook_io_coin_input_2(void* obj) +static int32_t exchook_io_light_neon(void *obj, uint8_t on) { - /* Stub */ + if (on) { + exchook_io_out_cab.bass = true; + } else { + exchook_io_out_cab.bass = false; + } - return 0; + exchook_piuio_api.set_output_cab(&exchook_io_out_cab); + + return 0; } -static int32_t exchook_io_coin_counter_2(void* obj) +static int32_t +exchook_io_light_halogan(void *obj, uint8_t on, uint16_t light_id) { - /* Stub */ + if (light_id & 0x0400) { + exchook_io_out_cab.halo_l1 = on; + } - return 0; + if (light_id & 0x0200) { + exchook_io_out_cab.halo_l2 = on; + } + + if (light_id & 0x0100) { + exchook_io_out_cab.halo_r1 = on; + } + + if (light_id & 0x0080) { + exchook_io_out_cab.halo_r2 = on; + } + + exchook_piuio_api.set_output_cab(&exchook_io_out_cab); + + return 0; +} + +static int32_t exchook_io_light_p1_ccfl(void *obj, uint8_t on, uint16_t cmd) +{ + if (cmd & 0x0004) { + exchook_io_out_pad_p1.lu = on; + } + + if (cmd & 0x0008) { + exchook_io_out_pad_p1.ru = on; + } + + if (cmd & 0x0010) { + exchook_io_out_pad_p1.cn = on; + } + + if (cmd & 0x0020) { + exchook_io_out_pad_p1.ld = on; + } + + if (cmd & 0x040) { + exchook_io_out_pad_p1.rd = on; + } + + return 0; +} + +static int32_t exchook_io_light_p2_ccfl(void *obj, uint8_t on, uint16_t cmd) +{ + if (cmd & 0x0004) { + exchook_io_out_pad_p2.lu = on; + } + + if (cmd & 0x0008) { + exchook_io_out_pad_p2.ru = on; + } + + if (cmd & 0x0010) { + exchook_io_out_pad_p2.cn = on; + } + + if (cmd & 0x0020) { + exchook_io_out_pad_p2.ld = on; + } + + if (cmd & 0x040) { + exchook_io_out_pad_p2.rd = on; + } + + return 0; +} + +static int32_t exchook_io_input(void *obj) +{ + uint32_t stat; + uint32_t stat_down; + uint32_t stat_up; + + struct ptapi_io_piuio_sys_inputs sys_in; + + memset(&sys_in, 0, sizeof(struct ptapi_io_piuio_sys_inputs)); + + exchook_piuio_api.get_input_sys(&sys_in); + + /* For game loaders and stuff */ + if (exchook_io_exit_on_service_test) { + if (sys_in.test && sys_in.service) { + log_info("Exit on service + test enabled and hit, bye"); + exit(0); + } + } + + /* process final input states for the game as well as service, test, clear + and coin which can't be handled in the check function */ + + stat = 0; + stat_down = 0; + stat_up = 0; + + /* Player 1 */ + if (exchook_io_sensores_p1.lu) { + stat |= GI_P1_7; + } + + if (exchook_io_sensores_p1.ru) { + stat |= GI_P1_9; + } + + if (exchook_io_sensores_p1.cn) { + stat |= GI_P1_5; + } + + if (exchook_io_sensores_p1.ld) { + stat |= GI_P1_1; + } + + if (exchook_io_sensores_p1.rd) { + stat |= GI_P1_3; + } + + /* Player 2 */ + if (exchook_io_sensores_p2.lu) { + stat |= GI_P2_7; + } + + if (exchook_io_sensores_p2.ru) { + stat |= GI_P2_9; + } + + if (exchook_io_sensores_p2.cn) { + stat |= GI_P2_5; + } + + if (exchook_io_sensores_p2.ld) { + stat |= GI_P2_1; + } + + if (exchook_io_sensores_p2.rd) { + stat |= GI_P2_3; + } + + /* Sys */ + if (sys_in.test) { + stat |= GI_TEST; + } + + if (sys_in.service) { + stat |= GI_SERVICE; + } + + /* Taken from source but doesn't seem to work (on some versions?) */ + if (sys_in.clear) { + stat |= GI_CLEAR; + } + + if (sys_in.coin) { + stat |= GI_COIN; + } + + if (sys_in.coin2) { + stat |= GI_COIN2; + } + + /* iterate bits for up and down events */ + for (uint8_t i = 0; i < 32; i++) { + + if (!(exchook_io_game_input_stat_prev & (1 << i)) && (stat & (1 << i))) { + /* New push down */ + stat_down |= (1 << i); + } else if ( + (exchook_io_game_input_stat_prev & (1 << i)) && !(stat & (1 << i))) { + /* New release */ + stat_up |= (1 << i); + } + } + + /* Extremely bad IO subsystem design */ + *exchook_io_game_input_stat |= stat; + *exchook_io_game_input_down |= stat_down; + *exchook_io_game_input_up = stat_up; + + /* swap for next iterateion */ + exchook_io_game_input_stat_prev = *exchook_io_game_input_stat; + + /* Welp, the game expects us to do output setting if a button is pressed + here...fuck that mess. Merge (i.e. |= not =) with other states set + by the game */ + + memset(&exchook_io_out_pad_press_p1, 0, sizeof(exchook_io_out_pad_press_p1)); + memset(&exchook_io_out_pad_press_p2, 0, sizeof(exchook_io_out_pad_press_p2)); + + /* Player 1 */ + exchook_io_out_pad_press_p1.lu |= exchook_io_sensores_p1.lu; + exchook_io_out_pad_press_p1.ru |= exchook_io_sensores_p1.ru; + exchook_io_out_pad_press_p1.cn |= exchook_io_sensores_p1.cn; + exchook_io_out_pad_press_p1.ld |= exchook_io_sensores_p1.ld; + exchook_io_out_pad_press_p1.rd |= exchook_io_sensores_p1.rd; + + /* Player 2 */ + exchook_io_out_pad_press_p2.lu |= exchook_io_sensores_p2.lu; + exchook_io_out_pad_press_p2.ru |= exchook_io_sensores_p2.ru; + exchook_io_out_pad_press_p2.cn |= exchook_io_sensores_p2.cn; + exchook_io_out_pad_press_p2.ld |= exchook_io_sensores_p2.ld; + exchook_io_out_pad_press_p2.rd |= exchook_io_sensores_p2.rd; + + /* merge */ + /* Player 1 */ + exchook_io_out_pad_press_p1.lu |= exchook_io_out_pad_p1.lu; + exchook_io_out_pad_press_p1.ru |= exchook_io_out_pad_p1.ru; + exchook_io_out_pad_press_p1.cn |= exchook_io_out_pad_p1.cn; + exchook_io_out_pad_press_p1.ld |= exchook_io_out_pad_p1.ld; + exchook_io_out_pad_press_p1.rd |= exchook_io_out_pad_p1.rd; + + /* Player 2 */ + exchook_io_out_pad_press_p2.lu |= exchook_io_out_pad_p2.lu; + exchook_io_out_pad_press_p2.ru |= exchook_io_out_pad_p2.ru; + exchook_io_out_pad_press_p2.cn |= exchook_io_out_pad_p2.cn; + exchook_io_out_pad_press_p2.ld |= exchook_io_out_pad_p2.ld; + exchook_io_out_pad_press_p2.rd |= exchook_io_out_pad_p2.rd; + + exchook_piuio_api.set_output_pad(0, &exchook_io_out_pad_press_p1); + exchook_piuio_api.set_output_pad(1, &exchook_io_out_pad_press_p2); + + return 0; +} + +static int32_t exchook_io_coin_input(void *obj) +{ + /* Stub */ + + return 0; +} + +static int32_t exchook_io_coin_input_2(void *obj) +{ + /* Stub */ + + return 0; +} + +static int32_t exchook_io_coin_counter_2(void *obj) +{ + /* Stub */ + + return 0; } \ No newline at end of file diff --git a/src/main/hook/exc/io.h b/src/main/hook/exc/io.h index 248986f..dae8eeb 100644 --- a/src/main/hook/exc/io.h +++ b/src/main/hook/exc/io.h @@ -15,7 +15,9 @@ * @param piuio_lib_path Path to piuio lib to use for emulation * @parma exit_on_service_test Exit the game when pressing service + test */ -void exchook_io_init(const struct exchook_mempatch_table* patch_table, const char* piuio_lib_path, +void exchook_io_init( + const struct exchook_mempatch_table *patch_table, + const char *piuio_lib_path, bool exit_on_service_test); /** diff --git a/src/main/hook/exc/lockchip.c b/src/main/hook/exc/lockchip.c index 9c5b844..32fe73e 100644 --- a/src/main/hook/exc/lockchip.c +++ b/src/main/hook/exc/lockchip.c @@ -2,42 +2,42 @@ #include -#include "sec/lockchip/lockchip.h" #include "sec/lockchip/lockchip-defs.h" +#include "sec/lockchip/lockchip.h" #include "util/log.h" #include "util/patch.h" #include "lockchip.h" -static void exchook_lockchip_dec_chunk(uint8_t len, const uint8_t* src, - uint8_t* dest); +static void +exchook_lockchip_dec_chunk(uint8_t len, const uint8_t *src, uint8_t *dest); -void exchook_lockchip_init(const struct exchook_mempatch_table* patch_table) +void exchook_lockchip_init(const struct exchook_mempatch_table *patch_table) { - sec_lockchip_init( - sec_lockchip_defs_transforms[SEC_LOCK_CHIP_DEFS_GAME_EXCEED]); + sec_lockchip_init( + sec_lockchip_defs_transforms[SEC_LOCK_CHIP_DEFS_GAME_EXCEED]); - /* Hook lockchip */ - util_patch_function(patch_table->addr_lockchip_dec_chunk, exchook_lockchip_dec_chunk); + /* Hook lockchip */ + util_patch_function( + patch_table->addr_lockchip_dec_chunk, exchook_lockchip_dec_chunk); - log_info("Initialized"); + log_info("Initialized"); } -static void exchook_lockchip_dec_chunk(uint8_t len, const uint8_t* src, - uint8_t* dest) +static void +exchook_lockchip_dec_chunk(uint8_t len, const uint8_t *src, uint8_t *dest) { - sec_lockchip_start(); + sec_lockchip_start(); - uint8_t last_res = sec_lockchip_step(src[0] ^ 0xFF); + uint8_t last_res = sec_lockchip_step(src[0] ^ 0xFF); - for (size_t i = 1; i < len; i++) - { - uint8_t result = sec_lockchip_step(src[i] ^ 0xFF); - dest[i - 1] = (uint8_t)((last_res >> 3) ^ (result << 5)); - last_res = result; - } + for (size_t i = 1; i < len; i++) { + uint8_t result = sec_lockchip_step(src[i] ^ 0xFF); + dest[i - 1] = (uint8_t)((last_res >> 3) ^ (result << 5)); + last_res = result; + } - uint8_t last_byte = sec_lockchip_step(0); - dest[len - 1] = (uint8_t)((last_res >> 3) ^ (last_byte << 5)); + uint8_t last_byte = sec_lockchip_step(0); + dest[len - 1] = (uint8_t)((last_res >> 3) ^ (last_byte << 5)); } \ No newline at end of file diff --git a/src/main/hook/exc/lockchip.h b/src/main/hook/exc/lockchip.h index 0721981..766f570 100644 --- a/src/main/hook/exc/lockchip.h +++ b/src/main/hook/exc/lockchip.h @@ -14,6 +14,6 @@ * * @param patch_table Patch table with memory addresses */ -void exchook_lockchip_init(const struct exchook_mempatch_table* patch_table); +void exchook_lockchip_init(const struct exchook_mempatch_table *patch_table); #endif \ No newline at end of file diff --git a/src/main/hook/exc/main.c b/src/main/hook/exc/main.c index 54bd09d..dcfb47f 100644 --- a/src/main/hook/exc/main.c +++ b/src/main/hook/exc/main.c @@ -30,225 +30,245 @@ #include "mempatch.h" #include "options.h" -static void exchook_bootstrapping(int argc, char** argv, struct exchook_options* options, char** game_data_path) +static void exchook_bootstrapping( + int argc, + char **argv, + struct exchook_options *options, + char **game_data_path) { - log_assert(argc >= 0); - log_assert(argv); - log_assert(options); - log_assert(game_data_path); + log_assert(argc >= 0); + log_assert(argv); + log_assert(options); + log_assert(game_data_path); - if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { - return; - } + if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { + return; + } - hook_core_piu_log_init(argc, argv); + hook_core_piu_log_init(argc, argv); - if (!exchook_options_init(argc, argv, options)) { - exit(0); - } + if (!exchook_options_init(argc, argv, options)) { + exit(0); + } - hook_core_piu_log_info(argc, argv); + hook_core_piu_log_info(argc, argv); - *game_data_path = hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); + *game_data_path = + hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); - hook_core_piu_utils_verify_root_user(); + hook_core_piu_utils_verify_root_user(); - log_info("Initializing, piu game data path: %s", *game_data_path); + log_info("Initializing, piu game data path: %s", *game_data_path); } static void exchook_game_version_mempatch_table_init( - struct exchook_options* options, - const struct exchook_mempatch_table** patch_table) + struct exchook_options *options, + const struct exchook_mempatch_table **patch_table) { - log_assert(options); - log_assert(patch_table); + log_assert(options); + log_assert(patch_table); - if (!options->game.version) { - log_die("No game version specified"); - } else { - log_info("Game version configured: %s", options->game.version); - } + if (!options->game.version) { + log_die("No game version specified"); + } else { + log_info("Game version configured: %s", options->game.version); + } - *patch_table = exchook_mempatch_get_table(options->game.version); + *patch_table = exchook_mempatch_get_table(options->game.version); - if (*patch_table == NULL) { - log_die("Unsupported game version %s", options->game.version); - } + if (*patch_table == NULL) { + log_die("Unsupported game version %s", options->game.version); + } } -static void exchook_patch_fs_init(struct exchook_options* options) +static void exchook_patch_fs_init(struct exchook_options *options) { - log_assert(options); + log_assert(options); - patch_hook_mon_init( - options->patch.hook_mon.io, - options->patch.hook_mon.file, - options->patch.hook_mon.fs, - options->patch.hook_mon.usb, - options->patch.hook_mon.open); + patch_hook_mon_init( + options->patch.hook_mon.io, + options->patch.hook_mon.file, + options->patch.hook_mon.fs, + options->patch.hook_mon.usb, + options->patch.hook_mon.open); - patch_redir_init(); + patch_redir_init(); } -static void exchook_fs_redir_settings(struct exchook_options* options) +static void exchook_fs_redir_settings(struct exchook_options *options) { - log_assert(options); + log_assert(options); - if (options->game.settings) { - if (!util_fs_path_exists(options->game.settings)) { - log_info("Settings path %s does not exist, creating", options->game.settings); + if (options->game.settings) { + if (!util_fs_path_exists(options->game.settings)) { + log_info( + "Settings path %s does not exist, creating", options->game.settings); - if (!util_fs_mkdir(options->game.settings)) { - log_error("Creating directory %s failed", options->game.settings); - } - } - - char* abs_path = util_fs_get_abs_path(options->game.settings); - - cnh_redir_add("/SETTINGS", abs_path); - free(abs_path); - } else { - log_warn("No settings path specified"); + if (!util_fs_mkdir(options->game.settings)) { + log_error("Creating directory %s failed", options->game.settings); + } } + + char *abs_path = util_fs_get_abs_path(options->game.settings); + + cnh_redir_add("/SETTINGS", abs_path); + free(abs_path); + } else { + log_warn("No settings path specified"); + } } static void exchook_fs_redir_usb() { - /* Needed on newer kernels */ - cnh_redir_add("/proc/bus/usb/devices", "/sys/kernel/debug/usb/devices"); + /* Needed on newer kernels */ + cnh_redir_add("/proc/bus/usb/devices", "/sys/kernel/debug/usb/devices"); } -static void exchook_patch_gfx_init(struct exchook_options* options) +static void exchook_patch_gfx_init(struct exchook_options *options) { - log_assert(options); + log_assert(options); - patch_gfx_init(); + patch_gfx_init(); - if (options->patch.gfx.windowed) { - patch_gfx_force_window_mode(); - } + if (options->patch.gfx.windowed) { + patch_gfx_force_window_mode(); + } } -static void exchook_patch_main_loop_init(struct exchook_options* options) +static void exchook_patch_main_loop_init(struct exchook_options *options) { - log_assert(options); + log_assert(options); - patch_main_loop_init(true, options->patch.main_loop.disable_built_in_inputs, false); + patch_main_loop_init( + true, options->patch.main_loop.disable_built_in_inputs, false); - if (options->patch.main_loop.x11_input_handler_api_lib) { - char* abs_path_x11_input_hook_lib = util_fs_get_abs_path(options->patch.main_loop.x11_input_handler_api_lib); + if (options->patch.main_loop.x11_input_handler_api_lib) { + char *abs_path_x11_input_hook_lib = util_fs_get_abs_path( + options->patch.main_loop.x11_input_handler_api_lib); - patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); - free(abs_path_x11_input_hook_lib); - } + patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); + free(abs_path_x11_input_hook_lib); + } } -static void exchook_patch_sound_init(struct exchook_options* options, const struct exchook_mempatch_table* patch_table) +static void exchook_patch_sound_init( + struct exchook_options *options, + const struct exchook_mempatch_table *patch_table) { - log_assert(options); - log_assert(patch_table); + log_assert(options); + log_assert(patch_table); - /* exceed crashes with its default device hw:0. use dmix instead */ - if (strcmp(options->patch.sound.device, "dmix") != 0) { - log_warn("Game might crash with selected sound device %s, use 'dmix' instead if that happens", - options->patch.sound.device); - } + /* exceed crashes with its default device hw:0. use dmix instead */ + if (strcmp(options->patch.sound.device, "dmix") != 0) { + log_warn( + "Game might crash with selected sound device %s, use 'dmix' instead if " + "that happens", + options->patch.sound.device); + } - patch_sound_init(options->patch.sound.device); - patch_asound_fix_init(); + patch_sound_init(options->patch.sound.device); + patch_asound_fix_init(); - /* return from StopAllEffects to avoid killing the sound thread */ - util_patch_write_memory_byte(patch_table->addr_stop_all_effects_return, 0xC3); + /* return from StopAllEffects to avoid killing the sound thread */ + util_patch_write_memory_byte(patch_table->addr_stop_all_effects_return, 0xC3); } -static void exchook_patch_sigsegv_init(struct exchook_options* options) +static void exchook_patch_sigsegv_init(struct exchook_options *options) { - log_assert(options); + log_assert(options); - patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); + patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); } -static void exchook_patch_lockchip_init(const struct exchook_mempatch_table* patch_table) +static void +exchook_patch_lockchip_init(const struct exchook_mempatch_table *patch_table) { - log_assert(patch_table); + log_assert(patch_table); - exchook_lockchip_init(patch_table); + exchook_lockchip_init(patch_table); } -static void exchook_patch_eeprom_init(struct exchook_options* options, const struct exchook_mempatch_table* patch_table) +static void exchook_patch_eeprom_init( + struct exchook_options *options, + const struct exchook_mempatch_table *patch_table) { - log_assert(options); - log_assert(patch_table); + log_assert(options); + log_assert(patch_table); - char* eeprom_path; + char *eeprom_path; - if (options->game.settings) { - char* abs_path = util_fs_get_abs_path(options->game.settings); + if (options->game.settings) { + char *abs_path = util_fs_get_abs_path(options->game.settings); - eeprom_path = util_str_merge(abs_path, "/eeprom.bin"); - free(abs_path); - } else { - eeprom_path = util_str_dup("/tmp/eeprom.bin"); - log_warn("No settings path specified to store eeprom data, defaulting to %s", eeprom_path); - } + eeprom_path = util_str_merge(abs_path, "/eeprom.bin"); + free(abs_path); + } else { + eeprom_path = util_str_dup("/tmp/eeprom.bin"); + log_warn( + "No settings path specified to store eeprom data, defaulting to %s", + eeprom_path); + } - exchook_eeprom_init(patch_table, eeprom_path); - free(eeprom_path); + exchook_eeprom_init(patch_table, eeprom_path); + free(eeprom_path); } -static void exchook_patch_piuio_init(struct exchook_options* options, const struct exchook_mempatch_table* patch_table) +static void exchook_patch_piuio_init( + struct exchook_options *options, + const struct exchook_mempatch_table *patch_table) { - log_assert(options); - log_assert(patch_table); + log_assert(options); + log_assert(patch_table); - if (options->patch.piuio.api_lib) { - char* abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); + if (options->patch.piuio.api_lib) { + char *abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); - exchook_io_init(patch_table, abs_path_iolib, options->patch.piuio.exit_test_serv); - free(abs_path_iolib); - } + exchook_io_init( + patch_table, abs_path_iolib, options->patch.piuio.exit_test_serv); + free(abs_path_iolib); + } } void exchook_constructor(void) { - /* Nothing here */ + /* Nothing here */ } void exchook_destructor(void) { - /* Nothing here */ + /* Nothing here */ } -void exchook_trap_before_main(int argc, char** argv) +void exchook_trap_before_main(int argc, char **argv) { - log_assert(argc >= 0); - log_assert(argv); + log_assert(argc >= 0); + log_assert(argv); - char* game_data_path; - struct exchook_options options; - const struct exchook_mempatch_table* mempatch_table; + char *game_data_path; + struct exchook_options options; + const struct exchook_mempatch_table *mempatch_table; - exchook_bootstrapping(argc, argv, &options, &game_data_path); - exchook_game_version_mempatch_table_init(&options, &mempatch_table); - exchook_patch_fs_init(&options); - exchook_fs_redir_settings(&options); - exchook_fs_redir_usb(); - exchook_patch_gfx_init(&options); - exchook_patch_main_loop_init(&options); - exchook_patch_sound_init(&options, mempatch_table); - exchook_patch_sigsegv_init(&options); - exchook_patch_lockchip_init(mempatch_table); - exchook_patch_eeprom_init(&options, mempatch_table); - exchook_patch_piuio_init(&options, mempatch_table); + exchook_bootstrapping(argc, argv, &options, &game_data_path); + exchook_game_version_mempatch_table_init(&options, &mempatch_table); + exchook_patch_fs_init(&options); + exchook_fs_redir_settings(&options); + exchook_fs_redir_usb(); + exchook_patch_gfx_init(&options); + exchook_patch_main_loop_init(&options); + exchook_patch_sound_init(&options, mempatch_table); + exchook_patch_sigsegv_init(&options); + exchook_patch_lockchip_init(mempatch_table); + exchook_patch_eeprom_init(&options, mempatch_table); + exchook_patch_piuio_init(&options, mempatch_table); - free(game_data_path); + free(game_data_path); - log_info("Hooking finished"); + log_info("Hooking finished"); } void exchook_trap_after_main(void) { - exchook_io_shutdown(); + exchook_io_shutdown(); } LIB_MAIN_CONSTRUCTOR(exchook_constructor); diff --git a/src/main/hook/exc/mempatch.c b/src/main/hook/exc/mempatch.c index 4f10f2f..96c4242 100644 --- a/src/main/hook/exc/mempatch.c +++ b/src/main/hook/exc/mempatch.c @@ -48,15 +48,16 @@ static const struct exchook_mempatch_table _exchook_mempatch_table[] = { }, }; -const struct exchook_mempatch_table* exchook_mempatch_get_table(const char* version) +const struct exchook_mempatch_table * +exchook_mempatch_get_table(const char *version) { - size_t entries = lengthof(_exchook_mempatch_table); + size_t entries = lengthof(_exchook_mempatch_table); - for (uint32_t i = 0; i < entries; i++) { - if (!strcmp(_exchook_mempatch_table[i].version, version)) { - return &_exchook_mempatch_table[i]; - } + for (uint32_t i = 0; i < entries; i++) { + if (!strcmp(_exchook_mempatch_table[i].version, version)) { + return &_exchook_mempatch_table[i]; } + } - return NULL; + return NULL; } \ No newline at end of file diff --git a/src/main/hook/exc/mempatch.h b/src/main/hook/exc/mempatch.h index 5926952..b062bec 100644 --- a/src/main/hook/exc/mempatch.h +++ b/src/main/hook/exc/mempatch.h @@ -4,26 +4,27 @@ #include struct exchook_mempatch_table { - const char* version; - uintptr_t addr_eeprom_read; - uintptr_t addr_eeprom_write; - uintptr_t addr_io_check; - uintptr_t addr_io_light_all; - uintptr_t addr_io_light_neon; - uintptr_t addr_io_light_halogan; - uintptr_t addr_io_light_p1_ccfl; - uintptr_t addr_io_light_p2_ccfl; - uintptr_t addr_io_input; - uintptr_t addr_io_coin_input; - uintptr_t addr_io_coin_input_2; - uintptr_t addr_io_coin_counter_2; - uintptr_t addr_io_game_input_stat; - uintptr_t addr_io_game_input_down; - uintptr_t addr_io_game_input_up; - uintptr_t addr_lockchip_dec_chunk; - uintptr_t addr_stop_all_effects_return; + const char *version; + uintptr_t addr_eeprom_read; + uintptr_t addr_eeprom_write; + uintptr_t addr_io_check; + uintptr_t addr_io_light_all; + uintptr_t addr_io_light_neon; + uintptr_t addr_io_light_halogan; + uintptr_t addr_io_light_p1_ccfl; + uintptr_t addr_io_light_p2_ccfl; + uintptr_t addr_io_input; + uintptr_t addr_io_coin_input; + uintptr_t addr_io_coin_input_2; + uintptr_t addr_io_coin_counter_2; + uintptr_t addr_io_game_input_stat; + uintptr_t addr_io_game_input_down; + uintptr_t addr_io_game_input_up; + uintptr_t addr_lockchip_dec_chunk; + uintptr_t addr_stop_all_effects_return; }; -const struct exchook_mempatch_table* exchook_mempatch_get_table(const char* version); +const struct exchook_mempatch_table * +exchook_mempatch_get_table(const char *version); #endif \ No newline at end of file diff --git a/src/main/hook/exc/options.c b/src/main/hook/exc/options.c index e25cbdd..081c129 100644 --- a/src/main/hook/exc/options.c +++ b/src/main/hook/exc/options.c @@ -10,12 +10,16 @@ #define EXCHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO "patch.hook_mon.io" #define EXCHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN "patch.hook_mon.open" #define EXCHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB "patch.hook_mon.usb" -#define EXCHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS "patch.hook_main_loop.disable_built_in_inputs" -#define EXCHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER "patch_hook_main_loop.x11_input_handler" +#define EXCHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS \ + "patch.hook_main_loop.disable_built_in_inputs" +#define EXCHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER \ + "patch_hook_main_loop.x11_input_handler" #define EXCHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB "patch.piuio.emu_lib" -#define EXCHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV "patch.piuio_exit.test_serv" +#define EXCHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV \ + "patch.piuio_exit.test_serv" #define EXCHOOK_OPTIONS_STR_PATCH_SOUND_DEVICE "patch.sound.device" -#define EXCHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV "patch.sigsegv.halt_on_segv" +#define EXCHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV \ + "patch.sigsegv.halt_on_segv" #define EXCHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE "util.log.file" #define EXCHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL "util.log.level" @@ -29,7 +33,9 @@ static const struct util_options_def exchook_options_def[] = { }, { .name = EXCHOOK_OPTIONS_STR_GAME_VERSION, - .description = "Version of the game (format YYYYMMDD). Make sure this matches exactly the version you are" + .description = + "Version of the game (format YYYYMMDD). Make sure this matches " + "exactly the version you are" " running because the hook lib has to apply memory patches.", .param = 'v', .type = UTIL_OPTIONS_TYPE_STR, @@ -78,22 +84,26 @@ static const struct util_options_def exchook_options_def[] = { .default_value.b = false, }, { - .name = EXCHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS, - .description = "Disable the built in keyboard inputs for test (F1), service (F2) and clear (F3)", + .name = + EXCHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS, + .description = "Disable the built in keyboard inputs for test (F1), " + "service (F2) and clear (F3)", .param = 'k', .type = UTIL_OPTIONS_TYPE_BOOL, .default_value.b = false, }, { .name = EXCHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER, - .description = "Path to a library implementing the x11-input-handler api to capture X11 keyboard inputs", + .description = "Path to a library implementing the x11-input-handler " + "api to capture X11 keyboard inputs", .param = 'q', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, }, { .name = EXCHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB, - .description = "Path to library implementing the piuio api for piuio emulation", + .description = + "Path to library implementing the piuio api for piuio emulation", .param = 'p', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, @@ -144,41 +154,54 @@ static const struct util_options_defs exchook_options_defs = { .ndefs = lengthof(exchook_options_def) }; -bool exchook_options_init(int argc, char** argv, struct exchook_options* options) +bool exchook_options_init( + int argc, char **argv, struct exchook_options *options) { - log_assert(argv); - log_assert(options); + log_assert(argv); + log_assert(options); - struct util_options_opts* options_opt; + struct util_options_opts *options_opt; - util_options_init(argc, argv); - options_opt = util_options_get(&exchook_options_defs); + util_options_init(argc, argv); + options_opt = util_options_get(&exchook_options_defs); - if (!options_opt) { - return false; - } + if (!options_opt) { + return false; + } - options->game.settings = util_options_get_str(options_opt, EXCHOOK_OPTIONS_STR_GAME_SETTINGS); - options->game.version = util_options_get_str(options_opt, EXCHOOK_OPTIONS_STR_GAME_VERSION); - options->patch.gfx.windowed = util_options_get_bool(options_opt, EXCHOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); - options->patch.hook_mon.file = util_options_get_bool(options_opt, EXCHOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); - options->patch.hook_mon.fs = util_options_get_bool(options_opt, EXCHOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); - options->patch.hook_mon.io = util_options_get_bool(options_opt, EXCHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); - options->patch.hook_mon.open = util_options_get_bool(options_opt, EXCHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); - options->patch.hook_mon.usb = util_options_get_bool(options_opt, EXCHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); - options->patch.main_loop.disable_built_in_inputs = util_options_get_bool(options_opt, - EXCHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); - options->patch.main_loop.x11_input_handler_api_lib = - util_options_get_str(options_opt, EXCHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); - options->patch.piuio.api_lib = util_options_get_str(options_opt, EXCHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); - options->patch.piuio.exit_test_serv = - util_options_get_bool(options_opt, EXCHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); - options->patch.sound.device = util_options_get_str(options_opt, EXCHOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); - options->patch.sigsegv.halt_on_segv = - util_options_get_bool(options_opt, EXCHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); - options->log.file = util_options_get_str(options_opt, EXCHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); - options->log.level = - (enum util_log_level) util_options_get_int(options_opt, EXCHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); + options->game.settings = + util_options_get_str(options_opt, EXCHOOK_OPTIONS_STR_GAME_SETTINGS); + options->game.version = + util_options_get_str(options_opt, EXCHOOK_OPTIONS_STR_GAME_VERSION); + options->patch.gfx.windowed = util_options_get_bool( + options_opt, EXCHOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); + options->patch.hook_mon.file = util_options_get_bool( + options_opt, EXCHOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); + options->patch.hook_mon.fs = + util_options_get_bool(options_opt, EXCHOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); + options->patch.hook_mon.io = + util_options_get_bool(options_opt, EXCHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); + options->patch.hook_mon.open = util_options_get_bool( + options_opt, EXCHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); + options->patch.hook_mon.usb = util_options_get_bool( + options_opt, EXCHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); + options->patch.main_loop.disable_built_in_inputs = util_options_get_bool( + options_opt, + EXCHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); + options->patch.main_loop.x11_input_handler_api_lib = util_options_get_str( + options_opt, EXCHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); + options->patch.piuio.api_lib = util_options_get_str( + options_opt, EXCHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); + options->patch.piuio.exit_test_serv = util_options_get_bool( + options_opt, EXCHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); + options->patch.sound.device = + util_options_get_str(options_opt, EXCHOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); + options->patch.sigsegv.halt_on_segv = util_options_get_bool( + options_opt, EXCHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); + options->log.file = util_options_get_str( + options_opt, EXCHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); + options->log.level = (enum util_log_level) util_options_get_int( + options_opt, EXCHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); - return true; + return true; } \ No newline at end of file diff --git a/src/main/hook/exc/options.h b/src/main/hook/exc/options.h index c16ead8..10df73c 100644 --- a/src/main/hook/exc/options.h +++ b/src/main/hook/exc/options.h @@ -7,49 +7,50 @@ #include "util/log.h" struct exchook_options { - struct game { - const char* settings; - const char* version; - } game; + struct game { + const char *settings; + const char *version; + } game; - struct patch { - struct gfx { - bool windowed; - } gfx; + struct patch { + struct gfx { + bool windowed; + } gfx; - struct hook_mon { - bool file; - bool fs; - bool io; - bool open; - bool usb; - } hook_mon; + struct hook_mon { + bool file; + bool fs; + bool io; + bool open; + bool usb; + } hook_mon; - struct main_loop { - bool disable_built_in_inputs; - const char* x11_input_handler_api_lib; - } main_loop; + struct main_loop { + bool disable_built_in_inputs; + const char *x11_input_handler_api_lib; + } main_loop; - struct piuio { - const char* api_lib; - bool exit_test_serv; - } piuio; + struct piuio { + const char *api_lib; + bool exit_test_serv; + } piuio; - struct sound { - const char* device; - } sound; + struct sound { + const char *device; + } sound; - struct sigsegv { - bool halt_on_segv; - } sigsegv; - } patch; + struct sigsegv { + bool halt_on_segv; + } sigsegv; + } patch; - struct log { - const char* file; - enum util_log_level level; - } log; + struct log { + const char *file; + enum util_log_level level; + } log; }; -bool exchook_options_init(int argc, char** argv, struct exchook_options* options); +bool exchook_options_init( + int argc, char **argv, struct exchook_options *options); #endif diff --git a/src/main/hook/f2/main.c b/src/main/hook/f2/main.c index ed144c8..61ecc81 100644 --- a/src/main/hook/f2/main.c +++ b/src/main/hook/f2/main.c @@ -17,8 +17,8 @@ #include "hook/patch/hook-mon.h" #include "hook/patch/main-loop.h" #include "hook/patch/mounts.h" -#include "hook/patch/piuio.h" #include "hook/patch/piuio-exit.h" +#include "hook/patch/piuio.h" #include "hook/patch/redir.h" #include "hook/patch/sigsegv.h" #include "hook/patch/sound.h" @@ -39,204 +39,217 @@ extern const uint8_t _binary_f2hook_hdd_raw_end[]; extern const uint8_t _binary_f2hook_hasp_key_start[]; extern const uint8_t _binary_f2hook_hasp_key_end[]; -static void f2hook_bootstrapping(int argc, char** argv, struct f2hook_options* options, char** game_data_path) +static void f2hook_bootstrapping( + int argc, + char **argv, + struct f2hook_options *options, + char **game_data_path) { - log_assert(argc >= 0); - log_assert(argv); - log_assert(options); - log_assert(game_data_path); + log_assert(argc >= 0); + log_assert(argv); + log_assert(options); + log_assert(game_data_path); - if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { - return; - } + if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { + return; + } - hook_core_piu_log_init(argc, argv); + hook_core_piu_log_init(argc, argv); - if (!f2hook_options_init(argc, argv, options)) { - exit(0); - } + if (!f2hook_options_init(argc, argv, options)) { + exit(0); + } - hook_core_piu_log_info(argc, argv); + hook_core_piu_log_info(argc, argv); - *game_data_path = hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); + *game_data_path = + hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); - hook_core_piu_utils_verify_root_user(); + hook_core_piu_utils_verify_root_user(); - hook_core_piu_utils_fix_locale(); + hook_core_piu_utils_fix_locale(); - log_info("Initializing, piu game data path: %s", *game_data_path); + log_info("Initializing, piu game data path: %s", *game_data_path); } -static void f2hook_patch_fs_init(struct f2hook_options* options) +static void f2hook_patch_fs_init(struct f2hook_options *options) { - log_assert(options); + log_assert(options); - patch_hook_mon_init( - options->patch.hook_mon.io, - options->patch.hook_mon.file, - options->patch.hook_mon.fs, - options->patch.hook_mon.usb, - options->patch.hook_mon.open); + patch_hook_mon_init( + options->patch.hook_mon.io, + options->patch.hook_mon.file, + options->patch.hook_mon.fs, + options->patch.hook_mon.usb, + options->patch.hook_mon.open); - patch_redir_init(); + patch_redir_init(); } -static void f2hook_fs_redir_settings(struct f2hook_options* options) +static void f2hook_fs_redir_settings(struct f2hook_options *options) { - log_assert(options); + log_assert(options); - if (options->game.settings) { - if (!util_fs_path_exists(options->game.settings)) { - log_info("Settings path %s does not exist, creating", options->game.settings); + if (options->game.settings) { + if (!util_fs_path_exists(options->game.settings)) { + log_info( + "Settings path %s does not exist, creating", options->game.settings); - if (!util_fs_mkdir(options->game.settings)) { - log_error("Creating directory %s failed", options->game.settings); - } - } - - char* abs_path = util_fs_get_abs_path(options->game.settings); - - cnh_redir_add("/SETTINGS", abs_path); - free(abs_path); - } else { - log_warn("No settings path specified"); + if (!util_fs_mkdir(options->game.settings)) { + log_error("Creating directory %s failed", options->game.settings); + } } + + char *abs_path = util_fs_get_abs_path(options->game.settings); + + cnh_redir_add("/SETTINGS", abs_path); + free(abs_path); + } else { + log_warn("No settings path specified"); + } } static void f2hook_fs_redir_usb() { - /* Needed on newer kernels */ - cnh_redir_add("/proc/bus/usb/devices", "/sys/kernel/debug/usb/devices"); - patch_usbfs_init(); + /* Needed on newer kernels */ + cnh_redir_add("/proc/bus/usb/devices", "/sys/kernel/debug/usb/devices"); + patch_usbfs_init(); } -static void f2hook_fs_redirs_init(struct f2hook_options* options, const char* game_data_path) +static void f2hook_fs_redirs_init( + struct f2hook_options *options, const char *game_data_path) { - log_assert(options); - log_assert(game_data_path); + log_assert(options); + log_assert(game_data_path); - f2hook_fs_redir_settings(options); + f2hook_fs_redir_settings(options); - f2hook_fs_redir_usb(); + f2hook_fs_redir_usb(); } static void f2hook_patch_fs_mounting_init() { - patch_mounts_init(); + patch_mounts_init(); - patch_usb_mnt_init(); + patch_usb_mnt_init(); } -static void f2hook_patch_gfx_init(struct f2hook_options* options) +static void f2hook_patch_gfx_init(struct f2hook_options *options) { - log_assert(options); + log_assert(options); - patch_gfx_init(); + patch_gfx_init(); - if (options->patch.gfx.windowed) { - patch_gfx_force_window_mode(); - } + if (options->patch.gfx.windowed) { + patch_gfx_force_window_mode(); + } } -static void f2hook_patch_main_loop_init(struct f2hook_options* options) +static void f2hook_patch_main_loop_init(struct f2hook_options *options) { - log_assert(options); + log_assert(options); - patch_main_loop_init(false, options->patch.main_loop.disable_built_in_inputs, false); + patch_main_loop_init( + false, options->patch.main_loop.disable_built_in_inputs, false); - if (options->patch.main_loop.x11_input_handler_api_lib) { - char* abs_path_x11_input_hook_lib = util_fs_get_abs_path(options->patch.main_loop.x11_input_handler_api_lib); + if (options->patch.main_loop.x11_input_handler_api_lib) { + char *abs_path_x11_input_hook_lib = util_fs_get_abs_path( + options->patch.main_loop.x11_input_handler_api_lib); - patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); - free(abs_path_x11_input_hook_lib); - } + patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); + free(abs_path_x11_input_hook_lib); + } } -static void f2hook_patch_sound_init(struct f2hook_options* options) +static void f2hook_patch_sound_init(struct f2hook_options *options) { - log_assert(options); + log_assert(options); - patch_sound_init(options->patch.sound.device); - patch_axmier_block_init(); + patch_sound_init(options->patch.sound.device); + patch_axmier_block_init(); } -static void f2hook_patch_sigsegv_init(struct f2hook_options* options) +static void f2hook_patch_sigsegv_init(struct f2hook_options *options) { - log_assert(options); + log_assert(options); - patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); + patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); } static void f2hook_patch_dongle_init() { - patch_hasp_init((const uint8_t*) _binary_f2hook_hasp_key_start, - ((uintptr_t) &_binary_f2hook_hasp_key_end - (uintptr_t) &_binary_f2hook_hasp_key_start)); + patch_hasp_init( + (const uint8_t *) _binary_f2hook_hasp_key_start, + ((uintptr_t) &_binary_f2hook_hasp_key_end - + (uintptr_t) &_binary_f2hook_hasp_key_start)); } static void f2hook_patch_hdd_check_init() { - patch_hdd_check_init((const uint8_t*) _binary_f2hook_hdd_raw_start, - ((uintptr_t) &_binary_f2hook_hdd_raw_end - (uintptr_t) &_binary_f2hook_hdd_raw_start)); + patch_hdd_check_init( + (const uint8_t *) _binary_f2hook_hdd_raw_start, + ((uintptr_t) &_binary_f2hook_hdd_raw_end - + (uintptr_t) &_binary_f2hook_hdd_raw_start)); } -static void f2hook_patch_piuio_init(struct f2hook_options* options) +static void f2hook_patch_piuio_init(struct f2hook_options *options) { - log_assert(options); + log_assert(options); - /* Hook before IO emulation */ - if (options->patch.piuio.exit_test_serv) { - patch_piuio_exit_init(); - } + /* Hook before IO emulation */ + if (options->patch.piuio.exit_test_serv) { + patch_piuio_exit_init(); + } - patch_usb_init_fix_init(); - patch_usb_emu_init(); + patch_usb_init_fix_init(); + patch_usb_emu_init(); - if (options->patch.piuio.api_lib) { - char* abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); + if (options->patch.piuio.api_lib) { + char *abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); - patch_piuio_init(abs_path_iolib); - free(abs_path_iolib); - } + patch_piuio_init(abs_path_iolib); + free(abs_path_iolib); + } } void f2hook_constructor(void) { - /* Nothing here */ + /* Nothing here */ } void f2hook_destructor(void) { - /* Nothing here */ + /* Nothing here */ } -void f2hook_trap_before_main(int argc, char** argv) +void f2hook_trap_before_main(int argc, char **argv) { - log_assert(argc >= 0); - log_assert(argv); + log_assert(argc >= 0); + log_assert(argv); - char* game_data_path; - struct f2hook_options options; + char *game_data_path; + struct f2hook_options options; - f2hook_bootstrapping(argc, argv, &options, &game_data_path); - f2hook_patch_fs_init(&options); - f2hook_fs_redirs_init(&options, game_data_path); - f2hook_patch_fs_mounting_init(); - f2hook_patch_gfx_init(&options); - f2hook_patch_main_loop_init(&options); - f2hook_patch_sound_init(&options); - f2hook_patch_sigsegv_init(&options); - f2hook_patch_dongle_init(); - f2hook_patch_hdd_check_init(); - f2hook_patch_piuio_init(&options); + f2hook_bootstrapping(argc, argv, &options, &game_data_path); + f2hook_patch_fs_init(&options); + f2hook_fs_redirs_init(&options, game_data_path); + f2hook_patch_fs_mounting_init(); + f2hook_patch_gfx_init(&options); + f2hook_patch_main_loop_init(&options); + f2hook_patch_sound_init(&options); + f2hook_patch_sigsegv_init(&options); + f2hook_patch_dongle_init(); + f2hook_patch_hdd_check_init(); + f2hook_patch_piuio_init(&options); - free(game_data_path); + free(game_data_path); - log_info("Hooking finished"); + log_info("Hooking finished"); } void f2hook_trap_after_main(void) { - patch_piuio_shutdown(); + patch_piuio_shutdown(); } LIB_MAIN_CONSTRUCTOR(f2hook_constructor); diff --git a/src/main/hook/f2/options.c b/src/main/hook/f2/options.c index 0e9995c..874937c 100644 --- a/src/main/hook/f2/options.c +++ b/src/main/hook/f2/options.c @@ -9,14 +9,19 @@ #define F2HOOK_OPTIONS_STR_PATCH_HOOK_MON_IO "patch.hook_mon.io" #define F2HOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN "patch.hook_mon.open" #define F2HOOK_OPTIONS_STR_PATCH_HOOK_MON_USB "patch.hook_mon.usb" -#define F2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS "patch.hook_main_loop.disable_built_in_inputs" -#define F2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER "patch_hook_main_loop.x11_input_handler" +#define F2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS \ + "patch.hook_main_loop.disable_built_in_inputs" +#define F2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER \ + "patch_hook_main_loop.x11_input_handler" #define F2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_SERVER "patch.net_profile.server" -#define F2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_MACHINE_ID "patch.net_profile.machine_id" +#define F2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_MACHINE_ID \ + "patch.net_profile.machine_id" #define F2HOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB "patch.piuio.emu_lib" -#define F2HOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV "patch.piuio_exit.test_serv" +#define F2HOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV \ + "patch.piuio_exit.test_serv" #define F2HOOK_OPTIONS_STR_PATCH_SOUND_DEVICE "patch.sound.device" -#define F2HOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV "patch.sigsegv.halt_on_segv" +#define F2HOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV \ + "patch.sigsegv.halt_on_segv" #define F2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE "util.log.file" #define F2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL "util.log.level" @@ -72,21 +77,24 @@ const struct util_options_def f2hook_options_def[] = { }, { .name = F2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS, - .description = "Disable the built in keyboard inputs for test (F1), service (F2) and clear (F3)", + .description = "Disable the built in keyboard inputs for test (F1), " + "service (F2) and clear (F3)", .param = 'k', .type = UTIL_OPTIONS_TYPE_BOOL, .default_value.b = false, }, { .name = F2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER, - .description = "Path to a library implementing the x11-input-handler api to capture X11 keyboard inputs", + .description = "Path to a library implementing the x11-input-handler " + "api to capture X11 keyboard inputs", .param = 'q', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, }, { .name = F2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_SERVER, - .description = "Address and port of pumpnet server (e.g. 127.0.0.1:1234)", + .description = + "Address and port of pumpnet server (e.g. 127.0.0.1:1234)", .param = 'n', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, @@ -100,7 +108,8 @@ const struct util_options_def f2hook_options_def[] = { }, { .name = F2HOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB, - .description = "Path to library implementing the piuio api for piuio emulation", + .description = + "Path to library implementing the piuio api for piuio emulation", .param = 'p', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, @@ -151,45 +160,58 @@ const struct util_options_defs f2hook_options_defs = { .ndefs = lengthof(f2hook_options_def) }; -bool f2hook_options_init(int argc, char** argv, struct f2hook_options* options) +bool f2hook_options_init(int argc, char **argv, struct f2hook_options *options) { - log_assert(argv); - log_assert(options); + log_assert(argv); + log_assert(options); - struct util_options_opts* options_opt; + struct util_options_opts *options_opt; - util_options_init(argc, argv); - options_opt = util_options_get(&f2hook_options_defs); + util_options_init(argc, argv); + options_opt = util_options_get(&f2hook_options_defs); - if (!options_opt) { - return false; - } + if (!options_opt) { + return false; + } - options->game.settings = util_options_get_str(options_opt, F2HOOK_OPTIONS_STR_GAME_SETTINGS); - options->patch.gfx.windowed = util_options_get_bool(options_opt, F2HOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); - options->patch.hook_mon.file = util_options_get_bool(options_opt, F2HOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); - options->patch.hook_mon.fs = util_options_get_bool(options_opt, F2HOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); - options->patch.hook_mon.io = util_options_get_bool(options_opt, F2HOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); - options->patch.hook_mon.open = util_options_get_bool(options_opt, F2HOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); - options->patch.hook_mon.usb = util_options_get_bool(options_opt, F2HOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); - options->patch.main_loop.disable_built_in_inputs = util_options_get_bool(options_opt, - F2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); - options->patch.main_loop.x11_input_handler_api_lib = - util_options_get_str(options_opt, F2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); - options->patch.net.server = util_options_get_str(options_opt, F2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_SERVER); - options->patch.net.machine_id = strtoul( - util_options_get_str(options_opt, F2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_MACHINE_ID), - NULL, - 16); - options->patch.piuio.api_lib = util_options_get_str(options_opt, F2HOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); - options->patch.piuio.exit_test_serv = - util_options_get_bool(options_opt, F2HOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); - options->patch.sound.device = util_options_get_str(options_opt, F2HOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); - options->patch.sigsegv.halt_on_segv = - util_options_get_bool(options_opt, F2HOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); - options->log.file = util_options_get_str(options_opt, F2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); - options->log.level = - (enum util_log_level) util_options_get_int(options_opt, F2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); + options->game.settings = + util_options_get_str(options_opt, F2HOOK_OPTIONS_STR_GAME_SETTINGS); + options->patch.gfx.windowed = + util_options_get_bool(options_opt, F2HOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); + options->patch.hook_mon.file = util_options_get_bool( + options_opt, F2HOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); + options->patch.hook_mon.fs = + util_options_get_bool(options_opt, F2HOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); + options->patch.hook_mon.io = + util_options_get_bool(options_opt, F2HOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); + options->patch.hook_mon.open = util_options_get_bool( + options_opt, F2HOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); + options->patch.hook_mon.usb = + util_options_get_bool(options_opt, F2HOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); + options->patch.main_loop.disable_built_in_inputs = util_options_get_bool( + options_opt, + F2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); + options->patch.main_loop.x11_input_handler_api_lib = util_options_get_str( + options_opt, F2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); + options->patch.net.server = util_options_get_str( + options_opt, F2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_SERVER); + options->patch.net.machine_id = strtoul( + util_options_get_str( + options_opt, F2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_MACHINE_ID), + NULL, + 16); + options->patch.piuio.api_lib = + util_options_get_str(options_opt, F2HOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); + options->patch.piuio.exit_test_serv = util_options_get_bool( + options_opt, F2HOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); + options->patch.sound.device = + util_options_get_str(options_opt, F2HOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); + options->patch.sigsegv.halt_on_segv = util_options_get_bool( + options_opt, F2HOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); + options->log.file = + util_options_get_str(options_opt, F2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); + options->log.level = (enum util_log_level) util_options_get_int( + options_opt, F2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); - return true; + return true; } \ No newline at end of file diff --git a/src/main/hook/f2/options.h b/src/main/hook/f2/options.h index 65c03d9..22b0051 100644 --- a/src/main/hook/f2/options.h +++ b/src/main/hook/f2/options.h @@ -7,53 +7,53 @@ #include "util/log.h" struct f2hook_options { - struct game { - const char* settings; - } game; + struct game { + const char *settings; + } game; - struct patch { - struct gfx { - bool windowed; - } gfx; + struct patch { + struct gfx { + bool windowed; + } gfx; - struct hook_mon { - bool file; - bool fs; - bool io; - bool open; - bool usb; - } hook_mon; + struct hook_mon { + bool file; + bool fs; + bool io; + bool open; + bool usb; + } hook_mon; - struct main_loop { - bool disable_built_in_inputs; - const char* x11_input_handler_api_lib; - } main_loop; + struct main_loop { + bool disable_built_in_inputs; + const char *x11_input_handler_api_lib; + } main_loop; - struct net { - const char* server; - uint32_t machine_id; - } net; + struct net { + const char *server; + uint32_t machine_id; + } net; - struct piuio { - const char* api_lib; - bool exit_test_serv; - } piuio; + struct piuio { + const char *api_lib; + bool exit_test_serv; + } piuio; - struct sound { - const char* device; - } sound; + struct sound { + const char *device; + } sound; - struct sigsegv { - bool halt_on_segv; - } sigsegv; - } patch; + struct sigsegv { + bool halt_on_segv; + } sigsegv; + } patch; - struct log { - const char* file; - enum util_log_level level; - } log; + struct log { + const char *file; + enum util_log_level level; + } log; }; -bool f2hook_options_init(int argc, char** argv, struct f2hook_options* options); +bool f2hook_options_init(int argc, char **argv, struct f2hook_options *options); #endif diff --git a/src/main/hook/fex/main.c b/src/main/hook/fex/main.c index 25cde24..316358a 100644 --- a/src/main/hook/fex/main.c +++ b/src/main/hook/fex/main.c @@ -17,8 +17,8 @@ #include "hook/patch/main-loop.h" #include "hook/patch/microdog40.h" #include "hook/patch/mounts.h" -#include "hook/patch/piuio.h" #include "hook/patch/piuio-exit.h" +#include "hook/patch/piuio.h" #include "hook/patch/redir.h" #include "hook/patch/sigsegv.h" #include "hook/patch/sound.h" @@ -39,202 +39,215 @@ extern const uint8_t _binary_fexhook_hdd_raw_end[]; extern const uint8_t _binary_fexhook_dog_key_start[]; extern const uint8_t _binary_fexhook_dog_key_end[]; -static void fexhook_bootstrapping(int argc, char** argv, struct fexhook_options* options, char** game_data_path) +static void fexhook_bootstrapping( + int argc, + char **argv, + struct fexhook_options *options, + char **game_data_path) { - log_assert(argc >= 0); - log_assert(argv); - log_assert(options); - log_assert(game_data_path); + log_assert(argc >= 0); + log_assert(argv); + log_assert(options); + log_assert(game_data_path); - if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { - return; - } + if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { + return; + } - hook_core_piu_log_init(argc, argv); + hook_core_piu_log_init(argc, argv); - if (!fexhook_options_init(argc, argv, options)) { - exit(0); - } + if (!fexhook_options_init(argc, argv, options)) { + exit(0); + } - hook_core_piu_log_info(argc, argv); + hook_core_piu_log_info(argc, argv); - *game_data_path = hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); + *game_data_path = + hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); - hook_core_piu_utils_verify_root_user(); + hook_core_piu_utils_verify_root_user(); - log_info("Initializing, piu game data path: %s", *game_data_path); + log_info("Initializing, piu game data path: %s", *game_data_path); } -static void fexhook_patch_fs_init(struct fexhook_options* options) +static void fexhook_patch_fs_init(struct fexhook_options *options) { - log_assert(options); + log_assert(options); - patch_hook_mon_init( - options->patch.hook_mon.io, - options->patch.hook_mon.file, - options->patch.hook_mon.fs, - options->patch.hook_mon.usb, - options->patch.hook_mon.open); + patch_hook_mon_init( + options->patch.hook_mon.io, + options->patch.hook_mon.file, + options->patch.hook_mon.fs, + options->patch.hook_mon.usb, + options->patch.hook_mon.open); - patch_redir_init(); + patch_redir_init(); } -static void fexhook_fs_redir_settings(struct fexhook_options* options) +static void fexhook_fs_redir_settings(struct fexhook_options *options) { - log_assert(options); + log_assert(options); - if (options->game.settings) { - if (!util_fs_path_exists(options->game.settings)) { - log_info("Settings path %s does not exist, creating", options->game.settings); + if (options->game.settings) { + if (!util_fs_path_exists(options->game.settings)) { + log_info( + "Settings path %s does not exist, creating", options->game.settings); - if (!util_fs_mkdir(options->game.settings)) { - log_error("Creating directory %s failed", options->game.settings); - } - } - - char* abs_path = util_fs_get_abs_path(options->game.settings); - - cnh_redir_add("/SETTINGS", abs_path); - free(abs_path); - } else { - log_warn("No settings path specified"); + if (!util_fs_mkdir(options->game.settings)) { + log_error("Creating directory %s failed", options->game.settings); + } } + + char *abs_path = util_fs_get_abs_path(options->game.settings); + + cnh_redir_add("/SETTINGS", abs_path); + free(abs_path); + } else { + log_warn("No settings path specified"); + } } static void fexhook_fs_redir_usb() { - /* Needed on newer kernels */ - cnh_redir_add("/proc/bus/usb/devices", "/sys/kernel/debug/usb/devices"); - patch_usbfs_init(); + /* Needed on newer kernels */ + cnh_redir_add("/proc/bus/usb/devices", "/sys/kernel/debug/usb/devices"); + patch_usbfs_init(); } -static void fexhook_fs_redirs_init(struct fexhook_options* options, const char* game_data_path) +static void fexhook_fs_redirs_init( + struct fexhook_options *options, const char *game_data_path) { - log_assert(options); - log_assert(game_data_path); + log_assert(options); + log_assert(game_data_path); - fexhook_fs_redir_settings(options); + fexhook_fs_redir_settings(options); - fexhook_fs_redir_usb(); + fexhook_fs_redir_usb(); } static void fexhook_patch_fs_mounting_init() { - patch_mounts_init(); + patch_mounts_init(); - patch_usb_mnt_init(); + patch_usb_mnt_init(); } -static void fexhook_patch_gfx_init(struct fexhook_options* options) +static void fexhook_patch_gfx_init(struct fexhook_options *options) { - log_assert(options); + log_assert(options); - patch_gfx_init(); + patch_gfx_init(); - if (options->patch.gfx.windowed) { - patch_gfx_force_window_mode(); - } + if (options->patch.gfx.windowed) { + patch_gfx_force_window_mode(); + } } -static void fexhook_patch_main_loop_init(struct fexhook_options* options) +static void fexhook_patch_main_loop_init(struct fexhook_options *options) { - log_assert(options); + log_assert(options); - patch_main_loop_init(false, options->patch.main_loop.disable_built_in_inputs, false); + patch_main_loop_init( + false, options->patch.main_loop.disable_built_in_inputs, false); - if (options->patch.main_loop.x11_input_handler_api_lib) { - char* abs_path_x11_input_hook_lib = util_fs_get_abs_path(options->patch.main_loop.x11_input_handler_api_lib); + if (options->patch.main_loop.x11_input_handler_api_lib) { + char *abs_path_x11_input_hook_lib = util_fs_get_abs_path( + options->patch.main_loop.x11_input_handler_api_lib); - patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); - free(abs_path_x11_input_hook_lib); - } + patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); + free(abs_path_x11_input_hook_lib); + } } -static void fexhook_patch_sound_init(struct fexhook_options* options) +static void fexhook_patch_sound_init(struct fexhook_options *options) { - log_assert(options); + log_assert(options); - patch_sound_init(options->patch.sound.device); - patch_axmier_block_init(); + patch_sound_init(options->patch.sound.device); + patch_axmier_block_init(); } -static void fexhook_patch_sigsegv_init(struct fexhook_options* options) +static void fexhook_patch_sigsegv_init(struct fexhook_options *options) { - log_assert(options); + log_assert(options); - patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); + patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); } static void fexhook_patch_dongle_init() { - patch_microdog40_init((const uint8_t*) _binary_fexhook_dog_key_start, - ((uintptr_t) &_binary_fexhook_dog_key_end - (uintptr_t) &_binary_fexhook_dog_key_start)); + patch_microdog40_init( + (const uint8_t *) _binary_fexhook_dog_key_start, + ((uintptr_t) &_binary_fexhook_dog_key_end - + (uintptr_t) &_binary_fexhook_dog_key_start)); } static void fexhook_patch_hdd_check_init() { - patch_hdd_check_init((const uint8_t*) _binary_fexhook_hdd_raw_start, - ((uintptr_t) &_binary_fexhook_hdd_raw_end - (uintptr_t) &_binary_fexhook_hdd_raw_start)); + patch_hdd_check_init( + (const uint8_t *) _binary_fexhook_hdd_raw_start, + ((uintptr_t) &_binary_fexhook_hdd_raw_end - + (uintptr_t) &_binary_fexhook_hdd_raw_start)); } -static void fexhook_patch_piuio_init(struct fexhook_options* options) +static void fexhook_patch_piuio_init(struct fexhook_options *options) { - log_assert(options); + log_assert(options); - /* Hook before IO emulation */ - if (options->patch.piuio.exit_test_serv) { - patch_piuio_exit_init(); - } + /* Hook before IO emulation */ + if (options->patch.piuio.exit_test_serv) { + patch_piuio_exit_init(); + } - patch_usb_init_fix_init(); - patch_usb_emu_init(); + patch_usb_init_fix_init(); + patch_usb_emu_init(); - if (options->patch.piuio.api_lib) { - char* abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); + if (options->patch.piuio.api_lib) { + char *abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); - patch_piuio_init(abs_path_iolib); - free(abs_path_iolib); - } + patch_piuio_init(abs_path_iolib); + free(abs_path_iolib); + } } void fexhook_constructor(void) { - /* Nothing here */ + /* Nothing here */ } void fexhook_destructor(void) { - /* Nothing here */ + /* Nothing here */ } -void fexhook_trap_before_main(int argc, char** argv) +void fexhook_trap_before_main(int argc, char **argv) { - log_assert(argc >= 0); - log_assert(argv); + log_assert(argc >= 0); + log_assert(argv); - char* game_data_path; - struct fexhook_options options; + char *game_data_path; + struct fexhook_options options; - fexhook_bootstrapping(argc, argv, &options, &game_data_path); - fexhook_patch_fs_init(&options); - fexhook_fs_redirs_init(&options, game_data_path); - fexhook_patch_fs_mounting_init(); - fexhook_patch_gfx_init(&options); - fexhook_patch_main_loop_init(&options); - fexhook_patch_sound_init(&options); - fexhook_patch_sigsegv_init(&options); - fexhook_patch_dongle_init(); - fexhook_patch_hdd_check_init(); - fexhook_patch_piuio_init(&options); + fexhook_bootstrapping(argc, argv, &options, &game_data_path); + fexhook_patch_fs_init(&options); + fexhook_fs_redirs_init(&options, game_data_path); + fexhook_patch_fs_mounting_init(); + fexhook_patch_gfx_init(&options); + fexhook_patch_main_loop_init(&options); + fexhook_patch_sound_init(&options); + fexhook_patch_sigsegv_init(&options); + fexhook_patch_dongle_init(); + fexhook_patch_hdd_check_init(); + fexhook_patch_piuio_init(&options); - free(game_data_path); + free(game_data_path); - log_info("Hooking finished"); + log_info("Hooking finished"); } void fexhook_trap_after_main(void) { - patch_piuio_shutdown(); + patch_piuio_shutdown(); } LIB_MAIN_CONSTRUCTOR(fexhook_constructor); diff --git a/src/main/hook/fex/options.c b/src/main/hook/fex/options.c index 525b8e1..9aceaf2 100644 --- a/src/main/hook/fex/options.c +++ b/src/main/hook/fex/options.c @@ -9,14 +9,19 @@ #define FEXHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO "patch.hook_mon.io" #define FEXHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN "patch.hook_mon.open" #define FEXHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB "patch.hook_mon.usb" -#define FEXHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS "patch.hook_main_loop.disable_built_in_inputs" -#define FEXHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER "patch_hook_main_loop.x11_input_handler" +#define FEXHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS \ + "patch.hook_main_loop.disable_built_in_inputs" +#define FEXHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER \ + "patch_hook_main_loop.x11_input_handler" #define FEXHOOK_OPTIONS_STR_PATCH_NET_PROFILE_SERVER "patch.net_profile.server" -#define FEXHOOK_OPTIONS_STR_PATCH_NET_PROFILE_MACHINE_ID "patch.net_profile.machine_id" +#define FEXHOOK_OPTIONS_STR_PATCH_NET_PROFILE_MACHINE_ID \ + "patch.net_profile.machine_id" #define FEXHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB "patch.piuio.emu_lib" -#define FEXHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV "patch.piuio_exit.test_serv" +#define FEXHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV \ + "patch.piuio_exit.test_serv" #define FEXHOOK_OPTIONS_STR_PATCH_SOUND_DEVICE "patch.sound.device" -#define FEXHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV "patch.sigsegv.halt_on_segv" +#define FEXHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV \ + "patch.sigsegv.halt_on_segv" #define FEXHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE "util.log.file" #define FEXHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL "util.log.level" @@ -71,22 +76,26 @@ const struct util_options_def fexhook_options_def[] = { .default_value.b = false, }, { - .name = FEXHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS, - .description = "Disable the built in keyboard inputs for test (F1), service (F2) and clear (F3)", + .name = + FEXHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS, + .description = "Disable the built in keyboard inputs for test (F1), " + "service (F2) and clear (F3)", .param = 'k', .type = UTIL_OPTIONS_TYPE_BOOL, .default_value.b = false, }, { .name = FEXHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER, - .description = "Path to a library implementing the x11-input-handler api to capture X11 keyboard inputs", + .description = "Path to a library implementing the x11-input-handler " + "api to capture X11 keyboard inputs", .param = 'q', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, }, { .name = FEXHOOK_OPTIONS_STR_PATCH_NET_PROFILE_SERVER, - .description = "Address and port of pumpnet server (e.g. 127.0.0.1:1234)", + .description = + "Address and port of pumpnet server (e.g. 127.0.0.1:1234)", .param = 'n', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, @@ -100,7 +109,8 @@ const struct util_options_def fexhook_options_def[] = { }, { .name = FEXHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB, - .description = "Path to library implementing the piuio api for piuio emulation", + .description = + "Path to library implementing the piuio api for piuio emulation", .param = 'p', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, @@ -151,45 +161,59 @@ const struct util_options_defs fexhook_options_defs = { .ndefs = lengthof(fexhook_options_def) }; -bool fexhook_options_init(int argc, char** argv, struct fexhook_options* options) +bool fexhook_options_init( + int argc, char **argv, struct fexhook_options *options) { - log_assert(argv); - log_assert(options); + log_assert(argv); + log_assert(options); - struct util_options_opts* options_opt; + struct util_options_opts *options_opt; - util_options_init(argc, argv); - options_opt = util_options_get(&fexhook_options_defs); + util_options_init(argc, argv); + options_opt = util_options_get(&fexhook_options_defs); - if (!options_opt) { - return false; - } + if (!options_opt) { + return false; + } - options->game.settings = util_options_get_str(options_opt, FEXHOOK_OPTIONS_STR_GAME_SETTINGS); - options->patch.gfx.windowed = util_options_get_bool(options_opt, FEXHOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); - options->patch.hook_mon.file = util_options_get_bool(options_opt, FEXHOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); - options->patch.hook_mon.fs = util_options_get_bool(options_opt, FEXHOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); - options->patch.hook_mon.io = util_options_get_bool(options_opt, FEXHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); - options->patch.hook_mon.open = util_options_get_bool(options_opt, FEXHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); - options->patch.hook_mon.usb = util_options_get_bool(options_opt, FEXHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); - options->patch.main_loop.disable_built_in_inputs = util_options_get_bool(options_opt, - FEXHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); - options->patch.main_loop.x11_input_handler_api_lib = - util_options_get_str(options_opt, FEXHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); - options->patch.net.server = util_options_get_str(options_opt, FEXHOOK_OPTIONS_STR_PATCH_NET_PROFILE_SERVER); - options->patch.net.machine_id = strtoul( - util_options_get_str(options_opt, FEXHOOK_OPTIONS_STR_PATCH_NET_PROFILE_MACHINE_ID), - NULL, - 16); - options->patch.piuio.api_lib = util_options_get_str(options_opt, FEXHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); - options->patch.piuio.exit_test_serv = - util_options_get_bool(options_opt, FEXHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); - options->patch.sound.device = util_options_get_str(options_opt, FEXHOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); - options->patch.sigsegv.halt_on_segv = - util_options_get_bool(options_opt, FEXHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); - options->log.file = util_options_get_str(options_opt, FEXHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); - options->log.level = - (enum util_log_level) util_options_get_int(options_opt, FEXHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); + options->game.settings = + util_options_get_str(options_opt, FEXHOOK_OPTIONS_STR_GAME_SETTINGS); + options->patch.gfx.windowed = util_options_get_bool( + options_opt, FEXHOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); + options->patch.hook_mon.file = util_options_get_bool( + options_opt, FEXHOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); + options->patch.hook_mon.fs = + util_options_get_bool(options_opt, FEXHOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); + options->patch.hook_mon.io = + util_options_get_bool(options_opt, FEXHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); + options->patch.hook_mon.open = util_options_get_bool( + options_opt, FEXHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); + options->patch.hook_mon.usb = util_options_get_bool( + options_opt, FEXHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); + options->patch.main_loop.disable_built_in_inputs = util_options_get_bool( + options_opt, + FEXHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); + options->patch.main_loop.x11_input_handler_api_lib = util_options_get_str( + options_opt, FEXHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); + options->patch.net.server = util_options_get_str( + options_opt, FEXHOOK_OPTIONS_STR_PATCH_NET_PROFILE_SERVER); + options->patch.net.machine_id = strtoul( + util_options_get_str( + options_opt, FEXHOOK_OPTIONS_STR_PATCH_NET_PROFILE_MACHINE_ID), + NULL, + 16); + options->patch.piuio.api_lib = util_options_get_str( + options_opt, FEXHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); + options->patch.piuio.exit_test_serv = util_options_get_bool( + options_opt, FEXHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); + options->patch.sound.device = + util_options_get_str(options_opt, FEXHOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); + options->patch.sigsegv.halt_on_segv = util_options_get_bool( + options_opt, FEXHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); + options->log.file = util_options_get_str( + options_opt, FEXHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); + options->log.level = (enum util_log_level) util_options_get_int( + options_opt, FEXHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); - return true; + return true; } \ No newline at end of file diff --git a/src/main/hook/fex/options.h b/src/main/hook/fex/options.h index 1d97a29..26d7a29 100644 --- a/src/main/hook/fex/options.h +++ b/src/main/hook/fex/options.h @@ -7,53 +7,54 @@ #include "util/log.h" struct fexhook_options { - struct game { - const char* settings; - } game; + struct game { + const char *settings; + } game; - struct patch { - struct gfx { - bool windowed; - } gfx; + struct patch { + struct gfx { + bool windowed; + } gfx; - struct hook_mon { - bool file; - bool fs; - bool io; - bool open; - bool usb; - } hook_mon; + struct hook_mon { + bool file; + bool fs; + bool io; + bool open; + bool usb; + } hook_mon; - struct main_loop { - bool disable_built_in_inputs; - const char* x11_input_handler_api_lib; - } main_loop; + struct main_loop { + bool disable_built_in_inputs; + const char *x11_input_handler_api_lib; + } main_loop; - struct net { - const char* server; - uint32_t machine_id; - } net; + struct net { + const char *server; + uint32_t machine_id; + } net; - struct piuio { - const char* api_lib; - bool exit_test_serv; - } piuio; + struct piuio { + const char *api_lib; + bool exit_test_serv; + } piuio; - struct sound { - const char* device; - } sound; + struct sound { + const char *device; + } sound; - struct sigsegv { - bool halt_on_segv; - } sigsegv; - } patch; + struct sigsegv { + bool halt_on_segv; + } sigsegv; + } patch; - struct log { - const char* file; - enum util_log_level level; - } log; + struct log { + const char *file; + enum util_log_level level; + } log; }; -bool fexhook_options_init(int argc, char** argv, struct fexhook_options* options); +bool fexhook_options_init( + int argc, char **argv, struct fexhook_options *options); #endif diff --git a/src/main/hook/fst/main.c b/src/main/hook/fst/main.c index 389328c..695996a 100644 --- a/src/main/hook/fst/main.c +++ b/src/main/hook/fst/main.c @@ -17,8 +17,8 @@ #include "hook/patch/main-loop.h" #include "hook/patch/microdog40.h" #include "hook/patch/mounts.h" -#include "hook/patch/piuio.h" #include "hook/patch/piuio-exit.h" +#include "hook/patch/piuio.h" #include "hook/patch/redir.h" #include "hook/patch/sigsegv.h" #include "hook/patch/sound.h" @@ -39,202 +39,215 @@ extern const uint8_t _binary_fsthook_hdd_raw_end[]; extern const uint8_t _binary_fsthook_dog_key_start[]; extern const uint8_t _binary_fsthook_dog_key_end[]; -static void fsthook_bootstrapping(int argc, char** argv, struct fsthook_options* options, char** game_data_path) +static void fsthook_bootstrapping( + int argc, + char **argv, + struct fsthook_options *options, + char **game_data_path) { - log_assert(argc >= 0); - log_assert(argv); - log_assert(options); - log_assert(game_data_path); + log_assert(argc >= 0); + log_assert(argv); + log_assert(options); + log_assert(game_data_path); - if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { - return; - } + if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { + return; + } - hook_core_piu_log_init(argc, argv); + hook_core_piu_log_init(argc, argv); - if (!fsthook_options_init(argc, argv, options)) { - exit(0); - } + if (!fsthook_options_init(argc, argv, options)) { + exit(0); + } - hook_core_piu_log_info(argc, argv); + hook_core_piu_log_info(argc, argv); - *game_data_path = hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); + *game_data_path = + hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); - hook_core_piu_utils_verify_root_user(); + hook_core_piu_utils_verify_root_user(); - log_info("Initializing, piu game data path: %s", *game_data_path); + log_info("Initializing, piu game data path: %s", *game_data_path); } -static void fsthook_patch_fs_init(struct fsthook_options* options) +static void fsthook_patch_fs_init(struct fsthook_options *options) { - log_assert(options); + log_assert(options); - patch_hook_mon_init( - options->patch.hook_mon.io, - options->patch.hook_mon.file, - options->patch.hook_mon.fs, - options->patch.hook_mon.usb, - options->patch.hook_mon.open); + patch_hook_mon_init( + options->patch.hook_mon.io, + options->patch.hook_mon.file, + options->patch.hook_mon.fs, + options->patch.hook_mon.usb, + options->patch.hook_mon.open); - patch_redir_init(); + patch_redir_init(); } -static void fsthook_fs_redir_settings(struct fsthook_options* options) +static void fsthook_fs_redir_settings(struct fsthook_options *options) { - log_assert(options); + log_assert(options); - if (options->game.settings) { - if (!util_fs_path_exists(options->game.settings)) { - log_info("Settings path %s does not exist, creating", options->game.settings); + if (options->game.settings) { + if (!util_fs_path_exists(options->game.settings)) { + log_info( + "Settings path %s does not exist, creating", options->game.settings); - if (!util_fs_mkdir(options->game.settings)) { - log_error("Creating directory %s failed", options->game.settings); - } - } - - char* abs_path = util_fs_get_abs_path(options->game.settings); - - cnh_redir_add("/SETTINGS", abs_path); - free(abs_path); - } else { - log_warn("No settings path specified"); + if (!util_fs_mkdir(options->game.settings)) { + log_error("Creating directory %s failed", options->game.settings); + } } + + char *abs_path = util_fs_get_abs_path(options->game.settings); + + cnh_redir_add("/SETTINGS", abs_path); + free(abs_path); + } else { + log_warn("No settings path specified"); + } } static void fsthook_fs_redir_usb() { - /* Needed on newer kernels */ - cnh_redir_add("/proc/bus/usb/devices", "/sys/kernel/debug/usb/devices"); - patch_usbfs_init(); + /* Needed on newer kernels */ + cnh_redir_add("/proc/bus/usb/devices", "/sys/kernel/debug/usb/devices"); + patch_usbfs_init(); } -static void fsthook_fs_redirs_init(struct fsthook_options* options, const char* game_data_path) +static void fsthook_fs_redirs_init( + struct fsthook_options *options, const char *game_data_path) { - log_assert(options); - log_assert(game_data_path); + log_assert(options); + log_assert(game_data_path); - fsthook_fs_redir_settings(options); + fsthook_fs_redir_settings(options); - fsthook_fs_redir_usb(); + fsthook_fs_redir_usb(); } static void fsthook_patch_fs_mounting_init() { - patch_mounts_init(); + patch_mounts_init(); - patch_usb_mnt_init(); + patch_usb_mnt_init(); } -static void fsthook_patch_gfx_init(struct fsthook_options* options) +static void fsthook_patch_gfx_init(struct fsthook_options *options) { - log_assert(options); + log_assert(options); - patch_gfx_init(); + patch_gfx_init(); - if (options->patch.gfx.windowed) { - patch_gfx_force_window_mode(); - } + if (options->patch.gfx.windowed) { + patch_gfx_force_window_mode(); + } } -static void fsthook_patch_main_loop_init(struct fsthook_options* options) +static void fsthook_patch_main_loop_init(struct fsthook_options *options) { - log_assert(options); + log_assert(options); - patch_main_loop_init(false, options->patch.main_loop.disable_built_in_inputs, false); + patch_main_loop_init( + false, options->patch.main_loop.disable_built_in_inputs, false); - if (options->patch.main_loop.x11_input_handler_api_lib) { - char* abs_path_x11_input_hook_lib = util_fs_get_abs_path(options->patch.main_loop.x11_input_handler_api_lib); + if (options->patch.main_loop.x11_input_handler_api_lib) { + char *abs_path_x11_input_hook_lib = util_fs_get_abs_path( + options->patch.main_loop.x11_input_handler_api_lib); - patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); - free(abs_path_x11_input_hook_lib); - } + patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); + free(abs_path_x11_input_hook_lib); + } } -static void fsthook_patch_sound_init(struct fsthook_options* options) +static void fsthook_patch_sound_init(struct fsthook_options *options) { - log_assert(options); + log_assert(options); - patch_sound_init(options->patch.sound.device); - patch_axmier_block_init(); + patch_sound_init(options->patch.sound.device); + patch_axmier_block_init(); } -static void fsthook_patch_sigsegv_init(struct fsthook_options* options) +static void fsthook_patch_sigsegv_init(struct fsthook_options *options) { - log_assert(options); + log_assert(options); - patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); + patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); } static void fsthook_patch_dongle_init() { - patch_microdog40_init((const uint8_t*) _binary_fsthook_dog_key_start, - ((uintptr_t) &_binary_fsthook_dog_key_end - (uintptr_t) &_binary_fsthook_dog_key_start)); + patch_microdog40_init( + (const uint8_t *) _binary_fsthook_dog_key_start, + ((uintptr_t) &_binary_fsthook_dog_key_end - + (uintptr_t) &_binary_fsthook_dog_key_start)); } static void fsthook_patch_hdd_check_init() { - patch_hdd_check_init((const uint8_t*) _binary_fsthook_hdd_raw_start, - ((uintptr_t) &_binary_fsthook_hdd_raw_end - (uintptr_t) &_binary_fsthook_hdd_raw_start)); + patch_hdd_check_init( + (const uint8_t *) _binary_fsthook_hdd_raw_start, + ((uintptr_t) &_binary_fsthook_hdd_raw_end - + (uintptr_t) &_binary_fsthook_hdd_raw_start)); } -static void fsthook_patch_piuio_init(struct fsthook_options* options) +static void fsthook_patch_piuio_init(struct fsthook_options *options) { - log_assert(options); + log_assert(options); - /* Hook before IO emulation */ - if (options->patch.piuio.exit_test_serv) { - patch_piuio_exit_init(); - } + /* Hook before IO emulation */ + if (options->patch.piuio.exit_test_serv) { + patch_piuio_exit_init(); + } - patch_usb_init_fix_init(); - patch_usb_emu_init(); + patch_usb_init_fix_init(); + patch_usb_emu_init(); - if (options->patch.piuio.api_lib) { - char* abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); + if (options->patch.piuio.api_lib) { + char *abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); - patch_piuio_init(abs_path_iolib); - free(abs_path_iolib); - } + patch_piuio_init(abs_path_iolib); + free(abs_path_iolib); + } } void fsthook_constructor(void) { - /* Nothing here */ + /* Nothing here */ } void fsthook_destructor(void) { - /* Nothing here */ + /* Nothing here */ } -void fsthook_trap_before_main(int argc, char** argv) +void fsthook_trap_before_main(int argc, char **argv) { - log_assert(argc >= 0); - log_assert(argv); + log_assert(argc >= 0); + log_assert(argv); - char* game_data_path; - struct fsthook_options options; + char *game_data_path; + struct fsthook_options options; - fsthook_bootstrapping(argc, argv, &options, &game_data_path); - fsthook_patch_fs_init(&options); - fsthook_fs_redirs_init(&options, game_data_path); - fsthook_patch_fs_mounting_init(); - fsthook_patch_gfx_init(&options); - fsthook_patch_main_loop_init(&options); - fsthook_patch_sound_init(&options); - fsthook_patch_sigsegv_init(&options); - fsthook_patch_dongle_init(); - fsthook_patch_hdd_check_init(); - fsthook_patch_piuio_init(&options); + fsthook_bootstrapping(argc, argv, &options, &game_data_path); + fsthook_patch_fs_init(&options); + fsthook_fs_redirs_init(&options, game_data_path); + fsthook_patch_fs_mounting_init(); + fsthook_patch_gfx_init(&options); + fsthook_patch_main_loop_init(&options); + fsthook_patch_sound_init(&options); + fsthook_patch_sigsegv_init(&options); + fsthook_patch_dongle_init(); + fsthook_patch_hdd_check_init(); + fsthook_patch_piuio_init(&options); - free(game_data_path); + free(game_data_path); - log_info("Hooking finished"); + log_info("Hooking finished"); } void fsthook_trap_after_main(void) { - patch_piuio_shutdown(); + patch_piuio_shutdown(); } LIB_MAIN_CONSTRUCTOR(fsthook_constructor); diff --git a/src/main/hook/fst/options.c b/src/main/hook/fst/options.c index 5343c73..db2b4d7 100644 --- a/src/main/hook/fst/options.c +++ b/src/main/hook/fst/options.c @@ -9,14 +9,19 @@ #define FSTHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO "patch.hook_mon.io" #define FSTHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN "patch.hook_mon.open" #define FSTHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB "patch.hook_mon.usb" -#define FSTHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS "patch.hook_main_loop.disable_built_in_inputs" -#define FSTHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER "patch_hook_main_loop.x11_input_handler" +#define FSTHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS \ + "patch.hook_main_loop.disable_built_in_inputs" +#define FSTHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER \ + "patch_hook_main_loop.x11_input_handler" #define FSTHOOK_OPTIONS_STR_PATCH_NET_PROFILE_SERVER "patch.net_profile.server" -#define FSTHOOK_OPTIONS_STR_PATCH_NET_PROFILE_MACHINE_ID "patch.net_profile.machine_id" +#define FSTHOOK_OPTIONS_STR_PATCH_NET_PROFILE_MACHINE_ID \ + "patch.net_profile.machine_id" #define FSTHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB "patch.piuio.emu_lib" -#define FSTHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV "patch.piuio_exit.test_serv" +#define FSTHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV \ + "patch.piuio_exit.test_serv" #define FSTHOOK_OPTIONS_STR_PATCH_SOUND_DEVICE "patch.sound.device" -#define FSTHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV "patch.sigsegv.halt_on_segv" +#define FSTHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV \ + "patch.sigsegv.halt_on_segv" #define FSTHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE "util.log.file" #define FSTHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL "util.log.level" @@ -26,7 +31,7 @@ const struct util_options_def fsthook_options_def[] = { .description = "Path to game settings (SETTINGS) folder", .param = 's', .type = UTIL_OPTIONS_TYPE_STR, - .default_value.str = "./save", + .default_value.str = "./save", }, { .name = FSTHOOK_OPTIONS_STR_PATCH_GFX_WINDOWED, @@ -71,22 +76,26 @@ const struct util_options_def fsthook_options_def[] = { .default_value.b = false, }, { - .name = FSTHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS, - .description = "Disable the built in keyboard inputs for test (F1), service (F2) and clear (F3)", + .name = + FSTHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS, + .description = "Disable the built in keyboard inputs for test (F1), " + "service (F2) and clear (F3)", .param = 'k', .type = UTIL_OPTIONS_TYPE_BOOL, .default_value.b = false, }, { .name = FSTHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER, - .description = "Path to a library implementing the x11-input-handler api to capture X11 keyboard inputs", + .description = "Path to a library implementing the x11-input-handler " + "api to capture X11 keyboard inputs", .param = 'q', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, }, { .name = FSTHOOK_OPTIONS_STR_PATCH_NET_PROFILE_SERVER, - .description = "Address and port of pumpnet server (e.g. 127.0.0.1:1234)", + .description = + "Address and port of pumpnet server (e.g. 127.0.0.1:1234)", .param = 'n', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, @@ -100,7 +109,8 @@ const struct util_options_def fsthook_options_def[] = { }, { .name = FSTHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB, - .description = "Path to library implementing the piuio api for piuio emulation", + .description = + "Path to library implementing the piuio api for piuio emulation", .param = 'p', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, @@ -151,45 +161,59 @@ const struct util_options_defs fsthook_options_defs = { .ndefs = lengthof(fsthook_options_def) }; -bool fsthook_options_init(int argc, char** argv, struct fsthook_options* options) +bool fsthook_options_init( + int argc, char **argv, struct fsthook_options *options) { - log_assert(argv); - log_assert(options); + log_assert(argv); + log_assert(options); - struct util_options_opts* options_opt; + struct util_options_opts *options_opt; - util_options_init(argc, argv); - options_opt = util_options_get(&fsthook_options_defs); + util_options_init(argc, argv); + options_opt = util_options_get(&fsthook_options_defs); - if (!options_opt) { - return false; - } + if (!options_opt) { + return false; + } - options->game.settings = util_options_get_str(options_opt, FSTHOOK_OPTIONS_STR_GAME_SETTINGS); - options->patch.gfx.windowed = util_options_get_bool(options_opt, FSTHOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); - options->patch.hook_mon.file = util_options_get_bool(options_opt, FSTHOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); - options->patch.hook_mon.fs = util_options_get_bool(options_opt, FSTHOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); - options->patch.hook_mon.io = util_options_get_bool(options_opt, FSTHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); - options->patch.hook_mon.open = util_options_get_bool(options_opt, FSTHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); - options->patch.hook_mon.usb = util_options_get_bool(options_opt, FSTHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); - options->patch.main_loop.disable_built_in_inputs = util_options_get_bool(options_opt, - FSTHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); - options->patch.main_loop.x11_input_handler_api_lib = - util_options_get_str(options_opt, FSTHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); - options->patch.net.server = util_options_get_str(options_opt, FSTHOOK_OPTIONS_STR_PATCH_NET_PROFILE_SERVER); - options->patch.net.machine_id = strtoul( - util_options_get_str(options_opt, FSTHOOK_OPTIONS_STR_PATCH_NET_PROFILE_MACHINE_ID), - NULL, - 16); - options->patch.piuio.api_lib = util_options_get_str(options_opt, FSTHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); - options->patch.piuio.exit_test_serv = - util_options_get_bool(options_opt, FSTHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); - options->patch.sound.device = util_options_get_str(options_opt, FSTHOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); - options->patch.sigsegv.halt_on_segv = - util_options_get_bool(options_opt, FSTHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); - options->log.file = util_options_get_str(options_opt, FSTHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); - options->log.level = - (enum util_log_level) util_options_get_int(options_opt, FSTHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); + options->game.settings = + util_options_get_str(options_opt, FSTHOOK_OPTIONS_STR_GAME_SETTINGS); + options->patch.gfx.windowed = util_options_get_bool( + options_opt, FSTHOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); + options->patch.hook_mon.file = util_options_get_bool( + options_opt, FSTHOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); + options->patch.hook_mon.fs = + util_options_get_bool(options_opt, FSTHOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); + options->patch.hook_mon.io = + util_options_get_bool(options_opt, FSTHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); + options->patch.hook_mon.open = util_options_get_bool( + options_opt, FSTHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); + options->patch.hook_mon.usb = util_options_get_bool( + options_opt, FSTHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); + options->patch.main_loop.disable_built_in_inputs = util_options_get_bool( + options_opt, + FSTHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); + options->patch.main_loop.x11_input_handler_api_lib = util_options_get_str( + options_opt, FSTHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); + options->patch.net.server = util_options_get_str( + options_opt, FSTHOOK_OPTIONS_STR_PATCH_NET_PROFILE_SERVER); + options->patch.net.machine_id = strtoul( + util_options_get_str( + options_opt, FSTHOOK_OPTIONS_STR_PATCH_NET_PROFILE_MACHINE_ID), + NULL, + 16); + options->patch.piuio.api_lib = util_options_get_str( + options_opt, FSTHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); + options->patch.piuio.exit_test_serv = util_options_get_bool( + options_opt, FSTHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); + options->patch.sound.device = + util_options_get_str(options_opt, FSTHOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); + options->patch.sigsegv.halt_on_segv = util_options_get_bool( + options_opt, FSTHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); + options->log.file = util_options_get_str( + options_opt, FSTHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); + options->log.level = (enum util_log_level) util_options_get_int( + options_opt, FSTHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); - return true; + return true; } \ No newline at end of file diff --git a/src/main/hook/fst/options.h b/src/main/hook/fst/options.h index c4bde17..0f0d87e 100644 --- a/src/main/hook/fst/options.h +++ b/src/main/hook/fst/options.h @@ -7,53 +7,54 @@ #include "util/log.h" struct fsthook_options { - struct game { - const char* settings; - } game; + struct game { + const char *settings; + } game; - struct patch { - struct gfx { - bool windowed; - } gfx; + struct patch { + struct gfx { + bool windowed; + } gfx; - struct hook_mon { - bool file; - bool fs; - bool io; - bool open; - bool usb; - } hook_mon; + struct hook_mon { + bool file; + bool fs; + bool io; + bool open; + bool usb; + } hook_mon; - struct main_loop { - bool disable_built_in_inputs; - const char* x11_input_handler_api_lib; - } main_loop; + struct main_loop { + bool disable_built_in_inputs; + const char *x11_input_handler_api_lib; + } main_loop; - struct net { - const char* server; - uint32_t machine_id; - } net; + struct net { + const char *server; + uint32_t machine_id; + } net; - struct piuio { - const char* api_lib; - bool exit_test_serv; - } piuio; + struct piuio { + const char *api_lib; + bool exit_test_serv; + } piuio; - struct sound { - const char* device; - } sound; + struct sound { + const char *device; + } sound; - struct sigsegv { - bool halt_on_segv; - } sigsegv; - } patch; + struct sigsegv { + bool halt_on_segv; + } sigsegv; + } patch; - struct log { - const char* file; - enum util_log_level level; - } log; + struct log { + const char *file; + enum util_log_level level; + } log; }; -bool fsthook_options_init(int argc, char** argv, struct fsthook_options* options); +bool fsthook_options_init( + int argc, char **argv, struct fsthook_options *options); #endif diff --git a/src/main/hook/mk3/1st-2nd-fs-fix.c b/src/main/hook/mk3/1st-2nd-fs-fix.c index 4ac50fe..89366a0 100644 --- a/src/main/hook/mk3/1st-2nd-fs-fix.c +++ b/src/main/hook/mk3/1st-2nd-fs-fix.c @@ -10,32 +10,39 @@ typedef int (*cnh_fshook_chdir_t)(const char *path); static cnh_fshook_chdir_t mk3hook_1st_2nd_fs_fix_real_chdir; -static char* mk3hook_1st_2nd_fs_fix_path_game_dir_abs; +static char *mk3hook_1st_2nd_fs_fix_path_game_dir_abs; int chdir(const char *path) { - if (!mk3hook_1st_2nd_fs_fix_real_chdir) { - mk3hook_1st_2nd_fs_fix_real_chdir = (cnh_fshook_chdir_t) cnh_lib_get_func_addr("chdir"); - } + if (!mk3hook_1st_2nd_fs_fix_real_chdir) { + mk3hook_1st_2nd_fs_fix_real_chdir = + (cnh_fshook_chdir_t) cnh_lib_get_func_addr("chdir"); + } - // This seems to be some kind of probe the game is doing to determine something...I assume which folder layout to - // use? When we change directory to our "game" dir which contains all stuff at that point, everything's fine. - // If we do not do that, the game will error not being able to find any files. When loading files, the code also - // does some odd iterating the file system starting at / at that point. I assume that this is some sort of search - // trying to look for the file on the filesystem. However, that breaks a lot of other stuf with the hooking code - // and therefore should not be triggered. - if (mk3hook_1st_2nd_fs_fix_path_game_dir_abs && !strcmp(path, "/datas/bga")) { - log_debug("Trapping /datas/bga chdir, chdir to %s", mk3hook_1st_2nd_fs_fix_path_game_dir_abs); + // This seems to be some kind of probe the game is doing to determine + // something...I assume which folder layout to use? When we change directory + // to our "game" dir which contains all stuff at that point, everything's + // fine. If we do not do that, the game will error not being able to find any + // files. When loading files, the code also does some odd iterating the file + // system starting at / at that point. I assume that this is some sort of + // search trying to look for the file on the filesystem. However, that breaks + // a lot of other stuf with the hooking code and therefore should not be + // triggered. + if (mk3hook_1st_2nd_fs_fix_path_game_dir_abs && !strcmp(path, "/datas/bga")) { + log_debug( + "Trapping /datas/bga chdir, chdir to %s", + mk3hook_1st_2nd_fs_fix_path_game_dir_abs); - return mk3hook_1st_2nd_fs_fix_real_chdir(mk3hook_1st_2nd_fs_fix_path_game_dir_abs); - } else { - return mk3hook_1st_2nd_fs_fix_real_chdir(path); - } + return mk3hook_1st_2nd_fs_fix_real_chdir( + mk3hook_1st_2nd_fs_fix_path_game_dir_abs); + } else { + return mk3hook_1st_2nd_fs_fix_real_chdir(path); + } } -void mk3hook_1st_2nd_fs_fix_init(const char* path_game_dir_abs) +void mk3hook_1st_2nd_fs_fix_init(const char *path_game_dir_abs) { - mk3hook_1st_2nd_fs_fix_path_game_dir_abs = util_str_dup(path_game_dir_abs); + mk3hook_1st_2nd_fs_fix_path_game_dir_abs = util_str_dup(path_game_dir_abs); - log_info("Initialized"); + log_info("Initialized"); } \ No newline at end of file diff --git a/src/main/hook/mk3/1st-2nd-fs-fix.h b/src/main/hook/mk3/1st-2nd-fs-fix.h index 5a8d429..ecbf9d1 100644 --- a/src/main/hook/mk3/1st-2nd-fs-fix.h +++ b/src/main/hook/mk3/1st-2nd-fs-fix.h @@ -1,5 +1,6 @@ /** - * Fixes an issue with the engine of 1st and 2nd when redirecting all game data to one game folder, e.g. ./game/. + * Fixes an issue with the engine of 1st and 2nd when redirecting all game data + * to one game folder, e.g. ./game/. */ #ifndef MK3HOOK_1ST_2ND_FS_FIX_H #define MK3HOOK_1ST_2ND_FS_FIX_H @@ -7,8 +8,9 @@ /** * Initialize the module. * - * @param path_game_dir_abs The absolute path to the "game" dir containing all game assets. + * @param path_game_dir_abs The absolute path to the "game" dir containing all + * game assets. */ -void mk3hook_1st_2nd_fs_fix_init(const char* path_game_dir_abs); +void mk3hook_1st_2nd_fs_fix_init(const char *path_game_dir_abs); #endif diff --git a/src/main/hook/mk3/config.c b/src/main/hook/mk3/config.c index 8b77efc..f1a5656 100644 --- a/src/main/hook/mk3/config.c +++ b/src/main/hook/mk3/config.c @@ -14,123 +14,130 @@ static double mk3hook_config_music_volume; static double mk3hook_config_sfx_volume; static int mk3hook_config_fullscreen; static int mk3hook_config_allow_exit; -static const char* mk3hook_config_save_file; +static const char *mk3hook_config_save_file; int config_read_file(config_t *config, const char *filename) { - // Just stub file loading - log_debug("config_read_file: %s", filename); + // Just stub file loading + log_debug("config_read_file: %s", filename); - return 1; + return 1; } int config_lookup_int(const config_t *config, const char *path, int *value) { - log_debug("config_lookup_int: %s", path); + log_debug("config_lookup_int: %s", path); - if (!strcmp(path, "sync_offset")) { - *value = mk3hook_config_sync_offset; - } else { - log_error("Unsupported int entry read: %s", path); - } + if (!strcmp(path, "sync_offset")) { + *value = mk3hook_config_sync_offset; + } else { + log_error("Unsupported int entry read: %s", path); + } - return 1; + return 1; } int config_lookup_float(const config_t *config, const char *path, double *value) { - log_debug("config_lookup_float: %s", path); + log_debug("config_lookup_float: %s", path); - if (!strcmp(path, "sync_multiplier")) { - *value = mk3hook_config_sync_multiplier; - } else if (!strcmp(path, "music_volume")) { - *value = mk3hook_config_music_volume; - } else if (!strcmp(path, "sfx_volume")) { - *value = mk3hook_config_sfx_volume; - } else { - log_error("Unsupported float entry read: %s", path); - } + if (!strcmp(path, "sync_multiplier")) { + *value = mk3hook_config_sync_multiplier; + } else if (!strcmp(path, "music_volume")) { + *value = mk3hook_config_music_volume; + } else if (!strcmp(path, "sfx_volume")) { + *value = mk3hook_config_sfx_volume; + } else { + log_error("Unsupported float entry read: %s", path); + } - return 1; + return 1; } int config_lookup_bool(const config_t *config, const char *path, int *value) { - log_debug("config_lookup_bool: %s", path); + log_debug("config_lookup_bool: %s", path); - if (!strcmp(path, "fullscreen")) { - *value = mk3hook_config_fullscreen; - } else if (!strcmp(path, "allow_exit")) { - *value = mk3hook_config_allow_exit; - } else { - log_error("Unsupported bool entry read: %s", path); - } + if (!strcmp(path, "fullscreen")) { + *value = mk3hook_config_fullscreen; + } else if (!strcmp(path, "allow_exit")) { + *value = mk3hook_config_allow_exit; + } else { + log_error("Unsupported bool entry read: %s", path); + } - return 1; + return 1; } -int config_lookup_string(const config_t *config, const char *path, const char **value) +int config_lookup_string( + const config_t *config, const char *path, const char **value) { - log_debug("config_lookup_string: %s", path); + log_debug("config_lookup_string: %s", path); - if (!strcmp(path, "save_file")) { - // Note: This is fine as the size of the string pointed to by the returned address is not relevant for any - // operations using them, e.g. there is no merging/copying with limited stack'd buffer sizes involved like - // below. - *value = mk3hook_config_save_file; - } else if (!strcmp(path, "effect_path")) { - // Needs to be hardcoded because the stack buffer for this is only 128 bytes large. This is likely fine for most - // paths and even when resolving relative paths to absolute ones. Still, this is a risk for a buffer overflow. - // Utilize the redirect module in the main lib hook function to redirect this to something like a local game dir - // and resolve this to an absolute path - *value = "EFFECTS/"; - } else if (!strcmp(path, "track_path")) { - // Needs to be hardcoded because the stack buffer for this is only 32 bytes large. When combining it with the - // "Track%02i.mp3" part, the buffer will overflow when this path is longer or even resolved to an absolute path. - // Utilize the redirect module in the main lib hook function to redirect this to something like a local game dir - // and resolve this to an absolute path - *value = "track/"; - } else { - log_error("Unsupported string entry read: %s", path); - } + if (!strcmp(path, "save_file")) { + // Note: This is fine as the size of the string pointed to by the returned + // address is not relevant for any operations using them, e.g. there is no + // merging/copying with limited stack'd buffer sizes involved like below. + *value = mk3hook_config_save_file; + } else if (!strcmp(path, "effect_path")) { + // Needs to be hardcoded because the stack buffer for this is only 128 bytes + // large. This is likely fine for most paths and even when resolving + // relative paths to absolute ones. Still, this is a risk for a buffer + // overflow. Utilize the redirect module in the main lib hook function to + // redirect this to something like a local game dir and resolve this to an + // absolute path + *value = "EFFECTS/"; + } else if (!strcmp(path, "track_path")) { + // Needs to be hardcoded because the stack buffer for this is only 32 bytes + // large. When combining it with the "Track%02i.mp3" part, the buffer will + // overflow when this path is longer or even resolved to an absolute path. + // Utilize the redirect module in the main lib hook function to redirect + // this to something like a local game dir and resolve this to an absolute + // path + *value = "track/"; + } else { + log_error("Unsupported string entry read: %s", path); + } - return 1; + return 1; } -static void mk3hook_config_assign_save_file(const struct mk3hook_options* options) +static void +mk3hook_config_assign_save_file(const struct mk3hook_options *options) { - const char* folder = options->game.settings; + const char *folder = options->game.settings; - if (!util_fs_path_exists(folder)) { - log_info("Settings path %s does not exist, creating", folder); + if (!util_fs_path_exists(folder)) { + log_info("Settings path %s does not exist, creating", folder); - if (!util_fs_mkdir(folder)) { - log_error("Creating directory %s failed", folder); - } + if (!util_fs_mkdir(folder)) { + log_error("Creating directory %s failed", folder); } + } - char* folder_abs = util_fs_get_abs_path(folder); + char *folder_abs = util_fs_get_abs_path(folder); - if (!folder_abs) { - log_error("Failed to resolve absolute path for settings folder"); - return; - } + if (!folder_abs) { + log_error("Failed to resolve absolute path for settings folder"); + return; + } - // Don't free this one after assigning the result value as this will still be read from. Keep memory leak. - mk3hook_config_save_file = util_str_merge(folder_abs, "/EEPROM.BIN"); - free(folder_abs); + // Don't free this one after assigning the result value as this will still be + // read from. Keep memory leak. + mk3hook_config_save_file = util_str_merge(folder_abs, "/EEPROM.BIN"); + free(folder_abs); } -void mk3hook_config_init(const struct mk3hook_options* options) +void mk3hook_config_init(const struct mk3hook_options *options) { - mk3hook_config_sync_offset = options->game.sync_offset; - mk3hook_config_sync_multiplier = options->game.sync_multiplier; - mk3hook_config_music_volume = options->game.music_vol; - mk3hook_config_sfx_volume = options->game.sfx_vol; - mk3hook_config_fullscreen = !options->patch.gfx.windowed; - mk3hook_config_allow_exit = options->patch.piuio.exit_test_serv; + mk3hook_config_sync_offset = options->game.sync_offset; + mk3hook_config_sync_multiplier = options->game.sync_multiplier; + mk3hook_config_music_volume = options->game.music_vol; + mk3hook_config_sfx_volume = options->game.sfx_vol; + mk3hook_config_fullscreen = !options->patch.gfx.windowed; + mk3hook_config_allow_exit = options->patch.piuio.exit_test_serv; - mk3hook_config_assign_save_file(options); + mk3hook_config_assign_save_file(options); - log_info("Initialized"); + log_info("Initialized"); } \ No newline at end of file diff --git a/src/main/hook/mk3/config.h b/src/main/hook/mk3/config.h index ad4e9d8..c99c76d 100644 --- a/src/main/hook/mk3/config.h +++ b/src/main/hook/mk3/config.h @@ -1,6 +1,6 @@ /** - * Patch the configuration file handling which uses libconfig. This hooks libconfig up to pumptools configuration - * infrastructure. + * Patch the configuration file handling which uses libconfig. This hooks + * libconfig up to pumptools configuration infrastructure. */ #ifndef MK3HOOK_CONFIG_H #define MK3HOOK_CONFIG_H @@ -10,8 +10,9 @@ /** * Initialize this module. * - * @param options The options provided to the hook which are injected into libconfig config value reading. + * @param options The options provided to the hook which are injected into + * libconfig config value reading. */ -void mk3hook_config_init(const struct mk3hook_options* options); +void mk3hook_config_init(const struct mk3hook_options *options); #endif diff --git a/src/main/hook/mk3/fmodex.c b/src/main/hook/mk3/fmodex.c index 1d6e58c..6fbfc0e 100644 --- a/src/main/hook/mk3/fmodex.c +++ b/src/main/hook/mk3/fmodex.c @@ -10,117 +10,161 @@ #include "util/log.h" #include "util/str.h" -typedef FMOD_RESULT (*FMOD_System_Init_t)(FMOD_SYSTEM *system, int maxchannels, FMOD_INITFLAGS flags, void *extradriverdata); +typedef FMOD_RESULT (*FMOD_System_Init_t)( + FMOD_SYSTEM *system, + int maxchannels, + FMOD_INITFLAGS flags, + void *extradriverdata); static FMOD_System_Init_t mk3hook_fmodex_real_FMOD_System_Init; static bool mk3hook_fmodex_debug_output; -static const char* mk3hook_fmodex_sound_device; +static const char *mk3hook_fmodex_sound_device; -FMOD_RESULT FMOD_System_Init(FMOD_SYSTEM *system, int maxchannels, FMOD_INITFLAGS flags, void *extradriverdata) +FMOD_RESULT FMOD_System_Init( + FMOD_SYSTEM *system, + int maxchannels, + FMOD_INITFLAGS flags, + void *extradriverdata) { - if (!mk3hook_fmodex_real_FMOD_System_Init) { - mk3hook_fmodex_real_FMOD_System_Init = (FMOD_System_Init_t) cnh_lib_get_func_addr("FMOD_System_Init"); - } + if (!mk3hook_fmodex_real_FMOD_System_Init) { + mk3hook_fmodex_real_FMOD_System_Init = + (FMOD_System_Init_t) cnh_lib_get_func_addr("FMOD_System_Init"); + } - FMOD_RESULT res; + FMOD_RESULT res; - unsigned int version; + unsigned int version; - res = FMOD_System_GetVersion(system, &version); + res = FMOD_System_GetVersion(system, &version); + + if (res != FMOD_OK) { + log_error( + "FMOD_System_GetVersion failed %d: %s", + res, + FMOD_ErrorString((FMOD_RESULT) res)); + return res; + } + + log_info( + "fmodex version: %d.%d.%d", + (version >> 16) & 0xFFFF, + (version >> 8) & 0xFF, + version & 0xFF); + + if (mk3hook_fmodex_debug_output) { + res = FMOD_Debug_SetLevel(FMOD_DEBUG_ALL); if (res != FMOD_OK) { - log_error("FMOD_System_GetVersion failed %d: %s", res, FMOD_ErrorString((FMOD_RESULT) res)); - return res; + log_error( + "FMOD_Debug_SetLevel failed %d: %s", + res, + FMOD_ErrorString((FMOD_RESULT) res)); + return res; } + } - log_info("fmodex version: %d.%d.%d", (version >> 16) & 0xFFFF, (version >> 8) & 0xFF, version & 0xFF); + res = FMOD_System_SetOutput(system, FMOD_OUTPUTTYPE_ALSA); - if (mk3hook_fmodex_debug_output) { - res = FMOD_Debug_SetLevel(FMOD_DEBUG_ALL); + if (res != FMOD_OK) { + log_error( + "FMOD_System_SetOutput failed %d: %s", + res, + FMOD_ErrorString((FMOD_RESULT) res)); + return res; + } - if (res != FMOD_OK) { - log_error("FMOD_Debug_SetLevel failed %d: %s", res, FMOD_ErrorString((FMOD_RESULT) res)); - return res; - } - } + FMOD_OUTPUTTYPE output_type; - res = FMOD_System_SetOutput(system, FMOD_OUTPUTTYPE_ALSA); + res = FMOD_System_GetOutput(system, &output_type); + + if (res != FMOD_OK) { + log_error( + "FMOD_System_GetOutput failed %d: %s", + res, + FMOD_ErrorString((FMOD_RESULT) res)); + return res; + } + + log_info("Output type: %d", output_type); + + int num_drivers; + res = FMOD_System_GetNumDrivers(system, &num_drivers); + + if (res != FMOD_OK) { + log_error( + "FMOD_System_GetNumDrivers failed %d: %s", + res, + FMOD_ErrorString((FMOD_RESULT) res)); + return res; + } + + log_info("Num available drivers %d", num_drivers); + + char buffer[4096]; + FMOD_GUID guid; + int selected_driver = -1; + + for (int i = 0; i < num_drivers; i++) { + res = FMOD_System_GetDriverInfo(system, i, buffer, sizeof(buffer), &guid); if (res != FMOD_OK) { - log_error("FMOD_System_SetOutput failed %d: %s", res, FMOD_ErrorString((FMOD_RESULT) res)); - return res; + log_error( + "FMOD_System_GetDriverInfo failed %d: %s", + res, + FMOD_ErrorString((FMOD_RESULT) res)); + break; } - FMOD_OUTPUTTYPE output_type; + log_info("Driver %d: %s", i, buffer); - res = FMOD_System_GetOutput(system, &output_type); - - if (res != FMOD_OK) { - log_error("FMOD_System_GetOutput failed %d: %s", res, FMOD_ErrorString((FMOD_RESULT) res)); - return res; + if (mk3hook_fmodex_sound_device && + !strcmp(buffer, mk3hook_fmodex_sound_device)) { + selected_driver = i; } + } - log_info("Output type: %d", output_type); + if (selected_driver == -1) { + log_info( + "Selecting default driver (0) because either the selected driver was " + "not found or no driver was " + "selected"); + selected_driver = 0; + } else { + log_info( + "Found selected driver %s, id %d", + mk3hook_fmodex_sound_device, + selected_driver); + } - int num_drivers; - res = FMOD_System_GetNumDrivers(system, &num_drivers); + res = FMOD_System_SetDriver(system, selected_driver); - if (res != FMOD_OK) { - log_error("FMOD_System_GetNumDrivers failed %d: %s", res, FMOD_ErrorString((FMOD_RESULT) res)); - return res; - } + if (res != FMOD_OK) { + log_error( + "FMOD_System_SetDriver failed %d: %s", + res, + FMOD_ErrorString((FMOD_RESULT) res)); + return res; + } - log_info("Num available drivers %d", num_drivers); + res = FMOD_System_SetSpeakerMode(system, FMOD_SPEAKERMODE_STEREO); - char buffer[4096]; - FMOD_GUID guid; - int selected_driver = -1; + if (res != FMOD_OK) { + log_error( + "FMOD_System_SetSpeakerMode failed %d: %s", + res, + FMOD_ErrorString((FMOD_RESULT) res)); + return res; + } - for (int i = 0; i < num_drivers; i++) { - res = FMOD_System_GetDriverInfo(system, i, buffer, sizeof(buffer), &guid); - - if (res != FMOD_OK) { - log_error("FMOD_System_GetDriverInfo failed %d: %s", res, FMOD_ErrorString((FMOD_RESULT) res)); - break; - } - - log_info("Driver %d: %s", i, buffer); - - if (mk3hook_fmodex_sound_device && !strcmp(buffer, mk3hook_fmodex_sound_device)) { - selected_driver = i; - } - } - - if (selected_driver == -1) { - log_info("Selecting default driver (0) because either the selected driver was not found or no driver was " - "selected"); - selected_driver = 0; - } else { - log_info("Found selected driver %s, id %d", mk3hook_fmodex_sound_device, selected_driver); - } - - res = FMOD_System_SetDriver(system, selected_driver); - - if (res != FMOD_OK) { - log_error("FMOD_System_SetDriver failed %d: %s", res, FMOD_ErrorString((FMOD_RESULT) res)); - return res; - } - - res = FMOD_System_SetSpeakerMode(system, FMOD_SPEAKERMODE_STEREO); - - if (res != FMOD_OK) { - log_error("FMOD_System_SetSpeakerMode failed %d: %s", res, FMOD_ErrorString((FMOD_RESULT) res)); - return res; - } - - return mk3hook_fmodex_real_FMOD_System_Init(system, maxchannels, flags, extradriverdata); + return mk3hook_fmodex_real_FMOD_System_Init( + system, maxchannels, flags, extradriverdata); } -void mk3hook_fmodex_init(bool debug_output, const char* sound_device) +void mk3hook_fmodex_init(bool debug_output, const char *sound_device) { - mk3hook_fmodex_debug_output = debug_output; - mk3hook_fmodex_sound_device = sound_device; + mk3hook_fmodex_debug_output = debug_output; + mk3hook_fmodex_sound_device = sound_device; - log_info("Initialized"); + log_info("Initialized"); } \ No newline at end of file diff --git a/src/main/hook/mk3/fmodex.h b/src/main/hook/mk3/fmodex.h index e623a5e..22a57a3 100644 --- a/src/main/hook/mk3/fmodex.h +++ b/src/main/hook/mk3/fmodex.h @@ -1,6 +1,6 @@ /** - * This patch module fixes a bunch of issues with fmodex which is used by the MK3 Linux ports to re-implement - * the sound hardware in software. + * This patch module fixes a bunch of issues with fmodex which is used by the + * MK3 Linux ports to re-implement the sound hardware in software. */ #ifndef MK3HOOK_FMODEX_H #define MK3HOOK_FMODEX_H @@ -10,10 +10,12 @@ /** * Initialize this patch module. * - * @param debug_output True to enable fmodex's debug output which requires the usage of fmodexL.so instead of fmodex.so. - * @param sound_device Provide a sound device to pick from the list of devices available with fmodex. NULL to go with - * with default device selected automatically by fmodex. + * @param debug_output True to enable fmodex's debug output which requires the + * usage of fmodexL.so instead of fmodex.so. + * @param sound_device Provide a sound device to pick from the list of devices + * available with fmodex. NULL to go with with default device selected + * automatically by fmodex. */ -void mk3hook_fmodex_init(bool debug_output, const char* sound_device); +void mk3hook_fmodex_init(bool debug_output, const char *sound_device); #endif diff --git a/src/main/hook/mk3/main.c b/src/main/hook/mk3/main.c index dbd4cc9..530be86 100644 --- a/src/main/hook/mk3/main.c +++ b/src/main/hook/mk3/main.c @@ -16,8 +16,8 @@ #include "hook/patch/asound-fix.h" #include "hook/patch/hook-mon.h" #include "hook/patch/main-loop.h" -#include "hook/patch/piuio.h" #include "hook/patch/piuio-exit.h" +#include "hook/patch/piuio.h" #include "hook/patch/redir.h" #include "hook/patch/sigsegv.h" #include "hook/patch/sound.h" @@ -31,219 +31,232 @@ #include "util/str.h" #include "util/sys-info.h" -static void mk3hook_bootstrapping(int argc, char** argv, struct mk3hook_options* options, char** game_data_path) +static void mk3hook_bootstrapping( + int argc, + char **argv, + struct mk3hook_options *options, + char **game_data_path) { - log_assert(argc >= 0); - log_assert(argv); - log_assert(options); - log_assert(game_data_path); + log_assert(argc >= 0); + log_assert(argv); + log_assert(options); + log_assert(game_data_path); - if (!mk3hook_options_init(argc, argv, options)) { - exit(0); - } + if (!mk3hook_options_init(argc, argv, options)) { + exit(0); + } - hook_core_piu_log_init(argc, argv); + hook_core_piu_log_init(argc, argv); - hook_core_piu_log_info(argc, argv); + hook_core_piu_log_info(argc, argv); - // Have different arguments to align with newer pump games - // argv[1]: game folder path - *game_data_path = hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); + // Have different arguments to align with newer pump games + // argv[1]: game folder path + *game_data_path = + hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); - hook_core_piu_utils_verify_root_user(); + hook_core_piu_utils_verify_root_user(); - log_info("Initializing, piu game data path: %s", *game_data_path); + log_info("Initializing, piu game data path: %s", *game_data_path); } -static void mk3hook_patch_config_init(struct mk3hook_options* options) +static void mk3hook_patch_config_init(struct mk3hook_options *options) { - mk3hook_config_init(options); + mk3hook_config_init(options); } -static void mk3hook_patch_fs_init(struct mk3hook_options* options) +static void mk3hook_patch_fs_init(struct mk3hook_options *options) { - log_assert(options); + log_assert(options); - patch_hook_mon_init( - options->patch.hook_mon.io, - options->patch.hook_mon.file, - options->patch.hook_mon.fs, - options->patch.hook_mon.usb, - options->patch.hook_mon.open); + patch_hook_mon_init( + options->patch.hook_mon.io, + options->patch.hook_mon.file, + options->patch.hook_mon.fs, + options->patch.hook_mon.usb, + options->patch.hook_mon.open); - patch_redir_init(); + patch_redir_init(); } -static void mk3hook_1st_2nd_fs_redirs(const char* game_data_path_abs) +static void mk3hook_1st_2nd_fs_redirs(const char *game_data_path_abs) { - log_assert(game_data_path_abs); + log_assert(game_data_path_abs); - // The "datas" directory does not require a redirect as the game uses chdir to move to that folder. For this, the - // additional patch module "1st-2nd-fs-fix" is required (see below). All files usually local to the piu executable, - // which are outside of the "datas" folder, have to be redirected. - cnh_redir_add("INTRO.ANI", util_str_merge(game_data_path_abs, "/INTRO.ANI")); - cnh_redir_add("intro.ani", util_str_merge(game_data_path_abs, "/INTRO.ANI")); - cnh_redir_add("spr.res", util_str_merge(game_data_path_abs, "/SPR.RES")); - cnh_redir_add("SPR.RES", util_str_merge(game_data_path_abs, "/SPR.RES")); - cnh_redir_add("piu.bin", util_str_merge(game_data_path_abs, "/PIU.BIN")); - cnh_redir_add("PIU.BIN", util_str_merge(game_data_path_abs, "/PIU.BIN")); - cnh_redir_add("stage.cfg", util_str_merge(game_data_path_abs, "/STAGE.CFG")); - cnh_redir_add("STAGE.CFG", util_str_merge(game_data_path_abs, "/STAGE.CFG")); + // The "datas" directory does not require a redirect as the game uses chdir to + // move to that folder. For this, the additional patch module "1st-2nd-fs-fix" + // is required (see below). All files usually local to the piu executable, + // which are outside of the "datas" folder, have to be redirected. + cnh_redir_add("INTRO.ANI", util_str_merge(game_data_path_abs, "/INTRO.ANI")); + cnh_redir_add("intro.ani", util_str_merge(game_data_path_abs, "/INTRO.ANI")); + cnh_redir_add("spr.res", util_str_merge(game_data_path_abs, "/SPR.RES")); + cnh_redir_add("SPR.RES", util_str_merge(game_data_path_abs, "/SPR.RES")); + cnh_redir_add("piu.bin", util_str_merge(game_data_path_abs, "/PIU.BIN")); + cnh_redir_add("PIU.BIN", util_str_merge(game_data_path_abs, "/PIU.BIN")); + cnh_redir_add("stage.cfg", util_str_merge(game_data_path_abs, "/STAGE.CFG")); + cnh_redir_add("STAGE.CFG", util_str_merge(game_data_path_abs, "/STAGE.CFG")); - // For redirecting additional files for linux ports. Configurable via MK3 linux ports config.cfg but causes stack - // overflow on long paths. Redirecting the paths afterwards is save. - cnh_redir_add("EFFECTS", util_str_merge(game_data_path_abs, "/EFFECTS/")); - cnh_redir_add("track", util_str_merge(game_data_path_abs, "/track/")); + // For redirecting additional files for linux ports. Configurable via MK3 + // linux ports config.cfg but causes stack overflow on long paths. Redirecting + // the paths afterwards is save. + cnh_redir_add("EFFECTS", util_str_merge(game_data_path_abs, "/EFFECTS/")); + cnh_redir_add("track", util_str_merge(game_data_path_abs, "/track/")); - mk3hook_1st_2nd_fs_fix_init(game_data_path_abs); + mk3hook_1st_2nd_fs_fix_init(game_data_path_abs); } -static void mk3hook_3rd_and_up_fs_redirs(const char* game_data_path_abs) +static void mk3hook_3rd_and_up_fs_redirs(const char *game_data_path_abs) { - log_assert(game_data_path_abs); + log_assert(game_data_path_abs); - // Sometimes, the game decides to read stuff using lower case, sometimes upper case *shrug* - // Also, we don't are about cleaning up the resulting merged strings here. Have some memory leaks! - cnh_redir_add(".", util_str_merge(game_data_path_abs, "/")); - cnh_redir_add("audio", util_str_merge(game_data_path_abs, "/AUDIO")); - cnh_redir_add("AUDIO", util_str_merge(game_data_path_abs, "/AUDIO")); - cnh_redir_add("bga", util_str_merge(game_data_path_abs, "/BGA")); - cnh_redir_add("BGA", util_str_merge(game_data_path_abs, "/BGA")); - cnh_redir_add("step", util_str_merge(game_data_path_abs, "/STEP")); - cnh_redir_add("STEP", util_str_merge(game_data_path_abs, "/STEP")); - cnh_redir_add("title", util_str_merge(game_data_path_abs, "/TITLE")); - cnh_redir_add("TITLE", util_str_merge(game_data_path_abs, "/TITLE")); - cnh_redir_add("piu.bin", util_str_merge(game_data_path_abs, "/PIU.BIN")); - cnh_redir_add("PIU.BIN", util_str_merge(game_data_path_abs, "/PIU.BIN")); - cnh_redir_add("stage.cfg", util_str_merge(game_data_path_abs, "/STAGE.CFG")); - cnh_redir_add("STAGE.CFG", util_str_merge(game_data_path_abs, "/STAGE.CFG")); - // Special treatment for extra because keeping the name stage.cfg was not good enough... - cnh_redir_add("game.cfg", util_str_merge(game_data_path_abs, "/GAME.CFG")); - cnh_redir_add("GAME.CFG", util_str_merge(game_data_path_abs, "/GAME.CFG")); + // Sometimes, the game decides to read stuff using lower case, sometimes upper + // case *shrug* Also, we don't are about cleaning up the resulting merged + // strings here. Have some memory leaks! + cnh_redir_add(".", util_str_merge(game_data_path_abs, "/")); + cnh_redir_add("audio", util_str_merge(game_data_path_abs, "/AUDIO")); + cnh_redir_add("AUDIO", util_str_merge(game_data_path_abs, "/AUDIO")); + cnh_redir_add("bga", util_str_merge(game_data_path_abs, "/BGA")); + cnh_redir_add("BGA", util_str_merge(game_data_path_abs, "/BGA")); + cnh_redir_add("step", util_str_merge(game_data_path_abs, "/STEP")); + cnh_redir_add("STEP", util_str_merge(game_data_path_abs, "/STEP")); + cnh_redir_add("title", util_str_merge(game_data_path_abs, "/TITLE")); + cnh_redir_add("TITLE", util_str_merge(game_data_path_abs, "/TITLE")); + cnh_redir_add("piu.bin", util_str_merge(game_data_path_abs, "/PIU.BIN")); + cnh_redir_add("PIU.BIN", util_str_merge(game_data_path_abs, "/PIU.BIN")); + cnh_redir_add("stage.cfg", util_str_merge(game_data_path_abs, "/STAGE.CFG")); + cnh_redir_add("STAGE.CFG", util_str_merge(game_data_path_abs, "/STAGE.CFG")); + // Special treatment for extra because keeping the name stage.cfg was not good + // enough... + cnh_redir_add("game.cfg", util_str_merge(game_data_path_abs, "/GAME.CFG")); + cnh_redir_add("GAME.CFG", util_str_merge(game_data_path_abs, "/GAME.CFG")); - // For redirecting additional files for linux ports. Configurable via MK3 linux ports config.cfg but causes stack - // overflow on long paths. Redirecting the paths afterwards is save. - cnh_redir_add("EFFECTS", util_str_merge(game_data_path_abs, "/EFFECTS/")); - cnh_redir_add("track", util_str_merge(game_data_path_abs, "/track/")); + // For redirecting additional files for linux ports. Configurable via MK3 + // linux ports config.cfg but causes stack overflow on long paths. Redirecting + // the paths afterwards is save. + cnh_redir_add("EFFECTS", util_str_merge(game_data_path_abs, "/EFFECTS/")); + cnh_redir_add("track", util_str_merge(game_data_path_abs, "/track/")); } -static void mk3hook_patch_1st_and_2nd_fs_init(struct mk3hook_options* options, const char* game_data_path) +static void mk3hook_patch_1st_and_2nd_fs_init( + struct mk3hook_options *options, const char *game_data_path) { - log_assert(options); - log_assert(game_data_path); + log_assert(options); + log_assert(game_data_path); - char* game_data_path_abs = util_fs_get_abs_path(game_data_path); + char *game_data_path_abs = util_fs_get_abs_path(game_data_path); - if (options->game.fs_1st_2nd) { - mk3hook_1st_2nd_fs_redirs(game_data_path_abs); - } else { - mk3hook_3rd_and_up_fs_redirs(game_data_path_abs); - } + if (options->game.fs_1st_2nd) { + mk3hook_1st_2nd_fs_redirs(game_data_path_abs); + } else { + mk3hook_3rd_and_up_fs_redirs(game_data_path_abs); + } - free(game_data_path_abs); + free(game_data_path_abs); } -static void mk3hook_patch_main_loop_init(struct mk3hook_options* options) +static void mk3hook_patch_main_loop_init(struct mk3hook_options *options) { - log_assert(options); + log_assert(options); - patch_main_loop_init(true, options->patch.main_loop.disable_built_in_inputs, true); + patch_main_loop_init( + true, options->patch.main_loop.disable_built_in_inputs, true); - if (options->patch.main_loop.x11_input_handler_api_lib) { - char* abs_path_x11_input_hook_lib = util_fs_get_abs_path(options->patch.main_loop.x11_input_handler_api_lib); + if (options->patch.main_loop.x11_input_handler_api_lib) { + char *abs_path_x11_input_hook_lib = util_fs_get_abs_path( + options->patch.main_loop.x11_input_handler_api_lib); - patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); - free(abs_path_x11_input_hook_lib); - } + patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); + free(abs_path_x11_input_hook_lib); + } } -static void mk3hook_patch_sound_init(struct mk3hook_options* options) +static void mk3hook_patch_sound_init(struct mk3hook_options *options) { - log_assert(options); + log_assert(options); - patch_asound_fix_init(); - mk3hook_fmodex_init(options->patch.sound.debug_output, options->patch.sound.device); + patch_asound_fix_init(); + mk3hook_fmodex_init( + options->patch.sound.debug_output, options->patch.sound.device); } -static void mk3hook_patch_sigsegv_init(struct mk3hook_options* options) +static void mk3hook_patch_sigsegv_init(struct mk3hook_options *options) { - log_assert(options); + log_assert(options); - patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); + patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); } -static void mk3hook_patch_piuio_init(struct mk3hook_options* options) +static void mk3hook_patch_piuio_init(struct mk3hook_options *options) { - log_assert(options); + log_assert(options); - /* Hook before IO emulation */ - if (options->patch.piuio.exit_test_serv) { - patch_piuio_exit_init(); - } + /* Hook before IO emulation */ + if (options->patch.piuio.exit_test_serv) { + patch_piuio_exit_init(); + } - patch_usb_emu_init(); + patch_usb_emu_init(); - if (options->patch.piuio.api_lib) { - char* abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); + if (options->patch.piuio.api_lib) { + char *abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); - patch_piuio_init(abs_path_iolib); - free(abs_path_iolib); - } + patch_piuio_init(abs_path_iolib); + free(abs_path_iolib); + } } -static void mk3hook_fix_argv(int argc, char** argv) +static void mk3hook_fix_argv(int argc, char **argv) { - log_assert(argc >= 0); - log_assert(argv); + log_assert(argc >= 0); + log_assert(argv); - // Game exec main expects the following arguments - // argv[1]: cfg1 path - // argv[2]: cfg2 path (optional) - // Config loading is stubbed, so just provide something + // Game exec main expects the following arguments + // argv[1]: cfg1 path + // argv[2]: cfg2 path (optional) + // Config loading is stubbed, so just provide something - argv[1] = "./save/config.cfg"; + argv[1] = "./save/config.cfg"; - if (argc > 2) { - argv[2] = "./save/config.cfg"; - } + if (argc > 2) { + argv[2] = "./save/config.cfg"; + } } void mk3hook_constructor(void) { - /* Nothing here */ + /* Nothing here */ } void mk3hook_destructor(void) { - /* Nothing here */ + /* Nothing here */ } -void mk3hook_trap_before_main(int argc, char** argv) +void mk3hook_trap_before_main(int argc, char **argv) { - log_assert(argc >= 0); - log_assert(argv); + log_assert(argc >= 0); + log_assert(argv); - struct mk3hook_options options; - char* game_data_path; + struct mk3hook_options options; + char *game_data_path; - mk3hook_bootstrapping(argc, argv, &options, &game_data_path); - mk3hook_patch_config_init(&options); - mk3hook_patch_fs_init(&options); - mk3hook_patch_1st_and_2nd_fs_init(&options, game_data_path); - mk3hook_patch_main_loop_init(&options); - mk3hook_patch_sound_init(&options); - mk3hook_patch_sigsegv_init(&options); - mk3hook_patch_piuio_init(&options); - mk3hook_fix_argv(argc, argv); + mk3hook_bootstrapping(argc, argv, &options, &game_data_path); + mk3hook_patch_config_init(&options); + mk3hook_patch_fs_init(&options); + mk3hook_patch_1st_and_2nd_fs_init(&options, game_data_path); + mk3hook_patch_main_loop_init(&options); + mk3hook_patch_sound_init(&options); + mk3hook_patch_sigsegv_init(&options); + mk3hook_patch_piuio_init(&options); + mk3hook_fix_argv(argc, argv); - free(game_data_path); + free(game_data_path); - log_info("Hooking finished"); + log_info("Hooking finished"); } void mk3hook_trap_after_main(void) { - } LIB_MAIN_CONSTRUCTOR(mk3hook_constructor); diff --git a/src/main/hook/mk3/ogl-fix.c b/src/main/hook/mk3/ogl-fix.c index ec03789..349bac5 100644 --- a/src/main/hook/mk3/ogl-fix.c +++ b/src/main/hook/mk3/ogl-fix.c @@ -2,10 +2,12 @@ * Module to fix weird OpenGL error that only appears on all MK3 linux ports. * * If OpenGL is not forced into single threaded mode, the backend will run in - * multi-threaded mode for some reason and crash in __glDispatchCheckMultithreaded - * when the game calls glXChooseVisual in its GFX init function. + * multi-threaded mode for some reason and crash in + * __glDispatchCheckMultithreaded when the game calls glXChooseVisual in its GFX + * init function. * - * The fix is quite simple (luckily) by just setting the environment variable __GL_SINGLETHREADED. + * The fix is quite simple (luckily) by just setting the environment variable + * __GL_SINGLETHREADED. */ #include @@ -13,25 +15,27 @@ #include "capnhook/hook/lib.h" -typedef char* (*getenv_t) (const char* name); +typedef char *(*getenv_t)(const char *name); static getenv_t _mk3hook_ogl_fix_real_getenv; -char* getenv(const char* name) +char *getenv(const char *name) { - if (!_mk3hook_ogl_fix_real_getenv) { - _mk3hook_ogl_fix_real_getenv = (getenv_t) cnh_lib_get_func_addr("getenv"); + if (!_mk3hook_ogl_fix_real_getenv) { + _mk3hook_ogl_fix_real_getenv = (getenv_t) cnh_lib_get_func_addr("getenv"); + } + + char *ret = _mk3hook_ogl_fix_real_getenv(name); + + if (!strcmp(name, "__GL_SINGLETHREADED")) { + if (ret == NULL || strcmp(name, "1") != 0) { + printf( + "!!! mk3hook: __GL_SINGLETHREADED not set or enabled, force patching " + "OpenGL to single " + "threaded to avoid crash !!!\n"); + return "1"; } + } - char* ret = _mk3hook_ogl_fix_real_getenv(name); - - if (!strcmp(name, "__GL_SINGLETHREADED")) { - if (ret == NULL || strcmp(name, "1") != 0) { - printf("!!! mk3hook: __GL_SINGLETHREADED not set or enabled, force patching OpenGL to single " - "threaded to avoid crash !!!\n"); - return "1"; - } - } - - return ret; + return ret; } \ No newline at end of file diff --git a/src/main/hook/mk3/options.c b/src/main/hook/mk3/options.c index a7f0892..0ee3a24 100644 --- a/src/main/hook/mk3/options.c +++ b/src/main/hook/mk3/options.c @@ -14,13 +14,17 @@ #define MK3HOOK_OPTIONS_STR_PATCH_HOOK_MON_IO "patch.hook_mon.io" #define MK3HOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN "patch.hook_mon.open" #define MK3HOOK_OPTIONS_STR_PATCH_HOOK_MON_USB "patch.hook_mon.usb" -#define MK3HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS "patch.hook_main_loop.disable_built_in_inputs" -#define MK3HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER "patch_hook_main_loop.x11_input_handler" +#define MK3HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS \ + "patch.hook_main_loop.disable_built_in_inputs" +#define MK3HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER \ + "patch_hook_main_loop.x11_input_handler" #define MK3HOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB "patch.piuio.emu_lib" -#define MK3HOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV "patch.piuio_exit.test_serv" +#define MK3HOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV \ + "patch.piuio_exit.test_serv" #define MK3HOOK_OPTIONS_STR_PATCH_SOUND_DEVICE "patch.sound.device" #define MK3HOOK_OPTIONS_STR_PATCH_SOUND_DEBUG_OUTPUT "patch.sound.debug_output" -#define MK3HOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV "patch.sigsegv.halt_on_segv" +#define MK3HOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV \ + "patch.sigsegv.halt_on_segv" #define MK3HOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE "util.log.file" #define MK3HOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL "util.log.level" @@ -62,8 +66,10 @@ static const struct util_options_def mk3hook_options_def[] = { }, { .name = MK3HOOK_OPTIONS_STR_GAME_1ST_2ND_FS, - .description = "Enable this option when running 1st or 2nd. This uses different file system redirects for the " - "game directory as well as enables a fix. Without this, the game throws errors about not finding files", + .description = "Enable this option when running 1st or 2nd. This uses " + "different file system redirects for the " + "game directory as well as enables a fix. Without this, " + "the game throws errors about not finding files", .param = 'x', .type = UTIL_OPTIONS_TYPE_BOOL, .default_value.b = false, @@ -111,22 +117,26 @@ static const struct util_options_def mk3hook_options_def[] = { .default_value.b = false, }, { - .name = MK3HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS, - .description = "Disable the built in keyboard inputs for test (F1), service (F2) and clear (F3)", + .name = + MK3HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS, + .description = "Disable the built in keyboard inputs for test (F1), " + "service (F2) and clear (F3)", .param = 'k', .type = UTIL_OPTIONS_TYPE_BOOL, .default_value.b = false, }, { .name = MK3HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER, - .description = "Path to a library implementing the x11-input-handler api to capture X11 keyboard inputs", + .description = "Path to a library implementing the x11-input-handler " + "api to capture X11 keyboard inputs", .param = 'q', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, }, { .name = MK3HOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB, - .description = "Path to library implementing the piuio api for piuio emulation", + .description = + "Path to library implementing the piuio api for piuio emulation", .param = 'p', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, @@ -147,8 +157,9 @@ static const struct util_options_def mk3hook_options_def[] = { }, { .name = MK3HOOK_OPTIONS_STR_PATCH_SOUND_DEBUG_OUTPUT, - .description = "Enable debug output for the fmod library. This requires you to use the fmodexL.so instead of " - "the standard fmodex.so", + .description = "Enable debug output for the fmod library. This " + "requires you to use the fmodexL.so instead of " + "the standard fmodex.so", .param = 'r', .type = UTIL_OPTIONS_TYPE_BOOL, .default_value.b = false, @@ -185,46 +196,64 @@ static const struct util_options_defs mk3hook_options_defs = { .ndefs = lengthof(mk3hook_options_def) }; -bool mk3hook_options_init(int argc, char** argv, struct mk3hook_options* options) +bool mk3hook_options_init( + int argc, char **argv, struct mk3hook_options *options) { - log_assert(argv); - log_assert(options); + log_assert(argv); + log_assert(options); - struct util_options_opts* options_opt; + struct util_options_opts *options_opt; - util_options_init(argc, argv); - options_opt = util_options_get(&mk3hook_options_defs); + util_options_init(argc, argv); + options_opt = util_options_get(&mk3hook_options_defs); - if (!options_opt) { - return false; - } + if (!options_opt) { + return false; + } - options->game.settings = util_options_get_str(options_opt, MK3HOOK_OPTIONS_STR_GAME_SETTINGS); - options->game.sync_offset = util_options_get_int(options_opt, MK3HOOK_OPTIONS_STR_GAME_SYNC_OFFSET); - options->game.sync_multiplier = util_options_get_double(options_opt, MK3HOOK_OPTIONS_STR_GAME_SYNC_MULTIPLIER); - options->game.music_vol = util_options_get_double(options_opt, MK3HOOK_OPTIONS_STR_GAME_MUSIC_VOL); - options->game.sfx_vol = util_options_get_double(options_opt, MK3HOOK_OPTIONS_STR_GAME_SFX_VOL); - options->game.fs_1st_2nd = util_options_get_bool(options_opt, MK3HOOK_OPTIONS_STR_GAME_1ST_2ND_FS); - options->patch.gfx.windowed = util_options_get_bool(options_opt, MK3HOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); - options->patch.hook_mon.file = util_options_get_bool(options_opt, MK3HOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); - options->patch.hook_mon.fs = util_options_get_bool(options_opt, MK3HOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); - options->patch.hook_mon.io = util_options_get_bool(options_opt, MK3HOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); - options->patch.hook_mon.open = util_options_get_bool(options_opt, MK3HOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); - options->patch.hook_mon.usb = util_options_get_bool(options_opt, MK3HOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); - options->patch.main_loop.disable_built_in_inputs = util_options_get_bool(options_opt, - MK3HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); - options->patch.main_loop.x11_input_handler_api_lib = - util_options_get_str(options_opt, MK3HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); - options->patch.piuio.api_lib = util_options_get_str(options_opt, MK3HOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); - options->patch.piuio.exit_test_serv = - util_options_get_bool(options_opt, MK3HOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); - options->patch.sound.device = util_options_get_str(options_opt, MK3HOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); - options->patch.sound.debug_output = util_options_get_bool(options_opt, MK3HOOK_OPTIONS_STR_PATCH_SOUND_DEBUG_OUTPUT); - options->patch.sigsegv.halt_on_segv = - util_options_get_bool(options_opt, MK3HOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); - options->log.file = util_options_get_str(options_opt, MK3HOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); - options->log.level = - (enum util_log_level) util_options_get_int(options_opt, MK3HOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); + options->game.settings = + util_options_get_str(options_opt, MK3HOOK_OPTIONS_STR_GAME_SETTINGS); + options->game.sync_offset = + util_options_get_int(options_opt, MK3HOOK_OPTIONS_STR_GAME_SYNC_OFFSET); + options->game.sync_multiplier = util_options_get_double( + options_opt, MK3HOOK_OPTIONS_STR_GAME_SYNC_MULTIPLIER); + options->game.music_vol = + util_options_get_double(options_opt, MK3HOOK_OPTIONS_STR_GAME_MUSIC_VOL); + options->game.sfx_vol = + util_options_get_double(options_opt, MK3HOOK_OPTIONS_STR_GAME_SFX_VOL); + options->game.fs_1st_2nd = + util_options_get_bool(options_opt, MK3HOOK_OPTIONS_STR_GAME_1ST_2ND_FS); + options->patch.gfx.windowed = util_options_get_bool( + options_opt, MK3HOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); + options->patch.hook_mon.file = util_options_get_bool( + options_opt, MK3HOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); + options->patch.hook_mon.fs = + util_options_get_bool(options_opt, MK3HOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); + options->patch.hook_mon.io = + util_options_get_bool(options_opt, MK3HOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); + options->patch.hook_mon.open = util_options_get_bool( + options_opt, MK3HOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); + options->patch.hook_mon.usb = util_options_get_bool( + options_opt, MK3HOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); + options->patch.main_loop.disable_built_in_inputs = util_options_get_bool( + options_opt, + MK3HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); + options->patch.main_loop.x11_input_handler_api_lib = util_options_get_str( + options_opt, MK3HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); + options->patch.piuio.api_lib = util_options_get_str( + options_opt, MK3HOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); + options->patch.piuio.exit_test_serv = util_options_get_bool( + options_opt, MK3HOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); + options->patch.sound.device = + util_options_get_str(options_opt, MK3HOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); + options->patch.sound.debug_output = util_options_get_bool( + options_opt, MK3HOOK_OPTIONS_STR_PATCH_SOUND_DEBUG_OUTPUT); + options->patch.sigsegv.halt_on_segv = util_options_get_bool( + options_opt, MK3HOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); + options->log.file = util_options_get_str( + options_opt, MK3HOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); + options->log.level = (enum util_log_level) util_options_get_int( + options_opt, MK3HOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); - return true; + return true; } \ No newline at end of file diff --git a/src/main/hook/mk3/options.h b/src/main/hook/mk3/options.h index ead48f5..d1d34db 100644 --- a/src/main/hook/mk3/options.h +++ b/src/main/hook/mk3/options.h @@ -7,54 +7,55 @@ #include "util/log.h" struct mk3hook_options { - struct game { - const char* settings; - int32_t sync_offset; - double sync_multiplier; - double music_vol; - double sfx_vol; - bool fs_1st_2nd; - } game; + struct game { + const char *settings; + int32_t sync_offset; + double sync_multiplier; + double music_vol; + double sfx_vol; + bool fs_1st_2nd; + } game; - struct patch { - struct gfx { - bool windowed; - } gfx; + struct patch { + struct gfx { + bool windowed; + } gfx; - struct hook_mon { - bool file; - bool fs; - bool io; - bool open; - bool usb; - } hook_mon; + struct hook_mon { + bool file; + bool fs; + bool io; + bool open; + bool usb; + } hook_mon; - struct main_loop { - bool disable_built_in_inputs; - const char* x11_input_handler_api_lib; - } main_loop; + struct main_loop { + bool disable_built_in_inputs; + const char *x11_input_handler_api_lib; + } main_loop; - struct piuio { - const char* api_lib; - bool exit_test_serv; - } piuio; + struct piuio { + const char *api_lib; + bool exit_test_serv; + } piuio; - struct sound { - const char* device; - bool debug_output; - } sound; + struct sound { + const char *device; + bool debug_output; + } sound; - struct sigsegv { - bool halt_on_segv; - } sigsegv; - } patch; + struct sigsegv { + bool halt_on_segv; + } sigsegv; + } patch; - struct log { - const char* file; - enum util_log_level level; - } log; + struct log { + const char *file; + enum util_log_level level; + } log; }; -bool mk3hook_options_init(int argc, char** argv, struct mk3hook_options* options); +bool mk3hook_options_init( + int argc, char **argv, struct mk3hook_options *options); #endif diff --git a/src/main/hook/nx/main.c b/src/main/hook/nx/main.c index 70aa7a0..ae35b0e 100644 --- a/src/main/hook/nx/main.c +++ b/src/main/hook/nx/main.c @@ -15,8 +15,8 @@ #include "hook/patch/hook-mon.h" #include "hook/patch/main-loop.h" #include "hook/patch/microdog34.h" -#include "hook/patch/piuio.h" #include "hook/patch/piuio-exit.h" +#include "hook/patch/piuio.h" #include "hook/patch/redir.h" #include "hook/patch/sigsegv.h" #include "hook/patch/sound.h" @@ -37,234 +37,249 @@ extern const uint8_t _binary_nxhook_hdd_raw_end[]; extern const uint8_t _binary_nxhook_dog_key_start[]; extern const uint8_t _binary_nxhook_dog_key_end[]; -static void nxhook_bootstrapping(int argc, char** argv, struct nxhook_options* options, char** game_data_path) +static void nxhook_bootstrapping( + int argc, + char **argv, + struct nxhook_options *options, + char **game_data_path) { - log_assert(argc >= 0); - log_assert(argv); - log_assert(options); - log_assert(game_data_path); + log_assert(argc >= 0); + log_assert(argv); + log_assert(options); + log_assert(game_data_path); - if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { - return; + if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { + return; + } + + hook_core_piu_log_init(argc, argv); + + if (!nxhook_options_init(argc, argv, options)) { + exit(0); + } + + hook_core_piu_log_info(argc, argv); + + *game_data_path = + hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); + + hook_core_piu_utils_verify_root_user(); + + log_info("Initializing, piu game data path: %s", *game_data_path); +} + +static void nxhook_patch_fs_init(struct nxhook_options *options) +{ + log_assert(options); + + patch_hook_mon_init( + options->patch.hook_mon.io, + options->patch.hook_mon.file, + options->patch.hook_mon.fs, + options->patch.hook_mon.usb, + options->patch.hook_mon.open); + + patch_redir_init(); +} + +static void nxhook_fs_redir_settings(struct nxhook_options *options) +{ + log_assert(options); + + if (options->game.settings) { + if (!util_fs_path_exists(options->game.settings)) { + log_info( + "Settings path %s does not exist, creating", options->game.settings); + + if (!util_fs_mkdir(options->game.settings)) { + log_error("Creating directory %s failed", options->game.settings); + } } - hook_core_piu_log_init(argc, argv); + char *abs_path = util_fs_get_abs_path(options->game.settings); - if (!nxhook_options_init(argc, argv, options)) { - exit(0); - } - - hook_core_piu_log_info(argc, argv); - - *game_data_path = hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); - - hook_core_piu_utils_verify_root_user(); - - log_info("Initializing, piu game data path: %s", *game_data_path); + cnh_redir_add("/SETTINGS", abs_path); + free(abs_path); + } else { + log_warn("No settings path specified"); + } } -static void nxhook_patch_fs_init(struct nxhook_options* options) +static void nxhook_fs_redir_script( + struct nxhook_options *options, const char *game_data_path) { - log_assert(options); + log_assert(options); + log_assert(game_data_path); - patch_hook_mon_init( - options->patch.hook_mon.io, - options->patch.hook_mon.file, - options->patch.hook_mon.fs, - options->patch.hook_mon.usb, - options->patch.hook_mon.open); + char *path_tmp; - patch_redir_init(); + path_tmp = util_str_merge(game_data_path, "/SCRIPT"); + cnh_redir_add("/SCRIPT", path_tmp); + free(path_tmp); } -static void nxhook_fs_redir_settings(struct nxhook_options* options) +static void nxhook_fs_redir_fonts( + struct nxhook_options *options, const char *game_data_path) { - log_assert(options); + log_assert(options); + log_assert(game_data_path); - if (options->game.settings) { - if (!util_fs_path_exists(options->game.settings)) { - log_info("Settings path %s does not exist, creating", options->game.settings); + char *path_tmp; - if (!util_fs_mkdir(options->game.settings)) { - log_error("Creating directory %s failed", options->game.settings); - } - } + path_tmp = util_str_merge(game_data_path, "/MICROGBE.TTF"); + cnh_redir_add("MICROGBE.TTF", path_tmp); + free(path_tmp); - char* abs_path = util_fs_get_abs_path(options->game.settings); - - cnh_redir_add("/SETTINGS", abs_path); - free(abs_path); - } else { - log_warn("No settings path specified"); - } -} - -static void nxhook_fs_redir_script(struct nxhook_options* options, const char* game_data_path) -{ - log_assert(options); - log_assert(game_data_path); - - char* path_tmp; - - path_tmp = util_str_merge(game_data_path, "/SCRIPT"); - cnh_redir_add("/SCRIPT", path_tmp); - free(path_tmp); -} - -static void nxhook_fs_redir_fonts(struct nxhook_options* options, const char* game_data_path) -{ - log_assert(options); - log_assert(game_data_path); - - char* path_tmp; - - path_tmp = util_str_merge(game_data_path, "/MICROGBE.TTF"); - cnh_redir_add("MICROGBE.TTF", path_tmp); - free(path_tmp); - - path_tmp = util_str_merge(game_data_path, "/NXTW.TTF"); - cnh_redir_add("NXTW.TTF", path_tmp); - free(path_tmp); + path_tmp = util_str_merge(game_data_path, "/NXTW.TTF"); + cnh_redir_add("NXTW.TTF", path_tmp); + free(path_tmp); } static void nxhook_fs_redir_usb() { - /* Needed on newer kernels */ - cnh_redir_add("/proc/bus/usb/devices", "/sys/kernel/debug/usb/devices"); + /* Needed on newer kernels */ + cnh_redir_add("/proc/bus/usb/devices", "/sys/kernel/debug/usb/devices"); } -static void nxhook_fs_redirs_init(struct nxhook_options* options, const char* game_data_path) +static void nxhook_fs_redirs_init( + struct nxhook_options *options, const char *game_data_path) { - log_assert(options); - log_assert(game_data_path); + log_assert(options); + log_assert(game_data_path); - /* Expecting all assets in the piu game (asset) folder. redirects for files - that are not in there by default for reasons */ - nxhook_fs_redir_settings(options); - nxhook_fs_redir_script(options, game_data_path); - nxhook_fs_redir_fonts(options, game_data_path); + /* Expecting all assets in the piu game (asset) folder. redirects for files + that are not in there by default for reasons */ + nxhook_fs_redir_settings(options); + nxhook_fs_redir_script(options, game_data_path); + nxhook_fs_redir_fonts(options, game_data_path); - nxhook_fs_redir_usb(); + nxhook_fs_redir_usb(); } -static void nxhook_patch_gfx_init(struct nxhook_options* options) +static void nxhook_patch_gfx_init(struct nxhook_options *options) { - log_assert(options); + log_assert(options); - patch_gfx_init(); + patch_gfx_init(); - if (options->patch.gfx.windowed) { - patch_gfx_force_window_mode(); - } + if (options->patch.gfx.windowed) { + patch_gfx_force_window_mode(); + } } -static void nxhook_patch_game_init(struct nxhook_options* options) +static void nxhook_patch_game_init(struct nxhook_options *options) { - log_assert(options); + log_assert(options); - if (options->game.force_unlock) { - hook_nx_unlock_init(); - } + if (options->game.force_unlock) { + hook_nx_unlock_init(); + } } -static void nxhook_patch_main_loop_init(struct nxhook_options* options) +static void nxhook_patch_main_loop_init(struct nxhook_options *options) { - log_assert(options); + log_assert(options); - patch_main_loop_init(true, options->patch.main_loop.disable_built_in_inputs, false); + patch_main_loop_init( + true, options->patch.main_loop.disable_built_in_inputs, false); - if (options->patch.main_loop.x11_input_handler_api_lib) { - char* abs_path_x11_input_hook_lib = util_fs_get_abs_path(options->patch.main_loop.x11_input_handler_api_lib); + if (options->patch.main_loop.x11_input_handler_api_lib) { + char *abs_path_x11_input_hook_lib = util_fs_get_abs_path( + options->patch.main_loop.x11_input_handler_api_lib); - patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); - free(abs_path_x11_input_hook_lib); - } + patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); + free(abs_path_x11_input_hook_lib); + } } -static void nxhook_patch_sound_init(struct nxhook_options* options) +static void nxhook_patch_sound_init(struct nxhook_options *options) { - log_assert(options); + log_assert(options); - patch_sound_init(options->patch.sound.device); + patch_sound_init(options->patch.sound.device); } -static void nxhook_patch_sigsegv_init(struct nxhook_options* options) +static void nxhook_patch_sigsegv_init(struct nxhook_options *options) { - log_assert(options); + log_assert(options); - patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); + patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); } static void nxhook_patch_dongle_init() { - patch_microdog34_init((const uint8_t*) _binary_nxhook_dog_key_start, - ((uintptr_t) &_binary_nxhook_dog_key_end - (uintptr_t) &_binary_nxhook_dog_key_start)); + patch_microdog34_init( + (const uint8_t *) _binary_nxhook_dog_key_start, + ((uintptr_t) &_binary_nxhook_dog_key_end - + (uintptr_t) &_binary_nxhook_dog_key_start)); } static void nxhook_patch_hdd_check_init() { - patch_hdd_check_init((const uint8_t*) _binary_nxhook_hdd_raw_start, - ((uintptr_t) &_binary_nxhook_hdd_raw_end - (uintptr_t) &_binary_nxhook_hdd_raw_start)); + patch_hdd_check_init( + (const uint8_t *) _binary_nxhook_hdd_raw_start, + ((uintptr_t) &_binary_nxhook_hdd_raw_end - + (uintptr_t) &_binary_nxhook_hdd_raw_start)); } -static void nxhook_patch_piuio_init(struct nxhook_options* options) +static void nxhook_patch_piuio_init(struct nxhook_options *options) { - log_assert(options); + log_assert(options); - /* Hook before IO emulation */ - if (options->patch.piuio.exit_test_serv) { - patch_piuio_exit_init(); - } + /* Hook before IO emulation */ + if (options->patch.piuio.exit_test_serv) { + patch_piuio_exit_init(); + } - patch_usb_init_fix_init(); - patch_usb_emu_init(); + patch_usb_init_fix_init(); + patch_usb_emu_init(); - if (options->patch.piuio.api_lib) { - char* abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); + if (options->patch.piuio.api_lib) { + char *abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); - patch_piuio_init(abs_path_iolib); - free(abs_path_iolib); - } + patch_piuio_init(abs_path_iolib); + free(abs_path_iolib); + } } void nxhook_constructor(void) { - /* Nothing here */ + /* Nothing here */ } void nxhook_destructor(void) { - /* Nothing here */ + /* Nothing here */ } -void nxhook_trap_before_main(int argc, char** argv) +void nxhook_trap_before_main(int argc, char **argv) { - log_assert(argc >= 0); - log_assert(argv); + log_assert(argc >= 0); + log_assert(argv); - char* game_data_path; - struct nxhook_options options; + char *game_data_path; + struct nxhook_options options; - nxhook_bootstrapping(argc, argv, &options, &game_data_path); - nxhook_patch_fs_init(&options); - nxhook_fs_redirs_init(&options, game_data_path); - nxhook_patch_gfx_init(&options); - nxhook_patch_game_init(&options); - nxhook_patch_main_loop_init(&options); - nxhook_patch_sound_init(&options); - nxhook_patch_sigsegv_init(&options); - nxhook_patch_dongle_init(); - nxhook_patch_hdd_check_init(); - nxhook_patch_piuio_init(&options); + nxhook_bootstrapping(argc, argv, &options, &game_data_path); + nxhook_patch_fs_init(&options); + nxhook_fs_redirs_init(&options, game_data_path); + nxhook_patch_gfx_init(&options); + nxhook_patch_game_init(&options); + nxhook_patch_main_loop_init(&options); + nxhook_patch_sound_init(&options); + nxhook_patch_sigsegv_init(&options); + nxhook_patch_dongle_init(); + nxhook_patch_hdd_check_init(); + nxhook_patch_piuio_init(&options); - free(game_data_path); + free(game_data_path); - log_info("Hooking finished"); + log_info("Hooking finished"); } void nxhook_trap_after_main(void) { - patch_piuio_shutdown(); + patch_piuio_shutdown(); } LIB_MAIN_CONSTRUCTOR(nxhook_constructor); diff --git a/src/main/hook/nx/options.c b/src/main/hook/nx/options.c index e365210..a591165 100644 --- a/src/main/hook/nx/options.c +++ b/src/main/hook/nx/options.c @@ -10,19 +10,24 @@ #define NXHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO "patch.hook_mon.io" #define NXHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN "patch.hook_mon.open" #define NXHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB "patch.hook_mon.usb" -#define NXHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS "patch.hook_main_loop.disable_built_in_inputs" -#define NXHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER "patch_hook_main_loop.x11_input_handler" +#define NXHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS \ + "patch.hook_main_loop.disable_built_in_inputs" +#define NXHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER \ + "patch_hook_main_loop.x11_input_handler" #define NXHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB "patch.piuio.emu_lib" -#define NXHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV "patch.piuio_exit.test_serv" +#define NXHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV \ + "patch.piuio_exit.test_serv" #define NXHOOK_OPTIONS_STR_PATCH_SOUND_DEVICE "patch.sound.device" -#define NXHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV "patch.sigsegv.halt_on_segv" +#define NXHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV \ + "patch.sigsegv.halt_on_segv" #define NXHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE "util.log.file" #define NXHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL "util.log.level" static const struct util_options_def nxhook_options_def[] = { { .name = NXHOOK_OPTIONS_STR_GAME_FORCE_UNLOCK, - .description = "Force unlock the game. Modifies the current and any new PIUNX.INI settings file permanently", + .description = "Force unlock the game. Modifies the current and any " + "new PIUNX.INI settings file permanently", .param = 'z', .type = UTIL_OPTIONS_TYPE_BOOL, .default_value.b = false, @@ -78,21 +83,24 @@ static const struct util_options_def nxhook_options_def[] = { }, { .name = NXHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS, - .description = "Disable the built in keyboard inputs for test (F1), service (F2) and clear (F3)", + .description = "Disable the built in keyboard inputs for test (F1), " + "service (F2) and clear (F3)", .param = 'k', .type = UTIL_OPTIONS_TYPE_BOOL, .default_value.b = false, }, { .name = NXHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER, - .description = "Path to a library implementing the x11-input-handler api to capture X11 keyboard inputs", + .description = "Path to a library implementing the x11-input-handler " + "api to capture X11 keyboard inputs", .param = 'q', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, }, { .name = NXHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB, - .description = "Path to library implementing the piuio api for piuio emulation", + .description = + "Path to library implementing the piuio api for piuio emulation", .param = 'p', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, @@ -143,41 +151,53 @@ static const struct util_options_defs nxhook_options_defs = { .ndefs = lengthof(nxhook_options_def) }; -bool nxhook_options_init(int argc, char** argv, struct nxhook_options* options) +bool nxhook_options_init(int argc, char **argv, struct nxhook_options *options) { - log_assert(argv); - log_assert(options); + log_assert(argv); + log_assert(options); - struct util_options_opts* options_opt; + struct util_options_opts *options_opt; - util_options_init(argc, argv); - options_opt = util_options_get(&nxhook_options_defs); + util_options_init(argc, argv); + options_opt = util_options_get(&nxhook_options_defs); - if (!options_opt) { - return false; - } + if (!options_opt) { + return false; + } - options->game.force_unlock = util_options_get_bool(options_opt, NXHOOK_OPTIONS_STR_GAME_FORCE_UNLOCK); - options->game.settings = util_options_get_str(options_opt, NXHOOK_OPTIONS_STR_GAME_SETTINGS); - options->patch.gfx.windowed = util_options_get_bool(options_opt, NXHOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); - options->patch.hook_mon.file = util_options_get_bool(options_opt, NXHOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); - options->patch.hook_mon.fs = util_options_get_bool(options_opt, NXHOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); - options->patch.hook_mon.io = util_options_get_bool(options_opt, NXHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); - options->patch.hook_mon.open = util_options_get_bool(options_opt, NXHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); - options->patch.hook_mon.usb = util_options_get_bool(options_opt, NXHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); - options->patch.main_loop.disable_built_in_inputs = util_options_get_bool(options_opt, - NXHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); - options->patch.main_loop.x11_input_handler_api_lib = - util_options_get_str(options_opt, NXHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); - options->patch.piuio.api_lib = util_options_get_str(options_opt, NXHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); - options->patch.piuio.exit_test_serv = - util_options_get_bool(options_opt, NXHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); - options->patch.sound.device = util_options_get_str(options_opt, NXHOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); - options->patch.sigsegv.halt_on_segv = - util_options_get_bool(options_opt, NXHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); - options->log.file = util_options_get_str(options_opt, NXHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); - options->log.level = - (enum util_log_level) util_options_get_int(options_opt, NXHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); + options->game.force_unlock = + util_options_get_bool(options_opt, NXHOOK_OPTIONS_STR_GAME_FORCE_UNLOCK); + options->game.settings = + util_options_get_str(options_opt, NXHOOK_OPTIONS_STR_GAME_SETTINGS); + options->patch.gfx.windowed = + util_options_get_bool(options_opt, NXHOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); + options->patch.hook_mon.file = util_options_get_bool( + options_opt, NXHOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); + options->patch.hook_mon.fs = + util_options_get_bool(options_opt, NXHOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); + options->patch.hook_mon.io = + util_options_get_bool(options_opt, NXHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); + options->patch.hook_mon.open = util_options_get_bool( + options_opt, NXHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); + options->patch.hook_mon.usb = + util_options_get_bool(options_opt, NXHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); + options->patch.main_loop.disable_built_in_inputs = util_options_get_bool( + options_opt, + NXHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); + options->patch.main_loop.x11_input_handler_api_lib = util_options_get_str( + options_opt, NXHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); + options->patch.piuio.api_lib = + util_options_get_str(options_opt, NXHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); + options->patch.piuio.exit_test_serv = util_options_get_bool( + options_opt, NXHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); + options->patch.sound.device = + util_options_get_str(options_opt, NXHOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); + options->patch.sigsegv.halt_on_segv = util_options_get_bool( + options_opt, NXHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); + options->log.file = + util_options_get_str(options_opt, NXHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); + options->log.level = (enum util_log_level) util_options_get_int( + options_opt, NXHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); - return true; + return true; } \ No newline at end of file diff --git a/src/main/hook/nx/options.h b/src/main/hook/nx/options.h index 45272ad..13b8d78 100644 --- a/src/main/hook/nx/options.h +++ b/src/main/hook/nx/options.h @@ -7,49 +7,49 @@ #include "util/log.h" struct nxhook_options { - struct game { - bool force_unlock; - const char* settings; - } game; + struct game { + bool force_unlock; + const char *settings; + } game; - struct patch { - struct gfx { - bool windowed; - } gfx; + struct patch { + struct gfx { + bool windowed; + } gfx; - struct hook_mon { - bool file; - bool fs; - bool io; - bool open; - bool usb; - } hook_mon; + struct hook_mon { + bool file; + bool fs; + bool io; + bool open; + bool usb; + } hook_mon; - struct main_loop { - bool disable_built_in_inputs; - const char* x11_input_handler_api_lib; - } main_loop; + struct main_loop { + bool disable_built_in_inputs; + const char *x11_input_handler_api_lib; + } main_loop; - struct piuio { - const char* api_lib; - bool exit_test_serv; - } piuio; + struct piuio { + const char *api_lib; + bool exit_test_serv; + } piuio; - struct sound { - const char* device; - } sound; + struct sound { + const char *device; + } sound; - struct sigsegv { - bool halt_on_segv; - } sigsegv; - } patch; + struct sigsegv { + bool halt_on_segv; + } sigsegv; + } patch; - struct log { - const char* file; - enum util_log_level level; - } log; + struct log { + const char *file; + enum util_log_level level; + } log; }; -bool nxhook_options_init(int argc, char** argv, struct nxhook_options* options); +bool nxhook_options_init(int argc, char **argv, struct nxhook_options *options); #endif diff --git a/src/main/hook/nx/unlock.c b/src/main/hook/nx/unlock.c index 272342c..71e2b70 100644 --- a/src/main/hook/nx/unlock.c +++ b/src/main/hook/nx/unlock.c @@ -10,72 +10,73 @@ #include "util/log.h" #include "util/str.h" -static FILE* _hook_nx_unlock_settings_file = NULL; +static FILE *_hook_nx_unlock_settings_file = NULL; static enum cnh_result _hook_nx_unlock_filehook(struct cnh_filehook_irp *irp); void hook_nx_unlock_init(void) { - cnh_filehook_push_handler(_hook_nx_unlock_filehook); + cnh_filehook_push_handler(_hook_nx_unlock_filehook); - log_info("Initialized"); + log_info("Initialized"); } static enum cnh_result _hook_nx_unlock_filehook(struct cnh_filehook_irp *irp) { - enum cnh_result result; + enum cnh_result result; - assert(irp); + assert(irp); - if (irp->op != CNH_FILEHOOK_IRP_OP_OPEN && irp->file != _hook_nx_unlock_settings_file) { - return cnh_filehook_invoke_next(irp); + if (irp->op != CNH_FILEHOOK_IRP_OP_OPEN && + irp->file != _hook_nx_unlock_settings_file) { + return cnh_filehook_invoke_next(irp); + } + + switch (irp->op) { + case CNH_FILEHOOK_IRP_OP_OPEN: { + /* Let it open the real file */ + result = cnh_filehook_invoke_next(irp); + + if (util_str_ends_with(irp->open_filename, ASSET_NX_SETTINGS_FILE_NAME)) { + if (result == CNH_RESULT_SUCCESS) { + log_debug("Intercepting settings file open"); + _hook_nx_unlock_settings_file = irp->file; + } + } + + break; } - switch (irp->op) { - case CNH_FILEHOOK_IRP_OP_OPEN: - { - /* Let it open the real file */ - result = cnh_filehook_invoke_next(irp); + case CNH_FILEHOOK_IRP_OP_READ: { + /* Let it read the real file */ + result = cnh_filehook_invoke_next(irp); - if (util_str_ends_with(irp->open_filename, ASSET_NX_SETTINGS_FILE_NAME)) { - if (result == CNH_RESULT_SUCCESS) { - log_debug("Intercepting settings file open"); - _hook_nx_unlock_settings_file = irp->file; - } - } + if (result == CNH_RESULT_SUCCESS) { + struct asset_nx_settings *settings = + (struct asset_nx_settings *) irp->read.bytes; - break; - } + asset_nx_settings_unlock_all(settings); - case CNH_FILEHOOK_IRP_OP_READ: - { - /* Let it read the real file */ - result = cnh_filehook_invoke_next(irp); + log_debug( + "Applied unlock patch to loaded settings (buffer size %d)", + irp->read.pos); + } - if (result == CNH_RESULT_SUCCESS) { - struct asset_nx_settings* settings = (struct asset_nx_settings*) irp->read.bytes; - - asset_nx_settings_unlock_all(settings); - - log_debug("Applied unlock patch to loaded settings (buffer size %d)", irp->read.pos); - } - - break; - } - - case CNH_FILEHOOK_IRP_OP_CLOSE: - { - _hook_nx_unlock_settings_file = NULL; - - result = cnh_filehook_invoke_next(irp); - - break; - } - - default: - result = cnh_filehook_invoke_next(irp); - break; + break; } - return result; + case CNH_FILEHOOK_IRP_OP_CLOSE: { + _hook_nx_unlock_settings_file = NULL; + + result = cnh_filehook_invoke_next(irp); + + break; + } + + default: + result = cnh_filehook_invoke_next(irp); + break; + } + + return result; } \ No newline at end of file diff --git a/src/main/hook/nx/unlock.h b/src/main/hook/nx/unlock.h index 5e63b4c..381726c 100644 --- a/src/main/hook/nx/unlock.h +++ b/src/main/hook/nx/unlock.h @@ -1,5 +1,6 @@ /** - * Patch module to force unlock all songs/features of the game without modifying the configuration stored on disk. + * Patch module to force unlock all songs/features of the game without modifying + * the configuration stored on disk. */ #ifndef HOOK_NX_UNLOCK_H #define HOOK_NX_UNLOCK_H diff --git a/src/main/hook/nx2/main.c b/src/main/hook/nx2/main.c index 6bf5e5f..39c3d85 100644 --- a/src/main/hook/nx2/main.c +++ b/src/main/hook/nx2/main.c @@ -14,8 +14,8 @@ #include "hook/patch/microdog40.h" #include "hook/patch/mounts.h" #include "hook/patch/net-profile.h" -#include "hook/patch/piuio.h" #include "hook/patch/piuio-exit.h" +#include "hook/patch/piuio.h" #include "hook/patch/redir.h" #include "hook/patch/sigsegv.h" #include "hook/patch/sound.h" @@ -39,280 +39,297 @@ extern const uint8_t _binary_nx2hook_hdd_raw_end[]; extern const uint8_t _binary_nx2hook_dog_key_start[]; extern const uint8_t _binary_nx2hook_dog_key_end[]; -static void nx2hook_bootstrapping(int argc, char** argv, struct nx2hook_options* options, char** game_data_path) +static void nx2hook_bootstrapping( + int argc, + char **argv, + struct nx2hook_options *options, + char **game_data_path) { - log_assert(argc >= 0); - log_assert(argv); - log_assert(options); - log_assert(game_data_path); + log_assert(argc >= 0); + log_assert(argv); + log_assert(options); + log_assert(game_data_path); - if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { - return; + if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { + return; + } + + hook_core_piu_log_init(argc, argv); + + if (!nx2hook_options_init(argc, argv, options)) { + exit(0); + } + + hook_core_piu_log_info(argc, argv); + + *game_data_path = + hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); + + hook_core_piu_utils_verify_root_user(); + + log_info("Initializing, piu game data path: %s", *game_data_path); +} + +static void nx2hook_patch_fs_init(struct nx2hook_options *options) +{ + log_assert(options); + + patch_hook_mon_init( + options->patch.hook_mon.io, + options->patch.hook_mon.file, + options->patch.hook_mon.fs, + options->patch.hook_mon.usb, + options->patch.hook_mon.open); + + patch_redir_init(); +} + +static void nx2hook_fs_redir_settings(struct nx2hook_options *options) +{ + log_assert(options); + + if (options->game.settings) { + if (!util_fs_path_exists(options->game.settings)) { + log_info( + "Settings path %s does not exist, creating", options->game.settings); + + if (!util_fs_mkdir(options->game.settings)) { + log_error("Creating directory %s failed", options->game.settings); + } } - hook_core_piu_log_init(argc, argv); + char *abs_path = util_fs_get_abs_path(options->game.settings); - if (!nx2hook_options_init(argc, argv, options)) { - exit(0); - } - - hook_core_piu_log_info(argc, argv); - - *game_data_path = hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); - - hook_core_piu_utils_verify_root_user(); - - log_info("Initializing, piu game data path: %s", *game_data_path); + cnh_redir_add("/SETTINGS", abs_path); + free(abs_path); + } else { + log_warn("No settings path specified"); + } } -static void nx2hook_patch_fs_init(struct nx2hook_options* options) +static void nx2hook_fs_redir_script( + struct nx2hook_options *options, const char *game_data_path) { - log_assert(options); + log_assert(options); + log_assert(game_data_path); - patch_hook_mon_init( - options->patch.hook_mon.io, - options->patch.hook_mon.file, - options->patch.hook_mon.fs, - options->patch.hook_mon.usb, - options->patch.hook_mon.open); + char *path_tmp; - patch_redir_init(); + path_tmp = util_str_merge(game_data_path, "/SCRIPT"); + cnh_redir_add("/SCRIPT", path_tmp); + free(path_tmp); } -static void nx2hook_fs_redir_settings(struct nx2hook_options* options) +static void nx2hook_fs_redir_fonts( + struct nx2hook_options *options, const char *game_data_path) { - log_assert(options); + log_assert(options); + log_assert(game_data_path); - if (options->game.settings) { - if (!util_fs_path_exists(options->game.settings)) { - log_info("Settings path %s does not exist, creating", options->game.settings); + char *path_tmp; - if (!util_fs_mkdir(options->game.settings)) { - log_error("Creating directory %s failed", options->game.settings); - } - } + /* Fonts, game expects lower case files */ + path_tmp = util_str_merge(game_data_path, "/nx.ttf"); + cnh_redir_add("nx.ttf", path_tmp); + free(path_tmp); - char* abs_path = util_fs_get_abs_path(options->game.settings); + path_tmp = util_str_merge(game_data_path, "/nxcn.ttf"); + cnh_redir_add("nxcn.ttf", path_tmp); + free(path_tmp); - cnh_redir_add("/SETTINGS", abs_path); - free(abs_path); - } else { - log_warn("No settings path specified"); - } + path_tmp = util_str_merge(game_data_path, "/nxpt.ttf"); + cnh_redir_add("nxpt.ttf", path_tmp); + free(path_tmp); + + path_tmp = util_str_merge(game_data_path, "/nxtw.ttf"); + cnh_redir_add("nxtw.ttf", path_tmp); + free(path_tmp); } -static void nx2hook_fs_redir_script(struct nx2hook_options* options, const char* game_data_path) +static void nx2hook_fs_redir_mission( + struct nx2hook_options *options, const char *game_data_path) { - log_assert(options); - log_assert(game_data_path); + log_assert(options); + log_assert(game_data_path); - char* path_tmp; + char *path_tmp; - path_tmp = util_str_merge(game_data_path, "/SCRIPT"); - cnh_redir_add("/SCRIPT", path_tmp); - free(path_tmp); -} - -static void nx2hook_fs_redir_fonts(struct nx2hook_options* options, const char* game_data_path) -{ - log_assert(options); - log_assert(game_data_path); - - char* path_tmp; - - /* Fonts, game expects lower case files */ - path_tmp = util_str_merge(game_data_path, "/nx.ttf"); - cnh_redir_add("nx.ttf", path_tmp); - free(path_tmp); - - path_tmp = util_str_merge(game_data_path, "/nxcn.ttf"); - cnh_redir_add("nxcn.ttf", path_tmp); - free(path_tmp); - - path_tmp = util_str_merge(game_data_path, "/nxpt.ttf"); - cnh_redir_add("nxpt.ttf", path_tmp); - free(path_tmp); - - path_tmp = util_str_merge(game_data_path, "/nxtw.ttf"); - cnh_redir_add("nxtw.ttf", path_tmp); - free(path_tmp); -} - -static void nx2hook_fs_redir_mission(struct nx2hook_options* options, const char* game_data_path) -{ - log_assert(options); - log_assert(game_data_path); - - char* path_tmp; - - /* mission.txt, game expects lower case file */ - path_tmp = util_str_merge(game_data_path, "/mission.txt"); - cnh_redir_add("/mission.txt", path_tmp); - free(path_tmp); + /* mission.txt, game expects lower case file */ + path_tmp = util_str_merge(game_data_path, "/mission.txt"); + cnh_redir_add("/mission.txt", path_tmp); + free(path_tmp); } static void nx2hook_fs_redir_usb() { - /* Needed on newer kernels */ - cnh_redir_add("/proc/bus/usb/devices", "/sys/kernel/debug/usb/devices"); - patch_usbfs_init(); + /* Needed on newer kernels */ + cnh_redir_add("/proc/bus/usb/devices", "/sys/kernel/debug/usb/devices"); + patch_usbfs_init(); } -static void nx2hook_fs_redirs_init(struct nx2hook_options* options, const char* game_data_path) +static void nx2hook_fs_redirs_init( + struct nx2hook_options *options, const char *game_data_path) { - log_assert(options); - log_assert(game_data_path); + log_assert(options); + log_assert(game_data_path); - /* Expecting all assets in the piu game (asset) folder. redirects for files - that are not in there by default for reasons */ - nx2hook_fs_redir_settings(options); - nx2hook_fs_redir_script(options, game_data_path); - nx2hook_fs_redir_fonts(options, game_data_path); - nx2hook_fs_redir_mission(options, game_data_path); + /* Expecting all assets in the piu game (asset) folder. redirects for files + that are not in there by default for reasons */ + nx2hook_fs_redir_settings(options); + nx2hook_fs_redir_script(options, game_data_path); + nx2hook_fs_redir_fonts(options, game_data_path); + nx2hook_fs_redir_mission(options, game_data_path); - nx2hook_fs_redir_usb(); + nx2hook_fs_redir_usb(); } static void nx2hook_patch_fs_mounting_init() { - patch_mounts_init(); + patch_mounts_init(); - patch_usb_mnt_init(); - patch_usb_unlock_init(); + patch_usb_mnt_init(); + patch_usb_unlock_init(); } -static void nx2hook_patch_gfx_init(struct nx2hook_options* options) +static void nx2hook_patch_gfx_init(struct nx2hook_options *options) { - log_assert(options); + log_assert(options); - patch_gfx_init(); + patch_gfx_init(); - if (options->patch.gfx.windowed) { - patch_gfx_force_window_mode(); - } + if (options->patch.gfx.windowed) { + patch_gfx_force_window_mode(); + } } -static void nx2hook_patch_main_loop_init(struct nx2hook_options* options) +static void nx2hook_patch_main_loop_init(struct nx2hook_options *options) { - log_assert(options); + log_assert(options); - patch_main_loop_init(false, options->patch.main_loop.disable_built_in_inputs, false); + patch_main_loop_init( + false, options->patch.main_loop.disable_built_in_inputs, false); - if (options->patch.main_loop.x11_input_handler_api_lib) { - char* abs_path_x11_input_hook_lib = util_fs_get_abs_path(options->patch.main_loop.x11_input_handler_api_lib); + if (options->patch.main_loop.x11_input_handler_api_lib) { + char *abs_path_x11_input_hook_lib = util_fs_get_abs_path( + options->patch.main_loop.x11_input_handler_api_lib); - patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); - free(abs_path_x11_input_hook_lib); - } + patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); + free(abs_path_x11_input_hook_lib); + } } -static void nx2hook_patch_sound_init(struct nx2hook_options* options) +static void nx2hook_patch_sound_init(struct nx2hook_options *options) { - log_assert(options); + log_assert(options); - patch_sound_init(options->patch.sound.device); + patch_sound_init(options->patch.sound.device); } -static void nx2hook_patch_sigsegv_init(struct nx2hook_options* options) +static void nx2hook_patch_sigsegv_init(struct nx2hook_options *options) { - log_assert(options); + log_assert(options); - patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); + patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); } static void nx2hook_patch_dongle_init() { - patch_microdog40_init((const uint8_t*) _binary_nx2hook_dog_key_start, - ((uintptr_t) &_binary_nx2hook_dog_key_end - (uintptr_t) &_binary_nx2hook_dog_key_start)); + patch_microdog40_init( + (const uint8_t *) _binary_nx2hook_dog_key_start, + ((uintptr_t) &_binary_nx2hook_dog_key_end - + (uintptr_t) &_binary_nx2hook_dog_key_start)); } static void nx2hook_patch_hdd_check_init() { - patch_hdd_check_init((const uint8_t*) _binary_nx2hook_hdd_raw_start, - ((uintptr_t) &_binary_nx2hook_hdd_raw_end - (uintptr_t) &_binary_nx2hook_hdd_raw_start)); + patch_hdd_check_init( + (const uint8_t *) _binary_nx2hook_hdd_raw_start, + ((uintptr_t) &_binary_nx2hook_hdd_raw_end - + (uintptr_t) &_binary_nx2hook_hdd_raw_start)); } -static void nx2hook_patch_piuio_init(struct nx2hook_options* options) +static void nx2hook_patch_piuio_init(struct nx2hook_options *options) { - log_assert(options); + log_assert(options); - /* Hook before IO emulation */ - if (options->patch.piuio.exit_test_serv) { - patch_piuio_exit_init(); - } + /* Hook before IO emulation */ + if (options->patch.piuio.exit_test_serv) { + patch_piuio_exit_init(); + } - patch_usb_init_fix_init(); - patch_usb_emu_init(); + patch_usb_init_fix_init(); + patch_usb_emu_init(); - if (options->patch.piuio.api_lib) { - char* abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); + if (options->patch.piuio.api_lib) { + char *abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); - patch_piuio_init(abs_path_iolib); - free(abs_path_iolib); - } + patch_piuio_init(abs_path_iolib); + free(abs_path_iolib); + } } static void nx2hook_patch_profile() { - nx2hook_profile_gen_init(); + nx2hook_profile_gen_init(); } -static void nx2hook_patch_pumpnet(struct nx2hook_options* options) +static void nx2hook_patch_pumpnet(struct nx2hook_options *options) { - if (options->patch.net.server && options->patch.net.machine_id != 0) { - patch_net_profile_init( - ASSET_GAME_VERSION_NX2, - options->patch.net.server, - options->patch.net.machine_id, - options->patch.net.cert_dir_path, - options->patch.net.verbose_log_output); - } + if (options->patch.net.server && options->patch.net.machine_id != 0) { + patch_net_profile_init( + ASSET_GAME_VERSION_NX2, + options->patch.net.server, + options->patch.net.machine_id, + options->patch.net.cert_dir_path, + options->patch.net.verbose_log_output); + } } void nx2hook_constructor(void) { - /* Nothing here */ + /* Nothing here */ } void nx2hook_destructor(void) { - /* Nothing here */ + /* Nothing here */ } -void nx2hook_trap_before_main(int argc, char** argv) +void nx2hook_trap_before_main(int argc, char **argv) { - log_assert(argc >= 0); - log_assert(argv); + log_assert(argc >= 0); + log_assert(argv); - char* game_data_path; - struct nx2hook_options options; + char *game_data_path; + struct nx2hook_options options; - nx2hook_bootstrapping(argc, argv, &options, &game_data_path); - nx2hook_patch_fs_init(&options); - nx2hook_fs_redirs_init(&options, game_data_path); - nx2hook_patch_fs_mounting_init(); - nx2hook_patch_gfx_init(&options); - nx2hook_patch_main_loop_init(&options); - nx2hook_patch_sound_init(&options); - nx2hook_patch_sigsegv_init(&options); - nx2hook_patch_dongle_init(); - nx2hook_patch_hdd_check_init(); - nx2hook_patch_piuio_init(&options); - // Init order of pumpnet and auto profile generating important: pumpnet hook, if active, needs to be applied before - // the auto gen profile hook. Otherwise, the game detects that no profile is available and auto generates one even - // it should take the pumpnet route to grab a profile from a remote server - nx2hook_patch_pumpnet(&options); - nx2hook_patch_profile(); + nx2hook_bootstrapping(argc, argv, &options, &game_data_path); + nx2hook_patch_fs_init(&options); + nx2hook_fs_redirs_init(&options, game_data_path); + nx2hook_patch_fs_mounting_init(); + nx2hook_patch_gfx_init(&options); + nx2hook_patch_main_loop_init(&options); + nx2hook_patch_sound_init(&options); + nx2hook_patch_sigsegv_init(&options); + nx2hook_patch_dongle_init(); + nx2hook_patch_hdd_check_init(); + nx2hook_patch_piuio_init(&options); + // Init order of pumpnet and auto profile generating important: pumpnet hook, + // if active, needs to be applied before the auto gen profile hook. Otherwise, + // the game detects that no profile is available and auto generates one even + // it should take the pumpnet route to grab a profile from a remote server + nx2hook_patch_pumpnet(&options); + nx2hook_patch_profile(); - free(game_data_path); + free(game_data_path); - log_info("Hooking finished"); + log_info("Hooking finished"); } void nx2hook_trap_after_main(void) { - patch_net_profile_shutdown(); - patch_piuio_shutdown(); + patch_net_profile_shutdown(); + patch_piuio_shutdown(); } LIB_MAIN_CONSTRUCTOR(nx2hook_constructor); diff --git a/src/main/hook/nx2/options.c b/src/main/hook/nx2/options.c index 24fbd1c..e3343b5 100644 --- a/src/main/hook/nx2/options.c +++ b/src/main/hook/nx2/options.c @@ -9,16 +9,23 @@ #define NX2HOOK_OPTIONS_STR_PATCH_HOOK_MON_IO "patch.hook_mon.io" #define NX2HOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN "patch.hook_mon.open" #define NX2HOOK_OPTIONS_STR_PATCH_HOOK_MON_USB "patch.hook_mon.usb" -#define NX2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS "patch.hook_main_loop.disable_built_in_inputs" -#define NX2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER "patch_hook_main_loop.x11_input_handler" +#define NX2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS \ + "patch.hook_main_loop.disable_built_in_inputs" +#define NX2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER \ + "patch_hook_main_loop.x11_input_handler" #define NX2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_SERVER "patch.net_profile.server" -#define NX2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_MACHINE_ID "patch.net_profile.machine_id" -#define NX2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_VERBOSE_LOG_OUTPUT "patch.net_profile.verbose_log_output" -#define NX2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_CERT_DIR_PATH "patch.net_profile.cert_dir_path" +#define NX2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_MACHINE_ID \ + "patch.net_profile.machine_id" +#define NX2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_VERBOSE_LOG_OUTPUT \ + "patch.net_profile.verbose_log_output" +#define NX2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_CERT_DIR_PATH \ + "patch.net_profile.cert_dir_path" #define NX2HOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB "patch.piuio.emu_lib" -#define NX2HOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV "patch.piuio_exit.test_serv" +#define NX2HOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV \ + "patch.piuio_exit.test_serv" #define NX2HOOK_OPTIONS_STR_PATCH_SOUND_DEVICE "patch.sound.device" -#define NX2HOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV "patch.sigsegv.halt_on_segv" +#define NX2HOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV \ + "patch.sigsegv.halt_on_segv" #define NX2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE "util.log.file" #define NX2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL "util.log.level" @@ -73,22 +80,26 @@ const struct util_options_def nx2hook_options_def[] = { .default_value.b = false, }, { - .name = NX2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS, - .description = "Disable the built in keyboard inputs for test (F1), service (F2) and clear (F3)", + .name = + NX2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS, + .description = "Disable the built in keyboard inputs for test (F1), " + "service (F2) and clear (F3)", .param = 'k', .type = UTIL_OPTIONS_TYPE_BOOL, .default_value.b = false, }, { .name = NX2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER, - .description = "Path to a library implementing the x11-input-handler api to capture X11 keyboard inputs", + .description = "Path to a library implementing the x11-input-handler " + "api to capture X11 keyboard inputs", .param = 'q', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, }, { .name = NX2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_SERVER, - .description = "Address and port of pumpnet server (e.g. 127.0.0.1:1234)", + .description = + "Address and port of pumpnet server (e.g. 127.0.0.1:1234)", .param = 'n', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, @@ -102,21 +113,25 @@ const struct util_options_def nx2hook_options_def[] = { }, { .name = NX2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_VERBOSE_LOG_OUTPUT, - .description = "Enable verbose log output for pumpnet related things, e.g. logging network traffic", + .description = "Enable verbose log output for pumpnet related things, " + "e.g. logging network traffic", .param = 'v', .type = UTIL_OPTIONS_TYPE_BOOL, .default_value.b = false, }, { .name = NX2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_CERT_DIR_PATH, - .description = "Path to a folder containing the client key, certificate and CA bundle to enable https communication", + .description = + "Path to a folder containing the client key, certificate and CA " + "bundle to enable https communication", .param = 'c', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, }, { .name = NX2HOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB, - .description = "Path to library implementing the piuio api for piuio emulation", + .description = + "Path to library implementing the piuio api for piuio emulation", .param = 'p', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, @@ -167,49 +182,63 @@ const struct util_options_defs nx2hook_options_defs = { .ndefs = lengthof(nx2hook_options_def) }; -bool nx2hook_options_init(int argc, char** argv, struct nx2hook_options* options) +bool nx2hook_options_init( + int argc, char **argv, struct nx2hook_options *options) { - log_assert(argv); - log_assert(options); + log_assert(argv); + log_assert(options); - struct util_options_opts* options_opt; + struct util_options_opts *options_opt; - util_options_init(argc, argv); - options_opt = util_options_get(&nx2hook_options_defs); + util_options_init(argc, argv); + options_opt = util_options_get(&nx2hook_options_defs); - if (!options_opt) { - return false; - } + if (!options_opt) { + return false; + } - options->game.settings = util_options_get_str(options_opt, NX2HOOK_OPTIONS_STR_GAME_SETTINGS); - options->patch.gfx.windowed = util_options_get_bool(options_opt, NX2HOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); - options->patch.hook_mon.file = util_options_get_bool(options_opt, NX2HOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); - options->patch.hook_mon.fs = util_options_get_bool(options_opt, NX2HOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); - options->patch.hook_mon.io = util_options_get_bool(options_opt, NX2HOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); - options->patch.hook_mon.open = util_options_get_bool(options_opt, NX2HOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); - options->patch.hook_mon.usb = util_options_get_bool(options_opt, NX2HOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); - options->patch.main_loop.disable_built_in_inputs = util_options_get_bool(options_opt, - NX2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); - options->patch.main_loop.x11_input_handler_api_lib = - util_options_get_str(options_opt, NX2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); - options->patch.net.server = util_options_get_str(options_opt, NX2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_SERVER); - options->patch.net.machine_id = strtoull( - util_options_get_str(options_opt, NX2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_MACHINE_ID), - NULL, - 16); - options->patch.net.verbose_log_output = - util_options_get_bool(options_opt, NX2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_VERBOSE_LOG_OUTPUT); - options->patch.net.cert_dir_path = - util_options_get_str(options_opt, NX2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_CERT_DIR_PATH); - options->patch.piuio.api_lib = util_options_get_str(options_opt, NX2HOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); - options->patch.piuio.exit_test_serv = - util_options_get_bool(options_opt, NX2HOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); - options->patch.sound.device = util_options_get_str(options_opt, NX2HOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); - options->patch.sigsegv.halt_on_segv = - util_options_get_bool(options_opt, NX2HOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); - options->log.file = util_options_get_str(options_opt, NX2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); - options->log.level = - (enum util_log_level) util_options_get_int(options_opt, NX2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); + options->game.settings = + util_options_get_str(options_opt, NX2HOOK_OPTIONS_STR_GAME_SETTINGS); + options->patch.gfx.windowed = util_options_get_bool( + options_opt, NX2HOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); + options->patch.hook_mon.file = util_options_get_bool( + options_opt, NX2HOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); + options->patch.hook_mon.fs = + util_options_get_bool(options_opt, NX2HOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); + options->patch.hook_mon.io = + util_options_get_bool(options_opt, NX2HOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); + options->patch.hook_mon.open = util_options_get_bool( + options_opt, NX2HOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); + options->patch.hook_mon.usb = util_options_get_bool( + options_opt, NX2HOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); + options->patch.main_loop.disable_built_in_inputs = util_options_get_bool( + options_opt, + NX2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); + options->patch.main_loop.x11_input_handler_api_lib = util_options_get_str( + options_opt, NX2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); + options->patch.net.server = util_options_get_str( + options_opt, NX2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_SERVER); + options->patch.net.machine_id = strtoull( + util_options_get_str( + options_opt, NX2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_MACHINE_ID), + NULL, + 16); + options->patch.net.verbose_log_output = util_options_get_bool( + options_opt, NX2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_VERBOSE_LOG_OUTPUT); + options->patch.net.cert_dir_path = util_options_get_str( + options_opt, NX2HOOK_OPTIONS_STR_PATCH_NET_PROFILE_CERT_DIR_PATH); + options->patch.piuio.api_lib = util_options_get_str( + options_opt, NX2HOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); + options->patch.piuio.exit_test_serv = util_options_get_bool( + options_opt, NX2HOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); + options->patch.sound.device = + util_options_get_str(options_opt, NX2HOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); + options->patch.sigsegv.halt_on_segv = util_options_get_bool( + options_opt, NX2HOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); + options->log.file = util_options_get_str( + options_opt, NX2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); + options->log.level = (enum util_log_level) util_options_get_int( + options_opt, NX2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); - return true; + return true; } \ No newline at end of file diff --git a/src/main/hook/nx2/options.h b/src/main/hook/nx2/options.h index 65a28b9..7b7e18a 100644 --- a/src/main/hook/nx2/options.h +++ b/src/main/hook/nx2/options.h @@ -7,55 +7,56 @@ #include "util/log.h" struct nx2hook_options { - struct game { - const char* settings; - } game; + struct game { + const char *settings; + } game; - struct patch { - struct gfx { - bool windowed; - } gfx; + struct patch { + struct gfx { + bool windowed; + } gfx; - struct hook_mon { - bool file; - bool fs; - bool io; - bool open; - bool usb; - } hook_mon; + struct hook_mon { + bool file; + bool fs; + bool io; + bool open; + bool usb; + } hook_mon; - struct main_loop { - bool disable_built_in_inputs; - const char* x11_input_handler_api_lib; - } main_loop; + struct main_loop { + bool disable_built_in_inputs; + const char *x11_input_handler_api_lib; + } main_loop; - struct net { - const char* server; - uint64_t machine_id; - bool verbose_log_output; - const char* cert_dir_path; - } net; + struct net { + const char *server; + uint64_t machine_id; + bool verbose_log_output; + const char *cert_dir_path; + } net; - struct piuio { - const char* api_lib; - bool exit_test_serv; - } piuio; + struct piuio { + const char *api_lib; + bool exit_test_serv; + } piuio; - struct sound { - const char* device; - } sound; + struct sound { + const char *device; + } sound; - struct sigsegv { - bool halt_on_segv; - } sigsegv; - } patch; + struct sigsegv { + bool halt_on_segv; + } sigsegv; + } patch; - struct log { - const char* file; - enum util_log_level level; - } log; + struct log { + const char *file; + enum util_log_level level; + } log; }; -bool nx2hook_options_init(int argc, char** argv, struct nx2hook_options* options); +bool nx2hook_options_init( + int argc, char **argv, struct nx2hook_options *options); #endif diff --git a/src/main/hook/nx2/profile-gen.c b/src/main/hook/nx2/profile-gen.c index 7994653..be41f99 100644 --- a/src/main/hook/nx2/profile-gen.c +++ b/src/main/hook/nx2/profile-gen.c @@ -12,59 +12,65 @@ static bool nx2hook_profile_gen_is_creating_file; -// Do not use util_fs_path_exists here as this fopens and causes an endless recursion -static bool nx2hook_profile_gen_check_if_exists(const char* path) +// Do not use util_fs_path_exists here as this fopens and causes an endless +// recursion +static bool nx2hook_profile_gen_check_if_exists(const char *path) { - return access(path, F_OK) != -1; + return access(path, F_OK) != -1; } -static enum cnh_result nx2hook_profile_gen_filehook(struct cnh_filehook_irp *irp) +static enum cnh_result +nx2hook_profile_gen_filehook(struct cnh_filehook_irp *irp) { - // nx2hook_profile_gen_is_creating_file: Avoid recursion of any file calls when creating the save/rank files - if (irp->op != CNH_FILEHOOK_IRP_OP_OPEN || nx2hook_profile_gen_is_creating_file) { - return cnh_filehook_invoke_next(irp); - } - - if (util_str_ends_with(irp->open_filename, "nx2save.bin") && - !nx2hook_profile_gen_check_if_exists(irp->open_filename)) { - nx2hook_profile_gen_is_creating_file = true; - - struct asset_nx2_usb_save* save = asset_nx2_usb_save_new(); - asset_nx2_usb_save_finalize(save); - - log_info("No %s file found, generate new", irp->open_filename); - - if (!asset_nx2_usb_save_save_to_file(irp->open_filename, save, true)) { - log_error("Saving generated nx2save.bin file to %s failed", irp->open_filename); - } - - free(save); - - nx2hook_profile_gen_is_creating_file = false; - } - - if (util_str_ends_with(irp->open_filename, "nx2rank.bin") && - !nx2hook_profile_gen_check_if_exists(irp->open_filename)) { - nx2hook_profile_gen_is_creating_file = true; - - struct asset_nx2_usb_rank* rank = asset_nx2_usb_rank_new(); - asset_nx2_usb_rank_finalize(rank); - - log_info("No %s file found, generate new", irp->open_filename); - - if (!asset_nx2_usb_rank_save_to_file(irp->open_filename, rank, true)) { - log_error("Saving generated nx2rank.bin file to %s failed", irp->open_filename); - } - - free(rank); - - nx2hook_profile_gen_is_creating_file = false; - } - + // nx2hook_profile_gen_is_creating_file: Avoid recursion of any file calls + // when creating the save/rank files + if (irp->op != CNH_FILEHOOK_IRP_OP_OPEN || + nx2hook_profile_gen_is_creating_file) { return cnh_filehook_invoke_next(irp); + } + + if (util_str_ends_with(irp->open_filename, "nx2save.bin") && + !nx2hook_profile_gen_check_if_exists(irp->open_filename)) { + nx2hook_profile_gen_is_creating_file = true; + + struct asset_nx2_usb_save *save = asset_nx2_usb_save_new(); + asset_nx2_usb_save_finalize(save); + + log_info("No %s file found, generate new", irp->open_filename); + + if (!asset_nx2_usb_save_save_to_file(irp->open_filename, save, true)) { + log_error( + "Saving generated nx2save.bin file to %s failed", irp->open_filename); + } + + free(save); + + nx2hook_profile_gen_is_creating_file = false; + } + + if (util_str_ends_with(irp->open_filename, "nx2rank.bin") && + !nx2hook_profile_gen_check_if_exists(irp->open_filename)) { + nx2hook_profile_gen_is_creating_file = true; + + struct asset_nx2_usb_rank *rank = asset_nx2_usb_rank_new(); + asset_nx2_usb_rank_finalize(rank); + + log_info("No %s file found, generate new", irp->open_filename); + + if (!asset_nx2_usb_rank_save_to_file(irp->open_filename, rank, true)) { + log_error( + "Saving generated nx2rank.bin file to %s failed", irp->open_filename); + } + + free(rank); + + nx2hook_profile_gen_is_creating_file = false; + } + + return cnh_filehook_invoke_next(irp); } void nx2hook_profile_gen_init(void) { - cnh_filehook_push_handler(nx2hook_profile_gen_filehook); + cnh_filehook_push_handler(nx2hook_profile_gen_filehook); } \ No newline at end of file diff --git a/src/main/hook/nxa/main.c b/src/main/hook/nxa/main.c index 9b20e1b..00a2a1c 100644 --- a/src/main/hook/nxa/main.c +++ b/src/main/hook/nxa/main.c @@ -16,8 +16,8 @@ #include "hook/patch/main-loop.h" #include "hook/patch/microdog40.h" #include "hook/patch/mounts.h" -#include "hook/patch/piuio.h" #include "hook/patch/piuio-exit.h" +#include "hook/patch/piuio.h" #include "hook/patch/redir.h" #include "hook/patch/sigsegv.h" #include "hook/patch/sound.h" @@ -41,268 +41,284 @@ extern const uint8_t _binary_nxahook_hdd_raw_end[]; extern const uint8_t _binary_nxahook_dog_key_start[]; extern const uint8_t _binary_nxahook_dog_key_end[]; -static void nxahook_bootstrapping(int argc, char** argv, struct nxahook_options* options, char** game_data_path) +static void nxahook_bootstrapping( + int argc, + char **argv, + struct nxahook_options *options, + char **game_data_path) { - log_assert(argc >= 0); - log_assert(argv); - log_assert(options); - log_assert(game_data_path); + log_assert(argc >= 0); + log_assert(argv); + log_assert(options); + log_assert(game_data_path); - if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { - return; + if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { + return; + } + + hook_core_piu_log_init(argc, argv); + + if (!nxahook_options_init(argc, argv, options)) { + exit(0); + } + + hook_core_piu_log_info(argc, argv); + + *game_data_path = + hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); + + hook_core_piu_utils_verify_root_user(); + + log_info("Initializing, piu game data path: %s", *game_data_path); +} + +static void nxahook_patch_fs_init(struct nxahook_options *options) +{ + log_assert(options); + + patch_hook_mon_init( + options->patch.hook_mon.io, + options->patch.hook_mon.file, + options->patch.hook_mon.fs, + options->patch.hook_mon.usb, + options->patch.hook_mon.open); + + patch_redir_init(); +} + +static void nxahook_fs_redir_settings(struct nxahook_options *options) +{ + log_assert(options); + + if (options->game.settings) { + if (!util_fs_path_exists(options->game.settings)) { + log_info( + "Settings path %s does not exist, creating", options->game.settings); + + if (!util_fs_mkdir(options->game.settings)) { + log_error("Creating directory %s failed", options->game.settings); + } } - hook_core_piu_log_init(argc, argv); + char *abs_path = util_fs_get_abs_path(options->game.settings); - if (!nxahook_options_init(argc, argv, options)) { - exit(0); - } - - hook_core_piu_log_info(argc, argv); - - *game_data_path = hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); - - hook_core_piu_utils_verify_root_user(); - - log_info("Initializing, piu game data path: %s", *game_data_path); + cnh_redir_add("/SETTINGS", abs_path); + free(abs_path); + } else { + log_warn("No settings path specified"); + } } -static void nxahook_patch_fs_init(struct nxahook_options* options) +static void nxahook_fs_redir_script( + struct nxahook_options *options, const char *game_data_path) { - log_assert(options); + log_assert(options); + log_assert(game_data_path); - patch_hook_mon_init( - options->patch.hook_mon.io, - options->patch.hook_mon.file, - options->patch.hook_mon.fs, - options->patch.hook_mon.usb, - options->patch.hook_mon.open); + char *path_tmp; - patch_redir_init(); + path_tmp = util_str_merge(game_data_path, "/SCRIPT"); + cnh_redir_add("/SCRIPT", path_tmp); + free(path_tmp); } -static void nxahook_fs_redir_settings(struct nxahook_options* options) +static void nxahook_fs_redir_fonts( + struct nxahook_options *options, const char *game_data_path) { - log_assert(options); + log_assert(options); + log_assert(game_data_path); - if (options->game.settings) { - if (!util_fs_path_exists(options->game.settings)) { - log_info("Settings path %s does not exist, creating", options->game.settings); + char *path_tmp; - if (!util_fs_mkdir(options->game.settings)) { - log_error("Creating directory %s failed", options->game.settings); - } - } + /* Fonts, game expects lower case files */ + path_tmp = util_str_merge(game_data_path, "/nx.ttf"); + cnh_redir_add("nx.ttf", path_tmp); + free(path_tmp); - char* abs_path = util_fs_get_abs_path(options->game.settings); + path_tmp = util_str_merge(game_data_path, "/nxcn.ttf"); + cnh_redir_add("nxcn.ttf", path_tmp); + free(path_tmp); - cnh_redir_add("/SETTINGS", abs_path); - free(abs_path); - } else { - log_warn("No settings path specified"); - } + path_tmp = util_str_merge(game_data_path, "/nxpt.ttf"); + cnh_redir_add("nxpt.ttf", path_tmp); + free(path_tmp); + + path_tmp = util_str_merge(game_data_path, "/nxtw.ttf"); + cnh_redir_add("nxtw.ttf", path_tmp); + free(path_tmp); } -static void nxahook_fs_redir_script(struct nxahook_options* options, const char* game_data_path) +static void nxahook_fs_redir_mission( + struct nxahook_options *options, const char *game_data_path) { - log_assert(options); - log_assert(game_data_path); + log_assert(options); + log_assert(game_data_path); - char* path_tmp; + char *path_tmp; - path_tmp = util_str_merge(game_data_path, "/SCRIPT"); - cnh_redir_add("/SCRIPT", path_tmp); - free(path_tmp); -} + /* mission.txt, game expects lower case file */ + path_tmp = util_str_merge(game_data_path, "/mission.txt"); + cnh_redir_add("/mission.txt", path_tmp); + free(path_tmp); -static void nxahook_fs_redir_fonts(struct nxahook_options* options, const char* game_data_path) -{ - log_assert(options); - log_assert(game_data_path); - - char* path_tmp; - - /* Fonts, game expects lower case files */ - path_tmp = util_str_merge(game_data_path, "/nx.ttf"); - cnh_redir_add("nx.ttf", path_tmp); - free(path_tmp); - - path_tmp = util_str_merge(game_data_path, "/nxcn.ttf"); - cnh_redir_add("nxcn.ttf", path_tmp); - free(path_tmp); - - path_tmp = util_str_merge(game_data_path, "/nxpt.ttf"); - cnh_redir_add("nxpt.ttf", path_tmp); - free(path_tmp); - - path_tmp = util_str_merge(game_data_path, "/nxtw.ttf"); - cnh_redir_add("nxtw.ttf", path_tmp); - free(path_tmp); -} - -static void nxahook_fs_redir_mission(struct nxahook_options* options, const char* game_data_path) -{ - log_assert(options); - log_assert(game_data_path); - - char* path_tmp; - - /* mission.txt, game expects lower case file */ - path_tmp = util_str_merge(game_data_path, "/mission.txt"); - cnh_redir_add("/mission.txt", path_tmp); - free(path_tmp); - - /* ufo.txt, game expects lower case file */ - path_tmp = util_str_merge(game_data_path, "/ufo.txt"); - cnh_redir_add("/ufo.txt", path_tmp); - free(path_tmp); + /* ufo.txt, game expects lower case file */ + path_tmp = util_str_merge(game_data_path, "/ufo.txt"); + cnh_redir_add("/ufo.txt", path_tmp); + free(path_tmp); } static void nxahook_fs_redir_usb() { - /* Needed on newer kernels */ - cnh_redir_add("/proc/bus/usb/devices", "/sys/kernel/debug/usb/devices"); - patch_usbfs_init(); + /* Needed on newer kernels */ + cnh_redir_add("/proc/bus/usb/devices", "/sys/kernel/debug/usb/devices"); + patch_usbfs_init(); } -static void nxahook_fs_redirs_init(struct nxahook_options* options, const char* game_data_path) +static void nxahook_fs_redirs_init( + struct nxahook_options *options, const char *game_data_path) { - log_assert(options); - log_assert(game_data_path); + log_assert(options); + log_assert(game_data_path); - /* Expecting all assets in the piu game (asset) folder. redirects for files - that are not in there by default for reasons */ - nxahook_fs_redir_settings(options); - nxahook_fs_redir_script(options, game_data_path); - nxahook_fs_redir_fonts(options, game_data_path); - nxahook_fs_redir_mission(options, game_data_path); + /* Expecting all assets in the piu game (asset) folder. redirects for files + that are not in there by default for reasons */ + nxahook_fs_redir_settings(options); + nxahook_fs_redir_script(options, game_data_path); + nxahook_fs_redir_fonts(options, game_data_path); + nxahook_fs_redir_mission(options, game_data_path); - nxahook_fs_redir_usb(); + nxahook_fs_redir_usb(); } static void nxahook_patch_fs_mounting_init() { - patch_mounts_init(); + patch_mounts_init(); - patch_usb_mnt_init(); - patch_usb_unlock_init(); + patch_usb_mnt_init(); + patch_usb_unlock_init(); } -static void nxahook_patch_gfx_init(struct nxahook_options* options) +static void nxahook_patch_gfx_init(struct nxahook_options *options) { - log_assert(options); + log_assert(options); - patch_gfx_init(); + patch_gfx_init(); - if (options->patch.gfx.windowed) { - patch_gfx_force_window_mode(); - } + if (options->patch.gfx.windowed) { + patch_gfx_force_window_mode(); + } } -static void nxahook_patch_main_loop_init(struct nxahook_options* options) +static void nxahook_patch_main_loop_init(struct nxahook_options *options) { - log_assert(options); + log_assert(options); - patch_main_loop_init(false, options->patch.main_loop.disable_built_in_inputs, false); + patch_main_loop_init( + false, options->patch.main_loop.disable_built_in_inputs, false); - if (options->patch.main_loop.x11_input_handler_api_lib) { - char* abs_path_x11_input_hook_lib = util_fs_get_abs_path(options->patch.main_loop.x11_input_handler_api_lib); + if (options->patch.main_loop.x11_input_handler_api_lib) { + char *abs_path_x11_input_hook_lib = util_fs_get_abs_path( + options->patch.main_loop.x11_input_handler_api_lib); - patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); - free(abs_path_x11_input_hook_lib); - } + patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); + free(abs_path_x11_input_hook_lib); + } } -static void nxahook_patch_sound_init(struct nxahook_options* options) +static void nxahook_patch_sound_init(struct nxahook_options *options) { - log_assert(options); + log_assert(options); - patch_sound_init(options->patch.sound.device); + patch_sound_init(options->patch.sound.device); } -static void nxahook_patch_sigsegv_init(struct nxahook_options* options) +static void nxahook_patch_sigsegv_init(struct nxahook_options *options) { - log_assert(options); + log_assert(options); - patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); + patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); } static void nxahook_patch_dongle_init() { - patch_microdog40_init((const uint8_t*) _binary_nxahook_dog_key_start, - ((uintptr_t) &_binary_nxahook_dog_key_end - (uintptr_t) &_binary_nxahook_dog_key_start)); + patch_microdog40_init( + (const uint8_t *) _binary_nxahook_dog_key_start, + ((uintptr_t) &_binary_nxahook_dog_key_end - + (uintptr_t) &_binary_nxahook_dog_key_start)); } static void nxahook_patch_hdd_check_init() { - patch_hdd_check_init((const uint8_t*) _binary_nxahook_hdd_raw_start, - ((uintptr_t) &_binary_nxahook_hdd_raw_end - (uintptr_t) &_binary_nxahook_hdd_raw_start)); + patch_hdd_check_init( + (const uint8_t *) _binary_nxahook_hdd_raw_start, + ((uintptr_t) &_binary_nxahook_hdd_raw_end - + (uintptr_t) &_binary_nxahook_hdd_raw_start)); } -static void nxahook_patch_piuio_init(struct nxahook_options* options) +static void nxahook_patch_piuio_init(struct nxahook_options *options) { - log_assert(options); + log_assert(options); - /* Hook before IO emulation */ - if (options->patch.piuio.exit_test_serv) { - patch_piuio_exit_init(); - } + /* Hook before IO emulation */ + if (options->patch.piuio.exit_test_serv) { + patch_piuio_exit_init(); + } - patch_usb_init_fix_init(); - patch_usb_emu_init(); + patch_usb_init_fix_init(); + patch_usb_emu_init(); - if (options->patch.piuio.api_lib) { - char* abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); + if (options->patch.piuio.api_lib) { + char *abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); - patch_piuio_init(abs_path_iolib); - free(abs_path_iolib); - } + patch_piuio_init(abs_path_iolib); + free(abs_path_iolib); + } } static void nxahook_patch_profile() { - nxahook_profile_gen_init(); + nxahook_profile_gen_init(); } void nxahook_constructor(void) { - /* Nothing here */ + /* Nothing here */ } void nxahook_destructor(void) { - /* Nothing here */ + /* Nothing here */ } -void nxahook_trap_before_main(int argc, char** argv) +void nxahook_trap_before_main(int argc, char **argv) { - log_assert(argc >= 0); - log_assert(argv); + log_assert(argc >= 0); + log_assert(argv); - char* game_data_path; - struct nxahook_options options; + char *game_data_path; + struct nxahook_options options; - nxahook_bootstrapping(argc, argv, &options, &game_data_path); - nxahook_patch_fs_init(&options); - nxahook_fs_redirs_init(&options, game_data_path); - nxahook_patch_fs_mounting_init(); - nxahook_patch_gfx_init(&options); - nxahook_patch_main_loop_init(&options); - nxahook_patch_sound_init(&options); - nxahook_patch_sigsegv_init(&options); - nxahook_patch_dongle_init(); - nxahook_patch_hdd_check_init(); - nxahook_patch_piuio_init(&options); - nxahook_patch_profile(); + nxahook_bootstrapping(argc, argv, &options, &game_data_path); + nxahook_patch_fs_init(&options); + nxahook_fs_redirs_init(&options, game_data_path); + nxahook_patch_fs_mounting_init(); + nxahook_patch_gfx_init(&options); + nxahook_patch_main_loop_init(&options); + nxahook_patch_sound_init(&options); + nxahook_patch_sigsegv_init(&options); + nxahook_patch_dongle_init(); + nxahook_patch_hdd_check_init(); + nxahook_patch_piuio_init(&options); + nxahook_patch_profile(); - free(game_data_path); + free(game_data_path); - log_info("Hooking finished"); + log_info("Hooking finished"); } void nxahook_trap_after_main(void) { - patch_piuio_shutdown(); + patch_piuio_shutdown(); } LIB_MAIN_CONSTRUCTOR(nxahook_constructor); diff --git a/src/main/hook/nxa/options.c b/src/main/hook/nxa/options.c index c3e6451..b23100a 100644 --- a/src/main/hook/nxa/options.c +++ b/src/main/hook/nxa/options.c @@ -9,14 +9,19 @@ #define NXAHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO "patch.hook_mon.io" #define NXAHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN "patch.hook_mon.open" #define NXAHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB "patch.hook_mon.usb" -#define NXAHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS "patch.hook_main_loop.disable_built_in_inputs" -#define NXAHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER "patch_hook_main_loop.x11_input_handler" +#define NXAHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS \ + "patch.hook_main_loop.disable_built_in_inputs" +#define NXAHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER \ + "patch_hook_main_loop.x11_input_handler" #define NXAHOOK_OPTIONS_STR_PATCH_NET_PROFILE_SERVER "patch.net_profile.server" -#define NXAHOOK_OPTIONS_STR_PATCH_NET_PROFILE_MACHINE_ID "patch.net_profile.machine_id" +#define NXAHOOK_OPTIONS_STR_PATCH_NET_PROFILE_MACHINE_ID \ + "patch.net_profile.machine_id" #define NXAHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB "patch.piuio.emu_lib" -#define NXAHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV "patch.piuio_exit.test_serv" +#define NXAHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV \ + "patch.piuio_exit.test_serv" #define NXAHOOK_OPTIONS_STR_PATCH_SOUND_DEVICE "patch.sound.device" -#define NXAHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV "patch.sigsegv.halt_on_segv" +#define NXAHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV \ + "patch.sigsegv.halt_on_segv" #define NXAHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE "util.log.file" #define NXAHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL "util.log.level" @@ -71,22 +76,26 @@ const struct util_options_def nxahook_options_def[] = { .default_value.b = false, }, { - .name = NXAHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS, - .description = "Disable the built in keyboard inputs for test (F1), service (F2) and clear (F3)", + .name = + NXAHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS, + .description = "Disable the built in keyboard inputs for test (F1), " + "service (F2) and clear (F3)", .param = 'k', .type = UTIL_OPTIONS_TYPE_BOOL, .default_value.b = false, }, { .name = NXAHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER, - .description = "Path to a library implementing the x11-input-handler api to capture X11 keyboard inputs", + .description = "Path to a library implementing the x11-input-handler " + "api to capture X11 keyboard inputs", .param = 'q', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, }, { .name = NXAHOOK_OPTIONS_STR_PATCH_NET_PROFILE_SERVER, - .description = "Address and port of pumpnet server (e.g. 127.0.0.1:1234)", + .description = + "Address and port of pumpnet server (e.g. 127.0.0.1:1234)", .param = 'n', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, @@ -100,7 +109,8 @@ const struct util_options_def nxahook_options_def[] = { }, { .name = NXAHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB, - .description = "Path to library implementing the piuio api for piuio emulation", + .description = + "Path to library implementing the piuio api for piuio emulation", .param = 'p', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, @@ -151,45 +161,59 @@ const struct util_options_defs nxahook_options_defs = { .ndefs = lengthof(nxahook_options_def) }; -bool nxahook_options_init(int argc, char** argv, struct nxahook_options* options) +bool nxahook_options_init( + int argc, char **argv, struct nxahook_options *options) { - log_assert(argv); - log_assert(options); + log_assert(argv); + log_assert(options); - struct util_options_opts* options_opt; + struct util_options_opts *options_opt; - util_options_init(argc, argv); - options_opt = util_options_get(&nxahook_options_defs); + util_options_init(argc, argv); + options_opt = util_options_get(&nxahook_options_defs); - if (!options_opt) { - return false; - } + if (!options_opt) { + return false; + } - options->game.settings = util_options_get_str(options_opt, NXAHOOK_OPTIONS_STR_GAME_SETTINGS); - options->patch.gfx.windowed = util_options_get_bool(options_opt, NXAHOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); - options->patch.hook_mon.file = util_options_get_bool(options_opt, NXAHOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); - options->patch.hook_mon.fs = util_options_get_bool(options_opt, NXAHOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); - options->patch.hook_mon.io = util_options_get_bool(options_opt, NXAHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); - options->patch.hook_mon.open = util_options_get_bool(options_opt, NXAHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); - options->patch.hook_mon.usb = util_options_get_bool(options_opt, NXAHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); - options->patch.main_loop.disable_built_in_inputs = util_options_get_bool(options_opt, - NXAHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); - options->patch.main_loop.x11_input_handler_api_lib = - util_options_get_str(options_opt, NXAHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); - options->patch.net.server = util_options_get_str(options_opt, NXAHOOK_OPTIONS_STR_PATCH_NET_PROFILE_SERVER); - options->patch.net.machine_id = strtoul( - util_options_get_str(options_opt, NXAHOOK_OPTIONS_STR_PATCH_NET_PROFILE_MACHINE_ID), - NULL, - 16); - options->patch.piuio.api_lib = util_options_get_str(options_opt, NXAHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); - options->patch.piuio.exit_test_serv = - util_options_get_bool(options_opt, NXAHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); - options->patch.sound.device = util_options_get_str(options_opt, NXAHOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); - options->patch.sigsegv.halt_on_segv = - util_options_get_bool(options_opt, NXAHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); - options->log.file = util_options_get_str(options_opt, NXAHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); - options->log.level = - (enum util_log_level) util_options_get_int(options_opt, NXAHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); + options->game.settings = + util_options_get_str(options_opt, NXAHOOK_OPTIONS_STR_GAME_SETTINGS); + options->patch.gfx.windowed = util_options_get_bool( + options_opt, NXAHOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); + options->patch.hook_mon.file = util_options_get_bool( + options_opt, NXAHOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); + options->patch.hook_mon.fs = + util_options_get_bool(options_opt, NXAHOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); + options->patch.hook_mon.io = + util_options_get_bool(options_opt, NXAHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); + options->patch.hook_mon.open = util_options_get_bool( + options_opt, NXAHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); + options->patch.hook_mon.usb = util_options_get_bool( + options_opt, NXAHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); + options->patch.main_loop.disable_built_in_inputs = util_options_get_bool( + options_opt, + NXAHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); + options->patch.main_loop.x11_input_handler_api_lib = util_options_get_str( + options_opt, NXAHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); + options->patch.net.server = util_options_get_str( + options_opt, NXAHOOK_OPTIONS_STR_PATCH_NET_PROFILE_SERVER); + options->patch.net.machine_id = strtoul( + util_options_get_str( + options_opt, NXAHOOK_OPTIONS_STR_PATCH_NET_PROFILE_MACHINE_ID), + NULL, + 16); + options->patch.piuio.api_lib = util_options_get_str( + options_opt, NXAHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); + options->patch.piuio.exit_test_serv = util_options_get_bool( + options_opt, NXAHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); + options->patch.sound.device = + util_options_get_str(options_opt, NXAHOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); + options->patch.sigsegv.halt_on_segv = util_options_get_bool( + options_opt, NXAHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); + options->log.file = util_options_get_str( + options_opt, NXAHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); + options->log.level = (enum util_log_level) util_options_get_int( + options_opt, NXAHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); - return true; + return true; } \ No newline at end of file diff --git a/src/main/hook/nxa/options.h b/src/main/hook/nxa/options.h index 32030e5..b30864c 100644 --- a/src/main/hook/nxa/options.h +++ b/src/main/hook/nxa/options.h @@ -7,53 +7,54 @@ #include "util/log.h" struct nxahook_options { - struct game { - const char* settings; - } game; + struct game { + const char *settings; + } game; - struct patch { - struct gfx { - bool windowed; - } gfx; + struct patch { + struct gfx { + bool windowed; + } gfx; - struct hook_mon { - bool file; - bool fs; - bool io; - bool open; - bool usb; - } hook_mon; + struct hook_mon { + bool file; + bool fs; + bool io; + bool open; + bool usb; + } hook_mon; - struct main_loop { - bool disable_built_in_inputs; - const char* x11_input_handler_api_lib; - } main_loop; + struct main_loop { + bool disable_built_in_inputs; + const char *x11_input_handler_api_lib; + } main_loop; - struct net { - const char* server; - uint32_t machine_id; - } net; + struct net { + const char *server; + uint32_t machine_id; + } net; - struct piuio { - const char* api_lib; - bool exit_test_serv; - } piuio; + struct piuio { + const char *api_lib; + bool exit_test_serv; + } piuio; - struct sound { - const char* device; - } sound; + struct sound { + const char *device; + } sound; - struct sigsegv { - bool halt_on_segv; - } sigsegv; - } patch; + struct sigsegv { + bool halt_on_segv; + } sigsegv; + } patch; - struct log { - const char* file; - enum util_log_level level; - } log; + struct log { + const char *file; + enum util_log_level level; + } log; }; -bool nxahook_options_init(int argc, char** argv, struct nxahook_options* options); +bool nxahook_options_init( + int argc, char **argv, struct nxahook_options *options); #endif diff --git a/src/main/hook/nxa/profile-gen.c b/src/main/hook/nxa/profile-gen.c index c9e93ce..ee83d51 100644 --- a/src/main/hook/nxa/profile-gen.c +++ b/src/main/hook/nxa/profile-gen.c @@ -12,97 +12,103 @@ static bool nxahook_profile_gen_is_creating_file; -// Do not use util_fs_path_exists here as this fopens and causes an endless recursion -static bool nxahook_profile_gen_check_if_exists(const char* path) +// Do not use util_fs_path_exists here as this fopens and causes an endless +// recursion +static bool nxahook_profile_gen_check_if_exists(const char *path) { - return access(path, F_OK) != -1; + return access(path, F_OK) != -1; } -static enum cnh_result nxahook_profile_gen_filehook(struct cnh_filehook_irp *irp) +static enum cnh_result +nxahook_profile_gen_filehook(struct cnh_filehook_irp *irp) { - // nx2hook_profile_gen_is_creating_file: Avoid recursion of any file calls when creating the save/rank files - if (irp->op != CNH_FILEHOOK_IRP_OP_OPEN || nxahook_profile_gen_is_creating_file) { - return cnh_filehook_invoke_next(irp); - } - - if (util_str_ends_with(irp->open_filename, "nxasave.bin") && - !nxahook_profile_gen_check_if_exists(irp->open_filename)) { - char* path_only; - char* path_nx2; - struct asset_nxa_usb_save* save; - - nxahook_profile_gen_is_creating_file = true; - - /* Check if a nx2save.bin exists and skip generating a new nxasave - file because the game migrates everything from the nx2 file */ - path_only = util_fs_get_path_to_file(irp->open_filename); - path_nx2 = util_str_merge(path_only, "/nx2save.bin"); - free(path_only); - - if (util_fs_path_exists(path_nx2)) { - free(path_nx2); - log_info("nx2save.bin exists, don't create new nxasave.bin"); - nxahook_profile_gen_is_creating_file = false; - return cnh_filehook_invoke_next(irp); - } - - free(path_nx2); - - save = asset_nxa_usb_save_new(); - asset_nxa_usb_save_finalize(save); - - log_info("No %s file found, generate new", irp->open_filename); - - if (!asset_nxa_usb_save_save_to_file(irp->open_filename, save, true)) { - log_error("Saving generated nxasave.bin file to %s failed", irp->open_filename); - } - - free(save); - - nxahook_profile_gen_is_creating_file = false; - } - - if (util_str_ends_with(irp->open_filename, "nxarank.bin") && - !nxahook_profile_gen_check_if_exists(irp->open_filename)) { - char* path_only; - char* path_nx2; - struct asset_nxa_usb_rank* rank; - - nxahook_profile_gen_is_creating_file = true; - - /* Check if a nx2rank.bin exists and skip generating a new nxarank - file because the game migrates everything from the nx2 file */ - path_only = util_fs_get_path_to_file(irp->open_filename); - path_nx2 = util_str_merge(path_only, "/nx2rank.bin"); - free(path_only); - - if (util_fs_path_exists(path_nx2)) { - free(path_nx2); - log_info("nx2rank.bin exists, don't create new nxarank.bin"); - nxahook_profile_gen_is_creating_file = false; - return cnh_filehook_invoke_next(irp); - } - - free(path_nx2); - - rank = asset_nxa_usb_rank_new(); - asset_nxa_usb_rank_finalize(rank); - - log_info("No %s file found, generate new", irp->open_filename); - - if (!asset_nxa_usb_rank_save_to_file(irp->open_filename, rank, true)) { - log_error("Saving generated nxarank.bin file to %s failed", irp->open_filename); - } - - free(rank); - - nxahook_profile_gen_is_creating_file = false; - } - + // nx2hook_profile_gen_is_creating_file: Avoid recursion of any file calls + // when creating the save/rank files + if (irp->op != CNH_FILEHOOK_IRP_OP_OPEN || + nxahook_profile_gen_is_creating_file) { return cnh_filehook_invoke_next(irp); + } + + if (util_str_ends_with(irp->open_filename, "nxasave.bin") && + !nxahook_profile_gen_check_if_exists(irp->open_filename)) { + char *path_only; + char *path_nx2; + struct asset_nxa_usb_save *save; + + nxahook_profile_gen_is_creating_file = true; + + /* Check if a nx2save.bin exists and skip generating a new nxasave + file because the game migrates everything from the nx2 file */ + path_only = util_fs_get_path_to_file(irp->open_filename); + path_nx2 = util_str_merge(path_only, "/nx2save.bin"); + free(path_only); + + if (util_fs_path_exists(path_nx2)) { + free(path_nx2); + log_info("nx2save.bin exists, don't create new nxasave.bin"); + nxahook_profile_gen_is_creating_file = false; + return cnh_filehook_invoke_next(irp); + } + + free(path_nx2); + + save = asset_nxa_usb_save_new(); + asset_nxa_usb_save_finalize(save); + + log_info("No %s file found, generate new", irp->open_filename); + + if (!asset_nxa_usb_save_save_to_file(irp->open_filename, save, true)) { + log_error( + "Saving generated nxasave.bin file to %s failed", irp->open_filename); + } + + free(save); + + nxahook_profile_gen_is_creating_file = false; + } + + if (util_str_ends_with(irp->open_filename, "nxarank.bin") && + !nxahook_profile_gen_check_if_exists(irp->open_filename)) { + char *path_only; + char *path_nx2; + struct asset_nxa_usb_rank *rank; + + nxahook_profile_gen_is_creating_file = true; + + /* Check if a nx2rank.bin exists and skip generating a new nxarank + file because the game migrates everything from the nx2 file */ + path_only = util_fs_get_path_to_file(irp->open_filename); + path_nx2 = util_str_merge(path_only, "/nx2rank.bin"); + free(path_only); + + if (util_fs_path_exists(path_nx2)) { + free(path_nx2); + log_info("nx2rank.bin exists, don't create new nxarank.bin"); + nxahook_profile_gen_is_creating_file = false; + return cnh_filehook_invoke_next(irp); + } + + free(path_nx2); + + rank = asset_nxa_usb_rank_new(); + asset_nxa_usb_rank_finalize(rank); + + log_info("No %s file found, generate new", irp->open_filename); + + if (!asset_nxa_usb_rank_save_to_file(irp->open_filename, rank, true)) { + log_error( + "Saving generated nxarank.bin file to %s failed", irp->open_filename); + } + + free(rank); + + nxahook_profile_gen_is_creating_file = false; + } + + return cnh_filehook_invoke_next(irp); } void nxahook_profile_gen_init(void) { - cnh_filehook_push_handler(nxahook_profile_gen_filehook); + cnh_filehook_push_handler(nxahook_profile_gen_filehook); } \ No newline at end of file diff --git a/src/main/hook/patch/amixer-block.c b/src/main/hook/patch/amixer-block.c index 6f65140..e8eb157 100644 --- a/src/main/hook/patch/amixer-block.c +++ b/src/main/hook/patch/amixer-block.c @@ -5,49 +5,49 @@ #include "util/log.h" #include "util/str.h" -typedef int (*system_t)(const char* command); -typedef int (*execv_t)(const char* path, char* const argv[]); +typedef int (*system_t)(const char *command); +typedef int (*execv_t)(const char *path, char *const argv[]); static bool patch_axmier_block_initialized; static system_t patch_amixer_block_real_system; static execv_t patch_amixer_block_real_execv; // for fst and fex -int system(const char* command) +int system(const char *command) { - if (!patch_amixer_block_real_system) { - patch_amixer_block_real_system = (system_t) cnh_lib_get_func_addr("system"); - } + if (!patch_amixer_block_real_system) { + patch_amixer_block_real_system = (system_t) cnh_lib_get_func_addr("system"); + } - if (patch_axmier_block_initialized) { - if (util_str_starts_with(command, "amixer")) { - log_info("Blocking call to amixer: %s", command); - return 0; - } + if (patch_axmier_block_initialized) { + if (util_str_starts_with(command, "amixer")) { + log_info("Blocking call to amixer: %s", command); + return 0; } + } - return patch_amixer_block_real_system(command); + return patch_amixer_block_real_system(command); } // for f2 and prime (yes, they figured using system() isn't a great idea...) -int execv(const char* path, char* const argv[]) +int execv(const char *path, char *const argv[]) { - if (!patch_amixer_block_real_execv) { - patch_amixer_block_real_execv = (execv_t) cnh_lib_get_func_addr("execv"); - } + if (!patch_amixer_block_real_execv) { + patch_amixer_block_real_execv = (execv_t) cnh_lib_get_func_addr("execv"); + } - if (patch_axmier_block_initialized) { - if (util_str_starts_with(path, "/usr/bin/amixer")) { - log_info("Blocking call to amixer: %s", path); - return 0; - } + if (patch_axmier_block_initialized) { + if (util_str_starts_with(path, "/usr/bin/amixer")) { + log_info("Blocking call to amixer: %s", path); + return 0; } + } - return patch_amixer_block_real_execv(path, argv); + return patch_amixer_block_real_execv(path, argv); } void patch_axmier_block_init(void) { - patch_axmier_block_initialized = true; - log_info("Initialized"); + patch_axmier_block_initialized = true; + log_info("Initialized"); } \ No newline at end of file diff --git a/src/main/hook/patch/asound-fix.c b/src/main/hook/patch/asound-fix.c index 37ebe71..3becadc 100644 --- a/src/main/hook/patch/asound-fix.c +++ b/src/main/hook/patch/asound-fix.c @@ -9,139 +9,161 @@ #include "util/mem.h" #include "util/str.h" -typedef int (*getgrnam_r_t)(const char *name, struct group *grp, char *buf, size_t buflen, struct group **result); +typedef int (*getgrnam_r_t)( + const char *name, + struct group *grp, + char *buf, + size_t buflen, + struct group **result); static getgrnam_r_t patch_asound_fix_real_getgrnam_r; -static char** patch_asound_fix_split_user_list_str(const char* user_list_str) +static char **patch_asound_fix_split_user_list_str(const char *user_list_str) { - char* user_list_str_cpy = util_str_dup(user_list_str); - char** user_list = util_xmalloc(sizeof(char*)); - size_t len_list = 1; + char *user_list_str_cpy = util_str_dup(user_list_str); + char **user_list = util_xmalloc(sizeof(char *)); + size_t len_list = 1; - char* ptr = strtok(user_list_str_cpy, ","); + char *ptr = strtok(user_list_str_cpy, ","); - while (ptr != NULL) { - // last token will likely read beyond newline to next : token for next group entry - char* new_line_char = strstr(ptr, "\n"); + while (ptr != NULL) { + // last token will likely read beyond newline to next : token for next group + // entry + char *new_line_char = strstr(ptr, "\n"); - if (new_line_char) { - *new_line_char = '\0'; - } - - len_list++; - user_list = util_xrealloc(user_list, len_list * sizeof(char*)); - - user_list[len_list - 2] = util_str_dup(ptr); - user_list[len_list - 1] = NULL; - - ptr = strtok(NULL, ","); + if (new_line_char) { + *new_line_char = '\0'; } - free(user_list_str_cpy); + len_list++; + user_list = util_xrealloc(user_list, len_list * sizeof(char *)); - return user_list; + user_list[len_list - 2] = util_str_dup(ptr); + user_list[len_list - 1] = NULL; + + ptr = strtok(NULL, ","); + } + + free(user_list_str_cpy); + + return user_list; } -static char* patch_asound_fix_user_list_to_str(char** user_list) +static char *patch_asound_fix_user_list_to_str(char **user_list) { - char** ptr = user_list; - char* str = util_str_dup("\0"); + char **ptr = user_list; + char *str = util_str_dup("\0"); - while (*ptr != NULL) { - char* mrg = util_str_merge(str, *ptr); - free(str); - str = util_str_merge(mrg, ","); - free(mrg); + while (*ptr != NULL) { + char *mrg = util_str_merge(str, *ptr); + free(str); + str = util_str_merge(mrg, ","); + free(mrg); - ptr++; - } + ptr++; + } - return str; + return str; } -int getgrnam_r(const char *name, struct group *grp, char *buf, size_t buflen, struct group **result) +int getgrnam_r( + const char *name, + struct group *grp, + char *buf, + size_t buflen, + struct group **result) { - if (!patch_asound_fix_real_getgrnam_r) { - patch_asound_fix_real_getgrnam_r = (getgrnam_r_t) cnh_lib_get_func_addr("getgrnam_r"); + if (!patch_asound_fix_real_getgrnam_r) { + patch_asound_fix_real_getgrnam_r = + (getgrnam_r_t) cnh_lib_get_func_addr("getgrnam_r"); + } + + // We expect to use the standard "audio" group here, otherwise detection of + // this is not possible. Intercept and execute the following re-implementation + // of the reading logic from file. I don't know if getgrnam_r usually reads + // from a cached version of /etc/group but I suppose that doesn't matter here. + if (!strcmp(name, "audio")) { + log_debug("Trapping getgrnam_r for audio group of libasound"); + + FILE *file = fopen("/etc/group", "r"); + + fseek(file, 0, SEEK_END); + size_t file_size = ftell(file); + fseek(file, 0, SEEK_SET); + + char *buffer = (char *) util_xmalloc(file_size); + + if (fread(buffer, file_size, 1, file) != 1) { + log_error("Reading /etc/group file failed: %s", strerror(errno)); + free(buffer); + *result = NULL; + return -1; } - // We expect to use the standard "audio" group here, otherwise detection of this is not possible. Intercept - // and execute the following re-implementation of the reading logic from file. I don't know if getgrnam_r usually - // reads from a cached version of /etc/group but I suppose that doesn't matter here. - if (!strcmp(name, "audio")) { - log_debug("Trapping getgrnam_r for audio group of libasound"); + char *str_audio_pos = strstr(buffer, name); - FILE* file = fopen("/etc/group", "r"); - - fseek(file, 0, SEEK_END); - size_t file_size = ftell(file); - fseek(file, 0, SEEK_SET); - - char* buffer = (char*) util_xmalloc(file_size); - - if (fread(buffer, file_size, 1, file) != 1) { - log_error("Reading /etc/group file failed: %s", strerror(errno)); - free(buffer); - *result = NULL; - return -1; - } - - char* str_audio_pos = strstr(buffer, name); - - if (str_audio_pos == NULL) { - log_error("Could not find 'audio' group in /etc/group required by libasound likely for defaults.pcm.ipc_gid" - " from asound.conf. Make sure the group exists."); - free(buffer); - *result = NULL; - return -1; - } - - char* tok = strtok(str_audio_pos, ":"); - uint8_t cnt = 0; - - while (tok != NULL) { - switch (cnt) { - case 0: - grp->gr_name = util_str_dup(tok); - break; - - case 1: - grp->gr_passwd = util_str_dup(tok); - break; - - case 2: - grp->gr_gid = strtol(tok, NULL, 10); - break; - - case 3: - grp->gr_mem = patch_asound_fix_split_user_list_str(tok); - break; - - default: - log_error("audio group entry format in /etc/group invalid. Check your /etc/group file!"); - free(buffer); - *result = NULL; - return -1; - } - - cnt++; - tok = strtok(NULL, ":"); - } - - char* grp_mem_str = patch_asound_fix_user_list_to_str(grp->gr_mem); - log_debug("Resulting group struct: %s %s %d %s", grp->gr_name, grp->gr_passwd, grp->gr_gid, grp_mem_str); - free(grp_mem_str); - - *result = grp; - - return 0; + if (str_audio_pos == NULL) { + log_error( + "Could not find 'audio' group in /etc/group required by libasound " + "likely for defaults.pcm.ipc_gid" + " from asound.conf. Make sure the group exists."); + free(buffer); + *result = NULL; + return -1; } - return patch_asound_fix_real_getgrnam_r(name, grp, buf, buflen, result); + char *tok = strtok(str_audio_pos, ":"); + uint8_t cnt = 0; + + while (tok != NULL) { + switch (cnt) { + case 0: + grp->gr_name = util_str_dup(tok); + break; + + case 1: + grp->gr_passwd = util_str_dup(tok); + break; + + case 2: + grp->gr_gid = strtol(tok, NULL, 10); + break; + + case 3: + grp->gr_mem = patch_asound_fix_split_user_list_str(tok); + break; + + default: + log_error( + "audio group entry format in /etc/group invalid. Check your " + "/etc/group file!"); + free(buffer); + *result = NULL; + return -1; + } + + cnt++; + tok = strtok(NULL, ":"); + } + + char *grp_mem_str = patch_asound_fix_user_list_to_str(grp->gr_mem); + log_debug( + "Resulting group struct: %s %s %d %s", + grp->gr_name, + grp->gr_passwd, + grp->gr_gid, + grp_mem_str); + free(grp_mem_str); + + *result = grp; + + return 0; + } + + return patch_asound_fix_real_getgrnam_r(name, grp, buf, buflen, result); } void patch_asound_fix_init() { - log_info("Initialized"); + log_info("Initialized"); } \ No newline at end of file diff --git a/src/main/hook/patch/asound-fix.h b/src/main/hook/patch/asound-fix.h index 67b8983..7d9ed36 100644 --- a/src/main/hook/patch/asound-fix.h +++ b/src/main/hook/patch/asound-fix.h @@ -1,16 +1,19 @@ /** - * Fix a quirk with getgrnam_r in the asound library always failing when loading the asound.conf file and reading the - * /etc/group file. For some reason, it cannot find the audio group entry even if it is available and can be read - * by other applications just fine. + * Fix a quirk with getgrnam_r in the asound library always failing when loading + * the asound.conf file and reading the /etc/group file. For some reason, it + * cannot find the audio group entry even if it is available and can be read by + * other applications just fine. * - * Your typical asound.conf, which is loaded by libasound in a application that uses it, contains the following line: - * defaults.pcm.ipc_gid audio + * Your typical asound.conf, which is loaded by libasound in a application that + * uses it, contains the following line: defaults.pcm.ipc_gid audio * - * Finding documentation about what this stuff does it difficult but judging by the name, this seems to be related to - * setting up shared memory IPC for reading and writing data to the sound driver. - * For some reason, this "fails" when the function getgrnam_r is called by libasound. The function itself returns - * successful but with no result. This function reads the entry from /etc/group. libsound queries the "audio" group - * in that case and even if the entry exists, the result is empty for some unknown reason. + * Finding documentation about what this stuff does it difficult but judging by + * the name, this seems to be related to setting up shared memory IPC for + * reading and writing data to the sound driver. For some reason, this "fails" + * when the function getgrnam_r is called by libasound. The function itself + * returns successful but with no result. This function reads the entry from + * /etc/group. libsound queries the "audio" group in that case and even if the + * entry exists, the result is empty for some unknown reason. * * This module fixes that issue. */ diff --git a/src/main/hook/patch/blacklist-url.c b/src/main/hook/patch/blacklist-url.c index cd28d99..9f63b3e 100644 --- a/src/main/hook/patch/blacklist-url.c +++ b/src/main/hook/patch/blacklist-url.c @@ -9,58 +9,60 @@ #include "util/mem.h" struct patch_blacklist_url_list_elem { - struct util_list_node head; - const char* url; + struct util_list_node head; + const char *url; }; -typedef int (*curl_easy_setopt_t)(int* handle, int option, void* param); +typedef int (*curl_easy_setopt_t)(int *handle, int option, void *param); static bool patch_blacklist_url_initialized; static curl_easy_setopt_t patch_blacklist_url_real_curl_easy_setopt; static struct util_list patch_blacklist_url_list; -int curl_easy_setopt(int* handle, int option, void* param) +int curl_easy_setopt(int *handle, int option, void *param) { - if (!patch_blacklist_url_real_curl_easy_setopt) { - patch_blacklist_url_real_curl_easy_setopt = (curl_easy_setopt_t) cnh_lib_get_func_addr("curl_easy_setopt"); - } + if (!patch_blacklist_url_real_curl_easy_setopt) { + patch_blacklist_url_real_curl_easy_setopt = + (curl_easy_setopt_t) cnh_lib_get_func_addr("curl_easy_setopt"); + } - if (patch_blacklist_url_initialized) { + if (patch_blacklist_url_initialized) { - /* option == 10002 to identify that param has a string */ - if (option == 10002) { + /* option == 10002 to identify that param has a string */ + if (option == 10002) { - struct util_list_node* pos; - struct patch_blacklist_url_list_elem* elem; + struct util_list_node *pos; + struct patch_blacklist_url_list_elem *elem; - for (pos = patch_blacklist_url_list.head; pos != NULL; pos = pos->next) { - elem = containerof(pos, struct patch_blacklist_url_list_elem, head); + for (pos = patch_blacklist_url_list.head; pos != NULL; pos = pos->next) { + elem = containerof(pos, struct patch_blacklist_url_list_elem, head); - if (!memcmp(param, elem->url, strlen(elem->url))) { - log_debug("Blocking url %s", elem->url); - return patch_blacklist_url_real_curl_easy_setopt(handle, option, (void*) "does-not-exist"); - } - } + if (!memcmp(param, elem->url, strlen(elem->url))) { + log_debug("Blocking url %s", elem->url); + return patch_blacklist_url_real_curl_easy_setopt( + handle, option, (void *) "does-not-exist"); } + } } + } - return patch_blacklist_url_real_curl_easy_setopt(handle, option, param); + return patch_blacklist_url_real_curl_easy_setopt(handle, option, param); } void patch_blacklist_url_init(void) { - util_list_init(&patch_blacklist_url_list); - patch_blacklist_url_initialized = true; - log_info("Initialized"); + util_list_init(&patch_blacklist_url_list); + patch_blacklist_url_initialized = true; + log_info("Initialized"); } -void patch_blacklist_url_add(const char* url) +void patch_blacklist_url_add(const char *url) { - struct patch_blacklist_url_list_elem* elem; + struct patch_blacklist_url_list_elem *elem; - elem = util_xmalloc(sizeof(struct patch_blacklist_url_list_elem)); - elem->url = strdup(url); + elem = util_xmalloc(sizeof(struct patch_blacklist_url_list_elem)); + elem->url = strdup(url); - util_list_append(&patch_blacklist_url_list, &elem->head); - log_info("Add url %s to blacklist", url); + util_list_append(&patch_blacklist_url_list, &elem->head); + log_info("Add url %s to blacklist", url); } \ No newline at end of file diff --git a/src/main/hook/patch/blacklist-url.h b/src/main/hook/patch/blacklist-url.h index 5e69d7d..fe1fc86 100644 --- a/src/main/hook/patch/blacklist-url.h +++ b/src/main/hook/patch/blacklist-url.h @@ -14,6 +14,6 @@ void patch_blacklist_url_init(void); * * @param url Url to block */ -void patch_blacklist_url_add(const char* url); +void patch_blacklist_url_add(const char *url); #endif \ No newline at end of file diff --git a/src/main/hook/patch/block-keyboard-grab.c b/src/main/hook/patch/block-keyboard-grab.c index 7614fed..4b64ca2 100644 --- a/src/main/hook/patch/block-keyboard-grab.c +++ b/src/main/hook/patch/block-keyboard-grab.c @@ -1,36 +1,49 @@ #define LOG_MODULE "block-keyboard-grab" -#include #include +#include #include "capnhook/hook/lib.h" #include "util/log.h" -typedef int (*XGrabKeyboard_t)(Display* display, Window window, Bool owner_events, int pointer_mode, int keyboard_mode, - Time time); +typedef int (*XGrabKeyboard_t)( + Display *display, + Window window, + Bool owner_events, + int pointer_mode, + int keyboard_mode, + Time time); static XGrabKeyboard_t _patch_main_loop_real_XGrabKeyboard; static bool _patch_block_keyboard_grab_enable; -int XGrabKeyboard(Display* display, Window window, Bool owner_events, int pointer_mode, int keyboard_mode, Time time) +int XGrabKeyboard( + Display *display, + Window window, + Bool owner_events, + int pointer_mode, + int keyboard_mode, + Time time) { - if (!_patch_main_loop_real_XGrabKeyboard) { - _patch_main_loop_real_XGrabKeyboard = (XGrabKeyboard_t) cnh_lib_get_func_addr("XGrabKeyboard"); - } + if (!_patch_main_loop_real_XGrabKeyboard) { + _patch_main_loop_real_XGrabKeyboard = + (XGrabKeyboard_t) cnh_lib_get_func_addr("XGrabKeyboard"); + } - if (_patch_block_keyboard_grab_enable) { - log_debug("Block keyboard grabbing"); - return 0; - } + if (_patch_block_keyboard_grab_enable) { + log_debug("Block keyboard grabbing"); + return 0; + } - return _patch_main_loop_real_XGrabKeyboard(display, window, owner_events, pointer_mode, keyboard_mode, time); + return _patch_main_loop_real_XGrabKeyboard( + display, window, owner_events, pointer_mode, keyboard_mode, time); } void patch_block_keyboard_grab_init() { - _patch_block_keyboard_grab_enable = true; + _patch_block_keyboard_grab_enable = true; - log_info("Initialized"); + log_info("Initialized"); } \ No newline at end of file diff --git a/src/main/hook/patch/block-keyboard-grab.h b/src/main/hook/patch/block-keyboard-grab.h index 1b9d767..e508486 100644 --- a/src/main/hook/patch/block-keyboard-grab.h +++ b/src/main/hook/patch/block-keyboard-grab.h @@ -2,8 +2,8 @@ #define PATCH_BLOCK_KEYBOARD_GRAB_H /** - * Enable blocking of X11 keyboard grabbing which causes Prime to not go to window mode and behave weird on desktop - * machines. + * Enable blocking of X11 keyboard grabbing which causes Prime to not go to + * window mode and behave weird on desktop machines. */ void patch_block_keyboard_grab_init(); diff --git a/src/main/hook/patch/gfx.c b/src/main/hook/patch/gfx.c index e093bbe..ba53149 100644 --- a/src/main/hook/patch/gfx.c +++ b/src/main/hook/patch/gfx.c @@ -1,7 +1,7 @@ #define LOG_MODULE "patch-gfx" -#include #include +#include #include "capnhook/hook/lib.h" @@ -10,11 +10,22 @@ #include "gfx.h" -typedef Window (*XCreateWindow_t)(Display *display, Window parent, int x, int y, unsigned int width, - unsigned int height, unsigned int border_width, int depth, unsigned int _class, Visual *visual, - unsigned long valuemask, XSetWindowAttributes *attributes); -typedef Display* (*XOpenDisplay_t)(const char *display_name); -typedef XVisualInfo* (*glXChooseVisual_t)(Display *dpy, int screen, int *attribList); +typedef Window (*XCreateWindow_t)( + Display *display, + Window parent, + int x, + int y, + unsigned int width, + unsigned int height, + unsigned int border_width, + int depth, + unsigned int _class, + Visual *visual, + unsigned long valuemask, + XSetWindowAttributes *attributes); +typedef Display *(*XOpenDisplay_t)(const char *display_name); +typedef XVisualInfo *(*glXChooseVisual_t)( + Display *dpy, int screen, int *attribList); static bool patch_gfx_force_window = false; @@ -23,103 +34,138 @@ static XCreateWindow_t patch_gfx_real_XCreateWindow; static XOpenDisplay_t patch_gfx_real_XOpenDisplay; static glXChooseVisual_t patch_gfx_real_GlXChooseVisual; -static char* patch_gfx_attrib_list_to_str(int* attrib_list) +static char *patch_gfx_attrib_list_to_str(int *attrib_list) { - int* ptr = attrib_list; - char* str = util_str_dup(""); - char buf[32]; + int *ptr = attrib_list; + char *str = util_str_dup(""); + char buf[32]; - while (*ptr != None) { - sprintf(buf, "%d, ", *ptr); + while (*ptr != None) { + sprintf(buf, "%d, ", *ptr); - char* tmp = util_str_merge(str, buf); + char *tmp = util_str_merge(str, buf); - free(str); - str = tmp; + free(str); + str = tmp; - ptr++; - } + ptr++; + } - return str; + return str; } -Window XCreateWindow(Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, - unsigned int border_width, int depth, unsigned int _class, Visual *visual, unsigned long valuemask, - XSetWindowAttributes *attributes) +Window XCreateWindow( + Display *display, + Window parent, + int x, + int y, + unsigned int width, + unsigned int height, + unsigned int border_width, + int depth, + unsigned int _class, + Visual *visual, + unsigned long valuemask, + XSetWindowAttributes *attributes) { - log_debug("XCreateWindow"); + log_debug("XCreateWindow"); - if (!patch_gfx_real_XCreateWindow) { - patch_gfx_real_XCreateWindow = (XCreateWindow_t) cnh_lib_get_func_addr("XCreateWindow"); + if (!patch_gfx_real_XCreateWindow) { + patch_gfx_real_XCreateWindow = + (XCreateWindow_t) cnh_lib_get_func_addr("XCreateWindow"); + } + + if (patch_gfx_initialized) { + + if (valuemask == 0x80A) { + log_info("Patching to enable usage of non nvidia cards."); + /* enables usage of non nvidia cards and newer nvidia models */ + valuemask = 0x280A; } + } - if (patch_gfx_initialized) { + if (patch_gfx_force_window) { + log_info("Forcing window mode"); + attributes->override_redirect = 0; + } - if (valuemask == 0x80A) { - log_info("Patching to enable usage of non nvidia cards."); - /* enables usage of non nvidia cards and newer nvidia models */ - valuemask = 0x280A; - } - } - - if (patch_gfx_force_window) { - log_info("Forcing window mode"); - attributes->override_redirect = 0; - } - - return patch_gfx_real_XCreateWindow(display, parent, x, y, width, height, border_width, depth, _class, visual, - valuemask, attributes); + return patch_gfx_real_XCreateWindow( + display, + parent, + x, + y, + width, + height, + border_width, + depth, + _class, + visual, + valuemask, + attributes); } Display *XOpenDisplay(const char *display_name) { - if (!patch_gfx_real_XOpenDisplay) { - patch_gfx_real_XOpenDisplay = (XOpenDisplay_t) cnh_lib_get_func_addr("XOpenDisplay"); - } + if (!patch_gfx_real_XOpenDisplay) { + patch_gfx_real_XOpenDisplay = + (XOpenDisplay_t) cnh_lib_get_func_addr("XOpenDisplay"); + } - log_info("XOpenDisplay: %s", display_name); + log_info("XOpenDisplay: %s", display_name); - Display* res = patch_gfx_real_XOpenDisplay(display_name); + Display *res = patch_gfx_real_XOpenDisplay(display_name); - if (!res) { - log_error("XOpenDisplay returned NULL. This might indicate that your environment is not properly setup. Check " - " that you have GPU drivers installed and configured properly and that OpenGL hardware acceleration is " - " working (use the command line tool \"glxinfo\")."); - } + if (!res) { + log_error( + "XOpenDisplay returned NULL. This might indicate that your environment " + "is not properly setup. Check " + " that you have GPU drivers installed and configured properly and that " + "OpenGL hardware acceleration is " + " working (use the command line tool \"glxinfo\")."); + } - return res; + return res; } -XVisualInfo* glXChooseVisual(Display *dpy, int screen, int *attribList) +XVisualInfo *glXChooseVisual(Display *dpy, int screen, int *attribList) { - if (!patch_gfx_real_GlXChooseVisual) { - patch_gfx_real_GlXChooseVisual = (glXChooseVisual_t) cnh_lib_get_func_addr("glXChooseVisual"); - } + if (!patch_gfx_real_GlXChooseVisual) { + patch_gfx_real_GlXChooseVisual = + (glXChooseVisual_t) cnh_lib_get_func_addr("glXChooseVisual"); + } - char* attrib_list_str =patch_gfx_attrib_list_to_str(attribList); + char *attrib_list_str = patch_gfx_attrib_list_to_str(attribList); - log_info("glXChooseVisual: dpy %p, screen %d, attribList %s", dpy, screen, attrib_list_str); + log_info( + "glXChooseVisual: dpy %p, screen %d, attribList %s", + dpy, + screen, + attrib_list_str); - free(attrib_list_str); + free(attrib_list_str); - XVisualInfo* res = patch_gfx_real_GlXChooseVisual(dpy, screen, attribList); + XVisualInfo *res = patch_gfx_real_GlXChooseVisual(dpy, screen, attribList); - if (!res) { - log_error("glXChooseVisual returned NULL. It is likely that your current environment does support hardware" - "acceleration. Either you do not have any GPU drivers installed or the drivers are not configured " - "properly. Fix that and use the command line tool \"glxinfo\" for debugging this."); - } + if (!res) { + log_error( + "glXChooseVisual returned NULL. It is likely that your current " + "environment does support hardware" + "acceleration. Either you do not have any GPU drivers installed or the " + "drivers are not configured " + "properly. Fix that and use the command line tool \"glxinfo\" for " + "debugging this."); + } - return res; + return res; } void patch_gfx_init() { - patch_gfx_initialized = true; - log_info("Initialized"); + patch_gfx_initialized = true; + log_info("Initialized"); } void patch_gfx_force_window_mode() { - patch_gfx_force_window = true; + patch_gfx_force_window = true; } \ No newline at end of file diff --git a/src/main/hook/patch/hasp.c b/src/main/hook/patch/hasp.c index a90177e..43c7f93 100644 --- a/src/main/hook/patch/hasp.c +++ b/src/main/hook/patch/hasp.c @@ -6,58 +6,75 @@ #include "util/patch.h" static const uint8_t patch_hasp_login_sig[] = { - 0x00, 0xB8, 0x16, 0x00, - 0x00, 0x00, 0x8B, 0x4C, - 0x24, 0x14, 0x8B, 0x74, - 0x24, 0x10, 0x8B, 0x54 -}; + 0x00, + 0xB8, + 0x16, + 0x00, + 0x00, + 0x00, + 0x8B, + 0x4C, + 0x24, + 0x14, + 0x8B, + 0x74, + 0x24, + 0x10, + 0x8B, + 0x54}; static const uint8_t patch_hasp_id_sig[] = { - 0x53, 0x83, 0xEC, 0x48, - 0xC7, 0x44, 0x24, 0x10 -}; + 0x53, 0x83, 0xEC, 0x48, 0xC7, 0x44, 0x24, 0x10}; -void patch_hasp_init(const uint8_t* key_data, size_t len) +void patch_hasp_init(const uint8_t *key_data, size_t len) { - void* func_api_login; - void* func_api_logout; - void* func_api_decrypt; - void* func_api_getid; + void *func_api_login; + void *func_api_logout; + void *func_api_decrypt; + void *func_api_getid; - func_api_login = util_patch_find_signiture(patch_hasp_login_sig, - sizeof(patch_hasp_login_sig), -16, (void*) 0x80c0000, (void*) 0x80f0000, - 16); + func_api_login = util_patch_find_signiture( + patch_hasp_login_sig, + sizeof(patch_hasp_login_sig), + -16, + (void *) 0x80c0000, + (void *) 0x80f0000, + 16); - if (!func_api_login) { - log_error("Could not find ApiLogin address"); - return; - } + if (!func_api_login) { + log_error("Could not find ApiLogin address"); + return; + } - log_debug("ApiLogin at %p", func_api_login); + log_debug("ApiLogin at %p", func_api_login); - func_api_logout = (void*) (((size_t) func_api_login) - 0x130); - log_debug("assuming ApiLogout at %p", func_api_logout); + func_api_logout = (void *) (((size_t) func_api_login) - 0x130); + log_debug("assuming ApiLogout at %p", func_api_logout); - func_api_decrypt = (void*) (((size_t) func_api_login) - 0x200); - log_debug("assuming ApiDecrypt at %p", func_api_decrypt); + func_api_decrypt = (void *) (((size_t) func_api_login) - 0x200); + log_debug("assuming ApiDecrypt at %p", func_api_decrypt); - func_api_getid = util_patch_find_signiture(patch_hasp_id_sig, - sizeof(patch_hasp_id_sig), 0, (void*) 0x8060000, (void*) 0x8090000, - 16); + func_api_getid = util_patch_find_signiture( + patch_hasp_id_sig, + sizeof(patch_hasp_id_sig), + 0, + (void *) 0x8060000, + (void *) 0x8090000, + 16); - if (!func_api_getid) { - log_error("Could not find ApiGetid address"); - return; - } + if (!func_api_getid) { + log_error("Could not find ApiGetid address"); + return; + } - log_debug("ApiGetid at %p", func_api_getid); + log_debug("ApiGetid at %p", func_api_getid); - util_patch_function((uintptr_t) func_api_login, sec_hasp_api_login); - util_patch_function((uintptr_t) func_api_logout, sec_hasp_api_logout); - util_patch_function((uintptr_t) func_api_decrypt, sec_hasp_api_decrypt); - util_patch_function((uintptr_t) func_api_getid, sec_hasp_api_getid); + util_patch_function((uintptr_t) func_api_login, sec_hasp_api_login); + util_patch_function((uintptr_t) func_api_logout, sec_hasp_api_logout); + util_patch_function((uintptr_t) func_api_decrypt, sec_hasp_api_decrypt); + util_patch_function((uintptr_t) func_api_getid, sec_hasp_api_getid); - sec_hasp_init(key_data, len); + sec_hasp_init(key_data, len); - log_info("Initialized"); + log_info("Initialized"); } \ No newline at end of file diff --git a/src/main/hook/patch/hasp.h b/src/main/hook/patch/hasp.h index 7c5c5f4..c2295bb 100644 --- a/src/main/hook/patch/hasp.h +++ b/src/main/hook/patch/hasp.h @@ -10,6 +10,6 @@ * @param key_data Pointer to loaded key data (key table) * @param len Length of the buffer */ -void patch_hasp_init(const uint8_t* key_data, size_t len); +void patch_hasp_init(const uint8_t *key_data, size_t len); #endif \ No newline at end of file diff --git a/src/main/hook/patch/hasp2.c b/src/main/hook/patch/hasp2.c index 81e8e81..ba10b51 100644 --- a/src/main/hook/patch/hasp2.c +++ b/src/main/hook/patch/hasp2.c @@ -8,33 +8,32 @@ static pthread_t patch_hasp_thread; -static void* patch_hasp_thread_run(void* args) +static void *patch_hasp_thread_run(void *args) { - log_info("Running hasp server thread"); + log_info("Running hasp server thread"); - sec_hasp_server_run(); + sec_hasp_server_run(); - log_info("Finished hasp server thread"); + log_info("Finished hasp server thread"); - return NULL; + return NULL; } -void patch_hasp_init(const uint8_t* key_data, size_t len) +void patch_hasp_init(const uint8_t *key_data, size_t len) { - sec_hasp_server_init(key_data, len); + sec_hasp_server_init(key_data, len); - /* Run the daemon in another thread */ - pthread_create(&patch_hasp_thread, NULL, - patch_hasp_thread_run, NULL); + /* Run the daemon in another thread */ + pthread_create(&patch_hasp_thread, NULL, patch_hasp_thread_run, NULL); - log_info("Initialized"); + log_info("Initialized"); } void patch_hasp_shutdown(void) { - log_info("Shutting down"); + log_info("Shutting down"); - sec_hasp_server_shutdown(); + sec_hasp_server_shutdown(); - pthread_join(patch_hasp_thread_run, NULL); + pthread_join(patch_hasp_thread_run, NULL); } \ No newline at end of file diff --git a/src/main/hook/patch/hasp2.h b/src/main/hook/patch/hasp2.h index 4d0e1d6..5e9eea5 100644 --- a/src/main/hook/patch/hasp2.h +++ b/src/main/hook/patch/hasp2.h @@ -1,5 +1,6 @@ /** - * Patch module to install the dongle emulator for a hasp dongle (runs a local server) + * Patch module to install the dongle emulator for a hasp dongle (runs a local + * server) */ #ifndef PATCH_HASP2_H #define PATCH_HASP2_H @@ -12,7 +13,7 @@ * @param key_data Pointer to loaded key data (attributes and key table) * @param len Length of the buffer */ -void patch_hasp_init(const uint8_t* key_data, size_t len); +void patch_hasp_init(const uint8_t *key_data, size_t len); /** * Shutdown and remove the emulator diff --git a/src/main/hook/patch/hdd-check.c b/src/main/hook/patch/hdd-check.c index 7ee692e..5f3a62b 100644 --- a/src/main/hook/patch/hdd-check.c +++ b/src/main/hook/patch/hdd-check.c @@ -10,248 +10,256 @@ #include "util/log.h" -static const uint8_t* patch_hdd_check_boot_area; +static const uint8_t *patch_hdd_check_boot_area; static int patch_hdd_check_fd = -1; -static FILE* patch_hdd_check_file = NULL; +static FILE *patch_hdd_check_file = NULL; static size_t patch_hdd_check_boot_area_size; static size_t patch_hdd_check_boot_area_fp; static enum cnh_result patch_hdd_check_filehook(struct cnh_filehook_irp *irp) { - enum cnh_result result; + enum cnh_result result; - result = CNH_RESULT_SUCCESS; + result = CNH_RESULT_SUCCESS; - assert(irp); + assert(irp); - if (irp->op != CNH_FILEHOOK_IRP_OP_OPEN && (!patch_hdd_check_file || irp->file != patch_hdd_check_file)) { + if (irp->op != CNH_FILEHOOK_IRP_OP_OPEN && + (!patch_hdd_check_file || irp->file != patch_hdd_check_file)) { + return cnh_filehook_invoke_next(irp); + } + + switch (irp->op) { + case CNH_FILEHOOK_IRP_OP_OPEN: { + if (!strcmp(irp->open_filename, "/dev/hdd")) { + patch_hdd_check_file = cnh_filehook_open_dummy_file_handle(); + irp->file = patch_hdd_check_file; + + log_debug("/dev/hdd fopened: %p", patch_hdd_check_file); + } else { return cnh_filehook_invoke_next(irp); + } + + break; } - switch (irp->op) { - case CNH_FILEHOOK_IRP_OP_OPEN: - { - if (!strcmp(irp->open_filename, "/dev/hdd")) { - patch_hdd_check_file = cnh_filehook_open_dummy_file_handle(); - irp->file = patch_hdd_check_file; + case CNH_FILEHOOK_IRP_OP_READ: { + uint32_t len; - log_debug("/dev/hdd fopened: %p", patch_hdd_check_file); - } else { - return cnh_filehook_invoke_next(irp); - } + log_debug( + "fread, pos 0x%X, bytes %d", + patch_hdd_check_boot_area_fp, + irp->read.nbytes); - break; - } + /* read up to eof, only */ + if (patch_hdd_check_boot_area_fp + irp->read.nbytes < + patch_hdd_check_boot_area_size) { + len = irp->read.nbytes; + } else { + len = patch_hdd_check_boot_area_size - patch_hdd_check_boot_area_fp; + } - case CNH_FILEHOOK_IRP_OP_READ: - { - uint32_t len; + memcpy( + irp->read.bytes, + patch_hdd_check_boot_area + patch_hdd_check_boot_area_fp, + len); - log_debug("fread, pos 0x%X, bytes %d", patch_hdd_check_boot_area_fp, irp->read.nbytes); + patch_hdd_check_boot_area_fp += len; + irp->read.pos = len; - /* read up to eof, only */ - if (patch_hdd_check_boot_area_fp + irp->read.nbytes < patch_hdd_check_boot_area_size) { - len = irp->read.nbytes; - } else { - len = patch_hdd_check_boot_area_size - patch_hdd_check_boot_area_fp; - } + break; + } - memcpy(irp->read.bytes, patch_hdd_check_boot_area + patch_hdd_check_boot_area_fp, len); + case CNH_FILEHOOK_IRP_OP_WRITE: { + // Apparently, Prime starts writing to /dev/hdd, stub + log_debug("fwrite"); - patch_hdd_check_boot_area_fp += len; - irp->read.pos = len; + break; + } - break; - } + case CNH_FILEHOOK_IRP_OP_SEEK: { + /* TODO this is not verified to work, yet + not needed on older games as it seems (zero for example) + patch seeking for CRED file so we can avoid a huge hdd file */ + if (irp->seek_offset == 0x1F70000) { + log_debug("fseek: fake for hdd (0x1F70000)"); + irp->seek_offset = 1024; + irp->seek_origin = SEEK_SET; + } else if (irp->seek_offset == 0x1F70800) { + log_debug("fseek: fake for hdd (0x1F70800)"); + irp->seek_offset = 1024 + 2048; + irp->seek_origin = SEEK_SET; + } - case CNH_FILEHOOK_IRP_OP_WRITE: - { - // Apparently, Prime starts writing to /dev/hdd, stub - log_debug("fwrite"); + switch (irp->seek_origin) { + case SEEK_SET: + patch_hdd_check_boot_area_fp = (size_t) irp->seek_offset; + break; - break; - } + case SEEK_CUR: + patch_hdd_check_boot_area_fp += irp->seek_offset; + break; - case CNH_FILEHOOK_IRP_OP_SEEK: - { - /* TODO this is not verified to work, yet - not needed on older games as it seems (zero for example) - patch seeking for CRED file so we can avoid a huge hdd file */ - if (irp->seek_offset == 0x1F70000) { - log_debug("fseek: fake for hdd (0x1F70000)"); - irp->seek_offset = 1024; - irp->seek_origin = SEEK_SET; - } else if (irp->seek_offset == 0x1F70800) { - log_debug("fseek: fake for hdd (0x1F70800)"); - irp->seek_offset = 1024 + 2048; - irp->seek_origin = SEEK_SET; - } - - switch (irp->seek_origin) { - case SEEK_SET: - patch_hdd_check_boot_area_fp = (size_t) irp->seek_offset; - break; - - case SEEK_CUR: - patch_hdd_check_boot_area_fp += irp->seek_offset; - break; - - case SEEK_END: - patch_hdd_check_boot_area_fp = patch_hdd_check_boot_area_size; - patch_hdd_check_boot_area_fp += irp->seek_offset; - break; - - default: - log_die("Unhandled origin %d", irp->seek_origin); - break; - } - - log_debug("fseek, offset 0x%X, origin %d", irp->seek_offset, irp->seek_origin); - - break; - } - - case CNH_FILEHOOK_IRP_OP_CLOSE: - patch_hdd_check_file = NULL; - - log_debug("/dev/hdd fclosed"); - - /* Actually close dummy handle */ - return cnh_filehook_invoke_next(irp); + case SEEK_END: + patch_hdd_check_boot_area_fp = patch_hdd_check_boot_area_size; + patch_hdd_check_boot_area_fp += irp->seek_offset; + break; default: - log_warn("Unhandled file op: %d", irp->op); - break; + log_die("Unhandled origin %d", irp->seek_origin); + break; + } + + log_debug( + "fseek, offset 0x%X, origin %d", irp->seek_offset, irp->seek_origin); + + break; } - return result; + case CNH_FILEHOOK_IRP_OP_CLOSE: + patch_hdd_check_file = NULL; + + log_debug("/dev/hdd fclosed"); + + /* Actually close dummy handle */ + return cnh_filehook_invoke_next(irp); + + default: + log_warn("Unhandled file op: %d", irp->op); + break; + } + + return result; } static enum cnh_result patch_hdd_check_iohook(struct cnh_iohook_irp *irp) { - enum cnh_result result; + enum cnh_result result; - result = CNH_RESULT_SUCCESS; + result = CNH_RESULT_SUCCESS; - assert(irp); + assert(irp); - if ((irp->op != CNH_IOHOOK_IRP_OP_OPEN && irp->fd != patch_hdd_check_fd) && - (irp->op != CNH_IOHOOK_IRP_OP_FDOPEN || irp->fdopen_fd != patch_hdd_check_fd)) { + if ((irp->op != CNH_IOHOOK_IRP_OP_OPEN && irp->fd != patch_hdd_check_fd) && + (irp->op != CNH_IOHOOK_IRP_OP_FDOPEN || + irp->fdopen_fd != patch_hdd_check_fd)) { + return cnh_iohook_invoke_next(irp); + } + + switch (irp->op) { + case CNH_IOHOOK_IRP_OP_OPEN: { + if (!strcmp(irp->open_filename, "/dev/hdd")) { + patch_hdd_check_fd = cnh_iohook_open_dummy_fd(); + irp->fd = patch_hdd_check_fd; + + log_debug("/dev/hdd opened: %d", patch_hdd_check_fd); + } else { return cnh_iohook_invoke_next(irp); + } + + break; } - switch (irp->op) { - case CNH_IOHOOK_IRP_OP_OPEN: - { - if (!strcmp(irp->open_filename, "/dev/hdd")) { - patch_hdd_check_fd = cnh_iohook_open_dummy_fd(); - irp->fd = patch_hdd_check_fd; + case CNH_IOHOOK_IRP_OP_FDOPEN: { + patch_hdd_check_file = cnh_filehook_open_dummy_file_handle(); + irp->fdopen_res = patch_hdd_check_file; - log_debug("/dev/hdd opened: %d", patch_hdd_check_fd); - } else { - return cnh_iohook_invoke_next(irp); - } + log_debug("/dev/hdd fdopen: %p", patch_hdd_check_file); - break; - } + break; + } - case CNH_IOHOOK_IRP_OP_FDOPEN: - { - patch_hdd_check_file = cnh_filehook_open_dummy_file_handle(); - irp->fdopen_res = patch_hdd_check_file; + case CNH_IOHOOK_IRP_OP_READ: { + uint32_t len; - log_debug("/dev/hdd fdopen: %p", patch_hdd_check_file); + log_debug( + "read, pos 0x%X, bytes %d", + patch_hdd_check_boot_area_fp, + irp->read.nbytes); - break; - } + /* read up to eof, only */ + if (patch_hdd_check_boot_area_fp + irp->read.nbytes < + patch_hdd_check_boot_area_size) { + len = irp->read.nbytes; + } else { + len = patch_hdd_check_boot_area_size - patch_hdd_check_boot_area_fp; + } - case CNH_IOHOOK_IRP_OP_READ: - { - uint32_t len; + memcpy( + irp->read.bytes, + patch_hdd_check_boot_area + patch_hdd_check_boot_area_fp, + len); - log_debug("read, pos 0x%X, bytes %d", patch_hdd_check_boot_area_fp, irp->read.nbytes); + patch_hdd_check_boot_area_fp += len; + irp->read.pos = len; - /* read up to eof, only */ - if (patch_hdd_check_boot_area_fp + irp->read.nbytes < patch_hdd_check_boot_area_size) { - len = irp->read.nbytes; - } else { - len = patch_hdd_check_boot_area_size - patch_hdd_check_boot_area_fp; - } + break; + } - memcpy(irp->read.bytes, patch_hdd_check_boot_area + patch_hdd_check_boot_area_fp, len); + case CNH_IOHOOK_IRP_OP_SEEK: { + log_debug("Seek: offset %d, orig %d", irp->seek_offset, irp->seek_origin); - patch_hdd_check_boot_area_fp += len; - irp->read.pos = len; + switch (irp->seek_origin) { + case SEEK_SET: + patch_hdd_check_boot_area_fp = (size_t) irp->seek_offset; + break; - break; - } + case SEEK_CUR: + patch_hdd_check_boot_area_fp += irp->seek_offset; + break; - case CNH_IOHOOK_IRP_OP_SEEK: - { - log_debug("Seek: offset %d, orig %d", irp->seek_offset, irp->seek_origin); - - switch (irp->seek_origin) { - case SEEK_SET: - patch_hdd_check_boot_area_fp = (size_t) irp->seek_offset; - break; - - case SEEK_CUR: - patch_hdd_check_boot_area_fp += irp->seek_offset; - break; - - case SEEK_END: - patch_hdd_check_boot_area_fp = patch_hdd_check_boot_area_size; - patch_hdd_check_boot_area_fp += irp->seek_offset; - break; - - default: - log_die("Unhandled origin %d", irp->seek_origin); - break; - } - - irp->seek_pos = patch_hdd_check_boot_area_fp; - - break; - } - - case CNH_IOHOOK_IRP_OP_IOCTL: - { - /* hdd information request */ - if (irp->ioctl_req == HDIO_GET_IDENTITY) { - log_info("ioctl: fake ioctl for hdd (0x30D)"); - /* just return empty data instead of real data */ - struct hd_driveid* drid = (struct hd_driveid*) irp->ioctl.bytes; - memset(drid, 0, sizeof(struct hd_driveid)); - irp->ioctl.pos = 0; - } - - break; - } - - case CNH_IOHOOK_IRP_OP_CLOSE: - patch_hdd_check_fd = -1; - - log_debug("/dev/hdd closed"); - - /* Actually close dummy handle */ - return cnh_iohook_invoke_next(irp); + case SEEK_END: + patch_hdd_check_boot_area_fp = patch_hdd_check_boot_area_size; + patch_hdd_check_boot_area_fp += irp->seek_offset; + break; default: - log_warn("Unhandled io op: %d", irp->op); - break; + log_die("Unhandled origin %d", irp->seek_origin); + break; + } + + irp->seek_pos = patch_hdd_check_boot_area_fp; + + break; } - return result; + case CNH_IOHOOK_IRP_OP_IOCTL: { + /* hdd information request */ + if (irp->ioctl_req == HDIO_GET_IDENTITY) { + log_info("ioctl: fake ioctl for hdd (0x30D)"); + /* just return empty data instead of real data */ + struct hd_driveid *drid = (struct hd_driveid *) irp->ioctl.bytes; + memset(drid, 0, sizeof(struct hd_driveid)); + irp->ioctl.pos = 0; + } + + break; + } + + case CNH_IOHOOK_IRP_OP_CLOSE: + patch_hdd_check_fd = -1; + + log_debug("/dev/hdd closed"); + + /* Actually close dummy handle */ + return cnh_iohook_invoke_next(irp); + + default: + log_warn("Unhandled io op: %d", irp->op); + break; + } + + return result; } -void patch_hdd_check_init(const uint8_t* boot_area_buffer, size_t len) +void patch_hdd_check_init(const uint8_t *boot_area_buffer, size_t len) { - patch_hdd_check_boot_area = boot_area_buffer; - patch_hdd_check_boot_area_size = len; + patch_hdd_check_boot_area = boot_area_buffer; + patch_hdd_check_boot_area_size = len; - cnh_iohook_push_handler(patch_hdd_check_iohook); - cnh_filehook_push_handler(patch_hdd_check_filehook); + cnh_iohook_push_handler(patch_hdd_check_iohook); + cnh_filehook_push_handler(patch_hdd_check_filehook); - log_info("Initialized: boot area size %d", patch_hdd_check_boot_area_size); + log_info("Initialized: boot area size %d", patch_hdd_check_boot_area_size); } \ No newline at end of file diff --git a/src/main/hook/patch/hdd-check.h b/src/main/hook/patch/hdd-check.h index a2822ab..f6fea50 100644 --- a/src/main/hook/patch/hdd-check.h +++ b/src/main/hook/patch/hdd-check.h @@ -11,6 +11,6 @@ * @param boot_area_buffer Buffer with boot area sections of a real drive * @param len Length of buffer provided */ -void patch_hdd_check_init(const uint8_t* boot_area_buffer, size_t len); +void patch_hdd_check_init(const uint8_t *boot_area_buffer, size_t len); #endif \ No newline at end of file diff --git a/src/main/hook/patch/hook-mon.c b/src/main/hook/patch/hook-mon.c index b08a29e..0437a0d 100644 --- a/src/main/hook/patch/hook-mon.c +++ b/src/main/hook/patch/hook-mon.c @@ -8,29 +8,34 @@ #include "util/log.h" -void patch_hook_mon_init(bool monitor_io, bool monitor_file, bool monitor_fs, bool monitor_usb, bool monitor_open) +void patch_hook_mon_init( + bool monitor_io, + bool monitor_file, + bool monitor_fs, + bool monitor_usb, + bool monitor_open) { - if (monitor_open) { - cnh_iohook_push_handler(cnh_fileopen_mon_iohook); - cnh_filehook_push_handler(cnh_fileopen_mon_filehook); - cnh_fshook_push_handler(cnh_fileopen_mon_fshook); - } + if (monitor_open) { + cnh_iohook_push_handler(cnh_fileopen_mon_iohook); + cnh_filehook_push_handler(cnh_fileopen_mon_filehook); + cnh_fshook_push_handler(cnh_fileopen_mon_fshook); + } - if (monitor_io) { - cnh_iohook_push_handler(cnh_iohook_mon); - } + if (monitor_io) { + cnh_iohook_push_handler(cnh_iohook_mon); + } - if (monitor_file) { - cnh_filehook_push_handler(cnh_filehook_mon); - } + if (monitor_file) { + cnh_filehook_push_handler(cnh_filehook_mon); + } - if (monitor_fs) { - cnh_fshook_push_handler(cnh_fshook_mon); - } + if (monitor_fs) { + cnh_fshook_push_handler(cnh_fshook_mon); + } - if (monitor_usb) { - cnh_usbhook_push_handler(cnh_usbhook_mon); - } + if (monitor_usb) { + cnh_usbhook_push_handler(cnh_usbhook_mon); + } - log_info("Initialized"); + log_info("Initialized"); } \ No newline at end of file diff --git a/src/main/hook/patch/hook-mon.h b/src/main/hook/patch/hook-mon.h index 4c5a1c6..656e1b2 100644 --- a/src/main/hook/patch/hook-mon.h +++ b/src/main/hook/patch/hook-mon.h @@ -1,5 +1,6 @@ /** - * Patch module for monitoring various system calls. For development and debugging purpose. + * Patch module for monitoring various system calls. For development and + * debugging purpose. */ #ifndef PATCH_HOOK_MON_H #define PATCH_HOOK_MON_H @@ -15,6 +16,11 @@ * @param monitor_usb True to enable monitoring of usb calls * @param monitor_open True to enable monitoring of any file/device open calls */ -void patch_hook_mon_init(bool monitor_io, bool monitor_file, bool monitor_fs, bool monitor_usb, bool monitor_open); +void patch_hook_mon_init( + bool monitor_io, + bool monitor_file, + bool monitor_fs, + bool monitor_usb, + bool monitor_open); #endif diff --git a/src/main/hook/patch/main-loop.c b/src/main/hook/patch/main-loop.c index bdcc7ff..30012b1 100644 --- a/src/main/hook/patch/main-loop.c +++ b/src/main/hook/patch/main-loop.c @@ -1,8 +1,8 @@ #define LOG_MODULE "patch-main-loop" +#include #include #include -#include #include "ptapi/io/x11-input-hook.h" @@ -13,223 +13,245 @@ #include "util/log.h" -typedef int (*XPending_t)(Display* display); -typedef int (*XNextEvent_t)(Display* display, XEvent* event_return); +typedef int (*XPending_t)(Display *display); +typedef int (*XNextEvent_t)(Display *display, XEvent *event_return); -typedef const struct ptapi_io_x11_input_hook_handler* (*ptapi_io_x11_input_handler_hook_t)(void); +typedef const struct ptapi_io_x11_input_hook_handler *( + *ptapi_io_x11_input_handler_hook_t)(void); static XPending_t _patch_main_loop_real_XPending; static XNextEvent_t _patch_main_loop_real_XNextEvent; -static void _patch_main_loop_sigalarm_handler(int signal, __sighandler_t orig_handler); -static bool _patch_main_loop_is_key_repeated(Display* display, XEvent* event); +static void +_patch_main_loop_sigalarm_handler(int signal, __sighandler_t orig_handler); +static bool _patch_main_loop_is_key_repeated(Display *display, XEvent *event); static __sighandler_t _patch_main_loop_sigalarm_orig_handler; static bool _patch_main_loop_disable_built_in_inputs; static bool _patch_main_loop_disable_mk3_linux_ports_built_in_inputs; static pthread_mutex_t _patch_main_loop_input_handlers_lock; -static const struct ptapi_io_x11_input_hook_handler** _patch_main_loop_input_handlers; +static const struct ptapi_io_x11_input_hook_handler * + *_patch_main_loop_input_handlers; static size_t _patch_main_loop_num_input_handlers; -void patch_main_loop_init(bool fix_sigalarm_main_loop, bool disable_built_in_inputs, bool disable_mk3_linux_port_inputs) +void patch_main_loop_init( + bool fix_sigalarm_main_loop, + bool disable_built_in_inputs, + bool disable_mk3_linux_port_inputs) { - _patch_main_loop_disable_built_in_inputs = disable_built_in_inputs; - _patch_main_loop_disable_mk3_linux_ports_built_in_inputs = disable_mk3_linux_port_inputs; + _patch_main_loop_disable_built_in_inputs = disable_built_in_inputs; + _patch_main_loop_disable_mk3_linux_ports_built_in_inputs = + disable_mk3_linux_port_inputs; - _patch_main_loop_sigalarm_orig_handler = NULL; + _patch_main_loop_sigalarm_orig_handler = NULL; - if (fix_sigalarm_main_loop) { - log_info("Applying sigalarm handler fix"); - cnh_sig_install(SIGALRM, _patch_main_loop_sigalarm_handler); - } + if (fix_sigalarm_main_loop) { + log_info("Applying sigalarm handler fix"); + cnh_sig_install(SIGALRM, _patch_main_loop_sigalarm_handler); + } - pthread_mutex_init(&_patch_main_loop_input_handlers_lock, NULL); + pthread_mutex_init(&_patch_main_loop_input_handlers_lock, NULL); - log_info("Initialized, disable built-in inputs %d", disable_built_in_inputs); + log_info("Initialized, disable built-in inputs %d", disable_built_in_inputs); } -void patch_main_loop_add_x11_input_handler(const char* lib_with_handler_impl) +void patch_main_loop_add_x11_input_handler(const char *lib_with_handler_impl) { - const struct ptapi_io_x11_input_hook_handler** new_array; - size_t new_size; - void* lib_handle; - ptapi_io_x11_input_handler_hook_t input_handler_hook_func; - const struct ptapi_io_x11_input_hook_handler* input_handler_hook; + const struct ptapi_io_x11_input_hook_handler **new_array; + size_t new_size; + void *lib_handle; + ptapi_io_x11_input_handler_hook_t input_handler_hook_func; + const struct ptapi_io_x11_input_hook_handler *input_handler_hook; - if (!lib_with_handler_impl) { - log_die("No library path with input handler implementation specified"); - } + if (!lib_with_handler_impl) { + log_die("No library path with input handler implementation specified"); + } - log_info("Loading library with x11-input-handler api implementation %s", lib_with_handler_impl); + log_info( + "Loading library with x11-input-handler api implementation %s", + lib_with_handler_impl); - lib_handle = cnh_lib_load(lib_with_handler_impl); + lib_handle = cnh_lib_load(lib_with_handler_impl); - input_handler_hook_func = (ptapi_io_x11_input_handler_hook_t) - cnh_lib_get_func_addr_handle(lib_handle, "ptapi_io_x11_input_handler_hook"); + input_handler_hook_func = + (ptapi_io_x11_input_handler_hook_t) cnh_lib_get_func_addr_handle( + lib_handle, "ptapi_io_x11_input_handler_hook"); - input_handler_hook = input_handler_hook_func(); + input_handler_hook = input_handler_hook_func(); - if (!input_handler_hook) { - log_warn("Library impl %s returned NULL hook handler, skipping", lib_with_handler_impl); - return; - } + if (!input_handler_hook) { + log_warn( + "Library impl %s returned NULL hook handler, skipping", + lib_with_handler_impl); + return; + } - pthread_mutex_lock(&_patch_main_loop_input_handlers_lock); + pthread_mutex_lock(&_patch_main_loop_input_handlers_lock); - new_size = _patch_main_loop_num_input_handlers + 1; - new_array = realloc(_patch_main_loop_input_handlers, new_size * sizeof(struct ptapi_io_input_hook_handler*)); + new_size = _patch_main_loop_num_input_handlers + 1; + new_array = realloc( + _patch_main_loop_input_handlers, + new_size * sizeof(struct ptapi_io_input_hook_handler *)); - if (new_array != NULL) { - _patch_main_loop_input_handlers = new_array; + if (new_array != NULL) { + _patch_main_loop_input_handlers = new_array; - _patch_main_loop_input_handlers[_patch_main_loop_num_input_handlers++] = input_handler_hook; - } else { - log_die("Out of memory"); - } + _patch_main_loop_input_handlers[_patch_main_loop_num_input_handlers++] = + input_handler_hook; + } else { + log_die("Out of memory"); + } - pthread_mutex_unlock(&_patch_main_loop_input_handlers_lock); + pthread_mutex_unlock(&_patch_main_loop_input_handlers_lock); - log_debug("Added input handler %p of lib %s", input_handler_hook, lib_with_handler_impl); + log_debug( + "Added input handler %p of lib %s", + input_handler_hook, + lib_with_handler_impl); } -int XPending(Display* display) +int XPending(Display *display) { - if (!_patch_main_loop_real_XPending) { - _patch_main_loop_real_XPending = (XPending_t) cnh_lib_get_func_addr("XPending"); - } + if (!_patch_main_loop_real_XPending) { + _patch_main_loop_real_XPending = + (XPending_t) cnh_lib_get_func_addr("XPending"); + } - /* poll the original SIGALRM handler to drive the pump engine */ - if (_patch_main_loop_sigalarm_orig_handler) { - _patch_main_loop_sigalarm_orig_handler(SIGALRM); - } + /* poll the original SIGALRM handler to drive the pump engine */ + if (_patch_main_loop_sigalarm_orig_handler) { + _patch_main_loop_sigalarm_orig_handler(SIGALRM); + } - return _patch_main_loop_real_XPending(display); + return _patch_main_loop_real_XPending(display); } -int XNextEvent(Display* display, XEvent* event_return) +int XNextEvent(Display *display, XEvent *event_return) { - int res; - KeySym key; + int res; + KeySym key; - if (!_patch_main_loop_real_XNextEvent) { - _patch_main_loop_real_XNextEvent = (XNextEvent_t) cnh_lib_get_func_addr("XNextEvent"); - } + if (!_patch_main_loop_real_XNextEvent) { + _patch_main_loop_real_XNextEvent = + (XNextEvent_t) cnh_lib_get_func_addr("XNextEvent"); + } - /* Trap KeyPress and KeyRelease events */ - res = _patch_main_loop_real_XNextEvent(display, event_return); + /* Trap KeyPress and KeyRelease events */ + res = _patch_main_loop_real_XNextEvent(display, event_return); - switch (event_return->type) { - case KeyPress: - { - /* Mask out the modifier states X11 sets and read again */ - event_return->xkey.state &= ~ShiftMask; - event_return->xkey.state &= ~LockMask; + switch (event_return->type) { + case KeyPress: { + /* Mask out the modifier states X11 sets and read again */ + event_return->xkey.state &= ~ShiftMask; + event_return->xkey.state &= ~LockMask; - XLookupString(&event_return->xkey, 0, 0, &key, 0); + XLookupString(&event_return->xkey, 0, 0, &key, 0); - /* Swallow some keys to disable them */ - if (_patch_main_loop_disable_built_in_inputs) { - if (key == XK_F1 || key == XK_F2 || key == XK_F3) { - event_return->type = GenericEvent; - } - } + /* Swallow some keys to disable them */ + if (_patch_main_loop_disable_built_in_inputs) { + if (key == XK_F1 || key == XK_F2 || key == XK_F3) { + event_return->type = GenericEvent; + } + } - /* Swallow all built-in inputs of the MK3 ports */ - if (_patch_main_loop_disable_mk3_linux_ports_built_in_inputs) { - if (key == XK_g || key == XK_h || key == XK_j || key == XK_k || key == XK_l || - key == XK_q || key == XK_e || key == XK_s || key == XK_z || key == XK_c || - key == XK_KP_7 || key == XK_KP_9 || key == XK_KP_5 || key == XK_KP_1 || key == XK_KP_3) { - event_return->type = GenericEvent; - } - } + /* Swallow all built-in inputs of the MK3 ports */ + if (_patch_main_loop_disable_mk3_linux_ports_built_in_inputs) { + if (key == XK_g || key == XK_h || key == XK_j || key == XK_k || + key == XK_l || key == XK_q || key == XK_e || key == XK_s || + key == XK_z || key == XK_c || key == XK_KP_7 || key == XK_KP_9 || + key == XK_KP_5 || key == XK_KP_1 || key == XK_KP_3) { + event_return->type = GenericEvent; + } + } - /* Dispatch to external input handlers */ - if (_patch_main_loop_num_input_handlers > 0) { - pthread_mutex_lock(&_patch_main_loop_input_handlers_lock); + /* Dispatch to external input handlers */ + if (_patch_main_loop_num_input_handlers > 0) { + pthread_mutex_lock(&_patch_main_loop_input_handlers_lock); - for (size_t i = 0; i < _patch_main_loop_num_input_handlers; i++) { - if (_patch_main_loop_input_handlers[i]->dispatch_key_press) { - _patch_main_loop_input_handlers[i]->dispatch_key_press(key); - } - } - - pthread_mutex_unlock(&_patch_main_loop_input_handlers_lock); - } - - break; + for (size_t i = 0; i < _patch_main_loop_num_input_handlers; i++) { + if (_patch_main_loop_input_handlers[i]->dispatch_key_press) { + _patch_main_loop_input_handlers[i]->dispatch_key_press(key); + } } - case KeyRelease: - { - /* Mask out the modifier states X11 sets and read again */ - event_return->xkey.state &= ~ShiftMask; - event_return->xkey.state &= ~LockMask; + pthread_mutex_unlock(&_patch_main_loop_input_handlers_lock); + } - XLookupString(&event_return->xkey, 0, 0, &key, 0); + break; + } - /* Swallow some keys to disable them */ - if (_patch_main_loop_disable_built_in_inputs) { - if (key == XK_F1 || key == XK_F2 || key == XK_F3) { - event_return->type = GenericEvent; - } - } + case KeyRelease: { + /* Mask out the modifier states X11 sets and read again */ + event_return->xkey.state &= ~ShiftMask; + event_return->xkey.state &= ~LockMask; - /* Swallow all built-in inputs of the MK3 ports */ - if (_patch_main_loop_disable_mk3_linux_ports_built_in_inputs) { - if (key == XK_g || key == XK_h || key == XK_j || key == XK_k || key == XK_l || - key == XK_q || key == XK_e || key == XK_s || key == XK_z || key == XK_c || - key == XK_KP_7 || key == XK_KP_9 || key == XK_KP_5 || key == XK_KP_1 || key == XK_KP_3) { - event_return->type = GenericEvent; - } - } + XLookupString(&event_return->xkey, 0, 0, &key, 0); - /* Dispatch to external input handlers */ - if (_patch_main_loop_num_input_handlers > 0) { - /* Dispatch release if key is not repeated */ - if (!_patch_main_loop_is_key_repeated(display, event_return)) { - pthread_mutex_lock(&_patch_main_loop_input_handlers_lock); - - for (size_t i = 0; i < _patch_main_loop_num_input_handlers; i++) { - if (_patch_main_loop_input_handlers[i]->dispatch_key_release) { - _patch_main_loop_input_handlers[i]->dispatch_key_release(key); - } - } - - pthread_mutex_unlock(&_patch_main_loop_input_handlers_lock); - } - } - - break; + /* Swallow some keys to disable them */ + if (_patch_main_loop_disable_built_in_inputs) { + if (key == XK_F1 || key == XK_F2 || key == XK_F3) { + event_return->type = GenericEvent; } + } - default: - break; + /* Swallow all built-in inputs of the MK3 ports */ + if (_patch_main_loop_disable_mk3_linux_ports_built_in_inputs) { + if (key == XK_g || key == XK_h || key == XK_j || key == XK_k || + key == XK_l || key == XK_q || key == XK_e || key == XK_s || + key == XK_z || key == XK_c || key == XK_KP_7 || key == XK_KP_9 || + key == XK_KP_5 || key == XK_KP_1 || key == XK_KP_3) { + event_return->type = GenericEvent; + } + } + + /* Dispatch to external input handlers */ + if (_patch_main_loop_num_input_handlers > 0) { + /* Dispatch release if key is not repeated */ + if (!_patch_main_loop_is_key_repeated(display, event_return)) { + pthread_mutex_lock(&_patch_main_loop_input_handlers_lock); + + for (size_t i = 0; i < _patch_main_loop_num_input_handlers; i++) { + if (_patch_main_loop_input_handlers[i]->dispatch_key_release) { + _patch_main_loop_input_handlers[i]->dispatch_key_release(key); + } + } + + pthread_mutex_unlock(&_patch_main_loop_input_handlers_lock); + } + } + + break; } - return res; + default: + break; + } + + return res; } -static void _patch_main_loop_sigalarm_handler(int signal, __sighandler_t orig_handler) +static void +_patch_main_loop_sigalarm_handler(int signal, __sighandler_t orig_handler) { - /* do nothing on sigalrm */ - _patch_main_loop_sigalarm_orig_handler = orig_handler; + /* do nothing on sigalrm */ + _patch_main_loop_sigalarm_orig_handler = orig_handler; } -static bool _patch_main_loop_is_key_repeated(Display* display, XEvent* event) +static bool _patch_main_loop_is_key_repeated(Display *display, XEvent *event) { - /* When a key is repeated, there will be two events: released, followed by another immediate pressed. - So check to see if another pressed is present */ - if (!_patch_main_loop_real_XPending(display)) { - return false; - } - - XEvent e; - XPeekEvent(display, &e); - - if (e.type == KeyPress && e.xkey.keycode == event->xkey.keycode && (e.xkey.time - event->xkey.time) < 2) { - _patch_main_loop_real_XNextEvent(display, &e); - return true; - } - + /* When a key is repeated, there will be two events: released, followed by + another immediate pressed. So check to see if another pressed is present */ + if (!_patch_main_loop_real_XPending(display)) { return false; + } + + XEvent e; + XPeekEvent(display, &e); + + if (e.type == KeyPress && e.xkey.keycode == event->xkey.keycode && + (e.xkey.time - event->xkey.time) < 2) { + _patch_main_loop_real_XNextEvent(display, &e); + return true; + } + + return false; } \ No newline at end of file diff --git a/src/main/hook/patch/main-loop.h b/src/main/hook/patch/main-loop.h index 83f9e2d..1d8d0ec 100644 --- a/src/main/hook/patch/main-loop.h +++ b/src/main/hook/patch/main-loop.h @@ -36,24 +36,31 @@ #ifndef PATCH_MAIN_LOOP_H #define PATCH_MAIN_LOOP_H -#include #include +#include /** * Initialize the patch module * - * @param fix_sigalarm_main_loop True to enable the sigalarm thread fix (doc see above) - * @param disable_built_in_inputs Disable the built in keyboard inputs for test (F1), service (F2) and clear (F3) - * @param disable_mk3_linux_port_inputs Disable the built-in keyboard inputs on the MK3 linux ports + * @param fix_sigalarm_main_loop True to enable the sigalarm thread fix (doc see + * above) + * @param disable_built_in_inputs Disable the built in keyboard inputs for test + * (F1), service (F2) and clear (F3) + * @param disable_mk3_linux_port_inputs Disable the built-in keyboard inputs on + * the MK3 linux ports */ -void patch_main_loop_init(bool fix_sigalarm_main_loop, bool disable_built_in_inputs, +void patch_main_loop_init( + bool fix_sigalarm_main_loop, + bool disable_built_in_inputs, bool disable_mk3_linux_port_inputs); /** - * Register a handler (multiple possible) to receive X11 input events, e.g. key pressed, released + * Register a handler (multiple possible) to receive X11 input events, e.g. key + * pressed, released * - * @param lib_with_handler_impl Path to a library implementing the x11-input-handler API + * @param lib_with_handler_impl Path to a library implementing the + * x11-input-handler API */ -void patch_main_loop_add_x11_input_handler(const char* lib_with_handler_impl); +void patch_main_loop_add_x11_input_handler(const char *lib_with_handler_impl); #endif diff --git a/src/main/hook/patch/microdog34.c b/src/main/hook/patch/microdog34.c index 110734c..17229f6 100644 --- a/src/main/hook/patch/microdog34.c +++ b/src/main/hook/patch/microdog34.c @@ -16,57 +16,54 @@ static int _patch_microdog34_fd = -1; enum cnh_result patch_microdog34_iohook(struct cnh_iohook_irp *irp); -void patch_microdog34_init(const uint8_t* key_data, size_t len) +void patch_microdog34_init(const uint8_t *key_data, size_t len) { - sec_microdog34_init(key_data, len); + sec_microdog34_init(key_data, len); - cnh_iohook_push_handler(patch_microdog34_iohook); - log_info("Initialized"); + cnh_iohook_push_handler(patch_microdog34_iohook); + log_info("Initialized"); } enum cnh_result patch_microdog34_iohook(struct cnh_iohook_irp *irp) { - if (irp->op != CNH_IOHOOK_IRP_OP_OPEN && irp->fd != _patch_microdog34_fd) { - return cnh_iohook_invoke_next(irp); + if (irp->op != CNH_IOHOOK_IRP_OP_OPEN && irp->fd != _patch_microdog34_fd) { + return cnh_iohook_invoke_next(irp); + } + + switch (irp->op) { + case CNH_IOHOOK_IRP_OP_OPEN: { + if (!strcmp(irp->open_filename, USBDOG_ENDPOINT)) { + _patch_microdog34_fd = cnh_iohook_open_dummy_fd(); + irp->fd = _patch_microdog34_fd; + return CNH_RESULT_SUCCESS; + } + + return cnh_iohook_invoke_next(irp); } - switch (irp->op) { - case CNH_IOHOOK_IRP_OP_OPEN: - { - if (!strcmp(irp->open_filename, USBDOG_ENDPOINT)) { - _patch_microdog34_fd = cnh_iohook_open_dummy_fd(); - irp->fd = _patch_microdog34_fd; - return CNH_RESULT_SUCCESS; - } + case CNH_IOHOOK_IRP_OP_CLOSE: { + assert(irp->fd); - return cnh_iohook_invoke_next(irp); - } + cnh_iohook_close_dummy_fd(irp->fd); + _patch_microdog34_fd = -1; - case CNH_IOHOOK_IRP_OP_CLOSE: - { - assert(irp->fd); - - cnh_iohook_close_dummy_fd(irp->fd); - _patch_microdog34_fd = -1; - - return CNH_RESULT_SUCCESS; - } - - case CNH_IOHOOK_IRP_OP_READ: - { - /* Just stub and return success */ - return CNH_RESULT_SUCCESS; - } - - case CNH_IOHOOK_IRP_OP_IOCTL: - { - irp->ioctl.pos = (size_t) sec_microdog34_process(irp->ioctl_req, irp->ioctl.bytes); - - return CNH_RESULT_SUCCESS; - } - - default: - log_die("Unhandled operation: %d", irp->op); - return CNH_RESULT_OTHER_ERROR; + return CNH_RESULT_SUCCESS; } + + case CNH_IOHOOK_IRP_OP_READ: { + /* Just stub and return success */ + return CNH_RESULT_SUCCESS; + } + + case CNH_IOHOOK_IRP_OP_IOCTL: { + irp->ioctl.pos = + (size_t) sec_microdog34_process(irp->ioctl_req, irp->ioctl.bytes); + + return CNH_RESULT_SUCCESS; + } + + default: + log_die("Unhandled operation: %d", irp->op); + return CNH_RESULT_OTHER_ERROR; + } } \ No newline at end of file diff --git a/src/main/hook/patch/microdog34.h b/src/main/hook/patch/microdog34.h index 9ec63c4..5727c1e 100644 --- a/src/main/hook/patch/microdog34.h +++ b/src/main/hook/patch/microdog34.h @@ -10,6 +10,6 @@ * @param key_data Pointer to loaded key data (dog attributes, key table) * @param len Length of the buffer */ -void patch_microdog34_init(const uint8_t* key_data, size_t len); +void patch_microdog34_init(const uint8_t *key_data, size_t len); #endif \ No newline at end of file diff --git a/src/main/hook/patch/microdog40.c b/src/main/hook/patch/microdog40.c index 0f53168..325e3a9 100644 --- a/src/main/hook/patch/microdog40.c +++ b/src/main/hook/patch/microdog40.c @@ -8,33 +8,33 @@ static pthread_t patch_microdog40_thread; -static void* patch_microdog40_thread_run(void* args) +static void *patch_microdog40_thread_run(void *args) { - log_info("Running daemon thread"); + log_info("Running daemon thread"); - sec_microdog40d_run(); + sec_microdog40d_run(); - log_info("Finished daemon thread"); + log_info("Finished daemon thread"); - return NULL; + return NULL; } -void patch_microdog40_init(const uint8_t* key_data, size_t len) +void patch_microdog40_init(const uint8_t *key_data, size_t len) { - sec_microdog40d_init(key_data, len); + sec_microdog40d_init(key_data, len); - /* Run the daemon in another thread */ - pthread_create(&patch_microdog40_thread, NULL, - patch_microdog40_thread_run, NULL); + /* Run the daemon in another thread */ + pthread_create( + &patch_microdog40_thread, NULL, patch_microdog40_thread_run, NULL); - log_info("Initialized"); + log_info("Initialized"); } void patch_microdog40_shutdown(void) { - log_info("Shutting down"); + log_info("Shutting down"); - sec_microdog40d_shutdown(); + sec_microdog40d_shutdown(); - pthread_join(patch_microdog40_thread, NULL); + pthread_join(patch_microdog40_thread, NULL); } \ No newline at end of file diff --git a/src/main/hook/patch/microdog40.h b/src/main/hook/patch/microdog40.h index 4cef422..17eeef2 100644 --- a/src/main/hook/patch/microdog40.h +++ b/src/main/hook/patch/microdog40.h @@ -10,7 +10,7 @@ * @param key_data Pointer to loaded key data (dog attributes, key table) * @param len Length of the buffer */ -void patch_microdog40_init(const uint8_t* key_data, size_t len); +void patch_microdog40_init(const uint8_t *key_data, size_t len); /** * Shutdown and remove the emulator diff --git a/src/main/hook/patch/mounts.c b/src/main/hook/patch/mounts.c index cd8f8c0..bae8b1c 100644 --- a/src/main/hook/patch/mounts.c +++ b/src/main/hook/patch/mounts.c @@ -10,96 +10,91 @@ #include "util/log.h" /* looks odd but hddd is intentional */ -static const char* patch_mount_proc_mount_file = "/dev/hddd /mnt/hd"; +static const char *patch_mount_proc_mount_file = "/dev/hddd /mnt/hd"; -static FILE* patch_mount_file = NULL; +static FILE *patch_mount_file = NULL; static bool patch_mount_eof; static enum cnh_result patch_hdd_check_filehook(struct cnh_filehook_irp *irp) { - enum cnh_result result; + enum cnh_result result; - result = CNH_RESULT_SUCCESS; + result = CNH_RESULT_SUCCESS; - assert(irp); + assert(irp); - if (irp->op != CNH_FILEHOOK_IRP_OP_OPEN && irp->file != patch_mount_file) { + if (irp->op != CNH_FILEHOOK_IRP_OP_OPEN && irp->file != patch_mount_file) { + return cnh_filehook_invoke_next(irp); + } + + switch (irp->op) { + case CNH_FILEHOOK_IRP_OP_OPEN: { + if (!strcmp(irp->open_filename, "/proc/mounts")) { + patch_mount_file = cnh_filehook_open_dummy_file_handle(); + irp->file = patch_mount_file; + + patch_mount_eof = false; + + log_debug("/proc/mounts opened: %p", irp->file); + } else { return cnh_filehook_invoke_next(irp); + } + + break; } - switch (irp->op) { - case CNH_FILEHOOK_IRP_OP_OPEN: - { - if (!strcmp(irp->open_filename, "/proc/mounts")) { - patch_mount_file = cnh_filehook_open_dummy_file_handle(); - irp->file = patch_mount_file; + case CNH_FILEHOOK_IRP_OP_FGETS: { + size_t size; - patch_mount_eof = false; + log_info("/proc/mounts fake read"); - log_debug("/proc/mounts opened: %p", irp->file); - } else { - return cnh_filehook_invoke_next(irp); - } + size = strlen(patch_mount_proc_mount_file) + 1; - break; - } + /* +1: copy the null terminator, too */ + memcpy( + &irp->read.bytes[irp->read.pos], patch_mount_proc_mount_file, size); + irp->read.pos += size; - case CNH_FILEHOOK_IRP_OP_FGETS: - { - size_t size; + patch_mount_eof = true; - log_info("/proc/mounts fake read"); - - size = strlen(patch_mount_proc_mount_file) + 1; - - /* +1: copy the null terminator, too */ - memcpy(&irp->read.bytes[irp->read.pos], patch_mount_proc_mount_file, size); - irp->read.pos += size; - - patch_mount_eof = true; - - break; - } - - case CNH_FILEHOOK_IRP_OP_SEEK: - { - /* Ignore seeking */ - - break; - } - - case CNH_FILEHOOK_IRP_OP_TELL: - { - /* Return size */ - irp->tell_offset = strlen(patch_mount_proc_mount_file) + 1; - - break; - } - - case CNH_FILEHOOK_IRP_OP_EOF: - { - irp->eof = patch_mount_eof; - break; - } - - case CNH_FILEHOOK_IRP_OP_CLOSE: - { - patch_mount_file = NULL; - - /* Actually close dummy handle */ - return cnh_filehook_invoke_next(irp); - } - - default: - log_warn("Unhandled file op: %d", irp->op); - break; + break; } - return result; + case CNH_FILEHOOK_IRP_OP_SEEK: { + /* Ignore seeking */ + + break; + } + + case CNH_FILEHOOK_IRP_OP_TELL: { + /* Return size */ + irp->tell_offset = strlen(patch_mount_proc_mount_file) + 1; + + break; + } + + case CNH_FILEHOOK_IRP_OP_EOF: { + irp->eof = patch_mount_eof; + break; + } + + case CNH_FILEHOOK_IRP_OP_CLOSE: { + patch_mount_file = NULL; + + /* Actually close dummy handle */ + return cnh_filehook_invoke_next(irp); + } + + default: + log_warn("Unhandled file op: %d", irp->op); + break; + } + + return result; } void patch_mounts_init(void) { - cnh_filehook_push_handler(patch_hdd_check_filehook); - log_info("Initialized"); + cnh_filehook_push_handler(patch_hdd_check_filehook); + log_info("Initialized"); } \ No newline at end of file diff --git a/src/main/hook/patch/net-profile.c b/src/main/hook/patch/net-profile.c index 7a9b038..2ab2701 100644 --- a/src/main/hook/patch/net-profile.c +++ b/src/main/hook/patch/net-profile.c @@ -20,575 +20,627 @@ #define PUMPNET_TRY_CONNECT_TIMEOUT_MS 2000 struct profile_virtual_mnt_point_file_info { - int player; - enum pumpnet_lib_file_type file_type; - const char* file_path; - size_t file_size; + int player; + enum pumpnet_lib_file_type file_type; + const char *file_path; + size_t file_size; }; struct profile_virtual_mnt_point_info { - struct { - struct profile_virtual_mnt_point_file_info file_info[PUMPNET_LIB_FILE_TYPE_COUNT]; - } player[PUMPNET_MAX_NUM_PLAYERS]; + struct { + struct profile_virtual_mnt_point_file_info + file_info[PUMPNET_LIB_FILE_TYPE_COUNT]; + } player[PUMPNET_MAX_NUM_PLAYERS]; }; struct profile_virtual_file { - uint64_t player_ref_id; - FILE* handle; - const struct profile_virtual_mnt_point_file_info* file_info; - size_t buffer_pos; - uint8_t* buffer; - bool is_written; + uint64_t player_ref_id; + FILE *handle; + const struct profile_virtual_mnt_point_file_info *file_info; + size_t buffer_pos; + uint8_t *buffer; + bool is_written; }; struct profile_virtual_mnt_point { - struct profile_virtual_file files[PUMPNET_LIB_FILE_TYPE_COUNT]; + struct profile_virtual_file files[PUMPNET_LIB_FILE_TYPE_COUNT]; }; -static enum cnh_result _patch_net_profile_filehook(struct cnh_filehook_irp* irp); -static enum cnh_result _patch_net_profile_fopen(struct cnh_filehook_irp* irp); -static enum cnh_result _patch_net_profile_fclose(struct cnh_filehook_irp* irp, - struct profile_virtual_file* virtual_file); -static enum cnh_result _patch_net_profile_fread(struct cnh_filehook_irp* irp, - struct profile_virtual_file* virtual_file); -static enum cnh_result _patch_net_profile_fwrite(struct cnh_filehook_irp* irp, - struct profile_virtual_file* virtual_file); -static enum cnh_result _patch_net_profile_fseek(struct cnh_filehook_irp* irp, - struct profile_virtual_file* virtual_file); -static enum cnh_result _patch_net_profile_ftell(struct cnh_filehook_irp* irp, - struct profile_virtual_file* virtual_file); -static enum cnh_result _patch_net_profile_feof(struct cnh_filehook_irp* irp, - struct profile_virtual_file* virtual_file); +static enum cnh_result +_patch_net_profile_filehook(struct cnh_filehook_irp *irp); +static enum cnh_result _patch_net_profile_fopen(struct cnh_filehook_irp *irp); +static enum cnh_result _patch_net_profile_fclose( + struct cnh_filehook_irp *irp, struct profile_virtual_file *virtual_file); +static enum cnh_result _patch_net_profile_fread( + struct cnh_filehook_irp *irp, struct profile_virtual_file *virtual_file); +static enum cnh_result _patch_net_profile_fwrite( + struct cnh_filehook_irp *irp, struct profile_virtual_file *virtual_file); +static enum cnh_result _patch_net_profile_fseek( + struct cnh_filehook_irp *irp, struct profile_virtual_file *virtual_file); +static enum cnh_result _patch_net_profile_ftell( + struct cnh_filehook_irp *irp, struct profile_virtual_file *virtual_file); +static enum cnh_result _patch_net_profile_feof( + struct cnh_filehook_irp *irp, struct profile_virtual_file *virtual_file); -static struct profile_virtual_file* _patch_net_profile_get_virtual_mnt_point(FILE* handle); +static struct profile_virtual_file * +_patch_net_profile_get_virtual_mnt_point(FILE *handle); static bool _patch_net_profile_determine_is_profile_and_player_and_file_type( - struct cnh_filehook_irp* irp, - uint8_t* player, - enum pumpnet_lib_file_type* file_type); + struct cnh_filehook_irp *irp, + uint8_t *player, + enum pumpnet_lib_file_type *file_type); static enum cnh_result _patch_net_profile_open_pumpnet_profile_file( - struct cnh_filehook_irp* irp, - uint8_t player, - enum pumpnet_lib_file_type file_type); -static bool _patch_net_profile_close_pumpnet_profile_file(struct profile_virtual_file* virtual_file); + struct cnh_filehook_irp *irp, + uint8_t player, + enum pumpnet_lib_file_type file_type); +static bool _patch_net_profile_close_pumpnet_profile_file( + struct profile_virtual_file *virtual_file); -static const struct profile_virtual_mnt_point_info _patch_net_profile_virtual_mnt_point_infos[] = { - { - .player = { - { - .file_info = { - { - .player = 0, - .file_type = PUMPNET_LIB_FILE_TYPE_SAVE, - .file_path = "/mnt/0/nx2save.bin", - .file_size = ASSET_NX2_USB_SAVE_SIZE - }, - { - .player = 0, - .file_type = PUMPNET_LIB_FILE_TYPE_RANK, - .file_path = "/mnt/0/nx2rank.bin", - .file_size = ASSET_NX2_USB_RANK_SIZE - } - } - }, - { - .file_info = { - { - .player = 1, - .file_type = PUMPNET_LIB_FILE_TYPE_SAVE, - .file_path = "/mnt/1/nx2save.bin", - .file_size = ASSET_NX2_USB_SAVE_SIZE - }, - { - .player = 1, - .file_type = PUMPNET_LIB_FILE_TYPE_RANK, - .file_path = "/mnt/1/nx2rank.bin", - .file_size = ASSET_NX2_USB_RANK_SIZE - } - } - }, - } - } -}; +static const struct profile_virtual_mnt_point_info + _patch_net_profile_virtual_mnt_point_infos[] = { + {.player = { + {.file_info = + {{.player = 0, + .file_type = PUMPNET_LIB_FILE_TYPE_SAVE, + .file_path = "/mnt/0/nx2save.bin", + .file_size = ASSET_NX2_USB_SAVE_SIZE}, + {.player = 0, + .file_type = PUMPNET_LIB_FILE_TYPE_RANK, + .file_path = "/mnt/0/nx2rank.bin", + .file_size = ASSET_NX2_USB_RANK_SIZE}}}, + {.file_info = + {{.player = 1, + .file_type = PUMPNET_LIB_FILE_TYPE_SAVE, + .file_path = "/mnt/1/nx2save.bin", + .file_size = ASSET_NX2_USB_SAVE_SIZE}, + {.player = 1, + .file_type = PUMPNET_LIB_FILE_TYPE_RANK, + .file_path = "/mnt/1/nx2rank.bin", + .file_size = ASSET_NX2_USB_RANK_SIZE}}}, + }}}; -static const struct profile_virtual_mnt_point_info* _patch_net_profile_file_info_ref; -static struct profile_virtual_mnt_point _patch_net_profile_virtual_mnt_points[PUMPNET_MAX_NUM_PLAYERS]; +static const struct profile_virtual_mnt_point_info + *_patch_net_profile_file_info_ref; +static struct profile_virtual_mnt_point + _patch_net_profile_virtual_mnt_points[PUMPNET_MAX_NUM_PLAYERS]; static pthread_mutex_t _patch_net_profile_mutex; -static enum cnh_result _patch_net_profile_filehook(struct cnh_filehook_irp* irp) +static enum cnh_result _patch_net_profile_filehook(struct cnh_filehook_irp *irp) { - if (irp->op == CNH_FILEHOOK_IRP_OP_OPEN) { - return _patch_net_profile_fopen(irp); - } else { - struct profile_virtual_file* virt_file = _patch_net_profile_get_virtual_mnt_point(irp->file); + if (irp->op == CNH_FILEHOOK_IRP_OP_OPEN) { + return _patch_net_profile_fopen(irp); + } else { + struct profile_virtual_file *virt_file = + _patch_net_profile_get_virtual_mnt_point(irp->file); - if (virt_file != NULL) { - switch (irp->op) { - case CNH_FILEHOOK_IRP_OP_CLOSE: - return _patch_net_profile_fclose(irp, virt_file); + if (virt_file != NULL) { + switch (irp->op) { + case CNH_FILEHOOK_IRP_OP_CLOSE: + return _patch_net_profile_fclose(irp, virt_file); - case CNH_FILEHOOK_IRP_OP_READ: - return _patch_net_profile_fread(irp, virt_file); + case CNH_FILEHOOK_IRP_OP_READ: + return _patch_net_profile_fread(irp, virt_file); - case CNH_FILEHOOK_IRP_OP_WRITE: - return _patch_net_profile_fwrite(irp, virt_file); + case CNH_FILEHOOK_IRP_OP_WRITE: + return _patch_net_profile_fwrite(irp, virt_file); - case CNH_FILEHOOK_IRP_OP_FGETS: - log_die("Unsupported operation"); - return CNH_RESULT_OTHER_ERROR; + case CNH_FILEHOOK_IRP_OP_FGETS: + log_die("Unsupported operation"); + return CNH_RESULT_OTHER_ERROR; - case CNH_FILEHOOK_IRP_OP_SEEK: - return _patch_net_profile_fseek(irp, virt_file); + case CNH_FILEHOOK_IRP_OP_SEEK: + return _patch_net_profile_fseek(irp, virt_file); - case CNH_FILEHOOK_IRP_OP_TELL: - return _patch_net_profile_ftell(irp, virt_file); + case CNH_FILEHOOK_IRP_OP_TELL: + return _patch_net_profile_ftell(irp, virt_file); - case CNH_FILEHOOK_IRP_OP_EOF: - return _patch_net_profile_feof(irp, virt_file); - - default: - log_die("Unhandled switch case"); - return CNH_RESULT_OTHER_ERROR; - } - } else { - return cnh_filehook_invoke_next(irp); - } - } -} - -static enum cnh_result _patch_net_profile_fopen(struct cnh_filehook_irp* irp) -{ - uint8_t player; - enum pumpnet_lib_file_type file_type; - player = -1; - file_type = PUMPNET_LIB_FILE_TYPE_COUNT; - - // not a profile file, pass - if (!_patch_net_profile_determine_is_profile_and_player_and_file_type(irp, &player, &file_type)) { - return cnh_filehook_invoke_next(irp); - } - - return _patch_net_profile_open_pumpnet_profile_file(irp, player, file_type); -} - -static enum cnh_result _patch_net_profile_fclose(struct cnh_filehook_irp* irp, - struct profile_virtual_file* virtual_file) -{ - log_debug("fclose %s", virtual_file->file_info->file_path); - - return _patch_net_profile_close_pumpnet_profile_file(virtual_file) ? CNH_RESULT_SUCCESS : CNH_RESULT_OTHER_ERROR; -} - -static enum cnh_result _patch_net_profile_fread(struct cnh_filehook_irp* irp, - struct profile_virtual_file* virtual_file) -{ - uint32_t len; - - pthread_mutex_lock(&_patch_net_profile_mutex); - - log_debug("fread %s, pos 0x%X, bytes %d", virtual_file->file_info->file_path, virtual_file->buffer_pos, - irp->read.nbytes); - - /* read up to eof, only */ - if (virtual_file->buffer_pos + irp->read.nbytes < virtual_file->file_info->file_size) { - len = irp->read.nbytes; - } else { - len = virtual_file->file_info->file_size - virtual_file->buffer_pos; - } - - memcpy(&irp->read.bytes[irp->read.pos], virtual_file->buffer + virtual_file->buffer_pos, len); - - virtual_file->buffer_pos += len; - irp->read.pos += len; - - pthread_mutex_unlock(&_patch_net_profile_mutex); - - return CNH_RESULT_SUCCESS; -} - -static enum cnh_result _patch_net_profile_fwrite(struct cnh_filehook_irp* irp, - struct profile_virtual_file* virtual_file) -{ - uint32_t len; - - pthread_mutex_lock(&_patch_net_profile_mutex); - - log_debug("fwrite %s, pos 0x%X, bytes %d", virtual_file->file_info->file_path, virtual_file->buffer_pos, - irp->read.nbytes); - - /* write up to eof, only */ - if (virtual_file->buffer_pos + irp->write.nbytes < virtual_file->file_info->file_size) { - len = irp->write.nbytes; - } else { - len = virtual_file->file_info->file_size - virtual_file->buffer_pos; - } - - memcpy(virtual_file->buffer + virtual_file->buffer_pos, irp->write.bytes, len); - - virtual_file->buffer_pos += len; - virtual_file->is_written = true; - irp->write.pos += len; - - pthread_mutex_unlock(&_patch_net_profile_mutex); - - return CNH_RESULT_SUCCESS; -} - -static enum cnh_result _patch_net_profile_fseek(struct cnh_filehook_irp* irp, - struct profile_virtual_file* virtual_file) -{ - pthread_mutex_lock(&_patch_net_profile_mutex); - - switch (irp->seek_origin) { - case SEEK_SET: - virtual_file->buffer_pos = (size_t) irp->seek_offset; - break; - - case SEEK_CUR: - virtual_file->buffer_pos += (size_t) irp->seek_offset; - break; - - case SEEK_END: - virtual_file->buffer_pos = virtual_file->file_info->file_size; - virtual_file->buffer_pos += (size_t) irp->seek_offset; - break; + case CNH_FILEHOOK_IRP_OP_EOF: + return _patch_net_profile_feof(irp, virt_file); default: - log_die("Unhandled origin %d", irp->seek_origin); - break; + log_die("Unhandled switch case"); + return CNH_RESULT_OTHER_ERROR; + } + } else { + return cnh_filehook_invoke_next(irp); } - - log_debug("fseek %s, offset 0x%X, origin %d", virtual_file->file_info->file_path, irp->seek_offset, - irp->seek_origin); - - pthread_mutex_unlock(&_patch_net_profile_mutex); - - return CNH_RESULT_SUCCESS; + } } -static enum cnh_result _patch_net_profile_ftell(struct cnh_filehook_irp* irp, - struct profile_virtual_file* virtual_file) +static enum cnh_result _patch_net_profile_fopen(struct cnh_filehook_irp *irp) { - pthread_mutex_lock(&_patch_net_profile_mutex); + uint8_t player; + enum pumpnet_lib_file_type file_type; + player = -1; + file_type = PUMPNET_LIB_FILE_TYPE_COUNT; - irp->tell_offset = virtual_file->buffer_pos; + // not a profile file, pass + if (!_patch_net_profile_determine_is_profile_and_player_and_file_type( + irp, &player, &file_type)) { + return cnh_filehook_invoke_next(irp); + } - pthread_mutex_unlock(&_patch_net_profile_mutex); - - return CNH_RESULT_SUCCESS; + return _patch_net_profile_open_pumpnet_profile_file(irp, player, file_type); } -static enum cnh_result _patch_net_profile_feof(struct cnh_filehook_irp* irp, - struct profile_virtual_file* virtual_file) +static enum cnh_result _patch_net_profile_fclose( + struct cnh_filehook_irp *irp, struct profile_virtual_file *virtual_file) { - pthread_mutex_lock(&_patch_net_profile_mutex); + log_debug("fclose %s", virtual_file->file_info->file_path); - irp->eof = virtual_file->buffer_pos == virtual_file->file_info->file_size; + return _patch_net_profile_close_pumpnet_profile_file(virtual_file) ? + CNH_RESULT_SUCCESS : + CNH_RESULT_OTHER_ERROR; +} - pthread_mutex_unlock(&_patch_net_profile_mutex); +static enum cnh_result _patch_net_profile_fread( + struct cnh_filehook_irp *irp, struct profile_virtual_file *virtual_file) +{ + uint32_t len; - return CNH_RESULT_SUCCESS; + pthread_mutex_lock(&_patch_net_profile_mutex); + + log_debug( + "fread %s, pos 0x%X, bytes %d", + virtual_file->file_info->file_path, + virtual_file->buffer_pos, + irp->read.nbytes); + + /* read up to eof, only */ + if (virtual_file->buffer_pos + irp->read.nbytes < + virtual_file->file_info->file_size) { + len = irp->read.nbytes; + } else { + len = virtual_file->file_info->file_size - virtual_file->buffer_pos; + } + + memcpy( + &irp->read.bytes[irp->read.pos], + virtual_file->buffer + virtual_file->buffer_pos, + len); + + virtual_file->buffer_pos += len; + irp->read.pos += len; + + pthread_mutex_unlock(&_patch_net_profile_mutex); + + return CNH_RESULT_SUCCESS; +} + +static enum cnh_result _patch_net_profile_fwrite( + struct cnh_filehook_irp *irp, struct profile_virtual_file *virtual_file) +{ + uint32_t len; + + pthread_mutex_lock(&_patch_net_profile_mutex); + + log_debug( + "fwrite %s, pos 0x%X, bytes %d", + virtual_file->file_info->file_path, + virtual_file->buffer_pos, + irp->read.nbytes); + + /* write up to eof, only */ + if (virtual_file->buffer_pos + irp->write.nbytes < + virtual_file->file_info->file_size) { + len = irp->write.nbytes; + } else { + len = virtual_file->file_info->file_size - virtual_file->buffer_pos; + } + + memcpy( + virtual_file->buffer + virtual_file->buffer_pos, irp->write.bytes, len); + + virtual_file->buffer_pos += len; + virtual_file->is_written = true; + irp->write.pos += len; + + pthread_mutex_unlock(&_patch_net_profile_mutex); + + return CNH_RESULT_SUCCESS; +} + +static enum cnh_result _patch_net_profile_fseek( + struct cnh_filehook_irp *irp, struct profile_virtual_file *virtual_file) +{ + pthread_mutex_lock(&_patch_net_profile_mutex); + + switch (irp->seek_origin) { + case SEEK_SET: + virtual_file->buffer_pos = (size_t) irp->seek_offset; + break; + + case SEEK_CUR: + virtual_file->buffer_pos += (size_t) irp->seek_offset; + break; + + case SEEK_END: + virtual_file->buffer_pos = virtual_file->file_info->file_size; + virtual_file->buffer_pos += (size_t) irp->seek_offset; + break; + + default: + log_die("Unhandled origin %d", irp->seek_origin); + break; + } + + log_debug( + "fseek %s, offset 0x%X, origin %d", + virtual_file->file_info->file_path, + irp->seek_offset, + irp->seek_origin); + + pthread_mutex_unlock(&_patch_net_profile_mutex); + + return CNH_RESULT_SUCCESS; +} + +static enum cnh_result _patch_net_profile_ftell( + struct cnh_filehook_irp *irp, struct profile_virtual_file *virtual_file) +{ + pthread_mutex_lock(&_patch_net_profile_mutex); + + irp->tell_offset = virtual_file->buffer_pos; + + pthread_mutex_unlock(&_patch_net_profile_mutex); + + return CNH_RESULT_SUCCESS; +} + +static enum cnh_result _patch_net_profile_feof( + struct cnh_filehook_irp *irp, struct profile_virtual_file *virtual_file) +{ + pthread_mutex_lock(&_patch_net_profile_mutex); + + irp->eof = virtual_file->buffer_pos == virtual_file->file_info->file_size; + + pthread_mutex_unlock(&_patch_net_profile_mutex); + + return CNH_RESULT_SUCCESS; } // ===================================================================================================================== -static struct profile_virtual_file* _patch_net_profile_get_virtual_mnt_point(FILE* handle) +static struct profile_virtual_file * +_patch_net_profile_get_virtual_mnt_point(FILE *handle) { - for (int i = 0; i < PUMPNET_MAX_NUM_PLAYERS; i++) { - for (int j = 0; j < PUMPNET_LIB_FILE_TYPE_COUNT; j++) { - if (_patch_net_profile_virtual_mnt_points->files[j].handle == handle) { - return &_patch_net_profile_virtual_mnt_points->files[j]; - } - } + for (int i = 0; i < PUMPNET_MAX_NUM_PLAYERS; i++) { + for (int j = 0; j < PUMPNET_LIB_FILE_TYPE_COUNT; j++) { + if (_patch_net_profile_virtual_mnt_points->files[j].handle == handle) { + return &_patch_net_profile_virtual_mnt_points->files[j]; + } } + } - return NULL; + return NULL; } static bool _patch_net_profile_determine_is_profile_and_player_and_file_type( - struct cnh_filehook_irp* irp, - uint8_t* player, - enum pumpnet_lib_file_type* file_type) + struct cnh_filehook_irp *irp, + uint8_t *player, + enum pumpnet_lib_file_type *file_type) { - log_assert(irp); - log_assert(player); - log_assert(file_type); + log_assert(irp); + log_assert(player); + log_assert(file_type); - // compare to static string to avoid slowing everything down - for (int i = 0; i < PUMPNET_MAX_NUM_PLAYERS; i++) { - for (int j = 0; j < PUMPNET_LIB_FILE_TYPE_COUNT; j++) { - if (!strcmp(irp->open_filename, - _patch_net_profile_virtual_mnt_point_infos->player[i].file_info[j].file_path)) { - *player = i; - *file_type = (enum pumpnet_lib_file_type) j; - return true; - } - } + // compare to static string to avoid slowing everything down + for (int i = 0; i < PUMPNET_MAX_NUM_PLAYERS; i++) { + for (int j = 0; j < PUMPNET_LIB_FILE_TYPE_COUNT; j++) { + if (!strcmp( + irp->open_filename, + _patch_net_profile_virtual_mnt_point_infos->player[i] + .file_info[j] + .file_path)) { + *player = i; + *file_type = (enum pumpnet_lib_file_type) j; + return true; + } } + } - return false; + return false; } -static struct profile_virtual_file* _patch_net_profile_setup_virtual_file( - uint8_t player, - enum pumpnet_lib_file_type file_type, - uint64_t player_ref_id) +static struct profile_virtual_file *_patch_net_profile_setup_virtual_file( + uint8_t player, + enum pumpnet_lib_file_type file_type, + uint64_t player_ref_id) { - struct profile_virtual_file* virtual_file; + struct profile_virtual_file *virtual_file; - log_debug("Setup virtual file, player %d, file_type %d", player, file_type); + log_debug("Setup virtual file, player %d, file_type %d", player, file_type); - virtual_file = &_patch_net_profile_virtual_mnt_points[player].files[file_type]; + virtual_file = + &_patch_net_profile_virtual_mnt_points[player].files[file_type]; - // sanity checks - log_assert(!virtual_file->handle); - log_assert(!virtual_file->file_info); - log_assert(!virtual_file->buffer); + // sanity checks + log_assert(!virtual_file->handle); + log_assert(!virtual_file->file_info); + log_assert(!virtual_file->buffer); - virtual_file->player_ref_id = player_ref_id; - virtual_file->handle = cnh_filehook_open_dummy_file_handle(); - virtual_file->file_info = &_patch_net_profile_virtual_mnt_point_infos->player[player].file_info[file_type]; - virtual_file->buffer_pos = 0; - virtual_file->is_written = false; + virtual_file->player_ref_id = player_ref_id; + virtual_file->handle = cnh_filehook_open_dummy_file_handle(); + virtual_file->file_info = + &_patch_net_profile_virtual_mnt_point_infos->player[player] + .file_info[file_type]; + virtual_file->buffer_pos = 0; + virtual_file->is_written = false; - virtual_file->buffer = (uint8_t*) malloc(virtual_file->file_info->file_size); + virtual_file->buffer = (uint8_t *) malloc(virtual_file->file_info->file_size); - log_debug("Setup virtual file done, size %d", virtual_file->file_info->file_size); + log_debug( + "Setup virtual file done, size %d", virtual_file->file_info->file_size); - return virtual_file; + return virtual_file; } -static void _patch_net_profile_destroy_virtual_file(uint8_t player, enum pumpnet_lib_file_type file_type) +static void _patch_net_profile_destroy_virtual_file( + uint8_t player, enum pumpnet_lib_file_type file_type) { - struct profile_virtual_file* virtual_file; + struct profile_virtual_file *virtual_file; - log_debug("Destroying virtual file, player %d, file_type %d", player, file_type); + log_debug( + "Destroying virtual file, player %d, file_type %d", player, file_type); - virtual_file = &_patch_net_profile_virtual_mnt_points[player].files[file_type]; + virtual_file = + &_patch_net_profile_virtual_mnt_points[player].files[file_type]; - // sanity checks - log_assert(virtual_file->handle); - log_assert(virtual_file->file_info); - log_assert(virtual_file->buffer); + // sanity checks + log_assert(virtual_file->handle); + log_assert(virtual_file->file_info); + log_assert(virtual_file->buffer); - cnh_filehook_close_dummy_file_handle(virtual_file->handle); - virtual_file->handle = NULL; - virtual_file->file_info = NULL; - free(virtual_file->buffer); - virtual_file->buffer = NULL; + cnh_filehook_close_dummy_file_handle(virtual_file->handle); + virtual_file->handle = NULL; + virtual_file->file_info = NULL; + free(virtual_file->buffer); + virtual_file->buffer = NULL; } -static bool _patch_net_profile_get_token(int player, uint64_t* player_ref_id) +static bool _patch_net_profile_get_token(int player, uint64_t *player_ref_id) { - log_assert(player_ref_id); - log_assert(player >= 0); - log_assert(player <= 1); + log_assert(player_ref_id); + log_assert(player >= 0); + log_assert(player <= 1); - char path_profile_token[128]; + char path_profile_token[128]; - *player_ref_id = 0; + *player_ref_id = 0; - sprintf(path_profile_token, "/mnt/%d/%s", player, PUMPNET_PROFILE_FILE_NAME); + sprintf(path_profile_token, "/mnt/%d/%s", player, PUMPNET_PROFILE_FILE_NAME); - if (util_fs_path_exists(path_profile_token)) { - log_info("Found pumpnet profile file %s", path_profile_token); + if (util_fs_path_exists(path_profile_token)) { + log_info("Found pumpnet profile file %s", path_profile_token); - if (pumpnet_lib_profile_token_load(path_profile_token, player_ref_id)) { - return true; - } else { - log_error("Loading pumpnet profile token %s failed, fallback to local profiles", path_profile_token); - } + if (pumpnet_lib_profile_token_load(path_profile_token, player_ref_id)) { + return true; } else { - log_info("No pumpnet profile found, fallback to local profile"); + log_error( + "Loading pumpnet profile token %s failed, fallback to local profiles", + path_profile_token); } + } else { + log_info("No pumpnet profile found, fallback to local profile"); + } - return false; + return false; } -static bool _patch_net_profile_download_profile_file(struct profile_virtual_file* virtual_file) +static bool _patch_net_profile_download_profile_file( + struct profile_virtual_file *virtual_file) { - int player; - enum pumpnet_lib_file_type file_type; - uint64_t player_ref_id; + int player; + enum pumpnet_lib_file_type file_type; + uint64_t player_ref_id; - player = virtual_file->file_info->player; - file_type = virtual_file->file_info->file_type; - player_ref_id = virtual_file->player_ref_id; + player = virtual_file->file_info->player; + file_type = virtual_file->file_info->file_type; + player_ref_id = virtual_file->player_ref_id; - log_info("Profile file player %d, file_type %d, refId %llX downloading from server...", + log_info( + "Profile file player %d, file_type %d, refId %llX downloading from " + "server...", + player, + file_type, + player_ref_id); + + if (!pumpnet_lib_get( + file_type, + player_ref_id, + virtual_file->buffer, + virtual_file->file_info->file_size)) { + log_error( + "Downloading file player %d, file_type %d, refId %llX failed", player, file_type, player_ref_id); + return false; + } - if (!pumpnet_lib_get(file_type, player_ref_id, virtual_file->buffer, virtual_file->file_info->file_size)) { - log_error("Downloading file player %d, file_type %d, refId %llX failed", - player, - file_type, - player_ref_id); - return false; - } - - log_info("Downloading file player %d, file_type %d, refId %llX successful", - player, - file_type, - player_ref_id); - return true; + log_info( + "Downloading file player %d, file_type %d, refId %llX successful", + player, + file_type, + player_ref_id); + return true; } static enum cnh_result _patch_net_profile_open_pumpnet_profile_file( - struct cnh_filehook_irp* irp, - uint8_t player, - enum pumpnet_lib_file_type file_type) + struct cnh_filehook_irp *irp, + uint8_t player, + enum pumpnet_lib_file_type file_type) { - uint64_t player_ref_id; + uint64_t player_ref_id; - log_debug("open %s %d %d", irp->open_filename, player, file_type); + log_debug("open %s %d %d", irp->open_filename, player, file_type); - // check if pumpnet.bin token is available and server reachable - // download all profile files on the first file request and hook all following files to virtual endpoints of - // the already downloaded and buffered data - if (_patch_net_profile_get_token(player, &player_ref_id)) { - struct profile_virtual_file* virtual_file = - _patch_net_profile_setup_virtual_file(player, file_type, player_ref_id); + // check if pumpnet.bin token is available and server reachable + // download all profile files on the first file request and hook all following + // files to virtual endpoints of the already downloaded and buffered data + if (_patch_net_profile_get_token(player, &player_ref_id)) { + struct profile_virtual_file *virtual_file = + _patch_net_profile_setup_virtual_file(player, file_type, player_ref_id); - if (_patch_net_profile_download_profile_file(virtual_file)) { - irp->file = virtual_file->handle; - pthread_mutex_unlock(&_patch_net_profile_mutex); + if (_patch_net_profile_download_profile_file(virtual_file)) { + irp->file = virtual_file->handle; + pthread_mutex_unlock(&_patch_net_profile_mutex); - return CNH_RESULT_SUCCESS; - } else { - _patch_net_profile_destroy_virtual_file(player, file_type); + return CNH_RESULT_SUCCESS; + } else { + _patch_net_profile_destroy_virtual_file(player, file_type); - pthread_mutex_unlock(&_patch_net_profile_mutex); + pthread_mutex_unlock(&_patch_net_profile_mutex); - return CNH_RESULT_NO_SUCH_FILE_OR_DIR; - } + return CNH_RESULT_NO_SUCH_FILE_OR_DIR; } + } - return cnh_filehook_invoke_next(irp); + return cnh_filehook_invoke_next(irp); } -static bool _patch_net_profile_upload_profile_file(struct profile_virtual_file* virtual_file) +static bool _patch_net_profile_upload_profile_file( + struct profile_virtual_file *virtual_file) { - int player; - enum pumpnet_lib_file_type file_type; - uint64_t player_ref_id; + int player; + enum pumpnet_lib_file_type file_type; + uint64_t player_ref_id; - player = virtual_file->file_info->player; - file_type = virtual_file->file_info->file_type; - player_ref_id = virtual_file->player_ref_id; + player = virtual_file->file_info->player; + file_type = virtual_file->file_info->file_type; + player_ref_id = virtual_file->player_ref_id; - log_info("Profile file player %d, file_type %d, refId %llX uploading to server...", + log_info( + "Profile file player %d, file_type %d, refId %llX uploading to server...", + player, + file_type, + player_ref_id); + + if (!pumpnet_lib_put( + file_type, + player_ref_id, + virtual_file->buffer, + virtual_file->file_info->file_size)) { + log_error( + "Uploading file player %d, file_type %d, refId %llX failed", player, file_type, player_ref_id); + return false; + } - if (!pumpnet_lib_put(file_type, player_ref_id, virtual_file->buffer, virtual_file->file_info->file_size)) { - log_error("Uploading file player %d, file_type %d, refId %llX failed", - player, - file_type, - player_ref_id); - return false; - } - - log_info("Uploading file player %d, file_type %d, refId %llX successful", - player, - file_type, - player_ref_id); - return true; + log_info( + "Uploading file player %d, file_type %d, refId %llX successful", + player, + file_type, + player_ref_id); + return true; } -static bool _patch_net_profile_close_pumpnet_profile_file(struct profile_virtual_file* virtual_file) +static bool _patch_net_profile_close_pumpnet_profile_file( + struct profile_virtual_file *virtual_file) { - bool res = true; + bool res = true; - pthread_mutex_lock(&_patch_net_profile_mutex); + pthread_mutex_lock(&_patch_net_profile_mutex); - if (virtual_file->is_written) { - res = _patch_net_profile_upload_profile_file(virtual_file); - } + if (virtual_file->is_written) { + res = _patch_net_profile_upload_profile_file(virtual_file); + } - _patch_net_profile_destroy_virtual_file(virtual_file->file_info->player, virtual_file->file_info->file_type); + _patch_net_profile_destroy_virtual_file( + virtual_file->file_info->player, virtual_file->file_info->file_type); - pthread_mutex_unlock(&_patch_net_profile_mutex); + pthread_mutex_unlock(&_patch_net_profile_mutex); - return res; + return res; } // ===================================================================================================================== void patch_net_profile_init( - enum asset_game_version game, - const char* pumpnet_server_addr, - uint64_t machine_id, - const char* cert_dir_path, - bool verbose_debug_log) + enum asset_game_version game, + const char *pumpnet_server_addr, + uint64_t machine_id, + const char *cert_dir_path, + bool verbose_debug_log) { - uint8_t idx; + uint8_t idx; - /* use a switch instead of offset'ing the enum for additional safety and block unsupported games */ - switch (game) { - case ASSET_GAME_VERSION_NX2: - idx = 0; - break; + /* use a switch instead of offset'ing the enum for additional safety and block + * unsupported games */ + switch (game) { + case ASSET_GAME_VERSION_NX2: + idx = 0; + break; -// case PUMPNET_LIB_GAME_NXA: -// idx = 1; -// break; -// -// case PUMPNET_LIB_GAME_FST: -// idx = 2; -// break; -// -// case PUMPNET_LIB_GAME_FEX: -// idx = 3; -// break; -// -// case PUMPNET_LIB_GAME_F2: -// idx = 4; -// break; - case ASSET_GAME_VERSION_NXA: - case ASSET_GAME_VERSION_FIESTA: - case ASSET_GAME_VERSION_FIESTA_EX: - case ASSET_GAME_VERSION_FIESTA_2: + // case PUMPNET_LIB_GAME_NXA: + // idx = 1; + // break; + // + // case PUMPNET_LIB_GAME_FST: + // idx = 2; + // break; + // + // case PUMPNET_LIB_GAME_FEX: + // idx = 3; + // break; + // + // case PUMPNET_LIB_GAME_F2: + // idx = 4; + // break; + case ASSET_GAME_VERSION_NXA: + case ASSET_GAME_VERSION_FIESTA: + case ASSET_GAME_VERSION_FIESTA_EX: + case ASSET_GAME_VERSION_FIESTA_2: - default: - log_error("Unsupported game version %d specified, disabled network service", game); - return; + default: + log_error( + "Unsupported game version %d specified, disabled network service", + game); + return; + } + + _patch_net_profile_file_info_ref = + &_patch_net_profile_virtual_mnt_point_infos[idx]; + + size_t max_data_size = 0; + + // determine max file size for network buffers, file sizes identical on for + // all players. + for (int i = 0; i < PUMPNET_LIB_FILE_TYPE_COUNT; i++) { + max_data_size += + _patch_net_profile_file_info_ref->player[0].file_info[i].file_size; + } + + // set buffers to NULL to detect illegal states + for (int i = 0; i < PUMPNET_LIB_FILE_TYPE_COUNT; i++) { + for (int j = 0; j < PUMPNET_MAX_NUM_PLAYERS; j++) { + _patch_net_profile_virtual_mnt_points[j].files[i].player_ref_id = 0; + _patch_net_profile_virtual_mnt_points[j].files[i].handle = NULL; + _patch_net_profile_virtual_mnt_points[j].files[i].file_info = NULL; + _patch_net_profile_virtual_mnt_points[j].files[i].buffer = NULL; } + } - _patch_net_profile_file_info_ref = &_patch_net_profile_virtual_mnt_point_infos[idx]; + pumpnet_lib_init( + game, pumpnet_server_addr, machine_id, cert_dir_path, verbose_debug_log); - size_t max_data_size = 0; + cnh_filehook_push_handler(_patch_net_profile_filehook); - // determine max file size for network buffers, file sizes identical on for all players. - for (int i = 0; i < PUMPNET_LIB_FILE_TYPE_COUNT; i++) { - max_data_size += _patch_net_profile_file_info_ref->player[0].file_info[i].file_size; - } + pthread_mutex_init(&_patch_net_profile_mutex, NULL); - // set buffers to NULL to detect illegal states - for (int i = 0; i < PUMPNET_LIB_FILE_TYPE_COUNT; i++) { - for (int j = 0; j < PUMPNET_MAX_NUM_PLAYERS; j++) { - _patch_net_profile_virtual_mnt_points[j].files[i].player_ref_id = 0; - _patch_net_profile_virtual_mnt_points[j].files[i].handle = NULL; - _patch_net_profile_virtual_mnt_points[j].files[i].file_info = NULL; - _patch_net_profile_virtual_mnt_points[j].files[i].buffer = NULL; - } - } - - pumpnet_lib_init(game, pumpnet_server_addr, machine_id, cert_dir_path, verbose_debug_log); - - cnh_filehook_push_handler(_patch_net_profile_filehook); - - pthread_mutex_init(&_patch_net_profile_mutex, NULL); - - log_info("Initialized: game %d, server %s, machine id %llX", game, pumpnet_server_addr, machine_id); + log_info( + "Initialized: game %d, server %s, machine id %llX", + game, + pumpnet_server_addr, + machine_id); } void patch_net_profile_shutdown() { - pumpnet_lib_shutdown(); + pumpnet_lib_shutdown(); - pthread_mutex_destroy(&_patch_net_profile_mutex); + pthread_mutex_destroy(&_patch_net_profile_mutex); - log_info("Shut down"); + log_info("Shut down"); } \ No newline at end of file diff --git a/src/main/hook/patch/net-profile.h b/src/main/hook/patch/net-profile.h index 2d5e254..26a7526 100644 --- a/src/main/hook/patch/net-profile.h +++ b/src/main/hook/patch/net-profile.h @@ -1,5 +1,6 @@ /** - * Patch module to redirect profile saving and loading to a pumpnet server (NX2 to Fiesta 2). + * Patch module to redirect profile saving and loading to a pumpnet server (NX2 + * to Fiesta 2). */ #ifndef HOOK_PATCH_NET_PROFILE_H #define HOOK_PATCH_NET_PROFILE_H @@ -12,16 +13,17 @@ * @param game Game version to run this module on * @param pumpnet_server_addr Server address of pumpnet to connect to * @param machine_id Machine ID to use for authentication - * @param cert_dir_path Path to a directory containing the client cert, client key and CA cert bundle to enable https - * communication - * @param verbose_debug_log Enable verbose debug log output, e.g. network backend logging/traffic. + * @param cert_dir_path Path to a directory containing the client cert, client + * key and CA cert bundle to enable https communication + * @param verbose_debug_log Enable verbose debug log output, e.g. network + * backend logging/traffic. */ void patch_net_profile_init( - enum asset_game_version game, - const char* pumpnet_server_addr, - uint64_t machine_id, - const char* cert_dir_path, - bool verbose_debug_log); + enum asset_game_version game, + const char *pumpnet_server_addr, + uint64_t machine_id, + const char *cert_dir_path, + bool verbose_debug_log); /** * Shut down the module. diff --git a/src/main/hook/patch/network.c b/src/main/hook/patch/network.c index aea31dc..3c8c017 100644 --- a/src/main/hook/patch/network.c +++ b/src/main/hook/patch/network.c @@ -1,7 +1,7 @@ #define LOG_MODULE "patch-network" -#include #include +#include #include "capnhook/hook/lib.h" @@ -11,13 +11,14 @@ #include "util/str.h" struct patch_network_redirect_elem { - struct util_list_node head; - char* orig_ipv4; - char* new_ipv4; - uint16_t new_port; + struct util_list_node head; + char *orig_ipv4; + char *new_ipv4; + uint16_t new_port; }; -typedef int (*connect_t) (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len); +typedef int (*connect_t)( + int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len); static connect_t patch_network_real_connect; @@ -26,71 +27,82 @@ static struct util_list patch_network_redirect_list; int connect(int fd, __CONST_SOCKADDR_ARG addr, socklen_t len) { - if (!patch_network_real_connect) { - patch_network_real_connect = (connect_t) cnh_lib_get_func_addr("connect"); - } + if (!patch_network_real_connect) { + patch_network_real_connect = (connect_t) cnh_lib_get_func_addr("connect"); + } - if (patch_network_initialized) { - if (addr.__sockaddr__->sa_family == AF_INET) { - log_debug("connect ipv4 %d.%d.%d.%d:%d", - addr.__sockaddr_in__->sin_addr.s_addr & 0xFF, - addr.__sockaddr_in__->sin_addr.s_addr >> 8 & 0xFF, - addr.__sockaddr_in__->sin_addr.s_addr >> 16 & 0xFF, - addr.__sockaddr_in__->sin_addr.s_addr >> 24 & 0xFF, - addr.__sockaddr_in__->sin_port); + if (patch_network_initialized) { + if (addr.__sockaddr__->sa_family == AF_INET) { + log_debug( + "connect ipv4 %d.%d.%d.%d:%d", + addr.__sockaddr_in__->sin_addr.s_addr & 0xFF, + addr.__sockaddr_in__->sin_addr.s_addr >> 8 & 0xFF, + addr.__sockaddr_in__->sin_addr.s_addr >> 16 & 0xFF, + addr.__sockaddr_in__->sin_addr.s_addr >> 24 & 0xFF, + addr.__sockaddr_in__->sin_port); - struct util_list_node* pos; - struct patch_network_redirect_elem* elem; - struct sockaddr_in tmp; + struct util_list_node *pos; + struct patch_network_redirect_elem *elem; + struct sockaddr_in tmp; - for (pos = patch_network_redirect_list.head; pos != NULL; pos = pos->next) { - elem = containerof(pos, struct patch_network_redirect_elem, head); + for (pos = patch_network_redirect_list.head; pos != NULL; + pos = pos->next) { + elem = containerof(pos, struct patch_network_redirect_elem, head); - inet_aton(elem->orig_ipv4, &tmp.sin_addr); + inet_aton(elem->orig_ipv4, &tmp.sin_addr); - if (addr.__sockaddr_in__->sin_addr.s_addr == tmp.sin_addr.s_addr) { - char* tmp_old = inet_ntoa(addr.__sockaddr_in__->sin_addr); - log_info("Redirect %s:%d -> %s:%d", tmp_old, - ((struct sockaddr_in*) addr.__sockaddr_in__)->sin_port, elem->new_ipv4, - elem->new_port != 0xFFFF ? elem->new_port : - ((struct sockaddr_in*) addr.__sockaddr_in__)->sin_port); + if (addr.__sockaddr_in__->sin_addr.s_addr == tmp.sin_addr.s_addr) { + char *tmp_old = inet_ntoa(addr.__sockaddr_in__->sin_addr); + log_info( + "Redirect %s:%d -> %s:%d", + tmp_old, + ((struct sockaddr_in *) addr.__sockaddr_in__)->sin_port, + elem->new_ipv4, + elem->new_port != 0xFFFF ? + elem->new_port : + ((struct sockaddr_in *) addr.__sockaddr_in__)->sin_port); - inet_aton(elem->new_ipv4, &((struct sockaddr_in*) addr.__sockaddr_in__)->sin_addr); + inet_aton( + elem->new_ipv4, + &((struct sockaddr_in *) addr.__sockaddr_in__)->sin_addr); - if (elem->new_port != 0xFFFF) { - ((struct sockaddr_in*) addr.__sockaddr_in__)->sin_port = htons(elem->new_port); - } - } - } - } else { - log_debug("connect, addr family: %d", addr.__sockaddr__->sa_family); + if (elem->new_port != 0xFFFF) { + ((struct sockaddr_in *) addr.__sockaddr_in__)->sin_port = + htons(elem->new_port); + } } + } + } else { + log_debug("connect, addr family: %d", addr.__sockaddr__->sa_family); } + } - return patch_network_real_connect(fd, addr, len); + return patch_network_real_connect(fd, addr, len); } void patch_network_init() { - util_list_init(&patch_network_redirect_list); - patch_network_initialized = true; - log_info("Initialized"); + util_list_init(&patch_network_redirect_list); + patch_network_initialized = true; + log_info("Initialized"); } -void patch_network_redirect_server_address(const char* orig_ipv4, const char* new_ipv4, uint16_t new_port) +void patch_network_redirect_server_address( + const char *orig_ipv4, const char *new_ipv4, uint16_t new_port) { - struct patch_network_redirect_elem* elem; + struct patch_network_redirect_elem *elem; - elem = util_xmalloc(sizeof(struct patch_network_redirect_elem)); - elem->orig_ipv4 = util_str_dup(orig_ipv4); - elem->new_ipv4 = util_str_dup(new_ipv4); - elem->new_port = new_port; + elem = util_xmalloc(sizeof(struct patch_network_redirect_elem)); + elem->orig_ipv4 = util_str_dup(orig_ipv4); + elem->new_ipv4 = util_str_dup(new_ipv4); + elem->new_port = new_port; - util_list_append(&patch_network_redirect_list, &elem->head); + util_list_append(&patch_network_redirect_list, &elem->head); - if (new_port != 0xFFFF) { - log_info("Add network redirect: %s -> %s:%d", orig_ipv4, new_ipv4, new_port); - } else { - log_info("Add network redirect: %s -> %s", orig_ipv4, new_ipv4); - } + if (new_port != 0xFFFF) { + log_info( + "Add network redirect: %s -> %s:%d", orig_ipv4, new_ipv4, new_port); + } else { + log_info("Add network redirect: %s -> %s", orig_ipv4, new_ipv4); + } } diff --git a/src/main/hook/patch/network.h b/src/main/hook/patch/network.h index 3548ff9..f9d98d5 100644 --- a/src/main/hook/patch/network.h +++ b/src/main/hook/patch/network.h @@ -18,6 +18,7 @@ void patch_network_init(); * @param new_ipv4 IPV4 address of the new server to redirect to * @param new_port Port of server to redirect to (-1 to keep old port) */ -void patch_network_redirect_server_address(const char* orig_ipv4, const char* new_ipv4, uint16_t new_port); +void patch_network_redirect_server_address( + const char *orig_ipv4, const char *new_ipv4, uint16_t new_port); #endif \ No newline at end of file diff --git a/src/main/hook/patch/piubtn.c b/src/main/hook/patch/piubtn.c index 3a8526b..4364c36 100644 --- a/src/main/hook/patch/piubtn.c +++ b/src/main/hook/patch/piubtn.c @@ -17,12 +17,17 @@ static bool _patch_piubtn_enumerate(bool real_exists); static enum cnh_result _patch_piubtn_open(void); static enum cnh_result _patch_piubtn_reset(void); -static enum cnh_result _patch_piubtn_control_msg(int request_type, int request, int value, int index, - struct cnh_iobuf* buffer, int timeout); +static enum cnh_result _patch_piubtn_control_msg( + int request_type, + int request, + int value, + int index, + struct cnh_iobuf *buffer, + int timeout); static void _patch_piubtn_close(void); -static enum cnh_result _patch_piubtn_process_inputs(struct cnh_iobuf* buffer); -static enum cnh_result _patch_piubtn_process_outputs(struct cnh_iobuf* buffer); +static enum cnh_result _patch_piubtn_process_inputs(struct cnh_iobuf *buffer); +static enum cnh_result _patch_piubtn_process_outputs(struct cnh_iobuf *buffer); static ptapi_io_piubtn_ident_t _patch_piubtn_ptapi_io_piubtn_ident; static ptapi_io_piubtn_open_t _patch_piubtn_ptapi_io_piubtn_open; @@ -42,251 +47,272 @@ static const struct cnh_usb_emu_virtdev_ep _patch_piubtn_virtdev = { .close = _patch_piubtn_close, }; -static void* _patch_piubtn_api_lib_handle; +static void *_patch_piubtn_api_lib_handle; -void patch_piubtn_init(const char* piubtn_lib_path) +void patch_piubtn_init(const char *piubtn_lib_path) { - if (!piubtn_lib_path) { - log_die("No piubtn emulation library path specified"); - } + if (!piubtn_lib_path) { + log_die("No piubtn emulation library path specified"); + } - /* Load piubtn library funcs */ - log_info("Loading piubtn api implementation %s", piubtn_lib_path); + /* Load piubtn library funcs */ + log_info("Loading piubtn api implementation %s", piubtn_lib_path); - _patch_piubtn_api_lib_handle = cnh_lib_load(piubtn_lib_path); + _patch_piubtn_api_lib_handle = cnh_lib_load(piubtn_lib_path); - _patch_piubtn_ptapi_io_piubtn_ident = (ptapi_io_piubtn_ident_t) - cnh_lib_get_func_addr_handle(_patch_piubtn_api_lib_handle, "ptapi_io_piubtn_ident"); + _patch_piubtn_ptapi_io_piubtn_ident = + (ptapi_io_piubtn_ident_t) cnh_lib_get_func_addr_handle( + _patch_piubtn_api_lib_handle, "ptapi_io_piubtn_ident"); - _patch_piubtn_ptapi_io_piubtn_open = (ptapi_io_piubtn_open_t) - cnh_lib_get_func_addr_handle(_patch_piubtn_api_lib_handle, "ptapi_io_piubtn_open"); - _patch_piubtn_ptapi_io_piubtn_close = (ptapi_io_piubtn_close_t) - cnh_lib_get_func_addr_handle(_patch_piubtn_api_lib_handle, "ptapi_io_piubtn_close"); - _patch_piubtn_ptapi_io_piubtn_recv = (ptapi_io_piubtn_recv_t) - cnh_lib_get_func_addr_handle(_patch_piubtn_api_lib_handle, "ptapi_io_piubtn_recv"); - _patch_piubtn_ptapi_io_piubtn_send = (ptapi_io_piubtn_send_t) - cnh_lib_get_func_addr_handle(_patch_piubtn_api_lib_handle, "ptapi_io_piubtn_send"); - _patch_piubtn_ptapi_io_piubtn_get_input = (ptapi_io_piubtn_get_input_t) - cnh_lib_get_func_addr_handle(_patch_piubtn_api_lib_handle, "ptapi_io_piubtn_get_input"); - _patch_piubtn_ptapi_io_piubtn_set_output = (ptapi_io_piubtn_set_output_t) - cnh_lib_get_func_addr_handle(_patch_piubtn_api_lib_handle, "ptapi_io_piubtn_set_output"); + _patch_piubtn_ptapi_io_piubtn_open = + (ptapi_io_piubtn_open_t) cnh_lib_get_func_addr_handle( + _patch_piubtn_api_lib_handle, "ptapi_io_piubtn_open"); + _patch_piubtn_ptapi_io_piubtn_close = + (ptapi_io_piubtn_close_t) cnh_lib_get_func_addr_handle( + _patch_piubtn_api_lib_handle, "ptapi_io_piubtn_close"); + _patch_piubtn_ptapi_io_piubtn_recv = + (ptapi_io_piubtn_recv_t) cnh_lib_get_func_addr_handle( + _patch_piubtn_api_lib_handle, "ptapi_io_piubtn_recv"); + _patch_piubtn_ptapi_io_piubtn_send = + (ptapi_io_piubtn_send_t) cnh_lib_get_func_addr_handle( + _patch_piubtn_api_lib_handle, "ptapi_io_piubtn_send"); + _patch_piubtn_ptapi_io_piubtn_get_input = + (ptapi_io_piubtn_get_input_t) cnh_lib_get_func_addr_handle( + _patch_piubtn_api_lib_handle, "ptapi_io_piubtn_get_input"); + _patch_piubtn_ptapi_io_piubtn_set_output = + (ptapi_io_piubtn_set_output_t) cnh_lib_get_func_addr_handle( + _patch_piubtn_api_lib_handle, "ptapi_io_piubtn_set_output"); - cnh_usb_emu_add_virtdevep(&_patch_piubtn_virtdev); + cnh_usb_emu_add_virtdevep(&_patch_piubtn_virtdev); - log_info("Initialized"); + log_info("Initialized"); } void patch_piubtn_shutdown(void) { - } static bool _patch_piubtn_enumerate(bool real_exists) { - if (real_exists) { - log_info("Real PIUBTN exists but emulation enabled, blocking real"); - } else { - log_info("Enumerating PIUBTN emulation"); - } + if (real_exists) { + log_info("Real PIUBTN exists but emulation enabled, blocking real"); + } else { + log_info("Enumerating PIUBTN emulation"); + } - return true; + return true; } static enum cnh_result _patch_piubtn_open(void) { - log_info("Opening PIUBTN: %s", _patch_piubtn_ptapi_io_piubtn_ident()); + log_info("Opening PIUBTN: %s", _patch_piubtn_ptapi_io_piubtn_ident()); - if (!_patch_piubtn_ptapi_io_piubtn_open()) { - log_error("Opening api piubtn %s failed", _patch_piubtn_ptapi_io_piubtn_ident()); - return CNH_RESULT_OTHER_ERROR; - } + if (!_patch_piubtn_ptapi_io_piubtn_open()) { + log_error( + "Opening api piubtn %s failed", _patch_piubtn_ptapi_io_piubtn_ident()); + return CNH_RESULT_OTHER_ERROR; + } - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } static enum cnh_result _patch_piubtn_reset(void) { - log_info("Resetting PIUBTN: %s", _patch_piubtn_ptapi_io_piubtn_ident()); + log_info("Resetting PIUBTN: %s", _patch_piubtn_ptapi_io_piubtn_ident()); - _patch_piubtn_ptapi_io_piubtn_close(); + _patch_piubtn_ptapi_io_piubtn_close(); - if (!_patch_piubtn_ptapi_io_piubtn_open()) { - log_error("Resetting api piubtn %s failed", _patch_piubtn_ptapi_io_piubtn_ident()); - return CNH_RESULT_OTHER_ERROR; - } + if (!_patch_piubtn_ptapi_io_piubtn_open()) { + log_error( + "Resetting api piubtn %s failed", + _patch_piubtn_ptapi_io_piubtn_ident()); + return CNH_RESULT_OTHER_ERROR; + } - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } -static enum cnh_result _patch_piubtn_control_msg(int request_type, int request, int value, int index, - struct cnh_iobuf* buffer, int timeout) +static enum cnh_result _patch_piubtn_control_msg( + int request_type, + int request, + int value, + int index, + struct cnh_iobuf *buffer, + int timeout) { - if (request_type == PIUBTN_DRV_USB_CTRL_TYPE_IN && request == PIUBTN_DRV_USB_CTRL_REQUEST) { - if (buffer->nbytes != PIUBTN_DRV_BUFFER_SIZE) { - log_error("Invalid buffer size for ctrl in: %d", buffer->nbytes); - return CNH_RESULT_INVALID_PARAMETER; - } - - return _patch_piubtn_process_inputs(buffer); - } else if (request_type == PIUBTN_DRV_USB_CTRL_TYPE_OUT && request == PIUBTN_DRV_USB_CTRL_REQUEST) { - if (buffer->nbytes != PIUBTN_DRV_BUFFER_SIZE) { - log_error("Invalid buffer size for ctrl out: %d", buffer->nbytes); - return CNH_RESULT_INVALID_PARAMETER; - } - - return _patch_piubtn_process_outputs(buffer); - } else { - log_error("Invalid usb control request to PIUBTN: 0x%02X", request); - return CNH_RESULT_INVALID_PARAMETER; + if (request_type == PIUBTN_DRV_USB_CTRL_TYPE_IN && + request == PIUBTN_DRV_USB_CTRL_REQUEST) { + if (buffer->nbytes != PIUBTN_DRV_BUFFER_SIZE) { + log_error("Invalid buffer size for ctrl in: %d", buffer->nbytes); + return CNH_RESULT_INVALID_PARAMETER; } + + return _patch_piubtn_process_inputs(buffer); + } else if ( + request_type == PIUBTN_DRV_USB_CTRL_TYPE_OUT && + request == PIUBTN_DRV_USB_CTRL_REQUEST) { + if (buffer->nbytes != PIUBTN_DRV_BUFFER_SIZE) { + log_error("Invalid buffer size for ctrl out: %d", buffer->nbytes); + return CNH_RESULT_INVALID_PARAMETER; + } + + return _patch_piubtn_process_outputs(buffer); + } else { + log_error("Invalid usb control request to PIUBTN: 0x%02X", request); + return CNH_RESULT_INVALID_PARAMETER; + } } static void _patch_piubtn_close(void) { - log_info("Closing PIUBTN: %s", _patch_piubtn_ptapi_io_piubtn_ident()); + log_info("Closing PIUBTN: %s", _patch_piubtn_ptapi_io_piubtn_ident()); - _patch_piubtn_ptapi_io_piubtn_close(); + _patch_piubtn_ptapi_io_piubtn_close(); } -static enum cnh_result _patch_piubtn_process_inputs(struct cnh_iobuf* buffer) +static enum cnh_result _patch_piubtn_process_inputs(struct cnh_iobuf *buffer) { - struct ptapi_io_piubtn_inputs p1; - struct ptapi_io_piubtn_inputs p2; + struct ptapi_io_piubtn_inputs p1; + struct ptapi_io_piubtn_inputs p2; - if (!_patch_piubtn_ptapi_io_piubtn_recv()) { - log_error("Receiving inputs on api piubtn %s failed", _patch_piubtn_ptapi_io_piubtn_ident()); - return CNH_RESULT_OTHER_ERROR; - } + if (!_patch_piubtn_ptapi_io_piubtn_recv()) { + log_error( + "Receiving inputs on api piubtn %s failed", + _patch_piubtn_ptapi_io_piubtn_ident()); + return CNH_RESULT_OTHER_ERROR; + } - memset(&p1, 0, sizeof(p1)); - memset(&p2, 0, sizeof(p2)); + memset(&p1, 0, sizeof(p1)); + memset(&p2, 0, sizeof(p2)); - _patch_piubtn_ptapi_io_piubtn_get_input(0, &p1); - _patch_piubtn_ptapi_io_piubtn_get_input(1, &p2); + _patch_piubtn_ptapi_io_piubtn_get_input(0, &p1); + _patch_piubtn_ptapi_io_piubtn_get_input(1, &p2); - memset(buffer->bytes, 0, PIUBTN_DRV_BUFFER_SIZE); + memset(buffer->bytes, 0, PIUBTN_DRV_BUFFER_SIZE); - /* - byte 0: - bit 0: P1 back (red) - bit 1: P1 left - bit 2: P1 right - bit 3: P1 start (green) - bit 4: P2 back (red) - bit 5: P2 left - bit 6: P2 right - bit 7: P2 start (green) - */ + /* + byte 0: + bit 0: P1 back (red) + bit 1: P1 left + bit 2: P1 right + bit 3: P1 start (green) + bit 4: P2 back (red) + bit 5: P2 left + bit 6: P2 right + bit 7: P2 start (green) + */ - /* Player 1 */ - if (p1.back) { - buffer->bytes[0] |= (1 << 0); - } + /* Player 1 */ + if (p1.back) { + buffer->bytes[0] |= (1 << 0); + } - if (p1.left) { - buffer->bytes[0] |= (1 << 1); - } + if (p1.left) { + buffer->bytes[0] |= (1 << 1); + } - if (p1.right) { - buffer->bytes[0] |= (1 << 2); - } + if (p1.right) { + buffer->bytes[0] |= (1 << 2); + } - if (p1.start) { - buffer->bytes[0] |= (1 << 3); - } + if (p1.start) { + buffer->bytes[0] |= (1 << 3); + } - /* Player 2 */ - if (p2.back) { - buffer->bytes[0] |= (1 << 4); - } + /* Player 2 */ + if (p2.back) { + buffer->bytes[0] |= (1 << 4); + } - if (p2.left) { - buffer->bytes[0] |= (1 << 5); - } + if (p2.left) { + buffer->bytes[0] |= (1 << 5); + } - if (p2.right) { - buffer->bytes[0] |= (1 << 6); - } + if (p2.right) { + buffer->bytes[0] |= (1 << 6); + } - if (p2.start) { - buffer->bytes[0] |= (1 << 7); - } + if (p2.start) { + buffer->bytes[0] |= (1 << 7); + } - /* xor inputs because pullup active */ - for (int i = 0; i < PIUBTN_DRV_BUFFER_SIZE; i++) { - buffer->bytes[i] ^= 0xFF; - } + /* xor inputs because pullup active */ + for (int i = 0; i < PIUBTN_DRV_BUFFER_SIZE; i++) { + buffer->bytes[i] ^= 0xFF; + } - buffer->pos = PIUBTN_DRV_BUFFER_SIZE; + buffer->pos = PIUBTN_DRV_BUFFER_SIZE; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } -static enum cnh_result _patch_piubtn_process_outputs(struct cnh_iobuf* buffer) +static enum cnh_result _patch_piubtn_process_outputs(struct cnh_iobuf *buffer) { - struct ptapi_io_piubtn_outputs p1; - struct ptapi_io_piubtn_outputs p2; + struct ptapi_io_piubtn_outputs p1; + struct ptapi_io_piubtn_outputs p2; - memset(&p1, 0, sizeof(p1)); - memset(&p2, 0, sizeof(p2)); + memset(&p1, 0, sizeof(p1)); + memset(&p2, 0, sizeof(p2)); - /* - byte 0: - bit 0: p1 start (green) - bit 1: p1 right - bit 2: p1 left - bit 3: p1 back (red) - bit 4: p2 start (green) - bit 5: p2 right - bit 6: p2 left - bit 7: p2 back (red) - */ + /* + byte 0: + bit 0: p1 start (green) + bit 1: p1 right + bit 2: p1 left + bit 3: p1 back (red) + bit 4: p2 start (green) + bit 5: p2 right + bit 6: p2 left + bit 7: p2 back (red) + */ - /* Player 1 */ + /* Player 1 */ - if (buffer->bytes[0] & (1 << 0)) { - p1.start = true; - } + if (buffer->bytes[0] & (1 << 0)) { + p1.start = true; + } - if (buffer->bytes[0] & (1 << 1)) { - p1.back = true; - } + if (buffer->bytes[0] & (1 << 1)) { + p1.back = true; + } - if (buffer->bytes[0] & (1 << 2)) { - p1.left = true; - } + if (buffer->bytes[0] & (1 << 2)) { + p1.left = true; + } - if (buffer->bytes[0] & (1 << 3)) { - p1.right = true; - } + if (buffer->bytes[0] & (1 << 3)) { + p1.right = true; + } - /* Player 2 */ + /* Player 2 */ - if (buffer->bytes[0] & (1 << 4)) { - p2.start = true; - } + if (buffer->bytes[0] & (1 << 4)) { + p2.start = true; + } - if (buffer->bytes[0] & (1 << 5)) { - p2.right = true; - } + if (buffer->bytes[0] & (1 << 5)) { + p2.right = true; + } - if (buffer->bytes[0] & (1 << 6)) { - p2.left = true; - } + if (buffer->bytes[0] & (1 << 6)) { + p2.left = true; + } - if (buffer->bytes[0] & (1 << 7)) { - p2.back = true; - } + if (buffer->bytes[0] & (1 << 7)) { + p2.back = true; + } - _patch_piubtn_ptapi_io_piubtn_set_output(0, &p1); - _patch_piubtn_ptapi_io_piubtn_set_output(1, &p2); + _patch_piubtn_ptapi_io_piubtn_set_output(0, &p1); + _patch_piubtn_ptapi_io_piubtn_set_output(1, &p2); - if (!_patch_piubtn_ptapi_io_piubtn_send()) { - log_error("Sending outputs on api piubtn %s failed", _patch_piubtn_ptapi_io_piubtn_ident()); - return CNH_RESULT_OTHER_ERROR; - } + if (!_patch_piubtn_ptapi_io_piubtn_send()) { + log_error( + "Sending outputs on api piubtn %s failed", + _patch_piubtn_ptapi_io_piubtn_ident()); + return CNH_RESULT_OTHER_ERROR; + } - buffer->pos = PIUBTN_DRV_BUFFER_SIZE; + buffer->pos = PIUBTN_DRV_BUFFER_SIZE; - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } \ No newline at end of file diff --git a/src/main/hook/patch/piubtn.h b/src/main/hook/patch/piubtn.h index 31b0b56..12a046c 100644 --- a/src/main/hook/patch/piubtn.h +++ b/src/main/hook/patch/piubtn.h @@ -15,14 +15,16 @@ * @param piubtn_lib_path Path to a library implementing the piubtn API * @param real_passthrough True to ignore the library and disable any emulation */ -void patch_piubtn_init(const char* piubtn_lib_path); +void patch_piubtn_init(const char *piubtn_lib_path); /** * Get the input hook handler provided by the piubtn library. * - * @return Input hook handler for main-loop patch module or NULL if none is used. + * @return Input hook handler for main-loop patch module or NULL if none is + * used. */ -const struct pumptools_input_hook_handler* patch_piubtn_get_input_hook_handler(void); +const struct pumptools_input_hook_handler * +patch_piubtn_get_input_hook_handler(void); /** * Shut down the patch module diff --git a/src/main/hook/patch/piuio-exit.c b/src/main/hook/patch/piuio-exit.c index 851c13d..12cb2c5 100644 --- a/src/main/hook/patch/piuio-exit.c +++ b/src/main/hook/patch/piuio-exit.c @@ -7,83 +7,84 @@ static enum cnh_result patch_piuio_exit_usbhook(struct cnh_usbhook_irp *irp); -static usb_dev_handle* _patch_piuio_exit_usb_handle; +static usb_dev_handle *_patch_piuio_exit_usb_handle; void patch_piuio_exit_init() { - cnh_usbhook_push_handler(patch_piuio_exit_usbhook); - log_info("Initialized"); + cnh_usbhook_push_handler(patch_piuio_exit_usbhook); + log_info("Initialized"); } static enum cnh_result patch_piuio_exit_usbhook(struct cnh_usbhook_irp *irp) { - enum cnh_result result; + enum cnh_result result; - if (irp->op != CNH_USBHOOK_IRP_OP_OPEN && _patch_piuio_exit_usb_handle != irp->handle) { - return cnh_usbhook_invoke_next(irp); + if (irp->op != CNH_USBHOOK_IRP_OP_OPEN && + _patch_piuio_exit_usb_handle != irp->handle) { + return cnh_usbhook_invoke_next(irp); + } + + switch (irp->op) { + case CNH_USBHOOK_IRP_OP_OPEN: { + if (irp->open_usb_dev->descriptor.idVendor == PIUIO_DRV_VID && + irp->open_usb_dev->descriptor.idProduct == PIUIO_DRV_PID) { + + if (_patch_piuio_exit_usb_handle) { + log_warn("Already detected PIUIO previously, ignore re-detection?"); + + irp->handle = _patch_piuio_exit_usb_handle; + result = CNH_RESULT_SUCCESS; + } else { + log_info("Detected PIUIO"); + + result = cnh_usbhook_invoke_next(irp); + + if (result == CNH_RESULT_SUCCESS) { + _patch_piuio_exit_usb_handle = irp->handle; + } + } + } else { + result = cnh_usbhook_invoke_next(irp); + } + + break; } - switch (irp->op) { - case CNH_USBHOOK_IRP_OP_OPEN: - { - if (irp->open_usb_dev->descriptor.idVendor == PIUIO_DRV_VID && - irp->open_usb_dev->descriptor.idProduct == PIUIO_DRV_PID) { + case CNH_USBHOOK_IRP_OP_CTRL_MSG: { + result = cnh_usbhook_invoke_next(irp); - if (_patch_piuio_exit_usb_handle) { - log_warn("Already detected PIUIO previously, ignore re-detection?"); - - irp->handle = _patch_piuio_exit_usb_handle; - result = CNH_RESULT_SUCCESS; - } else { - log_info("Detected PIUIO"); - - result = cnh_usbhook_invoke_next(irp); - - if (result == CNH_RESULT_SUCCESS) { - _patch_piuio_exit_usb_handle = irp->handle; - } - } - } else { - result = cnh_usbhook_invoke_next(irp); - } - - break; + /* Post process inputs */ + if (irp->ctrl_req_type == PIUIO_DRV_USB_CTRL_TYPE_IN && + irp->ctrl_req == PIUIO_DRV_USB_CTRL_REQUEST) { + if (irp->ctrl_buffer.nbytes != PIUIO_DRV_BUFFER_SIZE) { + log_error( + "Invalid buffer size for ctrl in: %d", irp->ctrl_buffer.nbytes); + } else { + /* Service + Test button pressed */ + /* Invert data -> pull up active */ + if (((~irp->ctrl_buffer.bytes[1]) & (1 << 1)) && + ((~irp->ctrl_buffer.bytes[1]) & (1 << 6))) { + log_info("Exit on service + test enabled and hit, bye"); + exit(0); + } } + } - case CNH_USBHOOK_IRP_OP_CTRL_MSG: - { - result = cnh_usbhook_invoke_next(irp); - - /* Post process inputs */ - if (irp->ctrl_req_type == PIUIO_DRV_USB_CTRL_TYPE_IN && irp->ctrl_req == PIUIO_DRV_USB_CTRL_REQUEST) { - if (irp->ctrl_buffer.nbytes != PIUIO_DRV_BUFFER_SIZE) { - log_error("Invalid buffer size for ctrl in: %d", irp->ctrl_buffer.nbytes); - } else { - /* Service + Test button pressed */ - /* Invert data -> pull up active */ - if (((~irp->ctrl_buffer.bytes[1]) & (1 << 1)) && ((~irp->ctrl_buffer.bytes[1]) & (1 << 6))) { - log_info("Exit on service + test enabled and hit, bye"); - exit(0); - } - } - } - - break; - } - - case CNH_USBHOOK_IRP_OP_CLOSE: - { - _patch_piuio_exit_usb_handle = NULL; - - result = cnh_usbhook_invoke_next(irp); - - break; - } - - default: - result = cnh_usbhook_invoke_next(irp); - break; + break; } - return result; + case CNH_USBHOOK_IRP_OP_CLOSE: { + _patch_piuio_exit_usb_handle = NULL; + + result = cnh_usbhook_invoke_next(irp); + + break; + } + + default: + result = cnh_usbhook_invoke_next(irp); + break; + } + + return result; } \ No newline at end of file diff --git a/src/main/hook/patch/piuio-exit.h b/src/main/hook/patch/piuio-exit.h index 74f40bb..425180e 100644 --- a/src/main/hook/patch/piuio-exit.h +++ b/src/main/hook/patch/piuio-exit.h @@ -1,5 +1,6 @@ /** - * Patch module to allow exiting the game using the PIUIO, e.g. pressing service + test. + * Patch module to allow exiting the game using the PIUIO, e.g. pressing service + * + test. */ #ifndef PATCH_PIUIO_EXIT_H #define PATCH_PIUIO_EXIT_H diff --git a/src/main/hook/patch/piuio-khack.c b/src/main/hook/patch/piuio-khack.c index 8341817..39c36ae 100644 --- a/src/main/hook/patch/piuio-khack.c +++ b/src/main/hook/patch/piuio-khack.c @@ -11,122 +11,130 @@ static enum cnh_result patch_piuio_khack_usbhook(struct cnh_usbhook_irp *irp); -static usb_dev_handle* _patch_piuio_khack_usb_handle; +static usb_dev_handle *_patch_piuio_khack_usb_handle; void patch_piuio_khack_init() { - cnh_usbhook_push_handler(patch_piuio_khack_usbhook); - log_info("Initialized"); + cnh_usbhook_push_handler(patch_piuio_khack_usbhook); + log_info("Initialized"); } static enum cnh_result patch_piuio_khack_usbhook(struct cnh_usbhook_irp *irp) { - enum cnh_result result; - uint8_t out_buffer[PATCH_PIUIO_KHACK_BUFFER_SIZE]; - uint8_t in_buffer[PATCH_PIUIO_KHACK_BUFFER_SIZE]; + enum cnh_result result; + uint8_t out_buffer[PATCH_PIUIO_KHACK_BUFFER_SIZE]; + uint8_t in_buffer[PATCH_PIUIO_KHACK_BUFFER_SIZE]; - if (irp->op != CNH_USBHOOK_IRP_OP_OPEN && _patch_piuio_khack_usb_handle != irp->handle) { - return cnh_usbhook_invoke_next(irp); + if (irp->op != CNH_USBHOOK_IRP_OP_OPEN && + _patch_piuio_khack_usb_handle != irp->handle) { + return cnh_usbhook_invoke_next(irp); + } + + switch (irp->op) { + case CNH_USBHOOK_IRP_OP_OPEN: { + if (irp->open_usb_dev->descriptor.idVendor == PIUIO_DRV_VID && + irp->open_usb_dev->descriptor.idProduct == PIUIO_DRV_PID) { + + if (_patch_piuio_khack_usb_handle) { + log_warn("Already detected PIUIO previously, ignoring re-detection"); + + irp->handle = _patch_piuio_khack_usb_handle; + result = CNH_RESULT_SUCCESS; + } else { + log_info("Detected PIUIO"); + + result = cnh_usbhook_invoke_next(irp); + + if (result == CNH_RESULT_SUCCESS) { + _patch_piuio_khack_usb_handle = irp->handle; + } + } + } else { + result = cnh_usbhook_invoke_next(irp); + } + + break; } - switch (irp->op) { - case CNH_USBHOOK_IRP_OP_OPEN: - { - if (irp->open_usb_dev->descriptor.idVendor == PIUIO_DRV_VID && - irp->open_usb_dev->descriptor.idProduct == PIUIO_DRV_PID) { + case CNH_USBHOOK_IRP_OP_CTRL_MSG: { + // Identifiers for custom kernel hack introduced by some update in ITG 2 + // back in the days + if (irp->ctrl_req_type == PATCH_PIUIO_KHACK_CTRL_REQ_TYPE && + irp->ctrl_req == PATCH_PIUIO_KHACK_CTRL_REQ && + irp->ctrl_timeout == PATCH_PIUIO_KHACK_TIMEOUT) { - if (_patch_piuio_khack_usb_handle) { - log_warn("Already detected PIUIO previously, ignoring re-detection"); - - irp->handle = _patch_piuio_khack_usb_handle; - result = CNH_RESULT_SUCCESS; - } else { - log_info("Detected PIUIO"); - - result = cnh_usbhook_invoke_next(irp); - - if (result == CNH_RESULT_SUCCESS) { - _patch_piuio_khack_usb_handle = irp->handle; - } - } - } else { - result = cnh_usbhook_invoke_next(irp); - } - - break; + // Hack combines the four calls for each sensor into a single call + if (irp->ctrl_buffer.nbytes != PATCH_PIUIO_KHACK_BUFFER_SIZE) { + log_error( + "Invalid buffer size for kernel hack: %d", + irp->ctrl_buffer.nbytes); + return CNH_RESULT_INVALID_PARAMETER; } - case CNH_USBHOOK_IRP_OP_CTRL_MSG: - { - // Identifiers for custom kernel hack introduced by some update in ITG 2 back in the days - if (irp->ctrl_req_type == PATCH_PIUIO_KHACK_CTRL_REQ_TYPE && - irp->ctrl_req == PATCH_PIUIO_KHACK_CTRL_REQ && - irp->ctrl_timeout == PATCH_PIUIO_KHACK_TIMEOUT) { + memcpy(out_buffer, irp->ctrl_buffer.bytes, irp->ctrl_buffer.nbytes); - // Hack combines the four calls for each sensor into a single call - if (irp->ctrl_buffer.nbytes != PATCH_PIUIO_KHACK_BUFFER_SIZE) { - log_error("Invalid buffer size for kernel hack: %d", irp->ctrl_buffer.nbytes); - return CNH_RESULT_INVALID_PARAMETER; - } + // Split the hack into single calls + for (uint8_t i = 0; i < 4; i++) { + irp->ctrl_req_type = PIUIO_DRV_USB_CTRL_TYPE_OUT; + irp->ctrl_req = PIUIO_DRV_USB_CTRL_REQUEST; + irp->ctrl_timeout = PIUIO_DRV_USB_REQ_TIMEOUT; + irp->ctrl_buffer.pos = 0; + irp->ctrl_buffer.nbytes = PIUIO_DRV_BUFFER_SIZE; - memcpy(out_buffer, irp->ctrl_buffer.bytes, irp->ctrl_buffer.nbytes); + memcpy( + irp->ctrl_buffer.bytes, + &out_buffer[PIUIO_DRV_BUFFER_SIZE * i], + PIUIO_DRV_BUFFER_SIZE); - // Split the hack into single calls - for (uint8_t i = 0; i < 4; i++) { - irp->ctrl_req_type = PIUIO_DRV_USB_CTRL_TYPE_OUT; - irp->ctrl_req = PIUIO_DRV_USB_CTRL_REQUEST; - irp->ctrl_timeout = PIUIO_DRV_USB_REQ_TIMEOUT; - irp->ctrl_buffer.pos = 0; - irp->ctrl_buffer.nbytes = PIUIO_DRV_BUFFER_SIZE; + result = cnh_usbhook_invoke_next_reset_advance(irp); - memcpy(irp->ctrl_buffer.bytes, &out_buffer[PIUIO_DRV_BUFFER_SIZE * i], PIUIO_DRV_BUFFER_SIZE); + if (result != CNH_RESULT_SUCCESS) { + return result; + } - result = cnh_usbhook_invoke_next_reset_advance(irp); + irp->ctrl_req_type = PIUIO_DRV_USB_CTRL_TYPE_IN; + irp->ctrl_req = PIUIO_DRV_USB_CTRL_REQUEST; + irp->ctrl_timeout = PIUIO_DRV_USB_REQ_TIMEOUT; + irp->ctrl_buffer.pos = 0; + irp->ctrl_buffer.nbytes = PIUIO_DRV_BUFFER_SIZE; - if (result != CNH_RESULT_SUCCESS) { - return result; - } + result = cnh_usbhook_invoke_next_reset_advance(irp); - irp->ctrl_req_type = PIUIO_DRV_USB_CTRL_TYPE_IN; - irp->ctrl_req = PIUIO_DRV_USB_CTRL_REQUEST; - irp->ctrl_timeout = PIUIO_DRV_USB_REQ_TIMEOUT; - irp->ctrl_buffer.pos = 0; - irp->ctrl_buffer.nbytes = PIUIO_DRV_BUFFER_SIZE; + if (result != CNH_RESULT_SUCCESS) { + return result; + } - result = cnh_usbhook_invoke_next_reset_advance(irp); - - if (result != CNH_RESULT_SUCCESS) { - return result; - } - - memcpy(&in_buffer[PIUIO_DRV_BUFFER_SIZE * i], irp->ctrl_buffer.bytes, PIUIO_DRV_BUFFER_SIZE); - } - - irp->ctrl_req_type = PATCH_PIUIO_KHACK_CTRL_REQ_TYPE; - irp->ctrl_req = PATCH_PIUIO_KHACK_CTRL_REQ; - irp->ctrl_timeout = PATCH_PIUIO_KHACK_TIMEOUT; - irp->ctrl_buffer.pos = PATCH_PIUIO_KHACK_BUFFER_SIZE; - irp->ctrl_buffer.nbytes = PATCH_PIUIO_KHACK_BUFFER_SIZE; - - memcpy(irp->ctrl_buffer.bytes, in_buffer, PATCH_PIUIO_KHACK_BUFFER_SIZE); - } - - break; + memcpy( + &in_buffer[PIUIO_DRV_BUFFER_SIZE * i], + irp->ctrl_buffer.bytes, + PIUIO_DRV_BUFFER_SIZE); } - case CNH_USBHOOK_IRP_OP_CLOSE: - { - _patch_piuio_khack_usb_handle = NULL; + irp->ctrl_req_type = PATCH_PIUIO_KHACK_CTRL_REQ_TYPE; + irp->ctrl_req = PATCH_PIUIO_KHACK_CTRL_REQ; + irp->ctrl_timeout = PATCH_PIUIO_KHACK_TIMEOUT; + irp->ctrl_buffer.pos = PATCH_PIUIO_KHACK_BUFFER_SIZE; + irp->ctrl_buffer.nbytes = PATCH_PIUIO_KHACK_BUFFER_SIZE; - result = cnh_usbhook_invoke_next(irp); + memcpy( + irp->ctrl_buffer.bytes, in_buffer, PATCH_PIUIO_KHACK_BUFFER_SIZE); + } - break; - } - - default: - result = cnh_usbhook_invoke_next(irp); - break; + break; } - return result; + case CNH_USBHOOK_IRP_OP_CLOSE: { + _patch_piuio_khack_usb_handle = NULL; + + result = cnh_usbhook_invoke_next(irp); + + break; + } + + default: + result = cnh_usbhook_invoke_next(irp); + break; + } + + return result; } \ No newline at end of file diff --git a/src/main/hook/patch/piuio.c b/src/main/hook/patch/piuio.c index 5dc2f4e..cb87eed 100644 --- a/src/main/hook/patch/piuio.c +++ b/src/main/hook/patch/piuio.c @@ -21,13 +21,19 @@ static bool _patch_piuio_enumerate(bool real_exists); static enum cnh_result _patch_piuio_open(void); static enum cnh_result _patch_piuio_reset(void); -static enum cnh_result _patch_piuio_control_msg(int request_type, int request, int value, int index, - struct cnh_iobuf* buffer, int timeout); +static enum cnh_result _patch_piuio_control_msg( + int request_type, + int request, + int value, + int index, + struct cnh_iobuf *buffer, + int timeout); static void _patch_piuio_close(void); -static void _patch_piuio_read_inputs_to_buffer(struct cnh_iobuf* buffer); -static void _patch_piuio_read_outputs_from_buffer(struct cnh_iobuf* buffer); -static enum ptapi_io_piuio_sensor_group _patch_piuio_get_sensor_group_from_buffer(struct cnh_iobuf* buffer); +static void _patch_piuio_read_inputs_to_buffer(struct cnh_iobuf *buffer); +static void _patch_piuio_read_outputs_from_buffer(struct cnh_iobuf *buffer); +static enum ptapi_io_piuio_sensor_group +_patch_piuio_get_sensor_group_from_buffer(struct cnh_iobuf *buffer); static const struct cnh_usb_emu_virtdev_ep _patch_piuio_virtdev = { .pid = PIUIO_DRV_PID, @@ -42,332 +48,347 @@ static const struct cnh_usb_emu_virtdev_ep _patch_piuio_virtdev = { static struct ptapi_io_piuio_api _patch_piuio_api; static enum ptapi_io_piuio_sensor_group _patch_piuio_sensor_group; -void patch_piuio_init(const char* piuio_lib_path) +void patch_piuio_init(const char *piuio_lib_path) { - if (!piuio_lib_path) { - log_die("No piuio emulation library path specified"); - } + if (!piuio_lib_path) { + log_die("No piuio emulation library path specified"); + } - /* Load piuio library funcs */ - log_info("Loading piuio api implementation %s", piuio_lib_path); + /* Load piuio library funcs */ + log_info("Loading piuio api implementation %s", piuio_lib_path); - if (!ptapi_io_piuio_util_lib_load(piuio_lib_path, &_patch_piuio_api)) { - log_error("Loading PIUIO API from %s failed", piuio_lib_path); - return; - } + if (!ptapi_io_piuio_util_lib_load(piuio_lib_path, &_patch_piuio_api)) { + log_error("Loading PIUIO API from %s failed", piuio_lib_path); + return; + } - cnh_usb_emu_add_virtdevep(&_patch_piuio_virtdev); + cnh_usb_emu_add_virtdevep(&_patch_piuio_virtdev); - log_info("Initialized"); + log_info("Initialized"); } void patch_piuio_shutdown(void) { - } static bool _patch_piuio_enumerate(bool real_exists) { - if (real_exists) { - log_info("Real PIUIO exists but emulation enabled, blocking real"); - } else { - log_info("Enumerating PIUIO emulation"); - } + if (real_exists) { + log_info("Real PIUIO exists but emulation enabled, blocking real"); + } else { + log_info("Enumerating PIUIO emulation"); + } - return true; + return true; } static enum cnh_result _patch_piuio_open(void) { - log_info("Opening PIUIO: %s", _patch_piuio_api.ident()); + log_info("Opening PIUIO: %s", _patch_piuio_api.ident()); - if (!_patch_piuio_api.open()) { - log_error("Opening api piuio %s failed", _patch_piuio_api.ident()); - return CNH_RESULT_OTHER_ERROR; - } + if (!_patch_piuio_api.open()) { + log_error("Opening api piuio %s failed", _patch_piuio_api.ident()); + return CNH_RESULT_OTHER_ERROR; + } - return CNH_RESULT_SUCCESS; + return CNH_RESULT_SUCCESS; } static enum cnh_result _patch_piuio_reset(void) { - log_info("Resetting PIUIO: %s", _patch_piuio_api.ident()); + log_info("Resetting PIUIO: %s", _patch_piuio_api.ident()); - _patch_piuio_api.close(); + _patch_piuio_api.close(); - if (!_patch_piuio_api.open()) { - log_error("Resetting api piuio %s failed", _patch_piuio_api.ident()); + if (!_patch_piuio_api.open()) { + log_error("Resetting api piuio %s failed", _patch_piuio_api.ident()); + return CNH_RESULT_OTHER_ERROR; + } + + return CNH_RESULT_SUCCESS; +} + +static enum cnh_result _patch_piuio_control_msg( + int request_type, + int request, + int value, + int index, + struct cnh_iobuf *buffer, + int timeout) +{ + /** + * Expected call pattern for a full game state update on a single frame (when + * done synchronously) + * + * CTRL_OUT: light data + sensor 0 + * CTRL_IN: input data of sensor 0 + * CTRL_OUT: light data + sensor 1 + * CTRL_IN: input data of sensor 1 + * CTRL_OUT: light data + sensor 2 + * CTRL_IN: input data of sensor 2 + * CTRL_OUT: light data + sensor 3 + * CTRL_IN: input data of sensor 3 + * + * Reduce call overhead to pumptools's piuio API for recv and send polling any + * potential implementation + */ + if (request_type == PIUIO_DRV_USB_CTRL_TYPE_IN && + request == PIUIO_DRV_USB_CTRL_REQUEST) { + if (buffer->nbytes != PIUIO_DRV_BUFFER_SIZE) { + log_error("Invalid buffer size for ctrl in: %d", buffer->nbytes); + return CNH_RESULT_INVALID_PARAMETER; + } + +#ifdef PATCH_PIUIO_CALL_TRACE + log_debug("Read"); +#endif + + // Only read buffered inputs, no need to trigger another update since + // this is taken of by the cycle start + + _patch_piuio_read_inputs_to_buffer(buffer); + + return CNH_RESULT_SUCCESS; + } else if ( + request_type == PIUIO_DRV_USB_CTRL_TYPE_OUT && + request == PIUIO_DRV_USB_CTRL_REQUEST) { + if (buffer->nbytes != PIUIO_DRV_BUFFER_SIZE) { + log_error("Invalid buffer size for ctrl out: %d", buffer->nbytes); + return CNH_RESULT_INVALID_PARAMETER; + } + + _patch_piuio_read_outputs_from_buffer(buffer); + + // Sync properly with sensor cycling by application + // Note: Naturally, the update code below will break if sensors are not + // cycled as expected + _patch_piuio_sensor_group = + _patch_piuio_get_sensor_group_from_buffer(buffer); + +#ifdef PATCH_PIUIO_CALL_TRACE + log_debug("Write: %d", _patch_piuio_sensor_group); +#endif + + // Trigger exactly ONE full update cycle on the API implementation on + // every first call of the whole update cycle + + if (_patch_piuio_sensor_group == 0) { +#ifdef PATCH_PIUIO_CALL_TRACE + log_debug("Update API"); +#endif + + if (!_patch_piuio_api.send()) { + log_error( + "Sending outputs on api piuio %s failed", _patch_piuio_api.ident()); return CNH_RESULT_OTHER_ERROR; + } + + if (!_patch_piuio_api.recv()) { + log_error( + "Receiving inputs on api piuio %s failed", + _patch_piuio_api.ident()); + return CNH_RESULT_OTHER_ERROR; + } } return CNH_RESULT_SUCCESS; -} + } else if (request_type == 0 && request == 0) { + // ITG 2/PIU Pro kernel hack, can be handled by piuio-khack module + // Safety net for visibility if the module is missing + log_error("Unhandled PIUIO kernel hack request detected, cannot dispatch"); -static enum cnh_result _patch_piuio_control_msg(int request_type, int request, int value, int index, - struct cnh_iobuf* buffer, int timeout) -{ - /** - * Expected call pattern for a full game state update on a single frame (when done synchronously) - * - * CTRL_OUT: light data + sensor 0 - * CTRL_IN: input data of sensor 0 - * CTRL_OUT: light data + sensor 1 - * CTRL_IN: input data of sensor 1 - * CTRL_OUT: light data + sensor 2 - * CTRL_IN: input data of sensor 2 - * CTRL_OUT: light data + sensor 3 - * CTRL_IN: input data of sensor 3 - * - * Reduce call overhead to pumptools's piuio API for recv and send polling any potential implementation - */ - if (request_type == PIUIO_DRV_USB_CTRL_TYPE_IN && request == PIUIO_DRV_USB_CTRL_REQUEST) { - if (buffer->nbytes != PIUIO_DRV_BUFFER_SIZE) { - log_error("Invalid buffer size for ctrl in: %d", buffer->nbytes); - return CNH_RESULT_INVALID_PARAMETER; - } - -#ifdef PATCH_PIUIO_CALL_TRACE - log_debug("Read"); -#endif - - // Only read buffered inputs, no need to trigger another update since - // this is taken of by the cycle start - - _patch_piuio_read_inputs_to_buffer(buffer); - - return CNH_RESULT_SUCCESS; - } else if (request_type == PIUIO_DRV_USB_CTRL_TYPE_OUT && request == PIUIO_DRV_USB_CTRL_REQUEST) { - if (buffer->nbytes != PIUIO_DRV_BUFFER_SIZE) { - log_error("Invalid buffer size for ctrl out: %d", buffer->nbytes); - return CNH_RESULT_INVALID_PARAMETER; - } - - _patch_piuio_read_outputs_from_buffer(buffer); - - // Sync properly with sensor cycling by application - // Note: Naturally, the update code below will break if sensors are not cycled - // as expected - _patch_piuio_sensor_group = _patch_piuio_get_sensor_group_from_buffer(buffer); - -#ifdef PATCH_PIUIO_CALL_TRACE - log_debug("Write: %d", _patch_piuio_sensor_group); -#endif - - // Trigger exactly ONE full update cycle on the API implementation on - // every first call of the whole update cycle - - if (_patch_piuio_sensor_group == 0) { -#ifdef PATCH_PIUIO_CALL_TRACE - log_debug("Update API"); -#endif - - if (!_patch_piuio_api.send()) { - log_error("Sending outputs on api piuio %s failed", _patch_piuio_api.ident()); - return CNH_RESULT_OTHER_ERROR; - } - - if (!_patch_piuio_api.recv()) { - log_error("Receiving inputs on api piuio %s failed", _patch_piuio_api.ident()); - return CNH_RESULT_OTHER_ERROR; - } - } - - return CNH_RESULT_SUCCESS; - } else if (request_type == 0 && request == 0) { - // ITG 2/PIU Pro kernel hack, can be handled by piuio-khack module - // Safety net for visibility if the module is missing - log_error("Unhandled PIUIO kernel hack request detected, cannot dispatch"); - - return CNH_RESULT_INVALID_PARAMETER; - } else { - log_error("Invalid usb control request to PIUIO: 0x%02X", request); - return CNH_RESULT_INVALID_PARAMETER; - } + return CNH_RESULT_INVALID_PARAMETER; + } else { + log_error("Invalid usb control request to PIUIO: 0x%02X", request); + return CNH_RESULT_INVALID_PARAMETER; + } } static void _patch_piuio_close(void) { - log_info("Closing PIUIO: %s", _patch_piuio_api.ident()); + log_info("Closing PIUIO: %s", _patch_piuio_api.ident()); - _patch_piuio_api.close(); + _patch_piuio_api.close(); } -static void _patch_piuio_read_inputs_to_buffer(struct cnh_iobuf* buffer) +static void _patch_piuio_read_inputs_to_buffer(struct cnh_iobuf *buffer) { - struct ptapi_io_piuio_pad_inputs p1_pad_in; - struct ptapi_io_piuio_pad_inputs p2_pad_in; - struct ptapi_io_piuio_sys_inputs sys_in; + struct ptapi_io_piuio_pad_inputs p1_pad_in; + struct ptapi_io_piuio_pad_inputs p2_pad_in; + struct ptapi_io_piuio_sys_inputs sys_in; - memset(&p1_pad_in, 0, sizeof(struct ptapi_io_piuio_pad_inputs)); - memset(&p2_pad_in, 0, sizeof(struct ptapi_io_piuio_pad_inputs)); - memset(&sys_in, 0, sizeof(struct ptapi_io_piuio_sys_inputs)); + memset(&p1_pad_in, 0, sizeof(struct ptapi_io_piuio_pad_inputs)); + memset(&p2_pad_in, 0, sizeof(struct ptapi_io_piuio_pad_inputs)); + memset(&sys_in, 0, sizeof(struct ptapi_io_piuio_sys_inputs)); - _patch_piuio_api.get_input_pad(0, _patch_piuio_sensor_group, &p1_pad_in); - _patch_piuio_api.get_input_pad(1, _patch_piuio_sensor_group, &p2_pad_in); + _patch_piuio_api.get_input_pad(0, _patch_piuio_sensor_group, &p1_pad_in); + _patch_piuio_api.get_input_pad(1, _patch_piuio_sensor_group, &p2_pad_in); - _patch_piuio_api.get_input_sys(&sys_in); + _patch_piuio_api.get_input_sys(&sys_in); - /* - byte 0: - bit 0: sensor p1: LU - bit 1: sensor p1: RU - bit 2: sensor p1: CN - bit 3: sensor p1: LD - bit 4: sensor p1: RD - bit 5: - bit 6: - bit 7: + /* + byte 0: + bit 0: sensor p1: LU + bit 1: sensor p1: RU + bit 2: sensor p1: CN + bit 3: sensor p1: LD + bit 4: sensor p1: RD + bit 5: + bit 6: + bit 7: - byte 1: - bit 0: - bit 1: test - bit 2: coin 1 - bit 3: - bit 4: - bit 5: - bit 6: service - bit 7: clear + byte 1: + bit 0: + bit 1: test + bit 2: coin 1 + bit 3: + bit 4: + bit 5: + bit 6: service + bit 7: clear - byte 2: - bit 0: sensor p2: LU - bit 1: sensor p2: RU - bit 2: sensor p2: CN - bit 3: sensor p2: LD - bit 4: sensor p2: RD - bit 5: - bit 6: - bit 7: + byte 2: + bit 0: sensor p2: LU + bit 1: sensor p2: RU + bit 2: sensor p2: CN + bit 3: sensor p2: LD + bit 4: sensor p2: RD + bit 5: + bit 6: + bit 7: - byte 3: - bit 0: - bit 1: - bit 2: coin 2 - bit 3: - bit 4: - bit 5: - bit 6: - bit 7: + byte 3: + bit 0: + bit 1: + bit 2: coin 2 + bit 3: + bit 4: + bit 5: + bit 6: + bit 7: - bytes 4 - 7 dummy - */ + bytes 4 - 7 dummy + */ - /* Player 1 */ - buffer->bytes[0] = 0; + /* Player 1 */ + buffer->bytes[0] = 0; - buffer->bytes[0] |= ((p1_pad_in.lu ? 1 : 0) << 0); - buffer->bytes[0] |= ((p1_pad_in.ru ? 1 : 0) << 1); - buffer->bytes[0] |= ((p1_pad_in.cn ? 1 : 0) << 2); - buffer->bytes[0] |= ((p1_pad_in.ld ? 1 : 0) << 3); - buffer->bytes[0] |= ((p1_pad_in.rd ? 1 : 0) << 4); + buffer->bytes[0] |= ((p1_pad_in.lu ? 1 : 0) << 0); + buffer->bytes[0] |= ((p1_pad_in.ru ? 1 : 0) << 1); + buffer->bytes[0] |= ((p1_pad_in.cn ? 1 : 0) << 2); + buffer->bytes[0] |= ((p1_pad_in.ld ? 1 : 0) << 3); + buffer->bytes[0] |= ((p1_pad_in.rd ? 1 : 0) << 4); - buffer->bytes[0] ^= 0xFF; + buffer->bytes[0] ^= 0xFF; - /* Player 2 */ - buffer->bytes[2] = 0; + /* Player 2 */ + buffer->bytes[2] = 0; - buffer->bytes[2] |= ((p1_pad_in.lu ? 1 : 0) << 0); - buffer->bytes[2] |= ((p1_pad_in.ru ? 1 : 0) << 1); - buffer->bytes[2] |= ((p1_pad_in.cn ? 1 : 0) << 2); - buffer->bytes[2] |= ((p1_pad_in.ld ? 1 : 0) << 3); - buffer->bytes[2] |= ((p1_pad_in.rd ? 1 : 0) << 4); + buffer->bytes[2] |= ((p1_pad_in.lu ? 1 : 0) << 0); + buffer->bytes[2] |= ((p1_pad_in.ru ? 1 : 0) << 1); + buffer->bytes[2] |= ((p1_pad_in.cn ? 1 : 0) << 2); + buffer->bytes[2] |= ((p1_pad_in.ld ? 1 : 0) << 3); + buffer->bytes[2] |= ((p1_pad_in.rd ? 1 : 0) << 4); - buffer->bytes[2] ^= 0xFF; + buffer->bytes[2] ^= 0xFF; - /* Sys */ - buffer->bytes[1] = 0; + /* Sys */ + buffer->bytes[1] = 0; - buffer->bytes[1] |= ((sys_in.test ? 1 : 0) << 1); - buffer->bytes[1] |= ((sys_in.service ? 1 : 0) << 6); - buffer->bytes[1] |= ((sys_in.clear ? 1 : 0) << 7); - buffer->bytes[1] |= ((sys_in.coin ? 1 : 0) << 2); + buffer->bytes[1] |= ((sys_in.test ? 1 : 0) << 1); + buffer->bytes[1] |= ((sys_in.service ? 1 : 0) << 6); + buffer->bytes[1] |= ((sys_in.clear ? 1 : 0) << 7); + buffer->bytes[1] |= ((sys_in.coin ? 1 : 0) << 2); - buffer->bytes[1] ^= 0xFF; + buffer->bytes[1] ^= 0xFF; - /* Apparently, "touching" byte 3 as a whole causes some random and weird input triggering - which results in the service menu popping up. Don't clear the whole byte, touch coin2 only to avoid this */ - if (!sys_in.coin2) { - buffer->bytes[3] |= (1 << 2); - } else { - buffer->bytes[3] &= ~(1 << 2); - } + /* Apparently, "touching" byte 3 as a whole causes some random and weird input + triggering which results in the service menu popping up. Don't clear the + whole byte, touch coin2 only to avoid this */ + if (!sys_in.coin2) { + buffer->bytes[3] |= (1 << 2); + } else { + buffer->bytes[3] &= ~(1 << 2); + } - buffer->pos = PIUIO_DRV_BUFFER_SIZE; + buffer->pos = PIUIO_DRV_BUFFER_SIZE; } -static void _patch_piuio_read_outputs_from_buffer(struct cnh_iobuf* buffer) +static void _patch_piuio_read_outputs_from_buffer(struct cnh_iobuf *buffer) { - struct ptapi_io_piuio_pad_outputs p1_pad_out; - struct ptapi_io_piuio_pad_outputs p2_pad_out; - struct ptapi_io_piuio_cab_outputs cab_out; + struct ptapi_io_piuio_pad_outputs p1_pad_out; + struct ptapi_io_piuio_pad_outputs p2_pad_out; + struct ptapi_io_piuio_cab_outputs cab_out; - /* - byte 0: - bit 0: sensor id bit 0 select sensor to be read for next input request: - bit 1: sensor id bit 1 00 = sens1, 01 = sens2, 10 = sens3, 11 = sens4 - bit 2: pad light p1: LU - bit 3: pad light p1: RU - bit 4: pad light p1: CN - bit 5: pad light p1: LD - bit 6: pad light p1: RD - bit 7: + /* + byte 0: + bit 0: sensor id bit 0 select sensor to be read for next input request: + bit 1: sensor id bit 1 00 = sens1, 01 = sens2, 10 = sens3, 11 = sens4 + bit 2: pad light p1: LU + bit 3: pad light p1: RU + bit 4: pad light p1: CN + bit 5: pad light p1: LD + bit 6: pad light p1: RD + bit 7: - byte 1: - bit 0: - bit 1: - bit 2: light neons - bit 3: coin counter 2 (front usb ports enable) - bit 4: - bit 5: - bit 6: - bit 7: + byte 1: + bit 0: + bit 1: + bit 2: light neons + bit 3: coin counter 2 (front usb ports enable) + bit 4: + bit 5: + bit 6: + bit 7: - byte 2: - bit 0: - bit 1: - bit 2: pad light p2: LU - bit 3: pad light p2: RU - bit 4: pad light p2: CN - bit 5: pad light p2: LD - bit 6: pad light p2: RD - bit 7: halogen R2 + byte 2: + bit 0: + bit 1: + bit 2: pad light p2: LU + bit 3: pad light p2: RU + bit 4: pad light p2: CN + bit 5: pad light p2: LD + bit 6: pad light p2: RD + bit 7: halogen R2 - byte 3: - bit 0: halogen R1 - bit 1: halogen L2 - bit 2: halogen L1 - bit 3: - bit 4: coin counter 1 - bit 5: - bit 6: - bit 7: + byte 3: + bit 0: halogen R1 + bit 1: halogen L2 + bit 2: halogen L1 + bit 3: + bit 4: coin counter 1 + bit 5: + bit 6: + bit 7: - bytes 4 - 7 dummy - */ + bytes 4 - 7 dummy + */ - p1_pad_out.lu = (buffer->bytes[0] & (1 << 2)) > 0; - p1_pad_out.ru = (buffer->bytes[0] & (1 << 3)) > 0; - p1_pad_out.cn = (buffer->bytes[0] & (1 << 4)) > 0; - p1_pad_out.ld = (buffer->bytes[0] & (1 << 5)) > 0; - p1_pad_out.rd = (buffer->bytes[0] & (1 << 6)) > 0; + p1_pad_out.lu = (buffer->bytes[0] & (1 << 2)) > 0; + p1_pad_out.ru = (buffer->bytes[0] & (1 << 3)) > 0; + p1_pad_out.cn = (buffer->bytes[0] & (1 << 4)) > 0; + p1_pad_out.ld = (buffer->bytes[0] & (1 << 5)) > 0; + p1_pad_out.rd = (buffer->bytes[0] & (1 << 6)) > 0; - p2_pad_out.lu = (buffer->bytes[2] & (1 << 2)) > 0; - p2_pad_out.ru = (buffer->bytes[2] & (1 << 3)) > 0; - p2_pad_out.cn = (buffer->bytes[2] & (1 << 4)) > 0; - p2_pad_out.ld = (buffer->bytes[2] & (1 << 5)) > 0; - p2_pad_out.rd = (buffer->bytes[2] & (1 << 6)) > 0; + p2_pad_out.lu = (buffer->bytes[2] & (1 << 2)) > 0; + p2_pad_out.ru = (buffer->bytes[2] & (1 << 3)) > 0; + p2_pad_out.cn = (buffer->bytes[2] & (1 << 4)) > 0; + p2_pad_out.ld = (buffer->bytes[2] & (1 << 5)) > 0; + p2_pad_out.rd = (buffer->bytes[2] & (1 << 6)) > 0; - cab_out.bass = (buffer->bytes[1] & (1 << 2)) > 0; - cab_out.halo_r2 = (buffer->bytes[2] & (1 << 7)) > 0; - cab_out.halo_r1 = (buffer->bytes[3] & (1 << 0)) > 0; - cab_out.halo_l2 = (buffer->bytes[3] & (1 << 1)) > 0; - cab_out.halo_l1 = (buffer->bytes[3] & (1 << 2)) > 0; + cab_out.bass = (buffer->bytes[1] & (1 << 2)) > 0; + cab_out.halo_r2 = (buffer->bytes[2] & (1 << 7)) > 0; + cab_out.halo_r1 = (buffer->bytes[3] & (1 << 0)) > 0; + cab_out.halo_l2 = (buffer->bytes[3] & (1 << 1)) > 0; + cab_out.halo_l1 = (buffer->bytes[3] & (1 << 2)) > 0; - _patch_piuio_api.set_output_pad(0, &p1_pad_out); - _patch_piuio_api.set_output_pad(1, &p2_pad_out); - _patch_piuio_api.set_output_cab(&cab_out); + _patch_piuio_api.set_output_pad(0, &p1_pad_out); + _patch_piuio_api.set_output_pad(1, &p2_pad_out); + _patch_piuio_api.set_output_cab(&cab_out); } -static enum ptapi_io_piuio_sensor_group _patch_piuio_get_sensor_group_from_buffer(struct cnh_iobuf* buffer) +static enum ptapi_io_piuio_sensor_group +_patch_piuio_get_sensor_group_from_buffer(struct cnh_iobuf *buffer) { - return (enum ptapi_io_piuio_sensor_group) (buffer->bytes[0] & 0x03); + return (enum ptapi_io_piuio_sensor_group)(buffer->bytes[0] & 0x03); } \ No newline at end of file diff --git a/src/main/hook/patch/piuio.h b/src/main/hook/patch/piuio.h index c2c2a3e..db04f79 100644 --- a/src/main/hook/patch/piuio.h +++ b/src/main/hook/patch/piuio.h @@ -12,7 +12,7 @@ * * @param piuio_lib_path Path to a library implementing the piuio API */ -void patch_piuio_init(const char* piuio_lib_path); +void patch_piuio_init(const char *piuio_lib_path); /** * Shut down the patch module diff --git a/src/main/hook/patch/ram-wipe.c b/src/main/hook/patch/ram-wipe.c index db97aae..83eec5f 100644 --- a/src/main/hook/patch/ram-wipe.c +++ b/src/main/hook/patch/ram-wipe.c @@ -10,16 +10,17 @@ static enum cnh_result _patch_ram_wipe_filehook(struct cnh_filehook_irp *irp); void patch_ram_wipe_init(void) { - cnh_filehook_push_handler(_patch_ram_wipe_filehook); - log_info("Initialized"); + cnh_filehook_push_handler(_patch_ram_wipe_filehook); + log_info("Initialized"); } static enum cnh_result _patch_ram_wipe_filehook(struct cnh_filehook_irp *irp) { - if (irp->op == CNH_FILEHOOK_IRP_OP_OPEN && !strcmp(irp->open_filename, "/dev/ram0")) { - log_info("Killing ram wipe"); - return CNH_RESULT_NO_SUCH_FILE_OR_DIR; - } else { - return cnh_filehook_invoke_next(irp); - } + if (irp->op == CNH_FILEHOOK_IRP_OP_OPEN && + !strcmp(irp->open_filename, "/dev/ram0")) { + log_info("Killing ram wipe"); + return CNH_RESULT_NO_SUCH_FILE_OR_DIR; + } else { + return cnh_filehook_invoke_next(irp); + } } \ No newline at end of file diff --git a/src/main/hook/patch/redir.c b/src/main/hook/patch/redir.c index 148acf4..cf2950b 100644 --- a/src/main/hook/patch/redir.c +++ b/src/main/hook/patch/redir.c @@ -6,9 +6,9 @@ void patch_redir_init() { - cnh_fshook_push_handler(cnh_redir_fshook); - cnh_filehook_push_handler(cnh_redir_filehook); - cnh_iohook_push_handler(cnh_redir_iohook); + cnh_fshook_push_handler(cnh_redir_fshook); + cnh_filehook_push_handler(cnh_redir_filehook); + cnh_iohook_push_handler(cnh_redir_iohook); - log_info("Initialized"); + log_info("Initialized"); } \ No newline at end of file diff --git a/src/main/hook/patch/redir.h b/src/main/hook/patch/redir.h index fa32093..482d8a1 100644 --- a/src/main/hook/patch/redir.h +++ b/src/main/hook/patch/redir.h @@ -9,4 +9,4 @@ */ void patch_redir_init(); -#endif //PATCH_REDIR_H +#endif // PATCH_REDIR_H diff --git a/src/main/hook/patch/sigsegv.c b/src/main/hook/patch/sigsegv.c index aed619c..abea683 100644 --- a/src/main/hook/patch/sigsegv.c +++ b/src/main/hook/patch/sigsegv.c @@ -15,39 +15,39 @@ static bool patch_sigsevc_halt_on_segv; static void patch_sigsegv_handler(int signal, __sighandler_t orig_handler) { - log_error("==================="); - log_error("!!!!! SIGSEGV !!!!!"); + log_error("==================="); + log_error("!!!!! SIGSEGV !!!!!"); - void* array[128]; - size_t size; - char** strings; + void *array[128]; + size_t size; + char **strings; - size = (size_t) backtrace(array, sizeof(array)); - strings = backtrace_symbols(array, size); + size = (size_t) backtrace(array, sizeof(array)); + strings = backtrace_symbols(array, size); - log_error("Backtrace (%d frames):", size); + log_error("Backtrace (%d frames):", size); - for (int i = 0; i < size; i++) { - log_error("%s", strings[i]); + for (int i = 0; i < size; i++) { + log_error("%s", strings[i]); + } + + free(strings); + + if (patch_sigsevc_halt_on_segv) { + log_error("Halting for debugger..."); + + while (true) { + sleep(1); } + } - free(strings); - - if (patch_sigsevc_halt_on_segv) { - log_error("Halting for debugger..."); - - while (true) { - sleep(1); - } - } - - exit(-1); + exit(-1); } void patch_sigsegv_init(bool halt_on_segv) { - patch_sigsevc_halt_on_segv = halt_on_segv; + patch_sigsevc_halt_on_segv = halt_on_segv; - cnh_sig_install(SIGSEGV, patch_sigsegv_handler); - log_info("Initialized"); + cnh_sig_install(SIGSEGV, patch_sigsegv_handler); + log_info("Initialized"); } \ No newline at end of file diff --git a/src/main/hook/patch/sound.c b/src/main/hook/patch/sound.c index a2bf707..8e3f841 100644 --- a/src/main/hook/patch/sound.c +++ b/src/main/hook/patch/sound.c @@ -1,66 +1,69 @@ #define LOG_MODULE "patch-sound" #include +#include #include - #include #include "capnhook/hook/lib.h" #include "util/log.h" -typedef int (*snd_pcm_open_t)(snd_pcm_t** pcmp, const char* name, - snd_pcm_stream_t stream, int mode); +typedef int (*snd_pcm_open_t)( + snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, int mode); static snd_pcm_open_t patch_sound_real_snd_pcm_open; -static const char* patch_sound_dev_name; +static const char *patch_sound_dev_name; -int snd_pcm_open(snd_pcm_t** pcmp, const char* name, snd_pcm_stream_t stream, int mode) +int snd_pcm_open( + snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, int mode) { - int ret = 0; - int retry_count = 5; + int ret = 0; + int retry_count = 5; - log_debug("snd_pcm_open: %s, stream %d, mode %d", name, stream, mode); + log_debug("snd_pcm_open: %s, stream %d, mode %d", name, stream, mode); - if (!patch_sound_real_snd_pcm_open) { - patch_sound_real_snd_pcm_open = (snd_pcm_open_t) cnh_lib_get_func_addr("snd_pcm_open"); - } + if (!patch_sound_real_snd_pcm_open) { + patch_sound_real_snd_pcm_open = + (snd_pcm_open_t) cnh_lib_get_func_addr("snd_pcm_open"); + } - if (patch_sound_dev_name) { - log_info("Opening sound device %s instead of %s", patch_sound_dev_name, name); + if (patch_sound_dev_name) { + log_info( + "Opening sound device %s instead of %s", patch_sound_dev_name, name); - name = patch_sound_dev_name; - } + name = patch_sound_dev_name; + } - /* - Notes about exceed and how it fucked up using alsa: - - Opening the same (hw:0) device multiple times without closing - - Opening and closing the device on each effect play - - No proper error handling on snd_pcm_open return - */ + /* + Notes about exceed and how it fucked up using alsa: + - Opening the same (hw:0) device multiple times without closing + - Opening and closing the device on each effect play + - No proper error handling on snd_pcm_open return + */ - /* Using dmix instead of hw:0 on exceed, snd_pcm_open sometimes returns - with a bad fd but after another retry, everything's fine */ - while (retry_count > 0) { - ret = patch_sound_real_snd_pcm_open(pcmp, name, stream, mode); - - if (ret < 0) { - retry_count--; - } else { - break; - } - } + /* Using dmix instead of hw:0 on exceed, snd_pcm_open sometimes returns + with a bad fd but after another retry, everything's fine */ + while (retry_count > 0) { + ret = patch_sound_real_snd_pcm_open(pcmp, name, stream, mode); if (ret < 0) { - log_error("snd_pcm_open failed: %s", snd_strerror(ret)); + retry_count--; + } else { + break; } + } - return ret; + if (ret < 0) { + log_error("snd_pcm_open failed: %s", snd_strerror(ret)); + } + + return ret; } -void patch_sound_init(const char* dev_name) +void patch_sound_init(const char *dev_name) { - patch_sound_dev_name = dev_name; + patch_sound_dev_name = dev_name; - log_info("Initialized"); + log_info("Initialized"); } \ No newline at end of file diff --git a/src/main/hook/patch/sound.h b/src/main/hook/patch/sound.h index 77a98ec..36cd3f4 100644 --- a/src/main/hook/patch/sound.h +++ b/src/main/hook/patch/sound.h @@ -10,6 +10,6 @@ * * @param dev_name Sound device name to open instead of whatever pump decides */ -void patch_sound_init(const char* dev_name); +void patch_sound_init(const char *dev_name); #endif \ No newline at end of file diff --git a/src/main/hook/patch/usb-emu.c b/src/main/hook/patch/usb-emu.c index 9d9e54c..bb27131 100644 --- a/src/main/hook/patch/usb-emu.c +++ b/src/main/hook/patch/usb-emu.c @@ -6,7 +6,7 @@ void patch_usb_emu_init() { - cnh_usbhook_push_handler(&cnh_usb_emu); + cnh_usbhook_push_handler(&cnh_usb_emu); - log_info("Initialized"); + log_info("Initialized"); } \ No newline at end of file diff --git a/src/main/hook/patch/usb-init-fix.c b/src/main/hook/patch/usb-init-fix.c index 12a45b7..5f3d0e6 100644 --- a/src/main/hook/patch/usb-init-fix.c +++ b/src/main/hook/patch/usb-init-fix.c @@ -6,7 +6,7 @@ void patch_usb_init_fix_init() { - cnh_usbhook_push_handler(&cnh_usb_init_fix); + cnh_usbhook_push_handler(&cnh_usb_init_fix); - log_info("Initialized"); + log_info("Initialized"); } \ No newline at end of file diff --git a/src/main/hook/patch/usb-mnt.c b/src/main/hook/patch/usb-mnt.c index 98f69ad..fd42d13 100644 --- a/src/main/hook/patch/usb-mnt.c +++ b/src/main/hook/patch/usb-mnt.c @@ -5,25 +5,28 @@ #include "usb-mnt.h" -static const char* patch_usb_mnt_player[2] = {"/mnt/0", "/mnt/1"}; +static const char *patch_usb_mnt_player[2] = {"/mnt/0", "/mnt/1"}; // Invalid files are used to detect if mounting the usb stick was successful -static const char* patch_usb_mnt_player_invalid[2] = {"/mnt/0/invalid", "/mnt/1/invalid"}; +static const char *patch_usb_mnt_player_invalid[2] = { + "/mnt/0/invalid", "/mnt/1/invalid"}; void patch_usb_mnt_init(void) { - for (uint8_t i = 0; i < 2; i++) { - if (!util_fs_path_exists(patch_usb_mnt_player[i])) { - log_info("%s does not exist, creating", patch_usb_mnt_player[i]); + for (uint8_t i = 0; i < 2; i++) { + if (!util_fs_path_exists(patch_usb_mnt_player[i])) { + log_info("%s does not exist, creating", patch_usb_mnt_player[i]); - if (!util_fs_mkdir(patch_usb_mnt_player[i])) { - log_error("Creating directory %s failed", patch_usb_mnt_player[i]); - } + if (!util_fs_mkdir(patch_usb_mnt_player[i])) { + log_error("Creating directory %s failed", patch_usb_mnt_player[i]); + } - if (!util_fs_mkfile(patch_usb_mnt_player_invalid[i])) { - log_error("Creating invalid indicator file %s failed", patch_usb_mnt_player_invalid[i]); - } - } + if (!util_fs_mkfile(patch_usb_mnt_player_invalid[i])) { + log_error( + "Creating invalid indicator file %s failed", + patch_usb_mnt_player_invalid[i]); + } } + } - log_info("Initialized"); + log_info("Initialized"); } \ No newline at end of file diff --git a/src/main/hook/patch/usb-unlock.c b/src/main/hook/patch/usb-unlock.c index 17581b3..93d14e9 100644 --- a/src/main/hook/patch/usb-unlock.c +++ b/src/main/hook/patch/usb-unlock.c @@ -20,54 +20,60 @@ static strcasecmp_t patch_usb_unlock_real_strcasecmp; int sscanf(const char *str, const char *format, ...) { - if (!patch_usb_unlock_real_sscanf) { - patch_usb_unlock_real_sscanf = (sscanf_t) cnh_lib_get_func_addr("sscanf"); - } + if (!patch_usb_unlock_real_sscanf) { + patch_usb_unlock_real_sscanf = (sscanf_t) cnh_lib_get_func_addr("sscanf"); + } - va_list ap; - va_start(ap, format); + va_list ap; + va_start(ap, format); - if (!strcmp(format, "P: Vendor=%4x ProdID=%4x")) { - log_debug("Spoofing VID 0x058f for usb stick"); + if (!strcmp(format, "P: Vendor=%4x ProdID=%4x")) { + log_debug("Spoofing VID 0x058f for usb stick"); - /* unpack argument list, we know we got 2 arguments here */ - /* VID */ - *va_arg(ap, int*) = 0x058f; - /* PID */ - *va_arg(ap, int*) = 0; + /* unpack argument list, we know we got 2 arguments here */ + /* VID */ + *va_arg(ap, int *) = 0x058f; + /* PID */ + *va_arg(ap, int *) = 0; - va_end(ap); - return 2; - } + va_end(ap); + return 2; + } - if (!strcmp(format, "S: SerialNumber=%s")) { - log_debug("Spoofing serial number of usb stick to kill serial number locking of profile in a moment..."); - memcpy(va_arg(ap, char*), SERIAL_UNLOCK_TOKEN, strlen(SERIAL_UNLOCK_TOKEN) + 1); + if (!strcmp(format, "S: SerialNumber=%s")) { + log_debug( + "Spoofing serial number of usb stick to kill serial number locking of " + "profile in a moment..."); + memcpy( + va_arg(ap, char *), + SERIAL_UNLOCK_TOKEN, + strlen(SERIAL_UNLOCK_TOKEN) + 1); - va_end(ap); - return 1; - } + va_end(ap); + return 1; + } - int ret = vsscanf(str, format, ap); - va_end(ap); - return ret; + int ret = vsscanf(str, format, ap); + va_end(ap); + return ret; } int strcasecmp(const char *s1, const char *s2) { - if (!patch_usb_unlock_real_strcasecmp) { - patch_usb_unlock_real_strcasecmp = (strcasecmp_t) cnh_lib_get_func_addr("strcasecmp"); - } + if (!patch_usb_unlock_real_strcasecmp) { + patch_usb_unlock_real_strcasecmp = + (strcasecmp_t) cnh_lib_get_func_addr("strcasecmp"); + } - if (!strcmp(s2, SERIAL_UNLOCK_TOKEN)) { - log_debug("Caught serial unlock token...unlocking profile"); - return 0; - } + if (!strcmp(s2, SERIAL_UNLOCK_TOKEN)) { + log_debug("Caught serial unlock token...unlocking profile"); + return 0; + } - return patch_usb_unlock_real_strcasecmp(s1, s2); + return patch_usb_unlock_real_strcasecmp(s1, s2); } void patch_usb_unlock_init(void) { - log_info("Initialized"); + log_info("Initialized"); } \ No newline at end of file diff --git a/src/main/hook/patch/usbfs.c b/src/main/hook/patch/usbfs.c index 899d297..bf963dc 100644 --- a/src/main/hook/patch/usbfs.c +++ b/src/main/hook/patch/usbfs.c @@ -1,8 +1,8 @@ #define LOG_MODULE "patch-usbfs" #include -#include #include +#include #include #include "capnhook/hook/lib.h" @@ -10,121 +10,146 @@ #include "util/fs.h" #include "util/log.h" -typedef int (*vsprintf_t)(char* str, const char* format, va_list ap); +typedef int (*vsprintf_t)(char *str, const char *format, va_list ap); typedef int (*sprintf_t)(char *str, const char *format, ...); static vsprintf_t patch_usbfs_vsprintf_orig; static sprintf_t patch_usbfs_sprintf_orig; -static const char* patch_usbfs_usb_str = "/sys/bus/usb/devices/"; +static const char *patch_usbfs_usb_str = "/sys/bus/usb/devices/"; int sprintf(char *str, const char *format, ...) { - va_list ap; - va_start(ap, format); - int ret = vsprintf(str, format, ap); - va_end(ap); - return ret; + va_list ap; + va_start(ap, format); + int ret = vsprintf(str, format, ap); + va_end(ap); + return ret; } -int __sprintf_chk(char *dest, int flags, size_t dest_len_from_compiler, const char *format, ...) +int __sprintf_chk( + char *dest, + int flags, + size_t dest_len_from_compiler, + const char *format, + ...) { - int ret; - va_list ap; - va_start(ap, format); + int ret; + va_list ap; + va_start(ap, format); - /* fuck...why did you guys have to switch from sprintf to sprintf_chk? - everything was perfectly fine... and you give a shit about "safe" code, - which doesn't make this mess better... */ - ret = vsprintf(dest, format, ap); + /* fuck...why did you guys have to switch from sprintf to sprintf_chk? + everything was perfectly fine... and you give a shit about "safe" code, + which doesn't make this mess better... */ + ret = vsprintf(dest, format, ap); - va_end(ap); - return ret; + va_end(ap); + return ret; } -int vsprintf(char* str, const char* format, va_list ap) +int vsprintf(char *str, const char *format, va_list ap) { - if (!patch_usbfs_vsprintf_orig) { - patch_usbfs_vsprintf_orig = (vsprintf_t) cnh_lib_get_func_addr("vsprintf"); + if (!patch_usbfs_vsprintf_orig) { + patch_usbfs_vsprintf_orig = (vsprintf_t) cnh_lib_get_func_addr("vsprintf"); + } + + if (!patch_usbfs_sprintf_orig) { + patch_usbfs_sprintf_orig = (sprintf_t) cnh_lib_get_func_addr("sprintf"); + } + + /* This path does not work on newer kernels (not sure which version it + started but everything > 3.18 doesn't work) */ + + // nx2/nxa path: + // /sys/bus/usb/devices/%d-%d/%d-%d:1.0/host*/target*:0:0/*:0:0:0/block:sd* + // fiesta and newer: + // /sys/bus/usb/devices/%d-%d:1.0/host*/target*:0:0/*:0:0:0/block/sd* + + if (!strncmp(patch_usbfs_usb_str, format, strlen(patch_usbfs_usb_str))) { + /* unpack argument list, we know we got 4 arguments here + the second pair is a dupe of the first one */ + uint8_t bus = (uint8_t) va_arg(ap, int); + uint8_t port = (uint8_t) va_arg(ap, int); + + // Removed because it spams the log. Put it back when debugging usb profile + // mounting related issues log_debug("Patching lookup of '%s' device node + // for bus %d, port %d.", format, bus, port); + + /* note: ports start with 1 (not 0) in sysfs */ + + /* because the linux kernel likes to change things here often, we have to + consider different paths. for each path we encountered so far (add more + if missing from different kernel versions) just + check if the path exists and use it */ + + int counter = 0; + + while (counter <= 2) { + switch (counter) { + case 0: + patch_usbfs_sprintf_orig( + str, + "/sys/bus/usb/devices/%d-1.%d:1.0/host*/" + "target*:0:0/*:0:0:0/block/sd*", + bus, + port); + break; + + case 1: + patch_usbfs_sprintf_orig( + str, + "/sys/bus/usb/devices/%d-%d:1.0/host*/" + "target*:0:0/*:0:0:0/block/sd*", + bus, + port); + break; + + case 2: + // Discovered that the string needs to be changed on 5.5.6. Probably + // changed slightly before that version + patch_usbfs_sprintf_orig( + str, + "/sys/bus/usb/devices/%d-%d/%d-%d:1.0/host*/" + "target*:0:0/*:0:0:0/block/sd*", + bus, + port, + bus, + port); + break; + + default: + log_error( + "Could not find path in sys-fs to lookup usb drive block device. " + "Likely, you have a " + "kernel version that uses a (slightly) different path. This " + "(new) path must be added in " + "order to get usb drives showing up in the game."); + break; + } + + glob_t gl; + + // Pump does the same after returning from this hooked call. Because there + // are different file system layouts depending on the kernel version, try + // the above list using the same method with glob + if (!glob(str, 4, NULL, &gl)) { + globfree(&gl); + break; + } + + globfree(&gl); + + counter++; } - if (!patch_usbfs_sprintf_orig) { - patch_usbfs_sprintf_orig = (sprintf_t) cnh_lib_get_func_addr("sprintf"); - } + /* original argument count */ + return 4; + } - /* This path does not work on newer kernels (not sure which version it - started but everything > 3.18 doesn't work) */ - - // nx2/nxa path: - // /sys/bus/usb/devices/%d-%d/%d-%d:1.0/host*/target*:0:0/*:0:0:0/block:sd* - // fiesta and newer: - // /sys/bus/usb/devices/%d-%d:1.0/host*/target*:0:0/*:0:0:0/block/sd* - - if (!strncmp(patch_usbfs_usb_str, format, strlen(patch_usbfs_usb_str))) { - /* unpack argument list, we know we got 4 arguments here - the second pair is a dupe of the first one */ - uint8_t bus = (uint8_t) va_arg(ap, int); - uint8_t port = (uint8_t) va_arg(ap, int); - - // Removed because it spams the log. Put it back when debugging usb profile mounting related issues - // log_debug("Patching lookup of '%s' device node for bus %d, port %d.", format, bus, port); - - /* note: ports start with 1 (not 0) in sysfs */ - - /* because the linux kernel likes to change things here often, we have to consider different paths. - for each path we encountered so far (add more if missing from different kernel versions) just - check if the path exists and use it */ - - int counter = 0; - - while (counter <= 2) { - switch (counter) { - case 0: - patch_usbfs_sprintf_orig(str, "/sys/bus/usb/devices/%d-1.%d:1.0/host*/" - "target*:0:0/*:0:0:0/block/sd*", bus, port); - break; - - case 1: - patch_usbfs_sprintf_orig(str, "/sys/bus/usb/devices/%d-%d:1.0/host*/" - "target*:0:0/*:0:0:0/block/sd*", bus, port); - break; - - case 2: - // Discovered that the string needs to be changed on 5.5.6. Probably changed slightly before that - // version - patch_usbfs_sprintf_orig(str, "/sys/bus/usb/devices/%d-%d/%d-%d:1.0/host*/" - "target*:0:0/*:0:0:0/block/sd*", bus, port, bus, port); - break; - - default: - log_error("Could not find path in sys-fs to lookup usb drive block device. Likely, you have a " - "kernel version that uses a (slightly) different path. This (new) path must be added in " - "order to get usb drives showing up in the game."); - break; - } - - glob_t gl; - - // Pump does the same after returning from this hooked call. Because there are different file system - // layouts depending on the kernel version, try the above list using the same method with glob - if (!glob(str, 4, NULL, &gl)) { - globfree(&gl); - break; - } - - globfree(&gl); - - counter++; - } - - /* original argument count */ - return 4; - } - - return patch_usbfs_vsprintf_orig(str, format, ap); + return patch_usbfs_vsprintf_orig(str, format, ap); } void patch_usbfs_init() { - log_info("Initialized"); + log_info("Initialized"); } \ No newline at end of file diff --git a/src/main/hook/patch/x11-event-loop.c b/src/main/hook/patch/x11-event-loop.c index 8ac4174..1f6a754 100644 --- a/src/main/hook/patch/x11-event-loop.c +++ b/src/main/hook/patch/x11-event-loop.c @@ -1,9 +1,9 @@ #define LOG_MODULE "patch-x11-event-loop" +#include #include #include #include -#include #include "capnhook/hook/lib.h" @@ -14,16 +14,26 @@ #include "util/time.h" struct patch_x11_event_loop_ctx { - Display* display; - Window window; - pthread_t thread; - atomic_int run; + Display *display; + Window window; + pthread_t thread; + atomic_int run; }; -typedef Window (*XCreateWindow_t)(Display *display, Window parent, int x, int y, unsigned int width, - unsigned int height, unsigned int border_width, int depth, unsigned int _class, Visual *visual, - unsigned long valuemask, XSetWindowAttributes *attributes); -typedef Display* (*XOpenDisplay_t)(const char *display_name); +typedef Window (*XCreateWindow_t)( + Display *display, + Window parent, + int x, + int y, + unsigned int width, + unsigned int height, + unsigned int border_width, + int depth, + unsigned int _class, + Visual *visual, + unsigned long valuemask, + XSetWindowAttributes *attributes); +typedef Display *(*XOpenDisplay_t)(const char *display_name); typedef int (*XDestroyWindow_t)(Display *display, Window w); static XCreateWindow_t patch_x11_event_loop_real_XCreateWindow; @@ -31,239 +41,290 @@ static XOpenDisplay_t patch_x11_event_loop_real_XOpenDisplay; static XDestroyWindow_t patch_x11_event_loop_real_XDestroyWindow; static bool patch_x11_event_loop_enabled; -static struct patch_x11_event_loop_ctx* patch_x11_event_loop_ctx; +static struct patch_x11_event_loop_ctx *patch_x11_event_loop_ctx; static pthread_mutex_t patch_x11_event_loop_input_handlers_lock; -static const struct ptapi_io_x11_input_hook_handler** patch_x11_event_loop_input_handlers; +static const struct ptapi_io_x11_input_hook_handler * + *patch_x11_event_loop_input_handlers; static size_t patch_x11_event_loop_num_input_handlers; -static bool patch_x11_event_loop_is_key_repeated(Display* display, XEvent* event) +static bool +patch_x11_event_loop_is_key_repeated(Display *display, XEvent *event) { - /* When a key is repeated, there will be two events: released, followed by another immediate pressed. - So check to see if another pressed is present */ - if (!XPending(display)) { - return false; - } - - XEvent e; - XPeekEvent(display, &e); - - if (e.type == KeyPress && e.xkey.keycode == event->xkey.keycode && (e.xkey.time - event->xkey.time) < 2) { - XNextEvent(display, &e); - return true; - } - + /* When a key is repeated, there will be two events: released, followed by + another immediate pressed. So check to see if another pressed is present */ + if (!XPending(display)) { return false; + } + + XEvent e; + XPeekEvent(display, &e); + + if (e.type == KeyPress && e.xkey.keycode == event->xkey.keycode && + (e.xkey.time - event->xkey.time) < 2) { + XNextEvent(display, &e); + return true; + } + + return false; } -static void* patch_x11_event_loop_run(void* args) +static void *patch_x11_event_loop_run(void *args) { - log_info("Running X11 event loop thread"); + log_info("Running X11 event loop thread"); - struct patch_x11_event_loop_ctx* ctx = (struct patch_x11_event_loop_ctx*) args; + struct patch_x11_event_loop_ctx *ctx = + (struct patch_x11_event_loop_ctx *) args; - if (XSelectInput(ctx->display, ctx->window, KeyPressMask | KeyReleaseMask) == BadWindow) { - log_error("XSelectInput failed"); - return NULL; - } + if (XSelectInput(ctx->display, ctx->window, KeyPressMask | KeyReleaseMask) == + BadWindow) { + log_error("XSelectInput failed"); + return NULL; + } - XGrabKeyboard(ctx->display, ctx->window, 1, GrabModeAsync, GrabModeAsync, CurrentTime); + XGrabKeyboard( + ctx->display, ctx->window, 1, GrabModeAsync, GrabModeAsync, CurrentTime); - while (atomic_load(&ctx->run) > 0) { - while (atomic_load(&ctx->run) > 0 && XPending(ctx->display) > 0) { - XEvent event; - KeySym key; + while (atomic_load(&ctx->run) > 0) { + while (atomic_load(&ctx->run) > 0 && XPending(ctx->display) > 0) { + XEvent event; + KeySym key; - if (XNextEvent(ctx->display, &event) != Success) { - log_error("XNextEvent"); - continue; + if (XNextEvent(ctx->display, &event) != Success) { + log_error("XNextEvent"); + continue; + } + + switch (event.type) { + case KeyPress: { + /* Mask out the modifier states X11 sets and read again */ + event.xkey.state &= ~ShiftMask; + event.xkey.state &= ~LockMask; + + XLookupString(&event.xkey, 0, 0, &key, 0); + + /* Dispatch to external input handlers */ + if (patch_x11_event_loop_num_input_handlers > 0) { + pthread_mutex_lock(&patch_x11_event_loop_input_handlers_lock); + + for (size_t i = 0; i < patch_x11_event_loop_num_input_handlers; + i++) { + if (patch_x11_event_loop_input_handlers[i]->dispatch_key_press) { + patch_x11_event_loop_input_handlers[i]->dispatch_key_press(key); + } } - switch (event.type) { - case KeyPress: - { - /* Mask out the modifier states X11 sets and read again */ - event.xkey.state &= ~ShiftMask; - event.xkey.state &= ~LockMask; + pthread_mutex_unlock(&patch_x11_event_loop_input_handlers_lock); + } - XLookupString(&event.xkey, 0, 0, &key, 0); - - /* Dispatch to external input handlers */ - if (patch_x11_event_loop_num_input_handlers > 0) { - pthread_mutex_lock(&patch_x11_event_loop_input_handlers_lock); - - for (size_t i = 0; i < patch_x11_event_loop_num_input_handlers; i++) { - if (patch_x11_event_loop_input_handlers[i]->dispatch_key_press) { - patch_x11_event_loop_input_handlers[i]->dispatch_key_press(key); - } - } - - pthread_mutex_unlock(&patch_x11_event_loop_input_handlers_lock); - } - - break; - } - - case KeyRelease: - { - /* Mask out the modifier states X11 sets and read again */ - event.xkey.state &= ~ShiftMask; - event.xkey.state &= ~LockMask; - - XLookupString(&event.xkey, 0, 0, &key, 0); - - /* Dispatch to external input handlers */ - if (patch_x11_event_loop_num_input_handlers > 0) { - /* Dispatch release if key is not repeated */ - if (!patch_x11_event_loop_is_key_repeated(ctx->display, &event)) { - pthread_mutex_lock(&patch_x11_event_loop_input_handlers_lock); - - for (size_t i = 0; i < patch_x11_event_loop_num_input_handlers; i++) { - if (patch_x11_event_loop_input_handlers[i]->dispatch_key_release) { - patch_x11_event_loop_input_handlers[i]->dispatch_key_release(key); - } - } - - pthread_mutex_unlock(&patch_x11_event_loop_input_handlers_lock); - } - } - - break; - } - - default: - break; - } + break; } - // Avoid CPU banging - util_time_sleep_ms(1); + case KeyRelease: { + /* Mask out the modifier states X11 sets and read again */ + event.xkey.state &= ~ShiftMask; + event.xkey.state &= ~LockMask; + + XLookupString(&event.xkey, 0, 0, &key, 0); + + /* Dispatch to external input handlers */ + if (patch_x11_event_loop_num_input_handlers > 0) { + /* Dispatch release if key is not repeated */ + if (!patch_x11_event_loop_is_key_repeated(ctx->display, &event)) { + pthread_mutex_lock(&patch_x11_event_loop_input_handlers_lock); + + for (size_t i = 0; i < patch_x11_event_loop_num_input_handlers; + i++) { + if (patch_x11_event_loop_input_handlers[i] + ->dispatch_key_release) { + patch_x11_event_loop_input_handlers[i]->dispatch_key_release( + key); + } + } + + pthread_mutex_unlock(&patch_x11_event_loop_input_handlers_lock); + } + } + + break; + } + + default: + break; + } } - log_info("Finished X11 event loop thread"); + // Avoid CPU banging + util_time_sleep_ms(1); + } - return NULL; + log_info("Finished X11 event loop thread"); + + return NULL; } Display *XOpenDisplay(const char *display_name) { - if (!patch_x11_event_loop_real_XOpenDisplay) { - patch_x11_event_loop_real_XOpenDisplay = (XOpenDisplay_t) cnh_lib_get_func_addr("XOpenDisplay"); - } + if (!patch_x11_event_loop_real_XOpenDisplay) { + patch_x11_event_loop_real_XOpenDisplay = + (XOpenDisplay_t) cnh_lib_get_func_addr("XOpenDisplay"); + } - log_debug("XOpenDisplay: %s", display_name); + log_debug("XOpenDisplay: %s", display_name); - // This function needs to be called before any other X11 function is called. - // Required to pump events in separate thread - if (patch_x11_event_loop_enabled && XInitThreads() != Success) { - log_error("XInitThreads failed"); - } + // This function needs to be called before any other X11 function is called. + // Required to pump events in separate thread + if (patch_x11_event_loop_enabled && XInitThreads() != Success) { + log_error("XInitThreads failed"); + } - Display* res = patch_x11_event_loop_real_XOpenDisplay(display_name); + Display *res = patch_x11_event_loop_real_XOpenDisplay(display_name); - if (!res) { - log_error("XOpenDisplay returned NULL. This might indicate that your environment is not properly setup. Check " - " that you have GPU drivers installed and configured properly and that OpenGL hardware acceleration is " - " working (use the command line tool \"glxinfo\")."); - } + if (!res) { + log_error( + "XOpenDisplay returned NULL. This might indicate that your environment " + "is not properly setup. Check " + " that you have GPU drivers installed and configured properly and that " + "OpenGL hardware acceleration is " + " working (use the command line tool \"glxinfo\")."); + } - return res; + return res; } -Window XCreateWindow(Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, - unsigned int border_width, int depth, unsigned int _class, Visual *visual, unsigned long valuemask, - XSetWindowAttributes *attributes) +Window XCreateWindow( + Display *display, + Window parent, + int x, + int y, + unsigned int width, + unsigned int height, + unsigned int border_width, + int depth, + unsigned int _class, + Visual *visual, + unsigned long valuemask, + XSetWindowAttributes *attributes) { - log_debug("XCreateWindow"); + log_debug("XCreateWindow"); - if (!patch_x11_event_loop_real_XCreateWindow) { - patch_x11_event_loop_real_XCreateWindow = (XCreateWindow_t) cnh_lib_get_func_addr("XCreateWindow"); - } + if (!patch_x11_event_loop_real_XCreateWindow) { + patch_x11_event_loop_real_XCreateWindow = + (XCreateWindow_t) cnh_lib_get_func_addr("XCreateWindow"); + } - Window w = patch_x11_event_loop_real_XCreateWindow(display, parent, x, y, width, height, border_width, depth, - _class, visual, valuemask, attributes); + Window w = patch_x11_event_loop_real_XCreateWindow( + display, + parent, + x, + y, + width, + height, + border_width, + depth, + _class, + visual, + valuemask, + attributes); - if (patch_x11_event_loop_enabled && !patch_x11_event_loop_ctx) { - patch_x11_event_loop_ctx = util_xmalloc(sizeof(struct patch_x11_event_loop_ctx)); + if (patch_x11_event_loop_enabled && !patch_x11_event_loop_ctx) { + patch_x11_event_loop_ctx = + util_xmalloc(sizeof(struct patch_x11_event_loop_ctx)); - patch_x11_event_loop_ctx->display = display; - patch_x11_event_loop_ctx->window = w; - patch_x11_event_loop_ctx->run = ATOMIC_VAR_INIT(1); + patch_x11_event_loop_ctx->display = display; + patch_x11_event_loop_ctx->window = w; + patch_x11_event_loop_ctx->run = ATOMIC_VAR_INIT(1); - pthread_create(&patch_x11_event_loop_ctx->thread, NULL, patch_x11_event_loop_run, patch_x11_event_loop_ctx); - } + pthread_create( + &patch_x11_event_loop_ctx->thread, + NULL, + patch_x11_event_loop_run, + patch_x11_event_loop_ctx); + } - return w; + return w; } int XDestroyWindow(Display *display, Window w) { - log_debug("XDestroyWindow"); + log_debug("XDestroyWindow"); - if (!patch_x11_event_loop_real_XDestroyWindow) { - patch_x11_event_loop_real_XDestroyWindow = (XDestroyWindow_t) cnh_lib_get_func_addr("XDestroyWindow"); - } + if (!patch_x11_event_loop_real_XDestroyWindow) { + patch_x11_event_loop_real_XDestroyWindow = + (XDestroyWindow_t) cnh_lib_get_func_addr("XDestroyWindow"); + } - if (patch_x11_event_loop_enabled && patch_x11_event_loop_ctx) { - log_debug("Stopping X11 event loop thread..."); + if (patch_x11_event_loop_enabled && patch_x11_event_loop_ctx) { + log_debug("Stopping X11 event loop thread..."); - atomic_store(&patch_x11_event_loop_ctx->run, 0); - pthread_join(patch_x11_event_loop_ctx->thread, NULL); - free(patch_x11_event_loop_ctx); - patch_x11_event_loop_ctx = NULL; + atomic_store(&patch_x11_event_loop_ctx->run, 0); + pthread_join(patch_x11_event_loop_ctx->thread, NULL); + free(patch_x11_event_loop_ctx); + patch_x11_event_loop_ctx = NULL; - log_debug("Stopped X11 event loop thread"); - } + log_debug("Stopped X11 event loop thread"); + } - return patch_x11_event_loop_real_XDestroyWindow(display, w); + return patch_x11_event_loop_real_XDestroyWindow(display, w); } void patch_x11_event_loop_init() { - patch_x11_event_loop_enabled = true; - log_info("Initialized"); + patch_x11_event_loop_enabled = true; + log_info("Initialized"); } -void patch_x11_event_loop_add_input_handler(const char* lib_with_handler_impl) +void patch_x11_event_loop_add_input_handler(const char *lib_with_handler_impl) { - const struct ptapi_io_x11_input_hook_handler** new_array; - size_t new_size; - void* lib_handle; - ptapi_io_x11_input_handler_hook_t input_handler_hook_func; - const struct ptapi_io_x11_input_hook_handler* input_handler_hook; + const struct ptapi_io_x11_input_hook_handler **new_array; + size_t new_size; + void *lib_handle; + ptapi_io_x11_input_handler_hook_t input_handler_hook_func; + const struct ptapi_io_x11_input_hook_handler *input_handler_hook; - if (!lib_with_handler_impl) { - log_die("No library path with input handler implementation specified"); - } + if (!lib_with_handler_impl) { + log_die("No library path with input handler implementation specified"); + } - log_info("Loading library with x11-input-handler api implementation %s", lib_with_handler_impl); + log_info( + "Loading library with x11-input-handler api implementation %s", + lib_with_handler_impl); - lib_handle = cnh_lib_load(lib_with_handler_impl); + lib_handle = cnh_lib_load(lib_with_handler_impl); - input_handler_hook_func = (ptapi_io_x11_input_handler_hook_t) - cnh_lib_get_func_addr_handle(lib_handle, "ptapi_io_x11_input_handler_hook"); + input_handler_hook_func = + (ptapi_io_x11_input_handler_hook_t) cnh_lib_get_func_addr_handle( + lib_handle, "ptapi_io_x11_input_handler_hook"); - input_handler_hook = input_handler_hook_func(); + input_handler_hook = input_handler_hook_func(); - if (!input_handler_hook) { - log_warn("Library impl %s returned NULL hook handler, skipping", lib_with_handler_impl); - return; - } + if (!input_handler_hook) { + log_warn( + "Library impl %s returned NULL hook handler, skipping", + lib_with_handler_impl); + return; + } - pthread_mutex_lock(&patch_x11_event_loop_input_handlers_lock); + pthread_mutex_lock(&patch_x11_event_loop_input_handlers_lock); - new_size = patch_x11_event_loop_num_input_handlers + 1; - new_array = realloc(patch_x11_event_loop_input_handlers, new_size * sizeof(struct ptapi_io_input_hook_handler*)); + new_size = patch_x11_event_loop_num_input_handlers + 1; + new_array = realloc( + patch_x11_event_loop_input_handlers, + new_size * sizeof(struct ptapi_io_input_hook_handler *)); - if (new_array != NULL) { - patch_x11_event_loop_input_handlers = new_array; + if (new_array != NULL) { + patch_x11_event_loop_input_handlers = new_array; - patch_x11_event_loop_input_handlers[patch_x11_event_loop_num_input_handlers++] = input_handler_hook; - } else { - log_die("Out of memory"); - } + patch_x11_event_loop_input_handlers + [patch_x11_event_loop_num_input_handlers++] = input_handler_hook; + } else { + log_die("Out of memory"); + } - pthread_mutex_unlock(&patch_x11_event_loop_input_handlers_lock); + pthread_mutex_unlock(&patch_x11_event_loop_input_handlers_lock); - log_debug("Added input handler %p of lib %s", input_handler_hook, lib_with_handler_impl); + log_debug( + "Added input handler %p of lib %s", + input_handler_hook, + lib_with_handler_impl); } \ No newline at end of file diff --git a/src/main/hook/patch/x11-event-loop.h b/src/main/hook/patch/x11-event-loop.h index 282ca17..3836062 100644 --- a/src/main/hook/patch/x11-event-loop.h +++ b/src/main/hook/patch/x11-event-loop.h @@ -2,17 +2,20 @@ #define PROHOOK_X11_EVENT_LOOP_H /** - * Initialize this module which re-implements a X11 event loop processing keyboard button presses and releases. - * This is required for Pro 1/2 because the game has all X11 input handling removed. Therefore, we cannot use any + * Initialize this module which re-implements a X11 event loop processing + * keyboard button presses and releases. This is required for Pro 1/2 because + * the game has all X11 input handling removed. Therefore, we cannot use any * ptapi io implementations using X11, e.g. keyboard inputs. */ void patch_x11_event_loop_init(); /** - * Register a handler (multiple possible) to receive X11 input events, e.g. key pressed, released + * Register a handler (multiple possible) to receive X11 input events, e.g. key + * pressed, released * - * @param lib_with_handler_impl Path to a library implementing the x11-input-handler API + * @param lib_with_handler_impl Path to a library implementing the + * x11-input-handler API */ -void patch_x11_event_loop_add_input_handler(const char* lib_with_handler_impl); +void patch_x11_event_loop_add_input_handler(const char *lib_with_handler_impl); #endif diff --git a/src/main/hook/pri/main.c b/src/main/hook/pri/main.c index 0d53da3..233dde5 100644 --- a/src/main/hook/pri/main.c +++ b/src/main/hook/pri/main.c @@ -20,10 +20,10 @@ #include "hook/patch/main-loop.h" #include "hook/patch/mounts.h" #include "hook/patch/network.h" -#include "hook/patch/piuio.h" #include "hook/patch/piuio-exit.h" -#include "hook/patch/redir.h" +#include "hook/patch/piuio.h" #include "hook/patch/ram-wipe.h" +#include "hook/patch/redir.h" #include "hook/patch/sigsegv.h" #include "hook/patch/sound.h" #include "hook/patch/usb-emu.h" @@ -45,248 +45,262 @@ extern const uint8_t _binary_prihook_hdd_raw_end[]; extern const uint8_t _binary_prihook_hasp_key_start[]; extern const uint8_t _binary_prihook_hasp_key_end[]; -static void prihook_bootstrapping(int argc, char** argv, struct prihook_options* options, char** game_data_path) +static void prihook_bootstrapping( + int argc, + char **argv, + struct prihook_options *options, + char **game_data_path) { - log_assert(argc >= 0); - log_assert(argv); - log_assert(options); - log_assert(game_data_path); + log_assert(argc >= 0); + log_assert(argv); + log_assert(options); + log_assert(game_data_path); - if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { - return; - } + if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { + return; + } - hook_core_piu_log_init(argc, argv); + hook_core_piu_log_init(argc, argv); - if (!prihook_options_init(argc, argv, options)) { - exit(0); - } + if (!prihook_options_init(argc, argv, options)) { + exit(0); + } - hook_core_piu_log_info(argc, argv); + hook_core_piu_log_info(argc, argv); - *game_data_path = hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); + *game_data_path = + hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); - hook_core_piu_utils_verify_root_user(); + hook_core_piu_utils_verify_root_user(); - hook_core_piu_utils_fix_locale(); + hook_core_piu_utils_fix_locale(); - log_info("Initializing, piu game data path: %s", *game_data_path); + log_info("Initializing, piu game data path: %s", *game_data_path); } -static void prihook_patch_fs_init(struct prihook_options* options) +static void prihook_patch_fs_init(struct prihook_options *options) { - log_assert(options); + log_assert(options); - patch_hook_mon_init( - options->patch.hook_mon.io, - options->patch.hook_mon.file, - options->patch.hook_mon.fs, - options->patch.hook_mon.usb, - options->patch.hook_mon.open); + patch_hook_mon_init( + options->patch.hook_mon.io, + options->patch.hook_mon.file, + options->patch.hook_mon.fs, + options->patch.hook_mon.usb, + options->patch.hook_mon.open); - patch_redir_init(); + patch_redir_init(); } -static void prihook_fs_redir_settings(struct prihook_options* options) +static void prihook_fs_redir_settings(struct prihook_options *options) { - log_assert(options); + log_assert(options); - if (options->game.settings) { - if (!util_fs_path_exists(options->game.settings)) { - log_info("Settings path %s does not exist, creating", options->game.settings); + if (options->game.settings) { + if (!util_fs_path_exists(options->game.settings)) { + log_info( + "Settings path %s does not exist, creating", options->game.settings); - if (!util_fs_mkdir(options->game.settings)) { - log_error("Creating directory %s failed", options->game.settings); - } - } - - char* abs_path = util_fs_get_abs_path(options->game.settings); - - cnh_redir_add("/SETTINGS", abs_path); - free(abs_path); - } else { - log_warn("No settings path specified"); + if (!util_fs_mkdir(options->game.settings)) { + log_error("Creating directory %s failed", options->game.settings); + } } + + char *abs_path = util_fs_get_abs_path(options->game.settings); + + cnh_redir_add("/SETTINGS", abs_path); + free(abs_path); + } else { + log_warn("No settings path specified"); + } } static void prihook_fs_redir_usb() { - /* Needed on newer kernels */ - cnh_redir_add("/proc/bus/usb/devices", "/sys/kernel/debug/usb/devices"); - patch_usbfs_init(); + /* Needed on newer kernels */ + cnh_redir_add("/proc/bus/usb/devices", "/sys/kernel/debug/usb/devices"); + patch_usbfs_init(); } -static void prihook_fs_redirs_init(struct prihook_options* options, const char* game_data_path) +static void prihook_fs_redirs_init( + struct prihook_options *options, const char *game_data_path) { - log_assert(options); - log_assert(game_data_path); + log_assert(options); + log_assert(game_data_path); - prihook_fs_redir_settings(options); + prihook_fs_redir_settings(options); - prihook_fs_redir_usb(); + prihook_fs_redir_usb(); } static void prihook_patch_fs_mounting_init() { - patch_mounts_init(); + patch_mounts_init(); - patch_usb_mnt_init(); + patch_usb_mnt_init(); } -static void prihook_patch_gfx_init(struct prihook_options* options) +static void prihook_patch_gfx_init(struct prihook_options *options) { - log_assert(options); + log_assert(options); - patch_gfx_init(); + patch_gfx_init(); - if (options->patch.gfx.windowed) { - patch_gfx_force_window_mode(); - } + if (options->patch.gfx.windowed) { + patch_gfx_force_window_mode(); + } } -static void prihook_patch_main_loop_init(struct prihook_options* options) +static void prihook_patch_main_loop_init(struct prihook_options *options) { - log_assert(options); + log_assert(options); - patch_main_loop_init(false, options->patch.main_loop.disable_built_in_inputs, false); + patch_main_loop_init( + false, options->patch.main_loop.disable_built_in_inputs, false); - if (options->patch.main_loop.x11_input_handler_api_lib) { - char* abs_path_x11_input_hook_lib = util_fs_get_abs_path(options->patch.main_loop.x11_input_handler_api_lib); + if (options->patch.main_loop.x11_input_handler_api_lib) { + char *abs_path_x11_input_hook_lib = util_fs_get_abs_path( + options->patch.main_loop.x11_input_handler_api_lib); - patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); - free(abs_path_x11_input_hook_lib); - } + patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); + free(abs_path_x11_input_hook_lib); + } - patch_block_keyboard_grab_init(); + patch_block_keyboard_grab_init(); } -static void prihook_patch_sound_init(struct prihook_options* options) +static void prihook_patch_sound_init(struct prihook_options *options) { - log_assert(options); + log_assert(options); - patch_sound_init(options->patch.sound.device); - patch_axmier_block_init(); + patch_sound_init(options->patch.sound.device); + patch_axmier_block_init(); } -static void prihook_patch_sigsegv_init(struct prihook_options* options) +static void prihook_patch_sigsegv_init(struct prihook_options *options) { - log_assert(options); + log_assert(options); - patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); + patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); } static void prihook_patch_dongle_init() { - patch_hasp_init((const uint8_t*) _binary_prihook_hasp_key_start, - ((uintptr_t) &_binary_prihook_hasp_key_end - (uintptr_t) &_binary_prihook_hasp_key_start)); + patch_hasp_init( + (const uint8_t *) _binary_prihook_hasp_key_start, + ((uintptr_t) &_binary_prihook_hasp_key_end - + (uintptr_t) &_binary_prihook_hasp_key_start)); } static void prihook_patch_hdd_check_init() { - patch_hdd_check_init((const uint8_t*) _binary_prihook_hdd_raw_start, - ((uintptr_t) &_binary_prihook_hdd_raw_end - (uintptr_t) &_binary_prihook_hdd_raw_start)); + patch_hdd_check_init( + (const uint8_t *) _binary_prihook_hdd_raw_start, + ((uintptr_t) &_binary_prihook_hdd_raw_end - + (uintptr_t) &_binary_prihook_hdd_raw_start)); } static void prihook_patch_ram_wipe_init() { - patch_ram_wipe_init(); + patch_ram_wipe_init(); } -static void prihook_patch_piuio_init(struct prihook_options* options) +static void prihook_patch_piuio_init(struct prihook_options *options) { - log_assert(options); + log_assert(options); - /* Hook before IO emulation */ - if (options->patch.piuio.exit_test_serv) { - patch_piuio_exit_init(); - } + /* Hook before IO emulation */ + if (options->patch.piuio.exit_test_serv) { + patch_piuio_exit_init(); + } - patch_usb_init_fix_init(); - patch_usb_emu_init(); + patch_usb_init_fix_init(); + patch_usb_emu_init(); - if (options->patch.piuio.api_lib) { - char* abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); + if (options->patch.piuio.api_lib) { + char *abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); - patch_piuio_init(abs_path_iolib); - free(abs_path_iolib); - } + patch_piuio_init(abs_path_iolib); + free(abs_path_iolib); + } } -static void prihook_patch_net_init(struct prihook_options* options) +static void prihook_patch_net_init(struct prihook_options *options) { - patch_blacklist_url_init(); - /* update server */ - patch_blacklist_url_add("http://update_kr"); - /* game server */ - patch_blacklist_url_add("http://www2.piugame.com"); + patch_blacklist_url_init(); + /* update server */ + patch_blacklist_url_add("http://update_kr"); + /* game server */ + patch_blacklist_url_add("http://www2.piugame.com"); - patch_network_init(); + patch_network_init(); - if (options->patch.net.server) { - char* address; - uint16_t port; + if (options->patch.net.server) { + char *address; + uint16_t port; - if (!util_net_split_ipv4_str(options->patch.net.server, &address, &port)) { - log_warn("Invalid format for option network address specified, ignored"); - } else { - patch_network_redirect_server_address("115.68.108.183", address, (uint16_t) port); - free(address); - } + if (!util_net_split_ipv4_str(options->patch.net.server, &address, &port)) { + log_warn("Invalid format for option network address specified, ignored"); } else { - // Redirect to avoid phoning home if no server address is set - patch_network_redirect_server_address("115.68.108.183", "127.0.0.1", 12345); + patch_network_redirect_server_address( + "115.68.108.183", address, (uint16_t) port); + free(address); } + } else { + // Redirect to avoid phoning home if no server address is set + patch_network_redirect_server_address("115.68.108.183", "127.0.0.1", 12345); + } - // Idk what this address is...redirect to something save for now - patch_network_redirect_server_address("45.76.222.114", "127.0.0.1", 12345); + // Idk what this address is...redirect to something save for now + patch_network_redirect_server_address("45.76.222.114", "127.0.0.1", 12345); } static void prihook_patch_usb_init() { - prihook_usb_updates_init(); + prihook_usb_updates_init(); } void prihook_constructor(void) { - /* Nothing here */ + /* Nothing here */ } void prihook_destructor(void) { - /* Nothing here */ + /* Nothing here */ } -void prihook_trap_before_main(int argc, char** argv) +void prihook_trap_before_main(int argc, char **argv) { - log_assert(argc >= 0); - log_assert(argv); + log_assert(argc >= 0); + log_assert(argv); - char* game_data_path; - struct prihook_options options; + char *game_data_path; + struct prihook_options options; - prihook_bootstrapping(argc, argv, &options, &game_data_path); - prihook_patch_fs_init(&options); - prihook_fs_redirs_init(&options, game_data_path); - prihook_patch_fs_mounting_init(); - prihook_patch_gfx_init(&options); - prihook_patch_main_loop_init(&options); - prihook_patch_sound_init(&options); - prihook_patch_sigsegv_init(&options); - prihook_patch_dongle_init(); - prihook_patch_hdd_check_init(); - prihook_patch_ram_wipe_init(); - prihook_patch_piuio_init(&options); - prihook_patch_net_init(&options); - prihook_patch_usb_init(); + prihook_bootstrapping(argc, argv, &options, &game_data_path); + prihook_patch_fs_init(&options); + prihook_fs_redirs_init(&options, game_data_path); + prihook_patch_fs_mounting_init(); + prihook_patch_gfx_init(&options); + prihook_patch_main_loop_init(&options); + prihook_patch_sound_init(&options); + prihook_patch_sigsegv_init(&options); + prihook_patch_dongle_init(); + prihook_patch_hdd_check_init(); + prihook_patch_ram_wipe_init(); + prihook_patch_piuio_init(&options); + prihook_patch_net_init(&options); + prihook_patch_usb_init(); - free(game_data_path); + free(game_data_path); - log_info("Hooking finished"); + log_info("Hooking finished"); } void prihook_trap_after_main(void) { - patch_piuio_shutdown(); + patch_piuio_shutdown(); } LIB_MAIN_CONSTRUCTOR(prihook_constructor); diff --git a/src/main/hook/pri/options.c b/src/main/hook/pri/options.c index e78db1d..3a46929 100644 --- a/src/main/hook/pri/options.c +++ b/src/main/hook/pri/options.c @@ -9,13 +9,17 @@ #define PRIHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO "patch.hook_mon.io" #define PRIHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN "patch.hook_mon.open" #define PRIHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB "patch.hook_mon.usb" -#define PRIHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS "patch.hook_main_loop.disable_built_in_inputs" -#define PRIHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER "patch_hook_main_loop.x11_input_handler" +#define PRIHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS \ + "patch.hook_main_loop.disable_built_in_inputs" +#define PRIHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER \ + "patch_hook_main_loop.x11_input_handler" #define PRIHOOK_OPTIONS_STR_PATCH_NET_SERVER "patch.net.server" #define PRIHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB "patch.piuio.emu_lib" -#define PRIHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV "patch.piuio_exit.test_serv" +#define PRIHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV \ + "patch.piuio_exit.test_serv" #define PRIHOOK_OPTIONS_STR_PATCH_SOUND_DEVICE "patch.sound.device" -#define PRIHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV "patch.sigsegv.halt_on_segv" +#define PRIHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV \ + "patch.sigsegv.halt_on_segv" #define PRIHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE "util.log.file" #define PRIHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL "util.log.level" @@ -70,29 +74,34 @@ const struct util_options_def prihook_options_def[] = { .default_value.b = false, }, { - .name = PRIHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS, - .description = "Disable the built in keyboard inputs for test (F1), service (PRI) and clear (F3)", + .name = + PRIHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS, + .description = "Disable the built in keyboard inputs for test (F1), " + "service (PRI) and clear (F3)", .param = 'k', .type = UTIL_OPTIONS_TYPE_BOOL, .default_value.b = false, }, { .name = PRIHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER, - .description = "Path to a library implementing the x11-input-handler api to capture X11 keyboard inputs", + .description = "Path to a library implementing the x11-input-handler " + "api to capture X11 keyboard inputs", .param = 'q', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, }, { .name = PRIHOOK_OPTIONS_STR_PATCH_NET_SERVER, - .description = "Address and port of pumpnet server (e.g. 127.0.0.1:1234)", + .description = + "Address and port of pumpnet server (e.g. 127.0.0.1:1234)", .param = 'n', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, }, { .name = PRIHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB, - .description = "Path to library implementing the piuio api for piuio emulation", + .description = + "Path to library implementing the piuio api for piuio emulation", .param = 'p', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, @@ -143,41 +152,54 @@ const struct util_options_defs prihook_options_defs = { .ndefs = lengthof(prihook_options_def) }; -bool prihook_options_init(int argc, char** argv, struct prihook_options* options) +bool prihook_options_init( + int argc, char **argv, struct prihook_options *options) { - log_assert(argv); - log_assert(options); + log_assert(argv); + log_assert(options); - struct util_options_opts* options_opt; + struct util_options_opts *options_opt; - util_options_init(argc, argv); - options_opt = util_options_get(&prihook_options_defs); + util_options_init(argc, argv); + options_opt = util_options_get(&prihook_options_defs); - if (!options_opt) { - return false; - } + if (!options_opt) { + return false; + } - options->game.settings = util_options_get_str(options_opt, PRIHOOK_OPTIONS_STR_GAME_SETTINGS); - options->patch.gfx.windowed = util_options_get_bool(options_opt, PRIHOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); - options->patch.hook_mon.file = util_options_get_bool(options_opt, PRIHOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); - options->patch.hook_mon.fs = util_options_get_bool(options_opt, PRIHOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); - options->patch.hook_mon.io = util_options_get_bool(options_opt, PRIHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); - options->patch.hook_mon.open = util_options_get_bool(options_opt, PRIHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); - options->patch.hook_mon.usb = util_options_get_bool(options_opt, PRIHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); - options->patch.main_loop.disable_built_in_inputs = util_options_get_bool(options_opt, - PRIHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); - options->patch.main_loop.x11_input_handler_api_lib = - util_options_get_str(options_opt, PRIHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); - options->patch.net.server = util_options_get_str(options_opt, PRIHOOK_OPTIONS_STR_PATCH_NET_SERVER); - options->patch.piuio.api_lib = util_options_get_str(options_opt, PRIHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); - options->patch.piuio.exit_test_serv = - util_options_get_bool(options_opt, PRIHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); - options->patch.sound.device = util_options_get_str(options_opt, PRIHOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); - options->patch.sigsegv.halt_on_segv = - util_options_get_bool(options_opt, PRIHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); - options->log.file = util_options_get_str(options_opt, PRIHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); - options->log.level = - (enum util_log_level) util_options_get_int(options_opt, PRIHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); + options->game.settings = + util_options_get_str(options_opt, PRIHOOK_OPTIONS_STR_GAME_SETTINGS); + options->patch.gfx.windowed = util_options_get_bool( + options_opt, PRIHOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); + options->patch.hook_mon.file = util_options_get_bool( + options_opt, PRIHOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); + options->patch.hook_mon.fs = + util_options_get_bool(options_opt, PRIHOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); + options->patch.hook_mon.io = + util_options_get_bool(options_opt, PRIHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); + options->patch.hook_mon.open = util_options_get_bool( + options_opt, PRIHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); + options->patch.hook_mon.usb = util_options_get_bool( + options_opt, PRIHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); + options->patch.main_loop.disable_built_in_inputs = util_options_get_bool( + options_opt, + PRIHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); + options->patch.main_loop.x11_input_handler_api_lib = util_options_get_str( + options_opt, PRIHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); + options->patch.net.server = + util_options_get_str(options_opt, PRIHOOK_OPTIONS_STR_PATCH_NET_SERVER); + options->patch.piuio.api_lib = util_options_get_str( + options_opt, PRIHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); + options->patch.piuio.exit_test_serv = util_options_get_bool( + options_opt, PRIHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); + options->patch.sound.device = + util_options_get_str(options_opt, PRIHOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); + options->patch.sigsegv.halt_on_segv = util_options_get_bool( + options_opt, PRIHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); + options->log.file = util_options_get_str( + options_opt, PRIHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); + options->log.level = (enum util_log_level) util_options_get_int( + options_opt, PRIHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); - return true; + return true; } \ No newline at end of file diff --git a/src/main/hook/pri/options.h b/src/main/hook/pri/options.h index e4ba4ed..36c437c 100644 --- a/src/main/hook/pri/options.h +++ b/src/main/hook/pri/options.h @@ -7,52 +7,53 @@ #include "util/log.h" struct prihook_options { - struct game { - const char* settings; - } game; + struct game { + const char *settings; + } game; - struct patch { - struct gfx { - bool windowed; - } gfx; + struct patch { + struct gfx { + bool windowed; + } gfx; - struct hook_mon { - bool file; - bool fs; - bool io; - bool open; - bool usb; - } hook_mon; + struct hook_mon { + bool file; + bool fs; + bool io; + bool open; + bool usb; + } hook_mon; - struct main_loop { - bool disable_built_in_inputs; - const char* x11_input_handler_api_lib; - } main_loop; + struct main_loop { + bool disable_built_in_inputs; + const char *x11_input_handler_api_lib; + } main_loop; - struct net { - const char* server; - } net; + struct net { + const char *server; + } net; - struct piuio { - const char* api_lib; - bool exit_test_serv; - } piuio; + struct piuio { + const char *api_lib; + bool exit_test_serv; + } piuio; - struct sound { - const char* device; - } sound; + struct sound { + const char *device; + } sound; - struct sigsegv { - bool halt_on_segv; - } sigsegv; - } patch; + struct sigsegv { + bool halt_on_segv; + } sigsegv; + } patch; - struct log { - const char* file; - enum util_log_level level; - } log; + struct log { + const char *file; + enum util_log_level level; + } log; }; -bool prihook_options_init(int argc, char** argv, struct prihook_options* options); +bool prihook_options_init( + int argc, char **argv, struct prihook_options *options); #endif diff --git a/src/main/hook/pri/usb-updates.c b/src/main/hook/pri/usb-updates.c index 876a7da..b1e674e 100644 --- a/src/main/hook/pri/usb-updates.c +++ b/src/main/hook/pri/usb-updates.c @@ -6,22 +6,24 @@ #include "util/log.h" -static enum cnh_result prihook_usb_updates_filehook(struct cnh_filehook_irp *irp) +static enum cnh_result +prihook_usb_updates_filehook(struct cnh_filehook_irp *irp) { - if (irp->op != CNH_FILEHOOK_IRP_OP_OPEN) { - return cnh_filehook_invoke_next(irp); - } - - if (!strcmp(irp->open_filename, "/mnt/0/prime_") || !strcmp(irp->open_filename, "/mnt/1/prime_")) { - log_info("Blocking usb update %s", irp->open_filename); - - return CNH_RESULT_NO_SUCH_FILE_OR_DIR; - } - + if (irp->op != CNH_FILEHOOK_IRP_OP_OPEN) { return cnh_filehook_invoke_next(irp); + } + + if (!strcmp(irp->open_filename, "/mnt/0/prime_") || + !strcmp(irp->open_filename, "/mnt/1/prime_")) { + log_info("Blocking usb update %s", irp->open_filename); + + return CNH_RESULT_NO_SUCH_FILE_OR_DIR; + } + + return cnh_filehook_invoke_next(irp); } void prihook_usb_updates_init(void) { - cnh_filehook_push_handler(prihook_usb_updates_filehook); + cnh_filehook_push_handler(prihook_usb_updates_filehook); } \ No newline at end of file diff --git a/src/main/hook/pro/main.c b/src/main/hook/pro/main.c index 4b6daec..46fc331 100644 --- a/src/main/hook/pro/main.c +++ b/src/main/hook/pro/main.c @@ -11,9 +11,9 @@ #include "hook/core/piu-utils.h" #include "hook/patch/hook-mon.h" -#include "hook/patch/piuio.h" #include "hook/patch/piuio-exit.h" #include "hook/patch/piuio-khack.h" +#include "hook/patch/piuio.h" #include "hook/patch/redir.h" #include "hook/patch/usb-emu.h" #include "hook/patch/usb-init-fix.h" @@ -31,201 +31,207 @@ #include "options.h" -static void prohook_bootstrapping(int argc, char** argv, struct prohook_options* options) +static void +prohook_bootstrapping(int argc, char **argv, struct prohook_options *options) { - log_assert(argc >= 0); - log_assert(argv); - log_assert(options); + log_assert(argc >= 0); + log_assert(argv); + log_assert(options); - if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { - return; - } + if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { + return; + } - hook_core_piu_log_init(argc, argv); + hook_core_piu_log_init(argc, argv); - if (!prohook_options_init(argc, argv, options)) { - exit(0); - } + if (!prohook_options_init(argc, argv, options)) { + exit(0); + } - hook_core_piu_log_info(argc, argv); + hook_core_piu_log_info(argc, argv); - hook_core_piu_utils_verify_root_user(); + hook_core_piu_utils_verify_root_user(); - log_info("Initializing"); + log_info("Initializing"); } -static void prohook_patch_fs_init(struct prohook_options* options) +static void prohook_patch_fs_init(struct prohook_options *options) { - log_assert(options); + log_assert(options); - patch_hook_mon_init( - options->patch.hook_mon.io, - options->patch.hook_mon.file, - options->patch.hook_mon.fs, - options->patch.hook_mon.usb, - options->patch.hook_mon.open); + patch_hook_mon_init( + options->patch.hook_mon.io, + options->patch.hook_mon.file, + options->patch.hook_mon.fs, + options->patch.hook_mon.usb, + options->patch.hook_mon.open); - patch_redir_init(); + patch_redir_init(); } -static void prohook_fs_redir_settings(struct prohook_options* options) +static void prohook_fs_redir_settings(struct prohook_options *options) { - if (options->game.settings) { - if (!util_fs_path_exists(options->game.settings)) { - log_info("Settings path %s does not exist, creating", options->game.settings); + if (options->game.settings) { + if (!util_fs_path_exists(options->game.settings)) { + log_info( + "Settings path %s does not exist, creating", options->game.settings); - if (!util_fs_mkdir(options->game.settings)) { - log_error("Creating directory %s failed", options->game.settings); - } - } - - char* abs_path = util_fs_get_abs_path(options->game.settings); - - cnh_redir_add("/data", abs_path); - free(abs_path); - } else { - log_warn("No settings (data) path specified"); - } -} - -static void prohook_fs_redir_data(struct prohook_options* options) -{ - if (options->game.data) { - char* abs_path = util_fs_get_abs_path(options->game.data); - - cnh_redir_add("/game", abs_path); - free(abs_path); - } else { - log_warn("No data (game) path specified"); - } -} - -static void prohook_fs_redirs_init(struct prohook_options* options) -{ - log_assert(options); - - prohook_fs_redir_settings(options); - prohook_fs_redir_data(options); -} - -static void prohook_patch_sigsegv_init(struct prohook_options* options) -{ - log_assert(options); - - /* seems like pump pro doesn't like it when injecting our own signal - handler. game crashes instantly when adding it. */ - /* - patch_sigsegv_init(); - */ -} - -static void prohook_patch_x11_event_loop_init(struct prohook_options* options) -{ - patch_x11_event_loop_init(); - - // Register up to two X11 input handlers for piuio and piubtn - - if (options->patch.x11_event_loop.api_lib) { - char* abs_path_lib = util_fs_get_abs_path(options->patch.x11_event_loop.api_lib); - - patch_x11_event_loop_add_input_handler(abs_path_lib); - free(abs_path_lib); + if (!util_fs_mkdir(options->game.settings)) { + log_error("Creating directory %s failed", options->game.settings); + } } - if (options->patch.x11_event_loop.api_lib2) { - char* abs_path_lib = util_fs_get_abs_path(options->patch.x11_event_loop.api_lib2); + char *abs_path = util_fs_get_abs_path(options->game.settings); - patch_x11_event_loop_add_input_handler(abs_path_lib); - free(abs_path_lib); - } + cnh_redir_add("/data", abs_path); + free(abs_path); + } else { + log_warn("No settings (data) path specified"); + } } -static void prohook_patch_usbprofiles(struct prohook_options* options) +static void prohook_fs_redir_data(struct prohook_options *options) { - propatch_usb_fix_init( - options->patch.usb_profile.device_nodes, - options->patch.usb_profile.p1_bus_port, - options->patch.usb_profile.p2_bus_port); + if (options->game.data) { + char *abs_path = util_fs_get_abs_path(options->game.data); + + cnh_redir_add("/game", abs_path); + free(abs_path); + } else { + log_warn("No data (game) path specified"); + } } -static void prohook_patch_piuio_init(struct prohook_options* options) +static void prohook_fs_redirs_init(struct prohook_options *options) { - log_assert(options); + log_assert(options); - // The order of layering the hooks is important here because of deps - // 1. Fix low level libusb thing with init - // 2. Turn the ITG 2 piuio kernel hack calls into normal piuio ctrl transfer calls - // 3. Introduce an abstraction layer to allow, to abstract libusb0.1 and allow adding fakedevs - // required for further software emulation - // 4. Exit module to allow exiting the game with test + service - // 5. Software emulation layer for piuio - // - // For example, the kernel hack layer takes care of removing that, so software - // emulation code doesn't have to bother with that edge case. Furthermore, it allows you - // to use the game with real hardware without any additional software emulation layers - // that have to detour to real hardware again - - patch_usb_init_fix_init(); - patch_piuio_khack_init(); - patch_usb_emu_init(); - - /* Hook before PIUIO emulation */ - if (options->patch.piuio.exit_test_serv) { - patch_piuio_exit_init(); - } - - if (options->patch.piuio.api_lib) { - char* abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); - - patch_piuio_init(abs_path_iolib); - free(abs_path_iolib); - } + prohook_fs_redir_settings(options); + prohook_fs_redir_data(options); } -static void prohook_patch_piubtn_init(struct prohook_options* options) +static void prohook_patch_sigsegv_init(struct prohook_options *options) { - if (options->patch.piubtn.api_lib) { - char* abs_path_btnlib = util_fs_get_abs_path(options->patch.piubtn.api_lib); + log_assert(options); - patch_piubtn_init(abs_path_btnlib); - free(abs_path_btnlib); - } + /* seems like pump pro doesn't like it when injecting our own signal + handler. game crashes instantly when adding it. */ + /* + patch_sigsegv_init(); + */ +} + +static void prohook_patch_x11_event_loop_init(struct prohook_options *options) +{ + patch_x11_event_loop_init(); + + // Register up to two X11 input handlers for piuio and piubtn + + if (options->patch.x11_event_loop.api_lib) { + char *abs_path_lib = + util_fs_get_abs_path(options->patch.x11_event_loop.api_lib); + + patch_x11_event_loop_add_input_handler(abs_path_lib); + free(abs_path_lib); + } + + if (options->patch.x11_event_loop.api_lib2) { + char *abs_path_lib = + util_fs_get_abs_path(options->patch.x11_event_loop.api_lib2); + + patch_x11_event_loop_add_input_handler(abs_path_lib); + free(abs_path_lib); + } +} + +static void prohook_patch_usbprofiles(struct prohook_options *options) +{ + propatch_usb_fix_init( + options->patch.usb_profile.device_nodes, + options->patch.usb_profile.p1_bus_port, + options->patch.usb_profile.p2_bus_port); +} + +static void prohook_patch_piuio_init(struct prohook_options *options) +{ + log_assert(options); + + // The order of layering the hooks is important here because of deps + // 1. Fix low level libusb thing with init + // 2. Turn the ITG 2 piuio kernel hack calls into normal piuio ctrl transfer + // calls + // 3. Introduce an abstraction layer to allow, to abstract libusb0.1 and allow + // adding fakedevs + // required for further software emulation + // 4. Exit module to allow exiting the game with test + service + // 5. Software emulation layer for piuio + // + // For example, the kernel hack layer takes care of removing that, so software + // emulation code doesn't have to bother with that edge case. Furthermore, it + // allows you to use the game with real hardware without any additional + // software emulation layers that have to detour to real hardware again + + patch_usb_init_fix_init(); + patch_piuio_khack_init(); + patch_usb_emu_init(); + + /* Hook before PIUIO emulation */ + if (options->patch.piuio.exit_test_serv) { + patch_piuio_exit_init(); + } + + if (options->patch.piuio.api_lib) { + char *abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); + + patch_piuio_init(abs_path_iolib); + free(abs_path_iolib); + } +} + +static void prohook_patch_piubtn_init(struct prohook_options *options) +{ + if (options->patch.piubtn.api_lib) { + char *abs_path_btnlib = util_fs_get_abs_path(options->patch.piubtn.api_lib); + + patch_piubtn_init(abs_path_btnlib); + free(abs_path_btnlib); + } } void prohook_constructor(void) { - /* Nothing here */ + /* Nothing here */ } void prohook_destructor(void) { - /* Nothing here */ + /* Nothing here */ } -void prohook_trap_before_main(int argc, char** argv) +void prohook_trap_before_main(int argc, char **argv) { - log_assert(argc >= 0); - log_assert(argv); + log_assert(argc >= 0); + log_assert(argv); - struct prohook_options options; + struct prohook_options options; - prohook_bootstrapping(argc, argv, &options); - prohook_patch_fs_init(&options); - prohook_fs_redirs_init(&options); - prohook_patch_sigsegv_init(&options); - prohook_patch_x11_event_loop_init(&options); - prohook_patch_usbprofiles(&options); - prohook_patch_piuio_init(&options); - prohook_patch_piubtn_init(&options); + prohook_bootstrapping(argc, argv, &options); + prohook_patch_fs_init(&options); + prohook_fs_redirs_init(&options); + prohook_patch_sigsegv_init(&options); + prohook_patch_x11_event_loop_init(&options); + prohook_patch_usbprofiles(&options); + prohook_patch_piuio_init(&options); + prohook_patch_piubtn_init(&options); - log_info("Hooking finished"); + log_info("Hooking finished"); } void prohook_trap_after_main(void) { - propatch_usb_fix_shutdown(); - patch_piubtn_shutdown(); - patch_piuio_shutdown(); + propatch_usb_fix_shutdown(); + patch_piubtn_shutdown(); + patch_piuio_shutdown(); } LIB_MAIN_CONSTRUCTOR(prohook_constructor); diff --git a/src/main/hook/pro/options.c b/src/main/hook/pro/options.c index 9aadcc5..950e6c9 100644 --- a/src/main/hook/pro/options.c +++ b/src/main/hook/pro/options.c @@ -11,12 +11,18 @@ #define PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB "patch.hook_mon.usb" #define PROHOOK_OPTIONS_STR_PATCH_PIUBTN_EMU_LIB "patch.piubtn.emu_lib" #define PROHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB "patch.piuio.emu_lib" -#define PROHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV "patch.piuio_exit.test_serv" -#define PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_P1_BUS_PORT "patch.usb_profile.p1.bus_port" -#define PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_P2_BUS_PORT "patch.usb_profile.p2.bus_port" -#define PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_DEV_NODES "patch.usb_profile.dev_nodes" -#define PROHOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER "patch_x11_event_loop.input_handler_lib" -#define PROHOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER2 "patch_x11_event_loop.input_handler_lib2" +#define PROHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV \ + "patch.piuio_exit.test_serv" +#define PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_P1_BUS_PORT \ + "patch.usb_profile.p1.bus_port" +#define PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_P2_BUS_PORT \ + "patch.usb_profile.p2.bus_port" +#define PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_DEV_NODES \ + "patch.usb_profile.dev_nodes" +#define PROHOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER \ + "patch_x11_event_loop.input_handler_lib" +#define PROHOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER2 \ + "patch_x11_event_loop.input_handler_lib2" #define PROHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE "util.log.file" #define PROHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL "util.log.level" @@ -72,14 +78,16 @@ static const struct util_options_def prohook_options_def[] = { }, { .name = PROHOOK_OPTIONS_STR_PATCH_PIUBTN_EMU_LIB, - .description = "Path to library implementing the piubtn api for piubtn emulation", + .description = + "Path to library implementing the piubtn api for piubtn emulation", .param = 'b', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, }, { .name = PROHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB, - .description = "Path to library implementing the piuio api for piuio emulation", + .description = + "Path to library implementing the piuio api for piuio emulation", .param = 'p', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, @@ -93,7 +101,8 @@ static const struct util_options_def prohook_options_def[] = { }, { .name = PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_P1_BUS_PORT, - .description = "Bus and port (format: X-X, e.g. 1-2) of the USB slot to assign to Player 1 when a USB thumb " + .description = "Bus and port (format: X-X, e.g. 1-2) of the USB slot " + "to assign to Player 1 when a USB thumb " "drive is plugged in", .param = 'a', .type = UTIL_OPTIONS_TYPE_STR, @@ -101,7 +110,8 @@ static const struct util_options_def prohook_options_def[] = { }, { .name = PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_P2_BUS_PORT, - .description = "Bus and port (format: X-X, e.g. 1-2) of the USB slot to assign to Player 2 when a USB thumb " + .description = "Bus and port (format: X-X, e.g. 1-2) of the USB slot " + "to assign to Player 2 when a USB thumb " "drive is plugged in", .param = 'k', .type = UTIL_OPTIONS_TYPE_STR, @@ -109,7 +119,8 @@ static const struct util_options_def prohook_options_def[] = { }, { .name = PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_DEV_NODES, - .description = "Device nodes of plugged in USB thumb drives to consider for mounting for usb profiles, format: " + .description = "Device nodes of plugged in USB thumb drives to " + "consider for mounting for usb profiles, format: " "sdX,sdY e.g. sde,sdf", .param = 't', .type = UTIL_OPTIONS_TYPE_STR, @@ -117,14 +128,16 @@ static const struct util_options_def prohook_options_def[] = { }, { .name = PROHOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER, - .description = "Path to a library implementing the x11-input-handler api to capture X11 keyboard inputs", + .description = "Path to a library implementing the x11-input-handler " + "api to capture X11 keyboard inputs", .param = 'q', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, }, - { + { .name = PROHOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER2, - .description = "Path to a second library implementing the x11-input-handler api to capture X11 keyboard inputs", + .description = "Path to a second library implementing the " + "x11-input-handler api to capture X11 keyboard inputs", .param = 'r', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, @@ -154,44 +167,55 @@ static const struct util_options_defs prohook_options_defs = { .ndefs = lengthof(prohook_options_def) }; -bool prohook_options_init(int argc, char** argv, struct prohook_options* options) +bool prohook_options_init( + int argc, char **argv, struct prohook_options *options) { - log_assert(argv); - log_assert(options); + log_assert(argv); + log_assert(options); - struct util_options_opts* options_opt; + struct util_options_opts *options_opt; - util_options_init(argc, argv); - options_opt = util_options_get(&prohook_options_defs); + util_options_init(argc, argv); + options_opt = util_options_get(&prohook_options_defs); - if (!options_opt) { - return false; - } + if (!options_opt) { + return false; + } - options->game.data = util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_GAME_DATA); - options->game.settings = util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_GAME_SETTINGS); - options->patch.hook_mon.file = util_options_get_bool(options_opt, PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); - options->patch.hook_mon.fs = util_options_get_bool(options_opt, PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); - options->patch.hook_mon.io = util_options_get_bool(options_opt, PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); - options->patch.hook_mon.open = util_options_get_bool(options_opt, PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); - options->patch.hook_mon.usb = util_options_get_bool(options_opt, PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); - options->patch.piubtn.api_lib = util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_PATCH_PIUBTN_EMU_LIB); - options->patch.piuio.api_lib = util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); - options->patch.piuio.exit_test_serv = - util_options_get_bool(options_opt, PROHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); - options->patch.usb_profile.device_nodes = - util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_DEV_NODES); - options->patch.usb_profile.p1_bus_port = - util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_P1_BUS_PORT); - options->patch.usb_profile.p2_bus_port = - util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_P2_BUS_PORT); - options->patch.x11_event_loop.api_lib = - util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER); - options->patch.x11_event_loop.api_lib2 = - util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER2); - options->log.file = util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); - options->log.level = - (enum util_log_level) util_options_get_int(options_opt, PROHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); + options->game.data = + util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_GAME_DATA); + options->game.settings = + util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_GAME_SETTINGS); + options->patch.hook_mon.file = util_options_get_bool( + options_opt, PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); + options->patch.hook_mon.fs = + util_options_get_bool(options_opt, PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); + options->patch.hook_mon.io = + util_options_get_bool(options_opt, PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); + options->patch.hook_mon.open = util_options_get_bool( + options_opt, PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); + options->patch.hook_mon.usb = util_options_get_bool( + options_opt, PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); + options->patch.piubtn.api_lib = util_options_get_str( + options_opt, PROHOOK_OPTIONS_STR_PATCH_PIUBTN_EMU_LIB); + options->patch.piuio.api_lib = util_options_get_str( + options_opt, PROHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); + options->patch.piuio.exit_test_serv = util_options_get_bool( + options_opt, PROHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); + options->patch.usb_profile.device_nodes = util_options_get_str( + options_opt, PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_DEV_NODES); + options->patch.usb_profile.p1_bus_port = util_options_get_str( + options_opt, PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_P1_BUS_PORT); + options->patch.usb_profile.p2_bus_port = util_options_get_str( + options_opt, PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_P2_BUS_PORT); + options->patch.x11_event_loop.api_lib = util_options_get_str( + options_opt, PROHOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER); + options->patch.x11_event_loop.api_lib2 = util_options_get_str( + options_opt, PROHOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER2); + options->log.file = util_options_get_str( + options_opt, PROHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); + options->log.level = (enum util_log_level) util_options_get_int( + options_opt, PROHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); - return true; + return true; } \ No newline at end of file diff --git a/src/main/hook/pro/options.h b/src/main/hook/pro/options.h index 8cd6010..0eab490 100644 --- a/src/main/hook/pro/options.h +++ b/src/main/hook/pro/options.h @@ -7,47 +7,48 @@ #include "util/log.h" struct prohook_options { - struct game { - const char* data; - const char* settings; - } game; + struct game { + const char *data; + const char *settings; + } game; - struct patch { - struct hook_mon { - bool file; - bool fs; - bool io; - bool open; - bool usb; - } hook_mon; + struct patch { + struct hook_mon { + bool file; + bool fs; + bool io; + bool open; + bool usb; + } hook_mon; - struct piubtn { - const char* api_lib; - } piubtn; + struct piubtn { + const char *api_lib; + } piubtn; - struct piuio { - const char* api_lib; - bool exit_test_serv; - } piuio; + struct piuio { + const char *api_lib; + bool exit_test_serv; + } piuio; - struct usb_profile { - const char* device_nodes; - const char* p1_bus_port; - const char* p2_bus_port; - } usb_profile; + struct usb_profile { + const char *device_nodes; + const char *p1_bus_port; + const char *p2_bus_port; + } usb_profile; - struct x11_event_loop { - const char* api_lib; - const char* api_lib2; - } x11_event_loop; - } patch; + struct x11_event_loop { + const char *api_lib; + const char *api_lib2; + } x11_event_loop; + } patch; - struct log { - const char* file; - enum util_log_level level; - } log; + struct log { + const char *file; + enum util_log_level level; + } log; }; -bool prohook_options_init(int argc, char** argv, struct prohook_options* options); +bool prohook_options_init( + int argc, char **argv, struct prohook_options *options); #endif diff --git a/src/main/hook/pro2/main.c b/src/main/hook/pro2/main.c index 790324a..81fd3b7 100644 --- a/src/main/hook/pro2/main.c +++ b/src/main/hook/pro2/main.c @@ -11,9 +11,9 @@ #include "hook/core/piu-utils.h" #include "hook/patch/hook-mon.h" -#include "hook/patch/piuio.h" #include "hook/patch/piuio-exit.h" #include "hook/patch/piuio-khack.h" +#include "hook/patch/piuio.h" #include "hook/patch/redir.h" #include "hook/patch/usb-emu.h" #include "hook/patch/usb-init-fix.h" @@ -36,16 +36,17 @@ * { * int result; // eax@1 * - * result = mprotect((void *)((unsigned int)dlopen & 0xFFFFF000), 0x2000u, 7) + 1; - * if ( !result ) + * result = mprotect((void *)((unsigned int)dlopen & 0xFFFFF000), 0x2000u, 7) + + * 1; if ( !result ) * { - * sub_836EF70("../../src/pump/SecureBinary.cpp", 127, (int)"Assertion 'ret != -1' failed"); - * sub_821B1B0("Assertion 'ret != -1' failed"); + * sub_836EF70("../../src/pump/SecureBinary.cpp", 127, (int)"Assertion 'ret + * != -1' failed"); sub_821B1B0("Assertion 'ret != -1' failed"); * } * if ( *(_BYTE *)dlopen != -1 ) * { - * sub_836EF70("../../src/pump/SecureBinary.cpp", 130, (int)"Assertion 'pDlopen[0] == 0xFF' failed"); - * sub_821B1B0("Assertion 'pDlopen[0] == 0xFF' failed"); + * sub_836EF70("../../src/pump/SecureBinary.cpp", 130, (int)"Assertion + * 'pDlopen[0] == 0xFF' failed"); sub_821B1B0("Assertion 'pDlopen[0] == 0xFF' + * failed"); * } * *((_BYTE *)dlopen + 5) = 0x90u; * *(_BYTE *)dlopen = 0xE9u; @@ -57,187 +58,192 @@ */ static void pro2hook_patch_secure_binary_dlopen_switcheroo() { - uint8_t buffer[4] = {0xC3, 0x90, 0x90, 0x90}; + uint8_t buffer[4] = {0xC3, 0x90, 0x90, 0x90}; - log_info("Patching dlopen switcheroo"); + log_info("Patching dlopen switcheroo"); - /* This address will only work with the latest revision executable (iirc - that was R5?) */ - util_patch_write_memory(0x8383BC0, buffer, 4); + /* This address will only work with the latest revision executable (iirc + that was R5?) */ + util_patch_write_memory(0x8383BC0, buffer, 4); } -static void pro2hook_bootstrapping(int argc, char** argv, struct pro2hook_options* options) +static void +pro2hook_bootstrapping(int argc, char **argv, struct pro2hook_options *options) { - log_assert(argc >= 0); - log_assert(argv); - log_assert(options); + log_assert(argc >= 0); + log_assert(argv); + log_assert(options); - if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { - return; - } + if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { + return; + } - hook_core_piu_log_init(argc, argv); + hook_core_piu_log_init(argc, argv); - if (!pro2hook_options_init(argc, argv, options)) { - exit(0); - } + if (!pro2hook_options_init(argc, argv, options)) { + exit(0); + } - hook_core_piu_log_info(argc, argv); + hook_core_piu_log_info(argc, argv); - hook_core_piu_utils_verify_root_user(); + hook_core_piu_utils_verify_root_user(); - log_info("Initializing"); + log_info("Initializing"); } -static void pro2hook_patch_fs_init(struct pro2hook_options* options) +static void pro2hook_patch_fs_init(struct pro2hook_options *options) { - log_assert(options); + log_assert(options); - patch_hook_mon_init( - options->patch.hook_mon.io, - options->patch.hook_mon.file, - options->patch.hook_mon.fs, - options->patch.hook_mon.usb, - options->patch.hook_mon.open); + patch_hook_mon_init( + options->patch.hook_mon.io, + options->patch.hook_mon.file, + options->patch.hook_mon.fs, + options->patch.hook_mon.usb, + options->patch.hook_mon.open); - patch_redir_init(); + patch_redir_init(); } -static void pro2hook_fs_redir_data(struct pro2hook_options* options) +static void pro2hook_fs_redir_data(struct pro2hook_options *options) { - log_assert(options); + log_assert(options); - if (options->game.data) { - char* abs_path = util_fs_get_abs_path(options->game.data); + if (options->game.data) { + char *abs_path = util_fs_get_abs_path(options->game.data); - cnh_redir_add("/pro2", abs_path); - free(abs_path); - } else { - log_warn("No data (game) path specified"); - } + cnh_redir_add("/pro2", abs_path); + free(abs_path); + } else { + log_warn("No data (game) path specified"); + } } -static void pro2hook_fs_redirs_init(struct pro2hook_options* options) +static void pro2hook_fs_redirs_init(struct pro2hook_options *options) { - log_assert(options); + log_assert(options); - pro2hook_fs_redir_data(options); + pro2hook_fs_redir_data(options); } -static void pro2hook_patch_sigsegv_init(struct pro2hook_options* options) +static void pro2hook_patch_sigsegv_init(struct pro2hook_options *options) { - log_assert(options); + log_assert(options); - /* seems like pump pro doesn't like it when injecting our own signal - handler. game crashes instantly when adding it. */ - /* - patch_sigsegv_init(); - */ + /* seems like pump pro doesn't like it when injecting our own signal + handler. game crashes instantly when adding it. */ + /* + patch_sigsegv_init(); + */ } -static void pro2hook_patch_x11_event_loop_init(struct pro2hook_options* options) +static void pro2hook_patch_x11_event_loop_init(struct pro2hook_options *options) { - patch_x11_event_loop_init(); + patch_x11_event_loop_init(); - // Register up to two X11 input handlers for piuio and piubtn + // Register up to two X11 input handlers for piuio and piubtn - if (options->patch.x11_event_loop.api_lib) { - char* abs_path_lib = util_fs_get_abs_path(options->patch.x11_event_loop.api_lib); + if (options->patch.x11_event_loop.api_lib) { + char *abs_path_lib = + util_fs_get_abs_path(options->patch.x11_event_loop.api_lib); - patch_x11_event_loop_add_input_handler(abs_path_lib); - free(abs_path_lib); - } + patch_x11_event_loop_add_input_handler(abs_path_lib); + free(abs_path_lib); + } - if (options->patch.x11_event_loop.api_lib2) { - char* abs_path_lib = util_fs_get_abs_path(options->patch.x11_event_loop.api_lib2); + if (options->patch.x11_event_loop.api_lib2) { + char *abs_path_lib = + util_fs_get_abs_path(options->patch.x11_event_loop.api_lib2); - patch_x11_event_loop_add_input_handler(abs_path_lib); - free(abs_path_lib); - } + patch_x11_event_loop_add_input_handler(abs_path_lib); + free(abs_path_lib); + } } -static void pro2hook_patch_piuio_init(struct pro2hook_options* options) +static void pro2hook_patch_piuio_init(struct pro2hook_options *options) { - log_assert(options); + log_assert(options); - // The order of layering the hooks is important here because of deps - // 1. Fix low level libusb thing with init - // 2. Turn the ITG 2 piuio kernel hack calls into normal piuio ctrl transfer calls - // 3. Introduce an abstraction layer to allow, to abstract libusb0.1 and allow adding fakedevs - // required for further software emulation - // 4. Exit module to allow exiting the game with test + service - // 5. Software emulation layer for piuio - // - // For example, the kernel hack layer takes care of removing that, so software - // emulation code doesn't have to bother with that edge case. Furthermore, it allows you - // to use the game with real hardware without any additional software emulation layers - // that have to detour to real hardware again + // The order of layering the hooks is important here because of deps + // 1. Fix low level libusb thing with init + // 2. Turn the ITG 2 piuio kernel hack calls into normal piuio ctrl transfer + // calls + // 3. Introduce an abstraction layer to allow, to abstract libusb0.1 and allow + // adding fakedevs + // required for further software emulation + // 4. Exit module to allow exiting the game with test + service + // 5. Software emulation layer for piuio + // + // For example, the kernel hack layer takes care of removing that, so software + // emulation code doesn't have to bother with that edge case. Furthermore, it + // allows you to use the game with real hardware without any additional + // software emulation layers that have to detour to real hardware again - patch_usb_init_fix_init(); - patch_piuio_khack_init(); - patch_usb_emu_init(); + patch_usb_init_fix_init(); + patch_piuio_khack_init(); + patch_usb_emu_init(); - /* Hook before PIUIO emulation */ - if (options->patch.piuio.exit_test_serv) { - patch_piuio_exit_init(); - } + /* Hook before PIUIO emulation */ + if (options->patch.piuio.exit_test_serv) { + patch_piuio_exit_init(); + } - if (options->patch.piuio.api_lib) { - char* abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); + if (options->patch.piuio.api_lib) { + char *abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); - patch_piuio_init(abs_path_iolib); - free(abs_path_iolib); - } + patch_piuio_init(abs_path_iolib); + free(abs_path_iolib); + } } -static void pro2hook_patch_piubtn_init(struct pro2hook_options* options) +static void pro2hook_patch_piubtn_init(struct pro2hook_options *options) { - if (options->patch.piubtn.api_lib) { - char* abs_path_btnlib = util_fs_get_abs_path(options->patch.piubtn.api_lib); + if (options->patch.piubtn.api_lib) { + char *abs_path_btnlib = util_fs_get_abs_path(options->patch.piubtn.api_lib); - patch_piubtn_init(abs_path_btnlib); - free(abs_path_btnlib); - } + patch_piubtn_init(abs_path_btnlib); + free(abs_path_btnlib); + } } static void pro2hook_patch_secure_binary() { - pro2hook_patch_secure_binary_dlopen_switcheroo(); + pro2hook_patch_secure_binary_dlopen_switcheroo(); } void pro2hook_constructor(void) { - /* Nothing here */ + /* Nothing here */ } void pro2hook_destructor(void) { - /* Nothing here */ + /* Nothing here */ } -void pro2hook_trap_before_main(int argc, char** argv) +void pro2hook_trap_before_main(int argc, char **argv) { - log_assert(argc >= 0); - log_assert(argv); + log_assert(argc >= 0); + log_assert(argv); - struct pro2hook_options options; + struct pro2hook_options options; - pro2hook_bootstrapping(argc, argv, &options); - pro2hook_patch_fs_init(&options); - pro2hook_fs_redirs_init(&options); - pro2hook_patch_sigsegv_init(&options); - pro2hook_patch_x11_event_loop_init(&options); - pro2hook_patch_piuio_init(&options); - pro2hook_patch_piubtn_init(&options); - pro2hook_patch_secure_binary(); + pro2hook_bootstrapping(argc, argv, &options); + pro2hook_patch_fs_init(&options); + pro2hook_fs_redirs_init(&options); + pro2hook_patch_sigsegv_init(&options); + pro2hook_patch_x11_event_loop_init(&options); + pro2hook_patch_piuio_init(&options); + pro2hook_patch_piubtn_init(&options); + pro2hook_patch_secure_binary(); - log_info("Hooking finished"); + log_info("Hooking finished"); } void pro2hook_trap_after_main(void) { - patch_piubtn_shutdown(); - patch_piuio_shutdown(); + patch_piubtn_shutdown(); + patch_piuio_shutdown(); } LIB_MAIN_CONSTRUCTOR(pro2hook_constructor); diff --git a/src/main/hook/pro2/options.c b/src/main/hook/pro2/options.c index 1dac0c9..8d8e9a5 100644 --- a/src/main/hook/pro2/options.c +++ b/src/main/hook/pro2/options.c @@ -10,9 +10,12 @@ #define PRO2HOOK_OPTIONS_STR_PATCH_HOOK_MON_USB "patch.hook_mon.usb" #define PRO2HOOK_OPTIONS_STR_PATCH_PIUBTN_EMU_LIB "patch.piubtn.emu_lib" #define PRO2HOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB "patch.piuio.emu_lib" -#define PRO2HOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV "patch.piuio_exit.test_serv" -#define PRO2HOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER "patch_x11_event_loop.input_handler_lib" -#define PRO2HOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER2 "patch_x11_event_loop.input_handler_lib2" +#define PRO2HOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV \ + "patch.piuio_exit.test_serv" +#define PRO2HOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER \ + "patch_x11_event_loop.input_handler_lib" +#define PRO2HOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER2 \ + "patch_x11_event_loop.input_handler_lib2" #define PRO2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE "util.log.file" #define PRO2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL "util.log.level" @@ -61,14 +64,16 @@ const struct util_options_def pro2hook_options_def[] = { }, { .name = PRO2HOOK_OPTIONS_STR_PATCH_PIUBTN_EMU_LIB, - .description = "Path to library implementing the piubtn api for piubtn emulation", + .description = + "Path to library implementing the piubtn api for piubtn emulation", .param = 'b', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, }, { .name = PRO2HOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB, - .description = "Path to library implementing the piuio api for piuio emulation", + .description = + "Path to library implementing the piuio api for piuio emulation", .param = 'p', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, @@ -82,14 +87,16 @@ const struct util_options_def pro2hook_options_def[] = { }, { .name = PRO2HOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER, - .description = "Path to a library implementing the x11-input-handler api to capture X11 keyboard inputs", + .description = "Path to a library implementing the x11-input-handler " + "api to capture X11 keyboard inputs", .param = 'q', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, }, - { + { .name = PRO2HOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER2, - .description = "Path to a second library implementing the x11-input-handler api to capture X11 keyboard inputs", + .description = "Path to a second library implementing the " + "x11-input-handler api to capture X11 keyboard inputs", .param = 'r', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, @@ -119,37 +126,47 @@ const struct util_options_defs pro2hook_options_defs = { .ndefs = lengthof(pro2hook_options_def) }; -bool pro2hook_options_init(int argc, char** argv, struct pro2hook_options* options) +bool pro2hook_options_init( + int argc, char **argv, struct pro2hook_options *options) { - log_assert(argv); - log_assert(options); + log_assert(argv); + log_assert(options); - struct util_options_opts* options_opt; + struct util_options_opts *options_opt; - util_options_init(argc, argv); - options_opt = util_options_get(&pro2hook_options_defs); + util_options_init(argc, argv); + options_opt = util_options_get(&pro2hook_options_defs); - if (!options_opt) { - return false; - } + if (!options_opt) { + return false; + } - options->game.data = util_options_get_str(options_opt, PRO2HOOK_OPTIONS_STR_GAME_DATA); - options->patch.hook_mon.file = util_options_get_bool(options_opt, PRO2HOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); - options->patch.hook_mon.fs = util_options_get_bool(options_opt, PRO2HOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); - options->patch.hook_mon.io = util_options_get_bool(options_opt, PRO2HOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); - options->patch.hook_mon.open = util_options_get_bool(options_opt, PRO2HOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); - options->patch.hook_mon.usb = util_options_get_bool(options_opt, PRO2HOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); - options->patch.piubtn.api_lib = util_options_get_str(options_opt, PRO2HOOK_OPTIONS_STR_PATCH_PIUBTN_EMU_LIB); - options->patch.piuio.api_lib = util_options_get_str(options_opt, PRO2HOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); - options->patch.piuio.exit_test_serv = - util_options_get_bool(options_opt, PRO2HOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); - options->patch.x11_event_loop.api_lib = - util_options_get_str(options_opt, PRO2HOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER); - options->patch.x11_event_loop.api_lib2 = - util_options_get_str(options_opt, PRO2HOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER2); - options->log.file = util_options_get_str(options_opt, PRO2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); - options->log.level = - (enum util_log_level) util_options_get_int(options_opt, PRO2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); + options->game.data = + util_options_get_str(options_opt, PRO2HOOK_OPTIONS_STR_GAME_DATA); + options->patch.hook_mon.file = util_options_get_bool( + options_opt, PRO2HOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); + options->patch.hook_mon.fs = util_options_get_bool( + options_opt, PRO2HOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); + options->patch.hook_mon.io = util_options_get_bool( + options_opt, PRO2HOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); + options->patch.hook_mon.open = util_options_get_bool( + options_opt, PRO2HOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); + options->patch.hook_mon.usb = util_options_get_bool( + options_opt, PRO2HOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); + options->patch.piubtn.api_lib = util_options_get_str( + options_opt, PRO2HOOK_OPTIONS_STR_PATCH_PIUBTN_EMU_LIB); + options->patch.piuio.api_lib = util_options_get_str( + options_opt, PRO2HOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); + options->patch.piuio.exit_test_serv = util_options_get_bool( + options_opt, PRO2HOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); + options->patch.x11_event_loop.api_lib = util_options_get_str( + options_opt, PRO2HOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER); + options->patch.x11_event_loop.api_lib2 = util_options_get_str( + options_opt, PRO2HOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER2); + options->log.file = util_options_get_str( + options_opt, PRO2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); + options->log.level = (enum util_log_level) util_options_get_int( + options_opt, PRO2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); - return true; + return true; } \ No newline at end of file diff --git a/src/main/hook/pro2/options.h b/src/main/hook/pro2/options.h index 19600df..b9a8df6 100644 --- a/src/main/hook/pro2/options.h +++ b/src/main/hook/pro2/options.h @@ -7,40 +7,41 @@ #include "util/log.h" struct pro2hook_options { - struct game { - const char* data; - } game; + struct game { + const char *data; + } game; - struct patch { - struct hook_mon { - bool file; - bool fs; - bool io; - bool open; - bool usb; - } hook_mon; + struct patch { + struct hook_mon { + bool file; + bool fs; + bool io; + bool open; + bool usb; + } hook_mon; - struct piubtn { - const char* api_lib; - } piubtn; + struct piubtn { + const char *api_lib; + } piubtn; - struct piuio { - const char* api_lib; - bool exit_test_serv; - } piuio; + struct piuio { + const char *api_lib; + bool exit_test_serv; + } piuio; - struct x11_event_loop { - const char* api_lib; - const char* api_lib2; - } x11_event_loop; - } patch; + struct x11_event_loop { + const char *api_lib; + const char *api_lib2; + } x11_event_loop; + } patch; - struct log { - const char* file; - enum util_log_level level; - } log; + struct log { + const char *file; + enum util_log_level level; + } log; }; -bool pro2hook_options_init(int argc, char** argv, struct pro2hook_options* options); +bool pro2hook_options_init( + int argc, char **argv, struct pro2hook_options *options); #endif diff --git a/src/main/hook/propatch/usb-fix.c b/src/main/hook/propatch/usb-fix.c index bd3021a..b9a6fb0 100644 --- a/src/main/hook/propatch/usb-fix.c +++ b/src/main/hook/propatch/usb-fix.c @@ -8,7 +8,7 @@ #include "util/mem.h" #include "util/str.h" -typedef ssize_t (*readlink_t) (const char * path, char * buf, size_t len); +typedef ssize_t (*readlink_t)(const char *path, char *buf, size_t len); static readlink_t pro_usb_fix_real_readlink; static const int16_t propatch_usb_fix_usb_static_ini_usb_bus[2] = {1, 1}; @@ -23,155 +23,173 @@ static int propatch_usb_fix_usb_port[2]; static bool propatch_usb_fix_enabled; // Non static for testing -ssize_t propatch_usb_fix_readlink(const char* path, char* buf, size_t len) +ssize_t propatch_usb_fix_readlink(const char *path, char *buf, size_t len) { - if (!pro_usb_fix_real_readlink) { - pro_usb_fix_real_readlink = (readlink_t) cnh_lib_get_func_addr("readlink"); - } + if (!pro_usb_fix_real_readlink) { + pro_usb_fix_real_readlink = (readlink_t) cnh_lib_get_func_addr("readlink"); + } - // pro is scanning the /sys/block directory where all usb thumb drives show up once connected - // The game iterates the directory and resolves the /sys/block/sdX/device symlink - // On current kernels, e.g. 5.6.14, it might look like this - // ../devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2:1.0/host7/target7:0:0/7:0:0:0/block/sdd - // However, when pro was developed, the symlink looked entirely different. - // In order to allow the game to detect and mount usb thumb drives on newer kernels, the path - // needs to be altered to match what the game is expecting which might be similar to this: - // ../devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2:1.0 - // The game tokenizes this path by / and picks the second to last item, which is '2-2' here. - // This item gets further split into bus (2) and port (2). If that is successful, the game treats the - // detected device as valid allowing it to mount if the bus and port match what has been configured in - // the Static.ini file - if (propatch_usb_fix_enabled && util_str_starts_with(path, "/sys/block/") && util_str_ends_with(path, "/device")) { - log_debug("Trap %s", path); + // pro is scanning the /sys/block directory where all usb thumb drives show up + // once connected The game iterates the directory and resolves the + // /sys/block/sdX/device symlink On current kernels, e.g. 5.6.14, it might + // look like this + // ../devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2:1.0/host7/target7:0:0/7:0:0:0/block/sdd + // However, when pro was developed, the symlink looked entirely different. + // In order to allow the game to detect and mount usb thumb drives on newer + // kernels, the path needs to be altered to match what the game is expecting + // which might be similar to this: + // ../devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2:1.0 + // The game tokenizes this path by / and picks the second to last item, which + // is '2-2' here. This item gets further split into bus (2) and port (2). If + // that is successful, the game treats the detected device as valid allowing + // it to mount if the bus and port match what has been configured in the + // Static.ini file + if (propatch_usb_fix_enabled && util_str_starts_with(path, "/sys/block/") && + util_str_ends_with(path, "/device")) { + log_debug("Trap %s", path); - // Remove the trailing "/device" part which is no longer valid on current kernels - // /sys/block/sdc/device -> /sys/block/sdc - char* tmp = util_str_dup(path); - size_t len_tmp = strlen(tmp); - tmp[len_tmp - 7] = '\0'; + // Remove the trailing "/device" part which is no longer valid on current + // kernels /sys/block/sdc/device -> /sys/block/sdc + char *tmp = util_str_dup(path); + size_t len_tmp = strlen(tmp); + tmp[len_tmp - 7] = '\0'; - memset(buf, 0, len); + memset(buf, 0, len); - ssize_t res = pro_usb_fix_real_readlink(tmp, buf, len); + ssize_t res = pro_usb_fix_real_readlink(tmp, buf, len); - util_xfree((void**) &tmp); + util_xfree((void **) &tmp); - if (strstr(buf, propatch_usb_fix_device_thumb_drive_p1) || strstr(buf, propatch_usb_fix_device_thumb_drive_p2)) { - log_debug("Detected assigned flash drive plugged in"); + if (strstr(buf, propatch_usb_fix_device_thumb_drive_p1) || + strstr(buf, propatch_usb_fix_device_thumb_drive_p2)) { + log_debug("Detected assigned flash drive plugged in"); - size_t count; - char** toks; + size_t count; + char **toks; - toks = util_str_split(buf, "/", &count); + toks = util_str_split(buf, "/", &count); - // some sanity checks to ensure the format isn't different - if ( count != 12 || - strcmp(toks[0], "..") != 0 || - strcmp(toks[1], "devices") != 0 || - strcmp(toks[10], "block") != 0) { - log_error( - "/sys/block device readlink format changed, usb thumb drive profiles will likely not work!: %s", - buf); - util_str_free_split(toks, count); - return 0; - } - - int bus; - int port; - const char* device = toks[11]; - - if (sscanf(toks[5], "%d-%d", &bus, &port) != 2) { - log_error("Parsing bus-port of %s failed", buf); - util_str_free_split(toks, count); - return 0; - } - - log_debug("Detected flash drive on bus %d, port %d, device %s", bus, port, device); - - for (int i = 0; i < 2; i++) { - if (propatch_usb_fix_usb_bus[i] == bus && propatch_usb_fix_usb_port[i] == port) { - // The usb manager only cares about reading the second to last token in the correct format - // Copy-paste everything else - sprintf( - buf, - "%s/%s/%s/%s/%s/%d-%d/%d-%d:1.0", - toks[0], - toks[1], - toks[2], - toks[3], - toks[4], - propatch_usb_fix_usb_static_ini_usb_bus[i], - propatch_usb_fix_usb_static_ini_usb_port[i], - propatch_usb_fix_usb_static_ini_usb_bus[i], - propatch_usb_fix_usb_static_ini_usb_port[i]); - - log_debug("Player %d usb thumb drive at path %s", i, buf); - - util_str_free_split(toks, count); - - return strlen(buf); - } - } - - util_str_free_split(toks, count); - } - - return res; - } - - return pro_usb_fix_real_readlink(path, buf, len); -} - -ssize_t readlink(const char* path, char* buf, size_t len) -{ - return propatch_usb_fix_readlink(path, buf, len); -} - -void propatch_usb_fix_init(const char* device_nodes, const char* p1_bus_port, const char* p2_bus_port) -{ - size_t count; - char** toks; - - if (!device_nodes || !p1_bus_port || !p2_bus_port) { - log_warn("Disabled, missing one or multiple option properties"); - return; - } - - toks = util_str_split(device_nodes, ",", &count); - - if (count != 2) { - log_error("Invalid format for device nodes: %s", device_nodes); + // some sanity checks to ensure the format isn't different + if (count != 12 || strcmp(toks[0], "..") != 0 || + strcmp(toks[1], "devices") != 0 || strcmp(toks[10], "block") != 0) { + log_error( + "/sys/block device readlink format changed, usb thumb drive " + "profiles will likely not work!: %s", + buf); util_str_free_split(toks, count); - return; + return 0; + } + + int bus; + int port; + const char *device = toks[11]; + + if (sscanf(toks[5], "%d-%d", &bus, &port) != 2) { + log_error("Parsing bus-port of %s failed", buf); + util_str_free_split(toks, count); + return 0; + } + + log_debug( + "Detected flash drive on bus %d, port %d, device %s", + bus, + port, + device); + + for (int i = 0; i < 2; i++) { + if (propatch_usb_fix_usb_bus[i] == bus && + propatch_usb_fix_usb_port[i] == port) { + // The usb manager only cares about reading the second to last token + // in the correct format Copy-paste everything else + sprintf( + buf, + "%s/%s/%s/%s/%s/%d-%d/%d-%d:1.0", + toks[0], + toks[1], + toks[2], + toks[3], + toks[4], + propatch_usb_fix_usb_static_ini_usb_bus[i], + propatch_usb_fix_usb_static_ini_usb_port[i], + propatch_usb_fix_usb_static_ini_usb_bus[i], + propatch_usb_fix_usb_static_ini_usb_port[i]); + + log_debug("Player %d usb thumb drive at path %s", i, buf); + + util_str_free_split(toks, count); + + return strlen(buf); + } + } + + util_str_free_split(toks, count); } - strcpy(propatch_usb_fix_device_thumb_drive_p1, toks[0]); - strcpy(propatch_usb_fix_device_thumb_drive_p2, toks[1]); + return res; + } + return pro_usb_fix_real_readlink(path, buf, len); +} + +ssize_t readlink(const char *path, char *buf, size_t len) +{ + return propatch_usb_fix_readlink(path, buf, len); +} + +void propatch_usb_fix_init( + const char *device_nodes, const char *p1_bus_port, const char *p2_bus_port) +{ + size_t count; + char **toks; + + if (!device_nodes || !p1_bus_port || !p2_bus_port) { + log_warn("Disabled, missing one or multiple option properties"); + return; + } + + toks = util_str_split(device_nodes, ",", &count); + + if (count != 2) { + log_error("Invalid format for device nodes: %s", device_nodes); util_str_free_split(toks, count); + return; + } - if (sscanf(p1_bus_port, "%d-%d", &propatch_usb_fix_usb_bus[0], &propatch_usb_fix_usb_port[0]) != 2) { - log_error("Invalid format for p1 bus-port: %s", p1_bus_port); - return; - } + strcpy(propatch_usb_fix_device_thumb_drive_p1, toks[0]); + strcpy(propatch_usb_fix_device_thumb_drive_p2, toks[1]); - if (sscanf(p2_bus_port, "%d-%d", &propatch_usb_fix_usb_bus[1], &propatch_usb_fix_usb_port[1]) != 2) { - log_error("Invalid format for p2 bus-port: %s", p2_bus_port); - return; - } + util_str_free_split(toks, count); - log_info("Initialized: device nodes %s,%s, p1 %d-%d, p2 %d-%d", - propatch_usb_fix_device_thumb_drive_p1, - propatch_usb_fix_device_thumb_drive_p2, - propatch_usb_fix_usb_bus[0], - propatch_usb_fix_usb_port[0], - propatch_usb_fix_usb_bus[1], - propatch_usb_fix_usb_port[1]); + if (sscanf( + p1_bus_port, + "%d-%d", + &propatch_usb_fix_usb_bus[0], + &propatch_usb_fix_usb_port[0]) != 2) { + log_error("Invalid format for p1 bus-port: %s", p1_bus_port); + return; + } - propatch_usb_fix_enabled = true; + if (sscanf( + p2_bus_port, + "%d-%d", + &propatch_usb_fix_usb_bus[1], + &propatch_usb_fix_usb_port[1]) != 2) { + log_error("Invalid format for p2 bus-port: %s", p2_bus_port); + return; + } + + log_info( + "Initialized: device nodes %s,%s, p1 %d-%d, p2 %d-%d", + propatch_usb_fix_device_thumb_drive_p1, + propatch_usb_fix_device_thumb_drive_p2, + propatch_usb_fix_usb_bus[0], + propatch_usb_fix_usb_port[0], + propatch_usb_fix_usb_bus[1], + propatch_usb_fix_usb_port[1]); + + propatch_usb_fix_enabled = true; } void propatch_usb_fix_shutdown() { - } \ No newline at end of file diff --git a/src/main/hook/propatch/usb-fix.h b/src/main/hook/propatch/usb-fix.h index 0246d83..4438bd2 100644 --- a/src/main/hook/propatch/usb-fix.h +++ b/src/main/hook/propatch/usb-fix.h @@ -1,5 +1,6 @@ #pragma once -void propatch_usb_fix_init(const char* device_nodes, const char* p1_bus_port, const char* p2_bus_port); +void propatch_usb_fix_init( + const char *device_nodes, const char *p1_bus_port, const char *p2_bus_port); void propatch_usb_fix_shutdown(); \ No newline at end of file diff --git a/src/main/hook/x2/main.c b/src/main/hook/x2/main.c index 00b4e3f..1b96d0e 100644 --- a/src/main/hook/x2/main.c +++ b/src/main/hook/x2/main.c @@ -14,8 +14,8 @@ #include "hook/patch/hook-mon.h" #include "hook/patch/main-loop.h" #include "hook/patch/microdog34.h" -#include "hook/patch/piuio.h" #include "hook/patch/piuio-exit.h" +#include "hook/patch/piuio.h" #include "hook/patch/redir.h" #include "hook/patch/sigsegv.h" #include "hook/patch/sound.h" @@ -35,214 +35,226 @@ extern const uint8_t _binary_x2hook_dog_key_start[]; extern const uint8_t _binary_x2hook_dog_key_end[]; -static void x2hook_bootstrapping(int argc, char** argv, struct x2hook_options* options, char** game_data_path) +static void x2hook_bootstrapping( + int argc, + char **argv, + struct x2hook_options *options, + char **game_data_path) { - log_assert(argc >= 0); - log_assert(argv); - log_assert(options); - log_assert(game_data_path); + log_assert(argc >= 0); + log_assert(argv); + log_assert(options); + log_assert(game_data_path); - if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { - return; - } + if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { + return; + } - hook_core_piu_log_init(argc, argv); + hook_core_piu_log_init(argc, argv); - if (!x2hook_options_init(argc, argv, options)) { - exit(0); - } + if (!x2hook_options_init(argc, argv, options)) { + exit(0); + } - hook_core_piu_log_info(argc, argv); + hook_core_piu_log_info(argc, argv); - *game_data_path = hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); + *game_data_path = + hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); - hook_core_piu_utils_verify_root_user(); + hook_core_piu_utils_verify_root_user(); - log_info("Initializing, piu game data path: %s", *game_data_path); + log_info("Initializing, piu game data path: %s", *game_data_path); } -static void x2hook_patch_fs_init(struct x2hook_options* options) +static void x2hook_patch_fs_init(struct x2hook_options *options) { - log_assert(options); + log_assert(options); - patch_hook_mon_init( - options->patch.hook_mon.io, - options->patch.hook_mon.file, - options->patch.hook_mon.fs, - options->patch.hook_mon.usb, - options->patch.hook_mon.open); + patch_hook_mon_init( + options->patch.hook_mon.io, + options->patch.hook_mon.file, + options->patch.hook_mon.fs, + options->patch.hook_mon.usb, + options->patch.hook_mon.open); - patch_redir_init(); + patch_redir_init(); } -static void x2hook_fs_redir_settings(struct x2hook_options* options) +static void x2hook_fs_redir_settings(struct x2hook_options *options) { - log_assert(options); + log_assert(options); - if (options->game.settings) { - if (!util_fs_path_exists(options->game.settings)) { - log_info("Settings path %s does not exist, creating", options->game.settings); + if (options->game.settings) { + if (!util_fs_path_exists(options->game.settings)) { + log_info( + "Settings path %s does not exist, creating", options->game.settings); - if (!util_fs_mkdir(options->game.settings)) { - log_error("Creating directory %s failed", options->game.settings); - } - } - - char* abs_path = util_fs_get_abs_path(options->game.settings); - - cnh_redir_add("/SETTINGS", abs_path); - free(abs_path); - } else { - log_warn("No settings path specified"); + if (!util_fs_mkdir(options->game.settings)) { + log_error("Creating directory %s failed", options->game.settings); + } } + + char *abs_path = util_fs_get_abs_path(options->game.settings); + + cnh_redir_add("/SETTINGS", abs_path); + free(abs_path); + } else { + log_warn("No settings path specified"); + } } -static void x2hook_fs_redir_script(struct x2hook_options* options, const char* game_data_path) +static void x2hook_fs_redir_script( + struct x2hook_options *options, const char *game_data_path) { - log_assert(options); - log_assert(game_data_path); + log_assert(options); + log_assert(game_data_path); - char* path_tmp; + char *path_tmp; - path_tmp = util_str_merge(game_data_path, "/SCRIPT"); - cnh_redir_add("/SCRIPT", path_tmp); - free(path_tmp); + path_tmp = util_str_merge(game_data_path, "/SCRIPT"); + cnh_redir_add("/SCRIPT", path_tmp); + free(path_tmp); } static void x2hook_fs_redir_usb() { - /* Needed on newer kernels */ - cnh_redir_add("/proc/bus/usb/devices", "/sys/kernel/debug/usb/devices"); + /* Needed on newer kernels */ + cnh_redir_add("/proc/bus/usb/devices", "/sys/kernel/debug/usb/devices"); } -static void x2hook_fs_redirs_init(struct x2hook_options* options, const char* game_data_path) +static void x2hook_fs_redirs_init( + struct x2hook_options *options, const char *game_data_path) { - log_assert(options); - log_assert(game_data_path); + log_assert(options); + log_assert(game_data_path); - /* Expecting all assets in the piu game (asset) folder. redirects for files - that are not in there by default for reasons */ - x2hook_fs_redir_settings(options); - x2hook_fs_redir_script(options, game_data_path); + /* Expecting all assets in the piu game (asset) folder. redirects for files + that are not in there by default for reasons */ + x2hook_fs_redir_settings(options); + x2hook_fs_redir_script(options, game_data_path); - x2hook_fs_redir_usb(); + x2hook_fs_redir_usb(); } -static void x2hook_patch_gfx_init(struct x2hook_options* options) +static void x2hook_patch_gfx_init(struct x2hook_options *options) { - log_assert(options); + log_assert(options); - patch_gfx_init(); + patch_gfx_init(); - if (options->patch.gfx.windowed) { - patch_gfx_force_window_mode(); - } + if (options->patch.gfx.windowed) { + patch_gfx_force_window_mode(); + } } -static void x2hook_patch_game_init(struct x2hook_options* options) +static void x2hook_patch_game_init(struct x2hook_options *options) { - log_assert(options); + log_assert(options); - if (options->game.force_unlock) { - hook_x2_unlock_init(); - } + if (options->game.force_unlock) { + hook_x2_unlock_init(); + } - /* return from StopAllEffects to avoid killing the sound thread */ - log_warn("Applying memory patch only valid for version 102"); - util_patch_write_memory_byte(0x08074CE0, 0xC3); + /* return from StopAllEffects to avoid killing the sound thread */ + log_warn("Applying memory patch only valid for version 102"); + util_patch_write_memory_byte(0x08074CE0, 0xC3); } -static void x2hook_patch_main_loop_init(struct x2hook_options* options) +static void x2hook_patch_main_loop_init(struct x2hook_options *options) { - log_assert(options); + log_assert(options); - patch_main_loop_init(true, options->patch.main_loop.disable_built_in_inputs, false); + patch_main_loop_init( + true, options->patch.main_loop.disable_built_in_inputs, false); - if (options->patch.main_loop.x11_input_handler_api_lib) { - char* abs_path_x11_input_hook_lib = util_fs_get_abs_path(options->patch.main_loop.x11_input_handler_api_lib); + if (options->patch.main_loop.x11_input_handler_api_lib) { + char *abs_path_x11_input_hook_lib = util_fs_get_abs_path( + options->patch.main_loop.x11_input_handler_api_lib); - patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); - free(abs_path_x11_input_hook_lib); - } + patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); + free(abs_path_x11_input_hook_lib); + } } -static void x2hook_patch_sound_init(struct x2hook_options* options) +static void x2hook_patch_sound_init(struct x2hook_options *options) { - log_assert(options); + log_assert(options); - patch_sound_init(options->patch.sound.device); + patch_sound_init(options->patch.sound.device); } -static void x2hook_patch_sigsegv_init(struct x2hook_options* options) +static void x2hook_patch_sigsegv_init(struct x2hook_options *options) { - log_assert(options); + log_assert(options); - patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); + patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); } static void x2hook_patch_dongle_init() { - patch_microdog34_init((const uint8_t*) _binary_x2hook_dog_key_start, - ((uintptr_t) &_binary_x2hook_dog_key_end - (uintptr_t) &_binary_x2hook_dog_key_start)); + patch_microdog34_init( + (const uint8_t *) _binary_x2hook_dog_key_start, + ((uintptr_t) &_binary_x2hook_dog_key_end - + (uintptr_t) &_binary_x2hook_dog_key_start)); } -static void x2hook_patch_piuio_init(struct x2hook_options* options) +static void x2hook_patch_piuio_init(struct x2hook_options *options) { - log_assert(options); + log_assert(options); - /* Hook before IO emulation */ - if (options->patch.piuio.exit_test_serv) { - patch_piuio_exit_init(); - } + /* Hook before IO emulation */ + if (options->patch.piuio.exit_test_serv) { + patch_piuio_exit_init(); + } - patch_usb_init_fix_init(); - patch_usb_emu_init(); + patch_usb_init_fix_init(); + patch_usb_emu_init(); - if (options->patch.piuio.api_lib) { - char* abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); + if (options->patch.piuio.api_lib) { + char *abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); - patch_piuio_init(abs_path_iolib); - free(abs_path_iolib); - } + patch_piuio_init(abs_path_iolib); + free(abs_path_iolib); + } } void x2hook_constructor(void) { - /* Nothing here */ + /* Nothing here */ } void x2hook_destructor(void) { - /* Nothing here */ + /* Nothing here */ } -void x2hook_trap_before_main(int argc, char** argv) +void x2hook_trap_before_main(int argc, char **argv) { - log_assert(argc >= 0); - log_assert(argv); + log_assert(argc >= 0); + log_assert(argv); - char* game_data_path; - struct x2hook_options options; + char *game_data_path; + struct x2hook_options options; - x2hook_bootstrapping(argc, argv, &options, &game_data_path); - x2hook_patch_fs_init(&options); - x2hook_fs_redirs_init(&options, game_data_path); - x2hook_patch_gfx_init(&options); - x2hook_patch_game_init(&options); - x2hook_patch_main_loop_init(&options); - x2hook_patch_sound_init(&options); - x2hook_patch_sigsegv_init(&options); - x2hook_patch_dongle_init(); - x2hook_patch_piuio_init(&options); + x2hook_bootstrapping(argc, argv, &options, &game_data_path); + x2hook_patch_fs_init(&options); + x2hook_fs_redirs_init(&options, game_data_path); + x2hook_patch_gfx_init(&options); + x2hook_patch_game_init(&options); + x2hook_patch_main_loop_init(&options); + x2hook_patch_sound_init(&options); + x2hook_patch_sigsegv_init(&options); + x2hook_patch_dongle_init(); + x2hook_patch_piuio_init(&options); - free(game_data_path); + free(game_data_path); - log_info("Hooking finished"); + log_info("Hooking finished"); } void x2hook_trap_after_main(void) { - patch_piuio_shutdown(); + patch_piuio_shutdown(); } LIB_MAIN_CONSTRUCTOR(x2hook_constructor); diff --git a/src/main/hook/x2/ogl-fix.c b/src/main/hook/x2/ogl-fix.c index 067909e..67ad82d 100644 --- a/src/main/hook/x2/ogl-fix.c +++ b/src/main/hook/x2/ogl-fix.c @@ -2,8 +2,9 @@ * Module to fix weird OpenGL error that only appeared on Exceed 2 thus far. * * If OpenGL is not forced into single threaded mode, the backend will run in - * multi-threaded mode for some reason and crash in __glDispatchCheckMultithreaded - * when the game calls glXChooseVisual in its GFX init function. + * multi-threaded mode for some reason and crash in + * __glDispatchCheckMultithreaded when the game calls glXChooseVisual in its GFX + * init function. * * The fix is quite simple (luckily) as this seems that Exceed 2 is not the only * game that requires the environment variable __GL_SINGLETHREADED to be set. @@ -14,25 +15,27 @@ #include "capnhook/hook/lib.h" -typedef char* (*getenv_t) (const char* name); +typedef char *(*getenv_t)(const char *name); static getenv_t _x2hook_ogl_fix_real_getenv; -char* getenv(const char* name) +char *getenv(const char *name) { - if (!_x2hook_ogl_fix_real_getenv) { - _x2hook_ogl_fix_real_getenv = (getenv_t) cnh_lib_get_func_addr("getenv"); + if (!_x2hook_ogl_fix_real_getenv) { + _x2hook_ogl_fix_real_getenv = (getenv_t) cnh_lib_get_func_addr("getenv"); + } + + char *ret = _x2hook_ogl_fix_real_getenv(name); + + if (!strcmp(name, "__GL_SINGLETHREADED")) { + if (ret == NULL || strcmp(name, "1") != 0) { + printf( + "!!! x2hook: __GL_SINGLETHREADED not set or enabled, force patching " + "OpenGL to single threaded to " + "avoid crash !!!\n"); + return "1"; } + } - char* ret = _x2hook_ogl_fix_real_getenv(name); - - if (!strcmp(name, "__GL_SINGLETHREADED")) { - if (ret == NULL || strcmp(name, "1") != 0) { - printf("!!! x2hook: __GL_SINGLETHREADED not set or enabled, force patching OpenGL to single threaded to " - "avoid crash !!!\n"); - return "1"; - } - } - - return ret; + return ret; } \ No newline at end of file diff --git a/src/main/hook/x2/options.c b/src/main/hook/x2/options.c index 3816488..9953189 100644 --- a/src/main/hook/x2/options.c +++ b/src/main/hook/x2/options.c @@ -10,19 +10,24 @@ #define X2HOOK_OPTIONS_STR_PATCH_HOOK_MON_IO "patch.hook_mon.io" #define X2HOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN "patch.hook_mon.open" #define X2HOOK_OPTIONS_STR_PATCH_HOOK_MON_USB "patch.hook_mon.usb" -#define X2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS "patch.hook_main_loop.disable_built_in_inputs" -#define X2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER "patch_hook_main_loop.x11_input_handler" +#define X2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS \ + "patch.hook_main_loop.disable_built_in_inputs" +#define X2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER \ + "patch_hook_main_loop.x11_input_handler" #define X2HOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB "patch.piuio.emu_lib" -#define X2HOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV "patch.piuio_exit.test_serv" +#define X2HOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV \ + "patch.piuio_exit.test_serv" #define X2HOOK_OPTIONS_STR_PATCH_SOUND_DEVICE "patch.sound.device" -#define X2HOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV "patch.sigsegv.halt_on_segv" +#define X2HOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV \ + "patch.sigsegv.halt_on_segv" #define X2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE "util.log.file" #define X2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL "util.log.level" static const struct util_options_def x2hook_options_def[] = { { .name = X2HOOK_OPTIONS_STR_GAME_FORCE_UNLOCK, - .description = "Force unlock the game. Modifies the current and any new PIUEXCEED.INI settings file permanently", + .description = "Force unlock the game. Modifies the current and any " + "new PIUEXCEED.INI settings file permanently", .param = 'z', .type = UTIL_OPTIONS_TYPE_BOOL, .default_value.b = false, @@ -78,21 +83,24 @@ static const struct util_options_def x2hook_options_def[] = { }, { .name = X2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS, - .description = "Disable the built in keyboard inputs for test (F1), service (F2) and clear (F3)", + .description = "Disable the built in keyboard inputs for test (F1), " + "service (F2) and clear (F3)", .param = 'k', .type = UTIL_OPTIONS_TYPE_BOOL, .default_value.b = false, }, { .name = X2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER, - .description = "Path to a library implementing the x11-input-handler api to capture X11 keyboard inputs", + .description = "Path to a library implementing the x11-input-handler " + "api to capture X11 keyboard inputs", .param = 'q', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, }, { .name = X2HOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB, - .description = "Path to library implementing the piuio api for piuio emulation", + .description = + "Path to library implementing the piuio api for piuio emulation", .param = 'p', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, @@ -143,41 +151,53 @@ static const struct util_options_defs x2hook_options_defs = { .ndefs = lengthof(x2hook_options_def) }; -bool x2hook_options_init(int argc, char** argv, struct x2hook_options* options) +bool x2hook_options_init(int argc, char **argv, struct x2hook_options *options) { - log_assert(argv); - log_assert(options); + log_assert(argv); + log_assert(options); - struct util_options_opts* options_opt; + struct util_options_opts *options_opt; - util_options_init(argc, argv); - options_opt = util_options_get(&x2hook_options_defs); + util_options_init(argc, argv); + options_opt = util_options_get(&x2hook_options_defs); - if (!options_opt) { - return false; - } + if (!options_opt) { + return false; + } - options->game.force_unlock = util_options_get_bool(options_opt, X2HOOK_OPTIONS_STR_GAME_FORCE_UNLOCK); - options->game.settings = util_options_get_str(options_opt, X2HOOK_OPTIONS_STR_GAME_SETTINGS); - options->patch.gfx.windowed = util_options_get_bool(options_opt, X2HOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); - options->patch.hook_mon.file = util_options_get_bool(options_opt, X2HOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); - options->patch.hook_mon.fs = util_options_get_bool(options_opt, X2HOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); - options->patch.hook_mon.io = util_options_get_bool(options_opt, X2HOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); - options->patch.hook_mon.open = util_options_get_bool(options_opt, X2HOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); - options->patch.hook_mon.usb = util_options_get_bool(options_opt, X2HOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); - options->patch.main_loop.disable_built_in_inputs = util_options_get_bool(options_opt, - X2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); - options->patch.main_loop.x11_input_handler_api_lib = - util_options_get_str(options_opt, X2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); - options->patch.piuio.api_lib = util_options_get_str(options_opt, X2HOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); - options->patch.piuio.exit_test_serv = - util_options_get_bool(options_opt, X2HOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); - options->patch.sound.device = util_options_get_str(options_opt, X2HOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); - options->patch.sigsegv.halt_on_segv = - util_options_get_bool(options_opt, X2HOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); - options->log.file = util_options_get_str(options_opt, X2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); - options->log.level = - (enum util_log_level) util_options_get_int(options_opt, X2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); + options->game.force_unlock = + util_options_get_bool(options_opt, X2HOOK_OPTIONS_STR_GAME_FORCE_UNLOCK); + options->game.settings = + util_options_get_str(options_opt, X2HOOK_OPTIONS_STR_GAME_SETTINGS); + options->patch.gfx.windowed = + util_options_get_bool(options_opt, X2HOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); + options->patch.hook_mon.file = util_options_get_bool( + options_opt, X2HOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); + options->patch.hook_mon.fs = + util_options_get_bool(options_opt, X2HOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); + options->patch.hook_mon.io = + util_options_get_bool(options_opt, X2HOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); + options->patch.hook_mon.open = util_options_get_bool( + options_opt, X2HOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); + options->patch.hook_mon.usb = + util_options_get_bool(options_opt, X2HOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); + options->patch.main_loop.disable_built_in_inputs = util_options_get_bool( + options_opt, + X2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); + options->patch.main_loop.x11_input_handler_api_lib = util_options_get_str( + options_opt, X2HOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); + options->patch.piuio.api_lib = + util_options_get_str(options_opt, X2HOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); + options->patch.piuio.exit_test_serv = util_options_get_bool( + options_opt, X2HOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); + options->patch.sound.device = + util_options_get_str(options_opt, X2HOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); + options->patch.sigsegv.halt_on_segv = util_options_get_bool( + options_opt, X2HOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); + options->log.file = + util_options_get_str(options_opt, X2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); + options->log.level = (enum util_log_level) util_options_get_int( + options_opt, X2HOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); - return true; + return true; } \ No newline at end of file diff --git a/src/main/hook/x2/options.h b/src/main/hook/x2/options.h index 21f963d..d75d8cd 100644 --- a/src/main/hook/x2/options.h +++ b/src/main/hook/x2/options.h @@ -7,49 +7,49 @@ #include "util/log.h" struct x2hook_options { - struct game { - bool force_unlock; - const char* settings; - } game; + struct game { + bool force_unlock; + const char *settings; + } game; - struct patch { - struct gfx { - bool windowed; - } gfx; + struct patch { + struct gfx { + bool windowed; + } gfx; - struct hook_mon { - bool file; - bool fs; - bool io; - bool open; - bool usb; - } hook_mon; + struct hook_mon { + bool file; + bool fs; + bool io; + bool open; + bool usb; + } hook_mon; - struct main_loop { - bool disable_built_in_inputs; - const char* x11_input_handler_api_lib; - } main_loop; + struct main_loop { + bool disable_built_in_inputs; + const char *x11_input_handler_api_lib; + } main_loop; - struct piuio { - const char* api_lib; - bool exit_test_serv; - } piuio; + struct piuio { + const char *api_lib; + bool exit_test_serv; + } piuio; - struct sound { - const char* device; - } sound; + struct sound { + const char *device; + } sound; - struct sigsegv { - bool halt_on_segv; - } sigsegv; - } patch; + struct sigsegv { + bool halt_on_segv; + } sigsegv; + } patch; - struct log { - const char* file; - enum util_log_level level; - } log; + struct log { + const char *file; + enum util_log_level level; + } log; }; -bool x2hook_options_init(int argc, char** argv, struct x2hook_options* options); +bool x2hook_options_init(int argc, char **argv, struct x2hook_options *options); #endif diff --git a/src/main/hook/x2/unlock.c b/src/main/hook/x2/unlock.c index 459cf44..376be6b 100644 --- a/src/main/hook/x2/unlock.c +++ b/src/main/hook/x2/unlock.c @@ -10,72 +10,73 @@ #include "util/log.h" #include "util/str.h" -static FILE* _hook_x2_unlock_settings_file = NULL; +static FILE *_hook_x2_unlock_settings_file = NULL; static enum cnh_result _hook_x2_unlock_filehook(struct cnh_filehook_irp *irp); void hook_x2_unlock_init(void) { - cnh_filehook_push_handler(_hook_x2_unlock_filehook); + cnh_filehook_push_handler(_hook_x2_unlock_filehook); - log_info("Initialized"); + log_info("Initialized"); } static enum cnh_result _hook_x2_unlock_filehook(struct cnh_filehook_irp *irp) { - enum cnh_result result; + enum cnh_result result; - assert(irp); + assert(irp); - if (irp->op != CNH_FILEHOOK_IRP_OP_OPEN && irp->file != _hook_x2_unlock_settings_file) { - return cnh_filehook_invoke_next(irp); + if (irp->op != CNH_FILEHOOK_IRP_OP_OPEN && + irp->file != _hook_x2_unlock_settings_file) { + return cnh_filehook_invoke_next(irp); + } + + switch (irp->op) { + case CNH_FILEHOOK_IRP_OP_OPEN: { + /* Let it open the real file */ + result = cnh_filehook_invoke_next(irp); + + if (util_str_ends_with(irp->open_filename, ASSET_X2_SETTINGS_FILE_NAME)) { + if (result == CNH_RESULT_SUCCESS) { + log_debug("Intercepting settings file open"); + _hook_x2_unlock_settings_file = irp->file; + } + } + + break; } - switch (irp->op) { - case CNH_FILEHOOK_IRP_OP_OPEN: - { - /* Let it open the real file */ - result = cnh_filehook_invoke_next(irp); + case CNH_FILEHOOK_IRP_OP_READ: { + /* Let it read the real file */ + result = cnh_filehook_invoke_next(irp); - if (util_str_ends_with(irp->open_filename, ASSET_X2_SETTINGS_FILE_NAME)) { - if (result == CNH_RESULT_SUCCESS) { - log_debug("Intercepting settings file open"); - _hook_x2_unlock_settings_file = irp->file; - } - } + if (result == CNH_RESULT_SUCCESS) { + struct asset_x2_settings *settings = + (struct asset_x2_settings *) irp->read.bytes; - break; - } + asset_x2_settings_unlock_all(settings); - case CNH_FILEHOOK_IRP_OP_READ: - { - /* Let it read the real file */ - result = cnh_filehook_invoke_next(irp); + log_debug( + "Applied unlock patch to loaded settings (buffer size %d)", + irp->read.pos); + } - if (result == CNH_RESULT_SUCCESS) { - struct asset_x2_settings* settings = (struct asset_x2_settings*) irp->read.bytes; - - asset_x2_settings_unlock_all(settings); - - log_debug("Applied unlock patch to loaded settings (buffer size %d)", irp->read.pos); - } - - break; - } - - case CNH_FILEHOOK_IRP_OP_CLOSE: - { - _hook_x2_unlock_settings_file = NULL; - - result = cnh_filehook_invoke_next(irp); - - break; - } - - default: - result = cnh_filehook_invoke_next(irp); - break; + break; } - return result; + case CNH_FILEHOOK_IRP_OP_CLOSE: { + _hook_x2_unlock_settings_file = NULL; + + result = cnh_filehook_invoke_next(irp); + + break; + } + + default: + result = cnh_filehook_invoke_next(irp); + break; + } + + return result; } \ No newline at end of file diff --git a/src/main/hook/x2/unlock.h b/src/main/hook/x2/unlock.h index 4105a0a..ce6f521 100644 --- a/src/main/hook/x2/unlock.h +++ b/src/main/hook/x2/unlock.h @@ -1,5 +1,6 @@ /** - * Patch module to force unlock all permanently unlockable songs and additional difficulties in the game. + * Patch module to force unlock all permanently unlockable songs and additional + * difficulties in the game. */ #ifndef HOOK_X2_UNLOCK_H #define HOOK_X2_UNLOCK_H diff --git a/src/main/hook/zero/main.c b/src/main/hook/zero/main.c index 3ecbc00..7ecabe7 100644 --- a/src/main/hook/zero/main.c +++ b/src/main/hook/zero/main.c @@ -15,8 +15,8 @@ #include "hook/patch/hook-mon.h" #include "hook/patch/main-loop.h" #include "hook/patch/microdog34.h" -#include "hook/patch/piuio.h" #include "hook/patch/piuio-exit.h" +#include "hook/patch/piuio.h" #include "hook/patch/redir.h" #include "hook/patch/sigsegv.h" #include "hook/patch/sound.h" @@ -37,217 +37,231 @@ extern const uint8_t _binary_zerohook_hdd_raw_end[]; extern const uint8_t _binary_zerohook_dog_key_start[]; extern const uint8_t _binary_zerohook_dog_key_end[]; -static void zerohook_bootstrapping(int argc, char** argv, struct zerohook_options* options, char** game_data_path) +static void zerohook_bootstrapping( + int argc, + char **argv, + struct zerohook_options *options, + char **game_data_path) { - log_assert(argc >= 0); - log_assert(argv); - log_assert(options); - log_assert(game_data_path); + log_assert(argc >= 0); + log_assert(argv); + log_assert(options); + log_assert(game_data_path); - if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { - return; - } + if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) { + return; + } - hook_core_piu_log_init(argc, argv); + hook_core_piu_log_init(argc, argv); - if (!zerohook_options_init(argc, argv, options)) { - exit(0); - } + if (!zerohook_options_init(argc, argv, options)) { + exit(0); + } - hook_core_piu_log_info(argc, argv); + hook_core_piu_log_info(argc, argv); - *game_data_path = hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); + *game_data_path = + hook_core_piu_utils_get_and_verify_game_data_path(argc, argv); - hook_core_piu_utils_verify_root_user(); + hook_core_piu_utils_verify_root_user(); - log_info("Initializing, piu game data path: %s", *game_data_path); + log_info("Initializing, piu game data path: %s", *game_data_path); } -static void zerohook_patch_fs_init(struct zerohook_options* options) +static void zerohook_patch_fs_init(struct zerohook_options *options) { - log_assert(options); + log_assert(options); - patch_hook_mon_init( - options->patch.hook_mon.io, - options->patch.hook_mon.file, - options->patch.hook_mon.fs, - options->patch.hook_mon.usb, - options->patch.hook_mon.open); + patch_hook_mon_init( + options->patch.hook_mon.io, + options->patch.hook_mon.file, + options->patch.hook_mon.fs, + options->patch.hook_mon.usb, + options->patch.hook_mon.open); - patch_redir_init(); + patch_redir_init(); } -static void zerohook_fs_redir_settings(struct zerohook_options* options) +static void zerohook_fs_redir_settings(struct zerohook_options *options) { - log_assert(options); + log_assert(options); - if (options->game.settings) { - if (!util_fs_path_exists(options->game.settings)) { - log_info("Settings path %s does not exist, creating", options->game.settings); + if (options->game.settings) { + if (!util_fs_path_exists(options->game.settings)) { + log_info( + "Settings path %s does not exist, creating", options->game.settings); - if (!util_fs_mkdir(options->game.settings)) { - log_error("Creating directory %s failed", options->game.settings); - } - } - - char* abs_path = util_fs_get_abs_path(options->game.settings); - - cnh_redir_add("/SETTINGS", abs_path); - free(abs_path); - } else { - log_warn("No settings path specified"); + if (!util_fs_mkdir(options->game.settings)) { + log_error("Creating directory %s failed", options->game.settings); + } } + + char *abs_path = util_fs_get_abs_path(options->game.settings); + + cnh_redir_add("/SETTINGS", abs_path); + free(abs_path); + } else { + log_warn("No settings path specified"); + } } -static void zerohook_fs_redir_script(struct zerohook_options* options, const char* game_data_path) +static void zerohook_fs_redir_script( + struct zerohook_options *options, const char *game_data_path) { - log_assert(options); - log_assert(game_data_path); + log_assert(options); + log_assert(game_data_path); - char* path_tmp; + char *path_tmp; - path_tmp = util_str_merge(game_data_path, "/SCRIPT"); - cnh_redir_add("/SCRIPT", path_tmp); - free(path_tmp); + path_tmp = util_str_merge(game_data_path, "/SCRIPT"); + cnh_redir_add("/SCRIPT", path_tmp); + free(path_tmp); } static void zerohook_fs_redir_usb() { - /* Needed on newer kernels */ - cnh_redir_add("/proc/bus/usb/devices", "/sys/kernel/debug/usb/devices"); + /* Needed on newer kernels */ + cnh_redir_add("/proc/bus/usb/devices", "/sys/kernel/debug/usb/devices"); } -static void zerohook_fs_redirs_init(struct zerohook_options* options, const char* game_data_path) +static void zerohook_fs_redirs_init( + struct zerohook_options *options, const char *game_data_path) { - log_assert(options); - log_assert(game_data_path); + log_assert(options); + log_assert(game_data_path); - /* Expecting all assets in the piu game (asset) folder. redirects for files - that are not in there by default for reasons */ - zerohook_fs_redir_settings(options); - zerohook_fs_redir_script(options, game_data_path); + /* Expecting all assets in the piu game (asset) folder. redirects for files + that are not in there by default for reasons */ + zerohook_fs_redir_settings(options); + zerohook_fs_redir_script(options, game_data_path); - zerohook_fs_redir_usb(); + zerohook_fs_redir_usb(); } -static void zerohook_patch_gfx_init(struct zerohook_options* options) +static void zerohook_patch_gfx_init(struct zerohook_options *options) { - log_assert(options); + log_assert(options); - patch_gfx_init(); + patch_gfx_init(); - if (options->patch.gfx.windowed) { - patch_gfx_force_window_mode(); - } + if (options->patch.gfx.windowed) { + patch_gfx_force_window_mode(); + } } -static void zerohook_patch_game_init(struct zerohook_options* options) +static void zerohook_patch_game_init(struct zerohook_options *options) { - log_assert(options); + log_assert(options); - if (options->game.force_unlock) { - hook_zero_unlock_init(); - } + if (options->game.force_unlock) { + hook_zero_unlock_init(); + } } -static void zerohook_patch_main_loop_init(struct zerohook_options* options) +static void zerohook_patch_main_loop_init(struct zerohook_options *options) { - log_assert(options); + log_assert(options); - patch_main_loop_init(true, options->patch.main_loop.disable_built_in_inputs, false); + patch_main_loop_init( + true, options->patch.main_loop.disable_built_in_inputs, false); - if (options->patch.main_loop.x11_input_handler_api_lib) { - char* abs_path_x11_input_hook_lib = util_fs_get_abs_path(options->patch.main_loop.x11_input_handler_api_lib); + if (options->patch.main_loop.x11_input_handler_api_lib) { + char *abs_path_x11_input_hook_lib = util_fs_get_abs_path( + options->patch.main_loop.x11_input_handler_api_lib); - patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); - free(abs_path_x11_input_hook_lib); - } + patch_main_loop_add_x11_input_handler(abs_path_x11_input_hook_lib); + free(abs_path_x11_input_hook_lib); + } } -static void zerohook_patch_sound_init(struct zerohook_options* options) +static void zerohook_patch_sound_init(struct zerohook_options *options) { - log_assert(options); + log_assert(options); - patch_sound_init(options->patch.sound.device); + patch_sound_init(options->patch.sound.device); } -static void zerohook_patch_sigsegv_init(struct zerohook_options* options) +static void zerohook_patch_sigsegv_init(struct zerohook_options *options) { - log_assert(options); + log_assert(options); - patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); + patch_sigsegv_init(options->patch.sigsegv.halt_on_segv); } static void zerohook_patch_dongle_init() { - patch_microdog34_init((const uint8_t*) _binary_zerohook_dog_key_start, - ((uintptr_t) &_binary_zerohook_dog_key_end - (uintptr_t) &_binary_zerohook_dog_key_start)); + patch_microdog34_init( + (const uint8_t *) _binary_zerohook_dog_key_start, + ((uintptr_t) &_binary_zerohook_dog_key_end - + (uintptr_t) &_binary_zerohook_dog_key_start)); } static void zerohook_patch_hdd_check_init() { - patch_hdd_check_init((const uint8_t*) _binary_zerohook_hdd_raw_start, - ((uintptr_t) &_binary_zerohook_hdd_raw_end - (uintptr_t) &_binary_zerohook_hdd_raw_start)); + patch_hdd_check_init( + (const uint8_t *) _binary_zerohook_hdd_raw_start, + ((uintptr_t) &_binary_zerohook_hdd_raw_end - + (uintptr_t) &_binary_zerohook_hdd_raw_start)); } -static void zerohook_patch_piuio_init(struct zerohook_options* options) +static void zerohook_patch_piuio_init(struct zerohook_options *options) { - log_assert(options); + log_assert(options); - /* Hook before IO emulation */ - if (options->patch.piuio.exit_test_serv) { - patch_piuio_exit_init(); - } + /* Hook before IO emulation */ + if (options->patch.piuio.exit_test_serv) { + patch_piuio_exit_init(); + } - patch_usb_init_fix_init(); - patch_usb_emu_init(); + patch_usb_init_fix_init(); + patch_usb_emu_init(); - if (options->patch.piuio.api_lib) { - char* abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); + if (options->patch.piuio.api_lib) { + char *abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib); - patch_piuio_init(abs_path_iolib); - free(abs_path_iolib); - } + patch_piuio_init(abs_path_iolib); + free(abs_path_iolib); + } } void zerohook_constructor(void) { - /* Nothing here */ + /* Nothing here */ } void zerohook_destructor(void) { - /* Nothing here */ + /* Nothing here */ } -void zerohook_trap_before_main(int argc, char** argv) +void zerohook_trap_before_main(int argc, char **argv) { - log_assert(argc >= 0); - log_assert(argv); + log_assert(argc >= 0); + log_assert(argv); - char* game_data_path; - struct zerohook_options options; + char *game_data_path; + struct zerohook_options options; - zerohook_bootstrapping(argc, argv, &options, &game_data_path); - zerohook_patch_fs_init(&options); - zerohook_fs_redirs_init(&options, game_data_path); - zerohook_patch_gfx_init(&options); - zerohook_patch_game_init(&options); - zerohook_patch_main_loop_init(&options); - zerohook_patch_sound_init(&options); - zerohook_patch_sigsegv_init(&options); - zerohook_patch_dongle_init(); - zerohook_patch_hdd_check_init(); - zerohook_patch_piuio_init(&options); + zerohook_bootstrapping(argc, argv, &options, &game_data_path); + zerohook_patch_fs_init(&options); + zerohook_fs_redirs_init(&options, game_data_path); + zerohook_patch_gfx_init(&options); + zerohook_patch_game_init(&options); + zerohook_patch_main_loop_init(&options); + zerohook_patch_sound_init(&options); + zerohook_patch_sigsegv_init(&options); + zerohook_patch_dongle_init(); + zerohook_patch_hdd_check_init(); + zerohook_patch_piuio_init(&options); - free(game_data_path); + free(game_data_path); - log_info("Hooking finished"); + log_info("Hooking finished"); } void zerohook_trap_after_main(void) { - patch_piuio_shutdown(); + patch_piuio_shutdown(); } LIB_MAIN_CONSTRUCTOR(zerohook_constructor); diff --git a/src/main/hook/zero/options.c b/src/main/hook/zero/options.c index 74166bc..ebaa86f 100644 --- a/src/main/hook/zero/options.c +++ b/src/main/hook/zero/options.c @@ -10,19 +10,24 @@ #define ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO "patch.hook_mon.io" #define ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN "patch.hook_mon.open" #define ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB "patch.hook_mon.usb" -#define ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS "patch.hook_main_loop.disable_built_in_inputs" -#define ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER "patch_hook_main_loop.x11_input_handler" +#define ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS \ + "patch.hook_main_loop.disable_built_in_inputs" +#define ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER \ + "patch_hook_main_loop.x11_input_handler" #define ZEROHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB "patch.piuio.emu_lib" -#define ZEROHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV "patch.piuio_exit.test_serv" +#define ZEROHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV \ + "patch.piuio_exit.test_serv" #define ZEROHOOK_OPTIONS_STR_PATCH_SOUND_DEVICE "patch.sound.device" -#define ZEROHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV "patch.sigsegv.halt_on_segv" +#define ZEROHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV \ + "patch.sigsegv.halt_on_segv" #define ZEROHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE "util.log.file" #define ZEROHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL "util.log.level" static const struct util_options_def zerohook_options_def[] = { { .name = ZEROHOOK_OPTIONS_STR_GAME_FORCE_UNLOCK, - .description = "Force unlock the game. Modifies the current and any new PIUZERO.INI settings file permanently", + .description = "Force unlock the game. Modifies the current and any " + "new PIUZERO.INI settings file permanently", .param = 'z', .type = UTIL_OPTIONS_TYPE_BOOL, .default_value.b = false, @@ -77,22 +82,26 @@ static const struct util_options_def zerohook_options_def[] = { .default_value.b = false, }, { - .name = ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS, - .description = "Disable the built in keyboard inputs for test (F1), service (F2) and clear (F3)", + .name = + ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS, + .description = "Disable the built in keyboard inputs for test (F1), " + "service (F2) and clear (F3)", .param = 'k', .type = UTIL_OPTIONS_TYPE_BOOL, .default_value.b = false, }, { .name = ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER, - .description = "Path to a library implementing the x11-input-handler api to capture X11 keyboard inputs", + .description = "Path to a library implementing the x11-input-handler " + "api to capture X11 keyboard inputs", .param = 'q', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, }, { .name = ZEROHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB, - .description = "Path to library implementing the piuio api for piuio emulation", + .description = + "Path to library implementing the piuio api for piuio emulation", .param = 'p', .type = UTIL_OPTIONS_TYPE_STR, .default_value.str = NULL, @@ -143,41 +152,54 @@ static const struct util_options_defs zerohook_options_defs = { .ndefs = lengthof(zerohook_options_def) }; -bool zerohook_options_init(int argc, char** argv, struct zerohook_options* options) +bool zerohook_options_init( + int argc, char **argv, struct zerohook_options *options) { - log_assert(argv); - log_assert(options); + log_assert(argv); + log_assert(options); - struct util_options_opts* options_opt; + struct util_options_opts *options_opt; - util_options_init(argc, argv); - options_opt = util_options_get(&zerohook_options_defs); + util_options_init(argc, argv); + options_opt = util_options_get(&zerohook_options_defs); - if (!options_opt) { - return false; - } + if (!options_opt) { + return false; + } - options->game.force_unlock = util_options_get_bool(options_opt, ZEROHOOK_OPTIONS_STR_GAME_FORCE_UNLOCK); - options->game.settings = util_options_get_str(options_opt, ZEROHOOK_OPTIONS_STR_GAME_SETTINGS); - options->patch.gfx.windowed = util_options_get_bool(options_opt, ZEROHOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); - options->patch.hook_mon.file = util_options_get_bool(options_opt, ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); - options->patch.hook_mon.fs = util_options_get_bool(options_opt, ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); - options->patch.hook_mon.io = util_options_get_bool(options_opt, ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); - options->patch.hook_mon.open = util_options_get_bool(options_opt, ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); - options->patch.hook_mon.usb = util_options_get_bool(options_opt, ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); - options->patch.main_loop.disable_built_in_inputs = util_options_get_bool(options_opt, - ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); - options->patch.main_loop.x11_input_handler_api_lib = - util_options_get_str(options_opt, ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); - options->patch.piuio.api_lib = util_options_get_str(options_opt, ZEROHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); - options->patch.piuio.exit_test_serv = - util_options_get_bool(options_opt, ZEROHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); - options->patch.sound.device = util_options_get_str(options_opt, ZEROHOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); - options->patch.sigsegv.halt_on_segv = - util_options_get_bool(options_opt, ZEROHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); - options->log.file = util_options_get_str(options_opt, ZEROHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); - options->log.level = - (enum util_log_level) util_options_get_int(options_opt, ZEROHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); + options->game.force_unlock = util_options_get_bool( + options_opt, ZEROHOOK_OPTIONS_STR_GAME_FORCE_UNLOCK); + options->game.settings = + util_options_get_str(options_opt, ZEROHOOK_OPTIONS_STR_GAME_SETTINGS); + options->patch.gfx.windowed = util_options_get_bool( + options_opt, ZEROHOOK_OPTIONS_STR_PATCH_GFX_WINDOWED); + options->patch.hook_mon.file = util_options_get_bool( + options_opt, ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE); + options->patch.hook_mon.fs = util_options_get_bool( + options_opt, ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MON_FS); + options->patch.hook_mon.io = util_options_get_bool( + options_opt, ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO); + options->patch.hook_mon.open = util_options_get_bool( + options_opt, ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN); + options->patch.hook_mon.usb = util_options_get_bool( + options_opt, ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB); + options->patch.main_loop.disable_built_in_inputs = util_options_get_bool( + options_opt, + ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_DISABLE_BUILT_IN_INPUTS); + options->patch.main_loop.x11_input_handler_api_lib = util_options_get_str( + options_opt, ZEROHOOK_OPTIONS_STR_PATCH_HOOK_MAIN_LOOP_X11_INPUT_HANDLER); + options->patch.piuio.api_lib = util_options_get_str( + options_opt, ZEROHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB); + options->patch.piuio.exit_test_serv = util_options_get_bool( + options_opt, ZEROHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV); + options->patch.sound.device = util_options_get_str( + options_opt, ZEROHOOK_OPTIONS_STR_PATCH_SOUND_DEVICE); + options->patch.sigsegv.halt_on_segv = util_options_get_bool( + options_opt, ZEROHOOK_OPTIONS_STR_PATCH_SIGSEGV_HALT_ON_SEGV); + options->log.file = util_options_get_str( + options_opt, ZEROHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE); + options->log.level = (enum util_log_level) util_options_get_int( + options_opt, ZEROHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL); - return true; + return true; } \ No newline at end of file diff --git a/src/main/hook/zero/options.h b/src/main/hook/zero/options.h index a5e4f00..83ab03b 100644 --- a/src/main/hook/zero/options.h +++ b/src/main/hook/zero/options.h @@ -7,49 +7,50 @@ #include "util/log.h" struct zerohook_options { - struct game { - bool force_unlock; - const char* settings; - } game; + struct game { + bool force_unlock; + const char *settings; + } game; - struct patch { - struct gfx { - bool windowed; - } gfx; + struct patch { + struct gfx { + bool windowed; + } gfx; - struct hook_mon { - bool file; - bool fs; - bool io; - bool open; - bool usb; - } hook_mon; + struct hook_mon { + bool file; + bool fs; + bool io; + bool open; + bool usb; + } hook_mon; - struct main_loop { - bool disable_built_in_inputs; - const char* x11_input_handler_api_lib; - } main_loop; + struct main_loop { + bool disable_built_in_inputs; + const char *x11_input_handler_api_lib; + } main_loop; - struct piuio { - const char* api_lib; - bool exit_test_serv; - } piuio; + struct piuio { + const char *api_lib; + bool exit_test_serv; + } piuio; - struct sound { - const char* device; - } sound; + struct sound { + const char *device; + } sound; - struct sigsegv { - bool halt_on_segv; - } sigsegv; - } patch; + struct sigsegv { + bool halt_on_segv; + } sigsegv; + } patch; - struct log { - const char* file; - enum util_log_level level; - } log; + struct log { + const char *file; + enum util_log_level level; + } log; }; -bool zerohook_options_init(int argc, char** argv, struct zerohook_options* options); +bool zerohook_options_init( + int argc, char **argv, struct zerohook_options *options); #endif diff --git a/src/main/hook/zero/unlock.c b/src/main/hook/zero/unlock.c index bb088c7..95665cd 100644 --- a/src/main/hook/zero/unlock.c +++ b/src/main/hook/zero/unlock.c @@ -10,72 +10,74 @@ #include "util/log.h" #include "util/str.h" -static FILE* _hook_zerounlock_settings_file = NULL; +static FILE *_hook_zerounlock_settings_file = NULL; static enum cnh_result _hook_zerounlock_filehook(struct cnh_filehook_irp *irp); void hook_zero_unlock_init(void) { - cnh_filehook_push_handler(_hook_zerounlock_filehook); + cnh_filehook_push_handler(_hook_zerounlock_filehook); - log_info("Initialized"); + log_info("Initialized"); } static enum cnh_result _hook_zerounlock_filehook(struct cnh_filehook_irp *irp) { - enum cnh_result result; + enum cnh_result result; - assert(irp); + assert(irp); - if (irp->op != CNH_FILEHOOK_IRP_OP_OPEN && irp->file != _hook_zerounlock_settings_file) { - return cnh_filehook_invoke_next(irp); + if (irp->op != CNH_FILEHOOK_IRP_OP_OPEN && + irp->file != _hook_zerounlock_settings_file) { + return cnh_filehook_invoke_next(irp); + } + + switch (irp->op) { + case CNH_FILEHOOK_IRP_OP_OPEN: { + /* Let it open the real file */ + result = cnh_filehook_invoke_next(irp); + + if (util_str_ends_with( + irp->open_filename, ASSET_ZERO_SETTINGS_FILE_NAME)) { + if (result == CNH_RESULT_SUCCESS) { + log_debug("Intercepting settings file open"); + _hook_zerounlock_settings_file = irp->file; + } + } + + break; } - switch (irp->op) { - case CNH_FILEHOOK_IRP_OP_OPEN: - { - /* Let it open the real file */ - result = cnh_filehook_invoke_next(irp); + case CNH_FILEHOOK_IRP_OP_READ: { + /* Let it read the real file */ + result = cnh_filehook_invoke_next(irp); - if (util_str_ends_with(irp->open_filename, ASSET_ZERO_SETTINGS_FILE_NAME)) { - if (result == CNH_RESULT_SUCCESS) { - log_debug("Intercepting settings file open"); - _hook_zerounlock_settings_file = irp->file; - } - } + if (result == CNH_RESULT_SUCCESS) { + struct asset_zero_settings *settings = + (struct asset_zero_settings *) irp->read.bytes; - break; - } + asset_zero_settings_unlock_all(settings); - case CNH_FILEHOOK_IRP_OP_READ: - { - /* Let it read the real file */ - result = cnh_filehook_invoke_next(irp); + log_debug( + "Applied unlock patch to loaded settings (buffer size %d)", + irp->read.pos); + } - if (result == CNH_RESULT_SUCCESS) { - struct asset_zero_settings* settings = (struct asset_zero_settings*) irp->read.bytes; - - asset_zero_settings_unlock_all(settings); - - log_debug("Applied unlock patch to loaded settings (buffer size %d)", irp->read.pos); - } - - break; - } - - case CNH_FILEHOOK_IRP_OP_CLOSE: - { - _hook_zerounlock_settings_file = NULL; - - result = cnh_filehook_invoke_next(irp); - - break; - } - - default: - result = cnh_filehook_invoke_next(irp); - break; + break; } - return result; + case CNH_FILEHOOK_IRP_OP_CLOSE: { + _hook_zerounlock_settings_file = NULL; + + result = cnh_filehook_invoke_next(irp); + + break; + } + + default: + result = cnh_filehook_invoke_next(irp); + break; + } + + return result; } \ No newline at end of file diff --git a/src/main/io/piubtn/defs.h b/src/main/io/piubtn/defs.h index 73bd7c8..edfd14a 100644 --- a/src/main/io/piubtn/defs.h +++ b/src/main/io/piubtn/defs.h @@ -1,16 +1,16 @@ #ifndef PIUBTN_DRV_DEFS_H #define PIUBTN_DRV_DEFS_H -#define PIUBTN_DRV_VID 0x0D2F -#define PIUBTN_DRV_PID 0x1010 +#define PIUBTN_DRV_VID 0x0D2F +#define PIUBTN_DRV_PID 0x1010 -#define PIUBTN_DRV_CONFIG 0x01 -#define PIUBTN_DRV_IFACE 0x00 +#define PIUBTN_DRV_CONFIG 0x01 +#define PIUBTN_DRV_IFACE 0x00 -#define PIUBTN_DRV_USB_CTRL_TYPE_IN 0xC0 -#define PIUBTN_DRV_USB_CTRL_TYPE_OUT 0x40 -#define PIUBTN_DRV_USB_CTRL_REQUEST 0xAE -#define PIUBTN_DRV_USB_REQ_TIMEOUT 10000 +#define PIUBTN_DRV_USB_CTRL_TYPE_IN 0xC0 +#define PIUBTN_DRV_USB_CTRL_TYPE_OUT 0x40 +#define PIUBTN_DRV_USB_CTRL_REQUEST 0xAE +#define PIUBTN_DRV_USB_REQ_TIMEOUT 10000 #define PIUBTN_DRV_BUFFER_SIZE 8 diff --git a/src/main/io/piubtn/device.c b/src/main/io/piubtn/device.c index e0c8e95..ea26744 100644 --- a/src/main/io/piubtn/device.c +++ b/src/main/io/piubtn/device.c @@ -7,78 +7,90 @@ #include "defs.h" #include "device.h" -static void* piubtn_drv_device_handle; +static void *piubtn_drv_device_handle; bool piubtn_drv_device_open(void) { - if (piubtn_drv_device_handle) { - log_warn("Device already opened"); - return true; - } + if (piubtn_drv_device_handle) { + log_warn("Device already opened"); + return true; + } - piubtn_drv_device_handle = io_usb_open(PIUBTN_DRV_VID, PIUBTN_DRV_PID, - PIUBTN_DRV_CONFIG, PIUBTN_DRV_IFACE); + piubtn_drv_device_handle = io_usb_open( + PIUBTN_DRV_VID, PIUBTN_DRV_PID, PIUBTN_DRV_CONFIG, PIUBTN_DRV_IFACE); - return piubtn_drv_device_handle; + return piubtn_drv_device_handle; } -bool piubtn_drv_device_read(uint8_t* buffer, uint8_t len) +bool piubtn_drv_device_read(uint8_t *buffer, uint8_t len) { - int32_t res; + int32_t res; - if (!piubtn_drv_device_handle) { - log_error("Device not opened"); - return false; - } + if (!piubtn_drv_device_handle) { + log_error("Device not opened"); + return false; + } - if (len < PIUBTN_DRV_BUFFER_SIZE) { - log_error("Read failed, buffer (%d) too small", len); - return false; - } + if (len < PIUBTN_DRV_BUFFER_SIZE) { + log_error("Read failed, buffer (%d) too small", len); + return false; + } - res = io_usb_control_transfer(piubtn_drv_device_handle, - PIUBTN_DRV_USB_CTRL_TYPE_IN, PIUBTN_DRV_USB_CTRL_REQUEST, 0, 0, buffer, - PIUBTN_DRV_BUFFER_SIZE, PIUBTN_DRV_USB_REQ_TIMEOUT); + res = io_usb_control_transfer( + piubtn_drv_device_handle, + PIUBTN_DRV_USB_CTRL_TYPE_IN, + PIUBTN_DRV_USB_CTRL_REQUEST, + 0, + 0, + buffer, + PIUBTN_DRV_BUFFER_SIZE, + PIUBTN_DRV_USB_REQ_TIMEOUT); - if (res != PIUBTN_DRV_BUFFER_SIZE) { - log_error("Read failed: %d", res); - return false; - } + if (res != PIUBTN_DRV_BUFFER_SIZE) { + log_error("Read failed: %d", res); + return false; + } - return true; + return true; } -bool piubtn_drv_device_write(uint8_t* buffer, uint8_t len) +bool piubtn_drv_device_write(uint8_t *buffer, uint8_t len) { - int32_t res; + int32_t res; - if (!piubtn_drv_device_handle) { - log_error("Device not opened"); - return false; - } + if (!piubtn_drv_device_handle) { + log_error("Device not opened"); + return false; + } - if (len < PIUBTN_DRV_BUFFER_SIZE) { - log_error("Write failed, buffer (%d) too small", len); - return false; - } + if (len < PIUBTN_DRV_BUFFER_SIZE) { + log_error("Write failed, buffer (%d) too small", len); + return false; + } - res = io_usb_control_transfer(piubtn_drv_device_handle, - PIUBTN_DRV_USB_CTRL_TYPE_OUT, PIUBTN_DRV_USB_CTRL_REQUEST, 0, 0, buffer, - PIUBTN_DRV_BUFFER_SIZE, PIUBTN_DRV_USB_REQ_TIMEOUT); + res = io_usb_control_transfer( + piubtn_drv_device_handle, + PIUBTN_DRV_USB_CTRL_TYPE_OUT, + PIUBTN_DRV_USB_CTRL_REQUEST, + 0, + 0, + buffer, + PIUBTN_DRV_BUFFER_SIZE, + PIUBTN_DRV_USB_REQ_TIMEOUT); - if (res != PIUBTN_DRV_BUFFER_SIZE) { - log_error("Write failed: %d", res); - return false; - } + if (res != PIUBTN_DRV_BUFFER_SIZE) { + log_error("Write failed: %d", res); + return false; + } - return true; + return true; } void piubtn_drv_device_close(void) { - if (!piubtn_drv_device_handle) { - log_error("Device not opened"); - } + if (!piubtn_drv_device_handle) { + log_error("Device not opened"); + } - io_usb_close(piubtn_drv_device_handle); + io_usb_close(piubtn_drv_device_handle); } \ No newline at end of file diff --git a/src/main/io/piubtn/device.h b/src/main/io/piubtn/device.h index e2bc097..c03a420 100644 --- a/src/main/io/piubtn/device.h +++ b/src/main/io/piubtn/device.h @@ -22,7 +22,7 @@ bool piubtn_drv_device_open(void); * @param len Number of bytes to read * @return True if reading data to device was successful, false otherwise */ -bool piubtn_drv_device_read(uint8_t* buffer, uint8_t len); +bool piubtn_drv_device_read(uint8_t *buffer, uint8_t len); /** * Write raw data to the piubtn device @@ -31,7 +31,7 @@ bool piubtn_drv_device_read(uint8_t* buffer, uint8_t len); * @param len Number of bytes to write * @return True if writing data to device was successful, false otherwise */ -bool piubtn_drv_device_write(uint8_t* buffer, uint8_t len); +bool piubtn_drv_device_write(uint8_t *buffer, uint8_t len); /** * Close the opened piubtn device diff --git a/src/main/io/piuio/defs.h b/src/main/io/piuio/defs.h index dd3641a..aef9d72 100644 --- a/src/main/io/piuio/defs.h +++ b/src/main/io/piuio/defs.h @@ -1,16 +1,16 @@ #ifndef PIUIO_DRV_DEFS_H #define PIUIO_DRV_DEFS_H -#define PIUIO_DRV_VID 0x0547 -#define PIUIO_DRV_PID 0x1002 +#define PIUIO_DRV_VID 0x0547 +#define PIUIO_DRV_PID 0x1002 -#define PIUIO_DRV_CONFIG 0x01 -#define PIUIO_DRV_IFACE 0x00 +#define PIUIO_DRV_CONFIG 0x01 +#define PIUIO_DRV_IFACE 0x00 -#define PIUIO_DRV_USB_CTRL_TYPE_IN 0xC0 -#define PIUIO_DRV_USB_CTRL_TYPE_OUT 0x40 -#define PIUIO_DRV_USB_CTRL_REQUEST 0xAE -#define PIUIO_DRV_USB_REQ_TIMEOUT 10000 +#define PIUIO_DRV_USB_CTRL_TYPE_IN 0xC0 +#define PIUIO_DRV_USB_CTRL_TYPE_OUT 0x40 +#define PIUIO_DRV_USB_CTRL_REQUEST 0xAE +#define PIUIO_DRV_USB_REQ_TIMEOUT 10000 #define PIUIO_DRV_BUFFER_SIZE 8 diff --git a/src/main/io/piuio/device.c b/src/main/io/piuio/device.c index b1db8b5..02877f0 100644 --- a/src/main/io/piuio/device.c +++ b/src/main/io/piuio/device.c @@ -7,78 +7,90 @@ #include "defs.h" #include "device.h" -static void* piuio_drv_device_handle; +static void *piuio_drv_device_handle; bool piuio_drv_device_open(void) { - if (piuio_drv_device_handle) { - log_warn("Device already opened"); - return true; - } + if (piuio_drv_device_handle) { + log_warn("Device already opened"); + return true; + } - piuio_drv_device_handle = io_usb_open(PIUIO_DRV_VID, PIUIO_DRV_PID, - PIUIO_DRV_CONFIG, PIUIO_DRV_IFACE); + piuio_drv_device_handle = io_usb_open( + PIUIO_DRV_VID, PIUIO_DRV_PID, PIUIO_DRV_CONFIG, PIUIO_DRV_IFACE); - return piuio_drv_device_handle; + return piuio_drv_device_handle; } -bool piuio_drv_device_read(uint8_t* buffer, uint8_t len) +bool piuio_drv_device_read(uint8_t *buffer, uint8_t len) { - int32_t res; + int32_t res; - if (!piuio_drv_device_handle) { - log_error("Device not opened"); - return false; - } + if (!piuio_drv_device_handle) { + log_error("Device not opened"); + return false; + } - if (len < PIUIO_DRV_BUFFER_SIZE) { - log_error("Read failed, buffer (%d) too small", len); - return false; - } + if (len < PIUIO_DRV_BUFFER_SIZE) { + log_error("Read failed, buffer (%d) too small", len); + return false; + } - res = io_usb_control_transfer(piuio_drv_device_handle, - PIUIO_DRV_USB_CTRL_TYPE_IN, PIUIO_DRV_USB_CTRL_REQUEST, 0, 0, buffer, - PIUIO_DRV_BUFFER_SIZE, PIUIO_DRV_USB_REQ_TIMEOUT); + res = io_usb_control_transfer( + piuio_drv_device_handle, + PIUIO_DRV_USB_CTRL_TYPE_IN, + PIUIO_DRV_USB_CTRL_REQUEST, + 0, + 0, + buffer, + PIUIO_DRV_BUFFER_SIZE, + PIUIO_DRV_USB_REQ_TIMEOUT); - if (res != PIUIO_DRV_BUFFER_SIZE) { - log_error("Read failed: %d", res); - return false; - } + if (res != PIUIO_DRV_BUFFER_SIZE) { + log_error("Read failed: %d", res); + return false; + } - return true; + return true; } -bool piuio_drv_device_write(uint8_t* buffer, uint8_t len) +bool piuio_drv_device_write(uint8_t *buffer, uint8_t len) { - int32_t res; + int32_t res; - if (!piuio_drv_device_handle) { - log_error("Device not opened"); - return false; - } + if (!piuio_drv_device_handle) { + log_error("Device not opened"); + return false; + } - if (len < PIUIO_DRV_BUFFER_SIZE) { - log_error("Write failed, buffer (%d) too small", len); - return false; - } + if (len < PIUIO_DRV_BUFFER_SIZE) { + log_error("Write failed, buffer (%d) too small", len); + return false; + } - res = io_usb_control_transfer(piuio_drv_device_handle, - PIUIO_DRV_USB_CTRL_TYPE_OUT, PIUIO_DRV_USB_CTRL_REQUEST, 0, 0, buffer, - PIUIO_DRV_BUFFER_SIZE, PIUIO_DRV_USB_REQ_TIMEOUT); + res = io_usb_control_transfer( + piuio_drv_device_handle, + PIUIO_DRV_USB_CTRL_TYPE_OUT, + PIUIO_DRV_USB_CTRL_REQUEST, + 0, + 0, + buffer, + PIUIO_DRV_BUFFER_SIZE, + PIUIO_DRV_USB_REQ_TIMEOUT); - if (res != PIUIO_DRV_BUFFER_SIZE) { - log_error("Write failed: %d", res); - return false; - } + if (res != PIUIO_DRV_BUFFER_SIZE) { + log_error("Write failed: %d", res); + return false; + } - return true; + return true; } void piuio_drv_device_close(void) { - if (!piuio_drv_device_handle) { - log_error("Device not opened"); - } + if (!piuio_drv_device_handle) { + log_error("Device not opened"); + } - io_usb_close(piuio_drv_device_handle); + io_usb_close(piuio_drv_device_handle); } \ No newline at end of file diff --git a/src/main/io/piuio/device.h b/src/main/io/piuio/device.h index 82d7400..ebabee3 100644 --- a/src/main/io/piuio/device.h +++ b/src/main/io/piuio/device.h @@ -22,7 +22,7 @@ bool piuio_drv_device_open(void); * @param len Number of bytes to read * @return True if reading data to device was successful, false otherwise */ -bool piuio_drv_device_read(uint8_t* buffer, uint8_t len); +bool piuio_drv_device_read(uint8_t *buffer, uint8_t len); /** * Write raw data to the piuio device @@ -31,7 +31,7 @@ bool piuio_drv_device_read(uint8_t* buffer, uint8_t len); * @param len Number of bytes to write * @return True if writing data to device was successful, false otherwise */ -bool piuio_drv_device_write(uint8_t* buffer, uint8_t len); +bool piuio_drv_device_write(uint8_t *buffer, uint8_t len); /** * Close the opened piuio device diff --git a/src/main/io/util/joystick-util.c b/src/main/io/util/joystick-util.c index 74be37b..0165653 100644 --- a/src/main/io/util/joystick-util.c +++ b/src/main/io/util/joystick-util.c @@ -11,41 +11,46 @@ #include "util/fs.h" #include "util/log.h" -size_t io_util_joystick_util_scan(struct io_util_joystick_util_device_info* devices, size_t len) +size_t io_util_joystick_util_scan( + struct io_util_joystick_util_device_info *devices, size_t len) { - log_assert(devices); + log_assert(devices); - char dev_path[PATH_MAX]; - int handle; - size_t num_joysticks; + char dev_path[PATH_MAX]; + int handle; + size_t num_joysticks; - num_joysticks = 0; + num_joysticks = 0; - for (size_t i = 0; i < len; i++) { - sprintf(dev_path, "/dev/input/js%d", i); + for (size_t i = 0; i < len; i++) { + sprintf(dev_path, "/dev/input/js%d", i); - memset(&devices[num_joysticks], 0, sizeof(struct io_util_joystick_util_device_info)); + memset( + &devices[num_joysticks], + 0, + sizeof(struct io_util_joystick_util_device_info)); - if (util_fs_path_exists(dev_path)) { - // temporarily have to open the device - handle = open(dev_path, O_RDONLY | O_NONBLOCK); + if (util_fs_path_exists(dev_path)) { + // temporarily have to open the device + handle = open(dev_path, O_RDONLY | O_NONBLOCK); - if (handle == -1) { - log_error("Opening joystick device %s failed: %s", dev_path, strerror(errno)); - continue; - } + if (handle == -1) { + log_error( + "Opening joystick device %s failed: %s", dev_path, strerror(errno)); + continue; + } - strcpy(devices[num_joysticks].dev_path, dev_path); + strcpy(devices[num_joysticks].dev_path, dev_path); - ioctl(handle, JSIOCGAXES, &(devices[num_joysticks].num_axes)); - ioctl(handle, JSIOCGBUTTONS, &(devices[num_joysticks].num_buttons)); - ioctl(handle, JSIOCGNAME(JOYSTICK_NAME_LEN), devices[num_joysticks].name); + ioctl(handle, JSIOCGAXES, &(devices[num_joysticks].num_axes)); + ioctl(handle, JSIOCGBUTTONS, &(devices[num_joysticks].num_buttons)); + ioctl(handle, JSIOCGNAME(JOYSTICK_NAME_LEN), devices[num_joysticks].name); - close(handle); + close(handle); - num_joysticks++; - } + num_joysticks++; } + } - return num_joysticks; + return num_joysticks; } \ No newline at end of file diff --git a/src/main/io/util/joystick-util.h b/src/main/io/util/joystick-util.h index f9becfd..44f2224 100644 --- a/src/main/io/util/joystick-util.h +++ b/src/main/io/util/joystick-util.h @@ -1,20 +1,21 @@ #ifndef IO_UTIL_JOYSTICK_UTIL_H #define IO_UTIL_JOYSTICK_UTIL_H +#include #include #include #include -#include #define JOYSTICK_NAME_LEN 128 struct io_util_joystick_util_device_info { - char dev_path[PATH_MAX]; - uint16_t num_buttons; - uint16_t num_axes; - char name[JOYSTICK_NAME_LEN]; + char dev_path[PATH_MAX]; + uint16_t num_buttons; + uint16_t num_axes; + char name[JOYSTICK_NAME_LEN]; }; -size_t io_util_joystick_util_scan(struct io_util_joystick_util_device_info* devices, size_t len); +size_t io_util_joystick_util_scan( + struct io_util_joystick_util_device_info *devices, size_t len); #endif diff --git a/src/main/io/util/joystick.c b/src/main/io/util/joystick.c index 3dee804..4a03db5 100644 --- a/src/main/io/util/joystick.c +++ b/src/main/io/util/joystick.c @@ -13,109 +13,123 @@ #define MAX_NUM_EVENTS 64 -bool io_util_joystick_open(const char* dev_path, struct io_util_joystick** ctx) +bool io_util_joystick_open(const char *dev_path, struct io_util_joystick **ctx) { - log_assert(dev_path); - log_assert(ctx); + log_assert(dev_path); + log_assert(ctx); - int handle; + int handle; - handle = open(dev_path, O_RDONLY | O_NONBLOCK); + handle = open(dev_path, O_RDONLY | O_NONBLOCK); - if (handle == -1) { - log_error("Opening joystick device %s failed: %s", dev_path, strerror(errno)); + if (handle == -1) { + log_error( + "Opening joystick device %s failed: %s", dev_path, strerror(errno)); + return false; + } + + *ctx = util_xmalloc(sizeof(struct io_util_joystick)); + + strcpy((*ctx)->dev_path, dev_path); + (*ctx)->handle = handle; + + // Init values to avoid having ioctl return garbage + (*ctx)->num_buttons = 0; + (*ctx)->num_axes = 0; + memset((*ctx)->name, 0, sizeof(char) * JOYSTICK_NAME_LEN); + + // grab data + ioctl(handle, JSIOCGAXES, &((*ctx)->num_axes)); + ioctl(handle, JSIOCGBUTTONS, &((*ctx)->num_buttons)); + ioctl(handle, JSIOCGNAME(JOYSTICK_NAME_LEN), (*ctx)->name); + + (*ctx)->button_state = util_xmalloc(sizeof(uint8_t) * (*ctx)->num_buttons); + + log_debug( + "Opened joystick device %s, handle %p, num buttons %d, num axes %d, name " + "%s", + (*ctx)->dev_path, + (*ctx)->handle, + (*ctx)->num_buttons, + (*ctx)->num_axes, + (*ctx)->name); + + return true; +} + +bool io_util_joystick_close(struct io_util_joystick *ctx) +{ + log_assert(ctx); + + bool res; + + log_debug( + "Closing joystick device %s, handle %p", ctx->dev_path, ctx->handle); + + if (close(ctx->handle) != 0) { + log_error( + "Closing joystick device %s failed: %s", + ctx->dev_path, + strerror(errno)); + res = false; + } else { + res = true; + } + + free(ctx->button_state); + free(ctx); + + return res; +} + +bool io_util_joystick_update(struct io_util_joystick *ctx) +{ + log_assert(ctx); + + struct js_event jse[MAX_NUM_EVENTS]; + + int bytes = read(ctx->handle, jse, sizeof(struct js_event) * MAX_NUM_EVENTS); + + if (bytes < 0) { + switch (errno) { + // try again on next poll + case EAGAIN: + return true; + default: + log_error( + "Reading from joystick device failed: %s", + ctx->dev_path, + strerror(errno)); return false; } + } - *ctx = util_xmalloc(sizeof(struct io_util_joystick)); + // determine how many whole events we read + bytes /= sizeof(struct js_event); - strcpy((*ctx)->dev_path, dev_path); - (*ctx)->handle = handle; + // now iterate all events + for (int i = 0; i < bytes; i++) { + switch (jse[i].type & ~JS_EVENT_INIT) { + case JS_EVENT_BUTTON: + ctx->button_state[jse[i].number] = (bool) jse[i].value; + break; - // Init values to avoid having ioctl return garbage - (*ctx)->num_buttons = 0; - (*ctx)->num_axes = 0; - memset((*ctx)->name, 0, sizeof(char) * JOYSTICK_NAME_LEN); + default: + break; + } + } - // grab data - ioctl(handle, JSIOCGAXES, &((*ctx)->num_axes)); - ioctl(handle, JSIOCGBUTTONS, &((*ctx)->num_buttons)); - ioctl(handle, JSIOCGNAME(JOYSTICK_NAME_LEN), (*ctx)->name); - - (*ctx)->button_state = util_xmalloc(sizeof(uint8_t) * (*ctx)->num_buttons); - - log_debug("Opened joystick device %s, handle %p, num buttons %d, num axes %d, name %s", (*ctx)->dev_path, - (*ctx)->handle, (*ctx)->num_buttons, (*ctx)->num_axes, (*ctx)->name); - - return true; + return true; } -bool io_util_joystick_close(struct io_util_joystick* ctx) +bool io_util_joystick_is_button_pressed( + struct io_util_joystick *ctx, uint16_t button) { - log_assert(ctx); + log_assert(ctx); - bool res; + if (button >= ctx->num_buttons) { + return false; + } - log_debug("Closing joystick device %s, handle %p", ctx->dev_path, ctx->handle); - - if (close(ctx->handle) != 0) { - log_error("Closing joystick device %s failed: %s", ctx->dev_path, strerror(errno)); - res = false; - } else { - res = true; - } - - free(ctx->button_state); - free(ctx); - - return res; -} - -bool io_util_joystick_update(struct io_util_joystick* ctx) -{ - log_assert(ctx); - - struct js_event jse[MAX_NUM_EVENTS]; - - int bytes = read(ctx->handle, jse, sizeof(struct js_event) * MAX_NUM_EVENTS); - - if (bytes < 0) { - switch (errno) { - // try again on next poll - case EAGAIN: - return true; - default: - log_error("Reading from joystick device failed: %s", ctx->dev_path, strerror(errno)); - return false; - } - } - - // determine how many whole events we read - bytes /= sizeof(struct js_event); - - // now iterate all events - for (int i = 0; i < bytes; i++) { - switch (jse[i].type & ~JS_EVENT_INIT) { - case JS_EVENT_BUTTON: - ctx->button_state[jse[i].number] = (bool) jse[i].value; - break; - - default: - break; - } - } - - - return true; -} - -bool io_util_joystick_is_button_pressed(struct io_util_joystick* ctx, uint16_t button) -{ - log_assert(ctx); - - if (button >= ctx->num_buttons) { - return false; - } - - return ctx->button_state[button]; + return ctx->button_state[button]; } \ No newline at end of file diff --git a/src/main/io/util/joystick.h b/src/main/io/util/joystick.h index 88e3c3d..e5bb622 100644 --- a/src/main/io/util/joystick.h +++ b/src/main/io/util/joystick.h @@ -1,27 +1,28 @@ #ifndef IO_UTIL_JOYSTICK_H #define IO_UTIL_JOYSTICK_H +#include #include #include -#include #define JOYSTICK_NAME_LEN 128 struct io_util_joystick { - char dev_path[PATH_MAX]; - int handle; - uint16_t num_buttons; - uint16_t num_axes; - char name[JOYSTICK_NAME_LEN]; - bool* button_state; + char dev_path[PATH_MAX]; + int handle; + uint16_t num_buttons; + uint16_t num_axes; + char name[JOYSTICK_NAME_LEN]; + bool *button_state; }; -bool io_util_joystick_open(const char* dev_path, struct io_util_joystick** ctx); +bool io_util_joystick_open(const char *dev_path, struct io_util_joystick **ctx); -bool io_util_joystick_close(struct io_util_joystick* ctx); +bool io_util_joystick_close(struct io_util_joystick *ctx); -bool io_util_joystick_update(struct io_util_joystick* ctx); +bool io_util_joystick_update(struct io_util_joystick *ctx); -bool io_util_joystick_is_button_pressed(struct io_util_joystick* ctx, uint16_t button); +bool io_util_joystick_is_button_pressed( + struct io_util_joystick *ctx, uint16_t button); #endif diff --git a/src/main/io/util/usb.c b/src/main/io/util/usb.c index 3acf0fc..5e05753 100644 --- a/src/main/io/util/usb.c +++ b/src/main/io/util/usb.c @@ -7,165 +7,188 @@ #include "util/mem.h" struct usb_io_ctx { - struct libusb_context* ctx; - struct libusb_device_handle* dev; + struct libusb_context *ctx; + struct libusb_device_handle *dev; }; -static struct libusb_device_handle* io_usb_get_device_handle( - struct libusb_context* ctx, uint16_t vid, uint16_t pid) +static struct libusb_device_handle * +io_usb_get_device_handle(struct libusb_context *ctx, uint16_t vid, uint16_t pid) { - int ret; - struct libusb_device** dev_list; - struct libusb_device* device; - struct libusb_device_handle* handle; + int ret; + struct libusb_device **dev_list; + struct libusb_device *device; + struct libusb_device_handle *handle; - dev_list = NULL; - device = NULL; + dev_list = NULL; + device = NULL; - ssize_t num_dev = libusb_get_device_list(ctx, &dev_list); + ssize_t num_dev = libusb_get_device_list(ctx, &dev_list); - /* find device */ - for (ssize_t i = 0; i < num_dev; i++) { - struct libusb_device_descriptor dev_desc_tmp; - struct libusb_device* dev_tmp; + /* find device */ + for (ssize_t i = 0; i < num_dev; i++) { + struct libusb_device_descriptor dev_desc_tmp; + struct libusb_device *dev_tmp; - dev_tmp = dev_list[i]; + dev_tmp = dev_list[i]; - libusb_get_device_descriptor(dev_tmp, &dev_desc_tmp); + libusb_get_device_descriptor(dev_tmp, &dev_desc_tmp); - /* for handling multiple devices with the same pid and vid */ - /* + /* for handling multiple devices with the same pid and vid */ + /* device_id_tmp = ((libusb_get_bus_number(dev_tmp) << 8) | libusb_get_port_number(dev_tmp)); */ - if (dev_desc_tmp.idVendor == vid && dev_desc_tmp.idProduct == pid) { - device = dev_tmp; - break; - } - } + if (dev_desc_tmp.idVendor == vid && dev_desc_tmp.idProduct == pid) { + device = dev_tmp; + break; + } + } - /* not found */ - if (device == NULL) { - libusb_free_device_list(dev_list, 1); - log_error("Could not find device %04X:%04X", vid, pid); - return NULL; - } + /* not found */ + if (device == NULL) { + libusb_free_device_list(dev_list, 1); + log_error("Could not find device %04X:%04X", vid, pid); + return NULL; + } - ret = libusb_open(device, &handle); - if (ret != LIBUSB_SUCCESS) { - libusb_free_device_list(dev_list, 1); + ret = libusb_open(device, &handle); + if (ret != LIBUSB_SUCCESS) { + libusb_free_device_list(dev_list, 1); - log_error("Could not open device %04X:%04X: %s", vid, pid, - libusb_error_name(ret)); - return NULL; - } + log_error( + "Could not open device %04X:%04X: %s", + vid, + pid, + libusb_error_name(ret)); + return NULL; + } - libusb_free_device_list(dev_list, 1); + libusb_free_device_list(dev_list, 1); - return handle; + return handle; } -void* io_usb_open(uint16_t vid, uint16_t pid, uint16_t config, uint16_t iface) +void *io_usb_open(uint16_t vid, uint16_t pid, uint16_t config, uint16_t iface) { - int ret; - struct libusb_context* ctx; - struct libusb_device_handle* dev; - struct usb_io_ctx* handle; + int ret; + struct libusb_context *ctx; + struct libusb_device_handle *dev; + struct usb_io_ctx *handle; - log_debug("Opening %04X:%04X, config %d, iface %d", vid, pid, config, - iface); + log_debug("Opening %04X:%04X, config %d, iface %d", vid, pid, config, iface); - ret = libusb_init(&ctx); + ret = libusb_init(&ctx); - if (ret != LIBUSB_SUCCESS) { - log_error("(%04X:%04X) Initializing libusb context failed: %s", - vid, pid, libusb_error_name(ret)); - return NULL; - } + if (ret != LIBUSB_SUCCESS) { + log_error( + "(%04X:%04X) Initializing libusb context failed: %s", + vid, + pid, + libusb_error_name(ret)); + return NULL; + } - /* dont print any error messages to stderr, change this for debugging */ - // libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_NONE); + /* dont print any error messages to stderr, change this for debugging */ + // libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_NONE); - dev = io_usb_get_device_handle(ctx, vid, pid); + dev = io_usb_get_device_handle(ctx, vid, pid); - if (!dev) { - libusb_exit(ctx); - return NULL; - } + if (!dev) { + libusb_exit(ctx); + return NULL; + } - ret = libusb_set_configuration(dev, config); + ret = libusb_set_configuration(dev, config); + if (ret != LIBUSB_SUCCESS) { + libusb_close(dev); + libusb_exit(ctx); + + log_error( + "(%04X:%04X) Setting configuration failed", + vid, + pid, + libusb_error_name(ret)); + return NULL; + } + + /* check if the device is attached to the kernel, detach it first then */ + if (libusb_kernel_driver_active(dev, iface) == 1) { + ret = libusb_detach_kernel_driver(dev, iface); if (ret != LIBUSB_SUCCESS) { - libusb_close(dev); - libusb_exit(ctx); + libusb_close(dev); + libusb_exit(ctx); - log_error("(%04X:%04X) Setting configuration failed", vid, pid, - libusb_error_name(ret)); - return NULL; + log_error( + "(%04X:%04X) Detaching interface %d from kernel failed: %s", + vid, + pid, + iface, + libusb_error_name(ret)); + return NULL; } + } - /* check if the device is attached to the kernel, detach it first then */ - if (libusb_kernel_driver_active(dev, iface) == 1) { - ret = libusb_detach_kernel_driver(dev, iface); - if (ret != LIBUSB_SUCCESS) { - libusb_close(dev); - libusb_exit(ctx); + ret = libusb_claim_interface(dev, iface); - log_error( - "(%04X:%04X) Detaching interface %d from kernel failed: %s", - vid, pid, iface, libusb_error_name(ret)); - return NULL; - } - } + if (ret != LIBUSB_SUCCESS) { + libusb_close(dev); + libusb_exit(ctx); - ret = libusb_claim_interface(dev, iface); + log_error( + "(%04X:%04X) Claiming interface %d failed: %s", + vid, + pid, + iface, + libusb_error_name(ret)); + return NULL; + } - if (ret != LIBUSB_SUCCESS) { - libusb_close(dev); - libusb_exit(ctx); + handle = (struct usb_io_ctx *) util_xmalloc(sizeof(struct usb_io_ctx)); - log_error("(%04X:%04X) Claiming interface %d failed: %s", vid, pid, - iface, libusb_error_name(ret)); - return NULL; - } + handle->ctx = ctx; + handle->dev = dev; - handle = (struct usb_io_ctx*) util_xmalloc(sizeof(struct usb_io_ctx)); + log_debug("Opened %04X:%04X, handle %p", vid, pid, handle); - handle->ctx = ctx; - handle->dev = dev; - - log_debug("Opened %04X:%04X, handle %p", vid, pid, handle); - - return handle; + return handle; } -int32_t io_usb_control_transfer(void* handle, uint8_t request_type, - uint8_t request, uint16_t value, uint16_t index, uint8_t* data, - uint16_t len, uint32_t timeout) +int32_t io_usb_control_transfer( + void *handle, + uint8_t request_type, + uint8_t request, + uint16_t value, + uint16_t index, + uint8_t *data, + uint16_t len, + uint32_t timeout) { - struct usb_io_ctx* dev = (struct usb_io_ctx*) handle; - int32_t ret; + struct usb_io_ctx *dev = (struct usb_io_ctx *) handle; + int32_t ret; - ret = libusb_control_transfer(dev->dev, request_type, request, value, - index, data, len, timeout); + ret = libusb_control_transfer( + dev->dev, request_type, request, value, index, data, len, timeout); - if (ret != len) { - log_error("Control transfer, handle %p failed: %s", handle, - libusb_error_name(ret)); - } + if (ret != len) { + log_error( + "Control transfer, handle %p failed: %s", + handle, + libusb_error_name(ret)); + } - return ret; + return ret; } -void io_usb_close(void* handle) +void io_usb_close(void *handle) { - struct usb_io_ctx* dev = (struct usb_io_ctx*) handle; + struct usb_io_ctx *dev = (struct usb_io_ctx *) handle; - log_debug("Closing handle %p", handle); + log_debug("Closing handle %p", handle); - libusb_close(dev->dev); - libusb_exit(dev->ctx); + libusb_close(dev->dev); + libusb_exit(dev->ctx); - free(dev); + free(dev); } diff --git a/src/main/io/util/usb_.h b/src/main/io/util/usb_.h index ab032cf..a38f82a 100644 --- a/src/main/io/util/usb_.h +++ b/src/main/io/util/usb_.h @@ -16,7 +16,7 @@ * @param iface Interface to claim * @return On success, a handle to the opened device, NULL on failure */ -void* io_usb_open(uint16_t vid, uint16_t pid, uint16_t config, uint16_t iface); +void *io_usb_open(uint16_t vid, uint16_t pid, uint16_t config, uint16_t iface); /** * Execute a control transfer @@ -32,15 +32,21 @@ void* io_usb_open(uint16_t vid, uint16_t pid, uint16_t config, uint16_t iface); * @param timeout Timeout for the operation in ms * @return Number of bytes read/written or -1 on error */ -int32_t io_usb_control_transfer(void* handle, uint8_t request_type, - uint8_t request, uint16_t value, uint16_t index, uint8_t* data, - uint16_t len, uint32_t timeout); +int32_t io_usb_control_transfer( + void *handle, + uint8_t request_type, + uint8_t request, + uint16_t value, + uint16_t index, + uint8_t *data, + uint16_t len, + uint32_t timeout); /** * Close a opened usb device * * @param handle Handle of the opened device */ -void io_usb_close(void* handle); +void io_usb_close(void *handle); #endif \ No newline at end of file diff --git a/src/main/ptapi/io/piubtn/joystick-conf/main.c b/src/main/ptapi/io/piubtn/joystick-conf/main.c index 0e381c3..987094c 100644 --- a/src/main/ptapi/io/piubtn/joystick-conf/main.c +++ b/src/main/ptapi/io/piubtn/joystick-conf/main.c @@ -1,8 +1,8 @@ #include #include -#include "io/util/joystick.h" #include "io/util/joystick-util.h" +#include "io/util/joystick.h" #include "ptapi/io/piubtn/joystick-util/joystick-conf.h" @@ -16,240 +16,276 @@ int kbhit() { - struct timeval tv = { 0L, 0L }; + struct timeval tv = {0L, 0L}; - fd_set fds; - FD_ZERO(&fds); - FD_SET(0, &fds); + fd_set fds; + FD_ZERO(&fds); + FD_SET(0, &fds); - return select(1, &fds, NULL, NULL, &tv); + return select(1, &fds, NULL, NULL, &tv); } int getch() { - int r; - unsigned char c; + int r; + unsigned char c; - if ((r = read(0, &c, sizeof(c))) < 0) { - return r; - } else { - return c; - } + if ((r = read(0, &c, sizeof(c))) < 0) { + return r; + } else { + return c; + } } -static uint16_t joystick_get_next_input(struct io_util_joystick* joystick) +static uint16_t joystick_get_next_input(struct io_util_joystick *joystick) { - bool pressed; - uint16_t button; + bool pressed; + uint16_t button; - pressed = false; - button = 0; + pressed = false; + button = 0; - while (true) { - if (!io_util_joystick_update(joystick)) { - printf("Error updating joystick failed.\n"); - exit(-1); - } - - // Allow skip-able input assignment via enter key on keyboard - if (kbhit() > 0) { - if (getch() == '\n') { - return SKIP_INPUT; - } - } - - if (!pressed) { - for (uint16_t j = 0; j < joystick->num_buttons; j++) { - if (io_util_joystick_is_button_pressed(joystick, j)) { - button = j; - pressed = true; - break; - } - } - } else { - // Wait for release of pressed input -> debouncing - if (!io_util_joystick_is_button_pressed(joystick, button)) { - break; - } - } - - util_time_sleep_ms(10); + while (true) { + if (!io_util_joystick_update(joystick)) { + printf("Error updating joystick failed.\n"); + exit(-1); } - return button; + // Allow skip-able input assignment via enter key on keyboard + if (kbhit() > 0) { + if (getch() == '\n') { + return SKIP_INPUT; + } + } + + if (!pressed) { + for (uint16_t j = 0; j < joystick->num_buttons; j++) { + if (io_util_joystick_is_button_pressed(joystick, j)) { + button = j; + pressed = true; + break; + } + } + } else { + // Wait for release of pressed input -> debouncing + if (!io_util_joystick_is_button_pressed(joystick, button)) { + break; + } + } + + util_time_sleep_ms(10); + } + + return button; } static void menu_joystick_test() { - struct io_util_joystick_util_device_info dev_info[MAX_JOYSTICKS]; - size_t connected_joysticks; + struct io_util_joystick_util_device_info dev_info[MAX_JOYSTICKS]; + size_t connected_joysticks; - connected_joysticks = io_util_joystick_util_scan(dev_info, MAX_JOYSTICKS); + connected_joysticks = io_util_joystick_util_scan(dev_info, MAX_JOYSTICKS); - printf("Connected joysticks: %d\n", connected_joysticks); + printf("Connected joysticks: %d\n", connected_joysticks); - for (size_t i = 0; i < connected_joysticks; i++) { - printf("%d: %s -> %s, buttons %d, axes %d\n", - i, dev_info[i].name, dev_info[i].dev_path, dev_info[i].num_buttons, dev_info[i].num_axes); - } + for (size_t i = 0; i < connected_joysticks; i++) { + printf( + "%d: %s -> %s, buttons %d, axes %d\n", + i, + dev_info[i].name, + dev_info[i].dev_path, + dev_info[i].num_buttons, + dev_info[i].num_axes); + } - size_t selected_device_idx; + size_t selected_device_idx; - printf("Select device: "); - scanf("%d", &selected_device_idx); + printf("Select device: "); + scanf("%d", &selected_device_idx); - if (selected_device_idx > connected_joysticks) { - printf("Invalid device id %d, out of range\n", selected_device_idx); - return; - } + if (selected_device_idx > connected_joysticks) { + printf("Invalid device id %d, out of range\n", selected_device_idx); + return; + } - struct io_util_joystick* joystick; + struct io_util_joystick *joystick; - if (!io_util_joystick_open(dev_info[selected_device_idx].dev_path, &joystick)) { - printf("Error opening device %s -> %s", dev_info[selected_device_idx].name, - dev_info[selected_device_idx].dev_path); - return; - } + if (!io_util_joystick_open( + dev_info[selected_device_idx].dev_path, &joystick)) { + printf( + "Error opening device %s -> %s", + dev_info[selected_device_idx].name, + dev_info[selected_device_idx].dev_path); + return; + } - printf("Pressed + released inputs:\n"); + printf("Pressed + released inputs:\n"); - while (true) { - printf("%d\n", joystick_get_next_input(joystick)); - } + while (true) { + printf("%d\n", joystick_get_next_input(joystick)); + } - io_util_joystick_close(joystick); + io_util_joystick_close(joystick); } static void menu_joystick_map() { - struct ptapi_io_piubtn_joystick_util_conf* config; - struct ptapi_io_piubtn_joystick_util_conf_entry config_entry; + struct ptapi_io_piubtn_joystick_util_conf *config; + struct ptapi_io_piubtn_joystick_util_conf_entry config_entry; - struct io_util_joystick_util_device_info dev_info[MAX_JOYSTICKS]; - size_t connected_joysticks; - struct io_util_joystick* joystick; + struct io_util_joystick_util_device_info dev_info[MAX_JOYSTICKS]; + size_t connected_joysticks; + struct io_util_joystick *joystick; - connected_joysticks = io_util_joystick_util_scan(dev_info, MAX_JOYSTICKS); + connected_joysticks = io_util_joystick_util_scan(dev_info, MAX_JOYSTICKS); - printf("Connected joysticks: %d\n", connected_joysticks); + printf("Connected joysticks: %d\n", connected_joysticks); - for (size_t i = 0; i < connected_joysticks; i++) { - printf("%d: %s -> %s, buttons %d, axes %d\n", - i, dev_info[i].name, dev_info[i].dev_path, dev_info[i].num_buttons, dev_info[i].num_axes); - } + for (size_t i = 0; i < connected_joysticks; i++) { + printf( + "%d: %s -> %s, buttons %d, axes %d\n", + i, + dev_info[i].name, + dev_info[i].dev_path, + dev_info[i].num_buttons, + dev_info[i].num_axes); + } - size_t selected_device_idx; + size_t selected_device_idx; - printf("Select device: "); - scanf("%d", &selected_device_idx); + printf("Select device: "); + scanf("%d", &selected_device_idx); - if (selected_device_idx > connected_joysticks) { - printf("Invalid device id %d, out of range\n", selected_device_idx); - return; - } + if (selected_device_idx > connected_joysticks) { + printf("Invalid device id %d, out of range\n", selected_device_idx); + return; + } - if (!ptapi_io_piubtn_joystick_util_conf_read_from_file(&config, CONFIG_FILENAME)) { - printf("Reading existing config file failed, creating new\n"); + if (!ptapi_io_piubtn_joystick_util_conf_read_from_file( + &config, CONFIG_FILENAME)) { + printf("Reading existing config file failed, creating new\n"); - ptapi_io_piubtn_joystick_util_conf_new(&config); + ptapi_io_piubtn_joystick_util_conf_new(&config); - memset(&config_entry, 0, sizeof(struct ptapi_io_piubtn_joystick_util_conf_entry)); + memset( + &config_entry, + 0, + sizeof(struct ptapi_io_piubtn_joystick_util_conf_entry)); - strcpy(config_entry.dev_path, dev_info[selected_device_idx].dev_path); - strcpy(config_entry.name, dev_info[selected_device_idx].name); + strcpy(config_entry.dev_path, dev_info[selected_device_idx].dev_path); + strcpy(config_entry.name, dev_info[selected_device_idx].name); + } else { + if (!ptapi_io_piubtn_joystick_util_conf_find_entry( + config, + dev_info[selected_device_idx].name, + dev_info[selected_device_idx].dev_path, + &config_entry)) { + printf( + "Could not find existing mapping entry in config for joystick, " + "creating new one\n"); + + memset( + &config_entry, + 0, + sizeof(struct ptapi_io_piubtn_joystick_util_conf_entry)); + + strcpy(config_entry.dev_path, dev_info[selected_device_idx].dev_path); + strcpy(config_entry.name, dev_info[selected_device_idx].name); } else { - if (!ptapi_io_piubtn_joystick_util_conf_find_entry(config, dev_info[selected_device_idx].name, - dev_info[selected_device_idx].dev_path, &config_entry)) { - printf("Could not find existing mapping entry in config for joystick, creating new one\n"); - - memset(&config_entry, 0, sizeof(struct ptapi_io_piubtn_joystick_util_conf_entry)); - - strcpy(config_entry.dev_path, dev_info[selected_device_idx].dev_path); - strcpy(config_entry.name, dev_info[selected_device_idx].name); - } else { - printf("Found existing mapping entry in config for joystick, overwriting\n"); - } + printf( + "Found existing mapping entry in config for joystick, overwriting\n"); } + } - printf("Configuring device %s -> %s\n", dev_info[selected_device_idx].name, dev_info[selected_device_idx].dev_path); + printf( + "Configuring device %s -> %s\n", + dev_info[selected_device_idx].name, + dev_info[selected_device_idx].dev_path); - if (!io_util_joystick_open(dev_info[selected_device_idx].dev_path, &joystick)) { - printf("Error opening device %s -> %s", dev_info[selected_device_idx].name, - dev_info[selected_device_idx].dev_path); - return; - } - - for (uint32_t i = PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P1_LEFT; - i < PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_COUNT; - i++) { - printf("Press button to assign to \"%s\" or Enter/Return to skip: ", ptapi_io_piubtn_joystick_util_conf_input_str[i]); - fflush(stdout); - - config_entry.button_map[i] = joystick_get_next_input(joystick); - - if (config_entry.button_map[i] == SKIP_INPUT) { - printf("SKIP\n"); - } else { - printf("%d\n", config_entry.button_map[i]); - } - } - - io_util_joystick_close(joystick); - - printf("Configuration of device %s -> %s done\n", dev_info[selected_device_idx].name, + if (!io_util_joystick_open( + dev_info[selected_device_idx].dev_path, &joystick)) { + printf( + "Error opening device %s -> %s", + dev_info[selected_device_idx].name, dev_info[selected_device_idx].dev_path); + return; + } - if (!ptapi_io_piubtn_joystick_util_conf_set_entry(config, &config_entry)) { - ptapi_io_piubtn_joystick_util_conf_append_entry(&config, &config_entry); + for (uint32_t i = PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P1_LEFT; + i < PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_COUNT; + i++) { + printf( + "Press button to assign to \"%s\" or Enter/Return to skip: ", + ptapi_io_piubtn_joystick_util_conf_input_str[i]); + fflush(stdout); + + config_entry.button_map[i] = joystick_get_next_input(joystick); + + if (config_entry.button_map[i] == SKIP_INPUT) { + printf("SKIP\n"); + } else { + printf("%d\n", config_entry.button_map[i]); } + } - ptapi_io_piubtn_joystick_util_conf_write_to_file(config, CONFIG_FILENAME); + io_util_joystick_close(joystick); - free(config); + printf( + "Configuration of device %s -> %s done\n", + dev_info[selected_device_idx].name, + dev_info[selected_device_idx].dev_path); - printf("Configuration file saved: %s\n", CONFIG_FILENAME); + if (!ptapi_io_piubtn_joystick_util_conf_set_entry(config, &config_entry)) { + ptapi_io_piubtn_joystick_util_conf_append_entry(&config, &config_entry); + } + + ptapi_io_piubtn_joystick_util_conf_write_to_file(config, CONFIG_FILENAME); + + free(config); + + printf("Configuration file saved: %s\n", CONFIG_FILENAME); } -int main(int argc, char** argv) +int main(int argc, char **argv) { - bool main_loop; + bool main_loop; - util_log_set_file("joystick-conf.log", false); - util_log_set_level(LOG_LEVEL_ERROR); + util_log_set_file("joystick-conf.log", false); + util_log_set_level(LOG_LEVEL_ERROR); - printf("ptapi PIUBTN joystick button mapping config tool\n"); + printf("ptapi PIUBTN joystick button mapping config tool\n"); - main_loop = true; + main_loop = true; - while (main_loop) { - uint32_t item; + while (main_loop) { + uint32_t item; - printf("Main menu, please select:\n"); - printf("1 > Joystick input test\n"); - printf("2 > Configure joystick mappings\n"); - printf("3 > Exit\n"); - printf("Select number: "); + printf("Main menu, please select:\n"); + printf("1 > Joystick input test\n"); + printf("2 > Configure joystick mappings\n"); + printf("3 > Exit\n"); + printf("Select number: "); - scanf("%d", &item); + scanf("%d", &item); - switch (item) { - case 1: - menu_joystick_test(); - break; + switch (item) { + case 1: + menu_joystick_test(); + break; - case 2: - menu_joystick_map(); - break; + case 2: + menu_joystick_map(); + break; - case 3: - main_loop = false; - break; + case 3: + main_loop = false; + break; - default: - printf("Invalid item chosen: %d\n", item); - break; - } + default: + printf("Invalid item chosen: %d\n", item); + break; } + } - return 0; + return 0; } \ No newline at end of file diff --git a/src/main/ptapi/io/piubtn/joystick-util/joystick-conf.c b/src/main/ptapi/io/piubtn/joystick-util/joystick-conf.c index 4242c8a..ff059cf 100644 --- a/src/main/ptapi/io/piubtn/joystick-util/joystick-conf.c +++ b/src/main/ptapi/io/piubtn/joystick-util/joystick-conf.c @@ -4,96 +4,123 @@ #include "util/log.h" #include "util/mem.h" -const char* ptapi_io_piubtn_joystick_util_conf_input_str[PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_COUNT] = { - "invalid", - "P1 Left", - "P1 Right", - "P1 Start", - "P1 Back", - "P2 Left", - "P2 Right", - "P2 Start", - "P2 Back", +const char *ptapi_io_piubtn_joystick_util_conf_input_str + [PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_COUNT] = { + "invalid", + "P1 Left", + "P1 Right", + "P1 Start", + "P1 Back", + "P2 Left", + "P2 Right", + "P2 Start", + "P2 Back", }; -void ptapi_io_piubtn_joystick_util_conf_new(struct ptapi_io_piubtn_joystick_util_conf** conf) +void ptapi_io_piubtn_joystick_util_conf_new( + struct ptapi_io_piubtn_joystick_util_conf **conf) { - log_assert(conf); + log_assert(conf); - *conf = util_xmalloc(sizeof(struct ptapi_io_piubtn_joystick_util_conf)); - (*conf)->num_entries = 0; + *conf = util_xmalloc(sizeof(struct ptapi_io_piubtn_joystick_util_conf)); + (*conf)->num_entries = 0; } -bool ptapi_io_piubtn_joystick_util_conf_read_from_file(struct ptapi_io_piubtn_joystick_util_conf** conf, const char* path) +bool ptapi_io_piubtn_joystick_util_conf_read_from_file( + struct ptapi_io_piubtn_joystick_util_conf **conf, const char *path) { - log_assert(path); - log_assert(conf); + log_assert(path); + log_assert(conf); - void* buffer; - size_t size; - - if (!util_file_load(path, &buffer, &size, false)) { - return false; - } - - *conf = (struct ptapi_io_piubtn_joystick_util_conf*) buffer; - - return true; -} - -bool ptapi_io_piubtn_joystick_util_conf_write_to_file(struct ptapi_io_piubtn_joystick_util_conf* conf, const char* path) -{ - log_assert(path); - log_assert(conf); - - return util_file_save(path, conf, sizeof(struct ptapi_io_piubtn_joystick_util_conf) + - sizeof(struct ptapi_io_piubtn_joystick_util_conf_entry) * conf->num_entries); -} - -bool ptapi_io_piubtn_joystick_util_conf_set_entry(struct ptapi_io_piubtn_joystick_util_conf* conf, - struct ptapi_io_piubtn_joystick_util_conf_entry* entry) -{ - log_assert(conf); - log_assert(entry); - - for (size_t i = 0; i < conf->num_entries; i++) { - if (!strcmp(conf->entries[i].name, entry->name) && !strcmp(conf->entries[i].dev_path, entry->dev_path)) { - memcpy(&conf->entries[i], entry, sizeof(struct ptapi_io_piubtn_joystick_util_conf_entry)); - return true; - } - } + void *buffer; + size_t size; + if (!util_file_load(path, &buffer, &size, false)) { return false; + } + + *conf = (struct ptapi_io_piubtn_joystick_util_conf *) buffer; + + return true; } -void ptapi_io_piubtn_joystick_util_conf_append_entry(struct ptapi_io_piubtn_joystick_util_conf** conf, - struct ptapi_io_piubtn_joystick_util_conf_entry* entry) +bool ptapi_io_piubtn_joystick_util_conf_write_to_file( + struct ptapi_io_piubtn_joystick_util_conf *conf, const char *path) { - log_assert(conf); - log_assert(entry); + log_assert(path); + log_assert(conf); - (*conf)->num_entries++; + return util_file_save( + path, + conf, + sizeof(struct ptapi_io_piubtn_joystick_util_conf) + + sizeof(struct ptapi_io_piubtn_joystick_util_conf_entry) * + conf->num_entries); +} - *conf = util_xrealloc(*conf, sizeof(struct ptapi_io_piubtn_joystick_util_conf*) + - sizeof(struct ptapi_io_piubtn_joystick_util_conf_entry) * (*conf)->num_entries); +bool ptapi_io_piubtn_joystick_util_conf_set_entry( + struct ptapi_io_piubtn_joystick_util_conf *conf, + struct ptapi_io_piubtn_joystick_util_conf_entry *entry) +{ + log_assert(conf); + log_assert(entry); - memcpy(&(*conf)->entries[(*conf)->num_entries - 1], entry, sizeof(struct ptapi_io_piubtn_joystick_util_conf_entry)); + for (size_t i = 0; i < conf->num_entries; i++) { + if (!strcmp(conf->entries[i].name, entry->name) && + !strcmp(conf->entries[i].dev_path, entry->dev_path)) { + memcpy( + &conf->entries[i], + entry, + sizeof(struct ptapi_io_piubtn_joystick_util_conf_entry)); + return true; + } + } + + return false; +} + +void ptapi_io_piubtn_joystick_util_conf_append_entry( + struct ptapi_io_piubtn_joystick_util_conf **conf, + struct ptapi_io_piubtn_joystick_util_conf_entry *entry) +{ + log_assert(conf); + log_assert(entry); + + (*conf)->num_entries++; + + *conf = util_xrealloc( + *conf, + sizeof(struct ptapi_io_piubtn_joystick_util_conf *) + + sizeof(struct ptapi_io_piubtn_joystick_util_conf_entry) * + (*conf)->num_entries); + + memcpy( + &(*conf)->entries[(*conf)->num_entries - 1], + entry, + sizeof(struct ptapi_io_piubtn_joystick_util_conf_entry)); }; -bool ptapi_io_piubtn_joystick_util_conf_find_entry(struct ptapi_io_piubtn_joystick_util_conf* conf, const char* name, - const char* dev_path, struct ptapi_io_piubtn_joystick_util_conf_entry* entry) +bool ptapi_io_piubtn_joystick_util_conf_find_entry( + struct ptapi_io_piubtn_joystick_util_conf *conf, + const char *name, + const char *dev_path, + struct ptapi_io_piubtn_joystick_util_conf_entry *entry) { - log_assert(name); - log_assert(dev_path); - log_assert(entry); + log_assert(name); + log_assert(dev_path); + log_assert(entry); - for (size_t i = 0; i < conf->num_entries; i++) { - if (!strcmp(conf->entries[i].name, name) && !strcmp(conf->entries[i].dev_path, dev_path)) { - memcpy(entry, &conf->entries[i], sizeof(struct ptapi_io_piubtn_joystick_util_conf_entry)); + for (size_t i = 0; i < conf->num_entries; i++) { + if (!strcmp(conf->entries[i].name, name) && + !strcmp(conf->entries[i].dev_path, dev_path)) { + memcpy( + entry, + &conf->entries[i], + sizeof(struct ptapi_io_piubtn_joystick_util_conf_entry)); - return true; - } + return true; } + } - return false; + return false; } \ No newline at end of file diff --git a/src/main/ptapi/io/piubtn/joystick-util/joystick-conf.h b/src/main/ptapi/io/piubtn/joystick-util/joystick-conf.h index d27dbc7..0b2889a 100644 --- a/src/main/ptapi/io/piubtn/joystick-util/joystick-conf.h +++ b/src/main/ptapi/io/piubtn/joystick-util/joystick-conf.h @@ -6,45 +6,54 @@ #include "io/util/joystick.h" enum PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT { - PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_INVALID = 0, - PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P1_LEFT = 1, - PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P1_RIGHT = 2, - PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P1_START = 3, - PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P1_BACK = 4, - PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P2_LEFT = 5, - PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P2_RIGHT = 6, - PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P2_START = 7, - PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P2_BACK = 8, - PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_COUNT = 9, + PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_INVALID = 0, + PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P1_LEFT = 1, + PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P1_RIGHT = 2, + PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P1_START = 3, + PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P1_BACK = 4, + PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P2_LEFT = 5, + PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P2_RIGHT = 6, + PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P2_START = 7, + PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P2_BACK = 8, + PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_COUNT = 9, }; -extern const char* ptapi_io_piubtn_joystick_util_conf_input_str[PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_COUNT]; +extern const char *ptapi_io_piubtn_joystick_util_conf_input_str + [PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_COUNT]; struct ptapi_io_piubtn_joystick_util_conf_entry { - char name[JOYSTICK_NAME_LEN]; - char dev_path[PATH_MAX]; + char name[JOYSTICK_NAME_LEN]; + char dev_path[PATH_MAX]; - uint16_t button_map[PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_COUNT]; + uint16_t button_map[PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_COUNT]; }; struct ptapi_io_piubtn_joystick_util_conf { - size_t num_entries; - struct ptapi_io_piubtn_joystick_util_conf_entry entries[]; + size_t num_entries; + struct ptapi_io_piubtn_joystick_util_conf_entry entries[]; }; -void ptapi_io_piubtn_joystick_util_conf_new(struct ptapi_io_piubtn_joystick_util_conf** conf); +void ptapi_io_piubtn_joystick_util_conf_new( + struct ptapi_io_piubtn_joystick_util_conf **conf); -bool ptapi_io_piubtn_joystick_util_conf_read_from_file(struct ptapi_io_piubtn_joystick_util_conf** conf, const char* path); +bool ptapi_io_piubtn_joystick_util_conf_read_from_file( + struct ptapi_io_piubtn_joystick_util_conf **conf, const char *path); -bool ptapi_io_piubtn_joystick_util_conf_write_to_file(struct ptapi_io_piubtn_joystick_util_conf* conf, const char* path); +bool ptapi_io_piubtn_joystick_util_conf_write_to_file( + struct ptapi_io_piubtn_joystick_util_conf *conf, const char *path); -bool ptapi_io_piubtn_joystick_util_conf_set_entry(struct ptapi_io_piubtn_joystick_util_conf* conf, - struct ptapi_io_piubtn_joystick_util_conf_entry* entry); +bool ptapi_io_piubtn_joystick_util_conf_set_entry( + struct ptapi_io_piubtn_joystick_util_conf *conf, + struct ptapi_io_piubtn_joystick_util_conf_entry *entry); -void ptapi_io_piubtn_joystick_util_conf_append_entry(struct ptapi_io_piubtn_joystick_util_conf** conf, - struct ptapi_io_piubtn_joystick_util_conf_entry* entry); +void ptapi_io_piubtn_joystick_util_conf_append_entry( + struct ptapi_io_piubtn_joystick_util_conf **conf, + struct ptapi_io_piubtn_joystick_util_conf_entry *entry); -bool ptapi_io_piubtn_joystick_util_conf_find_entry(struct ptapi_io_piubtn_joystick_util_conf* conf, const char* name, - const char* dev_path, struct ptapi_io_piubtn_joystick_util_conf_entry* entry); +bool ptapi_io_piubtn_joystick_util_conf_find_entry( + struct ptapi_io_piubtn_joystick_util_conf *conf, + const char *name, + const char *dev_path, + struct ptapi_io_piubtn_joystick_util_conf_entry *entry); #endif diff --git a/src/main/ptapi/io/piubtn/joystick/joystick.c b/src/main/ptapi/io/piubtn/joystick/joystick.c index 12d09d3..045e717 100644 --- a/src/main/ptapi/io/piubtn/joystick/joystick.c +++ b/src/main/ptapi/io/piubtn/joystick/joystick.c @@ -18,157 +18,199 @@ #define CONFIG_FILENAME "/piubtn-joystick-conf.bin" struct ptapi_io_piubtn_joystick_with_conf { - struct ptapi_io_piubtn_joystick_util_conf_entry* conf; - struct io_util_joystick* joystick; + struct ptapi_io_piubtn_joystick_util_conf_entry *conf; + struct io_util_joystick *joystick; }; -static struct ptapi_io_piubtn_joystick_util_conf* ptapi_io_piubtn_joystick_util_conf; -static struct ptapi_io_piubtn_joystick_with_conf ptapi_io_piubtn_joysticks_with_conf[MAX_NUM_JOYSTICKS]; +static struct ptapi_io_piubtn_joystick_util_conf + *ptapi_io_piubtn_joystick_util_conf; +static struct ptapi_io_piubtn_joystick_with_conf + ptapi_io_piubtn_joysticks_with_conf[MAX_NUM_JOYSTICKS]; static size_t ptapi_io_piubtn_num_active_joysticks; -static bool ptapi_io_piubtn_merge_inputs(enum PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT input) +static bool ptapi_io_piubtn_merge_inputs( + enum PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT input) { - bool pressed; + bool pressed; - pressed = false; + pressed = false; - for (size_t i = 0; i < ptapi_io_piubtn_num_active_joysticks; i++) { - if (ptapi_io_piubtn_joysticks_with_conf[i].joystick) { - pressed = pressed || - io_util_joystick_is_button_pressed( - ptapi_io_piubtn_joysticks_with_conf[i].joystick, - ptapi_io_piubtn_joysticks_with_conf[i].conf->button_map[input]); - } + for (size_t i = 0; i < ptapi_io_piubtn_num_active_joysticks; i++) { + if (ptapi_io_piubtn_joysticks_with_conf[i].joystick) { + pressed = + pressed || + io_util_joystick_is_button_pressed( + ptapi_io_piubtn_joysticks_with_conf[i].joystick, + ptapi_io_piubtn_joysticks_with_conf[i].conf->button_map[input]); } + } - return pressed; + return pressed; } -const char* ptapi_io_piubtn_ident(void) +const char *ptapi_io_piubtn_ident(void) { - return "joystick"; + return "joystick"; } bool ptapi_io_piubtn_open() { - char path[PATH_MAX]; - char* config_path; - struct io_util_joystick_util_device_info device_info[MAX_NUM_JOYSTICKS]; - size_t devices_connected; + char path[PATH_MAX]; + char *config_path; + struct io_util_joystick_util_device_info device_info[MAX_NUM_JOYSTICKS]; + size_t devices_connected; - // The game changes the working directory to the 'game' sub-folder. Therefore, ./my-config does not work here. - if (!util_proc_get_folder_path_executable_no_ld_linux(path, sizeof(path))) { - log_error("Getting executable folder path failed."); - return false; - } + // The game changes the working directory to the 'game' sub-folder. Therefore, + // ./my-config does not work here. + if (!util_proc_get_folder_path_executable_no_ld_linux(path, sizeof(path))) { + log_error("Getting executable folder path failed."); + return false; + } - config_path = util_str_merge(path, CONFIG_FILENAME); - - if (!ptapi_io_piubtn_joystick_util_conf_read_from_file(&ptapi_io_piubtn_joystick_util_conf, config_path)) { - log_error("Loading joystick config file %s failed.", CONFIG_FILENAME); - free(config_path); - return false; - } + config_path = util_str_merge(path, CONFIG_FILENAME); + if (!ptapi_io_piubtn_joystick_util_conf_read_from_file( + &ptapi_io_piubtn_joystick_util_conf, config_path)) { + log_error("Loading joystick config file %s failed.", CONFIG_FILENAME); free(config_path); + return false; + } - devices_connected = io_util_joystick_util_scan(device_info, MAX_NUM_JOYSTICKS); + free(config_path); - log_debug("Found connected joysticks: %d", devices_connected); + devices_connected = + io_util_joystick_util_scan(device_info, MAX_NUM_JOYSTICKS); - ptapi_io_piubtn_num_active_joysticks = 0; + log_debug("Found connected joysticks: %d", devices_connected); - memset(ptapi_io_piubtn_joysticks_with_conf, 0, sizeof(struct ptapi_io_piubtn_joystick_with_conf) * MAX_NUM_JOYSTICKS); + ptapi_io_piubtn_num_active_joysticks = 0; - for (size_t i = 0; i < devices_connected; i++) { - log_debug("%d: %s -> %s, buttons %d, axes %d\n", - i, device_info[i].name, device_info[i].dev_path, device_info[i].num_buttons, device_info[i].num_axes); + memset( + ptapi_io_piubtn_joysticks_with_conf, + 0, + sizeof(struct ptapi_io_piubtn_joystick_with_conf) * MAX_NUM_JOYSTICKS); - // Find a matching configuration - for (size_t j = 0; j < ptapi_io_piubtn_joystick_util_conf->num_entries; j++) { + for (size_t i = 0; i < devices_connected; i++) { + log_debug( + "%d: %s -> %s, buttons %d, axes %d\n", + i, + device_info[i].name, + device_info[i].dev_path, + device_info[i].num_buttons, + device_info[i].num_axes); - if (!strcmp(ptapi_io_piubtn_joystick_util_conf->entries[j].name, device_info[i].name) && - !strcmp(ptapi_io_piubtn_joystick_util_conf->entries[j].dev_path, device_info[i].dev_path)) { - log_debug("Found matching configuration for %s -> %s", device_info[i].name, device_info[i].dev_path); + // Find a matching configuration + for (size_t j = 0; j < ptapi_io_piubtn_joystick_util_conf->num_entries; + j++) { - ptapi_io_piubtn_joysticks_with_conf[ptapi_io_piubtn_num_active_joysticks].conf = - &ptapi_io_piubtn_joystick_util_conf->entries[j]; - ptapi_io_piubtn_num_active_joysticks++; - } - } + if (!strcmp( + ptapi_io_piubtn_joystick_util_conf->entries[j].name, + device_info[i].name) && + !strcmp( + ptapi_io_piubtn_joystick_util_conf->entries[j].dev_path, + device_info[i].dev_path)) { + log_debug( + "Found matching configuration for %s -> %s", + device_info[i].name, + device_info[i].dev_path); + + ptapi_io_piubtn_joysticks_with_conf + [ptapi_io_piubtn_num_active_joysticks] + .conf = &ptapi_io_piubtn_joystick_util_conf->entries[j]; + ptapi_io_piubtn_num_active_joysticks++; + } } + } - // Open all joysticks with a matching configuration + // Open all joysticks with a matching configuration - log_debug("Opening %d joysticks...", ptapi_io_piubtn_num_active_joysticks); + log_debug("Opening %d joysticks...", ptapi_io_piubtn_num_active_joysticks); - for (size_t i = 0; i < ptapi_io_piubtn_num_active_joysticks; i++) { + for (size_t i = 0; i < ptapi_io_piubtn_num_active_joysticks; i++) { - if (!io_util_joystick_open(ptapi_io_piubtn_joysticks_with_conf[i].conf->dev_path, - &ptapi_io_piubtn_joysticks_with_conf[i].joystick)) { - log_warn("Could not open joystick %s -> %s, ignoring", ptapi_io_piubtn_joysticks_with_conf[i].conf->name, - ptapi_io_piubtn_joysticks_with_conf[i].conf->dev_path); - } else { - log_info("Opened joystick %s -> %s", ptapi_io_piubtn_joysticks_with_conf[i].conf->name, - ptapi_io_piubtn_joysticks_with_conf[i].conf->dev_path); - } + if (!io_util_joystick_open( + ptapi_io_piubtn_joysticks_with_conf[i].conf->dev_path, + &ptapi_io_piubtn_joysticks_with_conf[i].joystick)) { + log_warn( + "Could not open joystick %s -> %s, ignoring", + ptapi_io_piubtn_joysticks_with_conf[i].conf->name, + ptapi_io_piubtn_joysticks_with_conf[i].conf->dev_path); + } else { + log_info( + "Opened joystick %s -> %s", + ptapi_io_piubtn_joysticks_with_conf[i].conf->name, + ptapi_io_piubtn_joysticks_with_conf[i].conf->dev_path); } + } - return true; + return true; } void ptapi_io_piubtn_close(void) { - free(ptapi_io_piubtn_joystick_util_conf); + free(ptapi_io_piubtn_joystick_util_conf); - for (size_t i = 0; i < ptapi_io_piubtn_num_active_joysticks; i++) { - if (ptapi_io_piubtn_joysticks_with_conf[i].joystick) { - io_util_joystick_close(ptapi_io_piubtn_joysticks_with_conf[i].joystick); - } + for (size_t i = 0; i < ptapi_io_piubtn_num_active_joysticks; i++) { + if (ptapi_io_piubtn_joysticks_with_conf[i].joystick) { + io_util_joystick_close(ptapi_io_piubtn_joysticks_with_conf[i].joystick); } + } } bool ptapi_io_piubtn_recv(void) { - bool success; + bool success; - success = true; + success = true; - for (size_t i = 0; i < ptapi_io_piubtn_num_active_joysticks; i++) { - if (ptapi_io_piubtn_joysticks_with_conf[i].joystick) { - success = io_util_joystick_update(ptapi_io_piubtn_joysticks_with_conf[i].joystick); + for (size_t i = 0; i < ptapi_io_piubtn_num_active_joysticks; i++) { + if (ptapi_io_piubtn_joysticks_with_conf[i].joystick) { + success = io_util_joystick_update( + ptapi_io_piubtn_joysticks_with_conf[i].joystick); - if (!success) { - log_error("Updating joystick %s -> %s failed", ptapi_io_piubtn_joysticks_with_conf[i].conf->name, - ptapi_io_piubtn_joysticks_with_conf[i].conf->dev_path); - } - } + if (!success) { + log_error( + "Updating joystick %s -> %s failed", + ptapi_io_piubtn_joysticks_with_conf[i].conf->name, + ptapi_io_piubtn_joysticks_with_conf[i].conf->dev_path); + } } + } - return success; + return success; } bool ptapi_io_piubtn_send(void) { - return true; + return true; } -void ptapi_io_piubtn_get_input(uint8_t player, struct ptapi_io_piubtn_inputs* inputs) +void ptapi_io_piubtn_get_input( + uint8_t player, struct ptapi_io_piubtn_inputs *inputs) { - if (player == 0) { - inputs->start = ptapi_io_piubtn_merge_inputs(PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P1_START); - inputs->back = ptapi_io_piubtn_merge_inputs(PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P1_BACK); - inputs->left = ptapi_io_piubtn_merge_inputs(PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P1_LEFT); - inputs->right = ptapi_io_piubtn_merge_inputs(PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P1_RIGHT); - } else { - inputs->start = ptapi_io_piubtn_merge_inputs(PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P2_START); - inputs->back = ptapi_io_piubtn_merge_inputs(PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P2_BACK); - inputs->left = ptapi_io_piubtn_merge_inputs(PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P2_LEFT); - inputs->right = ptapi_io_piubtn_merge_inputs(PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P2_RIGHT); - } + if (player == 0) { + inputs->start = ptapi_io_piubtn_merge_inputs( + PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P1_START); + inputs->back = ptapi_io_piubtn_merge_inputs( + PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P1_BACK); + inputs->left = ptapi_io_piubtn_merge_inputs( + PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P1_LEFT); + inputs->right = ptapi_io_piubtn_merge_inputs( + PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P1_RIGHT); + } else { + inputs->start = ptapi_io_piubtn_merge_inputs( + PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P2_START); + inputs->back = ptapi_io_piubtn_merge_inputs( + PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P2_BACK); + inputs->left = ptapi_io_piubtn_merge_inputs( + PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P2_LEFT); + inputs->right = ptapi_io_piubtn_merge_inputs( + PTAPI_IO_PIUBTN_JOYSTICK_UTIL_CONF_INPUT_P2_RIGHT); + } } -void ptapi_io_piubtn_set_output(uint8_t player, const struct ptapi_io_piubtn_outputs* outputs) +void ptapi_io_piubtn_set_output( + uint8_t player, const struct ptapi_io_piubtn_outputs *outputs) { - /* Not supported */ + /* Not supported */ } \ No newline at end of file diff --git a/src/main/ptapi/io/piubtn/keyboard-conf/main.c b/src/main/ptapi/io/piubtn/keyboard-conf/main.c index 5daeb98..f1cb534 100644 --- a/src/main/ptapi/io/piubtn/keyboard-conf/main.c +++ b/src/main/ptapi/io/piubtn/keyboard-conf/main.c @@ -11,132 +11,147 @@ #define CONFIG_FILENAME "piubtn-keyboard-conf.bin" -static Display* display; +static Display *display; static Window window; static uint32_t keyboard_get_next_input() { - XEvent event; - KeySym key; + XEvent event; + KeySym key; - key = 0; + key = 0; - while (true) { - XNextEvent(display, &event); + while (true) { + XNextEvent(display, &event); - if (event.type == KeyPress) { - XLookupString(&event.xkey, 0, 0, &key, 0); - } else if (event.type == KeyRelease) { - break; - } + if (event.type == KeyPress) { + XLookupString(&event.xkey, 0, 0, &key, 0); + } else if (event.type == KeyRelease) { + break; } + } - return key; + return key; } static void menu_keyboard_test() { - printf("Pressed + released inputs:\n"); + printf("Pressed + released inputs:\n"); - while (true) { - printf("%d\n", keyboard_get_next_input()); - } + while (true) { + printf("%d\n", keyboard_get_next_input()); + } } static void menu_keyboard_map() { - struct ptapi_io_piubtn_keyboard_util_conf* config; + struct ptapi_io_piubtn_keyboard_util_conf *config; - if (!ptapi_io_piubtn_keyboard_util_conf_read_from_file(&config, CONFIG_FILENAME)) { - printf("Reading existing config file failed, creating new\n"); + if (!ptapi_io_piubtn_keyboard_util_conf_read_from_file( + &config, CONFIG_FILENAME)) { + printf("Reading existing config file failed, creating new\n"); - ptapi_io_piubtn_keyboard_util_conf_new(&config); - } else { - printf("Found existing mapping entry in config for keyboard, overwriting\n"); - } + ptapi_io_piubtn_keyboard_util_conf_new(&config); + } else { + printf( + "Found existing mapping entry in config for keyboard, overwriting\n"); + } - printf("A new window with no contents/white background is opened. Ensure to have the application focus on that " - "window to allow input capturing. Otherwise, the tool cannot capture any keyboard inputs!\n"); + printf( + "A new window with no contents/white background is opened. Ensure to " + "have the application focus on that " + "window to allow input capturing. Otherwise, the tool cannot capture any " + "keyboard inputs!\n"); - // Delay a moment to avoid picking up any previous keyboard inputs - util_time_sleep_ms(500); + // Delay a moment to avoid picking up any previous keyboard inputs + util_time_sleep_ms(500); - for (uint32_t i = PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P1_LEFT; - i < PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_COUNT; - i++) { - printf("Press button to assign to \"%s\": ", ptapi_io_piubtn_keyboard_util_conf_input_str[i]); - fflush(stdout); + for (uint32_t i = PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P1_LEFT; + i < PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_COUNT; + i++) { + printf( + "Press button to assign to \"%s\": ", + ptapi_io_piubtn_keyboard_util_conf_input_str[i]); + fflush(stdout); - config->button_map[i] = keyboard_get_next_input(); + config->button_map[i] = keyboard_get_next_input(); - printf("%d\n", config->button_map[i]); - } + printf("%d\n", config->button_map[i]); + } - ptapi_io_piubtn_keyboard_util_conf_write_to_file(config, CONFIG_FILENAME); + ptapi_io_piubtn_keyboard_util_conf_write_to_file(config, CONFIG_FILENAME); - free(config); + free(config); - printf("Configuration file saved: %s\n", CONFIG_FILENAME); + printf("Configuration file saved: %s\n", CONFIG_FILENAME); } -int main(int argc, char** argv) +int main(int argc, char **argv) { - bool main_loop; - int screen; + bool main_loop; + int screen; - util_log_set_file("keyboard-conf.log", false); - util_log_set_level(LOG_LEVEL_ERROR); + util_log_set_file("keyboard-conf.log", false); + util_log_set_level(LOG_LEVEL_ERROR); - display = XOpenDisplay(NULL); + display = XOpenDisplay(NULL); - if (!display) { - printf("Opening display failed\n"); - return -1; + if (!display) { + printf("Opening display failed\n"); + return -1; + } + + screen = DefaultScreen(display); + + window = XCreateSimpleWindow( + display, + RootWindow(display, screen), + 10, + 10, + 200, + 200, + 1, + BlackPixel(display, screen), + WhitePixel(display, screen)); + + XSelectInput(display, window, KeyPressMask | KeyReleaseMask); + XMapWindow(display, window); + + printf("ptapi PIUBTN keyboard button mapping config tool\n"); + + main_loop = true; + + while (main_loop) { + uint32_t item; + + printf("Main menu, please select:\n"); + printf("1 > Keyboard input test\n"); + printf("2 > Configure keyboard mappings\n"); + printf("3 > Exit\n"); + printf("Select number: "); + + scanf("%d", &item); + + switch (item) { + case 1: + menu_keyboard_test(); + break; + + case 2: + menu_keyboard_map(); + break; + + case 3: + main_loop = false; + break; + + default: + printf("Invalid item chosen: %d\n", item); + break; } + } - screen = DefaultScreen(display); + XCloseDisplay(display); - window = XCreateSimpleWindow(display, RootWindow(display, screen), 10, 10, 200, 200, 1, - BlackPixel(display, screen), WhitePixel(display, screen)); - - XSelectInput(display, window, KeyPressMask | KeyReleaseMask); - XMapWindow(display, window); - - printf("ptapi PIUBTN keyboard button mapping config tool\n"); - - main_loop = true; - - while (main_loop) { - uint32_t item; - - printf("Main menu, please select:\n"); - printf("1 > Keyboard input test\n"); - printf("2 > Configure keyboard mappings\n"); - printf("3 > Exit\n"); - printf("Select number: "); - - scanf("%d", &item); - - switch (item) { - case 1: - menu_keyboard_test(); - break; - - case 2: - menu_keyboard_map(); - break; - - case 3: - main_loop = false; - break; - - default: - printf("Invalid item chosen: %d\n", item); - break; - } - } - - XCloseDisplay(display); - - return 0; + return 0; } \ No newline at end of file diff --git a/src/main/ptapi/io/piubtn/keyboard-util/keyboard-conf.c b/src/main/ptapi/io/piubtn/keyboard-util/keyboard-conf.c index a67bcf5..fa471af 100644 --- a/src/main/ptapi/io/piubtn/keyboard-util/keyboard-conf.c +++ b/src/main/ptapi/io/piubtn/keyboard-util/keyboard-conf.c @@ -4,47 +4,52 @@ #include "util/log.h" #include "util/mem.h" -const char* ptapi_io_piubtn_keyboard_util_conf_input_str[PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_COUNT] = { - "invalid", - "P1 Left", - "P1 Right", - "P1 Start", - "P1 Back", - "P2 Left", - "P2 Right", - "P2 Start", - "P2 Back", +const char *ptapi_io_piubtn_keyboard_util_conf_input_str + [PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_COUNT] = { + "invalid", + "P1 Left", + "P1 Right", + "P1 Start", + "P1 Back", + "P2 Left", + "P2 Right", + "P2 Start", + "P2 Back", }; -void ptapi_io_piubtn_keyboard_util_conf_new(struct ptapi_io_piubtn_keyboard_util_conf** conf) +void ptapi_io_piubtn_keyboard_util_conf_new( + struct ptapi_io_piubtn_keyboard_util_conf **conf) { - log_assert(conf); + log_assert(conf); - *conf = util_xmalloc(sizeof(struct ptapi_io_piubtn_keyboard_util_conf)); - memset(*conf, 0, sizeof(struct ptapi_io_piubtn_keyboard_util_conf)); + *conf = util_xmalloc(sizeof(struct ptapi_io_piubtn_keyboard_util_conf)); + memset(*conf, 0, sizeof(struct ptapi_io_piubtn_keyboard_util_conf)); } -bool ptapi_io_piubtn_keyboard_util_conf_read_from_file(struct ptapi_io_piubtn_keyboard_util_conf** conf, const char* path) +bool ptapi_io_piubtn_keyboard_util_conf_read_from_file( + struct ptapi_io_piubtn_keyboard_util_conf **conf, const char *path) { - log_assert(path); - log_assert(conf); + log_assert(path); + log_assert(conf); - void* buffer; - size_t size; + void *buffer; + size_t size; - if (!util_file_load(path, &buffer, &size, false)) { - return false; - } + if (!util_file_load(path, &buffer, &size, false)) { + return false; + } - *conf = (struct ptapi_io_piubtn_keyboard_util_conf*) buffer; + *conf = (struct ptapi_io_piubtn_keyboard_util_conf *) buffer; - return true; + return true; } -bool ptapi_io_piubtn_keyboard_util_conf_write_to_file(struct ptapi_io_piubtn_keyboard_util_conf* conf, const char* path) +bool ptapi_io_piubtn_keyboard_util_conf_write_to_file( + struct ptapi_io_piubtn_keyboard_util_conf *conf, const char *path) { - log_assert(path); - log_assert(conf); + log_assert(path); + log_assert(conf); - return util_file_save(path, conf, sizeof(struct ptapi_io_piubtn_keyboard_util_conf)); + return util_file_save( + path, conf, sizeof(struct ptapi_io_piubtn_keyboard_util_conf)); } \ No newline at end of file diff --git a/src/main/ptapi/io/piubtn/keyboard-util/keyboard-conf.h b/src/main/ptapi/io/piubtn/keyboard-util/keyboard-conf.h index 65ab31c..69ce14e 100644 --- a/src/main/ptapi/io/piubtn/keyboard-util/keyboard-conf.h +++ b/src/main/ptapi/io/piubtn/keyboard-util/keyboard-conf.h @@ -6,28 +6,32 @@ #include "io/util/joystick.h" enum PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT { - PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_INVALID = 0, - PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P1_LEFT = 1, - PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P1_RIGHT = 2, - PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P1_START = 3, - PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P1_BACK = 4, - PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P2_LEFT = 5, - PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P2_RIGHT = 6, - PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P2_START = 7, - PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P2_BACK = 8, - PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_COUNT = 9, + PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_INVALID = 0, + PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P1_LEFT = 1, + PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P1_RIGHT = 2, + PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P1_START = 3, + PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P1_BACK = 4, + PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P2_LEFT = 5, + PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P2_RIGHT = 6, + PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P2_START = 7, + PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P2_BACK = 8, + PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_COUNT = 9, }; -extern const char* ptapi_io_piubtn_keyboard_util_conf_input_str[PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_COUNT]; +extern const char *ptapi_io_piubtn_keyboard_util_conf_input_str + [PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_COUNT]; struct ptapi_io_piubtn_keyboard_util_conf { - uint32_t button_map[PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_COUNT]; + uint32_t button_map[PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_COUNT]; }; -void ptapi_io_piubtn_keyboard_util_conf_new(struct ptapi_io_piubtn_keyboard_util_conf** conf); +void ptapi_io_piubtn_keyboard_util_conf_new( + struct ptapi_io_piubtn_keyboard_util_conf **conf); -bool ptapi_io_piubtn_keyboard_util_conf_read_from_file(struct ptapi_io_piubtn_keyboard_util_conf** conf, const char* path); +bool ptapi_io_piubtn_keyboard_util_conf_read_from_file( + struct ptapi_io_piubtn_keyboard_util_conf **conf, const char *path); -bool ptapi_io_piubtn_keyboard_util_conf_write_to_file(struct ptapi_io_piubtn_keyboard_util_conf* conf, const char* path); +bool ptapi_io_piubtn_keyboard_util_conf_write_to_file( + struct ptapi_io_piubtn_keyboard_util_conf *conf, const char *path); #endif diff --git a/src/main/ptapi/io/piubtn/keyboard/keyboard.c b/src/main/ptapi/io/piubtn/keyboard/keyboard.c index 5a6a4c4..8e251f8 100644 --- a/src/main/ptapi/io/piubtn/keyboard/keyboard.c +++ b/src/main/ptapi/io/piubtn/keyboard/keyboard.c @@ -19,108 +19,122 @@ #define CONFIG_FILENAME "/piubtn-keyboard-conf.bin" #define KEY_MAP_SIZE 0xFFFF -struct ptapi_io_piubtn_keyboard_util_conf* ptapi_io_piubtn_keyboard_conf; +struct ptapi_io_piubtn_keyboard_util_conf *ptapi_io_piubtn_keyboard_conf; static bool ptapi_io_piubtn_keyboard_buffer[KEY_MAP_SIZE]; static void _piubtn_emu_keyboard_dispatch_key_press(KeySym key); static void _piubtn_emu_keyboard_dispatch_key_release(KeySym key); -static const struct ptapi_io_x11_input_hook_handler _piubtn_emu_keyboard_input_hook_handler = { - .dispatch_key_press = _piubtn_emu_keyboard_dispatch_key_press, - .dispatch_key_release = _piubtn_emu_keyboard_dispatch_key_release, +static const struct ptapi_io_x11_input_hook_handler + _piubtn_emu_keyboard_input_hook_handler = { + .dispatch_key_press = _piubtn_emu_keyboard_dispatch_key_press, + .dispatch_key_release = _piubtn_emu_keyboard_dispatch_key_release, }; -const char* ptapi_io_piubtn_ident(void) +const char *ptapi_io_piubtn_ident(void) { - return "keyboard"; + return "keyboard"; } -const struct ptapi_io_x11_input_hook_handler* ptapi_io_x11_input_handler_hook(void) +const struct ptapi_io_x11_input_hook_handler * +ptapi_io_x11_input_handler_hook(void) { - return &_piubtn_emu_keyboard_input_hook_handler; + return &_piubtn_emu_keyboard_input_hook_handler; } bool ptapi_io_piubtn_open() { - char path[PATH_MAX]; - char* config_path; + char path[PATH_MAX]; + char *config_path; - // The game changes the working directory to the 'game' sub-folder. Therefore, ./my-config does not work here. - if (!util_proc_get_folder_path_executable_no_ld_linux(path, sizeof(path))) { - log_error("Getting executable folder path failed."); - return false; - } + // The game changes the working directory to the 'game' sub-folder. Therefore, + // ./my-config does not work here. + if (!util_proc_get_folder_path_executable_no_ld_linux(path, sizeof(path))) { + log_error("Getting executable folder path failed."); + return false; + } - config_path = util_str_merge(path, CONFIG_FILENAME); - - if (!ptapi_io_piubtn_keyboard_util_conf_read_from_file(&ptapi_io_piubtn_keyboard_conf, config_path)) { - log_error("Loading keyboard config file %s failed.", config_path); - free(config_path); - return false; - } + config_path = util_str_merge(path, CONFIG_FILENAME); + if (!ptapi_io_piubtn_keyboard_util_conf_read_from_file( + &ptapi_io_piubtn_keyboard_conf, config_path)) { + log_error("Loading keyboard config file %s failed.", config_path); free(config_path); + return false; + } - memset(ptapi_io_piubtn_keyboard_buffer, 0, sizeof(bool) * KEY_MAP_SIZE); + free(config_path); - return true; + memset(ptapi_io_piubtn_keyboard_buffer, 0, sizeof(bool) * KEY_MAP_SIZE); + + return true; } void ptapi_io_piubtn_close(void) { - free(ptapi_io_piubtn_keyboard_conf); + free(ptapi_io_piubtn_keyboard_conf); } bool ptapi_io_piubtn_recv(void) { - /* Nothing to poll */ - return true; + /* Nothing to poll */ + return true; } bool ptapi_io_piubtn_send(void) { - return true; + return true; } -void ptapi_io_piubtn_get_input(uint8_t player, struct ptapi_io_piubtn_inputs* inputs) +void ptapi_io_piubtn_get_input( + uint8_t player, struct ptapi_io_piubtn_inputs *inputs) { - if (player == 0) { - inputs->left = ptapi_io_piubtn_keyboard_buffer[ - ptapi_io_piubtn_keyboard_conf->button_map[PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P1_LEFT]]; - inputs->right = ptapi_io_piubtn_keyboard_buffer[ - ptapi_io_piubtn_keyboard_conf->button_map[PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P1_RIGHT]]; - inputs->start = ptapi_io_piubtn_keyboard_buffer[ - ptapi_io_piubtn_keyboard_conf->button_map[PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P1_START]]; - inputs->back = ptapi_io_piubtn_keyboard_buffer[ - ptapi_io_piubtn_keyboard_conf->button_map[PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P1_BACK]]; - } else { - inputs->left = ptapi_io_piubtn_keyboard_buffer[ - ptapi_io_piubtn_keyboard_conf->button_map[PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P2_LEFT]]; - inputs->right = ptapi_io_piubtn_keyboard_buffer[ - ptapi_io_piubtn_keyboard_conf->button_map[PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P2_RIGHT]]; - inputs->start = ptapi_io_piubtn_keyboard_buffer[ - ptapi_io_piubtn_keyboard_conf->button_map[PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P2_START]]; - inputs->back = ptapi_io_piubtn_keyboard_buffer[ - ptapi_io_piubtn_keyboard_conf->button_map[PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P2_BACK]]; - } + if (player == 0) { + inputs->left = ptapi_io_piubtn_keyboard_buffer + [ptapi_io_piubtn_keyboard_conf + ->button_map[PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P1_LEFT]]; + inputs->right = ptapi_io_piubtn_keyboard_buffer + [ptapi_io_piubtn_keyboard_conf + ->button_map[PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P1_RIGHT]]; + inputs->start = ptapi_io_piubtn_keyboard_buffer + [ptapi_io_piubtn_keyboard_conf + ->button_map[PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P1_START]]; + inputs->back = ptapi_io_piubtn_keyboard_buffer + [ptapi_io_piubtn_keyboard_conf + ->button_map[PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P1_BACK]]; + } else { + inputs->left = ptapi_io_piubtn_keyboard_buffer + [ptapi_io_piubtn_keyboard_conf + ->button_map[PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P2_LEFT]]; + inputs->right = ptapi_io_piubtn_keyboard_buffer + [ptapi_io_piubtn_keyboard_conf + ->button_map[PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P2_RIGHT]]; + inputs->start = ptapi_io_piubtn_keyboard_buffer + [ptapi_io_piubtn_keyboard_conf + ->button_map[PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P2_START]]; + inputs->back = ptapi_io_piubtn_keyboard_buffer + [ptapi_io_piubtn_keyboard_conf + ->button_map[PTAPI_IO_PIUBTN_KEYBOARD_UTIL_CONF_INPUT_P2_BACK]]; + } } -void ptapi_io_piubtn_set_output(uint8_t player, const struct ptapi_io_piubtn_outputs* outputs) +void ptapi_io_piubtn_set_output( + uint8_t player, const struct ptapi_io_piubtn_outputs *outputs) { - /* Not supported */ + /* Not supported */ } static void _piubtn_emu_keyboard_dispatch_key_press(KeySym key) { - if (key > 0 && key < KEY_MAP_SIZE) { - ptapi_io_piubtn_keyboard_buffer[key] = true; - } + if (key > 0 && key < KEY_MAP_SIZE) { + ptapi_io_piubtn_keyboard_buffer[key] = true; + } } static void _piubtn_emu_keyboard_dispatch_key_release(KeySym key) { - if (key > 0 && key < KEY_MAP_SIZE) { - ptapi_io_piubtn_keyboard_buffer[key] = false; - } + if (key > 0 && key < KEY_MAP_SIZE) { + ptapi_io_piubtn_keyboard_buffer[key] = false; + } } \ No newline at end of file diff --git a/src/main/ptapi/io/piubtn/null/null.c b/src/main/ptapi/io/piubtn/null/null.c index b0f6e37..878d52e 100644 --- a/src/main/ptapi/io/piubtn/null/null.c +++ b/src/main/ptapi/io/piubtn/null/null.c @@ -1,42 +1,41 @@ /** - * Implementation of the piubtn API. Null driver for testing and starting piu without a real io + * Implementation of the piubtn API. Null driver for testing and starting piu + * without a real io */ #define LOG_MODULE "ptapi-io-piubtn-null" #include "ptapi/io/piubtn.h" -const char* ptapi_io_piubtn_ident(void) +const char *ptapi_io_piubtn_ident(void) { - return "null"; + return "null"; } bool ptapi_io_piubtn_open(void) { - return true; + return true; } - void ptapi_io_piubtn_close(void) { - } bool ptapi_io_piubtn_recv(void) { - return true; + return true; } bool ptapi_io_piubtn_send(void) { - return true; + return true; } -void ptapi_io_piubtn_get_input(uint8_t player, struct ptapi_io_piubtn_inputs* inputs) +void ptapi_io_piubtn_get_input( + uint8_t player, struct ptapi_io_piubtn_inputs *inputs) { - } -void ptapi_io_piubtn_set_output(uint8_t player, const struct ptapi_io_piubtn_outputs* outputs) +void ptapi_io_piubtn_set_output( + uint8_t player, const struct ptapi_io_piubtn_outputs *outputs) { - } \ No newline at end of file diff --git a/src/main/ptapi/io/piubtn/real/piubtn.c b/src/main/ptapi/io/piubtn/real/piubtn.c index 56afe59..1cb3f96 100644 --- a/src/main/ptapi/io/piubtn/real/piubtn.c +++ b/src/main/ptapi/io/piubtn/real/piubtn.c @@ -21,115 +21,118 @@ static struct ptapi_io_piubtn_outputs piubtn_drv_piubtn_out[2]; static void piubtn_drv_piubtn_copy_outputs() { - memset(piubtn_drv_piubtn_out_buffer, 0, - sizeof(piubtn_drv_piubtn_out_buffer)); + memset(piubtn_drv_piubtn_out_buffer, 0, sizeof(piubtn_drv_piubtn_out_buffer)); - /* Player 1 */ + /* Player 1 */ - if (piubtn_drv_piubtn_out[0].start) { - piubtn_drv_piubtn_out_buffer[0] |= (1 << 0); - } + if (piubtn_drv_piubtn_out[0].start) { + piubtn_drv_piubtn_out_buffer[0] |= (1 << 0); + } - if (piubtn_drv_piubtn_out[0].right) { - piubtn_drv_piubtn_out_buffer[0] |= (1 << 1); - } + if (piubtn_drv_piubtn_out[0].right) { + piubtn_drv_piubtn_out_buffer[0] |= (1 << 1); + } - if (piubtn_drv_piubtn_out[0].left) { - piubtn_drv_piubtn_out_buffer[0] |= (1 << 2); - } + if (piubtn_drv_piubtn_out[0].left) { + piubtn_drv_piubtn_out_buffer[0] |= (1 << 2); + } - if (piubtn_drv_piubtn_out[0].back) { - piubtn_drv_piubtn_out_buffer[0] |= (1 << 3); - } + if (piubtn_drv_piubtn_out[0].back) { + piubtn_drv_piubtn_out_buffer[0] |= (1 << 3); + } - /* Player 2 */ + /* Player 2 */ - if (piubtn_drv_piubtn_out[1].start) { - piubtn_drv_piubtn_out_buffer[0] |= (1 << 4); - } + if (piubtn_drv_piubtn_out[1].start) { + piubtn_drv_piubtn_out_buffer[0] |= (1 << 4); + } - if (piubtn_drv_piubtn_out[1].right) { - piubtn_drv_piubtn_out_buffer[0] |= (1 << 5); - } + if (piubtn_drv_piubtn_out[1].right) { + piubtn_drv_piubtn_out_buffer[0] |= (1 << 5); + } - if (piubtn_drv_piubtn_out[1].left) { - piubtn_drv_piubtn_out_buffer[0] |= (1 << 6); - } + if (piubtn_drv_piubtn_out[1].left) { + piubtn_drv_piubtn_out_buffer[0] |= (1 << 6); + } - if (piubtn_drv_piubtn_out[1].back) { - piubtn_drv_piubtn_out_buffer[0] |= (1 << 7); - } + if (piubtn_drv_piubtn_out[1].back) { + piubtn_drv_piubtn_out_buffer[0] |= (1 << 7); + } } static void piubtn_drv_piubtn_copy_inputs() { - /* Player 1 */ - piubtn_drv_piubtn_in[0].back = piubtn_drv_piubtn_in_buffer[0] & (1 << 0); - piubtn_drv_piubtn_in[0].left = piubtn_drv_piubtn_in_buffer[0] & (1 << 1); - piubtn_drv_piubtn_in[0].right = piubtn_drv_piubtn_in_buffer[0] & (1 << 2); - piubtn_drv_piubtn_in[0].start = piubtn_drv_piubtn_in_buffer[0] & (1 << 3); + /* Player 1 */ + piubtn_drv_piubtn_in[0].back = piubtn_drv_piubtn_in_buffer[0] & (1 << 0); + piubtn_drv_piubtn_in[0].left = piubtn_drv_piubtn_in_buffer[0] & (1 << 1); + piubtn_drv_piubtn_in[0].right = piubtn_drv_piubtn_in_buffer[0] & (1 << 2); + piubtn_drv_piubtn_in[0].start = piubtn_drv_piubtn_in_buffer[0] & (1 << 3); - /* Player 2 */ - piubtn_drv_piubtn_in[1].back = piubtn_drv_piubtn_in_buffer[0] & (1 << 4); - piubtn_drv_piubtn_in[1].left = piubtn_drv_piubtn_in_buffer[0] & (1 << 5); - piubtn_drv_piubtn_in[1].right = piubtn_drv_piubtn_in_buffer[0] & (1 << 6); - piubtn_drv_piubtn_in[1].start = piubtn_drv_piubtn_in_buffer[0] & (1 << 7); + /* Player 2 */ + piubtn_drv_piubtn_in[1].back = piubtn_drv_piubtn_in_buffer[0] & (1 << 4); + piubtn_drv_piubtn_in[1].left = piubtn_drv_piubtn_in_buffer[0] & (1 << 5); + piubtn_drv_piubtn_in[1].right = piubtn_drv_piubtn_in_buffer[0] & (1 << 6); + piubtn_drv_piubtn_in[1].start = piubtn_drv_piubtn_in_buffer[0] & (1 << 7); } -const char* ptapi_io_piubtn_ident(void) +const char *ptapi_io_piubtn_ident(void) { - return "piubtn"; + return "piubtn"; } bool ptapi_io_piubtn_open(void) { - return piubtn_drv_device_open(); + return piubtn_drv_device_open(); } void ptapi_io_piubtn_close(void) { - piubtn_drv_device_close(); + piubtn_drv_device_close(); } bool ptapi_io_piubtn_recv(void) { - if (!piubtn_drv_device_read(piubtn_drv_piubtn_in_buffer, - sizeof(piubtn_drv_piubtn_in_buffer))) { - return false; - } + if (!piubtn_drv_device_read( + piubtn_drv_piubtn_in_buffer, sizeof(piubtn_drv_piubtn_in_buffer))) { + return false; + } - /* Invert pull ups */ - for (uint8_t j = 0; j < 4; j++) { - piubtn_drv_piubtn_in_buffer[j] ^= 0xFF; - } + /* Invert pull ups */ + for (uint8_t j = 0; j < 4; j++) { + piubtn_drv_piubtn_in_buffer[j] ^= 0xFF; + } - piubtn_drv_piubtn_copy_inputs(); + piubtn_drv_piubtn_copy_inputs(); - return true; + return true; } bool ptapi_io_piubtn_send(void) { - piubtn_drv_piubtn_copy_outputs(); + piubtn_drv_piubtn_copy_outputs(); - if (!piubtn_drv_device_write(piubtn_drv_piubtn_out_buffer, - sizeof(piubtn_drv_piubtn_out_buffer))) { - return false; - } + if (!piubtn_drv_device_write( + piubtn_drv_piubtn_out_buffer, sizeof(piubtn_drv_piubtn_out_buffer))) { + return false; + } - return true; + return true; } -void ptapi_io_piubtn_get_input(uint8_t player, - struct ptapi_io_piubtn_inputs* inputs) +void ptapi_io_piubtn_get_input( + uint8_t player, struct ptapi_io_piubtn_inputs *inputs) { - memcpy(inputs, &piubtn_drv_piubtn_in[player], - sizeof(struct ptapi_io_piubtn_inputs)); + memcpy( + inputs, + &piubtn_drv_piubtn_in[player], + sizeof(struct ptapi_io_piubtn_inputs)); } -void ptapi_io_piubtn_set_output(uint8_t player, - const struct ptapi_io_piubtn_outputs* outputs) +void ptapi_io_piubtn_set_output( + uint8_t player, const struct ptapi_io_piubtn_outputs *outputs) { - memcpy(&piubtn_drv_piubtn_out[player], outputs, - sizeof(struct ptapi_io_piubtn_outputs)); + memcpy( + &piubtn_drv_piubtn_out[player], + outputs, + sizeof(struct ptapi_io_piubtn_outputs)); } \ No newline at end of file diff --git a/src/main/ptapi/io/piubtn/test/main.c b/src/main/ptapi/io/piubtn/test/main.c index d3fe9f0..6bf32eb 100644 --- a/src/main/ptapi/io/piubtn/test/main.c +++ b/src/main/ptapi/io/piubtn/test/main.c @@ -1,8 +1,8 @@ /** * Tool to test implementations of the piubtn API */ -#include #include +#include #include #include @@ -13,91 +13,94 @@ static struct ptapi_io_piubtn_api api; -int main(int argc, char** argv) +int main(int argc, char **argv) { - struct ptapi_io_piubtn_inputs inputs[2]; - struct ptapi_io_piubtn_outputs outputs[2]; + struct ptapi_io_piubtn_inputs inputs[2]; + struct ptapi_io_piubtn_outputs outputs[2]; - util_log_set_file("piubtn-test.log", false); - util_log_set_level(LOG_LEVEL_ERROR); + util_log_set_file("piubtn-test.log", false); + util_log_set_level(LOG_LEVEL_ERROR); - if (argc < 2) { - printf( - "Usage: %s [debug]\n", - argv[0]); - return -1; + if (argc < 2) { + printf("Usage: %s [debug]\n", argv[0]); + return -1; + } + + for (int i = 0; i < argc; i++) { + if (!strcmp(argv[i], "debug")) { + util_log_set_level(LOG_LEVEL_DEBUG); + break; } + } - for (int i = 0; i < argc; i++) { - if (!strcmp(argv[i], "debug")) { - util_log_set_level(LOG_LEVEL_DEBUG); - break; - } - } + if (!ptapi_io_piubtn_util_lib_load(argv[1], &api)) { + printf("Loading piubtn lib %s failed\n", argv[1]); + return -2; + } - if (!ptapi_io_piubtn_util_lib_load(argv[1], &api)) { - printf("Loading piubtn lib %s failed\n", argv[1]); - return -2; - } + if (!api.open()) { + return -3; + } - if (!api.open()) { - return -3; + for (uint8_t i = 0; i < 2; i++) { + memset(&inputs, 0, sizeof(inputs)); + memset(&outputs, 0, sizeof(outputs)); + } + + printf("Enter main loop by pressing any key (on the keyboard)\n"); + getchar(); + + while (true) { + if (!api.recv()) { + return -4; } for (uint8_t i = 0; i < 2; i++) { - memset(&inputs, 0, sizeof(inputs)); - memset(&outputs, 0, sizeof(outputs)); + api.get_input(i, &inputs[i]); } - printf("Enter main loop by pressing any key (on the keyboard)\n"); - getchar(); - - while (true) { - if (!api.recv()) { - return -4; - } - - for (uint8_t i = 0; i < 2; i++) { - api.get_input(i, &inputs[i]); - } - - if (inputs[0].start && inputs[1].start) { - break; - } - - system("clear"); - - printf("Press p1 start + p2 start to exit\n"); - printf( - "|-------------------|\n" - "| %d %d |\n" - "|%d %d %d %d|\n" - "| %d %d |\n" - "|-------------------|\n", - inputs[0].back, inputs[1].back, - inputs[0].left, inputs[0].right, inputs[1].left, inputs[1].right, - inputs[0].start, inputs[1].start); - - for (int i = 0; i < 2; i++) { - memset(&outputs[i], 0, sizeof(outputs[i])); - - inputs[i].start = outputs[i].start; - inputs[i].back = outputs[i].back; - inputs[i].left = outputs[i].left; - inputs[i].right = outputs[i].right; - - api.set_output(i, &outputs[i]); - } - - if (!api.send()) { - return -5; - } - - /* Avoid hardware banging */ - usleep(1000); + if (inputs[0].start && inputs[1].start) { + break; } - api.close(); + system("clear"); - return 0; + printf("Press p1 start + p2 start to exit\n"); + printf( + "|-------------------|\n" + "| %d %d |\n" + "|%d %d %d %d|\n" + "| %d %d |\n" + "|-------------------|\n", + inputs[0].back, + inputs[1].back, + inputs[0].left, + inputs[0].right, + inputs[1].left, + inputs[1].right, + inputs[0].start, + inputs[1].start); + + for (int i = 0; i < 2; i++) { + memset(&outputs[i], 0, sizeof(outputs[i])); + + inputs[i].start = outputs[i].start; + inputs[i].back = outputs[i].back; + inputs[i].left = outputs[i].left; + inputs[i].right = outputs[i].right; + + api.set_output(i, &outputs[i]); + } + + if (!api.send()) { + return -5; + } + + /* Avoid hardware banging */ + usleep(1000); + } + + api.close(); + + return 0; } \ No newline at end of file diff --git a/src/main/ptapi/io/piubtn/util/lib.c b/src/main/ptapi/io/piubtn/util/lib.c index 94934a3..b42fde9 100644 --- a/src/main/ptapi/io/piubtn/util/lib.c +++ b/src/main/ptapi/io/piubtn/util/lib.c @@ -4,31 +4,32 @@ #include "ptapi/io/piubtn/util/lib.h" -bool ptapi_io_piubtn_util_lib_load(const char* path, struct ptapi_io_piubtn_api* api) +bool ptapi_io_piubtn_util_lib_load( + const char *path, struct ptapi_io_piubtn_api *api) { - void* handle; + void *handle; - handle = cnh_lib_load(path); + handle = cnh_lib_load(path); - if (handle == NULL) { - return false; - } + if (handle == NULL) { + return false; + } - api->ident = (ptapi_io_piubtn_ident_t) cnh_lib_get_func_addr_handle( - handle, "ptapi_io_piubtn_ident"); + api->ident = (ptapi_io_piubtn_ident_t) cnh_lib_get_func_addr_handle( + handle, "ptapi_io_piubtn_ident"); - api->open = (ptapi_io_piubtn_open_t) cnh_lib_get_func_addr_handle( - handle, "ptapi_io_piubtn_open"); - api->close = (ptapi_io_piubtn_close_t) cnh_lib_get_func_addr_handle( - handle, "ptapi_io_piubtn_close"); - api->recv = (ptapi_io_piubtn_recv_t) cnh_lib_get_func_addr_handle( - handle, "ptapi_io_piubtn_recv"); - api->send = (ptapi_io_piubtn_send_t) cnh_lib_get_func_addr_handle( - handle, "ptapi_io_piubtn_send"); - api->get_input = (ptapi_io_piubtn_get_input_t) - cnh_lib_get_func_addr_handle(handle, "ptapi_io_piubtn_get_input"); - api->set_output = (ptapi_io_piubtn_set_output_t) - cnh_lib_get_func_addr_handle(handle, "ptapi_io_piubtn_set_output"); + api->open = (ptapi_io_piubtn_open_t) cnh_lib_get_func_addr_handle( + handle, "ptapi_io_piubtn_open"); + api->close = (ptapi_io_piubtn_close_t) cnh_lib_get_func_addr_handle( + handle, "ptapi_io_piubtn_close"); + api->recv = (ptapi_io_piubtn_recv_t) cnh_lib_get_func_addr_handle( + handle, "ptapi_io_piubtn_recv"); + api->send = (ptapi_io_piubtn_send_t) cnh_lib_get_func_addr_handle( + handle, "ptapi_io_piubtn_send"); + api->get_input = (ptapi_io_piubtn_get_input_t) cnh_lib_get_func_addr_handle( + handle, "ptapi_io_piubtn_get_input"); + api->set_output = (ptapi_io_piubtn_set_output_t) cnh_lib_get_func_addr_handle( + handle, "ptapi_io_piubtn_set_output"); - return true; + return true; } \ No newline at end of file diff --git a/src/main/ptapi/io/piubtn/util/lib.h b/src/main/ptapi/io/piubtn/util/lib.h index c8adcbc..d53fd39 100644 --- a/src/main/ptapi/io/piubtn/util/lib.h +++ b/src/main/ptapi/io/piubtn/util/lib.h @@ -3,6 +3,7 @@ #include "ptapi/io/piubtn.h" -bool ptapi_io_piubtn_util_lib_load(const char* path, struct ptapi_io_piubtn_api* api); +bool ptapi_io_piubtn_util_lib_load( + const char *path, struct ptapi_io_piubtn_api *api); #endif diff --git a/src/main/ptapi/io/piuio/joystick-conf/main.c b/src/main/ptapi/io/piuio/joystick-conf/main.c index 6e3dc66..7f756ce 100644 --- a/src/main/ptapi/io/piuio/joystick-conf/main.c +++ b/src/main/ptapi/io/piuio/joystick-conf/main.c @@ -1,8 +1,8 @@ #include #include -#include "io/util/joystick.h" #include "io/util/joystick-util.h" +#include "io/util/joystick.h" #include "ptapi/io/piuio/joystick-util/joystick-conf.h" @@ -16,239 +16,276 @@ int kbhit() { - struct timeval tv = { 0L, 0L }; + struct timeval tv = {0L, 0L}; - fd_set fds; - FD_ZERO(&fds); - FD_SET(0, &fds); + fd_set fds; + FD_ZERO(&fds); + FD_SET(0, &fds); - return select(1, &fds, NULL, NULL, &tv); + return select(1, &fds, NULL, NULL, &tv); } int getch() { - int r; - unsigned char c; + int r; + unsigned char c; - if ((r = read(0, &c, sizeof(c))) < 0) { - return r; - } else { - return c; - } + if ((r = read(0, &c, sizeof(c))) < 0) { + return r; + } else { + return c; + } } -static uint16_t joystick_get_next_input(struct io_util_joystick* joystick) +static uint16_t joystick_get_next_input(struct io_util_joystick *joystick) { - bool pressed; - uint16_t button; + bool pressed; + uint16_t button; - pressed = false; - button = 0; + pressed = false; + button = 0; - while (true) { - if (!io_util_joystick_update(joystick)) { - printf("Error updating joystick failed.\n"); - exit(-1); - } - - // Allow skip-able input assignment via enter key on keyboard - if (kbhit() > 0) { - if (getch() == '\n') { - return SKIP_INPUT; - } - } - - if (!pressed) { - for (uint16_t j = 0; j < joystick->num_buttons; j++) { - if (io_util_joystick_is_button_pressed(joystick, j)) { - button = j; - pressed = true; - break; - } - } - } else { - // Wait for release of pressed input -> debouncing - if (!io_util_joystick_is_button_pressed(joystick, button)) { - break; - } - } - - util_time_sleep_ms(10); + while (true) { + if (!io_util_joystick_update(joystick)) { + printf("Error updating joystick failed.\n"); + exit(-1); } - return button; + // Allow skip-able input assignment via enter key on keyboard + if (kbhit() > 0) { + if (getch() == '\n') { + return SKIP_INPUT; + } + } + + if (!pressed) { + for (uint16_t j = 0; j < joystick->num_buttons; j++) { + if (io_util_joystick_is_button_pressed(joystick, j)) { + button = j; + pressed = true; + break; + } + } + } else { + // Wait for release of pressed input -> debouncing + if (!io_util_joystick_is_button_pressed(joystick, button)) { + break; + } + } + + util_time_sleep_ms(10); + } + + return button; } static void menu_joystick_test() { - struct io_util_joystick_util_device_info dev_info[MAX_JOYSTICKS]; - size_t connected_joysticks; + struct io_util_joystick_util_device_info dev_info[MAX_JOYSTICKS]; + size_t connected_joysticks; - connected_joysticks = io_util_joystick_util_scan(dev_info, MAX_JOYSTICKS); + connected_joysticks = io_util_joystick_util_scan(dev_info, MAX_JOYSTICKS); - printf("Connected joysticks: %d\n", connected_joysticks); + printf("Connected joysticks: %d\n", connected_joysticks); - for (size_t i = 0; i < connected_joysticks; i++) { - printf("%d: %s -> %s, buttons %d, axes %d\n", - i, dev_info[i].name, dev_info[i].dev_path, dev_info[i].num_buttons, dev_info[i].num_axes); - } + for (size_t i = 0; i < connected_joysticks; i++) { + printf( + "%d: %s -> %s, buttons %d, axes %d\n", + i, + dev_info[i].name, + dev_info[i].dev_path, + dev_info[i].num_buttons, + dev_info[i].num_axes); + } - size_t selected_device_idx; + size_t selected_device_idx; - printf("Select device: "); - scanf("%d", &selected_device_idx); + printf("Select device: "); + scanf("%d", &selected_device_idx); - if (selected_device_idx > connected_joysticks) { - printf("Invalid device id %d, out of range\n", selected_device_idx); - return; - } + if (selected_device_idx > connected_joysticks) { + printf("Invalid device id %d, out of range\n", selected_device_idx); + return; + } - struct io_util_joystick* joystick; + struct io_util_joystick *joystick; - if (!io_util_joystick_open(dev_info[selected_device_idx].dev_path, &joystick)) { - printf("Error opening device %s -> %s", dev_info[selected_device_idx].name, - dev_info[selected_device_idx].dev_path); - return; - } + if (!io_util_joystick_open( + dev_info[selected_device_idx].dev_path, &joystick)) { + printf( + "Error opening device %s -> %s", + dev_info[selected_device_idx].name, + dev_info[selected_device_idx].dev_path); + return; + } - printf("Pressed + released inputs:\n"); + printf("Pressed + released inputs:\n"); - while (true) { - printf("%d\n", joystick_get_next_input(joystick)); - } + while (true) { + printf("%d\n", joystick_get_next_input(joystick)); + } - io_util_joystick_close(joystick); + io_util_joystick_close(joystick); } static void menu_joystick_map() { - struct ptapi_io_piuio_joystick_util_conf* config; - struct ptapi_io_piuio_joystick_util_conf_entry config_entry; + struct ptapi_io_piuio_joystick_util_conf *config; + struct ptapi_io_piuio_joystick_util_conf_entry config_entry; - struct io_util_joystick_util_device_info dev_info[MAX_JOYSTICKS]; - size_t connected_joysticks; - struct io_util_joystick* joystick; + struct io_util_joystick_util_device_info dev_info[MAX_JOYSTICKS]; + size_t connected_joysticks; + struct io_util_joystick *joystick; - connected_joysticks = io_util_joystick_util_scan(dev_info, MAX_JOYSTICKS); + connected_joysticks = io_util_joystick_util_scan(dev_info, MAX_JOYSTICKS); - printf("Connected joysticks: %d\n", connected_joysticks); + printf("Connected joysticks: %d\n", connected_joysticks); - for (size_t i = 0; i < connected_joysticks; i++) { - printf("%d: %s -> %s, buttons %d, axes %d\n", - i, dev_info[i].name, dev_info[i].dev_path, dev_info[i].num_buttons, dev_info[i].num_axes); - } + for (size_t i = 0; i < connected_joysticks; i++) { + printf( + "%d: %s -> %s, buttons %d, axes %d\n", + i, + dev_info[i].name, + dev_info[i].dev_path, + dev_info[i].num_buttons, + dev_info[i].num_axes); + } - size_t selected_device_idx; + size_t selected_device_idx; - printf("Select device: "); - scanf("%d", &selected_device_idx); + printf("Select device: "); + scanf("%d", &selected_device_idx); - if (selected_device_idx > connected_joysticks) { - printf("Invalid device id %d, out of range\n", selected_device_idx); - return; - } + if (selected_device_idx > connected_joysticks) { + printf("Invalid device id %d, out of range\n", selected_device_idx); + return; + } - if (!ptapi_io_piuio_joystick_util_conf_read_from_file(&config, CONFIG_FILENAME)) { - printf("Reading existing config file failed, creating new\n"); + if (!ptapi_io_piuio_joystick_util_conf_read_from_file( + &config, CONFIG_FILENAME)) { + printf("Reading existing config file failed, creating new\n"); - ptapi_io_piuio_joystick_util_conf_new(&config); + ptapi_io_piuio_joystick_util_conf_new(&config); - memset(&config_entry, 0, sizeof(struct ptapi_io_piuio_joystick_util_conf_entry)); + memset( + &config_entry, + 0, + sizeof(struct ptapi_io_piuio_joystick_util_conf_entry)); - strcpy(config_entry.dev_path, dev_info[selected_device_idx].dev_path); - strcpy(config_entry.name, dev_info[selected_device_idx].name); + strcpy(config_entry.dev_path, dev_info[selected_device_idx].dev_path); + strcpy(config_entry.name, dev_info[selected_device_idx].name); + } else { + if (!ptapi_io_piuio_joystick_util_conf_find_entry( + config, + dev_info[selected_device_idx].name, + dev_info[selected_device_idx].dev_path, + &config_entry)) { + printf( + "Could not find existing mapping entry in config for joystick, " + "creating new one\n"); + + memset( + &config_entry, + 0, + sizeof(struct ptapi_io_piuio_joystick_util_conf_entry)); + + strcpy(config_entry.dev_path, dev_info[selected_device_idx].dev_path); + strcpy(config_entry.name, dev_info[selected_device_idx].name); } else { - if (!ptapi_io_piuio_joystick_util_conf_find_entry(config, dev_info[selected_device_idx].name, - dev_info[selected_device_idx].dev_path, &config_entry)) { - printf("Could not find existing mapping entry in config for joystick, creating new one\n"); - - memset(&config_entry, 0, sizeof(struct ptapi_io_piuio_joystick_util_conf_entry)); - - strcpy(config_entry.dev_path, dev_info[selected_device_idx].dev_path); - strcpy(config_entry.name, dev_info[selected_device_idx].name); - } else { - printf("Found existing mapping entry in config for joystick, overwriting\n"); - } + printf( + "Found existing mapping entry in config for joystick, overwriting\n"); } + } - printf("Configuring device %s -> %s\n", dev_info[selected_device_idx].name, dev_info[selected_device_idx].dev_path); + printf( + "Configuring device %s -> %s\n", + dev_info[selected_device_idx].name, + dev_info[selected_device_idx].dev_path); - if (!io_util_joystick_open(dev_info[selected_device_idx].dev_path, &joystick)) { - printf("Error opening device %s -> %s", dev_info[selected_device_idx].name, - dev_info[selected_device_idx].dev_path); - return; - } - - for (uint32_t i = PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_LU; i < PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_COUNT; - i++) { - printf("Press button to assign to \"%s\" or Enter/Return to skip: ", ptapi_io_piuio_joystick_util_conf_input_str[i]); - fflush(stdout); - - config_entry.button_map[i] = joystick_get_next_input(joystick); - - if (config_entry.button_map[i] == SKIP_INPUT) { - printf("SKIP\n"); - } else { - printf("%d\n", config_entry.button_map[i]); - } - } - - io_util_joystick_close(joystick); - - printf("Configuration of device %s -> %s done\n", dev_info[selected_device_idx].name, + if (!io_util_joystick_open( + dev_info[selected_device_idx].dev_path, &joystick)) { + printf( + "Error opening device %s -> %s", + dev_info[selected_device_idx].name, dev_info[selected_device_idx].dev_path); + return; + } - if (!ptapi_io_piuio_joystick_util_conf_set_entry(config, &config_entry)) { - ptapi_io_piuio_joystick_util_conf_append_entry(&config, &config_entry); + for (uint32_t i = PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_LU; + i < PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_COUNT; + i++) { + printf( + "Press button to assign to \"%s\" or Enter/Return to skip: ", + ptapi_io_piuio_joystick_util_conf_input_str[i]); + fflush(stdout); + + config_entry.button_map[i] = joystick_get_next_input(joystick); + + if (config_entry.button_map[i] == SKIP_INPUT) { + printf("SKIP\n"); + } else { + printf("%d\n", config_entry.button_map[i]); } + } - ptapi_io_piuio_joystick_util_conf_write_to_file(config, CONFIG_FILENAME); + io_util_joystick_close(joystick); - free(config); + printf( + "Configuration of device %s -> %s done\n", + dev_info[selected_device_idx].name, + dev_info[selected_device_idx].dev_path); - printf("Configuration file saved: %s\n", CONFIG_FILENAME); + if (!ptapi_io_piuio_joystick_util_conf_set_entry(config, &config_entry)) { + ptapi_io_piuio_joystick_util_conf_append_entry(&config, &config_entry); + } + + ptapi_io_piuio_joystick_util_conf_write_to_file(config, CONFIG_FILENAME); + + free(config); + + printf("Configuration file saved: %s\n", CONFIG_FILENAME); } -int main(int argc, char** argv) +int main(int argc, char **argv) { - bool main_loop; + bool main_loop; - util_log_set_file("joystick-conf.log", false); - util_log_set_level(LOG_LEVEL_ERROR); + util_log_set_file("joystick-conf.log", false); + util_log_set_level(LOG_LEVEL_ERROR); - printf("ptapi PIUIO joystick button mapping config tool\n"); + printf("ptapi PIUIO joystick button mapping config tool\n"); - main_loop = true; + main_loop = true; - while (main_loop) { - uint32_t item; + while (main_loop) { + uint32_t item; - printf("Main menu, please select:\n"); - printf("1 > Joystick input test\n"); - printf("2 > Configure joystick mappings\n"); - printf("3 > Exit\n"); - printf("Select number: "); + printf("Main menu, please select:\n"); + printf("1 > Joystick input test\n"); + printf("2 > Configure joystick mappings\n"); + printf("3 > Exit\n"); + printf("Select number: "); - scanf("%d", &item); + scanf("%d", &item); - switch (item) { - case 1: - menu_joystick_test(); - break; + switch (item) { + case 1: + menu_joystick_test(); + break; - case 2: - menu_joystick_map(); - break; + case 2: + menu_joystick_map(); + break; - case 3: - main_loop = false; - break; + case 3: + main_loop = false; + break; - default: - printf("Invalid item chosen: %d\n", item); - break; - } + default: + printf("Invalid item chosen: %d\n", item); + break; } + } - return 0; + return 0; } \ No newline at end of file diff --git a/src/main/ptapi/io/piuio/joystick-util/joystick-conf.c b/src/main/ptapi/io/piuio/joystick-util/joystick-conf.c index 9216923..53b8fde 100644 --- a/src/main/ptapi/io/piuio/joystick-util/joystick-conf.c +++ b/src/main/ptapi/io/piuio/joystick-util/joystick-conf.c @@ -4,103 +4,129 @@ #include "util/log.h" #include "util/mem.h" -const char* ptapi_io_piuio_joystick_util_conf_input_str[PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_COUNT] = { - "invalid", - "P1 Left Up", - "P1 Right Up", - "P1 Center", - "P1 Left Down", - "P1 Right Down", - "P2 Left Up", - "P2 Right Up", - "P2 Center", - "P2 Left Down", - "P2 Right Down", - "Service", - "Test", - "Coin Clear", - "Coin", - "Coin 2" +const char *ptapi_io_piuio_joystick_util_conf_input_str + [PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_COUNT] = { + "invalid", + "P1 Left Up", + "P1 Right Up", + "P1 Center", + "P1 Left Down", + "P1 Right Down", + "P2 Left Up", + "P2 Right Up", + "P2 Center", + "P2 Left Down", + "P2 Right Down", + "Service", + "Test", + "Coin Clear", + "Coin", + "Coin 2"}; + +void ptapi_io_piuio_joystick_util_conf_new( + struct ptapi_io_piuio_joystick_util_conf **conf) +{ + log_assert(conf); + + *conf = util_xmalloc(sizeof(struct ptapi_io_piuio_joystick_util_conf)); + (*conf)->num_entries = 0; +} + +bool ptapi_io_piuio_joystick_util_conf_read_from_file( + struct ptapi_io_piuio_joystick_util_conf **conf, const char *path) +{ + log_assert(path); + log_assert(conf); + + void *buffer; + size_t size; + + if (!util_file_load(path, &buffer, &size, false)) { + return false; + } + + *conf = (struct ptapi_io_piuio_joystick_util_conf *) buffer; + + return true; +} + +bool ptapi_io_piuio_joystick_util_conf_write_to_file( + struct ptapi_io_piuio_joystick_util_conf *conf, const char *path) +{ + log_assert(path); + log_assert(conf); + + return util_file_save( + path, + conf, + sizeof(struct ptapi_io_piuio_joystick_util_conf) + + sizeof(struct ptapi_io_piuio_joystick_util_conf_entry) * + conf->num_entries); +} + +bool ptapi_io_piuio_joystick_util_conf_set_entry( + struct ptapi_io_piuio_joystick_util_conf *conf, + struct ptapi_io_piuio_joystick_util_conf_entry *entry) +{ + log_assert(conf); + log_assert(entry); + + for (size_t i = 0; i < conf->num_entries; i++) { + if (!strcmp(conf->entries[i].name, entry->name) && + !strcmp(conf->entries[i].dev_path, entry->dev_path)) { + memcpy( + &conf->entries[i], + entry, + sizeof(struct ptapi_io_piuio_joystick_util_conf_entry)); + return true; + } + } + + return false; +} + +void ptapi_io_piuio_joystick_util_conf_append_entry( + struct ptapi_io_piuio_joystick_util_conf **conf, + struct ptapi_io_piuio_joystick_util_conf_entry *entry) +{ + log_assert(conf); + log_assert(entry); + + (*conf)->num_entries++; + + *conf = util_xrealloc( + *conf, + sizeof(struct ptapi_io_piuio_joystick_util_conf *) + + sizeof(struct ptapi_io_piuio_joystick_util_conf_entry) * + (*conf)->num_entries); + + memcpy( + &(*conf)->entries[(*conf)->num_entries - 1], + entry, + sizeof(struct ptapi_io_piuio_joystick_util_conf_entry)); }; -void ptapi_io_piuio_joystick_util_conf_new(struct ptapi_io_piuio_joystick_util_conf** conf) +bool ptapi_io_piuio_joystick_util_conf_find_entry( + struct ptapi_io_piuio_joystick_util_conf *conf, + const char *name, + const char *dev_path, + struct ptapi_io_piuio_joystick_util_conf_entry *entry) { - log_assert(conf); + log_assert(name); + log_assert(dev_path); + log_assert(entry); - *conf = util_xmalloc(sizeof(struct ptapi_io_piuio_joystick_util_conf)); - (*conf)->num_entries = 0; -} + for (size_t i = 0; i < conf->num_entries; i++) { + if (!strcmp(conf->entries[i].name, name) && + !strcmp(conf->entries[i].dev_path, dev_path)) { + memcpy( + entry, + &conf->entries[i], + sizeof(struct ptapi_io_piuio_joystick_util_conf_entry)); -bool ptapi_io_piuio_joystick_util_conf_read_from_file(struct ptapi_io_piuio_joystick_util_conf** conf, const char* path) -{ - log_assert(path); - log_assert(conf); - - void* buffer; - size_t size; - - if (!util_file_load(path, &buffer, &size, false)) { - return false; + return true; } + } - *conf = (struct ptapi_io_piuio_joystick_util_conf*) buffer; - - return true; -} - -bool ptapi_io_piuio_joystick_util_conf_write_to_file(struct ptapi_io_piuio_joystick_util_conf* conf, const char* path) -{ - log_assert(path); - log_assert(conf); - - return util_file_save(path, conf, sizeof(struct ptapi_io_piuio_joystick_util_conf) + - sizeof(struct ptapi_io_piuio_joystick_util_conf_entry) * conf->num_entries); -} - -bool ptapi_io_piuio_joystick_util_conf_set_entry(struct ptapi_io_piuio_joystick_util_conf* conf, - struct ptapi_io_piuio_joystick_util_conf_entry* entry) -{ - log_assert(conf); - log_assert(entry); - - for (size_t i = 0; i < conf->num_entries; i++) { - if (!strcmp(conf->entries[i].name, entry->name) && !strcmp(conf->entries[i].dev_path, entry->dev_path)) { - memcpy(&conf->entries[i], entry, sizeof(struct ptapi_io_piuio_joystick_util_conf_entry)); - return true; - } - } - - return false; -} - -void ptapi_io_piuio_joystick_util_conf_append_entry(struct ptapi_io_piuio_joystick_util_conf** conf, - struct ptapi_io_piuio_joystick_util_conf_entry* entry) -{ - log_assert(conf); - log_assert(entry); - - (*conf)->num_entries++; - - *conf = util_xrealloc(*conf, sizeof(struct ptapi_io_piuio_joystick_util_conf*) + - sizeof(struct ptapi_io_piuio_joystick_util_conf_entry) * (*conf)->num_entries); - - memcpy(&(*conf)->entries[(*conf)->num_entries - 1], entry, sizeof(struct ptapi_io_piuio_joystick_util_conf_entry)); -}; - -bool ptapi_io_piuio_joystick_util_conf_find_entry(struct ptapi_io_piuio_joystick_util_conf* conf, const char* name, - const char* dev_path, struct ptapi_io_piuio_joystick_util_conf_entry* entry) -{ - log_assert(name); - log_assert(dev_path); - log_assert(entry); - - for (size_t i = 0; i < conf->num_entries; i++) { - if (!strcmp(conf->entries[i].name, name) && !strcmp(conf->entries[i].dev_path, dev_path)) { - memcpy(entry, &conf->entries[i], sizeof(struct ptapi_io_piuio_joystick_util_conf_entry)); - - return true; - } - } - - return false; + return false; } \ No newline at end of file diff --git a/src/main/ptapi/io/piuio/joystick-util/joystick-conf.h b/src/main/ptapi/io/piuio/joystick-util/joystick-conf.h index 094d768..94bc072 100644 --- a/src/main/ptapi/io/piuio/joystick-util/joystick-conf.h +++ b/src/main/ptapi/io/piuio/joystick-util/joystick-conf.h @@ -6,52 +6,61 @@ #include "io/util/joystick.h" enum PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT { - PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_INVALID = 0, - PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_LU = 1, - PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_RU = 2, - PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_CN = 3, - PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_LD = 4, - PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_RD = 5, - PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P2_LU = 6, - PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P2_RU = 7, - PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P2_CN = 8, - PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P2_LD = 9, - PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P2_RD = 10, - PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_SERVICE = 11, - PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_TEST = 12, - PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_CLEAR = 13, - PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_COIN = 14, - PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_COIN2 = 15, - PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_COUNT = 16, + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_INVALID = 0, + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_LU = 1, + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_RU = 2, + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_CN = 3, + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_LD = 4, + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_RD = 5, + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P2_LU = 6, + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P2_RU = 7, + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P2_CN = 8, + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P2_LD = 9, + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P2_RD = 10, + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_SERVICE = 11, + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_TEST = 12, + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_CLEAR = 13, + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_COIN = 14, + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_COIN2 = 15, + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_COUNT = 16, }; -extern const char* ptapi_io_piuio_joystick_util_conf_input_str[PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_COUNT]; +extern const char *ptapi_io_piuio_joystick_util_conf_input_str + [PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_COUNT]; struct ptapi_io_piuio_joystick_util_conf_entry { - char name[JOYSTICK_NAME_LEN]; - char dev_path[PATH_MAX]; + char name[JOYSTICK_NAME_LEN]; + char dev_path[PATH_MAX]; - uint16_t button_map[PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_COUNT]; + uint16_t button_map[PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_COUNT]; }; struct ptapi_io_piuio_joystick_util_conf { - size_t num_entries; - struct ptapi_io_piuio_joystick_util_conf_entry entries[]; + size_t num_entries; + struct ptapi_io_piuio_joystick_util_conf_entry entries[]; }; -void ptapi_io_piuio_joystick_util_conf_new(struct ptapi_io_piuio_joystick_util_conf** conf); +void ptapi_io_piuio_joystick_util_conf_new( + struct ptapi_io_piuio_joystick_util_conf **conf); -bool ptapi_io_piuio_joystick_util_conf_read_from_file(struct ptapi_io_piuio_joystick_util_conf** conf, const char* path); +bool ptapi_io_piuio_joystick_util_conf_read_from_file( + struct ptapi_io_piuio_joystick_util_conf **conf, const char *path); -bool ptapi_io_piuio_joystick_util_conf_write_to_file(struct ptapi_io_piuio_joystick_util_conf* conf, const char* path); +bool ptapi_io_piuio_joystick_util_conf_write_to_file( + struct ptapi_io_piuio_joystick_util_conf *conf, const char *path); -bool ptapi_io_piuio_joystick_util_conf_set_entry(struct ptapi_io_piuio_joystick_util_conf* conf, - struct ptapi_io_piuio_joystick_util_conf_entry* entry); +bool ptapi_io_piuio_joystick_util_conf_set_entry( + struct ptapi_io_piuio_joystick_util_conf *conf, + struct ptapi_io_piuio_joystick_util_conf_entry *entry); -void ptapi_io_piuio_joystick_util_conf_append_entry(struct ptapi_io_piuio_joystick_util_conf** conf, - struct ptapi_io_piuio_joystick_util_conf_entry* entry); +void ptapi_io_piuio_joystick_util_conf_append_entry( + struct ptapi_io_piuio_joystick_util_conf **conf, + struct ptapi_io_piuio_joystick_util_conf_entry *entry); -bool ptapi_io_piuio_joystick_util_conf_find_entry(struct ptapi_io_piuio_joystick_util_conf* conf, const char* name, - const char* dev_path, struct ptapi_io_piuio_joystick_util_conf_entry* entry); +bool ptapi_io_piuio_joystick_util_conf_find_entry( + struct ptapi_io_piuio_joystick_util_conf *conf, + const char *name, + const char *dev_path, + struct ptapi_io_piuio_joystick_util_conf_entry *entry); #endif diff --git a/src/main/ptapi/io/piuio/joystick/joystick.c b/src/main/ptapi/io/piuio/joystick/joystick.c index 5ad3663..48d615f 100644 --- a/src/main/ptapi/io/piuio/joystick/joystick.c +++ b/src/main/ptapi/io/piuio/joystick/joystick.c @@ -18,178 +18,228 @@ #define CONFIG_FILENAME "/piuio-joystick-conf.bin" struct ptapi_io_piuio_joystick_with_conf { - struct ptapi_io_piuio_joystick_util_conf_entry* conf; - struct io_util_joystick* joystick; + struct ptapi_io_piuio_joystick_util_conf_entry *conf; + struct io_util_joystick *joystick; }; -static struct ptapi_io_piuio_joystick_util_conf* ptapi_io_piuio_joystick_util_conf; -static struct ptapi_io_piuio_joystick_with_conf ptapi_io_piuio_joysticks_with_conf[MAX_NUM_JOYSTICKS]; +static struct ptapi_io_piuio_joystick_util_conf + *ptapi_io_piuio_joystick_util_conf; +static struct ptapi_io_piuio_joystick_with_conf + ptapi_io_piuio_joysticks_with_conf[MAX_NUM_JOYSTICKS]; static size_t ptapi_io_piuio_num_active_joysticks; -static bool ptapi_io_piuio_merge_inputs(enum PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT input) +static bool +ptapi_io_piuio_merge_inputs(enum PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT input) { - bool pressed; + bool pressed; - pressed = false; + pressed = false; - for (size_t i = 0; i < ptapi_io_piuio_num_active_joysticks; i++) { - if (ptapi_io_piuio_joysticks_with_conf[i].joystick) { - pressed = pressed || - io_util_joystick_is_button_pressed( - ptapi_io_piuio_joysticks_with_conf[i].joystick, - ptapi_io_piuio_joysticks_with_conf[i].conf->button_map[input]); - } + for (size_t i = 0; i < ptapi_io_piuio_num_active_joysticks; i++) { + if (ptapi_io_piuio_joysticks_with_conf[i].joystick) { + pressed = + pressed || + io_util_joystick_is_button_pressed( + ptapi_io_piuio_joysticks_with_conf[i].joystick, + ptapi_io_piuio_joysticks_with_conf[i].conf->button_map[input]); } + } - return pressed; + return pressed; } -const char* ptapi_io_piuio_ident(void) +const char *ptapi_io_piuio_ident(void) { - return "joystick"; + return "joystick"; } bool ptapi_io_piuio_open() { - char path[PATH_MAX]; - char* config_path; - struct io_util_joystick_util_device_info device_info[MAX_NUM_JOYSTICKS]; - size_t devices_connected; + char path[PATH_MAX]; + char *config_path; + struct io_util_joystick_util_device_info device_info[MAX_NUM_JOYSTICKS]; + size_t devices_connected; - // The game changes the working directory to the 'game' sub-folder. Therefore, ./my-config does not work here. - if (!util_proc_get_folder_path_executable_no_ld_linux(path, sizeof(path))) { - log_error("Getting executable folder path failed."); - return false; - } + // The game changes the working directory to the 'game' sub-folder. Therefore, + // ./my-config does not work here. + if (!util_proc_get_folder_path_executable_no_ld_linux(path, sizeof(path))) { + log_error("Getting executable folder path failed."); + return false; + } - config_path = util_str_merge(path, CONFIG_FILENAME); + config_path = util_str_merge(path, CONFIG_FILENAME); - log_info("Loading configuration: ", config_path); - - if (!ptapi_io_piuio_joystick_util_conf_read_from_file(&ptapi_io_piuio_joystick_util_conf, config_path)) { - log_error("Loading joystick config file %s failed.", CONFIG_FILENAME); - free(config_path); - return false; - } + log_info("Loading configuration: ", config_path); + if (!ptapi_io_piuio_joystick_util_conf_read_from_file( + &ptapi_io_piuio_joystick_util_conf, config_path)) { + log_error("Loading joystick config file %s failed.", CONFIG_FILENAME); free(config_path); + return false; + } - devices_connected = io_util_joystick_util_scan(device_info, MAX_NUM_JOYSTICKS); + free(config_path); - log_debug("Found connected joysticks: %d", devices_connected); + devices_connected = + io_util_joystick_util_scan(device_info, MAX_NUM_JOYSTICKS); - ptapi_io_piuio_num_active_joysticks = 0; + log_debug("Found connected joysticks: %d", devices_connected); - memset(ptapi_io_piuio_joysticks_with_conf, 0, sizeof(struct ptapi_io_piuio_joystick_with_conf) * MAX_NUM_JOYSTICKS); + ptapi_io_piuio_num_active_joysticks = 0; - for (size_t i = 0; i < devices_connected; i++) { - log_debug("%d: %s -> %s, buttons %d, axes %d\n", - i, device_info[i].name, device_info[i].dev_path, device_info[i].num_buttons, device_info[i].num_axes); + memset( + ptapi_io_piuio_joysticks_with_conf, + 0, + sizeof(struct ptapi_io_piuio_joystick_with_conf) * MAX_NUM_JOYSTICKS); - // Find a matching configuration - for (size_t j = 0; j < ptapi_io_piuio_joystick_util_conf->num_entries; j++) { + for (size_t i = 0; i < devices_connected; i++) { + log_debug( + "%d: %s -> %s, buttons %d, axes %d\n", + i, + device_info[i].name, + device_info[i].dev_path, + device_info[i].num_buttons, + device_info[i].num_axes); - if (!strcmp(ptapi_io_piuio_joystick_util_conf->entries[j].name, device_info[i].name) && - !strcmp(ptapi_io_piuio_joystick_util_conf->entries[j].dev_path, device_info[i].dev_path)) { - log_debug("Found matching configuration for %s -> %s", device_info[i].name, device_info[i].dev_path); + // Find a matching configuration + for (size_t j = 0; j < ptapi_io_piuio_joystick_util_conf->num_entries; + j++) { - ptapi_io_piuio_joysticks_with_conf[ptapi_io_piuio_num_active_joysticks].conf = - &ptapi_io_piuio_joystick_util_conf->entries[j]; - ptapi_io_piuio_num_active_joysticks++; - } - } + if (!strcmp( + ptapi_io_piuio_joystick_util_conf->entries[j].name, + device_info[i].name) && + !strcmp( + ptapi_io_piuio_joystick_util_conf->entries[j].dev_path, + device_info[i].dev_path)) { + log_debug( + "Found matching configuration for %s -> %s", + device_info[i].name, + device_info[i].dev_path); + + ptapi_io_piuio_joysticks_with_conf[ptapi_io_piuio_num_active_joysticks] + .conf = &ptapi_io_piuio_joystick_util_conf->entries[j]; + ptapi_io_piuio_num_active_joysticks++; + } } + } - // Open all joysticks with a matching configuration + // Open all joysticks with a matching configuration - log_debug("Opening %d joysticks...", ptapi_io_piuio_num_active_joysticks); + log_debug("Opening %d joysticks...", ptapi_io_piuio_num_active_joysticks); - for (size_t i = 0; i < ptapi_io_piuio_num_active_joysticks; i++) { + for (size_t i = 0; i < ptapi_io_piuio_num_active_joysticks; i++) { - if (!io_util_joystick_open(ptapi_io_piuio_joysticks_with_conf[i].conf->dev_path, - &ptapi_io_piuio_joysticks_with_conf[i].joystick)) { - log_warn("Could not open joystick %s -> %s, ignoring", ptapi_io_piuio_joysticks_with_conf[i].conf->name, - ptapi_io_piuio_joysticks_with_conf[i].conf->dev_path); - } else { - log_info("Opened joystick %s -> %s", ptapi_io_piuio_joysticks_with_conf[i].conf->name, - ptapi_io_piuio_joysticks_with_conf[i].conf->dev_path); - } + if (!io_util_joystick_open( + ptapi_io_piuio_joysticks_with_conf[i].conf->dev_path, + &ptapi_io_piuio_joysticks_with_conf[i].joystick)) { + log_warn( + "Could not open joystick %s -> %s, ignoring", + ptapi_io_piuio_joysticks_with_conf[i].conf->name, + ptapi_io_piuio_joysticks_with_conf[i].conf->dev_path); + } else { + log_info( + "Opened joystick %s -> %s", + ptapi_io_piuio_joysticks_with_conf[i].conf->name, + ptapi_io_piuio_joysticks_with_conf[i].conf->dev_path); } + } - return true; + return true; } void ptapi_io_piuio_close(void) { - free(ptapi_io_piuio_joystick_util_conf); + free(ptapi_io_piuio_joystick_util_conf); - for (size_t i = 0; i < ptapi_io_piuio_num_active_joysticks; i++) { - if (ptapi_io_piuio_joysticks_with_conf[i].joystick) { - io_util_joystick_close(ptapi_io_piuio_joysticks_with_conf[i].joystick); - } + for (size_t i = 0; i < ptapi_io_piuio_num_active_joysticks; i++) { + if (ptapi_io_piuio_joysticks_with_conf[i].joystick) { + io_util_joystick_close(ptapi_io_piuio_joysticks_with_conf[i].joystick); } + } } bool ptapi_io_piuio_recv(void) { - bool success; + bool success; - success = true; + success = true; - for (size_t i = 0; i < ptapi_io_piuio_num_active_joysticks; i++) { - if (ptapi_io_piuio_joysticks_with_conf[i].joystick) { - success = io_util_joystick_update(ptapi_io_piuio_joysticks_with_conf[i].joystick); + for (size_t i = 0; i < ptapi_io_piuio_num_active_joysticks; i++) { + if (ptapi_io_piuio_joysticks_with_conf[i].joystick) { + success = io_util_joystick_update( + ptapi_io_piuio_joysticks_with_conf[i].joystick); - if (!success) { - log_error("Updating joystick %s -> %s failed", ptapi_io_piuio_joysticks_with_conf[i].conf->name, - ptapi_io_piuio_joysticks_with_conf[i].conf->dev_path); - } - } + if (!success) { + log_error( + "Updating joystick %s -> %s failed", + ptapi_io_piuio_joysticks_with_conf[i].conf->name, + ptapi_io_piuio_joysticks_with_conf[i].conf->dev_path); + } } + } - return success; + return success; } bool ptapi_io_piuio_send(void) { - /* Not supported */ + /* Not supported */ - return true; + return true; } -void ptapi_io_piuio_get_input_pad(uint8_t player, enum ptapi_io_piuio_sensor_group sensor_group, - struct ptapi_io_piuio_pad_inputs* inputs) +void ptapi_io_piuio_get_input_pad( + uint8_t player, + enum ptapi_io_piuio_sensor_group sensor_group, + struct ptapi_io_piuio_pad_inputs *inputs) { - if (player == 0) { - inputs->lu = ptapi_io_piuio_merge_inputs(PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_LU); - inputs->ru = ptapi_io_piuio_merge_inputs(PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_RU); - inputs->cn = ptapi_io_piuio_merge_inputs(PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_CN); - inputs->ld = ptapi_io_piuio_merge_inputs(PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_LD); - inputs->rd = ptapi_io_piuio_merge_inputs(PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_RD); - } else { - inputs->lu = ptapi_io_piuio_merge_inputs(PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P2_LU); - inputs->ru = ptapi_io_piuio_merge_inputs(PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P2_RU); - inputs->cn = ptapi_io_piuio_merge_inputs(PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P2_CN); - inputs->ld = ptapi_io_piuio_merge_inputs(PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P2_LD); - inputs->rd = ptapi_io_piuio_merge_inputs(PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P2_RD); - } + if (player == 0) { + inputs->lu = ptapi_io_piuio_merge_inputs( + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_LU); + inputs->ru = ptapi_io_piuio_merge_inputs( + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_RU); + inputs->cn = ptapi_io_piuio_merge_inputs( + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_CN); + inputs->ld = ptapi_io_piuio_merge_inputs( + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_LD); + inputs->rd = ptapi_io_piuio_merge_inputs( + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P1_RD); + } else { + inputs->lu = ptapi_io_piuio_merge_inputs( + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P2_LU); + inputs->ru = ptapi_io_piuio_merge_inputs( + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P2_RU); + inputs->cn = ptapi_io_piuio_merge_inputs( + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P2_CN); + inputs->ld = ptapi_io_piuio_merge_inputs( + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P2_LD); + inputs->rd = ptapi_io_piuio_merge_inputs( + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_P2_RD); + } } -void ptapi_io_piuio_get_input_sys(struct ptapi_io_piuio_sys_inputs* inputs) +void ptapi_io_piuio_get_input_sys(struct ptapi_io_piuio_sys_inputs *inputs) { - inputs->test = ptapi_io_piuio_merge_inputs(PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_TEST); - inputs->service = ptapi_io_piuio_merge_inputs(PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_SERVICE); - inputs->clear = ptapi_io_piuio_merge_inputs(PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_CLEAR); - inputs->coin = ptapi_io_piuio_merge_inputs(PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_COIN); - inputs->coin2 = ptapi_io_piuio_merge_inputs(PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_COIN2); + inputs->test = + ptapi_io_piuio_merge_inputs(PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_TEST); + inputs->service = ptapi_io_piuio_merge_inputs( + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_SERVICE); + inputs->clear = ptapi_io_piuio_merge_inputs( + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_CLEAR); + inputs->coin = + ptapi_io_piuio_merge_inputs(PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_COIN); + inputs->coin2 = ptapi_io_piuio_merge_inputs( + PTAPI_IO_PIUIO_JOYSTICK_UTIL_CONF_INPUT_COIN2); } -void ptapi_io_piuio_set_output_pad(uint8_t player, const struct ptapi_io_piuio_pad_outputs* outputs) +void ptapi_io_piuio_set_output_pad( + uint8_t player, const struct ptapi_io_piuio_pad_outputs *outputs) { - /* Not supported */ + /* Not supported */ } -void ptapi_io_piuio_set_output_cab(const struct ptapi_io_piuio_cab_outputs* outputs) +void ptapi_io_piuio_set_output_cab( + const struct ptapi_io_piuio_cab_outputs *outputs) { - /* Not supported */ + /* Not supported */ } \ No newline at end of file diff --git a/src/main/ptapi/io/piuio/keyboard-conf/main.c b/src/main/ptapi/io/piuio/keyboard-conf/main.c index 34169df..8cd79a0 100644 --- a/src/main/ptapi/io/piuio/keyboard-conf/main.c +++ b/src/main/ptapi/io/piuio/keyboard-conf/main.c @@ -11,137 +11,152 @@ #define CONFIG_FILENAME "piuio-keyboard-conf.bin" -static Display* display; +static Display *display; static Window window; static uint32_t keyboard_get_next_input() { - XEvent event; - KeySym key; + XEvent event; + KeySym key; - key = 0; + key = 0; - while (true) { - XNextEvent(display, &event); + while (true) { + XNextEvent(display, &event); - if (event.type == KeyPress) { - XLookupString(&event.xkey, 0, 0, &key, 0); - } else if (event.type == KeyRelease) { - break; - } + if (event.type == KeyPress) { + XLookupString(&event.xkey, 0, 0, &key, 0); + } else if (event.type == KeyRelease) { + break; } + } - return key; + return key; } static void menu_keyboard_test() { - printf("Pressed + released inputs:\n"); + printf("Pressed + released inputs:\n"); - while (true) { - printf("%d\n", keyboard_get_next_input()); - } + while (true) { + printf("%d\n", keyboard_get_next_input()); + } } static void menu_keyboard_map() { - struct ptapi_io_piuio_keyboard_util_conf* config; + struct ptapi_io_piuio_keyboard_util_conf *config; - if (!ptapi_io_piuio_keyboard_util_conf_read_from_file(&config, CONFIG_FILENAME)) { - printf("Reading existing config file failed, creating new\n"); + if (!ptapi_io_piuio_keyboard_util_conf_read_from_file( + &config, CONFIG_FILENAME)) { + printf("Reading existing config file failed, creating new\n"); - ptapi_io_piuio_keyboard_util_conf_new(&config); + ptapi_io_piuio_keyboard_util_conf_new(&config); + } else { + printf( + "Found existing mapping entry in config for keyboard, overwriting\n"); + } + + printf( + "A new window with no contents/white background is opened. Ensure to " + "have the application focus on that " + "window to allow input capturing. Otherwise, the tool cannot capture any " + "keyboard inputs!\n"); + + // Delay a moment to avoid picking up any previous keyboard inputs + util_time_sleep_ms(500); + + for (uint32_t i = PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_LU; + i < PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_COUNT; + i++) { + printf( + "Press button to assign to \"%s\" or 'Enter/Return' to skip: ", + ptapi_io_piuio_keyboard_util_conf_input_str[i]); + fflush(stdout); + + config->button_map[i] = keyboard_get_next_input(); + + if (config->button_map[i] == XK_Return) { + config->button_map[i] = 0; + printf("SKIP\n"); } else { - printf("Found existing mapping entry in config for keyboard, overwriting\n"); + printf("%d\n", config->button_map[i]); } + } - printf("A new window with no contents/white background is opened. Ensure to have the application focus on that " - "window to allow input capturing. Otherwise, the tool cannot capture any keyboard inputs!\n"); + ptapi_io_piuio_keyboard_util_conf_write_to_file(config, CONFIG_FILENAME); - // Delay a moment to avoid picking up any previous keyboard inputs - util_time_sleep_ms(500); + free(config); - for (uint32_t i = PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_LU; i < PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_COUNT; - i++) { - printf("Press button to assign to \"%s\" or 'Enter/Return' to skip: ", - ptapi_io_piuio_keyboard_util_conf_input_str[i]); - fflush(stdout); - - config->button_map[i] = keyboard_get_next_input(); - - if (config->button_map[i] == XK_Return) { - config->button_map[i] = 0; - printf("SKIP\n"); - } else { - printf("%d\n", config->button_map[i]); - } - } - - ptapi_io_piuio_keyboard_util_conf_write_to_file(config, CONFIG_FILENAME); - - free(config); - - printf("Configuration file saved: %s\n", CONFIG_FILENAME); + printf("Configuration file saved: %s\n", CONFIG_FILENAME); } -int main(int argc, char** argv) +int main(int argc, char **argv) { - bool main_loop; - int screen; + bool main_loop; + int screen; - util_log_set_file("keyboard-conf.log", false); - util_log_set_level(LOG_LEVEL_ERROR); + util_log_set_file("keyboard-conf.log", false); + util_log_set_level(LOG_LEVEL_ERROR); - display = XOpenDisplay(NULL); + display = XOpenDisplay(NULL); - if (!display) { - printf("Opening display failed\n"); - return -1; + if (!display) { + printf("Opening display failed\n"); + return -1; + } + + screen = DefaultScreen(display); + + window = XCreateSimpleWindow( + display, + RootWindow(display, screen), + 10, + 10, + 200, + 200, + 1, + BlackPixel(display, screen), + WhitePixel(display, screen)); + + XSelectInput(display, window, KeyPressMask | KeyReleaseMask); + XMapWindow(display, window); + + printf("ptapi PIUIO keyboard button mapping config tool\n"); + + main_loop = true; + + while (main_loop) { + uint32_t item; + + printf("Main menu, please select:\n"); + printf("1 > Keyboard input test\n"); + printf("2 > Configure keyboard mappings\n"); + printf("3 > Exit\n"); + printf("Select number: "); + + scanf("%d", &item); + + switch (item) { + case 1: + menu_keyboard_test(); + break; + + case 2: + menu_keyboard_map(); + break; + + case 3: + main_loop = false; + break; + + default: + printf("Invalid item chosen: %d\n", item); + break; } + } - screen = DefaultScreen(display); + XCloseDisplay(display); - window = XCreateSimpleWindow(display, RootWindow(display, screen), 10, 10, 200, 200, 1, - BlackPixel(display, screen), WhitePixel(display, screen)); - - XSelectInput(display, window, KeyPressMask | KeyReleaseMask); - XMapWindow(display, window); - - printf("ptapi PIUIO keyboard button mapping config tool\n"); - - main_loop = true; - - while (main_loop) { - uint32_t item; - - printf("Main menu, please select:\n"); - printf("1 > Keyboard input test\n"); - printf("2 > Configure keyboard mappings\n"); - printf("3 > Exit\n"); - printf("Select number: "); - - scanf("%d", &item); - - switch (item) { - case 1: - menu_keyboard_test(); - break; - - case 2: - menu_keyboard_map(); - break; - - case 3: - main_loop = false; - break; - - default: - printf("Invalid item chosen: %d\n", item); - break; - } - } - - XCloseDisplay(display); - - return 0; + return 0; } \ No newline at end of file diff --git a/src/main/ptapi/io/piuio/keyboard-util/keyboard-conf.c b/src/main/ptapi/io/piuio/keyboard-util/keyboard-conf.c index 604936e..07dc1a3 100644 --- a/src/main/ptapi/io/piuio/keyboard-util/keyboard-conf.c +++ b/src/main/ptapi/io/piuio/keyboard-util/keyboard-conf.c @@ -4,54 +4,58 @@ #include "util/log.h" #include "util/mem.h" -const char* ptapi_io_piuio_keyboard_util_conf_input_str[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_COUNT] = { - "invalid", - "P1 Left Up", - "P1 Right Up", - "P1 Center", - "P1 Left Down", - "P1 Right Down", - "P2 Left Up", - "P2 Right Up", - "P2 Center", - "P2 Left Down", - "P2 Right Down", - "Service", - "Test", - "Coin Clear", - "Coin", - "Coin 2" -}; +const char *ptapi_io_piuio_keyboard_util_conf_input_str + [PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_COUNT] = { + "invalid", + "P1 Left Up", + "P1 Right Up", + "P1 Center", + "P1 Left Down", + "P1 Right Down", + "P2 Left Up", + "P2 Right Up", + "P2 Center", + "P2 Left Down", + "P2 Right Down", + "Service", + "Test", + "Coin Clear", + "Coin", + "Coin 2"}; -void ptapi_io_piuio_keyboard_util_conf_new(struct ptapi_io_piuio_keyboard_util_conf** conf) +void ptapi_io_piuio_keyboard_util_conf_new( + struct ptapi_io_piuio_keyboard_util_conf **conf) { - log_assert(conf); + log_assert(conf); - *conf = util_xmalloc(sizeof(struct ptapi_io_piuio_keyboard_util_conf)); - memset(*conf, 0, sizeof(struct ptapi_io_piuio_keyboard_util_conf)); + *conf = util_xmalloc(sizeof(struct ptapi_io_piuio_keyboard_util_conf)); + memset(*conf, 0, sizeof(struct ptapi_io_piuio_keyboard_util_conf)); } -bool ptapi_io_piuio_keyboard_util_conf_read_from_file(struct ptapi_io_piuio_keyboard_util_conf** conf, const char* path) +bool ptapi_io_piuio_keyboard_util_conf_read_from_file( + struct ptapi_io_piuio_keyboard_util_conf **conf, const char *path) { - log_assert(path); - log_assert(conf); + log_assert(path); + log_assert(conf); - void* buffer; - size_t size; + void *buffer; + size_t size; - if (!util_file_load(path, &buffer, &size, false)) { - return false; - } + if (!util_file_load(path, &buffer, &size, false)) { + return false; + } - *conf = (struct ptapi_io_piuio_keyboard_util_conf*) buffer; + *conf = (struct ptapi_io_piuio_keyboard_util_conf *) buffer; - return true; + return true; } -bool ptapi_io_piuio_keyboard_util_conf_write_to_file(struct ptapi_io_piuio_keyboard_util_conf* conf, const char* path) +bool ptapi_io_piuio_keyboard_util_conf_write_to_file( + struct ptapi_io_piuio_keyboard_util_conf *conf, const char *path) { - log_assert(path); - log_assert(conf); + log_assert(path); + log_assert(conf); - return util_file_save(path, conf, sizeof(struct ptapi_io_piuio_keyboard_util_conf)); + return util_file_save( + path, conf, sizeof(struct ptapi_io_piuio_keyboard_util_conf)); } \ No newline at end of file diff --git a/src/main/ptapi/io/piuio/keyboard-util/keyboard-conf.h b/src/main/ptapi/io/piuio/keyboard-util/keyboard-conf.h index 79f63fb..51857f4 100644 --- a/src/main/ptapi/io/piuio/keyboard-util/keyboard-conf.h +++ b/src/main/ptapi/io/piuio/keyboard-util/keyboard-conf.h @@ -6,35 +6,39 @@ #include "io/util/joystick.h" enum PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT { - PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_INVALID = 0, - PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_LU = 1, - PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_RU = 2, - PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_CN = 3, - PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_LD = 4, - PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_RD = 5, - PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P2_LU = 6, - PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P2_RU = 7, - PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P2_CN = 8, - PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P2_LD = 9, - PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P2_RD = 10, - PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_SERVICE = 11, - PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_TEST = 12, - PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_CLEAR = 13, - PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_COIN = 14, - PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_COIN2 = 15, - PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_COUNT = 16, + PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_INVALID = 0, + PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_LU = 1, + PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_RU = 2, + PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_CN = 3, + PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_LD = 4, + PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_RD = 5, + PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P2_LU = 6, + PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P2_RU = 7, + PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P2_CN = 8, + PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P2_LD = 9, + PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P2_RD = 10, + PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_SERVICE = 11, + PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_TEST = 12, + PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_CLEAR = 13, + PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_COIN = 14, + PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_COIN2 = 15, + PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_COUNT = 16, }; -extern const char* ptapi_io_piuio_keyboard_util_conf_input_str[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_COUNT]; +extern const char *ptapi_io_piuio_keyboard_util_conf_input_str + [PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_COUNT]; struct ptapi_io_piuio_keyboard_util_conf { - uint32_t button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_COUNT]; + uint32_t button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_COUNT]; }; -void ptapi_io_piuio_keyboard_util_conf_new(struct ptapi_io_piuio_keyboard_util_conf** conf); +void ptapi_io_piuio_keyboard_util_conf_new( + struct ptapi_io_piuio_keyboard_util_conf **conf); -bool ptapi_io_piuio_keyboard_util_conf_read_from_file(struct ptapi_io_piuio_keyboard_util_conf** conf, const char* path); +bool ptapi_io_piuio_keyboard_util_conf_read_from_file( + struct ptapi_io_piuio_keyboard_util_conf **conf, const char *path); -bool ptapi_io_piuio_keyboard_util_conf_write_to_file(struct ptapi_io_piuio_keyboard_util_conf* conf, const char* path); +bool ptapi_io_piuio_keyboard_util_conf_write_to_file( + struct ptapi_io_piuio_keyboard_util_conf *conf, const char *path); #endif diff --git a/src/main/ptapi/io/piuio/keyboard/keyboard.c b/src/main/ptapi/io/piuio/keyboard/keyboard.c index 0adf510..8a07c01 100644 --- a/src/main/ptapi/io/piuio/keyboard/keyboard.c +++ b/src/main/ptapi/io/piuio/keyboard/keyboard.c @@ -18,134 +18,157 @@ #define CONFIG_FILENAME "/piuio-keyboard-conf.bin" #define KEY_MAP_SIZE 0xFFFF -struct ptapi_io_piuio_keyboard_util_conf* ptapi_io_piuio_keyboard_conf; +struct ptapi_io_piuio_keyboard_util_conf *ptapi_io_piuio_keyboard_conf; static bool ptapi_io_piuio_keyboard_buffer[KEY_MAP_SIZE]; static void _piuio_emu_keyboard_dispatch_key_press(KeySym key); static void _piuio_emu_keyboard_dispatch_key_release(KeySym key); -static const struct ptapi_io_x11_input_hook_handler _piuio_emu_keyboard_input_hook_handler = { - .dispatch_key_press = _piuio_emu_keyboard_dispatch_key_press, - .dispatch_key_release = _piuio_emu_keyboard_dispatch_key_release, +static const struct ptapi_io_x11_input_hook_handler + _piuio_emu_keyboard_input_hook_handler = { + .dispatch_key_press = _piuio_emu_keyboard_dispatch_key_press, + .dispatch_key_release = _piuio_emu_keyboard_dispatch_key_release, }; -const char* ptapi_io_piuio_ident(void) +const char *ptapi_io_piuio_ident(void) { - return "keyboard"; + return "keyboard"; } -const struct ptapi_io_x11_input_hook_handler* ptapi_io_x11_input_handler_hook(void) +const struct ptapi_io_x11_input_hook_handler * +ptapi_io_x11_input_handler_hook(void) { - return &_piuio_emu_keyboard_input_hook_handler; + return &_piuio_emu_keyboard_input_hook_handler; } bool ptapi_io_piuio_open() { - char path[PATH_MAX]; - char* config_path; + char path[PATH_MAX]; + char *config_path; - // The game changes the working directory to the 'game' sub-folder. Therefore, ./my-config does not work here. - if (!util_proc_get_folder_path_executable_no_ld_linux(path, sizeof(path))) { - log_error("Getting executable folder path failed."); - return false; - } + // The game changes the working directory to the 'game' sub-folder. Therefore, + // ./my-config does not work here. + if (!util_proc_get_folder_path_executable_no_ld_linux(path, sizeof(path))) { + log_error("Getting executable folder path failed."); + return false; + } - config_path = util_str_merge(path, CONFIG_FILENAME); + config_path = util_str_merge(path, CONFIG_FILENAME); - log_info("Loading configuration: ", config_path); - - if (!ptapi_io_piuio_keyboard_util_conf_read_from_file(&ptapi_io_piuio_keyboard_conf, config_path)) { - log_error("Loading keyboard config file %s failed.", config_path); - free(config_path); - return false; - } + log_info("Loading configuration: ", config_path); + if (!ptapi_io_piuio_keyboard_util_conf_read_from_file( + &ptapi_io_piuio_keyboard_conf, config_path)) { + log_error("Loading keyboard config file %s failed.", config_path); free(config_path); + return false; + } - memset(ptapi_io_piuio_keyboard_buffer, 0, sizeof(bool) * KEY_MAP_SIZE); + free(config_path); - return true; + memset(ptapi_io_piuio_keyboard_buffer, 0, sizeof(bool) * KEY_MAP_SIZE); + + return true; } void ptapi_io_piuio_close(void) { - free(ptapi_io_piuio_keyboard_conf); + free(ptapi_io_piuio_keyboard_conf); } bool ptapi_io_piuio_recv(void) { - /* Nothing to poll */ - return true; + /* Nothing to poll */ + return true; } bool ptapi_io_piuio_send(void) { - return true; + return true; } -void ptapi_io_piuio_get_input_pad(uint8_t player, enum ptapi_io_piuio_sensor_group sensor_group, - struct ptapi_io_piuio_pad_inputs* inputs) +void ptapi_io_piuio_get_input_pad( + uint8_t player, + enum ptapi_io_piuio_sensor_group sensor_group, + struct ptapi_io_piuio_pad_inputs *inputs) { - if (player == 0) { - inputs->lu = ptapi_io_piuio_keyboard_buffer[ - ptapi_io_piuio_keyboard_conf->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_LU]]; - inputs->ru = ptapi_io_piuio_keyboard_buffer[ - ptapi_io_piuio_keyboard_conf->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_RU]]; - inputs->cn = ptapi_io_piuio_keyboard_buffer[ - ptapi_io_piuio_keyboard_conf->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_CN]]; - inputs->ld = ptapi_io_piuio_keyboard_buffer[ - ptapi_io_piuio_keyboard_conf->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_LD]]; - inputs->rd = ptapi_io_piuio_keyboard_buffer[ - ptapi_io_piuio_keyboard_conf->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_RD]]; - } else { - inputs->lu = ptapi_io_piuio_keyboard_buffer[ - ptapi_io_piuio_keyboard_conf->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P2_LU]]; - inputs->ru = ptapi_io_piuio_keyboard_buffer[ - ptapi_io_piuio_keyboard_conf->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P2_RU]]; - inputs->cn = ptapi_io_piuio_keyboard_buffer[ - ptapi_io_piuio_keyboard_conf->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P2_CN]]; - inputs->ld = ptapi_io_piuio_keyboard_buffer[ - ptapi_io_piuio_keyboard_conf->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P2_LD]]; - inputs->rd = ptapi_io_piuio_keyboard_buffer[ - ptapi_io_piuio_keyboard_conf->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P2_RD]]; - } + if (player == 0) { + inputs->lu = ptapi_io_piuio_keyboard_buffer + [ptapi_io_piuio_keyboard_conf + ->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_LU]]; + inputs->ru = ptapi_io_piuio_keyboard_buffer + [ptapi_io_piuio_keyboard_conf + ->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_RU]]; + inputs->cn = ptapi_io_piuio_keyboard_buffer + [ptapi_io_piuio_keyboard_conf + ->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_CN]]; + inputs->ld = ptapi_io_piuio_keyboard_buffer + [ptapi_io_piuio_keyboard_conf + ->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_LD]]; + inputs->rd = ptapi_io_piuio_keyboard_buffer + [ptapi_io_piuio_keyboard_conf + ->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P1_RD]]; + } else { + inputs->lu = ptapi_io_piuio_keyboard_buffer + [ptapi_io_piuio_keyboard_conf + ->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P2_LU]]; + inputs->ru = ptapi_io_piuio_keyboard_buffer + [ptapi_io_piuio_keyboard_conf + ->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P2_RU]]; + inputs->cn = ptapi_io_piuio_keyboard_buffer + [ptapi_io_piuio_keyboard_conf + ->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P2_CN]]; + inputs->ld = ptapi_io_piuio_keyboard_buffer + [ptapi_io_piuio_keyboard_conf + ->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P2_LD]]; + inputs->rd = ptapi_io_piuio_keyboard_buffer + [ptapi_io_piuio_keyboard_conf + ->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_P2_RD]]; + } } -void ptapi_io_piuio_get_input_sys(struct ptapi_io_piuio_sys_inputs* inputs) +void ptapi_io_piuio_get_input_sys(struct ptapi_io_piuio_sys_inputs *inputs) { - inputs->test = ptapi_io_piuio_keyboard_buffer[ - ptapi_io_piuio_keyboard_conf->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_TEST]]; - inputs->service = ptapi_io_piuio_keyboard_buffer[ - ptapi_io_piuio_keyboard_conf->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_SERVICE]]; - inputs->clear = ptapi_io_piuio_keyboard_buffer[ - ptapi_io_piuio_keyboard_conf->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_CLEAR]]; - inputs->coin = ptapi_io_piuio_keyboard_buffer[ - ptapi_io_piuio_keyboard_conf->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_COIN]]; - inputs->coin2 = ptapi_io_piuio_keyboard_buffer[ - ptapi_io_piuio_keyboard_conf->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_COIN2]]; + inputs->test = ptapi_io_piuio_keyboard_buffer + [ptapi_io_piuio_keyboard_conf + ->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_TEST]]; + inputs->service = ptapi_io_piuio_keyboard_buffer + [ptapi_io_piuio_keyboard_conf + ->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_SERVICE]]; + inputs->clear = ptapi_io_piuio_keyboard_buffer + [ptapi_io_piuio_keyboard_conf + ->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_CLEAR]]; + inputs->coin = ptapi_io_piuio_keyboard_buffer + [ptapi_io_piuio_keyboard_conf + ->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_COIN]]; + inputs->coin2 = ptapi_io_piuio_keyboard_buffer + [ptapi_io_piuio_keyboard_conf + ->button_map[PTAPI_IO_PIUIO_KEYBOARD_UTIL_CONF_INPUT_COIN2]]; } -void ptapi_io_piuio_set_output_pad(uint8_t player, const struct ptapi_io_piuio_pad_outputs* outputs) +void ptapi_io_piuio_set_output_pad( + uint8_t player, const struct ptapi_io_piuio_pad_outputs *outputs) { - /* Not supported */ + /* Not supported */ } -void ptapi_io_piuio_set_output_cab(const struct ptapi_io_piuio_cab_outputs* outputs) +void ptapi_io_piuio_set_output_cab( + const struct ptapi_io_piuio_cab_outputs *outputs) { - /* Not supported */ + /* Not supported */ } static void _piuio_emu_keyboard_dispatch_key_press(KeySym key) { - if (key > 0 && key < KEY_MAP_SIZE) { - ptapi_io_piuio_keyboard_buffer[key] = true; - } + if (key > 0 && key < KEY_MAP_SIZE) { + ptapi_io_piuio_keyboard_buffer[key] = true; + } } static void _piuio_emu_keyboard_dispatch_key_release(KeySym key) { - if (key > 0 && key < KEY_MAP_SIZE) { - ptapi_io_piuio_keyboard_buffer[key] = false; - } + if (key > 0 && key < KEY_MAP_SIZE) { + ptapi_io_piuio_keyboard_buffer[key] = false; + } } \ No newline at end of file diff --git a/src/main/ptapi/io/piuio/null/null.c b/src/main/ptapi/io/piuio/null/null.c index 7669052..93c8b6a 100644 --- a/src/main/ptapi/io/piuio/null/null.c +++ b/src/main/ptapi/io/piuio/null/null.c @@ -1,55 +1,53 @@ /** - * Implementation of the piuio API. Null driver for testing and starting piu without a real io + * Implementation of the piuio API. Null driver for testing and starting piu + * without a real io */ #define LOG_MODULE "ptapi-io-piuio-null" #include "ptapi/io/piuio.h" -const char* ptapi_io_piuio_ident(void) +const char *ptapi_io_piuio_ident(void) { - return "null"; + return "null"; } bool ptapi_io_piuio_open(void) { - return true; + return true; } void ptapi_io_piuio_close(void) { - } bool ptapi_io_piuio_recv(void) { - return true; + return true; } bool ptapi_io_piuio_send(void) { - return true; + return true; } -void ptapi_io_piuio_get_input_pad(uint8_t player, - enum ptapi_io_piuio_sensor_group sensor_group, - struct ptapi_io_piuio_pad_inputs* inputs) +void ptapi_io_piuio_get_input_pad( + uint8_t player, + enum ptapi_io_piuio_sensor_group sensor_group, + struct ptapi_io_piuio_pad_inputs *inputs) { - } -void ptapi_io_piuio_get_input_sys(struct ptapi_io_piuio_sys_inputs* inputs) +void ptapi_io_piuio_get_input_sys(struct ptapi_io_piuio_sys_inputs *inputs) { - } -void ptapi_io_piuio_set_output_pad(uint8_t player, - const struct ptapi_io_piuio_pad_outputs* outputs) +void ptapi_io_piuio_set_output_pad( + uint8_t player, const struct ptapi_io_piuio_pad_outputs *outputs) { - } void ptapi_io_piuio_set_output_cab( - const struct ptapi_io_piuio_cab_outputs* outputs) + const struct ptapi_io_piuio_cab_outputs *outputs) { - /* Not supported */ + /* Not supported */ } \ No newline at end of file diff --git a/src/main/ptapi/io/piuio/real/piuio.c b/src/main/ptapi/io/piuio/real/piuio.c index d3ed607..ba94841 100644 --- a/src/main/ptapi/io/piuio/real/piuio.c +++ b/src/main/ptapi/io/piuio/real/piuio.c @@ -24,164 +24,171 @@ static struct ptapi_io_piuio_cab_outputs piuio_drv_piuio_cab_out; static void piuio_drv_piuio_copy_outputs(uint8_t sensor_group) { - memset(piuio_drv_piuio_out_buffer, 0, sizeof(piuio_drv_piuio_out_buffer)); + memset(piuio_drv_piuio_out_buffer, 0, sizeof(piuio_drv_piuio_out_buffer)); - /* 00 = sensor 1 (right), 01 = sensor 2 (left), 10 = sensor 3 (down), + /* 00 = sensor 1 (right), 01 = sensor 2 (left), 10 = sensor 3 (down), 11 = sensor 4 (up) */ - /* Pad 1 sensor group selector */ - piuio_drv_piuio_out_buffer[0] |= sensor_group; - /* Pad 2 sensor group selector */ - piuio_drv_piuio_out_buffer[2] |= sensor_group; + /* Pad 1 sensor group selector */ + piuio_drv_piuio_out_buffer[0] |= sensor_group; + /* Pad 2 sensor group selector */ + piuio_drv_piuio_out_buffer[2] |= sensor_group; - /* Set pad lights */ - for (uint8_t i = 0; i < 2; i++) { - if (piuio_drv_piuio_pad_out[i].lu) { - piuio_drv_piuio_out_buffer[i * 2] |= (1 << 2); - } - - if (piuio_drv_piuio_pad_out[i].ru) { - piuio_drv_piuio_out_buffer[i * 2] |= (1 << 3); - } - - if (piuio_drv_piuio_pad_out[i].cn) { - piuio_drv_piuio_out_buffer[i * 2] |= (1 << 4); - } - - if (piuio_drv_piuio_pad_out[i].ld) { - piuio_drv_piuio_out_buffer[i * 2] |= (1 << 5); - } - - if (piuio_drv_piuio_pad_out[i].rd) { - piuio_drv_piuio_out_buffer[i * 2] |= (1 << 6); - } + /* Set pad lights */ + for (uint8_t i = 0; i < 2; i++) { + if (piuio_drv_piuio_pad_out[i].lu) { + piuio_drv_piuio_out_buffer[i * 2] |= (1 << 2); } - /* Neons/Bass */ - if (piuio_drv_piuio_cab_out.bass) { - piuio_drv_piuio_out_buffer[1] |= (1 << 2); + if (piuio_drv_piuio_pad_out[i].ru) { + piuio_drv_piuio_out_buffer[i * 2] |= (1 << 3); } - /* Halogens */ - if (piuio_drv_piuio_cab_out.halo_r2) { - piuio_drv_piuio_out_buffer[2] |= (1 << 7); + if (piuio_drv_piuio_pad_out[i].cn) { + piuio_drv_piuio_out_buffer[i * 2] |= (1 << 4); } - if (piuio_drv_piuio_cab_out.halo_r1) { - piuio_drv_piuio_out_buffer[3] |= (1 << 0); + if (piuio_drv_piuio_pad_out[i].ld) { + piuio_drv_piuio_out_buffer[i * 2] |= (1 << 5); } - if (piuio_drv_piuio_cab_out.halo_l2) { - piuio_drv_piuio_out_buffer[3] |= (1 << 1); + if (piuio_drv_piuio_pad_out[i].rd) { + piuio_drv_piuio_out_buffer[i * 2] |= (1 << 6); } + } - if (piuio_drv_piuio_cab_out.halo_l1) { - piuio_drv_piuio_out_buffer[3] |= (1 << 2); - } + /* Neons/Bass */ + if (piuio_drv_piuio_cab_out.bass) { + piuio_drv_piuio_out_buffer[1] |= (1 << 2); + } - // // set coin counter 1 - // piuio_drv_piuio_out_buffer[3] |= ((m_outputStates->m_counter & 0x01) << 4); + /* Halogens */ + if (piuio_drv_piuio_cab_out.halo_r2) { + piuio_drv_piuio_out_buffer[2] |= (1 << 7); + } - // // set coin counter 2 (front usb enable) - // piuio_drv_piuio_out_buffer[1] |= ((m_outputStates->m_counter & 0x02) << 3); + if (piuio_drv_piuio_cab_out.halo_r1) { + piuio_drv_piuio_out_buffer[3] |= (1 << 0); + } + + if (piuio_drv_piuio_cab_out.halo_l2) { + piuio_drv_piuio_out_buffer[3] |= (1 << 1); + } + + if (piuio_drv_piuio_cab_out.halo_l1) { + piuio_drv_piuio_out_buffer[3] |= (1 << 2); + } + + // // set coin counter 1 + // piuio_drv_piuio_out_buffer[3] |= ((m_outputStates->m_counter & 0x01) << 4); + + // // set coin counter 2 (front usb enable) + // piuio_drv_piuio_out_buffer[1] |= ((m_outputStates->m_counter & 0x02) << 3); } static void piuio_drv_piuio_copy_inputs(uint8_t sensor_group) { - /* Pad */ - for (uint8_t i = 0; i < 2; i++) { - piuio_drv_piuio_pad_in[i][sensor_group].lu = - piuio_drv_piuio_in_buffer[i * 2] & (1 << 0); - piuio_drv_piuio_pad_in[i][sensor_group].ru = - piuio_drv_piuio_in_buffer[i * 2] & (1 << 1); - piuio_drv_piuio_pad_in[i][sensor_group].cn = - piuio_drv_piuio_in_buffer[i * 2] & (1 << 2); - piuio_drv_piuio_pad_in[i][sensor_group].ld = - piuio_drv_piuio_in_buffer[i * 2] & (1 << 3); - piuio_drv_piuio_pad_in[i][sensor_group].rd = - piuio_drv_piuio_in_buffer[i * 2] & (1 << 4); - } + /* Pad */ + for (uint8_t i = 0; i < 2; i++) { + piuio_drv_piuio_pad_in[i][sensor_group].lu = + piuio_drv_piuio_in_buffer[i * 2] & (1 << 0); + piuio_drv_piuio_pad_in[i][sensor_group].ru = + piuio_drv_piuio_in_buffer[i * 2] & (1 << 1); + piuio_drv_piuio_pad_in[i][sensor_group].cn = + piuio_drv_piuio_in_buffer[i * 2] & (1 << 2); + piuio_drv_piuio_pad_in[i][sensor_group].ld = + piuio_drv_piuio_in_buffer[i * 2] & (1 << 3); + piuio_drv_piuio_pad_in[i][sensor_group].rd = + piuio_drv_piuio_in_buffer[i * 2] & (1 << 4); + } - /* Sys */ - piuio_drv_piuio_sys.test = piuio_drv_piuio_in_buffer[1] & (1 << 1); - piuio_drv_piuio_sys.service = piuio_drv_piuio_in_buffer[1] & (1 << 6); - piuio_drv_piuio_sys.clear = piuio_drv_piuio_in_buffer[1] & (1 << 7); - piuio_drv_piuio_sys.coin = piuio_drv_piuio_in_buffer[1] & (1 << 2); + /* Sys */ + piuio_drv_piuio_sys.test = piuio_drv_piuio_in_buffer[1] & (1 << 1); + piuio_drv_piuio_sys.service = piuio_drv_piuio_in_buffer[1] & (1 << 6); + piuio_drv_piuio_sys.clear = piuio_drv_piuio_in_buffer[1] & (1 << 7); + piuio_drv_piuio_sys.coin = piuio_drv_piuio_in_buffer[1] & (1 << 2); - memset(piuio_drv_piuio_in_buffer, 0, sizeof(piuio_drv_piuio_in_buffer)); + memset(piuio_drv_piuio_in_buffer, 0, sizeof(piuio_drv_piuio_in_buffer)); } -const char* ptapi_io_piuio_ident(void) +const char *ptapi_io_piuio_ident(void) { - return "piuio"; + return "piuio"; } bool ptapi_io_piuio_open(void) { - return piuio_drv_device_open(); + return piuio_drv_device_open(); } void ptapi_io_piuio_close(void) { - piuio_drv_device_close(); + piuio_drv_device_close(); } bool ptapi_io_piuio_recv(void) { - /* cycle all four sensor groups */ - for (uint8_t i = 0; i < PTAPI_IO_PIUIO_SENSOR_GROUP_NUM; i++) { - piuio_drv_piuio_copy_outputs(i); + /* cycle all four sensor groups */ + for (uint8_t i = 0; i < PTAPI_IO_PIUIO_SENSOR_GROUP_NUM; i++) { + piuio_drv_piuio_copy_outputs(i); - if (!piuio_drv_device_write(piuio_drv_piuio_out_buffer, - sizeof(piuio_drv_piuio_out_buffer))) { - return false; - } - - if (!piuio_drv_device_read(piuio_drv_piuio_in_buffer, - sizeof(piuio_drv_piuio_in_buffer))) { - return false; - } - - /* Invert pull ups */ - for (uint8_t j = 0; j < 4; j++) { - piuio_drv_piuio_in_buffer[j] ^= 0xFF; - } - - piuio_drv_piuio_copy_inputs(i); + if (!piuio_drv_device_write( + piuio_drv_piuio_out_buffer, sizeof(piuio_drv_piuio_out_buffer))) { + return false; } - return true; + if (!piuio_drv_device_read( + piuio_drv_piuio_in_buffer, sizeof(piuio_drv_piuio_in_buffer))) { + return false; + } + + /* Invert pull ups */ + for (uint8_t j = 0; j < 4; j++) { + piuio_drv_piuio_in_buffer[j] ^= 0xFF; + } + + piuio_drv_piuio_copy_inputs(i); + } + + return true; } bool ptapi_io_piuio_send(void) { - /* Already done in recv */ - return true; + /* Already done in recv */ + return true; } -void ptapi_io_piuio_get_input_pad(uint8_t player, - enum ptapi_io_piuio_sensor_group sensor_group, - struct ptapi_io_piuio_pad_inputs* inputs) +void ptapi_io_piuio_get_input_pad( + uint8_t player, + enum ptapi_io_piuio_sensor_group sensor_group, + struct ptapi_io_piuio_pad_inputs *inputs) { - memcpy(inputs, &piuio_drv_piuio_pad_in[player][sensor_group], - sizeof(struct ptapi_io_piuio_pad_inputs)); + memcpy( + inputs, + &piuio_drv_piuio_pad_in[player][sensor_group], + sizeof(struct ptapi_io_piuio_pad_inputs)); } -void ptapi_io_piuio_get_input_sys(struct ptapi_io_piuio_sys_inputs* inputs) +void ptapi_io_piuio_get_input_sys(struct ptapi_io_piuio_sys_inputs *inputs) { - memcpy(inputs, &piuio_drv_piuio_sys, - sizeof(struct ptapi_io_piuio_sys_inputs)); + memcpy( + inputs, &piuio_drv_piuio_sys, sizeof(struct ptapi_io_piuio_sys_inputs)); } -void ptapi_io_piuio_set_output_pad(uint8_t player, - const struct ptapi_io_piuio_pad_outputs* outputs) +void ptapi_io_piuio_set_output_pad( + uint8_t player, const struct ptapi_io_piuio_pad_outputs *outputs) { - memcpy(&piuio_drv_piuio_pad_out[player], outputs, - sizeof(struct ptapi_io_piuio_pad_outputs)); + memcpy( + &piuio_drv_piuio_pad_out[player], + outputs, + sizeof(struct ptapi_io_piuio_pad_outputs)); } void ptapi_io_piuio_set_output_cab( - const struct ptapi_io_piuio_cab_outputs* outputs) + const struct ptapi_io_piuio_cab_outputs *outputs) { - memcpy(&piuio_drv_piuio_cab_out, outputs, - sizeof(struct ptapi_io_piuio_cab_outputs)); + memcpy( + &piuio_drv_piuio_cab_out, + outputs, + sizeof(struct ptapi_io_piuio_cab_outputs)); } \ No newline at end of file diff --git a/src/main/ptapi/io/piuio/test/main.c b/src/main/ptapi/io/piuio/test/main.c index 437d681..8e8f98a 100644 --- a/src/main/ptapi/io/piuio/test/main.c +++ b/src/main/ptapi/io/piuio/test/main.c @@ -1,8 +1,8 @@ /** * Tool to test implementations of the piuio API */ -#include #include +#include #include #include @@ -13,169 +13,169 @@ static struct ptapi_io_piuio_api api; -int main(int argc, char** argv) +int main(int argc, char **argv) { - struct ptapi_io_piuio_pad_inputs - pad_in[2][PTAPI_IO_PIUIO_SENSOR_GROUP_NUM]; - struct ptapi_io_piuio_sys_inputs sys_in; - struct ptapi_io_piuio_pad_outputs pad_out[2]; - struct ptapi_io_piuio_cab_outputs cab_out; + struct ptapi_io_piuio_pad_inputs pad_in[2][PTAPI_IO_PIUIO_SENSOR_GROUP_NUM]; + struct ptapi_io_piuio_sys_inputs sys_in; + struct ptapi_io_piuio_pad_outputs pad_out[2]; + struct ptapi_io_piuio_cab_outputs cab_out; - util_log_set_file("piuio-test.log", false); - util_log_set_level(LOG_LEVEL_ERROR); + util_log_set_file("piuio-test.log", false); + util_log_set_level(LOG_LEVEL_ERROR); - if (argc < 2) { - printf( - "Usage: %s [debug]\n", - argv[0]); - return -1; + if (argc < 2) { + printf("Usage: %s [debug]\n", argv[0]); + return -1; + } + + for (int i = 0; i < argc; i++) { + if (!strcmp(argv[i], "debug")) { + util_log_set_level(LOG_LEVEL_DEBUG); + break; + } + } + + if (!ptapi_io_piuio_util_lib_load(argv[1], &api)) { + printf("Loading piuio lib %s failed\n", argv[1]); + return -2; + } + + if (!api.open()) { + return -3; + } + + memset(&pad_in, 0, sizeof(pad_in)); + memset(&sys_in, 0, sizeof(sys_in)); + memset(&pad_out, 0, sizeof(pad_out)); + memset(&cab_out, 0, sizeof(cab_out)); + + printf("Enter main loop by pressing any key (on the keyboard)\n"); + getchar(); + + while (true) { + if (!api.recv()) { + return -4; } - for (int i = 0; i < argc; i++) { - if (!strcmp(argv[i], "debug")) { - util_log_set_level(LOG_LEVEL_DEBUG); - break; - } + for (uint8_t i = 0; i < 2; i++) { + for (uint8_t j = 0; j < PTAPI_IO_PIUIO_SENSOR_GROUP_NUM; j++) { + api.get_input_pad(i, j, &pad_in[i][j]); + } } - if (!ptapi_io_piuio_util_lib_load(argv[1], &api)) { - printf("Loading piuio lib %s failed\n", argv[1]); - return -2; + api.get_input_sys(&sys_in); + + if (sys_in.test && sys_in.service) { + break; } - if (!api.open()) { - return -3; - } + system("clear"); + + printf("Press test + service to exit\n"); + printf( + "| Test %d Service %d Clear %d Coin %d |\n" + "|-------------------||-------------------|\n" + "| %d %d || %d %d |\n" + "|%d %d %d %d||%d %d %d %d|\n" + "| %d %d || %d %d |\n" + "| %d || %d |\n" + "| %d %d || %d %d |\n" + "| %d || %d |\n" + "| %d %d || %d %d |\n" + "|%d %d %d %d||%d %d %d %d|\n" + "| %d %d || %d %d |\n" + "|-------------------||-------------------|\n", + sys_in.test, + sys_in.service, + sys_in.clear, + sys_in.coin, + + pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_UP].lu, + pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_UP].ru, + pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_UP].lu, + pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_UP].ru, + + pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT].lu, + pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT].lu, + pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT].ru, + pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT].ru, + pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT].lu, + pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT].lu, + pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT].ru, + pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT].ru, + + pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN].lu, + pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN].ru, + pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN].lu, + pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN].ru, + + pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_UP].cn, + pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_UP].cn, + + pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT].cn, + pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT].cn, + pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT].cn, + pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT].cn, + + pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN].cn, + pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN].cn, + + pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_UP].ld, + pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_UP].rd, + pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_UP].ld, + pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_UP].rd, + + pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT].ld, + pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT].ld, + pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT].rd, + pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT].rd, + pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT].ld, + pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT].ld, + pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT].rd, + pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT].rd, + + pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN].ld, + pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN].rd, + pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN].ld, + pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN].rd); - memset(&pad_in, 0, sizeof(pad_in)); - memset(&sys_in, 0, sizeof(sys_in)); memset(&pad_out, 0, sizeof(pad_out)); - memset(&cab_out, 0, sizeof(cab_out)); - printf("Enter main loop by pressing any key (on the keyboard)\n"); - getchar(); - - while (true) { - if (!api.recv()) { - return -4; + for (int i = 0; i < 2; i++) { + for (int j = 0; j < PTAPI_IO_PIUIO_SENSOR_GROUP_NUM; j++) { + if (pad_in[i][j].lu) { + pad_out[i].lu = true; } - for (uint8_t i = 0; i < 2; i++) { - for (uint8_t j = 0; j < PTAPI_IO_PIUIO_SENSOR_GROUP_NUM; j++) { - api.get_input_pad(i, j, &pad_in[i][j]); - } + if (pad_in[i][j].ru) { + pad_out[i].ru = true; } - api.get_input_sys(&sys_in); - - if (sys_in.test && sys_in.service) { - break; + if (pad_in[i][j].cn) { + pad_out[i].cn = true; } - system("clear"); - - printf("Press test + service to exit\n"); - printf( - "| Test %d Service %d Clear %d Coin %d |\n" - "|-------------------||-------------------|\n" - "| %d %d || %d %d |\n" - "|%d %d %d %d||%d %d %d %d|\n" - "| %d %d || %d %d |\n" - "| %d || %d |\n" - "| %d %d || %d %d |\n" - "| %d || %d |\n" - "| %d %d || %d %d |\n" - "|%d %d %d %d||%d %d %d %d|\n" - "| %d %d || %d %d |\n" - "|-------------------||-------------------|\n", - sys_in.test, sys_in.service, sys_in.clear, sys_in.coin, - - pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_UP].lu, - pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_UP].ru, - pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_UP].lu, - pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_UP].ru, - - pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT].lu, - pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT].lu, - pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT].ru, - pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT].ru, - pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT].lu, - pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT].lu, - pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT].ru, - pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT].ru, - - pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN].lu, - pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN].ru, - pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN].lu, - pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN].ru, - - pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_UP].cn, - pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_UP].cn, - - pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT].cn, - pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT].cn, - pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT].cn, - pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT].cn, - - pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN].cn, - pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN].cn, - - pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_UP].ld, - pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_UP].rd, - pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_UP].ld, - pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_UP].rd, - - pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT].ld, - pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT].ld, - pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT].rd, - pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT].rd, - pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT].ld, - pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT].ld, - pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_LEFT].rd, - pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_RIGHT].rd, - - pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN].ld, - pad_in[0][PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN].rd, - pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN].ld, - pad_in[1][PTAPI_IO_PIUIO_SENSOR_GROUP_DOWN].rd); - - memset(&pad_out, 0, sizeof(pad_out)); - - for (int i = 0; i < 2; i++) { - for (int j = 0; j < PTAPI_IO_PIUIO_SENSOR_GROUP_NUM; j++) { - if (pad_in[i][j].lu) { - pad_out[i].lu = true; - } - - if (pad_in[i][j].ru) { - pad_out[i].ru = true; - } - - if (pad_in[i][j].cn) { - pad_out[i].cn = true; - } - - if (pad_in[i][j].ld) { - pad_out[i].ld = true; - } - - if (pad_in[i][j].rd) { - pad_out[i].rd = true; - } - } - - api.set_output_pad(i, &pad_out[i]); + if (pad_in[i][j].ld) { + pad_out[i].ld = true; } - if (!api.send()) { - return -5; + if (pad_in[i][j].rd) { + pad_out[i].rd = true; } + } - /* Avoid hardware banging */ - usleep(1000); + api.set_output_pad(i, &pad_out[i]); } - api.close(); + if (!api.send()) { + return -5; + } - return 0; + /* Avoid hardware banging */ + usleep(1000); + } + + api.close(); + + return 0; } \ No newline at end of file diff --git a/src/main/ptapi/io/piuio/util/lib.c b/src/main/ptapi/io/piuio/util/lib.c index 7d15d7b..5634a12 100644 --- a/src/main/ptapi/io/piuio/util/lib.c +++ b/src/main/ptapi/io/piuio/util/lib.c @@ -4,35 +4,40 @@ #include "ptapi/io/piuio/util/lib.h" -bool ptapi_io_piuio_util_lib_load(const char* path, struct ptapi_io_piuio_api* api) +bool ptapi_io_piuio_util_lib_load( + const char *path, struct ptapi_io_piuio_api *api) { - void* handle; + void *handle; - handle = cnh_lib_load(path); + handle = cnh_lib_load(path); - if (handle == NULL) { - return false; - } + if (handle == NULL) { + return false; + } - api->ident = (ptapi_io_piuio_ident_t) cnh_lib_get_func_addr_handle( - handle, "ptapi_io_piuio_ident"); + api->ident = (ptapi_io_piuio_ident_t) cnh_lib_get_func_addr_handle( + handle, "ptapi_io_piuio_ident"); - api->open = (ptapi_io_piuio_open_t) cnh_lib_get_func_addr_handle( - handle, "ptapi_io_piuio_open"); - api->close = (ptapi_io_piuio_close_t) cnh_lib_get_func_addr_handle( - handle, "ptapi_io_piuio_close"); - api->recv = (ptapi_io_piuio_recv_t) cnh_lib_get_func_addr_handle( - handle, "ptapi_io_piuio_recv"); - api->send = (ptapi_io_piuio_send_t) cnh_lib_get_func_addr_handle( - handle, "ptapi_io_piuio_send"); - api->get_input_pad = (ptapi_io_piuio_get_input_pad_t) - cnh_lib_get_func_addr_handle(handle, "ptapi_io_piuio_get_input_pad"); - api->get_input_sys = (ptapi_io_piuio_get_input_sys_t) - cnh_lib_get_func_addr_handle(handle, "ptapi_io_piuio_get_input_sys"); - api->set_output_pad = (ptapi_io_piuio_set_output_pad_t) - cnh_lib_get_func_addr_handle(handle, "ptapi_io_piuio_set_output_pad"); - api->set_output_cab = (ptapi_io_piuio_set_output_cab_t) - cnh_lib_get_func_addr_handle(handle, "ptapi_io_piuio_set_output_cab"); + api->open = (ptapi_io_piuio_open_t) cnh_lib_get_func_addr_handle( + handle, "ptapi_io_piuio_open"); + api->close = (ptapi_io_piuio_close_t) cnh_lib_get_func_addr_handle( + handle, "ptapi_io_piuio_close"); + api->recv = (ptapi_io_piuio_recv_t) cnh_lib_get_func_addr_handle( + handle, "ptapi_io_piuio_recv"); + api->send = (ptapi_io_piuio_send_t) cnh_lib_get_func_addr_handle( + handle, "ptapi_io_piuio_send"); + api->get_input_pad = + (ptapi_io_piuio_get_input_pad_t) cnh_lib_get_func_addr_handle( + handle, "ptapi_io_piuio_get_input_pad"); + api->get_input_sys = + (ptapi_io_piuio_get_input_sys_t) cnh_lib_get_func_addr_handle( + handle, "ptapi_io_piuio_get_input_sys"); + api->set_output_pad = + (ptapi_io_piuio_set_output_pad_t) cnh_lib_get_func_addr_handle( + handle, "ptapi_io_piuio_set_output_pad"); + api->set_output_cab = + (ptapi_io_piuio_set_output_cab_t) cnh_lib_get_func_addr_handle( + handle, "ptapi_io_piuio_set_output_cab"); - return true; + return true; } \ No newline at end of file diff --git a/src/main/ptapi/io/piuio/util/lib.h b/src/main/ptapi/io/piuio/util/lib.h index e564b1a..36049d2 100644 --- a/src/main/ptapi/io/piuio/util/lib.h +++ b/src/main/ptapi/io/piuio/util/lib.h @@ -3,6 +3,7 @@ #include "ptapi/io/piuio.h" -bool ptapi_io_piuio_util_lib_load(const char* path, struct ptapi_io_piuio_api* api); +bool ptapi_io_piuio_util_lib_load( + const char *path, struct ptapi_io_piuio_api *api); #endif diff --git a/src/main/pumpnet/client/main.c b/src/main/pumpnet/client/main.c index 143fe6d..68f3aae 100644 --- a/src/main/pumpnet/client/main.c +++ b/src/main/pumpnet/client/main.c @@ -12,104 +12,109 @@ #include "util/log.h" #include "util/mem.h" -static void _print_usage_and_exit(const char* program_name) +static void _print_usage_and_exit(const char *program_name) { - log_info("Usage: %s " - "", program_name); - exit(EXIT_FAILURE); + log_info( + "Usage: %s " + "", + program_name); + exit(EXIT_FAILURE); } static size_t _get_size_save_file(enum asset_game_version game_version) { - switch (game_version) { - case ASSET_GAME_VERSION_NX2: - return ASSET_NX2_USB_SAVE_SIZE; + switch (game_version) { + case ASSET_GAME_VERSION_NX2: + return ASSET_NX2_USB_SAVE_SIZE; - default: - log_die_illegal_state(); - return 0; - } + default: + log_die_illegal_state(); + return 0; + } } static size_t _get_size_rank_file(enum asset_game_version game_version) { - switch (game_version) { - case ASSET_GAME_VERSION_NX2: - return ASSET_NX2_USB_RANK_SIZE; + switch (game_version) { + case ASSET_GAME_VERSION_NX2: + return ASSET_NX2_USB_RANK_SIZE; - default: - log_die_illegal_state(); - return 0; - } + default: + log_die_illegal_state(); + return 0; + } } -static size_t _get_size_usb_file(enum asset_game_version game_version, enum pumpnet_lib_file_type file_type) +static size_t _get_size_usb_file( + enum asset_game_version game_version, enum pumpnet_lib_file_type file_type) { - switch (file_type) { - case PUMPNET_LIB_FILE_TYPE_SAVE: - return _get_size_save_file(game_version); + switch (file_type) { + case PUMPNET_LIB_FILE_TYPE_SAVE: + return _get_size_save_file(game_version); - case PUMPNET_LIB_FILE_TYPE_RANK: - return _get_size_rank_file(game_version); + case PUMPNET_LIB_FILE_TYPE_RANK: + return _get_size_rank_file(game_version); - default: - log_die_illegal_state(); - return 0; - } + default: + log_die_illegal_state(); + return 0; + } } -int main(int argc, char** argv) +int main(int argc, char **argv) { - util_log_set_level(LOG_LEVEL_DEBUG); + util_log_set_level(LOG_LEVEL_DEBUG); - if (argc < 8) { - _print_usage_and_exit(argv[0]); - } + if (argc < 8) { + _print_usage_and_exit(argv[0]); + } - const char* server_addr = argv[1]; - const char* cmd = argv[2]; - enum asset_game_version game_version = strtol(argv[3], NULL, 10); - enum pumpnet_lib_file_type file_type = strtol(argv[4], NULL, 10); - uint64_t machine_id = strtol(argv[5], NULL, 16); - uint64_t player_ref_id = strtol(argv[6], NULL, 16); - const char* file_path = argv[7]; + const char *server_addr = argv[1]; + const char *cmd = argv[2]; + enum asset_game_version game_version = strtol(argv[3], NULL, 10); + enum pumpnet_lib_file_type file_type = strtol(argv[4], NULL, 10); + uint64_t machine_id = strtol(argv[5], NULL, 16); + uint64_t player_ref_id = strtol(argv[6], NULL, 16); + const char *file_path = argv[7]; - bool success; + bool success; - pumpnet_lib_init(game_version, server_addr, machine_id, NULL, true); + pumpnet_lib_init(game_version, server_addr, machine_id, NULL, true); - if (!strcmp(cmd, "put")) { - size_t size; - void* buffer; + if (!strcmp(cmd, "put")) { + size_t size; + void *buffer; - if (!util_file_load(file_path, &buffer, &size, false)) { - log_error("Loading data from %s failed", file_path); - success = false; - } else { - success = pumpnet_lib_put(file_type, player_ref_id, buffer, sizeof(buffer)); - } - } else if (!strcmp(cmd, "get")) { - size_t buffer_size = _get_size_usb_file(game_version, file_type); - uint8_t* buffer = malloc(buffer_size); - - success = pumpnet_lib_get(file_type, player_ref_id, buffer, sizeof(buffer)); - - if (success) { - if (!util_file_save(file_path, buffer, buffer_size)) { - log_error("Saving data to %s, size %d failed", file_path, buffer_size); - success = false; - } - } + if (!util_file_load(file_path, &buffer, &size, false)) { + log_error("Loading data from %s failed", file_path); + success = false; } else { - log_error("Invalid command %s", cmd); - success = false; + success = + pumpnet_lib_put(file_type, player_ref_id, buffer, sizeof(buffer)); } + } else if (!strcmp(cmd, "get")) { + size_t buffer_size = _get_size_usb_file(game_version, file_type); + uint8_t *buffer = malloc(buffer_size); - pumpnet_lib_shutdown(); + success = pumpnet_lib_get(file_type, player_ref_id, buffer, sizeof(buffer)); if (success) { - exit(EXIT_SUCCESS); - } else { - exit(EXIT_FAILURE); + if (!util_file_save(file_path, buffer, buffer_size)) { + log_error("Saving data to %s, size %d failed", file_path, buffer_size); + success = false; + } } + } else { + log_error("Invalid command %s", cmd); + success = false; + } + + pumpnet_lib_shutdown(); + + if (success) { + exit(EXIT_SUCCESS); + } else { + exit(EXIT_FAILURE); + } } \ No newline at end of file diff --git a/src/main/pumpnet/lib/http.c b/src/main/pumpnet/lib/http.c index 91a4df5..fbfff83 100644 --- a/src/main/pumpnet/lib/http.c +++ b/src/main/pumpnet/lib/http.c @@ -16,282 +16,305 @@ #define CA_BUNDLE_CRT "/ca-bundle-crt.pem" struct pumpnet_lib_http_buffer { - void* data; - size_t size; - size_t pos; + void *data; + size_t size; + size_t pos; }; -static size_t _pumpnet_lib_http_curl_cb_write_data(void* ptr, size_t size, size_t nmemb, void* ctx) +static size_t _pumpnet_lib_http_curl_cb_write_data( + void *ptr, size_t size, size_t nmemb, void *ctx) { - struct pumpnet_lib_http_buffer* buffer; + struct pumpnet_lib_http_buffer *buffer; - buffer = (struct pumpnet_lib_http_buffer*) ctx; + buffer = (struct pumpnet_lib_http_buffer *) ctx; - if (buffer->pos == buffer->size) { - return 0; - } + if (buffer->pos == buffer->size) { + return 0; + } - if (buffer->pos + size * nmemb >= buffer->size) { - log_error("Buffer overflow, pos %d, size %d | size %d, nmemb %d", - buffer->pos, - buffer->size, - size, - nmemb); - return 0; - } + if (buffer->pos + size * nmemb >= buffer->size) { + log_error( + "Buffer overflow, pos %d, size %d | size %d, nmemb %d", + buffer->pos, + buffer->size, + size, + nmemb); + return 0; + } - memcpy(buffer->data + buffer->pos, ptr, size * nmemb); - buffer->pos += size * nmemb; + memcpy(buffer->data + buffer->pos, ptr, size * nmemb); + buffer->pos += size * nmemb; - return size * nmemb; + return size * nmemb; } -static size_t _pumpnet_lib_http_curl_cb_read_data(void* ptr, size_t size, size_t nmemb, void* ctx) +static size_t _pumpnet_lib_http_curl_cb_read_data( + void *ptr, size_t size, size_t nmemb, void *ctx) { - struct pumpnet_lib_http_buffer* buffer; - size_t max_size; - size_t read; + struct pumpnet_lib_http_buffer *buffer; + size_t max_size; + size_t read; - max_size = size * nmemb; + max_size = size * nmemb; - buffer = (struct pumpnet_lib_http_buffer*) ctx; + buffer = (struct pumpnet_lib_http_buffer *) ctx; - if (buffer->size == buffer->pos) { - return 0; - } + if (buffer->size == buffer->pos) { + return 0; + } - if (buffer->size - buffer->pos < max_size) { - read = buffer->size - buffer->pos; - } else { - read = max_size; - } + if (buffer->size - buffer->pos < max_size) { + read = buffer->size - buffer->pos; + } else { + read = max_size; + } - memcpy(ptr, buffer->data + buffer->pos, read); + memcpy(ptr, buffer->data + buffer->pos, read); - buffer->pos += read; + buffer->pos += read; - return read; + return read; } int _pumpnet_libcurl_debug_callback( - CURL *handle, - curl_infotype type, - char *data, - size_t size, - void *userptr) + CURL *handle, curl_infotype type, char *data, size_t size, void *userptr) { - char* null_term_buffer; + char *null_term_buffer; - switch (type) { - case CURLINFO_TEXT: - log_debug("[CURL]: %s", data); - break; + switch (type) { + case CURLINFO_TEXT: + log_debug("[CURL]: %s", data); + break; - case CURLINFO_HEADER_IN: - case CURLINFO_HEADER_OUT: - null_term_buffer = util_xmalloc(size + 1); - memcpy(null_term_buffer, data, size); - null_term_buffer[size] = '\0'; + case CURLINFO_HEADER_IN: + case CURLINFO_HEADER_OUT: + null_term_buffer = util_xmalloc(size + 1); + memcpy(null_term_buffer, data, size); + null_term_buffer[size] = '\0'; - log_debug("[CURL]: %d (%p), len %ld:\n%s", type, handle, size, data); + log_debug("[CURL]: %d (%p), len %ld:\n%s", type, handle, size, data); - free(null_term_buffer); - break; - case CURLINFO_DATA_IN: - case CURLINFO_DATA_OUT: - case CURLINFO_SSL_DATA_OUT: - case CURLINFO_SSL_DATA_IN: - log_debug("[CURL]: %d (%p), len %ld", type, handle, size); - break; - default: - log_die_illegal_state(); - } + free(null_term_buffer); + break; + case CURLINFO_DATA_IN: + case CURLINFO_DATA_OUT: + case CURLINFO_SSL_DATA_OUT: + case CURLINFO_SSL_DATA_IN: + log_debug("[CURL]: %d (%p), len %ld", type, handle, size); + break; + default: + log_die_illegal_state(); + } - return 0; + return 0; } -static char* pumpnet_lib_http_client_crt_path; -static char* pumpnet_lib_http_client_key_path; -static char* pumpnet_lib_http_ca_bundle_crt_path; +static char *pumpnet_lib_http_client_crt_path; +static char *pumpnet_lib_http_client_key_path; +static char *pumpnet_lib_http_ca_bundle_crt_path; static bool pumpnet_lib_http_verbose_debug_log; -void pumpnet_lib_http_init(const char* cert_dir_path, bool verbose_debug_log) +void pumpnet_lib_http_init(const char *cert_dir_path, bool verbose_debug_log) { - if (cert_dir_path) { - char* absolute_path = util_fs_get_abs_path(cert_dir_path); + if (cert_dir_path) { + char *absolute_path = util_fs_get_abs_path(cert_dir_path); - pumpnet_lib_http_client_crt_path = util_str_merge(absolute_path, CLIENT_CRT); - pumpnet_lib_http_client_key_path = util_str_merge(absolute_path, CLIENT_KEY); - pumpnet_lib_http_ca_bundle_crt_path = util_str_merge(absolute_path, CA_BUNDLE_CRT); + pumpnet_lib_http_client_crt_path = + util_str_merge(absolute_path, CLIENT_CRT); + pumpnet_lib_http_client_key_path = + util_str_merge(absolute_path, CLIENT_KEY); + pumpnet_lib_http_ca_bundle_crt_path = + util_str_merge(absolute_path, CA_BUNDLE_CRT); - free(absolute_path); - } + free(absolute_path); + } - pumpnet_lib_http_verbose_debug_log = verbose_debug_log; + pumpnet_lib_http_verbose_debug_log = verbose_debug_log; - log_info("Initialized, client crt %s, client key %s, ca bundle crt %s, verbose debug log %d", - pumpnet_lib_http_client_crt_path, - pumpnet_lib_http_client_key_path, - pumpnet_lib_http_ca_bundle_crt_path, - verbose_debug_log); + log_info( + "Initialized, client crt %s, client key %s, ca bundle crt %s, verbose " + "debug log %d", + pumpnet_lib_http_client_crt_path, + pumpnet_lib_http_client_key_path, + pumpnet_lib_http_ca_bundle_crt_path, + verbose_debug_log); } void pumpnet_lib_http_shutdown() { - if (pumpnet_lib_http_client_crt_path) { - free(pumpnet_lib_http_client_crt_path); - } + if (pumpnet_lib_http_client_crt_path) { + free(pumpnet_lib_http_client_crt_path); + } - if (pumpnet_lib_http_client_key_path) { - free(pumpnet_lib_http_client_key_path); - } + if (pumpnet_lib_http_client_key_path) { + free(pumpnet_lib_http_client_key_path); + } - if (pumpnet_lib_http_ca_bundle_crt_path) { - free(pumpnet_lib_http_ca_bundle_crt_path); - } + if (pumpnet_lib_http_ca_bundle_crt_path) { + free(pumpnet_lib_http_ca_bundle_crt_path); + } } bool pumpnet_lib_http_get_put( - uint64_t trace_id, - const char* address, - void* send_data, - size_t send_size, - void* recv_data, - size_t recv_size, - uint32_t* http_code, - bool is_post) + uint64_t trace_id, + const char *address, + void *send_data, + size_t send_size, + void *recv_data, + size_t recv_size, + uint32_t *http_code, + bool is_post) { - log_assert(address); - log_assert(send_data); - log_assert(recv_data); - log_assert(http_code); + log_assert(address); + log_assert(send_data); + log_assert(recv_data); + log_assert(http_code); - CURL* curl_handle; - CURLcode res; - struct pumpnet_lib_http_buffer send_buffer; - struct pumpnet_lib_http_buffer recv_buffer; - struct curl_slist* host = NULL; + CURL *curl_handle; + CURLcode res; + struct pumpnet_lib_http_buffer send_buffer; + struct pumpnet_lib_http_buffer recv_buffer; + struct curl_slist *host = NULL; - *http_code = 0; + *http_code = 0; - curl_handle = curl_easy_init(); + curl_handle = curl_easy_init(); - if (!curl_handle) { - log_error("[%llX] Initializing curl backend failed", trace_id); - return false; - } + if (!curl_handle) { + log_error("[%llX] Initializing curl backend failed", trace_id); + return false; + } - send_buffer.data = util_base64_encode(send_data, send_size, &send_buffer.size); - send_buffer.pos = 0; + send_buffer.data = + util_base64_encode(send_data, send_size, &send_buffer.size); + send_buffer.pos = 0; - recv_buffer.data = util_xmalloc(RECV_BUFFER_SIZE); - recv_buffer.size = RECV_BUFFER_SIZE; - recv_buffer.pos = 0; + recv_buffer.data = util_xmalloc(RECV_BUFFER_SIZE); + recv_buffer.size = RECV_BUFFER_SIZE; + recv_buffer.pos = 0; - if (is_post) { - curl_easy_setopt(curl_handle, CURLOPT_POST, 1L); - } else { - curl_easy_setopt(curl_handle, CURLOPT_POST, 1L); - curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "GET"); - } + if (is_post) { + curl_easy_setopt(curl_handle, CURLOPT_POST, 1L); + } else { + curl_easy_setopt(curl_handle, CURLOPT_POST, 1L); + curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "GET"); + } - if (pumpnet_lib_http_verbose_debug_log) { - curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1); - curl_easy_setopt(curl_handle, CURLOPT_DEBUGFUNCTION, _pumpnet_libcurl_debug_callback); - } + if (pumpnet_lib_http_verbose_debug_log) { + curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1); + curl_easy_setopt( + curl_handle, CURLOPT_DEBUGFUNCTION, _pumpnet_libcurl_debug_callback); + } - if (pumpnet_lib_http_client_crt_path) { - host = curl_slist_append(NULL, "pumpnet:443:185.41.243.94"); - curl_easy_setopt(curl_handle, CURLOPT_RESOLVE, host); - curl_easy_setopt(curl_handle, CURLOPT_SSLCERT, pumpnet_lib_http_client_crt_path); - curl_easy_setopt(curl_handle, CURLOPT_SSLKEY, pumpnet_lib_http_client_key_path); - curl_easy_setopt(curl_handle, CURLOPT_SSLKEYTYPE, "PEM"); - curl_easy_setopt(curl_handle, CURLOPT_CAINFO, pumpnet_lib_http_ca_bundle_crt_path); - curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 1); - } + if (pumpnet_lib_http_client_crt_path) { + host = curl_slist_append(NULL, "pumpnet:443:185.41.243.94"); + curl_easy_setopt(curl_handle, CURLOPT_RESOLVE, host); + curl_easy_setopt( + curl_handle, CURLOPT_SSLCERT, pumpnet_lib_http_client_crt_path); + curl_easy_setopt( + curl_handle, CURLOPT_SSLKEY, pumpnet_lib_http_client_key_path); + curl_easy_setopt(curl_handle, CURLOPT_SSLKEYTYPE, "PEM"); + curl_easy_setopt( + curl_handle, CURLOPT_CAINFO, pumpnet_lib_http_ca_bundle_crt_path); + curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 1); + } - // It seems like some libcurl revisions cut off the content after processing it using the provided - // CURLOPT_READFUNCTION if the size is not force set like this - curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, send_buffer.size); + // It seems like some libcurl revisions cut off the content after processing + // it using the provided CURLOPT_READFUNCTION if the size is not force set + // like this + curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, send_buffer.size); - curl_easy_setopt(curl_handle, CURLOPT_URL, address); - curl_easy_setopt(curl_handle, CURLOPT_READFUNCTION, _pumpnet_lib_http_curl_cb_read_data); - curl_easy_setopt(curl_handle, CURLOPT_READDATA, &send_buffer); - curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, _pumpnet_lib_http_curl_cb_write_data); - curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &recv_buffer); + curl_easy_setopt(curl_handle, CURLOPT_URL, address); + curl_easy_setopt( + curl_handle, CURLOPT_READFUNCTION, _pumpnet_lib_http_curl_cb_read_data); + curl_easy_setopt(curl_handle, CURLOPT_READDATA, &send_buffer); + curl_easy_setopt( + curl_handle, CURLOPT_WRITEFUNCTION, _pumpnet_lib_http_curl_cb_write_data); + curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &recv_buffer); - struct curl_slist *hs=NULL; - hs = curl_slist_append(hs, "Content-Type: " MEDIA_TYPE); - curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, hs); + struct curl_slist *hs = NULL; + hs = curl_slist_append(hs, "Content-Type: " MEDIA_TYPE); + curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, hs); - log_debug("[%llX][%s] %s %d %d", trace_id, address, is_post ? "POST" : "GET", send_size, recv_size); + log_debug( + "[%llX][%s] %s %d %d", + trace_id, + address, + is_post ? "POST" : "GET", + send_size, + recv_size); - res = curl_easy_perform(curl_handle); + res = curl_easy_perform(curl_handle); - curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, http_code); + curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, http_code); - log_debug("[%llX][%s] %s: %d (%d %d)", + log_debug( + "[%llX][%s] %s: %d (%d %d)", + trace_id, + address, + is_post ? "POST" : "GET", + *http_code, + recv_buffer.pos, + send_buffer.pos); + + if (host) { + curl_slist_free_all(host); + } + + curl_slist_free_all(hs); + + curl_easy_cleanup(curl_handle); + + if (res != CURLE_OK) { + log_error( + "[%llX][%s][%d] Performing curl request failed: %s", trace_id, address, - is_post ? "POST" : "GET", - *http_code, - recv_buffer.pos, - send_buffer.pos); - - if (host) { - curl_slist_free_all(host); - } - - curl_slist_free_all(hs); - - curl_easy_cleanup(curl_handle); - - if (res != CURLE_OK) { - log_error("[%llX][%s][%d] Performing curl request failed: %s", - trace_id, - address, - is_post, - curl_easy_strerror(res)); - - free(send_buffer.data); - free(recv_buffer.data); - return false; - } - - if (send_buffer.pos != send_buffer.size) { - log_error("[%llX][%s][%d] Invalid send data size: %d != %d", - trace_id, - address, - is_post, - send_buffer.pos, - send_buffer.size); - - free(send_buffer.data); - free(recv_buffer.data); - return false; - } + is_post, + curl_easy_strerror(res)); free(send_buffer.data); - - size_t recv_size_decoded; - uint8_t* tmp_recv_decoded = util_base64_decode(recv_buffer.data, recv_buffer.pos, &recv_size_decoded); - free(recv_buffer.data); + return false; + } - if (recv_size_decoded != recv_size) { - log_error("[%llX][%s][%d] Invalid recv data size: %d != %d", - trace_id, - address, - is_post, - recv_size_decoded, - recv_size); + if (send_buffer.pos != send_buffer.size) { + log_error( + "[%llX][%s][%d] Invalid send data size: %d != %d", + trace_id, + address, + is_post, + send_buffer.pos, + send_buffer.size); - free(tmp_recv_decoded); - return false; - } + free(send_buffer.data); + free(recv_buffer.data); + return false; + } + + free(send_buffer.data); + + size_t recv_size_decoded; + uint8_t *tmp_recv_decoded = + util_base64_decode(recv_buffer.data, recv_buffer.pos, &recv_size_decoded); + + free(recv_buffer.data); + + if (recv_size_decoded != recv_size) { + log_error( + "[%llX][%s][%d] Invalid recv data size: %d != %d", + trace_id, + address, + is_post, + recv_size_decoded, + recv_size); - memcpy(recv_data, tmp_recv_decoded, recv_size); free(tmp_recv_decoded); + return false; + } - return true; + memcpy(recv_data, tmp_recv_decoded, recv_size); + free(tmp_recv_decoded); + + return true; } \ No newline at end of file diff --git a/src/main/pumpnet/lib/http.h b/src/main/pumpnet/lib/http.h index 312fb8e..52edf2c 100644 --- a/src/main/pumpnet/lib/http.h +++ b/src/main/pumpnet/lib/http.h @@ -7,16 +7,16 @@ #define HTTP_CODE_OK 200 #define HTTP_CODE_PRECONDITION_FAILED 412 -void pumpnet_lib_http_init(const char* cert_dir_path, bool verbose_debug_log); +void pumpnet_lib_http_init(const char *cert_dir_path, bool verbose_debug_log); void pumpnet_lib_http_shutdown(); bool pumpnet_lib_http_get_put( - uint64_t trace_id, - const char* address, - void* send_data, - size_t send_size, - void* recv_data, - size_t recv_size, - uint32_t* http_code, - bool is_post); \ No newline at end of file + uint64_t trace_id, + const char *address, + void *send_data, + size_t send_size, + void *recv_data, + size_t recv_size, + uint32_t *http_code, + bool is_post); \ No newline at end of file diff --git a/src/main/pumpnet/lib/profile-token.c b/src/main/pumpnet/lib/profile-token.c index 5ac22a9..6630239 100644 --- a/src/main/pumpnet/lib/profile-token.c +++ b/src/main/pumpnet/lib/profile-token.c @@ -8,37 +8,37 @@ #include "util/log.h" -bool pumpnet_lib_profile_token_load(const char* path, uint64_t* profile_id) +bool pumpnet_lib_profile_token_load(const char *path, uint64_t *profile_id) { - FILE* file = fopen(path, "rb"); - ssize_t size; + FILE *file = fopen(path, "rb"); + ssize_t size; - if (!file) { - *profile_id = PUMPNET_LIB_PROFILE_TOKEN_INVALID; - return false; - } + if (!file) { + *profile_id = PUMPNET_LIB_PROFILE_TOKEN_INVALID; + return false; + } - // TODO file needs to be encrypted + // TODO file needs to be encrypted - fseek(file, 0, SEEK_END); - size = ftell(file); - - if (size != 8) { - fclose(file); - *profile_id = PUMPNET_LIB_PROFILE_TOKEN_INVALID; - log_error("Invalid file size (%d) for pumpnet profile %s", size, path); - return false; - } - - fseek(file, 0, SEEK_SET); - - if (fread(profile_id, 8, 1, file) != 1) { - fclose(file); - *profile_id = PUMPNET_LIB_PROFILE_TOKEN_INVALID; - log_error("Reading pumpnet profile %s failed: %s", path, strerror(errno)); - return false; - } + fseek(file, 0, SEEK_END); + size = ftell(file); + if (size != 8) { fclose(file); - return true; + *profile_id = PUMPNET_LIB_PROFILE_TOKEN_INVALID; + log_error("Invalid file size (%d) for pumpnet profile %s", size, path); + return false; + } + + fseek(file, 0, SEEK_SET); + + if (fread(profile_id, 8, 1, file) != 1) { + fclose(file); + *profile_id = PUMPNET_LIB_PROFILE_TOKEN_INVALID; + log_error("Reading pumpnet profile %s failed: %s", path, strerror(errno)); + return false; + } + + fclose(file); + return true; } \ No newline at end of file diff --git a/src/main/pumpnet/lib/profile-token.h b/src/main/pumpnet/lib/profile-token.h index 6776d19..85f7393 100644 --- a/src/main/pumpnet/lib/profile-token.h +++ b/src/main/pumpnet/lib/profile-token.h @@ -10,6 +10,6 @@ #define PUMPNET_LIB_PROFILE_TOKEN_INVALID 0xFFFFFFFFFFFFFFFF -bool pumpnet_lib_profile_token_load(const char* path, uint64_t* profile_id); +bool pumpnet_lib_profile_token_load(const char *path, uint64_t *profile_id); #endif diff --git a/src/main/pumpnet/lib/protocol.h b/src/main/pumpnet/lib/protocol.h index a3743ca..63bc7db 100644 --- a/src/main/pumpnet/lib/protocol.h +++ b/src/main/pumpnet/lib/protocol.h @@ -7,33 +7,33 @@ #define USBPROFILE_ENDPOINT "/usbprofile/v1" struct pumpnet_lib_get_save_req { - uint64_t trace_id; - uint64_t machine_id; - uint64_t player_ref_id; + uint64_t trace_id; + uint64_t machine_id; + uint64_t player_ref_id; } __attribute__((__packed__)); struct pumpnet_lib_get_save_resp { - size_t size; - uint8_t data[]; + size_t size; + uint8_t data[]; } __attribute__((__packed__)); struct pumpnet_lib_get_rank_req { - uint64_t trace_id; - uint64_t machine_id; - uint64_t player_ref_id; + uint64_t trace_id; + uint64_t machine_id; + uint64_t player_ref_id; } __attribute__((__packed__)); struct pumpnet_lib_get_rank_resp { - size_t size; - uint8_t data[]; + size_t size; + uint8_t data[]; } __attribute__((__packed__)); struct pumpnet_lib_put_save_req { - uint64_t trace_id; - uint64_t machine_id; - uint64_t player_ref_id; - size_t size; - uint8_t data[]; + uint64_t trace_id; + uint64_t machine_id; + uint64_t player_ref_id; + size_t size; + uint8_t data[]; } __attribute__((__packed__)); struct pumpnet_lib_put_save_resp { @@ -41,11 +41,11 @@ struct pumpnet_lib_put_save_resp { } __attribute__((__packed__)); struct pumpnet_lib_put_rank_req { - uint64_t trace_id; - uint64_t machine_id; - uint64_t player_ref_id; - size_t size; - uint8_t data[]; + uint64_t trace_id; + uint64_t machine_id; + uint64_t player_ref_id; + size_t size; + uint8_t data[]; } __attribute__((__packed__)); struct pumpnet_lib_put_rank_resp { diff --git a/src/main/pumpnet/lib/pumpnet.c b/src/main/pumpnet/lib/pumpnet.c index 3ec46f7..57a4a69 100644 --- a/src/main/pumpnet/lib/pumpnet.c +++ b/src/main/pumpnet/lib/pumpnet.c @@ -16,328 +16,354 @@ #define RETRY_TIME_BACKOFF_MS 2000 static enum asset_game_version pumpnet_lib_game; -static char* pumpnet_lib_server_addr; +static char *pumpnet_lib_server_addr; static uint64_t pumpnet_lib_machine_id; -static char* pumpnet_lib_server_endpoint_save; -static char* pumpnet_lib_server_endpoint_rank; +static char *pumpnet_lib_server_endpoint_save; +static char *pumpnet_lib_server_endpoint_rank; -static char* _pumpnet_lib_get_endpoint_save(enum asset_game_version game, const char* server_addr) +static char *_pumpnet_lib_get_endpoint_save( + enum asset_game_version game, const char *server_addr) { - switch (game) { - case ASSET_GAME_VERSION_NX2: - return util_str_merge(server_addr, USBPROFILE_ENDPOINT "/nx2/save"); + switch (game) { + case ASSET_GAME_VERSION_NX2: + return util_str_merge(server_addr, USBPROFILE_ENDPOINT "/nx2/save"); - default: - log_die("Unsupported game version %d", game); - return NULL; - } + default: + log_die("Unsupported game version %d", game); + return NULL; + } } -static char* _pumpnet_lib_get_endpoint_rank(enum asset_game_version game, const char* server_addr) +static char *_pumpnet_lib_get_endpoint_rank( + enum asset_game_version game, const char *server_addr) { - switch (game) { - case ASSET_GAME_VERSION_NX2: - return util_str_merge(server_addr, USBPROFILE_ENDPOINT "/nx2/rank"); + switch (game) { + case ASSET_GAME_VERSION_NX2: + return util_str_merge(server_addr, USBPROFILE_ENDPOINT "/nx2/rank"); - default: - log_die("Unsupported game version %d", game); - return NULL; - } + default: + log_die("Unsupported game version %d", game); + return NULL; + } } static uint64_t _pumpnet_lib_generate_tracing_id() { - return util_rand_gen_64(); + return util_rand_gen_64(); } static bool _pumpnet_lib_get_put( - uint64_t trace_id, - const char* endpoint, - void* req_buffer, - size_t req_size, - void* resp_buffer, - size_t resp_size, - bool is_post) + uint64_t trace_id, + const char *endpoint, + void *req_buffer, + size_t req_size, + void *resp_buffer, + size_t resp_size, + bool is_post) { - uint32_t http_code; - bool success; + uint32_t http_code; + bool success; - http_code = 0; - success = false; + http_code = 0; + success = false; - for (int i = 0; i < RETRY_COUNT_ON_ERROR; i++) { - success = pumpnet_lib_http_get_put( - trace_id, - endpoint, - req_buffer, - req_size, - resp_buffer, - resp_size, - &http_code, - is_post); + for (int i = 0; i < RETRY_COUNT_ON_ERROR; i++) { + success = pumpnet_lib_http_get_put( + trace_id, + endpoint, + req_buffer, + req_size, + resp_buffer, + resp_size, + &http_code, + is_post); - if (http_code == 0 || http_code == HTTP_CODE_PRECONDITION_FAILED) { - log_warn("[%llX][%s][%s] Failed, http code %d, retrying (%d)...", - trace_id, - is_post ? "post" : "get", - endpoint, - http_code, - i); + if (http_code == 0 || http_code == HTTP_CODE_PRECONDITION_FAILED) { + log_warn( + "[%llX][%s][%s] Failed, http code %d, retrying (%d)...", + trace_id, + is_post ? "post" : "get", + endpoint, + http_code, + i); - util_time_sleep_ms(RETRY_TIME_BACKOFF_MS); - } else { - break; - } + util_time_sleep_ms(RETRY_TIME_BACKOFF_MS); + } else { + break; } + } - if (!success) { - log_error("[%llX][%s][%s] Failed", trace_id, is_post ? "post" : "get", endpoint); + if (!success) { + log_error( + "[%llX][%s][%s] Failed", trace_id, is_post ? "post" : "get", endpoint); - return false; - } else if (http_code != 200) { - log_error("[%llX][%s][%s] Get non successful: %d", trace_id, is_post ? "post" : "get", endpoint, http_code); - return false; - } + return false; + } else if (http_code != 200) { + log_error( + "[%llX][%s][%s] Get non successful: %d", + trace_id, + is_post ? "post" : "get", + endpoint, + http_code); + return false; + } - return true; + return true; } -static bool _pumpnet_lib_get_rank(uint64_t player_ref_id, void* buffer, size_t size) +static bool +_pumpnet_lib_get_rank(uint64_t player_ref_id, void *buffer, size_t size) { - log_assert(buffer); + log_assert(buffer); - struct pumpnet_lib_get_rank_req req; - struct pumpnet_lib_get_rank_resp* resp; - size_t resp_size; - uint64_t trace_id; + struct pumpnet_lib_get_rank_req req; + struct pumpnet_lib_get_rank_resp *resp; + size_t resp_size; + uint64_t trace_id; - trace_id = _pumpnet_lib_generate_tracing_id(); + trace_id = _pumpnet_lib_generate_tracing_id(); - req.trace_id = trace_id; - req.machine_id = pumpnet_lib_machine_id; - req.player_ref_id = player_ref_id; + req.trace_id = trace_id; + req.machine_id = pumpnet_lib_machine_id; + req.player_ref_id = player_ref_id; - resp_size = sizeof(struct pumpnet_lib_get_rank_resp) + size; - resp = util_xmalloc(resp_size); + resp_size = sizeof(struct pumpnet_lib_get_rank_resp) + size; + resp = util_xmalloc(resp_size); - log_info("[%llX][%llX] Get rank", trace_id, player_ref_id); - - if (!_pumpnet_lib_get_put( - trace_id, - pumpnet_lib_server_endpoint_rank, - &req, - sizeof(req), - resp, - resp_size, - false)) { - free(resp); - return false; - } - - if (resp->size > size) { - log_error("[%llX] Rank resp size greater than buffer size: %d > %d", - trace_id, - resp->size, - size); - free(resp); - return false; - } - - memcpy(buffer, resp->data, resp->size); + log_info("[%llX][%llX] Get rank", trace_id, player_ref_id); + if (!_pumpnet_lib_get_put( + trace_id, + pumpnet_lib_server_endpoint_rank, + &req, + sizeof(req), + resp, + resp_size, + false)) { free(resp); + return false; + } - return true; -} - -static bool _pumpnet_lib_get_save(uint64_t player_ref_id, void* buffer, size_t size) -{ - log_assert(buffer); - - struct pumpnet_lib_get_save_req req; - struct pumpnet_lib_get_save_resp* resp; - size_t resp_size; - uint64_t trace_id; - - trace_id = _pumpnet_lib_generate_tracing_id(); - - req.trace_id = trace_id; - req.machine_id = pumpnet_lib_machine_id; - req.player_ref_id = player_ref_id; - - resp_size = sizeof(struct pumpnet_lib_get_save_resp) + size; - resp = util_xmalloc(resp_size); - - log_info("[%llX][%llX] Get save", trace_id, player_ref_id); - - if (!_pumpnet_lib_get_put( - trace_id, - pumpnet_lib_server_endpoint_save, - &req, - sizeof(req), - resp, - resp_size, - false)) { - free(resp); - return false; - } - - if (resp->size > size) { - log_error("[%llX] Save resp size greater than buffer size: %d > %d", - trace_id, - resp->size, - size); - free(resp); - return false; - } - - memcpy(buffer, resp->data, resp->size); - + if (resp->size > size) { + log_error( + "[%llX] Rank resp size greater than buffer size: %d > %d", + trace_id, + resp->size, + size); free(resp); + return false; + } - return true; + memcpy(buffer, resp->data, resp->size); + + free(resp); + + return true; } -static bool _pumpnet_lib_put_rank(uint64_t player_ref_id, const void* buffer, size_t size) +static bool +_pumpnet_lib_get_save(uint64_t player_ref_id, void *buffer, size_t size) { - log_assert(buffer); + log_assert(buffer); - struct pumpnet_lib_put_rank_req* req; - struct pumpnet_lib_put_rank_resp resp; - size_t req_size; - uint64_t trace_id; + struct pumpnet_lib_get_save_req req; + struct pumpnet_lib_get_save_resp *resp; + size_t resp_size; + uint64_t trace_id; - trace_id = _pumpnet_lib_generate_tracing_id(); + trace_id = _pumpnet_lib_generate_tracing_id(); - req_size = sizeof(struct pumpnet_lib_put_rank_req) + size; - req = util_xmalloc(req_size); + req.trace_id = trace_id; + req.machine_id = pumpnet_lib_machine_id; + req.player_ref_id = player_ref_id; - req->trace_id = trace_id; - req->machine_id = pumpnet_lib_machine_id; - req->player_ref_id = player_ref_id; - req->size = size; - memcpy(req->data, buffer, size); + resp_size = sizeof(struct pumpnet_lib_get_save_resp) + size; + resp = util_xmalloc(resp_size); - log_info("[%llX][%llX] Put rank", trace_id, player_ref_id); + log_info("[%llX][%llX] Get save", trace_id, player_ref_id); - if (!_pumpnet_lib_get_put( - trace_id, - pumpnet_lib_server_endpoint_rank, - req, - req_size, - &resp, - sizeof(resp), - true)) { - free(req); - return false; - } + if (!_pumpnet_lib_get_put( + trace_id, + pumpnet_lib_server_endpoint_save, + &req, + sizeof(req), + resp, + resp_size, + false)) { + free(resp); + return false; + } - free(req); + if (resp->size > size) { + log_error( + "[%llX] Save resp size greater than buffer size: %d > %d", + trace_id, + resp->size, + size); + free(resp); + return false; + } - return true; + memcpy(buffer, resp->data, resp->size); + + free(resp); + + return true; } -static bool _pumpnet_lib_put_save(uint64_t player_ref_id, const void* buffer, size_t size) +static bool +_pumpnet_lib_put_rank(uint64_t player_ref_id, const void *buffer, size_t size) { - log_assert(buffer); + log_assert(buffer); - struct pumpnet_lib_put_save_req* req; - struct pumpnet_lib_put_save_resp resp; - size_t req_size; - uint64_t trace_id; + struct pumpnet_lib_put_rank_req *req; + struct pumpnet_lib_put_rank_resp resp; + size_t req_size; + uint64_t trace_id; - trace_id = _pumpnet_lib_generate_tracing_id(); + trace_id = _pumpnet_lib_generate_tracing_id(); - req_size = sizeof(struct pumpnet_lib_put_save_req) + size; - req = util_xmalloc(req_size); + req_size = sizeof(struct pumpnet_lib_put_rank_req) + size; + req = util_xmalloc(req_size); - req->trace_id = trace_id; - req->machine_id = pumpnet_lib_machine_id; - req->player_ref_id = player_ref_id; - req->size = size; - memcpy(req->data, buffer, size); + req->trace_id = trace_id; + req->machine_id = pumpnet_lib_machine_id; + req->player_ref_id = player_ref_id; + req->size = size; + memcpy(req->data, buffer, size); - log_info("[%llX][%llX] Put save", trace_id, player_ref_id); - - if (!_pumpnet_lib_get_put( - trace_id, - pumpnet_lib_server_endpoint_save, - req, - req_size, - &resp, - sizeof(resp), - true)) { - free(req); - return false; - } + log_info("[%llX][%llX] Put rank", trace_id, player_ref_id); + if (!_pumpnet_lib_get_put( + trace_id, + pumpnet_lib_server_endpoint_rank, + req, + req_size, + &resp, + sizeof(resp), + true)) { free(req); + return false; + } - return true; + free(req); + + return true; +} + +static bool +_pumpnet_lib_put_save(uint64_t player_ref_id, const void *buffer, size_t size) +{ + log_assert(buffer); + + struct pumpnet_lib_put_save_req *req; + struct pumpnet_lib_put_save_resp resp; + size_t req_size; + uint64_t trace_id; + + trace_id = _pumpnet_lib_generate_tracing_id(); + + req_size = sizeof(struct pumpnet_lib_put_save_req) + size; + req = util_xmalloc(req_size); + + req->trace_id = trace_id; + req->machine_id = pumpnet_lib_machine_id; + req->player_ref_id = player_ref_id; + req->size = size; + memcpy(req->data, buffer, size); + + log_info("[%llX][%llX] Put save", trace_id, player_ref_id); + + if (!_pumpnet_lib_get_put( + trace_id, + pumpnet_lib_server_endpoint_save, + req, + req_size, + &resp, + sizeof(resp), + true)) { + free(req); + return false; + } + + free(req); + + return true; } void pumpnet_lib_init( - enum asset_game_version game, - const char* server_addr, - uint64_t machine_id, - const char* cert_dir_path, - bool verbose_debug_log) + enum asset_game_version game, + const char *server_addr, + uint64_t machine_id, + const char *cert_dir_path, + bool verbose_debug_log) { - pumpnet_lib_http_init(cert_dir_path, verbose_debug_log); + pumpnet_lib_http_init(cert_dir_path, verbose_debug_log); - pumpnet_lib_game = game; - pumpnet_lib_server_addr = util_str_dup(server_addr); - pumpnet_lib_machine_id = machine_id; + pumpnet_lib_game = game; + pumpnet_lib_server_addr = util_str_dup(server_addr); + pumpnet_lib_machine_id = machine_id; - pumpnet_lib_server_endpoint_save = _pumpnet_lib_get_endpoint_save(game, server_addr); - pumpnet_lib_server_endpoint_rank = _pumpnet_lib_get_endpoint_rank(game, server_addr); + pumpnet_lib_server_endpoint_save = + _pumpnet_lib_get_endpoint_save(game, server_addr); + pumpnet_lib_server_endpoint_rank = + _pumpnet_lib_get_endpoint_rank(game, server_addr); - log_info("Initialized pumpnet for game %d, serveraddr %s, main endpoint version %s", - pumpnet_lib_game, - pumpnet_lib_server_addr, - USBPROFILE_ENDPOINT); + log_info( + "Initialized pumpnet for game %d, serveraddr %s, main endpoint version " + "%s", + pumpnet_lib_game, + pumpnet_lib_server_addr, + USBPROFILE_ENDPOINT); } void pumpnet_lib_shutdown() { - free(pumpnet_lib_server_endpoint_save); - free(pumpnet_lib_server_endpoint_rank); + free(pumpnet_lib_server_endpoint_save); + free(pumpnet_lib_server_endpoint_rank); - pumpnet_lib_http_shutdown(); + pumpnet_lib_http_shutdown(); - log_info("Shut down"); + log_info("Shut down"); } -bool pumpnet_lib_get(enum pumpnet_lib_file_type file_type, uint64_t player_ref_id, void* buffer, size_t size) +bool pumpnet_lib_get( + enum pumpnet_lib_file_type file_type, + uint64_t player_ref_id, + void *buffer, + size_t size) { - switch (file_type) { - case PUMPNET_LIB_FILE_TYPE_SAVE: - return _pumpnet_lib_get_save(player_ref_id, buffer, size); + switch (file_type) { + case PUMPNET_LIB_FILE_TYPE_SAVE: + return _pumpnet_lib_get_save(player_ref_id, buffer, size); - case PUMPNET_LIB_FILE_TYPE_RANK: - return _pumpnet_lib_get_rank(player_ref_id, buffer, size); + case PUMPNET_LIB_FILE_TYPE_RANK: + return _pumpnet_lib_get_rank(player_ref_id, buffer, size); - case PUMPNET_LIB_FILE_TYPE_COUNT: - default: - log_die_illegal_state(); - return false; - } + case PUMPNET_LIB_FILE_TYPE_COUNT: + default: + log_die_illegal_state(); + return false; + } } -bool pumpnet_lib_put(enum pumpnet_lib_file_type file_type, uint64_t player_ref_id, const void* buffer, size_t size) +bool pumpnet_lib_put( + enum pumpnet_lib_file_type file_type, + uint64_t player_ref_id, + const void *buffer, + size_t size) { - switch (file_type) { - case PUMPNET_LIB_FILE_TYPE_SAVE: - return _pumpnet_lib_put_save(player_ref_id, buffer, size); + switch (file_type) { + case PUMPNET_LIB_FILE_TYPE_SAVE: + return _pumpnet_lib_put_save(player_ref_id, buffer, size); - case PUMPNET_LIB_FILE_TYPE_RANK: - return _pumpnet_lib_put_rank(player_ref_id, buffer, size); + case PUMPNET_LIB_FILE_TYPE_RANK: + return _pumpnet_lib_put_rank(player_ref_id, buffer, size); - case PUMPNET_LIB_FILE_TYPE_COUNT: - default: - log_die_illegal_state(); - return false; - } + case PUMPNET_LIB_FILE_TYPE_COUNT: + default: + log_die_illegal_state(); + return false; + } } - diff --git a/src/main/pumpnet/lib/pumpnet.h b/src/main/pumpnet/lib/pumpnet.h index 1494e21..f55066d 100644 --- a/src/main/pumpnet/lib/pumpnet.h +++ b/src/main/pumpnet/lib/pumpnet.h @@ -12,22 +12,30 @@ #include "asset/game-version.h" enum pumpnet_lib_file_type { - PUMPNET_LIB_FILE_TYPE_SAVE = 0, - PUMPNET_LIB_FILE_TYPE_RANK = 1, - PUMPNET_LIB_FILE_TYPE_COUNT = 2, + PUMPNET_LIB_FILE_TYPE_SAVE = 0, + PUMPNET_LIB_FILE_TYPE_RANK = 1, + PUMPNET_LIB_FILE_TYPE_COUNT = 2, }; void pumpnet_lib_init( - enum asset_game_version game, - const char* server_addr, - uint64_t machine_id, - const char* cert_dir_path, - bool verbose_debug_log); + enum asset_game_version game, + const char *server_addr, + uint64_t machine_id, + const char *cert_dir_path, + bool verbose_debug_log); void pumpnet_lib_shutdown(); -bool pumpnet_lib_get(enum pumpnet_lib_file_type file_type, uint64_t player_ref_id, void* buffer, size_t size); +bool pumpnet_lib_get( + enum pumpnet_lib_file_type file_type, + uint64_t player_ref_id, + void *buffer, + size_t size); -bool pumpnet_lib_put(enum pumpnet_lib_file_type file_type, uint64_t player_ref_id, const void* buffer, size_t size); +bool pumpnet_lib_put( + enum pumpnet_lib_file_type file_type, + uint64_t player_ref_id, + const void *buffer, + size_t size); #endif diff --git a/src/main/sec/hasp/lib/asn1.c b/src/main/sec/hasp/lib/asn1.c index 8d0f4f5..420b883 100644 --- a/src/main/sec/hasp/lib/asn1.c +++ b/src/main/sec/hasp/lib/asn1.c @@ -7,512 +7,553 @@ #include "asn1.h" -static uint32_t sec_hasp_asn1_decode_int(const uint8_t* buffer, size_t* offset, uint32_t blen); -static uint8_t* sec_hasp_asn1_decode_data(const uint8_t* buffer, size_t* offset, uint32_t blen); -static char* sec_hasp_asn1_decode_str(const uint8_t* buffer, size_t* offset, uint32_t blen); -static uint32_t sec_hasp_asn1_decode_length(const uint8_t* buffer, size_t* offset); -static uint16_t sec_hasp_asn1_decode_tag(const uint8_t* buffer, size_t* offset); -static void sec_hasp_asn1_encode_int(uint32_t val, uint8_t* buffer, size_t* offset); -static void sec_hasp_asn1_encode_data(const uint8_t* data, size_t len, uint8_t* buffer, size_t* offset); -static void sec_hasp_asn1_encode_str(const char* str, uint8_t* buffer, size_t* offset); -static void sec_hasp_asn1_encode_length(uint32_t len, uint8_t* buffer, size_t* offset); -static void sec_hasp_asn1_encode_tag(uint16_t tag, uint8_t* buffer, size_t* offset); +static uint32_t +sec_hasp_asn1_decode_int(const uint8_t *buffer, size_t *offset, uint32_t blen); +static uint8_t * +sec_hasp_asn1_decode_data(const uint8_t *buffer, size_t *offset, uint32_t blen); +static char * +sec_hasp_asn1_decode_str(const uint8_t *buffer, size_t *offset, uint32_t blen); +static uint32_t +sec_hasp_asn1_decode_length(const uint8_t *buffer, size_t *offset); +static uint16_t sec_hasp_asn1_decode_tag(const uint8_t *buffer, size_t *offset); +static void +sec_hasp_asn1_encode_int(uint32_t val, uint8_t *buffer, size_t *offset); +static void sec_hasp_asn1_encode_data( + const uint8_t *data, size_t len, uint8_t *buffer, size_t *offset); +static void +sec_hasp_asn1_encode_str(const char *str, uint8_t *buffer, size_t *offset); +static void +sec_hasp_asn1_encode_length(uint32_t len, uint8_t *buffer, size_t *offset); +static void +sec_hasp_asn1_encode_tag(uint16_t tag, uint8_t *buffer, size_t *offset); -struct sec_hasp_asn1_store* sec_hasp_asn1_object_store_alloc(uint16_t oid, uint32_t size) +struct sec_hasp_asn1_store * +sec_hasp_asn1_object_store_alloc(uint16_t oid, uint32_t size) { - struct sec_hasp_asn1_store* tmp = malloc(sizeof(struct sec_hasp_asn1_store)); + struct sec_hasp_asn1_store *tmp = malloc(sizeof(struct sec_hasp_asn1_store)); - tmp->objects = malloc(sizeof(struct sec_hasp_asn1_object) * size); - tmp->capacity = size; - tmp->oid = oid; - tmp->pos = 0; + tmp->objects = malloc(sizeof(struct sec_hasp_asn1_object) * size); + tmp->capacity = size; + tmp->oid = oid; + tmp->pos = 0; - memset(tmp->objects, 0, sizeof(struct sec_hasp_asn1_object) * size); + memset(tmp->objects, 0, sizeof(struct sec_hasp_asn1_object) * size); - return tmp; + return tmp; } -void sec_hasp_asn1_store_free(struct sec_hasp_asn1_store* store) +void sec_hasp_asn1_store_free(struct sec_hasp_asn1_store *store) { - for (size_t i = 0; i < store->pos; i++) { - if (store->objects[i].type == SEC_HASP_ASN1_VT_STR) { - free(store->objects[i].str); - } else if (store->objects[i].type == SEC_HASP_ASN1_VT_DATA) { - free(store->objects[i].data); - } + for (size_t i = 0; i < store->pos; i++) { + if (store->objects[i].type == SEC_HASP_ASN1_VT_STR) { + free(store->objects[i].str); + } else if (store->objects[i].type == SEC_HASP_ASN1_VT_DATA) { + free(store->objects[i].data); } + } - free(store); + free(store); } -void sec_hasp_asn1_object_add_int(struct sec_hasp_asn1_store* store, uint16_t tag, uint32_t value) +void sec_hasp_asn1_object_add_int( + struct sec_hasp_asn1_store *store, uint16_t tag, uint32_t value) { - if (store->pos == store->capacity) { - return; - } + if (store->pos == store->capacity) { + return; + } - store->objects[store->pos].tag = tag; - store->objects[store->pos].type = SEC_HASP_ASN1_VT_INT; - - /* Determine length, considers padding for encoding later as well */ - // TODO not sure if this is correct, ask mario - if (value <= 0xFF) { - store->objects[store->pos].blen = 1; - } else if (value <= 0xFFFF) { - store->objects[store->pos].blen = 2; - } else if (value <= 0xFFFFFF) { - store->objects[store->pos].blen = 3; - } else if (value <= 0x7FFFFFFF) { - store->objects[store->pos].blen = 4; - } else { - store->objects[store->pos].blen = 5; - } - - store->objects[store->pos].int_val = value; - store->pos++; -} - -void sec_hasp_asn1_object_add_str(struct sec_hasp_asn1_store* store, uint16_t tag, const char* str) -{ - if (store->pos == store->capacity) { - return; - } - - store->objects[store->pos].tag = tag; - store->objects[store->pos].type = SEC_HASP_ASN1_VT_STR; - - /* Store len + null terminator */ - store->objects[store->pos].blen = strlen(str) + 1; - store->objects[store->pos].str = util_str_dup(str); - store->pos++; -} - -void sec_hasp_asn1_object_add_time(struct sec_hasp_asn1_store* store, uint16_t tag, uint32_t time) -{ - if (store->pos == store->capacity) { - return; - } - - store->objects[store->pos].tag = tag; - store->objects[store->pos].type = SEC_HASP_ASN1_VT_TIME; + store->objects[store->pos].tag = tag; + store->objects[store->pos].type = SEC_HASP_ASN1_VT_INT; + /* Determine length, considers padding for encoding later as well */ + // TODO not sure if this is correct, ask mario + if (value <= 0xFF) { + store->objects[store->pos].blen = 1; + } else if (value <= 0xFFFF) { + store->objects[store->pos].blen = 2; + } else if (value <= 0xFFFFFF) { + store->objects[store->pos].blen = 3; + } else if (value <= 0x7FFFFFFF) { + store->objects[store->pos].blen = 4; + } else { store->objects[store->pos].blen = 5; - store->objects[store->pos].time = time; - store->pos++; + } + + store->objects[store->pos].int_val = value; + store->pos++; } -void sec_hasp_asn1_object_add_data(struct sec_hasp_asn1_store* store, uint16_t tag, const uint8_t* data, - size_t len) +void sec_hasp_asn1_object_add_str( + struct sec_hasp_asn1_store *store, uint16_t tag, const char *str) { - if (store->pos == store->capacity) { - return; + if (store->pos == store->capacity) { + return; + } + + store->objects[store->pos].tag = tag; + store->objects[store->pos].type = SEC_HASP_ASN1_VT_STR; + + /* Store len + null terminator */ + store->objects[store->pos].blen = strlen(str) + 1; + store->objects[store->pos].str = util_str_dup(str); + store->pos++; +} + +void sec_hasp_asn1_object_add_time( + struct sec_hasp_asn1_store *store, uint16_t tag, uint32_t time) +{ + if (store->pos == store->capacity) { + return; + } + + store->objects[store->pos].tag = tag; + store->objects[store->pos].type = SEC_HASP_ASN1_VT_TIME; + + store->objects[store->pos].blen = 5; + store->objects[store->pos].time = time; + store->pos++; +} + +void sec_hasp_asn1_object_add_data( + struct sec_hasp_asn1_store *store, + uint16_t tag, + const uint8_t *data, + size_t len) +{ + if (store->pos == store->capacity) { + return; + } + + store->objects[store->pos].tag = tag; + store->objects[store->pos].type = SEC_HASP_ASN1_VT_DATA; + + /* Store len + null terminator */ + store->objects[store->pos].blen = len; + store->objects[store->pos].data = util_xmalloc(len); + memcpy(store->objects[store->pos].data, data, len); + + store->pos++; +} + +void sec_hasp_asn1_object_set_int( + struct sec_hasp_asn1_store *store, uint16_t tag) +{ + store->objects[store->pos].tag = tag; + store->objects[store->pos].type = SEC_HASP_ASN1_VT_INT; + store->pos++; +} + +void sec_hasp_asn1_object_set_str( + struct sec_hasp_asn1_store *store, uint16_t tag) +{ + store->objects[store->pos].tag = tag; + store->objects[store->pos].type = SEC_HASP_ASN1_VT_STR; + store->pos++; +} + +void sec_hasp_asn1_object_set_time( + struct sec_hasp_asn1_store *store, uint16_t tag) +{ + store->objects[store->pos].tag = tag; + store->objects[store->pos].type = SEC_HASP_ASN1_VT_TIME; + store->pos++; +} + +void sec_hasp_asn1_object_set_data( + struct sec_hasp_asn1_store *store, uint16_t tag) +{ + store->objects[store->pos].tag = tag; + store->objects[store->pos].type = SEC_HASP_ASN1_VT_DATA; + store->pos++; +} + +bool sec_hasp_asn1_object_get_int( + struct sec_hasp_asn1_store *store, uint16_t tag, uint32_t *ret_value) +{ + for (size_t i = 0; i < store->pos; i++) { + if (store->objects[i].tag == tag) { + if (store->objects[i].type != SEC_HASP_ASN1_VT_INT) { + log_error("Type of tag %X is not int", tag); + return false; + } else { + *ret_value = store->objects[i].int_val; + return true; + } + } + } + + return false; +} + +bool sec_hasp_asn1_object_get_str( + struct sec_hasp_asn1_store *store, uint16_t tag, char **ret_value) +{ + for (size_t i = 0; i < store->pos; i++) { + if (store->objects[i].tag == tag) { + if (store->objects[i].type != SEC_HASP_ASN1_VT_STR) { + log_error("Type of tag %X is not str", tag); + return false; + } else { + *ret_value = util_str_dup(store->objects[i].str); + return true; + } + } + } + + return false; +} + +bool sec_hasp_asn1_object_get_time( + struct sec_hasp_asn1_store *store, uint16_t tag, uint32_t *ret_value) +{ + for (size_t i = 0; i < store->pos; i++) { + if (store->objects[i].tag == tag) { + if (store->objects[i].type != SEC_HASP_ASN1_VT_TIME) { + log_error("Type of tag %X is not time", tag); + return false; + } else { + *ret_value = store->objects[i].int_val; + return true; + } + } + } + + return false; +} + +bool sec_hasp_asn1_object_get_data( + struct sec_hasp_asn1_store *store, + uint16_t tag, + uint8_t **ret_data, + size_t *ret_len) +{ + for (size_t i = 0; i < store->pos; i++) { + if (store->objects[i].tag == tag) { + if (store->objects[i].type != SEC_HASP_ASN1_VT_DATA) { + log_error("Type of tag %X is not str", tag); + return false; + } else { + *ret_len = store->objects[i].blen; + *ret_data = util_xmalloc(*ret_len); + memcpy(*ret_data, store->objects[i].data, *ret_len); + return true; + } + } + } + + return false; +} + +size_t sec_hasp_asn1_encode( + struct sec_hasp_asn1_store *store, uint8_t *buffer, size_t len) +{ + uint8_t buffer_tmp[32768]; + size_t offset = 0; + + /* we need to know the size of the payload to encode the first length field, + * encode all objects first */ + for (size_t i = 0; i < store->pos; i++) { + sec_hasp_asn1_encode_tag(store->objects[i].tag, buffer_tmp, &offset); + sec_hasp_asn1_encode_length(store->objects[i].blen, buffer_tmp, &offset); + + switch (store->objects[i].type) { + case SEC_HASP_ASN1_VT_INVALID: + log_error("Invalid object type"); + break; + + case SEC_HASP_ASN1_VT_TIME: + buffer_tmp[offset++] = 0x00; + sec_hasp_asn1_encode_int(store->objects[i].time, buffer_tmp, &offset); + break; + + case SEC_HASP_ASN1_VT_INT: + sec_hasp_asn1_encode_int(store->objects[i].time, buffer_tmp, &offset); + break; + + case SEC_HASP_ASN1_VT_STR: + sec_hasp_asn1_encode_str(store->objects[i].str, buffer_tmp, &offset); + break; + + case SEC_HASP_ASN1_VT_DATA: + sec_hasp_asn1_encode_data( + store->objects[i].data, + store->objects[i].blen, + buffer_tmp, + &offset); + break; + + default: + log_error("Unknown object type %d", store->objects[i].type); + break; + } + } + + size_t offset_out = 0; + + sec_hasp_asn1_encode_tag(store->oid, buffer, &offset_out); + sec_hasp_asn1_encode_length(offset, buffer, &offset_out); + + if (offset > len) { + log_error("Target buffer too small: %d < %d", len, offset + offset_out); + } else { + memcpy(&buffer[offset_out], buffer_tmp, offset); + } + + return offset + offset_out; +} + +void sec_hasp_asn1_decode( + struct sec_hasp_asn1_store *store, const uint8_t *buffer, size_t len) +{ + size_t offset = 0; + + store->oid = sec_hasp_asn1_decode_tag(buffer, &offset); + sec_hasp_asn1_decode_length(buffer, &offset); + + while (offset < len) { + uint16_t tag = sec_hasp_asn1_decode_tag(buffer, &offset); + uint32_t obj_len = sec_hasp_asn1_decode_length(buffer, &offset); + + if (tag <= 0x7F || tag >= 0x9F) { + log_error("Found invalid object tag: %X", tag); + return; } - store->objects[store->pos].tag = tag; - store->objects[store->pos].type = SEC_HASP_ASN1_VT_DATA; + struct sec_hasp_asn1_object *obj = NULL; - /* Store len + null terminator */ - store->objects[store->pos].blen = len; - store->objects[store->pos].data = util_xmalloc(len); - memcpy(store->objects[store->pos].data, data, len); - - store->pos++; -} - -void sec_hasp_asn1_object_set_int(struct sec_hasp_asn1_store* store, uint16_t tag) -{ - store->objects[store->pos].tag = tag; - store->objects[store->pos].type = SEC_HASP_ASN1_VT_INT; - store->pos++; -} - -void sec_hasp_asn1_object_set_str(struct sec_hasp_asn1_store* store, uint16_t tag) -{ - store->objects[store->pos].tag = tag; - store->objects[store->pos].type = SEC_HASP_ASN1_VT_STR; - store->pos++; -} - -void sec_hasp_asn1_object_set_time(struct sec_hasp_asn1_store* store, uint16_t tag) -{ - store->objects[store->pos].tag = tag; - store->objects[store->pos].type = SEC_HASP_ASN1_VT_TIME; - store->pos++; -} - -void sec_hasp_asn1_object_set_data(struct sec_hasp_asn1_store* store, uint16_t tag) -{ - store->objects[store->pos].tag = tag; - store->objects[store->pos].type = SEC_HASP_ASN1_VT_DATA; - store->pos++; -} - -bool sec_hasp_asn1_object_get_int(struct sec_hasp_asn1_store* store, uint16_t tag, uint32_t* ret_value) -{ + /* find object that matches the tag and type */ for (size_t i = 0; i < store->pos; i++) { - if (store->objects[i].tag == tag) { - if (store->objects[i].type != SEC_HASP_ASN1_VT_INT) { - log_error("Type of tag %X is not int", tag); - return false; - } else { - *ret_value = store->objects[i].int_val; - return true; - } - } + if (store->objects[i].tag == tag) { + obj = &store->objects[i]; + break; + } } - return false; -} - -bool sec_hasp_asn1_object_get_str(struct sec_hasp_asn1_store* store, uint16_t tag, char** ret_value) -{ - for (size_t i = 0; i < store->pos; i++) { - if (store->objects[i].tag == tag) { - if (store->objects[i].type != SEC_HASP_ASN1_VT_STR) { - log_error("Type of tag %X is not str", tag); - return false; - } else { - *ret_value = util_str_dup(store->objects[i].str); - return true; - } - } + if (!obj) { + log_error("No object in store that matches tag %X", tag); + return; } - return false; -} + obj->blen = obj_len; -bool sec_hasp_asn1_object_get_time(struct sec_hasp_asn1_store* store, uint16_t tag, uint32_t* ret_value) -{ - for (size_t i = 0; i < store->pos; i++) { - if (store->objects[i].tag == tag) { - if (store->objects[i].type != SEC_HASP_ASN1_VT_TIME) { - log_error("Type of tag %X is not time", tag); - return false; - } else { - *ret_value = store->objects[i].int_val; - return true; - } - } + switch (obj->type) { + case SEC_HASP_ASN1_VT_INVALID: + log_error("Invalid object type specified for tag %X", obj->tag); + break; + + case SEC_HASP_ASN1_VT_TIME: + case SEC_HASP_ASN1_VT_INT: + obj->int_val = sec_hasp_asn1_decode_int(buffer, &offset, obj->blen); + break; + + case SEC_HASP_ASN1_VT_STR: + obj->str = sec_hasp_asn1_decode_str(buffer, &offset, obj->blen); + break; + + case SEC_HASP_ASN1_VT_DATA: + obj->data = sec_hasp_asn1_decode_data(buffer, &offset, obj->blen); + break; + + default: + log_error("Unknown object type for tag %X", obj->tag); + break; } - - return false; + } } -bool sec_hasp_asn1_object_get_data(struct sec_hasp_asn1_store* store, uint16_t tag, uint8_t** ret_data, - size_t* ret_len) +static uint32_t +sec_hasp_asn1_decode_int(const uint8_t *buffer, size_t *offset, uint32_t blen) { - for (size_t i = 0; i < store->pos; i++) { - if (store->objects[i].tag == tag) { - if (store->objects[i].type != SEC_HASP_ASN1_VT_DATA) { - log_error("Type of tag %X is not str", tag); - return false; - } else { - *ret_len = store->objects[i].blen; - *ret_data = util_xmalloc(*ret_len); - memcpy(*ret_data, store->objects[i].data, *ret_len); - return true; - } - } - } + uint32_t data = 0; - return false; + switch (blen) { + case 1: + data = buffer[(*offset)++]; + break; + + case 2: + data |= buffer[(*offset)++] << 8; + data |= buffer[(*offset)++]; + break; + + case 3: + data |= buffer[(*offset)++] << 16; + data |= buffer[(*offset)++] << 8; + data |= buffer[(*offset)++]; + break; + + case 4: + data |= buffer[(*offset)++] << 24; + data |= buffer[(*offset)++] << 16; + data |= buffer[(*offset)++] << 8; + data |= buffer[(*offset)++]; + break; + + case 5: + /* skip first byte? */ + (*offset)++; + data |= buffer[(*offset)++] << 24; + data |= buffer[(*offset)++] << 16; + data |= buffer[(*offset)++] << 8; + data |= buffer[(*offset)++]; + break; + + default: + // TODO invalid len? + break; + } + + return data; } - -size_t sec_hasp_asn1_encode(struct sec_hasp_asn1_store* store, uint8_t* buffer, size_t len) +static uint8_t * +sec_hasp_asn1_decode_data(const uint8_t *buffer, size_t *offset, uint32_t blen) { - uint8_t buffer_tmp[32768]; - size_t offset = 0; + uint8_t *data = util_xmalloc(sizeof(uint8_t) * blen); - /* we need to know the size of the payload to encode the first length field, encode all objects first */ - for (size_t i = 0; i < store->pos; i++) { - sec_hasp_asn1_encode_tag(store->objects[i].tag, buffer_tmp, &offset); - sec_hasp_asn1_encode_length(store->objects[i].blen, buffer_tmp, &offset); + memcpy(data, buffer + *offset, blen); + (*offset) += blen; - switch(store->objects[i].type) { - case SEC_HASP_ASN1_VT_INVALID: - log_error("Invalid object type"); - break; - - case SEC_HASP_ASN1_VT_TIME: - buffer_tmp[offset++] = 0x00; - sec_hasp_asn1_encode_int(store->objects[i].time, buffer_tmp, &offset); - break; - - case SEC_HASP_ASN1_VT_INT: - sec_hasp_asn1_encode_int(store->objects[i].time, buffer_tmp, &offset); - break; - - case SEC_HASP_ASN1_VT_STR: - sec_hasp_asn1_encode_str(store->objects[i].str, buffer_tmp, &offset); - break; - - case SEC_HASP_ASN1_VT_DATA: - sec_hasp_asn1_encode_data(store->objects[i].data, store->objects[i].blen, buffer_tmp, &offset); - break; - - default: - log_error("Unknown object type %d", store->objects[i].type); - break; - } - } - - size_t offset_out = 0; - - sec_hasp_asn1_encode_tag(store->oid, buffer, &offset_out); - sec_hasp_asn1_encode_length(offset, buffer, &offset_out); - - if (offset > len) { - log_error("Target buffer too small: %d < %d", len, offset + offset_out); - } else { - memcpy(&buffer[offset_out], buffer_tmp, offset); - } - - return offset + offset_out; + return data; } -void sec_hasp_asn1_decode(struct sec_hasp_asn1_store* store, const uint8_t* buffer, size_t len) +static char * +sec_hasp_asn1_decode_str(const uint8_t *buffer, size_t *offset, uint32_t blen) { - size_t offset = 0; + /* len already includes null terminator */ + char *str = util_xmalloc(sizeof(char) * blen); - store->oid = sec_hasp_asn1_decode_tag(buffer, &offset); - sec_hasp_asn1_decode_length(buffer, &offset); + memcpy(str, buffer + *offset, blen); + (*offset) += blen; - while (offset < len) { - uint16_t tag = sec_hasp_asn1_decode_tag(buffer, &offset); - uint32_t obj_len = sec_hasp_asn1_decode_length(buffer, &offset); - - if (tag <= 0x7F || tag >= 0x9F) { - log_error("Found invalid object tag: %X", tag); - return; - } - - struct sec_hasp_asn1_object* obj = NULL; - - /* find object that matches the tag and type */ - for (size_t i = 0; i < store->pos; i++) { - if (store->objects[i].tag == tag) { - obj = &store->objects[i]; - break; - } - } - - if (!obj) { - log_error("No object in store that matches tag %X", tag); - return; - } - - obj->blen = obj_len; - - switch (obj->type) { - case SEC_HASP_ASN1_VT_INVALID: - log_error("Invalid object type specified for tag %X", obj->tag); - break; - - case SEC_HASP_ASN1_VT_TIME: - case SEC_HASP_ASN1_VT_INT: - obj->int_val = sec_hasp_asn1_decode_int(buffer, &offset, obj->blen); - break; - - case SEC_HASP_ASN1_VT_STR: - obj->str = sec_hasp_asn1_decode_str(buffer, &offset, obj->blen); - break; - - case SEC_HASP_ASN1_VT_DATA: - obj->data = sec_hasp_asn1_decode_data(buffer, &offset, obj->blen); - break; - - default: - log_error("Unknown object type for tag %X", obj->tag); - break; - } - } + return str; } -static uint32_t sec_hasp_asn1_decode_int(const uint8_t* buffer, size_t* offset, uint32_t blen) +static uint32_t +sec_hasp_asn1_decode_length(const uint8_t *buffer, size_t *offset) { - uint32_t data = 0; + uint32_t len; - switch (blen) { - case 1: - data = buffer[(*offset)++]; - break; - - case 2: - data |= buffer[(*offset)++] << 8; - data |= buffer[(*offset)++]; - break; - - case 3: - data |= buffer[(*offset)++] << 16; - data |= buffer[(*offset)++] << 8; - data |= buffer[(*offset)++]; - break; - - case 4: - data |= buffer[(*offset)++] << 24; - data |= buffer[(*offset)++] << 16; - data |= buffer[(*offset)++] << 8; - data |= buffer[(*offset)++]; - break; - - case 5: - /* skip first byte? */ - (*offset)++; - data |= buffer[(*offset)++] << 24; - data |= buffer[(*offset)++] << 16; - data |= buffer[(*offset)++] << 8; - data |= buffer[(*offset)++]; - break; - - default: - // TODO invalid len? - break; - } - - return data; -} - -static uint8_t* sec_hasp_asn1_decode_data(const uint8_t* buffer, size_t* offset, uint32_t blen) -{ - uint8_t* data = util_xmalloc(sizeof(uint8_t) * blen); - - memcpy(data, buffer + *offset, blen); - (*offset) += blen; - - return data; -} - -static char* sec_hasp_asn1_decode_str(const uint8_t* buffer, size_t* offset, uint32_t blen) -{ - /* len already includes null terminator */ - char* str = util_xmalloc(sizeof(char) * blen); - - memcpy(str, buffer + *offset, blen); - (*offset) += blen; - - return str; -} - -static uint32_t sec_hasp_asn1_decode_length(const uint8_t* buffer, size_t* offset) -{ - uint32_t len; + len = buffer[(*offset)++]; + if (len == 0x81) { len = buffer[(*offset)++]; + } else if (len == 0x82) { + /* Big endian */ + len = buffer[(*offset)++] << 8; + len |= buffer[(*offset)++]; + } - if (len == 0x81) { - len = buffer[(*offset)++]; - } else if (len == 0x82) { - /* Big endian */ - len = buffer[(*offset)++] << 8; - len |= buffer[(*offset)++]; - } - - return len; + return len; } -static uint16_t sec_hasp_asn1_decode_tag(const uint8_t* buffer, size_t* offset) +static uint16_t sec_hasp_asn1_decode_tag(const uint8_t *buffer, size_t *offset) { - uint16_t tag; + uint16_t tag; - tag = buffer[(*offset)++]; + tag = buffer[(*offset)++]; - if (tag == 0x7F) { - /* Big endian */ - tag = tag << 8; - tag |= buffer[(*offset)++]; - } + if (tag == 0x7F) { + /* Big endian */ + tag = tag << 8; + tag |= buffer[(*offset)++]; + } - return tag; + return tag; } -static void sec_hasp_asn1_encode_int(uint32_t val, uint8_t* buffer, size_t* offset) +static void +sec_hasp_asn1_encode_int(uint32_t val, uint8_t *buffer, size_t *offset) { - uint8_t tmp[8]; - size_t tmp_pos = 0; + uint8_t tmp[8]; + size_t tmp_pos = 0; - if (val <= 0xFF) { - tmp[tmp_pos++] = (uint8_t) val; - } else if (val <= 0xFFFF) { - /* Big endian */ - tmp[tmp_pos++] = (uint8_t) (val >> 8); - tmp[tmp_pos++] = (uint8_t) val; - } else if (val <= 0xFFFFFF) { - /* Big endian */ - tmp[tmp_pos++] = (uint8_t) (val >> 16); - tmp[tmp_pos++] = (uint8_t) (val >> 8); - tmp[tmp_pos++] = (uint8_t) val; - } else if (val <= 0xFFFFFFFF) { - /* Big endian */ - tmp[tmp_pos++] = (uint8_t) (val >> 24); - tmp[tmp_pos++] = (uint8_t) (val >> 16); - tmp[tmp_pos++] = (uint8_t) (val >> 8); - tmp[tmp_pos++] = (uint8_t) val; - } else if (val <= 0xFFFFFFFFFFFFFFFF) { - // TODO quad words not supported in decode? - } + if (val <= 0xFF) { + tmp[tmp_pos++] = (uint8_t) val; + } else if (val <= 0xFFFF) { + /* Big endian */ + tmp[tmp_pos++] = (uint8_t)(val >> 8); + tmp[tmp_pos++] = (uint8_t) val; + } else if (val <= 0xFFFFFF) { + /* Big endian */ + tmp[tmp_pos++] = (uint8_t)(val >> 16); + tmp[tmp_pos++] = (uint8_t)(val >> 8); + tmp[tmp_pos++] = (uint8_t) val; + } else if (val <= 0xFFFFFFFF) { + /* Big endian */ + tmp[tmp_pos++] = (uint8_t)(val >> 24); + tmp[tmp_pos++] = (uint8_t)(val >> 16); + tmp[tmp_pos++] = (uint8_t)(val >> 8); + tmp[tmp_pos++] = (uint8_t) val; + } else if (val <= 0xFFFFFFFFFFFFFFFF) { + // TODO quad words not supported in decode? + } - /* Deal with padding */ - if (tmp[0] > 0x7F) { - buffer[(*offset)++] = 0x00; - } - - memcpy(buffer + *offset, tmp, tmp_pos); - (*offset) += tmp_pos; -} - -static void sec_hasp_asn1_encode_data(const uint8_t* data, size_t len, uint8_t* buffer, size_t* offset) -{ - memcpy(buffer + *offset, data, len); - (*offset) += len; -} - -static void sec_hasp_asn1_encode_str(const char* str, uint8_t* buffer, size_t* offset) -{ - size_t len = strlen(str); - - memcpy(buffer + *offset, str, len); - (*offset) += len; - - /* Add null terminator */ + /* Deal with padding */ + if (tmp[0] > 0x7F) { buffer[(*offset)++] = 0x00; + } + + memcpy(buffer + *offset, tmp, tmp_pos); + (*offset) += tmp_pos; } -static void sec_hasp_asn1_encode_length(uint32_t len, uint8_t* buffer, size_t* offset) +static void sec_hasp_asn1_encode_data( + const uint8_t *data, size_t len, uint8_t *buffer, size_t *offset) { - if (len <= 0xF7) { - buffer[(*offset)++] = (uint8_t) len; - } else if (len <= 0xFF) { - buffer[(*offset)++] = 0x81; - buffer[(*offset)++] = (uint8_t) len; - } else if (len <= 0xFFFF) { - buffer[(*offset)++] = 0x82; - /* Big endian */ - buffer[(*offset)++] = (uint8_t) (len >> 8); - buffer[(*offset)++] = (uint8_t) len; - } else if (len <= 0xFFFF) { - buffer[(*offset)++] = 0x82; - /* Big endian */ - buffer[(*offset)++] = (uint8_t) (len >> 16); - buffer[(*offset)++] = (uint8_t) (len >> 8); - buffer[(*offset)++] = (uint8_t) len; - } else if (len <= 0xFFFFFFFF) { - buffer[(*offset)++] = 0x84; - /* Big endian */ - buffer[(*offset)++] = (uint8_t) (len >> 24); - buffer[(*offset)++] = (uint8_t) (len >> 16); - buffer[(*offset)++] = (uint8_t) (len >> 8); - buffer[(*offset)++] = (uint8_t) len; - } + memcpy(buffer + *offset, data, len); + (*offset) += len; } -static void sec_hasp_asn1_encode_tag(uint16_t tag, uint8_t* buffer, size_t* offset) +static void +sec_hasp_asn1_encode_str(const char *str, uint8_t *buffer, size_t *offset) { - if (tag > 0xFF) { - /* Big endian */ - buffer[(*offset)++] = (uint8_t) (tag >> 8); - buffer[(*offset)++] = (uint8_t) (tag); - } else { - buffer[(*offset)++] = (uint8_t) (tag); - } + size_t len = strlen(str); + + memcpy(buffer + *offset, str, len); + (*offset) += len; + + /* Add null terminator */ + buffer[(*offset)++] = 0x00; +} + +static void +sec_hasp_asn1_encode_length(uint32_t len, uint8_t *buffer, size_t *offset) +{ + if (len <= 0xF7) { + buffer[(*offset)++] = (uint8_t) len; + } else if (len <= 0xFF) { + buffer[(*offset)++] = 0x81; + buffer[(*offset)++] = (uint8_t) len; + } else if (len <= 0xFFFF) { + buffer[(*offset)++] = 0x82; + /* Big endian */ + buffer[(*offset)++] = (uint8_t)(len >> 8); + buffer[(*offset)++] = (uint8_t) len; + } else if (len <= 0xFFFF) { + buffer[(*offset)++] = 0x82; + /* Big endian */ + buffer[(*offset)++] = (uint8_t)(len >> 16); + buffer[(*offset)++] = (uint8_t)(len >> 8); + buffer[(*offset)++] = (uint8_t) len; + } else if (len <= 0xFFFFFFFF) { + buffer[(*offset)++] = 0x84; + /* Big endian */ + buffer[(*offset)++] = (uint8_t)(len >> 24); + buffer[(*offset)++] = (uint8_t)(len >> 16); + buffer[(*offset)++] = (uint8_t)(len >> 8); + buffer[(*offset)++] = (uint8_t) len; + } +} + +static void +sec_hasp_asn1_encode_tag(uint16_t tag, uint8_t *buffer, size_t *offset) +{ + if (tag > 0xFF) { + /* Big endian */ + buffer[(*offset)++] = (uint8_t)(tag >> 8); + buffer[(*offset)++] = (uint8_t)(tag); + } else { + buffer[(*offset)++] = (uint8_t)(tag); + } } \ No newline at end of file diff --git a/src/main/sec/hasp/lib/asn1.h b/src/main/sec/hasp/lib/asn1.h index 19120b8..83b19a9 100644 --- a/src/main/sec/hasp/lib/asn1.h +++ b/src/main/sec/hasp/lib/asn1.h @@ -7,65 +7,84 @@ #include "util/list.h" enum sec_hasp_asn1_value_type { - SEC_HASP_ASN1_VT_INVALID = 0, - SEC_HASP_ASN1_VT_INT = 1, - SEC_HASP_ASN1_VT_STR = 2, - SEC_HASP_ASN1_VT_TIME = 3, - SEC_HASP_ASN1_VT_DATA = 4, + SEC_HASP_ASN1_VT_INVALID = 0, + SEC_HASP_ASN1_VT_INT = 1, + SEC_HASP_ASN1_VT_STR = 2, + SEC_HASP_ASN1_VT_TIME = 3, + SEC_HASP_ASN1_VT_DATA = 4, }; struct sec_hasp_asn1_object { - uint16_t tag; - uint32_t blen; - enum sec_hasp_asn1_value_type type; + uint16_t tag; + uint32_t blen; + enum sec_hasp_asn1_value_type type; - union { - uint32_t time; - uint32_t int_val; - uint8_t* data; - char* str; - }; + union { + uint32_t time; + uint32_t int_val; + uint8_t *data; + char *str; + }; }; struct sec_hasp_asn1_store { - uint16_t oid; - size_t capacity; - size_t pos; - struct sec_hasp_asn1_object* objects; + uint16_t oid; + size_t capacity; + size_t pos; + struct sec_hasp_asn1_object *objects; }; -struct sec_hasp_asn1_store* sec_hasp_asn1_object_store_alloc(uint16_t oid, uint32_t size); +struct sec_hasp_asn1_store * +sec_hasp_asn1_object_store_alloc(uint16_t oid, uint32_t size); -void sec_hasp_asn1_store_free(struct sec_hasp_asn1_store* store); +void sec_hasp_asn1_store_free(struct sec_hasp_asn1_store *store); -void sec_hasp_asn1_object_add_int(struct sec_hasp_asn1_store* store, uint16_t tag, uint32_t value); +void sec_hasp_asn1_object_add_int( + struct sec_hasp_asn1_store *store, uint16_t tag, uint32_t value); -void sec_hasp_asn1_object_add_str(struct sec_hasp_asn1_store* store, uint16_t tag, const char* str); +void sec_hasp_asn1_object_add_str( + struct sec_hasp_asn1_store *store, uint16_t tag, const char *str); -void sec_hasp_asn1_object_add_time(struct sec_hasp_asn1_store* store, uint16_t tag, uint32_t time); +void sec_hasp_asn1_object_add_time( + struct sec_hasp_asn1_store *store, uint16_t tag, uint32_t time); -void sec_hasp_asn1_object_add_data(struct sec_hasp_asn1_store* store, uint16_t tag, const uint8_t* data, - size_t len); +void sec_hasp_asn1_object_add_data( + struct sec_hasp_asn1_store *store, + uint16_t tag, + const uint8_t *data, + size_t len); -void sec_hasp_asn1_object_set_int(struct sec_hasp_asn1_store* store, uint16_t tag); +void sec_hasp_asn1_object_set_int( + struct sec_hasp_asn1_store *store, uint16_t tag); -void sec_hasp_asn1_object_set_str(struct sec_hasp_asn1_store* store, uint16_t tag); +void sec_hasp_asn1_object_set_str( + struct sec_hasp_asn1_store *store, uint16_t tag); -void sec_hasp_asn1_object_set_time(struct sec_hasp_asn1_store* store, uint16_t tag); +void sec_hasp_asn1_object_set_time( + struct sec_hasp_asn1_store *store, uint16_t tag); -void sec_hasp_asn1_object_set_data(struct sec_hasp_asn1_store* store, uint16_t tag); +void sec_hasp_asn1_object_set_data( + struct sec_hasp_asn1_store *store, uint16_t tag); -bool sec_hasp_asn1_object_get_int(struct sec_hasp_asn1_store* store, uint16_t tag, uint32_t* ret_value); +bool sec_hasp_asn1_object_get_int( + struct sec_hasp_asn1_store *store, uint16_t tag, uint32_t *ret_value); -bool sec_hasp_asn1_object_get_str(struct sec_hasp_asn1_store* store, uint16_t tag, char** ret_value); +bool sec_hasp_asn1_object_get_str( + struct sec_hasp_asn1_store *store, uint16_t tag, char **ret_value); -bool sec_hasp_asn1_object_get_time(struct sec_hasp_asn1_store* store, uint16_t tag, uint32_t* ret_value); +bool sec_hasp_asn1_object_get_time( + struct sec_hasp_asn1_store *store, uint16_t tag, uint32_t *ret_value); -bool sec_hasp_asn1_object_get_data(struct sec_hasp_asn1_store* store, uint16_t tag, uint8_t** ret_data, - size_t* ret_len); +bool sec_hasp_asn1_object_get_data( + struct sec_hasp_asn1_store *store, + uint16_t tag, + uint8_t **ret_data, + size_t *ret_len); -size_t sec_hasp_asn1_encode(struct sec_hasp_asn1_store* store, uint8_t* buffer, size_t len); +size_t sec_hasp_asn1_encode( + struct sec_hasp_asn1_store *store, uint8_t *buffer, size_t len); -void sec_hasp_asn1_decode(struct sec_hasp_asn1_store* store, const uint8_t* buffer, size_t len); +void sec_hasp_asn1_decode( + struct sec_hasp_asn1_store *store, const uint8_t *buffer, size_t len); #endif diff --git a/src/main/sec/hasp/lib/const.h b/src/main/sec/hasp/lib/const.h index 8949476..11e0237 100644 --- a/src/main/sec/hasp/lib/const.h +++ b/src/main/sec/hasp/lib/const.h @@ -6,75 +6,83 @@ #define SEC_HAS_CONST_FILEID_RW = 0xfff4 #define SEC_HAS_CONST_FILEID_RO = 0xfff5 -#define SEC_HAS_CONST_SCOPE_LM "" -#define SEC_HAS_CONST_SCOPE_HANDLE "" +#define SEC_HAS_CONST_SCOPE_LM \ + "" +#define SEC_HAS_CONST_SCOPE_HANDLE \ + "" -#define SEC_HAS_CONST_FORMAT_GETID "" -#define SEC_HAS_CONST_FORMAT_GETSESSION "" -#define SEC_HAS_CONST_FORMAT_GETKEYINFO "" +#define SEC_HAS_CONST_FORMAT_GETID \ + "" +#define SEC_HAS_CONST_FORMAT_GETSESSION \ + "" +#define SEC_HAS_CONST_FORMAT_GETKEYINFO \ + "" -#define SEC_HAS_CONST_SPEC_FEATURE_ID "" +#define SEC_HAS_CONST_SPEC_FEATURE_ID \ + "" enum sec_hasp_const_status { - SEC_HASP_CONST_STATUS_OK = 0, - SEC_HASP_CONST_STATUS_MEM_RANGE = 1, - SEC_HASP_CONST_STATUS_INV_FILEID = 10, - SEC_HASP_CONST_STATUS_NO_TIME = 12, - SEC_HASP_CONST_STATUS_INV_VCODE = 22, - SEC_HASP_CONST_STATUS_INV_HND = 9, - SEC_HASP_CONST_STATUS_TOO_SHORT = 8, - SEC_HASP_CONST_STATUS_DEVICE_ERR = 43, - SEC_HASP_CONST_STATUS_SCHAN_ERR = 46, - SEC_HASP_CONST_STATUS_BROKEN_SESSION = 0x7F000027 + SEC_HASP_CONST_STATUS_OK = 0, + SEC_HASP_CONST_STATUS_MEM_RANGE = 1, + SEC_HASP_CONST_STATUS_INV_FILEID = 10, + SEC_HASP_CONST_STATUS_NO_TIME = 12, + SEC_HASP_CONST_STATUS_INV_VCODE = 22, + SEC_HASP_CONST_STATUS_INV_HND = 9, + SEC_HASP_CONST_STATUS_TOO_SHORT = 8, + SEC_HASP_CONST_STATUS_DEVICE_ERR = 43, + SEC_HASP_CONST_STATUS_SCHAN_ERR = 46, + SEC_HASP_CONST_STATUS_BROKEN_SESSION = 0x7F000027 }; enum sec_hasp_const_operation_id { - /* Not Used - Admin or Get LMS Version? */ - SEC_HASP_CONST_OP_ID_ADMIN = 0, - /* Not Used */ - SEC_HASP_CONST_OP_ID_ECHO = 1, - SEC_HASP_CONST_OP_ID_LOGIN = 0x2711, - SEC_HASP_CONST_OP_ID_LOGOUT = 0x2712, - SEC_HASP_CONST_OP_ID_LOGINSCOPE = 0x2713, - SEC_HASP_CONST_OP_ID_GETINFO = 0x2714, - SEC_HASP_CONST_OP_ID_PARSE_SCOPE = 0x2715, - SEC_HASP_CONST_OP_ID_SETUPSCHANNEL = 0x2716, - SEC_HASP_CONST_OP_ID_ENCRYPT = 0x2724, - SEC_HASP_CONST_OP_ID_DECRYPT = 0x2725, - SEC_HASP_CONST_OP_ID_READ = 0x271A, - SEC_HASP_CONST_OP_ID_WRITE = 0x271B, - SEC_HASP_CONST_OP_ID_GETSIZE = 0x271C, - SEC_HASP_CONST_OP_ID_GETRTC = 0x271D, - SEC_HASP_CONST_OP_ID_GETAPIUID = 0x2774, - /* Not Used */ - SEC_HASP_CONST_OP_ID_UPDATE = 0x2775, - /* Not Used */ - SEC_HASP_CONST_OP_ID_DETACH = 0x2779, + /* Not Used - Admin or Get LMS Version? */ + SEC_HASP_CONST_OP_ID_ADMIN = 0, + /* Not Used */ + SEC_HASP_CONST_OP_ID_ECHO = 1, + SEC_HASP_CONST_OP_ID_LOGIN = 0x2711, + SEC_HASP_CONST_OP_ID_LOGOUT = 0x2712, + SEC_HASP_CONST_OP_ID_LOGINSCOPE = 0x2713, + SEC_HASP_CONST_OP_ID_GETINFO = 0x2714, + SEC_HASP_CONST_OP_ID_PARSE_SCOPE = 0x2715, + SEC_HASP_CONST_OP_ID_SETUPSCHANNEL = 0x2716, + SEC_HASP_CONST_OP_ID_ENCRYPT = 0x2724, + SEC_HASP_CONST_OP_ID_DECRYPT = 0x2725, + SEC_HASP_CONST_OP_ID_READ = 0x271A, + SEC_HASP_CONST_OP_ID_WRITE = 0x271B, + SEC_HASP_CONST_OP_ID_GETSIZE = 0x271C, + SEC_HASP_CONST_OP_ID_GETRTC = 0x271D, + SEC_HASP_CONST_OP_ID_GETAPIUID = 0x2774, + /* Not Used */ + SEC_HASP_CONST_OP_ID_UPDATE = 0x2775, + /* Not Used */ + SEC_HASP_CONST_OP_ID_DETACH = 0x2779, }; enum sec_hasp_const_operational_object_id { - SEC_HASP_CONST_OID_CLIENTID_REQ = 0x7F34, - SEC_HASP_CONST_OID_CLIENTID_RESP =0x7F35, - SEC_HASP_CONST_OID_LOGIN_REQ = 0x61, - SEC_HASP_CONST_OID_LOGIN_REP = 0x62, - SEC_HASP_CONST_OID_LOGINSCOPE_REQ = 0x63, - SEC_HASP_CONST_OID_LOGINSCOPE_REP = 0x64, - SEC_HASP_CONST_OID_LOGOUT_REQ = 0x65, - SEC_HASP_CONST_OID_LOGOUT_REP = 0x66, - SEC_HASP_CONST_OID_INFO_REQ = 0x67, - SEC_HASP_CONST_OID_INFO_REP = 0x68, - SEC_HASP_CONST_OID_READ_REQ = 0x6A, - SEC_HASP_CONST_OID_READ_REP = 0x6B, - SEC_HASP_CONST_OID_WRITE_REQ = 0x6C, - SEC_HASP_CONST_OID_WRITE_REP = 0x6D, - SEC_HASP_CONST_OID_GETSIZE_REQ = 0x6E, - SEC_HASP_CONST_OID_GETSIZE_REP = 0x6F, - SEC_HASP_CONST_OID_GETRTC_REQ = 0x70, - SEC_HASP_CONST_OID_GETRTC_REP = 0x71, - SEC_HASP_CONST_OID_SCHANNEL_REQ = 0x72, - SEC_HASP_CONST_OID_SCHANNEL_REP = 0x73, - SEC_HASP_CONST_OID_CRYPT_REQ = 0x77, - SEC_HASP_CONST_OID_CRYPT_REP = 0x78, + SEC_HASP_CONST_OID_CLIENTID_REQ = 0x7F34, + SEC_HASP_CONST_OID_CLIENTID_RESP = 0x7F35, + SEC_HASP_CONST_OID_LOGIN_REQ = 0x61, + SEC_HASP_CONST_OID_LOGIN_REP = 0x62, + SEC_HASP_CONST_OID_LOGINSCOPE_REQ = 0x63, + SEC_HASP_CONST_OID_LOGINSCOPE_REP = 0x64, + SEC_HASP_CONST_OID_LOGOUT_REQ = 0x65, + SEC_HASP_CONST_OID_LOGOUT_REP = 0x66, + SEC_HASP_CONST_OID_INFO_REQ = 0x67, + SEC_HASP_CONST_OID_INFO_REP = 0x68, + SEC_HASP_CONST_OID_READ_REQ = 0x6A, + SEC_HASP_CONST_OID_READ_REP = 0x6B, + SEC_HASP_CONST_OID_WRITE_REQ = 0x6C, + SEC_HASP_CONST_OID_WRITE_REP = 0x6D, + SEC_HASP_CONST_OID_GETSIZE_REQ = 0x6E, + SEC_HASP_CONST_OID_GETSIZE_REP = 0x6F, + SEC_HASP_CONST_OID_GETRTC_REQ = 0x70, + SEC_HASP_CONST_OID_GETRTC_REP = 0x71, + SEC_HASP_CONST_OID_SCHANNEL_REQ = 0x72, + SEC_HASP_CONST_OID_SCHANNEL_REP = 0x73, + SEC_HASP_CONST_OID_CRYPT_REQ = 0x77, + SEC_HASP_CONST_OID_CRYPT_REP = 0x78, }; #endif diff --git a/src/main/sec/hasp/lib/handler.c b/src/main/sec/hasp/lib/handler.c index 9c471ac..52990ff 100644 --- a/src/main/sec/hasp/lib/handler.c +++ b/src/main/sec/hasp/lib/handler.c @@ -7,93 +7,105 @@ #include "util/log.h" enum sec_hasp_handler_packet_type { - SEC_HASP_HANDLER_PT_APIUID = 0x2774, - SEC_HASP_HANDLER_PT_LOGIN = 0x2711, - SEC_HASP_HANDLER_PT_LOGOUT = 0x2712, - SEC_HASP_HANDLER_PT_GETINFO = 0x2714, - SEC_HASP_HANDLER_PT_SCHANNEL = 0x2716, - SEC_HASP_HANDLER_PT_ENCRYPT = 0x2724, - SEC_HASP_HANDLER_PT_DECRYPT = 0x2725, - SEC_HASP_HANDLER_PT_READ = 0x271A, - SEC_HASP_HANDLER_PT_WRITE = 0x271B, + SEC_HASP_HANDLER_PT_APIUID = 0x2774, + SEC_HASP_HANDLER_PT_LOGIN = 0x2711, + SEC_HASP_HANDLER_PT_LOGOUT = 0x2712, + SEC_HASP_HANDLER_PT_GETINFO = 0x2714, + SEC_HASP_HANDLER_PT_SCHANNEL = 0x2716, + SEC_HASP_HANDLER_PT_ENCRYPT = 0x2724, + SEC_HASP_HANDLER_PT_DECRYPT = 0x2725, + SEC_HASP_HANDLER_PT_READ = 0x271A, + SEC_HASP_HANDLER_PT_WRITE = 0x271B, }; -void sec_hasp_handler_init(const uint8_t* key_data, size_t len) +void sec_hasp_handler_init(const uint8_t *key_data, size_t len) { - } -struct sec_hasp_handler_transaction* sec_hasp_handler_alloc_transaction(size_t max_payload_size) +struct sec_hasp_handler_transaction * +sec_hasp_handler_alloc_transaction(size_t max_payload_size) { - struct sec_hasp_handler_transaction* trans; + struct sec_hasp_handler_transaction *trans; - trans = malloc(sizeof(struct sec_hasp_handler_transaction)); - trans->req_resp_max_size = sizeof(struct sec_hasp_handler_header) + max_payload_size; - trans->req = malloc(trans->req_resp_max_size); - trans->resp = malloc(trans->req_resp_max_size); + trans = malloc(sizeof(struct sec_hasp_handler_transaction)); + trans->req_resp_max_size = + sizeof(struct sec_hasp_handler_header) + max_payload_size; + trans->req = malloc(trans->req_resp_max_size); + trans->resp = malloc(trans->req_resp_max_size); - return trans; + return trans; } -void sec_hasp_handler_free_transaction(struct sec_hasp_handler_transaction* transaction) +void sec_hasp_handler_free_transaction( + struct sec_hasp_handler_transaction *transaction) { - free(transaction->req); - free(transaction->resp); - free(transaction); + free(transaction->req); + free(transaction->resp); + free(transaction); } -void sec_hasp_handler_do_transaction(struct sec_hasp_handler_transaction* transaction) +void sec_hasp_handler_do_transaction( + struct sec_hasp_handler_transaction *transaction) { - log_debug("Req: packet_size %d, head_value 0x%X, transaction_num %d, session_id 0x%X, packet_type 0x%X, " - "unknown 0x%X, tail_value 0x%X", transaction->req->header.packet_size, transaction->req->header.head_value, - transaction->req->header.transaction_num, transaction->req->header.session_id, - transaction->req->header.packet_type, transaction->req->header.tail_value); + log_debug( + "Req: packet_size %d, head_value 0x%X, transaction_num %d, session_id " + "0x%X, packet_type 0x%X, " + "unknown 0x%X, tail_value 0x%X", + transaction->req->header.packet_size, + transaction->req->header.head_value, + transaction->req->header.transaction_num, + transaction->req->header.session_id, + transaction->req->header.packet_type, + transaction->req->header.tail_value); - switch (transaction->req->header.packet_type) { - case SEC_HASP_HANDLER_PT_APIUID: - log_debug("SEC_HASP_HANDLER_PT_APIUID"); - break; + switch (transaction->req->header.packet_type) { + case SEC_HASP_HANDLER_PT_APIUID: + log_debug("SEC_HASP_HANDLER_PT_APIUID"); + break; - case SEC_HASP_HANDLER_PT_LOGIN: - log_debug("SEC_HASP_HANDLER_PT_LOGIN"); - break; + case SEC_HASP_HANDLER_PT_LOGIN: + log_debug("SEC_HASP_HANDLER_PT_LOGIN"); + break; - case SEC_HASP_HANDLER_PT_LOGOUT: - log_debug("SEC_HASP_HANDLER_PT_LOGOUT"); - break; + case SEC_HASP_HANDLER_PT_LOGOUT: + log_debug("SEC_HASP_HANDLER_PT_LOGOUT"); + break; - case SEC_HASP_HANDLER_PT_GETINFO: - log_debug("SEC_HASP_HANDLER_PT_GETINFO"); - break; + case SEC_HASP_HANDLER_PT_GETINFO: + log_debug("SEC_HASP_HANDLER_PT_GETINFO"); + break; - case SEC_HASP_HANDLER_PT_SCHANNEL: - log_debug("SEC_HASP_HANDLER_PT_SCHANNEL"); - break; + case SEC_HASP_HANDLER_PT_SCHANNEL: + log_debug("SEC_HASP_HANDLER_PT_SCHANNEL"); + break; - case SEC_HASP_HANDLER_PT_ENCRYPT: - log_debug("SEC_HASP_HANDLER_PT_ENCRYPT"); - break; + case SEC_HASP_HANDLER_PT_ENCRYPT: + log_debug("SEC_HASP_HANDLER_PT_ENCRYPT"); + break; - case SEC_HASP_HANDLER_PT_DECRYPT: - log_debug("SEC_HASP_HANDLER_PT_DECRYPT"); - break; + case SEC_HASP_HANDLER_PT_DECRYPT: + log_debug("SEC_HASP_HANDLER_PT_DECRYPT"); + break; - case SEC_HASP_HANDLER_PT_READ: - log_debug("SEC_HASP_HANDLER_PT_READ"); - break; + case SEC_HASP_HANDLER_PT_READ: + log_debug("SEC_HASP_HANDLER_PT_READ"); + break; - case SEC_HASP_HANDLER_PT_WRITE: - log_debug("SEC_HASP_HANDLER_PT_WRITE"); - break; + case SEC_HASP_HANDLER_PT_WRITE: + log_debug("SEC_HASP_HANDLER_PT_WRITE"); + break; - default: - log_error("Invalid packet type: %X", transaction->req->header.packet_type); - memset(&transaction->req->header, 0, sizeof(struct sec_hasp_handler_header)); - break; - } + default: + log_error( + "Invalid packet type: %X", transaction->req->header.packet_type); + memset( + &transaction->req->header, 0, sizeof(struct sec_hasp_handler_header)); + break; + } } -//static void sec_hasp_handler_get_client_id(struct sec_hasp_handler_transaction* transaction) +// static void sec_hasp_handler_get_client_id(struct +// sec_hasp_handler_transaction* transaction) //{ // transaction->resp->header.packet_size // transaction->resp->header.head_value @@ -115,4 +127,3 @@ void sec_hasp_handler_do_transaction(struct sec_hasp_handler_transaction* transa // // return client_id_response //} - diff --git a/src/main/sec/hasp/lib/handler.h b/src/main/sec/hasp/lib/handler.h index 27b27fe..436830a 100644 --- a/src/main/sec/hasp/lib/handler.h +++ b/src/main/sec/hasp/lib/handler.h @@ -5,37 +5,40 @@ #include struct sec_hasp_handler_header { - uint32_t packet_size; - uint16_t head_value; - uint32_t transaction_num; - uint32_t session_id; - uint16_t unknown; - uint16_t packet_type; - uint32_t tail_value; + uint32_t packet_size; + uint16_t head_value; + uint32_t transaction_num; + uint32_t session_id; + uint16_t unknown; + uint16_t packet_type; + uint32_t tail_value; } __attribute((__packed__)); struct sec_hasp_handler_req { - struct sec_hasp_handler_header header; - uint8_t payload[]; + struct sec_hasp_handler_header header; + uint8_t payload[]; }; struct sec_hasp_handler_resp { - struct sec_hasp_handler_header header; - uint8_t payload[]; + struct sec_hasp_handler_header header; + uint8_t payload[]; }; struct sec_hasp_handler_transaction { - size_t req_resp_max_size; - struct sec_hasp_handler_req* req; - struct sec_hasp_handler_resp* resp; + size_t req_resp_max_size; + struct sec_hasp_handler_req *req; + struct sec_hasp_handler_resp *resp; }; -void sec_hasp_handler_init(const uint8_t* key_data, size_t len); +void sec_hasp_handler_init(const uint8_t *key_data, size_t len); -struct sec_hasp_handler_transaction* sec_hasp_handler_alloc_transaction(size_t max_payload_size); +struct sec_hasp_handler_transaction * +sec_hasp_handler_alloc_transaction(size_t max_payload_size); -void sec_hasp_handler_free_transaction(struct sec_hasp_handler_transaction* transaction); +void sec_hasp_handler_free_transaction( + struct sec_hasp_handler_transaction *transaction); -void sec_hasp_handler_do_transaction(struct sec_hasp_handler_transaction* transaction); +void sec_hasp_handler_do_transaction( + struct sec_hasp_handler_transaction *transaction); #endif diff --git a/src/main/sec/hasp/lib/object.c b/src/main/sec/hasp/lib/object.c index 8a175c6..46d35b7 100644 --- a/src/main/sec/hasp/lib/object.c +++ b/src/main/sec/hasp/lib/object.c @@ -1,4 +1,3 @@ // // Created by on 6/2/18. // - diff --git a/src/main/sec/hasp/lib/object.h b/src/main/sec/hasp/lib/object.h index 9985258..cfe2d49 100644 --- a/src/main/sec/hasp/lib/object.h +++ b/src/main/sec/hasp/lib/object.h @@ -1,6 +1,4 @@ #ifndef SEC_HASP_OBJECT_H #define SEC_HASP_OBJECT_H - - #endif diff --git a/src/main/sec/hasp/lib/object/client-id-req.c b/src/main/sec/hasp/lib/object/client-id-req.c index 5c731f6..37df3e2 100644 --- a/src/main/sec/hasp/lib/object/client-id-req.c +++ b/src/main/sec/hasp/lib/object/client-id-req.c @@ -7,55 +7,60 @@ #include "client-id-req.h" -struct sec_hasp_object_client_id_req* sec_hasp_object_client_id_req_alloc() +struct sec_hasp_object_client_id_req *sec_hasp_object_client_id_req_alloc() { - struct sec_hasp_object_client_id_req* obj = util_xmalloc(sizeof(struct sec_hasp_object_client_id_req)); + struct sec_hasp_object_client_id_req *obj = + util_xmalloc(sizeof(struct sec_hasp_object_client_id_req)); - obj->oid = SEC_HASP_CONST_OID_CLIENTID_REQ; - obj->val_80 = 0; - obj->api_version_major = 0; - obj->api_version_minor = 0; - obj->timestamp = 0; + obj->oid = SEC_HASP_CONST_OID_CLIENTID_REQ; + obj->val_80 = 0; + obj->api_version_major = 0; + obj->api_version_minor = 0; + obj->timestamp = 0; - return obj; + return obj; } -void sec_hasp_object_client_id_req_free(struct sec_hasp_object_client_id_req* obj) +void sec_hasp_object_client_id_req_free( + struct sec_hasp_object_client_id_req *obj) { - free(obj); + free(obj); } -size_t sec_hasp_object_client_id_req_encode(struct sec_hasp_object_client_id_req* obj, uint8_t* buffer, - size_t len) +size_t sec_hasp_object_client_id_req_encode( + struct sec_hasp_object_client_id_req *obj, uint8_t *buffer, size_t len) { - struct sec_hasp_asn1_store* store = sec_hasp_asn1_object_store_alloc(obj->oid, 4); + struct sec_hasp_asn1_store *store = + sec_hasp_asn1_object_store_alloc(obj->oid, 4); - /* populate right before encoding */ - obj->timestamp = (uint32_t) time(NULL); + /* populate right before encoding */ + obj->timestamp = (uint32_t) time(NULL); - sec_hasp_asn1_object_add_int(store, 0x80, obj->val_80); - sec_hasp_asn1_object_add_int(store, 0x81, obj->api_version_major); - sec_hasp_asn1_object_add_int(store, 0x82, obj->api_version_minor); - sec_hasp_asn1_object_add_time(store, 0x84, obj->timestamp); + sec_hasp_asn1_object_add_int(store, 0x80, obj->val_80); + sec_hasp_asn1_object_add_int(store, 0x81, obj->api_version_major); + sec_hasp_asn1_object_add_int(store, 0x82, obj->api_version_minor); + sec_hasp_asn1_object_add_time(store, 0x84, obj->timestamp); - return sec_hasp_asn1_encode(store, buffer, len); + return sec_hasp_asn1_encode(store, buffer, len); } -void sec_hasp_object_client_id_req_decode(uint8_t* buffer, size_t len, struct sec_hasp_object_client_id_req* obj) +void sec_hasp_object_client_id_req_decode( + uint8_t *buffer, size_t len, struct sec_hasp_object_client_id_req *obj) { - struct sec_hasp_asn1_store* store = sec_hasp_asn1_object_store_alloc(obj->oid, 4); + struct sec_hasp_asn1_store *store = + sec_hasp_asn1_object_store_alloc(obj->oid, 4); - sec_hasp_asn1_object_set_int(store, 0x80); - sec_hasp_asn1_object_set_int(store, 0x81); - sec_hasp_asn1_object_set_int(store, 0x82); - sec_hasp_asn1_object_set_time(store, 0x84); + sec_hasp_asn1_object_set_int(store, 0x80); + sec_hasp_asn1_object_set_int(store, 0x81); + sec_hasp_asn1_object_set_int(store, 0x82); + sec_hasp_asn1_object_set_time(store, 0x84); - sec_hasp_asn1_decode(store, buffer, len); + sec_hasp_asn1_decode(store, buffer, len); - obj->oid = store->oid; + obj->oid = store->oid; - sec_hasp_asn1_object_get_int(store, 0x80, &obj->val_80); - sec_hasp_asn1_object_get_int(store, 0x81, &obj->api_version_major); - sec_hasp_asn1_object_get_int(store, 0x82, &obj->api_version_minor); - sec_hasp_asn1_object_get_time(store, 0x84, &obj->timestamp); + sec_hasp_asn1_object_get_int(store, 0x80, &obj->val_80); + sec_hasp_asn1_object_get_int(store, 0x81, &obj->api_version_major); + sec_hasp_asn1_object_get_int(store, 0x82, &obj->api_version_minor); + sec_hasp_asn1_object_get_time(store, 0x84, &obj->timestamp); } \ No newline at end of file diff --git a/src/main/sec/hasp/lib/object/client-id-req.h b/src/main/sec/hasp/lib/object/client-id-req.h index 11081cb..37973bb 100644 --- a/src/main/sec/hasp/lib/object/client-id-req.h +++ b/src/main/sec/hasp/lib/object/client-id-req.h @@ -5,20 +5,22 @@ #include struct sec_hasp_object_client_id_req { - uint16_t oid; - uint32_t val_80; - uint32_t api_version_major; - uint32_t api_version_minor; - uint32_t timestamp; + uint16_t oid; + uint32_t val_80; + uint32_t api_version_major; + uint32_t api_version_minor; + uint32_t timestamp; }; -struct sec_hasp_object_client_id_req* sec_hasp_object_client_id_req_alloc(); +struct sec_hasp_object_client_id_req *sec_hasp_object_client_id_req_alloc(); -void sec_hasp_object_client_id_req_free(struct sec_hasp_object_client_id_req* obj); +void sec_hasp_object_client_id_req_free( + struct sec_hasp_object_client_id_req *obj); -size_t sec_hasp_object_client_id_req_encode(struct sec_hasp_object_client_id_req* obj, uint8_t* buffer, - size_t len); +size_t sec_hasp_object_client_id_req_encode( + struct sec_hasp_object_client_id_req *obj, uint8_t *buffer, size_t len); -void sec_hasp_object_client_id_req_decode(uint8_t* buffer, size_t len, struct sec_hasp_object_client_id_req* obj); +void sec_hasp_object_client_id_req_decode( + uint8_t *buffer, size_t len, struct sec_hasp_object_client_id_req *obj); #endif diff --git a/src/main/sec/hasp/lib/object/client-id-resp.c b/src/main/sec/hasp/lib/object/client-id-resp.c index a8df9de..e51ab14 100644 --- a/src/main/sec/hasp/lib/object/client-id-resp.c +++ b/src/main/sec/hasp/lib/object/client-id-resp.c @@ -5,44 +5,49 @@ #include "client-id-resp.h" -struct sec_hasp_object_client_id_resp* sec_hasp_object_client_id_resp_alloc() +struct sec_hasp_object_client_id_resp *sec_hasp_object_client_id_resp_alloc() { - struct sec_hasp_object_client_id_resp* obj = util_xmalloc(sizeof(struct sec_hasp_object_client_id_resp)); + struct sec_hasp_object_client_id_resp *obj = + util_xmalloc(sizeof(struct sec_hasp_object_client_id_resp)); - obj->oid = SEC_HASP_CONST_OID_CLIENTID_RESP; - obj->status = 0; - obj->client_id = 0; + obj->oid = SEC_HASP_CONST_OID_CLIENTID_RESP; + obj->status = 0; + obj->client_id = 0; - return obj; + return obj; } -void sec_hasp_object_client_id_resp_free(struct sec_hasp_object_client_id_resp* obj) +void sec_hasp_object_client_id_resp_free( + struct sec_hasp_object_client_id_resp *obj) { - free(obj); + free(obj); } -size_t sec_hasp_object_client_id_resp_encode(struct sec_hasp_object_client_id_resp* obj, uint8_t* buffer, - size_t len) +size_t sec_hasp_object_client_id_resp_encode( + struct sec_hasp_object_client_id_resp *obj, uint8_t *buffer, size_t len) { - struct sec_hasp_asn1_store* store = sec_hasp_asn1_object_store_alloc(obj->oid, 4); + struct sec_hasp_asn1_store *store = + sec_hasp_asn1_object_store_alloc(obj->oid, 4); - sec_hasp_asn1_object_add_int(store, 0x80, obj->status); - sec_hasp_asn1_object_add_int(store, 0x81, obj->client_id); + sec_hasp_asn1_object_add_int(store, 0x80, obj->status); + sec_hasp_asn1_object_add_int(store, 0x81, obj->client_id); - return sec_hasp_asn1_encode(store, buffer, len); + return sec_hasp_asn1_encode(store, buffer, len); } -void sec_hasp_object_client_id_resp_decode(uint8_t* buffer, size_t len, struct sec_hasp_object_client_id_resp* obj) +void sec_hasp_object_client_id_resp_decode( + uint8_t *buffer, size_t len, struct sec_hasp_object_client_id_resp *obj) { - struct sec_hasp_asn1_store* store = sec_hasp_asn1_object_store_alloc(obj->oid, 2); + struct sec_hasp_asn1_store *store = + sec_hasp_asn1_object_store_alloc(obj->oid, 2); - sec_hasp_asn1_object_set_int(store, 0x80); - sec_hasp_asn1_object_set_int(store, 0x81); + sec_hasp_asn1_object_set_int(store, 0x80); + sec_hasp_asn1_object_set_int(store, 0x81); - sec_hasp_asn1_decode(store, buffer, len); + sec_hasp_asn1_decode(store, buffer, len); - obj->oid = store->oid; + obj->oid = store->oid; - sec_hasp_asn1_object_get_int(store, 0x80, &obj->status); - sec_hasp_asn1_object_get_int(store, 0x81, &obj->client_id); + sec_hasp_asn1_object_get_int(store, 0x80, &obj->status); + sec_hasp_asn1_object_get_int(store, 0x81, &obj->client_id); } \ No newline at end of file diff --git a/src/main/sec/hasp/lib/object/client-id-resp.h b/src/main/sec/hasp/lib/object/client-id-resp.h index e4d51a7..1c61c1c 100644 --- a/src/main/sec/hasp/lib/object/client-id-resp.h +++ b/src/main/sec/hasp/lib/object/client-id-resp.h @@ -5,18 +5,20 @@ #include struct sec_hasp_object_client_id_resp { - uint16_t oid; - uint32_t status; - uint32_t client_id; + uint16_t oid; + uint32_t status; + uint32_t client_id; }; -struct sec_hasp_object_client_id_resp* sec_hasp_object_client_id_resp_alloc(); +struct sec_hasp_object_client_id_resp *sec_hasp_object_client_id_resp_alloc(); -void sec_hasp_object_client_id_resp_free(struct sec_hasp_object_client_id_resp* obj); +void sec_hasp_object_client_id_resp_free( + struct sec_hasp_object_client_id_resp *obj); -size_t sec_hasp_object_client_id_resp_encode(struct sec_hasp_object_client_id_resp* obj, uint8_t* buffer, - size_t len); +size_t sec_hasp_object_client_id_resp_encode( + struct sec_hasp_object_client_id_resp *obj, uint8_t *buffer, size_t len); -void sec_hasp_object_client_id_resp_decode(uint8_t* buffer, size_t len, struct sec_hasp_object_client_id_resp* obj); +void sec_hasp_object_client_id_resp_decode( + uint8_t *buffer, size_t len, struct sec_hasp_object_client_id_resp *obj); #endif diff --git a/src/main/sec/hasp/lib/object/login-req.c b/src/main/sec/hasp/lib/object/login-req.c index 1f928f3..7d70133 100644 --- a/src/main/sec/hasp/lib/object/login-req.c +++ b/src/main/sec/hasp/lib/object/login-req.c @@ -1,139 +1,143 @@ #include -#include "sec/hasp/main.h" #include "sec/hasp/const.h" +#include "sec/hasp/main.h" #include "util/mem.h" #include "login-req.h" -struct sec_hasp_object_login_req* sec_hasp_object_login_req_init() +struct sec_hasp_object_login_req *sec_hasp_object_login_req_init() { - struct sec_hasp_object_login_req* obj = util_xmalloc(sizeof(struct sec_hasp_object_login_req)); + struct sec_hasp_object_login_req *obj = + util_xmalloc(sizeof(struct sec_hasp_object_login_req)); - obj->oid = SEC_HASP_CONST_OID_LOGIN_REQ; - obj->pid = 0; - obj->tid = 0; - obj->hasp_uid = 0; - obj->vendor_id = 0; - obj->feature_id = 0; - obj->username = NULL; - obj->machine_name = NULL; - obj->login_type = NULL; - obj->api_version_major = 0; - obj->api_version_minor = 0; - obj->timestamp = 0; - obj->val_8b = 0; - obj->val_8c = 0; - obj->val_8d = 0; - obj->val_8e = 0; - obj->volume_serial = 0; - obj->val_90 = 0; - obj->hasp_handle = 0; + obj->oid = SEC_HASP_CONST_OID_LOGIN_REQ; + obj->pid = 0; + obj->tid = 0; + obj->hasp_uid = 0; + obj->vendor_id = 0; + obj->feature_id = 0; + obj->username = NULL; + obj->machine_name = NULL; + obj->login_type = NULL; + obj->api_version_major = 0; + obj->api_version_minor = 0; + obj->timestamp = 0; + obj->val_8b = 0; + obj->val_8c = 0; + obj->val_8d = 0; + obj->val_8e = 0; + obj->volume_serial = 0; + obj->val_90 = 0; + obj->hasp_handle = 0; - return obj; + return obj; } -void sec_hasp_object_login_req_free(struct sec_hasp_object_login_req* obj) +void sec_hasp_object_login_req_free(struct sec_hasp_object_login_req *obj) { - if (obj->username) { - free(obj->username); - } + if (obj->username) { + free(obj->username); + } - if (obj->machine_name) { - free(obj->machine_name); - } + if (obj->machine_name) { + free(obj->machine_name); + } - if (obj->login_type) { - free(obj->login_type); - } + if (obj->login_type) { + free(obj->login_type); + } } -size_t sec_hasp_object_login_req_encode(struct sec_hasp_object_login_req* obj, uint8_t* buffer, - size_t len) +size_t sec_hasp_object_login_req_encode( + struct sec_hasp_object_login_req *obj, uint8_t *buffer, size_t len) { - struct sec_hasp_asn1_store* store = sec_hasp_asn1_object_store_alloc(obj->oid, 18); + struct sec_hasp_asn1_store *store = + sec_hasp_asn1_object_store_alloc(obj->oid, 18); - /* populate right before encoding */ - obj->timestamp = (uint32_t) time(NULL); + /* populate right before encoding */ + obj->timestamp = (uint32_t) time(NULL); - sec_hasp_asn1_object_add_int(store, 0x80, obj->pid); - sec_hasp_asn1_object_add_int(store, 0x81, obj->tid); - sec_hasp_asn1_object_add_int(store, 0x82, obj->hasp_uid); - sec_hasp_asn1_object_add_int(store, 0x83, obj->vendor_id); - sec_hasp_asn1_object_add_int(store, 0x84, obj->feature_id); + sec_hasp_asn1_object_add_int(store, 0x80, obj->pid); + sec_hasp_asn1_object_add_int(store, 0x81, obj->tid); + sec_hasp_asn1_object_add_int(store, 0x82, obj->hasp_uid); + sec_hasp_asn1_object_add_int(store, 0x83, obj->vendor_id); + sec_hasp_asn1_object_add_int(store, 0x84, obj->feature_id); - sec_hasp_asn1_object_add_str(store, 0x85, obj->username); - sec_hasp_asn1_object_add_str(store, 0x86, obj->machine_name); - sec_hasp_asn1_object_add_str(store, 0x87, obj->login_type); + sec_hasp_asn1_object_add_str(store, 0x85, obj->username); + sec_hasp_asn1_object_add_str(store, 0x86, obj->machine_name); + sec_hasp_asn1_object_add_str(store, 0x87, obj->login_type); - sec_hasp_asn1_object_add_int(store, 0x88, obj->api_version_major); - sec_hasp_asn1_object_add_int(store, 0x89, obj->api_version_minor); + sec_hasp_asn1_object_add_int(store, 0x88, obj->api_version_major); + sec_hasp_asn1_object_add_int(store, 0x89, obj->api_version_minor); - sec_hasp_asn1_object_add_time(store, 0x8A, obj->timestamp); + sec_hasp_asn1_object_add_time(store, 0x8A, obj->timestamp); - sec_hasp_asn1_object_add_int(store, 0x8B, obj->val_8b); - sec_hasp_asn1_object_add_int(store, 0x8C, obj->val_8c); - sec_hasp_asn1_object_add_int(store, 0x8D, obj->val_8d); - sec_hasp_asn1_object_add_int(store, 0x8E, obj->val_8e); - sec_hasp_asn1_object_add_int(store, 0x8F, obj->volume_serial); - sec_hasp_asn1_object_add_int(store, 0x90, obj->val_90); - sec_hasp_asn1_object_add_int(store, 0x91, obj->hasp_handle); + sec_hasp_asn1_object_add_int(store, 0x8B, obj->val_8b); + sec_hasp_asn1_object_add_int(store, 0x8C, obj->val_8c); + sec_hasp_asn1_object_add_int(store, 0x8D, obj->val_8d); + sec_hasp_asn1_object_add_int(store, 0x8E, obj->val_8e); + sec_hasp_asn1_object_add_int(store, 0x8F, obj->volume_serial); + sec_hasp_asn1_object_add_int(store, 0x90, obj->val_90); + sec_hasp_asn1_object_add_int(store, 0x91, obj->hasp_handle); - return sec_hasp_asn1_encode(store, buffer, len); + return sec_hasp_asn1_encode(store, buffer, len); } -void sec_hasp_object_login_req_decode(uint8_t* buffer, size_t len, struct sec_hasp_object_login_req* obj) +void sec_hasp_object_login_req_decode( + uint8_t *buffer, size_t len, struct sec_hasp_object_login_req *obj) { - struct sec_hasp_asn1_store* store = sec_hasp_asn1_object_store_alloc(obj->oid, 18); + struct sec_hasp_asn1_store *store = + sec_hasp_asn1_object_store_alloc(obj->oid, 18); - sec_hasp_asn1_object_set_int(store, 0x80); - sec_hasp_asn1_object_set_int(store, 0x81); - sec_hasp_asn1_object_set_int(store, 0x82); - sec_hasp_asn1_object_set_int(store, 0x83); - sec_hasp_asn1_object_set_int(store, 0x84); + sec_hasp_asn1_object_set_int(store, 0x80); + sec_hasp_asn1_object_set_int(store, 0x81); + sec_hasp_asn1_object_set_int(store, 0x82); + sec_hasp_asn1_object_set_int(store, 0x83); + sec_hasp_asn1_object_set_int(store, 0x84); - sec_hasp_asn1_object_set_str(store, 0x85); - sec_hasp_asn1_object_set_str(store, 0x86); - sec_hasp_asn1_object_set_str(store, 0x87); + sec_hasp_asn1_object_set_str(store, 0x85); + sec_hasp_asn1_object_set_str(store, 0x86); + sec_hasp_asn1_object_set_str(store, 0x87); - sec_hasp_asn1_object_set_int(store, 0x88); - sec_hasp_asn1_object_set_int(store, 0x89); + sec_hasp_asn1_object_set_int(store, 0x88); + sec_hasp_asn1_object_set_int(store, 0x89); - sec_hasp_asn1_object_set_time(store, 0x8A); + sec_hasp_asn1_object_set_time(store, 0x8A); - sec_hasp_asn1_object_set_int(store, 0x8B); - sec_hasp_asn1_object_set_int(store, 0x8C); - sec_hasp_asn1_object_set_int(store, 0x8D); - sec_hasp_asn1_object_set_int(store, 0x8E); - sec_hasp_asn1_object_set_int(store, 0x8F); - sec_hasp_asn1_object_set_int(store, 0x90); - sec_hasp_asn1_object_set_int(store, 0x91); + sec_hasp_asn1_object_set_int(store, 0x8B); + sec_hasp_asn1_object_set_int(store, 0x8C); + sec_hasp_asn1_object_set_int(store, 0x8D); + sec_hasp_asn1_object_set_int(store, 0x8E); + sec_hasp_asn1_object_set_int(store, 0x8F); + sec_hasp_asn1_object_set_int(store, 0x90); + sec_hasp_asn1_object_set_int(store, 0x91); - sec_hasp_asn1_decode(store, buffer, len); + sec_hasp_asn1_decode(store, buffer, len); - obj->oid = store->oid; + obj->oid = store->oid; - sec_hasp_asn1_object_get_int(store, 0x80, &obj->pid); - sec_hasp_asn1_object_get_int(store, 0x81, &obj->tid); - sec_hasp_asn1_object_get_int(store, 0x82, &obj->hasp_uid); - sec_hasp_asn1_object_get_int(store, 0x83, &obj->vendor_id); - sec_hasp_asn1_object_get_int(store, 0x84, &obj->feature_id); + sec_hasp_asn1_object_get_int(store, 0x80, &obj->pid); + sec_hasp_asn1_object_get_int(store, 0x81, &obj->tid); + sec_hasp_asn1_object_get_int(store, 0x82, &obj->hasp_uid); + sec_hasp_asn1_object_get_int(store, 0x83, &obj->vendor_id); + sec_hasp_asn1_object_get_int(store, 0x84, &obj->feature_id); - sec_hasp_asn1_object_get_str(store, 0x85, &obj->username); - sec_hasp_asn1_object_get_str(store, 0x86, &obj->machine_name); - sec_hasp_asn1_object_get_str(store, 0x87, &obj->login_type); + sec_hasp_asn1_object_get_str(store, 0x85, &obj->username); + sec_hasp_asn1_object_get_str(store, 0x86, &obj->machine_name); + sec_hasp_asn1_object_get_str(store, 0x87, &obj->login_type); - sec_hasp_asn1_object_get_int(store, 0x88, &obj->api_version_major); - sec_hasp_asn1_object_get_int(store, 0x89, &obj->api_version_minor); + sec_hasp_asn1_object_get_int(store, 0x88, &obj->api_version_major); + sec_hasp_asn1_object_get_int(store, 0x89, &obj->api_version_minor); - sec_hasp_asn1_object_get_time(store, 0x8A, &obj->timestamp); + sec_hasp_asn1_object_get_time(store, 0x8A, &obj->timestamp); - sec_hasp_asn1_object_get_int(store, 0x8B, &obj->val_8b); - sec_hasp_asn1_object_get_int(store, 0x8C, &obj->val_8c); - sec_hasp_asn1_object_get_int(store, 0x8D, &obj->val_8d); - sec_hasp_asn1_object_get_int(store, 0x8E, &obj->val_8e); - sec_hasp_asn1_object_get_int(store, 0x8F, &obj->volume_serial); - sec_hasp_asn1_object_get_int(store, 0x90, &obj->val_90); - sec_hasp_asn1_object_get_int(store, 0x91, &obj->hasp_handle); + sec_hasp_asn1_object_get_int(store, 0x8B, &obj->val_8b); + sec_hasp_asn1_object_get_int(store, 0x8C, &obj->val_8c); + sec_hasp_asn1_object_get_int(store, 0x8D, &obj->val_8d); + sec_hasp_asn1_object_get_int(store, 0x8E, &obj->val_8e); + sec_hasp_asn1_object_get_int(store, 0x8F, &obj->volume_serial); + sec_hasp_asn1_object_get_int(store, 0x90, &obj->val_90); + sec_hasp_asn1_object_get_int(store, 0x91, &obj->hasp_handle); } \ No newline at end of file diff --git a/src/main/sec/hasp/lib/object/login-req.h b/src/main/sec/hasp/lib/object/login-req.h index f9d0cf9..8c4d71e 100644 --- a/src/main/sec/hasp/lib/object/login-req.h +++ b/src/main/sec/hasp/lib/object/login-req.h @@ -5,34 +5,35 @@ #include struct sec_hasp_object_login_req { - uint16_t oid; - uint32_t pid; - uint32_t tid; - uint32_t hasp_uid; - uint32_t vendor_id; - uint32_t feature_id; - char* username; - char* machine_name; - char* login_type; - uint32_t api_version_major; - uint32_t api_version_minor; - uint32_t timestamp; - uint32_t val_8b; - uint32_t val_8c; - uint32_t val_8d; - uint32_t val_8e; - uint32_t volume_serial; - uint32_t val_90; - uint32_t hasp_handle; + uint16_t oid; + uint32_t pid; + uint32_t tid; + uint32_t hasp_uid; + uint32_t vendor_id; + uint32_t feature_id; + char *username; + char *machine_name; + char *login_type; + uint32_t api_version_major; + uint32_t api_version_minor; + uint32_t timestamp; + uint32_t val_8b; + uint32_t val_8c; + uint32_t val_8d; + uint32_t val_8e; + uint32_t volume_serial; + uint32_t val_90; + uint32_t hasp_handle; }; -struct sec_hasp_object_login_req* sec_hasp_object_login_req_init(); +struct sec_hasp_object_login_req *sec_hasp_object_login_req_init(); -void sec_hasp_object_login_req_free(struct sec_hasp_object_login_req* obj); +void sec_hasp_object_login_req_free(struct sec_hasp_object_login_req *obj); -size_t sec_hasp_object_login_req_encode(struct sec_hasp_object_login_req* obj, uint8_t* buffer, - size_t len); +size_t sec_hasp_object_login_req_encode( + struct sec_hasp_object_login_req *obj, uint8_t *buffer, size_t len); -void sec_hasp_object_login_req_decode(uint8_t* buffer, size_t len, struct sec_hasp_object_login_req* obj); +void sec_hasp_object_login_req_decode( + uint8_t *buffer, size_t len, struct sec_hasp_object_login_req *obj); #endif diff --git a/src/main/sec/hasp/lib/server.c b/src/main/sec/hasp/lib/server.c index 3834571..fbe2490 100644 --- a/src/main/sec/hasp/lib/server.c +++ b/src/main/sec/hasp/lib/server.c @@ -2,8 +2,8 @@ #include #include -#include #include +#include #include #include @@ -19,144 +19,150 @@ static bool sec_hasp_server_run_s; static bool sec_hasp_server_is_running_s; -void sec_hasp_server_init(const uint8_t* key_data, size_t len) +void sec_hasp_server_init(const uint8_t *key_data, size_t len) { - sec_hasp_handler_init(key_data, len); - sec_hasp_server_run_s = true; - sec_hasp_server_is_running_s = false; + sec_hasp_handler_init(key_data, len); + sec_hasp_server_run_s = true; + sec_hasp_server_is_running_s = false; } void sec_hasp_server_run() { - int fd = -1; - struct sockaddr_in addr; - struct sockaddr_in addr_remote; - socklen_t addr_len_remote; - int fd_remote = -1; - int retval; - struct sec_hasp_handler_transaction* transaction; - ssize_t recv_len; + int fd = -1; + struct sockaddr_in addr; + struct sockaddr_in addr_remote; + socklen_t addr_len_remote; + int fd_remote = -1; + int retval; + struct sec_hasp_handler_transaction *transaction; + ssize_t recv_len; - log_info("Setting up socket for server"); + log_info("Setting up socket for server"); - sec_hasp_server_is_running_s = true; + sec_hasp_server_is_running_s = true; - transaction = sec_hasp_handler_alloc_transaction(HASP_MAX_BUFFER); + transaction = sec_hasp_handler_alloc_transaction(HASP_MAX_BUFFER); - fd = socket(AF_INET, SOCK_STREAM, 0); + fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd == -1) { - log_error("Opening socket failed: %s", strerror(errno)); - goto return_cleanup; - } + if (fd == -1) { + log_error("Opening socket failed: %s", strerror(errno)); + goto return_cleanup; + } - memset(&addr, 0, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - /* bind to localhost which limits accepting connections to localhost, only */ - addr.sin_addr.s_addr = htonl(0x7F000001); - addr.sin_port = htons(HASP_PORT); + memset(&addr, 0, sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + /* bind to localhost which limits accepting connections to localhost, only */ + addr.sin_addr.s_addr = htonl(0x7F000001); + addr.sin_port = htons(HASP_PORT); - retval = bind(fd, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)); + retval = bind(fd, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)); + + if (retval == -1) { + log_error("Binding socket failed: %s", strerror(errno)); + goto return_cleanup; + } + + log_info("Running server..."); + + while (sec_hasp_server_run_s) { + /* a single connection is fine here */ + retval = listen(fd, 1); if (retval == -1) { - log_error("Binding socket failed: %s", strerror(errno)); - goto return_cleanup; + log_error( + "Listening for incoming connections failed: %s", strerror(errno)); + goto return_cleanup; } - log_info("Running server..."); + /* got a connection */ + addr_len_remote = sizeof(addr_remote); + fd_remote = accept(fd, &addr_remote, &addr_len_remote); + + if (fd_remote == -1) { + log_error("Accepting incoming connection failed: %s", strerror(errno)); + goto return_cleanup; + } + + log_debug("Remote %X connected", addr_remote.sin_addr.s_addr); + + /* put the socket to the remote into non blocking mode */ + if (fcntl(fd_remote, F_SETFL, fcntl(fd_remote, F_GETFL) | O_NONBLOCK) < 0) { + log_error("Setting socket to non blocking failed: %s", strerror(errno)); + goto return_cleanup; + } while (sec_hasp_server_run_s) { - /* a single connection is fine here */ - retval = listen(fd, 1); + recv_len = + recv(fd_remote, transaction->req, transaction->req_resp_max_size, 0); - if (retval == -1) { - log_error("Listening for incoming connections failed: %s", strerror(errno)); - goto return_cleanup; + if (recv_len == -1) { + /* no data available, sleep to reduce cpu load and retry */ + if (errno == EAGAIN || errno == EWOULDBLOCK) { + /* 10 ms */ + usleep(1000 * 10); + continue; + } else if (errno == ECONNRESET) { + log_debug("Remote %X disconnected", addr_remote.sin_addr.s_addr); + close(fd_remote); + break; + } else { + log_error("Reading from connection failed: %s", strerror(errno)); + goto return_cleanup; } + } - /* got a connection */ - addr_len_remote = sizeof(addr_remote); - fd_remote = accept(fd, &addr_remote, &addr_len_remote); + if (recv_len == 0) { + /* remote disconnected */ + log_debug("Remote %X disconnected", addr_remote.sin_addr.s_addr); + close(fd_remote); + break; + } - if (fd_remote == -1) { - log_error("Accepting incoming connection failed: %s", strerror(errno)); - goto return_cleanup; - } - - log_debug("Remote %X connected", addr_remote.sin_addr.s_addr); - - /* put the socket to the remote into non blocking mode */ - if (fcntl(fd_remote, F_SETFL, fcntl(fd_remote, F_GETFL) | O_NONBLOCK) < 0) { - log_error("Setting socket to non blocking failed: %s", strerror(errno)); - goto return_cleanup; - } - - while (sec_hasp_server_run_s) { - recv_len = recv(fd_remote, transaction->req, transaction->req_resp_max_size, 0); - - if (recv_len == -1) { - /* no data available, sleep to reduce cpu load and retry */ - if (errno == EAGAIN || errno == EWOULDBLOCK) { - /* 10 ms */ - usleep(1000 * 10); - continue; - } else if (errno == ECONNRESET) { - log_debug("Remote %X disconnected", addr_remote.sin_addr.s_addr); - close(fd_remote); - break; - } else { - log_error("Reading from connection failed: %s", strerror(errno)); - goto return_cleanup; - } - } - - if (recv_len == 0) { - /* remote disconnected */ - log_debug("Remote %X disconnected", addr_remote.sin_addr.s_addr); - close(fd_remote); - break; - } - - log_debug("Received data: %d bytes", recv_len); - - sec_hasp_handler_do_transaction(transaction); - - /* send reply */ - recv_len = send(fd_remote, transaction->resp, transaction->resp->header.packet_size, 0); - - if (recv_len == -1) { - if (errno == ECONNRESET) { - log_debug("Remote %X disconnected", addr_remote.sin_addr.s_addr); - close(fd_remote); - break; - } else { - log_error("Writing to connection failed: %s", strerror(errno)); - goto return_cleanup; - } - } + log_debug("Received data: %d bytes", recv_len); + + sec_hasp_handler_do_transaction(transaction); + + /* send reply */ + recv_len = send( + fd_remote, + transaction->resp, + transaction->resp->header.packet_size, + 0); + + if (recv_len == -1) { + if (errno == ECONNRESET) { + log_debug("Remote %X disconnected", addr_remote.sin_addr.s_addr); + close(fd_remote); + break; + } else { + log_error("Writing to connection failed: %s", strerror(errno)); + goto return_cleanup; } + } } + } return_cleanup: - if (fd_remote != -1) { - close(fd); - } + if (fd_remote != -1) { + close(fd); + } - if (fd != -1) { - close(fd); - } + if (fd != -1) { + close(fd); + } - sec_hasp_handler_free_transaction(transaction); + sec_hasp_handler_free_transaction(transaction); - sec_hasp_server_is_running_s = false; + sec_hasp_server_is_running_s = false; } bool sec_hasp_server_is_running(void) { - return sec_hasp_server_is_running_s; + return sec_hasp_server_is_running_s; } void sec_hasp_server_shutdown(void) { - sec_hasp_server_run_s = false; + sec_hasp_server_run_s = false; } \ No newline at end of file diff --git a/src/main/sec/hasp/lib/server.h b/src/main/sec/hasp/lib/server.h index f7e9eae..d02dfbf 100644 --- a/src/main/sec/hasp/lib/server.h +++ b/src/main/sec/hasp/lib/server.h @@ -12,7 +12,7 @@ * @param key_data Pointer to loaded key data (attributes, key table) * @param len Length of the buffer */ -void sec_hasp_server_init(const uint8_t* key_data, size_t len); +void sec_hasp_server_init(const uint8_t *key_data, size_t len); /** * Run the server. This call blocks until the server is shut down. diff --git a/src/main/sec/hasp/lib/util.c b/src/main/sec/hasp/lib/util.c index 5f5941b..6d59b83 100644 --- a/src/main/sec/hasp/lib/util.c +++ b/src/main/sec/hasp/lib/util.c @@ -6,10 +6,10 @@ uint32_t sec_hasp_util_make_fake_handle_value() { - return util_rand_gen_32(); + return util_rand_gen_32(); } uint32_t sec_hasp_util_get_timestamp() { - return (uint32_t) time(NULL); + return (uint32_t) time(NULL); } \ No newline at end of file diff --git a/src/main/sec/hasp/old/hasp.c b/src/main/sec/hasp/old/hasp.c index b365255..fc3d234 100644 --- a/src/main/sec/hasp/old/hasp.c +++ b/src/main/sec/hasp/old/hasp.c @@ -9,8 +9,8 @@ #include "util/str.h" struct sec_hasp_key_table { - uint32_t nkeys; - struct sec_hasp_key* keys; + uint32_t nkeys; + struct sec_hasp_key *keys; }; /* index 0 (type): 1 = dev, 2 = retail @@ -19,69 +19,79 @@ struct sec_hasp_key_table { static const uint32_t sec_hasp_key_id = 0xDEADBEEF; static struct sec_hasp_key_table sec_hasp_keys; -void sec_hasp_init(const uint8_t* key_data, size_t len) +void sec_hasp_init(const uint8_t *key_data, size_t len) { - sec_hasp_keys.nkeys = len / sizeof(struct sec_hasp_key); - sec_hasp_keys.keys = - util_xmalloc(sizeof(struct sec_hasp_key) * sec_hasp_keys.nkeys); + sec_hasp_keys.nkeys = len / sizeof(struct sec_hasp_key); + sec_hasp_keys.keys = + util_xmalloc(sizeof(struct sec_hasp_key) * sec_hasp_keys.nkeys); - memcpy(sec_hasp_keys.keys, key_data, - sec_hasp_keys.nkeys * sizeof(struct sec_hasp_key)); + memcpy( + sec_hasp_keys.keys, + key_data, + sec_hasp_keys.nkeys * sizeof(struct sec_hasp_key)); - log_info("Loaded %d keys", sec_hasp_keys.nkeys); + log_info("Loaded %d keys", sec_hasp_keys.nkeys); } -int sec_hasp_api_login(int feature, int vendor_code, int* handle) +int sec_hasp_api_login(int feature, int vendor_code, int *handle) { - *handle = (int) &sec_hasp_key_id; + *handle = (int) &sec_hasp_key_id; - log_debug("login, feature %d, vendor_code %d, ret handle 0x%X", feature, - vendor_code, *handle); + log_debug( + "login, feature %d, vendor_code %d, ret handle 0x%X", + feature, + vendor_code, + *handle); - return 0; + return 0; } int sec_hasp_api_logout(int handle) { - if (handle != (int) &sec_hasp_key_id) { - log_error("Logout of unknown handle 0x%X", handle); - } else { - log_debug("Logout: 0x%X", handle); - } + if (handle != (int) &sec_hasp_key_id) { + log_error("Logout of unknown handle 0x%X", handle); + } else { + log_debug("Logout: 0x%X", handle); + } - return 0; + return 0; } unsigned int sec_hasp_api_getid(void) { - return sec_hasp_key_id; + return sec_hasp_key_id; } -int sec_hasp_api_decrypt(int handle, void* buffer, size_t length) +int sec_hasp_api_decrypt(int handle, void *buffer, size_t length) { - char* buf; + char *buf; - if (handle != (int) &sec_hasp_key_id) { - log_error("Unknown handle 0x%X sending decrypt request, ignored"); - return -1; + if (handle != (int) &sec_hasp_key_id) { + log_error("Unknown handle 0x%X sending decrypt request, ignored"); + return -1; + } + + for (uint32_t i = 0; i < sec_hasp_keys.nkeys; i++) { + if (!memcmp( + buffer, + sec_hasp_keys.keys[i].req, + sizeof(sec_hasp_keys.keys[i].req))) { + log_debug( + "Decrypt %u -> %u", + *((uint64_t *) sec_hasp_keys.keys[i].req), + *((uint64_t *) sec_hasp_keys.keys[i].resp)); + memcpy( + buffer, + sec_hasp_keys.keys[i].resp, + sizeof(sec_hasp_keys.keys[i].resp)); + return 0; } + } - for (uint32_t i = 0; i < sec_hasp_keys.nkeys; i++) { - if (!memcmp(buffer, sec_hasp_keys.keys[i].req, - sizeof(sec_hasp_keys.keys[i].req))) { - log_debug("Decrypt %u -> %u", - *((uint64_t*) sec_hasp_keys.keys[i].req), - *((uint64_t*) sec_hasp_keys.keys[i].resp)); - memcpy(buffer, sec_hasp_keys.keys[i].resp, - sizeof(sec_hasp_keys.keys[i].resp)); - return 0; - } - } + buf = util_str_buffer(buffer, length); - buf = util_str_buffer(buffer, length); + log_warn("Missing key for request %s", buf); + free(buf); - log_warn("Missing key for request %s", buf); - free(buf); - - return 0; + return 0; } \ No newline at end of file diff --git a/src/main/sec/hasp/old/hasp.h b/src/main/sec/hasp/old/hasp.h index 582ae0c..8236f9b 100644 --- a/src/main/sec/hasp/old/hasp.h +++ b/src/main/sec/hasp/old/hasp.h @@ -11,8 +11,8 @@ * A single entry in the key table */ struct sec_hasp_key { - uint8_t req[64]; - uint8_t resp[64]; + uint8_t req[64]; + uint8_t resp[64]; } __attribute__((packed)); /** @@ -22,14 +22,14 @@ struct sec_hasp_key { * @param key_data Pointer to loaded key data (key table) * @param len Length of the buffer */ -void sec_hasp_init(const uint8_t* key_data, size_t len); +void sec_hasp_init(const uint8_t *key_data, size_t len); -int sec_hasp_api_login(int feature, int vendor_code, int* handle); +int sec_hasp_api_login(int feature, int vendor_code, int *handle); int sec_hasp_api_logout(int handle); unsigned int sec_hasp_api_getid(void); -int sec_hasp_api_decrypt(int handle, void* buffer, size_t length); +int sec_hasp_api_decrypt(int handle, void *buffer, size_t length); #endif \ No newline at end of file diff --git a/src/main/sec/hasp/server/main.c b/src/main/sec/hasp/server/main.c index 7e1ddb8..68a4c5c 100644 --- a/src/main/sec/hasp/server/main.c +++ b/src/main/sec/hasp/server/main.c @@ -1,7 +1,7 @@ #include "sec/hasp/lib/server.h" -int main(int argc, char** argv) +int main(int argc, char **argv) { - sec_hasp_server_init(NULL, 0); - sec_hasp_server_run(); + sec_hasp_server_init(NULL, 0); + sec_hasp_server_run(); } \ No newline at end of file diff --git a/src/main/sec/lockchip/lockchip-defs.h b/src/main/sec/lockchip/lockchip-defs.h index 438537f..42a2b36 100644 --- a/src/main/sec/lockchip/lockchip-defs.h +++ b/src/main/sec/lockchip/lockchip-defs.h @@ -5,60 +5,60 @@ /* List of games using the old type mk3 lockchip board */ enum sec_lockchip_defs_games { - SEC_LOCK_CHIP_DEFS_GAME_3RD_SE = 0, - SEC_LOCK_CHIP_DEFS_GAME_COLLECTION = 1, - SEC_LOCK_CHIP_DEFS_GAME_PERFECT_COLLECTION = 2, - SEC_LOCK_CHIP_DEFS_GAME_EXTRA_PROTO = 3, - SEC_LOCK_CHIP_DEFS_GAME_PREMIERE = 4, - SEC_LOCK_CHIP_DEFS_GAME_PREX = 5, - SEC_LOCK_CHIP_DEFS_GAME_REBIRTH = 6, - SEC_LOCK_CHIP_DEFS_GAME_PREMIERE_2 = 7, - /* Extra Plus */ - SEC_LOCK_CHIP_DEFS_GAME_PREX_2_BETA = 8, - SEC_LOCK_CHIP_DEFS_GAME_PREX_2 = 9, - SEC_LOCK_CHIP_DEFS_GAME_PREMIERE_3 = 10, - SEC_LOCK_CHIP_DEFS_GAME_PREX_3 = 11, - SEC_LOCK_CHIP_DEFS_GAME_EXTRA = 12, - /* NXA for mk3, funbox... */ - SEC_LOCK_CHIP_DEFS_GAME_BOOTLEGS = 13, - SEC_LOCK_CHIP_DEFS_GAME_EXCEED = 14, - SEC_LOCK_CHIP_DEFS_GAME_COUNT = 15, + SEC_LOCK_CHIP_DEFS_GAME_3RD_SE = 0, + SEC_LOCK_CHIP_DEFS_GAME_COLLECTION = 1, + SEC_LOCK_CHIP_DEFS_GAME_PERFECT_COLLECTION = 2, + SEC_LOCK_CHIP_DEFS_GAME_EXTRA_PROTO = 3, + SEC_LOCK_CHIP_DEFS_GAME_PREMIERE = 4, + SEC_LOCK_CHIP_DEFS_GAME_PREX = 5, + SEC_LOCK_CHIP_DEFS_GAME_REBIRTH = 6, + SEC_LOCK_CHIP_DEFS_GAME_PREMIERE_2 = 7, + /* Extra Plus */ + SEC_LOCK_CHIP_DEFS_GAME_PREX_2_BETA = 8, + SEC_LOCK_CHIP_DEFS_GAME_PREX_2 = 9, + SEC_LOCK_CHIP_DEFS_GAME_PREMIERE_3 = 10, + SEC_LOCK_CHIP_DEFS_GAME_PREX_3 = 11, + SEC_LOCK_CHIP_DEFS_GAME_EXTRA = 12, + /* NXA for mk3, funbox... */ + SEC_LOCK_CHIP_DEFS_GAME_BOOTLEGS = 13, + SEC_LOCK_CHIP_DEFS_GAME_EXCEED = 14, + SEC_LOCK_CHIP_DEFS_GAME_COUNT = 15, }; /** List of lockchip transforms of all pump games that used it. */ -static const uint8_t sec_lockchip_defs_transforms - [SEC_LOCK_CHIP_DEFS_GAME_COUNT][8] = { - /* 3rd SE */ - {0xF0, 0x1C, 0xFE, 0x03, 0x81, 0x40, 0x38, 0xF8}, - /* Collection */ - {0xF0, 0x1C, 0xFE, 0x03, 0x81, 0x40, 0x38, 0xF8}, - /* Perfect Collection */ - {0xF0, 0x1C, 0xFE, 0x03, 0x81, 0x40, 0x38, 0xF8}, - /* Extra Proto */ - {0xF8, 0x82, 0x70, 0x0C, 0xFD, 0xC1, 0x20, 0xE0}, - /* Premiere */ - {0xE0, 0x78, 0x7C, 0xFD, 0xF1, 0xF2, 0xC2, 0xC0}, - /* Prex */ - {0xE0, 0x78, 0x7C, 0xFD, 0xF1, 0xF2, 0xC2, 0xC0}, - /* Rebirth */ - {0xFC, 0xF9, 0x08, 0x10, 0xE2, 0xC2, 0x40, 0x80}, - /* Premiere 2 */ - {0xFC, 0x03, 0xE1, 0x20, 0x38, 0x78, 0x70, 0xF0}, - /* Prex 2 Beta */ - {0xE0, 0x38, 0x78, 0x81, 0x03, 0xFE, 0x0C, 0xF0}, - /* Prex 2 */ - {0xE0, 0x38, 0x78, 0x81, 0x03, 0xFE, 0x0C, 0xF0}, - /* Premiere 3 */ - {0x02, 0xC1, 0xF9, 0x78, 0x7C, 0x1C, 0x10, 0xF0}, - /* Prex 3 */ - {0xF0, 0xE1, 0xF9, 0x78, 0x7C, 0xFE, 0xC2, 0xC0}, - /* Extra */ - {0xF8, 0x82, 0x70, 0x0C, 0xFD, 0xC1, 0x20, 0xE0}, - /* Bootlegs */ - {0x02, 0xC1, 0xF9, 0x78, 0x7C, 0x1C, 0x10, 0xF0}, - /* Exceed */ - {0xF0, 0x78, 0xF9, 0xFD, 0x1C, 0x20, 0xC2, 0x02}, +static const uint8_t + sec_lockchip_defs_transforms[SEC_LOCK_CHIP_DEFS_GAME_COUNT][8] = { + /* 3rd SE */ + {0xF0, 0x1C, 0xFE, 0x03, 0x81, 0x40, 0x38, 0xF8}, + /* Collection */ + {0xF0, 0x1C, 0xFE, 0x03, 0x81, 0x40, 0x38, 0xF8}, + /* Perfect Collection */ + {0xF0, 0x1C, 0xFE, 0x03, 0x81, 0x40, 0x38, 0xF8}, + /* Extra Proto */ + {0xF8, 0x82, 0x70, 0x0C, 0xFD, 0xC1, 0x20, 0xE0}, + /* Premiere */ + {0xE0, 0x78, 0x7C, 0xFD, 0xF1, 0xF2, 0xC2, 0xC0}, + /* Prex */ + {0xE0, 0x78, 0x7C, 0xFD, 0xF1, 0xF2, 0xC2, 0xC0}, + /* Rebirth */ + {0xFC, 0xF9, 0x08, 0x10, 0xE2, 0xC2, 0x40, 0x80}, + /* Premiere 2 */ + {0xFC, 0x03, 0xE1, 0x20, 0x38, 0x78, 0x70, 0xF0}, + /* Prex 2 Beta */ + {0xE0, 0x38, 0x78, 0x81, 0x03, 0xFE, 0x0C, 0xF0}, + /* Prex 2 */ + {0xE0, 0x38, 0x78, 0x81, 0x03, 0xFE, 0x0C, 0xF0}, + /* Premiere 3 */ + {0x02, 0xC1, 0xF9, 0x78, 0x7C, 0x1C, 0x10, 0xF0}, + /* Prex 3 */ + {0xF0, 0xE1, 0xF9, 0x78, 0x7C, 0xFE, 0xC2, 0xC0}, + /* Extra */ + {0xF8, 0x82, 0x70, 0x0C, 0xFD, 0xC1, 0x20, 0xE0}, + /* Bootlegs */ + {0x02, 0xC1, 0xF9, 0x78, 0x7C, 0x1C, 0x10, 0xF0}, + /* Exceed */ + {0xF0, 0x78, 0xF9, 0xFD, 0x1C, 0x20, 0xC2, 0x02}, }; #endif \ No newline at end of file diff --git a/src/main/sec/lockchip/lockchip.c b/src/main/sec/lockchip/lockchip.c index cf8e7f6..6892847 100644 --- a/src/main/sec/lockchip/lockchip.c +++ b/src/main/sec/lockchip/lockchip.c @@ -3,85 +3,84 @@ #include "sec/lockchip/lockchip.h" static const uint8_t sec_lockchip_initial_sbox[8] = { - 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x7f -}; + 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x7f}; -static const uint8_t* sec_lockchip_transform; +static const uint8_t *sec_lockchip_transform; static uint8_t sec_lockchip_state; static void sec_lockchip_apply_initial_sbox(void) { - uint8_t r = 0; + uint8_t r = 0; - for (uint8_t i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { - if (sec_lockchip_state & (1 << i)) { - r ^= sec_lockchip_initial_sbox[i]; - } - } + if (sec_lockchip_state & (1 << i)) { + r ^= sec_lockchip_initial_sbox[i]; + } + } - sec_lockchip_state = r; + sec_lockchip_state = r; } static uint8_t sec_lockchip_comp_sbox_ceof(uint8_t sel, uint8_t bit) { - uint8_t r ; + uint8_t r; - if (!sel) { - return sec_lockchip_transform[bit]; - } + if (!sel) { + return sec_lockchip_transform[bit]; + } - r = sec_lockchip_comp_sbox_ceof((sel - 1) & 7, (bit - 1) & 7); - r = (r << 1) | (((r >> 7) ^ (r >> 6)) & 1); + r = sec_lockchip_comp_sbox_ceof((sel - 1) & 7, (bit - 1) & 7); + r = (r << 1) | (((r >> 7) ^ (r >> 6)) & 1); - if (bit != 7) { - return r; - } + if (bit != 7) { + return r; + } - return r ^ sec_lockchip_comp_sbox_ceof(sel, 0); + return r ^ sec_lockchip_comp_sbox_ceof(sel, 0); } static void sec_lockchip_apply_bit_sbox(uint8_t bit) { - uint8_t r = 0; + uint8_t r = 0; - for (uint8_t i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { - if (sec_lockchip_state & (1 << i)) { - r ^= sec_lockchip_comp_sbox_ceof(bit, i); - } - } + if (sec_lockchip_state & (1 << i)) { + r ^= sec_lockchip_comp_sbox_ceof(bit, i); + } + } - sec_lockchip_state = r; + sec_lockchip_state = r; } -void sec_lockchip_init(const uint8_t* transform) +void sec_lockchip_init(const uint8_t *transform) { - sec_lockchip_transform = transform; - sec_lockchip_state = 0; + sec_lockchip_transform = transform; + sec_lockchip_state = 0; } void sec_lockchip_start(void) { - sec_lockchip_state = 0xFC; + sec_lockchip_state = 0xFC; } uint8_t sec_lockchip_step(uint8_t data) { - uint8_t result = 0; + uint8_t result = 0; - for (uint8_t bit = 0; bit < 8; bit++) { + for (uint8_t bit = 0; bit < 8; bit++) { - if (bit == 0) { - sec_lockchip_apply_initial_sbox(); - } + if (bit == 0) { + sec_lockchip_apply_initial_sbox(); + } - result ^= (((sec_lockchip_state >> bit) & 1) << bit); + result ^= (((sec_lockchip_state >> bit) & 1) << bit); - if (((data >> bit) & 1) == 0) { - sec_lockchip_apply_bit_sbox(bit); - } - } + if (((data >> bit) & 1) == 0) { + sec_lockchip_apply_bit_sbox(bit); + } + } - return result; + return result; } \ No newline at end of file diff --git a/src/main/sec/lockchip/lockchip.h b/src/main/sec/lockchip/lockchip.h index 9034763..56a48dc 100644 --- a/src/main/sec/lockchip/lockchip.h +++ b/src/main/sec/lockchip/lockchip.h @@ -13,7 +13,7 @@ * * @param transform Pointer to a transform to use for the step calls */ -void sec_lockchip_init(const uint8_t* transform); +void sec_lockchip_init(const uint8_t *transform); /** * Start lockchip emulation and set the initial state before calling step diff --git a/src/main/sec/microdog34/microdog34.c b/src/main/sec/microdog34/microdog34.c index a9902aa..c1a348f 100644 --- a/src/main/sec/microdog34/microdog34.c +++ b/src/main/sec/microdog34/microdog34.c @@ -12,388 +12,400 @@ #define MAGIC 0x484D enum sec_microdog34_req_opcode { - SEC_MICRODOG34_OP_DOG_CHECK = 0x01, - SEC_MICRODOG34_OP_READ_DOG = 0x02, - SEC_MICRODOG34_OP_WRITE_DOG = 0x03, - SEC_MICRODOG34_OP_CONVERT = 0x04, - SEC_MICRODOG34_OP_SET_PASS = 0x07, - SEC_MICRODOG34_OP_SET_SHARE = 0x08, - SEC_MICRODOG34_OP_GET_LOCK_NO = 0x0B, - SEC_MICRODOG34_OP_LOGIN = 0x14, - SEC_MICRODOG34_OP_DOG_CASCADE = 0x15, - SEC_MICRODOG34_OP_RAINBOW_TABLE_ADD = 0x539, - SEC_MICRODOG34_OP_DOG_SERIAL = 0x53A, - SEC_MICRODOG34_OP_SET_MFG_SERIAL = 0x53B, - SEC_MICRODOG34_OP_SET_VID = 0x53C, - SEC_MICRODOG34_OP_RELOAD_RAINBOW_TABLE = 0x53D + SEC_MICRODOG34_OP_DOG_CHECK = 0x01, + SEC_MICRODOG34_OP_READ_DOG = 0x02, + SEC_MICRODOG34_OP_WRITE_DOG = 0x03, + SEC_MICRODOG34_OP_CONVERT = 0x04, + SEC_MICRODOG34_OP_SET_PASS = 0x07, + SEC_MICRODOG34_OP_SET_SHARE = 0x08, + SEC_MICRODOG34_OP_GET_LOCK_NO = 0x0B, + SEC_MICRODOG34_OP_LOGIN = 0x14, + SEC_MICRODOG34_OP_DOG_CASCADE = 0x15, + SEC_MICRODOG34_OP_RAINBOW_TABLE_ADD = 0x539, + SEC_MICRODOG34_OP_DOG_SERIAL = 0x53A, + SEC_MICRODOG34_OP_SET_MFG_SERIAL = 0x53B, + SEC_MICRODOG34_OP_SET_VID = 0x53C, + SEC_MICRODOG34_OP_RELOAD_RAINBOW_TABLE = 0x53D }; struct sec_microdog34_req { - uint16_t magic; - uint16_t opcode; - uint32_t dog_serial; - uint32_t mask_key; - uint16_t dog_addr; - uint16_t dog_bytes; - uint8_t dog_data[256]; - uint32_t dog_password; - uint8_t host_id; + uint16_t magic; + uint16_t opcode; + uint32_t dog_serial; + uint32_t mask_key; + uint16_t dog_addr; + uint16_t dog_bytes; + uint8_t dog_data[256]; + uint32_t dog_password; + uint8_t host_id; } __attribute__((__packed__)); enum sec_microdog34_resp_code { - SEC_MICRODOG34_RESP_NO_ERR = 0, - SEC_MICRODOG34_RESP_ERR_PASS = 0x2745 + SEC_MICRODOG34_RESP_NO_ERR = 0, + SEC_MICRODOG34_RESP_ERR_PASS = 0x2745 }; struct sec_microdog34_resp { - uint32_t dog_serial; - uint32_t return_code; - uint8_t dog_data[200]; + uint32_t dog_serial; + uint32_t return_code; + uint8_t dog_data[200]; } __attribute__((__packed__)); struct sec_microdog34_header { - uint32_t serial; - uint32_t password; - uint8_t vendor_id[8]; - uint32_t mfg_serial; - uint8_t flash_memory[200]; - uint32_t num_keys; + uint32_t serial; + uint32_t password; + uint8_t vendor_id[8]; + uint32_t mfg_serial; + uint8_t flash_memory[200]; + uint32_t num_keys; }; struct sec_microdog34_key { - uint32_t response; - uint32_t algorithm; - uint32_t req_len; - uint8_t request[64]; + uint32_t response; + uint32_t algorithm; + uint32_t req_len; + uint8_t request[64]; }; -static void sec_microdog34_dispatch(struct sec_microdog34_req* req, - struct sec_microdog34_resp* resp); -static void sec_microdog34_crypt_req(struct sec_microdog34_req* req); -static void sec_microdog34_crypt_resp(struct sec_microdog34_req* req, - struct sec_microdog34_resp* resp); -static void sec_microdog34_dump_req(struct sec_microdog34_req* req); -static void sec_microdog34_dump_resq(struct sec_microdog34_resp* resp); -static uint32_t sec_microdog34_convert_req(const uint8_t* req_data, - uint16_t req_len); +static void sec_microdog34_dispatch( + struct sec_microdog34_req *req, struct sec_microdog34_resp *resp); +static void sec_microdog34_crypt_req(struct sec_microdog34_req *req); +static void sec_microdog34_crypt_resp( + struct sec_microdog34_req *req, struct sec_microdog34_resp *resp); +static void sec_microdog34_dump_req(struct sec_microdog34_req *req); +static void sec_microdog34_dump_resq(struct sec_microdog34_resp *resp); +static uint32_t +sec_microdog34_convert_req(const uint8_t *req_data, uint16_t req_len); static struct sec_microdog34_header sec_microdog34_header; -static struct sec_microdog34_key* sec_microdog34_key_table; +static struct sec_microdog34_key *sec_microdog34_key_table; static uint8_t sec_microdog34_share; -void sec_microdog34_init(const uint8_t* key_data, size_t len) +void sec_microdog34_init(const uint8_t *key_data, size_t len) { - memcpy(&sec_microdog34_header, key_data, - sizeof(struct sec_microdog34_header)); + memcpy( + &sec_microdog34_header, key_data, sizeof(struct sec_microdog34_header)); - if (len - sizeof(struct sec_microdog34_header) < - sec_microdog34_header.num_keys * - sizeof(struct sec_microdog34_key)) { - log_error("Loading key table failed, incomplete key table " - "(num_keys entry: %d, num_keys size: %d", - sec_microdog34_header.num_keys, - (len - sizeof(struct sec_microdog34_header)) / - sizeof(struct sec_microdog34_key)); - return; + if (len - sizeof(struct sec_microdog34_header) < + sec_microdog34_header.num_keys * sizeof(struct sec_microdog34_key)) { + log_error( + "Loading key table failed, incomplete key table " + "(num_keys entry: %d, num_keys size: %d", + sec_microdog34_header.num_keys, + (len - sizeof(struct sec_microdog34_header)) / + sizeof(struct sec_microdog34_key)); + return; + } + + sec_microdog34_key_table = util_xmalloc( + sec_microdog34_header.num_keys * sizeof(struct sec_microdog34_key)); + + memcpy( + sec_microdog34_key_table, + key_data + sizeof(struct sec_microdog34_header), + sec_microdog34_header.num_keys * sizeof(struct sec_microdog34_key)); + + log_info( + "Loaded %d keys, serial 0x%X, password 0x%X", + sec_microdog34_header.num_keys, + sec_microdog34_header.serial, + sec_microdog34_header.password); + + sec_microdog34_share = 0; +} + +int sec_microdog34_process(int request, void *data) +{ + if (request == IOCTL_REQUEST_MD_XACT) { + struct sec_microdog34_req req; + struct sec_microdog34_resp resp; + + memset(&resp, 0, sizeof(struct sec_microdog34_resp)); + + // where to get the data? weird stuff, but that's how it's done + // it really has to be like that, otherwise we get trash from data + uint32_t req_data_offset = *(unsigned int *) data; + memcpy(&req, (void *) req_data_offset, sizeof(struct sec_microdog34_req)); + + sec_microdog34_crypt_req(&req); + sec_microdog34_dispatch(&req, &resp); + sec_microdog34_crypt_resp(&req, &resp); + + // again, same as req data + // it really has to be like that, otherwise we get trash from data + uint32_t resp_data_offset = *(unsigned int *) data - 272; + memcpy( + (void *) resp_data_offset, &resp, sizeof(struct sec_microdog34_resp)); + + return 0; + } + + return -1; +} + +static void sec_microdog34_dispatch( + struct sec_microdog34_req *req, struct sec_microdog34_resp *resp) +{ + struct sec_microdog34_key *key; + + resp->dog_serial = req->dog_serial; + + if (req->magic != MAGIC) { + log_error("Bad magic 0x%X for request", req->magic); + } + + sec_microdog34_dump_req(req); + + switch (req->opcode) { + case SEC_MICRODOG34_OP_DOG_CHECK: + log_debug("SEC_MICRODOG34_OP_DOG_CHECK"); + break; + + case SEC_MICRODOG34_OP_READ_DOG: + log_debug("SEC_MICRODOG34_OP_READ_DOG"); + + if (req->dog_password == sec_microdog34_header.password) { + memcpy( + resp->dog_data, + sec_microdog34_header.flash_memory + req->dog_addr, + req->dog_bytes); + } else { + resp->return_code = SEC_MICRODOG34_RESP_ERR_PASS; + } + + break; + + case SEC_MICRODOG34_OP_WRITE_DOG: + log_debug("SEC_MICRODOG34_OP_WRITE_DOG"); + + if (req->dog_password == sec_microdog34_header.password) { + memcpy( + sec_microdog34_header.flash_memory + req->dog_addr, + req->dog_data, + req->dog_bytes); + } else { + resp->return_code = SEC_MICRODOG34_RESP_ERR_PASS; + } + + break; + + case SEC_MICRODOG34_OP_CONVERT: + log_debug("SEC_MICRODOG34_OP_CONVERT"); + + uint32_t resp_data = + sec_microdog34_convert_req(req->dog_data, req->dog_bytes); + memcpy(resp->dog_data, &resp_data, sizeof(uint32_t)); + + break; + + case SEC_MICRODOG34_OP_SET_PASS: + log_debug( + "SEC_MICRODOG34_OP_SET_PASS: 0x%08X", *((uint32_t *) req->dog_data)); + + if (req->dog_password == sec_microdog34_header.password) { + sec_microdog34_header.password = *((uint32_t *) req->dog_data); + } else + resp->return_code = SEC_MICRODOG34_RESP_ERR_PASS; + + break; + + case SEC_MICRODOG34_OP_SET_SHARE: + log_debug("SEC_MICRODOG34_OP_SET_SHARE"); + + sec_microdog34_share = req->dog_data[0]; + resp->dog_data[0] = sec_microdog34_share; + + break; + + case SEC_MICRODOG34_OP_GET_LOCK_NO: + log_debug( + "SEC_MICRODOG34_OP_GET_LOCK_NO: 0x%08X", + sec_microdog34_header.mfg_serial); + + memcpy(resp->dog_data, &sec_microdog34_header.mfg_serial, 4); + + break; + + case SEC_MICRODOG34_OP_LOGIN: + log_debug("SEC_MICRODOG34_OP_LOGIN"); + + memcpy( + resp->dog_data, + sec_microdog34_header.vendor_id, + sizeof(sec_microdog34_header.vendor_id)); + + break; + + case SEC_MICRODOG34_OP_DOG_CASCADE: + log_debug("SEC_MICRODOG34_OP_DOG_CASCADE"); + + resp->dog_data[0] = req->dog_data[0]; + + break; + + case SEC_MICRODOG34_OP_RAINBOW_TABLE_ADD: + log_debug("SEC_MICRODOG34_OP_RAINBOW_TABLE_ADD"); + + /* expand table */ + sec_microdog34_key_table = util_xrealloc( + sec_microdog34_key_table, + (sec_microdog34_header.num_keys + 1) * + sizeof(struct sec_microdog34_key)); + + key = &sec_microdog34_key_table[sec_microdog34_header.num_keys]; + key->response = req->dog_password; + /* algorithm(last 4 bytes of flash memory) */ + key->algorithm = + *((uint32_t *) (sec_microdog34_header.flash_memory + 196)); + key->req_len = req->dog_bytes; + memcpy(key->request, req->dog_data, sizeof(key->request)); + + sec_microdog34_header.num_keys++; + + break; + + case SEC_MICRODOG34_OP_DOG_SERIAL: + log_debug( + "SEC_MICRODOG34_OP_DOG_SERIAL: 0x%08X", + *((uint32_t *) req->dog_data)); + + sec_microdog34_header.serial = *((uint32_t *) req->dog_data); + + break; + + case SEC_MICRODOG34_OP_SET_MFG_SERIAL: + log_debug( + "SEC_MICRODOG34_OP_SET_MFG_SERIAL: 0x%08X ", + *((uint32_t *) req->dog_data)); + + sec_microdog34_header.mfg_serial = *((uint32_t *) req->dog_data); + + break; + + case SEC_MICRODOG34_OP_SET_VID: + log_debug("SEC_MICRODOG34_OP_SET_VID"); + + memcpy( + sec_microdog34_header.vendor_id, + req->dog_data, + sizeof(sec_microdog34_header.vendor_id)); + + break; + + case SEC_MICRODOG34_OP_RELOAD_RAINBOW_TABLE: + log_debug("SEC_MICRODOG34_OP_RELOAD_RAINBOW_TABLE"); + + /* nothing to load here */ + break; + + default: + log_warn("Unsupported opcode: %04X", req->opcode); + break; + } + + sec_microdog34_dump_resq(resp); +} + +static void sec_microdog34_crypt_req(struct sec_microdog34_req *req) +{ + uint32_t tmp_mask = (req->mask_key + GOLD_SALT) & 0xFFFFFFFF; + uint8_t tmb_mask[4] = {0, 0, 0, 0}; + memcpy(tmb_mask, &tmp_mask, 4); + + req->dog_addr ^= (tmp_mask & 0xFFFF); + req->dog_bytes ^= (tmp_mask & 0xFFFF); + req->dog_password ^= tmp_mask; + req->host_id ^= (tmp_mask & 0xFF); + + for (int i = 0; i < sizeof(req->dog_data); i++) { + req->dog_data[i] ^= tmb_mask[i % 4]; + } +} + +static void sec_microdog34_crypt_resp( + struct sec_microdog34_req *req, struct sec_microdog34_resp *resp) +{ + uint32_t tmp_mask = (req->mask_key + GOLD_SALT) & 0xFFFFFFFF; + uint8_t tmb_mask[4] = {0, 0, 0, 0}; + memcpy(tmb_mask, &tmp_mask, 4); + + for (int i = 0; i < sizeof(resp->dog_data); i++) { + resp->dog_data[i] ^= tmb_mask[i % 4]; + } +} + +static void sec_microdog34_dump_req(struct sec_microdog34_req *req) +{ + char *data_tmp = util_str_buffer(req->dog_data, sizeof(req->dog_data)); + + log_debug( + "Dog request:\n" + "magic: 0x%X\n" + "opcode: 0x%X\n" + "dog_serial: 0x%X\n" + "mask_key: 0x%X\n" + "dog_addr: 0x%X\n" + "dog_bytes: 0x%X\n" + "dog_data: %s\n" + "dog_pass: 0x%X\n" + "host_id: 0x%X", + req->magic, + req->opcode, + req->dog_serial, + req->mask_key, + req->dog_addr, + req->dog_bytes, + data_tmp, + req->dog_password, + req->host_id); + + free(data_tmp); +} + +static void sec_microdog34_dump_resq(struct sec_microdog34_resp *resp) +{ + char *data_tmp = util_str_buffer(resp->dog_data, sizeof(resp->dog_data)); + + log_debug( + "Dog response:\n" + "dog_serial: 0x%X\n" + "return_code: 0x%X\n" + "dog_data: %s\n", + resp->dog_serial, + resp->return_code, + data_tmp); + + free(data_tmp); +} + +static uint32_t +sec_microdog34_convert_req(const uint8_t *req_data, uint16_t req_len) +{ + uint32_t cur_algo; + + cur_algo = 0; + memcpy(&cur_algo, sec_microdog34_header.flash_memory + 196, 4); + + for (uint32_t i = 0; i < sec_microdog34_header.num_keys; i++) { + struct sec_microdog34_key *key = &sec_microdog34_key_table[i]; + + if (key->algorithm == cur_algo) { + + if (key->req_len == req_len) { + + if (!memcmp(key->request, req_data, req_len)) { + char *tmp = util_str_buffer(req_data, req_len); + log_debug("Converting: %s ==> %X", tmp, key->response); + free(tmp); + return key->response; + } + } } + } - sec_microdog34_key_table = util_xmalloc(sec_microdog34_header.num_keys * - sizeof(struct sec_microdog34_key)); - - memcpy(sec_microdog34_key_table, - key_data + sizeof(struct sec_microdog34_header), - sec_microdog34_header.num_keys * sizeof(struct sec_microdog34_key)); - - log_info("Loaded %d keys, serial 0x%X, password 0x%X", - sec_microdog34_header.num_keys, sec_microdog34_header.serial, - sec_microdog34_header.password); - - sec_microdog34_share = 0; -} - -int sec_microdog34_process(int request, void* data) -{ - if (request == IOCTL_REQUEST_MD_XACT) { - struct sec_microdog34_req req; - struct sec_microdog34_resp resp; - - memset(&resp, 0, sizeof(struct sec_microdog34_resp)); - - // where to get the data? weird stuff, but that's how it's done - // it really has to be like that, otherwise we get trash from data - uint32_t req_data_offset = *(unsigned int*) data; - memcpy(&req, (void*) req_data_offset, - sizeof(struct sec_microdog34_req)); - - sec_microdog34_crypt_req(&req); - sec_microdog34_dispatch(&req, &resp); - sec_microdog34_crypt_resp(&req, &resp); - - // again, same as req data - // it really has to be like that, otherwise we get trash from data - uint32_t resp_data_offset = *(unsigned int*) data - 272; - memcpy((void*) resp_data_offset, &resp, - sizeof(struct sec_microdog34_resp)); - - return 0; - } - - return -1; -} - -static void sec_microdog34_dispatch(struct sec_microdog34_req* req, - struct sec_microdog34_resp* resp) -{ - struct sec_microdog34_key* key; - - resp->dog_serial = req->dog_serial; - - if (req->magic != MAGIC) { - log_error("Bad magic 0x%X for request", req->magic); - } - - sec_microdog34_dump_req(req); - - switch (req->opcode) { - case SEC_MICRODOG34_OP_DOG_CHECK: - log_debug("SEC_MICRODOG34_OP_DOG_CHECK"); - break; - - case SEC_MICRODOG34_OP_READ_DOG: - log_debug("SEC_MICRODOG34_OP_READ_DOG"); - - if (req->dog_password == sec_microdog34_header.password) { - memcpy(resp->dog_data, - sec_microdog34_header.flash_memory + req->dog_addr, - req->dog_bytes); - } else { - resp->return_code = SEC_MICRODOG34_RESP_ERR_PASS; - } - - break; - - case SEC_MICRODOG34_OP_WRITE_DOG: - log_debug("SEC_MICRODOG34_OP_WRITE_DOG"); - - if (req->dog_password == sec_microdog34_header.password) { - memcpy(sec_microdog34_header.flash_memory + req->dog_addr, - req->dog_data, req->dog_bytes); - } else { - resp->return_code = SEC_MICRODOG34_RESP_ERR_PASS; - } - - break; - - case SEC_MICRODOG34_OP_CONVERT: - log_debug("SEC_MICRODOG34_OP_CONVERT"); - - uint32_t resp_data = sec_microdog34_convert_req(req->dog_data, - req->dog_bytes); - memcpy(resp->dog_data, &resp_data, sizeof(uint32_t)); - - break; - - case SEC_MICRODOG34_OP_SET_PASS: - log_debug("SEC_MICRODOG34_OP_SET_PASS: 0x%08X", - *((uint32_t*) req->dog_data)); - - if (req->dog_password == sec_microdog34_header.password) { - sec_microdog34_header.password = *((uint32_t*) req->dog_data); - } - else - resp->return_code = SEC_MICRODOG34_RESP_ERR_PASS; - - break; - - case SEC_MICRODOG34_OP_SET_SHARE: - log_debug("SEC_MICRODOG34_OP_SET_SHARE"); - - sec_microdog34_share = req->dog_data[0]; - resp->dog_data[0] = sec_microdog34_share; - - break; - - case SEC_MICRODOG34_OP_GET_LOCK_NO: - log_debug("SEC_MICRODOG34_OP_GET_LOCK_NO: 0x%08X", - sec_microdog34_header.mfg_serial); - - memcpy(resp->dog_data, &sec_microdog34_header.mfg_serial, 4); - - break; - - case SEC_MICRODOG34_OP_LOGIN: - log_debug("SEC_MICRODOG34_OP_LOGIN"); - - memcpy(resp->dog_data, sec_microdog34_header.vendor_id, - sizeof(sec_microdog34_header.vendor_id)); - - break; - - case SEC_MICRODOG34_OP_DOG_CASCADE: - log_debug("SEC_MICRODOG34_OP_DOG_CASCADE"); - - resp->dog_data[0] = req->dog_data[0]; - - break; - - case SEC_MICRODOG34_OP_RAINBOW_TABLE_ADD: - log_debug("SEC_MICRODOG34_OP_RAINBOW_TABLE_ADD"); - - /* expand table */ - sec_microdog34_key_table = util_xrealloc(sec_microdog34_key_table, - (sec_microdog34_header.num_keys + 1) * - sizeof(struct sec_microdog34_key)); - - key = &sec_microdog34_key_table[sec_microdog34_header.num_keys]; - key->response = req->dog_password; - /* algorithm(last 4 bytes of flash memory) */ - key->algorithm = - *((uint32_t*) (sec_microdog34_header.flash_memory + 196)); - key->req_len = req->dog_bytes; - memcpy(key->request, req->dog_data, sizeof(key->request)); - - sec_microdog34_header.num_keys++; - - break; - - case SEC_MICRODOG34_OP_DOG_SERIAL: - log_debug("SEC_MICRODOG34_OP_DOG_SERIAL: 0x%08X", - *((uint32_t*) req->dog_data)); - - sec_microdog34_header.serial = *((uint32_t*) req->dog_data); - - break; - - case SEC_MICRODOG34_OP_SET_MFG_SERIAL: - log_debug("SEC_MICRODOG34_OP_SET_MFG_SERIAL: 0x%08X ", - *((uint32_t*) req->dog_data)); - - sec_microdog34_header.mfg_serial = *((uint32_t*) req->dog_data); - - break; - - case SEC_MICRODOG34_OP_SET_VID: - log_debug("SEC_MICRODOG34_OP_SET_VID"); - - memcpy(sec_microdog34_header.vendor_id, req->dog_data, - sizeof(sec_microdog34_header.vendor_id)); - - break; - - case SEC_MICRODOG34_OP_RELOAD_RAINBOW_TABLE: - log_debug("SEC_MICRODOG34_OP_RELOAD_RAINBOW_TABLE"); - - /* nothing to load here */ - break; - - default: - log_warn("Unsupported opcode: %04X", req->opcode); - break; - } - - sec_microdog34_dump_resq(resp); -} - -static void sec_microdog34_crypt_req(struct sec_microdog34_req* req) -{ - uint32_t tmp_mask = (req->mask_key + GOLD_SALT) & 0xFFFFFFFF; - uint8_t tmb_mask[4] = {0, 0, 0, 0}; - memcpy(tmb_mask, &tmp_mask, 4); - - req->dog_addr ^= (tmp_mask & 0xFFFF); - req->dog_bytes ^= (tmp_mask & 0xFFFF); - req->dog_password ^= tmp_mask; - req->host_id ^= (tmp_mask & 0xFF); - - for (int i = 0 ; i < sizeof(req->dog_data); i++) { - req->dog_data[i] ^= tmb_mask[i % 4]; - } -} - -static void sec_microdog34_crypt_resp(struct sec_microdog34_req* req, - struct sec_microdog34_resp* resp) -{ - uint32_t tmp_mask = (req->mask_key + GOLD_SALT) & 0xFFFFFFFF; - uint8_t tmb_mask[4] = {0, 0, 0, 0}; - memcpy(tmb_mask, &tmp_mask, 4); - - for (int i = 0 ; i < sizeof(resp->dog_data); i++) { - resp->dog_data[i] ^= tmb_mask[i % 4]; - } -} - -static void sec_microdog34_dump_req(struct sec_microdog34_req* req) -{ - char* data_tmp = util_str_buffer(req->dog_data, sizeof(req->dog_data)); - - log_debug( - "Dog request:\n" - "magic: 0x%X\n" - "opcode: 0x%X\n" - "dog_serial: 0x%X\n" - "mask_key: 0x%X\n" - "dog_addr: 0x%X\n" - "dog_bytes: 0x%X\n" - "dog_data: %s\n" - "dog_pass: 0x%X\n" - "host_id: 0x%X", - req->magic, - req->opcode, - req->dog_serial, - req->mask_key, - req->dog_addr, - req->dog_bytes, - data_tmp, - req->dog_password, - req->host_id); - - free(data_tmp); -} - -static void sec_microdog34_dump_resq(struct sec_microdog34_resp* resp) -{ - char* data_tmp = util_str_buffer(resp->dog_data, sizeof(resp->dog_data)); - - log_debug( - "Dog response:\n" - "dog_serial: 0x%X\n" - "return_code: 0x%X\n" - "dog_data: %s\n", - resp->dog_serial, - resp->return_code, - data_tmp); - - free(data_tmp); -} - -static uint32_t sec_microdog34_convert_req(const uint8_t* req_data, - uint16_t req_len) -{ - uint32_t cur_algo; - - cur_algo = 0; - memcpy(&cur_algo, sec_microdog34_header.flash_memory + 196, 4); - - for (uint32_t i = 0; i < sec_microdog34_header.num_keys; i++) { - struct sec_microdog34_key* key = &sec_microdog34_key_table[i]; - - if (key->algorithm == cur_algo) { - - if (key->req_len == req_len) { - - if (!memcmp(key->request, req_data, req_len)) { - char* tmp = util_str_buffer(req_data, req_len); - log_debug("Converting: %s ==> %X", tmp, key->response); - free(tmp); - return key->response; - } - } - } - } - - char* tmp = util_str_buffer(req_data, req_len); - log_warn("Converting request %s failed, no matching response found", tmp); - free(tmp); - return 0; + char *tmp = util_str_buffer(req_data, req_len); + log_warn("Converting request %s failed, no matching response found", tmp); + free(tmp); + return 0; } \ No newline at end of file diff --git a/src/main/sec/microdog34/microdog34.h b/src/main/sec/microdog34/microdog34.h index 04d75d8..33034f3 100644 --- a/src/main/sec/microdog34/microdog34.h +++ b/src/main/sec/microdog34/microdog34.h @@ -11,22 +11,22 @@ * by an arbitrary number of keys */ struct sec_microdog34_header { - uint32_t serial; - uint32_t password; - uint8_t vendor_id[8]; - uint32_t mfg_serial; - uint8_t flash_memory[200]; - uint32_t num_keys; + uint32_t serial; + uint32_t password; + uint8_t vendor_id[8]; + uint32_t mfg_serial; + uint8_t flash_memory[200]; + uint32_t num_keys; }; /** * A single entry in the key table (comes after the header) */ struct sec_microdog34_key { - uint32_t response; - uint32_t algorithm; - uint32_t req_len; - uint8_t request[64]; + uint32_t response; + uint32_t algorithm; + uint32_t req_len; + uint8_t request[64]; }; /** @@ -36,7 +36,7 @@ struct sec_microdog34_key { * @param key_data Pointer to loaded key data (dog attributes, key table) * @param len Length of the buffer */ -void sec_microdog34_init(const uint8_t* key_data, size_t len); +void sec_microdog34_init(const uint8_t *key_data, size_t len); /** * Process an incoming request to the dongle @@ -46,6 +46,6 @@ void sec_microdog34_init(const uint8_t* key_data, size_t len); * to the same buffer (request overwritten) * @return 0 and success, -1 on failure */ -int sec_microdog34_process(int request, void* data); +int sec_microdog34_process(int request, void *data); #endif \ No newline at end of file diff --git a/src/main/sec/microdog40/main.c b/src/main/sec/microdog40/main.c index 78f432f..981eb06 100644 --- a/src/main/sec/microdog40/main.c +++ b/src/main/sec/microdog40/main.c @@ -1,54 +1,52 @@ -#include #include +#include #include "hook/patch/microdog40.c" -#include "util/log.h" #include "util/fs.h" +#include "util/log.h" #include "util/mem.h" void shutdown(int); int main(int argc, char *argv[]) { - if (argc < 2) { - printf( "Usage: %s [debug]\n", argv[0] ); - return 1; + if (argc < 2) { + printf("Usage: %s [debug]\n", argv[0]); + return 1; + } + + for (int i = 0; i < argc; i++) { + if (!strcmp(argv[i], "debug")) { + util_log_set_level(LOG_LEVEL_DEBUG); + break; } + } - for (int i = 0; i < argc; i++) { - if (!strcmp(argv[i], "debug")) { - util_log_set_level(LOG_LEVEL_DEBUG); - break; - } - } + size_t key_data_len; + void *key_data; - size_t key_data_len; - void* key_data; + if (!util_file_load(argv[1], &key_data, &key_data_len, false)) { + log_error("Loading key file %s failed", argv[1]); + return 2; + } - if (!util_file_load(argv[1], &key_data, &key_data_len, false)) { - log_error("Loading key file %s failed", argv[1]); - return 2; - } + log_info("Running Microdog 4.0 Emulator"); + patch_microdog40_init(key_data, key_data_len); + util_xfree(&key_data); - log_info("Running Microdog 4.0 Emulator"); - patch_microdog40_init(key_data, key_data_len); - util_xfree(&key_data); - - signal(SIGINT, shutdown); + signal(SIGINT, shutdown); - // Run Daemon - while(true) { - sleep(2); + // Run Daemon + while (true) { + sleep(2); - if (!sec_microdog40d_is_running()){ - return 0; - } + if (!sec_microdog40d_is_running()) { + return 0; } + } } void shutdown(int sig) { - patch_microdog40_shutdown(); + patch_microdog40_shutdown(); } - - diff --git a/src/main/sec/microdog40/microdog40.c b/src/main/sec/microdog40/microdog40.c index c58ee10..8c4c567 100644 --- a/src/main/sec/microdog40/microdog40.c +++ b/src/main/sec/microdog40/microdog40.c @@ -16,149 +16,158 @@ #define PROTOCOL_VERSION 0x11 enum sec_microdog40_req_opcode { - SEC_MICRODOG40_REQ_OPCODE_DOG_CHECK = 0x01, - SEC_MICRODOG40_REQ_OPCODE_SET_SHARE = 0x08, - SEC_MICRODOG40_REQ_OPCODE_GET_LOCK_NO = 0x0B, - SEC_MICRODOG40_REQ_OPCODE_GET_ID = 0x14, - SEC_MICRODOG40_REQ_OPCODE_CONVERT = 0x40, - SEC_MICRODOG40_REQ_OPCODE_AUTH_STEP_1 = 0x65, - SEC_MICRODOG40_REQ_OPCODE_AUTH_STEP_2 = 0x67, - SEC_MICRODOG40_REQ_OPCODE_AUTH_STEP_3 = 0x66 + SEC_MICRODOG40_REQ_OPCODE_DOG_CHECK = 0x01, + SEC_MICRODOG40_REQ_OPCODE_SET_SHARE = 0x08, + SEC_MICRODOG40_REQ_OPCODE_GET_LOCK_NO = 0x0B, + SEC_MICRODOG40_REQ_OPCODE_GET_ID = 0x14, + SEC_MICRODOG40_REQ_OPCODE_CONVERT = 0x40, + SEC_MICRODOG40_REQ_OPCODE_AUTH_STEP_1 = 0x65, + SEC_MICRODOG40_REQ_OPCODE_AUTH_STEP_2 = 0x67, + SEC_MICRODOG40_REQ_OPCODE_AUTH_STEP_3 = 0x66 }; struct sec_microdog40_month_key_hash_input { - uint8_t ssk_prefix[25]; - uint16_t year; - uint8_t const45; - uint16_t month; + uint8_t ssk_prefix[25]; + uint16_t year; + uint8_t const45; + uint16_t month; } __attribute((__packed__)); static const uint8_t sec_microdog40_shared_secret[30] = { - 0x2A, 0x2F, 0xED, 0x5E, 0x49, - 0x26, 0x40, 0x19, 0x40, 0x40, - 0xE2, 0x51, 0xAA, 0xFA, 0xDB, - 0xCB, 0x67, 0x21, 0x4C, 0xA4, - 0x10, 0x7E, 0x51, 0x22, 0x25, - 0x11, 0x2B, 0x3C, 0x46, 0x5E -}; + 0x2A, 0x2F, 0xED, 0x5E, 0x49, 0x26, 0x40, 0x19, 0x40, 0x40, + 0xE2, 0x51, 0xAA, 0xFA, 0xDB, 0xCB, 0x67, 0x21, 0x4C, 0xA4, + 0x10, 0x7E, 0x51, 0x22, 0x25, 0x11, 0x2B, 0x3C, 0x46, 0x5E}; static const uint16_t sec_microdog40_magic = 0x484D; static struct sec_microdog40_header sec_microdog40_header; -static struct sec_microdog40_key* sec_microdog40_key_table; +static struct sec_microdog40_key *sec_microdog40_key_table; static uint8_t sec_microdog40_share; -static void sec_microdog40_log_req(const struct sec_microdog40_req* req) +static void sec_microdog40_log_req(const struct sec_microdog40_req *req) { - char* data_tmp = util_str_buffer(req->payload, sizeof(req->payload)); + char *data_tmp = util_str_buffer(req->payload, sizeof(req->payload)); - log_debug( - "Processing request:\n" - "magic: 0x%X\n" - "req_type: 0x%X\n" - "mask_key1: 0x%X\n" - "dog_cascade: 0x%X\n" - "mfg_serial: 0x%X\n" - "mask_key2: 0x%X\n" - "dog_addr: 0x%X\n" - "payload_size: %d\n" - "mask_key3: 0x%X\n" - "payload: %s\n" - "dog_password: 0x%X\n" - "host_id: 0x%X\n" - "mask_key4: 0x%X\n" - "timestamp.year: %d\n" - "timestamp.month: %d\n" - "timestamp.day: %d\n" - "timestamp.hour: %d\n" - "timestamp.minute: %d\n" - "timestamp.second: %d", - req->magic, - req->req_type, - req->mask_key1, - req->dog_cascade, - req->mfg_serial, - req->mask_key2, - req->dog_addr, - req->payload_size, - req->mask_key3, - data_tmp, - req->dog_password, - req->host_id, - req->mask_key4, - req->timestamp.year, - req->timestamp.month, - req->timestamp.day, - req->timestamp.hour, - req->timestamp.minute, - req->timestamp.second); + log_debug( + "Processing request:\n" + "magic: 0x%X\n" + "req_type: 0x%X\n" + "mask_key1: 0x%X\n" + "dog_cascade: 0x%X\n" + "mfg_serial: 0x%X\n" + "mask_key2: 0x%X\n" + "dog_addr: 0x%X\n" + "payload_size: %d\n" + "mask_key3: 0x%X\n" + "payload: %s\n" + "dog_password: 0x%X\n" + "host_id: 0x%X\n" + "mask_key4: 0x%X\n" + "timestamp.year: %d\n" + "timestamp.month: %d\n" + "timestamp.day: %d\n" + "timestamp.hour: %d\n" + "timestamp.minute: %d\n" + "timestamp.second: %d", + req->magic, + req->req_type, + req->mask_key1, + req->dog_cascade, + req->mfg_serial, + req->mask_key2, + req->dog_addr, + req->payload_size, + req->mask_key3, + data_tmp, + req->dog_password, + req->host_id, + req->mask_key4, + req->timestamp.year, + req->timestamp.month, + req->timestamp.day, + req->timestamp.hour, + req->timestamp.minute, + req->timestamp.second); - free(data_tmp); + free(data_tmp); } -static void sec_microdog40_get_month_key(uint8_t* month_key, - const struct sec_microdog40_timestamp* timestamp) +static void sec_microdog40_get_month_key( + uint8_t *month_key, const struct sec_microdog40_timestamp *timestamp) { - struct sec_microdog40_month_key_hash_input hash_in; + struct sec_microdog40_month_key_hash_input hash_in; - memcpy(hash_in.ssk_prefix, sec_microdog40_shared_secret, - sizeof(hash_in.ssk_prefix)); - hash_in.year = timestamp->year; - hash_in.month = timestamp->month; - hash_in.const45 = 45; + memcpy( + hash_in.ssk_prefix, + sec_microdog40_shared_secret, + sizeof(hash_in.ssk_prefix)); + hash_in.year = timestamp->year; + hash_in.month = timestamp->month; + hash_in.const45 = 45; - crypt_md5_hash(month_key, (const uint8_t*) &hash_in, - sizeof(struct sec_microdog40_month_key_hash_input)); + crypt_md5_hash( + month_key, + (const uint8_t *) &hash_in, + sizeof(struct sec_microdog40_month_key_hash_input)); } -static void sec_microdog40_dec_req(const struct sec_microdog40_req* enc_req, - struct sec_microdog40_req* dec_req) +static void sec_microdog40_dec_req( + const struct sec_microdog40_req *enc_req, + struct sec_microdog40_req *dec_req) { - uint8_t key[16]; + uint8_t key[16]; - crypt_md5_hash(key, sec_microdog40_shared_secret, - sizeof(sec_microdog40_shared_secret)); - crypt_aes_dec(key, CRYPT_AES_KEY_LENGTH_16_BYTES, ((uint8_t *) dec_req) + - REQHEAD_SIZE, ((uint8_t*) enc_req) + REQHEAD_SIZE, REQTAIL_SIZE); + crypt_md5_hash( + key, sec_microdog40_shared_secret, sizeof(sec_microdog40_shared_secret)); + crypt_aes_dec( + key, + CRYPT_AES_KEY_LENGTH_16_BYTES, + ((uint8_t *) dec_req) + REQHEAD_SIZE, + ((uint8_t *) enc_req) + REQHEAD_SIZE, + REQTAIL_SIZE); - sec_microdog40_get_month_key(key, &dec_req->timestamp); - crypt_aes_dec(key, CRYPT_AES_KEY_LENGTH_16_BYTES, ((uint8_t *) dec_req), - ((uint8_t*) enc_req), REQHEAD_SIZE); + sec_microdog40_get_month_key(key, &dec_req->timestamp); + crypt_aes_dec( + key, + CRYPT_AES_KEY_LENGTH_16_BYTES, + ((uint8_t *) dec_req), + ((uint8_t *) enc_req), + REQHEAD_SIZE); - dec_req->magic ^= dec_req->mask_key4; - dec_req->req_type ^= dec_req->mask_key4; - dec_req->mask_key1 ^= dec_req->mask_key4; - dec_req->dog_cascade ^= dec_req->mask_key4; - dec_req->mfg_serial ^= dec_req->mask_key4; - dec_req->mask_key2 ^= dec_req->mask_key4; - dec_req->dog_addr ^= dec_req->mask_key4; - dec_req->payload_size ^= dec_req->mask_key4; - dec_req->mask_key3 ^= dec_req->mask_key4; - dec_req->dog_password ^= dec_req->mask_key4; - dec_req->host_id ^= dec_req->mask_key4; + dec_req->magic ^= dec_req->mask_key4; + dec_req->req_type ^= dec_req->mask_key4; + dec_req->mask_key1 ^= dec_req->mask_key4; + dec_req->dog_cascade ^= dec_req->mask_key4; + dec_req->mfg_serial ^= dec_req->mask_key4; + dec_req->mask_key2 ^= dec_req->mask_key4; + dec_req->dog_addr ^= dec_req->mask_key4; + dec_req->payload_size ^= dec_req->mask_key4; + dec_req->mask_key3 ^= dec_req->mask_key4; + dec_req->dog_password ^= dec_req->mask_key4; + dec_req->host_id ^= dec_req->mask_key4; - for (int i = 0 ; i < 64 ; i++) { - ((uint32_t *) dec_req->payload)[i] ^= dec_req->mask_key4; - } + for (int i = 0; i < 64; i++) { + ((uint32_t *) dec_req->payload)[i] ^= dec_req->mask_key4; + } - dec_req->magic ^= dec_req->mask_key3; - dec_req->req_type ^= dec_req->mask_key3; - dec_req->mask_key1 ^= dec_req->mask_key3; - dec_req->dog_cascade ^= dec_req->mask_key3; - dec_req->mfg_serial ^= dec_req->mask_key3; - dec_req->mask_key2 ^= dec_req->mask_key3; - dec_req->dog_addr ^= dec_req->mask_key3; - dec_req->payload_size ^= dec_req->mask_key3; + dec_req->magic ^= dec_req->mask_key3; + dec_req->req_type ^= dec_req->mask_key3; + dec_req->mask_key1 ^= dec_req->mask_key3; + dec_req->dog_cascade ^= dec_req->mask_key3; + dec_req->mfg_serial ^= dec_req->mask_key3; + dec_req->mask_key2 ^= dec_req->mask_key3; + dec_req->dog_addr ^= dec_req->mask_key3; + dec_req->payload_size ^= dec_req->mask_key3; - dec_req->magic ^= dec_req->mask_key2; - dec_req->req_type ^= dec_req->mask_key2; - dec_req->mask_key1 ^= dec_req->mask_key2; - dec_req->dog_cascade ^= dec_req->mask_key2; - dec_req->mfg_serial ^= dec_req->mask_key2; + dec_req->magic ^= dec_req->mask_key2; + dec_req->req_type ^= dec_req->mask_key2; + dec_req->mask_key1 ^= dec_req->mask_key2; + dec_req->dog_cascade ^= dec_req->mask_key2; + dec_req->mfg_serial ^= dec_req->mask_key2; - dec_req->magic ^= dec_req->mask_key1; - dec_req->req_type ^= dec_req->mask_key1; + dec_req->magic ^= dec_req->mask_key1; + dec_req->req_type ^= dec_req->mask_key1; } /* unused */ @@ -219,217 +228,219 @@ static void sec_microdog40_enc_req(const struct sec_microdog40_req* dec_req, */ static void sec_microdog40_encrypt_resp( - const struct sec_microdog40_resp* dec_resp, - struct sec_microdog40_resp* enc_resp, - const struct sec_microdog40_timestamp* timestamp) + const struct sec_microdog40_resp *dec_resp, + struct sec_microdog40_resp *enc_resp, + const struct sec_microdog40_timestamp *timestamp) { - uint8_t key[16]; + uint8_t key[16]; - sec_microdog40_get_month_key(key, timestamp); - crypt_aes_enc(key, CRYPT_AES_KEY_LENGTH_16_BYTES, (uint8_t*) enc_resp, - (uint8_t*) dec_resp, sizeof(struct sec_microdog40_resp)); + sec_microdog40_get_month_key(key, timestamp); + crypt_aes_enc( + key, + CRYPT_AES_KEY_LENGTH_16_BYTES, + (uint8_t *) enc_resp, + (uint8_t *) dec_resp, + sizeof(struct sec_microdog40_resp)); } -static uint32_t sec_microdog40_convert_req(const uint8_t* req_data, - uint16_t req_len) +static uint32_t +sec_microdog40_convert_req(const uint8_t *req_data, uint16_t req_len) { - uint32_t cur_algo; + uint32_t cur_algo; - cur_algo = 0; - memcpy(&cur_algo, sec_microdog40_header.flash_memory + 196, 4); + cur_algo = 0; + memcpy(&cur_algo, sec_microdog40_header.flash_memory + 196, 4); - for (uint32_t i = 0; i < sec_microdog40_header.num_keys; i++) { - struct sec_microdog40_key* key = &sec_microdog40_key_table[i]; + for (uint32_t i = 0; i < sec_microdog40_header.num_keys; i++) { + struct sec_microdog40_key *key = &sec_microdog40_key_table[i]; - if (key->algorithm == cur_algo) { + if (key->algorithm == cur_algo) { - if (key->req_len == req_len) { + if (key->req_len == req_len) { - if (!memcmp(key->request, req_data, req_len)) { - char* tmp = util_str_buffer(req_data, req_len); - log_debug("Converting: %s ==> %X", tmp, key->response); - free(tmp); - return key->response; - } - } - } - } + if (!memcmp(key->request, req_data, req_len)) { + char *tmp = util_str_buffer(req_data, req_len); + log_debug("Converting: %s ==> %X", tmp, key->response); + free(tmp); + return key->response; + } + } + } + } - char* tmp = util_str_buffer(req_data, req_len); - log_warn("Converting request %s failed, no matching response found", tmp); - free(tmp); - return 0; + char *tmp = util_str_buffer(req_data, req_len); + log_warn("Converting request %s failed, no matching response found", tmp); + free(tmp); + return 0; } -static void sec_microdog40_dispatch(const struct sec_microdog40_req* req, - struct sec_microdog40_resp* resp) +static void sec_microdog40_dispatch( + const struct sec_microdog40_req *req, struct sec_microdog40_resp *resp) { - // prepare response - resp->magic = sec_microdog40_magic; - resp->req_type = req->req_type; + // prepare response + resp->magic = sec_microdog40_magic; + resp->req_type = req->req_type; - if (req->magic != sec_microdog40_magic) { - log_warn("Bad magic for request: %X", req->magic); + if (req->magic != sec_microdog40_magic) { + log_warn("Bad magic for request: %X", req->magic); + } + + sec_microdog40_log_req(req); + + switch (req->req_type) { + case SEC_MICRODOG40_REQ_OPCODE_DOG_CHECK: { + log_debug("SEC_MICRODOG40_REQ_OPCODE_DOG_CHECK"); + /* no-op */ + break; } - sec_microdog40_log_req(req); + case SEC_MICRODOG40_REQ_OPCODE_SET_SHARE: { + log_debug("SEC_MICRODOG40_REQ_OPCODE_SET_SHARE"); - switch (req->req_type) - { - case SEC_MICRODOG40_REQ_OPCODE_DOG_CHECK: - { - log_debug("SEC_MICRODOG40_REQ_OPCODE_DOG_CHECK"); - /* no-op */ - break; - } - - case SEC_MICRODOG40_REQ_OPCODE_SET_SHARE: - { - log_debug("SEC_MICRODOG40_REQ_OPCODE_SET_SHARE"); - - sec_microdog40_share = req->payload[0]; - break; - } - - case SEC_MICRODOG40_REQ_OPCODE_GET_LOCK_NO: - { - log_debug("SEC_MICRODOG40_REQ_OPCODE_GET_LOCK_NO 0x%08X", - sec_microdog40_header.mfg_serial); - - memcpy(resp->payload, &sec_microdog40_header.mfg_serial, 4); - break; - } - - case SEC_MICRODOG40_REQ_OPCODE_GET_ID: - { - log_debug("SEC_MICRODOG40_REQ_OPCODE_GET_ID 0x%02X 0x%02X 0x%02X " - "0x%02X 0x%02X 0x%02X 0x%02X 0x%02X", - sec_microdog40_header.vendor_id[0], - sec_microdog40_header.vendor_id[1], - sec_microdog40_header.vendor_id[2], - sec_microdog40_header.vendor_id[3], - sec_microdog40_header.vendor_id[4], - sec_microdog40_header.vendor_id[5], - sec_microdog40_header.vendor_id[6], - sec_microdog40_header.vendor_id[7]); - - memcpy(resp->payload, sec_microdog40_header.vendor_id, - sizeof(sec_microdog40_header.vendor_id)); - - break; - } - - case SEC_MICRODOG40_REQ_OPCODE_CONVERT: - { - uint32_t resp_data; - - log_debug("SEC_MICRODOG40_REQ_OPCODE_CONVERT"); - - resp_data = sec_microdog40_convert_req(req->payload, - req->payload_size); - memcpy(resp->payload, &resp_data, sizeof(uint32_t)); - - break; - } - - case SEC_MICRODOG40_REQ_OPCODE_AUTH_STEP_1: - { - log_debug("SEC_MICRODOG40_REQ_OPCODE_AUTH_STEP_1"); - /* no-op */ - break; - } - - case SEC_MICRODOG40_REQ_OPCODE_AUTH_STEP_2: - { - log_debug("SEC_MICRODOG40_REQ_OPCODE_AUTH_STEP_2"); - /* no-op */ - break; - } - - case SEC_MICRODOG40_REQ_OPCODE_AUTH_STEP_3: - { - uint8_t month_key[16]; - - log_debug("SEC_MICRODOG40_REQ_OPCODE_AUTH_STEP_3"); - - sec_microdog40_get_month_key(month_key, &req->timestamp); - - crypt_aes_enc(month_key, CRYPT_AES_KEY_LENGTH_16_BYTES, - resp->payload, req->payload, 16); - - break; - } - - default: - { - log_warn("Unsupported Opcode: %04X", req->req_type); - resp->magic = 0; // mark to indicate error - break; - } + sec_microdog40_share = req->payload[0]; + break; } + + case SEC_MICRODOG40_REQ_OPCODE_GET_LOCK_NO: { + log_debug( + "SEC_MICRODOG40_REQ_OPCODE_GET_LOCK_NO 0x%08X", + sec_microdog40_header.mfg_serial); + + memcpy(resp->payload, &sec_microdog40_header.mfg_serial, 4); + break; + } + + case SEC_MICRODOG40_REQ_OPCODE_GET_ID: { + log_debug( + "SEC_MICRODOG40_REQ_OPCODE_GET_ID 0x%02X 0x%02X 0x%02X " + "0x%02X 0x%02X 0x%02X 0x%02X 0x%02X", + sec_microdog40_header.vendor_id[0], + sec_microdog40_header.vendor_id[1], + sec_microdog40_header.vendor_id[2], + sec_microdog40_header.vendor_id[3], + sec_microdog40_header.vendor_id[4], + sec_microdog40_header.vendor_id[5], + sec_microdog40_header.vendor_id[6], + sec_microdog40_header.vendor_id[7]); + + memcpy( + resp->payload, + sec_microdog40_header.vendor_id, + sizeof(sec_microdog40_header.vendor_id)); + + break; + } + + case SEC_MICRODOG40_REQ_OPCODE_CONVERT: { + uint32_t resp_data; + + log_debug("SEC_MICRODOG40_REQ_OPCODE_CONVERT"); + + resp_data = sec_microdog40_convert_req(req->payload, req->payload_size); + memcpy(resp->payload, &resp_data, sizeof(uint32_t)); + + break; + } + + case SEC_MICRODOG40_REQ_OPCODE_AUTH_STEP_1: { + log_debug("SEC_MICRODOG40_REQ_OPCODE_AUTH_STEP_1"); + /* no-op */ + break; + } + + case SEC_MICRODOG40_REQ_OPCODE_AUTH_STEP_2: { + log_debug("SEC_MICRODOG40_REQ_OPCODE_AUTH_STEP_2"); + /* no-op */ + break; + } + + case SEC_MICRODOG40_REQ_OPCODE_AUTH_STEP_3: { + uint8_t month_key[16]; + + log_debug("SEC_MICRODOG40_REQ_OPCODE_AUTH_STEP_3"); + + sec_microdog40_get_month_key(month_key, &req->timestamp); + + crypt_aes_enc( + month_key, + CRYPT_AES_KEY_LENGTH_16_BYTES, + resp->payload, + req->payload, + 16); + + break; + } + + default: { + log_warn("Unsupported Opcode: %04X", req->req_type); + resp->magic = 0; // mark to indicate error + break; + } + } } -void sec_microdog40_init(const uint8_t* key_data, size_t len) +void sec_microdog40_init(const uint8_t *key_data, size_t len) { - if (len < sizeof(struct sec_microdog40_header)) { - log_error("Loading key table failed, incomplete header"); - return; - } + if (len < sizeof(struct sec_microdog40_header)) { + log_error("Loading key table failed, incomplete header"); + return; + } - memcpy(&sec_microdog40_header, key_data, - sizeof(struct sec_microdog40_header)); + memcpy( + &sec_microdog40_header, key_data, sizeof(struct sec_microdog40_header)); - if (len - sizeof(struct sec_microdog40_header) < - sec_microdog40_header.num_keys * - sizeof(struct sec_microdog40_key)) { - log_error("Loading key table failed, incomplete key table"); - return; - } + if (len - sizeof(struct sec_microdog40_header) < + sec_microdog40_header.num_keys * sizeof(struct sec_microdog40_key)) { + log_error("Loading key table failed, incomplete key table"); + return; + } - sec_microdog40_key_table = util_xmalloc(sec_microdog40_header.num_keys * - sizeof(struct sec_microdog40_key)); + sec_microdog40_key_table = util_xmalloc( + sec_microdog40_header.num_keys * sizeof(struct sec_microdog40_key)); - memcpy(sec_microdog40_key_table, - key_data + sizeof(struct sec_microdog40_header), - sec_microdog40_header.num_keys * sizeof(struct sec_microdog40_key)); + memcpy( + sec_microdog40_key_table, + key_data + sizeof(struct sec_microdog40_header), + sec_microdog40_header.num_keys * sizeof(struct sec_microdog40_key)); - log_info("Loaded %d keys, serial 0x%X, password 0x%X", - sec_microdog40_header.num_keys, sec_microdog40_header.serial, - sec_microdog40_header.password); + log_info( + "Loaded %d keys, serial 0x%X, password 0x%X", + sec_microdog40_header.num_keys, + sec_microdog40_header.serial, + sec_microdog40_header.password); - sec_microdog40_share = 0; + sec_microdog40_share = 0; } bool sec_microdog40_do_transaction( - struct sec_microdog40_transaction* transaction) + struct sec_microdog40_transaction *transaction) { - struct sec_microdog40_req dec_req; - struct sec_microdog40_resp dec_resp; + struct sec_microdog40_req dec_req; + struct sec_microdog40_resp dec_resp; - if (transaction->header != PROTOCOL_VERSION) { - log_error("Wrong protocol version of transaction %X.", - transaction->header); - return false; - } + if (transaction->header != PROTOCOL_VERSION) { + log_error("Wrong protocol version of transaction %X.", transaction->header); + return false; + } - log_debug("Decrypting request..."); - sec_microdog40_dec_req(&transaction->request, &dec_req); + log_debug("Decrypting request..."); + sec_microdog40_dec_req(&transaction->request, &dec_req); - sec_microdog40_dispatch(&dec_req, &dec_resp); + sec_microdog40_dispatch(&dec_req, &dec_resp); - /* no error */ - if (dec_resp.magic != 0) { - transaction->header = 0; + /* no error */ + if (dec_resp.magic != 0) { + transaction->header = 0; - log_debug("Encrypting response..."); - sec_microdog40_encrypt_resp(&dec_resp, &transaction->response, - &dec_req.timestamp); - } else { - transaction->header = 20023; - log_error("Transaction failed."); - } + log_debug("Encrypting response..."); + sec_microdog40_encrypt_resp( + &dec_resp, &transaction->response, &dec_req.timestamp); + } else { + transaction->header = 20023; + log_error("Transaction failed."); + } - log_debug("Transaction successful"); + log_debug("Transaction successful"); - return true; + return true; } diff --git a/src/main/sec/microdog40/microdog40.h b/src/main/sec/microdog40/microdog40.h index c356ad1..41f63a4 100644 --- a/src/main/sec/microdog40/microdog40.h +++ b/src/main/sec/microdog40/microdog40.h @@ -14,79 +14,79 @@ * by an arbitrary number of keys */ struct sec_microdog40_header { - uint32_t serial; - uint32_t password; - uint8_t vendor_id[8]; - uint32_t mfg_serial; - uint8_t flash_memory[200]; - uint32_t num_keys; + uint32_t serial; + uint32_t password; + uint8_t vendor_id[8]; + uint32_t mfg_serial; + uint8_t flash_memory[200]; + uint32_t num_keys; }; /** * A single entry in the key table (comes after the header) */ struct sec_microdog40_key { - uint32_t response; - uint32_t algorithm; - uint32_t req_len; - uint8_t request[64]; + uint32_t response; + uint32_t algorithm; + uint32_t req_len; + uint8_t request[64]; }; /** * Timestamp for a dongle request */ struct sec_microdog40_timestamp { - uint16_t year; - uint16_t month; - uint16_t day; - uint16_t hour; - uint16_t minute; - uint16_t second; - uint8_t padding[3]; + uint16_t year; + uint16_t month; + uint16_t day; + uint16_t hour; + uint16_t minute; + uint16_t second; + uint8_t padding[3]; } __attribute((__packed__)); /** * Request to the dongle as part of a transaction */ struct sec_microdog40_req { - uint16_t magic; - uint8_t req_type; - uint32_t mask_key1; - uint8_t dog_cascade; - uint32_t mfg_serial; - uint32_t mask_key2; - uint16_t dog_addr; - uint16_t payload_size; - uint32_t mask_key3; - uint8_t payload[256]; - uint32_t dog_password; - uint8_t host_id; - uint32_t mask_key4; - struct sec_microdog40_timestamp timestamp; + uint16_t magic; + uint8_t req_type; + uint32_t mask_key1; + uint8_t dog_cascade; + uint32_t mfg_serial; + uint32_t mask_key2; + uint16_t dog_addr; + uint16_t payload_size; + uint32_t mask_key3; + uint8_t payload[256]; + uint32_t dog_password; + uint8_t host_id; + uint32_t mask_key4; + struct sec_microdog40_timestamp timestamp; } __attribute((__packed__)); /** * Dongle response as part of a transaction */ struct sec_microdog40_resp { - uint16_t magic; - uint32_t mask_key1; - uint8_t req_type; - uint32_t mask_key2; - uint32_t krnl_retval; - uint32_t mask_key3; - uint8_t payload[256]; - uint32_t mask_key4; - uint8_t padding[9]; + uint16_t magic; + uint32_t mask_key1; + uint8_t req_type; + uint32_t mask_key2; + uint32_t krnl_retval; + uint32_t mask_key3; + uint8_t payload[256]; + uint32_t mask_key4; + uint8_t padding[9]; } __attribute((__packed__)); /** * Dongle emulator transaction data */ struct sec_microdog40_transaction { - uint32_t header; - struct sec_microdog40_req request; - struct sec_microdog40_resp response; + uint32_t header; + struct sec_microdog40_req request; + struct sec_microdog40_resp response; } __attribute((__packed__)); /** @@ -96,7 +96,7 @@ struct sec_microdog40_transaction { * @param key_data Pointer to loaded key data (dog attributes, key table) * @param len Length of the buffer */ -void sec_microdog40_init(const uint8_t* key_data, size_t len); +void sec_microdog40_init(const uint8_t *key_data, size_t len); /** * Execute a transaction on the dongle @@ -106,6 +106,7 @@ void sec_microdog40_init(const uint8_t* key_data, size_t len); * @return True if the request was successfully processed and a response was * written, false on failure */ -bool sec_microdog40_do_transaction(struct sec_microdog40_transaction* transaction); +bool sec_microdog40_do_transaction( + struct sec_microdog40_transaction *transaction); #endif \ No newline at end of file diff --git a/src/main/sec/microdog40/microdog40d.c b/src/main/sec/microdog40/microdog40d.c index fe897c7..ab2ea0a 100644 --- a/src/main/sec/microdog40/microdog40d.c +++ b/src/main/sec/microdog40/microdog40d.c @@ -11,109 +11,118 @@ #include "util/log.h" -static const char* sec_microdog40d_sock_path = "/var/run/microdog/u.daemon"; +static const char *sec_microdog40d_sock_path = "/var/run/microdog/u.daemon"; static bool sec_microdog40d_run_d; static bool sec_microdog40d_is_running_d; struct timeval tv; -void sec_microdog40d_init(const uint8_t* key_data, size_t len) +void sec_microdog40d_init(const uint8_t *key_data, size_t len) { - sec_microdog40_init(key_data, len); - sec_microdog40d_run_d = true; - sec_microdog40d_is_running_d = false; + sec_microdog40_init(key_data, len); + sec_microdog40d_run_d = true; + sec_microdog40d_is_running_d = false; } void sec_microdog40d_run(void) { - int fd; - struct sec_microdog40_transaction transaction; - struct sockaddr_un peer_addr; - socklen_t peer_addr_len; - int retval; + int fd; + struct sec_microdog40_transaction transaction; + struct sockaddr_un peer_addr; + socklen_t peer_addr_len; + int retval; - sec_microdog40d_is_running_d = true; + sec_microdog40d_is_running_d = true; - fd = -1; + fd = -1; + peer_addr_len = sizeof(peer_addr); + retval = 0; + + unlink(sec_microdog40d_sock_path); + + /* make sure /var/run/microdog folder exists */ + mkdir("/var/run/microdog", 0700); + + fd = socket(AF_UNIX, SOCK_DGRAM, 0); + if (fd == -1) { + log_error("Opening socket failed: %s", strerror(errno)); + sec_microdog40d_is_running_d = false; + return; + } + + tv.tv_sec = 5; + tv.tv_usec = 0; + if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { + sec_microdog40d_is_running_d = false; + return; + } + + memset(&peer_addr, 0, sizeof(struct sockaddr_un)); + peer_addr.sun_family = AF_UNIX; + strcpy(peer_addr.sun_path, sec_microdog40d_sock_path); + + retval = bind(fd, (struct sockaddr *) &peer_addr, sizeof(struct sockaddr_un)); + + if (retval == -1) { + log_error("Binding socket failed: %s", strerror(errno)); + sec_microdog40d_is_running_d = false; + return; + } + + while (sec_microdog40d_run_d) { peer_addr_len = sizeof(peer_addr); - retval = 0; - - unlink(sec_microdog40d_sock_path); - - /* make sure /var/run/microdog folder exists */ - mkdir("/var/run/microdog", 0700); - - fd = socket(AF_UNIX, SOCK_DGRAM, 0); - if (fd == -1) { - log_error("Opening socket failed: %s", strerror(errno)); - sec_microdog40d_is_running_d = false; - return; - } - - tv.tv_sec=5; - tv.tv_usec = 0; - if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) < 0) { - sec_microdog40d_is_running_d = false; - return; - } - - memset(&peer_addr, 0, sizeof(struct sockaddr_un)); - peer_addr.sun_family = AF_UNIX; - strcpy(peer_addr.sun_path, sec_microdog40d_sock_path); - - retval = bind(fd, (struct sockaddr *) &peer_addr, - sizeof(struct sockaddr_un)); + retval = recvfrom( + fd, + &transaction, + sizeof(struct sec_microdog40_transaction), + 0, + (struct sockaddr *) &peer_addr, + &peer_addr_len); if (retval == -1) { - log_error("Binding socket failed: %s", strerror(errno)); + + if (errno == EBADF) { + break; + } else if (errno == EAGAIN) { + continue; + } else { + log_error("Receiving data failed: %s", strerror(errno)); sec_microdog40d_is_running_d = false; return; + } + } else if (retval != sizeof(struct sec_microdog40_transaction)) { + log_warn( + "Package too short, expected %d bytes, got %d bytes", + sizeof(struct sec_microdog40_transaction), + retval); + } else { + if (sec_microdog40_do_transaction(&transaction)) { + sendto( + fd, + &transaction, + sizeof(struct sec_microdog40_transaction), + 0, + (struct sockaddr *) &peer_addr, + peer_addr_len); + } else { + log_error("Transaction failed."); + } } + } - while (sec_microdog40d_run_d) { - peer_addr_len = sizeof(peer_addr); - retval = recvfrom(fd, &transaction, - sizeof(struct sec_microdog40_transaction), 0, - (struct sockaddr *) &peer_addr, &peer_addr_len); + // cleanup + close(fd); + unlink(sec_microdog40d_sock_path); - if (retval == -1) { - - if (errno == EBADF) { - break; - } else if (errno == EAGAIN) { - continue; - } else { - log_error("Receiving data failed: %s", strerror(errno)); - sec_microdog40d_is_running_d = false; - return; - } - } else if (retval != sizeof(struct sec_microdog40_transaction)) { - log_warn("Package too short, expected %d bytes, got %d bytes", - sizeof(struct sec_microdog40_transaction), retval); - } else { - if (sec_microdog40_do_transaction(&transaction)) { - sendto(fd, &transaction, - sizeof(struct sec_microdog40_transaction), 0, - (struct sockaddr *) &peer_addr, peer_addr_len); - } else { - log_error("Transaction failed."); - } - } - } - - // cleanup - close(fd); - unlink(sec_microdog40d_sock_path); - - sec_microdog40d_is_running_d = false; + sec_microdog40d_is_running_d = false; } bool sec_microdog40d_is_running(void) { - return sec_microdog40d_is_running_d; + return sec_microdog40d_is_running_d; } void sec_microdog40d_shutdown(void) { - sec_microdog40d_run_d = false; + sec_microdog40d_run_d = false; } diff --git a/src/main/sec/microdog40/microdog40d.h b/src/main/sec/microdog40/microdog40d.h index e429cbd..9216001 100644 --- a/src/main/sec/microdog40/microdog40d.h +++ b/src/main/sec/microdog40/microdog40d.h @@ -14,7 +14,7 @@ * @param key_data Pointer to loaded key data (dog attributes, key table) * @param len Length of the buffer */ -void sec_microdog40d_init(const uint8_t* key_data, size_t len); +void sec_microdog40d_init(const uint8_t *key_data, size_t len); /** * Run the daemon. This call blocks until the daemon is shut down. diff --git a/src/main/util/adler32.c b/src/main/util/adler32.c index 8d05078..dc2ec53 100644 --- a/src/main/util/adler32.c +++ b/src/main/util/adler32.c @@ -2,16 +2,17 @@ #define BASE 65521 -uint32_t util_adler32_calc(uint32_t initval, const uint8_t* input, size_t length) +uint32_t +util_adler32_calc(uint32_t initval, const uint8_t *input, size_t length) { - unsigned int s1 = initval & 0xffff; - unsigned int s2 = (initval >> 16) & 0xffff; - unsigned int n; + unsigned int s1 = initval & 0xffff; + unsigned int s2 = (initval >> 16) & 0xffff; + unsigned int n; - for (n = 0; n < length; n++) { - s1 = (s1 + input[n]) % BASE; - s2 = (s2 + s1) % BASE; - } + for (n = 0; n < length; n++) { + s1 = (s1 + input[n]) % BASE; + s2 = (s2 + s1) % BASE; + } - return (s2 << 16) + s1; + return (s2 << 16) + s1; } \ No newline at end of file diff --git a/src/main/util/adler32.h b/src/main/util/adler32.h index 1f74a50..0265924 100644 --- a/src/main/util/adler32.h +++ b/src/main/util/adler32.h @@ -12,6 +12,7 @@ * @param length Length of the input buffer * @return Adler32 value of input buffer */ -uint32_t util_adler32_calc(uint32_t initval, const uint8_t* input, size_t length); +uint32_t +util_adler32_calc(uint32_t initval, const uint8_t *input, size_t length); #endif \ No newline at end of file diff --git a/src/main/util/array.c b/src/main/util/array.c index e9f61f3..26d4610 100644 --- a/src/main/util/array.c +++ b/src/main/util/array.c @@ -6,50 +6,52 @@ #include "util/log.h" #include "util/mem.h" -void util_array_init(struct util_array* array) +void util_array_init(struct util_array *array) { - memset(array, 0, sizeof(*array)); + memset(array, 0, sizeof(*array)); } -void util_array_remove_(size_t itemsz, struct util_array* array, size_t i) +void util_array_remove_(size_t itemsz, struct util_array *array, size_t i) { - array->nitems--; + array->nitems--; - memmove(((uint8_t *) array->items) + i * itemsz, - ((uint8_t *) array->items) + (i + 1) * itemsz, - (array->nitems - i) * itemsz); + memmove( + ((uint8_t *) array->items) + i * itemsz, + ((uint8_t *) array->items) + (i + 1) * itemsz, + (array->nitems - i) * itemsz); } -void* util_array_reserve_(size_t itemsz, struct util_array* array, size_t nitems) +void * +util_array_reserve_(size_t itemsz, struct util_array *array, size_t nitems) { - size_t new_nalloced; - size_t new_nitems; - void* result; + size_t new_nalloced; + size_t new_nitems; + void *result; - new_nitems = array->nitems + nitems; + new_nitems = array->nitems + nitems; - if (new_nitems > array->nalloced) { - new_nalloced = array->nalloced; + if (new_nitems > array->nalloced) { + new_nalloced = array->nalloced; - if (new_nalloced == 0) { - new_nalloced = 1; - } - - while (new_nalloced < new_nitems) { - new_nalloced *= 2; - } - - array->items = util_xrealloc(array->items, new_nalloced * itemsz); - array->nalloced = new_nalloced; + if (new_nalloced == 0) { + new_nalloced = 1; } - result = ((uint8_t *) array->items) + array->nitems * itemsz; - array->nitems = new_nitems; + while (new_nalloced < new_nitems) { + new_nalloced *= 2; + } - return result; + array->items = util_xrealloc(array->items, new_nalloced * itemsz); + array->nalloced = new_nalloced; + } + + result = ((uint8_t *) array->items) + array->nitems * itemsz; + array->nitems = new_nitems; + + return result; } -void util_array_fini(struct util_array* array) +void util_array_fini(struct util_array *array) { - free(array->items); + free(array->items); } diff --git a/src/main/util/array.h b/src/main/util/array.h index 8a541ce..6ebe48b 100644 --- a/src/main/util/array.h +++ b/src/main/util/array.h @@ -7,29 +7,27 @@ * Array with a fixed number of items */ struct util_array { - void* items; - size_t nitems; - size_t nalloced; + void *items; + size_t nitems; + size_t nalloced; }; -#define util_array_item(type, array, i) \ - (&(((type*) (array)->items)[i])) +#define util_array_item(type, array, i) (&(((type *) (array)->items)[i])) #define util_array_reserve(type, array, nitems) \ - ((type*) util_array_reserve_(sizeof(type), array, nitems)) + ((type *) util_array_reserve_(sizeof(type), array, nitems)) #define util_array_remove(type, array, i) \ - util_array_remove_(sizeof(type), array, i) + util_array_remove_(sizeof(type), array, i) -#define util_array_append(type, array) \ - util_array_reserve(type, array, 1) +#define util_array_append(type, array) util_array_reserve(type, array, 1) /** * Initialize the array after allocation * * @param array Pointer to allocated array to initialize */ -void util_array_init(struct util_array* array); +void util_array_init(struct util_array *array); /** * Reserve/allocate space for the specified number of items in the array @@ -39,7 +37,8 @@ void util_array_init(struct util_array* array); * @param Number of items with itemsz each to reserve * @return Pointer to first index of reserved slots in array */ -void* util_array_reserve_(size_t itemsz, struct util_array* array, size_t nitems); +void * +util_array_reserve_(size_t itemsz, struct util_array *array, size_t nitems); /** * Remove an item from the array. The array will be shrunken to current_size - 1 @@ -48,13 +47,13 @@ void* util_array_reserve_(size_t itemsz, struct util_array* array, size_t nitems * @param array Array to remove the item from * @param i Index of the item to remove */ -void util_array_remove_(size_t itemsz, struct util_array* array, size_t i); +void util_array_remove_(size_t itemsz, struct util_array *array, size_t i); /** * Free/Deallocate an allocated array * * @param array Allocated array to free */ -void util_array_fini(struct util_array* array); +void util_array_fini(struct util_array *array); #endif diff --git a/src/main/util/base64.c b/src/main/util/base64.c index 0ab955a..10bc72b 100644 --- a/src/main/util/base64.c +++ b/src/main/util/base64.c @@ -6,17 +6,13 @@ // Copy-pasted with minor tweaks from: https://github.com/littlstar/b64.c static const char b64_table[] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '+', '/' -}; + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; -uint8_t* util_base64_encode(const uint8_t* src, size_t len, size_t* out_len) +uint8_t *util_base64_encode(const uint8_t *src, size_t len, size_t *out_len) { int i = 0; int j = 0; @@ -75,7 +71,7 @@ uint8_t* util_base64_encode(const uint8_t* src, size_t len, size_t* out_len) return enc; } -uint8_t* util_base64_decode(const uint8_t* src, size_t len, size_t* out_len) +uint8_t *util_base64_decode(const uint8_t *src, size_t len, size_t *out_len) { int i = 0; int j = 0; @@ -89,10 +85,10 @@ uint8_t* util_base64_decode(const uint8_t* src, size_t len, size_t* out_len) while (len--) { if ('=' == src[j]) { - break; + break; } if (!(isalnum(src[j]) || '+' == src[j] || '/' == src[j])) { - break; + break; } tmp[i++] = src[j++]; @@ -113,7 +109,7 @@ uint8_t* util_base64_decode(const uint8_t* src, size_t len, size_t* out_len) dec = (unsigned char *) util_xrealloc(dec, size + 3); - if (dec != NULL){ + if (dec != NULL) { for (i = 0; i < 3; ++i) { dec[size++] = buf[i]; } @@ -131,21 +127,21 @@ uint8_t* util_base64_decode(const uint8_t* src, size_t len, size_t* out_len) } for (j = 0; j < 4; ++j) { - for (l = 0; l < 64; ++l) { - if (tmp[j] == b64_table[l]) { - tmp[j] = l; - break; - } + for (l = 0; l < 64; ++l) { + if (tmp[j] == b64_table[l]) { + tmp[j] = l; + break; } + } } buf[0] = (tmp[0] << 2) + ((tmp[1] & 0x30) >> 4); buf[1] = ((tmp[1] & 0xf) << 4) + ((tmp[2] & 0x3c) >> 2); buf[2] = ((tmp[2] & 0x3) << 6) + tmp[3]; - dec = (unsigned char *)util_xrealloc(dec, size + (i - 1)); + dec = (unsigned char *) util_xrealloc(dec, size + (i - 1)); - if (dec != NULL){ + if (dec != NULL) { for (j = 0; (j < i - 1); ++j) { dec[size++] = buf[j]; } @@ -154,9 +150,9 @@ uint8_t* util_base64_decode(const uint8_t* src, size_t len, size_t* out_len) } } - dec = (unsigned char *)util_xrealloc(dec, size + 1); + dec = (unsigned char *) util_xrealloc(dec, size + 1); - if (dec != NULL){ + if (dec != NULL) { dec[size] = '\0'; } else { return NULL; diff --git a/src/main/util/base64.h b/src/main/util/base64.h index e3fdcf2..4d0853e 100644 --- a/src/main/util/base64.h +++ b/src/main/util/base64.h @@ -1,8 +1,8 @@ #pragma once -#include #include +#include -uint8_t* util_base64_encode(const uint8_t* src, size_t len, size_t* out_len); +uint8_t *util_base64_encode(const uint8_t *src, size_t len, size_t *out_len); -uint8_t* util_base64_decode(const uint8_t* src, size_t len, size_t* out_len); \ No newline at end of file +uint8_t *util_base64_decode(const uint8_t *src, size_t len, size_t *out_len); \ No newline at end of file diff --git a/src/main/util/defs.h b/src/main/util/defs.h index c90240d..0c41db2 100644 --- a/src/main/util/defs.h +++ b/src/main/util/defs.h @@ -4,7 +4,8 @@ #include #include -#define FILENAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) +#define FILENAME \ + (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) #define STRINGIFY_(x) #x #define STRINGIFY(x) STRINGIFY_(x) @@ -13,6 +14,6 @@ #define lengthof(x) (sizeof(x) / sizeof(x[0])) #define containerof(ptr, outer_t, member) \ - ((void *) (((uint8_t *) ptr) - offsetof(outer_t, member))) + ((void *) (((uint8_t *) ptr) - offsetof(outer_t, member))) #endif diff --git a/src/main/util/fs.c b/src/main/util/fs.c index 2b5d773..3556b9d 100644 --- a/src/main/util/fs.c +++ b/src/main/util/fs.c @@ -13,210 +13,213 @@ #include "util/log.h" #include "util/mem.h" -bool util_file_load(const char* filename, void** out_bytes, size_t *out_nbytes, - bool text_mode) +bool util_file_load( + const char *filename, void **out_bytes, size_t *out_nbytes, bool text_mode) { - FILE *f; - void *bytes; - size_t nbytes; - int result; + FILE *f; + void *bytes; + size_t nbytes; + int result; - log_assert(out_bytes != NULL); - *out_bytes = NULL; + log_assert(out_bytes != NULL); + *out_bytes = NULL; - f = fopen(filename, "rb"); + f = fopen(filename, "rb"); - if (f == NULL) { - log_warn("%s: Error opening file: %s", filename, strerror(errno)); + if (f == NULL) { + log_warn("%s: Error opening file: %s", filename, strerror(errno)); - goto open_fail; - } + goto open_fail; + } - fseek(f, 0, SEEK_END); - nbytes = ftell(f); - fseek(f, 0, SEEK_SET); + fseek(f, 0, SEEK_END); + nbytes = ftell(f); + fseek(f, 0, SEEK_SET); - /* Add for null terminator */ - if (text_mode) { - nbytes++; - } + /* Add for null terminator */ + if (text_mode) { + nbytes++; + } - bytes = malloc(nbytes); + bytes = malloc(nbytes); - if (bytes == NULL) { - log_warn("%s: malloc(%u) failed", filename, (unsigned int) nbytes); + if (bytes == NULL) { + log_warn("%s: malloc(%u) failed", filename, (unsigned int) nbytes); - goto malloc_fail; - } + goto malloc_fail; + } - if (text_mode) { - result = fread(bytes, nbytes - 1, 1, f); - } else { - result = fread(bytes, nbytes, 1, f); - } + if (text_mode) { + result = fread(bytes, nbytes - 1, 1, f); + } else { + result = fread(bytes, nbytes, 1, f); + } - if (result != 1) { - log_warn("%s: Error reading file: %s", filename, strerror(errno)); + if (result != 1) { + log_warn("%s: Error reading file: %s", filename, strerror(errno)); - goto read_fail; - } + goto read_fail; + } - *out_bytes = bytes; + *out_bytes = bytes; - if (out_nbytes != NULL) { - *out_nbytes = nbytes; - } + if (out_nbytes != NULL) { + *out_nbytes = nbytes; + } - fclose(f); + fclose(f); - /* Add null terminator */ - if (text_mode) { - ((char*) bytes)[nbytes - 1] = '\0'; - } + /* Add null terminator */ + if (text_mode) { + ((char *) bytes)[nbytes - 1] = '\0'; + } - log_debug("File loaded %s, size %d", filename, *out_nbytes); + log_debug("File loaded %s, size %d", filename, *out_nbytes); - return true; + return true; read_fail: - free(bytes); + free(bytes); malloc_fail: - fclose(f); + fclose(f); open_fail: - return false; + return false; } -bool util_file_save(const char* filename, const void* bytes, size_t nbytes) +bool util_file_save(const char *filename, const void *bytes, size_t nbytes) { - FILE *f; - int result; + FILE *f; + int result; - f = fopen(filename, "wb"); + f = fopen(filename, "wb"); - if (f == NULL) { - log_warn("%s: Error creating file: %s", filename, strerror(errno)); + if (f == NULL) { + log_warn("%s: Error creating file: %s", filename, strerror(errno)); - goto open_fail; - } + goto open_fail; + } - result = fwrite(bytes, nbytes, 1, f); + result = fwrite(bytes, nbytes, 1, f); - if (result != 1) { - log_warn("%s: Error writing file: %s", filename, strerror(errno)); + if (result != 1) { + log_warn("%s: Error writing file: %s", filename, strerror(errno)); - goto write_fail; - } + goto write_fail; + } - fclose(f); + fclose(f); - log_debug("File saved %s, size %d", filename, nbytes); + log_debug("File saved %s, size %d", filename, nbytes); - return true; + return true; write_fail: - fclose(f); + fclose(f); open_fail: - return false; + return false; } -bool util_fs_path_exists(const char* path) +bool util_fs_path_exists(const char *path) { - // Don't use stat here because that doesn't work on mounts, e.g. sqashfs/appimage + // Don't use stat here because that doesn't work on mounts, e.g. + // sqashfs/appimage - bool exists; - FILE* file = fopen(path, "r"); + bool exists; + FILE *file = fopen(path, "r"); - exists = file != NULL; + exists = file != NULL; - if (file != NULL) { - fclose(file); + if (file != NULL) { + fclose(file); + } + + return exists; +} + +bool util_fs_mkdir(const char *path) +{ + return mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0; +} + +bool util_fs_mkfile(const char *path) +{ + FILE *file; + bool res; + + file = fopen(path, "a"); + + res = file != NULL; + + if (file) { + fclose(file); + } + + return res; +} + +char *util_fs_get_path_to_file(const char *path) +{ + size_t len; + char *res; + + len = strlen(path); + + for (ssize_t i = len - 1; i >= 0; i--) { + if (path[i] == '/') { + len--; + break; } - return exists; + len--; + } + + res = (char *) util_xmalloc(sizeof(char) * (len + 1)); + strncpy(res, path, len); + res[len] = '\0'; + + return res; } -bool util_fs_mkdir(const char* path) +char *util_fs_get_filename(const char *path) { - return mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0; -} + size_t path_len; + size_t len; + char *res; -bool util_fs_mkfile(const char* path) -{ - FILE* file; - bool res; + len = strlen(path); + path_len = len; - file = fopen(path, "a"); - - res = file != NULL; - - if (file) { - fclose(file); + for (ssize_t i = len - 1; i >= 0; i--) { + if (path[i] == '/') { + len++; + break; } - return res; + len--; + } + + res = (char *) util_xmalloc(sizeof(char) * ((path_len - len) + 1)); + strncpy(res, path + len, path_len - len); + res[path_len - len] = '\0'; + + return res; } -char* util_fs_get_path_to_file(const char* path) +char *util_fs_get_abs_path(const char *path) { - size_t len; - char* res; + char *real_path; - len = strlen(path); + real_path = realpath(path, NULL); - for (ssize_t i = len - 1; i >= 0; i--) { - if (path[i] == '/') { - len--; - break; - } + if (!real_path) { + log_error( + "Resolving path '%s' to absolute path failed: %s", + path, + strerror(errno)); + } - len--; - } - - res = (char*) util_xmalloc(sizeof(char) * (len + 1)); - strncpy(res, path, len); - res[len] = '\0'; - - return res; -} - -char* util_fs_get_filename(const char* path) -{ - size_t path_len; - size_t len; - char* res; - - len = strlen(path); - path_len = len; - - for (ssize_t i = len - 1; i >= 0; i--) { - if (path[i] == '/') { - len++; - break; - } - - len--; - } - - res = (char*) util_xmalloc(sizeof(char) * ((path_len - len) + 1)); - strncpy(res, path + len, path_len - len); - res[path_len - len] = '\0'; - - return res; -} - -char* util_fs_get_abs_path(const char* path) -{ - char* real_path; - - real_path = realpath(path, NULL); - - if (!real_path) { - log_error("Resolving path '%s' to absolute path failed: %s", path, - strerror(errno)); - } - - return real_path; + return real_path; } \ No newline at end of file diff --git a/src/main/util/fs.h b/src/main/util/fs.h index 31f92af..76d96c5 100644 --- a/src/main/util/fs.h +++ b/src/main/util/fs.h @@ -17,7 +17,8 @@ * false for binary mode * @return True on success, false on error */ -bool util_file_load(const char* filename, void** bytes, size_t* nbytes, bool text_mode); +bool util_file_load( + const char *filename, void **bytes, size_t *nbytes, bool text_mode); /** * Save a buffer to a file (overwrite any existing files with the same name) @@ -27,14 +28,14 @@ bool util_file_load(const char* filename, void** bytes, size_t* nbytes, bool tex * @param nbytes Number of bytes to write to the file * @return True on success, false on error */ -bool util_file_save(const char* filename, const void* bytes, size_t nbytes); +bool util_file_save(const char *filename, const void *bytes, size_t nbytes); /** * Check if a normal file, folder, symlink, ... exists * * @return True if exists, false otherwise */ -bool util_fs_path_exists(const char* path); +bool util_fs_path_exists(const char *path); /** * Create a new directory @@ -42,7 +43,7 @@ bool util_fs_path_exists(const char* path); * @param path Path to directory * @return True if successful, false on failure */ -bool util_fs_mkdir(const char* path); +bool util_fs_mkdir(const char *path); /** * Create a new empty file @@ -50,7 +51,7 @@ bool util_fs_mkdir(const char* path); * @param path Path to the file to create * @return True if successful, false on failure */ -bool util_fs_mkfile(const char* path); +bool util_fs_mkfile(const char *path); /** * Get the path pointing to the file (without the filename) @@ -58,7 +59,7 @@ bool util_fs_mkfile(const char* path); * @param path Full path to file * @return Newly allocated string (caller has to free) containing the path, only */ -char* util_fs_get_path_to_file(const char* path); +char *util_fs_get_path_to_file(const char *path); /** * Get the start position of the filename in the path @@ -67,7 +68,7 @@ char* util_fs_get_path_to_file(const char* path); * @return Newly allocated string (caller has to free) containing the filename, * only */ -char* util_fs_get_filename(const char* path); +char *util_fs_get_filename(const char *path); /** * Get the absolute path of the give (relative) path @@ -76,6 +77,6 @@ char* util_fs_get_filename(const char* path); * @return Allocated string (caller has to free) containing the full absolute * path for the given (relative) path */ -char* util_fs_get_abs_path(const char* path); +char *util_fs_get_abs_path(const char *path); #endif diff --git a/src/main/util/glibc.c b/src/main/util/glibc.c index bc0b506..2f1a973 100644 --- a/src/main/util/glibc.c +++ b/src/main/util/glibc.c @@ -6,5 +6,8 @@ void util_glibc_info_log() { - log_info("glibc release '%s', version '%s'", gnu_get_libc_release(), gnu_get_libc_version()); + log_info( + "glibc release '%s', version '%s'", + gnu_get_libc_release(), + gnu_get_libc_version()); } \ No newline at end of file diff --git a/src/main/util/hex.c b/src/main/util/hex.c index bcfd471..cc5e120 100644 --- a/src/main/util/hex.c +++ b/src/main/util/hex.c @@ -7,67 +7,70 @@ static bool util_hex_decode_nibble(char c, uint8_t *nibble) { - if (c >= '0' && c <= '9') { - *nibble = c - '0'; - } else if (c >= 'A' && c <= 'F') { - *nibble = c - 'A' + 10; - } else if (c >= 'a' && c <= 'f') { - *nibble = c - 'a' + 10; - } else { - return false; - } + if (c >= '0' && c <= '9') { + *nibble = c - '0'; + } else if (c >= 'A' && c <= 'F') { + *nibble = c - 'A' + 10; + } else if (c >= 'a' && c <= 'f') { + *nibble = c - 'a' + 10; + } else { + return false; + } - return true; + return true; } bool util_hex_decode(void *ptr, size_t nbytes, const char *chars, size_t nchars) { - uint8_t *bytes = ptr; + uint8_t *bytes = ptr; - uint32_t i; - uint8_t hi; - uint8_t lo; + uint32_t i; + uint8_t hi; + uint8_t lo; - log_assert(nchars >= 2 * nbytes); + log_assert(nchars >= 2 * nbytes); - for (i = 0 ; i < nbytes ; i++) { - if ( !util_hex_decode_nibble(chars[2 * i + 0], &hi) || - !util_hex_decode_nibble(chars[2 * i + 1], &lo)) { - return false; - } - - bytes[i] = (hi << 4) | lo; + for (i = 0; i < nbytes; i++) { + if (!util_hex_decode_nibble(chars[2 * i + 0], &hi) || + !util_hex_decode_nibble(chars[2 * i + 1], &lo)) { + return false; } - return true; + bytes[i] = (hi << 4) | lo; + } + + return true; } -static void util_hex_encode(const void *ptr, size_t nbytes, char *chars, - size_t nchars, const char *digits) +static void util_hex_encode( + const void *ptr, + size_t nbytes, + char *chars, + size_t nchars, + const char *digits) { - const uint8_t *bytes = ptr; + const uint8_t *bytes = ptr; - size_t i; + size_t i; - log_assert(nchars >= 2 * nbytes + 1); + log_assert(nchars >= 2 * nbytes + 1); - for (i = 0 ; i < nbytes ; i++) { - chars[i * 2 + 0] = digits[bytes[i] >> 4]; - chars[i * 2 + 1] = digits[bytes[i] & 15]; - } + for (i = 0; i < nbytes; i++) { + chars[i * 2 + 0] = digits[bytes[i] >> 4]; + chars[i * 2 + 1] = digits[bytes[i] & 15]; + } - chars[nbytes * 2] = '\0'; + chars[nbytes * 2] = '\0'; } -void util_hex_encode_lc(const void *bytes, size_t nbytes, char *chars, - size_t nchars) +void util_hex_encode_lc( + const void *bytes, size_t nbytes, char *chars, size_t nchars) { - util_hex_encode(bytes, nbytes, chars, nchars, "0123456789abcdef"); + util_hex_encode(bytes, nbytes, chars, nchars, "0123456789abcdef"); } -void util_hex_encode_uc(const void *bytes, size_t nbytes, char *chars, - size_t nchars) +void util_hex_encode_uc( + const void *bytes, size_t nbytes, char *chars, size_t nchars) { - util_hex_encode(bytes, nbytes, chars, nchars, "0123456789ABCDEF"); + util_hex_encode(bytes, nbytes, chars, nchars, "0123456789ABCDEF"); } - diff --git a/src/main/util/hex.h b/src/main/util/hex.h index 96486cb..57dc494 100644 --- a/src/main/util/hex.h +++ b/src/main/util/hex.h @@ -4,11 +4,11 @@ #include #include -bool util_hex_decode(void *bytes, size_t nbytes, const char *chars, - size_t nchars); -void util_hex_encode_uc(const void *bytes, size_t nbytes, char *chars, - size_t nchars); -void util_hex_encode_lc(const void *bytes, size_t nbytes, char *chars, - size_t nchars); +bool util_hex_decode( + void *bytes, size_t nbytes, const char *chars, size_t nchars); +void util_hex_encode_uc( + const void *bytes, size_t nbytes, char *chars, size_t nchars); +void util_hex_encode_lc( + const void *bytes, size_t nbytes, char *chars, size_t nchars); #endif diff --git a/src/main/util/iobuf.c b/src/main/util/iobuf.c index b8bd76e..56df2a8 100644 --- a/src/main/util/iobuf.c +++ b/src/main/util/iobuf.c @@ -2,21 +2,20 @@ #include -size_t util_iobuf_move(struct util_iobuf* dest, struct util_const_iobuf* src) +size_t util_iobuf_move(struct util_iobuf *dest, struct util_const_iobuf *src) { - size_t dest_avail; - size_t src_avail; - size_t chunksz; + size_t dest_avail; + size_t src_avail; + size_t chunksz; - dest_avail = dest->nbytes - dest->pos; - src_avail = src->nbytes - src->pos; - chunksz = dest_avail < src_avail ? dest_avail : src_avail; + dest_avail = dest->nbytes - dest->pos; + src_avail = src->nbytes - src->pos; + chunksz = dest_avail < src_avail ? dest_avail : src_avail; - memcpy(&dest->bytes[dest->pos], &src->bytes[src->pos], chunksz); + memcpy(&dest->bytes[dest->pos], &src->bytes[src->pos], chunksz); - dest->pos += chunksz; - src->pos += chunksz; + dest->pos += chunksz; + src->pos += chunksz; - return chunksz; + return chunksz; } - diff --git a/src/main/util/iobuf.h b/src/main/util/iobuf.h index 4086482..d39bd56 100644 --- a/src/main/util/iobuf.h +++ b/src/main/util/iobuf.h @@ -8,18 +8,18 @@ * Iobuffer struct holding data, size and position */ struct util_iobuf { - uint8_t* bytes; - size_t nbytes; - size_t pos; + uint8_t *bytes; + size_t nbytes; + size_t pos; }; /** * Const variant of iobuffer struct holding data, size and position */ struct util_const_iobuf { - const uint8_t* bytes; - size_t nbytes; - size_t pos; + const uint8_t *bytes; + size_t nbytes; + size_t pos; }; /** @@ -27,9 +27,9 @@ struct util_const_iobuf { * * @param dest Destination to move to * @param src Source to move from - * @return Number of bytes moved (this can be less than the source's size + * @return Number of bytes moved (this can be less than the source's size * e.g. if destination size < src size) */ -size_t util_iobuf_move(struct util_iobuf* dest, struct util_const_iobuf* src); +size_t util_iobuf_move(struct util_iobuf *dest, struct util_const_iobuf *src); #endif diff --git a/src/main/util/list.c b/src/main/util/list.c index b88d2c1..0218e09 100644 --- a/src/main/util/list.c +++ b/src/main/util/list.c @@ -3,89 +3,88 @@ #include #include -void util_list_init(struct util_list* list) +void util_list_init(struct util_list *list) { - memset(list, 0, sizeof(*list)); + memset(list, 0, sizeof(*list)); } -void util_list_append(struct util_list* list, struct util_list_node* node) +void util_list_append(struct util_list *list, struct util_list_node *node) { - node->next = NULL; + node->next = NULL; - if (list->tail != NULL) { - list->tail->next = node; - } else { - list->head = node; + if (list->tail != NULL) { + list->tail->next = node; + } else { + list->head = node; + } + + list->tail = node; +} + +bool util_list_contains(struct util_list *list, struct util_list_node *node) +{ + struct util_list_node *pos; + + for (pos = list->head; pos != NULL; pos = pos->next) { + if (pos == node) { + return true; } + } - list->tail = node; + return false; } -bool util_list_contains(struct util_list* list, struct util_list_node* node) +struct util_list_node *util_list_pop_head(struct util_list *list) { - struct util_list_node* pos; + struct util_list_node *node; - for (pos = list->head ; pos != NULL ; pos = pos->next) { - if (pos == node) { - return true; - } + if (list->head == NULL) { + return NULL; + } + + node = list->head; + list->head = node->next; + + if (node->next == NULL) { + list->tail = NULL; + } + + node->next = NULL; + + return node; +} + +void util_list_remove(struct util_list *list, struct util_list_node *node) +{ + struct util_list_node *pos; + struct util_list_node *prev; + + for (prev = NULL, pos = list->head; pos != NULL; + prev = pos, pos = pos->next) { + if (pos == node) { + if (prev != NULL) { + prev->next = node->next; + } else { + list->head = node->next; + } + + if (node->next == NULL) { + list->tail = prev; + } + + node->next = NULL; + + return; } - - return false; + } } -struct util_list_node* util_list_pop_head(struct util_list* list) +bool util_list_empty(struct util_list *list) { - struct util_list_node* node; - - if (list->head == NULL) { - return NULL; - } - - node = list->head; - list->head = node->next; - - if (node->next == NULL) { - list->tail = NULL; - } - - node->next = NULL; - - return node; + return list->head == NULL; } -void util_list_remove(struct util_list* list, struct util_list_node* node) +inline struct util_list_node *util_list_peek_head(struct util_list *list) { - struct util_list_node* pos; - struct util_list_node* prev; - - for (prev = NULL, pos = list->head - ; pos != NULL - ; prev = pos, pos = pos->next) { - if (pos == node) { - if (prev != NULL) { - prev->next = node->next; - } else { - list->head = node->next; - } - - if (node->next == NULL) { - list->tail = prev; - } - - node->next = NULL; - - return; - } - } -} - -bool util_list_empty(struct util_list* list) -{ - return list->head == NULL; -} - -inline struct util_list_node* util_list_peek_head(struct util_list* list) -{ - return list->head; + return list->head; } diff --git a/src/main/util/list.h b/src/main/util/list.h index 7ab8aeb..fe9efc6 100644 --- a/src/main/util/list.h +++ b/src/main/util/list.h @@ -8,15 +8,15 @@ * (Doubly linked) list object */ struct util_list { - struct util_list_node* head; - struct util_list_node* tail; + struct util_list_node *head; + struct util_list_node *tail; }; /** * List element/node */ struct util_list_node { - struct util_list_node* next; + struct util_list_node *next; }; /** @@ -24,7 +24,7 @@ struct util_list_node { * * @param list Pointer to a list to initialize */ -void util_list_init(struct util_list* list); +void util_list_init(struct util_list *list); /** * Append an element to a list @@ -32,7 +32,7 @@ void util_list_init(struct util_list* list); * @param list List to append to * @param node Node to append to the list */ -void util_list_append(struct util_list* list, struct util_list_node* node); +void util_list_append(struct util_list *list, struct util_list_node *node); /** * Check if the list contains the specified element @@ -41,7 +41,7 @@ void util_list_append(struct util_list* list, struct util_list_node* node); * @param node Node to look for in the list * @return True if list contains the specified node, false otherwise */ -bool util_list_contains(struct util_list* list, struct util_list_node* node); +bool util_list_contains(struct util_list *list, struct util_list_node *node); /** * Peak (get but do not remove) the head of the list @@ -49,7 +49,7 @@ bool util_list_contains(struct util_list* list, struct util_list_node* node); * @param list List to peak * @return Head element of the list (or null if empty) */ -struct util_list_node* util_list_peek_head(struct util_list* list); +struct util_list_node *util_list_peek_head(struct util_list *list); /** * Pop (get and remove) the head of the list @@ -57,16 +57,16 @@ struct util_list_node* util_list_peek_head(struct util_list* list); * @param list List to pop * @return Removed head element of the list (or null if empty) */ -struct util_list_node* util_list_pop_head(struct util_list* list); +struct util_list_node *util_list_pop_head(struct util_list *list); /** * Remove a specific element of the list. If the element is not part of the, * the list is not modified. - * + * * @param list List to remove an element from * @param node Element to remove from the list */ -void util_list_remove(struct util_list* list, struct util_list_node* node); +void util_list_remove(struct util_list *list, struct util_list_node *node); /** * Check if a list is empty @@ -74,6 +74,6 @@ void util_list_remove(struct util_list* list, struct util_list_node* node); * @param list List to check * @return True if empty, false otherwise */ -bool util_list_empty(struct util_list* list); +bool util_list_empty(struct util_list *list); #endif diff --git a/src/main/util/log.c b/src/main/util/log.c index cee3fc6..105b9a5 100644 --- a/src/main/util/log.c +++ b/src/main/util/log.c @@ -11,139 +11,203 @@ #define COLORIZING_CONTROL_SEQ "\033[%d;%dm%s\033[0m" -static void util_log_format(enum util_log_level level, const char* module, - const char* trace_file, size_t trace_line, const char* fmt, va_list ap); -static void util_log_writer_console(void* ctx, enum util_log_level level, const char* module, const char* trace_file, - size_t trace_line, const char* msg); -static void util_log_writer_file(void* ctx, enum util_log_level level, const char* module, const char* trace_file, - size_t trace_line, const char* msg); +static void util_log_format( + enum util_log_level level, + const char *module, + const char *trace_file, + size_t trace_line, + const char *fmt, + va_list ap); +static void util_log_writer_console( + void *ctx, + enum util_log_level level, + const char *module, + const char *trace_file, + size_t trace_line, + const char *msg); +static void util_log_writer_file( + void *ctx, + enum util_log_level level, + const char *module, + const char *trace_file, + size_t trace_line, + const char *msg); static const char util_log_level_chars[] = "DEWIM"; static enum util_log_level util_log_level = LOG_LEVEL_DEBUG; -static FILE* util_log_file; +static FILE *util_log_file; -void util_log_set_file(const char* path, bool append) +void util_log_set_file(const char *path, bool append) { - const char* mode = append ? "a+" : "w+"; + const char *mode = append ? "a+" : "w+"; - if (path) { - util_log_file = fopen(path, mode); - log_info("Open log file: %s", path); - } + if (path) { + util_log_file = fopen(path, mode); + log_info("Open log file: %s", path); + } } void util_log_set_level(enum util_log_level new_level) { - util_log_level = new_level; + util_log_level = new_level; } -FILE* util_log_get_file_handle(void) +FILE *util_log_get_file_handle(void) { - return util_log_file; + return util_log_file; } -void util_log(enum util_log_level level, const char* module, const char* trace_file, size_t trace_line, - const char* fmt, ...) +void util_log( + enum util_log_level level, + const char *module, + const char *trace_file, + size_t trace_line, + const char *fmt, + ...) { - va_list ap; + va_list ap; - va_start(ap, fmt); - util_log_format(level, module, trace_file, trace_line, fmt, ap); - va_end(ap); + va_start(ap, fmt); + util_log_format(level, module, trace_file, trace_line, fmt, ap); + va_end(ap); } -static void util_log_colorize_text(enum util_log_level level, const char* text, char* buffer) +static void util_log_colorize_text( + enum util_log_level level, const char *text, char *buffer) { - switch (level) { - case LOG_LEVEL_DEBUG: - sprintf(buffer, COLORIZING_CONTROL_SEQ, 0, 37, text); - break; + switch (level) { + case LOG_LEVEL_DEBUG: + sprintf(buffer, COLORIZING_CONTROL_SEQ, 0, 37, text); + break; - case LOG_LEVEL_INFO: - sprintf(buffer, COLORIZING_CONTROL_SEQ, 0, 34, text); - break; + case LOG_LEVEL_INFO: + sprintf(buffer, COLORIZING_CONTROL_SEQ, 0, 34, text); + break; - case LOG_LEVEL_WARN: - sprintf(buffer, COLORIZING_CONTROL_SEQ, 0, 33, text); - break; + case LOG_LEVEL_WARN: + sprintf(buffer, COLORIZING_CONTROL_SEQ, 0, 33, text); + break; - case LOG_LEVEL_ERROR: - sprintf(buffer, COLORIZING_CONTROL_SEQ, 0, 31, text); - break; + case LOG_LEVEL_ERROR: + sprintf(buffer, COLORIZING_CONTROL_SEQ, 0, 31, text); + break; - case LOG_LEVEL_DIE: - sprintf(buffer, COLORIZING_CONTROL_SEQ, 0, 31, text); - break; + case LOG_LEVEL_DIE: + sprintf(buffer, COLORIZING_CONTROL_SEQ, 0, 31, text); + break; - default: - log_die_illegal_state(); - break; + default: + log_die_illegal_state(); + break; + } +} + +static void util_log_format( + enum util_log_level level, + const char *module, + const char *trace_file, + size_t trace_line, + const char *fmt, + va_list ap) +{ + char msg[8192]; + + if (level <= util_log_level) { + util_str_vformat(msg, sizeof(msg), fmt, ap); + + util_log_writer_console(NULL, level, module, trace_file, trace_line, msg); + + if (util_log_file != NULL) { + util_log_writer_file( + util_log_file, level, module, trace_file, trace_line, msg); } + } + + if (level == LOG_LEVEL_DIE) { + abort(); + } } -static void util_log_format(enum util_log_level level, const char* module, - const char* trace_file, size_t trace_line, const char* fmt, va_list ap) +static void util_log_writer_console( + void *ctx, + enum util_log_level level, + const char *module, + const char *trace_file, + size_t trace_line, + const char *msg) { - char msg[8192]; + char text_level[128]; + char text_level_color[128]; - if (level <= util_log_level) { - util_str_vformat(msg, sizeof(msg), fmt, ap); + util_str_format( + text_level, sizeof(text_level), "[%c]", util_log_level_chars[level]); + util_log_colorize_text(level, text_level, text_level_color); - util_log_writer_console(NULL, level, module, trace_file, trace_line, msg); + // --------------------------- - if (util_log_file != NULL) { - util_log_writer_file(util_log_file, level, module, trace_file, trace_line, msg); - } - } + struct util_time_timestamp timestamp; - if (level == LOG_LEVEL_DIE) { - abort(); - } + util_time_get_current_time(×tamp); + + // --------------------------- + + char line[8192]; + + util_str_format( + line, + sizeof(line), + "%s[%d/%d/%d-%d:%d:%d:%d][%s][%s:%d] %s\n", + text_level_color, + timestamp.year, + timestamp.month, + timestamp.day, + timestamp.hour, + timestamp.min, + timestamp.sec, + timestamp.millisec, + module, + trace_file, + trace_line, + msg); + + printf("%s", line); } -static void util_log_writer_console(void* ctx, enum util_log_level level, const char* module, const char* trace_file, - size_t trace_line, const char* msg) +static void util_log_writer_file( + void *ctx, + enum util_log_level level, + const char *module, + const char *trace_file, + size_t trace_line, + const char *msg) { - char text_level[128]; - char text_level_color[128]; + struct util_time_timestamp timestamp; - util_str_format(text_level, sizeof(text_level), "[%c]", util_log_level_chars[level]); - util_log_colorize_text(level, text_level, text_level_color); + util_time_get_current_time(×tamp); - // --------------------------- + // --------------------------- - struct util_time_timestamp timestamp; + char line[8192]; + size_t line_len; - util_time_get_current_time(×tamp); + line_len = util_str_format( + line, + sizeof(line), + "[%c][%d/%d/%d-%d:%d:%d:%d][%s][%s:%d] %s\n", + util_log_level_chars[level], + timestamp.year, + timestamp.month, + timestamp.day, + timestamp.hour, + timestamp.min, + timestamp.sec, + timestamp.millisec, + module, + trace_file, + trace_line, + msg); - // --------------------------- - - char line[8192]; - - util_str_format(line, sizeof(line), "%s[%d/%d/%d-%d:%d:%d:%d][%s][%s:%d] %s\n", text_level_color, timestamp.year, - timestamp.month, timestamp.day, timestamp.hour, timestamp.min, timestamp.sec, timestamp.millisec, - module, trace_file, trace_line, msg); - - printf("%s", line); -} - -static void util_log_writer_file(void* ctx, enum util_log_level level, const char* module, const char* trace_file, - size_t trace_line, const char* msg) -{ - struct util_time_timestamp timestamp; - - util_time_get_current_time(×tamp); - - // --------------------------- - - char line[8192]; - size_t line_len; - - line_len = util_str_format(line, sizeof(line), "[%c][%d/%d/%d-%d:%d:%d:%d][%s][%s:%d] %s\n", - util_log_level_chars[level], timestamp.year, timestamp.month, timestamp.day, timestamp.hour, timestamp.min, - timestamp.sec, timestamp.millisec, module, trace_file, trace_line, msg); - - fwrite(line, 1, line_len, (FILE*) ctx); - fflush((FILE*) ctx); + fwrite(line, 1, line_len, (FILE *) ctx); + fflush((FILE *) ctx); } \ No newline at end of file diff --git a/src/main/util/log.h b/src/main/util/log.h index 708a0fb..a6dd4e8 100644 --- a/src/main/util/log.h +++ b/src/main/util/log.h @@ -22,12 +22,18 @@ #define SOURCE_LINE __LINE__ #endif -#define log_debug(...) util_log(LOG_LEVEL_DEBUG, LOG_MODULE, FILENAME, SOURCE_LINE, __VA_ARGS__) -#define log_info(...) util_log(LOG_LEVEL_INFO, LOG_MODULE, FILENAME, SOURCE_LINE, __VA_ARGS__) -#define log_warn(...) util_log(LOG_LEVEL_WARN, LOG_MODULE, FILENAME, SOURCE_LINE, __VA_ARGS__) -#define log_error(...) util_log(LOG_LEVEL_ERROR, LOG_MODULE, FILENAME, SOURCE_LINE, __VA_ARGS__) -#define log_die(...) util_log(LOG_LEVEL_DIE, LOG_MODULE, FILENAME, SOURCE_LINE, __VA_ARGS__) -#define log_die_illegal_state() util_log(LOG_LEVEL_DIE, LOG_MODULE, FILENAME, SOURCE_LINE, "Illegal state") +#define log_debug(...) \ + util_log(LOG_LEVEL_DEBUG, LOG_MODULE, FILENAME, SOURCE_LINE, __VA_ARGS__) +#define log_info(...) \ + util_log(LOG_LEVEL_INFO, LOG_MODULE, FILENAME, SOURCE_LINE, __VA_ARGS__) +#define log_warn(...) \ + util_log(LOG_LEVEL_WARN, LOG_MODULE, FILENAME, SOURCE_LINE, __VA_ARGS__) +#define log_error(...) \ + util_log(LOG_LEVEL_ERROR, LOG_MODULE, FILENAME, SOURCE_LINE, __VA_ARGS__) +#define log_die(...) \ + util_log(LOG_LEVEL_DIE, LOG_MODULE, FILENAME, SOURCE_LINE, __VA_ARGS__) +#define log_die_illegal_state() \ + util_log(LOG_LEVEL_DIE, LOG_MODULE, FILENAME, SOURCE_LINE, "Illegal state") #else @@ -39,31 +45,33 @@ #endif -#define log_assert(x) \ - do { \ - if (!(x)) { \ - log_die(FILENAME, __LINE__, __FUNCTION__); \ - } \ - } while (0) +#define log_assert(x) \ + do { \ + if (!(x)) { \ + log_die(FILENAME, __LINE__, __FUNCTION__); \ + } \ + } while (0) /** * Different log levels for logging */ enum util_log_level { - LOG_LEVEL_DIE = 0, - LOG_LEVEL_ERROR = 1, - LOG_LEVEL_WARN = 2, - LOG_LEVEL_INFO = 3, - LOG_LEVEL_DEBUG = 4 + LOG_LEVEL_DIE = 0, + LOG_LEVEL_ERROR = 1, + LOG_LEVEL_WARN = 2, + LOG_LEVEL_INFO = 3, + LOG_LEVEL_DEBUG = 4 }; /** * Open a log file to write log output to in addition to stdout * - * @param path Path of the log file (existing files are overwritten of append argument false) - * @param append True to append to an existing file, false to create a new file with the specified name + * @param path Path of the log file (existing files are overwritten of append + * argument false) + * @param append True to append to an existing file, false to create a new file + * with the specified name */ -void util_log_set_file(const char* path, bool append); +void util_log_set_file(const char *path, bool append); /** * Set the log level for logging @@ -73,11 +81,12 @@ void util_log_set_file(const char* path, bool append); void util_log_set_level(enum util_log_level new_level); /** - * Get the log file handle (required for hooking to filter it on fwrite calls on the filehook monitor) + * Get the log file handle (required for hooking to filter it on fwrite calls on + * the filehook monitor) * * @return FILE handle of log file or NULL if logging to file disabled */ -FILE* util_log_get_file_handle(void); +FILE *util_log_get_file_handle(void); /** * Log a message @@ -91,7 +100,12 @@ FILE* util_log_get_file_handle(void); * @param fmt Format string of log message * @param ... Arguments for format string */ -void util_log(enum util_log_level level, const char* module, const char* trace_file, size_t trace_line, - const char* fmt, ...); +void util_log( + enum util_log_level level, + const char *module, + const char *trace_file, + size_t trace_line, + const char *fmt, + ...); #endif \ No newline at end of file diff --git a/src/main/util/mem.c b/src/main/util/mem.c index b6923c7..589837e 100644 --- a/src/main/util/mem.c +++ b/src/main/util/mem.c @@ -9,9 +9,9 @@ static bool _util_mem_debug_output; -static void* _util_xmalloc(size_t nbytes); -static void* _util_xrealloc(void* mem, size_t nbytes); -static void _util_xfree(void** mem); +static void *_util_xmalloc(size_t nbytes); +static void *_util_xrealloc(void *mem, size_t nbytes); +static void _util_xfree(void **mem); static const struct util_mem_interface _util_mem_interface_default = { .xmalloc = _util_xmalloc, @@ -19,90 +19,91 @@ static const struct util_mem_interface _util_mem_interface_default = { .xfree = _util_xfree, }; -static const struct util_mem_interface* _util_mem_interface = &_util_mem_interface_default; +static const struct util_mem_interface *_util_mem_interface = + &_util_mem_interface_default; -static void* _util_xmalloc(size_t nbytes) +static void *_util_xmalloc(size_t nbytes) { - void* mem; + void *mem; - mem = malloc(nbytes); + mem = malloc(nbytes); + if (_util_mem_debug_output) { + log_debug("xmalloc(%d): %p", nbytes, mem); + } + + if (mem == NULL) { + log_die("xmalloc(%u) failed", (uint32_t) nbytes); + return NULL; + } + + return mem; +} + +static void *_util_xrealloc(void *mem, size_t nbytes) +{ + void *newmem; + + newmem = realloc(mem, nbytes); + + if (_util_mem_debug_output) { + log_debug("xrealloc(%p %d): %p", mem, nbytes, newmem); + } + + if (newmem == NULL) { + log_die("xrealloc(%p, %u) failed", mem, (uint32_t) nbytes); + return NULL; + } + + return newmem; +} + +static void _util_xfree(void **mem) +{ + log_assert(mem); + + if (*mem != NULL) { if (_util_mem_debug_output) { - log_debug("xmalloc(%d): %p", nbytes, mem); + log_debug("xfree(%p %p)", mem, *mem); } - if (mem == NULL) { - log_die("xmalloc(%u) failed", (uint32_t) nbytes); - return NULL; - } - - return mem; -} - -static void* _util_xrealloc(void* mem, size_t nbytes) -{ - void* newmem; - - newmem = realloc(mem, nbytes); - + free(*mem); + *mem = NULL; + } else { if (_util_mem_debug_output) { - log_debug("xrealloc(%p %d): %p", mem, nbytes, newmem); + log_warn("xfree(%p NULL)", mem); } - - if (newmem == NULL) { - log_die("xrealloc(%p, %u) failed", mem, (uint32_t) nbytes); - return NULL; - } - - return newmem; + } } -static void _util_xfree(void** mem) +void util_mem_init(const struct util_mem_interface *interface) { - log_assert(mem); + log_assert(interface); - if (*mem != NULL) { - if (_util_mem_debug_output) { - log_debug("xfree(%p %p)", mem, *mem); - } - - free(*mem); - *mem = NULL; - } else { - if (_util_mem_debug_output) { - log_warn("xfree(%p NULL)", mem); - } - } -} - -void util_mem_init(const struct util_mem_interface* interface) -{ - log_assert(interface); - - _util_mem_interface = interface; + _util_mem_interface = interface; } void util_mem_init_default() { - _util_mem_interface = &_util_mem_interface_default; + _util_mem_interface = &_util_mem_interface_default; } void util_mem_enable_debug_output() { - _util_mem_debug_output = true; + _util_mem_debug_output = true; } -void* util_xmalloc(size_t nbytes) +void *util_xmalloc(size_t nbytes) { - return _util_mem_interface->xmalloc(nbytes); + return _util_mem_interface->xmalloc(nbytes); } -void* util_xrealloc(void* mem, size_t nbytes) +void *util_xrealloc(void *mem, size_t nbytes) { - return _util_mem_interface->xrealloc(mem, nbytes); + return _util_mem_interface->xrealloc(mem, nbytes); } -void util_xfree(void** mem) +void util_xfree(void **mem) { - _util_mem_interface->xfree(mem); + _util_mem_interface->xfree(mem); } \ No newline at end of file diff --git a/src/main/util/mem.h b/src/main/util/mem.h index 5eaedb1..b9a0c00 100644 --- a/src/main/util/mem.h +++ b/src/main/util/mem.h @@ -1,32 +1,35 @@ #ifndef UTIL_MEM_H #define UTIL_MEM_H -#include #include +#include -typedef void* (*util_xmalloc_t)(size_t nbytes); -typedef void* (*util_xrealloc_t)(void* mem, size_t nbytes); -typedef void (*util_free_t)(void** mem); +typedef void *(*util_xmalloc_t)(size_t nbytes); +typedef void *(*util_xrealloc_t)(void *mem, size_t nbytes); +typedef void (*util_free_t)(void **mem); struct util_mem_interface { - util_xmalloc_t xmalloc; - util_xrealloc_t xrealloc; - util_free_t xfree; + util_xmalloc_t xmalloc; + util_xrealloc_t xrealloc; + util_free_t xfree; }; /** - * Install a different memory interfacee, e.g. to use a different allocator or hooks for unit-testing. + * Install a different memory interfacee, e.g. to use a different allocator or + * hooks for unit-testing. */ -void util_mem_init(const struct util_mem_interface* interface); +void util_mem_init(const struct util_mem_interface *interface); /** - * Optional, initialize the default memory interface. This needs to be called only if you want to switch back from - * a non-default interface that got installed using util_mem_init. + * Optional, initialize the default memory interface. This needs to be called + * only if you want to switch back from a non-default interface that got + * installed using util_mem_init. */ void util_mem_init_default(); /** - * Enable debug output of all allocations and de-allocations that go through the default interface of this module. + * Enable debug output of all allocations and de-allocations that go through the + * default interface of this module. */ void util_mem_enable_debug_output(); @@ -36,7 +39,7 @@ void util_mem_enable_debug_output(); * @param nbytes Number of bytes to allocate * @return Pointer to allocated memory */ -void* util_xmalloc(size_t nbytes); +void *util_xmalloc(size_t nbytes); /** * Realloc memory (realloc wrapper) @@ -45,13 +48,14 @@ void* util_xmalloc(size_t nbytes); * @param nbytes New size of memory region * @return Pointer to reallocated memory region */ -void* util_xrealloc(void* mem, size_t nbytes); +void *util_xrealloc(void *mem, size_t nbytes); /** * Free allocated memory. * - * @param mem Pointer to the pointer with allocated memory to free. The pointer to the memory will be set to NULL. + * @param mem Pointer to the pointer with allocated memory to free. The pointer + * to the memory will be set to NULL. */ -void util_xfree(void** mem); +void util_xfree(void **mem); #endif diff --git a/src/main/util/net.c b/src/main/util/net.c index c65fd65..e6d4dda 100644 --- a/src/main/util/net.c +++ b/src/main/util/net.c @@ -4,38 +4,38 @@ #include "util/net.h" #include "util/str.h" -bool util_net_split_ipv4_str(const char* str, char** address, uint16_t* port) +bool util_net_split_ipv4_str(const char *str, char **address, uint16_t *port) { - char* tmp = util_str_dup(str); - char* pch = strtok(tmp, ":"); - int counter = 0; + char *tmp = util_str_dup(str); + char *pch = strtok(tmp, ":"); + int counter = 0; - *address = NULL; - *port = 0xFFFF; + *address = NULL; + *port = 0xFFFF; - while (pch != NULL) { - switch (counter) { - case 0: - *address = util_str_dup(pch); - break; + while (pch != NULL) { + switch (counter) { + case 0: + *address = util_str_dup(pch); + break; - case 1: - *port = (uint16_t) strtol(pch, NULL, 10); - break; + case 1: + *port = (uint16_t) strtol(pch, NULL, 10); + break; - default: - if (*address) { - free(*address); - } - - free(tmp); - return false; + default: + if (*address) { + free(*address); } - pch = strtok (NULL, ":"); - counter++; + free(tmp); + return false; } - free(tmp); - return true; + pch = strtok(NULL, ":"); + counter++; + } + + free(tmp); + return true; } \ No newline at end of file diff --git a/src/main/util/net.h b/src/main/util/net.h index 1aac758..9e2073b 100644 --- a/src/main/util/net.h +++ b/src/main/util/net.h @@ -5,13 +5,14 @@ #include /** - * Split an ipv4 string (e.g. 127.0.0.1:22 or just 127.0.0.1) into address and port + * Split an ipv4 string (e.g. 127.0.0.1:22 or just 127.0.0.1) into address and + * port * * @param str String to split * @param address Address part (must be free'd by caller) * @param port Port part (or -1 if it doesn't exist) * @return True if successful, false on format error */ -bool util_net_split_ipv4_str(const char* str, char** address, uint16_t* port); +bool util_net_split_ipv4_str(const char *str, char **address, uint16_t *port); #endif diff --git a/src/main/util/options.c b/src/main/util/options.c index b086b22..626a5b8 100644 --- a/src/main/util/options.c +++ b/src/main/util/options.c @@ -12,747 +12,755 @@ #include "util/options.h" #include "util/str.h" -static struct util_options_opts* util_options_get2(int argc, char** argv, - const struct util_options_defs* option_defs); -static bool util_options_init_from_args(struct util_options_opts* options, - const struct util_options_defs* option_defs, int argc, char** argv); -static bool util_options_init_from_file(struct util_options_opts* options, - const struct util_options_defs* option_defs, char* file_path); +static struct util_options_opts *util_options_get2( + int argc, char **argv, const struct util_options_defs *option_defs); +static bool util_options_init_from_args( + struct util_options_opts *options, + const struct util_options_defs *option_defs, + int argc, + char **argv); +static bool util_options_init_from_file( + struct util_options_opts *options, + const struct util_options_defs *option_defs, + char *file_path); static bool util_options_write_default_options_file( - const struct util_options_defs* option_defs, char* file_path); + const struct util_options_defs *option_defs, char *file_path); static int util_options_argc; -static char** util_options_argv; +static char **util_options_argv; -void util_options_init(int argc, char** argv) +void util_options_init(int argc, char **argv) { - util_options_argc = argc; - util_options_argv = argv; + util_options_argc = argc; + util_options_argv = argv; } -struct util_options_opts* util_options_get( - const struct util_options_defs* option_defs) +struct util_options_opts * +util_options_get(const struct util_options_defs *option_defs) { - struct util_options_opts* options; + struct util_options_opts *options; - options = util_options_get2(util_options_argc, util_options_argv, - option_defs); + options = + util_options_get2(util_options_argc, util_options_argv, option_defs); - if (!options) { - exit(0); + if (!options) { + exit(0); + } + + return options; +} + +int util_options_get_int(const struct util_options_opts *opts, const char *name) +{ + for (uint32_t i = 0; i < opts->entries; i++) { + + if (!strcmp(opts->defs->defs[i].name, name)) { + + if (opts->defs->defs[i].type != UTIL_OPTIONS_TYPE_INT) { + log_warn("Option %s is not of type int", name); + return 0; + } + + if (opts->values[i].avail) { + return opts->values[i].value.i; + } else { + return opts->defs->defs[i].default_value.i; + } } + } - return options; + log_warn("Could not find int option %s", name); + return 0; } -int util_options_get_int(const struct util_options_opts* opts, - const char* name) +double +util_options_get_double(const struct util_options_opts *opts, const char *name) { - for (uint32_t i = 0; i < opts->entries; i++) { + for (uint32_t i = 0; i < opts->entries; i++) { - if (!strcmp(opts->defs->defs[i].name, name)) { + if (!strcmp(opts->defs->defs[i].name, name)) { - if (opts->defs->defs[i].type != UTIL_OPTIONS_TYPE_INT) { - log_warn("Option %s is not of type int", name); - return 0; - } + if (opts->defs->defs[i].type != UTIL_OPTIONS_TYPE_DOUBLE) { + log_warn("Option %s is not of type double", name); + return 0; + } - if (opts->values[i].avail) { - return opts->values[i].value.i; - } else { - return opts->defs->defs[i].default_value.i; - } + if (opts->values[i].avail) { + return opts->values[i].value.d; + } else { + return opts->defs->defs[i].default_value.d; + } + } + } + + log_warn("Could not find double option %s", name); + return 0; +} + +const char * +util_options_get_str(const struct util_options_opts *opts, const char *name) +{ + for (uint32_t i = 0; i < opts->entries; i++) { + + if (!strcmp(opts->defs->defs[i].name, name)) { + + if (opts->defs->defs[i].type != UTIL_OPTIONS_TYPE_STR) { + log_warn("Option %s is not of type str", name); + return 0; + } + + if (opts->values[i].avail) { + return opts->values[i].value.str; + } else { + return opts->defs->defs[i].default_value.str; + } + } + } + + log_warn("Could not find str option %s", name); + return NULL; +} + +bool util_options_get_bool( + const struct util_options_opts *opts, const char *name) +{ + for (uint32_t i = 0; i < opts->entries; i++) { + + if (!strcmp(opts->defs->defs[i].name, name)) { + + if (opts->defs->defs[i].type != UTIL_OPTIONS_TYPE_BOOL) { + log_warn("Option %s is not of type bool", name); + return false; + } + + if (opts->values[i].avail) { + return opts->values[i].value.b; + } else { + return opts->defs->defs[i].default_value.b; + } + } + } + + log_warn("Could not find bool option %s", name); + return false; +} + +const uint8_t *util_options_get_bin( + const struct util_options_opts *opts, const char *name, size_t *length) +{ + for (uint32_t i = 0; i < opts->entries; i++) { + + if (!strcmp(opts->defs->defs[i].name, name)) { + + if (opts->defs->defs[i].type != UTIL_OPTIONS_TYPE_BIN) { + log_warn("Option %s is not of type bin", name); + return 0; + } + + if (opts->values[i].avail) { + if (length) { + *length = opts->values[i].value.bin.len; } - } - log_warn("Could not find int option %s", name); - return 0; + return opts->values[i].value.bin.data; + } else { + if (length) { + *length = opts->defs->defs[i].default_value.bin.len; + } + + return opts->defs->defs[i].default_value.bin.data; + } + } + } + + log_warn("Could not find bin option %s", name); + return NULL; } -double util_options_get_double(const struct util_options_opts* opts, const char* name) +void util_options_print_usage(const struct util_options_defs *option_defs) { - for (uint32_t i = 0; i < opts->entries; i++) { + printf( + "%s\nSpecify options as arguments or use --options [path file] to " + "specify a config file containing key=value per line entries\n", + option_defs->usage_header); - if (!strcmp(opts->defs->defs[i].name, name)) { + for (uint32_t i = 0; i < option_defs->ndefs; i++) { - if (opts->defs->defs[i].type != UTIL_OPTIONS_TYPE_DOUBLE) { - log_warn("Option %s is not of type double", name); - return 0; - } + switch (option_defs->defs[i].type) { + case UTIL_OPTIONS_TYPE_INT: { + printf( + " -%c [int] %s: %s\n" + " default: %d\n", + option_defs->defs[i].param, + option_defs->defs[i].name, + option_defs->defs[i].description, + option_defs->defs[i].default_value.i); - if (opts->values[i].avail) { - return opts->values[i].value.d; - } else { - return opts->defs->defs[i].default_value.d; - } - } + break; + } + + case UTIL_OPTIONS_TYPE_DOUBLE: { + printf( + " -%c [double] %s: %s\n" + " default: %f\n", + option_defs->defs[i].param, + option_defs->defs[i].name, + option_defs->defs[i].description, + option_defs->defs[i].default_value.d); + + break; + } + + case UTIL_OPTIONS_TYPE_STR: { + printf( + " -%c [str] %s: %s\n" + " default: %s\n", + option_defs->defs[i].param, + option_defs->defs[i].name, + option_defs->defs[i].description, + option_defs->defs[i].default_value.str); + + break; + } + + case UTIL_OPTIONS_TYPE_BOOL: { + printf( + " -%c [bool] %s: %s\n" + " default: %d\n", + option_defs->defs[i].param, + option_defs->defs[i].name, + option_defs->defs[i].description, + option_defs->defs[i].default_value.b); + + break; + } + + case UTIL_OPTIONS_TYPE_BIN: { + size_t len = option_defs->defs[i].default_value.bin.len * 2 + 1; + char *buf = util_xmalloc(len); + + util_hex_encode_uc( + option_defs->defs[i].default_value.bin.data, + option_defs->defs[i].default_value.bin.len, + buf, + len); + + printf( + " -%c [bin] %s: %s\n" + " default (len %Iu): %s\n", + option_defs->defs[i].param, + option_defs->defs[i].name, + option_defs->defs[i].description, + option_defs->defs[i].default_value.bin.len, + buf); + + free(buf); + + break; + } + + default: { + printf( + " -%c [unkn] %s: %s\n" + " default: -invalid-\n", + option_defs->defs[i].param, + option_defs->defs[i].name, + option_defs->defs[i].description); + + break; + } } - - log_warn("Could not find double option %s", name); - return 0; + } } -const char* util_options_get_str(const struct util_options_opts* opts, - const char* name) +void util_options_free(struct util_options_opts *opts) { - for (uint32_t i = 0; i < opts->entries; i++) { + for (uint32_t i = 0; i < opts->entries; i++) { - if (!strcmp(opts->defs->defs[i].name, name)) { - - if (opts->defs->defs[i].type != UTIL_OPTIONS_TYPE_STR) { - log_warn("Option %s is not of type str", name); - return 0; - } - - if (opts->values[i].avail) { - return opts->values[i].value.str; - } else { - return opts->defs->defs[i].default_value.str; - } + switch (opts->defs->defs[i].type) { + case UTIL_OPTIONS_TYPE_STR: { + if (opts->values[i].value.str) { + free(opts->values[i].value.str); } - } - log_warn("Could not find str option %s", name); - return NULL; -} + break; + } -bool util_options_get_bool(const struct util_options_opts* opts, - const char* name) -{ - for (uint32_t i = 0; i < opts->entries; i++) { - - if (!strcmp(opts->defs->defs[i].name, name)) { - - if (opts->defs->defs[i].type != UTIL_OPTIONS_TYPE_BOOL) { - log_warn("Option %s is not of type bool", name); - return false; - } - - if (opts->values[i].avail) { - return opts->values[i].value.b; - } else { - return opts->defs->defs[i].default_value.b; - } + case UTIL_OPTIONS_TYPE_BIN: { + if (opts->values[i].value.bin.data) { + free(opts->values[i].value.bin.data); } + + break; + } + + default: + break; } + } - log_warn("Could not find bool option %s", name); - return false; -} - -const uint8_t* util_options_get_bin(const struct util_options_opts* opts, - const char* name, size_t* length) -{ - for (uint32_t i = 0; i < opts->entries; i++) { - - if (!strcmp(opts->defs->defs[i].name, name)) { - - if (opts->defs->defs[i].type != UTIL_OPTIONS_TYPE_BIN) { - log_warn("Option %s is not of type bin", name); - return 0; - } - - if (opts->values[i].avail) { - if (length) { - *length = opts->values[i].value.bin.len; - } - - return opts->values[i].value.bin.data; - } else { - if (length) { - *length = opts->defs->defs[i].default_value.bin.len; - } - - return opts->defs->defs[i].default_value.bin.data; - } - } - } - - log_warn("Could not find bin option %s", name); - return NULL; -} - -void util_options_print_usage(const struct util_options_defs* option_defs) -{ - printf( - "%s\nSpecify options as arguments or use --options [path file] to " - "specify a config file containing key=value per line entries\n", - option_defs->usage_header); - - for (uint32_t i = 0; i < option_defs->ndefs; i++) { - - switch (option_defs->defs[i].type) { - case UTIL_OPTIONS_TYPE_INT: - { - printf( - " -%c [int] %s: %s\n" - " default: %d\n", - option_defs->defs[i].param, option_defs->defs[i].name, - option_defs->defs[i].description, - option_defs->defs[i].default_value.i); - - break; - } - - case UTIL_OPTIONS_TYPE_DOUBLE: - { - printf( - " -%c [double] %s: %s\n" - " default: %f\n", - option_defs->defs[i].param, option_defs->defs[i].name, - option_defs->defs[i].description, - option_defs->defs[i].default_value.d); - - break; - } - - case UTIL_OPTIONS_TYPE_STR: - { - printf( - " -%c [str] %s: %s\n" - " default: %s\n", - option_defs->defs[i].param, option_defs->defs[i].name, - option_defs->defs[i].description, - option_defs->defs[i].default_value.str); - - break; - } - - case UTIL_OPTIONS_TYPE_BOOL: - { - printf( - " -%c [bool] %s: %s\n" - " default: %d\n", - option_defs->defs[i].param, option_defs->defs[i].name, - option_defs->defs[i].description, - option_defs->defs[i].default_value.b); - - break; - } - - case UTIL_OPTIONS_TYPE_BIN: - { - size_t len = option_defs->defs[i].default_value.bin.len * 2 + 1; - char* buf = util_xmalloc(len); - - util_hex_encode_uc(option_defs->defs[i].default_value.bin.data, - option_defs->defs[i].default_value.bin.len, buf, len); - - printf( - " -%c [bin] %s: %s\n" - " default (len %Iu): %s\n", - option_defs->defs[i].param, option_defs->defs[i].name, - option_defs->defs[i].description, - option_defs->defs[i].default_value.bin.len, - buf); - - free(buf); - - break; - } - - default: - { - printf( - " -%c [unkn] %s: %s\n" - " default: -invalid-\n", - option_defs->defs[i].param, option_defs->defs[i].name, - option_defs->defs[i].description); - - break; - } - } - } -} - -void util_options_free(struct util_options_opts* opts) -{ - for (uint32_t i = 0; i < opts->entries; i++) { - - switch (opts->defs->defs[i].type) { - case UTIL_OPTIONS_TYPE_STR: - { - if (opts->values[i].value.str) { - free(opts->values[i].value.str); - } - - break; - } - - case UTIL_OPTIONS_TYPE_BIN: - { - if (opts->values[i].value.bin.data) { - free(opts->values[i].value.bin.data); - } - - break; - } - - default: - break; - } - } - - free(opts->values); - free(opts); + free(opts->values); + free(opts); } // if NULL, usage is printed -static struct util_options_opts* util_options_get2( - int argc, char** argv, const struct util_options_defs* option_defs) +static struct util_options_opts *util_options_get2( + int argc, char **argv, const struct util_options_defs *option_defs) { - bool success; - char* options_file = NULL; - struct util_options_opts* options = - (struct util_options_opts*) - util_xmalloc(sizeof(struct util_options_opts)); + bool success; + char *options_file = NULL; + struct util_options_opts *options = (struct util_options_opts *) util_xmalloc( + sizeof(struct util_options_opts)); - if (option_defs == NULL) { - options->defs = NULL; - options->values = NULL; - options->entries = 0; + if (option_defs == NULL) { + options->defs = NULL; + options->values = NULL; + options->entries = 0; - return options; - } + return options; + } - options->defs = option_defs; - options->entries = option_defs->ndefs; + options->defs = option_defs; + options->entries = option_defs->ndefs; - options->values = (struct util_options_value*) util_xmalloc( - sizeof(struct util_options_value) * options->entries); + options->values = (struct util_options_value *) util_xmalloc( + sizeof(struct util_options_value) * options->entries); - memset(options->values, 0, - sizeof(struct util_options_value) * options->entries); + memset( + options->values, 0, sizeof(struct util_options_value) * options->entries); - /* detect if we read options from a file */ - for (int i = 0; i < argc; i++) { + /* detect if we read options from a file */ + for (int i = 0; i < argc; i++) { - if (!strcmp(argv[i], "--options")) { + if (!strcmp(argv[i], "--options")) { - if (i + 1 >= argc) { - log_warn("Missing argument for --options\n"); + if (i + 1 >= argc) { + log_warn("Missing argument for --options\n"); - util_options_print_usage(option_defs); - util_options_free(options); - return NULL; - } - - options_file = argv[i + 1]; - break; - } - } - - if (options_file) { - log_debug("Processing options file %s", options_file); - success = util_options_init_from_file(options, option_defs, - options_file); - - if (!success) { - exit(0); - } - } - - log_debug("Processing cmd args"); - success = util_options_init_from_args(options, option_defs, argc, argv); - - if (!success) { util_options_print_usage(option_defs); util_options_free(options); return NULL; - } else { - return options; + } + + options_file = argv[i + 1]; + break; } + } + + if (options_file) { + log_debug("Processing options file %s", options_file); + success = util_options_init_from_file(options, option_defs, options_file); + + if (!success) { + exit(0); + } + } + + log_debug("Processing cmd args"); + success = util_options_init_from_args(options, option_defs, argc, argv); + + if (!success) { + util_options_print_usage(option_defs); + util_options_free(options); + return NULL; + } else { + return options; + } } -static bool util_options_init_from_args(struct util_options_opts* options, - const struct util_options_defs* option_defs, int argc, char** argv) +static bool util_options_init_from_args( + struct util_options_opts *options, + const struct util_options_defs *option_defs, + int argc, + char **argv) { - for (int i = 0; i < argc; i++) { + for (int i = 0; i < argc; i++) { - if (argv[i][0] != '-') { + if (argv[i][0] != '-') { + continue; + } + + for (uint32_t j = 0; j < options->entries; j++) { + /* prints usage */ + if (argv[i][1] == option_defs->usage_param) { + return false; + } + + if (options->defs->defs[j].param == argv[i][1]) { + + switch (options->defs->defs[j].type) { + case UTIL_OPTIONS_TYPE_INT: { + if (i + 1 >= argc) { + break; + } + + ++i; + + options->values[j].value.i = atoi(argv[i]); + + break; + } + + case UTIL_OPTIONS_TYPE_DOUBLE: { + if (i + 1 >= argc) { + break; + } + + ++i; + + options->values[j].value.d = atof(argv[i]); + + break; + } + + case UTIL_OPTIONS_TYPE_STR: { + if (i + 1 >= argc) { + break; + } + + ++i; + + /* FIXME memory leak if overriding string from options + file */ + + if (strlen(argv[i]) > 0) { + options->values[j].value.str = util_str_dup(argv[i]); + } else { + options->values[j].value.str = NULL; + } + + break; + } + + case UTIL_OPTIONS_TYPE_BOOL: { + options->values[j].value.b = true; + + break; + } + + case UTIL_OPTIONS_TYPE_BIN: { + if (i + 1 >= argc) { + break; + } + + ++i; + + /* FIXME memory leak if overriding bin data from options + file */ + + if (strlen(argv[i]) > 0) { + size_t len = strlen(argv[i]); + len = len / 2 + len % 2; + + options->values[j].value.bin.len = len; + options->values[j].value.bin.data = util_xmalloc(len); + + if (!util_hex_decode( + options->values[j].value.bin.data, + options->values[j].value.bin.len, + argv[i], + strlen(argv[i]))) { + log_warn( + "Decoding binary data for key %s " + "failed", + options->defs->defs[j].name); + options->values[j].value.bin.len = 0; + options->values[j].value.bin.data = NULL; + } + } else { + options->values[j].value.bin.len = 0; + options->values[j].value.bin.data = NULL; + } + + break; + } + + default: continue; } - for (uint32_t j = 0; j < options->entries; j++) { - /* prints usage */ - if (argv[i][1] == option_defs->usage_param) { - return false; - } + log_debug( + "Cmd arg: -%c %s (type %d): %s", + options->defs->defs[j].param, + options->defs->defs[j].name, + options->defs->defs[j].type, + argv[i]); - if (options->defs->defs[j].param == argv[i][1]) { - - switch (options->defs->defs[j].type) { - case UTIL_OPTIONS_TYPE_INT: - { - if (i + 1 >= argc) { - break; - } - - ++i; - - options->values[j].value.i = atoi(argv[i]); - - break; - } - - case UTIL_OPTIONS_TYPE_DOUBLE: - { - if (i + 1 >= argc) { - break; - } - - ++i; - - options->values[j].value.d = atof(argv[i]); - - break; - } - - case UTIL_OPTIONS_TYPE_STR: - { - if (i + 1 >= argc) { - break; - } - - ++i; - - /* FIXME memory leak if overriding string from options - file */ - - if (strlen(argv[i]) > 0) { - options->values[j].value.str = util_str_dup(argv[i]); - } else { - options->values[j].value.str = NULL; - } - - break; - } - - case UTIL_OPTIONS_TYPE_BOOL: - { - options->values[j].value.b = true; - - break; - } - - case UTIL_OPTIONS_TYPE_BIN: - { - if (i + 1 >= argc) { - break; - } - - ++i; - - /* FIXME memory leak if overriding bin data from options - file */ - - if (strlen(argv[i]) > 0) { - size_t len = strlen(argv[i]); - len = len / 2 + len % 2; - - options->values[j].value.bin.len = len; - options->values[j].value.bin.data = util_xmalloc(len); - - if (!util_hex_decode(options->values[j].value.bin.data, - options->values[j].value.bin.len, argv[i], - strlen(argv[i]))) { - log_warn("Decoding binary data for key %s " - "failed", options->defs->defs[j].name); - options->values[j].value.bin.len = 0; - options->values[j].value.bin.data = NULL; - } - } else { - options->values[j].value.bin.len = 0; - options->values[j].value.bin.data = NULL; - } - - break; - } - - default: - continue; - } - - log_debug("Cmd arg: -%c %s (type %d): %s", - options->defs->defs[j].param, options->defs->defs[j].name, - options->defs->defs[j].type, argv[i]); - - options->values[j].avail = true; - break; - } - } + options->values[j].avail = true; + break; + } } + } - return true; + return true; } - - -static bool util_options_init_from_file(struct util_options_opts* options, - const struct util_options_defs* option_defs, char* file_path) +static bool util_options_init_from_file( + struct util_options_opts *options, + const struct util_options_defs *option_defs, + char *file_path) { - char* pos_lines; - char* pos_key_val; - char* ctx_lines; - char* ctx_key_val; - char* data; - size_t len; + char *pos_lines; + char *pos_key_val; + char *ctx_lines; + char *ctx_key_val; + char *data; + size_t len; - if (!util_file_load(file_path, (void**) &data, &len, true)) { - /* If file does not exist, create one with default configuration - values */ - if (util_fs_path_exists(file_path)) { - log_warn("Loading options file %s failed, faulty or corrupted " - "configuration", file_path); + if (!util_file_load(file_path, (void **) &data, &len, true)) { + /* If file does not exist, create one with default configuration + values */ + if (util_fs_path_exists(file_path)) { + log_warn( + "Loading options file %s failed, faulty or corrupted " + "configuration", + file_path); + } else { + /* Create a default config file if the usage param is set. This + indicates that we are currently not on the inject process + but already on the inject library. We want all config params + of the inject lib */ + if (option_defs->usage_param) { + log_info( + "Options file %s does not exist, creating default...", file_path); + + if (!util_options_write_default_options_file(option_defs, file_path)) { + log_warn("Creating default options file %s failed", file_path); } else { - /* Create a default config file if the usage param is set. This - indicates that we are currently not on the inject process - but already on the inject library. We want all config params - of the inject lib */ - if (option_defs->usage_param) { - log_info("Options file %s does not exist, creating default...", - file_path); - - if (!util_options_write_default_options_file(option_defs, - file_path)) { - log_warn("Creating default options file %s failed", - file_path); - } else { - log_info("Options file %s created. Tweak it to your needs and restart the game.", - file_path); - } - } + log_info( + "Options file %s created. Tweak it to your needs and restart the " + "game.", + file_path); } + } + } + return false; + } + + pos_lines = strtok_r(data, "\n", &ctx_lines); + + while (pos_lines != NULL) { + char *pos_line_dup; + char *key = NULL; + char *val = NULL; + + /* ignore comments and empty lines */ + if (strlen(pos_lines) > 0 && pos_lines[0] != '#') { + pos_line_dup = util_str_dup(pos_lines); + pos_key_val = strtok_r(pos_line_dup, "=", &ctx_key_val); + + log_debug("Line: %s", pos_lines); + + if (pos_key_val != NULL) { + key = pos_key_val; + val = &pos_key_val[strlen(key) + 1]; + } else { + log_warn( + "Invalid options line %s in options file %s", pos_lines, file_path); + free(pos_line_dup); + free(data); return false; - } + } - pos_lines = strtok_r(data, "\n", &ctx_lines); + log_debug("Key: %s, Value: %s", key, val); - while (pos_lines != NULL) { - char* pos_line_dup; - char* key = NULL; - char* val = NULL; + /* search for key */ + for (uint32_t j = 0; j < options->entries; j++) { - /* ignore comments and empty lines */ - if (strlen(pos_lines) > 0 && pos_lines[0] != '#') { - pos_line_dup = util_str_dup(pos_lines); - pos_key_val = strtok_r(pos_line_dup, "=", &ctx_key_val); + if (!strcmp(options->defs->defs[j].name, key)) { - log_debug("Line: %s", pos_lines); + switch (options->defs->defs[j].type) { + case UTIL_OPTIONS_TYPE_INT: { + if (val) { + options->values[j].value.i = atoi(val); + } else { + options->values[j].value.i = 0; + } - if (pos_key_val != NULL) { - key = pos_key_val; - val = &pos_key_val[strlen(key) + 1]; - } else { - log_warn("Invalid options line %s in options file %s", pos_lines, file_path); - free(pos_line_dup); - free(data); - return false; + break; } - log_debug("Key: %s, Value: %s", key, val); + case UTIL_OPTIONS_TYPE_DOUBLE: { + if (val) { + options->values[j].value.d = atof(val); + } else { + options->values[j].value.d = 0.0; + } - /* search for key */ - for (uint32_t j = 0; j < options->entries; j++) { - - if (!strcmp(options->defs->defs[j].name, key)) { - - switch (options->defs->defs[j].type) { - case UTIL_OPTIONS_TYPE_INT: - { - if (val) { - options->values[j].value.i = atoi(val); - } else { - options->values[j].value.i = 0; - } - - break; - } - - case UTIL_OPTIONS_TYPE_DOUBLE: - { - if (val) { - options->values[j].value.d = atof(val); - } else { - options->values[j].value.d = 0.0; - } - - break; - } - - case UTIL_OPTIONS_TYPE_STR: - { - if (val && strlen(val) > 0) { - options->values[j].value.str = - util_str_dup(val); - } else { - options->values[j].value.str = NULL; - } - - break; - } - - case UTIL_OPTIONS_TYPE_BOOL: - { - if (val) { - if (atoi(val) <= 0) { - options->values[j].value.b = false; - } else { - options->values[j].value.b = true; - } - } else { - options->values[j].value.b = false; - } - - - break; - } - - case UTIL_OPTIONS_TYPE_BIN: - { - if (val && strlen(val) > 0) { - size_t lenBin = strlen(val); - lenBin = lenBin / 2 + lenBin % 2; - - options->values[j].value.bin.len = lenBin; - options->values[j].value.bin.data = - util_xmalloc(lenBin); - - if (!util_hex_decode( - options->values[j].value.bin.data, - options->values[j].value.bin.len, val, - strlen(val))) { - log_warn("Decoding binary data for key " - "%s failed", - options->defs->defs[j].name); - options->values[j].value.bin.len = 0; - options->values[j].value.bin.data = NULL; - } - } else { - options->values[j].value.bin.len = 0; - options->values[j].value.bin.data = NULL; - } - - break; - } - - default: - continue; - } - - log_debug("Options file param: -%c %s (type %d): %s", - options->defs->defs[j].param, - options->defs->defs[j].name, - options->defs->defs[j].type, val ? val : "NULL"); - - options->values[j].avail = true; - break; - } + break; } - free(pos_line_dup); - } + case UTIL_OPTIONS_TYPE_STR: { + if (val && strlen(val) > 0) { + options->values[j].value.str = util_str_dup(val); + } else { + options->values[j].value.str = NULL; + } - pos_lines = strtok_r(NULL, "\n", &ctx_lines); - } - - free(data); - - return true; -} - -static bool util_options_write_default_options_file( - const struct util_options_defs* option_defs, char* file_path) -{ - FILE* file; - - file = fopen(file_path, "wb"); - - if (file == NULL) { - return false; - } - - for (uint32_t i = 0; i < option_defs->ndefs; i++) { - - switch (option_defs->defs[i].type) { - case UTIL_OPTIONS_TYPE_INT: - { - fprintf(file, "# [int]: %s\n", - option_defs->defs[i].description); - fprintf(file, "%s=%d\n\n", option_defs->defs[i].name, - option_defs->defs[i].default_value.i); - - break; + break; } - case UTIL_OPTIONS_TYPE_DOUBLE: - { - fprintf(file, "# [double]: %s\n", - option_defs->defs[i].description); - fprintf(file, "%s=%f\n\n", option_defs->defs[i].name, - option_defs->defs[i].default_value.d); - - break; - } - - case UTIL_OPTIONS_TYPE_STR: - { - fprintf(file, "# [str]: %s\n", - option_defs->defs[i].description); - - if (option_defs->defs[i].default_value.str) { - fprintf(file, "%s=%s\n\n", option_defs->defs[i].name, - option_defs->defs[i].default_value.str); + case UTIL_OPTIONS_TYPE_BOOL: { + if (val) { + if (atoi(val) <= 0) { + options->values[j].value.b = false; } else { - fprintf(file, "%s=\n\n", option_defs->defs[i].name); + options->values[j].value.b = true; } + } else { + options->values[j].value.b = false; + } - break; + break; } - case UTIL_OPTIONS_TYPE_BOOL: - { - fprintf(file, "# [bool (0/1)]: %s\n", - option_defs->defs[i].description); - fprintf(file, "%s=%d\n\n", option_defs->defs[i].name, - option_defs->defs[i].default_value.b); + case UTIL_OPTIONS_TYPE_BIN: { + if (val && strlen(val) > 0) { + size_t lenBin = strlen(val); + lenBin = lenBin / 2 + lenBin % 2; - break; - } + options->values[j].value.bin.len = lenBin; + options->values[j].value.bin.data = util_xmalloc(lenBin); - case UTIL_OPTIONS_TYPE_BIN: - { - fprintf(file, "# [bin]: %s\n", - option_defs->defs[i].description); - - if (option_defs->defs[i].default_value.bin.data) { - size_t len = - option_defs->defs[i].default_value.bin.len * 2 + 1; - char* buf = util_xmalloc(len); - - util_hex_encode_uc( - option_defs->defs[i].default_value.bin.data, - option_defs->defs[i].default_value.bin.len, buf, len); - - - fprintf(file, "%s=%s\n\n", option_defs->defs[i].name, buf); - - free(buf); + if (!util_hex_decode( + options->values[j].value.bin.data, + options->values[j].value.bin.len, + val, + strlen(val))) { + log_warn( + "Decoding binary data for key " + "%s failed", + options->defs->defs[j].name); + options->values[j].value.bin.len = 0; + options->values[j].value.bin.data = NULL; } + } else { + options->values[j].value.bin.len = 0; + options->values[j].value.bin.data = NULL; + } - break; + break; } default: - { - log_warn("Invalid value type %d found", - option_defs->defs[i].type); - break; - } + continue; + } + + log_debug( + "Options file param: -%c %s (type %d): %s", + options->defs->defs[j].param, + options->defs->defs[j].name, + options->defs->defs[j].type, + val ? val : "NULL"); + + options->values[j].avail = true; + break; } + } + + free(pos_line_dup); } - fclose(file); - return true; + pos_lines = strtok_r(NULL, "\n", &ctx_lines); + } + + free(data); + + return true; +} + +static bool util_options_write_default_options_file( + const struct util_options_defs *option_defs, char *file_path) +{ + FILE *file; + + file = fopen(file_path, "wb"); + + if (file == NULL) { + return false; + } + + for (uint32_t i = 0; i < option_defs->ndefs; i++) { + + switch (option_defs->defs[i].type) { + case UTIL_OPTIONS_TYPE_INT: { + fprintf(file, "# [int]: %s\n", option_defs->defs[i].description); + fprintf( + file, + "%s=%d\n\n", + option_defs->defs[i].name, + option_defs->defs[i].default_value.i); + + break; + } + + case UTIL_OPTIONS_TYPE_DOUBLE: { + fprintf(file, "# [double]: %s\n", option_defs->defs[i].description); + fprintf( + file, + "%s=%f\n\n", + option_defs->defs[i].name, + option_defs->defs[i].default_value.d); + + break; + } + + case UTIL_OPTIONS_TYPE_STR: { + fprintf(file, "# [str]: %s\n", option_defs->defs[i].description); + + if (option_defs->defs[i].default_value.str) { + fprintf( + file, + "%s=%s\n\n", + option_defs->defs[i].name, + option_defs->defs[i].default_value.str); + } else { + fprintf(file, "%s=\n\n", option_defs->defs[i].name); + } + + break; + } + + case UTIL_OPTIONS_TYPE_BOOL: { + fprintf(file, "# [bool (0/1)]: %s\n", option_defs->defs[i].description); + fprintf( + file, + "%s=%d\n\n", + option_defs->defs[i].name, + option_defs->defs[i].default_value.b); + + break; + } + + case UTIL_OPTIONS_TYPE_BIN: { + fprintf(file, "# [bin]: %s\n", option_defs->defs[i].description); + + if (option_defs->defs[i].default_value.bin.data) { + size_t len = option_defs->defs[i].default_value.bin.len * 2 + 1; + char *buf = util_xmalloc(len); + + util_hex_encode_uc( + option_defs->defs[i].default_value.bin.data, + option_defs->defs[i].default_value.bin.len, + buf, + len); + + fprintf(file, "%s=%s\n\n", option_defs->defs[i].name, buf); + + free(buf); + } + + break; + } + + default: { + log_warn("Invalid value type %d found", option_defs->defs[i].type); + break; + } + } + } + + fclose(file); + return true; } \ No newline at end of file diff --git a/src/main/util/options.h b/src/main/util/options.h index 6a871c6..24c3aee 100644 --- a/src/main/util/options.h +++ b/src/main/util/options.h @@ -9,11 +9,11 @@ * Value types support by option values */ enum util_options_type { - UTIL_OPTIONS_TYPE_INT, - UTIL_OPTIONS_TYPE_DOUBLE, - UTIL_OPTIONS_TYPE_STR, - UTIL_OPTIONS_TYPE_BOOL, - UTIL_OPTIONS_TYPE_BIN, + UTIL_OPTIONS_TYPE_INT, + UTIL_OPTIONS_TYPE_DOUBLE, + UTIL_OPTIONS_TYPE_STR, + UTIL_OPTIONS_TYPE_BOOL, + UTIL_OPTIONS_TYPE_BIN, }; /** @@ -21,20 +21,20 @@ enum util_options_type { * key-value tuples to parse from an argument list */ struct util_options_def { - const char* name; - const char* description; - const char param; - enum util_options_type type; - union { - int i; - double d; - const char* str; - bool b; - struct { - const uint8_t* data; - size_t len; - } bin; - } default_value; + const char *name; + const char *description; + const char param; + enum util_options_type type; + union { + int i; + double d; + const char *str; + bool b; + struct { + const uint8_t *data; + size_t len; + } bin; + } default_value; }; /** @@ -42,36 +42,36 @@ struct util_options_def { * as well as usage information for the application */ struct util_options_defs { - const char* usage_header; - char usage_param; - const struct util_options_def* defs; - uint32_t ndefs; + const char *usage_header; + char usage_param; + const struct util_options_def *defs; + uint32_t ndefs; }; /** * A single option value as part of the key-value tuple */ struct util_options_value { - bool avail; - union { - int i; - double d; - char* str; - bool b; - struct { - uint8_t* data; - size_t len; - } bin; - } value; + bool avail; + union { + int i; + double d; + char *str; + bool b; + struct { + uint8_t *data; + size_t len; + } bin; + } value; }; /** * Parsed option values based on an options definition */ struct util_options_opts { - const struct util_options_defs* defs; - struct util_options_value* values; - uint32_t entries; + const struct util_options_defs *defs; + struct util_options_value *values; + uint32_t entries; }; /** @@ -83,7 +83,7 @@ struct util_options_opts { * @param argc Argc from main * @param argv Argv from main */ -void util_options_init(int argc, char** argv); +void util_options_init(int argc, char **argv); /** * Get options from the initial argument list @@ -94,8 +94,8 @@ void util_options_init(int argc, char** argv); * @return A list of parsed options based on the specified definitions or * NULL if usage information was printed. */ -struct util_options_opts* util_options_get( - const struct util_options_defs* option_defs); +struct util_options_opts * +util_options_get(const struct util_options_defs *option_defs); /** * Get an integer value from an options list @@ -105,8 +105,8 @@ struct util_options_opts* util_options_get( * @return Value of the options key converted to an integer value. If the type * of the options key is not matching, 0 is returned */ -int util_options_get_int(const struct util_options_opts* opts, - const char* name); +int util_options_get_int( + const struct util_options_opts *opts, const char *name); /** * Get a double value from an options list @@ -116,7 +116,8 @@ int util_options_get_int(const struct util_options_opts* opts, * @return Value of the options key converted to a double value. If the type * of the options key is not matching, 0 is returned */ -double util_options_get_double(const struct util_options_opts* opts, const char* name); +double +util_options_get_double(const struct util_options_opts *opts, const char *name); /** * Get a string from an options list @@ -126,8 +127,8 @@ double util_options_get_double(const struct util_options_opts* opts, const char* * @return Value of the options key converted to a string. If the type * of the options key is not matching, NULL is returned */ -const char* util_options_get_str(const struct util_options_opts* opts, - const char* name); +const char * +util_options_get_str(const struct util_options_opts *opts, const char *name); /** * Get a bool value from an options list @@ -137,8 +138,8 @@ const char* util_options_get_str(const struct util_options_opts* opts, * @return Value of the options key converted to a bool value. If the type * of the options key is not matching, false is returned */ -bool util_options_get_bool(const struct util_options_opts* opts, - const char* name); +bool util_options_get_bool( + const struct util_options_opts *opts, const char *name); /** * Get binary data from an options list @@ -150,21 +151,21 @@ bool util_options_get_bool(const struct util_options_opts* opts, * @return Value of the options key converted to a binary array. If the type * of the options key is not matching, NULL is returned */ -const uint8_t* util_options_get_bin(const struct util_options_opts* opts, - const char* name, size_t* length); +const uint8_t *util_options_get_bin( + const struct util_options_opts *opts, const char *name, size_t *length); /** * Print usage information * * @param option_defs A list of option definitions. */ -void util_options_print_usage(const struct util_options_defs* opts); +void util_options_print_usage(const struct util_options_defs *opts); /** * Free an options list * * @param opts Options list to free */ -void util_options_free(struct util_options_opts* opts); +void util_options_free(struct util_options_opts *opts); #endif diff --git a/src/main/util/patch.c b/src/main/util/patch.c index 61bcb52..91d484b 100644 --- a/src/main/util/patch.c +++ b/src/main/util/patch.c @@ -6,54 +6,61 @@ #include "util/patch.h" /* addr needs to be a multiple of page size */ -#define UNPROTECT(addr,len) mprotect((void*)(addr-(addr%4096)),(addr%4096) + \ - len,PROT_READ|PROT_WRITE|PROT_EXEC) +#define UNPROTECT(addr, len) \ + mprotect( \ + (void *) (addr - (addr % 4096)), \ + (addr % 4096) + len, \ + PROT_READ | PROT_WRITE | PROT_EXEC) -void util_patch_write_memory(uintptr_t mem, const void* data, size_t len) +void util_patch_write_memory(uintptr_t mem, const void *data, size_t len) { - if (UNPROTECT(mem, len) != 0) { - log_die("Unprotecting memory %p, len %d failed", mem, len); - } + if (UNPROTECT(mem, len) != 0) { + log_die("Unprotecting memory %p, len %d failed", mem, len); + } - memcpy((void*) mem, data, len); + memcpy((void *) mem, data, len); } void util_patch_write_memory_byte(uintptr_t mem, uint8_t data) { - util_patch_write_memory(mem, (const void*) &data, sizeof(uint8_t)); + util_patch_write_memory(mem, (const void *) &data, sizeof(uint8_t)); } -void util_patch_function(uintptr_t func_addr, void* detour_func) +void util_patch_function(uintptr_t func_addr, void *detour_func) { - /* uintptr_t is said to be portable (32/64-bit) */ - uint8_t offset = 5; + /* uintptr_t is said to be portable (32/64-bit) */ + uint8_t offset = 5; - /* 64-bit binary */ - if (sizeof(uintptr_t) == 8) { - offset += 4; - } + /* 64-bit binary */ + if (sizeof(uintptr_t) == 8) { + offset += 4; + } - uintptr_t call = - (uintptr_t) (((uintptr_t) detour_func) - func_addr - offset); - - if (UNPROTECT(func_addr, 4096) != 0) { - log_die("Unprotecting memory %p, len %d failed", func_addr); - } + uintptr_t call = (uintptr_t)(((uintptr_t) detour_func) - func_addr - offset); - *((uint8_t*) (func_addr)) = 0xE9; - *((uintptr_t*) (func_addr + 1)) = call; + if (UNPROTECT(func_addr, 4096) != 0) { + log_die("Unprotecting memory %p, len %d failed", func_addr); + } + + *((uint8_t *) (func_addr)) = 0xE9; + *((uintptr_t *) (func_addr + 1)) = call; } -void* util_patch_find_signiture(const uint8_t* sig, uint32_t sig_len, - int32_t sig_offset, void* start_addr, void* end_addr, int32_t alignment) +void *util_patch_find_signiture( + const uint8_t *sig, + uint32_t sig_len, + int32_t sig_offset, + void *start_addr, + void *end_addr, + int32_t alignment) { - size_t pos; - - for (pos = (size_t) start_addr; pos < (size_t) end_addr; pos += alignment) { - if (!memcmp((void*) pos, sig, sig_len)) { - return (void*) (pos + sig_offset); - } - } - - return NULL; + size_t pos; + + for (pos = (size_t) start_addr; pos < (size_t) end_addr; pos += alignment) { + if (!memcmp((void *) pos, sig, sig_len)) { + return (void *) (pos + sig_offset); + } + } + + return NULL; } \ No newline at end of file diff --git a/src/main/util/patch.h b/src/main/util/patch.h index 1bd5249..60bef30 100644 --- a/src/main/util/patch.h +++ b/src/main/util/patch.h @@ -12,7 +12,7 @@ * @param data Pointer to buffer with data to write * @param len Length of data to write */ -void util_patch_write_memory(uintptr_t mem, const void* data, size_t len); +void util_patch_write_memory(uintptr_t mem, const void *data, size_t len); /** * Write a single byte to an arbitrary memory location @@ -30,23 +30,28 @@ void util_patch_write_memory_byte(uintptr_t mem, uint8_t data); * @param func_addr Address of the function/call instruction to replace * @param detour_func Address of your function to detour to */ -void util_patch_function(uintptr_t func_addr, void* detour_func); +void util_patch_function(uintptr_t func_addr, void *detour_func); /** * Scan a memory area limited by a start and end address for a signiture. * * @param sig Buffer with signiture to search for * @param sig_len Length of signiture - * @param sig_offset Offset that gets added to the address where the signiture - * starts (if found) + * @param sig_offset Offset that gets added to the address where the signiture + * starts (if found) * @param start_addr Pointer to the address to start searching at * @param end_addr Pointer to the address to stop searching at - * @param alignment Aligns the search signiture, i.e. search in steps of + * @param alignment Aligns the search signiture, i.e. search in steps of * X bytes - * @return If found, pointer to memory where the signiture was found (first + * @return If found, pointer to memory where the signiture was found (first * occurance) with the signiture offset added, NULL otherwise */ -void* util_patch_find_signiture(const uint8_t* sig, uint32_t sig_len, - int32_t sig_offset, void* start_addr, void* end_addr, int32_t alignment); +void *util_patch_find_signiture( + const uint8_t *sig, + uint32_t sig_len, + int32_t sig_offset, + void *start_addr, + void *end_addr, + int32_t alignment); #endif \ No newline at end of file diff --git a/src/main/util/proc.c b/src/main/util/proc.c index e78ee6e..692832f 100644 --- a/src/main/util/proc.c +++ b/src/main/util/proc.c @@ -9,210 +9,217 @@ #include "util/proc.h" #include "util/str.h" -static char* util_sys_read_entries_from_proc_file(const char* path, int* count_out) +static char * +util_sys_read_entries_from_proc_file(const char *path, int *count_out) { - const char* sep = "\n"; - char* str = util_str_dup(""); - char* tmp; + const char *sep = "\n"; + char *str = util_str_dup(""); + char *tmp; - FILE* cmdline = fopen(path, "rb"); - - if (!cmdline) { - log_error("Opening %s failed: %s", path, strerror(errno)); - return str; - } - - char* arg = 0; - size_t size = 0; - int count = 0; - - while (getdelim(&arg, &size, 0, cmdline) != -1) { - if (strlen(str) > 0) { - tmp = util_str_merge(str, sep); - free(str); - str = tmp; - } - - tmp = util_str_merge(str, arg); - free(str); - str = tmp; - count++; - } - - free(arg); - fclose(cmdline); - - if (count_out) { - *count_out = count; - } + FILE *cmdline = fopen(path, "rb"); + if (!cmdline) { + log_error("Opening %s failed: %s", path, strerror(errno)); return str; + } + + char *arg = 0; + size_t size = 0; + int count = 0; + + while (getdelim(&arg, &size, 0, cmdline) != -1) { + if (strlen(str) > 0) { + tmp = util_str_merge(str, sep); + free(str); + str = tmp; + } + + tmp = util_str_merge(str, arg); + free(str); + str = tmp; + count++; + } + + free(arg); + fclose(cmdline); + + if (count_out) { + *count_out = count; + } + + return str; } static void util_proc_log_current_working_dir() { - char tmp[PATH_MAX]; + char tmp[PATH_MAX]; - if (!getcwd(tmp, sizeof(tmp))) { - log_error("Getting current working directory failed"); - } else { - log_info("Current working directory: %s", tmp); - } + if (!getcwd(tmp, sizeof(tmp))) { + log_error("Getting current working directory failed"); + } else { + log_info("Current working directory: %s", tmp); + } } static void util_proc_log_current_process() { - log_info("PID: %d", getpid()); + log_info("PID: %d", getpid()); } static void util_sys_info_log_path_executable() { - char buffer[PATH_MAX]; + char buffer[PATH_MAX]; - if (!util_proc_get_path_executable(buffer, sizeof(buffer))) { - log_error("Getting path of executable failed"); - } else { - log_info("Executable: %s", buffer); - } + if (!util_proc_get_path_executable(buffer, sizeof(buffer))) { + log_error("Getting path of executable failed"); + } else { + log_info("Executable: %s", buffer); + } } static void util_sys_info_log_user() { - log_info("User: %d", getuid()); + log_info("User: %d", getuid()); } static void util_sys_info_log_running_as_root() { - log_info("Running as root: %d", util_proc_is_running_as_root()); + log_info("Running as root: %d", util_proc_is_running_as_root()); } static void util_sys_info_log_cmd_line_args() { - int count; - char* str = util_sys_read_entries_from_proc_file("/proc/self/cmdline", &count); + int count; + char *str = + util_sys_read_entries_from_proc_file("/proc/self/cmdline", &count); - log_info("Cmd arguments (%d):\n%s", count, str); + log_info("Cmd arguments (%d):\n%s", count, str); - free(str); + free(str); } static void util_sys_info_log_env_vars() { - int count; - char* str = util_sys_read_entries_from_proc_file("/proc/self/environ", &count); + int count; + char *str = + util_sys_read_entries_from_proc_file("/proc/self/environ", &count); - log_info("Environment variables (%d):\n%s", count, str); + log_info("Environment variables (%d):\n%s", count, str); - free(str); + free(str); } bool util_proc_is_running_as_root() { - return getuid() == 0; + return getuid() == 0; } -bool util_proc_get_path_executable(char* buffer, size_t size) +bool util_proc_get_path_executable(char *buffer, size_t size) { - // readlink does not null terminate - memset(buffer, 0, size); + // readlink does not null terminate + memset(buffer, 0, size); - return readlink("/proc/self/exe", buffer, size) != -1; + return readlink("/proc/self/exe", buffer, size) != -1; } -bool util_proc_get_folder_path_executable(char* buffer, size_t size) +bool util_proc_get_folder_path_executable(char *buffer, size_t size) { - if (!util_proc_get_path_executable(buffer, size)) { - return false; - } + if (!util_proc_get_path_executable(buffer, size)) { + return false; + } - size_t pos = strlen(buffer) - 1; + size_t pos = strlen(buffer) - 1; - // If executable in the root folder, keep the single / - while (pos > 0 && buffer[pos] != '/') { - buffer[pos] = '\0'; - pos--; - } + // If executable in the root folder, keep the single / + while (pos > 0 && buffer[pos] != '/') { + buffer[pos] = '\0'; + pos--; + } - // delete / - if (pos > 0) { - buffer[pos] = '\0'; - } + // delete / + if (pos > 0) { + buffer[pos] = '\0'; + } - return true; + return true; } -bool util_proc_get_folder_path_executable_no_ld_linux(char* buffer, size_t size) +bool util_proc_get_folder_path_executable_no_ld_linux(char *buffer, size_t size) { - if (!util_proc_get_path_executable(buffer, size)) { - log_error("Getting executable path failed"); - return false; - } + if (!util_proc_get_path_executable(buffer, size)) { + log_error("Getting executable path failed"); + return false; + } - if (util_str_ends_with(buffer, "ld-linux.so.2")) { - int argc; - char* args = util_sys_read_entries_from_proc_file("/proc/self/cmdline", &argc); + if (util_str_ends_with(buffer, "ld-linux.so.2")) { + int argc; + char *args = + util_sys_read_entries_from_proc_file("/proc/self/cmdline", &argc); - char* tok = strtok(args, "\n"); - bool awaiting_value = false; + char *tok = strtok(args, "\n"); + bool awaiting_value = false; - // Skip first token, ld-linux binary - tok = strtok(NULL, "\n"); + // Skip first token, ld-linux binary + tok = strtok(NULL, "\n"); - while (tok != NULL) { - // Check if the next arg is declaring an option key for ld-linux - if (util_str_starts_with(tok, "--")) { - awaiting_value = 1; - } else if (awaiting_value) { - // Just hit the awaited value for the previously skipped option key - awaiting_value = false; - } else { - // Got executable arg passed to ld-linux - if (strlen(tok) > size) { - free(args); - return false; - } + while (tok != NULL) { + // Check if the next arg is declaring an option key for ld-linux + if (util_str_starts_with(tok, "--")) { + awaiting_value = 1; + } else if (awaiting_value) { + // Just hit the awaited value for the previously skipped option key + awaiting_value = false; + } else { + // Got executable arg passed to ld-linux + if (strlen(tok) > size) { + free(args); + return false; + } - strcpy(buffer, tok); + strcpy(buffer, tok); - // Remove executable name - // If executable in the root folder, keep the single / - size_t pos = strlen(buffer) - 1; - while (pos > 0 && buffer[pos] != '/') { - buffer[pos] = '\0'; - pos--; - } + // Remove executable name + // If executable in the root folder, keep the single / + size_t pos = strlen(buffer) - 1; + while (pos > 0 && buffer[pos] != '/') { + buffer[pos] = '\0'; + pos--; + } - // delete / - if (pos > 0) { - buffer[pos] = '\0'; - } - - free(args); - return true; - } - - tok = strtok(NULL, "\n"); + // delete / + if (pos > 0) { + buffer[pos] = '\0'; } free(args); - return false; - } else { - return util_proc_get_folder_path_executable(buffer, size); - } -} + return true; + } + tok = strtok(NULL, "\n"); + } + + free(args); + return false; + } else { + return util_proc_get_folder_path_executable(buffer, size); + } +} void util_proc_log_info() { - log_info("================================ Current process information ================================"); + log_info( + "================================ Current process information " + "================================"); - util_proc_log_current_process(); - util_sys_info_log_path_executable(); - util_proc_log_current_working_dir(); - util_sys_info_log_user(); - util_sys_info_log_running_as_root(); - util_sys_info_log_cmd_line_args(); - util_sys_info_log_env_vars(); + util_proc_log_current_process(); + util_sys_info_log_path_executable(); + util_proc_log_current_working_dir(); + util_sys_info_log_user(); + util_sys_info_log_running_as_root(); + util_sys_info_log_cmd_line_args(); + util_sys_info_log_env_vars(); - log_info("================================================================================================"); + log_info( + "========================================================================" + "========================"); } \ No newline at end of file diff --git a/src/main/util/proc.h b/src/main/util/proc.h index 601a0b8..e260290 100644 --- a/src/main/util/proc.h +++ b/src/main/util/proc.h @@ -12,32 +12,36 @@ bool util_proc_is_running_as_root(); /** - * Get the full path of the executable of the current process (including the executable name). + * Get the full path of the executable of the current process (including the + * executable name). * * @param buffer Buffer to read the path into. * @param size Size of the buffer * @return True on success, false on failure, e.g. buffer too small. */ -bool util_proc_get_path_executable(char* buffer, size_t size); +bool util_proc_get_path_executable(char *buffer, size_t size); /** - * Get the full path of the folder the executable of the current process is located in. + * Get the full path of the folder the executable of the current process is + * located in. * * @param buffer Buffer to read the path into. * @param size Size of the buffer * @return True on success, false on failure, e.g. buffer too small. */ -bool util_proc_get_folder_path_executable(char* buffer, size_t size); +bool util_proc_get_folder_path_executable(char *buffer, size_t size); /** - * Special version of util_proc_get_folder_path_executable that considers when the process is run explicitly with a - * ld-linux binary. Returns the path of the application's executable and not ld-linux in that case. + * Special version of util_proc_get_folder_path_executable that considers when + * the process is run explicitly with a ld-linux binary. Returns the path of the + * application's executable and not ld-linux in that case. * * @param buffer Buffer to read the path into. * @param size Size of the buffer * @return True on success, false on failure, e.g. buffer too small. */ -bool util_proc_get_folder_path_executable_no_ld_linux(char* buffer, size_t size); +bool util_proc_get_folder_path_executable_no_ld_linux( + char *buffer, size_t size); /** * Log information about the current process to the console. diff --git a/src/main/util/rand.c b/src/main/util/rand.c index cbd365d..589bc34 100644 --- a/src/main/util/rand.c +++ b/src/main/util/rand.c @@ -1,5 +1,5 @@ -#include #include +#include #include "rand.h" @@ -7,28 +7,28 @@ static int _util_rand_init = 0; static void _util_rand_initialize() { - if (!_util_rand_init) { - _util_rand_init = 1; - srand((unsigned int) time(NULL)); - } + if (!_util_rand_init) { + _util_rand_init = 1; + srand((unsigned int) time(NULL)); + } } uint32_t util_rand_gen_32() { - _util_rand_initialize(); + _util_rand_initialize(); - return (uint32_t) rand(); + return (uint32_t) rand(); } uint64_t util_rand_gen_64() { - uint64_t value; + uint64_t value; - _util_rand_initialize(); + _util_rand_initialize(); - value = 0; - value |= (((uint64_t) rand()) << 32); - value |= ((uint64_t) rand()); + value = 0; + value |= (((uint64_t) rand()) << 32); + value |= ((uint64_t) rand()); - return value; + return value; } \ No newline at end of file diff --git a/src/main/util/sock-tcp.c b/src/main/util/sock-tcp.c index 655146e..2a0369e 100644 --- a/src/main/util/sock-tcp.c +++ b/src/main/util/sock-tcp.c @@ -6,180 +6,187 @@ #include #include -#include "util/net.h" #include "util/log.h" +#include "util/net.h" #include "util/sock-tcp.h" -bool util_sock_tcp_is_connectable(const char* ipv4, uint32_t timeout_ms) +bool util_sock_tcp_is_connectable(const char *ipv4, uint32_t timeout_ms) { - char* address; - uint16_t port; + char *address; + uint16_t port; - util_net_split_ipv4_str(ipv4, &address, &port); + util_net_split_ipv4_str(ipv4, &address, &port); - bool res = util_sock_tcp_is_connectable2(address, port, timeout_ms); + bool res = util_sock_tcp_is_connectable2(address, port, timeout_ms); - free(address); - return res; + free(address); + return res; } -bool util_sock_tcp_is_connectable2(const char* ipv4, uint16_t port, uint32_t timeout_ms) +bool util_sock_tcp_is_connectable2( + const char *ipv4, uint16_t port, uint32_t timeout_ms) { - struct sockaddr_in sa; + struct sockaddr_in sa; - // store this IP address in sa: - inet_pton(AF_INET, ipv4, &(sa.sin_addr)); + // store this IP address in sa: + inet_pton(AF_INET, ipv4, &(sa.sin_addr)); - return util_sock_tcp_is_connectable3(htonl(sa.sin_addr.s_addr), port, timeout_ms); + return util_sock_tcp_is_connectable3( + htonl(sa.sin_addr.s_addr), port, timeout_ms); } -bool util_sock_tcp_is_connectable3(uint32_t ipv4, uint16_t port, uint32_t timeout_ms) +bool util_sock_tcp_is_connectable3( + uint32_t ipv4, uint16_t port, uint32_t timeout_ms) { - int handle; - struct sockaddr_in addr; - fd_set fdset; - struct timeval tv; - bool res; + int handle; + struct sockaddr_in addr; + fd_set fdset; + struct timeval tv; + bool res; - handle = socket(AF_INET, SOCK_STREAM, 0); + handle = socket(AF_INET, SOCK_STREAM, 0); - if (handle == -1) { - log_error("Creating socket (%X, %d) failed: %s", ipv4, port, strerror(errno)); - return false; - } + if (handle == -1) { + log_error( + "Creating socket (%X, %d) failed: %s", ipv4, port, strerror(errno)); + return false; + } - fcntl(handle, F_SETFL, O_NONBLOCK); + fcntl(handle, F_SETFL, O_NONBLOCK); - memset(&addr, 0, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = htonl(ipv4); + memset(&addr, 0, sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = htonl(ipv4); - connect(handle, (const struct sockaddr*) &addr, sizeof(addr)); + connect(handle, (const struct sockaddr *) &addr, sizeof(addr)); - FD_ZERO(&fdset); - FD_SET(handle, &fdset); - tv.tv_sec = (__time_t) (timeout_ms / 1000); - tv.tv_usec = (__suseconds_t) ((timeout_ms % 1000) * 1000); + FD_ZERO(&fdset); + FD_SET(handle, &fdset); + tv.tv_sec = (__time_t)(timeout_ms / 1000); + tv.tv_usec = (__suseconds_t)((timeout_ms % 1000) * 1000); - if (select(handle + 1, NULL, &fdset, NULL, &tv) == 1) { - int so_error; - socklen_t len = sizeof(so_error); + if (select(handle + 1, NULL, &fdset, NULL, &tv) == 1) { + int so_error; + socklen_t len = sizeof(so_error); - getsockopt(handle, SOL_SOCKET, SO_ERROR, &so_error, &len); + getsockopt(handle, SOL_SOCKET, SO_ERROR, &so_error, &len); - if (so_error == 0) { - res = true; - } else { - res = false; - } + if (so_error == 0) { + res = true; } else { - res = false; + res = false; } + } else { + res = false; + } - close(handle); + close(handle); - return res; + return res; } -int util_sock_tcp_connect(const char* ipv4) +int util_sock_tcp_connect(const char *ipv4) { - char* address; - uint16_t port; + char *address; + uint16_t port; - util_net_split_ipv4_str(ipv4, &address, &port); + util_net_split_ipv4_str(ipv4, &address, &port); - int res = util_sock_tcp_connect2(address, port); + int res = util_sock_tcp_connect2(address, port); - free(address); - return res; + free(address); + return res; } -int util_sock_tcp_connect2(const char* ipv4, uint16_t port) +int util_sock_tcp_connect2(const char *ipv4, uint16_t port) { - struct sockaddr_in sa; + struct sockaddr_in sa; - // store this IP address in sa: - inet_pton(AF_INET, ipv4, &(sa.sin_addr)); + // store this IP address in sa: + inet_pton(AF_INET, ipv4, &(sa.sin_addr)); - return util_sock_tcp_connect3(htonl(sa.sin_addr.s_addr), port); + return util_sock_tcp_connect3(htonl(sa.sin_addr.s_addr), port); } int util_sock_tcp_connect3(uint32_t ipv4, uint16_t port) { - int handle; - struct sockaddr_in addr; + int handle; + struct sockaddr_in addr; - handle = socket(AF_INET, SOCK_STREAM, 0); + handle = socket(AF_INET, SOCK_STREAM, 0); - if (handle == -1) { - log_error("Creating socket (%X, %d) failed: %s", ipv4, port, strerror(errno)); - return -1; - } + if (handle == -1) { + log_error( + "Creating socket (%X, %d) failed: %s", ipv4, port, strerror(errno)); + return -1; + } - memset(&addr, 0, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = htonl(ipv4); + memset(&addr, 0, sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = htonl(ipv4); - if (connect(handle, (const struct sockaddr*) &addr, sizeof(addr)) == -1) { - close(handle); - log_error("Connecting to %X, %d failed: %s", ipv4, port, strerror(errno)); - return -1; - } + if (connect(handle, (const struct sockaddr *) &addr, sizeof(addr)) == -1) { + close(handle); + log_error("Connecting to %X, %d failed: %s", ipv4, port, strerror(errno)); + return -1; + } - log_debug("Connected to %X on port %d", ipv4, port); + log_debug("Connected to %X on port %d", ipv4, port); - return handle; + return handle; } -ssize_t util_sock_tcp_send(int handle, void* buffer, size_t size, uint32_t timeout_ms) +ssize_t +util_sock_tcp_send(int handle, void *buffer, size_t size, uint32_t timeout_ms) { - struct timeval tv; - tv.tv_sec = (__time_t) (timeout_ms / 1000); - tv.tv_usec = (__suseconds_t) ((timeout_ms % 1000) * 1000); + struct timeval tv; + tv.tv_sec = (__time_t)(timeout_ms / 1000); + tv.tv_usec = (__suseconds_t)((timeout_ms % 1000) * 1000); - setsockopt(handle, SOL_SOCKET, SO_SNDTIMEO, (const char*) &tv, sizeof(tv)); + setsockopt(handle, SOL_SOCKET, SO_SNDTIMEO, (const char *) &tv, sizeof(tv)); - ssize_t length = send(handle, buffer, size, 0); + ssize_t length = send(handle, buffer, size, 0); - if (length < 0) { - // same as EWOULDBLOCK - if (errno == EAGAIN) { - // no data for non blocking - return 0; - } - - return -1; + if (length < 0) { + // same as EWOULDBLOCK + if (errno == EAGAIN) { + // no data for non blocking + return 0; } - return length; + return -1; + } + + return length; } -ssize_t util_sock_tcp_recv(int handle, void* buffer, size_t size, uint32_t timeout_ms) +ssize_t +util_sock_tcp_recv(int handle, void *buffer, size_t size, uint32_t timeout_ms) { - struct timeval tv; - tv.tv_sec = (__time_t) (timeout_ms / 1000); - tv.tv_usec = (__suseconds_t) ((timeout_ms % 1000) * 1000); + struct timeval tv; + tv.tv_sec = (__time_t)(timeout_ms / 1000); + tv.tv_usec = (__suseconds_t)((timeout_ms % 1000) * 1000); - setsockopt(handle, SOL_SOCKET, SO_RCVTIMEO, (const char*) &tv, sizeof(tv)); + setsockopt(handle, SOL_SOCKET, SO_RCVTIMEO, (const char *) &tv, sizeof(tv)); - ssize_t length = recv(handle, buffer, size, 0); + ssize_t length = recv(handle, buffer, size, 0); - if (length < 0) { - // same as EWOULDBLOCK - if (errno == EAGAIN) { - // no data for non blocking - return 0; - } - - return -1; + if (length < 0) { + // same as EWOULDBLOCK + if (errno == EAGAIN) { + // no data for non blocking + return 0; } - return length; + return -1; + } + + return length; } void util_sock_tcp_close(int handle) { - close(handle); + close(handle); } \ No newline at end of file diff --git a/src/main/util/sock-tcp.h b/src/main/util/sock-tcp.h index 67134de..faa2be7 100644 --- a/src/main/util/sock-tcp.h +++ b/src/main/util/sock-tcp.h @@ -9,21 +9,25 @@ #include #include -bool util_sock_tcp_is_connectable(const char* ipv4, uint32_t timeout_ms); +bool util_sock_tcp_is_connectable(const char *ipv4, uint32_t timeout_ms); -bool util_sock_tcp_is_connectable2(const char* ipv4, uint16_t port, uint32_t timeout_ms); +bool util_sock_tcp_is_connectable2( + const char *ipv4, uint16_t port, uint32_t timeout_ms); -bool util_sock_tcp_is_connectable3(uint32_t ipv4, uint16_t port, uint32_t timeout_ms); +bool util_sock_tcp_is_connectable3( + uint32_t ipv4, uint16_t port, uint32_t timeout_ms); -int util_sock_tcp_connect(const char* ipv4); +int util_sock_tcp_connect(const char *ipv4); -int util_sock_tcp_connect2(const char* ipv4, uint16_t port); +int util_sock_tcp_connect2(const char *ipv4, uint16_t port); int util_sock_tcp_connect3(uint32_t ipv4, uint16_t port); -ssize_t util_sock_tcp_send(int handle, void* buffer, size_t size, uint32_t timeout_ms); +ssize_t +util_sock_tcp_send(int handle, void *buffer, size_t size, uint32_t timeout_ms); -ssize_t util_sock_tcp_recv(int handle, void* buffer, size_t size, uint32_t timeout_ms); +ssize_t +util_sock_tcp_recv(int handle, void *buffer, size_t size, uint32_t timeout_ms); void util_sock_tcp_close(int handle); diff --git a/src/main/util/str.c b/src/main/util/str.c index 6e2c1ce..d7bf6bd 100644 --- a/src/main/util/str.c +++ b/src/main/util/str.c @@ -8,205 +8,205 @@ #include "util/mem.h" #include "util/str.h" -bool util_str_starts_with(const char* haystack, const char* needle) +bool util_str_starts_with(const char *haystack, const char *needle) { - size_t haystack_len; - size_t needle_len; + size_t haystack_len; + size_t needle_len; - haystack_len = strlen(haystack); - needle_len = strlen(needle); + haystack_len = strlen(haystack); + needle_len = strlen(needle); - if (needle_len > haystack_len) { - return false; + if (needle_len > haystack_len) { + return false; + } + + return !memcmp(haystack, needle, needle_len); +} + +bool util_str_ends_with(const char *haystack, const char *needle) +{ + size_t haystack_len; + size_t needle_len; + + haystack_len = strlen(haystack); + needle_len = strlen(needle); + + if (needle_len > haystack_len) { + return false; + } + + return !memcmp(&haystack[haystack_len - needle_len], needle, needle_len); +} + +size_t util_str_format(char *buf, size_t nchars, const char *fmt, ...) +{ + va_list ap; + size_t result; + + va_start(ap, fmt); + result = util_str_vformat(buf, nchars, fmt, ap); + va_end(ap); + + return result; +} + +size_t util_str_vformat(char *buf, size_t nchars, const char *fmt, va_list ap) +{ + int result; + + result = vsnprintf(buf, nchars, fmt, ap); + + if (result >= (int) nchars || result < 0) { + abort(); + } + + return (size_t) result; +} + +void util_str_cat(char *dest, size_t dnchars, const char *src) +{ + size_t dlen; + size_t slen; + + dlen = strlen(dest); + slen = strlen(src); + + if (dlen + slen >= dnchars) { + abort(); + } + + memcpy(dest + dlen, src, (slen + 1) * sizeof(char)); +} + +void util_str_cpy(char *dest, size_t dnchars, const char *src) +{ + size_t slen; + + slen = strlen(src); + + if (slen >= dnchars) { + abort(); + } + + memcpy(dest, src, (slen + 1) * sizeof(char)); +} + +char *util_str_merge(const char *str1, const char *str2) +{ + char *out; + size_t str1_len; + size_t str2_len; + size_t total; + + str1_len = strlen(str1); + str2_len = strlen(str2); + total = str1_len + str2_len + 1; + + out = util_xmalloc(total); + memcpy(out, str1, str1_len); + memcpy(out + str1_len, str2, str2_len); + out[total - 1] = '\0'; + + return out; +} + +char *util_str_dup(const char *str) +{ + char *dest; + size_t nbytes; + + log_assert(str); + + nbytes = strlen(str) + 1; + dest = util_xmalloc(nbytes); + memcpy(dest, str, nbytes); + + return dest; +} + +void util_str_trim(char *str) +{ + char *pos; + + for (pos = str + strlen(str) - 1; pos > str; pos--) { + if (!isspace(*pos)) { + return; } - return !memcmp(haystack, needle, needle_len); + *pos = '\0'; + } } -bool util_str_ends_with(const char* haystack, const char* needle) +char *util_str_buffer(const uint8_t *buf, size_t len) { - size_t haystack_len; - size_t needle_len; + char *ret; + size_t pos; - haystack_len = strlen(haystack); - needle_len = strlen(needle); + pos = 0; + ret = util_xmalloc(len * 3 + 1); - if (needle_len > haystack_len) { - return false; - } + for (size_t i = 0; i < len; i++) { + uint8_t tmp = buf[i]; - return !memcmp(&haystack[haystack_len - needle_len], needle, needle_len); + pos += sprintf(ret + pos, "%02X ", tmp); + } + + ret[len * 3] = '\0'; + + return ret; } -size_t util_str_format(char* buf, size_t nchars, const char* fmt, ...) +char **util_str_split(const char *str, const char *delim, size_t *count) { - va_list ap; - size_t result; + char **toks; + char *copy; + char *cur; + size_t counter; - va_start(ap, fmt); - result = util_str_vformat(buf, nchars, fmt, ap); - va_end(ap); + log_assert(str); + log_assert(delim); + log_assert(count); - return result; + *count = 0; + + copy = util_str_dup(str); + cur = strtok(copy, delim); + + // First iteration, just count items + while (cur != NULL) { + (*count)++; + cur = strtok(NULL, delim); + } + + util_xfree((void **) ©); + + toks = util_xmalloc(sizeof(char *) * (*count)); + + copy = util_str_dup(str); + cur = strtok(copy, delim); + + counter = 0; + + // Second iteration, grab tokens + while (cur != NULL) { + toks[counter] = util_str_dup(cur); + counter++; + + cur = strtok(NULL, delim); + } + + util_xfree((void **) ©); + + return toks; } -size_t util_str_vformat(char* buf, size_t nchars, const char* fmt, va_list ap) +void util_str_free_split(char **split, size_t count) { - int result; + log_assert(split); - result = vsnprintf(buf, nchars, fmt, ap); + for (int i = 0; i < count; i++) { + util_xfree((void **) &split[i]); + } - if (result >= (int) nchars || result < 0) { - abort(); - } - - return (size_t) result; -} - -void util_str_cat(char* dest, size_t dnchars, const char* src) -{ - size_t dlen; - size_t slen; - - dlen = strlen(dest); - slen = strlen(src); - - if (dlen + slen >= dnchars) { - abort(); - } - - memcpy(dest + dlen, src, (slen + 1) * sizeof(char)); -} - -void util_str_cpy(char* dest, size_t dnchars, const char* src) -{ - size_t slen; - - slen = strlen(src); - - if (slen >= dnchars) { - abort(); - } - - memcpy(dest, src, (slen + 1) * sizeof(char)); -} - -char* util_str_merge(const char* str1, const char* str2) -{ - char* out; - size_t str1_len; - size_t str2_len; - size_t total; - - str1_len = strlen(str1); - str2_len = strlen(str2); - total = str1_len + str2_len + 1; - - out = util_xmalloc(total); - memcpy(out, str1, str1_len); - memcpy(out + str1_len, str2, str2_len); - out[total - 1] = '\0'; - - return out; -} - -char* util_str_dup(const char* str) -{ - char *dest; - size_t nbytes; - - log_assert(str); - - nbytes = strlen(str) + 1; - dest = util_xmalloc(nbytes); - memcpy(dest, str, nbytes); - - return dest; -} - -void util_str_trim(char* str) -{ - char *pos; - - for (pos = str + strlen(str) - 1 ; pos > str ; pos--) { - if (!isspace(*pos)) { - return; - } - - *pos = '\0'; - } -} - -char* util_str_buffer(const uint8_t* buf, size_t len) -{ - char* ret; - size_t pos; - - pos = 0; - ret = util_xmalloc(len * 3 + 1); - - for (size_t i = 0; i < len; i++) { - uint8_t tmp = buf[i]; - - pos += sprintf(ret + pos, "%02X ", tmp); - } - - ret[len * 3] = '\0'; - - return ret; -} - -char** util_str_split(const char* str, const char* delim, size_t* count) -{ - char** toks; - char* copy; - char* cur; - size_t counter; - - log_assert(str); - log_assert(delim); - log_assert(count); - - *count = 0; - - copy = util_str_dup(str); - cur = strtok(copy, delim); - - // First iteration, just count items - while (cur != NULL) { - (*count)++; - cur = strtok(NULL, delim); - } - - util_xfree((void**) ©); - - toks = util_xmalloc(sizeof(char*) * (*count)); - - copy = util_str_dup(str); - cur = strtok(copy, delim); - - counter = 0; - - // Second iteration, grab tokens - while (cur != NULL) { - toks[counter] = util_str_dup(cur); - counter++; - - cur = strtok(NULL, delim); - } - - util_xfree((void**) ©); - - return toks; -} - -void util_str_free_split(char** split, size_t count) -{ - log_assert(split); - - for (int i = 0; i < count; i++) { - util_xfree((void**) &split[i]); - } - - util_xfree((void**) &split); + util_xfree((void **) &split); } \ No newline at end of file diff --git a/src/main/util/str.h b/src/main/util/str.h index 7720d5a..5c91472 100644 --- a/src/main/util/str.h +++ b/src/main/util/str.h @@ -2,8 +2,8 @@ #define UTIL_STR_H #include -#include #include +#include #include /** @@ -13,7 +13,7 @@ * @param needle String to compare with start of haystack * @return True if haystack ends with needle, false otherwise */ -bool util_str_starts_with(const char* haystack, const char* needle); +bool util_str_starts_with(const char *haystack, const char *needle); /** * Check if a string ends with a specific (sub-) string @@ -22,7 +22,7 @@ bool util_str_starts_with(const char* haystack, const char* needle); * @param needle String to compare with end of haystack * @return True if haystack ends with needle, false otherwise */ -bool util_str_ends_with(const char* haystack, const char* needle); +bool util_str_ends_with(const char *haystack, const char *needle); /** * Print a formated string to a buffer @@ -33,7 +33,7 @@ bool util_str_ends_with(const char* haystack, const char* needle); * @param ... Arguments for the format string * @return Size of the string printed to the buffer */ -size_t util_str_format(char* buf, size_t nchars, const char* fmt, ...); +size_t util_str_format(char *buf, size_t nchars, const char *fmt, ...); /** * Print a formated string to a buffer @@ -44,7 +44,7 @@ size_t util_str_format(char* buf, size_t nchars, const char* fmt, ...); * @param ap Argument list for format * @return Size of the string printed to the buffer */ -size_t util_str_vformat(char* buf, size_t nchars, const char* fmt, va_list ap); +size_t util_str_vformat(char *buf, size_t nchars, const char *fmt, va_list ap); /** * Concat a string to another one @@ -53,7 +53,7 @@ size_t util_str_vformat(char* buf, size_t nchars, const char* fmt, va_list ap); * @param dnchars Size of dest buffer * @param src Source string to concat to dest */ -void util_str_cat(char* dest, size_t dnchars, const char* src); +void util_str_cat(char *dest, size_t dnchars, const char *src); /** * Copy a string @@ -62,7 +62,7 @@ void util_str_cat(char* dest, size_t dnchars, const char* src); * @param dnchars Size of destination * @param src Source string to copy from (to dest) */ -void util_str_cpy(char* dest, size_t dnchars, const char* src); +void util_str_cpy(char *dest, size_t dnchars, const char *src); /** * Merge to strings (str1 + str2) @@ -72,7 +72,7 @@ void util_str_cpy(char* dest, size_t dnchars, const char* src); * @return Newly allocated merged string: str1 + str2. Caller has to manage * memory returned */ -char* util_str_merge(const char* str1, const char* str2); +char *util_str_merge(const char *str1, const char *str2); /** * Duplicate a string @@ -81,14 +81,14 @@ char* util_str_merge(const char* str1, const char* str2); * @return Duplicated string (newly allocated memory). Caller has to manage * memory returned */ -char* util_str_dup(const char* src); +char *util_str_dup(const char *src); /** * Remove trailing spaces of a string * * @param str String to trim */ -void util_str_trim(char* str); +void util_str_trim(char *str); /** * Print a buffer as hex digits to a string @@ -98,10 +98,10 @@ void util_str_trim(char* str); * @return String representation of the buffer. Caller has to manage returned * memory */ -char* util_str_buffer(const uint8_t* buf, size_t len); +char *util_str_buffer(const uint8_t *buf, size_t len); -char** util_str_split(const char* str, const char* delim, size_t* count); +char **util_str_split(const char *str, const char *delim, size_t *count); -void util_str_free_split(char** split, size_t count); +void util_str_free_split(char **split, size_t count); #endif diff --git a/src/main/util/sys-info.c b/src/main/util/sys-info.c index 32715c1..1f953fe 100644 --- a/src/main/util/sys-info.c +++ b/src/main/util/sys-info.c @@ -6,17 +6,23 @@ static void util_sys_info_log_kernel() { - struct utsname buf; + struct utsname buf; - if (uname(&buf)) { - log_error("Reading kernel version failed"); - return; - } + if (uname(&buf)) { + log_error("Reading kernel version failed"); + return; + } - log_info("%s|%s|%s|%s|%s", buf.sysname, buf.nodename, buf.release, buf.version, buf.machine); + log_info( + "%s|%s|%s|%s|%s", + buf.sysname, + buf.nodename, + buf.release, + buf.version, + buf.machine); } void util_sys_info_log() { - util_sys_info_log_kernel(); + util_sys_info_log_kernel(); } diff --git a/src/main/util/test.c b/src/main/util/test.c index abfb6c1..c393b6a 100644 --- a/src/main/util/test.c +++ b/src/main/util/test.c @@ -5,13 +5,13 @@ #include "list.h" #include "log.h" #include "mem.h" -#include "test.h" #include "str.h" +#include "test.h" struct util_test_case { - struct util_list_node head; - char* name; - util_test_func_t func; + struct util_list_node head; + char *name; + util_test_func_t func; }; static size_t util_test_count; @@ -19,141 +19,201 @@ static struct util_list util_test_list; void util_test_init() { - util_test_count = 0; - util_list_init(&util_test_list); + util_test_count = 0; + util_list_init(&util_test_list); - log_info("Initialized"); + log_info("Initialized"); } -void util_test_add(const char* name, util_test_func_t func) +void util_test_add(const char *name, util_test_func_t func) { - struct util_test_case* test; + struct util_test_case *test; - test = util_xmalloc(sizeof(struct util_test_case)); + test = util_xmalloc(sizeof(struct util_test_case)); - test->name = util_str_dup(name); - test->func = func; + test->name = util_str_dup(name); + test->func = func; - util_list_append(&util_test_list, &test->head); - util_test_count++; + util_list_append(&util_test_list, &test->head); + util_test_count++; - log_info("Added %s, func %p", name, func); + log_info("Added %s, func %p", name, func); } void util_test_exec() { - log_info("Exec %d tests", util_test_count); + log_info("Exec %d tests", util_test_count); - struct util_list_node* pos; - struct util_test_case* test; - size_t counter = 1; + struct util_list_node *pos; + struct util_test_case *test; + size_t counter = 1; - for (pos = util_test_list.head; pos != NULL; pos = pos->next) { - test = containerof(pos, struct util_test_case, head); + for (pos = util_test_list.head; pos != NULL; pos = pos->next) { + test = containerof(pos, struct util_test_case, head); - log_debug("%d/%d Executing %s...", counter++, util_test_count, test->name); + log_debug("%d/%d Executing %s...", counter++, util_test_count, test->name); - if (!test->func()) { - log_error("%s failed", test->name); - return; - } + if (!test->func()) { + log_error("%s failed", test->name); + return; } + } - log_info("All tests passed"); + log_info("All tests passed"); } void util_test_shutdown() { - log_info("Shutdown"); + log_info("Shutdown"); - struct util_list_node* pos; - struct util_test_case* test; + struct util_list_node *pos; + struct util_test_case *test; - // TODO list elems cleanup? + // TODO list elems cleanup? - for (pos = util_test_list.head; pos != NULL; pos = pos->next) { - test = containerof(pos, struct util_test_case, head); + for (pos = util_test_list.head; pos != NULL; pos = pos->next) { + test = containerof(pos, struct util_test_case, head); - free(test->name); - } + free(test->name); + } } -bool util_test_assert_exp(bool exp, const char* exp_str, const char* file, size_t line_num) +bool util_test_assert_exp( + bool exp, const char *exp_str, const char *file, size_t line_num) { - if (!exp) { - log_error("Assert failed [%s:%d]: Expression %s failed", file, line_num, exp_str); - return false; - } else { - log_debug("Assert successful [%s:%d]: Expression %s", file, line_num, exp_str); - return true; - } + if (!exp) { + log_error( + "Assert failed [%s:%d]: Expression %s failed", file, line_num, exp_str); + return false; + } else { + log_debug( + "Assert successful [%s:%d]: Expression %s", file, line_num, exp_str); + return true; + } } -bool util_test_assert_uint(size_t val_exp, size_t val_actual, const char* exp, const char* actual, const char* file, - size_t line_num) +bool util_test_assert_uint( + size_t val_exp, + size_t val_actual, + const char *exp, + const char *actual, + const char *file, + size_t line_num) { - if (val_exp != val_actual) { - log_error("Assert failed [%s:%d]: %d != %d of expected %s and actual %s", file, line_num, val_exp, val_actual, - exp, actual); - return false; - } else { - log_debug("Assert successful [%s:%d]: %d == %d of expected %s and actual %s", file, line_num, val_exp, - val_actual, exp, actual); - return true; - } + if (val_exp != val_actual) { + log_error( + "Assert failed [%s:%d]: %d != %d of expected %s and actual %s", + file, + line_num, + val_exp, + val_actual, + exp, + actual); + return false; + } else { + log_debug( + "Assert successful [%s:%d]: %d == %d of expected %s and actual %s", + file, + line_num, + val_exp, + val_actual, + exp, + actual); + return true; + } } -bool util_test_assert_str(const char* val_exp, const char* val_actual, const char* exp, const char* actual, - const char* file, size_t line_num) +bool util_test_assert_str( + const char *val_exp, + const char *val_actual, + const char *exp, + const char *actual, + const char *file, + size_t line_num) { - if (strcmp(val_exp, val_actual) != 0) { - log_error("Assert failed [%s:%d]: %s != %s of expected %s and actual %s", file, line_num, val_exp, val_actual, - exp, actual); - return false; - } else { - log_debug("Assert successful [%s:%d]: %s == %s of expected %s and actual %s", file, line_num, val_exp, - val_actual, exp, actual); - return true; - } + if (strcmp(val_exp, val_actual) != 0) { + log_error( + "Assert failed [%s:%d]: %s != %s of expected %s and actual %s", + file, + line_num, + val_exp, + val_actual, + exp, + actual); + return false; + } else { + log_debug( + "Assert successful [%s:%d]: %s == %s of expected %s and actual %s", + file, + line_num, + val_exp, + val_actual, + exp, + actual); + return true; + } } -bool util_test_assert_data(const void* data_exp, const void* data_actual, size_t len, const char* exp, - const char* actual, const char* file, size_t line_num) +bool util_test_assert_data( + const void *data_exp, + const void *data_actual, + size_t len, + const char *exp, + const char *actual, + const char *file, + size_t line_num) { - bool ret; - char* data_exp_str = util_str_buffer(data_exp, len); - char* data_actual_str = util_str_buffer(data_actual, len); + bool ret; + char *data_exp_str = util_str_buffer(data_exp, len); + char *data_actual_str = util_str_buffer(data_actual, len); - if (memcmp(data_exp, data_actual, len) != 0) { - log_error("Assert failed [%s:%d]: %s != %s of expected %s and actual %s", file, line_num, data_exp_str, - data_actual_str, exp, actual); + if (memcmp(data_exp, data_actual, len) != 0) { + log_error( + "Assert failed [%s:%d]: %s != %s of expected %s and actual %s", + file, + line_num, + data_exp_str, + data_actual_str, + exp, + actual); - uint32_t cnt = 0; + uint32_t cnt = 0; - for (size_t i = 0; i < len; i++) { - /* print the first 5 diffs, only */ - if (((const uint8_t*) data_exp)[i] != ((const uint8_t*) data_actual)[i]) { - if (cnt < 5) { - log_error("pos %d: %x != %x", i, ((const uint8_t*) data_exp)[i], ((const uint8_t*) data_actual)[i]); - } - - cnt++; - } + for (size_t i = 0; i < len; i++) { + /* print the first 5 diffs, only */ + if (((const uint8_t *) data_exp)[i] != + ((const uint8_t *) data_actual)[i]) { + if (cnt < 5) { + log_error( + "pos %d: %x != %x", + i, + ((const uint8_t *) data_exp)[i], + ((const uint8_t *) data_actual)[i]); } - if (cnt > 5) { - log_error("...and more different bytes, total diffs %d", cnt); - } - - ret = false; - } else { - log_debug("Assert successful [%s:%d]: %s == %s of expected %s and actual %s", file, line_num, data_exp_str, - data_actual_str, exp, actual); - ret = true; + cnt++; + } } - free(data_exp_str); - free(data_actual_str); + if (cnt > 5) { + log_error("...and more different bytes, total diffs %d", cnt); + } - return ret; + ret = false; + } else { + log_debug( + "Assert successful [%s:%d]: %s == %s of expected %s and actual %s", + file, + line_num, + data_exp_str, + data_actual_str, + exp, + actual); + ret = true; + } + + free(data_exp_str); + free(data_actual_str); + + return ret; } \ No newline at end of file diff --git a/src/main/util/test.h b/src/main/util/test.h index c41eabe..4bd9ee2 100644 --- a/src/main/util/test.h +++ b/src/main/util/test.h @@ -7,75 +7,111 @@ #include "defs.h" #include "log.h" -#define UTIL_TEST_MAIN_START \ - int main() \ - { \ - log_info("Unit test %s", FILENAME); \ - util_test_init(); \ +#define UTIL_TEST_MAIN_START \ + int main() \ + { \ + log_info("Unit test %s", FILENAME); \ + util_test_init(); #define UTIL_TEST_MAIN_END \ - util_test_exec(); \ - util_test_shutdown(); \ - return 0; \ - } \ + util_test_exec(); \ + util_test_shutdown(); \ + return 0; \ + } #define UTIL_TEST_FUNC_START(name) \ - bool name() \ -{ \ + bool name() \ + { #define UTIL_TEST_FUNC_END \ - return true; \ -} \ + return true; \ + } #define UTIL_TEST_ADD(func) util_test_add(STRINGIFY(func), func); -#define UTIL_TEST_ASSERT(exp) \ - do { \ - if (!util_test_assert_exp(exp, STRINGIFY(exp), FILENAME, __LINE__)) { \ - return false; \ - } \ - } while (0); \ +#define UTIL_TEST_ASSERT(exp) \ + do { \ + if (!util_test_assert_exp(exp, STRINGIFY(exp), FILENAME, __LINE__)) { \ + return false; \ + } \ + } while (0); #define UTIL_TEST_ASSERT_UINT(exp, actual) \ - do { \ - if (!util_test_assert_uint(exp, actual, STRINGIFY(exp), STRINGIFY(actual), FILENAME, __LINE__)) { \ - return false; \ - } \ - } while (0); \ + do { \ + if (!util_test_assert_uint( \ + exp, \ + actual, \ + STRINGIFY(exp), \ + STRINGIFY(actual), \ + FILENAME, \ + __LINE__)) { \ + return false; \ + } \ + } while (0); #define UTIL_TEST_ASSERT_STR(exp, actual) \ - do { \ - if (!util_test_assert_str(exp, actual, STRINGIFY(exp), STRINGIFY(actual), FILENAME, __LINE__)) { \ - return false; \ - } \ - } while (0); \ + do { \ + if (!util_test_assert_str( \ + exp, \ + actual, \ + STRINGIFY(exp), \ + STRINGIFY(actual), \ + FILENAME, \ + __LINE__)) { \ + return false; \ + } \ + } while (0); #define UTIL_TEST_ASSERT_DATA(exp, actual, len) \ - do { \ - if (!util_test_assert_data(exp, actual, len, STRINGIFY(exp), STRINGIFY(actual), FILENAME, __LINE__)) { \ - return false; \ - } \ - } while (0); \ + do { \ + if (!util_test_assert_data( \ + exp, \ + actual, \ + len, \ + STRINGIFY(exp), \ + STRINGIFY(actual), \ + FILENAME, \ + __LINE__)) { \ + return false; \ + } \ + } while (0); typedef bool (*util_test_func_t)(); void util_test_init(); -void util_test_add(const char* name, util_test_func_t func); +void util_test_add(const char *name, util_test_func_t func); void util_test_exec(); void util_test_shutdown(); -bool util_test_assert_exp(bool exp, const char* exp_str, const char* file, size_t line_num); +bool util_test_assert_exp( + bool exp, const char *exp_str, const char *file, size_t line_num); -bool util_test_assert_uint(size_t val_exp, size_t val_actual, const char* exp, const char* actual, const char* file, +bool util_test_assert_uint( + size_t val_exp, + size_t val_actual, + const char *exp, + const char *actual, + const char *file, size_t line_num); -bool util_test_assert_str(const char* val_exp, const char* val_actual, const char* exp, const char* actual, - const char* file, size_t line_num); +bool util_test_assert_str( + const char *val_exp, + const char *val_actual, + const char *exp, + const char *actual, + const char *file, + size_t line_num); -bool util_test_assert_data(const void* data_exp, const void* data_actual, size_t len, const char* exp, - const char* actual, const char* file, size_t line_num); +bool util_test_assert_data( + const void *data_exp, + const void *data_actual, + size_t len, + const char *exp, + const char *actual, + const char *file, + size_t line_num); #endif diff --git a/src/main/util/time.c b/src/main/util/time.c index acee0f5..f890355 100644 --- a/src/main/util/time.c +++ b/src/main/util/time.c @@ -1,69 +1,69 @@ #include #include -#include #include +#include #include "util/time.h" -#define SEC_PER_DAY 86400 -#define SEC_PER_HOUR 3600 -#define SEC_PER_MIN 60 +#define SEC_PER_DAY 86400 +#define SEC_PER_HOUR 3600 +#define SEC_PER_MIN 60 void util_time_sleep_ns(uint64_t time_ns) { - struct timespec t; - t.tv_sec = (__time_t) (time_ns / (1000 * 1000 * 1000)); - t.tv_nsec = (__syscall_slong_t) time_ns % (1000 * 1000 * 1000); + struct timespec t; + t.tv_sec = (__time_t)(time_ns / (1000 * 1000 * 1000)); + t.tv_nsec = (__syscall_slong_t) time_ns % (1000 * 1000 * 1000); - nanosleep(&t, NULL); + nanosleep(&t, NULL); } void util_time_sleep_us(uint64_t time_us) { - struct timespec t; - t.tv_sec = (__time_t) (time_us / (1000 * 1000)); - t.tv_nsec = (__syscall_slong_t) (time_us % (1000 * 1000)) * 1000; + struct timespec t; + t.tv_sec = (__time_t)(time_us / (1000 * 1000)); + t.tv_nsec = (__syscall_slong_t)(time_us % (1000 * 1000)) * 1000; - nanosleep(&t, NULL); + nanosleep(&t, NULL); } void util_time_sleep_ms(uint64_t time_ms) { - struct timespec t; - t.tv_sec = (__time_t) (time_ms / 1000); - t.tv_nsec = (__syscall_slong_t) (time_ms % 1000) * 1000 * 1000; + struct timespec t; + t.tv_sec = (__time_t)(time_ms / 1000); + t.tv_nsec = (__syscall_slong_t)(time_ms % 1000) * 1000 * 1000; - nanosleep(&t, NULL); + nanosleep(&t, NULL); } void util_time_sleep_sec(uint64_t time_sec) { - struct timespec t; - t.tv_sec = (__time_t) time_sec; - t.tv_nsec = 0; + struct timespec t; + t.tv_sec = (__time_t) time_sec; + t.tv_nsec = 0; - nanosleep(&t, NULL); + nanosleep(&t, NULL); } -void util_time_get_current_time(struct util_time_timestamp* timestamp) +void util_time_get_current_time(struct util_time_timestamp *timestamp) { - if (!timestamp) { - return; - } + if (!timestamp) { + return; + } - time_t t = time(NULL); - struct tm* tm = localtime(&t); + time_t t = time(NULL); + struct tm *tm = localtime(&t); - struct timeval tv; - gettimeofday(&tv, NULL); + struct timeval tv; + gettimeofday(&tv, NULL); - timestamp->millisec = tv.tv_usec / 1000; - timestamp->sec = tm->tm_sec; - timestamp->min = tm->tm_min; - timestamp->hour = tm->tm_hour; - timestamp->day = tm->tm_mday; - // Months since January [0, 11] - timestamp->month = tm->tm_mon + 1; - // Years since 1900 - timestamp->year = tm->tm_year + 1900; + timestamp->millisec = tv.tv_usec / 1000; + timestamp->sec = tm->tm_sec; + timestamp->min = tm->tm_min; + timestamp->hour = tm->tm_hour; + timestamp->day = tm->tm_mday; + // Months since January [0, 11] + timestamp->month = tm->tm_mon + 1; + // Years since 1900 + timestamp->year = tm->tm_year + 1900; } \ No newline at end of file diff --git a/src/main/util/time.h b/src/main/util/time.h index 80f106b..8680adc 100644 --- a/src/main/util/time.h +++ b/src/main/util/time.h @@ -4,13 +4,13 @@ #include struct util_time_timestamp { - uint16_t year; - uint8_t month; - uint8_t day; - uint8_t hour; - uint8_t min; - uint8_t sec; - uint16_t millisec; + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t min; + uint8_t sec; + uint16_t millisec; }; void util_time_sleep_ns(uint64_t time_ns); @@ -21,6 +21,6 @@ void util_time_sleep_ms(uint64_t time_ms); void util_time_sleep_sec(uint64_t time_sec); -void util_time_get_current_time(struct util_time_timestamp* timestamp); +void util_time_get_current_time(struct util_time_timestamp *timestamp); -#endif //UTIL_TIME_H +#endif // UTIL_TIME_H diff --git a/src/test/capnhook/hook/lib/main.c b/src/test/capnhook/hook/lib/main.c index f13cf59..e88657c 100644 --- a/src/test/capnhook/hook/lib/main.c +++ b/src/test/capnhook/hook/lib/main.c @@ -8,66 +8,65 @@ typedef int (*test_mock_function_t)(int a); static int test_mock_function(int a) { - return a * 2; + return a * 2; } -static void test_cnh_lib_mock_init_unit_test(void** state) +static void test_cnh_lib_mock_init_unit_test(void **state) { - struct cnh_lib_unit_test_func_mocks* mocks; - size_t mocks_cnt; - void* ptr; + struct cnh_lib_unit_test_func_mocks *mocks; + size_t mocks_cnt; + void *ptr; - mocks_cnt = 1; - mocks = cnh_lib_allocate_func_mocks(mocks_cnt); + mocks_cnt = 1; + mocks = cnh_lib_allocate_func_mocks(mocks_cnt); - mocks[0].name = "test_mock_function"; - mocks[0].func = test_mock_function; + mocks[0].name = "test_mock_function"; + mocks[0].func = test_mock_function; - cnh_lib_init_unit_test(mocks, mocks_cnt); + cnh_lib_init_unit_test(mocks, mocks_cnt); - ptr = cnh_lib_load("asdf"); - assert_ptr_not_equal(ptr, NULL); + ptr = cnh_lib_load("asdf"); + assert_ptr_not_equal(ptr, NULL); - ptr = cnh_lib_get_func_addr_handle(ptr, "test_mock_function"); - assert_ptr_equal(ptr, test_mock_function); + ptr = cnh_lib_get_func_addr_handle(ptr, "test_mock_function"); + assert_ptr_equal(ptr, test_mock_function); - assert_int_equal(((test_mock_function_t) ptr)(2), 4); + assert_int_equal(((test_mock_function_t) ptr)(2), 4); - ptr = cnh_lib_get_func_addr_handle(ptr, "asdf"); - assert_ptr_equal(ptr, NULL); + ptr = cnh_lib_get_func_addr_handle(ptr, "asdf"); + assert_ptr_equal(ptr, NULL); - cnh_lib_unload(ptr); - // Nothing happens here + cnh_lib_unload(ptr); + // Nothing happens here - ptr = cnh_lib_get_func_addr( "test_mock_function"); - assert_ptr_equal(ptr, test_mock_function); + ptr = cnh_lib_get_func_addr("test_mock_function"); + assert_ptr_equal(ptr, test_mock_function); - cnh_lib_shutdown_unit_test(); + cnh_lib_shutdown_unit_test(); } -static void test_cnh_lib_real(void** state) +static void test_cnh_lib_real(void **state) { - void* ptr; + void *ptr; - cnh_lib_init(); + cnh_lib_init(); - ptr = cnh_lib_load("libc.so.6"); + ptr = cnh_lib_load("libc.so.6"); - assert_ptr_not_equal(ptr, NULL); - assert_ptr_equal(cnh_lib_load("asdfasdas"), NULL); + assert_ptr_not_equal(ptr, NULL); + assert_ptr_equal(cnh_lib_load("asdfasdas"), NULL); - assert_ptr_not_equal(cnh_lib_get_func_addr_handle(ptr, "printf"), NULL); - assert_ptr_not_equal(cnh_lib_get_func_addr("printf"), NULL); + assert_ptr_not_equal(cnh_lib_get_func_addr_handle(ptr, "printf"), NULL); + assert_ptr_not_equal(cnh_lib_get_func_addr("printf"), NULL); - assert_ptr_equal(cnh_lib_get_func_addr("asdasdas"), NULL); + assert_ptr_equal(cnh_lib_get_func_addr("asdasdas"), NULL); } -int main(int argc, char* argv[]) +int main(int argc, char *argv[]) { - const struct CMUnitTest tests[] ={ - cmocka_unit_test(test_cnh_lib_mock_init_unit_test), - cmocka_unit_test(test_cnh_lib_real) - }; + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_cnh_lib_mock_init_unit_test), + cmocka_unit_test(test_cnh_lib_real)}; - return cmocka_run_group_tests(tests, NULL, NULL); + return cmocka_run_group_tests(tests, NULL, NULL); } \ No newline at end of file diff --git a/src/test/hook/propatch/usb-fix/main.c b/src/test/hook/propatch/usb-fix/main.c index 01de203..de9a4b5 100644 --- a/src/test/hook/propatch/usb-fix/main.c +++ b/src/test/hook/propatch/usb-fix/main.c @@ -11,135 +11,133 @@ #include "util/log.h" #include "util/mem.h" -static const char* readlink_return_value = "../devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2:1.0/host7/target7:0:0/7:0:0:0/block/sde"; -static const char* player1_match_buf = "../devices/pci0000:00/0000:00:14.0/usb2/1-1/1-1:1.0"; -static const char* player2_match_buf = "../devices/pci0000:00/0000:00:14.0/usb2/1-2/1-2:1.0"; +static const char *readlink_return_value = + "../devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2:1.0/host7/target7:0:0/" + "7:0:0:0/block/sde"; +static const char *player1_match_buf = + "../devices/pci0000:00/0000:00:14.0/usb2/1-1/1-1:1.0"; +static const char *player2_match_buf = + "../devices/pci0000:00/0000:00:14.0/usb2/1-2/1-2:1.0"; -extern ssize_t propatch_usb_fix_readlink(const char* path, char* buf, size_t len); +extern ssize_t +propatch_usb_fix_readlink(const char *path, char *buf, size_t len); static uint32_t readlink_call_count = 0; -ssize_t readlink_mock(const char* path, char* buf, size_t len) +ssize_t readlink_mock(const char *path, char *buf, size_t len) { - ssize_t len_return; + ssize_t len_return; - readlink_call_count++; + readlink_call_count++; - len_return = strlen(readlink_return_value); + len_return = strlen(readlink_return_value); - assert_true(len >= len_return); + assert_true(len >= len_return); - strcpy(buf, readlink_return_value); + strcpy(buf, readlink_return_value); - return len_return; + return len_return; } -static int setup(void** state) +static int setup(void **state) { - struct cnh_lib_unit_test_func_mocks* func_mocks; - size_t func_mocks_cnt; + struct cnh_lib_unit_test_func_mocks *func_mocks; + size_t func_mocks_cnt; - test_util_mem_install_mem_interface(); + test_util_mem_install_mem_interface(); - func_mocks_cnt = 1; - func_mocks = cnh_lib_allocate_func_mocks(func_mocks_cnt); + func_mocks_cnt = 1; + func_mocks = cnh_lib_allocate_func_mocks(func_mocks_cnt); - func_mocks[0].name = "readlink"; - func_mocks[0].func = readlink_mock; + func_mocks[0].name = "readlink"; + func_mocks[0].func = readlink_mock; - cnh_lib_init_unit_test(func_mocks, func_mocks_cnt); + cnh_lib_init_unit_test(func_mocks, func_mocks_cnt); - readlink_call_count = 0; + readlink_call_count = 0; - return 0; + return 0; } -static int teardown(void** state) +static int teardown(void **state) { - propatch_usb_fix_shutdown(); + propatch_usb_fix_shutdown(); - cnh_lib_shutdown_unit_test(); + cnh_lib_shutdown_unit_test(); - return 0; + return 0; } -static void test_usb_fix_disabled(void** state) +static void test_usb_fix_disabled(void **state) { - ssize_t res; - char buffer[256]; + ssize_t res; + char buffer[256]; - res = propatch_usb_fix_readlink( - "/sys/block/sde/device", - buffer, - sizeof(buffer)); + res = propatch_usb_fix_readlink( + "/sys/block/sde/device", buffer, sizeof(buffer)); - assert_int_equal(res, strlen(readlink_return_value)); - assert_string_equal(buffer, readlink_return_value); + assert_int_equal(res, strlen(readlink_return_value)); + assert_string_equal(buffer, readlink_return_value); - assert_int_equal(readlink_call_count, 1); + assert_int_equal(readlink_call_count, 1); } -static void test_no_match_usb_fix(void** state) +static void test_no_match_usb_fix(void **state) { - ssize_t res; - char buffer[256]; + ssize_t res; + char buffer[256]; - propatch_usb_fix_init("sdd,sdf", "2-1", "2-2"); + propatch_usb_fix_init("sdd,sdf", "2-1", "2-2"); - res = propatch_usb_fix_readlink( - "/sys/block/sde/device", - buffer, - sizeof(buffer)); + res = propatch_usb_fix_readlink( + "/sys/block/sde/device", buffer, sizeof(buffer)); - assert_int_equal(res, strlen(readlink_return_value)); + assert_int_equal(res, strlen(readlink_return_value)); - assert_int_equal(readlink_call_count, 1); + assert_int_equal(readlink_call_count, 1); } -static void test_match_player1_usb_fix(void** state) +static void test_match_player1_usb_fix(void **state) { - ssize_t res; - char buffer[256]; + ssize_t res; + char buffer[256]; - propatch_usb_fix_init("sde,sdf", "2-1", "2-2"); + propatch_usb_fix_init("sde,sdf", "2-1", "2-2"); - res = propatch_usb_fix_readlink( - "/sys/block/sde/device", - buffer, - sizeof(buffer)); + res = propatch_usb_fix_readlink( + "/sys/block/sde/device", buffer, sizeof(buffer)); - assert_int_equal(res, strlen(player1_match_buf)); - assert_string_equal(buffer, player1_match_buf); + assert_int_equal(res, strlen(player1_match_buf)); + assert_string_equal(buffer, player1_match_buf); - assert_int_equal(readlink_call_count, 1); + assert_int_equal(readlink_call_count, 1); } -static void test_match_player2_usb_fix(void** state) +static void test_match_player2_usb_fix(void **state) { - ssize_t res; - char buffer[256]; + ssize_t res; + char buffer[256]; - propatch_usb_fix_init("sde,sdf", "2-2", "2-1"); + propatch_usb_fix_init("sde,sdf", "2-2", "2-1"); - res = propatch_usb_fix_readlink( - "/sys/block/sde/device", - buffer, - sizeof(buffer)); + res = propatch_usb_fix_readlink( + "/sys/block/sde/device", buffer, sizeof(buffer)); - assert_int_equal(res, strlen(player2_match_buf)); - assert_string_equal(buffer, player2_match_buf); + assert_int_equal(res, strlen(player2_match_buf)); + assert_string_equal(buffer, player2_match_buf); - assert_int_equal(readlink_call_count, 1); + assert_int_equal(readlink_call_count, 1); } -int main(int argc, char* argv[]) +int main(int argc, char *argv[]) { - const struct CMUnitTest tests[] ={ - cmocka_unit_test_setup_teardown(test_usb_fix_disabled, setup, teardown), - cmocka_unit_test_setup_teardown(test_no_match_usb_fix, setup, teardown), - cmocka_unit_test_setup_teardown(test_match_player1_usb_fix, setup, teardown), - cmocka_unit_test_setup_teardown(test_match_player2_usb_fix, setup, teardown) - }; + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown(test_usb_fix_disabled, setup, teardown), + cmocka_unit_test_setup_teardown(test_no_match_usb_fix, setup, teardown), + cmocka_unit_test_setup_teardown( + test_match_player1_usb_fix, setup, teardown), + cmocka_unit_test_setup_teardown( + test_match_player2_usb_fix, setup, teardown)}; - return cmocka_run_group_tests(tests, NULL, NULL); + return cmocka_run_group_tests(tests, NULL, NULL); } \ No newline at end of file diff --git a/src/test/test-util/mem.c b/src/test/test-util/mem.c index 3a96046..ae70a3c 100644 --- a/src/test/test-util/mem.c +++ b/src/test/test-util/mem.c @@ -7,37 +7,37 @@ #include "util/log.h" #include "util/mem.h" -static void* _test_util_mem_xmalloc(size_t nbytes) +static void *_test_util_mem_xmalloc(size_t nbytes) { - void* ptr; + void *ptr; - ptr = test_malloc(nbytes); + ptr = test_malloc(nbytes); - log_debug("malloc(%d): %p", nbytes, ptr); + log_debug("malloc(%d): %p", nbytes, ptr); - return ptr; + return ptr; } -static void* _test_util_mem_xrealloc(void* mem, size_t nbytes) +static void *_test_util_mem_xrealloc(void *mem, size_t nbytes) { - void* ptr; + void *ptr; - ptr = test_realloc(mem, nbytes); + ptr = test_realloc(mem, nbytes); - log_debug("realloc(%p %d): %p", mem, nbytes, ptr); + log_debug("realloc(%p %d): %p", mem, nbytes, ptr); - return ptr; + return ptr; } -static void _test_util_mem_xfree(void** mem) +static void _test_util_mem_xfree(void **mem) { - if (*mem != NULL) { - log_debug("free(%p %p)", mem, *mem); - test_free(*mem); - *mem = NULL; - } else { - log_warn("free(%p NULL)", mem); - } + if (*mem != NULL) { + log_debug("free(%p %p)", mem, *mem); + test_free(*mem); + *mem = NULL; + } else { + log_warn("free(%p NULL)", mem); + } } static const struct util_mem_interface _test_util_mem_interface_test = { @@ -48,5 +48,5 @@ static const struct util_mem_interface _test_util_mem_interface_test = { void test_util_mem_install_mem_interface() { - util_mem_init(&_test_util_mem_interface_test); + util_mem_init(&_test_util_mem_interface_test); } \ No newline at end of file diff --git a/src/test/test-util/mem.h b/src/test/test-util/mem.h index 8e5d797..e88f462 100644 --- a/src/test/test-util/mem.h +++ b/src/test/test-util/mem.h @@ -1,6 +1,7 @@ #pragma once /** - * Install the memory test interface which is backed by cmocka for leak and error detection on unit tests. + * Install the memory test interface which is backed by cmocka for leak and + * error detection on unit tests. */ void test_util_mem_install_mem_interface(); \ No newline at end of file diff --git a/src/test/util/mem/main.c b/src/test/util/mem/main.c index 4f8551e..06b4208 100644 --- a/src/test/util/mem/main.c +++ b/src/test/util/mem/main.c @@ -4,47 +4,46 @@ #include "util/mem.h" -static void test_util_mem_mock_interface(void** state) +static void test_util_mem_mock_interface(void **state) { - void* ptr; + void *ptr; - test_util_mem_install_mem_interface(); + test_util_mem_install_mem_interface(); - ptr = util_xmalloc(100); - assert_ptr_not_equal(ptr, NULL); + ptr = util_xmalloc(100); + assert_ptr_not_equal(ptr, NULL); - ptr = util_xrealloc(ptr, 200); - assert_ptr_not_equal(ptr, NULL); + ptr = util_xrealloc(ptr, 200); + assert_ptr_not_equal(ptr, NULL); - util_xfree(&ptr); - assert_ptr_equal(ptr, NULL); + util_xfree(&ptr); + assert_ptr_equal(ptr, NULL); } -static void test_util_mem_real(void** state) +static void test_util_mem_real(void **state) { - void* ptr; + void *ptr; - util_mem_init_default(); + util_mem_init_default(); - ptr = util_xmalloc(100); - assert_ptr_not_equal(ptr, NULL); + ptr = util_xmalloc(100); + assert_ptr_not_equal(ptr, NULL); - ptr = util_xrealloc(ptr, 200); - assert_ptr_not_equal(ptr, NULL); + ptr = util_xrealloc(ptr, 200); + assert_ptr_not_equal(ptr, NULL); - util_xfree(&ptr); - assert_ptr_equal(ptr, NULL); + util_xfree(&ptr); + assert_ptr_equal(ptr, NULL); - // Should not crash - util_xfree(&ptr); + // Should not crash + util_xfree(&ptr); } -int main(int argc, char* argv[]) +int main(int argc, char *argv[]) { - const struct CMUnitTest tests[] ={ - cmocka_unit_test(test_util_mem_mock_interface), - cmocka_unit_test(test_util_mem_real) - }; + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_util_mem_mock_interface), + cmocka_unit_test(test_util_mem_real)}; - return cmocka_run_group_tests(tests, NULL, NULL); + return cmocka_run_group_tests(tests, NULL, NULL); } \ No newline at end of file diff --git a/src/test/util/str/main.c b/src/test/util/str/main.c index 743bcdd..cafe3d7 100644 --- a/src/test/util/str/main.c +++ b/src/test/util/str/main.c @@ -5,97 +5,96 @@ #include "util/mem.h" #include "util/str.h" -static int setup(void** state) +static int setup(void **state) { - test_util_mem_install_mem_interface(); + test_util_mem_install_mem_interface(); - return 0; + return 0; } -static void test_str_dup(void** state) +static void test_str_dup(void **state) { - char* str; + char *str; - str = util_str_dup("aasdf"); - assert_string_equal(str, "aasdf"); + str = util_str_dup("aasdf"); + assert_string_equal(str, "aasdf"); - util_xfree((void**) &str); + util_xfree((void **) &str); } -static void test_str_dup_empty(void** state) +static void test_str_dup_empty(void **state) { - char* str; + char *str; - str = util_str_dup(""); - assert_string_equal(str, ""); + str = util_str_dup(""); + assert_string_equal(str, ""); - util_xfree((void**) &str); + util_xfree((void **) &str); } -static void test_str_split0(void** state) +static void test_str_split0(void **state) { - size_t count; - char** toks; + size_t count; + char **toks; - toks = util_str_split("", ",", &count); + toks = util_str_split("", ",", &count); - assert_int_equal(count, 0); + assert_int_equal(count, 0); - util_str_free_split(toks, count); + util_str_free_split(toks, count); } -static void test_str_split1(void** state) +static void test_str_split1(void **state) { - size_t count; - char** toks; + size_t count; + char **toks; - toks = util_str_split("asd", ",", &count); + toks = util_str_split("asd", ",", &count); - assert_int_equal(count, 1); - assert_string_equal(toks[0], "asd"); + assert_int_equal(count, 1); + assert_string_equal(toks[0], "asd"); - util_str_free_split(toks, count); + util_str_free_split(toks, count); } -static void test_str_split2(void** state) +static void test_str_split2(void **state) { - size_t count; - char** toks; + size_t count; + char **toks; - toks = util_str_split("asd,123", ",", &count); + toks = util_str_split("asd,123", ",", &count); - assert_int_equal(count, 2); - assert_string_equal(toks[0], "asd"); - assert_string_equal(toks[1], "123"); + assert_int_equal(count, 2); + assert_string_equal(toks[0], "asd"); + assert_string_equal(toks[1], "123"); - util_str_free_split(toks, count); + util_str_free_split(toks, count); } -static void test_str_split3(void** state) +static void test_str_split3(void **state) { - size_t count; - char** toks; + size_t count; + char **toks; - toks = util_str_split("/asd/123/ddd/", "/", &count); + toks = util_str_split("/asd/123/ddd/", "/", &count); - assert_int_equal(count, 3); - assert_string_equal(toks[0], "asd"); - assert_string_equal(toks[1], "123"); - assert_string_equal(toks[2], "ddd"); + assert_int_equal(count, 3); + assert_string_equal(toks[0], "asd"); + assert_string_equal(toks[1], "123"); + assert_string_equal(toks[2], "ddd"); - util_str_free_split(toks, count); + util_str_free_split(toks, count); } -int main(int argc, char* argv[]) +int main(int argc, char *argv[]) { - const struct CMUnitTest tests[] ={ - cmocka_unit_test_setup(test_str_dup, setup), - cmocka_unit_test_setup(test_str_dup_empty, setup), - cmocka_unit_test_setup(test_str_split0, setup), - cmocka_unit_test_setup(test_str_split1, setup), - cmocka_unit_test_setup(test_str_split2, setup), - cmocka_unit_test_setup(test_str_split3, setup) - }; + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup(test_str_dup, setup), + cmocka_unit_test_setup(test_str_dup_empty, setup), + cmocka_unit_test_setup(test_str_split0, setup), + cmocka_unit_test_setup(test_str_split1, setup), + cmocka_unit_test_setup(test_str_split2, setup), + cmocka_unit_test_setup(test_str_split3, setup)}; - return cmocka_run_group_tests(tests, NULL, NULL); + return cmocka_run_group_tests(tests, NULL, NULL); } \ No newline at end of file