VirtualBox

source: vbox/trunk/src/VBox/Main/win32/svchlp.cpp@ 172

Last change on this file since 172 was 8, checked in by vboxsync, 18 years ago

Add Windows svchlp code.

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