ReactOS 0.4.15-dev-7961-gdcf9eb0
rxce.c File Reference
#include <rx.h>
#include <pseh/pseh2.h>
#include <dfs.h>
#include <debug.h>
Include dependency graph for rxce.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID RxAssert (PVOID Assert, PVOID File, ULONG Line, PVOID Message)
 
VOID NTAPI RxCreateSrvCallCallBack (IN OUT PMRX_SRVCALL_CALLBACK_CONTEXT Context)
 
NTSTATUS RxFinishSrvCallConstruction (PMRX_SRVCALLDOWN_STRUCTURE Calldown)
 
VOID NTAPI RxFinishSrvCallConstructionDispatcher (IN PVOID Context)
 
NTSTATUS RxInsertWorkQueueItem (PRDBSS_DEVICE_OBJECT pMRxDeviceObject, WORK_QUEUE_TYPE WorkQueueType, PRX_WORK_QUEUE_ITEM WorkQueueItem)
 
PVOID RxNewMapUserBuffer (PRX_CONTEXT RxContext)
 
VOID NTAPI RxpDestroySrvCall (IN PVOID Context)
 
VOID RxpDispatchChangeBufferingStateRequests (PSRV_CALL SrvCall, PSRV_OPEN SrvOpen, PLIST_ENTRY DiscardedRequests)
 
VOID NTAPI RxScavengerTimerRoutine (PVOID Context)
 
VOID NTAPI RxTimerDispatch (_In_ struct _KDPC *Dpc, _In_opt_ PVOID DeferredContext, _In_opt_ PVOID SystemArgument1, _In_opt_ PVOID SystemArgument2)
 
VOID 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)
 
NTSTATUS NTAPI RxAcquireExclusiveFcbResourceInMRx (_Inout_ PMRX_FCB Fcb)
 
BOOLEAN NTAPI RxAcquireFcbForLazyWrite (PVOID Context, BOOLEAN Wait)
 
BOOLEAN NTAPI RxAcquireFcbForReadAhead (PVOID Context, BOOLEAN Wait)
 
VOID NTAPI RxAcquireFileForNtCreateSection (PFILE_OBJECT FileObject)
 
NTSTATUS NTAPI RxAcquireForCcFlush (PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject)
 
VOID RxAddVirtualNetRootToNetRoot (PNET_ROOT NetRoot, PV_NET_ROOT VNetRoot)
 
PVOID RxAllocateFcbObject (PRDBSS_DEVICE_OBJECT RxDeviceObject, NODE_TYPE_CODE NodeType, POOL_TYPE PoolType, ULONG NameSize, PVOID AlreadyAllocatedObject)
 
PVOID RxAllocateObject (NODE_TYPE_CODE NodeType, PMINIRDR_DISPATCH MRxDispatch, ULONG NameLength)
 
VOID NTAPI RxBootstrapWorkerThreadDispatcher (IN PVOID WorkQueue)
 
VOID RxCancelBlockingOperation (IN OUT PRX_CONTEXT RxContext)
 
NTSTATUS NTAPI RxChangeBufferingState (PSRV_OPEN SrvOpen, PVOID Context, BOOLEAN ComputeNewState)
 
NTSTATUS RxCheckVNetRootCredentials (PRX_CONTEXT RxContext, PV_NET_ROOT VNetRoot, PLUID LogonId, PUNICODE_STRING UserName, PUNICODE_STRING UserDomain, PUNICODE_STRING Password, ULONG Flags)
 
NTSTATUS RxCompleteRequest (PRX_CONTEXT Context, NTSTATUS Status)
 
VOID RxCompleteRequest_Real (IN PRX_CONTEXT RxContext, IN PIRP Irp, IN NTSTATUS Status)
 
VOID RxCompleteSrvOpenKeyAssociation (IN OUT PSRV_OPEN SrvOpen)
 
NTSTATUS RxConstructNetRoot (IN PRX_CONTEXT RxContext, IN PSRV_CALL SrvCall, IN PNET_ROOT NetRoot, IN PV_NET_ROOT VirtualNetRoot, OUT PLOCK_HOLDING_STATE LockHoldingState)
 
NTSTATUS RxConstructSrvCall (IN PRX_CONTEXT RxContext, IN PSRV_CALL SrvCall, OUT PLOCK_HOLDING_STATE LockHoldingState)
 
NTSTATUS RxConstructVirtualNetRoot (IN PRX_CONTEXT RxContext, IN PUNICODE_STRING CanonicalName, IN NET_ROOT_TYPE NetRootType, OUT PV_NET_ROOT *VirtualNetRootPointer, OUT PLOCK_HOLDING_STATE LockHoldingState, OUT PRX_CONNECTION_ID RxConnectionId)
 
PFCB RxCreateNetFcb (IN PRX_CONTEXT RxContext, IN PV_NET_ROOT VNetRoot, IN PUNICODE_STRING Name)
 
PMRX_FOBX NTAPI RxCreateNetFobx (OUT PRX_CONTEXT RxContext, IN PMRX_SRV_OPEN MrxSrvOpen)
 
PNET_ROOT RxCreateNetRoot (IN PSRV_CALL SrvCall, IN PUNICODE_STRING Name, IN ULONG NetRootFlags, IN PRX_CONNECTION_ID OPTIONAL RxConnectionId)
 
VOID NTAPI RxCreateNetRootCallBack (IN PMRX_CREATENETROOT_CONTEXT CreateNetRootContext)
 
PRX_CONTEXT NTAPI RxCreateRxContext (IN PIRP Irp, IN PRDBSS_DEVICE_OBJECT RxDeviceObject, IN ULONG InitialContextFlags)
 
PSRV_CALL RxCreateSrvCall (IN PRX_CONTEXT RxContext, IN PUNICODE_STRING Name, IN PUNICODE_STRING InnerNamePrefix OPTIONAL, IN PRX_CONNECTION_ID RxConnectionId)
 
PSRV_OPEN RxCreateSrvOpen (IN PV_NET_ROOT VNetRoot, IN OUT PFCB Fcb)
 
PV_NET_ROOT RxCreateVNetRoot (IN PRX_CONTEXT RxContext, IN PNET_ROOT NetRoot, IN PUNICODE_STRING CanonicalName, IN PUNICODE_STRING LocalNetRootName, IN PUNICODE_STRING FilePath, IN PRX_CONNECTION_ID RxConnectionId)
 
VOID RxDereference (IN OUT PVOID Instance, IN LOCK_HOLDING_STATE LockHoldingState)
 
VOID NTAPI RxDereferenceAndDeleteRxContext_Real (IN PRX_CONTEXT RxContext)
 
VOID NTAPI RxDispatchChangeBufferingStateRequests (PVOID Context)
 
NTSTATUS NTAPI RxDispatchToWorkerThread (IN PRDBSS_DEVICE_OBJECT pMRxDeviceObject, IN WORK_QUEUE_TYPE WorkQueueType, IN PRX_WORKERTHREAD_ROUTINE Routine, IN PVOID pContext)
 
VOID RxExclusivePrefixTableLockToShared (PRX_PREFIX_TABLE Table)
 
VOID RxExtractServerName (IN PUNICODE_STRING FilePathName, OUT PUNICODE_STRING SrvCallName, OUT PUNICODE_STRING RestOfName)
 
NTSTATUS RxFcbTableInsertFcb (IN OUT PRX_FCB_TABLE FcbTable, IN OUT PFCB Fcb)
 
PFCB RxFcbTableLookupFcb (IN PRX_FCB_TABLE FcbTable, IN PUNICODE_STRING Path)
 
NTSTATUS RxFcbTableRemoveFcb (IN OUT PRX_FCB_TABLE FcbTable, IN OUT PFCB Fcb)
 
NTSTATUS NTAPI RxFinalizeConnection (IN OUT PNET_ROOT NetRoot, IN OUT PV_NET_ROOT VNetRoot OPTIONAL, IN LOGICAL ForceFilesClosed)
 
VOID RxFinalizeFcbTable (IN OUT PRX_FCB_TABLE FcbTable)
 
BOOLEAN RxFinalizeNetFcb (OUT PFCB ThisFcb, IN BOOLEAN RecursiveFinalize, IN BOOLEAN ForceFinalize, IN LONG ReferenceCount)
 
BOOLEAN RxFinalizeNetFobx (_Out_ PFOBX ThisFobx, _In_ BOOLEAN RecursiveFinalize, _In_ BOOLEAN ForceFinalize)
 
BOOLEAN RxFinalizeNetRoot (OUT PNET_ROOT ThisNetRoot, IN BOOLEAN RecursiveFinalize, IN BOOLEAN ForceFinalize)
 
BOOLEAN RxFinalizeSrvCall (OUT PSRV_CALL ThisSrvCall, IN BOOLEAN RecursiveFinalize, IN BOOLEAN ForceFinalize)
 
BOOLEAN RxFinalizeSrvOpen (OUT PSRV_OPEN ThisSrvOpen, IN BOOLEAN RecursiveFinalize, IN BOOLEAN ForceFinalize)
 
BOOLEAN RxFinalizeVNetRoot (OUT PV_NET_ROOT ThisVNetRoot, IN BOOLEAN RecursiveFinalize, IN BOOLEAN ForceFinalize)
 
NTSTATUS RxFindOrConstructVirtualNetRoot (IN PRX_CONTEXT RxContext, IN PUNICODE_STRING CanonicalName, IN NET_ROOT_TYPE NetRootType, IN PUNICODE_STRING RemainingName)
 
NTSTATUS RxFindOrCreateConnections (_In_ PRX_CONTEXT RxContext, _In_ PUNICODE_STRING CanonicalName, _In_ NET_ROOT_TYPE NetRootType, _Out_ PUNICODE_STRING LocalNetRootName, _Out_ PUNICODE_STRING FilePathName, _Inout_ PLOCK_HOLDING_STATE LockState, _In_ PRX_CONNECTION_ID RxConnectionId)
 
VOID NTAPI RxFinishFcbInitialization (IN OUT PMRX_FCB Fcb, IN RX_FILE_TYPE FileType, IN PFCB_INIT_PACKET InitPacket OPTIONAL)
 
NTSTATUS RxFlushFcbInSystemCache (IN PFCB Fcb, IN BOOLEAN SynchronizeWithLazyWriter)
 
VOID RxFreeFcbObject (PVOID Object)
 
VOID RxFreeObject (PVOID pObject)
 
VOID RxGatherRequestsForSrvOpen (IN OUT PSRV_CALL SrvCall, IN PSRV_OPEN SrvOpen, IN OUT PLIST_ENTRY RequestsListHead)
 
PRDBSS_DEVICE_OBJECT RxGetDeviceObjectOfInstance (PVOID Instance)
 
VOID RxGetFileSizeWithLock (IN PFCB Fcb, OUT PLONGLONG FileSize)
 
PEPROCESS NTAPI RxGetRDBSSProcess (VOID)
 
NTSTATUS RxInitializeBufferingManager (PSRV_CALL SrvCall)
 
VOID NTAPI RxInitializeContext (IN PIRP Irp, IN PRDBSS_DEVICE_OBJECT RxDeviceObject, IN ULONG InitialContextFlags, IN OUT PRX_CONTEXT RxContext)
 
VOID NTAPI RxInitializeDebugSupport (VOID)
 
NTSTATUS NTAPI RxInitializeDispatcher (VOID)
 
VOID RxInitializeFcbTable (IN OUT PRX_FCB_TABLE FcbTable, IN BOOLEAN CaseInsensitiveMatch)
 
VOID NTAPI RxInitializeLowIoContext (OUT PLOWIO_CONTEXT LowIoContext, IN ULONG Operation)
 
VOID RxInitializeLowIoPerFcbInfo (PLOWIO_PER_FCB_INFO LowIoPerFcbInfo)
 
NTSTATUS RxInitializeMRxDispatcher (IN OUT PRDBSS_DEVICE_OBJECT pMRxDeviceObject)
 
VOID RxInitializePrefixTable (IN OUT PRX_PREFIX_TABLE ThisTable, IN ULONG TableSize OPTIONAL, IN BOOLEAN CaseInsensitiveMatch)
 
VOID RxInitializePurgeSyncronizationContext (PPURGE_SYNCHRONIZATION_CONTEXT PurgeSyncronizationContext)
 
NTSTATUS RxInitializeSrvCallParameters (IN PRX_CONTEXT RxContext, IN OUT PSRV_CALL SrvCall)
 
NTSTATUS NTAPI RxInitializeRxTimer (VOID)
 
NTSTATUS RxInitializeVNetRootParameters (PRX_CONTEXT RxContext, OUT LUID *LogonId, OUT PULONG SessionId, OUT PUNICODE_STRING *UserNamePtr, OUT PUNICODE_STRING *UserDomainNamePtr, OUT PUNICODE_STRING *PasswordPtr, OUT PULONG Flags)
 
VOID RxInitializeWorkQueue (PRX_WORK_QUEUE WorkQueue, WORK_QUEUE_TYPE WorkQueueType, ULONG MaximumNumberOfWorkerThreads, ULONG MinimumNumberOfWorkerThreads)
 
NTSTATUS RxInitializeWorkQueueDispatcher (PRX_WORK_QUEUE_DISPATCHER Dispatcher)
 
VOID RxInitiateSrvOpenKeyAssociation (IN OUT PSRV_OPEN SrvOpen)
 
BOOLEAN RxIsThisACscAgentOpen (IN PRX_CONTEXT RxContext)
 
VOID RxLockUserBuffer (IN PRX_CONTEXT RxContext, IN LOCK_OPERATION Operation, IN ULONG BufferLength)
 
NTSTATUS RxLowIoCompletionTail (IN PRX_CONTEXT RxContext)
 
NTSTATUS NTAPI RxLowIoPopulateFsctlInfo (IN PRX_CONTEXT RxContext)
 
NTSTATUS NTAPI RxLowIoSubmit (IN PRX_CONTEXT RxContext, IN PLOWIO_COMPLETION_ROUTINE CompletionRoutine)
 
PVOID RxMapSystemBuffer (IN PRX_CONTEXT RxContext)
 
VOID RxMarkFobxOnCleanup (PFOBX pFobx, PBOOLEAN NeedPurge)
 
VOID RxMarkFobxOnClose (PFOBX Fobx)
 
BOOLEAN NTAPI RxNoOpAcquire (IN PVOID Fcb, IN BOOLEAN Wait)
 
VOID NTAPI RxNoOpRelease (IN PVOID Fcb)
 
VOID RxOrphanThisFcb (PFCB Fcb)
 
VOID RxOrphanSrvOpens (IN PV_NET_ROOT ThisVNetRoot)
 
VOID RxOrphanSrvOpensForThisFcb (IN PFCB Fcb, IN PV_NET_ROOT ThisVNetRoot, IN BOOLEAN OrphanAll)
 
BOOLEAN RxpAcquirePrefixTableLockShared (PRX_PREFIX_TABLE pTable, BOOLEAN Wait, BOOLEAN ProcessBufferingStateChangeRequests)
 
BOOLEAN RxpAcquirePrefixTableLockExclusive (PRX_PREFIX_TABLE pTable, BOOLEAN Wait, BOOLEAN ProcessBufferingStateChangeRequests)
 
BOOLEAN RxpDereferenceAndFinalizeNetFcb (OUT PFCB ThisFcb, IN PRX_CONTEXT RxContext, IN BOOLEAN RecursiveFinalize, IN BOOLEAN ForceFinalize)
 
LONG RxpDereferenceNetFcb (PFCB Fcb)
 
VOID RxpDiscardChangeBufferingStateRequests (_Inout_ PLIST_ENTRY DiscardedRequests)
 
NTSTATUS RxpLookupSrvOpenForRequestLite (IN PSRV_CALL SrvCall, IN OUT PCHANGE_BUFFERING_STATE_REQUEST Request)
 
VOID RxpMarkInstanceForScavengedFinalization (PVOID Instance)
 
NTSTATUS NTAPI RxPostOneShotTimerRequest (IN PRDBSS_DEVICE_OBJECT pDeviceObject, IN PRX_WORK_ITEM pWorkItem, IN PRX_WORKERTHREAD_ROUTINE Routine, IN PVOID pContext, IN LARGE_INTEGER TimeInterval)
 
NTSTATUS NTAPI RxPostToWorkerThread (_In_ PRDBSS_DEVICE_OBJECT pMRxDeviceObject, _In_ WORK_QUEUE_TYPE WorkQueueType, _In_ PRX_WORK_QUEUE_ITEM pWorkQueueItem, _In_ PRX_WORKERTHREAD_ROUTINE Routine, _In_ PVOID pContext)
 
VOID RxpProcessChangeBufferingStateRequests (PSRV_CALL SrvCall, BOOLEAN UpdateHandlerState)
 
PRX_PREFIX_ENTRY RxPrefixTableInsertName (IN OUT PRX_PREFIX_TABLE ThisTable, IN OUT PRX_PREFIX_ENTRY ThisEntry, IN PVOID Container, IN PULONG ContainerRefCount, IN USHORT CaseInsensitiveLength, IN PRX_CONNECTION_ID ConnectionId)
 
PVOID RxPrefixTableLookupName (IN PRX_PREFIX_TABLE ThisTable, IN PUNICODE_STRING CanonicalName, OUT PUNICODE_STRING RemainingName, IN PRX_CONNECTION_ID ConnectionId)
 
LONG RxpReferenceNetFcb (PFCB Fcb)
 
VOID RxpReleasePrefixTableLock (PRX_PREFIX_TABLE pTable, BOOLEAN ProcessBufferingStateChangeRequests)
 
VOID NTAPI RxPrepareContextForReuse (IN OUT PRX_CONTEXT RxContext)
 
VOID RxPrepareRequestForReuse (PCHANGE_BUFFERING_STATE_REQUEST Request)
 
VOID NTAPI RxProcessChangeBufferingStateRequests (_In_ PVOID SrvCall)
 
VOID RxProcessChangeBufferingStateRequestsForSrvOpen (PSRV_OPEN SrvOpen)
 
VOID RxProcessFcbChangeBufferingStateRequest (PFCB Fcb)
 
VOID RxpScavengeFobxs (PRDBSS_SCAVENGER Scavenger, PLIST_ENTRY FobxToScavenge)
 
BOOLEAN RxpTrackDereference (_In_ ULONG TraceType, _In_ PCSTR FileName, _In_ ULONG Line, _In_ PVOID Instance)
 
VOID RxpTrackReference (_In_ ULONG TraceType, _In_ PCSTR FileName, _In_ ULONG Line, _In_ PVOID Instance)
 
VOID RxpUndoScavengerFinalizationMarking (PVOID Instance)
 
VOID RxPurgeChangeBufferingStateRequestsForSrvOpen (PSRV_OPEN SrvOpen)
 
VOID RxPurgeFcb (IN PFCB Fcb)
 
NTSTATUS RxPurgeFcbInSystemCache (IN PFCB Fcb, IN PLARGE_INTEGER FileOffset OPTIONAL, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps, IN BOOLEAN FlushFile)
 
BOOLEAN RxPurgeFobx (PFOBX pFobx)
 
NTSTATUS RxPurgeFobxFromCache (PFOBX FobxToBePurged)
 
NTSTATUS RxPurgeRelatedFobxs (PNET_ROOT NetRoot, PRX_CONTEXT RxContext, BOOLEAN AttemptFinalization, PFCB PurgingFcb)
 
VOID RxpWorkerThreadDispatcher (IN PRX_WORK_QUEUE WorkQueue, IN PLARGE_INTEGER WaitInterval)
 
VOID RxReference (IN OUT PVOID Instance)
 
VOID NTAPI RxReinitializeContext (IN OUT PRX_CONTEXT RxContext)
 
VOID NTAPI RxReleaseFcbFromLazyWrite (PVOID Context)
 
VOID NTAPI RxReleaseFcbFromReadAhead (PVOID Context)
 
VOID NTAPI RxReleaseFileForNtCreateSection (PFILE_OBJECT FileObject)
 
NTSTATUS NTAPI RxReleaseForCcFlush (PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject)
 
VOID RxRemoveNameNetFcb (OUT PFCB ThisFcb)
 
VOID RxRemoveOperationFromBlockingQueue (IN OUT PRX_CONTEXT RxContext)
 
VOID RxRemovePrefixTableEntry (IN OUT PRX_PREFIX_TABLE ThisTable, IN OUT PRX_PREFIX_ENTRY Entry)
 
VOID RxRemoveVirtualNetRootFromNetRoot (PNET_ROOT NetRoot, PV_NET_ROOT VNetRoot)
 
VOID RxResumeBlockedOperations_ALL (IN OUT PRX_CONTEXT RxContext)
 
VOID NTAPI RxResumeBlockedOperations_Serially (IN OUT PRX_CONTEXT RxContext, IN OUT PLIST_ENTRY BlockingIoQ)
 
VOID RxSetFileSizeWithLock (IN OUT PFCB Fcb, IN PLONGLONG FileSize)
 
VOID RxScavengeFobxsForNetRoot (PNET_ROOT NetRoot, PFCB PurgingFcb, BOOLEAN SynchronizeWithScavenger)
 
BOOLEAN RxScavengeRelatedFobxs (PFCB Fcb)
 
VOID RxScavengerFinalizeEntries (PRDBSS_DEVICE_OBJECT DeviceObject)
 
BOOLEAN RxScavengeVNetRoots (PRDBSS_DEVICE_OBJECT RxDeviceObject)
 
VOID NTAPI RxSpinUpRequestsDispatcher (PVOID Dispatcher)
 
NTSTATUS RxSpinUpWorkerThread (PRX_WORK_QUEUE WorkQueue, PRX_WORKERTHREAD_ROUTINE Routine, PVOID Parameter)
 
VOID RxSpinUpWorkerThreads (PRX_WORK_QUEUE WorkQueue)
 
VOID RxSynchronizeWithScavenger (IN PRX_CONTEXT RxContext)
 
ULONG RxTableComputeHashValue (IN PUNICODE_STRING Name)
 
ULONG RxTableComputePathHashValue (IN PUNICODE_STRING Name)
 
PVOID RxTableLookupName (IN PRX_PREFIX_TABLE ThisTable, IN PUNICODE_STRING Name, OUT PUNICODE_STRING RemainingName, IN PRX_CONNECTION_ID OPTIONAL RxConnectionId)
 
PRX_PREFIX_ENTRY RxTableLookupName_ExactLengthMatch (IN PRX_PREFIX_TABLE ThisTable, IN PUNICODE_STRING Name, IN ULONG HashValue, IN PRX_CONNECTION_ID OPTIONAL RxConnectionId)
 
NTSTATUS RxTearDownBufferingManager (PSRV_CALL SrvCall)
 
VOID RxTrackPagingIoResource (_Inout_ PVOID Instance, _In_ ULONG Type, _In_ ULONG Line, _In_ PCSTR File)
 
VOID RxUndoScavengerFinalizationMarking (PVOID Instance)
 
VOID RxUninitializeVNetRootParameters (IN PUNICODE_STRING UserName, IN PUNICODE_STRING UserDomainName, IN PUNICODE_STRING Password, OUT PULONG Flags)
 
VOID RxUpdateCondition (IN RX_BLOCK_CONDITION NewConditionValue, OUT PRX_BLOCK_CONDITION Condition, IN OUT PLIST_ENTRY TransitionWaitList)
 
VOID RxVerifyOperationIsLegal (IN PRX_CONTEXT RxContext)
 
VOID RxWaitForStableCondition (IN PRX_BLOCK_CONDITION Condition, IN OUT PLIST_ENTRY TransitionWaitList, IN OUT PRX_CONTEXT RxContext, OUT NTSTATUS *AsyncStatus OPTIONAL)
 
NTSTATUS __RxAcquireFcb (_Inout_ PFCB Fcb, _Inout_opt_ PRX_CONTEXT RxContext OPTIONAL, _In_ ULONG Mode)
 
VOID __RxItsTheSameContext (_In_ PRX_CONTEXT RxContext, _In_ ULONG CapturedRxContextSerialNumber, _In_ ULONG Line, _In_ PCSTR File)
 
VOID __RxReleaseFcb (_Inout_opt_ PRX_CONTEXT RxContext, _Inout_ PMRX_FCB MrxFcb)
 
VOID __RxReleaseFcbForThread (_Inout_opt_ PRX_CONTEXT RxContext, _Inout_ PMRX_FCB MrxFcb, _In_ ERESOURCE_THREAD ResourceThreadId)
 

Variables

ULONG ReadAheadGranularity
 
volatile LONG RxNumberOfActiveFcbs = 0
 
ULONG SerialNumber = 1
 
PVOID RxNull = NULL
 
volatile ULONG RxContextSerialNumberCounter
 
BOOLEAN RxStopOnLoudCompletion = TRUE
 
BOOLEAN RxSrvCallConstructionDispatcherActive = FALSE
 
LIST_ENTRY RxSrvCalldownList
 
RX_SPIN_LOCK RxStrucSupSpinLock
 
ULONG RdbssReferenceTracingValue = 0
 
LARGE_INTEGER RxWorkQueueWaitInterval [RxMaximumWorkQueue]
 
LARGE_INTEGER RxSpinUpDispatcherWaitInterval
 
RX_DISPATCHER RxDispatcher
 
RX_WORK_QUEUE_DISPATCHER RxDispatcherWorkQueues
 
FAST_MUTEX RxLowIoPagingIoSyncMutex
 
BOOLEAN RxContinueFromAssert = TRUE
 
ULONG RxExplodePoolTags = 1
 
LARGE_INTEGER RxTimerInterval
 
RX_SPIN_LOCK RxTimerLock
 
LIST_ENTRY RxTimerQueueHead
 
LIST_ENTRY RxRecurrentWorkItemsList
 
KDPC RxTimerDpc
 
KTIMER RxTimer
 
ULONG RxTimerTickCount
 
FAST_MUTEX RxContextPerFileSerializationMutex
 
BOOLEAN DumpDispatchRoutine = FALSE
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 33 of file rxce.c.

Function Documentation

◆ __RxAcquireFcb()

NTSTATUS __RxAcquireFcb ( _Inout_ PFCB  Fcb,
_Inout_opt_ PRX_CONTEXT RxContext  OPTIONAL,
_In_ ULONG  Mode 
)

Definition at line 8973 of file rxce.c.

8984{
8986 BOOLEAN SpecialContext, CanWait, Acquired, ContextIsPresent;
8987
8988 PAGED_CODE();
8989
8990 DPRINT("__RxAcquireFcb(%p, %p, %d, %d, %s, %d)\n", Fcb, RxContext, Mode, LineNumber, FileName, SerialNumber);
8991
8992 SpecialContext = FALSE;
8993 ContextIsPresent = FALSE;
8994 /* Check for special context */
8996 {
8997 SpecialContext = TRUE;
8998 }
8999
9000 /* We don't handle buffering state change yet... */
9001 if (!RxIsFcbAcquired(Fcb) && !SpecialContext &&
9003 {
9005 }
9006
9007 /* Nor special contexts */
9008 if (SpecialContext)
9009 {
9011 }
9012
9013 /* If we don't have a context, assume we can wait! */
9014 if (RxContext == NULL)
9015 {
9016 CanWait = TRUE;
9017 }
9018 else
9019 {
9020 /* That said: we have a real context! */
9021 ContextIsPresent = TRUE;
9022
9023 /* If we've been cancelled in between, give up */
9025 if (!NT_SUCCESS(Status))
9026 {
9027 return Status;
9028 }
9029
9030 /* Can we wait? */
9031 CanWait = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
9032 }
9033
9034 while (TRUE)
9035 {
9036 /* Assume we cannot lock */
9038
9039 /* Lock according to what the caller asked */
9040 switch (Mode)
9041 {
9042 case FCB_MODE_EXCLUSIVE:
9043 Acquired = ExAcquireResourceExclusiveLite(Fcb->Header.Resource, CanWait);
9044 break;
9045
9046 case FCB_MODE_SHARED:
9047 Acquired = ExAcquireResourceSharedLite(Fcb->Header.Resource, CanWait);
9048 break;
9049
9051 Acquired = ExAcquireSharedWaitForExclusive(Fcb->Header.Resource, CanWait);
9052 break;
9053
9054 default:
9056 Acquired = ExAcquireSharedStarveExclusive(Fcb->Header.Resource, CanWait);
9057 break;
9058 }
9059
9060 /* Lock granted! */
9061 if (Acquired)
9062 {
9065
9066 /* Handle paging write - not implemented */
9068 {
9070 }
9071 }
9072
9073 /* And break, that cool! */
9074 if (Acquired)
9075 {
9076 break;
9077 }
9078
9079 /* If it failed, return immediately */
9080 if (!NT_SUCCESS(Status))
9081 {
9082 return Status;
9083 }
9084 }
9085
9086 /* If we don't have to check for valid operation, job done, nothing more to do */
9087 if (!ContextIsPresent || BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_BYPASS_VALIDOP_CHECK))
9088 {
9089 if (NT_SUCCESS(Status))
9090 {
9091 RxTrackerUpdateHistory(RxContext, RX_GET_MRX_FCB(Fcb), TRACKER_ACQUIRE_FCB, LineNumber, FileName, SerialNumber);
9092 }
9093
9094 return Status;
9095 }
9096
9097 /* Verify operation */
9098 _SEH2_TRY
9099 {
9100 RxVerifyOperationIsLegal(RxContext);
9101 }
9103 {
9104 /* If it failed, release lock and fail */
9106 {
9107 ExReleaseResourceLite(Fcb->Header.Resource);
9109 }
9110 }
9111 _SEH2_END;
9112
9113 if (NT_SUCCESS(Status))
9114 {
9115 RxTrackerUpdateHistory(RxContext, RX_GET_MRX_FCB(Fcb), TRACKER_ACQUIRE_FCB, LineNumber, FileName, SerialNumber);
9116 }
9117
9118 DPRINT("Status: %x\n", Status);
9119 return Status;
9120}
#define PAGED_CODE()
unsigned char BOOLEAN
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 LineNumber
Definition: acpixf.h:1220
LONG NTSTATUS
Definition: precomp.h:26
#define UNIMPLEMENTED
Definition: debug.h:115
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define FCB_STATE_BUFFERING_STATE_CHANGE_PENDING
Definition: fcb.h:207
#define ASSERT_CORRECT_FCB_STRUCTURE(Fcb)
Definition: fcb.h:562
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
Status
Definition: gdiplustypes.h:25
_In_ ULONG Mode
Definition: hubbusif.h:303
#define ASSERT(a)
Definition: mode.c:44
BOOLEAN NTAPI ExAcquireSharedWaitForExclusive(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:1222
BOOLEAN NTAPI ExAcquireSharedStarveExclusive(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:1068
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
#define STATUS_LOCK_NOT_GRANTED
Definition: ntstatus.h:321
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:160
VOID RxVerifyOperationIsLegal(IN PRX_CONTEXT RxContext)
Definition: rxce.c:8759
ULONG SerialNumber
Definition: rxce.c:117
@ RX_CONTEXT_FLAG_CANCELLED
Definition: rxcontx.h:300
@ RX_CONTEXT_FLAG_BYPASS_VALIDOP_CHECK
Definition: rxcontx.h:303
@ RX_CONTEXT_FLAG_WAIT
Definition: rxcontx.h:282
#define FCB_MODE_EXCLUSIVE
Definition: rxprocs.h:130
#define CHANGE_BUFFERING_STATE_CONTEXT
Definition: rxprocs.h:135
#define FCB_MODE_SHARED_WAIT_FOR_EXCLUSIVE
Definition: rxprocs.h:132
#define FCB_MODE_SHARED_STARVE_EXCLUSIVE
Definition: rxprocs.h:133
#define RX_GET_MRX_FCB(F)
Definition: rxprocs.h:157
#define RxTrackerUpdateHistory(R, F, O, L, F, S)
Definition: rxprocs.h:218
#define CHANGE_BUFFERING_STATE_CONTEXT_WAIT
Definition: rxprocs.h:136
#define RxIsFcbAcquired(Fcb)
Definition: rxprocs.h:230
#define FCB_MODE_SHARED
Definition: rxprocs.h:131
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:925
ULONG FcbState
Definition: cdstruc.h:971
PNON_PAGED_FCB NonPaged
Definition: fatstruc.h:811
ULONG OutstandingAsyncWrites
Definition: fatstruc.h:737
#define STATUS_CANCELLED
Definition: udferr_usr.h:170

◆ __RxItsTheSameContext()

VOID __RxItsTheSameContext ( _In_ PRX_CONTEXT  RxContext,
_In_ ULONG  CapturedRxContextSerialNumber,
_In_ ULONG  Line,
_In_ PCSTR  File 
)

Definition at line 9126 of file rxce.c.

9131{
9132 /* Check we have a context with the same serial number */
9133 if (NodeType(RxContext) != RDBSS_NTC_RX_CONTEXT ||
9134 RxContext->SerialNumber != CapturedRxContextSerialNumber)
9135 {
9136 /* Just be noisy */
9137 DPRINT1("Context %p has changed at line %d in file %s\n", RxContext, Line, File);
9138 }
9139}
#define DPRINT1
Definition: precomp.h:8
Definition: File.h:16
#define NodeType(P)
Definition: nodetype.h:51
#define RDBSS_NTC_RX_CONTEXT
Definition: nodetype.h:58
Definition: ncftp.h:79

◆ __RxReleaseFcb()

VOID __RxReleaseFcb ( _Inout_opt_ PRX_CONTEXT  RxContext,
_Inout_ PMRX_FCB  MrxFcb 
)

Definition at line 9142 of file rxce.c.

9152{
9153 BOOLEAN IsExclusive, BufferingPending;
9154
9156
9157 BufferingPending = BooleanFlagOn(MrxFcb->FcbState, FCB_STATE_BUFFERING_STATE_CHANGE_PENDING);
9158 IsExclusive = !!RxIsResourceOwnershipStateExclusive(MrxFcb->Header.Resource);
9159
9160 /* If no buffering pending, or no exclusive lock (we can only handle with an exclusive lock),
9161 * then just release the FCB
9162 */
9163 if (!BufferingPending || !IsExclusive)
9164 {
9165 RxTrackerUpdateHistory(RxContext, MrxFcb, (!BufferingPending ? TRACKER_RELEASE_FCB_NO_BUFF_PENDING : TRACKER_RELEASE_NON_EXCL_FCB_BUFF_PENDING),
9167 ExReleaseResourceLite(MrxFcb->Header.Resource);
9168 }
9169
9171
9172 /* And finally leave */
9173 if (!BufferingPending || !IsExclusive)
9174 {
9175 return;
9176 }
9177
9179
9180 /* Otherwise, handle buffering state and release */
9182
9183 RxTrackerUpdateHistory(RxContext, MrxFcb, TRACKER_RELEASE_EXCL_FCB_BUFF_PENDING, LineNumber, FileName, SerialNumber);
9184 ExReleaseResourceLite(MrxFcb->Header.Resource);
9185}
#define RxIsResourceOwnershipStateExclusive(Resource)
Definition: ntrxdef.h:28
VOID RxProcessFcbChangeBufferingStateRequest(PFCB Fcb)
Definition: rxce.c:6685
#define RxReleaseSerializationMutex()
Definition: rxdata.h:9
#define RxAcquireSerializationMutex()
Definition: rxdata.h:8
#define RxIsFcbAcquiredExclusive(Fcb)
Definition: rxprocs.h:229
Definition: cdstruc.h:902
_In_ PWDFDEVICE_INIT _In_ BOOLEAN IsExclusive
Definition: wdfdevice.h:3112

◆ __RxReleaseFcbForThread()

VOID __RxReleaseFcbForThread ( _Inout_opt_ PRX_CONTEXT  RxContext,
_Inout_ PMRX_FCB  MrxFcb,
_In_ ERESOURCE_THREAD  ResourceThreadId 
)

Definition at line 9188 of file rxce.c.

9199{
9200 BOOLEAN IsExclusive, BufferingPending;
9201
9203
9204 BufferingPending = BooleanFlagOn(MrxFcb->FcbState, FCB_STATE_BUFFERING_STATE_CHANGE_PENDING);
9205 IsExclusive = !!RxIsResourceOwnershipStateExclusive(MrxFcb->Header.Resource);
9206
9207 /* If no buffering pending, or no exclusive lock (we can only handle with an exclusive lock),
9208 * then just release the FCB
9209 */
9210 if (!BufferingPending || !IsExclusive)
9211 {
9212 RxTrackerUpdateHistory(RxContext, MrxFcb,
9213 (!BufferingPending ? TRACKER_RELEASE_FCB_FOR_THRD_NO_BUFF_PENDING : TRACKER_RELEASE_NON_EXCL_FCB_FOR_THRD_BUFF_PENDING),
9215 ExReleaseResourceForThreadLite(MrxFcb->Header.Resource, ResourceThreadId);
9216 }
9217
9219
9220 /* And finally leave */
9221 if (!BufferingPending || !IsExclusive)
9222 {
9223 return;
9224 }
9225
9226 /* Otherwise, handle buffering state and release */
9227 RxTrackerUpdateHistory(RxContext, MrxFcb, TRACKER_RELEASE_EXCL_FCB_FOR_THRD_BUFF_PENDING, LineNumber, FileName, SerialNumber);
9229 ExReleaseResourceForThreadLite(MrxFcb->Header.Resource, ResourceThreadId);
9230}
#define ExReleaseResourceForThreadLite(res, thrdID)
Definition: env_spec_w32.h:635
_In_ ERESOURCE_THREAD ResourceThreadId
Definition: exfuncs.h:1052

◆ _RxAllocatePoolWithTag()

PVOID NTAPI _RxAllocatePoolWithTag ( _In_ POOL_TYPE  PoolType,
_In_ SIZE_T  NumberOfBytes,
_In_ ULONG  Tag 
)

Definition at line 8941 of file rxce.c.

8945{
8947}
PVOID NTAPI ExAllocatePoolWithTagPriority(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag, IN EX_POOL_PRIORITY Priority)
Definition: expool.c:2963
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3815
@ LowPoolPriority
Definition: extypes.h:40
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:1036

◆ _RxFreePool()

VOID NTAPI _RxFreePool ( _In_ PVOID  Buffer)

Definition at line 8954 of file rxce.c.

8956{
8958}
Definition: bufpool.h:45
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109

◆ _RxFreePoolWithTag()

VOID NTAPI _RxFreePoolWithTag ( _In_ PVOID  Buffer,
_In_ ULONG  Tag 
)

Definition at line 8965 of file rxce.c.

8968{
8970}

◆ RxAcquireExclusiveFcbResourceInMRx()

NTSTATUS NTAPI RxAcquireExclusiveFcbResourceInMRx ( _Inout_ PMRX_FCB  Fcb)

Definition at line 183 of file rxce.c.

185{
187}
#define RxAcquireExclusiveFcb(R, F)
Definition: rxprocs.h:154

◆ RxAcquireFcbForLazyWrite()

BOOLEAN NTAPI RxAcquireFcbForLazyWrite ( PVOID  Context,
BOOLEAN  Wait 
)

Definition at line 194 of file rxce.c.

197{
198 PFCB Fcb;
199 BOOLEAN Ret;
200
201 PAGED_CODE();
202
203 Fcb = Context;
204 /* The received context is a FCB */
207 ASSERT(Fcb->Specific.Fcb.LazyWriteThread == NULL);
208
209 /* Acquire the paging resource (shared) */
210 Ret = ExAcquireResourceSharedLite(Fcb->Header.PagingIoResource, Wait);
211 if (Ret)
212 {
213 /* Update tracker information */
214 Fcb->PagingIoResourceFile = __FILE__;
215 Fcb->PagingIoResourceLine = __LINE__;
216 /* Lazy writer thread is the current one */
217 Fcb->Specific.Fcb.LazyWriteThread = PsGetCurrentThread();
218
219 /* There is no top level IRP */
221 /* Now, there will be! */
224 /* In case of failure, release the lock and reset everything */
225 if (!Ret)
226 {
229 ExReleaseResourceLite(Fcb->Header.PagingIoResource);
230 Fcb->Specific.Fcb.LazyWriteThread = NULL;
231 }
232 }
233
234 return Ret;
235}
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define FSRTL_CACHE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:60
BOOLEAN RxIsThisTheTopLevelIrp(_In_ PIRP Irp)
BOOLEAN RxTryToBecomeTheTopLevelIrp(_Inout_ PRX_TOPLEVELIRP_CONTEXT TopLevelContext, _In_ PIRP Irp, _In_ PRDBSS_DEVICE_OBJECT RxDeviceObject, _In_ BOOLEAN ForceTopLevel)
#define RDBSS_NTC_FCB
Definition: nodetype.h:66
union _FCB::@720 Specific
struct _FCB::@720::@723 Fcb
PRDBSS_DEVICE_OBJECT RxDeviceObject
Definition: fcb.h:149
PCHAR PagingIoResourceFile
Definition: fcb.h:198
ULONG PagingIoResourceLine
Definition: fcb.h:199
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170

◆ RxAcquireFcbForReadAhead()

BOOLEAN NTAPI RxAcquireFcbForReadAhead ( PVOID  Context,
BOOLEAN  Wait 
)

Definition at line 242 of file rxce.c.

245{
246 PFCB Fcb;
247 BOOLEAN Ret;
248
249 PAGED_CODE();
250
251 Fcb = Context;
252 /* The received context is a FCB */
255
256 Ret = ExAcquireResourceSharedLite(Fcb->Header.Resource, Wait);
257 if (Ret)
258 {
259 /* There is no top level IRP */
261 /* Now, there will be! */
264 /* In case of failure, release the lock and reset everything */
265 if (!Ret)
266 {
268 }
269 }
270
271 return Ret;
272}

◆ RxAcquireFileForNtCreateSection()

VOID NTAPI RxAcquireFileForNtCreateSection ( PFILE_OBJECT  FileObject)

Definition at line 276 of file rxce.c.

278{
280}

Referenced by RxInitializeDispatchVectors().

◆ RxAcquireForCcFlush()

NTSTATUS NTAPI RxAcquireForCcFlush ( PFILE_OBJECT  FileObject,
PDEVICE_OBJECT  DeviceObject 
)

Definition at line 284 of file rxce.c.

287{
290}
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239

Referenced by RxInitializeDispatchVectors().

◆ RxAddVirtualNetRootToNetRoot()

VOID RxAddVirtualNetRootToNetRoot ( PNET_ROOT  NetRoot,
PV_NET_ROOT  VNetRoot 
)

Definition at line 296 of file rxce.c.

299{
300 PAGED_CODE();
301
302 DPRINT("RxAddVirtualNetRootToNetRoot(%p, %p)\n", NetRoot, VNetRoot);
303
304 /* Insert in the VNetRoot list - make sure lock is held */
305 ASSERT(RxIsPrefixTableLockExclusive(NetRoot->SrvCall->RxDeviceObject->pRxNetNameTable));
306
307 VNetRoot->pNetRoot = (PMRX_NET_ROOT)NetRoot;
308 ++NetRoot->NumberOfVirtualNetRoots;
309 InsertTailList(&NetRoot->VirtualNetRoots, &VNetRoot->NetRootListEntry);
310}
#define InsertTailList(ListHead, Entry)
struct _MRX_NET_ROOT_ * PMRX_NET_ROOT
#define RxIsPrefixTableLockExclusive(T)
Definition: prefix.h:112
PSRV_CALL SrvCall
Definition: fcb.h:41
ULONG NumberOfVirtualNetRoots
Definition: fcb.h:51
LIST_ENTRY VirtualNetRoots
Definition: fcb.h:50
LIST_ENTRY NetRootListEntry
Definition: fcb.h:75

Referenced by RxCreateVNetRoot().

◆ RxAllocateFcbObject()

PVOID RxAllocateFcbObject ( PRDBSS_DEVICE_OBJECT  RxDeviceObject,
NODE_TYPE_CODE  NodeType,
POOL_TYPE  PoolType,
ULONG  NameSize,
PVOID  AlreadyAllocatedObject 
)

Definition at line 316 of file rxce.c.

322{
323 PFCB Fcb;
324 PFOBX Fobx;
325 PSRV_OPEN SrvOpen;
326 PVOID Buffer, PAPNBuffer;
327 PNON_PAGED_FCB NonPagedFcb;
329 ULONG NonPagedSize, FobxSize, SrvOpenSize, FcbSize;
330
331 PAGED_CODE();
332
333 Dispatch = RxDeviceObject->Dispatch;
334
335 NonPagedSize = 0;
336 FobxSize = 0;
337 SrvOpenSize = 0;
338 FcbSize = 0;
339
340 Fcb = NULL;
341 Fobx = NULL;
342 SrvOpen = NULL;
343 NonPagedFcb = NULL;
344 PAPNBuffer = NULL;
345
346 /* If we ask for FOBX, just allocate FOBX and its extension if asked */
348 {
349 FobxSize = sizeof(FOBX);
351 {
352 FobxSize += QuadAlign(Dispatch->MRxFobxSize);
353 }
354 }
355 /* If we ask for SRV_OPEN, also allocate the "internal" FOBX and the extensions if asked */
357 {
358 SrvOpenSize = sizeof(SRV_OPEN);
360 {
361 SrvOpenSize += QuadAlign(Dispatch->MRxSrvOpenSize);
362 }
363
364 FobxSize = sizeof(FOBX);
366 {
367 FobxSize += QuadAlign(Dispatch->MRxFobxSize);
368 }
369 }
370 /* Otherwise, we're asked to allocate a FCB */
371 else
372 {
373 /* So, allocate the FCB and its extension if asked */
374 FcbSize = sizeof(FCB);
376 {
377 FcbSize += QuadAlign(Dispatch->MRxFcbSize);
378 }
379
380 /* If we're asked to allocate from nonpaged, also allocate the NON_PAGED_FCB
381 * Otherwise, it will be allocated later on, specifically
382 */
383 if (PoolType == NonPagedPool)
384 {
385 NonPagedSize = sizeof(NON_PAGED_FCB);
386 }
387
388 /* And if it's not for a rename operation also allcoate the internal SRV_OPEN and FOBX and their extensions */
390 {
391 SrvOpenSize = sizeof(SRV_OPEN);
393 {
394 SrvOpenSize += QuadAlign(Dispatch->MRxSrvOpenSize);
395 }
396
397 FobxSize = sizeof(FOBX);
399 {
400 FobxSize += QuadAlign(Dispatch->MRxFobxSize);
401 }
402 }
403 }
404
405 /* If we already have a buffer, go ahead */
406 if (AlreadyAllocatedObject != NULL)
407 {
408 Buffer = AlreadyAllocatedObject;
409 }
410 /* Otherwise, allocate it */
411 else
412 {
413 Buffer = RxAllocatePoolWithTag(PoolType, NameSize + FcbSize + SrvOpenSize + FobxSize + NonPagedSize, RX_FCB_POOLTAG);
414 if (Buffer == NULL)
415 {
416 return NULL;
417 }
418 }
419
420 /* Now, get the pointers - FOBX is easy */
422 {
423 Fobx = Buffer;
424 }
425 /* SRV_OPEN first, FOBX next */
426 else if (NodeType == RDBSS_NTC_SRVOPEN)
427 {
428 SrvOpen = Buffer;
429 Fobx = Add2Ptr(Buffer, SrvOpenSize);
430 }
432 {
433 SrvOpen = Buffer;
434 }
435 else
436 {
437 /* FCB first, and if needed, SRV_OPEN next, FOBX last */
438 Fcb = Buffer;
440 {
441 SrvOpen = Add2Ptr(Buffer, FcbSize);
442 Fobx = Add2Ptr(Buffer, FcbSize + SrvOpenSize);
443 }
444
445 /* If we were not allocated from non paged, allocate the NON_PAGED_FCB now */
446 if (PoolType != NonPagedPool)
447 {
449 if (NonPagedFcb == NULL)
450 {
451 RxFreePoolWithTag(Buffer, RX_FCB_POOLTAG);
452 return NULL;
453 }
454
455 PAPNBuffer = Add2Ptr(Buffer, FcbSize + SrvOpenSize + FobxSize);
456 }
457 /* Otherwise, just point at the right place in what has been allocated previously */
458 else
459 {
460 NonPagedFcb = Add2Ptr(Fobx, FobxSize);
461 PAPNBuffer = Add2Ptr(Fobx, FobxSize + NonPagedSize);
462 }
463 }
464
465 /* If we have allocated a SRV_OPEN, initialize it */
466 if (SrvOpen != NULL)
467 {
468 ZeroAndInitializeNodeType(SrvOpen, RDBSS_NTC_SRVOPEN, SrvOpenSize);
469
471 {
472 SrvOpen->InternalFobx = Fobx;
473 }
474 else
475 {
476 SrvOpen->InternalFobx = NULL;
477 SrvOpen->Flags |= SRVOPEN_FLAG_FOBX_USED;
478 }
479
481 {
482 SrvOpen->Context = Add2Ptr(SrvOpen, sizeof(SRV_OPEN));
483 }
484
485 InitializeListHead(&SrvOpen->SrvOpenQLinks);
486 }
487
488 /* If we have allocated a FOBX, initialize it */
489 if (Fobx != NULL)
490 {
492
494 {
495 Fobx->Context = Add2Ptr(Fobx, sizeof(FOBX));
496 }
497 }
498
499 /* If we have allocated a FCB, initialize it */
500 if (Fcb != NULL)
501 {
503
504 Fcb->NonPaged = NonPagedFcb;
506#if DBG
507 Fcb->CopyOfNonPaged = NonPagedFcb;
508 NonPagedFcb->FcbBackPointer = Fcb;
509#endif
510
511 Fcb->InternalSrvOpen = SrvOpen;
512 Fcb->InternalFobx = Fobx;
513
517
519 {
520 Fcb->Context = Add2Ptr(Fcb, sizeof(FCB));
521 }
522
524
526 InterlockedIncrement((volatile long *)&RxDeviceObject->NumberOfActiveFcbs);
527
529 FsRtlSetupAdvancedHeader(Fcb, &NonPagedFcb->AdvancedFcbHeaderMutex);
530 }
531
532 DPRINT("Allocated %p\n", Buffer);
533
534 return Buffer;
535}
NodeType
Definition: Node.h:6
#define InterlockedIncrement
Definition: armddk.h:53
#define QuadAlign(Ptr)
Definition: cdprocs.h:1572
struct _FCB FCB
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
struct _NON_PAGED_FCB NON_PAGED_FCB
struct _SRV_OPEN SRV_OPEN
struct _FOBX FOBX
#define SRVOPEN_FLAG_FOBX_USED
Definition: fcb.h:257
#define Add2Ptr(PTR, INC)
#define RDBSS_MANAGE_SRV_OPEN_EXTENSION
Definition: mrx.h:333
#define RDBSS_MANAGE_FOBX_EXTENSION
Definition: mrx.h:334
#define RDBSS_MANAGE_FCB_EXTENSION
Definition: mrx.h:332
#define RxAllocatePoolWithTag
Definition: ntrxdef.h:25
volatile LONG RxNumberOfActiveFcbs
Definition: rxce.c:116
#define RX_FCB_POOLTAG
Definition: rxpooltg.h:7
#define RX_NONPAGEDFCB_POOLTAG
Definition: rxpooltg.h:8
#define RDBSS_NTC_OPENTARGETDIR_FCB
Definition: nodetype.h:44
#define RDBSS_NTC_INTERNAL_SRVOPEN
Definition: nodetype.h:53
#define RDBSS_NTC_FOBX
Definition: nodetype.h:57
#define RDBSS_STORAGE_NTC(x)
Definition: nodetype.h:32
@ FileTypeNotYetKnown
Definition: nodetype.h:36
#define RDBSS_NTC_SRVOPEN
Definition: nodetype.h:52
#define RDBSS_NTC_FCB_TABLE_ENTRY
Definition: nodetype.h:62
#define ZeroAndInitializeNodeType(Node, Type, Size)
Definition: nodetype.h:25
#define RDBSS_NTC_NONPAGED_FCB
Definition: nodetype.h:63
PSRV_OPEN InternalSrvOpen
Definition: fcb.h:152
PFOBX InternalFobx
Definition: fcb.h:153
RX_FCB_TABLE_ENTRY FcbTableEntry
Definition: fcb.h:144
UNICODE_STRING PrivateAlreadyPrefixedName
Definition: fcb.h:145
Definition: fcb.h:305
FAST_MUTEX AdvancedFcbHeaderMutex
Definition: fatstruc.h:750
PMINIRDR_DISPATCH Dispatch
Definition: rxstruc.h:89
volatile ULONG NumberOfActiveFcbs
Definition: rxstruc.h:98
Definition: fcbtable.h:4
Definition: fcb.h:261
PFOBX InternalFobx
Definition: fcb.h:280
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint32_t ULONG
Definition: typedefs.h:59
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH * Dispatch
Definition: wsk.h:188
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274

Referenced by RxCreateNetFcb(), RxCreateNetFobx(), and RxCreateSrvOpen().

◆ RxAllocateObject()

PVOID RxAllocateObject ( NODE_TYPE_CODE  NodeType,
PMINIRDR_DISPATCH  MRxDispatch,
ULONG  NameLength 
)

Definition at line 541 of file rxce.c.

545{
546 ULONG Tag, ObjectSize;
548 PRX_PREFIX_ENTRY PrefixEntry;
549 USHORT StructSize, ExtensionSize;
550
551 PAGED_CODE();
552
553 /* Select the node to allocate and always deal with the fact we may have to manage its extension */
554 ExtensionSize = 0;
555 switch (NodeType)
556 {
559 StructSize = sizeof(SRV_CALL);
560 if (MRxDispatch != NULL && BooleanFlagOn(MRxDispatch->MRxFlags, RDBSS_MANAGE_SRV_CALL_EXTENSION))
561 {
562 ExtensionSize = QuadAlign(MRxDispatch->MRxSrvCallSize);
563 }
564 break;
565
568 StructSize = sizeof(NET_ROOT);
570 {
571 ExtensionSize = QuadAlign(MRxDispatch->MRxNetRootSize);
572 }
573 break;
574
577 StructSize = sizeof(V_NET_ROOT);
579 {
580 ExtensionSize = QuadAlign(MRxDispatch->MRxVNetRootSize);
581 }
582 break;
583
584 default:
585 ASSERT(FALSE);
586 break;
587 }
588
589 /* Now, allocate the object */
590 ObjectSize = ExtensionSize + StructSize + NameLength;
592 if (Object == NULL)
593 {
594 return NULL;
595 }
596 /* Initialize it */
598
599 /* For SRV_CALL and NETROOT, the name points to the prefix table name */
600 switch (NodeType)
601 {
603 PrefixEntry = &((PSRV_CALL)Object)->PrefixEntry;
604 Extension = &((PSRV_CALL)Object)->Context;
605 ((PSRV_CALL)Object)->pSrvCallName = &PrefixEntry->Prefix;
606 break;
607
609 PrefixEntry = &((PNET_ROOT)Object)->PrefixEntry;
610 Extension = &((PNET_ROOT)Object)->Context;
611 ((PNET_ROOT)Object)->pNetRootName = &PrefixEntry->Prefix;
612 break;
613
615 PrefixEntry = &((PV_NET_ROOT)Object)->PrefixEntry;
616 Extension = &((PV_NET_ROOT)Object)->Context;
617 break;
618
619 default:
620 ASSERT(FALSE);
621 break;
622 }
623
624 /* Set the prefix table unicode string */
625 RtlZeroMemory(PrefixEntry, sizeof(RX_PREFIX_ENTRY));
627 PrefixEntry->NodeByteSize = sizeof(RX_PREFIX_ENTRY);
628 PrefixEntry->Prefix.Length = NameLength;
629 PrefixEntry->Prefix.MaximumLength = NameLength;
630 PrefixEntry->Prefix.Buffer = Add2Ptr(Object, ExtensionSize + StructSize);
631
632 /* Return the extension if we are asked to manage it */
633 if (ExtensionSize != 0)
634 {
635 *Extension = Add2Ptr(Object, StructSize);
636 }
637
638 return Object;
639}
struct _NET_ROOT NET_ROOT
struct _SRV_CALL * PSRV_CALL
struct _V_NET_ROOT V_NET_ROOT
struct _V_NET_ROOT * PV_NET_ROOT
struct _SRV_CALL SRV_CALL
struct _NET_ROOT * PNET_ROOT
_Inout_opt_ PUNICODE_STRING Extension
Definition: fltkernel.h:1092
#define RDBSS_MANAGE_V_NET_ROOT_EXTENSION
Definition: mrx.h:331
#define RDBSS_MANAGE_NET_ROOT_EXTENSION
Definition: mrx.h:330
#define RDBSS_MANAGE_SRV_CALL_EXTENSION
Definition: mrx.h:329
unsigned short USHORT
Definition: pedump.c:61
struct _RX_PREFIX_ENTRY RX_PREFIX_ENTRY
#define RX_NETROOT_POOLTAG
Definition: rxpooltg.h:5
#define RX_V_NETROOT_POOLTAG
Definition: rxpooltg.h:6
#define RX_SRVCALL_POOLTAG
Definition: rxpooltg.h:4
#define RDBSS_NTC_NETROOT
Definition: nodetype.h:49
#define RDBSS_NTC_SRVCALL
Definition: nodetype.h:48
#define RDBSS_NTC_V_NETROOT
Definition: nodetype.h:50
#define RDBSS_NTC_PREFIX_ENTRY
Definition: nodetype.h:60
ULONG MRxSrvCallSize
Definition: mrx.h:342
ULONG MRxNetRootSize
Definition: mrx.h:343
ULONG MRxVNetRootSize
Definition: mrx.h:344
ULONG MRxFlags
Definition: mrx.h:341
Definition: prefix.h:45
NODE_TYPE_CODE NodeTypeCode
Definition: prefix.h:46
UNICODE_STRING Prefix
Definition: prefix.h:53
NODE_BYTE_SIZE NodeByteSize
Definition: prefix.h:47
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object

Referenced by RxCreateNetRoot(), RxCreateSrvCall(), and RxCreateVNetRoot().

◆ RxAssert()

VOID RxAssert ( PVOID  Assert,
PVOID  File,
ULONG  Line,
PVOID  Message 
)

Definition at line 645 of file rxce.c.

650{
651 CHAR Response[2];
653
654 /* If we're not asked to continue, just stop the system */
656 {
657 KeBugCheckEx(RDBSS_FILE_SYSTEM, RDBSS_BUG_CHECK_ASSERT | Line, 0, 0, 0);
658 }
659
660 /* Otherwise, capture context to offer the user to dump it */
662
663 /* Loop until the user hits 'i' */
664 while (TRUE)
665 {
666 /* If no file provided, use empty name */
667 if (File == NULL)
668 {
669 File = "";
670 }
671
672 /* If no message provided, use empty one */
673 if (Message == NULL)
674 {
675 Message = "";
676 }
677
678 /* Display the message */
679 DbgPrint("\n*** Assertion failed: %s%s\n*** Source File: %s, line %ld\n\n", Message, Assert, File, Line);
680 /* And ask the user */
681 DbgPrompt("Break, Ignore (bi)? ", Response, sizeof(Response));
682 /* If he asks for ignore, quit
683 * In case of invalid input, ask again
684 */
685 if (Response[0] != 'B' && Response[0] != 'b')
686 {
687 if (Response[0] == 'I' || Response[0] == 'i')
688 {
689 return;
690 }
691
692 continue;
693 }
694
695 /* Break: offer the user to dump the context and break */
696 DbgPrint("Execute '!cxr %lx' to dump context\n", &Context);
698
699 /* Continue looping, so that after dump, execution can continue (with ignore) */
700 }
701}
#define Assert(cond, msg)
Definition: inflate.c:41
static const WCHAR Message[]
Definition: register.c:74
#define DbgPrint
Definition: hal.h:12
NTSYSAPI void WINAPI DbgBreakPoint(void)
NTSYSAPI ULONG NTAPI DbgPrompt(_In_z_ PCCH Prompt, _Out_writes_bytes_(MaximumResponseLength) PCH Response, _In_ ULONG MaximumResponseLength)
NTSYSAPI VOID NTAPI RtlCaptureContext(_Out_ PCONTEXT ContextRecord)
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
BOOLEAN RxContinueFromAssert
Definition: rxce.c:137
#define RDBSS_FILE_SYSTEM
Definition: nodetype.h:84
Definition: ncftp.h:89
char CHAR
Definition: xmlstorage.h:175

◆ RxBootstrapWorkerThreadDispatcher()

VOID NTAPI RxBootstrapWorkerThreadDispatcher ( IN PVOID  WorkQueue)

Definition at line 708 of file rxce.c.

710{
711 PRX_WORK_QUEUE RxWorkQueue;
712
713 PAGED_CODE();
714
715 RxWorkQueue = WorkQueue;
716 RxpWorkerThreadDispatcher(RxWorkQueue, NULL);
717}
VOID RxpWorkerThreadDispatcher(IN PRX_WORK_QUEUE WorkQueue, IN PLARGE_INTEGER WaitInterval)
Definition: rxce.c:7282
LIST_ENTRY WorkQueue
Definition: workqueue.c:16

Referenced by RxInitializeWorkQueueDispatcher().

◆ RxCancelBlockingOperation()

VOID RxCancelBlockingOperation ( IN OUT PRX_CONTEXT  RxContext)

Definition at line 723 of file rxce.c.

725{
726 PFOBX Fobx;
727 BOOLEAN PostRequest;
728
729 PAGED_CODE();
730
731 Fobx = (PFOBX)RxContext->pFobx;
732 PostRequest = FALSE;
733
734 /* Acquire the pipe mutex */
736
737 /* If that's a blocking pipe operation which is not the CCB one, then handle it */
738 if (BooleanFlagOn(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION) &&
739 RxContext->RxContextSerializationQLinks.Flink != NULL &&
740 RxContext != CONTAINING_RECORD(&Fobx->Specific.NamedPipe.ReadSerializationQueue, RX_CONTEXT, RxContextSerializationQLinks) &&
741 RxContext != CONTAINING_RECORD(&Fobx->Specific.NamedPipe.WriteSerializationQueue, RX_CONTEXT, RxContextSerializationQLinks))
742 {
743 /* Clear it! */
744 ClearFlag(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION);
745
746 /* Drop it off the list */
747 RemoveEntryList(&RxContext->RxContextSerializationQLinks);
748 RxContext->RxContextSerializationQLinks.Flink = NULL;
749 RxContext->RxContextSerializationQLinks.Blink = NULL;
750
751 /* Set we've been cancelled */
752 RxContext->IoStatusBlock.Status = STATUS_CANCELLED;
753
754 /*
755 * If it's async, we'll post completion, otherwise, we signal to waiters
756 * it's being cancelled
757 */
758 if (BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION))
759 {
760 PostRequest = TRUE;
761 }
762 else
763 {
764 RxSignalSynchronousWaiter(RxContext);
765 }
766 }
767
768 /* Done */
770
771 /* Post if async */
772 if (PostRequest)
773 {
774 RxFsdPostRequest(RxContext);
775 }
776}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
struct _FOBX * PFOBX
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
FAST_MUTEX RxContextPerFileSerializationMutex
Definition: rxce.c:146
@ RX_CONTEXT_FLAG_ASYNC_OPERATION
Definition: rxcontx.h:293
@ RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION
Definition: rxcontx.h:333
#define RxSignalSynchronousWaiter(RxContext)
Definition: rxcontx.h:417
NTSTATUS RxFsdPostRequest(_In_ PRX_CONTEXT RxContext)
struct _FOBX::@1958::@1961 NamedPipe
union _FOBX::@1958 Specific
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

◆ RxChangeBufferingState()

NTSTATUS NTAPI RxChangeBufferingState ( PSRV_OPEN  SrvOpen,
PVOID  Context,
BOOLEAN  ComputeNewState 
)

Definition at line 783 of file rxce.c.

787{
788 PFCB Fcb;
790 ULONG NewBufferingState, OldBufferingState;
791
792 PAGED_CODE();
793
794 DPRINT("RxChangeBufferingState(%p, %p, %d)\n", SrvOpen, Context, ComputeNewState);
795
796 Fcb = (PFCB)SrvOpen->pFcb;
798 /* First of all, mark that buffering state is changing */
800
801 /* Assume success */
804 {
805 /* If we're asked to compute a new state, ask the mini-rdr for it */
806 if (ComputeNewState)
807 {
808 MINIRDR_CALL_THROUGH(MiniStatus, Fcb->MRxDispatch, MRxComputeNewBufferingState,
809 ((PMRX_SRV_OPEN)SrvOpen, Context, &NewBufferingState));
811 {
812 NewBufferingState = 0;
813 }
814 }
815 else
816 {
817 /* If not, use SRV_OPEN state */
818 NewBufferingState = SrvOpen->BufferingFlags;
819 }
820
821 /* If no shared access, and if we're not asked to compute a new state, use maximum flags set */
822 if ((Fcb->ShareAccess.SharedRead + Fcb->ShareAccess.SharedWrite + Fcb->ShareAccess.SharedDelete) == 0 && !ComputeNewState)
823 {
824 SetFlag(NewBufferingState, FCB_STATE_BUFFERING_STATE_WITH_NO_SHARES);
825 }
826
827 /* If there's a lock operation to complete, clear that flag */
828 if (Fcb->OutstandingLockOperationsCount != 0)
829 {
831 }
832
833 /* Get the old state */
834 OldBufferingState = Fcb->FcbState & FCB_STATE_BUFFERING_STATE_MASK;
835 DPRINT("ChangeBufferingState %x -> %x (%x)\n", OldBufferingState, NewBufferingState, SrvOpen->BufferingFlags);
836
837 /* If we're dropping write cache, then flush the FCB */
838 if (BooleanFlagOn(OldBufferingState, FCB_STATE_WRITECACHING_ENABLED) &&
840 {
841 DPRINT("Flushing\n");
842
844 }
845
846 /* If we're dropping read cache, then purge */
847 if (Fcb->UncleanCount == 0 ||
848 (BooleanFlagOn(OldBufferingState, FCB_STATE_READCACHING_ENABLED) &&
849 !BooleanFlagOn(NewBufferingState, FCB_STATE_READCACHING_ENABLED)) ||
850 BooleanFlagOn(NewBufferingState, FCB_STATE_DELETE_ON_CLOSE))
851 {
852 DPRINT("Purging\n");
853
854 if (!NT_SUCCESS(Status))
855 {
856 DPRINT("Previous flush failed with status: %lx\n", Status);
857 }
858
860 }
861
862 /* If there's already a change pending in SRV_OPEN */
863 if (ComputeNewState && BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_BUFFERING_STATE_CHANGE_PENDING))
864 {
865 /* If there's a FOBX at least */
866 if (!IsListEmpty(&SrvOpen->FobxList))
867 {
868 PRX_CONTEXT RxContext;
869
870 /* Create a fake context to pass to the mini-rdr */
872 if (RxContext != NULL)
873 {
874 PFOBX Fobx;
875
876 RxContext->pFcb = RX_GET_MRX_FCB(Fcb);
877
878 /* Give the first FOBX */
879 Fobx = CONTAINING_RECORD(SrvOpen->FobxList.Flink, FOBX, FobxQLinks);
880 RxContext->pFobx = (PMRX_FOBX)Fobx;
881 RxContext->pRelevantSrvOpen = Fobx->pSrvOpen;
882
883 /* If there was a delayed close, perform it */
884 if (BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_CLOSE_DELAYED))
885 {
886 DPRINT("Oplock break close for %p\n", SrvOpen);
887
888 RxCloseAssociatedSrvOpen(Fobx, RxContext);
889 }
890 /* Otherwise, inform the mini-rdr about completion */
891 else
892 {
893 MINIRDR_CALL_THROUGH(MiniStatus, Fcb->MRxDispatch, MRxCompleteBufferingStateChangeRequest,
894 (RxContext, (PMRX_SRV_OPEN)SrvOpen, Context));
896 }
897
899 }
900 }
901 }
902
903 /* Set the new state */
904 Fcb->FcbState ^= (NewBufferingState ^ Fcb->FcbState) & FCB_STATE_BUFFERING_STATE_MASK;
905 }
907 {
908 /* Job done, clear the flag */
910
911 if (!BooleanFlagOn(NewBufferingState, FCB_STATE_FILETIMECACHEING_ENABLED))
912 {
914 }
915 }
916 _SEH2_END;
917
918 return Status;
919}
FCB * PFCB
Definition: cdstruc.h:1040
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FCB_STATE_DELETE_ON_CLOSE
Definition: fatstruc.h:1193
#define FCB_STATE_WRITECACHING_ENABLED
Definition: fcb.h:226
#define FCB_STATE_TIME_AND_SIZE_ALREADY_SET
Definition: fcb.h:217
#define FCB_STATE_BUFFERSTATE_CHANGING
Definition: fcb.h:215
#define FCB_STATE_READCACHING_ENABLED
Definition: fcb.h:224
#define FCB_STATE_FILETIMECACHEING_ENABLED
Definition: fcb.h:218
#define FCB_STATE_BUFFERING_STATE_MASK
Definition: fcb.h:232
#define FCB_STATE_LOCK_BUFFERING_ENABLED
Definition: fcb.h:220
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:386
struct _MRX_FOBX_ * PMRX_FOBX
#define SRVOPEN_FLAG_BUFFERING_STATE_CHANGE_PENDING
Definition: mrxfcb.h:136
#define SRVOPEN_FLAG_CLOSE_DELAYED
Definition: mrxfcb.h:133
VOID NTAPI MiniStatus(IN NDIS_HANDLE MiniportHandle, IN NDIS_STATUS GeneralStatus, IN PVOID StatusBuffer, IN UINT StatusBufferSize)
Definition: miniport.c:1384
NTSTATUS RxFlushFcbInSystemCache(IN PFCB Fcb, IN BOOLEAN SynchronizeWithLazyWriter)
Definition: rxce.c:4249
PRX_CONTEXT NTAPI RxCreateRxContext(IN PIRP Irp, IN PRDBSS_DEVICE_OBJECT RxDeviceObject, IN ULONG InitialContextFlags)
Definition: rxce.c:1797
@ RX_CONTEXT_FLAG_MUST_SUCCEED_NONBLOCKING
Definition: rxcontx.h:309
#define MINIRDR_CALL_THROUGH(STATUS, DISPATCH, FUNC, ARGLIST)
Definition: rxcontx.h:375
#define RxDereferenceAndDeleteRxContext(RXCONTEXT)
Definition: rxcontx.h:514
NTSTATUS RxCloseAssociatedSrvOpen(_In_ PFOBX Fobx, _In_opt_ PRX_CONTEXT RxContext)
#define NodeTypeIsFcb(FCB)
Definition: nodetype.h:68
SHARE_ACCESS ShareAccess
Definition: cdstruc.h:1009
PMINIRDR_DISPATCH MRxDispatch
Definition: fcb.h:150
CLONG UncleanCount
Definition: fatstruc.h:873
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
SECTION_OBJECT_POINTERS SectionObjectPointers
Definition: fatstruc.h:729
PMRX_FOBX pFobx
Definition: rxcontx.h:113
PMRX_SRV_OPEN pRelevantSrvOpen
Definition: rxcontx.h:114
PMRX_FCB pFcb
Definition: rxcontx.h:112
ULONG SharedRead
Definition: iotypes.h:529
ULONG SharedWrite
Definition: iotypes.h:530
ULONG SharedDelete
Definition: iotypes.h:531
LIST_ENTRY FobxList
Definition: fcb.h:279

Referenced by enable_caching(), and RxCreateFromNetRoot().

◆ RxCheckVNetRootCredentials()

NTSTATUS RxCheckVNetRootCredentials ( PRX_CONTEXT  RxContext,
PV_NET_ROOT  VNetRoot,
PLUID  LogonId,
PUNICODE_STRING  UserName,
PUNICODE_STRING  UserDomain,
PUNICODE_STRING  Password,
ULONG  Flags 
)

Definition at line 922 of file rxce.c.

930{
931 PAGED_CODE();
932
933 /* If that's a UNC name, there's nothing to process */
936 Flags != 0))
937 {
939 }
940
941 /* Compare the logon ID in the VNetRoot with the one provided */
942 if (RtlCompareMemory(&VNetRoot->LogonId, LogonId, sizeof(LUID)) != sizeof(LUID))
943 {
945 }
946
947 /* No credential provided? That's OK */
948 if (UserName == NULL && UserDomain == NULL && Password == NULL)
949 {
950 return STATUS_SUCCESS;
951 }
952
953 /* Left to do! */
956}
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define VNETROOT_FLAG_CSCAGENT_INSTANCE
Definition: mrxfcb.h:88
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID LogonId
@ RX_CONTEXT_CREATE_FLAG_UNC_NAME
Definition: rxcontx.h:324
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
ULONG Flags
Definition: rxcontx.h:124
@ Password
Definition: telnetd.h:65
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by RxFindOrConstructVirtualNetRoot().

◆ RxCompleteRequest()

NTSTATUS RxCompleteRequest ( PRX_CONTEXT  Context,
NTSTATUS  Status 
)

Definition at line 959 of file rxce.c.

962{
963 PIRP Irp;
964
965 PAGED_CODE();
966
967 DPRINT("RxCompleteRequest(%p, %lx)\n", Context, Status);
968
969 ASSERT(Context != NULL);
970 ASSERT(Context->CurrentIrp != NULL);
971 Irp = Context->CurrentIrp;
972
973 /* Debug what the caller asks for */
974 if (Context->LoudCompletionString != NULL)
975 {
976 DPRINT("LoudCompletion: %lx/%lx with %wZ\n", Status, Irp->IoStatus.Information, Context->LoudCompletionString);
977 /* Does the user asks to stop on failed completion */
979 {
980 DPRINT1("LoudFailure: %lx/%lx with %wZ\n", Status, Irp->IoStatus.Information, Context->LoudCompletionString);
981 }
982 }
983
984 /* Complete for real */
985 Context->CurrentIrp = NULL;
987
988 DPRINT("Status: %lx\n", Status);
989 return Status;
990}
_In_ PIRP Irp
Definition: csq.h:116
BOOLEAN RxStopOnLoudCompletion
Definition: rxce.c:120
VOID RxCompleteRequest_Real(IN PRX_CONTEXT RxContext, IN PIRP Irp, IN NTSTATUS Status)
Definition: rxce.c:996

Referenced by RxFinishSrvCallConstruction(), and RxLowIoCompletionTail().

◆ RxCompleteRequest_Real()

VOID RxCompleteRequest_Real ( IN PRX_CONTEXT  RxContext,
IN PIRP  Irp,
IN NTSTATUS  Status 
)

Definition at line 996 of file rxce.c.

1000{
1001 CCHAR Boost;
1002 KIRQL OldIrql;
1004
1005 DPRINT("RxCompleteRequest_Real(%p, %p, %lx)\n", RxContext, Irp, Status);
1006
1007 /* Nothing to complete, just free context */
1008 if (Irp == NULL)
1009 {
1010 DPRINT("NULL IRP for %p\n", RxContext);
1011 if (RxContext != NULL)
1012 {
1014 }
1015
1016 return;
1017 }
1018
1019 /* Remove cancel routine */
1023
1024 /* Select the boost, given the success/paging operation */
1026 {
1027 Boost = IO_DISK_INCREMENT;
1028 }
1029 else
1030 {
1031 Irp->IoStatus.Information = 0;
1032 Boost = IO_NO_INCREMENT;
1033 }
1034 Irp->IoStatus.Status = Status;
1035
1036 if (RxContext != NULL)
1037 {
1038 ASSERT(RxContext->MajorFunction <= IRP_MJ_MAXIMUM_FUNCTION);
1039 if (RxContext->MajorFunction != IRP_MJ_DEVICE_CONTROL)
1040 {
1041 DPRINT("Completing: MN: %d, Context: %p, IRP: %p, Status: %lx, Info: %lx, #%lx\n",
1042 RxContext->MinorFunction, RxContext, Irp,
1043 Status, Irp->IoStatus.Information, RxContext->SerialNumber);
1044 }
1045 }
1046
1047 /* If that's an opening, there might be a canonical name allocated,
1048 * if completion isn't pending, release it
1049 */
1051 if (Stack->MajorFunction == IRP_MJ_CREATE && Status != STATUS_PENDING &&
1052 RxContext != NULL)
1053 {
1054 if (BooleanFlagOn(RxContext->Create.Flags, 2))
1055 {
1056 Stack->FileObject->FileName.Length += sizeof(WCHAR);
1057 }
1058
1060 ASSERT(RxContext->Create.CanonicalNameBuffer == NULL);
1061 }
1062
1063 /* If it's a write, validate the correct behavior of the operation */
1064 if (Stack->MajorFunction == IRP_MJ_WRITE)
1065 {
1066 if (NT_SUCCESS(Irp->IoStatus.Status))
1067 {
1068 ASSERT(Irp->IoStatus.Information <= Stack->Parameters.Write.Length);
1069 }
1070 }
1071
1072 /* If it's pending, make sure IRP is marked as such */
1073 if (RxContext != NULL)
1074 {
1075 if (RxContext->PendingReturned)
1076 {
1078 }
1079 }
1080
1081 /* Complete now */
1082 DPRINT("Completing IRP with %x/%x\n", Irp->IoStatus.Status, Irp->IoStatus.Information);
1083 IoCompleteRequest(Irp, Boost);
1084
1085 /* If there's a context, dereference it */
1086 if (RxContext != NULL)
1087 {
1089 }
1090}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
UCHAR KIRQL
Definition: env_spec_w32.h:591
IoSetCancelRoutine(Irp, CancelRoutine)
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
#define STATUS_PENDING
Definition: ntstatus.h:82
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
VOID NTAPI RxDereferenceAndDeleteRxContext_Real(IN PRX_CONTEXT RxContext)
Definition: rxce.c:2309
VOID RxpPrepareCreateContextForReuse(_In_ PRX_CONTEXT RxContext)
char CCHAR
Definition: typedefs.h:51
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
#define SL_PENDING_RETURNED
Definition: iotypes.h:3325
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IO_DISK_INCREMENT
Definition: iotypes.h:600
#define IRP_SYNCHRONOUS_PAGING_IO
#define IRP_MJ_MAXIMUM_FUNCTION
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by RxCompleteRequest().

◆ RxCompleteSrvOpenKeyAssociation()

VOID RxCompleteSrvOpenKeyAssociation ( IN OUT PSRV_OPEN  SrvOpen)

Definition at line 1096 of file rxce.c.

1098{
1099 PSRV_CALL SrvCall;
1100
1101 SrvCall = (PSRV_CALL)((PFCB)SrvOpen->pFcb)->VNetRoot->pNetRoot->pSrvCall;
1102 /* Only handle requests if opening was a success */
1103 if (SrvOpen->Condition == Condition_Good)
1104 {
1105 KIRQL OldIrql;
1106 BOOLEAN ProcessChange;
1107 LIST_ENTRY DiscardedRequests;
1108
1109 /* Initialize our discarded requests list */
1110 InitializeListHead(&DiscardedRequests);
1111
1113
1114 /* Transfer our requests in the SRV_CALL */
1115 RxTransferList(&SrvCall->BufferingManager.SrvOpenLists[0], &SrvOpen->SrvOpenKeyList);
1116
1117 /* Was increased in RxInitiateSrvOpenKeyAssociation(), opening is done */
1119
1120 /* Dispatch requests and get the discarded ones */
1121 RxpDispatchChangeBufferingStateRequests(SrvCall, SrvOpen, &DiscardedRequests);
1122
1124
1125 /* Is there still anything to process? */
1128 {
1129 ProcessChange = FALSE;
1130 }
1131 else
1132 {
1133 ProcessChange = (SrvCall->BufferingManager.HandlerInactive == FALSE);
1134 if (ProcessChange)
1135 {
1137 }
1138 }
1140
1141 /* Yes? Go ahead! */
1142 if (ProcessChange)
1143 {
1144 RxReferenceSrvCall(SrvCall);
1148 }
1149
1150 /* And discard left requests */
1151 RxpDiscardChangeBufferingStateRequests(&DiscardedRequests);
1152 }
1153 else
1154 {
1156 }
1157}
#define InterlockedDecrement
Definition: armddk.h:52
#define RxReleaseBufferingManagerMutex(BufMan)
Definition: buffring.h:50
#define RxAcquireBufferingManagerMutex(BufMan)
Definition: buffring.h:42
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define RxReferenceSrvCall(SrvCall)
Definition: fcb.h:391
if(dx< 0)
Definition: linetemp.h:194
@ Condition_Good
Definition: mrx.h:76
VOID RxpDiscardChangeBufferingStateRequests(_Inout_ PLIST_ENTRY DiscardedRequests)
Definition: rxce.c:6065
VOID NTAPI RxProcessChangeBufferingStateRequests(_In_ PVOID SrvCall)
Definition: rxce.c:6643
NTSTATUS NTAPI RxPostToWorkerThread(_In_ PRDBSS_DEVICE_OBJECT pMRxDeviceObject, _In_ WORK_QUEUE_TYPE WorkQueueType, _In_ PRX_WORK_QUEUE_ITEM pWorkQueueItem, _In_ PRX_WORKERTHREAD_ROUTINE Routine, _In_ PVOID pContext)
Definition: rxce.c:6400
VOID RxpDispatchChangeBufferingStateRequests(PSRV_CALL SrvCall, PSRV_OPEN SrvOpen, PLIST_ENTRY DiscardedRequests)
Definition: rxce.c:6098
#define RxTransferList(Destination, Source)
Definition: rxcontx.h:449
PRDBSS_DEVICE_OBJECT RxFileSystemDeviceObject
Definition: rdbss.c:573
Definition: typedefs.h:120
BOOLEAN HandlerInactive
Definition: buffring.h:21
LIST_ENTRY HandlerList
Definition: buffring.h:30
volatile LONG NumberOfOutstandingOpens
Definition: buffring.h:28
LIST_ENTRY SrvOpenLists[1]
Definition: buffring.h:36
RX_WORK_QUEUE_ITEM HandlerWorkItem
Definition: buffring.h:33
KSPIN_LOCK SpinLock
Definition: buffring.h:24
Definition: fcb.h:10
RX_BUFFERING_MANAGER BufferingManager
Definition: fcb.h:27
@ HyperCriticalWorkQueue
Definition: extypes.h:191

◆ RxConstructNetRoot()

NTSTATUS RxConstructNetRoot ( IN PRX_CONTEXT  RxContext,
IN PSRV_CALL  SrvCall,
IN PNET_ROOT  NetRoot,
IN PV_NET_ROOT  VirtualNetRoot,
OUT PLOCK_HOLDING_STATE  LockHoldingState 
)

Definition at line 1163 of file rxce.c.

1169{
1171 PRX_PREFIX_TABLE PrefixTable;
1173 RX_BLOCK_CONDITION RootCondition, VRootCondition;
1174
1175 PAGED_CODE();
1176
1177 DPRINT("RxConstructNetRoot(%p, %p, %p, %p, %p)\n", RxContext, SrvCall, NetRoot,
1178 VirtualNetRoot, LockHoldingState);
1179
1180 /* Validate the lock is exclusively held */
1181 PrefixTable = RxContext->RxDeviceObject->pRxNetNameTable;
1182 ASSERT(*LockHoldingState == LHS_ExclusiveLockHeld);
1183
1184 /* Allocate the context */
1186 if (Context == NULL)
1187 {
1189 }
1190
1191 /* We can release lock now */
1192 RxReleasePrefixTableLock(PrefixTable);
1193 *LockHoldingState = LHS_LockNotHeld;
1194
1195 RootCondition = Condition_Bad;
1196 VRootCondition = Condition_Bad;
1197
1198 /* Initialize the context */
1201 Context->RxContext = RxContext;
1202 Context->pVNetRoot = VirtualNetRoot;
1203 Context->Callback = RxCreateNetRootCallBack;
1204
1205 /* And call the mini-rdr */
1206 MINIRDR_CALL_THROUGH(Status, SrvCall->RxDeviceObject->Dispatch, MRxCreateVNetRoot, (Context));
1207 if (Status == STATUS_PENDING)
1208 {
1209 /* Wait for the mini-rdr to be done */
1211 /* Update the structures condition according to mini-rdr return */
1212 if (NT_SUCCESS(Context->NetRootStatus))
1213 {
1214 if (NT_SUCCESS(Context->VirtualNetRootStatus))
1215 {
1216 RootCondition = Condition_Good;
1217 VRootCondition = Condition_Good;
1219 }
1220 else
1221 {
1222 RootCondition = Condition_Good;
1223 Status = Context->VirtualNetRootStatus;
1224 }
1225 }
1226 else
1227 {
1228 Status = Context->VirtualNetRootStatus;
1229 if (NT_SUCCESS(Status))
1230 {
1231 Status = Context->NetRootStatus;
1232 }
1233 }
1234 }
1235 else
1236 {
1237 /* It has to return STATUS_PENDING! */
1238 ASSERT(FALSE);
1239 }
1240
1241 /* Acquire lock again - for caller lock status will remain unchanged */
1242 ASSERT(*LockHoldingState == LHS_LockNotHeld);
1244 *LockHoldingState = LHS_ExclusiveLockHeld;
1245
1246 /* Do the transition to the condition got from mini-rdr */
1247 RxTransitionNetRoot(NetRoot, RootCondition);
1248 RxTransitionVNetRoot(VirtualNetRoot, VRootCondition);
1249
1250 /* Context is not longer needed */
1251 RxFreePoolWithTag(Context, RX_SRVCALL_POOLTAG);
1252
1253 DPRINT("Status: %x\n", Status);
1254
1255 return Status;
1256}
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define PagedPool
Definition: env_spec_w32.h:308
#define RxTransitionVNetRoot(V, C)
Definition: fcb.h:515
#define RxTransitionNetRoot(N, C)
Definition: fcb.h:474
enum _RX_BLOCK_CONDITION RX_BLOCK_CONDITION
@ Condition_Bad
Definition: mrx.h:77
#define KernelMode
Definition: asm.h:34
@ SynchronizationEvent
#define RxAcquirePrefixTableLockExclusive(T, W)
Definition: prefix.h:83
#define RxReleasePrefixTableLock(T)
Definition: prefix.h:84
VOID NTAPI RxCreateNetRootCallBack(IN PMRX_CREATENETROOT_CONTEXT CreateNetRootContext)
Definition: rxce.c:1784
@ LHS_LockNotHeld
Definition: rxstruc.h:20
@ LHS_ExclusiveLockHeld
Definition: rxstruc.h:22
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
@ Executive
Definition: ketypes.h:415

Referenced by RxConstructVirtualNetRoot(), and RxFindOrCreateConnections().

◆ RxConstructSrvCall()

NTSTATUS RxConstructSrvCall ( IN PRX_CONTEXT  RxContext,
IN PSRV_CALL  SrvCall,
OUT PLOCK_HOLDING_STATE  LockHoldingState 
)

Definition at line 1262 of file rxce.c.

1266{
1268 PRX_PREFIX_TABLE PrefixTable;
1269 PRDBSS_DEVICE_OBJECT RxDeviceObject;
1272
1273 PAGED_CODE();
1274
1275 DPRINT("RxConstructSrvCall(%p, %p, %p)\n", RxContext, SrvCall, LockHoldingState);
1276
1277 /* Validate the lock is exclusively held */
1278 RxDeviceObject = RxContext->RxDeviceObject;
1279 PrefixTable = RxDeviceObject->pRxNetNameTable;
1280 ASSERT(*LockHoldingState == LHS_ExclusiveLockHeld);
1281
1282 /* Allocate the context for mini-rdr */
1284 if (Calldown == NULL)
1285 {
1286 SrvCall->Context = NULL;
1287 SrvCall->Condition = Condition_Bad;
1288 RxReleasePrefixTableLock(PrefixTable);
1289 *LockHoldingState = LHS_LockNotHeld;
1291 }
1292
1293 /* Initialize it */
1294 RtlZeroMemory(Calldown, sizeof(MRX_SRVCALLDOWN_STRUCTURE));
1295
1296 SrvCall->Context = NULL;
1297 SrvCall->Condition = Condition_InTransition;
1298
1299 RxReleasePrefixTableLock(PrefixTable);
1300 *LockHoldingState = LHS_LockNotHeld;
1301
1302 CallbackContext = &Calldown->CallbackContexts[0];
1303 DPRINT("CalldownContext %p for %wZ\n", CallbackContext, &RxDeviceObject->DeviceName);
1304 DPRINT("With calldown %p and SrvCall %p\n", Calldown, SrvCall);
1305 CallbackContext->SrvCalldownStructure = Calldown;
1306 CallbackContext->CallbackContextOrdinal = 0;
1307 CallbackContext->RxDeviceObject = RxDeviceObject;
1308
1309 RxReferenceSrvCall(SrvCall);
1310
1311 /* If we're async, we'll post, otherwise, we'll have to wait for completion */
1312 if (BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION))
1313 {
1314 RxPrePostIrp(RxContext, RxContext->CurrentIrp);
1315 }
1316 else
1317 {
1319 }
1320
1321 Calldown->NumberToWait = 1;
1322 Calldown->NumberRemaining = 1;
1323 Calldown->RxContext = RxContext;
1324 Calldown->SrvCall = (PMRX_SRV_CALL)SrvCall;
1326 Calldown->BestFinisher = NULL;
1329
1330 /* Call the mini-rdr */
1331 ASSERT(RxDeviceObject->Dispatch != NULL);
1333 ASSERT(RxDeviceObject->Dispatch->MRxCreateSrvCall != NULL);
1334 Status = RxDeviceObject->Dispatch->MRxCreateSrvCall((PMRX_SRV_CALL)SrvCall, CallbackContext);
1335 /* It has to return STATUS_PENDING! */
1337
1338 /* No async, start completion */
1339 if (!BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION))
1340 {
1342
1343 /* Finish construction - we'll notify mini-rdr it's the winner */
1345 if (!NT_SUCCESS(Status))
1346 {
1347 RxReleasePrefixTableLock(PrefixTable);
1348 *LockHoldingState = LHS_LockNotHeld;
1349 }
1350 else
1351 {
1352 ASSERT(RxIsPrefixTableLockAcquired(PrefixTable));
1353 *LockHoldingState = LHS_ExclusiveLockHeld;
1354 }
1355 }
1356
1357 DPRINT("RxConstructSrvCall() = Status: %x\n", Status);
1358 return Status;
1359}
@ Condition_InTransition
Definition: mrx.h:74
struct _MRX_SRV_CALL_ * PMRX_SRV_CALL
#define STATUS_BAD_NETWORK_PATH
Definition: ntstatus.h:426
#define RxIsPrefixTableLockAcquired(T)
Definition: prefix.h:113
VOID NTAPI RxCreateSrvCallCallBack(IN OUT PMRX_SRVCALL_CALLBACK_CONTEXT Context)
Definition: rxce.c:1895
NTSTATUS RxFinishSrvCallConstruction(PMRX_SRVCALLDOWN_STRUCTURE Calldown)
Definition: rxce.c:4089
VOID RxPrePostIrp(_In_ PVOID Context, _In_ PIRP Irp)
#define RDBSS_NTC_MINIRDR_DISPATCH
Definition: nodetype.h:64
PMRX_CREATE_SRVCALL MRxCreateSrvCall
Definition: mrx.h:393
PMRX_SRV_CALL SrvCall
Definition: mrx.h:136
PRX_CONTEXT RxContext
Definition: mrx.h:135
PRDBSS_DEVICE_OBJECT BestFinisher
Definition: mrx.h:142
PMRX_SRVCALL_CALLBACK CallBack
Definition: mrx.h:137
MRX_SRVCALL_CALLBACK_CONTEXT CallbackContexts[1]
Definition: mrx.h:143
LIST_ENTRY SrvCalldownList
Definition: mrx.h:134
PRX_PREFIX_TABLE pRxNetNameTable
Definition: rxstruc.h:127
UNICODE_STRING DeviceName
Definition: rxstruc.h:90
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR _In_ ULONGLONG _In_ ULONGLONG _In_opt_ PEVENT_FILTER_DESCRIPTOR _Inout_opt_ PVOID CallbackContext
Definition: wmitypes.h:60

Referenced by RxFindOrCreateConnections().

◆ RxConstructVirtualNetRoot()

NTSTATUS RxConstructVirtualNetRoot ( IN PRX_CONTEXT  RxContext,
IN PUNICODE_STRING  CanonicalName,
IN NET_ROOT_TYPE  NetRootType,
OUT PV_NET_ROOT VirtualNetRootPointer,
OUT PLOCK_HOLDING_STATE  LockHoldingState,
OUT PRX_CONNECTION_ID  RxConnectionId 
)

Definition at line 1365 of file rxce.c.

1372{
1374 PV_NET_ROOT VNetRoot;
1376 UNICODE_STRING LocalNetRootName, FilePathName;
1377
1378 PAGED_CODE();
1379
1380 ASSERT(*LockHoldingState != LHS_LockNotHeld);
1381
1382 VNetRoot = NULL;
1384 /* Before creating the VNetRoot, try to find the appropriate connection */
1385 Status = RxFindOrCreateConnections(RxContext, CanonicalName, NetRootType,
1386 &LocalNetRootName, &FilePathName,
1387 LockHoldingState, RxConnectionId);
1388 /* Found and active */
1390 {
1391 /* We need a new VNetRoot */
1392 VNetRoot = RxCreateVNetRoot(RxContext, (PNET_ROOT)RxContext->Create.pVNetRoot->pNetRoot,
1393 CanonicalName, &LocalNetRootName, &FilePathName, RxConnectionId);
1394 if (VNetRoot != NULL)
1395 {
1396 RxReferenceVNetRoot(VNetRoot);
1397 }
1398
1399 /* Dereference previous VNetRoot */
1400 RxDereferenceVNetRoot(RxContext->Create.pVNetRoot->pNetRoot, *LockHoldingState);
1401 /* Reset and start construct (new structures will replace old ones) */
1402 RxContext->Create.pSrvCall = NULL;
1403 RxContext->Create.pNetRoot = NULL;
1404 RxContext->Create.pVNetRoot = NULL;
1405
1406 /* Construct new NetRoot */
1407 if (VNetRoot != NULL)
1408 {
1409 Status = RxConstructNetRoot(RxContext, (PSRV_CALL)VNetRoot->pNetRoot->pSrvCall,
1410 (PNET_ROOT)VNetRoot->pNetRoot, VNetRoot, LockHoldingState);
1411 if (NT_SUCCESS(Status))
1412 {
1414 }
1415 }
1416 else
1417 {
1419 }
1420 }
1421 else
1422 {
1423 /* If it failed creating the connection, leave */
1424 if (Status != STATUS_SUCCESS)
1425 {
1426 if (*LockHoldingState != LHS_LockNotHeld)
1427 {
1428 RxReleasePrefixTableLock(RxContext->RxDeviceObject->pRxNetNameTable);
1429 *LockHoldingState = LHS_LockNotHeld;
1430 }
1431
1432 *VirtualNetRootPointer = VNetRoot;
1433 DPRINT("RxConstructVirtualNetRoot() = Status: %x\n", Status);
1434 return Status;
1435 }
1436
1437 *LockHoldingState = LHS_ExclusiveLockHeld;
1438
1439 VNetRoot = (PV_NET_ROOT)RxContext->Create.pVNetRoot;
1441 }
1442
1443 /* We have a non stable VNetRoot - transition it */
1444 if (VNetRoot != NULL && !StableCondition(VNetRoot->Condition))
1445 {
1447 }
1448
1449 /* If recreation failed */
1450 if (Status != STATUS_SUCCESS)
1451 {
1452 /* Dereference potential VNetRoot */
1453 if (VNetRoot != NULL)
1454 {
1455 ASSERT(*LockHoldingState != LHS_LockNotHeld);
1456 RxDereferenceVNetRoot(VNetRoot, *LockHoldingState);
1457 VNetRoot = NULL;
1458 }
1459
1460 /* Release lock */
1461 if (*LockHoldingState != LHS_LockNotHeld)
1462 {
1463 RxReleasePrefixTableLock(RxContext->RxDeviceObject->pRxNetNameTable);
1464 *LockHoldingState = LHS_LockNotHeld;
1465 }
1466
1467 /* Set NULL ptr */
1468 *VirtualNetRootPointer = VNetRoot;
1469 return Status;
1470 }
1471
1472 /* Return the allocated VNetRoot */
1473 *VirtualNetRootPointer = VNetRoot;
1474 return Status;
1475}
#define RxReferenceVNetRoot(VNetRoot)
Definition: fcb.h:407
#define RxDereferenceVNetRoot(VNetRoot, LockHoldingState)
Definition: fcb.h:411
#define StableCondition(X)
Definition: mrx.h:81
IN ULONG IN UCHAR Condition
#define STATUS_CONNECTION_ACTIVE
Definition: ntstatus.h:703
PV_NET_ROOT RxCreateVNetRoot(IN PRX_CONTEXT RxContext, IN PNET_ROOT NetRoot, IN PUNICODE_STRING CanonicalName, IN PUNICODE_STRING LocalNetRootName, IN PUNICODE_STRING FilePath, IN PRX_CONNECTION_ID RxConnectionId)
Definition: rxce.c:2052
NTSTATUS RxFindOrCreateConnections(_In_ PRX_CONTEXT RxContext, _In_ PUNICODE_STRING CanonicalName, _In_ NET_ROOT_TYPE NetRootType, _Out_ PUNICODE_STRING LocalNetRootName, _Out_ PUNICODE_STRING FilePathName, _Inout_ PLOCK_HOLDING_STATE LockState, _In_ PRX_CONNECTION_ID RxConnectionId)
Definition: rxce.c:3675
NTSTATUS RxConstructNetRoot(IN PRX_CONTEXT RxContext, IN PSRV_CALL SrvCall, IN PNET_ROOT NetRoot, IN PV_NET_ROOT VirtualNetRoot, OUT PLOCK_HOLDING_STATE LockHoldingState)
Definition: rxce.c:1163
Definition: fcb.h:34
RX_BLOCK_CONDITION Condition
Definition: fcb.h:70

Referenced by RxFindOrConstructVirtualNetRoot().

◆ RxCreateNetFcb()

PFCB RxCreateNetFcb ( IN PRX_CONTEXT  RxContext,
IN PV_NET_ROOT  VNetRoot,
IN PUNICODE_STRING  Name 
)

Definition at line 1481 of file rxce.c.

1485{
1486 PFCB Fcb;
1487 BOOLEAN FakeFcb;
1488 PNET_ROOT NetRoot;
1492 PRDBSS_DEVICE_OBJECT RxDeviceObject;
1493
1494 PAGED_CODE();
1495
1496 /* We need a decent VNetRoot */
1497 ASSERT(VNetRoot != NULL && NodeType(VNetRoot) == RDBSS_NTC_V_NETROOT);
1498
1499 NetRoot = (PNET_ROOT)VNetRoot->pNetRoot;
1500 ASSERT(NodeType(NetRoot) == RDBSS_NTC_NETROOT);
1501 ASSERT((PMRX_NET_ROOT)NetRoot == RxContext->Create.pNetRoot);
1502
1503 RxDeviceObject = NetRoot->pSrvCall->RxDeviceObject;
1504 ASSERT(RxDeviceObject == RxContext->RxDeviceObject);
1505
1506 Stack = RxContext->CurrentIrpSp;
1507
1508 /* Do we need to create a fake FCB? Like for renaming */
1509 FakeFcb = BooleanFlagOn(Stack->Flags, SL_OPEN_TARGET_DIRECTORY) &&
1511 ASSERT(FakeFcb || RxIsFcbTableLockExclusive(&NetRoot->FcbTable));
1512
1515
1516 /* Allocate the FCB */
1517 Fcb = RxAllocateFcbObject(RxDeviceObject, NodeType, PoolType,
1518 NetRoot->InnerNamePrefix.Length + Name->Length, NULL);
1519 if (Fcb == NULL)
1520 {
1521 return NULL;
1522 }
1523
1524 /* Initialize the FCB */
1525 Fcb->CachedNetRootType = NetRoot->Type;
1526 Fcb->RxDeviceObject = RxDeviceObject;
1527 Fcb->MRxDispatch = RxDeviceObject->Dispatch;
1528 Fcb->VNetRoot = VNetRoot;
1529 Fcb->pNetRoot = VNetRoot->pNetRoot;
1530
1531 InitializeListHead(&Fcb->SrvOpenList);
1532 Fcb->SrvOpenListVersion = 0;
1533
1534 Fcb->FcbTableEntry.Path.Length = Name->Length;
1536 Fcb->FcbTableEntry.Path.Buffer = Add2Ptr(Fcb->PrivateAlreadyPrefixedName.Buffer, NetRoot->InnerNamePrefix.Length);
1537 RtlMoveMemory(Fcb->PrivateAlreadyPrefixedName.Buffer, NetRoot->InnerNamePrefix.Buffer,
1538 NetRoot->InnerNamePrefix.Length);
1539 RtlMoveMemory(Fcb->FcbTableEntry.Path.Buffer, Name->Buffer, Name->Length);
1540
1541 /* Copy back parameters from RxContext */
1542 if (BooleanFlagOn(RxContext->Create.Flags, RX_CONTEXT_CREATE_FLAG_ADDEDBACKSLASH))
1543 {
1545 }
1546
1548
1550 {
1552 }
1553
1554 if (RxContext->MajorFunction == IRP_MJ_CREATE && BooleanFlagOn(RxContext->Create.Flags, RX_CONTEXT_CREATE_FLAG_SPECIAL_PATH))
1555 {
1557 }
1558
1559 Fcb->Header.Resource = &Fcb->NonPaged->HeaderResource;
1561
1562 Fcb->Header.PagingIoResource = &Fcb->NonPaged->PagingIoResource;
1563 ExInitializeResourceLite(Fcb->Header.PagingIoResource);
1564
1567
1568 /* Fake FCB doesn't go in prefix table */
1569 if (FakeFcb)
1570 {
1573 DPRINT("Fake FCB: %p\n", Fcb);
1574 }
1575 else
1576 {
1577 RxFcbTableInsertFcb(&NetRoot->FcbTable, Fcb);
1578 }
1579
1580 RxReferenceVNetRoot(VNetRoot);
1581 InterlockedIncrement((volatile long *)&Fcb->pNetRoot->NumberOfFcbs);
1582
1584
1585 DPRINT("FCB %p for %wZ\n", Fcb, &Fcb->FcbTableEntry.Path);
1587
1588 return Fcb;
1589}
USHORT NODE_TYPE_CODE
Definition: nodetype.h:22
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define FCB_STATE_PAGING_FILE
Definition: fatstruc.h:1195
#define FCB_STATE_SPECIAL_PATH
Definition: fcb.h:216
#define FCB_STATE_NAME_ALREADY_REMOVED
Definition: fcb.h:227
#define FCB_STATE_FAKEFCB
Definition: fcb.h:211
#define RxReferenceNetFcb(Fcb)
Definition: fcb.h:431
#define FCB_STATE_ADDEDBACKSLASH
Definition: fcb.h:228
#define RxIsFcbTableLockExclusive(T)
Definition: fcbtable.h:58
#define NETROOT_FLAG_SUPPORTS_SYMBOLIC_LINKS
Definition: mrxfcb.h:44
PVOID RxAllocateFcbObject(PRDBSS_DEVICE_OBJECT RxDeviceObject, NODE_TYPE_CODE NodeType, POOL_TYPE PoolType, ULONG NameSize, PVOID AlreadyAllocatedObject)
Definition: rxce.c:316
NTSTATUS RxFcbTableInsertFcb(IN OUT PRX_FCB_TABLE FcbTable, IN OUT PFCB Fcb)
Definition: rxce.c:2492
@ RX_CONTEXT_CREATE_FLAG_SPECIAL_PATH
Definition: rxcontx.h:328
@ RX_CONTEXT_CREATE_FLAG_ADDEDBACKSLASH
Definition: rxcontx.h:326
PERESOURCE Resource
Definition: fcb.h:125
ULONG ulFileSizeVersion
Definition: fcb.h:164
PV_NET_ROOT VNetRoot
Definition: fcb.h:139
FCB_BUFFERED_LOCKS BufferedLocks
Definition: fcb.h:188
RX_FCB_TABLE FcbTable
Definition: fcb.h:54
ERESOURCE BufferedLocksResource
Definition: fcb.h:97
ERESOURCE HeaderResource
Definition: fcb.h:86
ERESOURCE PagingIoResource
Definition: fcb.h:87
LIST_ENTRY TransitionWaitList
Definition: fcb.h:91
LIST_ENTRY HashLinks
Definition: fcbtable.h:9
UNICODE_STRING Path
Definition: fcbtable.h:8
INT POOL_TYPE
Definition: typedefs.h:78
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define SL_OPEN_PAGING_FILE
Definition: iotypes.h:1817
#define SL_OPEN_TARGET_DIRECTORY
Definition: iotypes.h:1818

◆ RxCreateNetFobx()

PMRX_FOBX NTAPI RxCreateNetFobx ( OUT PRX_CONTEXT  RxContext,
IN PMRX_SRV_OPEN  MrxSrvOpen 
)

Definition at line 1596 of file rxce.c.

1599{
1600 PFCB Fcb;
1601 PFOBX Fobx;
1602 ULONG Flags;
1603 PNET_ROOT NetRoot;
1604 PSRV_OPEN SrvOpen;
1606
1607 PAGED_CODE();
1608
1609 SrvOpen = (PSRV_OPEN)MrxSrvOpen;
1610 ASSERT(NodeType(SrvOpen) == RDBSS_NTC_SRVOPEN);
1611 ASSERT(NodeTypeIsFcb(SrvOpen->Fcb));
1613
1614 Fcb = SrvOpen->Fcb;
1616 /* Can we use pre-allocated FOBX? */
1618 {
1619 Fobx = Fcb->InternalFobx;
1620 /* Call allocate to initialize the FOBX */
1622 /* Mark it used now */
1625 }
1626 else if (!BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_FOBX_USED))
1627 {
1628 Fobx = SrvOpen->InternalFobx;
1629 /* Call allocate to initialize the FOBX */
1631 /* Mark it used now */
1632 SrvOpen->Flags |= SRVOPEN_FLAG_FOBX_USED;
1634 }
1635 else
1636 {
1637 /* Last case, we cannot, allocate a FOBX */
1639 Flags = 0;
1640 }
1641
1642 /* Allocation failed! */
1643 if (Fobx == NULL)
1644 {
1645 return NULL;
1646 }
1647
1648 /* Set flags */
1649 Fobx->Flags = Flags;
1650
1651 /* Initialize throttling */
1652 NetRoot = (PNET_ROOT)RxContext->Create.pNetRoot;
1653 if (NetRoot != NULL)
1654 {
1655 if (NetRoot->DeviceType == FILE_DEVICE_DISK)
1656 {
1657 RxInitializeThrottlingState(&Fobx->Specific.DiskFile.LockThrottlingState,
1658 NetRoot->DiskParameters.LockThrottlingParameters.Increment,
1659 NetRoot->DiskParameters.LockThrottlingParameters.MaximumDelay);
1660 }
1661 else if (NetRoot->DeviceType == FILE_DEVICE_NAMED_PIPE)
1662 {
1663 RxInitializeThrottlingState(&Fobx->Specific.NamedPipe.ThrottlingState,
1664 NetRoot->NamedPipeParameters.PipeReadThrottlingParameters.Increment,
1665 NetRoot->NamedPipeParameters.PipeReadThrottlingParameters.MaximumDelay);
1666 }
1667 }
1668
1669 /* Propagate flags fron RxContext */
1670 if (BooleanFlagOn(RxContext->Create.Flags, RX_CONTEXT_CREATE_FLAG_UNC_NAME))
1671 {
1672 Fobx->Flags |= FOBX_FLAG_UNC_NAME;
1673 }
1674
1675 if (BooleanFlagOn(RxContext->Create.NtCreateParameters.CreateOptions, FILE_OPEN_FOR_BACKUP_INTENT))
1676 {
1677 Fobx->Flags |= FOBX_FLAG_BACKUP_INTENT;
1678 }
1679
1680 /* Continue init */
1681 Fobx->FobxSerialNumber = 0;
1682 Fobx->SrvOpen = (PSRV_OPEN)MrxSrvOpen;
1683 Fobx->NodeReferenceCount = 1;
1685
1686 RxReferenceSrvOpen(SrvOpen);
1687 InterlockedIncrement((volatile long *)&SrvOpen->pVNetRoot->NumberOfFobxs);
1688
1689 InsertTailList(&SrvOpen->FobxList, &Fobx->FobxQLinks);
1692
1693 Fobx->CloseTime.QuadPart = 0;
1695
1696 DPRINT("FOBX %p for SRV_OPEN %p FCB %p\n", Fobx, Fobx->SrvOpen, Fobx->SrvOpen->pFcb);
1697
1698 return (PMRX_FOBX)Fobx;
1699}
#define RxInitializeThrottlingState(BP, Inc, MaxDelay)
Definition: backpack.h:13
#define FOBX_FLAG_ENCLOSED_ALLOCATED
Definition: fcb.h:298
#define FCB_STATE_FOBX_USED
Definition: fcb.h:229
struct _SRV_OPEN * PSRV_OPEN
#define FOBX_FLAG_UNC_NAME
Definition: fcb.h:297
#define RxReferenceSrvOpen(SrvOpen)
Definition: fcb.h:423
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
#define FOBX_FLAG_BACKUP_INTENT
Definition: mrxfcb.h:183
#define FILE_DEVICE_NAMED_PIPE
Definition: winioctl.h:123
#define FILE_DEVICE_DISK
Definition: winioctl.h:113
volatile ULONG FobxSerialNumber
Definition: fcb.h:315
LIST_ENTRY FobxQLinks
Definition: fcb.h:316
LIST_ENTRY ClosePendingList
Definition: fcb.h:318
struct _FOBX::@1958::@1962 DiskFile
BOOLEAN fOpenCountDecremented
Definition: fcb.h:322
PSRV_OPEN SrvOpen
Definition: fcb.h:312
LARGE_INTEGER CloseTime
Definition: fcb.h:319
LIST_ENTRY ScavengerFinalizationList
Definition: fcb.h:317
PRDBSS_DEVICE_OBJECT RxDeviceObject
Definition: fcb.h:346
PFCB Fcb
Definition: fcb.h:268
LONGLONG QuadPart
Definition: typedefs.h:114

◆ RxCreateNetRoot()

PNET_ROOT RxCreateNetRoot ( IN PSRV_CALL  SrvCall,
IN PUNICODE_STRING  Name,
IN ULONG  NetRootFlags,
IN PRX_CONNECTION_ID OPTIONAL  RxConnectionId 
)

Definition at line 1705 of file rxce.c.

1710{
1711 PNET_ROOT NetRoot;
1712 USHORT CaseInsensitiveLength;
1713 PRX_PREFIX_TABLE PrefixTable;
1714
1715 DPRINT("RxCreateNetRoot(%p, %wZ, %x, %p)\n", SrvCall, Name, NetRootFlags, RxConnectionId);
1716
1717 PAGED_CODE();
1718
1719 /* We need a SRV_CALL */
1720 ASSERT(SrvCall != NULL);
1721
1722 PrefixTable = SrvCall->RxDeviceObject->pRxNetNameTable;
1724
1725 /* Get name length */
1726 CaseInsensitiveLength = SrvCall->PrefixEntry.Prefix.Length + Name->Length;
1727 if (CaseInsensitiveLength > MAXUSHORT)
1728 {
1729 return NULL;
1730 }
1731
1732 /* Allocate the NetRoot */
1733 NetRoot = RxAllocateObject(RDBSS_NTC_NETROOT, SrvCall->RxDeviceObject->Dispatch,
1734 CaseInsensitiveLength);
1735 if (NetRoot == NULL)
1736 {
1737 return NULL;
1738 }
1739
1740 /* Construct name */
1741 RtlMoveMemory(Add2Ptr(NetRoot->PrefixEntry.Prefix.Buffer, SrvCall->PrefixEntry.Prefix.Length),
1742 Name->Buffer, Name->Length);
1743 if (SrvCall->PrefixEntry.Prefix.Length != 0)
1744 {
1745 RtlMoveMemory(NetRoot->PrefixEntry.Prefix.Buffer, SrvCall->PrefixEntry.Prefix.Buffer,
1746 SrvCall->PrefixEntry.Prefix.Length);
1747 }
1748
1750 {
1751 CaseInsensitiveLength = SrvCall->PrefixEntry.CaseInsensitiveLength;
1752 }
1753 /* Inisert in prefix table */
1754 RxPrefixTableInsertName(PrefixTable, &NetRoot->PrefixEntry, NetRoot,
1755 (PULONG)&NetRoot->NodeReferenceCount, CaseInsensitiveLength,
1756 RxConnectionId);
1757
1758 /* Prepare the FCB table */
1760
1764
1766
1767 NetRoot->SerialNumberForEnum = SerialNumber++;
1768 NetRoot->Flags |= NetRootFlags;
1769 NetRoot->DiskParameters.ClusterSize = 1;
1770 NetRoot->DiskParameters.ReadAheadGranularity = ReadAheadGranularity;
1771 NetRoot->SrvCall = SrvCall;
1772
1773 RxReferenceSrvCall(SrvCall);
1774
1775 DPRINT("NetRootName: %wZ (%p)\n", NetRoot->pNetRootName, NetRoot);
1776 return NetRoot;
1777}
#define SRVCALL_FLAG_CASE_INSENSITIVE_NETROOTS
Definition: mrxfcb.h:11
ULONG ReadAheadGranularity
Definition: rdbss.c:534
PVOID RxAllocateObject(NODE_TYPE_CODE NodeType, PMINIRDR_DISPATCH MRxDispatch, ULONG NameLength)
Definition: rxce.c:541
VOID RxInitializeFcbTable(IN OUT PRX_FCB_TABLE FcbTable, IN BOOLEAN CaseInsensitiveMatch)
Definition: rxce.c:4742
VOID RxInitializePurgeSyncronizationContext(PPURGE_SYNCHRONIZATION_CONTEXT PurgeSyncronizationContext)
Definition: rxce.c:4911
PRX_PREFIX_ENTRY RxPrefixTableInsertName(IN OUT PRX_PREFIX_TABLE ThisTable, IN OUT PRX_PREFIX_ENTRY ThisEntry, IN PVOID Container, IN PULONG ContainerRefCount, IN USHORT CaseInsensitiveLength, IN PRX_CONNECTION_ID ConnectionId)
Definition: rxce.c:6428
LIST_ENTRY ScavengerFinalizationList
Definition: fcb.h:47
PURGE_SYNCHRONIZATION_CONTEXT PurgeSyncronizationContext
Definition: fcb.h:48
ULONG SerialNumberForEnum
Definition: fcb.h:52
LIST_ENTRY TransitionWaitList
Definition: fcb.h:46
RX_PREFIX_ENTRY PrefixEntry
Definition: fcb.h:53
uint32_t * PULONG
Definition: typedefs.h:59
#define MAXUSHORT
Definition: typedefs.h:83

Referenced by RxFindOrCreateConnections().

◆ RxCreateNetRootCallBack()

VOID NTAPI RxCreateNetRootCallBack ( IN PMRX_CREATENETROOT_CONTEXT  CreateNetRootContext)

Definition at line 1784 of file rxce.c.

1786{
1787 PAGED_CODE();
1788
1789 KeSetEvent(&CreateNetRootContext->FinishEvent, IO_NETWORK_INCREMENT, FALSE);
1790}
#define IO_NETWORK_INCREMENT
Definition: tcpip.h:43
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476

Referenced by RxConstructNetRoot().

◆ RxCreateRxContext()

PRX_CONTEXT NTAPI RxCreateRxContext ( IN PIRP  Irp,
IN PRDBSS_DEVICE_OBJECT  RxDeviceObject,
IN ULONG  InitialContextFlags 
)

Definition at line 1797 of file rxce.c.

1801{
1802 KIRQL OldIrql;
1804
1805 ASSERT(RxDeviceObject != NULL);
1806
1807 DPRINT("RxCreateRxContext(%p, %p, %u)\n", Irp, RxDeviceObject, InitialContextFlags);
1808
1809#if DBG
1811#endif
1812 InterlockedIncrement((volatile LONG *)&RxDeviceObject->NumberOfActiveContexts);
1813
1814 /* Allocate the context from our lookaside list */
1815 Context = ExAllocateFromNPagedLookasideList(&RxContextLookasideList);
1816 if (Context == NULL)
1817 {
1818 return NULL;
1819 }
1820
1821 /* Zero it */
1823
1824 /* It was allocated on NP pool, keep track of it! */
1826 /* And initialize it */
1827 RxInitializeContext(Irp, RxDeviceObject, InitialContextFlags, Context);
1829
1830 /* Add it to our global list */
1832 InsertTailList(&RxActiveContexts, &Context->ContextListEntry);
1834
1835 DPRINT("Context: %p\n", Context);
1836 return Context;
1837}
long LONG
Definition: pedump.c:60
ULONG RxFsdEntryCount
Definition: rdbss.c:605
RX_SPIN_LOCK RxStrucSupSpinLock
Definition: rxce.c:123
VOID NTAPI RxInitializeContext(IN PIRP Irp, IN PRDBSS_DEVICE_OBJECT RxDeviceObject, IN ULONG InitialContextFlags, IN OUT PRX_CONTEXT RxContext)
Definition: rxce.c:4529
NPAGED_LOOKASIDE_LIST RxContextLookasideList
Definition: rdbss.c:536
@ RX_CONTEXT_FLAG_FROM_POOL
Definition: rxcontx.h:281
@ RX_CONTEXT_FLAG_MUST_SUCCEED_ALLOCATED
Definition: rxcontx.h:310
LIST_ENTRY RxActiveContexts
Definition: rdbss.c:535

Referenced by RxChangeBufferingState().

◆ RxCreateSrvCall()

PSRV_CALL RxCreateSrvCall ( IN PRX_CONTEXT  RxContext,
IN PUNICODE_STRING  Name,
IN PUNICODE_STRING InnerNamePrefix  OPTIONAL,
IN PRX_CONNECTION_ID  RxConnectionId 
)

Definition at line 1843 of file rxce.c.

1848{
1849 ULONG NameLength;
1850 PSRV_CALL SrvCall;
1851
1852 PAGED_CODE();
1853
1854 DPRINT("RxCreateSrvCall(%p, %wZ, %wZ, %p)\n", RxContext, Name, InnerNamePrefix, RxConnectionId);
1855
1856 ASSERT(RxIsPrefixTableLockExclusive(RxContext->RxDeviceObject->pRxNetNameTable));
1857
1858 /* Get the name length */
1859 NameLength = Name->Length + 2 * sizeof(WCHAR);
1860 if (InnerNamePrefix != NULL)
1861 {
1862 NameLength += InnerNamePrefix->Length;
1863 }
1864
1865 /* Allocate the object */
1866 SrvCall = RxAllocateObject(RDBSS_NTC_SRVCALL, NULL, NameLength);
1867 if (SrvCall == NULL)
1868 {
1869 return NULL;
1870 }
1871
1872 /* Initialize it */
1873 SrvCall->SerialNumberForEnum = SerialNumber++;
1874 SrvCall->RxDeviceObject = RxContext->RxDeviceObject;
1879 RxInitializeSrvCallParameters(RxContext, SrvCall);
1880 RtlMoveMemory(SrvCall->PrefixEntry.Prefix.Buffer, Name->Buffer, Name->Length);
1881 SrvCall->PrefixEntry.Prefix.MaximumLength = Name->Length + 2 * sizeof(WCHAR);
1882 SrvCall->PrefixEntry.Prefix.Length = Name->Length;
1883 RxPrefixTableInsertName(RxContext->RxDeviceObject->pRxNetNameTable, &SrvCall->PrefixEntry,
1884 SrvCall, (PULONG)&SrvCall->NodeReferenceCount, Name->Length, RxConnectionId);
1885
1886 DPRINT("SrvCallName: %wZ (%p)\n", SrvCall->pSrvCallName, SrvCall);
1887 return SrvCall;
1888}
NTSTATUS RxInitializeSrvCallParameters(IN PRX_CONTEXT RxContext, IN OUT PSRV_CALL SrvCall)
Definition: rxce.c:4921
NTSTATUS RxInitializeBufferingManager(PSRV_CALL SrvCall)
Definition: rxce.c:4507
LIST_ENTRY TransitionWaitList
Definition: fcb.h:24
LIST_ENTRY ScavengerFinalizationList
Definition: fcb.h:25
RX_PREFIX_ENTRY PrefixEntry
Definition: fcb.h:20
PURGE_SYNCHRONIZATION_CONTEXT PurgeSyncronizationContext
Definition: fcb.h:26
ULONG SerialNumberForEnum
Definition: fcb.h:22

Referenced by RxFindOrCreateConnections().

◆ RxCreateSrvCallCallBack()

VOID NTAPI RxCreateSrvCallCallBack ( IN OUT PMRX_SRVCALL_CALLBACK_CONTEXT  Context)

Definition at line 1895 of file rxce.c.

1897{
1898 KIRQL OldIrql;
1899 PSRV_CALL SrvCall;
1900 PRX_CONTEXT RxContext;
1901 ULONG NumberRemaining;
1902 BOOLEAN StartDispatcher;
1904
1905 DPRINT("RxCreateSrvCallCallBack(%p)\n", Context);
1906
1907 /* Get our context structures */
1908 Calldown = Context->SrvCalldownStructure;
1909 SrvCall = (PSRV_CALL)Calldown->SrvCall;
1910
1911 /* If it is a success, that's the winner */
1913 if (Context->Status == STATUS_SUCCESS)
1914 {
1915 Calldown->BestFinisherOrdinal = Context->CallbackContextOrdinal;
1916 Calldown->BestFinisher = Context->RxDeviceObject;
1917 }
1918 NumberRemaining = --Calldown->NumberRemaining;
1919 SrvCall->Status = Context->Status;
1921
1922 /* Still some to ask, keep going */
1923 if (NumberRemaining != 0)
1924 {
1925 return;
1926 }
1927
1928 /* If that's not async, signal we're done */
1929 RxContext = Calldown->RxContext;
1931 {
1933 return;
1934 }
1935 /* If that's a mailslot, finish construction, no more to do */
1937 {
1939 return;
1940 }
1941
1942 /* Queue our finish call for delayed completion */
1943 DPRINT("Queuing RxFinishSrvCallConstruction() call\n");
1946 StartDispatcher = !RxSrvCallConstructionDispatcherActive;
1948
1949 /* If we have to start dispatcher, go ahead */
1950 if (StartDispatcher)
1951 {
1953
1956 if (!NT_SUCCESS(Status))
1957 {
1958 /* It failed - run it manually.... */
1960 }
1961 }
1962}
BOOLEAN RxSrvCallConstructionDispatcherActive
Definition: rxce.c:121
VOID NTAPI RxFinishSrvCallConstructionDispatcher(IN PVOID Context)
Definition: rxce.c:4192
NTSTATUS NTAPI RxDispatchToWorkerThread(IN PRDBSS_DEVICE_OBJECT pMRxDeviceObject, IN WORK_QUEUE_TYPE WorkQueueType, IN PRX_WORKERTHREAD_ROUTINE Routine, IN PVOID pContext)
Definition: rxce.c:2401
LIST_ENTRY RxSrvCalldownList
Definition: rxce.c:122
@ RX_CONTEXT_FLAG_CREATE_MAILSLOT
Definition: rxcontx.h:291
@ CriticalWorkQueue
Definition: extypes.h:189

Referenced by RxConstructSrvCall().

◆ RxCreateSrvOpen()

PSRV_OPEN RxCreateSrvOpen ( IN PV_NET_ROOT  VNetRoot,
IN OUT PFCB  Fcb 
)

Definition at line 1968 of file rxce.c.

1971{
1972 ULONG Flags;
1973 PSRV_OPEN SrvOpen;
1975
1976 PAGED_CODE();
1977
1980
1982
1983 _SEH2_TRY
1984 {
1985 SrvOpen = Fcb->InternalSrvOpen;
1986 /* Check whethet we have to allocate a new SRV_OPEN */
1989 !IsListEmpty(&Fcb->InternalSrvOpen->SrvOpenQLinks))
1990 {
1991 /* Proceed */
1992 SrvOpen = RxAllocateFcbObject(Fcb->VNetRoot->NetRoot->pSrvCall->RxDeviceObject,
1994 Flags = 0;
1995 }
1996 else
1997 {
1998 /* Otherwise, just use internal one and initialize it */
1999 RxAllocateFcbObject(Fcb->VNetRoot->NetRoot->pSrvCall->RxDeviceObject,
2004 }
2005
2006 /* If SrvOpen was properly allocated, initialize it */
2007 if (SrvOpen != NULL)
2008 {
2009 SrvOpen->Flags = Flags;
2010 SrvOpen->pFcb = RX_GET_MRX_FCB(Fcb);
2011 SrvOpen->pAlreadyPrefixedName = &Fcb->PrivateAlreadyPrefixedName;
2012 SrvOpen->pVNetRoot = (PMRX_V_NET_ROOT)VNetRoot;
2013 SrvOpen->ulFileSizeVersion = Fcb->ulFileSizeVersion;
2014 SrvOpen->NodeReferenceCount = 1;
2015
2016 RxReferenceVNetRoot(VNetRoot);
2018
2019 InsertTailList(&Fcb->SrvOpenList, &SrvOpen->SrvOpenQLinks);
2020 ++Fcb->SrvOpenListVersion;
2021
2024 InitializeListHead(&SrvOpen->FobxList);
2026 }
2027 }
2029 {
2031 {
2032 if (SrvOpen != NULL)
2033 {
2034 RxFinalizeSrvOpen(SrvOpen, TRUE, TRUE);
2035 SrvOpen = NULL;
2036 }
2037 }
2038 else
2039 {
2040 DPRINT("SrvOpen %p for FCB %p\n", SrvOpen, SrvOpen->pFcb);
2041 }
2042 }
2043 _SEH2_END;
2044
2045 return SrvOpen;
2046}
#define SRVOPEN_FLAG_ENCLOSED_ALLOCATED
Definition: fcb.h:256
#define FCB_STATE_SRVOPEN_USED
Definition: fcb.h:230
struct _MRX_V_NET_ROOT_ * PMRX_V_NET_ROOT
BOOLEAN RxFinalizeSrvOpen(OUT PSRV_OPEN ThisSrvOpen, IN BOOLEAN RecursiveFinalize, IN BOOLEAN ForceFinalize)
Definition: rxce.c:3254
LIST_ENTRY ScavengerFinalizationList
Definition: fcb.h:277
LIST_ENTRY SrvOpenKeyList
Definition: fcb.h:283
LIST_ENTRY TransitionWaitList
Definition: fcb.h:278
PNET_ROOT NetRoot
Definition: fcb.h:65

◆ RxCreateVNetRoot()

PV_NET_ROOT RxCreateVNetRoot ( IN PRX_CONTEXT  RxContext,
IN PNET_ROOT  NetRoot,
IN PUNICODE_STRING  CanonicalName,
IN PUNICODE_STRING  LocalNetRootName,
IN PUNICODE_STRING  FilePath,
IN PRX_CONNECTION_ID  RxConnectionId 
)

Definition at line 2052 of file rxce.c.

2059{
2061 PV_NET_ROOT VNetRoot;
2062 USHORT CaseInsensitiveLength;
2063
2064 PAGED_CODE();
2065
2066 DPRINT("RxCreateVNetRoot(%p, %p, %wZ, %wZ, %wZ, %p)\n", RxContext, NetRoot, CanonicalName,
2067 LocalNetRootName, FilePath, RxConnectionId);
2068
2069 /* Lock must be held exclusively */
2070 ASSERT(RxIsPrefixTableLockExclusive(RxContext->RxDeviceObject->pRxNetNameTable));
2071
2072 /* Check for overflow */
2073 if (LocalNetRootName->Length + NetRoot->PrefixEntry.Prefix.Length > MAXUSHORT)
2074 {
2075 return NULL;
2076 }
2077
2078 /* Get name length and allocate VNetRoot */
2079 CaseInsensitiveLength = LocalNetRootName->Length + NetRoot->PrefixEntry.Prefix.Length;
2080 VNetRoot = RxAllocateObject(RDBSS_NTC_V_NETROOT, NetRoot->SrvCall->RxDeviceObject->Dispatch,
2081 CaseInsensitiveLength);
2082 if (VNetRoot == NULL)
2083 {
2084 return NULL;
2085 }
2086
2087 /* Initialize its connection parameters */
2088 Status = RxInitializeVNetRootParameters(RxContext, &VNetRoot->LogonId, &VNetRoot->SessionId,
2089 &VNetRoot->pUserName, &VNetRoot->pUserDomainName,
2090 &VNetRoot->pPassword, &VNetRoot->Flags);
2091 if (!NT_SUCCESS(Status))
2092 {
2093 RxUninitializeVNetRootParameters(VNetRoot->pUserName, VNetRoot->pUserDomainName,
2094 VNetRoot->pPassword, &VNetRoot->Flags);
2095 RxFreeObject(VNetRoot);
2096
2097 return NULL;
2098 }
2099
2100 /* Set name */
2101 RtlMoveMemory(VNetRoot->PrefixEntry.Prefix.Buffer, CanonicalName->Buffer, VNetRoot->PrefixEntry.Prefix.Length);
2102
2103 VNetRoot->PrefixOffsetInBytes = LocalNetRootName->Length + NetRoot->PrefixEntry.Prefix.Length;
2104 VNetRoot->NamePrefix.Buffer = Add2Ptr(VNetRoot->PrefixEntry.Prefix.Buffer, VNetRoot->PrefixOffsetInBytes);
2105 VNetRoot->NamePrefix.Length = VNetRoot->PrefixEntry.Prefix.Length - VNetRoot->PrefixOffsetInBytes;
2106 VNetRoot->NamePrefix.MaximumLength = VNetRoot->PrefixEntry.Prefix.Length - VNetRoot->PrefixOffsetInBytes;
2107
2110
2111 if (!BooleanFlagOn(NetRoot->SrvCall->Flags, SRVCALL_FLAG_CASE_INSENSITIVE_FILENAMES))
2112 {
2113 USHORT i;
2114
2115 if (BooleanFlagOn(NetRoot->SrvCall->Flags, SRVCALL_FLAG_CASE_INSENSITIVE_NETROOTS))
2116 {
2117 CaseInsensitiveLength = NetRoot->PrefixEntry.CaseInsensitiveLength;
2118 }
2119 else
2120 {
2121 CaseInsensitiveLength = NetRoot->SrvCall->PrefixEntry.CaseInsensitiveLength;
2122 }
2123
2124 for (i = 1; i < CanonicalName->Length / sizeof(WCHAR); ++i)
2125 {
2126 if (CanonicalName->Buffer[i] != OBJ_NAME_PATH_SEPARATOR)
2127 {
2128 break;
2129 }
2130 }
2131
2132 CaseInsensitiveLength += (i * sizeof(WCHAR));
2133 }
2134
2135 /* Insert in prefix table */
2136 RxPrefixTableInsertName(RxContext->RxDeviceObject->pRxNetNameTable, &VNetRoot->PrefixEntry,
2137 VNetRoot, (PULONG)&VNetRoot->NodeReferenceCount, CaseInsensitiveLength,
2138 RxConnectionId);
2139
2140 RxReferenceNetRoot(NetRoot);
2141 RxAddVirtualNetRootToNetRoot(NetRoot, VNetRoot);
2142
2143 /* Finish init */
2144 VNetRoot->SerialNumberForEnum = SerialNumber++;
2145 VNetRoot->UpperFinalizationDone = FALSE;
2148
2149 DPRINT("NamePrefix: %wZ\n", &VNetRoot->NamePrefix);
2150 DPRINT("PrefixEntry: %wZ\n", &VNetRoot->PrefixEntry.Prefix);
2151
2152 return VNetRoot;
2153}
PCWSTR FilePath
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define RxReferenceNetRoot(NetRoot)
Definition: fcb.h:399
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define SRVCALL_FLAG_CASE_INSENSITIVE_FILENAMES
Definition: mrxfcb.h:12
VOID RxAddVirtualNetRootToNetRoot(PNET_ROOT NetRoot, PV_NET_ROOT VNetRoot)
Definition: rxce.c:296
VOID RxUninitializeVNetRootParameters(IN PUNICODE_STRING UserName, IN PUNICODE_STRING UserDomainName, IN PUNICODE_STRING Password, OUT PULONG Flags)
Definition: rxce.c:8680
NTSTATUS RxInitializeVNetRootParameters(PRX_CONTEXT RxContext, OUT LUID *LogonId, OUT PULONG SessionId, OUT PUNICODE_STRING *UserNamePtr, OUT PUNICODE_STRING *UserDomainNamePtr, OUT PUNICODE_STRING *PasswordPtr, OUT PULONG Flags)
Definition: rxce.c:4963
VOID RxFreeObject(PVOID pObject)
Definition: rxce.c:4319
ULONG SerialNumberForEnum
Definition: fcb.h:76
BOOLEAN UpperFinalizationDone
Definition: fcb.h:68
BOOLEAN ConnectionFinalizationDone
Definition: fcb.h:69
ULONG PrefixOffsetInBytes
Definition: fcb.h:74
LIST_ENTRY ScavengerFinalizationList
Definition: fcb.h:78
UNICODE_STRING NamePrefix
Definition: fcb.h:73
RX_PREFIX_ENTRY PrefixEntry
Definition: fcb.h:72
volatile LONG AdditionalReferenceForDeleteFsctlTaken
Definition: fcb.h:71
LIST_ENTRY TransitionWaitList
Definition: fcb.h:77

Referenced by RxConstructVirtualNetRoot(), and RxFindOrCreateConnections().

◆ RxDereference()

VOID RxDereference ( IN OUT PVOID  Instance,
IN LOCK_HOLDING_STATE  LockHoldingState 
)

Definition at line 2159 of file rxce.c.

2162{
2163 LONG RefCount;
2166
2167 PAGED_CODE();
2168
2170
2171 /* Check we have a node we can handle */
2176
2178 RefCount = InterlockedDecrement((volatile long *)&Node->NodeReferenceCount);
2179 ASSERT(RefCount >= 0);
2180
2181 /* Trace refcount */
2182 switch (NodeType)
2183 {
2184 case RDBSS_NTC_SRVCALL:
2185 PRINT_REF_COUNT(SRVCALL, Node->NodeReferenceCount);
2186 break;
2187
2188 case RDBSS_NTC_NETROOT:
2189 PRINT_REF_COUNT(NETROOT, Node->NodeReferenceCount);
2190 break;
2191
2193 PRINT_REF_COUNT(VNETROOT, Node->NodeReferenceCount);
2194 break;
2195
2196 case RDBSS_NTC_SRVOPEN:
2197 PRINT_REF_COUNT(SRVOPEN, Node->NodeReferenceCount);
2198 break;
2199
2200 case RDBSS_NTC_FOBX:
2201 PRINT_REF_COUNT(NETFOBX, Node->NodeReferenceCount);
2202 break;
2203
2204 default:
2205 ASSERT(FALSE);
2206 break;
2207 }
2208
2209 /* No need to free - still in use */
2210 if (RefCount > 1)
2211 {
2213 return;
2214 }
2215
2216 /* We have to be locked exclusively */
2217 if (LockHoldingState != LHS_ExclusiveLockHeld)
2218 {
2219 if ((NodeType == RDBSS_NTC_FOBX && RefCount == 0) ||
2221 {
2223 }
2224
2226 return;
2227 }
2228 else
2229 {
2231 {
2233 }
2234 }
2235
2237
2238 /* Now, deallocate the memory */
2239 switch (NodeType)
2240 {
2241 case RDBSS_NTC_SRVCALL:
2242 {
2243 PSRV_CALL SrvCall;
2244
2245 SrvCall = (PSRV_CALL)Instance;
2246
2247 ASSERT(SrvCall->RxDeviceObject != NULL);
2248 ASSERT(RxIsPrefixTableLockAcquired(SrvCall->RxDeviceObject->pRxNetNameTable));
2249 RxFinalizeSrvCall(SrvCall, TRUE, TRUE);
2250 break;
2251 }
2252
2253 case RDBSS_NTC_NETROOT:
2254 {
2255 PNET_ROOT NetRoot;
2256
2257 NetRoot = (PNET_ROOT)Instance;
2258
2259 ASSERT(NetRoot->pSrvCall->RxDeviceObject != NULL);
2260 ASSERT(RxIsPrefixTableLockAcquired(NetRoot->pSrvCall->RxDeviceObject->pRxNetNameTable));
2261 RxFinalizeNetRoot(NetRoot, TRUE, TRUE);
2262 break;
2263 }
2264
2266 {
2267 PV_NET_ROOT VNetRoot;
2268
2269 VNetRoot = (PV_NET_ROOT)Instance;
2270
2271 ASSERT(VNetRoot->pNetRoot->pSrvCall->RxDeviceObject != NULL);
2272 ASSERT(RxIsPrefixTableLockAcquired(VNetRoot->pNetRoot->pSrvCall->RxDeviceObject->pRxNetNameTable));
2273 RxFinalizeVNetRoot(VNetRoot, TRUE, TRUE);
2274 break;
2275 }
2276
2277 case RDBSS_NTC_SRVOPEN:
2278 {
2279 PSRV_OPEN SrvOpen;
2280
2281 SrvOpen = (PSRV_OPEN)Instance;
2282
2283 ASSERT(RxIsFcbAcquired(SrvOpen->Fcb));
2284 if (SrvOpen->OpenCount == 0)
2285 {
2286 RxFinalizeSrvOpen(SrvOpen, FALSE, FALSE);
2287 }
2288 break;
2289 }
2290
2291 case RDBSS_NTC_FOBX:
2292 {
2293 PFOBX Fobx;
2294
2295 Fobx = (PFOBX)Instance;
2296
2299 break;
2300 }
2301 }
2302}
union node Node
Definition: types.h:1255
#define PRINT_REF_COUNT(TYPE, Count)
Definition: fcb.h:376
BOOLEAN RxFinalizeNetFobx(_Out_ PFOBX ThisFobx, _In_ BOOLEAN RecursiveFinalize, _In_ BOOLEAN ForceFinalize)
Definition: rxce.c:2964
BOOLEAN RxFinalizeSrvCall(OUT PSRV_CALL ThisSrvCall, IN BOOLEAN RecursiveFinalize, IN BOOLEAN ForceFinalize)
Definition: rxce.c:3164
BOOLEAN RxFinalizeNetRoot(OUT PNET_ROOT ThisNetRoot, IN BOOLEAN RecursiveFinalize, IN BOOLEAN ForceFinalize)
Definition: rxce.c:3062
VOID RxpMarkInstanceForScavengedFinalization(PVOID Instance)
Definition: rxce.c:6277
VOID RxpUndoScavengerFinalizationMarking(PVOID Instance)
Definition: rxce.c:6862
BOOLEAN RxFinalizeVNetRoot(OUT PV_NET_ROOT ThisVNetRoot, IN BOOLEAN RecursiveFinalize, IN BOOLEAN ForceFinalize)
Definition: rxce.c:3367
#define RxReleaseScavengerMutex()
Definition: scavengr.h:27
#define RxAcquireScavengerMutex()
Definition: scavengr.h:26
#define RX_SCAVENGER_MASK
Definition: nodetype.h:70
struct _NODE_TYPE_CODE_AND_SIZE * PNODE_TYPE_AND_SIZE
Definition: dlist.c:348
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_WMI_INSTANCE_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_opt_ WDFWMIINSTANCE * Instance
Definition: wdfwmi.h:481

◆ RxDereferenceAndDeleteRxContext_Real()

VOID NTAPI RxDereferenceAndDeleteRxContext_Real ( IN PRX_CONTEXT  RxContext)

Definition at line 2309 of file rxce.c.

2311{
2312 KIRQL OldIrql;
2313 ULONG RefCount;
2315 PRX_CONTEXT StopContext = NULL;
2316
2317 /* Make sure we really have a context */
2319 ASSERT(RxContext->NodeTypeCode == RDBSS_NTC_RX_CONTEXT);
2320 RefCount = InterlockedDecrement((volatile LONG *)&RxContext->ReferenceCount);
2321 /* If refcount is 0, start releasing stuff that needs spinlock held */
2322 if (RefCount == 0)
2323 {
2324 PRDBSS_DEVICE_OBJECT RxDeviceObject;
2325
2327
2328 /* If that's stop context from DO, remove it */
2329 RxDeviceObject = RxContext->RxDeviceObject;
2330 if (RxDeviceObject->StartStopContext.pStopContext == RxContext)
2331 {
2332 RxDeviceObject->StartStopContext.pStopContext = NULL;
2333 }
2334 else
2335 {
2336 /* Remove it from the list */
2337 ASSERT((RxContext->ContextListEntry.Flink->Blink == &RxContext->ContextListEntry) &&
2338 (RxContext->ContextListEntry.Blink->Flink == &RxContext->ContextListEntry));
2339 RemoveEntryList(&RxContext->ContextListEntry);
2340
2341 /* If that was the last active context, save the stop context */
2342 if (InterlockedExchangeAdd((volatile LONG *)&RxDeviceObject->NumberOfActiveContexts, -1) == 0)
2343 {
2344 if (RxDeviceObject->StartStopContext.pStopContext != NULL)
2345 {
2346 StopContext = RxDeviceObject->StartStopContext.pStopContext;
2347 }
2348 }
2349 }
2350 }
2352
2353 /* Now, deal with what can be done without spinlock held */
2354 if (RefCount == 0)
2355 {
2356 /* Refcount shouldn't have changed */
2357 ASSERT(RxContext->ReferenceCount == 0);
2358 /* Reset everything that can be */
2359 RxPrepareContextForReuse(RxContext);
2360
2361#ifdef RDBSS_TRACKER
2362 ASSERT(RxContext->AcquireReleaseFcbTrackerX == 0);
2363#endif
2364 /* If that was the last active, set the event */
2365 if (StopContext != NULL)
2366 {
2367 StopContext->Flags &= ~RX_CONTEXT_FLAG_RECURSIVE_CALL;
2368 KeSetEvent(&StopContext->SyncEvent, IO_NO_INCREMENT, FALSE);
2369 }
2370
2371#if DBG
2372 /* Is ShadowCrit still owned? Shouldn't happen! */
2373 if (RxContext->ShadowCritOwner != 0)
2374 {
2375 DPRINT1("ShadowCritOwner not null! %lx\n", RxContext->ShadowCritOwner);
2376 ASSERT(FALSE);
2377 }
2378#endif
2379
2380 /* If it was allocated, free it */
2381 if (Allocated)
2382 {
2383 ExFreeToNPagedLookasideList(&RxContextLookasideList, RxContext);
2384 }
2385 }
2386}
IN PFCB IN VBO OUT PLBO OUT PULONG OUT PBOOLEAN Allocated
Definition: fatprocs.h:310
#define InterlockedExchangeAdd
Definition: interlocked.h:181
VOID NTAPI RxPrepareContextForReuse(IN OUT PRX_CONTEXT RxContext)
Definition: rxce.c:6583
RDBSS_STARTSTOP_CONTEXT StartStopContext
Definition: rxstruc.h:125
volatile ULONG NumberOfActiveContexts
Definition: rxstruc.h:99
PRX_CONTEXT pStopContext
Definition: rxstruc.h:61
KEVENT SyncEvent
Definition: rxcontx.h:151

Referenced by RxCompleteRequest_Real().

◆ RxDispatchChangeBufferingStateRequests()

VOID NTAPI RxDispatchChangeBufferingStateRequests ( PVOID  Context)

Definition at line 2390 of file rxce.c.

2392{
2394}

Referenced by RxpDispatchChangeBufferingStateRequests().

◆ RxDispatchToWorkerThread()

NTSTATUS NTAPI RxDispatchToWorkerThread ( IN PRDBSS_DEVICE_OBJECT  pMRxDeviceObject,
IN WORK_QUEUE_TYPE  WorkQueueType,
IN PRX_WORKERTHREAD_ROUTINE  Routine,
IN PVOID  pContext 
)

Definition at line 2401 of file rxce.c.

2406{
2408 PRX_WORK_DISPATCH_ITEM DispatchItem;
2409
2410 /* Allocate a bit of context */
2412 if (DispatchItem == NULL)
2413 {
2415 }
2416
2417 /* Set all the routines, the one our dispatcher will call, the one ntoskrnl will call */
2418 DispatchItem->DispatchRoutine = Routine;
2419 DispatchItem->DispatchRoutineParameter = pContext;
2420 DispatchItem->WorkQueueItem.WorkerRoutine = RxWorkItemDispatcher;
2421 DispatchItem->WorkQueueItem.Parameter = DispatchItem;
2422
2423 /* Insert item */
2424 Status = RxInsertWorkQueueItem(pMRxDeviceObject, WorkQueueType, &DispatchItem->WorkQueueItem);
2425 if (!NT_SUCCESS(Status))
2426 {
2427 RxFreePoolWithTag(DispatchItem, RX_WORKQ_POOLTAG);
2428 DPRINT1("RxInsertWorkQueueItem failed! Queue: %ld, Routine: %p, Context: %p, Status: %lx\n", WorkQueueType, Routine, pContext, Status);
2429 }
2430
2431 DPRINT("Dispatching: %p, %p\n", Routine, pContext);
2432
2433 return Status;
2434}
NTSTATUS RxInsertWorkQueueItem(PRDBSS_DEVICE_OBJECT pMRxDeviceObject, WORK_QUEUE_TYPE WorkQueueType, PRX_WORK_QUEUE_ITEM WorkQueueItem)
Definition: rxce.c:5161
VOID NTAPI RxWorkItemDispatcher(PVOID Context)
Definition: rxce.c:8924
#define RX_WORKQ_POOLTAG
Definition: rxpooltg.h:9
RX_WORK_QUEUE_ITEM WorkQueueItem
Definition: rxworkq.h:17
PRX_WORKERTHREAD_ROUTINE DispatchRoutine
Definition: rxworkq.h:18
PVOID DispatchRoutineParameter
Definition: rxworkq.h:19

Referenced by RxCreateSrvCallCallBack(), and RxFinalizeSrvCall().

◆ RxExclusivePrefixTableLockToShared()

VOID RxExclusivePrefixTableLockToShared ( PRX_PREFIX_TABLE  Table)

Definition at line 2440 of file rxce.c.

2442{
2443 PAGED_CODE();
2444
2446}
#define ExConvertExclusiveToSharedLite(res)
Definition: env_spec_w32.h:652
ASMGENDATA Table[]
Definition: genincdata.c:61

Referenced by RxFindOrCreateConnections().

◆ RxExtractServerName()

VOID RxExtractServerName ( IN PUNICODE_STRING  FilePathName,
OUT PUNICODE_STRING  SrvCallName,
OUT PUNICODE_STRING  RestOfName 
)

Definition at line 2452 of file rxce.c.

2456{
2457 USHORT i, Length;
2458
2459 PAGED_CODE();
2460
2461 ASSERT(SrvCallName != NULL);
2462
2463 /* SrvCall name will start from the begin up to the first separator */
2464 SrvCallName->Buffer = FilePathName->Buffer;
2465 for (i = 1; i < FilePathName->Length / sizeof(WCHAR); ++i)
2466 {
2467 if (FilePathName->Buffer[i] == OBJ_NAME_PATH_SEPARATOR)
2468 {
2469 break;
2470 }
2471 }
2472
2473 /* Compute length */
2474 Length = (USHORT)((ULONG_PTR)&FilePathName->Buffer[i] - (ULONG_PTR)FilePathName->Buffer);
2475 SrvCallName->MaximumLength = Length;
2476 SrvCallName->Length = Length;
2477
2478 /* Return the rest if asked */
2479 if (RestOfName != NULL)
2480 {
2481 Length = (USHORT)((ULONG_PTR)&FilePathName->Buffer[FilePathName->Length / sizeof(WCHAR)] - (ULONG_PTR)FilePathName->Buffer[i]);
2482 RestOfName->Buffer = &FilePathName->Buffer[i];
2483 RestOfName->MaximumLength = Length;
2484 RestOfName->Length = Length;
2485 }
2486}
#define ULONG_PTR
Definition: config.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by RxFindOrCreateConnections().

◆ RxFcbTableInsertFcb()

NTSTATUS RxFcbTableInsertFcb ( IN OUT PRX_FCB_TABLE  FcbTable,
IN OUT PFCB  Fcb 
)

Definition at line 2492 of file rxce.c.

2495{
2496 PAGED_CODE();
2497
2498 /* We deal with the table, make sure it's locked */
2500
2501 /* Compute the hash */
2503
2505
2506 /* If no length, it will be our null entry */
2507 if (Fcb->FcbTableEntry.Path.Length == 0)
2508 {
2509 FcbTable->TableEntryForNull = &Fcb->FcbTableEntry;
2510 }
2511 /* Otherwise, insert in the appropriate bucket */
2512 else
2513 {
2514 InsertTailList(FCB_HASH_BUCKET(FcbTable, Fcb->FcbTableEntry.HashValue),
2516 }
2517
2518 /* Propagate the change by incrementing the version number */
2519 InterlockedIncrement((volatile long *)&FcbTable->Version);
2520
2521 return STATUS_SUCCESS;
2522}
ULONG RxTableComputePathHashValue(IN PUNICODE_STRING Name)
Definition: rxce.c:8213
ULONG HashValue
Definition: fcbtable.h:7

Referenced by RxCreateNetFcb().

◆ RxFcbTableLookupFcb()

PFCB RxFcbTableLookupFcb ( IN PRX_FCB_TABLE  FcbTable,
IN PUNICODE_STRING  Path 
)

Definition at line 2528 of file rxce.c.

2531{
2532 PFCB Fcb;
2534
2535 PAGED_CODE();
2536
2537 /* No path - easy, that's null entry */
2538 if (Path == NULL)
2539 {
2540 TableEntry = FcbTable->TableEntryForNull;
2541 }
2542 else
2543 {
2544 ULONG Hash;
2545 PLIST_ENTRY HashBucket, ListEntry;
2546
2547 /* Otherwise, compute the hash value and find the associated bucket */
2549 HashBucket = FCB_HASH_BUCKET(FcbTable, Hash);
2550 /* If the bucket is empty, it means there's no entry yet */
2551 if (IsListEmpty(HashBucket))
2552 {
2553 TableEntry = NULL;
2554 }
2555 else
2556 {
2557 /* Otherwise, browse all the entry */
2558 for (ListEntry = HashBucket->Flink;
2559 ListEntry != HashBucket;
2560 ListEntry = ListEntry->Flink)
2561 {
2562 TableEntry = CONTAINING_RECORD(ListEntry, RX_FCB_TABLE_ENTRY, HashLinks);
2563 InterlockedIncrement(&FcbTable->Compares);
2564
2565 /* If entry hash and string are equal, thatt's the one! */
2566 if (TableEntry->HashValue == Hash &&
2567 TableEntry->Path.Length == Path->Length &&
2568 RtlEqualUnicodeString(Path, &TableEntry->Path, FcbTable->CaseInsensitiveMatch))
2569 {
2570 break;
2571 }
2572 }
2573
2574 /* We reached the end? Not found */
2575 if (ListEntry == HashBucket)
2576 {
2577 TableEntry = NULL;
2578 }
2579 }
2580 }
2581
2582 InterlockedIncrement(&FcbTable->Lookups);
2583
2584 /* If table entry isn't null, return the FCB */
2585 if (TableEntry != NULL)
2586 {
2587 Fcb = CONTAINING_RECORD(TableEntry, FCB, FcbTableEntry);
2589 }
2590 else
2591 {
2592 Fcb = NULL;
2593 InterlockedIncrement(&FcbTable->FailedLookups);
2594 }
2595
2596 return Fcb;
2597}
PRTL_UNICODE_STRING_BUFFER Path
static int Hash(const char *)
Definition: reader.c:2257
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
_Must_inspect_result_ typedef _In_ ULONG TableEntry
Definition: iotypes.h:4303

◆ RxFcbTableRemoveFcb()

NTSTATUS RxFcbTableRemoveFcb ( IN OUT PRX_FCB_TABLE  FcbTable,
IN OUT PFCB  Fcb 
)

Definition at line 2603 of file rxce.c.

2606{
2607 PAGED_CODE();
2608
2610
2611 /* If no path, then remove entry for null */
2612 if (Fcb->FcbTableEntry.Path.Length == 0)
2613 {
2614 FcbTable->TableEntryForNull = NULL;
2615 }
2616 /* Otherwise, remove from the bucket */
2617 else
2618 {
2620 }
2621
2622 /* Reset its list entry */
2624
2625 /* Propagate the change by incrementing the version number */
2626 InterlockedIncrement((volatile long *)&FcbTable->Version);
2627
2628 return STATUS_SUCCESS;
2629}

Referenced by RxFinalizeNetFcb(), and RxRemoveNameNetFcb().

◆ RxFinalizeConnection()

NTSTATUS NTAPI RxFinalizeConnection ( IN OUT PNET_ROOT  NetRoot,
IN OUT PV_NET_ROOT VNetRoot  OPTIONAL,
IN LOGICAL  ForceFilesClosed 
)

Definition at line 2636 of file rxce.c.

2640{
2642 PRX_PREFIX_TABLE PrefixTable;
2643 ULONG UncleanAny, UncleanDir;
2644 LONG FilesOpen, AdditionalRef;
2645 BOOLEAN PrefixLocked, FcbTableLocked, ForceClose;
2646
2647 PAGED_CODE();
2648
2649 ASSERT(NodeType(NetRoot) == RDBSS_NTC_NETROOT);
2650
2651 /* Get a BOOLEAN out of LOGICAL
2652 * -1 is like FALSE but also drops extra V_NET_ROOT reference in case of failure
2653 */
2654 ForceClose = (ForceFilesClosed == TRUE ? TRUE : FALSE);
2655
2656 /* First, delete any notification change */
2658 /* If it failed, continue if forced */
2659 if (Status != STATUS_SUCCESS && !ForceFilesClosed)
2660 {
2661 return Status;
2662 }
2663 /* Reset status, in case notification deletion failed */
2665
2666 PrefixTable = NetRoot->pSrvCall->RxDeviceObject->pRxNetNameTable;
2667
2668 PrefixLocked = FALSE;
2669 FcbTableLocked = FALSE;
2670 FilesOpen = 0;
2671 AdditionalRef = 0;
2672 UncleanAny = 0;
2673 UncleanDir = 0;
2674 _SEH2_TRY
2675 {
2677 PrefixLocked = TRUE;
2678
2679 RxReferenceNetRoot(NetRoot);
2680
2681 RxAcquireFcbTableLockExclusive(&NetRoot->FcbTable, TRUE);
2682 FcbTableLocked = TRUE;
2683
2684 /* If our V_NET_ROOT wasn't finalized yet, proceed! */
2685 if (!VNetRoot->ConnectionFinalizationDone)
2686 {
2687 USHORT Bucket;
2688 PRX_FCB_TABLE FcbTable;
2689
2690 DPRINT("Finalizing connection %p: %wZ\n", NetRoot, &NetRoot->PrefixEntry.Prefix);
2691
2692 /* We'll browse all its associated FCB to check whether they're open/orphaned */
2693 FcbTable = &NetRoot->FcbTable;
2694 for (Bucket = 0; Bucket < FcbTable->NumberOfBuckets; ++Bucket)
2695 {
2696 PLIST_ENTRY BucketList, Entry;
2697
2698 BucketList = &FcbTable->HashBuckets[Bucket];
2699 Entry = BucketList->Flink;
2700 while (Entry != BucketList)
2701 {
2702 PFCB Fcb;
2703
2704 Fcb = CONTAINING_RECORD(Entry, FCB, FcbTableEntry.HashLinks);
2705 Entry = Entry->Flink;
2706
2707 /* FCB for this connection, go ahead */
2708 if (Fcb->VNetRoot == VNetRoot)
2709 {
2710 /* It's still open, and no force? Fail and keep track */
2711 if (Fcb->UncleanCount > 0 && !ForceClose)
2712 {
2715 {
2716 ++UncleanDir;
2717 }
2718 else
2719 {
2720 ++UncleanAny;
2721 }
2722 }
2723 else
2724 {
2725 /* Else, force purge */
2727
2730
2732
2734 RxPurgeFcb(Fcb);
2735
2736 /* We don't need to release FCB lock, FCB finalize will take care of it */
2737 }
2738 }
2739 }
2740 }
2741
2742 /* No files left, our V_NET_ROOT is finalized */
2743 if (VNetRoot->NumberOfFobxs == 0)
2744 {
2745 VNetRoot->ConnectionFinalizationDone = TRUE;
2746 }
2747 }
2748
2749 /* Keep Number of open files and track of the extra reference */
2750 FilesOpen = VNetRoot->NumberOfFobxs;
2751 AdditionalRef = VNetRoot->AdditionalReferenceForDeleteFsctlTaken;
2752 /* If force close, caller doesn't want to keep connection alive
2753 * and wants it totally close, so drop the V_NET_ROOT too
2754 */
2755 if (ForceClose)
2756 {
2757 RxFinalizeVNetRoot(VNetRoot, FALSE, TRUE);
2758 }
2759 }
2761 {
2762 /* Release what was acquired */
2763 if (FcbTableLocked)
2764 {
2765 RxReleaseFcbTableLock(&NetRoot->FcbTable);
2766 }
2767
2768 /* If close is forced, only fix status if there are open files */
2769 if (ForceClose)
2770 {
2771 if (Status != STATUS_SUCCESS && UncleanAny != 0)
2772 {
2774 }
2775 }
2776 /* Else, fix status and fail closing if there are open files */
2777 else
2778 {
2779 if ((Status != STATUS_SUCCESS && UncleanAny != 0) || FilesOpen > 0)
2780 {
2782 }
2783 }
2784
2785 DPRINT("UncleanAny: %ld, UncleanDir: %ld, FilesOpen: %ld\n", UncleanAny, UncleanDir, FilesOpen);
2786
2787 /* If we're are asked to remove the extra ref, or if closing was a success, do it;
2788 * only if it was still referenced!
2789 */
2790 if ((ForceFilesClosed == 0xFF || Status == STATUS_SUCCESS) && AdditionalRef != 0)
2791 {
2792 VNetRoot->AdditionalReferenceForDeleteFsctlTaken = 0;
2794 }
2795
2796 if (PrefixLocked)
2797 {
2799 RxReleasePrefixTableLock(PrefixTable);
2800 }
2801 }
2802 _SEH2_END;
2803
2804 return Status;
2805}
#define RxDereferenceNetRoot(NetRoot, LockHoldingState)
Definition: fcb.h:403
#define FCB_STATE_COLLAPSING_ENABLED
Definition: fcb.h:221
#define RxAcquireFcbTableLockExclusive(T, W)
Definition: fcbtable.h:55
#define RxReleaseFcbTableLock(T)
Definition: fcbtable.h:56
#define STATUS_CONNECTION_IN_USE
Definition: ntstatus.h:500
#define STATUS_FILES_OPEN
Definition: ntstatus.h:499
VOID RxPurgeFcb(IN PFCB Fcb)
Definition: rxce.c:6972
BOOLEAN RxScavengeRelatedFobxs(PFCB Fcb)
Definition: rxce.c:7887
NTSTATUS RxCancelNotifyChangeDirectoryRequestsForVNetRoot(PV_NET_ROOT VNetRoot, BOOLEAN ForceFilesClosed)
Definition: rdbss.c:1040
#define RDBSS_NTC_STORAGE_TYPE_DIRECTORY
Definition: nodetype.h:42
base of all file and directory entries
Definition: entries.h:83
LIST_ENTRY HashBuckets[RX_FCB_TABLE_NUMBER_OF_HASH_BUCKETS]
Definition: fcbtable.h:27
USHORT NumberOfBuckets
Definition: fcbtable.h:21

◆ RxFinalizeFcbTable()

VOID RxFinalizeFcbTable ( IN OUT PRX_FCB_TABLE  FcbTable)

Definition at line 2811 of file rxce.c.

2813{
2814 USHORT Bucket;
2815
2816 PAGED_CODE();
2817
2818 /* Just delete the lock */
2819 ExDeleteResourceLite(&FcbTable->TableLock);
2820
2821 /* And make sure (checked) that the table is really empty... */
2822 for (Bucket = 0; Bucket < FcbTable->NumberOfBuckets; ++Bucket)
2823 {
2824 ASSERT(IsListEmpty(&FcbTable->HashBuckets[Bucket]));
2825 }
2826}
#define ExDeleteResourceLite(res)
Definition: env_spec_w32.h:647

Referenced by RxFinalizeNetRoot().

◆ RxFinalizeNetFcb()

BOOLEAN RxFinalizeNetFcb ( OUT PFCB  ThisFcb,
IN BOOLEAN  RecursiveFinalize,
IN BOOLEAN  ForceFinalize,
IN LONG  ReferenceCount 
)

Definition at line 2832 of file rxce.c.

2837{
2838 PAGED_CODE();
2839
2840 DPRINT("RxFinalizeNetFcb(%p, %d, %d, %d)\n", ThisFcb, RecursiveFinalize, ForceFinalize, ReferenceCount);
2841 DPRINT("Finalize: %wZ\n", &ThisFcb->FcbTableEntry.Path);
2842
2843 /* Make sure we have an exclusively acquired FCB */
2846
2847 /* We shouldn't force finalization... */
2848 ASSERT(!ForceFinalize);
2849
2850 /* If recurisve, finalize all the associated SRV_OPEN */
2851 if (RecursiveFinalize)
2852 {
2853 PLIST_ENTRY ListEntry;
2854
2855 for (ListEntry = ThisFcb->SrvOpenList.Flink;
2856 ListEntry != &ThisFcb->SrvOpenList;
2857 ListEntry = ListEntry->Flink)
2858 {
2859 PSRV_OPEN SrvOpen;
2860
2861 SrvOpen = CONTAINING_RECORD(ListEntry, SRV_OPEN, SrvOpenQLinks);
2862 RxFinalizeSrvOpen(SrvOpen, TRUE, ForceFinalize);
2863 }
2864 }
2865 /* If FCB is still in use, that's over */
2866 else
2867 {
2868 if (ThisFcb->OpenCount != 0 || ThisFcb->UncleanCount != 0)
2869 {
2870 ASSERT(ReferenceCount > 0);
2871
2872 return FALSE;
2873 }
2874 }
2875
2876 ASSERT(ReferenceCount >= 1);
2877
2878 /* If FCB is still referenced, that's over - unless you force it and want to BSOD somewhere */
2879 if (ReferenceCount != 1 && !ForceFinalize)
2880 {
2881 return FALSE;
2882 }
2883
2884 ASSERT(ForceFinalize || ((ThisFcb->OpenCount == 0) && (ThisFcb->UncleanCount == 0)));
2885
2886 DPRINT("Finalizing FCB open: %d (%d)\n", ThisFcb->OpenCount, ForceFinalize);
2887
2888 /* If finalization was not already initiated, go ahead */
2889 if (!ThisFcb->UpperFinalizationDone)
2890 {
2891 /* Free any FCB_LOCK */
2892 if (NodeType(ThisFcb) == RDBSS_NTC_STORAGE_TYPE_FILE)
2893 {
2894 FsRtlUninitializeFileLock(&ThisFcb->Specific.Fcb.FileLock);
2895
2896 while (ThisFcb->BufferedLocks.List != NULL)
2897 {
2899
2900 Entry = ThisFcb->BufferedLocks.List;
2901 ThisFcb->BufferedLocks.List = Entry->Next;
2902
2904 }
2905 }
2906
2907 /* If not orphaned, it still has a NET_ROOT and potentially is still in a table */
2908 if (!BooleanFlagOn(ThisFcb->FcbState, FCB_STATE_ORPHANED))
2909 {
2910 PNET_ROOT NetRoot;
2911
2912 NetRoot = (PNET_ROOT)ThisFcb->pNetRoot;
2913
2915 /* So, remove it */
2916 if (!BooleanFlagOn(ThisFcb->FcbState, FCB_STATE_NAME_ALREADY_REMOVED))
2917 {
2918 RxFcbTableRemoveFcb(&NetRoot->FcbTable, ThisFcb);
2919 }
2920 }
2921
2922 ThisFcb->UpperFinalizationDone = TRUE;
2923 }
2924
2925 ASSERT(ReferenceCount >= 1);
2926
2927 /* Even if forced, don't allow broken free */
2928 if (ReferenceCount != 1)
2929 {
2930 return FALSE;
2931 }
2932
2933 /* Now, release everything */
2934 if (ThisFcb->pBufferingStateChangeCompletedEvent != NULL)
2935 {
2936 RxFreePool(ThisFcb->pBufferingStateChangeCompletedEvent);
2937 }
2938
2939 if (ThisFcb->MRxDispatch != NULL)
2940 {
2941 ThisFcb->MRxDispatch->MRxDeallocateForFcb(RX_GET_MRX_FCB(ThisFcb));
2942 }
2943
2944 ExDeleteResourceLite(ThisFcb->BufferedLocks.Resource);
2945 ExDeleteResourceLite(ThisFcb->Header.Resource);
2946 ExDeleteResourceLite(ThisFcb->Header.PagingIoResource);
2947
2948 InterlockedDecrement((volatile long *)&ThisFcb->pNetRoot->NumberOfFcbs);
2949 RxDereferenceVNetRoot(ThisFcb->VNetRoot, LHS_LockNotHeld);
2950
2951 ASSERT(IsListEmpty(&ThisFcb->FcbTableEntry.HashLinks));
2952 ASSERT(!ThisFcb->fMiniInited);
2953
2954 /* And free the object */
2955 RxFreeFcbObject(ThisFcb);
2956
2957 return TRUE;
2958}
#define FCB_STATE_ORPHANED
Definition: fcb.h:208
VOID NTAPI FsRtlUninitializeFileLock(IN PFILE_LOCK FileLock)
Definition: filelock.c:1279
#define RxFreePool
Definition: ntrxdef.h:26
NTSTATUS RxFcbTableRemoveFcb(IN OUT PRX_FCB_TABLE FcbTable, IN OUT PFCB Fcb)
Definition: rxce.c:2603
VOID RxFreeFcbObject(PVOID Object)
Definition: rxce.c:4274
#define RDBSS_NTC_STORAGE_TYPE_FILE
Definition: nodetype.h:43
Definition: fcb.h:113

Referenced by RxpDereferenceAndFinalizeNetFcb().

◆ RxFinalizeNetFobx()

BOOLEAN RxFinalizeNetFobx ( _Out_ PFOBX  ThisFobx,
_In_ BOOLEAN  RecursiveFinalize,
_In_ BOOLEAN  ForceFinalize 
)

Definition at line 2964 of file rxce.c.

2968{
2969 PFCB Fcb;
2970 PSRV_OPEN SrvOpen;
2971
2972 PAGED_CODE();
2973
2974 ASSERT(NodeType(ThisFobx) == RDBSS_NTC_FOBX);
2975
2976 /* Only finalize if forced or if there's no ref left */
2977 if (ThisFobx->NodeReferenceCount != 0 &&
2978 !ForceFinalize)
2979 {
2980 return FALSE;
2981 }
2982
2983 DPRINT("Finalize Fobx: %p (with %d ref), forced: %d\n", ThisFobx, ThisFobx->NodeReferenceCount, ForceFinalize);
2984
2985 SrvOpen = ThisFobx->SrvOpen;
2986 Fcb = SrvOpen->Fcb;
2987 /* If it wasn't finalized yet, do it */
2988 if (!ThisFobx->UpperFinalizationDone)
2989 {
2992
2993 /* Remove it from the SRV_OPEN */
2994 RemoveEntryList(&ThisFobx->FobxQLinks);
2995
2996 /* If we were used to browse a directory, free the query buffer */
2997 if (BooleanFlagOn(ThisFobx->Flags, FOBX_FLAG_FREE_UNICODE))
2998 {
2999 RxFreePoolWithTag(ThisFobx->UnicodeQueryTemplate.Buffer, RX_DIRCTL_POOLTAG);
3000 }
3001
3002 /* Notify the mini-rdr */
3004 {
3006 }
3007
3008 /* If the SRV_OPEN wasn't closed yet, do it */
3009 if (!BooleanFlagOn(ThisFobx->Flags, FOBX_FLAG_SRVOPEN_CLOSED))
3010 {
3012
3014 DPRINT("Closing SRV_OPEN %p for %p: %x\n", SrvOpen, ThisFobx, Status);
3015 }
3016
3017 /* Finalization done */
3018 ThisFobx->UpperFinalizationDone = TRUE;
3019 }
3020
3021 /* If we're still referenced, don't go any further! */
3022 if (ThisFobx->NodeReferenceCount != 0)
3023 {
3024 return FALSE;
3025 }
3026
3027 /* At that point, everything should be closed */
3028 ASSERT(IsListEmpty(&ThisFobx->ClosePendingList));
3029
3030 /* Was the FOBX allocated with another object?
3031 * If so, mark the buffer free in said object
3032 */
3033 if (ThisFobx == Fcb->InternalFobx)
3034 {
3036 }
3037 else if (ThisFobx == SrvOpen->InternalFobx)
3038 {
3039 ClearFlag(SrvOpen->Flags, SRVOPEN_FLAG_FOBX_USED);
3040 }
3041
3042 ThisFobx->pSrvOpen = NULL;
3043
3044 /* A FOBX less */
3045 InterlockedDecrement((volatile long *)&SrvOpen->pVNetRoot->NumberOfFobxs);
3046
3048
3049 /* If it wasn't allocated with another object, free the FOBX */
3050 if (!BooleanFlagOn(ThisFobx->Flags, FOBX_FLAG_ENCLOSED_ALLOCATED))
3051 {
3052 RxFreeFcbObject(ThisFobx);
3053 }
3054
3055 return TRUE;
3056}
#define RxDereferenceSrvOpen(SrvOpen, LockHoldingState)
Definition: fcb.h:427
#define FOBX_FLAG_FREE_UNICODE
Definition: fcb.h:290
#define FOBX_FLAG_SRVOPEN_CLOSED
Definition: fcb.h:296
#define RX_DIRCTL_POOLTAG
Definition: rxpooltg.h:20
PMRX_DEALLOCATE_FOR_FOBX MRxDeallocateForFobx
Definition: mrx.h:360

Referenced by RxDereference(), RxFinalizeSrvOpen(), and RxScavengeRelatedFobxs().

◆ RxFinalizeNetRoot()

BOOLEAN RxFinalizeNetRoot ( OUT PNET_ROOT  ThisNetRoot,
IN BOOLEAN  RecursiveFinalize,
IN BOOLEAN  ForceFinalize 
)

Definition at line 3062 of file rxce.c.

3066{
3067 PSRV_CALL SrvCall;
3068 PRX_FCB_TABLE FcbTable;
3069 PRX_PREFIX_TABLE PrefixTable;
3070
3071 PAGED_CODE();
3072
3073 ASSERT(NodeType(ThisNetRoot) == RDBSS_NTC_NETROOT);
3074
3075 PrefixTable = ThisNetRoot->pSrvCall->RxDeviceObject->pRxNetNameTable;
3076 ASSERT(RxIsPrefixTableLockAcquired(PrefixTable));
3077
3078 /* If sme finalization is already ongoing, leave */
3080 {
3081 return FALSE;
3082 }
3083
3084 /* Mark we're finalizing */
3086
3087 FcbTable = &ThisNetRoot->FcbTable;
3088 /* Did caller asked us to finalize any associated FCB? */
3089 if (RecursiveFinalize)
3090 {
3091 USHORT Bucket;
3092
3093 /* Browse all the FCBs in our FCB table */
3095 for (Bucket = 0; Bucket < FcbTable->NumberOfBuckets; ++Bucket)
3096 {
3097 PLIST_ENTRY HashBucket, ListEntry;
3098
3099 HashBucket = &FcbTable->HashBuckets[Bucket];
3100 ListEntry = HashBucket->Flink;
3101 while (ListEntry != HashBucket)
3102 {
3103 PFCB Fcb;
3104
3105 Fcb = CONTAINING_RECORD(ListEntry, FCB, FcbTableEntry.HashLinks);
3107
3108 ListEntry = ListEntry->Flink;
3109
3110 /* If the FCB isn't orphaned, then, it's time to purge it */
3112 {
3114
3117 RxPurgeFcb(Fcb);
3118 }
3119 }
3120 }
3121 RxReleaseFcbTableLock(FcbTable);
3122 }
3123
3124 /* Only finalize if forced or if there's a single ref left */
3125 if (ThisNetRoot->NodeReferenceCount != 1 && !ForceFinalize)
3126 {
3127 return FALSE;
3128 }
3129
3130 DPRINT("Finalizing NetRoot %p for %wZ\n", ThisNetRoot, &ThisNetRoot->PrefixEntry.Prefix);
3131
3132 /* If we're still referenced, don't go any further! */
3133 if (ThisNetRoot->NodeReferenceCount != 1)
3134 {
3135 return FALSE;
3136 }
3137
3138 /* Finalize the FCB table (and make sure it's empty!) */
3139 RxFinalizeFcbTable(FcbTable);
3140
3141 /* If name wasn't remove already, do it now */
3142 if (!BooleanFlagOn(ThisNetRoot->Flags, NETROOT_FLAG_NAME_ALREADY_REMOVED))
3143 {
3144 RxRemovePrefixTableEntry(PrefixTable, &ThisNetRoot->PrefixEntry);
3145 }
3146
3147 /* Delete the object */
3148 SrvCall = (PSRV_CALL)ThisNetRoot->pSrvCall;
3149 RxFreeObject(ThisNetRoot);
3150
3151 /* And dereference the associated SRV_CALL */
3152 if (SrvCall != NULL)
3153 {
3155 }
3156
3157 return TRUE;
3158}
#define NETROOT_FLAG_NAME_ALREADY_REMOVED
Definition: fcb.h:31
#define NETROOT_FLAG_FINALIZATION_IN_PROGRESS
Definition: fcb.h:30
#define RxDereferenceSrvCall(SrvCall, LockHoldingState)
Definition: fcb.h:395
VOID RxFinalizeFcbTable(IN OUT PRX_FCB_TABLE FcbTable)
Definition: rxce.c:2811
VOID RxRemovePrefixTableEntry(IN OUT PRX_PREFIX_TABLE ThisTable, IN OUT PRX_PREFIX_ENTRY Entry)
Definition: rxce.c:7655

Referenced by RxDereference(), and RxFindOrCreateConnections().

◆ RxFinalizeSrvCall()

BOOLEAN RxFinalizeSrvCall ( OUT PSRV_CALL  ThisSrvCall,
IN BOOLEAN  RecursiveFinalize,
IN BOOLEAN  ForceFinalize 
)

Definition at line 3164 of file rxce.c.

3168{
3169 PRX_PREFIX_TABLE PrefixTable;
3170
3171 PAGED_CODE();
3172
3173 ASSERT(NodeType(ThisSrvCall) == RDBSS_NTC_SRVCALL);
3174
3175 PrefixTable = ThisSrvCall->RxDeviceObject->pRxNetNameTable;
3176 ASSERT(RxIsPrefixTableLockAcquired(PrefixTable));
3177
3178 /* Only finalize if forced or if there's a single ref left */
3179 if (ThisSrvCall->NodeReferenceCount != 1 &&
3180 !ForceFinalize)
3181 {
3182 return FALSE;
3183 }
3184
3185 DPRINT("Finalizing SrvCall %p for %wZ\n", ThisSrvCall, &ThisSrvCall->PrefixEntry.Prefix);
3186
3187 /* If it wasn't finalized yet, do it */
3188 if (!ThisSrvCall->UpperFinalizationDone)
3189 {
3190 BOOLEAN WillFree;
3191
3192 /* Remove ourselves from prefix table */
3193 RxRemovePrefixTableEntry(PrefixTable, &ThisSrvCall->PrefixEntry);
3194
3195 /* Remember our third arg, in case we get queued for later execution */
3196 if (ForceFinalize)
3197 {
3198 SetFlag(ThisSrvCall->Flags, SRVCALL_FLAG_FORCE_FINALIZED);
3199 }
3200
3201 /* And done */
3202 ThisSrvCall->UpperFinalizationDone = TRUE;
3203
3204 /* Would defered execution free the object? */
3205 WillFree = (ThisSrvCall->NodeReferenceCount == 1);
3206
3207 /* If we have a device object */
3208 if (ThisSrvCall->RxDeviceObject != NULL)
3209 {
3211
3212 /* If we're not executing in the RDBSS thread, queue for execution within the thread */
3214 {
3215 /* Extra ref, as usual */
3216 InterlockedIncrement((volatile long *)&ThisSrvCall->NodeReferenceCount);
3217 /* And dispatch */
3218 RxDispatchToWorkerThread(ThisSrvCall->RxDeviceObject, DelayedWorkQueue, RxpDestroySrvCall, ThisSrvCall);
3219
3220 /* Return to the caller, in advance, whether we're freeing the object or not */
3221 return WillFree;
3222 }
3223
3224 /* If in the right thread already, call the mini-rdr */
3225 MINIRDR_CALL_THROUGH(Status, ThisSrvCall->RxDeviceObject->Dispatch,
3226 MRxFinalizeSrvCall, ((PMRX_SRV_CALL)ThisSrvCall, ForceFinalize));
3227 (void)Status;
3228 }
3229 }
3230
3231 /* If we're still referenced, don't go any further! */
3232 if (ThisSrvCall->NodeReferenceCount != 1)
3233 {
3234 return FALSE;
3235 }
3236
3237 /* Don't leak */
3238 if (ThisSrvCall->pDomainName != NULL)
3239 {
3240 RxFreePool(ThisSrvCall->pDomainName);
3241 }
3242
3243 /* And free! */
3244 RxTearDownBufferingManager(ThisSrvCall);
3245 RxFreeObject(ThisSrvCall);
3246
3247 return TRUE;
3248}
#define SRVCALL_FLAG_FORCE_FINALIZED
Definition: mrxfcb.h:14
PEPROCESS NTAPI IoGetCurrentProcess(VOID)
Definition: util.c:139
PEPROCESS NTAPI RxGetRDBSSProcess(VOID)
Definition: rxce.c:4497
VOID NTAPI RxpDestroySrvCall(IN PVOID Context)
Definition: rxce.c:6031
NTSTATUS RxTearDownBufferingManager(PSRV_CALL SrvCall)
Definition: rxce.c:8488
@ DelayedWorkQueue
Definition: extypes.h:190

Referenced by RxDereference(), and RxpDestroySrvCall().

◆ RxFinalizeSrvOpen()

BOOLEAN RxFinalizeSrvOpen ( OUT PSRV_OPEN  ThisSrvOpen,
IN BOOLEAN  RecursiveFinalize,
IN BOOLEAN  ForceFinalize 
)

Definition at line 3254 of file rxce.c.

3258{
3259 PFCB Fcb;
3260
3261 PAGED_CODE();
3262
3263 /* We have to have a SRV_OPEN */
3264 ASSERT(NodeType(ThisSrvOpen) == RDBSS_NTC_SRVOPEN);
3265
3266 /* If that's a recursive finalization, finalize any related FOBX */
3267 if (RecursiveFinalize)
3268 {
3269 PLIST_ENTRY ListEntry;
3270
3271 ListEntry = ThisSrvOpen->FobxList.Flink;
3272 while (ListEntry != &ThisSrvOpen->FobxList)
3273 {
3274 PFOBX Fobx;
3275
3276 Fobx = CONTAINING_RECORD(ListEntry, FOBX, FobxQLinks);
3277 ListEntry = ListEntry->Flink;
3278 RxFinalizeNetFobx(Fobx, TRUE, ForceFinalize);
3279 }
3280 }
3281
3282 /* If we have still references, don't finalize unless forced */
3283 if (ThisSrvOpen->NodeReferenceCount != 0 &&
3284 !ForceFinalize)
3285 {
3286 return FALSE;
3287 }
3288
3289 DPRINT("Finalize SRV_OPEN: %p (with %d ref), forced: %d\n", ThisSrvOpen, ThisSrvOpen->NodeReferenceCount, ForceFinalize);
3290
3291 /* Only finalize if closed, or if it wasn't already done and SRV_OPEN is in a bad shape */
3292 Fcb = (PFCB)ThisSrvOpen->pFcb;
3293 if ((!ThisSrvOpen->UpperFinalizationDone && ThisSrvOpen->Condition != Condition_Good) ||
3294 BooleanFlagOn(ThisSrvOpen->Flags, SRVOPEN_FLAG_CLOSED))
3295 {
3296 PV_NET_ROOT VNetRoot;
3297
3298 /* Associated FCB can't be fake one */
3301
3302 /* Purge any pending operation */
3304
3305 /* If the FCB wasn't orphaned, inform the mini-rdr about close */
3307 {
3309
3310 MINIRDR_CALL_THROUGH(Status, Fcb->MRxDispatch, MRxForceClosed, ((PMRX_SRV_OPEN)ThisSrvOpen));
3311 (void)Status;
3312 }
3313
3314 /* Remove ourselves from the FCB */
3315 RemoveEntryList(&ThisSrvOpen->SrvOpenQLinks);
3316 InitializeListHead(&ThisSrvOpen->SrvOpenQLinks);
3317 ++Fcb->SrvOpenListVersion;
3318
3319 /* If we have a V_NET_ROOT, dereference it */
3320 VNetRoot = (PV_NET_ROOT)ThisSrvOpen->pVNetRoot;
3321 if (VNetRoot != NULL)
3322 {
3323 InterlockedDecrement((volatile long *)&VNetRoot->pNetRoot->NumberOfSrvOpens);
3325 ThisSrvOpen->pVNetRoot = NULL;
3326 }
3327
3328 /* Finalization done */
3329 ThisSrvOpen->UpperFinalizationDone = TRUE;
3330 }
3331
3332 /* Don't free memory if still referenced */
3333 if (ThisSrvOpen->NodeReferenceCount != 0)
3334 {
3335 return FALSE;
3336 }
3337
3338 /* No key association left */
3339 ASSERT(IsListEmpty(&ThisSrvOpen->SrvOpenKeyList));
3340
3341 /* If we're still in some FCB, remove us */
3342 if (!IsListEmpty(&ThisSrvOpen->SrvOpenQLinks))
3343 {
3344 RemoveEntryList(&ThisSrvOpen->SrvOpenQLinks);
3345 }
3346
3347 /* If enclosed allocation, mark the memory zone free */
3348 if (BooleanFlagOn(ThisSrvOpen->Flags, SRVOPEN_FLAG_ENCLOSED_ALLOCATED))
3349 {
3351 }
3352 /* Otherwise, free the memory */
3353 else
3354 {
3355 RxFreeFcbObject(ThisSrvOpen);
3356 }
3357
3359
3360 return TRUE;
3361}
#define RxDereferenceNetFcb(Fcb)
Definition: fcb.h:435
#define SRVOPEN_FLAG_CLOSED
Definition: mrxfcb.h:132
VOID RxPurgeChangeBufferingStateRequestsForSrvOpen(PSRV_OPEN SrvOpen)
Definition: rxce.c:6924

Referenced by RxCreateSrvOpen(), RxDereference(), and RxFinalizeNetFcb().

◆ RxFinalizeVNetRoot()

BOOLEAN RxFinalizeVNetRoot ( OUT PV_NET_ROOT  ThisVNetRoot,
IN BOOLEAN  RecursiveFinalize,
IN BOOLEAN  ForceFinalize 
)

Definition at line 3367 of file rxce.c.

3371{
3372 PNET_ROOT NetRoot;
3373 PRX_PREFIX_TABLE PrefixTable;
3374
3375 PAGED_CODE();
3376
3377 ASSERT(NodeType(ThisVNetRoot) == RDBSS_NTC_V_NETROOT);
3378
3379 PrefixTable = ThisVNetRoot->pNetRoot->pSrvCall->RxDeviceObject->pRxNetNameTable;
3380 ASSERT(RxIsPrefixTableLockAcquired(PrefixTable));
3381
3382 /* Only finalize if forced or if there's a single ref left */
3383 if (ThisVNetRoot->NodeReferenceCount != 1 &&
3384 !ForceFinalize)
3385 {
3386 return FALSE;
3387 }
3388
3389 DPRINT("Finalizing VNetRoot %p for %wZ\n", ThisVNetRoot, &ThisVNetRoot->PrefixEntry.Prefix);
3390
3391 NetRoot = (PNET_ROOT)ThisVNetRoot->pNetRoot;
3392 /* If it wasn't finalized yet, do it */
3393 if (!ThisVNetRoot->UpperFinalizationDone)
3394 {
3395 ASSERT(NodeType(NetRoot) == RDBSS_NTC_NETROOT);
3396
3397 /* Reference the NetRoot so that it doesn't disappear */
3398 RxReferenceNetRoot(NetRoot);
3399 RxOrphanSrvOpens(ThisVNetRoot);
3400 /* Remove us from the available VNetRoot for NetRoot */
3401 RxRemoveVirtualNetRootFromNetRoot(NetRoot, ThisVNetRoot);
3402 /* Remove extra ref */
3404
3405 /* Remove ourselves from prefix table */
3406 RxRemovePrefixTableEntry(PrefixTable, &ThisVNetRoot->PrefixEntry);
3407
3408 /* Finalization done */
3409 ThisVNetRoot->UpperFinalizationDone = TRUE;
3410 }
3411
3412 /* If we're still referenced, don't go any further! */
3413 if (ThisVNetRoot->NodeReferenceCount != 1)
3414 {
3415 return FALSE;
3416 }
3417
3418 /* If there's an associated device, notify mini-rdr */
3419 if (NetRoot->pSrvCall->RxDeviceObject != NULL)
3420 {
3422
3423 MINIRDR_CALL_THROUGH(Status, NetRoot->pSrvCall->RxDeviceObject->Dispatch,
3424 MRxFinalizeVNetRoot, ((PMRX_V_NET_ROOT)ThisVNetRoot, FALSE));
3425 (void)Status;
3426 }
3427
3428 /* Free parameters */
3429 RxUninitializeVNetRootParameters(ThisVNetRoot->pUserName, ThisVNetRoot->pUserDomainName,
3430 ThisVNetRoot->pPassword, &ThisVNetRoot->Flags);
3431 /* Dereference our NetRoot, we won't reference it anymore */
3433
3434 /* And free the object! */
3435 RxFreePoolWithTag(ThisVNetRoot, RX_V_NETROOT_POOLTAG);
3436
3437 return TRUE;
3438}
VOID RxOrphanSrvOpens(IN PV_NET_ROOT ThisVNetRoot)
Definition: rxce.c:5817
VOID RxRemoveVirtualNetRootFromNetRoot(PNET_ROOT NetRoot, PV_NET_ROOT VNetRoot)
Definition: rxce.c:7686

Referenced by RxDereference(), and RxFinalizeConnection().

◆ RxFindOrConstructVirtualNetRoot()

NTSTATUS RxFindOrConstructVirtualNetRoot ( IN PRX_CONTEXT  RxContext,
IN PUNICODE_STRING  CanonicalName,
IN NET_ROOT_TYPE  NetRootType,
IN PUNICODE_STRING  RemainingName 
)

Definition at line 3441 of file rxce.c.

3446{
3447 ULONG Flags;
3449 PVOID Container;
3450 BOOLEAN Construct;
3451 PV_NET_ROOT VNetRoot;
3452 RX_CONNECTION_ID ConnectionID;
3453 PRDBSS_DEVICE_OBJECT RxDeviceObject;
3454 LOCK_HOLDING_STATE LockHoldingState;
3455
3456 PAGED_CODE();
3457
3458 RxDeviceObject = RxContext->RxDeviceObject;
3459 ASSERT(RxDeviceObject->Dispatch != NULL);
3461
3462 /* Ask the mini-rdr for connection ID */
3463 ConnectionID.SessionID = 0;
3464 if (RxDeviceObject->Dispatch->MRxGetConnectionId != NULL)
3465 {
3466 Status = RxDeviceObject->Dispatch->MRxGetConnectionId(RxContext, &ConnectionID);
3468 {
3469 /* mini-rdr is expected not to fail - unless it's not implemented */
3470 DPRINT1("Failed to initialize connection ID\n");
3471 ASSERT(FALSE);
3472 }
3473 }
3474
3475 RxContext->Create.NetNamePrefixEntry = NULL;
3476
3479 LockHoldingState = LHS_SharedLockHeld;
3480 Construct = TRUE;
3481 Flags = 0;
3482
3483 /* We will try twice to find a matching VNetRoot: shared locked and then exlusively locked */
3484 while (TRUE)
3485 {
3486 PNET_ROOT NetRoot;
3487 PV_NET_ROOT SavedVNetRoot;
3488
3489 /* Look in prefix table */
3490 Container = RxPrefixTableLookupName(RxDeviceObject->pRxNetNameTable, CanonicalName, RemainingName, &ConnectionID);
3491 if (Container != NULL)
3492 {
3493 /* If that's not a VNetRoot, that's a SrvCall, not interesting, loop again */
3494 if (NodeType(Container) != RDBSS_NTC_V_NETROOT)
3495 {
3496 ASSERT(NodeType(Container) == RDBSS_NTC_SRVCALL);
3497 RxDereferenceSrvCall(Container, LockHoldingState);
3498 }
3499 else
3500 {
3501 VNetRoot = Container;
3502 NetRoot = VNetRoot->NetRoot;
3503
3504 /* If the matching VNetRoot isn't in a good shape, there's something wrong - fail */
3505 if ((NetRoot->Condition != Condition_InTransition && NetRoot->Condition != Condition_Good) ||
3506 NetRoot->SrvCall->RxDeviceObject != RxContext->RxDeviceObject)
3507 {
3509 SavedVNetRoot = NULL;
3510 }
3511 else
3512 {
3513 LUID LogonId;
3515 PUNICODE_STRING UserName, UserDomain, Password;
3516
3517 /* We can reuse if we use same credentials */
3519 &SessionId, &UserName,
3520 &UserDomain, &Password,
3521 &Flags);
3522 if (NT_SUCCESS(Status))
3523 {
3524 SavedVNetRoot = VNetRoot;
3525 Status = RxCheckVNetRootCredentials(RxContext, VNetRoot,
3526 &LogonId, UserName,
3527 UserDomain, Password,
3528 Flags);
3530 {
3531 PLIST_ENTRY ListEntry;
3532
3533 for (ListEntry = NetRoot->VirtualNetRoots.Flink;
3534 ListEntry != &NetRoot->VirtualNetRoots;
3535 ListEntry = ListEntry->Flink)
3536 {
3537 SavedVNetRoot = CONTAINING_RECORD(ListEntry, V_NET_ROOT, NetRootListEntry);
3538 Status = RxCheckVNetRootCredentials(RxContext, SavedVNetRoot,
3539 &LogonId, UserName,
3540 UserDomain, Password,
3541 Flags);
3543 {
3544 break;
3545 }
3546 }
3547
3548 if (ListEntry == &NetRoot->VirtualNetRoots)
3549 {
3550 SavedVNetRoot = NULL;
3551 }
3552 }
3553
3554 if (!NT_SUCCESS(Status))
3555 {
3556 SavedVNetRoot = NULL;
3557 }
3558
3559 RxUninitializeVNetRootParameters(UserName, UserDomain, Password, &Flags);
3560 }
3561 }
3562
3563 /* We'll fail, if we had referenced a VNetRoot, dereference it */
3565 {
3566 if (SavedVNetRoot == NULL)
3567 {
3568 RxDereferenceVNetRoot(VNetRoot, LockHoldingState);
3569 }
3570 }
3571 /* Reference VNetRoot we'll keep, and dereference current */
3572 else if (SavedVNetRoot != VNetRoot)
3573 {
3574 RxDereferenceVNetRoot(VNetRoot, LockHoldingState);
3575 if (SavedVNetRoot != NULL)
3576 {
3577 RxReferenceVNetRoot(SavedVNetRoot);
3578 }
3579 }
3580 }
3581
3582 /* We may have found something, or we fail hard, so don't attempt to create a VNetRoot */
3584 {
3585 Construct = FALSE;
3586 break;
3587 }
3588 }
3589
3590 /* If we're locked exclusive, we won't loop again, it was the second pass */
3591 if (LockHoldingState != LHS_SharedLockHeld)
3592 {
3593 break;
3594 }
3595
3596 /* Otherwise, prepare for second pass, exclusive, making sure we can acquire without delay */
3598 {
3600 LockHoldingState = LHS_ExclusiveLockHeld;
3601 break;
3602 }
3603
3606 LockHoldingState = LHS_ExclusiveLockHeld;
3607 }
3608
3609 /* We didn't fail, and didn't find any VNetRoot, construct one */
3610 if (Construct)
3611 {
3612 ASSERT(LockHoldingState == LHS_ExclusiveLockHeld);
3613
3614 Status = RxConstructVirtualNetRoot(RxContext, CanonicalName, NetRootType, &VNetRoot, &LockHoldingState, &ConnectionID);
3615 ASSERT(Status != STATUS_SUCCESS || LockHoldingState != LHS_LockNotHeld);
3616
3617 if (Status == STATUS_SUCCESS)
3618 {
3619 DPRINT("CanonicalName: %wZ (%d)\n", CanonicalName, CanonicalName->Length);
3620 DPRINT("VNetRoot: %wZ (%d)\n", &VNetRoot->PrefixEntry.Prefix, VNetRoot->PrefixEntry.Prefix.Length);
3621 ASSERT(CanonicalName->Length >= VNetRoot->PrefixEntry.Prefix.Length);
3622
3623 RemainingName->Buffer = Add2Ptr(CanonicalName->Buffer, VNetRoot->PrefixEntry.Prefix.Length);
3624 RemainingName->Length = CanonicalName->Length - VNetRoot->PrefixEntry.Prefix.Length;
3625 RemainingName->MaximumLength = RemainingName->Length;
3626
3628 {
3629 DPRINT("CSC instance, VNetRoot: %p\n", VNetRoot);
3630 }
3631 VNetRoot->Flags |= Flags;
3632 }
3633 }
3634
3635 /* Release the prefix table - caller expects it to be released */
3636 if (LockHoldingState != LHS_LockNotHeld)
3637 {
3639 }
3640
3641 /* If we failed creating, quit */
3642 if (Status != STATUS_SUCCESS)
3643 {
3644 DPRINT1("RxFindOrConstructVirtualNetRoot() = Status: %x\n", Status);
3645 return Status;
3646 }
3647
3648 /* Otherwise, wait until the VNetRoot is stable */
3649 DPRINT("Waiting for stable condition for: %p\n", VNetRoot);
3650 RxWaitForStableVNetRoot(VNetRoot, RxContext);
3651 /* It's all good, update the RX_CONTEXT with all our structs */
3652 if (VNetRoot->Condition == Condition_Good)
3653 {
3654 PNET_ROOT NetRoot;
3655
3656 NetRoot = VNetRoot->NetRoot;
3657 RxContext->Create.pVNetRoot = (PMRX_V_NET_ROOT)VNetRoot;
3658 RxContext->Create.pNetRoot = (PMRX_NET_ROOT)NetRoot;
3659 RxContext->Create.pSrvCall = (PMRX_SRV_CALL)NetRoot->SrvCall;
3660 }
3661 else
3662 {
3664 RxContext->Create.pVNetRoot = NULL;
3666 }
3667
3668 return Status;
3669}
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:802
ULONG SessionId
Definition: dllmain.c:28
#define RxWaitForStableVNetRoot(V, R)
Definition: fcb.h:514
#define RxAcquirePrefixTableLockShared(T, W)
Definition: prefix.h:82
NTSTATUS RxCheckVNetRootCredentials(PRX_CONTEXT RxContext, PV_NET_ROOT VNetRoot, PLUID LogonId, PUNICODE_STRING UserName, PUNICODE_STRING UserDomain, PUNICODE_STRING Password, ULONG Flags)
Definition: rxce.c:922
PVOID RxPrefixTableLookupName(IN PRX_PREFIX_TABLE ThisTable, IN PUNICODE_STRING CanonicalName, OUT PUNICODE_STRING RemainingName, IN PRX_CONNECTION_ID ConnectionId)
Definition: rxce.c:6487
NTSTATUS RxConstructVirtualNetRoot(IN PRX_CONTEXT RxContext, IN PUNICODE_STRING CanonicalName, IN NET_ROOT_TYPE NetRootType, OUT PV_NET_ROOT *VirtualNetRootPointer, OUT PLOCK_HOLDING_STATE LockHoldingState, OUT PRX_CONNECTION_ID RxConnectionId)
Definition: rxce.c:1365
@ LHS_SharedLockHeld
Definition: rxstruc.h:21
enum _LOCK_HOLDING_STATE LOCK_HOLDING_STATE
PMRX_GET_CONNECTION_ID MRxGetConnectionId
Definition: mrx.h:399
RX_BLOCK_CONDITION Condition
Definition: fcb.h:45
ULONG SessionID
Definition: prefix.h:8

◆ RxFindOrCreateConnections()

NTSTATUS RxFindOrCreateConnections ( _In_ PRX_CONTEXT  RxContext,
_In_ PUNICODE_STRING  CanonicalName,
_In_ NET_ROOT_TYPE  NetRootType,
_Out_ PUNICODE_STRING  LocalNetRootName,
_Out_ PUNICODE_STRING  FilePathName,
_Inout_ PLOCK_HOLDING_STATE  LockState,
_In_ PRX_CONNECTION_ID  RxConnectionId 
)

Definition at line 3675 of file rxce.c.

3683{
3684 PVOID Container;
3685 PSRV_CALL SrvCall;
3686 PNET_ROOT NetRoot;
3687 PV_NET_ROOT VNetRoot;
3689 PRX_PREFIX_TABLE PrefixTable;
3690 UNICODE_STRING RemainingName, NetRootName;
3691
3692 PAGED_CODE();
3693
3694 DPRINT("RxFindOrCreateConnections(%p, %wZ, %x, %p, %p, %p, %p)\n",
3695 RxContext, CanonicalName, NetRootType, LocalNetRootName,
3696 FilePathName, LockState, RxConnectionId);
3697
3698 *FilePathName = *CanonicalName;
3699 LocalNetRootName->Length = 0;
3700 LocalNetRootName->MaximumLength = 0;
3701 LocalNetRootName->Buffer = CanonicalName->Buffer;
3702
3703 /* UNC path, split it */
3704 if (FilePathName->Buffer[1] == ';')
3705 {
3706 BOOLEAN Slash;
3707 USHORT i, Length;
3708
3709 Slash = FALSE;
3710 for (i = 2; i < FilePathName->Length / sizeof(WCHAR); ++i)
3711 {
3712 if (FilePathName->Buffer[i] == OBJ_NAME_PATH_SEPARATOR)
3713 {
3714 Slash = TRUE;
3715 break;
3716 }
3717 }
3718
3719 if (!Slash)
3720 {
3722 }
3723
3724 FilePathName->Buffer = &FilePathName->Buffer[i];
3725 Length = (USHORT)((ULONG_PTR)FilePathName->Buffer - (ULONG_PTR)LocalNetRootName->Buffer);
3726 LocalNetRootName->Length = Length;
3727 LocalNetRootName->MaximumLength = Length;
3728 FilePathName->Length -= Length;
3729
3730 DPRINT("CanonicalName: %wZ\n", CanonicalName);
3731 DPRINT(" -> FilePathName: %wZ\n", FilePathName);
3732 DPRINT(" -> LocalNetRootName: %wZ\n", LocalNetRootName);
3733 }
3734
3735 Container = NULL;
3736 PrefixTable = RxContext->RxDeviceObject->pRxNetNameTable;
3737
3738 _SEH2_TRY
3739 {
3740RetryLookup:
3742
3743 /* If previous lookup left something, dereference it */
3744 if (Container != NULL)
3745 {
3746 switch (NodeType(Container))
3747 {
3748 case RDBSS_NTC_SRVCALL:
3749 RxDereferenceSrvCall(Container, *LockState);
3750 break;
3751
3752 case RDBSS_NTC_NETROOT:
3753 RxDereferenceNetRoot(Container, *LockState);
3754 break;
3755
3757 RxDereferenceVNetRoot(Container, *LockState);
3758 break;
3759
3760 default:
3761 /* Should never happen */
3762 ASSERT(FALSE);
3763 break;
3764 }
3765 }
3766
3767 /* Look for our NetRoot in prefix table */
3768 Container = RxPrefixTableLookupName(PrefixTable, FilePathName, &RemainingName, RxConnectionId);
3769 DPRINT("Container %p for path %wZ\n", Container, FilePathName);
3770
3771 while (TRUE)
3772 {
3773 UNICODE_STRING SrvCallName;
3774
3775 SrvCall = NULL;
3776 NetRoot = NULL;
3777 VNetRoot = NULL;
3778
3779 /* Assume we didn't succeed */
3780 RxContext->Create.pVNetRoot = NULL;
3781 RxContext->Create.pNetRoot = NULL;
3782 RxContext->Create.pSrvCall = NULL;
3783 RxContext->Create.Type = NetRootType;
3784
3785 /* If we found something */
3786 if (Container != NULL)
3787 {
3788 /* A VNetRoot */
3789 if (NodeType(Container) == RDBSS_NTC_V_NETROOT)
3790 {
3791 VNetRoot = Container;
3792 /* Use its NetRoot */
3793 NetRoot = VNetRoot->NetRoot;
3794
3795 /* If it's not stable, wait for it to be stable */
3796 if (NetRoot->Condition == Condition_InTransition)
3797 {
3798 RxReleasePrefixTableLock(PrefixTable);
3799 DPRINT("Waiting for stable condition for: %p\n", NetRoot);
3800 RxWaitForStableNetRoot(NetRoot, RxContext);
3803
3804 /* Now that's it's ok, retry lookup to find what we want */
3805 if (NetRoot->Condition == Condition_Good)
3806 {
3807 goto RetryLookup;
3808 }
3809 }
3810
3811 /* Is the associated netroot good? */
3812 if (NetRoot->Condition == Condition_Good)
3813 {
3814 SrvCall = (PSRV_CALL)NetRoot->pSrvCall;
3815
3816 /* If it is, and SrvCall as well, then, we have our active connection */
3817 if (SrvCall->Condition == Condition_Good &&
3818 SrvCall->RxDeviceObject == RxContext->RxDeviceObject)
3819 {
3820 RxContext->Create.pVNetRoot = (PMRX_V_NET_ROOT)VNetRoot;
3821 RxContext->Create.pNetRoot = (PMRX_NET_ROOT)NetRoot;
3822 RxContext->Create.pSrvCall = (PMRX_SRV_CALL)SrvCall;
3823
3826 }
3827 }
3828
3829 /* If VNetRoot was well constructed, it means the connection is active */
3830 if (VNetRoot->ConstructionStatus == STATUS_SUCCESS)
3831 {
3833 }
3834 else
3835 {
3836 Status = VNetRoot->ConstructionStatus;
3837 }
3838
3839 RxDereferenceVNetRoot(VNetRoot, *LockState);
3841 }
3842 /* Can only be a SrvCall */
3843 else
3844 {
3845 ASSERT(NodeType(Container) == RDBSS_NTC_SRVCALL);
3846 SrvCall = Container;
3847
3848 /* Wait for the SRV_CALL to be stable */
3849 if (SrvCall->Condition == Condition_InTransition)
3850 {
3851 RxReleasePrefixTableLock(PrefixTable);
3852 DPRINT("Waiting for stable condition for: %p\n", SrvCall);
3853 RxWaitForStableSrvCall(SrvCall, RxContext);
3856
3857 /* It went good, loop again to find what we look for */
3858 if (SrvCall->Condition == Condition_Good)
3859 {
3860 goto RetryLookup;
3861 }
3862 }
3863
3864 /* If it's not good... */
3865 if (SrvCall->Condition != Condition_Good)
3866 {
3867 /* But SRV_CALL was well constructed, assume a connection was active */
3868 if (SrvCall->Status == STATUS_SUCCESS)
3869 {
3871 }
3872 else
3873 {
3874 Status = SrvCall->Status;
3875 }
3876
3879 }
3880 }
3881 }
3882
3883 /* If we found a SRV_CALL not matching our DO, quit */
3884 if (SrvCall != NULL && SrvCall->Condition == Condition_Good &&
3885 SrvCall->RxDeviceObject != RxContext->RxDeviceObject)
3886 {
3890 }
3891
3892 /* Now, we want exclusive lock */
3894 {
3895 if (!RxAcquirePrefixTableLockExclusive(PrefixTable, FALSE))
3896 {
3897 RxReleasePrefixTableLock(PrefixTable);
3900 goto RetryLookup;
3901 }
3902
3903 RxReleasePrefixTableLock(PrefixTable);
3905 }
3906
3908
3909 /* If we reach that point, we found something, no need to create something */
3910 if (Container != NULL)
3911 {
3912 break;
3913 }
3914
3915 /* Get the name for the SRV_CALL */
3916 RxExtractServerName(FilePathName, &SrvCallName, NULL);
3917 DPRINT(" -> SrvCallName: %wZ\n", &SrvCallName);
3918 /* And create the SRV_CALL */
3919 SrvCall = RxCreateSrvCall(RxContext, &SrvCallName, NULL, RxConnectionId);
3920 if (SrvCall == NULL)
3921 {
3924 }
3925
3926 /* Reset RX_CONTEXT, so far, connection creation isn't a success */
3927 RxReferenceSrvCall(SrvCall);
3928 RxContext->Create.pVNetRoot = NULL;
3929 RxContext->Create.pNetRoot = NULL;
3930 RxContext->Create.pSrvCall = NULL;
3931 RxContext->Create.Type = NetRootType;
3932 Container = SrvCall;
3933
3934 /* Construct SRV_CALL, ie, use mini-rdr */
3935 Status = RxConstructSrvCall(RxContext, SrvCall, LockState);
3937 if (Status != STATUS_SUCCESS)
3938 {
3939 DPRINT1("RxConstructSrvCall() = Status: %x\n", Status);
3942 RxReleasePrefixTableLock(PrefixTable);
3944 }
3945
3946 /* Loop again to make use of SRV_CALL stable condition wait */
3947 }
3948
3949 /* At that point, we have a stable SRV_CALL (either found or constructed) */
3950 ASSERT((NodeType(SrvCall) == RDBSS_NTC_SRVCALL) && (SrvCall->Condition == Condition_Good));
3951 ASSERT(NetRoot == NULL && VNetRoot == NULL);
3952 ASSERT(SrvCall->RxDeviceObject == RxContext->RxDeviceObject);
3953
3954 /* Call mini-rdr to get NetRoot name */
3955 SrvCall->RxDeviceObject->Dispatch->MRxExtractNetRootName(FilePathName, (PMRX_SRV_CALL)SrvCall, &NetRootName, NULL);
3956 /* And create the NetRoot with that name */
3957 NetRoot = RxCreateNetRoot(SrvCall, &NetRootName, 0, RxConnectionId);
3958 if (NetRoot == NULL)
3959 {
3962 }
3963 NetRoot->Type = NetRootType;
3964
3966
3967 /* Finally, create the associated VNetRoot */
3968 VNetRoot = RxCreateVNetRoot(RxContext, NetRoot, CanonicalName, LocalNetRootName, FilePathName, RxConnectionId);
3969 if (VNetRoot == NULL)
3970 {
3971 RxFinalizeNetRoot(NetRoot, TRUE, TRUE);
3974 }
3975 RxReferenceVNetRoot(VNetRoot);
3976
3977 /* We're get closer! */
3979 RxContext->Create.pSrvCall = (PMRX_SRV_CALL)SrvCall;
3980 RxContext->Create.pNetRoot = (PMRX_NET_ROOT)NetRoot;
3981 RxContext->Create.pVNetRoot = (PMRX_V_NET_ROOT)VNetRoot;
3982
3983 /* Construct the NetRoot, involving the mini-rdr now that we have our three control structs */
3984 Status = RxConstructNetRoot(RxContext, SrvCall, NetRoot, VNetRoot, LockState);
3985 if (!NT_SUCCESS(Status))
3986 {
3988 DPRINT1("RxConstructNetRoot failed Ctxt: %p, VNet: %p, Status: %lx, Condition: %d\n", RxContext, VNetRoot, Status, VNetRoot->Condition);
3989 RxDereferenceVNetRoot(VNetRoot, *LockState);
3990
3991 RxContext->Create.pNetRoot = NULL;
3992 RxContext->Create.pVNetRoot = NULL;
3993 }
3994 else
3995 {
3997
3999
4000 Stack = RxContext->CurrentIrpSp;
4001 if (BooleanFlagOn(Stack->Parameters.Create.Options, FILE_CREATE_TREE_CONNECTION))
4002 {
4005 }
4006 }
4007 }
4009 {
4011 {
4012 if (*LockState != LHS_LockNotHeld)
4013 {
4014 RxReleasePrefixTableLock(PrefixTable);
4016 }
4017 }
4018 }
4019 _SEH2_END;
4020
4021 DPRINT("RxFindOrCreateConnections() = Status: %x\n", Status);
4022 return Status;
4023}
#define RxWaitForStableSrvCall(S, R)
Definition: fcb.h:450
#define RxWaitForStableNetRoot(N, R)
Definition: fcb.h:473
#define _SEH2_LEAVE
Definition: filesup.c:20
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment IN PNDIS_RW_LOCK Lock IN PNDIS_RW_LOCK IN PLOCK_STATE LockState
Definition: CrNtStubs.h:104
#define FILE_CREATE_TREE_CONNECTION
Definition: from_kernel.h:33
#define STATUS_BAD_NETWORK_NAME
Definition: ntstatus.h:440
VOID RxExclusivePrefixTableLockToShared(PRX_PREFIX_TABLE Table)
Definition: rxce.c:2440
VOID RxExtractServerName(IN PUNICODE_STRING FilePathName, OUT PUNICODE_STRING SrvCallName, OUT PUNICODE_STRING RestOfName)
Definition: rxce.c:2452
PNET_ROOT RxCreateNetRoot(IN PSRV_CALL SrvCall, IN PUNICODE_STRING Name, IN ULONG NetRootFlags, IN PRX_CONNECTION_ID OPTIONAL RxConnectionId)
Definition: rxce.c:1705
PSRV_CALL RxCreateSrvCall(IN PRX_CONTEXT RxContext, IN PUNICODE_STRING Name, IN PUNICODE_STRING InnerNamePrefix OPTIONAL, IN PRX_CONNECTION_ID RxConnectionId)
Definition: rxce.c:1843
NTSTATUS RxConstructSrvCall(IN PRX_CONTEXT RxContext, IN PSRV_CALL SrvCall, OUT PLOCK_HOLDING_STATE LockHoldingState)
Definition: rxce.c:1262
RX_BLOCK_CONDITION Condition
Definition: fcb.h:21
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148

Referenced by RxConstructVirtualNetRoot().

◆ RxFinishFcbInitialization()

VOID NTAPI RxFinishFcbInitialization ( IN OUT PMRX_FCB  Fcb,
IN RX_FILE_TYPE  FileType,
IN PFCB_INIT_PACKET InitPacket  OPTIONAL 
)

Definition at line 4030 of file rxce.c.

4034{
4035 RX_FILE_TYPE OldType;
4036
4037 PAGED_CODE();
4038
4039 DPRINT("RxFinishFcbInitialization(%p, %x, %p)\n", Fcb, FileType, InitPacket);
4040
4041 OldType = NodeType(Fcb);
4043 /* If mini-rdr already did the job for mailslot attributes, 0 the rest */
4045 {
4046 FILL_IN_FCB((PFCB)Fcb, 0, 0, 0, 0, 0, 0, 0, 0, 0);
4047 }
4048 /* Otherwise, if mini-rdr provided us with an init packet, copy its data */
4049 else if (InitPacket != NULL)
4050 {
4051 FILL_IN_FCB((PFCB)Fcb, *InitPacket->pAttributes, *InitPacket->pNumLinks,
4052 InitPacket->pCreationTime->QuadPart, InitPacket->pLastAccessTime->QuadPart,
4053 InitPacket->pLastWriteTime->QuadPart, InitPacket->pLastChangeTime->QuadPart,
4054 InitPacket->pAllocationSize->QuadPart, InitPacket->pFileSize->QuadPart,
4055 InitPacket->pValidDataLength->QuadPart);
4056 }
4057
4060 {
4061 /* If our FCB newly points to a file, initiliaze everything related */
4063
4064 {
4065 if (OldType != RDBSS_NTC_STORAGE_TYPE_FILE)
4066 {
4067 RxInitializeLowIoPerFcbInfo(&((PFCB)Fcb)->Specific.Fcb.LowIoPerFcbInfo);
4068 FsRtlInitializeFileLock(&((PFCB)Fcb)->Specific.Fcb.FileLock, RxLockOperationCompletion,
4070
4071 ((PFCB)Fcb)->BufferedLocks.List = NULL;
4072 ((PFCB)Fcb)->BufferedLocks.PendingLockOps = 0;
4073
4074 Fcb->Header.IsFastIoPossible = FastIoIsQuestionable;
4075 }
4076 }
4077 /* If not a file, validate type */
4078 else
4079 {
4081 }
4082 }
4083}
VOID NTAPI FsRtlInitializeFileLock(IN PFILE_LOCK FileLock, IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL)
Definition: filelock.c:1262
@ FastIoIsQuestionable
Definition: fsrtltypes.h:242
VOID RxInitializeLowIoPerFcbInfo(PLOWIO_PER_FCB_INFO LowIoPerFcbInfo)
Definition: rxce.c:4847
VOID NTAPI RxUnlockOperation(_In_ PVOID Context, _In_ PFILE_LOCK_INFO LockInfo)
NTSTATUS NTAPI RxLockOperationCompletion(_In_ PVOID Context, _In_ PIRP Irp)
#define RDBSS_NTC_STORAGE_TYPE_UNKNOWN
Definition: nodetype.h:41
enum _RX_FILE_TYPE RX_FILE_TYPE
#define RDBSS_NTC_MAILSLOT
Definition: nodetype.h:46
#define RDBSS_NTC_SPOOLFILE
Definition: nodetype.h:47
_In_ WDFDEVICE _In_ WDF_SPECIAL_FILE_TYPE FileType
Definition: wdfdevice.h:2741

◆ RxFinishSrvCallConstruction()

NTSTATUS RxFinishSrvCallConstruction ( PMRX_SRVCALLDOWN_STRUCTURE  Calldown)

Definition at line 4089 of file rxce.c.

4091{
4093 PSRV_CALL SrvCall;
4096 PRX_PREFIX_TABLE PrefixTable;
4097
4098 DPRINT("RxFinishSrvCallConstruction(%p)\n", Calldown);
4099
4100 SrvCall = (PSRV_CALL)Calldown->SrvCall;
4101 Context = Calldown->RxContext;
4102 PrefixTable = Context->RxDeviceObject->pRxNetNameTable;
4103
4104 /* We have a winner, notify him */
4105 if (Calldown->BestFinisher != NULL)
4106 {
4107 DPRINT("Notify the winner: %p (%wZ)\n", Calldown->BestFinisher, &Calldown->BestFinisher->DeviceName);
4108
4109 ASSERT(SrvCall->RxDeviceObject == Calldown->BestFinisher);
4110
4112 MRxSrvCallWinnerNotify,
4113 ((PMRX_SRV_CALL)SrvCall, TRUE,
4115 if (Status != STATUS_SUCCESS)
4116 {
4118 }
4119 else
4120 {
4122 }
4123 }
4124 /* Otherwise, just fail our SRV_CALL */
4125 else
4126 {
4127 Status = Calldown->CallbackContexts[0].Status;
4129 }
4130
4133 RxFreePoolWithTag(Calldown, RX_SRVCALL_POOLTAG);
4134
4135 /* If async, finish it here, otherwise, caller has already finished the stuff */
4137 {
4138 DPRINT("Finishing async call\n");
4139
4140 RxReleasePrefixTableLock(PrefixTable);
4141
4142 /* Make sure we weren't cancelled in-between */
4144 {
4146 }
4147
4148 /* In case that was a create, context can be reused */
4149 if (Context->MajorFunction == IRP_MJ_CREATE)
4150 {
4152 }
4153
4154 /* If that's a failure, reset everything and return failure */
4155 if (Status != STATUS_SUCCESS)
4156 {
4157 Context->MajorFunction = Context->CurrentIrpSp->MajorFunction;
4158 if (Context->MajorFunction == IRP_MJ_DEVICE_CONTROL)
4159 {
4160 if (Context->Info.Buffer != NULL)
4161 {
4162 RxFreePool(Context->Info.Buffer);
4163 Context->Info.Buffer = NULL;
4164 }
4165 }
4166 Context->CurrentIrp->IoStatus.Information = 0;
4167 Context->CurrentIrp->IoStatus.Status = Status;
4169 }
4170 /* Otherwise, call resume routine and done! */
4171 else
4172 {
4173 Status = Context->ResumeRoutine(Context);
4174 if (Status != STATUS_PENDING)
4175 {
4177 }
4178
4179 DPRINT("Not completing, pending\n");
4180 }
4181 }
4182
4184 return Status;
4185}
#define RxTransitionSrvCall(S, C)
Definition: fcb.h:451
NTSTATUS RxCompleteRequest(PRX_CONTEXT Context, NTSTATUS Status)
Definition: rxce.c:959

Referenced by RxConstructSrvCall(), RxCreateSrvCallCallBack(), and RxFinishSrvCallConstructionDispatcher().

◆ RxFinishSrvCallConstructionDispatcher()

VOID NTAPI RxFinishSrvCallConstructionDispatcher ( IN PVOID  Context)

Definition at line 4192 of file rxce.c.

4194{
4195 KIRQL OldIrql;
4196 BOOLEAN Direct, KeepLoop;
4197
4198 DPRINT("RxFinishSrvCallConstructionDispatcher(%p)\n", Context);
4199
4200 /* In case of failure of starting dispatcher, context is not set
4201 * We keep track of it to fail associated SRV_CALL
4202 */
4203 Direct = (Context == NULL);
4204
4205 /* Separated thread, loop forever */
4206 while (TRUE)
4207 {
4208 PLIST_ENTRY ListEntry;
4210
4211 /* If there are no SRV_CALL to finalize left, just finish thread */
4214 {
4215 KeepLoop = FALSE;
4217 }
4218 /* Otherwise, get the SRV_CALL to finish construction */
4219 else
4220 {
4221 ListEntry = RemoveHeadList(&RxSrvCalldownList);
4222 KeepLoop = TRUE;
4223 }
4225
4226 /* Nothing to do */
4227 if (!KeepLoop)
4228 {
4229 break;
4230 }
4231
4232 /* If direct is set, reset the finisher to avoid electing a winner
4233 * and fail SRV_CALL (see upper comment)
4234 */
4235 Calldown = CONTAINING_RECORD(ListEntry, MRX_SRVCALLDOWN_STRUCTURE, SrvCalldownList);
4236 if (Direct)
4237 {
4238 Calldown->BestFinisher = NULL;
4239 }
4240 /* Finish SRV_CALL construction */
4242 }
4243}
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964

Referenced by RxCreateSrvCallCallBack().

◆ RxFlushFcbInSystemCache()

NTSTATUS RxFlushFcbInSystemCache ( IN PFCB  Fcb,
IN BOOLEAN  SynchronizeWithLazyWriter 
)

Definition at line 4249 of file rxce.c.

4252{
4254
4255 PAGED_CODE();
4256
4257 /* Deal with Cc */
4259 /* If we're asked to sync with LW, do it in case of success */
4260 if (SynchronizeWithLazyWriter && NT_SUCCESS(IoStatus.Status))
4261 {
4264 }
4265
4266 DPRINT("Flushing for FCB %p returns %lx\n", Fcb, IoStatus.Status);
4267 return IoStatus.Status;
4268}
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:222
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define RxReleasePagingIoResource(RxContext, Fcb)
Definition: rxprocs.h:268
#define RxAcquirePagingIoResource(RxContext, Fcb)
Definition: rxprocs.h:233

Referenced by RxChangeBufferingState(), and RxPurgeFcbInSystemCache().

◆ RxFreeFcbObject()

VOID RxFreeFcbObject ( PVOID  Object)

Definition at line 4274 of file rxce.c.

4276{
4277 PAGED_CODE();
4278
4279 DPRINT("Freeing %p\n", Object);
4280
4281 /* If that's a FOBX/SRV_OPEN, nothing to do, just free it */
4283 {
4284 RxFreePoolWithTag(Object, RX_FCB_POOLTAG);
4285 }
4286 /* If that's a FCB... */
4287 else if (NodeTypeIsFcb(Object))
4288 {
4289 PFCB Fcb;
4291
4292 Fcb = (PFCB)Object;
4294
4295 /* Delete per stream contexts */
4297
4299
4300 /* If there was a non-paged FCB allocated, free it */
4302 {
4303 RxFreePoolWithTag(Fcb->NonPaged, RX_NONPAGEDFCB_POOLTAG);
4304 }
4305
4306 /* Free the FCB */
4307 RxFreePool(Fcb);
4308
4309 /* Update statistics */
4311 InterlockedDecrement((volatile long *)&DeviceObject->NumberOfActiveFcbs);
4312 }
4313}
VOID NTAPI FsRtlTeardownPerStreamContexts(IN PFSRTL_ADVANCED_FCB_HEADER AdvFcbHeader)
Definition: filtrctx.c:368
#define FSRTL_FLAG_ACQUIRE_MAIN_RSRC_SH
Definition: fsrtltypes.h:49
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055

Referenced by RxFinalizeNetFcb(), RxFinalizeNetFobx(), and RxFinalizeSrvOpen().

◆ RxFreeObject()

VOID RxFreeObject ( PVOID  pObject)

Definition at line 4319 of file rxce.c.

4321{
4322 PAGED_CODE();
4323
4324 /* First, perform a few sanity checks if we're dealing with a SRV_CALL or a NET_ROOT */
4326 {
4327 PSRV_CALL SrvCall;
4329
4330 SrvCall = (PSRV_CALL)pObject;
4331 DeviceObject = SrvCall->RxDeviceObject;
4332 if (DeviceObject != NULL)
4333 {
4335 {
4336 ASSERT(SrvCall->Context == NULL);
4337 }
4338
4339 ASSERT(SrvCall->Context2 == NULL);
4340
4341 SrvCall->RxDeviceObject = NULL;
4342 }
4343 }
4344 else if (NodeType(pObject) == RDBSS_NTC_NETROOT)
4345 {
4346 PNET_ROOT NetRoot;
4347
4348 NetRoot = (PNET_ROOT)pObject;
4349 NetRoot->pSrvCall = NULL;
4350 NetRoot->NodeTypeCode = NodeType(pObject) | 0xF000;
4351 }
4352
4353 /* And just free the object */
4355}
FxObject * pObject

Referenced by RxCreateVNetRoot(), RxFinalizeNetRoot(), and RxFinalizeSrvCall().

◆ RxGatherRequestsForSrvOpen()

VOID RxGatherRequestsForSrvOpen ( IN OUT PSRV_CALL  SrvCall,
IN PSRV_OPEN  SrvOpen,
IN OUT PLIST_ENTRY  RequestsListHead 
)

Definition at line 4361 of file rxce.c.

4365{
4366 KIRQL OldIrql;
4367 LIST_ENTRY Discarded, *Entry;
4369
4370 /* Dispatch any pending operation first */
4371 RxpDispatchChangeBufferingStateRequests(SrvCall, SrvOpen, &Discarded);
4372
4373 /* Then, get any entry related to our key and SRV_OPEN */
4374 KeAcquireSpinLock(&SrvCall->BufferingManager.SpinLock, &OldIrql);
4375 Entry = SrvCall->BufferingManager.HandlerList.Flink;
4376 while (Entry != &SrvCall->BufferingManager.HandlerList)
4377 {
4379 Entry = Entry->Flink;
4380 if (Request->SrvOpenKey == SrvOpen->Key && Request->SrvOpen == SrvOpen)
4381 {
4382 RemoveEntryList(&Request->ListEntry);
4383 InsertTailList(RequestsListHead, &Request->ListEntry);
4384 }
4385 }
4386 KeReleaseSpinLock(&SrvCall->BufferingManager.SpinLock, OldIrql);
4387
4388 /* Perform the same search in the last change list */
4389 Entry = SrvCall->BufferingManager.LastChanceHandlerList.Flink;
4390 while (Entry != &SrvCall->BufferingManager.LastChanceHandlerList)
4391 {
4393 Entry = Entry->Flink;
4394 if (Request->SrvOpenKey == SrvOpen->Key && Request->SrvOpen == SrvOpen)
4395 {
4396 RemoveEntryList(&Request->ListEntry);
4397 InsertTailList(RequestsListHead, &Request->ListEntry);
4398 }
4399 }
4400
4401 /* Discard the discarded requests */
4403}
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547

Referenced by RxPurgeChangeBufferingStateRequestsForSrvOpen().

◆ RxGetDeviceObjectOfInstance()

PRDBSS_DEVICE_OBJECT RxGetDeviceObjectOfInstance ( PVOID  Instance)

Definition at line 4409 of file rxce.c.

4411{
4414
4415 PAGED_CODE();
4416
4417 /* We only handle a few object types */
4421
4422 /* Get the device object depending on the object */
4423 switch (NodeType)
4424 {
4425 case RDBSS_NTC_FOBX:
4426 {
4427 PFOBX Fobx;
4428
4429 Fobx = (PFOBX)Instance;
4431 break;
4432 }
4433
4434 case RDBSS_NTC_SRVCALL:
4435 {
4436 PSRV_CALL SrvCall;
4437
4438 SrvCall = (PSRV_CALL)Instance;
4439 DeviceObject = SrvCall->RxDeviceObject;
4440 break;
4441 }
4442
4443 case RDBSS_NTC_NETROOT:
4444 {
4445 PNET_ROOT NetRoot;
4446
4447 NetRoot = (PNET_ROOT)Instance;
4448 DeviceObject = NetRoot->pSrvCall->RxDeviceObject;
4449 break;
4450 }
4451
4453 {
4454 PV_NET_ROOT VNetRoot;
4455
4456 VNetRoot = (PV_NET_ROOT)Instance;
4457 DeviceObject = VNetRoot->pNetRoot->pSrvCall->RxDeviceObject;
4458 break;
4459 }
4460
4461 case RDBSS_NTC_SRVOPEN:
4462 {
4463 PSRV_OPEN SrvOpen;
4464
4465 SrvOpen = (PSRV_OPEN)Instance;
4466 DeviceObject = ((PFCB)SrvOpen->pFcb)->RxDeviceObject;
4467 break;
4468 }
4469
4470 default:
4472 break;
4473 }
4474
4475 /* Job done */
4476 return DeviceObject;
4477}

Referenced by RxpMarkInstanceForScavengedFinalization(), and RxpUndoScavengerFinalizationMarking().

◆ RxGetFileSizeWithLock()

VOID RxGetFileSizeWithLock ( IN PFCB  Fcb,
OUT PLONGLONG  FileSize 
)

Definition at line 4483 of file rxce.c.

4486{
4487 PAGED_CODE();
4488
4489 *FileSize = Fcb->Header.FileSize.QuadPart;
4490}
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108

◆ RxGetRDBSSProcess()

PEPROCESS NTAPI RxGetRDBSSProcess ( VOID  )

Definition at line 4497 of file rxce.c.

4499{
4500 return RxData.OurProcess;
4501}
RDBSS_DATA RxData
Definition: rdbss.c:537
PEPROCESS OurProcess
Definition: rxstruc.h:34

Referenced by nfs41_CreateSrvCall(), and RxFinalizeSrvCall().

◆ RxInitializeBufferingManager()

NTSTATUS RxInitializeBufferingManager ( PSRV_CALL  SrvCall)

Definition at line 4507 of file rxce.c.

Referenced by RxCreateSrvCall().

◆ RxInitializeContext()

VOID NTAPI RxInitializeContext ( IN PIRP  Irp,
IN PRDBSS_DEVICE_OBJECT  RxDeviceObject,
IN ULONG  InitialContextFlags,
IN OUT PRX_CONTEXT  RxContext 
)

Definition at line 4529 of file rxce.c.

4534{
4536
4537 /* Initialize our various fields */
4538 RxContext->NodeTypeCode = RDBSS_NTC_RX_CONTEXT;
4539 RxContext->NodeByteSize = sizeof(RX_CONTEXT);
4540 RxContext->ReferenceCount = 1;
4541 RxContext->SerialNumber = InterlockedExchangeAdd((volatile LONG *)&RxContextSerialNumberCounter, 1);
4542 RxContext->RxDeviceObject = RxDeviceObject;
4543 KeInitializeEvent(&RxContext->SyncEvent, SynchronizationEvent, FALSE);
4544 RxInitializeScavengerEntry(&RxContext->ScavengerEntry);
4545 InitializeListHead(&RxContext->BlockedOperations);
4546 RxContext->MRxCancelRoutine = NULL;
4547 RxContext->ResumeRoutine = NULL;
4548 RxContext->Flags |= InitialContextFlags;
4549 RxContext->CurrentIrp = Irp;
4550 RxContext->LastExecutionThread = PsGetCurrentThread();
4551 RxContext->OriginalThread = RxContext->LastExecutionThread;
4552
4553 /* If've got no IRP, mark RX_CONTEXT */
4554 if (Irp == NULL)
4555 {
4556 RxContext->CurrentIrpSp = NULL;
4557 RxContext->MajorFunction = IRP_MJ_MAXIMUM_FUNCTION + 1;
4558 RxContext->MinorFunction = 0;
4559 }
4560 else
4561 {
4562 /* Otherwise, first determine whether we are performing async operation */
4564 if (Stack->FileObject != NULL)
4565 {
4566 PFCB Fcb;
4567
4568 Fcb = Stack->FileObject->FsContext;
4570 ((Fcb != NULL && NodeTypeIsFcb(Fcb)) &&
4571 (Stack->MajorFunction == IRP_MJ_READ || Stack->MajorFunction == IRP_MJ_WRITE || Stack->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) &&
4572 (Fcb->pNetRoot != NULL && (Fcb->pNetRoot->Type == NET_ROOT_PIPE))))
4573 {
4574 RxContext->Flags |= RX_CONTEXT_FLAG_ASYNC_OPERATION;
4575 }
4576 }
4577
4578 if (Stack->MajorFunction == IRP_MJ_DIRECTORY_CONTROL && Stack->MinorFunction == IRP_MN_NOTIFY_CHANGE_DIRECTORY)
4579 {
4580 RxContext->Flags |= RX_CONTEXT_FLAG_ASYNC_OPERATION;
4581 }
4582 if (Stack->MajorFunction == IRP_MJ_DEVICE_CONTROL)
4583 {
4584 RxContext->Flags |= RX_CONTEXT_FLAG_ASYNC_OPERATION;
4585 }
4586
4587 /* Set proper flags if TopLevl IRP/Device */
4589 {
4590 RxContext->Flags |= RX_CONTEXT_FLAG_RECURSIVE_CALL;
4591 }
4592 if (RxGetTopDeviceObjectIfRdbssIrp() == RxDeviceObject)
4593 {
4594 RxContext->Flags |= RX_CONTEXT_FLAG_THIS_DEVICE_TOP_LEVEL;
4595 }
4596
4597 /* Copy stack information */
4598 RxContext->MajorFunction = Stack->MajorFunction;
4599 RxContext->MinorFunction = Stack->MinorFunction;
4600 ASSERT(RxContext->MajorFunction <= IRP_MJ_MAXIMUM_FUNCTION);
4601 RxContext->CurrentIrpSp = Stack;
4602
4603 /* If we have a FO associated, learn for more */
4604 if (Stack->FileObject != NULL)
4605 {
4606 PFCB Fcb;
4607 PFOBX Fobx;
4608
4609 /* Get the FCB and CCB (FOBX) */
4610 Fcb = Stack->FileObject->FsContext;
4611 Fobx = Stack->FileObject->FsContext2;
4612 RxContext->pFcb = (PMRX_FCB)Fcb;
4613 if (Fcb != NULL && NodeTypeIsFcb(Fcb))
4614 {
4615 RxContext->NonPagedFcb = Fcb->NonPaged;
4616 }
4617
4618 /* We have a FOBX, this not a DFS opening, keep track of it */
4619 if (Fobx != NULL && Fobx != UIntToPtr(DFS_OPEN_CONTEXT) && Fobx != UIntToPtr(DFS_DOWNLEVEL_OPEN_CONTEXT))
4620 {
4621 RxContext->pFobx = (PMRX_FOBX)Fobx;
4622 RxContext->pRelevantSrvOpen = Fobx->pSrvOpen;
4623 if (Fobx->NodeTypeCode == RDBSS_NTC_FOBX)
4624 {
4625 RxContext->FobxSerialNumber = InterlockedIncrement((volatile LONG *)&Fobx->FobxSerialNumber);
4626 }
4627 }
4628 else
4629 {
4630 RxContext->pFobx = NULL;
4631 }
4632
4633 /* In case of directory change notification, Fobx may be a VNetRoot, take note of that */
4634 if (RxContext->MajorFunction == IRP_MJ_DIRECTORY_CONTROL && RxContext->MinorFunction == IRP_MN_NOTIFY_CHANGE_DIRECTORY &&
4635 Fobx != NULL)
4636 {
4637 PV_NET_ROOT VNetRoot = NULL;
4638
4639 if (Fobx->NodeTypeCode == RDBSS_NTC_FOBX)
4640 {
4641 VNetRoot = Fcb->VNetRoot;
4642 }
4643 else if (Fobx->NodeTypeCode == RDBSS_NTC_V_NETROOT)
4644 {
4645 VNetRoot = (PV_NET_ROOT)Fobx;
4646 }
4647
4648 if (VNetRoot != NULL)
4649 {
4650 RxContext->NotifyChangeDirectory.pVNetRoot = (PMRX_V_NET_ROOT)VNetRoot;
4651 }
4652 }
4653
4654 /* Remember if that's a write through file */
4655 RxContext->RealDevice = Stack->FileObject->DeviceObject;
4656 if (BooleanFlagOn(Stack->FileObject->Flags, FO_WRITE_THROUGH))
4657 {
4658 RxContext->Flags |= RX_CONTEXT_FLAG_WRITE_THROUGH;
4659 }
4660 }
4661 }
4662
4663 if (RxContext->MajorFunction != IRP_MJ_DEVICE_CONTROL)
4664 {
4665 DPRINT("New Ctxt: %p for MN: %d, IRP: %p, THRD: %p, FCB: %p, FOBX:%p #%lx\n",
4666 RxContext, RxContext->MinorFunction, Irp,
4667 PsGetCurrentThread(), RxContext->pFcb, RxContext->pFobx,
4668 RxContext->SerialNumber);
4669 }
4670}
#define UIntToPtr(ui)
Definition: basetsd.h:90
#define DFS_DOWNLEVEL_OPEN_CONTEXT
Definition: dfs.h:7
#define DFS_OPEN_CONTEXT
Definition: dfs.h:6
#define NET_ROOT_PIPE
Definition: mrxfcb.h:31
struct _MRX_FCB_ * PMRX_FCB
BOOLEAN NTAPI IoIsOperationSynchronous(IN PIRP Irp)
Definition: irp.c:1882
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY
Definition: rdpdr.c:56
#define IRP_MJ_READ
Definition: rdpdr.c:46
volatile ULONG RxContextSerialNumberCounter
Definition: rxce.c:119
@ RX_CONTEXT_FLAG_RECURSIVE_CALL
Definition: rxcontx.h:285
@ RX_CONTEXT_FLAG_THIS_DEVICE_TOP_LEVEL
Definition: rxcontx.h:286
@ RX_CONTEXT_FLAG_WRITE_THROUGH
Definition: rxcontx.h:283
struct _RX_CONTEXT RX_CONTEXT
PRDBSS_DEVICE_OBJECT RxGetTopDeviceObjectIfRdbssIrp(VOID)
Definition: rdbss.c:6826
#define RxInitializeScavengerEntry(ScavengerEntry)
Definition: scavengr.h:18
PFILE_OBJECT FileObject
Definition: ntfs.h:520
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define FO_WRITE_THROUGH
Definition: iotypes.h:1779

Referenced by RxCreateRxContext(), and RxReinitializeContext().

◆ RxInitializeDebugSupport()

VOID NTAPI RxInitializeDebugSupport ( VOID  )

Definition at line 4677 of file rxce.c.

4679{
4680 /* Nothing to do */
4681}

Referenced by RxDriverEntry().

◆ RxInitializeDispatcher()

NTSTATUS NTAPI RxInitializeDispatcher ( VOID  )

Definition at line 4688 of file rxce.c.

4690{
4692 HANDLE ThreadHandle;
4693
4694 PAGED_CODE();
4695
4698
4699 /* Set appropriate timeouts: 10s & 60s */
4700 RxWorkQueueWaitInterval[CriticalWorkQueue].QuadPart = -10 * 1000 * 1000 * 10;
4701 RxWorkQueueWaitInterval[DelayedWorkQueue].QuadPart = -10 * 1000 * 1000 * 10;
4703 RxSpinUpDispatcherWaitInterval.QuadPart = -60 * 1000 * 1000 * 10;
4704
4708
4709 /* Initialize our dispatchers */
4711 if (!NT_SUCCESS(Status))
4712 {
4713 return Status;
4714 }
4715
4717 if (!NT_SUCCESS(Status))
4718 {
4719 return Status;
4720 }
4721
4722 /* And start them */
4730 if (NT_SUCCESS(Status))
4731 {
4732 ZwClose(ThreadHandle);
4733 }
4734
4735 return Status;
4736}
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define PROCESS_ALL_ACCESS
Definition: nt_native.h:1324
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
Definition: thread.c:602
NTSTATUS RxInitializeWorkQueueDispatcher(PRX_WORK_QUEUE_DISPATCHER Dispatcher)
Definition: rxce.c:5090
VOID NTAPI RxSpinUpRequestsDispatcher(PVOID Dispatcher)
Definition: rxce.c:8039
LARGE_INTEGER RxWorkQueueWaitInterval[RxMaximumWorkQueue]
Definition: rxce.c:132
NTSTATUS RxInitializeMRxDispatcher(IN OUT PRDBSS_DEVICE_OBJECT pMRxDeviceObject)
Definition: rxce.c:4860
RX_DISPATCHER RxDispatcher
Definition: rxce.c:134
RX_WORK_QUEUE_DISPATCHER RxDispatcherWorkQueues
Definition: rxce.c:135
LARGE_INTEGER RxSpinUpDispatcherWaitInterval
Definition: rxce.c:133
@ RxDispatcherActive
Definition: rxworkq.h:67
RX_DISPATCHER_CONTEXT DispatcherContext
Definition: rxstruc.h:126
volatile PKEVENT pTearDownEvent
Definition: rxstruc.h:67
volatile LONG NumberOfWorkerThreads
Definition: rxstruc.h:66
LONG NumberOfProcessors
Definition: rxworkq.h:73
PRX_WORK_QUEUE_DISPATCHER pWorkQueueDispatcher
Definition: rxworkq.h:75
PEPROCESS OwnerProcess
Definition: rxworkq.h:74
KEVENT SpinUpRequestsTearDownEvent
Definition: rxworkq.h:80
RX_DISPATCHER_STATE State
Definition: rxworkq.h:76
LIST_ENTRY SpinUpRequests
Definition: rxworkq.h:77
KSPIN_LOCK SpinUpRequestsLock
Definition: rxworkq.h:78
KEVENT SpinUpRequestsEvent
Definition: rxworkq.h:79

Referenced by RxDriverEntry().

◆ RxInitializeFcbTable()

VOID RxInitializeFcbTable ( IN OUT PRX_FCB_TABLE  FcbTable,
IN BOOLEAN  CaseInsensitiveMatch 
)

Definition at line 4742 of file rxce.c.

4745{
4746 USHORT i;
4747
4748 PAGED_CODE();
4749
4750 FcbTable->NodeTypeCode = RDBSS_NTC_FCB_TABLE;
4751 FcbTable->NodeByteSize = sizeof(RX_FCB_TABLE);
4752
4753 ExInitializeResourceLite(&FcbTable->TableLock);
4754 FcbTable->CaseInsensitiveMatch = CaseInsensitiveMatch;
4755 FcbTable->Version = 0;
4756 FcbTable->TableEntryForNull = NULL;
4757
4758 FcbTable->NumberOfBuckets = RX_FCB_TABLE_NUMBER_OF_HASH_BUCKETS;
4759 for (i = 0; i < FcbTable->NumberOfBuckets; ++i)
4760 {
4761 InitializeListHead(&FcbTable->HashBuckets[i]);
4762 }
4763
4764 FcbTable->Lookups = 0;
4765 FcbTable->FailedLookups = 0;
4766 FcbTable->Compares = 0;
4767}
#define RX_FCB_TABLE_NUMBER_OF_HASH_BUCKETS
Definition: fcbtable.h:13
struct _RX_FCB_TABLE RX_FCB_TABLE
#define RDBSS_NTC_FCB_TABLE
Definition: nodetype.h:61

Referenced by RxCreateNetRoot().

◆ RxInitializeLowIoContext()

VOID NTAPI RxInitializeLowIoContext ( OUT PLOWIO_CONTEXT  LowIoContext,
IN ULONG  Operation 
)

Definition at line 4774 of file rxce.c.

4777{
4778 PRX_CONTEXT RxContext;
4780
4781 PAGED_CODE();
4782
4783 RxContext = CONTAINING_RECORD(LowIoContext, RX_CONTEXT, LowIoContext);
4784 ASSERT(LowIoContext == &RxContext->LowIoContext);
4785
4786 Stack = RxContext->CurrentIrpSp;
4787
4790 RxContext->LowIoContext.Operation = Operation;
4791
4792 switch (Operation)
4793 {
4794 case LOWIO_OP_READ:
4795 case LOWIO_OP_WRITE:
4796 /* In case of RW, set a canary, to make sure these fields are properly set
4797 * they will be asserted when lowio request will be submit to mini-rdr
4798 * See LowIoSubmit()
4799 */
4800 RxContext->LowIoContext.ParamsFor.ReadWrite.ByteOffset = 0xFFFFFFEE;
4801 RxContext->LowIoContext.ParamsFor.ReadWrite.ByteCount = 0xEEEEEEEE;
4802 RxContext->LowIoContext.ParamsFor.ReadWrite.Key = Stack->Parameters.Read.Key;
4803
4804 /* Keep track of paging IOs */
4805 if (BooleanFlagOn(RxContext->CurrentIrp->Flags, IRP_PAGING_IO))
4806 {
4808 }
4809 else
4810 {
4811 RxContext->LowIoContext.ParamsFor.ReadWrite.Flags = 0;
4812 }
4813
4814 break;
4815
4816 case LOWIO_OP_FSCTL:
4817 case LOWIO_OP_IOCTL:
4818 /* This will be initialized later on with a call to RxLowIoPopulateFsctlInfo() */
4819 RxContext->LowIoContext.ParamsFor.FsCtl.Flags = 0;
4825 break;
4826
4827 /* Nothing to do for these */
4830 case LOWIO_OP_UNLOCK:
4833 case LOWIO_OP_CLEAROUT:
4834 break;
4835
4836 default:
4837 /* Should never happen */
4838 ASSERT(FALSE);
4839 break;
4840 }
4841}
FP_OP Operation
Definition: fpcontrol.c:150
@ LOWIO_OP_FSCTL
Definition: mrx.h:240
@ LOWIO_OP_EXCLUSIVELOCK
Definition: mrx.h:237
@ LOWIO_OP_WRITE
Definition: mrx.h:235
@ LOWIO_OP_CLEAROUT
Definition: mrx.h:243
@ LOWIO_OP_READ
Definition: mrx.h:234
@ LOWIO_OP_NOTIFY_CHANGE_DIRECTORY
Definition: mrx.h:242
@ LOWIO_OP_UNLOCK
Definition: mrx.h:238
@ LOWIO_OP_UNLOCK_MULTIPLE
Definition: mrx.h:239
@ LOWIO_OP_SHAREDLOCK
Definition: mrx.h:236
@ LOWIO_OP_IOCTL
Definition: mrx.h:241
#define LOWIO_READWRITEFLAG_PAGING_IO
Definition: mrx.h:325
@ NotificationEvent
struct _LOWIO_CONTEXT::@2065::@2066 ReadWrite
XXCTL_LOWIO_COMPONENT FsCtl
Definition: mrx.h:308
USHORT Operation
Definition: mrx.h:281
union _LOWIO_CONTEXT::@2065 ParamsFor
ERESOURCE_THREAD ResourceThreadId
Definition: mrx.h:285
PIRP CurrentIrp
Definition: rxcontx.h:110
LOWIO_CONTEXT LowIoContext
Definition: rxcontx.h:263
PIO_STACK_LOCATION CurrentIrpSp
Definition: rxcontx.h:111
ULONG OutputBufferLength
Definition: mrx.h:274
ULONG InputBufferLength
Definition: mrx.h:272
PVOID pInputBuffer
Definition: mrx.h:273
UCHAR MinorFunction
Definition: mrx.h:276
PVOID pOutputBuffer
Definition: mrx.h:275
ULONG_PTR ERESOURCE_THREAD
Definition: extypes.h:208
#define IRP_PAGING_IO

◆ RxInitializeLowIoPerFcbInfo()

VOID RxInitializeLowIoPerFcbInfo ( PLOWIO_PER_FCB_INFO  LowIoPerFcbInfo)

Definition at line 4847 of file rxce.c.

4849{
4850 PAGED_CODE();
4851
4854}
LIST_ENTRY PagingIoReadsOutstanding
Definition: lowio.h:19
LIST_ENTRY PagingIoWritesOutstanding
Definition: lowio.h:20

Referenced by RxFinishFcbInitialization().

◆ RxInitializeMRxDispatcher()

NTSTATUS RxInitializeMRxDispatcher ( IN OUT PRDBSS_DEVICE_OBJECT  pMRxDeviceObject)

Definition at line 4860 of file rxce.c.

4862{
4863 PAGED_CODE();
4864
4865 pMRxDeviceObject->DispatcherContext.NumberOfWorkerThreads = 0;
4866 pMRxDeviceObject->DispatcherContext.pTearDownEvent = NULL;
4867
4868 return STATUS_SUCCESS;
4869}

Referenced by RxInitializeDispatcher().

◆ RxInitializePrefixTable()

VOID RxInitializePrefixTable ( IN OUT PRX_PREFIX_TABLE  ThisTable,
IN ULONG TableSize  OPTIONAL,
IN BOOLEAN  CaseInsensitiveMatch 
)

Definition at line 4875 of file rxce.c.

4879{
4880 PAGED_CODE();
4881
4882 if (TableSize == 0)
4883 {
4885 }
4886
4887 ThisTable->NodeTypeCode = RDBSS_NTC_PREFIX_TABLE;
4888 ThisTable->NodeByteSize = sizeof(RX_PREFIX_TABLE);
4889 InitializeListHead(&ThisTable->MemberQueue);
4890 ThisTable->Version = 0;
4891 ThisTable->TableEntryForNull = NULL;
4892 ThisTable->IsNetNameTable = FALSE;
4893 ThisTable->CaseInsensitiveMatch = CaseInsensitiveMatch;
4894 ThisTable->TableSize = TableSize;
4895
4896 if (TableSize > 0)
4897 {
4898 USHORT i;
4899
4900 for (i = 0; i < RX_PREFIX_TABLE_DEFAULT_LENGTH; ++i)
4901 {
4902 InitializeListHead(&ThisTable->HashBuckets[i]);
4903 }
4904 }
4905}
struct _RX_PREFIX_TABLE RX_PREFIX_TABLE
#define RX_PREFIX_TABLE_DEFAULT_LENGTH
Definition: prefix.h:60
#define RDBSS_NTC_PREFIX_TABLE
Definition: nodetype.h:59
_Must_inspect_result_ typedef _Out_ PULONG TableSize
Definition: iotypes.h:4327

◆ RxInitializePurgeSyncronizationContext()

VOID RxInitializePurgeSyncronizationContext ( PPURGE_SYNCHRONIZATION_CONTEXT  PurgeSyncronizationContext)

Definition at line 4911 of file rxce.c.

4913{
4914 PAGED_CODE();
4915
4916 InitializeListHead(&PurgeSyncronizationContext->ContextsAwaitingPurgeCompletion);
4917 PurgeSyncronizationContext->PurgeInProgress = FALSE;
4918}
LIST_ENTRY ContextsAwaitingPurgeCompletion
Definition: scavengr.h:117

Referenced by RxCreateNetRoot(), and RxCreateSrvCall().

◆ RxInitializeRxTimer()

NTSTATUS NTAPI RxInitializeRxTimer ( VOID  )

Definition at line 4946 of file rxce.c.

4948{
4949 PAGED_CODE();
4950
4951 RxTimerInterval.QuadPart = -550000;
4957 RxTimerTickCount = 0;
4958
4959 return STATUS_SUCCESS;
4960}
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
RX_SPIN_LOCK RxTimerLock
Definition: rxce.c:140
LARGE_INTEGER RxTimerInterval
Definition: rxce.c:139
ULONG RxTimerTickCount
Definition: rxce.c:145
LIST_ENTRY RxRecurrentWorkItemsList
Definition: rxce.c:142
KTIMER RxTimer
Definition: rxce.c:144
LIST_ENTRY RxTimerQueueHead
Definition: rxce.c:141
KDPC RxTimerDpc
Definition: rxce.c:143
VOID NTAPI RxTimerDispatch(_In_ struct _KDPC *Dpc, _In_opt_ PVOID DeferredContext, _In_opt_ PVOID SystemArgument1, _In_opt_ PVOID SystemArgument2)
Definition: rxce.c:8502
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233

Referenced by RxDriverEntry().

◆ RxInitializeSrvCallParameters()

NTSTATUS RxInitializeSrvCallParameters ( IN PRX_CONTEXT  RxContext,
IN OUT PSRV_CALL  SrvCall 
)

Definition at line 4921 of file rxce.c.

4924{
4925 PAGED_CODE();
4926
4927 SrvCall->pPrincipalName = NULL;
4928
4929 /* We only have stuff to initialize for file opening from DFS */
4930 if (RxContext->MajorFunction != IRP_MJ_CREATE || RxContext->Create.EaLength == 0)
4931 {
4932 return STATUS_SUCCESS;
4933 }
4934
4935 ASSERT(RxContext->Create.EaBuffer != NULL);
4936
4939}

Referenced by RxCreateSrvCall().

◆ RxInitializeVNetRootParameters()

NTSTATUS RxInitializeVNetRootParameters ( PRX_CONTEXT  RxContext,
OUT LUID LogonId,
OUT PULONG  SessionId,
OUT PUNICODE_STRING UserNamePtr,
OUT PUNICODE_STRING UserDomainNamePtr,
OUT PUNICODE_STRING PasswordPtr,
OUT PULONG  Flags 
)

Definition at line 4963 of file rxce.c.

4971{
4974
4975 PAGED_CODE();
4976
4977 DPRINT("RxInitializeVNetRootParameters(%p, %p, %p, %p, %p, %p, %p)\n", RxContext,
4978 LogonId, SessionId, UserNamePtr, UserDomainNamePtr, PasswordPtr, Flags);
4979
4980 *UserNamePtr = NULL;
4981 *UserDomainNamePtr = NULL;
4982 *PasswordPtr = NULL;
4983 /* By default, that's not CSC instance */
4984 *Flags &= ~VNETROOT_FLAG_CSCAGENT_INSTANCE;
4985
4986 Token = SeQuerySubjectContextToken(&RxContext->Create.NtCreateParameters.SecurityContext->AccessState->SubjectSecurityContext);
4988 {
4989 return STATUS_ACCESS_DENIED;
4990 }
4991
4992 /* Get LogonId */
4994 if (!NT_SUCCESS(Status))
4995 {
4996 return Status;
4997 }
4998
4999 /* And SessionId */
5001 if (!NT_SUCCESS(Status))
5002 {
5003 return Status;
5004 }
5005
5006 if (RxContext->Create.UserName.Buffer != NULL)
5007 {
5010 goto Leave;
5011 }
5012
5013 /* Deal with connection credentials */
5014 if (RxContext->Create.UserDomainName.Buffer != NULL)
5015 {
5018 goto Leave;
5019 }
5020
5021 if (RxContext->Create.Password.Buffer != NULL)
5022 {
5025 goto Leave;
5026 }
5027
5028Leave:
5029 if (NT_SUCCESS(Status))
5030 {
5031 /* If that's a CSC instance, mark it as such */
5032 if (RxIsThisACscAgentOpen(RxContext))
5033 {
5035 }
5036 return Status;
5037 }
5038
5039 return Status;
5040}
NTSTATUS NTAPI SeQueryAuthenticationIdToken(_In_ PACCESS_TOKEN Token, _Out_ PLUID LogonId)
Queries the authentication ID of an access token.
Definition: token.c:2036
NTSTATUS NTAPI SeQuerySessionIdToken(_In_ PACCESS_TOKEN Token, _Out_ PULONG pSessionId)
Queries the session ID of an access token.
Definition: token.c:2004
BOOLEAN NTAPI SeTokenIsRestricted(_In_ PACCESS_TOKEN Token)
Determines if a token is restricted or not, based upon the token flags.
Definition: token.c:2126
BOOLEAN RxIsThisACscAgentOpen(IN PRX_CONTEXT RxContext)
Definition: rxce.c:5226
struct _RX_CONTEXT::@2148::@2160 Create
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define SeQuerySubjectContextToken(SubjectContext)
Definition: sefuncs.h:583

Referenced by RxCreateVNetRoot(), and RxFindOrConstructVirtualNetRoot().

◆ RxInitializeWorkQueue()

VOID RxInitializeWorkQueue ( PRX_WORK_QUEUE  WorkQueue,
WORK_QUEUE_TYPE  WorkQueueType,
ULONG  MaximumNumberOfWorkerThreads,
ULONG  MinimumNumberOfWorkerThreads 
)

Definition at line 5046 of file rxce.c.

5051{
5052 PAGED_CODE();
5053
5054 WorkQueue->Type = WorkQueueType;
5055 WorkQueue->MaximumNumberOfWorkerThreads = MaximumNumberOfWorkerThreads;
5056 WorkQueue->MinimumNumberOfWorkerThreads = MinimumNumberOfWorkerThreads;
5057
5059 WorkQueue->SpinUpRequestPending = FALSE;
5060 WorkQueue->pRundownContext = NULL;
5061 WorkQueue->NumberOfWorkItemsDispatched = 0;
5062 WorkQueue->NumberOfWorkItemsToBeDispatched = 0;
5063 WorkQueue->CumulativeQueueLength = 0;
5064 WorkQueue->NumberOfSpinUpRequests = 0;
5065 WorkQueue->NumberOfActiveWorkerThreads = 0;
5066 WorkQueue->NumberOfIdleWorkerThreads = 0;
5067 WorkQueue->NumberOfFailedSpinUpRequests = 0;
5068 WorkQueue->WorkQueueItemForSpinUpWorkerThreadInUse = 0;
5069 WorkQueue->WorkQueueItemForTearDownWorkQueue.List.Flink = NULL;
5070 WorkQueue->WorkQueueItemForTearDownWorkQueue.WorkerRoutine = NULL;
5071 WorkQueue->WorkQueueItemForTearDownWorkQueue.Parameter = NULL;
5072 WorkQueue->WorkQueueItemForTearDownWorkQueue.pDeviceObject = NULL;
5073 WorkQueue->WorkQueueItemForSpinUpWorkerThread.List.Flink = NULL;
5074 WorkQueue->WorkQueueItemForSpinUpWorkerThread.WorkerRoutine = NULL;
5075 WorkQueue->WorkQueueItemForSpinUpWorkerThread.Parameter = NULL;
5076 WorkQueue->WorkQueueItemForSpinUpWorkerThread.pDeviceObject = NULL;
5077 WorkQueue->WorkQueueItemForSpinDownWorkerThread.List.Flink = NULL;
5078 WorkQueue->WorkQueueItemForSpinDownWorkerThread.WorkerRoutine = NULL;
5079 WorkQueue->WorkQueueItemForSpinDownWorkerThread.Parameter = NULL;
5080 WorkQueue->WorkQueueItemForSpinDownWorkerThread.pDeviceObject = NULL;
5081
5082 KeInitializeQueue(&WorkQueue->Queue, MaximumNumberOfWorkerThreads);
5083 KeInitializeSpinLock(&WorkQueue->SpinLock);
5084}
VOID NTAPI KeInitializeQueue(IN PKQUEUE Queue, IN ULONG Count OPTIONAL)
Definition: queue.c:148
@ RxWorkQueueActive
Definition: rxworkq.h:24

Referenced by RxInitializeWorkQueueDispatcher().

◆ RxInitializeWorkQueueDispatcher()

NTSTATUS RxInitializeWorkQueueDispatcher ( PRX_WORK_QUEUE_DISPATCHER  Dispatcher)

Definition at line 5090 of file rxce.c.

5092{
5094 ULONG MaximumNumberOfWorkerThreads;
5095
5096 PAGED_CODE();
5097
5098 /* Number of threads will depend on system capacity */
5100 {
5101 MaximumNumberOfWorkerThreads = 5;
5102 }
5103 else
5104 {
5105 MaximumNumberOfWorkerThreads = 10;
5106 }
5107
5108 /* Initialize the work queues */
5110 MaximumNumberOfWorkerThreads, 1);
5113
5114 /* And start the worker threads */
5117 &Dispatcher->WorkQueue[HyperCriticalWorkQueue]);
5118 if (!NT_SUCCESS(Status))
5119 {
5120 return Status;
5121 }
5122
5125 &Dispatcher->WorkQueue[CriticalWorkQueue]);
5126 if (!NT_SUCCESS(Status))
5127 {
5128 return Status;
5129 }
5130
5133 &Dispatcher->WorkQueue[DelayedWorkQueue]);
5134 return Status;
5135}
MM_SYSTEMSIZE NTAPI MmQuerySystemSize(VOID)
Definition: mmsup.c:257
NTSTATUS RxSpinUpWorkerThread(PRX_WORK_QUEUE WorkQueue, PRX_WORKERTHREAD_ROUTINE Routine, PVOID Parameter)
Definition: rxce.c:8097
VOID NTAPI RxBootstrapWorkerThreadDispatcher(IN PVOID WorkQueue)
Definition: rxce.c:708
VOID RxInitializeWorkQueue(PRX_WORK_QUEUE WorkQueue, WORK_QUEUE_TYPE WorkQueueType, ULONG MaximumNumberOfWorkerThreads, ULONG MinimumNumberOfWorkerThreads)
Definition: rxce.c:5046
RX_WORK_QUEUE WorkQueue[RxMaximumWorkQueue]
Definition: rxworkq.h:62
@ MmLargeSystem
Definition: mmtypes.h:147

Referenced by RxInitializeDispatcher().

◆ RxInitiateSrvOpenKeyAssociation()

VOID RxInitiateSrvOpenKeyAssociation ( IN OUT PSRV_OPEN  SrvOpen)

Definition at line 5141 of file rxce.c.

5143{
5144 PRX_BUFFERING_MANAGER BufferingManager;
5145
5146 PAGED_CODE();
5147
5148 SrvOpen->Key = NULL;
5149
5150 /* Just keep track of the opening request */
5151 BufferingManager = &((PSRV_CALL)((PFCB)SrvOpen->pFcb)->VNetRoot->pNetRoot->pSrvCall)->BufferingManager;
5153
5154 InitializeListHead(&SrvOpen->SrvOpenKeyList);
5155}

◆ RxInsertWorkQueueItem()

NTSTATUS RxInsertWorkQueueItem ( PRDBSS_DEVICE_OBJECT  pMRxDeviceObject,
WORK_QUEUE_TYPE  WorkQueueType,
PRX_WORK_QUEUE_ITEM  WorkQueueItem 
)

Definition at line 5161 of file rxce.c.

5165{
5166 KIRQL OldIrql;
5168 BOOLEAN SpinUpThreads;
5170
5171 /* No dispatcher, nothing to insert */
5173 {
5174 return STATUS_UNSUCCESSFUL;
5175 }
5176
5177 /* Get the work queue */
5179
5180 KeAcquireSpinLock(&WorkQueue->SpinLock, &OldIrql);
5181 /* Only insert if the work queue is in decent state */
5182 if (WorkQueue->State != RxWorkQueueActive || pMRxDeviceObject->DispatcherContext.pTearDownEvent != NULL)
5183 {
5185 }
5186 else
5187 {
5188 SpinUpThreads = FALSE;
5189 WorkQueueItem->pDeviceObject = pMRxDeviceObject;
5191 WorkQueue->CumulativeQueueLength += WorkQueue->NumberOfWorkItemsToBeDispatched;
5192 InterlockedIncrement(&WorkQueue->NumberOfWorkItemsToBeDispatched);
5193
5194 /* If required (and possible!), spin up a new worker thread */
5195 if (WorkQueue->NumberOfIdleWorkerThreads < WorkQueue->NumberOfWorkItemsToBeDispatched &&
5196 WorkQueue->NumberOfActiveWorkerThreads < WorkQueue->MaximumNumberOfWorkerThreads &&
5197 !WorkQueue->SpinUpRequestPending)
5198 {
5199 WorkQueue->SpinUpRequestPending = TRUE;
5200 SpinUpThreads = TRUE;
5201 }
5202
5204 }
5205 KeReleaseSpinLock(&WorkQueue->SpinLock, OldIrql);
5206
5207 /* If we failed, return and still not insert item */
5208 if (!NT_SUCCESS(Status))
5209 {
5210 return Status;
5211 }
5212
5213 /* All fine, insert the item */
5214 KeInsertQueue(&WorkQueue->Queue, &WorkQueueItem->List);
5215
5216 /* And start a new worker thread if needed */
5217 if (SpinUpThreads)
5218 {
5220 }
5221
5222 return Status;
5223}
LONG NTAPI KeInsertQueue(IN PKQUEUE Queue, IN PLIST_ENTRY Entry)
Definition: queue.c:198
VOID RxSpinUpWorkerThreads(PRX_WORK_QUEUE WorkQueue)
Definition: rxce.c:8157
PRDBSS_DEVICE_OBJECT pDeviceObject
Definition: rxworkq.h:12

Referenced by RxDispatchToWorkerThread(), and RxPostToWorkerThread().

◆ RxIsThisACscAgentOpen()

BOOLEAN RxIsThisACscAgentOpen ( IN PRX_CONTEXT  RxContext)

Definition at line 5226 of file rxce.c.

5228{
5229 BOOLEAN CscAgent;
5230
5231 CscAgent = FALSE;
5232
5233 /* Client Side Caching is DFS stuff - we don't support it */
5234 if (RxContext->Create.EaLength != 0)
5235 {
5237 }
5238
5239 if (RxContext->Create.NtCreateParameters.DfsNameContext != NULL &&
5240 ((PDFS_NAME_CONTEXT)RxContext->Create.NtCreateParameters.DfsNameContext)->NameContextType == 0xAAAAAAAA)
5241 {
5242 CscAgent = TRUE;
5243 }
5244
5245 return CscAgent;
5246}

Referenced by RxInitializeVNetRootParameters().

◆ RxLockUserBuffer()

VOID RxLockUserBuffer ( IN PRX_CONTEXT  RxContext,
IN LOCK_OPERATION  Operation,
IN ULONG  BufferLength 
)

Definition at line 5249 of file rxce.c.

5253{
5254 PIRP Irp;
5255 PMDL Mdl = NULL;
5256
5257 PAGED_CODE();
5258
5259 _SEH2_TRY
5260 {
5261 Irp = RxContext->CurrentIrp;
5262 /* If we already have a MDL, make sure it's locked */
5263 if (Irp->MdlAddress != NULL)
5264 {
5265 ASSERT(RxLowIoIsMdlLocked(Irp->MdlAddress));
5266 }
5267 else
5268 {
5269 /* That likely means the driver asks for buffered IOs - we don't support it! */
5271
5272 /* If we have a real length */
5273 if (BufferLength > 0)
5274 {
5275 /* Allocate a MDL and lock it */
5276 Mdl = IoAllocateMdl(Irp->UserBuffer, BufferLength, FALSE, FALSE, Irp);
5277 if (Mdl == NULL)
5278 {
5279 RxContext->StoredStatus = STATUS_INSUFFICIENT_RESOURCES;
5281 }
5282
5283 MmProbeAndLockPages(Mdl, Irp->RequestorMode, Operation);
5284 }
5285 }
5286 }
5288 {
5290
5292
5293 /* Free the possible MDL we have allocated */
5294 IoFreeMdl(Mdl);
5295 Irp->MdlAddress = NULL;
5296
5297 RxContext->Flags |= RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT;
5298
5299 /* Fix status */
5301 {
5303 }
5304
5305 RxContext->IoStatusBlock.Status = Status;
5307 }
5308 _SEH2_END;
5309}
#define IoFreeMdl
Definition: fxmdl.h:89
#define IoAllocateMdl
Definition: fxmdl.h:88
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define RxLowIoIsMdlLocked(MDL)
Definition: lowio.h:8
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:931
BOOLEAN NTAPI FsRtlIsNtstatusExpected(IN NTSTATUS NtStatus)
Definition: filter.c:61
#define ExRaiseStatus
Definition: ntoskrnl.h:114
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
@ RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT
Definition: rxcontx.h:306
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
#define IRP_INPUT_OPERATION

Referenced by RxLowIoSubmit().

◆ RxLowIoCompletionTail()

NTSTATUS RxLowIoCompletionTail ( IN PRX_CONTEXT  RxContext)

Definition at line 5315 of file rxce.c.

5317{
5320
5321 PAGED_CODE();
5322
5323 DPRINT("RxLowIoCompletionTail(%p)\n", RxContext);
5324
5325 /* Only continue if we're at APC_LEVEL or lower */
5326 if (RxShouldPostCompletion() &&
5327 !BooleanFlagOn(RxContext->LowIoContext.Flags, LOWIO_CONTEXT_FLAG_CAN_COMPLETE_AT_DPC_LEVEL))
5328 {
5330 }
5331
5332 /* Call the completion routine */
5333 DPRINT("Calling completion routine: %p\n", RxContext->LowIoContext.CompletionRoutine);
5334 Status = RxContext->LowIoContext.CompletionRoutine(RxContext);
5336 {
5337 return Status;
5338 }
5339
5340 /* If it was a RW operation, for a paging file ... */
5341 Operation = RxContext->LowIoContext.Operation;
5343 {
5344 /* Remove ourselves from the list and resume operations */
5345 if (BooleanFlagOn(RxContext->LowIoContext.ParamsFor.ReadWrite.Flags, LOWIO_READWRITEFLAG_PAGING_IO))
5346 {
5348 RemoveEntryList(&RxContext->RxContextSerializationQLinks);
5349 RxContext->RxContextSerializationQLinks.Flink = NULL;
5350 RxContext->RxContextSerializationQLinks.Blink = NULL;
5353 }
5354 }
5355 else
5356 {
5357 /* Sanity check: we had known operation */
5359 }
5360
5361 /* If not sync operation, complete now. Otherwise, caller has already completed */
5362 if (!BooleanFlagOn(RxContext->LowIoContext.Flags, LOWIO_CONTEXT_FLAG_SYNCCALL))
5363 {
5364 RxCompleteRequest(RxContext, Status);
5365 }
5366
5367 DPRINT("Status: %x\n", Status);
5368 return Status;
5369}
#define RxShouldPostCompletion()
Definition: mrx.h:7
@ LOWIO_OP_MAXIMUM
Definition: mrx.h:244
#define LOWIO_CONTEXT_FLAG_SYNCCALL
Definition: mrx.h:320
#define LOWIO_CONTEXT_FLAG_CAN_COMPLETE_AT_DPC_LEVEL
Definition: mrx.h:323
VOID FASTCALL ExReleaseFastMutexUnsafe(IN OUT PFAST_MUTEX FastMutex)
Definition: fmutex.c:86
VOID FASTCALL ExAcquireFastMutexUnsafe(IN OUT PFAST_MUTEX FastMutex)
Definition: fmutex.c:75
FAST_MUTEX RxLowIoPagingIoSyncMutex
Definition: rxce.c:136
VOID RxResumeBlockedOperations_ALL(IN OUT PRX_CONTEXT RxContext)
Definition: rxce.c:7741
#define STATUS_RETRY
Definition: udferr_usr.h:182

Referenced by RxLowIoSubmit().

◆ RxLowIoPopulateFsctlInfo()

NTSTATUS NTAPI RxLowIoPopulateFsctlInfo ( IN PRX_CONTEXT  RxContext)

Definition at line 5376 of file rxce.c.

5378{
5379 PMDL Mdl;
5380 PIRP Irp;
5381 UCHAR Method;
5383
5384 PAGED_CODE();
5385
5386 DPRINT("RxLowIoPopulateFsctlInfo(%p)\n", RxContext);
5387
5388 Irp = RxContext->CurrentIrp;
5389 Stack = RxContext->CurrentIrpSp;
5390
5391 /* Copy stack parameters */
5392 RxContext->LowIoContext.ParamsFor.FsCtl.FsControlCode = Stack->Parameters.FileSystemControl.FsControlCode;
5393 RxContext->LowIoContext.ParamsFor.FsCtl.InputBufferLength = Stack->Parameters.FileSystemControl.InputBufferLength;
5394 RxContext->LowIoContext.ParamsFor.FsCtl.OutputBufferLength = Stack->Parameters.FileSystemControl.OutputBufferLength;
5395 RxContext->LowIoContext.ParamsFor.FsCtl.MinorFunction = Stack->MinorFunction;
5396 Method = METHOD_FROM_CTL_CODE(RxContext->LowIoContext.ParamsFor.FsCtl.FsControlCode);
5397
5398 /* Same buffer in case of buffered */
5399 if (Method == METHOD_BUFFERED)
5400 {
5401 RxContext->LowIoContext.ParamsFor.FsCtl.pInputBuffer = Irp->AssociatedIrp.SystemBuffer;
5402 RxContext->LowIoContext.ParamsFor.FsCtl.pOutputBuffer = Irp->AssociatedIrp.SystemBuffer;
5403
5404 return STATUS_SUCCESS;
5405 }
5406
5407 /* Two buffers for neither */
5408 if (Method == METHOD_NEITHER)
5409 {
5410 RxContext->LowIoContext.ParamsFor.FsCtl.pInputBuffer = Stack->Parameters.FileSystemControl.Type3InputBuffer;
5411 RxContext->LowIoContext.ParamsFor.FsCtl.pOutputBuffer = Irp->UserBuffer;
5412
5413 return STATUS_SUCCESS;
5414 }
5415
5416 /* Only IN/OUT remain */
5417 ASSERT(Method == METHOD_IN_DIRECT || Method == METHOD_OUT_DIRECT);
5418
5419 /* Use system buffer for input */
5420 RxContext->LowIoContext.ParamsFor.FsCtl.pInputBuffer = Irp->AssociatedIrp.SystemBuffer;
5421 /* And MDL for output */
5422 Mdl = Irp->MdlAddress;
5423 if (Mdl != NULL)
5424 {
5425 RxContext->LowIoContext.ParamsFor.FsCtl.pOutputBuffer = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);
5426 if (RxContext->LowIoContext.ParamsFor.FsCtl.pOutputBuffer == NULL)
5427 {
5429 }
5430 }
5431 else
5432 {
5433 RxContext->LowIoContext.ParamsFor.FsCtl.pOutputBuffer = NULL;
5434 }
5435
5436 return STATUS_SUCCESS;
5437}
@ NormalPagePriority
Definition: imports.h:56
#define METHOD_NEITHER
Definition: nt_native.h:597
#define METHOD_OUT_DIRECT
Definition: nt_native.h:596
#define METHOD_BUFFERED
Definition: nt_native.h:594
#define METHOD_IN_DIRECT
Definition: nt_native.h:595
#define METHOD_FROM_CTL_CODE(ctrlCode)
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by RxLowIoSubmit().

◆ RxLowIoSubmit()

NTSTATUS NTAPI RxLowIoSubmit ( IN PRX_CONTEXT  RxContext,
IN PLOWIO_COMPLETION_ROUTINE  CompletionRoutine 
)

Definition at line 5441 of file rxce.c.

5444{
5447 BOOLEAN Synchronous;
5448 PLOWIO_CONTEXT LowIoContext;
5449
5450 DPRINT("RxLowIoSubmit(%p, %p)\n", RxContext, CompletionRoutine);
5451
5452 PAGED_CODE();
5453
5454 LowIoContext = &RxContext->LowIoContext;
5455 Synchronous = !BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION);
5456
5457 LowIoContext->CompletionRoutine = CompletionRoutine;
5458
5460 Operation = LowIoContext->Operation;
5461 switch (Operation)
5462 {
5463 case LOWIO_OP_READ:
5464 case LOWIO_OP_WRITE:
5465 /* Check that the parameters were properly set by caller
5466 * See comment in RxInitializeLowIoContext()
5467 */
5468 ASSERT(LowIoContext->ParamsFor.ReadWrite.ByteOffset != 0xFFFFFFEE);
5469 ASSERT(LowIoContext->ParamsFor.ReadWrite.ByteCount != 0xEEEEEEEE);
5470
5471 /* Lock the buffer */
5472 RxLockUserBuffer(RxContext,
5474 LowIoContext->ParamsFor.ReadWrite.ByteCount);
5475 if (RxNewMapUserBuffer(RxContext) == NULL)
5476 {
5478 }
5479 LowIoContext->ParamsFor.ReadWrite.Buffer = RxContext->CurrentIrp->MdlAddress;
5480
5481 /* If that's a paging IO, initialize serial operation */
5483 {
5484 PFCB Fcb;
5485
5486 Fcb = (PFCB)RxContext->pFcb;
5487
5489 RxContext->BlockedOpsMutex = &RxLowIoPagingIoSyncMutex;
5490 if (Operation == LOWIO_OP_READ)
5491 {
5492 InsertTailList(&Fcb->Specific.Fcb.PagingIoReadsOutstanding, &RxContext->RxContextSerializationQLinks);
5493 }
5494 else
5495 {
5496 InsertTailList(&Fcb->Specific.Fcb.PagingIoWritesOutstanding, &RxContext->RxContextSerializationQLinks);
5497 }
5498
5500 }
5501
5502 break;
5503
5504 case LOWIO_OP_FSCTL:
5505 case LOWIO_OP_IOCTL:
5506 /* Set FSCTL/IOCTL parameters */
5507 Status = RxLowIoPopulateFsctlInfo(RxContext);
5508 /* Check whether we're consistent: a length means a buffer */
5509 if (NT_SUCCESS(Status))
5510 {
5511 if ((LowIoContext->ParamsFor.FsCtl.InputBufferLength > 0 &&
5512 LowIoContext->ParamsFor.FsCtl.pInputBuffer == NULL) ||
5513 (LowIoContext->ParamsFor.FsCtl.OutputBufferLength > 0 &&
5514 LowIoContext->ParamsFor.FsCtl.pOutputBuffer == NULL))
5515 {
5517 }
5518 }
5519 break;
5520
5521 /* Nothing to do */
5524 case LOWIO_OP_UNLOCK:
5527 case LOWIO_OP_CLEAROUT:
5528 break;
5529
5530 default:
5531 ASSERT(FALSE);
5533 break;
5534 }
5535
5536 /* No need to perform extra init in case of posting */
5537 RxContext->Flags |= RX_CONTEXT_FLAG_NO_PREPOSTING_NEEDED;
5538
5539 /* Preflight checks were OK, time to submit */
5540 if (NT_SUCCESS(Status))
5541 {
5543
5544 if (!Synchronous)
5545 {
5546 InterlockedIncrement((volatile long *)&RxContext->ReferenceCount);
5547 /* If not synchronous, we're likely to return before the operation is finished */
5548 if (!BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP))
5549 {
5550 IoMarkIrpPending(RxContext->CurrentIrp);
5551 }
5552 }
5553
5554 Dispatch = RxContext->RxDeviceObject->Dispatch;
5555 if (Dispatch != NULL)
5556 {
5557 /* We'll try to execute until the mini-rdr doesn't return pending */
5558 do
5559 {
5560 RxContext->IoStatusBlock.Information = 0;
5561
5562 MINIRDR_CALL(Status, RxContext, Dispatch, MRxLowIOSubmit[Operation], (RxContext));
5563 if (Status == STATUS_PENDING)
5564 {
5565 /* Unless it's not synchronous, caller will be happy with pending op */
5566 if (!Synchronous)
5567 {
5568 return Status;
5569 }
5570
5571 RxWaitSync(RxContext);
5572 Status = RxContext->IoStatusBlock.Status;
5573 }
5574 else
5575 {
5576 if (!Synchronous)
5577 {
5578 /* We had marked the IRP pending, whereas the operation finished, drop that */
5579 if (Status != STATUS_RETRY)
5580 {
5581 if (!BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP))
5582 {
5583 RxContext->CurrentIrpSp->Flags &= ~SL_PENDING_RETURNED;
5584 }
5585
5586 InterlockedDecrement((volatile long *)&RxContext->ReferenceCount);
5587 }
5588 }
5589 }
5590 } while (Status == STATUS_PENDING);
5591 }
5592 else
5593 {
5595 }
5596 }
5597
5598 /* Call completion and return */
5599 RxContext->IoStatusBlock.Status = Status;
5600 LowIoContext->Flags |= LOWIO_CONTEXT_FLAG_SYNCCALL;
5601 return RxLowIoCompletionTail(RxContext);
5602}
IoMarkIrpPending(Irp)
VOID RxLockUserBuffer(IN PRX_CONTEXT RxContext, IN LOCK_OPERATION Operation, IN ULONG BufferLength)
Definition: rxce.c:5249
NTSTATUS RxLowIoCompletionTail(IN PRX_CONTEXT RxContext)
Definition: rxce.c:5315
PVOID RxNewMapUserBuffer(PRX_CONTEXT RxContext)
Definition: rxce.c:5775
NTSTATUS NTAPI RxLowIoPopulateFsctlInfo(IN PRX_CONTEXT RxContext)
Definition: rxce.c:5376
#define RxWaitSync(RxContext)
Definition: rxcontx.h:412
@ RX_CONTEXT_FLAG_NO_PREPOSTING_NEEDED
Definition: rxcontx.h:302
@ RX_CONTEXT_FLAG_IN_FSP
Definition: rxcontx.h:290
#define MINIRDR_CALL(STATUS, CONTEXT, DISPATCH, FUNC, ARGLIST)
Definition: rxcontx.h:389
USHORT Flags
Definition: mrx.h:282
PLOWIO_COMPLETION_ROUTINE CompletionRoutine
Definition: mrx.h:283
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine
Definition: wdfrequest.h:895
@ IoReadAccess
Definition: ketypes.h:863
@ IoWriteAccess
Definition: ketypes.h:864

◆ RxMapSystemBuffer()

PVOID RxMapSystemBuffer ( IN PRX_CONTEXT  RxContext)

Definition at line 5608 of file rxce.c.

5610{
5611 PIRP Irp;
5612
5613 PAGED_CODE();
5614
5615 Irp = RxContext->CurrentIrp;
5616 /* We should have a MDL (buffered IOs are not supported!) */
5617 if (Irp->MdlAddress != NULL)
5618 {
5619 ASSERT(FALSE);
5621 }
5622
5623 /* Just return system buffer */
5624 return Irp->AssociatedIrp.SystemBuffer;
5625}

◆ RxMarkFobxOnCleanup()

VOID RxMarkFobxOnCleanup ( PFOBX  pFobx,
PBOOLEAN  NeedPurge 
)

Definition at line 5631 of file rxce.c.

5634{
5635 PFCB Fcb;
5636 PFOBX ScavengerFobx;
5637 LARGE_INTEGER TickCount;
5638 PRDBSS_SCAVENGER Scavenger;
5639
5640 PAGED_CODE();
5641
5642 /* No FOBX, nothing to mark */
5643 if (pFobx == NULL)
5644 {
5645 return;
5646 }
5647
5648 /* Query time for close */
5649 KeQueryTickCount(&TickCount);
5650
5651 Fcb = (PFCB)pFobx->pSrvOpen->pFcb;
5653
5654 Scavenger = Fcb->RxDeviceObject->pRdbssScavenger;
5656
5657 ScavengerFobx = NULL;
5658 /* If that's not a file, or even not a disk resource, just mark as dormant */
5659 if (NodeType(Fcb) != RDBSS_NTC_STORAGE_TYPE_FILE || Fcb->VNetRoot->pNetRoot->DeviceType != FILE_DEVICE_DISK)
5660 {
5661 SetFlag(pFobx->Flags, FOBX_FLAG_MARKED_AS_DORMANT);
5663 ++Scavenger->NumberOfDormantFiles;
5664 }
5665 else
5666 {
5667 ASSERT(Scavenger->NumberOfDormantFiles >= 0);
5668 /* If we're about to reach the maximum dormant of FOBX */
5669 if (Scavenger->NumberOfDormantFiles >= Scavenger->MaximumNumberOfDormantFiles)
5670 {
5671 /* This should never be wrong... */
5672 if (!IsListEmpty(&Scavenger->ClosePendingFobxsList))
5673 {
5674 /* Then, take the first from the list (oldest) and save it for later purge */
5675 ScavengerFobx = CONTAINING_RECORD(Scavenger->ClosePendingFobxsList.Flink, FOBX, ClosePendingList);
5676 if (ScavengerFobx->pSrvOpen != NULL && ScavengerFobx->pSrvOpen->pFcb == RX_GET_MRX_FCB(Fcb))
5677 {
5678 *NeedPurge = TRUE;
5679 ScavengerFobx = NULL;
5680 }
5681 else
5682 {
5683 RxReferenceNetFobx(ScavengerFobx);
5684 }
5685 }
5686 }
5687
5688 /* Mark ourselves as dormant */
5689 SetFlag(pFobx->Flags, FOBX_FLAG_MARKED_AS_DORMANT);
5690 pFobx->CloseTime.QuadPart = TickCount.QuadPart;
5691
5692 /* And insert us in the list of dormant files */
5694 /* If scavenger was inactive, start it */
5695 if (Scavenger->NumberOfDormantFiles++ == 0 && Scavenger->State == RDBSS_SCAVENGER_INACTIVE)
5696 {
5697 Scavenger->State = RDBSS_SCAVENGER_DORMANT;
5699 Fcb->RxDeviceObject, Scavenger->TimeLimit);
5700 }
5701 }
5702
5704
5705 /* If we had reached max */
5706 if (ScavengerFobx != NULL)
5707 {
5709
5710 /* Purge the oldest FOBX */
5711 Status = RxPurgeFobxFromCache(ScavengerFobx);
5712 if (Status != STATUS_SUCCESS)
5713 {
5714 *NeedPurge = TRUE;
5715 }
5716 }
5717}
#define RxReferenceNetFobx(Fobx)
Definition: fcb.h:415
#define FOBX_FLAG_MARKED_AS_DORMANT
Definition: fcb.h:299
NTSTATUS RxPurgeFobxFromCache(PFOBX FobxToBePurged)
Definition: rxce.c:7087
NTSTATUS NTAPI RxPostOneShotTimerRequest(IN PRDBSS_DEVICE_OBJECT pDeviceObject, IN PRX_WORK_ITEM pWorkItem, IN PRX_WORKERTHREAD_ROUTINE Routine, IN PVOID pContext, IN LARGE_INTEGER TimeInterval)
Definition: rxce.c:6362
VOID NTAPI RxScavengerTimerRoutine(PVOID Context)
Definition: rxce.c:7964
@ RDBSS_SCAVENGER_INACTIVE
Definition: scavengr.h:50
@ RDBSS_SCAVENGER_DORMANT
Definition: scavengr.h:51
#define KeQueryTickCount(CurrentCount)
Definition: ke.h:43
PRDBSS_SCAVENGER pRdbssScavenger
Definition: rxstruc.h:129
RX_WORK_ITEM WorkItem
Definition: scavengr.h:75
LARGE_INTEGER TimeLimit
Definition: scavengr.h:61
LIST_ENTRY ClosePendingFobxsList
Definition: scavengr.h:74
volatile LONG NumberOfDormantFiles
Definition: scavengr.h:60
LONG MaximumNumberOfDormantFiles
Definition: scavengr.h:59
RDBSS_SCAVENGER_STATE State
Definition: scavengr.h:58

◆ RxMarkFobxOnClose()

VOID RxMarkFobxOnClose ( PFOBX  Fobx)

Definition at line 5723 of file rxce.c.

5725{
5726 PFCB Fcb;
5727 PRDBSS_SCAVENGER Scavenger;
5728
5729 PAGED_CODE();
5730
5731 /* No FOBX, nothing to mark */
5732 if (Fobx == NULL)
5733 {
5734 return;
5735 }
5736
5737 Fcb = (PFCB)Fobx->pSrvOpen->pFcb;
5739
5740 Scavenger = Fcb->RxDeviceObject->pRdbssScavenger;
5741
5743 /* Only mark it if it was already marked as dormant */
5745 {
5746 /* If FCB wasn't already decrement, do it now */
5747 if (!Fobx->fOpenCountDecremented)
5748 {
5749 Fcb = (PFCB)Fobx->pSrvOpen->pFcb;
5751 InterlockedDecrement((volatile long *)&Fcb->OpenCount);
5752
5754 }
5755
5756 /* We're no longer dormant */
5759 }
5760
5761 /* If we were inserted in the scavenger, drop ourselves out */
5762 if (!IsListEmpty(&Fobx->ClosePendingList))
5763 {
5766 }
5767
5769}
CLONG OpenCount
Definition: fatstruc.h:881

◆ RxNewMapUserBuffer()

PVOID RxNewMapUserBuffer ( PRX_CONTEXT  RxContext)

Definition at line 5775 of file rxce.c.

5777{
5778 PIRP Irp;
5779
5780 PAGED_CODE();
5781
5782 Irp = RxContext->CurrentIrp;
5783 if (Irp->MdlAddress != NULL)
5784 {
5786 }
5787
5788 return Irp->UserBuffer;
5789}

Referenced by RxCommonRead(), RxCommonWrite(), RxLowIoSubmit(), and RxQueryDirectory().

◆ RxNoOpAcquire()

BOOLEAN NTAPI RxNoOpAcquire ( IN PVOID  Fcb,
IN BOOLEAN  Wait 
)

Definition at line 5793 of file rxce.c.

5796{
5798 return FALSE;
5799}

◆ RxNoOpRelease()

VOID NTAPI RxNoOpRelease ( IN PVOID  Fcb)

Definition at line 5803 of file rxce.c.

5805{
5807}

◆ RxOrphanSrvOpens()

VOID RxOrphanSrvOpens ( IN PV_NET_ROOT  ThisVNetRoot)

Definition at line 5817 of file rxce.c.

5819{
5820 PFCB Fcb;
5821 USHORT Bucket;
5822 PNET_ROOT NetRoot;
5823 PRX_FCB_TABLE FcbTable;
5824 PRX_PREFIX_TABLE PrefixTable;
5825
5826 PAGED_CODE();
5827
5828 /* Mailslot won't have any SRV_OPEN (to orphan) */
5829 NetRoot = (PNET_ROOT)ThisVNetRoot->pNetRoot;
5830 if (NetRoot->Type == NET_ROOT_MAILSLOT)
5831 {
5832 return;
5833 }
5834
5835 PrefixTable = NetRoot->pSrvCall->RxDeviceObject->pRxNetNameTable;
5837
5838 FcbTable = &NetRoot->FcbTable;
5840
5841 _SEH2_TRY
5842 {
5843 /* Now, we'll browse all the FCBs attached, and orphan related SRV_OPENs */
5844 for (Bucket = 0; Bucket < FcbTable->NumberOfBuckets; ++Bucket)
5845 {
5846 PLIST_ENTRY BucketList, Entry;
5847
5848 BucketList = &FcbTable->HashBuckets[Bucket];
5849 Entry = BucketList->Flink;
5850 while (Entry != BucketList)
5851 {
5852 Fcb = CONTAINING_RECORD(Entry, FCB, FcbTableEntry.HashLinks);
5853 Entry = Entry->Flink;
5854
5856 RxOrphanSrvOpensForThisFcb(Fcb, ThisVNetRoot, FALSE);
5857 }
5858 }
5859
5860 /* Of course, don't forget about NULL-entry */
5861 if (FcbTable->TableEntryForNull != NULL)
5862 {
5863 Fcb = CONTAINING_RECORD(FcbTable->TableEntryForNull, FCB, FcbTableEntry.HashLinks);
5865 RxOrphanSrvOpensForThisFcb(Fcb, ThisVNetRoot, FALSE);
5866 }
5867 }
5869 {
5870 RxReleaseFcbTableLock(FcbTable);
5871 }
5872 _SEH2_END;
5873}
#define NET_ROOT_MAILSLOT
Definition: mrxfcb.h:34
VOID RxOrphanSrvOpensForThisFcb(IN PFCB Fcb, IN PV_NET_ROOT ThisVNetRoot, IN BOOLEAN OrphanAll)
Definition: rxce.c:5876
PRX_FCB_TABLE_ENTRY TableEntryForNull
Definition: fcbtable.h:26

Referenced by RxFinalizeVNetRoot().

◆ RxOrphanSrvOpensForThisFcb()

VOID RxOrphanSrvOpensForThisFcb ( IN PFCB  Fcb,
IN PV_NET_ROOT  ThisVNetRoot,
IN BOOLEAN  OrphanAll 
)

Definition at line 5876 of file rxce.c.

5880{
5882}

Referenced by RxOrphanSrvOpens().

◆ RxOrphanThisFcb()

VOID RxOrphanThisFcb ( PFCB  Fcb)

Definition at line 5810 of file rxce.c.

5812{
5814}

◆ RxpAcquirePrefixTableLockExclusive()

BOOLEAN RxpAcquirePrefixTableLockExclusive ( PRX_PREFIX_TABLE  pTable,
BOOLEAN  Wait,
BOOLEAN  ProcessBufferingStateChangeRequests 
)

Definition at line 5905 of file rxce.c.

5909{
5910 PAGED_CODE();
5911
5912 DPRINT("RxpAcquirePrefixTableLockExclusive(%p, %d, %d) -> %d\n", pTable, Wait, ProcessBufferingStateChangeRequests,
5913 pTable->TableLock.ActiveEntries);
5914
5915 return ExAcquireResourceExclusiveLite(&pTable->TableLock, Wait);
5916}
static const EHCI_PERIOD pTable[]
Definition: usbehci.c:29

◆ RxpAcquirePrefixTableLockShared()

BOOLEAN RxpAcquirePrefixTableLockShared ( PRX_PREFIX_TABLE  pTable,
BOOLEAN  Wait,
BOOLEAN  ProcessBufferingStateChangeRequests 
)

Definition at line 5888 of file rxce.c.

5892{
5893 PAGED_CODE();
5894
5895 DPRINT("RxpAcquirePrefixTableLockShared(%p, %d, %d) -> %d\n", pTable, Wait, ProcessBufferingStateChangeRequests,
5896 pTable->TableLock.ActiveEntries);
5897
5898 return ExAcquireResourceSharedLite(&pTable->TableLock, Wait);
5899}

◆ RxpDereferenceAndFinalizeNetFcb()

BOOLEAN RxpDereferenceAndFinalizeNetFcb ( OUT PFCB  ThisFcb,
IN PRX_CONTEXT  RxContext,
IN BOOLEAN  RecursiveFinalize,
IN BOOLEAN  ForceFinalize 
)

Definition at line 5922 of file rxce.c.

5927{
5929 ULONG References;
5930 PNET_ROOT NetRoot;
5931 BOOLEAN ResourceAcquired, NetRootReferenced, Freed;
5932
5933 PAGED_CODE();
5934
5935 ASSERT(!ForceFinalize);
5936 ASSERT(NodeTypeIsFcb(ThisFcb));
5938
5939 /* Unless we're recursively finalizing, or forcing, if FCB is still in use, quit */
5940 References = InterlockedDecrement((volatile long *)&ThisFcb->NodeReferenceCount);
5941 if (!ForceFinalize && !RecursiveFinalize && (ThisFcb->OpenCount != 0 || ThisFcb->UncleanCount != 0 || References > 1))
5942 {
5943 return FALSE;
5944 }
5945
5946 Freed = FALSE;
5948 NetRoot = (PNET_ROOT)ThisFcb->VNetRoot->pNetRoot;
5949 ResourceAcquired = FALSE;
5950 NetRootReferenced = FALSE;
5951 /* If FCB isn't orphaned, it still have context attached */
5952 if (!BooleanFlagOn(ThisFcb->FcbState, FCB_STATE_ORPHANED))
5953 {
5954 /* Don't let NetRoot go away before we're done */
5955 RxReferenceNetRoot(NetRoot);
5956 NetRootReferenced = TRUE;
5957
5958 /* Try to acquire the table lock exclusively */
5959 if (!RxIsFcbTableLockExclusive(&NetRoot->FcbTable))
5960 {
5961 RxReferenceNetFcb(ThisFcb);
5962
5964 {
5965 if (RxContext != NULL && RxContext != CHANGE_BUFFERING_STATE_CONTEXT &&
5967 {
5968 RxContext->Flags |= RX_CONTEXT_FLAG_BYPASS_VALIDOP_CHECK;
5969 }
5970
5971 RxReleaseFcb(RxContext, ThisFcb);
5972
5974
5975 Status = RxAcquireExclusiveFcb(RxContext, ThisFcb);
5976 }
5977
5978 References = RxDereferenceNetFcb(ThisFcb);
5979
5980 ResourceAcquired = TRUE;
5981 }
5982 }
5983
5984 /* If locking was OK (or not needed!), attempt finalization */
5985 if (Status == STATUS_SUCCESS)
5986 {
5987 Freed = RxFinalizeNetFcb(ThisFcb, RecursiveFinalize, ForceFinalize, References);
5988 }
5989
5990 /* Release table lock if acquired */
5991 if (ResourceAcquired)
5992 {
5994 }
5995
5996 /* We don't need the NetRoot anylonger */
5997 if (NetRootReferenced)
5998 {
6000 }
6001
6002 return Freed;
6003}
BOOLEAN RxFinalizeNetFcb(OUT PFCB ThisFcb, IN BOOLEAN RecursiveFinalize, IN BOOLEAN ForceFinalize, IN LONG ReferenceCount)
Definition: rxce.c:2832
#define RxReleaseFcb(R, F)
Definition: rxprocs.h:186

◆ RxpDereferenceNetFcb()

LONG RxpDereferenceNetFcb ( PFCB  Fcb)

Definition at line 6009 of file rxce.c.

6011{
6012 LONG NewCount;
6013
6014 PAGED_CODE();
6015
6017
6018 NewCount = InterlockedDecrement((volatile long *)&Fcb->NodeReferenceCount);
6019 ASSERT(NewCount >= 0);
6020
6021 PRINT_REF_COUNT(NETFCB, NewCount);
6022
6023 return NewCount;
6024}

◆ RxpDestroySrvCall()

VOID NTAPI RxpDestroySrvCall ( IN PVOID  Context)

Definition at line 6031 of file rxce.c.

6033{
6035 PSRV_CALL SrvCall;
6036 BOOLEAN ForceFinalize;
6037 PRX_PREFIX_TABLE PrefixTable;
6038
6039 SrvCall = (PSRV_CALL)Context;
6040 /* At this step, RxFinalizeSrvCall already cleaned some fields */
6041 ASSERT(SrvCall->UpperFinalizationDone);
6042
6043 PrefixTable = SrvCall->RxDeviceObject->pRxNetNameTable;
6044 /* Were we called with ForceFinalize? */
6045 ForceFinalize = BooleanFlagOn(SrvCall->Flags, SRVCALL_FLAG_FORCE_FINALIZED);
6046
6047 /* Notify mini-rdr */
6048 MINIRDR_CALL_THROUGH(Status, SrvCall->RxDeviceObject->Dispatch,
6049 MRxFinalizeSrvCall, ((PMRX_SRV_CALL)SrvCall,
6050 ForceFinalize));
6051 (void)Status;
6052
6053 /* Dereference our extra reference (set before queueing) */
6055 InterlockedDecrement((volatile long *)&SrvCall->NodeReferenceCount);
6056 /* And finalize for real, with the right context */
6057 RxFinalizeSrvCall(SrvCall, FALSE, ForceFinalize);
6058 RxReleasePrefixTableLock(PrefixTable);
6059}
BOOLEAN UpperFinalizationDone
Definition: fcb.h:19

Referenced by RxFinalizeSrvCall().

◆ RxpDiscardChangeBufferingStateRequests()

VOID RxpDiscardChangeBufferingStateRequests ( _Inout_ PLIST_ENTRY  DiscardedRequests)

Definition at line 6065 of file rxce.c.

6067{
6069
6070 PAGED_CODE();
6071
6072 /* No requests to discard */
6073 if (IsListEmpty(DiscardedRequests))
6074 {
6075 return;
6076 }
6077
6078 /* Free all the discarded requests */
6079 Entry = DiscardedRequests->Flink;
6080 while (Entry != DiscardedRequests)
6081 {
6083
6085 Entry = Entry->Flink;
6086
6087 DPRINT("Req %p for %p (%p) discarded\n", Request, Request->SrvOpenKey, Request->SrvOpen);
6088
6091 }
6092}
VOID RxPrepareRequestForReuse(PCHANGE_BUFFERING_STATE_REQUEST Request)
Definition: rxce.c:6607

Referenced by RxCompleteSrvOpenKeyAssociation(), RxGatherRequestsForSrvOpen(), and RxPurgeChangeBufferingStateRequestsForSrvOpen().

◆ RxpDispatchChangeBufferingStateRequests()

VOID RxpDispatchChangeBufferingStateRequests ( PSRV_CALL  SrvCall,
PSRV_OPEN  SrvOpen,
PLIST_ENTRY  DiscardedRequests 
)

Definition at line 6098 of file rxce.c.

6102{
6103 KIRQL OldIrql;
6105 BOOLEAN StartDispatcher;
6106 LIST_ENTRY AcceptedReqs;
6107 LIST_ENTRY DispatcherList;
6108 PRX_BUFFERING_MANAGER BufferingManager;
6109
6110 /* Initialize our lists */
6111 InitializeListHead(&AcceptedReqs);
6112 InitializeListHead(DiscardedRequests);
6113
6114 /* Transfer the requests to dispatch locally */
6115 BufferingManager = &SrvCall->BufferingManager;
6116 KeAcquireSpinLock(&BufferingManager->SpinLock, &OldIrql);
6117 RxTransferList(&DispatcherList, &BufferingManager->DispatcherList);
6118 KeReleaseSpinLock(&BufferingManager->SpinLock, OldIrql);
6119
6120 /* If there were requests */
6121 if (!IsListEmpty(&DispatcherList))
6122 {
6124
6125 /* For each of the entries... */
6126 Entry = DispatcherList.Flink;
6127 while (Entry != &DispatcherList)
6128 {
6130
6132 Entry = Entry->Flink;
6133
6134 /* If we have been provided a SRV_OPEN, see whether it matches */
6135 if (SrvOpen != NULL)
6136 {
6137 /* Match, the request is accepted */
6138 if (Request->SrvOpenKey == SrvOpen->Key)
6139 {
6140 Request->SrvOpen = SrvOpen;
6141 RxReferenceSrvOpen(SrvOpen);
6142
6143 RemoveEntryList(&Request->ListEntry);
6144 InsertTailList(&AcceptedReqs, &Request->ListEntry);
6145
6146 /* Move to the next entry */
6147 continue;
6148 }
6149 else
6150 {
6152 }
6153 }
6154 else
6155 {
6156 /* No SRV_OPEN provided, try to find one */
6158 }
6159
6160 /* We found a matching SRV_OPEN, accept the request */
6161 if (Status == STATUS_SUCCESS)
6162 {
6163 RemoveEntryList(&Request->ListEntry);
6164 InsertTailList(&AcceptedReqs, &Request->ListEntry);
6165 }
6166 /* Another run might help handling it, don't discard it */
6167 else if (Status == STATUS_PENDING)
6168 {
6169 continue;
6170 }
6171 /* Otherwise, discard the request */
6172 else
6173 {
6175
6176 RemoveEntryList(&Request->ListEntry);
6177 InsertTailList(DiscardedRequests, &Request->ListEntry);
6178 }
6179 }
6180 }
6181
6182 KeAcquireSpinLock(&BufferingManager->SpinLock, &OldIrql);
6183 /* Nothing to dispatch, no need to start dispatcher */
6184 if (IsListEmpty(&DispatcherList))
6185 {
6186 StartDispatcher = FALSE;
6187 }
6188 else
6189 {
6190 /* Transfer back the list of the not treated entries to the buffering manager */
6191 RxTransferList(&BufferingManager->DispatcherList, &DispatcherList);
6192 StartDispatcher = (BufferingManager->DispatcherActive == FALSE);
6193 /* If the dispatcher isn't active, start it */
6194 if (StartDispatcher)
6195 {
6196 BufferingManager->DispatcherActive = TRUE;
6197 }
6198 }
6199
6200 /* If there were accepted requests, move them to the buffering manager */
6201 if (!IsListEmpty(&AcceptedReqs))
6202 {
6203 RxTransferList(&BufferingManager->HandlerList, &AcceptedReqs);
6204 }
6205 KeReleaseSpinLock(&BufferingManager->SpinLock, OldIrql);
6206
6207 /* If we're to start the dispatcher, do it */
6208 if (StartDispatcher)
6209 {
6210 RxReferenceSrvCall(SrvCall);
6211 DPRINT("Starting dispatcher\n");
6213 &BufferingManager->DispatcherWorkItem,
6215 }
6216}
NTSTATUS RxpLookupSrvOpenForRequestLite(IN PSRV_CALL SrvCall, IN OUT PCHANGE_BUFFERING_STATE_REQUEST Request)
Definition: rxce.c:6222
VOID NTAPI RxDispatchChangeBufferingStateRequests(PVOID Context)
Definition: rxce.c:2390
#define STATUS_NOT_FOUND
Definition: shellext.h:72
RX_WORK_QUEUE_ITEM DispatcherWorkItem
Definition: buffring.h:32

Referenced by RxCompleteSrvOpenKeyAssociation(), and RxGatherRequestsForSrvOpen().

◆ RxpLookupSrvOpenForRequestLite()

NTSTATUS RxpLookupSrvOpenForRequestLite ( IN PSRV_CALL  SrvCall,
IN OUT PCHANGE_BUFFERING_STATE_REQUEST  Request 
)

Definition at line 6222 of file rxce.c.

6225{
6228 PSRV_OPEN SrvOpen;
6229
6230 PAGED_CODE();
6231
6233 /* Browse all our associated SRV_OPENs to find the one! */
6234 for (Entry = SrvCall->BufferingManager.SrvOpenLists[0].Flink;
6235 Entry != &SrvCall->BufferingManager.SrvOpenLists[0];
6236 Entry = Entry->Flink)
6237 {
6238 /* Same key, not orphaned, this is ours */
6239 SrvOpen = CONTAINING_RECORD(Entry, SRV_OPEN, SrvOpenKeyList);
6240 if (SrvOpen->Key == Request->SrvOpenKey)
6241 {
6242 if (!BooleanFlagOn(SrvOpen->pFcb->FcbState, FCB_STATE_ORPHANED))
6243 {
6244 RxReferenceSrvOpen(SrvOpen);
6245 break;
6246 }
6247 }
6248 }
6249
6250 /* We didn't manage to find a SRV_OPEN */
6251 if (Entry == &SrvCall->BufferingManager.SrvOpenLists[0])
6252 {
6253 SrvOpen = NULL;
6254
6255 /* The coming open might help, mark as pending for later retry */
6256 if (SrvCall->BufferingManager.NumberOfOutstandingOpens != 0)
6257 {
6259 }
6260 /* Else, it's a complete failure */
6261 else
6262 {
6264 }
6265 }
6266
6267 /* Return the (not) found SRV_OPEN */
6268 Request->SrvOpen = SrvOpen;
6269
6270 return Status;
6271}

Referenced by RxpDispatchChangeBufferingStateRequests().

◆ RxpMarkInstanceForScavengedFinalization()

VOID RxpMarkInstanceForScavengedFinalization ( PVOID  Instance)

Definition at line 6277 of file rxce.c.

6279{
6282 PRDBSS_SCAVENGER Scavenger;
6284 PLIST_ENTRY ScavengerHead, InstEntry;
6285
6286 PAGED_CODE();
6287
6288 /* If still referenced, don't mark it (broken caller) */
6290 if (Node->NodeReferenceCount > 1)
6291 {
6292 return;
6293 }
6294
6296 Scavenger = DeviceObject->pRdbssScavenger;
6297
6298 /* Mark the node */
6301 DPRINT("Node %p has now the scavenger mark!\n", Instance);
6302
6303 /* Increase the count in the scavenger, and queue it */
6304 ScavengerHead = NULL;
6305 switch (NodeType)
6306 {
6307 case RDBSS_NTC_FOBX:
6308 ++Scavenger->FobxsToBeFinalized;
6309 ScavengerHead = &Scavenger->FobxFinalizationList;
6310 InstEntry = &((PFOBX)Instance)->ScavengerFinalizationList;
6311 break;
6312
6313 case RDBSS_NTC_SRVCALL:
6314 ++Scavenger->SrvCallsToBeFinalized;
6315 ScavengerHead = &Scavenger->SrvCallFinalizationList;
6316 InstEntry = &((PSRV_CALL)Instance)->ScavengerFinalizationList;
6317 break;
6318
6319 case RDBSS_NTC_NETROOT:
6320 ++Scavenger->NetRootsToBeFinalized;
6321 ScavengerHead = &Scavenger->NetRootFinalizationList;
6322 InstEntry = &((PNET_ROOT)Instance)->ScavengerFinalizationList;
6323 break;
6324
6326 ++Scavenger->VNetRootsToBeFinalized;
6327 ScavengerHead = &Scavenger->VNetRootFinalizationList;
6328 InstEntry = &((PV_NET_ROOT)Instance)->ScavengerFinalizationList;
6329 break;
6330
6331 case RDBSS_NTC_SRVOPEN:
6332 ++Scavenger->SrvOpensToBeFinalized;
6333 ScavengerHead = &Scavenger->SrvOpenFinalizationList;
6334 InstEntry = &((PSRV_OPEN)Instance)->ScavengerFinalizationList;
6335 break;
6336 }
6337
6338 /* Extra ref for scavenger */
6339 InterlockedIncrement((volatile long *)&Node->NodeReferenceCount);
6340
6341 /* If matching type */
6342 if (ScavengerHead != NULL)
6343 {
6344 /* Insert in the scavenger list */
6345 InsertTailList(ScavengerHead, InstEntry);
6346
6347 /* And if it wasn't started, start it */
6348 if (Scavenger->State == RDBSS_SCAVENGER_INACTIVE)
6349 {
6350 Scavenger->State = RDBSS_SCAVENGER_DORMANT;
6353 }
6354 }
6355}
PRDBSS_DEVICE_OBJECT RxGetDeviceObjectOfInstance(PVOID Instance)
Definition: rxce.c:4409
ULONG NetRootsToBeFinalized
Definition: scavengr.h:63
LIST_ENTRY FobxFinalizationList
Definition: scavengr.h:73
ULONG SrvCallsToBeFinalized
Definition: scavengr.h:62
LIST_ENTRY VNetRootFinalizationList
Definition: scavengr.h:70
LIST_ENTRY SrvOpenFinalizationList
Definition: scavengr.h:72
ULONG FobxsToBeFinalized
Definition: scavengr.h:67
ULONG SrvOpensToBeFinalized
Definition: scavengr.h:66
LIST_ENTRY NetRootFinalizationList
Definition: scavengr.h:69
ULONG VNetRootsToBeFinalized
Definition: scavengr.h:64
LIST_ENTRY SrvCallFinalizationList
Definition: scavengr.h:68

Referenced by RxDereference().

◆ RxPostOneShotTimerRequest()

NTSTATUS NTAPI RxPostOneShotTimerRequest ( IN PRDBSS_DEVICE_OBJECT  pDeviceObject,
IN PRX_WORK_ITEM  pWorkItem,
IN PRX_WORKERTHREAD_ROUTINE  Routine,
IN PVOID  pContext,
IN LARGE_INTEGER  TimeInterval 
)

Definition at line 6362 of file rxce.c.

6368{
6369 KIRQL OldIrql;
6370
6371 ASSERT(pWorkItem != NULL);
6372
6373 /* Prepare the work item */
6374 ExInitializeWorkItem(&pWorkItem->WorkQueueItem, Routine, pContext);
6375 pWorkItem->WorkQueueItem.pDeviceObject = pDeviceObject;
6376
6377 /* Last tick can be computed with the number of times it was caller (timertickcount)
6378 * and the interval between calls
6379 */
6381 pWorkItem->LastTick = (TimeInterval.QuadPart / 550000) + RxTimerTickCount + 1;
6382 /* Insert in work queue */
6383 InsertTailList(&RxTimerQueueHead, &pWorkItem->WorkQueueItem.List);
6385
6386 /* If there are queued events, queue an execution */
6388 {
6390 }
6391
6392 return STATUS_SUCCESS;
6393}
_In_ PNDIS_STRING _In_ PNDIS_STRING _Out_ PDEVICE_OBJECT * pDeviceObject
Definition: ndis.h:4679
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265

Referenced by RxMarkFobxOnCleanup(), RxpMarkInstanceForScavengedFinalization(), and RxScavengerTimerRoutine().

◆ RxPostToWorkerThread()

NTSTATUS NTAPI RxPostToWorkerThread ( _In_ PRDBSS_DEVICE_OBJECT  pMRxDeviceObject,
_In_ WORK_QUEUE_TYPE  WorkQueueType,
_In_ PRX_WORK_QUEUE_ITEM  pWorkQueueItem,
_In_ PRX_WORKERTHREAD_ROUTINE  Routine,
_In_ PVOID  pContext 
)

Definition at line 6400 of file rxce.c.

6406{
6407 /* Initialize work queue item */
6408 pWorkQueueItem->List.Flink = NULL;
6409 pWorkQueueItem->WorkerRoutine = Routine;
6410 pWorkQueueItem->Parameter = pContext;
6411
6412 /* And insert it in the work queue */
6413 return RxInsertWorkQueueItem(pMRxDeviceObject, WorkQueueType, pWorkQueueItem);
6414}

Referenced by RxCompleteSrvOpenKeyAssociation(), RxpDispatchChangeBufferingStateRequests(), and RxTimerDispatch().

◆ RxpProcessChangeBufferingStateRequests()

VOID RxpProcessChangeBufferingStateRequests ( PSRV_CALL  SrvCall,
BOOLEAN  UpdateHandlerState 
)

Definition at line 6417 of file rxce.c.

6420{
6422}

Referenced by RxCommonCreate(), and RxProcessChangeBufferingStateRequests().

◆ RxpReferenceNetFcb()

LONG RxpReferenceNetFcb ( PFCB  Fcb)

Definition at line 6546 of file rxce.c.

6548{
6549 LONG NewCount;
6550
6551 PAGED_CODE();
6552
6554
6555 NewCount = InterlockedIncrement((volatile long *)&Fcb->NodeReferenceCount);
6556
6557 PRINT_REF_COUNT(NETFCB, Fcb->NodeReferenceCount);
6558
6559 return NewCount;
6560}

◆ RxPrefixTableInsertName()

PRX_PREFIX_ENTRY RxPrefixTableInsertName ( IN OUT PRX_PREFIX_TABLE  ThisTable,
IN OUT PRX_PREFIX_ENTRY  ThisEntry,
IN PVOID  Container,
IN PULONG  ContainerRefCount,
IN USHORT  CaseInsensitiveLength,
IN PRX_CONNECTION_ID  ConnectionId 
)

Definition at line 6428 of file rxce.c.

6436{
6437 PAGED_CODE();
6438
6439 DPRINT("Insert: %wZ\n", &ThisEntry->Prefix);
6440
6442 ASSERT(CaseInsensitiveLength <= ThisEntry->Prefix.Length);
6443
6444 /* Copy parameters and compute hash */
6445 ThisEntry->CaseInsensitiveLength = CaseInsensitiveLength;
6446 ThisEntry->ContainingRecord = Container;
6447 ThisEntry->ContainerRefCount = ContainerRefCount;
6448 InterlockedIncrement((volatile long *)ContainerRefCount);
6449 ThisEntry->SavedHashValue = RxTableComputeHashValue(&ThisEntry->Prefix);
6450 DPRINT("Associated hash: %x\n", ThisEntry->SavedHashValue);
6451
6452 /* If no path length: this is entry for null path */
6453 if (ThisEntry->Prefix.Length == 0)
6454 {
6455 ThisTable->TableEntryForNull = ThisEntry;
6456 }
6457 /* Otherwise, insert in the appropriate bucket */
6458 else
6459 {
6460 InsertTailList(HASH_BUCKET(ThisTable, ThisEntry->SavedHashValue), &ThisEntry->HashLinks);
6461 }
6462
6463 /* If we had a connection ID, keep track of it */
6464 if (ConnectionId != NULL)
6465 {
6466 ThisEntry->ConnectionId.Luid = ConnectionId->Luid;
6467 }
6468 else
6469 {
6470 ThisEntry->ConnectionId.Luid.LowPart = 0;
6471 ThisEntry->ConnectionId.Luid.HighPart = 0;
6472 }
6473
6474 InsertTailList(&ThisTable->MemberQueue, &ThisEntry->MemberQLinks);
6475 /* Reflect the changes */
6476 ++ThisTable->Version;
6477
6478 DPRINT("Inserted in bucket: %p\n", HASH_BUCKET(ThisTable, ThisEntry->SavedHashValue));
6479
6480 return ThisEntry;
6481}
ULONG RxTableComputeHashValue(IN PUNICODE_STRING Name)
Definition: rxce.c:8174
unsigned short Length
Definition: sprintf.c:451
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1630

Referenced by RxCreateNetRoot(), RxCreateSrvCall(), and RxCreateVNetRoot().

◆ RxPrefixTableLookupName()

PVOID RxPrefixTableLookupName ( IN PRX_PREFIX_TABLE  ThisTable,
IN PUNICODE_STRING  CanonicalName,
OUT PUNICODE_STRING  RemainingName,
IN PRX_CONNECTION_ID  ConnectionId 
)

Definition at line 6487 of file rxce.c.

6492{
6493 PVOID Container;
6494
6495 PAGED_CODE();
6496
6498 ASSERT(CanonicalName->Length > 0);
6499
6500 /* Call the internal helper */
6501 Container = RxTableLookupName(ThisTable, CanonicalName, RemainingName, ConnectionId);
6502 if (Container == NULL)
6503 {
6504 return NULL;
6505 }
6506
6507 /* Reference our container before returning it */
6509 {
6511
6512 Type = (NodeType(Container) & ~RX_SCAVENGER_MASK);
6513 switch (Type)
6514 {
6515 case RDBSS_NTC_SRVCALL:
6516 RxReferenceSrvCall(Container);
6517 break;
6518
6519 case RDBSS_NTC_NETROOT:
6520 RxReferenceNetRoot(Container);
6521 break;
6522
6524 RxReferenceVNetRoot(Container);
6525 break;
6526
6527 default:
6528 DPRINT1("Invalid node type: %x\n", Type);
6529 ASSERT(FALSE);
6530 RxReference(Container);
6531 break;
6532 }
6533 }
6534 else
6535 {
6536 RxReference(Container);
6537 }
6538
6539 return Container;
6540}
Type
Definition: Type.h:7
VOID RxReference(IN OUT PVOID Instance)
Definition: rxce.c:7437
ULONG RdbssReferenceTracingValue
Definition: rxce.c:130
PVOID RxTableLookupName(IN PRX_PREFIX_TABLE ThisTable, IN PUNICODE_STRING Name, OUT PUNICODE_STRING RemainingName, IN PRX_CONNECTION_ID OPTIONAL RxConnectionId)
Definition: rxce.c:8252

Referenced by RxFindOrConstructVirtualNetRoot(), and RxFindOrCreateConnections().

◆ RxpReleasePrefixTableLock()

VOID RxpReleasePrefixTableLock ( PRX_PREFIX_TABLE  pTable,
BOOLEAN  ProcessBufferingStateChangeRequests 
)

Definition at line 6566 of file rxce.c.

6569{
6570 PAGED_CODE();
6571
6572 DPRINT("RxpReleasePrefixTableLock(%p, %d) -> %d\n", pTable, ProcessBufferingStateChangeRequests,
6573 pTable->TableLock.ActiveEntries);
6574
6575 ExReleaseResourceLite(&pTable->TableLock);
6576}

◆ RxPrepareContextForReuse()

VOID NTAPI RxPrepareContextForReuse ( IN OUT PRX_CONTEXT  RxContext)

Definition at line 6583 of file rxce.c.

6585{
6586 PAGED_CODE();
6587
6588 /* When we reach that point, make sure mandatory parts are null-ed */
6589 if (RxContext->MajorFunction == IRP_MJ_CREATE)
6590 {
6591 ASSERT(RxContext->Create.CanonicalNameBuffer == NULL);
6592 RxContext->Create.RdrFlags = 0;
6593 }
6594 else if (RxContext->MajorFunction == IRP_MJ_READ || RxContext->MajorFunction == IRP_MJ_WRITE)
6595 {
6596 ASSERT(RxContext->RxContextSerializationQLinks.Flink == NULL);
6597 ASSERT(RxContext->RxContextSerializationQLinks.Blink == NULL);
6598 }
6599
6600 RxContext->ReferenceCount = 0;
6601}

Referenced by RxDereferenceAndDeleteRxContext_Real(), and RxReinitializeContext().

◆ RxPrepareRequestForReuse()

VOID RxPrepareRequestForReuse ( PCHANGE_BUFFERING_STATE_REQUEST  Request)

Definition at line 6607 of file rxce.c.

6609{
6610 PSRV_OPEN SrvOpen;
6611
6612 PAGED_CODE();
6613
6614 SrvOpen = Request->SrvOpen;
6615
6616 /* If the request was already prepared for service */
6618 {
6619 /* We have to dereference the associated SRV_OPEN depending on the lock */
6620 if (RxIsFcbAcquiredExclusive(SrvOpen->pFcb))
6621 {
6623 }
6624 else
6625 {
6627 }
6628 }
6629 /* Otherwise, just dereference */
6630 else if (SrvOpen != NULL)
6631 {
6633 }
6634
6635 Request->SrvOpen = NULL;
6636}
#define RX_REQUEST_PREPARED_FOR_HANDLING
Definition: buffring.h:4

Referenced by RxpDiscardChangeBufferingStateRequests().

◆ RxProcessChangeBufferingStateRequests()

VOID NTAPI RxProcessChangeBufferingStateRequests ( _In_ PVOID  SrvCall)

Definition at line 6643 of file rxce.c.

6645{
6646 /* Call internal routine */
6649}
VOID RxUndoScavengerFinalizationMarking(PVOID Instance)
Definition: rxce.c:8667
VOID RxpProcessChangeBufferingStateRequests(PSRV_CALL SrvCall, BOOLEAN UpdateHandlerState)
Definition: rxce.c:6417

Referenced by RxCompleteSrvOpenKeyAssociation().

◆ RxProcessChangeBufferingStateRequestsForSrvOpen()

VOID RxProcessChangeBufferingStateRequestsForSrvOpen ( PSRV_OPEN  SrvOpen)

Definition at line 6655 of file rxce.c.

6657{
6658 LONG NumberOfBufferingChangeRequests, LockedOldBufferingToken, OldBufferingToken;
6659
6660 /* Get the current number of change requests */
6661 NumberOfBufferingChangeRequests = ((PSRV_CALL)SrvOpen->pVNetRoot->pNetRoot->pSrvCall)->BufferingManager.CumulativeNumberOfBufferingChangeRequests;
6662 /* Get our old token */
6663 OldBufferingToken = SrvOpen->BufferingToken;
6664 LockedOldBufferingToken = InterlockedCompareExchange(&SrvOpen->BufferingToken,
6665 NumberOfBufferingChangeRequests,
6666 NumberOfBufferingChangeRequests);
6667 /* If buffering state changed in between, process changes */
6668 if (OldBufferingToken != LockedOldBufferingToken)
6669 {
6670 PFCB Fcb;
6672
6673 /* Acquire the FCB and start processing */
6674 Fcb = (PFCB)SrvOpen->pFcb;
6676 if (Status == STATUS_SUCCESS)
6677 {
6680 }
6681 }
6682}
#define InterlockedCompareExchange
Definition: interlocked.h:104
volatile LONG BufferingToken
Definition: fcb.h:276

Referenced by RxFastIoCheckIfPossible().

◆ RxProcessFcbChangeBufferingStateRequest()

VOID RxProcessFcbChangeBufferingStateRequest ( PFCB  Fcb)

◆ RxpScavengeFobxs()

VOID RxpScavengeFobxs ( PRDBSS_SCAVENGER  Scavenger,
PLIST_ENTRY  FobxToScavenge 
)

Definition at line 6695 of file rxce.c.

6698{
6699 /* Explore the whole list of FOBX to scavenge */
6700 while (!IsListEmpty(FobxToScavenge))
6701 {
6702 PFCB Fcb;
6703 PFOBX Fobx;
6705
6706 Entry = RemoveHeadList(FobxToScavenge);
6707 Fobx = CONTAINING_RECORD(Entry, FOBX, ScavengerFinalizationList);
6708 Fcb = (PFCB)Fobx->SrvOpen->pFcb;
6709
6710 /* Try to acquire the lock exclusively to perform finalization */
6712 {
6714 }
6715 else
6716 {
6719
6721 {
6723 }
6724 }
6725 }
6726}
#define RxDereferenceAndFinalizeNetFcb(Fcb, RxContext, RecursiveFinalize, ForceFinalize)
Definition: fcb.h:439

Referenced by RxScavengeFobxsForNetRoot().

◆ RxpTrackDereference()

BOOLEAN RxpTrackDereference ( _In_ ULONG  TraceType,
_In_ PCSTR  FileName,
_In_ ULONG  Line,
_In_ PVOID  Instance 
)

Definition at line 6729 of file rxce.c.

6734{
6735 PCSTR InstanceType;
6736 ULONG ReferenceCount;
6737
6738 PAGED_CODE();
6739
6741 {
6742 return TRUE;
6743 }
6744
6745 switch (TraceType)
6746 {
6748 InstanceType = "SrvCall";
6749 ReferenceCount = ((PSRV_CALL)Instance)->NodeReferenceCount;
6750 break;
6751
6753 InstanceType = "NetRoot";
6754 ReferenceCount = ((PNET_ROOT)Instance)->NodeReferenceCount;
6755 break;
6756
6758 InstanceType = "VNetRoot";
6759 ReferenceCount = ((PV_NET_ROOT)Instance)->NodeReferenceCount;
6760 break;
6761
6763 InstanceType = "NetFobx";
6764 ReferenceCount = ((PFOBX)Instance)->NodeReferenceCount;
6765 break;
6766
6768 InstanceType = "NetFcb";
6769 ReferenceCount = ((PFCB)Instance)->NodeReferenceCount;
6770 break;
6771
6773 InstanceType = "SrvOpen";
6774 ReferenceCount = ((PSRV_OPEN)Instance)->NodeReferenceCount;
6775 break;
6776
6777 default:
6778 DPRINT1("Invalid node type!\n");
6779 return TRUE;
6780 }
6781
6783 {
6785 }
6786
6788 {
6789 DbgPrint("(%s:%d) %p (%s) dereferenced from %d\n", FileName, Line, Instance, InstanceType, ReferenceCount);
6790 }
6791
6792 return TRUE;
6793}
#define RDBSS_REF_TRACK_SRVOPEN
Definition: fcb.h:354
#define RDBSS_REF_TRACK_NETFCB
Definition: fcb.h:353
#define RDBSS_REF_TRACK_SRVCALL
Definition: fcb.h:349
#define RDBSS_REF_TRACK_NETROOT
Definition: fcb.h:350
#define RDBSS_REF_TRACK_NETFOBX
Definition: fcb.h:352
#define RDBSS_REF_TRACK_VNETROOT
Definition: fcb.h:351
#define RX_PRINT_REF_TRACKING
Definition: fcb.h:355
#define RX_LOG_REF_TRACKING
Definition: fcb.h:356
const char * PCSTR
Definition: typedefs.h:52

◆ RxpTrackReference()

VOID RxpTrackReference ( _In_ ULONG  TraceType,
_In_ PCSTR  FileName,
_In_ ULONG  Line,
_In_ PVOID  Instance 
)

Definition at line 6796 of file rxce.c.

6801{
6802 PCSTR InstanceType;
6803 ULONG ReferenceCount;
6804
6806 {
6807 return;
6808 }
6809
6810 switch (TraceType)
6811 {
6813 InstanceType = "SrvCall";
6814 ReferenceCount = ((PSRV_CALL)Instance)->NodeReferenceCount;
6815 break;
6816
6818 InstanceType = "NetRoot";
6819 ReferenceCount = ((PNET_ROOT)Instance)->NodeReferenceCount;
6820 break;
6821
6823 InstanceType = "VNetRoot";
6824 ReferenceCount = ((PV_NET_ROOT)Instance)->NodeReferenceCount;
6825 break;
6826
6828 InstanceType = "NetFobx";
6829 ReferenceCount = ((PFOBX)Instance)->NodeReferenceCount;
6830 break;
6831
6833 InstanceType = "NetFcb";
6834 ReferenceCount = ((PFCB)Instance)->NodeReferenceCount;
6835 break;
6836
6838 InstanceType = "SrvOpen";
6839 ReferenceCount = ((PSRV_OPEN)Instance)->NodeReferenceCount;
6840 break;
6841
6842 default:
6843 DPRINT1("Invalid node type!\n");
6844 return;
6845 }
6846
6848 {
6850 }
6851
6853 {
6854 DbgPrint("(%s:%d) %p (%s) referenced from %d\n", FileName, Line, Instance, InstanceType, ReferenceCount);
6855 }
6856}

◆ RxpUndoScavengerFinalizationMarking()

VOID RxpUndoScavengerFinalizationMarking ( PVOID  Instance)

Definition at line 6862 of file rxce.c.

6864{
6865 PLIST_ENTRY ListEntry;
6867 PRDBSS_SCAVENGER Scavenger;
6868
6869 PAGED_CODE();
6870
6872 /* There's no marking - nothing to do */
6874 {
6875 return;
6876 }
6877
6878 /* First of all, remove the mark */
6880 DPRINT("Node %p no longer has the scavenger mark\n");
6881
6882 /* And now, remove from the scavenger */
6884 switch (NodeType(Node))
6885 {
6886 case RDBSS_NTC_FOBX:
6887 --Scavenger->FobxsToBeFinalized;
6888 ListEntry = &((PFOBX)Instance)->ScavengerFinalizationList;
6889 break;
6890
6891 case RDBSS_NTC_SRVCALL:
6892 --Scavenger->SrvCallsToBeFinalized;
6893 ListEntry = &((PSRV_CALL)Instance)->ScavengerFinalizationList;
6894 break;
6895
6896 case RDBSS_NTC_NETROOT:
6897 --Scavenger->NetRootsToBeFinalized;
6898 ListEntry = &((PNET_ROOT)Instance)->ScavengerFinalizationList;
6899 break;
6900
6902 --Scavenger->VNetRootsToBeFinalized;
6903 ListEntry = &((PV_NET_ROOT)Instance)->ScavengerFinalizationList;
6904 break;
6905
6906 case RDBSS_NTC_SRVOPEN:
6907 --Scavenger->SrvOpensToBeFinalized;
6908 ListEntry = &((PSRV_OPEN)Instance)->ScavengerFinalizationList;
6909 break;
6910
6911 default:
6912 return;
6913 }
6914
6915 /* Also, remove the extra ref from the scavenger */
6916 RemoveEntryList(ListEntry);
6917 InterlockedDecrement((volatile long *)&Node->NodeReferenceCount);
6918}

Referenced by RxDereference(), RxReference(), RxScavengeRelatedFobxs(), and RxUndoScavengerFinalizationMarking().

◆ RxPurgeChangeBufferingStateRequestsForSrvOpen()

VOID RxPurgeChangeBufferingStateRequestsForSrvOpen ( PSRV_OPEN  SrvOpen)

Definition at line 6924 of file rxce.c.

6926{
6927 PSRV_CALL SrvCall;
6928 LIST_ENTRY Discarded;
6929
6930 PAGED_CODE();
6931
6933
6934 /* Initialize our discarded list */
6935 InitializeListHead(&Discarded);
6936
6937 SrvCall = (PSRV_CALL)SrvOpen->Fcb->VNetRoot->pNetRoot->pSrvCall;
6939
6940 /* Set the flag, and get the requests */
6943 RxGatherRequestsForSrvOpen(SrvCall, SrvOpen, &Discarded);
6944
6946
6947 /* If there were discarded requests */
6948 if (!IsListEmpty(&Discarded))
6949 {
6950 /* And a pending buffering state change */
6952 {
6953 /* Clear the flag, and set the associated event - job done */
6957 {
6959 }
6961 }
6962
6963 /* Drop the discarded requests */
6965 }
6966}
#define SRVOPEN_FLAG_BUFFERING_STATE_CHANGE_REQUESTS_PURGED
Definition: mrxfcb.h:138
VOID RxGatherRequestsForSrvOpen(IN OUT PSRV_CALL SrvCall, IN PSRV_OPEN SrvOpen, IN OUT PLIST_ENTRY RequestsListHead)
Definition: rxce.c:4361
PKEVENT pBufferingStateChangeCompletedEvent
Definition: fcb.h:142

Referenced by RxFinalizeSrvOpen().

◆ RxPurgeFcb()

VOID RxPurgeFcb ( IN PFCB  Fcb)

Definition at line 6972 of file rxce.c.

6974{
6975 PAGED_CODE();
6976
6978
6979 /* Reference our FCB so that it doesn't disappear */
6981 /* Purge Cc if required */
6982 if (Fcb->OpenCount != 0)
6983 {
6985 }
6986
6987 /* If it wasn't freed, release the lock */
6989 {
6991 }
6992}
NTSTATUS RxPurgeFcbInSystemCache(IN PFCB Fcb, IN PLARGE_INTEGER FileOffset OPTIONAL, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps, IN BOOLEAN FlushFile)
Definition: rxce.c:6998

Referenced by RxFinalizeConnection(), and RxFinalizeNetRoot().

◆ RxPurgeFcbInSystemCache()

NTSTATUS RxPurgeFcbInSystemCache ( IN PFCB  Fcb,
IN PLARGE_INTEGER FileOffset  OPTIONAL,
IN ULONG  Length,
IN BOOLEAN  UninitializeCacheMaps,
IN BOOLEAN  FlushFile 
)

Definition at line 6998 of file rxce.c.

7004{
7005 BOOLEAN Purged;
7007
7008 PAGED_CODE();
7009
7011
7012 /* Try to flush first, if asked */
7013 if (FlushFile)
7014 {
7015 /* If flushing failed, just make some noise */
7017 if (!NT_SUCCESS(Status))
7018 {
7019 PVOID CallersAddress, CallersCaller;
7020
7021 RtlGetCallersAddress(&CallersAddress, &CallersCaller);
7022 DPRINT1("Flush failed with status %lx for FCB %p\n", Status, Fcb);
7023 DPRINT1("Caller was %p %p\n", CallersAddress, CallersCaller);
7024 }
7025 }
7026
7027 /* Deal with Cc for purge */
7029 Length, UninitializeCacheMaps);
7030 /* If purge failed, force section closing */
7031 if (!Purged)
7032 {
7034
7038 }
7039
7040 /* Return appropriate status */
7042 DPRINT("Purge for FCB %p returns %lx\n", Fcb, Status);
7043
7044 return Status;
7045}
BOOLEAN NTAPI MmForceSectionClosed(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN BOOLEAN DelayClose)
Definition: section.c:3042
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
BOOLEAN NTAPI MmFlushImageSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
Definition: section.c:4356
NTSYSAPI VOID NTAPI RtlGetCallersAddress(_Out_ PVOID *CallersAddress, _Out_ PVOID *CallersCaller)
Definition: except.c:22

Referenced by RxPurgeFcb(), RxPurgeFobx(), and RxPurgeFobxFromCache().

◆ RxPurgeFobx()

BOOLEAN RxPurgeFobx ( PFOBX  pFobx)

Definition at line 7051 of file rxce.c.

7053{
7055 PFCB FcbToBePurged;
7056
7057 PAGED_CODE();
7058
7059 /* Get the associated FCB */
7060 FcbToBePurged = (PFCB)pFobx->pSrvOpen->pFcb;
7061 Status = RxAcquireExclusiveFcb(NULL, FcbToBePurged);
7063
7064 /* Purge it */
7065 Status = RxPurgeFcbInSystemCache(FcbToBePurged, NULL, 0, FALSE, TRUE);
7066 if (Status != STATUS_SUCCESS)
7067 {
7068 DPRINT1("Purge failed for %p (%p)\n", FcbToBePurged, pFobx);
7069 return FALSE;
7070 }
7071
7072 /* And flush */
7073 if (!MmFlushImageSection(&FcbToBePurged->NonPaged->SectionObjectPointers, MmFlushForWrite))
7074 {
7075 DPRINT1("Image section flush failed for %p (%p)\n", FcbToBePurged, pFobx);
7076 return FALSE;
7077 }
7078
7079 DPRINT("Purge OK for %p (%p)\n", FcbToBePurged, pFobx);
7080 return TRUE;
7081}

Referenced by RxPurgeRelatedFobxs().

◆ RxPurgeFobxFromCache()

NTSTATUS RxPurgeFobxFromCache ( PFOBX  FobxToBePurged)

Definition at line 7087 of file rxce.c.

7089{
7091 PFCB FcbToBePurged;
7092
7093 PAGED_CODE();
7094
7095 FcbToBePurged = (PFCB)FobxToBePurged->pSrvOpen->pFcb;
7096 ASSERT(FcbToBePurged != NULL);
7097
7098 /* If we cannot have our FCB exclusively, give up */
7099 Status = RxAcquireExclusiveFcb(NULL, FcbToBePurged);
7100 if (Status != STATUS_SUCCESS)
7101 {
7102 RxDereferenceNetFobx(FobxToBePurged, LHS_LockNotHeld);
7103 return Status;
7104 }
7105
7106 /* Don't let the FCB disappear */
7107 RxReferenceNetFcb(FcbToBePurged);
7108
7109 /* If the SRV_OPEN was already closed, or if there are unclean FOBX, give up */
7110 if (BooleanFlagOn(FobxToBePurged->Flags, FOBX_FLAG_SRVOPEN_CLOSED) || FobxToBePurged->pSrvOpen->UncleanFobxCount != 0)
7111 {
7112 DPRINT("FCB purge skipped\n");
7113 }
7114 else
7115 {
7116 Status = RxPurgeFcbInSystemCache(FcbToBePurged, NULL, 0, FALSE, TRUE);
7117 }
7118
7120 /* Drop our extra reference */
7121 if (!RxDereferenceAndFinalizeNetFcb(FcbToBePurged, NULL, FALSE, FALSE))
7122 {
7123 RxReleaseFcb(NULL, FcbToBePurged);
7124 }
7125
7126 return Status;
7127}
#define RxDereferenceNetFobx(Fobx, LockHoldingState)
Definition: fcb.h:419

Referenced by RxMarkFobxOnCleanup().

◆ RxPurgeRelatedFobxs()

NTSTATUS RxPurgeRelatedFobxs ( PNET_ROOT  NetRoot,
PRX_CONTEXT  RxContext,
BOOLEAN  AttemptFinalization,
PFCB  PurgingFcb 
)

Definition at line 7133 of file rxce.c.

7138{
7140 ULONG SuccessfullPurge;
7141 PRDBSS_SCAVENGER Scavenger;
7142 PRDBSS_DEVICE_OBJECT RxDeviceObject;
7143 PPURGE_SYNCHRONIZATION_CONTEXT PurgeSyncCtx;
7144
7145 PAGED_CODE();
7146
7147 RxDeviceObject = RxContext->RxDeviceObject;
7148 Scavenger = RxDeviceObject->pRdbssScavenger;
7149 PurgeSyncCtx = &NetRoot->PurgeSyncronizationContext;
7150
7152
7153 /* If there's already a purge in progress */
7154 if (PurgeSyncCtx->PurgeInProgress)
7155 {
7156 /* Add our RX_CONTEXT to the current run */
7158 &RxContext->RxContextSerializationQLinks);
7159
7160 /* And wait until it's done */
7162 RxWaitSync(RxContext);
7164 }
7165
7166 /* Start the purge */
7167 PurgeSyncCtx->PurgeInProgress = TRUE;
7168
7169 /* While the purge is still handling our NET_ROOT, do nothing but wait */
7170 while (Scavenger->CurrentNetRootForClosePendingProcessing == NetRoot)
7171 {
7174 KernelMode, TRUE, NULL);
7176 }
7177
7178 /* Now, for all the entries */
7179 SuccessfullPurge = 0;
7180 Entry = Scavenger->ClosePendingFobxsList.Flink;
7181 while (Entry != &Scavenger->ClosePendingFobxsList)
7182 {
7183 PFCB Fcb;
7184 PFOBX Fobx;
7186
7187 Fobx = CONTAINING_RECORD(Entry, FOBX, ClosePendingList);
7188 DPRINT("Dealing with FOBX: %p\n", Fobx);
7189
7190 Entry = Entry->Flink;
7191
7192 /* If it's not matching our NET_ROOT, ignore */
7193 if (Fobx->pSrvOpen == NULL ||
7194 Fobx->pSrvOpen->pFcb == NULL ||
7195 ((PFCB)Fobx->pSrvOpen->pFcb)->VNetRoot == NULL ||
7196 (PNET_ROOT)((PFCB)Fobx->pSrvOpen->pFcb)->VNetRoot->pNetRoot != NetRoot)
7197 {
7198 continue;
7199 }
7200
7201 /* Determine if it matches our FCB */
7202 Fcb = (PFCB)Fobx->pSrvOpen->pFcb;
7203 if (PurgingFcb != NULL && NodeType(PurgingFcb) != RDBSS_NTC_STORAGE_TYPE_DIRECTORY &&
7204 PurgingFcb != Fcb)
7205 {
7207
7208 MINIRDR_CALL_THROUGH(Status, RxDeviceObject->Dispatch, MRxAreFilesAliased, (Fcb, PurgingFcb));
7209 if (Status == STATUS_SUCCESS)
7210 {
7211 continue;
7212 }
7213 }
7214
7215 /* Matching, we'll purge it */
7217
7218 /* Reference it so that it doesn't disappear */
7219 RxReferenceNetFobx(Fobx);
7220
7222
7223 /* And purge */
7224 Success = RxPurgeFobx(Fobx);
7225 if (Success)
7226 {
7227 ++SuccessfullPurge;
7228 }
7229
7230 /* If we don't have to finalize it (or if we cannot acquire lock exclusively
7231 * Just normally dereference
7232 */
7233 if ((AttemptFinalization == DONT_ATTEMPT_FINALIZE_ON_PURGE) ||
7235 {
7237 }
7238 /* Otherwise, finalize */
7239 else
7240 {
7244 {
7246 }
7247 }
7248
7249 if (!Success)
7250 {
7251 DPRINT1("Failed purging %p (%p)\n", Fcb, Fobx);
7252 }
7253
7255 }
7256
7257 /* If no contexts left, purge is not running */
7258 if (IsListEmpty(&PurgeSyncCtx->ContextsAwaitingPurgeCompletion))
7259 {
7260 PurgeSyncCtx->PurgeInProgress = FALSE;
7261 }
7262 /* Otherwise, notify a waiter it can start */
7263 else
7264 {
7266
7268 Context = CONTAINING_RECORD(Entry, RX_CONTEXT, RxContextSerializationQLinks);
7269
7271 }
7272
7274
7275 return (SuccessfullPurge > 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
7276}
@ Success
Definition: eventcreate.c:712
BOOLEAN RxPurgeFobx(PFOBX pFobx)
Definition: rxce.c:7051
#define DONT_ATTEMPT_FINALIZE_ON_PURGE
Definition: scavengr.h:45
PNET_ROOT CurrentNetRootForClosePendingProcessing
Definition: scavengr.h:79
KEVENT ClosePendingProcessingSyncEvent
Definition: scavengr.h:81
PRDBSS_DEVICE_OBJECT RxDeviceObject
Definition: rxcontx.h:116
LIST_ENTRY RxContextSerializationQLinks
Definition: rxcontx.h:154

Referenced by RxCommonCreate(), RxCommonSetInformation(), and RxCreateFromNetRoot().

◆ RxpWorkerThreadDispatcher()

VOID RxpWorkerThreadDispatcher ( IN PRX_WORK_QUEUE  WorkQueue,
IN PLARGE_INTEGER  WaitInterval 
)

Definition at line 7282 of file rxce.c.

7285{
7288 PETHREAD CurrentThread;
7289 BOOLEAN KillThread, Dereference;
7290 PRX_WORK_QUEUE_ITEM WorkQueueItem;
7292
7293 InterlockedIncrement(&WorkQueue->NumberOfIdleWorkerThreads);
7294
7295 /* Reference ourselves */
7296 CurrentThread = PsGetCurrentThread();
7299
7300 /* Infinite loop for worker */
7301 KillThread = FALSE;
7302 Dereference = FALSE;
7303 do
7304 {
7305 KIRQL OldIrql;
7306 PLIST_ENTRY ListEntry;
7307
7308 /* Remove an entry from the work queue */
7309 ListEntry = KeRemoveQueue(&WorkQueue->Queue, KernelMode, WaitInterval);
7310 if ((ULONG_PTR)ListEntry != STATUS_TIMEOUT)
7311 {
7313
7314 WorkQueueItem = CONTAINING_RECORD(ListEntry, RX_WORK_QUEUE_ITEM, List);
7315
7316 InterlockedIncrement(&WorkQueue->NumberOfWorkItemsDispatched);
7317 InterlockedDecrement(&WorkQueue->NumberOfWorkItemsToBeDispatched);
7318 InterlockedDecrement(&WorkQueue->NumberOfIdleWorkerThreads);
7319
7320 /* Get the parameters, and null-them in the struct */
7321 WorkerRoutine = WorkQueueItem->WorkerRoutine;
7322 Parameter = WorkQueueItem->Parameter;
7323 DeviceObject = WorkQueueItem->pDeviceObject;
7324
7325 WorkQueueItem->List.Flink = NULL;
7326 WorkQueueItem->WorkerRoutine = NULL;
7327 WorkQueueItem->Parameter = NULL;
7328 WorkQueueItem->pDeviceObject = NULL;
7329
7330 /* Call the routine */
7331 DPRINT("Calling: %p(%p)\n", WorkerRoutine, Parameter);
7333
7334 /* Are we going down now? */
7335 if (InterlockedDecrement(&DeviceObject->DispatcherContext.NumberOfWorkerThreads) == 0)
7336 {
7337 PKEVENT TearDownEvent;
7338
7339 TearDownEvent = InterlockedExchangePointer((void * volatile*)&DeviceObject->DispatcherContext.pTearDownEvent, NULL);
7340 if (TearDownEvent != NULL)
7341 {
7342 KeSetEvent(TearDownEvent, IO_NO_INCREMENT, FALSE);
7343 }
7344 }
7345
7346 InterlockedIncrement(&WorkQueue->NumberOfIdleWorkerThreads);
7347 }
7348
7349 /* Shall we shutdown... */
7350 KeAcquireSpinLock(&WorkQueue->SpinLock, &OldIrql);
7351 switch (WorkQueue->State)
7352 {
7353 /* Our queue is active, kill it if we have no more items to dispatch
7354 * and more threads than the required minimum
7355 */
7356 case RxWorkQueueActive:
7357 if (WorkQueue->NumberOfWorkItemsToBeDispatched <= 0)
7358 {
7359 ASSERT(WorkQueue->NumberOfActiveWorkerThreads > 0);
7360 if (WorkQueue->NumberOfActiveWorkerThreads > WorkQueue->MinimumNumberOfWorkerThreads)
7361 {
7362 KillThread = TRUE;
7363 Dereference = TRUE;
7364 InterlockedDecrement(&WorkQueue->NumberOfActiveWorkerThreads);
7365 }
7366
7367 if (KillThread)
7368 {
7369 InterlockedDecrement(&WorkQueue->NumberOfIdleWorkerThreads);
7370 }
7371 }
7372 break;
7373
7374 /* The queue is inactive: kill it we have more threads than the required minimum */
7376 ASSERT(WorkQueue->NumberOfActiveWorkerThreads > 0);
7377 if (WorkQueue->NumberOfActiveWorkerThreads > WorkQueue->MinimumNumberOfWorkerThreads)
7378 {
7379 KillThread = TRUE;
7380 Dereference = TRUE;
7381 InterlockedDecrement(&WorkQueue->NumberOfActiveWorkerThreads);
7382 }
7383
7384 if (KillThread)
7385 {
7386 InterlockedDecrement(&WorkQueue->NumberOfIdleWorkerThreads);
7387 }
7388 break;
7389
7390 /* Rundown in progress..., kill it for sure! */
7392 {
7393 PRX_WORK_QUEUE_RUNDOWN_CONTEXT RundownContext;
7394
7395 ASSERT(WorkQueue->pRundownContext != NULL);
7396
7397 RundownContext = WorkQueue->pRundownContext;
7398 RundownContext->ThreadPointers[RundownContext->NumberOfThreadsSpunDown++] = CurrentThread;
7399
7400 InterlockedDecrement(&WorkQueue->NumberOfActiveWorkerThreads);
7401 KillThread = TRUE;
7402 Dereference = FALSE;
7403
7404 if (WorkQueue->NumberOfActiveWorkerThreads == 0)
7405 {
7407 }
7408
7409 InterlockedDecrement(&WorkQueue->NumberOfIdleWorkerThreads);
7410 }
7411 break;
7412
7413 default:
7414 break;
7415 }
7416 KeReleaseSpinLock(&WorkQueue->SpinLock, OldIrql);
7417 } while (!KillThread);
7418
7419 DPRINT("Killed worker thread\n");
7420
7421 /* Do we have to dereference ourselves? */
7422 if (Dereference)
7423 {
7424 ObDereferenceObject(CurrentThread);
7425 }
7426
7427 /* Dump last executed routine */
7429 {
7430 DPRINT("Dispatch routine %p(%p) taken from %p\n", WorkerRoutine, Parameter, WorkQueueItem);
7431 }
7432
7434}
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
_Must_inspect_result_ _In_ PFLT_CALLBACK_DATA _In_ PFLT_DEFERRED_IO_WORKITEM_ROUTINE WorkerRoutine
Definition: fltkernel.h:1977
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
PLIST_ENTRY NTAPI KeRemoveQueue(IN PKQUEUE Queue, IN KPROCESSOR_MODE WaitMode, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: queue.c:238
NTSTATUS NTAPI PsTerminateSystemThread(IN NTSTATUS ExitStatus)
Definition: kill.c:1145
POBJECT_TYPE PsThreadType
Definition: thread.c:20
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
NTSTATUS NTAPI ObReferenceObjectByPointer(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode)
Definition: obref.c:381
BOOLEAN DumpDispatchRoutine
Definition: rxce.c:150
@ RxWorkQueueRundownInProgress
Definition: rxworkq.h:26
@ RxWorkQueueInactive
Definition: rxworkq.h:25
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
WORKER_THREAD_ROUTINE * PWORKER_THREAD_ROUTINE
Definition: extypes.h:200
#define ObDereferenceObject
Definition: obfuncs.h:203
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323

Referenced by RxBootstrapWorkerThreadDispatcher().

◆ RxReference()

VOID RxReference ( IN OUT PVOID  Instance)

Definition at line 7437 of file rxce.c.

7439{
7442
7443 PAGED_CODE();
7444
7446
7447 /* We can only reference a few structs */
7448 NodeType = NodeType(Instance) & ~RX_SCAVENGER_MASK;
7452
7454 InterlockedIncrement((volatile long *)&Node->NodeReferenceCount);
7455
7456 /* Trace refcount if asked */
7457 switch (NodeType)
7458 {
7459 case RDBSS_NTC_SRVCALL:
7460 PRINT_REF_COUNT(SRVCALL, Node->NodeReferenceCount);
7461 break;
7462
7463 case RDBSS_NTC_NETROOT:
7464 PRINT_REF_COUNT(NETROOT, Node->NodeReferenceCount);
7465 break;
7466
7468 PRINT_REF_COUNT(VNETROOT, Node->NodeReferenceCount);
7469 break;
7470
7471 case RDBSS_NTC_SRVOPEN:
7472 PRINT_REF_COUNT(SRVOPEN, Node->NodeReferenceCount);
7473 break;
7474
7475 case RDBSS_NTC_FOBX:
7476 PRINT_REF_COUNT(NETFOBX, Node->NodeReferenceCount);
7477 break;
7478
7479 default:
7480 ASSERT(FALSE);
7481 break;
7482 }
7483
7486}

Referenced by RxPrefixTableLookupName().

◆ RxReinitializeContext()

VOID NTAPI RxReinitializeContext ( IN OUT PRX_CONTEXT  RxContext)

Definition at line 7493 of file rxce.c.

7495{
7496 PIRP Irp;
7497 PRDBSS_DEVICE_OBJECT RxDeviceObject;
7498 ULONG InitialContextFlags, SavedFlags;
7499
7500 PAGED_CODE();
7501
7502 /* Backup a few flags */
7503 Irp = RxContext->CurrentIrp;
7504 RxDeviceObject = RxContext->RxDeviceObject;
7505 SavedFlags = RxContext->Flags & RX_CONTEXT_PRESERVED_FLAGS;
7506 InitialContextFlags = RxContext->Flags & RX_CONTEXT_INITIALIZATION_FLAGS;
7507
7508 /* Reset our context */
7509 RxPrepareContextForReuse(RxContext);
7510
7511 /* Zero everything */
7512 RtlZeroMemory(&RxContext->MajorFunction, sizeof(RX_CONTEXT) - FIELD_OFFSET(RX_CONTEXT, MajorFunction));
7513
7514 /* Restore saved flags */
7515 RxContext->Flags = SavedFlags;
7516 /* And reinit the context */
7517 RxInitializeContext(Irp, RxDeviceObject, InitialContextFlags, RxContext);
7518}
#define RX_CONTEXT_PRESERVED_FLAGS
Definition: rxcontx.h:314
#define RX_CONTEXT_INITIALIZATION_FLAGS
Definition: rxcontx.h:318
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
_In_ UCHAR MajorFunction
Definition: wdfdevice.h:1697

◆ RxReleaseFcbFromLazyWrite()

VOID NTAPI RxReleaseFcbFromLazyWrite ( PVOID  Context)

Definition at line 7525 of file rxce.c.

7527{
7528 PFCB Fcb;
7529
7530 PAGED_CODE();
7531
7532 Fcb = Context;
7533 /* The received context is a FCB */
7536
7537 /* Lazy writer is releasing lock, so forget about it */
7538 Fcb->Specific.Fcb.LazyWriteThread = NULL;
7539
7540 /* If we were top level IRP, unwind */
7542 {
7544 }
7545
7546 /* And finally, release the lock */
7549 ExReleaseResourceLite(Fcb->Header.PagingIoResource);
7550}
PIRP RxGetTopIrpIfRdbssIrp(VOID)
Definition: rdbss.c:6845
VOID RxUnwindTopLevelIrp(_Inout_ PRX_TOPLEVELIRP_CONTEXT TopLevelContext)

◆ RxReleaseFcbFromReadAhead()

VOID NTAPI RxReleaseFcbFromReadAhead ( PVOID  Context)

Definition at line 7557 of file rxce.c.

7559{
7560 PFCB Fcb;
7561
7562 PAGED_CODE();
7563
7564 Fcb = Context;
7565 /* The received context is a FCB */
7568
7569 /* Top Level IRP is CC */
7572
7573 ExReleaseResourceLite(Fcb->Header.Resource);
7574}

◆ RxReleaseFileForNtCreateSection()

VOID NTAPI RxReleaseFileForNtCreateSection ( PFILE_OBJECT  FileObject)

Definition at line 7578 of file rxce.c.

7580{
7582}

Referenced by RxInitializeDispatchVectors().

◆ RxReleaseForCcFlush()

NTSTATUS NTAPI RxReleaseForCcFlush ( PFILE_OBJECT  FileObject,
PDEVICE_OBJECT  DeviceObject 
)

Definition at line 7586 of file rxce.c.

7589{
7592}

Referenced by RxInitializeDispatchVectors().

◆ RxRemoveNameNetFcb()

VOID RxRemoveNameNetFcb ( OUT PFCB  ThisFcb)

Definition at line 7598 of file rxce.c.

7600{
7601 PNET_ROOT NetRoot;
7602
7603 PAGED_CODE();
7604
7605 ASSERT(NodeTypeIsFcb(ThisFcb));
7606
7607 /* Just remove the entry from the FCB_TABLE */
7608 NetRoot = (PNET_ROOT)ThisFcb->VNetRoot->pNetRoot;
7611
7612#ifdef __REACTOS__
7613 if (!BooleanFlagOn(ThisFcb->FcbState, FCB_STATE_NAME_ALREADY_REMOVED))
7614 {
7615#endif
7616 RxFcbTableRemoveFcb(&NetRoot->FcbTable, ThisFcb);
7617 DPRINT("FCB (%p) %wZ removed\n", ThisFcb, &ThisFcb->FcbTableEntry.Path);
7618 /* Mark, so that we don't try to do it twice */
7619 SetFlag(ThisFcb->FcbState, FCB_STATE_NAME_ALREADY_REMOVED);
7620#ifdef __REACTOS__
7621 }
7622#endif
7623}

◆ RxRemoveOperationFromBlockingQueue()

VOID RxRemoveOperationFromBlockingQueue ( IN OUT PRX_CONTEXT  RxContext)

Definition at line 7629 of file rxce.c.

7631{
7632 /* Acquire the pipe mutex */
7634
7635 /* Is that a blocking serial operation? */
7636 if (BooleanFlagOn(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION))
7637 {
7638 /* Clear it! */
7639 ClearFlag(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION);
7640
7641 /* Drop it off the list */
7642 RemoveEntryList(&RxContext->RxContextSerializationQLinks);
7643 RxContext->RxContextSerializationQLinks.Flink = NULL;
7644 RxContext->RxContextSerializationQLinks.Blink = NULL;
7645 }
7646
7647 /* Done */
7649}

◆ RxRemovePrefixTableEntry()

VOID RxRemovePrefixTableEntry ( IN OUT PRX_PREFIX_TABLE  ThisTable,
IN OUT PRX_PREFIX_ENTRY  Entry 
)

Definition at line 7655 of file rxce.c.

7658{
7659 PAGED_CODE();
7660
7663
7664 /* Check whether we're asked to remove null entry */
7665 if (Entry->Prefix.Length == 0)
7666 {
7667 ThisTable->TableEntryForNull = NULL;
7668 }
7669 else
7670 {
7671 RemoveEntryList(&Entry->HashLinks);
7672 }
7673
7674 Entry->ContainingRecord = NULL;
7675
7676 /* Also remove it from global list */
7677 RemoveEntryList(&Entry->MemberQLinks);
7678
7679 ++ThisTable->Version;
7680}

Referenced by RxFinalizeNetRoot(), RxFinalizeSrvCall(), RxFinalizeVNetRoot(), and RxRemoveVirtualNetRootFromNetRoot().

◆ RxRemoveVirtualNetRootFromNetRoot()

VOID RxRemoveVirtualNetRootFromNetRoot ( PNET_ROOT  NetRoot,
PV_NET_ROOT  VNetRoot 
)

Definition at line 7686 of file rxce.c.

7689{
7690 PRX_PREFIX_TABLE PrefixTable;
7691
7692 PAGED_CODE();
7693
7694 PrefixTable = NetRoot->pSrvCall->RxDeviceObject->pRxNetNameTable;
7695 ASSERT(RxIsPrefixTableLockAcquired(PrefixTable));
7696
7697 /* Remove the VNetRoot from the list in the NetRoot */
7698 --NetRoot->NumberOfVirtualNetRoots;
7700
7701 /* Fix the NetRoot if we were the default VNetRoot */
7702 if (NetRoot->DefaultVNetRoot == VNetRoot)
7703 {
7704 /* Put the first one available */
7705 if (!IsListEmpty(&NetRoot->VirtualNetRoots))
7706 {
7707 NetRoot->DefaultVNetRoot = CONTAINING_RECORD(NetRoot->VirtualNetRoots.Flink, V_NET_ROOT, NetRootListEntry);
7708 }
7709 /* Otherwise, none */
7710 else
7711 {
7712 NetRoot->DefaultVNetRoot = NULL;
7713 }
7714 }
7715
7716 /* If there are still other VNetRoot available, we're done */
7717 if (!IsListEmpty(&NetRoot->VirtualNetRoots))
7718 {
7719 return;
7720 }
7721
7722 /* Otherwise, initiate NetRoot finalization */
7724 {
7725 RxRemovePrefixTableEntry(PrefixTable, &NetRoot->PrefixEntry);
7727 }
7728
7729 /* Notify mini-rdr */
7730 if (NetRoot->pSrvCall != NULL && NetRoot->pSrvCall->RxDeviceObject != NULL)
7731 {
7733
7734 MINIRDR_CALL_THROUGH(Status, NetRoot->pSrvCall->RxDeviceObject->Dispatch,
7735 MRxFinalizeNetRoot, ((PMRX_NET_ROOT)NetRoot, FALSE));
7736 (void)Status;
7737 }
7738}
PV_NET_ROOT DefaultVNetRoot
Definition: fcb.h:49

Referenced by RxFinalizeVNetRoot().

◆ RxResumeBlockedOperations_ALL()

VOID RxResumeBlockedOperations_ALL ( IN OUT PRX_CONTEXT  RxContext)

Definition at line 7741 of file rxce.c.

7743{
7744 LIST_ENTRY BlockedOps;
7745
7746 PAGED_CODE();
7747
7748 /* Get the blocked operations */
7749 RxTransferListWithMutex(&BlockedOps, &RxContext->BlockedOperations, RxContext->BlockedOpsMutex);
7750
7751 if (!IsListEmpty(&BlockedOps))
7752 {
7754 }
7755}
#define RxTransferListWithMutex(Destination, Source, Mutex)
Definition: rxcontx.h:460

Referenced by RxLowIoCompletionTail().

◆ RxResumeBlockedOperations_Serially()

VOID NTAPI RxResumeBlockedOperations_Serially ( IN OUT PRX_CONTEXT  RxContext,
IN OUT PLIST_ENTRY  BlockingIoQ 
)

Definition at line 7759 of file rxce.c.

7762{
7763 PAGED_CODE();
7764
7766
7767 /* This can only happen on pipes */
7768 if (!BooleanFlagOn(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION))
7769 {
7771 return;
7772 }
7773
7775
7777}

◆ RxScavengeFobxsForNetRoot()

VOID RxScavengeFobxsForNetRoot ( PNET_ROOT  NetRoot,
PFCB  PurgingFcb,
BOOLEAN  SynchronizeWithScavenger 
)

Definition at line 7798 of file rxce.c.

7802{
7803 PRDBSS_SCAVENGER Scavenger;
7804 PRDBSS_DEVICE_OBJECT RxDeviceObject;
7805
7806 PAGED_CODE();
7807
7808 RxDeviceObject = NetRoot->pSrvCall->RxDeviceObject;
7809 Scavenger = RxDeviceObject->pRdbssScavenger;
7810
7811 /* Wait for the scavenger, if asked to */
7812 if (SynchronizeWithScavenger)
7813 {
7815 }
7816
7818
7819 /* If there's nothing left to do... */
7820 if (Scavenger->FobxsToBeFinalized <= 0)
7821 {
7823 }
7824 else
7825 {
7827 LIST_ENTRY FobxToScavenge;
7828
7829 InitializeListHead(&FobxToScavenge);
7830
7831 /* Browse all the FOBXs to finalize */
7832 Entry = Scavenger->FobxFinalizationList.Flink;
7833 while (Entry != &Scavenger->FobxFinalizationList)
7834 {
7835 PFOBX Fobx;
7836
7837 Fobx = CONTAINING_RECORD(Entry, FOBX, ScavengerFinalizationList);
7838 Entry = Entry->Flink;
7839
7840 if (Fobx->SrvOpen != NULL)
7841 {
7842 PFCB Fcb;
7843
7844 Fcb = (PFCB)Fobx->SrvOpen->pFcb;
7845
7846 /* If it matches our NET_ROOT */
7847 if ((PNET_ROOT)Fcb->pNetRoot == NetRoot)
7848 {
7850
7851 /* Check whether it matches our FCB */
7853 if (PurgingFcb != NULL && PurgingFcb != Fcb)
7854 {
7855 MINIRDR_CALL_THROUGH(Status, RxDeviceObject->Dispatch, MRxAreFilesAliased, (Fcb, PurgingFcb));
7856 }
7857
7858 /* If so, add it to the list of the FOBXs to scavenge */
7859 if (Status != STATUS_SUCCESS)
7860 {
7861 RxReferenceNetFobx(Fobx);
7862 ASSERT(NodeType(Fobx) == RDBSS_NTC_FOBX);
7863
7865 InsertTailList(&FobxToScavenge, &Fobx->ScavengerFinalizationList);
7866 }
7867 }
7868 }
7869 }
7870
7872
7873 /* Now, scavenge all the extracted FOBX */
7874 RxpScavengeFobxs(Scavenger, &FobxToScavenge);
7875 }
7876
7877 if (SynchronizeWithScavenger)
7878 {
7880 }
7881}
VOID RxpScavengeFobxs(PRDBSS_SCAVENGER Scavenger, PLIST_ENTRY FobxToScavenge)
Definition: rxce.c:6695
KEVENT ScavengeEvent
Definition: scavengr.h:77

Referenced by RxCommonCreate(), and RxCommonSetInformation().

◆ RxScavengeRelatedFobxs()

BOOLEAN RxScavengeRelatedFobxs ( PFCB  Fcb)

Definition at line 7887 of file rxce.c.

7889{
7890 PFOBX Fobx;
7891 LIST_ENTRY LocalList;
7892 PLIST_ENTRY NextEntry;
7893 PRDBSS_SCAVENGER Scavenger;
7894
7895 PAGED_CODE();
7896
7897 /* First of all, check whether there are FOBX to scavenge */
7898 Scavenger = Fcb->RxDeviceObject->pRdbssScavenger;
7900 if (Scavenger->FobxsToBeFinalized <= 0)
7901 {
7903 return FALSE;
7904 }
7905
7906 /* Initialize our local list which will hold all the FOBX to scavenge so
7907 * that we don't acquire the scavenger mutex too long
7908 */
7909 InitializeListHead(&LocalList);
7910
7911 /* Technically, that condition should all be true... */
7912 if (!IsListEmpty(&Scavenger->FobxFinalizationList))
7913 {
7914 PLIST_ENTRY NextEntry, LastEntry;
7915
7916 /* Browse all the FCBs to find the matching ones */
7917 NextEntry = Scavenger->FobxFinalizationList.Flink;
7918 LastEntry = &Scavenger->FobxFinalizationList;
7919 while (NextEntry != LastEntry)
7920 {
7921 Fobx = CONTAINING_RECORD(NextEntry, FOBX, ScavengerFinalizationList);
7922 NextEntry = NextEntry->Flink;
7923 /* Matching our FCB? Let's finalize it */
7924 if (Fobx->pSrvOpen != NULL && Fobx->pSrvOpen->pFcb == RX_GET_MRX_FCB(Fcb))
7925 {
7927 ASSERT(NodeType(Fobx) == RDBSS_NTC_FOBX);
7928 InsertTailList(&LocalList, &Fobx->ScavengerFinalizationList);
7929 }
7930 }
7931 }
7932
7934
7935 /* Nothing to scavenge? Quit */
7936 if (IsListEmpty(&LocalList))
7937 {
7938 return FALSE;
7939 }
7940
7941 /* Now, finalize all the extracted FOBX */
7942 while (!IsListEmpty(&LocalList))
7943 {
7944 NextEntry = RemoveHeadList(&LocalList);
7945 Fobx = CONTAINING_RECORD(NextEntry, FOBX, ScavengerFinalizationList);
7946 RxFinalizeNetFobx(Fobx, TRUE, TRUE);
7947 }
7948
7949 return TRUE;
7950}

Referenced by RxFinalizeConnection().

◆ RxScavengerFinalizeEntries()

VOID RxScavengerFinalizeEntries ( PRDBSS_DEVICE_OBJECT  DeviceObject)

Definition at line 7953 of file rxce.c.

7955{
7957}

Referenced by RxScavengerTimerRoutine().

◆ RxScavengerTimerRoutine()

VOID NTAPI RxScavengerTimerRoutine ( PVOID  Context)

Definition at line 7964 of file rxce.c.

7966{
7969 PRDBSS_SCAVENGER Scavenger;
7970
7971 PAGED_CODE();
7972
7974 Scavenger = DeviceObject->pRdbssScavenger;
7975
7976 Requeue = FALSE;
7978 /* If the scavenger was dormant, wake it up! */
7979 if (Scavenger->State == RDBSS_SCAVENGER_DORMANT)
7980 {
7981 /* Done */
7982 Scavenger->State = RDBSS_SCAVENGER_ACTIVE;
7983 KeClearEvent(&Scavenger->ScavengeEvent);
7984
7985 /* Scavenger the entries */
7989
7990 /* If we're still active (race) */
7991 if (Scavenger->State == RDBSS_SCAVENGER_ACTIVE)
7992 {
7993 /* If there are new entries to scavenge, stay dormant and requeue a run */
7994 if (Scavenger->NumberOfDormantFiles + Scavenger->SrvCallsToBeFinalized +
7995 Scavenger->NetRootsToBeFinalized + Scavenger->VNetRootsToBeFinalized +
7996 Scavenger->FcbsToBeFinalized + Scavenger->SrvOpensToBeFinalized +
7997 Scavenger->FobxsToBeFinalized != 0)
7998 {
7999 Requeue = TRUE;
8000 Scavenger->State = RDBSS_SCAVENGER_DORMANT;
8001 }
8002 /* Otherwise, we're inactive again */
8003 else
8004 {
8005 Scavenger->State = RDBSS_SCAVENGER_INACTIVE;
8006 }
8007 }
8008
8010
8011 /* Requeue an execution */
8012 if (Requeue)
8013 {
8016 }
8017 }
8018 else
8019 {
8021 }
8022
8024}
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
VOID RxScavengerFinalizeEntries(PRDBSS_DEVICE_OBJECT DeviceObject)
Definition: rxce.c:7953
@ RDBSS_SCAVENGER_ACTIVE
Definition: scavengr.h:52
ULONG FcbsToBeFinalized
Definition: scavengr.h:65
_In_ WDFREQUEST _In_ BOOLEAN Requeue
Definition: wdfrequest.h:1654

Referenced by RxMarkFobxOnCleanup(), RxpMarkInstanceForScavengedFinalization(), and RxScavengerTimerRoutine().

◆ RxScavengeVNetRoots()

BOOLEAN RxScavengeVNetRoots ( PRDBSS_DEVICE_OBJECT  RxDeviceObject)

Definition at line 8027 of file rxce.c.

8029{
8031 return FALSE;
8032}

◆ RxSetFileSizeWithLock()

VOID RxSetFileSizeWithLock ( IN OUT PFCB  Fcb,
IN PLONGLONG  FileSize 
)

Definition at line 7783 of file rxce.c.

7786{
7787 PAGED_CODE();
7788
7789 /* Set attribute and increase version */
7790 Fcb->Header.FileSize.QuadPart = *FileSize;
7792}

◆ RxSpinUpRequestsDispatcher()

VOID NTAPI RxSpinUpRequestsDispatcher ( PVOID  Dispatcher)

Definition at line 8039 of file rxce.c.

8041{
8044
8046 if (!NT_SUCCESS(Status))
8047 {
8049 }
8050
8051 RxDispatcher = Dispatcher;
8052
8053 do
8054 {
8055 KIRQL OldIrql;
8056 PLIST_ENTRY ListEntry;
8057
8061
8064 {
8066 }
8067 else
8068 {
8069 ListEntry = &RxDispatcher->SpinUpRequests;
8070 }
8073
8074 while (ListEntry != &RxDispatcher->SpinUpRequests)
8075 {
8078
8080 WorkQueue = WorkItem->Parameter;
8081
8082 InterlockedDecrement(&WorkQueue->WorkQueueItemForSpinUpWorkerThreadInUse);
8083
8084 DPRINT("Workqueue: calling %p(%p)\n", WorkItem->WorkerRoutine, WorkItem->Parameter);
8085 WorkItem->WorkerRoutine(WorkItem->Parameter);
8086 }
8088
8091}
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:115

Referenced by RxInitializeDispatcher().

◆ RxSpinUpWorkerThread()

NTSTATUS RxSpinUpWorkerThread ( PRX_WORK_QUEUE  WorkQueue,
PRX_WORKERTHREAD_ROUTINE  Routine,
PVOID  Parameter 
)

Definition at line 8097 of file rxce.c.

8101{
8102 KIRQL OldIrql;
8104 HANDLE ThreadHandle;
8105
8106 PAGED_CODE();
8107
8108 /* If work queue is inactive, that cannot work */
8109 KeAcquireSpinLock(&WorkQueue->SpinLock, &OldIrql);
8110 if (WorkQueue->State != RxWorkQueueActive)
8111 {
8113 DPRINT("Workqueue not active! WorkQ: %p, State: %d, Active: %d\n", WorkQueue, WorkQueue->State, WorkQueue->NumberOfActiveWorkerThreads);
8114 }
8115 else
8116 {
8117 ++WorkQueue->NumberOfActiveWorkerThreads;
8119 }
8120 KeReleaseSpinLock(&WorkQueue->SpinLock, OldIrql);
8121
8122 /* Quit on failure */
8123 if (!NT_SUCCESS(Status))
8124 {
8125 return Status;
8126 }
8127
8128 /* Spin up the worker thread */
8129 Status = PsCreateSystemThread(&ThreadHandle, PROCESS_ALL_ACCESS, NULL, NULL, NULL, Routine, Parameter);
8130 if (NT_SUCCESS(Status))
8131 {
8132 ZwClose(ThreadHandle);
8133 return Status;
8134 }
8135 /* Read well: we reached that point because it failed! */
8136 DPRINT("WorkQ: %p, Status: %lx\n", WorkQueue, Status);
8137
8138 KeAcquireSpinLock(&WorkQueue->SpinLock, &OldIrql);
8139 --WorkQueue->NumberOfActiveWorkerThreads;
8140 ++WorkQueue->NumberOfFailedSpinUpRequests;
8141
8142 /* Rundown, no more active threads, set the event! */
8143 if (WorkQueue->NumberOfActiveWorkerThreads == 0 &&
8145 {
8146 KeSetEvent(&WorkQueue->pRundownContext->RundownCompletionEvent, IO_NO_INCREMENT, FALSE);
8147 }
8148
8149 DPRINT("Workqueue not active! WorkQ: %p, State: %d, Active: %d\n", WorkQueue, WorkQueue->State, WorkQueue->NumberOfActiveWorkerThreads);
8150
8151 KeReleaseSpinLock(&WorkQueue->SpinLock, OldIrql);
8152
8153 return Status;
8154}

Referenced by RxInitializeWorkQueueDispatcher().

◆ RxSpinUpWorkerThreads()

VOID RxSpinUpWorkerThreads ( PRX_WORK_QUEUE  WorkQueue)

Definition at line 8157 of file rxce.c.

8159{
8161}

Referenced by RxInsertWorkQueueItem().

◆ RxSynchronizeWithScavenger()

VOID RxSynchronizeWithScavenger ( IN PRX_CONTEXT  RxContext)

Definition at line 8164 of file rxce.c.

8166{
8168}

◆ RxTableComputeHashValue()

ULONG RxTableComputeHashValue ( IN PUNICODE_STRING  Name)

Definition at line 8174 of file rxce.c.

8176{
8177 ULONG Hash;
8178 SHORT Loops[8];
8179 USHORT MaxChar, i;
8180
8181 PAGED_CODE();
8182
8183 MaxChar = Name->Length / sizeof(WCHAR);
8184
8185 Loops[0] = 1;
8186 Loops[1] = MaxChar - 1;
8187 Loops[2] = MaxChar - 2;
8188 Loops[3] = MaxChar - 3;
8189 Loops[4] = MaxChar - 4;
8190 Loops[5] = MaxChar / 4;
8191 Loops[6] = 2 * MaxChar / 4;
8192 Loops[7] = 3 * MaxChar / 4;
8193
8194 Hash = 0;
8195 for (i = 0; i < 8; ++i)
8196 {
8197 SHORT Idx;
8198
8199 Idx = Loops[i];
8200 if (Idx >= 0 && Idx < MaxChar)
8201 {
8202 Hash = RtlUpcaseUnicodeChar(Name->Buffer[Idx]) + 8 * Hash;
8203 }
8204 }
8205
8206 return Hash;
8207}
WCHAR NTAPI RtlUpcaseUnicodeChar(_In_ WCHAR Source)
Definition: nlsboot.c:176
short SHORT
Definition: pedump.c:59

Referenced by RxPrefixTableInsertName(), and RxTableLookupName().

◆ RxTableComputePathHashValue()

ULONG RxTableComputePathHashValue ( IN PUNICODE_STRING  Name)

Definition at line 8213 of file rxce.c.

8215{
8216 ULONG Hash;
8217 SHORT Loops[8];
8218 USHORT MaxChar, i;
8219
8220 PAGED_CODE();
8221
8222 MaxChar = Name->Length / sizeof(WCHAR);
8223
8224 Loops[0] = 1;
8225 Loops[1] = MaxChar - 1;
8226 Loops[2] = MaxChar - 2;
8227 Loops[3] = MaxChar - 3;
8228 Loops[4] = MaxChar - 4;
8229 Loops[5] = MaxChar / 4;
8230 Loops[6] = 2 * MaxChar / 4;
8231 Loops[7] = 3 * MaxChar / 4;
8232
8233 Hash = 0;
8234 for (i = 0; i < 8; ++i)
8235 {
8236 SHORT Idx;
8237
8238 Idx = Loops[i];
8239 if (Idx >= 0 && Idx < MaxChar)
8240 {
8241 Hash = RtlUpcaseUnicodeChar(Name->Buffer[Idx]) + 8 * Hash;
8242 }
8243 }
8244
8245 return Hash;
8246}

Referenced by RxFcbTableInsertFcb(), and RxFcbTableLookupFcb().

◆ RxTableLookupName()

PVOID RxTableLookupName ( IN PRX_PREFIX_TABLE  ThisTable,
IN PUNICODE_STRING  Name,
OUT PUNICODE_STRING  RemainingName,
IN PRX_CONNECTION_ID OPTIONAL  RxConnectionId 
)

Definition at line 8252 of file rxce.c.

8257{
8258 PVOID Container;
8259 USHORT i, MaxChar;
8261 RX_CONNECTION_ID NullId;
8262 UNICODE_STRING LookupString;
8263
8264 PAGED_CODE();
8265
8266 /* If caller didn't provide a connection ID, setup one */
8267 if (ThisTable->IsNetNameTable && RxConnectionId == NULL)
8268 {
8269 NullId.Luid.LowPart = 0;
8270 NullId.Luid.HighPart = 0;
8271 RxConnectionId = &NullId;
8272 }
8273
8274 /* Validate name */
8275 ASSERT(Name->Buffer[0] == OBJ_NAME_PATH_SEPARATOR);
8276
8277 Entry = NULL;
8278 Container = NULL;
8279 LookupString.Buffer = Name->Buffer;
8280 MaxChar = Name->Length / sizeof(WCHAR);
8281 /* We'll perform the lookup, path component after another */
8282 for (i = 1; i < MaxChar; ++i)
8283 {
8284 ULONG Hash;
8285 PRX_PREFIX_ENTRY CurEntry;
8286
8287 /* Don't cut in the middle of a path element */
8288 if (Name->Buffer[i] != OBJ_NAME_PATH_SEPARATOR && Name->Buffer[i] != ':')
8289 {
8290 continue;
8291 }
8292
8293 /* Perform lookup in the table */
8294 LookupString.Length = i * sizeof(WCHAR);
8295 Hash = RxTableComputeHashValue(&LookupString);
8296 CurEntry = RxTableLookupName_ExactLengthMatch(ThisTable, &LookupString, Hash, RxConnectionId);
8297#if DBG
8298 ++ThisTable->Lookups;
8299#endif
8300 /* Entry not found, move to the next component */
8301 if (CurEntry == NULL)
8302 {
8303#if DBG
8304 ++ThisTable->FailedLookups;
8305#endif
8306 continue;
8307 }
8308
8309 Entry = CurEntry;
8310 ASSERT(Entry->ContainingRecord != NULL);
8311 Container = Entry->ContainingRecord;
8312
8313 /* If we have a NET_ROOT, let's return a V_NET_ROOT */
8314 if ((NodeType(Entry->ContainingRecord) & ~RX_SCAVENGER_MASK) == RDBSS_NTC_NETROOT)
8315 {
8316 PNET_ROOT NetRoot;
8317
8318 NetRoot = (PNET_ROOT)Entry->ContainingRecord;
8319 /* If there's a default one, perfect, that's a match */
8320 if (NetRoot->DefaultVNetRoot != NULL)
8321 {
8322 Container = NetRoot->DefaultVNetRoot;
8323 }
8324 /* If none (that shouldn't happen!), try to find one */
8325 else
8326 {
8327 /* Use the first one in the list */
8328 if (!IsListEmpty(&NetRoot->VirtualNetRoots))
8329 {
8330 Container = CONTAINING_RECORD(NetRoot->VirtualNetRoots.Flink, V_NET_ROOT, NetRootListEntry);
8331 }
8332 /* Really, really, shouldn't happen */
8333 else
8334 {
8335 ASSERT(FALSE);
8336 Entry = NULL;
8337 Container = NULL;
8338 }
8339 }
8340
8341 break;
8342 }
8343 else if ((NodeType(Entry->ContainingRecord) & ~RX_SCAVENGER_MASK) == RDBSS_NTC_V_NETROOT)
8344 {
8345 break;
8346 }
8347 else
8348 {
8349 ASSERT((NodeType(Entry->ContainingRecord) & ~RX_SCAVENGER_MASK) == RDBSS_NTC_SRVCALL);
8350 }
8351 }
8352
8353 /* Entry was found */
8354 if (Entry != NULL)
8355 {
8356 DPRINT("Found\n");
8357
8358 ASSERT(Name->Length >= Entry->Prefix.Length);
8359
8360 /* Setup remaining name */
8361 RemainingName->Buffer = Add2Ptr(Name->Buffer, Entry->Prefix.Length);
8362 RemainingName->Length = Name->Length - Entry->Prefix.Length;
8363 RemainingName->MaximumLength = Name->Length - Entry->Prefix.Length;
8364 }
8365 else
8366 {
8367 /* Otherwise, that's the whole name */
8369 }
8370
8371 return Container;
8372}
struct NameRec_ * Name
Definition: cdprocs.h:460
PRX_PREFIX_ENTRY RxTableLookupName_ExactLengthMatch(IN PRX_PREFIX_TABLE ThisTable, IN PUNICODE_STRING Name, IN ULONG HashValue, IN PRX_CONNECTION_ID OPTIONAL RxConnectionId)
Definition: rxce.c:8378
LONG HighPart
DWORD LowPart

Referenced by RxPrefixTableLookupName().

◆ RxTableLookupName_ExactLengthMatch()

PRX_PREFIX_ENTRY RxTableLookupName_ExactLengthMatch ( IN PRX_PREFIX_TABLE  ThisTable,
IN PUNICODE_STRING  Name,
IN ULONG  HashValue,
IN PRX_CONNECTION_ID OPTIONAL  RxConnectionId 
)

Definition at line 8378 of file rxce.c.

8383{
8384 PLIST_ENTRY ListEntry, HashBucket;
8385
8386 PAGED_CODE();
8387
8388 ASSERT(RxConnectionId != NULL);
8389
8390 /* Select the right bucket */
8391 HashBucket = HASH_BUCKET(ThisTable, HashValue);
8392 DPRINT("Looking in bucket: %p for %x\n", HashBucket, HashValue);
8393 /* If bucket is empty, no match */
8394 if (IsListEmpty(HashBucket))
8395 {
8396 return NULL;
8397 }
8398
8399 /* Browse all the entries in the bucket */
8400 for (ListEntry = HashBucket->Flink;
8401 ListEntry != HashBucket;
8402 ListEntry = ListEntry->Flink)
8403 {
8404 PVOID Container;
8407 PUNICODE_STRING CmpName, CmpPrefix;
8408 UNICODE_STRING InsensitiveName, InsensitivePrefix;
8409
8410 Entry = CONTAINING_RECORD(ListEntry, RX_PREFIX_ENTRY, HashLinks);
8411#if DBG
8412 ++ThisTable->Considers;
8413#endif
8414 ASSERT(HashBucket == HASH_BUCKET(ThisTable, Entry->SavedHashValue));
8415
8416 Container = Entry->ContainingRecord;
8417 ASSERT(Container != NULL);
8418
8419 /* Not the same hash, not the same length, move on */
8420 if (Entry->SavedHashValue != HashValue || Entry->Prefix.Length != Name->Length)
8421 {
8422 continue;
8423 }
8424
8425#if DBG
8426 ++ThisTable->Compares;
8427#endif
8428 /* If we have to perform a case insensitive compare on a portion... */
8429 if (Entry->CaseInsensitiveLength != 0)
8430 {
8431 ASSERT(Entry->CaseInsensitiveLength <= Name->Length);
8432
8433 /* Perform the case insensitive check on the asked length */
8434 InsensitiveName.Buffer = Name->Buffer;
8435 InsensitivePrefix.Buffer = Entry->Prefix.Buffer;
8436 InsensitiveName.Length = Entry->CaseInsensitiveLength;
8437 InsensitivePrefix.Length = Entry->CaseInsensitiveLength;
8438 /* No match, move to the next entry */
8439 if (!RtlEqualUnicodeString(&InsensitiveName, &InsensitivePrefix, TRUE))
8440 {
8441 continue;
8442 }
8443
8444 /* Was the case insensitive covering the whole name? */
8445 if (Name->Length == Entry->CaseInsensitiveLength)
8446 {
8447 /* If connection ID also matches, that a complete match! */
8448 if (!ThisTable->IsNetNameTable || RxEqualConnectionId(RxConnectionId, &Entry->ConnectionId))
8449 {
8450 return Entry;
8451 }
8452 }
8453
8454 /* Otherwise, we have to continue with the sensitive match.... */
8455 InsensitiveName.Buffer = Add2Ptr(InsensitiveName.Buffer, Entry->CaseInsensitiveLength);
8456 InsensitivePrefix.Buffer = Add2Ptr(InsensitivePrefix.Buffer, Entry->CaseInsensitiveLength);
8457 InsensitiveName.Length = Name->Length - Entry->CaseInsensitiveLength;
8458 InsensitivePrefix.Length = Entry->Prefix.Length - Entry->CaseInsensitiveLength;
8459
8460 CmpName = &InsensitiveName;
8461 CmpPrefix = &InsensitivePrefix;
8463 }
8464 else
8465 {
8466 CmpName = Name;
8467 CmpPrefix = &Entry->Prefix;
8468 CaseInsensitive = ThisTable->CaseInsensitiveMatch;
8469 }
8470
8471 /* Perform the compare, if there's a match, also check for connection ID */
8472 if (RtlEqualUnicodeString(CmpName, CmpPrefix, CaseInsensitive))
8473 {
8474 if (!ThisTable->IsNetNameTable || RxEqualConnectionId(RxConnectionId, &Entry->ConnectionId))
8475 {
8476 return Entry;
8477 }
8478 }
8479 }
8480
8481 return NULL;
8482}
_In_ const STRING _In_ BOOLEAN CaseInsensitive
Definition: rtlfuncs.h:2359
#define RxEqualConnectionId(C1, C2)
Definition: rxprocs.h:774
_In_ BOOLEAN _In_ ULONG _Out_ PULONG HashValue
Definition: rtlfuncs.h:2039

Referenced by RxTableLookupName().

◆ RxTearDownBufferingManager()

NTSTATUS RxTearDownBufferingManager ( PSRV_CALL  SrvCall)

Definition at line 8488 of file rxce.c.

8490{
8491 PAGED_CODE();
8492
8493 /* Nothing to do */
8494 return STATUS_SUCCESS;
8495}

Referenced by RxFinalizeSrvCall().

◆ RxTimerDispatch()

VOID NTAPI RxTimerDispatch ( _In_ struct _KDPC Dpc,
_In_opt_ PVOID  DeferredContext,
_In_opt_ PVOID  SystemArgument1,
_In_opt_ PVOID  SystemArgument2 
)

Definition at line 8502 of file rxce.c.

8507{
8508 BOOLEAN Set;
8509 LIST_ENTRY LocalList;
8510 PLIST_ENTRY ListEntry;
8512
8513 InitializeListHead(&LocalList);
8514
8517
8518 /* Find any entry matching */
8520 {
8521 ListEntry = RxTimerQueueHead.Flink;
8522 do
8523 {
8524 WorkItem = CONTAINING_RECORD(ListEntry, RX_WORK_ITEM, WorkQueueItem.List);
8525 if (WorkItem->LastTick == RxTimerTickCount)
8526 {
8527 ListEntry = ListEntry->Flink;
8528
8529 RemoveEntryList(&WorkItem->WorkQueueItem.List);
8530 InsertTailList(&LocalList, &WorkItem->WorkQueueItem.List);
8531 }
8532 else
8533 {
8534 ListEntry = ListEntry->Flink;
8535 }
8536 } while (ListEntry != &RxTimerQueueHead);
8537 }
8538 /* Do we have to requeue a later execution? */
8540
8542
8543 /* Requeue if list wasn't empty */
8544 if (Set)
8545 {
8547 }
8548
8549 /* If we had matching entries */
8550 if (!IsListEmpty(&LocalList))
8551 {
8552 /* Post them, one after another */
8553 ListEntry = LocalList.Flink;
8554 do
8555 {
8556 WorkItem = CONTAINING_RECORD(ListEntry, RX_WORK_ITEM, WorkQueueItem.List);
8557 ListEntry = ListEntry->Flink;
8558
8559 WorkItem->WorkQueueItem.List.Flink = NULL;
8560 WorkItem->WorkQueueItem.List.Blink = NULL;
8561 RxPostToWorkerThread(WorkItem->WorkQueueItem.pDeviceObject, CriticalWorkQueue,
8562 &WorkItem->WorkQueueItem, WorkItem->WorkQueueItem.WorkerRoutine,
8563 WorkItem->WorkQueueItem.Parameter);
8564 }
8565 while (ListEntry != &LocalList);
8566 }
8567}
static BOOL Set
Definition: pageheap.c:10
#define KeAcquireSpinLockAtDpcLevel(SpinLock)
Definition: ke.h:125
#define KeReleaseSpinLockFromDpcLevel(SpinLock)
Definition: ke.h:135

Referenced by RxInitializeRxTimer().

◆ RxTrackPagingIoResource()

VOID RxTrackPagingIoResource ( _Inout_ PVOID  Instance,
_In_ ULONG  Type,
_In_ ULONG  Line,
_In_ PCSTR  File 
)

Definition at line 8654 of file rxce.c.

8659{
8661}

◆ RxUndoScavengerFinalizationMarking()

VOID RxUndoScavengerFinalizationMarking ( PVOID  Instance)

Definition at line 8667 of file rxce.c.

8669{
8670 /* Just call internal routine with mutex held */
8674}

Referenced by RxProcessChangeBufferingStateRequests().

◆ RxUninitializeVNetRootParameters()

VOID RxUninitializeVNetRootParameters ( IN PUNICODE_STRING  UserName,
IN PUNICODE_STRING  UserDomainName,
IN PUNICODE_STRING  Password,
OUT PULONG  Flags 
)

Definition at line 8680 of file rxce.c.

8685{
8686 PAGED_CODE();
8687
8688 /* Only free what could have been allocated */
8689 if (UserName != NULL)
8690 {
8691 RxFreePool(UserName);
8692 }
8693
8694 if (UserDomainName != NULL)
8695 {
8696 RxFreePool(UserDomainName);
8697 }
8698
8699 if (Password != NULL)
8700 {
8702 }
8703
8704 /* And remove the possibly set CSC agent flag */
8705 if (Flags != NULL)
8706 {
8707 (*Flags) &= ~VNETROOT_FLAG_CSCAGENT_INSTANCE;
8708 }
8709}

Referenced by RxCreateVNetRoot(), RxFinalizeVNetRoot(), and RxFindOrConstructVirtualNetRoot().

◆ RxUpdateCondition()

VOID RxUpdateCondition ( IN RX_BLOCK_CONDITION  NewConditionValue,
OUT PRX_BLOCK_CONDITION  Condition,
IN OUT PLIST_ENTRY  TransitionWaitList 
)

Definition at line 8715 of file rxce.c.

8719{
8721 LIST_ENTRY SerializationQueue;
8722
8723 PAGED_CODE();
8724
8725 DPRINT("RxUpdateCondition(%d, %p, %p)\n", NewConditionValue, Condition, TransitionWaitList);
8726
8727 /* Set the new condition */
8729 ASSERT(NewConditionValue != Condition_InTransition);
8730 *Condition = NewConditionValue;
8731 /* And get the serialization queue for treatment */
8732 RxTransferList(&SerializationQueue, TransitionWaitList);
8734
8735 /* Handle the serialization queue */
8737 while (Context != NULL)
8738 {
8739 /* If the caller asked for post, post the request */
8741 {
8742 Context->Flags &= ~RX_CONTEXT_FLAG_POST_ON_STABLE_CONDITION;
8744 }
8745 /* Otherwise, wake up sleeping waiters */
8746 else
8747 {
8749 }
8750
8752 }
8753}
@ RX_CONTEXT_FLAG_POST_ON_STABLE_CONDITION
Definition: rxcontx.h:295
FORCEINLINE PRX_CONTEXT RxRemoveFirstContextFromSerializationQueue(PLIST_ENTRY SerializationQueue)
Definition: rxcontx.h:427

◆ RxVerifyOperationIsLegal()

VOID RxVerifyOperationIsLegal ( IN PRX_CONTEXT  RxContext)

Definition at line 8759 of file rxce.c.

8761{
8762 PIRP Irp;
8763 PMRX_FOBX Fobx;
8764 BOOLEAN FlagSet;
8767
8768 PAGED_CODE();
8769
8770 Irp = RxContext->CurrentIrp;
8771 Stack = RxContext->CurrentIrpSp;
8772 FileObject = Stack->FileObject;
8773
8774 /* We'll only check stuff on opened files, this requires an IRP and a FO */
8775 if (Irp == NULL || FileObject == NULL)
8776 {
8777 return;
8778 }
8779
8780 /* Set no exception for breakpoint - remember whether is was already set */
8781 FlagSet = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT);
8783
8784 /* If we have a CCB, perform a few checks on opened file */
8785 Fobx = RxContext->pFobx;
8786 if (Fobx != NULL)
8787 {
8788 PMRX_SRV_OPEN SrvOpen;
8789
8790 SrvOpen = Fobx->pSrvOpen;
8791 if (SrvOpen != NULL)
8792 {
8794
8795 MajorFunction = RxContext->MajorFunction;
8796 /* Only allow closing/cleanup operations on renamed files */
8799 {
8800 RxContext->IoStatusBlock.Status = STATUS_FILE_RENAMED;
8802 }
8803
8804 /* Only allow closing/cleanup operations on deleted files */
8807 {
8808 RxContext->IoStatusBlock.Status = STATUS_FILE_DELETED;
8810 }
8811 }
8812 }
8813
8814 /* If that's an open operation */
8815 if (RxContext->MajorFunction == IRP_MJ_CREATE)
8816 {
8817 PFILE_OBJECT RelatedFileObject;
8818
8819 /* We won't allow an open operation relative to a file to be deleted */
8820 RelatedFileObject = FileObject->RelatedFileObject;
8821 if (RelatedFileObject != NULL)
8822 {
8823 PMRX_FCB Fcb;
8824
8825 Fcb = RelatedFileObject->FsContext;
8827 {
8828 RxContext->IoStatusBlock.Status = STATUS_DELETE_PENDING;
8830 }
8831 }
8832 }
8833
8834 /* If cleanup was completed */
8836 {
8837 if (!BooleanFlagOn(Irp->Flags, IRP_PAGING_IO))
8838 {
8840
8841 /* We only allow a subset of operations (see FatVerifyOperationIsLegal for instance) */
8842 MajorFunction = Stack->MajorFunction;
8845 {
8847 !BooleanFlagOn(Stack->MinorFunction, IRP_MN_COMPLETE))
8848 {
8849 RxContext->IoStatusBlock.Status = STATUS_FILE_CLOSED;
8851 }
8852 }
8853 }
8854 }
8855
8856 /* If flag was already set, don't clear it */
8857 if (!FlagSet)
8858 {
8860 }
8861}
#define SRVOPEN_FLAG_FILE_DELETED
Definition: mrxfcb.h:135
#define SRVOPEN_FLAG_FILE_RENAMED
Definition: mrxfcb.h:134
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
#define STATUS_FILE_CLOSED
Definition: ntstatus.h:532
#define STATUS_FILE_RENAMED
Definition: ntstatus.h:449
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
PMRX_SRV_OPEN pSrvOpen
Definition: mrxfcb.h:195
ULONG Flags
Definition: mrxfcb.h:168
#define STATUS_FILE_DELETED
Definition: udferr_usr.h:172
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
#define IRP_MN_COMPLETE
Definition: iotypes.h:4420
#define FO_CLEANUP_COMPLETE
Definition: iotypes.h:1790
* PFILE_OBJECT
Definition: iotypes.h:1998
#define IRP_MJ_CLEANUP

Referenced by __RxAcquireFcb().

◆ RxWaitForStableCondition()

VOID RxWaitForStableCondition ( IN PRX_BLOCK_CONDITION  Condition,
IN OUT PLIST_ENTRY  TransitionWaitList,
IN OUT PRX_CONTEXT  RxContext,
OUT NTSTATUS *AsyncStatus  OPTIONAL 
)

Definition at line 8867 of file rxce.c.

8872{
8873 BOOLEAN Wait;
8874 NTSTATUS LocalStatus;
8875
8876 PAGED_CODE();
8877
8878 /* Make sure to always get status */
8879 if (AsyncStatus == NULL)
8880 {
8881 AsyncStatus = &LocalStatus;
8882 }
8883
8884 /* By default, it's a success */
8885 *AsyncStatus = STATUS_SUCCESS;
8886
8887 Wait = FALSE;
8888 /* If it's not stable, we've to wait */
8890 {
8891 /* Lock the mutex */
8893 /* Still not stable? */
8895 {
8896 /* Insert us in the wait list for processing on stable condition */
8897 RxInsertContextInSerializationQueue(TransitionWaitList, RxContext);
8898
8899 /* If we're asked to post on stable, don't wait, and just return pending */
8901 {
8902 *AsyncStatus = STATUS_PENDING;
8903 }
8904 else
8905 {
8906 Wait = TRUE;
8907 }
8908 }
8910
8911 /* We don't post on stable, so, just wait... */
8912 if (Wait)
8913 {
8914 RxWaitSync(RxContext);
8915 }
8916 }
8917}
#define RxInsertContextInSerializationQueue(SerializationQueue, RxContext)
Definition: rxcontx.h:421

◆ RxWorkItemDispatcher()

VOID NTAPI RxWorkItemDispatcher ( PVOID  Context)

Definition at line 8924 of file rxce.c.

8926{
8927 PRX_WORK_DISPATCH_ITEM DispatchItem = Context;
8928
8929 DPRINT("Calling: %p, %p\n", DispatchItem->DispatchRoutine, DispatchItem->DispatchRoutineParameter);
8930
8931 DispatchItem->DispatchRoutine(DispatchItem->DispatchRoutineParameter);
8932
8933 RxFreePoolWithTag(DispatchItem, RX_WORKQ_POOLTAG);
8934}

Referenced by RxDispatchToWorkerThread().

Variable Documentation

◆ DumpDispatchRoutine

BOOLEAN DumpDispatchRoutine = FALSE

Definition at line 150 of file rxce.c.

Referenced by RxpWorkerThreadDispatcher().

◆ RdbssReferenceTracingValue

ULONG RdbssReferenceTracingValue = 0

Definition at line 130 of file rxce.c.

Referenced by RxPrefixTableLookupName(), RxpTrackDereference(), and RxpTrackReference().

◆ ReadAheadGranularity

ULONG ReadAheadGranularity
extern

Definition at line 534 of file rdbss.c.

Referenced by RxCreateNetRoot(), and RxReadRegistryParameters().

◆ RxContextPerFileSerializationMutex

FAST_MUTEX RxContextPerFileSerializationMutex

◆ RxContextSerialNumberCounter

volatile ULONG RxContextSerialNumberCounter

Definition at line 119 of file rxce.c.

Referenced by RxInitializeContext().

◆ RxContinueFromAssert

BOOLEAN RxContinueFromAssert = TRUE

Definition at line 137 of file rxce.c.

Referenced by RxAssert().

◆ RxDispatcher

RX_DISPATCHER RxDispatcher

◆ RxDispatcherWorkQueues

RX_WORK_QUEUE_DISPATCHER RxDispatcherWorkQueues

Definition at line 135 of file rxce.c.

Referenced by RxInitializeDispatcher().

◆ RxExplodePoolTags

ULONG RxExplodePoolTags = 1

Definition at line 138 of file rxce.c.

◆ RxLowIoPagingIoSyncMutex

FAST_MUTEX RxLowIoPagingIoSyncMutex

Definition at line 136 of file rxce.c.

Referenced by RxDriverEntry(), RxLowIoCompletionTail(), and RxLowIoSubmit().

◆ RxNull

PVOID RxNull = NULL

Definition at line 118 of file rxce.c.

Referenced by RxFsdCommonDispatch().

◆ RxNumberOfActiveFcbs

volatile LONG RxNumberOfActiveFcbs = 0

Definition at line 116 of file rxce.c.

Referenced by RxAllocateFcbObject(), and RxFreeFcbObject().

◆ RxRecurrentWorkItemsList

LIST_ENTRY RxRecurrentWorkItemsList

Definition at line 142 of file rxce.c.

Referenced by RxInitializeRxTimer().

◆ RxSpinUpDispatcherWaitInterval

LARGE_INTEGER RxSpinUpDispatcherWaitInterval

Definition at line 133 of file rxce.c.

Referenced by RxInitializeDispatcher(), and RxSpinUpRequestsDispatcher().

◆ RxSrvCallConstructionDispatcherActive

BOOLEAN RxSrvCallConstructionDispatcherActive = FALSE

Definition at line 121 of file rxce.c.

Referenced by RxCreateSrvCallCallBack(), and RxFinishSrvCallConstructionDispatcher().

◆ RxSrvCalldownList

LIST_ENTRY RxSrvCalldownList

◆ RxStopOnLoudCompletion

BOOLEAN RxStopOnLoudCompletion = TRUE

Definition at line 120 of file rxce.c.

Referenced by RxCompleteRequest().

◆ RxStrucSupSpinLock

◆ RxTimer

KTIMER RxTimer

Definition at line 144 of file rxce.c.

Referenced by RxInitializeRxTimer(), RxPostOneShotTimerRequest(), and RxTimerDispatch().

◆ RxTimerDpc

KDPC RxTimerDpc

Definition at line 143 of file rxce.c.

Referenced by RxInitializeRxTimer(), RxPostOneShotTimerRequest(), and RxTimerDispatch().

◆ RxTimerInterval

LARGE_INTEGER RxTimerInterval

Definition at line 139 of file rxce.c.

Referenced by RxInitializeRxTimer(), RxPostOneShotTimerRequest(), and RxTimerDispatch().

◆ RxTimerLock

RX_SPIN_LOCK RxTimerLock

Definition at line 140 of file rxce.c.

Referenced by RxInitializeRxTimer(), RxPostOneShotTimerRequest(), and RxTimerDispatch().

◆ RxTimerQueueHead

LIST_ENTRY RxTimerQueueHead

Definition at line 141 of file rxce.c.

Referenced by RxInitializeRxTimer(), RxPostOneShotTimerRequest(), and RxTimerDispatch().

◆ RxTimerTickCount

ULONG RxTimerTickCount

Definition at line 145 of file rxce.c.

Referenced by RxInitializeRxTimer(), RxPostOneShotTimerRequest(), and RxTimerDispatch().

◆ RxWorkQueueWaitInterval

LARGE_INTEGER RxWorkQueueWaitInterval[RxMaximumWorkQueue]

Definition at line 132 of file rxce.c.

Referenced by RxInitializeDispatcher().

◆ SerialNumber