By introducing a dedicated thread and keep my info there you are saying I have to use regular ZwWrite() calls, correct? And, after shutdown process put all comming write irps to WorkItems and in this case the system will have to wait while all my IRP’s are completed. Also, I am dropping my WriteRoutine().
NTSTATUS WriteRoutine(PDEVICE_OBJECT xi_device_object, PIRP xi_irp)
{
NTSTATUS result = STATUS_SUCCESS;
BOOLEAN handled = FALSE;
TraceRoutine(DEBUG_LEVEL_TRACE, (“WriteRoutine: init, IRQL [%ld].”, KeGetCurrentIrql()));
ASSERT_IRQL(DISPATCH_LEVEL);
NT_ASSERT(xi_device_object != NULL && xi_irp != NULL);
if(xi_device_object != NULL && xi_irp != NULL)
{
BBVT_DEVICE_EXTENTION* dx = (BBVT_DEVICE_EXTENTION*)(*xi_device_object).DeviceExtension;
NT_ASSERT(dx != NULL);
if(dx != NULL)
{
BOOLEAN complete_irp = FALSE;
__try
{
result = IoAcquireRemoveLock(&(*dx).Irp.RemoveLock, xi_irp);
if(NT_SUCCESS(result))
{
PIO_STACK_LOCATION curr_stack_location = IoGetCurrentIrpStackLocation(xi_irp);
NT_ASSERT(curr_stack_location != NULL);
if(curr_stack_location != NULL)
{
ULONG size = (*curr_stack_location).Parameters.Write.Length;
LARGE_INTEGER offset;
offset.QuadPart = (*curr_stack_location).Parameters.Write.ByteOffset.QuadPart;
TraceMJFName(curr_stack_location, “WriteRoutine”);
if((*xi_irp).Tail.Overlay.OriginalFileObject != (*dx).Bitmap.FileObject && size > 0)
{
UpdateBitmapFile(dx, &offset, size);
}
IoCopyCurrentIrpStackLocationToNext(xi_irp);
IoSetCompletionRoutine(xi_irp, WriteCompletionRoutine, dx, TRUE, TRUE, TRUE);
result = IoCallDriver((*dx).Core.TargetDeviceObject, xi_irp);
handled = TRUE;
}
else
{
// log error
IoReleaseRemoveLock(&(*dx).Irp.RemoveLock, xi_irp);
result = STATUS_INVALID_PARAMETER;
TraceRoutine(DEBUG_LEVEL_LOGGING, (“ERROR: [%X], %s (%ld)”, result, FILE, LINE));
}
}
else
{
complete_irp = TRUE;
}
}
__finally
{
if(complete_irp)
{
handled = TRUE;
(*xi_irp).IoStatus.Status = result;
IoCompleteRequest(xi_irp, IO_NO_INCREMENT);
}
}
}
else
{
// log error
result = STATUS_INVALID_PARAMETER;
TraceRoutine(DEBUG_LEVEL_LOGGING, (“ERROR: [%X], %s (%ld)”, result, FILE, LINE));
}
}
else
{
// log error
result = STATUS_INVALID_PARAMETER;
TraceRoutine(DEBUG_LEVEL_LOGGING, (“ERROR: [%X], %s (%ld)”, result, FILE, LINE));
}
if(!handled)
{
result = ForwardIrp(xi_device_object, xi_irp);
}
TraceRoutine(DEBUG_LEVEL_TRACE, (“WriteRoutine: final [%X], handled is [%s].”, result, handled ? “TRUE” : “FALSE”));
return result;
}
Thanks,
Arthur