156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall/*
256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* Copyright (C) 2011 The Android Open Source Project
356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall*
456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* Licensed under the Apache License, Version 2.0 (the "License");
556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* you may not use this file except in compliance with the License.
656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* You may obtain a copy of the License at
756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall*
856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* http://www.apache.org/licenses/LICENSE-2.0
956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall*
1056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* Unless required by applicable law or agreed to in writing, software
1156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* distributed under the License is distributed on an "AS IS" BASIS,
1256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* See the License for the specific language governing permissions and
1456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* limitations under the License.
1556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall*/
1656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#include "Win32PipeStream.h"
1756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
1856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#include <errno.h>
1956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#include <stdio.h>
2056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#include <stdlib.h>
2156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#include <unistd.h>
2256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#include <string.h>
2356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#include <windows.h>
2456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
2556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#ifndef _WIN32
2656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#error ONLY BUILD THIS SOURCE FILE FOR WINDOWS!
2756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#endif
2856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
2956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall/* The official documentation states that the name of a given named
3056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall * pipe cannot be more than 256 characters long.
3156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall */
3256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#define NAMED_PIPE_MAX 256
3356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
3456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse HallWin32PipeStream::Win32PipeStream(size_t bufSize) :
3556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    SocketStream(bufSize),
3656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    m_pipe(INVALID_HANDLE_VALUE)
3756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall{
3856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall}
3956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
4056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse HallWin32PipeStream::Win32PipeStream(HANDLE pipe, size_t bufSize) :
4156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    SocketStream(-1, bufSize),
4256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    m_pipe(pipe)
4356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall{
4456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall}
4556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
4656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse HallWin32PipeStream::~Win32PipeStream()
4756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall{
4856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    if (m_pipe != INVALID_HANDLE_VALUE) {
4956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        CloseHandle(m_pipe);
5056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        m_pipe = INVALID_HANDLE_VALUE;
5156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    }
5256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall}
5356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
5456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall/* Initialize the pipe name corresponding to a given port
5556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall */
5656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hallstatic void
5756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hallmake_pipe_name(char *path, size_t  pathlen, int port_number)
5856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall{
5956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    snprintf(path, pathlen, "\\\\.\\pipe\\qemu-gles-%d", port_number);
6056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall}
6156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
6256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
6356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall/* Technical note: Named pipes work differently from BSD Sockets.
6456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall * One does not create/bind a pipe, and collect a new handle each
6556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall * time a client connects with accept().
6656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall *
6756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall * Instead, the server creates a new pipe instance each time it wants
6856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall * to get a new client connection, then calls ConnectNamedPipe() to
6956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall * wait for a connection.
7056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall *
7156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall * So listen() is a no-op, and accept() really creates the pipe handle.
7256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall *
7356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall * Also, connect() must create a pipe handle with CreateFile() and
7456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall * wait for a server instance with WaitNamedPipe()
7556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall */
7656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hallint Win32PipeStream::listen(unsigned short port)
7756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall{
7856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    // just save the port number for accept()
7956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    m_port = port;
8056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    return 0;
8156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall}
8256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
8356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse HallSocketStream * Win32PipeStream::accept()
8456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall{
8556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    char path[NAMED_PIPE_MAX+1];
8656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    SocketStream*  clientStream;
8756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    HANDLE pipe;
8856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
8956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    make_pipe_name(path, sizeof(path), m_port);
9056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
9156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    pipe = ::CreateNamedPipe(
9256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall                path,                // pipe name
9356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall                PIPE_ACCESS_DUPLEX,  // read-write access
9456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall                PIPE_TYPE_BYTE |     // byte-oriented writes
9556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall                PIPE_READMODE_BYTE | // byte-oriented reads
9656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall                PIPE_WAIT,           // blocking operations
9756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall                PIPE_UNLIMITED_INSTANCES, // no limit on clients
9856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall                4096,                // input buffer size
9956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall                4096,                // output buffer size
10056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall                0,                   // client time-out
10156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall                NULL);               // default security attributes
10256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
10356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    if (pipe == INVALID_HANDLE_VALUE) {
10456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        ERR("%s: CreateNamedPipe failed %d\n", __FUNCTION__, (int)GetLastError());
10556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        return NULL;
10656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    }
10756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
10856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    // Stupid Win32 API design: If a client is already connected, then
10956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    // ConnectNamedPipe will return 0, and GetLastError() will return
11056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    // ERROR_PIPE_CONNECTED. This is not an error! It just means that the
11156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    // function didn't have to wait.
11256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    //
11356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    if (::ConnectNamedPipe(pipe, NULL) == 0 && GetLastError() != ERROR_PIPE_CONNECTED) {
11456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        ERR("%s: ConnectNamedPipe failed: %d\n", __FUNCTION__, (int)GetLastError());
11556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        CloseHandle(pipe);
11656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        return NULL;
11756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    }
11856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
11956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    clientStream = new Win32PipeStream(pipe, m_bufsize);
12056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    return clientStream;
12156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall}
12256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
12356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hallint Win32PipeStream::connect(unsigned short port)
12456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall{
12556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    char   path[NAMED_PIPE_MAX+1];
12656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    HANDLE pipe;
12756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    int    tries = 10;
12856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
12956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    make_pipe_name(path, sizeof(path), port);
13056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
13156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    /* We're going to loop in order to wait for the pipe server to
13256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall     * be setup properly.
13356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall     */
13456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    for (; tries > 0; tries--) {
13556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        pipe = ::CreateFile(
13656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall                    path,                          // pipe name
13756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall                    GENERIC_READ | GENERIC_WRITE,  // read & write
13856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall                    0,                             // no sharing
13956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall                    NULL,                          // default security attrs
14056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall                    OPEN_EXISTING,                 // open existing pipe
14156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall                    0,                             // default attributes
14256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall                    NULL);                         // no template file
14356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
14456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        /* If we have a valid pipe handle, break from the loop */
14556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        if (pipe != INVALID_HANDLE_VALUE) {
14656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall            break;
14756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        }
14856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
14956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        /* We can get here if the pipe is busy, i.e. if the server hasn't
15056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall         * create a new pipe instance to service our request. In which case
15156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall         * GetLastError() will return ERROR_PIPE_BUSY.
15256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall         *
15356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall         * If so, then use WaitNamedPipe() to wait for a decent time
15456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall         * to try again.
15556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall         */
15656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        if (GetLastError() != ERROR_PIPE_BUSY) {
15756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall            /* Not ERROR_PIPE_BUSY */
15856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall            ERR("%s: CreateFile failed: %d\n", __FUNCTION__, (int)GetLastError());
15956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall            errno = EINVAL;
16056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall            return -1;
16156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        }
16256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
16356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        /* Wait for 5 seconds */
16456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        if ( !WaitNamedPipe(path, 5000) ) {
16556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall            ERR("%s: WaitNamedPipe failed: %d\n", __FUNCTION__, (int)GetLastError());
16656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall            errno = EINVAL;
16756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall            return -1;
16856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        }
16956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    }
17056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
17156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    m_pipe = pipe;
17256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    return 0;
17356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall}
17456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
17556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall/* Special buffer methods, since we can't use socket functions here */
17656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
17756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hallint Win32PipeStream::commitBuffer(size_t size)
17856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall{
17956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    if (m_pipe == INVALID_HANDLE_VALUE)
18056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        return -1;
18156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
18256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    size_t res = size;
18356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    int retval = 0;
18456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
18556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    while (res > 0) {
18656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        DWORD  written;
18756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        if (! ::WriteFile(m_pipe, (const char *)m_buf + (size - res), res, &written, NULL)) {
18856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall            retval =  -1;
18956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall            ERR("%s: failed: %d\n", __FUNCTION__, (int)GetLastError());
19056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall            break;
19156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        }
19256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        res -= written;
19356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    }
19456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    return retval;
19556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall}
19656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
19756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hallconst unsigned char *Win32PipeStream::readFully(void *buf, size_t len)
19856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall{
19956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    const unsigned char* ret = NULL;
20056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
20156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    if (m_pipe == INVALID_HANDLE_VALUE)
20256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        return NULL;
20356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
20456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    if (!buf) {
20556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        return NULL;  // do not allow NULL buf in that implementation
20656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    }
20756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
20856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    size_t res = len;
20956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    while (res > 0) {
21056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        DWORD  readcount = 0;
21156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        if (! ::ReadFile(m_pipe, (char *)buf + (len - res), res, &readcount, NULL) || readcount == 0) {
21256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall            errno = (int)GetLastError();
21356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall            return NULL;
21456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        }
21556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        res -= readcount;
21656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    }
21756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    return (const unsigned char *)buf;
21856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall}
21956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
22056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hallconst unsigned char *Win32PipeStream::read( void *buf, size_t *inout_len)
22156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall{
22256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    size_t len = *inout_len;
22356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    DWORD  readcount;
22456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
22556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    if (m_pipe == INVALID_HANDLE_VALUE)
22656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        return NULL;
22756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
22856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    if (!buf) {
22956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        return NULL;  // do not allow NULL buf in that implementation
23056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    }
23156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
23256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    if (!::ReadFile(m_pipe, (char *)buf, len, &readcount, NULL)) {
23356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        errno = (int)GetLastError();
23456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall        return NULL;
23556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    }
23656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall
23756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    *inout_len = (size_t)readcount;
23856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall    return (const unsigned char *)buf;
23956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall}
240