VirtualBox

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

Last change on this file since 76900 was 76592, checked in by vboxsync, 6 years ago

Main: Don't use Logging.h.

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