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

📄 testpnp.c

📁 usb开发的资料!!USB标准
💻 C
📖 第 1 页 / 共 2 页
字号:
// ===================================================================

//

//      testpnp.c

//

//      rev 1.0 beta

//

//      this module handles USB PnP calls.

//

//      USB device driver for USB Device Example 

//      kernel mode driver 

//

//

//      to be compiled with 

//      - Windows 98 Beta 3 DDK 

//     

// ===================================================================



#include <wdm.h>

#include "test98.h"

#include "stdio.h"



// ==================================================================

NTSTATUS

Test98_AddDevice(

    IN PDRIVER_OBJECT DriverObject,

    IN PDEVICE_OBJECT PhysicalDeviceObject

    )

/*++

    

    to create and initialize our FDO, set things up...



    DeviceObject - Device object representing the new FDO.



    DriverObject - This very self referenced driver.



--*/

{

    NTSTATUS            status;

    PDEVICE_OBJECT      deviceObject;

    PFDO_DEVICE_DATA    deviceData;

    UNICODE_STRING      deviceNameUni;

    PWCHAR              deviceName;

    ULONG               nameLength;



    UNICODE_STRING      pdoUniName;

    WCHAR               pdoName[] = L"\\Device\\Test-0" ;  // DeviceNameBuffer

    

    WCHAR DeviceLinkBuffer[] = L"\\DosDevices\\Test-0";

    UNICODE_STRING  DeviceLinkUnicodeString;   



    RtlInitUnicodeString (&pdoUniName, pdoName);

        

    status = IoCreateDevice (

                    DriverObject,  // our driver object

                    sizeof (FDO_DEVICE_DATA), // device object extension size

                    

                    &pdoUniName,  

                    

                    FILE_DEVICE_UNKNOWN,   

                    0,          // No special characteristics

                    FALSE,      

                    &deviceObject); // The device object created



    if (NT_SUCCESS (status)) {



        RtlInitUnicodeString (&DeviceLinkUnicodeString, 

                                DeviceLinkBuffer);



        status = IoCreateSymbolicLink(&DeviceLinkUnicodeString,

                        &pdoUniName);                                



        deviceData = (PFDO_DEVICE_DATA) deviceObject->DeviceExtension;

        RtlFillMemory (deviceData, sizeof (FDO_DEVICE_DATA), 0);



        deviceData->IsFDO = TRUE;

        deviceData->DebugLevel = TEST_DEFAULT_DEBUG_OUTPUT_LEVEL;

        deviceData->Self = deviceObject;

 

        KeInitializeSpinLock (&deviceData->Spin);



        deviceData->Removed = FALSE;

        

        InitializeListHead (&deviceData->PDOs);



        // Set the PDO for use with PlugPlay functions

        deviceData->UnderlyingPDO = PhysicalDeviceObject;



        // Attach our driver to the device stack.

        deviceData->TopOfStack = IoAttachDeviceToDeviceStack (

                                        deviceObject,

                                        PhysicalDeviceObject);



        // Bias outstanding request to 1 so that we can look for a

        // transition to zero when processing the remove device PlugPlay IRP.

        

        deviceData->OutstandingIO = 1;



        KeInitializeEvent(&deviceData->RemoveEvent,

                          SynchronizationEvent,

                          FALSE); // initialized to not signalled



        deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

        deviceObject->Flags |= DO_POWER_PAGABLE;



        // register device functionality

        status = IoRegisterDeviceInterface (

                    PhysicalDeviceObject,

                    (LPGUID) &GUID_TEST_DEVICE,

                    NULL, // No ref string

                    &deviceData->DevClassAssocName);



        status = IoSetDeviceInterfaceState (

                        &deviceData->DevClassAssocName,

                        TRUE);



        }



return status;



}



// ==================================================================

NTSTATUS

Test98_FDO_PnPComplete (

    IN PDEVICE_OBJECT   DeviceObject,

    IN PIRP             Pirp,

    IN PVOID            Context

    );



// ==================================================================

NTSTATUS

Test98_PnP (

    IN PDEVICE_OBJECT   DeviceObject,

    IN PIRP             Irp

    )

/*++



    Handles Major PnP IRPS...



--*/

{

    PIO_STACK_LOCATION      irpStack;

    NTSTATUS                status;

    PCOMMON_DEVICE_DATA     commonData;

    KIRQL                   oldIrq;



    PAGED_CODE ();



    status = STATUS_SUCCESS;

    irpStack = IoGetCurrentIrpStackLocation (Irp);

    ASSERT (IRP_MJ_PNP == irpStack->MajorFunction);



    commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension;



    

    status = Test98_FDO_PnP (

                    DeviceObject,

                    Irp,

                    irpStack,

                    (PFDO_DEVICE_DATA) commonData);

    

    return status;



}



// ==================================================================

NTSTATUS

Test98_FDO_PnP (

    IN PDEVICE_OBJECT       DeviceObject,

    IN PIRP                 Irp,

    IN PIO_STACK_LOCATION   IrpStack,

    IN PFDO_DEVICE_DATA     DeviceData

    )

/*++



    Handles requests from the PlugPlay system for the FDO



--*/

{

    NTSTATUS    status;

    KIRQL       oldIrq;

    KEVENT      event;

    ULONG       length;

    ULONG       i;

    PLIST_ENTRY entry;

    PPDO_DEVICE_DATA    pdoData;

    PDEVICE_RELATIONS   relations;

    PIO_STACK_LOCATION  stack;



    PAGED_CODE ();



    status = Test98_IncIoCount (DeviceData);

    if (!NT_SUCCESS (status)) {

        Irp->IoStatus.Information = 0;

        Irp->IoStatus.Status = status;

        IoCompleteRequest (Irp, IO_NO_INCREMENT);

        return status;

    }



    stack = IoGetCurrentIrpStackLocation (Irp);



    switch (IrpStack->MinorFunction) {

    case IRP_MN_START_DEVICE:

        // PnP manager send this IPR after assigning resoureces to the device; 

        // the device may have been recently numerate and being started 

        // for the first time 



        if (DeviceData->Started) {

            status = STATUS_SUCCESS;

            break;

        }



        Test98_KdPrint (DeviceData, TEST_DBG_PNP_TRACE, ("Start Device\n"));



        KeInitializeEvent (&event, NotificationEvent, FALSE);

        IoCopyCurrentIrpStackLocationToNext (Irp);



        IoSetCompletionRoutine (Irp,

                                Test98_FDO_PnPComplete,

                                &event,

                                TRUE,

                                TRUE,

                                TRUE);



        status = IoCallDriver (DeviceData->TopOfStack, Irp);



        if (STATUS_PENDING == status) {

            // wait for it...



            status = KeWaitForSingleObject (&event,

                                            Executive,

                                            KernelMode,

                                            FALSE, // Not allertable

                                            NULL); // No timeout structure



            ASSERT (STATUS_SUCCESS == status);



            status = Irp->IoStatus.Status;

        }



        if (NT_SUCCESS(status)) {

            //

            // Do what ever after device started

            //



            if ((NULL == stack->Parameters.StartDevice.AllocatedResources) ||

                (NULL == stack->Parameters.StartDevice.AllocatedResourcesTranslated)) {



                status = STATUS_INSUFFICIENT_RESOURCES;

                break;

            }

            status = Test98_StartFdo (DeviceData,

                                    &stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList,

                                    &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList);





            if (NT_SUCCESS (status)) {

                DeviceData->Started = TRUE;

            }

        }



        //

        // We must now complete the IRP, since we stopped it in the

        // completetion routine with MORE_PROCESSING_REQUIRED.

        //



        Irp->IoStatus.Information = 0;

        break;



    case IRP_MN_QUERY_STOP_DEVICE:

        Test98_KdPrint (DeviceData, TEST_DBG_PNP_TRACE, ("Query Stop Device\n"));



        // This occurs during shutdown when user explicitly requesting

        // the service to be stopped

        //        

       

        if (DeviceData->NumPDOs) {

            status = STATUS_UNSUCCESSFUL;

        } else {

            status = STATUS_SUCCESS;

        }



        Irp->IoStatus.Status = status;

        IoSkipCurrentIrpStackLocation (Irp);

        status = IoCallDriver (DeviceData->TopOfStack, Irp);



        Test98_DecIoCount (DeviceData);

        return status;



    case IRP_MN_STOP_DEVICE:

        Test98_KdPrint (DeviceData, TEST_DBG_PNP_TRACE, ("Stop Device\n"));



        // PnP manager sends this IPR to stop a device so that it can reconfigure

        // its resources.  sends this only after IRP_MN_QUERY_STOP_DEVICE

        // completed successfully

        //

        if (DeviceData->Started) {

            //

            // Free resources given by start device.

            //

            if (DeviceData->MappedPorts) {

                MmUnmapIoSpace (DeviceData->TestPortAddress, 1);

            }

        }

        DeviceData->Started = FALSE;



        //

        // don't need a completion routine so fire and forget.

        //

        Irp->IoStatus.Status = STATUS_SUCCESS;

        IoSkipCurrentIrpStackLocation (Irp);

        status = IoCallDriver (DeviceData->TopOfStack, Irp);



        Test98_DecIoCount (DeviceData);

        return status;



    case IRP_MN_REMOVE_DEVICE:

        Test98_KdPrint (DeviceData, TEST_DBG_PNP_TRACE, ("Remove Device\n"));



        //

        // PnP manager uses this IRP to dirct drivers to remove a device

        //

        DeviceData->Removed = TRUE;



        //

        // Complete any outstanding IRPs queued by the driver here.

        //



        IoSetDeviceInterfaceState (&DeviceData->DevClassAssocName, FALSE);



        //

        // complete any outstanding reqeusts now.

        // Fire and forget

        //

        

        IoSkipCurrentIrpStackLocation (Irp);

        IoCallDriver (DeviceData->TopOfStack, Irp);



        //

        // Wait for all outstanding requests to complete

        //

        i = InterlockedDecrement (&DeviceData->OutstandingIO);



        ASSERT (0 < i);



        if (0 != InterlockedDecrement (&DeviceData->OutstandingIO)) {

            Test98_KdPrint (DeviceData, TEST_DBG_PNP_INFO,

                          ("Remove Device waiting for request to complete\n"));



            KeWaitForSingleObject (&DeviceData->RemoveEvent,

                                   Suspended,

                                   KernelMode,

                                   FALSE, // Not Alertable

                                   NULL); // No timeout

        }

        //

        // Free the associated resources

        // Detatch from the undelying devices.

        //

        Test98_KdPrint(DeviceData, TEST_DBG_PNP_INFO,

                        ("IoDetachDevice: 0x%x\n", DeviceData->TopOfStack));

        IoDetachDevice (DeviceData->TopOfStack);



        //

        // Clean up any resources here

        //

        if (DeviceData->Started) {

            //

            // Free resources given by start device.

            //

            if (DeviceData->MappedPorts) {

                MmUnmapIoSpace (DeviceData->TestPortAddress, 1);

            }

        }



        ExFreePool (DeviceData->DevClassAssocName.Buffer);

        Test98_KdPrint(DeviceData, TEST_DBG_PNP_INFO,

                        ("IoDeleteDevice1: 0x%x\n", DeviceObject));

        IoDeleteDevice (DeviceObject);



        return STATUS_SUCCESS;



    case IRP_MN_QUERY_REMOVE_DEVICE:

        //

        // the driver indicates to system whether it can be removed  

        // in response to this IPR...

        //



        Irp->IoStatus.Status = STATUS_SUCCESS;

        IoSkipCurrentIrpStackLocation (Irp);

        status = IoCallDriver (DeviceData->TopOfStack, Irp);

        Test98_DecIoCount (DeviceData);

        return status;



    default:

        //

        // In the default case we merely call the next driver since

        // we don't know what to do.

        // Fire and Forget

        //

        IoSkipCurrentIrpStackLocation (Irp);



        //

        // Done, do NOT complete the IRP, it will be processed by the lower

        // device object, which will complete the IRP

        //



        status = IoCallDriver (DeviceData->TopOfStack, Irp);

        Test98_DecIoCount (DeviceData);

        return status;

    }



    Irp->IoStatus.Status = status;

    DbgRaiseIrql (DISPATCH_LEVEL, &oldIrq);

    IoCompleteRequest (Irp, IO_NO_INCREMENT);

    DbgLowerIrql (oldIrq);



    Test98_DecIoCount (DeviceData);

    return status;

}



// ==================================================================

NTSTATUS

Test98_FDO_PnPComplete (

    IN PDEVICE_OBJECT   DeviceObject,

    IN PIRP             Irp,

    IN PVOID            Context

    )

/*++



    A completion routine for use when calling the lower device objects to

    which our FDO is attached.



--*/

{

    UNREFERENCED_PARAMETER (DeviceObject);



    if (Irp->PendingReturned) {

        IoMarkIrpPending( Irp );

    }

⌨️ 快捷键说明

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