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 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,
00061 GENERIC_READ |
00062 GENERIC_WRITE,
00063 0,
00064 NULL,
00065 OPEN_EXISTING,
00066 0,
00067 NULL);
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,
00083 GENERIC_READ |
00084 GENERIC_WRITE,
00085 0,
00086 NULL,
00087 OPEN_EXISTING,
00088 0,
00089 NULL);
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,
00121 TRUE,
00122 TRUE,
00123 NULL);
00124 }
00125
00126 JackWinAsyncNamedPipeClient::JackWinAsyncNamedPipeClient(HANDLE pipe, bool pending)
00127 : JackWinNamedPipeClient(pipe), fPendingIO(pending), fIOState(kIdle)
00128 {
00129 fOverlap.hEvent = CreateEvent(NULL,
00130 TRUE,
00131 TRUE,
00132 NULL);
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,
00149 &fOverlap,
00150 &ret,
00151 FALSE);
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
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
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,
00234 PIPE_TYPE_MESSAGE |
00235 PIPE_READMODE_MESSAGE |
00236 PIPE_WAIT,
00237 PIPE_UNLIMITED_INSTANCES,
00238 BUFSIZE,
00239 BUFSIZE,
00240 INFINITE,
00241 NULL)) == INVALID_HANDLE_VALUE) {
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,
00256 PIPE_TYPE_MESSAGE |
00257 PIPE_READMODE_MESSAGE |
00258 PIPE_WAIT,
00259 PIPE_UNLIMITED_INSTANCES,
00260 BUFSIZE,
00261 BUFSIZE,
00262 INFINITE,
00263 NULL)) == INVALID_HANDLE_VALUE) {
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
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
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,
00330 PIPE_TYPE_MESSAGE |
00331 PIPE_READMODE_MESSAGE |
00332 PIPE_WAIT,
00333 PIPE_UNLIMITED_INSTANCES,
00334 BUFSIZE,
00335 BUFSIZE,
00336 INFINITE,
00337 NULL)) == INVALID_HANDLE_VALUE) {
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,
00352 PIPE_TYPE_MESSAGE |
00353 PIPE_READMODE_MESSAGE |
00354 PIPE_WAIT,
00355 PIPE_UNLIMITED_INSTANCES,
00356 BUFSIZE,
00357 BUFSIZE,
00358 INFINITE,
00359 NULL)) == INVALID_HANDLE_VALUE) {
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 }
00394