Extending the main() function
The main() function has remained mostly intact, only adding changes to look up the USB VID and PID information and present a superior output for the end user. One way we are facilitating this lookup is by providing a file path as the local_usb_ids parameter, which allows us to use an offline file for our VID/PID lookup database. To cut down on clutter in our output, we have elected to remove the script name and version printing. On line 51, a new function call to prep_usb_info() is made to initiate the setup of the VID/PID lookups. Our loop on line 52 has been reconfigured to hand each processed device entry to the parse_device_info() function on line 53. This new function is responsible for reading the raw string from the log file and attempts to split the VID and PID values for lookup:
042 def main(in_file, local_usb_ids=None):
043 """
044 Main function to handle operation
045 :param in_file: Str - Path to setupapi log to analyze
046 :return: None
047 """
048
049 if os.path.isfile(in_file):
050 device_information = parse_setupapi(in_file)
051 usb_ids = prep_usb_lookup(local_usb_ids)
052 for device in device_information:
053 parsed_info = parse_device_info(device)
The if statement on line 54 checks the value of the parsed_info variable to ensure that it was parsed correctly and can be compared against our known values. In the case that it is not prepared for this, the information is not queried or printed. See the following code:
054 if isinstance(parsed_info, dict):
055 parsed_info = get_device_names(usb_ids,
056 parsed_info)
Additional logic on line 57 checks to see whether the parsed_info value is not equivalent to None. A None value is assigned to parsed_info if the parse_device_info() function discovered that the device was not recorded as a USB, eliminating false positives:
057 if parsed_info is not None:
058 print_output(parsed_info)
Finally, on line 59, we print to the console that we have completed parsing the log file. On lines 62 through 65, we address the situation where the setupapi.dev.log is not valid or accessible by our script and notify the user of the situation before exiting. The message that is printed before exiting the script is more detailed than in previous iterations. The more details we can provide to our users, especially regarding potential bugs, will improve their capability to determine the error and correct it on their own:
059 print('\n\n{} parsed and printed successfully.'.format(
060 in_file)) 061
062 else:
063 print("Input: {} was not found. Please check your path "
064 "and permissions.".format(in_file))
065 sys.exit(1)