VirtualBox

source: vbox/trunk/src/VBox/Main/linux/server_module.cpp@ 3317

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

InnoTek -> innotek: all the headers and comments.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 8.5 KB
Line 
1/** @file
2 *
3 * XPCOM server process hepler module implementation functions
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
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 as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * If you received this file as part of a commercial VirtualBox
18 * distribution, then only the terms of your commercial VirtualBox
19 * license agreement apply instead of the previous paragraph.
20 */
21
22#include <nsMemory.h>
23#include <nsString.h>
24#include <nsCOMPtr.h>
25#include <nsIFile.h>
26#include <nsIGenericFactory.h>
27#include <nsIServiceManagerUtils.h>
28#include <nsICategoryManager.h>
29#include <nsDirectoryServiceDefs.h>
30
31#include <ipcIService.h>
32#include <ipcIDConnectService.h>
33#include <ipcCID.h>
34#include <ipcdclient.h>
35
36// official XPCOM headers don't define it yet
37#define IPC_DCONNECTSERVICE_CONTRACTID \
38 "@mozilla.org/ipc/dconnect-service;1"
39
40// generated file
41#include <VirtualBox_XPCOM.h>
42
43#include "linux/server.h"
44#include "Logging.h"
45
46#include <VBox/err.h>
47
48#include <iprt/param.h>
49#include <iprt/path.h>
50#include <iprt/process.h>
51#include <iprt/thread.h>
52
53#include <string.h>
54
55
56/// @todo move this to RT headers (and use them in MachineImpl.cpp as well)
57#if defined(__WIN__) || defined(__OS2__)
58#define HOSTSUFF_EXE ".exe"
59#else /* !__WIN__ */
60#define HOSTSUFF_EXE ""
61#endif /* !__WIN__ */
62
63
64/** Name of the server executable. */
65const char VBoxSVC_exe[] = RTPATH_SLASH_STR "VBoxSVC" HOSTSUFF_EXE;
66
67enum
68{
69 /** Amount of time to wait for the server to establish a connection, ms */
70 VBoxSVC_Timeout = 30000,
71 /** How often to perform a connection check, ms */
72 VBoxSVC_WaitSlice = 100,
73};
74
75/**
76 * Full path to the VBoxSVC executable.
77 */
78static char VBoxSVCPath [RTPATH_MAX];
79static bool IsVBoxSVCPathSet = false;
80
81/*
82 * The following macros define the method necessary to provide a list of
83 * interfaces implemented by the VirtualBox component. Note that this must be
84 * in sync with macros used for VirtualBox in server.cpp for the same purpose.
85 */
86
87NS_DECL_CLASSINFO (VirtualBox)
88NS_IMPL_CI_INTERFACE_GETTER1 (VirtualBox, IVirtualBox)
89
90/**
91 * VirtualBox component constructor.
92 *
93 * This constructor is responsible for starting the VirtualBox server
94 * process, connecting to it, and redirecting the constructor request to the
95 * VirtualBox component defined on the server.
96 */
97static NS_IMETHODIMP
98VirtualBoxConstructor (nsISupports *aOuter, REFNSIID aIID,
99 void **aResult)
100{
101 LogFlowFuncEnter();
102
103 nsresult rc = NS_OK;
104 int vrc = VINF_SUCCESS;
105
106 do
107 {
108 *aResult = NULL;
109 if (NULL != aOuter)
110 {
111 rc = NS_ERROR_NO_AGGREGATION;
112 break;
113 }
114
115 if (!IsVBoxSVCPathSet)
116 {
117 /* Get the directory containing XPCOM components -- the VBoxSVC
118 * executable is expected in the parent directory. */
119 nsCOMPtr <nsIProperties> dirServ = do_GetService (NS_DIRECTORY_SERVICE_CONTRACTID, &rc);
120 if (NS_SUCCEEDED (rc))
121 {
122 nsCOMPtr <nsIFile> componentDir;
123 rc = dirServ->Get (NS_XPCOM_COMPONENT_DIR,
124 NS_GET_IID (nsIFile), getter_AddRefs (componentDir));
125
126 if (NS_SUCCEEDED (rc))
127 {
128 nsCAutoString path;
129 componentDir->GetNativePath (path);
130
131 LogFlowFunc (("components path = \"%s\"\n", path.get()));
132 AssertBreak (path.Length() + strlen (VBoxSVC_exe) < RTPATH_MAX,
133 rc = NS_ERROR_FAILURE);
134
135 strcpy (VBoxSVCPath, path.get());
136 RTPathStripFilename (VBoxSVCPath);
137 strcat (VBoxSVCPath, VBoxSVC_exe);
138
139 IsVBoxSVCPathSet = true;
140 }
141 }
142 if (NS_FAILED (rc))
143 break;
144 }
145
146 nsCOMPtr <ipcIService> ipcServ = do_GetService (IPC_SERVICE_CONTRACTID, &rc);
147 if (NS_FAILED (rc))
148 break;
149
150 /* connect to the VBoxSVC server process */
151
152 bool startedOnce = false;
153 unsigned timeLeft = VBoxSVC_Timeout;
154
155 do
156 {
157 LogFlowFunc (("Resolving server name \"%s\"...\n", VBOXSVC_IPC_NAME));
158
159 PRUint32 serverID = 0;
160 rc = ipcServ->ResolveClientName (VBOXSVC_IPC_NAME, &serverID);
161 if (NS_FAILED (rc))
162 {
163 LogFlowFunc (("Starting server...\n", VBoxSVCPath));
164
165 startedOnce = true;
166
167 RTPROCESS pid = NIL_RTPROCESS;
168 const char *args[] = { VBoxSVCPath, "--automate", 0 };
169 vrc = RTProcCreate (VBoxSVCPath, args, NULL, 0, &pid);
170 if (VBOX_FAILURE (vrc))
171 {
172 rc = NS_ERROR_FAILURE;
173 break;
174 }
175
176 /* wait for the server process to establish a connection */
177 do
178 {
179 RTThreadSleep (VBoxSVC_WaitSlice);
180 rc = ipcServ->ResolveClientName (VBOXSVC_IPC_NAME, &serverID);
181 if (NS_SUCCEEDED (rc))
182 break;
183 if (timeLeft <= VBoxSVC_WaitSlice)
184 {
185 timeLeft = 0;
186 break;
187 }
188 timeLeft -= VBoxSVC_WaitSlice;
189 }
190 while (1);
191
192 if (!timeLeft)
193 {
194 rc = IPC_ERROR_WOULD_BLOCK;
195 break;
196 }
197 }
198
199 LogFlowFunc (("Connecting to server (ID=%d)...\n", serverID));
200
201 nsCOMPtr <ipcIDConnectService> dconServ =
202 do_GetService (IPC_DCONNECTSERVICE_CONTRACTID, &rc);
203 if (NS_FAILED (rc))
204 break;
205
206 rc = dconServ->CreateInstance (serverID,
207 (nsCID) NS_VIRTUALBOX_CID,
208 aIID, aResult);
209 if (NS_SUCCEEDED (rc))
210 break;
211
212 /* It's possible that the server gets shut down after we
213 * successfully resolve the server name but before it
214 * receives our CreateInstance() request. So, check for the
215 * name again, and restart the cycle if it fails. */
216 if (!startedOnce)
217 {
218 nsresult rc2 =
219 ipcServ->ResolveClientName (VBOXSVC_IPC_NAME, &serverID);
220 if (NS_SUCCEEDED (rc2))
221 break;
222 }
223 else
224 break;
225 }
226 while (1);
227 }
228 while (0);
229
230 LogFlowFunc (("rc=%08X, vrc=%Vrc\n", rc, vrc));
231 LogFlowFuncLeave();
232
233 return rc;
234}
235
236#if 0
237/// @todo not really necessary for the moment
238/**
239 *
240 * @param aCompMgr
241 * @param aPath
242 * @param aLoaderStr
243 * @param aType
244 * @param aInfo
245 *
246 * @return
247 */
248static NS_IMETHODIMP
249VirtualBoxRegistration (nsIComponentManager *aCompMgr,
250 nsIFile *aPath,
251 const char *aLoaderStr,
252 const char *aType,
253 const nsModuleComponentInfo *aInfo)
254{
255 nsCAutoString modulePath;
256 aPath->GetNativePath (modulePath);
257 nsCAutoString moduleTarget;
258 aPath->GetNativeTarget (moduleTarget);
259
260 LogFlowFunc (("aPath=%s, aTarget=%s, aLoaderStr=%s, aType=%s\n",
261 modulePath.get(), moduleTarget.get(), aLoaderStr, aType));
262
263 nsresult rc = NS_OK;
264
265 return rc;
266}
267#endif
268
269/**
270 * Component definition table.
271 * Lists all components defined in this module.
272 */
273static const nsModuleComponentInfo components[] =
274{
275 {
276 "VirtualBox component", // description
277 NS_VIRTUALBOX_CID, NS_VIRTUALBOX_CONTRACTID, // CID/ContractID
278 VirtualBoxConstructor, // constructor function
279 NULL, /* VirtualBoxRegistration, */ // registration function
280 NULL, // deregistration function
281 NULL, // destructor function
282 /// @todo
283 NS_CI_INTERFACE_GETTER_NAME(VirtualBox), // interfaces function
284 NULL, // language helper
285 /// @todo
286 &NS_CLASSINFO_NAME(VirtualBox) // global class info & flags
287 }
288};
289
290NS_IMPL_NSGETMODULE (VirtualBox_Server_Module, components)
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