1 USING: alien alien.accessors alien.c-types byte-arrays
2 continuations destructors io.ports io.timeouts io.sockets
3 io.sockets io namespaces io.streams.duplex io.windows
5 io.windows.nt.backend windows.winsock kernel libc math sequences
6 threads classes.tuple.lib system combinators accessors ;
7 IN: io.windows.nt.sockets
9 : malloc-int ( object -- object )
10 "int" heap-size malloc tuck 0 set-alien-signed-4 ; inline
12 M: winnt WSASocket-flags ( -- DWORD )
15 : get-ConnectEx-ptr ( socket -- void* )
16 SIO_GET_EXTENSION_FUNCTION_POINTER
25 WSAIoctl SOCKET_ERROR = [
26 winsock-error-string throw
30 TUPLE: ConnectEx-args port
31 s* name* namelen* lpSendBuffer* dwSendDataLength*
32 lpdwBytesSent* lpOverlapped* ptr* ;
34 : wait-for-socket ( args -- n )
35 [ lpOverlapped*>> ] [ port>> ] bi twiddle-thumbs ;
37 : <ConnectEx-args> ( sockaddr size -- ConnectEx )
44 (make-overlapped) >>lpOverlapped* ;
46 : call-ConnectEx ( ConnectEx -- )
47 ConnectEx-args >tuple*<
49 { "SOCKET" "sockaddr_in*" "int" "PVOID" "DWORD" "LPDWORD" "void*" }
50 "stdcall" alien-indirect drop
51 winsock-error-string [ throw ] when* ;
53 M: object establish-connection ( client-out remote -- )
54 make-sockaddr/size <ConnectEx-args>
56 dup port>> handle>> handle>> >>s*
57 dup s*>> get-ConnectEx-ptr >>ptr*
59 wait-for-socket drop ;
61 TUPLE: AcceptEx-args port
62 sListenSocket* sAcceptSocket* lpOutputBuffer* dwReceiveDataLength*
63 dwLocalAddressLength* dwRemoteAddressLength* lpdwBytesReceived* lpOverlapped* ;
65 : init-accept-buffer ( addr AcceptEx -- )
66 swap sockaddr-type heap-size 16 +
67 [ >>dwLocalAddressLength* ] [ >>dwRemoteAddressLength* ] bi
68 dup dwLocalAddressLength*>> 2 * malloc &free >>lpOutputBuffer*
71 : <AcceptEx-args> ( server addr -- AcceptEx )
73 2dup init-accept-buffer
74 swap SOCK_STREAM open-socket |dispose handle>> >>sAcceptSocket*
75 over handle>> handle>> >>sListenSocket*
77 0 >>dwReceiveDataLength*
78 f >>lpdwBytesReceived*
79 (make-overlapped) >>lpOverlapped* ;
81 : call-AcceptEx ( AcceptEx -- )
82 AcceptEx-args >tuple*< AcceptEx drop
83 winsock-error-string [ throw ] when* ;
85 : extract-remote-address ( AcceptEx -- sockaddr )
88 [ dwReceiveDataLength*>> ]
89 [ dwLocalAddressLength*>> ]
90 [ dwRemoteAddressLength*>> ]
95 [ 0 <int> GetAcceptExSockaddrs ] keep *void* ;
97 M: object (accept) ( server addr -- handle sockaddr )
102 [ wait-for-socket drop ]
103 [ sAcceptSocket*>> <win32-socket> ]
104 [ extract-remote-address ]
108 TUPLE: WSARecvFrom-args port
109 s* lpBuffers* dwBufferCount* lpNumberOfBytesRecvd*
110 lpFlags* lpFrom* lpFromLen* lpOverlapped* lpCompletionRoutine* ;
112 : make-receive-buffer ( -- WSABUF )
113 "WSABUF" malloc-object &free
114 default-buffer-size get over set-WSABUF-len
115 default-buffer-size get malloc &free over set-WSABUF-buf ;
117 : <WSARecvFrom-args> ( datagram -- WSARecvFrom )
120 dup port>> handle>> handle>> >>s*
121 dup port>> addr>> sockaddr-type heap-size
122 [ malloc &free >>lpFrom* ]
123 [ malloc-int &free >>lpFromLen* ] bi
124 make-receive-buffer >>lpBuffers*
126 0 malloc-int &free >>lpFlags*
127 0 malloc-int &free >>lpNumberOfBytesRecvd*
128 (make-overlapped) >>lpOverlapped* ;
130 : call-WSARecvFrom ( WSARecvFrom -- )
131 WSARecvFrom-args >tuple*< WSARecvFrom socket-error* ;
133 : parse-WSARecvFrom ( n WSARecvFrom -- packet sockaddr )
134 [ lpBuffers*>> WSABUF-buf swap memory>byte-array ]
135 [ [ lpFrom*>> ] [ lpFromLen*>> *int ] bi memory>byte-array ] bi ;
137 M: winnt (receive) ( datagram -- packet addrspec )
142 [ parse-WSARecvFrom ]
146 TUPLE: WSASendTo-args port
147 s* lpBuffers* dwBufferCount* lpNumberOfBytesSent*
148 dwFlags* lpTo* iToLen* lpOverlapped* lpCompletionRoutine* ;
150 : make-send-buffer ( packet -- WSABUF )
151 "WSABUF" malloc-object &free
152 [ >r malloc-byte-array &free r> set-WSABUF-buf ]
153 [ >r length r> set-WSABUF-len ]
157 : <WSASendTo-args> ( packet addrspec datagram -- WSASendTo )
160 dup port>> handle>> handle>> >>s*
161 swap make-sockaddr/size
162 >r malloc-byte-array &free
163 r> [ >>lpTo* ] [ >>iToLen* ] bi*
164 swap make-send-buffer >>lpBuffers*
167 0 <uint> >>lpNumberOfBytesSent*
168 (make-overlapped) >>lpOverlapped* ;
170 : call-WSASendTo ( WSASendTo -- )
171 WSASendTo-args >tuple*< WSASendTo socket-error* ;
173 M: winnt (send) ( packet addrspec datagram -- )
177 [ wait-for-socket drop ]