📄 fdoioctl.c
字号:
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1998 - 1999
//
// File: ioctl.c
//
//--------------------------------------------------------------------------
#include "pch.h"
NTSTATUS
PptFdoInternalDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine is the dispatch routine for IRP_MJ_INTERNAL_DEVICE_CONTROL.
Arguments:
DeviceObject - Supplies the device object.
Irp - Supplies the I/O request packet.
Return Value:
STATUS_SUCCESS - Success.
STATUS_UNSUCCESSFUL - The request was unsuccessful.
STATUS_PENDING - The request is pending.
STATUS_INVALID_PARAMETER - Invalid parameter.
STATUS_CANCELLED - The request was cancelled.
STATUS_BUFFER_TOO_SMALL - The supplied buffer is too small.
STATUS_INVALID_DEVICE_STATE - The current chip mode is invalid to change to asked mode
--*/
{
PIO_STACK_LOCATION IrpSp;
PFDO_EXTENSION Extension = DeviceObject->DeviceExtension;
NTSTATUS Status;
PPARALLEL_PORT_INFORMATION PortInfo;
PPARALLEL_PNP_INFORMATION PnpInfo;
PMORE_PARALLEL_PORT_INFORMATION MorePortInfo;
KIRQL CancelIrql;
SYNCHRONIZED_COUNT_CONTEXT SyncContext;
PPARALLEL_INTERRUPT_SERVICE_ROUTINE IsrInfo;
PPARALLEL_INTERRUPT_INFORMATION InterruptInfo;
PISR_LIST_ENTRY IsrListEntry;
SYNCHRONIZED_LIST_CONTEXT ListContext;
SYNCHRONIZED_DISCONNECT_CONTEXT DisconnectContext;
BOOLEAN DisconnectInterrupt;
//
// Verify that our device has not been SUPRISE_REMOVED. Generally
// only parallel ports on hot-plug busses (e.g., PCMCIA) and
// parallel ports in docking stations will be surprise removed.
//
// dvdf - RMT - It would probably be a good idea to also check
// here if we are in a "paused" state (stop-pending, stopped, or
// remove-pending) and queue the request until we either return to
// a fully functional state or are removed.
//
if( Extension->PnpState & PPT_DEVICE_SURPRISE_REMOVED ) {
return P4CompleteRequest( Irp, STATUS_DELETE_PENDING, Irp->IoStatus.Information );
}
//
// Try to acquire RemoveLock to prevent the device object from going
// away while we're using it.
//
Status = PptAcquireRemoveLockOrFailIrp( DeviceObject, Irp );
if ( !NT_SUCCESS(Status) ) {
return Status;
}
IrpSp = IoGetCurrentIrpStackLocation(Irp);
Irp->IoStatus.Information = 0;
switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
case IOCTL_INTERNAL_DISABLE_END_OF_CHAIN_BUS_RESCAN:
Extension->DisableEndOfChainBusRescan = TRUE;
Status = STATUS_SUCCESS;
break;
case IOCTL_INTERNAL_ENABLE_END_OF_CHAIN_BUS_RESCAN:
Extension->DisableEndOfChainBusRescan = FALSE;
Status = STATUS_SUCCESS;
break;
case IOCTL_INTERNAL_PARALLEL_PORT_FREE:
PptFreePort(Extension);
PptReleaseRemoveLock(&Extension->RemoveLock, Irp);
return P4CompleteRequest( Irp, STATUS_SUCCESS, Irp->IoStatus.Information );
case IOCTL_INTERNAL_PARALLEL_PORT_ALLOCATE:
IoAcquireCancelSpinLock(&CancelIrql);
if( Irp->Cancel ) {
Status = STATUS_CANCELLED;
} else {
SyncContext.Count = &Extension->WorkQueueCount;
if( Extension->InterruptRefCount ) {
KeSynchronizeExecution( Extension->InterruptObject, PptSynchronizedIncrement, &SyncContext );
} else {
PptSynchronizedIncrement( &SyncContext );
}
if (SyncContext.NewCount) {
// someone else currently has the port, queue request
PptSetCancelRoutine( Irp, PptCancelRoutine );
IoMarkIrpPending( Irp );
InsertTailList( &Extension->WorkQueue, &Irp->Tail.Overlay.ListEntry );
Status = STATUS_PENDING;
} else {
// port aquired
Extension->WmiPortAllocFreeCounts.PortAllocates++;
Status = STATUS_SUCCESS;
}
} // endif Irp->Cancel
IoReleaseCancelSpinLock(CancelIrql);
break;
case IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO:
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(PARALLEL_PORT_INFORMATION)) {
Status = STATUS_BUFFER_TOO_SMALL;
} else {
Irp->IoStatus.Information = sizeof(PARALLEL_PORT_INFORMATION);
PortInfo = Irp->AssociatedIrp.SystemBuffer;
*PortInfo = Extension->PortInfo;
Status = STATUS_SUCCESS;
}
break;
case IOCTL_INTERNAL_RELEASE_PARALLEL_PORT_INFO:
Status = STATUS_SUCCESS;
break;
case IOCTL_INTERNAL_GET_PARALLEL_PNP_INFO:
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(PARALLEL_PNP_INFORMATION)) {
Status = STATUS_BUFFER_TOO_SMALL;
} else {
Irp->IoStatus.Information = sizeof(PARALLEL_PNP_INFORMATION);
PnpInfo = Irp->AssociatedIrp.SystemBuffer;
*PnpInfo = Extension->PnpInfo;
Status = STATUS_SUCCESS;
}
break;
case IOCTL_INTERNAL_GET_MORE_PARALLEL_PORT_INFO:
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(MORE_PARALLEL_PORT_INFORMATION)) {
Status = STATUS_BUFFER_TOO_SMALL;
} else {
Irp->IoStatus.Information = sizeof(MORE_PARALLEL_PORT_INFORMATION);
MorePortInfo = Irp->AssociatedIrp.SystemBuffer;
MorePortInfo->InterfaceType = Extension->InterfaceType;
MorePortInfo->BusNumber = Extension->BusNumber;
MorePortInfo->InterruptLevel = Extension->InterruptLevel;
MorePortInfo->InterruptVector = Extension->InterruptVector;
MorePortInfo->InterruptAffinity = Extension->InterruptAffinity;
MorePortInfo->InterruptMode = Extension->InterruptMode;
Status = STATUS_SUCCESS;
}
break;
case IOCTL_INTERNAL_PARALLEL_SET_CHIP_MODE:
//
// Port already acquired?
//
// Make sure right parameters are sent in
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
sizeof(PARALLEL_CHIP_MODE) ) {
Status = STATUS_BUFFER_TOO_SMALL;
} else {
Status = PptSetChipMode (Extension,
((PPARALLEL_CHIP_MODE)Irp->AssociatedIrp.SystemBuffer)->ModeFlags );
} // end check input buffer
break;
case IOCTL_INTERNAL_PARALLEL_CLEAR_CHIP_MODE:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -