/dll/win32/msafd/misc/dllmain.c
C | 3025 lines | 2301 code | 424 blank | 300 comment | 367 complexity | 0e9108fd373225420c56433e6347f8f6 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
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 13#include <msafd.h> 14 15#if DBG 16//DWORD DebugTraceLevel = DEBUG_ULTRA; 17DWORD DebugTraceLevel = 0; 18#endif /* DBG */ 19 20HANDLE GlobalHeap; 21WSPUPCALLTABLE Upcalls; 22LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest; 23PSOCKET_INFORMATION SocketListHead = NULL; 24CRITICAL_SECTION SocketListLock; 25LIST_ENTRY SockHelpersListHead = { NULL, NULL }; 26ULONG SockAsyncThreadRefCount; 27HANDLE SockAsyncHelperAfdHandle; 28HANDLE SockAsyncCompletionPort = NULL; 29BOOLEAN SockAsyncSelectCalled; 30 31 32 33/* 34 * FUNCTION: Creates a new socket 35 * ARGUMENTS: 36 * af = Address family 37 * type = Socket type 38 * protocol = Protocol type 39 * lpProtocolInfo = Pointer to protocol information 40 * g = Reserved 41 * dwFlags = Socket flags 42 * lpErrno = Address of buffer for error information 43 * RETURNS: 44 * Created socket, or INVALID_SOCKET if it could not be created 45 */ 46SOCKET 47WSPAPI 48WSPSocket(int AddressFamily, 49 int SocketType, 50 int Protocol, 51 LPWSAPROTOCOL_INFOW lpProtocolInfo, 52 GROUP g, 53 DWORD dwFlags, 54 LPINT lpErrno) 55{ 56 OBJECT_ATTRIBUTES Object; 57 IO_STATUS_BLOCK IOSB; 58 USHORT SizeOfPacket; 59 ULONG SizeOfEA; 60 PAFD_CREATE_PACKET AfdPacket; 61 HANDLE Sock; 62 PSOCKET_INFORMATION Socket = NULL; 63 PFILE_FULL_EA_INFORMATION EABuffer = NULL; 64 PHELPER_DATA HelperData; 65 PVOID HelperDLLContext; 66 DWORD HelperEvents; 67 UNICODE_STRING TransportName; 68 UNICODE_STRING DevName; 69 LARGE_INTEGER GroupData; 70 INT Status; 71 72 AFD_DbgPrint(MAX_TRACE, ("Creating Socket, getting TDI Name\n")); 73 AFD_DbgPrint(MAX_TRACE, ("AddressFamily (%d) SocketType (%d) Protocol (%d).\n", 74 AddressFamily, SocketType, Protocol)); 75 76 /* Get Helper Data and Transport */ 77 Status = SockGetTdiName (&AddressFamily, 78 &SocketType, 79 &Protocol, 80 g, 81 dwFlags, 82 &TransportName, 83 &HelperDLLContext, 84 &HelperData, 85 &HelperEvents); 86 87 /* Check for error */ 88 if (Status != NO_ERROR) 89 { 90 AFD_DbgPrint(MID_TRACE,("SockGetTdiName: Status %x\n", Status)); 91 goto error; 92 } 93 94 /* AFD Device Name */ 95 RtlInitUnicodeString(&DevName, L"\\Device\\Afd\\Endpoint"); 96 97 /* Set Socket Data */ 98 Socket = HeapAlloc(GlobalHeap, 0, sizeof(*Socket)); 99 if (!Socket) 100 return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL); 101 102 RtlZeroMemory(Socket, sizeof(*Socket)); 103 Socket->RefCount = 2; 104 Socket->Handle = -1; 105 Socket->SharedData.Listening = FALSE; 106 Socket->SharedData.State = SocketOpen; 107 Socket->SharedData.AddressFamily = AddressFamily; 108 Socket->SharedData.SocketType = SocketType; 109 Socket->SharedData.Protocol = Protocol; 110 Socket->HelperContext = HelperDLLContext; 111 Socket->HelperData = HelperData; 112 Socket->HelperEvents = HelperEvents; 113 Socket->LocalAddress = &Socket->WSLocalAddress; 114 Socket->SharedData.SizeOfLocalAddress = HelperData->MaxWSAddressLength; 115 Socket->RemoteAddress = &Socket->WSRemoteAddress; 116 Socket->SharedData.SizeOfRemoteAddress = HelperData->MaxWSAddressLength; 117 Socket->SharedData.UseDelayedAcceptance = HelperData->UseDelayedAcceptance; 118 Socket->SharedData.CreateFlags = dwFlags; 119 Socket->SharedData.CatalogEntryId = lpProtocolInfo->dwCatalogEntryId; 120 Socket->SharedData.ServiceFlags1 = lpProtocolInfo->dwServiceFlags1; 121 Socket->SharedData.ProviderFlags = lpProtocolInfo->dwProviderFlags; 122 Socket->SharedData.GroupID = g; 123 Socket->SharedData.GroupType = 0; 124 Socket->SharedData.UseSAN = FALSE; 125 Socket->SharedData.NonBlocking = FALSE; /* Sockets start blocking */ 126 Socket->SanData = NULL; 127 128 /* Ask alex about this */ 129 if( Socket->SharedData.SocketType == SOCK_DGRAM || 130 Socket->SharedData.SocketType == SOCK_RAW ) 131 { 132 AFD_DbgPrint(MID_TRACE,("Connectionless socket\n")); 133 Socket->SharedData.ServiceFlags1 |= XP1_CONNECTIONLESS; 134 } 135 136 /* Packet Size */ 137 SizeOfPacket = TransportName.Length + sizeof(AFD_CREATE_PACKET) + sizeof(WCHAR); 138 139 /* EA Size */ 140 SizeOfEA = SizeOfPacket + sizeof(FILE_FULL_EA_INFORMATION) + AFD_PACKET_COMMAND_LENGTH; 141 142 /* Set up EA Buffer */ 143 EABuffer = HeapAlloc(GlobalHeap, 0, SizeOfEA); 144 if (!EABuffer) 145 return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL); 146 147 RtlZeroMemory(EABuffer, SizeOfEA); 148 EABuffer->NextEntryOffset = 0; 149 EABuffer->Flags = 0; 150 EABuffer->EaNameLength = AFD_PACKET_COMMAND_LENGTH; 151 RtlCopyMemory (EABuffer->EaName, 152 AfdCommand, 153 AFD_PACKET_COMMAND_LENGTH + 1); 154 EABuffer->EaValueLength = SizeOfPacket; 155 156 /* Set up AFD Packet */ 157 AfdPacket = (PAFD_CREATE_PACKET)(EABuffer->EaName + EABuffer->EaNameLength + 1); 158 AfdPacket->SizeOfTransportName = TransportName.Length; 159 RtlCopyMemory (AfdPacket->TransportName, 160 TransportName.Buffer, 161 TransportName.Length + sizeof(WCHAR)); 162 AfdPacket->GroupID = g; 163 164 /* Set up Endpoint Flags */ 165 if ((Socket->SharedData.ServiceFlags1 & XP1_CONNECTIONLESS) != 0) 166 { 167 if ((SocketType != SOCK_DGRAM) && (SocketType != SOCK_RAW)) 168 { 169 /* Only RAW or UDP can be Connectionless */ 170 goto error; 171 } 172 AfdPacket->EndpointFlags |= AFD_ENDPOINT_CONNECTIONLESS; 173 } 174 175 if ((Socket->SharedData.ServiceFlags1 & XP1_MESSAGE_ORIENTED) != 0) 176 { 177 if (SocketType == SOCK_STREAM) 178 { 179 if ((Socket->SharedData.ServiceFlags1 & XP1_PSEUDO_STREAM) == 0) 180 { 181 /* The Provider doesn't actually support Message Oriented Streams */ 182 goto error; 183 } 184 } 185 AfdPacket->EndpointFlags |= AFD_ENDPOINT_MESSAGE_ORIENTED; 186 } 187 188 if (SocketType == SOCK_RAW) AfdPacket->EndpointFlags |= AFD_ENDPOINT_RAW; 189 190 if (dwFlags & (WSA_FLAG_MULTIPOINT_C_ROOT | 191 WSA_FLAG_MULTIPOINT_C_LEAF | 192 WSA_FLAG_MULTIPOINT_D_ROOT | 193 WSA_FLAG_MULTIPOINT_D_LEAF)) 194 { 195 if ((Socket->SharedData.ServiceFlags1 & XP1_SUPPORT_MULTIPOINT) == 0) 196 { 197 /* The Provider doesn't actually support Multipoint */ 198 goto error; 199 } 200 AfdPacket->EndpointFlags |= AFD_ENDPOINT_MULTIPOINT; 201 202 if (dwFlags & WSA_FLAG_MULTIPOINT_C_ROOT) 203 { 204 if (((Socket->SharedData.ServiceFlags1 & XP1_MULTIPOINT_CONTROL_PLANE) == 0) 205 || ((dwFlags & WSA_FLAG_MULTIPOINT_C_LEAF) != 0)) 206 { 207 /* The Provider doesn't support Control Planes, or you already gave a leaf */ 208 goto error; 209 } 210 AfdPacket->EndpointFlags |= AFD_ENDPOINT_C_ROOT; 211 } 212 213 if (dwFlags & WSA_FLAG_MULTIPOINT_D_ROOT) 214 { 215 if (((Socket->SharedData.ServiceFlags1 & XP1_MULTIPOINT_DATA_PLANE) == 0) 216 || ((dwFlags & WSA_FLAG_MULTIPOINT_D_LEAF) != 0)) 217 { 218 /* The Provider doesn't support Data Planes, or you already gave a leaf */ 219 goto error; 220 } 221 AfdPacket->EndpointFlags |= AFD_ENDPOINT_D_ROOT; 222 } 223 } 224 225 /* Set up Object Attributes */ 226 InitializeObjectAttributes (&Object, 227 &DevName, 228 OBJ_CASE_INSENSITIVE | OBJ_INHERIT, 229 0, 230 0); 231 232 /* Create the Socket as asynchronous. That means we have to block 233 ourselves after every call to NtDeviceIoControlFile. This is 234 because the kernel doesn't support overlapping synchronous I/O 235 requests (made from multiple threads) at this time (Sep 2005) */ 236 Status = NtCreateFile(&Sock, 237 GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 238 &Object, 239 &IOSB, 240 NULL, 241 0, 242 FILE_SHARE_READ | FILE_SHARE_WRITE, 243 FILE_OPEN_IF, 244 0, 245 EABuffer, 246 SizeOfEA); 247 248 HeapFree(GlobalHeap, 0, EABuffer); 249 250 if (Status != STATUS_SUCCESS) 251 { 252 AFD_DbgPrint(MIN_TRACE, ("Failed to open socket\n")); 253 254 HeapFree(GlobalHeap, 0, Socket); 255 256 return MsafdReturnWithErrno(Status, lpErrno, 0, NULL); 257 } 258 259 /* Save Handle */ 260 Socket->Handle = (SOCKET)Sock; 261 262 /* Save Group Info */ 263 if (g != 0) 264 { 265 GetSocketInformation(Socket, AFD_INFO_GROUP_ID_TYPE, NULL, NULL, &GroupData); 266 Socket->SharedData.GroupID = GroupData.u.LowPart; 267 Socket->SharedData.GroupType = GroupData.u.HighPart; 268 } 269 270 /* Get Window Sizes and Save them */ 271 GetSocketInformation (Socket, 272 AFD_INFO_SEND_WINDOW_SIZE, 273 NULL, 274 &Socket->SharedData.SizeOfSendBuffer, 275 NULL); 276 277 GetSocketInformation (Socket, 278 AFD_INFO_RECEIVE_WINDOW_SIZE, 279 NULL, 280 &Socket->SharedData.SizeOfRecvBuffer, 281 NULL); 282 283 /* Save in Process Sockets List */ 284 EnterCriticalSection(&SocketListLock); 285 Socket->NextSocket = SocketListHead; 286 SocketListHead = Socket; 287 LeaveCriticalSection(&SocketListLock); 288 289 /* Create the Socket Context */ 290 CreateContext(Socket); 291 292 /* Notify Winsock */ 293 Upcalls.lpWPUModifyIFSHandle(1, (SOCKET)Sock, lpErrno); 294 295 /* Return Socket Handle */ 296 AFD_DbgPrint(MID_TRACE,("Success %x\n", Sock)); 297 298 return (SOCKET)Sock; 299 300error: 301 AFD_DbgPrint(MID_TRACE,("Ending %x\n", Status)); 302 303 if( Socket ) 304 HeapFree(GlobalHeap, 0, Socket); 305 306 if( lpErrno ) 307 *lpErrno = Status; 308 309 return INVALID_SOCKET; 310} 311 312INT 313TranslateNtStatusError(NTSTATUS Status) 314{ 315 switch (Status) 316 { 317 case STATUS_CANT_WAIT: 318 return WSAEWOULDBLOCK; 319 320 case STATUS_TIMEOUT: 321 return WSAETIMEDOUT; 322 323 case STATUS_SUCCESS: 324 return NO_ERROR; 325 326 case STATUS_FILE_CLOSED: 327 case STATUS_END_OF_FILE: 328 return WSAESHUTDOWN; 329 330 case STATUS_PENDING: 331 return WSA_IO_PENDING; 332 333 case STATUS_BUFFER_TOO_SMALL: 334 case STATUS_BUFFER_OVERFLOW: 335 DbgPrint("MSAFD: STATUS_BUFFER_TOO_SMALL/STATUS_BUFFER_OVERFLOW\n"); 336 return WSAEMSGSIZE; 337 338 case STATUS_NO_MEMORY: 339 case STATUS_INSUFFICIENT_RESOURCES: 340 DbgPrint("MSAFD: STATUS_NO_MEMORY/STATUS_INSUFFICIENT_RESOURCES\n"); 341 return WSAENOBUFS; 342 343 case STATUS_INVALID_CONNECTION: 344 DbgPrint("MSAFD: STATUS_INVALID_CONNECTION\n"); 345 return WSAEAFNOSUPPORT; 346 347 case STATUS_INVALID_ADDRESS: 348 DbgPrint("MSAFD: STATUS_INVALID_ADDRESS\n"); 349 return WSAEADDRNOTAVAIL; 350 351 case STATUS_REMOTE_NOT_LISTENING: 352 DbgPrint("MSAFD: STATUS_REMOTE_NOT_LISTENING\n"); 353 return WSAECONNREFUSED; 354 355 case STATUS_NETWORK_UNREACHABLE: 356 DbgPrint("MSAFD: STATUS_NETWORK_UNREACHABLE\n"); 357 return WSAENETUNREACH; 358 359 case STATUS_INVALID_PARAMETER: 360 DbgPrint("MSAFD: STATUS_INVALID_PARAMETER\n"); 361 return WSAEINVAL; 362 363 case STATUS_CANCELLED: 364 DbgPrint("MSAFD: STATUS_CANCELLED\n"); 365 return WSA_OPERATION_ABORTED; 366 367 case STATUS_ADDRESS_ALREADY_EXISTS: 368 DbgPrint("MSAFD: STATUS_ADDRESS_ALREADY_EXISTS\n"); 369 return WSAEADDRINUSE; 370 371 case STATUS_LOCAL_DISCONNECT: 372 DbgPrint("MSAFD: STATUS_LOCAL_DISCONNECT\n"); 373 return WSAECONNABORTED; 374 375 case STATUS_REMOTE_DISCONNECT: 376 DbgPrint("MSAFD: STATUS_REMOTE_DISCONNECT\n"); 377 return WSAECONNRESET; 378 379 default: 380 DbgPrint("MSAFD: Unhandled NTSTATUS value: 0x%x\n", Status); 381 return WSAENETDOWN; 382 } 383} 384 385/* 386 * FUNCTION: Closes an open socket 387 * ARGUMENTS: 388 * s = Socket descriptor 389 * lpErrno = Address of buffer for error information 390 * RETURNS: 391 * NO_ERROR, or SOCKET_ERROR if the socket could not be closed 392 */ 393INT 394WSPAPI 395WSPCloseSocket(IN SOCKET Handle, 396 OUT LPINT lpErrno) 397{ 398 IO_STATUS_BLOCK IoStatusBlock; 399 PSOCKET_INFORMATION Socket = NULL, CurrentSocket; 400 NTSTATUS Status; 401 HANDLE SockEvent; 402 AFD_DISCONNECT_INFO DisconnectInfo; 403 SOCKET_STATE OldState; 404 LONG LingerWait = -1; 405 406 /* Create the Wait Event */ 407 Status = NtCreateEvent(&SockEvent, 408 GENERIC_READ | GENERIC_WRITE, 409 NULL, 410 1, 411 FALSE); 412 413 if(!NT_SUCCESS(Status)) 414 return SOCKET_ERROR; 415 416 /* Get the Socket Structure associate to this Socket*/ 417 Socket = GetSocketStructure(Handle); 418 if (!Socket) 419 { 420 NtClose(SockEvent); 421 *lpErrno = WSAENOTSOCK; 422 return SOCKET_ERROR; 423 } 424 425 if (Socket->HelperEvents & WSH_NOTIFY_CLOSE) 426 { 427 Status = Socket->HelperData->WSHNotify(Socket->HelperContext, 428 Socket->Handle, 429 Socket->TdiAddressHandle, 430 Socket->TdiConnectionHandle, 431 WSH_NOTIFY_CLOSE); 432 433 if (Status) 434 { 435 if (lpErrno) *lpErrno = Status; 436 NtClose(SockEvent); 437 return SOCKET_ERROR; 438 } 439 } 440 441 /* If a Close is already in Process, give up */ 442 if (Socket->SharedData.State == SocketClosed) 443 { 444 NtClose(SockEvent); 445 *lpErrno = WSAENOTSOCK; 446 return SOCKET_ERROR; 447 } 448 449 /* Set the state to close */ 450 OldState = Socket->SharedData.State; 451 Socket->SharedData.State = SocketClosed; 452 453 /* If SO_LINGER is ON and the Socket is connected, we need to disconnect */ 454 /* FIXME: Should we do this on Datagram Sockets too? */ 455 if ((OldState == SocketConnected) && (Socket->SharedData.LingerData.l_onoff)) 456 { 457 ULONG SendsInProgress; 458 ULONG SleepWait; 459 460 /* We need to respect the timeout */ 461 SleepWait = 100; 462 LingerWait = Socket->SharedData.LingerData.l_linger * 1000; 463 464 /* Loop until no more sends are pending, within the timeout */ 465 while (LingerWait) 466 { 467 /* Find out how many Sends are in Progress */ 468 if (GetSocketInformation(Socket, 469 AFD_INFO_SENDS_IN_PROGRESS, 470 NULL, 471 &SendsInProgress, 472 NULL)) 473 { 474 /* Bail out if anything but NO_ERROR */ 475 LingerWait = 0; 476 break; 477 } 478 479 /* Bail out if no more sends are pending */ 480 if (!SendsInProgress) 481 { 482 LingerWait = -1; 483 break; 484 } 485 486 /* 487 * We have to execute a sleep, so it's kind of like 488 * a block. If the socket is Nonblock, we cannot 489 * go on since asyncronous operation is expected 490 * and we cannot offer it 491 */ 492 if (Socket->SharedData.NonBlocking) 493 { 494 NtClose(SockEvent); 495 Socket->SharedData.State = OldState; 496 *lpErrno = WSAEWOULDBLOCK; 497 return SOCKET_ERROR; 498 } 499 500 /* Now we can sleep, and decrement the linger wait */ 501 /* 502 * FIXME: It seems Windows does some funky acceleration 503 * since the waiting seems to be longer and longer. I 504 * don't think this improves performance so much, so we 505 * wait a fixed time instead. 506 */ 507 Sleep(SleepWait); 508 LingerWait -= SleepWait; 509 } 510 } 511 512 if (OldState == SocketConnected) 513 { 514 if (LingerWait <= 0) 515 { 516 DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(0); 517 DisconnectInfo.DisconnectType = LingerWait < 0 ? AFD_DISCONNECT_SEND : AFD_DISCONNECT_ABORT; 518 519 if (((DisconnectInfo.DisconnectType & AFD_DISCONNECT_SEND) && (!Socket->SharedData.SendShutdown)) || 520 ((DisconnectInfo.DisconnectType & AFD_DISCONNECT_ABORT) && (!Socket->SharedData.ReceiveShutdown))) 521 { 522 /* Send IOCTL */ 523 Status = NtDeviceIoControlFile((HANDLE)Handle, 524 SockEvent, 525 NULL, 526 NULL, 527 &IoStatusBlock, 528 IOCTL_AFD_DISCONNECT, 529 &DisconnectInfo, 530 sizeof(DisconnectInfo), 531 NULL, 532 0); 533 534 /* Wait for return */ 535 if (Status == STATUS_PENDING) 536 { 537 WaitForSingleObject(SockEvent, INFINITE); 538 Status = IoStatusBlock.Status; 539 } 540 } 541 } 542 } 543 544 /* Cleanup Time! */ 545 Socket->HelperContext = NULL; 546 Socket->SharedData.AsyncDisabledEvents = -1; 547 NtClose(Socket->TdiAddressHandle); 548 Socket->TdiAddressHandle = NULL; 549 NtClose(Socket->TdiConnectionHandle); 550 Socket->TdiConnectionHandle = NULL; 551 552 EnterCriticalSection(&SocketListLock); 553 if (SocketListHead == Socket) 554 { 555 SocketListHead = SocketListHead->NextSocket; 556 } 557 else 558 { 559 CurrentSocket = SocketListHead; 560 while (CurrentSocket->NextSocket) 561 { 562 if (CurrentSocket->NextSocket == Socket) 563 { 564 CurrentSocket->NextSocket = CurrentSocket->NextSocket->NextSocket; 565 break; 566 } 567 568 CurrentSocket = CurrentSocket->NextSocket; 569 } 570 } 571 LeaveCriticalSection(&SocketListLock); 572 573 /* Close the handle */ 574 NtClose((HANDLE)Handle); 575 NtClose(SockEvent); 576 577 HeapFree(GlobalHeap, 0, Socket); 578 return MsafdReturnWithErrno(Status, lpErrno, 0, NULL); 579} 580 581 582/* 583 * FUNCTION: Associates a local address with a socket 584 * ARGUMENTS: 585 * s = Socket descriptor 586 * name = Pointer to local address 587 * namelen = Length of name 588 * lpErrno = Address of buffer for error information 589 * RETURNS: 590 * 0, or SOCKET_ERROR if the socket could not be bound 591 */ 592INT 593WSPAPI 594WSPBind(SOCKET Handle, 595 const struct sockaddr *SocketAddress, 596 int SocketAddressLength, 597 LPINT lpErrno) 598{ 599 IO_STATUS_BLOCK IOSB; 600 PAFD_BIND_DATA BindData; 601 PSOCKET_INFORMATION Socket = NULL; 602 NTSTATUS Status; 603 SOCKADDR_INFO SocketInfo; 604 HANDLE SockEvent; 605 606 /* See below */ 607 BindData = HeapAlloc(GlobalHeap, 0, 0xA + SocketAddressLength); 608 if (!BindData) 609 { 610 return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL); 611 } 612 613 Status = NtCreateEvent(&SockEvent, 614 GENERIC_READ | GENERIC_WRITE, 615 NULL, 616 1, 617 FALSE); 618 619 if (!NT_SUCCESS(Status)) 620 { 621 HeapFree(GlobalHeap, 0, BindData); 622 return SOCKET_ERROR; 623 } 624 625 /* Get the Socket Structure associate to this Socket*/ 626 Socket = GetSocketStructure(Handle); 627 if (!Socket) 628 { 629 HeapFree(GlobalHeap, 0, BindData); 630 *lpErrno = WSAENOTSOCK; 631 return SOCKET_ERROR; 632 } 633 634 /* Set up Address in TDI Format */ 635 BindData->Address.TAAddressCount = 1; 636 BindData->Address.Address[0].AddressLength = SocketAddressLength - sizeof(SocketAddress->sa_family); 637 BindData->Address.Address[0].AddressType = SocketAddress->sa_family; 638 RtlCopyMemory (BindData->Address.Address[0].Address, 639 SocketAddress->sa_data, 640 SocketAddressLength - sizeof(SocketAddress->sa_family)); 641 642 /* Get Address Information */ 643 Socket->HelperData->WSHGetSockaddrType ((PSOCKADDR)SocketAddress, 644 SocketAddressLength, 645 &SocketInfo); 646 647 /* Set the Share Type */ 648 if (Socket->SharedData.ExclusiveAddressUse) 649 { 650 BindData->ShareType = AFD_SHARE_EXCLUSIVE; 651 } 652 else if (SocketInfo.EndpointInfo == SockaddrEndpointInfoWildcard) 653 { 654 BindData->ShareType = AFD_SHARE_WILDCARD; 655 } 656 else if (Socket->SharedData.ReuseAddresses) 657 { 658 BindData->ShareType = AFD_SHARE_REUSE; 659 } 660 else 661 { 662 BindData->ShareType = AFD_SHARE_UNIQUE; 663 } 664 665 /* Send IOCTL */ 666 Status = NtDeviceIoControlFile((HANDLE)Socket->Handle, 667 SockEvent, 668 NULL, 669 NULL, 670 &IOSB, 671 IOCTL_AFD_BIND, 672 BindData, 673 0xA + Socket->SharedData.SizeOfLocalAddress, /* Can't figure out a way to calculate this in C*/ 674 BindData, 675 0xA + Socket->SharedData.SizeOfLocalAddress); /* Can't figure out a way to calculate this C */ 676 677 /* Wait for return */ 678 if (Status == STATUS_PENDING) 679 { 680 WaitForSingleObject(SockEvent, INFINITE); 681 Status = IOSB.Status; 682 } 683 684 NtClose( SockEvent ); 685 HeapFree(GlobalHeap, 0, BindData); 686 687 if (Status != STATUS_SUCCESS) 688 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL ); 689 690 /* Set up Socket Data */ 691 Socket->SharedData.State = SocketBound; 692 Socket->TdiAddressHandle = (HANDLE)IOSB.Information; 693 694 if (Socket->HelperEvents & WSH_NOTIFY_BIND) 695 { 696 Status = Socket->HelperData->WSHNotify(Socket->HelperContext, 697 Socket->Handle, 698 Socket->TdiAddressHandle, 699 Socket->TdiConnectionHandle, 700 WSH_NOTIFY_BIND); 701 702 if (Status) 703 { 704 if (lpErrno) *lpErrno = Status; 705 return SOCKET_ERROR; 706 } 707 } 708 709 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL ); 710} 711 712int 713WSPAPI 714WSPListen(SOCKET Handle, 715 int Backlog, 716 LPINT lpErrno) 717{ 718 IO_STATUS_BLOCK IOSB; 719 AFD_LISTEN_DATA ListenData; 720 PSOCKET_INFORMATION Socket = NULL; 721 HANDLE SockEvent; 722 NTSTATUS Status; 723 724 /* Get the Socket Structure associate to this Socket*/ 725 Socket = GetSocketStructure(Handle); 726 if (!Socket) 727 { 728 *lpErrno = WSAENOTSOCK; 729 return SOCKET_ERROR; 730 } 731 732 if (Socket->SharedData.Listening) 733 return 0; 734 735 Status = NtCreateEvent(&SockEvent, 736 GENERIC_READ | GENERIC_WRITE, 737 NULL, 738 1, 739 FALSE); 740 741 if( !NT_SUCCESS(Status) ) 742 return -1; 743 744 /* Set Up Listen Structure */ 745 ListenData.UseSAN = FALSE; 746 ListenData.UseDelayedAcceptance = Socket->SharedData.UseDelayedAcceptance; 747 ListenData.Backlog = Backlog; 748 749 /* Send IOCTL */ 750 Status = NtDeviceIoControlFile((HANDLE)Socket->Handle, 751 SockEvent, 752 NULL, 753 NULL, 754 &IOSB, 755 IOCTL_AFD_START_LISTEN, 756 &ListenData, 757 sizeof(ListenData), 758 NULL, 759 0); 760 761 /* Wait for return */ 762 if (Status == STATUS_PENDING) 763 { 764 WaitForSingleObject(SockEvent, INFINITE); 765 Status = IOSB.Status; 766 } 767 768 NtClose( SockEvent ); 769 770 if (Status != STATUS_SUCCESS) 771 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL ); 772 773 /* Set to Listening */ 774 Socket->SharedData.Listening = TRUE; 775 776 if (Socket->HelperEvents & WSH_NOTIFY_LISTEN) 777 { 778 Status = Socket->HelperData->WSHNotify(Socket->HelperContext, 779 Socket->Handle, 780 Socket->TdiAddressHandle, 781 Socket->TdiConnectionHandle, 782 WSH_NOTIFY_LISTEN); 783 784 if (Status) 785 { 786 if (lpErrno) *lpErrno = Status; 787 return SOCKET_ERROR; 788 } 789 } 790 791 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL ); 792} 793 794 795int 796WSPAPI 797WSPSelect(IN int nfds, 798 IN OUT fd_set *readfds OPTIONAL, 799 IN OUT fd_set *writefds OPTIONAL, 800 IN OUT fd_set *exceptfds OPTIONAL, 801 IN const struct timeval *timeout OPTIONAL, 802 OUT LPINT lpErrno) 803{ 804 IO_STATUS_BLOCK IOSB; 805 PAFD_POLL_INFO PollInfo; 806 NTSTATUS Status; 807 ULONG HandleCount; 808 LONG OutCount = 0; 809 ULONG PollBufferSize; 810 PVOID PollBuffer; 811 ULONG i, j = 0, x; 812 HANDLE SockEvent; 813 BOOL HandleCounted; 814 LARGE_INTEGER Timeout; 815 816 /* Find out how many sockets we have, and how large the buffer needs 817 * to be */ 818 819 HandleCount = ( readfds ? readfds->fd_count : 0 ) + 820 ( writefds ? writefds->fd_count : 0 ) + 821 ( exceptfds ? exceptfds->fd_count : 0 ); 822 823 if ( HandleCount == 0 ) 824 { 825 AFD_DbgPrint(MAX_TRACE,("HandleCount: %u. Return SOCKET_ERROR\n", 826 HandleCount)); 827 if (lpErrno) *lpErrno = WSAEINVAL; 828 return SOCKET_ERROR; 829 } 830 831 PollBufferSize = sizeof(*PollInfo) + ((HandleCount - 1) * sizeof(AFD_HANDLE)); 832 833 AFD_DbgPrint(MID_TRACE,("HandleCount: %u BufferSize: %u\n", 834 HandleCount, PollBufferSize)); 835 836 /* Convert Timeout to NT Format */ 837 if (timeout == NULL) 838 { 839 Timeout.u.LowPart = -1; 840 Timeout.u.HighPart = 0x7FFFFFFF; 841 AFD_DbgPrint(MAX_TRACE,("Infinite timeout\n")); 842 } 843 else 844 { 845 Timeout = RtlEnlargedIntegerMultiply 846 ((timeout->tv_sec * 1000) + (timeout->tv_usec / 1000), -10000); 847 /* Negative timeouts are illegal. Since the kernel represents an 848 * incremental timeout as a negative number, we check for a positive 849 * result. 850 */ 851 if (Timeout.QuadPart > 0) 852 { 853 if (lpErrno) *lpErrno = WSAEINVAL; 854 return SOCKET_ERROR; 855 } 856 AFD_DbgPrint(MAX_TRACE,("Timeout: Orig %d.%06d kernel %d\n", 857 timeout->tv_sec, timeout->tv_usec, 858 Timeout.u.LowPart)); 859 } 860 861 Status = NtCreateEvent(&SockEvent, 862 GENERIC_READ | GENERIC_WRITE, 863 NULL, 864 1, 865 FALSE); 866 867 if( !NT_SUCCESS(Status) ) 868 return SOCKET_ERROR; 869 870 /* Allocate */ 871 PollBuffer = HeapAlloc(GlobalHeap, 0, PollBufferSize); 872 873 if (!PollBuffer) 874 { 875 if (lpErrno) 876 *lpErrno = WSAEFAULT; 877 NtClose(SockEvent); 878 return SOCKET_ERROR; 879 } 880 881 PollInfo = (PAFD_POLL_INFO)PollBuffer; 882 883 RtlZeroMemory( PollInfo, PollBufferSize ); 884 885 /* Number of handles for AFD to Check */ 886 PollInfo->Exclusive = FALSE; 887 PollInfo->Timeout = Timeout; 888 889 if (readfds != NULL) { 890 for (i = 0; i < readfds->fd_count; i++, j++) 891 { 892 PollInfo->Handles[j].Handle = readfds->fd_array[i]; 893 PollInfo->Handles[j].Events = AFD_EVENT_RECEIVE | 894 AFD_EVENT_DISCONNECT | 895 AFD_EVENT_ABORT | 896 AFD_EVENT_CLOSE | 897 AFD_EVENT_ACCEPT; 898 } 899 } 900 if (writefds != NULL) 901 { 902 for (i = 0; i < writefds->fd_count; i++, j++) 903 { 904 PollInfo->Handles[j].Handle = writefds->fd_array[i]; 905 PollInfo->Handles[j].Events = AFD_EVENT_SEND | AFD_EVENT_CONNECT; 906 } 907 } 908 if (exceptfds != NULL) 909 { 910 for (i = 0; i < exceptfds->fd_count; i++, j++) 911 { 912 PollInfo->Handles[j].Handle = exceptfds->fd_array[i]; 913 PollInfo->Handles[j].Events = AFD_EVENT_OOB_RECEIVE | AFD_EVENT_CONNECT_FAIL; 914 } 915 } 916 917 PollInfo->HandleCount = j; 918 PollBufferSize = FIELD_OFFSET(AFD_POLL_INFO, Handles) + PollInfo->HandleCount * sizeof(AFD_HANDLE); 919 920 /* Send IOCTL */ 921 Status = NtDeviceIoControlFile((HANDLE)PollInfo->Handles[0].Handle, 922 SockEvent, 923 NULL, 924 NULL, 925 &IOSB, 926 IOCTL_AFD_SELECT, 927 PollInfo, 928 PollBufferSize, 929 PollInfo, 930 PollBufferSize); 931 932 AFD_DbgPrint(MID_TRACE,("DeviceIoControlFile => %x\n", Status)); 933 934 /* Wait for Completition */ 935 if (Status == STATUS_PENDING) 936 { 937 WaitForSingleObject(SockEvent, INFINITE); 938 Status = IOSB.Status; 939 } 940 941 /* Clear the Structures */ 942 if( readfds ) 943 FD_ZERO(readfds); 944 if( writefds ) 945 FD_ZERO(writefds); 946 if( exceptfds ) 947 FD_ZERO(exceptfds); 948 949 /* Loop through return structure */ 950 HandleCount = PollInfo->HandleCount; 951 952 /* Return in FDSET Format */ 953 for (i = 0; i < HandleCount; i++) 954 { 955 HandleCounted = FALSE; 956 for(x = 1; x; x<<=1) 957 { 958 switch (PollInfo->Handles[i].Events & x) 959 { 960 case AFD_EVENT_RECEIVE: 961 case AFD_EVENT_DISCONNECT: 962 case AFD_EVENT_ABORT: 963 case AFD_EVENT_ACCEPT: 964 case AFD_EVENT_CLOSE: 965 AFD_DbgPrint(MID_TRACE,("Event %x on handle %x\n", 966 PollInfo->Handles[i].Events, 967 PollInfo->Handles[i].Handle)); 968 if (! HandleCounted) 969 { 970 OutCount++; 971 HandleCounted = TRUE; 972 } 973 if( readfds ) 974 FD_SET(PollInfo->Handles[i].Handle, readfds); 975 break; 976 case AFD_EVENT_SEND: 977 case AFD_EVENT_CONNECT: 978 AFD_DbgPrint(MID_TRACE,("Event %x on handle %x\n", 979 PollInfo->Handles[i].Events, 980 PollInfo->Handles[i].Handle)); 981 if (! HandleCounted) 982 { 983 OutCount++; 984 HandleCounted = TRUE; 985 } 986 if( writefds ) 987 FD_SET(PollInfo->Handles[i].Handle, writefds); 988 break; 989 case AFD_EVENT_OOB_RECEIVE: 990 case AFD_EVENT_CONNECT_FAIL: 991 AFD_DbgPrint(MID_TRACE,("Event %x on handle %x\n", 992 PollInfo->Handles[i].Events, 993 PollInfo->Handles[i].Handle)); 994 if (! HandleCounted) 995 { 996 OutCount++; 997 HandleCounted = TRUE; 998 } 999 if( exceptfds ) 1000 FD_SET(PollInfo->Handles[i].Handle, exceptfds); 1001 break; 1002 } 1003 } 1004 } 1005 1006 HeapFree( GlobalHeap, 0, PollBuffer ); 1007 NtClose( SockEvent ); 1008 1009 if( lpErrno ) 1010 { 1011 switch( IOSB.Status ) 1012 { 1013 case STATUS_SUCCESS: 1014 case STATUS_TIMEOUT: 1015 *lpErrno = 0; 1016 break; 1017 default: 1018 *lpErrno = WSAEINVAL; 1019 break; 1020 } 1021 AFD_DbgPrint(MID_TRACE,("*lpErrno = %x\n", *lpErrno)); 1022 } 1023 1024 AFD_DbgPrint(MID_TRACE,("%d events\n", OutCount)); 1025 1026 return OutCount; 1027} 1028 1029SOCKET 1030WSPAPI 1031WSPAccept(SOCKET Handle, 1032 struct sockaddr *SocketAddress, 1033 int *SocketAddressLength, 1034 LPCONDITIONPROC lpfnCondition, 1035 DWORD dwCallbackData, 1036 LPINT lpErrno) 1037{ 1038 IO_STATUS_BLOCK IOSB; 1039 PAFD_RECEIVED_ACCEPT_DATA ListenReceiveData; 1040 AFD_ACCEPT_DATA AcceptData; 1041 AFD_DEFER_ACCEPT_DATA DeferData; 1042 AFD_PENDING_ACCEPT_DATA PendingAcceptData; 1043 PSOCKET_INFORMATION Socket = NULL; 1044 NTSTATUS Status; 1045 struct fd_set ReadSet; 1046 struct timeval Timeout; 1047 PVOID PendingData = NULL; 1048 ULONG PendingDataLength = 0; 1049 PVOID CalleeDataBuffer; 1050 WSABUF CallerData, CalleeID, CallerID, CalleeData; 1051 PSOCKADDR RemoteAddress = NULL; 1052 GROUP GroupID = 0; 1053 ULONG CallBack; 1054 WSAPROTOCOL_INFOW ProtocolInfo; 1055 SOCKET AcceptSocket; 1056 PSOCKET_INFORMATION AcceptSocketInfo; 1057 UCHAR ReceiveBuffer[0x1A]; 1058 HANDLE SockEvent; 1059 1060 Status = NtCreateEvent(&SockEvent, 1061 GENERIC_READ | GENERIC_WRITE, 1062 NULL, 1063 1, 1064 FALSE); 1065 1066 if( !NT_SUCCESS(Status) ) 1067 { 1068 MsafdReturnWithErrno( Status, lpErrno, 0, NULL ); 1069 return INVALID_SOCKET; 1070 } 1071 1072 /* Dynamic Structure...ugh */ 1073 ListenReceiveData = (PAFD_RECEIVED_ACCEPT_DATA)ReceiveBuffer; 1074 1075 /* Get the Socket Structure associate to this Socket*/ 1076 Socket = GetSocketStructure(Handle); 1077 if (!Socket) 1078 { 1079 NtClose(SockEvent); 1080 *lpErrno = WSAENOTSOCK; 1081 return INVALID_SOCKET; 1082 } 1083 1084 /* If this is non-blocking, make sure there's something for us to accept */ 1085 FD_ZERO(&ReadSet); 1086 FD_SET(Socket->Handle, &ReadSet); 1087 Timeout.tv_sec=0; 1088 Timeout.tv_usec=0; 1089 1090 if (WSPSelect(0, &ReadSet, NULL, NULL, &Timeout, lpErrno) == SOCKET_ERROR) 1091 { 1092 NtClose(SockEvent); 1093 return INVALID_SOCKET; 1094 } 1095 1096 if (ReadSet.fd_array[0] != Socket->Handle) 1097 { 1098 NtClose(SockEvent); 1099 *lpErrno = WSAEWOULDBLOCK; 1100 return INVALID_SOCKET; 1101 } 1102 1103 /* Send IOCTL */ 1104 Status = NtDeviceIoControlFile((HANDLE)Socket->Handle, 1105 SockEvent, 1106 NULL, 1107 NULL, 1108 &IOSB, 1109 IOCTL_AFD_WAIT_FOR_LISTEN, 1110 NULL, 1111 0, 1112 ListenReceiveData, 1113 0xA + sizeof(*ListenReceiveData)); 1114 1115 /* Wait for return */ 1116 if (Status == STATUS_PENDING) 1117 { 1118 WaitForSingleObject(SockEvent, INFINITE); 1119 Status = IOSB.Status; 1120 } 1121 1122 if (!NT_SUCCESS(Status)) 1123 { 1124 NtClose( SockEvent ); 1125 MsafdReturnWithErrno( Status, lpErrno, 0, NULL ); 1126 return INVALID_SOCKET; 1127 } 1128 1129 if (lpfnCondition != NULL) 1130 { 1131 if ((Socket->SharedData.ServiceFlags1 & XP1_CONNECT_DATA) != 0) 1132 { 1133 /* Find out how much data is pending */ 1134 PendingAcceptData.SequenceNumber = ListenReceiveData->SequenceNumber; 1135 PendingAcceptData.ReturnSize = TRUE; 1136 1137 /* Send IOCTL */ 1138 Status = NtDeviceIoControlFile((HANDLE)Socket->Handle, 1139 SockEvent, 1140 NULL, 1141 NULL, 1142 &IOSB, 1143 IOCTL_AFD_GET_PENDING_CONNECT_DATA, 1144 &PendingAcceptData, 1145 sizeof(PendingAcceptData), 1146 &PendingAcceptData, 1147 sizeof(PendingAcceptData)); 1148 1149 /* Wait for return */ 1150 if (Status == STATUS_PENDING) 1151 { 1152 WaitForSingleObject(SockEvent, INFINITE); 1153 Status = IOSB.Status; 1154 } 1155 1156 if (!NT_SUCCESS(Status)) 1157 { 1158 NtClose( SockEvent ); 1159 MsafdReturnWithErrno( Status, lpErrno, 0, NULL ); 1160 return INVALID_SOCKET; 1161 } 1162 1163 /* How much data to allocate */ 1164 PendingDataLength = IOSB.Information; 1165 1166 if (PendingDataLength) 1167 { 1168 /* Allocate needed space */ 1169 PendingData = HeapAlloc(GlobalHeap, 0, PendingDataLength); 1170 if (!PendingData) 1171 { 1172 MsafdReturnWithErrno( STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL ); 1173 return INVALID_SOCKET; 1174 } 1175 1176 /* We want the data now */ 1177 PendingAcceptData.ReturnSize = FALSE; 1178 1179 /* Send IOCTL */ 1180 Status = NtDeviceIoControlFile((HANDLE)Socket->Handle, 1181 SockEvent, 1182 NULL, 1183 NULL, 1184 &IOSB, 1185 IOCTL_AFD_GET_PENDING_CONNECT_DATA, 1186 &PendingAcceptData, 1187 sizeof(PendingAcceptData), 1188 PendingData, 1189 PendingDataLength); 1190 1191 /* Wait for return */ 1192 if (Status == STATUS_PENDING) 1193 { 1194 WaitForSingleObject(SockEvent, INFINITE); 1195 Status = IOSB.Status; 1196 } 1197 1198 if (!NT_SUCCESS(Status)) 1199 { 1200 NtClose( SockEvent ); 1201 MsafdReturnWithErrno( Status, lpErrno, 0, NULL ); 1202 return INVALID_SOCKET; 1203 } 1204 } 1205 } 1206 1207 if ((Socket->SharedData.ServiceFlags1 & XP1_QOS_SUPPORTED) != 0) 1208 { 1209 /* I don't support this yet */ 1210 } 1211 1212 /* Build Callee ID */ 1213 CalleeID.buf = (PVOID)Socket->LocalAddress; 1214 CalleeID.len = Socket->SharedData.SizeOfLocalAddress; 1215 1216 RemoteAddress = HeapAlloc(GlobalHeap, 0, sizeof(*RemoteAddress)); 1217 if (!RemoteAddress) 1218 { 1219 MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL); 1220 return INVALID_SOCKET; 1221 } 1222 1223 /* Set up Address in SOCKADDR Format */ 1224 RtlCopyMemory (RemoteAddress, 1225 &ListenReceiveData->Address.Address[0].AddressType, 1226 sizeof(*RemoteAddress)); 1227 1228 /* Build Caller ID */ 1229 CallerID.buf = (PVOID)RemoteAddress; 1230 CallerID.len = sizeof(*RemoteAddress); 1231 1232 /* Build Caller Data */ 1233 CallerData.buf = PendingData; 1234 CallerData.len = PendingDataLength; 1235 1236 /* Check if socket supports Conditional Accept */ 1237 if (Socket->SharedData.UseDelayedAcceptance != 0) 1238 { 1239 /* Allocate Buffer for Callee Data */ 1240 CalleeDataBuffer = HeapAlloc(GlobalHeap, 0, 4096); 1241 if (!CalleeDataBuffer) { 1242 MsafdReturnWithErrno( STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL ); 1243 return INVALID_SOCKET; 1244 } 1245 CalleeData.buf = CalleeDataBuffer; 1246 CalleeData.len = 4096; 1247 } 1248 else 1249 { 1250 /* Nothing */ 1251 CalleeData.buf = 0; 1252 CalleeData.len = 0; 1253 } 1254 1255 /* Call the Condition Function */ 1256 CallBack = (lpfnCondition)(&CallerID, 1257 CallerData.buf == NULL ? NULL : &CallerData, 1258 NULL, 1259 NULL, 1260 &CalleeID, 1261 CalleeData.buf == NULL ? NULL : &CalleeData, 1262 &GroupID, 1263 dwCallbackData); 1264 1265 if (((CallBack == CF_ACCEPT) && GroupID) != 0) 1266 { 1267 /* TBD: Check for Validity */ 1268 } 1269 1270 if (CallBack == CF_ACCEPT) 1271 { 1272 if ((Socket->SharedData.ServiceFlags1 & XP1_QOS_SUPPORTED) != 0) 1273 { 1274 /* I don't support this yet */ 1275 } 1276 if (CalleeData.buf) 1277 { 1278 // SockSetConnectData Sockets(SocketID), IOCTL_AFD_SET_CONNECT_DATA, CalleeData.Buffer, CalleeData.BuffSize, 0 1279 } 1280 } 1281 else 1282 { 1283 /* Callback rejected. Build Defer Structure */ 1284 DeferData.SequenceNumber = ListenReceiveData->SequenceNumber; 1285 DeferData.RejectConnection = (CallBack == CF_REJECT); 1286 1287 /* Send IOCTL */ 1288 Status = NtDeviceIoControlFile((HANDLE)Socket->Handle, 1289 SockEvent, 1290 NULL, 1291 NULL, 1292 &IOSB, 1293 IOCTL_AFD_DEFER_ACCEPT, 1294 &DeferData, 1295 sizeof(DeferData), 1296 NULL, 1297 0); 1298 1299 /* Wait for return */ 1300 if (Status == STATUS_PENDING) 1301 { 1302 WaitForSingleObject(SockEvent, INFINITE); 1303 Status = IOSB.Status; 1304 } 1305 1306 NtClose( SockEvent ); 1307 1308 if (!NT_SUCCESS(Status)) 1309 { 1310 MsafdReturnWithErrno( Status, lpErrno, 0, NULL ); 1311 return INVALID_SOCKET; 1312 } 1313 1314 if (CallBack == CF_REJECT ) 1315 { 1316 *lpErrno = WSAECONNREFUSED; 1317 return INVALID_SOCKET; 1318 } 1319 else 1320 { 1321 *lpErrno = WSAECONNREFUSED; 1322 return INVALID_SOCKET; 1323 } 1324 } 1325 } 1326 1327 /* Create a new Socket */ 1328 ProtocolInfo.dwCatalogEntryId = Socket->SharedData.CatalogEntryId; 1329 ProtocolInfo.dwServiceFlags1 = Socket->SharedData.ServiceFlags1; 1330 ProtocolInfo.dwProviderFlags = Socket->SharedData.ProviderFlags; 1331 1332 AcceptSocket = WSPSocket (Socket->SharedData.AddressFamily, 1333 Socket->SharedData.SocketType, 1334 Socket->SharedData.Protocol, 1335 &ProtocolInfo, 1336 GroupID, 1337 Socket->SharedData.CreateFlags, 1338 lpErrno); 1339 if (AcceptSocket == INVALID_SOCKET) 1340 return INVALID_SOCKET; 1341 1342 /* Set up the Accept Structure */ 1343 AcceptData.ListenHandle = (HANDLE)AcceptSocket; 1344 AcceptData.SequenceNumber = ListenReceiveData->SequenceNumber; 1345 1346 /* Send IOCTL to Accept */ 1347 Status = NtDeviceIoControlFile((HANDLE)Socket->Handle, 1348 SockEvent, 1349 NULL, 1350 NULL, 1351 &IOSB, 1352 IOCTL_AFD_ACCEPT, 1353 &AcceptData, 1354 sizeof(AcceptData), 1355 NULL, 1356 0); 1357 1358 /* Wait for return */ 1359 if (Status == STATUS_PENDING) 1360 { 1361 WaitForSingleObject(SockEvent, INFINITE); 1362 Status = IOSB.Status; 1363 } 1364 1365 if (!NT_SUCCESS(Status)) 1366 { 1367 NtClose(SockEvent); 1368 WSPCloseSocket( AcceptSocket, lpErrno ); 1369 MsafdReturnWithErrno( Status, lpErrno, 0, NULL ); 1370 return INVALID_SOCKET; 1371 } 1372 1373 AcceptSocketInfo = GetSocketStructure(AcceptSocket); 1374 if (!AcceptSocketInfo) 1375 { 1376 NtClose(SockEvent); 1377 WSPCloseSocket( AcceptSocket, lpErrno ); 1378 MsafdReturnWithErrno( STATUS_INVALID_CONNECTION, lpErrno, 0, NULL ); 1379 return INVALID_SOCKET; 1380 } 1381 1382 AcceptSocketInfo->SharedData.State = SocketConnected; 1383 1384 /* Return Address in SOCKADDR FORMAT */ 1385 if( SocketAddress ) 1386 { 1387 RtlCopyMemory (SocketAddress, 1388 &ListenReceiveData->Address.Address[0].AddressType, 1389 sizeof(*RemoteAddress)); 1390 if( SocketAddressLength ) 1391 *SocketAddressLength = ListenReceiveData->Address.Address[0].AddressLength; 1392 } 1393 1394 NtClose( SockEvent ); 1395 1396 /* Re-enable Async Event */ 1397 SockReenableAsyncSelectEvent(Socket, FD_ACCEPT); 1398 1399 AFD_DbgPrint(MID_TRACE,("Socket %x\n", AcceptSocket)); 1400 1401 if (Status == STATUS_SUCCESS && (Socket->HelperEvents & WSH_NOTIFY_ACCEPT)) 1402 { 1403 Status = Socket->HelperData->WSHNotify(Socket->HelperContext, 1404 Socket->Handle, 1405 Socket->TdiAddressHandle, 1406 Socket->TdiConnectionHandle, 1407 WSH_NOTIFY_ACCEPT); 1408 1409 if (Status) 1410 { 1411 if (lpErrno) *lpErrno = Status; 1412 return INVALID_SOCKET; 1413 } 1414 } 1415 1416 *lpErrno = 0; 1417 1418 /* Return Socket */ 1419 return AcceptSocket; 1420} 1421 1422int 1423WSPAPI 1424WSPConnect(SOCKET Handle, 1425 const struct sockaddr * SocketAddress, 1426 int SocketAddressLength, 1427 LPWSABUF lpCallerData, 1428 LPWSABUF lpCalleeData, 1429 LPQOS lpSQOS, 1430 LPQOS lpGQOS, 1431 LPINT lpErrno) 1432{ 1433 IO_STATUS_BLOCK IOSB; 1434 PAFD_CONNECT_INFO ConnectInfo = NULL; 1435 PSOCKET_INFORMATION Socket; 1436 NTSTATUS Status; 1437 INT Errno; 1438 ULONG ConnectDataLength; 1439 ULONG InConnectDataLength; 1440 INT BindAddressLength; 1441 PSOCKADDR BindAddress; 1442 HANDLE SockEvent; 1443 int SocketDataLength; 1444 1445 Status = NtCreateEvent(&SockEvent, 1446 GENERIC_READ | GENERIC_WRITE, 1447 NULL, 1448 1, 1449 FALSE); 1450 1451 if (!NT_SUCCESS(Status)) 1452 return MsafdReturnWithErrno(Status, lpErrno, 0, NULL); 1453 1454 AFD_DbgPrint(MID_TRACE,("Called\n")); 1455 1456 /* Get the Socket Structure associate to this Socket*/ 1457 Socket = GetSocketStructure(Handle); 1458 if (!Socket) 1459 { 1460 NtClose(SockEvent); 1461 if (lpErrno) *lpErrno = WSAENOTSOCK; 1462 return SOCKET_ERROR; 1463 } 1464 1465 /* Bind us First */ 1466 if (Socket->SharedData.State == SocketOpen) 1467 { 1468 /* Get the Wildcard Address */ 1469 BindAddressLength = Socket->HelperData->MaxWSAddressLength; 1470 BindAddress = HeapAlloc(GetProcessHeap(), 0, BindAddressLength); 1471 if (!BindAddress) 1472 { 1473 NtClose(SockEvent); 1474 return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL); 1475 } 1476 Socket->HelperData->WSHGetWildcardSockaddr (Socket->HelperContext, 1477 BindAddress, 1478 &BindAddressLength); 1479 /* Bind it */ 1480 if (WSPBind(Handle, BindAddress, BindAddressLength, lpErrno) == SOCKET_ERROR) 1481 return SOCKET_ERROR; 1482 } 1483 1484 /* Set the Connect Data */ 1485 if (lpCallerData != NULL) 1486 { 1487 ConnectDataLength = lpCallerData->len; 1488 Status = NtDeviceIoControlFile((HANDLE)Handle, 1489 SockEvent, 1490 NULL, 1491 NULL, 1492 &IOSB, 1493 IOCTL_AFD_SET_CONNECT_DATA, 1494 lpCallerData->buf, 1495 ConnectDataLength, 1496 NULL, 1497 0); 1498 /* Wait for return */ 1499 if (Status == STATUS_PENDING) 1500 { 1501 WaitForSingleObject(SockEvent, INFINITE); 1502 Status = IOSB.Status; 1503 } 1504 1505 if (Status != STATUS_SUCCESS) 1506 goto notify; 1507 } 1508 1509 /* Calculate the size of SocketAddress->sa_data */ 1510 SocketDataLength = SocketAddres…
Large files files are truncated, but you can click here to view the full file