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

📄 startiochardevice.cpp

📁 windows 2000/XP WDM设备驱动程序开发 附书光盘 武安河著
💻 CPP
字号:
// StartIoCharDevice.cpp
// Implementation of StartIoCharDevice device class
//
// Generated by DriverWizard version DriverStudio 2.6.0 (Build 336)
// Requires Compuware's DriverWorks classes
//

#pragma warning(disable:4065) // Allow switch statement with no cases
		  
#include <vdw.h>
#include "..\StartIoCharDeviceinterface.h"

#include "StartIoChar.h"
#include "StartIoCharDevice.h"
#include "..\StartIoCharioctl.h"

#pragma hdrstop("StartIoChar.pch")


GUID StartIoCharDevice_Guid = StartIoCharDevice_CLASS_GUID;

StartIoCharDevice::StartIoCharDevice(PDEVICE_OBJECT Pdo, ULONG Unit) :
	KPnpDevice(Pdo, &StartIoCharDevice_Guid)
{

	// Check constructor status
    if ( ! NT_SUCCESS(m_ConstructorStatus) )
	{
	    return;
	}

	// Remember our unit number
	m_Unit = Unit;

	// Initialize the lower device
	m_Lower.Initialize(this, Pdo);

    // Inform the base class of the lower edge device object
	SetLowerDevice(&m_Lower);

	// Initialize the PnP Policy settings to the "standard" policy
	SetPnpPolicy();

// TODO:	Customize the PnP Policy for this device by setting
//			flags in m_Policies.

}

StartIoCharDevice::~StartIoCharDevice()
{
}

NTSTATUS StartIoCharDevice::DefaultPnp(KIrp I) 
{
	I.ForceReuseOfCurrentStackLocationInCalldown();
	return m_Lower.PnpCall(this, I);
}

NTSTATUS StartIoCharDevice::DefaultPower(KIrp I) 
{
	I.IndicatePowerIrpProcessed();
	I.CopyParametersDown();
	return m_Lower.PnpPowerCall(this, I);
}

NTSTATUS StartIoCharDevice::SystemControl(KIrp I) 
{
	I.ForceReuseOfCurrentStackLocationInCalldown();
	return m_Lower.PnpCall(this, I);
}

NTSTATUS StartIoCharDevice::OnStartDevice(KIrp I)
{
	return STATUS_SUCCESS;
}

NTSTATUS StartIoCharDevice::OnStopDevice(KIrp I)
{
	return STATUS_SUCCESS;
}

NTSTATUS StartIoCharDevice::OnRemoveDevice(KIrp I)
{
	return STATUS_SUCCESS;
}

VOID StartIoCharDevice::CancelQueuedIrp(KIrp I)
{
	KDeviceQueue dq(DeviceQueue());

	// Test if the IRP is the current IRP.
	if ( (PIRP)I == CurrentIrp() )
	{

		// If so, NULL it out, release the global cancel spinlock, then
		// complete it as canceled and start the next IRP.  Note that
		// if we got here, the IRP was still in a cancelable state when
		// it was canceled, and most likely is just about to start being
		// processed on the device.
		CurrentIrp() = NULL;
		CancelSpinLock::Release(I.CancelIrql());
	    I.Information() = 0;
		I.Status() = STATUS_CANCELLED;
		PnpNextIrp(I);
	}
	// See if the IRP can be removed from the device queue.
	else if (dq.RemoveSpecificEntry(I))
	{

		// If so, release the global cancel spinlock and complete it
		// as canceled.
		CancelSpinLock::Release(I.CancelIrql());
	    I.Information() = 0;
		I.PnpComplete(this, STATUS_CANCELLED);
	}
	else
	{

		// If we got here the IRP wasn't the current IRP, and wasn't in the
		// device queue.  This could happen if the IRP was removed by the
		// device queue's cleanup routine, just as it was being canceled.
		// In this case we have no work to do, since the cleanup routine
		// will cancel the IRP.  Simply release the global cancel spinlock.
		CancelSpinLock::Release(I.CancelIrql());
	}
}

VOID StartIoCharDevice::StartIo(KIrp I)
{

	// Before processing the Irp, we need to check to see if it has been
	// canceled.  We also want to set the Irp into an non-cancelable state
	// (cancel routine set to NULL) so we can process it. You may want to set
	// a different cancel routine here, or at other points within this function.
	// When performing these operations, it is necessary to hold the global
	// cancel spin lock and take special precautions to ensure the Irp is still
	// valid.  This is accomplished using the routine KIrp::TestAndSetCancelRoutine().
	if ( !I.TestAndSetCancelRoutine(
		LinkTo(CancelQueuedIrp),
		NULL,
		CurrentIrp()) )
	{
		
		// The Irp has been canceled we stop processing and exit.  Since
		// it was in a cancelable state previously, it will be completed by
		// the cancel routine that had been set on it.
		return;
	}

	// Start processing request.

	// Switch on the IRP's function:
	switch (I.MajorFunction())
	{
		case IRP_MJ_DEVICE_CONTROL:
			switch (I.IoctlCode())
			{
				case STARTIOCHAR_IOCTL_800:
					SerialDeviceControl(I);
					break;
				default:
					// We queued a request that shouldn't have been queued
					// (should never get here)
					ASSERT(FALSE);
					PnpNextIrp(I);
					break;
			}
			break;
		default:
			// The driver queued an Irp that isn't handled
			// by StartIo.  This shouldn't happen.
			ASSERT(FALSE);
			PnpNextIrp(I);
			break;
	}
}

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

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

	return status;
}

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

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

    return status;
}

NTSTATUS StartIoCharDevice::CleanUp(KIrp I)
{
// TODO:	Insert your code to respond to the CLEANUP message.
//			This code cleans up the single Wizard created queue.  If you
//			have created additional queues,	or have any outstanding Irps
//			stored in some other fashion in your driver, you should clean
//			these up as well for the file object specified in the cleanup Irp.

    KDeviceQueue dq(DeviceQueue());
	dq.PnpCleanUp(this, I.FileObject());
	return I.PnpComplete(this, STATUS_SUCCESS);
}


NTSTATUS StartIoCharDevice::DeviceControl(KIrp I) 
{
	NTSTATUS status;
	switch (I.IoctlCode())
	{
		case STARTIOCHAR_IOCTL_800:
		{
			char n=*(CHAR *)I.IoctlBuffer();
			if ((n < '0') || (n > '9'))	// If (Request is invalid)
			{
				// Invalid parameter in the Read request
				I.Information() = 0;
				return I.PnpComplete(this, STATUS_INVALID_PARAMETER);
			}

			// Always ok to read 0 elements.
			if (I.IoctlInputBufferSize() == 0)
			{
				I.Information() = 0;
				return I.PnpComplete(this, STATUS_SUCCESS);
			}

			// Queue the IRP for processing in StartIO
			// The read function is performed in SerialRead
			return QueueIrp(I, LinkTo(CancelQueuedIrp));
		}
		default:
			// Unrecognized IOCTL request
			status = STATUS_INVALID_PARAMETER;
			break;
	}

	return I.PnpComplete(this, status);
}

void StartIoCharDevice::SerialDeviceControl(KIrp I) 
{
	CHAR n,c[]="零一二三四五六七八九";
	n=*(CHAR *)I.IoctlBuffer();
	n -= '0';
	strncpy((PCHAR)I.IoctlBuffer(),&c[n*2],2);
	I.Information() = 2;
	I.Status() = STATUS_SUCCESS;
	PnpNextIrp(I);
}

⌨️ 快捷键说明

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