ReactOS  0.4.13-dev-39-g8b6696f
async.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_new/src/async.c
5  * PURPOSE: Async Block Object and Async Thread Management
6  * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include <ws2_32.h>
12 
13 /* DATA **********************************************************************/
14 
23 
24 #define WsAsyncLock() EnterCriticalSection(&WsAsyncCritSect)
25 #define WsAsyncUnlock() LeaveCriticalSection(&WsAsyncCritSect)
26 
27 /* FUNCTIONS *****************************************************************/
28 
29 VOID
30 WSAAPI
32 {
33  /* Initialize the async lock */
35 }
36 
37 VOID
38 WSAAPI
40 {
41  /* Destroy the async lock */
43 }
44 
45 
46 SIZE_T
47 WSAAPI
49 {
50  SIZE_T Bytes;
51  INT i;
52 
53  /* Start with the static stuff */
54  Bytes = sizeof(HOSTENT) + strlen(Hostent->h_name) + sizeof(CHAR);
55 
56  /* Add 2 pointers for the list-terminators */
57  Bytes += 2 * sizeof(ULONG_PTR);
58 
59  /* Now loop for the aliases */
60  for (i = 0; Hostent->h_aliases[i]; i++)
61  {
62  /* Add the alias size, plus the space its pointer takes */
63  Bytes += strlen(Hostent->h_aliases[i]) + sizeof(CHAR) + sizeof(ULONG_PTR);
64  }
65 
66  /* Now loop for the hostnames */
67  for (i = 0; Hostent->h_addr_list[i]; i++)
68  {
69  /* Add the alias size, plus the space its pointer takes */
70  Bytes += Hostent->h_length + sizeof(ULONG_PTR);
71  }
72 
73  /* Align to 8 bytes */
74  return (Bytes + 7) & ~7;
75 }
76 
77 SIZE_T
78 WSAAPI
80 {
81  SIZE_T Bytes;
82  INT i;
83 
84  /* Start with the static stuff */
85  Bytes = sizeof(SERVENT) +
86  strlen(Servent->s_name) + sizeof(CHAR) +
87  strlen(Servent->s_proto) + sizeof(CHAR);
88 
89  /* Add 1 pointers for the list terminator */
90  Bytes += sizeof(ULONG_PTR);
91 
92  /* Now loop for the aliases */
93  for (i = 0; Servent->s_aliases[i]; i++)
94  {
95  /* Add the alias size, plus the space its pointer takes */
96  Bytes += strlen(Servent->s_aliases[i]) + sizeof(CHAR) + sizeof(ULONG_PTR);
97  }
98 
99  /* return */
100  return Bytes;
101 }
102 
103 SIZE_T
104 WSAAPI
106 {
107  SIZE_T Bytes;
108  INT i;
109 
110  /* Start with the static stuff */
111  Bytes = sizeof(SERVENT) + strlen(Protoent->p_name) + sizeof(CHAR);
112 
113  /* Add 1 pointers for the list terminator */
114  Bytes += sizeof(ULONG_PTR);
115 
116  /* Now loop for the aliases */
117  for (i = 0; Protoent->p_aliases[i]; i++)
118  {
119  /* Add the alias size, plus the space its pointer takes */
120  Bytes += strlen(Protoent->p_aliases[i]) + sizeof(CHAR) + sizeof(ULONG_PTR);
121  }
122 
123  /* return */
124  return Bytes;
125 }
126 
127 SIZE_T
128 WSAAPI
131  IN PHOSTENT Hostent)
132 {
133  SIZE_T BufferSize, CurrentSize, NameSize;
134  PCHAR p = Buffer;
135  DWORD Aliases = 0, Names = 0;
136  DWORD i;
137  PHOSTENT ReturnedHostent = (PHOSTENT)Buffer;
138 
139  /* Determine the buffer size required */
140  BufferSize = BytesInHostent(Hostent);
141 
142  /* Check which size to use */
144  {
145  /* Zero the buffer */
147  }
148  else
149  {
150  /* Zero the buffer */
152  }
153 
154  /* Start with the raw Hostent */
155  CurrentSize = sizeof(HOSTENT);
156 
157  /* Return the size needed now */
158  if (CurrentSize > (DWORD)BufferLength) return BufferSize;
159 
160  /* Copy the Hostent and initialize it */
161  CopyMemory(p, Hostent, sizeof(HOSTENT));
162  p = Buffer + CurrentSize;
163  ReturnedHostent->h_name = NULL;
164  ReturnedHostent->h_aliases = NULL;
165  ReturnedHostent->h_addr_list = NULL;
166 
167  /* Find out how many aliases there are */
168  while (Hostent->h_aliases[Aliases])
169  {
170  /* Increase the alias count */
171  Aliases++;
172  }
173 
174  /* Add the aliases to the size, and validate it */
175  CurrentSize += (Aliases + 1) * sizeof(ULONG_PTR);
176  if (CurrentSize > (DWORD)BufferLength)
177  {
178  /* Clear the aliases and return */
179  Hostent->h_aliases = NULL;
180  return BufferSize;
181  }
182 
183  /* Write the aliases, update the pointer */
184  ReturnedHostent->h_aliases = (PCHAR*)p;
185  p = Buffer + CurrentSize;
186 
187  /* Find out how many names there are */
188  while (Hostent->h_addr_list[Names])
189  {
190  /* Increase the alias count */
191  Names++;
192  }
193 
194  /* Add the names to the size, and validate it */
195  CurrentSize += (Names + 1) * sizeof(ULONG_PTR);
196  if (CurrentSize > (DWORD)BufferLength)
197  {
198  /* Clear the aliases and return */
199  Hostent->h_addr_list = NULL;
200  return BufferSize;
201  }
202 
203  /* Write the names, update the pointer */
204  ReturnedHostent->h_addr_list = (PCHAR*)p;
205  p = Buffer + CurrentSize;
206 
207  /* Now add the names */
208  for (i = 0; i < Names; i++)
209  {
210  /* Update size and validate */
211  CurrentSize += Hostent->h_length;
212  if (CurrentSize > (DWORD)BufferLength) return BufferSize;
213 
214  /* Write pointer and copy */
215  ReturnedHostent->h_addr_list[i] = p;
216  CopyMemory(p, Hostent->h_addr_list[i], Hostent->h_length);
217 
218  /* Update pointer */
219  p = Buffer + CurrentSize;
220  }
221 
222  /* Finalize the list */
223  ReturnedHostent->h_addr_list[i] = NULL;
224 
225  /* Add the service name to the size, and validate it */
226  NameSize = strlen(Hostent->h_name) + sizeof(CHAR);
227  CurrentSize += NameSize;
228  if (CurrentSize > (DWORD)BufferLength) return BufferSize;
229 
230  /* Write the service name and update the pointer */
231  ReturnedHostent->h_name = p;
232  CopyMemory(p, Hostent->h_name, NameSize);
233  p = Buffer + CurrentSize;
234 
235  /* Now add the aliases */
236  for (i = 0; i < Aliases; i++)
237  {
238  /* Update size and validate */
239  NameSize = strlen(Hostent->h_aliases[i]) + sizeof(CHAR);
240  CurrentSize += NameSize;
241  if (CurrentSize > (DWORD)BufferLength) return BufferSize;
242 
243  /* Write pointer and copy */
244  ReturnedHostent->h_aliases[i] = p;
245  CopyMemory(p, Hostent->h_aliases[i], NameSize);
246 
247  /* Update pointer */
248  p = Buffer + CurrentSize;
249  }
250 
251  /* Finalize the list and return */
252  ReturnedHostent->h_aliases[i] = NULL;
253  return BufferSize;
254 }
255 
256 SIZE_T
257 WSAAPI
260  IN PSERVENT Servent)
261 {
262  SIZE_T BufferSize, CurrentSize, NameSize;
263  PCHAR p = Buffer;
264  DWORD Aliases = 0;
265  DWORD i;
266  PSERVENT ReturnedServent = (PSERVENT)Buffer;
267 
268  /* Determine the buffer size required */
269  BufferSize = BytesInServent(Servent);
270 
271  /* Check which size to use */
273  {
274  /* Zero the buffer */
276  }
277  else
278  {
279  /* Zero the buffer */
281  }
282 
283  /* Start with the raw servent */
284  CurrentSize = sizeof(SERVENT);
285 
286  /* Return the size needed now */
287  if (CurrentSize > (DWORD)BufferLength) return BufferSize;
288 
289  /* Copy the servent and initialize it */
290  CopyMemory(p, Servent, sizeof(SERVENT));
291  p = Buffer + CurrentSize;
292  ReturnedServent->s_name = NULL;
293  ReturnedServent->s_aliases = NULL;
294  ReturnedServent->s_proto = NULL;
295 
296  /* Find out how many aliases there are */
297  while (Servent->s_aliases[Aliases])
298  {
299  /* Increase the alias count */
300  Aliases++;
301  }
302 
303  /* Add the aliases to the size, and validate it */
304  CurrentSize += (Aliases + 1) * sizeof(ULONG_PTR);
305  if (CurrentSize > (DWORD)BufferLength)
306  {
307  /* Clear the aliases and return */
308  Servent->s_aliases = NULL;
309  return BufferSize;
310  }
311 
312  /* Write the aliases, update the pointer */
313  ReturnedServent->s_aliases = (PCHAR*)p;
314  p = Buffer + CurrentSize;
315 
316  /* Add the service name to the size, and validate it */
317  NameSize = strlen(Servent->s_name) + sizeof(CHAR);
318  CurrentSize += NameSize;
319  if (CurrentSize > (DWORD)BufferLength) return BufferSize;
320 
321  /* Write the service name and update the pointer */
322  ReturnedServent->s_name = p;
323  CopyMemory(p, Servent->s_name, NameSize);
324  p = Buffer + CurrentSize;
325 
326  /* Now add the aliases */
327  for (i = 0; i < Aliases; i++)
328  {
329  /* Update size and validate */
330  NameSize = strlen(Servent->s_aliases[i]) + sizeof(CHAR);
331  CurrentSize += NameSize;
332  if (CurrentSize > (DWORD)BufferLength) return BufferSize;
333 
334  /* Write pointer and copy */
335  ReturnedServent->s_aliases[i] = p;
336  CopyMemory(p, Servent->s_aliases[i], NameSize);
337 
338  /* Update pointer */
339  p = Buffer + CurrentSize;
340  }
341 
342  /* Finalize the list and return */
343  ReturnedServent->s_aliases[i] = NULL;
344  return BufferSize;
345 }
346 
347 SIZE_T
348 WSAAPI
351  IN PPROTOENT Protoent)
352 {
353  SIZE_T BufferSize, CurrentSize, NameSize;
354  PCHAR p = Buffer;
355  DWORD Aliases = 0;
356  DWORD i;
357  PPROTOENT ReturnedProtoent = (PPROTOENT)Buffer;
358 
359  /* Determine the buffer size required */
360  BufferSize = BytesInProtoent(Protoent);
361 
362  /* Check which size to use */
364  {
365  /* Zero the buffer */
367  }
368  else
369  {
370  /* Zero the buffer */
372  }
373 
374  /* Start with the raw servent */
375  CurrentSize = sizeof(PROTOENT);
376 
377  /* Return the size needed now */
378  if (CurrentSize > (DWORD)BufferLength) return BufferSize;
379 
380  /* Copy the servent and initialize it */
381  CopyMemory(p, Protoent, sizeof(PROTOENT));
382  p = Buffer + CurrentSize;
383  ReturnedProtoent->p_name = NULL;
384  ReturnedProtoent->p_aliases = NULL;
385 
386  /* Find out how many aliases there are */
387  while (Protoent->p_aliases[Aliases])
388  {
389  /* Increase the alias count */
390  Aliases++;
391  }
392 
393  /* Add the aliases to the size, and validate it */
394  CurrentSize += (Aliases + 1) * sizeof(ULONG_PTR);
395  if (CurrentSize > (DWORD)BufferLength)
396  {
397  /* Clear the aliases and return */
398  Protoent->p_aliases = NULL;
399  return BufferSize;
400  }
401 
402  /* Write the aliases, update the pointer */
403  ReturnedProtoent->p_aliases = (PCHAR*)p;
404  p = Buffer + CurrentSize;
405 
406  /* Add the service name to the size, and validate it */
407  NameSize = strlen(Protoent->p_name) + sizeof(CHAR);
408  CurrentSize += NameSize;
409  if (CurrentSize > (DWORD)BufferLength) return BufferSize;
410 
411  /* Write the service name and update the pointer */
412  ReturnedProtoent->p_name = p;
413  CopyMemory(p, Protoent->p_name, NameSize);
414  p = Buffer + CurrentSize;
415 
416  /* Now add the aliases */
417  for (i = 0; i < Aliases; i++)
418  {
419  /* Update size and validate */
420  NameSize = strlen(Protoent->p_aliases[i]) + sizeof(CHAR);
421  CurrentSize += NameSize;
422  if (CurrentSize > (DWORD)BufferLength) return BufferSize;
423 
424  /* Write pointer and copy */
425  ReturnedProtoent->p_aliases[i] = p;
426  CopyMemory(p, Protoent->p_aliases[i], NameSize);
427 
428  /* Update pointer */
429  p = Buffer + CurrentSize;
430  }
431 
432  /* Finalize the list and return */
433  ReturnedProtoent->p_aliases[i] = NULL;
434  return BufferSize;
435 }
436 
438 WSAAPI
440 {
441  PWSASYNCBLOCK AsyncBlock;
442 
443  /* Add the size of the block */
444  ExtraLength += sizeof(WSASYNCBLOCK);
445 
446  /* Allocate it */
447  AsyncBlock = HeapAlloc(WsSockHeap, 0, ExtraLength);
448 
449  /* Get a handle to it */
451 
452  /* Return it */
453  return AsyncBlock;
454 }
455 
456 BOOL
457 WINAPI
459 {
460  /* Check if this task is being cancelled */
462  {
463  /* Cancel the blocking call so we can get back */
465  }
466 
467  /* Return to system */
468  return FALSE;
469 }
470 
471 VOID
472 WSAAPI
474 {
475  /* Free it */
476  HeapFree(WsSockHeap, 0, AsyncBlock);
477 }
478 
479 VOID
480 WSAAPI
483  IN HWND hWnd,
484  IN UINT wMsg,
485  IN CHAR FAR *ByWhat,
486  IN CHAR FAR *Protocol,
487  IN CHAR FAR *Buffer,
489 {
490  PSERVENT Servent;
491  SIZE_T BufferSize = 0;
492  LPARAM lParam;
493  INT ErrorCode = 0;
494 
495  /* Check the operation */
497  {
498  /* Call the API */
499  Servent = getservbyname(ByWhat, Protocol);
500  }
501  else
502  {
503  /* Call the API */
504  Servent = getservbyport(PtrToUlong(ByWhat), Protocol);
505  }
506 
507  /* Make sure we got one */
508  if (!Servent) ErrorCode = GetLastError();
509 
510  /* Acquire the lock */
511  WsAsyncLock();
512 
513  /* Check if this task got cancelled */
514  if (TaskHandle == WsAsyncCancelledTaskHandle)
515  {
516  /* Return */
517  WsAsyncUnlock();
518  return;
519  }
520 
521  /* If we got a Servent back, copy it */
522  if (Servent)
523  {
524  /* Copy it into the buffer */
526 
527  /* Check if we had enough space */
529  {
530  /* Not enough */
532  }
533  else
534  {
535  /* Perfect */
537  }
538  }
539 
540  /* Not processing anymore */
542 
543  /* Release the lock */
544  WsAsyncUnlock();
545 
546  /* Make the messed-up lParam reply */
548 
549  /* Sent it through the Upcall API */
550  WPUPostMessage(hWnd, wMsg, (WPARAM)TaskHandle, lParam);
551 }
552 
553 VOID
554 WSAAPI
557  IN HWND hWnd,
558  IN UINT wMsg,
559  IN CHAR FAR *ByWhat,
560  IN CHAR FAR *Buffer,
562 {
563  PPROTOENT Protoent;
564  SIZE_T BufferSize = 0;
565  LPARAM lParam;
566  INT ErrorCode = 0;
567 
568  /* Check the operation */
570  {
571  /* Call the API */
572  Protoent = getprotobyname(ByWhat);
573  }
574  else
575  {
576  /* Call the API */
577  Protoent = getprotobynumber(PtrToUlong(ByWhat));
578  }
579 
580  /* Make sure we got one */
581  if (!Protoent) ErrorCode = GetLastError();
582 
583  /* Acquire the lock */
584  WsAsyncLock();
585 
586  /* Check if this task got cancelled */
587  if (TaskHandle == WsAsyncCancelledTaskHandle)
588  {
589  /* Return */
590  WsAsyncUnlock();
591  return;
592  }
593 
594  /* If we got a Servent back, copy it */
595  if (Protoent)
596  {
597  /* Copy it into the buffer */
599 
600  /* Check if we had enough space */
602  {
603  /* Not enough */
605  }
606  else
607  {
608  /* Perfect */
610  }
611  }
612 
613  /* Not processing anymore */
615 
616  /* Release the lock */
617  WsAsyncUnlock();
618 
619  /* Make the messed-up lParam reply */
621 
622  /* Sent it through the Upcall API */
623  WPUPostMessage(hWnd, wMsg, (WPARAM)TaskHandle, lParam);
624 }
625 
626 VOID
627 WSAAPI
630  IN HWND hWnd,
631  IN UINT wMsg,
632  IN CHAR FAR *ByWhat,
633  IN INT Length,
634  IN INT Type,
635  IN CHAR FAR *Buffer,
637 {
638  PHOSTENT Hostent;
639  SIZE_T BufferSize = 0;
640  LPARAM lParam;
641  INT ErrorCode = 0;
642 
643  /* Check the operation */
645  {
646  /* Call the API */
647  Hostent = gethostbyaddr(ByWhat, Length, Type);
648  }
649  else
650  {
651  /* Call the API */
652  Hostent = gethostbyname(ByWhat);
653  }
654 
655  /* Make sure we got one */
656  if (!Hostent) ErrorCode = GetLastError();
657 
658  /* Acquire the lock */
659  WsAsyncLock();
660 
661  /* Check if this task got cancelled */
662  if (TaskHandle == WsAsyncCancelledTaskHandle)
663  {
664  /* Return */
665  WsAsyncUnlock();
666  return;
667  }
668 
669  /* If we got a Servent back, copy it */
670  if (Hostent)
671  {
672  /* Copy it into the buffer */
674 
675  /* Check if we had enough space */
677  {
678  /* Not enough */
680  }
681  else
682  {
683  /* Perfect */
685  }
686  }
687 
688  /* Not processing anymore */
690 
691  /* Release the lock */
692  WsAsyncUnlock();
693 
694  /* Make the messed-up lParam reply */
696 
697  /* Sent it through the Upcall API */
698  WPUPostMessage(hWnd, wMsg, (WPARAM)TaskHandle, lParam);
699 }
700 
701 DWORD
702 WINAPI
703 WsAsyncThread(IN PVOID ThreadContext)
704 {
705  PWSASYNCCONTEXT Context = ThreadContext;
706  PWSASYNCBLOCK AsyncBlock;
708  HANDLE AsyncEvent = Context->AsyncEvent;
709  PLIST_ENTRY ListHead = &Context->AsyncQueue;
710 
711  /* Set the blocking hook */
713 
714  /* Loop */
715  while (TRUE)
716  {
717  /* Wait for the event */
718  WaitForSingleObject(AsyncEvent, INFINITE);
719 
720  /* Get the lock */
721  WsAsyncLock();
722 
723  /* Process the queue */
724  while (!IsListEmpty(ListHead))
725  {
726  /* Remove this entry and get the async block */
727  Entry = RemoveHeadList(ListHead);
728  AsyncBlock = CONTAINING_RECORD(Entry, WSASYNCBLOCK, AsyncQueue);
729 
730  /* Save the current task handle */
731  WsAsyncCurrentTaskHandle = AsyncBlock->TaskHandle;
732 
733  /* Release the lock */
734  WsAsyncUnlock();
735 
736  /* Check which operation to do */
737  switch (AsyncBlock->Operation)
738  {
739  /* Get Host by Y */
741 
742  /* Call the handler */
743  WsAsyncGetHost(AsyncBlock->TaskHandle,
744  AsyncBlock->Operation,
745  AsyncBlock->GetHost.hWnd,
746  AsyncBlock->GetHost.wMsg,
747  AsyncBlock->GetHost.ByWhat,
748  AsyncBlock->GetHost.Length,
749  AsyncBlock->GetHost.Type,
750  AsyncBlock->GetHost.Buffer,
751  AsyncBlock->GetHost.BufferLength);
752  break;
753 
754  /* Get Proto by Y */
756 
757  /* Call the handler */
758  WsAsyncGetProto(AsyncBlock->TaskHandle,
759  AsyncBlock->Operation,
760  AsyncBlock->GetProto.hWnd,
761  AsyncBlock->GetProto.wMsg,
762  AsyncBlock->GetHost.ByWhat,
763  AsyncBlock->GetProto.Buffer,
764  AsyncBlock->GetProto.BufferLength);
765  break;
766 
767  /* Get Serv by Y */
769 
770  /* Call the handler */
771  WsAsyncGetServ(AsyncBlock->TaskHandle,
772  AsyncBlock->Operation,
773  AsyncBlock->GetServ.hWnd,
774  AsyncBlock->GetServ.wMsg,
775  AsyncBlock->GetServ.ByWhat,
776  AsyncBlock->GetServ.Protocol,
777  AsyncBlock->GetServ.Buffer,
778  AsyncBlock->GetServ.BufferLength);
779  break;
780 
781  /* Termination */
782  case WsAsyncTerminate:
783 
784  /* Clean up the extra reference */
785  WSACleanup();
786 
787  /* Free the context block */
788  WsAsyncFreeBlock(AsyncBlock);
789 
790  /* Acquire the lock */
791  WsAsyncLock();
792 
793  /* Loop the queue and flush it */
794  while (!IsListEmpty(ListHead))
795  {
796  Entry = RemoveHeadList(ListHead);
797  AsyncBlock = CONTAINING_RECORD(Entry,
798  WSASYNCBLOCK,
799  AsyncQueue);
800  WsAsyncFreeBlock(AsyncBlock);
801  }
802 
803  /* Release lock */
804  WsAsyncUnlock();
805 
806  /* Close the event, free the Context */
807  CloseHandle(AsyncEvent);
809 
810  /* Remove the extra DLL reference and kill us */
812 
813  default:
814  break;
815  }
816 
817  /* Done processing */
819 
820  /* Free this block, get lock and reloop */
821  WsAsyncFreeBlock(AsyncBlock);
822  WsAsyncLock();
823  }
824 
825  /* Release the lock */
826  WsAsyncUnlock();
827  }
828 }
829 
830 BOOL
831 WSAAPI
833 {
834  HANDLE ThreadHandle;
835  DWORD Tid;
837  WSADATA WsaData;
838 
839  /* Make sure we're not initialized */
840  if (WsAsyncThreadInitialized) return TRUE;
841 
842  /* Acquire the lock */
843  WsAsyncLock();
844 
845  /* Make sure we're not initialized */
847  {
848  /* Initialize Thread Context */
849  Context = HeapAlloc(WsSockHeap, 0, sizeof(*Context));
850  if (!Context)
851  goto Exit;
852 
853  /* Initialize the Queue and event */
854  WsAsyncQueue = &Context->AsyncQueue;
856  Context->AsyncEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
857  WsAsyncEvent = Context->AsyncEvent;
858 
859  /* Prevent us from ever being killed while running */
860  if (WSAStartup(MAKEWORD(2,2), &WsaData) != ERROR_SUCCESS)
861  goto Fail;
862 
863  /* Create the thread */
864  ThreadHandle = CreateThread(NULL,
865  0,
867  Context,
868  0,
869  &Tid);
870  if (ThreadHandle == NULL)
871  {
872  /* Cleanup and fail */
873  WSACleanup();
874  goto Fail;
875  }
876 
877  /* Close the handle and set init */
878  CloseHandle(ThreadHandle);
880  }
881 
882 Exit:
883  /* Release the lock */
884  WsAsyncUnlock();
886 
887 Fail:
888  /* Close the event, free the Context */
889  if (Context->AsyncEvent)
890  CloseHandle(Context->AsyncEvent);
892 
893  /* Bail out */
894  goto Exit;
895 }
896 
897 VOID
898 WSAAPI
900 {
901  PWSASYNCBLOCK AsyncBlock;
902 
903  /* Make sure we're initialized */
904  if (!WsAsyncThreadInitialized) return;
905 
906  /* Allocate a block */
907  AsyncBlock = WsAsyncAllocateBlock(0);
908 
909  /* Initialize it for termination */
910  AsyncBlock->Operation = WsAsyncTerminate;
911 
912  /* Queue the request and return */
913  WsAsyncQueueRequest(AsyncBlock);
915 }
916 
917 VOID
918 WSAAPI
920 {
921  /* Get the lock */
922  WsAsyncLock();
923 
924  /* Insert it into the queue */
925  InsertTailList(WsAsyncQueue, &AsyncBlock->AsyncQueue);
926 
927  /* Wake up the thread */
929 
930  /* Release lock and return */
931  WsAsyncUnlock();
932 }
933 
934 INT
935 WSAAPI
937 {
939  PWSASYNCBLOCK AsyncBlock;
940 
941  /* Make sure we're initialized */
942  if (!WsAsyncThreadInitialized) return WSAEINVAL;
943 
944  /* Acquire the lock */
945  WsAsyncLock();
946 
947  /* Check if we're cancelling the current task */
948  if (TaskHandle == WsAsyncCurrentTaskHandle)
949  {
950  /* Mark us as cancelled, the async thread will see this later */
951  WsAsyncCancelledTaskHandle = TaskHandle;
952 
953  /* Release lock and return */
954  WsAsyncUnlock();
955  return NO_ERROR;
956  }
957 
958  /* Loop the queue */
960  while (Entry != WsAsyncQueue)
961  {
962  /* Get the Async Block */
963  AsyncBlock = CONTAINING_RECORD(Entry, WSASYNCBLOCK, AsyncQueue);
964 
965  /* Check if this is the one */
966  if (TaskHandle == AsyncBlock->TaskHandle)
967  {
968  /* It is, remove it */
970 
971  /* Release the lock, free the block, and return */
972  WsAsyncUnlock();
973  WsAsyncFreeBlock(AsyncBlock);
974  return NO_ERROR;
975  }
976 
977  /* Move to the next entry */
978  Entry = Entry->Flink;
979  }
980 
981  /* Nothing found, fail */
982  WsAsyncUnlock();
983  return WSAEINVAL;
984 }
HANDLE TaskHandle
Definition: ws2_32p.h:27
#define CreateEvent
Definition: winbase.h:3562
SIZE_T WSAAPI BytesInHostent(PHOSTENT Hostent)
Definition: async.c:48
signed char * PCHAR
Definition: retypes.h:7
#define IN
Definition: typedefs.h:38
PWSTR Names[NAMES_COUNT]
HINSTANCE WsAsyncDllHandle
Definition: async.c:22
FARPROC WSAAPI WSASetBlockingHook(IN FARPROC lpBlockFunc)
Definition: bhook.c:89
char ** h_addr_list
Definition: winsock.h:138
VOID WSAAPI WsAsyncGetProto(IN HANDLE TaskHandle, IN DWORD Operation, IN HWND hWnd, IN UINT wMsg, IN CHAR FAR *ByWhat, IN CHAR FAR *Buffer, IN INT BufferLength)
Definition: async.c:555
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4418
Type
Definition: Type.h:6
#define ERROR_SUCCESS
Definition: deptool.c:10
struct _Entry Entry
Definition: kefuncs.h:640
LPPROTOENT WSAAPI getprotobynumber(IN INT number)
Definition: getproto.c:241
struct _WSASYNCBLOCK::@567::@571 GetServ
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define MAKEWORD(a, b)
Definition: typedefs.h:247
#define WSAEINVAL
Definition: winerror.h:1946
char * h_name
Definition: winsock.h:134
char CHAR
Definition: xmlstorage.h:175
SIZE_T WSAAPI CopyProtoentToBuffer(IN PCHAR Buffer, IN INT BufferLength, IN PPROTOENT Protoent)
Definition: async.c:349
INT WSAAPI WSACleanup(VOID)
Definition: startup.c:60
LPPROTOENT WSAAPI getprotobyname(IN CONST CHAR FAR *name)
Definition: getproto.c:305
HWND hWnd
Definition: settings.c:17
_In_ UINT Bytes
Definition: mmcopy.h:9
char ** h_aliases
Definition: winsock.h:135
#define WsAsyncUnlock()
Definition: async.c:25
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:679
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1635
struct _WSASYNCBLOCK::@567::@569 GetHost
SIZE_T WSAAPI BytesInProtoent(PPROTOENT Protoent)
Definition: async.c:105
UINT_PTR WPARAM
Definition: windef.h:207
struct _WSASYNCBLOCK::@567::@570 GetProto
PWSASYNCBLOCK WSAAPI WsAsyncAllocateBlock(IN SIZE_T ExtraLength)
Definition: async.c:439
#define InsertTailList(ListHead, Entry)
#define NO_ERROR
Definition: dderror.h:5
int32_t INT
Definition: typedefs.h:56
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
HANDLE WsAsyncEvent
Definition: async.c:19
BOOL WINAPI WsAsyncThreadBlockingHook(VOID)
Definition: async.c:458
uint32_t ULONG_PTR
Definition: typedefs.h:63
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
VOID WINAPI FreeLibraryAndExitThread(HMODULE hLibModule, DWORD dwExitCode)
Definition: loader.c:514
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
PHOSTENT WSAAPI gethostbyaddr(IN const char FAR *addr, IN int len, IN int type)
Definition: getxbyxx.c:309
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
_In_ ULONG BufferLength
Definition: usbdlib.h:225
#define WSAMAKEASYNCREPLY(b, e)
Definition: winsock.h:477
#define FAR
Definition: guiddef.h:36
short h_length
Definition: winsock.h:137
unsigned char BOOLEAN
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:112
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:697
SIZE_T WSAAPI CopyServentToBuffer(IN PCHAR Buffer, IN INT BufferLength, IN PSERVENT Servent)
Definition: async.c:258
smooth NULL
Definition: ftsmooth.c:416
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
LONG_PTR LPARAM
Definition: windef.h:208
VOID WSAAPI WsAsyncGlobalTerminate(VOID)
Definition: async.c:39
Definition: bufpool.h:45
struct servent * PSERVENT
Definition: winsock.h:500
DWORD WINAPI WsAsyncThread(IN PVOID ThreadContext)
Definition: async.c:703
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define UlongToPtr(u)
Definition: config.h:106
BOOLEAN WsAsyncThreadInitialized
Definition: async.c:15
#define PtrToUlong(u)
Definition: config.h:107
struct protoent * PPROTOENT
Definition: winsock.h:503
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
PHOSTENT WSAAPI gethostbyname(IN const char FAR *name)
Definition: getxbyxx.c:221
PSERVENT WSAAPI getservbyname(IN const char FAR *name, IN const char FAR *proto)
Definition: getxbyxx.c:500
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
INT WSAAPI WSACancelBlockingCall(VOID)
Definition: bhook.c:23
static void Exit(void)
Definition: sock.c:1331
#define WINAPI
Definition: msvc.h:8
#define CopyMemory
Definition: winbase.h:1633
char * s_name
Definition: winsock.h:159
#define BufferSize
Definition: classpnp.h:419
unsigned long DWORD
Definition: ntddk_ex.h:95
VOID WSAAPI WsAsyncGetServ(IN HANDLE TaskHandle, IN DWORD Operation, IN HWND hWnd, IN UINT wMsg, IN CHAR FAR *ByWhat, IN CHAR FAR *Protocol, IN CHAR FAR *Buffer, IN INT BufferLength)
Definition: async.c:481
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
VOID WSAAPI WsAsyncGetHost(IN HANDLE TaskHandle, IN DWORD Operation, IN HWND hWnd, IN UINT wMsg, IN CHAR FAR *ByWhat, IN INT Length, IN INT Type, IN CHAR FAR *Buffer, IN INT BufferLength)
Definition: async.c:628
LONG WsAsyncTaskHandle
Definition: async.c:16
CRITICAL_SECTION WsAsyncCritSect
Definition: async.c:18
Definition: typedefs.h:117
SIZE_T WSAAPI BytesInServent(PSERVENT Servent)
Definition: async.c:79
VOID WSAAPI WsAsyncGlobalInitialize(VOID)
Definition: async.c:31
Definition: hiveinit.c:368
ULONG_PTR SIZE_T
Definition: typedefs.h:78
INT WSAAPI WsAsyncCancelRequest(IN HANDLE TaskHandle)
Definition: async.c:936
#define InterlockedIncrement
Definition: armddk.h:53
char ** p_aliases
Definition: winsock.h:172
struct hostent HOSTENT
Definition: winsock.h:496
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define WSAAPI
Definition: winsock2.h:584
struct servent SERVENT
Definition: winsock.h:499
VOID WSAAPI WsAsyncFreeBlock(IN PWSASYNCBLOCK AsyncBlock)
Definition: async.c:473
unsigned int UINT
Definition: ndis.h:50
VOID WSAAPI WsAsyncQueueRequest(IN PWSASYNCBLOCK AsyncBlock)
Definition: async.c:919
char * s_proto
Definition: winsock.h:166
char ** s_aliases
Definition: winsock.h:160
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
_In_ FLT_SET_CONTEXT_OPERATION Operation
Definition: fltkernel.h:1468
struct protoent PROTOENT
Definition: winsock.h:502
HANDLE WsAsyncCancelledTaskHandle
Definition: async.c:21
struct hostent * PHOSTENT
Definition: winsock.h:497
GLfloat GLfloat p
Definition: glext.h:8902
PSERVENT WSAAPI getservbyport(IN int port, IN const char FAR *proto)
Definition: getxbyxx.c:431
#define INFINITE
Definition: serial.h:102
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
struct _WSASYNCBLOCK WSASYNCBLOCK
PLIST_ENTRY WsAsyncQueue
Definition: async.c:17
#define CHAR(Char)
HANDLE WsSockHeap
Definition: dllmain.c:21
VOID WSAAPI WsAsyncTerminateThread(VOID)
Definition: async.c:899
LPARAM lParam
Definition: combotst.c:139
WSASYNCOPS Operation
Definition: ws2_32p.h:28
HANDLE WsAsyncCurrentTaskHandle
Definition: async.c:20
#define WSAENOBUFS
Definition: winerror.h:1968
SIZE_T WSAAPI CopyHostentToBuffer(IN PCHAR Buffer, IN INT BufferLength, IN PHOSTENT Hostent)
Definition: async.c:129
#define HeapFree(x, y, z)
Definition: compat.h:394
#define WsAsyncLock()
Definition: async.c:24
base of all file and directory entries
Definition: entries.h:82
int(* FARPROC)()
Definition: compat.h:28
BOOL WSPAPI WPUPostMessage(IN HWND hWnd, IN UINT Msg, IN WPARAM wParam, IN LPARAM lParam)
Definition: sputil.c:85
char * p_name
Definition: winsock.h:171
BOOL WSAAPI WsAsyncCheckAndInitThread(VOID)
Definition: async.c:832