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

📄 vdevadap.cpp

📁 驱动设计文档
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// VdevAdap.cpp: implementation of the VdevAdapter class.
//
//=============================================================================
//
// Compuware Corporation
// NuMega Lab
// 9 Townsend West
// Nashua, NH 03060  USA
//
// Copyright (c) 2001 Compuware Corporation. All Rights Reserved.
// Unpublished - rights reserved under the Copyright laws of the
// United States.
//
//=============================================================================
//////////////////////////////////////////////////////////////////////

#include "VdevAdap.h"


KNdisDebugTrace T("VDEV");

#define		SENDBUFLENGMAX	1518
unsigned char NicSendDataBuf[SENDBUFLENGMAX];
unsigned int NicSendDataBufLength;
KMutex	RWBufMutex;
////////////////
//定义写的相关变量
NDIS_HANDLE PacketPoolHandle;
int pphflag;

NDIS_HANDLE BufferPoolHandle;
int bphflag;

#define	MAX_PACKET_LENGTH	1700

////////
NDIS_HANDLE pMiniHandle;
///////////////////////////
VdevAdapter *pThisVdevAdapter;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction	
//////////////////////////////////////////////////////////////////////

VdevAdapter::VdevAdapter() :
	KNdisMiniAdapter(), m_DeviceHandle(NULL)

{
	// TODO: initialize your private data members
	//       Do NOT call any NDIS functions in here. Defer to Initialize()
}

VdevAdapter::~VdevAdapter()
{
	// TODO: deallocate all the resources allocated in constructor/Initialize()

}

////////////////////////////////////////////////////////////////////
// NDIS callback handlers
////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////
// VdevAdapter::Initialize
//
// MiniportInitialize is a required function that sets up a NIC (or 
// virtual NIC) for network I/O operations, claims all hardware resources
// necessary to the NIC in the registry, and allocates resources the driver
// needs to carry out network I/O operations
//
// Parameters:
//		Medium	
//			Reference to KNdisMedium object that we have to set the medium 
//			type our NIC supports
//		Config
//			Reference to KNdisConfig object that we use to query various
//			configuration parameters
// IRQL: 
//		PASSIVE_LEVEL
// Return Mode:
//		Synchronous
//
// TODO: 
// 1) Select supported medium in Medium object
// 2) Read config parameters if any using Config object
// 3) Allocate h/w resources, pools, etc.
// 4) Register with NDIS using SetAttributes()
// 5) Register Shutdown Handler
// 6) Initialize and enable the NIC.
// NOTE: Be ready to process INTs even before the function exits
//
NDIS_STATUS VdevAdapter::Initialize
				(IN OUT KNdisMedium& Medium, IN KNdisConfig& Config)
{
	T.Trace("VdevAdapter::Initialize() Entered\n");
	
	// Select our the Medium:

	if (! Medium.Select(VDEV_MEDIUM_TYPE) )
		KNDIS_RETURN_ERROR (NDIS_STATUS_UNSUPPORTED_MEDIA);

	// Get network address (if any) from the Registry. If specified
	// it will be used instead of burned permanent address:

	if (Config.ReadNetworkAddress(m_CurrentAddress) != NDIS_STATUS_SUCCESS)
	{
		
		m_CurrentAddress.Invalidate();
	}

	//m_CurrentAddress.m_bytes[0] = 0x2; 
	// Read some other config stuff from the Registry, e.g.

	ULONG	uMode;
	Config.Read(KNDIS_STRING_CONST("Mode"), &uMode);

	
    // Now let NDIS know about the BUS the NIC is on. Here's where the NDIS/Adapter-instance
	// handshake takes place. This should happen *before* allocating the h/w resources:
	SetAttributesEx(NdisInterfaceInternal,
		NDIS_ATTRIBUTE_DESERIALIZE);

	// Creating "Upper" Device


	// 1) Fill in the dispatch table
    static PDRIVER_DISPATCH MajorFunctions[IRP_MJ_MAXIMUM_FUNCTION + 1];
	NdisZeroMemory(MajorFunctions, sizeof(MajorFunctions));
    MajorFunctions[IRP_MJ_CREATE] = IoCreate;
    MajorFunctions[IRP_MJ_CLOSE] = IoClose;
    MajorFunctions[IRP_MJ_CLEANUP] = IoCleanup;
    MajorFunctions[IRP_MJ_READ] = IoRead;
    MajorFunctions[IRP_MJ_WRITE] = IoWrite;
    MajorFunctions[IRP_MJ_DEVICE_CONTROL] = IoDispatch;

	NDIS_STATUS  Status = NdisMRegisterDevice(
					*KNdisMiniDriver::DriverInstance(),
					KNDIS_STRING_CONST("\\Device\\MyNdisDevice"),
					KNDIS_STRING_CONST("\\DosDevices\\MyNdisDevice"),
					MajorFunctions,
					&m_pDeviceObject,
					&m_DeviceHandle);

	T.Trace("VdevAdapter Create Device: %s\n", ((Status)?"FAILED":"OK"));

	// TODO: Read perm address from the card instead
	m_PermanentAddress = m_CurrentAddress;

	// Set default filter and MAC options. In principle, we should ralso
	// relay that to our card...
	m_uPacketFilter = NDIS_PACKET_TYPE_DIRECTED |
					  NDIS_PACKET_TYPE_MULTICAST |
					  NDIS_PACKET_TYPE_BROADCAST;

	m_uMacOptions = NDIS_MAC_OPTION_TRANSFERS_NOT_PEND  |
				    NDIS_MAC_OPTION_RECEIVE_SERIALIZED  |
					NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
					NDIS_MAC_OPTION_NO_LOOPBACK;


	// TODO:	Start the card up. 

	RWBufMutex.Initialize(1);

/////////////////////////
	
	pMiniHandle = m_DeviceHandle;

////////////////
	NDIS_STATUS	NStatus;
	
	PacketPoolHandle = NULL;
	
	NdisAllocatePacketPool( &NStatus, &PacketPoolHandle, 16, MAX_PACKET_LENGTH );
	if( NStatus != NDIS_STATUS_SUCCESS ) 
	{
		pphflag = -1;
	} 
	else
	{
		pphflag = 1;
	}
	
	BufferPoolHandle = NULL;
	NdisAllocateBufferPool(&NStatus,&BufferPoolHandle,24);
	if( NStatus != NDIS_STATUS_SUCCESS ) 
	{
		bphflag = -1;
	} 
	else
	{
		bphflag = 1;
	}
	
/////////////////////////
	pThisVdevAdapter = this;
////////////////////////
	return NDIS_STATUS_SUCCESS;
}

////////////////////////////////////////////////////////////////////
// VdevAdapter::Halt
//
// MiniportHalt is a required function that deallocates resources when
// the NIC is removed and halts the NIC.
//
// Parameters:
//		None
// IRQL: 
//		PASSIVE_LEVEL
// Return Mode:
//		Synchronous
//
// NOTE: Miniports has no "unload" for the driver. The Halt() is the last
//       function called into a miniport, so everything should be stopped 
//		 and freed right here. The KNDIS framework takes care of destroying
//		 the adapter object itself, so this member function is merery required
//       to undo things done by the Initialize() above - in the inversed order.
//
//		 Alternatevely, the driver writer can move all the deallocations to the
//       destructor: the destructor will be called immediatelly after Halt() 
//		 returns. Our sample follows this practice.
//
VOID VdevAdapter::Halt(VOID)
{
	T.Trace("VdevAdapter::Halt() Entered\n");

	if (bphflag == 1)
		NdisFreeBufferPool(BufferPoolHandle); 	

	if (pphflag == 1)
		NdisFreePacketPool(PacketPoolHandle);

	if (m_DeviceHandle)
		NdisMDeregisterDevice(m_DeviceHandle);
	

}

////////////////////////////////////////////////////////////////////
// VdevAdapter::Reset
//
// MiniportReset is a required function that issues a hardware reset
// to the NIC and/or resets the driver's software state.
//
// Parameters:
//		AddressingReset
//			Points to a variable that MiniportReset sets to TRUE if the
//			NDIS library should call MiniportSetInformation to restore
//			addressing information to the current values.
// IRQL: 
//		DISPATCH_LEVEL
// Return Mode:
//		Asynchronous
NDIS_STATUS VdevAdapter::Reset
			(OUT PBOOLEAN AddressingReset)
{
	T.Trace("VdevAdapter::Reset() Entered\n");
	// TODO:	Reset the card

	return NDIS_STATUS_SUCCESS;
}
	
////////////////////////////////////////////////////////////////////
// VdevAdapter::Shutdown
//
// MiniportShutdown does nothing more than restore the NIC to its 
// initial state (before the miniport's DriverEntry function runs)
//
// Parameters:
//		None
// IRQL: 
//		If MiniportShutdown is called due to a user-initiated system shutdown,
//		it runs at IRQL PASSIVE_LEVEL in a system-thread context. If it is called
//		due to an unrecoverable error, MiniportShutdown runs at an arbitrary IRQL
//		and in the context of whatever component raised the error. 
// Return Mode:
//		Synchronous
VOID VdevAdapter::Shutdown(VOID)
{
	T.Trace("VdevAdapter::Shutdown() Entered\n");


	// TODO:	Reset the card for good
}


void CopyPacket2Buffer(IN PNDIS_PACKET pPacket,IN OUT PUCHAR pBuff,IN OUT PUINT pLength)
{
	PNDIS_BUFFER BuffDT;
	PVOID BuffVA;
	UINT BuffLen;
	
	*pLength = 0;
	BuffLen = 0;
	
	NdisQueryPacket(pPacket,NULL,NULL,&BuffDT,NULL);
	
	while(BuffDT != (PNDIS_BUFFER)NULL)
	{
		NdisQueryBuffer(BuffDT,&BuffVA,&BuffLen);
		NdisMoveMemory(pBuff,BuffVA,BuffLen);

		pBuff = pBuff + BuffLen;
		*pLength += BuffLen;

		NdisGetNextBuffer(BuffDT,&BuffDT);
	}
	return; 
}
////////////////////////////////////////////////////////////////////
// VdevAdapter::Send
//
// Transfers a protocol-supplied packet over the network
//
// Parameters:
//		Packet 
//			Points to a packet descriptor specifying the data to be transmitted. 
//		Flags 
//			Specifies the packet flags, if any, set by the protocol. 
// IRQL: 
//		DISPATCH_LEVEL
// Return Mode:
//		Asynchronous
// NOTE:
//		The return code determines the ownership of the packet and further
//		interaction between NDIS and our driver. Specifically,
//
//      NDIS_STATUS_SUCCESS - Done with.
//      NDIS_STATUS_PENDING - We keep it until further notice.
//      NDIS_STATUS_RESOURCES - We didn't have the resouces *now*, so tell NDIS
//                              please hold it on until further notice.
// NOTE: Deserialized Miniports should never return NDIS_STATUS_RESOURCES to NDIS,
// and must instead queue it internally.
//
NDIS_STATUS VdevAdapter::Send(
			IN	PNDIS_PACKET			Packet,
			IN	UINT					Flags
			)
{
	T.Trace("VdevAdapter::Send() Entered\n");
	T << Packet;

//NicSendDataBuf
//NicSendDataBufLength

	// declare for convenience
#if 0
	KNdisPacket pkt(Packet);
	KNdisBuffer buf;
	UINT size;
	PUCHAR Buffer;
#endif
//	RWBufMutex.Wait();

	NicSendDataBufLength = 0;

	CopyPacket2Buffer(Packet,NicSendDataBuf,&NicSendDataBufLength);

	for (UINT i = 0 ;i < NicSendDataBufLength; i ++)
	{
		T.Trace("[%02x]",NicSendDataBuf[i]);
	}
	m_GenStats->xmit_ok++;
	
	return NDIS_STATUS_SUCCESS;

#if 0
	buf = pkt.QueryFirstBuffer();
	
	while(buf.IsValid())
	{
		
		size = buf.Length();
		T.Trace("VdevAdapter::Send size is [%ud]\n",size);
		
		Buffer = (PUCHAR)buf.Address();
		if (Buffer != NULL) {
			if (size > 1)
			{
				memcpy(NicSendDataBuf + NicSendDataBufLength,Buffer,size);
				NicSendDataBufLength = NicSendDataBufLength + size;

				if (NicSendDataBufLength > SENDBUFLENGMAX)
				{
					NicSendDataBufLength = SENDBUFLENGMAX;
					break;
				}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -