Commit ae50941a authored by Andreas Mohr's avatar Andreas Mohr Committed by Alexandre Julliard

Fixed the Win16/Win32 structure size/alignment differences of

ws_hostent, ws_protoent, ws_servent, ws_netent.
parent 4e095e6e
...@@ -17,8 +17,6 @@ ...@@ -17,8 +17,6 @@
* (not sure why) * (not sure why)
* - This implementation did ignore the "NOTE:" section above (since the * - This implementation did ignore the "NOTE:" section above (since the
* whole stuff did not work anyway to other changes). * 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" #include "config.h"
...@@ -81,7 +79,8 @@ ...@@ -81,7 +79,8 @@
#include "wine/winbase16.h" #include "wine/winbase16.h"
#include "wingdi.h" #include "wingdi.h"
#include "winuser.h" #include "winuser.h"
#include "winsock.h" #include "winsock2.h"
#include "wine/winsock16.h"
#include "winnt.h" #include "winnt.h"
#include "heap.h" #include "heap.h"
#include "task.h" #include "task.h"
...@@ -97,6 +96,23 @@ DEFAULT_DEBUG_CHANNEL(winsock) ...@@ -97,6 +96,23 @@ DEFAULT_DEBUG_CHANNEL(winsock)
UINT16 wsaErrno(void); UINT16 wsaErrno(void);
UINT16 wsaHerrno(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 - */ /* ----------------------------------- helper functions - */
static int list_size(char** l, int item_size) static int list_size(char** l, int item_size)
...@@ -143,15 +159,22 @@ static int hostent_size(struct hostent* p_he) ...@@ -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 /* Copy hostent to p_to, fix up inside pointers using p_base (different for
* Win16 (linear vs. segmented). Return -neededsize on overrun. * 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; 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) if (t_size < size)
return -size; return -size;
p = (char*)p_to; p = p_to;
p += sizeof(struct ws_hostent); p += (flag & AQ_WIN16) ?
sizeof(struct ws_hostent16) : sizeof(struct ws_hostent32);
p_name = p; p_name = p;
strcpy(p, p_he->h_name); p += strlen(p) + 1; strcpy(p, p_he->h_name); p += strlen(p) + 1;
p_aliases = p; 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 ...@@ -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; p_addr = p;
list_dup(p_he->h_addr_list, p, p_base + (p - (char*)p_to), p_he->h_length); 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; if (flag & AQ_WIN16)
p_to->h_length = (INT16)p_he->h_length; {
p_to->h_name = (SEGPTR)(p_base + (p_name - (char*)p_to)); p_to16->h_addrtype = (INT16)p_he->h_addrtype;
p_to->h_aliases = (SEGPTR)(p_base + (p_aliases - (char*)p_to)); p_to16->h_length = (INT16)p_he->h_length;
p_to->h_addr_list = (SEGPTR)(p_base + (p_addr - (char*)p_to)); 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; return size;
} }
...@@ -183,24 +217,39 @@ static int protoent_size(struct protoent* p_pe) ...@@ -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 /* Copy protoent to p_to, fix up inside pointers using p_base (different for
* Win16 (linear vs. segmented). Return -neededsize on overrun. * 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; 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) if (t_size < size)
return -size; return -size;
p = (char*)p_to; p = p_to;
p += sizeof(struct ws_protoent); p += (flag & AQ_WIN16) ?
sizeof(struct ws_protoent16) : sizeof(struct ws_protoent32);
p_name = p; p_name = p;
strcpy(p, p_pe->p_name); p += strlen(p) + 1; strcpy(p, p_pe->p_name); p += strlen(p) + 1;
p_aliases = p; p_aliases = p;
list_dup(p_pe->p_aliases, p, p_base + (p - (char*)p_to), 0); list_dup(p_pe->p_aliases, p, p_base + (p - (char*)p_to), 0);
p_to->p_proto = (INT16)p_pe->p_proto; if (flag & AQ_WIN16)
p_to->p_name = (SEGPTR)(p_base) + (p_name - (char*)p_to); {
p_to->p_aliases = (SEGPTR)((p_base) + (p_aliases - (char*)p_to)); 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; return size;
} }
...@@ -220,27 +269,45 @@ static int servent_size(struct servent* p_se) ...@@ -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 /* Copy servent to p_to, fix up inside pointers using p_base (different for
* Win16 (linear vs. segmented). Return -neededsize on overrun. * 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; 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; return -size;
p = (char*)p_to; p = p_to;
p += sizeof(struct ws_servent); p += (flag & AQ_WIN16) ?
sizeof(struct ws_servent16) : sizeof(struct ws_servent32);
p_name = p; p_name = p;
strcpy(p, p_se->s_name); p += strlen(p) + 1; strcpy(p, p_se->s_name); p += strlen(p) + 1;
p_proto = p; p_proto = p;
strcpy(p, p_se->s_proto); p += strlen(p) + 1; strcpy(p, p_se->s_proto); p += strlen(p) + 1;
p_aliases = p; 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; if (flag & AQ_WIN16)
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_to16->s_port = (INT16)p_se->s_port;
p_to->s_aliases = (SEGPTR)(p_base + (p_aliases - (char*)p_to)); 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; return size;
} }
...@@ -271,22 +338,6 @@ typedef struct _async_query { ...@@ -271,22 +338,6 @@ typedef struct _async_query {
HANDLE16 async_handle; HANDLE16 async_handle;
int flags; 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; int qt;
char xbuf[1]; char xbuf[1];
} async_query; } async_query;
...@@ -310,14 +361,14 @@ static DWORD WINAPI _async_queryfun(LPVOID arg) { ...@@ -310,14 +361,14 @@ static DWORD WINAPI _async_queryfun(LPVOID arg) {
switch (aq->flags & AQ_GETMASK) { switch (aq->flags & AQ_GETMASK) {
case AQ_GETHOST: { case AQ_GETHOST: {
struct hostent *he; struct hostent *he;
struct ws_hostent *wshe = (struct ws_hostent*)targetptr; char *copy_hostent = targetptr;
he = (aq->flags & AQ_NAME) ? he = (aq->flags & AQ_NAME) ?
gethostbyname(aq->host_name): gethostbyname(aq->host_name):
gethostbyaddr(aq->host_addr,aq->host_len,aq->host_type); gethostbyaddr(aq->host_addr,aq->host_len,aq->host_type);
if (he) { 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) { if (size < 0) {
fail = WSAENOBUFS; fail = WSAENOBUFS;
size = -size; size = -size;
...@@ -328,13 +379,13 @@ static DWORD WINAPI _async_queryfun(LPVOID arg) { ...@@ -328,13 +379,13 @@ static DWORD WINAPI _async_queryfun(LPVOID arg) {
} }
break; break;
case AQ_GETPROTO: { case AQ_GETPROTO: {
struct protoent *pe; struct protoent *pe;
struct ws_protoent *wspe = (struct ws_protoent*)targetptr; char *copy_protoent = targetptr;
pe = (aq->flags & AQ_NAME)? pe = (aq->flags & AQ_NAME)?
getprotobyname(aq->proto_name) : getprotobyname(aq->proto_name) :
getprotobynumber(aq->proto_number); getprotobynumber(aq->proto_number);
if (pe) { 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) { if (size < 0) {
fail = WSAENOBUFS; fail = WSAENOBUFS;
size = -size; size = -size;
...@@ -351,13 +402,13 @@ static DWORD WINAPI _async_queryfun(LPVOID arg) { ...@@ -351,13 +402,13 @@ static DWORD WINAPI _async_queryfun(LPVOID arg) {
} }
break; break;
case AQ_GETSERV: { case AQ_GETSERV: {
struct servent *se; struct servent *se;
struct ws_servent *wsse = (struct ws_servent*)targetptr; char *copy_servent = targetptr;
se = (aq->flags & AQ_NAME)? se = (aq->flags & AQ_NAME)?
getservbyname(aq->serv_name,aq->serv_proto) : getservbyname(aq->serv_name,aq->serv_proto) :
getservbyport(aq->serv_port,aq->serv_proto); getservbyport(aq->serv_port,aq->serv_proto);
if (se) { 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) { if (size < 0) {
fail = WSAENOBUFS; fail = WSAENOBUFS;
size = -size; size = -size;
......
#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 */
...@@ -42,45 +42,47 @@ ...@@ -42,45 +42,47 @@
extern "C" { extern "C" {
#endif /* defined(__cplusplus) */ #endif /* defined(__cplusplus) */
#include "pshpack1.h" /* no "forced" alignment of ws_XXXXent here ! */
/* Win16 socket-related types */
typedef UINT16 SOCKET16;
typedef UINT SOCKET;
typedef struct ws_hostent typedef struct ws_hostent
{ {
SEGPTR h_name; /* official name of host */ char *h_name; /* official name of host */
SEGPTR h_aliases; /* alias list */ char **h_aliases; /* alias list */
INT16 h_addrtype; /* host address type */ short h_addrtype; /* host address type */
INT16 h_length; /* length of address */ short h_length; /* length of address */
SEGPTR h_addr_list; /* list of addresses from name server */ char **h_addr_list; /* list of addresses from name server */
} _ws_hostent; } _ws_hostent;
typedef struct ws_protoent typedef struct ws_protoent
{ {
SEGPTR p_name; /* official protocol name */ char *p_name; /* official protocol name */
SEGPTR p_aliases; /* alias list */ char **p_aliases; /* alias list */
INT16 p_proto; /* protocol # */ short p_proto; /* protocol # */
} _ws_protoent; } _ws_protoent;
typedef struct ws_servent typedef struct ws_servent
{ {
SEGPTR s_name; /* official service name */ char *s_name; /* official service name */
SEGPTR s_aliases; /* alias list */ char **s_aliases; /* alias list */
INT16 s_port; /* port # */ short s_port; /* port # */
SEGPTR s_proto; /* protocol to use */ char *s_proto; /* protocol to use */
} _ws_servent; } _ws_servent;
typedef struct ws_netent typedef struct ws_netent
{ {
SEGPTR n_name; /* official name of net */ char *n_name; /* official name of net */
SEGPTR n_aliases; /* alias list */ char **n_aliases; /* alias list */
INT16 n_addrtype; /* net address type */ short n_addrtype; /* net address type */
INT n_net; /* network # */ u_long n_net; /* network # */
} _ws_netent; } _ws_netent;
#include "pshpack1.h"
/* Win16 socket-related types */
typedef UINT16 SOCKET16;
typedef UINT SOCKET;
typedef struct sockaddr ws_sockaddr; typedef struct sockaddr ws_sockaddr;
typedef struct typedef struct
...@@ -175,7 +177,7 @@ typedef struct WSAData { ...@@ -175,7 +177,7 @@ typedef struct WSAData {
#include "poppack.h" #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 * This is used instead of -1, since the
......
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
#include "winsock.h" #include "winsock.h"
#include "wtypes.h" #include "wtypes.h"
/* proper 4-byte packing */
#include "pshpack4.h"
#define FD_MAX_EVENTS 10 #define FD_MAX_EVENTS 10
#define FD_READ_BIT 0 #define FD_READ_BIT 0
#define FD_WRITE_BIT 1 #define FD_WRITE_BIT 1
...@@ -57,6 +60,7 @@ ...@@ -57,6 +60,7 @@
#ifdef s6_addr #ifdef s6_addr
#undef s6_addr #undef s6_addr
#endif #endif
struct ws_in_addr6 struct ws_in_addr6
{ {
unsigned char s6_addr[16]; /* IPv6 address */ unsigned char s6_addr[16]; /* IPv6 address */
...@@ -76,6 +80,40 @@ typedef union sockaddr_gen ...@@ -76,6 +80,40 @@ typedef union sockaddr_gen
struct ws_sockaddr_in6 AddressIn6; struct ws_sockaddr_in6 AddressIn6;
} sockaddr_gen; } 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 */ /* Structure to keep interface specific information */
typedef struct _INTERFACE_INFO typedef struct _INTERFACE_INFO
{ {
...@@ -161,4 +199,6 @@ SOCKET WINAPI WSASocketA(int af, int type, int protocol, ...@@ -161,4 +199,6 @@ SOCKET WINAPI WSASocketA(int af, int type, int protocol,
LPWSAPROTOCOL_INFOA lpProtocolInfo, LPWSAPROTOCOL_INFOA lpProtocolInfo,
GROUP g, DWORD dwFlags); GROUP g, DWORD dwFlags);
#include "poppack.h"
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment