|
|
Definition at line 144 of file common.c.
Referenced by CdfsGetVolumeData(), and CdfsOpenFile().
{
PIO_STACK_LOCATION Stack;
IO_STATUS_BLOCK IoStatus;
KEVENT Event;
PIRP Irp;
NTSTATUS Status;
BOOLEAN LastChance = FALSE;
DPRINT("CdfsDeviceIoControl(DeviceObject %x, CtlCode %x, "
"InputBuffer %x, InputBufferSize %x, OutputBuffer %x, "
"POutputBufferSize %x (%x)\n", DeviceObject, CtlCode,
InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize,
OutputBufferSize ? *OutputBufferSize : 0);
again:
KeInitializeEvent (&Event, NotificationEvent, FALSE);
DPRINT("Building device I/O control request ...\n");
Irp = IoBuildDeviceIoControlRequest(CtlCode,
DeviceObject,
InputBuffer,
InputBufferSize,
OutputBuffer,
(OutputBufferSize != NULL) ? *OutputBufferSize : 0,
FALSE,
&Event,
&IoStatus);
if (Irp == NULL)
{
DPRINT("IoBuildDeviceIoControlRequest failed\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
if (Override)
{
Stack = IoGetNextIrpStackLocation(Irp);
Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
}
DPRINT ("Calling IO Driver... with irp %x\n", Irp);
Status = IoCallDriver(DeviceObject, Irp);
DPRINT ("Waiting for IO Operation for %x\n", Irp);
if (Status == STATUS_PENDING)
{
DPRINT ("Operation pending\n");
KeWaitForSingleObject (&Event, Suspended, KernelMode, FALSE, NULL);
DPRINT ("Getting IO Status... for %x\n", Irp);
Status = IoStatus.Status;
}
if (OutputBufferSize != NULL)
{
*OutputBufferSize = IoStatus.Information;
}
if (Status == STATUS_VERIFY_REQUIRED)
{
PDEVICE_OBJECT DeviceToVerify;
DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
if (DeviceToVerify)
{
Status = IoVerifyVolume(DeviceToVerify, FALSE);
DPRINT("IoVerifyVolume() returned (Status %lx)\n", Status);
}
if (NT_SUCCESS(Status) && !LastChance)
{
DPRINT1("Volume verify succeeded; trying request again\n");
LastChance = TRUE;
goto again;
}
else if (NT_SUCCESS(Status))
{
DPRINT1("Failed to read after successful verify, aborting\n");
Status = STATUS_DEVICE_NOT_READY;
}
else
{
DPRINT1("IoVerifyVolume() failed (Status %lx)\n", Status);
}
}
DPRINT("Returning Status %x\n", Status);
return Status;
}
|