sysdeps_win32.c revision 1b7a7e81195ff06a7482f81cb92b094bb3481cb1
1#include "sysdeps.h"
2#include <windows.h>
3#include <winsock2.h>
4#include <stdio.h>
5#include <errno.h>
6#define  TRACE_TAG  TRACE_SYSDEPS
7#include "adb.h"
8
9extern void fatal(const char *fmt, ...);
10
11#define assert(cond)  do { if (!(cond)) fatal( "assertion failed '%s' on %s:%ld\n", #cond, __FILE__, __LINE__ ); } while (0)
12
13/**************************************************************************/
14/**************************************************************************/
15/*****                                                                *****/
16/*****      replaces libs/cutils/load_file.c                          *****/
17/*****                                                                *****/
18/**************************************************************************/
19/**************************************************************************/
20
21void *load_file(const char *fn, unsigned *_sz)
22{
23    HANDLE    file;
24    char     *data;
25    DWORD     file_size;
26
27    file = CreateFile( fn,
28                       GENERIC_READ,
29                       FILE_SHARE_READ,
30                       NULL,
31                       OPEN_EXISTING,
32                       0,
33                       NULL );
34
35    if (file == INVALID_HANDLE_VALUE)
36        return NULL;
37
38    file_size = GetFileSize( file, NULL );
39    data      = NULL;
40
41    if (file_size > 0) {
42        data = (char*) malloc( file_size + 1 );
43        if (data == NULL) {
44            D("load_file: could not allocate %ld bytes\n", file_size );
45            file_size = 0;
46        } else {
47            DWORD  out_bytes;
48
49            if ( !ReadFile( file, data, file_size, &out_bytes, NULL ) ||
50                 out_bytes != file_size )
51            {
52                D("load_file: could not read %ld bytes from '%s'\n", file_size, fn);
53                free(data);
54                data      = NULL;
55                file_size = 0;
56            }
57        }
58    }
59    CloseHandle( file );
60
61    *_sz = (unsigned) file_size;
62    return  data;
63}
64
65/**************************************************************************/
66/**************************************************************************/
67/*****                                                                *****/
68/*****    common file descriptor handling                             *****/
69/*****                                                                *****/
70/**************************************************************************/
71/**************************************************************************/
72
73typedef const struct FHClassRec_*   FHClass;
74
75typedef struct FHRec_*          FH;
76
77typedef struct EventHookRec_*  EventHook;
78
79typedef struct FHClassRec_
80{
81    void (*_fh_init) ( FH  f );
82    int  (*_fh_close)( FH  f );
83    int  (*_fh_lseek)( FH  f, int  pos, int  origin );
84    int  (*_fh_read) ( FH  f, void*  buf, int  len );
85    int  (*_fh_write)( FH  f, const void*  buf, int  len );
86    void (*_fh_hook) ( FH  f, int  events, EventHook  hook );
87
88} FHClassRec;
89
90/* used to emulate unix-domain socket pairs */
91typedef struct SocketPairRec_*  SocketPair;
92
93typedef struct FHRec_
94{
95    FHClass    clazz;
96    int        used;
97    int        eof;
98    union {
99        HANDLE      handle;
100        SOCKET      socket;
101        SocketPair  pair;
102    } u;
103
104    HANDLE    event;
105    int       mask;
106
107    char  name[32];
108
109} FHRec;
110
111#define  fh_handle  u.handle
112#define  fh_socket  u.socket
113#define  fh_pair    u.pair
114
115#define  WIN32_FH_BASE    100
116
117#define  WIN32_MAX_FHS    128
118
119static adb_mutex_t   _win32_lock;
120static  FHRec        _win32_fhs[ WIN32_MAX_FHS ];
121static  int          _win32_fh_count;
122
123static FH
124_fh_from_int( int   fd )
125{
126    FH  f;
127
128    fd -= WIN32_FH_BASE;
129
130    if (fd < 0 || fd >= _win32_fh_count) {
131        D( "_fh_from_int: invalid fd %d\n", fd + WIN32_FH_BASE );
132        errno = EBADF;
133        return NULL;
134    }
135
136    f = &_win32_fhs[fd];
137
138    if (f->used == 0) {
139        D( "_fh_from_int: invalid fd %d\n", fd + WIN32_FH_BASE );
140        errno = EBADF;
141        return NULL;
142    }
143
144    return f;
145}
146
147
148static int
149_fh_to_int( FH  f )
150{
151    if (f && f->used && f >= _win32_fhs && f < _win32_fhs + WIN32_MAX_FHS)
152        return (int)(f - _win32_fhs) + WIN32_FH_BASE;
153
154    return -1;
155}
156
157static FH
158_fh_alloc( FHClass  clazz )
159{
160    int  nn;
161    FH   f = NULL;
162
163    adb_mutex_lock( &_win32_lock );
164
165    if (_win32_fh_count < WIN32_MAX_FHS) {
166        f = &_win32_fhs[ _win32_fh_count++ ];
167        goto Exit;
168    }
169
170    for (nn = 0; nn < WIN32_MAX_FHS; nn++) {
171        if ( _win32_fhs[nn].clazz == NULL) {
172            f = &_win32_fhs[nn];
173            goto Exit;
174        }
175    }
176    D( "_fh_alloc: no more free file descriptors\n" );
177Exit:
178    if (f) {
179        f->clazz = clazz;
180        f->used  = 1;
181        f->eof   = 0;
182        clazz->_fh_init(f);
183    }
184    adb_mutex_unlock( &_win32_lock );
185    return f;
186}
187
188
189static int
190_fh_close( FH   f )
191{
192    if ( f->used ) {
193        f->clazz->_fh_close( f );
194        f->used = 0;
195        f->eof  = 0;
196        f->clazz = NULL;
197    }
198    return 0;
199}
200
201/* forward definitions */
202static const FHClassRec   _fh_file_class;
203static const FHClassRec   _fh_socket_class;
204
205/**************************************************************************/
206/**************************************************************************/
207/*****                                                                *****/
208/*****    file-based descriptor handling                              *****/
209/*****                                                                *****/
210/**************************************************************************/
211/**************************************************************************/
212
213static void
214_fh_file_init( FH  f )
215{
216    f->fh_handle = INVALID_HANDLE_VALUE;
217}
218
219static int
220_fh_file_close( FH  f )
221{
222    CloseHandle( f->fh_handle );
223    f->fh_handle = INVALID_HANDLE_VALUE;
224    return 0;
225}
226
227static int
228_fh_file_read( FH  f,  void*  buf, int   len )
229{
230    DWORD  read_bytes;
231
232    if ( !ReadFile( f->fh_handle, buf, (DWORD)len, &read_bytes, NULL ) ) {
233        D( "adb_read: could not read %d bytes from %s\n", len, f->name );
234        errno = EIO;
235        return -1;
236    } else if (read_bytes < (DWORD)len) {
237        f->eof = 1;
238    }
239    return (int)read_bytes;
240}
241
242static int
243_fh_file_write( FH  f,  const void*  buf, int   len )
244{
245    DWORD  wrote_bytes;
246
247    if ( !WriteFile( f->fh_handle, buf, (DWORD)len, &wrote_bytes, NULL ) ) {
248        D( "adb_file_write: could not write %d bytes from %s\n", len, f->name );
249        errno = EIO;
250        return -1;
251    } else if (wrote_bytes < (DWORD)len) {
252        f->eof = 1;
253    }
254    return  (int)wrote_bytes;
255}
256
257static int
258_fh_file_lseek( FH  f, int  pos, int  origin )
259{
260    DWORD  method;
261    DWORD  result;
262
263    switch (origin)
264    {
265        case SEEK_SET:  method = FILE_BEGIN; break;
266        case SEEK_CUR:  method = FILE_CURRENT; break;
267        case SEEK_END:  method = FILE_END; break;
268        default:
269            errno = EINVAL;
270            return -1;
271    }
272
273    result = SetFilePointer( f->fh_handle, pos, NULL, method );
274    if (result == INVALID_SET_FILE_POINTER) {
275        errno = EIO;
276        return -1;
277    } else {
278        f->eof = 0;
279    }
280    return (int)result;
281}
282
283static void  _fh_file_hook( FH  f, int  event, EventHook  eventhook );  /* forward */
284
285static const FHClassRec  _fh_file_class =
286{
287    _fh_file_init,
288    _fh_file_close,
289    _fh_file_lseek,
290    _fh_file_read,
291    _fh_file_write,
292    _fh_file_hook
293};
294
295/**************************************************************************/
296/**************************************************************************/
297/*****                                                                *****/
298/*****    file-based descriptor handling                              *****/
299/*****                                                                *****/
300/**************************************************************************/
301/**************************************************************************/
302
303int  adb_open(const char*  path, int  options)
304{
305    FH  f;
306
307    DWORD  desiredAccess       = 0;
308    DWORD  shareMode           = FILE_SHARE_READ | FILE_SHARE_WRITE;
309
310    switch (options) {
311        case O_RDONLY:
312            desiredAccess = GENERIC_READ;
313            break;
314        case O_WRONLY:
315            desiredAccess = GENERIC_WRITE;
316            break;
317        case O_RDWR:
318            desiredAccess = GENERIC_READ | GENERIC_WRITE;
319            break;
320        default:
321            D("adb_open: invalid options (0x%0x)\n", options);
322            errno = EINVAL;
323            return -1;
324    }
325
326    f = _fh_alloc( &_fh_file_class );
327    if ( !f ) {
328        errno = ENOMEM;
329        return -1;
330    }
331
332    f->fh_handle = CreateFile( path, desiredAccess, shareMode, NULL, OPEN_EXISTING,
333                               0, NULL );
334
335    if ( f->fh_handle == INVALID_HANDLE_VALUE ) {
336        _fh_close(f);
337        D( "adb_open: could not open '%s':", path );
338        switch (GetLastError()) {
339            case ERROR_FILE_NOT_FOUND:
340                D( "file not found\n" );
341                errno = ENOENT;
342                return -1;
343
344            case ERROR_PATH_NOT_FOUND:
345                D( "path not found\n" );
346                errno = ENOTDIR;
347                return -1;
348
349            default:
350                D( "unknown error\n" );
351                errno = ENOENT;
352                return -1;
353        }
354    }
355
356    snprintf( f->name, sizeof(f->name), "%d(%s)", _fh_to_int(f), path );
357    D( "adb_open: '%s' => fd %d\n", path, _fh_to_int(f) );
358    return _fh_to_int(f);
359}
360
361/* ignore mode on Win32 */
362int  adb_creat(const char*  path, int  mode)
363{
364    FH  f;
365
366    f = _fh_alloc( &_fh_file_class );
367    if ( !f ) {
368        errno = ENOMEM;
369        return -1;
370    }
371
372    f->fh_handle = CreateFile( path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
373                               NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
374                               NULL );
375
376    if ( f->fh_handle == INVALID_HANDLE_VALUE ) {
377        _fh_close(f);
378        D( "adb_creat: could not open '%s':", path );
379        switch (GetLastError()) {
380            case ERROR_FILE_NOT_FOUND:
381                D( "file not found\n" );
382                errno = ENOENT;
383                return -1;
384
385            case ERROR_PATH_NOT_FOUND:
386                D( "path not found\n" );
387                errno = ENOTDIR;
388                return -1;
389
390            default:
391                D( "unknown error\n" );
392                errno = ENOENT;
393                return -1;
394        }
395    }
396    snprintf( f->name, sizeof(f->name), "%d(%s)", _fh_to_int(f), path );
397    D( "adb_creat: '%s' => fd %d\n", path, _fh_to_int(f) );
398    return _fh_to_int(f);
399}
400
401
402int  adb_read(int  fd, void* buf, int len)
403{
404    FH     f = _fh_from_int(fd);
405
406    if (f == NULL) {
407        return -1;
408    }
409
410    return f->clazz->_fh_read( f, buf, len );
411}
412
413
414int  adb_write(int  fd, const void*  buf, int  len)
415{
416    FH     f = _fh_from_int(fd);
417
418    if (f == NULL) {
419        return -1;
420    }
421
422    return f->clazz->_fh_write(f, buf, len);
423}
424
425
426int  adb_lseek(int  fd, int  pos, int  where)
427{
428    FH     f = _fh_from_int(fd);
429
430    if (!f) {
431        return -1;
432    }
433
434    return f->clazz->_fh_lseek(f, pos, where);
435}
436
437
438int  adb_shutdown(int  fd)
439{
440    FH   f = _fh_from_int(fd);
441
442    if (!f) {
443        return -1;
444    }
445
446    D( "adb_shutdown: %s\n", f->name);
447    shutdown( f->fh_socket, SD_BOTH );
448    return 0;
449}
450
451
452int  adb_close(int  fd)
453{
454    FH   f = _fh_from_int(fd);
455
456    if (!f) {
457        return -1;
458    }
459
460    D( "adb_close: %s\n", f->name);
461    _fh_close(f);
462    return 0;
463}
464
465/**************************************************************************/
466/**************************************************************************/
467/*****                                                                *****/
468/*****    socket-based file descriptors                               *****/
469/*****                                                                *****/
470/**************************************************************************/
471/**************************************************************************/
472
473static void
474_socket_set_errno( void )
475{
476    switch (WSAGetLastError()) {
477    case 0:              errno = 0; break;
478    case WSAEWOULDBLOCK: errno = EAGAIN; break;
479    case WSAEINTR:       errno = EINTR; break;
480    default:
481        D( "_socket_set_errno: unhandled value %d\n", WSAGetLastError() );
482        errno = EINVAL;
483    }
484}
485
486static void
487_fh_socket_init( FH  f )
488{
489    f->fh_socket = INVALID_SOCKET;
490    f->event     = WSACreateEvent();
491    f->mask      = 0;
492}
493
494static int
495_fh_socket_close( FH  f )
496{
497    /* gently tell any peer that we're closing the socket */
498    shutdown( f->fh_socket, SD_BOTH );
499    closesocket( f->fh_socket );
500    f->fh_socket = INVALID_SOCKET;
501    CloseHandle( f->event );
502    f->mask = 0;
503    return 0;
504}
505
506static int
507_fh_socket_lseek( FH  f, int pos, int origin )
508{
509    errno = EPIPE;
510    return -1;
511}
512
513static int
514_fh_socket_read( FH  f, void*  buf, int  len )
515{
516    int  result = recv( f->fh_socket, buf, len, 0 );
517    if (result == SOCKET_ERROR) {
518        _socket_set_errno();
519        result = -1;
520    }
521    return  result;
522}
523
524static int
525_fh_socket_write( FH  f, const void*  buf, int  len )
526{
527    int  result = send( f->fh_socket, buf, len, 0 );
528    if (result == SOCKET_ERROR) {
529        _socket_set_errno();
530        result = -1;
531    }
532    return result;
533}
534
535static void  _fh_socket_hook( FH  f, int  event, EventHook  hook );  /* forward */
536
537static const FHClassRec  _fh_socket_class =
538{
539    _fh_socket_init,
540    _fh_socket_close,
541    _fh_socket_lseek,
542    _fh_socket_read,
543    _fh_socket_write,
544    _fh_socket_hook
545};
546
547/**************************************************************************/
548/**************************************************************************/
549/*****                                                                *****/
550/*****    replacement for libs/cutils/socket_xxxx.c                   *****/
551/*****                                                                *****/
552/**************************************************************************/
553/**************************************************************************/
554
555#include <winsock2.h>
556
557static int  _winsock_init;
558
559static void
560_cleanup_winsock( void )
561{
562    WSACleanup();
563}
564
565static void
566_init_winsock( void )
567{
568    if (!_winsock_init) {
569        WSADATA  wsaData;
570        int      rc = WSAStartup( MAKEWORD(2,2), &wsaData);
571        if (rc != 0) {
572            fatal( "adb: could not initialize Winsock\n" );
573        }
574        atexit( _cleanup_winsock );
575        _winsock_init = 1;
576    }
577}
578
579int socket_loopback_client(int port, int type)
580{
581    FH  f = _fh_alloc( &_fh_socket_class );
582    struct sockaddr_in addr;
583    SOCKET  s;
584
585    if (!f)
586        return -1;
587
588    if (!_winsock_init)
589        _init_winsock();
590
591    memset(&addr, 0, sizeof(addr));
592    addr.sin_family = AF_INET;
593    addr.sin_port = htons(port);
594    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
595
596    s = socket(AF_INET, type, 0);
597    if(s == INVALID_SOCKET) {
598        D("socket_loopback_client: could not create socket\n" );
599        _fh_close(f);
600        return -1;
601    }
602
603    f->fh_socket = s;
604    if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
605        D("socket_loopback_client: could not connect to %s:%d\n", type != SOCK_STREAM ? "udp" : "tcp", port );
606        _fh_close(f);
607        return -1;
608    }
609    snprintf( f->name, sizeof(f->name), "%d(lo-client:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );
610    D( "socket_loopback_client: port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) );
611    return _fh_to_int(f);
612}
613
614#define LISTEN_BACKLOG 4
615
616int socket_loopback_server(int port, int type)
617{
618    FH   f = _fh_alloc( &_fh_socket_class );
619    struct sockaddr_in addr;
620    SOCKET  s;
621    int  n;
622
623    if (!f) {
624        return -1;
625    }
626
627    if (!_winsock_init)
628        _init_winsock();
629
630    memset(&addr, 0, sizeof(addr));
631    addr.sin_family = AF_INET;
632    addr.sin_port = htons(port);
633    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
634
635    s = socket(AF_INET, type, 0);
636    if(s == INVALID_SOCKET) return -1;
637
638    f->fh_socket = s;
639
640    n = 1;
641    setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*)&n, sizeof(n));
642
643    if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
644        _fh_close(f);
645        return -1;
646    }
647    if (type == SOCK_STREAM) {
648        int ret;
649
650        ret = listen(s, LISTEN_BACKLOG);
651        if (ret < 0) {
652            _fh_close(f);
653            return -1;
654        }
655    }
656    snprintf( f->name, sizeof(f->name), "%d(lo-server:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );
657    D( "socket_loopback_server: port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) );
658    return _fh_to_int(f);
659}
660
661
662int socket_network_client(const char *host, int port, int type)
663{
664    FH  f = _fh_alloc( &_fh_socket_class );
665    struct hostent *hp;
666    struct sockaddr_in addr;
667    SOCKET s;
668
669    if (!f)
670        return -1;
671
672    if (!_winsock_init)
673        _init_winsock();
674
675    hp = gethostbyname(host);
676    if(hp == 0) {
677        _fh_close(f);
678        return -1;
679    }
680
681    memset(&addr, 0, sizeof(addr));
682    addr.sin_family = hp->h_addrtype;
683    addr.sin_port = htons(port);
684    memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
685
686    s = socket(hp->h_addrtype, type, 0);
687    if(s == INVALID_SOCKET) {
688        _fh_close(f);
689        return -1;
690    }
691    f->fh_socket = s;
692
693    if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
694        _fh_close(f);
695        return -1;
696    }
697
698    snprintf( f->name, sizeof(f->name), "%d(net-client:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );
699    D( "socket_network_client: host '%s' port %d type %s => fd %d\n", host, port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) );
700    return _fh_to_int(f);
701}
702
703
704int socket_inaddr_any_server(int port, int type)
705{
706    FH  f = _fh_alloc( &_fh_socket_class );
707    struct sockaddr_in addr;
708    SOCKET  s;
709    int n;
710
711    if (!f)
712        return -1;
713
714    if (!_winsock_init)
715        _init_winsock();
716
717    memset(&addr, 0, sizeof(addr));
718    addr.sin_family = AF_INET;
719    addr.sin_port = htons(port);
720    addr.sin_addr.s_addr = htonl(INADDR_ANY);
721
722    s = socket(AF_INET, type, 0);
723    if(s == INVALID_SOCKET) {
724        _fh_close(f);
725        return -1;
726    }
727
728    f->fh_socket = s;
729    n = 1;
730    setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*)&n, sizeof(n));
731
732    if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
733        _fh_close(f);
734        return -1;
735    }
736
737    if (type == SOCK_STREAM) {
738        int ret;
739
740        ret = listen(s, LISTEN_BACKLOG);
741        if (ret < 0) {
742            _fh_close(f);
743            return -1;
744        }
745    }
746    snprintf( f->name, sizeof(f->name), "%d(any-server:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );
747    D( "socket_inaddr_server: port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) );
748    return _fh_to_int(f);
749}
750
751#undef accept
752int  adb_socket_accept(int  serverfd, struct sockaddr*  addr, socklen_t  *addrlen)
753{
754    FH   serverfh = _fh_from_int(serverfd);
755    FH   fh;
756
757    if ( !serverfh || serverfh->clazz != &_fh_socket_class ) {
758        D( "adb_socket_accept: invalid fd %d\n", serverfd );
759        return -1;
760    }
761
762    fh = _fh_alloc( &_fh_socket_class );
763    if (!fh) {
764        D( "adb_socket_accept: not enough memory to allocate accepted socket descriptor\n" );
765        return -1;
766    }
767
768    fh->fh_socket = accept( serverfh->fh_socket, addr, addrlen );
769    if (fh->fh_socket == INVALID_SOCKET) {
770        _fh_close( fh );
771        D( "adb_socket_accept: accept on fd %d return error %ld\n", serverfd, GetLastError() );
772        return -1;
773    }
774
775    snprintf( fh->name, sizeof(fh->name), "%d(accept:%s)", _fh_to_int(fh), serverfh->name );
776    D( "adb_socket_accept on fd %d returns fd %d\n", serverfd, _fh_to_int(fh) );
777    return  _fh_to_int(fh);
778}
779
780
781void  disable_tcp_nagle(int fd)
782{
783    FH   fh = _fh_from_int(fd);
784    int  on;
785
786    if ( !fh || fh->clazz != &_fh_socket_class )
787        return;
788
789    setsockopt( fh->fh_socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&on, sizeof(on) );
790}
791
792/**************************************************************************/
793/**************************************************************************/
794/*****                                                                *****/
795/*****    emulated socketpairs                                       *****/
796/*****                                                                *****/
797/**************************************************************************/
798/**************************************************************************/
799
800/* we implement socketpairs directly in use space for the following reasons:
801 *   - it avoids copying data from/to the Nt kernel
802 *   - it allows us to implement fdevent hooks easily and cheaply, something
803 *     that is not possible with standard Win32 pipes !!
804 *
805 * basically, we use two circular buffers, each one corresponding to a given
806 * direction.
807 *
808 * each buffer is implemented as two regions:
809 *
810 *   region A which is (a_start,a_end)
811 *   region B which is (0, b_end)  with b_end <= a_start
812 *
813 * an empty buffer has:  a_start = a_end = b_end = 0
814 *
815 * a_start is the pointer where we start reading data
816 * a_end is the pointer where we start writing data, unless it is BUFFER_SIZE,
817 * then you start writing at b_end
818 *
819 * the buffer is full when  b_end == a_start && a_end == BUFFER_SIZE
820 *
821 * there is room when b_end < a_start || a_end < BUFER_SIZE
822 *
823 * when reading, a_start is incremented, it a_start meets a_end, then
824 * we do:  a_start = 0, a_end = b_end, b_end = 0, and keep going on..
825 */
826
827#define  BIP_BUFFER_SIZE   4096
828
829#if 0
830#include <stdio.h>
831#  define  BIPD(x)      D x
832#  define  BIPDUMP   bip_dump_hex
833
834static void  bip_dump_hex( const unsigned char*  ptr, size_t  len )
835{
836    int  nn, len2 = len;
837
838    if (len2 > 8) len2 = 8;
839
840    for (nn = 0; nn < len2; nn++)
841        printf("%02x", ptr[nn]);
842    printf("  ");
843
844    for (nn = 0; nn < len2; nn++) {
845        int  c = ptr[nn];
846        if (c < 32 || c > 127)
847            c = '.';
848        printf("%c", c);
849    }
850    printf("\n");
851    fflush(stdout);
852}
853
854#else
855#  define  BIPD(x)        do {} while (0)
856#  define  BIPDUMP(p,l)   BIPD(p)
857#endif
858
859typedef struct BipBufferRec_
860{
861    int                a_start;
862    int                a_end;
863    int                b_end;
864    int                fdin;
865    int                fdout;
866    int                closed;
867    int                can_write;  /* boolean */
868    HANDLE             evt_write;  /* event signaled when one can write to a buffer  */
869    int                can_read;   /* boolean */
870    HANDLE             evt_read;   /* event signaled when one can read from a buffer */
871    CRITICAL_SECTION  lock;
872    unsigned char      buff[ BIP_BUFFER_SIZE ];
873
874} BipBufferRec, *BipBuffer;
875
876static void
877bip_buffer_init( BipBuffer  buffer )
878{
879    D( "bit_buffer_init %p\n", buffer );
880    buffer->a_start   = 0;
881    buffer->a_end     = 0;
882    buffer->b_end     = 0;
883    buffer->can_write = 1;
884    buffer->can_read  = 0;
885    buffer->fdin      = 0;
886    buffer->fdout     = 0;
887    buffer->closed    = 0;
888    buffer->evt_write = CreateEvent( NULL, TRUE, TRUE, NULL );
889    buffer->evt_read  = CreateEvent( NULL, TRUE, FALSE, NULL );
890    InitializeCriticalSection( &buffer->lock );
891}
892
893static void
894bip_buffer_close( BipBuffer  bip )
895{
896    bip->closed = 1;
897
898    if (!bip->can_read) {
899        SetEvent( bip->evt_read );
900    }
901    if (!bip->can_write) {
902        SetEvent( bip->evt_write );
903    }
904}
905
906static void
907bip_buffer_done( BipBuffer  bip )
908{
909    BIPD(( "bip_buffer_done: %d->%d\n", bip->fdin, bip->fdout ));
910    CloseHandle( bip->evt_read );
911    CloseHandle( bip->evt_write );
912    DeleteCriticalSection( &bip->lock );
913}
914
915static int
916bip_buffer_write( BipBuffer  bip, const void* src, int  len )
917{
918    int  avail, count = 0;
919
920    if (len <= 0)
921        return 0;
922
923    BIPD(( "bip_buffer_write: enter %d->%d len %d\n", bip->fdin, bip->fdout, len ));
924    BIPDUMP( src, len );
925
926    EnterCriticalSection( &bip->lock );
927
928    while (!bip->can_write) {
929        int  ret;
930        LeaveCriticalSection( &bip->lock );
931
932        if (bip->closed) {
933            errno = EPIPE;
934            return -1;
935        }
936        /* spinlocking here is probably unfair, but let's live with it */
937        ret = WaitForSingleObject( bip->evt_write, INFINITE );
938        if (ret != WAIT_OBJECT_0) {  /* buffer probably closed */
939            D( "bip_buffer_write: error %d->%d WaitForSingleObject returned %d, error %ld\n", bip->fdin, bip->fdout, ret, GetLastError() );
940            return 0;
941        }
942        if (bip->closed) {
943            errno = EPIPE;
944            return -1;
945        }
946        EnterCriticalSection( &bip->lock );
947    }
948
949    BIPD(( "bip_buffer_write: exec %d->%d len %d\n", bip->fdin, bip->fdout, len ));
950
951    avail = BIP_BUFFER_SIZE - bip->a_end;
952    if (avail > 0)
953    {
954        /* we can append to region A */
955        if (avail > len)
956            avail = len;
957
958        memcpy( bip->buff + bip->a_end, src, avail );
959        src   += avail;
960        count += avail;
961        len   -= avail;
962
963        bip->a_end += avail;
964        if (bip->a_end == BIP_BUFFER_SIZE && bip->a_start == 0) {
965            bip->can_write = 0;
966            ResetEvent( bip->evt_write );
967            goto Exit;
968        }
969    }
970
971    if (len == 0)
972        goto Exit;
973
974    avail = bip->a_start - bip->b_end;
975    assert( avail > 0 );  /* since can_write is TRUE */
976
977    if (avail > len)
978        avail = len;
979
980    memcpy( bip->buff + bip->b_end, src, avail );
981    count += avail;
982    bip->b_end += avail;
983
984    if (bip->b_end == bip->a_start) {
985        bip->can_write = 0;
986        ResetEvent( bip->evt_write );
987    }
988
989Exit:
990    assert( count > 0 );
991
992    if ( !bip->can_read ) {
993        bip->can_read = 1;
994        SetEvent( bip->evt_read );
995    }
996
997    BIPD(( "bip_buffer_write: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d\n",
998            bip->fdin, bip->fdout, count, bip->a_start, bip->a_end, bip->b_end, bip->can_write, bip->can_read ));
999    LeaveCriticalSection( &bip->lock );
1000
1001    return count;
1002 }
1003
1004static int
1005bip_buffer_read( BipBuffer  bip, void*  dst, int  len )
1006{
1007    int  avail, count = 0;
1008
1009    if (len <= 0)
1010        return 0;
1011
1012    BIPD(( "bip_buffer_read: enter %d->%d len %d\n", bip->fdin, bip->fdout, len ));
1013
1014    EnterCriticalSection( &bip->lock );
1015    while ( !bip->can_read )
1016    {
1017#if 0
1018        LeaveCriticalSection( &bip->lock );
1019        errno = EAGAIN;
1020        return -1;
1021#else
1022        int  ret;
1023        LeaveCriticalSection( &bip->lock );
1024
1025        if (bip->closed) {
1026            errno = EPIPE;
1027            return -1;
1028        }
1029
1030        ret = WaitForSingleObject( bip->evt_read, INFINITE );
1031        if (ret != WAIT_OBJECT_0) { /* probably closed buffer */
1032            D( "bip_buffer_read: error %d->%d WaitForSingleObject returned %d, error %ld\n", bip->fdin, bip->fdout, ret, GetLastError());
1033            return 0;
1034        }
1035        if (bip->closed) {
1036            errno = EPIPE;
1037            return -1;
1038        }
1039        EnterCriticalSection( &bip->lock );
1040#endif
1041    }
1042
1043    BIPD(( "bip_buffer_read: exec %d->%d len %d\n", bip->fdin, bip->fdout, len ));
1044
1045    avail = bip->a_end - bip->a_start;
1046    assert( avail > 0 );  /* since can_read is TRUE */
1047
1048    if (avail > len)
1049        avail = len;
1050
1051    memcpy( dst, bip->buff + bip->a_start, avail );
1052    dst   += avail;
1053    count += avail;
1054    len   -= avail;
1055
1056    bip->a_start += avail;
1057    if (bip->a_start < bip->a_end)
1058        goto Exit;
1059
1060    bip->a_start = 0;
1061    bip->a_end   = bip->b_end;
1062    bip->b_end   = 0;
1063
1064    avail = bip->a_end;
1065    if (avail > 0) {
1066        if (avail > len)
1067            avail = len;
1068        memcpy( dst, bip->buff, avail );
1069        count += avail;
1070        bip->a_start += avail;
1071
1072        if ( bip->a_start < bip->a_end )
1073            goto Exit;
1074
1075        bip->a_start = bip->a_end = 0;
1076    }
1077
1078    bip->can_read = 0;
1079    ResetEvent( bip->evt_read );
1080
1081Exit:
1082    assert( count > 0 );
1083
1084    if (!bip->can_write ) {
1085        bip->can_write = 1;
1086        SetEvent( bip->evt_write );
1087    }
1088
1089    BIPDUMP( (const unsigned char*)dst - count, count );
1090    BIPD(( "bip_buffer_read: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d\n",
1091            bip->fdin, bip->fdout, count, bip->a_start, bip->a_end, bip->b_end, bip->can_write, bip->can_read ));
1092    LeaveCriticalSection( &bip->lock );
1093
1094    return count;
1095}
1096
1097typedef struct SocketPairRec_
1098{
1099    BipBufferRec  a2b_bip;
1100    BipBufferRec  b2a_bip;
1101    FH            a_fd;
1102    int           used;
1103
1104} SocketPairRec;
1105
1106void _fh_socketpair_init( FH  f )
1107{
1108    f->fh_pair = NULL;
1109}
1110
1111static int
1112_fh_socketpair_close( FH  f )
1113{
1114    if ( f->fh_pair ) {
1115        SocketPair  pair = f->fh_pair;
1116
1117        if ( f == pair->a_fd ) {
1118            pair->a_fd = NULL;
1119        }
1120
1121        bip_buffer_close( &pair->b2a_bip );
1122        bip_buffer_close( &pair->a2b_bip );
1123
1124        if ( --pair->used == 0 ) {
1125            bip_buffer_done( &pair->b2a_bip );
1126            bip_buffer_done( &pair->a2b_bip );
1127            free( pair );
1128        }
1129        f->fh_pair = NULL;
1130    }
1131    return 0;
1132}
1133
1134static int
1135_fh_socketpair_lseek( FH  f, int pos, int  origin )
1136{
1137    errno = ESPIPE;
1138    return -1;
1139}
1140
1141static int
1142_fh_socketpair_read( FH  f, void* buf, int  len )
1143{
1144    SocketPair  pair = f->fh_pair;
1145    BipBuffer   bip;
1146
1147    if (!pair)
1148        return -1;
1149
1150    if ( f == pair->a_fd )
1151        bip = &pair->b2a_bip;
1152    else
1153        bip = &pair->a2b_bip;
1154
1155    return bip_buffer_read( bip, buf, len );
1156}
1157
1158static int
1159_fh_socketpair_write( FH  f, const void*  buf, int  len )
1160{
1161    SocketPair  pair = f->fh_pair;
1162    BipBuffer   bip;
1163
1164    if (!pair)
1165        return -1;
1166
1167    if ( f == pair->a_fd )
1168        bip = &pair->a2b_bip;
1169    else
1170        bip = &pair->b2a_bip;
1171
1172    return bip_buffer_write( bip, buf, len );
1173}
1174
1175
1176static void  _fh_socketpair_hook( FH  f, int  event, EventHook  hook );  /* forward */
1177
1178static const FHClassRec  _fh_socketpair_class =
1179{
1180    _fh_socketpair_init,
1181    _fh_socketpair_close,
1182    _fh_socketpair_lseek,
1183    _fh_socketpair_read,
1184    _fh_socketpair_write,
1185    _fh_socketpair_hook
1186};
1187
1188
1189int  adb_socketpair( int  sv[2] )
1190{
1191    FH          fa, fb;
1192    SocketPair  pair;
1193
1194    fa = _fh_alloc( &_fh_socketpair_class );
1195    fb = _fh_alloc( &_fh_socketpair_class );
1196
1197    if (!fa || !fb)
1198        goto Fail;
1199
1200    pair = malloc( sizeof(*pair) );
1201    if (pair == NULL) {
1202        D("adb_socketpair: not enough memory to allocate pipes\n" );
1203        goto Fail;
1204    }
1205
1206    bip_buffer_init( &pair->a2b_bip );
1207    bip_buffer_init( &pair->b2a_bip );
1208
1209    fa->fh_pair = pair;
1210    fb->fh_pair = pair;
1211    pair->used  = 2;
1212    pair->a_fd  = fa;
1213
1214    sv[0] = _fh_to_int(fa);
1215    sv[1] = _fh_to_int(fb);
1216
1217    pair->a2b_bip.fdin  = sv[0];
1218    pair->a2b_bip.fdout = sv[1];
1219    pair->b2a_bip.fdin  = sv[1];
1220    pair->b2a_bip.fdout = sv[0];
1221
1222    snprintf( fa->name, sizeof(fa->name), "%d(pair:%d)", sv[0], sv[1] );
1223    snprintf( fb->name, sizeof(fb->name), "%d(pair:%d)", sv[1], sv[0] );
1224    D( "adb_socketpair: returns (%d, %d)\n", sv[0], sv[1] );
1225    return 0;
1226
1227Fail:
1228    _fh_close(fb);
1229    _fh_close(fa);
1230    return -1;
1231}
1232
1233/**************************************************************************/
1234/**************************************************************************/
1235/*****                                                                *****/
1236/*****    fdevents emulation                                          *****/
1237/*****                                                                *****/
1238/*****   this is a very simple implementation, we rely on the fact    *****/
1239/*****   that ADB doesn't use FDE_ERROR.                              *****/
1240/*****                                                                *****/
1241/**************************************************************************/
1242/**************************************************************************/
1243
1244#define FATAL(x...) fatal(__FUNCTION__, x)
1245
1246#if DEBUG
1247static void dump_fde(fdevent *fde, const char *info)
1248{
1249    fprintf(stderr,"FDE #%03d %c%c%c %s\n", fde->fd,
1250            fde->state & FDE_READ ? 'R' : ' ',
1251            fde->state & FDE_WRITE ? 'W' : ' ',
1252            fde->state & FDE_ERROR ? 'E' : ' ',
1253            info);
1254}
1255#else
1256#define dump_fde(fde, info) do { } while(0)
1257#endif
1258
1259#define FDE_EVENTMASK  0x00ff
1260#define FDE_STATEMASK  0xff00
1261
1262#define FDE_ACTIVE     0x0100
1263#define FDE_PENDING    0x0200
1264#define FDE_CREATED    0x0400
1265
1266static void fdevent_plist_enqueue(fdevent *node);
1267static void fdevent_plist_remove(fdevent *node);
1268static fdevent *fdevent_plist_dequeue(void);
1269
1270static fdevent list_pending = {
1271    .next = &list_pending,
1272    .prev = &list_pending,
1273};
1274
1275static fdevent **fd_table = 0;
1276static int       fd_table_max = 0;
1277
1278typedef struct EventLooperRec_*  EventLooper;
1279
1280typedef struct EventHookRec_
1281{
1282    EventHook    next;
1283    FH           fh;
1284    HANDLE       h;
1285    int          wanted;   /* wanted event flags */
1286    int          ready;    /* ready event flags  */
1287    void*        aux;
1288    void        (*prepare)( EventHook  hook );
1289    int         (*start)  ( EventHook  hook );
1290    void        (*stop)   ( EventHook  hook );
1291    int         (*check)  ( EventHook  hook );
1292    int         (*peek)   ( EventHook  hook );
1293} EventHookRec;
1294
1295static EventHook  _free_hooks;
1296
1297static EventHook
1298event_hook_alloc( FH  fh )
1299{
1300    EventHook  hook = _free_hooks;
1301    if (hook != NULL)
1302        _free_hooks = hook->next;
1303    else {
1304        hook = malloc( sizeof(*hook) );
1305        if (hook == NULL)
1306            fatal( "could not allocate event hook\n" );
1307    }
1308    hook->next   = NULL;
1309    hook->fh     = fh;
1310    hook->wanted = 0;
1311    hook->ready  = 0;
1312    hook->h      = INVALID_HANDLE_VALUE;
1313    hook->aux    = NULL;
1314
1315    hook->prepare = NULL;
1316    hook->start   = NULL;
1317    hook->stop    = NULL;
1318    hook->check   = NULL;
1319    hook->peek    = NULL;
1320
1321    return hook;
1322}
1323
1324static void
1325event_hook_free( EventHook  hook )
1326{
1327    hook->fh     = NULL;
1328    hook->wanted = 0;
1329    hook->ready  = 0;
1330    hook->next   = _free_hooks;
1331    _free_hooks  = hook;
1332}
1333
1334
1335static void
1336event_hook_signal( EventHook  hook )
1337{
1338    FH        f   = hook->fh;
1339    int       fd  = _fh_to_int(f);
1340    fdevent*  fde = fd_table[ fd - WIN32_FH_BASE ];
1341
1342    if (fde != NULL && fde->fd == fd) {
1343        if ((fde->state & FDE_PENDING) == 0) {
1344            fde->state |= FDE_PENDING;
1345            fdevent_plist_enqueue( fde );
1346        }
1347        fde->events |= hook->wanted;
1348    }
1349}
1350
1351
1352#define  MAX_LOOPER_HANDLES  WIN32_MAX_FHS
1353
1354typedef struct EventLooperRec_
1355{
1356    EventHook    hooks;
1357    HANDLE       htab[ MAX_LOOPER_HANDLES ];
1358    int          htab_count;
1359
1360} EventLooperRec;
1361
1362static EventHook*
1363event_looper_find_p( EventLooper  looper, FH  fh )
1364{
1365    EventHook  *pnode = &looper->hooks;
1366    EventHook   node  = *pnode;
1367    for (;;) {
1368        if ( node == NULL || node->fh == fh )
1369            break;
1370        pnode = &node->next;
1371        node  = *pnode;
1372    }
1373    return  pnode;
1374}
1375
1376static void
1377event_looper_hook( EventLooper  looper, int  fd, int  events )
1378{
1379    FH          f = _fh_from_int(fd);
1380    EventHook  *pnode;
1381    EventHook   node;
1382
1383    if (f == NULL)  /* invalid arg */ {
1384        D("event_looper_hook: invalid fd=%d\n", fd);
1385        return;
1386    }
1387
1388    pnode = event_looper_find_p( looper, f );
1389    node  = *pnode;
1390    if ( node == NULL ) {
1391        node       = event_hook_alloc( f );
1392        node->next = *pnode;
1393        *pnode     = node;
1394    }
1395
1396    if ( (node->wanted & events) != events ) {
1397        /* this should update start/stop/check/peek */
1398        D("event_looper_hook: call hook for %d (new=%x, old=%x)\n",
1399           fd, node->wanted, events);
1400        f->clazz->_fh_hook( f, events & ~node->wanted, node );
1401        node->wanted |= events;
1402    } else {
1403        D("event_looper_hook: ignoring events %x for %d wanted=%x)\n",
1404           events, fd, node->wanted);
1405    }
1406}
1407
1408static void
1409event_looper_unhook( EventLooper  looper, int  fd, int  events )
1410{
1411    FH          fh    = _fh_from_int(fd);
1412    EventHook  *pnode = event_looper_find_p( looper, fh );
1413    EventHook   node  = *pnode;
1414
1415    if (node != NULL) {
1416        int  events2 = events & node->wanted;
1417        if ( events2 == 0 ) {
1418            D( "event_looper_unhook: events %x not registered for fd %d\n", events, fd );
1419            return;
1420        }
1421        node->wanted &= ~events2;
1422        if (!node->wanted) {
1423            *pnode = node->next;
1424            event_hook_free( node );
1425        }
1426    }
1427}
1428
1429/*
1430 * A fixer for WaitForMultipleObjects on condition that there are more than 64
1431 * handles to wait on.
1432 *
1433 * In cetain cases DDMS may establish more than 64 connections with ADB. For
1434 * instance, this may happen if there are more than 64 processes running on a
1435 * device, or there are multiple devices connected (including the emulator) with
1436 * the combined number of running processes greater than 64. In this case using
1437 * WaitForMultipleObjects to wait on connection events simply wouldn't cut,
1438 * because of the API limitations (64 handles max). So, we need to provide a way
1439 * to scale WaitForMultipleObjects to accept an arbitrary number of handles. The
1440 * easiest (and "Microsoft recommended") way to do that would be dividing the
1441 * handle array into chunks with the chunk size less than 64, and fire up as many
1442 * waiting threads as there are chunks. Then each thread would wait on a chunk of
1443 * handles, and will report back to the caller which handle has been set.
1444 * Here is the implementation of that algorithm.
1445 */
1446
1447/* Number of handles to wait on in each wating thread. */
1448#define WAIT_ALL_CHUNK_SIZE 63
1449
1450/* Descriptor for a wating thread */
1451typedef struct WaitForAllParam {
1452    /* A handle to an event to signal when waiting is over. This handle is shared
1453     * accross all the waiting threads, so each waiting thread knows when any
1454     * other thread has exited, so it can exit too. */
1455    HANDLE          main_event;
1456    /* Upon exit from a waiting thread contains the index of the handle that has
1457     * been signaled. The index is an absolute index of the signaled handle in
1458     * the original array. This pointer is shared accross all the waiting threads
1459     * and it's not guaranteed (due to a race condition) that when all the
1460     * waiting threads exit, the value contained here would indicate the first
1461     * handle that was signaled. This is fine, because the caller cares only
1462     * about any handle being signaled. It doesn't care about the order, nor
1463     * about the whole list of handles that were signaled. */
1464    LONG volatile   *signaled_index;
1465    /* Array of handles to wait on in a waiting thread. */
1466    HANDLE*         handles;
1467    /* Number of handles in 'handles' array to wait on. */
1468    int             handles_count;
1469    /* Index inside the main array of the first handle in the 'handles' array. */
1470    int             first_handle_index;
1471    /* Waiting thread handle. */
1472    HANDLE          thread;
1473} WaitForAllParam;
1474
1475/* Waiting thread routine. */
1476static unsigned __stdcall
1477_in_waiter_thread(void*  arg)
1478{
1479    HANDLE wait_on[WAIT_ALL_CHUNK_SIZE + 1];
1480    int res;
1481    WaitForAllParam* const param = (WaitForAllParam*)arg;
1482
1483    /* We have to wait on the main_event in order to be notified when any of the
1484     * sibling threads is exiting. */
1485    wait_on[0] = param->main_event;
1486    /* The rest of the handles go behind the main event handle. */
1487    memcpy(wait_on + 1, param->handles, param->handles_count * sizeof(HANDLE));
1488
1489    res = WaitForMultipleObjects(param->handles_count + 1, wait_on, FALSE, INFINITE);
1490    if (res > 0 && res < (param->handles_count + 1)) {
1491        /* One of the original handles got signaled. Save its absolute index into
1492         * the output variable. */
1493        InterlockedCompareExchange(param->signaled_index,
1494                                   res - 1L + param->first_handle_index, -1L);
1495    }
1496
1497    /* Notify the caller (and the siblings) that the wait is over. */
1498    SetEvent(param->main_event);
1499
1500    _endthreadex(0);
1501    return 0;
1502}
1503
1504/* WaitForMultipeObjects fixer routine.
1505 * Param:
1506 *  handles Array of handles to wait on.
1507 *  handles_count Number of handles in the array.
1508 * Return:
1509 *  (>= 0 && < handles_count) - Index of the signaled handle in the array, or
1510 *  WAIT_FAILED on an error.
1511 */
1512static int
1513_wait_for_all(HANDLE* handles, int handles_count)
1514{
1515    WaitForAllParam* threads;
1516    HANDLE main_event;
1517    int chunks, chunk, remains;
1518
1519    /* This variable is going to be accessed by several threads at the same time,
1520     * this is bound to fail randomly when the core is run on multi-core machines.
1521     * To solve this, we need to do the following (1 _and_ 2):
1522     * 1. Use the "volatile" qualifier to ensure the compiler doesn't optimize
1523     *    out the reads/writes in this function unexpectedly.
1524     * 2. Ensure correct memory ordering. The "simple" way to do that is to wrap
1525     *    all accesses inside a critical section. But we can also use
1526     *    InterlockedCompareExchange() which always provide a full memory barrier
1527     *    on Win32.
1528     */
1529    volatile LONG sig_index = -1;
1530
1531    /* Calculate number of chunks, and allocate thread param array. */
1532    chunks = handles_count / WAIT_ALL_CHUNK_SIZE;
1533    remains = handles_count % WAIT_ALL_CHUNK_SIZE;
1534    threads = (WaitForAllParam*)malloc((chunks + (remains ? 1 : 0)) *
1535                                        sizeof(WaitForAllParam));
1536    if (threads == NULL) {
1537        D("Unable to allocate thread array for %d handles.", handles_count);
1538        return (int)WAIT_FAILED;
1539    }
1540
1541    /* Create main event to wait on for all waiting threads. This is a "manualy
1542     * reset" event that will remain set once it was set. */
1543    main_event = CreateEvent(NULL, TRUE, FALSE, NULL);
1544    if (main_event == NULL) {
1545        D("Unable to create main event. Error: %d", GetLastError());
1546        free(threads);
1547        return (int)WAIT_FAILED;
1548    }
1549
1550    /*
1551     * Initialize waiting thread parameters.
1552     */
1553
1554    for (chunk = 0; chunk < chunks; chunk++) {
1555        threads[chunk].main_event = main_event;
1556        threads[chunk].signaled_index = &sig_index;
1557        threads[chunk].first_handle_index = WAIT_ALL_CHUNK_SIZE * chunk;
1558        threads[chunk].handles = handles + threads[chunk].first_handle_index;
1559        threads[chunk].handles_count = WAIT_ALL_CHUNK_SIZE;
1560    }
1561    if (remains) {
1562        threads[chunk].main_event = main_event;
1563        threads[chunk].signaled_index = &sig_index;
1564        threads[chunk].first_handle_index = WAIT_ALL_CHUNK_SIZE * chunk;
1565        threads[chunk].handles = handles + threads[chunk].first_handle_index;
1566        threads[chunk].handles_count = remains;
1567        chunks++;
1568    }
1569
1570    /* Start the waiting threads. */
1571    for (chunk = 0; chunk < chunks; chunk++) {
1572        /* Note that using adb_thread_create is not appropriate here, since we
1573         * need a handle to wait on for thread termination. */
1574        threads[chunk].thread = (HANDLE)_beginthreadex(NULL, 0, _in_waiter_thread,
1575                                                       &threads[chunk], 0, NULL);
1576        if (threads[chunk].thread == NULL) {
1577            /* Unable to create a waiter thread. Collapse. */
1578            D("Unable to create a waiting thread %d of %d. errno=%d",
1579              chunk, chunks, errno);
1580            chunks = chunk;
1581            SetEvent(main_event);
1582            break;
1583        }
1584    }
1585
1586    /* Wait on any of the threads to get signaled. */
1587    WaitForSingleObject(main_event, INFINITE);
1588
1589    /* Wait on all the waiting threads to exit. */
1590    for (chunk = 0; chunk < chunks; chunk++) {
1591        WaitForSingleObject(threads[chunk].thread, INFINITE);
1592        CloseHandle(threads[chunk].thread);
1593    }
1594
1595    CloseHandle(main_event);
1596    free(threads);
1597
1598
1599    const int ret = (int)InterlockedCompareExchange(&sig_index, -1, -1);
1600    return (ret >= 0) ? ret : (int)WAIT_FAILED;
1601}
1602
1603static EventLooperRec  win32_looper;
1604
1605static void fdevent_init(void)
1606{
1607    win32_looper.htab_count = 0;
1608    win32_looper.hooks      = NULL;
1609}
1610
1611static void fdevent_connect(fdevent *fde)
1612{
1613    EventLooper  looper = &win32_looper;
1614    int          events = fde->state & FDE_EVENTMASK;
1615
1616    if (events != 0)
1617        event_looper_hook( looper, fde->fd, events );
1618}
1619
1620static void fdevent_disconnect(fdevent *fde)
1621{
1622    EventLooper  looper = &win32_looper;
1623    int          events = fde->state & FDE_EVENTMASK;
1624
1625    if (events != 0)
1626        event_looper_unhook( looper, fde->fd, events );
1627}
1628
1629static void fdevent_update(fdevent *fde, unsigned events)
1630{
1631    EventLooper  looper  = &win32_looper;
1632    unsigned     events0 = fde->state & FDE_EVENTMASK;
1633
1634    if (events != events0) {
1635        int  removes = events0 & ~events;
1636        int  adds    = events  & ~events0;
1637        if (removes) {
1638            D("fdevent_update: remove %x from %d\n", removes, fde->fd);
1639            event_looper_unhook( looper, fde->fd, removes );
1640        }
1641        if (adds) {
1642            D("fdevent_update: add %x to %d\n", adds, fde->fd);
1643            event_looper_hook  ( looper, fde->fd, adds );
1644        }
1645    }
1646}
1647
1648static void fdevent_process()
1649{
1650    EventLooper  looper = &win32_looper;
1651    EventHook    hook;
1652    int          gotone = 0;
1653
1654    /* if we have at least one ready hook, execute it/them */
1655    for (hook = looper->hooks; hook; hook = hook->next) {
1656        hook->ready = 0;
1657        if (hook->prepare) {
1658            hook->prepare(hook);
1659            if (hook->ready != 0) {
1660                event_hook_signal( hook );
1661                gotone = 1;
1662            }
1663        }
1664    }
1665
1666    /* nothing's ready yet, so wait for something to happen */
1667    if (!gotone)
1668    {
1669        looper->htab_count = 0;
1670
1671        for (hook = looper->hooks; hook; hook = hook->next)
1672        {
1673            if (hook->start && !hook->start(hook)) {
1674                D( "fdevent_process: error when starting a hook\n" );
1675                return;
1676            }
1677            if (hook->h != INVALID_HANDLE_VALUE) {
1678                int  nn;
1679
1680                for (nn = 0; nn < looper->htab_count; nn++)
1681                {
1682                    if ( looper->htab[nn] == hook->h )
1683                        goto DontAdd;
1684                }
1685                looper->htab[ looper->htab_count++ ] = hook->h;
1686            DontAdd:
1687                ;
1688            }
1689        }
1690
1691        if (looper->htab_count == 0) {
1692            D( "fdevent_process: nothing to wait for !!\n" );
1693            return;
1694        }
1695
1696        do
1697        {
1698            int   wait_ret;
1699
1700            D( "adb_win32: waiting for %d events\n", looper->htab_count );
1701            if (looper->htab_count > MAXIMUM_WAIT_OBJECTS) {
1702                D("handle count %d exceeds MAXIMUM_WAIT_OBJECTS.\n", looper->htab_count);
1703                wait_ret = _wait_for_all(looper->htab, looper->htab_count);
1704            } else {
1705                wait_ret = WaitForMultipleObjects( looper->htab_count, looper->htab, FALSE, INFINITE );
1706            }
1707            if (wait_ret == (int)WAIT_FAILED) {
1708                D( "adb_win32: wait failed, error %ld\n", GetLastError() );
1709            } else {
1710                D( "adb_win32: got one (index %d)\n", wait_ret );
1711
1712                /* according to Cygwin, some objects like consoles wake up on "inappropriate" events
1713                 * like mouse movements. we need to filter these with the "check" function
1714                 */
1715                if ((unsigned)wait_ret < (unsigned)looper->htab_count)
1716                {
1717                    for (hook = looper->hooks; hook; hook = hook->next)
1718                    {
1719                        if ( looper->htab[wait_ret] == hook->h       &&
1720                         (!hook->check || hook->check(hook)) )
1721                        {
1722                            D( "adb_win32: signaling %s for %x\n", hook->fh->name, hook->ready );
1723                            event_hook_signal( hook );
1724                            gotone = 1;
1725                            break;
1726                        }
1727                    }
1728                }
1729            }
1730        }
1731        while (!gotone);
1732
1733        for (hook = looper->hooks; hook; hook = hook->next) {
1734            if (hook->stop)
1735                hook->stop( hook );
1736        }
1737    }
1738
1739    for (hook = looper->hooks; hook; hook = hook->next) {
1740        if (hook->peek && hook->peek(hook))
1741                event_hook_signal( hook );
1742    }
1743}
1744
1745
1746static void fdevent_register(fdevent *fde)
1747{
1748    int  fd = fde->fd - WIN32_FH_BASE;
1749
1750    if(fd < 0) {
1751        FATAL("bogus negative fd (%d)\n", fde->fd);
1752    }
1753
1754    if(fd >= fd_table_max) {
1755        int oldmax = fd_table_max;
1756        if(fde->fd > 32000) {
1757            FATAL("bogus huuuuge fd (%d)\n", fde->fd);
1758        }
1759        if(fd_table_max == 0) {
1760            fdevent_init();
1761            fd_table_max = 256;
1762        }
1763        while(fd_table_max <= fd) {
1764            fd_table_max *= 2;
1765        }
1766        fd_table = realloc(fd_table, sizeof(fdevent*) * fd_table_max);
1767        if(fd_table == 0) {
1768            FATAL("could not expand fd_table to %d entries\n", fd_table_max);
1769        }
1770        memset(fd_table + oldmax, 0, sizeof(int) * (fd_table_max - oldmax));
1771    }
1772
1773    fd_table[fd] = fde;
1774}
1775
1776static void fdevent_unregister(fdevent *fde)
1777{
1778    int  fd = fde->fd - WIN32_FH_BASE;
1779
1780    if((fd < 0) || (fd >= fd_table_max)) {
1781        FATAL("fd out of range (%d)\n", fde->fd);
1782    }
1783
1784    if(fd_table[fd] != fde) {
1785        FATAL("fd_table out of sync");
1786    }
1787
1788    fd_table[fd] = 0;
1789
1790    if(!(fde->state & FDE_DONT_CLOSE)) {
1791        dump_fde(fde, "close");
1792        adb_close(fde->fd);
1793    }
1794}
1795
1796static void fdevent_plist_enqueue(fdevent *node)
1797{
1798    fdevent *list = &list_pending;
1799
1800    node->next = list;
1801    node->prev = list->prev;
1802    node->prev->next = node;
1803    list->prev = node;
1804}
1805
1806static void fdevent_plist_remove(fdevent *node)
1807{
1808    node->prev->next = node->next;
1809    node->next->prev = node->prev;
1810    node->next = 0;
1811    node->prev = 0;
1812}
1813
1814static fdevent *fdevent_plist_dequeue(void)
1815{
1816    fdevent *list = &list_pending;
1817    fdevent *node = list->next;
1818
1819    if(node == list) return 0;
1820
1821    list->next = node->next;
1822    list->next->prev = list;
1823    node->next = 0;
1824    node->prev = 0;
1825
1826    return node;
1827}
1828
1829fdevent *fdevent_create(int fd, fd_func func, void *arg)
1830{
1831    fdevent *fde = (fdevent*) malloc(sizeof(fdevent));
1832    if(fde == 0) return 0;
1833    fdevent_install(fde, fd, func, arg);
1834    fde->state |= FDE_CREATED;
1835    return fde;
1836}
1837
1838void fdevent_destroy(fdevent *fde)
1839{
1840    if(fde == 0) return;
1841    if(!(fde->state & FDE_CREATED)) {
1842        FATAL("fde %p not created by fdevent_create()\n", fde);
1843    }
1844    fdevent_remove(fde);
1845}
1846
1847void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg)
1848{
1849    memset(fde, 0, sizeof(fdevent));
1850    fde->state = FDE_ACTIVE;
1851    fde->fd = fd;
1852    fde->func = func;
1853    fde->arg = arg;
1854
1855    fdevent_register(fde);
1856    dump_fde(fde, "connect");
1857    fdevent_connect(fde);
1858    fde->state |= FDE_ACTIVE;
1859}
1860
1861void fdevent_remove(fdevent *fde)
1862{
1863    if(fde->state & FDE_PENDING) {
1864        fdevent_plist_remove(fde);
1865    }
1866
1867    if(fde->state & FDE_ACTIVE) {
1868        fdevent_disconnect(fde);
1869        dump_fde(fde, "disconnect");
1870        fdevent_unregister(fde);
1871    }
1872
1873    fde->state = 0;
1874    fde->events = 0;
1875}
1876
1877
1878void fdevent_set(fdevent *fde, unsigned events)
1879{
1880    events &= FDE_EVENTMASK;
1881
1882    if((fde->state & FDE_EVENTMASK) == (int)events) return;
1883
1884    if(fde->state & FDE_ACTIVE) {
1885        fdevent_update(fde, events);
1886        dump_fde(fde, "update");
1887    }
1888
1889    fde->state = (fde->state & FDE_STATEMASK) | events;
1890
1891    if(fde->state & FDE_PENDING) {
1892            /* if we're pending, make sure
1893            ** we don't signal an event that
1894            ** is no longer wanted.
1895            */
1896        fde->events &= (~events);
1897        if(fde->events == 0) {
1898            fdevent_plist_remove(fde);
1899            fde->state &= (~FDE_PENDING);
1900        }
1901    }
1902}
1903
1904void fdevent_add(fdevent *fde, unsigned events)
1905{
1906    fdevent_set(
1907        fde, (fde->state & FDE_EVENTMASK) | (events & FDE_EVENTMASK));
1908}
1909
1910void fdevent_del(fdevent *fde, unsigned events)
1911{
1912    fdevent_set(
1913        fde, (fde->state & FDE_EVENTMASK) & (~(events & FDE_EVENTMASK)));
1914}
1915
1916void fdevent_loop()
1917{
1918    fdevent *fde;
1919
1920    for(;;) {
1921#if DEBUG
1922        fprintf(stderr,"--- ---- waiting for events\n");
1923#endif
1924        fdevent_process();
1925
1926        while((fde = fdevent_plist_dequeue())) {
1927            unsigned events = fde->events;
1928            fde->events = 0;
1929            fde->state &= (~FDE_PENDING);
1930            dump_fde(fde, "callback");
1931            fde->func(fde->fd, events, fde->arg);
1932        }
1933    }
1934}
1935
1936/**  FILE EVENT HOOKS
1937 **/
1938
1939static void  _event_file_prepare( EventHook  hook )
1940{
1941    if (hook->wanted & (FDE_READ|FDE_WRITE)) {
1942        /* we can always read/write */
1943        hook->ready |= hook->wanted & (FDE_READ|FDE_WRITE);
1944    }
1945}
1946
1947static int  _event_file_peek( EventHook  hook )
1948{
1949    return (hook->wanted & (FDE_READ|FDE_WRITE));
1950}
1951
1952static void  _fh_file_hook( FH  f, int  events, EventHook  hook )
1953{
1954    hook->h       = f->fh_handle;
1955    hook->prepare = _event_file_prepare;
1956    hook->peek    = _event_file_peek;
1957}
1958
1959/** SOCKET EVENT HOOKS
1960 **/
1961
1962static void  _event_socket_verify( EventHook  hook, WSANETWORKEVENTS*  evts )
1963{
1964    if ( evts->lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE) ) {
1965        if (hook->wanted & FDE_READ)
1966            hook->ready |= FDE_READ;
1967        if ((evts->iErrorCode[FD_READ] != 0) && hook->wanted & FDE_ERROR)
1968            hook->ready |= FDE_ERROR;
1969    }
1970    if ( evts->lNetworkEvents & (FD_WRITE|FD_CONNECT|FD_CLOSE) ) {
1971        if (hook->wanted & FDE_WRITE)
1972            hook->ready |= FDE_WRITE;
1973        if ((evts->iErrorCode[FD_WRITE] != 0) && hook->wanted & FDE_ERROR)
1974            hook->ready |= FDE_ERROR;
1975    }
1976    if ( evts->lNetworkEvents & FD_OOB ) {
1977        if (hook->wanted & FDE_ERROR)
1978            hook->ready |= FDE_ERROR;
1979    }
1980}
1981
1982static void  _event_socket_prepare( EventHook  hook )
1983{
1984    WSANETWORKEVENTS  evts;
1985
1986    /* look if some of the events we want already happened ? */
1987    if (!WSAEnumNetworkEvents( hook->fh->fh_socket, NULL, &evts ))
1988        _event_socket_verify( hook, &evts );
1989}
1990
1991static int  _socket_wanted_to_flags( int  wanted )
1992{
1993    int  flags = 0;
1994    if (wanted & FDE_READ)
1995        flags |= FD_READ | FD_ACCEPT | FD_CLOSE;
1996
1997    if (wanted & FDE_WRITE)
1998        flags |= FD_WRITE | FD_CONNECT | FD_CLOSE;
1999
2000    if (wanted & FDE_ERROR)
2001        flags |= FD_OOB;
2002
2003    return flags;
2004}
2005
2006static int _event_socket_start( EventHook  hook )
2007{
2008    /* create an event which we're going to wait for */
2009    FH    fh    = hook->fh;
2010    long  flags = _socket_wanted_to_flags( hook->wanted );
2011
2012    hook->h = fh->event;
2013    if (hook->h == INVALID_HANDLE_VALUE) {
2014        D( "_event_socket_start: no event for %s\n", fh->name );
2015        return 0;
2016    }
2017
2018    if ( flags != fh->mask ) {
2019        D( "_event_socket_start: hooking %s for %x (flags %ld)\n", hook->fh->name, hook->wanted, flags );
2020        if ( WSAEventSelect( fh->fh_socket, hook->h, flags ) ) {
2021            D( "_event_socket_start: WSAEventSelect() for %s failed, error %d\n", hook->fh->name, WSAGetLastError() );
2022            CloseHandle( hook->h );
2023            hook->h = INVALID_HANDLE_VALUE;
2024            exit(1);
2025            return 0;
2026        }
2027        fh->mask = flags;
2028    }
2029    return 1;
2030}
2031
2032static void _event_socket_stop( EventHook  hook )
2033{
2034    hook->h = INVALID_HANDLE_VALUE;
2035}
2036
2037static int  _event_socket_check( EventHook  hook )
2038{
2039    int               result = 0;
2040    FH                fh = hook->fh;
2041    WSANETWORKEVENTS  evts;
2042
2043    if (!WSAEnumNetworkEvents( fh->fh_socket, hook->h, &evts ) ) {
2044        _event_socket_verify( hook, &evts );
2045        result = (hook->ready != 0);
2046        if (result) {
2047            ResetEvent( hook->h );
2048        }
2049    }
2050    D( "_event_socket_check %s returns %d\n", fh->name, result );
2051    return  result;
2052}
2053
2054static int  _event_socket_peek( EventHook  hook )
2055{
2056    WSANETWORKEVENTS  evts;
2057    FH                fh = hook->fh;
2058
2059    /* look if some of the events we want already happened ? */
2060    if (!WSAEnumNetworkEvents( fh->fh_socket, NULL, &evts )) {
2061        _event_socket_verify( hook, &evts );
2062        if (hook->ready)
2063            ResetEvent( hook->h );
2064    }
2065
2066    return hook->ready != 0;
2067}
2068
2069
2070
2071static void  _fh_socket_hook( FH  f, int  events, EventHook  hook )
2072{
2073    hook->prepare = _event_socket_prepare;
2074    hook->start   = _event_socket_start;
2075    hook->stop    = _event_socket_stop;
2076    hook->check   = _event_socket_check;
2077    hook->peek    = _event_socket_peek;
2078
2079    _event_socket_start( hook );
2080}
2081
2082/** SOCKETPAIR EVENT HOOKS
2083 **/
2084
2085static void  _event_socketpair_prepare( EventHook  hook )
2086{
2087    FH          fh   = hook->fh;
2088    SocketPair  pair = fh->fh_pair;
2089    BipBuffer   rbip = (pair->a_fd == fh) ? &pair->b2a_bip : &pair->a2b_bip;
2090    BipBuffer   wbip = (pair->a_fd == fh) ? &pair->a2b_bip : &pair->b2a_bip;
2091
2092    if (hook->wanted & FDE_READ && rbip->can_read)
2093        hook->ready |= FDE_READ;
2094
2095    if (hook->wanted & FDE_WRITE && wbip->can_write)
2096        hook->ready |= FDE_WRITE;
2097 }
2098
2099 static int  _event_socketpair_start( EventHook  hook )
2100 {
2101    FH          fh   = hook->fh;
2102    SocketPair  pair = fh->fh_pair;
2103    BipBuffer   rbip = (pair->a_fd == fh) ? &pair->b2a_bip : &pair->a2b_bip;
2104    BipBuffer   wbip = (pair->a_fd == fh) ? &pair->a2b_bip : &pair->b2a_bip;
2105
2106    if (hook->wanted == FDE_READ)
2107        hook->h = rbip->evt_read;
2108
2109    else if (hook->wanted == FDE_WRITE)
2110        hook->h = wbip->evt_write;
2111
2112    else {
2113        D("_event_socketpair_start: can't handle FDE_READ+FDE_WRITE\n" );
2114        return 0;
2115    }
2116    D( "_event_socketpair_start: hook %s for %x wanted=%x\n",
2117       hook->fh->name, _fh_to_int(fh), hook->wanted);
2118    return 1;
2119}
2120
2121static int  _event_socketpair_peek( EventHook  hook )
2122{
2123    _event_socketpair_prepare( hook );
2124    return hook->ready != 0;
2125}
2126
2127static void  _fh_socketpair_hook( FH  fh, int  events, EventHook  hook )
2128{
2129    hook->prepare = _event_socketpair_prepare;
2130    hook->start   = _event_socketpair_start;
2131    hook->peek    = _event_socketpair_peek;
2132}
2133
2134
2135void
2136adb_sysdeps_init( void )
2137{
2138#define  ADB_MUTEX(x)  InitializeCriticalSection( & x );
2139#include "mutex_list.h"
2140    InitializeCriticalSection( &_win32_lock );
2141}
2142
2143/* Windows doesn't have strtok_r.  Use the one from bionic. */
2144
2145/*
2146 * Copyright (c) 1988 Regents of the University of California.
2147 * All rights reserved.
2148 *
2149 * Redistribution and use in source and binary forms, with or without
2150 * modification, are permitted provided that the following conditions
2151 * are met:
2152 * 1. Redistributions of source code must retain the above copyright
2153 *    notice, this list of conditions and the following disclaimer.
2154 * 2. Redistributions in binary form must reproduce the above copyright
2155 *    notice, this list of conditions and the following disclaimer in the
2156 *    documentation and/or other materials provided with the distribution.
2157 * 3. Neither the name of the University nor the names of its contributors
2158 *    may be used to endorse or promote products derived from this software
2159 *    without specific prior written permission.
2160 *
2161 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2162 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2163 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2164 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2165 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2166 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2167 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2168 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2169 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2170 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2171 * SUCH DAMAGE.
2172 */
2173
2174char *
2175adb_strtok_r(char *s, const char *delim, char **last)
2176{
2177	char *spanp;
2178	int c, sc;
2179	char *tok;
2180
2181
2182	if (s == NULL && (s = *last) == NULL)
2183		return (NULL);
2184
2185	/*
2186	 * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
2187	 */
2188cont:
2189	c = *s++;
2190	for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
2191		if (c == sc)
2192			goto cont;
2193	}
2194
2195	if (c == 0) {		/* no non-delimiter characters */
2196		*last = NULL;
2197		return (NULL);
2198	}
2199	tok = s - 1;
2200
2201	/*
2202	 * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
2203	 * Note that delim must have one NUL; we stop if we see that, too.
2204	 */
2205	for (;;) {
2206		c = *s++;
2207		spanp = (char *)delim;
2208		do {
2209			if ((sc = *spanp++) == c) {
2210				if (c == 0)
2211					s = NULL;
2212				else
2213					s[-1] = 0;
2214				*last = s;
2215				return (tok);
2216			}
2217		} while (sc != 0);
2218	}
2219	/* NOTREACHED */
2220}
2221