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

📄 fdoioctl.c

📁 鼠标Windows驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
        
        //
        // 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 = PptClearChipMode (Extension, ((PPARALLEL_CHIP_MODE)Irp->AssociatedIrp.SystemBuffer)->ModeFlags);
        } // end check input buffer
        
        break;
        
    case IOCTL_INTERNAL_INIT_1284_3_BUS:

        // Initialize the 1284.3 bus

        // RMT - Port is locked out already?

        Extension->PnpInfo.Ieee1284_3DeviceCount = PptInitiate1284_3( Extension );

        Status = STATUS_SUCCESS;
        
        break;
            
    case IOCTL_INTERNAL_SELECT_DEVICE:
        // Takes a flat namespace Id for the device, also acquires the
        //   port unless HAVE_PORT_KEEP_PORT Flag is set
        

        if ( IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(PARALLEL_1284_COMMAND) ) {

            Status = STATUS_BUFFER_TOO_SMALL;
            
        } else {
            
            if ( Irp->Cancel ) {
                Status = STATUS_CANCELLED;
            } else {
                // Call Function to try to select device
                Status = PptTrySelectDevice( Extension, Irp->AssociatedIrp.SystemBuffer );

                IoAcquireCancelSpinLock(&CancelIrql);
                if ( Status == STATUS_PENDING ) {
                    PptSetCancelRoutine(Irp, PptCancelRoutine);
                    IoMarkIrpPending(Irp);
                    InsertTailList(&Extension->WorkQueue, &Irp->Tail.Overlay.ListEntry);
                }
                IoReleaseCancelSpinLock(CancelIrql);
            }
        }
        
        break;
        
    case IOCTL_INTERNAL_DESELECT_DEVICE:
        // Deselects the current device, also releases the port unless HAVE_PORT_KEEP_PORT Flag set
        
        if( IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(PARALLEL_1284_COMMAND) ) {
            
            Status = STATUS_BUFFER_TOO_SMALL;
            
        } else {
            
            Status = PptDeselectDevice( Extension, Irp->AssociatedIrp.SystemBuffer );

        }
        break;
        
    case IOCTL_INTERNAL_PARALLEL_CONNECT_INTERRUPT:
        
        {
            //
            // Verify that this interface has been explicitly enabled via the registry flag, otherwise
            //   FAIL the request with STATUS_UNSUCCESSFUL
            //
            ULONG EnableConnectInterruptIoctl = 0;
            PptRegGetDeviceParameterDword( Extension->PhysicalDeviceObject, 
                                           (PWSTR)L"EnableConnectInterruptIoctl", 
                                           &EnableConnectInterruptIoctl );
            if( 0 == EnableConnectInterruptIoctl ) {
                Status = STATUS_UNSUCCESSFUL;
                goto targetExit;
            }
        }


        //
        // This interface has been explicitly enabled via the registry flag, process request.
        //

        if (IrpSp->Parameters.DeviceIoControl.InputBufferLength  < sizeof(PARALLEL_INTERRUPT_SERVICE_ROUTINE) ||
            IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(PARALLEL_INTERRUPT_INFORMATION)) {
            
            Status = STATUS_BUFFER_TOO_SMALL;
            
        } else {
            
            IsrInfo = Irp->AssociatedIrp.SystemBuffer;
            InterruptInfo = Irp->AssociatedIrp.SystemBuffer;
            IoAcquireCancelSpinLock(&CancelIrql);
            
            if (Extension->InterruptRefCount) {
                
                ++Extension->InterruptRefCount;
                IoReleaseCancelSpinLock(CancelIrql);
                Status = STATUS_SUCCESS;
                
            } else {
                
                IoReleaseCancelSpinLock(CancelIrql);
                Status = PptConnectInterrupt(Extension);
                if (NT_SUCCESS(Status)) {
                    IoAcquireCancelSpinLock(&CancelIrql);
                    ++Extension->InterruptRefCount;
                    IoReleaseCancelSpinLock(CancelIrql);
                }
            }
            
            if (NT_SUCCESS(Status)) {
                
                IsrListEntry = ExAllocatePool(NonPagedPool, sizeof(ISR_LIST_ENTRY));
                
                if (IsrListEntry) {
                    
                    IsrListEntry->ServiceRoutine           = IsrInfo->InterruptServiceRoutine;
                    IsrListEntry->ServiceContext           = IsrInfo->InterruptServiceContext;
                    IsrListEntry->DeferredPortCheckRoutine = IsrInfo->DeferredPortCheckRoutine;
                    IsrListEntry->CheckContext             = IsrInfo->DeferredPortCheckContext;
                    
                    // Put the ISR_LIST_ENTRY onto the ISR list.
                    
                    ListContext.List = &Extension->IsrList;
                    ListContext.NewEntry = &IsrListEntry->ListEntry;
                    KeSynchronizeExecution(Extension->InterruptObject, PptSynchronizedQueue, &ListContext);
                    
                    InterruptInfo->InterruptObject                 = Extension->InterruptObject;
                    InterruptInfo->TryAllocatePortAtInterruptLevel = PptTryAllocatePortAtInterruptLevel;
                    InterruptInfo->FreePortFromInterruptLevel      = PptFreePortFromInterruptLevel;
                    InterruptInfo->Context                         = Extension;
                    
                    Irp->IoStatus.Information = sizeof(PARALLEL_INTERRUPT_INFORMATION);
                    Status = STATUS_SUCCESS;
                    
                } else {
                    Status = STATUS_INSUFFICIENT_RESOURCES;
                }
            }
        }
        break;
        
    case IOCTL_INTERNAL_PARALLEL_DISCONNECT_INTERRUPT:
        
        if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
            sizeof(PARALLEL_INTERRUPT_SERVICE_ROUTINE)) {
            
            Status = STATUS_BUFFER_TOO_SMALL;
            
        } else {
            
            IsrInfo = Irp->AssociatedIrp.SystemBuffer;
            
            // Take the ISR out of the ISR list.
            
            IoAcquireCancelSpinLock(&CancelIrql);
            
            if (Extension->InterruptRefCount) {
                
                IoReleaseCancelSpinLock(CancelIrql);
                
                DisconnectContext.Extension = Extension;
                DisconnectContext.IsrInfo = IsrInfo;
                
                if (KeSynchronizeExecution(Extension->InterruptObject, PptSynchronizedDisconnect, &DisconnectContext)) {
                    
                    Status = STATUS_SUCCESS;
                    IoAcquireCancelSpinLock(&CancelIrql);
                    
                    if (--Extension->InterruptRefCount == 0) {
                        DisconnectInterrupt = TRUE;
                    } else {
                        DisconnectInterrupt = FALSE;
                    }
                    
                    IoReleaseCancelSpinLock(CancelIrql);
                    
                } else {
                    Status = STATUS_INVALID_PARAMETER;
                    DisconnectInterrupt = FALSE;
                }
                
            } else {
                IoReleaseCancelSpinLock(CancelIrql);
                DisconnectInterrupt = FALSE;
                Status = STATUS_INVALID_PARAMETER;
            }
            
            //
            // Disconnect the interrupt if appropriate.
            //
            if (DisconnectInterrupt) {
                PptDisconnectInterrupt(Extension);
            }
        }
        break;

    default:
        
        DD((PCE)Extension,DDE,"PptDispatchDeviceControl - default case - invalid/unsupported request\n");
        Status = STATUS_INVALID_PARAMETER;
        break;
    }
    
targetExit:

    if( Status != STATUS_PENDING ) {
        PptReleaseRemoveLock(&Extension->RemoveLock, Irp);
        P4CompleteRequest( Irp, Status, Irp->IoStatus.Information );
    }
    
    return Status;
}

⌨️ 快捷键说明

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