xuplus
驱动牛犊
驱动牛犊
  • 注册日期2008-04-10
  • 最后登录2010-06-11
  • 粉丝1
  • 关注0
  • 积分2分
  • 威望28点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
阅读:1623回复:0

关于获取HID硬件设备的iD问题,我快崩溃了!SOS!

楼主#
更多 发布于:2008-05-19 10:23
我想通过给内部设备发送IOCTL消息获取一个hid设备的id,
但是都调试了1个多星期了都没能实现,我的心情也落到了低谷,请大家帮我一下,给点提示也好!
我的代码如下:
//DriverEntry
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
                     IN PUNICODE_STRING RegistryPath)
{


    DbgPrint("Entering DriverEntry");

    NTSTATUS status = STATUS_SUCCESS;
    PDEVICE_OBJECT fdo = NULL;
    PFILE_OBJECT  fobj = NULL;
    UNICODE_STRING name;
    IO_STATUS_BLOCK ioblock;
    int uBuffLen = 0;
    unsigned char buff[1024];

    RtlInitUnicodeString(&name, L"\\Device\\00000080");

    //设置卸载例程,方便卸载
    DriverObject->DriverUnload = DriverUnload;

    //获取设备指针
    status = IoGetDeviceObjectPointer(&name,
                                    //FILE_READ_ATTRIBUTES,
                                    FILE_ALL_ACCESS,
                                    &fobj,
                                    &fdo);
    
    if(!NT_SUCCESS(status))
    {
        DbgPrint("IoGetDeviceObjectPointer failed! 0x%08X", status);
        return status;
    }

    g_fdo = fdo;

    KEVENT kevent;
    KeInitializeEvent(&kevent, NotificationEvent, FALSE);

    PIRP irp  = NULL;

    irp = IoBuildDeviceIoControlRequest(IOCTL_HID_GET_HARDWARE_ID,
                                        fdo,
                                        NULL,
                                        0,
                                        NULL,
                                        0,
                                        TRUE,
                                        &kevent,
                                        &ioblock);
    if (NULL == irp)
    {
        DbgPrint("IoBuildDeviceIoControlRequest failed!");
        ObDereferenceObject(fdo);    
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    else
    {
        DbgPrint("IoBuildDeviceIoControlRequest Succeed!");        
    }
    

    
    //获取需要分配的空间长度
    PIO_STACK_LOCATION stack;
    stack = IoGetNextIrpStackLocation(irp);
    DbgPrint("original outbufferlength is: %08X", stack->Parameters.DeviceIoControl.OutputBufferLength);
    stack->Parameters.DeviceIoControl.OutputBufferLength = 1024;
    DbgPrint("after outbufferlength is: %08X", stack->Parameters.DeviceIoControl.OutputBufferLength);
    
    
    PMDL mdl = NULL;
    mdl = IoAllocateMdl(buff, 1024, FALSE, FALSE, NULL);    
    if (NULL != mdl)
    {
        //MmBuildMdlForNonPagedPool(mdl); //
        irp->MdlAddress = mdl; //direct way
        DbgPrint("IoAllocateMdl succeed!");
    }
    else
    {
        DbgPrint("IoAllocateMdl faliled!");
    }
    
    //stack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
    //stack->MinorFunction = IOCTL_HID_GET_HARDWARE_ID;
    DbgPrint("mj code : %08X, mn code : %08X", stack->MajorFunction, stack->MinorFunction);
    DbgPrint("input len: %08X", stack->Parameters.DeviceIoControl.OutputBufferLength);
    DbgPrint("mdladdr : %08X", irp->MdlAddress);
    
    PMDL ormdladdr = irp->MdlAddress;
    status = IoCallDriver(fdo, irp);
    if (status == STATUS_PENDING)
    {
        status = KeWaitForSingleObject(&kevent, Executive, KernelMode, FALSE, NULL);
        status = ioblock.Status;
    }
    
    if (NT_SUCCESS(status))
    {
        DbgPrint("out wait, blocksize, %08X", irp->IoStatus.Information);
        //DbgPrint("irp->mdladdr:%08X, original mdladdr: %08X", irp->MdlAddress, ormdladdr);
    }
    else
    {
        DbgPrint("ioblock status == faliled! status:%08X, irp->io.status:%08X", status, irp->IoStatus.Status);
        ObDereferenceObject(fdo);
    }

    return status;
}

============代码就是这样,
但我将编译好的驱动加载后,出现蓝屏,windgb显示如下消息:
kd> !analyze -v
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

PFN_LIST_CORRUPT (4e)
Typically caused by drivers passing bad memory descriptor lists (ie: calling
MmUnlockPages twice with the same list, etc).  If a kernel debugger is
available get the stack trace.
Arguments:
Arg1: 00000007, A driver has unlocked a page more times than it locked it
Arg2: 0000e995, page frame number
Arg3: 00000001, current share count
Arg4: 00000000, 0

Debugging Details:
------------------


BUGCHECK_STR:  0x4E_7

DEFAULT_BUCKET_ID:  DRIVER_FAULT

PROCESS_NAME:  System

LAST_CONTROL_TRANSFER:  from 80522fdf to 804fadeb

STACK_TEXT:  
f9518bb0 80522fdf 0000004e 00000007 0000e995 nt!KeBugCheckEx+0x1b
f9518bd0 80506ae6 00000000 80564c20 fed71000 nt!MiDecrementReferenceCount+0x33
f9518c14 80548c46 8055c568 ff257c60 80564c20 nt!MiDeferredUnlockPages+0x17c
f9518c44 8054b49a fed71000 ff257c60 e1777316 nt!MiFreePoolPages+0xa4
f9518c84 8058112b fed71000 00000000 00000000 nt!ExFreePoolWithTag+0x1ba
f9518d54 805811fb 0000037c 00000001 00000000 nt!IopLoadDriver+0x6ab
f9518d7c 805389bd 0000037c 00000000 80e3ada8 nt!IopLoadUnloadDriver+0x45
f9518dac 805cf84c f0afacf4 00000000 00000000 nt!ExpWorkerThread+0xef
f9518ddc 8054632e 805388ce 80000001 00000000 nt!PspSystemThreadStartup+0x34
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16
=====
我想搞清楚:
1,我这种方法获取hid设备的硬件id正确吗?
2,我的实现步骤有什么问题?我用IoBuildDeviceIoControlRequest创建完irp后,是否需要调用stack = IoGetNextIrpStackLocation(irp);
然后设定输出缓冲区长度,我需要自己设定吗?还是驱动底层会自己判断?
3,我需要PMDL mdl = NULL;
    mdl = IoAllocateMdl(buff, 1024, FALSE, FALSE, NULL);
irp->MdlAddress = mdl; ,来给irp分配一个缓冲区用来存放返回的数据吗?
4,返回的数据我该如何取出来?


我刚入门,请个位达人高手给与指点……先谢过了……
游客

返回顶部