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;
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
{ \
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 ****************************************************************/
/* 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;
/* 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;
}
/* Now, allocate the object */
ObjectSize = ExtensionSize + StructSize + NameLength;
- Object = ExAllocatePoolWithTag(NonPagedPool, ObjectSize, Tag);
+ Object = RxAllocatePoolWithTag(NonPagedPool, ObjectSize, Tag);
if (Object == NULL)
{
return NULL;
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;
RxTransitionVNetRoot(VirtualNetRoot, VRootCondition);
/* Context is not longer needed */
- ExFreePoolWithTag(Context, RX_SRVCALL_POOLTAG);
+ RxFreePoolWithTag(Context, RX_SRVCALL_POOLTAG);
DPRINT("Status: %x\n", Status);
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;
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;
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);
}
Entry = ThisFcb->BufferedLocks.List;
ThisFcb->BufferedLocks.List = Entry->Next;
- ExFreePool(Entry);
+ RxFreePool(Entry);
}
}
/* Now, release everything */
if (ThisFcb->pBufferingStateChangeCompletedEvent != NULL)
{
- ExFreePool(ThisFcb->pBufferingStateChangeCompletedEvent);
+ RxFreePool(ThisFcb->pBufferingStateChangeCompletedEvent);
}
if (ThisFcb->MRxDispatch != NULL)
{
/* 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,
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))
{
if (Context->Info.Buffer != NULL)
{
- ExFreePool(Context->Info.Buffer);
+ RxFreePool(Context->Info.Buffer);
Context->Info.Buffer = NULL;
}
}
PAGED_CODE();
RxContext = CONTAINING_RECORD(LowIoContext, RX_CONTEXT, LowIoContext);
- ASSERT(LowIoContext = &RxContext->LowIoContext);
+ ASSERT(LowIoContext == &RxContext->LowIoContext);
Stack = RxContext->CurrentIrpSp;
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;
}
/*
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;
}
/*
_In_ ULONG Line,
_In_ PVOID Instance)
{
+ PAGED_CODE();
+
+ if (!BooleanFlagOn(RdbssReferenceTracingValue, TraceType))
+ {
+ return TRUE;
+ }
+
UNIMPLEMENTED;
- return FALSE;
+ return TRUE;
}
VOID
_In_ ULONG Line,
_In_ PVOID Instance)
{
+ if (!BooleanFlagOn(RdbssReferenceTracingValue, TraceType))
+ {
+ return;
+ }
+
UNIMPLEMENTED;
}
/* 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 */
{
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);
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);
/* 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 */
}
}
+/*
+ * @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);
+ }
}
/*
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