ReactOS 0.4.15-dev-7924-g5949c20
rdbss.c File Reference
#include <rx.h>
#include <pseh/pseh2.h>
#include <limits.h>
#include <dfs.h>
#include <copysup.h>
#include <debug.h>
Include dependency graph for rdbss.c:

Go to the source code of this file.

Classes

struct  _RX_FSD_DISPATCH_VECTOR
 

Macros

#define NDEBUG
 
#define RX_TOPLEVELCTX_FLAG_FROM_POOL   1
 
#define ALLSCR_LENGTH   (sizeof(L"all.scr") - sizeof(UNICODE_NULL))
 
#define BugCheckFileId   RDBSS_BUG_CHECK_CLEANUP
 
#define BugCheckFileId   RDBSS_BUG_CHECK_CLOSE
 
#define SET_SIZE_AND_QUERY(AlreadyConsummed, Function)
 
#define _SEH2_TRY_RETURN(S)   S; goto try_exit
 
#define _SEH2_TRY_RETURN(S)   S; goto try_exit
 
#define BugCheckFileId   RDBSS_BUG_CHECK_CACHESUP
 
#define FILE_ATTRIBUTE_VOLUME   0x8
 
#define VALID_FILE_ATTRIBUTES
 
#define VALID_DIR_ATTRIBUTES   (VALID_FILE_ATTRIBUTES | FILE_ATTRIBUTE_DIRECTORY)
 

Typedefs

typedef NTSTATUS(NTAPIPRX_FSD_DISPATCH) (PRX_CONTEXT Context)
 
typedef struct _RX_FSD_DISPATCH_VECTOR RX_FSD_DISPATCH_VECTOR
 
typedef struct _RX_FSD_DISPATCH_VECTORPRX_FSD_DISPATCH_VECTOR
 

Functions

VOID NTAPI RxAcquireFileForNtCreateSection (PFILE_OBJECT FileObject)
 
NTSTATUS NTAPI RxAcquireForCcFlush (PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject)
 
VOID RxAddToTopLevelIrpAllocatedContextsList (PRX_TOPLEVELIRP_CONTEXT TopLevelContext)
 
VOID RxAssert (PVOID Assert, PVOID File, ULONG Line, PVOID Message)
 
NTSTATUS NTAPI RxCommonCleanup (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonClose (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonCreate (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonDevFCBCleanup (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonDevFCBClose (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonDevFCBFsCtl (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonDevFCBIoCtl (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonDevFCBQueryVolInfo (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonDeviceControl (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonDirectoryControl (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonDispatchProblem (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonFileSystemControl (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonFlushBuffers (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonLockControl (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonQueryEa (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonQueryInformation (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonQueryQuotaInformation (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonQuerySecurity (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonQueryVolumeInformation (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonRead (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonSetEa (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonSetInformation (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonSetQuotaInformation (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonSetSecurity (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonSetVolumeInformation (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonUnimplemented (PRX_CONTEXT Context)
 
NTSTATUS NTAPI RxCommonWrite (PRX_CONTEXT Context)
 
VOID RxCopyCreateParameters (IN PRX_CONTEXT RxContext)
 
NTSTATUS RxCreateFromNetRoot (PRX_CONTEXT Context, PUNICODE_STRING NetRootName)
 
NTSTATUS RxCreateTreeConnect (IN PRX_CONTEXT RxContext)
 
BOOLEAN NTAPI RxFastIoCheckIfPossible (PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait, ULONG LockKey, BOOLEAN CheckForReadOperation, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject)
 
BOOLEAN NTAPI RxFastIoDeviceControl (PFILE_OBJECT FileObject, BOOLEAN Wait, PVOID InputBuffer OPTIONAL, ULONG InputBufferLength, PVOID OutputBuffer OPTIONAL, ULONG OutputBufferLength, ULONG IoControlCode, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject)
 
BOOLEAN NTAPI RxFastIoRead (PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait, ULONG LockKey, PVOID Buffer, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject)
 
BOOLEAN NTAPI RxFastIoWrite (PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait, ULONG LockKey, PVOID Buffer, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject)
 
NTSTATUS RxFindOrCreateFcb (PRX_CONTEXT RxContext, PUNICODE_STRING NetRootName)
 
NTSTATUS RxFirstCanonicalize (PRX_CONTEXT RxContext, PUNICODE_STRING FileName, PUNICODE_STRING CanonicalName, PNET_ROOT_TYPE NetRootType)
 
VOID RxFreeCanonicalNameBuffer (PRX_CONTEXT Context)
 
VOID NTAPI RxFspDispatch (IN PVOID Context)
 
VOID NTAPI RxGetRegistryParameters (IN PUNICODE_STRING RegistryPath)
 
NTSTATUS NTAPI RxGetStringRegistryParameter (IN HANDLE KeyHandle, IN PCWSTR KeyName, OUT PUNICODE_STRING OutString, IN PUCHAR Buffer, IN ULONG BufferLength, IN BOOLEAN LogFailure)
 
VOID NTAPI RxInitializeDebugSupport (VOID)
 
VOID NTAPI RxInitializeDispatchVectors (PDRIVER_OBJECT DriverObject)
 
NTSTATUS NTAPI RxInitializeRegistrationStructures (VOID)
 
VOID NTAPI RxInitializeTopLevelIrpPackage (VOID)
 
VOID NTAPI RxInitUnwind (PDRIVER_OBJECT DriverObject, USHORT State)
 
BOOLEAN RxIsThisAnRdbssTopLevelContext (PRX_TOPLEVELIRP_CONTEXT TopLevelContext)
 
NTSTATUS NTAPI RxLowIoIoCtlShellCompletion (PRX_CONTEXT RxContext)
 
NTSTATUS RxLowIoReadShell (PRX_CONTEXT RxContext)
 
NTSTATUS NTAPI RxLowIoReadShellCompletion (PRX_CONTEXT RxContext)
 
NTSTATUS RxLowIoWriteShell (IN PRX_CONTEXT RxContext)
 
NTSTATUS NTAPI RxLowIoWriteShellCompletion (PRX_CONTEXT RxContext)
 
PVOID RxNewMapUserBuffer (PRX_CONTEXT RxContext)
 
NTSTATUS RxNotifyChangeDirectory (PRX_CONTEXT RxContext)
 
VOID NTAPI RxpCancelRoutine (PVOID Context)
 
NTSTATUS RxpQueryInfoMiniRdr (PRX_CONTEXT RxContext, FILE_INFORMATION_CLASS FileInfoClass, PVOID Buffer)
 
VOID RxPurgeNetFcb (PFCB Fcb, PRX_CONTEXT LocalContext)
 
NTSTATUS RxQueryAlternateNameInfo (PRX_CONTEXT RxContext, PFILE_NAME_INFORMATION AltNameInfo)
 
NTSTATUS RxQueryBasicInfo (PRX_CONTEXT RxContext, PFILE_BASIC_INFORMATION BasicInfo)
 
NTSTATUS RxQueryCompressedInfo (PRX_CONTEXT RxContext, PFILE_COMPRESSION_INFORMATION CompressionInfo)
 
NTSTATUS RxQueryDirectory (PRX_CONTEXT RxContext)
 
NTSTATUS RxQueryEaInfo (PRX_CONTEXT RxContext, PFILE_EA_INFORMATION EaInfo)
 
NTSTATUS RxQueryInternalInfo (PRX_CONTEXT RxContext, PFILE_INTERNAL_INFORMATION InternalInfo)
 
NTSTATUS RxQueryNameInfo (PRX_CONTEXT RxContext, PFILE_NAME_INFORMATION NameInfo)
 
NTSTATUS RxQueryPipeInfo (PRX_CONTEXT RxContext, PFILE_PIPE_INFORMATION PipeInfo)
 
NTSTATUS RxQueryPositionInfo (PRX_CONTEXT RxContext, PFILE_POSITION_INFORMATION PositionInfo)
 
NTSTATUS RxQueryStandardInfo (PRX_CONTEXT RxContext, PFILE_STANDARD_INFORMATION StandardInfo)
 
VOID NTAPI RxReadRegistryParameters (VOID)
 
VOID NTAPI RxReleaseFileForNtCreateSection (PFILE_OBJECT FileObject)
 
NTSTATUS NTAPI RxReleaseForCcFlush (PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject)
 
PRX_CONTEXT RxRemoveOverflowEntry (PRDBSS_DEVICE_OBJECT DeviceObject, WORK_QUEUE_TYPE Queue)
 
NTSTATUS RxSearchForCollapsibleOpen (PRX_CONTEXT RxContext, ACCESS_MASK DesiredAccess, ULONG ShareAccess)
 
NTSTATUS RxSetAllocationInfo (PRX_CONTEXT RxContext)
 
NTSTATUS RxSetBasicInfo (PRX_CONTEXT RxContext)
 
NTSTATUS RxSetDispositionInfo (PRX_CONTEXT RxContext)
 
NTSTATUS RxSetEndOfFileInfo (PRX_CONTEXT RxContext)
 
NTSTATUS RxSetPipeInfo (PRX_CONTEXT RxContext)
 
NTSTATUS RxSetPositionInfo (PRX_CONTEXT RxContext)
 
NTSTATUS RxSetRenameInfo (PRX_CONTEXT RxContext)
 
NTSTATUS RxSetSimpleInfo (PRX_CONTEXT RxContext)
 
VOID RxSetupNetFileObject (PRX_CONTEXT RxContext)
 
NTSTATUS RxSystemControl (IN PRDBSS_DEVICE_OBJECT RxDeviceObject, IN PIRP Irp)
 
VOID RxUninitializeCacheMap (PRX_CONTEXT RxContext, PFILE_OBJECT FileObject, PLARGE_INTEGER TruncateSize)
 
VOID RxUnstart (PRX_CONTEXT Context, PRDBSS_DEVICE_OBJECT DeviceObject)
 
NTSTATUS RxXXXControlFileCallthru (PRX_CONTEXT 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)
 
 DECLARE_CONST_UNICODE_STRING (unknownId, L"???")
 
VOID CheckForLoudOperations (PRX_CONTEXT RxContext)
 
VOID __RxInitializeTopLevelIrpContext (IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext, IN PIRP Irp, IN PRDBSS_DEVICE_OBJECT RxDeviceObject, IN ULONG Flags)
 
VOID __RxWriteReleaseResources (PRX_CONTEXT RxContext, BOOLEAN ResourceOwnerSet, ULONG LineNumber, PCSTR FileName, ULONG SerialNumber)
 
VOID NTAPI RxAddToWorkque (IN PRX_CONTEXT RxContext, IN PIRP Irp)
 
VOID RxAdjustFileTimesAndSize (PRX_CONTEXT RxContext)
 
NTSTATUS RxAllocateCanonicalNameBuffer (PRX_CONTEXT RxContext, PUNICODE_STRING CanonicalName, USHORT CanonicalLength)
 
VOID RxCancelNotifyChangeDirectoryRequestsForFobx (PFOBX Fobx)
 
NTSTATUS RxCancelNotifyChangeDirectoryRequestsForVNetRoot (PV_NET_ROOT VNetRoot, BOOLEAN ForceFilesClosed)
 
BOOLEAN RxCancelOperationInOverflowQueue (PRX_CONTEXT RxContext)
 
VOID NTAPI RxCancelRoutine (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS RxCanonicalizeFileNameByServerSpecs (PRX_CONTEXT RxContext, PUNICODE_STRING NetRootName)
 
NTSTATUS RxCanonicalizeNameAndObtainNetRoot (PRX_CONTEXT RxContext, PUNICODE_STRING FileName, PUNICODE_STRING NetRootName)
 
VOID NTAPI RxCheckFcbStructuresForAlignment (VOID)
 
NTSTATUS RxCheckShareAccessPerSrvOpens (IN PFCB Fcb, IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess)
 
VOID RxCleanupPipeQueues (PRX_CONTEXT Context)
 
NTSTATUS RxCloseAssociatedSrvOpen (IN PFOBX Fobx, IN PRX_CONTEXT RxContext OPTIONAL)
 
NTSTATUS RxCollapseOrCreateSrvOpen (PRX_CONTEXT RxContext)
 
NTSTATUS NTAPI RxCompleteMdl (IN PRX_CONTEXT RxContext)
 
VOID RxConjureOriginalName (PFCB Fcb, PFOBX Fobx, PULONG ActualNameLength, PWCHAR OriginalName, PLONG LengthRemaining, RX_NAME_CONJURING_METHODS NameConjuringMethod)
 
VOID NTAPI RxDebugControlCommand (_In_ PSTR ControlString)
 
NTSTATUS NTAPI RxDriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
 
NTSTATUS RxFsdCommonDispatch (PRX_FSD_DISPATCH_VECTOR DispatchVector, UCHAR MajorFunction, PIO_STACK_LOCATION Stack, PFILE_OBJECT FileObject, PIRP Irp, PRDBSS_DEVICE_OBJECT RxDeviceObject)
 
NTSTATUS NTAPI RxFsdDispatch (IN PRDBSS_DEVICE_OBJECT RxDeviceObject, IN PIRP Irp)
 
NTSTATUS RxFsdPostRequest (IN PRX_CONTEXT RxContext)
 
ULONG RxGetNetworkProviderPriority (PUNICODE_STRING DeviceName)
 
ULONG RxGetSessionId (IN PIO_STACK_LOCATION IrpSp)
 
PRDBSS_DEVICE_OBJECT RxGetTopDeviceObjectIfRdbssIrp (VOID)
 
PIRP RxGetTopIrpIfRdbssIrp (VOID)
 
LUID RxGetUid (IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext)
 
VOID NTAPI RxIndicateChangeOfBufferingStateForSrvOpen (PMRX_SRV_CALL SrvCall, PMRX_SRV_OPEN SrvOpen, PVOID SrvOpenKey, PVOID Context)
 
NTSTATUS NTAPI RxInitializeLog (VOID)
 
VOID RxInitializeMinirdrDispatchTable (IN PDRIVER_OBJECT DriverObject)
 
BOOLEAN RxIsMemberOfTopLevelIrpAllocatedContextsList (PRX_TOPLEVELIRP_CONTEXT TopLevelContext)
 
BOOLEAN RxIsOkToPurgeFcb (PFCB Fcb)
 
BOOLEAN RxIsThisTheTopLevelIrp (IN PIRP Irp)
 
NTSTATUS NTAPI RxLockOperationCompletion (IN PVOID Context, IN PIRP Irp)
 
VOID NTAPI RxLogEventDirect (IN PRDBSS_DEVICE_OBJECT DeviceObject, IN PUNICODE_STRING OriginatorId, IN ULONG EventId, IN NTSTATUS Status, IN ULONG Line)
 
VOID NTAPI RxLogEventWithAnnotation (IN PRDBSS_DEVICE_OBJECT DeviceObject, IN ULONG EventId, IN NTSTATUS Status, IN PVOID DataBuffer, IN USHORT DataBufferLength, IN PUNICODE_STRING Annotation, IN ULONG AnnotationCount)
 
NTSTATUS NTAPI RxLowIoCompletion (PRX_CONTEXT RxContext)
 
NTSTATUS RxLowIoLockControlShell (IN PRX_CONTEXT RxContext)
 
NTSTATUS NTAPI RxLowIoNotifyChangeDirectoryCompletion (PRX_CONTEXT RxContext)
 
NTSTATUS RxPostStackOverflowRead (IN PRX_CONTEXT RxContext)
 
VOID RxpPrepareCreateContextForReuse (PRX_CONTEXT RxContext)
 
NTSTATUS RxPrefixClaim (IN PRX_CONTEXT RxContext)
 
NTSTATUS NTAPI RxPrepareToReparseSymbolicLink (PRX_CONTEXT RxContext, BOOLEAN SymbolicLinkEmbeddedInOldPath, PUNICODE_STRING NewPath, BOOLEAN NewPathIsAbsolute, PBOOLEAN ReparseRequired)
 
VOID RxPrePostIrp (IN PVOID Context, IN PIRP Irp)
 
NTSTATUS RxpSetInfoMiniRdr (PRX_CONTEXT RxContext, FILE_INFORMATION_CLASS Class)
 
VOID NTAPI RxpUnregisterMinirdr (IN PRDBSS_DEVICE_OBJECT RxDeviceObject)
 
NTSTATUS NTAPI RxRegisterMinirdr (OUT PRDBSS_DEVICE_OBJECT *DeviceObject, IN OUT PDRIVER_OBJECT DriverObject, IN PMINIRDR_DISPATCH MrdrDispatch, IN ULONG Controls, IN PUNICODE_STRING DeviceName, IN ULONG DeviceExtensionSize, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics)
 
VOID RxRemoveFromTopLevelIrpAllocatedContextsList (PRX_TOPLEVELIRP_CONTEXT TopLevelContext)
 
VOID RxRemoveShareAccessPerSrvOpens (IN OUT PSRV_OPEN SrvOpen)
 
NTSTATUS NTAPI RxStartMinirdr (IN PRX_CONTEXT RxContext, OUT PBOOLEAN PostToFsp)
 
NTSTATUS NTAPI RxStopMinirdr (IN PRX_CONTEXT RxContext, OUT PBOOLEAN PostToFsp)
 
BOOLEAN RxTryToBecomeTheTopLevelIrp (IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext, IN PIRP Irp, IN PRDBSS_DEVICE_OBJECT RxDeviceObject, IN BOOLEAN ForceTopLevel)
 
VOID NTAPI RxUnload (IN PDRIVER_OBJECT DriverObject)
 
VOID NTAPI RxUnlockOperation (IN PVOID Context, IN PFILE_LOCK_INFO LockInfo)
 
VOID RxUnwindTopLevelIrp (IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext)
 
VOID RxUpdateShareAccessPerSrvOpens (IN PSRV_OPEN SrvOpen)
 

Variables

WCHAR RxStarForTemplate = '*'
 
WCHAR Rx8QMdot3QM [] = L">>>>>>>>.>>>*"
 
BOOLEAN DisableByteRangeLockingOnReadOnlyFiles = FALSE
 
BOOLEAN DisableFlushOnCleanup = FALSE
 
ULONG ReadAheadGranularity = 1 << PAGE_SHIFT
 
LIST_ENTRY RxActiveContexts
 
NPAGED_LOOKASIDE_LIST RxContextLookasideList
 
RDBSS_DATA RxData
 
FCB RxDeviceFCB
 
BOOLEAN RxLoudLowIoOpsEnabled = FALSE
 
RX_FSD_DISPATCH_VECTOR RxDeviceFCBVector [IRP_MJ_MAXIMUM_FUNCTION+1]
 
RDBSS_EXPORTS RxExports
 
FAST_IO_DISPATCH RxFastIoDispatch
 
PRDBSS_DEVICE_OBJECT RxFileSystemDeviceObject
 
RX_FSD_DISPATCH_VECTOR RxFsdDispatchVector [IRP_MJ_MAXIMUM_FUNCTION+1]
 
ULONG RxFsdEntryCount
 
LIST_ENTRY RxIrpsList
 
KSPIN_LOCK RxIrpsListSpinLock
 
KMUTEX RxScavengerMutex
 
KMUTEX RxSerializationMutex
 
UCHAR RxSpaceForTheWrappersDeviceObject [sizeof(*RxFileSystemDeviceObject)]
 
KSPIN_LOCK TopLevelIrpSpinLock
 
LIST_ENTRY TopLevelIrpAllocatedContextsList
 
BOOLEAN RxForceQFIPassThrough = FALSE
 
BOOLEAN RxNoAsync = FALSE
 

Macro Definition Documentation

◆ _SEH2_TRY_RETURN [1/2]

#define _SEH2_TRY_RETURN (   S)    S; goto try_exit

◆ _SEH2_TRY_RETURN [2/2]

#define _SEH2_TRY_RETURN (   S)    S; goto try_exit

◆ ALLSCR_LENGTH

#define ALLSCR_LENGTH   (sizeof(L"all.scr") - sizeof(UNICODE_NULL))

◆ BugCheckFileId [1/3]

#define BugCheckFileId   RDBSS_BUG_CHECK_CLEANUP

◆ BugCheckFileId [2/3]

#define BugCheckFileId   RDBSS_BUG_CHECK_CLOSE

◆ BugCheckFileId [3/3]

#define BugCheckFileId   RDBSS_BUG_CHECK_CACHESUP

◆ FILE_ATTRIBUTE_VOLUME

#define FILE_ATTRIBUTE_VOLUME   0x8

◆ NDEBUG

#define NDEBUG

Definition at line 35 of file rdbss.c.

◆ RX_TOPLEVELCTX_FLAG_FROM_POOL

#define RX_TOPLEVELCTX_FLAG_FROM_POOL   1

Definition at line 38 of file rdbss.c.

◆ SET_SIZE_AND_QUERY

#define SET_SIZE_AND_QUERY (   AlreadyConsummed,
  Function 
)
Value:
Context->Info.Length = Stack->Parameters.QueryFile.Length - (AlreadyConsummed); \
Status = Function(Context, Add2Ptr(Buffer, AlreadyConsummed))
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
Definition: bufpool.h:45
Status
Definition: gdiplustypes.h:25
#define Add2Ptr(PTR, INC)
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639

◆ VALID_DIR_ATTRIBUTES

#define VALID_DIR_ATTRIBUTES   (VALID_FILE_ATTRIBUTES | FILE_ATTRIBUTE_DIRECTORY)

◆ VALID_FILE_ATTRIBUTES

#define VALID_FILE_ATTRIBUTES
Value:
( \
#define FILE_ATTRIBUTE_DEVICE
Definition: disk.h:27
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define FILE_ATTRIBUTE_COMPRESSED
Definition: nt_native.h:711
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
#define FILE_ATTRIBUTE_OFFLINE
Definition: nt_native.h:712
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
#define FILE_ATTRIBUTE_TEMPORARY
Definition: nt_native.h:708
#define FILE_ATTRIBUTE_ENCRYPTED
Definition: ntifs_ex.h:385
#define FILE_ATTRIBUTE_SPARSE_FILE
Definition: ntifs_ex.h:380
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
Definition: ntifs_ex.h:384
#define FILE_ATTRIBUTE_VOLUME
#define FILE_ATTRIBUTE_INTEGRITY_STREAM

Typedef Documentation

◆ PRX_FSD_DISPATCH

typedef NTSTATUS(NTAPI * PRX_FSD_DISPATCH) (PRX_CONTEXT Context)

Definition at line 41 of file rdbss.c.

◆ PRX_FSD_DISPATCH_VECTOR

◆ RX_FSD_DISPATCH_VECTOR

Function Documentation

◆ __RxInitializeTopLevelIrpContext()

VOID __RxInitializeTopLevelIrpContext ( IN OUT PRX_TOPLEVELIRP_CONTEXT  TopLevelContext,
IN PIRP  Irp,
IN PRDBSS_DEVICE_OBJECT  RxDeviceObject,
IN ULONG  Flags 
)

Definition at line 674 of file rdbss.c.

679{
680 DPRINT("__RxInitializeTopLevelIrpContext(%p, %p, %p, %u)\n", TopLevelContext, Irp, RxDeviceObject, Flags);
681
682 RtlZeroMemory(TopLevelContext, sizeof(RX_TOPLEVELIRP_CONTEXT));
683 TopLevelContext->Irp = Irp;
684 TopLevelContext->Flags = (Flags ? RX_TOPLEVELCTX_FLAG_FROM_POOL : 0);
685 TopLevelContext->Signature = RX_TOPLEVELIRP_CONTEXT_SIGNATURE;
686 TopLevelContext->RxDeviceObject = RxDeviceObject;
687 TopLevelContext->Previous = IoGetTopLevelIrp();
688 TopLevelContext->Thread = PsGetCurrentThread();
689
690 /* We cannot add to list something that'd come from stack */
691 if (BooleanFlagOn(TopLevelContext->Flags, RX_TOPLEVELCTX_FLAG_FROM_POOL))
692 {
694 }
695}
_In_ PIRP Irp
Definition: csq.h:116
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
VOID RxAddToTopLevelIrpAllocatedContextsList(PRX_TOPLEVELIRP_CONTEXT TopLevelContext)
Definition: rdbss.c:752
#define RX_TOPLEVELCTX_FLAG_FROM_POOL
Definition: rdbss.c:38
#define RX_TOPLEVELIRP_CONTEXT_SIGNATURE
Definition: rxcontx.h:4
#define DPRINT
Definition: sndvol32.h:71
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by RxTryToBecomeTheTopLevelIrp().

◆ __RxWriteReleaseResources()

VOID __RxWriteReleaseResources ( PRX_CONTEXT  RxContext,
BOOLEAN  ResourceOwnerSet,
ULONG  LineNumber,
PCSTR  FileName,
ULONG  SerialNumber 
)

Definition at line 701 of file rdbss.c.

707{
709
710 PAGED_CODE();
711
712 ASSERT(RxContext != NULL);
713 ASSERT(capFcb != NULL);
714
715 /* If FCB resource was acquired, release it */
716 if (RxContext->FcbResourceAcquired)
717 {
718 /* Taking care of owner */
719 if (ResourceOwnerSet)
720 {
722 }
723 else
724 {
725 RxReleaseFcb(RxContext, capFcb);
726 }
727
728 RxContext->FcbResourceAcquired = FALSE;
729 }
730
731 /* If FCB paging resource was acquired, release it */
732 if (RxContext->FcbPagingIoResourceAcquired)
733 {
734 /* Taking care of owner */
735 if (ResourceOwnerSet)
736 {
738 }
739 else
740 {
742 }
743
744 /* No need to release boolean here, RxReleasePagingIoResource() takes care of it */
745 }
746}
#define PAGED_CODE()
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define ASSERT(a)
Definition: mode.c:44
#define capFcb
Definition: ntrxdef.h:20
#define RxCaptureFcb
Definition: ntrxdef.h:10
#define RxReleasePagingIoResource(RxContext, Fcb)
Definition: rxprocs.h:268
#define RxReleaseFcb(R, F)
Definition: rxprocs.h:186
#define RxReleasePagingIoResourceForThread(RxContext, Fcb, Thread)
Definition: rxprocs.h:276
#define RxReleaseFcbForThread(R, F, T)
Definition: rxprocs.h:205
ERESOURCE_THREAD ResourceThreadId
Definition: mrx.h:285
BOOLEAN FcbResourceAcquired
Definition: rxcontx.h:125
LOWIO_CONTEXT LowIoContext
Definition: rxcontx.h:263
BOOLEAN FcbPagingIoResourceAcquired
Definition: rxcontx.h:126

◆ _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}
#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}

◆ CheckForLoudOperations()

VOID CheckForLoudOperations ( PRX_CONTEXT  RxContext)

Definition at line 647 of file rdbss.c.

649{
651
652 PAGED_CODE();
653
654#define ALLSCR_LENGTH (sizeof(L"all.scr") - sizeof(UNICODE_NULL))
655
656 /* Are loud operations enabled? */
658 {
659 /* If so, the operation will be loud only if filename ends with all.scr */
660 if (RtlCompareMemory(Add2Ptr(capFcb->PrivateAlreadyPrefixedName.Buffer,
661 (capFcb->PrivateAlreadyPrefixedName.Length - ALLSCR_LENGTH)),
662 L"all.scr", ALLSCR_LENGTH) == ALLSCR_LENGTH)
663 {
665 }
666 }
667#undef ALLSCR_LENGTH
668}
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define LOWIO_CONTEXT_FLAG_LOUDOPS
Definition: mrx.h:322
#define L(x)
Definition: ntvdm.h:50
#define ALLSCR_LENGTH
BOOLEAN RxLoudLowIoOpsEnabled
Definition: rdbss.c:539
USHORT Flags
Definition: mrx.h:282

Referenced by RxCommonRead(), and RxCommonWrite().

◆ DECLARE_CONST_UNICODE_STRING()

DECLARE_CONST_UNICODE_STRING ( unknownId  ,
L"???"   
)

◆ RxAcquireFileForNtCreateSection()

VOID NTAPI RxAcquireFileForNtCreateSection ( PFILE_OBJECT  FileObject)

Definition at line 276 of file rxce.c.

278{
280}
#define UNIMPLEMENTED
Definition: debug.h:115

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().

◆ RxAddToTopLevelIrpAllocatedContextsList()

VOID RxAddToTopLevelIrpAllocatedContextsList ( PRX_TOPLEVELIRP_CONTEXT  TopLevelContext)

Definition at line 752 of file rdbss.c.

754{
756
757 DPRINT("RxAddToTopLevelIrpAllocatedContextsList(%p)\n", TopLevelContext);
758
761
765}
#define InsertTailList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
LIST_ENTRY TopLevelIrpAllocatedContextsList
Definition: rdbss.c:612
KSPIN_LOCK TopLevelIrpSpinLock
Definition: rdbss.c:611
LIST_ENTRY ListEntry
Definition: rxcontx.h:13
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by __RxInitializeTopLevelIrpContext().

◆ RxAddToWorkque()

VOID NTAPI RxAddToWorkque ( IN PRX_CONTEXT  RxContext,
IN PIRP  Irp 
)

Definition at line 772 of file rdbss.c.

775{
776 ULONG Queued;
779
781
782 RxContext->PostRequest = FALSE;
783
784 /* First of all, select the appropriate queue - delayed for prefix claim, critical for the rest */
785 if (RxContext->MajorFunction == IRP_MJ_DEVICE_CONTROL &&
786 capPARAMS->Parameters.DeviceIoControl.IoControlCode == IOCTL_REDIR_QUERY_PATH)
787 {
790 }
791 else
792 {
795 }
796
797 /* Check for overflow */
798 if (capPARAMS->FileObject != NULL)
799 {
801
803 /* In case of an overflow, add the new queued call to the overflow list */
804 if (Queued > 1)
805 {
807 InsertTailList(&RxFileSystemDeviceObject->OverflowQueue[Queue], &RxContext->OverflowListEntry);
809
811 return;
812 }
813
815 }
816
817 ExInitializeWorkItem(&RxContext->WorkQueueItem, RxFspDispatch, RxContext);
818 ExQueueWorkItem((PWORK_QUEUE_ITEM)&RxContext->WorkQueueItem, Queue);
819}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define IOCTL_REDIR_QUERY_PATH
#define capPARAMS
Definition: ntrxdef.h:22
#define RxCaptureParamBlock
Definition: ntrxdef.h:17
VOID NTAPI RxFspDispatch(IN PVOID Context)
Definition: rdbss.c:6571
PRDBSS_DEVICE_OBJECT RxFileSystemDeviceObject
Definition: rdbss.c:573
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
@ RX_CONTEXT_FLAG_FSP_DELAYED_OVERFLOW_QUEUE
Definition: rxcontx.h:296
@ RX_CONTEXT_FLAG_FSP_CRITICAL_OVERFLOW_QUEUE
Definition: rxcontx.h:297
LONG OverflowQueueCount[RxMaximumWorkQueue]
Definition: rxstruc.h:120
LIST_ENTRY OverflowQueue[RxMaximumWorkQueue]
Definition: rxstruc.h:121
RX_SPIN_LOCK OverflowQueueSpinLock
Definition: rxstruc.h:122
volatile LONG PostedRequestCount[RxMaximumWorkQueue]
Definition: rxstruc.h:119
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2225
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
enum _WORK_QUEUE_TYPE WORK_QUEUE_TYPE
@ DelayedWorkQueue
Definition: extypes.h:190
@ CriticalWorkQueue
Definition: extypes.h:189

Referenced by RxCommonWrite(), and RxFsdPostRequest().

◆ RxAdjustFileTimesAndSize()

VOID RxAdjustFileTimesAndSize ( PRX_CONTEXT  RxContext)

Definition at line 825 of file rdbss.c.

827{
829 LARGE_INTEGER CurrentTime;
830 FILE_BASIC_INFORMATION FileBasicInfo;
832 BOOLEAN FileModified, SetLastChange, SetLastAccess, SetLastWrite, NeedUpdate;
833
838
839 PAGED_CODE();
840
841 /* If Cc isn't initialized, the file was not read nor written, nothing to do */
842 if (capFileObject->PrivateCacheMap == NULL)
843 {
844 return;
845 }
846
847 /* Get now */
848 KeQuerySystemTime(&CurrentTime);
849
850 /* Was the file modified? */
851 FileModified = BooleanFlagOn(capFileObject->Flags, FO_FILE_MODIFIED);
852 /* We'll set last write if it was modified and user didn't update yet */
853 SetLastWrite = FileModified && !BooleanFlagOn(capFobx->Flags, FOBX_FLAG_USER_SET_LAST_WRITE);
854 /* File was accessed if: written or read (fastio), we'll update last access if user didn't */
855 SetLastAccess = SetLastWrite ||
858 /* We'll set last change if it was modified and user didn't update yet */
859 SetLastChange = FileModified && !BooleanFlagOn(capFobx->Flags, FOBX_FLAG_USER_SET_LAST_CHANGE);
860
861 /* Nothing to update? Job done */
862 if (!FileModified && !SetLastWrite && !SetLastAccess && !SetLastChange)
863 {
864 return;
865 }
866
867 /* By default, we won't issue any MRxSetFileInfoAtCleanup call */
868 NeedUpdate = FALSE;
869 RtlZeroMemory(&FileBasicInfo, sizeof(FileBasicInfo));
870
871 /* Update lastwrite time if required */
872 if (SetLastWrite)
873 {
874 NeedUpdate = TRUE;
875 capFcb->LastWriteTime.QuadPart = CurrentTime.QuadPart;
876 FileBasicInfo.LastWriteTime.QuadPart = CurrentTime.QuadPart;
877 }
878
879 /* Update lastaccess time if required */
880 if (SetLastAccess)
881 {
882 NeedUpdate = TRUE;
883 capFcb->LastAccessTime.QuadPart = CurrentTime.QuadPart;
884 FileBasicInfo.LastAccessTime.QuadPart = CurrentTime.QuadPart;
885 }
886
887 /* Update lastchange time if required */
888 if (SetLastChange)
889 {
890 NeedUpdate = TRUE;
891 capFcb->LastChangeTime.QuadPart = CurrentTime.QuadPart;
892 FileBasicInfo.ChangeTime.QuadPart = CurrentTime.QuadPart;
893 }
894
895 /* If one of the date was modified, issue a call to mini-rdr */
896 if (NeedUpdate)
897 {
898 RxContext->Info.FileInformationClass = FileBasicInformation;
899 RxContext->Info.Buffer = &FileBasicInfo;
900 RxContext->Info.Length = sizeof(FileBasicInfo);
901
902 MINIRDR_CALL(Status, RxContext, capFcb->MRxDispatch, MRxSetFileInfoAtCleanup, (RxContext));
903 (void)Status;
904 }
905
906 /* If the file was modified, update its EOF */
907 if (FileModified)
908 {
909 FileEOFInfo.EndOfFile.QuadPart = capFcb->Header.FileSize.QuadPart;
910
911 RxContext->Info.FileInformationClass = FileEndOfFileInformation;
912 RxContext->Info.Buffer = &FileEOFInfo;
913 RxContext->Info.Length = sizeof(FileEOFInfo);
914
915 MINIRDR_CALL(Status, RxContext, capFcb->MRxDispatch, MRxSetFileInfoAtCleanup, (RxContext));
916 (void)Status;
917 }
918}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define TRUE
Definition: types.h:120
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define FOBX_FLAG_USER_SET_LAST_CHANGE
Definition: fcb.h:294
#define FOBX_FLAG_USER_SET_LAST_WRITE
Definition: fcb.h:291
#define FOBX_FLAG_USER_SET_LAST_ACCESS
Definition: fcb.h:292
@ FileEndOfFileInformation
Definition: from_kernel.h:81
@ FileBasicInformation
Definition: from_kernel.h:65
#define capFileObject
Definition: ntrxdef.h:23
#define capFobx
Definition: ntrxdef.h:21
#define RxCaptureFileObject
Definition: ntrxdef.h:18
#define RxCaptureFobx
Definition: ntrxdef.h:11
#define MINIRDR_CALL(STATUS, CONTEXT, DISPATCH, FUNC, ARGLIST)
Definition: rxcontx.h:389
LARGE_INTEGER LastWriteTime
Definition: nt_native.h:941
LARGE_INTEGER ChangeTime
Definition: nt_native.h:942
LARGE_INTEGER LastAccessTime
Definition: nt_native.h:940
struct _RX_CONTEXT::@2146::@2154 Info
LONGLONG QuadPart
Definition: typedefs.h:114
#define FO_FILE_FAST_IO_READ
Definition: iotypes.h:1795
#define FO_FILE_MODIFIED
Definition: iotypes.h:1788

Referenced by RxCommonCleanup().

◆ RxAllocateCanonicalNameBuffer()

NTSTATUS RxAllocateCanonicalNameBuffer ( PRX_CONTEXT  RxContext,
PUNICODE_STRING  CanonicalName,
USHORT  CanonicalLength 
)

Definition at line 924 of file rdbss.c.

928{
929 PAGED_CODE();
930
931 DPRINT("RxContext: %p - CanonicalNameBuffer: %p\n", RxContext, RxContext->Create.CanonicalNameBuffer);
932
933 /* Context must be free of any already allocated name */
934 ASSERT(RxContext->Create.CanonicalNameBuffer == NULL);
935
936 /* Validate string length */
937 if (CanonicalLength > USHRT_MAX - 1)
938 {
939 CanonicalName->Buffer = NULL;
941 }
942
943 CanonicalName->Buffer = RxAllocatePoolWithTag(PagedPool | POOL_COLD_ALLOCATION, CanonicalLength, RX_MISC_POOLTAG);
944 if (CanonicalName->Buffer == NULL)
945 {
947 }
948
949 CanonicalName->Length = 0;
950 CanonicalName->MaximumLength = CanonicalLength;
951
952 /* Set the two places - they must always be identical */
953 RxContext->Create.CanonicalNameBuffer = CanonicalName->Buffer;
954 RxContext->AlsoCanonicalNameBuffer = CanonicalName->Buffer;
955
956 return STATUS_SUCCESS;
957}
#define PagedPool
Definition: env_spec_w32.h:308
#define USHRT_MAX
Definition: limits.h:38
#define RxAllocatePoolWithTag
Definition: ntrxdef.h:25
#define STATUS_OBJECT_PATH_INVALID
Definition: ntstatus.h:293
#define RX_MISC_POOLTAG
Definition: rxpooltg.h:10
#define STATUS_SUCCESS
Definition: shellext.h:65
PWCH AlsoCanonicalNameBuffer
Definition: rxcontx.h:267
struct _RX_CONTEXT::@2148::@2160 Create
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define POOL_COLD_ALLOCATION

Referenced by RxFirstCanonicalize().

◆ 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}
Definition: File.h:16
#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:79
Definition: ncftp.h:89
char CHAR
Definition: xmlstorage.h:175

◆ RxCancelNotifyChangeDirectoryRequestsForFobx()

VOID RxCancelNotifyChangeDirectoryRequestsForFobx ( PFOBX  Fobx)

Definition at line 963 of file rdbss.c.

965{
969 LIST_ENTRY ContextsToCancel;
970
971 /* Init a list for the contexts to cancel */
972 InitializeListHead(&ContextsToCancel);
973
974 /* Lock our list lock */
976
977 /* Now, browse all the active contexts, to find the associated ones */
979 while (Entry != &RxActiveContexts)
980 {
981 Context = CONTAINING_RECORD(Entry, RX_CONTEXT, ContextListEntry);
982 Entry = Entry->Flink;
983
984 /* Not the IRP we're looking for, ignore */
985 if (Context->MajorFunction != IRP_MJ_DIRECTORY_CONTROL ||
986 Context->MinorFunction != IRP_MN_NOTIFY_CHANGE_DIRECTORY)
987 {
988 continue;
989 }
990
991 /* Not the FOBX we're looking for, ignore */
992 if ((PFOBX)Context->pFobx != Fobx)
993 {
994 continue;
995 }
996
997 /* No cancel routine (can't be cancel, then), ignore */
998 if (Context->MRxCancelRoutine == NULL)
999 {
1000 continue;
1001 }
1002
1003 /* Mark our context as cancelled */
1005
1006 /* Move it to our list */
1007 RemoveEntryList(&Context->ContextListEntry);
1008 InsertTailList(&ContextsToCancel, &Context->ContextListEntry);
1009
1010 InterlockedIncrement((volatile long *)&Context->ReferenceCount);
1011 }
1012
1013 /* Done with the contexts */
1015
1016 /* Now, handle all our "extracted" contexts */
1017 while (!IsListEmpty(&ContextsToCancel))
1018 {
1019 Entry = RemoveHeadList(&ContextsToCancel);
1020 Context = CONTAINING_RECORD(Entry, RX_CONTEXT, ContextListEntry);
1021
1022 /* If they had an associated IRP (should be always true) */
1023 if (Context->CurrentIrp != NULL)
1024 {
1025 /* Then, call cancel routine */
1026 ASSERT(Context->MRxCancelRoutine != NULL);
1027 DPRINT1("Canceling %p with %p\n", Context, Context->MRxCancelRoutine);
1028 Context->MRxCancelRoutine(Context);
1029 }
1030
1031 /* And delete the context */
1033 }
1034}
#define DPRINT1
Definition: precomp.h:8
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
LIST_ENTRY RxActiveContexts
Definition: rdbss.c:535
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY
Definition: rdpdr.c:56
@ RX_CONTEXT_FLAG_CANCELLED
Definition: rxcontx.h:300
#define RxDereferenceAndDeleteRxContext(RXCONTEXT)
Definition: rxcontx.h:514
RX_SPIN_LOCK RxStrucSupSpinLock
Definition: rxce.c:123
base of all file and directory entries
Definition: entries.h:83
Definition: fcb.h:305
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by RxCommonCleanup().

◆ RxCancelNotifyChangeDirectoryRequestsForVNetRoot()

NTSTATUS RxCancelNotifyChangeDirectoryRequestsForVNetRoot ( PV_NET_ROOT  VNetRoot,
BOOLEAN  ForceFilesClosed 
)

Definition at line 1040 of file rdbss.c.

1043{
1044 KIRQL OldIrql;
1048 LIST_ENTRY ContextsToCancel;
1049
1050 /* Init a list for the contexts to cancel */
1051 InitializeListHead(&ContextsToCancel);
1052
1053 /* Lock our list lock */
1055
1056 /* Assume success */
1058
1059 /* Now, browse all the active contexts, to find the associated ones */
1061 while (Entry != &RxActiveContexts)
1062 {
1063 Context = CONTAINING_RECORD(Entry, RX_CONTEXT, ContextListEntry);
1064 Entry = Entry->Flink;
1065
1066 /* Not the IRP we're looking for, ignore */
1067 if (Context->MajorFunction != IRP_MJ_DIRECTORY_CONTROL ||
1068 Context->MinorFunction != IRP_MN_NOTIFY_CHANGE_DIRECTORY)
1069 {
1070 continue;
1071 }
1072
1073 /* Not the VNetRoot we're looking for, ignore */
1074 if (Context->pFcb == NULL ||
1075 (PV_NET_ROOT)Context->NotifyChangeDirectory.pVNetRoot != VNetRoot)
1076 {
1077 continue;
1078 }
1079
1080 /* No cancel routine (can't be cancel, then), ignore */
1081 if (Context->MRxCancelRoutine == NULL)
1082 {
1083 continue;
1084 }
1085
1086 /* At that point, we found a matching context
1087 * If we're not asked to force close, then fail - it's still open
1088 */
1089 if (!ForceFilesClosed)
1090 {
1092 break;
1093 }
1094
1095 /* Mark our context as cancelled */
1097
1098 /* Move it to our list */
1099 RemoveEntryList(&Context->ContextListEntry);
1100 InsertTailList(&ContextsToCancel, &Context->ContextListEntry);
1101
1102 InterlockedIncrement((volatile long *)&Context->ReferenceCount);
1103 }
1104
1105 /* Done with the contexts */
1107
1108 if (Status != STATUS_SUCCESS)
1109 {
1110 return Status;
1111 }
1112
1113 /* Now, handle all our "extracted" contexts */
1114 while (!IsListEmpty(&ContextsToCancel))
1115 {
1116 Entry = RemoveHeadList(&ContextsToCancel);
1117 Context = CONTAINING_RECORD(Entry, RX_CONTEXT, ContextListEntry);
1118
1119 /* If they had an associated IRP (should be always true) */
1120 if (Context->CurrentIrp != NULL)
1121 {
1122 /* Then, call cancel routine */
1123 ASSERT(Context->MRxCancelRoutine != NULL);
1124 DPRINT1("Canceling %p with %p\n", Context, Context->MRxCancelRoutine);
1125 Context->MRxCancelRoutine(Context);
1126 }
1127
1128 /* And delete the context */
1130 }
1131
1132 return Status;
1133}
#define STATUS_FILES_OPEN
Definition: ntstatus.h:499

Referenced by RxFinalizeConnection().

◆ RxCancelOperationInOverflowQueue()

BOOLEAN RxCancelOperationInOverflowQueue ( PRX_CONTEXT  RxContext)

Definition at line 1139 of file rdbss.c.

1141{
1142 KIRQL OldIrql;
1143 BOOLEAN OperationToCancel;
1144
1145 /* By default, nothing cancelled */
1146 OperationToCancel = FALSE;
1147
1148 /* Acquire the overflow spinlock */
1150
1151 /* Is our context in any queue? */
1153 {
1154 /* Make sure flag is consistent with facts... */
1155 if (RxContext->OverflowListEntry.Flink != NULL)
1156 {
1157 /* Remove it from the list */
1159 RxContext->OverflowListEntry.Flink = NULL;
1160
1161 /* Decrement appropriate count */
1163 {
1165 }
1166 else
1167 {
1169 }
1170
1171 /* Clear the flag */
1173
1174 /* Time to cancel! */
1175 OperationToCancel = TRUE;
1176 }
1177 }
1178
1180
1181 /* We have something to cancel & complete */
1182 if (OperationToCancel)
1183 {
1186 }
1187
1188 return OperationToCancel;
1189}
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
VOID RxRemoveOperationFromBlockingQueue(_Inout_ PRX_CONTEXT RxContext)
NTSTATUS RxCompleteRequest(_In_ PRX_CONTEXT pContext, _In_ NTSTATUS Status)
LIST_ENTRY OverflowListEntry
Definition: rxcontx.h:150
ULONG Flags
Definition: rxcontx.h:124
#define STATUS_CANCELLED
Definition: udferr_usr.h:170

Referenced by RxpCancelRoutine().

◆ RxCancelRoutine()

VOID NTAPI RxCancelRoutine ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 1196 of file rdbss.c.

1199{
1200 KIRQL OldIrql;
1202 PRX_CONTEXT RxContext;
1203
1204 /* Lock our contexts list */
1206
1207 /* Now, find a context that matches the cancelled IRP */
1209 while (Entry != &RxActiveContexts)
1210 {
1211 RxContext = CONTAINING_RECORD(Entry, RX_CONTEXT, ContextListEntry);
1212 Entry = Entry->Flink;
1213
1214 /* Found! */
1215 if (RxContext->CurrentIrp == Irp)
1216 {
1217 break;
1218 }
1219 }
1220
1221 /* If we reached the end of the list, we didn't find any context, so zero the buffer
1222 * If the context is already under cancellation, forget about it too
1223 */
1225 {
1226 RxContext = NULL;
1227 }
1228 else
1229 {
1230 /* Otherwise, reference it and mark it cancelled */
1232 InterlockedIncrement((volatile long *)&RxContext->ReferenceCount);
1233 }
1234
1235 /* Done with the contexts list */
1237
1238 /* And done with the cancellation, we'll do it now */
1239 IoReleaseCancelSpinLock(Irp->CancelIrql);
1240
1241 /* If we have a context to cancel */
1242 if (RxContext != NULL)
1243 {
1244 /* We cannot executed at dispatch, so queue a deferred cancel */
1246 {
1248 }
1249 /* Cancel now! */
1250 else
1251 {
1252 RxpCancelRoutine(RxContext);
1253 }
1254 }
1255}
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
VOID NTAPI RxpCancelRoutine(PVOID Context)
Definition: rdbss.c:7616
NTSTATUS NTAPI RxDispatchToWorkerThread(_In_ PRDBSS_DEVICE_OBJECT pMRxDeviceObject, _In_ WORK_QUEUE_TYPE WorkQueueType, _In_ PRX_WORKERTHREAD_ROUTINE Routine, _In_ PVOID pContext)
PIRP CurrentIrp
Definition: rxcontx.h:110
volatile ULONG ReferenceCount
Definition: rxcontx.h:103

Referenced by RxFsdCommonDispatch().

◆ RxCanonicalizeFileNameByServerSpecs()

NTSTATUS RxCanonicalizeFileNameByServerSpecs ( PRX_CONTEXT  RxContext,
PUNICODE_STRING  NetRootName 
)

Definition at line 1261 of file rdbss.c.

1264{
1265 USHORT NextChar, CurChar;
1266 USHORT MaxChars;
1267
1268 PAGED_CODE();
1269
1270 /* Validate file name is not empty */
1271 MaxChars = NetRootName->Length / sizeof(WCHAR);
1272 if (MaxChars == 0)
1273 {
1275 }
1276
1277 /* Validate name is correct */
1278 for (NextChar = 0, CurChar = 0; CurChar + 1 < MaxChars; NextChar = CurChar + 1)
1279 {
1280 USHORT i;
1281
1282 for (i = NextChar + 1; i < MaxChars; ++i)
1283 {
1284 if (NetRootName->Buffer[i] == '\\' || NetRootName->Buffer[i] == ':')
1285 {
1286 break;
1287 }
1288 }
1289
1290 CurChar = i - 1;
1291 if (CurChar == NextChar)
1292 {
1293 if (((NetRootName->Buffer[NextChar] != '\\' && NetRootName->Buffer[NextChar] != ':') || NextChar == (MaxChars - 1)) && NetRootName->Buffer[NextChar] != '.')
1294 {
1295 continue;
1296 }
1297
1298 if (CurChar != 0)
1299 {
1300 if (CurChar >= MaxChars - 1)
1301 {
1302 continue;
1303 }
1304
1305 if (NetRootName->Buffer[CurChar + 1] != ':')
1306 {
1308 }
1309 }
1310 else
1311 {
1312 if (NetRootName->Buffer[1] != ':')
1313 {
1315 }
1316 }
1317 }
1318 else
1319 {
1320 if ((CurChar - NextChar) == 1)
1321 {
1322 if (NetRootName->Buffer[NextChar + 2] != '.')
1323 {
1324 continue;
1325 }
1326
1327 if (NetRootName->Buffer[NextChar] == '\\' || NetRootName->Buffer[NextChar] == ':' || NetRootName->Buffer[NextChar] == '.')
1328 {
1330 }
1331 }
1332 else
1333 {
1334 if ((CurChar - NextChar) != 2 || (NetRootName->Buffer[NextChar] != '\\' && NetRootName->Buffer[NextChar] != ':')
1335 || NetRootName->Buffer[NextChar + 1] != '.')
1336 {
1337 continue;
1338 }
1339
1340 if (NetRootName->Buffer[NextChar + 2] == '.')
1341 {
1343 }
1344 }
1345 }
1346 }
1347
1349}
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 STATUS_OBJECT_PATH_SYNTAX_BAD
Definition: ntstatus.h:295
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by RxCanonicalizeNameAndObtainNetRoot().

◆ RxCanonicalizeNameAndObtainNetRoot()

NTSTATUS RxCanonicalizeNameAndObtainNetRoot ( PRX_CONTEXT  RxContext,
PUNICODE_STRING  FileName,
PUNICODE_STRING  NetRootName 
)

Definition at line 1352 of file rdbss.c.

1356{
1358 NET_ROOT_TYPE NetRootType;
1359 UNICODE_STRING CanonicalName;
1360
1363
1364 PAGED_CODE();
1365
1366 NetRootType = NET_ROOT_WILD;
1367
1368 RtlInitEmptyUnicodeString(NetRootName, NULL, 0);
1369 RtlInitEmptyUnicodeString(&CanonicalName, NULL, 0);
1370
1371 /* if not relative opening, just handle the passed name */
1372 if (capFileObject->RelatedFileObject == NULL)
1373 {
1374 Status = RxFirstCanonicalize(RxContext, FileName, &CanonicalName, &NetRootType);
1375 if (!NT_SUCCESS(Status))
1376 {
1377 return Status;
1378 }
1379 }
1380 else
1381 {
1382 PFCB Fcb;
1383
1384 /* Make sure we have a valid FCB and a FOBX */
1385 Fcb = capFileObject->RelatedFileObject->FsContext;
1386 if (Fcb == NULL || capFileObject->RelatedFileObject->FsContext2 == NULL)
1387 {
1389 }
1390
1391 if (!NodeTypeIsFcb(Fcb))
1392 {
1394 }
1395
1397 }
1398
1399 /* Get/Create the associated VNetRoot for opening */
1400 Status = RxFindOrConstructVirtualNetRoot(RxContext, &CanonicalName, NetRootType, NetRootName);
1401 if (!NT_SUCCESS(Status) && Status != STATUS_PENDING &&
1403 {
1404 ASSERT(CanonicalName.Buffer == RxContext->Create.CanonicalNameBuffer);
1405
1406 RxFreeCanonicalNameBuffer(RxContext);
1407 Status = RxFirstCanonicalize(RxContext, FileName, &CanonicalName, &NetRootType);
1408 if (NT_SUCCESS(Status))
1409 {
1410 Status = RxFindOrConstructVirtualNetRoot(RxContext, &CanonicalName, NetRootType, NetRootName);
1411 }
1412 }
1413
1414 /* Filename cannot contain wildcards */
1415 if (FsRtlDoesNameContainWildCards(NetRootName))
1416 {
1418 }
1419
1420 /* Make sure file name is correct */
1421 if (NT_SUCCESS(Status))
1422 {
1423 Status = RxCanonicalizeFileNameByServerSpecs(RxContext, NetRootName);
1424 }
1425
1426 /* Give the mini-redirector a chance to prepare the name */
1428 {
1429 if (RxContext->Create.pNetRoot != NULL)
1430 {
1431 NTSTATUS IgnoredStatus;
1432
1433 MINIRDR_CALL(IgnoredStatus, RxContext, RxContext->Create.pNetRoot->pSrvCall->RxDeviceObject->Dispatch,
1434 MRxPreparseName, (RxContext, NetRootName));
1435 (void)IgnoredStatus;
1436 }
1437 }
1438
1439 return Status;
1440}
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define NET_ROOT_WILD
Definition: mrxfcb.h:33
UCHAR NET_ROOT_TYPE
Definition: mrxfcb.h:36
BOOLEAN NTAPI FsRtlDoesNameContainWildCards(IN PUNICODE_STRING Name)
Definition: name.c:464
#define STATUS_PENDING
Definition: ntstatus.h:82
VOID RxFreeCanonicalNameBuffer(PRX_CONTEXT Context)
Definition: rdbss.c:6159
NTSTATUS RxCanonicalizeFileNameByServerSpecs(PRX_CONTEXT RxContext, PUNICODE_STRING NetRootName)
Definition: rdbss.c:1261
NTSTATUS RxFirstCanonicalize(PRX_CONTEXT RxContext, PUNICODE_STRING FileName, PUNICODE_STRING CanonicalName, PNET_ROOT_TYPE NetRootType)
Definition: rdbss.c:6010
@ RX_CONTEXT_FLAG_MAILSLOT_REPARSE
Definition: rxcontx.h:292
NTSTATUS RxFindOrConstructVirtualNetRoot(_In_ PRX_CONTEXT RxContext, _In_ PUNICODE_STRING CanonicalName, _In_ NET_ROOT_TYPE NetRootType, _In_ PUNICODE_STRING RemainingName)
#define NodeTypeIsFcb(FCB)
Definition: nodetype.h:68
Definition: cdstruc.h:902
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148

Referenced by RxCommonCreate().

◆ RxCheckFcbStructuresForAlignment()

VOID NTAPI RxCheckFcbStructuresForAlignment ( VOID  )

Definition at line 1447 of file rdbss.c.

1449{
1450 PAGED_CODE();
1451}

Referenced by RxDriverEntry().

◆ RxCheckShareAccessPerSrvOpens()

NTSTATUS RxCheckShareAccessPerSrvOpens ( IN PFCB  Fcb,
IN ACCESS_MASK  DesiredAccess,
IN ULONG  DesiredShareAccess 
)

Definition at line 1477 of file rdbss.c.

1481{
1484 BOOLEAN DeleteAccess;
1486
1487 PAGED_CODE();
1488
1490
1491 RxDumpWantedAccess("RxCheckShareAccessPerSrvOpens", "", "RxCheckShareAccessPerSrvOpens", DesiredAccess, DesiredShareAccess);
1492 RxDumpCurrentAccess("RxCheckShareAccessPerSrvOpens", "", "RxCheckShareAccessPerSrvOpens", ShareAccess);
1493
1494 /* Check if any access wanted */
1497 DeleteAccess = (DesiredAccess & DELETE) != 0;
1498
1499 if (ReadAccess || WriteAccess || DeleteAccess)
1500 {
1501 BOOLEAN SharedRead = (DesiredShareAccess & FILE_SHARE_READ) != 0;
1502 BOOLEAN SharedWrite = (DesiredShareAccess & FILE_SHARE_WRITE) != 0;
1503 BOOLEAN SharedDelete = (DesiredShareAccess & FILE_SHARE_DELETE) != 0;
1504
1505 /* Check whether there's a violation */
1506 if ((ReadAccess &&
1507 (ShareAccess->SharedRead < ShareAccess->OpenCount)) ||
1508 (WriteAccess &&
1509 (ShareAccess->SharedWrite < ShareAccess->OpenCount)) ||
1510 (DeleteAccess &&
1511 (ShareAccess->SharedDelete < ShareAccess->OpenCount)) ||
1512 ((ShareAccess->Readers != 0) && !SharedRead) ||
1513 ((ShareAccess->Writers != 0) && !SharedWrite) ||
1514 ((ShareAccess->Deleters != 0) && !SharedDelete))
1515 {
1517 }
1518 }
1519
1520 return STATUS_SUCCESS;
1521}
#define FILE_SHARE_READ
Definition: compat.h:136
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK _In_ USHORT ShareAccess
Definition: create.c:4147
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define FILE_READ_DATA
Definition: nt_native.h:628
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FILE_EXECUTE
Definition: nt_native.h:642
#define FILE_APPEND_DATA
Definition: nt_native.h:634
#define DELETE
Definition: nt_native.h:57
#define RxDumpWantedAccess(w1, w2, wlt, DA, DSA)
Definition: rxprocs.h:526
#define RxDumpCurrentAccess(w1, w2, wlt, SA)
Definition: rxprocs.h:527
SHARE_ACCESS ShareAccessPerSrvOpens
Definition: fcb.h:155
#define STATUS_SHARING_VIOLATION
Definition: udferr_usr.h:154
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_In_ ULONG DesiredShareAccess
Definition: iofuncs.h:781
@ ReadAccess
Definition: iotypes.h:424
@ WriteAccess
Definition: iotypes.h:425

Referenced by RxSearchForCollapsibleOpen().

◆ RxCleanupPipeQueues()

VOID RxCleanupPipeQueues ( PRX_CONTEXT  Context)

Definition at line 1524 of file rdbss.c.

1526{
1528}

Referenced by RxCommonCleanup().

◆ RxCloseAssociatedSrvOpen()

NTSTATUS RxCloseAssociatedSrvOpen ( IN PFOBX  Fobx,
IN PRX_CONTEXT RxContext  OPTIONAL 
)

Definition at line 1534 of file rdbss.c.

1537{
1538 PFCB Fcb;
1540 PSRV_OPEN SrvOpen;
1541 BOOLEAN CloseSrvOpen;
1542 PRX_CONTEXT LocalContext;
1543
1544 PAGED_CODE();
1545
1546 /* Assume SRV_OPEN is already closed */
1547 CloseSrvOpen = FALSE;
1548 /* If we have a FOBX, we'll have to close it */
1549 if (Fobx != NULL)
1550 {
1551 /* If the FOBX isn't closed yet */
1552 if (!BooleanFlagOn(Fobx->Flags, FOBX_FLAG_SRVOPEN_CLOSED))
1553 {
1554 SrvOpen = Fobx->SrvOpen;
1555 Fcb = (PFCB)SrvOpen->pFcb;
1556 /* Check whether we've to close SRV_OPEN first */
1557 if (!BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_CLOSED))
1558 {
1559 CloseSrvOpen = TRUE;
1560 }
1561 else
1562 {
1564
1565 /* Not much to do */
1566 SetFlag(Fobx->Flags, FOBX_FLAG_SRVOPEN_CLOSED);
1567
1568 if (SrvOpen->OpenCount > 0)
1569 {
1570 --SrvOpen->OpenCount;
1571 }
1572 }
1573 }
1574
1575 /* No need to close SRV_OPEN, so close FOBX */
1576 if (!CloseSrvOpen)
1577 {
1578 RxMarkFobxOnClose(Fobx);
1579
1580 return STATUS_SUCCESS;
1581 }
1582 }
1583 else
1584 {
1585 /* No FOBX? No RX_CONTEXT, ok, job done! */
1586 if (RxContext == NULL)
1587 {
1588 return STATUS_SUCCESS;
1589 }
1590
1591 /* Get the FCB from RX_CONTEXT */
1592 Fcb = (PFCB)RxContext->pFcb;
1593 SrvOpen = NULL;
1594 }
1595
1596 /* If we don't have RX_CONTEXT, allocte one, we'll need it */
1597 if (RxContext == NULL)
1598 {
1599 ASSERT(Fobx != NULL);
1600
1602 if (LocalContext == NULL)
1603 {
1605 }
1606
1607 LocalContext->MajorFunction = 2;
1608 LocalContext->pFcb = RX_GET_MRX_FCB(Fcb);
1609 LocalContext->pFobx = (PMRX_FOBX)Fobx;
1610 LocalContext->pRelevantSrvOpen = (PMRX_SRV_OPEN)Fobx->SrvOpen;
1611 }
1612 else
1613 {
1614 LocalContext = RxContext;
1615 }
1616
1618
1619 /* Now, close the FOBX */
1620 if (Fobx != NULL)
1621 {
1622 RxMarkFobxOnClose(Fobx);
1623 }
1624 else
1625 {
1626 InterlockedDecrement((volatile long *)&Fcb->OpenCount);
1627 }
1628
1629 /* If not a "standard" file, SRV_OPEN can be null */
1630 if (SrvOpen == NULL)
1631 {
1634
1635 if (LocalContext != RxContext)
1636 {
1637 RxDereferenceAndDeleteRxContext(LocalContext);
1638 }
1639
1640 return STATUS_SUCCESS;
1641 }
1642
1643 /* If SRV_OPEN isn't in a good condition, nothing to close */
1644 if (SrvOpen->Condition != Condition_Good)
1645 {
1646 if (LocalContext != RxContext)
1647 {
1648 RxDereferenceAndDeleteRxContext(LocalContext);
1649 }
1650
1651 return STATUS_SUCCESS;
1652 }
1653
1654 /* Decrease open count */
1655 if (SrvOpen->OpenCount > 0)
1656 {
1657 --SrvOpen->OpenCount;
1658 }
1659
1660 /* If we're the only one left, is there a FOBX handled by Scavenger? */
1661 if (SrvOpen->OpenCount == 1)
1662 {
1663 if (!IsListEmpty(&SrvOpen->FobxList))
1664 {
1665 if (!IsListEmpty(&CONTAINING_RECORD(SrvOpen->FobxList.Flink, FOBX, FobxQLinks)->ScavengerFinalizationList))
1666 {
1667 SetFlag(SrvOpen->Flags, SRVOPEN_FLAG_CLOSE_DELAYED);
1668 }
1669 }
1670 }
1671
1672 /* Nothing left, purge FCB */
1673 if (SrvOpen->OpenCount == 0 && RxContext == NULL)
1674 {
1675 RxPurgeNetFcb(Fcb, LocalContext);
1676 }
1677
1678 /* Already closed? Job done! */
1679 SrvOpen = Fobx->SrvOpen;
1680 if (SrvOpen == NULL ||
1681 (SrvOpen->OpenCount != 0 && !BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_BUFFERING_STATE_CHANGE_PENDING)) ||
1682 BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_CLOSED))
1683 {
1684 SetFlag(Fobx->Flags, FOBX_FLAG_SRVOPEN_CLOSED);
1685 if (LocalContext != RxContext)
1686 {
1687 RxDereferenceAndDeleteRxContext(LocalContext);
1688 }
1689
1690 return STATUS_SUCCESS;
1691 }
1692
1694
1695 /* Inform mini-rdr about closing */
1696 MINIRDR_CALL(Status, LocalContext, Fcb->MRxDispatch, MRxCloseSrvOpen, (LocalContext));
1697 DPRINT("MRxCloseSrvOpen returned: %lx, called with RX_CONTEXT %p for FOBX %p (FCB %p, SRV_OPEN %p)\n ",
1698 Status, RxContext, Fobx, Fcb, SrvOpen);
1699
1700 /* And mark as such */
1701 SetFlag(SrvOpen->Flags, SRVOPEN_FLAG_CLOSED);
1702 SrvOpen->Key = (PVOID)-1;
1703
1704 /* If we were delayed, we're not! */
1705 if (BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_CLOSE_DELAYED))
1706 {
1707 InterlockedDecrement(&((PSRV_CALL)Fcb->pNetRoot->pSrvCall)->NumberOfCloseDelayedFiles);
1708 }
1709
1710 /* Clear access */
1713
1714 /* Dereference */
1716
1717 /* Mark the FOBX closed as well */
1718 SetFlag(Fobx->Flags, FOBX_FLAG_SRVOPEN_CLOSED);
1719
1720 if (LocalContext != RxContext)
1721 {
1722 RxDereferenceAndDeleteRxContext(LocalContext);
1723 }
1724
1725 return Status;
1726}
VOID RxPurgeChangeBufferingStateRequestsForSrvOpen(_In_ PSRV_OPEN SrvOpen)
FCB * PFCB
Definition: cdstruc.h:1040
#define NodeType(P)
Definition: nodetype.h:51
#define RxDereferenceSrvOpen(SrvOpen, LockHoldingState)
Definition: fcb.h:427
#define RxDereferenceNetFcb(Fcb)
Definition: fcb.h:435
#define FOBX_FLAG_SRVOPEN_CLOSED
Definition: fcb.h:296
if(dx< 0)
Definition: linetemp.h:194
@ Condition_Good
Definition: mrx.h:76
struct _MRX_SRV_OPEN_ * PMRX_SRV_OPEN
struct _MRX_FOBX_ * PMRX_FOBX
#define SRVOPEN_FLAG_BUFFERING_STATE_CHANGE_PENDING
Definition: mrxfcb.h:136
#define SRVOPEN_FLAG_CLOSED
Definition: mrxfcb.h:132
#define SRVOPEN_FLAG_CLOSE_DELAYED
Definition: mrxfcb.h:133
VOID RxRemoveShareAccessPerSrvOpens(IN OUT PSRV_OPEN SrvOpen)
Definition: rdbss.c:8635
VOID RxPurgeNetFcb(PFCB Fcb, PRX_CONTEXT LocalContext)
Definition: rdbss.c:7995
@ RX_CONTEXT_FLAG_MUST_SUCCEED_NONBLOCKING
Definition: rxcontx.h:309
@ RX_CONTEXT_FLAG_WAIT
Definition: rxcontx.h:282
PRX_CONTEXT NTAPI RxCreateRxContext(_In_ PIRP Irp, _In_ PRDBSS_DEVICE_OBJECT RxDeviceObject, _In_ ULONG InitialContextFlags)
#define RxIsFcbAcquiredExclusive(Fcb)
Definition: rxprocs.h:229
#define RX_GET_MRX_FCB(F)
Definition: rxprocs.h:157
@ LHS_ExclusiveLockHeld
Definition: rxstruc.h:22
VOID RxMarkFobxOnClose(_In_ PFOBX Fobx)
#define RDBSS_NTC_OPENTARGETDIR_FCB
Definition: nodetype.h:44
#define RDBSS_NTC_MAILSLOT
Definition: nodetype.h:46
#define RDBSS_NTC_IPC_SHARE
Definition: nodetype.h:45
PMINIRDR_DISPATCH MRxDispatch
Definition: fcb.h:150
CLONG OpenCount
Definition: fatstruc.h:881
PRDBSS_DEVICE_OBJECT RxDeviceObject
Definition: fcb.h:149
PMRX_FOBX pFobx
Definition: rxcontx.h:113
UCHAR MajorFunction
Definition: rxcontx.h:105
PMRX_SRV_OPEN pRelevantSrvOpen
Definition: rxcontx.h:114
PMRX_FCB pFcb
Definition: rxcontx.h:112
Definition: fcb.h:10
Definition: fcb.h:261
LIST_ENTRY FobxList
Definition: fcb.h:279
RX_BLOCK_CONDITION Condition
Definition: fcb.h:275
void * PVOID
Definition: typedefs.h:50

Referenced by RxCommonClose().

◆ RxCollapseOrCreateSrvOpen()

NTSTATUS RxCollapseOrCreateSrvOpen ( PRX_CONTEXT  RxContext)

Definition at line 1732 of file rdbss.c.

1734{
1737 PSRV_OPEN SrvOpen;
1740 RX_BLOCK_CONDITION FcbCondition;
1741
1744
1745 PAGED_CODE();
1746
1747 DPRINT("RxCollapseOrCreateSrvOpen(%p)\n", RxContext);
1748
1750 ++capFcb->UncleanCount;
1751
1752 DesiredAccess = capPARAMS->Parameters.Create.SecurityContext->DesiredAccess & FILE_ALL_ACCESS;
1753 ShareAccess = capPARAMS->Parameters.Create.ShareAccess & FILE_SHARE_VALID_FLAGS;
1754
1755 Disposition = RxContext->Create.NtCreateParameters.Disposition;
1756
1757 /* Try to find a reusable SRV_OPEN */
1759 if (Status == STATUS_NOT_FOUND)
1760 {
1761 /* If none found, create one */
1762 SrvOpen = RxCreateSrvOpen((PV_NET_ROOT)RxContext->Create.pVNetRoot, capFcb);
1763 if (SrvOpen == NULL)
1764 {
1766 }
1767 else
1768 {
1769 SrvOpen->DesiredAccess = DesiredAccess;
1770 SrvOpen->ShareAccess = ShareAccess;
1772 }
1773
1774 RxContext->pRelevantSrvOpen = (PMRX_SRV_OPEN)SrvOpen;
1775
1776 if (Status != STATUS_SUCCESS)
1777 {
1778 FcbCondition = Condition_Bad;
1779 }
1780 else
1781 {
1783
1784 /* Cookie to check the mini-rdr doesn't mess with RX_CONTEXT */
1785 RxContext->CurrentIrp->IoStatus.Information = 0xABCDEF;
1786 /* Inform the mini-rdr we're handling a create */
1787 MINIRDR_CALL(Status, RxContext, capFcb->MRxDispatch, MRxCreate, (RxContext));
1788 ASSERT(RxContext->CurrentIrp->IoStatus.Information == 0xABCDEF);
1789
1790 DPRINT("MRxCreate returned: %x\n", Status);
1791 if (Status == STATUS_SUCCESS)
1792 {
1793 /* In case of overwrite, reset file size */
1795 {
1797 capFcb->Header.AllocationSize.QuadPart = 0LL;
1798 capFcb->Header.FileSize.QuadPart = 0LL;
1799 capFcb->Header.ValidDataLength.QuadPart = 0LL;
1800 RxContext->CurrentIrpSp->FileObject->SectionObjectPointer = &capFcb->NonPaged->SectionObjectPointers;
1801 CcSetFileSizes(RxContext->CurrentIrpSp->FileObject, (PCC_FILE_SIZES)&capFcb->Header.AllocationSize);
1803 }
1804 else
1805 {
1806 /* Otherwise, adjust sizes */
1807 RxContext->CurrentIrpSp->FileObject->SectionObjectPointer = &capFcb->NonPaged->SectionObjectPointers;
1808 if (CcIsFileCached(RxContext->CurrentIrpSp->FileObject))
1809 {
1811 }
1812 CcSetFileSizes(RxContext->CurrentIrpSp->FileObject, (PCC_FILE_SIZES)&capFcb->Header.AllocationSize);
1813 }
1814 }
1815
1816 /* Set the IoStatus with information returned by mini-rdr */
1817 RxContext->CurrentIrp->IoStatus.Information = RxContext->Create.ReturnedCreateInformation;
1818
1819 SrvOpen->OpenStatus = Status;
1820 /* Set SRV_OPEN state - good or bad - depending on whether create succeed */
1822
1824
1826
1827 if (Status == STATUS_SUCCESS)
1828 {
1829 if (BooleanFlagOn(capPARAMS->Parameters.Create.Options, FILE_DELETE_ON_CLOSE))
1830 {
1832 }
1833 SrvOpen->CreateOptions = RxContext->Create.NtCreateParameters.CreateOptions;
1834 FcbCondition = Condition_Good;
1835 }
1836 else
1837 {
1838 FcbCondition = Condition_Bad;
1840 RxContext->pRelevantSrvOpen = NULL;
1841
1842 if (RxContext->pFobx != NULL)
1843 {
1845 RxContext->pFobx = NULL;
1846 }
1847 }
1848 }
1849
1850 /* Set FCB state - good or bad - depending on whether create succeed */
1851 DPRINT("Transitioning FCB %p to condition %lx\n", capFcb, capFcb->Condition);
1852 RxTransitionNetFcb(capFcb, FcbCondition);
1853 }
1854 else if (Status == STATUS_SUCCESS)
1855 {
1856 BOOLEAN IsGood, ExtraOpen;
1857
1858 /* A reusable SRV_OPEN was found */
1860 ExtraOpen = FALSE;
1861
1862 SrvOpen = (PSRV_OPEN)RxContext->pRelevantSrvOpen;
1863
1864 IsGood = (SrvOpen->Condition == Condition_Good);
1865 /* If the SRV_OPEN isn't in a stable situation, wait for it to become stable */
1866 if (!StableCondition(SrvOpen->Condition))
1867 {
1868 RxReferenceSrvOpen(SrvOpen);
1869 ++SrvOpen->OpenCount;
1870 ExtraOpen = TRUE;
1871
1872 RxReleaseFcb(RxContext, capFcb);
1873 RxContext->Create.FcbAcquired = FALSE;
1874
1875 RxWaitForStableSrvOpen(SrvOpen, RxContext);
1876
1877 if (NT_SUCCESS(RxAcquireExclusiveFcb(RxContext, capFcb)))
1878 {
1879 RxContext->Create.FcbAcquired = TRUE;
1880 }
1881
1882 IsGood = (SrvOpen->Condition == Condition_Good);
1883 }
1884
1885 /* Inform the mini-rdr we do an opening with a reused SRV_OPEN */
1886 if (IsGood)
1887 {
1888 MINIRDR_CALL(Status, RxContext, capFcb->MRxDispatch, MRxCollapseOpen, (RxContext));
1889
1891 }
1892 else
1893 {
1894 Status = SrvOpen->OpenStatus;
1895 }
1896
1897 if (ExtraOpen)
1898 {
1899 --SrvOpen->OpenCount;
1901 }
1902 }
1903
1904 --capFcb->UncleanCount;
1905
1906 DPRINT("Status: %x\n", Status);
1907 return Status;
1908}
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
VOID RxCompleteSrvOpenKeyAssociation(_Inout_ PSRV_OPEN SrvOpen)
VOID RxInitiateSrvOpenKeyAssociation(_Inout_ PSRV_OPEN SrvOpen)
#define CcIsFileCached(FO)
#define RxTransitionNetFcb(F, C)
Definition: fcb.h:543
#define RxTransitionSrvOpen(S, C)
Definition: fcb.h:578
PSRV_OPEN RxCreateSrvOpen(_In_ PV_NET_ROOT VNetRoot, _In_ OUT PFCB Fcb)
struct _SRV_OPEN * PSRV_OPEN
#define RxReferenceSrvOpen(SrvOpen)
Definition: fcb.h:423
#define FCB_STATE_COLLAPSING_ENABLED
Definition: fcb.h:221
#define RxWaitForStableSrvOpen(S, R)
Definition: fcb.h:577
#define RxDereferenceNetFobx(Fobx, LockHoldingState)
Definition: fcb.h:419
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
#define FILE_OVERWRITE
Definition: from_kernel.h:57
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:356
enum _RX_BLOCK_CONDITION RX_BLOCK_CONDITION
@ Condition_Bad
Definition: mrx.h:77
#define StableCondition(X)
Definition: mrx.h:81
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:56
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define FILE_SHARE_VALID_FLAGS
Definition: nt_native.h:683
#define FILE_ALL_ACCESS
Definition: nt_native.h:651
#define FILE_OPENED
Definition: nt_native.h:769
#define RxAdjustAllocationSizeforCC(Fcb)
Definition: ntrxdef.h:35
NTSTATUS RxSearchForCollapsibleOpen(PRX_CONTEXT RxContext, ACCESS_MASK DesiredAccess, ULONG ShareAccess)
Definition: rdbss.c:8679
#define RxAcquireExclusiveFcb(R, F)
Definition: rxprocs.h:154
#define RxAcquirePagingIoResource(RxContext, Fcb)
Definition: rxprocs.h:233
#define STATUS_NOT_FOUND
Definition: shellext.h:72
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
IO_STATUS_BLOCK IoStatus
PIO_STACK_LOCATION CurrentIrpSp
Definition: rxcontx.h:111
NTSTATUS OpenStatus
Definition: fcb.h:286
#define LL
Definition: tui.h:167

Referenced by RxCreateFromNetRoot().

◆ RxCommonCleanup()

NTSTATUS NTAPI RxCommonCleanup ( PRX_CONTEXT  Context)

Definition at line 1915 of file rdbss.c.

1917{
1918#define BugCheckFileId RDBSS_BUG_CHECK_CLEANUP
1919 PFCB Fcb;
1920 PFOBX Fobx;
1923 PNET_ROOT NetRoot;
1925 LARGE_INTEGER TruncateSize;
1926 PLARGE_INTEGER TruncateSizePtr;
1927 BOOLEAN NeedPurge, FcbTableAcquired, OneLeft, IsFile, FcbAcquired, LeftForDelete;
1928
1929 PAGED_CODE();
1930
1931 Fcb = (PFCB)Context->pFcb;
1932 Fobx = (PFOBX)Context->pFobx;
1933 DPRINT("RxCommonCleanup(%p); FOBX: %p, FCB: %p\n", Context, Fobx, Fcb);
1934
1935 /* File system closing, it's OK */
1936 if (Fobx == NULL)
1937 {
1938 if (Fcb->UncleanCount > 0)
1939 {
1940 InterlockedDecrement((volatile long *)&Fcb->UncleanCount);
1941 }
1942
1943 return STATUS_SUCCESS;
1944 }
1945
1946 /* Check we have a correct FCB type */
1951 {
1952 DPRINT1("Invalid Fcb type for %p\n", Fcb);
1953 RxBugCheck(Fcb->Header.NodeTypeCode, 0, 0);
1954 }
1955
1956 FileObject = Context->CurrentIrpSp->FileObject;
1958
1959 RxMarkFobxOnCleanup(Fobx, &NeedPurge);
1960
1962 if (!NT_SUCCESS(Status))
1963 {
1964 return Status;
1965 }
1966
1967 FcbAcquired = TRUE;
1968
1969 Fobx->AssociatedFileObject = NULL;
1970
1971 /* In case it was already orphaned */
1973 {
1974 ASSERT(Fcb->UncleanCount != 0);
1975 InterlockedDecrement((volatile long *)&Fcb->UncleanCount);
1976
1978 {
1979 --Fcb->UncachedUncleanCount;
1980 }
1981
1982 /* Inform mini-rdr */
1983 MINIRDR_CALL(Status, Context, Fcb->MRxDispatch, MRxCleanupFobx, (Context));
1984
1985 ASSERT(Fobx->SrvOpen->UncleanFobxCount != 0);
1986 --Fobx->SrvOpen->UncleanFobxCount;
1987
1989
1991
1992 return STATUS_SUCCESS;
1993 }
1994
1995 /* Report the fact that file could be set as delete on close */
1996 if (BooleanFlagOn(Fobx->Flags, FOBX_FLAG_DELETE_ON_CLOSE))
1997 {
1999 }
2000
2001 /* Cancel any pending notification */
2003
2004 /* Backup open count before we start playing with it */
2006
2007 NetRoot = (PNET_ROOT)Fcb->pNetRoot;
2008 FcbTableAcquired = FALSE;
2009 LeftForDelete = FALSE;
2010 OneLeft = (Fcb->UncleanCount == 1);
2011
2012 _SEH2_TRY
2013 {
2014 /* Unclean count and delete on close? Verify whether we're the one */
2016 {
2018 {
2019 FcbTableAcquired = TRUE;
2020 }
2021 else
2022 {
2024
2026
2028 if (Status != STATUS_SUCCESS)
2029 {
2031 return Status;
2032 }
2033
2034 FcbTableAcquired = TRUE;
2035 }
2036
2037 /* That means we'll perform the delete on close! */
2038 if (Fcb->UncleanCount == 1)
2039 {
2040 LeftForDelete = TRUE;
2041 }
2042 else
2043 {
2045 FcbTableAcquired = FALSE;
2046 }
2047 }
2048
2049 IsFile = FALSE;
2050 TruncateSizePtr = NULL;
2051 /* Handle cleanup for pipes and printers */
2052 if (NetRoot->Type == NET_ROOT_PIPE || NetRoot->Type == NET_ROOT_PRINT)
2053 {
2055 }
2056 /* Handle cleanup for files */
2057 else if (NetRoot->Type == NET_ROOT_DISK || NetRoot->Type == NET_ROOT_WILD)
2058 {
2059 Context->LowIoContext.Flags |= LOWIO_CONTEXT_FLAG_SAVEUNLOCKS;
2061 {
2062 /* First, unlock */
2064
2065 /* If there are still locks to release, proceed */
2066 if (Context->LowIoContext.ParamsFor.Locks.LockList != NULL)
2067 {
2069 Context->LowIoContext.ParamsFor.Locks.Flags = 0;
2071 }
2072
2073 /* Fix times and size */
2075
2076 /* If we're the only one left... */
2077 if (OneLeft)
2078 {
2079 /* And if we're supposed to delete on close */
2080 if (LeftForDelete)
2081 {
2082 /* Update the sizes */
2084 Fcb->Header.FileSize.QuadPart = 0;
2085 Fcb->Header.ValidDataLength.QuadPart = 0;
2087 }
2088 /* Otherwise, call the mini-rdr to adjust sizes */
2089 else
2090 {
2091 /* File got grown up, fill with zeroes */
2093 (Fcb->Header.ValidDataLength.QuadPart < Fcb->Header.FileSize.QuadPart))
2094 {
2095 MINIRDR_CALL(Status, Context, Fcb->MRxDispatch, MRxZeroExtend, (Context));
2096 Fcb->Header.ValidDataLength.QuadPart = Fcb->Header.FileSize.QuadPart;
2097 }
2098
2099 /* File was truncated, let mini-rdr proceed */
2101 {
2102 MINIRDR_CALL(Status, Context, Fcb->MRxDispatch, MRxTruncate, (Context));
2104
2105 /* Keep track of file change for Cc uninit */
2106 TruncateSize.QuadPart = Fcb->Header.FileSize.QuadPart;
2107 TruncateSizePtr = &TruncateSize;
2108 }
2109 }
2110 }
2111
2112 /* If RxMarkFobxOnCleanup() asked for purge, make sure we're the only one left first */
2113 if (NeedPurge)
2114 {
2115 if (!OneLeft)
2116 {
2117 NeedPurge = FALSE;
2118 }
2119 }
2120 /* Otherwise, try to see whether we can purge */
2121 else
2122 {
2123 NeedPurge = (OneLeft && (LeftForDelete || !BooleanFlagOn(Fcb->FcbState, FCB_STATE_COLLAPSING_ENABLED)));
2124 }
2125
2126 IsFile = TRUE;
2127 }
2128 }
2129
2130 /* We have to still be there! */
2131 ASSERT(Fcb->UncleanCount != 0);
2132 InterlockedDecrement((volatile long *)&Fcb->UncleanCount);
2133
2135 {
2136 --Fcb->UncachedUncleanCount;
2137 }
2138
2139 /* Inform mini-rdr about ongoing cleanup */
2140 MINIRDR_CALL(Status, Context, Fcb->MRxDispatch, MRxCleanupFobx, (Context));
2141
2142 ASSERT(Fobx->SrvOpen->UncleanFobxCount != 0);
2143 --Fobx->SrvOpen->UncleanFobxCount;
2144
2145 /* Flush cache */
2147 {
2148 /* Only if we're the last standing */
2150 Fcb->UncleanCount == Fcb->UncachedUncleanCount)
2151 {
2152 DPRINT("Flushing %p due to last cached handle cleanup\n", Context);
2154 }
2155 }
2156 else
2157 {
2158 /* Always */
2160 {
2161 DPRINT("Flushing %p on cleanup\n", Context);
2163 }
2164 }
2165
2166 /* If only remaining uncached & unclean, then flush and purge */
2168 {
2169 if (Fcb->UncachedUncleanCount != 0)
2170 {
2171 if (Fcb->UncachedUncleanCount == Fcb->UncleanCount &&
2173 {
2174 DPRINT("Flushing FCB in system cache for %p\n", Context);
2176 }
2177 }
2178 }
2179
2180 /* If purge required, and not about to delete, flush */
2181 if (!LeftForDelete && NeedPurge)
2182 {
2183 DPRINT("Flushing FCB in system cache for %p\n", Context);
2185 }
2186
2187 /* If it was a file, drop cache */
2188 if (IsFile)
2189 {
2190 DPRINT("Uninit cache map for file\n");
2191 RxUninitializeCacheMap(Context, FileObject, TruncateSizePtr);
2192 }
2193
2194 /* If that's the one left for deletion, or if it needs purge, flush */
2195 if (LeftForDelete || NeedPurge)
2196 {
2197 RxPurgeFcbInSystemCache(Fcb, NULL, 0, FALSE, !LeftForDelete);
2198 /* If that's for deletion, also remove from FCB table */
2199 if (LeftForDelete)
2200 {
2203 FcbTableAcquired = FALSE;
2204 }
2205 }
2206
2207 /* Remove any share access */
2208 if (OpenCount != 0 && NetRoot->Type == NET_ROOT_DISK)
2209 {
2210 RxRemoveShareAccess(FileObject, &Fcb->ShareAccess, "Cleanup the share access", "ClnUpShr");
2211 }
2212
2213 /* In case there's caching, on a file, and we were asked to drop collapsing, handle it */
2214 if (NodeType(Fcb) == RDBSS_NTC_STORAGE_TYPE_FILE && BooleanFlagOn(Fobx->Flags, FOBX_FLAG_DISABLE_COLLAPSING) &&
2215 RxWriteCacheingAllowed(Fcb, Fobx->pSrvOpen))
2216 {
2217 NTSTATUS InternalStatus;
2218 PRX_CONTEXT InternalContext;
2219
2220 /* If we can properly set EOF, there's no need to drop collapsing, try to do it */
2221 InternalStatus = STATUS_UNSUCCESSFUL;
2222 InternalContext = RxCreateRxContext(Context->CurrentIrp,
2225 if (InternalContext != NULL)
2226 {
2228
2229 InternalStatus = STATUS_SUCCESS;
2230
2231 /* Initialize the context for file information set */
2232 InternalContext->pFcb = RX_GET_MRX_FCB(Fcb);
2233 InternalContext->pFobx = (PMRX_FOBX)Fobx;
2234 InternalContext->pRelevantSrvOpen = Fobx->pSrvOpen;
2235
2236 /* Get EOF from the FCB */
2237 FileEOF.EndOfFile.QuadPart = Fcb->Header.FileSize.QuadPart;
2238 InternalContext->Info.FileInformationClass = FileEndOfFileInformation;
2239 InternalContext->Info.Buffer = &FileEOF;
2240 InternalContext->Info.Length = sizeof(FileEOF);
2241
2242 /* Call the mini-rdr */
2243 MINIRDR_CALL_THROUGH(InternalStatus, Fcb->MRxDispatch, MRxSetFileInfo, (InternalContext));
2244
2245 /* We're done */
2246 RxDereferenceAndDeleteRxContext(InternalContext);
2247 }
2248
2249 /* We tried, so, clean the FOBX flag */
2250 ClearFlag(Fobx->Flags, FOBX_FLAG_DISABLE_COLLAPSING);
2251 /* If it failed, then, disable collapsing on the FCB */
2252 if (!NT_SUCCESS(InternalStatus))
2253 {
2255 }
2256 }
2257
2258 /* We're clean! */
2260
2261 FcbAcquired = FALSE;
2263 }
2265 {
2266 if (FcbAcquired)
2267 {
2269 }
2270
2271 if (FcbTableAcquired)
2272 {
2274 }
2275 }
2276 _SEH2_END;
2277
2278 return Status;
2279#undef BugCheckFileId
2280}
NTSTATUS RxPurgeFcbInSystemCache(_In_ PFCB Fcb, _In_ PLARGE_INTEGER FileOffset OPTIONAL, _In_ ULONG Length, _In_ BOOLEAN UninitializeCacheMaps, _In_ BOOLEAN FlushFile)
NTSTATUS RxFlushFcbInSystemCache(_In_ PFCB Fcb, _In_ BOOLEAN SynchronizeWithLazyWriter)
DWORD OpenCount
Definition: legacy.c:25
#define FCB_STATE_DELETE_ON_CLOSE
Definition: fatstruc.h:1193
#define FCB_STATE_TRUNCATE_ON_CLOSE
Definition: fatstruc.h:1194
#define FCB_STATE_PAGING_FILE
Definition: fatstruc.h:1195
#define FCB_STATE_ORPHANED
Definition: fcb.h:208
#define FOBX_FLAG_DELETE_ON_CLOSE
Definition: fcb.h:295
struct _NET_ROOT * PNET_ROOT
VOID RxRemoveNameNetFcb(_Out_ PFCB ThisFcb)
#define RxAcquireFcbTableLockExclusive(T, W)
Definition: fcbtable.h:55
#define RxReleaseFcbTableLock(T)
Definition: fcbtable.h:56
NTSTATUS NTAPI FsRtlFastUnlockAll(IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PEPROCESS Process, IN PVOID Context OPTIONAL)
Definition: filelock.c:1025
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
VOID NTAPI RxInitializeLowIoContext(_Out_ PLOWIO_CONTEXT LowIoContext, _In_ ULONG Operation)
#define LOWIO_CONTEXT_FLAG_SAVEUNLOCKS
Definition: mrx.h:321
@ LOWIO_OP_UNLOCK_MULTIPLE
Definition: mrx.h:239
#define NET_ROOT_PIPE
Definition: mrxfcb.h:31
#define NET_ROOT_DISK
Definition: mrxfcb.h:30
#define NET_ROOT_PRINT
Definition: mrxfcb.h:32
#define RxGetRequestorProcess(RxContext)
Definition: ntrxdef.h:33
BOOLEAN DisableFlushOnCleanup
Definition: rdbss.c:533
VOID RxAdjustFileTimesAndSize(PRX_CONTEXT RxContext)
Definition: rdbss.c:825
VOID RxUninitializeCacheMap(PRX_CONTEXT RxContext, PFILE_OBJECT FileObject, PLARGE_INTEGER TruncateSize)
Definition: rdbss.c:9414
NTSTATUS RxLowIoLockControlShell(IN PRX_CONTEXT RxContext)
Definition: rdbss.c:7212
VOID RxCleanupPipeQueues(PRX_CONTEXT Context)
Definition: rdbss.c:1524
VOID RxCancelNotifyChangeDirectoryRequestsForFobx(PFOBX Fobx)
Definition: rdbss.c:963
#define MINIRDR_CALL_THROUGH(STATUS, DISPATCH, FUNC, ARGLIST)
Definition: rxcontx.h:375
#define RxRemoveShareAccess(a1, a2, a3, a4)
Definition: rxprocs.h:579
VOID RxMarkFobxOnCleanup(_In_ PFOBX pFobx, _Out_ PBOOLEAN NeedPurge)
#define RDBSS_NTC_STORAGE_TYPE_UNKNOWN
Definition: nodetype.h:41
#define RDBSS_NTC_STORAGE_TYPE_DIRECTORY
Definition: nodetype.h:42
#define RDBSS_NTC_STORAGE_TYPE_FILE
Definition: nodetype.h:43
#define RDBSS_NTC_SPOOLFILE
Definition: nodetype.h:47
#define RxBugCheck(A, B, C)
Definition: nodetype.h:86
union _FCB::@720 Specific
SHARE_ACCESS ShareAccess
Definition: cdstruc.h:1009
struct _FCB::@720::@723 Fcb
CLONG UncleanCount
Definition: fatstruc.h:873
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:925
ULONG FcbState
Definition: cdstruc.h:971
PNON_PAGED_FCB NonPaged
Definition: fatstruc.h:811
PSRV_OPEN SrvOpen
Definition: fcb.h:312
Definition: fcb.h:34
RX_FCB_TABLE FcbTable
Definition: fcb.h:54
SECTION_OBJECT_POINTERS SectionObjectPointers
Definition: fatstruc.h:729
ULONG OpenCount
Definition: iotypes.h:525
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
#define FO_CLEANUP_COMPLETE
Definition: iotypes.h:1790
* PFILE_OBJECT
Definition: iotypes.h:1998
#define FO_NO_INTERMEDIATE_BUFFERING
Definition: iotypes.h:1778

◆ RxCommonClose()

NTSTATUS NTAPI RxCommonClose ( PRX_CONTEXT  Context)

Definition at line 2284 of file rdbss.c.

2286{
2287#define BugCheckFileId RDBSS_BUG_CHECK_CLOSE
2288 PFCB Fcb;
2289 PFOBX Fobx;
2292 BOOLEAN DereferenceFobx, AcquiredFcb;
2293
2294 PAGED_CODE();
2295
2296 Fcb = (PFCB)Context->pFcb;
2297 Fobx = (PFOBX)Context->pFobx;
2298 FileObject = Context->CurrentIrpSp->FileObject;
2299 DPRINT("RxCommonClose(%p); FOBX: %p, FCB: %p, FO: %p\n", Context, Fobx, Fcb, FileObject);
2300
2302 if (!NT_SUCCESS(Status))
2303 {
2304 return Status;
2305 }
2306
2307 AcquiredFcb = TRUE;
2308 _SEH2_TRY
2309 {
2310 BOOLEAN Freed;
2311
2312 /* Check our FCB type is expected */
2316 {
2317 RxBugCheck(NodeType(Fcb), 0, 0);
2318 }
2319
2321
2322 DereferenceFobx = FALSE;
2323 /* If we're not closing FS */
2324 if (Fobx != NULL)
2325 {
2326 PSRV_OPEN SrvOpen;
2327 PSRV_CALL SrvCall;
2328
2329 SrvOpen = (PSRV_OPEN)Fobx->pSrvOpen;
2330 SrvCall = (PSRV_CALL)Fcb->pNetRoot->pSrvCall;
2331 /* Handle delayed close */
2333 {
2335 {
2337 {
2338 DPRINT("Delay close for FOBX: %p, SrvOpen %p\n", Fobx, SrvOpen);
2339
2340 if (SrvOpen->OpenCount == 1 && !BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_COLLAPSING_DISABLED))
2341 {
2342 if (InterlockedIncrement(&SrvCall->NumberOfCloseDelayedFiles) >= SrvCall->MaximumNumberOfCloseDelayedFiles)
2343 {
2345 }
2346 else
2347 {
2348 DereferenceFobx = TRUE;
2349 SetFlag(SrvOpen->Flags, SRVOPEN_FLAG_CLOSE_DELAYED);
2350 }
2351 }
2352 }
2353 }
2354 }
2355
2356 /* If we reach maximum of delayed close/or if there are no delayed close */
2357 if (!DereferenceFobx)
2358 {
2359 PNET_ROOT NetRoot;
2360
2361 NetRoot = (PNET_ROOT)Fcb->pNetRoot;
2362 if (NetRoot->Type != NET_ROOT_PRINT)
2363 {
2364 /* Delete if asked */
2365 if (BooleanFlagOn(Fobx->Flags, FOBX_FLAG_DELETE_ON_CLOSE))
2366 {
2369
2371
2375
2378 }
2379 }
2380 }
2381
2382 RxMarkFobxOnClose(Fobx);
2383 }
2384
2385 if (DereferenceFobx)
2386 {
2387 ASSERT(Fobx != NULL);
2389 }
2390 else
2391 {
2393 if (Fobx != NULL)
2394 {
2396 }
2397 }
2398
2400 AcquiredFcb = !Freed;
2401
2402 FileObject->FsContext = (PVOID)-1;
2403
2404 if (Freed)
2405 {
2406 RxTrackerUpdateHistory(Context, NULL, TRACKER_FCB_FREE, __LINE__, __FILE__, 0);
2407 }
2408 else
2409 {
2411 AcquiredFcb = FALSE;
2412 }
2413 }
2415 {
2417 {
2418 if (AcquiredFcb)
2419 {
2421 }
2422 }
2423 else
2424 {
2425 ASSERT(!AcquiredFcb);
2426 }
2427 }
2428 _SEH2_END;
2429
2430 DPRINT("Status: %x\n", Status);
2431 return Status;
2432#undef BugCheckFileId
2433}
#define RxReferenceNetFcb(Fcb)
Definition: fcb.h:431
#define RxDereferenceAndFinalizeNetFcb(Fcb, RxContext, RecursiveFinalize, ForceFinalize)
Definition: fcb.h:439
#define SRVOPEN_FLAG_COLLAPSING_DISABLED
Definition: mrxfcb.h:137
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:160
NTSTATUS RxCloseAssociatedSrvOpen(IN PFOBX Fobx, IN PRX_CONTEXT RxContext OPTIONAL)
Definition: rdbss.c:1534
VOID RxOrphanThisFcb(_In_ PFCB Fcb)
#define RxTrackerUpdateHistory(R, F, O, L, F, S)
Definition: rxprocs.h:218
@ LHS_SharedLockHeld
Definition: rxstruc.h:21
VOID RxSynchronizeWithScavenger(_In_ PRX_CONTEXT RxContext)
BOOLEAN RxScavengeRelatedFobxs(_In_ PFCB Fcb)
volatile LONG NumberOfCloseDelayedFiles
Definition: fcb.h:23

◆ RxCommonCreate()

NTSTATUS NTAPI RxCommonCreate ( PRX_CONTEXT  Context)

Definition at line 2440 of file rdbss.c.

2442{
2443 PIRP Irp;
2447
2448 PAGED_CODE();
2449
2450 DPRINT("RxCommonCreate(%p)\n", Context);
2451
2452 Irp = Context->CurrentIrp;
2453 Stack = Context->CurrentIrpSp;
2454 FileObject = Stack->FileObject;
2455
2456 /* Check whether that's a device opening */
2457 if (FileObject->FileName.Length == 0 && FileObject->RelatedFileObject == NULL)
2458 {
2459 FileObject->FsContext = &RxDeviceFCB;
2460 FileObject->FsContext2 = NULL;
2461
2462 ++RxDeviceFCB.NodeReferenceCount;
2464
2465 Irp->IoStatus.Information = FILE_OPENED;
2466 DPRINT("Device opening FO: %p, DO: %p, Name: %wZ\n", FileObject, Context->RxDeviceObject, &Context->RxDeviceObject->DeviceName);
2467
2469 }
2470 else
2471 {
2472 PFCB RelatedFcb = NULL;
2473
2474 /* Make sure caller is consistent */
2477 {
2478 DPRINT1("Create.Options: %x\n", Stack->Parameters.Create.Options);
2480 }
2481
2482 DPRINT("Ctxt: %p, FO: %p, Options: %lx, Flags: %lx, Attr: %lx, ShareAccess: %lx, DesiredAccess: %lx\n",
2483 Context, FileObject, Stack->Parameters.Create.Options, Stack->Flags, Stack->Parameters.Create.FileAttributes,
2484 Stack->Parameters.Create.ShareAccess, Stack->Parameters.Create.SecurityContext->DesiredAccess);
2485 DPRINT("FileName: %wZ\n", &FileObject->FileName);
2486
2487 if (FileObject->RelatedFileObject != NULL)
2488 {
2489 RelatedFcb = FileObject->RelatedFileObject->FsContext;
2490 DPRINT("Rel FO: %p, path: %wZ\n", FileObject->RelatedFileObject, RelatedFcb->FcbTableEntry.Path);
2491 }
2492
2493 /* Going to rename? */
2495 {
2496 DPRINT("TargetDir!\n");
2497 }
2498
2499 /* Copy create parameters to the context */
2501
2502 /* If the caller wants to establish a connection, go ahead */
2503 if (BooleanFlagOn(Stack->Parameters.Create.Options, FILE_CREATE_TREE_CONNECTION))
2504 {
2506 }
2507 else
2508 {
2509 /* Validate file name */
2510 if (FileObject->FileName.Length > sizeof(WCHAR) &&
2511 FileObject->FileName.Buffer[1] == OBJ_NAME_PATH_SEPARATOR &&
2512 FileObject->FileName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
2513 {
2514 FileObject->FileName.Length -= sizeof(WCHAR);
2515 RtlMoveMemory(&FileObject->FileName.Buffer[0], &FileObject->FileName.Buffer[1],
2516 FileObject->FileName.Length);
2517
2518 if (FileObject->FileName.Length > sizeof(WCHAR) &&
2519 FileObject->FileName.Buffer[1] == OBJ_NAME_PATH_SEPARATOR &&
2520 FileObject->FileName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
2521 {
2523 }
2524 }
2525
2526 /* Attempt to open the file */
2527 do
2528 {
2529 UNICODE_STRING NetRootName;
2530
2531 /* Strip last \ if required */
2532 if (FileObject->FileName.Length != 0 &&
2533 FileObject->FileName.Buffer[FileObject->FileName.Length / sizeof(WCHAR) - 1] == OBJ_NAME_PATH_SEPARATOR)
2534 {
2535 if (BooleanFlagOn(Stack->Parameters.Create.Options, FILE_NON_DIRECTORY_FILE))
2536 {
2538 }
2539
2540 FileObject->FileName.Length -= sizeof(WCHAR);
2542 }
2543
2545 {
2546 FileObject->Flags |= FO_WRITE_THROUGH;
2547 }
2548
2549 /* Get the associated net root to opening */
2550 Status = RxCanonicalizeNameAndObtainNetRoot(Context, &FileObject->FileName, &NetRootName);
2552 {
2553 break;
2554 }
2555
2556 /* And attempt to open */
2557 Status = RxCreateFromNetRoot(Context, &NetRootName);
2559 {
2561
2562 /* If that happens for file creation, fail for real */
2563 if (Context->Create.NtCreateParameters.Disposition == FILE_CREATE)
2564 {
2566 }
2567 else
2568 {
2569 /* Otherwise, if possible, attempt to scavenger current FOBX
2570 * to check whether a dormant FOBX is the reason for sharing violation
2571 */
2572 if (Context->Create.TryForScavengingOnSharingViolation &&
2573 !Context->Create.ScavengingAlreadyTried)
2574 {
2575 /* Only doable with a VNetRoot */
2576 if (Context->Create.pVNetRoot != NULL)
2577 {
2578 PV_NET_ROOT VNetRoot;
2579 NT_CREATE_PARAMETERS SavedParameters;
2580
2581 /* Save create parameters */
2582 RtlCopyMemory(&SavedParameters, &Context->Create.NtCreateParameters, sizeof(NT_CREATE_PARAMETERS));
2583
2584 /* Reference the VNetRoot for the scavenging time */
2585 VNetRoot = (PV_NET_ROOT)Context->Create.pVNetRoot;
2586 RxReferenceVNetRoot(VNetRoot);
2587
2588 /* Prepare the RX_CONTEXT for reuse */
2591
2592 /* Copy what we saved */
2593 RtlCopyMemory(&Context->Create.NtCreateParameters, &SavedParameters, sizeof(NT_CREATE_PARAMETERS));
2594
2595 /* And recopy what can be */
2597
2598 /* And start purging, then scavenging FOBX */
2599 RxPurgeRelatedFobxs((PNET_ROOT)VNetRoot->pNetRoot, Context,
2601 RxScavengeFobxsForNetRoot((PNET_ROOT)VNetRoot->pNetRoot,
2602 NULL, TRUE);
2603
2604 /* Ask for a second round */
2606
2607 /* Keep track we already scavenged */
2608 Context->Create.ScavengingAlreadyTried = TRUE;
2609
2610 /* Reference our SRV_CALL for CBS handling */
2611 RxReferenceSrvCall(VNetRoot->pNetRoot->pSrvCall);
2612 RxpProcessChangeBufferingStateRequests((PSRV_CALL)VNetRoot->pNetRoot->pSrvCall, FALSE);
2613
2614 /* Drop our extra reference */
2616 }
2617 }
2618 }
2619 }
2620 else if (Status == STATUS_REPARSE)
2621 {
2622 Context->CurrentIrp->IoStatus.Information = 0;
2623 }
2624 else
2625 {
2627 }
2628 }
2630 }
2631
2632 if (Status == STATUS_RETRY)
2633 {
2635 }
2637 }
2638
2639 DPRINT("Status: %lx\n", Status);
2640 return Status;
2641}
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
VOID RxpProcessChangeBufferingStateRequests(PSRV_CALL SrvCall, BOOLEAN UpdateHandlerState)
Definition: rxce.c:6417
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define RxReferenceVNetRoot(VNetRoot)
Definition: fcb.h:407
struct _V_NET_ROOT * PV_NET_ROOT
#define RxReferenceSrvCall(SrvCall)
Definition: fcb.h:391
#define RxDereferenceVNetRoot(VNetRoot, LockHoldingState)
Definition: fcb.h:411
#define FILE_CREATE
Definition: from_kernel.h:55
#define FILE_OPEN_REMOTE_INSTANCE
Definition: from_kernel.h:37
#define FILE_CREATE_TREE_CONNECTION
Definition: from_kernel.h:33
#define STATUS_REPARSE
Definition: ntstatus.h:83
FCB RxDeviceFCB
Definition: rdbss.c:538
VOID RxpPrepareCreateContextForReuse(PRX_CONTEXT RxContext)
Definition: rdbss.c:7654
VOID RxCopyCreateParameters(IN PRX_CONTEXT RxContext)
Definition: rdbss.c:5039
NTSTATUS RxCreateFromNetRoot(PRX_CONTEXT Context, PUNICODE_STRING NetRootName)
Definition: rdbss.c:5114
NTSTATUS RxCreateTreeConnect(IN PRX_CONTEXT RxContext)
Definition: rdbss.c:5409
NTSTATUS RxCanonicalizeNameAndObtainNetRoot(PRX_CONTEXT RxContext, PUNICODE_STRING FileName, PUNICODE_STRING NetRootName)
Definition: rdbss.c:1352
@ RX_CONTEXT_FLAG_WRITE_THROUGH
Definition: rxcontx.h:283
VOID NTAPI RxReinitializeContext(_Inout_ PRX_CONTEXT RxContext)
@ RX_CONTEXT_CREATE_FLAG_REPARSE
Definition: rxcontx.h:327
@ RX_CONTEXT_CREATE_FLAG_STRIPPED_TRAILING_BACKSLASH
Definition: rxcontx.h:325
@ LHS_LockNotHeld
Definition: rxstruc.h:20
VOID RxScavengeFobxsForNetRoot(PNET_ROOT NetRoot, PFCB PurgingFcb, BOOLEAN SynchronizeWithScavenger)
Definition: rxce.c:7798
NTSTATUS RxPurgeRelatedFobxs(PNET_ROOT NetRoot, PRX_CONTEXT RxContext, BOOLEAN AttemptFinalization, PFCB PurgingFcb)
Definition: rxce.c:7133
#define DONT_ATTEMPT_FINALIZE_ON_PURGE
Definition: scavengr.h:45
RX_FCB_TABLE_ENTRY FcbTableEntry
Definition: fcb.h:144
UNICODE_STRING Path
Definition: fcbtable.h:8
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define STATUS_RETRY
Definition: udferr_usr.h:182
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define FO_WRITE_THROUGH
Definition: iotypes.h:1779
#define SL_OPEN_TARGET_DIRECTORY
Definition: iotypes.h:1818

◆ RxCommonDevFCBCleanup()

NTSTATUS NTAPI RxCommonDevFCBCleanup ( PRX_CONTEXT  Context)

Definition at line 2648 of file rdbss.c.

2650{
2651 PMRX_FCB Fcb;
2653
2654 PAGED_CODE();
2655
2656 DPRINT("RxCommonDevFCBCleanup(%p)\n", Context);
2657
2658 Fcb = Context->pFcb;
2661
2662 /* Our FOBX if set, has to be a VNetRoot */
2663 if (Context->pFobx != NULL)
2664 {
2665 RxAcquirePrefixTableLockShared(Context->RxDeviceObject->pRxNetNameTable, TRUE);
2666 if (Context->pFobx->NodeTypeCode != RDBSS_NTC_V_NETROOT)
2667 {
2669 }
2670 RxReleasePrefixTableLock(Context->RxDeviceObject->pRxNetNameTable);
2671 }
2672 else
2673 {
2674 --Fcb->UncleanCount;
2675 }
2676
2677 return Status;
2678}
#define RxAcquirePrefixTableLockShared(T, W)
Definition: prefix.h:82
#define RxReleasePrefixTableLock(T)
Definition: prefix.h:84
#define RDBSS_NTC_DEVICE_FCB
Definition: nodetype.h:54
#define RDBSS_NTC_V_NETROOT
Definition: nodetype.h:50
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138

◆ RxCommonDevFCBClose()

NTSTATUS NTAPI RxCommonDevFCBClose ( PRX_CONTEXT  Context)

Definition at line 2685 of file rdbss.c.

2687{
2688 PMRX_FCB Fcb;
2690 PMRX_V_NET_ROOT NetRoot;
2691
2692 PAGED_CODE();
2693
2694 DPRINT("RxCommonDevFCBClose(%p)\n", Context);
2695
2696 Fcb = Context->pFcb;
2697 NetRoot = (PMRX_V_NET_ROOT)Context->pFobx;
2700
2701 /* Our FOBX if set, has to be a VNetRoot */
2702 if (NetRoot != NULL)
2703 {
2704 RxAcquirePrefixTableLockExclusive(Context->RxDeviceObject->pRxNetNameTable, TRUE);
2705 if (NetRoot->NodeTypeCode == RDBSS_NTC_V_NETROOT)
2706 {
2707 --NetRoot->NumberOfOpens;
2709 }
2710 else
2711 {
2713 }
2714 RxReleasePrefixTableLock(Context->RxDeviceObject->pRxNetNameTable);
2715 }
2716 else
2717 {
2718 --Fcb->OpenCount;
2719 }
2720
2721 return Status;
2722}
struct _MRX_V_NET_ROOT_ * PMRX_V_NET_ROOT
#define RxAcquirePrefixTableLockExclusive(T, W)
Definition: prefix.h:83
ULONG NumberOfOpens
Definition: mrxfcb.h:97

◆ RxCommonDevFCBFsCtl()

NTSTATUS NTAPI RxCommonDevFCBFsCtl ( PRX_CONTEXT  Context)

Definition at line 2726 of file rdbss.c.

2728{
2731}

◆ RxCommonDevFCBIoCtl()

NTSTATUS NTAPI RxCommonDevFCBIoCtl ( PRX_CONTEXT  Context)

Definition at line 2738 of file rdbss.c.

2740{
2742
2743 PAGED_CODE();
2744
2745 DPRINT("RxCommonDevFCBIoCtl(%p)\n", Context);
2746
2747 if (Context->pFobx != NULL)
2748 {
2749 return STATUS_INVALID_HANDLE;
2750 }
2751
2752 /* Is that a prefix claim from MUP? */
2753 if (Context->CurrentIrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_REDIR_QUERY_PATH)
2754 {
2755 return RxPrefixClaim(Context);
2756 }
2757
2758 /* Otherwise, pass through the mini-rdr */
2760 if (Status != STATUS_PENDING)
2761 {
2762 if (Context->PostRequest)
2763 {
2764 Context->ResumeRoutine = RxCommonDevFCBIoCtl;
2766 }
2767 }
2768
2769 DPRINT("Status: %lx\n", Status);
2770 return Status;
2771}
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
NTSTATUS RxFsdPostRequest(IN PRX_CONTEXT RxContext)
Definition: rdbss.c:6548
NTSTATUS RxPrefixClaim(IN PRX_CONTEXT RxContext)
Definition: rdbss.c:7714
NTSTATUS RxXXXControlFileCallthru(PRX_CONTEXT Context)
Definition: rdbss.c:9561
NTSTATUS NTAPI RxCommonDevFCBIoCtl(PRX_CONTEXT Context)
Definition: rdbss.c:2738

Referenced by RxCommonDevFCBIoCtl().

◆ RxCommonDevFCBQueryVolInfo()

NTSTATUS NTAPI RxCommonDevFCBQueryVolInfo ( PRX_CONTEXT  Context)

Definition at line 2775 of file rdbss.c.

2777{
2780}

◆ RxCommonDeviceControl()

NTSTATUS NTAPI RxCommonDeviceControl ( PRX_CONTEXT  Context)

Definition at line 2787 of file rdbss.c.

2789{
2791
2792 PAGED_CODE();
2793
2794 /* Prefix claim is only allowed for device, not files */
2795 if (Context->CurrentIrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_REDIR_QUERY_PATH)
2796 {
2798 }
2799
2800 /* Submit to mini-rdr */
2803 if (Status == STATUS_PENDING)
2804 {
2806 }
2807
2808 return Status;
2809}
NTSTATUS NTAPI RxLowIoSubmit(_In_ PRX_CONTEXT RxContext, _In_ PLOWIO_COMPLETION_ROUTINE CompletionRoutine)
@ LOWIO_OP_IOCTL
Definition: mrx.h:241
NTSTATUS NTAPI RxLowIoIoCtlShellCompletion(PRX_CONTEXT RxContext)
Definition: rdbss.c:7187
VOID NTAPI RxDereferenceAndDeleteRxContext_Real(_In_ PRX_CONTEXT RxContext)

◆ RxCommonDirectoryControl()

NTSTATUS NTAPI RxCommonDirectoryControl ( PRX_CONTEXT  Context)

Definition at line 2816 of file rdbss.c.

2818{
2819 PFCB Fcb;
2820 PFOBX Fobx;
2823
2824 PAGED_CODE();
2825
2826 Fcb = (PFCB)Context->pFcb;
2827 Fobx = (PFOBX)Context->pFobx;
2828 Stack = Context->CurrentIrpSp;
2829 DPRINT("RxCommonDirectoryControl(%p) FOBX: %p, FCB: %p, Minor: %d\n", Context, Fobx, Fcb, Stack->MinorFunction);
2830
2831 /* Call the appropriate helper */
2832 if (Stack->MinorFunction == IRP_MN_QUERY_DIRECTORY)
2833 {
2835 }
2836 else if (Stack->MinorFunction == IRP_MN_NOTIFY_CHANGE_DIRECTORY)
2837 {
2839 if (Status == STATUS_PENDING)
2840 {
2842 }
2843 }
2844 else
2845 {
2847 }
2848
2849 return Status;
2850}
NTSTATUS RxQueryDirectory(PRX_CONTEXT RxContext)
Definition: rdbss.c:8052
NTSTATUS RxNotifyChangeDirectory(PRX_CONTEXT RxContext)
Definition: rdbss.c:7556
#define IRP_MN_QUERY_DIRECTORY
Definition: rdpdr.c:55

◆ RxCommonDispatchProblem()

NTSTATUS NTAPI RxCommonDispatchProblem ( PRX_CONTEXT  Context)

Definition at line 2854 of file rdbss.c.

2856{
2859}

◆ RxCommonFileSystemControl()

NTSTATUS NTAPI RxCommonFileSystemControl ( PRX_CONTEXT  Context)

Definition at line 2863 of file rdbss.c.

2865{
2866 PIRP Irp;
2869
2870 PAGED_CODE();
2871
2872 Irp = Context->CurrentIrp;
2873 Stack = Context->CurrentIrpSp;
2874 ControlCode = Stack->Parameters.FileSystemControl.FsControlCode;
2875
2876 DPRINT1("RxCommonFileSystemControl: %p, %p, %d, %lx\n", Context, Irp, Stack->MinorFunction, ControlCode);
2877
2880}
_IRQL_requires_same_ typedef _In_ ULONG ControlCode
Definition: wmitypes.h:55

◆ RxCommonFlushBuffers()

NTSTATUS NTAPI RxCommonFlushBuffers ( PRX_CONTEXT  Context)

Definition at line 2884 of file rdbss.c.

2886{
2889}

◆ RxCommonLockControl()

NTSTATUS NTAPI RxCommonLockControl ( PRX_CONTEXT  Context)

Definition at line 2893 of file rdbss.c.

2895{
2898}

◆ RxCommonQueryEa()

NTSTATUS NTAPI RxCommonQueryEa ( PRX_CONTEXT  Context)

Definition at line 2902 of file rdbss.c.

2904{
2907}

◆ RxCommonQueryInformation()

NTSTATUS NTAPI RxCommonQueryInformation ( PRX_CONTEXT  Context)

Definition at line 2914 of file rdbss.c.

2916{
2917#define SET_SIZE_AND_QUERY(AlreadyConsummed, Function) \
2918 Context->Info.Length = Stack->Parameters.QueryFile.Length - (AlreadyConsummed); \
2919 Status = Function(Context, Add2Ptr(Buffer, AlreadyConsummed))
2920
2921 PFCB Fcb;
2922 PIRP Irp;
2923 PFOBX Fobx;
2927 FILE_INFORMATION_CLASS FileInfoClass;
2928
2929 PAGED_CODE();
2930
2931 Fcb = (PFCB)Context->pFcb;
2932 Fobx = (PFOBX)Context->pFobx;
2933 DPRINT("RxCommonQueryInformation(%p) FCB: %p, FOBX: %p\n", Context, Fcb, Fobx);
2934
2935 Irp = Context->CurrentIrp;
2936 Stack = Context->CurrentIrpSp;
2937 DPRINT("Buffer: %p, Length: %lx, Class: %ld\n", Irp->AssociatedIrp.SystemBuffer,
2938 Stack->Parameters.QueryFile.Length, Stack->Parameters.QueryFile.FileInformationClass);
2939
2940 Context->Info.Length = Stack->Parameters.QueryFile.Length;
2941 FileInfoClass = Stack->Parameters.QueryFile.FileInformationClass;
2942
2943 Locked = FALSE;
2944 _SEH2_TRY
2945 {
2946 PVOID Buffer;
2947
2948 /* Get a writable buffer */
2950 if (Buffer == NULL)
2951 {
2954 }
2955 /* Zero it */
2956 RtlZeroMemory(Buffer, Context->Info.Length);
2957
2958 /* Validate file type */
2960 {
2962 {
2965 }
2967 {
2969 {
2971 }
2972 else
2973 {
2975 }
2976
2978 }
2979 }
2980
2981 /* Acquire the right lock */
2983 FileInfoClass != FileNameInformation)
2984 {
2985 if (FileInfoClass == FileCompressionInformation)
2986 {
2988 }
2989 else
2990 {
2992 }
2993
2995 {
2998 }
2999 else if (!NT_SUCCESS(Status))
3000 {
3002 }
3003
3004 Locked = TRUE;
3005 }
3006
3007 /* Dispatch to the right helper */
3008 switch (FileInfoClass)
3009 {
3012 break;
3013
3016 break;
3017
3020 break;
3021
3022 case FileEaInformation:
3024 break;
3025
3028 break;
3029
3030 case FileAllInformation:
3032 if (!NT_SUCCESS(Status))
3033 {
3034 break;
3035 }
3036
3038 if (!NT_SUCCESS(Status))
3039 {
3040 break;
3041 }
3042
3045 if (!NT_SUCCESS(Status))
3046 {
3047 break;
3048 }
3049
3053 if (!NT_SUCCESS(Status))
3054 {
3055 break;
3056 }
3057
3062 if (!NT_SUCCESS(Status))
3063 {
3064 break;
3065 }
3066
3070 sizeof(FILE_EA_INFORMATION) +
3072 break;
3073
3076 break;
3077
3082 break;
3083
3086 break;
3087
3088 default:
3089 Context->IoStatusBlock.Status = RxpQueryInfoMiniRdr(Context, FileInfoClass, Buffer);
3090 Status = Context->IoStatusBlock.Status;
3091 break;
3092 }
3093
3094 if (Context->Info.Length < 0)
3095 {
3097 Context->Info.Length = Stack->Parameters.QueryFile.Length;
3098 }
3099
3100 Irp->IoStatus.Information = Stack->Parameters.QueryFile.Length - Context->Info.Length;
3101 }
3103 {
3104 if (Locked)
3105 {
3107 }
3108 }
3109 _SEH2_END;
3110
3111 DPRINT("Status: %x\n", Status);
3112 return Status;
3113
3114#undef SET_SIZE_AND_QUERY
3115}
#define _SEH2_LEAVE
Definition: filesup.c:20
@ FilePipeLocalInformation
Definition: from_kernel.h:85
@ FileCompressionInformation
Definition: from_kernel.h:89
@ FileAllInformation
Definition: from_kernel.h:79
@ FilePipeRemoteInformation
Definition: from_kernel.h:86
@ FileInternalInformation
Definition: from_kernel.h:67
@ FileEaInformation
Definition: from_kernel.h:68
@ FilePipeInformation
Definition: from_kernel.h:84
@ FileAlternateNameInformation
Definition: from_kernel.h:82
@ FileNameInformation
Definition: from_kernel.h:70
enum _FILE_INFORMATION_CLASS FILE_INFORMATION_CLASS
Definition: directory.c:44
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
Definition: newmm.h:209
#define STATUS_LOCK_NOT_GRANTED
Definition: ntstatus.h:321
#define FileStandardInformation
Definition: propsheet.cpp:61
NTSTATUS RxQueryInternalInfo(PRX_CONTEXT RxContext, PFILE_INTERNAL_INFORMATION InternalInfo)
Definition: rdbss.c:8274
NTSTATUS RxQueryBasicInfo(PRX_CONTEXT RxContext, PFILE_BASIC_INFORMATION BasicInfo)
Definition: rdbss.c:8026
NTSTATUS RxQueryCompressedInfo(PRX_CONTEXT RxContext, PFILE_COMPRESSION_INFORMATION CompressionInfo)
Definition: rdbss.c:8040
#define SET_SIZE_AND_QUERY(AlreadyConsummed, Function)
NTSTATUS RxQueryNameInfo(PRX_CONTEXT RxContext, PFILE_NAME_INFORMATION NameInfo)
Definition: rdbss.c:8286
NTSTATUS RxQueryStandardInfo(PRX_CONTEXT RxContext, PFILE_STANDARD_INFORMATION StandardInfo)
Definition: rdbss.c:8358
NTSTATUS RxQueryEaInfo(PRX_CONTEXT RxContext, PFILE_EA_INFORMATION EaInfo)
Definition: rdbss.c:8265
NTSTATUS RxQueryAlternateNameInfo(PRX_CONTEXT RxContext, PFILE_NAME_INFORMATION AltNameInfo)
Definition: rdbss.c:8014
NTSTATUS RxQueryPipeInfo(PRX_CONTEXT RxContext, PFILE_PIPE_INFORMATION PipeInfo)
Definition: rdbss.c:8337
NTSTATUS RxpQueryInfoMiniRdr(PRX_CONTEXT RxContext, FILE_INFORMATION_CLASS FileInfoClass, PVOID Buffer)
Definition: rdbss.c:7690
NTSTATUS RxQueryPositionInfo(PRX_CONTEXT RxContext, PFILE_POSITION_INFORMATION PositionInfo)
Definition: rdbss.c:8346
PVOID RxMapSystemBuffer(_In_ PRX_CONTEXT RxContext)
#define RxAcquireSharedFcb(R, F)
Definition: rxprocs.h:162
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66

◆ RxCommonQueryQuotaInformation()

NTSTATUS NTAPI RxCommonQueryQuotaInformation ( PRX_CONTEXT  Context)

Definition at line 3119 of file rdbss.c.

3121{
3124}

◆ RxCommonQuerySecurity()

NTSTATUS NTAPI RxCommonQuerySecurity ( PRX_CONTEXT  Context)

Definition at line 3128 of file rdbss.c.

3130{
3133}

◆ RxCommonQueryVolumeInformation()

NTSTATUS NTAPI RxCommonQueryVolumeInformation ( PRX_CONTEXT  Context)

Definition at line 3140 of file rdbss.c.

3142{
3143 PIRP Irp;
3144 PFCB Fcb;
3145 PFOBX Fobx;
3148
3149 PAGED_CODE();
3150
3151 Fcb = (PFCB)Context->pFcb;
3152 Fobx = (PFOBX)Context->pFobx;
3153
3154 DPRINT("RxCommonQueryVolumeInformation(%p) FCB: %p, FOBX: %p\n", Context, Fcb, Fobx);
3155
3156 Irp = Context->CurrentIrp;
3157 Stack = Context->CurrentIrpSp;
3158 DPRINT("Length: %lx, Class: %lx, Buffer %p\n", Stack->Parameters.QueryVolume.Length,
3159 Stack->Parameters.QueryVolume.FsInformationClass, Irp->AssociatedIrp.SystemBuffer);
3160
3161 Context->Info.FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
3162 Context->Info.Buffer = Irp->AssociatedIrp.SystemBuffer;
3163 Context->Info.Length = Stack->Parameters.QueryVolume.Length;
3164
3165 /* Forward to mini-rdr */
3166 MINIRDR_CALL(Status, Context, Fcb->MRxDispatch, MRxQueryVolumeInfo, (Context));
3167
3168 /* Post request if mini-rdr asked to */
3169 if (Context->PostRequest)
3170 {
3172 }
3173 else
3174 {
3175 Irp->IoStatus.Information = Stack->Parameters.QueryVolume.Length - Context->Info.Length;
3176 }
3177
3178 DPRINT("Status: %x\n", Status);
3179 return Status;
3180}

◆ RxCommonRead()

NTSTATUS NTAPI RxCommonRead ( PRX_CONTEXT  Context)

Definition at line 3184 of file rdbss.c.

3186{
3187 PFCB Fcb;
3188 PIRP Irp;
3189 PFOBX Fobx;
3191 PNET_ROOT NetRoot;
3192 PVOID SystemBuffer;
3196 PLOWIO_CONTEXT LowIoContext;
3197 PRDBSS_DEVICE_OBJECT RxDeviceObject;
3198 ULONG ReadLength, CapturedRxContextSerialNumber = RxContext->SerialNumber;
3199 BOOLEAN CanWait, PagingIo, NoCache, Sync, PostRequest, IsPipe, ReadCachingEnabled, ReadCachingDisabled, InFsp, OwnerSet;
3200
3201 PAGED_CODE();
3202
3203 Fcb = (PFCB)RxContext->pFcb;
3204 Fobx = (PFOBX)RxContext->pFobx;
3205 DPRINT("RxCommonRead(%p) FOBX: %p, FCB: %p\n", RxContext, Fobx, Fcb);
3206
3207 /* Get some parameters */
3208 Irp = RxContext->CurrentIrp;
3209 Stack = RxContext->CurrentIrpSp;
3210 CanWait = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
3211 PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO);
3212 NoCache = BooleanFlagOn(Irp->Flags, IRP_NOCACHE);
3213 Sync = !BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION);
3214 InFsp = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP);
3215 ReadLength = Stack->Parameters.Read.Length;
3216 ByteOffset.QuadPart = Stack->Parameters.Read.ByteOffset.QuadPart;
3217 DPRINT("Reading: %lx@%I64x %s %s %s %s\n", ReadLength, ByteOffset.QuadPart,
3218 (CanWait ? "CW" : "!CW"), (PagingIo ? "PI" : "!PI"), (NoCache ? "NC" : "!NC"), (Sync ? "S" : "!S"));
3219
3221
3222 Irp->IoStatus.Information = 0;
3223
3224 /* Should the read be loud - so far, it's just ignored on ReactOS:
3225 * s/DPRINT/DPRINT1/g will make it loud
3226 */
3227 LowIoContext = &RxContext->LowIoContext;
3228 CheckForLoudOperations(RxContext);
3230 {
3231 DPRINT("LoudRead %I64x/%lx on %lx vdl/size/alloc %I64x/%I64x/%I64x\n",
3233 Fcb, Fcb->Header.ValidDataLength, Fcb->Header.FileSize, Fcb->Header.AllocationSize);
3234 }
3235
3236 RxDeviceObject = RxContext->RxDeviceObject;
3237 /* Update stats */
3238 if (!BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP) && Fcb->CachedNetRootType == NET_ROOT_DISK)
3239 {
3240 InterlockedIncrement((volatile long *)&RxDeviceObject->ReadOperations);
3241
3242 if (ByteOffset.QuadPart != Fobx->Specific.DiskFile.PredictedReadOffset)
3243 {
3244 InterlockedIncrement((volatile long *)&RxDeviceObject->RandomReadOperations);
3245 }
3246 Fobx->Specific.DiskFile.PredictedReadOffset = ByteOffset.QuadPart + ReadLength;
3247
3248 if (PagingIo)
3249 {
3251 }
3252 else if (NoCache)
3253 {
3255 }
3256 else
3257 {
3259 }
3260 }
3261
3262 /* A pagefile cannot be a pipe */
3263 IsPipe = Fcb->NetRoot->Type == NET_ROOT_PIPE;
3264 if (IsPipe && PagingIo)
3265 {
3267 }
3268
3269 /* Null-length read is no-op */
3270 if (ReadLength == 0)
3271 {
3272 return STATUS_SUCCESS;
3273 }
3274
3275 /* Validate FCB type */
3277 {
3279 }
3280
3281 /* Init the lowio context for possible forward */
3283
3284 PostRequest = FALSE;
3285 ReadCachingDisabled = FALSE;
3286 OwnerSet = FALSE;
3288 FileObject = Stack->FileObject;
3289 NetRoot = (PNET_ROOT)Fcb->pNetRoot;
3290 _SEH2_TRY
3291 {
3293
3294 /* If no caching, make sure current Cc data have been flushed */
3295 if (!PagingIo && NoCache && !ReadCachingEnabled && FileObject->SectionObjectPointer != NULL)
3296 {
3297 Status = RxAcquireExclusiveFcb(RxContext, Fcb);
3299 {
3300 PostRequest = TRUE;
3302 }
3303 else if (Status != STATUS_SUCCESS)
3304 {
3306 }
3307
3308 ExAcquireResourceSharedLite(Fcb->Header.PagingIoResource, TRUE);
3309 CcFlushCache(FileObject->SectionObjectPointer, &ByteOffset, ReadLength, &Irp->IoStatus);
3310 RxReleasePagingIoResource(RxContext, Fcb);
3311
3312 if (!NT_SUCCESS(Irp->IoStatus.Status))
3313 {
3314 Status = Irp->IoStatus.Status;
3316 }
3317
3318 RxAcquirePagingIoResource(RxContext, Fcb);
3319 RxReleasePagingIoResource(RxContext, Fcb);
3320 }
3321
3322 /* Acquire the appropriate lock */
3323 if (PagingIo && !ReadCachingEnabled)
3324 {
3325 ASSERT(!IsPipe);
3326
3327 if (!ExAcquireResourceSharedLite(Fcb->Header.PagingIoResource, CanWait))
3328 {
3329 PostRequest = TRUE;
3331 }
3332
3333 if (!CanWait)
3334 {
3335 LowIoContext->Resource = Fcb->Header.PagingIoResource;
3336 }
3337 }
3338 else
3339 {
3340 if (!ReadCachingEnabled)
3341 {
3342 if (!CanWait && NoCache)
3343 {
3346 {
3347 DPRINT1("RdAsyLNG %x\n", RxContext);
3348 PostRequest = TRUE;
3350 }
3351 if (Status != STATUS_SUCCESS)
3352 {
3353 DPRINT1("RdAsyOthr %x\n", RxContext);
3355 }
3356
3357 if (RxIsFcbAcquiredShared(Fcb) <= 0xF000)
3358 {
3359 LowIoContext->Resource = Fcb->Header.Resource;
3360 }
3361 else
3362 {
3363 PostRequest = TRUE;
3365 }
3366 }
3367 else
3368 {
3369 Status = RxAcquireSharedFcb(RxContext, Fcb);
3371 {
3372 PostRequest = TRUE;
3374 }
3375 else if (Status != STATUS_SUCCESS)
3376 {
3378 }
3379 }
3380 }
3381 }
3382
3384
3385 ReadCachingDisabled = (ReadCachingEnabled == FALSE);
3386 if (IsPipe)
3387 {
3389 }
3390
3392
3393 /* Make sure FLOCK doesn't conflict */
3394 if (!PagingIo)
3395 {
3397 {
3400 }
3401 }
3402
3403 /* Validate byteoffset vs length */
3405 {
3406 if (ByteOffset.QuadPart >= FileSize)
3407 {
3410 }
3411
3412 if (ReadLength > FileSize - ByteOffset.QuadPart)
3413 {
3414 ReadLength = FileSize - ByteOffset.QuadPart;
3415 }
3416 }
3417
3418 /* Read with Cc! */
3419 if (!PagingIo && !NoCache && ReadCachingEnabled &&
3420 !BooleanFlagOn(Fobx->pSrvOpen->Flags, SRVOPEN_FLAG_DONTUSE_READ_CACHING))
3421 {
3422 /* File was not cached yet, do it */
3423 if (FileObject->PrivateCacheMap == NULL)
3424 {
3426 {
3429 }
3430
3432
3435
3437 {
3439 }
3440 else
3441 {
3444 }
3445
3446 CcSetReadAheadGranularity(FileObject, NetRoot->DiskParameters.ReadAheadGranularity);
3447 }
3448
3449 /* This should never happen - fix your RDR */
3450 if (BooleanFlagOn(RxContext->MinorFunction, IRP_MN_MDL))
3451 {
3452 ASSERT(FALSE);
3453 ASSERT(CanWait);
3454
3455 CcMdlRead(FileObject, &ByteOffset, ReadLength, &Irp->MdlAddress, &Irp->IoStatus);
3456 Status = Irp->IoStatus.Status;
3458 }
3459 else
3460 {
3461 /* Map buffer */
3462 SystemBuffer = RxNewMapUserBuffer(RxContext);
3463 if (SystemBuffer == NULL)
3464 {
3467 }
3468
3470
3472
3473 /* Perform the read */
3474 if (!CcCopyRead(FileObject, &ByteOffset, ReadLength, CanWait, SystemBuffer, &Irp->IoStatus))
3475 {
3476 if (!ReadCachingEnabled)
3477 {
3479 }
3480
3482
3483 PostRequest = TRUE;
3485 }
3486
3487 if (!ReadCachingEnabled)
3488 {
3490 }
3491
3492 Status = Irp->IoStatus.Status;
3494 }
3495 }
3496 else
3497 {
3498 /* Validate the reading */
3499 if (FileObject->PrivateCacheMap != NULL && BooleanFlagOn(Fcb->FcbState, FCB_STATE_READAHEAD_DEFERRED) &&
3500 ByteOffset.QuadPart >= 4096)
3501 {
3504 }
3505
3506 /* If it's consistent, forward to mini-rdr */
3507 if (Fcb->CachedNetRootType != NET_ROOT_DISK || BooleanFlagOn(Fcb->FcbState, FCB_STATE_READAHEAD_DEFERRED) ||
3508 ByteOffset.QuadPart < Fcb->Header.ValidDataLength.QuadPart)
3509 {
3510 LowIoContext->ParamsFor.ReadWrite.ByteCount = ReadLength;
3511 LowIoContext->ParamsFor.ReadWrite.ByteOffset = ByteOffset.QuadPart;
3512
3514
3515 if (InFsp && ReadCachingDisabled)
3516 {
3517 ExSetResourceOwnerPointer((PagingIo ? Fcb->Header.PagingIoResource : Fcb->Header.Resource),
3518 (PVOID)((ULONG_PTR)RxContext | 3));
3519 OwnerSet = TRUE;
3520 }
3521
3522 Status = RxLowIoReadShell(RxContext);
3523
3525 }
3526 else
3527 {
3528 if (ByteOffset.QuadPart > FileSize)
3529 {
3530 ReadLength = 0;
3531 Irp->IoStatus.Information = ReadLength;
3533 }
3534
3535 if (ByteOffset.QuadPart + ReadLength > FileSize)
3536 {
3537 ReadLength = FileSize - ByteOffset.QuadPart;
3538 }
3539
3540 SystemBuffer = RxNewMapUserBuffer(RxContext);
3541 RtlZeroMemory(SystemBuffer, ReadLength);
3542 Irp->IoStatus.Information = ReadLength;
3543 }
3544 }
3545 }
3547 {
3549
3550 /* Post if required */
3551 if (PostRequest)
3552 {
3553 InterlockedIncrement((volatile long *)&RxContext->ReferenceCount);
3554 Status = RxFsdPostRequest(RxContext);
3555 }
3556 else
3557 {
3558 /* Update FO in case of sync IO */
3559 if (!IsPipe && !PagingIo)
3560 {
3562 {
3563 FileObject->CurrentByteOffset.QuadPart = ByteOffset.QuadPart + Irp->IoStatus.Information;
3564 }
3565 }
3566 }
3567
3568 /* Set FastIo if read was a success */
3570 {
3571 if (!IsPipe && !PagingIo)
3572 {
3574 }
3575 }
3576
3577 /* In case we're done (not expected any further processing */
3578 if (_SEH2_AbnormalTermination() || Status != STATUS_PENDING || PostRequest)
3579 {
3580 /* Release everything that can be */
3581 if (ReadCachingDisabled)
3582 {
3583 if (PagingIo)
3584 {
3585 if (OwnerSet)
3586 {
3587 RxReleasePagingIoResourceForThread(RxContext, Fcb, LowIoContext->ResourceThreadId);
3588 }
3589 else
3590 {
3591 RxReleasePagingIoResource(RxContext, Fcb);
3592 }
3593 }
3594 else
3595 {
3596 if (OwnerSet)
3597 {
3598 RxReleaseFcbForThread(RxContext, Fcb, LowIoContext->ResourceThreadId);
3599 }
3600 else
3601 {
3602 RxReleaseFcb(RxContext, Fcb);
3603 }
3604 }
3605 }
3606
3607 /* Dereference/Delete context */
3608 if (PostRequest)
3609 {
3611 }
3612 else
3613 {
3614 if (BooleanFlagOn(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION))
3615 {
3616 RxResumeBlockedOperations_Serially(RxContext, &Fobx->Specific.NamedPipe.ReadSerializationQueue);
3617 }
3618 }
3619
3620 /* We cannot return more than asked */
3621 if (Status == STATUS_SUCCESS)
3622 {
3623 ASSERT(Irp->IoStatus.Information <= Stack->Parameters.Read.Length);
3624 }
3625 }
3626 else
3627 {
3628 ASSERT(!Sync);
3629
3631 }
3632 }
3633 _SEH2_END;
3634
3635 return Status;
3636}
ULONG ReadLength
VOID NTAPI CcMdlRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus)
Definition: mdlsup.c:64
VOID NTAPI CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject, IN ULONG Granularity)
Definition: cachesub.c:36
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
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:731
VOID RxGetFileSizeWithLock(_In_ PFCB Fcb, _Out_ PLONGLONG FileSize)
#define FCB_STATE_READCACHING_ENABLED
Definition: fcb.h:224
#define FCB_STATE_READAHEAD_DEFERRED
Definition: fcb.h:209
BOOLEAN NTAPI FsRtlCheckLockForReadAccess(IN PFILE_LOCK FileLock, IN PIRP Irp)
Definition: filelock.c:672
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
VOID NTAPI CcInitializeCacheMap(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes, IN BOOLEAN PinAccess, IN PCACHE_MANAGER_CALLBACKS Callbacks, IN PVOID LazyWriteContext)
Definition: fssup.c:195
VOID NTAPI CcSetAdditionalCacheAttributes(IN PFILE_OBJECT FileObject, IN BOOLEAN DisableReadAhead, IN BOOLEAN DisableWriteBehind)
Definition: logsup.c:22
@ LOWIO_OP_READ
Definition: mrx.h:234
#define RDBSS_NO_DEFERRED_CACHE_READAHEAD
Definition: mrx.h:335
#define SRVOPEN_FLAG_DONTUSE_READ_CACHING
Definition: mrxfcb.h:130
BOOLEAN NTAPI CcCopyRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus)
Definition: copysup.c:43
VOID NTAPI ExSetResourceOwnerPointer(IN PERESOURCE Resource, IN PVOID OwnerPointer)
Definition: resource.c:2050
#define STATUS_FILE_LOCK_CONFLICT
Definition: ntstatus.h:320
#define STATUS_FILE_CLOSED
Definition: ntstatus.h:532
RDBSS_DATA RxData
Definition: rdbss.c:537
PVOID RxNewMapUserBuffer(PRX_CONTEXT RxContext)
Definition: rxce.c:5775
VOID CheckForLoudOperations(PRX_CONTEXT RxContext)
Definition: rdbss.c:647
NTSTATUS RxLowIoReadShell(PRX_CONTEXT RxContext)
Definition: rdbss.c:7242
@ RX_CONTEXT_FLAG_IN_FSP
Definition: rxcontx.h:290
@ RX_CONTEXT_FLAG_ASYNC_OPERATION
Definition: rxcontx.h:293
@ RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION
Definition: rxcontx.h:333
VOID NTAPI RxResumeBlockedOperations_Serially(_Inout_ PRX_CONTEXT RxContext, _Inout_ PLIST_ENTRY BlockingIoQ)
#define RxItsTheSameContext()
Definition: rxcontx.h:370
#define RxIsFcbAcquiredShared(Fcb)
Definition: rxprocs.h:228
#define RxAcquireSharedFcbWaitForEx(R, F)
Definition: rxprocs.h:168
#define RDBSS_NTC_VOLUME_FCB
Definition: nodetype.h:51
#define STATUS_END_OF_FILE
Definition: shellext.h:67
PNET_ROOT NetRoot
Definition: fcb.h:136
struct _FOBX::@1958::@1962 DiskFile
struct _FOBX::@1958::@1961 NamedPipe
union _FOBX::@1958 Specific
struct _LOWIO_CONTEXT::@2065::@2066 ReadWrite
union _LOWIO_CONTEXT::@2065 ParamsFor
PERESOURCE Resource
Definition: mrx.h:284
ULONG MRxFlags
Definition: mrx.h:341
CACHE_MANAGER_CALLBACKS CacheManagerCallbacks
Definition: rxstruc.h:35
volatile ULONG RandomReadOperations
Definition: rxstruc.h:109
volatile ULONG ReadOperations
Definition: rxstruc.h:107
LARGE_INTEGER CacheReadBytesRequested
Definition: rxstruc.h:104
LARGE_INTEGER PagingReadBytesRequested
Definition: rxstruc.h:102
LARGE_INTEGER NonPagingReadBytesRequested
Definition: rxstruc.h:103
int64_t LONGLONG
Definition: typedefs.h:68
uint32_t ULONG_PTR
Definition: typedefs.h:65
static const unsigned short IsPipe
Definition: typegen.c:75
#define ExInterlockedAddLargeStatistic(Addend, Increment)
Definition: exfuncs.h:850
#define IRP_PAGING_IO
#define IRP_MN_MDL
Definition: iotypes.h:4419
#define FO_SYNCHRONOUS_IO
Definition: iotypes.h:1776
#define IRP_NOCACHE

◆ RxCommonSetEa()

NTSTATUS NTAPI RxCommonSetEa ( PRX_CONTEXT  Context)

Definition at line 3640 of file rdbss.c.

3642{
3645}

◆ RxCommonSetInformation()

NTSTATUS NTAPI RxCommonSetInformation ( PRX_CONTEXT  Context)

Definition at line 3652 of file rdbss.c.

3654{
3655 PIRP Irp;
3656 PFCB Fcb;
3657 PFOBX Fobx;
3659 PNET_ROOT NetRoot;
3662 BOOLEAN CanWait, FcbTableAcquired, FcbAcquired;
3663
3664 PAGED_CODE();
3665
3666 Fcb = (PFCB)Context->pFcb;
3667 Fobx = (PFOBX)Context->pFobx;
3668 DPRINT("RxCommonSetInformation(%p), FCB: %p, FOBX: %p\n", Context, Fcb, Fobx);
3669
3670 Irp = Context->CurrentIrp;
3671 Stack = Context->CurrentIrpSp;
3672 Class = Stack->Parameters.SetFile.FileInformationClass;
3673 DPRINT("Buffer: %p, Length: %lx, Class: %ld, ReplaceIfExists: %d\n",
3674 Irp->AssociatedIrp.SystemBuffer, Stack->Parameters.SetFile.Length,
3675 Class, Stack->Parameters.SetFile.ReplaceIfExists);
3676
3678 CanWait = BooleanFlagOn(Context->Flags, RX_CONTEXT_FLAG_WAIT);
3679 FcbTableAcquired = FALSE;
3680 FcbAcquired = FALSE;
3681 NetRoot = (PNET_ROOT)Fcb->pNetRoot;
3682
3683#define _SEH2_TRY_RETURN(S) S; goto try_exit
3684
3685 _SEH2_TRY
3686 {
3687 /* Valide the node type first */
3690 {
3692 {
3694 {
3696 }
3697 }
3698 else if (NodeType(Fcb) != RDBSS_NTC_SPOOLFILE)
3699 {
3701 {
3703 }
3704 else
3705 {
3706 DPRINT1("Illegal type of file provided: %x\n", NodeType(Fcb));
3708 }
3709 }
3710 }
3711
3712 /* We don't autorize advance operation */
3713 if (Class == FileEndOfFileInformation && Stack->Parameters.SetFile.AdvanceOnly)
3714 {
3715 DPRINT1("Not allowed\n");
3716
3718 }
3719
3720 /* For these to classes, we'll have to deal with the FCB table (removal)
3721 * We thus need the exclusive FCB table lock
3722 */
3724 {
3725 RxPurgeRelatedFobxs(NetRoot, Context, TRUE, Fcb);
3727
3728 if (!RxAcquireFcbTableLockExclusive(&NetRoot->FcbTable, CanWait))
3729 {
3730 Context->PostRequest = TRUE;
3732 }
3733
3734 FcbTableAcquired = TRUE;
3735 }
3736
3737 /* Finally, if not paging file, we need exclusive FCB lock */
3739 {
3742 {
3743 Context->PostRequest = TRUE;
3745 }
3746 else if (Status != STATUS_SUCCESS)
3747 {
3749 }
3750
3751 FcbAcquired = TRUE;
3752 }
3753
3755
3756 /* And now, perform the job! */
3757 switch (Class)
3758 {
3761 break;
3762
3764 {
3766
3767 /* Check whether user wants deletion */
3768 FDI = Irp->AssociatedIrp.SystemBuffer;
3769 if (FDI->DeleteFile)
3770 {
3771 /* If so, check whether it's doable */
3772 if (!MmFlushImageSection(&Fcb->NonPaged->SectionObjectPointers, MmFlushForDelete))
3773 {
3775 }
3776
3777 /* And if doable, already remove from FCB table */
3778 if (Status == STATUS_SUCCESS)
3779 {
3780 ASSERT(FcbAcquired && FcbTableAcquired);
3782
3784 FcbTableAcquired = FALSE;
3785 }
3786 }
3787
3788 /* If it succeed, perform the operation */
3789 if (Status == STATUS_SUCCESS)
3790 {
3792 }
3793
3794 break;
3795 }
3796
3799 break;
3800
3803 break;
3804
3807 break;
3808
3813 break;
3814
3818 /* If we can wait, try to perform the operation right now */
3819 if (CanWait)
3820 {
3821 /* Of course, collapsing is not doable anymore, file is
3822 * in an inbetween state
3823 */
3825
3826 /* Set the information */
3828 /* If it succeed, drop the current entry from FCB table */
3830 {
3831 ASSERT(FcbAcquired && FcbTableAcquired);
3833 }
3835 }
3836 /* Can't wait? Post for async retry */
3837 else
3838 {
3841 }
3842 break;
3843
3846 {
3848 }
3849 break;
3850
3853 break;
3854
3855 default:
3856 DPRINT1("Insupported class: %x\n", Class);
3858
3859 break;
3860 }
3861
3862try_exit: NOTHING;
3863 /* If mini-rdr was OK and wants a re-post on this, do it */
3864 if (Status == STATUS_SUCCESS)
3865 {
3866 if (Context->PostRequest)
3867 {
3869 }
3870 }
3871 }
3873 {
3874 /* Release any acquired lock */
3875 if (FcbAcquired)
3876 {
3878 }
3879
3880 if (FcbTableAcquired)
3881 {
3883 }
3884 }
3885 _SEH2_END;
3886
3887#undef _SEH2_TRY_RETURN
3888
3889 return Status;
3890}
@ FilePositionInformation
Definition: from_kernel.h:75
@ FileMoveClusterInformation
Definition: from_kernel.h:92
@ FileRenameInformation
Definition: from_kernel.h:71
@ FileLinkInformation
Definition: from_kernel.h:72
@ FileValidDataLengthInformation
Definition: from_kernel.h:100
@ FileAllocationInformation
Definition: from_kernel.h:80
@ FileDispositionInformation
Definition: from_kernel.h:74
@ FileShortNameInformation
Definition: from_kernel.h:101
#define NOTHING
Definition: input_list.c:10
#define STATUS_USER_MAPPED_FILE
Definition: ntstatus.h:711
NTSTATUS RxSetEndOfFileInfo(PRX_CONTEXT RxContext)
Definition: rdbss.c:9018
NTSTATUS RxSetAllocationInfo(PRX_CONTEXT RxContext)
Definition: rdbss.c:8864
NTSTATUS RxSetDispositionInfo(PRX_CONTEXT RxContext)
Definition: rdbss.c:8978
NTSTATUS RxSetRenameInfo(PRX_CONTEXT RxContext)
Definition: rdbss.c:9045
#define _SEH2_TRY_RETURN(S)
NTSTATUS RxSetBasicInfo(PRX_CONTEXT RxContext)
Definition: rdbss.c:8875
NTSTATUS RxSetPositionInfo(PRX_CONTEXT RxContext)
Definition: rdbss.c:9034
NTSTATUS RxSetSimpleInfo(PRX_CONTEXT RxContext)
Definition: rdbss.c:9136
NTSTATUS RxSetPipeInfo(PRX_CONTEXT RxContext)
Definition: rdbss.c:9026
#define S(x)
Definition: test.h:217
BOOLEAN NTAPI MmCanFileBeTruncated(_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER NewFileSize)
Definition: section.c:4255
BOOLEAN NTAPI MmFlushImageSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
Definition: section.c:4356
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
Definition: movable.cpp:9

◆ RxCommonSetQuotaInformation()

NTSTATUS NTAPI RxCommonSetQuotaInformation ( PRX_CONTEXT  Context)

Definition at line 3894 of file rdbss.c.

3896{
3899}

◆ RxCommonSetSecurity()

NTSTATUS NTAPI RxCommonSetSecurity ( PRX_CONTEXT  Context)

Definition at line 3903 of file rdbss.c.

3905{
3908}

◆ RxCommonSetVolumeInformation()

NTSTATUS NTAPI RxCommonSetVolumeInformation ( PRX_CONTEXT  Context)

Definition at line 3912 of file rdbss.c.

3914{
3917}

◆ RxCommonUnimplemented()

NTSTATUS NTAPI RxCommonUnimplemented ( PRX_CONTEXT  Context)

Definition at line 3921 of file rdbss.c.

3923{
3926}

◆ RxCommonWrite()

NTSTATUS NTAPI RxCommonWrite ( PRX_CONTEXT  Context)

Definition at line 3930 of file rdbss.c.

3932{
3933 PIRP Irp;
3934 PFCB Fcb;
3935 PFOBX Fobx;
3937 PNET_ROOT NetRoot;
3938 PSRV_OPEN SrvOpen;
3942 NODE_TYPE_CODE NodeTypeCode;
3943 PLOWIO_CONTEXT LowIoContext;
3944 PRDBSS_DEVICE_OBJECT RxDeviceObject;
3945 ULONG WriteLength, CapturedRxContextSerialNumber = RxContext->SerialNumber;
3946 LONGLONG FileSize, ValidDataLength, InitialFileSize, InitialValidDataLength;
3947 BOOLEAN CanWait, PagingIo, NoCache, Sync, NormalFile, WriteToEof, IsPipe, NoPreposting, InFsp, RecursiveWriteThrough, CalledByLazyWriter, SwitchBackToAsync, ExtendingFile, ExtendingValidData, UnwindOutstandingAsync, ResourceOwnerSet, PostIrp, ContextReferenced;
3948
3949 PAGED_CODE();
3950
3951 Fcb = (PFCB)RxContext->pFcb;
3952 NodeTypeCode = NodeType(Fcb);
3953 /* Validate FCB type */
3954 if (NodeTypeCode != RDBSS_NTC_STORAGE_TYPE_FILE && NodeTypeCode != RDBSS_NTC_VOLUME_FCB &&
3955 NodeTypeCode != RDBSS_NTC_SPOOLFILE && NodeTypeCode != RDBSS_NTC_MAILSLOT)
3956 {
3958 }
3959
3960 /* We'll write to file, keep track of it */
3961 Fcb->IsFileWritten = TRUE;
3962
3963 Stack = RxContext->CurrentIrpSp;
3964 /* Set write through if asked */
3966 {
3967 SetFlag(RxContext->Flags, RX_CONTEXT_FLAG_WRITE_THROUGH);
3968 }
3969
3970 Fobx = (PFOBX)RxContext->pFobx;
3971 DPRINT("RxCommonWrite(%p) FOBX: %p, FCB: %p\n", RxContext, Fobx, Fcb);
3972
3973 /* Get some parameters */
3974 Irp = RxContext->CurrentIrp;
3975 NoPreposting = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_NO_PREPOSTING_NEEDED);
3976 InFsp = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP);
3977 CanWait = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
3978 PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO);
3979 NoCache = BooleanFlagOn(Irp->Flags, IRP_NOCACHE);
3980 Sync = !BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION);
3981 WriteLength = Stack->Parameters.Write.Length;
3982 ByteOffset.QuadPart = Stack->Parameters.Write.ByteOffset.QuadPart;
3983 DPRINT("Writing: %lx@%I64x %s %s %s %s\n", WriteLength, ByteOffset.QuadPart,
3984 (CanWait ? "CW" : "!CW"), (PagingIo ? "PI" : "!PI"), (NoCache ? "NC" : "!NC"), (Sync ? "S" : "!S"));
3985
3987
3988 RxContext->FcbResourceAcquired = FALSE;
3989 RxContext->FcbPagingIoResourceAcquired = FALSE;
3990
3991 LowIoContext = &RxContext->LowIoContext;
3992 CheckForLoudOperations(RxContext);
3994 {
3995 DPRINT("LoudWrite %I64x/%lx on %lx vdl/size/alloc %I64x/%I64x/%I64x\n",
3997 Fcb, Fcb->Header.ValidDataLength, Fcb->Header.FileSize, Fcb->Header.AllocationSize);
3998 }
3999
4000 RxDeviceObject = RxContext->RxDeviceObject;
4001 /* Update stats */
4002 if (!BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP) && Fcb->CachedNetRootType == NET_ROOT_DISK)
4003 {
4004 InterlockedIncrement((volatile long *)&RxDeviceObject->WriteOperations);
4005
4006 if (ByteOffset.QuadPart != Fobx->Specific.DiskFile.PredictedWriteOffset)
4007 {
4008 InterlockedIncrement((volatile long *)&RxDeviceObject->RandomWriteOperations);
4009 }
4010 Fobx->Specific.DiskFile.PredictedWriteOffset = ByteOffset.QuadPart + WriteLength;
4011
4012 if (PagingIo)
4013 {
4015 }
4016 else if (NoCache)
4017 {
4019 }
4020 else
4021 {
4023 }
4024 }
4025
4026 NetRoot = (PNET_ROOT)Fcb->NetRoot;
4027 IsPipe = (NetRoot->Type == NET_ROOT_PIPE);
4028 /* Keep track for normal writes */
4029 if (NetRoot->Type == NET_ROOT_DISK || NetRoot->Type == NET_ROOT_WILD)
4030 {
4031 NormalFile = TRUE;
4032 }
4033 else
4034 {
4035 NormalFile = FALSE;
4036 }
4037
4038 /* Zero-length write is immediate success */
4039 if (NormalFile && WriteLength == 0)
4040 {
4041 return STATUS_SUCCESS;
4042 }
4043
4044 /* Check whether we have input data */
4045 if (Irp->UserBuffer == NULL && Irp->MdlAddress == NULL)
4046 {
4048 }
4049
4050 /* Are we writting to EOF? */
4051 WriteToEof = ((ByteOffset.LowPart == FILE_WRITE_TO_END_OF_FILE) && (ByteOffset.HighPart == -1));
4052 /* FIXME: validate length/offset */
4053
4054 /* Get our SRV_OPEN in case of normal write */
4055 if (Fobx != NULL)
4056 {
4057 SrvOpen = (PSRV_OPEN)Fobx->pSrvOpen;
4058 }
4059 else
4060 {
4061 SrvOpen = NULL;
4062 }
4063
4064 FileObject = Stack->FileObject;
4065
4066 /* If we have caching enabled, check whether we have to defer write */
4067 if (!NoCache)
4068 {
4069 if (RxWriteCacheingAllowed(Fcb, SrvOpen))
4070 {
4072 (CanWait && !BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP)),
4074 {
4075 BOOLEAN Retrying;
4076
4077 Retrying = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_DEFERRED_WRITE);
4078
4079 RxPrePostIrp(RxContext, Irp);
4080
4081 SetFlag(RxContext->Flags, RX_CONTEXT_FLAG_DEFERRED_WRITE);
4082
4084
4085 return STATUS_PENDING;
4086 }
4087 }
4088 }
4089
4090 /* Initialize the low IO context for write */
4092
4093 /* Initialize our (many) booleans */
4094 RecursiveWriteThrough = FALSE;
4095 CalledByLazyWriter = FALSE;
4096 SwitchBackToAsync = FALSE;
4097 ExtendingFile = FALSE;
4098 ExtendingValidData = FALSE;
4099 UnwindOutstandingAsync = FALSE;
4100 ResourceOwnerSet = FALSE;
4101 PostIrp = FALSE;
4102 ContextReferenced = FALSE;
4103
4104#define _SEH2_TRY_RETURN(S) S; goto try_exit
4105
4106 _SEH2_TRY
4107 {
4108 /* No volume FCB here! */
4109 ASSERT((NodeTypeCode == RDBSS_NTC_STORAGE_TYPE_FILE) ||
4110 (NodeTypeCode == RDBSS_NTC_SPOOLFILE) ||
4111 (NodeTypeCode == RDBSS_NTC_MAILSLOT));
4112
4113 /* Writing to EOF on a paging file is non sense */
4114 ASSERT(!(WriteToEof && PagingIo));
4115
4117
4118 /* Start locking stuff */
4119 if (!PagingIo && !NoPreposting)
4120 {
4121 /* If it's already acquired, all fine */
4122 if (RxContext->FcbResourceAcquired)
4123 {
4124 ASSERT(!IsPipe);
4125 }
4126 else
4127 {
4128 /* Otherwise, try to acquire shared (excepted for pipes) */
4129 if (IsPipe)
4130 {
4131 Status = RxAcquireExclusiveFcb(RxContext, Fcb);
4132 }
4133 else if (CanWait ||
4134 (!NoCache && RxWriteCacheingAllowed(Fcb, SrvOpen)))
4135 {
4136 Status = RxAcquireSharedFcb(RxContext, Fcb);
4137 }
4138 else
4139 {
4141 }
4142
4143 /* We'll post IRP to retry */
4145 {
4146 PostIrp = TRUE;
4147 DPRINT1("Failed to acquire lock!\n");
4149 }
4150
4151 /* We'll just fail */
4152 if (Status != STATUS_SUCCESS)
4153 {
4155 }
4156
4157 /* Resource acquired */
4158 RxContext->FcbResourceAcquired = TRUE;
4159 }
4160
4161 /* At that point, resource is acquired */
4162 if (IsPipe)
4163 {
4164 ASSERT(RxContext->FcbResourceAcquired);
4165 }
4166 else
4167 {
4168 BOOLEAN IsDormant;
4169
4170 /* Now, check whether we have to promote shared lock */
4171 if (NodeTypeCode == RDBSS_NTC_STORAGE_TYPE_FILE && Fobx != NULL)
4172 {
4173 IsDormant = BooleanFlagOn(Fobx->Flags, FOBX_FLAG_MARKED_AS_DORMANT);
4174 }
4175 else
4176 {
4177 IsDormant = FALSE;
4178 }
4179
4180 /* We're writing beyond VDL, we'll need an exclusive lock if not dormant */
4182 ByteOffset.QuadPart + WriteLength > Fcb->Header.ValidDataLength.QuadPart)
4183 {
4184 if (!IsDormant)
4185 {
4186 RxReleaseFcb(RxContext, Fcb);
4187 RxContext->FcbResourceAcquired = FALSE;
4188
4189 Status = RxAcquireExclusiveFcb(RxContext, Fcb);
4191 {
4192 PostIrp = TRUE;
4193 DPRINT1("Failed to acquire lock!\n");
4195 }
4196
4197 if (Status != STATUS_SUCCESS)
4198 {
4200 }
4201
4202 RxContext->FcbResourceAcquired = TRUE;
4203 }
4204 }
4205
4206 /* If we're writing in VDL, or if we're dormant, shared lock is enough */
4207 if (ByteOffset.QuadPart + WriteLength <= Fcb->Header.ValidDataLength.QuadPart ||
4208 IsDormant)
4209 {
4211 {
4212 RxConvertToSharedFcb(RxContext, Fcb);
4213 }
4214 }
4215 else
4216 {
4217 /* We're extending file, disable collapsing */
4219
4220 DPRINT("Disabling collapsing\n");
4221
4222 if (NodeTypeCode == RDBSS_NTC_STORAGE_TYPE_FILE && Fobx != NULL)
4223 {
4224 SetFlag(Fobx->Flags, FOBX_FLAG_DISABLE_COLLAPSING);
4225 }
4226 }
4227
4228 ASSERT(RxContext->FcbResourceAcquired);
4229 }
4230
4231 /* Keep track of the acquired resource */
4232 LowIoContext->Resource = Fcb->Header.Resource;
4233 }
4234 else
4235 {
4236 /* Paging IO */
4237 ASSERT(!IsPipe);
4238
4239 /* Lock the paging resource */
4241
4242 /* Keep track of the acquired resource */
4243 LowIoContext->Resource = Fcb->Header.PagingIoResource;
4244 }
4245
4246 if (IsPipe)
4247 {
4250 }
4251
4252 /* If it's a non cached write, or if caching is disallowed */
4253 if (NoCache || !RxWriteCacheingAllowed(Fcb, SrvOpen))
4254 {
4255 /* If cache was previously enabled, we'll have to flush before writing */
4257 {
4258 LARGE_INTEGER FlushOffset;
4259
4260 /* FCB is lock */
4262
4263 /* If shared, we'll have to relock exclusive */
4265 {
4266 /* Release and retry exclusive */
4267 RxReleaseFcb(RxContext, Fcb);
4268 RxContext->FcbResourceAcquired = FALSE;
4269
4270 Status = RxAcquireExclusiveFcb(RxContext, Fcb);
4272 {
4273 PostIrp = TRUE;
4274 DPRINT1("Failed to acquire lock for flush!\n");
4276 }
4277
4278 if (Status != STATUS_SUCCESS)
4279 {
4281 }
4282
4283 RxContext->FcbResourceAcquired = TRUE;
4284 }
4285
4286 /* Get the length to flush */
4287 if (WriteToEof)
4288 {
4289 RxGetFileSizeWithLock(Fcb, &FlushOffset.QuadPart);
4290 }
4291 else
4292 {
4293 FlushOffset.QuadPart = ByteOffset.QuadPart;
4294 }
4295
4296 /* Perform the flushing */
4297 RxAcquirePagingIoResource(RxContext, Fcb);
4299 WriteLength, &Irp->IoStatus);
4300 RxReleasePagingIoResource(RxContext, Fcb);
4301
4302 /* Cannot continue if flushing failed */
4303 if (!NT_SUCCESS(Irp->IoStatus.Status))
4304 {
4305 _SEH2_TRY_RETURN(Status = Irp->IoStatus.Status);
4306 }
4307
4308 /* Synchronize */
4309 RxAcquirePagingIoResource(RxContext, Fcb);
4310 RxReleasePagingIoResource(RxContext, Fcb);
4311
4312 /* And purge */
4314 &FlushOffset, WriteLength, FALSE);
4315 }
4316 }
4317
4318 /* If not paging IO, check if write is allowed */
4319 if (!PagingIo)
4320 {
4322 {
4324 }
4325 }
4326
4327 /* Get file sizes */
4328 ValidDataLength = Fcb->Header.ValidDataLength.QuadPart;
4330 ASSERT(ValidDataLength <= FileSize);
4331
4332 /* If paging IO, we cannot write past file size
4333 * so fix write length if needed
4334 */
4335 if (PagingIo)
4336 {
4337 if (ByteOffset.QuadPart >= FileSize)
4338 {
4340 }
4341
4342 if (WriteLength > FileSize - ByteOffset.QuadPart)
4343 {
4344 WriteLength = FileSize - ByteOffset.QuadPart;
4345 }
4346 }
4347
4348 /* If we're being called by the lazywrite */
4349 if (Fcb->Specific.Fcb.LazyWriteThread == PsGetCurrentThread())
4350 {
4351 CalledByLazyWriter = TRUE;
4352
4353 /* Fail if we're beyong VDL */
4355 {
4356 if ((ByteOffset.QuadPart + WriteLength > ValidDataLength) &&
4357 (ByteOffset.QuadPart < FileSize))
4358 {
4359 if (ByteOffset.QuadPart + WriteLength > ((ValidDataLength + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
4360 {
4362 }
4363 }
4364 }
4365 }
4366
4367 /* If that's a recursive synchronous page write */
4370 {
4371 PIRP TopIrp;
4372
4373 /* Check the top level IRP on the FastIO path */
4374 TopIrp = RxGetTopIrpIfRdbssIrp();
4375 if (TopIrp != NULL && (ULONG_PTR)TopIrp > FSRTL_FAST_IO_TOP_LEVEL_IRP)
4376 {
4377 PIO_STACK_LOCATION IrpStack;
4378
4379 ASSERT(NodeType(TopIrp) == IO_TYPE_IRP);
4380
4381 /* If the top level IRP was a cached write for this file, keep track */
4382 IrpStack = IoGetCurrentIrpStackLocation(TopIrp);
4383 if (IrpStack->MajorFunction == IRP_MJ_WRITE &&
4384 IrpStack->FileObject->FsContext == FileObject->FsContext)
4385 {
4386 RecursiveWriteThrough = TRUE;
4387 SetFlag(RxContext->Flags, RX_CONTEXT_FLAG_WRITE_THROUGH);
4388 }
4389 }
4390 }
4391
4392 /* Now, deal with file size and VDL */
4393 if (!CalledByLazyWriter && !RecursiveWriteThrough &&
4394 (WriteToEof || ByteOffset.QuadPart + WriteLength > ValidDataLength))
4395 {
4396 /* Not sync? Let's make it sync, just the time we extended */
4397 if (!Sync)
4398 {
4399 CanWait = TRUE;
4400 SetFlag(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
4401 ClearFlag(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION);
4402 Sync = TRUE;
4403
4404 /* Keep track we'll have to switch back to async */
4405 if (NoCache)
4406 {
4407 SwitchBackToAsync = TRUE;
4408 }
4409 }
4410
4411 /* Release all the locks */
4412 RxWriteReleaseResources(RxContext, 0);
4413
4414 /* Acquire exclusive */
4415 Status = RxAcquireExclusiveFcb(RxContext, Fcb);
4417 {
4418 PostIrp = TRUE;
4419 DPRINT1("Failed to acquire lock for extension!\n");
4421 }
4422
4423 if (Status != STATUS_SUCCESS)
4424 {
4426 }
4427
4428 RxContext->FcbResourceAcquired = TRUE;
4429
4431
4432 /* Get the sizes again, to be sure they didn't change in the meantime */
4433 ValidDataLength = Fcb->Header.ValidDataLength.QuadPart;
4435 ASSERT(ValidDataLength <= FileSize);
4436
4437 /* Check we can switch back to async? */
4438 if ((SwitchBackToAsync && Fcb->NonPaged->SectionObjectPointers.DataSectionObject != NULL) ||
4439 (ByteOffset.QuadPart + WriteLength > FileSize) || RxNoAsync)
4440 {
4441 SwitchBackToAsync = FALSE;
4442 }
4443
4444 /* If paging IO, check we don't try to extend the file */
4445 if (PagingIo)
4446 {
4447 if (ByteOffset.QuadPart >= FileSize)
4448 {
4450 }
4451
4452 if (WriteLength > FileSize - ByteOffset.QuadPart)
4453 {
4454 WriteLength = FileSize - ByteOffset.QuadPart;
4455 }
4456 }
4457 }
4458
4459 /* Save our initial sizes for potential rollback */
4460 InitialFileSize = FileSize;
4461 InitialValidDataLength = ValidDataLength;
4462 /* If writing to EOF, update byte offset with file size */
4463 if (WriteToEof)
4464 {
4465 ByteOffset.QuadPart = FileSize;
4466 }
4467
4468 /* Check again whether we're allowed to write */
4469 if (!PagingIo)
4470 {
4471 if (!FsRtlCheckLockForWriteAccess(&Fcb->Specific.Fcb.FileLock, Irp ))
4472 {
4474 }
4475
4476 /* Do we have to extend? */
4477 if (NormalFile && (ByteOffset.QuadPart + WriteLength > FileSize))
4478 {
4479 DPRINT("Need to extend file\n");
4480 ExtendingFile = TRUE;
4482 }
4483 }
4484
4485 /* Let's start to extend */
4486 if (ExtendingFile)
4487 {
4488 /* If we're past allocating, inform mini-rdr */
4489 FileSize = ByteOffset.QuadPart + WriteLength;
4490 if (FileSize > Fcb->Header.AllocationSize.QuadPart)
4491 {
4492 LARGE_INTEGER NewAllocationSize;
4493
4494 DPRINT("Extending %p\n", RxContext);
4495
4496 if (NoCache)
4497 {
4498 C_ASSERT(sizeof(LONGLONG) == sizeof(LARGE_INTEGER));
4499 MINIRDR_CALL(Status, RxContext, Fcb->MRxDispatch, MRxExtendForNonCache,
4500 (RxContext, (PLARGE_INTEGER)&FileSize, &NewAllocationSize));
4501 }
4502 else
4503 {
4504 C_ASSERT(sizeof(LONGLONG) == sizeof(LARGE_INTEGER));
4505 MINIRDR_CALL(Status, RxContext, Fcb->MRxDispatch, MRxExtendForCache,
4506 (RxContext, (PLARGE_INTEGER)&FileSize, &NewAllocationSize));
4507 }
4508
4509 if (!NT_SUCCESS(Status))
4510 {
4512 }
4513
4514 if (FileSize > NewAllocationSize.QuadPart)
4515 {
4516 NewAllocationSize.QuadPart = FileSize;
4517 }
4518
4519 /* And update FCB */
4520 Fcb->Header.AllocationSize.QuadPart = NewAllocationSize.QuadPart;
4521 }
4522
4523 /* Set the new sizes */
4526
4527 /* And inform Cc */
4529 {
4531 }
4532 }
4533
4534 /* Do we have to extend VDL? */
4535 if (!CalledByLazyWriter && !RecursiveWriteThrough)
4536 {
4537 if (WriteToEof || ByteOffset.QuadPart + WriteLength > ValidDataLength)
4538 {
4539 ExtendingValidData = TRUE;
4541 }
4542 }
4543
4544 /* If none cached write */
4545 if (PagingIo || NoCache || !RxWriteCacheingAllowed(Fcb, SrvOpen))
4546 {
4547 /* Switch back to async, if asked to */
4548 if (SwitchBackToAsync)
4549 {
4550 CanWait = FALSE;
4551 Sync = FALSE;
4552
4553 ClearFlag(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
4554 SetFlag(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION);
4555 }
4556
4557 /* If not synchronous, keep track of writes to be finished */
4558 if (!Sync)
4559 {
4561 {
4565 }
4566
4568 1,
4569 &RxStrucSupSpinLock) == 0)
4570 {
4572 }
4573
4574 UnwindOutstandingAsync = TRUE;
4575 LowIoContext->ParamsFor.ReadWrite.NonPagedFcb = Fcb->NonPaged;
4576 }
4577
4578 /* Set our LOWIO_CONTEXT information */
4579 LowIoContext->ParamsFor.ReadWrite.ByteOffset = ByteOffset.QuadPart;
4580 LowIoContext->ParamsFor.ReadWrite.ByteCount = WriteLength;
4581
4583
4584 /* We have to be locked */
4585 ASSERT(RxContext->FcbResourceAcquired || RxContext->FcbPagingIoResourceAcquired);
4586
4587 /* Update thread ID if we're in FSP */
4588 if (InFsp)
4589 {
4590 LowIoContext->ResourceThreadId = (ULONG_PTR)RxContext | 3;
4591
4592 if (RxContext->FcbResourceAcquired)
4593 {
4594 ExSetResourceOwnerPointer(Fcb->Header.Resource, (PVOID)((ULONG_PTR)RxContext | 3));
4595 }
4596
4597 if (RxContext->FcbPagingIoResourceAcquired)
4598 {
4599 ExSetResourceOwnerPointer(Fcb->Header.PagingIoResource, (PVOID)((ULONG_PTR)RxContext | 3));
4600 }
4601
4602 ResourceOwnerSet = TRUE;
4603 }
4604
4605 /* And perform the write */
4606 Status = RxLowIoWriteShell(RxContext);
4607
4609
4610 /* Not outstanding write anymore */
4611 if (UnwindOutstandingAsync && Status == STATUS_PENDING)
4612 {
4613 UnwindOutstandingAsync = FALSE;
4614 }
4615 }
4616 /* Cached write */
4617 else
4618 {
4619 /* If cache wasn't enabled yet, do it */
4620 if (FileObject->PrivateCacheMap == NULL)
4621 {
4623 {
4625 }
4626
4628
4631
4632 CcSetReadAheadGranularity(FileObject, NetRoot->DiskParameters.ReadAheadGranularity);
4633 }
4634
4635 /* If that's a MDL backed write */
4636 if (BooleanFlagOn(RxContext->MinorFunction, IRP_MN_MDL))
4637 {
4638 /* Shouldn't happen */
4639 ASSERT(FALSE);
4640 ASSERT(CanWait);
4641
4642 /* Perform it, though */
4644 &Irp->MdlAddress, &Irp->IoStatus);
4645
4646 Status = Irp->IoStatus.Status;
4647 }
4648 else
4649 {
4650 PVOID SystemBuffer;
4651 ULONG BreakpointsSave;
4652
4653 /* Map the user buffer */
4654 SystemBuffer = RxNewMapUserBuffer(RxContext);
4655 if (SystemBuffer == NULL)
4656 {
4658 }
4659
4660 RxSaveAndSetExceptionNoBreakpointFlag(RxContext, BreakpointsSave);
4661
4663
4664 /* And deal with Cc */
4666 SystemBuffer))
4667 {
4668 RxRestoreExceptionNoBreakpointFlag(RxContext, BreakpointsSave);
4669
4671
4672 DPRINT1("CcCopyWrite failed for: %p %I64d %d %lx\n",
4673 FileObject, Fcb->Header.FileSize.QuadPart, WriteLength, Status);
4674
4675 PostIrp = TRUE;
4676 }
4677 else
4678 {
4679 Irp->IoStatus.Status = STATUS_SUCCESS;
4680 Irp->IoStatus.Information = WriteLength;
4681
4682 RxRestoreExceptionNoBreakpointFlag(RxContext, BreakpointsSave);
4683
4685
4686 DPRINT("CcCopyWrite succeed for: %p %I64d %d %lx\n",
4687 FileObject, Fcb->Header.FileSize.QuadPart, WriteLength, Status);
4688 }
4689 }
4690 }
4691
4692try_exit: NOTHING;
4693
4694 /* If we've to post the IRP */
4695 if (PostIrp)
4696 {
4697 /* Reset the file size if required */
4698 if (ExtendingFile && !IsPipe)
4699 {
4700 ASSERT(RxWriteCacheingAllowed(Fcb, SrvOpen));
4701 ASSERT(Fcb->Header.PagingIoResource != NULL);
4702
4703 RxAcquirePagingIoResource(RxContext, Fcb);
4704 RxSetFileSizeWithLock(Fcb, &InitialFileSize);
4705 RxReleasePagingIoResource(RxContext, Fcb);
4706
4707 if (FileObject->SectionObjectPointer->SharedCacheMap != NULL)
4708 {
4710 }
4711 }
4712
4713 InterlockedIncrement((volatile long *)&RxContext->ReferenceCount);
4714 ContextReferenced = TRUE;
4715
4716 /* Release locks */
4717 ASSERT(!ResourceOwnerSet);
4718 RxWriteReleaseResources(RxContext, ResourceOwnerSet);
4719
4720#ifdef RDBSS_TRACKER
4721 ASSERT(RxContext->AcquireReleaseFcbTrackerX == 0);
4722#endif
4723
4724 /* And post the request */
4725 Status = RxFsdPostRequest(RxContext);
4726 }
4727 else
4728 {
4729 if (!IsPipe)
4730 {
4731 /* Update FILE_OBJECT if synchronous write succeed */
4732 if (!PagingIo)
4733 {
4735 {
4736 FileObject->CurrentByteOffset.QuadPart = ByteOffset.QuadPart + Irp->IoStatus.Information;
4737 }
4738 }
4739
4740 /* If write succeed, ,also update FILE_OBJECT flags */
4742 {
4743 /* File was modified */
4744 if (!PagingIo)
4745 {
4747 }
4748
4749 /* If was even extended */
4750 if (ExtendingFile)
4751 {
4753 }
4754
4755 /* If VDL was extended, update FCB and inform Cc */
4756 if (ExtendingValidData)
4757 {
4758 LONGLONG LastOffset;
4759
4760 LastOffset = ByteOffset.QuadPart + Irp->IoStatus.Information;
4761 if (FileSize < LastOffset)
4762 {
4763 LastOffset = FileSize;
4764 }
4765
4766 Fcb->Header.ValidDataLength.QuadPart = LastOffset;
4767
4768 if (NoCache && CcIsFileCached(FileObject))
4769 {
4771 }
4772 }
4773 }
4774 }
4775 }
4776 }
4778 {
4779 /* Finally, if we failed while extension was required */
4780 if (_SEH2_AbnormalTermination() && (ExtendingFile || ExtendingValidData))
4781 {
4782 /* Rollback! */
4783 if (!IsPipe)
4784 {
4785 ASSERT(Fcb->Header.PagingIoResource != NULL);
4786
4787 RxAcquirePagingIoResource(RxContext, Fcb);
4788 RxSetFileSizeWithLock(Fcb, &InitialFileSize);
4789 Fcb->Header.ValidDataLength.QuadPart = InitialValidDataLength;
4790 RxReleasePagingIoResource(RxContext, Fcb);
4791
4792 if (FileObject->SectionObjectPointer->SharedCacheMap != NULL)
4793 {
4795 }
4796 }
4797 }
4798
4799 /* One async write less */
4800 if (UnwindOutstandingAsync)
4801 {
4802 ASSERT(!IsPipe);
4803
4806 }
4807
4808 /* And now, cleanup everything */
4809 if (_SEH2_AbnormalTermination() || Status != STATUS_PENDING || PostIrp)
4810 {
4811 /* If we didn't post, release every lock (for posting, it's already done) */
4812 if (!PostIrp)
4813 {
4814 RxWriteReleaseResources(RxContext, ResourceOwnerSet);
4815 }
4816
4817 /* If the context was referenced - posting, dereference it */
4818 if (ContextReferenced)
4819 {
4821 }
4822
4823 /* If that's a pipe operation, resume any blocked one */
4824 if (!PostIrp)
4825 {
4826 if (BooleanFlagOn(RxContext->FlagsForLowIo, RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION))
4827 {
4828 RxResumeBlockedOperations_Serially(RxContext, &Fobx->Specific.NamedPipe.ReadSerializationQueue);
4829 }
4830 }
4831
4832 /* Sanity check for write */
4833 if (Status == STATUS_SUCCESS)
4834 {
4835 ASSERT(Irp->IoStatus.Information <= Stack->Parameters.Write.Length);
4836 }
4837 }
4838 /* Just dereference our context */
4839 else
4840 {
4841 ASSERT(!Sync);
4843 }
4844 }
4845 _SEH2_END;
4846
4847#undef _SEH2_TRY_RETURN
4848
4849 return Status;
4850}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
ULONG WriteLength
Definition: CcPinRead_drv.c:40
NodeType
Definition: Node.h:6
VOID NTAPI CcPrepareMdlWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus)
Definition: mdlsup.c:91
#define CcGetFileSizePointer(FO)
Definition: ccfuncs.h:389
Definition: Header.h:9
USHORT NODE_TYPE_CODE
Definition: nodetype.h:22
#define ULONG_PTR
Definition: config.h:101
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
#define FILE_WRITE_TO_END_OF_FILE
Definition: ext2fs.h:278
VOID RxSetFileSizeWithLock(_Inout_ PFCB Fcb, _In_ PLONGLONG FileSize)
struct _FOBX * PFOBX
#define FOBX_FLAG_MARKED_AS_DORMANT
Definition: fcb.h:299
BOOLEAN NTAPI FsRtlCheckLockForWriteAccess(IN PFILE_LOCK FileLock, IN PIRP Irp)
Definition: filelock.c:710
#define FSRTL_FLAG_USER_MAPPED_FILE
Definition: fsrtltypes.h:50
#define FSRTL_FAST_IO_TOP_LEVEL_IRP
Definition: fsrtltypes.h:62
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:386
ULONG NTAPI ExInterlockedAddUlong(IN OUT PULONG Addend, IN ULONG Increment, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:88
#define C_ASSERT(e)
Definition: intsafe.h:73
#define LOWIO_READWRITEFLAG_EXTENDING_VDL
Definition: mrx.h:327
#define LOWIO_READWRITEFLAG_EXTENDING_FILESIZE
Definition: mrx.h:326
@ LOWIO_OP_WRITE
Definition: mrx.h:235
@ NotificationEvent
BOOLEAN NTAPI CcCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN PVOID Buffer)
Definition: copysup.c:129
BOOLEAN NTAPI CcCanIWrite(IN PFILE_OBJECT FileObject, IN ULONG BytesToWrite, IN BOOLEAN Wait, IN UCHAR Retrying)
Definition: copysup.c:214
VOID NTAPI CcDeferWrite(IN PFILE_OBJECT FileObject, IN PCC_POST_DEFERRED_WRITE PostRoutine, IN PVOID Context1, IN PVOID Context2, IN ULONG BytesToWrite, IN BOOLEAN Retrying)
Definition: copysup.c:225
VOID RxPrePostIrp(IN PVOID Context, IN PIRP Irp)
Definition: rdbss.c:7906
PIRP RxGetTopIrpIfRdbssIrp(VOID)
Definition: rdbss.c:6845
VOID NTAPI RxAddToWorkque(IN PRX_CONTEXT RxContext, IN PIRP Irp)
Definition: rdbss.c:772
BOOLEAN RxNoAsync
Definition: rdbss.c:614
NTSTATUS RxLowIoWriteShell(IN PRX_CONTEXT RxContext)
Definition: rdbss.c:7386
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define RxRestoreExceptionNoBreakpointFlag(R, F)
Definition: rxcontx.h:358
@ RX_CONTEXT_FLAG_RECURSIVE_CALL
Definition: rxcontx.h:285
@ RX_CONTEXT_FLAG_NO_PREPOSTING_NEEDED
Definition: rxcontx.h:302
@ RX_CONTEXT_FLAG_DEFERRED_WRITE
Definition: rxcontx.h:287
#define RxSaveAndSetExceptionNoBreakpointFlag(R, F)
Definition: rxcontx.h:357
#define RxAcquirePagingIoResourceShared(RxContext, Fcb, Flag)
Definition: rxprocs.h:242
#define RxConvertToSharedFcb(R, F)
Definition: rxprocs.h:337
KEVENT TheActualEvent
Definition: fcb.h:94
PKEVENT OutstandingAsyncEvent
Definition: fatstruc.h:743
ULONG OutstandingAsyncWrites
Definition: fatstruc.h:737
volatile ULONG WriteOperations
Definition: rxstruc.h:115
volatile ULONG RandomWriteOperations
Definition: rxstruc.h:117
LARGE_INTEGER NonPagingWriteBytesRequested
Definition: rxstruc.h:111
LARGE_INTEGER PagingWriteBytesRequested
Definition: rxstruc.h:110
LARGE_INTEGER CacheWriteBytesRequested
Definition: rxstruc.h:112
VOID(NTAPI * PCC_POST_DEFERRED_WRITE)(_In_ PVOID Context1, _In_ PVOID Context2)
Definition: cctypes.h:66
#define IO_TYPE_IRP
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define FO_FILE_SIZE_CHANGED
Definition: iotypes.h:1789
#define SL_WRITE_THROUGH
Definition: iotypes.h:1824
#define IRP_SYNCHRONOUS_PAGING_IO

◆ RxCompleteMdl()

NTSTATUS NTAPI RxCompleteMdl ( IN PRX_CONTEXT  RxContext)

Definition at line 4857 of file rdbss.c.

4859{
4860 PIRP Irp;
4863
4864#define BugCheckFileId RDBSS_BUG_CHECK_CACHESUP
4865
4866 PAGED_CODE();
4867
4868 Irp = RxContext->CurrentIrp;
4869 Stack = RxContext->CurrentIrpSp;
4870 FileObject = Stack->FileObject;
4871
4872 /* We can only complete for IRP_MJ_READ and IRP_MJ_WRITE */
4873 switch (RxContext->MajorFunction)
4874 {
4875 /* Call the Cc function */
4876 case IRP_MJ_READ:
4877 CcMdlReadComplete(FileObject, Irp->MdlAddress);
4878 break;
4879
4880 case IRP_MJ_WRITE:
4881 /* If here, we can wait */
4882 ASSERT(BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT));
4883
4884 /* Call the Cc function */
4885 CcMdlWriteComplete(FileObject, &Stack->Parameters.Write.ByteOffset, Irp->MdlAddress);
4886
4887 Irp->IoStatus.Status = STATUS_SUCCESS;
4888 break;
4889
4890 default:
4891 DPRINT1("Invalid major for RxCompleteMdl: %d\n", RxContext->MajorFunction);
4892 RxBugCheck(RxContext->MajorFunction, 0, 0);
4893 break;
4894 }
4895
4896 /* MDL was freed */
4897 Irp->MdlAddress = NULL;
4898
4899 /* And complete the IRP */
4901
4902#undef BugCheckFileId
4903
4904 return STATUS_SUCCESS;
4905}
VOID NTAPI CcMdlReadComplete(IN PFILE_OBJECT FileObject, IN PMDL MdlChain)
Definition: mdlsup.c:75
VOID NTAPI CcMdlWriteComplete(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain)
Definition: mdlsup.c:102
#define IRP_MJ_READ
Definition: rdpdr.c:46

Referenced by RxFsdCommonDispatch().

◆ RxConjureOriginalName()

VOID RxConjureOriginalName ( PFCB  Fcb,
PFOBX  Fobx,
PULONG  ActualNameLength,
PWCHAR  OriginalName,
PLONG  LengthRemaining,
RX_NAME_CONJURING_METHODS  NameConjuringMethod 
)

Definition at line 4911 of file rdbss.c.

4918{
4919 PWSTR Prefix, Name;
4920 PV_NET_ROOT VNetRoot;
4921 USHORT PrefixLength, NameLength, ToCopy;
4922
4923 PAGED_CODE();
4924
4925 VNetRoot = Fcb->VNetRoot;
4926 /* We will use the prefix contained in NET_ROOT, if we don't have
4927 * a V_NET_ROOT, or if it wasn't null deviced or if we already have
4928 * a UNC path */
4929 if (VNetRoot == NULL || VNetRoot->PrefixEntry.Prefix.Buffer[1] != L';' ||
4930 BooleanFlagOn(Fobx->Flags, FOBX_FLAG_UNC_NAME))
4931 {
4932 Prefix = ((PNET_ROOT)Fcb->pNetRoot)->PrefixEntry.Prefix.Buffer;
4933 PrefixLength = ((PNET_ROOT)Fcb->pNetRoot)->PrefixEntry.Prefix.Length;
4934 NameLength = 0;
4935
4936 /* In that case, keep track that we will have a prefix as buffer */
4937 NameConjuringMethod = VNetRoot_As_Prefix;
4938 }
4939 else
4940 {
4941 ASSERT(NodeType(VNetRoot) == RDBSS_NTC_V_NETROOT);
4942
4943 /* Otherwise, return the prefix from our V_NET_ROOT */
4944 Prefix = VNetRoot->PrefixEntry.Prefix.Buffer;
4945 PrefixLength = VNetRoot->PrefixEntry.Prefix.Length;
4946 NameLength = VNetRoot->NamePrefix.Length;
4947
4948 /* If we want a UNC path, skip potential device */
4949 if (NameConjuringMethod == VNetRoot_As_UNC_Name)
4950 {
4951 do
4952 {
4953 ++Prefix;
4954 PrefixLength -= sizeof(WCHAR);
4955 } while (PrefixLength > 0 && Prefix[0] != L'\\');
4956 }
4957 }
4958
4959 /* If we added an extra backslash, skip it */
4961 {
4962 NameLength += sizeof(WCHAR);
4963 }
4964
4965 /* If we're asked for a drive letter, skip the prefix */
4966 if (NameConjuringMethod == VNetRoot_As_DriveLetter)
4967 {
4968 PrefixLength = 0;
4969
4970 /* And make sure we arrive at a backslash */
4971 if (Fcb->FcbTableEntry.Path.Length > NameLength &&
4972 Fcb->FcbTableEntry.Path.Buffer[NameLength / sizeof(WCHAR)] != L'\\')
4973 {
4974 NameLength -= sizeof(WCHAR);
4975 }
4976 }
4977 else
4978 {
4979 /* Prepare to copy the prefix, make sure not to overflow */
4980 if (*LengthRemaining >= PrefixLength)
4981 {
4982 /* Copy everything */
4983 ToCopy = PrefixLength;
4984 *LengthRemaining = *LengthRemaining - PrefixLength;
4985 }
4986 else
4987 {
4988 /* Copy as much as we can */
4989 ToCopy = *LengthRemaining;
4990 /* And return failure */
4991 *LengthRemaining = -1;
4992 }
4993
4994 /* Copy the prefix */
4995 RtlCopyMemory(OriginalName, Prefix, ToCopy);
4996 }
4997
4998 /* Do we have a name to copy now? */
4999 if (Fcb->FcbTableEntry.Path.Length > NameLength)
5000 {
5001 ToCopy = Fcb->FcbTableEntry.Path.Length - NameLength;
5003 }
5004 else
5005 {
5006 /* Just use slash for now */
5007 ToCopy = sizeof(WCHAR);
5008 NameLength = 0;
5009 Name = L"\\";
5010 }
5011
5012 /* Total length we will have in the output buffer (if everything is alright) */
5013 *ActualNameLength = ToCopy + PrefixLength;
5014 /* If we still have room to write data */
5015 if (*LengthRemaining != -1)
5016 {
5017 /* If we can copy everything, it's fine! */
5018 if (*LengthRemaining > ToCopy)
5019 {
5020 *LengthRemaining = *LengthRemaining - ToCopy;
5021 }
5022 /* Otherwise, copy as much as possible, and return failure */
5023 else
5024 {
5025 ToCopy = *LengthRemaining;
5026 *LengthRemaining = -1;
5027 }
5028
5029 /* Copy name after the prefix */
5030 RtlCopyMemory(Add2Ptr(OriginalName, PrefixLength),
5031 Add2Ptr(Name, NameLength), ToCopy);
5032 }
5033}
struct NameRec_ * Name
Definition: cdprocs.h:460
#define FOBX_FLAG_UNC_NAME
Definition: fcb.h:297
#define FCB_STATE_ADDEDBACKSLASH
Definition: fcb.h:228
@ VNetRoot_As_DriveLetter
Definition: rxprocs.h:82
@ VNetRoot_As_Prefix
Definition: rxprocs.h:80
@ VNetRoot_As_UNC_Name
Definition: rxprocs.h:81
PV_NET_ROOT VNetRoot
Definition: fcb.h:139
UNICODE_STRING Prefix
Definition: prefix.h:53
void * Buffer
Definition: sprintf.c:453
UNICODE_STRING NamePrefix
Definition: fcb.h:73
RX_PREFIX_ENTRY PrefixEntry
Definition: fcb.h:72
uint16_t * PWSTR
Definition: typedefs.h:56
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1630

Referenced by RxQueryNameInfo().

◆ RxCopyCreateParameters()

VOID RxCopyCreateParameters ( IN PRX_CONTEXT  RxContext)

Definition at line 5039 of file rdbss.c.

5041{
5042 PIRP Irp;
5043 PVOID DfsContext;
5046 PDFS_NAME_CONTEXT DfsNameContext;
5047 PIO_SECURITY_CONTEXT SecurityContext;
5048
5049 Irp = RxContext->CurrentIrp;
5050 Stack = RxContext->CurrentIrpSp;
5051 FileObject = Stack->FileObject;
5052 SecurityContext = Stack->Parameters.Create.SecurityContext;
5053
5054 RxContext->Create.NtCreateParameters.SecurityContext = SecurityContext;
5055 if (SecurityContext->AccessState != NULL && SecurityContext->AccessState->SecurityDescriptor != NULL)
5056 {
5057 RxContext->Create.SdLength = RtlLengthSecurityDescriptor(SecurityContext->AccessState->SecurityDescriptor);
5058 DPRINT("SD Ctxt: %p, Length: %lx\n", RxContext->Create.NtCreateParameters.SecurityContext,
5059 RxContext->Create.SdLength);
5060 }
5061 if (SecurityContext->SecurityQos != NULL)
5062 {
5063 RxContext->Create.NtCreateParameters.ImpersonationLevel = SecurityContext->SecurityQos->ImpersonationLevel;
5064 }
5065 else
5066 {
5067 RxContext->Create.NtCreateParameters.ImpersonationLevel = SecurityImpersonation;
5068 }
5069 RxContext->Create.NtCreateParameters.DesiredAccess = SecurityContext->DesiredAccess;
5070
5071 RxContext->Create.NtCreateParameters.AllocationSize.QuadPart = Irp->Overlay.AllocationSize.QuadPart;
5072 RxContext->Create.NtCreateParameters.FileAttributes = Stack->Parameters.Create.FileAttributes & FILE_ATTRIBUTE_VALID_FLAGS;
5073 RxContext->Create.NtCreateParameters.ShareAccess = Stack->Parameters.Create.ShareAccess & FILE_SHARE_VALID_FLAGS;
5074 RxContext->Create.NtCreateParameters.Disposition = (Stack->Parameters.Create.Options >> 24) & 0x000000FF;
5075 RxContext->Create.NtCreateParameters.CreateOptions = Stack->Parameters.Create.Options & 0xFFFFFF;
5076
5077 DfsContext = FileObject->FsContext2;
5078 DfsNameContext = FileObject->FsContext;
5079 RxContext->Create.NtCreateParameters.DfsContext = DfsContext;
5080 RxContext->Create.NtCreateParameters.DfsNameContext = DfsNameContext;
5081 ASSERT(DfsContext == NULL || DfsContext == UIntToPtr(DFS_OPEN_CONTEXT) ||
5082 DfsContext == UIntToPtr(DFS_DOWNLEVEL_OPEN_CONTEXT) ||
5083 DfsContext == UIntToPtr(DFS_CSCAGENT_NAME_CONTEXT) ||
5084 DfsContext == UIntToPtr(DFS_USER_NAME_CONTEXT));
5085 ASSERT(DfsNameContext == NULL || DfsNameContext->NameContextType == DFS_OPEN_CONTEXT ||
5086 DfsNameContext->NameContextType == DFS_DOWNLEVEL_OPEN_CONTEXT ||
5087 DfsNameContext->NameContextType == DFS_CSCAGENT_NAME_CONTEXT ||
5088 DfsNameContext->NameContextType == DFS_USER_NAME_CONTEXT);
5089 FileObject->FsContext2 = NULL;
5090 FileObject->FsContext = NULL;
5091
5092 RxContext->pFcb = NULL;
5093 RxContext->Create.ReturnedCreateInformation = 0;
5094
5095 /* if we stripped last \, it has to be a directory! */
5097 {
5098 SetFlag(RxContext->Create.NtCreateParameters.CreateOptions, FILE_DIRECTORY_FILE);
5099 }
5100
5101 RxContext->Create.EaLength = Stack->Parameters.Create.EaLength;
5102 if (RxContext->Create.EaLength == 0)
5103 {
5104 RxContext->Create.EaBuffer = NULL;
5105 }
5106 else
5107 {
5108 RxContext->Create.EaBuffer = Irp->AssociatedIrp.SystemBuffer;
5109 DPRINT("EA Buffer: %p, Length: %lx\n", Irp->AssociatedIrp.SystemBuffer, RxContext->Create.EaLength);
5110 }
5111}
#define UIntToPtr(ui)
Definition: basetsd.h:90
#define DFS_DOWNLEVEL_OPEN_CONTEXT
Definition: dfs.h:7
#define DFS_USER_NAME_CONTEXT
Definition: dfs.h:9
#define DFS_CSCAGENT_NAME_CONTEXT
Definition: dfs.h:8
#define DFS_OPEN_CONTEXT
Definition: dfs.h:6
NTSYSAPI ULONG WINAPI RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR)
@ SecurityImpersonation
Definition: lsa.idl:57
#define FILE_ATTRIBUTE_VALID_FLAGS
Definition: nt_native.h:714
PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: setypes.h:235
LONG NameContextType
Definition: dfs.h:14
PACCESS_STATE AccessState
Definition: iotypes.h:2867
PSECURITY_QUALITY_OF_SERVICE SecurityQos
Definition: iotypes.h:2866
ACCESS_MASK DesiredAccess
Definition: iotypes.h:2868
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: lsa.idl:65

Referenced by RxCommonCreate().

◆ RxCreateFromNetRoot()

NTSTATUS RxCreateFromNetRoot ( PRX_CONTEXT  Context,
PUNICODE_STRING  NetRootName 
)

Definition at line 5114 of file rdbss.c.

5117{
5118 PFCB Fcb;
5120 PNET_ROOT NetRoot;
5125
5126 PAGED_CODE();
5127
5128 /* Validate that the context is consistent */
5129 if (Context->Create.pNetRoot == NULL)
5130 {
5132 }
5133
5134 NetRoot = (PNET_ROOT)Context->Create.pNetRoot;
5135 if (Context->RxDeviceObject != NetRoot->pSrvCall->RxDeviceObject)
5136 {
5138 }
5139
5140 if (Context->Create.NtCreateParameters.DfsContext == UIntToPtr(DFS_OPEN_CONTEXT) &&
5141 !BooleanFlagOn(NetRoot->pSrvCall->Flags, SRVCALL_FLAG_DFS_AWARE_SERVER))
5142 {
5144 }
5145
5146 if (Context->Create.NtCreateParameters.DfsContext == UIntToPtr(DFS_DOWNLEVEL_OPEN_CONTEXT) &&
5148 {
5150 }
5151
5152 Stack = Context->CurrentIrpSp;
5153 DesiredShareAccess = Stack->Parameters.Create.ShareAccess & FILE_SHARE_VALID_FLAGS;
5154 if (NetRoot->Type == NET_ROOT_PRINT)
5155 {
5157 }
5158
5159 DesiredAccess = Stack->Parameters.Create.SecurityContext->DesiredAccess & FILE_ALL_ACCESS;
5160
5161 /* Get file object */
5162 FileObject = Stack->FileObject;
5163
5164 /* Do we have to open target directory for renaming? */
5166 {
5167 DPRINT("Opening target directory\n");
5168
5169 /* If we have been asked for delete, try to purge first */
5170 if (BooleanFlagOn(Context->Create.NtCreateParameters.DesiredAccess, DELETE))
5171 {
5172 RxPurgeRelatedFobxs((PNET_ROOT)Context->Create.pVNetRoot->pNetRoot, Context,
5174 }
5175
5176 /* Create the FCB */
5177 Fcb = RxCreateNetFcb(Context, (PV_NET_ROOT)Context->Create.pVNetRoot, NetRootName);
5178 if (Fcb == NULL)
5179 {
5181 }
5182
5183 /* Fake it: it will be used only renaming */
5185 Context->Create.FcbAcquired = FALSE;
5186 Context->Create.NetNamePrefixEntry = NULL;
5187
5188 /* Assign it to the FO */
5189 FileObject->FsContext = Fcb;
5190
5191 /* If we have a FOBX already, check whether it's for DFS opening */
5192 if (Context->pFobx != NULL)
5193 {
5194 /* If so, reflect this in the FOBX */
5195 if (FileObject->FsContext2 == UIntToPtr(DFS_OPEN_CONTEXT))
5196 {
5197 SetFlag(Context->pFobx->Flags, FOBX_FLAG_DFS_OPEN);
5198 }
5199 else
5200 {
5201 ClearFlag(Context->pFobx->Flags, FOBX_FLAG_DFS_OPEN);
5202 }
5203 }
5204
5205 /* Acquire the FCB */
5207 if (Status != STATUS_SUCCESS)
5208 {
5209 return Status;
5210 }
5211
5212 /* Reference the FCB and release */
5215
5216 /* We're done! */
5217 return STATUS_SUCCESS;
5218 }
5219
5220 /* Try to find (or create) the FCB for the file */
5221 Status = RxFindOrCreateFcb(Context, NetRootName);
5222 Fcb = (PFCB)Context->pFcb;
5223 if (Fcb == NULL)
5224 {
5226 }
5227 if (!NT_SUCCESS(Status) || Fcb == NULL)
5228 {
5229 return Status;
5230 }
5231
5233 {
5234 Fcb->Header.NodeTypeCode = RDBSS_NTC_MAILSLOT;
5235 }
5236 else
5237 {
5239 }
5240
5241 /* If finding FCB worked (mailslot case), mark the FCB as good and quit */
5242 if (NT_SUCCESS(Status))
5243 {
5245 DPRINT("Transitioning FCB %lx Condition %lx\n", Fcb, Fcb->Condition);
5246 ++Fcb->OpenCount;
5248 return STATUS_SUCCESS;
5249 }
5250
5251 /* Not mailslot! */
5252 /* Check SA for conflict */
5253 if (Fcb->OpenCount > 0)
5254 {
5256 &Fcb->ShareAccess, FALSE, "early check per useropens", "EarlyPerUO");
5257 if (!NT_SUCCESS(Status))
5258 {
5260 return Status;
5261 }
5262 }
5263
5264 if (BooleanFlagOn(Context->Create.NtCreateParameters.CreateOptions, FILE_DELETE_ON_CLOSE) &&
5265 !BooleanFlagOn(Context->Create.NtCreateParameters.DesiredAccess, ~SYNCHRONIZE))
5266 {
5268 }
5269
5270 _SEH2_TRY
5271 {
5272 /* Find a SRV_OPEN that suits the opening */
5274 if (Status == STATUS_SUCCESS)
5275 {
5276 PFOBX Fobx;
5277 PSRV_OPEN SrvOpen;
5278
5279 SrvOpen = (PSRV_OPEN)Context->pRelevantSrvOpen;
5280 Fobx = (PFOBX)Context->pFobx;
5281 /* There are already opens, check for conflict */
5282 if (Fcb->OpenCount != 0)
5283 {
5286 FALSE, "second check per useropens",
5287 "2ndAccPerUO")))
5288 {
5289 ++SrvOpen->UncleanFobxCount;
5291
5293 }
5294 }
5295 else
5296 {
5297 if (NetRoot->Type != NET_ROOT_PIPE)
5298 {
5300 &Fcb->ShareAccess, "initial shareaccess setup", "InitShrAcc");
5301 }
5302 }
5303
5305
5306 /* No conflict? Set up SA */
5307 if (Fcb->OpenCount != 0 && NetRoot->Type != NET_ROOT_PIPE)
5308 {
5309 RxUpdateShareAccess(FileObject, &Fcb->ShareAccess, "update share access", "UpdShrAcc");
5310 }
5311
5312 ++Fcb->UncleanCount;
5314 {
5315 ++Fcb->UncachedUncleanCount;
5316 }
5317
5318 if (SrvOpen->UncleanFobxCount == 0 && Fcb->UncleanCount == 1 &&
5320 {
5322 }
5323
5324 /* No pending close, we're active */
5326
5327 ++Fcb->OpenCount;
5328 ++SrvOpen->UncleanFobxCount;
5329 ++SrvOpen->OpenCount;
5330 SrvOpen->ulFileSizeVersion = Fcb->ulFileSizeVersion;
5331
5332 if (BooleanFlagOn(Stack->Parameters.Create.Options, FILE_NO_INTERMEDIATE_BUFFERING))
5333 {
5336
5339
5341 }
5342
5343 /* Now, update SA for the SRV_OPEN */
5345
5346 if (BooleanFlagOn(Stack->Parameters.Create.Options, FILE_DELETE_ON_CLOSE))
5347 {
5348 SetFlag(Fobx->Flags, FOBX_FLAG_DELETE_ON_CLOSE);
5349 }
5350
5351 /* Update the FOBX info */
5352 if (Fobx != NULL)
5353 {
5354 if (Context->Create.pNetRoot->Type == NET_ROOT_PIPE)
5355 {
5357 }
5358
5359 if (Context->Create.pNetRoot->Type == NET_ROOT_PRINT ||
5360 Context->Create.pNetRoot->Type == NET_ROOT_PIPE)
5361 {
5362 Fobx->PipeHandleInformation = &Fobx->Specific.NamedPipe.PipeHandleInformation;
5363
5364 Fobx->Specific.NamedPipe.CollectDataTime.QuadPart = 0;
5365 Fobx->Specific.NamedPipe.CollectDataSize = Context->Create.pNetRoot->NamedPipeParameters.DataCollectionSize;
5366
5367 Fobx->Specific.NamedPipe.PipeHandleInformation.TypeOfPipe = Context->Create.PipeType;
5368 Fobx->Specific.NamedPipe.PipeHandleInformation.ReadMode = Context->Create.PipeReadMode;
5369 Fobx->Specific.NamedPipe.PipeHandleInformation.CompletionMode = Context->Create.PipeCompletionMode;
5370
5371 InitializeListHead(&Fobx->Specific.NamedPipe.ReadSerializationQueue);
5372 InitializeListHead(&Fobx->Specific.NamedPipe.WriteSerializationQueue);
5373 }
5374 }
5375
5377 }
5378 }
5380 {
5381 if (Fcb->OpenCount == 0)
5382 {
5383 if (Context->Create.FcbAcquired)
5384 {
5385 Context->Create.FcbAcquired = (RxDereferenceAndFinalizeNetFcb(Fcb,
5386 Context,
5387 FALSE,
5388 FALSE) == 0);
5389 if (!Context->Create.FcbAcquired)
5390 {
5391 RxTrackerUpdateHistory(Context, NULL, TRACKER_FCB_FREE, __LINE__, __FILE__, 0);
5392 }
5393 }
5394 }
5395 else
5396 {
5398 }
5399 }
5400 _SEH2_END;
5401
5402 return Status;
5403}
#define FCB_STATE_DELAY_CLOSE
Definition: fatstruc.h:1203
#define FCB_STATE_WRITECACHING_ENABLED
Definition: fcb.h:226
PFCB RxCreateNetFcb(_In_ PRX_CONTEXT RxContext, _In_ PV_NET_ROOT VNetRoot, _In_ PUNICODE_STRING Name)
#define FILE_NO_INTERMEDIATE_BUFFERING
Definition: from_kernel.h:28
#define FOBX_FLAG_DFS_OPEN
Definition: mrxfcb.h:181
#define SRVOPEN_FLAG_NO_BUFFERING_STATE_CHANGE
Definition: mrxfcb.h:139
#define SRVOPEN_FLAG_DONTUSE_WRITE_CACHING
Definition: mrxfcb.h:131
#define NETROOT_FLAG_DFS_AWARE_NETROOT
Definition: mrxfcb.h:45
#define SRVCALL_FLAG_DFS_AWARE_SERVER
Definition: mrxfcb.h:13
#define SYNCHRONIZE
Definition: nt_native.h:61
#define STATUS_BAD_NETWORK_PATH
Definition: ntstatus.h:426
#define STATUS_DFS_UNAVAILABLE
Definition: ntstatus.h:746
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:273
VOID RxUpdateShareAccessPerSrvOpens(IN PSRV_OPEN SrvOpen)
Definition: rdbss.c:9506
VOID RxSetupNetFileObject(PRX_CONTEXT RxContext)
Definition: rdbss.c:9147
NTSTATUS RxCollapseOrCreateSrvOpen(PRX_CONTEXT RxContext)
Definition: rdbss.c:1732
NTSTATUS RxFindOrCreateFcb(PRX_CONTEXT RxContext, PUNICODE_STRING NetRootName)
Definition: rdbss.c:5869
@ RX_CONTEXT_FLAG_CREATE_MAILSLOT
Definition: rxcontx.h:291
#define RxSetShareAccess(a1, a2, a3, a4, a5, a6)
Definition: rxprocs.h:580
NTSTATUS NTAPI RxChangeBufferingState(PSRV_OPEN SrvOpen, PVOID Context, BOOLEAN ComputeNewState)
Definition: rxce.c:783
#define RxCheckShareAccess(a1, a2, a3, a4, a5, a6, a7)
Definition: rxprocs.h:578
#define RxUpdateShareAccess(a1, a2, a3, a4)
Definition: rxprocs.h:581
#define ATTEMPT_FINALIZE_ON_PURGE
Definition: scavengr.h:46
RX_BLOCK_CONDITION Condition
Definition: fcb.h:147
ULONG ulFileSizeVersion
Definition: fcb.h:164
MRX_PIPE_HANDLE_INFORMATION PipeHandleInformation
Definition: fcb.h:330
#define FO_NAMED_PIPE
Definition: iotypes.h:1782

Referenced by RxCommonCreate().

◆ RxCreateTreeConnect()

NTSTATUS RxCreateTreeConnect ( IN PRX_CONTEXT  RxContext)

Definition at line 5409 of file rdbss.c.

5411{
5413 PV_NET_ROOT VNetRoot;
5416 NET_ROOT_TYPE NetRootType;
5417 UNICODE_STRING CanonicalName, RemainingName;
5418
5419 PAGED_CODE();
5420
5421 Stack = RxContext->CurrentIrpSp;
5422 FileObject = Stack->FileObject;
5423
5424 RtlInitEmptyUnicodeString(&CanonicalName, NULL, 0);
5425 /* As long as we don't know connection type, mark it wild */
5426 NetRootType = NET_ROOT_WILD;
5427 /* Get the type by parsing the name */
5428 Status = RxFirstCanonicalize(RxContext, &FileObject->FileName, &CanonicalName, &NetRootType);
5429 if (!NT_SUCCESS(Status))
5430 {
5431 return Status;
5432 }
5433
5434 RxContext->Create.ThisIsATreeConnectOpen = TRUE;
5435 RxContext->Create.TreeConnectOpenDeferred = FALSE;
5436 RtlInitEmptyUnicodeString(&RxContext->Create.TransportName, NULL, 0);
5437 RtlInitEmptyUnicodeString(&RxContext->Create.UserName, NULL, 0);
5438 RtlInitEmptyUnicodeString(&RxContext->Create.Password, NULL, 0);
5439 RtlInitEmptyUnicodeString(&RxContext->Create.UserDomainName, NULL, 0);
5440
5441 /* We don't handle EA - they come from DFS, don't care */
5442 if (Stack->Parameters.Create.EaLength > 0)
5443 {
5445 }
5446
5447 /* Mount if required */
5448 Status = RxFindOrConstructVirtualNetRoot(RxContext, &CanonicalName, NetRootType, &RemainingName);
5450 {
5451 RxScavengeVNetRoots(RxContext->RxDeviceObject);
5452 Status = RxFindOrConstructVirtualNetRoot(RxContext, &CanonicalName, NetRootType, &RemainingName);
5453 }
5454
5455 if (!NT_SUCCESS(Status))
5456 {
5457 return Status;
5458 }
5459
5460 /* Validate the rest of the name with mini-rdr */
5461 if (RemainingName.Length > 0)
5462 {
5463 MINIRDR_CALL(Status, RxContext,
5464 RxContext->Create.pNetRoot->pSrvCall->RxDeviceObject->Dispatch,
5465 MRxIsValidDirectory, (RxContext, &RemainingName));
5466 }
5467
5468 if (!NT_SUCCESS(Status))
5469 {
5470 return Status;
5471 }
5472
5473 VNetRoot = (PV_NET_ROOT)RxContext->Create.pVNetRoot;
5474 RxReferenceVNetRoot(VNetRoot);
5476 {
5478 }
5479
5480 FileObject->FsContext = &RxDeviceFCB;
5481 FileObject->FsContext2 = VNetRoot;
5482
5483 VNetRoot->ConstructionStatus = STATUS_SUCCESS;
5484 ++VNetRoot->NumberOfOpens;
5485
5486 /* Create is over - clear context */
5487 RxContext->Create.pSrvCall = NULL;
5488 RxContext->Create.pNetRoot = NULL;
5489 RxContext->Create.pVNetRoot = NULL;
5490
5491 return Status;
5492}
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:802
#define InterlockedCompareExchange
Definition: interlocked.h:104
#define STATUS_NETWORK_CREDENTIAL_CONFLICT
Definition: ntstatus.h:638
BOOLEAN RxScavengeVNetRoots(_In_ PRDBSS_DEVICE_OBJECT RxDeviceObject)
volatile LONG AdditionalReferenceForDeleteFsctlTaken
Definition: fcb.h:71

Referenced by RxCommonCreate().

◆ RxDebugControlCommand()

VOID NTAPI RxDebugControlCommand ( _In_ PSTR  ControlString)

Definition at line 5496 of file rdbss.c.

5498{
5500}

Referenced by RxGetRegistryParameters().

◆ RxDriverEntry()

NTSTATUS NTAPI RxDriverEntry ( IN PDRIVER_OBJECT  DriverObject,
IN PUNICODE_STRING  RegistryPath 
)

Definition at line 5504 of file rdbss.c.

5507{
5509 USHORT i, State = 0;
5510
5511 DPRINT("RxDriverEntry(%p, %p)\n", DriverObject, RegistryPath);
5512
5513 _SEH2_TRY
5514 {
5516
5517 RtlZeroMemory(&RxData, sizeof(RxData));
5519 RxData.NodeByteSize = sizeof(RxData);
5521
5524 RxDeviceFCB.spacer.NodeByteSize = sizeof(RxDeviceFCB);
5525
5528
5530
5533
5535 State = 2;
5536
5539
5541 if (!NT_SUCCESS(Status))
5542 {
5544 }
5545 State = 1;
5546
5548
5550
5553
5556
5561
5562 for (i = 0; i < RxMaximumWorkQueue; ++i)
5563 {
5567 }
5568
5570
5572
5575
5577 }
5579 {
5580 if (!NT_SUCCESS(Status))
5581 {
5584 }
5585 } _SEH2_END;
5586
5587 /* There are still bits to init - be consider it's fine for now */
5588#if 0
5591#else
5592 return STATUS_SUCCESS;
5593#endif
5594}
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
VOID NTAPI ExInitializeNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, IN PFREE_FUNCTION Free OPTIONAL, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth)
Definition: lookas.c:218
FAST_MUTEX RxLowIoPagingIoSyncMutex
Definition: rxce.c:136
PEPROCESS NTAPI IoGetCurrentProcess(VOID)
Definition: util.c:139
VOID NTAPI KeInitializeMutex(IN PKMUTEX Mutex, IN ULONG Level)
Definition: mutex.c:67
#define RxFreePool
Definition: ntrxdef.h:26
KMUTEX RxSerializationMutex
Definition: rdbss.c:609
VOID NTAPI RxGetRegistryParameters(IN PUNICODE_STRING RegistryPath)
Definition: rdbss.c:6695
NPAGED_LOOKASIDE_LIST RxContextLookasideList
Definition: rdbss.c:536
KMUTEX RxScavengerMutex
Definition: rdbss.c:608
VOID NTAPI RxInitUnwind(PDRIVER_OBJECT DriverObject, USHORT State)
Definition: rdbss.c:6991
UCHAR RxSpaceForTheWrappersDeviceObject[sizeof(*RxFileSystemDeviceObject)]
Definition: rdbss.c:610
NTSTATUS NTAPI RxInitializeRegistrationStructures(VOID)
Definition: rdbss.c:6964
NTSTATUS NTAPI RxInitializeLog(VOID)
Definition: rdbss.c:6942
VOID NTAPI RxInitializeDebugSupport(VOID)
Definition: rxce.c:4677
LIST_ENTRY RxIrpsList
Definition: rdbss.c:606
VOID NTAPI RxCheckFcbStructuresForAlignment(VOID)
Definition: rdbss.c:1447
VOID NTAPI RxReadRegistryParameters(VOID)
Definition: rdbss.c:8416
RDBSS_EXPORTS RxExports
Definition: rdbss.c:571
KSPIN_LOCK RxIrpsListSpinLock
Definition: rdbss.c:607
VOID NTAPI RxInitializeDispatchVectors(PDRIVER_OBJECT DriverObject)
Definition: rdbss.c:6894
FAST_MUTEX RxContextPerFileSerializationMutex
Definition: rxce.c:146
LIST_ENTRY RxSrvCalldownList
Definition: rxce.c:122
#define RX_IRPC_POOLTAG
Definition: rxpooltg.h:11
#define RxLogFailure(DO, Originator, Event, Status)
Definition: rxprocs.h:11
struct _RDBSS_DEVICE_OBJECT * PRDBSS_DEVICE_OBJECT
NTSTATUS NTAPI RxInitializeRxTimer(VOID)
Definition: rxce.c:4946
#define RxMaximumWorkQueue
Definition: rxtypes.h:6
NTSTATUS NTAPI RxInitializeDispatcher(VOID)
Definition: rxce.c:4688
#define RDBSS_NTC_DATA_HEADER
Definition: nodetype.h:55
FSRTL_ADVANCED_FCB_HEADER spacer
Definition: fcb.h:135
ERESOURCE Resource
Definition: rxstruc.h:39
PDRIVER_OBJECT DriverObject
Definition: rxstruc.h:29
PEPROCESS OurProcess
Definition: rxstruc.h:34
NODE_BYTE_SIZE NodeByteSize
Definition: rxstruc.h:28
NODE_TYPE_CODE NodeTypeCode
Definition: rxstruc.h:27
PRX_SPIN_LOCK pRxStrucSupSpinLock
Definition: rxstruc.h:14
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274

◆ RxFastIoCheckIfPossible()

BOOLEAN NTAPI RxFastIoCheckIfPossible ( PFILE_OBJECT  FileObject,
PLARGE_INTEGER  FileOffset,
ULONG  Length,
BOOLEAN  Wait,
ULONG  LockKey,
BOOLEAN  CheckForReadOperation,
PIO_STATUS_BLOCK  IoStatus,
PDEVICE_OBJECT  DeviceObject 
)

Definition at line 5630 of file rdbss.c.

5637{
5638 PFCB Fcb;
5639 PSRV_OPEN SrvOpen;
5640 LARGE_INTEGER LargeLength;
5641
5642 PAGED_CODE();
5643
5644 /* Get the FCB to validate it */
5645 Fcb = FileObject->FsContext;
5647 {
5648 DPRINT1("Not a file, FastIO not possible!\n");
5649 return FALSE;
5650 }
5651
5652 if (FileObject->DeletePending)
5653 {
5654 DPRINT1("File delete pending\n");
5655 return FALSE;
5656 }
5657
5658 /* If there's a pending write operation, deny fast operation */
5660 {
5661 DPRINT1("Write operations to be completed\n");
5662 return FALSE;
5663 }
5664
5665 /* Deny read on orphaned node */
5666 SrvOpen = (PSRV_OPEN)((PFOBX)FileObject->FsContext2)->pSrvOpen;
5667 if (BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_ORPHANED))
5668 {
5669 DPRINT1("SRV_OPEN orphaned\n");
5670 return FALSE;
5671 }
5672
5674 {
5675 DPRINT1("FCB orphaned\n");
5676 return FALSE;
5677 }
5678
5679 /* If there's a buffering state change pending, deny fast operation (it might change
5680 * cache status)
5681 */
5683 {
5684 DPRINT1("Buffering change pending\n");
5685 return FALSE;
5686 }
5687
5688 /* File got renamed/deleted, deny operation */
5689 if (BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_FILE_DELETED) ||
5691 {
5692 DPRINT1("File renamed/deleted\n");
5693 return FALSE;
5694 }
5695
5696 /* Process pending change buffering state operations */
5700
5701 LargeLength.QuadPart = Length;
5702
5703 /* If operation to come is a read operation */
5705 {
5706 /* Check that read cache is enabled */
5708 {
5709 DPRINT1("Read caching disabled\n");
5710 return FALSE;
5711 }
5712
5713 /* Check whether there's a lock conflict */
5714 if (!FsRtlFastCheckLockForRead(&Fcb->Specific.Fcb.FileLock,
5715 FileOffset,
5716 &LargeLength,
5717 LockKey,
5718 FileObject,
5720 {
5721 DPRINT1("FsRtlFastCheckLockForRead failed\n");
5722 return FALSE;
5723 }
5724
5725 return TRUE;
5726 }
5727
5728 /* Check that write cache is enabled */
5730 {
5731 DPRINT1("Write caching disabled\n");
5732 return FALSE;
5733 }
5734
5735 /* Check whether there's a lock conflict */
5737 FileOffset,
5738 &LargeLength,
5739 LockKey,
5740 FileObject,
5742 {
5743 DPRINT1("FsRtlFastCheckLockForWrite failed\n");
5744 return FALSE;
5745 }
5746
5747 return TRUE;
5748}
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG LockKey
Definition: fatprocs.h:2665
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN CheckForReadOperation
Definition: fatprocs.h:2666
BOOLEAN NTAPI FsRtlFastCheckLockForWrite(IN PFILE_LOCK FileLock, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, IN ULONG Key, IN PFILE_OBJECT FileObject, IN PVOID Process)
Definition: filelock.c:782
BOOLEAN NTAPI FsRtlFastCheckLockForRead(IN PFILE_LOCK FileLock, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, IN ULONG Key, IN PFILE_OBJECT FileObject, IN PVOID Process)
Definition: filelock.c:748
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
#define SRVOPEN_FLAG_FILE_DELETED
Definition: mrxfcb.h:135
#define SRVOPEN_FLAG_ORPHANED
Definition: mrxfcb.h:140
#define SRVOPEN_FLAG_FILE_RENAMED
Definition: mrxfcb.h:134
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
VOID RxProcessChangeBufferingStateRequestsForSrvOpen(PSRV_OPEN SrvOpen)
Definition: rxce.c:6655
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by RxInitializeDispatchVectors().

◆ RxFastIoDeviceControl()

BOOLEAN NTAPI RxFastIoDeviceControl ( PFILE_OBJECT  FileObject,
BOOLEAN  Wait,
PVOID InputBuffer  OPTIONAL,
ULONG  InputBufferLength,
PVOID OutputBuffer  OPTIONAL,
ULONG  OutputBufferLength,
ULONG  IoControlCode,
PIO_STATUS_BLOCK  IoStatus,
PDEVICE_OBJECT  DeviceObject 
)

Definition at line 5752 of file rdbss.c.

5762{
5763 /* Only supported IOCTL */
5765 {
5767 return FALSE;
5768 }
5769 else
5770 {
5771 return FALSE;
5772 }
5773}
_In_ WDFREQUEST _In_ size_t _In_ size_t _In_ ULONG IoControlCode
Definition: wdfio.h:325
#define IOCTL_LMR_ARE_FILE_OBJECTS_ON_SAME_SERVER
Definition: iotypes.h:7253

Referenced by RxInitializeDispatchVectors().

◆ RxFastIoRead()

BOOLEAN NTAPI RxFastIoRead ( PFILE_OBJECT  FileObject,
PLARGE_INTEGER  FileOffset,
ULONG  Length,
BOOLEAN  Wait,
ULONG  LockKey,
PVOID  Buffer,
PIO_STATUS_BLOCK  IoStatus,
PDEVICE_OBJECT  DeviceObject 
)

Definition at line 5780 of file rdbss.c.

5789{
5790 BOOLEAN Ret;
5791 RX_TOPLEVELIRP_CONTEXT TopLevelContext;
5792
5793 PAGED_CODE();
5794
5795 DPRINT("RxFastIoRead: %p (%p, %p)\n", FileObject, FileObject->FsContext,
5796 FileObject->FsContext2);
5797 DPRINT("Reading %ld at %I64x\n", Length, FileOffset->QuadPart);
5798
5799 /* Prepare a TLI context */
5803
5805 IoStatus, DeviceObject, &TopLevelContext);
5806 if (Ret)
5807 {
5808 DPRINT("Read OK\n");
5809 }
5810 else
5811 {
5812 DPRINT1("Read failed!\n");
5813 }
5814
5815 return Ret;
5816}
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
BOOLEAN RxIsThisTheTopLevelIrp(IN PIRP Irp)
Definition: rdbss.c:7108
#define RxInitializeTopLevelIrpContext(a, b, c)
Definition: rxcontx.h:38
BOOLEAN FsRtlCopyRead2(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject, IN PVOID TopLevelContext)
Definition: copysup.c:40
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170

Referenced by RxInitializeDispatchVectors().

◆ RxFastIoWrite()

BOOLEAN NTAPI RxFastIoWrite ( PFILE_OBJECT  FileObject,
PLARGE_INTEGER  FileOffset,
ULONG  Length,
BOOLEAN  Wait,
ULONG  LockKey,
PVOID  Buffer,
PIO_STATUS_BLOCK  IoStatus,
PDEVICE_OBJECT  DeviceObject 
)

Definition at line 5823 of file rdbss.c.

5832{
5833 PFOBX Fobx;
5834 BOOLEAN Ret;
5835 RX_TOPLEVELIRP_CONTEXT TopLevelContext;
5836
5837 PAGED_CODE();
5838
5839 Fobx = (PFOBX)FileObject->FsContext2;
5840 if (BooleanFlagOn(Fobx->Flags, FOBX_FLAG_BAD_HANDLE))
5841 {
5842 return FALSE;
5843 }
5844
5845 DPRINT("RxFastIoWrite: %p (%p, %p)\n", FileObject, FileObject->FsContext,
5846 FileObject->FsContext2);
5847 DPRINT("Writing %ld at %I64x\n", Length, FileOffset->QuadPart);
5848
5849 /* Prepare a TLI context */
5853
5855 IoStatus, DeviceObject, &TopLevelContext);
5856 if (Ret)
5857 {
5858 DPRINT("Write OK\n");
5859 }
5860 else
5861 {
5862 DPRINT1("Write failed!\n");
5863 }
5864
5865 return Ret;
5866}
#define FOBX_FLAG_BAD_HANDLE
Definition: mrxfcb.h:182
BOOLEAN FsRtlCopyWrite2(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject, IN PVOID TopLevelContext)
Definition: copysup.c:190

Referenced by RxInitializeDispatchVectors().

◆ RxFindOrCreateFcb()

NTSTATUS RxFindOrCreateFcb ( PRX_CONTEXT  RxContext,
PUNICODE_STRING  NetRootName 
)

Definition at line 5869 of file rdbss.c.

5872{
5873 PFCB Fcb;
5874 ULONG Version;
5876 PNET_ROOT NetRoot;
5877 PV_NET_ROOT VNetRoot;
5878 BOOLEAN TableAcquired, AcquiredExclusive;
5879
5880 PAGED_CODE();
5881
5882 NetRoot = (PNET_ROOT)RxContext->Create.pNetRoot;
5883 VNetRoot = (PV_NET_ROOT)RxContext->Create.pVNetRoot;
5884 ASSERT(NetRoot == VNetRoot->NetRoot);
5885
5887 AcquiredExclusive = FALSE;
5888
5890 TableAcquired = TRUE;
5891 Version = NetRoot->FcbTable.Version;
5892
5893 /* Look for a cached FCB */
5894 Fcb = RxFcbTableLookupFcb(&NetRoot->FcbTable, NetRootName);
5895 if (Fcb == NULL)
5896 {
5897 DPRINT("RxFcbTableLookupFcb returned NULL fcb for %wZ\n", NetRootName);
5898 }
5899 else
5900 {
5901 DPRINT("FCB found for %wZ\n", &Fcb->FcbTableEntry.Path);
5902 /* If FCB was to be orphaned, consider it as not suitable */
5903 if (Fcb->fShouldBeOrphaned)
5904 {
5907
5909 TableAcquired = TRUE;
5910 AcquiredExclusive = TRUE;
5911
5912 Fcb = RxFcbTableLookupFcb(&NetRoot->FcbTable, NetRootName);
5913 if (Fcb != NULL && Fcb->fShouldBeOrphaned)
5914 {
5917 Fcb = NULL;
5918 }
5919 }
5920 }
5921
5922 /* If FCB was not found or is not covering full path, prepare for more work */
5923 if (Fcb == NULL || Fcb->FcbTableEntry.Path.Length != NetRootName->Length)
5924 {
5925 if (Fcb != NULL)
5926 {
5927 DPRINT1("FCB was found and it's not covering the whole path: %wZ - %wZ\n", &Fcb->FcbTableEntry.Path, NetRootName);
5928 }
5929
5930 if (!AcquiredExclusive)
5931 {
5934 TableAcquired = TRUE;
5935 }
5936
5937 /* If FCB table was updated in between, re-attempt a lookup */
5938 if (NetRoot->FcbTable.Version != Version)
5939 {
5940 Fcb = RxFcbTableLookupFcb(&NetRoot->FcbTable, NetRootName);
5941 if (Fcb != NULL && Fcb->FcbTableEntry.Path.Length != NetRootName->Length)
5942 {
5943 Fcb = NULL;
5944 }
5945 }
5946 }
5947
5948 /* Allocate the FCB */
5949 _SEH2_TRY
5950 {
5951 if (Fcb == NULL)
5952 {
5953 Fcb = RxCreateNetFcb(RxContext, VNetRoot, NetRootName);
5954 if (Fcb == NULL)
5955 {
5957 }
5958 else
5959 {
5960 Status = RxAcquireExclusiveFcb(RxContext, Fcb);
5961 RxContext->Create.FcbAcquired = NT_SUCCESS(Status);
5962 }
5963 }
5964 }
5966 {
5968 {
5970 TableAcquired = FALSE;
5971
5972 if (Fcb != NULL)
5973 {
5975
5978 {
5979 ExReleaseResourceLite(Fcb->Header.Resource);
5980 }
5981 }
5982 }
5983 }
5984 _SEH2_END;
5985
5986 if (TableAcquired)
5987 {
5989 }
5990
5991 if (!NT_SUCCESS(Status))
5992 {
5993 return Status;
5994 }
5995
5996 RxContext->pFcb = RX_GET_MRX_FCB(Fcb);
5997 DPRINT("FCB %p is in condition %lx\n", Fcb, Fcb->Condition);
5998
5999 if (!RxContext->Create.FcbAcquired)
6000 {
6001 RxWaitForStableNetFcb(Fcb, RxContext);
6002 Status = RxAcquireExclusiveFcb(RxContext, Fcb);
6003 RxContext->Create.FcbAcquired = NT_SUCCESS(Status);
6004 }
6005
6006 return Status;
6007}
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define RxWaitForStableNetFcb(F, R)
Definition: fcb.h:542
#define RxAcquireFcbTableLockShared(T, W)
Definition: fcbtable.h:54
PFCB RxFcbTableLookupFcb(_In_ PRX_FCB_TABLE FcbTable, _In_ PUNICODE_STRING Path)
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
volatile ULONG Version
Definition: fcbtable.h:19
PNET_ROOT NetRoot
Definition: fcb.h:65
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE _In_ USHORT _In_ USHORT Version
Definition: wdffdo.h:469

Referenced by RxCreateFromNetRoot().

◆ RxFirstCanonicalize()

NTSTATUS RxFirstCanonicalize ( PRX_CONTEXT  RxContext,
PUNICODE_STRING  FileName,
PUNICODE_STRING  CanonicalName,
PNET_ROOT_TYPE  NetRootType 
)

Definition at line 6010 of file rdbss.c.

6015{
6018 BOOLEAN UncName, PrependString, IsSpecial;
6019 USHORT CanonicalLength;
6020 UNICODE_STRING SessionIdString;
6021 WCHAR SessionIdBuffer[16];
6022
6023 PAGED_CODE();
6024
6026 PrependString = FALSE;
6027 IsSpecial = FALSE;
6028 UncName = FALSE;
6030
6031 /* Name has to contain at least \\ */
6032 if (FileName->Length < 2 * sizeof(WCHAR))
6033 {
6035 }
6036
6037 /* First easy check, is that a path with a name? */
6038 CanonicalLength = FileName->Length;
6039 if (FileName->Length > 5 * sizeof(WCHAR))
6040 {
6041 if (FileName->Buffer[0] == '\\' && FileName->Buffer[1] == ';')
6042 {
6043 if (FileName->Buffer[3] == ':')
6044 {
6046 }
6047 else
6048 {
6050 }
6051 }
6052 }
6053
6054 /* Nope, attempt deeper parsing */
6055 if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR && FileName->Buffer[1] != ';')
6056 {
6058 PWSTR FirstSlash, EndOfString;
6059
6061 UncName = TRUE;
6062
6063 /* The lack of drive letter will be replaced by session ID */
6065 RtlInitEmptyUnicodeString(&SessionIdString, SessionIdBuffer, sizeof(SessionIdBuffer));
6066 RtlIntegerToUnicodeString(SessionId, 10, &SessionIdString);
6067
6068 EndOfString = Add2Ptr(FileName->Buffer, FileName->Length);
6069 for (FirstSlash = &FileName->Buffer[1]; FirstSlash != EndOfString; ++FirstSlash)
6070 {
6071 if (*FirstSlash == OBJ_NAME_PATH_SEPARATOR)
6072 {
6073 break;
6074 }
6075 }
6076
6077 if (EndOfString - FirstSlash <= 1)
6078 {
6080 }
6081 else
6082 {
6084 DPRINT1("WARNING: Assuming not special + disk!\n");
6087 //Status = STATUS_NOT_IMPLEMENTED;
6088 /* Should be check against IPC, mailslot, and so on */
6089 }
6090 }
6091
6092 /* Update net root type with our deduced one */
6093 *NetRootType = Type;
6094 DPRINT("Returning type: %x\n", Type);
6095
6096 if (!NT_SUCCESS(Status))
6097 {
6098 return Status;
6099 }
6100
6101 /* Do we have to prepend session ID? */
6102 if (UncName)
6103 {
6104 if (!IsSpecial)
6105 {
6106 PrependString = TRUE;
6107 CanonicalLength += SessionIdString.Length + 3 * sizeof(WCHAR);
6108 }
6109 }
6110
6111 /* If not UNC path, we should preprend stuff */
6112 if (!PrependString && !IsSpecial && FileName->Buffer[0] != '\\')
6113 {
6115 }
6116
6117 /* Allocate the buffer */
6118 Status = RxAllocateCanonicalNameBuffer(RxContext, CanonicalName, CanonicalLength);
6119 if (!NT_SUCCESS(Status))
6120 {
6121 return Status;
6122 }
6123
6124 /* We don't support that case, we always return disk */
6125 if (IsSpecial)
6126 {
6127 ASSERT(CanonicalName->Length == CanonicalLength);
6130 }
6131 else
6132 {
6133 /* If we have to prepend, go ahead */
6134 if (PrependString)
6135 {
6136 CanonicalName->Buffer[0] = '\\';
6137 CanonicalName->Buffer[1] = ';';
6138 CanonicalName->Buffer[2] = ':';
6139 CanonicalName->Length = 3 * sizeof(WCHAR);
6140 RtlAppendUnicodeStringToString(CanonicalName, &SessionIdString);
6142
6143 DPRINT1("CanonicalName: %wZ\n", CanonicalName);
6144 }
6145 /* Otherwise, that's a simple copy */
6146 else
6147 {
6148 RtlCopyUnicodeString(CanonicalName, FileName);
6149 }
6150 }
6151
6152 return Status;
6153}
Type
Definition: Type.h:7
ULONG SessionId
Definition: dllmain.c:28
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
NTSYSAPI NTSTATUS NTAPI RtlIntegerToUnicodeString(ULONG Value, ULONG Base, PUNICODE_STRING String)
ULONG RxGetSessionId(IN PIO_STACK_LOCATION IrpSp)
Definition: rdbss.c:6751
NTSTATUS RxAllocateCanonicalNameBuffer(PRX_CONTEXT RxContext, PUNICODE_STRING CanonicalName, USHORT CanonicalLength)
Definition: rdbss.c:924
@ RX_CONTEXT_CREATE_FLAG_UNC_NAME
Definition: rxcontx.h:324

Referenced by RxCanonicalizeNameAndObtainNetRoot(), RxCreateTreeConnect(), and RxPrefixClaim().

◆ RxFreeCanonicalNameBuffer()

VOID RxFreeCanonicalNameBuffer ( PRX_CONTEXT  Context)

Definition at line 6159 of file rdbss.c.

6161{
6162 /* These two buffers are always the same */
6163 ASSERT(Context->Create.CanonicalNameBuffer == Context->AlsoCanonicalNameBuffer);
6164
6165 if (Context->Create.CanonicalNameBuffer != NULL)
6166 {
6167 RxFreePoolWithTag(Context->Create.CanonicalNameBuffer, RX_MISC_POOLTAG);
6168 Context->Create.CanonicalNameBuffer = NULL;
6169 Context->AlsoCanonicalNameBuffer = NULL;
6170 }
6171
6172 ASSERT(Context->AlsoCanonicalNameBuffer == NULL);
6173}

Referenced by RxCanonicalizeNameAndObtainNetRoot(), and RxpPrepareCreateContextForReuse().

◆ RxFsdCommonDispatch()

NTSTATUS RxFsdCommonDispatch ( PRX_FSD_DISPATCH_VECTOR  DispatchVector,
UCHAR  MajorFunction,
PIO_STACK_LOCATION  Stack,
PFILE_OBJECT  FileObject,
PIRP  Irp,
PRDBSS_DEVICE_OBJECT  RxDeviceObject 
)

Definition at line 6176 of file rdbss.c.

6183{
6184 KIRQL OldIrql;
6188 PFILE_OBJECT StackFileObject;
6189 PRX_FSD_DISPATCH DispatchFunc;
6190 RX_TOPLEVELIRP_CONTEXT TopLevelContext;
6191 BOOLEAN TopLevel, Closing, PassToDriver, SetCancelRoutine, PostRequest, CanWait;
6192
6194
6195 DPRINT("RxFsdCommonDispatch(%p, %d, %p, %p, %p, %p)\n", DispatchVector, MajorFunction, Stack, FileObject, Irp, RxDeviceObject);
6196
6198
6199 TopLevel = RxTryToBecomeTheTopLevelIrp(&TopLevelContext, Irp, RxDeviceObject, FALSE);
6200
6201 _SEH2_TRY
6202 {
6203 CanWait = TRUE;
6204 Closing = FALSE;
6205 PostRequest = FALSE;
6206 SetCancelRoutine = TRUE;
6207 MinorFunction = Stack->MinorFunction;
6208 /* Can we wait? */
6209 switch (MajorFunction)
6210 {
6212 if (FileObject != NULL)
6213 {
6214 CanWait = IoIsOperationSynchronous(Irp);
6215 }
6216 else
6217 {
6218 CanWait = TRUE;
6219 }
6220 break;
6221
6222 case IRP_MJ_READ:
6223 case IRP_MJ_WRITE:
6226 case IRP_MJ_QUERY_EA:
6227 case IRP_MJ_SET_EA:
6236 CanWait = IoIsOperationSynchronous(Irp);
6237 break;
6238
6239 case IRP_MJ_CLOSE:
6240 case IRP_MJ_CLEANUP:
6241 Closing = TRUE;
6242 SetCancelRoutine = FALSE;
6243 break;
6244
6245 default:
6246 break;
6247 }
6248
6250 /* Should we stop it right now, or mini-rdr deserves to know? */
6251 PassToDriver = TRUE;
6252 if (RxGetRdbssState(RxDeviceObject) != RDBSS_STARTABLE)
6253 {
6254 if (RxGetRdbssState(RxDeviceObject) == RDBSS_STOP_IN_PROGRESS && !Closing)
6255 {
6256 PassToDriver = FALSE;
6258 DPRINT1("Not started!\n");
6259 }
6260 }
6261 else
6262 {
6263 if (DispatchVector != RxDeviceFCBVector && (FileObject->FileName.Length != 0 || FileObject->RelatedFileObject != NULL))
6264 {
6265 PassToDriver = FALSE;
6267 DPRINT1("Not started!\n");
6268 }
6269 }
6271
6272 StackFileObject = Stack->FileObject;
6273 /* Make sure we don't deal with orphaned stuff */
6274 if (StackFileObject != NULL && StackFileObject->FsContext != NULL)
6275 {
6276 if (StackFileObject->FsContext2 != UIntToPtr(DFS_OPEN_CONTEXT) &&
6277 StackFileObject->FsContext2 != UIntToPtr(DFS_DOWNLEVEL_OPEN_CONTEXT) &&
6278 StackFileObject->FsContext != &RxDeviceFCB)
6279 {
6280 PFCB Fcb;
6281 PFOBX Fobx;
6282
6283 Fcb = StackFileObject->FsContext;
6284 Fobx = StackFileObject->FsContext2;
6285
6287 ((Fobx != NULL) && BooleanFlagOn(Fobx->pSrvOpen->Flags, SRVOPEN_FLAG_ORPHANED)))
6288 {
6289 if (Closing)
6290 {
6291 PassToDriver = TRUE;
6292 }
6293 else
6294 {
6295 PassToDriver = FALSE;
6297 DPRINT1("Operation on orphaned FCB: %p\n", Fcb);
6298 }
6299 }
6300 }
6301 }
6302
6303 /* Did we receive a close request whereas we're stopping? */
6304 if (RxGetRdbssState(RxDeviceObject) == RDBSS_STOP_IN_PROGRESS && Closing)
6305 {
6306 PFCB Fcb;
6307
6308 Fcb = StackFileObject->FsContext;
6309
6310 DPRINT1("Close received after stop\n");
6311 DPRINT1("Irp: %p %d:%d FO: %p FCB: %p\n",
6312 Irp, Stack->MajorFunction, Stack->MinorFunction, StackFileObject, Fcb);
6313
6314 if (Fcb != NULL && Fcb != &RxDeviceFCB &&
6316 {
6317 DPRINT1("OpenCount: %ld, UncleanCount: %ld, Name: %wZ\n",
6319 }
6320 }
6321
6322 /* Should we stop the whole thing now? */
6323 if (!PassToDriver)
6324 {
6326 {
6328 Irp->IoStatus.Status = Status;
6329 Irp->IoStatus.Information = 0;
6332 }
6333 else
6334 {
6335 Irp->IoStatus.Status = Status;
6336 Irp->IoStatus.Information = 0;
6338 }
6339
6341 }
6342
6343 /* No? Allocate a context to deal with the mini-rdr */
6344 Context = RxCreateRxContext(Irp, RxDeviceObject, (CanWait ? RX_CONTEXT_FLAG_WAIT : 0));
6345 if (Context == NULL)
6346 {
6350 }
6351
6352 /* Set cancel routine if required */
6353 if (SetCancelRoutine)
6354 {
6357 }
6358 else
6359 {
6362 }
6364
6366
6367 Irp->IoStatus.Status = STATUS_SUCCESS;
6368 Irp->IoStatus.Information = 0;
6369 /* Get the dispatch routine */
6370 DispatchFunc = DispatchVector[MajorFunction].CommonRoutine;
6371
6373 {
6374 /* Handle the complete MDL case */
6376 {
6377 DispatchFunc = RxCompleteMdl;
6378 }
6379 else
6380 {
6381 /* Do we have to post request? */
6383 {
6384 PostRequest = TRUE;
6385 }
6386 else
6387 {
6388 /* Our read function needs stack, make sure we won't overflow,
6389 * otherwise, post the request
6390 */
6392 {
6393 if (IoGetRemainingStackSize() < 0xE00)
6394 {
6395 Context->PendingReturned = TRUE;
6397 if (Status != STATUS_PENDING)
6398 {
6399 Context->PendingReturned = FALSE;
6401 }
6402
6404 }
6405 }
6406 }
6407 }
6408 }
6409
6410 Context->ResumeRoutine = DispatchFunc;
6411 /* There's a dispatch routine? Time to dispatch! */
6412 if (DispatchFunc != NULL)
6413 {
6414 Context->PendingReturned = TRUE;
6415 if (PostRequest)
6416 {
6418 }
6419 else
6420 {
6421 /* Retry as long as we have */
6422 do
6423 {
6424 Status = DispatchFunc(Context);
6425 }
6426 while (Status == STATUS_RETRY);
6427
6428 if (Status == STATUS_PENDING)
6429 {
6431 }
6432
6433 /* Sanity check: did someone mess with our context? */
6434 if (Context->CurrentIrp != Irp || Context->CurrentIrpSp != Stack ||
6435 Context->MajorFunction != MajorFunction || Stack->MinorFunction != MinorFunction)
6436 {
6437 DPRINT1("RX_CONTEXT %p has been contaminated!\n", Context);
6438 DPRINT1("->CurrentIrp %p %p\n", Context->CurrentIrp, Irp);
6439 DPRINT1("->CurrentIrpSp %p %p\n", Context->CurrentIrpSp, Stack);
6440 DPRINT1("->MajorFunction %d %d\n", Context->MajorFunction, MajorFunction);
6441 DPRINT1("->MinorFunction %d %d\n", Context->MinorFunction, MinorFunction);
6442 }
6443 Context->PendingReturned = FALSE;
6445 }
6446 }
6447 else
6448 {
6450 }
6451 }
6453 {
6454 if (TopLevel)
6455 {
6456 RxUnwindTopLevelIrp(&TopLevelContext);
6457 }
6458
6460 }
6461 _SEH2_END;
6462
6463 DPRINT("RxFsdDispatch, Status: %lx\n", Status);
6464 return Status;
6465}
IN PFCB IN PCCB IN TYPE_OF_OPEN IN BOOLEAN IN BOOLEAN TopLevel
Definition: fatprocs.h:2417
IoMarkIrpPending(Irp)
IoSetCancelRoutine(Irp, CancelRoutine)
#define IoCompleteRequest
Definition: irp.c:1240
BOOLEAN NTAPI IoIsOperationSynchronous(IN PIRP Irp)
Definition: irp.c:1882
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
#define STATUS_REDIRECTOR_NOT_STARTED
Definition: ntstatus.h:487
#define STATUS_UNEXPECTED_NETWORK_ERROR
Definition: ntstatus.h:432
VOID RxUnwindTopLevelIrp(IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext)
Definition: rdbss.c:9471
NTSTATUS RxPostStackOverflowRead(IN PRX_CONTEXT RxContext)
Definition: rdbss.c:7641
NTSTATUS(NTAPI * PRX_FSD_DISPATCH)(PRX_CONTEXT Context)
Definition: rdbss.c:42
VOID NTAPI RxCancelRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: rdbss.c:1196
BOOLEAN RxTryToBecomeTheTopLevelIrp(IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext, IN PIRP Irp, IN PRDBSS_DEVICE_OBJECT RxDeviceObject, IN BOOLEAN ForceTopLevel)
Definition: rdbss.c:9348
RX_FSD_DISPATCH_VECTOR RxDeviceFCBVector[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: rdbss.c:540
NTSTATUS NTAPI RxCompleteMdl(IN PRX_CONTEXT RxContext)
Definition: rdbss.c:4857
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
VOID RxCompleteRequest_Real(_In_ PRX_CONTEXT RxContext, _In_ PIRP Irp, _In_ NTSTATUS Status)
#define RxCompleteAsynchronousRequest(C, S)
Definition: rxprocs.h:386
PVOID RxNull
Definition: rxce.c:118
#define RxGetRdbssState(RxDeviceObject)
Definition: rxstruc.h:78
@ RDBSS_STARTABLE
Definition: rxstruc.h:52
@ RDBSS_STOP_IN_PROGRESS
Definition: rxstruc.h:54
PRX_FSD_DISPATCH CommonRoutine
Definition: rdbss.c:47
_In_ UCHAR MajorFunction
Definition: wdfdevice.h:1697
_In_ UCHAR _In_ UCHAR MinorFunction
Definition: wdfdevice.h:1699
#define IRP_MN_COMPLETE
Definition: iotypes.h:4420
#define IRP_MJ_QUERY_EA
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define IRP_MJ_SET_VOLUME_INFORMATION
#define IRP_MN_REMOVE_DEVICE
#define IRP_MJ_QUERY_SECURITY
#define IRP_MJ_SET_EA
#define IRP_MJ_FLUSH_BUFFERS
#define IRP_MN_DPC
Definition: iotypes.h:4418
#define IRP_MJ_SET_SECURITY
#define IRP_MJ_CLEANUP
#define IRP_MJ_MAXIMUM_FUNCTION
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by RxFsdDispatch().

◆ RxFsdDispatch()

NTSTATUS NTAPI RxFsdDispatch ( IN PRDBSS_DEVICE_OBJECT  RxDeviceObject,
IN PIRP  Irp 
)

Definition at line 6472 of file rdbss.c.

6475{
6476 PFCB Fcb;
6478 PRX_FSD_DISPATCH_VECTOR DispatchVector;
6479
6480 PAGED_CODE();
6481
6482 DPRINT("RxFsdDispatch(%p, %p)\n", RxDeviceObject, Irp);
6483
6485
6486 /* Dispatch easy case */
6487 if (Stack->MajorFunction == IRP_MJ_SYSTEM_CONTROL)
6488 {
6489 return RxSystemControl(RxDeviceObject, Irp);
6490 }
6491
6492 /* Bail out broken cases */
6493 if (Stack->MajorFunction == IRP_MJ_CREATE_MAILSLOT ||
6494 Stack->MajorFunction == IRP_MJ_CREATE_NAMED_PIPE)
6495 {
6497 Irp->IoStatus.Information = 0;
6498 Irp->IoStatus.Status = STATUS_OBJECT_NAME_INVALID;
6500 return STATUS_PENDING;
6501 }
6502
6503 /* Immediately handle create */
6504 if (Stack->MajorFunction == IRP_MJ_CREATE)
6505 {
6506 return RxFsdCommonDispatch(&RxFsdDispatchVector[0], Stack->MajorFunction, Stack, Stack->FileObject, Irp, RxDeviceObject);
6507 }
6508
6509 /* If not a creation, we must have at least a FO with a FCB */
6510 if (Stack->FileObject == NULL || Stack->FileObject->FsContext == NULL)
6511 {
6513 Irp->IoStatus.Information = 0;
6514 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
6516 return STATUS_PENDING;
6517 }
6518
6519 /* Set the dispatch vector if required */
6520 Fcb = Stack->FileObject->FsContext;
6522 {
6523 DispatchVector = &RxFsdDispatchVector[0];
6524 }
6525 else
6526 {
6527 DispatchVector = Fcb->PrivateDispatchVector;
6528 }
6529
6530 /* Device cannot accept such requests */
6531 if (RxDeviceObject == RxFileSystemDeviceObject)
6532 {
6534 Irp->IoStatus.Information = 0;
6535 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
6537 return STATUS_PENDING;
6538 }
6539
6540 /* Dispatch for real! */
6541 return RxFsdCommonDispatch(DispatchVector, Stack->MajorFunction, Stack, Stack->FileObject, Irp, RxDeviceObject);
6542}
NTSTATUS RxSystemControl(IN PRDBSS_DEVICE_OBJECT RxDeviceObject, IN PIRP Irp)
Definition: rdbss.c:9336
RX_FSD_DISPATCH_VECTOR RxFsdDispatchVector[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: rdbss.c:574
NTSTATUS RxFsdCommonDispatch(PRX_FSD_DISPATCH_VECTOR DispatchVector, UCHAR MajorFunction, PIO_STACK_LOCATION Stack, PFILE_OBJECT FileObject, PIRP Irp, PRDBSS_DEVICE_OBJECT RxDeviceObject)
Definition: rdbss.c:6176
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
PRX_FSD_DISPATCH_VECTOR PrivateDispatchVector
Definition: fcb.h:148
PFILE_OBJECT FileObject
Definition: ntfs.h:520
#define IRP_MJ_CREATE_NAMED_PIPE
#define IRP_MJ_CREATE_MAILSLOT
#define IRP_MJ_SYSTEM_CONTROL

Referenced by RxInitializeDispatchVectors().

◆ RxFsdPostRequest()

NTSTATUS RxFsdPostRequest ( IN PRX_CONTEXT  RxContext)

Definition at line 6548 of file rdbss.c.

6550{
6551 /* Initialize posting if required */
6553 {
6554 RxPrePostIrp(RxContext, RxContext->CurrentIrp);
6555 }
6556
6557 DPRINT("Posting MN: %d, Ctxt: %p, IRP: %p, Thrd: %lx #%lx\n",
6558 RxContext->MinorFunction, RxContext,
6559 RxContext->CurrentIrp, RxContext->LastExecutionThread,
6560 RxContext->SerialNumber);
6561
6562 RxAddToWorkque(RxContext, RxContext->CurrentIrp);
6563 return STATUS_PENDING;
6564}

Referenced by RxCommonDevFCBIoCtl(), RxCommonQueryVolumeInformation(), RxCommonSetInformation(), RxCommonWrite(), RxFsdCommonDispatch(), and RxQueryDirectory().

◆ RxFspDispatch()

VOID NTAPI RxFspDispatch ( IN PVOID  Context)

Definition at line 6571 of file rdbss.c.

6573{
6574 KIRQL EntryIrql;
6576 PRDBSS_DEVICE_OBJECT VolumeDO;
6577 PRX_CONTEXT RxContext, EntryContext;
6578
6579 PAGED_CODE();
6580
6581 RxContext = Context;
6583 /* Save IRQL at entry for later checking */
6584 EntryIrql = KeGetCurrentIrql();
6585
6586 /* No FO, deal with device */
6587 if (RxContext->CurrentIrpSp->FileObject != NULL)
6588 {
6589 VolumeDO = RxFileSystemDeviceObject;
6590 }
6591 else
6592 {
6593 VolumeDO = NULL;
6594 }
6595
6596 /* Which queue to used for delayed? */
6598 {
6600 }
6601 else
6602 {
6605 }
6606
6607 do
6608 {
6609 PIRP Irp;
6611 BOOLEAN RecursiveCall;
6612 RX_TOPLEVELIRP_CONTEXT TopLevelContext;
6613
6615 ASSERT(!RxContext->PostRequest);
6616
6619
6620 DPRINT("Dispatch: MN: %d, Ctxt: %p, IRP: %p, THRD: %lx #%lx\n", RxContext->MinorFunction,
6621 RxContext, RxContext->CurrentIrp, RxContext->LastExecutionThread,
6622 RxContext->SerialNumber);
6623
6624 Irp = RxContext->CurrentIrp;
6625
6627
6628 RecursiveCall = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_RECURSIVE_CALL);
6629 RxTryToBecomeTheTopLevelIrp(&TopLevelContext,
6630 (RecursiveCall ? (PIRP)FSRTL_FSP_TOP_LEVEL_IRP : RxContext->CurrentIrp),
6631 RxContext->RxDeviceObject, TRUE);
6632
6633 ASSERT(RxContext->ResumeRoutine != NULL);
6634
6635 if (BooleanFlagOn(RxContext->MinorFunction, IRP_MN_DPC) && Irp->Tail.Overlay.Thread == NULL)
6636 {
6637 ASSERT((RxContext->MajorFunction == IRP_MJ_WRITE) || (RxContext->MajorFunction == IRP_MJ_READ));
6638 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
6639 }
6640
6641 /* Call the resume routine */
6642 do
6643 {
6644 BOOLEAN NoComplete;
6645
6647
6648 Status = RxContext->ResumeRoutine(RxContext);
6649 if (!NoComplete && Status != STATUS_PENDING)
6650 {
6651 if (Status != STATUS_RETRY)
6652 {
6653 Status = RxCompleteRequest(RxContext, Status);
6654 }
6655 }
6656 }
6657 while (Status == STATUS_RETRY);
6658
6659 RxUnwindTopLevelIrp(&TopLevelContext);
6661
6662 if (VolumeDO != NULL)
6663 {
6664 RxContext = RxRemoveOverflowEntry(VolumeDO, Queue);
6665 }
6666 else
6667 {
6668 RxContext = NULL;
6669 }
6670 } while (RxContext != NULL);
6671
6672 /* Did we mess with IRQL? */
6673 if (KeGetCurrentIrql() >= APC_LEVEL)
6674 {
6675 DPRINT1("High IRQL for Ctxt %p, on entry: %x\n", EntryContext, EntryIrql);
6676 }
6677}
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4207
PRX_CONTEXT RxRemoveOverflowEntry(PRDBSS_DEVICE_OBJECT DeviceObject, WORK_QUEUE_TYPE Queue)
Definition: rdbss.c:8580
@ RX_CONTEXT_FLAG_NO_COMPLETE_FROM_FSP
Definition: rxcontx.h:294
BOOLEAN PostRequest
Definition: rxcontx.h:108
PRX_DISPATCH ResumeRoutine
Definition: rxcontx.h:148
PETHREAD LastExecutionThread
Definition: rxcontx.h:118
ULONG SerialNumber
Definition: rxcontx.h:122
UCHAR MinorFunction
Definition: rxcontx.h:106
PRDBSS_DEVICE_OBJECT RxDeviceObject
Definition: rxcontx.h:116

Referenced by RxAddToWorkque().

◆ RxGetNetworkProviderPriority()

ULONG RxGetNetworkProviderPriority ( PUNICODE_STRING  DeviceName)

Definition at line 6683 of file rdbss.c.

6685{
6686 PAGED_CODE();
6687 return 1;
6688}

Referenced by RxRegisterMinirdr().

◆ RxGetRegistryParameters()

VOID NTAPI RxGetRegistryParameters ( IN PUNICODE_STRING  RegistryPath)

Definition at line 6695 of file rdbss.c.

6697{
6698 USHORT i;
6700 UCHAR Buffer[0x400];
6702 UNICODE_STRING KeyName, OutString;
6704
6705 PAGED_CODE();
6706
6709 if (!NT_SUCCESS(Status))
6710 {
6711 return;
6712 }
6713
6714 RtlInitUnicodeString(&KeyName, L"Parameters");
6717 if (NT_SUCCESS(Status))
6718 {
6719 /* The only parameter we deal with is InitialDebugString */
6720 RxGetStringRegistryParameter(KeyHandle, L"InitialDebugString", &OutString, Buffer, sizeof(Buffer), 0);
6721 if (OutString.Length != 0 && OutString.Length < 0x140)
6722 {
6723 PWSTR Read;
6724 PSTR Write;
6725
6726 Read = OutString.Buffer;
6727 Write = (PSTR)OutString.Buffer;
6728 for (i = 0; i < OutString.Length; ++i)
6729 {
6730 *Read = *Write;
6731 ++Write;
6732 *Write = ANSI_NULL;
6733 ++Read;
6734 }
6735
6736 /* Which is a string we'll just write out */
6737 DPRINT("InitialDebugString read from registry: '%s'\n", OutString.Buffer);
6738 RxDebugControlCommand((PSTR)OutString.Buffer);
6739 }
6740
6742 }
6743
6745}
static NDIS_HANDLE DriverHandle
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define for
Definition: utility.h:88
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define READ_CONTROL
Definition: nt_native.h:58
#define KEY_NOTIFY
Definition: nt_native.h:1020
#define ANSI_NULL
VOID NTAPI RxDebugControlCommand(_In_ PSTR ControlString)
Definition: rdbss.c:5496
NTSTATUS NTAPI RxGetStringRegistryParameter(IN HANDLE KeyHandle, IN PCWSTR KeyName, OUT PUNICODE_STRING OutString, IN PUCHAR Buffer, IN ULONG BufferLength, IN BOOLEAN LogFailure)
Definition: rdbss.c:6787
_In_ BOOLEAN Read
Definition: strmini.h:479
char * PSTR
Definition: typedefs.h:51
static BOOL Write(PBYTE Address, PBYTE Data, SIZE_T Size)
Definition: vmhorizon.c:15
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699

Referenced by RxDriverEntry().

◆ RxGetSessionId()

ULONG RxGetSessionId ( IN PIO_STACK_LOCATION  IrpSp)

Definition at line 6751 of file rdbss.c.

6753{
6756 PIO_SECURITY_CONTEXT SecurityContext;
6757
6758 PAGED_CODE();
6759
6760 /* If that's not a prefix claim, not an open request, session id will be 0 */
6762 {
6763 if (IrpSp->MajorFunction != IRP_MJ_CREATE || IrpSp->Parameters.Create.SecurityContext == NULL)
6764 {
6765 return 0;
6766 }
6767
6768 SecurityContext = IrpSp->Parameters.Create.SecurityContext;
6769 }
6770 else
6771 {
6772 SecurityContext = ((PQUERY_PATH_REQUEST)IrpSp->Parameters.DeviceIoControl.Type3InputBuffer)->SecurityContext;
6773 }
6774
6775 /* Query the session id */
6778
6779 return SessionId;
6780}
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
struct _QUERY_PATH_REQUEST * PQUERY_PATH_REQUEST
NTSTATUS NTAPI SeQuerySessionIdToken(_In_ PACCESS_TOKEN Token, _Out_ PULONG pSessionId)
Queries the session ID of an access token.
Definition: token.c:2004
SECURITY_SUBJECT_CONTEXT SubjectSecurityContext
Definition: setypes.h:234
struct _IO_STACK_LOCATION::@1564::@1565 DeviceIoControl
union _IO_STACK_LOCATION::@1564 Parameters
struct _IO_STACK_LOCATION::@3978::@3979 Create
#define SeQuerySubjectContextToken(SubjectContext)
Definition: sefuncs.h:583

Referenced by RxFirstCanonicalize().

◆ RxGetStringRegistryParameter()

NTSTATUS NTAPI RxGetStringRegistryParameter ( IN HANDLE  KeyHandle,
IN PCWSTR  KeyName,
OUT PUNICODE_STRING  OutString,
IN PUCHAR  Buffer,
IN ULONG  BufferLength,
IN BOOLEAN  LogFailure 
)

Definition at line 6787 of file rdbss.c.

6794{
6797 UNICODE_STRING KeyString;
6798
6799 PAGED_CODE();
6800
6801 RtlInitUnicodeString(&KeyString, KeyName);
6802 Status = ZwQueryValueKey(KeyHandle, &KeyString, KeyValuePartialInformation, Buffer, BufferLength, &ResultLength);
6803 OutString->Length = 0;
6804 OutString->Buffer = 0;
6805 if (!NT_SUCCESS(Status))
6806 {
6807 if (LogFailure)
6808 {
6810 }
6811
6812 return Status;
6813 }
6814
6815 OutString->Buffer = (PWSTR)(((PKEY_VALUE_PARTIAL_INFORMATION)Buffer)->Data);
6816 OutString->Length = ((PKEY_VALUE_PARTIAL_INFORMATION)Buffer)->DataLength - sizeof(UNICODE_NULL);
6817 OutString->MaximumLength = OutString->Length;
6818
6819 return STATUS_SUCCESS;
6820}
@ KeyValuePartialInformation
Definition: nt_native.h:1182
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
#define UNICODE_NULL
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771

Referenced by RxGetRegistryParameters().

◆ RxGetTopDeviceObjectIfRdbssIrp()

PRDBSS_DEVICE_OBJECT RxGetTopDeviceObjectIfRdbssIrp ( VOID  )

Definition at line 6826 of file rdbss.c.

6828{
6829 PIRP TopLevelIrp;
6830 PRDBSS_DEVICE_OBJECT TopDevice = NULL;
6831
6832 TopLevelIrp = IoGetTopLevelIrp();
6834 {
6835 TopDevice = ((PRX_TOPLEVELIRP_CONTEXT)TopLevelIrp)->RxDeviceObject;
6836 }
6837
6838 return TopDevice;
6839}
BOOLEAN RxIsThisAnRdbssTopLevelContext(PRX_TOPLEVELIRP_CONTEXT TopLevelContext)
Definition: rdbss.c:7075
struct _RX_TOPLEVELIRP_CONTEXT * PRX_TOPLEVELIRP_CONTEXT

Referenced by RxInitializeContext().

◆ RxGetTopIrpIfRdbssIrp()

PIRP RxGetTopIrpIfRdbssIrp ( VOID  )

Definition at line 6845 of file rdbss.c.

6847{
6848 PIRP Irp = NULL;
6850
6853 {
6854 Irp = TopLevel->Irp;
6855 }
6856
6857 return Irp;
6858}

Referenced by RxCommonWrite(), RxReleaseFcbFromLazyWrite(), and RxReleaseFcbFromReadAhead().

◆ RxGetUid()

LUID RxGetUid ( IN PSECURITY_SUBJECT_CONTEXT  SubjectSecurityContext)

Definition at line 6864 of file rdbss.c.

6866{
6867 LUID Luid;
6869
6870 PAGED_CODE();
6871
6874
6875 return Luid;
6876}
NTSTATUS NTAPI SeQueryAuthenticationIdToken(_In_ PACCESS_TOKEN Token, _Out_ PLUID LogonId)
Queries the authentication ID of an access token.
Definition: token.c:2036
_In_ PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
Definition: sefuncs.h:13

Referenced by RxStartMinirdr().

◆ RxIndicateChangeOfBufferingStateForSrvOpen()

VOID NTAPI RxIndicateChangeOfBufferingStateForSrvOpen ( PMRX_SRV_CALL  SrvCall,
PMRX_SRV_OPEN  SrvOpen,
PVOID  SrvOpenKey,
PVOID  Context 
)

Definition at line 6880 of file rdbss.c.

6885{
6887}

Referenced by fcbopen_main(), and nfs41_invalidate_cache().

◆ RxInitializeDebugSupport()

VOID NTAPI RxInitializeDebugSupport ( VOID  )

Definition at line 4677 of file rxce.c.

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

Referenced by RxDriverEntry().

◆ RxInitializeDispatchVectors()

VOID NTAPI RxInitializeDispatchVectors ( PDRIVER_OBJECT  DriverObject)

Definition at line 6894 of file rdbss.c.

6896{
6897 USHORT i;
6898
6899 PAGED_CODE();
6900
6901 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i)
6902 {
6903 DriverObject->MajorFunction[i] = (PDRIVER_DISPATCH)RxFsdDispatch;
6904 }
6905
6909
6910 DriverObject->FastIoDispatch = &RxFastIoDispatch;
6926
6928
6933
6938}
FAST_IO_DISPATCH RxFastIoDispatch
Definition: rdbss.c:572
VOID NTAPI RxReleaseFileForNtCreateSection(PFILE_OBJECT FileObject)
Definition: rxce.c:7578
NTSTATUS NTAPI RxReleaseForCcFlush(PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject)
Definition: rxce.c:7586
BOOLEAN NTAPI RxFastIoCheckIfPossible(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait, ULONG LockKey, BOOLEAN CheckForReadOperation, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject)
Definition: rdbss.c:5630
NTSTATUS NTAPI RxFsdDispatch(IN PRDBSS_DEVICE_OBJECT RxDeviceObject, IN PIRP Irp)
Definition: rdbss.c:6472
BOOLEAN NTAPI RxFastIoWrite(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait, ULONG LockKey, PVOID Buffer, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject)
Definition: rdbss.c:5823
VOID NTAPI RxAcquireFileForNtCreateSection(PFILE_OBJECT FileObject)
Definition: rxce.c:276
BOOLEAN NTAPI RxFastIoDeviceControl(PFILE_OBJECT FileObject, BOOLEAN Wait, PVOID InputBuffer OPTIONAL, ULONG InputBufferLength, PVOID OutputBuffer OPTIONAL, ULONG OutputBufferLength, ULONG IoControlCode, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject)
Definition: rdbss.c:5752
VOID NTAPI RxInitializeTopLevelIrpPackage(VOID)
Definition: rdbss.c:6982
BOOLEAN NTAPI RxFastIoRead(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait, ULONG LockKey, PVOID Buffer, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject)
Definition: rdbss.c:5780
NTSTATUS NTAPI RxAcquireForCcFlush(PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject)
Definition: rxce.c:284
VOID NTAPI RxNoOpRelease(_In_ PVOID Fcb)
VOID NTAPI RxReleaseFcbFromReadAhead(_In_ PVOID Null)
BOOLEAN NTAPI RxAcquireFcbForReadAhead(_In_ PVOID Null, _In_ BOOLEAN Wait)
BOOLEAN NTAPI RxNoOpAcquire(_In_ PVOID Fcb, _In_ BOOLEAN Wait)
BOOLEAN NTAPI RxAcquireFcbForLazyWrite(_In_ PVOID Null, _In_ BOOLEAN Wait)
VOID NTAPI RxReleaseFcbFromLazyWrite(_In_ PVOID Null)
PACQUIRE_FOR_LAZY_WRITE AcquireForLazyWrite
Definition: cctypes.h:39
PRELEASE_FROM_LAZY_WRITE ReleaseFromLazyWrite
Definition: cctypes.h:40
PACQUIRE_FOR_READ_AHEAD AcquireForReadAhead
Definition: cctypes.h:41
PRELEASE_FROM_READ_AHEAD ReleaseFromReadAhead
Definition: cctypes.h:42
PFAST_IO_QUERY_STANDARD_INFO FastIoQueryStandardInfo
Definition: iotypes.h:1738
PFAST_IO_UNLOCK_ALL_BY_KEY FastIoUnlockAllByKey
Definition: iotypes.h:1742
PFAST_IO_RELEASE_FOR_CCFLUSH ReleaseForCcFlush
Definition: iotypes.h:1760
PFAST_IO_WRITE FastIoWrite
Definition: iotypes.h:1736
PFAST_IO_UNLOCK_ALL FastIoUnlockAll
Definition: iotypes.h:1741
PFAST_IO_ACQUIRE_FOR_CCFLUSH AcquireForCcFlush
Definition: iotypes.h:1759
ULONG SizeOfFastIoDispatch
Definition: iotypes.h:1733
PFAST_IO_DEVICE_CONTROL FastIoDeviceControl
Definition: iotypes.h:1743
PFAST_IO_ACQUIRE_FILE AcquireFileForNtCreateSection
Definition: iotypes.h:1744
PFAST_IO_READ FastIoRead
Definition: iotypes.h:1735
PFAST_IO_QUERY_BASIC_INFO FastIoQueryBasicInfo
Definition: iotypes.h:1737
PFAST_IO_LOCK FastIoLock
Definition: iotypes.h:1739
PFAST_IO_UNLOCK_SINGLE FastIoUnlockSingle
Definition: iotypes.h:1740
PFAST_IO_RELEASE_FILE ReleaseFileForNtCreateSection
Definition: iotypes.h:1745
PFAST_IO_CHECK_IF_POSSIBLE FastIoCheckIfPossible
Definition: iotypes.h:1734
CACHE_MANAGER_CALLBACKS CacheManagerNoOpCallbacks
Definition: rxstruc.h:37
DRIVER_DISPATCH * PDRIVER_DISPATCH
Definition: iotypes.h:2262

Referenced by RxDriverEntry().

◆ RxInitializeLog()

NTSTATUS NTAPI RxInitializeLog ( VOID  )

Definition at line 6942 of file rdbss.c.

6944{
6947}

Referenced by RxDriverEntry().

◆ RxInitializeMinirdrDispatchTable()

VOID RxInitializeMinirdrDispatchTable ( IN PDRIVER_OBJECT  DriverObject)

Definition at line 6953 of file rdbss.c.

6955{
6956 PAGED_CODE();
6957}

Referenced by RxRegisterMinirdr().

◆ RxInitializeRegistrationStructures()

NTSTATUS NTAPI RxInitializeRegistrationStructures ( VOID  )

Definition at line 6964 of file rdbss.c.

6966{
6967 PAGED_CODE();
6968
6973
6974 return STATUS_SUCCESS;
6975}
LONG NumberOfMinirdrsRegistered
Definition: rxstruc.h:33
FAST_MUTEX MinirdrRegistrationMutex
Definition: rxstruc.h:31
volatile LONG NumberOfMinirdrsStarted
Definition: rxstruc.h:30
LIST_ENTRY RegisteredMiniRdrs
Definition: rxstruc.h:32

Referenced by RxDriverEntry().

◆ RxInitializeTopLevelIrpPackage()

VOID NTAPI RxInitializeTopLevelIrpPackage ( VOID  )

◆ RxInitUnwind()

VOID NTAPI RxInitUnwind ( PDRIVER_OBJECT  DriverObject,
USHORT  State 
)

Definition at line 6991 of file rdbss.c.

6994{
6996}

Referenced by RxDriverEntry().

◆ RxIsMemberOfTopLevelIrpAllocatedContextsList()

BOOLEAN RxIsMemberOfTopLevelIrpAllocatedContextsList ( PRX_TOPLEVELIRP_CONTEXT  TopLevelContext)

Definition at line 7002 of file rdbss.c.

7004{
7005 KIRQL OldIrql;
7006 PLIST_ENTRY NextEntry;
7008 PRX_TOPLEVELIRP_CONTEXT ListContext;
7009
7010 /* Browse all the allocated TLC to find ours */
7012 for (NextEntry = TopLevelIrpAllocatedContextsList.Flink;
7014 NextEntry = NextEntry->Flink)
7015 {
7016 ListContext = CONTAINING_RECORD(NextEntry, RX_TOPLEVELIRP_CONTEXT, ListEntry);
7019
7020 /* Found! */
7021 if (ListContext == TopLevelContext)
7022 {
7023 Found = TRUE;
7024 break;
7025 }
7026 }
7028
7029 return Found;
7030}
return Found
Definition: dirsup.c:1270

Referenced by RxIsThisAnRdbssTopLevelContext().

◆ RxIsOkToPurgeFcb()

BOOLEAN RxIsOkToPurgeFcb ( PFCB  Fcb)

Definition at line 7036 of file rdbss.c.

7038{
7040
7041 /* No associated SRV_OPEN, it's OK to purge */
7042 if (IsListEmpty(&Fcb->SrvOpenList))
7043 {
7044 return TRUE;
7045 }
7046
7047 /* Only allow to purge if all the associated SRV_OPEN
7048 * - have no outstanding opens ongoing
7049 * - have only read attribute set
7050 */
7051 for (Entry = Fcb->SrvOpenList.Flink;
7052 Entry != &Fcb->SrvOpenList;
7053 Entry = Entry->Flink)
7054 {
7055 PSRV_OPEN SrvOpen;
7056
7057 SrvOpen = CONTAINING_RECORD(Entry, SRV_OPEN, SrvOpenQLinks);
7058
7059 /* Failing previous needs, don't allow purge */
7060 if (SrvOpen->UncleanFobxCount != 0 ||
7061 (SrvOpen->DesiredAccess & 0xFFEFFFFF) != FILE_READ_ATTRIBUTES)
7062 {
7063 return FALSE;
7064 }
7065 }
7066
7067 /* All correct, allow purge */
7068 return TRUE;
7069}
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647

Referenced by RxSearchForCollapsibleOpen().

◆ RxIsThisAnRdbssTopLevelContext()

BOOLEAN RxIsThisAnRdbssTopLevelContext ( PRX_TOPLEVELIRP_CONTEXT  TopLevelContext)

Definition at line 7075 of file rdbss.c.

7077{
7078 ULONG_PTR StackTop, StackBottom;
7079
7080 /* Bail out for flags */
7081 if ((ULONG_PTR)TopLevelContext <= FSRTL_FAST_IO_TOP_LEVEL_IRP)
7082 {
7083 return FALSE;
7084 }
7085
7086 /* Is our provided TLC allocated on stack? */
7087 IoGetStackLimits(&StackTop, &StackBottom);
7088 if ((ULONG_PTR)TopLevelContext <= StackBottom - sizeof(RX_TOPLEVELIRP_CONTEXT) &&
7089 (ULONG_PTR)TopLevelContext >= StackTop)
7090 {
7091 /* Yes, so check whether it's really a TLC by checking alignement & signature */
7092 if (!BooleanFlagOn((ULONG_PTR)TopLevelContext, 0x3) && TopLevelContext->Signature == RX_TOPLEVELIRP_CONTEXT_SIGNATURE)
7093 {
7094 return TRUE;
7095 }
7096
7097 return FALSE;
7098 }
7099
7100 /* No, use the helper function */
7101 return RxIsMemberOfTopLevelIrpAllocatedContextsList(TopLevelContext);
7102}
VOID NTAPI IoGetStackLimits(OUT PULONG_PTR LowLimit, OUT PULONG_PTR HighLimit)
Definition: util.c:78
BOOLEAN RxIsMemberOfTopLevelIrpAllocatedContextsList(PRX_TOPLEVELIRP_CONTEXT TopLevelContext)
Definition: rdbss.c:7002

Referenced by RxGetTopDeviceObjectIfRdbssIrp(), RxGetTopIrpIfRdbssIrp(), RxIsThisTheTopLevelIrp(), and RxUnwindTopLevelIrp().

◆ RxIsThisTheTopLevelIrp()

BOOLEAN RxIsThisTheTopLevelIrp ( IN PIRP  Irp)

Definition at line 7108 of file rdbss.c.

7110{
7111 PIRP TopLevelIrp;
7112
7113 /* When we put oursleves as top level, we set TLC as 'IRP', so look for it */
7114 TopLevelIrp = IoGetTopLevelIrp();
7116 {
7117 TopLevelIrp = ((PRX_TOPLEVELIRP_CONTEXT)TopLevelIrp)->Irp;
7118 }
7119
7120 return (TopLevelIrp == Irp);
7121}

Referenced by RxFastIoRead(), and RxFastIoWrite().

◆ RxLockOperationCompletion()

NTSTATUS NTAPI RxLockOperationCompletion ( IN PVOID  Context,
IN PIRP  Irp 
)

Definition at line 7125 of file rdbss.c.

7128{
7131}

◆ RxLogEventDirect()

VOID NTAPI RxLogEventDirect ( IN PRDBSS_DEVICE_OBJECT  DeviceObject,
IN PUNICODE_STRING  OriginatorId,
IN ULONG  EventId,
IN NTSTATUS  Status,
IN ULONG  Line 
)

Definition at line 7138 of file rdbss.c.

7144{
7145 PUNICODE_STRING Originator = OriginatorId;
7146 LARGE_INTEGER LargeLine;
7147
7148 /* Set optional parameters */
7149 LargeLine.QuadPart = Line;
7150 if (OriginatorId == NULL || OriginatorId->Length == 0)
7151 {
7152 Originator = (PUNICODE_STRING)&unknownId;
7153 }
7154
7155 /* And log */
7156 RxLogEventWithAnnotation(DeviceObject, EventId, Status, &LargeLine, sizeof(LargeLine), Originator, 1);
7157}
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
VOID NTAPI RxLogEventWithAnnotation(IN PRDBSS_DEVICE_OBJECT DeviceObject, IN ULONG EventId, IN NTSTATUS Status, IN PVOID DataBuffer, IN USHORT DataBufferLength, IN PUNICODE_STRING Annotation, IN ULONG AnnotationCount)
Definition: rdbss.c:7161

◆ RxLogEventWithAnnotation()

VOID NTAPI RxLogEventWithAnnotation ( IN PRDBSS_DEVICE_OBJECT  DeviceObject,
IN ULONG  EventId,
IN NTSTATUS  Status,
IN PVOID  DataBuffer,
IN USHORT  DataBufferLength,
IN PUNICODE_STRING  Annotation,
IN ULONG  AnnotationCount 
)

Definition at line 7161 of file rdbss.c.

7169{
7171}

Referenced by RxLogEventDirect().

◆ RxLowIoCompletion()

NTSTATUS NTAPI RxLowIoCompletion ( PRX_CONTEXT  RxContext)

Definition at line 7175 of file rdbss.c.

7177{
7180}

◆ RxLowIoIoCtlShellCompletion()

NTSTATUS NTAPI RxLowIoIoCtlShellCompletion ( PRX_CONTEXT  RxContext)

Definition at line 7187 of file rdbss.c.

7189{
7190 PIRP Irp;
7192
7193 PAGED_CODE();
7194
7195 DPRINT("RxLowIoIoCtlShellCompletion(%p)\n", RxContext);
7196
7197 Irp = RxContext->CurrentIrp;
7198 Status = RxContext->IoStatusBlock.Status;
7199
7200 /* Set information and status */
7202 {
7203 Irp->IoStatus.Information = RxContext->IoStatusBlock.Information;
7204 }
7205
7206 Irp->IoStatus.Status = Status;
7207
7208 return Status;
7209}
IO_STATUS_BLOCK IoStatusBlock
Definition: rxcontx.h:139

Referenced by RxCommonDeviceControl().

◆ RxLowIoLockControlShell()

NTSTATUS RxLowIoLockControlShell ( IN PRX_CONTEXT  RxContext)

Definition at line 7212 of file rdbss.c.

7214{
7217}

Referenced by RxCommonCleanup().

◆ RxLowIoNotifyChangeDirectoryCompletion()

NTSTATUS NTAPI RxLowIoNotifyChangeDirectoryCompletion ( PRX_CONTEXT  RxContext)

Definition at line 7224 of file rdbss.c.

7226{
7227 PAGED_CODE();
7228
7229 DPRINT("Completing NCD with: %lx, %lx\n", RxContext->IoStatusBlock.Status, RxContext->IoStatusBlock.Information);
7230
7231 /* Just copy back the IO_STATUS to the IRP */
7232 RxSetIoStatusStatus(RxContext, RxContext->IoStatusBlock.Status);
7233 RxSetIoStatusInfo(RxContext, RxContext->IoStatusBlock.Information);
7234
7235 return RxContext->IoStatusBlock.Status;
7236}
#define RxSetIoStatusStatus(R, S)
Definition: mrx.h:4
#define RxSetIoStatusInfo(R, I)
Definition: mrx.h:5

Referenced by RxNotifyChangeDirectory().

◆ RxLowIoReadShell()

NTSTATUS RxLowIoReadShell ( PRX_CONTEXT  RxContext)

Definition at line 7242 of file rdbss.c.

7244{
7245 PFCB Fcb;
7247
7248 PAGED_CODE();
7249
7250 DPRINT("RxLowIoReadShell(%p)\n", RxContext);
7251
7252 Fcb = (PFCB)RxContext->pFcb;
7254 {
7256 }
7257
7258 /* Always update stats for disks */
7259 if (Fcb->CachedNetRootType == NET_ROOT_DISK)
7260 {
7262 }
7263
7264 /* And forward the read to the mini-rdr */
7266 DPRINT("RxLowIoReadShell(%p), Status: %lx\n", RxContext, Status);
7267
7268 return Status;
7269}
#define FCB_STATE_FILE_IS_SHADOWED
Definition: fcb.h:214
NTSTATUS NTAPI RxLowIoReadShellCompletion(PRX_CONTEXT RxContext)
Definition: rdbss.c:7273
LARGE_INTEGER NetworkReadBytesRequested
Definition: rxstruc.h:106

Referenced by RxCommonRead().

◆ RxLowIoReadShellCompletion()

NTSTATUS NTAPI RxLowIoReadShellCompletion ( PRX_CONTEXT  RxContext)

Definition at line 7273 of file rdbss.c.

7275{
7276 PIRP Irp;
7277 PFCB Fcb;
7279 BOOLEAN PagingIo, IsPipe;
7281 PLOWIO_CONTEXT LowIoContext;
7282
7283 PAGED_CODE();
7284
7285 DPRINT("RxLowIoReadShellCompletion(%p)\n", RxContext);
7286
7287 Status = RxContext->IoStatusBlock.Status;
7288 DPRINT("In %p, Status: %lx, Information: %lx\n", RxContext, Status, RxContext->IoStatusBlock.Information);
7289
7290 Irp = RxContext->CurrentIrp;
7291 PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO);
7292
7293 /* Set IRP information from the RX_CONTEXT status block */
7294 Irp->IoStatus.Information = RxContext->IoStatusBlock.Information;
7295
7296 /* Fixup status for paging file if nothing was read */
7297 if (PagingIo)
7298 {
7299 if (NT_SUCCESS(Status) && RxContext->IoStatusBlock.Information == 0)
7300 {
7302 }
7303 }
7304
7305 LowIoContext = &RxContext->LowIoContext;
7306 ASSERT(RxLowIoIsBufferLocked(LowIoContext));
7307
7308 /* Check broken cases that should never happen */
7309 Fcb = (PFCB)RxContext->pFcb;
7311 {
7313 {
7314 ASSERT(FALSE);
7315 return STATUS_RETRY;
7316 }
7317 }
7318 else if (Status == STATUS_SUCCESS)
7319 {
7321 {
7324 {
7325 ASSERT(FALSE);
7326 }
7327 }
7328
7330 {
7331 ASSERT(FALSE);
7332 }
7333 }
7334
7335 /* Readahead should go through Cc and not finish here */
7337
7338 /* If it's sync, RxCommonRead will finish the work - nothing to do here */
7340 {
7341 return Status;
7342 }
7343
7344 Stack = RxContext->CurrentIrpSp;
7346 /* Release lock if required */
7347 if (PagingIo)
7348 {
7349 RxReleasePagingIoResourceForThread(RxContext, Fcb, LowIoContext->ResourceThreadId);
7350 }
7351 else
7352 {
7353 /* Set FastIo if read was a success */
7354 if (NT_SUCCESS(Status) && !IsPipe)
7355 {
7356 SetFlag(Stack->FileObject->Flags, FO_FILE_FAST_IO_READ);
7357 }
7358
7360 {
7361 RxResumeBlockedOperations_Serially(RxContext, &((PFOBX)RxContext->pFobx)->Specific.NamedPipe.ReadSerializationQueue);
7362 }
7363 else
7364 {
7365 RxReleaseFcbForThread(RxContext, Fcb, LowIoContext->ResourceThreadId);
7366 }
7367 }
7368
7369 if (IsPipe)
7370 {
7372 }
7373
7374 /* Final sanity checks */
7376 ASSERT(Irp->IoStatus.Information <= Stack->Parameters.Read.Length);
7377 ASSERT(RxContext->MajorFunction == IRP_MJ_READ);
7378
7379 return Status;
7380}
#define FCB_STATE_FILE_IS_BUF_COMPRESSED
Definition: fcb.h:212
#define FCB_STATE_FILE_IS_DISK_COMPRESSED
Definition: fcb.h:213
#define RxLowIoIsBufferLocked(LowIoContext)
Definition: lowio.h:10
#define LOWIO_CONTEXT_FLAG_SYNCCALL
Definition: mrx.h:320
@ RXCONTEXT_FLAG4LOWIO_THIS_READ_ENLARGED
Definition: rxcontx.h:335
@ RXCONTEXT_FLAG4LOWIO_READAHEAD
Definition: rxcontx.h:334
@ RXCONTEXT_FLAG4LOWIO_PIPE_OPERATION
Definition: rxcontx.h:332
ULONG FlagsForLowIo
Definition: rxcontx.h:262

Referenced by RxLowIoReadShell().

◆ RxLowIoWriteShell()

NTSTATUS RxLowIoWriteShell ( IN PRX_CONTEXT  RxContext)

Definition at line 7386 of file rdbss.c.

7388{
7389 PFCB Fcb;
7391
7392 PAGED_CODE();
7393
7394 DPRINT("RxLowIoWriteShell(%p)\n", RxContext);
7395
7396 Fcb = (PFCB)RxContext->pFcb;
7397
7400
7401 /* Always update stats for disks */
7402 if (Fcb->CachedNetRootType == NET_ROOT_DISK)
7403 {
7404 ExInterlockedAddLargeStatistic(&RxContext->RxDeviceObject->NetworkWriteBytesRequested, RxContext->LowIoContext.ParamsFor.ReadWrite.ByteCount);
7405 }
7406
7407 /* And forward the write to the mini-rdr */
7409 DPRINT("RxLowIoWriteShell(%p), Status: %lx\n", RxContext, Status);
7410
7411 return Status;
7412}
NTSTATUS NTAPI RxLowIoWriteShellCompletion(PRX_CONTEXT RxContext)
Definition: rdbss.c:7416

Referenced by RxCommonWrite().

◆ RxLowIoWriteShellCompletion()

NTSTATUS NTAPI RxLowIoWriteShellCompletion ( PRX_CONTEXT  RxContext)

Definition at line 7416 of file rdbss.c.

7418{
7419 PIRP Irp;
7420 PFCB Fcb;
7422 BOOLEAN PagingIo;
7423 PLOWIO_CONTEXT LowIoContext;
7424
7425 PAGED_CODE();
7426
7427 DPRINT("RxLowIoWriteShellCompletion(%p)\n", RxContext);
7428
7429 Status = RxContext->IoStatusBlock.Status;
7430 DPRINT("In %p, Status: %lx, Information: %lx\n", RxContext, Status, RxContext->IoStatusBlock.Information);
7431
7432 Irp = RxContext->CurrentIrp;
7433
7434 /* Set IRP information from the RX_CONTEXT status block */
7436
7437 LowIoContext = &RxContext->LowIoContext;
7438 ASSERT(RxLowIoIsBufferLocked(LowIoContext));
7439
7440 /* Perform a few sanity checks */
7441 Fcb = (PFCB)RxContext->pFcb;
7443 {
7445 {
7448 }
7449
7451 }
7452
7453 PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO);
7454 if (Status != STATUS_SUCCESS && PagingIo)
7455 {
7456 DPRINT1("Paging IO failed %p (%p) %lx\n", Fcb, Fcb->NetRoot, Status);
7457 }
7458
7459 /* In case of async call, perform last bits not done in RxCommonWrite */
7460 if (!BooleanFlagOn(LowIoContext->Flags, LOWIO_CONTEXT_FLAG_SYNCCALL))
7461 {
7464
7465 /* We only succeed if we wrote what was asked for */
7467 {
7468 ASSERT(Irp->IoStatus.Information == LowIoContext->ParamsFor.ReadWrite.ByteCount);
7469 }
7470
7471 /* If write succeed, ,also update FILE_OBJECT flags */
7472 Stack = RxContext->CurrentIrpSp;
7474 if (!PagingIo)
7475 {
7477 }
7478
7480 {
7482 }
7483
7484 /* If VDL was extended, fix attributes */
7486 {
7487 LONGLONG LastOffset, FileSize;
7488
7489 LastOffset = LowIoContext->ParamsFor.ReadWrite.ByteOffset +
7490 Irp->IoStatus.Information;
7492
7493 if (FileSize < LastOffset)
7494 {
7495 LastOffset = FileSize;
7496 }
7497
7498 Fcb->Header.ValidDataLength.QuadPart = LastOffset;
7499 }
7500
7501 /* One less outstanding write */
7503 {
7504 PNON_PAGED_FCB NonPagedFcb;
7505
7506 NonPagedFcb = LowIoContext->ParamsFor.ReadWrite.NonPagedFcb;
7507 if (NonPagedFcb != NULL)
7508 {
7510 -1, &RxStrucSupSpinLock) == 1)
7511 {
7513 }
7514 }
7515 }
7516
7517 /* Release paging resource if acquired */
7518 if (RxContext->FcbPagingIoResourceAcquired)
7519 {
7520 RxReleasePagingIoResourceForThread(RxContext, Fcb, LowIoContext->ResourceThreadId);
7521 }
7522
7523 /* Resume blocked operations for pipes */
7525 {
7527 &((PFOBX)RxContext->pFobx)->Specific.NamedPipe.WriteSerializationQueue);
7528 }
7529 else
7530 {
7531 /* And release FCB only for files */
7532 if (RxContext->FcbResourceAcquired)
7533 {
7534 RxReleaseFcbForThread(RxContext, Fcb, LowIoContext->ResourceThreadId);
7535 }
7536 }
7537
7538 /* Final sanity checks */
7540 ASSERT((Status != STATUS_SUCCESS) || (Irp->IoStatus.Information <= Stack->Parameters.Write.Length));
7541 ASSERT(RxContext->MajorFunction == IRP_MJ_WRITE);
7542
7544 {
7546 }
7547 }
7548
7549 return Status;
7550}
@ RXCONTEXT_FLAG4LOWIO_THIS_IO_BUFFERED
Definition: rxcontx.h:336

Referenced by RxLowIoWriteShell().

◆ 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}
@ NormalPagePriority
Definition: imports.h:56
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)

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

◆ RxNotifyChangeDirectory()

NTSTATUS RxNotifyChangeDirectory ( PRX_CONTEXT  RxContext)

Definition at line 7556 of file rdbss.c.

7558{
7559 PIRP Irp;
7562
7563 PAGED_CODE();
7564
7565 /* The IRP can abviously wait */
7566 SetFlag(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
7567
7568 /* Initialize its lowio */
7570
7571 _SEH2_TRY
7572 {
7573 /* Lock user buffer */
7574 Stack = RxContext->CurrentIrpSp;
7575 RxLockUserBuffer(RxContext, IoWriteAccess, Stack->Parameters.NotifyDirectory.Length);
7576
7577 /* Copy parameters from IO_STACK */
7579 RxContext->LowIoContext.ParamsFor.NotifyChangeDirectory.CompletionFilter = Stack->Parameters.NotifyDirectory.CompletionFilter;
7580 RxContext->LowIoContext.ParamsFor.NotifyChangeDirectory.NotificationBufferLength = Stack->Parameters.NotifyDirectory.Length;
7581
7582 /* If we have an associated MDL */
7583 Irp = RxContext->CurrentIrp;
7584 if (Irp->MdlAddress != NULL)
7585 {
7586 /* Then, call mini-rdr */
7588 if (RxContext->LowIoContext.ParamsFor.NotifyChangeDirectory.pNotificationBuffer != NULL)
7589 {
7591 }
7592 else
7593 {
7595 }
7596 }
7597 else
7598 {
7600 }
7601 }
7603 {
7604 /* All correct */
7605 }
7606 _SEH2_END;
7607
7608 return Status;
7609}
@ LOWIO_OP_NOTIFY_CHANGE_DIRECTORY
Definition: mrx.h:242
NTSTATUS NTAPI RxLowIoNotifyChangeDirectoryCompletion(PRX_CONTEXT RxContext)
Definition: rdbss.c:7224
VOID RxLockUserBuffer(_In_ PRX_CONTEXT RxContext, _In_ LOCK_OPERATION Operation, _In_ ULONG BufferLength)
struct _LOWIO_CONTEXT::@2065::@2068 NotifyChangeDirectory
#define SL_WATCH_TREE
Definition: iotypes.h:1839
@ IoWriteAccess
Definition: ketypes.h:864

Referenced by RxCommonDirectoryControl().

◆ RxpCancelRoutine()

VOID NTAPI RxpCancelRoutine ( PVOID  Context)

Definition at line 7616 of file rdbss.c.

7618{
7619 PRX_CONTEXT RxContext;
7620
7621 PAGED_CODE();
7622
7623 RxContext = Context;
7624
7625 /* First, notify mini-rdr about cancellation */
7626 if (RxContext->MRxCancelRoutine != NULL)
7627 {
7628 RxContext->MRxCancelRoutine(RxContext);
7629 }
7630 /* If we didn't find in overflow queue, try in blocking operations */
7631 else if (!RxCancelOperationInOverflowQueue(RxContext))
7632 {
7633 RxCancelBlockingOperation(RxContext);
7634 }
7635
7636 /* And delete the context */
7638}
BOOLEAN RxCancelOperationInOverflowQueue(PRX_CONTEXT RxContext)
Definition: rdbss.c:1139
VOID RxCancelBlockingOperation(_Inout_ PRX_CONTEXT RxContext)
PMRX_CALLDOWN MRxCancelRoutine
Definition: rxcontx.h:147

Referenced by RxCancelRoutine().

◆ RxPostStackOverflowRead()

NTSTATUS RxPostStackOverflowRead ( IN PRX_CONTEXT  RxContext)

Definition at line 7641 of file rdbss.c.

7643{
7644 PAGED_CODE();
7645
7648}

Referenced by RxFsdCommonDispatch().

◆ RxpPrepareCreateContextForReuse()

VOID RxpPrepareCreateContextForReuse ( PRX_CONTEXT  RxContext)

Definition at line 7654 of file rdbss.c.

7656{
7657 /* Reuse can only happen for open operations (STATUS_RETRY) */
7658 ASSERT(RxContext->MajorFunction == IRP_MJ_CREATE);
7659
7660 /* Release the FCB if it was acquired */
7661 if (RxContext->Create.FcbAcquired)
7662 {
7663 RxReleaseFcb(RxContext, RxContext->pFcb);
7664 RxContext->Create.FcbAcquired = FALSE;
7665 }
7666
7667 /* Free the canonical name */
7668 RxFreeCanonicalNameBuffer(RxContext);
7669
7670 /* If we have a VNetRoot associated */
7671 if (RxContext->Create.pVNetRoot != NULL || RxContext->Create.NetNamePrefixEntry != NULL)
7672 {
7673 /* Remove our link and thus, dereference the VNetRoot */
7675 if (RxContext->Create.pVNetRoot != NULL)
7676 {
7677 RxDereferenceVNetRoot(RxContext->Create.pVNetRoot, TRUE);
7678 RxContext->Create.pVNetRoot = NULL;
7679 }
7681 }
7682
7683 DPRINT("RxContext: %p prepared for reuse\n", RxContext);
7684}
VOID RxpReleasePrefixTableLock(_In_ PRX_PREFIX_TABLE pTable, _In_ BOOLEAN ProcessBufferingStateChangeRequests)
BOOLEAN RxpAcquirePrefixTableLockShared(_In_ PRX_PREFIX_TABLE pTable, _In_ BOOLEAN Wait, _In_ BOOLEAN ProcessBufferingStateChangeRequests)
PRX_PREFIX_TABLE pRxNetNameTable
Definition: rxstruc.h:127

Referenced by RxCommonCreate(), and RxPrefixClaim().

◆ RxpQueryInfoMiniRdr()

NTSTATUS RxpQueryInfoMiniRdr ( PRX_CONTEXT  RxContext,
FILE_INFORMATION_CLASS  FileInfoClass,
PVOID  Buffer 
)

Definition at line 7690 of file rdbss.c.

7694{
7695 PFCB Fcb;
7697
7698 Fcb = (PFCB)RxContext->pFcb;
7699
7700 /* Set the RX_CONTEXT */
7701 RxContext->Info.FileInformationClass = FileInfoClass;
7702 RxContext->Info.Buffer = Buffer;
7703
7704 /* Pass down */
7705 MINIRDR_CALL(Status, RxContext, Fcb->MRxDispatch, MRxQueryFileInfo, (RxContext));
7706
7707 return Status;
7708}

Referenced by RxCommonQueryInformation(), RxQueryBasicInfo(), and RxQueryStandardInfo().

◆ RxPrefixClaim()

NTSTATUS RxPrefixClaim ( IN PRX_CONTEXT  RxContext)

Definition at line 7714 of file rdbss.c.

7716{
7717 PIRP Irp;
7719 NET_ROOT_TYPE NetRootType;
7720 UNICODE_STRING CanonicalName, FileName, NetRootName;
7721
7722 PAGED_CODE();
7723
7724 Irp = RxContext->CurrentIrp;
7725
7726 /* This has to come from MUP */
7727 if (Irp->RequestorMode == UserMode)
7728 {
7730 }
7731
7732 if (RxContext->MajorFunction == IRP_MJ_DEVICE_CONTROL)
7733 {
7734 PQUERY_PATH_REQUEST QueryRequest;
7735
7736 /* Get parameters */
7737 QueryRequest = RxContext->CurrentIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
7738
7739 /* Don't overflow allocation */
7740 if (QueryRequest->PathNameLength >= MAXUSHORT - 1)
7741 {
7743 }
7744
7745 /* Forcefully rewrite IRP MJ */
7746 RxContext->MajorFunction = IRP_MJ_CREATE;
7747
7748 /* Fake canon name */
7749 RxContext->PrefixClaim.SuppliedPathName.Buffer = RxAllocatePoolWithTag(NonPagedPool, QueryRequest->PathNameLength, RX_MISC_POOLTAG);
7750 if (RxContext->PrefixClaim.SuppliedPathName.Buffer == NULL)
7751 {
7753 goto Leave;
7754 }
7755
7756 /* Copy the prefix to look for */
7757 RtlCopyMemory(RxContext->PrefixClaim.SuppliedPathName.Buffer, &QueryRequest->FilePathName[0], QueryRequest->PathNameLength);
7758 RxContext->PrefixClaim.SuppliedPathName.Length = QueryRequest->PathNameLength;
7759 RxContext->PrefixClaim.SuppliedPathName.MaximumLength = QueryRequest->PathNameLength;
7760
7761 /* Zero the create parameters */
7762 RtlZeroMemory(&RxContext->Create,
7763 FIELD_OFFSET(RX_CONTEXT, AlsoCanonicalNameBuffer) - FIELD_OFFSET(RX_CONTEXT, Create.NtCreateParameters));
7764 RxContext->Create.ThisIsATreeConnectOpen = TRUE;
7765 RxContext->Create.NtCreateParameters.SecurityContext = QueryRequest->SecurityContext;
7766 }
7767 else
7768 {
7769 /* If not devcontrol, it comes from open, name was already copied */
7770 ASSERT(RxContext->MajorFunction == IRP_MJ_CREATE);
7771 ASSERT(RxContext->PrefixClaim.SuppliedPathName.Buffer != NULL);
7772 }
7773
7774 /* Canonilize name */
7775 NetRootType = NET_ROOT_WILD;
7776 RtlInitEmptyUnicodeString(&CanonicalName, NULL, 0);
7777 FileName.Length = RxContext->PrefixClaim.SuppliedPathName.Length;
7778 FileName.MaximumLength = RxContext->PrefixClaim.SuppliedPathName.MaximumLength;
7779 FileName.Buffer = RxContext->PrefixClaim.SuppliedPathName.Buffer;
7780 NetRootName.Length = RxContext->PrefixClaim.SuppliedPathName.Length;
7781 NetRootName.MaximumLength = RxContext->PrefixClaim.SuppliedPathName.MaximumLength;
7782 NetRootName.Buffer = RxContext->PrefixClaim.SuppliedPathName.Buffer;
7783 Status = RxFirstCanonicalize(RxContext, &FileName, &CanonicalName, &NetRootType);
7784 /* It went fine, attempt to establish a connection (that way we know whether the prefix is accepted) */
7785 if (NT_SUCCESS(Status))
7786 {
7787 Status = RxFindOrConstructVirtualNetRoot(RxContext, &CanonicalName, NetRootType, &NetRootName);
7788 }
7789 if (Status == STATUS_PENDING)
7790 {
7791 return Status;
7792 }
7793 /* Reply to MUP */
7794 if (NT_SUCCESS(Status))
7795 {
7796 PQUERY_PATH_RESPONSE QueryResponse;
7797
7798 /* We accept the length that was canon (minus netroot) */
7799 QueryResponse = RxContext->CurrentIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
7800 QueryResponse->LengthAccepted = RxContext->PrefixClaim.SuppliedPathName.Length - NetRootName.Length;
7801 }
7802
7803Leave:
7804 /* If we reach that point with MJ, reset everything and make IRP being a device control */
7805 if (RxContext->MajorFunction == IRP_MJ_CREATE)
7806 {
7807 if (RxContext->PrefixClaim.SuppliedPathName.Buffer != NULL)
7808 {
7809 RxFreePoolWithTag(RxContext->PrefixClaim.SuppliedPathName.Buffer, RX_MISC_POOLTAG);
7810 }
7811
7813
7814 RxContext->MajorFunction = IRP_MJ_DEVICE_CONTROL;
7815 }
7816
7817 return Status;
7818}
@ Create
Definition: registry.c:563
#define NonPagedPool
Definition: env_spec_w32.h:307
struct _FileName FileName
Definition: fatprocs.h:896
#define UserMode
Definition: asm.h:35
PIO_SECURITY_CONTEXT SecurityContext
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define MAXUSHORT
Definition: typedefs.h:83

Referenced by RxCommonDevFCBIoCtl().

◆ RxPrepareToReparseSymbolicLink()

NTSTATUS NTAPI RxPrepareToReparseSymbolicLink ( PRX_CONTEXT  RxContext,
BOOLEAN  SymbolicLinkEmbeddedInOldPath,
PUNICODE_STRING  NewPath,
BOOLEAN  NewPathIsAbsolute,
PBOOLEAN  ReparseRequired 
)

Definition at line 7825 of file rdbss.c.

7831{
7832 PWSTR NewBuffer;
7835
7836 /* Assume no reparse is required first */
7837 *ReparseRequired = FALSE;
7838
7839 /* Only supported for IRP_MJ_CREATE */
7840 if (RxContext->MajorFunction != IRP_MJ_CREATE)
7841 {
7843 }
7844
7845 /* If symbolic link is not embedded, and DELETE is specified, fail */
7846 if (!SymbolicLinkEmbeddedInOldPath)
7847 {
7848 /* Excepted if DELETE is the only flag specified, then, open has to succeed
7849 * See: https://msdn.microsoft.com/en-us/library/windows/hardware/ff554649(v=vs.85).aspx (remarks)
7850 */
7851 if (BooleanFlagOn(RxContext->Create.NtCreateParameters.DesiredAccess, DELETE) &&
7852 BooleanFlagOn(RxContext->Create.NtCreateParameters.DesiredAccess, ~DELETE))
7853 {
7854 return STATUS_ACCESS_DENIED;
7855 }
7856 }
7857
7858 /* At that point, assume reparse will be required */
7859 *ReparseRequired = TRUE;
7860
7861 /* If new path isn't absolute, it's up to us to make it absolute */
7862 if (!NewPathIsAbsolute)
7863 {
7864 /* The prefix will be \Device\Mup */
7865 NewLength = NewPath->Length + (sizeof(L"\\Device\\Mup") - sizeof(UNICODE_NULL));
7868 if (NewBuffer == NULL)
7869 {
7871 }
7872
7873 /* Copy data for the new path */
7874 RtlMoveMemory(NewBuffer, L"\\Device\\Mup", (sizeof(L"\\Device\\Mup") - sizeof(UNICODE_NULL)));
7875 RtlMoveMemory(Add2Ptr(NewBuffer, (sizeof(L"\\Device\\Mup") - sizeof(UNICODE_NULL))),
7876 NewPath->Buffer, NewPath->Length);
7877 }
7878 /* Otherwise, use caller path as it */
7879 else
7880 {
7881 NewLength = NewPath->Length;
7882 NewBuffer = NewPath->Buffer;
7883 }
7884
7885 /* Get the FILE_OBJECT we'll modify */
7886 FileObject = RxContext->CurrentIrpSp->FileObject;
7887
7888 /* Free old path first */
7889 ExFreePoolWithTag(FileObject->FileName.Buffer, 0);
7890 /* And setup new one */
7891 FileObject->FileName.Length = NewLength;
7892 FileObject->FileName.MaximumLength = NewLength;
7893 FileObject->FileName.Buffer = NewBuffer;
7894
7895 /* And set reparse flag */
7897
7898 /* Done! */
7899 return STATUS_SUCCESS;
7900}
static USHORT USHORT * NewLength
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145

◆ RxPrePostIrp()

VOID RxPrePostIrp ( IN PVOID  Context,
IN PIRP  Irp 
)

Definition at line 7906 of file rdbss.c.

7909{
7912 PRX_CONTEXT RxContext = Context;
7913
7914 /* NULL IRP is no option */
7915 if (Irp == NULL)
7916 {
7917 return;
7918 }
7919
7920 /* Check whether preparation was really needed */
7922 {
7923 return;
7924 }
7925 /* Mark the context as prepared */
7927
7928 /* Just lock the user buffer, with the correct length, depending on the MJ */
7930 Stack = RxContext->CurrentIrpSp;
7931 if (RxContext->MajorFunction == IRP_MJ_READ || RxContext->MajorFunction == IRP_MJ_WRITE)
7932 {
7933 if (!BooleanFlagOn(RxContext->MinorFunction, IRP_MN_MDL))
7934 {
7935 if (RxContext->MajorFunction == IRP_MJ_READ)
7936 {
7938 }
7939 RxLockUserBuffer(RxContext, Lock, Stack->Parameters.Read.Length);
7940 }
7941 }
7942 else
7943 {
7944 if ((RxContext->MajorFunction == IRP_MJ_DIRECTORY_CONTROL && RxContext->MinorFunction == IRP_MN_QUERY_DIRECTORY) ||
7945 RxContext->MajorFunction == IRP_MJ_QUERY_EA)
7946 {
7948 RxLockUserBuffer(RxContext, Lock, Stack->Parameters.QueryDirectory.Length);
7949 }
7950 else if (RxContext->MajorFunction == IRP_MJ_SET_EA)
7951 {
7952 RxLockUserBuffer(RxContext, Lock, Stack->Parameters.SetEa.Length);
7953 }
7954 }
7955
7956 /* As it will be posted (async), mark the IRP pending */
7958}
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127
enum _LOCK_OPERATION LOCK_OPERATION
@ IoReadAccess
Definition: ketypes.h:863

Referenced by RxCommonWrite(), and RxFsdPostRequest().

◆ RxpSetInfoMiniRdr()

NTSTATUS RxpSetInfoMiniRdr ( PRX_CONTEXT  RxContext,
FILE_INFORMATION_CLASS  Class 
)

Definition at line 7964 of file rdbss.c.

7967{
7968 PFCB Fcb;
7970
7971 /* Initialize parameters in RX_CONTEXT */
7972 RxContext->Info.FileInformationClass = Class;
7973 RxContext->Info.Buffer = RxContext->CurrentIrp->AssociatedIrp.SystemBuffer;
7974 RxContext->Info.Length = RxContext->CurrentIrpSp->Parameters.SetFile.Length;
7975
7976 /* And call mini-rdr */
7977 Fcb = (PFCB)RxContext->pFcb;
7978 MINIRDR_CALL(Status, RxContext, Fcb->MRxDispatch, MRxSetFileInfo, (RxContext));
7979
7980 return Status;
7981}
struct _IO_STACK_LOCATION::@3978::@3988 SetFile
PVOID SystemBuffer
union _IRP::@1566 AssociatedIrp

Referenced by RxSetBasicInfo(), RxSetDispositionInfo(), and RxSetRenameInfo().

◆ RxpUnregisterMinirdr()

VOID NTAPI RxpUnregisterMinirdr ( IN PRDBSS_DEVICE_OBJECT  RxDeviceObject)

Definition at line 7985 of file rdbss.c.

7987{
7989}

◆ RxPurgeNetFcb()

VOID RxPurgeNetFcb ( PFCB  Fcb,
PRX_CONTEXT  LocalContext 
)

Definition at line 7995 of file rdbss.c.

7998{
8000
8001 PAGED_CODE();
8002
8003 /* First, flush */
8005
8006 /* And force close */
8011}
BOOLEAN NTAPI MmForceSectionClosed(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN BOOLEAN DelayClose)
Definition: section.c:3042

Referenced by RxCloseAssociatedSrvOpen().

◆ RxQueryAlternateNameInfo()

NTSTATUS RxQueryAlternateNameInfo ( PRX_CONTEXT  RxContext,
PFILE_NAME_INFORMATION  AltNameInfo 
)

Definition at line 8014 of file rdbss.c.

8017{
8020}

Referenced by RxCommonQueryInformation().

◆ RxQueryBasicInfo()

NTSTATUS RxQueryBasicInfo ( PRX_CONTEXT  RxContext,
PFILE_BASIC_INFORMATION  BasicInfo 
)

Definition at line 8026 of file rdbss.c.

8029{
8030 PAGED_CODE();
8031
8032 DPRINT("RxQueryBasicInfo(%p, %p)\n", RxContext, BasicInfo);
8033
8034 /* Simply zero and forward to mini-rdr */
8035 RtlZeroMemory(BasicInfo, sizeof(FILE_BASIC_INFORMATION));
8036 return RxpQueryInfoMiniRdr(RxContext, FileBasicInformation, BasicInfo);
8037}

Referenced by RxCommonQueryInformation().

◆ RxQueryCompressedInfo()

NTSTATUS RxQueryCompressedInfo ( PRX_CONTEXT  RxContext,
PFILE_COMPRESSION_INFORMATION  CompressionInfo 
)

Definition at line 8040 of file rdbss.c.

8043{
8046}

Referenced by RxCommonQueryInformation().

◆ RxQueryDirectory()

NTSTATUS RxQueryDirectory ( PRX_CONTEXT  RxContext)

Definition at line 8052 of file rdbss.c.

8054{
8055 PIRP Irp;
8056 PFCB Fcb;
8057 PFOBX Fobx;
8058 UCHAR Flags;
8060 BOOLEAN LockNotGranted;
8061 ULONG Length, FileIndex;
8064 FILE_INFORMATION_CLASS FileInfoClass;
8065
8066 PAGED_CODE();
8067
8068 DPRINT("RxQueryDirectory(%p)\n", RxContext);
8069
8070 /* Get parameters */
8071 Stack = RxContext->CurrentIrpSp;
8073 FileName = Stack->Parameters.QueryDirectory.FileName;
8074 FileInfoClass = Stack->Parameters.QueryDirectory.FileInformationClass;
8075 DPRINT("Wait: %d, Length: %ld, FileName: %p, Class: %d\n",
8077 FileName, FileInfoClass);
8078
8079 Irp = RxContext->CurrentIrp;
8080 Flags = Stack->Flags;
8081 FileIndex = Stack->Parameters.QueryDirectory.FileIndex;
8082 DPRINT("Index: %d, Buffer: %p, Flags: %x\n", FileIndex, Irp->UserBuffer, Flags);
8083
8084 if (FileName != NULL)
8085 {
8086 DPRINT("FileName: %wZ\n", FileName);
8087 }
8088
8089 /* No FOBX: not a standard file/directory */
8090 Fobx = (PFOBX)RxContext->pFobx;
8091 if (Fobx == NULL)
8092 {
8094 }
8095
8096 /* We can only deal with a disk */
8097 Fcb = (PFCB)RxContext->pFcb;
8098 if (Fcb->pNetRoot->Type != NET_ROOT_DISK)
8099 {
8100 DPRINT1("Not a disk! %x\n", Fcb->pNetRoot->Type);
8102 }
8103
8104 /* Setup RX_CONTEXT related fields */
8105 RxContext->QueryDirectory.FileIndex = FileIndex;
8106 RxContext->QueryDirectory.RestartScan = BooleanFlagOn(Flags, SL_RESTART_SCAN);
8107 RxContext->QueryDirectory.ReturnSingleEntry = BooleanFlagOn(Flags, SL_RETURN_SINGLE_ENTRY);
8108 RxContext->QueryDirectory.IndexSpecified = BooleanFlagOn(Flags, SL_INDEX_SPECIFIED);
8109 RxContext->QueryDirectory.InitialQuery = (Fobx->UnicodeQueryTemplate.Buffer == NULL) && !BooleanFlagOn(Fobx->Flags, FOBX_FLAG_MATCH_ALL);
8110
8111 /* We don't support (yet?) a specific index being set */
8112 if (RxContext->QueryDirectory.IndexSpecified)
8113 {
8115 }
8116
8117 /* Try to lock FCB */
8118 LockNotGranted = TRUE;
8119 if (RxContext->QueryDirectory.InitialQuery)
8120 {
8121 Status = RxAcquireExclusiveFcb(RxContext, Fcb);
8123 {
8124 if (!NT_SUCCESS(Status))
8125 {
8126 return Status;
8127 }
8128
8129 if (Fobx->UnicodeQueryTemplate.Buffer != NULL)
8130 {
8131 RxContext->QueryDirectory.InitialQuery = FALSE;
8132 RxConvertToSharedFcb(RxContext, Fcb);
8133 }
8134
8135 LockNotGranted = FALSE;
8136 }
8137 }
8138 else
8139 {
8140 Status = RxAcquireExclusiveFcb(RxContext, Fcb);
8142 {
8143 if (!NT_SUCCESS(Status))
8144 {
8145 return Status;
8146 }
8147
8148 LockNotGranted = FALSE;
8149 }
8150 }
8151
8152 /* If it failed, post request */
8153 if (LockNotGranted)
8154 {
8155 return RxFsdPostRequest(RxContext);
8156 }
8157
8158 /* This cannot be done on a orphaned directory */
8160 {
8161 RxReleaseFcb(RxContext, Fcb);
8162 return STATUS_FILE_CLOSED;
8163 }
8164
8165 _SEH2_TRY
8166 {
8167 /* Set index */
8168 if (!RxContext->QueryDirectory.IndexSpecified && RxContext->QueryDirectory.RestartScan)
8169 {
8170 RxContext->QueryDirectory.FileIndex = 0;
8171 }
8172
8173 /* Assume success */
8175 /* If initial query, prepare FOBX */
8176 if (RxContext->QueryDirectory.InitialQuery)
8177 {
8178 /* We cannot have a template already! */
8180
8181 /* If we have a file name and a correct one, duplicate it in the FOBX */
8182 if (FileName != NULL && FileName->Length != 0 && FileName->Buffer != NULL &&
8183 (FileName->Length != sizeof(WCHAR) || FileName->Buffer[0] != '*') &&
8184 (FileName->Length != 12 * sizeof(WCHAR) ||
8185 RtlCompareMemory(FileName->Buffer, Rx8QMdot3QM, 12 * sizeof(WCHAR)) != 12 * sizeof(WCHAR)))
8186 {
8188
8189 Fobx->UnicodeQueryTemplate.Buffer = RxAllocatePoolWithTag(PagedPool, FileName->Length, RX_DIRCTL_POOLTAG);
8190 if (Fobx->UnicodeQueryTemplate.Buffer != NULL)
8191 {
8192 /* UNICODE_STRING; length has to be even */
8193 if ((FileName->Length & 1) != 0)
8194 {
8196 RxFreePoolWithTag(Fobx->UnicodeQueryTemplate.Buffer, RX_DIRCTL_POOLTAG);
8197 }
8198 else
8199 {
8200 Fobx->UnicodeQueryTemplate.Length = FileName->Length;
8201 Fobx->UnicodeQueryTemplate.MaximumLength = FileName->Length;
8202 RtlMoveMemory(Fobx->UnicodeQueryTemplate.Buffer, FileName->Buffer, FileName->Length);
8203
8204 SetFlag(Fobx->Flags, FOBX_FLAG_FREE_UNICODE);
8205 }
8206 }
8207 else
8208 {
8210 }
8211 }
8212 /* No name specified, or a match all wildcard? Match everything */
8213 else
8214 {
8215 Fobx->ContainsWildCards = TRUE;
8216
8217 Fobx->UnicodeQueryTemplate.Buffer = &RxStarForTemplate;
8218 Fobx->UnicodeQueryTemplate.Length = sizeof(WCHAR);
8219 Fobx->UnicodeQueryTemplate.MaximumLength = sizeof(WCHAR);
8220
8221 SetFlag(Fobx->Flags, FOBX_FLAG_MATCH_ALL);
8222 }
8223
8224 /* No need for exclusive any longer */
8225 if (NT_SUCCESS(Status))
8226 {
8227 RxConvertToSharedFcb(RxContext, Fcb);
8228 }
8229 }
8230
8231 /* Lock user buffer and forward to mini-rdr */
8232 if (NT_SUCCESS(Status))
8233 {
8235 RxContext->Info.FileInformationClass = FileInfoClass;
8236 RxContext->Info.Buffer = RxNewMapUserBuffer(RxContext);
8237 RxContext->Info.Length = Length;
8238
8239 if (RxContext->Info.Buffer != NULL)
8240 {
8241 MINIRDR_CALL(Status, RxContext, Fcb->MRxDispatch, MRxQueryDirectory, (RxContext));
8242 }
8243
8244 /* Post if mini-rdr asks to */
8245 if (RxContext->PostRequest)
8246 {
8247 RxFsdPostRequest(RxContext);
8248 }
8249 else
8250 {
8251 Irp->IoStatus.Information = Length - RxContext->Info.LengthRemaining;
8252 }
8253 }
8254 }
8256 {
8257 RxReleaseFcb(RxContext, Fcb);
8258 }
8259 _SEH2_END;
8260
8261 return Status;
8262}
#define FOBX_FLAG_MATCH_ALL
Definition: fcb.h:289
#define FOBX_FLAG_FREE_UNICODE
Definition: fcb.h:290
WCHAR Rx8QMdot3QM[]
Definition: rdbss.c:531
WCHAR RxStarForTemplate
Definition: rdbss.c:530
#define RX_DIRCTL_POOLTAG
Definition: rxpooltg.h:20
BOOLEAN ContainsWildCards
Definition: fcb.h:321
struct _IO_STACK_LOCATION::@3978::@3984 QueryDirectory
struct _RX_CONTEXT::@2148::@2161 QueryDirectory
#define SL_INDEX_SPECIFIED
Definition: iotypes.h:1837
#define SL_RETURN_SINGLE_ENTRY
Definition: iotypes.h:1836
#define SL_RESTART_SCAN
Definition: iotypes.h:1835
@ IoModifyAccess
Definition: ketypes.h:865

Referenced by RxCommonDirectoryControl().

◆ RxQueryEaInfo()

NTSTATUS RxQueryEaInfo ( PRX_CONTEXT  RxContext,
PFILE_EA_INFORMATION  EaInfo 
)

Definition at line 8265 of file rdbss.c.

8268{
8271}

Referenced by RxCommonQueryInformation().

◆ RxQueryInternalInfo()

NTSTATUS RxQueryInternalInfo ( PRX_CONTEXT  RxContext,
PFILE_INTERNAL_INFORMATION  InternalInfo 
)

Definition at line 8274 of file rdbss.c.

8277{
8280}

Referenced by RxCommonQueryInformation().

◆ RxQueryNameInfo()

NTSTATUS RxQueryNameInfo ( PRX_CONTEXT  RxContext,
PFILE_NAME_INFORMATION  NameInfo 
)

Definition at line 8286 of file rdbss.c.

8289{
8290 PFCB Fcb;
8291 PFOBX Fobx;
8292 PAGED_CODE();
8293
8294 DPRINT("RxQueryNameInfo(%p, %p)\n", RxContext, NameInfo);
8295
8296 /* Check we can at least copy name size */
8297 if (RxContext->Info.LengthRemaining < FIELD_OFFSET(FILE_NAME_INFORMATION, FileName))
8298 {
8299 DPRINT1("Buffer too small: %d\n", RxContext->Info.LengthRemaining);
8300 RxContext->Info.Length = 0;
8302 }
8303
8304 RxContext->Info.LengthRemaining -= FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
8305
8306 Fcb = (PFCB)RxContext->pFcb;
8307 Fobx = (PFOBX)RxContext->pFobx;
8308 /* Get the UNC name */
8309 RxConjureOriginalName(Fcb, Fobx, &NameInfo->FileNameLength, &NameInfo->FileName[0],
8310 &RxContext->Info.Length, VNetRoot_As_UNC_Name);
8311
8312 /* If RxConjureOriginalName returned a negative len (-1) then output buffer
8313 * was too small, return the appropriate length & status.
8314 */
8315 if (RxContext->Info.LengthRemaining < 0)
8316 {
8317 DPRINT1("Buffer too small!\n");
8318 RxContext->Info.Length = 0;
8320 }
8321
8322#if 1 // CORE-13938, rfb: please note I replaced 0 with 1 here
8324 RxContext->Info.LengthRemaining >= sizeof(WCHAR))
8325 {
8326 NameInfo->FileName[NameInfo->FileNameLength / sizeof(WCHAR)] = L'\\';
8327 NameInfo->FileNameLength += sizeof(WCHAR);
8328 RxContext->Info.LengthRemaining -= sizeof(WCHAR);
8329 }
8330#endif
8331
8332 /* All correct */
8333 return STATUS_SUCCESS;
8334}
VOID RxConjureOriginalName(PFCB Fcb, PFOBX Fobx, PULONG ActualNameLength, PWCHAR OriginalName, PLONG LengthRemaining, RX_NAME_CONJURING_METHODS NameConjuringMethod)
Definition: rdbss.c:4911

Referenced by RxCommonQueryInformation().

◆ RxQueryPipeInfo()

NTSTATUS RxQueryPipeInfo ( PRX_CONTEXT  RxContext,
PFILE_PIPE_INFORMATION  PipeInfo 
)

Definition at line 8337 of file rdbss.c.

8340{
8343}

Referenced by RxCommonQueryInformation().

◆ RxQueryPositionInfo()

NTSTATUS RxQueryPositionInfo ( PRX_CONTEXT  RxContext,
PFILE_POSITION_INFORMATION  PositionInfo 
)

Definition at line 8346 of file rdbss.c.

8349{
8352}

Referenced by RxCommonQueryInformation().

◆ RxQueryStandardInfo()

NTSTATUS RxQueryStandardInfo ( PRX_CONTEXT  RxContext,
PFILE_STANDARD_INFORMATION  StandardInfo 
)

Definition at line 8358 of file rdbss.c.

8361{
8362 PFCB Fcb;
8363 PFOBX Fobx;
8365
8366 PAGED_CODE();
8367
8368 DPRINT("RxQueryStandardInfo(%p, %p)\n", RxContext, StandardInfo);
8369
8370 /* Zero output buffer */
8371 RtlZeroMemory(StandardInfo, sizeof(FILE_STANDARD_INFORMATION));
8372
8373 Fcb = (PFCB)RxContext->pFcb;
8374 Fobx = (PFOBX)RxContext->pFobx;
8375 /* If not a standard file type, or opened for backup, immediately forward to mini-rdr */
8377 BooleanFlagOn(Fobx->pSrvOpen->CreateOptions, FILE_OPEN_FOR_BACKUP_INTENT))
8378 {
8379 return RxpQueryInfoMiniRdr(RxContext, FileStandardInformation, StandardInfo);
8380 }
8381
8382 /* Otherwise, fill what we can already */
8384 StandardInfo->NumberOfLinks = Fcb->NumberOfLinks;
8387 if (StandardInfo->NumberOfLinks == 0)
8388 {
8389 StandardInfo->NumberOfLinks = 1;
8390 }
8391
8393 {
8394 StandardInfo->AllocationSize.QuadPart = Fcb->Header.AllocationSize.QuadPart;
8396 }
8397
8398 /* If we are asked to forcefully forward to mini-rdr or if size isn't cached, do it */
8400 {
8401 Status = RxpQueryInfoMiniRdr(RxContext, FileStandardInformation, StandardInfo);
8402 }
8403 else
8404 {
8406 }
8407
8408 return Status;
8409}
#define FCB_STATE_FILESIZECACHEING_ENABLED
Definition: fcb.h:219
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
#define FILE_STANDARD_INFORMATION
Definition: disk.h:54
BOOLEAN RxForceQFIPassThrough
Definition: rdbss.c:613
ULONG NumberOfLinks
Definition: fcb.h:156
LARGE_INTEGER AllocationSize
Definition: propsheet.cpp:54

Referenced by RxCommonQueryInformation().

◆ RxReadRegistryParameters()

VOID NTAPI RxReadRegistryParameters ( VOID  )

Definition at line 8416 of file rdbss.c.

8418{
8422 UCHAR Buffer[0x40];
8423 UNICODE_STRING KeyName, ParamName;
8426
8427 PAGED_CODE();
8428
8429 RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\LanmanWorkStation\\Parameters");
8432 if (!NT_SUCCESS(Status))
8433 {
8434 return;
8435 }
8436
8438 RtlInitUnicodeString(&ParamName, L"DisableByteRangeLockingOnReadOnlyFiles");
8439 Status = ZwQueryValueKey(KeyHandle, &ParamName, KeyValuePartialInformation, PartialInfo, sizeof(Buffer), &ResultLength);
8440 if (NT_SUCCESS(Status) && PartialInfo->Type == REG_DWORD)
8441 {
8442 DisableByteRangeLockingOnReadOnlyFiles = (*(PULONG)PartialInfo->Data != 0);
8443 }
8444
8445 RtlInitUnicodeString(&ParamName, L"ReadAheadGranularity");
8446 Status = ZwQueryValueKey(KeyHandle, &ParamName, KeyValuePartialInformation, PartialInfo, sizeof(Buffer), &ResultLength);
8447 if (NT_SUCCESS(Status) && PartialInfo->Type == REG_DWORD)
8448 {
8449 ULONG Granularity = *(PULONG)PartialInfo->Data;
8450
8451 if (Granularity > 16)
8452 {
8453 Granularity = 16;
8454 }
8455
8456 ReadAheadGranularity = Granularity << PAGE_SHIFT;
8457 }
8458
8459 RtlInitUnicodeString(&ParamName, L"DisableFlushOnCleanup");
8460 Status = ZwQueryValueKey(KeyHandle, &ParamName, KeyValuePartialInformation, PartialInfo, sizeof(Buffer), &ResultLength);
8461 if (NT_SUCCESS(Status) && PartialInfo->Type == REG_DWORD)
8462 {
8463 DisableFlushOnCleanup = (*(PULONG)PartialInfo->Data != 0);
8464 }
8465
8467}
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
BOOLEAN DisableByteRangeLockingOnReadOnlyFiles
Definition: rdbss.c:532
ULONG ReadAheadGranularity
Definition: rdbss.c:534
#define REG_DWORD
Definition: sdbapi.c:596
uint32_t * PULONG
Definition: typedefs.h:59

Referenced by RxDriverEntry().

◆ RxRegisterMinirdr()

NTSTATUS NTAPI RxRegisterMinirdr ( OUT PRDBSS_DEVICE_OBJECT DeviceObject,
IN OUT PDRIVER_OBJECT  DriverObject,
IN PMINIRDR_DISPATCH  MrdrDispatch,
IN ULONG  Controls,
IN PUNICODE_STRING  DeviceName,
IN ULONG  DeviceExtensionSize,
IN DEVICE_TYPE  DeviceType,
IN ULONG  DeviceCharacteristics 
)

Definition at line 8474 of file rdbss.c.

8483{
8485 PRDBSS_DEVICE_OBJECT RDBSSDevice;
8486
8487 PAGED_CODE();
8488
8489 if (!DeviceObject)
8490 {
8492 }
8493
8494 /* Create device object with provided parameters */
8496 DeviceExtensionSize + sizeof(RDBSS_DEVICE_OBJECT),
8497 DeviceName,
8498 DeviceType,
8500 FALSE,
8501 (PDEVICE_OBJECT *)&RDBSSDevice);
8502 if (!NT_SUCCESS(Status))
8503 {
8504 return Status;
8505 }
8506
8507 if (!RxData.DriverObject)
8508 {
8509 return STATUS_UNSUCCESSFUL;
8510 }
8511
8512 /* Initialize our DO extension */
8513 RDBSSDevice->RDBSSDeviceObject = NULL;
8514 ++RxFileSystemDeviceObject->ReferenceCount;
8515 *DeviceObject = RDBSSDevice;
8516 RDBSSDevice->RdbssExports = &RxExports;
8517 RDBSSDevice->Dispatch = MrdrDispatch;
8518 RDBSSDevice->RegistrationControls = Controls;
8519 RDBSSDevice->DeviceName = *DeviceName;
8522 InitializeListHead(&RDBSSDevice->OverflowQueue[0]);
8523 InitializeListHead(&RDBSSDevice->OverflowQueue[1]);
8524 InitializeListHead(&RDBSSDevice->OverflowQueue[2]);
8527
8528 DPRINT("Registered MiniRdr %wZ (prio: %x)\n", DeviceName, RDBSSDevice->NetworkProviderPriority);
8529
8533
8534 /* Unless mini-rdr explicitly asked not to, initialize dispatch table */
8536 {
8538 }
8539
8540 /* Unless mini-rdr explicitly asked not to, initialize prefix scavenger */
8542 {
8543 LARGE_INTEGER ScavengerTimeLimit;
8544
8545 RDBSSDevice->pRxNetNameTable = &RDBSSDevice->RxNetNameTableInDeviceObject;
8548 ScavengerTimeLimit.QuadPart = MrdrDispatch->ScavengerTimeout * 10000000LL;
8549 RDBSSDevice->pRdbssScavenger = &RDBSSDevice->RdbssScavengerInDeviceObject;
8550 RxInitializeRdbssScavenger(RDBSSDevice->pRdbssScavenger, ScavengerTimeLimit);
8551 }
8552
8554
8555 return STATUS_SUCCESS;
8556}
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
DeviceType
Definition: mmdrv.h:42
#define RX_REGISTERMINI_FLAG_DONT_PROVIDE_MAILSLOTS
Definition: mrx.h:10
#define RX_REGISTERMINI_FLAG_DONT_INIT_DRIVER_DISPATCH
Definition: mrx.h:11
#define RX_REGISTERMINI_FLAG_DONT_PROVIDE_UNCS
Definition: mrx.h:9
#define RX_REGISTERMINI_FLAG_DONT_INIT_PREFIX_N_SCAVENGER
Definition: mrx.h:12
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
VOID RxInitializePrefixTable(_Inout_ PRX_PREFIX_TABLE ThisTable, _In_opt_ ULONG TableSize, _In_ BOOLEAN CaseInsensitiveMatch)
ULONG RxGetNetworkProviderPriority(PUNICODE_STRING DeviceName)
Definition: rdbss.c:6683
VOID RxInitializeMinirdrDispatchTable(IN PDRIVER_OBJECT DriverObject)
Definition: rdbss.c:6953
#define RxInitializeRdbssScavenger(Scavenger, ScavengerTimeLimit)
Definition: scavengr.h:84
ULONG NetworkProviderPriority
Definition: rxstruc.h:91
PMINIRDR_DISPATCH Dispatch
Definition: rxstruc.h:89
BOOLEAN RegisterMailSlotProvider
Definition: rxstruc.h:94
RDBSS_SCAVENGER RdbssScavengerInDeviceObject
Definition: rxstruc.h:130
PRDBSS_SCAVENGER pRdbssScavenger
Definition: rxstruc.h:129
PRDBSS_EXPORTS RdbssExports
Definition: rxstruc.h:87
RX_PREFIX_TABLE RxNetNameTableInDeviceObject
Definition: rxstruc.h:128
PDEVICE_OBJECT RDBSSDeviceObject
Definition: rxstruc.h:88
PKEVENT pAsynchronousRequestsCompletionEvent
Definition: rxstruc.h:124
ULONG RegistrationControls
Definition: rxstruc.h:86
BOOLEAN RegisterUncProvider
Definition: rxstruc.h:93
UNICODE_STRING DeviceName
Definition: rxstruc.h:90
LIST_ENTRY MiniRdrListLinks
Definition: rxstruc.h:97
BOOLEAN IsNetNameTable
Definition: prefix.h:70
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
_In_ WDFDEVICE _In_ ULONG DeviceCharacteristics
Definition: wdfdevice.h:2775

◆ 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().

◆ RxRemoveFromTopLevelIrpAllocatedContextsList()

VOID RxRemoveFromTopLevelIrpAllocatedContextsList ( PRX_TOPLEVELIRP_CONTEXT  TopLevelContext)

Definition at line 8562 of file rdbss.c.

8564{
8565 KIRQL OldIrql;
8566
8567 /* Make sure this is a TLC and that it was allocated (otherwise, it is not in the list */
8570
8572 RemoveEntryList(&TopLevelContext->ListEntry);
8574}

Referenced by RxUnwindTopLevelIrp().

◆ RxRemoveOverflowEntry()

PRX_CONTEXT RxRemoveOverflowEntry ( PRDBSS_DEVICE_OBJECT  DeviceObject,
WORK_QUEUE_TYPE  Queue 
)

Definition at line 8580 of file rdbss.c.

8583{
8584 KIRQL OldIrql;
8586
8587 KeAcquireSpinLock(&DeviceObject->OverflowQueueSpinLock, &OldIrql);
8588 if (DeviceObject->OverflowQueueCount[Queue] <= 0)
8589 {
8590 /* No entries left, nothing to return */
8591 InterlockedDecrement(&DeviceObject->PostedRequestCount[Queue]);
8592 Context = NULL;
8593 }
8594 else
8595 {
8597
8598 /* Decrement count */
8599 --DeviceObject->OverflowQueueCount[Queue];
8600
8601 /* Return head */
8602 Entry = RemoveHeadList(&DeviceObject->OverflowQueue[Queue]);
8603 Context = CONTAINING_RECORD(Entry, RX_CONTEXT, OverflowListEntry);
8605 Context->OverflowListEntry.Flink = NULL;
8606 }
8607 KeReleaseSpinLock(&DeviceObject->OverflowQueueSpinLock, OldIrql);
8608
8609 return Context;
8610}

Referenced by RxFspDispatch().

◆ RxRemoveShareAccessPerSrvOpens()

VOID RxRemoveShareAccessPerSrvOpens ( IN OUT PSRV_OPEN  SrvOpen)

Definition at line 8635 of file rdbss.c.

8637{
8641 BOOLEAN DeleteAccess;
8642
8643 PAGED_CODE();
8644
8645 /* Get access that were granted to SRV_OPEN */
8646 DesiredAccess = SrvOpen->DesiredAccess;
8649 DeleteAccess = (DesiredAccess & DELETE) != 0;
8650
8651 /* If any, drop them */
8652 if ((ReadAccess) || (WriteAccess) || (DeleteAccess))
8653 {
8654 BOOLEAN SharedRead;
8655 BOOLEAN SharedWrite;
8656 BOOLEAN SharedDelete;
8659
8660 ShareAccess = &((PFCB)SrvOpen->pFcb)->ShareAccessPerSrvOpens;
8661 DesiredShareAccess = SrvOpen->ShareAccess;
8662
8663 ShareAccess->Readers -= ReadAccess;
8664 ShareAccess->Writers -= WriteAccess;
8665 ShareAccess->Deleters -= DeleteAccess;
8666
8667 ShareAccess->OpenCount--;
8668
8669 SharedRead = (DesiredShareAccess & FILE_SHARE_READ) != 0;
8670 SharedWrite = (DesiredShareAccess & FILE_SHARE_WRITE) != 0;
8671 SharedDelete = (DesiredShareAccess & FILE_SHARE_DELETE) != 0;
8672 ShareAccess->SharedRead -= SharedRead;
8673 ShareAccess->SharedWrite -= SharedWrite;
8674 ShareAccess->SharedDelete -= SharedDelete;
8675 }
8676}

Referenced by RxCloseAssociatedSrvOpen().

◆ RxSearchForCollapsibleOpen()

NTSTATUS RxSearchForCollapsibleOpen ( PRX_CONTEXT  RxContext,
ACCESS_MASK  DesiredAccess,
ULONG  ShareAccess 
)

Definition at line 8679 of file rdbss.c.

8683{
8684 PFCB Fcb;
8686 PLIST_ENTRY ListEntry;
8687 BOOLEAN ShouldTry, Purged, Scavenged;
8688
8689 PAGED_CODE();
8690
8691 DPRINT("RxSearchForCollapsibleOpen(%p, %x, %x)\n", RxContext, DesiredAccess, ShareAccess);
8692
8693 Fcb = (PFCB)RxContext->pFcb;
8694
8695 /* If we're asked to open for backup, don't allow SRV_OPEN reuse */
8696 if (BooleanFlagOn(RxContext->Create.NtCreateParameters.CreateOptions, FILE_OPEN_FOR_BACKUP_INTENT))
8697 {
8699
8702
8703 return STATUS_NOT_FOUND;
8704 }
8705
8706 /* If basic open, ask the mini-rdr if we should try to collapse */
8707 if (RxContext->Create.NtCreateParameters.Disposition == FILE_OPEN ||
8708 RxContext->Create.NtCreateParameters.Disposition == FILE_OPEN_IF)
8709 {
8710 ShouldTry = TRUE;
8711
8712 if (Fcb->MRxDispatch != NULL)
8713 {
8714 ASSERT(RxContext->pRelevantSrvOpen == NULL);
8716
8717 ShouldTry = NT_SUCCESS(Fcb->MRxDispatch->MRxShouldTryToCollapseThisOpen(RxContext));
8718 }
8719 }
8720 else
8721 {
8722 ShouldTry = FALSE;
8723 }
8724
8725 if (BooleanFlagOn(RxContext->Create.NtCreateParameters.CreateOptions, FILE_DELETE_ON_CLOSE))
8726 {
8727 ShouldTry = FALSE;
8728 }
8729
8730 /* If we shouldn't try, ask the caller to allocate a new SRV_OPEN */
8731 if (!ShouldTry)
8732 {
8734 {
8735 return STATUS_NOT_FOUND;
8736 }
8737
8739
8742
8743 return STATUS_NOT_FOUND;
8744 }
8745
8746 /* Only collapse for matching NET_ROOT & disks */
8747 if (Fcb->pNetRoot != RxContext->Create.pNetRoot ||
8748 Fcb->pNetRoot->Type != NET_ROOT_DISK)
8749 {
8750 return STATUS_NOT_FOUND;
8751 }
8752
8753 Purged = FALSE;
8754 Scavenged = FALSE;
8756TryAgain:
8757 /* Browse all our SRV_OPEN to find the matching one */
8758 for (ListEntry = Fcb->SrvOpenList.Flink;
8759 ListEntry != &Fcb->SrvOpenList;
8760 ListEntry = ListEntry->Flink)
8761 {
8762 PSRV_OPEN SrvOpen;
8763
8764 SrvOpen = CONTAINING_RECORD(ListEntry, SRV_OPEN, SrvOpenQLinks);
8765 /* Not the same VNET_ROOT, move to the next one */
8766 if (SrvOpen->pVNetRoot != RxContext->Create.pVNetRoot)
8767 {
8768 RxContext->Create.TryForScavengingOnSharingViolation = TRUE;
8769 continue;
8770 }
8771
8772 /* Is there a sharing violation? */
8773 if (SrvOpen->DesiredAccess != DesiredAccess || SrvOpen->ShareAccess != ShareAccess ||
8775 {
8776 if (SrvOpen->pVNetRoot != RxContext->Create.pVNetRoot)
8777 {
8778 RxContext->Create.TryForScavengingOnSharingViolation = TRUE;
8779 continue;
8780 }
8781
8782 /* Check against the SRV_OPEN */
8784 if (!NT_SUCCESS(Status))
8785 {
8786 break;
8787 }
8788 }
8789 else
8790 {
8791 /* Don't allow collaspse for reparse point opening */
8792 if (BooleanFlagOn(RxContext->Create.NtCreateParameters.CreateOptions ^ SrvOpen->CreateOptions, FILE_OPEN_REPARSE_POINT))
8793 {
8794 Purged = TRUE;
8795 Scavenged = TRUE;
8797 break;
8798 }
8799
8800 /* Not readonly? Or bytereange lock disabled? Try to collapse! */
8802 {
8803 RxContext->pRelevantSrvOpen = (PMRX_SRV_OPEN)SrvOpen;
8804
8807 {
8808 /* Is close delayed - great reuse*/
8809 if (BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_CLOSE_DELAYED))
8810 {
8811 DPRINT("Delayed close successfull, reusing %p\n", SrvOpen);
8812 InterlockedDecrement(&((PSRV_CALL)Fcb->pNetRoot->pSrvCall)->NumberOfCloseDelayedFiles);
8813 ClearFlag(SrvOpen->Flags, SRVOPEN_FLAG_CLOSE_DELAYED);
8814 }
8815
8816 return STATUS_SUCCESS;
8817 }
8818
8820 break;
8821 }
8822 }
8823 }
8824 /* We browse the whole list and didn't find any matching? NOT_FOUND */
8825 if (ListEntry == &Fcb->SrvOpenList)
8826 {
8828 }
8829
8830 /* Only required access: read attributes? Don't reuse */
8831 if ((DesiredAccess & 0xFFEFFFFF) == FILE_READ_ATTRIBUTES)
8832 {
8833 return STATUS_NOT_FOUND;
8834 }
8835
8836 /* Not found? Scavenge and retry to look for collaspile SRV_OPEN */
8837 if (!Scavenged)
8838 {
8840 Scavenged = TRUE;
8842 goto TryAgain;
8843 }
8844
8845 /* Not found? Purgeable? Purge and retry to look for collaspile SRV_OPEN */
8846 if (!Purged && RxIsOkToPurgeFcb(Fcb))
8847 {
8849 Purged = TRUE;
8850 goto TryAgain;
8851 }
8852
8853 /* If sharing violation, keep track of it */
8855 {
8856 RxContext->Create.TryForScavengingOnSharingViolation = TRUE;
8857 }
8858
8859 DPRINT("Status: %x\n", Status);
8860 return Status;
8861}
@ TryAgain
Definition: bl.h:896
#define FILE_OPEN
Definition: from_kernel.h:54
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46
#define FILE_OPEN_IF
Definition: from_kernel.h:56
BOOLEAN RxIsOkToPurgeFcb(PFCB Fcb)
Definition: rdbss.c:7036
NTSTATUS RxCheckShareAccessPerSrvOpens(IN PFCB Fcb, IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess)
Definition: rdbss.c:1477
PMRX_CALLDOWN MRxShouldTryToCollapseThisOpen
Definition: mrx.h:353

Referenced by RxCollapseOrCreateSrvOpen().

◆ RxSetAllocationInfo()

NTSTATUS RxSetAllocationInfo ( PRX_CONTEXT  RxContext)

Definition at line 8864 of file rdbss.c.

8866{
8869}

Referenced by RxCommonSetInformation().

◆ RxSetBasicInfo()

NTSTATUS RxSetBasicInfo ( PRX_CONTEXT  RxContext)

Definition at line 8875 of file rdbss.c.

8877{
8879
8880 PAGED_CODE();
8881
8882#define FILE_ATTRIBUTE_VOLUME 0x8
8883#define VALID_FILE_ATTRIBUTES ( \
8884 FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | \
8885 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_VOLUME | \
8886 FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_DEVICE | \
8887 FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_SPARSE_FILE | \
8888 FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_COMPRESSED | \
8889 FILE_ATTRIBUTE_OFFLINE | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | \
8890 FILE_ATTRIBUTE_ENCRYPTED | FILE_ATTRIBUTE_INTEGRITY_STREAM)
8891#define VALID_DIR_ATTRIBUTES (VALID_FILE_ATTRIBUTES | FILE_ATTRIBUTE_DIRECTORY)
8892
8893 /* First of all, call the mini-rdr */
8895 /* If it succeed, perform last bits */
8896 if (NT_SUCCESS(Status))
8897 {
8898 PIRP Irp;
8899 PFCB Fcb;
8900 PFOBX Fobx;
8902 ULONG Attributes, CleanAttr;
8903 PFILE_BASIC_INFORMATION BasicInfo;
8904
8905 Fcb = (PFCB)RxContext->pFcb;
8906 Fobx = (PFOBX)RxContext->pFobx;
8907 Irp = RxContext->CurrentIrp;
8908 BasicInfo = Irp->AssociatedIrp.SystemBuffer;
8909 FileObject = RxContext->CurrentIrpSp->FileObject;
8910
8911 /* If caller provided flags, handle the change */
8912 Attributes = BasicInfo->FileAttributes;
8913 if (Attributes != 0)
8914 {
8915 /* Clean our flags first, with only stuff we support */
8917 {
8919 }
8920 else
8921 {
8922 CleanAttr = Attributes & VALID_FILE_ATTRIBUTES;
8923 }
8924
8925 /* Handle the temporary mark (set/unset depending on caller) */
8927 {
8930 }
8931 else
8932 {
8935 }
8936
8937 /* And set new attributes */
8938 Fcb->Attributes = CleanAttr;
8939 }
8940
8941 /* If caller provided a creation time, set it */
8942 if (BasicInfo->CreationTime.QuadPart != 0LL)
8943 {
8944 Fcb->CreationTime.QuadPart = BasicInfo->CreationTime.QuadPart;
8946 }
8947
8948 /* If caller provided a last access time, set it */
8949 if (BasicInfo->LastAccessTime.QuadPart != 0LL)
8950 {
8953 }
8954
8955 /* If caller provided a last write time, set it */
8956 if (BasicInfo->LastWriteTime.QuadPart != 0LL)
8957 {
8960 }
8961
8962 /* If caller provided a last change time, set it */
8963 if (BasicInfo->ChangeTime.QuadPart != 0LL)
8964 {
8967 }
8968 }
8969
8970 /* Done */
8971 return Status;
8972}
#define FCB_STATE_TEMPORARY
Definition: fatstruc.h:1198
#define FOBX_FLAG_USER_SET_CREATION
Definition: fcb.h:293
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define VALID_FILE_ATTRIBUTES
#define VALID_DIR_ATTRIBUTES
NTSTATUS RxpSetInfoMiniRdr(PRX_CONTEXT RxContext, FILE_INFORMATION_CLASS Class)
Definition: rdbss.c:7964
LONGLONG CreationTime
Definition: cdstruc.h:1030
LARGE_INTEGER LastWriteTime
Definition: fatstruc.h:922
LARGE_INTEGER LastAccessTime
Definition: fatstruc.h:921
LARGE_INTEGER LastChangeTime
Definition: fcb.h:160
LARGE_INTEGER CreationTime
Definition: nt_native.h:939
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
#define FO_TEMPORARY_FILE
Definition: iotypes.h:1791

Referenced by RxCommonSetInformation().

◆ RxSetDispositionInfo()

NTSTATUS RxSetDispositionInfo ( PRX_CONTEXT  RxContext)

Definition at line 8978 of file rdbss.c.

8980{
8982
8983 PAGED_CODE();
8984
8985 /* First, make the mini-rdr work! */
8987 /* If it succeed, we'll keep track of the change */
8988 if (NT_SUCCESS(Status))
8989 {
8990 PFCB Fcb;
8993
8994 Fcb = (PFCB)RxContext->pFcb;
8995 FileObject = RxContext->CurrentIrpSp->FileObject;
8996 FileDispo = RxContext->CurrentIrp->AssociatedIrp.SystemBuffer;
8997 /* Caller asks for deletion: mark as delete on close */
8998 if (FileDispo->DeleteFile)
8999 {
9001 FileObject->DeletePending = TRUE;
9002 }
9003 /* Otherwise, clear it */
9004 else
9005 {
9007 FileObject->DeletePending = FALSE;
9008 }
9009
9010 /* Sanitize output */
9012 }
9013
9014 return Status;
9015}

Referenced by RxCommonSetInformation().

◆ RxSetEndOfFileInfo()

NTSTATUS RxSetEndOfFileInfo ( PRX_CONTEXT  RxContext)

Definition at line 9018 of file rdbss.c.

9020{
9023}

Referenced by RxCommonSetInformation().

◆ RxSetPipeInfo()

NTSTATUS RxSetPipeInfo ( PRX_CONTEXT  RxContext)

Definition at line 9026 of file rdbss.c.

9028{
9031}

Referenced by RxCommonSetInformation().

◆ RxSetPositionInfo()

NTSTATUS RxSetPositionInfo ( PRX_CONTEXT  RxContext)

Definition at line 9034 of file rdbss.c.

9036{
9039}

Referenced by RxCommonSetInformation().

◆ RxSetRenameInfo()

NTSTATUS RxSetRenameInfo ( PRX_CONTEXT  RxContext)

Definition at line 9045 of file rdbss.c.

9047{
9048 ULONG Length;
9050 PFCB RenameFcb, Fcb;
9052 PFILE_RENAME_INFORMATION RenameInfo, UserInfo;
9053
9054 PAGED_CODE();
9055
9056 DPRINT("RxSetRenameInfo(%p)\n", RxContext);
9057
9058 Stack = RxContext->CurrentIrpSp;
9059 DPRINT("FO: %p, Replace: %d\n", Stack->Parameters.SetFile.FileObject, Stack->Parameters.SetFile.ReplaceIfExists);
9060
9061 /* If there's no FO, we won't do extra operation, so directly pass to mini-rdr and quit */
9062 RxContext->Info.ReplaceIfExists = Stack->Parameters.SetFile.ReplaceIfExists;
9063 if (Stack->Parameters.SetFile.FileObject == NULL)
9064 {
9065 return RxpSetInfoMiniRdr(RxContext, Stack->Parameters.SetFile.FileInformationClass);
9066 }
9067
9068 Fcb = (PFCB)RxContext->pFcb;
9069 RenameFcb = Stack->Parameters.SetFile.FileObject->FsContext;
9070 /* First, validate the received file object */
9072 if (Fcb->pNetRoot != RenameFcb->pNetRoot)
9073 {
9074 DPRINT1("Not the same device: %p:%p (%wZ) - %p:%p (%wZ)\n", Fcb, Fcb->pNetRoot, Fcb->pNetRoot->pNetRootName, RenameFcb, RenameFcb->pNetRoot, RenameFcb->pNetRoot->pNetRootName);
9076 }
9077
9078 /* We'll reallocate a safe buffer */
9079 Length = Fcb->pNetRoot->DiskParameters.RenameInfoOverallocationSize + RenameFcb->FcbTableEntry.Path.Length + FIELD_OFFSET(FILE_RENAME_INFORMATION, FileName);
9080 RenameInfo = RxAllocatePoolWithTag(PagedPool, Length, '??xR');
9081 if (RenameInfo == NULL)
9082 {
9084 }
9085
9086 _SEH2_TRY
9087 {
9088 /* Copy the data */
9089 UserInfo = RxContext->CurrentIrp->AssociatedIrp.SystemBuffer;
9090 RenameInfo->ReplaceIfExists = UserInfo->ReplaceIfExists;
9091 RenameInfo->RootDirectory = UserInfo->RootDirectory;
9092 RenameInfo->FileNameLength = RenameFcb->FcbTableEntry.Path.Length;
9093 RtlMoveMemory(&RenameInfo->FileName[0], RenameFcb->FcbTableEntry.Path.Buffer, RenameFcb->FcbTableEntry.Path.Length);
9094
9095 /* Set them in the RX_CONTEXT */
9096 RxContext->Info.FileInformationClass = Stack->Parameters.SetFile.FileInformationClass;
9097 RxContext->Info.Buffer = RenameInfo;
9098 RxContext->Info.Length = Length;
9099
9100 /* And call the mini-rdr */
9101 MINIRDR_CALL(Status, RxContext, Fcb->MRxDispatch, MRxSetFileInfo, (RxContext));
9102 }
9104 {
9105 /* Free */
9106 RxFreePoolWithTag(RenameInfo, '??xR');
9107 }
9108 _SEH2_END;
9109
9110 /* Done! */
9111 return Status;
9112}
#define STATUS_NOT_SAME_DEVICE
Definition: ntstatus.h:448

Referenced by RxCommonSetInformation().

◆ RxSetSimpleInfo()

NTSTATUS RxSetSimpleInfo ( PRX_CONTEXT  RxContext)

Definition at line 9136 of file rdbss.c.

9138{
9141}

Referenced by RxCommonSetInformation().

◆ RxSetupNetFileObject()

VOID RxSetupNetFileObject ( PRX_CONTEXT  RxContext)

Definition at line 9147 of file rdbss.c.

9149{
9150 PFCB Fcb;
9151 PFOBX Fobx;
9154
9155 PAGED_CODE();
9156
9157 /* Assert FOBX is FOBX or NULL */
9158 Fobx = (PFOBX)RxContext->pFobx;
9159 ASSERT((Fobx == NULL) || (NodeType(Fobx) == RDBSS_NTC_FOBX));
9160
9161 Fcb = (PFCB)RxContext->pFcb;
9162 Stack = RxContext->CurrentIrpSp;
9164 /* If it's temporary mark FO as such */
9165 if (Fcb != NULL && NodeType(Fcb) != RDBSS_NTC_VCB &&
9167 {
9168 if (FileObject == NULL)
9169 {
9170 return;
9171 }
9172
9173 FileObject->Flags |= FO_TEMPORARY_FILE;
9174 }
9175
9176 /* No FO, nothing to setup */
9177 if (FileObject == NULL)
9178 {
9179 return;
9180 }
9181
9182 /* Assign FCB & CCB (FOBX) to FO */
9183 FileObject->FsContext = Fcb;
9184 FileObject->FsContext2 = Fobx;
9185 if (Fobx != NULL)
9186 {
9187 ULONG_PTR StackTop, StackBottom;
9188
9189 /* If FO is allocated on pool, keep track of it */
9190 IoGetStackLimits(&StackTop, &StackBottom);
9191 if ((ULONG_PTR)FileObject <= StackBottom || (ULONG_PTR)FileObject >= StackTop)
9192 {
9193 Fobx->AssociatedFileObject = FileObject;
9194 }
9195 else
9196 {
9197 Fobx->AssociatedFileObject = NULL;
9198 }
9199
9200 /* Make sure to mark FOBX if it's a DFS open */
9201 if (RxContext->Create.NtCreateParameters.DfsContext == UIntToPtr(DFS_OPEN_CONTEXT))
9202 {
9203 SetFlag(Fobx->Flags, FOBX_FLAG_DFS_OPEN);
9204 }
9205 else
9206 {
9207 ClearFlag(Fobx->Flags, FOBX_FLAG_DFS_OPEN);
9208 }
9209 }
9210
9211 /* Set Cc pointers */
9212 FileObject->SectionObjectPointer = &Fcb->NonPaged->SectionObjectPointers;
9213
9214 /* Update access state */
9215 if (Stack->Parameters.Create.SecurityContext != NULL)
9216 {
9218
9219 AccessState = Stack->Parameters.Create.SecurityContext->AccessState;
9220 AccessState->PreviouslyGrantedAccess |= AccessState->RemainingDesiredAccess;
9221 AccessState->RemainingDesiredAccess = 0;
9222 }
9223}
#define RDBSS_NTC_FOBX
Definition: nodetype.h:57
#define RDBSS_NTC_VCB
Definition: nodetype.h:56
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:417

Referenced by RxCreateFromNetRoot().

◆ RxStartMinirdr()

NTSTATUS NTAPI RxStartMinirdr ( IN PRX_CONTEXT  RxContext,
OUT PBOOLEAN  PostToFsp 
)

Definition at line 9230 of file rdbss.c.

9233{
9235 BOOLEAN Wait, AlreadyStarted;
9237
9238 /* If we've not been post, then, do it */
9239 if (!BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP))
9240 {
9242
9244 RxContext->FsdUid = RxGetUid(&SubjectContext);
9246
9247 *PostToFsp = TRUE;
9248 return STATUS_PENDING;
9249 }
9250
9251 /* Acquire all the required locks */
9252 Wait = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
9254 {
9255 *PostToFsp = TRUE;
9256 return STATUS_PENDING;
9257 }
9258
9259 if (!RxAcquirePrefixTableLockExclusive(RxContext->RxDeviceObject->pRxNetNameTable, Wait))
9260 {
9262 *PostToFsp = TRUE;
9263 return STATUS_PENDING;
9264 }
9265
9266 AlreadyStarted = FALSE;
9267 DeviceObject = RxContext->RxDeviceObject;
9268 _SEH2_TRY
9269 {
9270 /* MUP handle set, means already registered */
9271 if (DeviceObject->MupHandle != NULL)
9272 {
9273 AlreadyStarted = TRUE;
9276 }
9277
9278 /* If we're asked to register to MUP, then do it */
9280 if (DeviceObject->RegisterUncProvider)
9281 {
9283 &DeviceObject->DeviceName,
9284 DeviceObject->RegisterMailSlotProvider);
9285 }
9286 if (!NT_SUCCESS(Status))
9287 {
9288 DeviceObject->MupHandle = NULL;
9290 }
9291
9292 /* Register as file system */
9293 IoRegisterFileSystem(&DeviceObject->DeviceObject);
9294 DeviceObject->RegisteredAsFileSystem = TRUE;
9295
9296 /* Inform mini-rdr it has to start */
9297 MINIRDR_CALL(Status, RxContext, DeviceObject->Dispatch, MRxStart, (RxContext, DeviceObject));
9298 if (NT_SUCCESS(Status))
9299 {
9300 ++DeviceObject->StartStopContext.Version;
9303
9305 }
9306 }
9308 {
9310 {
9311 if (!AlreadyStarted)
9312 {
9313 RxUnstart(RxContext, DeviceObject);
9314 }
9315 }
9316
9317 RxReleasePrefixTableLock(RxContext->RxDeviceObject->pRxNetNameTable);
9319 }
9320 _SEH2_END;
9321
9322 return Status;
9323}
_Inout_ PLIST_ENTRY _In_ PVOID _In_ PSTRING _In_ BOOLEAN _In_ BOOLEAN _In_ ULONG _In_ PFLT_CALLBACK_DATA _In_opt_ PCHECK_FOR_TRAVERSE_ACCESS _In_opt_ PSECURITY_SUBJECT_CONTEXT SubjectContext
Definition: fltkernel.h:2246
#define InterlockedExchangeAdd
Definition: interlocked.h:181
VOID NTAPI IoRegisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:987
#define STATUS_REDIRECTOR_STARTED
Definition: ntstatus.h:488
LUID RxGetUid(IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext)
Definition: rdbss.c:6864
VOID RxUnstart(PRX_CONTEXT Context, PRDBSS_DEVICE_OBJECT DeviceObject)
Definition: rdbss.c:9460
@ RDBSS_STARTED
Definition: rxstruc.h:53
#define RxSetRdbssState(RxDeviceObject, NewState)
Definition: rxstruc.h:70
NTSTATUS RxInitializeMRxDispatcher(_Inout_ PRDBSS_DEVICE_OBJECT pMRxDeviceObject)
VOID NTAPI SeReleaseSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Releases both the primary and client tokens of a security subject context.
Definition: subject.c:171
VOID NTAPI SeCaptureSubjectContext(_Out_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Captures the security subject context of the calling thread and calling process.
Definition: subject.c:85
NTSTATUS NTAPI FsRtlRegisterUncProvider(OUT PHANDLE Handle, IN PCUNICODE_STRING RedirectorDeviceName, IN BOOLEAN MailslotsSupported)
Definition: unc.c:280

◆ RxStopMinirdr()

NTSTATUS NTAPI RxStopMinirdr ( IN PRX_CONTEXT  RxContext,
OUT PBOOLEAN  PostToFsp 
)

Definition at line 9327 of file rdbss.c.

9330{
9333}

◆ RxSystemControl()

NTSTATUS RxSystemControl ( IN PRDBSS_DEVICE_OBJECT  RxDeviceObject,
IN PIRP  Irp 
)

Definition at line 9336 of file rdbss.c.

9339{
9342}

Referenced by RxFsdDispatch().

◆ RxTryToBecomeTheTopLevelIrp()

BOOLEAN RxTryToBecomeTheTopLevelIrp ( IN OUT PRX_TOPLEVELIRP_CONTEXT  TopLevelContext,
IN PIRP  Irp,
IN PRDBSS_DEVICE_OBJECT  RxDeviceObject,
IN BOOLEAN  ForceTopLevel 
)

Definition at line 9348 of file rdbss.c.

9354{
9355 BOOLEAN FromPool = FALSE;
9356
9357 PAGED_CODE();
9358
9359 /* If not top level, and not have to be, quit */
9360 if (IoGetTopLevelIrp() && !ForceTopLevel)
9361 {
9362 return FALSE;
9363 }
9364
9365 /* If not TLC provider, allocate one */
9366 if (TopLevelContext == NULL)
9367 {
9368 TopLevelContext = RxAllocatePoolWithTag(NonPagedPool, sizeof(RX_TOPLEVELIRP_CONTEXT), RX_TLC_POOLTAG);
9369 if (TopLevelContext == NULL)
9370 {
9371 return FALSE;
9372 }
9373
9374 FromPool = TRUE;
9375 }
9376
9377 /* Init it */
9378 __RxInitializeTopLevelIrpContext(TopLevelContext, Irp, RxDeviceObject, FromPool);
9379
9380 ASSERT(TopLevelContext->Signature == RX_TOPLEVELIRP_CONTEXT_SIGNATURE);
9381 if (FromPool)
9382 {
9383 ASSERT(BooleanFlagOn(TopLevelContext->Flags, RX_TOPLEVELCTX_FLAG_FROM_POOL));
9384 }
9385
9386 /* Make it top level IRP */
9387 IoSetTopLevelIrp((PIRP)TopLevelContext);
9388 return TRUE;
9389}
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
VOID __RxInitializeTopLevelIrpContext(IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext, IN PIRP Irp, IN PRDBSS_DEVICE_OBJECT RxDeviceObject, IN ULONG Flags)
Definition: rdbss.c:674

Referenced by RxFsdCommonDispatch(), and RxFspDispatch().

◆ RxUninitializeCacheMap()

VOID RxUninitializeCacheMap ( PRX_CONTEXT  RxContext,
PFILE_OBJECT  FileObject,
PLARGE_INTEGER  TruncateSize 
)

Definition at line 9414 of file rdbss.c.

9418{
9419 PFCB Fcb;
9421 CACHE_UNINITIALIZE_EVENT UninitEvent;
9422
9423 PAGED_CODE();
9424
9425 Fcb = FileObject->FsContext;
9428
9430 CcUninitializeCacheMap(FileObject, TruncateSize, &UninitEvent);
9431
9432 /* Always release the FCB before waiting for the uninit event */
9433 RxReleaseFcb(RxContext, Fcb);
9434
9436
9437 /* Re-acquire it afterwards */
9438 Status = RxAcquireExclusiveFcb(RxContext, Fcb);
9440}
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:286
#define KernelMode
Definition: asm.h:34
@ SynchronizationEvent
@ Executive
Definition: ketypes.h:415

Referenced by RxCommonCleanup().

◆ RxUnload()

VOID NTAPI RxUnload ( IN PDRIVER_OBJECT  DriverObject)

Definition at line 9444 of file rdbss.c.

9446{
9448}

◆ RxUnlockOperation()

VOID NTAPI RxUnlockOperation ( IN PVOID  Context,
IN PFILE_LOCK_INFO  LockInfo 
)

Definition at line 9452 of file rdbss.c.

9455{
9457}

◆ RxUnstart()

VOID RxUnstart ( PRX_CONTEXT  Context,
PRDBSS_DEVICE_OBJECT  DeviceObject 
)

Definition at line 9460 of file rdbss.c.

9463{
9465}

Referenced by RxStartMinirdr().

◆ RxUnwindTopLevelIrp()

VOID RxUnwindTopLevelIrp ( IN OUT PRX_TOPLEVELIRP_CONTEXT  TopLevelContext)

Definition at line 9471 of file rdbss.c.

9473{
9474 DPRINT("RxUnwindTopLevelIrp(%p)\n", TopLevelContext);
9475
9476 /* No TLC provided? Ask the system for ours! */
9477 if (TopLevelContext == NULL)
9478 {
9479 TopLevelContext = (PRX_TOPLEVELIRP_CONTEXT)IoGetTopLevelIrp();
9480 if (TopLevelContext == NULL)
9481 {
9482 return;
9483 }
9484
9485 /* In that case, just assert it's really ours */
9486 ASSERT(RxIsThisAnRdbssTopLevelContext(TopLevelContext));
9487 ASSERT(BooleanFlagOn(TopLevelContext->Flags, RX_TOPLEVELCTX_FLAG_FROM_POOL));
9488 }
9489
9490 ASSERT(TopLevelContext->Signature == RX_TOPLEVELIRP_CONTEXT_SIGNATURE);
9491 ASSERT(TopLevelContext->Thread == PsGetCurrentThread());
9492 /* Restore the previous top level IRP */
9493 IoSetTopLevelIrp(TopLevelContext->Previous);
9494 /* If TLC was allocated from pool, remove it from list and release it */
9495 if (BooleanFlagOn(TopLevelContext->Flags, RX_TOPLEVELCTX_FLAG_FROM_POOL))
9496 {
9498 RxFreePoolWithTag(TopLevelContext, RX_TLC_POOLTAG);
9499 }
9500}
VOID RxRemoveFromTopLevelIrpAllocatedContextsList(PRX_TOPLEVELIRP_CONTEXT TopLevelContext)
Definition: rdbss.c:8562

Referenced by RxFsdCommonDispatch(), and RxFspDispatch().

◆ RxUpdateShareAccessPerSrvOpens()

VOID RxUpdateShareAccessPerSrvOpens ( IN PSRV_OPEN  SrvOpen)

Definition at line 9506 of file rdbss.c.

9508{
9512 BOOLEAN DeleteAccess;
9513
9514 PAGED_CODE();
9515
9516 /* If already updated, no need to continue */
9518 {
9519 return;
9520 }
9521
9522 /* Check if any access wanted */
9523 DesiredAccess = SrvOpen->DesiredAccess;
9526 DeleteAccess = (DesiredAccess & DELETE) != 0;
9527
9528 /* In that case, update it */
9529 if ((ReadAccess) || (WriteAccess) || (DeleteAccess))
9530 {
9531 BOOLEAN SharedRead;
9532 BOOLEAN SharedWrite;
9533 BOOLEAN SharedDelete;
9536
9537 ShareAccess = &((PFCB)SrvOpen->pFcb)->ShareAccessPerSrvOpens;
9538 DesiredShareAccess = SrvOpen->ShareAccess;
9539
9540 SharedRead = (DesiredShareAccess & FILE_SHARE_READ) != 0;
9541 SharedWrite = (DesiredShareAccess & FILE_SHARE_WRITE) != 0;
9542 SharedDelete = (DesiredShareAccess & FILE_SHARE_DELETE) != 0;
9543
9544 ShareAccess->OpenCount++;
9545
9546 ShareAccess->Readers += ReadAccess;
9547 ShareAccess->Writers += WriteAccess;
9548 ShareAccess->Deleters += DeleteAccess;
9549 ShareAccess->SharedRead += SharedRead;
9550 ShareAccess->SharedWrite += SharedWrite;
9551 ShareAccess->SharedDelete += SharedDelete;
9552 }
9553
9555}
#define SRVOPEN_FLAG_SHAREACCESS_UPDATED
Definition: fcb.h:258

Referenced by RxCreateFromNetRoot().

◆ RxXXXControlFileCallthru()

NTSTATUS RxXXXControlFileCallthru ( PRX_CONTEXT  Context)

Definition at line 9561 of file rdbss.c.

9563{
9565
9566 PAGED_CODE();
9567
9568 DPRINT("RxXXXControlFileCallthru(%p)\n", Context);
9569
9570 /* No dispatch table? Nothing to dispatch */
9571 if (Context->RxDeviceObject->Dispatch == NULL)
9572 {
9573 Context->pFobx = NULL;
9575 }
9576
9577 /* Init the lowio context */
9579 if (!NT_SUCCESS(Status))
9580 {
9581 return Status;
9582 }
9583
9584 /* Check whether we're consistent: a length means a buffer */
9585 if ((Context->LowIoContext.ParamsFor.FsCtl.InputBufferLength > 0 && Context->LowIoContext.ParamsFor.FsCtl.pInputBuffer == NULL) ||
9586 (Context->LowIoContext.ParamsFor.FsCtl.OutputBufferLength > 0 && Context->LowIoContext.ParamsFor.FsCtl.pOutputBuffer == NULL))
9587 {
9589 }
9590
9591 /* Forward the call to the mini-rdr */
9592 DPRINT("Calling: %p\n", Context->RxDeviceObject->Dispatch->MRxDevFcbXXXControlFile);
9593 Status = Context->RxDeviceObject->Dispatch->MRxDevFcbXXXControlFile(Context);
9594 if (Status != STATUS_PENDING)
9595 {
9596 Context->CurrentIrp->IoStatus.Information = Context->InformationToReturn;
9597 }
9598
9599 DPRINT("RxXXXControlFileCallthru: %x, %ld\n", Context->CurrentIrp->IoStatus.Status, Context->CurrentIrp->IoStatus.Information);
9600 return Status;
9601}
NTSTATUS NTAPI RxLowIoPopulateFsctlInfo(_In_ PRX_CONTEXT RxContext)

Referenced by RxCommonDevFCBIoCtl().

Variable Documentation

◆ DisableByteRangeLockingOnReadOnlyFiles

BOOLEAN DisableByteRangeLockingOnReadOnlyFiles = FALSE

Definition at line 532 of file rdbss.c.

Referenced by RxReadRegistryParameters(), and RxSearchForCollapsibleOpen().

◆ DisableFlushOnCleanup

BOOLEAN DisableFlushOnCleanup = FALSE

Definition at line 533 of file rdbss.c.

Referenced by RxCommonCleanup(), and RxReadRegistryParameters().

◆ ReadAheadGranularity

ULONG ReadAheadGranularity = 1 << PAGE_SHIFT

Definition at line 534 of file rdbss.c.

Referenced by RxCreateNetRoot(), and RxReadRegistryParameters().

◆ Rx8QMdot3QM

WCHAR Rx8QMdot3QM[] = L">>>>>>>>.>>>*"

Definition at line 531 of file rdbss.c.

Referenced by RxQueryDirectory().

◆ RxActiveContexts

◆ RxContextLookasideList

NPAGED_LOOKASIDE_LIST RxContextLookasideList

Definition at line 536 of file rdbss.c.

Referenced by RxCreateRxContext(), RxDereferenceAndDeleteRxContext_Real(), and RxDriverEntry().

◆ RxData

◆ RxDeviceFCB

◆ RxDeviceFCBVector

Definition at line 540 of file rdbss.c.

Referenced by RxFsdCommonDispatch(), and RxInitializeDispatchVectors().

◆ RxExports

RDBSS_EXPORTS RxExports

Definition at line 571 of file rdbss.c.

Referenced by RxDriverEntry(), and RxRegisterMinirdr().

◆ RxFastIoDispatch

FAST_IO_DISPATCH RxFastIoDispatch

Definition at line 572 of file rdbss.c.

Referenced by RxInitializeDispatchVectors().

◆ RxFileSystemDeviceObject

◆ RxForceQFIPassThrough

BOOLEAN RxForceQFIPassThrough = FALSE

Definition at line 613 of file rdbss.c.

Referenced by RxQueryStandardInfo().

◆ RxFsdDispatchVector

Definition at line 574 of file rdbss.c.

Referenced by RxFsdDispatch(), and RxInitializeDispatchVectors().

◆ RxFsdEntryCount

ULONG RxFsdEntryCount

Definition at line 605 of file rdbss.c.

Referenced by RxCreateRxContext().

◆ RxIrpsList

LIST_ENTRY RxIrpsList

Definition at line 606 of file rdbss.c.

Referenced by RxDriverEntry().

◆ RxIrpsListSpinLock

KSPIN_LOCK RxIrpsListSpinLock

Definition at line 607 of file rdbss.c.

Referenced by RxDriverEntry().

◆ RxLoudLowIoOpsEnabled

BOOLEAN RxLoudLowIoOpsEnabled = FALSE

Definition at line 539 of file rdbss.c.

Referenced by CheckForLoudOperations().

◆ RxNoAsync

BOOLEAN RxNoAsync = FALSE

Definition at line 614 of file rdbss.c.

Referenced by RxCommonWrite().

◆ RxScavengerMutex

KMUTEX RxScavengerMutex

Definition at line 608 of file rdbss.c.

Referenced by RxDriverEntry().

◆ RxSerializationMutex

KMUTEX RxSerializationMutex

Definition at line 609 of file rdbss.c.

Referenced by RxDriverEntry().

◆ RxSpaceForTheWrappersDeviceObject

UCHAR RxSpaceForTheWrappersDeviceObject[sizeof(*RxFileSystemDeviceObject)]

Definition at line 610 of file rdbss.c.

Referenced by RxDriverEntry().

◆ RxStarForTemplate

WCHAR RxStarForTemplate = '*'

Definition at line 530 of file rdbss.c.

Referenced by RxQueryDirectory().

◆ TopLevelIrpAllocatedContextsList

◆ TopLevelIrpSpinLock