- Move the code from my previous commit before signalling the user event
[reactos.git] / reactos / ntoskrnl / io / iomgr / irp.c
index e8854be..21870d5 100644 (file)
@@ -253,7 +253,7 @@ IopCompleteRequest(IN PKAPC Apc,
             FileObject);
 
     /* Sanity check */
-    ASSERT(Irp->IoStatus.Status != 0xFFFFFFFF);
+    ASSERT(Irp->IoStatus.Status != (NTSTATUS)0xFFFFFFFF);
 
     /* Check if we have a file object */
     if (*SystemArgument2)
@@ -286,7 +286,7 @@ IopCompleteRequest(IN PKAPC Apc,
         if (Irp->Flags & IRP_DEALLOCATE_BUFFER)
         {
             /* Deallocate it */
-            ExFreePoolWithTag(Irp->AssociatedIrp.SystemBuffer, TAG_SYS_BUF);
+            ExFreePool(Irp->AssociatedIrp.SystemBuffer);
         }
     }
 
@@ -323,16 +323,16 @@ IopCompleteRequest(IN PKAPC Apc,
         }
 
         /* 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)
@@ -393,6 +393,29 @@ IopCompleteRequest(IN PKAPC Apc,
             }
         }
 
+        /* 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);
 
@@ -419,7 +442,7 @@ IopCompleteRequest(IN PKAPC Apc,
         {
             /* 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
@@ -437,6 +460,22 @@ IopCompleteRequest(IN PKAPC Apc,
     }
     else
     {
+        /* Check if we have an associated user IOSB */
+        if (Irp->UserIosb)
+        {
+            /* We do, so let's give them the final status */
+            _SEH2_TRY
+            {
+               /*  Save the IOSB Information */
+               *Irp->UserIosb = Irp->IoStatus;
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
+               /* Ignore any error */
+            }
+            _SEH2_END;
+        }
+
         /*
          * Either we didn't return from the request, or we did return but this
          * request was synchronous.
@@ -446,9 +485,6 @@ IopCompleteRequest(IN PKAPC Apc,
             /* So we did return with a synch operation, was it the IRP? */
             if (Irp->Flags & IRP_SYNCHRONOUS_API)
             {
-                /* Yes, this IRP was synchronous, so return the I/O Status */
-                *Irp->UserIosb = Irp->IoStatus;
-
                 /* Now check if the user gave an event */
                 if (Irp->UserEvent)
                 {
@@ -519,6 +555,8 @@ IoAllocateIrp(IN CCHAR StackSize,
     /* 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))
     {
@@ -579,9 +617,6 @@ IoAllocateIrp(IN CCHAR StackSize,
     }
     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;
     }
@@ -677,7 +712,7 @@ IoBuildAsynchronousFsdRequest(IN ULONG MajorFunction,
             }
 
                        /* Probe and Lock */
-                       _SEH_TRY
+                       _SEH2_TRY
                        {
                                /* Do the probe */
                                MmProbeAndLockPages(Irp->MdlAddress,
@@ -685,17 +720,16 @@ IoBuildAsynchronousFsdRequest(IN ULONG MajorFunction,
                                                                        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
         {
@@ -869,7 +903,7 @@ IoBuildDeviceIoControlRequest(IN ULONG IoControlCode,
                 }
 
                 /* Probe and Lock */
-                _SEH_TRY
+                _SEH2_TRY
                 {
                     /* Do the probe */
                     MmProbeAndLockPages(Irp->MdlAddress,
@@ -878,7 +912,7 @@ IoBuildDeviceIoControlRequest(IN ULONG IoControlCode,
                                         METHOD_IN_DIRECT ?
                                         IoReadAccess : IoWriteAccess);
                 }
-                _SEH_HANDLE
+                _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
                 {
                     /* Free the MDL */
                     IoFreeMdl(Irp->MdlAddress);
@@ -886,12 +920,11 @@ IoBuildDeviceIoControlRequest(IN ULONG IoControlCode,
                     /* 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;
 
@@ -976,7 +1009,7 @@ IoCancelIrp(IN PIRP Irp)
     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 */
@@ -1114,6 +1147,9 @@ IofCallDriver(IN PDEVICE_OBJECT DeviceObject,
     PDRIVER_OBJECT DriverObject;
     PIO_STACK_LOCATION StackPtr;
 
+    /* Make sure this is a valid IRP */
+    ASSERT(Irp->Type == IO_TYPE_IRP);
+
     /* Get the Driver Object */
     DriverObject = DeviceObject->DriverObject;
 
@@ -1184,23 +1220,25 @@ IofCompleteRequest(IN PIRP Irp,
     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 */
+    /* Get the Current Stack */
     StackPtr = IoGetCurrentIrpStackLocation(Irp);
-    IoSkipCurrentIrpStackLocation(Irp);
 
     /* Loop the Stacks and complete the IRPs */
     do
     {
+        /* Skip current stack location */
+        IoSkipCurrentIrpStackLocation(Irp);
+
         /* Set Pending Returned */
         Irp->PendingReturned = StackPtr->Control & SL_PENDING_RETURNED;
 
@@ -1213,7 +1251,7 @@ IofCompleteRequest(IN PIRP Irp,
                 /* 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;
             }
         }
@@ -1263,10 +1301,9 @@ IofCompleteRequest(IN PIRP Irp,
             IopClearStackLocation(StackPtr);
         }
 
-        /* Move to next stack location and pointer */
-        IoSkipCurrentIrpStackLocation(Irp);
+        /* Move pointer to next stack location */
         StackPtr++;
-    } while (Irp->CurrentLocation <= (Irp->StackCount + 1));
+    } while (Irp->CurrentLocation <= Irp->StackCount);
 
     /* Check if the IRP is an associated IRP */
     if (Irp->Flags & IRP_ASSOCIATED_IRP)
@@ -1587,7 +1624,7 @@ NTAPI
 IoGetRequestorProcessId(IN PIRP Irp)
 {
     /* Return the requestor process' id */
-    return (ULONG)(IoGetRequestorProcess(Irp)->UniqueProcessId);
+    return PtrToUlong(IoGetRequestorProcess(Irp)->UniqueProcessId);
 }
 
 /*
@@ -1759,5 +1796,5 @@ NTAPI
 IoSetTopLevelIrp(IN PIRP Irp)
 {
     /* Set the IRP */
-    PsGetCurrentThread()->TopLevelIrp = (ULONG)Irp;
+    PsGetCurrentThread()->TopLevelIrp = (ULONG_PTR)Irp;
 }