VirtualBox

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

Last change on this file since 3874 was 3861, checked in by vboxsync, 18 years ago

use generic functions for determining paths instead of home-brewn solutions

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.2 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 , mComponentDirLocation (NULL), mCurrProcDirLocation (NULL)
67 {}
68
69 virtual ~DirectoryServiceProvider();
70
71 HRESULT init (const char *aCompRegLocation,
72 const char *aXPTIDatLocation,
73 const char *aComponentDirLocation,
74 const char *aCurrProcDirLocation);
75
76 NS_DECL_NSIDIRECTORYSERVICEPROVIDER
77
78private:
79
80 char *mCompRegLocation;
81 char *mXPTIDatLocation;
82 char *mComponentDirLocation;
83 char *mCurrProcDirLocation;
84};
85
86NS_IMPL_ISUPPORTS1 (DirectoryServiceProvider, nsIDirectoryServiceProvider)
87
88DirectoryServiceProvider::~DirectoryServiceProvider()
89{
90 if (mCompRegLocation)
91 {
92 RTStrFree (mCompRegLocation);
93 mCompRegLocation = NULL;
94 }
95 if (mXPTIDatLocation)
96 {
97 RTStrFree (mXPTIDatLocation);
98 mXPTIDatLocation = NULL;
99 }
100 if (mComponentDirLocation)
101 {
102 RTStrFree (mComponentDirLocation);
103 mComponentDirLocation = NULL;
104 }
105 if (mCurrProcDirLocation)
106 {
107 RTStrFree (mCurrProcDirLocation);
108 mCurrProcDirLocation = NULL;
109 }
110}
111
112/**
113 * @param aCompRegLocation Path to compreg.dat, in Utf8.
114 * @param aXPTIDatLocation Path to xpti.data, in Utf8.
115 */
116HRESULT
117DirectoryServiceProvider::init (const char *aCompRegLocation,
118 const char *aXPTIDatLocation,
119 const char *aComponentDirLocation,
120 const char *aCurrProcDirLocation)
121{
122 AssertReturn (aCompRegLocation, NS_ERROR_INVALID_ARG);
123 AssertReturn (aXPTIDatLocation, NS_ERROR_INVALID_ARG);
124
125 int vrc = RTStrUtf8ToCurrentCP (&mCompRegLocation, aCompRegLocation);
126 if (RT_SUCCESS (vrc))
127 vrc = RTStrUtf8ToCurrentCP (&mXPTIDatLocation, aXPTIDatLocation);
128 if (RT_SUCCESS (vrc) && aComponentDirLocation)
129 vrc = RTStrUtf8ToCurrentCP (&mComponentDirLocation, aComponentDirLocation);
130 if (RT_SUCCESS (vrc) && aCurrProcDirLocation)
131 vrc = RTStrUtf8ToCurrentCP (&mCurrProcDirLocation, aCurrProcDirLocation);
132
133 return RT_SUCCESS (vrc) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
134}
135
136NS_IMETHODIMP
137DirectoryServiceProvider::GetFile (const char *aProp,
138 PRBool *aPersistent,
139 nsIFile **aRetval)
140{
141 nsCOMPtr <nsILocalFile> localFile;
142 nsresult rv = NS_ERROR_FAILURE;
143
144 *aRetval = nsnull;
145 *aPersistent = PR_TRUE;
146
147 const char *fileLocation = NULL;
148
149 if (strcmp (aProp, NS_XPCOM_COMPONENT_REGISTRY_FILE) == 0)
150 fileLocation = mCompRegLocation;
151 else if (strcmp (aProp, NS_XPCOM_XPTI_REGISTRY_FILE) == 0)
152 fileLocation = mXPTIDatLocation;
153 else if (mComponentDirLocation && strcmp (aProp, NS_XPCOM_COMPONENT_DIR) == 0)
154 fileLocation = mComponentDirLocation;
155 else if (mCurrProcDirLocation && strcmp (aProp, NS_XPCOM_CURRENT_PROCESS_DIR) == 0)
156 fileLocation = mCurrProcDirLocation;
157 else
158 return NS_ERROR_FAILURE;
159
160 rv = NS_NewNativeLocalFile (nsEmbedCString (fileLocation),
161 PR_TRUE, getter_AddRefs (localFile));
162 if (NS_FAILED(rv))
163 return rv;
164
165 return localFile->QueryInterface (NS_GET_IID (nsIFile),
166 (void **) aRetval);
167}
168
169#endif /* defined (VBOX_WITH_XPCOM) */
170
171HRESULT Initialize()
172{
173 HRESULT rc = E_FAIL;
174
175#if !defined (VBOX_WITH_XPCOM)
176
177 rc = CoInitializeEx (NULL, COINIT_MULTITHREADED |
178 COINIT_DISABLE_OLE1DDE |
179 COINIT_SPEED_OVER_MEMORY);
180
181#else /* !defined (VBOX_WITH_XPCOM) */
182
183 /* Set VBOX_XPCOM_HOME if not present */
184 if (!RTEnvExist ("VBOX_XPCOM_HOME"))
185 {
186 /* get the executable path */
187 char pathProgram [RTPATH_MAX];
188 int vrc = RTPathProgram (pathProgram, sizeof (pathProgram));
189 if (RT_SUCCESS (vrc))
190 {
191 char *pathProgramCP = NULL;
192 vrc = RTStrUtf8ToCurrentCP (&pathProgramCP, pathProgram);
193 if (RT_SUCCESS (vrc))
194 {
195 vrc = RTEnvSet ("VBOX_XPCOM_HOME", pathProgramCP);
196 RTStrFree (pathProgramCP);
197 }
198 }
199 AssertRC (vrc);
200 }
201
202 nsCOMPtr <nsIEventQueue> eventQ;
203 rc = NS_GetMainEventQ (getter_AddRefs (eventQ));
204 if (rc == NS_ERROR_NOT_INITIALIZED)
205 {
206 XPCOMGlueStartup (nsnull);
207
208 nsCOMPtr <DirectoryServiceProvider> dsProv;
209
210 /* prepare paths for registry files */
211 char homeDir [RTPATH_MAX];
212 char privateArchDir [RTPATH_MAX];
213 int vrc = GetVBoxUserHomeDirectory (homeDir, sizeof (homeDir));
214 if (RT_SUCCESS (vrc))
215 vrc = RTPathAppPrivateArch (privateArchDir, sizeof (privateArchDir));
216 if (RT_SUCCESS (vrc))
217 {
218 char compReg [RTPATH_MAX];
219 char xptiDat [RTPATH_MAX];
220 char compDir [RTPATH_MAX];
221
222 RTStrPrintf (compReg, sizeof (compReg), "%s%c%s",
223 homeDir, RTPATH_DELIMITER, "compreg.dat");
224 RTStrPrintf (xptiDat, sizeof (xptiDat), "%s%c%s",
225 homeDir, RTPATH_DELIMITER, "xpti.dat");
226 RTStrPrintf (compDir, sizeof (compDir), "%s%c/components",
227 privateArchDir, RTPATH_DELIMITER);
228
229 dsProv = new DirectoryServiceProvider();
230 if (dsProv)
231 rc = dsProv->init (compReg, xptiDat, compDir, privateArchDir);
232 else
233 rc = NS_ERROR_OUT_OF_MEMORY;
234 }
235 else
236 rc = NS_ERROR_FAILURE;
237
238 /* get the path to the executable */
239 nsCOMPtr <nsIFile> appDir;
240 {
241 char path [RTPATH_MAX];
242 char *appDirCP = NULL;
243#if defined (DEBUG)
244 const char *env = RTEnvGet ("VIRTUALBOX_APP_HOME");
245 if (env)
246 {
247 char *appDirUtf8 = NULL;
248 vrc = RTStrCurrentCPToUtf8 (&appDirUtf8, env);
249 if (RT_SUCCESS (vrc))
250 {
251 vrc = RTPathReal (appDirUtf8, path, RTPATH_MAX);
252 if (RT_SUCCESS (vrc))
253 vrc = RTStrUtf8ToCurrentCP (&appDirCP, appDirUtf8);
254 RTStrFree (appDirUtf8);
255 }
256 }
257 else
258#endif
259 {
260 vrc = RTPathProgram (path, RTPATH_MAX);
261 if (RT_SUCCESS (vrc))
262 vrc = RTStrUtf8ToCurrentCP (&appDirCP, path);
263 }
264
265 if (RT_SUCCESS (vrc))
266 {
267 nsCOMPtr <nsILocalFile> file;
268 rc = NS_NewNativeLocalFile (nsEmbedCString (appDirCP),
269 PR_FALSE, getter_AddRefs (file));
270 if (NS_SUCCEEDED (rc))
271 appDir = do_QueryInterface (file, &rc);
272
273 RTStrFree (appDirCP);
274 }
275 else
276 rc = NS_ERROR_FAILURE;
277 }
278
279 /* Finally, initialize XPCOM */
280 if (NS_SUCCEEDED (rc))
281 {
282 nsCOMPtr <nsIServiceManager> serviceManager;
283 rc = NS_InitXPCOM2 (getter_AddRefs (serviceManager),
284 appDir, dsProv);
285
286 if (NS_SUCCEEDED (rc))
287 {
288 nsCOMPtr <nsIComponentRegistrar> registrar =
289 do_QueryInterface (serviceManager, &rc);
290 if (NS_SUCCEEDED (rc))
291 registrar->AutoRegister (nsnull);
292 }
293 }
294 }
295
296#endif /* !defined (VBOX_WITH_XPCOM) */
297
298 AssertComRC (rc);
299
300 return rc;
301}
302
303HRESULT Shutdown()
304{
305 HRESULT rc = S_OK;
306
307#if !defined (VBOX_WITH_XPCOM)
308
309 CoUninitialize();
310
311#else /* !defined (VBOX_WITH_XPCOM) */
312
313 nsCOMPtr <nsIEventQueue> eventQ;
314 rc = NS_GetMainEventQ (getter_AddRefs (eventQ));
315
316 if (NS_SUCCEEDED (rc) || rc == NS_ERROR_NOT_AVAILABLE)
317 {
318 /* NS_ERROR_NOT_AVAILABLE seems to mean that
319 * nsIEventQueue::StopAcceptingEvents() has been called (see
320 * nsEventQueueService.cpp). We hope that this error code always means
321 * just that in this case and assume that we're on the main thread
322 * (it's a kind of unexpected behavior if a non-main thread ever calls
323 * StopAcceptingEvents() on the main event queue). */
324
325 BOOL isOnMainThread = FALSE;
326 if (NS_SUCCEEDED (rc))
327 {
328 rc = eventQ->IsOnCurrentThread (&isOnMainThread);
329 eventQ = nsnull; /* early release */
330 }
331 else
332 {
333 isOnMainThread = TRUE;
334 rc = NS_OK;
335 }
336
337 if (NS_SUCCEEDED (rc) && isOnMainThread)
338 {
339 /* only the main thread needs to uninitialize XPCOM */
340 rc = NS_ShutdownXPCOM (nsnull);
341 XPCOMGlueShutdown();
342 }
343 }
344
345#endif /* !defined (VBOX_WITH_XPCOM) */
346
347 AssertComRC (rc);
348
349 return rc;
350}
351
352}; // 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