FORCEINLINE VOID FxIrp::SetCompletionRoutineEx( __in MdDeviceObject DeviceObject, __in MdCompletionRoutine CompletionRoutine, __in PVOID Context, __in BOOLEAN InvokeOnSuccess, __in BOOLEAN InvokeOnError, __in BOOLEAN InvokeOnCancel ) { if (!NT_SUCCESS(IoSetCompletionRoutineEx( DeviceObject, m_Irp, CompletionRoutine, Context, InvokeOnSuccess, InvokeOnError, InvokeOnCancel))) { IoSetCompletionRoutine( m_Irp, CompletionRoutine, Context, InvokeOnSuccess, InvokeOnError, InvokeOnCancel ); } }
/* * @implemented */ VOID IssueUniqueIdChangeNotifyWorker(IN PUNIQUE_ID_WORK_ITEM WorkItem, IN PMOUNTDEV_UNIQUE_ID UniqueId) { PIRP Irp; NTSTATUS Status; PFILE_OBJECT FileObject; PIO_STACK_LOCATION Stack; PDEVICE_OBJECT DeviceObject; /* Get the device object */ Status = IoGetDeviceObjectPointer(&(WorkItem->DeviceName), FILE_READ_ATTRIBUTES, &FileObject, &DeviceObject); if (!NT_SUCCESS(Status)) { RemoveWorkItem(WorkItem); return; } /* And then, the attached device */ DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject); /* Initialize the IRP */ Irp = WorkItem->Irp; IoInitializeIrp(Irp, IoSizeOfIrp(WorkItem->StackSize), (CCHAR)WorkItem->StackSize); if (InterlockedExchange((PLONG)&(WorkItem->Event), 0) != 0) { ObDereferenceObject(FileObject); ObDereferenceObject(DeviceObject); RemoveWorkItem(WorkItem); return; } Irp->AssociatedIrp.SystemBuffer = WorkItem->IrpBuffer; Irp->Tail.Overlay.Thread = PsGetCurrentThread(); RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, UniqueId, UniqueId->UniqueIdLength + sizeof(USHORT)); Stack = IoGetNextIrpStackLocation(Irp); Stack->Parameters.DeviceIoControl.InputBufferLength = UniqueId->UniqueIdLength + sizeof(USHORT); Stack->Parameters.DeviceIoControl.OutputBufferLength = WorkItem->IrpBufferLength; Stack->Parameters.DeviceIoControl.Type3InputBuffer = 0; Stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY; Stack->MajorFunction = IRP_MJ_DEVICE_CONTROL; Status = IoSetCompletionRoutineEx(WorkItem->DeviceExtension->DeviceObject, Irp, UniqueIdChangeNotifyCompletion, WorkItem, TRUE, TRUE, TRUE); if (!NT_SUCCESS(Status)) { ObDereferenceObject(FileObject); ObDereferenceObject(DeviceObject); RemoveWorkItem(WorkItem); return; } /* Call the driver */ IoCallDriver(DeviceObject, Irp); ObDereferenceObject(FileObject); ObDereferenceObject(DeviceObject); }