|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Окт 12, 2003 00:13:03 · Поправил: Безпощадный даос Скачал пример WDM драйвера. Проблема- почему он не хочет просто выгрузиться(DeviceManager->MyDriver->Uninstall) , т.е. WinXP говорит- нужно перезагрузиться чтобы изменения (Uninstall) вступили в силу. Например, драйвер, собранный в NumegaDriverStudio (на VC++) отлично выгружается-загружается без перезагрузок. Подскажите что нужно дописать(?) в OnUnload чтобы драйвер выгружался нормально без перезагрузки! ;-------------------------------------- ; Обработчик события выгрузки драйвера ;-------------------------------------- OnUnload proc near, DriverObject:PDRIVER_OBJECT ; Удаляем символическую связь invoke IoDeleteSymbolicLink, addr Win32DeviceName ; Удаляем логическое устройство mov eax, DriverObject invoke IoDeleteDevice, (DRIVER_OBJECT PTR [eax]).DeviceObject ; Деинициализируем юникодовые строки invoke RtlFreeUnicodeString,offset NtDeviceName invoke RtlFreeUnicodeString,offset Win32DeviceName ret OnUnload endp ;-------------------------------------- Буду Очень благодарен за Помощь! |
|
|
Дата: Окт 13, 2003 01:30:21 Ну.. хоть кто-нибудь чтото подскажите!!!! Драйвер вот откуда (статья): http://www.wasm.ru/article.php?article=drvw2k05 сами исходники: http://four-f.narod.ru/KmdKit10.zip зеркала: http://www32.brinkster.com/fourf/KmdKit10.zip http://wasm.ru/tools/11/KmdKit10.zip update исходников: http://www32.brinkster.com/fourf/kkupto11.zip ---- может драйвер не все после себя восстанавливает/отдает/освобождает/итд. ? и поэтому он както некорректно выгружается?(точнее - Win не может его выгрузить, насколько я понимаю) Хотябы подскажите в каком направлении думать :( Спасибо! |
|
|
Дата: Окт 13, 2003 02:12:17 у меня была такая проблемма , я справился , но не помню как , точно не скажу но это не при выгрузке драйвера, а при запуске (инсталляции) надо такие параметры давать , чтоб он без перезагрузки работал , извини непомню какие (прогу уже купили и я забыл) |
|
|
Дата: Окт 13, 2003 14:31:52 [ prog: Скачал пример WDM драйвера. Проблема- почему он не хочет просто выгрузиться... ] Что-то я не понял. Это мой драйвер из статьи не хочет выгружаться что ли? Все дрова я тестил под 2000/ХР/2003 - все работает и выгружается без проблем. Или проблема с твоим драйвером? [ prog: Подскажите что нужно дописать(?) в OnUnload... ] Ты должен вернуть STATUS_SUCCESS, т.к. RtlFreeUnicodeString по докам ничего не возвращает, т.е. в eax какой-нить мусор и система считает, что OnUnload не отработала. Наверное в этом проблема. |
|
|
Дата: Окт 13, 2003 17:02:47 · Поправил: prog Что-то я не понял. Это мой драйвер из статьи не хочет выгружаться что ли? Все дрова я тестил под 2000/ХР/2003 - все работает и выгружается без проблем. Или проблема с твоим драйвером? Да. Я в этом драйвере из примера ничего не менял. Взял исходники (KmdKit10.zip -> VirtToPhys), сделал свой .inf , скомпилировал, установил. Все хорошо. Тутже делаю Uninstall - WinXP говорит, что нужно перегрузиться чтобы изменения вступили в силу. Перезагружаюсь- все как он и обещал- драйвера нету. Ты должен вернуть STATUS_SUCCESS, т.к. RtlFreeUnicodeString по докам ничего не возвращает, т.е. в eax какой-нить мусор и система считает, что OnUnload не отработала. Наверное в этом проблема. В конце UnLoad записал в eax STATUS_SUCCESS - все тоже самое :( Вот полный код драйвера (это из другого источника, но, помоему, все сделано также , как и в статье Four-F(Уважаемого мной! :) )): Тут у меня еще одна ПРОБЛЕМА- dll не видит буфер (buffered IOCTL). На С++ это лечилось заменой в драйвере (написанном на VС++) Irp.UserBuffer() на Irp.IoctlBuffer() : //Получаем указатель на буфер пользователя //buf=(unsigned int*) I.UserBuffer(); так dll не видит то, что возвращается в буфере buf=(unsigned int*) I.IoctlBuffer(); так- видит А как в ASM получить указатель на IoctlBuffer ? Это- "SystemBuffer": ; Получаем указатель на системный буфер mov eax,(_IRP ptr [ebx]).AssociatedIrp.SystemBuffer А что такое и где его взять "IoctlBuffer" ? Спасибо всем за помощь!!! .586p .model flat, stdcall option casemap:none ; Включения .nolist include usewdm.inc includelib wdm.lib .list include ioctlcodes.inc ; ---------------------------------------------------------------------- ---------------- .data ; Имя устройства NT wsNtDeviceName dw '\','D','e','v','i','c','e','\','S','a','m','p','l','e','A','s','m','D ','r','v',0 ; Имя линка wsWin32DeviceName dw '\','D','o','s','D','e','v','i','c','e','s','\','S','a','m','p','l','e ','A','s','m','D','r','v',0 NtDeviceName UNICODE_STRING {0,0,0} Win32DeviceName UNICODE_STRING {0,0,0} ; Указатель на device object DeviceObject PDEVICE_OBJECT 0 ; ---------------------------------------------------------------------- ---------------- .code ; ---------------------------------------------------------------------- ---------------- ; Точка входа для первичной инициализации ; ---------------------------------------------------------------------- ---------------- DriverEntry proc near public, DriverObject:PDRIVER_OBJECT, RegistryPath:PUNICODE_STRING LOCAL Status:DWORD mov Status,STATUS_SUCCESS ; Статусное значение push ebx mov ebx,DriverObject mov (DRIVER_OBJECT ptr [ebx]).DriverUnload, offset OnUnload mov eax, offset OnDispatch mov (DRIVER_OBJECT ptr [ebx]).MajorFunction[IRP_MJ_CREATE * (TYPE PDRIVER_DISPATCH)],eax mov (DRIVER_OBJECT ptr [ebx]).MajorFunction[IRP_MJ_CLOSE * (TYPE PDRIVER_DISPATCH)],eax mov (DRIVER_OBJECT ptr [ebx]).MajorFunction[IRP_MJ_DEVICE_CONTROL * (TYPE PDRIVER_DISPATCH)],eax pop ebx ; Инициализируем юникодовые строки с именами устройства и линка invoke RtlInitUnicodeString, offset NtDeviceName, offset wsNtDeviceName invoke RtlInitUnicodeString, offset Win32DeviceName, offset wsWin32DeviceName ; Создаём логический объект устройства invoke IoCreateDevice, DriverObject, 0, offset NtDeviceName, FILE_DEVICE_UNKNOWN,0,FALSE,offset DeviceObject; cmp eax,STATUS_SUCCESS ; Проверим, не было ли ошибки. jnz @F ; Создаём symbolic link invoke IoCreateSymbolicLink, offset Win32DeviceName, offset NtDeviceName ; в eax останется код результата @@: ret DriverEntry endp ; ---------------------------------------------------------------------- ---------------- ; Обработчик события выгрузки драйвера ; ---------------------------------------------------------------------- ---------------- OnUnload proc near, DriverObject:PDRIVER_OBJECT ; Удаляем символическую связь invoke IoDeleteSymbolicLink, addr Win32DeviceName ; Деинициализируем юникодовые строки invoke RtlFreeUnicodeString,offset NtDeviceName invoke RtlFreeUnicodeString,offset Win32DeviceName mov eax, DriverObject invoke IoDeleteDevice, (DRIVER_OBJECT PTR [eax]).DeviceObject ;!!!!Это добавил- ничего не изменилось!!!! (XP требует перезагрузки после Uninstall) mov eax,STATUS_SUCCESS ret OnUnload endp ; ---------------------------------------------------------------------- ---------------- ; Процедура обработки запроса device IO control ; Re: должна возвращать в eax статусный код ; ---------------------------------------------------------------------- ---------------- DeviceIoControlHandler proc near, Code:ULONG, pBuffer:PCHAR, InputBufferLength:ULONG, OutputBufferLength:ULONG, pOutputLength:PULONG mov eax,Code cmp eax,IOCTL_CODE_801 ; Тип запроса 1 jz IoCtl_1 ; <...> -- Прочие запросы mov eax,STATUS_NOT_IMPLEMENTED ; Непредусмотренный код запроса ret IoCtl_1: ; Пытаемся возвратить байт, на 01h бОльший, чем получили (НИЧЕГО НЕ ВОЗВРАЩАЕТСЯ!) push ebx xor eax,eax mov ebx,pBuffer mov al,BYTE ptr [ebx] add al,01h mov BYTE ptr [ebx],al pop ebx ; Длина данных, передаваемых обратно приложению пользователя. push ebx mov eax,OutputBufferLength mov ebx,pOutputLength mov DWORD ptr [ebx],eax pop ebx @@: mov eax,STATUS_SUCCESS ret DeviceIoControlHandler endp ; ---------------------------------------------------------------------- ---------------- ; Диспетчер вызовов IRP_MJ_XXX ; ---------------------------------------------------------------------- ---------------- OnDispatch proc near, pDeviceObject:PDEVICE_OBJECT,pIrp:PIRP LOCAL Status:DWORD ; Хранит статусное значение для возврата LOCAL pIrpStack:DWORD ; Указывает на структурку IO_STACK_LOCATION LOCAL Code ; Хранит код запроса DeviceIoControl LOCAL InputBufferLength ; Хранит длину входного буфера LOCAL OutputBufferLength ; Хранит длину выходного буфера LOCAL pBuffer ; Хранит ссылку на буфер mov Status,STATUS_UNSUCCESSFULL push ebx mov ebx,pIrp mov eax,(_IRP ptr [ebx]).Tail.Overlay.CurrentStackLocation ; Восстанавливаем указатель на структуру IO_STACK_LOCATION mov pIrpStack,eax mov ebx,pIrpStack mov al,(IO_STACK_LOCATION ptr [ebx]).MajorFunction ; Код сообщения pop ebx ; IRP_MJ_CREATE -- CreateFile() cmp al,IRP_MJ_CREATE jnz @F mov Status,STATUS_SUCCESS jmp OnDispatchLeave ; IRP_MJ_CLOSE -- CloseHandle() @@: cmp al,IRP_MJ_CLOSE jnz @F mov Status,STATUS_SUCCESS jmp OnDispatchLeave ; IRP_MJ_DEVICE_CONTROL -- DeviceIoControl() @@: cmp al,IRP_MJ_DEVICE_CONTROL jnz @F push ebx mov ebx,pIrp ; Получаем указатель на системный буфер mov eax,(_IRP ptr [ebx]).AssociatedIrp.SystemBuffer mov pBuffer,eax mov ebx,pIrpStack ; Подготовим параметры для вызова. ; Может, это не очень красиво, но упростит код в DeviceIoControlHandler ; Получаем код запроса mov eax,(IO_STACK_LOCATION ptr [ebx]).Parameters.DeviceIoControl.IoControlCode mov Code,eax ; Читаем длину входного буфера mov eax,(IO_STACK_LOCATION ptr [ebx]).Parameters.DeviceIoControl.InputBufferLength mov InputBufferLength,eax ; Читаем длину выходного буфера mov eax,(IO_STACK_LOCATION ptr [ebx]).Parameters.DeviceIoControl.OutputBufferLength mov OutputBufferLength,eax mov ebx,pIrp xor eax,eax ; Пока ничего не возвращаем mov (_IRP ptr [ebx]).IoStatus.Information,eax mov eax,ebx ; В обработчике потребуется смещение поля Information для записи длины возвращаемых данных add eax,offset _IRP.IoStatus.Information pop ebx ; Вызываем обработчик. invoke DeviceIoControlHandler, Code, pBuffer, InputBufferLength, OutputBufferLength, eax mov Status,eax ; Запомним код возврата jmp OnDispatchLeave @@: ; default mov Status,STATUS_NOT_IMPLEMENTED OnDispatchLeave: mov ecx,pIrp ; Уведомим менеджер ввода-вывода об окончании обработки запроса mov edx,0 call @IofCompleteRequest@8 mov eax,Status ; Запишем код возврата push ebx mov ebx,pIrp mov (_IRP ptr [ebx]).IoStatus.Status,eax pop ebx ret OnDispatch endp end |
|
|
Дата: Окт 13, 2003 18:07:59 [ prog: ...сделал свой .inf... ] Ясно. Я с инфами никогда дело не имел. Поэтому конкретно ничего сказать не могу. Тебе нужно внимательно почитать в ддк раздел "Creating an INF File" и у Вальтера Они во втором издании есть глава "Distributing Device Drivers". Уверен, что там есть ответ на твой вопрос. |
|
|
Дата: Окт 13, 2003 18:18:31 · Поправил: prog Понятно. Буду смотреть. Но я взял .inf от своего драйвера, написанного на VC++ , который нормально грузится-выгружается. Поэтому и не думал, что дело может быть в .inf Сейчас почитаю.. А насчет Буфера? IoctlBuffer - нужно использовть при буферизированном способе общения драйвера с dll а тут- ; Получаем указатель на системный буфер mov eax,(_IRP ptr [ebx]).AssociatedIrp.SystemBuffer mov pBuffer,eax - аналог Irp.UserBuffer() в VC++ А как получить адрес IoctlBuffer ? |
|
|
Дата: Окт 13, 2003 18:29:57 Насчет возвращения STATUS_SUCCESS из DriverUnload я, наверное, протупил. Похоже, что система вообще не проверяет это. |
|
|
Дата: Окт 13, 2003 18:37:27 [ prog: А как получить адрес IoctlBuffer ? ] Если ты используешь METHOD_BUFFERED, то система сама занимается копированием буферов. Поэтому она скопирует, то что было в твоем буфере в системное адресное пространство и ты в драйвере получишь указатель на него в _IRP.AssociatedIrp.SystemBuffer. В статье подробно про это написано. По поводу невыгрузки. При инсталяции через инф задействуется P'n'P Manager. Видимо при выгрузке драйвер как-то должен его уведомить об этом. Как я не знаю - читай доки. |
|
|
Дата: Окт 13, 2003 19:21:00 · Поправил: prog Если ты используешь METHOD_BUFFERED, то система сама занимается копированием буферов. Поэтому она скопирует, то что было в твоем буфере в системное адресное пространство и ты в драйвере получишь указатель на него в _IRP.AssociatedIrp.SystemBuffer. В статье подробно про это написано. Это я понимаю. Драйвер Получает данные снаружи в _IRP.AssociatedIrp.SystemBuffer , с этим проблем нет. Проблема- в обратном действии. Я записываю в _IRP.AssociatedIrp.SystemBuffer данные - dll их не видит. Точнее - она видит какуюто "левую" область памяти (у моего конкретного кампутера там "ММММ...") Вот в этом проблема. |
|
|
Дата: Окт 14, 2003 00:31:00 · Поправил: prog Ясно. Я с инфами никогда дело не имел. Поэтому конкретно ничего сказать не могу. Тебе нужно внимательно почитать в ддк раздел "Creating an INF File" и у Вальтера Они во втором издании есть глава "Distributing Device Drivers". Уверен, что там есть ответ на твой вопрос. Сделал inf с помощью входящего в DDK geninf.exe по всем правилам. Это ничего не дало- все также при DeviceManager->Driver->Unistall выдается- Теперь нужно перезагрузить компьютер. у меня крыша уже едет. или уехала. :((( Кто-нибудь! Помогите! %( Проблемы две: 1. в WinXP делаю драйверу Uninstall --> XP требует перезагрузки для того, чтобы закончить деинсталляцию драйвера. (собранный вроде по правилам .inf не помог) 2. записываю в _IRP.AssociatedIrp.SystemBuffer данные --> приложение (dll) их не видит (в dll все сделано заведомо правильно). (переданные из приложения (dll) данные драйвер отлично видит и берет из _IRP.AssociatedIrp.SystemBuffer) |
|
|
Дата: Окт 14, 2003 03:35:31 · Поправил: prog УРА! проблема 2 разрешилась! Как всегда- причина в моей невнимательности! я везде использовал IOCTL в лоб- просто числом, например, asm: IOCTL_1 equ 801h IOCTL_2 equ 802h VC++ dll: #define IOCTL_Command_1 0x801 #define IOCTL_Command_2 0x802 ВОТ ЛОПУХ! Конечно! причина того, что данные из SystemBuffer не появлялись в выходном буффере- в том, что метод передачи данных был вообще не знаю какой... сделал вот так: asm: CTL_CODE MACRO DeviceType:=<0>, Function:=<0>, Method:=<0>, Access:=<0> EXITM %(((DeviceType) SHL 16) OR ((Access) SHL 14) OR ((Function) SHL 2) OR (Method)) ENDM IOCTL_1 equ CTL_CODE(FILE_DEVICE_UNKNOWN, 801h, METHOD_BUFFERED, FILE_ANY_ACCESS) VC++ dll: #define IOCTL_Command_1 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) И теперь данные из буфера появляются в выходном буфере в dll! Спасибо всем!!! Но теперь остается одна проблема- в WinXP делаю драйверу Uninstall --> XP требует перезагрузки для того, чтобы закончить деинсталляцию драйвера. (собранный вроде по правилам .inf не помог) |
|
|
Дата: Окт 14, 2003 11:23:18 [ prog: (собранный вроде по правилам .inf не помог) ] Возможно, причина в том, что твой драйвер не является WDM драйвером. Это обычный kernel-mode driver и все мои примеры из статей тоже не WDM. WDM отличается от KMD поддержкой P'n'P. Точно я не знаю, но видимо он взаимодействует с диспетчером P'n'P вызывая его сервисы и наверное предоставляя ему свои колбэки. У тебя ничего этого нет - в этом, видимо, и причина. Кстати, не совсем понятно зачем устанавливать твой драйвер через инф. Посмотри примеры WDM-драйверов у того же Вальтера Они или еще где. |
|
|
Дата: Окт 15, 2003 11:08:28 · Поправил: prog У него все на C++ :( Подскажите хоть какую-нибудь ссылку где можно посмотреть как решить проблему в MASM |
|
|
Дата: Окт 15, 2003 11:24:45 · Поправил: Four-F Вряд ли ты найдешь такую ссылку, ибо на асме дрова писать, тем более WDM, нонче не популярно - это удел энтузазистов. Читай Они и ддк, смотри примеры - другого путя, IMHO, нет. Изучи С++, наконец - пригодится. |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.095 |