Skip to content

Commit 7e0bdfc

Browse files
committed
Add root_prefix arg to get_installed_packages #2614
* The root prefix will be passed into get_installed_packages instead of assuming that the root_prefix is always "Files" * Update win_pe extensions * Update test files Signed-off-by: Jono Yang <jyang@nexb.com>
1 parent 3a1c182 commit 7e0bdfc

5 files changed

Lines changed: 72 additions & 46 deletions

File tree

src/packagedcode/win_pe.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -225,14 +225,22 @@ def pe_info(location):
225225
class WindowsExecutable(models.Package):
226226
metafiles = ()
227227
extensions = (
228-
'.exe*',
229-
'.dll*',
230-
'.mui*',
231-
'.mun*',
232-
'.com*',
233-
'.winmd*',
234-
'.sys*',
235-
'.tlb*',
228+
'.exe',
229+
'.dll',
230+
'.mui',
231+
'.mun',
232+
'.com',
233+
'.winmd',
234+
'.sys',
235+
'.tlb',
236+
'.exe_*',
237+
'.dll_*',
238+
'.mui_*',
239+
'.mun_*',
240+
'.com_*',
241+
'.winmd_*',
242+
'.sys_*',
243+
'.tlb_*',
236244
)
237245
filetypes = ('pe32', 'for ms windows',)
238246
mimetypes = ('application/x-dosexec',)

src/packagedcode/win_reg.py

Lines changed: 56 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -227,19 +227,38 @@ def get_installed_packages(root_dir, is_container=True):
227227
"""
228228
# These paths are relative to a Windows docker image layer root directory
229229
if is_container:
230-
software_registry_locations = [
231-
os.path.join(root_dir, 'Hives', 'Software_Delta'),
232-
os.path.join(root_dir, 'Files', 'Windows', 'System32', 'config', 'SOFTWARE')
233-
]
230+
hives_software_delta_loc = os.path.join(root_dir, 'Hives', 'Software_Delta')
231+
files_software_loc = os.path.join(
232+
root_dir,
233+
'Files',
234+
'Windows',
235+
'System32',
236+
'config',
237+
'SOFTWARE'
238+
)
239+
utilityvm_software_loc = os.path.join(
240+
root_dir,
241+
'UtilityVM',
242+
'Files',
243+
'Windows',
244+
'System32',
245+
'config',
246+
'SOFTWARE'
247+
)
248+
root_prefixes_by_software_registry_locations = {
249+
hives_software_delta_loc: 'Files',
250+
files_software_loc: 'Files',
251+
utilityvm_software_loc: os.path.join('UtilityVM', 'Files')
252+
}
234253
else:
235254
# TODO: Add support for virtual machines
236255
raise Exception('Unsuported file system type')
237256

238-
for software_registry_loc in software_registry_locations:
257+
for software_registry_loc, root_prefix in root_prefixes_by_software_registry_locations.items():
239258
if not os.path.exists(software_registry_loc):
240259
continue
241260
for package in reg_parse(software_registry_loc):
242-
package.populate_installed_files(root_dir, is_container=is_container)
261+
package.populate_installed_files(root_dir, root_prefix=root_prefix)
243262
yield package
244263

245264

@@ -266,16 +285,27 @@ def create_absolute_installed_file_path(root_dir, file_path):
266285
return str(Path(root_dir).joinpath(file_path))
267286

268287

269-
def create_relative_file_path(file_path, root_dir):
288+
def create_relative_file_path(file_path, root_dir, root_prefix=''):
270289
"""
271290
Return a subpath of `file_path` that is relative to `root_dir`
272291
273292
>>> file_path = '/home/test/example/foo.txt'
274293
>>> root_dir = '/home/test/'
275294
>>> create_relative_file_path(file_path, root_dir)
276295
'example/foo.txt'
296+
297+
If there is a `root_prefix`, then it is prepended to the resulting
298+
relative file path.
299+
300+
>>> file_path = '/home/test/example/foo.txt'
301+
>>> root_dir = '/home/test/'
302+
>>> create_relative_file_path(file_path, root_dir, 'prefix')
303+
'prefix/example/foo.txt'
277304
"""
278-
return str(Path(file_path).relative_to(root_dir))
305+
relative_file_path = str(Path(file_path).relative_to(root_dir))
306+
if root_prefix:
307+
return os.path.join(root_prefix, relative_file_path)
308+
return relative_file_path
279309

280310

281311
@attr.s()
@@ -287,20 +317,18 @@ def recognize(cls, location):
287317
for installed in reg_parse(location):
288318
yield installed
289319

290-
def populate_installed_files(self, root_dir, is_container=False):
320+
def populate_installed_files(self, root_dir, root_prefix=''):
291321
install_location = self.extra_data.get('install_location')
292322
if not install_location:
293323
return
294324

295-
if is_container:
296-
original_root_dir = root_dir
297-
# If we are getting installed files from `root_dir` that is a
298-
# Windows Docker layer path, we are setting the root to be the
299-
# `Files` directory, since this directory represents the root `C:\`
300-
# drive of a Windows installation.
301-
# e.g. given a Windows Docker layer named `windows_docker_layer_id`,
302-
# the files are stored in the subdirectory `windows_docker_layer_id/Files`
303-
root_dir = os.path.join(root_dir, 'Files')
325+
if root_prefix:
326+
# The rootfs location of a Docker image layer can be in a
327+
# subdirectory of the layer directory (where `root_dir` is the path
328+
# to the layer directory), so we append `root_prefix` (where prefix
329+
# is relative to the file paths within the Docker image layer's
330+
# rootfs files) to `root_dir`
331+
root_dir = os.path.join(root_dir, root_prefix)
304332

305333
absolute_install_location = create_absolute_installed_file_path(
306334
root_dir=root_dir,
@@ -313,16 +341,11 @@ def populate_installed_files(self, root_dir, is_container=False):
313341
for root, _, files in os.walk(absolute_install_location):
314342
for file in files:
315343
installed_file_location = os.path.join(root, file)
316-
if is_container:
317-
relative_installed_file_path = create_relative_file_path(
318-
file_path=installed_file_location,
319-
root_dir=original_root_dir
320-
)
321-
else:
322-
relative_installed_file_path = create_relative_file_path(
323-
file_path=installed_file_location,
324-
root_dir=root_dir
325-
)
344+
relative_installed_file_path = create_relative_file_path(
345+
file_path=installed_file_location,
346+
root_dir=root_dir,
347+
root_prefix=root_prefix
348+
)
326349
installed_files.append(relative_installed_file_path)
327350

328351
known_program_files = self.extra_data.get('known_program_files', [])
@@ -331,16 +354,11 @@ def populate_installed_files(self, root_dir, is_container=False):
331354
root_dir=root_dir,
332355
file_path=known_program_file_path,
333356
)
334-
if is_container:
335-
relative_known_file_path = create_relative_file_path(
336-
file_path=known_program_file_location,
337-
root_dir=original_root_dir
338-
)
339-
else:
340-
relative_known_file_path = create_relative_file_path(
341-
file_path=known_program_file_location,
342-
root_dir=root_dir
343-
)
357+
relative_known_file_path = create_relative_file_path(
358+
file_path=known_program_file_location,
359+
root_dir=root_dir,
360+
root_prefix=root_prefix
361+
)
344362
if (not os.path.exists(known_program_file_location)
345363
or relative_known_file_path in installed_files):
346364
continue

tests/packagedcode/data/win_reg/get_installed_packages_docker/layer/Files/Program Files (x86)/Test2/Test2.dat

Whitespace-only changes.

tests/packagedcode/data/win_reg/get_installed_packages_docker/layer/Files/Program Files (x86)/Test2/Test2.exe

Whitespace-only changes.

tests/packagedcode/data/win_reg/get_installed_packages_docker/layer/Files/Program Files (x86)/Test2/Uninstall.exe

Whitespace-only changes.

0 commit comments

Comments
 (0)