[RXCE]
[reactos.git] / reactos / sdk / lib / drivers / rxce / rxce.c
index d0009d3..42bed2b 100644 (file)
@@ -69,6 +69,24 @@ NTAPI
 RxWorkItemDispatcher(
     PVOID Context);
 
+PVOID
+NTAPI
+_RxAllocatePoolWithTag(
+    _In_ POOL_TYPE PoolType,
+    _In_ SIZE_T NumberOfBytes,
+    _In_ ULONG Tag);
+
+VOID
+NTAPI
+_RxFreePool(
+    _In_ PVOID Buffer);
+
+VOID
+NTAPI
+_RxFreePoolWithTag(
+    _In_ PVOID Buffer,
+    _In_ ULONG Tag);
+
 extern ULONG ReadAheadGranularity;
 
 volatile LONG RxNumberOfActiveFcbs = 0;
@@ -86,12 +104,14 @@ RX_DISPATCHER RxDispatcher;
 RX_WORK_QUEUE_DISPATCHER RxDispatcherWorkQueues;
 FAST_MUTEX RxLowIoPagingIoSyncMutex;
 BOOLEAN RxContinueFromAssert = TRUE;
+ULONG RxExplodePoolTags = 1;
 #if DBG
 BOOLEAN DumpDispatchRoutine = TRUE;
 #else
 BOOLEAN DumpDispatchRoutine = FALSE;
 #endif
 
+#if RDBSS_ASSERTS
 #ifdef ASSERT
 #undef ASSERT
 #endif
@@ -101,6 +121,18 @@ BOOLEAN DumpDispatchRoutine = FALSE;
     {                                             \
         RxAssert(#exp, __FILE__, __LINE__, NULL); \
     }
+#endif
+
+#if RX_POOL_WRAPPER
+#undef RxAllocatePool
+#undef RxAllocatePoolWithTag
+#undef RxFreePool
+
+#define RxAllocatePool(P, S) _RxAllocatePoolWithTag(P, S, 0)
+#define RxAllocatePoolWithTag _RxAllocatePoolWithTag
+#define RxFreePool _RxFreePool
+#define RxFreePoolWithTag _RxFreePoolWithTag
+#endif
 
 /* FUNCTIONS ****************************************************************/
 
@@ -225,7 +257,7 @@ RxAllocateFcbObject(
     /* Otherwise, allocate it */
     else
     {
-        Buffer = ExAllocatePoolWithTag(PoolType, NameSize + FcbSize + SrvOpenSize + FobxSize + NonPagedSize, RX_FCB_POOLTAG);
+        Buffer = RxAllocatePoolWithTag(PoolType, NameSize + FcbSize + SrvOpenSize + FobxSize + NonPagedSize, RX_FCB_POOLTAG);
         if (Buffer == NULL)
         {
             return NULL;
@@ -260,10 +292,10 @@ RxAllocateFcbObject(
         /* If we were not allocated from non paged, allocate the NON_PAGED_FCB now */
         if (PoolType != NonPagedPool)
         {
-            NonPagedFcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(NON_PAGED_FCB), RX_NONPAGEDFCB_POOLTAG);
+            NonPagedFcb = RxAllocatePoolWithTag(NonPagedPool, sizeof(NON_PAGED_FCB), RX_NONPAGEDFCB_POOLTAG);
             if (NonPagedFcb == NULL)
             {
-                ExFreePoolWithTag(Buffer, RX_FCB_POOLTAG);
+                RxFreePoolWithTag(Buffer, RX_FCB_POOLTAG);
                 return NULL;
             }
 
@@ -399,7 +431,7 @@ RxAllocateObject(
 
     /* Now, allocate the object */
     ObjectSize = ExtensionSize + StructSize + NameLength;
-    Object = ExAllocatePoolWithTag(NonPagedPool, ObjectSize, Tag);
+    Object = RxAllocatePoolWithTag(NonPagedPool, ObjectSize, Tag);
     if (Object == NULL)
     {
         return NULL;
@@ -731,7 +763,7 @@ RxConstructNetRoot(
     ASSERT(*LockHoldingState == LHS_ExclusiveLockHeld);
 
     /* Allocate the context */
-    Context = ExAllocatePoolWithTag(PagedPool, sizeof(MRX_CREATENETROOT_CONTEXT), RX_SRVCALL_POOLTAG);
+    Context = RxAllocatePoolWithTag(PagedPool, sizeof(MRX_CREATENETROOT_CONTEXT), RX_SRVCALL_POOLTAG);
     if (Context == NULL)
     {
         return STATUS_INSUFFICIENT_RESOURCES;
@@ -797,7 +829,7 @@ RxConstructNetRoot(
     RxTransitionVNetRoot(VirtualNetRoot, VRootCondition);
 
     /* Context is not longer needed */
-    ExFreePoolWithTag(Context, RX_SRVCALL_POOLTAG);
+    RxFreePoolWithTag(Context, RX_SRVCALL_POOLTAG);
 
     DPRINT("Status: %x\n", Status);
 
@@ -829,7 +861,7 @@ RxConstructSrvCall(
     ASSERT(*LockHoldingState == LHS_ExclusiveLockHeld);
 
     /* Allocate the context for mini-rdr */
-    Calldown = ExAllocatePoolWithTag(NonPagedPool, sizeof(MRX_SRVCALLDOWN_STRUCTURE), RX_SRVCALL_POOLTAG);
+    Calldown = RxAllocatePoolWithTag(NonPagedPool, sizeof(MRX_SRVCALLDOWN_STRUCTURE), RX_SRVCALL_POOLTAG);
     if (Calldown == NULL)
     {
         SrvCall->Context = NULL;
@@ -1893,7 +1925,7 @@ RxDispatchToWorkerThread(
     PRX_WORK_DISPATCH_ITEM DispatchItem;
 
     /* Allocate a bit of context */
-    DispatchItem = ExAllocatePoolWithTag(PagedPool, sizeof(RX_WORK_DISPATCH_ITEM), RX_WORKQ_POOLTAG);
+    DispatchItem = RxAllocatePoolWithTag(PagedPool, sizeof(RX_WORK_DISPATCH_ITEM), RX_WORKQ_POOLTAG);
     if (DispatchItem == NULL)
     {
         return STATUS_INSUFFICIENT_RESOURCES;
@@ -1909,7 +1941,7 @@ RxDispatchToWorkerThread(
     Status = RxInsertWorkQueueItem(pMRxDeviceObject, WorkQueueType, DispatchItem);
     if (!NT_SUCCESS(Status))
     {
-        ExFreePoolWithTag(DispatchItem, RX_WORKQ_POOLTAG);
+        RxFreePoolWithTag(DispatchItem, RX_WORKQ_POOLTAG);
         DPRINT1("RxInsertWorkQueueItem failed! Queue: %ld, Routine: %p, Context: %p, Status: %lx\n", WorkQueueType, Routine, pContext, Status);
     }
 
@@ -2188,7 +2220,7 @@ RxFinalizeNetFcb(
                 Entry = ThisFcb->BufferedLocks.List;
                 ThisFcb->BufferedLocks.List = Entry->Next;
 
-                ExFreePool(Entry);
+                RxFreePool(Entry);
             }
         }
 
@@ -2221,7 +2253,7 @@ RxFinalizeNetFcb(
     /* Now, release everything */
     if (ThisFcb->pBufferingStateChangeCompletedEvent != NULL)
     {
-        ExFreePool(ThisFcb->pBufferingStateChangeCompletedEvent);
+        RxFreePool(ThisFcb->pBufferingStateChangeCompletedEvent);
     }
 
     if (ThisFcb->MRxDispatch != NULL)
@@ -2899,7 +2931,7 @@ RxFinishFcbInitialization(
     {
         /* If our FCB newly points to a file, initiliaz everything related */
         if (FileType == RDBSS_NTC_STORAGE_TYPE_FILE &&
-            !OldType != RDBSS_NTC_STORAGE_TYPE_FILE)
+            OldType != RDBSS_NTC_STORAGE_TYPE_FILE)
         {
             RxInitializeLowIoPerFcbInfo(&((PFCB)Fcb)->Specific.Fcb.LowIoPerFcbInfo);
             FsRtlInitializeFileLock(&((PFCB)Fcb)->Specific.Fcb.FileLock, &RxLockOperationCompletion,
@@ -2965,7 +2997,7 @@ RxFinishSrvCallConstruction(
 
     RxAcquirePrefixTableLockExclusive(PrefixTable, TRUE);
     RxTransitionSrvCall(SrvCall, Condition);
-    ExFreePoolWithTag(Calldown, RX_SRVCALL_POOLTAG);
+    RxFreePoolWithTag(Calldown, RX_SRVCALL_POOLTAG);
 
     /* If async, finish it here, otherwise, caller has already finished the stuff */
     if (BooleanFlagOn(Context->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION))
@@ -2994,7 +3026,7 @@ RxFinishSrvCallConstruction(
             {
                 if (Context->Info.Buffer != NULL)
                 {
-                    ExFreePool(Context->Info.Buffer);
+                    RxFreePool(Context->Info.Buffer);
                     Context->Info.Buffer = NULL;
                 }
             }
@@ -3385,7 +3417,7 @@ RxInitializeLowIoContext(
     PAGED_CODE();
 
     RxContext = CONTAINING_RECORD(LowIoContext, RX_CONTEXT, LowIoContext);
-    ASSERT(LowIoContext = &RxContext->LowIoContext);
+    ASSERT(LowIoContext == &RxContext->LowIoContext);
 
     Stack = RxContext->CurrentIrpSp;
 
@@ -4367,12 +4399,25 @@ RxpDereferenceAndFinalizeNetFcb(
     return Freed;
 }
 
+/*
+ * @implemented
+ */
 LONG
 RxpDereferenceNetFcb(
    PFCB Fcb)
 {
-    UNIMPLEMENTED;
-    return 0;
+    LONG NewCount;
+
+    PAGED_CODE();
+
+    ASSERT(NodeTypeIsFcb(Fcb));
+
+    NewCount = InterlockedDecrement((volatile long *)&Fcb->NodeReferenceCount);
+    ASSERT(NewCount >= 0);
+
+    PRINT_REF_COUNT(NETFCB, NewCount);
+
+    return NewCount;
 }
 
 /*
@@ -4491,12 +4536,24 @@ RxPrefixTableLookupName(
     return Container;
 }
 
+/*
+ * @implemented
+ */
 LONG
 RxpReferenceNetFcb(
    PFCB Fcb)
 {
-    UNIMPLEMENTED;
-    return 0;
+    LONG NewCount;
+
+    PAGED_CODE();
+
+    ASSERT(NodeTypeIsFcb(Fcb));
+
+    NewCount = InterlockedIncrement((volatile long *)&Fcb->NodeReferenceCount);
+
+    PRINT_REF_COUNT(NETFCB, Fcb->NodeReferenceCount);
+
+    return NewCount;
 }
 
 /*
@@ -4554,8 +4611,15 @@ RxpTrackDereference(
     _In_ ULONG Line,
     _In_ PVOID Instance)
 {
+    PAGED_CODE();
+
+    if (!BooleanFlagOn(RdbssReferenceTracingValue, TraceType))
+    {
+        return TRUE;
+    }
+
     UNIMPLEMENTED;
-    return FALSE;
+    return TRUE;
 }
 
 VOID
@@ -4565,6 +4629,11 @@ RxpTrackReference(
     _In_ ULONG Line,
     _In_ PVOID Instance)
 {
+    if (!BooleanFlagOn(RdbssReferenceTracingValue, TraceType))
+    {
+        return;
+    }
+
     UNIMPLEMENTED;
 }
 
@@ -4617,7 +4686,7 @@ RxpWorkerThreadDispatcher(
 
     /* Reference ourselves */
     CurrentThread = PsGetCurrentThread();
-    Status = ObReferenceObjectByPointer(CurrentThread, THREAD_ALL_ACCESS, PsThreadType, KernelMode);
+    Status = ObReferenceObjectByPointer(CurrentThread, THREAD_ALL_ACCESS, *PsThreadType, KernelMode);
     ASSERT(NT_SUCCESS(Status));
 
     /* Infinite loop for worker */
@@ -4659,7 +4728,7 @@ RxpWorkerThreadDispatcher(
             {
                 PKEVENT TearDownEvent;
 
-                TearDownEvent = InterlockedExchangePointer((volatile PVOID)&DeviceObject->DispatcherContext.pTearDownEvent, NULL);
+                TearDownEvent = InterlockedExchangePointer((void * volatile*)&DeviceObject->DispatcherContext.pTearDownEvent, NULL);
                 if (TearDownEvent != NULL)
                 {
                     KeSetEvent(TearDownEvent, IO_NO_INCREMENT, FALSE);
@@ -4857,7 +4926,7 @@ RxSpinUpRequestsDispatcher(
     NTSTATUS Status;
     PRX_DISPATCHER RxDispatcher;
 
-    Status = ObReferenceObjectByPointer(PsGetCurrentThread(), THREAD_ALL_ACCESS, PsThreadType, KernelMode);
+    Status = ObReferenceObjectByPointer(PsGetCurrentThread(), THREAD_ALL_ACCESS, *PsThreadType, KernelMode);
     if (!NT_SUCCESS(Status))
     {
         PsTerminateSystemThread(STATUS_SUCCESS);
@@ -5372,17 +5441,17 @@ RxUninitializeVNetRootParameters(
     /* Only free what could have been allocated */
     if (UserName != NULL)
     {
-        ExFreePool(UserName);
+        RxFreePool(UserName);
     }
 
     if (UserDomainName != NULL)
     {
-        ExFreePool(UserDomainName);
+        RxFreePool(UserDomainName);
     }
 
     if (Password != NULL)
     {
-        ExFreePool(Password);
+        RxFreePool(Password);
     }
 
     /* And remove the possibly set CSC agent flag */
@@ -5436,11 +5505,112 @@ RxUpdateCondition(
     }
 }
 
+/*
+ * @implemented
+ */
 VOID
 RxVerifyOperationIsLegal(
     IN PRX_CONTEXT RxContext)
 {
-    UNIMPLEMENTED;
+    PIRP Irp;
+    PMRX_FOBX Fobx;
+    BOOLEAN FlagSet;
+    PFILE_OBJECT FileObject;
+    PIO_STACK_LOCATION Stack;
+
+    PAGED_CODE();
+
+    Irp = RxContext->CurrentIrp;
+    Stack = RxContext->CurrentIrpSp;
+    FileObject = Stack->FileObject;
+
+    /* We'll only check stuff on opened files, this requires an IRP and a FO */
+    if (Irp == NULL || FileObject == NULL)
+    {
+        return;
+    }
+
+    /* Set no exception for breakpoint - remember whether is was already set */
+    FlagSet = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT);
+    SetFlag(RxContext->Flags, RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT);
+
+    /* If we have a CCB, perform a few checks on opened file */
+    Fobx = RxContext->pFobx;
+    if (Fobx != NULL)
+    {
+        PMRX_SRV_OPEN SrvOpen;
+
+        SrvOpen = Fobx->pSrvOpen;
+        if (SrvOpen != NULL)
+        {
+            UCHAR MajorFunction;
+
+            MajorFunction = RxContext->MajorFunction;
+            /* Only allow closing/cleanup operations on renamed files */
+            if (MajorFunction != IRP_MJ_CLEANUP && MajorFunction != IRP_MJ_CLOSE &&
+                BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_FILE_RENAMED))
+            {
+                RxContext->IoStatusBlock.Status = STATUS_FILE_RENAMED;
+                ExRaiseStatus(STATUS_FILE_RENAMED);
+            }
+
+            /* Only allow closing/cleanup operations on deleted files */
+            if (MajorFunction != IRP_MJ_CLEANUP && MajorFunction != IRP_MJ_CLOSE &&
+                BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_FILE_DELETED))
+            {
+                RxContext->IoStatusBlock.Status = STATUS_FILE_DELETED;
+                ExRaiseStatus(STATUS_FILE_DELETED);
+            }
+        }
+    }
+
+    /* If that's an open operation */
+    if (RxContext->MajorFunction == IRP_MJ_CREATE)
+    {
+        PFILE_OBJECT RelatedFileObject;
+
+        /* We won't allow an open operation relative to a file to be deleted */
+        RelatedFileObject = FileObject->RelatedFileObject;
+        if (RelatedFileObject != NULL)
+        {
+            PMRX_FCB Fcb;
+
+            Fcb = RelatedFileObject->FsContext;
+            if (BooleanFlagOn(Fcb->FcbState, FCB_STATE_DELETE_ON_CLOSE))
+            {
+                RxContext->IoStatusBlock.Status = STATUS_DELETE_PENDING;
+                ExRaiseStatus(STATUS_DELETE_PENDING);
+            }
+        }
+    }
+
+    /* If cleanup was completed */
+    if (BooleanFlagOn(FileObject->Flags, FO_CLEANUP_COMPLETE))
+    {
+        if (!BooleanFlagOn(Irp->Flags, IRP_PAGING_IO))
+        {
+            UCHAR MajorFunction;
+
+            /* We only allow a subset of operations (see FatVerifyOperationIsLegal for instance) */
+            MajorFunction = Stack->MajorFunction;
+            if (MajorFunction != IRP_MJ_CLOSE && MajorFunction != IRP_MJ_QUERY_INFORMATION &&
+                MajorFunction != IRP_MJ_SET_INFORMATION)
+            {
+                if ((MajorFunction != IRP_MJ_READ && MajorFunction != IRP_MJ_WRITE) ||
+                    !BooleanFlagOn(Stack->MinorFunction, IRP_MN_COMPLETE))
+                {
+                    RxContext->IoStatusBlock.Status = STATUS_FILE_CLOSED;
+                    ExRaiseStatus(STATUS_FILE_CLOSED);
+                }
+            }
+        }
+    }
+
+    /* If flag was already set, don't clear it */
+    if (!FlagSet)
+    {
+        ClearFlag(RxContext->Flags, RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT);
+    }
 }
 
 /*
@@ -5513,7 +5683,43 @@ RxWorkItemDispatcher(
 
     DispatchItem->DispatchRoutine(DispatchItem->DispatchRoutineParameter);
 
-    ExFreePoolWithTag(DispatchItem, RX_WORKQ_POOLTAG);
+    RxFreePoolWithTag(DispatchItem, RX_WORKQ_POOLTAG);
+}
+
+/*
+ * @implemented
+ */
+PVOID
+NTAPI
+_RxAllocatePoolWithTag(
+    _In_ POOL_TYPE PoolType,
+    _In_ SIZE_T NumberOfBytes,
+    _In_ ULONG Tag)
+{
+    return ExAllocatePoolWithTagPriority(PoolType, NumberOfBytes, Tag, LowPoolPriority);
+}
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+_RxFreePool(
+    _In_ PVOID Buffer)
+{
+    ExFreePoolWithTag(Buffer, 0);
+}
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+_RxFreePoolWithTag(
+    _In_ PVOID Buffer,
+    _In_ ULONG Tag)
+{
+    ExFreePoolWithTag(Buffer, Tag);
 }
 
 NTSTATUS