On Dec 16, 2014, at 9:30 AM, zhanghailiang zhang.zhanghaili...@huawei.com
wrote:
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) {
If one of the motivations is to update drivers on the guest - those should be
treated as deferent architectures.
Why not return string as well (x64, x86, IA64, ARM)?
+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 {
+