Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Преобразование "на лету" буфера в MDL  (Прочитано 9768 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Yarilo
Гость
« : 19-09-2003 16:22 » 

Проблемка следующего характера:
драйвер-фильтр (USB) передает информацию в приложение. Все хорошо. Но вот возникла задача, реализовать отправку полученных блоков URB на выполнение низлежащим драйвером. Вот тут и появляется неприятность. Нужно "налету" преобразовывать буфер, переданный драйверу от приложения в формат MDL. Скажем я с MDL не часто сталкивался, поэтому как это сделать правильно не знаю Жаль. Да и еще, расположение в стеке драйвера не меняется, все описатели для интерфейсов и pipe-ов остаются в силе, т.е. не меняются (это точно проверил, даже checked build молчит, пакеты с обычным буфером (не MDL) выполняются нормально). Все что пришло в голову это сделать так:
Код:

PMDL        pMdl;
PMDL *pMdlBuffer; // по этому адресу должен находиться PMDL
PMDL *ppMdl;        // существует, чтобы потом освободить PMDL
ULONG      bufLength;

if)*pMdlBuffer:
|
pMdl = IoAllocateMdl)buffer, bufLength, FALSE, FALSE, )PIRP: NULL:;
ASSERT)pMdl:;
if)pMdl:
|
*pMdlBuffer = pMdl;
*ppMdl = pMdl;
"
else
|
DbgPrint)"ERROR{ can't map MDL!\n":;
*ppMdl = NULL;
return FALSE;
"
Но вот драйвер ругается страшно что-то ему не нравится, чуть позже я выложу код ошибки (SoftIce глючит пока).
После выполенения низлежащим драйвером я вызываю:
Код:
if)*ppMdl:
|
IoFreeMdl)*ppMdl:;
"
Правильно ли я это делаю? Наверняка, существует более правильный способ.?
С уважением Ярослав.
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #1 : 22-09-2003 06:47 » 

И правильно он на тебя ругается.
IoAllocateMdl тошлько создает MDL, но не инициализирует указатели на страницы и не блокирует их в памяти. Надо заблокировать страницы, потом проинициализировать MDL - это делает ф-ция MmProbeAndLockPages, а потом желательно отобразить на системное адресное пространство, чтобы не было проблем с контекстом.

То есть последовательность действий такая.

IoAllocateMdl
MmProbeAndLockPages()
MmMapLockedPagesSpecifyCache(...KernelMode...) или MmMapLockedPages(...KernelMode) или MmGetSystemAddressForMdlSafe.

Не забудь MmUnmapLockedPages и MmUnlockPages(), IoFreeMdl!
Записан
Yarilo
Гость
« Ответ #2 : 22-09-2003 08:23 » 

Спасибо.
У меня еще на выходных заработало, я делал так:

IoAllocateMdl()
MmBuildMdlForNonPagedPool()

С уважением Ярослав.
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #3 : 22-09-2003 09:18 » 

Цитата

IoAllocateMdl()
MmBuildMdlForNonPagedPool()


Что-то я сомневаюсь в работоспособности такого кода для буфера, переданного из приложения. Этот код работает для буфера, созданного в неподкачиваемом пуле ядра или отображенного на него(тогда при чем тут приложение?). Если буфер в приложении выделен, то работать этот код будет при двух условиях
1) Контекст не меняется
2) Страницы не вытесняются.
Ты можешь гарантировать это для нижнего драйвера?
Записан
Yarilo
Гость
« Ответ #4 : 22-09-2003 10:26 » 

Да sorry, я описался
Цитата

драйвер-фильтр (USB) передает информацию в приложение.

  наоборот от приложения к драйверу.
Я передаю URB, со всеми буферами из приложения в драйвер, через DeviceIoControl с использованием метода Buffered I/O. Т.е. насколько я понимаю, содержимое памяти приложения копируется в драйвер. Кстати, какой тип памяти при этом методе в драйвере используется? (NonPaged или Paged). Я думаю, что NonPaged. Так вот, затем я анализирую сам URB и если для этого блока нужно передать именно MDL, то я формирую свой MDL, указывающий на буфер в памяти драйвера, подставляю его в URB и отдаю на исполнение низлежащим драйвером. После того, как драйвер этот запрос выполнил, освобождаю MDL. И все довольны. Разве не так?
Записан
Anonymous
Гость
« Ответ #5 : 22-09-2003 10:52 » 

Цитата

наоборот от приложения к драйверу


Я так и понял, и отвечал именно про это, но я думал, что буфер в юзер моде.
Все что делает ф-ция MmBuildMdlForNonPagedPool()
- это берет виртуальные адреса по которым находятся буфера, описываемые MDL, и в соответствии с ними прописывает массив указателей на физические страницы. Поэтому ее можно использовать для буферизованного ввода-вывода при условии что буфер в невыгружаемой области.
 Где выделяется буфер я не знаю, у меня нет уверенности, что он в неподкачиваемом пуле.
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #6 : 22-09-2003 11:08 » 

Это я был. Опять автоматическая регистрация не сработала.

Я отдебагил вызов  NtDeviceIoControl похоже там создают буфер при помощи ф-ции ExAllocatePoolWithQuotaTag с типом пула NonPagedPoolCacheAligned.
 Так что тебе повезло.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines