While setting up a proper NAND for Wii emulation has become much easier
now that disc and online system updates work, they still require users
to have a recent disc game, certificates extracted from IOS or a NAND
dump for online updates to work and to really get all system titles.
This commit adds the ability to do an online update right from
Dolphin itself, which solves that usability issue.
Allows reusing the WAD import logic more easily, whereas UICommon
code can only be used from UICommon and UI.
And managing what's on the NAND is the Core's responsability, not UI.
* IOS: WiiRoot shutdown was moved to HW.
* Movie: Don't call UpdateWantDeterminism() if we're not running yet,
because this will automatically be done during the boot process.
Not doing this will result in two NANDs being created.
This is larger than I thought I would be, but unfortunately it's quite
hard to split fixes like this when the handling is wrong in tons of
different places.
The content table is limited in size. It can only hold 16 entries.
Three consequences:
* Since the table cannot grow indefinitely, instead of using a std::map
we use a std::array as we should.
* Remove a hack where the CFD was cleared back to 0 on IPC close (wtf?)
* The CFD now doesn't keep increasing to infinity. It's unknown if this
would fix anything at all, but some issues in the past were caused
by CFDs being excessively large.
Other minor changes:
* Simplify save state logic.
* Keep track of the UID like ES does. Not sure how useful this is, but
we can do this very easily so why not.
* Remove the guesswork and use the actual error codes.
* Add more error checking to make Dolphin less likely to crash.
Something that should be done in the future: deduplicate the filesystem
logic. Something that takes one line in the actual ES code takes
10+ lines in our implementation... while duplicating the FS logic...
This will likely harder to fix though, so I'm leaving that
for another time.
The sanity check runs *before* finalising the import, so at that time
the whole title directory is still in /import and not in /title.
This means we should check for contents there, not in /title. Whoops.
Simpler, and puts the call to CheckIntegrity right where it should be,
instead of being hidden somewhere in a thread class.
This also makes it more obvious what we're getting from the async task.
Oh, and coincidentally, this fixes a random crash that could occur
during the check. I'm not sure why.
This adds a check to ImportTitleDone to make sure all required contents
that are listed in the TMD have been imported before allowing to finish
the import. Not checking for this could allow titles to be left in an
inconsistent state.
This allows the user to go through the Wii Menu first boot setup
screen when they launch the System Menu for the first time.
Most useful on a clean profile, after doing a full system update,
to configure settings like the console country.
This rewrites the SysConf code for several reasons:
* Modernising the SysConf class. The naming was entirely cleaned up.
constexpr for constants.
* Exposing less stuff in the header.
* Probably less efficient parsing and writing logic, but much simpler
to understand and use in my opinion. No more hardcoded offsets.
No more duplicated code for the initial SYSCONF generation.
* More flexibility. It is now possible to add and remove entries,
since we rebuild the file. This allows us to stop spamming
"section not found" panic alerts; we can now use and insert
default entries.
On a real Wii, the title list is not in any particular order. However,
because of how the flash filesystem works, titles such as 1-2 are
*never* in the first position. We must keep this behaviour, or some
versions of the System Menu may break.
Will be used from several functions to verify the signatures for
different containers (TMDs, tickets, device signed blobs).
An option was added to disable signature checks, because that could be
useful for people trying to import unsigned stuff.
stat() returns an error code in errno on both POSIX compliant
platforms and Windows.
This means we should always use errno instead of GetLastErrorMsg
which uses GetLastError() (Win32) on Windows.
POSIX allows one or more trailing slashes for directories.
From POSIX.1-2008, section 3.271 (Base Definitions / Pathname):
> A pathname can optionally contain one or more trailing <slash>
> characters. Multiple successive <slash> characters are considered to
> be the same as one <slash>, except for the case of exactly two
> leading <slash> characters.
On Windows, the extra trailing slashes are ignored for directories too.
Too much boilerplate that is duplicated if we use curl directly.
Let's add a simple wrapper class that hides the implementation details
and just allows to simply make HTTP requests and get responses.
Makes it slightly less likely to forget a check and end up doing an
out-of-bounds access. Also makes it obvious that we *are* indeed
checking whether the handle is valid, instead of hiding it in
HasOwnership (which won't handle the root key handle case properly).
This code hadn't been touched since 2010. Nowadays, the panic alert
setting is loaded by ConfigManager and applied in UICommon.
VideoConfig has no business messing with it.
I don't see why we need to call ShutdownWiiRoot on InitializeWiiRoot.
Also, atexit? Really? Not only is this unnecessary, it will also cause
ShutdownWiiRoot to be called twice in rapid succession for no reason.
The config must only be restored after the HW has shut down, not while
it is still running, because the HW can still query the config, which
can lead to inconsistent states.
This fixes WiiRoot not being able to copy back saves on shutdown.
This ioctlv is used to get an IOSC decrypt handle for a title.
It is known to be used internally by the WFS modules, but it can also
be used from the PPC under some conditions.
Brings us down to 2 essentially unimplementable ioctlvs (syscalls which
seem to return kernel thread priorities...), and 1 known but
unimplemented ioctlv (VerifySign).
In the future, NAND filesystem access will be limited to one IOS
instance, for safety reasons and to make it possible to consider
supporting NAND images. This means that any code accessing the NAND
filesystem must go through the FS device, both for code that is
external to IOS and internal.
Because we don't want to introduce any singleton, this requires
internal IOS code that needs NAND access to be part of an IOS device
class, so they can access the FS device easily.
Making some of the internal ES implementation functions member
functions also prevents them from being (mis)used outside of IOS,
since they cannot be called everywhere anymore.
I don't see any reason to disable loading the IPL if bHLE_BS2 is
disabled. bHLE_BS2 should only cause us not to run the IPL, but not
skip loading it in the first place. More importantly, without always
loading it, this causes issues when trying to launch only the GC IPL
while having bHLE_BS2 = false.
They're essentially the same. To achieve this, this commit unifies
DolReader and ElfReader into a common interface for boot executable
readers, so the only remaining difference between ELF and DOL is
how which volume is inserted.
* Move out boot parameters to a separate struct, which is not part
of SConfig/ConfigManager because there is no reason for it to
be there.
* Move out file name parsing and constructing the appropriate params
from paths to a separate function that does that, and only that.
* For every different boot type we support, add a proper struct with
only the required parameters, with descriptive names and use
std::variant to only store what we need.
* Clean up the bHLE_BS2 stuff which made no sense sometimes. Now
instead of using bHLE_BS2 for two different things, both for storing
the user config setting and as a runtime boot parameter,
we simply replace the Disc boot params with BootParameters::IPL.
* Const correctness so it's clear what can or cannot update the config.
* Drop unused parameters and unneeded checks.
* Make a few checks a lot more concise. (Looking at you, extension
checks for disc images.)
* Remove a mildly terrible workaround where we needed to pass an empty
string in order to boot the GC IPL without any game inserted.
(Not required anymore thanks to std::variant and std::optional.)
The motivation for this are multiple: cleaning up and being able to add
support for booting an installed NAND title. Without this change, it'd
be pretty much impossible to implement that.
Also, using std::visit with std::variant makes the compiler do
additional type checks: now we're guaranteed that the boot code will
handle all boot types and no invalid boot type will be possible.
I didn't know better back then, but the boot type is only supposed to
be used for the actual boot params. It shouldn't be used or changed
after booting.
Instead of applying PRs as patches and leaving them as staged changes,
the lint builder now checks out the PR branch, so the lint script
must be able to call git diff with more than just --cached.
(The buildbot will call it with "master...".)
This makes the interface slightly cleaner and a bit more consistent
with the other getters. Still not fully the same, since the others
don't really handle failures with std::optional; but at least the
value is returned by value now, as opposed to having the function
take a pointer to a u64.
This is more reliable, as this guarantees subsystems will be
shut down in the same order they were initialised (if they were
initialised). It also allows us to stop keeping track of what needs to
be shut down manually and just return in case of errors.
This should prevent the emulator from getting totally stuck when
the boot process does fail.
This makes it hard to support different boot params for different boot
types. We should not be making the assumption that Dolphin will
always be booting directly from a file (and in particular, only
using a string).
It's incompatible with future changes that will allow Dolphin to boot
a NAND title properly from well, the NAND, as opposed to booting from
WADs. (And no, treating the title TMD as a "bootable" path doesn't
count. Especially when that approach won't work with NAND images
or IOS LLE.)
And it's confusing to expose this functionality from the UI. It's
pretty bad for UX to change the play button's behaviour depending on
whether the user has launched something before, configured a default
file to boot, added a directory to their game paths.
This commit moves the write function to where it should be (IOS),
especially when ES::ImportTicket() is the only place to use it.
Prevents misusing the ticket import function, and removes one unsafe
direct write to the NAND that does not go through IOS.
This also fixes the destination path: the session root is the one which
should be used for determining the ticket path, not the configured one.
The whole NANDContentLoader stuff is truly awful and will be removed
as soon as possible.
For now, this fixes a bug that was exposed by std::optional::operator*.
std::optional makes a few things a bit neater and less error prone.
However, we still cannot use C++17 (unfortunately), so this commit
adds an implementation of std::optional that we can use right now.
Based on https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/lib/gtl/optional.h
which seems to be fairly similar to C++17's <optional> and standards
compliant. It's one of the few implementations that handle propagating
type traits like copy constructibility, just like libc++/libstdc++.