📄 bpskdevice.cpp
字号:
// BPSKDevice.cpp
// Implementation of BPSKDevice device class
//
// Generated by DriverWizard version DriverStudio 3.1.0 (Build 1722)
// Requires Compuware's DriverWorks classes
//
#pragma warning(disable:4065) // Allow switch statement with no cases
#include <vdw.h>
#include "BPSKDeviceinterface.h"
#include "BPSK.h"
#include "BPSKDevice.h"
#include "BPSKioctl.h"
#pragma hdrstop("BPSK.pch")
extern KDebugOnlyTrace t; // Global driver trace object
GUID BPSKDevice_Guid = BPSKDevice_CLASS_GUID;
#define INTCSR 0x68 //中断控制地址
#define DMAMODE0 0x80 //DMA0通道
#define DMAPADR0 0x84 //DMA0通道PCI地址
#define DMALADR0 0x88 //DMA0通道本地地址
#define DMASIZ0 0x8C //DMA0通道传输字节计数
#define DMADPR0 0x90 //DMA0通道指针
#define DMACSR0 0xA8 //DMA(0、1)通道状态
////////////////////////////////////////////////////////////////////////
// BPSKDevice::BPSKDevice
//
// Routine Description:
// This is the constructor for the Functional Device Object, or FDO.
// It is derived from KPnpDevice, which builds in automatic
// dispatching of subfunctions of IRP_MJ_POWER and IRP_MJ_PNP to
// virtual member functions.
//
// Parameters:
// Pdo - Physical Device Object - this is a pointer to a system
// device object that represents the physical device.
//
// Unit - Unit number. This is a number to append to the device's
// base device name to form the Logical Device Object's name
//
// Return Value:
// None
//
// Comments:
// The object being constructed contains a data member (m_Lower) of type
// KPnpLowerDevice. By initializing it, the driver binds the FDO to the
// PDO and creates an interface to the upper edge of the system class driver.
//
BPSKDevice::BPSKDevice(PDEVICE_OBJECT Pdo, ULONG Unit) :
KPnpDevice(Pdo, &BPSKDevice_Guid)
{
t << "Entering BPSKDevice::BPSKDevice (constructor)\n";
// 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.
// Initialize the Power Policy settings to the "standard" policy
SetPowerPolicy();
// TODO: Customize the Power Policy for this device by setting
// flags in m_PowerPolicies.
}
////////////////////////////////////////////////////////////////////////
// BPSKDevice::~BPSKDevice
//
// Routine Description:
// This is the destructor for the Functional Device Object, or FDO.
//
// Parameters:
// None
//
// Return Value:
// None
//
// Comments:
// None
//
BPSKDevice::~BPSKDevice()
{
t << "Entering BPSKDevice::~BPSKDevice() (destructor)\n";
}
char *PNPMinorFunctionName(ULONG mn)
{
static char* minors[] = {
"IRP_MN_START_DEVICE",
"IRP_MN_QUERY_REMOVE_DEVICE",
"IRP_MN_REMOVE_DEVICE",
"IRP_MN_CANCEL_REMOVE_DEVICE",
"IRP_MN_STOP_DEVICE",
"IRP_MN_QUERY_STOP_DEVICE",
"IRP_MN_CANCEL_STOP_DEVICE",
"IRP_MN_QUERY_DEVICE_RELATIONS",
"IRP_MN_QUERY_INTERFACE",
"IRP_MN_QUERY_CAPABILITIES",
"IRP_MN_QUERY_RESOURCES",
"IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
"IRP_MN_QUERY_DEVICE_TEXT",
"IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
"<unknown minor function>",
"IRP_MN_READ_CONFIG",
"IRP_MN_WRITE_CONFIG",
"IRP_MN_EJECT",
"IRP_MN_SET_LOCK",
"IRP_MN_QUERY_ID",
"IRP_MN_QUERY_PNP_DEVICE_STATE",
"IRP_MN_QUERY_BUS_INFORMATION",
"IRP_MN_DEVICE_USAGE_NOTIFICATION",
"IRP_MN_SURPRISE_REMOVAL"
};
if (mn > IRP_MN_SURPRISE_REMOVAL)
return "<unknown minor function>";
else
return minors[mn];
}
////////////////////////////////////////////////////////////////////////
// BPSKDevice::DefaultPnp
//
// Routine Description:
// Default handler for IRP_MJ_PNP
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result returned from lower device
//
// Comments:
// This routine just passes the IRP through to the lower device. It is
// the default handler for IRP_MJ_PNP. IRPs that correspond to
// any virtual members of KpnpDevice that handle minor functions of
// IRP_MJ_PNP and that are not overridden get passed to this routine.
//
NTSTATUS BPSKDevice::DefaultPnp(KIrp I)
{
t << "Entering BPSKDevice::DefaultPnp\n" << I << EOL;
I.ForceReuseOfCurrentStackLocationInCalldown();
return m_Lower.PnpCall(this, I);
}
////////////////////////////////////////////////////////////////////////
// BPSKDevice::DefaultPower
//
// Routine Description:
// Default handler for IRP_MJ_POWER
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result returned from lower device
//
// Comments:
// This routine just passes the IRP through to the lower device. It is
// the default handler for IRP_MJ_POWER.
//
NTSTATUS BPSKDevice::DefaultPower(KIrp I)
{
t << "Entering BPSKDevice::DefaultPower\n" << I << EOL;
I.IndicatePowerIrpProcessed();
I.CopyParametersDown();
return m_Lower.PnpPowerCall(this, I);
}
////////////////////////////////////////////////////////////////////////////////
// BPSKDevice::SystemControl
//
// Routine Description:
// Default handler for IRP_MJ_SYSTEM_CONTROL
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result returned from lower device
//
// Comments:
// This routine just passes the IRP through to the next device since this driver
// is not a WMI provider.
//
NTSTATUS BPSKDevice::SystemControl(KIrp I)
{
t << "Entering BPSKDevice::SystemControl\n";
I.ForceReuseOfCurrentStackLocationInCalldown();
return m_Lower.PnpCall(this, I);
}
////////////////////////////////////////////////////////////////////////
// BPSKDevice::Invalidate
//
// Routine Description:
// Calls Invalidate methods for system resources
//
// Parameters:
// None
//
// Return Value:
// None
//
// Comments:
// This function is called from OnStopDevice, OnRemoveDevice and
// OnStartDevice (in error conditions). It calls the Invalidate
// member funcitons for each resource to free the underlying system
// resource if allocated. It is safe to call Invalidate more than
// once for a resource, or for an uninitialized resource.
VOID BPSKDevice::Invalidate()
{
// It is not necessary to release the system resource for the DMA adapter
// object, since NT provides no mechanism for this.
//不需要释放DMA适配器对象即m_Dma;
if(m_Buffer.IsValid())
m_Buffer.Invalidate();//添加
// For each memory mapped region, release the underlying system resoruce.
m_MemoryRange0.Invalidate();
// For each I/O port mapped region, release the underlying system resource.
m_IoPortRange0.Invalidate();
m_IoPortRange1.Invalidate();
// For the interrupt, release the underlying system resource.
// m_Irq.Invalidate();
if(m_pEvent)
delete m_pEvent;
if(m_pEvent1)
delete m_pEvent1;
}
////////////////////////////////////////////////////////////////////////
// BPSKDevice::OnStartDevice
//
// Routine Description:
// Handler for IRP_MJ_PNP subfcn IRP_MN_START_DEVICE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
// Initialize the physical device. Typically, the driver initializes
// physical resources here. Call I.AllocatedResources() for a list
// of the raw resources that the system has assigned to the device,
// or I.TranslatedResources() for the translated resource list.
//
NTSTATUS BPSKDevice::OnStartDevice(KIrp I)
{
t << "Entering BPSKDevice::OnStartDevice\n";
NTSTATUS status = STATUS_SUCCESS;
I.Information() = 0;
// The default Pnp policy has already cleared the IRP with the lower device
// Initialize the physical device object.
// Get the list of raw resources from the IRP
PCM_RESOURCE_LIST pResListRaw = I.AllocatedResources();
// Get the list of translated resources from the IRP
PCM_RESOURCE_LIST pResListTranslated = I.TranslatedResources();
// TODO: Check to ensure that the following parameters are correct for your hardware
//
#define MAX_DMA_LENGTH 0x100000 // 0x100000 is 1 MB
//DMA对象
// Initialize the device descriptor for the DMA object using the assigned resource
DEVICE_DESCRIPTION dd;
RtlZeroMemory(&dd, sizeof(dd));
dd.Version = DEVICE_DESCRIPTION_VERSION;
dd.Master = TRUE;
dd.ScatterGather = FALSE;
dd.DemandMode = FALSE;//Indicates whether to use the system DMA controller's demand mode. Not used for busmaster DMA.
dd.AutoInitialize = FALSE;
dd.Dma32BitAddresses = TRUE;
dd.IgnoreCount = FALSE;
dd.DmaChannel = 0;
dd.InterfaceType = PCIBus;
dd.DmaWidth = Width32Bits; // PCI default width 32bit
dd.DmaSpeed = Compatible;
dd.MaximumLength = MAX_DMA_LENGTH;
// Initialize the DMA adapter object
m_Dma.Initialize(&dd, m_Lower.TopOfStack());
m_Buffer.Initialize(&m_Dma,1024*64);//初始化KCommonDmaBuffer类对象大小64k
KPciConfiguration PciConfig(m_Lower.TopOfStack());
// For each memory mapped region, initialize the memory mapped range
// using the resources provided by NT. Once initialized, each memory
// range's base virtual address in system space can be obtained by calling
// member Base(). Each memory range's physical address in CPU space can
// obtained by calling CpuPhysicalAddress(). To access the memory mapped
// range use member functions such as inb/outb, or the array element operator.
status = m_MemoryRange0.Initialize(
pResListTranslated,
pResListRaw,
PciConfig.BaseAddressIndexToOrdinal(0)
);
if (!NT_SUCCESS(status))
{
Invalidate();
return status;
}
// For each I/O port mapped region, initialize the I/O port range using
// the resources provided by NT. Once initialized, use member functions such as
// inb/outb, or the array element operator to access the ports range.
status = m_IoPortRange0.Initialize(
pResListTranslated,
pResListRaw,
PciConfig.BaseAddressIndexToOrdinal(1)
);
if (!NT_SUCCESS(status))
{
Invalidate();
return status;
}
status = m_IoPortRange1.Initialize(
pResListTranslated,
pResListRaw,
PciConfig.BaseAddressIndexToOrdinal(2),
TRUE
);
if (!NT_SUCCESS(status))
{
Invalidate();
return status;
}
// Initialize and connect the interrupt
status = m_Irq.InitializeAndConnect(
pResListTranslated,
LinkTo(Isr_Irq),
this
);
if (!NT_SUCCESS(status))
{
Invalidate();
return status;
}
// Setup the DPC to be used for interrupt processing
m_DpcFor_Irq.Setup(LinkTo(DpcFor_Irq), this);
// TODO: Add device-specific code to start your device.
// The base class will handle completion
return status;
}
////////////////////////////////////////////////////////////////////////
// BPSKDevice::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.
// Some function codes may be handled immediately,
// while others may be serialized through the StartIo routine.
//
// The KPnpDevice class handles restricting IRP flow
// if the device is stopping or being removed.
//
NTSTATUS BPSKDevice::DeviceControl(KIrp I)
{
NTSTATUS status;
t << "Entering BPSKDevice::Device Control, " << I << EOL;
switch (I.IoctlCode())
{
case CONFIG_SYMBOL_RATE:
status = CONFIG_SYMBOL_RATE_Handler(I);
break;
case MODULATE_MODE:
status = MODULATE_MODE_Handler(I);
break;
case SET_IF_FRE:
status = SET_IF_FRE_Handler(I);
break;
case CTRL_AD9851_INIT:
status = CTRL_AD9851_INIT_Handler(I);
break;
case IOCTL_SET_NOTIFICATION_EVENT:
status = IOCTL_SET_NOTIFICATION_EVENT_Handler(I);
break;
case START_COLLECT:
status = START_COLLECT_Handler(I);
break;
case STOP_COLLECT:
status = STOP_COLLECT_Handler(I);
break;
default:
// Unrecognized IOCTL request
status = STATUS_INVALID_PARAMETER;
break;
}
// If the IRP was queued, or its 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);
}
}
////////////////////////////////////////////////////////////////////////
// BPSKDevice::OnStopDevice
//
// Routine Description:
// Handler for IRP_MJ_PNP subfcn IRP_MN_STOP_DEVICE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
// The system calls this when the device is stopped.
// The driver should release any hardware resources
// in this routine.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -