// Roco.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <winsock2.h> #pragma comment(lib, "Ws2_32.lib") void broadcastThreadFunction(void *context) { const SOCKET *broadcastSocket = (SOCKET*)context; sockaddr_in broadcastSocketServiceInfo; ZeroMemory(&broadcastSocketServiceInfo, sizeof(broadcastSocketServiceInfo)); broadcastSocketServiceInfo.sin_family = AF_INET; broadcastSocketServiceInfo.sin_addr.s_addr = htonl(INADDR_BROADCAST); broadcastSocketServiceInfo.sin_port = htons(28777); static const char broadcastMessage[] = "ROCO-BROADCAST-MESSAGE"; do { const int result = sendto(*broadcastSocket, broadcastMessage, sizeof(broadcastMessage), 0, (SOCKADDR*)&broadcastSocketServiceInfo, sizeof(broadcastSocketServiceInfo)); if (result == SOCKET_ERROR && ::WSAGetLastError() == WSAENOTSOCK) { break; } ::Sleep(300); } while (true); _endthread(); } int _tmain(int argc, _TCHAR* argv[]) { if (argc >= 2 && _tcscmp(argv[1], _T("/silent")) == 0) { ::ShowWindow(::GetConsoleWindow(), SW_HIDE); } WSADATA wsaData; ZeroMemory(&wsaData, sizeof(wsaData)); printf("Initializing network... "); int result = ::WSAStartup(MAKEWORD(2,2), &wsaData); if (result == NO_ERROR) { printf("Done.\n"); printf("Creating broadcast socket... "); const SOCKET broadcastSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (broadcastSocket != INVALID_SOCKET) { printf("Done.\n"); static const BOOL onValue = TRUE; setsockopt(broadcastSocket, SOL_SOCKET, SO_BROADCAST, (const char*)&onValue, sizeof(onValue)); printf("Starting broadcast thread... "); HANDLE broadcastThreadHandle =(HANDLE)_beginthread(broadcastThreadFunction, 0, (void*)&broadcastSocket); if (broadcastThreadHandle != INVALID_HANDLE_VALUE) { printf("Done.\n"); printf("Creating listen socket... "); const SOCKET listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (listenSocket != INVALID_SOCKET) { printf("Done.\n"); printf("Binding listen socket... "); sockaddr_in listenSocketServiceInfo; ZeroMemory(&listenSocketServiceInfo, sizeof(listenSocketServiceInfo)); listenSocketServiceInfo.sin_family = AF_INET; listenSocketServiceInfo.sin_addr.s_addr = htonl(INADDR_ANY); listenSocketServiceInfo.sin_port = htons(28666); result = bind(listenSocket, (SOCKADDR*)&listenSocketServiceInfo, sizeof(listenSocketServiceInfo)); if (result != SOCKET_ERROR) { printf("Done.\n"); printf("Listening for incoming connection... "); result = listen(listenSocket, SOMAXCONN); if (result != SOCKET_ERROR) { printf("Done.\n"); unsigned connectionIndex = 0; do { printf("Accepting incoming connection #%d... ", connectionIndex + 1); ::ResumeThread(broadcastThreadHandle); SOCKET commandSocket = accept(listenSocket, NULL, NULL); if (commandSocket != INVALID_SOCKET) { printf("Done.\n"); ::SuspendThread(broadcastThreadHandle); printf("Sending PING to command socket... "); static const char ping[] = "PING"; result = send(commandSocket, ping, sizeof(ping), 0); if (result != SOCKET_ERROR && result == sizeof(ping)) { printf("Done.\n"); printf("Receiving PONG from command socket... "); static char pong[sizeof("PONG")]; pong[0] = '\0'; result = recv(commandSocket, pong, sizeof(pong), 0); if (result != SOCKET_ERROR && result == sizeof(pong) && strcmp(pong, "PONG") == 0) { printf("Done.\n"); unsigned commandIndex = 0; do { printf("Waiting for command #%d...\n", commandIndex + 1); static char command[2]; ZeroMemory(command, sizeof(command)); result = recv(commandSocket, command, sizeof(command), 0); if (result != SOCKET_ERROR && result == sizeof(command)) { enum { CC_KEY_DOWM = 1, CC_KEY_UP = 0 }; const char commandCode = command[0]; const char keyCode = command[1]; static const char res = 1; switch (commandCode) { case CC_KEY_DOWM: { printf("KEY_DOWN(%d)\n", keyCode); keybd_event(keyCode, 0, 0, 0); send(commandSocket, &res, sizeof(res), 0); } break; case CC_KEY_UP: { printf("KEY_UP(%d)\n", keyCode); keybd_event(keyCode, 0, KEYEVENTF_KEYUP, 0); send(commandSocket, &res, sizeof(res), 0); } break; default: { printf("Invalid command received - %d!\n", commandCode); } break; } } else { printf("Could not receive command from socket (error - %d)!\n", ::WSAGetLastError()); break; } ++commandIndex; } while (true); } else { printf("\nCould not receive PONG from command socket (error - %d)!\n", ::WSAGetLastError()); } } else { printf("\nCould not sent PING to command socket (error - %d)!\n", ::WSAGetLastError()); } } else { printf("\nCould not accept incoming connection (error - %d)!\n", ::WSAGetLastError()); } ++connectionIndex; } while (true); } else { printf("\nCould not listen for incoming connection (error - %d)!\n", ::WSAGetLastError()); } } else { printf("\nCould not bind listen socket (error - %d)!\n", ::WSAGetLastError()); } closesocket(listenSocket); } else { printf("\nCould not create listen socket (error - %d)!\n", ::WSAGetLastError()); } } else { printf("\nCould not start broadcast thread!\n"); } ::ResumeThread(broadcastThreadHandle); closesocket(broadcastSocket); ::WaitForSingleObject(broadcastThreadHandle, INFINITE); } else { printf("\nCould not create broadcast socket (error - %d)!\n", ::WSAGetLastError()); } ::WSACleanup(); } else { printf("\nWSAStartup failed (error - %d)!", result); } return 0; }