Given an instance of an RxContext structure passed between rdbss.sys
and mrxsmb.sys, is it possible to figure out the endpoints of a TCP
connection that carries the corresponding SMB traffic?
Thanks,
Alex
typedef struct _RX_CONTEXT {
//
// the node type, size and reference count, aka standard header
//
NODE_TYPE_CODE NodeTypeCode;
NODE_BYTE_SIZE NodeByteSize;
ULONG ReferenceCount;
//
// the list entry to wire the context to the list of active contexts
//
LIST_ENTRY ContextListEntry;
//
// Major and minor function of the IRP associated with the context
//
UCHAR MajorFunction;
UCHAR MinorFunction;
//
// this is similar to the same field in Irps; it
// allows callback routines for async operations
// to know whether to do asynchronous work or not
//
BOOLEAN PendingReturned;
//
// indicates if the associated request is to be posted to a RDBSS
worker thread.
//
BOOLEAN PostRequest;
//
// Originating Device (required for workque algorithms)
// not currently used but could be used for local minis
//
PDEVICE_OBJECT RealDevice;
//
// ptr to the originating Irp
//
PIRP CurrentIrp;
//
// ptr to the IRP stack location
//
PIO_STACK_LOCATION CurrentIrpSp;
//
// ptr to the FCB and FOBX, derived from the context pointers in the
// file object associated with the IRP
//
PMRX_FCB pFcb;
PMRX_FOBX pFobx;
PMRX_SRV_OPEN pRelevantSrvOpen;
PNON_PAGED_FCB NonPagedFcb;
//
// device object calldown (not irpsp…)
//
PRDBSS_DEVICE_OBJECT RxDeviceObject;
//
// The original thread in which the request was initiated and the last
// thread in which some processing associated with the context was done
//
PETHREAD OriginalThread;
PETHREAD LastExecutionThread;
PVOID LockManagerContext;
//
// One word of the context is given to rdbss for dbg information
//
PVOID RdbssDbgExtension;
RX_SCAVENGER_ENTRY ScavengerEntry;
//
// global serial number for this operation
//
ULONG SerialNumber;
//
// used by minirdrs to see if multiple calls are part
// of the same larger operation and (therefore) more cacheable
//
ULONG FobxSerialNumber;
ULONG Flags;
BOOLEAN FcbResourceAcquired;
BOOLEAN FcbPagingIoResourceAcquired;
UCHAR MustSucceedDescriptorNumber;
//
// mostly you want the individual components…sometimes it’s
nice as a pair
// used to record the status when you can’t just return it; e.g., when
// RXSTATUS is not an appropriate return type or if the consumer of the
// status didn’t call directly (lowiocompletions). minirdrs will not need
// to set the information directly
//
union {
struct {
union {
NTSTATUS StoredStatus;
PVOID StoredStatusAlignment;
};
ULONG_PTR InformationToReturn;
};
IO_STATUS_BLOCK IoStatusBlock;
};
//
// the context fields provided for use by the mini redirectors
// this is defined as a union to force longlong alignment
//
union {
ULONGLONG ForceLonglongAligmentDummyField;
PVOID MRxContext[MRX_CONTEXT_FIELD_COUNT];
};
//
// The following field is included to fix the problem related to write only
// opens. This introduces a new field for the mini redirector to squirrel
// some state. This is redundant and should be removed after Windows 2000.
// Having a unique field reduces the impact of the change that we
are making
// to the specific code path. It will be ideal to use one of the MRXContext
// fields defined above
//
PVOID WriteOnlyOpenRetryContext;
//
// the cancellation routine to be invoked, set by the mini redirector
//
PMRX_CALLDOWN MRxCancelRoutine;
//
// private dispatch, if any. used in fspdisp
//
PRX_DISPATCH ResumeRoutine;
//
// for posting to worker threads
// the minirdr can use this for posting within the minirdr
// a potential problem can arise if the minirdr relies on this both
// for queueing async stuff and for queueing cancel stuff
//
//
// The OverflowListEntry is used for queueing items to the overflow queue.
// This is seperate now to allow us to distinguish between an
item in the overflow
// queue and one in the active work queue (for cancellation logic)
//
RX_WORK_QUEUE_ITEM WorkQueueItem;
LIST_ENTRY OverflowListEntry;
//
// this event is used for synchronous operations
// that have to i/f with an underlying async service. it can be used
// by the minirdr with the following provisions:
// 1) on entering the minirdr through lowio, it is set to the
// nonsignaled state (but a wise user will reset it before using
// it…particularly if it’s used multiple times.
// 2) if you are returning STATUS_PENDING on a sync operation, you must
// return with it set to the nonsignaled state; that is, either
// you don’t use it or you reset it in this case
//
KEVENT SyncEvent;
//
// this is a list head of operations that are to be released on completion
//
LIST_ENTRY BlockedOperations;
//
// this is the mutex that controls serialization of the blocked operations
//
PFAST_MUTEX BlockedOpsMutex;
//
// these links are used to serialize pipe operations on a
// per-file-object basis AND FOR LOTS OF OTHER STUFF
//
LIST_ENTRY RxContextSerializationQLinks;
union {
struct {
union {
FS_INFORMATION_CLASS FsInformationClass;
FILE_INFORMATION_CLASS FileInformationClass;
};
PVOID Buffer;
union {
LONG Length;
LONG LengthRemaining;
};
BOOLEAN ReplaceIfExists;
BOOLEAN AdvanceOnly;
} Info;
struct {
UNICODE_STRING SuppliedPathName;
NET_ROOT_TYPE NetRootType;
PIO_SECURITY_CONTEXT pSecurityContext;
} PrefixClaim;
};
//
// THIS UNION MUST BE LAST…AT SOME POINT, WE MAY START ALLOCATING
// SMALLER PER OPERATION!
//
union{
struct {
NT_CREATE_PARAMETERS NtCreateParameters; // a copy of the
createparameters
ULONG ReturnedCreateInformation;
PWCH CanonicalNameBuffer; // if the canonical name is
larger than available buffer
PRX_PREFIX_ENTRY NetNamePrefixEntry; // the entry
returned by the lookup…for dereferencing
PMRX_SRV_CALL pSrvCall; // Server Call being used
PMRX_NET_ROOT pNetRoot; // Net Root being used
PMRX_V_NET_ROOT pVNetRoot; // Virtual Net Root
//PMRX_SRV_OPEN pSrvOpen; // Server Open
PVOID EaBuffer;
ULONG EaLength;
ULONG SdLength;
ULONG PipeType;
ULONG PipeReadMode;
ULONG PipeCompletionMode;
USHORT Flags;
NET_ROOT_TYPE Type; // Type of Net
Root(Pipe/File/Mailslot…)
BOOLEAN FcbAcquired;
BOOLEAN TryForScavengingOnSharingViolation;
BOOLEAN ScavengingAlreadyTried;
BOOLEAN ThisIsATreeConnectOpen;
BOOLEAN TreeConnectOpenDeferred;
UNICODE_STRING TransportName;
UNICODE_STRING UserName;
UNICODE_STRING Password;
UNICODE_STRING UserDomainName;
} Create;
struct {
ULONG FileIndex;
BOOLEAN RestartScan;
BOOLEAN ReturnSingleEntry;
BOOLEAN IndexSpecified;
BOOLEAN InitialQuery;
} QueryDirectory;
struct {
PMRX_V_NET_ROOT pVNetRoot;
} NotifyChangeDirectory;
struct {
PUCHAR UserEaList;
ULONG UserEaListLength;
ULONG UserEaIndex;
BOOLEAN RestartScan;
BOOLEAN ReturnSingleEntry;
BOOLEAN IndexSpecified;
} QueryEa;
struct {
SECURITY_INFORMATION SecurityInformation;
ULONG Length;
} QuerySecurity;
struct {
SECURITY_INFORMATION SecurityInformation;
PSECURITY_DESCRIPTOR SecurityDescriptor;
} SetSecurity;
struct {
ULONG Length;
PSID StartSid;
PFILE_GET_QUOTA_INFORMATION SidList;
ULONG SidListLength;
BOOLEAN RestartScan;
BOOLEAN ReturnSingleEntry;
BOOLEAN IndexSpecified;
} QueryQuota;
struct {
ULONG Length;
} SetQuota;
struct {
PV_NET_ROOT VNetRoot;
PSRV_CALL SrvCall;
PNET_ROOT NetRoot;
} DosVolumeFunction;
struct {
ULONG FlagsForLowIo;
LOWIO_CONTEXT LowIoContext; // the LOWIO parameters
}; // no name here…
LUID FsdUid;
} ;
//
// CODE.IMPROVEMENT remove this to wrapperdbgprivates
//
PWCH AlsoCanonicalNameBuffer; // if the canonical name is larger
than available buffer
PUNICODE_STRING LoudCompletionString;
#ifdef RDBSS_TRACKER
LONG AcquireReleaseFcbTrackerX;
ULONG TrackerHistoryPointer;
RX_FCBTRACKER_CALLINFO TrackerHistory[RDBSS_TRACKER_HISTORY_SIZE];
#endif
#if DBG
ULONG ShadowCritOwner;
#endif
} RX_CONTEXT, *PRX_CONTEXT;