Added .Type and .Size attributes to the IRP object: so far nothing
[reactos.git] / reactos / ntoskrnl / io / irp.c
index 85ce624..ff02e89 100644 (file)
@@ -1,4 +1,5 @@
-/*
+/* $Id: irp.c,v 1.26 2000/03/06 01:02:30 ea Exp $
+ *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/io/irp.c
 
 /* INCLUDES ****************************************************************/
 
+#include <ddk/ntddk.h>
+#include <string.h>
 #include <internal/string.h>
 #include <internal/io.h>
-#include <ddk/ntddk.h>
 
 #define NDEBUG
 #include <internal/debug.h>
 
 /* FUNCTIONS ****************************************************************/
 
-PDEVICE_OBJECT IoGetDeviceToVerify(PETHREAD Thread)
+PDEVICE_OBJECT
+STDCALL
+IoGetDeviceToVerify (PETHREAD Thread)
 /*
  * FUNCTION: Returns a pointer to the device, representing a removable-media
  * device, that is the target of the given thread's I/O request
@@ -47,7 +51,10 @@ PDEVICE_OBJECT IoGetDeviceToVerify(PETHREAD Thread)
    UNIMPLEMENTED;
 }
 
-VOID IoFreeIrp(PIRP Irp)
+
+VOID
+STDCALL
+IoFreeIrp (PIRP Irp)
 /*
  * FUNCTION: Releases a caller allocated irp
  * ARGUMENTS:
@@ -57,7 +64,10 @@ VOID IoFreeIrp(PIRP Irp)
    ExFreePool(Irp);
 }
 
-PIRP IoMakeAssociatedIrp(PIRP Irp, CCHAR StackSize)
+
+PIRP
+STDCALL
+IoMakeAssociatedIrp (PIRP Irp, CCHAR StackSize)
 /*
  * FUNCTION: Allocates and initializes an irp to associated with a master irp
  * ARGUMENTS:
@@ -72,7 +82,13 @@ PIRP IoMakeAssociatedIrp(PIRP Irp, CCHAR StackSize)
    UNIMPLEMENTED;
 }
 
-VOID IoMarkIrpPending(PIRP Irp)
+
+/**********************************************************************
+ * NAME                                                        INTERNAL
+ *     IoMarkIrpPending
+ */
+VOID
+IoMarkIrpPending (PIRP Irp)
 /*
  * FUNCTION: Marks the specified irp, indicating further processing will
  * be required by other driver routines
@@ -80,16 +96,18 @@ VOID IoMarkIrpPending(PIRP Irp)
  *      Irp = Irp to mark
  */
 {
-   DPRINT("IoGetCurrentIrpStackLocation(Irp) %x\n",
-         IoGetCurrentIrpStackLocation(Irp));
+//   DPRINT("IoGetCurrentIrpStackLocation(Irp) %x\n",
+//       IoGetCurrentIrpStackLocation(Irp));
    IoGetCurrentIrpStackLocation(Irp)->Control |= SL_PENDING_RETURNED;
-   Irp->Tail.Overlay.Thread = KeGetCurrentThread();
-   DPRINT("IoGetCurrentIrpStackLocation(Irp)->Control %x\n",
-         IoGetCurrentIrpStackLocation(Irp)->Control);
-   DPRINT("SL_PENDING_RETURNED %x\n",SL_PENDING_RETURNED);
 }
 
-USHORT IoSizeOfIrp(CCHAR StackSize)
+
+/**********************************************************************
+ * NAME                                                        INTERNAL
+ *     IoSizeOfIrp
+ */
+USHORT
+IoSizeOfIrp (CCHAR StackSize)
 /*
  * FUNCTION:  Determines the size of an IRP
  * ARGUMENTS: 
@@ -100,7 +118,10 @@ USHORT IoSizeOfIrp(CCHAR StackSize)
    return(sizeof(IRP)+((StackSize-1)*sizeof(IO_STACK_LOCATION)));
 }
 
-VOID IoInitializeIrp(PIRP Irp, USHORT PacketSize, CCHAR StackSize)
+
+VOID
+STDCALL
+IoInitializeIrp (PIRP Irp, USHORT PacketSize, CCHAR StackSize)
 /*
  * FUNCTION: Initalizes an irp allocated by the caller
  * ARGUMENTS:
@@ -109,14 +130,22 @@ VOID IoInitializeIrp(PIRP Irp, USHORT PacketSize, CCHAR StackSize)
  *          StackSize = Number of stack locations in the IRP
  */
 {
-   assert(Irp!=NULL);
-   memset(Irp,0,PacketSize);
-   Irp->StackCount=StackSize;
-   Irp->CurrentLocation=StackSize;
-   Irp->Tail.Overlay.CurrentStackLocation=IoGetCurrentIrpStackLocation(Irp);
+   assert(Irp != NULL);
+
+   memset(Irp, 0, PacketSize);
+   Irp->Size = PacketSize;
+   Irp->StackCount = StackSize;
+   Irp->CurrentLocation = StackSize;
+   Irp->Tail.Overlay.CurrentStackLocation = IoGetCurrentIrpStackLocation(Irp);
 }
 
-PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
+
+/**********************************************************************
+ * NAME                                                        INTERNAL
+ *     IoGetCurrentIrpStackLocation
+ */
+PIO_STACK_LOCATION
+IoGetCurrentIrpStackLocation (PIRP Irp)
 /*
  * FUNCTION: Gets a pointer to the callers location in the I/O stack in
  * the given IRP
@@ -125,17 +154,33 @@ PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
  * RETURNS: A pointer to the stack location
  */
 {
-   return(&Irp->Stack[Irp->CurrentLocation]);
+//   DPRINT("IoGetCurrentIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n", 
+//          Irp,
+//          Irp->CurrentLocation,
+//          Irp->StackCount);
+
+   return(&Irp->Stack[(ULONG)Irp->CurrentLocation]);
 }
 
 
-VOID IoSetNextIrpStackLocation(PIRP Irp)
+/**********************************************************************
+ * NAME                                                        INTERNAL
+ *     IoSetNextIrpStackLocation
+ */
+VOID
+IoSetNextIrpStackLocation (PIRP Irp)
 {
    Irp->CurrentLocation--;
    Irp->Tail.Overlay.CurrentStackLocation--;
 }
 
-PIO_STACK_LOCATION IoGetNextIrpStackLocation(PIRP Irp)
+
+/**********************************************************************
+ * NAME                                                        INTERNAL
+ *     IoGetNextIrpStackLocation
+ */
+PIO_STACK_LOCATION
+IoGetNextIrpStackLocation (PIRP Irp)
 /*
  * FUNCTION: Gives a higher level driver access to the next lower driver's 
  * I/O stack location
@@ -144,30 +189,56 @@ PIO_STACK_LOCATION IoGetNextIrpStackLocation(PIRP Irp)
  * RETURNS: A pointer to the stack location 
  */
 {
+//   DPRINT("IoGetNextIrpStackLocation(Irp %x)\n",Irp);
+
    assert(Irp!=NULL);
-   DPRINT("Irp %x Irp->StackPtr %x\n",Irp,Irp->CurrentLocation);
+//   DPRINT("Irp %x Irp->StackPtr %x\n",Irp,Irp->CurrentLocation);
    return(&Irp->Stack[Irp->CurrentLocation-1]);
 }
 
-NTSTATUS IoCallDriver(PDEVICE_OBJECT DevObject, PIRP irp)
+
+NTSTATUS
+FASTCALL
+IofCallDriver (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 /*
- * FUNCTION: Sends an IRP to the next lower driver
 * FUNCTION: Sends an IRP to the next lower driver
  */
 {
-   PDRIVER_OBJECT drv = DevObject->DriverObject;
-   IO_STACK_LOCATION* param = IoGetNextIrpStackLocation(irp);
-   DPRINT("Deviceobject %x\n",DevObject);
-   DPRINT("Irp %x\n",irp);
-   irp->Tail.Overlay.CurrentStackLocation--;
-   irp->CurrentLocation--;
-   DPRINT("Io stack address %x\n",param);
-   DPRINT("Function %d Routine %x\n",param->MajorFunction,
-         drv->MajorFunction[param->MajorFunction]);
-
-   return(drv->MajorFunction[param->MajorFunction](DevObject,irp));
+   NTSTATUS Status;
+   PDRIVER_OBJECT DriverObject;
+   PIO_STACK_LOCATION Param;
+   
+//   DPRINT("IoCallDriver(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
+   
+   DriverObject = DeviceObject->DriverObject;
+   Param = IoGetNextIrpStackLocation(Irp);
+   
+   Irp->Tail.Overlay.CurrentStackLocation--;
+   Irp->CurrentLocation--;
+   
+//   DPRINT("MajorFunction %d\n", Param->MajorFunction);
+//   DPRINT("DriverObject->MajorFunction[Param->MajorFunction] %x\n",
+//         DriverObject->MajorFunction[Param->MajorFunction]);
+   Status = DriverObject->MajorFunction[Param->MajorFunction](DeviceObject,
+                                                             Irp);
+   return Status;
 }
 
-PIRP IoAllocateIrp(CCHAR StackSize, BOOLEAN ChargeQuota)
+
+NTSTATUS
+STDCALL
+IoCallDriver (PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+       return IofCallDriver (
+                       DeviceObject,
+                       Irp
+                       );
+}
+
+
+PIRP
+STDCALL
+IoAllocateIrp (CCHAR StackSize, BOOLEAN ChargeQuota)
 /*
  * FUNCTION: Allocates an IRP
  * ARGUMENTS:
@@ -177,12 +248,18 @@ PIRP IoAllocateIrp(CCHAR StackSize, BOOLEAN ChargeQuota)
  */
 {
    PIRP Irp;
-   
-   DPRINT("IoAllocateIrp(StackSize %d ChargeQuota %d)\n",StackSize,
+
+#if 0
+   DbgPrint("IoAllocateIrp(StackSize %d ChargeQuota %d)\n",
+          StackSize,
          ChargeQuota);
+   KeDumpStackFrames(0,8);
+#endif
+   
    if (ChargeQuota)
      {
-       Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));
+//     Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));
+       Irp = ExAllocatePool(NonPagedPool,IoSizeOfIrp(StackSize));
      }
    else
      { 
@@ -194,14 +271,20 @@ PIRP IoAllocateIrp(CCHAR StackSize, BOOLEAN ChargeQuota)
        return(NULL);
      }
    
-   Irp->StackCount=StackSize;
-   Irp->CurrentLocation=StackSize;
+   IoInitializeIrp(Irp, IoSizeOfIrp(StackSize), StackSize);
+
+//   DPRINT("Irp %x Irp->StackPtr %d\n", Irp, Irp->CurrentLocation);
 
-   DPRINT("Irp %x Irp->StackPtr %d\n",Irp,Irp->CurrentLocation);
-   return(Irp);
+   return Irp;
 }
 
-VOID IoSetCompletionRoutine(PIRP Irp,
+
+/**********************************************************************
+ * NAME                                                        INTERNAL
+ *     IoSetCompletionRoutine
+ */
+VOID
+IoSetCompletionRoutine (PIRP Irp,
                            PIO_COMPLETION_ROUTINE CompletionRoutine,
                            PVOID Context,
                            BOOLEAN InvokeOnSuccess,
@@ -232,11 +315,17 @@ VOID IopCompleteRequest(struct _KAPC* Apc,
                        PVOID* SystemArgument1,
                        PVOID* SystemArgument2)
 {
-   IoSecondStageCompletion((PIRP)(*NormalContext),
-                           IO_NO_INCREMENT);
+   DPRINT("IopCompleteRequest(Apc %x, SystemArgument1 %x, "
+         "(*SystemArgument1) %x\n", Apc, SystemArgument1,
+         *SystemArgument1);
+   IoSecondStageCompletion((PIRP)(*SystemArgument1),
+                           (KPRIORITY)(*SystemArgument2));
 }
 
-VOID IoCompleteRequest(PIRP Irp, CCHAR PriorityBoost)
+
+VOID
+FASTCALL
+IofCompleteRequest (PIRP Irp, CCHAR PriorityBoost)
 /*
  * FUNCTION: Indicates the caller has finished all processing for a given
  * I/O request and is returning the given IRP to the I/O manager
@@ -248,14 +337,14 @@ VOID IoCompleteRequest(PIRP Irp, CCHAR PriorityBoost)
 {
    unsigned int i;
    NTSTATUS Status;
+   PKTHREAD Thread;
    
-   DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d)\n",
-                Irp,PriorityBoost);
+   DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n",
+          Irp,PriorityBoost, Irp->UserEvent, PsGetCurrentThread());
 
    for (i=0;i<Irp->StackCount;i++)
      {
-       DPRINT("&Irp->Stack[i] %x\n",&Irp->Stack[i]);
-       if (Irp->Stack[i].CompletionRoutine!=NULL)
+       if (Irp->Stack[i].CompletionRoutine != NULL)
          {
             Status = Irp->Stack[i].CompletionRoutine(
                                             Irp->Stack[i].DeviceObject,
@@ -266,28 +355,107 @@ VOID IoCompleteRequest(PIRP Irp, CCHAR PriorityBoost)
                  return;
               }
          }
-       DPRINT("Irp->Stack[i].Control %x\n",Irp->Stack[i].Control);
        if (Irp->Stack[i].Control & SL_PENDING_RETURNED)
          {
-            DPRINT("Setting PendingReturned flag\n");
             Irp->PendingReturned = TRUE;
          }
      }
 
    if (Irp->PendingReturned)
      {
+       DPRINT("Dispatching APC\n");
+       Thread = &Irp->Tail.Overlay.Thread->Tcb;
        KeInitializeApc(&Irp->Tail.Apc,
-                       &Irp->Tail.Overlay.Thread->Tcb,
+                       Thread,
                        0,
                        IopCompleteRequest,
                        NULL,
-                       NULL,
-                       0,
-                       Irp);
-       KeInsertQueueApc(&Irp->Tail.Apc,NULL,NULL,0);
+                       (PKNORMAL_ROUTINE)
+                       Irp->Overlay.AsynchronousParameters.UserApcRoutine,
+                       UserMode,
+                       (PVOID)
+                          Irp->Overlay.AsynchronousParameters.UserApcContext);
+       KeInsertQueueApc(&Irp->Tail.Apc,
+                        (PVOID)Irp,
+                        (PVOID)(ULONG)PriorityBoost,
+                        KernelMode);
+       DPRINT("Finished dispatching APC\n");
      }
    else
      {
+       DPRINT("Calling completion routine directly\n");
        IoSecondStageCompletion(Irp,PriorityBoost);
+       DPRINT("Finished completition routine\n");
      }
 }
+
+
+VOID
+STDCALL
+IoCompleteRequest (PIRP Irp, CCHAR PriorityBoost)
+{
+       IofCompleteRequest (
+               Irp,
+               PriorityBoost
+               );
+}
+
+
+/**********************************************************************
+ * NAME                                                        EXPORTED
+ *     IoIsOperationSynchronous@4
+ *
+ * DESCRIPTION
+ *     Check if the I/O operation associated with the given IRP
+ *     is synchronous.
+ *
+ * ARGUMENTS
+ *     Irp     Packet to check.
+ *
+ * RETURN VALUE
+ *     TRUE if Irp's operation is synchronous; otherwise FALSE.
+ */
+BOOLEAN
+STDCALL
+IoIsOperationSynchronous (
+       IN      PIRP    Irp
+       )
+{
+       ULONG           Flags = 0;
+       PFILE_OBJECT    FileObject = NULL;
+       
+       /*
+        * Check the associated FILE_OBJECT's
+        * flags first.
+        */
+       FileObject = Irp->Tail.Overlay.OriginalFileObject;
+       if (!(FO_SYNCHRONOUS_IO & FileObject->Flags))
+       {
+               /* Check IRP's flags. */
+               Flags = Irp->Flags;
+               if (!(  (IRP_SYNCHRONOUS_API | IRP_SYNCHRONOUS_PAGING_IO)
+                       & Flags
+                       ))
+               {
+                       return FALSE;
+               }
+       }
+       /*
+        * Check more IRP's flags.
+        */
+       Flags = Irp->Flags;
+       if (    !(IRP_MOUNT_COMPLETION & Flags)
+               || (IRP_SYNCHRONOUS_PAGING_IO & Flags)
+               )
+       {
+               return TRUE;
+       }
+       /*
+        * Otherwise, it is an
+        * asynchronous operation.
+        */
+       return FALSE;
+}
+
+
+/* EOF */