[RDBSS][RXCE] Implement IRP cancellation
[reactos.git] / sdk / lib / drivers / rxce / rxce.c
index 424294b..9c106d4 100644 (file)
@@ -143,6 +143,7 @@ LIST_ENTRY RxRecurrentWorkItemsList;
 KDPC RxTimerDpc;
 KTIMER RxTimer;
 ULONG RxTimerTickCount;
 KDPC RxTimerDpc;
 KTIMER RxTimer;
 ULONG RxTimerTickCount;
+FAST_MUTEX RxContextPerFileSerializationMutex;
 #if DBG
 BOOLEAN DumpDispatchRoutine = TRUE;
 #else
 #if DBG
 BOOLEAN DumpDispatchRoutine = TRUE;
 #else
@@ -715,6 +716,66 @@ RxBootstrapWorkerThreadDispatcher(
     RxpWorkerThreadDispatcher(RxWorkQueue, NULL);
 }
 
     RxpWorkerThreadDispatcher(RxWorkQueue, NULL);
 }
 
+/*
+ * @implemented
+ */
+VOID
+RxCancelBlockingOperation(
+    IN OUT PRX_CONTEXT RxContext)
+{
+    PFOBX Fobx;
+    BOOLEAN PostRequest;
+    C_ASSERT(FIELD_OFFSET(RX_CONTEXT, IoStatusBlock.Status) == 100);
+
+    PAGED_CODE();
+
+    Fobx = (PFOBX)RxContext->pFobx;
+    PostRequest = FALSE;
+
+    /* Acquire the pipe mutex */
+    ExAcquireFastMutex(&RxContextPerFileSerializationMutex);
+
+    /* If that's a blocking pipe operation which is not the CCB one, then handle it */
+    if (BooleanFlagOn(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION) &&
+        RxContext->RxContextSerializationQLinks.Flink != NULL &&
+        RxContext != CONTAINING_RECORD(&Fobx->Specific.NamedPipe.ReadSerializationQueue, RX_CONTEXT, RxContextSerializationQLinks) &&
+        RxContext != CONTAINING_RECORD(&Fobx->Specific.NamedPipe.WriteSerializationQueue, RX_CONTEXT, RxContextSerializationQLinks))
+    {
+        /* Clear it! */
+        ClearFlag(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION);
+
+        /* Drop it off the list */
+        RemoveEntryList(&RxContext->RxContextSerializationQLinks);
+        RxContext->RxContextSerializationQLinks.Flink = NULL;
+        RxContext->RxContextSerializationQLinks.Blink = NULL;
+
+        /* Set we've been cancelled */
+        RxContext->IoStatusBlock.Status = STATUS_CANCELLED;
+
+        /*
+         * If it's async, we'll post completion, otherwise, we signal to waiters
+         * it's being cancelled
+         */
+        if (BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION))
+        {
+            PostRequest = TRUE;
+        }
+        else
+        {
+            RxSignalSynchronousWaiter(RxContext);
+        }
+    }
+
+    /* Done */
+    ExReleaseFastMutex(&RxContextPerFileSerializationMutex);
+
+    /* Post if async */
+    if (PostRequest)
+    {
+        RxFsdPostRequest(RxContext);
+    }
+}
+
 /*
  * @implemented
  */
 /*
  * @implemented
  */
@@ -7562,6 +7623,32 @@ RxRemoveNameNetFcb(
 #endif
 }
 
 #endif
 }
 
+/*
+ * @implemented
+ */
+VOID
+RxRemoveOperationFromBlockingQueue(
+    IN OUT PRX_CONTEXT RxContext)
+{
+    /* Acquire the pipe mutex */
+    ExAcquireFastMutex(&RxContextPerFileSerializationMutex);
+
+    /* Is that a blocking serial operation? */
+    if (BooleanFlagOn(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION))
+    {
+        /* Clear it! */
+        ClearFlag(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION);
+
+        /* Drop it off the list */
+        RemoveEntryList(&RxContext->RxContextSerializationQLinks);
+        RxContext->RxContextSerializationQLinks.Flink = NULL;
+        RxContext->RxContextSerializationQLinks.Blink = NULL;
+    }
+
+    /* Done */
+    ExReleaseFastMutex(&RxContextPerFileSerializationMutex);
+}
+
 /*
  * @implemented
  */
 /*
  * @implemented
  */