-
-
Notifications
You must be signed in to change notification settings - Fork 71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WiiU / vWii] libogc may mistakenly mount WiiU's USB storage drive when multiple USB drives are connected #145
Comments
hey, thanks for the report! first of all, i edited your report because this is an interesting report though but im not sure the linked fix is a correct fix. i don't know if doing a fatMount shows this error? |
Thanks for the quick response and for cleaning up my issue description! I also had a few reservations about the fix in WiiFlow pull request 343 as noted in the WiiFlow issue. Looking through the functions available in
The
Which, in turn, appears to reference Lines 997 to 1006 in bc4b778
This seems to imply that whatever device Additionally (and perhaps even more convincingly), it looks like
To me, all this taken together suggests that given how the function is used today, its callers expect it to only mount FAT formatted devices. To your point though, it could be argued that all the callers are actually misusing the function since making I'm not sure what the ideal solution is but at this point I'm fairly convinced there is a problem with the current code. One, possibly cleaner, approach to solving this might be to introduce a |
Yeah this isn't a bug in USB storage, there's a handling layer missing. We did this in wiimc - see FindPartitions You can also mount multiple partitions if you want. Libogc / libfat only provide simplified tools. https://github.com/dborth/wiimc/blob/master/source/fileop.cpp |
holy damn, what an impressive analysis @kcpants ! there was an attempt by wintermute to add more drivers to libogc by using the existing drivers and porting them over, and reuse the disc interfaces for device access. the idea is the device interface does the raw device access, the driver (libfat, ntfs-3g, ... ) do the filesystem interpretations & handles calls done by fopen and such. im conflicted though, because fixing this would require to rewrite it all and therefor break current applications... @dborth : multiple partitions but 1 from each device, if i see that correctly? i think the issue here is having 2 usbdrives in which the first is not FAT32 and the second is |
Thank you! Happy to help the community and very happy to have my comment novellas read and thoughtfully considered! Overhauling From a practical standpoint, I'm not aware of any real world need to actually access multiple USB storage devices at this time. I think the main problem with the current implementation is that callers need access to the "right" device but they have no control over which device gets mounted (that behavior depends on what order the devices appear in the device A "band-aid" type fix might be to introduce some way to reverse the order that the buffer is iterated over but it's not obvious how to do this cleanly without changing the Lines 49 to 65 in bc4b778
Perhaps some global state which controls the iteration order could be added and applications could be allowed to modify it. Or, to solve the problem for more than two devices, the function could be altered to iterate through all devices once (rather than breaking immediately) and store the indices of all the "mountable" devices somewhere accessible to callers such that they could then set which one they wanted to access on subsequent calls. This seems a little bit fragile but if the vast majority of users only have one attached USB storage device it may be safe enough (since in that case the new global state would not change user visible behavior at all). If this approach were pursued, you may also need to consider edge cases of devices being inserted / removed between invocations and messing up the indices (although I think the Wii U itself throws some errors if its storage device is removed while the console is powered on so it might be fair to assume that devices are not inserted / removed after power-on). As for other possible solutions, there is already precedent for hardcoded logic that skips devices in Lines 885 to 886 in 46b47a0
All these ideas feel pretty ugly. At this point it's probably worth mentioning that I'm not in need of a fix for this issue since I mainly wanted to prevent future WiiFlow users from struggling through the diagnostic challenge that I just went through and my slightly hacky PR was accepted. My goal in filing this issue here is primarily to document the problem so that other applications relying on |
Hey, sorry my reply took so long. ive been busy with other stuff but did not forget this! first off all, i understand you don't have a need for a fix @kcpants, and it was merged in wiiflow etc but optimally that copy in wiiflow shouldn't exist at all and (correct) fixes should be done in libogc instead. this would benefit everyone, which is the goal here and which is why i would rather see this fixed somehow. that said, think the correct fix would be for applications (and libfat/libfilesystem) to pass the requested partition to the disc interface and ask it to find a certain partition. however, this obviously breaks everything so that will have to wait. would this work in the case you have in your mind? |
Thanks for staying on this! I appreciate your dedication and agree that a solution in The approach you've outlined seems like it would work for the Wii U use case. There may be some challenges though. It sounds like the ID you're planning to use would come from the
Note that there are multiple bytes which map to The other challenge I can think of would be if you want to handle both MBR and GPT partition tables. To mount a drive that has at least one partition which matches the partition type passed in you need
This seems pretty interesting but also looks like it could be a lot to take on. If GPT drives are not supported and its safe to assume all attached drives are MBR then I think the loop in my WiiFlow patch could be adapted to work without too many changes. One final note on MBR / GPT - Wii U apps support USB drives that have been hidden from the Wii U by modifying the MBR signature so if "partition table aware" code were added to
|
@DacoTaco Just wanted to post an update here to mention that a new solution to this problem that does not require reading partition tables has been found (my original fix broke GPT support in WiiFlow so needed to be reverted). Full details can be found in my comment in the WiiFlow issue. To summarize here, the WiiU USB drive appears to be formatted as encrypted GPT without a protective MBR. Info on the protective MBR from Wikipedia:
The new solution ignores drives that do not have an MBR signature (or the modified MBR signature altered by UStealth) rather than ignoring drives without a readable partition (the original code likely only worked because the WiiU drive was GPT, if logic to read GPT partition tables were added the WiiU drive would probably present as "readable"). I don't think code that deals with the layout of the partition table (GPT vs MBR) breaks the abstractions in |
The loop in
usbstorage.c#__usbstorage_IsInserted
(referenced in the first link below) breaks as soon as it finds any USB storage device. If a drive with an unreadable proprietary format (e.g. a Wii U formatted drive) happens to appear ahead of a readable drive (e.g. a FAT32 Wii USB drive) in theusb_device_entry
buffer,usbstorage.c
will mount it and exit the function. This may cause issues in higher level apps which rely on this function to mount a USB storage drive when multiple USB storage drives are connected and some subset of them are in an unreadable proprietary format.libogc/libogc/usbstorage.c
Lines 879 to 917 in 46b47a0
This behavior affected WiiFlow on Wii U as documented in WiiFlow issue 338. WiiFlow contains its own modified copy of this function and a fix for the issue can be viewed in pull request 343. Opening this issue to track the problem in
libogc
and to note that the fix in WiiFlow could be adapted and included here if desired.The text was updated successfully, but these errors were encountered: