We can get guest's OS version info by using 'guest-get-os-version', The return value contains version name and type (32-bit or 64-bit). For example: {"return":{"name":"Microsoft Windows Server 2012 R2","type":64}}
Signed-off-by: zhanghailiang <zhang.zhanghaili...@huawei.com> --- qga/commands-win32.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 121 insertions(+), 2 deletions(-) diff --git a/qga/commands-win32.c b/qga/commands-win32.c index d133082..7743e1a 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -446,10 +446,129 @@ int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp) return -1; } +static int get_system_type(Error **errp) +{ + SYSTEM_INFO si; + + typedef void (WINAPI * LPFN_GetNativeSystemInfo)(LPSYSTEM_INFO systemInfo); + LPFN_GetNativeSystemInfo ga_GetNativeSystemInfo = + (LPFN_GetNativeSystemInfo)GetProcAddress( + GetModuleHandle("kernel32"), + "GetNativeSystemInfo"); + if (ga_GetNativeSystemInfo) { + ga_GetNativeSystemInfo(&si); + } else { + GetSystemInfo(&si); + } + + if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 || + si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) { + return 64; + } else { + return 32; + } +} + +static BOOL compare_windows_version(DWORD dwMajorVersion, + DWORD dwMinorVersion) +{ + OSVERSIONINFOEX osvi; + DWORDLONG dwlConditionMask = 0; + + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + osvi.dwMajorVersion = dwMajorVersion; + osvi.dwMinorVersion = dwMinorVersion; + + VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_EQUAL); + VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_EQUAL); + + return VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, + dwlConditionMask); +} + +/* +* We get the version by using version information, you can find more info +* about operating systems and identical version numbers from bellow links: +* http://msdn.microsoft.com/en-us/library/ms724834(v=vs.85).aspx +* http://msdn.microsoft.com/en-us/library/ms724832(v=vs.85).aspx +*/ struct GuestOSVersion *qmp_guest_get_os_version(Error **errp) { - error_set(errp, QERR_UNSUPPORTED); - return NULL; + OSVERSIONINFOEX osvi; + GuestOSVersion *osv = g_malloc0(sizeof(GuestOSVersion)); + + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + if (!(GetVersionEx((OSVERSIONINFO *)&osvi))) { + error_setg(errp, "GetVersionEx failed\n"); + return NULL; + } + osv->type = get_system_type(NULL); + + switch (osvi.dwMajorVersion) { + case 5: + switch (osvi.dwMinorVersion) { + case 0: + osv->name = g_strdup("Microsoft Windows 2000"); + break; + case 1: + osv->name = g_strdup("Microsoft Windows XP"); + break; + case 2: + if (GetSystemMetrics(SM_SERVERR2) == 0) { + osv->name = g_strdup("Microsoft Windows Server 2003"); + } else { + osv->name = g_strdup("Microsoft Windows Server 2003 R2"); + } + break; + } + break; /* case 5*/ + case 6: + switch (osvi.dwMinorVersion) { + case 0: + if (osvi.wProductType == VER_NT_WORKSTATION) { + osv->name = g_strdup("Microsoft Windows Vista"); + } else { + osv->name = g_strdup("Microsoft Windows Server 2008"); + } + break; + case 1: + if (osvi.wProductType == VER_NT_WORKSTATION) { + osv->name = g_strdup("Microsoft Windows 7"); + } else { + osv->name = g_strdup("Microsoft Windows Server 2008 R2"); + } + break; + case 2: + /* + * GetVersionEx APIs have been deprecated. + * if we do not specifically target Windows 8.1 Preview, + * we will get Windows 8 version. So here we use + * VerifyVersionInfo to verify the correct version number. + * More info can be found at: + * http://msdn.microsoft.com/en-us/library/ms724834(v=vs.85).aspx + */ + if (compare_windows_version(6, 3)) { + if (osvi.wProductType == VER_NT_WORKSTATION) { + osv->name = g_strdup("Microsoft Windows 8.1"); + } else { + osv->name = g_strdup("Microsoft Windows Server 2012 R2"); + } + } else { + if (osvi.wProductType == VER_NT_WORKSTATION) { + osv->name = g_strdup("Microsoft Windows 8"); + } else { + osv->name = g_strdup("Microsoft Windows Server 2012"); + } + } + break; + } + break; /* case 6*/ + default: + osv->name = g_strdup("unknow os"); + } /* switch (osvi.dwMajorVersion) */ + return osv; } /* add unsupported commands to the blacklist */ -- 1.7.12.4