ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

sndrcv.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.