2011/6/4 Daniel Veillard <veillard(a)redhat.com>:
On Sat, Jun 04, 2011 at 10:53:06AM +0200, Matthias Bolte wrote:
> 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(a)googlemail.com>
> + * Copyright (C) 2010-2011 Matthias Bolte <matthias.bolte(a)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;
> }
Okay, looks reasonable, ACK, please push for release :-)
Daniel
Thanks, pushed.
Matthias