проблема с MmGetSystemAddressForMdlSafe

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

  1. Kola

    Kola New Member

    Публикаций:
    0
    Регистрация:
    23 июн 2004
    Сообщения:
    69
    Ситуация...

    код выполняется в обработчике IRP_MJ_DEVICE_CONTROL (METHOD_BUFFERED)

    1) имеем указатель на 8 байт в юзер памяти процесса (передается через Irp->UserBuffer)

    2) аллокирую MDL -

    IoAllocateMdl(buff, cb, FALSE, TRUE, NULL);

    3) локирую MDL - MmProbeAndLockPages(mdl, UserMode, IoWriteAccess);

    4) вызываю MmGetSystemAddressForMdlSafe (сиречь MmMapLockedPadeSpecifyCache )

    ...и получаю кернел мод буффер, который нихрена не замаплен с изначальным буффером :dntknw:

    затем все это дело падает с треском где-то далеко в кишках ntoskrnl



    мучию код с утра и не пойму почему не работает :dntknw:((

    может с Irp->UserBuffer ядро что-нибыть злое проделывает?
     
  2. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Если METHOD_BUFFERED, то всё уже отмаплено и залочено, а адрес замапленного буфера в Irp->AssociatedIrp.SystemBuffer. Irp->UserBuffer для METHOD_NEITHER, а при METHOD_BUFFERED система запоминает там адрес выходного юзерного буфера, чтобы при завершении IRP скопировать туда данные из системного буфера и юзать его, наверное, не стОит.
     
  3. Kola

    Kola New Member

    Публикаций:
    0
    Регистрация:
    23 июн 2004
    Сообщения:
    69
    Irp->AssociatedIrp.SystemBuffer уже используется для других целей - переделать не могу изза backward compatibility :dntknw:(
     
  4. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Не понял. При чем здесь "backward compatibility"? У тебя баг! Ты пытаешься использовать Irp->UserBuffer неправильным образом. А для каких целей может использоваться Irp->AssociatedIrp.SystemBuffer в методе METHOD_BUFFERED, кроме указателя на системный буфер с пользовательскими данными?
     
  5. Kola

    Kola New Member

    Публикаций:
    0
    Регистрация:
    23 июн 2004
    Сообщения:
    69
    в общем-то проблема порешилась - был чисто кодерский баг :)



    backward compatibility при том что нежелательно было менять протокол обмена между драйвером и приложением

    там из приложения приходит два буффера:

    Irp->AssociatedIrp.SystemBuffer и Irp->UserBuffer

    соотвественно это lpInBuffer и lpOutBuffer в DiviceIoControl-е



    В программе которую я корёжил он используется для передачи результата в приложение из драйвера и поскольку оно всегда выполнялась в контексте приложения все работало.

    Из-за изменений в железке пришлось переделать обработчик одного из IoControl запросов с polled mode на interrupt и IoCompleteRequest вызывается после соответствующего прерывания в DPC. Естественнно с UserBuffer возникла проблема и пришлось его лочить и мапить...

    вот такая беда :)



    Вот вопрос - как живет Irp->UserBuffer при METHOD_BUFFERED?

    Я так понял что с ним ядро ничего не делает - просто передает адресс и все...

    типа как в METHOD_NEITHER
     
  6. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    [ Kola: <font color="indigo]там из приложения приходит два буффера:

    Irp->AssociatedIrp.SystemBuffer и Irp->UserBuffer

    соотвественно это lpInBuffer и lpOutBuffer в DiviceIoControl-е
    </font><!--color--> ]



    При использовании метода METHOD_BUFFERED из приложения в драйвер вообще ничего не приходит. Система выделяет буфер в системном же пространстве, равный по размеру максимуму от InBufferSize и OutBufferSize и копирует туда входной пользовательский буфер, а указатель на системный буфер пихает в Irp->AssociatedIrp.SystemBuffer. Драйвер забирает оттуда входные данные, что-то делает с ними и если нужны выходные данные пихает их в тот же самый системный буфер. Завершая IRP, система копирует из системного буфера данные в пользовательский выходной буфер. А чтобы знать адрес этого буфера она и запоминает его в поле irp->UserBuffer и ставит в IRP флажок IRP_INPUT_OPERATION. Драйвер работает только с системным буфером! Ты не должен юзать irp->UserBuffer. Ну, может до завершения IRP и можно акуратно заюзать, но только зачем? Система сама скопирует всё туда куда надо.





    [ Kola: <font color="indigo]Вот вопрос - как живет Irp->UserBuffer при METHOD_BUFFERED?</font><!--color--> ]



    См. выше и учи матчасть.