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

📄 dispatch.cpp

📁 这是一个人精简的1394设备驱动程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include "amc2102.h"


 //HANDLE hEvent = NULL;
 //PKEVENT pEvent = NULL;
 KSPIN_LOCK BufferLock;
 WCHAR NameBuffer[128]=L"\\BaseNamedObjects\\v1394";
 //UNICODE_STRING EventName;
LARGE_INTEGER interval;


NTSTATUS v1394Create(IN PDEVICE_OBJECT fdo,
					 IN PIRP Irp)
{
	DebugPrintMsg("v1394 Create");
	NTSTATUS status;

	status=CompleteIrp(Irp,STATUS_SUCCESS,0);

	return status;
}

NTSTATUS v1394Close(IN PDEVICE_OBJECT fdo,
					 IN PIRP Irp)
{
	
	PIRB pIrb=NULL;
	NTSTATUS status=STATUS_SUCCESS;
	PV1394_DEVICE_EXTENSION dx=(PV1394_DEVICE_EXTENSION)fdo->DeviceExtension;

	DebugPrintMsg("v1394 Close");

	DebugPrint("hEvent:%x",dx->hEvent);
//	status=ZwClose(dx->hEvent);//hehu2004 11 19
	if(dx->nProcess>=2)
	{
	status=ZwClose(dx->hEvent);	
	dx->nProcess--;//hehu add 2004 1030
	}
	DebugPrint("dx->nProcess:%x",dx->nProcess);
	if(dx->nProcess==0)
{	
/*
	dx->hEvent = NULL;
	dx->pEvent = NULL;

	if(dx->fAlloc == TRUE)
	{
		pIrb=(PIRB)ExAllocatePool(NonPagedPool,sizeof(IRB));
		if(pIrb==NULL)
			status=STATUS_INSUFFICIENT_RESOURCES;
		else
		{

			pIrb->FunctionNumber=REQUEST_FREE_ADDRESS_RANGE;
			pIrb->Flags=0;
			pIrb->u.FreeAddressRange.nAddressesToFree=4;
			pIrb->u.FreeAddressRange.p1394AddressRange=&(dx->AddrRange);
			pIrb->u.FreeAddressRange.pAddressRange=&(dx->hAddress);

			DebugPrint("%x",pIrb->u.FreeAddressRange.p1394AddressRange);
			DebugPrint("%x",*(pIrb->u.FreeAddressRange.pAddressRange));
     
			status=ForwardIrpAndWait(fdo,Irp,pIrb);
			DebugPrint("v1394 Free Address:%x",status);
			if(status==STATUS_SUCCESS)
				dx->hAddress=NULL;

			ExFreePool(pIrb);
	           if(dx->pMdl)
			   {IoFreeMdl(dx->pMdl);
			    DebugPrint("                   dx->mdl have been release ");
			   }
		}
		dx->fAlloc = FALSE;
	}


	if(dx->interrupt)
	{
		ExFreePool(dx->interrupt);
		dx->interrupt = NULL;
	}
	*/
}	
	status=CompleteIrp(Irp,status,0);

	return status;
}

NTSTATUS v1394DeviceControl(IN PDEVICE_OBJECT fdo,
							IN PIRP Irp)
{
	NTSTATUS status=STATUS_SUCCESS;
	PMDL pMdl=NULL;
	PIRB pIrb=NULL;
	PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(Irp);
	PV1394_DEVICE_EXTENSION dx=(PV1394_DEVICE_EXTENSION)fdo->DeviceExtension;
	ULONG NodeID=0;//hehu 12 03
	CHAR ASCIIcode=0;//hehu12 13
	int j=0;//hehu12 13
	PVOID pIOBuffer=NULL;
	//hehu 2005 5 30
	PIRP                    newIrp;
	BOOLEAN                 allocNewIrp = FALSE;
	 KEVENT                  Event;
	IO_STATUS_BLOCK         ioStatus;
	PIO_STACK_LOCATION  NextIrpStack;
	LONG eventstatus;
	//hehu 2005 5 30
	ULONG ControlCode=IrpStack->Parameters.DeviceIoControl.IoControlCode;
		switch( ControlCode)
		{
		case IOCTL_WAIT_INT:
			if(dx->fAlloc == FALSE)
			{	NodeID=dx->NodeID;
				NodeID=NodeID<<8;
				pIrb=(PIRB)ExAllocatePool(NonPagedPool,sizeof(IRB));
				if(pIrb==NULL)
					status=STATUS_INSUFFICIENT_RESOURCES;
				else
				{
					
					
					pIrb->FunctionNumber=REQUEST_ALLOCATE_ADDRESS_RANGE;
					pIrb->Flags=0;
					pIrb->u.AllocateAddressRange.nLength=4;
					pIrb->u.AllocateAddressRange.Required1394Offset.Off_High=0x10;
					pIrb->u.AllocateAddressRange.Required1394Offset.Off_Low=NodeID;
					pIrb->u.AllocateAddressRange.FifoSListHead=NULL;
					pIrb->u.AllocateAddressRange.FifoSpinLock=NULL;
					
					pIrb->u.AllocateAddressRange.fulAccessType=ACCESS_FLAGS_TYPE_READ
						|ACCESS_FLAGS_TYPE_WRITE;
					pIrb->u.AllocateAddressRange.fulNotificationOptions=NOTIFY_FLAGS_AFTER_READ
						|NOTIFY_FLAGS_AFTER_WRITE;
					pIrb->u.AllocateAddressRange.Context=dx;
					pIrb->u.AllocateAddressRange.Callback=NotificationRoutine;
					pIrb->u.AllocateAddressRange.p1394AddressRange=&(dx->AddrRange);
					dx->pMdl=IoAllocateMdl(dx->interrupt,4,FALSE,FALSE,NULL);//modified
					DebugPrint("            dx->pmdl have been created");
					
					if(dx->pMdl==NULL)
						status=STATUS_INSUFFICIENT_RESOURCES;
					else
					{
						MmBuildMdlForNonPagedPool(dx->pMdl);
						pIrb->u.AllocateAddressRange.Mdl=dx->pMdl;
						
						status=ForwardIrpAndWait(fdo,Irp,pIrb);
						DebugPrint("v1394 Allocate Address:%x",status);
						dx->hAddress=pIrb->u.AllocateAddressRange.hAddressRange;
						DebugPrint("%x,%x,%x",dx->AddrRange.AR_Off_High,
							dx->AddrRange.AR_Off_Low,dx->AddrRange.AR_Length);
						DebugPrint("AddressesReturned:%x",pIrb->u.AllocateAddressRange.AddressesReturned);
						DebugPrint("hAddressRange:%x",pIrb->u.AllocateAddressRange.hAddressRange);
						DebugPrintMsg("       the interrupt have been matched    ");
					}
					ExFreePool(pIrb);
				}
				dx->fAlloc = TRUE;
			}
			status=CompleteIrp(Irp,status,0);
			
			break;
//////////////////////////////////////////////////////////////////////////////////////
		case IOCTL_END_INT:
			
			status=CompleteIrp(Irp,status,0);
			
			break;
//////////////////////////////////////////////////////////////////////////////////////
		case IOCTL_CREATE_EVENT:
		//在这个回调例程中创建通知事件并且开辟一个非分页内存来,该内存在ioctl_wait_int中注册为接收包的地址区间
		//将节点号dx->NodeID以字符串的形式表达出来并加在L"\\BaseNamedObjects\\v1394"之后
			for(j=0;j<4;j++)
		{
		ASCIIcode=(CHAR)((dx->NodeID>>4*(3-j))&0X0F);
		if((ASCIIcode>=10)&&(ASCIIcode<=15))
			NameBuffer[j+23]=ASCIIcode+55;
		else if((ASCIIcode>=0)&&(ASCIIcode<=9))
			NameBuffer[j+23]=ASCIIcode+48;
		}
		
		NameBuffer[j+23]=0;
		RtlInitUnicodeString(&(dx->EventName),NameBuffer);
		dx->EventName.MaximumLength=128;
		DebugPrint("event name %T",&(dx->EventName));
		dx->pEvent= IoCreateNotificationEvent(&(dx->EventName),&(dx->hEvent));
		
		DebugPrintMsg("                have build the notification event 0");
		DebugPrint("dx->pEvent:%x,dx->hEvent:%x",dx->pEvent,dx->hEvent);
		if(dx->pEvent==NULL)
        {
        
		status=STATUS_INSUFFICIENT_RESOURCES;
		}
		else
        {	DebugPrintMsg("               enter the else ");
		    DebugPrint("dx->nProcess:%x",dx->nProcess);
			if(dx->nProcess==0)
			{
				KeClearEvent(dx->pEvent);
				dx->interrupt = (PCHAR)ExAllocatePool(NonPagedPool,4);
				DebugPrintMsg("                have build the notification event ");
				DebugPrint("dx->interrupt:%x",dx->interrupt);
				if(dx->interrupt==NULL)
				status=STATUS_INSUFFICIENT_RESOURCES;
			}
		}
		dx->nProcess++;

		status=CompleteIrp(Irp,status,0);

			break;
/////////////////////////////////////////////////////////////////////////////

/*
	case IOCTL_ASYNC_WRITE:
		//
		// If this is a UserMode request create a newIrp so that the request
		// will be issued from KernelMode
		//

		if (Irp->RequestorMode == UserMode) {
			
			KeInitializeEvent (&Event, NotificationEvent, FALSE);
			eventstatus=KeReadStateEvent(&Event);
			DebugPrint("eventstatus :%x",eventstatus);
			KeSetEvent(&Event,0,FALSE);
			eventstatus=KeReadStateEvent(&Event);
			status=KeWaitForSingleObject (&Event, Executive, KernelMode, FALSE, NULL); 
			DebugPrint("eventstatus :%x",eventstatus);
			DebugPrint("status :%x",status);
			DebugPrint("eventstatus :%x",eventstatus);
			DebugPrint("status :%x",status);
			DebugPrint("eventstatus :%x",eventstatus);
			DebugPrint("status :%x",status);
			KeClearEvent(&Event);
			
			newIrp = IoBuildDeviceIoControlRequest (IOCTL_1394_CLASS, dx->NextStackDevice, 
				NULL, 0, NULL, 0, TRUE, &Event, &ioStatus);
			
			if (!newIrp) {					
				
				
				status = STATUS_INSUFFICIENT_RESOURCES;
				goto Exitasycnwrite;            
			}
			allocNewIrp = TRUE;
		}
		
		
		pIrb=(PIRB)ExAllocatePool(NonPagedPool,sizeof(IRB));
		if(pIrb==NULL)
			status=STATUS_INSUFFICIENT_RESOURCES;
		else
		{
			pIOBuffer=Irp->AssociatedIrp.SystemBuffer;
			
			pIrb->FunctionNumber=REQUEST_ASYNC_WRITE;
			pIrb->Flags=0;
			pIrb->u.AsyncWrite.DestinationAddress.IA_Destination_Offset=((PV1394_IO_STRUCTURE)pIOBuffer)->address;
			pIrb->u.AsyncWrite.nNumberOfBytesToWrite=4;
			pIrb->u.AsyncWrite.nBlockSize=0;
			pIrb->u.AsyncWrite.fulFlags=0;
			pIrb->u.AsyncWrite.ulGeneration=dx->Generation;
			
			pMdl=IoAllocateMdl(&(((PV1394_IO_STRUCTURE)pIOBuffer)->data),4,FALSE,FALSE,NULL);
			if(pMdl==NULL)
				status=STATUS_INSUFFICIENT_RESOURCES;
			else
			{
				MmBuildMdlForNonPagedPool(pMdl);
				pIrb->u.AsyncWrite.Mdl=pMdl;
				if(allocNewIrp==TRUE)
				{
					//hehu 2005 5 30
					DebugPrintMsg("allocNewIrp==TRUE ,Enter to ");					
					NextIrpStack = IoGetNextIrpStackLocation(newIrp);
					NextIrpStack->Parameters.Others.Argument1 = pIrb;
					// newIrp->IoStatus.Status = STATUS_NOT_SUPPORTED ; 
					status = IoCallDriver (dx->NextStackDevice, newIrp);					
					if (status == STATUS_PENDING)
					{   DebugPrintMsg("IoCallDriver return status_pending");
					 DebugPrint("%x",status);
					 DebugPrint("%x",status);
					interval=RtlConvertLongToLargeInteger((LONG)(-10));
					status=KeWaitForSingleObject (&Event, Executive, KernelMode, FALSE, NULL); 
					//status = KeDelayExecutionThread(KernelMode, FALSE, &interval);
					DebugPrint("%x",status);
					DebugPrint("%x",status);
					DebugPrint("%x",status);
					DebugPrint("%x",status);
					status = ioStatus.Status;
					}
					//hehu 2005 5 30
					//	status=ForwardIrpAndWait(fdo,newIrp,pIrb);
					DebugPrint("the single write status:%x",status);
					DebugPrint("Write Address:%x,%x",((PV1394_IO_STRUCTURE)pIOBuffer)->address.Off_High,((PV1394_IO_STRUCTURE)pIOBuffer)->address.Off_Low);
					DebugPrint("v1394 Async Write:%x",((PV1394_IO_STRUCTURE)pIOBuffer)->data);
				}
				IoFreeMdl(pMdl);
			}
			ExFreePool(pIrb);
		}
Exitasycnwrite :
		if (allocNewIrp) 
			Irp->IoStatus = ioStatus;
		//status=CompleteIrp(Irp,status,0);hehu 2005 5 30
		
		break;
		
/////////////////////////////////////////////////////////////////////////////	 
		
		 case IOCTL_ASYNC_READ:
			 //
			 // If this is a UserMode request create a newIrp so that the request
			 // will be issued from KernelMode
			 //	
			 if (Irp->RequestorMode == UserMode) {
				 
				 KeInitializeEvent (&Event, NotificationEvent, FALSE);
				 
				 newIrp = IoBuildDeviceIoControlRequest (IOCTL_1394_CLASS, dx->NextStackDevice, 
					 NULL, 0, NULL, 0, TRUE, &Event, &ioStatus);
				 
				 if (!newIrp) {					
					 

⌨️ 快捷键说明

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