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

📄 usbfx2lk_pnp.cpp

📁 基于vc++6.0环境的cypress USB 驱动源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        // result of receiving the QUERY_STOP IRP).  After all in-
        // progress requests are complete, we return our resources
        // and wait for further instructions from the PnP Manager (
        // which better include a START_DEVICE someplace down the line!).
        // 
        // While in this state, any IRPs we receive will be queued
        // for processing until we get A START_DEVICE.
        //
        case (STATE_STOP_PENDING + IRP_MN_STOP_DEVICE): {

            //
            // We're stopped...
            //
            OsrUpdateDeviceState(devExt, STATE_STOPPED);

            //
            // We need to cancel our outstanding wait wake operation if there
            //  is one
            //
            if(devExt->WaitWakeEnable) {
                CancelWaitWake(devExt);
            }

            //
            // Return any allocated resources...
            //
            OsrReturnResources(devExt);

            //
            // Indicate that we've successfully processed the IRP.
            //  Note that we can't fail it (we agreed to the 
            //  stop in the QUERY_STOP case)...
            //
            Irp->IoStatus.Status = STATUS_SUCCESS;
            
            //
            // Don't wait for the Irp to finish, don't set a completion 
            // routine and don't complete the Irp! Just foist it off to the
            // PDO and propogate the returned status
            //
            IoSkipCurrentIrpStackLocation(Irp);
            
            OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_PNP_INFO, 
                ("OsrPnp: Finished! Leaving with state %s\n",
                OsrPrintState(devExt)));
            
            status = IoCallDriver(devExt->DeviceToSendIrpsTo, Irp);

            //
            // We're done with this request
            //
            OsrDecrementOutstandingIoCount(devExt,__FILE__,__LINE__);

            return status;
            
        }
            
        //
        // STATE:   STARTED
        // IRP_MN:  _QUERY_REMOVE
        //
        // We're here because the PnP Manager wants to "nicely"
        // remove our device.  This is the orderly way the PnP Manager
        // handles device disconnections (as opposed to doing a 
        // SURPRISE_REMOVAL).
        //
        // If we decide it's OK to remove the device, what we do here 
        // is (a) change the state of the device such that newly arriving 
        // requests will be rejected, (b) stall the queues so no new I/O
        // with be started and wait for all in progress I/O to complete on 
        // the device, and (c) pass the request on down.
        //
        case (STATE_STARTED + IRP_MN_QUERY_REMOVE_DEVICE): {
        
            //
            // WE process this request FIRST
            //
 
            //
            // See if we're OK with removing the device at this point.
            // We do NOT actually RETURN the resources here... we
            // just affirm or deny that we're OK with returning them.
            //
            status = OsrCanRemoveDevice(devExt, Irp);
            
            if (!NT_SUCCESS(status)) {
                
                //
                // Nope...We can't remove the device
                //  so there's no need to pass it 
                //  down to see if anyone else can remove.
                //  Just complete the Irp and return...
                //
                Irp->IoStatus.Status      = status;
                Irp->IoStatus.Information = 0;
                
                IoCompleteRequest(Irp, IO_NO_INCREMENT);

                //
                // We're done with this request
                //
                OsrDecrementOutstandingIoCount(devExt,__FILE__,__LINE__);
                
                OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_PNP_INFO, 
                    ("OsrPnp: Finished! Leaving with state %s\n",
                    OsrPrintState(devExt)));
                
                
                return status;
                
            }
            
            //
            // We're cool with being removed...
            //
            
            //
            // We handle this request before the bus driver
            //

            //
            // Power the device up if it isn't already. 
            //  Do this before changing the device's 
            //  PnP state.
            //
            SSPowerDeviceIfSuspended(devExt);

            //
            // If enabled, disable selective suspend. We'll
            //  enable again if we get a cancel
            //
            DisableSelectiveSuspend(devExt);


            //
            // Set new state -- This state results in any new
            // requests received at our dispath entry points 
            // being QUEUED
            //
            OsrUpdateDeviceState(devExt, STATE_REMOVE_PENDING);

            //
            // Wait for any in progress I/O to finish. 
            //  Note that even though this is called
            //  OsrWaitForStop, it is the right function
            //  to call here because it waits for any
            //  in progress I/O to finish, but having
            //  I/O in the queues is fine. This is what 
            //  we want since we might get a CANCEL_REMOVE,
            //  in which case we'll go back and process any
            //  queued up requests...
            //
            OsrDecrementOutstandingIoCount(devExt,__FILE__,__LINE__);
            OsrWaitForStop(devExt);

            //
            // Replace status code that's in the IRP to indicate our
            // opinion about stopping the device.  If we're
            // OK with being removed this HAS to be
            // STATUS_SUCCESS.
            //
            Irp->IoStatus.Status = STATUS_SUCCESS;
            
            //
            // Pass this request on down to the next driver
            //
            IoSkipCurrentIrpStackLocation(Irp);
            
            OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_PNP_INFO, 
                ("OsrPnp: Finished! Leaving with state %s\n",
                OsrPrintState(devExt)));
            
            status = IoCallDriver(devExt->DeviceToSendIrpsTo, Irp);

            //
            // We're done with this request
            //
            return status;

        }

        //
        // STATE:   REMOVE_PENDING
        // IRP_MN:  _CANCEL_REMOVE_DEVICE
        //
        // We're here because we've already received a QUERY_REMOVE,
        // that we've agreed to.  We've completed any pending I/O
        // requests.  Now we've received a CANCEL_REMOVE_DEVICE
        // IRP, that sort of says "never mind" about that remove.
        //
        // We (hopefully) restart our queues and return to the Started 
        // state 
        //
        case (STATE_REMOVE_PENDING + IRP_MN_CANCEL_REMOVE_DEVICE): {
            
            //
            // This is a BUS FIRST Irp. 
            //
            status = OsrForwardIrpSynchronous(devExt,Irp);
                
                
            if (NT_SUCCESS(status)) {
                
                //
                // We're now back to a STARTED state
                //
                OsrUpdateDeviceState(devExt, STATE_STARTED);
                
                //
                // Go and start any I/O that may have been
                //  queued while in the REMOVE_PENDING 
                //  state...
                //
                OsrProcessQueuedRequests(devExt);
                    
            } else {
                
                //
                // If we're here one of the drivers below us is
                //  busted, you can never fail this Irp. We'll just
                //  stay right where we are and break into a debugger
                //  if possible
                //
                OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_PNP_INFO, 
                    ("OsrPnp: Lower level device FAILED CANCEL_REMOVE?? Returned status 0x%8.8x (%s)\n",
                    Irp->IoStatus.Status, OsrNtStatusToString(Irp->IoStatus.Status)));
                

                //
                // Use KdBreakPoint instead of DbgBreakPoint so that 
                //  we only break in the checked build...
                //
                KdBreakPoint();
                
            }

            //
            // Enable selective suspend again (if enabled)
            //
            EnableSelectiveSuspend(devExt);


            //
            // Complete the Irp with whatever status the lower driver returned
            //
            Irp->IoStatus.Status      = status;
            Irp->IoStatus.Information = 0;
            
            
            //
            // OsrForwardIrpSynchronous is just a nice little
            //  wrapper that sets a completion routine, calls
            //  the next lowest driver, waits, and then reclaims the Irp
            //  for us in the completion routine by returning
            //  STATUS_MORE_PROCESSING_REQUIRED (or calls 
            //  IoForwardIrpSynchronously to do all of that if 
            //  we're built for XP and later). Just as if we
            //  had carried these steps out by ourselves, we now
            //  own the Irp and need to call IoCompleteRequest on it
            //  to finish processing. 
            //
            IoCompleteRequest(Irp, IO_NO_INCREMENT);

            //
            // We're done with this request
            //
            OsrDecrementOutstandingIoCount(devExt,__FILE__,__LINE__);
            
            OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_PNP_INFO, 
                ("OsrPnp: Finished! Leaving with state %s\n",
                OsrPrintState(devExt)));
            
            return status;

        }
            
        //
        // STATE:   STOPPED, STARTED, _STOP_PENDING, or _REMOVE_PENDING
        // IRP_MN:  _SURPRISE_REMOVAL
        //
        // We're here when the device is forcibly removed.  The PnP 
        // Manager will send us a remove device IRP when all open handles
        // are close and when we're supposed to actually detach and 
        // delete the device object
        //
        case (STATE_STARTED        + IRP_MN_SURPRISE_REMOVAL):
        case (STATE_STOPPED        + IRP_MN_SURPRISE_REMOVAL):
        case (STATE_STOP_PENDING   + IRP_MN_SURPRISE_REMOVAL):
        case (STATE_REMOVE_PENDING + IRP_MN_SURPRISE_REMOVAL): {
            
           
            //
            // A surprise removed device must still handle subsequent
            // close, clean-up, power and PnP requests. A removed device
            // handles NO subsequent requests
            //

            //
            // Power the device up if it isn't already. 
            //  Do this before changing the device's 
            //  PnP state.
            //
            //  Though the device doesn't exist anymore, we're 
            //  doing this to indicate to the hub that it
            //  should power the port that the device 
            //  was plugged into. 
            //
            SSPowerDeviceIfSuspended(devExt);

            //
            // If enabled, disable selective suspend
            //
            DisableSelectiveSuspend(devExt);

            //
            // Update our Device State
            //
            OsrUpdateDeviceState(devExt, STATE_SURPRISE_REMOVED);
            
            //
            // Because we registered a device interface we need to disable
            //  it now...
            //
            status = IoSetDeviceInterfaceState(&devExt->InterfaceName,
                                             FALSE);
            
            if (!NT_SUCCESS(status)) {
                
                //
                // Eh, big deal. Just print out some info and
                //  keep going...
                //
                OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_PNP_INFO, 
                    ("OsrPnp: IoSetDeviceInterfaceState failed! Returned status 0x%8.8x (%s)\n",
                    status, OsrNtStatusToString(status)));
                
            }
            
            //
            // Fail any queued I/O requests...
            //
            OsrClearQueues(devExt);
            

            //
            // Tell the thread that we have out there to terminate itself
            //
            KeSetEvent(&devExt->SSSubmissionThreadTerminateEvent,
                       EVENT_INCREMENT, FALSE);
    
            //
            // And wait for the thread to terminate
            //
            (VOID)OsrWaitForSingleObject(devExt->SSSubmissionThreadObject);

            //
            // Close the HANDLE that we opened to the thread
            //
            ZwClose(devExt->SSSubmissionThread);

            //
            // And drop our reference to the object
            //
            ObDereferenceObject(devExt->SSSubmissionThreadObject);

            //
            // We need to cancel our outstanding wait wake operation if there
            //  is one
            //
            if(devExt->WaitWakeEnable) {
                CancelWaitWake(devExt);
            }

⌨️ 快捷键说明

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