VirtualBox

source: vbox/trunk/src/VBox/Main/glue/com.cpp@ 42566

Last change on this file since 42566 was 42385, checked in by vboxsync, 12 years ago

Main/glue: Add a flag to GetVBoxUserHomeDirectory to disable creating the VirtualBox settings directory automatically

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.0 KB
Line 
1/* $Id: com.cpp 42385 2012-07-25 11:52:31Z vboxsync $ */
2/** @file
3 * MS COM / XPCOM Abstraction Layer
4 */
5
6/*
7 * Copyright (C) 2005-2012 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#if !defined (VBOX_WITH_XPCOM)
19
20# include <objbase.h>
21
22#else /* !defined (VBOX_WITH_XPCOM) */
23# include <stdlib.h>
24# include <nsCOMPtr.h>
25# include <nsIServiceManagerUtils.h>
26# include <nsIComponentManager.h>
27# include <ipcIService.h>
28# include <ipcCID.h>
29# include <ipcIDConnectService.h>
30# include <nsIInterfaceInfo.h>
31# include <nsIInterfaceInfoManager.h>
32// official XPCOM headers don't define it yet
33#define IPC_DCONNECTSERVICE_CONTRACTID \
34 "@mozilla.org/ipc/dconnect-service;1"
35#endif /* !defined (VBOX_WITH_XPCOM) */
36
37#include "VBox/com/com.h"
38#include "VBox/com/assert.h"
39
40#include "VBox/com/Guid.h"
41#include "VBox/com/array.h"
42
43#include <package-generated.h>
44
45#include <iprt/buildconfig.h>
46#include <iprt/param.h>
47#include <iprt/path.h>
48#include <iprt/dir.h>
49#include <iprt/env.h>
50#include <iprt/string.h>
51#include <iprt/system.h>
52#include <iprt/process.h>
53
54#include <VBox/err.h>
55#include <VBox/version.h>
56
57#ifdef RT_OS_DARWIN
58# define VBOX_USER_HOME_SUFFIX "Library/VirtualBox"
59#else
60# define VBOX_USER_HOME_SUFFIX ".VirtualBox"
61#endif
62
63#include "Logging.h"
64
65namespace com
66{
67
68void GetInterfaceNameByIID(const GUID &aIID, BSTR *aName)
69{
70 Assert(aName);
71 if (!aName)
72 return;
73
74 *aName = NULL;
75
76#if !defined(VBOX_WITH_XPCOM)
77
78 LONG rc;
79 LPOLESTR iidStr = NULL;
80 if (StringFromIID(aIID, &iidStr) == S_OK)
81 {
82 HKEY ifaceKey;
83 rc = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Interface",
84 0, KEY_QUERY_VALUE, &ifaceKey);
85 if (rc == ERROR_SUCCESS)
86 {
87 HKEY iidKey;
88 rc = RegOpenKeyExW(ifaceKey, iidStr, 0, KEY_QUERY_VALUE, &iidKey);
89 if (rc == ERROR_SUCCESS)
90 {
91 /* determine the size and type */
92 DWORD sz, type;
93 rc = RegQueryValueExW(iidKey, NULL, NULL, &type, NULL, &sz);
94 if (rc == ERROR_SUCCESS && type == REG_SZ)
95 {
96 /* query the value to BSTR */
97 *aName = SysAllocStringLen(NULL, (sz + 1) / sizeof(TCHAR) + 1);
98 rc = RegQueryValueExW(iidKey, NULL, NULL, NULL, (LPBYTE) *aName, &sz);
99 if (rc != ERROR_SUCCESS)
100 {
101 SysFreeString(*aName);
102 aName = NULL;
103 }
104 }
105 RegCloseKey(iidKey);
106 }
107 RegCloseKey(ifaceKey);
108 }
109 CoTaskMemFree(iidStr);
110 }
111
112#else /* !defined (VBOX_WITH_XPCOM) */
113
114 nsresult rv;
115 nsCOMPtr<nsIInterfaceInfoManager> iim =
116 do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv);
117 if (NS_SUCCEEDED(rv))
118 {
119 nsCOMPtr<nsIInterfaceInfo> iinfo;
120 rv = iim->GetInfoForIID(&aIID, getter_AddRefs(iinfo));
121 if (NS_SUCCEEDED(rv))
122 {
123 const char *iname = NULL;
124 iinfo->GetNameShared(&iname);
125 char *utf8IName = NULL;
126 if (RT_SUCCESS(RTStrCurrentCPToUtf8(&utf8IName, iname)))
127 {
128 PRTUTF16 utf16IName = NULL;
129 if (RT_SUCCESS(RTStrToUtf16(utf8IName, &utf16IName)))
130 {
131 *aName = SysAllocString((OLECHAR *) utf16IName);
132 RTUtf16Free(utf16IName);
133 }
134 RTStrFree(utf8IName);
135 }
136 }
137 }
138
139#endif /* !defined (VBOX_WITH_XPCOM) */
140}
141
142#ifdef VBOX_WITH_XPCOM
143
144HRESULT GlueCreateObjectOnServer(const CLSID &clsid,
145 const char *serverName,
146 const nsIID &id,
147 void** ppobj)
148{
149 HRESULT rc;
150 nsCOMPtr<ipcIService> ipcServ = do_GetService(IPC_SERVICE_CONTRACTID, &rc);
151 if (SUCCEEDED(rc))
152 {
153 PRUint32 serverID = 0;
154 rc = ipcServ->ResolveClientName(serverName, &serverID);
155 if (SUCCEEDED (rc))
156 {
157 nsCOMPtr<ipcIDConnectService> dconServ = do_GetService(IPC_DCONNECTSERVICE_CONTRACTID, &rc);
158 if (SUCCEEDED(rc))
159 rc = dconServ->CreateInstance(serverID,
160 clsid,
161 id,
162 ppobj);
163 }
164 }
165 return rc;
166}
167
168HRESULT GlueCreateInstance(const CLSID &clsid,
169 const nsIID &id,
170 void** ppobj)
171{
172 nsCOMPtr<nsIComponentManager> manager;
173 HRESULT rc = NS_GetComponentManager(getter_AddRefs(manager));
174 if (SUCCEEDED(rc))
175 rc = manager->CreateInstance(clsid,
176 nsnull,
177 id,
178 ppobj);
179 return rc;
180}
181
182#endif // VBOX_WITH_XPCOM
183
184int GetVBoxUserHomeDirectory(char *aDir, size_t aDirLen, bool fCreateDir)
185{
186 AssertReturn(aDir, VERR_INVALID_POINTER);
187 AssertReturn(aDirLen > 0, VERR_BUFFER_OVERFLOW);
188
189 /* start with null */
190 *aDir = 0;
191
192 char szTmp[RTPATH_MAX];
193 int vrc = RTEnvGetEx(RTENV_DEFAULT, "VBOX_USER_HOME", szTmp, sizeof(szTmp), NULL);
194 if (RT_SUCCESS(vrc) || vrc == VERR_ENV_VAR_NOT_FOUND)
195 {
196 if (RT_SUCCESS(vrc))
197 {
198 /* get the full path name */
199 vrc = RTPathAbs(szTmp, aDir, aDirLen);
200 }
201 else
202 {
203 /* compose the config directory (full path) */
204 /** @todo r=bird: RTPathUserHome doesn't necessarily return a full (abs) path
205 * like the comment above seems to indicate. */
206 vrc = RTPathUserHome(aDir, aDirLen);
207 if (RT_SUCCESS(vrc))
208 vrc = RTPathAppend(aDir, aDirLen, VBOX_USER_HOME_SUFFIX);
209 }
210
211 /* ensure the home directory exists */
212 if (RT_SUCCESS(vrc))
213 if (!RTDirExists(aDir) && fCreateDir)
214 vrc = RTDirCreateFullPath(aDir, 0700);
215 }
216
217 return vrc;
218}
219
220static const char *g_pszLogEntity = NULL;
221
222static void vboxHeaderFooter(PRTLOGGER pReleaseLogger, RTLOGPHASE enmPhase, PFNRTLOGPHASEMSG pfnLog)
223{
224 /* some introductory information */
225 static RTTIMESPEC s_TimeSpec;
226 char szTmp[256];
227 if (enmPhase == RTLOGPHASE_BEGIN)
228 RTTimeNow(&s_TimeSpec);
229 RTTimeSpecToString(&s_TimeSpec, szTmp, sizeof(szTmp));
230
231 switch (enmPhase)
232 {
233 case RTLOGPHASE_BEGIN:
234 {
235 bool fOldBuffered = RTLogSetBuffering(pReleaseLogger, true /*fBuffered*/);
236 pfnLog(pReleaseLogger,
237 "VirtualBox %s %s r%u %s (%s %s) release log\n"
238#ifdef VBOX_BLEEDING_EDGE
239 "EXPERIMENTAL build " VBOX_BLEEDING_EDGE "\n"
240#endif
241 "Log opened %s\n",
242 g_pszLogEntity, VBOX_VERSION_STRING, RTBldCfgRevision(),
243 RTBldCfgTargetDotArch(), __DATE__, __TIME__, szTmp);
244
245 int vrc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szTmp, sizeof(szTmp));
246 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
247 pfnLog(pReleaseLogger, "OS Product: %s\n", szTmp);
248 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szTmp, sizeof(szTmp));
249 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
250 pfnLog(pReleaseLogger, "OS Release: %s\n", szTmp);
251 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szTmp, sizeof(szTmp));
252 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
253 pfnLog(pReleaseLogger, "OS Version: %s\n", szTmp);
254 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_SERVICE_PACK, szTmp, sizeof(szTmp));
255 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
256 pfnLog(pReleaseLogger, "OS Service Pack: %s\n", szTmp);
257
258 vrc = RTSystemQueryDmiString(RTSYSDMISTR_PRODUCT_NAME, szTmp, sizeof(szTmp));
259 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
260 pfnLog(pReleaseLogger, "DMI Product Name: %s\n", szTmp);
261 vrc = RTSystemQueryDmiString(RTSYSDMISTR_PRODUCT_VERSION, szTmp, sizeof(szTmp));
262 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
263 pfnLog(pReleaseLogger, "DMI Product Version: %s\n", szTmp);
264
265 uint64_t cbHostRam = 0, cbHostRamAvail = 0;
266 vrc = RTSystemQueryTotalRam(&cbHostRam);
267 if (RT_SUCCESS(vrc))
268 vrc = RTSystemQueryAvailableRam(&cbHostRamAvail);
269 if (RT_SUCCESS(vrc))
270 pfnLog(pReleaseLogger, "Host RAM: %lluMB RAM, available: %lluMB\n",
271 cbHostRam / _1M, cbHostRamAvail / _1M);
272
273 /* the package type is interesting for Linux distributions */
274 char szExecName[RTPATH_MAX];
275 char *pszExecName = RTProcGetExecutablePath(szExecName, sizeof(szExecName));
276 pfnLog(pReleaseLogger,
277 "Executable: %s\n"
278 "Process ID: %u\n"
279 "Package type: %s"
280#ifdef VBOX_OSE
281 " (OSE)"
282#endif
283 "\n",
284 pszExecName ? pszExecName : "unknown",
285 RTProcSelf(),
286 VBOX_PACKAGE_STRING);
287 RTLogSetBuffering(pReleaseLogger, fOldBuffered);
288 break;
289 }
290 case RTLOGPHASE_PREROTATE:
291 pfnLog(pReleaseLogger, "Log rotated - Log started %s\n", szTmp);
292 break;
293
294 case RTLOGPHASE_POSTROTATE:
295 pfnLog(pReleaseLogger, "Log continuation - Log started %s\n", szTmp);
296 break;
297
298 case RTLOGPHASE_END:
299 pfnLog(pReleaseLogger, "End of log file - Log started %s\n", szTmp);
300 break;
301
302 default:
303 /* nothing */;
304 }
305}
306
307int VBoxLogRelCreate(const char *pcszEntity, const char *pcszLogFile,
308 uint32_t fFlags, const char *pcszGroupSettings,
309 const char *pcszEnvVarBase, uint32_t fDestFlags,
310 uint32_t cMaxEntriesPerGroup, uint32_t cHistory,
311 uint32_t uHistoryFileTime, uint64_t uHistoryFileSize,
312 char *pszError, size_t cbError)
313{
314 Assert(cbError >= RTPATH_MAX + 128);
315
316 /* create release logger */
317 PRTLOGGER pReleaseLogger;
318 static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
319#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
320 fFlags |= RTLOGFLAGS_USECRLF;
321#endif
322 g_pszLogEntity = pcszEntity;
323 int vrc = RTLogCreateEx(&pReleaseLogger, fFlags, "all all.restrict default.unrestricted",
324 pcszEnvVarBase, RT_ELEMENTS(s_apszGroups), s_apszGroups, fDestFlags,
325 vboxHeaderFooter, cHistory, uHistoryFileSize, uHistoryFileTime,
326 pszError, cbError, pcszLogFile);
327 if (RT_SUCCESS(vrc))
328 {
329 /* make sure that we don't flood logfiles */
330 RTLogSetGroupLimit(pReleaseLogger, cMaxEntriesPerGroup);
331
332 /* explicitly flush the log, to have some info when buffering */
333 RTLogFlush(pReleaseLogger);
334
335 /* register this logger as the release logger */
336 RTLogRelSetDefaultInstance(pReleaseLogger);
337 }
338 return vrc;
339}
340
341
342/* static */
343const Guid Guid::Empty; /* default ctor is OK */
344
345#if defined (VBOX_WITH_XPCOM)
346
347/* static */
348const nsID *SafeGUIDArray::nsIDRef::Empty = (const nsID *)Guid::Empty.raw();
349
350#endif /* (VBOX_WITH_XPCOM) */
351
352/**
353 * Used by ComPtr and friends to log details about reference counting.
354 * @param pcszFormat
355 */
356void LogRef(const char *pcszFormat, ...)
357{
358 char *pszNewMsg;
359 va_list args;
360 va_start(args, pcszFormat);
361 RTStrAPrintfV(&pszNewMsg, pcszFormat, args);
362 LogDJ((pszNewMsg));
363 RTStrFree(pszNewMsg);
364 va_end(args);
365}
366
367} /* namespace com */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette