#include "sysdeps.h"
#include <windows.h>
#include <winsock2.h>
#include <stdio.h>
#include <errno.h>
#define  TRACE_TAG  TRACE_SYSDEPS
#include "adb.h"

extern void fatal(const char *fmt, ...);

#define assert(cond)  do { if (!(cond)) fatal( "assertion failed '%s' on %s:%ld\n", #cond, __FILE__, __LINE__ ); } while (0)

/**************************************************************************/
/**************************************************************************/
/*****                                                                *****/
/*****      replaces libs/cutils/load_file.c                          *****/
/*****                                                                *****/
/**************************************************************************/
/**************************************************************************/

void *load_file(const char *fn, unsigned *_sz)
{
    HANDLE    file;
    char     *data;
    DWORD     file_size;

    file = CreateFile( fn,
                       GENERIC_READ,
                       FILE_SHARE_READ,
                       NULL,
                       OPEN_EXISTING,
                       0,
                       NULL );

    if (file == INVALID_HANDLE_VALUE)
        return NULL;

    file_size = GetFileSize( file, NULL );
    data      = NULL;

    if (file_size > 0) {
        data = (char*) malloc( file_size + 1 );
        if (data == NULL) {
            D("load_file: could not allocate %ld bytes\n", file_size );
            file_size = 0;
        } else {
            DWORD  out_bytes;

            if ( !ReadFile( file, data, file_size, &out_bytes, NULL ) ||
                 out_bytes != file_size )
            {
                D("load_file: could not read %ld bytes from '%s'\n", file_size, fn);
                free(data);
                data      = NULL;
                file_size = 0;
            }
        }
    }
    CloseHandle( file );

    *_sz = (unsigned) file_size;
    return  data;
}

/**************************************************************************/
/**************************************************************************/
/*****                                                                *****/
/*****    common file descriptor handling                             *****/
/*****                                                                *****/
/**************************************************************************/
/**************************************************************************/

typedef const struct FHClassRec_*   FHClass;

typedef struct FHRec_*          FH;

typedef struct EventHookRec_*  EventHook;

typedef struct FHClassRec_
{
    void (*_fh_init) ( FH  f );
    int  (*_fh_close)( FH  f );
    int  (*_fh_lseek)( FH  f, int  pos, int  origin );
    int  (*_fh_read) ( FH  f, void*  buf, int  len );
    int  (*_fh_write)( FH  f, const void*  buf, int  len );
    void (*_fh_hook) ( FH  f, int  events, EventHook  hook );

} FHClassRec;

/* used to emulate unix-domain socket pairs */
typedef struct SocketPairRec_*  SocketPair;

typedef struct FHRec_
{
    FHClass    clazz;
    int        used;
    int        eof;
    union {
        HANDLE      handle;
        SOCKET      socket;
        SocketPair  pair;
    } u;

    HANDLE    event;
    int       mask;

    char  name[32];

} FHRec;

#define  fh_handle  u.handle
#define  fh_socket  u.socket
#define  fh_pair    u.pair

#define  WIN32_FH_BASE    100

#define  WIN32_MAX_FHS    128

static adb_mutex_t   _win32_lock;
static  FHRec        _win32_fhs[ WIN32_MAX_FHS ];
static  int          _win32_fh_count;

static FH
_fh_from_int( int   fd )
{
    FH  f;

    fd -= WIN32_FH_BASE;

    if (fd < 0 || fd >= _win32_fh_count) {
        D( "_fh_from_int: invalid fd %d\n", fd + WIN32_FH_BASE );
        errno = EBADF;
        return NULL;
    }

    f = &_win32_fhs[fd];

    if (f->used == 0) {
        D( "_fh_from_int: invalid fd %d\n", fd + WIN32_FH_BASE );
        errno = EBADF;
        return NULL;
    }

    return f;
}


static int
_fh_to_int( FH  f )
{
    if (f && f->used && f >= _win32_fhs && f < _win32_fhs + WIN32_MAX_FHS)
        return (int)(f - _win32_fhs) + WIN32_FH_BASE;

    return -1;
}

static FH
_fh_alloc( FHClass  clazz )
{
    int  nn;
    FH   f = NULL;

    adb_mutex_lock( &_win32_lock );

    if (_win32_fh_count < WIN32_MAX_FHS) {
        f = &_win32_fhs[ _win32_fh_count++ ];
        goto Exit;
    }

    for (nn = 0; nn < WIN32_MAX_FHS; nn++) {
        if ( _win32_fhs[nn].clazz == NULL) {
            f = &_win32_fhs[nn];
            goto Exit;
        }
    }
    D( "_fh_alloc: no more free file descriptors\n" );
Exit:
    if (f) {
        f->clazz = clazz;
        f->used  = 1;
        f->eof   = 0;
        clazz->_fh_init(f);
    }
    adb_mutex_unlock( &_win32_lock );
    return f;
}


static int
_fh_close( FH   f )
{
    if ( f->used ) {
        f->clazz->_fh_close( f );
        f->used = 0;
        f->eof  = 0;
        f->clazz = NULL;
    }
    return 0;
}

/* forward definitions */
static const FHClassRec   _fh_file_class;
static const FHClassRec   _fh_socket_class;

/**************************************************************************/
/**************************************************************************/
/*****                                                                *****/
/*****    file-based descriptor handling                              *****/
/*****                                                                *****/
/**************************************************************************/
/**************************************************************************/

static void
_fh_file_init( FH  f )
{
    f->fh_handle = INVALID_HANDLE_VALUE;
}

static int
_fh_file_close( FH  f )
{
    CloseHandle( f->fh_handle );
    f->fh_handle = INVALID_HANDLE_VALUE;
    return 0;
}

static int
_fh_file_read( FH  f,  void*  buf, int   len )
{
    DWORD  read_bytes;

    if ( !ReadFile( f->fh_handle, buf, (DWORD)len, &read_bytes, NULL ) ) {
        D( "adb_read: could not read %d bytes from %s\n", len, f->name );
        errno = EIO;
        return -1;
    } else if (read_bytes < (DWORD)len) {
        f->eof = 1;
    }
    return (int)read_bytes;
}

static int
_fh_file_write( FH  f,  const void*  buf, int   len )
{
    DWORD  wrote_bytes;

    if ( !WriteFile( f->fh_handle, buf, (DWORD)len, &wrote_bytes, NULL ) ) {
        D( "adb_file_write: could not write %d bytes from %s\n", len, f->name );
        errno = EIO;
        return -1;
    } else if (wrote_bytes < (DWORD)len) {
        f->eof = 1;
    }
    return  (int)wrote_bytes;
}

static int
_fh_file_lseek( FH  f, int  pos, int  origin )
{
    DWORD  method;
    DWORD  result;

    switch (origin)
    {
        case SEEK_SET:  method = FILE_BEGIN; break;
        case SEEK_CUR:  method = FILE_CURRENT; break;
        case SEEK_END:  method = FILE_END; break;
        default:
            errno = EINVAL;
            return -1;
    }

    result = SetFilePointer( f->fh_handle, pos, NULL, method );
    if (result == INVALID_SET_FILE_POINTER) {
        errno = EIO;
        return -1;
    } else {
        f->eof = 0;
    }
    return (int)result;
}

static void  _fh_file_hook( FH  f, int  event, EventHook  eventhook );  /* forward */

static const FHClassRec  _fh_file_class =
{
    _fh_file_init,
    _fh_file_close,
    _fh_file_lseek,
    _fh_file_read,
    _fh_file_write,
    _fh_file_hook
};

/**************************************************************************/
/**************************************************************************/
/*****                                                                *****/
/*****    file-based descriptor handling                              *****/
/*****                                                                *****/
/**************************************************************************/
/**************************************************************************/

int  adb_open(const char*  path, int  options)
{
    FH  f;

    DWORD  desiredAccess       = 0;
    DWORD  shareMode           = FILE_SHARE_READ | FILE_SHARE_WRITE;

    switch (options) {
        case O_RDONLY:
            desiredAccess = GENERIC_READ;
            break;
        case O_WRONLY:
            desiredAccess = GENERIC_WRITE;
            break;
        case O_RDWR:
            desiredAccess = GENERIC_READ | GENERIC_WRITE;
            break;
        default:
            D("adb_open: invalid options (0x%0x)\n", options);
            errno = EINVAL;
            return -1;
    }

    f = _fh_alloc( &_fh_file_class );
    if ( !f ) {
        errno = ENOMEM;
        return -1;
    }

    f->fh_handle = CreateFile( path, desiredAccess, shareMode, NULL, OPEN_EXISTING,
                               0, NULL );

    if ( f->fh_handle == INVALID_HANDLE_VALUE ) {
        _fh_close(f);
        D( "adb_open: could not open '%s':", path );
        switch (GetLastError()) {
            case ERROR_FILE_NOT_FOUND:
                D( "file not found\n" );
                errno = ENOENT;
                return -1;

            case ERROR_PATH_NOT_FOUND:
                D( "path not found\n" );
                errno = ENOTDIR;
                return -1;

            default:
                D( "unknown error\n" );
                errno = ENOENT;
                return -1;
        }
    }
    
    snprintf( f->name, sizeof(f->name), "%d(%s)", _fh_to_int(f), path );
    D( "adb_open: '%s' => fd %d\n", path, _fh_to_int(f) );
    return _fh_to_int(f);
}

/* ignore mode on Win32 */
int  adb_creat(const char*  path, int  mode)
{
    FH  f;

    f = _fh_alloc( &_fh_file_class );
    if ( !f ) {
        errno = ENOMEM;
        return -1;
    }

    f->fh_handle = CreateFile( path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
                               NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
                               NULL );

    if ( f->fh_handle == INVALID_HANDLE_VALUE ) {
        _fh_close(f);
        D( "adb_creat: could not open '%s':", path );
        switch (GetLastError()) {
            case ERROR_FILE_NOT_FOUND:
                D( "file not found\n" );
                errno = ENOENT;
                return -1;

            case ERROR_PATH_NOT_FOUND:
                D( "path not found\n" );
                errno = ENOTDIR;
                return -1;

            default:
                D( "unknown error\n" );
                errno = ENOENT;
                return -1;
        }
    }
    snprintf( f->name, sizeof(f->name), "%d(%s)", _fh_to_int(f), path );
    D( "adb_creat: '%s' => fd %d\n", path, _fh_to_int(f) );
    return _fh_to_int(f);
}


int  adb_read(int  fd, void* buf, int len)
{
    FH     f = _fh_from_int(fd);

    if (f == NULL) {
        return -1;
    }

    return f->clazz->_fh_read( f, buf, len );
}


int  adb_write(int  fd, const void*  buf, int  len)
{
    FH     f = _fh_from_int(fd);

    if (f == NULL) {
        return -1;
    }

    return f->clazz->_fh_write(f, buf, len);
}


int  adb_lseek(int  fd, int  pos, int  where)
{
    FH     f = _fh_from_int(fd);

    if (!f) {
        return -1;
    }

    return f->clazz->_fh_lseek(f, pos, where);
}


int  adb_shutdown(int  fd)
{
    FH   f = _fh_from_int(fd);

    if (!f) {
        return -1;
    }

    D( "adb_shutdown: %s\n", f->name);
    shutdown( f->fh_socket, SD_BOTH );
    return 0;
}


int  adb_close(int  fd)
{
    FH   f = _fh_from_int(fd);

    if (!f) {
        return -1;
    }

    D( "adb_close: %s\n", f->name);
    _fh_close(f);
    return 0;
}

/**************************************************************************/
/**************************************************************************/
/*****                                                                *****/
/*****    socket-based file descriptors                               *****/
/*****                                                                *****/
/**************************************************************************/
/**************************************************************************/

static void
_socket_set_errno( void )
{
    switch (WSAGetLastError()) {
    case 0:              errno = 0; break;
    case WSAEWOULDBLOCK: errno = EAGAIN; break;
    case WSAEINTR:       errno = EINTR; break;
    default:
        D( "_socket_set_errno: unhandled value %d\n", WSAGetLastError() );
        errno = EINVAL;
    }
}

static void
_fh_socket_init( FH  f )
{
    f->fh_socket = INVALID_SOCKET;
    f->event     = WSACreateEvent();
    f->mask      = 0;
}

static int
_fh_socket_close( FH  f )
{
    /* gently tell any peer that we're closing the socket */
    shutdown( f->fh_socket, SD_BOTH );
    closesocket( f->fh_socket );
    f->fh_socket = INVALID_SOCKET;
    CloseHandle( f->event );
    f->mask = 0;
    return 0;
}

static int
_fh_socket_lseek( FH  f, int pos, int origin )
{
    errno = EPIPE;
    return -1;
}

static int
_fh_socket_read( FH  f, void*  buf, int  len )
{
    int  result = recv( f->fh_socket, buf, len, 0 );
    if (result == SOCKET_ERROR) {
        _socket_set_errno();
        result = -1;
    }
    return  result;
}

static int
_fh_socket_write( FH  f, const void*  buf, int  len )
{
    int  result = send( f->fh_socket, buf, len, 0 );
    if (result == SOCKET_ERROR) {
        _socket_set_errno();
        result = -1;
    }
    return result;
}

static void  _fh_socket_hook( FH  f, int  event, EventHook  hook );  /* forward */

static const FHClassRec  _fh_socket_class =
{
    _fh_socket_init,
    _fh_socket_close,
    _fh_socket_lseek,
    _fh_socket_read,
    _fh_socket_write,
    _fh_socket_hook
};

/**************************************************************************/
/**************************************************************************/
/*****                                                                *****/
/*****    replacement for libs/cutils/socket_xxxx.c                   *****/
/*****                                                                *****/
/**************************************************************************/
/**************************************************************************/

#include <winsock2.h>

static int  _winsock_init;

static void
_cleanup_winsock( void )
{
    WSACleanup();
}

static void
_init_winsock( void )
{
    if (!_winsock_init) {
        WSADATA  wsaData;
        int      rc = WSAStartup( MAKEWORD(2,2), &wsaData);
        if (rc != 0) {
            fatal( "adb: could not initialize Winsock\n" );
        }
        atexit( _cleanup_winsock );
        _winsock_init = 1;
    }
}

int socket_loopback_client(int port, int type)
{
    FH  f = _fh_alloc( &_fh_socket_class );
    struct sockaddr_in addr;
    SOCKET  s;

    if (!f)
        return -1;

    if (!_winsock_init)
        _init_winsock();

    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

    s = socket(AF_INET, type, 0);
    if(s == INVALID_SOCKET) {
        D("socket_loopback_client: could not create socket\n" );
        _fh_close(f);
        return -1;
    }

    f->fh_socket = s;
    if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
        D("socket_loopback_client: could not connect to %s:%d\n", type != SOCK_STREAM ? "udp" : "tcp", port );
        _fh_close(f);
        return -1;
    }
    snprintf( f->name, sizeof(f->name), "%d(lo-client:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );
    D( "socket_loopback_client: port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) );
    return _fh_to_int(f);
}

#define LISTEN_BACKLOG 4

int socket_loopback_server(int port, int type)
{
    FH   f = _fh_alloc( &_fh_socket_class );
    struct sockaddr_in addr;
    SOCKET  s;
    int  n;

    if (!f) {
        return -1;
    }

    if (!_winsock_init)
        _init_winsock();

    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

    s = socket(AF_INET, type, 0);
    if(s == INVALID_SOCKET) return -1;

    f->fh_socket = s;

    n = 1;
    setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*)&n, sizeof(n));

    if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
        _fh_close(f);
        return -1;
    }
    if (type == SOCK_STREAM) {
        int ret;

        ret = listen(s, LISTEN_BACKLOG);
        if (ret < 0) {
            _fh_close(f);
            return -1;
        }
    }
    snprintf( f->name, sizeof(f->name), "%d(lo-server:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );
    D( "socket_loopback_server: port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) );
    return _fh_to_int(f);
}


int socket_network_client(const char *host, int port, int type)
{
    FH  f = _fh_alloc( &_fh_socket_class );
    struct hostent *hp;
    struct sockaddr_in addr;
    SOCKET s;

    if (!f)
        return -1;

    if (!_winsock_init)
        _init_winsock();

    hp = gethostbyname(host);
    if(hp == 0) {
        _fh_close(f);
        return -1;
    }

    memset(&addr, 0, sizeof(addr));
    addr.sin_family = hp->h_addrtype;
    addr.sin_port = htons(port);
    memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);

    s = socket(hp->h_addrtype, type, 0);
    if(s == INVALID_SOCKET) {
        _fh_close(f);
        return -1;
    }
    f->fh_socket = s;

    if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
        _fh_close(f);
        return -1;
    }

    snprintf( f->name, sizeof(f->name), "%d(net-client:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );
    D( "socket_network_client: host '%s' port %d type %s => fd %d\n", host, port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) );
    return _fh_to_int(f);
}


int socket_inaddr_any_server(int port, int type)
{
    FH  f = _fh_alloc( &_fh_socket_class );
    struct sockaddr_in addr;
    SOCKET  s;
    int n;

    if (!f)
        return -1;

    if (!_winsock_init)
        _init_winsock();

    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);

    s = socket(AF_INET, type, 0);
    if(s == INVALID_SOCKET) {
        _fh_close(f);
        return -1;
    }

    f->fh_socket = s;
    n = 1;
    setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*)&n, sizeof(n));

    if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
        _fh_close(f);
        return -1;
    }

    if (type == SOCK_STREAM) {
        int ret;

        ret = listen(s, LISTEN_BACKLOG);
        if (ret < 0) {
            _fh_close(f);
            return -1;
        }
    }
    snprintf( f->name, sizeof(f->name), "%d(any-server:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );
    D( "socket_inaddr_server: port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) );
    return _fh_to_int(f);
}

#undef accept
int  adb_socket_accept(int  serverfd, struct sockaddr*  addr, socklen_t  *addrlen)
{
    FH   serverfh = _fh_from_int(serverfd);
    FH   fh;

    if ( !serverfh || serverfh->clazz != &_fh_socket_class ) {
        D( "adb_socket_accept: invalid fd %d\n", serverfd );
        return -1;
    }

    fh = _fh_alloc( &_fh_socket_class );
    if (!fh) {
        D( "adb_socket_accept: not enough memory to allocate accepted socket descriptor\n" );
        return -1;
    }

    fh->fh_socket = accept( serverfh->fh_socket, addr, addrlen );
    if (fh->fh_socket == INVALID_SOCKET) {
        _fh_close( fh );
        D( "adb_socket_accept: accept on fd %d return error %ld\n", serverfd, GetLastError() );
        return -1;
    }

    snprintf( fh->name, sizeof(fh->name), "%d(accept:%s)", _fh_to_int(fh), serverfh->name );
    D( "adb_socket_accept on fd %d returns fd %d\n", serverfd, _fh_to_int(fh) );
    return  _fh_to_int(fh);
}


void  disable_tcp_nagle(int fd)
{
    FH   fh = _fh_from_int(fd);
    int  on;

    if ( !fh || fh->clazz != &_fh_socket_class )
        return;

    setsockopt( fh->fh_socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&on, sizeof(on) );
}

/**************************************************************************/
/**************************************************************************/
/*****                                                                *****/
/*****    emulated socketpairs                                       *****/
/*****                                                                *****/
/**************************************************************************/
/**************************************************************************/

/* we implement socketpairs directly in use space for the following reasons:
 *   - it avoids copying data from/to the Nt kernel
 *   - it allows us to implement fdevent hooks easily and cheaply, something
 *     that is not possible with standard Win32 pipes !!
 *
 * basically, we use two circular buffers, each one corresponding to a given
 * direction.
 *
 * each buffer is implemented as two regions:
 *
 *   region A which is (a_start,a_end)
 *   region B which is (0, b_end)  with b_end <= a_start
 *
 * an empty buffer has:  a_start = a_end = b_end = 0
 *
 * a_start is the pointer where we start reading data
 * a_end is the pointer where we start writing data, unless it is BUFFER_SIZE,
 * then you start writing at b_end
 *
 * the buffer is full when  b_end == a_start && a_end == BUFFER_SIZE
 *
 * there is room when b_end < a_start || a_end < BUFER_SIZE
 *
 * when reading, a_start is incremented, it a_start meets a_end, then
 * we do:  a_start = 0, a_end = b_end, b_end = 0, and keep going on..
 */

#define  BIP_BUFFER_SIZE   4096

#if 0
#include <stdio.h>
#  define  BIPD(x)      D x
#  define  BIPDUMP   bip_dump_hex

static void  bip_dump_hex( const unsigned char*  ptr, size_t  len )
{
    int  nn, len2 = len;

    if (len2 > 8) len2 = 8;

    for (nn = 0; nn < len2; nn++) 
        printf("%02x", ptr[nn]);
    printf("  ");

    for (nn = 0; nn < len2; nn++) {
        int  c = ptr[nn];
        if (c < 32 || c > 127)
            c = '.';
        printf("%c", c);
    }
    printf("\n");
    fflush(stdout);
}

#else
#  define  BIPD(x)        do {} while (0)
#  define  BIPDUMP(p,l)   BIPD(p)
#endif

typedef struct BipBufferRec_
{
    int                a_start;
    int                a_end;
    int                b_end;
    int                fdin;
    int                fdout;
    int                closed;
    int                can_write;  /* boolean */
    HANDLE             evt_write;  /* event signaled when one can write to a buffer  */
    int                can_read;   /* boolean */
    HANDLE             evt_read;   /* event signaled when one can read from a buffer */
    CRITICAL_SECTION  lock;
    unsigned char      buff[ BIP_BUFFER_SIZE ];

} BipBufferRec, *BipBuffer;

static void
bip_buffer_init( BipBuffer  buffer )
{
    D( "bit_buffer_init %p\n", buffer );
    buffer->a_start   = 0;
    buffer->a_end     = 0;
    buffer->b_end     = 0;
    buffer->can_write = 1;
    buffer->can_read  = 0;
    buffer->fdin      = 0;
    buffer->fdout     = 0;
    buffer->closed    = 0;
    buffer->evt_write = CreateEvent( NULL, TRUE, TRUE, NULL );
    buffer->evt_read  = CreateEvent( NULL, TRUE, FALSE, NULL );
    InitializeCriticalSection( &buffer->lock );
}

static void
bip_buffer_close( BipBuffer  bip )
{
    bip->closed = 1;

    if (!bip->can_read) {
        SetEvent( bip->evt_read );
    }
    if (!bip->can_write) {
        SetEvent( bip->evt_write );
    }
}

static void
bip_buffer_done( BipBuffer  bip )
{
    BIPD(( "bip_buffer_done: %d->%d\n", bip->fdin, bip->fdout ));
    CloseHandle( bip->evt_read );
    CloseHandle( bip->evt_write );
    DeleteCriticalSection( &bip->lock );
}

static int
bip_buffer_write( BipBuffer  bip, const void* src, int  len )
{
    int  avail, count = 0;

    if (len <= 0)
        return 0;

    BIPD(( "bip_buffer_write: enter %d->%d len %d\n", bip->fdin, bip->fdout, len ));
    BIPDUMP( src, len );

    EnterCriticalSection( &bip->lock );

    while (!bip->can_write) {
        int  ret;
        LeaveCriticalSection( &bip->lock );

        if (bip->closed) {
            errno = EPIPE;
            return -1;
        }
        /* spinlocking here is probably unfair, but let's live with it */
        ret = WaitForSingleObject( bip->evt_write, INFINITE );
        if (ret != WAIT_OBJECT_0) {  /* buffer probably closed */
            D( "bip_buffer_write: error %d->%d WaitForSingleObject returned %d, error %ld\n", bip->fdin, bip->fdout, ret, GetLastError() );
            return 0;
        }
        if (bip->closed) {
            errno = EPIPE;
            return -1;
        }
        EnterCriticalSection( &bip->lock );
    }

    BIPD(( "bip_buffer_write: exec %d->%d len %d\n", bip->fdin, bip->fdout, len ));

    avail = BIP_BUFFER_SIZE - bip->a_end;
    if (avail > 0)
    {
        /* we can append to region A */
        if (avail > len)
            avail = len;

        memcpy( bip->buff + bip->a_end, src, avail );
        src   += avail;
        count += avail;
        len   -= avail;

        bip->a_end += avail;
        if (bip->a_end == BIP_BUFFER_SIZE && bip->a_start == 0) {
            bip->can_write = 0;
            ResetEvent( bip->evt_write );
            goto Exit;
        }
    }

    if (len == 0)
        goto Exit;

    avail = bip->a_start - bip->b_end;
    assert( avail > 0 );  /* since can_write is TRUE */

    if (avail > len)
        avail = len;

    memcpy( bip->buff + bip->b_end, src, avail );
    count += avail;
    bip->b_end += avail;

    if (bip->b_end == bip->a_start) {
        bip->can_write = 0;
        ResetEvent( bip->evt_write );
    }

Exit:
    assert( count > 0 );

    if ( !bip->can_read ) {
        bip->can_read = 1;
        SetEvent( bip->evt_read );
    }

    BIPD(( "bip_buffer_write: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d\n", 
            bip->fdin, bip->fdout, count, bip->a_start, bip->a_end, bip->b_end, bip->can_write, bip->can_read ));
    LeaveCriticalSection( &bip->lock );

    return count;
 }

static int
bip_buffer_read( BipBuffer  bip, void*  dst, int  len )
{
    int  avail, count = 0;

    if (len <= 0)
        return 0;

    BIPD(( "bip_buffer_read: enter %d->%d len %d\n", bip->fdin, bip->fdout, len ));

    EnterCriticalSection( &bip->lock );
    while ( !bip->can_read )
    {
#if 0
        LeaveCriticalSection( &bip->lock );
        errno = EAGAIN;
        return -1;
#else    
        int  ret;
        LeaveCriticalSection( &bip->lock );

        if (bip->closed) {
            errno = EPIPE;
            return -1;
        }

        ret = WaitForSingleObject( bip->evt_read, INFINITE );
        if (ret != WAIT_OBJECT_0) { /* probably closed buffer */
            D( "bip_buffer_read: error %d->%d WaitForSingleObject returned %d, error %ld\n", bip->fdin, bip->fdout, ret, GetLastError());
            return 0;
        }
        if (bip->closed) {
            errno = EPIPE;
            return -1;
        }
        EnterCriticalSection( &bip->lock );
#endif
    }

    BIPD(( "bip_buffer_read: exec %d->%d len %d\n", bip->fdin, bip->fdout, len ));

    avail = bip->a_end - bip->a_start;
    assert( avail > 0 );  /* since can_read is TRUE */

    if (avail > len)
        avail = len;

    memcpy( dst, bip->buff + bip->a_start, avail );
    dst   += avail;
    count += avail;
    len   -= avail;

    bip->a_start += avail;
    if (bip->a_start < bip->a_end)
        goto Exit;

    bip->a_start = 0;
    bip->a_end   = bip->b_end;
    bip->b_end   = 0;

    avail = bip->a_end;
    if (avail > 0) {
        if (avail > len)
            avail = len;
        memcpy( dst, bip->buff, avail );
        count += avail;
        bip->a_start += avail;

        if ( bip->a_start < bip->a_end )
            goto Exit;

        bip->a_start = bip->a_end = 0;
    }

    bip->can_read = 0;
    ResetEvent( bip->evt_read );

Exit:
    assert( count > 0 );

    if (!bip->can_write ) {
        bip->can_write = 1;
        SetEvent( bip->evt_write );
    }

    BIPDUMP( (const unsigned char*)dst - count, count );
    BIPD(( "bip_buffer_read: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d\n", 
            bip->fdin, bip->fdout, count, bip->a_start, bip->a_end, bip->b_end, bip->can_write, bip->can_read ));
    LeaveCriticalSection( &bip->lock );

    return count;
}

typedef struct SocketPairRec_ 
{
    BipBufferRec  a2b_bip;
    BipBufferRec  b2a_bip;
    FH            a_fd;
    int           used;

} SocketPairRec;

void _fh_socketpair_init( FH  f )
{
    f->fh_pair = NULL;
}

static int
_fh_socketpair_close( FH  f )
{
    if ( f->fh_pair ) {
        SocketPair  pair = f->fh_pair;

        if ( f == pair->a_fd ) {
            pair->a_fd = NULL;
        }

        bip_buffer_close( &pair->b2a_bip );
        bip_buffer_close( &pair->a2b_bip );

        if ( --pair->used == 0 ) {
            bip_buffer_done( &pair->b2a_bip );
            bip_buffer_done( &pair->a2b_bip );
            free( pair );
        }
        f->fh_pair = NULL;
    }
    return 0;
}

static int
_fh_socketpair_lseek( FH  f, int pos, int  origin )
{
    errno = ESPIPE;
    return -1;
}

static int
_fh_socketpair_read( FH  f, void* buf, int  len )
{
    SocketPair  pair = f->fh_pair;
    BipBuffer   bip;

    if (!pair)
        return -1;

    if ( f == pair->a_fd )
        bip = &pair->b2a_bip;
    else
        bip = &pair->a2b_bip;

    return bip_buffer_read( bip, buf, len );
}

static int
_fh_socketpair_write( FH  f, const void*  buf, int  len )
{
    SocketPair  pair = f->fh_pair;
    BipBuffer   bip;

    if (!pair)
        return -1;

    if ( f == pair->a_fd )
        bip = &pair->a2b_bip;
    else
        bip = &pair->b2a_bip;

    return bip_buffer_write( bip, buf, len );
}


static void  _fh_socketpair_hook( FH  f, int  event, EventHook  hook );  /* forward */

static const FHClassRec  _fh_socketpair_class =
{
    _fh_socketpair_init,
    _fh_socketpair_close,
    _fh_socketpair_lseek,
    _fh_socketpair_read,
    _fh_socketpair_write,
    _fh_socketpair_hook
};


int  adb_socketpair( int  sv[2] )
{
    FH          fa, fb;
    SocketPair  pair;

    fa = _fh_alloc( &_fh_socketpair_class );
    fb = _fh_alloc( &_fh_socketpair_class );

    if (!fa || !fb)
        goto Fail;

    pair = malloc( sizeof(*pair) );
    if (pair == NULL) {
        D("adb_socketpair: not enough memory to allocate pipes\n" );
        goto Fail;
    }

    bip_buffer_init( &pair->a2b_bip );
    bip_buffer_init( &pair->b2a_bip );

    fa->fh_pair = pair;
    fb->fh_pair = pair;
    pair->used  = 2;
    pair->a_fd  = fa;

    sv[0] = _fh_to_int(fa);
    sv[1] = _fh_to_int(fb);

    pair->a2b_bip.fdin  = sv[0];
    pair->a2b_bip.fdout = sv[1];
    pair->b2a_bip.fdin  = sv[1];
    pair->b2a_bip.fdout = sv[0];

    snprintf( fa->name, sizeof(fa->name), "%d(pair:%d)", sv[0], sv[1] );
    snprintf( fb->name, sizeof(fb->name), "%d(pair:%d)", sv[1], sv[0] );
    D( "adb_socketpair: returns (%d, %d)\n", sv[0], sv[1] );
    return 0;

Fail:
    _fh_close(fb);
    _fh_close(fa);
    return -1;
}

/**************************************************************************/
/**************************************************************************/
/*****                                                                *****/
/*****    fdevents emulation                                          *****/
/*****                                                                *****/
/*****   this is a very simple implementation, we rely on the fact    *****/
/*****   that ADB doesn't use FDE_ERROR.                              *****/
/*****                                                                *****/
/**************************************************************************/
/**************************************************************************/

#define FATAL(x...) fatal(__FUNCTION__, x)

#if DEBUG
static void dump_fde(fdevent *fde, const char *info)
{
    fprintf(stderr,"FDE #%03d %c%c%c %s\n", fde->fd,
            fde->state & FDE_READ ? 'R' : ' ',
            fde->state & FDE_WRITE ? 'W' : ' ',
            fde->state & FDE_ERROR ? 'E' : ' ',
            info);
}
#else
#define dump_fde(fde, info) do { } while(0)
#endif

#define FDE_EVENTMASK  0x00ff
#define FDE_STATEMASK  0xff00

#define FDE_ACTIVE     0x0100
#define FDE_PENDING    0x0200
#define FDE_CREATED    0x0400

static void fdevent_plist_enqueue(fdevent *node);
static void fdevent_plist_remove(fdevent *node);
static fdevent *fdevent_plist_dequeue(void);

static fdevent list_pending = {
    .next = &list_pending,
    .prev = &list_pending,
};

static fdevent **fd_table = 0;
static int       fd_table_max = 0;

typedef struct EventLooperRec_*  EventLooper;

typedef struct EventHookRec_
{
    EventHook    next;
    FH           fh;
    HANDLE       h;
    int          wanted;   /* wanted event flags */
    int          ready;    /* ready event flags  */
    void*        aux;
    void        (*prepare)( EventHook  hook );
    int         (*start)  ( EventHook  hook );
    void        (*stop)   ( EventHook  hook );
    int         (*check)  ( EventHook  hook );
    int         (*peek)   ( EventHook  hook );
} EventHookRec;

static EventHook  _free_hooks;

static EventHook
event_hook_alloc( FH  fh )
{
    EventHook  hook = _free_hooks;
    if (hook != NULL)
        _free_hooks = hook->next;
    else {
        hook = malloc( sizeof(*hook) );
        if (hook == NULL)
            fatal( "could not allocate event hook\n" );
    }
    hook->next   = NULL;
    hook->fh     = fh;
    hook->wanted = 0;
    hook->ready  = 0;
    hook->h      = INVALID_HANDLE_VALUE;
    hook->aux    = NULL;

    hook->prepare = NULL;
    hook->start   = NULL;
    hook->stop    = NULL;
    hook->check   = NULL;
    hook->peek    = NULL;

    return hook;
}

static void
event_hook_free( EventHook  hook )
{
    hook->fh     = NULL;
    hook->wanted = 0;
    hook->ready  = 0;
    hook->next   = _free_hooks;
    _free_hooks  = hook;
}


static void
event_hook_signal( EventHook  hook )
{
    FH        f   = hook->fh;
    int       fd  = _fh_to_int(f);
    fdevent*  fde = fd_table[ fd - WIN32_FH_BASE ];

    if (fde != NULL && fde->fd == fd) {
        if ((fde->state & FDE_PENDING) == 0) {
            fde->state |= FDE_PENDING;
            fdevent_plist_enqueue( fde );
        }
        fde->events |= hook->wanted;
    }
}


#define  MAX_LOOPER_HANDLES  WIN32_MAX_FHS

typedef struct EventLooperRec_
{
    EventHook    hooks;
    HANDLE       htab[ MAX_LOOPER_HANDLES ];
    int          htab_count;

} EventLooperRec;

static EventHook*
event_looper_find_p( EventLooper  looper, FH  fh )
{
    EventHook  *pnode = &looper->hooks;
    EventHook   node  = *pnode;
    for (;;) {
        if ( node == NULL || node->fh == fh )
            break;
        pnode = &node->next;
        node  = *pnode;
    }
    return  pnode;
}

static void
event_looper_hook( EventLooper  looper, int  fd, int  events )
{
    FH          f = _fh_from_int(fd);
    EventHook  *pnode;
    EventHook   node;

    if (f == NULL)  /* invalid arg */ {
        D("event_looper_hook: invalid fd=%d\n", fd);
        return;
    }

    pnode = event_looper_find_p( looper, f );
    node  = *pnode;
    if ( node == NULL ) {
        node       = event_hook_alloc( f );
        node->next = *pnode;
        *pnode     = node;
    }

    if ( (node->wanted & events) != events ) {
        /* this should update start/stop/check/peek */
        D("event_looper_hook: call hook for %d (new=%x, old=%x)\n",
           fd, node->wanted, events);
        f->clazz->_fh_hook( f, events & ~node->wanted, node );
        node->wanted |= events;
    } else {
        D("event_looper_hook: ignoring events %x for %d wanted=%x)\n", 
           events, fd, node->wanted);
    }
}

static void
event_looper_unhook( EventLooper  looper, int  fd, int  events )
{
    FH          fh    = _fh_from_int(fd);
    EventHook  *pnode = event_looper_find_p( looper, fh );
    EventHook   node  = *pnode;

    if (node != NULL) {
        int  events2 = events & node->wanted;
        if ( events2 == 0 ) {
            D( "event_looper_unhook: events %x not registered for fd %d\n", events, fd );
            return;
        }
        node->wanted &= ~events2;
        if (!node->wanted) {
            *pnode = node->next;
            event_hook_free( node );
        }
    }
}

static EventLooperRec  win32_looper;

static void fdevent_init(void)
{
    win32_looper.htab_count = 0;
    win32_looper.hooks      = NULL;
}

static void fdevent_connect(fdevent *fde)
{
    EventLooper  looper = &win32_looper;
    int          events = fde->state & FDE_EVENTMASK;

    if (events != 0)
        event_looper_hook( looper, fde->fd, events );
}

static void fdevent_disconnect(fdevent *fde)
{
    EventLooper  looper = &win32_looper;
    int          events = fde->state & FDE_EVENTMASK;

    if (events != 0)
        event_looper_unhook( looper, fde->fd, events );
}

static void fdevent_update(fdevent *fde, unsigned events)
{
    EventLooper  looper  = &win32_looper;
    unsigned     events0 = fde->state & FDE_EVENTMASK;

    if (events != events0) {
        int  removes = events0 & ~events;
        int  adds    = events  & ~events0;
        if (removes) {
            D("fdevent_update: remove %x from %d\n", removes, fde->fd);
            event_looper_unhook( looper, fde->fd, removes );
        }
        if (adds) {
            D("fdevent_update: add %x to %d\n", adds, fde->fd);
            event_looper_hook  ( looper, fde->fd, adds );
        }
    }
}

static void fdevent_process()
{
    EventLooper  looper = &win32_looper;
    EventHook    hook;
    int          gotone = 0;

    /* if we have at least one ready hook, execute it/them */
    for (hook = looper->hooks; hook; hook = hook->next) {
        hook->ready = 0;
        if (hook->prepare) {
            hook->prepare(hook);
            if (hook->ready != 0) {
                event_hook_signal( hook );
                gotone = 1;
            }
        }
    }

    /* nothing's ready yet, so wait for something to happen */
    if (!gotone)
    {
        looper->htab_count = 0;

        for (hook = looper->hooks; hook; hook = hook->next) 
        {
            if (hook->start && !hook->start(hook)) {
                D( "fdevent_process: error when starting a hook\n" );
                return;
            }
            if (hook->h != INVALID_HANDLE_VALUE) {
                int  nn;

                for (nn = 0; nn < looper->htab_count; nn++)
                {
                    if ( looper->htab[nn] == hook->h )
                        goto DontAdd;
                }
                looper->htab[ looper->htab_count++ ] = hook->h;
            DontAdd:
                ;
            }
        }

        if (looper->htab_count == 0) {
            D( "fdevent_process: nothing to wait for !!\n" );
            return;
        }

        do
        {
            int   wait_ret;

            D( "adb_win32: waiting for %d events\n", looper->htab_count );
            if (looper->htab_count > MAXIMUM_WAIT_OBJECTS) {
                D("handle count %d exceeds MAXIMUM_WAIT_OBJECTS, aborting!\n", looper->htab_count);
                abort();
            }
            wait_ret = WaitForMultipleObjects( looper->htab_count, looper->htab, FALSE, INFINITE );
            if (wait_ret == (int)WAIT_FAILED) {
                D( "adb_win32: wait failed, error %ld\n", GetLastError() );
            } else {
                D( "adb_win32: got one (index %d)\n", wait_ret );

                /* according to Cygwin, some objects like consoles wake up on "inappropriate" events
                 * like mouse movements. we need to filter these with the "check" function
                 */
                if ((unsigned)wait_ret < (unsigned)looper->htab_count)
                {
                    for (hook = looper->hooks; hook; hook = hook->next)
                    {
                        if ( looper->htab[wait_ret] == hook->h       &&
                         (!hook->check || hook->check(hook)) )
                        {
                            D( "adb_win32: signaling %s for %x\n", hook->fh->name, hook->ready );
                            event_hook_signal( hook );
                            gotone = 1;
                            break;
                        }
                    }
                }
            }
        }
        while (!gotone);

        for (hook = looper->hooks; hook; hook = hook->next) {
            if (hook->stop)
                hook->stop( hook );
        }
    }

    for (hook = looper->hooks; hook; hook = hook->next) {
        if (hook->peek && hook->peek(hook))
                event_hook_signal( hook );
    }
}


static void fdevent_register(fdevent *fde)
{
    int  fd = fde->fd - WIN32_FH_BASE;

    if(fd < 0) {
        FATAL("bogus negative fd (%d)\n", fde->fd);
    }

    if(fd >= fd_table_max) {
        int oldmax = fd_table_max;
        if(fde->fd > 32000) {
            FATAL("bogus huuuuge fd (%d)\n", fde->fd);
        }
        if(fd_table_max == 0) {
            fdevent_init();
            fd_table_max = 256;
        }
        while(fd_table_max <= fd) {
            fd_table_max *= 2;
        }
        fd_table = realloc(fd_table, sizeof(fdevent*) * fd_table_max);
        if(fd_table == 0) {
            FATAL("could not expand fd_table to %d entries\n", fd_table_max);
        }
        memset(fd_table + oldmax, 0, sizeof(int) * (fd_table_max - oldmax));
    }

    fd_table[fd] = fde;
}

static void fdevent_unregister(fdevent *fde)
{
    int  fd = fde->fd - WIN32_FH_BASE;

    if((fd < 0) || (fd >= fd_table_max)) {
        FATAL("fd out of range (%d)\n", fde->fd);
    }

    if(fd_table[fd] != fde) {
        FATAL("fd_table out of sync");
    }

    fd_table[fd] = 0;

    if(!(fde->state & FDE_DONT_CLOSE)) {
        dump_fde(fde, "close");
        adb_close(fde->fd);
    }
}

static void fdevent_plist_enqueue(fdevent *node)
{
    fdevent *list = &list_pending;

    node->next = list;
    node->prev = list->prev;
    node->prev->next = node;
    list->prev = node;
}

static void fdevent_plist_remove(fdevent *node)
{
    node->prev->next = node->next;
    node->next->prev = node->prev;
    node->next = 0;
    node->prev = 0;
}

static fdevent *fdevent_plist_dequeue(void)
{
    fdevent *list = &list_pending;
    fdevent *node = list->next;

    if(node == list) return 0;

    list->next = node->next;
    list->next->prev = list;
    node->next = 0;
    node->prev = 0;

    return node;
}

fdevent *fdevent_create(int fd, fd_func func, void *arg)
{
    fdevent *fde = (fdevent*) malloc(sizeof(fdevent));
    if(fde == 0) return 0;
    fdevent_install(fde, fd, func, arg);
    fde->state |= FDE_CREATED;
    return fde;
}

void fdevent_destroy(fdevent *fde)
{
    if(fde == 0) return;
    if(!(fde->state & FDE_CREATED)) {
        FATAL("fde %p not created by fdevent_create()\n", fde);
    }
    fdevent_remove(fde);
}

void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg) 
{
    memset(fde, 0, sizeof(fdevent));
    fde->state = FDE_ACTIVE;
    fde->fd = fd;
    fde->func = func;
    fde->arg = arg;

    fdevent_register(fde);
    dump_fde(fde, "connect");
    fdevent_connect(fde);
    fde->state |= FDE_ACTIVE;
}

void fdevent_remove(fdevent *fde)
{
    if(fde->state & FDE_PENDING) {
        fdevent_plist_remove(fde);
    }

    if(fde->state & FDE_ACTIVE) {
        fdevent_disconnect(fde);
        dump_fde(fde, "disconnect");    
        fdevent_unregister(fde);
    }

    fde->state = 0;
    fde->events = 0;
}


void fdevent_set(fdevent *fde, unsigned events)
{
    events &= FDE_EVENTMASK;

    if((fde->state & FDE_EVENTMASK) == (int)events) return;

    if(fde->state & FDE_ACTIVE) {
        fdevent_update(fde, events);
        dump_fde(fde, "update");
    }

    fde->state = (fde->state & FDE_STATEMASK) | events;

    if(fde->state & FDE_PENDING) {
            /* if we're pending, make sure
            ** we don't signal an event that
            ** is no longer wanted.
            */
        fde->events &= (~events);
        if(fde->events == 0) {
            fdevent_plist_remove(fde);
            fde->state &= (~FDE_PENDING);
        }
    }
}

void fdevent_add(fdevent *fde, unsigned events)
{
    fdevent_set(
        fde, (fde->state & FDE_EVENTMASK) | (events & FDE_EVENTMASK));
}

void fdevent_del(fdevent *fde, unsigned events)
{
    fdevent_set(
        fde, (fde->state & FDE_EVENTMASK) & (~(events & FDE_EVENTMASK)));
}

void fdevent_loop()
{
    fdevent *fde;

    for(;;) {
#if DEBUG
        fprintf(stderr,"--- ---- waiting for events\n");
#endif
        fdevent_process();

        while((fde = fdevent_plist_dequeue())) {
            unsigned events = fde->events;
            fde->events = 0;
            fde->state &= (~FDE_PENDING);
            dump_fde(fde, "callback");
            fde->func(fde->fd, events, fde->arg);
        }
    }
}

/**  FILE EVENT HOOKS
 **/

static void  _event_file_prepare( EventHook  hook )
{
    if (hook->wanted & (FDE_READ|FDE_WRITE)) {
        /* we can always read/write */
        hook->ready |= hook->wanted & (FDE_READ|FDE_WRITE);
    }
}

static int  _event_file_peek( EventHook  hook )
{
    return (hook->wanted & (FDE_READ|FDE_WRITE));
}

static void  _fh_file_hook( FH  f, int  events, EventHook  hook )
{
    hook->h       = f->fh_handle;
    hook->prepare = _event_file_prepare;
    hook->peek    = _event_file_peek;
}

/** SOCKET EVENT HOOKS
 **/

static void  _event_socket_verify( EventHook  hook, WSANETWORKEVENTS*  evts )
{
    if ( evts->lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE) ) {
        if (hook->wanted & FDE_READ)
            hook->ready |= FDE_READ;
        if ((evts->iErrorCode[FD_READ] != 0) && hook->wanted & FDE_ERROR)
            hook->ready |= FDE_ERROR;
    }
    if ( evts->lNetworkEvents & (FD_WRITE|FD_CONNECT|FD_CLOSE) ) {
        if (hook->wanted & FDE_WRITE)
            hook->ready |= FDE_WRITE;
        if ((evts->iErrorCode[FD_WRITE] != 0) && hook->wanted & FDE_ERROR)
            hook->ready |= FDE_ERROR;
    }
    if ( evts->lNetworkEvents & FD_OOB ) {
        if (hook->wanted & FDE_ERROR)
            hook->ready |= FDE_ERROR;
    }
}

static void  _event_socket_prepare( EventHook  hook )
{
    WSANETWORKEVENTS  evts;

    /* look if some of the events we want already happened ? */
    if (!WSAEnumNetworkEvents( hook->fh->fh_socket, NULL, &evts ))
        _event_socket_verify( hook, &evts );
}

static int  _socket_wanted_to_flags( int  wanted )
{
    int  flags = 0;
    if (wanted & FDE_READ)
        flags |= FD_READ | FD_ACCEPT | FD_CLOSE;

    if (wanted & FDE_WRITE)
        flags |= FD_WRITE | FD_CONNECT | FD_CLOSE;

    if (wanted & FDE_ERROR)
        flags |= FD_OOB;

    return flags;
}

static int _event_socket_start( EventHook  hook )
{
    /* create an event which we're going to wait for */
    FH    fh    = hook->fh;
    long  flags = _socket_wanted_to_flags( hook->wanted );

    hook->h = fh->event;
    if (hook->h == INVALID_HANDLE_VALUE) {
        D( "_event_socket_start: no event for %s\n", fh->name );
        return 0;
    }

    if ( flags != fh->mask ) {
        D( "_event_socket_start: hooking %s for %x (flags %ld)\n", hook->fh->name, hook->wanted, flags );
        if ( WSAEventSelect( fh->fh_socket, hook->h, flags ) ) {
            D( "_event_socket_start: WSAEventSelect() for %s failed, error %d\n", hook->fh->name, WSAGetLastError() );
            CloseHandle( hook->h );
            hook->h = INVALID_HANDLE_VALUE;
            exit(1);
            return 0;
        }
        fh->mask = flags;
    }
    return 1;
}

static void _event_socket_stop( EventHook  hook )
{
    hook->h = INVALID_HANDLE_VALUE;
}

static int  _event_socket_check( EventHook  hook )
{
    int               result = 0;
    FH                fh = hook->fh;
    WSANETWORKEVENTS  evts;

    if (!WSAEnumNetworkEvents( fh->fh_socket, hook->h, &evts ) ) {
        _event_socket_verify( hook, &evts );
        result = (hook->ready != 0);
        if (result) {
            ResetEvent( hook->h );
        }
    }
    D( "_event_socket_check %s returns %d\n", fh->name, result );
    return  result;
}

static int  _event_socket_peek( EventHook  hook )
{
    WSANETWORKEVENTS  evts;
    FH                fh = hook->fh;

    /* look if some of the events we want already happened ? */
    if (!WSAEnumNetworkEvents( fh->fh_socket, NULL, &evts )) {
        _event_socket_verify( hook, &evts );
        if (hook->ready)
            ResetEvent( hook->h );
    }

    return hook->ready != 0;
}



static void  _fh_socket_hook( FH  f, int  events, EventHook  hook )
{
    hook->prepare = _event_socket_prepare;
    hook->start   = _event_socket_start;
    hook->stop    = _event_socket_stop;
    hook->check   = _event_socket_check;
    hook->peek    = _event_socket_peek;

    _event_socket_start( hook );
}

/** SOCKETPAIR EVENT HOOKS
 **/

static void  _event_socketpair_prepare( EventHook  hook )
{
    FH          fh   = hook->fh;
    SocketPair  pair = fh->fh_pair;
    BipBuffer   rbip = (pair->a_fd == fh) ? &pair->b2a_bip : &pair->a2b_bip;
    BipBuffer   wbip = (pair->a_fd == fh) ? &pair->a2b_bip : &pair->b2a_bip;

    if (hook->wanted & FDE_READ && rbip->can_read)
        hook->ready |= FDE_READ;

    if (hook->wanted & FDE_WRITE && wbip->can_write) 
        hook->ready |= FDE_WRITE;
 }

 static int  _event_socketpair_start( EventHook  hook )
 {
    FH          fh   = hook->fh;
    SocketPair  pair = fh->fh_pair;
    BipBuffer   rbip = (pair->a_fd == fh) ? &pair->b2a_bip : &pair->a2b_bip;
    BipBuffer   wbip = (pair->a_fd == fh) ? &pair->a2b_bip : &pair->b2a_bip;

    if (hook->wanted == FDE_READ)
        hook->h = rbip->evt_read;

    else if (hook->wanted == FDE_WRITE)
        hook->h = wbip->evt_write;

    else {
        D("_event_socketpair_start: can't handle FDE_READ+FDE_WRITE\n" );
        return 0;
    }
    D( "_event_socketpair_start: hook %s for %x wanted=%x\n", 
       hook->fh->name, _fh_to_int(fh), hook->wanted);
    return 1;
}

static int  _event_socketpair_peek( EventHook  hook )
{
    _event_socketpair_prepare( hook );
    return hook->ready != 0;
}

static void  _fh_socketpair_hook( FH  fh, int  events, EventHook  hook )
{
    hook->prepare = _event_socketpair_prepare;
    hook->start   = _event_socketpair_start;
    hook->peek    = _event_socketpair_peek;
}


void
adb_sysdeps_init( void )
{
#define  ADB_MUTEX(x)  InitializeCriticalSection( & x );
#include "mutex_list.h"
    InitializeCriticalSection( &_win32_lock );
}

