jakcron / nstool

General purpose read/extract tool for Nintendo Switch file formats.
MIT License
450 stars 43 forks source link

[Bug] Extracting single file - access denied #101

Open Clearmist opened 1 year ago

Clearmist commented 1 year ago

Version: 1.7.0 Built: 15:09:37 Jan 21 2023 OS: Windows 11

I thoroughly read the documentation about extracting files. I am unable to extract single files from any archive without editing your source code. Even when the program absolutely has write access to the given directory an access is denied error is thrown. This line in FsProcess.cpp is the culprit. I commented out this line and the first try/catch and the file was extracted successfully.

https://github.com/jakcron/nstool/blob/7abcedb7e5d1765616f8d27e8b9be3543c489997/src/FsProcess.cpp#L151

https://github.com/jakcron/nstool/blob/7abcedb7e5d1765616f8d27e8b9be3543c489997/src/FsProcess.cpp#L121-L135

This means we need to clarify and separate some parameters so we can rely on separate functions instead of one big function.

Perhaps:

-x --extract: Extract all files or extract a single file if an optional value is supplied.
-o --output: Specify the output path.
-n --name: Overwrite the original file name with one you supply.

Extract all files:
.\nstool --output "./files" --extract

Extract one file:
.\nstool --output "./files" --extract "f79d12018da9db962f796fad2256fdfb.cnmt.nca"

Extract one file and give it a new name:
.\nstool --output "./files" --extract "f79d12018da9db962f796fad2256fdfb.cnmt.nca" --name "meta.nca"

Confirming this is a valid file

.\nstool.exe --fstree "test.nsp"

[PartitionFs]
  Type:        PFS0
  FileNum:     6
[PartitionFs/Tree]
 Root:/
  0100100016fb0000000000000000000e.tik
  0100100016fb0000000000000000000e.cert
  f79d12018da9db962f796fad2256fdfb.cnmt.nca
  b129954666b4baa187ad57e15cd87e49.nca
  5fb8eb95a47d349cfd0d7bfab12c2674.nca
  65a1ed53bb896c71ec9e6af3568f6a59.nca

Extracting all files is successful

.\nstool.exe --extract "./" "test.nsp"

[PartitionFs]
  Type:        PFS0
  FileNum:     6
[PartitionFs/Extract]
Saving .\0100100016fb0000000000000000000e.tik...
Saving .\0100100016fb0000000000000000000e.cert...
Saving .\f79d12018da9db962f796fad2256fdfb.cnmt.nca...
Saving .\b129954666b4baa187ad57e15cd87e49.nca...
Saving .\5fb8eb95a47d349cfd0d7bfab12c2674.nca...
Saving .\65a1ed53bb896c71ec9e6af3568f6a59.nca...

Extracting a single file fails

.\nstool.exe --extract "f79d12018da9db962f796fad2256fdfb.cnmt.nca" "./" "test.nsp"

[PartitionFs/Extract]
[tc::io::FileStream::open() ERROR] Access is denied.
jakcron commented 1 year ago

Hi,

Thank you for this well written bug report. (And debugging the issue for me)

I think I was too ambitious with the the extract command making it too versatile. Resulting in weird bugs.

This means we need to clarify and separate some parameters so we can rely on separate functions instead of one big function.

You are make a good point. I'll consider making more explicit commands instead of just fixing the uncaught exception.

Clearmist commented 1 year ago

I built from commit 17b40911aefabfbc7fd2b57e2197e83d753dd2df on the bugfix-101-fs-extraction-issues branch and these are the new results.

Providing an output directory

.\nstool.exe --extract "f79d12018da9db962f796fad2256fdfb.cnmt.nca" "D:\Switch\images" "test.nsp"

[WARNING] Extract path was invalid, and was skipped: D:\Switch\images

Providing an output directory and output filename

.\nstool.exe --extract "f79d12018da9db962f796fad2256fdfb.cnmt.nca" "D:\Switch\images\extract.nca" "test.nsp"

[tc::io::LocalFileSystem::getDirectoryListing() ERROR] Failed to open directory (The directory name is invalid.)

TsilaAllaoui commented 1 year ago

Hi, i have the same problem when extracting a single file from a nsp. Which branch or PR have the modified code that i can test please? I only want to get cmnt.nca and the nca that contain the game icon by the way

VolkerSchlegel commented 11 months ago

Also encountering this one, I'll try that branch.

VolkerSchlegel commented 11 months ago

Building with Visual Studio is broken as well.