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

📄 vhidmini.c

📁 winddk src目录下的WDM源码压缩!
💻 C
📖 第 1 页 / 共 3 页
字号:
/*++

Copyright (c) Microsoft Corporation.  All rights reserved.

    THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
    KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
    PURPOSE.

Module Name:

    VHIDMINI.C
    
Abstract:


Author:

    Kumar Rajeev & Eliyas Yakub  (1/04/2002) 


Environment:

    kernel mode only

Notes:


Revision History:


--*/

#include <VHidMini.h>

#ifdef ALLOC_PRAGMA
    #pragma alloc_text( INIT, DriverEntry )
    #pragma alloc_text( PAGE, AddDevice)
    #pragma alloc_text( PAGE, Unload)
    #pragma alloc_text( PAGE, PnP)
    #pragma alloc_text( PAGE, ReadDescriptorFromRegistry)

#endif 


NTSTATUS 
DriverEntry (
    IN PDRIVER_OBJECT  DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
/*++

Routine Description:

    Installable driver initialization entry point.
    This entry point is called directly by the I/O system.

Arguments:

    DriverObject - pointer to the driver object

    RegistryPath - pointer to a unicode string representing the path,
                   to driver-specific key in the registry.

Return Value:

    STATUS_SUCCESS if successful,
    STATUS_UNSUCCESSFUL otherwise.

--*/
{
    NTSTATUS                      ntStatus;
    HID_MINIDRIVER_REGISTRATION   hidMinidriverRegistration;

    DebugPrint(("Enter DriverEntry()\n"));

    DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] =
                                                InternalIoctl;
    DriverObject->MajorFunction[IRP_MJ_PNP]   = PnP;
    DriverObject->MajorFunction[IRP_MJ_POWER] = Power;
    DriverObject->DriverUnload                = Unload;
    DriverObject->DriverExtension->AddDevice  = AddDevice;

    RtlZeroMemory(&hidMinidriverRegistration, 
                  sizeof(hidMinidriverRegistration));

    //
    // Revision must be set to HID_REVISION by the minidriver
    //
    
    hidMinidriverRegistration.Revision            = HID_REVISION;
    hidMinidriverRegistration.DriverObject        = DriverObject;
    hidMinidriverRegistration.RegistryPath        = RegistryPath;
    hidMinidriverRegistration.DeviceExtensionSize = sizeof(DEVICE_EXTENSION);

    //
    // if "DevicesArePolled" is False then the hidclass driver does not do
    // polling and instead reuses a few Irps (ping-pong) if the device has 
    // an Input item. Otherwise, it will do polling at regular interval. USB 
    // HID devices do not need polling by the HID classs driver. Some leagcy 
    // devices may need polling. 
    //
    
    hidMinidriverRegistration.DevicesArePolled    = FALSE; 

    //
    //Register with hidclass
    //

    ntStatus = HidRegisterMinidriver(&hidMinidriverRegistration);

    if(!NT_SUCCESS(ntStatus) ){
        DebugPrint(("HidRegisterMinidriver FAILED, returnCode=%x\n", 
                  ntStatus));

    }
    
    DebugPrint(("Exit DriverEntry() status=0x%x\n", ntStatus));

    return ntStatus;
    
}


NTSTATUS  
AddDevice (
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT FunctionalDeviceObject
    )
/*++

Routine Description:

    HidClass Driver calls our AddDevice routine after creating an FDO for us.
    We do not need to create a device object or attach it to the PDO. 
    Hidclass driver will do it for us.
   
Arguments:

    DriverObject - pointer to the driver object.

    FunctionalDeviceObject -  pointer to the FDO created by the
                            Hidclass driver for us.

Return Value:

    NT status code.

--*/
{
    NTSTATUS            ntStatus = STATUS_SUCCESS;
    PDEVICE_EXTENSION   deviceInfo;

    PAGED_CODE ();

    DebugPrint(("Enter AddDevice(DriverObject=0x%x,"
                "FunctionalDeviceObject=0x%x)\n",
                DriverObject, FunctionalDeviceObject));

    ASSERTMSG("AddDevice:", FunctionalDeviceObject != NULL);

    deviceInfo = GET_MINIDRIVER_DEVICE_EXTENSION (FunctionalDeviceObject);

    //
    // Initialize all the members of device extension
    //

    RtlZeroMemory((PVOID)deviceInfo, sizeof(DEVICE_EXTENSION));

    //
    // Set the initial state of the FDO
    //

    INITIALIZE_PNP_STATE(deviceInfo);

    FunctionalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
    
    DebugPrint(("Exit AddDevice\n", ntStatus));

    return ntStatus;
    
}


NTSTATUS  
PnP (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
/*++
Routine Description:

    Handles PnP Irps sent to FDO .

Arguments:

    DeviceObject - Pointer to deviceobject
    Irp          - Pointer to a PnP Irp.
    
Return Value:

    NT Status is returned.
--*/
{
    NTSTATUS            ntStatus, queryStatus;
    PDEVICE_EXTENSION   deviceInfo;
    KEVENT              startEvent;
    PIO_STACK_LOCATION  IrpStack, previousSp;
    PWCHAR              buffer;

    PAGED_CODE();

    //
    //Get a pointer to the device extension
    //

    deviceInfo = GET_MINIDRIVER_DEVICE_EXTENSION(DeviceObject);

    //
    //Get a pointer to the current location in the Irp
    //

    IrpStack = IoGetCurrentIrpStackLocation (Irp);

    DebugPrint(("%s Irp=0x%x\n", 
               PnPMinorFunctionString(IrpStack->MinorFunction), 
               Irp ));

    switch(IrpStack->MinorFunction)
    {
    case IRP_MN_START_DEVICE:

        KeInitializeEvent(&startEvent, NotificationEvent, FALSE);

        IoCopyCurrentIrpStackLocationToNext (Irp);

        IoSetCompletionRoutine (Irp, 
                                PnPComplete, 
                                &startEvent, 
                                TRUE, 
                                TRUE, 
                                TRUE);

        ntStatus = IoCallDriver (GET_NEXT_DEVICE_OBJECT(DeviceObject), Irp);

        if (STATUS_PENDING == ntStatus) {
            KeWaitForSingleObject(
                    		&startEvent,
                    		Executive, 
                    		KernelMode, 
                    		FALSE, // No allert
                    		NULL); // No timeout
            ntStatus = Irp->IoStatus.Status;
        }

        if (NT_SUCCESS(ntStatus)) {
            //
            // Use default "HID Descriptor" (hardcoded). We will set the 
            // wReportLength memeber of HID descriptor when we read the 
            // the report descriptor either from registry or the hard-coded 
            // one.
            //

            deviceInfo->HidDescriptor = DefaultHidDescriptor;

            //
            // Check to see if we need to read the Report Descriptor from
            // registry. If the "ReadFromRegistry" flag in the registry is set
            // then we will read the descriptor from registry using routine 
            // ReadDescriptorFromRegistry(). Otherwise, we will use the 
            // hard-coded default report descriptor.
            //

            queryStatus = CheckRegistryForDescriptor(DeviceObject);

            if(NT_SUCCESS(queryStatus)){
                //
                // We need to read read descriptor from registry
                //
                
                queryStatus = ReadDescriptorFromRegistry(DeviceObject);
            
                if(!NT_SUCCESS(queryStatus)){
                    DebugPrint(("Failed to read descriptor from registry\n"));
                    ntStatus = STATUS_UNSUCCESSFUL;
                }

            }
            else{
                //
                // We will use hard-coded report descriptor. 
                //
                
                deviceInfo->ReportDescriptor = DefaultReportDescriptor;

                DebugPrint(("Using Hard-coded Report descriptor\n"));
                
            }
            
            //
            //Set new PnP state
            //
            if(NT_SUCCESS(ntStatus)){
                
                SET_NEW_PNP_STATE(deviceInfo, Started);
                
            }
        }

        Irp->IoStatus.Status = ntStatus;
        IoCompleteRequest (Irp, IO_NO_INCREMENT);
        return ntStatus;

    case IRP_MN_STOP_DEVICE:
        //
        // Mark the device as stopped.
        //
        SET_NEW_PNP_STATE(deviceInfo, Stopped);
        ntStatus = STATUS_SUCCESS;
        break;

    case IRP_MN_CANCEL_STOP_DEVICE:

        RESTORE_PREVIOUS_PNP_STATE(deviceInfo);
        ntStatus = STATUS_SUCCESS;         
        break;

    case IRP_MN_QUERY_STOP_DEVICE:    

        SET_NEW_PNP_STATE(deviceInfo, StopPending);
        ntStatus = STATUS_SUCCESS;
        break;

    case IRP_MN_QUERY_REMOVE_DEVICE:

        SET_NEW_PNP_STATE(deviceInfo, RemovePending);
        ntStatus = STATUS_SUCCESS;
        break;

    case IRP_MN_CANCEL_REMOVE_DEVICE:

        RESTORE_PREVIOUS_PNP_STATE(deviceInfo);
        ntStatus = STATUS_SUCCESS;
        break;

    case IRP_MN_SURPRISE_REMOVAL:

        SET_NEW_PNP_STATE(deviceInfo, SurpriseRemovePending);
        ntStatus = STATUS_SUCCESS;
        break;

    case IRP_MN_REMOVE_DEVICE:
        //
        // free memory if allocated for report descriptor
        //
        if(deviceInfo->ReadReportDescFromRegistry)
            ExFreePool(deviceInfo->ReportDescriptor);
        
        SET_NEW_PNP_STATE(deviceInfo, Deleted);
        ntStatus = STATUS_SUCCESS;           
        break;
        
    case IRP_MN_QUERY_ID:

        //
        // This check is required to filter out QUERY_IDs forwarded
        // by the HIDCLASS for the parent FDO. These IDs are sent
        // by PNP manager for the parent FDO if you root-enumerate this driver.
        //
        previousSp = ((PIO_STACK_LOCATION) ((UCHAR *) (IrpStack) + 
                            sizeof(IO_STACK_LOCATION)));
        
        if(previousSp->DeviceObject == DeviceObject) {
            //
            // Filtering out this basically prevents the Found New Hardware 
            // popup for the root-enumerated VHIDMINI on reboot.
            // 
            ntStatus = Irp->IoStatus.Status;            
            break;
        }
                
        switch (IrpStack->Parameters.QueryId.IdType) 
        {
        case BusQueryDeviceID:
        case BusQueryHardwareIDs:
            //
            // HIDClass is asking for child deviceid & hardwareids.
            // Let us just make up some  id for our child device.
            //
            buffer = (PWCHAR)ExAllocatePoolWithTag(
                          NonPagedPool, 
                          VHID_HARDWARE_IDS_LENGTH, 
                          VHID_POOL_TAG
                          );

            if (buffer) {
                //
                // Do the copy, store the buffer in the Irp
                //
                RtlCopyMemory(buffer, 
                              VHID_HARDWARE_IDS, 
                              VHID_HARDWARE_IDS_LENGTH
                              );
                
                Irp->IoStatus.Information = (ULONG_PTR)buffer;
                ntStatus = STATUS_SUCCESS;
            } 
            else {
                //
                //  No memory
                //
                ntStatus = STATUS_INSUFFICIENT_RESOURCES;
            }

            Irp->IoStatus.Status = ntStatus;
            //
            // We don't need to forward this to our bus. This query 
            // is for our child so we should complete it right here. 
            // fallthru.
            //
            IoCompleteRequest (Irp, IO_NO_INCREMENT);     
            
            return ntStatus;           
                 
        default:            
            ntStatus = Irp->IoStatus.Status;
            IoCompleteRequest (Irp, IO_NO_INCREMENT);          
            return ntStatus;
        }

    default:         
        ntStatus = Irp->IoStatus.Status;
        break;
    }
    
    Irp->IoStatus.Status = ntStatus;
    IoSkipCurrentIrpStackLocation (Irp);
    return IoCallDriver(GET_NEXT_DEVICE_OBJECT(DeviceObject), Irp);
    
}


NTSTATUS 
PnPComplete (
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp,
    IN PVOID            Context
    )
{
    DebugPrint(("PnPComplete(DeviceObject=0x%x,Irp=0x%x,Context=0x%x)\n",
                DeviceObject, Irp, Context));

    UNREFERENCED_PARAMETER (DeviceObject);

    if (Irp->PendingReturned) 
    {
        KeSetEvent ((PKEVENT) Context, 0, FALSE);
    }
    return STATUS_MORE_PROCESSING_REQUIRED;
}


NTSTATUS
Power(
    IN PDEVICE_OBJECT    DeviceObject,
    IN PIRP              Irp
    )
/*++

Routine Description:

    This routine is the dispatch routine for power irps.
    Does nothing except forwarding the IRP to the next device
    in the stack.

Arguments:

    DeviceObject - Pointer to the device object.

    Irp - Pointer to the request packet.

Return Value:

    NT Status code
--*/
{
    PDEVICE_EXTENSION   deviceInfo;

    DebugPrint(("Enter Power()\n"));
    
    deviceInfo = GET_MINIDRIVER_DEVICE_EXTENSION (DeviceObject);

    //
    // Make sure to store and restore the device context depending
    // on whether the system is going into lower power state
    // or resuming. The job of converting S-IRPs to D-IRPs is done
    // by HIDCLASS. All you need to do here is handle Set-Power request
    // for device power state according to the guidelines given in the 
    // power management documentation of the DDK. Before powering down  
    // your device make sure to cancel any pending IRPs, if any, sent by 
    // you to the lower device stack.
    //

    PoStartNextPowerIrp(Irp);     
    IoSkipCurrentIrpStackLocation(Irp);

    return PoCallDriver(GET_NEXT_DEVICE_OBJECT (DeviceObject), Irp);
}


VOID
Unload(
    IN PDRIVER_OBJECT DriverObject
    )
/*++

Routine Description:

    Free all the allocated resources, etc.

Arguments:

    DriverObject - pointer to a driver object.

Return Value:

    VOID.

--*/
{
    PAGED_CODE ();
    //
    // The device object(s) should be NULL now
    // (since we unload, all the devices objects associated with this
    // driver must have been deleted.
    //
    DebugPrint(("Enter Unload()\n"));

    ASSERT(DriverObject->DeviceObject == NULL);

    return;
}


NTSTATUS 
InternalIoctl
    (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )

⌨️ 快捷键说明

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