День добрый, товарищи! Такой вопрос, у меня драйвер-перехватчик открытия файлов(ntCreateFile, перехват через SDT). Он должен фильтровать обращения юзеров к определенным файлам, но критерии фильтра в самом драйвере не находятся. Все уславия и проверки должны выполняться в Юзермодном приложении. А теперь вопрос: как можно обеспечить двустороннее "общение" между этими программами? Т.е: - драйвер перехватил открытие файла (это есть); - получил его имя (есть) - передал его юзермодномe апп (сейчас это реализовано через Event(CreateEvent, etc)) - получил ответ от апп, в котором сказано: блокируем или нет (нету ) - шуруем дальше (есть ) Вот собственно и все. Передача данных от драйвера в приложение реализовано по примеру статьи Four-F "Драйверы режима ядра: Часть 14: Базовая техника. Синхронизация: Использование объекта /03.08.04/" (Thnx). Буду рад любой помощи, но хотелось бы по-существу
Я просто не знаю возможно ли такое. Ведь я могу из-под своего обработчика ntCreateFile установить Event и апп заберет новые данные, но чем в это время должен заниматься сам обработчик? Ведь он должен еще каким-то макаром получить ответ. Будет ли все это работать параллельно(обработчик ntCreateFile и рабочая процедура обработки IRP)? Если да, тогда можно ставить какие-то задержки в ntCreateFile. Как тут лучше поступить? И как все это счастье будет работать в условиях паралелльно работающих нескольких процессов, работающих с файлами...
Использовать общую область памяти - ядро выделяет ядерную неподкачиваемую память и проецирует вторую проекцию на пользовательское пространство. Сделать в памяти так - один бит - будет Present-бит и означать то, что информация готова. Остальная часть памяти будет хранить информацию. Пользовательский процесс ждет установки бита P и сразу считывает информацию из этой области. А драйвер записывает информацию в буфер и выставляет бит P. Вообщем, простейшие еденицы синхронизации
Понятно. Вот только я немного торможу от фразы Можешь немного разъяснить? Я с этим знаком плехо-плехо...
ExAllocatePoolWithTag - выделение памяти ядра, указывай пул NonPagedPool (пул неподкачиваемой памяти) IoAllocateMdl выделяет структуру Memory Descriptor List (MDL), необходимую для операций с проекциями областей памяти. MmBuildMdlForNonPagedPool заполнит структуру MDL физическими адресами страниц выделенной памяти и блокирует (возможно, я перевел немного криво, потому что слово "блокировать" обычно имеет отрицаиельный оттенок, а тут lock используется в смысле "прикреплять") область памяти. MmMapLockedPagesSpecifyCache создает проекцию заблокированных страниц, указывай ей тип доступа UserMode, что означает, что память будет доступна из пользовательского кода После этих махинаций, если драйвер запишет что-нибудь в свой указатель, который вернула ExAllocatePoolWithTag, то эта память будет доступна так же и по юзеомодному указателю, который вернет MmMapLockedPagesSpecifyCache. И наоборот. Таким образом память разделяется между драйвером и пользовательским процессом.
Понял. А в Апп я должен просто передать указатель. И еще один вопрос: как лучше организвать ожидание на драйверной стороне. Что-то мне подсказывает что никакие Слипы там не пройдут
dr_ivers Почитай Four-F (http://www.wasm.ru/article.php?article=drvw2k09) и вообще заучи все его статьи , там основа. И тогда этот вопрос бы отпал .
Страннейшее дело... Создаю область памяти так как объяснил Great (thankx). Дальше записываю туда к примеру "TestString" (используя wcscpy()). Выводим через DPRINT по кернеловскому указателю - все Ок, наша строка. В Апп (на Visual Basic ) принимаю указатель на юзерспейс-указатель и т.п. но когда пытаюсь прочесть оттуда строку получаю: "T\0e\0T\0e\0", т.е. "TeTe" в юникоде. Читаю используя RtlMoveMemory(). Код драйвера: Код (Text): PVOID MapInUserSpace(PVOID pBuf, PMDL *pMdl, ULONG dwSize){ PVOID pUserModeBuf = NULL; PMDL pBufMdl = NULL; if (!pMdl) return NULL; pBufMdl = IoAllocateMdl(pBuf, dwSize, FALSE, FALSE, NULL); if (!pBufMdl) goto exit; MmBuildMdlForNonPagedPool(pBufMdl); pUserModeBuf = MmMapLockedPagesSpecifyCache(pBufMdl, UserMode, MmCached, NULL, FALSE, NormalPagePriority); exit: *pMdl = pBufMdl; return pUserModeBuf; } VOID UnmapInUserSpace(PMDL pMdl, PVOID pPool, PVOID pUserModeBuf, ULONG Attrib){ if (pUserModeBuf) MmUnmapLockedPages(pUserModeBuf, pMdl); if (pMdl) IoFreeMdl(pMdl); if (pPool) if (Attrib) ExFreePoolWithTag(pPool, ' gaT'); else ExFreePool(pPool); } .... .... .... pszBuffer=(PWSTR)ExAllocatePoolWithTag(NonPagedPool, 0x1000, ' gaT'); if (pszBuffer) { RtlZeroMemory (pszBuffer, 0x1000); pszUserBuffer=MapInUserSpace(pszBuffer, &pBufferMdl2, 0x1000); RtlZeroMemory(pszBuffer, 0x1000); wcscpy(pszBuffer, L"Test string"); } .... .... .... И Апп(ВБ): Код (Text): ReceiveBuffer="" CopyMemory Buffer(0), Driver.SharedPointer, 12 For i = 0 To 11 ReceivedBuffer = ReceivedBuffer & Chr(Buffer(i)) Next i Driver.SharedPointer - полученный от драйвера указатель на юзермодную проекцию буфера. CopyMemory - псевдоним RtlMoveMemory()
А сорц функций взял у меня :P Код (Text): if (pszBuffer) { RtlZeroMemory (pszBuffer, 0x1000); pszUserBuffer=MapInUserSpace(pszBuffer, &pBufferMdl2, 0x1000); RtlZeroMemory(pszBuffer, 0x1000); wcscpy(pszUserBuffer, L"Test string"); } Так не пробовал?
n0name Да, ф-ции твои, за что тебе привеликий Thanks! (посик рулит) А что касается совета - БСОД... Да и не правильно это как-то...