mirror of
https://github.com/Maschell/fuse-wiiu.git
synced 2024-11-22 14:39:15 +01:00
Add support to access the original WUD if the input was compressed (WUX) or splitted (_partX.wud)
This commit is contained in:
parent
c7f65b2e08
commit
889b790afd
@ -90,7 +90,7 @@ It's possible to use any directory as input, `fuse-wiiu` will scan will useable
|
|||||||
If a supported format is found and successfully mounted, a support starting with `[EMULATED] ` will be emulated, which will give you access to the files. The actual content and file layout may differ from format to format.
|
If a supported format is found and successfully mounted, a support starting with `[EMULATED] ` will be emulated, which will give you access to the files. The actual content and file layout may differ from format to format.
|
||||||
|
|
||||||
## Wii U disc images - WUD/WUX
|
## Wii U disc images - WUD/WUX
|
||||||
Images of Wii U discs are saved `.wud` (or `.wux` if compressed). Every .wux or .wud will be emulated as two different directories (for image names `game.wux`).
|
Images of Wii U discs are saved `.wud` (or `.wux` if compressed, or `game_partX.wud` when dumped on FAT32). Every .wux or .wud will be emulated as up to three different directories (for image names `game.wux`).
|
||||||
|
|
||||||
- [EMULATED] game.wux
|
- [EMULATED] game.wux
|
||||||
- This directory is the "normal" representation of a Wii U disc image. It'll have one subfolder for each partition. The `GM`-Partitions will be mounted and decrypted directly in the common `code, content and meta` format. The `SI` contain the ticket and tmd for `GM` partitions. All other partitions give you files in the "installable" format (tmd,app,tik).
|
- This directory is the "normal" representation of a Wii U disc image. It'll have one subfolder for each partition. The `GM`-Partitions will be mounted and decrypted directly in the common `code, content and meta` format. The `SI` contain the ticket and tmd for `GM` partitions. All other partitions give you files in the "installable" format (tmd,app,tik).
|
||||||
@ -99,6 +99,8 @@ Images of Wii U discs are saved `.wud` (or `.wux` if compressed). Every .wux or
|
|||||||
- The `GM` partitions in the "installable" format. (Folders with the prefix `[ENCRYPTED] `)
|
- The `GM` partitions in the "installable" format. (Folders with the prefix `[ENCRYPTED] `)
|
||||||
- Mounted and decrypted titles from all partitions. (Folder with the prefix `[DECRYPTED] [PARTITIONNAME]`)
|
- Mounted and decrypted titles from all partitions. (Folder with the prefix `[DECRYPTED] [PARTITIONNAME]`)
|
||||||
- This includes titles from the non-`GM` partitions (like updates), and installable titles from the decrypted `GM` partitions (titles from kiosk discs).
|
- This includes titles from the non-`GM` partitions (like updates), and installable titles from the decrypted `GM` partitions (titles from kiosk discs).
|
||||||
|
- [EMULATED] [WUD] game.wux (Only for WUX and splitted WUD)
|
||||||
|
- In this directory you can access Wii U disc image as the orginal WUD.
|
||||||
|
|
||||||
Expected file layout:
|
Expected file layout:
|
||||||
```
|
```
|
||||||
|
@ -0,0 +1,113 @@
|
|||||||
|
package de.mas.wiiu.jnus.fuse_wiiu.implementation;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import de.mas.wiiu.jnus.fuse_wiiu.interfaces.FuseContainer;
|
||||||
|
import de.mas.wiiu.jnus.fuse_wiiu.interfaces.FuseDirectory;
|
||||||
|
import de.mas.wiiu.jnus.fuse_wiiu.utils.WUDUtils;
|
||||||
|
import de.mas.wiiu.jnus.implementations.wud.WUDImage;
|
||||||
|
import de.mas.wiiu.jnus.implementations.wud.parser.WUDInfo;
|
||||||
|
import jnr.ffi.Pointer;
|
||||||
|
import ru.serce.jnrfuse.ErrorCodes;
|
||||||
|
import ru.serce.jnrfuse.FuseFillDir;
|
||||||
|
import ru.serce.jnrfuse.struct.FileStat;
|
||||||
|
import ru.serce.jnrfuse.struct.FuseFileInfo;
|
||||||
|
|
||||||
|
public class WUDToWUDContainer implements FuseContainer {
|
||||||
|
private final String filename;
|
||||||
|
private final Optional<WUDInfo> wudInfo;
|
||||||
|
private final Optional<FuseDirectory> parent;
|
||||||
|
|
||||||
|
public WUDToWUDContainer(Optional<FuseDirectory> parent, File c) {
|
||||||
|
this.wudInfo = WUDUtils.loadWUDInfo(c);
|
||||||
|
this.parent = parent;
|
||||||
|
this.filename = c.getName().replace("_part1.", ".").replace(".wux", ".wud");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<FuseDirectory> getParent() {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getattr(String path, FileStat stat) {
|
||||||
|
if (path.equals("/")) {
|
||||||
|
stat.st_mode.set(FileStat.S_IFDIR | 0755);
|
||||||
|
stat.st_nlink.set(2);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.equals("/" + filename)) {
|
||||||
|
if (stat != null) {
|
||||||
|
stat.st_mode.set(FileStat.S_IFREG | FileStat.ALL_READ);
|
||||||
|
stat.st_nlink.set(1);
|
||||||
|
stat.st_size.set(WUDImage.WUD_FILESIZE);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ErrorCodes.ENOENT();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int open(String path, FuseFileInfo fi) {
|
||||||
|
if (path.equals("/")) {
|
||||||
|
return -ErrorCodes.EISDIR();
|
||||||
|
}
|
||||||
|
return getattr(path, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int readdir(String path, Pointer buf, FuseFillDir filter, long offset, FuseFileInfo fi) {
|
||||||
|
filter.apply(buf, ".", null, 0);
|
||||||
|
if (getParent().isPresent()) {
|
||||||
|
filter.apply(buf, "..", null, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wudInfo.isPresent()) {
|
||||||
|
filter.apply(buf, filename, null, 0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(String path, Pointer buf, long size, long offset, FuseFileInfo fi) {
|
||||||
|
if (path.equals("/")) {
|
||||||
|
return -ErrorCodes.EISDIR();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!path.equals("/" + filename)) {
|
||||||
|
return -ErrorCodes.ENOENT();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset >= WUDImage.WUD_FILESIZE) {
|
||||||
|
return -ErrorCodes.ENOENT();
|
||||||
|
}
|
||||||
|
if (offset + size > WUDImage.WUD_FILESIZE) {
|
||||||
|
size = WUDImage.WUD_FILESIZE - offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
byte[] data;
|
||||||
|
data = wudInfo.get().getWUDDiscReader().readEncryptedToByteArray(offset, 0, size);
|
||||||
|
buf.put(0, data, 0, data.length);
|
||||||
|
return data.length;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return -ErrorCodes.ENOENT();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
// Not used
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deinit() {
|
||||||
|
// Not used
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -10,6 +10,7 @@ import de.mas.wiiu.jnus.fuse_wiiu.implementation.LocalBackupNUSTitleContainer;
|
|||||||
import de.mas.wiiu.jnus.fuse_wiiu.implementation.LocalNUSTitleContainer;
|
import de.mas.wiiu.jnus.fuse_wiiu.implementation.LocalNUSTitleContainer;
|
||||||
import de.mas.wiiu.jnus.fuse_wiiu.implementation.WUDFuseContainer;
|
import de.mas.wiiu.jnus.fuse_wiiu.implementation.WUDFuseContainer;
|
||||||
import de.mas.wiiu.jnus.fuse_wiiu.implementation.WUDMountedFuseContainer;
|
import de.mas.wiiu.jnus.fuse_wiiu.implementation.WUDMountedFuseContainer;
|
||||||
|
import de.mas.wiiu.jnus.fuse_wiiu.implementation.WUDToWUDContainer;
|
||||||
import de.mas.wiiu.jnus.fuse_wiiu.interfaces.FuseContainer;
|
import de.mas.wiiu.jnus.fuse_wiiu.interfaces.FuseContainer;
|
||||||
import de.mas.wiiu.jnus.fuse_wiiu.interfaces.FuseDirectory;
|
import de.mas.wiiu.jnus.fuse_wiiu.interfaces.FuseDirectory;
|
||||||
import de.mas.wiiu.jnus.implementations.wud.reader.WUDDiscReaderSplitted;
|
import de.mas.wiiu.jnus.implementations.wud.reader.WUDDiscReaderSplitted;
|
||||||
@ -60,6 +61,9 @@ public class FuseContainerWrapper {
|
|||||||
|
|
||||||
result.put(prefix + c.getName(), new WUDFuseContainer(parent, c));
|
result.put(prefix + c.getName(), new WUDFuseContainer(parent, c));
|
||||||
result.put(prefix + "[EXTRA] " + c.getName(), new WUDMountedFuseContainer(parent, c));
|
result.put(prefix + "[EXTRA] " + c.getName(), new WUDMountedFuseContainer(parent, c));
|
||||||
|
if (c.getName().endsWith("part1.wud") || c.getName().endsWith(".wux")) {
|
||||||
|
result.put(prefix + "[WUD] " + c.getName(), new WUDToWUDContainer(parent, c));
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user