1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WinSock 2 API
4 * FILE: dll/win32/ws2_32/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
WsSockStartup(VOID)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
WsSockCleanup(VOID)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
WsSockAllocate(VOID)48 WsSockAllocate(VOID)
49 {
50 PWSSOCKET Socket;
51
52 /* Allocate the socket object */
53 Socket = HeapAlloc(WsSockHeap, HEAP_ZERO_MEMORY, sizeof(*Socket));
54 if (Socket)
55 {
56 /* Setup default non-zero values */
57 Socket->RefCount = 2;
58 Socket->Overlapped = TRUE;
59 }
60
61 /* Return it */
62 return Socket;
63 }
64
65 INT
66 WSAAPI
WsSockInitialize(IN PWSSOCKET Socket,IN PTCATALOG_ENTRY CatalogEntry)67 WsSockInitialize(IN PWSSOCKET Socket,
68 IN PTCATALOG_ENTRY CatalogEntry)
69 {
70 PWSTHREAD CurrentThread;
71
72 /* Associate this catalog and reference it */
73 Socket->CatalogEntry = CatalogEntry;
74 InterlockedIncrement(&CatalogEntry->RefCount);
75
76 /* Associate the Provider and Process Objects */
77 Socket->Provider = CatalogEntry->Provider;
78
79 /* Get the current Thread Object */
80 if ((CurrentThread = TlsGetValue(TlsIndex)))
81 {
82 /* Set the overlapped mode */
83 Socket->Overlapped = (CurrentThread->OpenType == 0);
84 }
85
86 /* Return status */
87 return ERROR_SUCCESS;
88 }
89
90 PWSSOCKET
91 WSAAPI
WsSockGetSocketNoExport(IN SOCKET Handle)92 WsSockGetSocketNoExport(IN SOCKET Handle)
93 {
94 /* Let WAH do the translation */
95 return (PWSSOCKET)WahReferenceContextByHandle(WsSockHandleTable,
96 (HANDLE)Handle);
97 }
98
99 PWSSOCKET
100 WSAAPI
WsSockFindIfsSocket(IN SOCKET Handle)101 WsSockFindIfsSocket(IN SOCKET Handle)
102 {
103 INT ErrorCode;
104 DWORD Flags;
105 PWSSOCKET Socket = NULL;
106 PWSPROCESS Process = NULL;
107 PTCATALOG Catalog = NULL;
108
109 /* Validate the socket and get handle info */
110 if ((Handle != INVALID_SOCKET) &&
111 (GetHandleInformation((HANDLE)Handle, &Flags)))
112 {
113 /* Get the process */
114 if ((Process = WsGetProcess()))
115 {
116 /* Get the catalog */
117 Catalog = WsProcGetTCatalog(Process);
118
119 /* Get the IFS Provider */
120 ErrorCode = WsTcFindIfsProviderForSocket(Catalog, Handle);
121
122 /* Check for success */
123 if (ErrorCode == ERROR_SUCCESS)
124 {
125 /* Get the Socket now */
126 Socket = WsSockGetSocketNoExport(Handle);
127
128 /* Mark it as an API Socket */
129 if (Socket) Socket->ApiSocket = TRUE;
130 }
131 }
132 }
133
134 /* Return the socket */
135 return Socket;
136 }
137
138 PWSSOCKET
139 WSAAPI
WsSockGetSocket(IN SOCKET Handle)140 WsSockGetSocket(IN SOCKET Handle)
141 {
142 PWSSOCKET Socket;
143
144 /* Let WAH do the translation */
145 if ((WsSockHandleTable != NULL) &&
146 (Socket = (PWSSOCKET)WahReferenceContextByHandle(WsSockHandleTable, (HANDLE)Handle)))
147 {
148 return Socket;
149 }
150 else
151 {
152 /* WAH didn't find it, use IFS */
153 return WsSockFindIfsSocket(Handle);
154 }
155 }
156
157 INT
158 WSAAPI
WsSockAddApiReference(IN SOCKET Handle)159 WsSockAddApiReference(IN SOCKET Handle)
160 {
161 PWSSOCKET Socket;
162
163 /* Get the Socket now */
164 if ((Socket = WsSockGetSocketNoExport(Handle)))
165 {
166 /* Mark it as an API Socket */
167 if (Socket) Socket->ApiSocket = TRUE;
168
169 /* Remove a reference and return */
170 WsSockDereference(Socket);
171 return ERROR_SUCCESS;
172 }
173
174 /* Return error */
175 return WSASYSCALLFAILURE;
176 }
177
178 BOOL
179 WSAAPI
WsSockDeleteSockets(IN LPVOID Context,IN PWAH_HANDLE Handle)180 WsSockDeleteSockets(IN LPVOID Context,
181 IN PWAH_HANDLE Handle)
182 {
183 /* Call the detach routine */
184 return WsProcDetachSocket((PWSPROCESS)Context, Handle);
185 }
186
187 VOID
188 WSAAPI
WsSockDelete(IN PWSSOCKET Socket)189 WsSockDelete(IN PWSSOCKET Socket)
190 {
191 /* Check if we have a catalog entry */
192 if (Socket->CatalogEntry)
193 {
194 /* Dereference it */
195 WsTcEntryDereference(Socket->CatalogEntry);
196 Socket->CatalogEntry = NULL;
197 }
198
199 /* Delete us */
200 HeapFree(WsSockHeap, 0, Socket);
201 }
202
203 VOID
204 WSAAPI
WsSockDereference(IN PWSSOCKET Socket)205 WsSockDereference(IN PWSSOCKET Socket)
206 {
207 /* Dereference and check if it's now 0 */
208 if (!(InterlockedDecrement(&Socket->RefCount)))
209 {
210 /* We can delete the Provider now */
211 WsSockDelete(Socket);
212 }
213 }
214
215 INT
216 WSAAPI
WsSockDisassociateHandle(IN PWSSOCKET Socket)217 WsSockDisassociateHandle(IN PWSSOCKET Socket)
218 {
219 /* Remove it from the list */
220 return WahRemoveHandleContext(WsSockHandleTable, (PWAH_HANDLE)Socket);
221 }
222
223 INT
224 WSAAPI
WsSockAssociateHandle(IN PWSSOCKET Socket,IN SOCKET Handle,IN BOOLEAN IsProvider)225 WsSockAssociateHandle(IN PWSSOCKET Socket,
226 IN SOCKET Handle,
227 IN BOOLEAN IsProvider)
228 {
229 INT ErrorCode = ERROR_SUCCESS;
230 PWSSOCKET OldSocket;
231
232 /* Save the socket and provider */
233 Socket->IsProvider = IsProvider;
234 Socket->Handle = (HANDLE)Handle;
235
236 /* Insert it into the handle table */
237 OldSocket = (PWSSOCKET)WahInsertHandleContext(WsSockHandleTable,
238 (PWAH_HANDLE)Socket);
239
240 /* Check if a socket already existed */
241 if (OldSocket != Socket)
242 {
243 /* We'll dereference it */
244 WsSockDereference(OldSocket);
245 }
246 else if (!OldSocket)
247 {
248 /* No memory to allocate it */
249 ErrorCode = WSAENOBUFS;
250 }
251
252 /* Return */
253 return ErrorCode;
254 }
255