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 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(*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 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 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 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 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 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 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 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 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 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 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