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 JackLog("JackWinNamedPipeClient::Read len = %ld\n", len);
00033 BOOL res = ReadFile(fNamedPipe, data, len, &read, NULL);
00034 JackLog("JackWinNamedPipeClient::Read res = %ld read %ld\n", res, read);
00035 if (read != len) {
00036 jack_error("Cannot read named pipe err = %ld", GetLastError());
00037 return -1;
00038 } else {
00039 return 0;
00040 }
00041 }
00042
00043 int JackWinNamedPipe::Write(void* data, int len)
00044 {
00045 DWORD written;
00046 JackLog("JackWinNamedPipeClient::Write len = %ld\n", len);
00047 BOOL res = WriteFile(fNamedPipe, data, len, &written, NULL);
00048 if (written != len) {
00049 jack_error("Cannot write named pipe err = %ld", GetLastError());
00050 return -1;
00051 } else {
00052 return 0;
00053 }
00054 }
00055
00056 int JackWinNamedPipeClient::Connect(const char* dir, int which)
00057 {
00058 sprintf(fName, "\\\\.\\pipe\\%s_jack_%d", dir, which);
00059 JackLog("Connect: fName %s\n", fName);
00060
00061 fNamedPipe = CreateFile(fName,
00062 GENERIC_READ |
00063 GENERIC_WRITE,
00064 0,
00065 NULL,
00066 OPEN_EXISTING,
00067 0,
00068 NULL);
00069
00070 if (fNamedPipe == INVALID_HANDLE_VALUE) {
00071 jack_error("Cannot connect to named pipe = %s err = %ld", fName, GetLastError());
00072 return -1;
00073 } else {
00074 return 0;
00075 }
00076 }
00077
00078 int JackWinNamedPipeClient::Connect(const char* dir, const char* name, int which)
00079 {
00080 sprintf(fName, "\\\\.\\pipe\\%s_jack_%s", dir, name);
00081 JackLog("Connect: fName %s\n", fName);
00082
00083 fNamedPipe = CreateFile(fName,
00084 GENERIC_READ |
00085 GENERIC_WRITE,
00086 0,
00087 NULL,
00088 OPEN_EXISTING,
00089 0,
00090 NULL);
00091
00092 if (fNamedPipe == INVALID_HANDLE_VALUE) {
00093 jack_error("Cannot connect to named pipe = %s err = %ld", fName, GetLastError());
00094 return -1;
00095 } else {
00096 return 0;
00097 }
00098 }
00099
00100 int JackWinNamedPipeClient::Close()
00101 {
00102 if (fNamedPipe != INVALID_HANDLE_VALUE) {
00103 CloseHandle(fNamedPipe);
00104 fNamedPipe = INVALID_HANDLE_VALUE;
00105 return 0;
00106 } else {
00107 return -1;
00108 }
00109 }
00110
00111 void JackWinNamedPipeClient::SetReadTimeOut(long sec)
00112 {}
00113
00114 void JackWinNamedPipeClient::SetWriteTimeOut(long sec)
00115 {}
00116
00117
00118 JackWinAsyncNamedPipeClient::JackWinAsyncNamedPipeClient()
00119 : JackWinNamedPipeClient(), fIOState(kIdle), fPendingIO(false)
00120 {
00121 fIOState = kIdle;
00122 fOverlap.hEvent = CreateEvent(NULL,
00123 TRUE,
00124 TRUE,
00125 NULL);
00126 }
00127
00128 JackWinAsyncNamedPipeClient::JackWinAsyncNamedPipeClient(HANDLE pipe, bool pending)
00129 : JackWinNamedPipeClient(pipe), fIOState(kIdle), fPendingIO(pending)
00130 {
00131 fOverlap.hEvent = CreateEvent(NULL,
00132 TRUE,
00133 TRUE,
00134 NULL);
00135
00136 if (!fPendingIO)
00137 SetEvent(fOverlap.hEvent);
00138
00139 fIOState = (fPendingIO) ? kConnecting : kReading;
00140 }
00141
00142 JackWinAsyncNamedPipeClient::~JackWinAsyncNamedPipeClient()
00143 {
00144 CloseHandle(fOverlap.hEvent);
00145 }
00146
00147 int JackWinAsyncNamedPipeClient::FinishIO()
00148 {
00149 DWORD success, ret;
00150 success = GetOverlappedResult(fNamedPipe,
00151 &fOverlap,
00152 &ret,
00153 FALSE);
00154
00155 switch (fIOState) {
00156
00157 case kConnecting:
00158 if (!success) {
00159 jack_error("Conection error");
00160 return -1;
00161 } else {
00162 fIOState = kReading;
00163
00164 }
00165 break;
00166
00167 case kReading:
00168 if (!success || ret == 0) {
00169 return -1;
00170 }
00171 fIOState = kWriting;
00172 break;
00173
00174 case kWriting:
00175 if (!success || ret == 0) {
00176 return -1;
00177 }
00178 fIOState = kReading;
00179 break;
00180 }
00181
00182 return 0;
00183 }
00184
00185 int JackWinAsyncNamedPipeClient::Read(void* data, int len)
00186 {
00187 DWORD read;
00188 JackLog("JackWinNamedPipeClient::Read len = %ld\n", len);
00189 BOOL res = ReadFile(fNamedPipe, data, len, &read, &fOverlap);
00190 JackLog("JackWinNamedPipeClient::Read res = %ld read %ld\n", 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 JackLog("JackWinNamedPipeClient::Write len = %ld\n", 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 JackLog("Bind: fName %s\n", 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", dir, name);
00251 JackLog("Bind: fName %s\n", 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 } else {
00292 switch (GetLastError()) {
00293
00294 case ERROR_PIPE_CONNECTED:
00295 return new JackWinNamedPipeClient(fNamedPipe);
00296
00297 default:
00298 jack_error("Cannot connect server pipe name = %s err = %ld", fName, GetLastError());
00299 return NULL;
00300 break;
00301 }
00302 }
00303 }
00304
00305 int JackWinNamedPipeServer::Close()
00306 {
00307 JackLog("JackWinNamedPipeServer::Close\n");
00308
00309 if (fNamedPipe != INVALID_HANDLE_VALUE) {
00310 DisconnectNamedPipe(fNamedPipe);
00311 CloseHandle(fNamedPipe);
00312 fNamedPipe = INVALID_HANDLE_VALUE;
00313 return 0;
00314 } else {
00315 return -1;
00316 }
00317 }
00318
00319
00320
00321 int JackWinAsyncNamedPipeServer::Bind(const char* dir, int which)
00322 {
00323 sprintf(fName, "\\\\.\\pipe\\%s_jack_%d", dir, which);
00324 JackLog("Bind: fName %s\n", fName);
00325
00326 if ((fNamedPipe = CreateNamedPipe(fName,
00327 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
00328 PIPE_TYPE_MESSAGE |
00329 PIPE_READMODE_MESSAGE |
00330 PIPE_WAIT,
00331 PIPE_UNLIMITED_INSTANCES,
00332 BUFSIZE,
00333 BUFSIZE,
00334 INFINITE,
00335 NULL)) == INVALID_HANDLE_VALUE) {
00336 jack_error("Cannot bind server to pipe err = %ld", GetLastError());
00337 return -1;
00338 } else {
00339 return 0;
00340 }
00341 }
00342
00343 int JackWinAsyncNamedPipeServer::Bind(const char* dir, const char* name, int which)
00344 {
00345 sprintf(fName, "\\\\.\\pipe\\%s_jack_%s", dir, name);
00346 JackLog("Bind: fName %s\n", fName);
00347
00348 if ((fNamedPipe = CreateNamedPipe(fName,
00349 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
00350 PIPE_TYPE_MESSAGE |
00351 PIPE_READMODE_MESSAGE |
00352 PIPE_WAIT,
00353 PIPE_UNLIMITED_INSTANCES,
00354 BUFSIZE,
00355 BUFSIZE,
00356 INFINITE,
00357 NULL)) == INVALID_HANDLE_VALUE) {
00358 jack_error("Cannot bind server to pipe err = %ld", GetLastError());
00359 return -1;
00360 } else {
00361 return 0;
00362 }
00363 }
00364
00365 JackWinNamedPipeClient* JackWinAsyncNamedPipeServer::AcceptClient()
00366 {
00367 if (ConnectNamedPipe(fNamedPipe, NULL)) {
00368 return new JackWinAsyncNamedPipeClient(fNamedPipe, false);
00369 } else {
00370 switch (GetLastError()) {
00371
00372 case ERROR_IO_PENDING:
00373 return new JackWinAsyncNamedPipeClient(fNamedPipe, true);
00374
00375 case ERROR_PIPE_CONNECTED:
00376 return new JackWinAsyncNamedPipeClient(fNamedPipe, false);
00377
00378 default:
00379 jack_error("Cannot connect server pipe name = %s err = %ld", fName, GetLastError());
00380 return NULL;
00381 break;
00382 }
00383 }
00384 }
00385
00386 }
00387