ReactOS 0.4.15-dev-8419-g7f0e8a3
dthread.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WinSock 2 API
4 * FILE: dll/win32/ws2_32/src/dthread.c
5 * PURPOSE: Thread Object
6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
7 */
8
9/* INCLUDES ******************************************************************/
10
11#include <ws2_32.h>
12
13/* FUNCTIONS *****************************************************************/
14
18{
20 BOOL GotMessage = FALSE;
21
22 /* Get the message */
23 GotMessage = PeekMessage(&Message, NULL, 0, 0, PM_REMOVE);
24
25 /* Check if we got one */
26 if (GotMessage)
27 {
28 /* Process it */
31 }
32
33 /* return */
34 return GotMessage;
35}
36
37BOOL
40{
42
43 /* Set thread as blocking, set cancel callback and the clear cancel flag */
44 Thread->Blocking = TRUE;
45 Thread->CancelBlockingCall = (LPWSPCANCELBLOCKINGCALL)Context;
46 Thread->Cancelled = FALSE;
47
48 /* Call the blocking hook */
49 while (Thread->BlockingHook());
50
51 /* We're not blocking anymore */
52 Thread->Blocking = FALSE;
53
54 /* Return whether or not we were cancelled */
55 return !Thread->Cancelled;
56}
57
61 IN FARPROC BlockingHook)
62{
63 FARPROC OldHook = Thread->BlockingHook;
64
65 /* Check if we're resetting to our default hook */
66 if (BlockingHook == (FARPROC)WsThreadDefaultBlockingHook)
67 {
68 /* Clear out the blocking callback */
69 Thread->BlockingCallback = NULL;
70 }
71 else
72 {
73 /* Set the blocking callback */
74 Thread->BlockingCallback = WsThreadBlockingCallback;
75 }
76
77 /* Set the new blocking hook and return the previous */
78 Thread->BlockingHook = BlockingHook;
79 return OldHook;
80}
81
85{
86 /* Reset the hook to the default, and remove the callback */
88 Thread->BlockingCallback = NULL;
89
90 /* Return success */
91 return ERROR_SUCCESS;
92}
93
97{
99
100 /* Make sure that the Thread is really in a blocking call */
101 if (!Thread->Blocking) return WSAEINVAL;
102
103 /* Make sure we haven't already been cancelled */
104 if (!Thread->Cancelled)
105 {
106 /* Call the cancel procedure */
107 ReturnValue = Thread->CancelBlockingCall(&ErrorCode);
108 if (ReturnValue != ERROR_SUCCESS) return ErrorCode;
109
110 /* Set us as cancelled */
111 Thread->Cancelled = TRUE;
112 }
113
114 /* Success */
115 return ERROR_SUCCESS;
116}
117
119WSAAPI
121{
122 /* See if it already exists */
123 if (!Thread->ProtocolInfo)
124 {
125 /* We don't have a buffer; allocate it */
126 Thread->ProtocolInfo = HeapAlloc(WsSockHeap, 0, sizeof(WSPROTO_BUFFER));
127 }
128
129 /* Return it */
130 return Thread->ProtocolInfo;
131}
132
134WSAAPI
136{
138
139 /* Allocate the object */
141 if (Thread)
142 {
143 /* Set non-zero data */
145 }
146
147 /* Return it */
148 return Thread;
149}
150
151DWORD
152WSAAPI
154{
156
157 /* Check if we have a valid TLS */
159 {
160 /* TLS was already OK */
162 }
163
164 /* Return */
165 return ErrorCode;
166}
167
168VOID
169WSAAPI
171{
172}
173
174DWORD
175WSAAPI
178{
180
181 /* Set the process */
182 Thread->Process = Process;
183
184 /* Get the helper device */
185 if ((WsProcGetAsyncHelper(Process, &Thread->AsyncHelper)) == ERROR_SUCCESS)
186 {
187 /* Initialize a WAH Thread ID */
188 if ((WahOpenCurrentThread(Thread->AsyncHelper,
189 &Thread->WahThreadId)) == ERROR_SUCCESS)
190 {
191 /* Success */
193 }
194 }
195
196 /* Return */
197 return ErrorCode;
198}
199
200VOID
201WSAAPI
203{
204 /* Remove the blocking hook */
205 Thread->BlockingHook = NULL;
206
207 /* Free our buffers */
208 if (Thread->Hostent) HeapFree(WsSockHeap, 0, Thread->Hostent);
209 if (Thread->Servent) HeapFree(WsSockHeap, 0, Thread->Servent);
210 if (Thread->ProtocolInfo) HeapFree(WsSockHeap, 0, Thread->ProtocolInfo);
211
212 /* Clear the TLS */
214
215 /* Close the WAH Handle */
216 WahCloseThread(Thread->AsyncHelper, &Thread->WahThreadId);
217
218 /* Unlink the process and free us */
219 Thread->Process = NULL;
221}
222
223VOID
224WSAAPI
226{
228
229 /* Make sure we have TLS */
231 {
232 /* Get the thread */
233 if ((Thread = TlsGetValue(TlsIndex)))
234 {
235 /* Delete it */
238 }
239 }
240}
241
242DWORD
243WSAAPI
245 IN PWSTHREAD *CurrentThread)
246{
249
250 /* Make sure we have TLS */
252 {
253 /* Allocate the thread */
254 if ((Thread = WsThreadAllocate()))
255 {
256 /* Initialize it */
258 {
259 /* Set the TLS */
261 {
262 /* Return it and success */
263 *CurrentThread = Thread;
265 }
266 }
267
268 /* Check for any failures */
270 }
271 }
272
273 /* Return */
274 return ErrorCode;
275}
276
277DWORD
278WSAAPI
281{
282 /* Get the thread */
283 if ((*Thread = TlsGetValue(TlsIndex)))
284 {
285 /* Success */
286 return ERROR_SUCCESS;
287 }
288 else
289 {
290 /* We failed, initialize it */
292 }
293}
294
296WSAAPI
298{
300
301 /* Get the thread */
302 if ((Thread = TlsGetValue(TlsIndex)))
303 {
304 /* Return the ID */
305 return &Thread->WahThreadId;
306 }
307 else
308 {
309 /* Not a valid thread */
310 return NULL;
311 }
312}
313
315WSAAPI
317 IN LPBLOB Blob)
318{
319 /* Check if our buffer is too small */
320 if (Thread->HostentSize < Blob->cbSize)
321 {
322 /* Delete the current buffer and allocate a new one */
323 HeapFree(WsSockHeap, 0, Thread->Hostent);
324 Thread->Hostent = HeapAlloc(WsSockHeap, 0, Blob->cbSize);
325
326 /* Set the new size */
327 Thread->HostentSize = Blob->cbSize;
328 }
329
330 /* Do we have a buffer? */
331 if (Thread->Hostent)
332 {
333 /* Copy the data inside */
334 RtlMoveMemory(Thread->Hostent, Blob->pBlobData, Blob->cbSize);
335 }
336 else
337 {
338 /* No buffer space! */
339 Thread->HostentSize = 0;
341 }
342
343 /* Return the buffer */
344 return (PHOSTENT)Thread->Hostent;
345}
346
348WSAAPI
350 IN LPBLOB Blob)
351{
352 /* Check if our buffer is too small */
353 if (Thread->ServentSize < Blob->cbSize)
354 {
355 /* Delete the current buffer and allocate a new one */
356 HeapFree(WsSockHeap, 0, Thread->Servent);
357 Thread->Servent = HeapAlloc(WsSockHeap, 0, Blob->cbSize);
358
359 /* Set the new size */
360 Thread->ServentSize = Blob->cbSize;
361 }
362
363 /* Do we have a buffer? */
364 if (Thread->Servent)
365 {
366 /* Copy the data inside */
367 RtlMoveMemory(Thread->Servent, Blob->pBlobData, Blob->cbSize);
368 }
369 else
370 {
371 /* No buffer space! */
372 Thread->ServentSize = 0;
374 }
375
376 /* Return the buffer */
377 return (PSERVENT)Thread->Servent;
378}
379
UINT32 void void ** ReturnValue
Definition: acevents.h:216
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
int(* FARPROC)()
Definition: compat.h:36
#define SetLastError(x)
Definition: compat.h:752
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
LPVOID WINAPI TlsGetValue(IN DWORD Index)
Definition: thread.c:1240
BOOL WINAPI TlsSetValue(IN DWORD Index, IN LPVOID Value)
Definition: thread.c:1276
static const WCHAR Message[]
Definition: register.c:74
DWORD WINAPI WahOpenCurrentThread(IN HANDLE ApcHelperHandle, OUT LPWSATHREADID ThreadId)
Definition: apc.c:118
DWORD WINAPI WahCloseThread(IN HANDLE ApcHelperHandle, IN LPWSATHREADID ThreadId)
Definition: apc.c:59
DWORD WSAAPI WsThreadDefaultBlockingHook(VOID)
Definition: dthread.c:17
BOOL WSAAPI WsThreadBlockingCallback(IN DWORD_PTR Context)
Definition: dthread.c:39
DWORD WSAAPI WsThreadInitialize(IN PWSTHREAD Thread, IN PWSPROCESS Process)
Definition: dthread.c:176
DWORD WSAAPI WsThreadStartup(VOID)
Definition: dthread.c:153
PSERVENT WSAAPI WsThreadBlobToServent(IN PWSTHREAD Thread, IN LPBLOB Blob)
Definition: dthread.c:349
LPWSATHREADID WSAAPI WsThreadGetThreadId(IN PWSPROCESS Process)
Definition: dthread.c:297
DWORD WSAAPI WsThreadGetCurrentThread(IN PWSPROCESS Process, IN PWSTHREAD *Thread)
Definition: dthread.c:279
VOID WSAAPI WsThreadCleanup(VOID)
Definition: dthread.c:170
PWSPROTO_BUFFER WSAAPI WsThreadGetProtoBuffer(IN PWSTHREAD Thread)
Definition: dthread.c:120
PHOSTENT WSAAPI WsThreadBlobToHostent(IN PWSTHREAD Thread, IN LPBLOB Blob)
Definition: dthread.c:316
DWORD WSAAPI WsThreadCancelBlockingCall(IN PWSTHREAD Thread)
Definition: dthread.c:96
VOID WSAAPI WsThreadDestroyCurrentThread(VOID)
Definition: dthread.c:225
FARPROC WSAAPI WsThreadSetBlockingHook(IN PWSTHREAD Thread, IN FARPROC BlockingHook)
Definition: dthread.c:60
DWORD WSAAPI WsThreadUnhookBlockingHook(IN PWSTHREAD Thread)
Definition: dthread.c:84
PWSTHREAD WSAAPI WsThreadAllocate(VOID)
Definition: dthread.c:135
VOID WSAAPI WsThreadDelete(IN PWSTHREAD Thread)
Definition: dthread.c:202
DWORD WSAAPI WsThreadCreate(IN PWSPROCESS Process, IN PWSTHREAD *CurrentThread)
Definition: dthread.c:244
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
Definition: nspapi.h:57
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
uint32_t DWORD_PTR
Definition: typedefs.h:65
int32_t INT
Definition: typedefs.h:58
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define TLS_OUT_OF_INDEXES
Definition: winbase.h:549
#define WSASYSCALLFAILURE
Definition: winerror.h:1994
#define WSAEINVAL
Definition: winerror.h:1946
#define WSA_NOT_ENOUGH_MEMORY
Definition: winsock2.h:620
#define WSAAPI
Definition: winsock2.h:605
BOOL WINAPI TranslateMessage(_In_ const MSG *)
#define PM_REMOVE
Definition: winuser.h:1196
#define PeekMessage
Definition: winuser.h:5839
#define DispatchMessage
Definition: winuser.h:5774
HANDLE WsSockHeap
Definition: dllmain.c:21
INT WSAAPI WsProcGetAsyncHelper(IN PWSPROCESS Process, OUT PHANDLE Handle)
Definition: dprocess.c:107
#define TlsIndex
Definition: ws2_32p.h:277
int(WSPAPI * LPWSPCANCELBLOCKINGCALL)(_Out_ LPINT lpErrno)
Definition: ws2spi.h:96