⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 protocol.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
  NTSTATUS NtStatus;
  UINT MinSize;
  HANDLE DriverKeyHandle = NULL;
  PKEY_VALUE_PARTIAL_INFORMATION KeyInformation = NULL;
  WCHAR *DataPtr;

  NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));

  /* first validate the PROTOCOL_CHARACTERISTICS */
  switch (ProtocolCharacteristics->MajorNdisVersion)
    {
    case 0x03:
      /* we don't really want to support ndis3 drivers - so we complain for now */
      NDIS_DbgPrint(MID_TRACE, ("NDIS 3 protocol attempting to register\n"));
      MinSize = sizeof(NDIS30_PROTOCOL_CHARACTERISTICS);
      break;

    case 0x04:
      MinSize = sizeof(NDIS40_PROTOCOL_CHARACTERISTICS);
      break;

    case 0x05:
      MinSize = sizeof(NDIS50_PROTOCOL_CHARACTERISTICS);
      break;

    default:
      *Status = NDIS_STATUS_BAD_VERSION;
      NDIS_DbgPrint(MIN_TRACE, ("Incorrect characteristics size\n"));
      return;
    }

  if (CharacteristicsLength < MinSize)
    {
      NDIS_DbgPrint(DEBUG_PROTOCOL, ("Bad protocol characteristics.\n"));
      *Status = NDIS_STATUS_BAD_CHARACTERISTICS;
      return;
    }

  /* set up the protocol block */
  Protocol = ExAllocatePool(NonPagedPool, sizeof(PROTOCOL_BINDING));
  if (!Protocol)
    {
      NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
      *Status = NDIS_STATUS_RESOURCES;
      return;
    }

  RtlZeroMemory(Protocol, sizeof(PROTOCOL_BINDING));
  RtlCopyMemory(&Protocol->Chars, ProtocolCharacteristics, MinSize);

  NtStatus = RtlUpcaseUnicodeString(&Protocol->Chars.Name, &ProtocolCharacteristics->Name, TRUE);
  if (!NT_SUCCESS(NtStatus))
    {
      NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
      ExFreePool(Protocol);
      *Status = NDIS_STATUS_RESOURCES;
      return;
    }

  KeInitializeSpinLock(&Protocol->Lock);

  InitializeListHead(&Protocol->AdapterListHead);

  /*
   * bind the protocol to all of its miniports
   *
   * open registry path
   * get list of devices from Bind key
   * call BindAdapterHandler for each
   */
  {
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING RegistryPath;
    WCHAR *RegistryPathStr;

    RegistryPathStr = ExAllocatePoolWithTag(PagedPool, sizeof(SERVICES_KEY) + ProtocolCharacteristics->Name.Length + sizeof(LINKAGE_KEY), NDIS_TAG + __LINE__);
    if(!RegistryPathStr)
      {
        NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
        ExFreePool(Protocol);
        *Status = NDIS_STATUS_RESOURCES;
        return;
      }

    wcscpy(RegistryPathStr, SERVICES_KEY);
    wcsncat(RegistryPathStr, ((WCHAR *)ProtocolCharacteristics->Name.Buffer), ProtocolCharacteristics->Name.Length / sizeof(WCHAR));
    RegistryPathStr[wcslen(SERVICES_KEY)+ProtocolCharacteristics->Name.Length/sizeof(WCHAR)] = 0;
    wcscat(RegistryPathStr, LINKAGE_KEY);

    RtlInitUnicodeString(&RegistryPath, RegistryPathStr);
    NDIS_DbgPrint(MAX_TRACE, ("Opening configuration key: %wZ\n", &RegistryPath));

    InitializeObjectAttributes(&ObjectAttributes, &RegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL);
    NtStatus = ZwOpenKey(&DriverKeyHandle, KEY_READ, &ObjectAttributes);

    ExFreePool(RegistryPathStr);

    if(!NT_SUCCESS(NtStatus))
      {
        NDIS_DbgPrint(MID_TRACE, ("Unable to open protocol configuration\n"));
        ExFreePool(Protocol);
        *Status = NDIS_STATUS_FAILURE;
        return;
      }
  }

  NDIS_DbgPrint(MAX_TRACE, ("Successfully opened the registry configuration\n"));

  {
    UNICODE_STRING ValueName;
    ULONG ResultLength;

    RtlInitUnicodeString(&ValueName, L"Bind");

    NtStatus = ZwQueryValueKey(DriverKeyHandle, &ValueName, KeyValuePartialInformation, NULL, 0, &ResultLength);
    if(NtStatus != STATUS_BUFFER_OVERFLOW && NtStatus != STATUS_BUFFER_TOO_SMALL)
      {
        NDIS_DbgPrint(MID_TRACE, ("Unable to query the Bind value for size\n"));
        ZwClose(DriverKeyHandle);
        ExFreePool(Protocol);
        *Status = NDIS_STATUS_FAILURE;
        return;
      }

    KeyInformation = ExAllocatePoolWithTag(PagedPool, sizeof(KEY_VALUE_PARTIAL_INFORMATION) + ResultLength, NDIS_TAG + __LINE__);
    if(!KeyInformation)
      {
        NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
        ZwClose(DriverKeyHandle);
        ExFreePool(Protocol);
        *Status = NDIS_STATUS_FAILURE;
        return;
      }

    NtStatus = ZwQueryValueKey(DriverKeyHandle, &ValueName, KeyValuePartialInformation, KeyInformation,
        sizeof(KEY_VALUE_PARTIAL_INFORMATION) + ResultLength, &ResultLength);

    if(!NT_SUCCESS(NtStatus))
      {
        NDIS_DbgPrint(MIN_TRACE, ("Unable to query the Bind value\n"));
        ZwClose(DriverKeyHandle);
        ExFreePool(KeyInformation);
        ExFreePool(Protocol);
        *Status = NDIS_STATUS_FAILURE;
        return;
      }
  }

  for (DataPtr = (WCHAR *)KeyInformation->Data;
       *DataPtr != 0;
       DataPtr += wcslen(DataPtr) + 1)
    {
      /* BindContext is for tracking pending binding operations */
      VOID *BindContext = 0;
      NDIS_STRING DeviceName;
      NDIS_STRING RegistryPath;
      WCHAR *RegistryPathStr = NULL;
      ULONG PathLength = 0;

      RtlInitUnicodeString(&DeviceName, DataPtr);	/* we know this is 0-term */

      /*
       * RegistryPath should be:
       *     \Registry\Machine\System\CurrentControlSet\Services\Nic1\Parameters\Tcpip
       *
       *  This is constructed as follows:
       *      SERVICES_KEY + extracted device name + Protocol name from characteristics
       */

      PathLength = sizeof(SERVICES_KEY) +                               /* \Registry\Machine\System\CurrentControlSet\Services\ */
          wcslen( DataPtr + 8 ) * sizeof(WCHAR) + /* Adapter1  (extracted from \Device\Adapter1)          */
          sizeof(PARAMETERS_KEY) +                                      /* \Parameters\                                         */
          ProtocolCharacteristics->Name.Length + sizeof(WCHAR);                         /* Tcpip                                                */

      RegistryPathStr = ExAllocatePool(PagedPool, PathLength);
      if(!RegistryPathStr)
        {
          NDIS_DbgPrint(MIN_TRACE, ("insufficient resources.\n"));
          ExFreePool(KeyInformation);
          ExFreePool(Protocol);
          *Status = NDIS_STATUS_RESOURCES;
          return;
        }

      wcscpy(RegistryPathStr, SERVICES_KEY);
      wcscat(RegistryPathStr, DataPtr + 8 );
      wcscat(RegistryPathStr, PARAMETERS_KEY);
      wcsncat(RegistryPathStr, ProtocolCharacteristics->Name.Buffer, ProtocolCharacteristics->Name.Length / sizeof(WCHAR) );

      RegistryPathStr[PathLength/sizeof(WCHAR) - 1] = 0;

      RtlInitUnicodeString(&RegistryPath, RegistryPathStr);

      NDIS_DbgPrint(MAX_TRACE, ("Calling protocol's BindAdapter handler with DeviceName %wZ and RegistryPath %wZ\n",
          &DeviceName, &RegistryPath));

      /* XXX SD must do something with bind context */
      *NdisProtocolHandle = Protocol;

        {
          BIND_HANDLER BindHandler = ProtocolCharacteristics->BindAdapterHandler;
          if(BindHandler)
            BindHandler(Status, BindContext, &DeviceName, &RegistryPath, 0);
          else
            NDIS_DbgPrint(MID_TRACE, ("No protocol bind handler specified\n"));
        }

      /*
      (*(Protocol->Chars.BindAdapterHandler))(Status, BindContext, &DeviceName, &RegistryPath, 0);
      */

      if(*Status == NDIS_STATUS_SUCCESS)
        {
          /* Put protocol binding struct on global list */
          ExInterlockedInsertTailList(&ProtocolListHead, &Protocol->ListEntry, &ProtocolListLock);
        }

      /*
      else if(*Status != NDIS_STATUS_PENDING)
        {
          // what to do here?
        }
       */
    }

  *Status             = NDIS_STATUS_SUCCESS;
}


/*
 * @implemented
 */
VOID
EXPORT
NdisRequest(
    OUT PNDIS_STATUS    Status,
    IN  NDIS_HANDLE     NdisBindingHandle,
    IN  PNDIS_REQUEST   NdisRequest)
/*
 * FUNCTION: Forwards a request to an NDIS driver
 * ARGUMENTS:
 *     Status            = Address of buffer for status information
 *     NdisBindingHandle = Adapter binding handle
 *     NdisRequest       = Pointer to request to perform
 */
{
    *Status = ProRequest(NdisBindingHandle, NdisRequest);
}


/*
 * @implemented
 */
VOID
EXPORT
NdisReset(
    OUT PNDIS_STATUS    Status,
    IN  NDIS_HANDLE     NdisBindingHandle)
{
    *Status = ProReset(NdisBindingHandle);
}


/*
 * @implemented
 */
#undef NdisSend
VOID
EXPORT
NdisSend(
    OUT PNDIS_STATUS    Status,
    IN  NDIS_HANDLE     NdisBindingHandle,
    IN  PNDIS_PACKET    Packet)
/*
 * FUNCTION: Forwards a request to send a packet
 * ARGUMENTS:
 *     Status             = Address of buffer for status information
 *     NdisBindingHandle  = Adapter binding handle
 *     Packet             = Pointer to NDIS packet descriptor
 */
{
    *Status = ProSend(NdisBindingHandle, Packet);
}


/*
 * @implemented
 */
#undef NdisSendPackets
VOID
EXPORT
NdisSendPackets(
    IN  NDIS_HANDLE     NdisBindingHandle,
    IN  PPNDIS_PACKET   PacketArray,
    IN  UINT            NumberOfPackets)
{
    ProSendPackets(NdisBindingHandle, PacketArray, NumberOfPackets);
}


/*
 * @implemented
 */
#undef NdisTransferData
VOID
EXPORT
NdisTransferData(
    OUT     PNDIS_STATUS    Status,
    IN      NDIS_HANDLE     NdisBindingHandle,
    IN      NDIS_HANDLE     MacReceiveContext,
    IN      UINT            ByteOffset,
    IN      UINT            BytesToTransfer,
    IN OUT	PNDIS_PACKET    Packet,
    OUT     PUINT           BytesTransferred)
/*
 * FUNCTION: Forwards a request to copy received data into a protocol-supplied packet
 * ARGUMENTS:
 *     Status            = Address of buffer for status information
 *     NdisBindingHandle = Adapter binding handle
 *     MacReceiveContext = MAC receive context
 *     ByteOffset        = Offset in packet to place data
 *     BytesToTransfer   = Number of bytes to copy into packet
 *     Packet            = Pointer to NDIS packet descriptor
 *     BytesTransferred  = Address of buffer to place number of bytes copied
 */
{
    *Status = ProTransferData(NdisBindingHandle,
                              MacReceiveContext,
                              ByteOffset,
                              BytesToTransfer,
                              Packet,
                              BytesTransferred);
}

/* EOF */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -