Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

IoAttachDeviceToDeviceStack - вроде сдесь проблема

6.0K
08 июля 2010 года
spyrytus
51 / / 14.07.2006
Здравствуйте.
Сразу прошу прощения, если не в том разделе - мне показалось, что он самый подходящий раздел для этого ... :(
Проблема в следующем, пишу драйвер для устройства на PIC18F4550, драйвер инсталлируется в систему, но когда вставляешь устройство - менеджер устройств определяет следующие:
Цитата:
Недостаточно свободных ресурсов для работы данного устройства. (Код 12) Чтобы использовать это устройство, нужно отключить одно из прочих устройств в системе.


Если закомментировать в функции AddDevice строчку вызова функции IoAttachDeviceToDeviceStack - то драйвер опеределяеться в системе нормально, когда я присоединяю устройство ... :confused: При этом данная функция возвращает адрес устройства добавленного в стек, и этот адрес совпадает из адресом PhysicalDeviceObject ... :confused: Причем совпадать начинает только после 2-го или 3-го раза, когда я подключаю устройство к компьютеру ...
Прошу помощи, может кто-то из Вас уже встречался с подобной проблемой ...
Заранее благодарен.

14
08 июля 2010 года
Phodopus
3.3K / / 19.06.2008
Слушайте, вам же написали - недостаточно ресурсов. Значит ваше устройство требует ресурсы которые заняты.
6.0K
08 июля 2010 года
spyrytus
51 / / 14.07.2006
Цитата: Phodopus
Слушайте, вам же написали - недостаточно ресурсов. Значит ваше устройство требует ресурсы которые заняты.


Да, так и есть - ему нужно было обработать запрос IRP_MN_START_DEVICE ...
Написал его обработку - все прошло, драйвер завелся в системе без проблем, но вот возникла еще одна, на мой взгляд - самая страшная:
Когда удаляю устройство из системы (безопасное извлечение или просто выдергиваю его) - вознакаетСиний экран смерти, ошибка возникает в обработчике IRP_MN_REMOVE_DEVICE, а именно в месте вызова функции IoCallDriver ...
Во время этой функции - Windows "падает" ...
Что может быть не так ? - уже всю голову сломал ...
Заранее благодарен ...

14
09 июля 2010 года
Phodopus
3.3K / / 19.06.2008
Цитата: spyrytus
вознакаетСиний экран смерти


синих экранов смерти - великое множество

6.0K
09 июля 2010 года
spyrytus
51 / / 14.07.2006
Цитата: Phodopus
синих экранов смерти - великое множество


MULTIPLE_IRP_DEVICE_REQUEST - вот мой экран ...
Что может происходить ? :confused:

6.0K
11 июля 2010 года
spyrytus
51 / / 14.07.2006
Вот код драйвера (удалил все, что было, хочу чтобы завелся):
Код:
NTSTATUS DriverEntry(
    IN PDRIVER_OBJECT  DriverObject,
    IN PUNICODE_STRING UniRegistryPath )
{
    NTSTATUS ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    PUNICODE_STRING ntRegisterPath = &Globals.UkroUSB_RegistryPath;
    ANSI_STRING DriverName;
    ntRegisterPath->MaximumLength = UniRegistryPath->Length + sizeof( UNICODE_NULL );
    ntRegisterPath->Length = UniRegistryPath->Length;
    ntRegisterPath->Buffer = ExAllocatePoolWithTag( PagedPool, ntRegisterPath->MaximumLength, BULKTAG );
   
    if ( ntRegisterPath->Buffer == NULL )
    {
        DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "Buffer is EMPTY" );
        return ( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
    }

    RtlZeroMemory( ntRegisterPath->Buffer, ntRegisterPath->MaximumLength );
    RtlMoveMemory( ntRegisterPath->Buffer, UniRegistryPath->Buffer, UniRegistryPath->Length );
    ntRegisterPath->Buffer[ntRegisterPath->Length / sizeof( WCHAR )] = '\0';

    RtlUnicodeStringToAnsiString( &DriverName, ntRegisterPath, TRUE );
    DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "Driver name is %s", DriverName.Buffer );
    RtlFreeAnsiString( &DriverName );

    ntStatus = STATUS_SUCCESS;

    DriverObject->DriverUnload          =   ( PDRIVER_UNLOAD )UkroUSB_DriverUnload;
    DriverObject->DriverExtension->AddDevice    =   ( PDRIVER_ADD_DEVICE )UkroUSB_AddDevice;
    DriverObject->MajorFunction[IRP_MJ_PNP]     =   UkroUSB_DispatchPnP;

    DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "DriverEntry complete successfully - ERROR = %X", ntStatus );

    return ntStatus;
}

NTSTATUS UkroUSB_AddDevice(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PhysicalDeviceObject )
{
    NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
    PDEVICE_OBJECT    deviceObject = NULL;
        PDEVICE_EXTENSION deviceExtension;
   
    ntStatus = IoCreateDevice(
                        DriverObject,
                        sizeof( DEVICE_EXTENSION ),
                        NULL,
                        FILE_DEVICE_UNKNOWN,
                        FILE_DEVICE_SECURE_OPEN,
                        //FILE_AUTOGENERATED_DEVICE_NAME,
                        FALSE,
                        &deviceObject );
    if ( !NT_SUCCESS( ntStatus ) )
    {
        DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "IoCreateDevice is ERROR - ERROR = %X", ntStatus );
        return ntStatus;
    }

    DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "IoCreateDevice is 0x%X to 0x%X", deviceObject, PhysicalDeviceObject );
   
    deviceExtension = ( PDEVICE_EXTENSION ) deviceObject->DeviceExtension;
    deviceExtension->DeviceObject = deviceObject;
    deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
    deviceObject->Flags |= DO_DIRECT_IO;
    if ( PhysicalDeviceObject->Flags & DO_POWER_PAGABLE ) deviceObject->Flags |= DO_POWER_PAGABLE;
   
    ntStatus = IoRegisterDeviceInterface(
                        PhysicalDeviceObject,
                        ( LPGUID )&GUID_CLASS_USB_UKRO,
                        NULL,
                        &deviceExtension->InterfaceName );
    if ( !NT_SUCCESS( ntStatus ) )
    {
        DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "IoRegisterDeviceInterface is ERROR - ERROR = %X", ntStatus );
        IoDeleteDevice( deviceObject );
        return ntStatus;
    }
    deviceExtension->CurrentDeviceState = Stopped;
    deviceExtension->PowerDeviceState = PowerDeviceD0;
    deviceExtension->SystemDeviceState = PowerSystemWorking;
   
    KeInitializeSpinLock( &deviceExtension->DevStateLock );
   
    if( RtlIsNtDdiVersionAvailable( NTDDI_WIN2K ) ) deviceExtension->WdmVersion = NTDDI_WIN2K;
        else if( RtlIsNtDdiVersionAvailable( NTDDI_WINXP ) ) deviceExtension->WdmVersion = NTDDI_WINXP;
        else if( RtlIsNtDdiVersionAvailable( NTDDI_VISTA ) ) deviceExtension->WdmVersion = NTDDI_VISTA;
        else if( RtlIsNtDdiVersionAvailable( NTDDI_WIN7 ) ) deviceExtension->WdmVersion = NTDDI_WIN7;

    ntStatus = IoAttachDeviceToDeviceStackSafe( deviceObject, PhysicalDeviceObject, &deviceExtension->LowerDeviceObject );
    if ( !NT_SUCCESS( ntStatus ) )
    {
        DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "IoAttachDeviceToDeviceStack is ERROR - ERROR = %X", ntStatus );
        IoDeleteDevice( deviceObject );
        return ntStatus;
    }
   
    deviceObject->Characteristics = deviceExtension->LowerDeviceObject->Characteristics;
    deviceObject->DeviceType = deviceExtension->LowerDeviceObject->DeviceType;
   
    deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
    ntStatus = STATUS_SUCCESS;
   
    DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "AddDevice complete successfully - ERROR = %X", ntStatus );

    return ntStatus;
}

NTSTATUS UkroUSB_DispatchPnP(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp )
{
    PIO_STACK_LOCATION  StackLocation;
    PDEVICE_EXTENSION   DeviceExtension;
    NTSTATUS        status = STATUS_UNSUCCESSFUL;
   
    StackLocation = IoGetCurrentIrpStackLocation( Irp );
    DeviceExtension = DeviceObject->DeviceExtension;

    DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "UkroUSB_DispatchPnP is begining 0x%X", DeviceExtension->LowerDeviceObject );

    switch( StackLocation->MinorFunction )
    {
        case IRP_MN_START_DEVICE:
            status = PnpStartDevice( DeviceObject, Irp );
            DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "IRP_MN_START_DEVICE is 0x%X", status );
            break;
        /*case IRP_MN_QUERY_STOP_DEVICE:
            UNREFERENCED_PARAMETER( DeviceObject );
            UNREFERENCED_PARAMETER( Irp );      
            status = PnpQueryStopDevice( DeviceObject, Irp );
            DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "IRP_MN_QUERY_STOP_DEVICE is 0x%X", status );
            break;
        case IRP_MN_STOP_DEVICE:
            status = PnpStopDevice( DeviceObject, Irp );
            DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "IRP_MN_STOP_DEVICE is 0x%X", status );
            break;*/
        case IRP_MN_QUERY_REMOVE_DEVICE:
            status = PnpQueryRemoveDevice( DeviceObject, Irp );
            DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "IRP_MN_QUERY_REMOVE_DEVICE is 0x%X", status );
            break;
        case IRP_MN_REMOVE_DEVICE:
            status = IoAcquireRemoveLock( &DeviceExtension->RemoveLock, Irp );
            if ( !NT_SUCCESS( status ) )
            {
                Irp->IoStatus.Status = status;
                Irp->IoStatus.Information = 0;
                IoCompleteRequest( Irp, IO_NO_INCREMENT );
                DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "IRP_MN_QUERY_REMOVE_DEVICE is ERROR = 0x%X", status );
                return status;
            }
            status = PnpRemoveDevice( DeviceObject, Irp );
            IoReleaseRemoveLockAndWait( &DeviceExtension->RemoveLock, Irp );
            DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "IRP_MN_REMOVE_DEVICE is 0x%X", status );
            break;
        /*case IRP_MN_CANCEL_REMOVE_DEVICE:
            status = PnpCancelRemoveDevice( DeviceObject, Irp );
            DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "IRP_MN_CANCEL_REMOVE_DEVICE is 0x%X", status );
            break;
        case IRP_MN_SURPRISE_REMOVAL:
            status = PnpSurpriseRemoval( DeviceObject, Irp );
            DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "IRP_MN_SURPRISE_REMOVAL is 0x%X", status );
            break;
        case IRP_MN_QUERY_CAPABILITIES:
            status = PnpQueryCapabilities( DeviceObject, Irp );
            DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "IRP_MN_QUERY_CAPABILITIES is 0x%X", status );
            break;*/
        default:
            IoSkipCurrentIrpStackLocation( Irp );
            status = IoCallDriver(DeviceExtension->LowerDeviceObject, Irp );
            DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "UkroUSB_DispatchPnP default, ERROR = 0x%X", status );
            return status;
    }

    Irp->IoStatus.Status = status;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest( Irp, IO_NO_INCREMENT );
    DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "UkroUSB_DispatchPnP is ending, ERROR = 0x%X", status );

    return status;
}
6.0K
11 июля 2010 года
spyrytus
51 / / 14.07.2006
Код:
NTSTATUS PnpStartDevice(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp )
{
    KIRQL           oldIrql;
    KEVENT          startDeviceEvent;
    NTSTATUS        ntStatus = STATUS_UNSUCCESSFUL;
    PDEVICE_EXTENSION   deviceExtension;

    DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "PnpStartDevice is begining IRP= 0x%X", Irp );

    deviceExtension = ( PDEVICE_EXTENSION )DeviceObject->DeviceExtension;
    deviceExtension->ConfigurationDescriptor = NULL;

    KeInitializeEvent( &startDeviceEvent, NotificationEvent, FALSE );
    IoCopyCurrentIrpStackLocationToNext( Irp );
    IoSetCompletionRoutine( Irp,
                (PIO_COMPLETION_ROUTINE)IrpCompletionRoutine,
                (PVOID)&startDeviceEvent,
                TRUE,
                TRUE,
                TRUE );
    ntStatus = IoCallDriver( deviceExtension->LowerDeviceObject, Irp );
    if ( ntStatus == STATUS_PENDING )
    {
        KeWaitForSingleObject(  &startDeviceEvent,
                    Executive,
                    KernelMode,
                    FALSE,
                    NULL );
        ntStatus = Irp->IoStatus.Status;
    }
    if( !NT_SUCCESS( ntStatus ) )
    {
        DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "Lower drivers failed this Irp, ERROR = 0x%X", ntStatus );
        return ntStatus;
    }

    ntStatus = IoSetDeviceInterfaceState( &deviceExtension->InterfaceName, TRUE );
    if( !NT_SUCCESS( ntStatus ) )
    {
        DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "IoSetDeviceInterfaceState enable = failed, ERROR = 0x%X", ntStatus );
        return ntStatus;
    }

    DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "PnpStartDevice is ending IRP= 0x%X, ERROR = 0x%X", Irp, ntStatus );

    return ntStatus;
}

NTSTATUS PnpQueryRemoveDevice(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp )
{
    KIRQL           oldIrql;
    NTSTATUS        ntStatus = STATUS_SUCCESS;
    PDEVICE_EXTENSION   deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;;

    DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "PnpQueryRemoveDevice is begining IRP = 0x%X", Irp );

    UNREFERENCED_PARAMETER( DeviceObject );
    UNREFERENCED_PARAMETER( Irp );

    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    IoSkipCurrentIrpStackLocation( Irp );

    DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "IoSkipCurrentIrpStackLocation, Irp->IoStatus.Status = 0x%X", Irp->IoStatus.Status );

    ntStatus = IoCallDriver( deviceExtension->LowerDeviceObject, Irp ); // ОШИБКА В ЭТОМ МЕСТЕ - СИНИЙ ЭКРАН СМЕРТИ

    if ( !NT_SUCCESS( ntStatus ) )
    {
        IoCompleteRequest( Irp, IO_NO_INCREMENT );
        return ntStatus;
    }

    DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "PnpQueryRemoveDevice is ending, ERROR = 0x%X", ntStatus );

    return ntStatus;
}

NTSTATUS PnpRemoveDevice(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp )
{
    KIRQL           oldIrql;
    NTSTATUS        ntStatus = STATUS_UNSUCCESSFUL;
    PDEVICE_EXTENSION   deviceExtension;

    DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "PnpRemoveDevice is begining IRP= 0x%X", Irp );

    deviceExtension = ( PDEVICE_EXTENSION )DeviceObject->DeviceExtension;

    ReleaseMemory( DeviceObject );

    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    IoSkipCurrentIrpStackLocation( Irp );

    DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "IoSkipCurrentIrpStackLocation, Irp->IoStatus.Status = 0x%X", Irp->IoStatus.Status );

    ntStatus = IoCallDriver( deviceExtension->LowerDeviceObject, Irp ); // ОШИБКА В ЭТОМ МЕСТЕ - СИНИЙ ЭКРАН СМЕРТИ (ЕСЛИ НЕТ ОБРАБОТЧИКА PnpQueryRemoveDevice)

    if ( !NT_SUCCESS( ntStatus ) )
    {
        IoCompleteRequest( Irp, IO_NO_INCREMENT );
        return ntStatus;
    }

    IoDetachDevice( deviceExtension->LowerDeviceObject );
    IoDeleteDevice( DeviceObject );

    DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "PnpRemoveDevice is ending ERROR = 0x%X", ntStatus );

    return ntStatus;
}

NTSTATUS ReleaseMemory( IN PDEVICE_OBJECT DeviceObject )
{
    PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

    DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "ReleaseMemory is begining, DeviceObject = 0x%X", DeviceObject );

    if( deviceExtension->ConfigurationDescriptor != NULL )
    {
        ExFreePool( deviceExtension->ConfigurationDescriptor );
        deviceExtension->ConfigurationDescriptor = NULL;
    }
   
    DbgPrintEx( DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "ReleaseMemory is ending, DeviceObject = 0x%X", DeviceObject );

    return STATUS_SUCCESS;
}

Прошу помощи, что может быть не так, вроде все написал по книге и почти все работает, кроме - извлечения устройства из компьютера ...
Если кто знает - помогите пожалуйста ...
14
13 июля 2010 года
Phodopus
3.3K / / 19.06.2008
Возможно драйвер выполняет другой IRP во время прихода surprise removal?
6.0K
14 июля 2010 года
spyrytus
51 / / 14.07.2006
Цитата: Phodopus
Возможно драйвер выполняет другой IRP во время прихода surprise removal?

Я поставил синхронизацию с помощью IoReleaseRemoveLockAndWait все объекты удаляются и функция отрабатывает успешно, а вот дальше ... :(

14
16 июля 2010 года
Phodopus
3.3K / / 19.06.2008
Вы все же уверены что ошибка лезет на IoCallDriver(), а не на IoCompleteRequest()? И что у вас в процедуре завершения?
6.0K
20 июля 2010 года
spyrytus
51 / / 14.07.2006
Цитата: Phodopus
Вы все же уверены что ошибка лезет на IoCallDriver(), а не на IoCompleteRequest()?


Да, т.к. если комментируешь вызов данной функции - все отрабатывает без проблем, правда не знаю правильно ли ... :confused:, т.к. в DDK написана последовательность команд, которая у меня не работает, а именно вызывает BSOD на IoCallDriver ... :mad:

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог