Vinzenz Feenstra has uploaded a new change for review. Change subject: win32: Read serial info directly when not available through WMI ......................................................................
win32: Read serial info directly when not available through WMI The SerialNumber field in the WMI table 'Win32_DiskDrive' is only available from Windows Vista and Windows 2008 Server. This patch works around this issue by querying the device directly, but only if the SerialNumber field is not available. Change-Id: Id39914464377c388b8ef3e2551a47a295de4a750 Bug-Url: https://bugzilla.redhat.com/1158907 Signed-off-by: Vinzenz Feenstra <vfeen...@redhat.com> --- M ovirt-guest-agent/GuestAgentWin32.py 1 file changed, 64 insertions(+), 2 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-guest-agent refs/changes/35/35035/1 diff --git a/ovirt-guest-agent/GuestAgentWin32.py b/ovirt-guest-agent/GuestAgentWin32.py index 8678b05..469a9a2 100644 --- a/ovirt-guest-agent/GuestAgentWin32.py +++ b/ovirt-guest-agent/GuestAgentWin32.py @@ -7,6 +7,7 @@ import win32net import win32ts import win32api +import win32file import win32pipe import win32security import win32process @@ -21,12 +22,39 @@ from ctypes.util import find_library from ctypes.wintypes import DWORD import _winreg - +import ctypes +import ctypes.wintypes # Constants according to # http://msdn.microsoft.com/en-us/library/windows/desktop/ms724878.aspx KEY_WOW64_32KEY = 0x0100 KEY_WOW64_64KEY = 0x0200 + + +class StoragePropertyQuery(ctypes.Structure): + _fields_ = ( + ("a", ctypes.wintypes.ULONG), + ("b", ctypes.wintypes.ULONG), + ("c", ctypes.wintypes.BYTE), + ) + + +class StorageDeviceDescriptor(ctypes.Structure): + _fields_ = ( + ("Version", ctypes.wintypes.ULONG), + ("Size", ctypes.wintypes.ULONG), + ("DeviceType", ctypes.wintypes.BYTE), + ("DeviceTypeModifier", ctypes.wintypes.BYTE), + ("RemovableMedia", ctypes.wintypes.BOOLEAN), + ("CommandQueueing", ctypes.wintypes.BOOLEAN), + ("VendorIdOffset", ctypes.wintypes.ULONG), + ("ProductIdOffset", ctypes.wintypes.ULONG), + ("ProductRevisionOffset", ctypes.wintypes.ULONG), + ("SerialNumberOffset", ctypes.wintypes.ULONG), + ("BusType", ctypes.wintypes.DWORD), + ("RawPropertiesLength", ctypes.wintypes.ULONG), + ("DATA", ctypes.wintypes.BYTE * 1024), + ) # _winreg.QueryValueEx and win32api.RegQueryValueEx don't support reading @@ -488,6 +516,35 @@ logging.exception("Error retrieving disks usages.") return usages + def _readSMART(self, name): + serial = 'NO SERIAL NUMBER' + handle = ctypes.windll.kernel32.CreateFileW( + name, + win32file.GENERIC_READ | win32file.GENERIC_WRITE, + win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE, + None, win32file.OPEN_EXISTING, 0, 0) + if handle == -1: + logging.warning("Failed to open device '%s' for querying the " + "serial number. Error code: %d", name, + win32api.GetLastError()) + return serial + q = StoragePropertyQuery() + r = StorageDeviceDescriptor() + read_count = ctypes.wintypes.ULONG() + ret = ctypes.windll.kernel32.DeviceIoControl( + handle, 0x002D1400, ctypes.addressof(q), ctypes.sizeof(q), + ctypes.addressof(r), ctypes.sizeof(r), + ctypes.addressof(read_count), 0) + + if ret: + serial = buffer(r)[r.SerialNumberOffset:r.SerialNumberOffset + 20] + else: + logging.warning("DeviceIoControl for device %s failed with" + "eror code: %d. Could not look up serial number", + name, win32api.GetLastError()) + ctypes.windll.kernel32.CloseHandle(handle) + return serial + def getDiskMapping(self): result = {} try: @@ -500,7 +557,11 @@ objSWbemServices.ExecQuery( "SELECT * FROM Win32_DiskDrive") for objItem in colItems: - result[objItem.SerialNumber] = {'name': objItem.DeviceID} + try: + serial = objItem.SerialNumber + except AttributeError: + serial = self._readSMART(objItem.DeviceID) + result[serial] = {'name': objItem.DeviceID} except Exception: logging.exception("Failed to retrieve disk mapping") return result @@ -600,6 +661,7 @@ print "Active User:", dr.getActiveUser() print "Disks Usage:", dr.getDisksUsage() print "Memory Stats:", dr.getMemoryStats() + print "DiskMapping:", dr.getDiskMapping() if __name__ == '__main__': test() -- To view, visit http://gerrit.ovirt.org/35035 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id39914464377c388b8ef3e2551a47a295de4a750 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-guest-agent Gerrit-Branch: master Gerrit-Owner: Vinzenz Feenstra <vfeen...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches