VirtualBox

source: vbox/trunk/src/VBox/Main/win/svchlp.cpp@ 22875

Last change on this file since 22875 was 21878, checked in by vboxsync, 15 years ago

Main: coding style: have Main obey the standard VirtualBox coding style rules (no functional changes)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 7.5 KB
Line 
1/** @file
2 *
3 * Definition of SVC Helper Process control routines.
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 "svchlp.h"
23
24//#include "HostImpl.h"
25#include "Logging.h"
26
27#include <VBox/err.h>
28
29int netIfNetworkInterfaceHelperServer (SVCHlpClient *aClient,
30 SVCHlpMsg::Code aMsgCode);
31
32using namespace com;
33
34enum { PipeBufSize = 1024 };
35
36////////////////////////////////////////////////////////////////////////////////
37
38/**
39 * GetLastError() is known to return NO_ERROR even after the Win32 API
40 * function (i.e. Write() to a non-connected server end of a pipe) returns
41 * FALSE... This method ensures that at least VERR_GENERAL_FAILURE is returned
42 * in cases like that. Intended to be called immediately after a failed API
43 * call.
44 */
45static inline int rtErrConvertFromWin32OnFailure()
46{
47 DWORD err = GetLastError();
48 return err == NO_ERROR ? VERR_GENERAL_FAILURE
49 : RTErrConvertFromWin32 (err);
50}
51
52////////////////////////////////////////////////////////////////////////////////
53
54SVCHlpClient::SVCHlpClient()
55 : mIsOpen (false), mIsServer (false)
56 , mReadEnd (NULL), mWriteEnd (NULL)
57{
58}
59
60SVCHlpClient::~SVCHlpClient()
61{
62 close();
63}
64
65int SVCHlpClient::create (const char *aName)
66{
67 AssertReturn(aName, VERR_INVALID_PARAMETER);
68
69 if (mIsOpen)
70 return VERR_WRONG_ORDER;
71
72 Bstr pipeName = Utf8StrFmt ("\\\\.\\pipe\\%s", aName);
73
74 HANDLE pipe = CreateNamedPipe (pipeName,
75 PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
76 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
77 1, // PIPE_UNLIMITED_INSTANCES,
78 PipeBufSize, PipeBufSize,
79 NMPWAIT_USE_DEFAULT_WAIT,
80 NULL);
81
82 if (pipe == INVALID_HANDLE_VALUE)
83 rtErrConvertFromWin32OnFailure();
84
85 mIsOpen = true;
86 mIsServer = true;
87 mReadEnd = pipe;
88 mWriteEnd = pipe;
89 mName = aName;
90
91 return VINF_SUCCESS;
92}
93
94int SVCHlpClient::open (const char *aName)
95{
96 AssertReturn(aName, VERR_INVALID_PARAMETER);
97
98 if (mIsOpen)
99 return VERR_WRONG_ORDER;
100
101 Bstr pipeName = Utf8StrFmt ("\\\\.\\pipe\\%s", aName);
102
103 HANDLE pipe = CreateFile (pipeName,
104 GENERIC_READ | GENERIC_WRITE,
105 0,
106 NULL,
107 OPEN_EXISTING,
108 0,
109 NULL);
110
111 if (pipe == INVALID_HANDLE_VALUE)
112 rtErrConvertFromWin32OnFailure();
113
114 mIsOpen = true;
115 mIsServer = false;
116 mReadEnd = pipe;
117 mWriteEnd = pipe;
118 mName = aName;
119
120 return VINF_SUCCESS;
121}
122
123int SVCHlpClient::connect()
124{
125 if (!mIsOpen || !mIsServer)
126 return VERR_WRONG_ORDER;
127
128 BOOL ok = ConnectNamedPipe (mReadEnd, NULL);
129 if (!ok && GetLastError() != ERROR_PIPE_CONNECTED)
130 rtErrConvertFromWin32OnFailure();
131
132 return VINF_SUCCESS;
133}
134
135int SVCHlpClient::close()
136{
137 if (!mIsOpen)
138 return VERR_WRONG_ORDER;
139
140 if (mWriteEnd != NULL && mWriteEnd != mReadEnd)
141 {
142 if (!CloseHandle (mWriteEnd))
143 rtErrConvertFromWin32OnFailure();
144 mWriteEnd = NULL;
145 }
146
147 if (mReadEnd != NULL)
148 {
149 if (!CloseHandle (mReadEnd))
150 rtErrConvertFromWin32OnFailure();
151 mReadEnd = NULL;
152 }
153
154 mIsOpen = false;
155 mIsServer = false;
156 mName.setNull();
157
158 return VINF_SUCCESS;
159}
160
161int SVCHlpClient::write (const void *aVal, size_t aLen)
162{
163 AssertReturn(aVal != NULL, VERR_INVALID_PARAMETER);
164 AssertReturn(aLen != 0, VERR_INVALID_PARAMETER);
165
166 if (!mIsOpen)
167 return VERR_WRONG_ORDER;
168
169 DWORD written = 0;
170 BOOL ok = WriteFile (mWriteEnd, aVal, (ULONG)aLen, &written, NULL);
171 AssertReturn(!ok || written == aLen, VERR_GENERAL_FAILURE);
172 return ok ? VINF_SUCCESS : rtErrConvertFromWin32OnFailure();
173}
174
175int SVCHlpClient::write (const Utf8Str &aVal)
176{
177 if (!mIsOpen)
178 return VERR_WRONG_ORDER;
179
180 /* write -1 for NULL strings */
181 if (aVal.isEmpty())
182 return write ((size_t) ~0);
183
184 size_t len = aVal.length();
185
186 /* write string length */
187 int vrc = write (len);
188 if (RT_SUCCESS(vrc))
189 {
190 /* write string data */
191 vrc = write (aVal.raw(), len);
192 }
193
194 return vrc;
195}
196
197int SVCHlpClient::write (const Guid &aGuid)
198{
199 Utf8Str guidStr = aGuid.toString();
200 return write (guidStr);
201}
202
203int SVCHlpClient::read (void *aVal, size_t aLen)
204{
205 AssertReturn(aVal != NULL, VERR_INVALID_PARAMETER);
206 AssertReturn(aLen != 0, VERR_INVALID_PARAMETER);
207
208 if (!mIsOpen)
209 return VERR_WRONG_ORDER;
210
211 DWORD read = 0;
212 BOOL ok = ReadFile (mReadEnd, aVal, (ULONG)aLen, &read, NULL);
213 AssertReturn(!ok || read == aLen, VERR_GENERAL_FAILURE);
214 return ok ? VINF_SUCCESS : rtErrConvertFromWin32OnFailure();
215}
216
217int SVCHlpClient::read (Utf8Str &aVal)
218{
219 if (!mIsOpen)
220 return VERR_WRONG_ORDER;
221
222 size_t len = 0;
223
224 /* read string length */
225 int vrc = read (len);
226 if (RT_FAILURE(vrc))
227 return vrc;
228
229 /* length -1 means a NULL string */
230 if (len == (size_t) ~0)
231 {
232 aVal.setNull();
233 return VINF_SUCCESS;
234 }
235
236 aVal.reserve(len + 1);
237 aVal.mutableRaw() [len] = 0;
238
239 /* read string data */
240 vrc = read (aVal.mutableRaw(), len);
241
242 return vrc;
243}
244
245int SVCHlpClient::read (Guid &aGuid)
246{
247 Utf8Str guidStr;
248 int vrc = read (guidStr);
249 if (RT_SUCCESS(vrc))
250 aGuid = Guid (guidStr.c_str());
251 return vrc;
252}
253
254////////////////////////////////////////////////////////////////////////////////
255
256SVCHlpServer::SVCHlpServer ()
257{
258}
259
260int SVCHlpServer::run()
261{
262 int vrc = VINF_SUCCESS;
263 SVCHlpMsg::Code msgCode = SVCHlpMsg::Null;
264
265 do
266 {
267 vrc = read (msgCode);
268 if (RT_FAILURE(vrc))
269 return vrc;
270
271 /* terminate request received */
272 if (msgCode == SVCHlpMsg::Null)
273 return VINF_SUCCESS;
274
275 switch (msgCode)
276 {
277 case SVCHlpMsg::CreateHostOnlyNetworkInterface:
278 case SVCHlpMsg::RemoveHostOnlyNetworkInterface:
279 case SVCHlpMsg::EnableDynamicIpConfig:
280 case SVCHlpMsg::EnableStaticIpConfig:
281 case SVCHlpMsg::EnableStaticIpConfigV6:
282 case SVCHlpMsg::DhcpRediscover:
283 {
284#ifdef VBOX_WITH_NETFLT
285 vrc = netIfNetworkInterfaceHelperServer (this, msgCode);
286#endif
287 break;
288 }
289 default:
290 AssertMsgFailedReturn ((
291 "Invalid message code %d (%08lX)\n", msgCode, msgCode),
292 VERR_GENERAL_FAILURE);
293 }
294
295 if (RT_FAILURE(vrc))
296 return vrc;
297 }
298 while (1);
299
300 /* we never get here */
301 AssertFailed();
302 return VERR_GENERAL_FAILURE;
303}
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