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 + -
显示快捷键?