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 + -
显示快捷键?