Jack2 1.9.6
|
00001 /* 00002 Copyright (C) 2004-2008 Grame 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU Lesser General Public License as published by 00006 the Free Software Foundation; either version 2.1 of the License, or 00007 (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU Lesser General Public License for more details. 00013 00014 You should have received a copy of the GNU Lesser General Public License 00015 along with this program; if not, write to the Free Software 00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 00018 */ 00019 00020 00021 #include "JackWinNamedPipe.h" 00022 #include "JackError.h" 00023 #include <assert.h> 00024 #include <stdio.h> 00025 00026 #define BUFSIZE 4096 00027 00028 namespace Jack 00029 { 00030 00031 int JackWinNamedPipe::Read(void* data, int len) 00032 { 00033 DWORD read; 00034 BOOL res = ReadFile(fNamedPipe, data, len, &read, NULL); 00035 if (res && read == (DWORD)len) { 00036 return 0; 00037 } else { 00038 jack_error("Cannot read named pipe err = %ld", GetLastError()); 00039 return -1; 00040 } 00041 } 00042 00043 int JackWinNamedPipe::Write(void* data, int len) 00044 { 00045 DWORD written; 00046 BOOL res = WriteFile(fNamedPipe, data, len, &written, NULL); 00047 if (res && written == (DWORD)len) { 00048 return 0; 00049 } else { 00050 jack_error("Cannot write named pipe err = %ld", GetLastError()); 00051 return -1; 00052 } 00053 } 00054 00055 int JackWinNamedPipeClient::Connect(const char* dir, int which) 00056 { 00057 sprintf(fName, "\\\\.\\pipe\\%s_jack_%d", dir, which); 00058 jack_log("Connect: fName %s", fName); 00059 00060 fNamedPipe = CreateFile(fName, // pipe name 00061 GENERIC_READ | // read and write access 00062 GENERIC_WRITE, 00063 0, // no sharing 00064 NULL, // default security attributes 00065 OPEN_EXISTING, // opens existing pipe 00066 0, // default attributes 00067 NULL); // no template file 00068 00069 if (fNamedPipe == INVALID_HANDLE_VALUE) { 00070 jack_error("Cannot connect to named pipe = %s err = %ld", fName, GetLastError()); 00071 return -1; 00072 } else { 00073 return 0; 00074 } 00075 } 00076 00077 int JackWinNamedPipeClient::Connect(const char* dir, const char* name, int which) 00078 { 00079 sprintf(fName, "\\\\.\\pipe\\%s_jack_%s_%d", dir, name, which); 00080 jack_log("Connect: fName %s", fName); 00081 00082 fNamedPipe = CreateFile(fName, // pipe name 00083 GENERIC_READ | // read and write access 00084 GENERIC_WRITE, 00085 0, // no sharing 00086 NULL, // default security attributes 00087 OPEN_EXISTING, // opens existing pipe 00088 0, // default attributes 00089 NULL); // no template file 00090 00091 if (fNamedPipe == INVALID_HANDLE_VALUE) { 00092 jack_error("Cannot connect to named pipe = %s err = %ld", fName, GetLastError()); 00093 return -1; 00094 } else { 00095 return 0; 00096 } 00097 } 00098 00099 int JackWinNamedPipeClient::Close() 00100 { 00101 if (fNamedPipe != INVALID_HANDLE_VALUE) { 00102 CloseHandle(fNamedPipe); 00103 fNamedPipe = INVALID_HANDLE_VALUE; 00104 return 0; 00105 } else { 00106 return -1; 00107 } 00108 } 00109 00110 void JackWinNamedPipeClient::SetReadTimeOut(long sec) 00111 {} 00112 00113 void JackWinNamedPipeClient::SetWriteTimeOut(long sec) 00114 {} 00115 00116 JackWinAsyncNamedPipeClient::JackWinAsyncNamedPipeClient() 00117 : JackWinNamedPipeClient(), fPendingIO(false), fIOState(kIdle) 00118 { 00119 fIOState = kIdle; 00120 fOverlap.hEvent = CreateEvent(NULL, // default security attribute 00121 TRUE, // manual-reset event 00122 TRUE, // initial state = signaled 00123 NULL); // unnamed event object 00124 } 00125 00126 JackWinAsyncNamedPipeClient::JackWinAsyncNamedPipeClient(HANDLE pipe, bool pending) 00127 : JackWinNamedPipeClient(pipe), fPendingIO(pending), fIOState(kIdle) 00128 { 00129 fOverlap.hEvent = CreateEvent(NULL, // default security attribute 00130 TRUE, // manual-reset event 00131 TRUE, // initial state = signaled 00132 NULL); // unnamed event object 00133 00134 if (!fPendingIO) 00135 SetEvent(fOverlap.hEvent); 00136 00137 fIOState = (fPendingIO) ? kConnecting : kReading; 00138 } 00139 00140 JackWinAsyncNamedPipeClient::~JackWinAsyncNamedPipeClient() 00141 { 00142 CloseHandle(fOverlap.hEvent); 00143 } 00144 00145 int JackWinAsyncNamedPipeClient::FinishIO() 00146 { 00147 DWORD success, ret; 00148 success = GetOverlappedResult(fNamedPipe, // handle to pipe 00149 &fOverlap, // OVERLAPPED structure 00150 &ret, // bytes transferred 00151 FALSE); // do not wait 00152 00153 switch (fIOState) { 00154 00155 case kConnecting: 00156 if (!success) { 00157 jack_error("Conection error"); 00158 return -1; 00159 } else { 00160 fIOState = kReading; 00161 // Prepare connection for new client ?? 00162 } 00163 break; 00164 00165 case kReading: 00166 if (!success || ret == 0) { 00167 return -1; 00168 } 00169 fIOState = kWriting; 00170 break; 00171 00172 case kWriting: 00173 if (!success || ret == 0) { 00174 return -1; 00175 } 00176 fIOState = kReading; 00177 break; 00178 00179 default: 00180 break; 00181 } 00182 00183 return 0; 00184 } 00185 00186 int JackWinAsyncNamedPipeClient::Read(void* data, int len) 00187 { 00188 DWORD read; 00189 jack_log("JackWinNamedPipeClient::Read len = %ld", len); 00190 BOOL res = ReadFile(fNamedPipe, data, len, &read, &fOverlap); 00191 jack_log("JackWinNamedPipeClient::Read res = %ld read %ld", res, read); 00192 00193 if (res && read != 0) { 00194 fPendingIO = false; 00195 fIOState = kWriting; 00196 return 0; 00197 } else if (!res && GetLastError() == ERROR_IO_PENDING) { 00198 fPendingIO = true; 00199 return 0; 00200 } else { 00201 jack_error("Cannot read named pipe err = %ld", GetLastError()); 00202 return -1; 00203 } 00204 } 00205 00206 int JackWinAsyncNamedPipeClient::Write(void* data, int len) 00207 { 00208 DWORD written; 00209 jack_log("JackWinNamedPipeClient::Write len = %ld", len); 00210 BOOL res = WriteFile(fNamedPipe, data, len, &written, &fOverlap); 00211 00212 if (res && written != 0) { 00213 fPendingIO = false; 00214 fIOState = kWriting; 00215 return 0; 00216 } else if (!res && GetLastError() == ERROR_IO_PENDING) { 00217 fPendingIO = true; 00218 return 0; 00219 } else { 00220 jack_error("Cannot write named pipe err = %ld", GetLastError()); 00221 return -1; 00222 } 00223 } 00224 00225 // Server side 00226 00227 int JackWinNamedPipeServer::Bind(const char* dir, int which) 00228 { 00229 sprintf(fName, "\\\\.\\pipe\\%s_jack_%d", dir, which); 00230 jack_log("Bind: fName %s", fName); 00231 00232 if ((fNamedPipe = CreateNamedPipe(fName, 00233 PIPE_ACCESS_DUPLEX, // read/write access 00234 PIPE_TYPE_MESSAGE | // message type pipe 00235 PIPE_READMODE_MESSAGE | // message-read mode 00236 PIPE_WAIT, // blocking mode 00237 PIPE_UNLIMITED_INSTANCES, // max. instances 00238 BUFSIZE, // output buffer size 00239 BUFSIZE, // input buffer size 00240 INFINITE, // client time-out 00241 NULL)) == INVALID_HANDLE_VALUE) { // no security a 00242 jack_error("Cannot bind server to pipe err = %ld", GetLastError()); 00243 return -1; 00244 } else { 00245 return 0; 00246 } 00247 } 00248 00249 int JackWinNamedPipeServer::Bind(const char* dir, const char* name, int which) 00250 { 00251 sprintf(fName, "\\\\.\\pipe\\%s_jack_%s_%d", dir, name, which); 00252 jack_log("Bind: fName %s", fName); 00253 00254 if ((fNamedPipe = CreateNamedPipe(fName, 00255 PIPE_ACCESS_DUPLEX, // read/write access 00256 PIPE_TYPE_MESSAGE | // message type pipe 00257 PIPE_READMODE_MESSAGE | // message-read mode 00258 PIPE_WAIT, // blocking mode 00259 PIPE_UNLIMITED_INSTANCES, // max. instances 00260 BUFSIZE, // output buffer size 00261 BUFSIZE, // input buffer size 00262 INFINITE, // client time-out 00263 NULL)) == INVALID_HANDLE_VALUE) { // no security a 00264 jack_error("Cannot bind server to pipe err = %ld", GetLastError()); 00265 return -1; 00266 } else { 00267 return 0; 00268 } 00269 } 00270 00271 bool JackWinNamedPipeServer::Accept() 00272 { 00273 if (ConnectNamedPipe(fNamedPipe, NULL)) { 00274 return true; 00275 } else { 00276 jack_error("Cannot bind server pipe name = %s err = %ld", fName, GetLastError()); 00277 if (GetLastError() == ERROR_PIPE_CONNECTED) { 00278 jack_error("pipe already connnected = %s ", fName); 00279 return true; 00280 } else { 00281 return false; 00282 } 00283 } 00284 } 00285 00286 JackWinNamedPipeClient* JackWinNamedPipeServer::AcceptClient() 00287 { 00288 if (ConnectNamedPipe(fNamedPipe, NULL)) { 00289 JackWinNamedPipeClient* client = new JackWinNamedPipeClient(fNamedPipe); 00290 // Init the pipe to the default value 00291 fNamedPipe = INVALID_HANDLE_VALUE; 00292 return client; 00293 } else { 00294 switch (GetLastError()) { 00295 00296 case ERROR_PIPE_CONNECTED: 00297 return new JackWinNamedPipeClient(fNamedPipe); 00298 00299 default: 00300 jack_error("Cannot connect server pipe name = %s err = %ld", fName, GetLastError()); 00301 return NULL; 00302 break; 00303 } 00304 } 00305 } 00306 00307 int JackWinNamedPipeServer::Close() 00308 { 00309 jack_log("JackWinNamedPipeServer::Close"); 00310 00311 if (fNamedPipe != INVALID_HANDLE_VALUE) { 00312 DisconnectNamedPipe(fNamedPipe); 00313 CloseHandle(fNamedPipe); 00314 fNamedPipe = INVALID_HANDLE_VALUE; 00315 return 0; 00316 } else { 00317 return -1; 00318 } 00319 } 00320 00321 // Server side 00322 00323 int JackWinAsyncNamedPipeServer::Bind(const char* dir, int which) 00324 { 00325 sprintf(fName, "\\\\.\\pipe\\%s_jack_%d", dir, which); 00326 jack_log("Bind: fName %s", fName); 00327 00328 if ((fNamedPipe = CreateNamedPipe(fName, 00329 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, // read/write access 00330 PIPE_TYPE_MESSAGE | // message type pipe 00331 PIPE_READMODE_MESSAGE | // message-read mode 00332 PIPE_WAIT, // blocking mode 00333 PIPE_UNLIMITED_INSTANCES, // max. instances 00334 BUFSIZE, // output buffer size 00335 BUFSIZE, // input buffer size 00336 INFINITE, // client time-out 00337 NULL)) == INVALID_HANDLE_VALUE) { // no security a 00338 jack_error("Cannot bind server to pipe err = %ld", GetLastError()); 00339 return -1; 00340 } else { 00341 return 0; 00342 } 00343 } 00344 00345 int JackWinAsyncNamedPipeServer::Bind(const char* dir, const char* name, int which) 00346 { 00347 sprintf(fName, "\\\\.\\pipe\\%s_jack_%s_%d", dir, name, which); 00348 jack_log("Bind: fName %s", fName); 00349 00350 if ((fNamedPipe = CreateNamedPipe(fName, 00351 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, // read/write access 00352 PIPE_TYPE_MESSAGE | // message type pipe 00353 PIPE_READMODE_MESSAGE | // message-read mode 00354 PIPE_WAIT, // blocking mode 00355 PIPE_UNLIMITED_INSTANCES, // max. instances 00356 BUFSIZE, // output buffer size 00357 BUFSIZE, // input buffer size 00358 INFINITE, // client time-out 00359 NULL)) == INVALID_HANDLE_VALUE) { // no security a 00360 jack_error("Cannot bind server to pipe err = %ld", GetLastError()); 00361 return -1; 00362 } else { 00363 return 0; 00364 } 00365 } 00366 00367 bool JackWinAsyncNamedPipeServer::Accept() 00368 { 00369 return false; 00370 } 00371 00372 JackWinNamedPipeClient* JackWinAsyncNamedPipeServer::AcceptClient() 00373 { 00374 if (ConnectNamedPipe(fNamedPipe, NULL)) { 00375 return new JackWinAsyncNamedPipeClient(fNamedPipe, false); 00376 } else { 00377 switch (GetLastError()) { 00378 00379 case ERROR_IO_PENDING: 00380 return new JackWinAsyncNamedPipeClient(fNamedPipe, true); 00381 00382 case ERROR_PIPE_CONNECTED: 00383 return new JackWinAsyncNamedPipeClient(fNamedPipe, false); 00384 00385 default: 00386 jack_error("Cannot connect server pipe name = %s err = %ld", fName, GetLastError()); 00387 return NULL; 00388 break; 00389 } 00390 } 00391 } 00392 00393 } // end of namespace 00394