elDraco
Гость
|
|
« : 07-12-2008 17:29 » |
|
необходимо написать управляемый фильтр-драйвер для дисков под Win XP, который разрешает запись на выбранных дисках возникло несколько вопросов связанных с управлением списком дисков: для каждого физического диска будет создан свой фильтрующий FDO, в этот момент мне надо как-то узнать блокировать запись на этот диск или нет (я предполагаю грузить драйвер до драйверов файловых систем, чтобы они ничего не успели изменить во время монтирования), поэтому вопрос: 1) где лучше держать список разрешённых дисков(реестр или файл на диске) и соответственно когда загружать (лучше всего имхо в DriverEntry и там же создать управляющий FDO)? предполагается хранение в виде количество разрешённых и потом список их uid? запрещённые хранить не предполагается 2) как его адекватно хранить в период выполнения(учитывая что количество дисков может меняться за счёт флэшек например), так чтобы он был доступен всем фильтрующим FDO(им только читать надо будет своё разрешение) и управляющему FDO(он может менять разрешения)? предполагаю хранить количество дисков в системе массив их uid и массив байтов с разрешениями, проблема в неизвестном размере и том что это фактически получаются глобальные переменные (которых насколько я понимаю нужно избегать) 3) как определить что я загрузился с этого диска, соответственно запись запрещать нельзя (где-то подобное вроде видел, но так уж за компанию)? 4) сохранять список надо только в DriverUnload и в Shutdown или ещё где-то? 5) блокировать достаточно только IRP_MJ_WRITE? или есть ещё способы осуществить физическую запись на носитель? 6) смена разрешения во время исполнения я так полагаю вполне может привести к бсоду, есть ли рекомендации как этого избежать? и вообще если я на любую попытку записи буду отвечать access denied виндовс это переживёт? 7) работать собираюсь только с физическими дисками (партишены не интересуют), следовательно если я правильно понимаю цепляться мне нужно под или над disk.sys?
зы: извиняюсь если похоже на поток сознания, просто постарался разделить интересующие вопросы на мелкие зыы: приложил файл с функцией которой собираюсь читать uid'ы, будет ли она работать так как предполагается?
|
tools.c (4.98 Кб - загружено 1455 раз.)
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #1 : 07-12-2008 20:33 » |
|
1. на ваше усмотрение. загружать наверное не AddDevice... мне кажется. 2. в данном случае глобольные переменные не только допустимы, это как раз тот случай когда их надо использовать. 3. поищите поиском по форуме - вобще эту тему уже не раз обсуждали. в каком то поле IRP содержится имя файла. 4. сохранять... опять же если не путаю ничего - то по IRP_MJ_PNP - по REMOVE и SUPRISE_REMOVE. 1 и 4 - это если я правильно понял к чему вы фильтр аттачить будете. будет там PNP или нет... 5 опять же зависит от того к чему атачить 6 переживет я думаю... смену разрешения надо аккуратно реализовать) 7 эээ...а вот тут как раз не знаю) гляньте форум. тут народ не раз такой фильтр строил)
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
elDraco
Гость
|
|
« Ответ #2 : 08-12-2008 07:25 » |
|
3) видимо я не достаточно чётко выразился, мне нужно уметь определять является ли диск системным(то есть на нём расположен раздел с загружающейся сейчас системой) ещё в AddDevice, если пошли IRP то я уже должен знать, можно мне блокировать этот диск или нет. То есть подразумевается, что запись на него разрешена по умолчанию 4) сохранять я собираюсь только при выгрузке драйвера, например во время останова системы или я что-то путаю? хотя щас подумал, обрабатывать удаление устройств всё равно придётся, иначе в пользовательском ПО я никак не узнаю, что диска больше нет в системе
зы: если я правильно всё понимаю (я в этом пока новичёк, так сказать "боевое крещение") то цепляться мне нужно чем ближе к железу тем лучше (чтобы иметь возможность перехватить не только пользовательские запросы на запись, но и системные типа установки времени последнего изменения файла и тп), а целевые устройства для меня это носители информации(харды, флэшки там)
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #3 : 08-12-2008 13:30 » |
|
3. можно вытащить через реестр. там должен быть такой ключ. 4. лучше по удалению. PNP посылается для конкретного диска. а unload там общий для всех экземпляров.
по зы - ну тут вопрос странный. если совсем близко к диску - придется поди и файловую систему самому разбитать? оно вам надо?) впрочем тут я не специалист - не знаю точно. а запросы к файлам через вас пройдут я думаю...
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
elDraco
Гость
|
|
« Ответ #4 : 08-12-2008 14:12 » |
|
по зы - ну тут вопрос странный. если совсем близко к диску - придется поди и файловую систему самому разбитать? оно вам надо?) впрочем тут я не специалист - не знаю точно. а запросы к файлам через вас пройдут я думаю...
я думаю что драйверы файловых систем будут преобразовывать запросы типа "записать в этот файл" в запросы типа "записать на этот хдд по такому-то смещению" и мне останется только заблокировать запрос на запись, или я что-то неправильно понял в идеологии? в конечном счёте, по моему разумению, любое обращение к диску это либо read, либо write, мне по сути надо встроиться туда, где уже остаются только эти read/write, наверно это будет самый нижний общий для всех storage драйвер
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #5 : 08-12-2008 20:27 » |
|
увы, с дисками никогда не разбирался, надо их стек смотреть. так ничего - не скажу...
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
elDraco
Гость
|
|
« Ответ #6 : 17-12-2008 15:51 » |
|
написал драйвер, еле понял как отлаживаться на вмваре в итоге обнаружил проблему... драйвер грузится в boot time, в DriverEntry мне передают мой ключ в реестре... могу ли я им воспользоваться? при попытке его открыть получаю инвэлид хэндл посему вопрос, а как хранить настройки драйверам которые стартуют в boot time? когда вызывается AddDevice я должен уже знать что мне делать с этим устройством моя функция загрузки списка разрешений: NTSTATUS MWBLoadPermitList(){ //Ok UNICODE_STRING DeviceListValueName; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE handle; // Stores the open handle NTSTATUS status; PKEY_VALUE_FULL_INFORMATION ValueInfo; LONG ValueSize; LONG InnerCounter;
RtlInitUnicodeString(&DeviceListValueName, L"PermissionList");//<<<mem allocation for local use<<< ValueInfo = (PKEY_VALUE_FULL_INFORMATION)ExAllocatePool(PagedPool, sizeof(KEY_VALUE_FULL_INFORMATION));//<<<mem allocation for local use<<< if(!ValueInfo){ return STATUS_INSUFFICIENT_RESOURCES; } DeviceList.ListCapacity = 100; //--- DefaultPermission = MWBPermitAlways;//if not changed then key not found(first run, permit new disks) InitializeObjectAttributes(&ObjectAttributes, &MWBDriverRegistryPath, OBJ_KERNEL_HANDLE, NULL, NULL);
status = ZwOpenKey(&handle, KEY_SET_VALUE, &ObjectAttributes); if (status == STATUS_SUCCESS) {//handle opened status = ZwQueryValueKey(handle, &DeviceListValueName, KeyValueFullInformation, ValueInfo, sizeof(KEY_VALUE_FULL_INFORMATION), &ValueSize); if ( (status == STATUS_BUFFER_OVERFLOW) || (status == STATUS_BUFFER_TOO_SMALL) ) { ExFreePool(ValueInfo);//>>>freeing local mem>>>normal ValueInfo = (PKEY_VALUE_FULL_INFORMATION)ExAllocatePool(PagedPool, ValueSize);//<<<mem allocation for local use<<< if(!ValueInfo){ ZwClose(handle); return STATUS_INSUFFICIENT_RESOURCES; } status = ZwQueryValueKey(handle, &DeviceListValueName, KeyValueFullInformation, ValueInfo, sizeof(KEY_VALUE_FULL_INFORMATION), &ValueSize); if(status == STATUS_SUCCESS){ PMWB_DEVICE_LIST CurrentList; LONG CurrentOffset; //--- ValueSize = ValueInfo->DataLength - sizeof(CHAR); LoadedBuffer = (PCHAR)ExAllocatePool(NonPagedPool, ValueSize);//<<<mem allocation for global use<<<buffer for loaded uids RtlCopyMemory(LoadedBuffer, (ValueInfo + ValueInfo->DataOffset), ValueSize);//copying strings array ExFreePool(ValueInfo);//>>>freeing local mem>>>normal //---global counters--- DeviceCount = 0; LoadedDeviceCount = 0; ConnectedDeviceCount = 0; //--- CurrentList = &DeviceList; CurrentOffset = 0; InnerCounter = 0; while(CurrentOffset < ValueSize){ if(InnerCounter == CurrentList->ListCapacity){ InterlockedCompareExchangePointer(CurrentList->NextBlock, (ExAllocatePool(NonPagedPool, sizeof(MWB_DEVICE_LIST))), NULL);//<<<mem allocation for global use<<< CurrentList = CurrentList->NextBlock; CurrentList->ListCapacity = 100;//crush may be CurrentList->NextBlock = NULL; InnerCounter = 0; } CurrentList->PermitList[InnerCounter].DeviceConnected = FALSE; CurrentList->PermitList[InnerCounter].DevicePermission = MWBPermitAlways; RtlInitAnsiString(&(CurrentList->PermitList[InnerCounter].DeviceUID), (LoadedBuffer + CurrentOffset)); CurrentOffset += CurrentList->PermitList[InnerCounter].DeviceUID.Length + sizeof(CHAR); DeviceCount++; InnerCounter++; LoadedDeviceCount++; } DefaultPermission = MWBBlock;//not a first run, block new disks } else {//error while loading key LoadedBuffer = NULL; //---global counters--- DeviceCount = 0; LoadedDeviceCount = 0; ConnectedDeviceCount = 0; //--- ZwClose(handle); #if DBG DbgPrint("MWBLoadPermitList: Fail to read key value\n"); #endif return STATUS_INSUFFICIENT_RESOURCES; } } else {//error while opening key LoadedBuffer = NULL; //---global counters--- DeviceCount = 0; LoadedDeviceCount = 0; ConnectedDeviceCount = 0; //--- ZwClose(handle); #if DBG DbgPrint("MWBLoadPermitList: Fail to check key value\n"); #endif return STATUS_INSUFFICIENT_RESOURCES; } status = ZwClose(handle); } else {//can't open handle LoadedBuffer = NULL; //---global counters--- DeviceCount = 0; LoadedDeviceCount = 0; ConnectedDeviceCount = 0; //--- #if DBG DbgPrint("MWBLoadPermitList: Fail to open key handle\n"); #endif return STATUS_INSUFFICIENT_RESOURCES; } return status; } в WinDBG при этом вижу MWBLoadPermitList: Fail to open key handle я что-то делаю не так или так вообще делать нельзя?
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #7 : 18-12-2008 08:02 » |
|
хранить точно так же в реестре. правда сам никогда не использовал. исключение только для драйверов которые в реальном режиме стартуют. или это для 95го было...? раздел Kernel-Mode Driver Architecture: Windows DDK Using the Registry in a Driver
не уверен что надо открывать только с KEY_SET_VALUE .
|
|
« Последнее редактирование: 18-12-2008 08:06 от Ochkarik »
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
elDraco
Гость
|
|
« Ответ #8 : 18-12-2008 08:32 » |
|
хранить точно так же в реестре. правда сам никогда не использовал. исключение только для драйверов которые в реальном режиме стартуют. или это для 95го было...? раздел Kernel-Mode Driver Architecture: Windows DDK Using the Registry in a Driver
не уверен что надо открывать только с KEY_SET_VALUE .
да думаю насчёт KEY_SET_VALUE это не то, сам когда перебирал не понял откуда взял более подробно получаю вот что: MWBLoadPermitList: my key is \Registry\Machine\System\CurrentControlSet\Services\mwblock keyLength is 118 MWBLoadPermitList: Fail to open key handle [status = C000003A]// судя по ntstatus.h это STATUS_OBJECT_PATH_NOT_FOUND MWBDriverEntry: Fail to load device list //--- в чём может быть проблема? ключ точно создан, в реестре специально перед перезагрузкой смотрел выглядит сейчас это так: #if DBG DbgPrint("MWBLoadPermitList: my key is %ws keyLength is %d\n", MWBDriverRegistryPath.Buffer, MWBDriverRegistryPath.Length); #endif InitializeObjectAttributes(&ObjectAttributes, &MWBDriverRegistryPath, OBJ_KERNEL_HANDLE, NULL, NULL);
status = ZwOpenKey(&handle, KEY_READ, &ObjectAttributes); if (status != STATUS_SUCCESS){//can't open handle LoadedBuffer = NULL; //---global counters--- DeviceCount = 0; LoadedDeviceCount = 0; ConnectedDeviceCount = 0; //--- #if DBG DbgPrint("MWBLoadPermitList: Fail to open key handle [status = %X]\n", status); #endif return STATUS_INSUFFICIENT_RESOURCES; }
|
|
« Последнее редактирование: 18-12-2008 08:40 от elDraco »
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #9 : 18-12-2008 08:35 » |
|
GENERIC_ALL - это где вы такое нашли?)хотя вроде есть... попробуйте KEY_ALL_ACCESS и попробуйте ZwCreateKey() PS и может быть не обязательно OBJ_KERNEL_HANDLE? это только если не в контексте системной нити... в вы где вызываете функцию? подозреваю что AddDev...? тогда системная вроде должна быть...
|
|
« Последнее редактирование: 18-12-2008 08:39 от Ochkarik »
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
elDraco
Гость
|
|
« Ответ #10 : 18-12-2008 08:54 » |
|
GENERIC_ALL - это где вы такое нашли?)хотя вроде есть... попробуйте KEY_ALL_ACCESS
это я в документации потерялся:) поставил пока KEY_READ, сейчас попробую поиграться с параметрами ещё и попробуйте ZwCreateKey() PS и может быть не обязательно OBJ_KERNEL_HANDLE? это только если не в контексте системной нити... в вы где вызываете функцию? подозреваю что AddDev...? тогда системная вроде должна быть...
нет функция вызывается в DriverEntry сейчас вот пробовал после установки до перезагрузки вставить флэшку и... тоже улетел:) попробую помониторить зы: а вообще к чему этот статус относится? не найден путь в реестре? путь пишется именно так?
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #11 : 18-12-2008 10:04 » |
|
сами сообразите? примеры использования из DDK: C:\DDK3790.1830\src\input\kbdclass\kbdclass.c NTSTATUS status; HANDLE hService, hParameters; ULONG tmp; OBJECT_ATTRIBUTES oa; InitializeObjectAttributes (&oa, &Globals.RegistryPath, OBJ_CASE_INSENSITIVE, NULL, (PSECURITY_DESCRIPTOR) NULL);
status = ZwOpenKey (&hService, KEY_ALL_ACCESS, &oa);
if (NT_SUCCESS (status)) { UNICODE_STRING parameters;
RtlInitUnicodeString(¶meters, L"Parameters"); InitializeObjectAttributes (&oa, ¶meters, OBJ_CASE_INSENSITIVE, hService, (PSECURITY_DESCRIPTOR) NULL);
status = ZwOpenKey (&hParameters, KEY_ALL_ACCESS, &oa); if (NT_SUCCESS (status)) { .... ZwClose (hParameters); }
ZwClose (hService); }
HANDLE serviceKey, paramsKey; UNICODE_STRING UnicodeString; OBJECT_ATTRIBUTES attributes;
RtlInitUnicodeString(&UnicodeString, L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\" L"Control");
// // Open the global hack key and retrieve the gloabl hack table // InitializeObjectAttributes(&attributes, &UnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL );
Status = ZwOpenKey(&serviceKey, KEY_READ, &attributes );
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
elDraco
Гость
|
|
« Ответ #12 : 18-12-2008 10:28 » |
|
может прозвучать смешно, но похоже дело было в InitializeObjectAttributes(&ObjectAttributes, &MWBDriverRegistryPath, OBJ_CASE_INSENSITIVE, NULL, (PSECURITY_DESCRIPTOR) NULL);
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #13 : 18-12-2008 11:55 » |
|
вобще то я намекал на InitializeObjectAttributes(&ObjectAttributes, &MWBDriverRegistryPath, OBJ_CASE_INSENSITIVE, NULL,(PSECURITY_DESCRIPTOR) NULL); вместо OBJ_KERNEL_HANDLE
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
elDraco
Гость
|
|
« Ответ #14 : 18-12-2008 11:59 » |
|
я пробовал OBJ_CASE_INSENSITIVE до этого, но без приведения типа, сейчас думаю что просто невнимательно прочитал вывод дебаг принтов и результат был удовлетворительный спасибо за помощь, продолжаю отлаживаться:)
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #15 : 18-12-2008 13:39 » |
|
тут приведение типа только на варнинги должно было повлиять. наверное)
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
elDraco
Гость
|
|
« Ответ #16 : 18-12-2008 20:34 » |
|
решил почти все проблемы драйвер загружается, права сохраняются, меняются и восстанавливаются корректно, физическая запись вроде блокируется(дотошно не тестировал ещё) но как обычно несколько проблем:) 1) управляющее приложение может открыть хэндл, пообщаться вдоволь с драйвером (результаты корректные судя по выводу проги), но при попытке закрыть хэндл получаю в отладчике вот такую бяку: Access violation - code c0000005 (!!! second chance !!!) nt!IofCallDriver+0x29: 804e37ee 8b7108 mov esi,dword ptr [ecx+8] функция слизана у Солдатова: NTSTATUS MWBClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PAGED_CODE();
UNREFERENCED_PARAMETER(DeviceObject); #if DBG DbgPrint("MWBClose: Started\n"); #endif
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT);
#if DBG DbgPrint("MWBClose: Finished\n"); #endif return STATUS_SUCCESS; }// end MWBClose() даже не могу понять что тут может произойти... я даже не вижу сообщения ни одного из этой функции 2) при попытке изменить файл на "защищённом от записи" диске получил попап в трее об ошибке отложенной записи... и потом винда постоянно пытается повторить запись:) пока предположение, что связано с тем что я возвращаю STATUS_MEDIA_WRITE_PROTECTED, завтра попробую ещё ACCESS_DENIED И может ещё что-нибудь, очень надеюсь что мне не придётся перехватывать более высокоуровневые функции (по сути запись произошла в кэш и я потом видел что запись произошла, хотя физически это не так), надо вернуть что-нибудь такое чтоб винда отменила запись в кэш в придачу иначе будет некрасиво
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #17 : 19-12-2008 11:02 » |
|
Irp->IoStatus.Information = 0 - не надо! возврашайте ошибку записи)
|
|
« Последнее редактирование: 19-12-2008 11:07 от Ochkarik »
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
elDraco
Гость
|
|
« Ответ #18 : 19-12-2008 20:49 » |
|
дело похоже не в Information вот вывод !analyze -v: MODULE_NAME: nt
FAULTING_MODULE: 804d7000 nt
DEBUG_FLR_IMAGE_TIMESTAMP: 47d00080
FAULTING_IP: nt!IofCallDriver+29 804e37ee 8b7108 mov esi,dword ptr [ecx+8]
EXCEPTION_RECORD: ffffffff -- (.exr 0xffffffffffffffff) ExceptionAddress: 804e37ee (nt!IofCallDriver+0x00000029) ExceptionCode: c0000005 (Access violation) ExceptionFlags: 00000000 NumberParameters: 2 Parameter[0]: 00000000 Parameter[1]: 00000008 Attempt to read from address 00000008
ERROR_CODE: (NTSTATUS) 0xc0000005 - <Unable to get error code text>
EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - <Unable to get error code text>
EXCEPTION_PARAMETER1: 00000000
EXCEPTION_PARAMETER2: 00000008
READ_ADDRESS: unable to get nt!MmSpecialPoolStart unable to get nt!MmSpecialPoolEnd unable to get nt!MmPoolCodeStart unable to get nt!MmPoolCodeEnd 00000008
FOLLOWUP_IP: nt!IofCallDriver+29 804e37ee 8b7108 mov esi,dword ptr [ecx+8]
BUGCHECK_STR: ACCESS_VIOLATION
DEFAULT_BUCKET_ID: WRONG_SYMBOLS
LAST_CONTROL_TRANSFER: from 804e37f7 to 804e37ee
STACK_TEXT: WARNING: Stack unwind information not available. Following frames may be wrong. f9648c60 804e37f7 81b88030 819623a8 819623a8 nt!IofCallDriver+0x29 f9648ca4 80567697 81a6bbc0 81b88030 0012019f nt!IofCallDriver+0x32 f9648cd4 8056783f 81a6bbc0 00000001 81bb8730 nt!RtlAddAtomToAtomTable+0x3f3 f9648cfc 805678b0 e190fe90 819fb308 000007c4 nt!RtlAddAtomToAtomTable+0x59b f9648d44 805678fa 000007c4 00000001 00000000 nt!RtlAddAtomToAtomTable+0x60c f9648d58 804de7ec 000007c4 0012ff58 7c90e4f4 nt!NtClose+0x1d f9648e08 7c91003d 00143fe8 00140178 00145b94 nt!ZwYieldExecution+0xb78 f9648ecc 7c911432 00000483 7c97b120 7c911440 ntdll!RtlFreeHeap+0x647 f9648f04 7c911440 00140000 7c9113d2 0012f624 ntdll!RtlpFreeDebugInfo+0x5c f9648f2c 7c91003d 00144bf4 00144be0 00000000 ntdll!RtlpFreeDebugInfo+0x6a f9648fec 00000000 00000000 00000000 00000000 ntdll!RtlFreeHeap+0x647
STACK_COMMAND: kb
SYMBOL_STACK_INDEX: 0
SYMBOL_NAME: nt!IofCallDriver+29
FOLLOWUP_NAME: MachineOwner
IMAGE_NAME: ntoskrnl.exe
BUCKET_ID: WRONG_SYMBOLS
Followup: MachineOwner
попробую проверить все выделения памяти ещё, повторюсь до моей функции дело даже не доходит, собственно поэтому не важно, что я пишу в Information(ну во всяком случае пока не важно:)) или я где-то чего-то затираю или перерасходую память
дело в том что любая запись на носитель виндой кэшируется, попробую проверить ещё какие IOCTL ходят во время попытки записи и попутный вопрос, я видел что в DEVICE_OBJECT есть поле Characteristics а одно из его значений FILE_READ_ONLY_DEVICE, так вот что будет если я буду динамически выставлять и снимать эту характеристику в своём FDO?
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #19 : 19-12-2008 22:06 » |
|
проверьте - всегда ли он падает, или только с случае если в работе запрещал какие то IRP? READ_ONLY - это надо посмотреть чnо обозначает, но больше похоже на реакцию на ReadFile... больше похоже на запорченную память смущает вызов RtlpFreeDebugInfo в стеке вызовов... правда не знаю что за функция... и стек может быть выведен некорректно... переполнение стека проверьте - в кернеле он помоему 4кб всего. ВЕЗДЕ вставляйте проверку NTSTATUS() вызываемых функций... а то часто люди ленятся... проверьте все ли функции могут быть вызваны и на используемых IRQL. вставьте проверку на всякий случай, где не уверены. а теперь главная жо**... UNICODE_STRING parameters; RtlInitUnicodeString(¶meters, L"Parameters"); а кто размещает буфер для строки: parameters.Buffer??!? про RtlInitUnicodeString - это не сказано!?.... завтра полезу в примеры DDK... ЗЫ посмотрел. ну да... забыл совсем) проверьте на всякий случай выделение памяти под CurrentList->PermitList[InnerCounter].DeviceUID в строке: RtlInitAnsiString(&(CurrentList->PermitList[InnerCounter].DeviceUID), (LoadedBuffer + CurrentOffset)); второй параметр - это верно? должен быть указатель на буфер со строкой... после этого CurrentList не живет без LoadedBuffer? ЕСЛИ Я ПРАВИЛЬНО ПОНЯЛ (судя по примерам DDK): RtlInitUnicodeString/RtlInitAnsiString - память для буфера не выделют! однако если в качестве инициализации используется константное выражение... то видимо они просто подставляют его указатель? UNICODE_STRING ntDeviceName; RtlInitUnicodeString( &ntDeviceName, NTDEVICE_NAME_STRING ); В случае, если сначала происходит инициализация константным выражением, а потом оно изменяется... то память выделяется ОБЯЗАТЕЛЬНО! (кусок примера) UNICODE_STRING fullPortName; ..... fullPortName.MaximumLength = 0; RtlInitUnicodeString(&fullPortName, NULL);
fullPortName.MaximumLength = sizeof(L"\\Device\\") + basePortName.Length + sizeof (UNICODE_NULL);
fullPortName.Buffer = ExAllocatePool(PagedPool, fullPortName.MaximumLength); if (!fullPortName.Buffer) { status = STATUS_UNSUCCESSFUL; goto KeyboardClassInitializeExit; } RtlZeroMemory(fullPortName.Buffer, fullPortName.MaximumLength); RtlAppendUnicodeToString(&fullPortName, L"\\Device\\"); RtlAppendUnicodeToString(&fullPortName, basePortName.Buffer); RtlAppendUnicodeToString(&fullPortName, L"0");
......................
if (fullPortName.MaximumLength != 0){ ExFreePool (fullPortName.Buffer); }
полез у себя проверять...))) PPS не... я просто зайка) у меня все правильно)))
|
|
« Последнее редактирование: 20-12-2008 10:58 от Ochkarik »
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
elDraco
Гость
|
|
« Ответ #20 : 20-12-2008 18:45 » |
|
таки свершилось:) отладил вроде:) 1) по висюку: что-то я действительно видимо затирал, но не из-за выделенной мной памяти, при создании управляющего FDO потерял 2 важных действия ControlDeviceObject->Flags |= DO_BUFFERED_IO;//скорее всего память портилась из-за отсутствия именно этого флага ControlDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;//ну это просто косяк, особого влияния на падения он не оказывал не знаю необходимо ли обрабатывать IRP_MJ_CLEANUP, но про него я тоже забыл 2) запись смог заблокировать полностью, но только до первого разрешения записи (то есть, если устройство стартануло в заблокированном состоянии, то запись блокируется полностью, а если сделать разрешить запись потом заблокировать, то начинает опять ругаться кэш) сделано было путём обработки IOCTL_DISK_IS_WRITEABLE, если нужно блокировать запись, то возвращаю тут STATUS_MEDIA_WRITE_PROTECTED иначе просто шлю дальше по стеку с этим я ещё поработаю и протестирую по полной Ochkarik, огромное спасибо за помощь и терпение:) надеюсь мои грабли помогут ещё кому-нить избежать лишних шишек:) зы: руководство по управляемым фильтрам от мелкософта http://support.microsoft.com/kb/262305, я сделал интуитивно практически то же самое, но чуть проще (без инстанс каунтера просто создаю управляющий FDO в DriverEntry и удаляю в DriverUnload)
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #21 : 20-12-2008 22:12 » |
|
и вам спасибо за интересный опыт)
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
|