VirtualBox

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