📄 bpskdevice.cpp
字号:
//
// The base class passes the irp to the lower device.
//
NTSTATUS BPSKDevice::OnStopDevice(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering BPSKDevice::OnStopDevice\n";
// Device stopped, release the system resources.
Invalidate();
// TODO: Add device-specific code to stop your device
return status;
// 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);
}
////////////////////////////////////////////////////////////////////////
// BPSKDevice::OnRemoveDevice
//
// Routine Description:
// Handler for IRP_MJ_PNP subfcn IRP_MN_REMOVE_DEVICE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
// The system calls this when the device is removed.
// 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 BPSKDevice::OnRemoveDevice(KIrp I)
{
t << "Entering BPSKDevice::OnRemoveDevice\n";
// Device removed, release the system resources.
m_Irq.Disconnect();
// Device removed, release the system resources.
m_Irq.Invalidate();
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);
}
VOID BPSKDevice::CancelQueuedIrp(KIrp I)
{
KDeviceQueue dq(DeviceQueue());
// Test if the IRP is the current IRP如果请求的IRP是当前IRP就直接将他删除.
if ( (PIRP)I == CurrentIrp() )
{
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))
{
CancelSpinLock::Release(I.CancelIrql());
I.Information() = 0;
I.PnpComplete(this, STATUS_CANCELLED);
}
//如果请求取消的IRP不在对列中,释放对IRP的请求
else
{
CancelSpinLock::Release(I.CancelIrql());
}
}
VOID BPSKDevice::StartIo(KIrp I)
{
if ( !I.TestAndSetCancelRoutine(
LinkTo(CancelQueuedIrp),
NULL,
CurrentIrp()) )
{
return;
}
switch (I.MajorFunction())
{
case IRP_MJ_READ:
SerialRead(I);
break;
case IRP_MJ_WRITE:
SerialWrite(I);
break;
default:
ASSERT(FALSE);
PnpNextIrp(I);
break;
}
}
////////////////////////////////////////////////////////////////////////
// BPSKDevice::OnDevicePowerUp
//
// Routine Description:
// Handler for IRP_MJ_POWER with minor function IRP_MN_SET_POWER
// for a request to go to power on state from low power state
//
// Parameters:
// I - IRP containing POWER request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the OnDevicePowerUp function.
// This function was called by the framework from the completion
// routine of the IRP_MJ_POWER dispatch handler in KPnpDevice.
// The bus driver has completed the IRP and this driver can now
// access the hardware device.
// This routine runs at dispatch level.
//
NTSTATUS BPSKDevice::OnDevicePowerUp(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering BPSKDevice::OnDevicePowerUp\n";
// TODO: Service the device.
// Restore any context to the hardware device that
// was saved during the handling of a power down request.
// See the OnDeviceSleep function.
// Do NOT complete this IRP.
//
return status;
// 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);
}
////////////////////////////////////////////////////////////////////////
// BPSKDevice::OnDeviceSleep
//
// Routine Description:
// Handler for IRP_MJ_POWER with minor function IRP_MN_SET_POWER
// for a request to go to a low power state from a high power state
//
// Parameters:
// I - IRP containing POWER request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the OnDeviceSleep function.
// This function was called by the framework from the IRP_MJ_POWER
// dispatch handler in KPnpDevice prior to forwarding to the PDO.
// The hardware has yet to be powered down and this driver can now
// access the hardware device.
// This routine runs at passive level.
//
NTSTATUS BPSKDevice::OnDeviceSleep(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering BPSKDevice::OnDeviceSleep\n";
// TODO: Service the device.
// Save any context to the hardware device that will be required
// during a power up request. See the OnDevicePowerUp function.
// Do NOT complete this IRP. The base class handles forwarding
// this IRP to the PDO.
//
return status;
// 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);
}
////////////////////////////////////////////////////////////////////////
// BPSKDevice::Create
//
// Routine Description:
// Handler for IRP_MJ_CREATE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//
NTSTATUS BPSKDevice::Create(KIrp I)
{
NTSTATUS status;
t << "Entering BPSKDevice::Create, " << I << EOL;
// 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);
t << "BPSKDevice::Create Status " << (ULONG)status << EOL;
return status;
}
////////////////////////////////////////////////////////////////////////
// BPSKDevice::Close
//
// Routine Description:
// Handler for IRP_MJ_CLOSE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//
NTSTATUS BPSKDevice::Close(KIrp I)
{
NTSTATUS status;
t << "Entering BPSKDevice::Close, " << I << EOL;
// 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);
status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);
t << "BPSKDevice::Close Status " << (ULONG)status << EOL;
return status;
}
////////////////////////////////////////////////////////////////////////
// BPSKDevice::Cleanup
//
// Routine Description:
// Handler for IRP_MJ_CLEANUP
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//
NTSTATUS BPSKDevice::CleanUp(KIrp I)
{
t << "Entering CleanUp, " << I << EOL;
// 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);
}
////////////////////////////////////////////////////////////////////////
// BPSKDevice::SerialRead
//
// Routine Description:
// Handler for serialized READ
//
// Parameters:
// I - Current IRP
//
// Return Value:
// None
//
// Comments:
// This routine is called when the IRP is removed from the
// STARTIO queue. This guarantees that multiple requests are
// never processed simultaneously.
//
// This routine is called at dispatch level.
//
void BPSKDevice::SerialRead(KIrp I)
{
t << "Entering BPSKDevice::SerialRead, " << I << EOL;
NTSTATUS status = STATUS_SUCCESS;
//进行DMA传输
m_CurrentTransfer=new(NonPagedPool)KDmaTransfer(this,&m_Dma);
if(m_CurrentTransfer==NULL)
{
status=STATUS_INSUFFICIENT_RESOURCES;
t<<"unable to allocate transfer object:"<<status<<EOL;
I.Information()=0;
I.Status()=status;
PnpNextIrp(I);
}
/* status=m_CurrentTransfer->Initiate(I.Mdl(),(I.MajorFunction()==IRP_MJ_READ)?
FromDeviceToMemory:FromMemoryToDevice,
LinkTo(OnDmaReady)
);
*/
status=m_CurrentTransfer->Initiate(this,&m_Dma,I.Mdl(),(I.MajorFunction()==IRP_MJ_READ)?
FromDeviceToMemory:FromMemoryToDevice,
LinkTo(OnDmaReady),&m_Buffer
);
// If the transfer cannot be initiated, complete it with an error status.
if ( ! NT_SUCCESS(status) )
{
t<<"unable to initiate transfer: "<< status<<EOL;
delete m_CurrentTransfer;
m_CurrentTransfer = NULL;
I.Information() = 0;
I.Status() = status;
PnpNextIrp(I);
}
}
////////////////////////////////////////////////////////////////////////
// BPSKDevice::Read
//
// Routine Description:
// Handler for IRP_MJ_READ
//
// Parameters:
// I Current IRP
//
// Return Value:
// NTSTATUS Result code
//
// Comments:
// This routine handles read requests.
//
// The KPnpDevice class handles restricting IRP flow
// if the device is stopping or being removed.
//
NTSTATUS BPSKDevice::Read(KIrp I)
{
t << "Entering BPSKDevice::Read, " << I << EOL;
// TODO: Check the incoming request. Replace "FALSE" in the following
// line with a check that returns TRUE if the request is not valid.
if (I.ReadSize() == 0)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_SUCCESS);
}
return QueueIrp(I, LinkTo(CancelQueuedIrp));
/*原来的框架
if (FALSE) // 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.ReadSize() == 0)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_SUCCESS);
}
NTSTATUS status = STATUS_SUCCESS;
KMemory Mem(I.Mdl()); // Declare a memory object
// Use the memory object to create a pointer to the caller's buffer
PUCHAR pBuffer = (PUCHAR) Mem.VirtualAddress();
ULONG dwTotalSize = I.ReadSize(CURRENT); // Requested read size
ULONG dwBytesRead = 0; // Count of bytes read
// TODO: If the read can be satisfied immediately, set the Information
// and Status fields now, then call NextIrp to complete this IRP
// and start processing the next IRP in the queue.
// TODO: If the data is not yet available, initiate a request to the
// physical device here, and defer the Information, Status,
// and NextIrp handling until the hardware indicates that the
// read is complete. Typically, this might be handled in a
// DPC that is called after the hardware finishes transferring
// the data.
// TODO: To satisfy the read now, transfer data from the device to
// caller's buffer at "pBuffer". Then, indicate how much data was
// transferred:
I.Information() = dwBytesRead;
return I.PnpComplete(this, status);
*/
}
////////////////////////////////////////////////////////////////////////
// BPSKDevice::SerialWrite
//
// Routine Description:
// Handler for serialized WRITE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// None
//
// Comments:
// This routine is called when the IRP is removed from the
// STARTIO queue. This guarantees that multiple requests are
// never processed simultaneously.
//
void BPSKDevice::SerialWrite(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
// ULONG i;
// Declare a memory object
KMemory Mem(I.Mdl());
// Use the memory object to create a pointer to the caller's buffer
PUCHAR pBuffer = (PUCHAR) Mem.MapToSystemSpace();
ULONG dwTotalSize = I.WriteSize(CURRENT);
ULONG dwBytesSent = 0;
//清空FIFO
//m_IoPortRange1.outb(0,0);
//用I/O输出命令往FIFO写数据
//for (i=0;i<dwTotalSize;i++) m_IoPortRange1.outb(0x4,*pBuffer++);//自己修改的0x04:Local Base Address (Remap) for PCI-to-Local Address Space 0
I.Information() = dwBytesSent;
I.Status() = status;
PnpNextIrp(I);
}
////////////////////////////////////////////////////////////////////////
// BPSKDevice::Write
//
// Routine Description:
// Handler for IRP_MJ_WRITE
//
// Parameters:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -