Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318//// pipetunnel.cpp//// Martin Fuchs, 30.11.2003//
//// Invoke as: "pipetunnel [pipe_name]",// for example: "pipetunnel com_2"//// Then start up RectOS in VMWare, wait for the serial connect.// After that you can connect GDB using the command "target remote :9999".//
#define WIN32_LEAN_AND_MEAN#include <windows.h>
#include <winsock.h>
#ifdef _MSC_VER#pragma comment(lib, "wsock32")#endif
#include <stdio.h>#include <errno.h>
// This definition currently missing in MinGW.#ifndef FILE_FLAG_FIRST_PIPE_INSTANCE#define FILE_FLAG_FIRST_PIPE_INSTANCE 0x00080000#endif
static void print_error(DWORD win32_error){ fprintf(stderr, "WIN32 error %lu\n", win32_error);}
#ifdef _DEBUG
// critical section wrapperstruct CritSect : public CRITICAL_SECTION{ CritSect() { InitializeCriticalSection(this); }
~CritSect() { DeleteCriticalSection(this); }};
static void dbg_trace(char mode, const char* buffer, int l){ static char s_mode = '\0'; static CritSect crit_sect;
EnterCriticalSection(&crit_sect);
if (l) { for(const char*p=buffer; l--; ++p) { if (mode != s_mode) { putchar('\n'); putchar(mode); putchar(' ');
s_mode = mode; }
if (*p=='\n' || !*p /*|| *p=='#'*/) { /*if (*p == '#') putchar(*p);*/
s_mode = '\0'; } else putchar(*p); } }
LeaveCriticalSection(&crit_sect);}
#endif
static SOCKET s_srv_socket = (SOCKET)-1;
SOCKET open_tcp_connect(){ if (s_srv_socket == (SOCKET)-1) { SOCKADDR_IN srv_addr = {0};
srv_addr.sin_family = AF_INET; srv_addr.sin_addr.s_addr = htonl(INADDR_ANY); srv_addr.sin_port = htons(9999);
s_srv_socket = socket(PF_INET, SOCK_STREAM, 0); if (s_srv_socket == (SOCKET)-1) { perror("socket()"); return 0; }
if (bind(s_srv_socket, (struct sockaddr*) &srv_addr, sizeof(srv_addr)) == -1) { perror("bind()"); return 0; }
if (listen(s_srv_socket, 4) == -1) { perror("listen()"); return 0; } }
SOCKADDR_IN rem_addr; int rem_len = sizeof(rem_addr);
for(;;) { SOCKET sock = accept(s_srv_socket, (struct sockaddr*)&rem_addr, &rem_len);
if (sock < 0) { if (errno == EINTR) continue;
perror("accept()"); return 0; }
return sock; }}
struct WriterThread{ WriterThread(SOCKET sock, HANDLE hPipe) : _sock(sock), _hPipe(hPipe) { DWORD tid;
HANDLE hThread = CreateThread(NULL, 0, WriterThreadRoutine, this, 0, &tid);
if (hThread) { SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST);
CloseHandle(hThread); } else delete this; }
protected: SOCKET _sock; HANDLE _hPipe;
static DWORD WINAPI WriterThreadRoutine(LPVOID param) { WriterThread* pThis = (WriterThread*) param;
DWORD ret = pThis->Run();
delete pThis;
return ret; }
DWORD Run() { char buffer[1024];
for(;;) { int r = recv(_sock, buffer, sizeof(buffer), 0);
if (r == -1) { perror("recv()"); fprintf(stderr, "debugger connection broken\n"); _sock = (SOCKET)-1; return 1; }
if (r) { DWORD wrote;
if (!WriteFile(_hPipe, buffer, r, &wrote, NULL)) break;
#ifdef _DEBUG dbg_trace('<', buffer, r);#endif } }
return 0; }};
LONG read_pipe(HANDLE hPipe, SOCKET sock){ for(;;) { DWORD read; char buffer[1024];
// wait for input data WaitForSingleObject(hPipe, INFINITE);
if (!ReadFile(hPipe, buffer, sizeof(buffer), &read, NULL)) { DWORD error = GetLastError();
if (error == ERROR_PIPE_LISTENING) Sleep(1000); else return error; }
if (read) {#ifdef _DEBUG dbg_trace('>', buffer, read);#endif
if (!send(sock, buffer, read, 0)) { perror("send()"); return GetLastError(); } } }}
int main(int argc, char** argv){ char path[MAX_PATH]; const char* pipe_name;
if (argc > 1) pipe_name = *++argv; else pipe_name = "com_2";
sprintf(path, "\\\\.\\pipe\\%s", pipe_name);
// initialize winsock WSADATA wsa_data;
if (WSAStartup(MAKEWORD(2,2), &wsa_data)) { fprintf(stderr, "WSAStartup() failed\n"); return 0; }
// increment priority to be faster than the cpu eating VMWare process SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
HANDLE hPipe = INVALID_HANDLE_VALUE;
for(;;) { DWORD read;
if (hPipe == INVALID_HANDLE_VALUE) { hPipe = CreateNamedPipe(path, PIPE_ACCESS_DUPLEX|FILE_FLAG_FIRST_PIPE_INSTANCE|FILE_FLAG_OVERLAPPED, PIPE_WAIT|PIPE_TYPE_BYTE, 1, 4096, 4096, 30000, NULL);
if (hPipe == INVALID_HANDLE_VALUE) { print_error(GetLastError()); return 1; } }
// wait for the client side of the pipe while(!ReadFile(hPipe, NULL, 0, &read, NULL) && GetLastError()==ERROR_PIPE_LISTENING) Sleep(1000);
puts("\nnamed pipe connected, now waiting for TCP connection...");
SOCKET sock = open_tcp_connect(); if (sock == (SOCKET)-1) break;
puts("TCP connection established.");
// launch writer thread new WriterThread(sock, hPipe);
// launch reader loop LONG error = read_pipe(hPipe, sock);
// close TCP connectiom closesocket(sock); sock = (SOCKET)-1;
// close named pipe CloseHandle(hPipe); hPipe = INVALID_HANDLE_VALUE;
if (error == ERROR_BROKEN_PIPE) puts("\nconnection closed."); // normal connection termination else { print_error(GetLastError()); break; } }
if (hPipe != INVALID_HANDLE_VALUE) if (!CloseHandle(hPipe)) print_error(GetLastError());
return 0;}