The section is 0x461 bytes long, not 0x460. The config data is also now
initialised to zero to avoid garbage being written to the SYSCONF.
Because our handling has been wrong forever, we discard older BT.DINF
section backups as using them would result in the section being the
wrong size / incomplete again.
It turns out that the last byte of array entries isn't unused (as we
thought); instead, it looks like it's actually part of the main data,
and the length stored next to the name is in fact the length minus one.
Getting it wrong and always storing a null byte in there won't affect
most entries (since the last byte is zeroed most of the time), except:
- IPL.NIK: the length is stored in the last byte, and it must be kept.
- BT.DINF: u8 unknown[0x45] should be another Bluetooth device entry.
- Possibly other unknown affected entries.
BluetoothEmu had its own bdaddr_t type which is a old style C struct
and typedef, which makes comparisons and copies a bit ugly.
On the other hand, BTReal had its own btaddr_t type using std::array.
To make things very slightly nicer, this commit changes the Bluetooth
code to use a single type (std::array<u8, 6>) for all BT addresses.
Imports/exports don't always use the title key. Exporting a title and
importing it back uses the PRNG key (aka backup key handle or key #5),
not the title key (at all).
To make things even more fun, some versions of IOS have a bug that
causes it to use a zeroed key instead of the PRNG key. When Nintendo
decided to fix it, they added checks to keep using the zeroed key only
in affected titles to avoid making existing exports useless.
(Thanks to tueidj for drawing my attention to this.
I missed this edge case during the initial implementation.)
This commit implements these checks so we are using the correct key
in all of these cases.
We now also use IOSC for decryption/encryption since built-in key
handles are used. And we now reject any invalid common key index,
just like ES.
Core::PauseAndLock requires all calls to it to be balanced, like this:
const bool was_unpaused = Core::PauseAndLock(true);
// do stuff on the CPU thread
Core::PauseAndLock(false, was_unpaused);
Aside from being a bit cumbersome, it turns out all callers really
don't need to know about was_unpaused at all. They just need to do
something on the CPU thread safely, including locking/unlocking.
So this commit replaces Core::PauseAndLock with a function that
makes both the purpose and the scope of what is being run on the
CPU thread visually clear. This makes it harder to accidentally run
something on the wrong thread, or forget the second call to
PauseAndLock to unpause, or forget that it needs to be passed
was_unpaused at the end.
We also don't need comments to indicate code X is being run on the
CPU thread anymore, as the function name makes it obvious.
The region mismatch check that we used can give false positives.
Skipping the check won't lead to any harm - games will ignore
save files that have a non-matching fourth game ID character.
Now fails if any commands fail. I noticed that on the buildbot, the
arguments to this script can be incorrect (somehow?) which can result in
no lint checks happening but the buildbot still passing.