mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add a basic Getting Started page (#59)
* Begin adding a samples document * Minor text changes * Update examples * Update usage text
This commit is contained in:
parent
353c538c6b
commit
b92750688e
2 changed files with 130 additions and 1 deletions
16
README.md
16
README.md
|
@ -10,6 +10,10 @@ Most content is imported and exported using a standard `IStorage` interface. Thi
|
||||||
For example, the files from a title stored on the external SD card can be read or extracted in this way.
|
For example, the files from a title stored on the external SD card can be read or extracted in this way.
|
||||||
`NAX0 Reader` -> `NCA Reader` -> `RomFS Reader` -> `Individual Files`
|
`NAX0 Reader` -> `NCA Reader` -> `RomFS Reader` -> `Individual Files`
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
[Library Overview and Samples](docs/getting-started.md)
|
||||||
|
|
||||||
# hactoolnet
|
# hactoolnet
|
||||||
|
|
||||||
hactoolnet is an example program that uses LibHac. It is used in a similar manner to [hactool](https://github.com/SciresM/hactool).
|
hactoolnet is an example program that uses LibHac. It is used in a similar manner to [hactool](https://github.com/SciresM/hactool).
|
||||||
|
@ -21,11 +25,13 @@ Options:
|
||||||
-r, --raw Keep raw data, don't unpack.
|
-r, --raw Keep raw data, don't unpack.
|
||||||
-y, --verify Verify all hashes in the input file.
|
-y, --verify Verify all hashes in the input file.
|
||||||
-h, --enablehash Enable hash checks when reading the input file.
|
-h, --enablehash Enable hash checks when reading the input file.
|
||||||
|
-d, --dev Decrypt with development keys instead of retail.
|
||||||
-k, --keyset Load keys from an external file.
|
-k, --keyset Load keys from an external file.
|
||||||
-t, --intype=type Specify input file type [nca, xci, romfs, pk11, pk21, ini1, kip1, switchfs, save, ndv0, keygen, romfsbuild]
|
-t, --intype=type Specify input file type [nca, xci, romfs, pfs0, pk11, pk21, ini1, kip1, switchfs, save, ndv0, keygen, romfsbuild, pfsbuild]
|
||||||
--titlekeys <file> Load title keys from an external file.
|
--titlekeys <file> Load title keys from an external file.
|
||||||
NCA options:
|
NCA options:
|
||||||
--plaintext <file> Specify file path for saving a decrypted copy of the NCA.
|
--plaintext <file> Specify file path for saving a decrypted copy of the NCA.
|
||||||
|
--header <file> Specify Header file path.
|
||||||
--section0 <file> Specify Section 0 file path.
|
--section0 <file> Specify Section 0 file path.
|
||||||
--section1 <file> Specify Section 1 file path.
|
--section1 <file> Specify Section 1 file path.
|
||||||
--section2 <file> Specify Section 2 file path.
|
--section2 <file> Specify Section 2 file path.
|
||||||
|
@ -46,6 +52,12 @@ RomFS options:
|
||||||
RomFS creation options:
|
RomFS creation options:
|
||||||
Input path must be a directory
|
Input path must be a directory
|
||||||
--outfile <file> Specify created RomFS file path.
|
--outfile <file> Specify created RomFS file path.
|
||||||
|
Partition FS options:
|
||||||
|
--outdir <dir> Specify extracted FS directory path.
|
||||||
|
Partition FS creation options:
|
||||||
|
Input path must be a directory
|
||||||
|
--outfile <file> Specify created Partition FS file path.
|
||||||
|
--hashedfs Create a hashed Partition FS (HFS0).
|
||||||
XCI options:
|
XCI options:
|
||||||
--rootdir <dir> Specify root XCI directory path.
|
--rootdir <dir> Specify root XCI directory path.
|
||||||
--updatedir <dir> Specify update XCI directory path.
|
--updatedir <dir> Specify update XCI directory path.
|
||||||
|
@ -81,7 +93,9 @@ Save data options:
|
||||||
--outdir <dir> Specify directory path to save contents to.
|
--outdir <dir> Specify directory path to save contents to.
|
||||||
--debugoutdir <dir> Specify directory path to save intermediate data to for debugging.
|
--debugoutdir <dir> Specify directory path to save intermediate data to for debugging.
|
||||||
--sign Sign the save file. (Requires device_key in key file)
|
--sign Sign the save file. (Requires device_key in key file)
|
||||||
|
--trim Trim garbage data in the save file. (Requires device_key in key file)
|
||||||
--listfiles List files in save file.
|
--listfiles List files in save file.
|
||||||
|
--repack <dir> Replaces the contents of the save data with the specified directory.
|
||||||
--replacefile <filename in save> <file> Replaces a file in the save data
|
--replacefile <filename in save> <file> Replaces a file in the save data
|
||||||
NDV0 (Delta) options:
|
NDV0 (Delta) options:
|
||||||
Input delta patch can be a delta NCA file or a delta fragment file.
|
Input delta patch can be a delta NCA file or a delta fragment file.
|
||||||
|
|
115
docs/getting-started.md
Normal file
115
docs/getting-started.md
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
# Getting Started
|
||||||
|
|
||||||
|
## LibHac Interfaces
|
||||||
|
|
||||||
|
LibHac uses several interfaces for reading and writing data and files. These are based off the interfaces used by Horizon OS.
|
||||||
|
|
||||||
|
### IStorage
|
||||||
|
|
||||||
|
`IStorage` is an interface that LibHac uses for reading and writing data.
|
||||||
|
An `IStorage` is similar to a .NET `Stream`, but an `IStorage` does not keep track of its position. An offset must be provided on every read.
|
||||||
|
|
||||||
|
`IStorage` uses byte Spans for reading and writing data. The length of the data read or written is equal to the length of the provided span.
|
||||||
|
|
||||||
|
### IFile
|
||||||
|
|
||||||
|
`IFile` is similar to `IStorage` with slight differences.
|
||||||
|
- `IFile` can automatically grow if data is written past the end of the file. `IStorage` does not grow by default.
|
||||||
|
- When more bytes are requested than there are bytes available,
|
||||||
|
`IFile` will read as many bytes as it can and return the number of bytes read. `IStorage` will throw an exception.
|
||||||
|
|
||||||
|
### IFileSystem
|
||||||
|
|
||||||
|
This is an interface for representing a standard file system. It provides functionality for reading files, navigating the file system, creating files, etc.
|
||||||
|
|
||||||
|
## Using LibHac
|
||||||
|
|
||||||
|
### Loading Keys
|
||||||
|
|
||||||
|
Most of LibHac's functionality requires a `Keyset` object that holds encryption keys required for reading content.
|
||||||
|
|
||||||
|
This can be done by loading keys from an external text file, or by creating a new `Keyset` and copying the keys into it.
|
||||||
|
```
|
||||||
|
Keyset keyset = ExternalKeys.ReadKeyFile("common_key_file", "title_key_file", "console_key_file");
|
||||||
|
```
|
||||||
|
|
||||||
|
The text files should follow the format as specified [here](../KEYS.md).
|
||||||
|
|
||||||
|
### Reading an NCA
|
||||||
|
|
||||||
|
Open an NCA and get an `IStorage` of the decrypted file.
|
||||||
|
```
|
||||||
|
using (IStorage inFile = new LocalStorage("filename.nca", FileAccess.Read))
|
||||||
|
{
|
||||||
|
var nca = new Nca(keyset, inFile);
|
||||||
|
|
||||||
|
IStorage decryptedNca = nca.OpenDecryptedNca();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Open an NCA's code section.
|
||||||
|
```
|
||||||
|
using (IStorage inFile = new LocalStorage("filename.nca", FileAccess.Read))
|
||||||
|
{
|
||||||
|
var nca = new Nca(keyset, inFile);
|
||||||
|
|
||||||
|
IStorage section = nca.OpenStorage(NcaSectionType.Code, IntegrityCheckLevel.ErrorOnInvalid);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Open an NCA's data section as an `IFileSystem`.
|
||||||
|
```
|
||||||
|
using (IStorage inFile = new LocalStorage("filename.nca", FileAccess.Read))
|
||||||
|
{
|
||||||
|
var nca = new Nca(keyset, inFile);
|
||||||
|
|
||||||
|
IFileSystem fileSystem = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Extension methods are provided for common operations on LibHac interfaces.
|
||||||
|
|
||||||
|
`IFileSystem.CopyFileSystem` will fully copy the contents of one `IFileSystem` to another.
|
||||||
|
```
|
||||||
|
using (IStorage inFile = new LocalStorage("filename.nca", FileAccess.Read))
|
||||||
|
{
|
||||||
|
var nca = new Nca(keyset, inFile);
|
||||||
|
var outFileSystem = new LocalFileSystem("extracted_path");
|
||||||
|
|
||||||
|
IFileSystem fileSystem = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
|
||||||
|
fileSystem.CopyFileSystem(outFileSystem);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Open a patched NCA.
|
||||||
|
```
|
||||||
|
using (IStorage baseFile = new LocalStorage("base.nca", FileAccess.Read))
|
||||||
|
using (IStorage patchFile = new LocalStorage("base.nca", FileAccess.Read))
|
||||||
|
{
|
||||||
|
var baseNca = new Nca(keyset, baseFile);
|
||||||
|
var patchNca = new Nca(keyset, patchFile);
|
||||||
|
|
||||||
|
IFileSystem fileSystem = baseNca.OpenFileSystemWithPatch(patchNca, NcaSectionType.Data,
|
||||||
|
IntegrityCheckLevel.ErrorOnInvalid);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### IFileSystem Operations
|
||||||
|
|
||||||
|
Open a file and read the first 0x4000 bytes.
|
||||||
|
```
|
||||||
|
using (IStorage inFile = new LocalStorage("filename.nca", FileAccess.Read))
|
||||||
|
{
|
||||||
|
var nca = new Nca(keyset, inFile);
|
||||||
|
IFileSystem fileSystem = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
|
||||||
|
|
||||||
|
var buffer = new byte[0x4000];
|
||||||
|
|
||||||
|
IFile myFile = fileSystem.OpenFile("/my/file/path.ext", OpenMode.Read);
|
||||||
|
int bytesRead = myFile.Read(buffer, 0);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
An `IDirectory` can be used to enumerate the file system entries in a directory.
|
||||||
|
|
||||||
|
...
|
Loading…
Reference in a new issue