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

📄 intwdmdevice.cpp

📁 武安河书第一版(vxd)Windows 驱动例子
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//		Our PnP policy will take care of 
//			(1) giving the IRP to the lower device
//			(2) detaching the PDO
//			(3) deleting the device object
//

NTSTATUS IntwdmDevice::OnRemoveDevice(KIrp I)
{
	// Device stopped, release the system resources.
	m_Irq.Disconnect();
	Invalidate();

// TODO:	Add device-specific code to remove your device   

	return STATUS_SUCCESS;

	// The following macro simply allows compilation at Warning Level 4
	// If you reference this parameter in the function simply remove the macro.
	UNREFERENCED_PARAMETER(I);
}

////////////////////////////////////////////////////////////////////////
//  IntwdmDevice::Create
//
//	Routine Description:
//		Handler for IRP_MJ_CREATE
//
//	Parameters:
//		I - Current IRP
//
//	Return Value:
//		NTSTATUS - Result code
//
//	Comments:
//

NTSTATUS IntwdmDevice::Create(KIrp I)
{
	NTSTATUS status;

// TODO: Add driver specific create handling code here

	// Generally a create IRP is targeted at our FDO, so we don't need
	// to pass it down to the PDO.  We have found for some devices, the
	// PDO is not expecting this Irp and returns an error code.
	// The default wizard code, therefore completes the Irp here using
	// PnpComplete().  The following commented code could be used instead
	// of PnpComplete() to pass the Irp to the PDO, which would complete it.
	//
//	I.ForceReuseOfCurrentStackLocationInCalldown();
//	status = m_Lower.PnpCall(this, I);

	status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);

	return status;
}


////////////////////////////////////////////////////////////////////////
//  IntwdmDevice::Close
//
//	Routine Description:
//		Handler for IRP_MJ_CLOSE
//
//	Parameters:
//		I - Current IRP
//
//	Return Value:
//		NTSTATUS - Result code
//
//	Comments:
//

NTSTATUS IntwdmDevice::Close(KIrp I)
{
	NTSTATUS status;

// TODO: Add driver specific close handling code here

	// Generally a close IRP is targeted at our FDO, so we don't need
	// to pass it down to the PDO.  We have found for some devices, the
	// PDO is not expecting this Irp and returns an error code.
	// The default wizard code, therefore completes the Irp here using
	// PnpComplete().  The following commented code could be used instead
	// of PnpComplete() to pass the Irp to the PDO, which would complete it.
	//
//	I.ForceReuseOfCurrentStackLocationInCalldown();
//	status = m_Lower.PnpCall(this, I);

	m_Irq.Disconnect();
	status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);

    return status;
}

////////////////////////////////////////////////////////////////////////
//  IntwdmDevice::DeviceControl
//
//	Routine Description:
//		Handler for IRP_MJ_DEVICE_CONTROL
//
//	Parameters:
//		I - Current IRP
// 
//	Return Value:
//		None
//
//	Comments:
//		This routine is the first handler for Device Control requests.
//		The KPnpDevice class handles restricting IRP flow
//		if the device is stopping or being removed.
//

NTSTATUS IntwdmDevice::DeviceControl(KIrp I) 
{
	NTSTATUS status;
	switch (I.IoctlCode())
	{
		case EVENT_REGISTER:
			status = EVENT_REGISTER_Handler(I);
			m_Irq.Connect(LinkTo(Isr_Irq),this);
			break;

		case READ_DATA:
			status = READ_DATA_Handler(I);
			break;

		default:
			// Unrecognized IOCTL request
			status = STATUS_INVALID_PARAMETER;
			break;
	}

	// If the IRP's IOCTL handler deferred processing using some driver
	// specific scheme, the status variable is set to STATUS_PENDING.
	// In this case we simply return that status, and the IRP will be
	// completed later.  Otherwise, complete the IRP using the status
	// returned by the IOCTL handler.
	if (status == STATUS_PENDING)
	{
		return status;
	}
	else
	{
		return I.PnpComplete(this, status);
	}
}

////////////////////////////////////////////////////////////////////////
//  IntwdmDevice::EVENT_REGISTER_Handler
//
//	Routine Description:
//		Handler for IO Control Code EVENT_REGISTER
//
//	Parameters:
//		I - IRP containing IOCTL request
//
//	Return Value:
//		NTSTATUS - Status code indicating success or failure
//
//	Comments:
//		This routine implements the EVENT_REGISTER function.
//		This routine runs at passive level.
//

NTSTATUS IntwdmDevice::EVENT_REGISTER_Handler(KIrp I)
{
  	HANDLE hEvent;
	NTSTATUS status;

// TODO:	Verify that the input parameters are correct
//			If not, return STATUS_INVALID_PARAMETER

// TODO:	Handle the the EVENT_REGISTER request, or 
//			defer the processing of the IRP (i.e. by queuing) and set
//			status to STATUS_PENDING.

// TODO:	Assuming that the request was handled here. Set I.Information
//			to indicate how much data to copy back to the user.
	hEvent = *(HANDLE*)I.IoctlBuffer();
	m_pEventToSignal = new(NonPagedPool) KEvent(hEvent);
	status = (m_pEventToSignal != NULL) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
	I.Information() = 0;

	return status;
}

////////////////////////////////////////////////////////////////////////
//  IntwdmDevice::READ_DATA_Handler
//
//	Routine Description:
//		Handler for IO Control Code READ_DATA
//
//	Parameters:
//		I - IRP containing IOCTL request
//
//	Return Value:
//		NTSTATUS - Status code indicating success or failure
//
//	Comments:
//		This routine implements the READ_DATA function.
//		This routine runs at passive level.
//

NTSTATUS IntwdmDevice::READ_DATA_Handler(KIrp I)
{
	const char* TEST_WAH = "TEST OK! - WAH";
	ULONG fwLength=0;
	NTSTATUS status;

    fwLength = strlen(TEST_WAH)+1;

    if (I.IoctlOutputBufferSize() >= fwLength)
    {
		strcpy((PCHAR)I.IoctlBuffer(),TEST_WAH);
//		KMemory Mem(I.Mdl());
//		strcpy((PCHAR)Mem.MapToSystemSpace(),TEST_WAH);
//			PVOID pa=MmGetSystemAddressForMdl(I.Mdl());//DDK的用法
//			strcpy((PCHAR)pa,TEST_WAH);
//		strcpy((PCHAR)I.UserBuffer(),TEST_WAH);
        I.Information() = fwLength;
        status = STATUS_SUCCESS;
    }
    else
    {
        I.Information() = 0;
        status = STATUS_BUFFER_TOO_SMALL;
	}

	return status;
}


////////////////////////////////////////////////////////////////////////
//  IntwdmDevice::DpcFor_Irq
//
//	Routine Description:
//		Deferred Procedure Call (DPC) for Irq
//
//	Parameters:
//		Arg1 - User-defined context variable
//		Arg2 - User-defined context variable
//
//	Return Value:
//		None
//
//	Comments:
//		This function is called for secondary processing of an interrupt.
//		Most code that runs at elevated IRQL should run here rather than
//		in the ISR, so that other interrupt handlers can continue to run.
//

VOID IntwdmDevice::DpcFor_Irq(PVOID Arg1, PVOID Arg2)
{
// TODO:	Typically, the interrupt signals the end of a data transfer
//			operation for a READ or WRITE operation. If this is the
//			case, add code to handle the completion of the IRP
//			associated with this operation here.

// TODO:	Enable further interrupts on the device.

	// The following macros simply allows compilation at Warning Level 4
	// If you reference these parameters in the function simply remove the macro.
	m_pEventToSignal->Set(); // or Pulse
	UNREFERENCED_PARAMETER(Arg1);
	UNREFERENCED_PARAMETER(Arg2);
}

////////////////////////////////////////////////////////////////////////
//  IntwdmDevice::Isr_Irq
//
//	Routine Description:
//		Interrupt Service Routine (ISR) for IRQ Irq
//
//	Parameters:
//		None
// 
//	Return Value:
//		BOOLEAN		True if this is our interrupt
//
//	Comments:
//

#define IsOurInterrupt() TRUE	// replace with actual test
BOOLEAN IntwdmDevice::Isr_Irq(void)
{
	if (IsOurInterrupt())
	{
	// acknowledge interrupt to deassert interrupt request signal

	// Queue a DPC
		m_DpcFor_Irq.Request();

	// Return TRUE to indicate that the interrupt was handled
		return TRUE;
	}

	else
	// Return FALSE to indicate that the interrupt was not for this device
		return FALSE;
}

⌨️ 快捷键说明

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