00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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 JackWinNamedPipeAux::ReadAux(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_log("Cannot read named pipe name = %s err = %ld", fName, GetLastError());
00039 return -1;
00040 }
00041 }
00042
00043 int JackWinNamedPipeAux::WriteAux(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_log("Cannot write named pipe name = %s err = %ld", fName, GetLastError());
00051 return -1;
00052 }
00053 }
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 int JackWinNamedPipeClient::ConnectAux()
00083 {
00084 jack_log("JackWinNamedPipeClient::ConnectAux : fName %s", fName);
00085
00086 while (true) {
00087
00088 fNamedPipe = CreateFile(fName,
00089 GENERIC_READ |
00090 GENERIC_WRITE,
00091 0,
00092 NULL,
00093 OPEN_EXISTING,
00094 0,
00095 NULL);
00096
00097
00098 if (fNamedPipe != INVALID_HANDLE_VALUE) {
00099 return 0;
00100 }
00101
00102
00103 if ((GetLastError() != ERROR_PIPE_BUSY) && (GetLastError() != ERROR_FILE_NOT_FOUND)) {
00104 jack_error("Cannot connect to named pipe = %s err = %ld", fName, GetLastError());
00105 return -1;
00106 }
00107
00108
00109 if (!WaitNamedPipe(fName, 2000)) {
00110 jack_error("Cannot connect to named pipe after wait = %s err = %ld", fName, GetLastError());
00111 return -1;
00112 }
00113 }
00114 }
00115
00116 int JackWinNamedPipeClient::Connect(const char* dir, int which)
00117 {
00118 snprintf(fName, sizeof(fName), "\\\\.\\pipe\\%s_jack_%d", dir, which);
00119 return ConnectAux();
00120 }
00121
00122 int JackWinNamedPipeClient::Connect(const char* dir, const char* name, int which)
00123 {
00124 snprintf(fName, sizeof(fName), "\\\\.\\pipe\\%s_jack_%s_%d", dir, name, which);
00125 return ConnectAux();
00126 }
00127
00128 int JackWinNamedPipeClient::Close()
00129 {
00130 if (fNamedPipe != INVALID_HANDLE_VALUE) {
00131 CloseHandle(fNamedPipe);
00132 fNamedPipe = INVALID_HANDLE_VALUE;
00133 return 0;
00134 } else {
00135 return -1;
00136 }
00137 }
00138
00139 void JackWinNamedPipeClient::SetReadTimeOut(long sec)
00140 {
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 }
00152
00153 void JackWinNamedPipeClient::SetWriteTimeOut(long sec)
00154 {
00155
00156
00157
00158
00159
00160
00161
00162 }
00163
00164 void JackWinNamedPipeClient::SetNonBlocking(bool onoff)
00165 {}
00166
00167 JackWinAsyncNamedPipeClient::JackWinAsyncNamedPipeClient()
00168 : JackWinNamedPipeClient(), fPendingIO(false), fIOState(kIdle)
00169 {
00170 fIOState = kIdle;
00171 fOverlap.hEvent = CreateEvent(NULL,
00172 TRUE,
00173 TRUE,
00174 NULL);
00175 }
00176
00177 JackWinAsyncNamedPipeClient::JackWinAsyncNamedPipeClient(HANDLE pipe, const char* name, bool pending)
00178 : JackWinNamedPipeClient(pipe, name), fPendingIO(pending), fIOState(kIdle)
00179 {
00180 fOverlap.hEvent = CreateEvent(NULL,
00181 TRUE,
00182 TRUE,
00183 NULL);
00184
00185 if (!fPendingIO) {
00186 SetEvent(fOverlap.hEvent);
00187 }
00188
00189 fIOState = (fPendingIO) ? kConnecting : kReading;
00190 }
00191
00192 JackWinAsyncNamedPipeClient::~JackWinAsyncNamedPipeClient()
00193 {
00194 CloseHandle(fOverlap.hEvent);
00195 }
00196
00197 int JackWinAsyncNamedPipeClient::FinishIO()
00198 {
00199 DWORD success, ret;
00200 success = GetOverlappedResult(fNamedPipe,
00201 &fOverlap,
00202 &ret,
00203 FALSE);
00204
00205 switch (fIOState) {
00206
00207 case kConnecting:
00208 if (!success) {
00209 jack_error("Conection error");
00210 return -1;
00211 } else {
00212 fIOState = kReading;
00213
00214 }
00215 break;
00216
00217 case kReading:
00218 if (!success || ret == 0) {
00219 return -1;
00220 }
00221 fIOState = kWriting;
00222 break;
00223
00224 case kWriting:
00225 if (!success || ret == 0) {
00226 return -1;
00227 }
00228 fIOState = kReading;
00229 break;
00230
00231 default:
00232 break;
00233 }
00234
00235 return 0;
00236 }
00237
00238 int JackWinAsyncNamedPipeClient::Read(void* data, int len)
00239 {
00240 DWORD read;
00241 jack_log("JackWinNamedPipeClient::Read len = %ld", len);
00242 BOOL res = ReadFile(fNamedPipe, data, len, &read, &fOverlap);
00243
00244 if (res && read != 0) {
00245 fPendingIO = false;
00246 fIOState = kWriting;
00247 return 0;
00248 } else if (!res && GetLastError() == ERROR_IO_PENDING) {
00249 fPendingIO = true;
00250 return 0;
00251 } else {
00252 jack_error("Cannot read named pipe err = %ld", GetLastError());
00253 return -1;
00254 }
00255 }
00256
00257 int JackWinAsyncNamedPipeClient::Write(void* data, int len)
00258 {
00259 DWORD written;
00260 jack_log("JackWinNamedPipeClient::Write len = %ld", len);
00261 BOOL res = WriteFile(fNamedPipe, data, len, &written, &fOverlap);
00262
00263 if (res && written != 0) {
00264 fPendingIO = false;
00265 fIOState = kWriting;
00266 return 0;
00267 } else if (!res && GetLastError() == ERROR_IO_PENDING) {
00268 fPendingIO = true;
00269 return 0;
00270 } else {
00271 jack_error("Cannot write named pipe err = %ld", GetLastError());
00272 return -1;
00273 }
00274 }
00275
00276
00277 int JackWinNamedPipeServer::BindAux()
00278 {
00279 jack_log("JackWinNamedPipeServer::BindAux : fName %s", fName);
00280
00281 if ((fNamedPipe = CreateNamedPipe(fName,
00282 PIPE_ACCESS_DUPLEX,
00283 PIPE_TYPE_MESSAGE |
00284 PIPE_READMODE_MESSAGE |
00285 PIPE_WAIT,
00286 PIPE_UNLIMITED_INSTANCES,
00287 BUFSIZE,
00288 BUFSIZE,
00289 INFINITE,
00290 NULL)) == INVALID_HANDLE_VALUE) {
00291 jack_error("Cannot bind server to pipe err = %ld", GetLastError());
00292 return -1;
00293 } else {
00294 return 0;
00295 }
00296 }
00297
00298 int JackWinNamedPipeServer::Bind(const char* dir, int which)
00299 {
00300 snprintf(fName, sizeof(fName), "\\\\.\\pipe\\%s_jack_%d", dir, which);
00301 return BindAux();
00302 }
00303
00304 int JackWinNamedPipeServer::Bind(const char* dir, const char* name, int which)
00305 {
00306 snprintf(fName, sizeof(fName), "\\\\.\\pipe\\%s_jack_%s_%d", dir, name, which);
00307 return BindAux();
00308 }
00309
00310 bool JackWinNamedPipeServer::Accept()
00311 {
00312 if (ConnectNamedPipe(fNamedPipe, NULL)) {
00313 return true;
00314 } else {
00315 jack_error("Cannot connect server pipe name = %s err = %ld", fName, GetLastError());
00316 if (GetLastError() == ERROR_PIPE_CONNECTED) {
00317 jack_error("Pipe already connnected = %s", fName);
00318 return true;
00319 } else {
00320 return false;
00321 }
00322 }
00323 }
00324
00325 JackWinNamedPipeClient* JackWinNamedPipeServer::AcceptClient()
00326 {
00327 if (ConnectNamedPipe(fNamedPipe, NULL)) {
00328 JackWinNamedPipeClient* client = new JackWinNamedPipeClient(fNamedPipe, fName);
00329
00330 fNamedPipe = INVALID_HANDLE_VALUE;
00331 return client;
00332 } else {
00333 switch (GetLastError()) {
00334
00335 case ERROR_PIPE_CONNECTED:
00336 return new JackWinNamedPipeClient(fNamedPipe, fName);
00337
00338 default:
00339 jack_error("Cannot connect server pipe name = %s err = %ld", fName, GetLastError());
00340 return NULL;
00341 }
00342 }
00343 }
00344
00345 int JackWinNamedPipeServer::Close()
00346 {
00347 jack_log("JackWinNamedPipeServer::Close");
00348
00349 if (fNamedPipe != INVALID_HANDLE_VALUE) {
00350 DisconnectNamedPipe(fNamedPipe);
00351 CloseHandle(fNamedPipe);
00352 fNamedPipe = INVALID_HANDLE_VALUE;
00353 return 0;
00354 } else {
00355 return -1;
00356 }
00357 }
00358
00359
00360
00361 int JackWinAsyncNamedPipeServer::BindAux()
00362 {
00363 jack_log("JackWinAsyncNamedPipeServer::BindAux : fName %s", fName);
00364
00365 if ((fNamedPipe = CreateNamedPipe(fName,
00366 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
00367 PIPE_TYPE_MESSAGE |
00368 PIPE_READMODE_MESSAGE |
00369 PIPE_WAIT,
00370 PIPE_UNLIMITED_INSTANCES,
00371 BUFSIZE,
00372 BUFSIZE,
00373 INFINITE,
00374 NULL)) == INVALID_HANDLE_VALUE) {
00375 jack_error("Cannot bind server to pipe err = %ld", GetLastError());
00376 return -1;
00377 } else {
00378 return 0;
00379 }
00380 }
00381
00382 int JackWinAsyncNamedPipeServer::Bind(const char* dir, int which)
00383 {
00384 snprintf(fName, sizeof(fName), "\\\\.\\pipe\\%s_jack_%d", dir, which);
00385 return BindAux();
00386 }
00387
00388 int JackWinAsyncNamedPipeServer::Bind(const char* dir, const char* name, int which)
00389 {
00390 snprintf(fName, sizeof(fName), "\\\\.\\pipe\\%s_jack_%s_%d", dir, name, which);
00391 return BindAux();
00392 }
00393
00394 bool JackWinAsyncNamedPipeServer::Accept()
00395 {
00396 return false;
00397 }
00398
00399 JackWinNamedPipeClient* JackWinAsyncNamedPipeServer::AcceptClient()
00400 {
00401 if (ConnectNamedPipe(fNamedPipe, NULL)) {
00402 return new JackWinAsyncNamedPipeClient(fNamedPipe, fName, false);
00403 } else {
00404 switch (GetLastError()) {
00405
00406 case ERROR_IO_PENDING:
00407 return new JackWinAsyncNamedPipeClient(fNamedPipe, fName, true);
00408
00409 case ERROR_PIPE_CONNECTED:
00410 return new JackWinAsyncNamedPipeClient(fNamedPipe, fName, false);
00411
00412 default:
00413 jack_error("Cannot connect server pipe name = %s err = %ld", fName, GetLastError());
00414 return NULL;
00415 break;
00416 }
00417 }
00418 }
00419
00420 }
00421