mirror of
https://github.com/reactos/reactos.git
synced 2024-09-10 21:04:26 +00:00
![Amine Khaldi](/assets/img/avatar_default.png)
* Create a branch for some evul shell experiments. svn path=/branches/shell-experiments/; revision=61927
356 lines
9.7 KiB
C
356 lines
9.7 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS WinSock 2 DLL
|
|
* FILE: misc/catalog.c
|
|
* PURPOSE: Service Provider Catalog
|
|
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
|
* REVISIONS:
|
|
* CSH 01/09-2000 Created
|
|
*/
|
|
|
|
#include "ws2_32.h"
|
|
|
|
LIST_ENTRY CatalogListHead;
|
|
CRITICAL_SECTION CatalogLock;
|
|
|
|
VOID
|
|
ReferenceProviderByPointer(PCATALOG_ENTRY Provider)
|
|
{
|
|
WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));
|
|
|
|
//EnterCriticalSection(&Provider->Lock);
|
|
Provider->ReferenceCount++;
|
|
//LeaveCriticalSection(&Provider->Lock);
|
|
|
|
WS_DbgPrint(MAX_TRACE, ("Leaving\n"));
|
|
}
|
|
|
|
|
|
VOID
|
|
DereferenceProviderByPointer(PCATALOG_ENTRY Provider)
|
|
{
|
|
WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));
|
|
|
|
#if DBG
|
|
if (Provider->ReferenceCount <= 0)
|
|
{
|
|
WS_DbgPrint(MIN_TRACE, ("Provider at 0x%X has invalid reference count (%ld).\n",
|
|
Provider, Provider->ReferenceCount));
|
|
}
|
|
#endif
|
|
|
|
//EnterCriticalSection(&Provider->Lock);
|
|
Provider->ReferenceCount--;
|
|
//LeaveCriticalSection(&Provider->Lock);
|
|
|
|
if (Provider->ReferenceCount == 0)
|
|
{
|
|
WS_DbgPrint(MAX_TRACE, ("Provider at 0x%X has reference count 0 (unloading).\n",
|
|
Provider));
|
|
|
|
DestroyCatalogEntry(Provider);
|
|
}
|
|
}
|
|
|
|
|
|
PCATALOG_ENTRY
|
|
CreateCatalogEntry(LPWSTR LibraryName)
|
|
{
|
|
PCATALOG_ENTRY Provider;
|
|
|
|
WS_DbgPrint(MAX_TRACE, ("LibraryName (%S).\n", LibraryName));
|
|
|
|
Provider = HeapAlloc(GlobalHeap, 0, sizeof(CATALOG_ENTRY));
|
|
if (!Provider)
|
|
return NULL;
|
|
|
|
ZeroMemory(Provider, sizeof(CATALOG_ENTRY));
|
|
|
|
if (!RtlCreateUnicodeString(&Provider->LibraryName, LibraryName))
|
|
{
|
|
RtlFreeHeap(GlobalHeap, 0, Provider);
|
|
return NULL;
|
|
}
|
|
|
|
Provider->ReferenceCount = 1;
|
|
|
|
InitializeCriticalSection(&Provider->Lock);
|
|
Provider->hModule = NULL;
|
|
|
|
Provider->Mapping = NULL;
|
|
|
|
//EnterCriticalSection(&CatalogLock);
|
|
|
|
InsertTailList(&CatalogListHead, &Provider->ListEntry);
|
|
|
|
//LeaveCriticalSection(&CatalogLock);
|
|
|
|
return Provider;
|
|
}
|
|
|
|
|
|
INT
|
|
DestroyCatalogEntry(PCATALOG_ENTRY Provider)
|
|
{
|
|
INT Status;
|
|
|
|
WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));
|
|
|
|
//EnterCriticalSection(&CatalogLock);
|
|
RemoveEntryList(&Provider->ListEntry);
|
|
//LeaveCriticalSection(&CatalogLock);
|
|
|
|
HeapFree(GlobalHeap, 0, Provider->Mapping);
|
|
|
|
if (NULL != Provider->hModule)
|
|
{
|
|
Status = UnloadProvider(Provider);
|
|
}
|
|
else
|
|
{
|
|
Status = NO_ERROR;
|
|
}
|
|
|
|
//DeleteCriticalSection(&Provider->Lock);
|
|
|
|
HeapFree(GlobalHeap, 0, Provider);
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
PCATALOG_ENTRY
|
|
LocateProvider(LPWSAPROTOCOL_INFOW lpProtocolInfo)
|
|
{
|
|
PLIST_ENTRY CurrentEntry;
|
|
PCATALOG_ENTRY Provider;
|
|
UINT i;
|
|
|
|
WS_DbgPrint(MAX_TRACE, ("lpProtocolInfo (0x%X).\n", lpProtocolInfo));
|
|
|
|
//EnterCriticalSection(&CatalogLock);
|
|
|
|
CurrentEntry = CatalogListHead.Flink;
|
|
while (CurrentEntry != &CatalogListHead)
|
|
{
|
|
Provider = CONTAINING_RECORD(CurrentEntry,
|
|
CATALOG_ENTRY,
|
|
ListEntry);
|
|
|
|
for (i = 0; i < Provider->Mapping->Rows; i++)
|
|
{
|
|
if ((lpProtocolInfo->iAddressFamily == (INT) Provider->Mapping->Mapping[i].AddressFamily) &&
|
|
(lpProtocolInfo->iSocketType == (INT) Provider->Mapping->Mapping[i].SocketType) &&
|
|
((lpProtocolInfo->iProtocol == (INT) Provider->Mapping->Mapping[i].Protocol) ||
|
|
(lpProtocolInfo->iSocketType == SOCK_RAW)))
|
|
{
|
|
//LeaveCriticalSection(&CatalogLock);
|
|
lpProtocolInfo->dwCatalogEntryId = Provider->ProtocolInfo.dwCatalogEntryId;
|
|
WS_DbgPrint(MID_TRACE, ("Returning provider at (0x%X).\n", Provider));
|
|
return Provider;
|
|
}
|
|
}
|
|
|
|
CurrentEntry = CurrentEntry->Flink;
|
|
}
|
|
|
|
//LeaveCriticalSection(&CatalogLock);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
PCATALOG_ENTRY
|
|
LocateProviderById(DWORD CatalogEntryId)
|
|
{
|
|
PLIST_ENTRY CurrentEntry;
|
|
PCATALOG_ENTRY Provider;
|
|
|
|
WS_DbgPrint(MAX_TRACE, ("CatalogEntryId (%d).\n", CatalogEntryId));
|
|
|
|
//EnterCriticalSection(&CatalogLock);
|
|
CurrentEntry = CatalogListHead.Flink;
|
|
while (CurrentEntry != &CatalogListHead)
|
|
{
|
|
Provider = CONTAINING_RECORD(CurrentEntry,
|
|
CATALOG_ENTRY,
|
|
ListEntry);
|
|
|
|
if (Provider->ProtocolInfo.dwCatalogEntryId == CatalogEntryId)
|
|
{
|
|
//LeaveCriticalSection(&CatalogLock);
|
|
WS_DbgPrint(MID_TRACE, ("Returning provider at (0x%X) Name (%wZ).\n",
|
|
Provider, &Provider->LibraryName));
|
|
return Provider;
|
|
}
|
|
|
|
CurrentEntry = CurrentEntry->Flink;
|
|
}
|
|
//LeaveCriticalSection(&CatalogLock);
|
|
|
|
WS_DbgPrint(MID_TRACE, ("Provider was not found.\n"));
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
INT
|
|
LoadProvider(PCATALOG_ENTRY Provider,
|
|
LPWSAPROTOCOL_INFOW lpProtocolInfo)
|
|
{
|
|
INT Status;
|
|
|
|
WS_DbgPrint(MID_TRACE, ("Loading provider at (0x%X) Name (%wZ).\n",
|
|
Provider, &Provider->LibraryName));
|
|
|
|
if (NULL == Provider->hModule)
|
|
{
|
|
/* DLL is not loaded so load it now
|
|
* UNICODE_STRING objects are not null-terminated, but LoadLibraryW
|
|
* expects a null-terminated string
|
|
*/
|
|
Provider->LibraryName.Buffer[Provider->LibraryName.Length / sizeof(WCHAR)] = L'\0';
|
|
Provider->hModule = LoadLibraryW(Provider->LibraryName.Buffer);
|
|
if (NULL != Provider->hModule)
|
|
{
|
|
Provider->WSPStartup = (LPWSPSTARTUP)GetProcAddress(Provider->hModule,
|
|
"WSPStartup");
|
|
if (Provider->WSPStartup)
|
|
{
|
|
WS_DbgPrint(MAX_TRACE, ("Calling WSPStartup at (0x%X).\n",
|
|
Provider->WSPStartup));
|
|
Status = Provider->WSPStartup(MAKEWORD(2, 2),
|
|
&Provider->WSPData,
|
|
lpProtocolInfo,
|
|
UpcallTable,
|
|
&Provider->ProcTable);
|
|
|
|
/* FIXME: Validate the procedure table */
|
|
}
|
|
else
|
|
Status = ERROR_BAD_PROVIDER;
|
|
}
|
|
else
|
|
Status = ERROR_DLL_NOT_FOUND;
|
|
}
|
|
else
|
|
Status = NO_ERROR;
|
|
|
|
WS_DbgPrint(MID_TRACE, ("Status (%d).\n", Status));
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
INT
|
|
UnloadProvider(PCATALOG_ENTRY Provider)
|
|
{
|
|
INT Status = NO_ERROR;
|
|
|
|
WS_DbgPrint(MAX_TRACE, ("Unloading provider at (0x%X)\n", Provider));
|
|
|
|
if (NULL != Provider->hModule)
|
|
{
|
|
WS_DbgPrint(MAX_TRACE, ("Calling WSPCleanup at (0x%X).\n",
|
|
Provider->ProcTable.lpWSPCleanup));
|
|
Provider->ProcTable.lpWSPCleanup(&Status);
|
|
|
|
WS_DbgPrint(MAX_TRACE, ("Calling FreeLibrary(0x%X).\n", Provider->hModule));
|
|
if (!FreeLibrary(Provider->hModule))
|
|
{
|
|
WS_DbgPrint(MIN_TRACE, ("Could not free library at (0x%X).\n", Provider->hModule));
|
|
Status = GetLastError();
|
|
}
|
|
|
|
Provider->hModule = NULL;
|
|
}
|
|
|
|
WS_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status));
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
VOID
|
|
CreateCatalog(VOID)
|
|
{
|
|
PCATALOG_ENTRY Provider;
|
|
|
|
InitializeCriticalSection(&CatalogLock);
|
|
|
|
InitializeListHead(&CatalogListHead);
|
|
|
|
/* FIXME: Read service provider catalog from registry
|
|
|
|
Catalog info is saved somewhere under
|
|
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinSock2
|
|
*/
|
|
|
|
#if 1
|
|
Provider = CreateCatalogEntry(L"msafd.dll");
|
|
if (!Provider)
|
|
{
|
|
WS_DbgPrint(MIN_TRACE, ("Could not create catalog entry.\n"));
|
|
return;
|
|
}
|
|
|
|
/* Assume one Service Provider with id 1 */
|
|
Provider->ProtocolInfo.dwCatalogEntryId = 1;
|
|
|
|
Provider->Mapping = HeapAlloc(GlobalHeap,
|
|
0,
|
|
6 * sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD));
|
|
if (!Provider->Mapping)
|
|
return;
|
|
|
|
Provider->Mapping->Rows = 6;
|
|
Provider->Mapping->Columns = 3;
|
|
|
|
Provider->Mapping->Mapping[0].AddressFamily = AF_INET;
|
|
Provider->Mapping->Mapping[0].SocketType = SOCK_STREAM;
|
|
Provider->Mapping->Mapping[0].Protocol = 0;
|
|
|
|
Provider->Mapping->Mapping[1].AddressFamily = AF_INET;
|
|
Provider->Mapping->Mapping[1].SocketType = SOCK_STREAM;
|
|
Provider->Mapping->Mapping[1].Protocol = IPPROTO_TCP;
|
|
|
|
Provider->Mapping->Mapping[2].AddressFamily = AF_INET;
|
|
Provider->Mapping->Mapping[2].SocketType = SOCK_DGRAM;
|
|
Provider->Mapping->Mapping[2].Protocol = 0;
|
|
|
|
Provider->Mapping->Mapping[3].AddressFamily = AF_INET;
|
|
Provider->Mapping->Mapping[3].SocketType = SOCK_DGRAM;
|
|
Provider->Mapping->Mapping[3].Protocol = IPPROTO_UDP;
|
|
|
|
Provider->Mapping->Mapping[4].AddressFamily = AF_INET;
|
|
Provider->Mapping->Mapping[4].SocketType = SOCK_RAW;
|
|
Provider->Mapping->Mapping[4].Protocol = IPPROTO_ICMP;
|
|
|
|
Provider->Mapping->Mapping[5].AddressFamily = AF_INET;
|
|
Provider->Mapping->Mapping[5].SocketType = SOCK_RAW;
|
|
Provider->Mapping->Mapping[5].Protocol = 0;
|
|
#endif
|
|
}
|
|
|
|
|
|
VOID DestroyCatalog(VOID)
|
|
{
|
|
PLIST_ENTRY CurrentEntry;
|
|
PLIST_ENTRY NextEntry;
|
|
PCATALOG_ENTRY Provider;
|
|
|
|
CurrentEntry = CatalogListHead.Flink;
|
|
while (CurrentEntry != &CatalogListHead)
|
|
{
|
|
NextEntry = CurrentEntry->Flink;
|
|
Provider = CONTAINING_RECORD(CurrentEntry,
|
|
CATALOG_ENTRY,
|
|
ListEntry);
|
|
DestroyCatalogEntry(Provider);
|
|
CurrentEntry = NextEntry;
|
|
}
|
|
//DeleteCriticalSection(&CatalogLock);
|
|
}
|
|
|
|
/* EOF */
|