PageRenderTime 69ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/dll/win32/msafd/misc/dllmain.c

https://bitbucket.org/arty/arty-newcc-reactos
C | 3025 lines | 2301 code | 424 blank | 300 comment | 367 complexity | 0e9108fd373225420c56433e6347f8f6 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, LGPL-3.0, CC-BY-SA-3.0, AGPL-3.0, GPL-3.0, CPL-1.0

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

Large files files are truncated, but you can click here to view the full file