я использую для обработки IRP_MN_MOUNT_VOLUME код примерно такой же как и SFilter, который крешит так же как SFilter, при подключении Usb device. Я делаю примерно так (код сокращен для понимания): FsControlMountVolume(DeviceObject,Irp) вызывается когда (irpStack->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL)&&(irpStack->MinorFunction == IRP_MN_MOUNT_VOLUEM) Код (Text): NTSTATUS FsControlMountVolume (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PSD_DEVICE_EXTENSION devExt = DeviceObject->DeviceExtension; PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp ); PDEVICE_OBJECT newDeviceObject; PDEVICE_OBJECT storageStackDeviceObject; PSD_DEVICE_EXTENSION newDevExt; PFSCTRL_COMPLETION_CONTEXT completionContext; KEVENT waitEvent; storageStackDeviceObject = irpSp->Parameters.MountVolume.Vpb->RealDevice; // code don't attach to shadow volums skipped status = IoCreateDevice( gDriverObject,sizeof( SD_DEVICE_EXTENSION ),NULL,DeviceObject->DeviceType,0,FALSE, &newDeviceObject ); //error handling skipped newDevExt = newDeviceObject->DeviceExtension; newDevExt->StorageStackDeviceObject = storageStackDeviceObject; KeInitializeEvent( &waitEvent, NotificationEvent, FALSE ); IoCopyCurrentIrpStackLocationToNext ( Irp ); IoSetCompletionRoutine( Irp, FsControlCompletion, &waitEvent,TRUE, TRUE, TRUE );//called by lower driver on completition status = IoCallDriver( devExt->AttachedToDeviceObject, Irp ); if (STATUS_PENDING == status) { status = KeWaitForSingleObject( &waitEvent,Executive,KernelMode,FALSE, NULL ); } //we here mounted status = FsControlMountVolumeComplete( DeviceObject,Irp,newDeviceObject, &Name );//attach here return status; } //callback NTSTATUS FsControlCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); return STATUS_MORE_PROCESSING_REQUIRED; } //called after volume mounted NTSTATUS FsControlMountVolumeComplete (IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PDEVICE_OBJECT NewDeviceObject,IN PUNICODE_STRING Name) { PVPB vpb; PSD_DEVICE_EXTENSION newDevExt; PIO_STACK_LOCATION irpSp; PDEVICE_OBJECT attachedDeviceObject; NTSTATUS status; newDevExt = NewDeviceObject->DeviceExtension; irpSp = IoGetCurrentIrpStackLocation( Irp ); vpb = newDevExt->StorageStackDeviceObject->Vpb; if (NT_SUCCESS( Irp->IoStatus.Status )) { ExAcquireFastMutex( &gExtensionListLock ); //check not to attached to volume so far ,skipped status = FsAttachToMountedDevice( newDevExt->StorageStackDeviceObject, NewDeviceObject ); //error handling skipped // Release the lock ExReleaseFastMutex( &gExtensionListLock ); status = Irp->IoStatus.Status; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return status; } NTSTATUS FsAttachToMountedDevice (IN PDEVICE_OBJECT volumeDeviceObject,IN PDEVICE_OBJECT ourDeviceObject) { PSD_DEVICE_EXTENSION newDevExt = ourDeviceObject->DeviceExtension; if(volumeDeviceObject->Flags & DO_BUFFERED_IO) ourDeviceObject->Flags |= DO_BUFFERED_IO; if(volumeDeviceObject->Flags & DO_DIRECT_IO) ourDeviceObject->Flags |= DO_DIRECT_IO; //i do 8-attempts, error handling skipped status = (gFuncTbl.AttachDeviceToDeviceStackSafe)( ourDeviceObject,volumeDeviceObject,&(newDevExt->AttachedToDeviceObject)); ourDeviceObject->Flags &= (~DO_DEVICE_INITIALIZING); return STATUS_SUCCESS; } Креш происходит после вызова AttachDeviceToDeviceStackSafe Кто может подсказать в чем тут дело, и если можно расскажите о VPB
вместо линии status = FsAttachToMountedDevice( newDevExt->StorageStackDeviceObject, NewDeviceObject ); следует читать status = FsAttachToMountedDevice( vpb->DeviceObject, NewDeviceObject ); но это моего вопроса не меняет (результат, что в первом случае, что во втором один и тот же, синий экран)
причина то кажется ясна, а уже вошел в сомплетишн рутин, а vpb->Flags бит VPB_MOUNTED ноль, то есть нет Logical Volume для физикл девайса. Но почему так и как с этим бороться.
после того как я выхожу из обработчика, наверное IO manager ставит VPB_MOUNTED бит (я делал pVpb глобальной и смотрел при следующем вызове какого либо объекта) Помогите как послать запрос этому же device объекту, но чтобы текущая обработка закончилась, а тот запрос был следующий
вопрос решен, проблема у меня была совсем в другом месте. Код тот что я приводил правильный и бит VPB_MOUNTED так и должен взводиться IO Manager только после возврата из обработчика IRP_MN_MOUNT_VOLUME.