📄 async.c
字号:
/* Async WINSOCK DNS services * * Copyright (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka. * Copyright (C) 1999 Marcus Meissner * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * NOTE: If you make any changes to fix a particular app, make sure * they don't break something else like Netscape or telnet and ftp * clients and servers (www.winsite.com got a lot of those). * * FIXME: * - Add WSACancel* and correct handle management. (works rather well for * now without it.) * - Verify & Check all calls for correctness * (currently only WSAGetHostByName*, WSAGetServByPort* calls) * - Check error returns. * - mirc/mirc32 Finger @linux.kernel.org sometimes fails in threaded mode. * (not sure why) * - This implementation did ignore the "NOTE:" section above (since the * whole stuff did not work anyway to other changes). */#include <windows.h>#include <winsock.h>#define WS_FD_SETSIZE FD_SETSIZE#define HAVE_GETPROTOBYNAME#define HAVE_GETPROTOBYNUMBER#define HAVE_GETSERVBYPORTtypedef struct hostent WS_hostent;typedef struct servent WS_servent;typedef struct protoent WS_protoent;#include "wine/config.h"#include "wine/port.h"#ifndef __REACTOS__#include <stdarg.h>#include <string.h>#include <sys/types.h>#ifdef HAVE_SYS_IPC_H# include <sys/ipc.h>#endif#ifdef HAVE_SYS_IOCTL_H# include <sys/ioctl.h>#endif#ifdef HAVE_SYS_FILIO_H# include <sys/filio.h>#endif#if defined(__svr4__)#include <sys/ioccom.h>#ifdef HAVE_SYS_SOCKIO_H# include <sys/sockio.h>#endif#endif#if defined(__EMX__)# include <sys/so_ioctl.h>#endif#ifdef HAVE_SYS_PARAM_H# include <sys/param.h>#endif#ifdef HAVE_SYS_MSG_H# include <sys/msg.h>#endif#ifdef HAVE_SYS_WAIT_H#include <sys/wait.h>#endif#ifdef HAVE_SYS_SOCKET_H#include <sys/socket.h>#endif#ifdef HAVE_NETINET_IN_H# include <netinet/in.h>#endif#ifdef HAVE_ARPA_INET_H# include <arpa/inet.h>#endif#include <ctype.h>#include <fcntl.h>#include <errno.h>#ifdef HAVE_SYS_ERRNO_H#include <sys/errno.h>#endif#ifdef HAVE_NETDB_H#include <netdb.h>#endif#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#include <stdlib.h>#ifdef HAVE_ARPA_NAMESER_H# include <arpa/nameser.h>#endif#ifdef HAVE_RESOLV_H# include <resolv.h>#endif#endif#define CALLBACK __stdcall#include "wine/winbase16.h"#include "windef.h"#include "winbase.h"#include "wingdi.h"#include "winuser.h"#include "winsock2.h"#include "ws2spi.h"#include "wownt32.h"#include "wine/winsock16.h"#include "winnt.h"#include "wine/debug.h"WINE_DEFAULT_DEBUG_CHANNEL(winsock);/* protoptypes of some functions in socket.c */#define AQ_WIN16 0x00#define AQ_WIN32 0x04#define HB_WIN32(hb) (hb->flags & AQ_WIN32)#define AQ_NUMBER 0x00#define AQ_NAME 0x08#define AQ_COPYPTR1 0x10#define AQ_DUPLOWPTR1 0x20#define AQ_MASKPTR1 0x30#define AQ_COPYPTR2 0x40#define AQ_DUPLOWPTR2 0x80#define AQ_MASKPTR2 0xC0#define AQ_GETHOST 0#define AQ_GETPROTO 1#define AQ_GETSERV 2#define AQ_GETMASK 3/* The handles used are pseudo-handles that can be simply casted. *//* 16-bit values are used internally (to be sure handle comparison works right in 16-bit apps). */#define WSA_H32(h16) ((HANDLE)(ULONG_PTR)(h16))/* ----------------------------------- helper functions - */static int list_size(char** l, int item_size){ int i,j = 0; if(l) { for(i=0;l[i];i++) j += (item_size) ? item_size : strlen(l[i]) + 1; j += (i + 1) * sizeof(char*); } return j;}static int list_dup(char** l_src, char* ref, char* base, int item_size){ /* base is either either equal to ref or 0 or SEGPTR */ char* p = ref; char** l_to = (char**)ref; int i,j,k; for(j=0;l_src[j];j++) ; p += (j + 1) * sizeof(char*); for(i=0;i<j;i++) { l_to[i] = base + (p - ref); k = ( item_size ) ? item_size : strlen(l_src[i]) + 1; memcpy(p, l_src[i], k); p += k; } l_to[i] = NULL; return (p - ref);}/* ----- hostent */static int hostent_size(struct hostent* p_he){ int size = 0; if( p_he ) { size = sizeof(struct hostent); size += strlen(p_he->h_name) + 1; size += list_size(p_he->h_aliases, 0); size += list_size(p_he->h_addr_list, p_he->h_length ); } return size;}/* Copy hostent to p_to, fix up inside pointers using p_base (different for * Win16 (linear vs. segmented). Return -neededsize on overrun. */static int WS_copy_he(char *p_to,char *p_base,int t_size,struct hostent* p_he, int flag){ char* p_name,*p_aliases,*p_addr,*p; struct ws_hostent16 *p_to16 = (struct ws_hostent16*)p_to; WS_hostent *p_to32 = (WS_hostent*)p_to; int size = hostent_size(p_he) + ( (flag & AQ_WIN16) ? sizeof(struct ws_hostent16) : sizeof(WS_hostent) - sizeof(struct hostent) ); if (t_size < size) return -size; p = p_to; p += (flag & AQ_WIN16) ? sizeof(struct ws_hostent16) : sizeof(WS_hostent); p_name = p; strcpy(p, p_he->h_name); p += strlen(p) + 1; p_aliases = p; p += list_dup(p_he->h_aliases, p, p_base + (p - (char*)p_to), 0); p_addr = p; list_dup(p_he->h_addr_list, p, p_base + (p - (char*)p_to), p_he->h_length); if (flag & AQ_WIN16) { p_to16->h_addrtype = (INT16)p_he->h_addrtype; p_to16->h_length = (INT16)p_he->h_length; p_to16->h_name = (SEGPTR)(p_base + (p_name - p_to)); p_to16->h_aliases = (SEGPTR)(p_base + (p_aliases - p_to)); p_to16->h_addr_list = (SEGPTR)(p_base + (p_addr - p_to)); } else { p_to32->h_addrtype = p_he->h_addrtype; p_to32->h_length = p_he->h_length; p_to32->h_name = (p_base + (p_name - p_to)); p_to32->h_aliases = (char **)(p_base + (p_aliases - p_to)); p_to32->h_addr_list = (char **)(p_base + (p_addr - p_to)); } return size;}/* ----- protoent */static int protoent_size(struct protoent* p_pe){ int size = 0; if( p_pe ) { size = sizeof(struct protoent); size += strlen(p_pe->p_name) + 1; size += list_size(p_pe->p_aliases, 0); } return size;}/* Copy protoent to p_to, fix up inside pointers using p_base (different for * Win16 (linear vs. segmented). Return -neededsize on overrun. */static int WS_copy_pe(char *p_to,char *p_base,int t_size,struct protoent* p_pe, int flag){ char* p_name,*p_aliases,*p; struct ws_protoent16 *p_to16 = (struct ws_protoent16*)p_to; WS_protoent *p_to32 = (WS_protoent*)p_to; int size = protoent_size(p_pe) + ( (flag & AQ_WIN16) ? sizeof(struct ws_protoent16) : sizeof(WS_protoent) - sizeof(struct protoent) ); if (t_size < size) return -size; p = p_to; p += (flag & AQ_WIN16) ? sizeof(struct ws_protoent16) : sizeof(WS_protoent); p_name = p; strcpy(p, p_pe->p_name); p += strlen(p) + 1; p_aliases = p; list_dup(p_pe->p_aliases, p, p_base + (p - (char*)p_to), 0); if (flag & AQ_WIN16) { p_to16->p_proto = (INT16)p_pe->p_proto; p_to16->p_name = (SEGPTR)(p_base) + (p_name - p_to); p_to16->p_aliases = (SEGPTR)((p_base) + (p_aliases - p_to)); } else { p_to32->p_proto = p_pe->p_proto; p_to32->p_name = (p_base) + (p_name - p_to); p_to32->p_aliases = (char **)((p_base) + (p_aliases - p_to)); } return size;}/* ----- servent */static int servent_size(struct servent* p_se){ int size = 0; if( p_se ) { size += sizeof(struct servent); size += strlen(p_se->s_proto) + strlen(p_se->s_name) + 2; size += list_size(p_se->s_aliases, 0); } return size;}/* Copy servent to p_to, fix up inside pointers using p_base (different for * Win16 (linear vs. segmented). Return -neededsize on overrun. * Take care of different Win16/Win32 servent structs (packing !) */static int WS_copy_se(char *p_to,char *p_base,int t_size,struct servent* p_se, int flag){ char* p_name,*p_aliases,*p_proto,*p; struct ws_servent16 *p_to16 = (struct ws_servent16*)p_to; WS_servent *p_to32 = (WS_servent*)p_to; int size = servent_size(p_se) + ( (flag & AQ_WIN16) ? sizeof(struct ws_servent16) : sizeof(WS_servent) - sizeof(struct servent) ); if (t_size < size) return -size; p = p_to; p += (flag & AQ_WIN16) ? sizeof(struct ws_servent16) : sizeof(WS_servent); p_name = p; strcpy(p, p_se->s_name); p += strlen(p) + 1; p_proto = p; strcpy(p, p_se->s_proto); p += strlen(p) + 1; p_aliases = p; list_dup(p_se->s_aliases, p, p_base + (p - p_to), 0); if (flag & AQ_WIN16) { p_to16->s_port = (INT16)p_se->s_port; p_to16->s_name = (SEGPTR)(p_base + (p_name - p_to)); p_to16->s_proto = (SEGPTR)(p_base + (p_proto - p_to)); p_to16->s_aliases = (SEGPTR)(p_base + (p_aliases - p_to)); } else { p_to32->s_port = p_se->s_port; p_to32->s_name = (p_base + (p_name - p_to)); p_to32->s_proto = (p_base + (p_proto - p_to)); p_to32->s_aliases = (char **)(p_base + (p_aliases - p_to)); } return size;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -