[libvirt] [PATCH] vbox: Fix version extraction on Windows for newer VirtualBox versions

Matthias Bolte matthias.bolte at googlemail.com
Sat Jun 4 08:53:06 UTC 2011


VirtualBox 4.0.8 changed the registry key layout. Before the version
number was in a Version key. Now the Version key contains %VER% and
the actual version number is in VersionExt now.

Move value lookup code into its own function: vboxLookupRegistryValue.
---
 src/vbox/vbox_MSCOMGlue.c |   87 +++++++++++++++++++++++++++++++--------------
 1 files changed, 60 insertions(+), 27 deletions(-)

diff --git a/src/vbox/vbox_MSCOMGlue.c b/src/vbox/vbox_MSCOMGlue.c
index e31a763..8aef266 100644
--- a/src/vbox/vbox_MSCOMGlue.c
+++ b/src/vbox/vbox_MSCOMGlue.c
@@ -2,7 +2,7 @@
 /*
  * vbox_MSCOMGlue.c: glue to the MSCOM based VirtualBox API
  *
- * Copyright (C) 2010 Matthias Bolte <matthias.bolte at googlemail.com>
+ * Copyright (C) 2010-2011 Matthias Bolte <matthias.bolte at googlemail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -338,45 +338,31 @@ static nsIEventQueue vboxEventQueue = {
 
 
 
-static int
-vboxLookupVersionInRegistry(void)
+static char *
+vboxLookupRegistryValue(HKEY key, const char *keyName, const char *valueName)
 {
-    int result = -1;
-    const char *keyName = VBOX_REGKEY_ORACLE;
     LONG status;
-    HKEY key;
     DWORD type;
     DWORD length;
     char *value = NULL;
 
-    status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, KEY_READ, &key);
+    status = RegQueryValueEx(key, valueName, NULL, &type, NULL, &length);
 
     if (status != ERROR_SUCCESS) {
-        keyName = VBOX_REGKEY_SUN;
-        status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, KEY_READ, &key);
-
-        if (status != ERROR_SUCCESS) {
-            /* Both keys aren't there, or we cannot open them. In general this
-             * indicates that VirtualBox is not installed, so we just silently
-             * fail here making vboxRegister() register the dummy driver. */
-            return -1;
-        }
-    }
-
-    status = RegQueryValueEx(key, "Version", NULL, &type, NULL, &length);
-
-    if (status != ERROR_SUCCESS) {
-        VIR_ERROR(_("Could not query registry value '%s\\Version'"), keyName);
+        VIR_ERROR(_("Could not query registry value '%s\\%s'"),
+                  keyName, valueName);
         goto cleanup;
     }
 
     if (type != REG_SZ) {
-        VIR_ERROR(_("Registry value '%s\\Version' has unexpected type"), keyName);
+        VIR_ERROR(_("Registry value '%s\\%s' has unexpected type"),
+                  keyName, valueName);
         goto cleanup;
     }
 
     if (length < 2) {
-        VIR_ERROR(_("Registry value '%s\\Version' is too short"), keyName);
+        VIR_ERROR(_("Registry value '%s\\%s' is too short"),
+                  keyName, valueName);
         goto cleanup;
     }
 
@@ -386,10 +372,12 @@ vboxLookupVersionInRegistry(void)
         goto cleanup;
     }
 
-    status = RegQueryValueEx(key, "Version", NULL, NULL, (LPBYTE)value, &length);
+    status = RegQueryValueEx(key, valueName, NULL, NULL, (LPBYTE)value, &length);
 
     if (status != ERROR_SUCCESS) {
-        VIR_ERROR(_("Could not query registry value '%s\\Version'"), keyName);
+        VIR_FREE(value);
+        VIR_ERROR(_("Could not query registry value '%s\\%s'"),
+                  keyName, valueName);
         goto cleanup;
     }
 
@@ -397,7 +385,52 @@ vboxLookupVersionInRegistry(void)
         value[length] = '\0';
     }
 
-    if (virParseVersionString(value, &vboxVersion)) {
+  cleanup:
+    return value;
+}
+
+static int
+vboxLookupVersionInRegistry(void)
+{
+    int result = -1;
+    const char *keyName = VBOX_REGKEY_ORACLE;
+    LONG status;
+    HKEY key;
+    char *value = NULL;
+
+    status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, KEY_READ, &key);
+
+    if (status != ERROR_SUCCESS) {
+        keyName = VBOX_REGKEY_SUN;
+        status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, KEY_READ, &key);
+
+        if (status != ERROR_SUCCESS) {
+            /* Both keys aren't there, or we cannot open them. In general this
+             * indicates that VirtualBox is not installed, so we just silently
+             * fail here making vboxRegister() register the dummy driver. */
+            return -1;
+        }
+    }
+
+    /* The registry key layout changed around version 4.0.8. Before the version
+     * number was in the Version key, now the Version key can contain %VER% and
+     * the actual version number is in the VersionExt key then. */
+    value = vboxLookupRegistryValue(key, keyName, "Version");
+
+    if (value == NULL) {
+        goto cleanup;
+    }
+
+    if (STREQ(value, "%VER%")) {
+        VIR_FREE(value);
+        value = vboxLookupRegistryValue(key, keyName, "VersionExt");
+
+        if (value == NULL) {
+            goto cleanup;
+        }
+    }
+
+    if (virParseVersionString(value, &vboxVersion) < 0) {
         VIR_ERROR(_("Could not parse version number from '%s'"), value);
         goto cleanup;
     }
-- 
1.7.0.4




More information about the libvir-list mailing list