📄 openclos.c
字号:
VOID
NPF_CloseOpenInstance(POPEN_INSTANCE pOpen)
{
PKEVENT pEvent;
UINT i;
TRACE_ENTER();
ASSERT(pOpen != NULL);
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Open= %p", pOpen);
NdisFreePacketPool(pOpen->PacketPool);
//
// free mem_ex
//
pOpen->mem_ex.size = 0;
if(pOpen->mem_ex.buffer != NULL)
ExFreePool(pOpen->mem_ex.buffer);
//
// Free the filter if it's present
//
if(pOpen->bpfprogram != NULL)
ExFreePool(pOpen->bpfprogram);
//
// Jitted filters are supported on x86 (32bit) only
//
#ifdef __NPF_x86__
// Free the jitted filter if it's present
if(pOpen->Filter != NULL)
BPF_Destroy_JIT_Filter(pOpen->Filter);
#endif
//
// Dereference the read event.
//
if (pOpen->ReadEvent != NULL)
ObDereferenceObject(pOpen->ReadEvent);
//
// free the buffer
// NOTE: the buffer is fragmented among the various CPUs, but the base pointer of the
// allocated chunk of memory is stored in the first slot (pOpen->CpuData[0])
//
if (pOpen->Size > 0)
ExFreePool(pOpen->CpuData[0].Buffer);
//
// free the per CPU spinlocks
//
for (i = 0; i < NCpu; i++)
{
NdisFreeSpinLock(&Open->CpuData[i].BufferLock);
}
//
// Free the string with the name of the dump file
//
if(pOpen->DumpFileName.Buffer!=NULL)
ExFreePool(pOpen->DumpFileName.Buffer);
//
// Free the open instance itself
//
ExFreePool(pOpen);
TRACE_EXIT();
}
//-------------------------------------------------------------------
VOID NPF_OpenAdapterComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status,
IN NDIS_STATUS OpenErrorStatus)
{
POPEN_INSTANCE Open;
PLIST_ENTRY RequestListEntry;
PINTERNAL_REQUEST MaxSizeReq;
NDIS_STATUS ReqStatus;
TRACE_ENTER();
Open = (POPEN_INSTANCE)ProtocolBindingContext;
ASSERT(Open != NULL);
if (Status != NDIS_STATUS_SUCCESS)
{
//
// this is not completely correct, as we are converting an NDIS_STATUS to a NTSTATUS
//
Open->OpenCloseStatus = Status;
}
else
{
Open->OpenCloseStatus = STATUS_SUCCESS;
}
//
// wake up the caller of NdisOpen, that is NPF_Open
//
NdisSetEvent(&Open->NdisOpenCloseCompleteEvent);
TRACE_EXIT();
}
NTSTATUS
NPF_GetDeviceMTU(
IN POPEN_INSTANCE pOpen,
IN PIRP pIrp,
OUT PUINT pMtu)
{
PLIST_ENTRY RequestListEntry;
PINTERNAL_REQUEST MaxSizeReq;
NDIS_STATUS ReqStatus;
TRACE_ENTER();
ASSERT(pOpen != NULL);
ASSERT(pIrp != NULL);
ASSERT(pMtu != NULL);
// Extract a request from the list of free ones
RequestListEntry = ExInterlockedRemoveHeadList(&pOpen->RequestList, &pOpen->RequestSpinLock);
if (RequestListEntry == NULL)
{
//
// THIS IS WRONG
//
//
// Assume Ethernet
//
*pMtu = 1514;
TRACE_EXIT();
return STATUS_SUCCESS;
}
MaxSizeReq = CONTAINING_RECORD(RequestListEntry, INTERNAL_REQUEST, ListElement);
MaxSizeReq->Request.RequestType = NdisRequestQueryInformation;
MaxSizeReq->Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAXIMUM_TOTAL_SIZE;
MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBuffer = pMtu;
MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(*pMtu);
NdisResetEvent(&MaxSizeReq->InternalRequestCompletedEvent);
// submit the request
NdisRequest(
&ReqStatus,
pOpen->AdapterHandle,
&MaxSizeReq->Request);
if (ReqStatus == NDIS_STATUS_PENDING)
{
NdisWaitEvent(&MaxSizeReq->InternalRequestCompletedEvent, 0);
ReqStatus = MaxSizeReq->RequestStatus;
}
//
// Put the request in the list of the free ones
//
ExInterlockedInsertTailList(&pOpen->RequestList, &MaxSizeReq->ListElement, &pOpen->RequestSpinLock);
if (ReqStatus == NDIS_STATUS_SUCCESS)
{
TRACE_EXIT();
return STATUS_SUCCESS;
}
else
{
//
// THIS IS WRONG
//
//
// Assume Ethernet
//
*pMtu = 1514;
TRACE_EXIT();
return STATUS_SUCCESS;
// return ReqStatus;
}
}
//-------------------------------------------------------------------
NTSTATUS
NPF_Close(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
TRACE_ENTER();
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
TRACE_EXIT();
return STATUS_SUCCESS;
}
//-------------------------------------------------------------------
NTSTATUS
NPF_Cleanup(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
POPEN_INSTANCE Open;
NDIS_STATUS Status;
PIO_STACK_LOCATION IrpSp;
LARGE_INTEGER ThreadDelay;
ULONG localNumOpenInstances;
TRACE_ENTER();
IrpSp = IoGetCurrentIrpStackLocation(Irp);
Open = IrpSp->FileObject->FsContext;
TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Open = %p\n", Open);
ASSERT(Open != NULL);
if (Open->ReadEvent != NULL)
KeSetEvent(Open->ReadEvent,0,FALSE);
NPF_CloseBinding(Open);
// NOTE:
// code commented out because the kernel dump feature is disabled
//
//if (AdapterAlreadyClosing == FALSE)
//{
//
// Unfreeze the consumer
//
// if(Open->mode & MODE_DUMP)
// NdisSetEvent(&Open->DumpEvent);
// else
// KeSetEvent(Open->ReadEvent,0,FALSE);
// //
// // If this instance is in dump mode, complete the dump and close the file
// //
// if((Open->mode & MODE_DUMP) && Open->DumpFileHandle != NULL)
// {
// NTSTATUS wres;
// ThreadDelay.QuadPart = -50000000;
// //
// // Wait the completion of the thread
// //
// wres = KeWaitForSingleObject(Open->DumpThreadObject,
// UserRequest,
// KernelMode,
// TRUE,
// &ThreadDelay);
// ObDereferenceObject(Open->DumpThreadObject);
// //
// // Flush and close the dump file
// //
// NPF_CloseDumpFile(Open);
// }
//}
//
// release all the resources
//
NPF_CloseOpenInstance(Open);
IrpSp->FileObject->FsContext = NULL;
//
// Decrease the counter of open instances
//
localNumOpenInstances = InterlockedDecrement(&g_NumOpenedInstances);
TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Opened Instances: %u", localNumOpenInstances);
if(localNumOpenInstances == 0)
{
//
// Force a synchronization at the next NPF_Open().
// This hopefully avoids the synchronization issues caused by hibernation or standby.
//
TIME_DESYNCHRONIZE(&G_Start_Time);
}
//
// and complete the IRP with status success
//
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
TRACE_EXIT();
return(STATUS_SUCCESS);
}
//-------------------------------------------------------------------
VOID
NPF_CloseAdapterComplete(IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_STATUS Status)
{
POPEN_INSTANCE Open;
PIRP Irp;
TRACE_ENTER();
Open = (POPEN_INSTANCE)ProtocolBindingContext;
ASSERT(Open != NULL);
TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Open= %p", Open);
NdisSetEvent(&Open->NdisOpenCloseCompleteEvent);
TRACE_EXIT();
return;
}
//-------------------------------------------------------------------
#ifdef NDIS50
NDIS_STATUS
NPF_PowerChange(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent)
{
TRACE_ENTER();
TIME_DESYNCHRONIZE(&G_Start_Time);
TIME_SYNCHRONIZE(&G_Start_Time);
TRACE_EXIT();
return STATUS_SUCCESS;
}
#endif
//-------------------------------------------------------------------
VOID
NPF_BindAdapter(
OUT PNDIS_STATUS Status,
IN NDIS_HANDLE BindContext,
IN PNDIS_STRING DeviceName,
IN PVOID SystemSpecific1,
IN PVOID SystemSpecific2
)
{
TRACE_ENTER();
TRACE_EXIT();
}
//-------------------------------------------------------------------
VOID
NPF_UnbindAdapter(
OUT PNDIS_STATUS Status,
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_HANDLE UnbindContext
)
{
POPEN_INSTANCE Open =(POPEN_INSTANCE)ProtocolBindingContext;
TRACE_ENTER();
ASSERT(Open != NULL);
//
// The following code has been disabled bcause the kernel dump feature has been disabled.
//
////
//// Awake a possible pending read on this instance
//// TODO should be ok.
////
// if(Open->mode & MODE_DUMP)
// NdisSetEvent(&Open->DumpEvent);
// else
if (Open->ReadEvent != NULL)
KeSetEvent(Open->ReadEvent,0,FALSE);
//
// The following code has been disabled bcause the kernel dump feature has been disabled.
//
////
//// If this instance is in dump mode, complete the dump and close the file
//// TODO needs to be checked again.
////
// if((Open->mode & MODE_DUMP) && Open->DumpFileHandle != NULL)
// NPF_CloseDumpFile(Open);
*Status = NDIS_STATUS_SUCCESS;
NPF_CloseBinding(Open);
TRACE_EXIT();
return;
}
//-------------------------------------------------------------------
VOID
NPF_ResetComplete(IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_STATUS Status)
{
POPEN_INSTANCE Open;
PIRP Irp;
PLIST_ENTRY ResetListEntry;
TRACE_ENTER();
Open = (POPEN_INSTANCE)ProtocolBindingContext;
//
// remove the reset IRP from the list
//
ResetListEntry=ExInterlockedRemoveHeadList(
&Open->ResetIrpList,
&Open->RequestSpinLock
);
Irp=CONTAINING_RECORD(ResetListEntry,IRP,Tail.Overlay.ListEntry);
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
TRACE_EXIT();
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -