Added .Type and .Size attributes to the IRP object: so far nothing
[reactos.git] / reactos / ntoskrnl / io / irp.c
index e7108dc..ff02e89 100644 (file)
-/*\r
- * COPYRIGHT:       See COPYING in the top level directory\r
- * PROJECT:         ReactOS kernel\r
- * FILE:            ntoskrnl/io/irp.c\r
- * PURPOSE:         Handle IRPs\r
- * PROGRAMMER:      David Welch (welch@mcmail.com)\r
- * UPDATE HISTORY: \r
- *                  24/05/98: Created \r
- */\r
-\r
-/* NOTES *******************************************************************\r
- * \r
- * Layout of an IRP \r
- * \r
- *             ################\r
- *             #    Headers   #\r
- *             ################\r
- *             #              #\r
- *             #   Variable   #\r
- *             # length list  #\r
- *             # of io stack  #\r
- *             #  locations   #\r
- *             #              #\r
- *             ################\r
- * \r
- * \r
- * \r
- */\r
-\r
-/* INCLUDES ****************************************************************/\r
-\r
-#include <internal/string.h>\r
-#include <internal/io.h>\r
-#include <ddk/ntddk.h>\r
-\r
-//#define NDEBUG\r
-#include <internal/debug.h>\r
-\r
-/* FUNCTIONS ****************************************************************/\r
-\r
-PDEVICE_OBJECT IoGetDeviceToVerify(PETHREAD Thread)\r
-/*\r
- * FUNCTION: Returns a pointer to the device, representing a removable-media\r
- * device, that is the target of the given thread's I/O request\r
- */\r
-{\r
-   UNIMPLEMENTED;\r
-}\r
-\r
-VOID IoFreeIrp(PIRP Irp)\r
-/*\r
- * FUNCTION: Releases a caller allocated irp\r
- * ARGUMENTS:\r
- *      Irp = Irp to free\r
- */\r
-{\r
-   ExFreePool(Irp);\r
-}\r
-\r
-PIRP IoMakeAssociatedIrp(PIRP Irp, CCHAR StackSize)\r
-/*\r
- * FUNCTION: Allocates and initializes an irp to associated with a master irp\r
- * ARGUMENTS:\r
- *       Irp = Master irp\r
- *       StackSize = Number of stack locations to be allocated in the irp\r
- * RETURNS: The irp allocated\r
- */\r
-{\r
-   PIRP AssocIrp;\r
-   \r
-   AssocIrp = IoAllocateIrp(StackSize,FALSE);\r
-   UNIMPLEMENTED;\r
-}\r
-\r
-VOID IoMarkIrpPending(PIRP Irp)\r
-/*\r
- * FUNCTION: Marks the specified irp, indicating further processing will\r
- * be required by other driver routines\r
- * ARGUMENTS:\r
- *      Irp = Irp to mark\r
- */\r
-{\r
-   DPRINT("IoGetCurrentIrpStackLocation(Irp) %x\n",\r
-         IoGetCurrentIrpStackLocation(Irp));\r
-   IoGetCurrentIrpStackLocation(Irp)->Control |= SL_PENDING_RETURNED;\r
-   Irp->Tail.Overlay.Thread = KeGetCurrentThread();\r
-   DPRINT("IoGetCurrentIrpStackLocation(Irp)->Control %x\n",\r
-         IoGetCurrentIrpStackLocation(Irp)->Control);\r
-   DPRINT("SL_PENDING_RETURNED %x\n",SL_PENDING_RETURNED);\r
-}\r
-\r
-USHORT IoSizeOfIrp(CCHAR StackSize)\r
-/*\r
- * FUNCTION:  Determines the size of an IRP\r
- * ARGUMENTS: \r
- *           StackSize = number of stack locations in the IRP\r
- * RETURNS: The size of the IRP in bytes \r
- */\r
-{\r
-   return(sizeof(IRP)+((StackSize-1)*sizeof(IO_STACK_LOCATION)));\r
-}\r
-\r
-VOID IoInitializeIrp(PIRP Irp, USHORT PacketSize, CCHAR StackSize)\r
-/*\r
- * FUNCTION: Initalizes an irp allocated by the caller\r
- * ARGUMENTS:\r
- *          Irp = IRP to initalize\r
- *          PacketSize = Size in bytes of the IRP\r
- *          StackSize = Number of stack locations in the IRP\r
- */\r
-{\r
-   assert(Irp!=NULL);\r
-   memset(Irp,0,PacketSize);\r
-   Irp->StackCount=StackSize;\r
-   Irp->CurrentLocation=StackSize;\r
-   Irp->Tail.Overlay.CurrentStackLocation=IoGetCurrentIrpStackLocation(Irp);\r
-}\r
-\r
-PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)\r
-/*\r
- * FUNCTION: Gets a pointer to the callers location in the I/O stack in\r
- * the given IRP\r
- * ARGUMENTS:\r
- *         Irp = Points to the IRP\r
- * RETURNS: A pointer to the stack location\r
- */\r
-{\r
-   DPRINT("IoGetCurrentIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n", \r
-          Irp,\r
-          Irp->CurrentLocation,\r
-          Irp->StackCount);\r
-\r
-   return &Irp->Stack[Irp->CurrentLocation];\r
-}\r
-\r
-\r
-VOID IoSetNextIrpStackLocation(PIRP Irp)\r
-{\r
-   Irp->CurrentLocation--;\r
-   Irp->Tail.Overlay.CurrentStackLocation--;\r
-}\r
-\r
-PIO_STACK_LOCATION IoGetNextIrpStackLocation(PIRP Irp)\r
-/*\r
- * FUNCTION: Gives a higher level driver access to the next lower driver's \r
- * I/O stack location\r
- * ARGUMENTS: \r
- *           Irp = points to the irp\r
- * RETURNS: A pointer to the stack location \r
- */\r
-{\r
-   DPRINT("IoGetNextIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n", \r
-          Irp,\r
-          Irp->CurrentLocation,\r
-          Irp->StackCount);\r
-\r
-   assert(Irp!=NULL);\r
-   DPRINT("Irp %x Irp->StackPtr %x\n",Irp,Irp->CurrentLocation);\r
-   return(&Irp->Stack[Irp->CurrentLocation-1]);\r
-}\r
-\r
-NTSTATUS IoCallDriver(PDEVICE_OBJECT DevObject, PIRP irp)\r
-/*\r
- * FUNCTION: Sends an IRP to the next lower driver\r
- */\r
-{\r
-   NTSTATUS Status;\r
-   PDRIVER_OBJECT drv = DevObject->DriverObject;\r
-   IO_STACK_LOCATION* param = IoGetNextIrpStackLocation(irp);\r
-\r
-   DPRINT("Deviceobject %x\n",DevObject);\r
-   DPRINT("Irp %x\n",irp);\r
-\r
-   irp->Tail.Overlay.CurrentStackLocation--;\r
-   irp->CurrentLocation--;\r
-\r
-   DPRINT("Io stack address %x\n",param);\r
-   DPRINT("Function %d Routine %x\n",param->MajorFunction,\r
-         drv->MajorFunction[param->MajorFunction]);\r
-\r
-   Status = drv->MajorFunction[param->MajorFunction](DevObject,irp);\r
-   return Status;\r
-}\r
-\r
-PIRP IoAllocateIrp(CCHAR StackSize, BOOLEAN ChargeQuota)\r
-/*\r
- * FUNCTION: Allocates an IRP\r
- * ARGUMENTS:\r
- *          StackSize = the size of the stack required for the irp\r
- *          ChargeQuota = Charge allocation to current threads quota\r
- * RETURNS: Irp allocated\r
- */\r
-{\r
-   PIRP Irp;\r
-   \r
-   DPRINT("IoAllocateIrp(StackSize %d ChargeQuota %d)\n",StackSize,\r
-         ChargeQuota);\r
-   if (ChargeQuota)\r
-     {\r
-       Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));\r
-     }\r
-   else\r
-     { \r
-       Irp = ExAllocatePool(NonPagedPool,IoSizeOfIrp(StackSize));\r
-     }\r
-      \r
-   if (Irp==NULL)\r
-     {\r
-       return(NULL);\r
-     }\r
-   \r
-   Irp->StackCount=StackSize;\r
-   Irp->CurrentLocation=StackSize;\r
-\r
-   DPRINT("Irp %x Irp->StackPtr %d\n",Irp,Irp->CurrentLocation);\r
-   return(Irp);\r
-}\r
-\r
-VOID IoSetCompletionRoutine(PIRP Irp,\r
-                           PIO_COMPLETION_ROUTINE CompletionRoutine,\r
-                           PVOID Context,\r
-                           BOOLEAN InvokeOnSuccess,\r
-                           BOOLEAN InvokeOnError,\r
-                           BOOLEAN InvokeOnCancel)\r
-{\r
-   IO_STACK_LOCATION* param = IoGetNextIrpStackLocation(Irp);\r
-   \r
-   param->CompletionRoutine=CompletionRoutine;\r
-   param->CompletionContext=Context;\r
-   if (InvokeOnSuccess)\r
-     {\r
-       param->Control = param->Control | SL_INVOKE_ON_SUCCESS;\r
-     }\r
-   if (InvokeOnError)\r
-     {\r
-       param->Control = param->Control | SL_INVOKE_ON_ERROR;\r
-     }\r
-   if (InvokeOnCancel)\r
-     {\r
-       param->Control = param->Control | SL_INVOKE_ON_CANCEL;\r
-     }\r
-}\r
-\r
-VOID IopCompleteRequest(struct _KAPC* Apc,\r
-                       PKNORMAL_ROUTINE* NormalRoutine,\r
-                       PVOID* NormalContext,\r
-                       PVOID* SystemArgument1,\r
-                       PVOID* SystemArgument2)\r
-{\r
-   IoSecondStageCompletion((PIRP)(*NormalContext),\r
-                           IO_NO_INCREMENT);\r
-}\r
-\r
-VOID IoCompleteRequest(PIRP Irp, CCHAR PriorityBoost)\r
-/*\r
- * FUNCTION: Indicates the caller has finished all processing for a given\r
- * I/O request and is returning the given IRP to the I/O manager\r
- * ARGUMENTS:\r
- *         Irp = Irp to be cancelled\r
- *         PriorityBoost = Increment by which to boost the priority of the\r
- *                         thread making the request\r
- */\r
-{\r
-   unsigned int i;\r
-   NTSTATUS Status;\r
-   \r
-   DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d)\n",\r
-                Irp,PriorityBoost);\r
-\r
-   for (i=0;i<Irp->StackCount;i++)\r
-     {\r
-       DPRINT("&Irp->Stack[i] %x\n",&Irp->Stack[i]);\r
-       if (Irp->Stack[i].CompletionRoutine!=NULL)\r
-         {\r
-            Status = Irp->Stack[i].CompletionRoutine(\r
-                                            Irp->Stack[i].DeviceObject,\r
-                                            Irp,\r
-                                            Irp->Stack[i].CompletionContext);\r
-            if (Status == STATUS_MORE_PROCESSING_REQUIRED)\r
-              {\r
-                 return;\r
-              }\r
-         }\r
-       DPRINT("Irp->Stack[i].Control %x\n",Irp->Stack[i].Control);\r
-       if (Irp->Stack[i].Control & SL_PENDING_RETURNED)\r
-         {\r
-            DPRINT("Setting PendingReturned flag\n");\r
-            Irp->PendingReturned = TRUE;\r
-         }\r
-     }\r
-\r
-   if (Irp->PendingReturned)\r
-     {\r
-       KeInitializeApc(&Irp->Tail.Apc,\r
-                       &Irp->Tail.Overlay.Thread->Tcb,\r
-                       0,\r
-                       IopCompleteRequest,\r
-                       NULL,\r
-                       NULL,\r
-                       0,\r
-                       Irp);\r
-       KeInsertQueueApc(&Irp->Tail.Apc,NULL,NULL,0);\r
-     }\r
-   else\r
-     {\r
-       IoSecondStageCompletion(Irp,PriorityBoost);\r
-     }\r
-}\r
->>>>>>> 1.7\r
+/* $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
+ * PURPOSE:         Handle IRPs
+ * PROGRAMMER:      David Welch (welch@mcmail.com)
+ * UPDATE HISTORY: 
+ *                  24/05/98: Created 
+ */
+
+/* NOTES *******************************************************************
+ * 
+ * Layout of an IRP 
+ * 
+ *             ################
+ *             #    Headers   #
+ *             ################
+ *             #              #
+ *             #   Variable   #
+ *             # length list  #
+ *             # of io stack  #
+ *             #  locations   #
+ *             #              #
+ *             ################
+ * 
+ * 
+ * 
+ */
+
+/* INCLUDES ****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <string.h>
+#include <internal/string.h>
+#include <internal/io.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ****************************************************************/
+
+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
+ */
+{
+   UNIMPLEMENTED;
+}
+
+
+VOID
+STDCALL
+IoFreeIrp (PIRP Irp)
+/*
+ * FUNCTION: Releases a caller allocated irp
+ * ARGUMENTS:
+ *      Irp = Irp to free
+ */
+{
+   ExFreePool(Irp);
+}
+
+
+PIRP
+STDCALL
+IoMakeAssociatedIrp (PIRP Irp, CCHAR StackSize)
+/*
+ * FUNCTION: Allocates and initializes an irp to associated with a master irp
+ * ARGUMENTS:
+ *       Irp = Master irp
+ *       StackSize = Number of stack locations to be allocated in the irp
+ * RETURNS: The irp allocated
+ */
+{
+   PIRP AssocIrp;
+   
+   AssocIrp = IoAllocateIrp(StackSize,FALSE);
+   UNIMPLEMENTED;
+}
+
+
+/**********************************************************************
+ * NAME                                                        INTERNAL
+ *     IoMarkIrpPending
+ */
+VOID
+IoMarkIrpPending (PIRP Irp)
+/*
+ * FUNCTION: Marks the specified irp, indicating further processing will
+ * be required by other driver routines
+ * ARGUMENTS:
+ *      Irp = Irp to mark
+ */
+{
+//   DPRINT("IoGetCurrentIrpStackLocation(Irp) %x\n",
+//       IoGetCurrentIrpStackLocation(Irp));
+   IoGetCurrentIrpStackLocation(Irp)->Control |= SL_PENDING_RETURNED;
+}
+
+
+/**********************************************************************
+ * NAME                                                        INTERNAL
+ *     IoSizeOfIrp
+ */
+USHORT
+IoSizeOfIrp (CCHAR StackSize)
+/*
+ * FUNCTION:  Determines the size of an IRP
+ * ARGUMENTS: 
+ *           StackSize = number of stack locations in the IRP
+ * RETURNS: The size of the IRP in bytes 
+ */
+{
+   return(sizeof(IRP)+((StackSize-1)*sizeof(IO_STACK_LOCATION)));
+}
+
+
+VOID
+STDCALL
+IoInitializeIrp (PIRP Irp, USHORT PacketSize, CCHAR StackSize)
+/*
+ * FUNCTION: Initalizes an irp allocated by the caller
+ * ARGUMENTS:
+ *          Irp = IRP to initalize
+ *          PacketSize = Size in bytes of the IRP
+ *          StackSize = Number of stack locations in the IRP
+ */
+{
+   assert(Irp != NULL);
+
+   memset(Irp, 0, PacketSize);
+   Irp->Size = PacketSize;
+   Irp->StackCount = StackSize;
+   Irp->CurrentLocation = StackSize;
+   Irp->Tail.Overlay.CurrentStackLocation = IoGetCurrentIrpStackLocation(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
+ * ARGUMENTS:
+ *         Irp = Points to the IRP
+ * RETURNS: A pointer to the stack location
+ */
+{
+//   DPRINT("IoGetCurrentIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n", 
+//          Irp,
+//          Irp->CurrentLocation,
+//          Irp->StackCount);
+
+   return(&Irp->Stack[(ULONG)Irp->CurrentLocation]);
+}
+
+
+/**********************************************************************
+ * NAME                                                        INTERNAL
+ *     IoSetNextIrpStackLocation
+ */
+VOID
+IoSetNextIrpStackLocation (PIRP Irp)
+{
+   Irp->CurrentLocation--;
+   Irp->Tail.Overlay.CurrentStackLocation--;
+}
+
+
+/**********************************************************************
+ * 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
+ * ARGUMENTS: 
+ *           Irp = points to the 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);
+   return(&Irp->Stack[Irp->CurrentLocation-1]);
+}
+
+
+NTSTATUS
+FASTCALL
+IofCallDriver (PDEVICE_OBJECT DeviceObject, PIRP Irp)
+/*
+  * FUNCTION: Sends an IRP to the next lower driver
+ */
+{
+   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;
+}
+
+
+NTSTATUS
+STDCALL
+IoCallDriver (PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+       return IofCallDriver (
+                       DeviceObject,
+                       Irp
+                       );
+}
+
+
+PIRP
+STDCALL
+IoAllocateIrp (CCHAR StackSize, BOOLEAN ChargeQuota)
+/*
+ * FUNCTION: Allocates an IRP
+ * ARGUMENTS:
+ *          StackSize = the size of the stack required for the irp
+ *          ChargeQuota = Charge allocation to current threads quota
+ * RETURNS: Irp allocated
+ */
+{
+   PIRP Irp;
+
+#if 0
+   DbgPrint("IoAllocateIrp(StackSize %d ChargeQuota %d)\n",
+          StackSize,
+         ChargeQuota);
+   KeDumpStackFrames(0,8);
+#endif
+   
+   if (ChargeQuota)
+     {
+//     Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));
+       Irp = ExAllocatePool(NonPagedPool,IoSizeOfIrp(StackSize));
+     }
+   else
+     { 
+       Irp = ExAllocatePool(NonPagedPool,IoSizeOfIrp(StackSize));
+     }
+      
+   if (Irp==NULL)
+     {
+       return(NULL);
+     }
+   
+   IoInitializeIrp(Irp, IoSizeOfIrp(StackSize), StackSize);
+
+//   DPRINT("Irp %x Irp->StackPtr %d\n", Irp, Irp->CurrentLocation);
+
+   return Irp;
+}
+
+
+/**********************************************************************
+ * NAME                                                        INTERNAL
+ *     IoSetCompletionRoutine
+ */
+VOID
+IoSetCompletionRoutine (PIRP Irp,
+                           PIO_COMPLETION_ROUTINE CompletionRoutine,
+                           PVOID Context,
+                           BOOLEAN InvokeOnSuccess,
+                           BOOLEAN InvokeOnError,
+                           BOOLEAN InvokeOnCancel)
+{
+   IO_STACK_LOCATION* param = IoGetNextIrpStackLocation(Irp);
+   
+   param->CompletionRoutine=CompletionRoutine;
+   param->CompletionContext=Context;
+   if (InvokeOnSuccess)
+     {
+       param->Control = param->Control | SL_INVOKE_ON_SUCCESS;
+     }
+   if (InvokeOnError)
+     {
+       param->Control = param->Control | SL_INVOKE_ON_ERROR;
+     }
+   if (InvokeOnCancel)
+     {
+       param->Control = param->Control | SL_INVOKE_ON_CANCEL;
+     }
+}
+
+VOID IopCompleteRequest(struct _KAPC* Apc,
+                       PKNORMAL_ROUTINE* NormalRoutine,
+                       PVOID* NormalContext,
+                       PVOID* SystemArgument1,
+                       PVOID* SystemArgument2)
+{
+   DPRINT("IopCompleteRequest(Apc %x, SystemArgument1 %x, "
+         "(*SystemArgument1) %x\n", Apc, SystemArgument1,
+         *SystemArgument1);
+   IoSecondStageCompletion((PIRP)(*SystemArgument1),
+                           (KPRIORITY)(*SystemArgument2));
+}
+
+
+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
+ * ARGUMENTS:
+ *         Irp = Irp to be cancelled
+ *         PriorityBoost = Increment by which to boost the priority of the
+ *                         thread making the request
+ */
+{
+   unsigned int i;
+   NTSTATUS Status;
+   PKTHREAD Thread;
+   
+   DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n",
+          Irp,PriorityBoost, Irp->UserEvent, PsGetCurrentThread());
+
+   for (i=0;i<Irp->StackCount;i++)
+     {
+       if (Irp->Stack[i].CompletionRoutine != NULL)
+         {
+            Status = Irp->Stack[i].CompletionRoutine(
+                                            Irp->Stack[i].DeviceObject,
+                                            Irp,
+                                            Irp->Stack[i].CompletionContext);
+            if (Status == STATUS_MORE_PROCESSING_REQUIRED)
+              {
+                 return;
+              }
+         }
+       if (Irp->Stack[i].Control & SL_PENDING_RETURNED)
+         {
+            Irp->PendingReturned = TRUE;
+         }
+     }
+
+   if (Irp->PendingReturned)
+     {
+       DPRINT("Dispatching APC\n");
+       Thread = &Irp->Tail.Overlay.Thread->Tcb;
+       KeInitializeApc(&Irp->Tail.Apc,
+                       Thread,
+                       0,
+                       IopCompleteRequest,
+                       NULL,
+                       (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 */