- Replace WIN32 types by corresponding native types.
[reactos.git] / reactos / lib / msafd / misc / dllmain.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Ancillary Function Driver DLL
4 * FILE: misc/dllmain.c
5 * PURPOSE: DLL entry point
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * Alex Ionescu (alex@relsoft.net)
8 * REVISIONS:
9 * CSH 01/09-2000 Created
10 * Alex 16/07/2004 - Complete Rewrite
11 */
12 #include <roscfg.h>
13 #include <string.h>
14 #include <msafd.h>
15 #include <helpers.h>
16 #include <rosrtl/string.h>
17
18 #ifdef DBG
19 //DWORD DebugTraceLevel = DEBUG_ULTRA;
20 DWORD DebugTraceLevel = 0;
21 #endif /* DBG */
22
23 HANDLE GlobalHeap;
24 WSPUPCALLTABLE Upcalls;
25 LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest;
26 ULONG SocketCount;
27 PSOCKET_INFORMATION *Sockets = NULL;
28 LIST_ENTRY SockHelpersListHead = {NULL};
29
30 SOCKET
31 WSPAPI
32 WSPSocket(
33 int AddressFamily,
34 int SocketType,
35 int Protocol,
36 LPWSAPROTOCOL_INFOW lpProtocolInfo,
37 GROUP g,
38 DWORD dwFlags,
39 LPINT lpErrno)
40 /*
41 * FUNCTION: Creates a new socket
42 * ARGUMENTS:
43 * af = Address family
44 * type = Socket type
45 * protocol = Protocol type
46 * lpProtocolInfo = Pointer to protocol information
47 * g = Reserved
48 * dwFlags = Socket flags
49 * lpErrno = Address of buffer for error information
50 * RETURNS:
51 * Created socket, or INVALID_SOCKET if it could not be created
52 */
53 {
54 OBJECT_ATTRIBUTES Object;
55 IO_STATUS_BLOCK IOSB;
56 USHORT SizeOfPacket;
57 ULONG SizeOfEA;
58 PAFD_CREATE_PACKET AfdPacket;
59 HANDLE Sock;
60 PSOCKET_INFORMATION Socket = NULL;
61 PFILE_FULL_EA_INFORMATION EABuffer = NULL;
62 PHELPER_DATA HelperData;
63 PVOID HelperDLLContext;
64 DWORD HelperEvents;
65 DWORD IOOptions;
66 UNICODE_STRING TransportName;
67 UNICODE_STRING DevName;
68 LARGE_INTEGER GroupData;
69 INT Status;
70
71 AFD_DbgPrint(MAX_TRACE, ("Creating Socket, getting TDI Name\n"));
72 AFD_DbgPrint(MAX_TRACE, ("AddressFamily (%d) SocketType (%d) Protocol (%d).\n",
73 AddressFamily, SocketType, Protocol));
74
75 /* Get Helper Data and Transport */
76 Status = SockGetTdiName (&AddressFamily,
77 &SocketType,
78 &Protocol,
79 g,
80 dwFlags,
81 &TransportName,
82 &HelperDLLContext,
83 &HelperData,
84 &HelperEvents);
85
86 /* Check for error */
87 if (Status != NO_ERROR) {
88 AFD_DbgPrint(MID_TRACE,("SockGetTdiName: Status %x\n", Status));
89 goto error;
90 }
91
92 /* AFD Device Name */
93 RtlInitUnicodeString(&DevName, L"\\Device\\Afd\\Endpoint");
94
95 /* Set Socket Data */
96 Socket = HeapAlloc(GlobalHeap, 0, sizeof(*Socket));
97 RtlZeroMemory(Socket, sizeof(*Socket));
98 Socket->RefCount = 2;
99 Socket->Handle = -1;
100 Socket->SharedData.State = SocketOpen;
101 Socket->SharedData.AddressFamily = AddressFamily;
102 Socket->SharedData.SocketType = SocketType;
103 Socket->SharedData.Protocol = Protocol;
104 Socket->HelperContext = HelperDLLContext;
105 Socket->HelperData = HelperData;
106 Socket->HelperEvents = HelperEvents;
107 Socket->LocalAddress = &Socket->WSLocalAddress;
108 Socket->SharedData.SizeOfLocalAddress = HelperData->MaxWSAddressLength;
109 Socket->RemoteAddress = &Socket->WSRemoteAddress;
110 Socket->SharedData.SizeOfRemoteAddress = HelperData->MaxWSAddressLength;
111 Socket->SharedData.UseDelayedAcceptance = HelperData->UseDelayedAcceptance;
112 Socket->SharedData.CreateFlags = dwFlags;
113 Socket->SharedData.CatalogEntryId = lpProtocolInfo->dwCatalogEntryId;
114 Socket->SharedData.ServiceFlags1 = lpProtocolInfo->dwServiceFlags1;
115 Socket->SharedData.ProviderFlags = lpProtocolInfo->dwProviderFlags;
116 Socket->SharedData.GroupID = g;
117 Socket->SharedData.GroupType = 0;
118 Socket->SharedData.UseSAN = FALSE;
119 Socket->SanData = NULL;
120
121 /* Ask alex about this */
122 if( Socket->SharedData.SocketType == SOCK_DGRAM )
123 Socket->SharedData.ServiceFlags1 |= XP1_CONNECTIONLESS;
124
125 /* Packet Size */
126 SizeOfPacket = TransportName.Length + sizeof(AFD_CREATE_PACKET) + sizeof(WCHAR);
127
128 /* EA Size */
129 SizeOfEA = SizeOfPacket + sizeof(FILE_FULL_EA_INFORMATION) + AFD_PACKET_COMMAND_LENGTH;
130
131 /* Set up EA Buffer */
132 EABuffer = HeapAlloc(GlobalHeap, 0, (SIZE_T)&SizeOfEA);
133 EABuffer->NextEntryOffset = 0;
134 EABuffer->Flags = 0;
135 EABuffer->EaNameLength = AFD_PACKET_COMMAND_LENGTH;
136 RtlCopyMemory (EABuffer->EaName,
137 AfdCommand,
138 AFD_PACKET_COMMAND_LENGTH + 1);
139 EABuffer->EaValueLength = SizeOfPacket;
140
141 /* Set up AFD Packet */
142 AfdPacket = (PAFD_CREATE_PACKET)(EABuffer->EaName + EABuffer->EaNameLength + 1);
143 AfdPacket->SizeOfTransportName = TransportName.Length;
144 RtlCopyMemory (AfdPacket->TransportName,
145 TransportName.Buffer,
146 TransportName.Length + sizeof(WCHAR));
147 AfdPacket->GroupID = g;
148
149 /* Set up Endpoint Flags */
150 if ((Socket->SharedData.ServiceFlags1 & XP1_CONNECTIONLESS) != 0) {
151 if ((SocketType != SOCK_DGRAM) && (SocketType != SOCK_RAW)) {
152 goto error; /* Only RAW or UDP can be Connectionless */
153 }
154 AfdPacket->EndpointFlags |= AFD_ENDPOINT_CONNECTIONLESS;
155 }
156
157 if ((Socket->SharedData.ServiceFlags1 & XP1_MESSAGE_ORIENTED) != 0) {
158 if (SocketType == SOCK_STREAM) {
159 if ((Socket->SharedData.ServiceFlags1 & XP1_PSEUDO_STREAM) == 0) {
160 goto error; /* The Provider doesn't actually support Message Oriented Streams */
161 }
162 }
163 AfdPacket->EndpointFlags |= AFD_ENDPOINT_MESSAGE_ORIENTED;
164 }
165
166 if (SocketType == SOCK_RAW) AfdPacket->EndpointFlags |= AFD_ENDPOINT_RAW;
167
168 if (dwFlags & (WSA_FLAG_MULTIPOINT_C_ROOT |
169 WSA_FLAG_MULTIPOINT_C_LEAF |
170 WSA_FLAG_MULTIPOINT_D_ROOT |
171 WSA_FLAG_MULTIPOINT_D_LEAF)) {
172 if ((Socket->SharedData.ServiceFlags1 & XP1_SUPPORT_MULTIPOINT) == 0) {
173 goto error; /* The Provider doesn't actually support Multipoint */
174 }
175 AfdPacket->EndpointFlags |= AFD_ENDPOINT_MULTIPOINT;
176 if (dwFlags & WSA_FLAG_MULTIPOINT_C_ROOT) {
177 if (((Socket->SharedData.ServiceFlags1 & XP1_MULTIPOINT_CONTROL_PLANE) == 0)
178 || ((dwFlags & WSA_FLAG_MULTIPOINT_C_LEAF) != 0)) {
179 goto error; /* The Provider doesn't support Control Planes, or you already gave a leaf */
180 }
181 AfdPacket->EndpointFlags |= AFD_ENDPOINT_C_ROOT;
182 }
183 if (dwFlags & WSA_FLAG_MULTIPOINT_D_ROOT) {
184 if (((Socket->SharedData.ServiceFlags1 & XP1_MULTIPOINT_DATA_PLANE) == 0)
185 || ((dwFlags & WSA_FLAG_MULTIPOINT_D_LEAF) != 0)) {
186 goto error; /* The Provider doesn't support Data Planes, or you already gave a leaf */
187 }
188 AfdPacket->EndpointFlags |= AFD_ENDPOINT_D_ROOT;
189 }
190 }
191
192 /* Set up Object Attributes */
193 InitializeObjectAttributes (&Object,
194 &DevName,
195 OBJ_CASE_INSENSITIVE | OBJ_INHERIT,
196 0,
197 0);
198
199 /* Set IO Flag */
200 if ((dwFlags & WSA_FLAG_OVERLAPPED) == 0) IOOptions = FILE_SYNCHRONOUS_IO_NONALERT;
201
202 /* Create the Socket */
203 ZwCreateFile(&Sock,
204 GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
205 &Object,
206 &IOSB,
207 NULL,
208 0,
209 FILE_SHARE_READ | FILE_SHARE_WRITE,
210 FILE_OPEN_IF,
211 IOOptions,
212 EABuffer,
213 SizeOfEA);
214
215 /* Save Handle */
216 Socket->Handle = (SOCKET)Sock;
217
218 /* Save Group Info */
219 if (g != 0) {
220 GetSocketInformation(Socket, AFD_INFO_GROUP_ID_TYPE, 0, &GroupData);
221
222 Socket->SharedData.GroupID = GroupData.u.LowPart;
223 Socket->SharedData.GroupType = GroupData.u.HighPart;
224 }
225
226 /* Get Window Sizes and Save them */
227 GetSocketInformation (Socket,
228 AFD_INFO_SEND_WINDOW_SIZE,
229 &Socket->SharedData.SizeOfSendBuffer,
230 NULL);
231 GetSocketInformation (Socket,
232 AFD_INFO_RECEIVE_WINDOW_SIZE,
233 &Socket->SharedData.SizeOfRecvBuffer,
234 NULL);
235
236 /* Save in Process Sockets List */
237 Sockets[SocketCount] = Socket;
238 SocketCount ++;
239
240 /* Create the Socket Context */
241 CreateContext(Socket);
242
243 /* Notify Winsock */
244 Upcalls.lpWPUModifyIFSHandle(1, (SOCKET)Sock, lpErrno);
245
246 /* Return Socket Handle */
247 return (SOCKET)Sock;
248
249 error:
250 AFD_DbgPrint(MID_TRACE,("Ending\n"));
251
252 *lpErrno = Status;
253
254 return INVALID_SOCKET;
255 }
256
257
258 INT
259 WSPAPI
260 WSPCloseSocket(
261 IN SOCKET s,
262 OUT LPINT lpErrno)
263 /*
264 * FUNCTION: Closes an open socket
265 * ARGUMENTS:
266 * s = Socket descriptor
267 * lpErrno = Address of buffer for error information
268 * RETURNS:
269 * NO_ERROR, or SOCKET_ERROR if the socket could not be closed
270 */
271 {
272 return 0;
273 }
274
275
276 INT
277 WSPAPI
278 WSPBind(
279 SOCKET Handle,
280 struct sockaddr *SocketAddress,
281 int SocketAddressLength,
282 LPINT lpErrno)
283 /*
284 * FUNCTION: Associates a local address with a socket
285 * ARGUMENTS:
286 * s = Socket descriptor
287 * name = Pointer to local address
288 * namelen = Length of name
289 * lpErrno = Address of buffer for error information
290 * RETURNS:
291 * 0, or SOCKET_ERROR if the socket could not be bound
292 */
293 {
294 IO_STATUS_BLOCK IOSB;
295 PAFD_BIND_DATA BindData;
296 PSOCKET_INFORMATION Socket = NULL;
297 NTSTATUS Status;
298 UCHAR BindBuffer[0x1A];
299 SOCKADDR_INFO SocketInfo;
300 HANDLE SockEvent;
301
302 Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
303 NULL, 1, FALSE );
304
305 if( !NT_SUCCESS(Status) ) return -1;
306
307 /* Get the Socket Structure associate to this Socket*/
308 Socket = GetSocketStructure(Handle);
309
310 /* Dynamic Structure...ugh */
311 BindData = (PAFD_BIND_DATA)BindBuffer;
312
313 /* Set up Address in TDI Format */
314 BindData->Address.TAAddressCount = 1;
315 BindData->Address.Address[0].AddressLength = SocketAddressLength - sizeof(SocketAddress->sa_family);
316 RtlCopyMemory (&BindData->Address.Address[0].AddressType,
317 SocketAddress,
318 SocketAddressLength);
319
320 /* Get Address Information */
321 Socket->HelperData->WSHGetSockaddrType ((PSOCKADDR)SocketAddress,
322 SocketAddressLength,
323 &SocketInfo);
324
325 /* Set the Share Type */
326 if (Socket->SharedData.ExclusiveAddressUse) {
327 BindData->ShareType = AFD_SHARE_EXCLUSIVE;
328 }
329 else if (SocketInfo.EndpointInfo == SockaddrEndpointInfoWildcard) {
330 BindData->ShareType = AFD_SHARE_WILDCARD;
331 }
332 else if (Socket->SharedData.ReuseAddresses) {
333 BindData->ShareType = AFD_SHARE_REUSE;
334 } else {
335 BindData->ShareType = AFD_SHARE_UNIQUE;
336 }
337
338 /* Send IOCTL */
339 Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
340 SockEvent,
341 NULL,
342 NULL,
343 &IOSB,
344 IOCTL_AFD_BIND,
345 BindData,
346 0xA + Socket->SharedData.SizeOfLocalAddress, /* Can't figure out a way to calculate this in C*/
347 BindData,
348 0xA + Socket->SharedData.SizeOfLocalAddress); /* Can't figure out a way to calculate this C */
349
350 /* Set up Socket Data */
351 Socket->SharedData.State = SocketBound;
352 Socket->TdiAddressHandle = (HANDLE)IOSB.Information;
353
354 NtClose( SockEvent );
355
356 return 0;
357 }
358
359 int
360 WSPAPI
361 WSPListen(
362 SOCKET Handle,
363 int Backlog,
364 LPINT lpErrno)
365 {
366 IO_STATUS_BLOCK IOSB;
367 AFD_LISTEN_DATA ListenData;
368 PSOCKET_INFORMATION Socket = NULL;
369 HANDLE SockEvent;
370 NTSTATUS Status;
371
372 Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
373 NULL, 1, FALSE );
374
375 if( !NT_SUCCESS(Status) ) return -1;
376
377 /* Get the Socket Structure associate to this Socket*/
378 Socket = GetSocketStructure(Handle);
379
380 /* Set Up Listen Structure */
381 ListenData.UseSAN = FALSE;
382 ListenData.UseDelayedAcceptance = Socket->SharedData.UseDelayedAcceptance;
383 ListenData.Backlog = Backlog;
384
385 /* Send IOCTL */
386 Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
387 SockEvent,
388 NULL,
389 NULL,
390 &IOSB,
391 IOCTL_AFD_START_LISTEN,
392 &ListenData,
393 sizeof(ListenData),
394 NULL,
395 0);
396
397 /* Set to Listening */
398 Socket->SharedData.Listening = TRUE;
399
400 NtClose( SockEvent );
401
402 return 0;
403 }
404
405
406 int
407 WSPAPI
408 WSPSelect(
409 int nfds,
410 fd_set *readfds,
411 fd_set *writefds,
412 fd_set *exceptfds,
413 struct timeval *timeout,
414 LPINT lpErrno)
415 {
416 IO_STATUS_BLOCK IOSB;
417 PAFD_POLL_INFO PollInfo;
418 NTSTATUS Status;
419 ULONG HandleCount, OutCount = 0;
420 ULONG PollBufferSize;
421 LARGE_INTEGER uSec;
422 PVOID PollBuffer;
423 ULONG i, j = 0, x;
424 HANDLE SockEvent;
425
426 Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
427 NULL, 1, FALSE );
428
429 if( !NT_SUCCESS(Status) ) return -1;
430
431 /* Find out how many sockets we have, and how large the buffer needs
432 * to be */
433
434 HandleCount =
435 ( readfds ? readfds->fd_count : 0 ) +
436 ( writefds ? writefds->fd_count : 0 ) +
437 ( exceptfds ? exceptfds->fd_count : 0 );
438 PollBufferSize = sizeof(*PollInfo) +
439 (HandleCount * sizeof(AFD_HANDLE));
440
441 /* Allocate */
442 PollBuffer = HeapAlloc(GlobalHeap, 0, PollBufferSize);
443 PollInfo = (PAFD_POLL_INFO)PollBuffer;
444
445 RtlZeroMemory( PollInfo, PollBufferSize );
446
447 /* Convert Timeout to NT Format */
448 if (timeout == NULL) {
449 PollInfo->Timeout.u.LowPart = -1;
450 PollInfo->Timeout.u.HighPart = 0x7FFFFFFF;
451 } else {
452 PollInfo->Timeout = RtlEnlargedIntegerMultiply
453 ((timeout->tv_sec * 1000) + timeout->tv_usec, -10000);
454 PollInfo->Timeout.QuadPart += uSec.QuadPart;
455 }
456
457 /* Number of handles for AFD to Check */
458 PollInfo->HandleCount = HandleCount;
459 PollInfo->InternalUse = 0;
460
461 if (readfds != NULL) {
462 for (i = 0; i < readfds->fd_count; i++, j++) {
463 PollInfo->Handles[j].Handle = readfds->fd_array[i];
464 PollInfo->Handles[j].Events = AFD_EVENT_RECEIVE | AFD_EVENT_DISCONNECT | AFD_EVENT_ABORT;
465 }
466 }
467 if (writefds != NULL) {
468 for (i = 0; i < writefds->fd_count; i++, j++) {
469 PollInfo->Handles[j].Handle = writefds->fd_array[i];
470 PollInfo->Handles[j].Events |= AFD_EVENT_SEND;
471 }
472
473 }
474 if (exceptfds != NULL) {
475 for (i = 0; i < exceptfds->fd_count; i++, j++) {
476 PollInfo->Handles[j].Handle = exceptfds->fd_array[i];
477 PollInfo->Handles[j].Events |=
478 AFD_EVENT_OOB_RECEIVE | AFD_EVENT_CONNECT_FAIL;
479 }
480 }
481
482 /* Send IOCTL */
483 Status = NtDeviceIoControlFile( (HANDLE)Sockets[0]->Handle,
484 SockEvent,
485 NULL,
486 NULL,
487 &IOSB,
488 IOCTL_AFD_SELECT,
489 PollInfo,
490 PollBufferSize,
491 PollInfo,
492 PollBufferSize);
493
494 AFD_DbgPrint(MID_TRACE,("DeviceIoControlFile => %x\n", Status));
495
496 /* Wait for Completition */
497 if (Status == STATUS_PENDING) {
498 WaitForSingleObject(SockEvent, 0);
499 }
500
501 /* Clear the Structures */
502 if( readfds ) FD_ZERO(readfds);
503 if( writefds ) FD_ZERO(writefds);
504 if( exceptfds ) FD_ZERO(exceptfds);
505
506 /* Loop through return structure */
507 HandleCount = PollInfo->HandleCount;
508
509 /* Return in FDSET Format */
510 for (i = 0; i < HandleCount; i++) {
511 for(x = 1; x; x<<=1) {
512 switch (PollInfo->Handles[i].Events & x) {
513 case AFD_EVENT_RECEIVE:
514 case AFD_EVENT_DISCONNECT:
515 case AFD_EVENT_ABORT:
516 case AFD_EVENT_ACCEPT:
517 case AFD_EVENT_CLOSE:
518 AFD_DbgPrint(MID_TRACE,("Event %x on handle %x\n",
519 PollInfo->Handles[i].Events,
520 PollInfo->Handles[i].Handle));
521 OutCount++;
522 if( readfds ) FD_SET(PollInfo->Handles[i].Handle, readfds);
523 case AFD_EVENT_SEND: case AFD_EVENT_CONNECT:
524 AFD_DbgPrint(MID_TRACE,("Event %x on handle %x\n",
525 PollInfo->Handles[i].Events,
526 PollInfo->Handles[i].Handle));
527 OutCount++;
528 if( writefds ) FD_SET(PollInfo->Handles[i].Handle, writefds);
529 break;
530
531 case AFD_EVENT_OOB_RECEIVE: case AFD_EVENT_CONNECT_FAIL:
532 AFD_DbgPrint(MID_TRACE,("Event %x on handle %x\n",
533 PollInfo->Handles[i].Events,
534 PollInfo->Handles[i].Handle));
535 OutCount++;
536 if( exceptfds ) FD_SET(PollInfo->Handles[i].Handle, exceptfds);
537 break;
538 }
539 }
540 }
541
542 NtClose( SockEvent );
543 switch( IOSB.Status ) {
544 case STATUS_SUCCESS:
545 case STATUS_TIMEOUT: *lpErrno = 0; break;
546 default: *lpErrno = WSAEINVAL;
547 }
548
549 AFD_DbgPrint(MID_TRACE,("%d events\n", OutCount));
550
551 return OutCount;
552 }
553
554 SOCKET
555 WSPAPI
556 WSPAccept(
557 SOCKET Handle,
558 struct sockaddr *SocketAddress,
559 int *SocketAddressLength,
560 LPCONDITIONPROC lpfnCondition,
561 DWORD_PTR dwCallbackData,
562 LPINT lpErrno)
563 {
564 IO_STATUS_BLOCK IOSB;
565 PAFD_RECEIVED_ACCEPT_DATA ListenReceiveData;
566 AFD_ACCEPT_DATA AcceptData;
567 AFD_DEFER_ACCEPT_DATA DeferData;
568 AFD_PENDING_ACCEPT_DATA PendingAcceptData;
569 PSOCKET_INFORMATION Socket = NULL;
570 NTSTATUS Status;
571 struct fd_set ReadSet;
572 struct timeval Timeout;
573 PVOID PendingData;
574 ULONG PendingDataLength;
575 PVOID CalleeDataBuffer;
576 WSABUF CallerData, CalleeID, CallerID, CalleeData;
577 PSOCKADDR RemoteAddress = NULL;
578 GROUP GroupID = 0;
579 ULONG CallBack;
580 WSAPROTOCOL_INFOW ProtocolInfo;
581 SOCKET AcceptSocket;
582 UCHAR ReceiveBuffer[0x1A];
583 HANDLE SockEvent;
584
585 Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
586 NULL, 1, FALSE );
587
588 if( !NT_SUCCESS(Status) ) return -1;
589
590 /* Dynamic Structure...ugh */
591 ListenReceiveData = (PAFD_RECEIVED_ACCEPT_DATA)ReceiveBuffer;
592
593 /* Get the Socket Structure associate to this Socket*/
594 Socket = GetSocketStructure(Handle);
595
596 /* If this is non-blocking, make sure there's something for us to accept */
597 FD_ZERO(&ReadSet);
598 FD_SET(Socket->Handle, &ReadSet);
599 Timeout.tv_sec=0;
600 Timeout.tv_usec=0;
601 WSPSelect(0, &ReadSet, NULL, NULL, &Timeout, NULL);
602 if (ReadSet.fd_array[0] != Socket->Handle) return 0;
603
604 /* Send IOCTL */
605 Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
606 SockEvent,
607 NULL,
608 NULL,
609 &IOSB,
610 IOCTL_AFD_WAIT_FOR_LISTEN,
611 NULL,
612 0,
613 ListenReceiveData,
614 0xA + sizeof(*ListenReceiveData));
615
616 if (lpfnCondition != NULL) {
617 if ((Socket->SharedData.ServiceFlags1 & XP1_CONNECT_DATA) != 0) {
618
619 /* Find out how much data is pending */
620 PendingAcceptData.SequenceNumber = ListenReceiveData->SequenceNumber;
621 PendingAcceptData.ReturnSize = TRUE;
622
623 /* Send IOCTL */
624 Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
625 SockEvent,
626 NULL,
627 NULL,
628 &IOSB,
629 IOCTL_AFD_GET_PENDING_CONNECT_DATA,
630 &PendingAcceptData,
631 sizeof(PendingAcceptData),
632 &PendingAcceptData,
633 sizeof(PendingAcceptData));
634
635 /* How much data to allocate */
636 PendingDataLength = IOSB.Information;
637
638 if (PendingDataLength) {
639
640 /* Allocate needed space */
641 PendingData = HeapAlloc(GlobalHeap, 0, PendingDataLength);
642
643 /* We want the data now */
644 PendingAcceptData.ReturnSize = FALSE;
645
646 /* Send IOCTL */
647 Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
648 SockEvent,
649 NULL,
650 NULL,
651 &IOSB,
652 IOCTL_AFD_GET_PENDING_CONNECT_DATA,
653 &PendingAcceptData,
654 sizeof(PendingAcceptData),
655 PendingData,
656 PendingDataLength);
657 }
658 }
659
660
661 if ((Socket->SharedData.ServiceFlags1 & XP1_QOS_SUPPORTED) != 0) {
662 /* I don't support this yet */
663 }
664
665 /* Build Callee ID */
666 CalleeID.buf = (PVOID)Socket->LocalAddress;
667 CalleeID.len = Socket->SharedData.SizeOfLocalAddress;
668
669 /* Set up Address in SOCKADDR Format */
670 RtlCopyMemory (RemoteAddress,
671 &ListenReceiveData->Address.Address[0].AddressType,
672 sizeof(RemoteAddress));
673
674 /* Build Caller ID */
675 CallerID.buf = (PVOID)RemoteAddress;
676 CallerID.len = sizeof(RemoteAddress);
677
678 /* Build Caller Data */
679 CallerData.buf = PendingData;
680 CallerData.len = PendingDataLength;
681
682 /* Check if socket supports Conditional Accept */
683 if (Socket->SharedData.UseDelayedAcceptance != 0) {
684
685 /* Allocate Buffer for Callee Data */
686 CalleeDataBuffer = HeapAlloc(GlobalHeap, 0, 4096);
687 CalleeData.buf = CalleeDataBuffer;
688 CalleeData.len = 4096;
689
690 } else {
691
692 /* Nothing */
693 CalleeData.buf = 0;
694 CalleeData.len = 0;
695 }
696
697 /* Call the Condition Function */
698 CallBack = (lpfnCondition)( &CallerID,
699 CallerData.buf == NULL
700 ? NULL
701 : & CallerData,
702 NULL,
703 NULL,
704 &CalleeID,
705 CalleeData.buf == NULL
706 ? NULL
707 : & CalleeData,
708 &GroupID,
709 dwCallbackData);
710
711 if (((CallBack == CF_ACCEPT) && GroupID) != 0) {
712 /* TBD: Check for Validity */
713 }
714
715 if (CallBack == CF_ACCEPT) {
716
717 if ((Socket->SharedData.ServiceFlags1 & XP1_QOS_SUPPORTED) != 0) {
718 /* I don't support this yet */
719 }
720
721 if (CalleeData.buf) {
722 // SockSetConnectData Sockets(SocketID), IOCTL_AFD_SET_CONNECT_DATA, CalleeData.Buffer, CalleeData.BuffSize, 0
723 }
724
725 } else {
726 /* Callback rejected. Build Defer Structure */
727 DeferData.SequenceNumber = ListenReceiveData->SequenceNumber;
728 DeferData.RejectConnection = (CallBack == CF_REJECT);
729
730 /* Send IOCTL */
731 Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
732 SockEvent,
733 NULL,
734 NULL,
735 &IOSB,
736 IOCTL_AFD_DEFER_ACCEPT,
737 &DeferData,
738 sizeof(DeferData),
739 NULL,
740 0);
741
742 NtClose( SockEvent );
743
744 if (CallBack == CF_REJECT ) {
745 return WSAECONNREFUSED;
746 } else {
747 return WSATRY_AGAIN;
748 }
749 }
750 }
751
752 /* Create a new Socket */
753 ProtocolInfo.dwCatalogEntryId = Socket->SharedData.CatalogEntryId;
754 ProtocolInfo.dwServiceFlags1 = Socket->SharedData.ServiceFlags1;
755 ProtocolInfo.dwProviderFlags = Socket->SharedData.ProviderFlags;
756 AcceptSocket = WSPSocket (Socket->SharedData.AddressFamily,
757 Socket->SharedData.SocketType,
758 Socket->SharedData.Protocol,
759 &ProtocolInfo,
760 GroupID,
761 Socket->SharedData.CreateFlags,
762 NULL);
763
764 /* Set up the Accept Structure */
765 AcceptData.ListenHandle = AcceptSocket;
766 AcceptData.SequenceNumber = ListenReceiveData->SequenceNumber;
767
768 /* Send IOCTL to Accept */
769 Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
770 SockEvent,
771 NULL,
772 NULL,
773 &IOSB,
774 IOCTL_AFD_ACCEPT,
775 &AcceptData,
776 sizeof(AcceptData),
777 NULL,
778 0);
779
780 /* Return Address in SOCKADDR FORMAT */
781 RtlCopyMemory (SocketAddress,
782 &ListenReceiveData->Address.Address[0].AddressType,
783 sizeof(RemoteAddress));
784
785 NtClose( SockEvent );
786
787 /* Return Socket */
788 return AcceptSocket;
789 }
790
791 int
792 WSPAPI
793 WSPConnect(
794 SOCKET Handle,
795 struct sockaddr * SocketAddress,
796 int SocketAddressLength,
797 LPWSABUF lpCallerData,
798 LPWSABUF lpCalleeData,
799 LPQOS lpSQOS,
800 LPQOS lpGQOS,
801 LPINT lpErrno)
802 {
803 IO_STATUS_BLOCK IOSB;
804 PAFD_CONNECT_INFO ConnectInfo;
805 PSOCKET_INFORMATION Socket = NULL;
806 NTSTATUS Status;
807 UCHAR ConnectBuffer[0x22];
808 ULONG ConnectDataLength;
809 ULONG InConnectDataLength;
810 UINT BindAddressLength;
811 PSOCKADDR BindAddress;
812 HANDLE SockEvent;
813
814 Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
815 NULL, 1, FALSE );
816
817 if( !NT_SUCCESS(Status) ) return -1;
818
819 AFD_DbgPrint(MID_TRACE,("Called\n"));
820
821 /* Get the Socket Structure associate to this Socket*/
822 Socket = GetSocketStructure(Handle);
823
824 /* Bind us First */
825 if (Socket->SharedData.State == SocketOpen) {
826
827 /* Get the Wildcard Address */
828 BindAddressLength = Socket->HelperData->MaxWSAddressLength;
829 BindAddress = HeapAlloc(GetProcessHeap(), 0, BindAddressLength);
830 Socket->HelperData->WSHGetWildcardSockaddr (Socket->HelperContext,
831 BindAddress,
832 &BindAddressLength);
833
834 /* Bind it */
835 WSPBind(Handle, BindAddress, BindAddressLength, NULL);
836 }
837
838 /* Set the Connect Data */
839 if (lpCallerData != NULL) {
840 ConnectDataLength = lpCallerData->len;
841 Status = NtDeviceIoControlFile((HANDLE)Handle,
842 SockEvent,
843 NULL,
844 NULL,
845 &IOSB,
846 IOCTL_AFD_SET_CONNECT_DATA,
847 lpCallerData->buf,
848 ConnectDataLength,
849 NULL,
850 0);
851 }
852
853 /* Dynamic Structure...ugh */
854 ConnectInfo = (PAFD_CONNECT_INFO)ConnectBuffer;
855
856 /* Set up Address in TDI Format */
857 ConnectInfo->RemoteAddress.TAAddressCount = 1;
858 ConnectInfo->RemoteAddress.Address[0].AddressLength = SocketAddressLength - sizeof(SocketAddress->sa_family);
859 RtlCopyMemory (&ConnectInfo->RemoteAddress.Address[0].AddressType,
860 SocketAddress,
861 SocketAddressLength);
862
863 /* Tell AFD that we want Connection Data back, have it allocate a buffer */
864 if (lpCalleeData != NULL) {
865 InConnectDataLength = lpCalleeData->len;
866 Status = NtDeviceIoControlFile((HANDLE)Handle,
867 SockEvent,
868 NULL,
869 NULL,
870 &IOSB,
871 IOCTL_AFD_SET_CONNECT_DATA_SIZE,
872 &InConnectDataLength,
873 sizeof(InConnectDataLength),
874 NULL,
875 0);
876 }
877
878 /* AFD doesn't seem to care if these are invalid, but let's 0 them anyways */
879 ConnectInfo->Root = 0;
880 ConnectInfo->UseSAN = FALSE;
881 ConnectInfo->Unknown = 0;
882
883 /* Send IOCTL */
884 Status = NtDeviceIoControlFile((HANDLE)Handle,
885 SockEvent,
886 NULL,
887 NULL,
888 &IOSB,
889 IOCTL_AFD_CONNECT,
890 ConnectInfo,
891 0x22,
892 NULL,
893 0);
894
895 /* Get any pending connect data */
896 if (lpCalleeData != NULL) {
897 Status = NtDeviceIoControlFile((HANDLE)Handle,
898 SockEvent,
899 NULL,
900 NULL,
901 &IOSB,
902 IOCTL_AFD_GET_CONNECT_DATA,
903 NULL,
904 0,
905 lpCalleeData->buf,
906 lpCalleeData->len);
907 }
908
909 AFD_DbgPrint(MID_TRACE,("Ending\n"));
910
911 NtClose( SockEvent );
912
913 return Status;
914 }
915 int
916 WSPAPI
917 WSPShutdown(
918 SOCKET Handle,
919 int HowTo,
920 LPINT lpErrno)
921
922 {
923 IO_STATUS_BLOCK IOSB;
924 AFD_DISCONNECT_INFO DisconnectInfo;
925 PSOCKET_INFORMATION Socket = NULL;
926 NTSTATUS Status;
927 HANDLE SockEvent;
928
929 Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
930 NULL, 1, FALSE );
931
932 if( !NT_SUCCESS(Status) ) return -1;
933
934 AFD_DbgPrint(MID_TRACE,("Called\n"));
935
936 /* Get the Socket Structure associate to this Socket*/
937 Socket = GetSocketStructure(Handle);
938
939 /* Set AFD Disconnect Type */
940 switch (HowTo) {
941
942 case SD_RECEIVE:
943 DisconnectInfo.DisconnectType = AFD_DISCONNECT_RECV;
944 Socket->SharedData.ReceiveShutdown = TRUE;
945 break;
946
947 case SD_SEND:
948 DisconnectInfo.DisconnectType= AFD_DISCONNECT_SEND;
949 Socket->SharedData.SendShutdown = TRUE;
950 break;
951
952 case SD_BOTH:
953 DisconnectInfo.DisconnectType = AFD_DISCONNECT_RECV | AFD_DISCONNECT_SEND;
954 Socket->SharedData.ReceiveShutdown = TRUE;
955 Socket->SharedData.SendShutdown = TRUE;
956 break;
957 }
958
959 DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(-1);
960
961 /* Send IOCTL */
962 Status = NtDeviceIoControlFile((HANDLE)Handle,
963 SockEvent,
964 NULL,
965 NULL,
966 &IOSB,
967 IOCTL_AFD_DISCONNECT,
968 &DisconnectInfo,
969 sizeof(DisconnectInfo),
970 NULL,
971 0);
972
973 /* Wait for return */
974 if (Status == STATUS_PENDING) {
975 WaitForSingleObject(SockEvent, 0);
976 }
977
978 AFD_DbgPrint(MID_TRACE,("Ending\n"));
979
980 NtClose( SockEvent );
981
982 return 0;
983 }
984
985
986 INT
987 WSPAPI
988 WSPGetSockName(
989 IN SOCKET s,
990 OUT LPSOCKADDR name,
991 IN OUT LPINT namelen,
992 OUT LPINT lpErrno)
993 {
994 return 0;
995 }
996
997
998 INT
999 WSPAPI
1000 WSPGetPeerName(
1001 IN SOCKET s,
1002 OUT LPSOCKADDR name,
1003 IN OUT LPINT namelen,
1004 OUT LPINT lpErrno)
1005 {
1006
1007 return 0;
1008 }
1009
1010 INT
1011 WSPAPI
1012 WSPIoctl(
1013 IN SOCKET Handle,
1014 IN DWORD dwIoControlCode,
1015 IN LPVOID lpvInBuffer,
1016 IN DWORD cbInBuffer,
1017 OUT LPVOID lpvOutBuffer,
1018 IN DWORD cbOutBuffer,
1019 OUT LPDWORD lpcbBytesReturned,
1020 IN LPWSAOVERLAPPED lpOverlapped,
1021 IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
1022 IN LPWSATHREADID lpThreadId,
1023 OUT LPINT lpErrno)
1024 {
1025 PSOCKET_INFORMATION Socket = NULL;
1026
1027 /* Get the Socket Structure associate to this Socket*/
1028 Socket = GetSocketStructure(Handle);
1029
1030 switch( dwIoControlCode ) {
1031 case FIONBIO:
1032 if( cbInBuffer < sizeof(INT) ) return -1;
1033 Socket->SharedData.NonBlocking = *((PINT)lpvInBuffer) ? 1 : 0;
1034 AFD_DbgPrint(MID_TRACE,("[%x] Set nonblocking %d\n",
1035 Handle, Socket->SharedData.NonBlocking));
1036 return 0;
1037 default:
1038 return -1;
1039 }
1040 }
1041
1042
1043 INT
1044 WSPAPI
1045 WSPStartup(
1046 IN WORD wVersionRequested,
1047 OUT LPWSPDATA lpWSPData,
1048 IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
1049 IN WSPUPCALLTABLE UpcallTable,
1050 OUT LPWSPPROC_TABLE lpProcTable)
1051 /*
1052 * FUNCTION: Initialize service provider for a client
1053 * ARGUMENTS:
1054 * wVersionRequested = Highest WinSock SPI version that the caller can use
1055 * lpWSPData = Address of WSPDATA structure to initialize
1056 * lpProtocolInfo = Pointer to structure that defines the desired protocol
1057 * UpcallTable = Pointer to upcall table of the WinSock DLL
1058 * lpProcTable = Address of procedure table to initialize
1059 * RETURNS:
1060 * Status of operation
1061 */
1062 {
1063 NTSTATUS Status;
1064
1065 AFD_DbgPrint(MAX_TRACE, ("wVersionRequested (0x%X) \n", wVersionRequested));
1066
1067 Status = NO_ERROR;
1068
1069 Upcalls = UpcallTable;
1070
1071 if (Status == NO_ERROR) {
1072 lpProcTable->lpWSPAccept = WSPAccept;
1073 lpProcTable->lpWSPAddressToString = WSPAddressToString;
1074 lpProcTable->lpWSPAsyncSelect = WSPAsyncSelect;
1075 lpProcTable->lpWSPBind = (LPWSPBIND)WSPBind;
1076 lpProcTable->lpWSPCancelBlockingCall = WSPCancelBlockingCall;
1077 lpProcTable->lpWSPCleanup = WSPCleanup;
1078 lpProcTable->lpWSPCloseSocket = WSPCloseSocket;
1079 lpProcTable->lpWSPConnect = (LPWSPCONNECT)WSPConnect;
1080 lpProcTable->lpWSPDuplicateSocket = WSPDuplicateSocket;
1081 lpProcTable->lpWSPEnumNetworkEvents = WSPEnumNetworkEvents;
1082 lpProcTable->lpWSPEventSelect = WSPEventSelect;
1083 lpProcTable->lpWSPGetOverlappedResult = WSPGetOverlappedResult;
1084 lpProcTable->lpWSPGetPeerName = WSPGetPeerName;
1085 lpProcTable->lpWSPGetSockName = WSPGetSockName;
1086 lpProcTable->lpWSPGetSockOpt = WSPGetSockOpt;
1087 lpProcTable->lpWSPGetQOSByName = WSPGetQOSByName;
1088 lpProcTable->lpWSPIoctl = WSPIoctl;
1089 lpProcTable->lpWSPJoinLeaf = (LPWSPJOINLEAF)WSPJoinLeaf;
1090 lpProcTable->lpWSPListen = WSPListen;
1091 lpProcTable->lpWSPRecv = WSPRecv;
1092 lpProcTable->lpWSPRecvDisconnect = WSPRecvDisconnect;
1093 lpProcTable->lpWSPRecvFrom = WSPRecvFrom;
1094 lpProcTable->lpWSPSelect = WSPSelect;
1095 lpProcTable->lpWSPSend = WSPSend;
1096 lpProcTable->lpWSPSendDisconnect = WSPSendDisconnect;
1097 lpProcTable->lpWSPSendTo = (LPWSPSENDTO)WSPSendTo;
1098 lpProcTable->lpWSPSetSockOpt = WSPSetSockOpt;
1099 lpProcTable->lpWSPShutdown = WSPShutdown;
1100 lpProcTable->lpWSPSocket = WSPSocket;
1101 lpProcTable->lpWSPStringToAddress = WSPStringToAddress;
1102
1103 lpWSPData->wVersion = MAKEWORD(2, 2);
1104 lpWSPData->wHighVersion = MAKEWORD(2, 2);
1105 }
1106
1107 AFD_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status));
1108
1109 return Status;
1110 }
1111
1112
1113 INT
1114 WSPAPI
1115 WSPCleanup(
1116 OUT LPINT lpErrno)
1117 /*
1118 * FUNCTION: Cleans up service provider for a client
1119 * ARGUMENTS:
1120 * lpErrno = Address of buffer for error information
1121 * RETURNS:
1122 * 0 if successful, or SOCKET_ERROR if not
1123 */
1124 {
1125 AFD_DbgPrint(MAX_TRACE, ("\n"));
1126
1127
1128 AFD_DbgPrint(MAX_TRACE, ("Leaving.\n"));
1129
1130 *lpErrno = NO_ERROR;
1131
1132 return 0;
1133 }
1134
1135
1136
1137 int
1138 GetSocketInformation(
1139 PSOCKET_INFORMATION Socket,
1140 ULONG AfdInformationClass,
1141 PULONG Ulong OPTIONAL,
1142 PLARGE_INTEGER LargeInteger OPTIONAL)
1143 {
1144 IO_STATUS_BLOCK IOSB;
1145 AFD_INFO InfoData;
1146 NTSTATUS Status;
1147 HANDLE SockEvent;
1148
1149 Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
1150 NULL, 1, FALSE );
1151
1152 if( !NT_SUCCESS(Status) ) return -1;
1153
1154 /* Set Info Class */
1155 InfoData.InformationClass = AfdInformationClass;
1156
1157 /* Send IOCTL */
1158 Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
1159 SockEvent,
1160 NULL,
1161 NULL,
1162 &IOSB,
1163 IOCTL_AFD_GET_INFO,
1164 &InfoData,
1165 sizeof(InfoData),
1166 &InfoData,
1167 sizeof(InfoData));
1168
1169 /* Wait for return */
1170 if (Status == STATUS_PENDING) {
1171 WaitForSingleObject(SockEvent, 0);
1172 }
1173
1174 /* Return Information */
1175 *Ulong = InfoData.Information.Ulong;
1176 if (LargeInteger != NULL) {
1177 *LargeInteger = InfoData.Information.LargeInteger;
1178 }
1179
1180 NtClose( SockEvent );
1181
1182 return 0;
1183
1184 }
1185
1186
1187 int
1188 SetSocketInformation(
1189 PSOCKET_INFORMATION Socket,
1190 ULONG AfdInformationClass,
1191 PULONG Ulong OPTIONAL,
1192 PLARGE_INTEGER LargeInteger OPTIONAL)
1193 {
1194 IO_STATUS_BLOCK IOSB;
1195 AFD_INFO InfoData;
1196 NTSTATUS Status;
1197 HANDLE SockEvent;
1198
1199 Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
1200 NULL, 1, FALSE );
1201
1202 if( !NT_SUCCESS(Status) ) return -1;
1203
1204 /* Set Info Class */
1205 InfoData.InformationClass = AfdInformationClass;
1206
1207 /* Set Information */
1208 InfoData.Information.Ulong = *Ulong;
1209 if (LargeInteger != NULL) {
1210 InfoData.Information.LargeInteger = *LargeInteger;
1211 }
1212
1213 /* Send IOCTL */
1214 Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
1215 SockEvent,
1216 NULL,
1217 NULL,
1218 &IOSB,
1219 IOCTL_AFD_GET_INFO,
1220 &InfoData,
1221 sizeof(InfoData),
1222 NULL,
1223 0);
1224
1225 /* Wait for return */
1226 if (Status == STATUS_PENDING) {
1227 WaitForSingleObject(SockEvent, 0);
1228 }
1229
1230 NtClose( SockEvent );
1231
1232 return 0;
1233
1234 }
1235
1236 PSOCKET_INFORMATION
1237 GetSocketStructure(
1238 SOCKET Handle)
1239 {
1240 ULONG i;
1241
1242 for (i=0; i<SocketCount; i++) {
1243 if (Sockets[i]->Handle == Handle) {
1244 return Sockets[i];
1245 }
1246 }
1247 return 0;
1248 }
1249
1250 int CreateContext(PSOCKET_INFORMATION Socket)
1251 {
1252 IO_STATUS_BLOCK IOSB;
1253 SOCKET_CONTEXT ContextData;
1254 NTSTATUS Status;
1255 HANDLE SockEvent;
1256
1257 Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
1258 NULL, 1, FALSE );
1259
1260 if( !NT_SUCCESS(Status) ) return -1;
1261
1262 /* Create Context */
1263 ContextData.SharedData = Socket->SharedData;
1264 ContextData.SizeOfHelperData = 0;
1265 RtlCopyMemory (&ContextData.LocalAddress,
1266 Socket->LocalAddress,
1267 Socket->SharedData.SizeOfLocalAddress);
1268 RtlCopyMemory (&ContextData.RemoteAddress,
1269 Socket->RemoteAddress,
1270 Socket->SharedData.SizeOfRemoteAddress);
1271
1272 /* Send IOCTL */
1273 Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
1274 SockEvent,
1275 NULL,
1276 NULL,
1277 &IOSB,
1278 IOCTL_AFD_SET_CONTEXT,
1279 &ContextData,
1280 sizeof(ContextData),
1281 NULL,
1282 0);
1283
1284 /* Wait for Completition */
1285 if (Status == STATUS_PENDING) {
1286 WaitForSingleObject(SockEvent, 0);
1287 }
1288
1289 NtClose( SockEvent );
1290
1291 return 0;
1292 }
1293
1294 BOOL
1295 STDCALL
1296 DllMain(HANDLE hInstDll,
1297 ULONG dwReason,
1298 PVOID Reserved)
1299 {
1300
1301 switch (dwReason) {
1302 case DLL_PROCESS_ATTACH:
1303
1304 AFD_DbgPrint(MAX_TRACE, ("Loading MSAFD.DLL \n"));
1305
1306 /* Don't need thread attach notifications
1307 so disable them to improve performance */
1308 DisableThreadLibraryCalls(hInstDll);
1309
1310 /* List of DLL Helpers */
1311 InitializeListHead(&SockHelpersListHead);
1312
1313 /* Heap to use when allocating */
1314 GlobalHeap = GetProcessHeap();
1315
1316 /* Allocate Heap for 1024 Sockets, can be expanded later */
1317 Sockets = HeapAlloc(GetProcessHeap(), 0, sizeof(PSOCKET_INFORMATION) * 1024);
1318
1319 AFD_DbgPrint(MAX_TRACE, ("MSAFD.DLL has been loaded\n"));
1320
1321 break;
1322
1323 case DLL_THREAD_ATTACH:
1324 break;
1325
1326 case DLL_THREAD_DETACH:
1327 break;
1328
1329 case DLL_PROCESS_DETACH:
1330 break;
1331 }
1332
1333 AFD_DbgPrint(MAX_TRACE, ("DllMain of msafd.dll (leaving)\n"));
1334
1335 return TRUE;
1336 }
1337
1338 /* EOF */
1339
1340