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

📄 whusb20pnp.c

📁 linux 下的驱动程序 欢迎下载
💻 C
字号:
//////////////////////////////////////////////////////////////////////////////
//文件名称:Whceb01Pnp.cpp
//文件功能:即插即用例程
//文件作者:张伟标
//工作部门:研究一室
//创建时间:2003年8月25日
//修改记录:
//版权所有:维豪信息技术有限公司
//
//Copyright 2003 WellHope Information Technology Corporation, Ltd.
//All rights reserved.
/////////////////////////////////////////////////////////////////////////////
//	Whceb01AddDevice					Add device routine
//	Whceb01Pnp						PNP IRP dispatcher
//	PnpStartDeviceHandler			Handle PnP start device
//*	PnpQueryCapabilitiesHandler		Print pdo device capabilities
//*	PnpQueryRemoveDeviceHandler		Handle PnP query remove device
//*	PnpSurpriseRemovalHandler		Handle PnP surprise removal
//*	PnpRemoveDeviceHandler			Handle PnP remove device
//*	PnpStopDeviceHandler			Handle PnP stop device
//*	PnpStopDevice					Handle PnP device stopping
//*	PnpDefaultHandler				Default PnP handler to pass to next stack device
//*	ForwardIrpAndWait				Forward IRP and wait for it to complete
//*	LockDevice						Lock out PnP remove request
//*	UnlockDevice					Unlock device allow PnP remove request
//	Whceb01Power						Power IRP handler
//*	ForwardedIrpCompletionRoutine	Completion routine for ForwardIrpAndWait
/////////////////////////////////////////////////////////////////////////////

#define INITGUID // initialize Whceb01_GUID in this module
#include "Whusb20.h"

#pragma code_seg("PAGE")	// start PAGE section

/////////////////////////////////////////////////////////////////////////////

NTSTATUS PnpStartDeviceHandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp);
NTSTATUS PnpQueryCapabilitiesHandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp);
NTSTATUS PnpQueryRemoveDeviceHandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp);
NTSTATUS PnpSurpriseRemovalHandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp);
NTSTATUS PnpRemoveDeviceHandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp);
NTSTATUS PnpStopDeviceHandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp);
void PnpStopDevice( IN PWHCEB01_DEVICE_EXTENSION dx);
NTSTATUS PnpDefaultHandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp);

NTSTATUS ForwardedIrpCompletionRoutine( IN PDEVICE_OBJECT fdo, IN PIRP Irp, IN PKEVENT ev);

/////////////////////////////////////////////////////////////////////////////
//	Whceb01AddDevice:
//
//	Description:
//		Cope with a new PnP device being added here.
//		Usually just attach to the top of the driver stack.
//		Do not talk to device here!
//
//	Arguments:
//		Pointer to the Driver object
//		Pointer to Physical Device Object
//
//	Return Value:
//		This function returns STATUS_XXX

NTSTATUS Whceb01AddDevice(	IN PDRIVER_OBJECT DriverObject,
						IN PDEVICE_OBJECT pdo)
{
	NTSTATUS status;
	PDEVICE_OBJECT fdo;
	PWHCEB01_DEVICE_EXTENSION dx;
	PUSB_DEVICE_DESCRIPTOR deviceDescriptor = NULL;
	ULONG	i = 0;

#ifdef DEBUG_INTERFACE
	TRACE0 ("进入Whceb01AddDevice()");
#endif//DEBUG_INTERFACE
	// Create our Functional Device Object in fdo
	status = IoCreateDevice( DriverObject, sizeof(WHCEB01_DEVICE_EXTENSION), NULL,	// No Name
								FILE_DEVICE_UNKNOWN, 0, FALSE, &fdo);
	if( !NT_SUCCESS(status))
		return status;

	// Remember fdo in our device extension
	dx = (PWHCEB01_DEVICE_EXTENSION)fdo->DeviceExtension;
	dx->fdo = fdo;
	dx->pdo = pdo;
	dx->UsageCount = 0;
	KeInitializeEvent( &dx->StoppingEvent, NotificationEvent, FALSE);
	KeInitializeEvent( &dx->WaitEvent , NotificationEvent , FALSE );
	KeInitializeMutex( &dx->ChannelMutex , 1 );//信号量
	KeInitializeMutex( &dx->FrameMutex , 1 );
	dx->OpenHandleCount = 0;
	dx->Whceb01NumOfPipes = 0;
	dx->GotResources = FALSE;
	dx->Paused = FALSE;
	dx->IODisabled = TRUE;
	dx->Stopping = FALSE;
	dx->hWhceb01ConfigurationHandle = NULL;
	for( i = 0 ; i < MAX_CHANNEL ; i ++ )
	{
		dx->hWhceb01InterruptInHandle[i] = NULL; 
		dx->hWhceb01InterruptOutHandle[i] = NULL;
		dx->ChannelisUsed[i] = FALSE; 
	}

	dx->PduHead.Reserved = 0;


	dx->UsbTimeout = 10;

	// Register and enable our device interface
	status = IoRegisterDeviceInterface( pdo, &WHCEB01_GUID, NULL, &dx->ifSymLinkName);
	if( !NT_SUCCESS(status))
	{
		IoDeleteDevice(fdo);
		return status;
	}
#ifdef DEBUG_INTERFACE
	TRACE1("Symbolic Link Name is %T",&dx->ifSymLinkName);
#endif//DEBUG_INTERFACE

	// Attach to the driver stack below us
	dx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo,pdo);

	// Set fdo flags appropriately
	fdo->Flags |= DO_BUFFERED_IO|DO_POWER_PAGABLE;
	fdo->Flags &= ~DO_DEVICE_INITIALIZING;



	return STATUS_SUCCESS;
}

/////////////////////////////////////////////////////////////////////////////
//	Whceb01Pnp:
//
//	Description:
//		Handle IRP_MJ_PNP requests
//
//	Arguments:
//		Pointer to our FDO
//		Pointer to the IRP
//			Various minor codes
//				IrpStack->Parameters.QueryDeviceRelations
//				IrpStack->Parameters.QueryInterface
//				IrpStack->Parameters.DeviceCapabilities
//				IrpStack->Parameters.FilterResourceRequirements
//				IrpStack->Parameters.ReadWriteConfig
//				IrpStack->Parameters.SetLock
//				IrpStack->Parameters.QueryId
//				IrpStack->Parameters.QueryDeviceText
//				IrpStack->Parameters.UsageNotification
//
//	Return Value:
//		This function returns STATUS_XXX

NTSTATUS Whceb01Pnp(	IN PDEVICE_OBJECT fdo,
					IN PIRP Irp)
{
	PWHCEB01_DEVICE_EXTENSION dx=(PWHCEB01_DEVICE_EXTENSION)fdo->DeviceExtension;
	PIO_STACK_LOCATION IrpStack;
	ULONG MinorFunction;
	NTSTATUS status;

	TRACE0( "Pnp" );
	if (!LockDevice(dx))
		return CompleteIrp(Irp, STATUS_DELETE_PENDING, 0);

	// Get minor function
	IrpStack = IoGetCurrentIrpStackLocation(Irp);
	MinorFunction = IrpStack->MinorFunction;

	status = STATUS_SUCCESS;
	switch( MinorFunction)
	{
	case IRP_MN_START_DEVICE:
		status = PnpStartDeviceHandler(fdo,Irp);
		break;
	case IRP_MN_QUERY_REMOVE_DEVICE:
		status = PnpQueryRemoveDeviceHandler(fdo,Irp);
		break;
	case IRP_MN_SURPRISE_REMOVAL:
		status = PnpSurpriseRemovalHandler(fdo,Irp);
		break;
	case IRP_MN_REMOVE_DEVICE:
		status = PnpRemoveDeviceHandler(fdo,Irp);
		return status;
	case IRP_MN_QUERY_STOP_DEVICE:
		dx->Paused = TRUE;
		dx->IODisabled = TRUE;
		status = PnpDefaultHandler(fdo,Irp);
		break;
	case IRP_MN_STOP_DEVICE:
		status = PnpStopDeviceHandler(fdo,Irp);
		break;
	case IRP_MN_CANCEL_REMOVE_DEVICE:	// fall thru
	case IRP_MN_CANCEL_STOP_DEVICE:
		dx->Paused = FALSE;
		dx->IODisabled = FALSE;
		// fall thru
	default:
		status = PnpDefaultHandler(fdo,Irp);
	}

	UnlockDevice(dx);
//#if DBG
//	if( status!=STATUS_SUCCESS)
//		DebugPrint("PnP completed %x",status);
//#endif
	return status;
}

/////////////////////////////////////////////////////////////////////////////
//	PnpStartDeviceHandler:	Handle PnP start device

NTSTATUS PnpStartDeviceHandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
	NTSTATUS status;
	PWHCEB01_DEVICE_EXTENSION dx=(PWHCEB01_DEVICE_EXTENSION)fdo->DeviceExtension;
	PIO_STACK_LOCATION IrpStack ;
	
	IrpStack = IoGetCurrentIrpStackLocation(Irp);

#ifdef DEBUG_INTERFACE
	TRACE0("-------进入PnpStartDeviceHandler!----------");
#endif//DEBUG_INTERFACE

	status = ForwardIrpAndWait( fdo, Irp);
	if( !NT_SUCCESS(status))
		return CompleteIrp( Irp, status, Irp->IoStatus.Information);


	status = StartDevice( dx, IrpStack->Parameters.StartDevice.AllocatedResourcesTranslated);
	if( NT_SUCCESS(status))
	{
		dx->Paused = FALSE;
		dx->IODisabled = FALSE;
		IoSetDeviceInterfaceState( &dx->ifSymLinkName, TRUE);
	}
#ifdef DEBUG_INTERFACE
	TRACE0("-----------Exit PnpStartDeviceHandler.---------------");
#endif//DEBUG_INTERFACE	
	return CompleteIrp( Irp, status, 0);
}


/////////////////////////////////////////////////////////////////////////////
//	PnpQueryRemoveDeviceHandler:	Handle PnP query remove device

NTSTATUS PnpQueryRemoveDeviceHandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
	PWHCEB01_DEVICE_EXTENSION dx=(PWHCEB01_DEVICE_EXTENSION)fdo->DeviceExtension;

	TRACE0("Enter PnpQueryRemoveDeviceHandler");

	if( dx->OpenHandleCount>0)
	{

		TRACE1("PnpQueryRemoveDeviceHandler: %d handles still open",dx->OpenHandleCount);

		return CompleteIrp( Irp, STATUS_UNSUCCESSFUL, 0);
	}
	dx->Paused = TRUE;
	dx->IODisabled = TRUE;
	return PnpDefaultHandler(fdo,Irp);
}

/////////////////////////////////////////////////////////////////////////////
//	PnpSurpriseRemovalHandler:	Handle PnP surprise removal

NTSTATUS PnpSurpriseRemovalHandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
	PWHCEB01_DEVICE_EXTENSION dx=(PWHCEB01_DEVICE_EXTENSION)fdo->DeviceExtension;

	TRACE0("Enter PnpSurpriseRemovalHandler");


	// Wait for I/O to complete and stop device
	PnpStopDevice(dx);

	// Pass down stack and carry on immediately
	return PnpDefaultHandler(fdo, Irp);
}

/////////////////////////////////////////////////////////////////////////////
//	PnpRemoveDeviceHandler:	Handle PnP remove device

NTSTATUS PnpRemoveDeviceHandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
	NTSTATUS status;
	PWHCEB01_DEVICE_EXTENSION dx=(PWHCEB01_DEVICE_EXTENSION)fdo->DeviceExtension;

	TRACE0("Enter PnpRemoveDeviceHandler");


	// Wait for I/O to complete and stop device
	PnpStopDevice(dx);

	// Pass down stack and carry on immediately
	status = PnpDefaultHandler(fdo, Irp);
	
	// disable device interface
	IoSetDeviceInterfaceState( &dx->ifSymLinkName, FALSE);
	RtlFreeUnicodeString(&dx->ifSymLinkName);
	
	// unattach from stack
	if (dx->NextStackDevice)
		IoDetachDevice(dx->NextStackDevice);

	// delete our fdo
	IoDeleteDevice(fdo);

	return status;
}

/////////////////////////////////////////////////////////////////////////////
//	PnpStopDeviceHandler:	Handle PnP stop device

NTSTATUS PnpStopDeviceHandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
	PWHCEB01_DEVICE_EXTENSION dx=(PWHCEB01_DEVICE_EXTENSION)fdo->DeviceExtension;

	TRACE0("Enter PnpStopDeviceHandler");

	// Wait for I/O to complete and stop device
	PnpStopDevice(dx);
	
	return PnpDefaultHandler( fdo, Irp);
}

/////////////////////////////////////////////////////////////////////////////
//	PnpStopDevice:	Handle PnP device stopping

void PnpStopDevice( IN PWHCEB01_DEVICE_EXTENSION dx)
{

	TRACE0 ("Enter PnpStopDevice");

	// Stop I/O ASAP
	dx->IODisabled = TRUE;

	// Do nothing if we're already stopped
	if( !dx->GotResources)
		return;

	// Wait for any pending I/O operations to complete
	dx->Stopping = TRUE;
	KeResetEvent(&dx->StoppingEvent);
//	UnlockDevice(dx);
	UnlockDevice(dx);
	TRACE1( "before WaitFor 0x%x" , dx->UsageCount );
	KeWaitForSingleObject( &dx->StoppingEvent, Executive, KernelMode, FALSE, NULL);
	TRACE0( "after WaitFor" );
	//DebugPrint("PnpStopDevice: All pending I/O completed");
	dx->Stopping = FALSE;

	// Stop our device before passing down
	StopDevice(dx);

	// Bump usage count back up again
	LockDevice(dx);
	LockDevice(dx);
}

/////////////////////////////////////////////////////////////////////////////
//	Support routines
/////////////////////////////////////////////////////////////////////////////
//	PnpDefaultHandler:	Default PnP handler to pass to next stack device

NTSTATUS PnpDefaultHandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
//	DebugPrintMsg("PnpDefaultHandler");
	PWHCEB01_DEVICE_EXTENSION dx=(PWHCEB01_DEVICE_EXTENSION)fdo->DeviceExtension;
	IoSkipCurrentIrpStackLocation(Irp);
	return IoCallDriver( dx->NextStackDevice, Irp);
}

/////////////////////////////////////////////////////////////////////////////
//	ForwardIrpAndWait:	Forward IRP and wait for it to complete

NTSTATUS ForwardIrpAndWait( IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
	NTSTATUS status;
	PWHCEB01_DEVICE_EXTENSION dx=(PWHCEB01_DEVICE_EXTENSION)fdo->DeviceExtension;

	KEVENT event;
	KeInitializeEvent( &event, NotificationEvent, FALSE);

	IoCopyCurrentIrpStackLocationToNext(Irp);
	IoSetCompletionRoutine( Irp, (PIO_COMPLETION_ROUTINE)ForwardedIrpCompletionRoutine,
								(PVOID)&event, TRUE, TRUE, TRUE);

	status = IoCallDriver( dx->NextStackDevice, Irp);
	if( status==STATUS_PENDING)
	{
		DebugPrintMsg("ForwardIrpAndWait: waiting for completion");
		KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL);
		status = Irp->IoStatus.Status;
	}
#ifdef DEBUG_INTERFACE
	if( status!=STATUS_SUCCESS)
		TRACE1("ForwardIrpAndWait: completed %x",status);
#endif
	return status;
}

/////////////////////////////////////////////////////////////////////////////
//	LockDevice:	Lock out PnP remove request

BOOL LockDevice( IN PWHCEB01_DEVICE_EXTENSION dx)
{
//	TRACE0("Enter LockDevice");
	InterlockedIncrement(&dx->UsageCount);

	if( dx->Stopping)
	{
		if( InterlockedDecrement(&dx->UsageCount)==0)
			KeSetEvent( &dx->StoppingEvent, 0, FALSE);
		return FALSE;
	}
	
//	TRACE0("Exit LockDevice");
	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
//	UnlockDevice:	Unlock device allow PnP remove request

void UnlockDevice( IN PWHCEB01_DEVICE_EXTENSION dx)
{
	LONG UsageCount ;

//	TRACE0("Enter UnlockDevice");
	UsageCount = InterlockedDecrement(&dx->UsageCount);
	if( UsageCount==0)
	{
		KeSetEvent( &dx->StoppingEvent, 0, FALSE);
	}
//	TRACE0("Exit UnlockDevice");

}

/////////////////////////////////////////////////////////////////////////////
//	Whceb01Power:
//
//	Description:
//		Handle IRP_MJ_POWER requests
//
//	Arguments:
//		Pointer to the FDO
//		Pointer to the IRP
//			IRP_MN_WAIT_WAKE:		IrpStack->Parameters.WaitWake.Xxx
//			IRP_MN_POWER_SEQUENCE:	IrpStack->Parameters.PowerSequence.Xxx
//			IRP_MN_SET_POWER:
//			IRP_MN_QUERY_POWER:		IrpStack->Parameters.Power.Xxx
//
//	Return Value:
//		This function returns STATUS_XXX

NTSTATUS Whceb01Power(	IN PDEVICE_OBJECT fdo,
					IN PIRP Irp)
{
//	DebugPrint("Power %I",Irp);
	PWHCEB01_DEVICE_EXTENSION dx = (PWHCEB01_DEVICE_EXTENSION)fdo->DeviceExtension;

	// Just pass to lower driver
	PoStartNextPowerIrp( Irp);
	IoSkipCurrentIrpStackLocation(Irp);
	return PoCallDriver( dx->NextStackDevice, Irp);
}

/////////////////////////////////////////////////////////////////////////////

#pragma code_seg()	// end PAGE section

/////////////////////////////////////////////////////////////////////////////
//	ForwardedIrpCompletionRoutine:	Completion routine for ForwardIrpAndWait
//	Can be called at DISPATCH_LEVEL IRQL

NTSTATUS ForwardedIrpCompletionRoutine( IN PDEVICE_OBJECT fdo, IN PIRP Irp, IN PKEVENT ev)
{
	KeSetEvent( ev, 0, FALSE);
	return STATUS_MORE_PROCESSING_REQUIRED;
}

/////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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