I'm trying to implement named pipes in C++, but either my reader isn't reading anything, or my writer isn't writing anything (or both). Here's my reader:
int main()
{
    HANDLE pipe = CreateFile(GetPipeName(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
    char data[1024];
    DWORD numRead = 1;
    while (numRead >= 0)
    {
        ReadFile(pipe, data, 1024, &numRead, NULL);
        if (numRead > 0)
            cout << data;
    }
    return 0;
}
LPCWSTR GetPipeName()
{
    return L"\\\\.\\pipe\\LogPipe";
}
And here's my writer:
int main()
{
    HANDLE pipe = CreateFile(GetPipeName(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
    string message = "Hi";
    WriteFile(pipe, message.c_str(), message.length() + 1, NULL, NULL); 
    return 0;
}
LPCWSTR GetPipeName()
{
    return L"\\\\.\\pipe\\LogPipe";
}
Does that look right? numRead in the reader is always 0, for some reason, and it reads nothing but 1024 -54's (some weird I character).
Solution:
Reader (Server):
while (true)
{
    HANDLE pipe = CreateNamedPipe(GetPipeName(), PIPE_ACCESS_INBOUND | PIPE_ACCESS_OUTBOUND , PIPE_WAIT, 1, 1024, 1024, 120 * 1000, NULL);
    if (pipe == INVALID_HANDLE_VALUE)
    {
        cout << "Error: " << GetLastError();
    }
    char data[1024];
    DWORD numRead;
    ConnectNamedPipe(pipe, NULL);
    ReadFile(pipe, data, 1024, &numRead, NULL);
    if (numRead > 0)
        cout << data << endl;
    CloseHandle(pipe);
}
Writer (client):
HANDLE pipe = CreateFile(GetPipeName(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (pipe == INVALID_HANDLE_VALUE)
{
    cout << "Error: " << GetLastError();
}
string message = "Hi";
cout << message.length();
DWORD numWritten;
WriteFile(pipe, message.c_str(), message.length(), &numWritten, NULL); 
return 0;
The server blocks until it gets a connected client, reads what the client writes, and then sets itself up for a new connection, ad infinitum. Thanks for the help, all!