Всем доброго! Собственно проблема следующего характера. В драйвер-фильтре при получении IRP_MJ_CREATE, я пытаюсь выделить(NonPagedPool) ресурс под собственную переменную, так вот иногда эта попытка завершается неудачей, я пытался завершать этот запрос таким образом Код (Text): Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; Irp->IoStatus.Information = 0; IoCompleteRequest (Irp, IO_NO_INCREMENT); return STATUS_INSUFFICIENT_RESOURCES; но желаемого результата такое завершение не дает, а именно, я надеялся, что такая комбинации побудит систему вновь сформировать IRP_MJ_CREATE, но как выясняется, этого не происходит, как решить эту проблему? Мне нужно, при неудачной поппытке заставитиь ситему вновь организовать запрос, какэто сделать? Всем откликнувшимся спасибо!
<font color="gray][ LuckyDevil</font><!--color--><font color="gray]: ...так вот иногда эта попытка завершается неудачей... ]</font><!--color--> В этом случае весьма велика вероятность, что очень скоро система вообще кирдыкнется. Либо ты просишь очень много. <font color="gray][ LuckyDevil</font><!--color--><font color="gray]: Мне нужно, при неудачной поппытке заставитиь ситему вновь организовать запрос, какэто сделать? ]</font><!--color--> Если это запрос к фильтруемому стеку, а не к CDO, то, IMHO, никак. Ты же даже не знаешь кто и зачем открывает девайс и нет предопределенного способа заставить его повторить попытку. Можно попробовать в цикле 3-4 раза повторять попытку. Может быть с задержкой. Но всё равно это очень странно. Если ты не можещь выделить память, то и никто другой не сможет и кирдык уже близок. Может ты с квотой отжираешь? Покажи код.
Four-F Привет, и так по порядку Будешь, смеяться но прошу порой не так много , т.е. приходить к примеру FileObject->FileName и Buffer содержит в себе не более 2-х байт, тобишь '\\', соответственно я расширяю этот буфер но не более чем на 66 байт, я не думаю что это супер много, но однако выделение памяти проходит неудачно, если честно я не ожидал столкнуться с такой проблемой. К примеру в такой же ситуации но при IRP_MJ_READ\WRITE я решал подобную проблему так Код (Text): Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; Irp->IoStatus.Information = 0; IoCompleteRequest (Irp, IO_NO_INCREMENT); return STATUS_INSUFFICIENT_RESOURCES; после чего я получал очередную попытку выделения ресурса, и это работает, т.е. система сама формировала повторный IRP. По поводу стабильности системы, тут скажу только одно драйвер, пусть даже и криво-сырой, но работает на удевление стабильно, проверяю его под verifier. Может именно из-за verifier я наблюдаю эти проблемы, но все же хочу изначально написать драйвер который будет максимально стабилен в системе, при любых нагрузках. Вообщем, полная з...ца, как быть не знаю!!!
Four-F вот код: Код (Text): ... StringLength = FileName->Length + LenExt + sizeof(WCHAR); SavedBackupFileName = (PUNICODE_STRING) ExAllocatePoolWithTag(NonPagedPool, sizeof(UNICODE_STRING) + StringLength, MY_TAG); if (SavedBackupFileName == NULL) { return NULL; } ...
<font color="gray][ LuckyDevil</font><!--color--><font color="gray]: Может именно из-за verifier я наблюдаю эти проблемы ]</font><!--color--> Ну ты сам подумай, если у тебя Verifier запарен с включённой опцией имитации нехватки ресурсов, то сколь малое коль-во памяти ты бы не просил, рано или поздно он это обломит. А теперь подумай, что будет на реально работающей системе, если ты даже не сможешь 100 байт из пула взять? Если дело действительно в Verifier'е, то забей! Если вдруг у одного из 1000000 юзеров один раз в 1000 лет и случится такая жуткая нехватка памяти, то система всё равно работать не сможет!
Four-F, еще вопрос. В коде своей программы использую списки для хранения моих данных, вставка, поиск и удаление из списка делаю как положено, через KeAcquireSpinLock и KeReleaseSpinLock. Так вот меня интересует следующее, к примеру нахожу я в списке нуные данные, стоит ли мне выполнять блокировку этих данный в процессе их модификации и если нужно, то как правильно это сделать Код (Text): ... //В этой функции выполянется посик искомых данных в списке formatsEntry = FindByFCB(&gGlobal,FileObject->FsContext); if(formatsEntry != NULL){ if((formatsEntry->ChangeFile)){ [b]//Сомнения возникают тут, стоит ли выполнять блокировку, на момент модификации данных? formatsEntry->Counter++; [/b] ... ... } return NULL; } ...
Лучше InterlockedIncrement(&formatsEntry->Counter) Но ты должен быть уверен, что ни в коем случае formatsEntry не будет удален до момента окончания его использования. В случае, если структура используется в многих местах программы, которые сложно взаимодействуют между собой, использовать блокируовку неприемлимо, вместо нее лучше сделать счетчик ссылок на обьект. Внимание: использование не Interlocked функций, приводит к глюкам на SMP системах (проверено на практике)
Ms Rem, как раз таки хотелось бы чтобы не было подобного, может использование FAST_MUTEX'ы поможет решить эту проблему(хотя на самом деле проблем пока не было, но явно может случиться так что, в тот момент когда будут производиться изменения в переменной "А", другой процесс может тоже начать выполнять подобного рода операции)?
<font color="gray][ LuckyDevil</font><!--color--><font color="gray]: стоит ли мне выполнять блокировку этих данный в процессе их модификации ]</font><!--color--> Однозначно блокировать нужно любой доступ на изменение совместно используемых данных. В твоём случае ты не можешь отпускать блокировку пока не изменишь счетчик. Либо ты должен отстигнуть структуру от списка, но это вряд ли приемлемо. Подумай об этом так: я хватаю блокировку, ищу данные... нашёл, но как только я отпущу блокировку обязательно кто-то другой её тут же схватит, отберёт у меня процессор и отстегнёт найденную мной структуру от списка и освободит память под ней, после чего я начну её изменять и ... кирдык. ЗЫ: Ms Rem, поделись секретом про глюки.