⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pdoioctl.c

📁 鼠标Windows驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
        }
        break;
        
    case IOCTL_IEEE1284_GET_MODE:
        
        DD((PCE)Pdx,DDT,"IOCTL_IEEE1284_GET_MODE\n");
        
        if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(PARCLASS_NEGOTIATION_MASK)) {
            Status = STATUS_BUFFER_TOO_SMALL;
        } else {

            PPARCLASS_NEGOTIATION_MASK  ppnmMask = (PPARCLASS_NEGOTIATION_MASK)Irp->AssociatedIrp.SystemBuffer;
            
            ppnmMask->usReadMask  = arpReverse[Pdx->IdxReverseProtocol].Protocol;
            ppnmMask->usWriteMask = afpForward[Pdx->IdxForwardProtocol].Protocol;
            
            Irp->IoStatus.Information = sizeof (PARCLASS_NEGOTIATION_MASK);
            
            Status = STATUS_SUCCESS;
        }
        break;

    case IOCTL_PAR_GET_DEFAULT_MODES:
        
        DD((PCE)Pdx,DDT,"IOCTL_IEEE1284_GET_MODE\n");
        
        if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(PARCLASS_NEGOTIATION_MASK)) {
            Status = STATUS_BUFFER_TOO_SMALL;
        } else {
            
            PPARCLASS_NEGOTIATION_MASK  ppnmMask = (PPARCLASS_NEGOTIATION_MASK)Irp->AssociatedIrp.SystemBuffer;
            
            ppnmMask->usReadMask  = NONE;            
            ppnmMask->usWriteMask = CENTRONICS;
            
            Irp->IoStatus.Information = sizeof (PARCLASS_NEGOTIATION_MASK);
            
            Status = STATUS_SUCCESS;
        }
        break;

    case IOCTL_PAR_ECP_HOST_RECOVERY:

        DD((PCE)Pdx,DDT,"IOCTL_PAR_ECP_HOST_RECOVERY\n");
        {
            BOOLEAN *isSupported;

            if( IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(BOOLEAN) ) {
                Status = STATUS_INVALID_PARAMETER;                
            } else {
                isSupported = (BOOLEAN *)Irp->AssociatedIrp.SystemBuffer;
                Pdx->bIsHostRecoverSupported = *isSupported;
                Status = STATUS_SUCCESS;
            }
        }
        break;

    case IOCTL_PAR_PING:
        DD((PCE)Pdx,DDT,"IOCTL_PAR_PING\n");
        // No Parms to check!
        Status = STATUS_PENDING;        
        break;

    case IOCTL_PAR_GET_DEVICE_CAPS:
        DD((PCE)Pdx,DDT,"IOCTL_PAR_GET_DEVICE_CAPS\n");
        if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(Pdx->ProtocolModesSupported)) {
            Status = STATUS_BUFFER_TOO_SMALL;
        } else {
            Status = STATUS_PENDING;
        }
        break;

    case IOCTL_IEEE1284_NEGOTIATE:
        
        DD((PCE)Pdx,DDT,"IOCTL_IEEE1284_NEGOTIATE\n");
        
        if ( IrpSp->Parameters.DeviceIoControl.InputBufferLength  < sizeof(PARCLASS_NEGOTIATION_MASK) ||
             IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(PARCLASS_NEGOTIATION_MASK) ) {

            DD((PCE)Pdx,DDW,"ParDeviceControl: IOCTL_IEEE1284_NEGOTIATE STATUS_INVALID_PARAMETER\n");
            Status = STATUS_INVALID_PARAMETER;

        } else {

            PPARCLASS_NEGOTIATION_MASK  ppnmMask = (PPARCLASS_NEGOTIATION_MASK)Irp->AssociatedIrp.SystemBuffer;
            
            if ((ppnmMask->usReadMask  == arpReverse[Pdx->IdxReverseProtocol].Protocol) &&
                (ppnmMask->usWriteMask == afpForward[Pdx->IdxForwardProtocol].Protocol)) {
                Irp->IoStatus.Information = sizeof(PARCLASS_NEGOTIATION_MASK);
                Status = STATUS_SUCCESS;
            } else {
                Status = STATUS_PENDING;
            }
        }
        break;

    default :

        DD((PCE)Pdx,DDT,"IOCTL default case\n");
        Status = STATUS_INVALID_PARAMETER;
        break;
    }
    
    if (Status == STATUS_PENDING) {
        
        IoAcquireCancelSpinLock(&OldIrql);
        
        if (Irp->Cancel) {
            
            IoReleaseCancelSpinLock(OldIrql);
            Status = STATUS_CANCELLED;
            
        } else {
            
            //
            // This IRP takes more time, so it should be queued.
            //
            BOOLEAN needToSignalSemaphore = IsListEmpty( &Pdx->WorkQueue ) ? TRUE: FALSE;
            IoMarkIrpPending(Irp);

#pragma warning( push ) 
#pragma warning( disable : 4054 4055 )
            IoSetCancelRoutine(Irp, ParCancelRequest);
#pragma warning( pop ) 

            InsertTailList(&Pdx->WorkQueue, &Irp->Tail.Overlay.ListEntry);
            IoReleaseCancelSpinLock(OldIrql);
            if( needToSignalSemaphore ) {
                KeReleaseSemaphore(&Pdx->RequestSemaphore, 0, 1, FALSE);
            }
        }
    }
    
    if (Status != STATUS_PENDING) {
        P4CompleteRequest( Irp, Status, Irp->IoStatus.Information );
    }

    return Status;
}

NTSTATUS
ParInternalDeviceControl(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp
    )

/*++

Routine Description:

    This routine is the dispatch for internal device control requests.

Arguments:

    DeviceObject    - Supplies the device object.

    Irp             - Supplies the I/O request packet.

Return Value:

    STATUS_SUCCESS              - Success.
    STATUS_PENDING              - Request pending.
    STATUS_BUFFER_TOO_SMALL     - Buffer too small.
    STATUS_INVALID_PARAMETER    - Invalid io control request.
    STATUS_DELETE_PENDING       - This device object is being deleted

--*/

{
    PIO_STACK_LOCATION              IrpSp;
    // PPAR_SET_INFORMATION            SetInfo;
    NTSTATUS                        Status;
    // PSERIAL_TIMEOUTS                SerialTimeouts;
    PPDO_EXTENSION               Pdx;
    KIRQL                           OldIrql;
    PPARCLASS_INFORMATION           pParclassInfo;

    Irp->IoStatus.Information = 0;

    IrpSp     = IoGetCurrentIrpStackLocation(Irp);
    Pdx = DeviceObject->DeviceExtension;

    //
    // bail out if a delete is pending for this device object
    //
    if(Pdx->DeviceStateFlags & PPT_DEVICE_DELETE_PENDING) {
        P4CompleteRequest( Irp, STATUS_DELETE_PENDING, Irp->IoStatus.Information );
        return STATUS_DELETE_PENDING;
    }

    //
    // bail out if a remove is pending for our ParPort device object
    //
    if(Pdx->DeviceStateFlags & PAR_DEVICE_PORT_REMOVE_PENDING) {
        P4CompleteRequest( Irp, STATUS_DELETE_PENDING, Irp->IoStatus.Information );
        return STATUS_DELETE_PENDING;
    }

    //
    // bail out if device has been removed
    //
    if(Pdx->DeviceStateFlags & (PPT_DEVICE_REMOVED|PPT_DEVICE_SURPRISE_REMOVED) ) {
        P4CompleteRequest( Irp, STATUS_DEVICE_REMOVED, Irp->IoStatus.Information );
        return STATUS_DEVICE_REMOVED;
    }

    switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {

    case IOCTL_INTERNAL_PARCLASS_CONNECT:
        
        DD((PCE)Pdx,DDT,"IOCTL_INTERNAL_PARCLASS_CONNECT\n");
        
        if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(PARCLASS_INFORMATION)) {
            
            Status = STATUS_BUFFER_TOO_SMALL;
            
        } else {
            PFDO_EXTENSION              fdx      = Pdx->Fdo->DeviceExtension;
            PPARALLEL_PORT_INFORMATION  portInfo = &fdx->PortInfo;
            PPARALLEL_PNP_INFORMATION   pnpInfo  = &fdx->PnpInfo;

            pParclassInfo = Irp->AssociatedIrp.SystemBuffer;
            
            pParclassInfo->ParclassContext       = Pdx;
            pParclassInfo->Controller            = portInfo->Controller;
            pParclassInfo->SpanOfController      = portInfo->SpanOfController;
            pParclassInfo->EcrController         = pnpInfo->EcpController;
            pParclassInfo->HardwareCapabilities  = pnpInfo->HardwareCapabilities;
            pParclassInfo->FifoDepth             = pnpInfo->FifoDepth;
            pParclassInfo->FifoWidth             = pnpInfo->FifoWidth;
            pParclassInfo->DetermineIeeeModes    = ParExportedDetermineIeeeModes;
            pParclassInfo->TerminateIeeeMode     = ParExportedTerminateIeeeMode;
            pParclassInfo->NegotiateIeeeMode     = ParExportedNegotiateIeeeMode;
            pParclassInfo->IeeeFwdToRevMode      = ParExportedIeeeFwdToRevMode;
            pParclassInfo->IeeeRevToFwdMode      = ParExportedIeeeRevToFwdMode;
            pParclassInfo->ParallelRead          = ParExportedParallelRead;
            pParclassInfo->ParallelWrite         = ParExportedParallelWrite;
            
            Irp->IoStatus.Information = sizeof(PARCLASS_INFORMATION);
            
            Status = STATUS_SUCCESS;
        }
        
        break;
        
    case IOCTL_INTERNAL_GET_PARPORT_FDO:

        DD((PCE)Pdx,DDT,"IOCTL_INTERNAL_GET_PARPORT_FDO\n");
        
        if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(PDEVICE_OBJECT)) {
            
            Status = STATUS_BUFFER_TOO_SMALL;
            
        } else {

            PDEVICE_OBJECT *pFdo = Irp->AssociatedIrp.SystemBuffer;
            *pFdo = Pdx->Fdo;
            Irp->IoStatus.Information = sizeof(PDEVICE_OBJECT);
            
            Status = STATUS_SUCCESS;
        }
        
        break;

    case IOCTL_INTERNAL_PARCLASS_DISCONNECT:
        
        Status = STATUS_SUCCESS;
        break;
        
    case IOCTL_INTERNAL_DISCONNECT_IDLE:
    case IOCTL_INTERNAL_LOCK_PORT:
    case IOCTL_INTERNAL_UNLOCK_PORT:
    case IOCTL_INTERNAL_LOCK_PORT_NO_SELECT:
    case IOCTL_INTERNAL_UNLOCK_PORT_NO_DESELECT:
    case IOCTL_INTERNAL_PARDOT3_CONNECT:
    case IOCTL_INTERNAL_PARDOT3_RESET:
    
        Status = STATUS_PENDING;
        break;

    case IOCTL_INTERNAL_PARDOT3_DISCONNECT:

        // immediately tell worker thread to stop signalling
        Pdx->P12843DL.bEventActive = FALSE;
        Status = STATUS_PENDING;
        break;

    case IOCTL_INTERNAL_PARDOT3_SIGNAL:
    
        if( IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(PKEVENT) ) {
            Status = STATUS_INVALID_PARAMETER;                
        } else {
            Status = STATUS_PENDING;
        }
        break;

    default :

        DD((PCE)Pdx,DDW,"IOCTL_INTERNAL... default case - invalid parameter\n");
        Status = STATUS_INVALID_PARAMETER;
        break;
    }
    

    if (Status == STATUS_PENDING) {
        
        //
        // This IRP takes more time, queue it for the worker thread
        //

        IoAcquireCancelSpinLock(&OldIrql);
        
        if (Irp->Cancel) {
            
            IoReleaseCancelSpinLock(OldIrql);
            Status = STATUS_CANCELLED;
            
        } else {
            
            BOOLEAN needToSignalSemaphore = IsListEmpty( &Pdx->WorkQueue ) ? TRUE : FALSE;
            IoMarkIrpPending(Irp);
#pragma warning( push ) 
#pragma warning( disable : 4054 4055 )
            IoSetCancelRoutine(Irp, ParCancelRequest);
#pragma warning( pop ) 
            InsertTailList(&Pdx->WorkQueue, &Irp->Tail.Overlay.ListEntry);
            IoReleaseCancelSpinLock(OldIrql);
            if( needToSignalSemaphore ) {
                KeReleaseSemaphore(&Pdx->RequestSemaphore, 0, 1, FALSE);
            }
        }
    }
    
    if (Status != STATUS_PENDING) {
        P4CompleteRequest( Irp, Status, Irp->IoStatus.Information );
    }

    return Status;
}

VOID
ParDeviceIo(
    IN  PPDO_EXTENSION   Pdx
    )
/*++

Routine Description:

    This routine implements a DEVICE_IOCTL request with the extension's current irp.

Arguments:

    Pdx   - Supplies the device extension.

Return Value:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -