VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/win/svchlp.cpp

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use