VirtualBox

source: vbox/trunk/src/VBox/Main/glue/initterm.cpp@ 3387

Last change on this file since 3387 was 3387, checked in by vboxsync, 17 years ago

Main: com::GetVBoxUserHomeDirectory() now takes char * instead of Utf8Str because on XPCOM platforms, this function may be called before XPCOM has been initialized, when Utf8Str functionality is not yet available (because it uses XPCOM memory management).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.8 KB
Line 
1/** @file
2 * MS COM / XPCOM Abstraction Layer - Initialization and Termination.
3 */
4
5/*
6 * Copyright (C) 2006-2007 innotek GmbH
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License as published by the Free Software Foundation,
12 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
13 * distribution. VirtualBox OSE is distributed in the hope that it will
14 * be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * If you received this file as part of a commercial VirtualBox
17 * distribution, then only the terms of your commercial VirtualBox
18 * license agreement apply instead of the previous paragraph.
19 */
20
21#if !defined (VBOX_WITH_XPCOM)
22
23#include <objbase.h>
24
25#else /* !defined (VBOX_WITH_XPCOM) */
26
27#include <stdlib.h>
28
29#include <nsXPCOMGlue.h>
30#include <nsIComponentRegistrar.h>
31#include <nsIServiceManager.h>
32#include <nsCOMPtr.h>
33#include <nsEventQueueUtils.h>
34#include <nsEmbedString.h>
35
36#include <nsILocalFile.h>
37#include <nsIDirectoryService.h>
38#include <nsDirectoryServiceDefs.h>
39
40#endif /* !defined (VBOX_WITH_XPCOM) */
41
42#include <iprt/param.h>
43#include <iprt/path.h>
44#include <iprt/string.h>
45#include <iprt/env.h>
46
47#include <VBox/err.h>
48
49#include "VBox/com/com.h"
50#include "VBox/com/assert.h"
51
52
53namespace com
54{
55
56#if defined (VBOX_WITH_XPCOM)
57
58class DirectoryServiceProvider : public nsIDirectoryServiceProvider
59{
60public:
61
62 NS_DECL_ISUPPORTS
63
64 DirectoryServiceProvider()
65 : mCompRegLocation (NULL), mXPTIDatLocation (NULL)
66 {}
67
68 virtual ~DirectoryServiceProvider();
69
70 HRESULT init (const char *aCompRegLocation,
71 const char *aXPTIDatLocation);
72
73 NS_DECL_NSIDIRECTORYSERVICEPROVIDER
74
75private:
76
77 char *mCompRegLocation;
78 char *mXPTIDatLocation;
79};
80
81NS_IMPL_ISUPPORTS1 (DirectoryServiceProvider, nsIDirectoryServiceProvider)
82
83DirectoryServiceProvider::~DirectoryServiceProvider()
84{
85 if (mCompRegLocation)
86 {
87 RTStrFree (mCompRegLocation);
88 mCompRegLocation = NULL;
89 }
90 if (mXPTIDatLocation)
91 {
92 RTStrFree (mXPTIDatLocation);
93 mXPTIDatLocation = NULL;
94 }
95}
96
97/**
98 * @param aCompRegLocation Path to compreg.dat, in Utf8.
99 * @param aXPTIDatLocation Path to xpti.data, in Utf8.
100 */
101HRESULT
102DirectoryServiceProvider::init (const char *aCompRegLocation,
103 const char *aXPTIDatLocation)
104{
105 AssertReturn (aCompRegLocation, NS_ERROR_INVALID_ARG);
106 AssertReturn (aXPTIDatLocation, NS_ERROR_INVALID_ARG);
107
108 int vrc = RTStrUtf8ToCurrentCP (&mCompRegLocation, aCompRegLocation);
109 if (RT_SUCCESS (vrc))
110 vrc = RTStrUtf8ToCurrentCP (&mXPTIDatLocation, aXPTIDatLocation);
111
112 return RT_SUCCESS (vrc) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
113}
114
115NS_IMETHODIMP
116DirectoryServiceProvider::GetFile (const char *aProp,
117 PRBool *aPersistent,
118 nsIFile **aRetval)
119{
120 nsCOMPtr <nsILocalFile> localFile;
121 nsresult rv = NS_ERROR_FAILURE;
122
123 *aRetval = nsnull;
124 *aPersistent = PR_TRUE;
125
126 const char *fileLocation = NULL;
127
128 if (strcmp (aProp, NS_XPCOM_COMPONENT_REGISTRY_FILE) == 0)
129 fileLocation = mCompRegLocation;
130 else if (strcmp (aProp, NS_XPCOM_XPTI_REGISTRY_FILE) == 0)
131 fileLocation = mXPTIDatLocation;
132 else
133 return NS_ERROR_FAILURE;
134
135 rv = NS_NewNativeLocalFile (nsEmbedCString (fileLocation),
136 PR_TRUE, getter_AddRefs (localFile));
137 if (NS_FAILED(rv))
138 return rv;
139
140 return localFile->QueryInterface (NS_GET_IID (nsIFile),
141 (void **) aRetval);
142}
143
144#endif /* defined (VBOX_WITH_XPCOM) */
145
146HRESULT Initialize()
147{
148 HRESULT rc = E_FAIL;
149
150#if !defined (VBOX_WITH_XPCOM)
151
152 rc = CoInitializeEx (NULL, COINIT_MULTITHREADED |
153 COINIT_DISABLE_OLE1DDE |
154 COINIT_SPEED_OVER_MEMORY);
155
156#else /* !defined (VBOX_WITH_XPCOM) */
157
158 /* Set VBOX_XPCOM_HOME if not present */
159 if (!RTEnvExist ("VBOX_XPCOM_HOME"))
160 {
161 /* get the executable path */
162 char pathProgram [RTPATH_MAX];
163 int vrc = RTPathProgram (pathProgram, sizeof (pathProgram));
164 if (RT_SUCCESS (vrc))
165 {
166 char *pathProgramCP = NULL;
167 vrc = RTStrUtf8ToCurrentCP (&pathProgramCP, pathProgram);
168 if (RT_SUCCESS (vrc))
169 {
170 vrc = RTEnvSet ("VBOX_XPCOM_HOME", pathProgramCP);
171 RTStrFree (pathProgramCP);
172 }
173 }
174 AssertRC (vrc);
175 }
176
177 nsCOMPtr <nsIEventQueue> eventQ;
178 rc = NS_GetMainEventQ (getter_AddRefs (eventQ));
179 if (rc == NS_ERROR_NOT_INITIALIZED)
180 {
181 XPCOMGlueStartup (nsnull);
182
183 nsCOMPtr <DirectoryServiceProvider> dsProv;
184
185 /* prepare paths for registry files */
186 char homeDir [RTPATH_MAX];
187 int vrc = GetVBoxUserHomeDirectory (homeDir, sizeof (homeDir));
188 if (RT_SUCCESS (vrc))
189 {
190 char compReg [RTPATH_MAX];
191 char xptiDat [RTPATH_MAX];
192
193 RTStrPrintf (compReg, sizeof (compReg), "%s%c%s",
194 homeDir, RTPATH_DELIMITER, "compreg.dat");
195 RTStrPrintf (xptiDat, sizeof (xptiDat), "%s%c%s",
196 homeDir, RTPATH_DELIMITER, "xpti.dat");
197
198 dsProv = new DirectoryServiceProvider();
199 if (dsProv)
200 rc = dsProv->init (compReg, xptiDat);
201 else
202 rc = NS_ERROR_OUT_OF_MEMORY;
203 }
204 else
205 rc = NS_ERROR_FAILURE;
206
207 /* get the path to the executable */
208 nsCOMPtr <nsIFile> appDir;
209 {
210 char path [RTPATH_MAX];
211 char *appDirCP = NULL;
212#if defined (DEBUG)
213 const char *env = RTEnvGet ("VIRTUALBOX_APP_HOME");
214 if (env)
215 {
216 char *appDirUtf8 = NULL;
217 vrc = RTStrCurrentCPToUtf8 (&appDirUtf8, env);
218 if (RT_SUCCESS (vrc))
219 {
220 vrc = RTPathReal (appDirUtf8, path, RTPATH_MAX);
221 if (RT_SUCCESS (vrc))
222 vrc = RTStrUtf8ToCurrentCP (&appDirCP, appDirUtf8);
223 RTStrFree (appDirUtf8);
224 }
225 }
226 else
227#endif
228 {
229 vrc = RTPathProgram (path, RTPATH_MAX);
230 if (RT_SUCCESS (vrc))
231 vrc = RTStrUtf8ToCurrentCP (&appDirCP, path);
232 }
233
234 if (RT_SUCCESS (vrc))
235 {
236 nsCOMPtr <nsILocalFile> file;
237 rc = NS_NewNativeLocalFile (nsEmbedCString (appDirCP),
238 PR_FALSE, getter_AddRefs (file));
239 if (NS_SUCCEEDED (rc))
240 appDir = do_QueryInterface (file, &rc);
241
242 RTStrFree (appDirCP);
243 }
244 else
245 rc = NS_ERROR_FAILURE;
246 }
247
248 /* Finally, initialize XPCOM */
249 if (NS_SUCCEEDED (rc))
250 {
251 nsCOMPtr <nsIServiceManager> serviceManager;
252 rc = NS_InitXPCOM2 (getter_AddRefs (serviceManager),
253 appDir, dsProv);
254
255 if (NS_SUCCEEDED (rc))
256 {
257 nsCOMPtr <nsIComponentRegistrar> registrar =
258 do_QueryInterface (serviceManager, &rc);
259 if (NS_SUCCEEDED (rc))
260 registrar->AutoRegister (nsnull);
261 }
262 }
263 }
264
265#endif /* !defined (VBOX_WITH_XPCOM) */
266
267 AssertComRC (rc);
268
269 return rc;
270}
271
272HRESULT Shutdown()
273{
274 HRESULT rc = S_OK;
275
276#if !defined (VBOX_WITH_XPCOM)
277
278 CoUninitialize();
279
280#else /* !defined (VBOX_WITH_XPCOM) */
281
282 nsCOMPtr <nsIEventQueue> eventQ;
283 rc = NS_GetMainEventQ (getter_AddRefs (eventQ));
284
285 if (NS_SUCCEEDED (rc) || rc == NS_ERROR_NOT_AVAILABLE)
286 {
287 /* NS_ERROR_NOT_AVAILABLE seems to mean that
288 * nsIEventQueue::StopAcceptingEvents() has been called (see
289 * nsEventQueueService.cpp). We hope that this error code always means
290 * just that in this case and assume that we're on the main thread
291 * (it's a kind of unexpected behavior if a non-main thread ever calls
292 * StopAcceptingEvents() on the main event queue). */
293
294 BOOL isOnMainThread = FALSE;
295 if (NS_SUCCEEDED (rc))
296 {
297 rc = eventQ->IsOnCurrentThread (&isOnMainThread);
298 eventQ = nsnull; /* early release */
299 }
300 else
301 {
302 isOnMainThread = TRUE;
303 rc = NS_OK;
304 }
305
306 if (NS_SUCCEEDED (rc) && isOnMainThread)
307 {
308 /* only the main thread needs to uninitialize XPCOM */
309 rc = NS_ShutdownXPCOM (nsnull);
310 XPCOMGlueShutdown();
311 }
312 }
313
314#endif /* !defined (VBOX_WITH_XPCOM) */
315
316 AssertComRC (rc);
317
318 return rc;
319}
320
321}; // 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