Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS WinSock 2 API * FILE: dll/win32/ws2_32/src/dthread.c * PURPOSE: Thread Object * PROGRAMMER: Alex Ionescu (alex@relsoft.net) */
/* INCLUDES ******************************************************************/
#include <ws2_32.h>
/* FUNCTIONS *****************************************************************/
DWORDWSAAPIWsThreadDefaultBlockingHook(VOID){ MSG Message; BOOL GotMessage = FALSE;
/* Get the message */ GotMessage = PeekMessage(&Message, NULL, 0, 0, PM_REMOVE);
/* Check if we got one */ if (GotMessage) { /* Process it */ TranslateMessage(&Message); DispatchMessage(&Message); }
/* return */ return GotMessage;}
BOOLWSAAPIWsThreadBlockingCallback(IN DWORD_PTR Context){ PWSTHREAD Thread = TlsGetValue(TlsIndex);
/* Set thread as blocking, set cancel callback and the clear cancel flag */ Thread->Blocking = TRUE; Thread->CancelBlockingCall = (LPWSPCANCELBLOCKINGCALL)Context; Thread->Cancelled = FALSE;
/* Call the blocking hook */ while (Thread->BlockingHook());
/* We're not blocking anymore */ Thread->Blocking = FALSE;
/* Return whether or not we were cancelled */ return !Thread->Cancelled;}
FARPROCWSAAPIWsThreadSetBlockingHook(IN PWSTHREAD Thread, IN FARPROC BlockingHook){ FARPROC OldHook = Thread->BlockingHook;
/* Check if we're resetting to our default hook */ if (BlockingHook == (FARPROC)WsThreadDefaultBlockingHook) { /* Clear out the blocking callback */ Thread->BlockingCallback = NULL; } else { /* Set the blocking callback */ Thread->BlockingCallback = WsThreadBlockingCallback; }
/* Set the new blocking hook and return the previous */ Thread->BlockingHook = BlockingHook; return OldHook;}
DWORDWSAAPIWsThreadUnhookBlockingHook(IN PWSTHREAD Thread){ /* Reset the hook to the default, and remove the callback */ Thread->BlockingHook = (FARPROC)WsThreadDefaultBlockingHook; Thread->BlockingCallback = NULL;
/* Return success */ return ERROR_SUCCESS;}
DWORDWSAAPIWsThreadCancelBlockingCall(IN PWSTHREAD Thread){ INT ErrorCode, ReturnValue;
/* Make sure that the Thread is really in a blocking call */ if (!Thread->Blocking) return WSAEINVAL;
/* Make sure we haven't already been cancelled */ if (!Thread->Cancelled) { /* Call the cancel procedure */ ReturnValue = Thread->CancelBlockingCall(&ErrorCode); if (ReturnValue != ERROR_SUCCESS) return ErrorCode;
/* Set us as cancelled */ Thread->Cancelled = TRUE; }
/* Success */ return ERROR_SUCCESS;}
PWSPROTO_BUFFERWSAAPIWsThreadGetProtoBuffer(IN PWSTHREAD Thread){ /* See if it already exists */ if (!Thread->ProtocolInfo) { /* We don't have a buffer; allocate it */ Thread->ProtocolInfo = HeapAlloc(WsSockHeap, 0, sizeof(WSPROTO_BUFFER)); }
/* Return it */ return Thread->ProtocolInfo;}
PWSTHREADWSAAPIWsThreadAllocate(VOID){ PWSTHREAD Thread;
/* Allocate the object */ Thread = HeapAlloc(WsSockHeap, HEAP_ZERO_MEMORY, sizeof(*Thread)); if (Thread) { /* Set non-zero data */ Thread->BlockingHook = (FARPROC)WsThreadDefaultBlockingHook; }
/* Return it */ return Thread;}
DWORDWSAAPIWsThreadStartup(VOID){ INT ErrorCode = WSASYSCALLFAILURE;
/* Check if we have a valid TLS */ if (TlsIndex != TLS_OUT_OF_INDEXES) { /* TLS was already OK */ ErrorCode = ERROR_SUCCESS; }
/* Return */ return ErrorCode;}
VOIDWSAAPIWsThreadCleanup(VOID){}
DWORDWSAAPIWsThreadInitialize(IN PWSTHREAD Thread, IN PWSPROCESS Process){ INT ErrorCode = WSASYSCALLFAILURE;
/* Set the process */ Thread->Process = Process;
/* Get the helper device */ if ((WsProcGetAsyncHelper(Process, &Thread->AsyncHelper)) == ERROR_SUCCESS) { /* Initialize a WAH Thread ID */ if ((WahOpenCurrentThread(Thread->AsyncHelper, &Thread->WahThreadId)) == ERROR_SUCCESS) { /* Success */ ErrorCode = ERROR_SUCCESS; } }
/* Return */ return ErrorCode;}
VOIDWSAAPIWsThreadDelete(IN PWSTHREAD Thread){ /* Remove the blocking hook */ Thread->BlockingHook = NULL;
/* Free our buffers */ if (Thread->Hostent) HeapFree(WsSockHeap, 0, Thread->Hostent); if (Thread->Servent) HeapFree(WsSockHeap, 0, Thread->Servent); if (Thread->ProtocolInfo) HeapFree(WsSockHeap, 0, Thread->ProtocolInfo);
/* Clear the TLS */ TlsSetValue(TlsIndex, NULL);
/* Close the WAH Handle */ WahCloseThread(Thread->AsyncHelper, &Thread->WahThreadId);
/* Unlink the process and free us */ Thread->Process = NULL; HeapFree(WsSockHeap, 0, Thread);}
VOIDWSAAPIWsThreadDestroyCurrentThread(VOID){ PWSTHREAD Thread;
/* Make sure we have TLS */ if (TlsIndex != TLS_OUT_OF_INDEXES) { /* Get the thread */ if ((Thread = TlsGetValue(TlsIndex))) { /* Delete it */ WsThreadDelete(Thread); TlsSetValue(TlsIndex, 0); } }}
DWORDWSAAPIWsThreadCreate(IN PWSPROCESS Process, IN PWSTHREAD *CurrentThread){ PWSTHREAD Thread = NULL; INT ErrorCode = WSASYSCALLFAILURE;
/* Make sure we have TLS */ if (TlsIndex != TLS_OUT_OF_INDEXES) { /* Allocate the thread */ if ((Thread = WsThreadAllocate())) { /* Initialize it */ if (WsThreadInitialize(Thread, Process) == ERROR_SUCCESS) { /* Set the TLS */ if (TlsSetValue(TlsIndex, Thread)) { /* Return it and success */ *CurrentThread = Thread; ErrorCode = ERROR_SUCCESS; } }
/* Check for any failures */ if (ErrorCode != ERROR_SUCCESS) WsThreadDelete(Thread); } }
/* Return */ return ErrorCode;}
DWORDWSAAPIWsThreadGetCurrentThread(IN PWSPROCESS Process, IN PWSTHREAD *Thread){ /* Get the thread */ if ((*Thread = TlsGetValue(TlsIndex))) { /* Success */ return ERROR_SUCCESS; } else { /* We failed, initialize it */ return WsThreadCreate(Process, Thread); }}
LPWSATHREADIDWSAAPIWsThreadGetThreadId(IN PWSPROCESS Process){ PWSTHREAD Thread;
/* Get the thread */ if ((Thread = TlsGetValue(TlsIndex))) { /* Return the ID */ return &Thread->WahThreadId; } else { /* Not a valid thread */ return NULL; }}
PHOSTENTWSAAPIWsThreadBlobToHostent(IN PWSTHREAD Thread, IN LPBLOB Blob){ /* Check if our buffer is too small */ if (Thread->HostentSize < Blob->cbSize) { /* Delete the current buffer and allocate a new one */ HeapFree(WsSockHeap, 0, Thread->Hostent); Thread->Hostent = HeapAlloc(WsSockHeap, 0, Blob->cbSize);
/* Set the new size */ Thread->HostentSize = Blob->cbSize; }
/* Do we have a buffer? */ if (Thread->Hostent) { /* Copy the data inside */ RtlMoveMemory(Thread->Hostent, Blob->pBlobData, Blob->cbSize); } else { /* No buffer space! */ Thread->HostentSize = 0; SetLastError(WSA_NOT_ENOUGH_MEMORY); }
/* Return the buffer */ return (PHOSTENT)Thread->Hostent;}
PSERVENTWSAAPIWsThreadBlobToServent(IN PWSTHREAD Thread, IN LPBLOB Blob){ /* Check if our buffer is too small */ if (Thread->ServentSize < Blob->cbSize) { /* Delete the current buffer and allocate a new one */ HeapFree(WsSockHeap, 0, Thread->Servent); Thread->Servent = HeapAlloc(WsSockHeap, 0, Blob->cbSize);
/* Set the new size */ Thread->ServentSize = Blob->cbSize; }
/* Do we have a buffer? */ if (Thread->Servent) { /* Copy the data inside */ RtlMoveMemory(Thread->Servent, Blob->pBlobData, Blob->cbSize); } else { /* No buffer space! */ Thread->ServentSize = 0; SetLastError(WSA_NOT_ENOUGH_MEMORY); }
/* Return the buffer */ return (PSERVENT)Thread->Servent;}