xref: /reactos/dll/win32/ws2_32/src/dupsock.c (revision 2b933529)
1 /*
2  * COPYRIGHT:   See COPYING in the top level directory
3  * PROJECT:     ReactOS WinSock 2 API
4  * FILE:        dll/win32/ws2_32/src/dupsock.c
5  * PURPOSE:     Socket Duplication
6  * PROGRAMMER:  Alex Ionescu (alex@relsoft.net)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include <ws2_32.h>
12 
13 #define NDEBUG
14 #include <debug.h>
15 
16 /* FUNCTIONS *****************************************************************/
17 
18 /*
19  * @implemented
20  */
21 INT
22 WSAAPI
23 WSADuplicateSocketA(IN SOCKET s,
24                     IN DWORD dwProcessId,
25                     OUT LPWSAPROTOCOL_INFOA lpProtocolInfo)
26 {
27     WSAPROTOCOL_INFOW ProtocolInfoW;
28     INT ErrorCode;
29     DPRINT("WSADuplicateSocketA: %lx, %lx, %p\n", s, dwProcessId, lpProtocolInfo);
30 
31     /* Call the Unicode Function */
32     ErrorCode = WSADuplicateSocketW(s, dwProcessId, &ProtocolInfoW);
33 
34     /* Check for success */
35     if (ErrorCode == ERROR_SUCCESS)
36     {
37         /* Convert Protocol Info to Ansi */
38         if (lpProtocolInfo)
39         {
40             /* Convert the information to ANSI */
41             ErrorCode = MapUnicodeProtocolInfoToAnsi(&ProtocolInfoW,
42                                                      lpProtocolInfo);
43         }
44         else
45         {
46             /* Fail */
47             ErrorCode = WSAEFAULT;
48         }
49 
50         /* Check if the conversion failed */
51         if (ErrorCode != ERROR_SUCCESS)
52         {
53             /* Set the last error and normalize the error */
54             SetLastError(ErrorCode);
55             ErrorCode = SOCKET_ERROR;
56         }
57     }
58 
59     /* Return */
60     return ErrorCode;
61 }
62 
63 /*
64  * @implemented
65  */
66 INT
67 WSAAPI
68 WSADuplicateSocketW(IN SOCKET s,
69                     IN DWORD dwProcessId,
70                     OUT LPWSAPROTOCOL_INFOW lpProtocolInfo)
71 {
72     PWSSOCKET Socket;
73     INT Status;
74     INT ErrorCode;
75     DPRINT("WSADuplicateSocketW: %lx, %lx, %p\n", s, dwProcessId, lpProtocolInfo);
76 
77     /* Check for WSAStartup */
78     if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS)
79     {
80         /* Get the Socket Context */
81         if ((Socket = WsSockGetSocket(s)))
82         {
83             /* Make the call */
84             Status = Socket->Provider->Service.lpWSPDuplicateSocket(s,
85                                                             dwProcessId,
86                                                             lpProtocolInfo,
87                                                             &ErrorCode);
88             /* Deference the Socket Context */
89             WsSockDereference(Socket);
90 
91             /* Return Provider Value */
92             if (Status == ERROR_SUCCESS) return Status;
93 
94             /* If everything seemed fine, then the WSP call failed itself */
95             if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE;
96         }
97         else
98         {
99             /* No Socket Context Found */
100             ErrorCode = WSAENOTSOCK;
101         }
102     }
103 
104     /* Return with an Error */
105     SetLastError(ErrorCode);
106     return SOCKET_ERROR;
107 }
108