From 579e3bbd9ff380666070cfd1570e76967ecb8c77 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Tue, 12 Feb 2019 17:44:33 +0100 Subject: Updated parent traversal to check for root device --- serial/tools/list_ports_windows.py | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/serial/tools/list_ports_windows.py b/serial/tools/list_ports_windows.py index 4dd1b9a..0539b57 100644 --- a/serial/tools/list_ports_windows.py +++ b/serial/tools/list_ports_windows.py @@ -21,6 +21,7 @@ from ctypes.wintypes import LONG from ctypes.wintypes import ULONG from ctypes.wintypes import HKEY from ctypes.wintypes import BYTE +import winerror import serial from serial.win32 import ULONG_PTR from serial.tools import list_ports_common @@ -127,6 +128,9 @@ CM_Get_Device_IDW = cfgmgr32.CM_Get_Device_IDW CM_Get_Device_IDW.argtypes = [DWORD, PTSTR, ULONG, ULONG] CM_Get_Device_IDW.restype = LONG +CM_MapCrToWin32Err = cfgmgr32.CM_MapCrToWin32Err +CM_MapCrToWin32Err.argtypes = [DWORD, DWORD] +CM_MapCrToWin32Err.restype = DWORD DIGCF_PRESENT = 2 @@ -161,21 +165,30 @@ def get_parent_serial_number(child_devinst, child_vid, child_pid, depth=0): # Get the parent device instance. devinst = DWORD() - if CM_Get_Parent( - ctypes.byref(devinst), - child_devinst, - 0): - raise ctypes.WinError() + ret = CM_Get_Parent(ctypes.byref(devinst), child_devinst, 0) + + if ret: + win_error = CM_MapCrToWin32Err(DWORD(ret), DWORD(0)) + + # If there is no parent available, the child was the root device. We cannot traverse + # further. + if win_error == winerror.ERROR_NOT_FOUND: + return '' + + raise ctypes.WinError(win_error) + # Get the ID of the parent device and parse it for vendor ID, product ID, and serial number. parentHardwareID = ctypes.create_unicode_buffer(250) - if CM_Get_Device_IDW( + ret = CM_Get_Device_IDW( devinst, parentHardwareID, ctypes.sizeof(parentHardwareID) - 1, - 0): - raise ctypes.WinError() + 0) + + if ret: + raise ctypes.WinError(CM_MapCrToWin32Err(DWORD(ret), DWORD(0))) parentHardwareID_str = parentHardwareID.value m = re.search(r'VID_([0-9a-f]{4})(&PID_([0-9a-f]{4}))?(&MI_(\d{2}))?(\\(.*))?', -- cgit v1.2.3