diff --git a/src/vbox/vbox_MSCOMGlue.c b/src/vbox/vbox_MSCOMGlue.c index e31a76328f67f0ccacb22d8c364067803f316835..8aef2660cf6df00b2af409a937f0c4ff6cb0283d 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 + * Copyright (C) 2010-2011 Matthias Bolte * * 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; }