Драйвер mouclass

Тема в разделе "WASM.WIN32", создана пользователем wish3, 26 апр 2005.

  1. wish3

    wish3 New Member

    Публикаций:
    0
    Регистрация:
    31 янв 2005
    Сообщения:
    29
    Адрес:
    Ukraine
    Это код обработчика IRP_MJ_READ с драйвера mouclass. Почему сдесь нет обращения к нижелижащему драйверу(в стэке)? Я вижу здесь что пакет додаеться в очередь необработаных сообщений через IoMarkIrpPending. Обясните, пожалуста, как это работает и где же всетаки пакет обрабатываеться.
    Код (Text):
    1.  
    2. NTSTATUS
    3. MouseClassRead(
    4.     IN PDEVICE_OBJECT Device,
    5.     IN PIRP Irp
    6.     )
    7. {
    8.     NTSTATUS status;
    9.     PIO_STACK_LOCATION irpSp;
    10.     PDEVICE_EXTENSION  deviceExtension;
    11.  
    12.     MouPrint((2,"MOUCLASS-MouseClassRead: enter\n"));
    13.  
    14.     irpSp = IoGetCurrentIrpStackLocation(Irp);
    15.  
    16.     deviceExtension = (PDEVICE_EXTENSION) Device->DeviceExtension;
    17.     if (irpSp->Parameters.Read.Length == 0) {
    18.         status = STATUS_SUCCESS;
    19.     } else if (irpSp->Parameters.Read.Length % sizeof(MOUSE_INPUT_DATA)) {
    20.         status = STATUS_BUFFER_TOO_SMALL;
    21.     } else if (IS_TRUSTED_FILE_FOR_READ (irpSp->FileObject)) {
    22.  
    23.         deviceExtension = (PDEVICE_EXTENSION) Device->DeviceExtension;
    24.         status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp);
    25.  
    26.         if (NT_SUCCESS (status)) {
    27.             status = STATUS_PENDING;
    28.         }
    29.     } else {
    30.         status = STATUS_PRIVILEGE_NOT_HELD;
    31.     }
    32.  
    33.     Irp->IoStatus.Status = status;
    34.     Irp->IoStatus.Information = 0;
    35.     if (status == STATUS_PENDING) {
    36.         IoMarkIrpPending(Irp);
    37.         IoStartPacket(Device, Irp, (PULONG)NULL, MouseClassCancel);
    38.     } else {
    39.         IoCompleteRequest(Irp, IO_NO_INCREMENT);
    40.     }
    41.  
    42.     MouPrint((2,"MOUCLASS-MouseClassRead: exit\n"));
    43.  
    44.     return(status);
    45. }
    46.  
     
  2. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    <font color="gray][ wish3</font><!--color--><font color="gray]: Обясните, пожалуста, как это работает и где же всетаки пакет обрабатываеться. ]</font><!--color-->



    В ДДК в разделе "Mouclass Driver Reference" очень многое объясняется. Схема такая: Mouclass общается с функциональным драйвером посредством callback'а, коий регистрируется функцией MouseClassServiceCallback. Когда происходит мышиное событие функциональный драйвер зовёт колбэк драйвера Mouclass, а тот заполняет свою внутреннюю очередь данными о событии. Когда к Mouclass приходит IRP_MJ_READ, он достает инфу из этой очереди и завершает IRP.



    Кстати, Kbdclass работает точно так же.
     
  3. wish3

    wish3 New Member

    Публикаций:
    0
    Регистрация:
    31 янв 2005
    Сообщения:
    29
    Адрес:
    Ukraine
    Перечитывал и Mouclass, и много чего, но так не нашел выход из своей проблемы. В написании драйверов я новичок, а хочеться дописать этот и ити дальше. Вобщем вот код обработки чтения, мне нужно подставлять свои даные IoCompletionRoutine не подходит. При перезагрузке с установленым драйвером я получаю только пикание. Помогите последний раз, очень прошу. Что я не так делаю??
    Код (Text):
    1.  
    2. NTSTATUS
    3. MouDrv_Read (
    4.         IN PDEVICE_OBJECT DeviceObject,
    5.         IN PIRP Irp
    6.         )
    7. {
    8.     PDEVICE_EXTENSION   devExt;
    9.     PMOUSE_INPUT_DATA MouseData;    
    10.     PIO_STACK_LOCATION currentIrpStack;
    11.     PIRP newIrp;
    12.     IO_STATUS_BLOCK iosb;
    13.     ULONG bytesToMove;
    14. //    
    15.  
    16.     #if DBG
    17.       DbgPrint("MouseDrv: Read started.");
    18.     #endif
    19.    
    20.     devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    21.     currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
    22.     bytesToMove = currentIrpStack->Parameters.Read.Length;
    23.  
    24.     Irp->IoStatus.Information = 0;    
    25.     if (currentIrpStack->Parameters.Read.Length == 0) {
    26.         Irp->IoStatus.Status = STATUS_SUCCESS;
    27.         IoCompleteRequest(Irp, IO_NO_INCREMENT);
    28.         return STATUS_SUCCESS;
    29.     } else if (currentIrpStack->Parameters.Read.Length % sizeof(MOUSE_INPUT_DATA)) {
    30.         Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
    31.         IoCompleteRequest(Irp, IO_NO_INCREMENT);
    32.         return STATUS_BUFFER_TOO_SMALL;
    33.     };
    34.     KeStallExecutionProcessor(40);
    35.     MouseData = Irp->AssociatedIrp.SystemBuffer;
    36.     MouseData->Flags |= MOUSE_MOVE_RELATIVE;
    37.     MouseData->LastX = 1;
    38.     MouseData->LastY = 1;
    39.  
    40.     Irp->IoStatus.Status = STATUS_SUCCESS; 
    41.     Irp->IoStatus.Information = sizeof(MOUSE_INPUT_DATA);
    42.     currentIrpStack->Parameters.Read.Length = sizeof(MOUSE_INPUT_DATA);
    43.     IoCompleteRequest( Irp, IO_NO_INCREMENT );
    44.     return STATUS_SUCCESS;
    45. }
    46.  


    Что я хочу сделать. Когда вы нажимаете на колесико, то появляется, рисунок в виде кольца на мониторе и теперь если мышу потянуть вниз и остановить, то страница начнет потихоньку прокручиваться и т.д. Я такое такое хочу сделать с обычным перемещением курсора, тоесть потянул мышу вниз, остановил и курсор потихонечку пополз вниз. Идея мне кажеться светлой, если напишу, то обязательно выложу исходники.
     
  4. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Почти всё правильно, окромя:



    <font color="red]currentIrpStack->Parameters.Read.Length = sizeof(MOUSE_INPUT_DATA);</font><!--color-->



    Эта строчка не нужна и вредна.





    <font color="gray][ wish3</font><!--color--><font color="gray]: получаю только пикание ]</font><!--color-->



    Поток RIT постоянно шлет IRP_MJ_READ в клавиатурный и мышиный стеки. Ты завершаешь IRP с интервалом в ~40 микросекунд тут же получаешь новый IRP. Т.е. RIT пытается опросить состояние мыши ~25000 раз в секунду! Т.к. у него довольно высокий приоритет - 19, то система только этим и занимается. А пищит, наверное из-за переполнения буфера клавиатуры, т.к. RIT не успевает забирать клавиатурные события.



    Вобщем, чтоб тебе с этим поиграться, вот код, который двигает мышь по диагонали вниз-вправо с интервалом 1 сек. Мышь при этом блокируется, т.к. Mouclass не получает IRP_MJ_READ. Когда наиграешься, сбрось g_bDo и всё должно заработать как обычно, при условии, что в DeviceExtension->TopDevice адрес нижестоящего драйвера. Код я не проверял - возможно, где-то чуть накосячил. Ну а для того, чтобы реализовать твою идею, код будет гораздо сложнее. Кстати, по-моему, это можно и без драйвера сделать, но как я не знаю, а думать некогда.




    Код (Text):
    1. BOOL g_bDo = TRUE;
    2.  
    3. NTSTATUS
    4. MouDrv_Read (
    5.     IN PDEVICE_OBJECT DeviceObject,
    6.     IN PIRP pIrp
    7.     )
    8. {
    9.  
    10.     NTSTATUS             status;
    11.     PIO_STACK_LOCATION   pIrpStack;
    12.     LARGE_INTEGER        liInterval;
    13.     PMOUSE_INPUT_DATA    pmd;  
    14.  
    15.     // _asm int 3
    16.  
    17.     if ( g_bDo ) {
    18.  
    19.         pIrpStack = IoGetCurrentIrpStackLocation( pIrp );
    20.  
    21.         if ( pIrpStack->Parameters.Read.Length >= sizeof(MOUSE_INPUT_DATA) ) {
    22.  
    23.             #define DELAY_ONE_MICROSECOND   (-10)
    24.             #define DELAY_ONE_MILLISECOND   (DELAY_ONE_MICROSECOND*1000)
    25.             #define DELAY_ONE_SECOND        (DELAY_ONE_MILLISECOND*1000)
    26.  
    27.             liInterval.QuadPart = DELAY_ONE_SECOND;
    28.             KeDelayExecutionThread( KernelMode, FALSE, &liInterval );
    29.  
    30.             pmd = pIrp->AssociatedIrp.SystemBuffer;
    31.  
    32.             pmd->Flags = MOUSE_MOVE_RELATIVE;
    33.             pmd->LastX = 1;
    34.             pmd->LastY = 1;
    35.  
    36.             pIrp->IoStatus.Status      = STATUS_SUCCESS;    
    37.             pIrp->IoStatus.Information = sizeof( MOUSE_INPUT_DATA );
    38.  
    39.         } else {
    40.  
    41.             pIrp->IoStatus.Status      = STATUS_BUFFER_TOO_SMALL;
    42.             pIrp->IoStatus.Information = 0;
    43.         }
    44.  
    45.         status = pIrp->IoStatus.Status;
    46.  
    47.         IoCompleteRequest( pIrp, IO_NO_INCREMENT );
    48.  
    49.         return status;
    50.  
    51.     } else {
    52.  
    53.         IoSkipCurrentIrpStackLocation( pIrp );
    54.         return IoCallDriver( ((PDEVICE_EXTENSION) DeviceObject->DeviceExtension)->TopDevice, pIrp );
    55.     }
    56. }
     
  5. wish3

    wish3 New Member

    Публикаций:
    0
    Регистрация:
    31 янв 2005
    Сообщения:
    29
    Адрес:
    Ukraine
    Большое спасибо за код! Главное, теперь я знаю, что действую в нужном направлении.

    ...к сожелению при загрузке опять одно пикание, только с унтервалом в одна секунда...я думаю что поток RIT хочет еще какието даные в структуре MOUSE_INPUT_DATA увидеть..

    ...В любом случее сейчас постараюсь освоить SoftIce, о ее командах я уже читал по H, .. сейчас ламаю голову как сбилдить драйвер с исходниками и загрузить его в SoftIce. Неподскажите??
     
  6. wish3

    wish3 New Member

    Публикаций:
    0
    Регистрация:
    31 янв 2005
    Сообщения:
    29
    Адрес:
    Ukraine
    Дебугить драйвер айсом научился, но есть проблемы:

    1. В коде дравера делаю KdBreakPoint();

    ...

    занимаемся отладкой

    ...

    не хотим больше заниматься отладкой

    i3here off

    рухаем мышой, тогда исполниться KdBreakPoint() и система сразу вырубуеться



    2. Как увидить исходный драйвера код в айсе.
     
  7. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    <font color="gray][ wish3</font><!--color--><font color="gray]: тогда исполниться KdBreakPoint() и система сразу вырубуеться ]</font><!--color-->



    Естественно. Пока у тебя стояло i3here on или i3here drv SoftICE отлавливает третье прерывание, которое и генерит функция KdBreakPoint. Когда ты выключил i3here, ловить int3 стало некому. И система показывает BSOD, но у тебя стоит галка Свойства системы -> Загрузка и восстановление -> Выполнить автоматическую перезагрузку. Убери её и тогда вместо ребута увидишь голубой экран.



    В таких случаях я делаю так. В коде драйвера пишешь стороку.



    _asm int 3



    Это тоже самое, что и KdBreakPoint, но намного удобнее. Это однобайтовая инструкция с кодом CCh. В айсе будешь трапаться прямо за этой строкой. Если трапаться больше не надо, нужно просто заменить CC (int3) на 90 (инструкция nop). Если ты не перемещался по коду, то просто набери eb eip-1 и увидишь в окне дампа CC, замени его на 90.



    Кстати, я подозреваю, что ты пользуешься "Checked Build Environment", но работаешь в релизной версии системы. Если это так, то очень плохо.





    <font color="gray][ wish3</font><!--color--><font color="gray]: Как увидить исходный драйвера код в айсе. ]</font><!--color-->



    Запусти SoftICE Symbol Loader. Перетащи к нему на окошко свой драйвер. Рядом с драйвером должен лежать .pdb - айс транслирует его в .nms. Если всё ОК, то увидишь код. Я помню, очень радовался, когда в айсе исходник увидел, прямо со всем комментариями ;) Только учти, что айс иногда может показать неверную строку, т.е. стоишь на одной, а он показывает, что на следующей и т.п. Переключаться между исходником, дизасмом и смесью оных можно по команде src.





    <font color="gray][ wish3</font><!--color--><font color="gray]: к сожелению при загрузке опять одно пикание ]</font><!--color-->



    Мышиный стек разрешает не-Pnp драйвера. Если ты постоянно ребутишься, так ты много не накодишь. Сделай legacy драйвер. В аттаче слегка модифицированный пример из 16 части. По правому щелчку 20 раз дергает курсор по диагонали - код аналогичен, вышеприведенному сишному. Изменения помечены "BAD CODE". Драйвер загружается/выгружается динамически без проблем, но для usb мышей не работает - подробности в статье, если не читал.





    Уфф...
     
  8. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
  9. wish3

    wish3 New Member

    Публикаций:
    0
    Регистрация:
    31 янв 2005
    Сообщения:
    29
    Адрес:
    Ukraine
    Спасибо за помощь.

    Если в системе есть две мыши, то как в реестре сделать записи, чтобы PnP-менеджер грузил мой фильтр только в стэк одной из них?

    Например, есть:

    SYSTEM\CurrentControlSet\Control\Class\{4D36E96F-E325-11CE-BFC1-08002B E10318}

    ....\0000\DriverDesc == PS/2-совместимая мышь

    ....\0001\DriverDesc == Microsoft USB IntelliMouse оптическая мышь

    Я перепробовал самые разные комбинации параметров UpperFilters, но ничего не добился.

    Возможно ли такое сделать?
     
  10. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Эта ветка реестра для всех устройств класса "мышь". В параметре UpperFilters определяются так называемые "Upper-level class filter drivers". Сам mouclass тоже является "Upper-level class filter driver".



    В общем виде стек может выглядеть так:



    Upper-level class filter driver

    Upper-level device filter driver

    Function driver

    Lower-level class filter driver

    Lower-level device filter driver

    Bus filter driver

    Bus driver



    Для того, чтобы поставить фильтр на конкретную мышь нужен "Upper-level device filter driver", но тогда он окажется под mouclass и должен будет работать по другим правилам. См. пример DDK\src\input\moufiltr. Вобщем я не знаю, можно ли заставить систему воткнуть "Upper-level class filter driver" в конкретный стек. Если узнаешь, расскажи. Но я бы не парился. Пусть твой фильтр болтается в обоих стеках, а девайсы различай по HardwareId.
     
  11. wish3

    wish3 New Member

    Публикаций:
    0
    Регистрация:
    31 янв 2005
    Сообщения:
    29
    Адрес:
    Ukraine
    Сделал по HardwareId.

    Спасибо за помощь.
     
  12. wish3

    wish3 New Member

    Публикаций:
    0
    Регистрация:
    31 янв 2005
    Сообщения:
    29
    Адрес:
    Ukraine
    Four-F



    Это так.(((

    Почему плохо? В плане, что я не смогу вкусностей отладочной винды заюзать, или в плане, что мне надо перейти в "Free Build Environment"?
     
  13. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Драйвер оказывается заточенным под отладочную версию системы. Некоторые функции могут быть к этому чувствительны. К тому же, "в плане вкусностей отладочной винды", это мало что дает. Разве что IoInitializeRemoveLock, IoAcquireRemoveLock, IoReleaseRemoveLock...



    Можно накатить только дебужные ntoskrnl и hal. В ДДК даже есть раздел "Installing Just the Checked Operating System and HAL"