Added .Type and .Size attributes to the IRP object: so far nothing
[reactos.git] / reactos / ntoskrnl / io / irp.c
index b28ac88..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
@@ -39,7 +40,9 @@
 
 /* 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
@@ -48,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:
@@ -58,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:
@@ -73,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
@@ -81,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: 
@@ -101,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:
@@ -112,13 +132,20 @@ VOID IoInitializeIrp(PIRP Irp, USHORT PacketSize, CCHAR StackSize)
 {
    assert(Irp != NULL);
 
-   memset(Irp,0,PacketSize);
-   Irp->StackCount=StackSize;
-   Irp->CurrentLocation=StackSize;
-   Irp->Tail.Overlay.CurrentStackLocation=IoGetCurrentIrpStackLocation(Irp);
+   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
@@ -127,22 +154,33 @@ PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
  * RETURNS: A pointer to the stack location
  */
 {
-   DPRINT("IoGetCurrentIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n", 
-          Irp,
-          Irp->CurrentLocation,
-          Irp->StackCount);
+//   DPRINT("IoGetCurrentIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n", 
+//          Irp,
+//          Irp->CurrentLocation,
+//          Irp->StackCount);
 
-   return &Irp->Stack[Irp->CurrentLocation];
+   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
@@ -151,38 +189,56 @@ PIO_STACK_LOCATION IoGetNextIrpStackLocation(PIRP Irp)
  * RETURNS: A pointer to the stack location 
  */
 {
-   DPRINT("IoGetNextIrpStackLocation(Irp %x)\n",Irp);
+//   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 DeviceObject, 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
  */
 {
    NTSTATUS Status;
    PDRIVER_OBJECT DriverObject;
-   PIO_STACK_LOCATION param;
+   PIO_STACK_LOCATION Param;
    
-   DPRINT("IoCallDriver(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
+//   DPRINT("IoCallDriver(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
    
    DriverObject = DeviceObject->DriverObject;
-   param = IoGetNextIrpStackLocation(Irp);
+   Param = IoGetNextIrpStackLocation(Irp);
    
    Irp->Tail.Overlay.CurrentStackLocation--;
    Irp->CurrentLocation--;
    
-   DPRINT("DriverObject->MajorFunction[param->MajorFunction] %x\n",
-           DriverObject->MajorFunction[param->MajorFunction]);
-   Status = DriverObject->MajorFunction[param->MajorFunction](DeviceObject,
+//   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:
@@ -202,7 +258,8 @@ PIRP IoAllocateIrp(CCHAR StackSize, BOOLEAN ChargeQuota)
    
    if (ChargeQuota)
      {
-       Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));
+//     Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));
+       Irp = ExAllocatePool(NonPagedPool,IoSizeOfIrp(StackSize));
      }
    else
      { 
@@ -216,12 +273,18 @@ PIRP IoAllocateIrp(CCHAR StackSize, BOOLEAN ChargeQuota)
    
    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;
 }
 
-VOID IoSetCompletionRoutine(PIRP Irp,
+
+/**********************************************************************
+ * NAME                                                        INTERNAL
+ *     IoSetCompletionRoutine
+ */
+VOID
+IoSetCompletionRoutine (PIRP Irp,
                            PIO_COMPLETION_ROUTINE CompletionRoutine,
                            PVOID Context,
                            BOOLEAN InvokeOnSuccess,
@@ -252,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
@@ -268,9 +337,10 @@ 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++)
      {
@@ -293,19 +363,99 @@ VOID IoCompleteRequest(PIRP Irp, CCHAR PriorityBoost)
 
    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 */