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