VirtualBox

source: vbox/trunk/src/VBox/Main/win/svcmain.cpp@ 8765

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

The Big Sun Rebranding Header Change

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.5 KB
Line 
1/** @file
2 *
3 * SVCMAIN - COM out-of-proc server main entry
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22#include <stdio.h>
23
24#include "VBox/com/defs.h"
25
26#include "svchlp.h"
27
28#include <VBox/err.h>
29#include <iprt/runtime.h>
30
31#include "MachineImpl.h"
32#include "HardDiskImpl.h"
33#include "DVDImageImpl.h"
34#include "FloppyImageImpl.h"
35#include "GuestOSTypeImpl.h"
36#include "ProgressImpl.h"
37#include "SystemPropertiesImpl.h"
38#include "VirtualBoxImpl.h"
39
40#include "Logging.h"
41
42#include <atlbase.h>
43#include <atlcom.h>
44
45#define _ATL_FREE_THREADED
46
47class CExeModule : public CComModule
48{
49public:
50 LONG Unlock();
51 DWORD dwThreadID;
52 HANDLE hEventShutdown;
53 void MonitorShutdown();
54 bool StartMonitor();
55 bool bActivity;
56};
57
58const DWORD dwTimeOut = 5000; /* time for EXE to be idle before shutting down */
59const DWORD dwPause = 1000; /* time to wait for threads to finish up */
60
61/* Passed to CreateThread to monitor the shutdown event */
62static DWORD WINAPI MonitorProc(void* pv)
63{
64 CExeModule* p = (CExeModule*)pv;
65 p->MonitorShutdown();
66 return 0;
67}
68
69LONG CExeModule::Unlock()
70{
71 LONG l = CComModule::Unlock();
72 if (l == 0)
73 {
74 bActivity = true;
75 SetEvent(hEventShutdown); /* tell monitor that we transitioned to zero */
76 }
77 return l;
78}
79
80/* Monitors the shutdown event */
81void CExeModule::MonitorShutdown()
82{
83 while (1)
84 {
85 WaitForSingleObject(hEventShutdown, INFINITE);
86 DWORD dwWait=0;
87 do
88 {
89 bActivity = false;
90 dwWait = WaitForSingleObject(hEventShutdown, dwTimeOut);
91 } while (dwWait == WAIT_OBJECT_0);
92 /* timed out */
93 if (!bActivity && m_nLockCnt == 0) /* if no activity let's really bail */
94 {
95#if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
96 CoSuspendClassObjects();
97 if (!bActivity && m_nLockCnt == 0)
98#endif
99 break;
100 }
101 }
102 CloseHandle(hEventShutdown);
103 PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
104}
105
106bool CExeModule::StartMonitor()
107{
108 hEventShutdown = CreateEvent(NULL, false, false, NULL);
109 if (hEventShutdown == NULL)
110 return false;
111 DWORD dwThreadID;
112 HANDLE h = CreateThread(NULL, 0, MonitorProc, this, 0, &dwThreadID);
113 return (h != NULL);
114}
115
116CExeModule _Module;
117
118BEGIN_OBJECT_MAP(ObjectMap)
119 OBJECT_ENTRY(CLSID_VirtualBox, VirtualBox)
120END_OBJECT_MAP()
121
122
123LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2)
124{
125 while (p1 != NULL && *p1 != NULL)
126 {
127 LPCTSTR p = p2;
128 while (p != NULL && *p != NULL)
129 {
130 if (*p1 == *p)
131 return CharNext(p1);
132 p = CharNext(p);
133 }
134 p1 = CharNext(p1);
135 }
136 return NULL;
137}
138
139static int WordCmpI(LPCTSTR psz1, LPCTSTR psz2) throw()
140{
141 TCHAR c1 = (TCHAR)CharUpper((LPTSTR)*psz1);
142 TCHAR c2 = (TCHAR)CharUpper((LPTSTR)*psz2);
143 while (c1 != NULL && c1 == c2 && c1 != ' ' && c1 != '\t')
144 {
145 psz1 = CharNext(psz1);
146 psz2 = CharNext(psz2);
147 c1 = (TCHAR)CharUpper((LPTSTR)*psz1);
148 c2 = (TCHAR)CharUpper((LPTSTR)*psz2);
149 }
150 if ((c1 == NULL || c1 == ' ' || c1 == '\t') && (c2 == NULL || c2 == ' ' || c2 == '\t'))
151 return 0;
152
153 return (c1 < c2) ? -1 : 1;
154}
155
156/////////////////////////////////////////////////////////////////////////////
157//
158extern "C" int WINAPI _tWinMain(HINSTANCE hInstance,
159 HINSTANCE /*hPrevInstance*/, LPTSTR lpCmdLine, int /*nShowCmd*/)
160{
161 /*
162 * Initialize the VBox runtime without loading
163 * the support driver.
164 */
165 RTR3Init(false);
166
167 lpCmdLine = GetCommandLine(); /* this line necessary for _ATL_MIN_CRT */
168
169#if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
170 HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
171#else
172 HRESULT hRes = CoInitialize(NULL);
173#endif
174 _ASSERTE(SUCCEEDED(hRes));
175 _Module.Init(ObjectMap, hInstance, &LIBID_VirtualBox);
176 _Module.dwThreadID = GetCurrentThreadId();
177 TCHAR szTokens[] = _T("-/");
178
179 int nRet = 0;
180 BOOL bRun = TRUE;
181 LPCTSTR lpszToken = FindOneOf(lpCmdLine, szTokens);
182 while (lpszToken != NULL)
183 {
184 if (WordCmpI(lpszToken, _T("UnregServer")) == 0)
185 {
186 _Module.UpdateRegistryFromResource(IDR_VIRTUALBOX, FALSE);
187 nRet = _Module.UnregisterServer(TRUE);
188 bRun = FALSE;
189 break;
190 }
191 else if (WordCmpI(lpszToken, _T("RegServer")) == 0)
192 {
193 _Module.UpdateRegistryFromResource(IDR_VIRTUALBOX, TRUE);
194 nRet = _Module.RegisterServer(TRUE);
195 bRun = FALSE;
196 break;
197 }
198 else if (WordCmpI(lpszToken, _T("ReregServer")) == 0)
199 {
200 _Module.UpdateRegistryFromResource(IDR_VIRTUALBOX, FALSE);
201 nRet = _Module.UnregisterServer(TRUE);
202 _Module.UpdateRegistryFromResource(IDR_VIRTUALBOX, TRUE);
203 nRet = _Module.RegisterServer(TRUE);
204 bRun = FALSE;
205 break;
206 }
207 else if ( (WordCmpI(lpszToken, _T("h")) == 0)
208 || (WordCmpI(lpszToken, _T("?")) == 0))
209 {
210 TCHAR txt[]= L"Options:\n\n"
211 L"/RegServer:\tregister COM out-of-proc server\n"
212 L"/UnregServer:\tunregister COM out-of-proc server\n"
213 L"/ReregServer:\tunregister and register COM server\n"
214 L"no options:\trun the server";
215 TCHAR title[]=_T("Usage");
216 nRet = -1;
217 bRun = FALSE;
218 MessageBox(NULL, txt, title, MB_OK);
219 break;
220 }
221 else if (WordCmpI (lpszToken, _T("Helper")) == 0)
222 {
223 Log (("SVCMAIN: Processing Helper request (cmdline=\"%ls\")...\n",
224 lpszToken + 6));
225
226 TCHAR szTokens[] = _T (" \t");
227
228 int vrc = VINF_SUCCESS;
229 Utf8Str pipeName;
230
231 lpszToken = FindOneOf (lpszToken, szTokens);
232 if (lpszToken)
233 {
234 while (*lpszToken != NULL &&
235 (*lpszToken == ' ' || *lpszToken == '\t'))
236 ++ lpszToken;
237
238 if (*lpszToken != NULL)
239 {
240 Bstr str (lpszToken);
241 LPCTSTR lpszToken2 = FindOneOf (lpszToken, szTokens);
242 if (lpszToken2)
243 str.mutableRaw() [lpszToken2 - lpszToken] = '\0';
244 pipeName = Utf8Str (lpszToken);
245 }
246 }
247
248 if (pipeName.isEmpty())
249 vrc = VERR_INVALID_PARAMETER;
250
251 if (VBOX_SUCCESS (vrc))
252 {
253 /* do the helper job */
254 SVCHlpServer server;
255 vrc = server.open (pipeName);
256 if (VBOX_SUCCESS (vrc))
257 vrc = server.run();
258 }
259 if (VBOX_FAILURE (vrc))
260 {
261 Utf8Str err = Utf8StrFmt (
262 "Failed to process Helper request (%Vrc).", vrc);
263 Log (("SVCMAIN: %s\n", err.raw()));
264 }
265
266 /* don't run the COM server */
267 bRun = FALSE;
268 break;
269 }
270
271 lpszToken = FindOneOf(lpszToken, szTokens);
272 }
273
274 if (bRun)
275 {
276 _Module.StartMonitor();
277#if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
278 hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED);
279 _ASSERTE(SUCCEEDED(hRes));
280 hRes = CoResumeClassObjects();
281#else
282 hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE);
283#endif
284 _ASSERTE(SUCCEEDED(hRes));
285
286 MSG msg;
287 while (GetMessage(&msg, 0, 0, 0))
288 DispatchMessage(&msg);
289
290 _Module.RevokeClassObjects();
291 Sleep(dwPause); //wait for any threads to finish
292 }
293
294 _Module.Term();
295 CoUninitialize();
296 Log(("SVCMAIN: Returning, COM server process ends.\n"));
297 return nRet;
298}
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