📄 plugplay.cpp
字号:
Return Value:
STATUS_SUCCESS if successful
NTSTATUS code otherwise
*/
NTSTATUS CancelStopDevice(PDEVICE_EXTENSION pdx, PIRP Irp)
{
NTSTATUS ntStatus;
Irp->IoStatus.Status = STATUS_SUCCESS;
if(pdx->state == PENDINGSTOP)
{
// Wait for lower level drivers.
ntStatus = ForwardAndWait(pdx, Irp);
if(NT_SUCCESS(ntStatus))
{
pdx->state = WORKING;
if(&pdx->dqReadWrite)
RestartRequests(&pdx->dqReadWrite, pdx->DeviceObject);
}
return CompleteRequest(Irp, ntStatus, 0);
}
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(pdx->LowerDeviceObject, Irp);
}
/*
Function name:
StopDevice
Routine Description:
Stops the device - IRP_MN_STOP_DEVICE.
Arguments:
pdx - pointer to device extension
Irp - I/O request being serviced
Return Value:
STATUS_SUCCESS if successful
NTSTATUS code otherwise
*/
NTSTATUS StopDevice(PDEVICE_EXTENSION pdx, PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
if(pdx->state != PENDINGSTOP)
{
if(&pdx->dqReadWrite)
AbortRequests(&pdx->dqReadWrite, STATUS_DELETE_PENDING);
}
ReleaseResources(pdx);
pdx->state = STOPPED;
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(pdx->LowerDeviceObject, Irp);
}
/*
Function name:
QueryRemoveDevice
Routine Description:
Determines if the device can handle a IRP_MN_REMOVE_DEVICE request.
Arguments:
pdx - pointer to the device extension
Irp - I/O request being serviced
Return Value:
STATUS_SUCCESS if successful
NTSTATUS code otherwise
*/
NTSTATUS QueryRemoveDevice(PDEVICE_EXTENSION pdx, PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
if(pdx->state == WORKING)
{
if((!IoIsWdmVersionAvailable(1, 0x10)) && pdx->DeviceObject->ReferenceCount)
{
KdPrint(("SIWDM - QueryRemoveDevice: Failing due to open handles\n"));
return CompleteRequest(Irp, STATUS_DEVICE_BUSY, 0);
}
if(&pdx->dqReadWrite)
{
StallRequests(&pdx->dqReadWrite);
WaitForCurrentIrp(&pdx->dqReadWrite);
}
}
pdx->oldstate = pdx->state;
pdx->state = PENDINGREMOVE;
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(pdx->LowerDeviceObject, Irp);
}
/*
Function name:
CancelRemoveDevice
Routine Description:
Cancels the previous query to remove the device - IRP_MN_CANCEL_REMOVE_DEVICE.
Arguments:
pdx - pointer to the device extension
Irp - I/O request being serviced
Return Value:
STATUS_SUCCESS if successful
NTSTATUS code otherwise
*/
NTSTATUS CancelRemoveDevice(PDEVICE_EXTENSION pdx, PIRP Irp)
{
NTSTATUS ntStatus;
Irp->IoStatus.Status = STATUS_SUCCESS;
if(pdx->state == PENDINGREMOVE)
{
ntStatus = ForwardAndWait(pdx, Irp);
if(NT_SUCCESS(ntStatus))
{
if((pdx->state = pdx->oldstate) == WORKING)
{
if(&pdx->dqReadWrite)
RestartRequests(&pdx->dqReadWrite, pdx->DeviceObject);
}
}
return CompleteRequest(Irp, ntStatus, 0);
}
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(pdx->LowerDeviceObject, Irp);
}
/*
Function name:
RemoveDevice
Routine Description:
Removes the device - IRP_MN_REMOVE_DEVICE request.
Arguments:
fdo - pointer to the device object
Irp - I/O request being serviced
Return Value:
STATUS_SUCCESS if successful
NTSTATUS code otherwise
*/
NTSTATUS RemoveDevice(PDEVICE_OBJECT fdo, PIRP Irp)
{
NTSTATUS ntStatus;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
Irp->IoStatus.Status = STATUS_SUCCESS;
if(&pdx->dqReadWrite)
AbortRequests(&pdx->dqReadWrite, STATUS_DELETE_PENDING);
ReleaseResources(pdx);
pdx->state = REMOVED;
IoSkipCurrentIrpStackLocation(Irp);
ntStatus = IoCallDriver(pdx->LowerDeviceObject, Irp);
if(pdx)
UnlockDeviceAndWait(pdx);
if(pdx->LowerDeviceObject)
IoDetachDevice(pdx->LowerDeviceObject);
IoDeleteDevice(fdo);
return ntStatus;
}
/*
Function name:
SupriseRemovalDevice
Routine Description:
Removes the device in cases of a suprise removal- IRP_MN_SUPRISE_REMOVAL request.
Arguments:
pdx - pointer to the device extension
Irp - I/O request being serviced
Return Value:
STATUS_SUCCESS if successful
NTSTATUS code otherwise
*/
NTSTATUS SurpriseRemovalDevice(PDEVICE_EXTENSION pdx, PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
if(&pdx->dqReadWrite)
AbortRequests(&pdx->dqReadWrite, STATUS_DELETE_PENDING);
pdx->state = SURPRISEREMOVED;
ReleaseResources(pdx);
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(pdx->LowerDeviceObject, Irp);
}
/*
Function name:
ReleaseResources
Routine Description:
Releases the resources and resets the hardware.
Arguments:
pdx - pointer to the device extension
Return Value:
*/
VOID ReleaseResources(IN PDEVICE_EXTENSION pdx)
{
ULONG i;
if(pdx->InterruptObject)
{
ResetDevice(pdx);
IoDisconnectInterrupt(pdx->InterruptObject);
pdx->InterruptObject = NULL;
}
SheldonUnMapDirect(pdx);
for(i=0;i<PCI_TYPE0_ADDRESSES;i++)
if(pdx->mem_mapped[i])
{
MmUnmapIoSpace(pdx->base[i], pdx->base_len[i]);
pdx->mem_mapped[i] = NULL;
}
}
/*
Function name:
ResetDevice
Routine Description:
Resets the hardware.
Arguments:
pdx - pointer to the device extension
Return Value:
*/
VOID ResetDevice(PDEVICE_EXTENSION pdx)
{
LARGE_INTEGER timeout;
// Reset the board
/////////////////
// IO and memory mapped
/////////////////
if( (ULONG)pdx->base[AMCC_OPREGS] & 0xffff0000 ) {
WRITE_REGISTER_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_MCSR), AMCC_MCSR_RESET);
// Delay to allow the add-on to reset
timeout.QuadPart = -10 * 10000;
KeDelayExecutionThread(KernelMode, FALSE, &timeout);
// Clear the reset for the benefit of the add-on
WRITE_REGISTER_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_MCSR), 0);
// Clear any interrupts
WRITE_REGISTER_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_INTCSR), AMCC_INTCSR_INTERRUPT_MASK);
}
else {
WRITE_PORT_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_MCSR), AMCC_MCSR_RESET);
// Delay to allow the add-on to reset
timeout.QuadPart = -10 * 10000;
KeDelayExecutionThread(KernelMode, FALSE, &timeout);
// Clear the reset for the benefit of the add-on
WRITE_PORT_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_MCSR), 0);
// Clear any interrupts
WRITE_PORT_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_INTCSR), AMCC_INTCSR_INTERRUPT_MASK);
}
/////////////////
// Memory mapped Only
/////////////////
// WRITE_REGISTER_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_MCSR), AMCC_MCSR_RESET);
//
// // Delay to allow the add-on to reset
// timeout.QuadPart = -10 * 10000;
// KeDelayExecutionThread(KernelMode, FALSE, &timeout);
//
// // Clear the reset for the benefit of the add-on
// WRITE_REGISTER_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_MCSR), 0);
//
// // Clear any interrupts
// WRITE_REGISTER_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_INTCSR), AMCC_INTCSR_INTERRUPT_MASK);
}
/*
Function name:
DisableDevice
Routine Description:
Prevents the device from generating interrupts.
Arguments:
pdx - pointer to the device extension
Return Value:
TRUE
*/
BOOLEAN DisableDevice(IN PDEVICE_EXTENSION pdx)
{
KdPrint(("SIWDM - DisableDevice\n"));
/////////////////
// IO and memory mapped
/////////////////
if( (ULONG)pdx->base[AMCC_OPREGS] & 0xffff0000 )
WRITE_REGISTER_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_INTCSR), AMCC_INTCSR_INTERRUPT_MASK);
else
WRITE_PORT_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_INTCSR), AMCC_INTCSR_INTERRUPT_MASK);
/////////////////
// Memory mapped Only
/////////////////
// WRITE_REGISTER_ULONG((PULONG) (pdx->base[AMCC_OPREGS] + AMCC_INTCSR), AMCC_INTCSR_INTERRUPT_MASK);
pdx->enabled = FALSE;
return TRUE;
}
/*
Function name:
EnableDevice
Routine Description:
Allows the device to generate interrupts.
Arguments:
pdx - pointer to the device extension
Return Value:
TRUE
*/
BOOLEAN EnableDevice(IN PDEVICE_EXTENSION pdx)
{
KdPrint(("SIWDM - EnableDevice\n"));
// Add code here to allow device to generate interrupts
pdx->enabled = TRUE;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -