Skip to content
/ winetd Public

A partial implementation of inetd functionality, in Windows

License

Notifications You must be signed in to change notification settings

gleon99/winetd

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Winetd

A partial implementation of inetd functionality in Windows. Winetd runs as a service, listens to incoming TCP connections and runs a configured command. The client socket is passed to the executable, allowing them to comminucate.

Usage

  1. Install using msiexec: msiexec /i winetd.msi /l*v install.log /q. Winetd service will start immediately, and run automatically on system boot.
  2. Each service is defined by creating a TOML file in C:\ProgramData\Winetd, for example:
 port = 1234
 command = "C:\\Program Files\\MyProgram\\main.exe"
  1. Restart the service: Restart-Service winetd (Powershell) or sc.exe stop winetd; sc.exe start winetd (cmd).
  2. That's it, the listener is ready. In case anything goes wrong, logs are in Event Viewer.

Important Notice

Unlike UNIX, one cannot simply pass socket handle as standard input/output to a newly created process. The method we chose is to write the incoming socket (WSA_PROTOCOLINFOW struct) to the child process STDIN, then the child process has to recreate the socket (using WSASocketW function). Therefore Winetd can't be used directly on any arbitrary executable. In order to use it, a wrapper which would extract the socket from STDIN must be added. Sample code that does the job in C++:

    #include <winsock2.h>

    HANDLE getHandle()
    {
        WSAData wsa_data;
        DWORD bytes_read = 0;
        WSAPROTOCOL_INFOW protocol_info;

        if (const auto result = WSAStartup(MAKEWORD(2, 2), &wsa_data); result != 0) {
            std::abort();
        }

        if (const auto result = ReadFile(GetStdHandle(STD_INPUT_HANDLE), (LPWSAPROTOCOL_INFOW) &protocol_info,
                                         sizeof(WSAPROTOCOL_INFOW), &bytes_read, nullptr);
            !result) {
            std::abort();
        }

        const SOCKET socket =
            WSASocketW(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, &protocol_info, 0, 0);
        if (socket == INVALID_SOCKET) {
            std::abort();
        }

        return reinterpret_cast<HANDLE>(socket);
    }

Once the socket is created, it can be used to communicate with the client almost interchangeably with any other handle (i.e ReadFile, WriteFile, etc).

About

A partial implementation of inetd functionality, in Windows

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages