📄 vbusdev.cpp
字号:
// 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 VBusDevice::OnDevicePowerUp(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering VBusDevice::OnDevicePowerUp " << I;
// inform the bus object about parent power state changes
m_Bus.SetPowerState(I.PowerStateSetting().DeviceState);
return status;
}
////////////////////////////////////////////////////////////////////////
// VBusDevice::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 VBusDevice::OnDeviceSleep(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering VBusDevice::OnDeviceSleep " << I;
// inform the bus object about parent power state changes
m_Bus.SetPowerState(I.PowerStateSetting().DeviceState);
return status;
}
////////////////////////////////////////////////////////////////////////
// VBusDevice::DetermineNewDevicePowerState
//
// Routine Description:
// Calculates the lowest possible device power state
//
// Parameters:
// [in] SystemPowerState
// New system power state
//
// Return Value:
// DEVICE_POWER_STATE - new device power state
//
// Comments:
// This routine finds the highest device power state among
// its children and returns the new device power state which is at least
// as high as that state.
//
DEVICE_POWER_STATE VBusDevice::DetermineNewDevicePowerState(SYSTEM_POWER_STATE SystemPowerState)
{
DEVICE_POWER_STATE DevicePowerState = KPnpDevice::DetermineNewDevicePowerState(SystemPowerState);
DEVICE_POWER_STATE ChildrenPowerState = m_Bus.HighestChildrenPowerState();
if ( DevicePowerState > ChildrenPowerState )
DevicePowerState = ChildrenPowerState;
return DevicePowerState;
}
////////////////////////////////////////////////////////////////////////
// VBusDevice::Create
//
// Routine Description:
// Handler for IRP_MJ_CREATE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//
NTSTATUS VBusDevice::Create(KIrp I)
{
t << "Entering VBusDevice::Create " << I << EOL;
return I.PnpComplete(this, STATUS_SUCCESS);
}
////////////////////////////////////////////////////////////////////////
// VBusDevice::Close
//
// Routine Description:
// Handler for IRP_MJ_CLOSE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//
NTSTATUS VBusDevice::Close(KIrp I)
{
t << "Entering VBusDevice::Close " << I << EOL;
return I.PnpComplete(this, STATUS_SUCCESS);
}
////////////////////////////////////////////////////////////////////////
// VBusDevice::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 VBusDevice::DeviceControl(KIrp I)
{
NTSTATUS status;
t << "Entering VBusDevice::Device Control " << I << EOL;
switch ( I.IoctlCode() )
{
case VBUS_IOCTL_ADD_DEVICE:
status = VBUS_IOCTL_ADD_DEVICE_Handler(I);
break;
case VBUS_IOCTL_DELETE_DEVICE:
status = VBUS_IOCTL_DELETE_DEVICE_Handler(I);
break;
default:
// Unrecognized IOCTL request
status = STATUS_INVALID_PARAMETER;
break;
}
return I.PnpComplete(this, status);
}
////////////////////////////////////////////////////////////////////////
// VBusDevice::VBUS_IOCTL_ADD_DEVICE_Handler
//
// Routine Description:
// Handler for IO Control Code VBUS_IOCTL_ADD_DEVICE
//
// Parameters:
// I - IRP containing IOCTL request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the VBUS_IOCTL_ADD_DEVICE function.
// This routine runs at passive level.
//
NTSTATUS VBusDevice::VBUS_IOCTL_ADD_DEVICE_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering VBusDevice::VBUS_IOCTL_ADD_DEVICE_Handler, " << I;
I.Information() = 0;
if ( I.IoctlInputBufferSize() == sizeof(ULONG) )
{
PULONG p = (PULONG)I.IoctlBuffer();
if ( m_Bus.IdUsed(*p) )
return STATUS_INVALID_PARAMETER;
VReader* pDevice = new (
NULL,
FILE_DEVICE_BUS_EXTENDER,
NULL,
FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN,
DO_BUFFERED_IO | DO_POWER_PAGABLE
)
VReader(this, &m_Bus, *p);
if ( pDevice )
{
status = pDevice->ConstructorStatus();
if ( NT_SUCCESS(status) )
{
m_Bus.AddChild(pDevice);
((PDEVICE_OBJECT)*pDevice)->Flags &= ~DO_DEVICE_INITIALIZING;
IoInvalidateDeviceRelations(m_Lower.PDO(), BusRelations);
}
else
{
delete pDevice;
}
}
else
{
status = STATUS_INSUFFICIENT_RESOURCES;
}
}
else
{
status = STATUS_INVALID_PARAMETER;
}
return status;
}
////////////////////////////////////////////////////////////////////////
// VBusDevice::VBUS_IOCTL_DELETE_DEVICE_Handler
//
// Routine Description:
// Handler for IO Control Code VBUS_IOCTL_DELETE_DEVICE
//
// Parameters:
// I - IRP containing IOCTL request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the VBUS_IOCTL_DELETE_DEVICE function.
// This routine runs at passive level.
//
NTSTATUS VBusDevice::VBUS_IOCTL_DELETE_DEVICE_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering VBusDevice::VBUS_IOCTL_DELETE_DEVICE_Handler, " << I;
I.Information() = 0;
if ( I.IoctlInputBufferSize() == sizeof(ULONG) )
{
PULONG p = (PULONG)I.IoctlBuffer();
if ( m_Bus.RemoveChild(*p) )
{
IoInvalidateDeviceRelations(m_Lower.PDO(), BusRelations);
}
else
{
status = STATUS_INVALID_PARAMETER;
}
}
else
{
status = STATUS_INVALID_PARAMETER;
}
return status;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// VBus::IdUsed
//
// Routine Description:
// determines if id is unique
//
// Parameters:
// [in] id
// id to check
//
// Return Value:
// true if found
//
// Comments:
// None
//
bool VBus::IdUsed(ULONG id)
{
t << "VBus::IdUsed\n";
bool bFound = false;
m_Lock.Acquire();
VPdo* pDevice = (VPdo*)m_Children.HeadNoLock();
while ( pDevice )
{
if ( pDevice->m_Unit == id )
{
bFound = true;
break;
}
else
pDevice = (VPdo*)m_Children.NextNoLock(pDevice);
}
m_Lock.Release();
return bFound;
}
////////////////////////////////////////////////////////////////////////
// VBus::RemoveChild
//
// Routine Description:
// mark child as not present, but keep it in a collection
//
// Parameters:
// [in] id
// id of a child
//
// Return Value:
// true if found
//
// Comments:
// None
//
bool VBus::RemoveChild(ULONG id)
{
t << "VBus::RemoveChild\n";
m_Lock.Acquire();
if ( m_NumberOfChildren == 0 )
{
m_Lock.Release();
return false;
}
bool bFound = false;
VPdo* pDevice = (VPdo*)m_Children.HeadNoLock();
while ( pDevice )
{
if ( pDevice->m_Unit == id )
{
bFound = true;
pDevice->Removed();
break;
}
else
pDevice = (VPdo*)m_Children.NextNoLock(pDevice);
}
m_Lock.Release();
return bFound;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -