📄 packet.c
字号:
//
// buffer too small
//
SET_FAILURE_BUFFER_SMALL();
break;
}
if (Status == NDIS_STATUS_PENDING)
{
NdisWaitEvent(&pRequest->InternalRequestCompletedEvent, 0);
Status = pRequest->RequestStatus;
}
//
// Release ownership of the Ndis Handle
//
NPF_StopUsingBinding(Open);
//
// Complete the request
//
if (FunctionCode == BIOCSETOID)
{
OidData->Length = pRequest->Request.DATA.SET_INFORMATION.BytesRead;
TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "BIOCSETOID completed, BytesRead = %u",OidData->Length);
}
else
{
if (FunctionCode == BIOCQUERYOID)
{
OidData->Length = pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten;
if (Status == NDIS_STATUS_SUCCESS)
{
//
// check for the stupid bug of the Nortel driver ipsecw2k.sys v. 4.10.0.0 that doesn't set the BytesWritten correctly
// The driver is the one shipped with Nortel client Contivity VPN Client V04_65.18, and the MD5 for the buggy (unsigned) driver
// is 3c2ff8886976214959db7d7ffaefe724 *ipsecw2k.sys (there are multiple copies of this binary with the same exact version info!)
//
// The (certified) driver shipped with Nortel client Contivity VPN Client V04_65.320 doesn't seem affected by the bug.
//
if (pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten > pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength)
{
TRACE_MESSAGE2(PACKET_DEBUG_LOUD, "Bogus return from NdisRequest (query): Bytes Written (%u) > InfoBufferLength (%u)!!",
pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten,
pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength);
Status = NDIS_STATUS_INVALID_DATA;
}
}
TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "BIOCQUERYOID completed, BytesWritten = %u",OidData->Length);
}
}
ExInterlockedInsertTailList(
&Open->RequestList,
&pRequest->ListElement,
&Open->RequestSpinLock);
if (Status == NDIS_STATUS_SUCCESS)
{
SET_RESULT_SUCCESS(sizeof(PACKET_OID_DATA) - 1 + OidData->Length);
}
else
{
SET_FAILURE_INVALID_REQUEST();
}
break;
default:
TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Unknown IOCTL code");
SET_FAILURE_INVALID_REQUEST();
break;
}
//
// complete the IRP
//
Irp->IoStatus.Information = Information;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
TRACE_EXIT();
return Status;
}
//-------------------------------------------------------------------
VOID
NPF_RequestComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_REQUEST NdisRequest,
IN NDIS_STATUS Status
)
{
PINTERNAL_REQUEST pRequest;
TRACE_ENTER();
pRequest = CONTAINING_RECORD(NdisRequest,INTERNAL_REQUEST,Request);
//
// Set the request result
//
pRequest->RequestStatus = Status;
//
// and awake the caller
//
NdisSetEvent(&pRequest->InternalRequestCompletedEvent);
TRACE_EXIT();
return;
}
//-------------------------------------------------------------------
VOID
NPF_Status(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status,
IN PVOID StatusBuffer,
IN UINT StatusBufferSize
)
{
IF_LOUD(DbgPrint("NPF: Status Indication\n");)
return;
}
//-------------------------------------------------------------------
VOID
NPF_StatusComplete(
IN NDIS_HANDLE ProtocolBindingContext
)
{
IF_LOUD(DbgPrint("NPF: StatusIndicationComplete\n");)
return;
}
//-------------------------------------------------------------------
NTSTATUS
NPF_ReadRegistry(
IN PWSTR *MacDriverName,
IN PWSTR *PacketDriverName,
IN PUNICODE_STRING RegistryPath
)
{
NTSTATUS Status;
RTL_QUERY_REGISTRY_TABLE ParamTable[4];
PWSTR Bind = L"Bind";
PWSTR Export = L"Export";
PWSTR Parameters = L"Parameters";
PWSTR Linkage = L"Linkage";
PWCHAR Path;
Path=ExAllocatePoolWithTag(PagedPool, RegistryPath->Length+sizeof(WCHAR), '7PWA');
if (Path == NULL) {
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(
Path,
RegistryPath->Length+sizeof(WCHAR)
);
RtlCopyMemory(
Path,
RegistryPath->Buffer,
RegistryPath->Length
);
IF_LOUD(DbgPrint("NPF: Reg path is %ws\n",RegistryPath->Buffer);)
RtlZeroMemory(
ParamTable,
sizeof(ParamTable)
);
//
// change to the linkage key
//
ParamTable[0].QueryRoutine = NULL;
ParamTable[0].Flags = RTL_QUERY_REGISTRY_SUBKEY;
ParamTable[0].Name = Linkage;
//
// Get the name of the mac driver we should bind to
//
ParamTable[1].QueryRoutine = NPF_QueryRegistryRoutine;
ParamTable[1].Flags = RTL_QUERY_REGISTRY_REQUIRED |
RTL_QUERY_REGISTRY_NOEXPAND;
ParamTable[1].Name = Bind;
ParamTable[1].EntryContext = (PVOID)MacDriverName;
ParamTable[1].DefaultType = REG_MULTI_SZ;
//
// Get the name that we should use for the driver object
//
ParamTable[2].QueryRoutine = NPF_QueryRegistryRoutine;
ParamTable[2].Flags = RTL_QUERY_REGISTRY_REQUIRED |
RTL_QUERY_REGISTRY_NOEXPAND;
ParamTable[2].Name = Export;
ParamTable[2].EntryContext = (PVOID)PacketDriverName;
ParamTable[2].DefaultType = REG_MULTI_SZ;
Status=RtlQueryRegistryValues(
RTL_REGISTRY_ABSOLUTE,
Path,
ParamTable,
NULL,
NULL
);
ExFreePool(Path);
return Status;
}
//-------------------------------------------------------------------
NTSTATUS
NPF_QueryRegistryRoutine(
IN PWSTR ValueName,
IN ULONG ValueType,
IN PVOID ValueData,
IN ULONG ValueLength,
IN PVOID Context,
IN PVOID EntryContext
)
{
PUCHAR Buffer;
IF_LOUD(DbgPrint("Perf: QueryRegistryRoutine\n");)
if (ValueType != REG_MULTI_SZ) {
return STATUS_OBJECT_NAME_NOT_FOUND;
}
Buffer=ExAllocatePoolWithTag(NonPagedPool, ValueLength, '8PWA');
if (Buffer==NULL) {
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyMemory(
Buffer,
ValueData,
ValueLength
);
*((PUCHAR *)EntryContext)=Buffer;
return STATUS_SUCCESS;
}
VOID NPF_ResetBufferContents(POPEN_INSTANCE Open)
{
UINT i;
//
// lock all the buffers
//
for (i = 0 ; i < NCpu ; i++)
{
//#pragma prefast(suppress:8103, "There's no Spinlock leak here, as it's released some lines below.")
NdisAcquireSpinLock(&Open->CpuData[i].BufferLock);
}
Open->ReaderSN = 0;
Open->WriterSN = 0;
//
// reset their pointers
//
for (i = 0 ; i < NCpu ; i++)
{
Open->CpuData[i].C=0;
Open->CpuData[i].P=0;
Open->CpuData[i].Free = Open->Size;
Open->CpuData[i].Accepted = 0;
Open->CpuData[i].Dropped = 0;
Open->CpuData[i].Received = 0;
}
//
// release the locks in reverse order
//
i = NCpu;
do
{
i--;
#pragma prefast(suppress:8107, "There's no Spinlock leak here, as it's allocated some lines above.")
NdisReleaseSpinLock(&Open->CpuData[i].BufferLock);
}
while (i != 0);
}
#if 0
//
// Old registry based WinPcap names
//
//-------------------------------------------------------------------
//NOTE: ValueLen is the length of Value in characters
VOID NPF_QueryWinpcapRegistryString(PWSTR SubKeyName,
WCHAR *Value,
UINT ValueLen,
WCHAR *DefaultValue)
{
UINT CharsToCopy;
#ifdef WPCAP_OEM
OBJECT_ATTRIBUTES objAttrs;
NTSTATUS status;
HANDLE keyHandle;
UNICODE_STRING SubKeyToQueryU;
CHAR kvpiBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(WCHAR) * MAX_WINPCAP_KEY_CHARS];
ULONG QvkResultLength;
PKEY_VALUE_PARTIAL_INFORMATION pKeyValuePartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION)kvpiBuffer;
PWCHAR pResultingKeyValue;
//
// Create subkey string
//
RtlInitUnicodeString(&SubKeyToQueryU, SubKeyName);
//
// Init Attributes
//
InitializeObjectAttributes(&objAttrs,
&g_WinpcapGlobalKey,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
//
// Open the key
//
status = ZwOpenKey(&keyHandle,
KEY_QUERY_VALUE,
&objAttrs);
if(!NT_SUCCESS(status))
{
IF_LOUD(DbgPrint("NPF_QueryWinpcapRegistryKey: ZwOpenKey error %x\n", status);)
//copy the default value and return
CharsToCopy = wcslen(DefaultValue) + 1;
if (CharsToCopy > ValueLen)
{
RtlCopyMemory(Value, DefaultValue, ValueLen * 2);
Value[ValueLen - 1] = 0;
}
else
{
RtlCopyMemory(Value, DefaultValue, CharsToCopy * 2);
}
return;
}
//
// Query the requested value
//
status = ZwQueryValueKey(keyHandle,
&SubKeyToQueryU,
KeyValuePartialInformation,
pKeyValuePartialInformation,
sizeof(kvpiBuffer),
&QvkResultLength);
if(!NT_SUCCESS(status))
{
IF_LOUD(DbgPrint("NPF_QueryWinpcapRegistryKey: Status of %x querying key value %ws\n",
status,
SubKeyToQueryU.Buffer);)
ZwClose(keyHandle);
//copy the default value and return
CharsToCopy = wcslen(DefaultValue) + 1;
if (CharsToCopy > ValueLen)
{
RtlCopyMemory(Value, DefaultValue, ValueLen * 2);
Value[ValueLen - 1] = 0;
}
else
{
RtlCopyMemory(Value, DefaultValue, CharsToCopy * 2);
}
return;
}
//
// Check that the resulting value is of the correct type
//
if (pKeyValuePartialInformation->Type != REG_SZ)
{
IF_LOUD(DbgPrint("NPF_QueryWinpcapRegistryKey: the reg key has the wrong type (%u)\n", pKeyValuePartialInformation->Type);)
ZwClose(keyHandle);
//copy the default value and return
CharsToCopy = wcslen(DefaultValue) + 1;
if (CharsToCopy > ValueLen)
{
RtlCopyMemory(Value, DefaultValue, ValueLen * 2);
Value[ValueLen - 1] = 0;
}
else
{
RtlCopyMemory(Value, DefaultValue, CharsToCopy * 2);
}
return;
}
pResultingKeyValue = (PWCHAR)pKeyValuePartialInformation->Data;
//
// Check we have enough space for the result. We include 1 to account for the UNICODE NULL terminator
//
if(wcslen(pResultingKeyValue) + 1 > ValueLen)
{
IF_LOUD(DbgPrint("NPF_QueryWinpcapRegistryKey: storage buffer too small\n");)
ZwClose(keyHandle);
//copy the default value and return
CharsToCopy = wcslen(DefaultValue) + 1;
if (CharsToCopy > ValueLen)
{
RtlCopyMemory(Value, DefaultValue, ValueLen * 2);
Value[ValueLen - 1] = 0;
}
else
{
RtlCopyMemory(Value, DefaultValue, CharsToCopy * 2);
}
return;
}
//
// Copy the value to the user-provided values
//
wcscpy(Value, pResultingKeyValue);
//
// Free the key
//
ZwClose(keyHandle);
return;
#else // WPCAP_OEM
//copy the default value and return
CharsToCopy = wcslen(DefaultValue) + 1;
if (CharsToCopy > ValueLen)
{
RtlCopyMemory(Value, DefaultValue, ValueLen * 2);
Value[ValueLen - 1] = 0;
}
else
{
RtlCopyMemory(Value, DefaultValue, CharsToCopy * 2);
}
return;
#endif // WPCAP_OEM
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -