XinHuaSoft
驱动牛犊
驱动牛犊
  • 注册日期2005-07-19
  • 最后登录2012-06-11
  • 粉丝0
  • 关注0
  • 积分15分
  • 威望167点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
阅读:2480回复:3

同一个设备,在不同派遣函数中有的可以挂接有的却不可以,奇怪!

楼主#
更多 发布于:2010-01-17 16:35
我机器上有一个叫Winachsf0的设备,我在DriverEntry中可以通过IoAttachDevice把我的设备挂接到设备栈上,而在我自定义的IoControl中却无法将我的设备挂接到设备栈上,返回的状态是STATUS_OBJECT_NAME_NOT_FOUND,不知道有没有碰到过?
weolar
驱动牛犊
驱动牛犊
  • 注册日期2007-05-14
  • 最后登录2012-11-30
  • 粉丝1
  • 关注0
  • 积分48分
  • 威望445点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分1分
沙发#
发布于:2010-01-18 09:14
贴代码看看?
XinHuaSoft
驱动牛犊
驱动牛犊
  • 注册日期2005-07-19
  • 最后登录2012-06-11
  • 粉丝0
  • 关注0
  • 积分15分
  • 威望167点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2010-01-18 10:06
代码如下
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
    KdPrint(("Enter DriverEntry!\n"));
    for(int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
        DriverObject->MajorFunction = DispatchPassthrough;
        
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IoCtlPassthrough;
    DriverObject->MajorFunction[IRP_MJ_READ] = Read;
    DriverObject->DriverUnload = DriverUnload;
    
    KdPrint(("Leave DriverEntry!\n"));
    return CreateDevice(DriverObject);
}

NTSTATUS CreateDevice(IN PDRIVER_OBJECT DriverObject)
{
    NTSTATUS status = STATUS_SUCCESS;
    KdPrint(("Enter CreateDevice!\n"));
    UNICODE_STRING DevName;
    RtlInitUnicodeString(&DevName, L"\\Device\\MyDevice");
    PDEVICE_OBJECT fdo = NULL;
    status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &fdo);
    if(!NT_SUCCESS(status))
        return status;
    
    PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION)fdo->DeviceExtension;
    RtlZeroMemory(DevExt, sizeof(DEVICE_EXTENSION));
    DevExt->FiltDeviceObject = fdo;
    
    UNICODE_STRING SymbolicLinkName;
    RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\COMMFILT");
    status = IoCreateSymbolicLink(&SymbolicLinkName, &DevName);
    if(!NT_SUCCESS(status))
    {
        IoDeleteDevice(fdo);
        return status;
    }
    DevExt->SymbolicLink = SymbolicLinkName;
    
    /*UNICODE_STRING TargetDeviceName;
    RtlInitUnicodeString(&TargetDeviceName, L"\\Device\\Winachsf0");
    status = IoAttachDevice(fdo, &TargetDeviceName, &DevExt->LowerLevelDeviceObject);
    if(!NT_SUCCESS(status))
    {
        IoDeleteSymbolicLink(&SymbolicLinkName);
        IoDeleteDevice(fdo);
        return status;
    }
    
    fdo->DeviceType = DevExt->LowerLevelDeviceObject->DeviceType;
    fdo->Characteristics = DevExt->LowerLevelDeviceObject->Characteristics;
    fdo->Flags |= (DevExt->LowerLevelDeviceObject->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO));
    */
    fdo->Flags &= ~DO_DEVICE_INITIALIZING;

    KdPrint(("Leave CreateDevice!\n"));
    return status;
}

NTSTATUS IoCtlPassthrough(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    KdPrint(("Enter IoCtlPassthrough!\n"));
    NTSTATUS status;

    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
    PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
    switch(stack->Parameters.DeviceIoControl.IoControlCode)
    {
        case ATTACH_CTL_CODE:
        {
            ULONG lInputBufferLen = stack->Parameters.DeviceIoControl.InputBufferLength;
            ANSI_STRING strDriver;
            strDriver.Buffer = (PCHAR)ExAllocatePool(PagedPool, lInputBufferLen);
            if(NULL == strDriver.Buffer)
            {
                status = STATUS_INSUFFICIENT_RESOURCES;
                Irp->IoStatus.Status = status;
                Irp->IoStatus.Information = 0;
                IoCompleteRequest(Irp, IO_NO_INCREMENT);
                return status;
                break;
            }
            RtlCopyMemory(strDriver.Buffer, Irp->AssociatedIrp.SystemBuffer, lInputBufferLen);
            strDriver.Length = (USHORT)lInputBufferLen;
            KdPrint(("strDriver is %Z!\n", &strDriver));
            
            UNICODE_STRING TargetDeviceName;
            if(!NT_SUCCESS(status = RtlAnsiStringToUnicodeString(&TargetDeviceName, &strDriver, TRUE)))
            {
                RtlFreeAnsiString(&strDriver);
                Irp->IoStatus.Status = status;
                Irp->IoStatus.Information = 0;
                IoCompleteRequest(Irp, IO_NO_INCREMENT);
                return status;
                break;
            }
            KdPrint(("TargetDeviceName is %wZ!\n", &TargetDeviceName));
            
            if(NULL != DevExt->LowerLevelDeviceObject)
            {
                IoDetachDevice(DevExt->LowerLevelDeviceObject);
                DevExt->LowerLevelDeviceObject = NULL;
            }
            
/***********该部分代码和CreateDevice中注释部分功能相同,此处IoAttachDevice失败,而CreateDevice中可以成功************/
            status = IoAttachDevice(DeviceObject, &TargetDeviceName, &DevExt->LowerLevelDeviceObject);
            if(!NT_SUCCESS(status))
            {
                KdPrint(("IoAttachDevice failed and status = %s!\n", OsrNTStatusToString(status)));
                RtlFreeAnsiString(&strDriver);
                RtlFreeUnicodeString(&TargetDeviceName);
                Irp->IoStatus.Status = status;
                Irp->IoStatus.Information = 0;
                IoCompleteRequest(Irp, IO_NO_INCREMENT);
                return status;
                break;
            }
/****************************************End********************************************/
            RtlFreeAnsiString(&strDriver);
            RtlFreeUnicodeString(&TargetDeviceName);
            DevExt->LowerLevelDeviceObject->DeviceType = DevExt->LowerLevelDeviceObject->DeviceType;
            DevExt->LowerLevelDeviceObject->Characteristics = DevExt->LowerLevelDeviceObject->Characteristics;
            DevExt->LowerLevelDeviceObject->Flags |= (DevExt->LowerLevelDeviceObject->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO));
            Irp->IoStatus.Status = status;
            Irp->IoStatus.Information = 0;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            return status;
            break;
        }
        case DETACH_CTL_CODE:
            if(NULL != DevExt->LowerLevelDeviceObject)
            {
                status = STATUS_SUCCESS;
                IoDetachDevice(DevExt->LowerLevelDeviceObject);
                Irp->IoStatus.Status = status;
                Irp->IoStatus.Information = 0;
                IoCompleteRequest(Irp, IO_NO_INCREMENT);
                return status;
            }
            break;
    }
    if(NULL == DevExt->LowerLevelDeviceObject)
    {
        status = STATUS_SUCCESS;
        Irp->IoStatus.Status = status;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
    }
    else
    {
        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(DevExt->LowerLevelDeviceObject, Irp);
    }
    KdPrint(("Leave IoCtlPassthrough!\n"));
    return status;
}
XinHuaSoft
驱动牛犊
驱动牛犊
  • 注册日期2005-07-19
  • 最后登录2012-06-11
  • 粉丝0
  • 关注0
  • 积分15分
  • 威望167点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
地板#
发布于:2010-01-19 21:16
找到问题了
问题出在IoControl派遣例程中
ULONG lInputBufferLen = stack->Parameters.DeviceIoControl.InputBufferLength;
            ANSI_STRING strDriver;
            strDriver.Buffer = (PCHAR)ExAllocatePool(PagedPool, lInputBufferLen);
            if(NULL == strDriver.Buffer)
            {
                status = STATUS_INSUFFICIENT_RESOURCES;
                Irp->IoStatus.Status = status;
                Irp->IoStatus.Information = 0;
                IoCompleteRequest(Irp, IO_NO_INCREMENT);
                return status;
                break;
            }
            RtlCopyMemory(strDriver.Buffer, Irp->AssociatedIrp.SystemBuffer, lInputBufferLen);
            strDriver.Length = (USHORT)lInputBufferLen;
            KdPrint(("strDriver is %Z!\n", &strDriver));

这里strDriver.Length是不正确的,其值应该是实际字符串的长度,strDriver.MaximumLength才应该是lInputBufferLen。strDriver错了就导致其对应的UNICODE_STRING也不正确,由此我的体会是ANSI_STRING和UNICODE_STRING的Length也很重要,大家不要只将注意力放在它们的值上而忽视大小,这个问题困扰了我好几天。
游客

返回顶部