Winsock rewrite. Sockets are now proper win32 handles.
Internal structures are now really internal.
This commit is contained in:
parent
42a474ed65
commit
f45608f639
|
@ -59,3 +59,5 @@ type win16
|
|||
115 pascal WSAStartup(word ptr) WSAStartup16
|
||||
116 pascal WSACleanup() WSACleanup
|
||||
151 pascal16 __WSAFDIsSet(word ptr) __WSAFDIsSet16
|
||||
|
||||
1999 pascal DllEntryPoint(long word word word long word) WINSOCK_LibMain
|
||||
|
|
|
@ -93,8 +93,7 @@ typedef struct _TDB
|
|||
DWORD compat_flags WINE_PACKED; /* 4e Compatibility flags */
|
||||
BYTE unused4[2]; /* 52 */
|
||||
struct _TEB *teb; /* 54 Pointer to thread database */
|
||||
struct _WSINFO *pwsi; /* 58 Socket control struct */
|
||||
BYTE unused5[4]; /* 5B */
|
||||
BYTE unused5[8]; /* 58 */
|
||||
HANDLE16 hPDB; /* 60 Selector of PDB (i.e. PSP) */
|
||||
SEGPTR dta WINE_PACKED; /* 62 Current DTA */
|
||||
BYTE curdrive; /* 66 Current drive */
|
||||
|
|
|
@ -279,10 +279,10 @@ typedef struct WSAData {
|
|||
#define WS_FD_CLOSE 0x0020
|
||||
|
||||
#define WS_FD_LISTENING 0x10000000 /* internal per-socket flags */
|
||||
#define WS_FD_INACTIVE 0x20000000
|
||||
#define WS_FD_NONBLOCKING 0x20000000
|
||||
#define WS_FD_CONNECTED 0x40000000
|
||||
#define WS_FD_RAW 0x80000000
|
||||
#define WS_FD_NONBLOCKING 0x01000000
|
||||
#define WS_FD_SERVEVENT 0x01000000
|
||||
#define WS_FD_INTERNAL 0xFFFF0000
|
||||
|
||||
/*
|
||||
|
@ -534,73 +534,6 @@ typedef struct timeval TIMEVAL, *PTIMEVAL, *LPTIMEVAL;
|
|||
*/
|
||||
#define WSAGETSELECTERROR(lParam) HIWORD(lParam)
|
||||
|
||||
/* ----------------------------------- internal structures */
|
||||
|
||||
/* ws_... struct conversion flags */
|
||||
|
||||
#define WS_DUP_LINEAR 0x0001
|
||||
#define WS_DUP_NATIVE 0x0000 /* not used anymore */
|
||||
#define WS_DUP_OFFSET 0x0002 /* internal pointers are offsets */
|
||||
#define WS_DUP_SEGPTR 0x0004 /* internal pointers are SEGPTRs */
|
||||
/* by default, internal pointers are linear */
|
||||
|
||||
typedef struct __sop /* WSAAsyncSelect() control struct */
|
||||
{
|
||||
struct __sop *next, *prev;
|
||||
|
||||
struct __ws* pws;
|
||||
HWND hWnd;
|
||||
UINT uMsg;
|
||||
} ws_select_op;
|
||||
|
||||
typedef struct __ws /* socket */
|
||||
{
|
||||
int fd;
|
||||
unsigned flags;
|
||||
ws_select_op* psop;
|
||||
} ws_socket;
|
||||
|
||||
#define WS_MAX_SOCKETS_PER_PROCESS 16
|
||||
#define WS_MAX_UDP_DATAGRAM 1024
|
||||
|
||||
#define WSI_BLOCKINGCALL 0x00000001 /* per-thread info flags */
|
||||
#define WSI_BLOCKINGHOOK 0x00000002 /* 32-bit callback */
|
||||
|
||||
typedef struct _WSINFO
|
||||
{
|
||||
struct _WSINFO* prev,*next;
|
||||
|
||||
unsigned flags;
|
||||
INT16 num_startup; /* reference counter */
|
||||
INT16 num_async_rq;
|
||||
INT16 last_free; /* entry in the socket table */
|
||||
UINT16 buflen;
|
||||
char* buffer; /* allocated from SEGPTR heap */
|
||||
struct ws_hostent *he;
|
||||
int helen;
|
||||
struct ws_servent *se;
|
||||
int selen;
|
||||
struct ws_protoent *pe;
|
||||
int pelen;
|
||||
char* dbuffer; /* buffer for dummies (32 bytes) */
|
||||
|
||||
ws_socket sock[WS_MAX_SOCKETS_PER_PROCESS];
|
||||
DWORD blocking_hook;
|
||||
HTASK16 tid; /* owning task id - process might be better */
|
||||
} WSINFO, *LPWSINFO;
|
||||
|
||||
/* function prototypes */
|
||||
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);
|
||||
|
||||
BOOL WINSOCK_Init(void);
|
||||
void WINSOCK_Shutdown(void);
|
||||
UINT16 wsaErrno(void);
|
||||
UINT16 wsaHerrno(void);
|
||||
|
||||
extern INT WINSOCK_DeleteTaskWSI( TDB* pTask, struct _WSINFO* );
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
|
|
@ -89,9 +89,6 @@ BOOL MAIN_MainInit( int *argc, char *argv[] )
|
|||
/* Initialize event handling */
|
||||
if (!EVENT_Init()) return FALSE;
|
||||
|
||||
/* Initialise WINSOCK handling */
|
||||
if (!WINSOCK_Init()) return FALSE;
|
||||
|
||||
/* Initialize communications */
|
||||
COMM_Init();
|
||||
|
||||
|
|
|
@ -451,11 +451,6 @@ void TASK_KillTask( HTASK16 hTask )
|
|||
|
||||
TRACE_(task)("Killing task %04x\n", hTask );
|
||||
|
||||
/* Delete active sockets */
|
||||
|
||||
if( pTask->pwsi )
|
||||
WINSOCK_DeleteTaskWSI( pTask, pTask->pwsi );
|
||||
|
||||
#ifdef MZ_SUPPORTED
|
||||
{
|
||||
/* Kill DOS VM task */
|
||||
|
|
|
@ -770,7 +770,6 @@ static void called_at_exit(void)
|
|||
if (USER_Driver)
|
||||
USER_Driver->pFinalize();
|
||||
|
||||
WINSOCK_Shutdown();
|
||||
CONSOLE_Close();
|
||||
}
|
||||
|
||||
|
|
1365
misc/winsock.c
1365
misc/winsock.c
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,6 @@
|
|||
name wsock32
|
||||
type win32
|
||||
init WSOCK32_LibMain
|
||||
|
||||
001 stdcall accept(long ptr ptr) WINSOCK_accept
|
||||
002 stdcall bind(long ptr long) WINSOCK_bind
|
||||
|
|
|
@ -91,7 +91,7 @@ extern void dump_objects(void);
|
|||
|
||||
#define READ_EVENT 1
|
||||
#define WRITE_EVENT 2
|
||||
#define EXCEPT_EVENT 3
|
||||
#define EXCEPT_EVENT 4
|
||||
|
||||
struct select_user
|
||||
{
|
||||
|
|
|
@ -84,7 +84,10 @@ static int sock_event( struct sock *sock )
|
|||
|
||||
static void sock_reselect( struct sock *sock )
|
||||
{
|
||||
set_select_events( &sock->select, sock_event( sock ) );
|
||||
int ev = sock_event( sock );
|
||||
if (debug_level)
|
||||
fprintf(stderr,"sock_reselect(%d): new mask %x\n", sock->select.fd, ev);
|
||||
set_select_events( &sock->select, ev );
|
||||
}
|
||||
|
||||
inline static int sock_error(int s)
|
||||
|
@ -101,6 +104,8 @@ static void sock_select_event( int event, void *private )
|
|||
struct sock *sock = (struct sock *)private;
|
||||
unsigned int emask;
|
||||
assert( sock->obj.ops == &sock_ops );
|
||||
if (debug_level)
|
||||
fprintf(stderr, "socket %d select event: %x\n", sock->select.fd, event);
|
||||
if (sock->state & WS_FD_CONNECT)
|
||||
{
|
||||
/* connecting */
|
||||
|
@ -111,6 +116,8 @@ static void sock_select_event( int event, void *private )
|
|||
sock->state &= ~WS_FD_CONNECT;
|
||||
sock->pmask |= FD_CONNECT;
|
||||
sock->errors[FD_CONNECT_BIT] = 0;
|
||||
if (debug_level)
|
||||
fprintf(stderr, "socket %d connection success\n", sock->select.fd);
|
||||
}
|
||||
else if (event & EXCEPT_EVENT)
|
||||
{
|
||||
|
@ -118,6 +125,8 @@ static void sock_select_event( int event, void *private )
|
|||
sock->state &= ~WS_FD_CONNECT;
|
||||
sock->pmask |= FD_CONNECT;
|
||||
sock->errors[FD_CONNECT_BIT] = sock_error( sock->select.fd );
|
||||
if (debug_level)
|
||||
fprintf(stderr, "socket %d connection failure\n", sock->select.fd);
|
||||
}
|
||||
} else
|
||||
if (sock->state & WS_FD_LISTENING)
|
||||
|
@ -151,6 +160,8 @@ static void sock_select_event( int event, void *private )
|
|||
sock->pmask |= FD_READ;
|
||||
sock->hmask |= FD_READ;
|
||||
sock->errors[FD_READ_BIT] = 0;
|
||||
if (debug_level)
|
||||
fprintf(stderr, "socket %d has %d bytes\n", sock->select.fd, bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -158,6 +169,8 @@ static void sock_select_event( int event, void *private )
|
|||
sock->state &= ~(WS_FD_CONNECTED|WS_FD_READ|WS_FD_WRITE);
|
||||
sock->pmask |= FD_CLOSE;
|
||||
sock->errors[FD_CLOSE_BIT] = 0;
|
||||
if (debug_level)
|
||||
fprintf(stderr, "socket %d is closing\n", sock->select.fd);
|
||||
}
|
||||
}
|
||||
if (event & WRITE_EVENT)
|
||||
|
@ -165,6 +178,8 @@ static void sock_select_event( int event, void *private )
|
|||
sock->pmask |= FD_WRITE;
|
||||
sock->hmask |= FD_WRITE;
|
||||
sock->errors[FD_WRITE_BIT] = 0;
|
||||
if (debug_level)
|
||||
fprintf(stderr, "socket %d is writable\n", sock->select.fd);
|
||||
}
|
||||
if (event & EXCEPT_EVENT)
|
||||
{
|
||||
|
@ -174,12 +189,16 @@ static void sock_select_event( int event, void *private )
|
|||
/* we got an error, socket closing? */
|
||||
sock->state &= ~(WS_FD_CONNECTED|WS_FD_READ|WS_FD_WRITE);
|
||||
sock->pmask |= FD_CLOSE;
|
||||
if (debug_level)
|
||||
fprintf(stderr, "socket %d aborted by error %d\n", sock->select.fd, sock->errors[FD_CLOSE_BIT]);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no error, OOB data? */
|
||||
sock->pmask |= FD_OOB;
|
||||
sock->hmask |= FD_OOB;
|
||||
if (debug_level)
|
||||
fprintf(stderr, "socket %d got OOB data\n", sock->select.fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -187,8 +206,12 @@ static void sock_select_event( int event, void *private )
|
|||
sock_reselect( sock );
|
||||
/* wake up anyone waiting for whatever just happened */
|
||||
emask = sock->pmask & sock->mask;
|
||||
if (emask && sock->event)
|
||||
if (debug_level && emask)
|
||||
fprintf(stderr, "socket %d pending events: %x\n", sock->select.fd, emask);
|
||||
if (emask && sock->event) {
|
||||
if (debug_level) fprintf(stderr, "signalling event ptr %p\n", sock->event);
|
||||
set_event(sock->event);
|
||||
}
|
||||
|
||||
/* if anyone is stupid enough to wait on the socket object itself,
|
||||
* maybe we should wake them up too, just in case? */
|
||||
|
@ -199,7 +222,9 @@ static void sock_dump( struct object *obj, int verbose )
|
|||
{
|
||||
struct sock *sock = (struct sock *)obj;
|
||||
assert( obj->ops == &sock_ops );
|
||||
printf( "Socket fd=%d\n", sock->select.fd );
|
||||
printf( "Socket fd=%d, state=%x, mask=%x, pending=%x, held=%x\n",
|
||||
sock->select.fd, sock->state,
|
||||
sock->mask, sock->pmask, sock->hmask );
|
||||
}
|
||||
|
||||
static int sock_add_queue( struct object *obj, struct wait_queue_entry *entry )
|
||||
|
@ -217,7 +242,7 @@ static void sock_remove_queue( struct object *obj, struct wait_queue_entry *entr
|
|||
assert( obj->ops == &sock_ops );
|
||||
|
||||
remove_queue( obj, entry );
|
||||
release_object( obj );
|
||||
/* release_object( obj ); */
|
||||
}
|
||||
|
||||
static int sock_signaled( struct object *obj, struct thread *thread )
|
||||
|
@ -252,11 +277,11 @@ static void sock_destroy( struct object *obj )
|
|||
/* if the service thread was waiting for the event object,
|
||||
* we should now signal it, to let the service thread
|
||||
* object detect that it is now orphaned... */
|
||||
if (sock->mask & WS_FD_SERVEVENT)
|
||||
set_event( sock->event );
|
||||
/* we're through with it */
|
||||
release_object( sock->event );
|
||||
}
|
||||
free( sock );
|
||||
}
|
||||
|
||||
/* create a new and unconnected socket */
|
||||
|
@ -274,9 +299,11 @@ static struct object *create_socket( int family, int type, int protocol )
|
|||
sock->hmask = 0;
|
||||
sock->pmask = 0;
|
||||
sock->event = NULL;
|
||||
if (debug_level)
|
||||
fprintf(stderr,"socket(%d,%d,%d)=%d\n",family,type,protocol,sock->select.fd);
|
||||
fcntl(sock->select.fd, F_SETFL, O_NONBLOCK); /* make socket nonblocking */
|
||||
register_select_user( &sock->select );
|
||||
sock_reselect( sock );
|
||||
clear_error();
|
||||
return &sock->obj;
|
||||
}
|
||||
|
@ -313,13 +340,14 @@ static struct object *accept_socket( int handle )
|
|||
|
||||
acceptsock->select.fd = acceptfd;
|
||||
acceptsock->select.func = sock_select_event;
|
||||
acceptsock->select.private = sock;
|
||||
acceptsock->select.private = acceptsock;
|
||||
acceptsock->state = WS_FD_CONNECTED|WS_FD_READ|WS_FD_WRITE;
|
||||
acceptsock->mask = sock->mask;
|
||||
acceptsock->hmask = 0;
|
||||
acceptsock->pmask = 0;
|
||||
acceptsock->event = (struct event *)grab_object( sock->event );
|
||||
register_select_user( &acceptsock->select );
|
||||
sock_reselect( acceptsock );
|
||||
clear_error();
|
||||
sock->pmask &= ~FD_ACCEPT;
|
||||
sock->hmask &= ~FD_ACCEPT;
|
||||
|
@ -424,19 +452,22 @@ DECL_HANDLER(set_socket_event)
|
|||
{
|
||||
struct sock *sock;
|
||||
struct event *oevent;
|
||||
unsigned int omask;
|
||||
|
||||
sock=(struct sock*)get_handle_obj(current->process,req->handle,GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,&sock_ops);
|
||||
if (!sock)
|
||||
return;
|
||||
oevent = sock->event;
|
||||
omask = sock->mask;
|
||||
sock->mask = req->mask;
|
||||
sock->event = get_event_obj( current->process, req->event, GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE );
|
||||
sock->event = get_event_obj( current->process, req->event, EVENT_MODIFY_STATE );
|
||||
if (debug_level && sock->event) fprintf(stderr, "event ptr: %p\n", sock->event);
|
||||
sock_reselect( sock );
|
||||
if (sock->mask)
|
||||
sock->state |= WS_FD_NONBLOCKING;
|
||||
if (oevent)
|
||||
{
|
||||
if (oevent != sock->event)
|
||||
if ((oevent != sock->event) && (omask & WS_FD_SERVEVENT))
|
||||
/* if the service thread was waiting for the old event object,
|
||||
* we should now signal it, to let the service thread
|
||||
* object detect that it is now orphaned... */
|
||||
|
@ -470,7 +501,7 @@ DECL_HANDLER(get_socket_event)
|
|||
{
|
||||
if (req->s_event)
|
||||
{
|
||||
struct event *sevent = get_event_obj(current->process, req->s_event, GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE);
|
||||
struct event *sevent = get_event_obj(current->process, req->s_event, 0);
|
||||
if (sevent == sock->event)
|
||||
req->s_event = 0;
|
||||
release_object( sevent );
|
||||
|
|
Loading…
Reference in New Issue