[MSAFD] When out of band data is inlined, calling WSPRecv/WSPRecvFrom with flag MSG_O...
[reactos.git] / reactos / dll / win32 / msafd / misc / sndrcv.c
index 9d5adb7..2f5fd32 100644 (file)
@@ -45,10 +45,10 @@ WSPAsyncSelect(IN  SOCKET Handle,
 
     /* Change the Socket to Non Blocking */
     BlockMode = TRUE;
-    SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &BlockMode, NULL, NULL);
+    SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &BlockMode, NULL, NULL, NULL, NULL);
     Socket->SharedData->NonBlocking = TRUE;
 
-    /* Deactive WSPEventSelect */
+    /* Deactivate WSPEventSelect */
     if (Socket->SharedData->AsyncEvents)
     {
         if (WSPEventSelect(Handle, NULL, 0, lpErrno) == SOCKET_ERROR)
@@ -104,9 +104,8 @@ WSPGetOverlappedResult(
     OUT LPDWORD lpdwFlags,
     OUT LPINT lpErrno)
 {
-    PIO_STATUS_BLOCK        IOSB;
-    NTSTATUS                Status;
     PSOCKET_INFORMATION     Socket;
+    BOOL                    Ret;
 
     TRACE("Called (%x)\n", Handle);
 
@@ -124,43 +123,19 @@ WSPGetOverlappedResult(
             *lpErrno = WSAEFAULT;
         return FALSE;
     }
-    IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal;
-    if (!IOSB)
-    {
-        if (lpErrno)
-            *lpErrno = WSAEFAULT;
-        return FALSE;
-    }
-    Status = IOSB->Status;
+    Ret = GetOverlappedResult((HANDLE)Handle, lpOverlapped, lpdwBytes, fWait);
 
-    /* Wait for completition of overlapped */
-    if (Status == STATUS_PENDING)
-    {
-        /* It's up to the protocol to time out recv.  We must wait
-        * until the protocol decides it's had enough.
-        */
-        if (fWait)
-        {
-            WaitForSingleObject(lpOverlapped->hEvent, INFINITE);
-            Status = IOSB->Status;
-        }
-    }
-
-    TRACE("Status %x Information %d\n", Status, IOSB->Information);
-
-    if (Status != STATUS_PENDING)
+    if (Ret)
     {
         *lpdwFlags = 0;
 
-        *lpdwBytes = IOSB->Information;
-
         /* Re-enable Async Event */
         SockReenableAsyncSelectEvent(Socket, FD_OOB);
         SockReenableAsyncSelectEvent(Socket, FD_WRITE);
         SockReenableAsyncSelectEvent(Socket, FD_READ);
     }
 
-    return Status == STATUS_SUCCESS;
+    return Ret;
 }
 
 VOID
@@ -208,8 +183,21 @@ WSPRecv(SOCKET Handle,
     Socket = GetSocketStructure(Handle);
     if (!Socket)
     {
-       *lpErrno = WSAENOTSOCK;
-       return SOCKET_ERROR;
+        if (lpErrno)
+            *lpErrno = WSAENOTSOCK;
+        return SOCKET_ERROR;
+    }
+    if (!lpNumberOfBytesRead && !lpOverlapped)
+    {
+        if (lpErrno)
+            *lpErrno = WSAEFAULT;
+        return SOCKET_ERROR;
+    }
+    if (Socket->SharedData->OobInline && ReceiveFlags && (*ReceiveFlags & MSG_OOB) != 0)
+    {
+        if (lpErrno)
+            *lpErrno = WSAEINVAL;
+        return SOCKET_ERROR;
     }
 
     Status = NtCreateEvent( &SockEvent, EVENT_ALL_ACCESS,
@@ -247,7 +235,7 @@ WSPRecv(SOCKET Handle,
         }
     }
 
-    /* Verifiy if we should use APC */
+    /* Verify if we should use APC */
 
     if (lpOverlapped == NULL)
     {
@@ -267,15 +255,15 @@ WSPRecv(SOCKET Handle,
         }
         if (lpCompletionRoutine == NULL)
         {
-            /* Using Overlapped Structure, but no Completition Routine, so no need for APC */
+            /* Using Overlapped Structure, but no Completion Routine, so no need for APC */
             APCContext = lpOverlapped;
             APCFunction = NULL;
             Event = lpOverlapped->hEvent;
         }
         else
         {
-            /* Using Overlapped Structure and a Completition Routine, so use an APC */
-            APCFunction = &AfdAPC; // should be a private io completition function inside us
+            /* Using Overlapped Structure and a Completion Routine, so use an APC */
+            APCFunction = &AfdAPC; // should be a private io completion function inside us
             APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
             if (!APCContext)
             {
@@ -306,7 +294,7 @@ WSPRecv(SOCKET Handle,
                                    NULL,
                                    0);
 
-    /* Wait for completition of not overlapped */
+    /* Wait for completion of not overlapped */
     if (Status == STATUS_PENDING && lpOverlapped == NULL)
     {
         /* It's up to the protocol to time out recv.  We must wait
@@ -389,8 +377,21 @@ WSPRecvFrom(SOCKET Handle,
     Socket = GetSocketStructure(Handle);
     if (!Socket)
     {
-       *lpErrno = WSAENOTSOCK;
-       return SOCKET_ERROR;
+        if (lpErrno)
+            *lpErrno = WSAENOTSOCK;
+        return SOCKET_ERROR;
+    }
+    if (!lpNumberOfBytesRead && !lpOverlapped)
+    {
+        if (lpErrno)
+            *lpErrno = WSAEFAULT;
+        return SOCKET_ERROR;
+    }
+    if (Socket->SharedData->OobInline && ReceiveFlags && (*ReceiveFlags & MSG_OOB) != 0)
+    {
+        if (lpErrno)
+            *lpErrno = WSAEINVAL;
+        return SOCKET_ERROR;
     }
 
     if (!(Socket->SharedData->ServiceFlags1 & XP1_CONNECTIONLESS))
@@ -455,7 +456,7 @@ WSPRecvFrom(SOCKET Handle,
         }
     }
 
-    /* Verifiy if we should use APC */
+    /* Verify if we should use APC */
 
     if (lpOverlapped == NULL)
     {
@@ -475,15 +476,15 @@ WSPRecvFrom(SOCKET Handle,
         }
         if (lpCompletionRoutine == NULL)
         {
-            /* Using Overlapped Structure, but no Completition Routine, so no need for APC */
+            /* Using Overlapped Structure, but no Completion Routine, so no need for APC */
             APCContext = lpOverlapped;
             APCFunction = NULL;
             Event = lpOverlapped->hEvent;
         }
         else
         {
-            /* Using Overlapped Structure and a Completition Routine, so use an APC */
-            APCFunction = &AfdAPC; // should be a private io completition function inside us
+            /* Using Overlapped Structure and a Completion Routine, so use an APC */
+            APCFunction = &AfdAPC; // should be a private io completion function inside us
             APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
             if (!APCContext)
             {
@@ -514,10 +515,10 @@ WSPRecvFrom(SOCKET Handle,
                                     NULL,
                                     0);
 
-    /* Wait for completition of not overlapped */
+    /* Wait for completion of not overlapped */
     if (Status == STATUS_PENDING && lpOverlapped == NULL)
     {
-        WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infintely for receive...
+        WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infinitely for receive...
         Status = IOSB->Status;
     }
 
@@ -591,8 +592,15 @@ WSPSend(SOCKET Handle,
     Socket = GetSocketStructure(Handle);
     if (!Socket)
     {
-       *lpErrno = WSAENOTSOCK;
-       return SOCKET_ERROR;
+        if (lpErrno)
+            *lpErrno = WSAENOTSOCK;
+        return SOCKET_ERROR;
+    }
+    if (!lpNumberOfBytesSent && !lpOverlapped)
+    {
+        if (lpErrno)
+            *lpErrno = WSAEFAULT;
+        return SOCKET_ERROR;
     }
 
     Status = NtCreateEvent( &SockEvent, EVENT_ALL_ACCESS,
@@ -622,7 +630,7 @@ WSPSend(SOCKET Handle,
         }
     }
 
-    /* Verifiy if we should use APC */
+    /* Verify if we should use APC */
     if (lpOverlapped == NULL)
     {
         /* Not using Overlapped structure, so use normal blocking on event */
@@ -641,15 +649,15 @@ WSPSend(SOCKET Handle,
         }
         if (lpCompletionRoutine == NULL)
         {
-            /* Using Overlapped Structure, but no Completition Routine, so no need for APC */
+            /* Using Overlapped Structure, but no Completion Routine, so no need for APC */
             APCContext = lpOverlapped;
             APCFunction = NULL;
             Event = lpOverlapped->hEvent;
         }
         else
         {
-            /* Using Overlapped Structure and a Completition Routine, so use an APC */
-            APCFunction = &AfdAPC; // should be a private io completition function inside us
+            /* Using Overlapped Structure and a Completion Routine, so use an APC */
+            APCFunction = &AfdAPC; // should be a private io completion function inside us
             APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
             if (!APCContext)
             {
@@ -680,10 +688,10 @@ WSPSend(SOCKET Handle,
                                     NULL,
                                     0);
 
-    /* Wait for completition of not overlapped */
+    /* Wait for completion of not overlapped */
     if (Status == STATUS_PENDING && lpOverlapped == NULL)
     {
-        WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infintely for send...
+        WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infinitely for send...
         Status = IOSB->Status;
     }
 
@@ -740,8 +748,15 @@ WSPSendTo(SOCKET Handle,
     Socket = GetSocketStructure(Handle);
     if (!Socket)
     {
-       *lpErrno = WSAENOTSOCK;
-       return SOCKET_ERROR;
+        if (lpErrno)
+            *lpErrno = WSAENOTSOCK;
+        return SOCKET_ERROR;
+    }
+    if (!lpNumberOfBytesSent && !lpOverlapped)
+    {
+        if (lpErrno)
+            *lpErrno = WSAEFAULT;
+        return SOCKET_ERROR;
     }
 
     if (!(Socket->SharedData->ServiceFlags1 & XP1_CONNECTIONLESS))
@@ -814,7 +829,7 @@ WSPSendTo(SOCKET Handle,
     SendInfo.TdiConnection.RemoteAddress = RemoteAddress;
     SendInfo.TdiConnection.RemoteAddressLength = Socket->HelperData->MaxTDIAddressLength;
 
-    /* Verifiy if we should use APC */
+    /* Verify if we should use APC */
     if (lpOverlapped == NULL)
     {
         /* Not using Overlapped structure, so use normal blocking on event */
@@ -833,15 +848,15 @@ WSPSendTo(SOCKET Handle,
         }
         if (lpCompletionRoutine == NULL)
         {
-            /* Using Overlapped Structure, but no Completition Routine, so no need for APC */
+            /* Using Overlapped Structure, but no Completion Routine, so no need for APC */
             APCContext = lpOverlapped;
             APCFunction = NULL;
             Event = lpOverlapped->hEvent;
         }
         else
         {
-            /* Using Overlapped Structure and a Completition Routine, so use an APC */
-            APCFunction = &AfdAPC; // should be a private io completition function inside us
+            /* Using Overlapped Structure and a Completion Routine, so use an APC */
+            APCFunction = &AfdAPC; // should be a private io completion function inside us
             APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
             if (!APCContext)
             {
@@ -870,10 +885,10 @@ WSPSendTo(SOCKET Handle,
                                    NULL,
                                    0);
 
-    /* Wait for completition of not overlapped */
+    /* Wait for completion of not overlapped */
     if (Status == STATUS_PENDING && lpOverlapped == NULL)
     {
-        /* BUGBUG, shouldn't wait infintely for send... */
+        /* BUGBUG, shouldn't wait infinitely for send... */
         WaitForSingleObject(SockEvent, INFINITE);
         Status = IOSB->Status;
     }