com.cpp revision 582e8de0cb73d07d7291c8ad587b2dc77985783e
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/* $Id$ */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/** @file
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * MS COM / XPCOM Abstraction Layer
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Copyright (C) 2006-2007 Oracle Corporation
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * available from http://www.virtualbox.org. This file is free software;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * you can redistribute it and/or modify it under the terms of the GNU
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * General Public License (GPL) as published by the Free Software
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#if !defined (VBOX_WITH_XPCOM)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync# include <objbase.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#else /* !defined (VBOX_WITH_XPCOM) */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync# include <stdlib.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync# include <nsCOMPtr.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync# include <nsIServiceManagerUtils.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync# include <nsIComponentManager.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync# include <ipcIService.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync# include <ipcCID.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync# include <ipcIDConnectService.h>
925b21ef13312d51bd7746073d52acd167d2f448vboxsync# include <nsIInterfaceInfo.h>
925b21ef13312d51bd7746073d52acd167d2f448vboxsync# include <nsIInterfaceInfoManager.h>
925b21ef13312d51bd7746073d52acd167d2f448vboxsync// official XPCOM headers don't define it yet
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#define IPC_DCONNECTSERVICE_CONTRACTID \
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync "@mozilla.org/ipc/dconnect-service;1"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif /* !defined (VBOX_WITH_XPCOM) */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
c18725c5feb3fb06870ff1b6fd3d424d3033bd11vboxsync#include "VBox/com/com.h"
c18725c5feb3fb06870ff1b6fd3d424d3033bd11vboxsync#include "VBox/com/assert.h"
c18725c5feb3fb06870ff1b6fd3d424d3033bd11vboxsync
c18725c5feb3fb06870ff1b6fd3d424d3033bd11vboxsync#include "VBox/com/Guid.h"
c18725c5feb3fb06870ff1b6fd3d424d3033bd11vboxsync#include "VBox/com/array.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <iprt/param.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <iprt/path.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <iprt/dir.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <iprt/env.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <iprt/string.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <VBox/err.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef RT_OS_DARWIN
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync# define VBOX_USER_HOME_SUFFIX "Library/VirtualBox"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync# define VBOX_USER_HOME_SUFFIX ".VirtualBox"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "Logging.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncnamespace com
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid GetInterfaceNameByIID(const GUID &aIID, BSTR *aName)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync Assert(aName);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (!aName)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync *aName = NULL;
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync#if !defined(VBOX_WITH_XPCOM)
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync LONG rc;
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync LPOLESTR iidStr = NULL;
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync if (StringFromIID(aIID, &iidStr) == S_OK)
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync {
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync HKEY ifaceKey;
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync rc = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Interface",
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync 0, KEY_QUERY_VALUE, &ifaceKey);
fb999cbaa7a2872d9cd7375901ff3ccfc050ffb3vboxsync if (rc == ERROR_SUCCESS)
fb999cbaa7a2872d9cd7375901ff3ccfc050ffb3vboxsync {
fb999cbaa7a2872d9cd7375901ff3ccfc050ffb3vboxsync HKEY iidKey;
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync rc = RegOpenKeyExW(ifaceKey, iidStr, 0, KEY_QUERY_VALUE, &iidKey);
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync if (rc == ERROR_SUCCESS)
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync {
/* determine the size and type */
DWORD sz, type;
rc = RegQueryValueExW(iidKey, NULL, NULL, &type, NULL, &sz);
if (rc == ERROR_SUCCESS && type == REG_SZ)
{
/* query the value to BSTR */
*aName = SysAllocStringLen(NULL, (sz + 1) / sizeof(TCHAR) + 1);
rc = RegQueryValueExW(iidKey, NULL, NULL, NULL, (LPBYTE) *aName, &sz);
if (rc != ERROR_SUCCESS)
{
SysFreeString(*aName);
aName = NULL;
}
}
RegCloseKey(iidKey);
}
RegCloseKey(ifaceKey);
}
CoTaskMemFree(iidStr);
}
#else /* !defined (VBOX_WITH_XPCOM) */
nsresult rv;
nsCOMPtr<nsIInterfaceInfoManager> iim =
do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv))
{
nsCOMPtr<nsIInterfaceInfo> iinfo;
rv = iim->GetInfoForIID(&aIID, getter_AddRefs(iinfo));
if (NS_SUCCEEDED(rv))
{
const char *iname = NULL;
iinfo->GetNameShared(&iname);
char *utf8IName = NULL;
if (RT_SUCCESS(RTStrCurrentCPToUtf8(&utf8IName, iname)))
{
PRTUTF16 utf16IName = NULL;
if (RT_SUCCESS(RTStrToUtf16(utf8IName, &utf16IName)))
{
*aName = SysAllocString((OLECHAR *) utf16IName);
RTUtf16Free(utf16IName);
}
RTStrFree(utf8IName);
}
}
}
#endif /* !defined (VBOX_WITH_XPCOM) */
}
#ifdef VBOX_WITH_XPCOM
HRESULT GlueCreateObjectOnServer(const CLSID &clsid,
const char *serverName,
const nsIID &id,
void** ppobj)
{
HRESULT rc;
nsCOMPtr<ipcIService> ipcServ = do_GetService(IPC_SERVICE_CONTRACTID, &rc);
if (SUCCEEDED(rc))
{
PRUint32 serverID = 0;
rc = ipcServ->ResolveClientName(serverName, &serverID);
if (SUCCEEDED (rc))
{
nsCOMPtr<ipcIDConnectService> dconServ = do_GetService(IPC_DCONNECTSERVICE_CONTRACTID, &rc);
if (SUCCEEDED(rc))
rc = dconServ->CreateInstance(serverID,
clsid,
id,
ppobj);
}
}
return rc;
}
HRESULT GlueCreateInstance(const CLSID &clsid,
const nsIID &id,
void** ppobj)
{
nsCOMPtr<nsIComponentManager> manager;
HRESULT rc = NS_GetComponentManager(getter_AddRefs(manager));
if (SUCCEEDED(rc))
rc = manager->CreateInstance(clsid,
nsnull,
id,
ppobj);
return rc;
}
#endif // VBOX_WITH_XPCOM
int GetVBoxUserHomeDirectory(char *aDir, size_t aDirLen)
{
AssertReturn(aDir, VERR_INVALID_POINTER);
AssertReturn(aDirLen > 0, VERR_BUFFER_OVERFLOW);
/* start with null */
*aDir = 0;
char szTmp[RTPATH_MAX];
int vrc = RTEnvGetEx(RTENV_DEFAULT, "VBOX_USER_HOME", szTmp, sizeof(szTmp), NULL);
if (RT_SUCCESS(vrc) || vrc == VERR_ENV_VAR_NOT_FOUND)
{
if (RT_SUCCESS(vrc))
{
/* get the full path name */
vrc = RTPathAbs(szTmp, aDir, aDirLen);
}
else
{
/* compose the config directory (full path) */
/** @todo r=bird: RTPathUserHome doesn't necessarily return a full (abs) path
* like the comment above seems to indicate. */
vrc = RTPathUserHome(aDir, aDirLen);
if (RT_SUCCESS(vrc))
vrc = RTPathAppend(aDir, aDirLen, VBOX_USER_HOME_SUFFIX);
}
/* ensure the home directory exists */
if (RT_SUCCESS(vrc))
if (!RTDirExists(aDir))
vrc = RTDirCreateFullPath(aDir, 0777);
}
return vrc;
}
/* static */
const Guid Guid::Empty; /* default ctor is OK */
#if defined (VBOX_WITH_XPCOM)
/* static */
const nsID *SafeGUIDArray::nsIDRef::Empty = (const nsID *)Guid::Empty.raw();
#endif /* (VBOX_WITH_XPCOM) */
/**
* Used by ComPtr and friends to log details about reference counting.
* @param pcszFormat
*/
void LogRef(const char *pcszFormat, ...)
{
char *pszNewMsg;
va_list args;
va_start(args, pcszFormat);
RTStrAPrintfV(&pszNewMsg, pcszFormat, args);
LogDJ((pszNewMsg));
RTStrFree(pszNewMsg);
va_end(args);
}
} /* namespace com */