2 Copyright (C) 2004-2008 Grame
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include "JackWinNamedPipe.h"
22 #include "JackError.h"
31 int JackWinNamedPipe::Read(void* data
, int len
)
34 BOOL res
= ReadFile(fNamedPipe
, data
, len
, &read
, NULL
);
35 if (res
&& read
== (DWORD
)len
) {
38 jack_error("Cannot read named pipe name = %s err = %ld", fName
, GetLastError());
43 int JackWinNamedPipe::Write(void* data
, int len
)
46 BOOL res
= WriteFile(fNamedPipe
, data
, len
, &written
, NULL
);
47 if (res
&& written
== (DWORD
)len
) {
50 jack_error("Cannot write named pipe name = %s err = %ld", fName
, GetLastError());
57 http://answers.google.com/answers/threadview?id=430173
58 http://msdn.microsoft.com/en-us/library/windows/desktop/aa365800(v=vs.85).aspx
62 int JackWinNamedPipeClient::ConnectAux()
64 fNamedPipe = CreateFile(fName, // pipe name
65 GENERIC_READ | // read and write access
68 NULL, // default security attributes
69 OPEN_EXISTING, // opens existing pipe
70 0, // default attributes
71 NULL); // no template file
73 if (fNamedPipe == INVALID_HANDLE_VALUE) {
74 jack_error("Cannot connect to named pipe = %s err = %ld", fName, GetLastError());
82 int JackWinNamedPipeClient::ConnectAux()
84 jack_log("Connect: fName %s", fName
);
88 fNamedPipe
= CreateFile(fName
, // pipe name
89 GENERIC_READ
| // read and write access
92 NULL
, // default security attributes
93 OPEN_EXISTING
, // opens existing pipe
94 0, // default attributes
95 NULL
); // no template file
97 // Break if the pipe handle is valid.
98 if (fNamedPipe
!= INVALID_HANDLE_VALUE
) {
102 // Exit if an error other than ERROR_PIPE_BUSY occurs.
103 if (GetLastError() != ERROR_PIPE_BUSY
) {
104 jack_error("Cannot connect to named pipe = %s err = %ld", fName
, GetLastError());
108 // All pipe instances are busy, so wait for 2 seconds.
109 if (!WaitNamedPipe(fName
, 2000)) {
110 jack_error("Cannot connect to named pipe = %s err = %ld", fName
, GetLastError());
116 int JackWinNamedPipeClient::Connect(const char* dir
, int which
)
118 snprintf(fName
, sizeof(fName
), "\\\\.\\pipe\\%s_jack_%d", dir
, which
);
122 int JackWinNamedPipeClient::Connect(const char* dir
, const char* name
, int which
)
124 snprintf(fName
, sizeof(fName
), "\\\\.\\pipe\\%s_jack_%s_%d", dir
, name
, which
);
128 int JackWinNamedPipeClient::Close()
130 if (fNamedPipe
!= INVALID_HANDLE_VALUE
) {
131 CloseHandle(fNamedPipe
);
132 fNamedPipe
= INVALID_HANDLE_VALUE
;
139 void JackWinNamedPipeClient::SetReadTimeOut(long sec
)
142 void JackWinNamedPipeClient::SetWriteTimeOut(long sec
)
145 JackWinAsyncNamedPipeClient::JackWinAsyncNamedPipeClient()
146 : JackWinNamedPipeClient(), fPendingIO(false), fIOState(kIdle
)
149 fOverlap
.hEvent
= CreateEvent(NULL
, // default security attribute
150 TRUE
, // manual-reset event
151 TRUE
, // initial state = signaled
152 NULL
); // unnamed event object
155 JackWinAsyncNamedPipeClient::JackWinAsyncNamedPipeClient(HANDLE pipe
, const char* name
, bool pending
)
156 : JackWinNamedPipeClient(pipe
, name
), fPendingIO(pending
), fIOState(kIdle
)
158 fOverlap
.hEvent
= CreateEvent(NULL
, // default security attribute
159 TRUE
, // manual-reset event
160 TRUE
, // initial state = signaled
161 NULL
); // unnamed event object
164 SetEvent(fOverlap
.hEvent
);
167 fIOState
= (fPendingIO
) ? kConnecting
: kReading
;
170 JackWinAsyncNamedPipeClient::~JackWinAsyncNamedPipeClient()
172 CloseHandle(fOverlap
.hEvent
);
175 int JackWinAsyncNamedPipeClient::FinishIO()
178 success
= GetOverlappedResult(fNamedPipe
, // handle to pipe
179 &fOverlap
, // OVERLAPPED structure
180 &ret
, // bytes transferred
181 FALSE
); // do not wait
187 jack_error("Conection error");
191 // Prepare connection for new client ??
196 if (!success
|| ret
== 0) {
203 if (!success
|| ret
== 0) {
216 int JackWinAsyncNamedPipeClient::Read(void* data
, int len
)
219 jack_log("JackWinNamedPipeClient::Read len = %ld", len
);
220 BOOL res
= ReadFile(fNamedPipe
, data
, len
, &read
, &fOverlap
);
222 if (res
&& read
!= 0) {
226 } else if (!res
&& GetLastError() == ERROR_IO_PENDING
) {
230 jack_error("Cannot read named pipe err = %ld", GetLastError());
235 int JackWinAsyncNamedPipeClient::Write(void* data
, int len
)
238 jack_log("JackWinNamedPipeClient::Write len = %ld", len
);
239 BOOL res
= WriteFile(fNamedPipe
, data
, len
, &written
, &fOverlap
);
241 if (res
&& written
!= 0) {
245 } else if (!res
&& GetLastError() == ERROR_IO_PENDING
) {
249 jack_error("Cannot write named pipe err = %ld", GetLastError());
255 int JackWinNamedPipeServer::BindAux()
257 jack_log("Bind: fName %s", fName
);
259 if ((fNamedPipe
= CreateNamedPipe(fName
,
260 PIPE_ACCESS_DUPLEX
, // read/write access
261 PIPE_TYPE_MESSAGE
| // message type pipe
262 PIPE_READMODE_MESSAGE
| // message-read mode
263 PIPE_WAIT
, // blocking mode
264 PIPE_UNLIMITED_INSTANCES
, // max. instances
265 BUFSIZE
, // output buffer size
266 BUFSIZE
, // input buffer size
267 INFINITE
, // client time-out
268 NULL
)) == INVALID_HANDLE_VALUE
) { // no security
269 jack_error("Cannot bind server to pipe err = %ld", GetLastError());
276 int JackWinNamedPipeServer::Bind(const char* dir
, int which
)
278 snprintf(fName
, sizeof(fName
), "\\\\.\\pipe\\%s_jack_%d", dir
, which
);
282 int JackWinNamedPipeServer::Bind(const char* dir
, const char* name
, int which
)
284 snprintf(fName
, sizeof(fName
), "\\\\.\\pipe\\%s_jack_%s_%d", dir
, name
, which
);
288 bool JackWinNamedPipeServer::Accept()
290 if (ConnectNamedPipe(fNamedPipe
, NULL
)) {
293 jack_error("Cannot bind server pipe name = %s err = %ld", fName
, GetLastError());
294 if (GetLastError() == ERROR_PIPE_CONNECTED
) {
295 jack_error("pipe already connnected = %s ", fName
);
303 JackWinNamedPipeClient
* JackWinNamedPipeServer::AcceptClient()
305 if (ConnectNamedPipe(fNamedPipe
, NULL
)) {
306 JackWinNamedPipeClient
* client
= new JackWinNamedPipeClient(fNamedPipe
, fName
);
307 // Init the pipe to the default value
308 fNamedPipe
= INVALID_HANDLE_VALUE
;
311 switch (GetLastError()) {
313 case ERROR_PIPE_CONNECTED
:
314 return new JackWinNamedPipeClient(fNamedPipe
, fName
);
317 jack_error("Cannot connect server pipe name = %s err = %ld", fName
, GetLastError());
324 int JackWinNamedPipeServer::Close()
326 jack_log("JackWinNamedPipeServer::Close");
328 if (fNamedPipe
!= INVALID_HANDLE_VALUE
) {
329 DisconnectNamedPipe(fNamedPipe
);
330 CloseHandle(fNamedPipe
);
331 fNamedPipe
= INVALID_HANDLE_VALUE
;
340 int JackWinAsyncNamedPipeServer::BindAux()
342 jack_log("Bind: fName %s", fName
);
344 if ((fNamedPipe
= CreateNamedPipe(fName
,
345 PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
, // read/write access
346 PIPE_TYPE_MESSAGE
| // message type pipe
347 PIPE_READMODE_MESSAGE
| // message-read mode
348 PIPE_WAIT
, // blocking mode
349 PIPE_UNLIMITED_INSTANCES
, // max. instances
350 BUFSIZE
, // output buffer size
351 BUFSIZE
, // input buffer size
352 INFINITE
, // client time-out
353 NULL
)) == INVALID_HANDLE_VALUE
) { // no security a
354 jack_error("Cannot bind server to pipe err = %ld", GetLastError());
361 int JackWinAsyncNamedPipeServer::Bind(const char* dir
, int which
)
363 snprintf(fName
, sizeof(fName
), "\\\\.\\pipe\\%s_jack_%d", dir
, which
);
367 int JackWinAsyncNamedPipeServer::Bind(const char* dir
, const char* name
, int which
)
369 snprintf(fName
, sizeof(fName
), "\\\\.\\pipe\\%s_jack_%s_%d", dir
, name
, which
);
373 bool JackWinAsyncNamedPipeServer::Accept()
378 JackWinNamedPipeClient
* JackWinAsyncNamedPipeServer::AcceptClient()
380 if (ConnectNamedPipe(fNamedPipe
, NULL
)) {
381 return new JackWinAsyncNamedPipeClient(fNamedPipe
, fName
, false);
383 switch (GetLastError()) {
385 case ERROR_IO_PENDING
:
386 return new JackWinAsyncNamedPipeClient(fNamedPipe
, fName
, true);
388 case ERROR_PIPE_CONNECTED
:
389 return new JackWinAsyncNamedPipeClient(fNamedPipe
, fName
, false);
392 jack_error("Cannot connect server pipe name = %s err = %ld", fName
, GetLastError());
399 } // end of namespace