⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 openclos.c

📁 Windows XP下的抓包程序实现
💻 C
📖 第 1 页 / 共 2 页
字号:

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 + -