📄 startiochardevice.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 + -