VBoxServiceUtils.cpp revision 019f39cc548f50d58cfdf91965f58eab1ded841b
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync/* $Id$ */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync/** @file
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * VBoxServiceUtils - Some utility functions.
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync/*
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * Copyright (C) 2009 Sun Microsystems, Inc.
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync *
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * available from http://www.virtualbox.org. This file is free software;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * you can redistribute it and/or modify it under the terms of the GNU
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * General Public License (GPL) as published by the Free Software
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync *
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * additional information or have any questions.
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync/*******************************************************************************
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync* Header Files *
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync*******************************************************************************/
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#ifdef RT_OS_WINDOWS
682a27d94b9116c719038882487b99053985f91avboxsync# include <Windows.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#endif
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <iprt/assert.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <iprt/mem.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <iprt/string.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
682a27d94b9116c719038882487b99053985f91avboxsync#include <VBox/VBoxGuestLib.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include "VBoxServiceInternal.h"
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
b0b8c85eb454e2a7ad926bbefda6d908932291e3vboxsync#ifdef VBOX_WITH_GUEST_PROPS
019f39cc548f50d58cfdf91965f58eab1ded841bvboxsync/**
019f39cc548f50d58cfdf91965f58eab1ded841bvboxsync * Wrapper around VbglR3GuestPropWriteValue that does value formatting and
019f39cc548f50d58cfdf91965f58eab1ded841bvboxsync * logging.
019f39cc548f50d58cfdf91965f58eab1ded841bvboxsync *
019f39cc548f50d58cfdf91965f58eab1ded841bvboxsync * @returns VBox status code. Errors will be logged.
019f39cc548f50d58cfdf91965f58eab1ded841bvboxsync *
019f39cc548f50d58cfdf91965f58eab1ded841bvboxsync * @param u32ClientId The HGCM client ID for the guest property session.
019f39cc548f50d58cfdf91965f58eab1ded841bvboxsync * @param pszName The property name.
019f39cc548f50d58cfdf91965f58eab1ded841bvboxsync * @param pszValueFormat The property format string. If this is NULL then
019f39cc548f50d58cfdf91965f58eab1ded841bvboxsync * the property will be removed.
019f39cc548f50d58cfdf91965f58eab1ded841bvboxsync * @param ... Format arguments.
019f39cc548f50d58cfdf91965f58eab1ded841bvboxsync */
324b7b7cb0e3e95595f5fb069043ff3643891ba2vboxsyncint VBoxServiceWritePropF(uint32_t u32ClientId, const char *pszName, const char *pszValueFormat, ...)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync{
23776fb44216ff7aa3b47916ef4975748de89de1vboxsync int rc;
23776fb44216ff7aa3b47916ef4975748de89de1vboxsync if (pszValueFormat != NULL)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
019f39cc548f50d58cfdf91965f58eab1ded841bvboxsync /** @todo Log the value as well? just copy the guts of
019f39cc548f50d58cfdf91965f58eab1ded841bvboxsync * VbglR3GuestPropWriteValueV. */
23776fb44216ff7aa3b47916ef4975748de89de1vboxsync VBoxServiceVerbose(3, "Writing guest property \"%s\"\n", pszName);
23776fb44216ff7aa3b47916ef4975748de89de1vboxsync va_list va;
23776fb44216ff7aa3b47916ef4975748de89de1vboxsync va_start(va, pszValueFormat);
23776fb44216ff7aa3b47916ef4975748de89de1vboxsync rc = VbglR3GuestPropWriteValueV(u32ClientId, pszName, pszValueFormat, va);
23776fb44216ff7aa3b47916ef4975748de89de1vboxsync va_end(va);
23776fb44216ff7aa3b47916ef4975748de89de1vboxsync if (RT_FAILURE(rc))
23776fb44216ff7aa3b47916ef4975748de89de1vboxsync VBoxServiceError("Error writing guest property \"%s\" (rc=%Rrc)\n", pszName, rc);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
23776fb44216ff7aa3b47916ef4975748de89de1vboxsync else
019f39cc548f50d58cfdf91965f58eab1ded841bvboxsync {
23776fb44216ff7aa3b47916ef4975748de89de1vboxsync rc = VbglR3GuestPropWriteValue(u32ClientId, pszName, NULL);
019f39cc548f50d58cfdf91965f58eab1ded841bvboxsync if (RT_FAILURE(rc))
019f39cc548f50d58cfdf91965f58eab1ded841bvboxsync VBoxServiceError("Error removing guest property \"%s\" (rc=%Rrc)\n", pszName, rc);
019f39cc548f50d58cfdf91965f58eab1ded841bvboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync return rc;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync}
b0b8c85eb454e2a7ad926bbefda6d908932291e3vboxsync#endif /* VBOX_WITH_GUEST_PROPS */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#ifdef RT_OS_WINDOWS
324b7b7cb0e3e95595f5fb069043ff3643891ba2vboxsyncBOOL VBoxServiceGetFileString(const char* pszFileName,
f65e6cba3e74ffd3dc9e6053828dcc82b367e8devboxsync char* pszBlock,
f65e6cba3e74ffd3dc9e6053828dcc82b367e8devboxsync char* pszString,
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync PUINT puiSize)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync{
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync DWORD dwHandle, dwLen = 0;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync UINT uiDataLen = 0;
f65e6cba3e74ffd3dc9e6053828dcc82b367e8devboxsync char* lpData = NULL;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync UINT uiValueLen = 0;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync LPTSTR lpValue = NULL;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync BOOL bRet = FALSE;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync Assert(pszFileName);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync Assert(pszBlock);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync Assert(pszString);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync Assert(puiSize > 0);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync /* The VS_FIXEDFILEINFO structure contains version information about a file.
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync This information is language and code page independent. */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync VS_FIXEDFILEINFO *pFileInfo = NULL;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync dwLen = GetFileVersionInfoSize(pszFileName, &dwHandle);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if (!dwLen)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
f65e6cba3e74ffd3dc9e6053828dcc82b367e8devboxsync VBoxServiceError("No file information found! File = %s, Error: %ld\n", pszFileName, GetLastError());
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync return FALSE;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync lpData = (LPTSTR) RTMemTmpAlloc(dwLen);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if (!lpData)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync VBoxServiceError("Could not allocate temp buffer!\n");
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync return FALSE;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if (GetFileVersionInfo(pszFileName, dwHandle, dwLen, lpData))
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if((bRet = VerQueryValue(lpData, pszBlock, (LPVOID*)&lpValue, (PUINT)&uiValueLen)))
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
f65e6cba3e74ffd3dc9e6053828dcc82b367e8devboxsync UINT uiSize = uiValueLen * sizeof(char);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if(uiSize > *puiSize)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync uiSize = *puiSize;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync ZeroMemory(pszString, *puiSize);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync memcpy(pszString, lpValue, uiSize);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync else VBoxServiceError("Could not query value!\n");
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync else VBoxServiceError("Could not get file version info!\n");
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync RTMemFree(lpData);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync return bRet;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync}
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
324b7b7cb0e3e95595f5fb069043ff3643891ba2vboxsyncBOOL VBoxServiceGetFileVersion(const char* pszFileName,
682a27d94b9116c719038882487b99053985f91avboxsync DWORD* pdwMajor,
682a27d94b9116c719038882487b99053985f91avboxsync DWORD* pdwMinor,
682a27d94b9116c719038882487b99053985f91avboxsync DWORD* pdwBuildNumber,
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync DWORD* pdwRevisionNumber)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync{
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync DWORD dwHandle, dwLen = 0;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync UINT BufLen = 0;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync LPTSTR lpData = NULL;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync BOOL bRet = FALSE;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync Assert(pszFileName);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync Assert(pdwMajor);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync Assert(pdwMinor);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync Assert(pdwBuildNumber);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync Assert(pdwRevisionNumber);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync /* The VS_FIXEDFILEINFO structure contains version information about a file.
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync This information is language and code page independent. */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync VS_FIXEDFILEINFO *pFileInfo = NULL;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync dwLen = GetFileVersionInfoSize(pszFileName, &dwHandle);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync /* Try own fields defined in block "\\StringFileInfo\\040904b0\\FileVersion". */
f65e6cba3e74ffd3dc9e6053828dcc82b367e8devboxsync char szValue[_MAX_PATH] = {0};
f65e6cba3e74ffd3dc9e6053828dcc82b367e8devboxsync char *pszValue = szValue;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync UINT uiSize = _MAX_PATH;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync int r = 0;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
324b7b7cb0e3e95595f5fb069043ff3643891ba2vboxsync bRet = VBoxServiceGetFileString(pszFileName, "\\StringFileInfo\\040904b0\\FileVersion", szValue, &uiSize);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if (bRet)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
f65e6cba3e74ffd3dc9e6053828dcc82b367e8devboxsync sscanf(pszValue, "%ld.%ld.%ld.%ld", pdwMajor, pdwMinor, pdwBuildNumber, pdwRevisionNumber);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync else if (dwLen > 0)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync /* Try regular fields - this maybe is not file provided by VBox! */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync lpData = (LPTSTR) RTMemTmpAlloc(dwLen);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if (!lpData)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync VBoxServiceError("Could not allocate temp buffer!\n");
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync return FALSE;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if (GetFileVersionInfo(pszFileName, dwHandle, dwLen, lpData))
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
f65e6cba3e74ffd3dc9e6053828dcc82b367e8devboxsync if((bRet = VerQueryValue(lpData, "\\", (LPVOID*)&pFileInfo, (PUINT)&BufLen)))
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync *pdwMajor = HIWORD(pFileInfo->dwFileVersionMS);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync *pdwMinor = LOWORD(pFileInfo->dwFileVersionMS);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync *pdwBuildNumber = HIWORD(pFileInfo->dwFileVersionLS);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync *pdwRevisionNumber = LOWORD(pFileInfo->dwFileVersionLS);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync else VBoxServiceError("Could not query file information value!\n");
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync else VBoxServiceError("Could not get file version info!\n");
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync RTMemFree(lpData);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync return bRet;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync}
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
324b7b7cb0e3e95595f5fb069043ff3643891ba2vboxsyncBOOL VBoxServiceGetFileVersionString(const char* pszPath, const char* pszFileName, char* pszVersion, UINT uiSize)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync{
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync BOOL bRet = FALSE;
f65e6cba3e74ffd3dc9e6053828dcc82b367e8devboxsync char szFullPath[_MAX_PATH] = {0};
f65e6cba3e74ffd3dc9e6053828dcc82b367e8devboxsync char szValue[_MAX_PATH] = {0};
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync int r = 0;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
f65e6cba3e74ffd3dc9e6053828dcc82b367e8devboxsync RTStrPrintf(szFullPath, 4096, "%s\\%s", pszPath, pszFileName);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync DWORD dwMajor, dwMinor, dwBuild, dwRev;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
324b7b7cb0e3e95595f5fb069043ff3643891ba2vboxsync bRet = VBoxServiceGetFileVersion(szFullPath, &dwMajor, &dwMinor, &dwBuild, &dwRev);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if (bRet)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync RTStrPrintf(pszVersion, uiSize, "%ld.%ld.%ldr%ld", dwMajor, dwMinor, dwBuild, dwRev);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync else
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync RTStrPrintf(pszVersion, uiSize, "-");
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync return bRet;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync}
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#endif /* !RT_OS_WINDOWS */
682a27d94b9116c719038882487b99053985f91avboxsync