diff --git a/dlls/winsock/async.c b/dlls/winsock/async.c index f7f32926adf..7e905289811 100644 --- a/dlls/winsock/async.c +++ b/dlls/winsock/async.c @@ -17,8 +17,6 @@ * (not sure why) * - This implementation did ignore the "NOTE:" section above (since the * whole stuff did not work anyway to other changes). - * - (Rein Klazes) Some structures returned (eg servent) are NOT correct in - * win32. The packing should be at 4 byte bounds. Same problem in socket.c */ #include "config.h" @@ -81,7 +79,8 @@ #include "wine/winbase16.h" #include "wingdi.h" #include "winuser.h" -#include "winsock.h" +#include "winsock2.h" +#include "wine/winsock16.h" #include "winnt.h" #include "heap.h" #include "task.h" @@ -97,6 +96,23 @@ DEFAULT_DEBUG_CHANNEL(winsock) UINT16 wsaErrno(void); UINT16 wsaHerrno(void); +#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 + /* ----------------------------------- helper functions - */ static int list_size(char** l, int item_size) @@ -143,15 +159,22 @@ static int hostent_size(struct hostent* p_he) /* 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(struct ws_hostent *p_to,char *p_base,int t_size,struct hostent* p_he) +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; - int size=hostent_size(p_he)+(sizeof(struct ws_hostent)-sizeof(struct hostent)); + struct ws_hostent16 *p_to16 = (struct ws_hostent16*)p_to; + struct ws_hostent32 *p_to32 = (struct ws_hostent32*)p_to; + int size = hostent_size(p_he) + + ( + (flag & AQ_WIN16) ? sizeof(struct ws_hostent16) : sizeof(struct ws_hostent32) + - sizeof(struct hostent) + ); if (t_size < size) return -size; - p = (char*)p_to; - p += sizeof(struct ws_hostent); + p = p_to; + p += (flag & AQ_WIN16) ? + sizeof(struct ws_hostent16) : sizeof(struct ws_hostent32); p_name = p; strcpy(p, p_he->h_name); p += strlen(p) + 1; p_aliases = p; @@ -159,11 +182,22 @@ static int WS_copy_he(struct ws_hostent *p_to,char *p_base,int t_size,struct hos p_addr = p; list_dup(p_he->h_addr_list, p, p_base + (p - (char*)p_to), p_he->h_length); - p_to->h_addrtype = (INT16)p_he->h_addrtype; - p_to->h_length = (INT16)p_he->h_length; - p_to->h_name = (SEGPTR)(p_base + (p_name - (char*)p_to)); - p_to->h_aliases = (SEGPTR)(p_base + (p_aliases - (char*)p_to)); - p_to->h_addr_list = (SEGPTR)(p_base + (p_addr - (char*)p_to)); + 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; } @@ -183,24 +217,39 @@ static int protoent_size(struct protoent* p_pe) /* 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(struct ws_protoent *p_to,char *p_base,int t_size,struct protoent* p_pe) +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; - int size=protoent_size(p_pe)+(sizeof(struct ws_protoent)-sizeof(struct protoent)); + struct ws_protoent16 *p_to16 = (struct ws_protoent16*)p_to; + struct ws_protoent32 *p_to32 = (struct ws_protoent32*)p_to; + int size = protoent_size(p_pe) + + ( + (flag & AQ_WIN16) ? sizeof(struct ws_protoent16) : sizeof(struct ws_protoent32) + - sizeof(struct protoent) + ); if (t_size < size) return -size; - p = (char*)p_to; - p += sizeof(struct ws_protoent); + p = p_to; + p += (flag & AQ_WIN16) ? + sizeof(struct ws_protoent16) : sizeof(struct ws_protoent32); 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); - p_to->p_proto = (INT16)p_pe->p_proto; - p_to->p_name = (SEGPTR)(p_base) + (p_name - (char*)p_to); - p_to->p_aliases = (SEGPTR)((p_base) + (p_aliases - (char*)p_to)); - + 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; } @@ -220,27 +269,45 @@ static int servent_size(struct servent* p_se) /* 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(struct ws_servent *p_to,char *p_base,int t_size,struct servent* p_se) +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; - int size = servent_size(p_se)+(sizeof(struct ws_servent)-sizeof(struct servent)); + struct ws_servent16 *p_to16 = (struct ws_servent16*)p_to; + struct ws_servent32 *p_to32 = (struct ws_servent32*)p_to; + int size = servent_size(p_se) + + ( + (flag & AQ_WIN16) ? sizeof(struct ws_servent16) : sizeof(struct ws_servent32) + - sizeof(struct servent) + ); - if (t_size < size ) + if (t_size < size) return -size; - p = (char*)p_to; - p += sizeof(struct ws_servent); + p = p_to; + p += (flag & AQ_WIN16) ? + sizeof(struct ws_servent16) : sizeof(struct ws_servent32); 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 - (char*)p_to), 0); + list_dup(p_se->s_aliases, p, p_base + (p - p_to), 0); - p_to->s_port = (INT16)p_se->s_port; - p_to->s_name = (SEGPTR)(p_base + (p_name - (char*)p_to)); - p_to->s_proto = (SEGPTR)(p_base + (p_proto - (char*)p_to)); - p_to->s_aliases = (SEGPTR)(p_base + (p_aliases - (char*)p_to)); + 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; } @@ -271,22 +338,6 @@ typedef struct _async_query { HANDLE16 async_handle; int flags; -#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 int qt; char xbuf[1]; } async_query; @@ -310,14 +361,14 @@ static DWORD WINAPI _async_queryfun(LPVOID arg) { switch (aq->flags & AQ_GETMASK) { case AQ_GETHOST: { - struct hostent *he; - struct ws_hostent *wshe = (struct ws_hostent*)targetptr; + struct hostent *he; + char *copy_hostent = targetptr; he = (aq->flags & AQ_NAME) ? gethostbyname(aq->host_name): gethostbyaddr(aq->host_addr,aq->host_len,aq->host_type); if (he) { - size = WS_copy_he(wshe,(char*)aq->sbuf,aq->sbuflen,he); + size = WS_copy_he(copy_hostent,(char*)aq->sbuf,aq->sbuflen,he,aq->flags); if (size < 0) { fail = WSAENOBUFS; size = -size; @@ -328,13 +379,13 @@ static DWORD WINAPI _async_queryfun(LPVOID arg) { } break; case AQ_GETPROTO: { - struct protoent *pe; - struct ws_protoent *wspe = (struct ws_protoent*)targetptr; + struct protoent *pe; + char *copy_protoent = targetptr; pe = (aq->flags & AQ_NAME)? getprotobyname(aq->proto_name) : getprotobynumber(aq->proto_number); if (pe) { - size = WS_copy_pe(wspe,(char*)aq->sbuf,aq->sbuflen,pe); + size = WS_copy_pe(copy_protoent,(char*)aq->sbuf,aq->sbuflen,pe,aq->flags); if (size < 0) { fail = WSAENOBUFS; size = -size; @@ -351,13 +402,13 @@ static DWORD WINAPI _async_queryfun(LPVOID arg) { } break; case AQ_GETSERV: { - struct servent *se; - struct ws_servent *wsse = (struct ws_servent*)targetptr; + struct servent *se; + char *copy_servent = targetptr; se = (aq->flags & AQ_NAME)? getservbyname(aq->serv_name,aq->serv_proto) : getservbyport(aq->serv_port,aq->serv_proto); if (se) { - size = WS_copy_se(wsse,(char*)aq->sbuf,aq->sbuflen,se); + size = WS_copy_se(copy_servent,(char*)aq->sbuf,aq->sbuflen,se,aq->flags); if (size < 0) { fail = WSAENOBUFS; size = -size; diff --git a/dlls/winsock/socket.c b/dlls/winsock/socket.c index 4f90de04cf3..d70bce35c72 100644 --- a/dlls/winsock/socket.c +++ b/dlls/winsock/socket.c @@ -8,6 +8,11 @@ * they don't break something else like Netscape or telnet and ftp * clients and servers (www.winsite.com got a lot of those). * + * NOTE 2: Many winsock structs such as servent, hostent, protoent, ... + * are used with 1-byte alignment for Win16 programs and 4-byte alignment + * for Win32 programs in winsock.h. winsock2.h uses forced 4-byte alignment. + * So we have non-forced (just as MSDN) ws_XXXXent (winsock.h), 4-byte forced + * ws_XXXXent32 (winsock2.h) and 1-byte forced ws_XXXXent16 (winsock16.h). */ #include "config.h" @@ -74,6 +79,7 @@ #include "wingdi.h" #include "winuser.h" #include "winsock2.h" +#include "wine/winsock16.h" #include "winnt.h" #include "heap.h" #include "task.h" @@ -135,11 +141,11 @@ typedef struct _WSINFO INT16 last_free; /* entry in the socket table */ UINT16 buflen; char* buffer; /* allocated from SEGPTR heap */ - struct ws_hostent *he; + void *he; /* typecast for Win16/32 ws_hostent */ int helen; - struct ws_servent *se; + void *se; /* typecast for Win16/32 ws_servent */ int selen; - struct ws_protoent *pe; + void *pe; /* typecast for Win16/32 ws_protoent */ int pelen; char* dbuffer; /* buffer for dummies (32 bytes) */ @@ -153,6 +159,10 @@ int WS_dup_he(LPWSINFO pwsi, struct hostent* p_he, int flag); int WS_dup_pe(LPWSINFO pwsi, struct protoent* p_pe, int flag); int WS_dup_se(LPWSINFO pwsi, struct servent* p_se, int flag); +typedef void WIN_hostent; +typedef void WIN_protoent; +typedef void WIN_servent; + int WSAIOCTL_GetInterfaceCount(void); int WSAIOCTL_GetInterfaceName(int intNumber, char *intName); @@ -746,16 +756,16 @@ struct ws_hostent* _check_buffer_he(LPWSINFO pwsi, int size) if( pwsi->he && pwsi->helen >= size ) return pwsi->he; else SEGPTR_FREE(pwsi->he); - pwsi->he = (struct ws_hostent*)SEGPTR_ALLOC((pwsi->helen = size)); + pwsi->he = SEGPTR_ALLOC((pwsi->helen = size)); return pwsi->he; } -struct ws_servent* _check_buffer_se(LPWSINFO pwsi, int size) +void* _check_buffer_se(LPWSINFO pwsi, int size) { if( pwsi->se && pwsi->selen >= size ) return pwsi->se; else SEGPTR_FREE(pwsi->se); - pwsi->se = (struct ws_servent*)SEGPTR_ALLOC((pwsi->selen = size)); + pwsi->se = SEGPTR_ALLOC((pwsi->selen = size)); return pwsi->se; } @@ -764,7 +774,7 @@ struct ws_protoent* _check_buffer_pe(LPWSINFO pwsi, int size) if( pwsi->pe && pwsi->pelen >= size ) return pwsi->pe; else SEGPTR_FREE(pwsi->pe); - pwsi->pe = (struct ws_protoent*)SEGPTR_ALLOC((pwsi->pelen = size)); + pwsi->pe = SEGPTR_ALLOC((pwsi->pelen = size)); return pwsi->pe; } @@ -2236,7 +2246,7 @@ static char* NULL_STRING = "NULL"; /*********************************************************************** * gethostbyaddr() (WINSOCK.51)(WSOCK32.51) */ -static struct WIN_hostent* __ws_gethostbyaddr(const char *addr, int len, int type, int dup_flag) +static WIN_hostent* __ws_gethostbyaddr(const char *addr, int len, int type, int dup_flag) { LPWSINFO pwsi = WINSOCK_GetIData(); @@ -2245,7 +2255,7 @@ static struct WIN_hostent* __ws_gethostbyaddr(const char *addr, int len, int typ struct hostent* host; if( (host = gethostbyaddr(addr, len, type)) != NULL ) if( WS_dup_he(pwsi, host, dup_flag) ) - return (struct WIN_hostent*)(pwsi->he); + return (WIN_hostent*)(pwsi->he); else SetLastError(WSAENOBUFS); else @@ -2256,14 +2266,14 @@ static struct WIN_hostent* __ws_gethostbyaddr(const char *addr, int len, int typ SEGPTR WINAPI WINSOCK_gethostbyaddr16(const char *addr, INT16 len, INT16 type) { - struct WIN_hostent* retval; + WIN_hostent* retval; TRACE("ptr %08x, len %d, type %d\n", (unsigned) addr, len, type); retval = __ws_gethostbyaddr( addr, len, type, WS_DUP_SEGPTR ); return retval ? SEGPTR_GET(retval) : ((SEGPTR)NULL); } -struct WIN_hostent* WINAPI WSOCK32_gethostbyaddr(const char *addr, INT len, +WIN_hostent* WINAPI WSOCK32_gethostbyaddr(const char *addr, INT len, INT type) { TRACE("ptr %08x, len %d, type %d\n", @@ -2274,7 +2284,7 @@ struct WIN_hostent* WINAPI WSOCK32_gethostbyaddr(const char *addr, INT len, /*********************************************************************** * gethostbyname() (WINSOCK.52)(WSOCK32.52) */ -static struct WIN_hostent * __ws_gethostbyname(const char *name, int dup_flag) +static WIN_hostent * __ws_gethostbyname(const char *name, int dup_flag) { LPWSINFO pwsi = WINSOCK_GetIData(); @@ -2283,7 +2293,7 @@ static struct WIN_hostent * __ws_gethostbyname(const char *name, int dup_flag) struct hostent* host; if( (host = gethostbyname(name)) != NULL ) if( WS_dup_he(pwsi, host, dup_flag) ) - return (struct WIN_hostent*)(pwsi->he); + return (WIN_hostent*)(pwsi->he); else SetLastError(WSAENOBUFS); else SetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno()); } @@ -2292,13 +2302,13 @@ static struct WIN_hostent * __ws_gethostbyname(const char *name, int dup_flag) SEGPTR WINAPI WINSOCK_gethostbyname16(const char *name) { - struct WIN_hostent* retval; + WIN_hostent* retval; TRACE("%s\n", (name)?name:NULL_STRING); retval = __ws_gethostbyname( name, WS_DUP_SEGPTR ); return (retval)? SEGPTR_GET(retval) : ((SEGPTR)NULL) ; } -struct WIN_hostent* WINAPI WSOCK32_gethostbyname(const char* name) +WIN_hostent* WINAPI WSOCK32_gethostbyname(const char* name) { TRACE("%s\n", (name)?name:NULL_STRING); return __ws_gethostbyname( name, WS_DUP_LINEAR ); @@ -2308,7 +2318,7 @@ struct WIN_hostent* WINAPI WSOCK32_gethostbyname(const char* name) /*********************************************************************** * getprotobyname() (WINSOCK.53)(WSOCK32.53) */ -static struct WIN_protoent* __ws_getprotobyname(const char *name, int dup_flag) +static WIN_protoent* __ws_getprotobyname(const char *name, int dup_flag) { LPWSINFO pwsi = WINSOCK_GetIData(); @@ -2317,7 +2327,7 @@ static struct WIN_protoent* __ws_getprotobyname(const char *name, int dup_flag) struct protoent* proto; if( (proto = getprotobyname(name)) != NULL ) if( WS_dup_pe(pwsi, proto, dup_flag) ) - return (struct WIN_protoent*)(pwsi->pe); + return (WIN_protoent*)(pwsi->pe); else SetLastError(WSAENOBUFS); else { MESSAGE("protocol %s not found; You might want to add " @@ -2330,13 +2340,13 @@ static struct WIN_protoent* __ws_getprotobyname(const char *name, int dup_flag) SEGPTR WINAPI WINSOCK_getprotobyname16(const char *name) { - struct WIN_protoent* retval; + WIN_protoent* retval; TRACE("%s\n", (name)?name:NULL_STRING); retval = __ws_getprotobyname(name, WS_DUP_SEGPTR); return retval ? SEGPTR_GET(retval) : ((SEGPTR)NULL); } -struct WIN_protoent* WINAPI WSOCK32_getprotobyname(const char* name) +WIN_protoent* WINAPI WSOCK32_getprotobyname(const char* name) { TRACE("%s\n", (name)?name:NULL_STRING); return __ws_getprotobyname(name, WS_DUP_LINEAR); @@ -2346,7 +2356,7 @@ struct WIN_protoent* WINAPI WSOCK32_getprotobyname(const char* name) /*********************************************************************** * getprotobynumber() (WINSOCK.54)(WSOCK32.54) */ -static struct WIN_protoent* __ws_getprotobynumber(int number, int dup_flag) +static WIN_protoent* __ws_getprotobynumber(int number, int dup_flag) { LPWSINFO pwsi = WINSOCK_GetIData(); @@ -2355,7 +2365,7 @@ static struct WIN_protoent* __ws_getprotobynumber(int number, int dup_flag) struct protoent* proto; if( (proto = getprotobynumber(number)) != NULL ) if( WS_dup_pe(pwsi, proto, dup_flag) ) - return (struct WIN_protoent*)(pwsi->pe); + return (WIN_protoent*)(pwsi->pe); else SetLastError(WSAENOBUFS); else { MESSAGE("protocol number %d not found; You might want to add " @@ -2368,13 +2378,13 @@ static struct WIN_protoent* __ws_getprotobynumber(int number, int dup_flag) SEGPTR WINAPI WINSOCK_getprotobynumber16(INT16 number) { - struct WIN_protoent* retval; + WIN_protoent* retval; TRACE("%i\n", number); retval = __ws_getprotobynumber(number, WS_DUP_SEGPTR); return retval ? SEGPTR_GET(retval) : ((SEGPTR)NULL); } -struct WIN_protoent* WINAPI WSOCK32_getprotobynumber(INT number) +WIN_protoent* WINAPI WSOCK32_getprotobynumber(INT number) { TRACE("%i\n", number); return __ws_getprotobynumber(number, WS_DUP_LINEAR); @@ -2384,7 +2394,7 @@ struct WIN_protoent* WINAPI WSOCK32_getprotobynumber(INT number) /*********************************************************************** * getservbyname() (WINSOCK.55)(WSOCK32.55) */ -struct WIN_servent* __ws_getservbyname(const char *name, const char *proto, int dup_flag) +static WIN_servent* __ws_getservbyname(const char *name, const char *proto, int dup_flag) { LPWSINFO pwsi = WINSOCK_GetIData(); @@ -2398,7 +2408,7 @@ struct WIN_servent* __ws_getservbyname(const char *name, const char *proto, int proto ? (pwsi->buffer + i) : NULL); if( serv != NULL ) if( WS_dup_se(pwsi, serv, dup_flag) ) - return (struct WIN_servent*)(pwsi->se); + return (WIN_servent*)(pwsi->se); else SetLastError(WSAENOBUFS); else { MESSAGE("service %s protocol %s not found; You might want to add " @@ -2414,14 +2424,14 @@ struct WIN_servent* __ws_getservbyname(const char *name, const char *proto, int SEGPTR WINAPI WINSOCK_getservbyname16(const char *name, const char *proto) { - struct WIN_servent* retval; + WIN_servent* retval; TRACE("'%s', '%s'\n", (name)?name:NULL_STRING, (proto)?proto:NULL_STRING); retval = __ws_getservbyname(name, proto, WS_DUP_SEGPTR); return retval ? SEGPTR_GET(retval) : ((SEGPTR)NULL); } -struct WIN_servent* WINAPI WSOCK32_getservbyname(const char *name, const char *proto) +WIN_servent* WINAPI WSOCK32_getservbyname(const char *name, const char *proto) { TRACE("'%s', '%s'\n", (name)?name:NULL_STRING, (proto)?proto:NULL_STRING); @@ -2432,7 +2442,7 @@ struct WIN_servent* WINAPI WSOCK32_getservbyname(const char *name, const char *p /*********************************************************************** * getservbyport() (WINSOCK.56)(WSOCK32.56) */ -static struct WIN_servent* __ws_getservbyport(int port, const char* proto, int dup_flag) +static WIN_servent* __ws_getservbyport(int port, const char* proto, int dup_flag) { LPWSINFO pwsi = WINSOCK_GetIData(); @@ -2442,7 +2452,7 @@ static struct WIN_servent* __ws_getservbyport(int port, const char* proto, int d if (!proto || wsi_strtolo( pwsi, proto, NULL )) { if( (serv = getservbyport(port, (proto) ? pwsi->buffer : NULL)) != NULL ) { if( WS_dup_se(pwsi, serv, dup_flag) ) - return (struct WIN_servent*)(pwsi->se); + return (WIN_servent*)(pwsi->se); else SetLastError(WSAENOBUFS); } else { @@ -2459,17 +2469,17 @@ static struct WIN_servent* __ws_getservbyport(int port, const char* proto, int d SEGPTR WINAPI WINSOCK_getservbyport16(INT16 port, const char *proto) { - struct WIN_servent* retval; - TRACE("%i, '%s'\n", - (int)port, (proto)?proto:NULL_STRING); + WIN_servent* retval; + TRACE("%d (i.e. port %d), '%s'\n", + (int)port, (int)ntohl(port), (proto)?proto:NULL_STRING); retval = __ws_getservbyport(port, proto, WS_DUP_SEGPTR); return retval ? SEGPTR_GET(retval) : ((SEGPTR)NULL); } -struct WIN_servent* WINAPI WSOCK32_getservbyport(INT port, const char *proto) +WIN_servent* WINAPI WSOCK32_getservbyport(INT port, const char *proto) { - TRACE("%i, '%s'\n", - (int)port, (proto)?proto:NULL_STRING); + TRACE("%d (i.e. port %d), '%s'\n", + (int)port, (int)ntohl(port), (proto)?proto:NULL_STRING); return __ws_getservbyport(port, proto, WS_DUP_LINEAR); } @@ -2912,43 +2922,63 @@ static int hostent_size(struct hostent* p_he) return size; } +/* duplicate hostent entry + * and handle all Win16/Win32 dependent things (struct size, ...) *correctly*. + * Dito for protoent and servent. + */ int WS_dup_he(LPWSINFO pwsi, struct hostent* p_he, int flag) { - /* Convert hostent structure into ws_hostent so that the data fits - * into pwsi->buffer. Internal pointers can be linear, SEGPTR, or - * relative to pwsi->buffer depending on "flag" value. Returns size - * of the data copied (also in the pwsi->buflen). - */ + /* Convert hostent structure into ws_hostent so that the data fits + * into pwsi->buffer. Internal pointers can be linear, SEGPTR, or + * relative to pwsi->buffer depending on "flag" value. Returns size + * of the data copied (also in the pwsi->buflen). + */ - int size = hostent_size(p_he); + int size = hostent_size(p_he); + if( size ) + { + char *p_name,*p_aliases,*p_addr,*p_base,*p; + char *p_to; + struct ws_hostent16 *p_to16; + struct ws_hostent32 *p_to32; - if( size ) - { - struct ws_hostent* p_to; - char* p_name,*p_aliases,*p_addr,*p_base,*p; + _check_buffer_he(pwsi, size); + p_to = (char *)pwsi->he; + p_to16 = (struct ws_hostent16*)pwsi->he; + p_to32 = (struct ws_hostent32*)pwsi->he; - _check_buffer_he(pwsi, size); - p_to = (struct ws_hostent*)pwsi->he; - p = (char*)pwsi->he; - p_base = (flag & WS_DUP_OFFSET) ? NULL - : ((flag & WS_DUP_SEGPTR) ? (char*)SEGPTR_GET(p) : p); - p += sizeof(struct 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*)pwsi->he), 0); - p_addr = p; - list_dup(p_he->h_addr_list, p, p_base + (p - (char*)pwsi->he), p_he->h_length); + p = p_to; + p_base = (flag & WS_DUP_OFFSET) ? NULL + : ((flag & WS_DUP_SEGPTR) ? (char*)SEGPTR_GET(p) : p); + p += (flag & WS_DUP_SEGPTR) ? + sizeof(struct ws_hostent16) : sizeof(struct ws_hostent32); + 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 - p_to), 0); + p_addr = p; + list_dup(p_he->h_addr_list, p, p_base + (p - p_to), p_he->h_length); - p_to->h_addrtype = (INT16)p_he->h_addrtype; - p_to->h_length = (INT16)p_he->h_length; - p_to->h_name = (SEGPTR)(p_base + (p_name - (char*)pwsi->he)); - p_to->h_aliases = (SEGPTR)(p_base + (p_aliases - (char*)pwsi->he)); - p_to->h_addr_list = (SEGPTR)(p_base + (p_addr - (char*)pwsi->he)); - - size += (sizeof(struct ws_hostent) - sizeof(struct hostent)); - } - return size; + if (flag & WS_DUP_SEGPTR) /* 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)); + size += (sizeof(struct ws_hostent16) - sizeof(struct hostent)); + } + else /* Win32 */ + { + 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)); + size += (sizeof(struct ws_hostent32) - sizeof(struct hostent)); + } + } + return size; } /* ----- protoent */ @@ -2965,30 +2995,44 @@ static int protoent_size(struct protoent* p_pe) int WS_dup_pe(LPWSINFO pwsi, struct protoent* p_pe, int flag) { - int size = protoent_size(p_pe); - if( size ) - { - struct ws_protoent* p_to; - char* p_name,*p_aliases,*p_base,*p; + int size = protoent_size(p_pe); + if( size ) + { + char *p_to; + struct ws_protoent16 *p_to16; + struct ws_protoent32 *p_to32; + char *p_name,*p_aliases,*p_base,*p; - _check_buffer_pe(pwsi, size); - p_to = (struct ws_protoent*)pwsi->pe; - p = (char*)pwsi->pe; - p_base = (flag & WS_DUP_OFFSET) ? NULL - : ((flag & WS_DUP_SEGPTR) ? (char*)SEGPTR_GET(p) : p); - p += sizeof(struct 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*)pwsi->pe), 0); + _check_buffer_pe(pwsi, size); + p_to = (char *)pwsi->pe; + p_to16 = (struct ws_protoent16*)pwsi->pe; + p_to32 = (struct ws_protoent32*)pwsi->pe; + p = p_to; + p_base = (flag & WS_DUP_OFFSET) ? NULL + : ((flag & WS_DUP_SEGPTR) ? (char*)SEGPTR_GET(p) : p); + p += (flag & WS_DUP_SEGPTR) ? + sizeof(struct ws_protoent16) : sizeof(struct ws_protoent32); + 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 - p_to), 0); - p_to->p_proto = (INT16)p_pe->p_proto; - p_to->p_name = (SEGPTR)(p_base) + (p_name - (char*)pwsi->pe); - p_to->p_aliases = (SEGPTR)((p_base) + (p_aliases - (char*)pwsi->pe)); - - size += (sizeof(struct ws_protoent) - sizeof(struct protoent)); - } - return size; + if (flag & WS_DUP_SEGPTR) /* 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)); + size += (sizeof(struct ws_protoent16) - sizeof(struct protoent)); + } + else /* Win32 */ + { + 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)); + size += (sizeof(struct ws_protoent32) - sizeof(struct protoent)); + } + } + return size; } /* ----- servent */ @@ -3005,33 +3049,48 @@ static int servent_size(struct servent* p_se) int WS_dup_se(LPWSINFO pwsi, struct servent* p_se, int flag) { - int size = servent_size(p_se); - if( size ) - { - struct ws_servent* p_to; - char* p_name,*p_aliases,*p_proto,*p_base,*p; + int size = servent_size(p_se); + if( size ) + { + char *p_name,*p_aliases,*p_proto,*p_base,*p; + char *p_to; + struct ws_servent16 *p_to16; + struct ws_servent32 *p_to32; - _check_buffer_se(pwsi, size); - p_to = (struct ws_servent*)pwsi->se; - p = (char*)pwsi->se; - p_base = (flag & WS_DUP_OFFSET) ? NULL - : ((flag & WS_DUP_SEGPTR) ? (char*)SEGPTR_GET(p) : p); - p += sizeof(struct 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 - (char*)pwsi->se), 0); + _check_buffer_se(pwsi, size); + p_to = (char *)pwsi->se; + p_to16 = (struct ws_servent16*)pwsi->se; + p_to32 = (struct ws_servent32*)pwsi->se; + p = p_to; + p_base = (flag & WS_DUP_OFFSET) ? NULL + : ((flag & WS_DUP_SEGPTR) ? (char*)SEGPTR_GET(p) : p); + p += (flag & WS_DUP_SEGPTR) ? + sizeof(struct ws_servent16) : sizeof(struct ws_servent32); + 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); - p_to->s_port = (INT16)p_se->s_port; - p_to->s_name = (SEGPTR)(p_base + (p_name - (char*)pwsi->se)); - p_to->s_proto = (SEGPTR)(p_base + (p_proto - (char*)pwsi->se)); - p_to->s_aliases = (SEGPTR)(p_base + (p_aliases - (char*)pwsi->se)); - - size += (sizeof(struct ws_servent) - sizeof(struct servent)); - } - return size; + if (flag & WS_DUP_SEGPTR) /* 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)); + size += (sizeof(struct ws_servent16) - sizeof(struct servent)); + } + else /* Win32 */ + { + 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)); + size += (sizeof(struct ws_servent32) - sizeof(struct servent)); + } + } + return size; } /* ----------------------------------- error handling */ diff --git a/include/wine/winsock16.h b/include/wine/winsock16.h new file mode 100644 index 00000000000..846e252faca --- /dev/null +++ b/include/wine/winsock16.h @@ -0,0 +1,43 @@ +#ifndef __WINE_WINE_WINSOCK16_H +#define __WINE_WINE_WINSOCK16_H + +#include "windef.h" +#include "pshpack1.h" + +/* ws_hostent16, ws_protoent16, ws_servent16, ws_netent16 + * are 1-byte aligned here ! */ +typedef struct ws_hostent16 +{ + SEGPTR h_name; /* official name of host */ + SEGPTR h_aliases; /* alias list */ + INT16 h_addrtype; /* host address type */ + INT16 h_length; /* length of address */ + SEGPTR h_addr_list; /* list of addresses from name server */ +} _ws_hostent16; + +typedef struct ws_protoent16 +{ + SEGPTR p_name; /* official protocol name */ + SEGPTR p_aliases; /* alias list */ + INT16 p_proto; /* protocol # */ +} _ws_protoent16; + +typedef struct ws_servent16 +{ + SEGPTR s_name; /* official service name */ + SEGPTR s_aliases; /* alias list */ + INT16 s_port; /* port # */ + SEGPTR s_proto; /* protocol to use */ +} _ws_servent16; + +typedef struct ws_netent16 +{ + SEGPTR n_name; /* official name of net */ + SEGPTR n_aliases; /* alias list */ + INT16 n_addrtype; /* net address type */ + INT n_net; /* network # */ +} _ws_netent16; + +#include "poppack.h" + +#endif /* __WINE_WINE_WINSOCK16_H */ diff --git a/include/winsock.h b/include/winsock.h index 390e1724cc9..f6b86bac7b2 100644 --- a/include/winsock.h +++ b/include/winsock.h @@ -42,6 +42,40 @@ extern "C" { #endif /* defined(__cplusplus) */ +/* no "forced" alignment of ws_XXXXent here ! */ + +typedef struct ws_hostent +{ + char *h_name; /* official name of host */ + char **h_aliases; /* alias list */ + short h_addrtype; /* host address type */ + short h_length; /* length of address */ + char **h_addr_list; /* list of addresses from name server */ +} _ws_hostent; + +typedef struct ws_protoent +{ + char *p_name; /* official protocol name */ + char **p_aliases; /* alias list */ + short p_proto; /* protocol # */ +} _ws_protoent; + +typedef struct ws_servent +{ + char *s_name; /* official service name */ + char **s_aliases; /* alias list */ + short s_port; /* port # */ + char *s_proto; /* protocol to use */ +} _ws_servent; + +typedef struct ws_netent +{ + char *n_name; /* official name of net */ + char **n_aliases; /* alias list */ + short n_addrtype; /* net address type */ + u_long n_net; /* network # */ +} _ws_netent; + #include "pshpack1.h" /* Win16 socket-related types */ @@ -49,38 +83,6 @@ extern "C" { typedef UINT16 SOCKET16; typedef UINT SOCKET; -typedef struct ws_hostent -{ - SEGPTR h_name; /* official name of host */ - SEGPTR h_aliases; /* alias list */ - INT16 h_addrtype; /* host address type */ - INT16 h_length; /* length of address */ - SEGPTR h_addr_list; /* list of addresses from name server */ -} _ws_hostent; - -typedef struct ws_protoent -{ - SEGPTR p_name; /* official protocol name */ - SEGPTR p_aliases; /* alias list */ - INT16 p_proto; /* protocol # */ -} _ws_protoent; - -typedef struct ws_servent -{ - SEGPTR s_name; /* official service name */ - SEGPTR s_aliases; /* alias list */ - INT16 s_port; /* port # */ - SEGPTR s_proto; /* protocol to use */ -} _ws_servent; - -typedef struct ws_netent -{ - SEGPTR n_name; /* official name of net */ - SEGPTR n_aliases; /* alias list */ - INT16 n_addrtype; /* net address type */ - INT n_net; /* network # */ -} _ws_netent; - typedef struct sockaddr ws_sockaddr; typedef struct @@ -175,7 +177,7 @@ typedef struct WSAData { #include "poppack.h" -/* ----------------------------------- no Win16 structure defs beyond this line! */ +/* ------ no Win16 structure defs (1-byte alignment) beyond this line! ------ */ /* * This is used instead of -1, since the diff --git a/include/winsock2.h b/include/winsock2.h index 74db352a81e..4f88973a67c 100644 --- a/include/winsock2.h +++ b/include/winsock2.h @@ -10,6 +10,9 @@ #include "winsock.h" #include "wtypes.h" +/* proper 4-byte packing */ +#include "pshpack4.h" + #define FD_MAX_EVENTS 10 #define FD_READ_BIT 0 #define FD_WRITE_BIT 1 @@ -57,6 +60,7 @@ #ifdef s6_addr #undef s6_addr #endif + struct ws_in_addr6 { unsigned char s6_addr[16]; /* IPv6 address */ @@ -76,6 +80,40 @@ typedef union sockaddr_gen struct ws_sockaddr_in6 AddressIn6; } sockaddr_gen; +/* ws_hostent, ws_protoent, ws_servent, ws_netent are 4-byte aligned here ! */ + +typedef struct ws_hostent32 +{ + char *h_name; /* official name of host */ + char **h_aliases; /* alias list */ + short h_addrtype; /* host address type */ + short h_length; /* length of address */ + char **h_addr_list; /* list of addresses from name server */ +} _ws_hostent32; + +typedef struct ws_protoent32 +{ + char *p_name; /* official protocol name */ + char **p_aliases; /* alias list */ + short p_proto; /* protocol # */ +} _ws_protoent32; + +typedef struct ws_servent32 +{ + char *s_name; /* official service name */ + char **s_aliases; /* alias list */ + short s_port; /* port # */ + char *s_proto; /* protocol to use */ +} _ws_servent32; + +typedef struct ws_netent32 +{ + char *n_name; /* official name of net */ + char **n_aliases; /* alias list */ + short n_addrtype; /* net address type */ + u_long n_net; /* network # */ +} _ws_netent32; + /* Structure to keep interface specific information */ typedef struct _INTERFACE_INFO { @@ -161,4 +199,6 @@ SOCKET WINAPI WSASocketA(int af, int type, int protocol, LPWSAPROTOCOL_INFOA lpProtocolInfo, GROUP g, DWORD dwFlags); +#include "poppack.h" + #endif