1 /// [internal]
2 module libasync.internals.win32;
3 
4 version(Windows):
5 
6 public import core.sys.windows.windows;
7 public import core.sys.windows.winsock2;
8 public import core.sys.windows.com : GUID;
9 
10 extern(System) nothrow
11 {
12 	enum HWND HWND_MESSAGE = cast(HWND)-3;
13 	enum {
14 		GWLP_WNDPROC = -4,
15 		GWLP_HINSTANCE = -6,
16 		GWLP_HWNDPARENT = -8,
17 		GWLP_USERDATA = -21,
18 		GWLP_ID = -12,
19 	}
20 
21 	version(Win32){ // avoiding linking errors with out-of-the-box dmd
22 		alias SetWindowLongA SetWindowLongPtrA;
23 		alias GetWindowLongA GetWindowLongPtrA;
24 	} else {
25 		LONG_PTR SetWindowLongPtrA(HWND hWnd, int nIndex, LONG_PTR dwNewLong);
26 		LONG_PTR GetWindowLongPtrA(HWND hWnd, int nIndex);
27 	}
28 	LONG_PTR SetWindowLongPtrW(HWND hWnd, int nIndex, LONG_PTR dwNewLong);
29 	LONG_PTR GetWindowLongPtrW(HWND hWnd, int nIndex);
30 	LONG_PTR SetWindowLongA(HWND hWnd, int nIndex, LONG dwNewLong);
31 	LONG_PTR GetWindowLongA(HWND hWnd, int nIndex);
32 
33 	alias void function(DWORD, DWORD, OVERLAPPED*) LPOVERLAPPED_COMPLETION_ROUTINE;
34 
35 	HANDLE CreateEventW(SECURITY_ATTRIBUTES* lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName);
36 	BOOL PostThreadMessageW(DWORD idThread, UINT Msg, WPARAM wParam, LPARAM lParam);
37 	DWORD MsgWaitForMultipleObjectsEx(DWORD nCount, const(HANDLE) *pHandles, DWORD dwMilliseconds, DWORD dwWakeMask, DWORD dwFlags);
38 	static if (!is(typeof(&CreateFileW))) BOOL CloseHandle(HANDLE hObject);
39 	static if (!is(typeof(&CreateFileW))) HANDLE CreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
40 					   DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
41 	BOOL WriteFileEx(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, OVERLAPPED* lpOverlapped,
42 					 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
43 	BOOL ReadFileEx(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, OVERLAPPED* lpOverlapped,
44 					LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
45 	BOOL GetFileSizeEx(HANDLE hFile, long *lpFileSize);
46 	BOOL SetEndOfFile(HANDLE hFile);
47 	BOOL GetOverlappedResult(HANDLE hFile, OVERLAPPED* lpOverlapped, DWORD* lpNumberOfBytesTransferred, BOOL bWait);
48 	BOOL WSAGetOverlappedResult(SOCKET s, OVERLAPPED* lpOverlapped, DWORD* lpcbTransfer, BOOL fWait, DWORD* lpdwFlags);
49 	BOOL PostMessageW(HWND hwnd, UINT msg, WPARAM wPara, LPARAM lParam);
50 	BOOL PostThreadMessageA(HWND hwnd, UINT msg, WPARAM wPara, LPARAM lParam);
51 
52 	HANDLE GetStdHandle(DWORD nStdHandle);
53 	bool ReadFile(HANDLE hFile, void* lpBuffer, DWORD nNumberOfBytesRead, DWORD* lpNumberOfBytesRead, OVERLAPPED* lpOverlapped);
54 
55 	static if (__VERSION__ < 2065) {
56 		BOOL PeekMessageW(MSG *lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg);
57 		LONG DispatchMessageW(MSG *lpMsg);
58 
59 		enum {
60 			ERROR_ALREADY_EXISTS = 183,
61 			ERROR_IO_PENDING = 997
62 		}
63 	}
64 
65 	struct FILE_NOTIFY_INFORMATION {
66 		DWORD NextEntryOffset;
67 		DWORD Action;
68 		DWORD FileNameLength;
69 		WCHAR[1] FileName;
70 	}
71 
72 	BOOL ReadDirectoryChangesW(HANDLE hDirectory, void* lpBuffer, DWORD nBufferLength, BOOL bWatchSubtree, DWORD dwNotifyFilter, LPDWORD lpBytesReturned, void* lpOverlapped, void* lpCompletionRoutine);
73 	HANDLE FindFirstChangeNotificationW(LPCWSTR lpPathName, BOOL bWatchSubtree, DWORD dwNotifyFilter);
74 	HANDLE FindNextChangeNotification(HANDLE hChangeHandle);
75 
76 	enum{
77 		WSAPROTOCOL_LEN  = 255,
78 		MAX_PROTOCOL_CHAIN = 7,
79 	};
80 
81 	enum WSA_IO_INCOMPLETE = 996;
82 	enum WSA_IO_PENDING = 997;
83 
84 	struct WSAPROTOCOL_INFOW {
85 		DWORD            dwServiceFlags1;
86 		DWORD            dwServiceFlags2;
87 		DWORD            dwServiceFlags3;
88 		DWORD            dwServiceFlags4;
89 		DWORD            dwProviderFlags;
90 		GUID             ProviderId;
91 		DWORD            dwCatalogEntryId;
92 		WSAPROTOCOLCHAIN ProtocolChain;
93 		int              iVersion;
94 		int              iAddressFamily;
95 		int              iMaxSockAddr;
96 		int              iMinSockAddr;
97 		int              iSocketType;
98 		int              iProtocol;
99 		int              iProtocolMaxOffset;
100 		int              iNetworkByteOrder;
101 		int              iSecurityScheme;
102 		DWORD            dwMessageSize;
103 		DWORD            dwProviderReserved;
104 		WCHAR[WSAPROTOCOL_LEN+1] szProtocol;
105 	};
106 
107 	struct WSAPROTOCOLCHAIN {
108 		int ChainLen;
109 		DWORD[MAX_PROTOCOL_CHAIN] ChainEntries;
110 	};
111 
112 	struct WSABUF {
113 		size_t   len;
114 		ubyte *buf;
115 	}
116 
117 	struct WSAMSG {
118         sockaddr*  name;
119         int        namelen;
120         WSABUF*    lpBuffers;
121         DWORD      dwBufferCount;
122         WSABUF     Control;
123         DWORD      dwFlags;
124     }
125 
126 	struct WSAOVERLAPPEDX {
127 		ULONG_PTR Internal;
128 		ULONG_PTR InternalHigh;
129 		union {
130 			struct {
131 				DWORD Offset;
132 				DWORD OffsetHigh;
133 			}
134 			PVOID  Pointer;
135 		}
136 		HANDLE hEvent;
137 	}
138 
139 	enum {
140 		WSA_FLAG_OVERLAPPED = 0x01
141 	}
142 
143 	enum {
144 		FD_READ = 0x0001,
145 		FD_WRITE = 0x0002,
146 		FD_OOB = 0x0004,
147 		FD_ACCEPT = 0x0008,
148 		FD_CONNECT = 0x0010,
149 		FD_CLOSE = 0x0020,
150 		FD_QOS = 0x0040,
151 		FD_GROUP_QOS = 0x0080,
152 		FD_ROUTING_INTERFACE_CHANGE = 0x0100,
153 		FD_ADDRESS_LIST_CHANGE = 0x0200
154 	}
155 
156 	struct ADDRINFOEXW {
157 		int ai_flags;
158 		int ai_family;
159 		int ai_socktype;
160 		int ai_protocol;
161 		size_t ai_addrlen;
162 		LPCWSTR ai_canonname;
163 		sockaddr* ai_addr;
164 		void* ai_blob;
165 		size_t ai_bloblen;
166 		GUID* ai_provider;
167 		ADDRINFOEXW* ai_next;
168 	}
169 
170 	struct ADDRINFOA {
171 		int ai_flags;
172 		int ai_family;
173 		int ai_socktype;
174 		int ai_protocol;
175 		size_t ai_addrlen;
176 		LPSTR ai_canonname;
177 		sockaddr* ai_addr;
178 		ADDRINFOA* ai_next;
179 	}
180 
181 	struct ADDRINFOW {
182 		int ai_flags;
183 		int ai_family;
184 		int ai_socktype;
185 		int ai_protocol;
186 		size_t ai_addrlen;
187 		LPWSTR ai_canonname;
188 		sockaddr* ai_addr;
189 		ADDRINFOW* ai_next;
190 	}
191 
192 	enum {
193 		NS_ALL = 0,
194 		NS_DNS = 12
195 	}
196 
197 	struct WSAPROTOCOL_INFO {
198 		DWORD            dwServiceFlags1;
199 		DWORD            dwServiceFlags2;
200 		DWORD            dwServiceFlags3;
201 		DWORD            dwServiceFlags4;
202 		DWORD            dwProviderFlags;
203 		GUID             ProviderId;
204 		DWORD            dwCatalogEntryId;
205 		WSAPROTOCOLCHAIN ProtocolChain;
206 		int              iVersion;
207 		int              iAddressFamily;
208 		int              iMaxSockAddr;
209 		int              iMinSockAddr;
210 		int              iSocketType;
211 		int              iProtocol;
212 		int              iProtocolMaxOffset;
213 		int              iNetworkByteOrder;
214 		int              iSecurityScheme;
215 		DWORD            dwMessageSize;
216 		DWORD            dwProviderReserved;
217 		CHAR[WSAPROTOCOL_LEN+1] szProtocol;
218 	}
219 	alias sockaddr SOCKADDR;
220 
221 	enum SOMAXCONN = 0x7fffffff;
222 	auto SOMAXCONN_HINT(int b) { return -b; }
223 
224 	enum _SS_MAXSIZE = 128;           // Maximum size
225 	enum _SS_ALIGNSIZE = long.sizeof; // Desired alignment
226 
227 	enum _SS_PAD1SIZE = _SS_ALIGNSIZE - ushort.sizeof;
228 	enum _SS_PAD2SIZE = _SS_MAXSIZE - (ushort.sizeof + _SS_PAD1SIZE + _SS_ALIGNSIZE);
229 
230 	struct SOCKADDR_STORAGE {
231 		ushort ss_family;
232 		byte[_SS_PAD1SIZE] __ss_pad1;
233 		long __ss_align;
234 		byte[_SS_PAD2SIZE] __ss_pad2;
235 	}
236 	alias SOCKADDR_STORAGE* PSOCKADDR_STORAGE;
237 	alias SOCKADDR_STORAGE sockaddr_storage;
238 
239 	alias void function(DWORD, DWORD, WSAOVERLAPPEDX*, DWORD) LPWSAOVERLAPPED_COMPLETION_ROUTINEX;
240 	alias void function(DWORD, DWORD, WSAOVERLAPPEDX*) LPLOOKUPSERVICE_COMPLETION_ROUTINE;
241 	alias void* LPCONDITIONPROC;
242 	alias void* LPTRANSMIT_FILE_BUFFERS;
243 
244 	alias BOOL function(SOCKET sListenSocket,
245 	                    SOCKET sAcceptSocket,
246 	                    void* lpOutputBuffer,
247 	                    DWORD dwReceiveDataLength,
248 	                    DWORD dwLocalAddressLength,
249 	                    DWORD dwRemoteAddressLength,
250 	                    DWORD* lpdwBytesReceived,
251 	                    OVERLAPPED* lpOverlapped) LPFN_ACCEPTEX;
252 	auto WSAID_ACCEPTEX = GUID(0xb5367df1, 0xcbac, 0x11cf, [ 0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92 ]);
253 
254 	alias void function(void* lpOutputBuffer,
255 	                    DWORD dwReceiveDataLength,
256 	                    DWORD dwLocalAddressLength,
257 	                    DWORD dwRemoteAddressLength,
258 	                    sockaddr** LocalSockaddr,
259 	                    int* LocalSockaddrLength,
260 	                    sockaddr** RemoteSockaddr,
261 	                    int* RemoteSockaddrLength) LPFN_GETACCEPTEXSOCKADDRS;
262 	auto WSAID_GETACCEPTEXSOCKADDRS = GUID(0xb5367df2, 0xcbac, 0x11cf, [ 0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92 ]);
263 
264 	alias BOOL function(SOCKET s, sockaddr* name, int namelen, void* lpSendBuffer, DWORD dwSendDataLength, DWORD* lpdwBytesSent, OVERLAPPED* lpOverlapped) LPFN_CONNECTEX;
265 	auto WSAID_CONNECTEX = GUID(0x25a207b9, 0xddf3, 0x4660, [ 0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e ]);
266 
267 	alias BOOL function(SOCKET s, OVERLAPPED* lpOverlapped, DWORD  dwFlags, DWORD  dwReserved) LPFN_DISCONNECTEX;
268 	auto WSAID_DISCONNECTEX = GUID(0x7fda2e11, 0x8630, 0x436f, [ 0xa0, 0x31, 0xf5, 0x36, 0xa6, 0xee, 0xc1, 0x57 ]);
269 
270 	int WSAIoctl(SOCKET s, DWORD dwIoControlCode, void* lpvInBuffer, DWORD cbInBuffer, void* lpvOutBuffer, DWORD cbOutBuffer, DWORD* lpcbBytesReturned, WSAOVERLAPPEDX* lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINEX lpCompletionRoutine);
271 
272 	enum IOCPARM_MASK = 0x7f;
273 	enum uint IOC_VOID         = 0x20000000;
274 	enum uint IOC_OUT          = 0x40000000;
275 	enum uint IOC_IN           = 0x80000000;
276 	enum uint IOC_INOUT        = (IOC_IN|IOC_OUT);
277 
278 	enum uint IOC_UNIX         = 0x00000000;
279 	enum uint IOC_WS2          = 0x08000000;
280 	enum uint IOC_PROTOCOL     = 0x10000000;
281 	enum uint IOC_VENDOR       = 0x18000000;
282 
283 	auto _WSAIO(uint x,uint y)      { return (IOC_VOID|(x)|(y)); }
284 	auto _WSAIOR(uint x,uint y)     { return (IOC_OUT|(x)|(y)); }
285 	auto _WSAIOW(uint x,uint y)     { return (IOC_IN|(x)|(y)); }
286 	auto _WSAIORW(uint x,uint y)    { return (IOC_INOUT|(x)|(y)); }
287 
288 	enum SIO_GET_EXTENSION_FUNCTION_POINTER = _WSAIORW(IOC_WS2,6);
289 
290 	LPFN_ACCEPTEX AcceptEx;
291 	LPFN_GETACCEPTEXSOCKADDRS GetAcceptExSockaddrs;
292 	LPFN_CONNECTEX ConnectEx;
293 	LPFN_DISCONNECTEX DisconnectEx;
294 
295 	enum SO_UPDATE_ACCEPT_CONTEXT    = 0x700B;
296 	enum SO_UPDATE_CONNECT_CONTEXT   = 0x7010;
297 
298 	bool CancelIo(HANDLE hFile);
299 	bool CancelIOEx(HANDLE hFile, OVERLAPPED* lpOverlapped);
300 
301 	SOCKET WSAAccept(SOCKET s, sockaddr *addr, INT* addrlen, LPCONDITIONPROC lpfnCondition, DWORD_PTR dwCallbackData);
302 	int WSAAsyncSelect(SOCKET s, HWND hWnd, uint wMsg, sizediff_t lEvent);
303 	SOCKET WSASocketW(int af, int type, int protocol, WSAPROTOCOL_INFOW *lpProtocolInfo, uint g, DWORD dwFlags);
304 	int WSARecv(SOCKET s, WSABUF* lpBuffers, DWORD dwBufferCount, DWORD* lpNumberOfBytesRecvd, DWORD* lpFlags, in WSAOVERLAPPEDX* lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINEX lpCompletionRoutine);
305 	int WSASend(SOCKET s, in WSABUF* lpBuffers, DWORD dwBufferCount, DWORD* lpNumberOfBytesSent, DWORD dwFlags, in WSAOVERLAPPEDX* lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINEX lpCompletionRoutine);
306 	int WSARecvFrom(SOCKET s, WSABUF* lpBuffers, DWORD dwBufferCount, DWORD* lpNumberOfBytesRecvd, DWORD* lpFlags, sockaddr* lpFrom, INT* lpFromlen, in WSAOVERLAPPEDX* lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINEX lpCompletionRoutine);
307 	int WSASendTo(SOCKET s, in WSABUF* lpBuffers, DWORD dwBufferCount, DWORD* lpNumberOfBytesSent, DWORD dwFlags, sockaddr* lpTo, int iToLen, in WSAOVERLAPPEDX* lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINEX lpCompletionRoutine);
308 	int WSASendDisconnect(SOCKET s, WSABUF* lpOutboundDisconnectData);
309 	INT WSAStringToAddressA(in LPTSTR AddressString, INT AddressFamily, in WSAPROTOCOL_INFO* lpProtocolInfo, SOCKADDR* lpAddress, INT* lpAddressLength);
310 	INT WSAStringToAddressW(in LPWSTR AddressString, INT AddressFamily, in WSAPROTOCOL_INFOW* lpProtocolInfo, SOCKADDR* lpAddress, INT* lpAddressLength);
311 	INT WSAAddressToStringW(in SOCKADDR* lpsaAddress, DWORD dwAddressLength, in WSAPROTOCOL_INFO* lpProtocolInfo, LPWSTR lpszAddressString, DWORD* lpdwAddressStringLength);
312 	int GetAddrInfoExW(LPCWSTR pName, LPCWSTR pServiceName, DWORD dwNameSpace, GUID* lpNspId, const ADDRINFOEXW *pHints, ADDRINFOEXW **ppResult, timeval *timeout, WSAOVERLAPPEDX* lpOverlapped, LPLOOKUPSERVICE_COMPLETION_ROUTINE lpCompletionRoutine, HANDLE* lpNameHandle);
313 	int GetAddrInfoW(LPCWSTR pName, LPCWSTR pServiceName, const ADDRINFOW *pHints, ADDRINFOW **ppResult);
314 	int getaddrinfo(LPCSTR pName, LPCSTR pServiceName, const ADDRINFOA *pHints, ADDRINFOA **ppResult);
315 	void FreeAddrInfoW(ADDRINFOW* pAddrInfo);
316 	void FreeAddrInfoExW(ADDRINFOEXW* pAddrInfo);
317 	void freeaddrinfo(ADDRINFOA* ai);
318 	BOOL TransmitFile(SOCKET hSocket, HANDLE hFile, DWORD nNumberOfBytesToWrite, DWORD nNumberOfBytesPerSend, OVERLAPPED* lpOverlapped, LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers, DWORD dwFlags);
319 
320 	enum WM_USER = 0x0400;
321 
322 	enum {
323 		QS_ALLPOSTMESSAGE = 0x0100,
324 		QS_HOTKEY = 0x0080,
325 		QS_KEY = 0x0001,
326 		QS_MOUSEBUTTON = 0x0004,
327 		QS_MOUSEMOVE = 0x0002,
328 		QS_PAINT = 0x0020,
329 		QS_POSTMESSAGE = 0x0008,
330 		QS_RAWINPUT = 0x0400,
331 		QS_SENDMESSAGE = 0x0040,
332 		QS_TIMER = 0x0010,
333 
334 		QS_MOUSE = (QS_MOUSEMOVE | QS_MOUSEBUTTON),
335 		QS_INPUT = (QS_MOUSE | QS_KEY | QS_RAWINPUT),
336 		QS_ALLEVENTS = (QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY),
337 		QS_ALLINPUT = (QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY | QS_SENDMESSAGE),
338 	};
339 
340 	enum {
341 		MWMO_ALERTABLE = 0x0002,
342 		MWMO_INPUTAVAILABLE = 0x0004,
343 		MWMO_WAITALL = 0x0001,
344 	};
345 }