-
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
- * FILE: ntoskrnl/io/irp.c
+ * FILE: ntoskrnl/io/iomgr/irp.c
* PURPOSE: IRP Handling Functions
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* Gunnar Dalsnes
#include <ntoskrnl.h>
#define NDEBUG
-#include <internal/debug.h>
+#include <debug.h>
/* Undefine some macros we implement here */
#undef IoCallDriver
FileObject);
/* Sanity check */
- ASSERT(Irp->IoStatus.Status != 0xFFFFFFFF);
+ ASSERT(Irp->IoStatus.Status != (NTSTATUS)0xFFFFFFFF);
/* Check if we have a file object */
if (*SystemArgument2)
if (Irp->Flags & IRP_DEALLOCATE_BUFFER)
{
/* Deallocate it */
- ExFreePoolWithTag(Irp->AssociatedIrp.SystemBuffer, TAG_SYS_BUF);
+ ExFreePool(Irp->AssociatedIrp.SystemBuffer);
}
}
}
/* Use SEH to make sure we don't write somewhere invalid */
- _SEH_TRY
+ _SEH2_TRY
{
/* Save the IOSB Information */
*Irp->UserIosb = Irp->IoStatus;
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Ignore any error */
}
- _SEH_END;
+ _SEH2_END;
/* Check if we have an event or a file object */
if (Irp->UserEvent)
/* Check if this is an Asynch API */
if (!(Irp->Flags & IRP_SYNCHRONOUS_API))
{
- /* HACK */
- if (*((PULONG)(Irp->UserEvent) - 1) != 0x87878787)
- {
/* Dereference the event */
ObDereferenceObject(Irp->UserEvent);
- }
- else
- {
- DPRINT1("Not an executive event -- should not be dereferenced\n");
- }
}
/*
}
}
+ /* Update transfer count for everything but create operation */
+ if (!(Irp->Flags & IRP_CREATE_OPERATION))
+ {
+ if (Irp->Flags & IRP_WRITE_OPERATION)
+ {
+ /* Update write transfer count */
+ IopUpdateTransferCount(IopWriteTransfer,
+ (ULONG)Irp->IoStatus.Information);
+ }
+ else if (Irp->Flags & IRP_READ_OPERATION)
+ {
+ /* Update read transfer count */
+ IopUpdateTransferCount(IopReadTransfer,
+ (ULONG)Irp->IoStatus.Information);
+ }
+ else
+ {
+ /* Update other transfer count */
+ IopUpdateTransferCount(IopOtherTransfer,
+ (ULONG)Irp->IoStatus.Information);
+ }
+ }
+
/* Now that we've signaled the events, de-associate the IRP */
IopUnQueueIrpFromThread(Irp);
{
/* We have an I/O Completion setup... create the special Overlay */
Irp->Tail.CompletionKey = Key;
- Irp->Tail.Overlay.PacketType = IrpCompletionPacket;
+ Irp->Tail.Overlay.PacketType = IopCompletionPacketIrp;
KeInsertQueue(Port, &Irp->Tail.Overlay.ListEntry);
}
else
/* Set Charge Quota Flag */
if (ChargeQuota) Flags |= IRP_QUOTA_CHARGED;
+ /* FIXME: Implement Lookaside Floats */
+
/* Figure out which Lookaside List to use */
if ((StackSize <= 8) && (ChargeQuota == FALSE))
{
}
else
{
- /* We have an IRP from Lookaside */
- if (ChargeQuota) Flags |= IRP_LOOKASIDE_ALLOCATION;
-
/* In this case there is no charge quota */
Flags &= ~IRP_QUOTA_CHARGED;
}
/* Allocate IRP */
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
- if (!Irp) return Irp;
+ if (!Irp) return NULL;
/* Get the Stack */
StackPtr = IoGetNextIrpStackLocation(Irp);
}
/* Probe and Lock */
- _SEH_TRY
+ _SEH2_TRY
{
/* Do the probe */
MmProbeAndLockPages(Irp->MdlAddress,
MajorFunction == IRP_MJ_READ ?
IoWriteAccess : IoReadAccess);
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Free the IRP and its MDL */
IoFreeMdl(Irp->MdlAddress);
IoFreeIrp(Irp);
- Irp = NULL;
+
+ /* Fail */
+ _SEH2_YIELD(return NULL);
}
- _SEH_END;
-
- /* This is how we know if we failed during the probe */
- if (!Irp) return NULL;
+ _SEH2_END;
}
else
{
Irp->UserIosb = IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
- /* Set the Status Block after all is done */
+ /* Return the IRP */
IOTRACE(IO_IRP_DEBUG,
"%s - Built IRP %p with Major, Buffer, DO %lx %p %p\n",
__FUNCTION__,
/* Allocate IRP */
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
- if (!Irp) return Irp;
+ if (!Irp) return NULL;
/* Get the Stack */
StackPtr = IoGetNextIrpStackLocation(Irp);
}
else
{
+ /* Clear the flags */
Irp->Flags = 0;
}
}
/* Probe and Lock */
- _SEH_TRY
+ _SEH2_TRY
{
/* Do the probe */
MmProbeAndLockPages(Irp->MdlAddress,
METHOD_IN_DIRECT ?
IoReadAccess : IoWriteAccess);
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Free the MDL */
IoFreeMdl(Irp->MdlAddress);
/* Free the input buffer and IRP */
if (InputBuffer) ExFreePool(Irp->AssociatedIrp.SystemBuffer);
IoFreeIrp(Irp);
- Irp = NULL;
- }
- _SEH_END;
- /* This is how we know if probing failed */
- if (!Irp) return NULL;
+ /* Fail */
+ _SEH2_YIELD(return NULL);
+ }
+ _SEH2_END;
}
break;
IoCancelIrp(IN PIRP Irp)
{
KIRQL OldIrql;
+ KIRQL IrqlAtEntry;
PDRIVER_CANCEL CancelRoutine;
IOTRACE(IO_IRP_DEBUG,
"%s - Canceling IRP %p\n",
__FUNCTION__,
Irp);
ASSERT(Irp->Type == IO_TYPE_IRP);
+ IrqlAtEntry = KeGetCurrentIrql();
/* Acquire the cancel lock and cancel the IRP */
IoAcquireCancelSpinLock(&OldIrql);
Irp->Cancel = TRUE;
/* Clear the cancel routine and get the old one */
- CancelRoutine = IoSetCancelRoutine(Irp, NULL);
+ CancelRoutine = (PVOID)IoSetCancelRoutine(Irp, NULL);
if (CancelRoutine)
{
/* We had a routine, make sure the IRP isn't completed */
/* Set the cancel IRQL And call the routine */
Irp->CancelIrql = OldIrql;
CancelRoutine(IoGetCurrentIrpStackLocation(Irp)->DeviceObject, Irp);
+ ASSERT(IrqlAtEntry == KeGetCurrentIrql());
return TRUE;
}
* Don't stay here forever if some broken driver doesn't complete
* the IRP.
*/
- if (!(Retries--)) IopRemoveThreadIrp();
+ if (!(Retries--))
+ {
+ /* Print out a message and remove the IRP */
+ DPRINT1("Broken driver did not complete!\n");
+ IopRemoveThreadIrp();
+ }
/* Raise the IRQL Again */
KeRaiseIrql(APC_LEVEL, &OldIrql);
IoCallDriver(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
- /* Call fast call */
+ /* Call fastcall */
return IofCallDriver(DeviceObject, Irp);
}
IN PIRP Irp)
{
PDRIVER_OBJECT DriverObject;
- PIO_STACK_LOCATION Param;
+ PIO_STACK_LOCATION StackPtr;
+
+ /* Make sure this is a valid IRP */
+ ASSERT(Irp->Type == IO_TYPE_IRP);
/* Get the Driver Object */
DriverObject = DeviceObject->DriverObject;
}
/* Now update the stack location */
- Param = IoGetNextIrpStackLocation(Irp);
- Irp->Tail.Overlay.CurrentStackLocation = Param;
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ Irp->Tail.Overlay.CurrentStackLocation = StackPtr;
/* Get the Device Object */
- Param->DeviceObject = DeviceObject;
+ StackPtr->DeviceObject = DeviceObject;
/* Call it */
- return DriverObject->MajorFunction[Param->MajorFunction](DeviceObject,
- Irp);
+ return DriverObject->MajorFunction[StackPtr->MajorFunction](DeviceObject,
+ Irp);
}
FORCEINLINE
ASSERT(Irp->Type == IO_TYPE_IRP);
ASSERT(!Irp->CancelRoutine);
ASSERT(Irp->IoStatus.Status != STATUS_PENDING);
- ASSERT(Irp->IoStatus.Status != 0xFFFFFFFF);
+ ASSERT(Irp->IoStatus.Status != (NTSTATUS)0xFFFFFFFF);
/* Get the last stack */
LastStackPtr = (PIO_STACK_LOCATION)(Irp + 1);
if (LastStackPtr->Control & SL_ERROR_RETURNED)
{
/* Get the error code */
- ErrorCode = (NTSTATUS)LastStackPtr->Parameters.Others.Argument4;
+ ErrorCode = PtrToUlong(LastStackPtr->Parameters.Others.Argument4);
}
/* Get the Current Stack and skip it */
/* Update the error for the current stack */
ErrorCode = Irp->IoStatus.Status;
StackPtr->Control |= SL_ERROR_RETURNED;
- LastStackPtr->Parameters.Others.Argument4 = (PVOID)ErrorCode;
+ LastStackPtr->Parameters.Others.Argument4 = UlongToPtr(ErrorCode);
LastStackPtr->Control |= SL_ERROR_RETURNED;
}
}
NTSTATUS
NTAPI
-IopSynchronousCompletion(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context)
+IopSynchronousCompletion(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context)
{
if (Irp->PendingReturned)
KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
}
+ /* Return success */
return TRUE;
}
if (!(Irp->AllocationFlags & IRP_ALLOCATED_FIXED_SIZE))
{
/* Free it */
- ExFreePool(Irp);
+ ExFreePoolWithTag(Irp, TAG_IRP);
}
else
{
{
/* All lists failed, use the pool */
List->L.FreeMisses++;
- ExFreePool(Irp);
+ ExFreePoolWithTag(Irp, TAG_IRP);
Irp = NULL;
}
}
/*
* @implemented
*/
-PEPROCESS NTAPI
+IO_PAGING_PRIORITY
+FASTCALL
+IoGetPagingIoPriority(IN PIRP Irp)
+{
+ IO_PAGING_PRIORITY Priority;
+ ULONG Flags;
+
+ /* Get the flags */
+ Flags = Irp->Flags;
+
+ /* Check what priority it has */
+ if (Flags & 0x8000) // FIXME: Undocumented flag
+ {
+ /* High priority */
+ Priority = IoPagingPriorityHigh;
+ }
+ else if (Flags & IRP_PAGING_IO)
+ {
+ /* Normal priority */
+ Priority = IoPagingPriorityNormal;
+ }
+ else
+ {
+ /* Invalid -- not a paging IRP */
+ Priority = IoPagingPriorityInvalid;
+ }
+
+ /* Return the priority */
+ return Priority;
+}
+
+/*
+ * @implemented
+ */
+PEPROCESS
+NTAPI
IoGetRequestorProcess(IN PIRP Irp)
{
- return(Irp->Tail.Overlay.Thread->ThreadsProcess);
+ /* Return the requestor process */
+ return Irp->Tail.Overlay.Thread->ThreadsProcess;
}
/*
NTAPI
IoGetRequestorProcessId(IN PIRP Irp)
{
- return (ULONG)(IoGetRequestorProcess(Irp)->UniqueProcessId);
+ /* Return the requestor process' id */
+ return PtrToUlong(IoGetRequestorProcess(Irp)->UniqueProcessId);
}
/*
NTAPI
IoGetTopLevelIrp(VOID)
{
+ /* Return the IRP */
return (PIRP)PsGetCurrentThread()->TopLevelIrp;
}
IoSetTopLevelIrp(IN PIRP Irp)
{
/* Set the IRP */
- PsGetCurrentThread()->TopLevelIrp = (ULONG)Irp;
+ PsGetCurrentThread()->TopLevelIrp = (ULONG_PTR)Irp;
}
-
-/* EOF */