1 module photon.windows.support;
2 version(Windows):
3 import core.sys.windows.core;
4 import core.sys.windows.winsock2;
5 import std.format;
6 
7 struct WSABUF 
8 {
9     uint length;
10     void* buf;
11 }
12 
13 extern(Windows) SOCKET WSASocketW(
14   int                af,
15   int                type,
16   int                protocol,
17   void*              lpProtocolInfo,
18   WORD               g,
19   DWORD              dwFlags
20 );
21 
22 // hackish, we do not use LPCONDITIONPROC
23 alias LPCONDITIONPROC = void*;
24 alias LPWSABUF = WSABUF*;
25 
26 extern(Windows) SOCKET WSAAccept(
27   SOCKET          s,
28   sockaddr        *addr,
29   LPINT           addrlen,
30   LPCONDITIONPROC lpfnCondition,
31   DWORD_PTR       dwCallbackData
32 );
33 
34 extern(Windows) int WSARecv(
35   SOCKET                             s,
36   LPWSABUF                           lpBuffers,
37   DWORD                              dwBufferCount,
38   LPDWORD                            lpNumberOfBytesRecvd,
39   LPDWORD                            lpFlags,
40   LPWSAOVERLAPPED                    lpOverlapped,
41   LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
42 );
43 
44 extern(Windows) int WSASend(
45   SOCKET                             s,
46   LPWSABUF                           lpBuffers,
47   DWORD                              dwBufferCount,
48   LPDWORD                            lpNumberOfBytesSent,
49   DWORD                              dwFlags,
50   LPWSAOVERLAPPED                    lpOverlapped,
51   LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
52 );
53 
54 struct OVERLAPPED_ENTRY {
55   ULONG_PTR    lpCompletionKey;
56   LPOVERLAPPED lpOverlapped;
57   ULONG_PTR    Internal;
58   DWORD        dwNumberOfBytesTransferred;
59 }
60 
61 alias LPOVERLAPPED_ENTRY = OVERLAPPED_ENTRY*;
62 
63 extern(Windows) BOOL GetQueuedCompletionStatusEx(
64   HANDLE             CompletionPort,
65   LPOVERLAPPED_ENTRY lpCompletionPortEntries,
66   ULONG              ulCount,
67   PULONG             ulNumEntriesRemoved,
68   DWORD              dwMilliseconds,
69   BOOL               fAlertable
70 );
71 
72 enum WSA_FLAG_OVERLAPPED  =  0x01;
73 
74 struct TP_POOL;
75 
76 alias PTP_POOL = TP_POOL*;
77 
78 extern(Windows) PTP_POOL CreateThreadpool(
79   PVOID reserved
80 );
81 
82 extern(Windows) void SetThreadpoolThreadMaximum(
83   PTP_POOL ptpp,
84   DWORD    cthrdMost
85 );
86 
87 extern(Windows) BOOL SetThreadpoolThreadMinimum(
88   PTP_POOL ptpp,
89   DWORD    cthrdMic
90 );
91 
92 alias TP_VERSION = DWORD;
93 alias PTP_VERSION = TP_VERSION*;
94 
95 struct TP_CALLBACK_INSTANCE;
96 alias PTP_CALLBACK_INSTANCE = TP_CALLBACK_INSTANCE*;
97 
98 alias PTP_SIMPLE_CALLBACK = extern(Windows) VOID function(PTP_CALLBACK_INSTANCE, PVOID);
99 
100 enum TP_CALLBACK_PRIORITY : int {
101   TP_CALLBACK_PRIORITY_HIGH,
102   TP_CALLBACK_PRIORITY_NORMAL,
103   TP_CALLBACK_PRIORITY_LOW,
104   TP_CALLBACK_PRIORITY_INVALID,
105   TP_CALLBACK_PRIORITY_COUNT = TP_CALLBACK_PRIORITY_INVALID
106 }
107 
108 struct TP_POOL_STACK_INFORMATION {
109   SIZE_T StackReserve;
110   SIZE_T StackCommit;
111 }
112 alias PTP_POOL_STACK_INFORMATION = TP_POOL_STACK_INFORMATION*;
113 
114 struct TP_CLEANUP_GROUP;
115 alias PTP_CLEANUP_GROUP = TP_CLEANUP_GROUP*;
116 
117 alias PTP_CLEANUP_GROUP_CANCEL_CALLBACK = extern(Windows) VOID function(PVOID, PVOID);
118 
119 struct ACTIVATION_CONTEXT;
120 
121 struct TP_CALLBACK_ENVIRON_V3 {
122   TP_VERSION Version;
123   PTP_POOL Pool;
124   PTP_CLEANUP_GROUP CleanupGroup;
125   PTP_CLEANUP_GROUP_CANCEL_CALLBACK CleanupGroupCancelCallback;
126   PVOID RaceDll;
127   ACTIVATION_CONTEXT* ActivationContext;
128   PTP_SIMPLE_CALLBACK FinalizationCallback;
129   DWORD Flags;
130   TP_CALLBACK_PRIORITY CallbackPriority;
131   DWORD Size;
132 }
133 
134 alias TP_CALLBACK_ENVIRON = TP_CALLBACK_ENVIRON_V3;
135 alias PTP_CALLBACK_ENVIRON = TP_CALLBACK_ENVIRON*;
136 
137 VOID InitializeThreadpoolEnvironment(PTP_CALLBACK_ENVIRON cbe) {
138   cbe.Pool = NULL;
139   cbe.CleanupGroup = NULL;
140   cbe.CleanupGroupCancelCallback = NULL;
141   cbe.RaceDll = NULL;
142   cbe.ActivationContext = NULL;
143   cbe.FinalizationCallback = NULL;
144   cbe.Flags = 0;
145   cbe.Version = 3;
146   cbe.CallbackPriority = TP_CALLBACK_PRIORITY.TP_CALLBACK_PRIORITY_NORMAL;
147   cbe.Size = TP_CALLBACK_ENVIRON.sizeof;
148 }
149 
150 extern(Windows) void CloseThreadpool(
151   PTP_POOL ptpp
152 );
153 
154 // inline "function"
155 VOID SetThreadpoolCallbackPool(PTP_CALLBACK_ENVIRON cbe, PTP_POOL pool) { cbe.Pool = pool; }
156 
157 struct TP_WORK;
158 alias PTP_WORK = TP_WORK*;
159 
160 struct TP_WAIT;
161 alias PTP_WAIT = TP_WAIT*;
162 
163 struct TP_TIMER;
164 alias PTP_TIMER = TP_TIMER*;
165 
166 alias TP_WAIT_RESULT = DWORD;
167 
168 alias PTP_WORK_CALLBACK = extern(Windows) VOID function (PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WORK Work);
169 alias PTP_WAIT_CALLBACK = extern(Windows) VOID function (PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WAIT  Wait, TP_WAIT_RESULT WaitResult);
170 alias PTP_TIMER_CALLBACK = extern(Windows) VOID function(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_TIMER Timer);
171 
172 extern(Windows) PTP_WORK CreateThreadpoolWork(
173   PTP_WORK_CALLBACK    pfnwk,
174   PVOID                pv,
175   PTP_CALLBACK_ENVIRON pcbe
176 );
177 
178 extern(Windows) PTP_WAIT CreateThreadpoolWait(PTP_WAIT_CALLBACK pfnwa, PVOID pv, PTP_CALLBACK_ENVIRON pcbe);
179 
180 extern(Windows) void SubmitThreadpoolWork(
181   PTP_WORK pwk
182 );
183 
184 extern(Windows) void CloseThreadpoolWork(
185   PTP_WORK pwk
186 );
187 
188 extern(Windows) void SetThreadpoolWait(
189   PTP_WAIT  pwa,
190   HANDLE    h,
191   PFILETIME pftTimeout
192 );
193 
194 extern(Windows) void CloseThreadpoolWait(
195   PTP_WAIT pwa
196 );
197 
198 extern(Windows) PTP_TIMER CreateThreadpoolTimer(
199   PTP_TIMER_CALLBACK   pfnti,
200   PVOID                pv,
201   PTP_CALLBACK_ENVIRON pcbe
202 );
203 
204 extern(Windows) void SetThreadpoolTimer(
205   PTP_TIMER pti,
206   PFILETIME pftDueTime,
207   DWORD     msPeriod,
208   DWORD     msWindowLength
209 );
210 
211 extern(Windows) void CloseThreadpoolTimer(
212   PTP_TIMER pti
213 );
214 
215 
216 void outputToConsole(const(wchar)[] msg)
217 {
218     HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
219     uint size = cast(uint)msg.length;
220     WriteConsole(output, msg.ptr, size, &size, null);
221 }
222 
223 void logf(T...)(const(wchar)[] fmt, T args)
224 {
225     debug(photon) try {
226         formattedWrite(&outputToConsole, fmt, args);
227         formattedWrite(&outputToConsole, "\n");
228     }
229     catch (Exception e) {
230         outputToConsole("ARGH!"w);
231     }
232 }
233