[MSAFD] Don't assume SOL_SOCKET is the only socket level. By Peter Hater. CORE-10440...
[reactos.git] / reactos / dll / win32 / ws2_32_new / src / dsocket.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WinSock 2 API
4 * FILE: dll/win32/ws2_32_new/src/dsocket.c
5 * PURPOSE: Socket Object
6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <ws2_32.h>
12
13 /* DATA **********************************************************************/
14
15 PWAH_HANDLE_TABLE WsSockHandleTable;
16
17 /* FUNCTIONS *****************************************************************/
18
19 INT
20 WSAAPI
21 WsSockStartup(VOID)
22 {
23 /* Check if we have a socket table */
24 if (!WsSockHandleTable)
25 {
26 /* Create it */
27 return WahCreateHandleContextTable(&WsSockHandleTable);
28 }
29
30 /* Nothing to do */
31 return NO_ERROR;
32 }
33
34 VOID
35 WSPAPI
36 WsSockCleanup(VOID)
37 {
38 /* Check if we have a socket table */
39 if (WsSockHandleTable)
40 {
41 /* Destroy it */
42 WahDestroyHandleContextTable(WsSockHandleTable);
43 }
44 }
45
46 PWSSOCKET
47 WSAAPI
48 WsSockAllocate(VOID)
49 {
50 PWSSOCKET Socket;
51
52 /* Allocate the socket object */
53 Socket = HeapAlloc(WsSockHeap, HEAP_ZERO_MEMORY, sizeof(WSSOCKET));
54
55 /* Setup default non-zero values */
56 Socket->RefCount = 2;
57 Socket->Overlapped = TRUE;
58
59 /* Return it */
60 return Socket;
61 }
62
63 INT
64 WSAAPI
65 WsSockInitialize(IN PWSSOCKET Socket,
66 IN PTCATALOG_ENTRY CatalogEntry)
67 {
68 PWSTHREAD CurrentThread;
69
70 /* Associate this catalog and reference it */
71 Socket->CatalogEntry = CatalogEntry;
72 InterlockedIncrement(&CatalogEntry->RefCount);
73
74 /* Associate the Provider and Process Objects */
75 Socket->Provider = CatalogEntry->Provider;
76
77 /* Get the current Thread Object */
78 if ((CurrentThread = TlsGetValue(TlsIndex)))
79 {
80 /* Set the overlapped mode */
81 Socket->Overlapped = (CurrentThread->OpenType == 0);
82 }
83
84 /* Return status */
85 return ERROR_SUCCESS;
86 }
87
88 PWSSOCKET
89 WSAAPI
90 WsSockGetSocketNoExport(IN SOCKET Handle)
91 {
92 /* Let WAH do the translation */
93 return (PWSSOCKET)WahReferenceContextByHandle(WsSockHandleTable,
94 (HANDLE)Handle);
95 }
96
97 PWSSOCKET
98 WSAAPI
99 WsSockFindIfsSocket(IN SOCKET Handle)
100 {
101 INT ErrorCode;
102 DWORD Flags;
103 PWSSOCKET Socket = NULL;
104 PWSPROCESS Process = NULL;
105 PTCATALOG Catalog = NULL;
106
107 /* Validate the socket and get handle info */
108 if ((Handle != INVALID_SOCKET) &&
109 (GetHandleInformation((HANDLE)Handle, &Flags)))
110 {
111 /* Get the process */
112 if ((Process = WsGetProcess()))
113 {
114 /* Get the catalog */
115 Catalog = WsProcGetTCatalog(Process);
116
117 /* Get the IFS Provider */
118 ErrorCode = WsTcFindIfsProviderForSocket(Catalog, Handle);
119
120 /* Check for success */
121 if (ErrorCode == ERROR_SUCCESS)
122 {
123 /* Get the Socket now */
124 Socket = WsSockGetSocketNoExport(Handle);
125
126 /* Mark it as an API Socket */
127 if (Socket) Socket->ApiSocket = TRUE;
128 }
129 }
130 }
131
132 /* Return the socket */
133 return Socket;
134 }
135
136 PWSSOCKET
137 WSAAPI
138 WsSockGetSocket(IN SOCKET Handle)
139 {
140 PWSSOCKET Socket;
141
142 /* Let WAH do the translation */
143 if ((Socket = (PWSSOCKET)WahReferenceContextByHandle(WsSockHandleTable,
144 (HANDLE)Handle)))
145 {
146 return Socket;
147 }
148 else
149 {
150 /* WAH didn't find it, use IFS */
151 return WsSockFindIfsSocket(Handle);
152 }
153 }
154
155 INT
156 WSAAPI
157 WsSockAddApiReference(IN SOCKET Handle)
158 {
159 PWSSOCKET Socket;
160
161 /* Get the Socket now */
162 if ((Socket = WsSockGetSocketNoExport(Handle)))
163 {
164 /* Mark it as an API Socket */
165 if (Socket) Socket->ApiSocket = TRUE;
166
167 /* Remove a reference and return */
168 WsSockDereference(Socket);
169 return ERROR_SUCCESS;
170 }
171
172 /* Return error */
173 return WSASYSCALLFAILURE;
174 }
175
176 BOOL
177 WSAAPI
178 WsSockDeleteSockets(IN LPVOID Context,
179 IN PWAH_HANDLE Handle)
180 {
181 /* Call the detach routine */
182 return WsProcDetachSocket((PWSPROCESS)Context, Handle);
183 }
184
185 VOID
186 WSAAPI
187 WsSockDelete(IN PWSSOCKET Socket)
188 {
189 /* Check if we have a catalog entry */
190 if (Socket->CatalogEntry)
191 {
192 /* Dereference it */
193 WsTcEntryDereference(Socket->CatalogEntry);
194 Socket->CatalogEntry = NULL;
195 }
196 }
197
198 VOID
199 WSAAPI
200 WsSockDereference(IN PWSSOCKET Socket)
201 {
202 /* Dereference and check if it's now 0 */
203 if (!(InterlockedDecrement(&Socket->RefCount)))
204 {
205 /* We can delete the Provider now */
206 WsSockDelete(Socket);
207 }
208 }
209
210 INT
211 WSAAPI
212 WsSockDisassociateHandle(IN PWSSOCKET Socket)
213 {
214 /* Remove it from the list */
215 return WahRemoveHandleContext(WsSockHandleTable, (PWAH_HANDLE)Socket);
216 }
217
218 INT
219 WSAAPI
220 WsSockAssociateHandle(IN PWSSOCKET Socket,
221 IN SOCKET Handle,
222 IN BOOLEAN IsProvider)
223 {
224 INT ErrorCode = ERROR_SUCCESS;
225 PWSSOCKET OldSocket;
226
227 /* Save the socket and provider */
228 Socket->IsProvider = IsProvider;
229 Socket->Handle = (HANDLE)Handle;
230
231 /* Insert it into the handle table */
232 OldSocket = (PWSSOCKET)WahInsertHandleContext(WsSockHandleTable,
233 (PWAH_HANDLE)Socket);
234
235 /* Check if a socket already existed */
236 if (OldSocket != Socket)
237 {
238 /* We'll dereference it */
239 WsSockDereference(OldSocket);
240 }
241 else if (!OldSocket)
242 {
243 /* No memory to allocate it */
244 ErrorCode = WSAENOBUFS;
245 }
246
247 /* Return */
248 return ErrorCode;
249 }