📄 protocol.c
字号:
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 + -