@@ -164,8 +164,9 @@ def GetRootKey(self):
164
164
self ._current_control_set_key_path )
165
165
166
166
registry_key = VirtualREGFWinRegistryKey (
167
- '' , regf_key , current_control_set_key = current_control_set_key ,
168
- key_path = self ._key_path_prefix )
167
+ '' , regf_key , key_path = self ._key_path_prefix )
168
+ registry_key .AddVirtualSubKey (
169
+ 'CurrentControlSet' , current_control_set_key )
169
170
170
171
else :
171
172
registry_key = REGFWinRegistryKey (
@@ -327,25 +328,23 @@ def GetValueByName(self, name):
327
328
class VirtualREGFWinRegistryKey (REGFWinRegistryKey ):
328
329
"""Implementation of a virtual Windows Registry key using pyregf.
329
330
330
- The virtual Windows Registry key are keys that do not exist on-disk but do
331
- exist at run-time, for example HKEY_LOCAL_MACHINE\\ System\\ CurrentControlSet.
331
+ Virtual Windows Registry key are used to handle keys that do not exist on-disk
332
+ but do exist at run-time, like HKEY_LOCAL_MACHINE\\ System\\ CurrentControlSet.
332
333
"""
333
334
334
- def __init__ (
335
- self , name , pyregf_key , current_control_set_key = None , key_path = '' ):
335
+ def __init__ (self , name , pyregf_key , key_path = '' ):
336
336
"""Initializes a virtual Windows Registry key.
337
337
338
338
Args:
339
339
name (str): name of the Windows Registry key.
340
340
pyregf_key (pyregf.key): pyregf key object.
341
- current_control_set_key (Optional[pyregf.key]): pyregf key object of
342
- the control set key that represents CurrentControlSet.
343
341
key_path (Optional[str]): Windows Registry key path.
344
342
"""
345
343
super (VirtualREGFWinRegistryKey , self ).__init__ (
346
344
pyregf_key , key_path = key_path )
347
- self ._current_control_set_key = current_control_set_key
348
345
self ._name = name
346
+ self ._virtual_subkeys = []
347
+ self ._virtual_subkeys_by_name = {}
349
348
350
349
@property
351
350
def name (self ):
@@ -356,10 +355,43 @@ def name(self):
356
355
def number_of_subkeys (self ):
357
356
"""int: number of subkeys within the key."""
358
357
number_of_keys = self ._pyregf_key .number_of_sub_keys
359
- if self ._current_control_set_key :
360
- number_of_keys += 1
358
+ if self ._virtual_subkeys :
359
+ number_of_keys += len ( self . _virtual_subkeys )
361
360
return number_of_keys
362
361
362
+ def _GetVirtualSubKey (self , name ):
363
+ """Retrieves a virtual subkey.
364
+
365
+ Args:
366
+ name (str): name of the Windows Registry subkey.
367
+
368
+ Raises:
369
+ tuple[str, pyregf.key]: name and pyregf key object of the subkey.
370
+ """
371
+ lookup_name = name .upper ()
372
+ subkey_index = self ._virtual_subkeys_by_name .get (lookup_name , None )
373
+ if subkey_index is None :
374
+ return None , None
375
+
376
+ return self ._virtual_subkeys [subkey_index ]
377
+
378
+ def AddVirtualSubKey (self , name , subkey ):
379
+ """Adds a virtual subkey.
380
+
381
+ Args:
382
+ name (str): name of the Windows Registry subkey.
383
+ subkey (pyregf.key): pyregf key object of the subkey.
384
+
385
+ Raises:
386
+ ValueError: if the subkey already exists.
387
+ """
388
+ lookup_name = name .upper ()
389
+ if lookup_name in self ._virtual_subkeys_by_name :
390
+ raise ValueError (f'Subkey: { name :s} already set' )
391
+
392
+ self ._virtual_subkeys_by_name [lookup_name ] = len (self ._virtual_subkeys )
393
+ self ._virtual_subkeys .append ((name , subkey ))
394
+
363
395
def GetSubkeyByIndex (self , index ):
364
396
"""Retrieves a subkey by index.
365
397
@@ -375,16 +407,20 @@ def GetSubkeyByIndex(self, index):
375
407
if index < 0 or index >= self .number_of_subkeys :
376
408
raise IndexError ('Index out of bounds.' )
377
409
378
- if (self ._current_control_set_key and
379
- index == self ._pyregf_key .number_of_sub_keys ):
380
- name = 'CurrentControlSet'
381
- key_path = key_paths .JoinKeyPath ([self ._key_path , name ])
382
- return VirtualREGFWinRegistryKey (
383
- name , self ._current_control_set_key , key_path = key_path )
410
+ if index < self ._pyregf_key .number_of_sub_keys :
411
+ pyregf_key = self ._pyregf_key .get_sub_key (index )
412
+ key_path = key_paths .JoinKeyPath ([self ._key_path , pyregf_key .name ])
413
+ subkey = REGFWinRegistryKey (pyregf_key , key_path = key_path )
384
414
385
- pyregf_key = self ._pyregf_key .get_sub_key (index )
386
- key_path = key_paths .JoinKeyPath ([self ._key_path , pyregf_key .name ])
387
- return REGFWinRegistryKey (pyregf_key , key_path = key_path )
415
+ else :
416
+ index -= self ._pyregf_key .number_of_sub_keys
417
+
418
+ virtual_name , virtual_subkey = self ._virtual_subkeys [index ]
419
+ key_path = key_paths .JoinKeyPath ([self ._key_path , virtual_name ])
420
+ subkey = VirtualREGFWinRegistryKey (
421
+ virtual_name , virtual_subkey , key_path = key_path )
422
+
423
+ return subkey
388
424
389
425
def GetSubkeyByName (self , name ):
390
426
"""Retrieves a subkey by name.
@@ -395,11 +431,11 @@ def GetSubkeyByName(self, name):
395
431
Returns:
396
432
WinRegistryKey: Windows Registry subkey or None if not found.
397
433
"""
398
- if self . _current_control_set_key and name . upper () == 'CURRENTCONTROLSET' :
399
- name = 'CurrentControlSet'
400
- key_path = key_paths .JoinKeyPath ([self ._key_path , name ])
434
+ virtual_name , virtual_sub_key = self . _GetVirtualSubKey ( name )
435
+ if virtual_sub_key :
436
+ key_path = key_paths .JoinKeyPath ([self ._key_path , virtual_name ])
401
437
return VirtualREGFWinRegistryKey (
402
- name , self . _current_control_set_key , key_path = key_path )
438
+ virtual_name , virtual_sub_key , key_path = key_path )
403
439
404
440
pyregf_key = self ._pyregf_key .get_sub_key_by_name (name )
405
441
if not pyregf_key :
@@ -422,22 +458,19 @@ def GetSubkeyByPath(self, key_path):
422
458
423
459
key_path_segments = key_path .split ('\\ ' )
424
460
425
- if (self ._current_control_set_key and
426
- key_path_segments [0 ].upper () == 'CURRENTCONTROLSET' ):
461
+ virtual_name , virtual_sub_key = self ._GetVirtualSubKey (key_path_segments [0 ])
462
+ if not virtual_sub_key :
463
+ pyregf_key = self ._pyregf_key .get_sub_key_by_path (key_path )
464
+ else :
427
465
key_path_segments .pop (0 )
428
466
429
467
if not key_path_segments :
430
- name = 'CurrentControlSet'
431
- key_path = key_paths .JoinKeyPath ([self ._key_path , name ])
468
+ key_path = key_paths .JoinKeyPath ([self ._key_path , virtual_name ])
432
469
return VirtualREGFWinRegistryKey (
433
- name , self . _current_control_set_key , key_path = key_path )
470
+ virtual_name , virtual_sub_key , key_path = key_path )
434
471
435
472
sub_key_path = '\\ ' .join (key_path_segments )
436
- pyregf_key = self ._current_control_set_key .get_sub_key_by_path (
437
- sub_key_path )
438
-
439
- else :
440
- pyregf_key = self ._pyregf_key .get_sub_key_by_path (key_path )
473
+ pyregf_key = virtual_sub_key .get_sub_key_by_path (sub_key_path )
441
474
442
475
if not pyregf_key :
443
476
return None
@@ -455,11 +488,10 @@ def GetSubkeys(self):
455
488
key_path = key_paths .JoinKeyPath ([self ._key_path , pyregf_key .name ])
456
489
yield REGFWinRegistryKey (pyregf_key , key_path = key_path )
457
490
458
- if self ._current_control_set_key :
459
- key_path = key_paths .JoinKeyPath ([self ._key_path , 'CurrentControlSet' ])
491
+ for virtual_name , virtual_sub_key in self ._virtual_subkeys :
492
+ key_path = key_paths .JoinKeyPath ([self ._key_path , virtual_name ])
460
493
yield VirtualREGFWinRegistryKey (
461
- 'CurrentControlSet' , self ._current_control_set_key ,
462
- key_path = key_path )
494
+ virtual_name , virtual_sub_key , key_path = key_path )
463
495
464
496
465
497
class REGFWinRegistryValue (interface .WinRegistryValue ):
0 commit comments