📄 filter.c
字号:
/*++
Copyright (c) 2004-2005 Microsoft Corporation
Module Name:
Filter.c
Abstract:
Sample NDIS Lightweight filter driver
Revision History:
Who When What
-------- -------- ----------------------------------------------
Notes:
--*/
#include "precomp.h"
#define __FILENUMBER 'PNPF'
#pragma NDIS_INIT_FUNCTION(DriverEntry)
//
// Global variables
//
NDIS_HANDLE FilterDriverHandle; // NDIS handle for filter driver
NDIS_HANDLE FilterDriverObject;
NDIS_HANDLE NdisFilterDeviceHandle = NULL;
PDEVICE_OBJECT DeviceObject = NULL;
FILTER_LOCK FilterListLock;
LIST_ENTRY FilterModuleList;
PWCHAR InstanceStrings = NULL;
NDIS_FILTER_PARTIAL_CHARACTERISTICS DefaultChars = {
{ 0, 0, 0},
0,
FilterSendNetBufferLists,
FilterSendNetBufferListsComplete,
NULL,
FilterReceiveNetBufferLists,
FilterReturnNetBufferLists
};
NDIS_STATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
First entry point to be called, when this driver is loaded.
Register with NDIS as a filter driver.
Arguments:
DriverObject - pointer to the system's driver object structure
for this driver
RegistryPath - system's registry path for this driver
Return Value:
STATUS_SUCCESS if all initialization is successful, STATUS_XXX
error code if not.
--*/
{
NDIS_STATUS Status;
NDIS_FILTER_DRIVER_CHARACTERISTICS FChars;
NDIS_STRING ServiceName;
NDIS_STRING UniqueName;
NDIS_STRING FriendlyName;
DEBUGP(DL_TRACE,("===>DriverEntry...\n"));
RtlInitUnicodeString(&ServiceName, FILTER_SERVICE_NAME);
RtlInitUnicodeString(&FriendlyName, FILTER_FRIENDLY_NAME);
RtlInitUnicodeString(&UniqueName, FILTER_UNIQUE_NAME);
FilterDriverObject = DriverObject;
do
{
NdisZeroMemory(&FChars, sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS));
FChars.Header.Type = NDIS_OBJECT_TYPE_FILTER_DRIVER_CHARACTERISTICS;
FChars.Header.Size = sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS);
FChars.Header.Revision = NDIS_FILTER_CHARACTERISTICS_REVISION_1;
FChars.MajorNdisVersion = FILTER_MAJOR_NDIS_VERSION;
FChars.MinorNdisVersion = FILTER_MINOR_NDIS_VERSION;
FChars.MajorDriverVersion = 1;
FChars.MinorDriverVersion = 0;
FChars.Flags = 0;
FChars.FriendlyName = FriendlyName;
FChars.UniqueName = UniqueName;
FChars.ServiceName = ServiceName;
//
// for the time being, there is no additional options to register
// but let's have this handler anyway
//
FChars.SetOptionsHandler = FilterRegisterOptions;
FChars.AttachHandler = FilterAttach;
FChars.DetachHandler = FilterDetach;
FChars.RestartHandler = FilterRestart;
FChars.PauseHandler = FilterPause;
FChars.SetFilterModuleOptionsHandler = FilterSetModuleOptions;
FChars.OidRequestHandler = FilterOidRequest;
FChars.OidRequestCompleteHandler = FilterOidRequestComplete;
FChars.CancelOidRequestHandler = FilterCancelOidRequest;
FChars.SendNetBufferListsHandler = FilterSendNetBufferLists;
FChars.ReturnNetBufferListsHandler = FilterReturnNetBufferLists;
FChars.SendNetBufferListsCompleteHandler = FilterSendNetBufferListsComplete;
FChars.ReceiveNetBufferListsHandler = FilterReceiveNetBufferLists;
FChars.DevicePnPEventNotifyHandler = FilterDevicePnPEventNotify;
FChars.NetPnPEventHandler = FilterNetPnPEvent;
FChars.StatusHandler = FilterStatus;
FChars.CancelSendNetBufferListsHandler = FilterCancelSendNetBufferLists;
DriverObject->DriverUnload = FilterUnload;
FilterDriverHandle = NULL;
FILTER_INIT_LOCK(&FilterListLock);
InitializeListHead(&FilterModuleList);
Status = NdisFRegisterFilterDriver(DriverObject,
(NDIS_HANDLE)FilterDriverObject,
&FChars,
&FilterDriverHandle);
if (Status != NDIS_STATUS_SUCCESS)
{
DEBUGP(DL_WARN, ("MSFilter: Register filter driver failed.\n"));
break;
}
//
// Initilize spin locks
//
Status = FilterRegisterDevice();
if (Status != NDIS_STATUS_SUCCESS)
{
NdisFDeregisterFilterDriver(FilterDriverHandle);
FILTER_FREE_LOCK(&FilterListLock);
DEBUGP(DL_WARN, ("MSFilter: Register device for the filter driver failed.\n"));
break;
}
}
while(FALSE);
DEBUGP(DL_TRACE, ("<===DriverEntry, Status = %8x\n", Status));
return Status;
}
NDIS_STATUS
FilterRegisterOptions(
IN NDIS_HANDLE NdisFilterDriverHandle,
IN NDIS_HANDLE FilterDriverContext
)
{
DEBUGP(DL_TRACE, ("===>FilterRegisterOptions\n"));
ASSERT(NdisFilterDriverHandle == FilterDriverHandle);
ASSERT(FilterDriverContext == (NDIS_HANDLE)FilterDriverObject);
if ((NdisFilterDriverHandle != (NDIS_HANDLE)FilterDriverHandle) ||
(FilterDriverContext != (NDIS_HANDLE)FilterDriverObject))
{
return NDIS_STATUS_INVALID_PARAMETER;
}
DEBUGP(DL_TRACE, ("<===FilterRegisterOptions\n"));
return (NDIS_STATUS_SUCCESS);
}
NDIS_STATUS
FilterAttach(
IN NDIS_HANDLE NdisFilterHandle,
IN NDIS_HANDLE FilterDriverContext,
IN PNDIS_FILTER_ATTACH_PARAMETERS AttachParameters
)
/*++
Routine Description:
Filter attach routine.
Create filter's context, and allocate NetBufferLists and NetBuffers pools and any
other resources, read configuration if needed.
Arguments:
NdisFilterHandle - Specify a handle identifying this instance of the filter. FilterAttach
should save this handle. It is a required parameter in subsequent calls
to NdisFxxx functions.
FilterDriverContext - Filter driver context passed to NdisFRegisterFilterDriver.
AttachParameters - attach parameters
Return Value:
NDIS_STATUS_SUCCESS: FilterAttach successfully allocated and initialize data structures
for this filter instance.
NDIS_STATUS_RESOURCES: FilterAttach failed due to insufficient resources.
NDIS_STATUS_FAILURE: FilterAttach could not set up this instance of this fitler and it has called
NDisWriteErrorLogEntry with parameters spedifying the reason for failure.
NOTE: Called at PASSIVE_LEVEL
FILTER can use NdisRegisterDeviceEx to create a device, so the upper layer can send Irps to the filter.
--*/
{
PMS_FILTER pFilter = NULL;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PFL_NDIS_FILTER_LIST FilterHandleEntry;
NDIS_FILTER_ATTRIBUTES FilterAttributes;
ULONG Size;
DEBUGP(DL_TRACE, ("===>FilterAttach: NdisFilterHandle %p\n", NdisFilterHandle));
do
{
ASSERT(FilterDriverContext == (NDIS_HANDLE)FilterDriverObject);
if (FilterDriverContext != (NDIS_HANDLE)FilterDriverObject)
{
Status = NDIS_STATUS_INVALID_PARAMETER;
break;
}
if ((AttachParameters->MiniportMediaType != NdisMedium802_3)
&& (AttachParameters->MiniportMediaType != NdisMediumWan))
{
DEBUGP(DL_ERROR, ("MSFilter: Doesn't support media type other than NdisMedium802_3.\n"));
Status = NDIS_STATUS_INVALID_PARAMETER;
break;
}
Size = sizeof(MS_FILTER) +
AttachParameters->FilterModuleGuidName->Length +
AttachParameters->BaseMiniportInstanceName->Length +
AttachParameters->BaseMiniportName->Length;
pFilter = (PMS_FILTER)FILTER_ALLOC_MEM(NdisFilterHandle, Size);
if (pFilter == NULL)
{
DEBUGP(DL_WARN, ("MSFilter: Failed to allocate context structure.\n"));
Status = NDIS_STATUS_RESOURCES;
break;
}
NdisZeroMemory(pFilter, sizeof(MS_FILTER));
pFilter->FilterModuleName.Length = pFilter->FilterModuleName.MaximumLength = AttachParameters->FilterModuleGuidName->Length;
pFilter->FilterModuleName.Buffer = (PWSTR)((PUCHAR)pFilter + sizeof(MS_FILTER));
NdisMoveMemory(pFilter->FilterModuleName.Buffer,
AttachParameters->FilterModuleGuidName->Buffer,
pFilter->FilterModuleName.Length);
pFilter->MiniportFriendlyName.Length = pFilter->MiniportFriendlyName.MaximumLength = AttachParameters->BaseMiniportInstanceName->Length;
pFilter->MiniportFriendlyName.Buffer = (PWSTR)((PUCHAR)pFilter->FilterModuleName.Buffer + pFilter->FilterModuleName.Length);
NdisMoveMemory(pFilter->MiniportFriendlyName.Buffer,
AttachParameters->BaseMiniportInstanceName->Buffer,
pFilter->MiniportFriendlyName.Length);
pFilter->MiniportName.Length = pFilter->MiniportName.MaximumLength = AttachParameters->BaseMiniportName->Length;
pFilter->MiniportName.Buffer = (PWSTR)((PUCHAR)pFilter->MiniportFriendlyName.Buffer +
pFilter->MiniportFriendlyName.Length);
NdisMoveMemory(pFilter->MiniportName.Buffer,
AttachParameters->BaseMiniportName->Buffer,
pFilter->MiniportName.Length);
pFilter->MiniportIfIndex = AttachParameters->BaseMiniportIfIndex;
//
// The filter should intialize NoTrackRecieves and NoTrackSends properly, for this
// driver, since its default characteristic has both send and receive handler, they
// are initiazed to FALSE.
//
pFilter->TrackReceives = TRUE;
pFilter->TrackSends = TRUE;
pFilter->FilterHandle = NdisFilterHandle;
NdisZeroMemory(&FilterAttributes, sizeof(NDIS_FILTER_ATTRIBUTES));
FilterAttributes.Header.Revision = NDIS_FILTER_ATTRIBUTES_REVISION_1;
FilterAttributes.Header.Size = sizeof(NDIS_FILTER_ATTRIBUTES);
FilterAttributes.Header.Type = NDIS_OBJECT_TYPE_FILTER_ATTRIBUTES;
FilterAttributes.Flags = 0;
Status = NdisFSetAttributes(NdisFilterHandle,
pFilter,
&FilterAttributes);
if (Status != NDIS_STATUS_SUCCESS)
{
DEBUGP(DL_WARN, ("MSFilter: Failed to set attributes.\n"));
break;
}
pFilter->State = FilterPaused;
FILTER_ACQUIRE_LOCK(&FilterListLock, FALSE);
InsertHeadList(&FilterModuleList, &pFilter->FilterModuleLink);
FILTER_RELEASE_LOCK(&FilterListLock, FALSE);
}
while (FALSE);
if (Status != NDIS_STATUS_SUCCESS)
{
if (pFilter != NULL)
{
FILTER_FREE_MEM(pFilter);
}
}
DEBUGP(DL_TRACE, ("<===FilterAttach: Status %x\n", Status));
return Status;
}
NDIS_STATUS
FilterPause(
IN NDIS_HANDLE FilterModuleContext,
IN PNDIS_FILTER_PAUSE_PARAMETERS PauseParameters
)
/*++
Routine Description:
Filter pause routine.
Complete all the outstanding sends and queued sends,
Waiting for all the outstanding recvs to be returned
and return all the queued receives
Arguments:
FilterModuleContext - pointer to the filter context stucture.
Return Value:
STATUS_SUCCESS if filter pauses successful, STATUS_PENDING
if not.
NOTE: when the filter is in pause state, it can still process requests, complete sending,
and returning packets to the lower filter, and also indicate status.
Called at PASSIVE_LEVEL
--*/
{
PMS_FILTER pFilter = (PMS_FILTER)(FilterModuleContext);
NDIS_STATUS Status;
UNREFERENCED_PARAMETER(PauseParameters);
DEBUGP(DL_TRACE, ("===>NDISLWF FilterPause: FilterInstance %p\n", FilterModuleContext));
//
// Set the flag that the filter is going to pause
//
FILTER_ASSERT(pFilter->State == FilterRunning);
FILTER_ACQUIRE_LOCK(&pFilter->Lock, FALSE);
pFilter->State = FilterPausing;
FILTER_RELEASE_LOCK(&pFilter->Lock, FALSE);
Status = NDIS_STATUS_SUCCESS;
pFilter->State = FilterPaused;
DEBUGP(DL_TRACE, ("<===FilterPause: Status %x\n", Status));
return Status;
}
NDIS_STATUS
FilterRestart(
IN NDIS_HANDLE FilterModuleContext,
IN PNDIS_FILTER_RESTART_PARAMETERS RestartParameters
)
/*++
Routine Description:
Filter restart routine.
Restart the filter
Arguments:
FilterModuleContext - pointer to the filter context stucture.
Return Value:
NDIS_STATUS_SUCCESS: if filter restarts successfully
NDIS_STATUS_XXX: Otherwise.
NOTE: called at PASSIVE_LEVEL
--*/
{
NDIS_STATUS Status;
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext; // BUGBUG, the cast may be wrong
NDIS_HANDLE ConfigurationHandle = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -