[опять повтор] Посылка IOCTL_INTERNAL_XXX

Тема в разделе "WASM.WIN32", создана пользователем ubil, 30 апр 2006.

  1. ubil

    ubil New Member

    Публикаций:
    0
    Регистрация:
    7 ноя 2004
    Сообщения:
    203
    Адрес:
    ODESSA:)
    Это уже обсуждалось в теме "Помогите составить IRP\n", но немного в другом контексте: там IRP обрабатывался как IRP_MJ_DEVICE_CONTROL, а не IRP_MJ_INTERNAL_DEVICE_CONTROL , как в моем случае.

    В общем, я написал функцию, которая посылает IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO стандартному драйверу LPT порта, в которой я находил объект устройства по имени, потом составлял IRP с помощью IoBuildDeviceIoControlRequest... Вроде все работает, я нахожу базовый адрес. Но работает криво: если я ТРИЖДЫ запущу и остановлю свой драйвер(при этом каждый раз драйвер из DriverEntry посылает IRP стандартному драйверу LPT), то в четвертый раз функция IoGetDeviceObjectPointer выполнится неудачно, и соответсвенно мой драйвер не сможет запуститься. Еще, что интересно, если попытаться в дивайсменеджере удалить LPT порт, то появится синий экран. Еще он может появится если включить Winamp:)

    Вот функция:
    Код (Text):
    1. NTSTATUS GetParPortBaseAddr( ULONG PortNum, PUCHAR *pPortBase )
    2. {  
    3.     NTSTATUS status = STATUS_SUCCESS;
    4.    
    5.     UNICODE_STRING uPP;
    6.  
    7.     STRING aPP;
    8.  
    9.     CHAR PP0[] = "\\Device\\ParallelPort0";
    10.     CHAR PP1[] = "\\Device\\ParallelPort1";
    11.     CHAR PP2[] = "\\Device\\ParallelPort2";
    12.  
    13.     PFILE_OBJECT pParPortXFileObj = NULL;
    14.     PDEVICE_OBJECT pParPortXDevObj = NULL;
    15.     PIRP pIrp = NULL;
    16.     KEVENT WaitEvent;
    17.     PARALLEL_PORT_INFORMATION ParPortInfo;
    18.     IO_STATUS_BLOCK IOStatus;
    19.    
    20.     switch( PortNum )
    21.     {
    22.     case 0:
    23.         RtlInitAnsiString(&aPP, PP0);
    24.         break;
    25.     case 1:
    26.         RtlInitAnsiString(&aPP, PP1);
    27.         break;
    28.     case 2:
    29.         RtlInitAnsiString(&aPP, PP2);
    30.         break;
    31.     default:
    32.         return -1;
    33.     }
    34.  
    35.     RtlAnsiStringToUnicodeString(&uPP,&aPP,TRUE);
    36.    
    37.     status = IoGetDeviceObjectPointer(  &uPP,
    38.                                 FILE_ALL_ACCESS,
    39.                                 &pParPortXFileObj,
    40.                                 &pParPortXDevObj    );
    41.     RtlFreeUnicodeString(&uPP);
    42.  
    43.     if(status!=STATUS_SUCCESS)
    44.     {
    45.         DbgPrint("Cann't obtain PPort DevObj\n");
    46.         return status;
    47.     }
    48.  
    49.     KeInitializeEvent(&WaitEvent,NotificationEvent,FALSE);
    50.  
    51.     pIrp = IoBuildDeviceIoControlRequest(
    52.                     IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO,
    53.                     pParPortXDevObj,
    54.                     &ParPortInfo,
    55.                     sizeof(PARALLEL_PORT_INFORMATION),
    56.                     &ParPortInfo,
    57.                     sizeof(PARALLEL_PORT_INFORMATION),
    58.                     TRUE,
    59.                     &WaitEvent,
    60.                     &IOStatus);
    61.     if(pIrp == NULL)
    62.     {
    63.         DbgPrint("Allocation of IRP failed\n");
    64.         ObDereferenceObject( pParPortXDevObj );
    65.         return -1;
    66.     }
    67.  
    68.     status = IoCallDriver(pParPortXDevObj, pIrp);
    69.     if(status==STATUS_PENDING)
    70.     {
    71.         KeWaitForSingleObject(  &WaitEvent,
    72.                                 Executive,
    73.                                 KernelMode,
    74.                                 FALSE,
    75.                                 NULL    );
    76.     }
    77.  
    78.     status = IOStatus.Status;
    79.     if(status!=STATUS_SUCCESS)
    80.     {
    81.         DbgPrint("pIrpCreationStatus: Not Successful\n");
    82.         ObDereferenceObject( pParPortXDevObj );
    83.         return status;
    84.     }
    85.  
    86.  
    87.     DbgPrint("ParPortBase = %X\n",(ULONG)ParPortInfo.Controller);
    88.     DbgPrint("ParPortSpan = %i\n",(ULONG)ParPortInfo.SpanOfController);
    89.  
    90.     ((PUCHAR*)pPortBase)[0] = ParPortInfo.Controller;
    91.  
    92.     ObDereferenceObject( pParPortXDevObj );
    93.  
    94.     return status;
    95. }




    Кто знает в чем тут дело?
     
  2. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    ubil

    Выделенным черным цветом, это чтобы обществ код не проворонило? :)
     
  3. ubil

    ubil New Member

    Публикаций:
    0
    Регистрация:
    7 ноя 2004
    Сообщения:
    203
    Адрес:
    ODESSA:)
    Думаю это лучше, чем тонким курсивом наклонным выделять как
     
  4. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    ubil

    Выделяй как "[" code "]"много кода "[" /code "]" без ковычек
     
  5. ubil

    ubil New Member

    Публикаций:
    0
    Регистрация:
    7 ноя 2004
    Сообщения:
    203
    Адрес:
    ODESSA:)
    Да, с форматированием вроде бы как разобрались:) Теперь бы с самой темой разобраться - ваще было бы круто...



    Беспощадный даос

    Я бы и сам мог поправить...
     
  6. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Что-то смотрю на ObDereferenceObject и вспомнилось:



    IoGetDeviceObjectPointer



    This routine also returns a pointer to the corresponding file object. When unloading, a driver can dereference the file object as a means of indirectly dereferencing the device object. To do so, the driver calls ObDereferenceObject from its Unload routine, passing the file object pointer returned by IoGetDeviceObjectPointer. Failure to dereference the device object in a driver's Unload routine prevents the next-lower driver from being unloaded. However, drivers that close the file object before the unload process must take out an extra reference on the device object before dereferencing the file object. Otherwise, dereferencing the file object can lead to a premature deletion of the device object.
     
  7. ubil

    ubil New Member

    Публикаций:
    0
    Регистрация:
    7 ноя 2004
    Сообщения:
    203
    Адрес:
    ODESSA:)
    cresta!!!

    Спасибо! Я только что заменил везде в вызовах ObDereferenceObject pParPortXDevObj на pParPortXFileObj и теперь могу запускать/останавливать драйвер сколько угодно раз! Ща попробую удалить стандартный драйвер...
     
  8. visualr

    visualr New Member

    Публикаций:
    0
    Регистрация:
    1 фев 2005
    Сообщения:
    33
    при получении другим драйвером IRP_MJ_INTERNAL_DEVICE_CONTROL как узнать кем был послан irp данного типа?