#include "Socket.h" #include "common.h" #include #include #include #define BUFSIZE 512 using namespace TelldusCore; class Socket::PrivateData { public: HANDLE hPipe; HANDLE readEvent; bool connected; bool running; }; Socket::Socket() { d = new PrivateData; d->hPipe = INVALID_HANDLE_VALUE; d->connected = false; d->running = true; } Socket::Socket(SOCKET_T hPipe) { d = new PrivateData; d->hPipe = hPipe; d->connected = true; d->running = true; } Socket::~Socket(void){ d->running = false; SetEvent(d->readEvent); //signal for break if (d->hPipe != INVALID_HANDLE_VALUE) { CloseHandle(d->hPipe); } delete d; } void Socket::connect(const std::wstring &server){ BOOL fSuccess = false; std::wstring name(L"\\\\.\\pipe\\" + server); d->hPipe = CreateFile( (const wchar_t *)name.c_str(), // pipe name GENERIC_READ | // read and write access GENERIC_WRITE, 0, // no sharing NULL, // default security attributes OPEN_EXISTING, // opens existing pipe FILE_FLAG_OVERLAPPED, // default attributes NULL); // no template file if (d->hPipe == INVALID_HANDLE_VALUE) { return; } DWORD dwMode = PIPE_READMODE_MESSAGE; fSuccess = SetNamedPipeHandleState( d->hPipe, // pipe handle &dwMode, // new pipe mode NULL, // don't set maximum bytes NULL); // don't set maximum time if (!fSuccess) { return; } d->connected = true; } void Socket::stopReadWait(){ d->running = false; SetEvent(d->readEvent); } std::wstring Socket::read() { return read(INFINITE); } std::wstring Socket::read(int timeout){ wchar_t buf[BUFSIZE]; int result; DWORD cbBytesRead = 0; OVERLAPPED oOverlap; memset(&oOverlap, 0, sizeof(OVERLAPPED)); d->readEvent = CreateEvent(NULL, TRUE, TRUE, NULL); oOverlap.hEvent = d->readEvent; BOOL fSuccess = false; std::wstring returnString; bool moreData = true; while(moreData){ moreData = false; memset(&buf, 0, sizeof(buf)); ReadFile( d->hPipe, &buf, sizeof(buf)-sizeof(wchar_t), &cbBytesRead, &oOverlap); result = WaitForSingleObject(oOverlap.hEvent, timeout); if(!d->running){ CancelIo(d->hPipe); CloseHandle(d->readEvent); //debuglog(1, "Not running"); return L""; } if (result == WAIT_TIMEOUT) { CancelIo(d->hPipe); CloseHandle(d->readEvent); //debuglog(1, "Wait timeout"); return L""; } fSuccess = GetOverlappedResult(d->hPipe, &oOverlap, &cbBytesRead, false); if (!fSuccess) { DWORD err = GetLastError(); //debuglog(result, "This then?"); //debuglog(1, "Unsuccessful"); if(err == ERROR_MORE_DATA){ moreData = true; } else{ buf[0] = 0; } if (err == ERROR_BROKEN_PIPE) { //debuglog(1, "Broken pipe"); d->connected = false; } } returnString.append(buf); } CancelIo(d->hPipe); CloseHandle(d->readEvent); return returnString; } void Socket::write(const std::wstring &msg){ OVERLAPPED oOverlap; DWORD bytesWritten = 0; int result; BOOL fSuccess; memset(&oOverlap, 0, sizeof(OVERLAPPED)); HANDLE writeEvent = CreateEvent(NULL, TRUE, TRUE, NULL); oOverlap.hEvent = writeEvent; WriteFile(d->hPipe, msg.data(), (DWORD)msg.length()*sizeof(wchar_t), &bytesWritten, &oOverlap); result = WaitForSingleObject(writeEvent, 500); if (result == WAIT_TIMEOUT) { CancelIo(d->hPipe); CloseHandle(writeEvent); d->connected = false; //debuglog(2, "Wait timeout"); return; } fSuccess = GetOverlappedResult(d->hPipe, &oOverlap, &bytesWritten, TRUE); CloseHandle(writeEvent); if (!fSuccess) { CancelIo(d->hPipe); d->connected = false; //debuglog(2, "Unsuccessful"); return; } } bool Socket::isConnected(){ return d->connected; }