📄 filter.c
字号:
PNDIS_RESTART_GENERAL_ATTRIBUTES NdisGeneralAttributes;
PNDIS_RESTART_ATTRIBUTES NdisRestartAttributes;
NDIS_CONFIGURATION_OBJECT ConfigObject;
DEBUGP(DL_TRACE, ("===>FilterRestart: FilterModuleContext %p\n", FilterModuleContext));
FILTER_ASSERT(pFilter->State == FilterPaused);
ConfigObject.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
ConfigObject.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;
ConfigObject.Header.Size = sizeof(NDIS_CONFIGURATION_OBJECT);
ConfigObject.NdisHandle = FilterDriverHandle;
ConfigObject.Flags = 0;
Status = NdisOpenConfigurationEx(&ConfigObject, &ConfigurationHandle);
if (Status != NDIS_STATUS_SUCCESS)
{
//
// Filter driver can choose to fail the restart if it cannot open the configuration
//
#if 0
//
// The code is here just to demonstrate how to call NDIS to write an eventlog. If drivers need to write
// an event log.
//
PWCHAR ErrorString = L"Ndislwf";
DEBUGP(DL_WARN, ("FilterRestart: Cannot open configuration.\n"));
NdisWriteEventLogEntry(FilterDriverObject,
EVENT_NDIS_DRIVER_FAILURE,
0,
1,
&ErrorString,
sizeof(Status),
&Status);
#endif
}
if (Status == NDIS_STATUS_SUCCESS)
{
NdisCloseConfiguration(ConfigurationHandle);
}
NdisRestartAttributes = RestartParameters->RestartAttributes;
//
// If NdisRestartAttributes is not NULL, then miniport can modify generic attributes and add
// new media specific info attributes at the end. Otherwise, NDIS restarts the miniport because
// of other reason, miniport should not try to modify/add attributes
//
if (NdisRestartAttributes != NULL)
{
PNDIS_RESTART_ATTRIBUTES NextAttributes;
ASSERT(NdisRestartAttributes->Oid == OID_GEN_MINIPORT_RESTART_ATTRIBUTES);
NdisGeneralAttributes = (PNDIS_RESTART_GENERAL_ATTRIBUTES)NdisRestartAttributes->Data;
//
// Check to see if we need to change any attributes, for example, the driver can change the current
// MAC address here. Or the driver can add media specific info attributes.
//
NdisGeneralAttributes->LookaheadSize = 128;
//
// Check the next attributes to see whether the filter need to modify
//
NextAttributes = NdisRestartAttributes->Next;
while (NextAttributes != NULL)
{
//
// If somehow the filter needs to change a attributes which requires more space then
// the current attributes:
// 1. Remove the attribute from the Attributes list:
// TempAttributes = NextAttributes;
// NextAttributes = NextAttributes->Next;
// 2. Free the memory for the current attributes: NdisFreeMemory(TempAttributes, 0 , 0);
// 3. Dynamically allocate the memory for the new attributes by calling
// NdisAllocateMemoryWithTagPriority:
// NewAttributes = NdisAllocateMemoryWithTagPriority(Handle, size, Priority);
// 4. Fill in the new attribute
// 5. NewAttributes->Next = NextAttributes;
// 6. NextAttributes = NewAttributes; // Just to make the next statement works.
//
NextAttributes = NextAttributes->Next;
}
//
// Add a new attributes at the end
// 1. Dynamically allocate the memory for the new attributes by calling
// NdisAllocateMemoryWithTagPriority.
// 2. Fill in the new attribute
// 3. NextAttributes->Next = NewAttributes;
// 4. NewAttributes->Next = NULL;
}
//
// If everything is OK, set the filter in running state
// If it get preempted, it doesn't matter
//
pFilter->State = FilterRunning; // when successful
Status = NDIS_STATUS_SUCCESS;
if (Status != NDIS_STATUS_SUCCESS)
{
pFilter->State = FilterPaused;
}
DEBUGP(DL_TRACE, ("<===FilterRestart: FilterModuleContext %p, Status %x\n", FilterModuleContext, Status));
return Status;
}
VOID
FilterDetach(
IN NDIS_HANDLE FilterModuleContext
)
/*++
Routine Description:
Filter detach routine.
This is a required function that will deallocate all the resources allocated during
FitlerAttach. NDIS calls FilterAttachto remove a filter instance from a fitler stack.
Arguments:
FilterModuleContext - pointer to the filter context area.
Return Value:
None.
NOTE: Called at PASSIVE_LEVEL and the filter is in paused state
--*/
{
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
PFL_NDIS_FILTER_LIST pEntry;
PLIST_ENTRY pLink;
DEBUGP(DL_TRACE, ("===>FilterDetach: FilterInstance %p\n", FilterModuleContext));
//
// Filter must be in paused state
//
FILTER_ASSERT(pFilter->State == FilterPaused);
//
// Don't come up anything that would prevent the filter from detaching
//
//
// Free filter instance name if allocated.
//
if (pFilter->FilterName.Buffer != NULL)
{
FILTER_FREE_MEM(pFilter->FilterName.Buffer);
}
FILTER_ACQUIRE_LOCK(&FilterListLock, FALSE);
RemoveEntryList(&pFilter->FilterModuleLink);
FILTER_RELEASE_LOCK(&FilterListLock, FALSE);
//
// Free the memory allocated
FILTER_FREE_MEM(pFilter);
//
// Alway return success
//
DEBUGP(DL_TRACE, ("<===FilterDetach Successfully\n"));
return;
}
VOID
FilterUnload(
IN PDRIVER_OBJECT DriverObject
)
/*++
Routine Description:
Filter driver's unload routine.
Deregister the driver from NDIS
Arguments:
DriverObject - pointer to the system's driver object structure
for this driver
Return Value:
NONE
--*/
{
DEBUGP(DL_TRACE, ("===>FilterUnload\n"));
//
// Should free the filter context list
//
FilterDeregisterDevice();
NdisFDeregisterFilterDriver(FilterDriverHandle);
#if DBG
FILTER_ACQUIRE_LOCK(&FilterListLock, FALSE);
ASSERT(IsListEmpty(&FilterModuleList));
FILTER_RELEASE_LOCK(&FilterListLock, FALSE);
#endif
FILTER_FREE_LOCK(&FilterListLock);
DEBUGP(DL_TRACE, ("<===FilterUnload\n"));
return;
}
NDIS_STATUS
FilterOidRequest(
IN NDIS_HANDLE FilterModuleContext,
IN PNDIS_OID_REQUEST Request
)
/*++
Routine Description:
Request handler
Handle requests from upper layers
Arguments:
FilterModuleContext: Pointer to out filter
Request: Pointer to request passed down
Return Value:
NDIS_STATUS_SUCCESS
NDIS_STATUS_PENDING
NDIS_STATUS_XXX
NOTE: Called at <= DISPATCH_LEVEL
--*/
{
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
NDIS_STATUS Status;
PNDIS_OID_REQUEST ClonedRequest=NULL;
BOOLEAN bSubmitted = FALSE;
PFILTER_REQUEST_CONTEXT Context;
DEBUGP(DL_TRACE, ("===>FilterOidRequest: Request %p.\n", Request));
do
{
Status = NdisAllocateCloneOidRequest(pFilter->FilterHandle,
Request,
FILTER_TAG,
&ClonedRequest);
if (Status != NDIS_STATUS_SUCCESS)
{
DEBUGP(DL_WARN, ("FilerOidRequest: Cannot Clone Request\n"));
break;
}
Context = (PFILTER_REQUEST_CONTEXT)(&ClonedRequest->SourceReserved[0]);
*Context = Request;
bSubmitted = TRUE;
//
// Use same request ID
//
ClonedRequest->RequestId = Request->RequestId;
pFilter->PendingOidRequest = ClonedRequest;
Status = NdisFOidRequest(pFilter->FilterHandle, ClonedRequest);
if (Status != NDIS_STATUS_PENDING)
{
FilterOidRequestComplete(pFilter, ClonedRequest, Status);
Status = NDIS_STATUS_PENDING;
}
}while (FALSE);
if (bSubmitted == FALSE)
{
switch(Request->RequestType)
{
case NdisRequestMethod:
Request->DATA.METHOD_INFORMATION.BytesRead = 0;
Request->DATA.METHOD_INFORMATION.BytesNeeded = 0;
Request->DATA.METHOD_INFORMATION.BytesWritten = 0;
break;
case NdisRequestSetInformation:
Request->DATA.SET_INFORMATION.BytesRead = 0;
Request->DATA.SET_INFORMATION.BytesNeeded = 0;
break;
case NdisRequestQueryInformation:
case NdisRequestQueryStatistics:
default:
Request->DATA.QUERY_INFORMATION.BytesWritten = 0;
Request->DATA.QUERY_INFORMATION.BytesNeeded = 0;
break;
}
}
DEBUGP(DL_TRACE, ("<===FilterOidRequest: Status %8x.\n", Status));
return Status;
}
VOID
FilterCancelOidRequest(
IN NDIS_HANDLE FilterModuleContext,
IN PVOID RequestId
)
{
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
PNDIS_OID_REQUEST Request = NULL;
PFILTER_REQUEST_CONTEXT Context;
PNDIS_OID_REQUEST OriginalRequest = NULL;
FILTER_ACQUIRE_LOCK(&pFilter->Lock, FALSE);
Request = pFilter->PendingOidRequest;
if (Request != NULL)
{
Context = (PFILTER_REQUEST_CONTEXT)(&Request->SourceReserved[0]);
OriginalRequest = (*Context);
}
if ((OriginalRequest != NULL) && (OriginalRequest->RequestId == RequestId))
{
FILTER_RELEASE_LOCK(&pFilter->Lock, FALSE);
NdisFCancelOidRequest(pFilter->FilterHandle, RequestId);
}
else
{
FILTER_RELEASE_LOCK(&pFilter->Lock, FALSE);
}
}
VOID
FilterOidRequestComplete(
IN NDIS_HANDLE FilterModuleContext,
IN PNDIS_OID_REQUEST Request,
IN NDIS_STATUS Status
)
/*++
Routine Description:
Same operation we need to do when outstanding request are completed
Arguments:
FilterModuleContext -- Pointer to the filter context area
NdisRequest - The request to complete
Status - The completion status
Return Value:
NONE
--*/
{
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
PNDIS_OID_REQUEST OriginalRequest;
PFILTER_REQUEST_CONTEXT Context;
DEBUGP(DL_TRACE, ("===>FilterOidRequestComplete, Request %p.\n", Request));
Context = (PFILTER_REQUEST_CONTEXT)(&Request->SourceReserved[0]);
OriginalRequest = (*Context);
//
// This is the internal request
//
if (OriginalRequest == NULL)
{
filterInternalRequestComplete(pFilter, Request, Status);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -