diff --git a/src/devtools/adb_tcp/sysdeps_win32.c b/src/devtools/adb_tcp/sysdeps_win32.c
new file mode 100644
index 0000000..b082c6d
--- /dev/null
+++ b/src/devtools/adb_tcp/sysdeps_win32.c
@@ -0,0 +1,2227 @@
+#include "sysdeps.h"
+#include <winsock2.h>
+#include <windows.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_network_client_timeout(const char *host, int port, int type, int timeout)
+{
+    // TODO: implement timeouts for Windows.
+    return socket_network_client(host, port, type);
+}
+
+
+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 = 1;
+
+    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   = (const char *)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   = (char *)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 );
+        }
+    }
+}
+
+/*
+ * A fixer for WaitForMultipleObjects on condition that there are more than 64
+ * handles to wait on.
+ *
+ * In cetain cases DDMS may establish more than 64 connections with ADB. For
+ * instance, this may happen if there are more than 64 processes running on a
+ * device, or there are multiple devices connected (including the emulator) with
+ * the combined number of running processes greater than 64. In this case using
+ * WaitForMultipleObjects to wait on connection events simply wouldn't cut,
+ * because of the API limitations (64 handles max). So, we need to provide a way
+ * to scale WaitForMultipleObjects to accept an arbitrary number of handles. The
+ * easiest (and "Microsoft recommended") way to do that would be dividing the
+ * handle array into chunks with the chunk size less than 64, and fire up as many
+ * waiting threads as there are chunks. Then each thread would wait on a chunk of
+ * handles, and will report back to the caller which handle has been set.
+ * Here is the implementation of that algorithm.
+ */
+
+/* Number of handles to wait on in each wating thread. */
+#define WAIT_ALL_CHUNK_SIZE 63
+
+/* Descriptor for a wating thread */
+typedef struct WaitForAllParam {
+    /* A handle to an event to signal when waiting is over. This handle is shared
+     * accross all the waiting threads, so each waiting thread knows when any
+     * other thread has exited, so it can exit too. */
+    HANDLE          main_event;
+    /* Upon exit from a waiting thread contains the index of the handle that has
+     * been signaled. The index is an absolute index of the signaled handle in
+     * the original array. This pointer is shared accross all the waiting threads
+     * and it's not guaranteed (due to a race condition) that when all the
+     * waiting threads exit, the value contained here would indicate the first
+     * handle that was signaled. This is fine, because the caller cares only
+     * about any handle being signaled. It doesn't care about the order, nor
+     * about the whole list of handles that were signaled. */
+    LONG volatile   *signaled_index;
+    /* Array of handles to wait on in a waiting thread. */
+    HANDLE*         handles;
+    /* Number of handles in 'handles' array to wait on. */
+    int             handles_count;
+    /* Index inside the main array of the first handle in the 'handles' array. */
+    int             first_handle_index;
+    /* Waiting thread handle. */
+    HANDLE          thread;
+} WaitForAllParam;
+
+/* Waiting thread routine. */
+static unsigned __stdcall
+_in_waiter_thread(void*  arg)
+{
+    HANDLE wait_on[WAIT_ALL_CHUNK_SIZE + 1];
+    int res;
+    WaitForAllParam* const param = (WaitForAllParam*)arg;
+
+    /* We have to wait on the main_event in order to be notified when any of the
+     * sibling threads is exiting. */
+    wait_on[0] = param->main_event;
+    /* The rest of the handles go behind the main event handle. */
+    memcpy(wait_on + 1, param->handles, param->handles_count * sizeof(HANDLE));
+
+    res = WaitForMultipleObjects(param->handles_count + 1, wait_on, FALSE, INFINITE);
+    if (res > 0 && res < (param->handles_count + 1)) {
+        /* One of the original handles got signaled. Save its absolute index into
+         * the output variable. */
+        InterlockedCompareExchange(param->signaled_index,
+                                   res - 1L + param->first_handle_index, -1L);
+    }
+
+    /* Notify the caller (and the siblings) that the wait is over. */
+    SetEvent(param->main_event);
+
+    _endthreadex(0);
+    return 0;
+}
+
+/* WaitForMultipeObjects fixer routine.
+ * Param:
+ *  handles Array of handles to wait on.
+ *  handles_count Number of handles in the array.
+ * Return:
+ *  (>= 0 && < handles_count) - Index of the signaled handle in the array, or
+ *  WAIT_FAILED on an error.
+ */
+static int
+_wait_for_all(HANDLE* handles, int handles_count)
+{
+    WaitForAllParam* threads;
+    HANDLE main_event;
+    int chunks, chunk, remains;
+
+    /* This variable is going to be accessed by several threads at the same time,
+     * this is bound to fail randomly when the core is run on multi-core machines.
+     * To solve this, we need to do the following (1 _and_ 2):
+     * 1. Use the "volatile" qualifier to ensure the compiler doesn't optimize
+     *    out the reads/writes in this function unexpectedly.
+     * 2. Ensure correct memory ordering. The "simple" way to do that is to wrap
+     *    all accesses inside a critical section. But we can also use
+     *    InterlockedCompareExchange() which always provide a full memory barrier
+     *    on Win32.
+     */
+    volatile LONG sig_index = -1;
+
+    /* Calculate number of chunks, and allocate thread param array. */
+    chunks = handles_count / WAIT_ALL_CHUNK_SIZE;
+    remains = handles_count % WAIT_ALL_CHUNK_SIZE;
+    threads = (WaitForAllParam*)malloc((chunks + (remains ? 1 : 0)) *
+                                        sizeof(WaitForAllParam));
+    if (threads == NULL) {
+        D("Unable to allocate thread array for %d handles.", handles_count);
+        return (int)WAIT_FAILED;
+    }
+
+    /* Create main event to wait on for all waiting threads. This is a "manualy
+     * reset" event that will remain set once it was set. */
+    main_event = CreateEvent(NULL, TRUE, FALSE, NULL);
+    if (main_event == NULL) {
+        D("Unable to create main event. Error: %d", (int)GetLastError());
+        free(threads);
+        return (int)WAIT_FAILED;
+    }
+
+    /*
+     * Initialize waiting thread parameters.
+     */
+
+    for (chunk = 0; chunk < chunks; chunk++) {
+        threads[chunk].main_event = main_event;
+        threads[chunk].signaled_index = &sig_index;
+        threads[chunk].first_handle_index = WAIT_ALL_CHUNK_SIZE * chunk;
+        threads[chunk].handles = handles + threads[chunk].first_handle_index;
+        threads[chunk].handles_count = WAIT_ALL_CHUNK_SIZE;
+    }
+    if (remains) {
+        threads[chunk].main_event = main_event;
+        threads[chunk].signaled_index = &sig_index;
+        threads[chunk].first_handle_index = WAIT_ALL_CHUNK_SIZE * chunk;
+        threads[chunk].handles = handles + threads[chunk].first_handle_index;
+        threads[chunk].handles_count = remains;
+        chunks++;
+    }
+
+    /* Start the waiting threads. */
+    for (chunk = 0; chunk < chunks; chunk++) {
+        /* Note that using adb_thread_create is not appropriate here, since we
+         * need a handle to wait on for thread termination. */
+        threads[chunk].thread = (HANDLE)_beginthreadex(NULL, 0, _in_waiter_thread,
+                                                       &threads[chunk], 0, NULL);
+        if (threads[chunk].thread == NULL) {
+            /* Unable to create a waiter thread. Collapse. */
+            D("Unable to create a waiting thread %d of %d. errno=%d",
+              chunk, chunks, errno);
+            chunks = chunk;
+            SetEvent(main_event);
+            break;
+        }
+    }
+
+    /* Wait on any of the threads to get signaled. */
+    WaitForSingleObject(main_event, INFINITE);
+
+    /* Wait on all the waiting threads to exit. */
+    for (chunk = 0; chunk < chunks; chunk++) {
+        WaitForSingleObject(threads[chunk].thread, INFINITE);
+        CloseHandle(threads[chunk].thread);
+    }
+
+    CloseHandle(main_event);
+    free(threads);
+
+
+    const int ret = (int)InterlockedCompareExchange(&sig_index, -1, -1);
+    return (ret >= 0) ? ret : (int)WAIT_FAILED;
+}
+
+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.\n", looper->htab_count);
+                wait_ret = _wait_for_all(looper->htab, looper->htab_count);
+            } else {
+                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 );
+}
+
+/* Windows doesn't have strtok_r.  Use the one from bionic. */
+
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+char *
+adb_strtok_r(char *s, const char *delim, char **last)
+{
+	char *spanp;
+	int c, sc;
+	char *tok;
+
+
+	if (s == NULL && (s = *last) == NULL)
+		return (NULL);
+
+	/*
+	 * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
+	 */
+cont:
+	c = *s++;
+	for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
+		if (c == sc)
+			goto cont;
+	}
+
+	if (c == 0) {		/* no non-delimiter characters */
+		*last = NULL;
+		return (NULL);
+	}
+	tok = s - 1;
+
+	/*
+	 * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
+	 * Note that delim must have one NUL; we stop if we see that, too.
+	 */
+	for (;;) {
+		c = *s++;
+		spanp = (char *)delim;
+		do {
+			if ((sc = *spanp++) == c) {
+				if (c == 0)
+					s = NULL;
+				else
+					s[-1] = 0;
+				*last = s;
+				return (tok);
+			}
+		} while (sc != 0);
+	}
+	/* NOTREACHED */
+}
