VirtualBox

source: vbox/trunk/src/VBox/Main/win32/svcmain.cpp@ 7936

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

The Giant CDDL Dual-License Header Change.

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