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

📄 pdoioctl.c

📁 鼠标Windows驱动
💻 C
📖 第 1 页 / 共 3 页
字号:

    None.

--*/
{

    PIRP                    Irp;
    PIO_STACK_LOCATION      IrpSp;
    ULONG                   IdLength;
    NTSTATUS                NtStatus;
    UCHAR                   Status;
    UCHAR                   Control;
    ULONG                   ioControlCode;

    Irp     = Pdx->CurrentOpIrp;
    IrpSp   = IoGetCurrentIrpStackLocation(Irp);

    ioControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;

    switch( ioControlCode ) {

    case IOCTL_PAR_SET_INFORMATION : 
        {

            Status = ParInitializeDevice(Pdx);
            
            if (!PAR_OK(Status)) {
                ParNotInitError(Pdx, Status); // Set the IoStatus.Status of the CurrentOpIrp appropriately
            } else {
                Irp->IoStatus.Status = STATUS_SUCCESS;
            }
        }
        break;

    case IOCTL_PAR_QUERY_INFORMATION :
        {
            PPAR_QUERY_INFORMATION IrpBuffer = Irp->AssociatedIrp.SystemBuffer;

            Irp->IoStatus.Status = STATUS_SUCCESS;

            Status  = GetStatus(Pdx->Controller);
            Control = GetControl(Pdx->Controller);

            // Interpretating Status & Control
            
            IrpBuffer->Status = 0x0;

            if (PAR_POWERED_OFF(Status) || PAR_NO_CABLE(Status)) {
                
                IrpBuffer->Status = (UCHAR)(IrpBuffer->Status | PARALLEL_POWER_OFF);
                
            } else if (PAR_PAPER_EMPTY(Status)) {
                
                IrpBuffer->Status = (UCHAR)(IrpBuffer->Status | PARALLEL_PAPER_EMPTY);
                
            } else if (PAR_OFF_LINE(Status)) {
                
                IrpBuffer->Status = (UCHAR)(IrpBuffer->Status | PARALLEL_OFF_LINE);
                
            } else if (PAR_NOT_CONNECTED(Status)) {

                IrpBuffer->Status = (UCHAR)(IrpBuffer->Status | PARALLEL_NOT_CONNECTED);

            }
            
            if (PAR_BUSY(Status)) {
                IrpBuffer->Status = (UCHAR)(IrpBuffer->Status | PARALLEL_BUSY);
            }
            
            if (PAR_SELECTED(Status)) {
                IrpBuffer->Status = (UCHAR)(IrpBuffer->Status | PARALLEL_SELECTED);
            }
            
            Irp->IoStatus.Information = sizeof( PAR_QUERY_INFORMATION );
        }
        break;

    case IOCTL_PAR_QUERY_RAW_DEVICE_ID :

        // We always read the Device Id in Nibble Mode.
        NtStatus = SppQueryDeviceId(Pdx,
                                    Irp->AssociatedIrp.SystemBuffer,
                                    IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
                                    &IdLength, TRUE);

        Irp->IoStatus.Status = NtStatus;

        if (NT_SUCCESS(NtStatus)) {
            Irp->IoStatus.Information = IdLength;
        } else {
            Irp->IoStatus.Information = 0;
        }
        break;

    case IOCTL_PAR_QUERY_DEVICE_ID :

        // We always read the Device Id in Nibble Mode.
        NtStatus = SppQueryDeviceId(Pdx,
                                    Irp->AssociatedIrp.SystemBuffer,
                                    IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
                                    &IdLength, FALSE);

        Irp->IoStatus.Status = NtStatus;

        if( NT_SUCCESS( NtStatus ) ) {
            DD((PCE)Pdx,DDT,"IOCTL_PAR_QUERY_ID - SUCCESS - size = %d\n", IdLength);
            // Include terminating NULL in the string to copy back to user buffer
            Irp->IoStatus.Information = IdLength + sizeof(CHAR);
        } else if( NtStatus == STATUS_BUFFER_TOO_SMALL) {
            DD((PCE)Pdx,DDT,"IOCTL_PAR_QUERY_ID - FAIL - BUFFER_TOO_SMALL - supplied= %d, required=%d\n",
                                 IrpSp->Parameters.DeviceIoControl.OutputBufferLength, IdLength);
            Irp->IoStatus.Information = 0;
        } else {
            DD((PCE)Pdx,DDT,"IOCTL_PAR_QUERY_ID - FAIL - QUERY ID FAILED\n");
            Irp->IoStatus.Information = 0;
        }
        break;

    case IOCTL_PAR_QUERY_DEVICE_ID_SIZE :

        //
        // Read the first two bytes of the Nibble Id, add room for the terminating NULL and
        // return this to the caller.
        //
        NtStatus = SppQueryDeviceId(Pdx, NULL, 0, &IdLength, FALSE);

        if (NtStatus == STATUS_BUFFER_TOO_SMALL) {

            DD((PCE)Pdx,DDT,"IOCTL_PAR_QUERY_DEVICE_ID_SIZE - size required = %d\n", IdLength);

            Irp->IoStatus.Status = STATUS_SUCCESS;

            Irp->IoStatus.Information =
                sizeof(PAR_DEVICE_ID_SIZE_INFORMATION);

            // include space for terminating NULL
            ((PPAR_DEVICE_ID_SIZE_INFORMATION)
                Irp->AssociatedIrp.SystemBuffer)->DeviceIdSize = IdLength + sizeof(CHAR);

        } else {

            Irp->IoStatus.Status      = NtStatus;
            Irp->IoStatus.Information = 0;
        }
        break;

    case IOCTL_PAR_PING :

        // We need to do a quick terminate and negotiate of the current modes
        NtStatus = ParPing(Pdx);
        DD((PCE)Pdx,DDT,"ParDeviceIo:IOCTL_PAR_PING\n");
        Irp->IoStatus.Status      = NtStatus;
        Irp->IoStatus.Information = 0;
        break;
        
    case IOCTL_INTERNAL_DISCONNECT_IDLE :

        if ((Pdx->Connected) &&
            (afpForward[Pdx->IdxForwardProtocol].fnDisconnect)) {
            
            DD((PCE)Pdx,DDT,"ParDeviceIo:IOCTL_INTERNAL_DISCONNECT_IDLE: Calling afpForward.fnDisconnect\n");
            afpForward[Pdx->IdxForwardProtocol].fnDisconnect (Pdx);
        }
        
        Irp->IoStatus.Status      = STATUS_SUCCESS;
        Irp->IoStatus.Information = 0;
        break;

    case IOCTL_IEEE1284_NEGOTIATE:
        {
            PPARCLASS_NEGOTIATION_MASK  ppnmMask = (PPARCLASS_NEGOTIATION_MASK)Irp->AssociatedIrp.SystemBuffer;

            ParTerminate(Pdx);
            Irp->IoStatus.Status = IeeeNegotiateMode(Pdx, ppnmMask->usReadMask, ppnmMask->usWriteMask);

            if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(PARCLASS_NEGOTIATION_MASK)) {
                DD((PCE)Pdx,DDT, "ParDeviceIo: IOCTL_IEEE1284_NEGOTIATE Passed.\n");
                ppnmMask->usReadMask  = arpReverse[Pdx->IdxReverseProtocol].Protocol;
                ppnmMask->usWriteMask = afpForward[Pdx->IdxForwardProtocol].Protocol;
                Irp->IoStatus.Information = sizeof (PARCLASS_NEGOTIATION_MASK);
            } else {
                DD((PCE)Pdx,DDT, "ParDeviceIo: IOCTL_IEEE1284_NEGOTIATE failed.\n");
                Irp->IoStatus.Information = 0;
            }
        }
        break;

    case IOCTL_PAR_GET_DEVICE_CAPS :

        Pdx->BadProtocolModes = *((USHORT *) Irp->AssociatedIrp.SystemBuffer);            
        IeeeDetermineSupportedProtocols(Pdx);
        *((USHORT *) Irp->AssociatedIrp.SystemBuffer) = Pdx->ProtocolModesSupported;
        Irp->IoStatus.Information = sizeof(Pdx->ProtocolModesSupported);
        Irp->IoStatus.Status = STATUS_SUCCESS;
        break;

    case IOCTL_PAR_SET_READ_ADDRESS:
        {
            PUCHAR pAddress = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
            
            if (Pdx->ReverseInterfaceAddress != *pAddress) {
                
                Pdx->ReverseInterfaceAddress = *pAddress;
                Pdx->SetReverseAddress = TRUE;
            }
            
            Irp->IoStatus.Information = 0;
            Irp->IoStatus.Status = STATUS_SUCCESS;
        }
        break;

    case IOCTL_PAR_SET_WRITE_ADDRESS :
        {
            PUCHAR pAddress = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
            NtStatus = STATUS_SUCCESS;

            if (Pdx->ForwardInterfaceAddress != *pAddress) {
        
                Pdx->ForwardInterfaceAddress = *pAddress;
                
                if (Pdx->Connected) {
                    if (afpForward[Pdx->IdxForwardProtocol].fnSetInterfaceAddress) {
                        
                        if (Pdx->CurrentPhase != PHASE_FORWARD_IDLE &&
                            Pdx->CurrentPhase != PHASE_FORWARD_XFER) {
                            NtStatus = ParReverseToForward(Pdx);
                        }
                        
                        if (NT_SUCCESS(NtStatus)) {
                            NtStatus  = afpForward[Pdx->IdxForwardProtocol].fnSetInterfaceAddress(
                                Pdx,
                                Pdx->ForwardInterfaceAddress
                                );
                        }
                        
                        if (NT_SUCCESS(NtStatus)) {
                            Pdx->SetForwardAddress = FALSE;
                            Pdx->SetReverseAddress = FALSE;
                            Pdx->ReverseInterfaceAddress = *pAddress;
                        } else {
                            Pdx->SetForwardAddress = TRUE;
                            DD((PCE)Pdx,DDE,"ParDeviceIo: IOCTL_PAR_SET_WRITE_ADDRESS Failed\n");
                        }
                    } else {
                        DD((PCE)Pdx,DDE, "ParDeviceIo: Someone called IOCTL_PAR_SET_WRITE_ADDRESS.\n");
                        DD((PCE)Pdx,DDE, "ParDeviceIo: You don't have a fnSetInterfaceAddress.\n");
                        DD((PCE)Pdx,DDE, "ParDeviceIo: Either IEEE1284.c has wrong info or your caller is in error!\n");
                        NtStatus = STATUS_UNSUCCESSFUL;
                    }    
                } else {
                    Pdx->SetForwardAddress = TRUE;
                }
            }
            
            Irp->IoStatus.Information = 0;
            Irp->IoStatus.Status = NtStatus;
        }
        break;

    case IOCTL_INTERNAL_LOCK_PORT :

        ParpIoctlThreadLockPort(Pdx);
        break;

    case IOCTL_INTERNAL_UNLOCK_PORT :

        ParpIoctlThreadUnlockPort(Pdx);
        break;
        
    case IOCTL_INTERNAL_LOCK_PORT_NO_SELECT:

        DD((PCE)Pdx,DDT, "ParDeviceIo - IOCTL_INTERNAL_LOCK_PORT_NO_SELECT\n");
        Pdx->AllocatedByLockPort  = TRUE;
        Irp->IoStatus.Status      = STATUS_SUCCESS;
        Irp->IoStatus.Information = 0;
        break;

    case IOCTL_INTERNAL_UNLOCK_PORT_NO_DESELECT:

        DD((PCE)Pdx,DDT, "ParDeviceIo - IOCTL_INTERNAL_UNLOCK_PORT_NO_DESELECT\n");
        Pdx->AllocatedByLockPort  = FALSE;
        PptAssert(!Pdx->Connected && !Pdx->AllocatedByLockPort);
        Irp->IoStatus.Status      = STATUS_SUCCESS;
        Irp->IoStatus.Information = 0;
        break;

    case IOCTL_SERIAL_SET_TIMEOUTS:
        {
            PSERIAL_TIMEOUTS ptoNew = Irp->AssociatedIrp.SystemBuffer;

            //
            // The only other thing let through is setting
            // the timer start.
            //
            
            Pdx->TimerStart = ptoNew->WriteTotalTimeoutConstant / 1000;
            Irp->IoStatus.Status  = STATUS_SUCCESS;
        }
        break;
    
    case IOCTL_INTERNAL_PARDOT3_CONNECT:
        DD((PCE)Pdx,DDT,"IOCTL_INTERNAL_PARDOT3_CONNECT - Dispatch\n");
        Irp->IoStatus.Status  = ParDot3Connect(Pdx);
        Irp->IoStatus.Information = 0;
        break;
    case IOCTL_INTERNAL_PARDOT3_DISCONNECT:
        DD((PCE)Pdx,DDT,"IOCTL_INTERNAL_PARDOT3_DISCONNECT - Dispatch\n");
        Irp->IoStatus.Status  = ParDot3Disconnect(Pdx);
        Irp->IoStatus.Information = 0;
        break;
    case IOCTL_INTERNAL_PARDOT3_SIGNAL:
        if( Pdx->IdxReverseProtocol != NIBBLE_MODE ) {
            PKEVENT Event;// = (PKEVENT)Irp->AssociatedIrp.SystemBuffer;
            
            RtlCopyMemory(&Event, Irp->AssociatedIrp.SystemBuffer, sizeof(PKEVENT));
            
            ASSERT_EVENT(Event);
            
            DD((PCE)Pdx,DDT,"IOCTL_INTERNAL_PARDOT3_SIGNAL - Dispatch. Event [%x]\n", Event);
            
            Pdx->P12843DL.Event        = Event;
            Pdx->P12843DL.bEventActive = TRUE;
            Irp->IoStatus.Status = STATUS_SUCCESS;
        } else {
            // don't use signalling in NIBBLE mode - rely on dot4 polling
            Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
        }
        Irp->IoStatus.Information = 0;
        break;
    case IOCTL_INTERNAL_PARDOT3_RESET:
        DD((PCE)Pdx,DDT,"IOCTL_INTERNAL_PARDOT3_RESET - Dispatch\n");
        if (Pdx->P12843DL.fnReset)
            Irp->IoStatus.Status = ((PDOT3_RESET_ROUTINE) (Pdx->P12843DL.fnReset))(Pdx);
        else
            Irp->IoStatus.Status  = STATUS_SUCCESS;
        Irp->IoStatus.Information = 0;
        break;
    default:

        //
        // unrecognized IOCTL? - we should never get here because the 
        //   dispatch routines should have filtered this out
        //

        // probably harmless, but we want to know if this happens
        //   so we can fix the problem elsewhere
        ASSERTMSG("Unrecognized IOCTL in ParDeviceIo()\n",FALSE);

        Irp->IoStatus.Status  = STATUS_UNSUCCESSFUL;
    }

    return;
}

⌨️ 快捷键说明

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