/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS WinSock 2 API * FILE: dll/win32/ws2_32/src/dsocket.c * PURPOSE: Socket Object * PROGRAMMER: Alex Ionescu (alex@relsoft.net) */ /* INCLUDES ******************************************************************/ #include /* DATA **********************************************************************/ PWAH_HANDLE_TABLE WsSockHandleTable; /* FUNCTIONS *****************************************************************/ INT WSAAPI WsSockStartup(VOID) { /* Check if we have a socket table */ if (!WsSockHandleTable) { /* Create it */ return WahCreateHandleContextTable(&WsSockHandleTable); } /* Nothing to do */ return NO_ERROR; } VOID WSPAPI WsSockCleanup(VOID) { /* Check if we have a socket table */ if (WsSockHandleTable) { /* Destroy it */ WahDestroyHandleContextTable(WsSockHandleTable); } } PWSSOCKET WSAAPI WsSockAllocate(VOID) { PWSSOCKET Socket; /* Allocate the socket object */ Socket = HeapAlloc(WsSockHeap, HEAP_ZERO_MEMORY, sizeof(*Socket)); if (Socket) { /* Setup default non-zero values */ Socket->RefCount = 2; Socket->Overlapped = TRUE; } /* Return it */ return Socket; } INT WSAAPI WsSockInitialize(IN PWSSOCKET Socket, IN PTCATALOG_ENTRY CatalogEntry) { PWSTHREAD CurrentThread; /* Associate this catalog and reference it */ Socket->CatalogEntry = CatalogEntry; InterlockedIncrement(&CatalogEntry->RefCount); /* Associate the Provider and Process Objects */ Socket->Provider = CatalogEntry->Provider; /* Get the current Thread Object */ if ((CurrentThread = TlsGetValue(TlsIndex))) { /* Set the overlapped mode */ Socket->Overlapped = (CurrentThread->OpenType == 0); } /* Return status */ return ERROR_SUCCESS; } PWSSOCKET WSAAPI WsSockGetSocketNoExport(IN SOCKET Handle) { /* Let WAH do the translation */ return (PWSSOCKET)WahReferenceContextByHandle(WsSockHandleTable, (HANDLE)Handle); } PWSSOCKET WSAAPI WsSockFindIfsSocket(IN SOCKET Handle) { INT ErrorCode; DWORD Flags; PWSSOCKET Socket = NULL; PWSPROCESS Process = NULL; PTCATALOG Catalog = NULL; /* Validate the socket and get handle info */ if ((Handle != INVALID_SOCKET) && (GetHandleInformation((HANDLE)Handle, &Flags))) { /* Get the process */ if ((Process = WsGetProcess())) { /* Get the catalog */ Catalog = WsProcGetTCatalog(Process); /* Get the IFS Provider */ ErrorCode = WsTcFindIfsProviderForSocket(Catalog, Handle); /* Check for success */ if (ErrorCode == ERROR_SUCCESS) { /* Get the Socket now */ Socket = WsSockGetSocketNoExport(Handle); /* Mark it as an API Socket */ if (Socket) Socket->ApiSocket = TRUE; } } } /* Return the socket */ return Socket; } PWSSOCKET WSAAPI WsSockGetSocket(IN SOCKET Handle) { PWSSOCKET Socket; /* Let WAH do the translation */ if ((WsSockHandleTable != NULL) && (Socket = (PWSSOCKET)WahReferenceContextByHandle(WsSockHandleTable, (HANDLE)Handle))) { return Socket; } else { /* WAH didn't find it, use IFS */ return WsSockFindIfsSocket(Handle); } } INT WSAAPI WsSockAddApiReference(IN SOCKET Handle) { PWSSOCKET Socket; /* Get the Socket now */ if ((Socket = WsSockGetSocketNoExport(Handle))) { /* Mark it as an API Socket */ if (Socket) Socket->ApiSocket = TRUE; /* Remove a reference and return */ WsSockDereference(Socket); return ERROR_SUCCESS; } /* Return error */ return WSASYSCALLFAILURE; } BOOL WSAAPI WsSockDeleteSockets(IN LPVOID Context, IN PWAH_HANDLE Handle) { /* Call the detach routine */ return WsProcDetachSocket((PWSPROCESS)Context, Handle); } VOID WSAAPI WsSockDelete(IN PWSSOCKET Socket) { /* Check if we have a catalog entry */ if (Socket->CatalogEntry) { /* Dereference it */ WsTcEntryDereference(Socket->CatalogEntry); Socket->CatalogEntry = NULL; } /* Delete us */ HeapFree(WsSockHeap, 0, Socket); } VOID WSAAPI WsSockDereference(IN PWSSOCKET Socket) { /* Dereference and check if it's now 0 */ if (!(InterlockedDecrement(&Socket->RefCount))) { /* We can delete the Provider now */ WsSockDelete(Socket); } } INT WSAAPI WsSockDisassociateHandle(IN PWSSOCKET Socket) { /* Remove it from the list */ return WahRemoveHandleContext(WsSockHandleTable, (PWAH_HANDLE)Socket); } INT WSAAPI WsSockAssociateHandle(IN PWSSOCKET Socket, IN SOCKET Handle, IN BOOLEAN IsProvider) { INT ErrorCode = ERROR_SUCCESS; PWSSOCKET OldSocket; /* Save the socket and provider */ Socket->IsProvider = IsProvider; Socket->Handle = (HANDLE)Handle; /* Insert it into the handle table */ OldSocket = (PWSSOCKET)WahInsertHandleContext(WsSockHandleTable, (PWAH_HANDLE)Socket); /* Check if a socket already existed */ if (OldSocket != Socket) { /* We'll dereference it */ WsSockDereference(OldSocket); } else if (!OldSocket) { /* No memory to allocate it */ ErrorCode = WSAENOBUFS; } /* Return */ return ErrorCode; }