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