Skip to content

Commit 65b26c4

Browse files
committed
Dell PFS BIOS Extractor v4.6
Fixed crash when PFS filenames include Windows reserved characters Fixed PFS Entry Version Type display typo, thanks to @vuquangtrong
1 parent e61e4b7 commit 65b26c4

File tree

1 file changed

+11
-10
lines changed

1 file changed

+11
-10
lines changed

Dell PFS BIOS Extractor/Dell_PFS_Extract.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
Inspired from https://github.com/LongSoft/PFSExtractor-RS by Nikolaj Schlej
88
"""
99

10-
title = 'Dell PFS BIOS Extractor v4.5'
10+
title = 'Dell PFS BIOS Extractor v4.6'
1111

1212
import os
1313
import re
@@ -74,7 +74,7 @@ class PFS_ENTRY(ctypes.LittleEndianStructure) :
7474

7575
def pfs_print(self) :
7676
GUID = ''.join('%0.8X' % int.from_bytes(struct.pack('<I', val), 'little') for val in reversed(self.GUID))
77-
VersionType = ''.join('%0.4X' % int.from_bytes(struct.pack('<I', val), 'little') for val in reversed(self.VersionType))
77+
VersionType = ''.join('%0.2X' % int.from_bytes(struct.pack('<I', val), 'little') for val in reversed(self.VersionType))
7878
Version = ''.join('%0.4X' % int.from_bytes(struct.pack('<I', val), 'little') for val in reversed(self.Version))
7979
Unknown = ''.join('%0.8X' % int.from_bytes(struct.pack('<I', val), 'little') for val in reversed(self.Unknown))
8080

@@ -108,7 +108,7 @@ class PFS_ENTRY_R2(ctypes.LittleEndianStructure) :
108108

109109
def pfs_print(self) :
110110
GUID = ''.join('%0.8X' % int.from_bytes(struct.pack('<I', val), 'little') for val in reversed(self.GUID))
111-
VersionType = ''.join('%0.4X' % int.from_bytes(struct.pack('<I', val), 'little') for val in reversed(self.VersionType))
111+
VersionType = ''.join('%0.2X' % int.from_bytes(struct.pack('<I', val), 'little') for val in reversed(self.VersionType))
112112
Version = ''.join('%0.4X' % int.from_bytes(struct.pack('<I', val), 'little') for val in reversed(self.Version))
113113
Unknown = ''.join('%0.8X' % int.from_bytes(struct.pack('<I', val), 'little') for val in reversed(self.Unknown))
114114

@@ -634,7 +634,8 @@ def pfs_extract(buffer, pfs_index, pfs_name, pfs_count) :
634634

635635
data_ext = '.data.bin' if is_advanced else '.bin' # Simpler Data Extension for non-advanced users
636636
meta_ext = '.meta.bin' if is_advanced else '.bin' # Simpler Metadata Extension for non-advanced users
637-
full_name = '%d%s -- %d %s v%s' % (pfs_index, pfs_name, file_index, file_name, file_version)
637+
full_name = '%d%s -- %d %s v%s' % (pfs_index, pfs_name, file_index, file_name, file_version) # Full Entry Name
638+
safe_name = re.sub(r'[\\/*?:"<>|]', '_', full_name) # Replace common Windows reserved/illegal filename characters
638639

639640
is_zlib = True if file_type == 'ZLIB' else False # Determine if PFS Entry Data was zlib-compressed
640641

@@ -644,13 +645,13 @@ def pfs_extract(buffer, pfs_index, pfs_name, pfs_count) :
644645
# Some Data may be Text or XML files with useful information for non-advanced users
645646
is_text, final_data, file_ext, write_mode = bin_is_text(file_data, file_type, False, is_advanced)
646647

647-
final_name = '%s%s' % (full_name, data_ext[:-4] + file_ext if is_text else data_ext)
648+
final_name = '%s%s' % (safe_name, data_ext[:-4] + file_ext if is_text else data_ext)
648649
final_path = os.path.join(output_path, final_name)
649650

650651
with open(final_path, write_mode) as o : o.write(final_data) # Write final Data
651652

652653
if file_data_sig and is_advanced : # Store Data Signature (advanced users only)
653-
final_name = '%s.data.sig' % full_name
654+
final_name = '%s.data.sig' % safe_name
654655
final_path = os.path.join(output_path, final_name)
655656

656657
with open(final_path, 'wb') as o : o.write(file_data_sig) # Write final Data Signature
@@ -661,13 +662,13 @@ def pfs_extract(buffer, pfs_index, pfs_name, pfs_count) :
661662
# Some Data may be Text or XML files with useful information for non-advanced users
662663
is_text, final_data, file_ext, write_mode = bin_is_text(file_meta, file_type, True, is_advanced)
663664

664-
final_name = '%s%s' % (full_name, meta_ext[:-4] + file_ext if is_text else meta_ext)
665+
final_name = '%s%s' % (safe_name, meta_ext[:-4] + file_ext if is_text else meta_ext)
665666
final_path = os.path.join(output_path, final_name)
666667

667668
with open(final_path, write_mode) as o : o.write(final_data) # Write final Data Metadata
668669

669670
if file_meta_sig and is_advanced : # Store Metadata Signature (advanced users only)
670-
final_name = '%s.meta.sig' % full_name
671+
final_name = '%s.meta.sig' % safe_name
671672
final_path = os.path.join(output_path, final_name)
672673

673674
with open(final_path, 'wb') as o : o.write(file_meta_sig) # Write final Data Metadata Signature
@@ -770,7 +771,7 @@ def show_exception_and_exit(exc_type, exc_value, tb) :
770771

771772
sys.exit(1)
772773

773-
# Set pause-able Python exception hander
774+
# Set pause-able Python exception handler
774775
sys.excepthook = show_exception_and_exit
775776

776777
# Show script title
@@ -824,7 +825,7 @@ def show_exception_and_exit(exc_type, exc_value, tb) :
824825
input_name,input_extension = os.path.splitext(os.path.basename(input_file))
825826
input_dir = os.path.dirname(os.path.abspath(input_file))
826827

827-
print('\nFile: %s%s' % (input_name, input_extension))
828+
print('\n*** %s%s' % (input_name, input_extension))
828829

829830
# Check if input file exists
830831
if not os.path.isfile(input_file) :

0 commit comments

Comments
 (0)