📄 wdmeppdevice.cpp
字号:
// 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 WDMEPPDevice::OnDevicePowerUp(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering WDMEPPDevice::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);
}
////////////////////////////////////////////////////////////////////////
// WDMEPPDevice::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 WDMEPPDevice::OnDeviceSleep(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering WDMEPPDevice::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);
}
////////////////////////////////////////////////////////////////////////
// WDMEPPDevice::Create
//
// Routine Description:
// Handler for IRP_MJ_CREATE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//
NTSTATUS WDMEPPDevice::Create(KIrp I)
{
NTSTATUS status;
t << "Entering WDMEPPDevice::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 << "WDMEPPDevice::Create Status " << (ULONG)status << EOL;
return status;
}
////////////////////////////////////////////////////////////////////////
// WDMEPPDevice::Close
//
// Routine Description:
// Handler for IRP_MJ_CLOSE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//
NTSTATUS WDMEPPDevice::Close(KIrp I)
{
NTSTATUS status;
t << "Entering WDMEPPDevice::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 << "WDMEPPDevice::Close Status " << (ULONG)status << EOL;
return status;
}
////////////////////////////////////////////////////////////////////////
// WDMEPPDevice::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 WDMEPPDevice::DeviceControl(KIrp I)
{
NTSTATUS status;
t << "Entering WDMEPPDevice::Device Control, " << I << EOL;
switch (I.IoctlCode())
{
case WDMEPP_IOCTL_READ:
status = WDMEPP_IOCTL_READ_Handler(I);
break;
case WDMEPP_IOCTL_WRITE:
status = WDMEPP_IOCTL_WRITE_Handler(I);
break;
case WDMEPP_IOCTL_BLOCK_READ:
status = WDMEPP_IOCTL_BLOCK_READ_Handler(I);
break;
case WDMEPP_IOCTL_BLOCK_WRITE:
status = WDMEPP_IOCTL_BLOCK_WRITE_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);
}
}
////////////////////////////////////////////////////////////////////////
// WDMEPPDevice::WDMEPP_IOCTL_READ_Handler
//
// Routine Description:
// Handler for IO Control Code WDMEPP_IOCTL_READ
//
// Parameters:
// I - IRP containing IOCTL request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the WDMEPP_IOCTL_READ function.
// This routine runs at passive level.
//
NTSTATUS WDMEPPDevice::WDMEPP_IOCTL_READ_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
UCHAR byResult;
PUCHAR pBuffer;
ULONG uOffset;
t << "Entering WDMIODevice::WDMIO_IOCTL_READ_Handler, " << I << EOL;
if((I.IoctlOutputBufferSize()>=1)&&(I.IoctlInputBufferSize()>=1))
{
pBuffer=(unsigned char*)I.IoctlBuffer();
uOffset=pBuffer[0];
if((uOffset>0)&&(uOffset<8))
byResult=m_DeviceIos.inb(uOffset);
else
byResult=0x00;
pBuffer[0]=byResult;
I.Information()=1;
}
else
{
I.Information()=0;
status=STATUS_BUFFER_TOO_SMALL;
}
return status;
}
////////////////////////////////////////////////////////////////////////
// WDMEPPDevice::WDMEPP_IOCTL_WRITE_Handler
//
// Routine Description:
// Handler for IO Control Code WDMEPP_IOCTL_WRITE
//
// Parameters:
// I - IRP containing IOCTL request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the WDMEPP_IOCTL_WRITE function.
// This routine runs at passive level.
//
NTSTATUS WDMEPPDevice::WDMEPP_IOCTL_WRITE_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
UCHAR byData;
PUCHAR pBuffer;
ULONG uOffset;
t << "Entering WDMIODevice::WDMIO_IOCTL_READ_Handler, " << I << EOL;
if(I.IoctlInputBufferSize()>=2)
{
pBuffer=(unsigned char*)I.IoctlBuffer();
uOffset=pBuffer[0];
byData=pBuffer[1];
if((uOffset>0)&&(uOffset<8))
m_DeviceIos.outb(uOffset,byData);
else
status=STATUS_BUFFER_TOO_SMALL;
}
else
status=STATUS_BUFFER_TOO_SMALL;
I.Information()=0;
return status;
}
//******************************************************
NTSTATUS WDMEPPDevice::WDMEPP_IOCTL_BLOCK_READ_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
PUCHAR pBuffer;
ULONG nLength;
t << "Entering WDMIODevice::WDMIO_IOCTL_READ_Handler, " << I << EOL;
nLength=0;
if(I.IoctlOutputBufferSize()>=255)
{
pBuffer=(unsigned char*)I.IoctlBuffer();
m_DeviceIos.outb(EPP_ADDR_REG,0x0a);
while((m_DeviceIos.inb(EPP_STATUS_REG)&0x20)!=0)
{
m_DeviceIos.outb(EPP_ADDR_REG,0x1b);
m_DeviceIos.outb(EPP_ADDR_REG,0x0b);
pBuffer[nLength]=m_DeviceIos.inb(EPP_DATA_REG);
nLength++;
if(nLength>255)
break;
}
}
m_DeviceIos.outb(EPP_ADDR_REG,0x00);
I.Information()=nLength;
return status;
}
//******************************************
NTSTATUS WDMEPPDevice::WDMEPP_IOCTL_BLOCK_WRITE_Handler(KIrp I)
{
NTSTATUS status = STATUS_BUFFER_TOO_SMALL;
PUCHAR pBuffer;
ULONG nSize;
ULONG nCounter;
t << "Entering WDMIODevice::WDMIO_IOCTL_READ_Handler, " << I << EOL;
if(I.IoctlInputBufferSize()>=1)
{
pBuffer=(unsigned char*)I.IoctlBuffer();
nSize=(unsigned long)pBuffer[0];
if(nSize<I.IoctlInputBufferSize())
{
m_DeviceIos.outb(EPP_ADDR_REG,0x00);
m_DeviceIos.outb(EPP_ADDR_REG,0x08);
for(nCounter=0;nCounter<3;nCounter++)
{
m_DeviceIos.outb(EPP_DATA_REG,0xff);
m_DeviceIos.outb(EPP_ADDR_REG,0x28);
m_DeviceIos.outb(EPP_ADDR_REG,0x08);
}
for(nCounter=0;nCounter<nSize;nCounter++)
{
m_DeviceIos.outb(EPP_DATA_REG,pBuffer[nCounter+1]);
m_DeviceIos.outb(EPP_ADDR_REG,0x28);
m_DeviceIos.outb(EPP_ADDR_REG,0x08);
}
for(nCounter=0;nCounter<2;nCounter++)
{
m_DeviceIos.outb(EPP_DATA_REG,0xff);
m_DeviceIos.outb(EPP_ADDR_REG,0x28);
m_DeviceIos.outb(EPP_ADDR_REG,0x08);
}
m_DeviceIos.outb(EPP_ADDR_REG,0x0c);
while((m_DeviceIos.inb(EPP_STATUS_REG)&0x10)!=0);
m_DeviceIos.outb(EPP_ADDR_REG,0x08);
m_DeviceIos.outb(EPP_ADDR_REG,0X09);
m_DeviceIos.outb(EPP_ADDR_REG,0X0b);
status = STATUS_SUCCESS;
}
}
I.Information()=0;
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -