catalog.c
来自「一个类似windows」· C语言 代码 · 共 338 行
C
338 行
/*
* 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>
#include <catalog.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));
#ifdef 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);
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 */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?