sysdeps_win32.c

来自「Android 一些工具」· C语言 代码 · 共 1,954 行 · 第 1/4 页

C
1,954
字号
#include "sysdeps.h"#include <windows.h>#include <winsock2.h>#include <stdio.h>#include <errno.h>#define  TRACE_TAG  TRACE_SYSDEPS#include "adb.h"extern void fatal(const char *fmt, ...);#define assert(cond)  do { if (!(cond)) fatal( "assertion failed '%s' on %s:%ld\n", #cond, __FILE__, __LINE__ ); } while (0)/**************************************************************************//**************************************************************************//*****                                                                *****//*****      replaces libs/cutils/load_file.c                          *****//*****                                                                *****//**************************************************************************//**************************************************************************/void *load_file(const char *fn, unsigned *_sz){    HANDLE    file;    char     *data;    DWORD     file_size;    file = CreateFile( fn,                       GENERIC_READ,                       FILE_SHARE_READ,                       NULL,                       OPEN_EXISTING,                       0,                       NULL );    if (file == INVALID_HANDLE_VALUE)        return NULL;    file_size = GetFileSize( file, NULL );    data      = NULL;    if (file_size > 0) {        data = (char*) malloc( file_size + 1 );        if (data == NULL) {            D("load_file: could not allocate %ld bytes\n", file_size );            file_size = 0;        } else {            DWORD  out_bytes;            if ( !ReadFile( file, data, file_size, &out_bytes, NULL ) ||                 out_bytes != file_size )            {                D("load_file: could not read %ld bytes from '%s'\n", file_size, fn);                free(data);                data      = NULL;                file_size = 0;            }        }    }    CloseHandle( file );    *_sz = (unsigned) file_size;    return  data;}/**************************************************************************//**************************************************************************//*****                                                                *****//*****    common file descriptor handling                             *****//*****                                                                *****//**************************************************************************//**************************************************************************/typedef const struct FHClassRec_*   FHClass;typedef struct FHRec_*          FH;typedef struct EventHookRec_*  EventHook;typedef struct FHClassRec_{    void (*_fh_init) ( FH  f );    int  (*_fh_close)( FH  f );    int  (*_fh_lseek)( FH  f, int  pos, int  origin );    int  (*_fh_read) ( FH  f, void*  buf, int  len );    int  (*_fh_write)( FH  f, const void*  buf, int  len );    void (*_fh_hook) ( FH  f, int  events, EventHook  hook );} FHClassRec;/* used to emulate unix-domain socket pairs */typedef struct SocketPairRec_*  SocketPair;typedef struct FHRec_{    FHClass    clazz;    int        used;    int        eof;    union {        HANDLE      handle;        SOCKET      socket;        SocketPair  pair;    } u;    HANDLE    event;    int       mask;    char  name[32];} FHRec;#define  fh_handle  u.handle#define  fh_socket  u.socket#define  fh_pair    u.pair#define  WIN32_FH_BASE    100#define  WIN32_MAX_FHS    128static 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_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;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?