Привет всем! столкнулся с такой проблемой: взял SFilter из из примеров DDK, и хочу теперь в IRP_MJ_READ dispatch routine сделать редирект запросов нижестоящему драйверу...однако получаю BSOD... код обработчика IRP_MJ_READ: Код (Text): hProcess = PsGetCurrentProcessId(); if( (KeGetCurrentIrql() >= APC_LEVEL)||(hAttachedProcessID != hProcess)||(hAttachedProcessID == 0) || (Irp->Flags & IRP_PAGING_IO) || (Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO) ) { IoSkipCurrentIrpStackLocation( Irp ); return IoCallDriver( ((PDRIVER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp ); } else { tIrpRead = IoAllocateIrp( ((PRBDRIVER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject->StackSize, FALSE ); // заполнение tIrpRead } так вот, может кто-нибудь подсказать, как правильно заполнять tIrpRead (или примерчик кода), чтобы операция чтения прошла без BSOD... заранее благодарен за помощь!
В общем случае примерно так. С IoAllocateIrp больно много руками заполнять придется. Ну и код выше очень странный... Код (Text): NTSTATUS status; PIRP pIrp; KEVENT event; IO_STATUS_BLOCK iosb; LARGE_INTEGER offset; UCHAR buffer[ 512 ]; // you'd better allocate it from the pool offset.QuadPart = 0; pIrp = IoBuildSynchronousFsdRequest( IRP_MJ_READ, pDeviceObject, buffer, sizeof(buffer), &offset, &event, &iosb); if ( pIrp ) { KeInitializeEvent( &event, NotificationEvent, FALSE ); status = IoCallDriver( pDeviceObject, pIrp ); if ( STATUS_PENDING == status ) { KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL ); status = iosb.Status; } if ( NT_SUCCESS( status ) ) { } }
Four-F, спасибо за код! а что такого странного в моем коде? пропускаю все запросы не от моей тестовой проги, а так же пропускаю все PAGING_IO... а вот мне что-то не совсем понятно насчет offset... используя этот код смещение будет получаться относительно чего? относительно начала диска (раздела)? т.е. обрабатывая IRP_MJ_READ, я могу получить смещение относительно начала файла: IrpSp = IoGetCurrentIrpStackLocation(Irp); IrpSp->Parameters.Read.ByteOffset; т.е. основной вопрос как прочитать содержимое файла используя IoBuildSynchronousFsdRequest. или я чего-то недопонимаю?
Странно то, что ты зачем-то создаешь новый IRP. Ты говоришь, что "хочу теперь в IRP_MJ_READ dispatch routine сделать редирект запросов нижестоящему драйверу". Ну так и редиректь. Зачем новый-то делать? И что делать с тем, что пришел в твою "IRP_MJ_READ dispatch routine"? Стандартно ставится процедура завершения (completion routine), которая будет вызвана при завершинии IRP. В ней и можно посмотреть, что прочитано, если тебе это надо. Например, вот так (опять же примерно): Код (Text): NTSTATUS ReadCompletion ( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp, IN PVOID pContext ) { if ( NT_SUCCESS(pIrp->IoStatus.Status) ) { DebugPrint( "Bytes transferred 0x%X \n", pIrp->IoStatus.Information ); } if ( pIrp->PendingReturned ) { IoMarkIrpPending( pIrp ); } return STATUS_SUCCESS; } . . . } else { IoCopyCurrentIrpStackLocationToNext( pIrp ); IoSetCompletionRoutine( pIrp, ReadCompletion, NULL, TRUE, TRUE, TRUE ); return IoCallDriver( ((PDRIVER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, pIrp ); } } Если запрос к девайсу, управляющему разделом, то от начала раздела. Я, кстати, не имел в виду именно запрос к диску. Это смещение драйвер получит в pIoStack->Parameters.Read.ByteOffset, а относительно чего, уже его дело. Например я могу создать драйвер, который выделит буфер и будет в него что-то писАть, лог какой-нибудь. Если клиент захочет получить лог с самого начала через ReadFile, то определит офсет равным нулю, а если с какого-нибудь другого места, то определит нужное смещение в буфере. Напрямую, видимо, никак. Если говорить о чтении диска, то можно зная размер сектора, читать его посекторно. Из исходного поста не понятно зачем вообще всё это нужно, и чего ты в итоге хочешь добиться, поэтому я тоже не совсем понимаю и, кстати, в драйверах файловых систем не силён - могу попутать что-нибудь.
начсет записи лога, и чтения его по ReadFile - это хорошая мысль! мне как-то это раньше в голову не приходило... все это я начал делать, т.к. просто интересно прочитать из драйвера файл, для которого было выполнено FAST_IO_LOCK. простым перенаправлением чтения нижестоящему драйверу я получаю STATUS_LOCK_CONFLICT, а хочется все-равно прочитать файл...не писать же для этого дела кэш залоченых файлов эт ничего...я сам напостой что-нить путаю главное понять где и что я не так делаю кстати, а если после IoBuildSynchronousFsdRequest сделать IoGetNextIrpStackLocation, и туда прописать валидный FILE_OBJECT, то вроде все должно встать на "свои" места...так ведь?
Понятно. К сожалению, это не моя тема. Сходи http://www.osronline.com/page.cfm?name=search - одна из самых дельных конф по дровам. Там есть спец раздел по драйверам файловых систем. Не знаю, но не думаю, что всё так просто. В любом случае гадание на кофейной гуще, в данном случае, плохой метод.