Skip to content

Commit

Permalink
fixes to support Windows: always change paths to lowercase, return 65…
Browse files Browse the repository at this point in the history
…792 for st_uid/st_gid (means "Everyone" it seems), add links to osxfuse/WinFsp
  • Loading branch information
ihaveamac committed Sep 2, 2017
1 parent bea9e25 commit 479d248
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 11 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ ARM9 bootROM required. Checked in order of:
* `~/.3ds/boot9.bin` (full)
* `~/.3ds/boot9_prot.bin` (protected)

Requires Python 3.5+, [fusepy](https://github.com/terencehonles/fusepy), and [pycryptodomex](https://github.com/Legrandin/pycryptodome).
Requires Python 3.5+, [fusepy](https://github.com/billziss-gh/fusepy), and [pycryptodomex](https://github.com/Legrandin/pycryptodome).
* macOS users require [OSXFuse](https://osxfuse.github.io).
* Windows users require [WinFsp](http://www.secfs.net/winfsp/). Windows is currently not extensively tested. Keep backups before writing.

## mount_nand.py
Mounts NAND images. Can read essentials backup by GodMode9, else OTP file/NAND CID must be provided in arguments.
Expand Down
31 changes: 22 additions & 9 deletions mount_nand.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,12 @@ def check_b9_file(path):
self.g_stat['st_ctime'] = int(nand_stat.st_ctime)
self.g_stat['st_mtime'] = int(nand_stat.st_mtime)
self.g_stat['st_atime'] = int(nand_stat.st_atime)
if os.name == 'nt':
self.g_stat['st_uid'] = 65792 # "Everyone"
self.g_stat['st_gid'] = 65792
else:
self.g_stat['st_uid'] = int(nand_stat.st_uid)
self.g_stat['st_gid'] = int(nand_stat.st_gid)

self.f.seek(0, 2)
raw_nand_size = self.f.tell()
Expand Down Expand Up @@ -290,45 +296,53 @@ def check_b9_file(path):

self.fd = 0

if os.name == 'nt':
print('NOTE: Windows is currently not extensively tested. Keep backups before writing.')

def __del__(self):
self.f.close()

def flush(self, path, fh):
return None

def getattr(self, path, fh=None):
if path == '/':
st = {'st_mode': (stat.S_IFDIR | (0o555 if a.ro else 0o755)), 'st_nlink': 2}
elif path in self.files:
st = {'st_mode': (stat.S_IFREG | (0o444 if a.ro else 0o644)), 'st_size': self.files[path]['size'], 'st_nlink': 1}
st = {'st_mode': (stat.S_IFDIR | (0o555 if a.ro else 0o777)), 'st_nlink': 2}
elif path.lower() in self.files:
st = {'st_mode': (stat.S_IFREG | (0o444 if a.ro else 0o666)), 'st_size': self.files[path.lower()]['size'], 'st_nlink': 1}
else:
raise FuseOSError(errno.ENOENT)
return {**st, **self.g_stat}

def getxattr(self, path, name, position=0):
attrs = self.getattr(path)
attrs = self.getattr(path.lower())
try:
return str(attrs[name])
except KeyError:
raise FuseOSError(errno.ENOATTR)

def listxattr(self, path):
attrs = self.getattr(path)
attrs = self.getattr(path.lower())
try:
return attrs.keys()
except KeyError:
raise FuseOSError(errno.ENOATTR)

def release(self, path, fh):
return None

def statfs(self, path):
return {'f_bsize': 4096, 'f_blocks': self.real_nand_size // 4096, 'f_bavail': 0, 'f_bfree': 0}

def open(self, path, flags):
# wat?
self.fd += 1
return self.fd

def readdir(self, path, fh):
return ['.', '..'] + [x[1:] for x in self.files]

def read(self, path, size, offset, fh):
fi = self.files[path]
fi = self.files[path.lower()]
real_offset = fi['offset'] + offset
if fi['type'] == 'raw':
self.f.seek(real_offset)
Expand All @@ -349,7 +363,6 @@ def read(self, path, size, offset, fh):
data = cipher.decrypt(data)[before:len(data) - after]

elif fi['type'] == 'twl':
pass
self.f.seek(real_offset)
data = self.f.read(size)
# thanks Stary2001
Expand All @@ -369,7 +382,7 @@ def read(self, path, size, offset, fh):
return data

def write(self, path, data, offset, fh):
fi = self.files[path]
fi = self.files[path.lower()]
real_offset = fi['offset'] + offset
real_len = len(data)
if offset >= fi['size']:
Expand Down
1 change: 0 additions & 1 deletion mount_sd.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,5 +157,4 @@ def write(self, path, data, offset, fh):
a = parser.parse_args()

# logging.basicConfig(level=logging.DEBUG)

fuse = FUSE(SDFilesystem(), a.mount_point, foreground=a.fg, ro=True)

0 comments on commit 479d248

Please sign in to comment.