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

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

ru
Offline Offline

« : 21-10-2008 16:55 » 

Прочитав https://forum.shelek.ru/index.php/topic,7559.0.html понял что можно сделать заготовку в Driver Studio. Скачал, поставил, все гуд, вот только никогда не имел дела с этим и разобраться не смог, пока. Может кто-нибудь подскажет как сгенерить "рыбу"? Задача из пользовательского приложения передавать в функцию драйвера два параметра (адрес памяти и ноль). Ну и соответственно после этого в указанный мною адрес памяти должен записаться ноль-) В дравере использую mmMapIoSpace. Заранее спасибо! И в чем разница между IRP_MJ_READ|WRITE и ИОКонтролами тоже не совсем понял?

to Ochkarik:
Огромное спасибо за ответы! Очень помогают.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 21-10-2008 19:29 » 

если DriverStudio поставилась после VS то....
открываешь VS создаешь новый проект.
тебе VS предлагает на выбор несколько визардов. среди них надо найти визард от драйверов. далее по шагам все будет понятно)

2. разнаца следующая.
вызов функций драйвера из приложения можно реализовать несколькими способами.
IRP_MJ_READ|WRITE - в этом случае приложение вызывает драйвер через функции ReadFile/WriteFile
IRP_MJ_IOCTL - функцию DeviceIOControl

в первом случае передача данных только через MDL, ну и соответственно специфика функции Read/WriteFile - смещение, длинна. в приложение возвращается только статус операции. Поэтому удобно использовать в случаях когда направление передачи данных в одну сторону.
во втором - разнообразие больше: DeviceIOControl - одновременно передает данные в обе стороны - есть входной/выходной буфер. способ передачи - на выбор: MDL, указатель напрямую, либо путем копирования(буферизации) данных. этим способом очень удобно вызывать функции которые имеют входные параметры и возвращают данные.

Есть некоторые грабли с правами доступа (пока честно говоря сам не разобрался)... но возможно - для обращения через DeviceIOControl - нужны более привелегированные права доступа (мои измышления!). по крайней мере под вистой - до сих пор не смог корректно их задать через INF файл. но в любом случае можно запустить приложение с помткой "с правами администратора" и все будет ок.

PS про MDL
Цитата
Диспетчер памяти использует структуру MDL для описания набора страниц физической памяти, составляющих буфер виртуальной памяти в контексте памяти некоторого процесса. Интерпретация MDL не зависит от контекста памяти, поскольку MDL оперирует со страницами физической памяти. Получив для данного буфера описание в виде MDL, драйвер в дальнейшем может использовать буфер в контексте памяти любого процесса. Для того, чтобы обращаться к такой памяти, необходимо получить для MDL адрес памяти в системном адресном пространстве. Сделать это можно с помощью функции MmGetSystemAddressForMdl().
http://www.realcoding.net/article/view/3317

PS у вас объем данных ничтожный, что использовать - все равно. мне болье нравится DeviceIOControl.... вот только с правами доступа как-нибудь разобраться бы...
займитесь рыбой от драйвер-студии - там будет и такой пример. понаделайте примеров с разными оциями  -посмотрите на разницу в коде)
« Последнее редактирование: 21-10-2008 19:37 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
iilisav
Участник

ru
Offline Offline

« Ответ #2 : 23-10-2008 13:50 » 

Спасибо за ответ, буду пробовать!
Пока вот пытаюсь создать устройство и ссылку на него вот таким образом:
Код:
  NTSTATUS DriverEntry (IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
   {
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_OBJECT pdo;
UNICODE_STRING devName;
UNICODE_STRING symLinkName;
PDEVICE_EXTENSION dx;
DbgPrint ("Entering DriverEntry...");
DbgPrint ("RegistryPath = %ws.", pRegistryPath->Buffer);

        //создаем экземпляр строк Unicode для имен устройства и символической ссылки
RtlInitUnicodeString(&devName, L"\\Device\\MyDevice");
RtlInitUnicodeString(&symLinkName, L"\\DosDevice\\MyDevice");
pDriverObject->DriverUnload = OnUnload;
//создаем устройство
status = IoCreateDevice(pDriverObject,
sizeof(DEVICE_EXTENSION),
&devName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&pdo);
if (!NT_SUCCESS(status))
{
   DbgPrint("DriverEntry IoCreateDevice error");
}
dx = (PDEVICE_EXTENSION)pdo->DeviceExtension;
dx->pdo = pdo;
dx->ustrSymLinkName = symLinkName;
//создаем символическую ссылку
status = IoCreateSymbolicLink(&symLinkName, &devName);
if (!NT_SUCCESS(status))
{
IoDeleteDevice(pdo);
return status;
}
DbgPrint("DriverEntry successfully completed.");
return status;
}
все собирается через DDK build, но когда я пытаюсь через Driver Manager запустить этот собранный драйвер пишет что : системе не удалось найти указанный путь, наверно я что-то не так написал?
« Последнее редактирование: 25-10-2008 20:10 от Finch » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 23-10-2008 15:29 » 

Driver Manager - это кто?) виндовский что ли?))) он тут не поможет)
создайте приложение в нем сделайте CreateFile(). в качестве имени указать : "\\\\.\\MyDevice"

PS не забудте про процедуру Unload в драйвере.
PPS и ВАЖНО! корректно обрабатывайте ВСЕ возможные и невозможные ошибки! привыкайте! в винде и так глючных приложений  хавтает. Почему при ошибке вызова IoCreateDevice вы дальше выполнение продолжаете?! pdo не инициализировано - в итоге будет BSOD. корректно надо обрабатывать все, вплоть до выделения памяти. и корректно останавливать/выгружать драйвер.
вызываете пятьсот одну функцию, и последняя возвращает ошибку? - ОСВОБОДИТЕ все, что захватили до этого, верните систему в исходное состояние!
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
iilisav
Участник

ru
Offline Offline

« Ответ #4 : 23-10-2008 16:08 » 

Извините что ввел в заблуждение! Ступил. До Driver Entry сделал:
Код:
NTSTATUS MyUnload (IN PDRIVER_OBJECT DriverObject)
   {
    DbgPrint("Unloading driver....");
    return STATUS_SUCCESS;
   }
typedef struct _DEVICE_EXTENSION
   {
    PDEVICE_OBJECT pdo;
UNICODE_STRING ustrSymLinkName;
    } DEVICE_EXTENSION, *PDEVICE_EXTENSION;

VOID OnUnload(IN PDRIVER_OBJECT pDriverObject)
   {
    PDEVICE_OBJECT pNextDevObj;
int i;
DbgPrint("OnUnLoad");
pNextDevObj = pDriverObject->DeviceObject;
for(i=0; pNextDevObj !=NULL; i++)
{
PDEVICE_EXTENSION dx = (PDEVICE_EXTENSION)pNextDevObj->DeviceExtension;
//символическая ссылка для удаления
UNICODE_STRING *pLinkName = & (dx->ustrSymLinkName);
//сохраняем указатель на следующее устройство
pNextDevObj = pNextDevObj->NextDevice;
DbgPrint("OnUnload Deleting device (%d) : pointer to PDO = %X.", i,dx->pdo);
DbgPrint("OnUnload Deleting symLink  = %ws.", pLinkName->Buffer);
//удаляем символичную ссылку
IoDeleteSymbolicLink(pLinkName);
//удаляем устройство
IoDeleteDevice(dx->pdo);
}
Вот, а Driver Manager взял из KmdKitа. Полное название Kernel Mode Driver Manager-)
« Последнее редактирование: 25-10-2008 20:10 от Finch » Записан
iilisav
Участник

ru
Offline Offline

« Ответ #5 : 23-10-2008 16:13 » 

Нашел в книжке этот исходник, но думаю что там опечатка скорей всего, только не могу понять где-( Заранее большое спасибо!
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 23-10-2008 16:52 » 

цикл в unload-е это не есть правильно)
вы должны удалить только одно, свое устройство, а не все что после вашего. остальное по идее должно удалятся ранее.
остальнное нормально. должно запуститься. по крайней мере хоть что то в окно отладчика вывести.. если скомпилировалось правильно...

теперь надо обработчики IRP ваять.
почитайте про инициализацию объекта дравера, поля:
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverDeviceControl;
DriverObject->DriverUnload = DriverUnload;
DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverOpen;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverClose;

PS посмотрите статью https://club.shelek.ru/viewart.php?id=76
PPS загрузчик через сервисы можно пока не трогать, обойтись простым CreateFile. в этом случае драйвер будет жить в памяти пока не закрыт его хендл.
« Последнее редактирование: 23-10-2008 16:54 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
iilisav
Участник

ru
Offline Offline

« Ответ #7 : 24-10-2008 18:42 » 

Спасибо за помощь! Обработчики наваял, но только не знаю куда мне девать строчки?
Код:
  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverDeviceControl;
  DriverObject->DriverUnload = DriverUnload;
  DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverOpen;
  DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverClose;
Пытаюсь:
Код:
   NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING pRegistryPath)
   {
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_OBJECT pdo;
UNICODE_STRING devName;
UNICODE_STRING symLinkName;
PDEVICE_EXTENSION dx;
DbgPrint ("Entering DriverEntry...");
DbgPrint ("RegistryPath = %ws.", pRegistryPath->Buffer);
//создаем экземпляр строк Unicode для имен устройства и символической ссылки
RtlInitUnicodeString(&devName, L"\\Device\\MyDevice");
RtlInitUnicodeString(&symLinkName, L"\\DosDevices\\MyDevice");
DriverObject->MajorFunction[IRP_MJ_CREATE] = onCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = onClose;
DriverObject->MajorFunction[IRP_MJ_READ] = onReadWrite;
DriverObject->MajorFunction[IRP_MJ_WRITE] = onReadWrite;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = onDeviceControl;
DriverObject->DriverUnload = OnUnload;
//создаем устройство
status = IoCreateDevice(DriverObject,
sizeof(DEVICE_EXTENSION),
&devName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&pdo);

if (!NT_SUCCESS(status))
{
   DbgPrint("DriverEntry IoCreateDevice error");
   //return ntStatus
}


dx = (PDEVICE_EXTENSION)pdo->DeviceExtension;
dx->pdo = pdo;
dx->ustrSymLinkName = symLinkName;
//создаем символическую ссылку
status = IoCreateSymbolicLink(&symLinkName, &devName);
if (!NT_SUCCESS(status))
{
IoDeleteDevice(pdo);
return status;
}
DbgPrint("DriverEntry successfully completed.");
return status;
}
Пишет что unresolved external symbol _onReadWrite@8 referenced in function _DriverEntry@8 и т.д.
Заранее спасибо!
« Последнее редактирование: 25-10-2008 20:09 от Finch » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 25-10-2008 08:44 » 

пральна пишет... вы статью посмотрели?)
думайте) я ж не говорил что надо тупо копировать...
строчки я вам дал для дальнейших поисков и размышлений)))
Код:
PS  чтобы привести пример своего кода пользуйтесь тегами [codе] и [/codе]  пожалуйста)
« Последнее редактирование: 25-10-2008 12:00 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
iilisav
Участник

ru
Offline Offline

« Ответ #9 : 25-10-2008 18:12 » 

Все разобрался вроде-) Спасибо большое! Теперь написал прогу на си :
Код:

  int test = 1;
  DWORD ReturetLength = 0;
  HANDLE hDevice;
  hDevice = CreateFile ("\\\\.\\MyDevice", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

  DeviceIoControl(hDevice, IOCTL_TEST_SMTH, &test, 0, NULL, 4, &ReturetLength, NULL);

пытаюсь передать драйверу  1-) Но ничего не происходит-( В сомой функции TEST_SMTH поставил вывод сообщения, но DbgView его не ловит. Как можно проверить загрузился ли драйвер и создалась ли ссылка не него по которой я обращаюсь к нему из приложения? Заранее спасибо!
« Последнее редактирование: 25-10-2008 20:08 от Finch » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 25-10-2008 20:09 » 

на ноуте DDK не стоит - точно не помню как называется... в комплекте DDK есть утилиты для отображения загруженных драйверов и всех созданных устройств. там вы должны и драйвер и устройство увидеть, и символическую ссылку. их там с десятка полтора в отдельной папочке...
еще на OSR.com sysinternals.com кучка утилит (http://technet.microsoft.com/en-us/sysinternals/0e18b180-9b7a-4c49-8120-c47c5a693683.aspx) была полезных...
PS а вы статус функций - традиционно не проверяете?Ага рекомендую)
PPS тэги не стоило из моего сообщения копировать))) я их специально через русские буквы написал, чтоб оторажались)))
« Последнее редактирование: 03-11-2008 19:38 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #11 : 25-10-2008 20:12 » 

Offtopic:

Теги подправил
Поставлю в угол.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 25-10-2008 20:13 » 

Offtopic:

гы) тока я собирался...)))
Поставлю в угол.

Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
iilisav
Участник

ru
Offline Offline

« Ответ #13 : 31-10-2008 13:40 » 

Большое вам всем спасибо! Форум здесь суперский! Не думал, что где-то еще осталиль люди безвоздмезно помогающие другим-)
Записан
iilisav
Участник

ru
Offline Offline

« Ответ #14 : 31-10-2008 13:41 » 

to: Ochkarik отдельное спасибо-)
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 31-10-2008 15:19 » 

iilisav, велкам)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines