9 kumpf 1.1 //
10 // Permission is hereby granted, free of charge, to any person obtaining a copy
11 // of this software and associated documentation files (the "Software"), to
12 // deal in the Software without restriction, including without limitation the
13 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
14 // sell copies of the Software, and to permit persons to whom the Software is
15 // furnished to do so, subject to the following conditions:
16 //
17 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
18 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
19 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
20 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
21 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 //
26 //==============================================================================
27 //
28 // Author: Carol Ann Krug Graves, Hewlett-Packard Company
29 // (carolann_graves@hp.com)
30 kumpf 1.1 //
31 // Modified By:
32 //
33 //%/////////////////////////////////////////////////////////////////////////////
34
35
36 #include "AnonymousPipe.h"
37 #include <Pegasus/Common/Signal.h>
38 #include <windows.h>
39 #include <stdio.h>
40
41
42 PEGASUS_NAMESPACE_BEGIN
43
44 AnonymousPipe::AnonymousPipe ()
45 {
46 PEG_METHOD_ENTER (TRC_OS_ABSTRACTION, "AnonymousPipe::AnonymousPipe ()");
47
48 AnonymousPipeHandle thePipe [2];
49
50 SECURITY_ATTRIBUTES saAttr;
51 kumpf 1.1 saAttr.nLength = sizeof (SECURITY_ATTRIBUTES);
52 saAttr.bInheritHandle = TRUE;
53 saAttr.lpSecurityDescriptor = NULL;
54
55 if (!CreatePipe (&thePipe [0], &thePipe [1], &saAttr, 0))
56 {
57 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
58 "Failed to create pipe. Error code: %d", GetLastError ());
59 PEG_METHOD_EXIT ();
60
61 MessageLoaderParms mlp ("Common.AnonymousPipe.CREATE_PIPE_FAILED",
62 "Failed to create pipe.");
63 throw Exception (mlp);
64 }
65
66 _readHandle = thePipe [0];
67 _writeHandle = thePipe [1];
68 _readOpen = true;
69 _writeOpen = true;
70
71 PEG_METHOD_EXIT ();
72 kumpf 1.1 }
73
74 AnonymousPipe::AnonymousPipe (
75 const char * readHandle,
76 const char * writeHandle)
77 {
78 PEG_METHOD_ENTER (TRC_OS_ABSTRACTION,
79 "AnonymousPipe::AnonymousPipe (const char *, const char *)");
80
81 _readHandle = 0;
82 _writeHandle = 0;
83 _readOpen = false;
84 _writeOpen = false;
85
86 if (readHandle != NULL)
87 {
88 if (sscanf (readHandle, "%p", &_readHandle) != 1)
89 {
90 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
91 "Failed to create pipe: invalid read handle %s", readHandle);
92 PEG_METHOD_EXIT ();
93 kumpf 1.1
94 MessageLoaderParms mlp ("Common.AnonymousPipe.CREATE_PIPE_FAILED",
95 "Failed to create pipe.");
96 throw Exception (mlp);
97 }
98 _readOpen = true;
99 }
100
101 if (writeHandle != NULL)
102 {
103 if (sscanf (writeHandle, "%p", &_writeHandle) != 1)
104 {
105 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
106 "Failed to create pipe: invalid write handle %s", writeHandle);
107 PEG_METHOD_EXIT ();
108
109 MessageLoaderParms mlp ("Common.AnonymousPipe.CREATE_PIPE_FAILED",
110 "Failed to create pipe.");
111 throw Exception (mlp);
112 }
113 _writeOpen = true;
114 kumpf 1.1 }
115
116 PEG_METHOD_EXIT ();
117 }
118
119 AnonymousPipe::~AnonymousPipe ()
120 {
121 PEG_METHOD_ENTER (TRC_OS_ABSTRACTION, "AnonymousPipe::~AnonymousPipe");
122
123 if (_readOpen)
124 {
125 closeReadHandle ();
126 }
127
128 if (_writeOpen)
129 {
130 closeWriteHandle ();
131 }
132
133 PEG_METHOD_EXIT ();
134 }
135 kumpf 1.1
136 AnonymousPipe::Status AnonymousPipe::writeBuffer (
137 const char * buffer,
138 Uint32 bytesToWrite)
139 {
140 //
141 // Treat invalid handle as connection closed
142 //
143 if (!_writeOpen)
144 {
145 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
146 "Attempted to write to pipe whose write handle is not open");
147 return STATUS_CLOSED;
148 }
149
150 //
151 // Ignore SIGPIPE signals
152 //
153 SignalHandler::ignore (PEGASUS_SIGPIPE);
154
155 const char * writeBuffer = buffer;
156 kumpf 1.1 DWORD expectedBytes = bytesToWrite;
157 do
158 {
159 BOOL returnValue;
160 DWORD bytesWritten = 0;
161 returnValue = WriteFile (_writeHandle, writeBuffer, expectedBytes,
162 &bytesWritten, NULL);
163
164 if (!returnValue)
165 {
166 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
167 "Failed to write buffer to pipe. Error code: %d",
168 GetLastError ());
169 return STATUS_ERROR;
170 }
171
172 if (bytesWritten < 0)
173 {
174 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
175 "Failed to write buffer to pipe. Error code: %d",
176 GetLastError ());
177 kumpf 1.1
178 if ((GetLastError () == ERROR_PIPE_NOT_CONNECTED) ||
179 (GetLastError () == ERROR_BROKEN_PIPE))
180 {
181 return STATUS_CLOSED;
182 }
183 else
184 {
185 return STATUS_ERROR;
186 }
187 }
188
189 expectedBytes -= bytesWritten;
190 writeBuffer += bytesWritten;
191 } while (expectedBytes > 0);
192
193 return STATUS_SUCCESS;
194 }
195
196 AnonymousPipe::Status AnonymousPipe::readBuffer (
197 char * buffer,
198 kumpf 1.1 Uint32 bytesToRead)
199 {
200 //
201 // Treat invalid handle as connection closed
202 //
203 if (!_readOpen)
204 {
205 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
206 "Attempted to read from pipe whose read handle is not open");
207 return STATUS_CLOSED;
208 }
209
210 DWORD expectedBytes = bytesToRead;
211
212 do
213 {
214 BOOL returnValue;
215 DWORD bytesRead;
216 returnValue = ReadFile (_readHandle, buffer, bytesToRead, &bytesRead,
217 NULL);
218
219 kumpf 1.1 if (!returnValue)
220 {
221 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
222 "Failed to read buffer from pipe. Error code: %d",
223 GetLastError ());
224 if ((GetLastError () == ERROR_PIPE_NOT_CONNECTED) ||
225 (GetLastError () == ERROR_BROKEN_PIPE))
226 {
227 return STATUS_CLOSED;
228 }
229
230 return STATUS_ERROR;
231 }
232
233 if (bytesRead == 0)
234 {
235 //
236 // Connection closed
237 //
238 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
239 "Failed to read buffer from pipe: connection closed");
240 kumpf 1.1 return STATUS_CLOSED;
241 }
242
243 if (bytesRead < 0)
244 {
245 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
246 "Failed to read buffer from pipe. Error code: %d",
247 GetLastError ());
248
249 //
250 // Error reading from pipe
251 //
252 return STATUS_ERROR;
253 }
254
255 buffer += bytesRead;
256 bytesToRead -= bytesRead;
257 } while (bytesToRead > 0);
258
259 return STATUS_SUCCESS;
260 }
261 kumpf 1.1
262 void AnonymousPipe::exportReadHandle (char * buffer) const
263 {
264 PEG_METHOD_ENTER (TRC_OS_ABSTRACTION, "AnonymousPipe::exportReadHandle");
265
266 sprintf (buffer, "%p", _readHandle);
267
268 PEG_METHOD_EXIT ();
269 }
270
271 void AnonymousPipe::exportWriteHandle (char * buffer) const
272 {
273 PEG_METHOD_ENTER (TRC_OS_ABSTRACTION, "AnonymousPipe::exportWriteHandle");
274
275 sprintf (buffer, "%p", _writeHandle);
276
277 PEG_METHOD_EXIT ();
278 }
279
280 void AnonymousPipe::closeReadHandle ()
281 {
282 kumpf 1.1 PEG_METHOD_ENTER (TRC_OS_ABSTRACTION, "AnonymousPipe::closeReadHandle");
283
284 if (_readOpen)
285 {
286 if (!CloseHandle (_readHandle))
287 {
288 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
289 "Failed to close read handle. Error code: %d",
290 GetLastError ());
291 }
292 else
293 {
294 _readOpen = false;
295 }
296 }
297 else
298 {
299 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
300 "Attempted to close read handle that was not open");
301 }
302
303 kumpf 1.1 PEG_METHOD_EXIT ();
304 }
305
306 void AnonymousPipe::closeWriteHandle ()
307 {
308 PEG_METHOD_ENTER (TRC_OS_ABSTRACTION, "AnonymousPipe::closeWriteHandle");
309
310 if (_writeOpen)
311 {
312 if (!CloseHandle (_writeHandle))
313 {
314 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
315 "Failed to close write handle. Error code: %d",
316 GetLastError ());
317 }
318 else
319 {
320 _writeOpen = false;
321 }
322 }
323 else
324 kumpf 1.1 {
325 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
326 "Attempted to close write handle that was not open");
327 }
328
329 PEG_METHOD_EXIT ();
330 }
331
332 PEGASUS_NAMESPACE_END
|