VirtualBox

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

Last change on this file since 14515 was 13837, checked in by vboxsync, 16 years ago

s/%Vr\([acfs]\)/%Rr\1/g - since I'm upsetting everyone anyway, better make the most of it...

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