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

📄 drvdispatch.c

📁 ddk编写的usb驱动源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	hwDbgPrint("IoCallDriver() USBD returned ntStatus = 0x%x\n", ntStatus);
	
	if (ntStatus == STATUS_PENDING)
	{		
		hwDbgPrint("Wait for single object\n");
		status = KeWaitForSingleObject(
				&event,
				Suspended,
				KernelMode,
				FALSE,
				NULL);
		
		hwDbgPrint("hwGetPortStatus() Wait for single object, returned 0x%x\n", status);
	}
	else
	{
		ioStatus.Status = ntStatus;
	}

	// USBD maps the error code for us
	ntStatus = ioStatus.Status;
	hwDbgPrint("hwGetPortStatus (ntStatus = 0x%x)-->>>>>>\n", ntStatus);
	
	return ntStatus;
}

/************************************************************************************************
* Function Type	:	global
* Parameter		:	fdo						-	pointer to our FDO (Functional Device Object )
* Return Value	:	STATUS_SUCCESS			-	if successful,
*					STATUS_UNSUCCESSFUL	-	otherwise
* Description		:	Reset the our parent port
*************************************************************************************************/
NTSTATUS hwResetParentPort(IN PDEVICE_OBJECT fdo)
{
	NTSTATUS			ntStatus, status = STATUS_SUCCESS;
	PIRP					irp;
	KEVENT				event;
	IO_STATUS_BLOCK	ioStatus;
	PIO_STACK_LOCATION	nextStack;
	PDEVICE_EXTENSION	dx;
	
	hwDbgPrint(" -->>>>>> hwResetParentPort(fdo=0x%x)\n",fdo);
	
	dx = fdo->DeviceExtension;
	//------------------------------------------------------------------
	// issue a synchronous request
	//------------------------------------------------------------------	
	KeInitializeEvent(&event, NotificationEvent, FALSE);	
	irp = IoBuildDeviceIoControlRequest(
			IOCTL_INTERNAL_USB_RESET_PORT,
			dx->LowerDeviceObject,
			NULL,
			0,
			NULL,
			0,
			TRUE, // internal ( use IRP_MJ_INTERNAL_DEVICE_CONTROL )
			&event,
			&ioStatus);
	
	//------------------------------------------------------------------
	// Call the class driver to perform the operation.  If the returned status
	// is PENDING, wait for the request to complete.
	//------------------------------------------------------------------

	nextStack = IoGetNextIrpStackLocation(irp);
	hwASSERT(nextStack != NULL);
	hwDbgPrint("hwResetParentPort() calling USBD enable port api\n");
	ntStatus = IoCallDriver(dx->LowerDeviceObject,irp);
	hwDbgPrint("hwResetParentPort() return from IoCallDriver USBD %x\n", ntStatus);
	
	if (ntStatus == STATUS_PENDING)
	{		
		hwDbgPrint("hwResetParentPort() Wait for single object\n");
		status = KeWaitForSingleObject(
								&event,
								Suspended,
								KernelMode,
								FALSE,
								NULL);
		hwDbgPrint("hwResetParentPort() Wait for single object, returned %x\n", status);
        
	}
	else
	{
		ioStatus.Status = ntStatus;
	}
	
	// USBD maps the error code for us
	ntStatus = ioStatus.Status;
	hwDbgPrint(" zjHMCFUsb_ResetPort (%x)-->>>>>>\n ", ntStatus);

	return ntStatus;
}

/************************************************************************************************
* Function Type	:	global
* Parameter		:	fdo			 - pointer to our FDO (Functional Device Object )
* Return Value	:	NT status code
* Description		:	Checks port status; if OK, return success and  do no more;
*					If bad, attempt reset
*************************************************************************************************/
NTSTATUS hwResetDevice( IN PDEVICE_OBJECT fdo )
{
	NTSTATUS	ntStatus;
	ULONG		portStatus;
	hwDbgPrint(" -->>>>>> hwResetDevice(fdo=0x%x)\n",fdo);
    
	//------------------------------------------------------------------
	// Check the port state, if it is disabled we will need 
	// to re-enable it
	//------------------------------------------------------------------
	ntStatus = hwGetPortStatus(fdo, &portStatus);
	if (NT_SUCCESS(ntStatus) && !(portStatus & USBD_PORT_ENABLED) &&
		portStatus & USBD_PORT_CONNECTED)
	{
		// port is disabled, attempt reset
		hwDbgPrint("Device will reset\n");
		ntStatus = hwResetParentPort(fdo);
	}
	hwDbgPrint(" hwResetDevice(ntStatus=0x%x)-->>>>>>\n",ntStatus);
	return ntStatus;
}

/************************************************************************************************
* Function Type	:	global
* Parameter		:	fdo			 - pointer to our FDO (Functional Device Object )
* Return Value	:	NT status code
* Description		:	Dispatch table handler for IRP_MJ_DEVICE_CONTROL; 
*					Handle DeviceIoControl() calls  from User mode
*************************************************************************************************/
NTSTATUS zjHMCFUsb_IOCTL(IN PDEVICE_OBJECT fdo,IN PIRP Irp)
{
	PIO_STACK_LOCATION				irpStack;
	PVOID							ioBuffer;
	ULONG							inputBufferLength;
	ULONG							outputBufferLength;
	PDEVICE_EXTENSION				dx;
	ULONG							ioControlCode;
	NTSTATUS						ntStatus = STATUS_SUCCESS;
	ULONG							length;
	PUCHAR							pch;
	PUSBD_PIPE_INFORMATION			pipe;
	PFILE_OBJECT						fileObject;
	PUSB_CONFIGURATION_DESCRIPTOR	configurationDescriptor;
	PUSB_DEVICE_DESCRIPTOR			usbDeviceDescriptor;
	ULONG_PTR						IrpInfo = 0;
	
	hwDbgPrint("-->>>>>>zjHMCFUsb_IOCTL(fdo=0x%x,Irp=0x%x)\n",fdo,Irp);
	PrintCurIrql();
	hwIncrementIoCount(fdo);
	
	dx = fdo->DeviceExtension;
	if ( !hwCanAcceptIoRequests( fdo ) )
	{
		hwDecrementIoCount(fdo);
		return CompleteIrp( Irp, STATUS_DELETE_PENDING,0,IO_NO_INCREMENT);		
	}

	//------------------------------------------------------------------
	// 取得当前IRP栈指针,以从中获取功能代码和参数
	//------------------------------------------------------------------
	irpStack = IoGetCurrentIrpStackLocation (Irp);
	//------------------------------------------------------------------
	// 获取用户的I/O缓冲地址和长度以及IOCTL代码
	//------------------------------------------------------------------
	ioBuffer			= Irp->AssociatedIrp.SystemBuffer;
	inputBufferLength	= irpStack->Parameters.DeviceIoControl.InputBufferLength;
	outputBufferLength	= irpStack->Parameters.DeviceIoControl.OutputBufferLength;	
	ioControlCode		= irpStack->Parameters.DeviceIoControl.IoControlCode;
	
	switch (ioControlCode)
	{
	case IOCTL_zjHMCFUsb_RESET_PIPE:
		// get our context and see if it is a pipe
		fileObject = irpStack->FileObject;
		pipe = (PUSBD_PIPE_INFORMATION) fileObject->FsContext;
		if(pipe == NULL)
		{
			// error, this is not a pipe
			ntStatus = STATUS_INVALID_PARAMETER;
		}
		else
		{
			hwResetPipe(fdo, pipe );
			ntStatus = STATUS_SUCCESS;
		}
		break;
	case IOCTL_zjHMCFUsb_GET_CONFIG_DESCRIPTOR:		
		//------------------------------------------------------------------
		// 这个API返回配置描述符和所有的端点、接点描
		// 述符的拷贝。
		// 输入	-	没有
		// 输出	-	配置描述符加上接点、端点描述符
		//------------------------------------------------------------------
		pch = (PUCHAR) ioBuffer;
		configurationDescriptor = dx->UsbConfigurationDescriptor;
		if (configurationDescriptor)
		{            
			length = configurationDescriptor->wTotalLength;
			if (outputBufferLength >= length)
			{				
				RtlCopyMemory(pch,(PUCHAR) configurationDescriptor,length);
				IrpInfo = length;
				ntStatus = STATUS_SUCCESS;
			}
			else
			{				
				ntStatus = STATUS_INVALID_PARAMETER;
			}
		}
		else
		{			
			ntStatus = STATUS_DEVICE_DATA_ERROR;
		}
		break;
	case IOCTL_zjHMCFUsb_GET_DEVICE_DESCRIPTOR:
		// 将设备描述符数据拷贝给用户层
		pch = (PUCHAR) ioBuffer;
		usbDeviceDescriptor = dx->UsbDeviceDescriptor;
		if ( usbDeviceDescriptor )
		{
			length = usbDeviceDescriptor->bLength;
			if (outputBufferLength >= length)
			{				
				RtlCopyMemory(pch,(PUCHAR) usbDeviceDescriptor,length);
				IrpInfo = length;
				ntStatus = STATUS_SUCCESS;
			}
			else
			{				
				ntStatus = STATUS_INVALID_PARAMETER;
			}
		}
		else
		{			
			ntStatus = STATUS_DEVICE_DATA_ERROR;
		}
		break;
	case IOCTL_zjHMCFUsb_RESET_DEVICE:        
		ntStatus = hwResetDevice( fdo );
		break;
	default:
		ntStatus = STATUS_INVALID_PARAMETER;
	}

	hwDecrementIoCount(fdo);	
	
	return CompleteIrp( Irp, ntStatus,IrpInfo,IO_NO_INCREMENT);;	
}
/************************************************************************************************
* Function Type	:	global
* Parameter		:	fdo			 - pointer to our FDO (Functional Device Object )
* Return Value	:	NT status code
* Description		:	This is the dispatch table routine for IRP_MJ_CREATE.
*					It's the entry point for CreateFile() calls
*					user mode apps may open "<name genned fron GUID>.\yy"
*					where yy is the internal pipe id
* Note			:	1、根据名字获得管道信息
*					2、从接口中找到这个管道,将标志
*						设置为"打开",打开的管道数加1
*					3、激活这个设备
*************************************************************************************************/
NTSTATUS zjHMCFUsb_Create(IN PDEVICE_OBJECT fdo, IN PIRP Irp )
{
	NTSTATUS						ntStatus = STATUS_SUCCESS;
	PFILE_OBJECT						fileObject;
	PIO_STACK_LOCATION				irpStack;
	PDEVICE_EXTENSION				dx;
	ULONG							i,
    									ix;
	NTSTATUS						actStat;
    	PUSBD_INTERFACE_INFORMATION	interface;
	PUSBD_PIPE_INFORMATION			PipeInfo;
	PzjHMCFUsb_PIPESTATE			PipeState = NULL;
	int								PipeIndex;

	PAGED_CODE();									//此代码包含可分页代码
	
	dx = fdo->DeviceExtension;
	interface = dx->UsbInterface;						//获取接口信息

	hwDbgPrint( " -->>>>>>zjHMCFUsb_Create(fdo=0x%x,Irp=0x%x)\n",fdo,Irp);
	PrintCurIrql();
	hwIncrementIoCount(fdo);

	if ( !hwCanAcceptIoRequests( fdo ) )
    	{
        	ntStatus = STATUS_DELETE_PENDING;

		hwDbgPrint( "ABORTING!!!\n");
		goto done;
	}
    
	irpStack = IoGetCurrentIrpStackLocation (Irp);
	fileObject = irpStack->FileObject;
	fileObject->FsContext = NULL;						//初始化文件对象中的内容参数
	if ( 0 == fileObject->FileName.Length )				//文件名长度为0则应用程序打开的只是设备本身
		goto done;									// nothing more to do

	PipeIndex = hwPipeWithName( fdo, &fileObject->FileName );

	if ( PipeIndex == -1 )
	{
		ntStatus = STATUS_INVALID_PARAMETER;
		goto done;
	}

	// init status to bad; will set good in below loop on success
	ntStatus = STATUS_INSUFFICIENT_RESOURCES;
	hwDbgPrint ( "Open pipe %d",PipeIndex );
	PipeState = &dx->PipeState[ PipeIndex ];
	PipeInfo =  &interface->Pipes[ PipeIndex ];
	fileObject->FsContext = PipeInfo;
	if ( PipeState->fPipeOpened )		// 这个管道已经被打开了	//d
	{
		ntStatus = STATUS_UNSUCCESSFUL;
		goto done;
	}
	PipeState->fPipeOpened = TRUE;		// set flag for opened
	ntStatus = STATUS_SUCCESS;
	dx->OpenPipeCount++;
	// try to power up device if its not in D0
	actStat = hwSelfSuspendOrActivate( fdo, FALSE );

done:
	hwDecrementIoCount(fdo);
	hwDbgPrint("zjHMCFUsb_Create() OpenPipeCount = %d, status = 0x%x-->>>>>>\n",
		dx->OpenPipeCount, ntStatus);
	return CompleteIrp( Irp, ntStatus,0,IO_NO_INCREMENT);
}

#ifdef _PRINT_COMM_DATA
VOID PrintCommData ( char *data, int dwLength )
{
	int i;
	for ( i=0; i<dwLength; i++ )
	{
		DbgPrint ( "%02x ", (UCHAR)data[i] );
	}
	DbgPrint ( "\n" );
}
#endif
/************************************************************************************************
* Function Type	:	global
* Parameter		:	fdo			- 	Pointer to the device object for next lower device in the  driver stack
*					Irp			-	Irp completed.
*					Context		-	our FDO.
* Return Value	:	此次IP操作的最后状态
* Description		:	单次URB传输的完成例程
*************************************************************************************************/
NTSTATUS hwReadWriteComplete
(
	IN PDEVICE_OBJECT	fdo,
	IN PIRP				Irp,
	IN PVOID				Context
)
{
	NTSTATUS			ntStatus = STATUS_SUCCESS;
	PURB				urb;
	PDEVICE_OBJECT		deviceObject;
	PDEVICE_EXTENSION	dx;

	//------------------------------------------------------------------
	// 我们不得不从Context中取得设备对象(deviceObject),因为
	// 传入的设备对象(fdo)是属于下层驱动的,因为
	// 我们调用了IoCallDriver()将irp传给下层,下层处理完irp
	// 后就调这个完成例程了。
	// 但是我们想要的设备对象应该是我们自己的,在
	// hwProcessReadWrite()中设置完成例程时我们将它放
	// 到上下文参数(Context)中了
	//------------------------------------------------------------------
	deviceObject =  (PDEVICE_OBJECT) Context;
	dx = deviceObject->DeviceExtension;	
	urb = dx->TransferDataUrb;	//get the urb we alloced for this xfer
	
	//  If the lower driver returned PENDING, mark our stack location as pending also.
	if ( Irp->PendingReturned )
	{  
		IoMarkIrpPending(Irp);
	}
    
	hwDbgPrint(" -->>>>>> hwReadWriteComplete():  Length 0x%08X decimal %d\n   Status 0x%08X\n",

⌨️ 快捷键说明

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