Опрос драйвера

Тема в разделе "WASM.NT.KERNEL", создана пользователем DeeoniS, 3 авг 2007.

  1. DeeoniS

    DeeoniS New Member

    Публикаций:
    0
    Регистрация:
    6 авг 2004
    Сообщения:
    132
    Есть драйвер который шарит свою память в юзермод. Клиентское приложение обращается к драйверу через посулку IOCTL запроса, а тот в свою очередь должен вернуть в буфере адрес расшаренной памяти. Вот код обработки запроса в драйвере:
    Код (Text):
    1.     inputBuffer        = Irp->AssociatedIrp.SystemBuffer;
    2.     inputBufferLength  = irpStack->Parameters.DeviceIoControl.InputBufferLength;
    3.     outputBuffer       = Irp->AssociatedIrp.SystemBuffer;
    4.     outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
    5.  
    6.     switch (ioControlCode)
    7.     {
    8.     // ...
    9.     case GET_SHARED_MEMORY:
    10.         if (outBufferLength >= sizeof(PVOID))
    11.         {
    12.             *(PVOID*)outputBuffer = ShareMem(PAGE_SIZE*4);
    13.         }
    14.         break;
    15.     // ...
    16.     }
    В клиентском приложение делаю так:
    Код (Text):
    1.     PVOID lpSharedMem = NULL;
    2.  
    3.     DeviceIoControl(m_hDev_, GET_SHARED_MEMORY, &lpSharedMem, sizeof(PVOID), &lpSharedMem, sizeof(PVOID),
    4.         &ReturnedLength, NULL);
    5.  
    6.     // lpSharedMem всегда равен нулю
    7.     if (lpSharedMem == NULL)
    8.         return FALSE;
    После вызова DeviceIoControl переменная lpSharedMem остается равной нуля, хотя при отладке драйвера видно что в буфер записывается значение отличное от нуля. GET_SHARED_MEMORY определен так:
    Код (Text):
    1. #define GET_SHARED_MEMORY   CTL_CODE(FILE_DEVICE_TEST, FIRST_IOCTL_INDEX + 103, METHOD_BUFFERED, FILE_ANY_ACCESS)
    В чем тут может быть дело???
     
  2. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    IO Manager может не отмапливать системный буфер на пользовательский, если у хендла нет нужных прав. См. есть ли у тебя флаг GENERIC_READ (или более специфичный read-флаг) в вызове CreateFile.

    ЗЫ: IMHO, в данном случае входных данных нет, поэтому параметры 3 и 4 в DeviceIoControl излишне вредны.
     
  3. DeeoniS

    DeeoniS New Member

    Публикаций:
    0
    Регистрация:
    6 авг 2004
    Сообщения:
    132
    собственно вот
    Код (Text):
    1.     m_hDev_ = CreateFile(DevName, GENERIC_READ | GENERIC_WRITE, 0,
    2.                         NULL, OPEN_EXISTING, 0, NULL);
     
  4. Four-F

    Four-F New Member

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

    Ну и проверь есть ли.
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = sizeof(PVOID);
    IoCompleteRequest( Irp, IO_NO_INCREMENT );
     
  5. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Four-F
    скорее всего он это и забыл сделать ;)
     
  6. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    А заполняется Irp->IoStatus.Information ?)
    Жопой чую что ReturnedLength=0 после вызова
     
  7. DeeoniS

    DeeoniS New Member

    Публикаций:
    0
    Регистрация:
    6 авг 2004
    Сообщения:
    132
    Four-F, Great
    про Irp->IoStatus.Information я что забыл... оно у меня всегда равно нулю... Завтра проверю что будет если правлиьно заполню..

    А как это мжет повлиять на то что пишется или в буфер данные??? Просто я думал что это чисто дополнительно-информативные данные... т.е. на работу драйвера не могут так повлиять...
     
  8. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Читай подробнее под буферизированный ввод-вывод у драйвера.

    Вообщем, в двух словах дело обстоит так. В IO Control Code задается метод ввода-вывода, у тебя он как раз равен METHOD_BUFFERED, то есть ты используешь буферизированный ввод-вывод. Менеджер ввода-вывода при вызове DeviceIoControl -> ZwDeviceIoControlFile видит это и выделяет системный буфер в ядерных адресах, размер которого равен наибольшему из указанных размеров входного и выходного буферов. Дальше в него копируется входной буфер и вызывается Dispatch-функция драйвера для IRP_MJ_DEVICE_CONTROL.
    Дальше, главное! При завершении IRP менеджер ввода-вывода смотрит число Irp->IoStatus.Information - там драйвер должен указать число байт, которые он записал в системный буфер. Именно это число байт он скопирует в пользовательский выходной буффер. Если оно равно нулю, НИЧЕГО в выходном буфере ты не обнаружишь.

    За подробностями Welcome to MSDN & статьи Four-F'а про драйвера.
     
  9. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Забыл сказать, что тоже самое действует при буферизированном вводе (или выводе) в операциях записи (чтения) по IRP_MJ_WRITE (IRP_MJ_READ), соответственно.
     
  10. DeeoniS

    DeeoniS New Member

    Публикаций:
    0
    Регистрация:
    6 авг 2004
    Сообщения:
    132
    Интересно а почему именно столько, а не все что есть в буфере... ведь туда уже все записанно и врядли я копировав туда 10 байт захочу чтоб в юзер мод попало всего 9...
     
  11. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Смотри, например у тебя размер входного буфера 20 байт, а выходного 15 байт.
    Менеджер ввода-вывода выделит системный буфер размером MAX(20,15)=20 байт и скопирует туда содержимое входного буфера.
    Дальше что ты ему прикажешь делать то? Ему нужно знать сколько драйвер туда реально записал байтов? Как он может скопировать все содержимое буфера (20 байт) в юзермодный выходной буфер (15 байт) ? А вдруг буфер выделен с запасом и реально туда записано должно быть только 4 байта?
    Для этого как раз в Irp->IoStatus.Information драйвер должен записать, сколько байт менеджер должен скопировать в выходной буфер.
     
  12. DeeoniS

    DeeoniS New Member

    Публикаций:
    0
    Регистрация:
    6 авг 2004
    Сообщения:
    132
    все равно как-то не логично... пусть копит не 20, а 15 а то что с запасом это уже дело клиента... он сам разберется....

    А вот кстати если я в Irp->IoStatus.Information запишу 25 вместо максимума в 15, то что IO менеджер деалть будет...
     
  13. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Не помню насчет того, есть ли там проверки. Но лучше так не делать. Обычно размер выходного буфера проверяют вначале и ругаются, если его не хватает.

    Что значит разберется? Вполне логично. Представь, что драйвер может отдать по каким-то там своим причинам от 4 до 8 байт данных. Я конечно же задаю выходной буфер 8 байт. Как изволите мне дальше определять сколько байт реально вернул драйвер, а сколько скопировано "с запасом" ? Как раз ReturnedLength - последний (кажется) параметр DeviceIoControl и берется из этого поля Irp->IoStatus.Information
    И ничего нелогичного я не вижу
     
  14. DeeoniS

    DeeoniS New Member

    Публикаций:
    0
    Регистрация:
    6 авг 2004
    Сообщения:
    132
    Ну просто избыточность некоторая получается... Можно например весь буфер забить нулями и тогда точно будешь знать сколько байт пришло от драйвера... Вообщем еслиб я писал ядро, я бы по другому сделал :)
     
  15. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    А если от драйвера пришли нули?

    Как нам повезло, что это был не ты ;)
     
  16. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    DeeoniS
    Я еще раз пытаюсь пояснить что избыточности нет. В любом случае нужно знать, сколько байт вернул драйвер. Ты же не знаешь сколько он вернет заранее (за искл. реедких случаев) и выделяешь буфер побольше, чтобы все вместилось если что.
    Поэтому тебе нужно как-то узнать, сколько он тебе вернул. И никакой избыточности я не вижу..

    Хорошо, предложи действительно более разумный вариант.

    Four-F
    Да уж:)