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++.
After getting in touch with the GameTDB maintainer about using their
databases, they have decided to implement a UNIQUE parameter so we
don't need to deduplicate ourselves. This simplifies the script a bit.
Thanks to lustar for their help.
This allows us to print user friendly names for titles out of the box,
without requiring the user to manually download a title database and
place it in the correct location.
No auto-update mechanism is implemented as it would be substantially
more complicated and overkill (imo), since titles are not updated
that often. I have however added a script to make updating them easier.
The database can be freely used without any restriction. I have
contacted the author.
Direct access to the WAD bytes is required to read contents with proper
padding data (since they can sometimes end up being outside of the
data app section). Allowing the whole buffer to be accessed directly
would be error prone, so this commit adds GetContent() to WiiWAD
for getting raw content data by index.
These cannot be booted, so it is bad UX to show them in the UI as if
they were regular titles, and yet have different behaviour for them.
And technically, there is no reason to allow them to be used to boot
in the first place.
Another reason they should not be shown is that Dolphin fails
spectacularly with WADs that have a valid boot content index, but are
not PPC titles (e.g. IOS WADs). The only reliable way to avoid this
is to check for the title type and only show channels, just like
the Wii System Menu.
Mistakenly used the wrong TMD to clean up the import.
The original TMD is the one that is supposed to be used when
cancelling an import, but I forgot it's in the /import directory after
starting an import.
This exposes all ES title management ioctlvs to avoid duplicating IOS
code everywhere and to make it easier to reuse (since this way it's
not unnecessarily tied to the PPC IPC mechanism anymore) and unit test.
Some functions were also renamed for consistency with the other names,
*and* with official names.
Just like DeleteTitle, Using CNANDContentManager is overkill,
inefficient and useless. And it results in a few failures in
situations where a delete should just always work.
But here it gets bonus points, because it manages to actually use
the TMD for deleting contents, when IOS does none of that and just
deletes files ending with .app in the title content directory. :)
This enables constructing an IOS instance that is not tied to emulation
and that can be simply used for internal purposes (ES, FS).
NAND root initialisation was moved to IOS since we cannot rely on HW
doing that for us anymore, and technically the NAND is entirely managed
by IOS anyway.
This is unsafe, because the NAND should not be accessed and messed with
while it is being used. In fact, this kind of inappropriate behaviour
will not be possible when we get NAND image support.
And even if there were no safety issue, there is still no reason
a *getter* function should *do* something that has lasting effects
on user data. GetWiiFSPath() should *just* return a path!
This adds code to update the PPC's UID and GID, which fixes a
regression with the system menu. Ideally, we would simply rely on IOS's
ES_Launch here and not duplicate the logic here, but we cannot do that
properly until the direct WAD launch hack is dropped, *and* until the
IOS changes that would enable internal calls are ready.
Since this fixes a semi-important regression with managing saves from
the SM, and the duplication is not too terrible, I believe it is a good
idea to get this fixed right now to avoid affecting users too much.
I do plan to fix this properly in the future.
* CNANDContentManager does things that are absolutely useless. In
particular, it parses the ticket, the TMD, reads contents, etc.
when we only need to remove the title directory.
* This means it will fail if the ticket cannot be found, when that
should not be the case.
* This also obviously caused DeleteTitle to be incredibly inefficient.
* We are already removing the title directory later in the function,
as CNANDContentManager does not even delete titles correctly.
DeleteTitle != DeleteTitleContents.
This introduces `constexpr` usages for compile-time constants in the
contributing guide, as apparently most people don't know it exists,
or that it doesn't have to be used with `const` most of the time.
* It should take a ticket view, not a title ID.
* It's missing a lot of checks.
* It's not deleting tickets properly.
* It's not deleting only the ticket it needs to delete.
* It should not return -1017 when the ticket doesn't exist.
* It's not returning the proper error code when a read/write fails.
* It's not cleaning up the ticket directory if there is nothing left.
This commit fixes its implementation.
* Supporting other ticket types makes the logic slightly more complex.
* There have been no such non-RSA2048 tickets seen during the Wii's
lifetime.
* The Wii's IOS doesn't even have support for them.
This changes some parts of IOS (actually just ES) to reuse more crypto
code from IOSC or Common::AES.
TicketReader still returns the title key directly as opposed to having
ES use IOSC directly to avoid duplicating the title key IV stuff.
Side effects:
* A nasty unbounded array access bug is now fixed.
* ES_Decrypt/ES_Encrypt now returns sane results for keys other than
the SD key.
* Titles with a Korean ticket can now be decrypted properly.
And in the future, we can look into implementing ioctlv 0x3c and 0x3d
now that we have the proper "infra" for IOSC calls.
This prevents the IOS crypto code and keys from being spread over
the codebase. Things only have to be implemented once, and can be
used everywhere from the IOS code.
Additionally, since ES exposes some IOSC calls directly (DeleteObject
and Encrypt/Decrypt), we need this for proper emulation.
Currently, this only supports AES key objects.
Netplay uses a blank NAND, which means that homebrew launchers like
Gecko will force users to install IOSes.
Expecting netplay users to have a proper NAND setup is unrealistic,
and we don't actually give them a good way of syncing NANDs, so
let's extend the hack to netplay/TAS until we have a better way
of dealing with the issue.
This changes the main IOS code (roughly the equivalent of the kernel)
to a class instead of being a set of free functions + tons of static
variables.
The reason for this change is that keeping tons of static variables
like that prevents us from making an IOS instance and reusing IOS
code easily.
Converting the IOS code to a class also allows us to mostly decouple
IOS from the PPC emulation.
The more interesting changes are in Core/IOS/IOS. Everything else is
mostly just boring stuff required by this change...
* Because the devices themselves call back to the main IOS code
for various things (getting the current version, replying to a
request, and other syscall-like functions), just like processes in
IOS call kernel syscalls, we have to pass a reference to the kernel
to anything that uses IOS syscalls.
* Change DoState to save device names instead of device IDs to simplify
AddDevice() and get rid of an ugly static count.
* Change ES_Launch's ack to be sent at IOS boot, now that we can do
this properly.
This changes the IOS code to handle ES contexts inside of ES, instead
of leaking out implementation details into the IPC request dispatcher.
The intent is to clarify what's shared between every single ES context,
and what is specific to an ES context. (Not much.) This should reduce
the number of static members in the ES class.
The other changes are there just because we now keep track of the
IPC FD inside of ES.
Future plans:
* After the WAD direct launch hack is dropped, the title context
will be made a class member.
* Have proper function prototypes, instead of having every single one
of them take ioctlv requests. This will allow reusing IOS code in
other parts of the Dolphin codebase without having to construct
ioctlv requests.
GTK2 is a dependency on Linux whenever USE_X11 is true, but we were
not linking or adding the include directory for GTK for DolphinWX.
Fixes a regression introduced by 6197d9622.
Simple quality-of-life addition that allows "uninstalling" WADs
(removing the corresponding installed title) from the NAND.
The option is only enabled when the WAD can be uninstalled
The motivation for this is actually to encourage proper usage of the
WAD launch feature (installing it to the NAND first), so we can
drop the "direct WAD title launch" hack.
Looking more carefully at the IOS ticket view generation code reveals
that the first field in the TicketView struct is copied over from
the ticket version, extended to 4 bytes.
This implements ES_SetUid, which is used by the system menu to change
its own permissions. This is required for implementing permission
checks and proper NAND metadata support in the future.
This will be required for permission checks in the future.
Note that this is only for the PPC as we do not have actual processes.
Keeping track of other modules' UIDs/GIDs is virtually useless anyway.
UID/GID changes are implemented in the following functions:
* ES_Launch
* ES_DIVerify
ES_SetUid is not implemented yet because it'd need further changes.
Instead of allowing unknown ioctlvs and faking success for both unknown
and unimplemented ioctlvs, which can possibly result in nasty, hard to
debug bugs (if the emulated software behaves unexpectedly), we should
reject unknown ioctlvs and log known, but unimplemented ioctlvs.
This adds unit tests for IOS/ESFormats, and in particular, for the
TMDReader. It is tested using invalid TMDs (to check IsValid()) and
two valid, properly signed TMDs.
Things which are now tested:
* Title type helper functions.
* TMDReader: Validity check.
* TMDReader: General information returned by the Get*() methods.
* TMDReader: Raw TMD and generated TMD view, compared against IOS.
* TMDReader: Game ID generation code (which is Dolphin specific).
* TMDReader: Content information: getting by ID/index, order, metadata.
This is an implementation detail that does not have to be exposed.
It was used in WII_IPC whenever the IPC gets reset, but that does not
make much sense to me: the only time when IOS loses state and the IPC
registers are set up again is when it's reloaded. And reloading IOS
already calls Reset() indirectly.
Also, an IPC reset from the PPC definitely should not close all opened
devices!
This also gets rid of a special case for clear_devices, which is now
completely unneeded.
This keeps all of the return codes in the same place and exposed
publicly (as they are not internal to ES).
I have also added proper IOSC error codes and renamed some codes
for more consistency. (Unix ones have an E prefix, others do not.)
A set of small changes to handle title imports more accurately.
* Clean up the import directory after an import, exactly like IOS.
This should prevent the title directory from having useless leftover
contents, which could confuse the emulated software.
* More robust failsafe in case an import does not complete normally.
IOS checks for stale imports and handles them appropriately on boot.
We now do the same.
* Create all directories as IOS does. This includes the data directory.
This may fix LIBUSB_ERROR_NOT_FOUND whenever devices end up being in
an unconfigured state. We don't need anything more than the first
config descriptor anyway.
Proper semantics.
IOS only cares about the TMD and nothing else, so we should use
FindInstalledTMD, instead of reading/parsing/decrypting a bunch of
useless stuff, which is slow *and* causes issues because of the cache.
Dolphin assumes that content 0 is opening.bnr, without checking
whether content 0 exists or if it is even supposed to be there (it's
only there for channels). This results in sometimes reading garbage.
This adds a check to only try to read names from content 0's header
if the title is a channel (channel, system channel or game channel).