Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensndrcv.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Ancillary Function Driver DLL 00004 * FILE: misc/sndrcv.c 00005 * PURPOSE: Send/receive routines 00006 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) 00007 * Alex Ionescu (alex@relsoft.net) 00008 * REVISIONS: 00009 * CSH 01/09-2000 Created 00010 * Alex 16/07/2004 - Complete Rewrite 00011 */ 00012 00013 #include <msafd.h> 00014 00015 INT 00016 WSPAPI 00017 WSPAsyncSelect(IN SOCKET Handle, 00018 IN HWND hWnd, 00019 IN UINT wMsg, 00020 IN LONG lEvent, 00021 OUT LPINT lpErrno) 00022 { 00023 PSOCKET_INFORMATION Socket = NULL; 00024 PASYNC_DATA AsyncData; 00025 BOOLEAN BlockMode; 00026 00027 /* Get the Socket Structure associated to this Socket */ 00028 Socket = GetSocketStructure(Handle); 00029 if (!Socket) 00030 { 00031 *lpErrno = WSAENOTSOCK; 00032 return SOCKET_ERROR; 00033 } 00034 00035 /* Allocate the Async Data Structure to pass on to the Thread later */ 00036 AsyncData = HeapAlloc(GetProcessHeap(), 0, sizeof(*AsyncData)); 00037 if (!AsyncData) 00038 { 00039 MsafdReturnWithErrno( STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL ); 00040 return INVALID_SOCKET; 00041 } 00042 00043 /* Change the Socket to Non Blocking */ 00044 BlockMode = TRUE; 00045 SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &BlockMode, NULL, NULL); 00046 Socket->SharedData.NonBlocking = TRUE; 00047 00048 /* Deactive WSPEventSelect */ 00049 if (Socket->SharedData.AsyncEvents) 00050 { 00051 if (WSPEventSelect(Handle, NULL, 0, lpErrno) == SOCKET_ERROR) 00052 { 00053 HeapFree(GetProcessHeap(), 0, AsyncData); 00054 return SOCKET_ERROR; 00055 } 00056 } 00057 00058 /* Create the Asynch Thread if Needed */ 00059 SockCreateOrReferenceAsyncThread(); 00060 00061 /* Open a Handle to AFD's Async Helper */ 00062 SockGetAsyncSelectHelperAfdHandle(); 00063 00064 /* Store Socket Data */ 00065 Socket->SharedData.hWnd = hWnd; 00066 Socket->SharedData.wMsg = wMsg; 00067 Socket->SharedData.AsyncEvents = lEvent; 00068 Socket->SharedData.AsyncDisabledEvents = 0; 00069 Socket->SharedData.SequenceNumber++; 00070 00071 /* Return if there are no more Events */ 00072 if ((Socket->SharedData.AsyncEvents & (~Socket->SharedData.AsyncDisabledEvents)) == 0) 00073 { 00074 HeapFree(GetProcessHeap(), 0, AsyncData); 00075 return 0; 00076 } 00077 00078 /* Set up the Async Data */ 00079 AsyncData->ParentSocket = Socket; 00080 AsyncData->SequenceNumber = Socket->SharedData.SequenceNumber; 00081 00082 /* Begin Async Select by using I/O Completion */ 00083 NtSetIoCompletion(SockAsyncCompletionPort, 00084 (PVOID)&SockProcessQueuedAsyncSelect, 00085 AsyncData, 00086 0, 00087 0); 00088 00089 /* Return */ 00090 return ERROR_SUCCESS; 00091 } 00092 00093 00094 int 00095 WSPAPI 00096 WSPRecv(SOCKET Handle, 00097 LPWSABUF lpBuffers, 00098 DWORD dwBufferCount, 00099 LPDWORD lpNumberOfBytesRead, 00100 LPDWORD ReceiveFlags, 00101 LPWSAOVERLAPPED lpOverlapped, 00102 LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, 00103 LPWSATHREADID lpThreadId, 00104 LPINT lpErrno) 00105 { 00106 PIO_STATUS_BLOCK IOSB; 00107 IO_STATUS_BLOCK DummyIOSB; 00108 AFD_RECV_INFO RecvInfo; 00109 NTSTATUS Status; 00110 PVOID APCContext; 00111 PVOID APCFunction; 00112 HANDLE Event = NULL; 00113 HANDLE SockEvent; 00114 PSOCKET_INFORMATION Socket; 00115 00116 AFD_DbgPrint(MID_TRACE,("Called (%x)\n", Handle)); 00117 00118 /* Get the Socket Structure associate to this Socket*/ 00119 Socket = GetSocketStructure(Handle); 00120 if (!Socket) 00121 { 00122 *lpErrno = WSAENOTSOCK; 00123 return SOCKET_ERROR; 00124 } 00125 00126 Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, 00127 NULL, 1, FALSE ); 00128 00129 if( !NT_SUCCESS(Status) ) 00130 return -1; 00131 00132 /* Set up the Receive Structure */ 00133 RecvInfo.BufferArray = (PAFD_WSABUF)lpBuffers; 00134 RecvInfo.BufferCount = dwBufferCount; 00135 RecvInfo.TdiFlags = 0; 00136 RecvInfo.AfdFlags = Socket->SharedData.NonBlocking ? AFD_IMMEDIATE : 0; 00137 00138 /* Set the TDI Flags */ 00139 if (*ReceiveFlags == 0) 00140 { 00141 RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL; 00142 } 00143 else 00144 { 00145 if (*ReceiveFlags & MSG_OOB) 00146 { 00147 RecvInfo.TdiFlags |= TDI_RECEIVE_EXPEDITED; 00148 } 00149 00150 if (*ReceiveFlags & MSG_PEEK) 00151 { 00152 RecvInfo.TdiFlags |= TDI_RECEIVE_PEEK; 00153 } 00154 00155 if (*ReceiveFlags & MSG_PARTIAL) 00156 { 00157 RecvInfo.TdiFlags |= TDI_RECEIVE_PARTIAL; 00158 } 00159 } 00160 00161 /* Verifiy if we should use APC */ 00162 00163 if (lpOverlapped == NULL) 00164 { 00165 /* Not using Overlapped structure, so use normal blocking on event */ 00166 APCContext = NULL; 00167 APCFunction = NULL; 00168 Event = SockEvent; 00169 IOSB = &DummyIOSB; 00170 } 00171 else 00172 { 00173 if (lpCompletionRoutine == NULL) 00174 { 00175 /* Using Overlapped Structure, but no Completition Routine, so no need for APC */ 00176 APCContext = lpOverlapped; 00177 APCFunction = NULL; 00178 Event = lpOverlapped->hEvent; 00179 } 00180 else 00181 { 00182 /* Using Overlapped Structure and a Completition Routine, so use an APC */ 00183 APCFunction = NULL; // should be a private io completition function inside us 00184 APCContext = lpCompletionRoutine; 00185 RecvInfo.AfdFlags |= AFD_SKIP_FIO; 00186 } 00187 00188 IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal; 00189 RecvInfo.AfdFlags |= AFD_OVERLAPPED; 00190 } 00191 00192 IOSB->Status = STATUS_PENDING; 00193 00194 /* Send IOCTL */ 00195 Status = NtDeviceIoControlFile((HANDLE)Handle, 00196 Event, 00197 APCFunction, 00198 APCContext, 00199 IOSB, 00200 IOCTL_AFD_RECV, 00201 &RecvInfo, 00202 sizeof(RecvInfo), 00203 NULL, 00204 0); 00205 00206 /* Wait for completition of not overlapped */ 00207 if (Status == STATUS_PENDING && lpOverlapped == NULL) 00208 { 00209 /* It's up to the protocol to time out recv. We must wait 00210 * until the protocol decides it's had enough. 00211 */ 00212 WaitForSingleObject(SockEvent, INFINITE); 00213 Status = IOSB->Status; 00214 } 00215 00216 NtClose( SockEvent ); 00217 00218 AFD_DbgPrint(MID_TRACE,("Status %x Information %d\n", Status, IOSB->Information)); 00219 00220 /* Return the Flags */ 00221 *ReceiveFlags = 0; 00222 00223 switch (Status) 00224 { 00225 case STATUS_RECEIVE_EXPEDITED: 00226 *ReceiveFlags = MSG_OOB; 00227 break; 00228 case STATUS_RECEIVE_PARTIAL_EXPEDITED: 00229 *ReceiveFlags = MSG_PARTIAL | MSG_OOB; 00230 break; 00231 case STATUS_RECEIVE_PARTIAL: 00232 *ReceiveFlags = MSG_PARTIAL; 00233 break; 00234 } 00235 00236 /* Re-enable Async Event */ 00237 if (*ReceiveFlags & MSG_OOB) 00238 { 00239 SockReenableAsyncSelectEvent(Socket, FD_OOB); 00240 } 00241 else 00242 { 00243 SockReenableAsyncSelectEvent(Socket, FD_READ); 00244 } 00245 00246 return MsafdReturnWithErrno ( Status, lpErrno, IOSB->Information, lpNumberOfBytesRead ); 00247 } 00248 00249 int 00250 WSPAPI 00251 WSPRecvFrom(SOCKET Handle, 00252 LPWSABUF lpBuffers, 00253 DWORD dwBufferCount, 00254 LPDWORD lpNumberOfBytesRead, 00255 LPDWORD ReceiveFlags, 00256 struct sockaddr *SocketAddress, 00257 int *SocketAddressLength, 00258 LPWSAOVERLAPPED lpOverlapped, 00259 LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, 00260 LPWSATHREADID lpThreadId, 00261 LPINT lpErrno ) 00262 { 00263 PIO_STATUS_BLOCK IOSB; 00264 IO_STATUS_BLOCK DummyIOSB; 00265 AFD_RECV_INFO_UDP RecvInfo; 00266 NTSTATUS Status; 00267 PVOID APCContext; 00268 PVOID APCFunction; 00269 HANDLE Event = NULL; 00270 HANDLE SockEvent; 00271 PSOCKET_INFORMATION Socket; 00272 00273 /* Get the Socket Structure associate to this Socket*/ 00274 Socket = GetSocketStructure(Handle); 00275 if (!Socket) 00276 { 00277 *lpErrno = WSAENOTSOCK; 00278 return SOCKET_ERROR; 00279 } 00280 00281 if (!(Socket->SharedData.ServiceFlags1 & XP1_CONNECTIONLESS)) 00282 { 00283 /* Call WSPRecv for a non-datagram socket */ 00284 return WSPRecv(Handle, 00285 lpBuffers, 00286 dwBufferCount, 00287 lpNumberOfBytesRead, 00288 ReceiveFlags, 00289 lpOverlapped, 00290 lpCompletionRoutine, 00291 lpThreadId, 00292 lpErrno); 00293 } 00294 00295 Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, 00296 NULL, 1, FALSE ); 00297 00298 if( !NT_SUCCESS(Status) ) 00299 return -1; 00300 00301 /* Set up the Receive Structure */ 00302 RecvInfo.BufferArray = (PAFD_WSABUF)lpBuffers; 00303 RecvInfo.BufferCount = dwBufferCount; 00304 RecvInfo.TdiFlags = 0; 00305 RecvInfo.AfdFlags = Socket->SharedData.NonBlocking ? AFD_IMMEDIATE : 0; 00306 RecvInfo.AddressLength = SocketAddressLength; 00307 RecvInfo.Address = SocketAddress; 00308 00309 /* Set the TDI Flags */ 00310 if (*ReceiveFlags == 0) 00311 { 00312 RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL; 00313 } 00314 else 00315 { 00316 if (*ReceiveFlags & MSG_OOB) 00317 { 00318 RecvInfo.TdiFlags |= TDI_RECEIVE_EXPEDITED; 00319 } 00320 00321 if (*ReceiveFlags & MSG_PEEK) 00322 { 00323 RecvInfo.TdiFlags |= TDI_RECEIVE_PEEK; 00324 } 00325 00326 if (*ReceiveFlags & MSG_PARTIAL) 00327 { 00328 RecvInfo.TdiFlags |= TDI_RECEIVE_PARTIAL; 00329 } 00330 } 00331 00332 /* Verifiy if we should use APC */ 00333 00334 if (lpOverlapped == NULL) 00335 { 00336 /* Not using Overlapped structure, so use normal blocking on event */ 00337 APCContext = NULL; 00338 APCFunction = NULL; 00339 Event = SockEvent; 00340 IOSB = &DummyIOSB; 00341 } 00342 else 00343 { 00344 if (lpCompletionRoutine == NULL) 00345 { 00346 /* Using Overlapped Structure, but no Completition Routine, so no need for APC */ 00347 APCContext = lpOverlapped; 00348 APCFunction = NULL; 00349 Event = lpOverlapped->hEvent; 00350 } 00351 else 00352 { 00353 /* Using Overlapped Structure and a Completition Routine, so use an APC */ 00354 APCFunction = NULL; // should be a private io completition function inside us 00355 APCContext = lpCompletionRoutine; 00356 RecvInfo.AfdFlags |= AFD_SKIP_FIO; 00357 } 00358 00359 IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal; 00360 RecvInfo.AfdFlags |= AFD_OVERLAPPED; 00361 } 00362 00363 IOSB->Status = STATUS_PENDING; 00364 00365 /* Send IOCTL */ 00366 Status = NtDeviceIoControlFile((HANDLE)Handle, 00367 Event, 00368 APCFunction, 00369 APCContext, 00370 IOSB, 00371 IOCTL_AFD_RECV_DATAGRAM, 00372 &RecvInfo, 00373 sizeof(RecvInfo), 00374 NULL, 00375 0); 00376 00377 /* Wait for completition of not overlapped */ 00378 if (Status == STATUS_PENDING && lpOverlapped == NULL) 00379 { 00380 WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infintely for receive... 00381 Status = IOSB->Status; 00382 } 00383 00384 NtClose( SockEvent ); 00385 00386 /* Return the Flags */ 00387 *ReceiveFlags = 0; 00388 00389 switch (Status) 00390 { 00391 case STATUS_RECEIVE_EXPEDITED: *ReceiveFlags = MSG_OOB; 00392 break; 00393 case STATUS_RECEIVE_PARTIAL_EXPEDITED: 00394 *ReceiveFlags = MSG_PARTIAL | MSG_OOB; 00395 break; 00396 case STATUS_RECEIVE_PARTIAL: 00397 *ReceiveFlags = MSG_PARTIAL; 00398 break; 00399 } 00400 00401 /* Re-enable Async Event */ 00402 if (*ReceiveFlags & MSG_OOB) 00403 { 00404 SockReenableAsyncSelectEvent(Socket, FD_OOB); 00405 } 00406 else 00407 { 00408 SockReenableAsyncSelectEvent(Socket, FD_READ); 00409 } 00410 00411 return MsafdReturnWithErrno ( Status, lpErrno, IOSB->Information, lpNumberOfBytesRead ); 00412 } 00413 00414 00415 int 00416 WSPAPI 00417 WSPSend(SOCKET Handle, 00418 LPWSABUF lpBuffers, 00419 DWORD dwBufferCount, 00420 LPDWORD lpNumberOfBytesSent, 00421 DWORD iFlags, 00422 LPWSAOVERLAPPED lpOverlapped, 00423 LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, 00424 LPWSATHREADID lpThreadId, 00425 LPINT lpErrno) 00426 { 00427 PIO_STATUS_BLOCK IOSB; 00428 IO_STATUS_BLOCK DummyIOSB; 00429 AFD_SEND_INFO SendInfo; 00430 NTSTATUS Status; 00431 PVOID APCContext; 00432 PVOID APCFunction; 00433 HANDLE Event = NULL; 00434 HANDLE SockEvent; 00435 PSOCKET_INFORMATION Socket; 00436 00437 /* Get the Socket Structure associate to this Socket*/ 00438 Socket = GetSocketStructure(Handle); 00439 if (!Socket) 00440 { 00441 *lpErrno = WSAENOTSOCK; 00442 return SOCKET_ERROR; 00443 } 00444 00445 Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE, 00446 NULL, 1, FALSE ); 00447 00448 if( !NT_SUCCESS(Status) ) 00449 return -1; 00450 00451 AFD_DbgPrint(MID_TRACE,("Called\n")); 00452 00453 /* Set up the Send Structure */ 00454 SendInfo.BufferArray = (PAFD_WSABUF)lpBuffers; 00455 SendInfo.BufferCount = dwBufferCount; 00456 SendInfo.TdiFlags = 0; 00457 SendInfo.AfdFlags = Socket->SharedData.NonBlocking ? AFD_IMMEDIATE : 0; 00458 00459 /* Set the TDI Flags */ 00460 if (iFlags) 00461 { 00462 if (iFlags & MSG_OOB) 00463 { 00464 SendInfo.TdiFlags |= TDI_SEND_EXPEDITED; 00465 } 00466 if (iFlags & MSG_PARTIAL) 00467 { 00468 SendInfo.TdiFlags |= TDI_SEND_PARTIAL; 00469 } 00470 } 00471 00472 /* Verifiy if we should use APC */ 00473 if (lpOverlapped == NULL) 00474 { 00475 /* Not using Overlapped structure, so use normal blocking on event */ 00476 APCContext = NULL; 00477 APCFunction = NULL; 00478 Event = SockEvent; 00479 IOSB = &DummyIOSB; 00480 } 00481 else 00482 { 00483 if (lpCompletionRoutine == NULL) 00484 { 00485 /* Using Overlapped Structure, but no Completition Routine, so no need for APC */ 00486 APCContext = lpOverlapped; 00487 APCFunction = NULL; 00488 Event = lpOverlapped->hEvent; 00489 } 00490 else 00491 { 00492 /* Using Overlapped Structure and a Completition Routine, so use an APC */ 00493 APCFunction = NULL; // should be a private io completition function inside us 00494 APCContext = lpCompletionRoutine; 00495 SendInfo.AfdFlags |= AFD_SKIP_FIO; 00496 } 00497 00498 IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal; 00499 SendInfo.AfdFlags |= AFD_OVERLAPPED; 00500 } 00501 00502 IOSB->Status = STATUS_PENDING; 00503 00504 /* Send IOCTL */ 00505 Status = NtDeviceIoControlFile((HANDLE)Handle, 00506 Event, 00507 APCFunction, 00508 APCContext, 00509 IOSB, 00510 IOCTL_AFD_SEND, 00511 &SendInfo, 00512 sizeof(SendInfo), 00513 NULL, 00514 0); 00515 00516 /* Wait for completition of not overlapped */ 00517 if (Status == STATUS_PENDING && lpOverlapped == NULL) 00518 { 00519 WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infintely for send... 00520 Status = IOSB->Status; 00521 } 00522 00523 NtClose( SockEvent ); 00524 00525 if (Status == STATUS_PENDING) 00526 { 00527 AFD_DbgPrint(MID_TRACE,("Leaving (Pending)\n")); 00528 return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesSent); 00529 } 00530 00531 /* Re-enable Async Event */ 00532 SockReenableAsyncSelectEvent(Socket, FD_WRITE); 00533 00534 AFD_DbgPrint(MID_TRACE,("Leaving (Success, %d)\n", IOSB->Information)); 00535 00536 return MsafdReturnWithErrno( Status, lpErrno, IOSB->Information, lpNumberOfBytesSent ); 00537 } 00538 00539 int 00540 WSPAPI 00541 WSPSendTo(SOCKET Handle, 00542 LPWSABUF lpBuffers, 00543 DWORD dwBufferCount, 00544 LPDWORD lpNumberOfBytesSent, 00545 DWORD iFlags, 00546 const struct sockaddr *SocketAddress, 00547 int SocketAddressLength, 00548 LPWSAOVERLAPPED lpOverlapped, 00549 LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, 00550 LPWSATHREADID lpThreadId, 00551 LPINT lpErrno) 00552 { 00553 PIO_STATUS_BLOCK IOSB; 00554 IO_STATUS_BLOCK DummyIOSB; 00555 AFD_SEND_INFO_UDP SendInfo; 00556 NTSTATUS Status; 00557 PVOID APCContext; 00558 PVOID APCFunction; 00559 HANDLE Event = NULL; 00560 PTRANSPORT_ADDRESS RemoteAddress; 00561 PSOCKADDR BindAddress = NULL; 00562 INT BindAddressLength; 00563 HANDLE SockEvent; 00564 PSOCKET_INFORMATION Socket; 00565 00566 /* Get the Socket Structure associate to this Socket */ 00567 Socket = GetSocketStructure(Handle); 00568 if (!Socket) 00569 { 00570 *lpErrno = WSAENOTSOCK; 00571 return SOCKET_ERROR; 00572 } 00573 00574 if (!(Socket->SharedData.ServiceFlags1 & XP1_CONNECTIONLESS)) 00575 { 00576 /* Use WSPSend for connection-oriented sockets */ 00577 return WSPSend(Handle, 00578 lpBuffers, 00579 dwBufferCount, 00580 lpNumberOfBytesSent, 00581 iFlags, 00582 lpOverlapped, 00583 lpCompletionRoutine, 00584 lpThreadId, 00585 lpErrno); 00586 } 00587 00588 /* Bind us First */ 00589 if (Socket->SharedData.State == SocketOpen) 00590 { 00591 /* Get the Wildcard Address */ 00592 BindAddressLength = Socket->HelperData->MaxWSAddressLength; 00593 BindAddress = HeapAlloc(GlobalHeap, 0, BindAddressLength); 00594 if (!BindAddress) 00595 { 00596 MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL); 00597 return INVALID_SOCKET; 00598 } 00599 00600 Socket->HelperData->WSHGetWildcardSockaddr(Socket->HelperContext, 00601 BindAddress, 00602 &BindAddressLength); 00603 /* Bind it */ 00604 if (WSPBind(Handle, BindAddress, BindAddressLength, lpErrno) == SOCKET_ERROR) 00605 return SOCKET_ERROR; 00606 } 00607 00608 RemoteAddress = HeapAlloc(GlobalHeap, 0, 0x6 + SocketAddressLength); 00609 if (!RemoteAddress) 00610 { 00611 if (BindAddress != NULL) 00612 { 00613 HeapFree(GlobalHeap, 0, BindAddress); 00614 } 00615 return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL); 00616 } 00617 00618 Status = NtCreateEvent(&SockEvent, 00619 GENERIC_READ | GENERIC_WRITE, 00620 NULL, 1, FALSE); 00621 00622 if (!NT_SUCCESS(Status)) 00623 { 00624 HeapFree(GlobalHeap, 0, RemoteAddress); 00625 if (BindAddress != NULL) 00626 { 00627 HeapFree(GlobalHeap, 0, BindAddress); 00628 } 00629 return SOCKET_ERROR; 00630 } 00631 00632 /* Set up Address in TDI Format */ 00633 RemoteAddress->TAAddressCount = 1; 00634 RemoteAddress->Address[0].AddressLength = SocketAddressLength - sizeof(SocketAddress->sa_family); 00635 RtlCopyMemory(&RemoteAddress->Address[0].AddressType, SocketAddress, SocketAddressLength); 00636 00637 /* Set up Structure */ 00638 SendInfo.BufferArray = (PAFD_WSABUF)lpBuffers; 00639 SendInfo.AfdFlags = Socket->SharedData.NonBlocking ? AFD_IMMEDIATE : 0; 00640 SendInfo.BufferCount = dwBufferCount; 00641 SendInfo.TdiConnection.RemoteAddress = RemoteAddress; 00642 SendInfo.TdiConnection.RemoteAddressLength = Socket->HelperData->MaxTDIAddressLength; 00643 00644 /* Verifiy if we should use APC */ 00645 if (lpOverlapped == NULL) 00646 { 00647 /* Not using Overlapped structure, so use normal blocking on event */ 00648 APCContext = NULL; 00649 APCFunction = NULL; 00650 Event = SockEvent; 00651 IOSB = &DummyIOSB; 00652 } 00653 else 00654 { 00655 if (lpCompletionRoutine == NULL) 00656 { 00657 /* Using Overlapped Structure, but no Completition Routine, so no need for APC */ 00658 APCContext = lpOverlapped; 00659 APCFunction = NULL; 00660 Event = lpOverlapped->hEvent; 00661 } 00662 else 00663 { 00664 /* Using Overlapped Structure and a Completition Routine, so use an APC */ 00665 /* Should be a private io completition function inside us */ 00666 APCFunction = NULL; 00667 APCContext = lpCompletionRoutine; 00668 SendInfo.AfdFlags |= AFD_SKIP_FIO; 00669 } 00670 00671 IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal; 00672 SendInfo.AfdFlags |= AFD_OVERLAPPED; 00673 } 00674 00675 /* Send IOCTL */ 00676 Status = NtDeviceIoControlFile((HANDLE)Handle, 00677 Event, 00678 APCFunction, 00679 APCContext, 00680 IOSB, 00681 IOCTL_AFD_SEND_DATAGRAM, 00682 &SendInfo, 00683 sizeof(SendInfo), 00684 NULL, 00685 0); 00686 00687 /* Wait for completition of not overlapped */ 00688 if (Status == STATUS_PENDING && lpOverlapped == NULL) 00689 { 00690 /* BUGBUG, shouldn't wait infintely for send... */ 00691 WaitForSingleObject(SockEvent, INFINITE); 00692 Status = IOSB->Status; 00693 } 00694 00695 NtClose(SockEvent); 00696 HeapFree(GlobalHeap, 0, RemoteAddress); 00697 if (BindAddress != NULL) 00698 { 00699 HeapFree(GlobalHeap, 0, BindAddress); 00700 } 00701 00702 SockReenableAsyncSelectEvent(Socket, FD_WRITE); 00703 00704 return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesSent); 00705 } 00706 00707 INT 00708 WSPAPI 00709 WSPRecvDisconnect(IN SOCKET s, 00710 OUT LPWSABUF lpInboundDisconnectData, 00711 OUT LPINT lpErrno) 00712 { 00713 UNIMPLEMENTED 00714 return 0; 00715 } 00716 00717 00718 00719 INT 00720 WSPAPI 00721 WSPSendDisconnect(IN SOCKET s, 00722 IN LPWSABUF lpOutboundDisconnectData, 00723 OUT LPINT lpErrno) 00724 { 00725 UNIMPLEMENTED 00726 return 0; 00727 } 00728 00729 /* EOF */ Generated on Fri May 25 2012 04:22:54 for ReactOS by
1.7.6.1
|