00001
00004
00005
00006 #include "stdafx.h"
00007 #include "PServer.h"
00008 #include "errorCodes.h"
00009
00011
00013
00022 PServer::PServer(const TString &name, const bool isOut, const DWORD bufferSize)
00023 : Pipe( name, isOut )
00024 {
00025 hConnectThread = NULL;
00026 connected = false;
00027
00028 if( isOutbound ){
00029 in = 0;
00030 out = bufferSize;
00031 } else {
00032 in = bufferSize;
00033 out = 0;
00034 }
00035 }
00036
00040 PServer::~PServer()
00041 {
00042 disconnect();
00043 if(hConnectThread != NULL)
00044 CloseHandle(hConnectThread);
00045 }
00046
00048
00050
00057 void PServer::disconnect()
00058 {
00059 if( getAttemptConnectResult() == PS_WAITING ) {
00061 TerminateThread(hConnectThread, PS_CANCELLED);
00062 connected = false;
00063 }
00064
00065 connected = false;
00066 DisconnectNamedPipe(hPipe);
00067 CloseHandle(hPipe);
00068
00069 ResetEvent(clientStayConnected);
00070 }
00071
00077 bool PServer::serve()
00078 {
00079 if( PServer::isConnected() ){
00080 return true;
00081 }
00082
00083 if( WaitForSingleObject(serverStayConnected, 0) == WAIT_OBJECT_0 ){
00084 return false;
00085 }
00086
00087 hPipe = CreateNamedPipe(
00088 pipeName,
00089 isOutbound ? PIPE_ACCESS_OUTBOUND : PIPE_ACCESS_INBOUND,
00090 0,
00091 1,
00092 out,
00093 in,
00094 NMPWAIT_WAIT_FOREVER,
00095 NULL);
00096
00097 if( GetLastError() == ERROR_ALREADY_EXISTS ) {
00098 CloseHandle(hPipe);
00099 hPipe = INVALID_HANDLE_VALUE;
00100 }
00101 if ( hPipe == INVALID_HANDLE_VALUE ) {
00102 return false;
00103 }
00104
00105 if(hConnectThread != NULL)
00106 CloseHandle(hConnectThread);
00107
00108 hConnectThread = chBEGINTHREADEX(
00109 NULL,
00110 0,
00111 &waitForClient,
00112 this,
00113 0,
00114 NULL);
00115
00116 if(hConnectThread == NULL){
00117 CloseHandle(hPipe);
00118 return false;
00119 }
00120
00121 return true;
00122 }
00123
00127 DWORD WINAPI PServer::waitForClient(LPVOID param)
00128 {
00129 PServer* server = (PServer*) param;
00130
00131
00132
00133
00134 server->connected = ConnectNamedPipe(server->hPipe, NULL) ?
00135 true : (GetLastError() == ERROR_PIPE_CONNECTED);
00136
00137 if( server->connected ){
00138 return PS_CONNECTED;
00139 } else {
00140 return PS_FAILED;
00141 }
00142
00143 }
00144
00148 HANDLE PServer::getConnectedEventHandle()
00149 {
00150 HANDLE rtrn;
00151
00152
00153
00154
00155 DuplicateHandle(
00156 GetCurrentProcess(),
00157 hConnectThread,
00158 GetCurrentProcess(),
00159 &rtrn,
00160 SYNCHRONIZE,
00161 false,
00162 0);
00163
00164 return rtrn;
00165 }
00166
00170 DWORD PServer::getAttemptConnectResult() const
00171 {
00172 DWORD exitCode;
00173 GetExitCodeThread(hConnectThread, &exitCode);
00174
00175 return exitCode;
00176 }
00177
00185 bool PServer::isConnected()
00186 {
00187 if( WaitForSingleObject(clientStayConnected, 0) == WAIT_OBJECT_0 ){
00188 this->disconnect();
00189 }
00190
00191 return connected;
00192 }