Мое почтение всем. Пара вопросов по этим ф-иям. 1. MmGetSystemAddressForMdlSafe -- макрос проверяет, есть ли отображение для MDL в адресном пространстве ядра и если нет, то создает его с помощью MmMapLockedPagesSpecifyCache. Вопрос в том, как я узнаю, было ли создано отображение или нет в случае получения MDL извне. Т.е. как я узнаю, надо ли вызвать MmUnmapLockedPages или нет. Если драйвер, передавший MDL уже отобразил его в адреса ядра, то MmMapLockedPagesSpecifyCache вызвана не будет, мне вернется существующий виртуальный адрес. В этом случае вызывать MmUnmapLockedPages не надо. Если отображения не было, то вызвать MmUnmapLockedPages надо. Но как это узнать? Или я чего-то недопонимаю в использовании этой ф-ии? 2. Встретил в интернете такой код: Код (Text): if(pMmMapLockedPagesSpecifyCache != NULL) { MmProbeAndLockPages(Irp->MdlAddress, KernelMode, Operation); IrpContext->LockedCount++; if(Irp->MdlAddress->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL)) { IrpContext->LockedBuffer = Irp->MdlAddress->MappedSystemVa; } else { IrpContext->LockedBufferMdl = Irp->MdlAddress; IrpContext->LockedBuffer = pMmMapLockedPagesSpecifyCache( Irp->MdlAddress, KernelMode, MmCached, NULL, FALSE, NormalPagePriority); } } Сначала идет вызов MmProbeAndLockPages, затем MmMapLockedPagesSpecifyCache. Код, как я понимаю, работает. Но почему нет вызова MmBuildMdlForNonPagedPool? Ведь MmProbeAndLockPages не создается PFN'ы для MDL. Заранее благодарю за ответ.
Mika0x65 А откуда, например, известно, что память, описываемая полученным от левого драйвера MDL, залочена?
l_inc Это обязанность драйвера -- передавать MDL, которые probed and locked, если верить восьмому посту здесь: http://www.osronline.com/showThread.cfm?link=68730. Вопрос в том, как MDL была создана. Если это, например, MmBuildMdlForNonPagedPool, то вызывать MmUnlockPages не надо. А если MmProbeAndLock, то надо. Кстати, MmBuildMdlForNonPagedPool сразу выделяет виртуальную память в адресах ядра, насколько я понимаю. Интересно, атрибуты доступа страниц копируются? Я просто думаю об использовании MmBuildMdlForNonPagedPool для записи, например, в SSDT вместо сброса CR0.WP, т.к. это, вроде, более стабильно. С другой стороны вызывать MmMapLockedPagesSpecifyCache для MDL, построенной с помощью MmBuildMdlForNonPagedPool нельзя, подозреваю от того, что при вызове MmMapLockedPagesSpecifyCache будет перезаписан MDL::MappedSystemVa, что чревато утечкой виртуальных адресов. Еще не проверял, так, просто подумалось в эту сторону.
Mika0x65 Ни в каком случае не надо. Если передающий драйвер сам лочил страницы, он сам же их и разлочит. А MmUnlockPages в том числе и размапит страницы из системного АП, если они там присутствуют.
l_inc Ага, прочитал про MmUnlockPages есть там такое: С другой стороны в описании MmGetSystemAddressForMdlSafe написано: Насчет MmUnlockPages и MDL::MappedSystemVa понятно, с другой стороны интересно, что имелось в виду в описании MmGetSystemAddressForMdlSafe.
l_inc Я пост исправил . Пока ответ читал, отвлекли, потом перечитал справку к MmUnlockPages, все сошлось. Вопрос, правда, остался, но это уже просто любопытство.
Mika0x65 Ну если просто любопытство, то по большому счёту что мешает вместо явного использования макроса раскрыть его и проверять MdlFlags самостоятельно так же, как это сделано в коде из #1?
l_inc Тот подход работать будет, но он не совсем правильный в том смысле, что теоретически нельзя напрямую читать MDL::Flags. Если есть возможность делать документированным способом, то лучше делать им. Ну а по сути я на все вопросы ответы уже получил, спасибо.