|
|
/*++ BUILD Version: 0003 // Increment this if a change has global effects
Copyright (c) 1989 Microsoft Corporation
Module Name:
srvblock.h
Abstract:
This module defines the standard header for data blocks maintained by the LAN Manager server.
Author:
Chuck Lenzmeier (chuckl) 1-Dec-1989 David Treadwell (davidtr)
Revision History:
--*/
#ifndef _SRVBLOCK_
#define _SRVBLOCK_
//#include "srvtypes.h"
//
// The following define the various types of data blocks used by the
// server.
//
// *** The pool tag array in heapmgr.c must be maintained in concert
// with these definitions.
//
#define BlockTypeGarbage 0x00
#define BlockTypeBuffer 0x01
#define BlockTypeConnection 0x02
#define BlockTypeEndpoint 0x03
#define BlockTypeLfcb 0x04
#define BlockTypeMfcb 0x05
#define BlockTypeRfcb 0x06
#define BlockTypeSearch 0x07
#define BlockTypeSearchCore 0x08
#define BlockTypeSession 0x0A
#define BlockTypeShare 0x0B
#define BlockTypeTransaction 0x0C
#define BlockTypeTreeConnect 0x0D
#define BlockTypeWaitForOplockBreak 0x0E
#define BlockTypeCommDevice 0x0F
#define BlockTypeWorkContextInitial 0x10
#define BlockTypeWorkContextNormal 0x11
#define BlockTypeWorkContextRaw 0x12
#define BlockTypeWorkContextSpecial 0x13
#define BlockTypeCachedDirectory 0x14
// The following "blocks" do NOT have block headers.
#define BlockTypeDataBuffer 0x15
#define BlockTypeTable 0x16
#define BlockTypeNonpagedHeader 0x17
#define BlockTypePagedConnection 0x18
#define BlockTypePagedRfcb 0x19
#define BlockTypeNonpagedMfcb 0x1A
#define BlockTypeTimer 0x1B
#define BlockTypeAdminCheck 0x1C
#define BlockTypeWorkQueue 0x1D
#define BlockTypeDfs 0x1E
#define BlockTypeLargeReadX 0x1F
#define BlockTypeAdapterStatus 0x20
#define BlockTypeShareRemark 0x21
#define BlockTypeShareSecurityDescriptor 0x22
#define BlockTypeVolumeInformation 0x23
#define BlockTypeFSName 0x24
#define BlockTypeNameInfo 0x25
#define BlockTypeDirectoryInfo 0x26
#define BlockTypeDirCache 0x27
#define BlockTypeMisc 0x28
#define BlockTypeSnapShot 0x29
#define BlockTypeSecurityContext 0x2A
// The following is defined just to know how many types there are.
#define BlockTypeMax 0x2B
//
// The following define the various states that blocks can be in.
// Initializing is used (relatively rarely) to indicate that
// creation/initialization of a block is in progress. Active is the
// state blocks are usually in. Closing is used to indicate that a
// block is being prepared for deletion; when the reference count on the
// block reaches 0, the block will be deleted. Dead is used when
// debugging code is enabled to indicate that the block has been
// deleted.
//
#define BlockStateDead 0x00
#define BlockStateInitializing 0x01
#define BlockStateActive 0x02
#define BlockStateClosing 0x03
// The following is defined just to know how many states there are.
#define BlockStateMax 0x04
//
// ALLOCATE_NONPAGED_POOL is a macro that translates to a call to
// SrvAllocateNonPagedPool if debugging is not enabled or to
// SrvAllocateNonPagedPoolDebug if it is enabled.
// DEALLOCATE_NONPAGED_POOL translates to SrvFreeNonPagedPool or
// SrvFreeNonPagedPoolDebug. The Srv routines are used to track pool
// usage by the server.
//
//
// When POOL_TAGGING is on, we pass the block type through to
// SrvAllocateNonPagedPool so that it can pass a tag to the pool
// allocator.
//
#ifdef POOL_TAGGING
#define ALLOCATE_NONPAGED_POOL(size,type) \
SrvAllocateNonPagedPool( (size), (type) ) #else
#define ALLOCATE_NONPAGED_POOL(size,type) \
SrvAllocateNonPagedPool( (size) ) #endif
#define DEALLOCATE_NONPAGED_POOL(addr) SrvFreeNonPagedPool( (addr) )
//
// Routines that track server nonpaged pool usage in order to support the
// "maxnonpagedmemoryusage" configuration parameter.
//
PVOID SRVFASTCALL SrvAllocateNonPagedPool ( IN CLONG NumberOfBytes #ifdef POOL_TAGGING
,IN CLONG BlockType #endif
);
VOID SRVFASTCALL SrvFreeNonPagedPool ( IN PVOID Address );
VOID SRVFASTCALL SrvClearLookAsideList( PLOOK_ASIDE_LIST l, VOID (SRVFASTCALL *FreeRoutine )( PVOID ) );
//
// The _HEAP macros are like the _NONPAGED_POOL macros, except they
// operate on paged pool. The "HEAP" name is historical, from the
// days when the server used process heap instead of paged pool.
//
// *** When SRVDBG2 is enabled, all server control blocks and all
// reference history blocks must be allocated from nonpaged pool,
// because SrvUpdateReferenceHistory touches these thing while
// holding a spin lock (i.e., at raised IRQL). To make this easy,
// the ALLOCATE_HEAP and FREE_HEAP macros are modified to use
// nonpaged pool. This means that ALL memory allocated by the
// server comes out of nonpaged pool when SRVDBG2 is on.
//
#if SRVDBG2
#define ALLOCATE_HEAP(size,type) ALLOCATE_NONPAGED_POOL( (size), (type) )
#define ALLOCATE_HEAP_COLD(size,type) ALLOCATE_NONPAGED_POOL( (size), (type) )
#define FREE_HEAP(addr) DEALLOCATE_NONPAGED_POOL( (addr) )
#else // SRVDBG2
//
// When POOL_TAGGING is on, we pass the block type through to
// SrvAllocateNonPagedPool so that it can pass a tag to the pool
// allocator.
//
#ifdef POOL_TAGGING
#define ALLOCATE_HEAP(size,type) SrvAllocatePagedPool( PagedPool, (size), (type) )
#define ALLOCATE_HEAP_COLD(size,type) SrvAllocatePagedPool( (PagedPool | POOL_COLD_ALLOCATION), (size), (type) )
#else
#define ALLOCATE_HEAP(size,type) SrvAllocatePagedPool( PagedPool, (size) )
#define ALLOCATE_HEAP_COLD(size,type) SrvAllocatePagedPool( (PagedPool | POOL_COLD_ALLOCATION), (size) )
#endif
#define FREE_HEAP(addr) SrvFreePagedPool( (addr) )
#endif // else SRVDBG2
//
// Routines that track server paged pool usage in order to support the
// "maxpagedmemoryusage" configuration parameter.
//
PVOID SRVFASTCALL SrvAllocatePagedPool ( IN POOL_TYPE PoolType, IN CLONG NumberOfBytes #ifdef POOL_TAGGING
,IN CLONG BlockType #endif
);
VOID SRVFASTCALL SrvFreePagedPool ( IN PVOID Address );
//
// SHARE_TYPE is an enumerated type used to indicate what type of
// resource is being shared. This type corresponds to the server
// table StrShareTypeNames. Keep the two in sync.
//
typedef enum _SHARE_TYPE { ShareTypeDisk, ShareTypePrint, ShareTypePipe, ShareTypeWild // not a real share type, but can be specified in tcon
} SHARE_TYPE, *PSHARE_TYPE;
//
// SHARE_SNAPSHOT represents a snapshot availible for this share.
//
typedef struct _SHARE_SNAPSHOT { LIST_ENTRY SnapShotList; ULONG Flags; HANDLE SnapShotRootDirectoryHandle; LARGE_INTEGER Timestamp; UNICODE_STRING SnapShotName; // "[email protected]"
UNICODE_STRING SnapShotPath; } SHARE_SNAPSHOT, *PSHARE_SNAPSHOT;
#define SNAPSHOT_NAME_LENGTH (strlen("@GMT-YYYY.MM.DD-HH.MM.SS")+1)*sizeof(WCHAR)
#define SNAPSHOT_NAME_FORMAT L"@GMT-%04d.%02d.%02d-%02d.%02d.%02d"
#define SRV_SNAP_SHARE_NOT_FOUND 1
//
// For each resource that the server shares, a Share Block is
// maintained. The global share list is anchored at SrvShareHashTable. A
// list of active tree connections using a resource is anchored in the
// Share Block.
//
typedef struct _SHARE { BLOCK_HEADER BlockHeader; // must be first element
LIST_ENTRY TreeConnectList; LIST_ENTRY GlobalShareList;
HANDLE RootDirectoryHandle;
UNICODE_STRING ShareName; UNICODE_STRING NtPathName; UNICODE_STRING DosPathName; UNICODE_STRING Remark; UNICODE_STRING RelativePath;
ULONG ShareNameHashValue;
union { struct { UNICODE_STRING Name; OEM_STRING OemName; } FileSystem; HANDLE hPrinter; } Type;
ULONG MaxUses; ULONG CurrentUses; ULONG CurrentRootHandleReferences; // used for removable devices
LONG QueryNamePrefixLength;
PSECURITY_DESCRIPTOR SecurityDescriptor; // for tree connects
PSECURITY_DESCRIPTOR FileSecurityDescriptor; // file acls on shares
SHARE_TYPE ShareType; BOOLEAN Removable; // Is the share storage removable?
BOOLEAN SpecialShare; BOOLEAN IsDfs; // Is this share in the Dfs?
BOOLEAN IsDfsRoot; // Is this share the root of a Dfs?
BOOLEAN PotentialSystemFile; // Are files in this share potentially
// system files?
BOOLEAN IsCatchShare; // Should the SRVCATCH code be active
ULONG ShareProperties;
//
// These flags are returned to the client on a tree connect to instruct the client
// how it can cache the files on this share. The server does not interpret these
// flags -- it is the client's responsibility to do the right thing.
//
ULONG CSCState;
PSRV_LOCK SecurityDescriptorLock;
HANDLE ShareVolumeHandle; LIST_ENTRY SnapShots; PSRV_LOCK SnapShotLock; LONG SnapShotEpic;
// WCHAR ShareNameData[ShareName.MaximumLength];
// WCHAR NtPathNameData[PathName.MaximumLength];
// WCHAR DosPathNameData[PathName.MaximumLength];
// SECURITY_DESCRIPTOR SecurityDescriptor;
} SHARE, *PSHARE;
//
// For each network that the server uses, an Endpoint Block is
// maintained. An ENDPOINT contains the network name (for
// administrative purposes), the endpoint name (server address), the
// endpoint (file) handle, a pointer to the endpoint object, a pointer
// to the transport provider's device object, and state information.
// The global endpoint list is anchored at SrvEndpointList. A list of
// active connections created using an endpoint is anchored in the
// Endpoint Block.
//
#if SRVDBG29
#define HISTORY_LENGTH 256
typedef struct { ULONG Operation; PVOID Connection; BLOCK_HEADER ConnectionHeader; } HISTORY, *PHISTORY; #define UpdateConnectionHistory(_op,_endp,_conn) { \
PHISTORY history = &(_endp)->History[(_endp)->NextHistoryLocation++]; \ if ((_endp)->NextHistoryLocation >= HISTORY_LENGTH) { \ (_endp)->NextHistoryLocation = 0; \ } \ history->Operation = *(PULONG)(_op); \ history->Connection = (_conn); \ if (_conn) { \ history->ConnectionHeader = *(PBLOCK_HEADER)(_conn); \ } \ } #endif
struct _CONNECTION;
typedef struct _ENDPOINT { BLOCK_HEADER BlockHeader; // must be first element
//
// List of free connections.
//
LIST_ENTRY FreeConnectionList;
//
// Table of connections. We use a table instead of a list in order
// to speed up lookup of IPX connections based on the SID stored in
// the SMB header.
//
TABLE_HEADER ConnectionTable;
ORDERED_LIST_ENTRY GlobalEndpointListEntry;
//
// Handle and file/device objects for connection-oriented endpoint
// or for connectionless server data socket.
//
HANDLE EndpointHandle; PFILE_OBJECT FileObject; PDEVICE_OBJECT DeviceObject; PULONG IpxMaxPacketSizeArray; ULONG MaxAdapters;
//
// Handle and file/device objects for connectionless NetBIOS name
// socket.
//
HANDLE NameSocketHandle; PFILE_OBJECT NameSocketFileObject; PDEVICE_OBJECT NameSocketDeviceObject;
PDRIVER_DISPATCH FastTdiSend; PDRIVER_DISPATCH FastTdiSendDatagram;
TDI_ADDRESS_IPX LocalAddress;
ULONG FreeConnectionCount; ULONG TotalConnectionCount;
//
// Various flags
//
struct { ULONG IsConnectionless : 1; // connectionless transport?
ULONG NameInConflict : 1; // unable to claim name?
ULONG IsPrimaryName : 1; // set if not an alternate name
ULONG IsNoNetBios : 1; // set if we are direct hosting on a VC
ULONG RemapPipeNames : 1; // set if we are remapping pipe names for clusters
};
WCHAR NetworkAddressData[12 + 1];
UNICODE_STRING NetworkName; // administrative name
UNICODE_STRING TransportName; // e.g., "\Device\Nbf_Elnkii01"
UNICODE_STRING ServerName; // e.g., L"NTSERVER"
ANSI_STRING TransportAddress; // e.g., "NTSERVER "
UNICODE_STRING NetworkAddress; UNICODE_STRING DomainName; // domain being served by this endpoint
OEM_STRING OemDomainName; // oem version of domain name
// WCHAR NetworkNameData[NetworkName.MaximumLength/2];
// WCHAR TransportNameData[TransportName.MaximumLength/2];
// WCHAR ServerName[ ServerName.MaximumLength/2 ];
// CHAR TransportAddressData[TransportAddress.MaximumLength];
// WCHAR DomainNameData[ DNLEN + 1];
// CHAR OemDomainNameData[ DNLEN+1 ]
BOOLEAN AlternateAddressFormat; // should this endpoint be included when
// enumerating?
#if SRVDBG29
ULONG NextHistoryLocation; HISTORY History[HISTORY_LENGTH]; #endif
} ENDPOINT, *PENDPOINT;
//
// Size of search hash table (must be a power of 2)
//
#define SEARCH_HASH_TABLE_SIZE 4
typedef struct _HASH_TABLE_ENTRY {
LIST_ENTRY ListHead; BOOLEAN Dirty;
} HASH_TABLE_ENTRY, *PHASH_TABLE_ENTRY;
//
// When we discover something which is a directory, we place the name
// in this per-connection cache for quick re-use for CheckPath.
//
typedef struct { BLOCK_HEADER; LIST_ENTRY ListEntry; // list is linked through this element
UNICODE_STRING DirectoryName; // canonicalized name of this directory
USHORT Tid; // DirectoryName is relative to this tid
ULONG TimeStamp; // Tick count when this element was cached
} CACHED_DIRECTORY, *PCACHED_DIRECTORY;
//
// For each connection (virtual circuit) that is created, a Connection
// Block is maintained. All connections made over a single endpoint are
// linked through that endpoint. Tables of sessions, tree connects, and
// files created using a connection are anchored in the connection
// block.
//
// The Lock field in the connection protects the data in the connection
// and the data structures associated with the connection, such as
// the tree connects and sessions. However, the list of connections
// linked off the endpoint is protected by the endpoint lock, and
// LFCBs and RFCBs associated with a connection are protected by
// the MFCB's lock.
//
typedef struct _PAGED_CONNECTION {
PAGED_HEADER PagedHeader;
//
// List of active transactions
//
LIST_ENTRY TransactionList;
//
// This list is maintained in order of access, so the entry at the top
// of the list is the oldest, the entry at the bottom is the youngest.
//
LIST_ENTRY CoreSearchList;
//
// This information is used to determine whether oplocks and Raw
// I/O's are allowed. This is determined by information obtained by
// querying the transport provider using TDI_QUERY_CONNECTION_INFO.
//
LARGE_INTEGER LinkInfoValidTime; LARGE_INTEGER Throughput; LARGE_INTEGER Delay;
//
// Table headers for session, tree connect, and search tables.
//
TABLE_HEADER SessionTable; TABLE_HEADER TreeConnectTable; TABLE_HEADER SearchTable;
HANDLE ConnectionHandle;
//
// The number of searches active on the connection.
//
USHORT CurrentNumberOfCoreSearches;
//
// Hash table for picking out duplicate core searches
//
HASH_TABLE_ENTRY SearchHashTable[SEARCH_HASH_TABLE_SIZE];
//
// The encryption key obtained from LsaCallAuthenticationPackage.
// This is a per-VC value--any logon on a given VC uses this
// encryption key.
//
UCHAR EncryptionKey[MSV1_0_CHALLENGE_LENGTH];
//
// If we have an NT5 client, this is its build number (if non-zero)
//
ULONG ClientBuildNumber;
//
// Have we logged an invalid SMB for this client yet? We use this
// flag to keep a single client from flooding the event log
//
BOOLEAN LoggedInvalidSmb;
#if SRVNTVERCHK
//
// Have we determined that the client's NT build number is too old to
// allow it to connect to this server?
//
BOOLEAN ClientTooOld; #endif
} PAGED_CONNECTION, *PPAGED_CONNECTION;
#define MAX_SAVED_RESPONSE_LENGTH 100
#define SRV_CONNECTION_SOCKADDR_SIZE 32
typedef struct _CONNECTION {
QUEUEABLE_BLOCK_HEADER ; // must be first element
/* start of spin lock cache line */
//
// Per-connection spin lock.
//
KSPIN_LOCK SpinLock;
//
// Points to the endpoint spinlock that guards this connection's
// entry in the endpoint connection table.
//
PKSPIN_LOCK EndpointSpinLock;
//
// This is the WORK_QUEUE we are queueing on, which may not be the
// same as PreferredWorkQueue due to load balancing
//
PWORK_QUEUE CurrentWorkQueue;
//
// A countdown for the number of operations we'll do before we try
// to pick a better processor for this connection
//
ULONG BalanceCount;
//
// Cached Rfcb
//
struct _RFCB *CachedRfcb; ULONG CachedFid;
//
// BreakIIToNoneJustSent is set when a oplock break II to none is
// sent, and reset whenever an SMB is received. If a raw read
// arrives while this is set, the raw read is rejected.
//
BOOLEAN BreakIIToNoneJustSent;
//
// Raw io enabled
//
BOOLEAN EnableRawIo;
//
// Sid represents the connection's location in the endpoint's
// connection table.
//
USHORT Sid;
// The SidIndex allows us to use all the 16 bits for the index. For
// regular connections this prevents the aliasing problem that can occur
// in using the IXPSID index since the IPX sequence number takes up 4 bits
USHORT SidIndex;
// additional USHORT to satisfy alignment on dword boundaries
USHORT Pad;
//
// Pointer to the endpoint, fileobject, and deviceobject
//
PENDPOINT Endpoint; PFILE_OBJECT FileObject;
PDEVICE_OBJECT DeviceObject;
//
// The maximum message size we can send over this connection.
//
ULONG MaximumSendSize;
//
// This is the WORK_QUEUE we would prefer to be on, because this
// queue assigns work to the same procesor that is handling the
// adaptor's DPCs
//
PWORK_QUEUE PreferredWorkQueue;
//
// Table header for file table.
//
TABLE_HEADER FileTable;
//
// The SMB dialect chosen for this connection. Used in fsd.
//
SMB_DIALECT SmbDialect;
//
// List of active work items associated with the connection.
//
LIST_ENTRY InProgressWorkItemList;
//
// Stores the time of the last oplock break resp processed. This is
// used to synchronize readraw processing with the oplock break
// processing.
//
ULONG LatestOplockBreakResponse;
//
// The following two fields descibe operations in progress on this
// connection. It is possible that there are multiple oplock breaks
// in progress. Also, there is a brief window when multiple raw
// reads can be active -- after we've sent the response to one raw
// read, but before we've done postprocessing (so it looks like the
// first one is still in progress), we could receive another raw
// read request.
//
// Interaction between the two fields are controlled using
// SrvFsdSpinLock (see the block comment in oplock.c for details).
//
LONG OplockBreaksInProgress; ULONG RawReadsInProgress;
//
// Are oplocks allowed?
//
BOOLEAN OplocksAlwaysDisabled; BOOLEAN EnableOplocks;
//
// Is the client coming in over IPX?
//
BOOLEAN DirectHostIpx;
//
// Are security signatures currently active for this connection?
// Security signatures are not supported for Direct Host IPX connections
// and some W9x clients
//
BOOLEAN SmbSecuritySignatureActive;
union { //
// The following struct of this union holds relevant state
// when the client is connecting over direct host IPX.
// IpxAddress holds the client's IPX address, when the client
// 'connects' over IPX.
//
struct { USHORT SequenceNumber; USHORT LastResponseLength; USHORT LastResponseBufferLength; USHORT LastUid; USHORT LastTid; NTSTATUS LastResponseStatus; ULONG IpxDuplicateCount; ULONG IpxDropDuplicateCount; ULONG StartupTime; TDI_ADDRESS_IPX IpxAddress; PVOID LastResponse; };
//
// This struct holds relevant state when the client is using
// a virtual circuit.
//
struct {
//
// The following fields are used for security signatures.
//
MD5_CTX Md5Context;
ULONG SmbSecuritySignatureIndex;
// If we are unable to allocate a WORK_CONTEXT
// at receive indicate time, the receive is done
// in SrvFsdServiceNeedResourceQueue. Depending
// on the received SMB, we sometimes do not send
// a response SMB. Since the Tdi lookahead data
// is not available when SrvFsdServiceNeedResourceQueue
// is run, we have to remember not to advance the signature
// index for the response.
BOOLEAN NoResponseSignatureIndex;
//
// The following field, if non-zero is the IP address of the client
//
ULONG ClientIPAddress;
USHORT SockAddr[SRV_CONNECTION_SOCKADDR_SIZE/sizeof(USHORT)];
}; };
//
// Pointer to paged part of connection block.
//
PPAGED_CONNECTION PagedConnection;
//
// Per-connection interlock.
//
KSPIN_LOCK Interlock;
//
// Quadword align list entries and large ints
//
LIST_ENTRY EndpointFreeListEntry;
//
// A list of deferred oplock work break items. Oplock breaks are
// deferred if a read raw is in progress, or if the server runs
// out of work context blocks, and cannot send the oplock break
// request.
//
LIST_ENTRY OplockWorkList;
//
// List of RFCBs with batch oplocks that have been cached after
// being closed by the client. Count of such RFCBs.
//
LIST_ENTRY CachedOpenList; ULONG CachedOpenCount;
//
// List of directories which have been recently identified. This is a list of
// CACHED_DIRECTORY entries.
//
LIST_ENTRY CachedDirectoryList; ULONG CachedDirectoryCount;
//
// Security context handle for the extensible security negotiate buffer.
//
CtxtHandle NegotiateHandle;
//
// The following represent consumer capabilities.
//
ULONG ClientCapabilities;
//
// Per-connection resource.
//
SRV_LOCK Lock;
//
// Lock for dealing with the license server
//
SRV_LOCK LicenseLock;
//
// Oem version of the client machine name string.
//
OEM_STRING OemClientMachineNameString;
//
// A string for the client's name. The Buffer field points to the
// leading slashes (below), the MaximumLength is
// (COMPUTER_NAME_LENGTH + 3) * sizeof(WCHAR), and Length is the
// number of characters in the name that are not blanks *
// sizeof(WHCAR).
//
UNICODE_STRING ClientMachineNameString;
//
// The following two fields make up the client's name in the form
// "\\client ", including a trailing NULL.
//
WCHAR LeadingSlashes[2]; WCHAR ClientMachineName[COMPUTER_NAME_LENGTH+1];
//
// Head of singly linked list of cached transactions.
//
SLIST_HEADER CachedTransactionList; LONG CachedTransactionCount;
//
// The time when the last message was received for this connection
//
ULONG LastRequestTime;
//
// If we are on the OnNeedResourceQueue for a pending recieve, this
// is the amount of data that was indicated to us.
//
ULONG BytesAvailable;
//
// OnNeedResource is true if this connection is on the global need
// recource queue. This happens if it is waiting for a work context
// block to complete a pending receive or an oplock break request.
//
BOOLEAN OnNeedResourceQueue;
//
// NotReusable is set when an operation fails in such a way that the
// server's idea of the connection state may be different than the
// transport's. For example, a server-initiated disconnect failed.
// If we tried to reuse the connection (by returning it from a
// connect indication), the transport would get confused. When
// NotReusable is set, SrvDereferenceConnection frees the connection
// instead of putting it on the endpoint's free list.
//
BOOLEAN NotReusable;
//
// DisconnectPending indicates that a disconect indication has been
// received from the transport. ReceivePending indicates that the
// server could not assign a work item to handle a receive indication.
//
BOOLEAN DisconnectPending; BOOLEAN ReceivePending;
//
// Oem version of the client name. We need this because we could
// not do unicode operations in the fsd, where we initially get our
// computer name.
//
CHAR OemClientMachineName[COMPUTER_NAME_LENGTH+1];
//
// Information about the client context.
//
UNICODE_STRING ClientOSType; UNICODE_STRING ClientLanManType;
UCHAR BuiltinSavedResponse[MAX_SAVED_RESPONSE_LENGTH];
//
// The number of sessions active on the connection.
//
USHORT CurrentNumberOfSessions;
// Used to monitor how many work contexts a client is using up
LONG InProgressWorkContextCount; LONG OperationsPendingOnTransport; BOOLEAN IsConnectionSuspect; DISCONNECT_REASON DisconnectReason;
} CONNECTION, *PCONNECTION;
//
// For each session that is created, a Session Block is maintained. All
// sessions created over a single connection are linked through a table
// owned by that connection. A list of files opened using a session can
// be obtained by searching the file table owned by the connection
// block.
//
// This is copied from ntmsv1_0.h
typedef struct _SECURITY_CONTEXT { BLOCK_HEADER BlockHeader; CtxtHandle UserHandle; } SECURITY_CONTEXT, *PSECURITY_CONTEXT;
typedef enum _SRV_SESSION_KEY_STATE { SrvSessionKeyUnavailible = 0, SrvSessionKeyAuthenticating, SrvSessionKeyAvailible } SRV_SESSION_KEY_STATE;
#define MSV1_0_USER_SESSION_KEY_LENGTH 16
typedef struct _SESSION { //
// *** NOTE: The reference count field in the session block
// header is not used! Instead, the reference count is
// in the NonpagedHeader structure.
//
BLOCK_HEADER BlockHeader;
PNONPAGED_HEADER NonpagedHeader;
ULONG CurrentFileOpenCount; // count of files open on the session
ULONG CurrentSearchOpenCount; // count of searches open on the session
ORDERED_LIST_ENTRY GlobalSessionListEntry;
PCONNECTION Connection;
//
// If clients are using the GSS-style authentication, we query the
// UserHandle for the user and domain names. If they are using
// old-style authentication, we store the names here. In any case,
// code that needs access to the user and/or domain names should
// call SrvGetUserAndDomainName() and SrvReleaseUserAndDomainName()
//
UNICODE_STRING NtUserName; UNICODE_STRING NtUserDomain;
LARGE_INTEGER StartTime; LARGE_INTEGER LastUseTime; // for autologoff
LARGE_INTEGER LogOffTime; // for forced logoff
LARGE_INTEGER KickOffTime; // for forced logoff
LARGE_INTEGER LastExpirationMessage; // for forced logoff
LUID LogonId; CHAR NtUserSessionKey[MSV1_0_USER_SESSION_KEY_LENGTH]; CHAR LanManSessionKey[MSV1_0_LANMAN_SESSION_KEY_LENGTH];
PSECURITY_CONTEXT SecurityContext; // Security handle to this user
USHORT MaxBufferSize; // Consumer's maximum buffer size
USHORT MaxMpxCount; // Actual max multiplexed pending requests
USHORT Uid;
SRV_SESSION_KEY_STATE SessionKeyState; // Used to determine if the session key can be given to the user.
BOOLEAN UsingUppercasePaths; // Must paths be uppercased?
BOOLEAN GuestLogon; // Is the client logged on as a guest?
BOOLEAN EncryptedLogon; // Was an encrypted password sent?
BOOLEAN LogoffAlertSent; BOOLEAN TwoMinuteWarningSent; BOOLEAN FiveMinuteWarningSent; BOOLEAN IsNullSession; // Is client using a null session?
BOOLEAN IsAdmin; // Is this an administrative user?
BOOLEAN IsLSNotified; // Does license server know about this user?
BOOLEAN LogonSequenceInProgress; // Are we in the middle of an extended logon sequence?
BOOLEAN IsSessionExpired; // Do we need to reauthenticate?
HANDLE hLicense; // if( IsLSNotified ) this is License handle
#if SRVNTVERCHK
//
// Have we determined that we don't like this client's domain?
//
BOOLEAN ClientBadDomain; #endif
//CHAR UserNameBuffer[UserName.MaximumLength];
} SESSION, *PSESSION;
//
// For each tree connect that is made, a Tree Connect Block is
// maintained. All tree connects made over a single connection are
// linked through a table owned by that connection. All tree connects
// made to a single shared resource are linked through that share block.
// A list of files opened using a tree connect can be obtained by
// searching the file table owned by the connection block.
//
typedef struct _TREE_CONNECT { //
// *** NOTE: The reference count field in the tree connect block
// header is not used! Instead, the reference count is
// in the NonpagedHeader structure.
//
BLOCK_HEADER BlockHeader;
PNONPAGED_HEADER NonpagedHeader;
PCONNECTION Connection; PSESSION Session; PSHARE Share;
ORDERED_LIST_ENTRY GlobalTreeConnectListEntry;
ULONG CurrentFileOpenCount;
LIST_ENTRY ShareListEntry; LIST_ENTRY PrintFileList; // only if print share
LARGE_INTEGER StartTime;
UNICODE_STRING ServerName;
BOOLEAN RemapPipeNames;
USHORT Tid;
} TREE_CONNECT, *PTREE_CONNECT;
//
// Master File Control Block (MFCB) -- one per named file that is open
// at least once. Used to support compatibility mode and oplocks.
//
// Local File Control Block (LFCB) -- one for each local open instance.
// Represents local file object/handle. There may be multiple
// LFCBs linked to a single MFCB.
//
// Remote File Control Block (RFCB) -- one for each remote open instance.
// Represents remote FID. There is usually one RFCB per LFCB, but
// multiple compatibility mode RFCBs may be linked to a single LFCB.
// Multiple remote FCB opens for a single file from a single session
// are folded into one RFCB, because old DOS redirectors only send
// one close.
//
//
// For each disk file that is open, a Master File Control Block (MFCB)
// is maintained. If a given file is open multiple times, there is one
// MFCB for the file and multiple LFCBs, one for each local open
// instance. All MFCBs are linked into the global Master File Table.
// The MFCB has a list of the LFCBs representing open instances for the
// file.
//
typedef struct _NONPAGED_MFCB {
union {
//
// When NONPAGED_MFCB structures are freed, they may be placed
// on the WORK_QUEUE's MfcbFreeList to avoid unnecessary Nonpaged
// pool activity. SingleListEntry is used for the linkage.
//
SLIST_ENTRY SingleListEntry;
struct { ULONG Type; PVOID PagedBlock;
//
// We must serialize opens to the same file, since 2 concurrent opens
// may be compatibility mode opens. This lock also protects all data
// in this MFCB and the LFCBs and RFCBs associated with this MFCB.
//
SRV_LOCK Lock; }; };
LARGE_INTEGER OpenFileSize; ULONG OpenFileAttributes;
} NONPAGED_MFCB, *PNONPAGED_MFCB;
typedef struct _MFCB {
//
// *** NOTE: The reference count field in the mfcb block
// header is not used! Instead, the reference count is
// in the NonpagedHeader structure.
//
BLOCK_HEADER BlockHeader; // must be first element
PNONPAGED_MFCB NonpagedMfcb;
//
// All LFCBs for a given named file are linked to the parent MFCB.
//
LIST_ENTRY LfcbList;
//
// The count of active RFCB for this MFCB. This is used to coordinate
// compatibility opens with non-compatibility mode opens.
//
ULONG ActiveRfcbCount;
//
// The fully qualified name of the file is appended to the MFCB.
// The FileName field is a descriptor for the name.
//
UNICODE_STRING FileName;
//
// Mfcbs are linked into the MfcbHashTable by MfcbHashTableEntry
//
LIST_ENTRY MfcbHashTableEntry;
//
// FileNameHashValue is a hash value derived from the upper case
// version of FileName. It is used to speed up name comparisons, and to
// locate the hash entry
//
ULONG FileNameHashValue;
//
// CompatibilityOpen indicates whether the file is open in
// compatibility mode.
//
BOOLEAN CompatibilityOpen;
//
// Timestamp for SnapShot opens
//
LARGE_INTEGER SnapShotTime;
#if SRVCATCH
CHAR SrvCatch; #endif
// WCHAR FileNameData[FileName.MaximumLength/2];
} MFCB, *PMFCB;
//
// The MFCBs are all linked into the master MFCB hash table.
//
typedef struct { LIST_ENTRY List; // the list of MFCBs in this bucket
PSRV_LOCK Lock; // protects this bucket's list
} MFCBHASH, *PMFCBHASH;
//
// For each instance of a local file open, a Local File Control Block
// (LFCB) is maintained. All LFCBs for a particular named file are
// linked through the MFCB for that file.
//
// LFCBs contain information that is specific to the local open, such
// as the file handle and a pointer to the file object. The LFCB also
// contains other information that is common to all child RFCBs, such
// as pointers to the owning connection and tree connect.
//
//
typedef struct _LFCB {
union { BLOCK_HEADER BlockHeader; // must be first element
SINGLE_LIST_ENTRY SingleListEntry; // used when LFCB is freed
};
//
// Multiple remote opens of a file are folded into a single local
// open by linking the RFCBs to the parent LFCB.
//
LIST_ENTRY RfcbList;
//
// The number of associated active RFCBs.
//
ULONG HandleCount;
//
// LFCBs are linked into their MFCB's open file list.
//
PMFCB Mfcb; LIST_ENTRY MfcbListEntry;
//
// Connection, Session, and TreeConnect are referenced pointers to
// the respective "owning" blocks.
//
PCONNECTION Connection; PSESSION Session; PTREE_CONNECT TreeConnect;
//
// GrantedAccess is the access obtained when the file was opened.
// For a compatibility mode open, this is the maximum access
// available to the client; individual opens may have less access.
//
ACCESS_MASK GrantedAccess;
//
// FileHandle is a handle to the open file. FileObject is a
// referenced pointer. DeviceObject is NOT a referenced pointer;
// the reference to the file object prevents the device object from
// going away.
//
HANDLE FileHandle; PFILE_OBJECT FileObject; PDEVICE_OBJECT DeviceObject;
//
// FileMode tracks whether writethrough is enabled for this file
// object.
ULONG FileMode;
//
// The job ID of a print job corresponding to the opened file.
// This is only used for print file opens.
//
ULONG JobId;
//
// Cache these hot-path entry points.
//
PFAST_IO_READ FastIoRead; PFAST_IO_WRITE FastIoWrite; PFAST_IO_LOCK FastIoLock; PFAST_IO_UNLOCK_SINGLE FastIoUnlockSingle; PFAST_IO_MDL_READ MdlRead; PFAST_IO_MDL_READ_COMPLETE MdlReadComplete; PFAST_IO_PREPARE_MDL_WRITE PrepareMdlWrite; PFAST_IO_MDL_WRITE_COMPLETE MdlWriteComplete;
//
// CompatibilityOpen indicates whether the file is open in
// compatibility mode.
//
BOOLEAN CompatibilityOpen;
} LFCB, *PLFCB;
//
// For each instance of a remote file open, a Remote File Control Block
// (RFCB) is maintained. The RFCB points to the LFCB that contains the
// local file handle. Normally RFCBs and LFCBs exist in one-to-one
// correspondence, but multiple compatibility mode opens are folded into
// a single local open, so that the server can enforce the appropriate
// sharing rules.
//
// RFCBs contain information that is specific to the remote open, such
// as the assigned FID, the PID of the creator, the granted access mask,
// and the current file position.
//
// All RFCBs for a single connection are linked through a table owned by
// that connection; the FID assigned to the RFCB represents an index
// into the file table. Pointers to the owning connection and tree
// connect can be found in the LFCB, which is pointed to by the RFCB. A
// list of files opened through a given tree connect can be obtained by
// searching the owning connection's file table for RFCBs whose parent
// LFCBs point to the tree connect.
//
//
// WRITE_MPX_CONTEXT holds context associated with an active Write Block
// Multiplexed sequence.
//
// !!! This structure is probably big enough to be worth putting
// outside the RFCB.
//
#define MAX_GLOM_RUN_COUNT 8
typedef struct _WRITE_MPX_RUN { USHORT Offset; USHORT Length; } WRITE_MPX_RUN, *PWRITE_MPX_RUN;
typedef struct _WRITE_MPX_CONTEXT {
//
// ReferenceCount counts the number of Write Mpx SMBs that are
// currently being processed. When this count goes to zero, and
// we have received the sequenced command that ends the current
// mux, we send the response. This method is needed to ensure
// that we don't process the mux SMBs out-of-order, which leads
// to performance problems, and even worse, data corruption,
// thanks to the mask-shifting method used by the Snowball redir.
//
ULONG ReferenceCount;
//
// Mask holds the logical OR of the masks received in multiplexed
// write requests. When an IPX client sends the last block of write
// mpx data, we send back MpxMask to indicate whether we lost any
// frames.
//
ULONG Mask;
//
// FileObject is a copy of the file object pointer from the LFCB.
//
PFILE_OBJECT FileObject;
//
// Mid holds the MID of the current multiplexed write. PreviousMid
// hold the MID of the previous one. This needs to be retained in
// order to deal with duplicated write mux SMBs -- if a duplicate
// SMB arrives AFTER the first SMB of the next write mux (with a new
// MID), we need to know to toss it, not kill the new write mux.
//
USHORT Mid; USHORT PreviousMid;
//
// SequenceNumber holds the sequence number given in the last
// request of the mux. This needs to be retained because we
// may be simultaneously processing previous parts of the mux
// when we detect that we've received the sequenced comand.
//
USHORT SequenceNumber;
//
// Glomming is set if the current write mux series is being glommed
// into one large write.
//
// GlomPending is set when the indication for the first packet of
// a new write mux occurs. It is cleared when the FSP is done
// preparing the glomming operation. While GlomPending is set,
// subsequent packets of the write mux are queued to GlomDelayList.
//
BOOLEAN Glomming; BOOLEAN GlomPending; LIST_ENTRY GlomDelayList;
ULONG StartOffset; USHORT Length; BOOLEAN GlomComplete;
//
// MpxGlommingAllowed is set when the underlying file system
// supports MDL write.
//
BOOLEAN MpxGlommingAllowed;
PMDL MdlChain;
ULONG NumberOfRuns; WRITE_MPX_RUN RunList[MAX_GLOM_RUN_COUNT];
} WRITE_MPX_CONTEXT, *PWRITE_MPX_CONTEXT;
#define NO_OPLOCK_BREAK_IN_PROGRESS ((UCHAR)-1)
typedef struct _PAGED_RFCB {
PAGED_HEADER PagedHeader;
//
// RFCBs are linked into their parent LFCB's compatibility open
// list.
//
LIST_ENTRY LfcbListEntry;
//
// Information about the last lock attempt by the client that failed.
//
LARGE_INTEGER LastFailingLockOffset;
//
// Current oplock break timeout.
//
LARGE_INTEGER OplockBreakTimeoutTime;
//
// FcbOpenCount indicates how many remote FCB opens this RFCB
// represents. (Whether an RFCB represents a compatibility mode
// open can be determined by looking at the LFCB.)
//
// *** Note that FCB opens are treated similarly to compatibility
// mode opens. However, soft compatibility maps compatibility
// opens into regular opens, but it does not change an FCB open
// into a non-FCB open. So it is possible to have an FCB open
// that is not a compatibility mode open.
//
CLONG FcbOpenCount;
//
// Per-file context for a direct host IPX smart card, if we have one.
// The smart card is willing to handle the read operations for this file if
// IpxSmartCardContext is not NULL.
//
PVOID IpxSmartCardContext;
//
// The time the RFCB was opened. This combined with the ResumeKey uniquely identify
// an RFCB
//
LARGE_INTEGER OpenTime;
} PAGED_RFCB, *PPAGED_RFCB;
typedef struct _RFCB {
//
// The list entry in the RFCB's block header is used to queue the
// RFCB for oplock processing to the nonblocking worker thread work
// queue, which also contains work context blocks.
//
// *** Note that this is an unnamed field, so that its elements can
// can be referenced directly. The field names defined in
// QUEUEABLE_BLOCK_HEADER cannot be used elsewhere in this
// block.
//
QUEUEABLE_BLOCK_HEADER ; // must be first element
/* start of spin lock cache line */
//
// These booleans indicate whether we've already been granted
// read/write/lock access, thus saving a few instructions on every
// read/write/lock. These are checked during the file open.
//
BOOLEAN ReadAccessGranted; // TRUE, if read access in granted
BOOLEAN WriteAccessGranted; // TRUE, if write access is granted
BOOLEAN LockAccessGranted; // TRUE, if lock access is granted
BOOLEAN UnlockAccessGranted; // TRUE, if unlock access is granted
BOOLEAN AppendAccessGranted; // TRUE, if append access is granted
BOOLEAN ExclusiveLockGranted; // TRUE, if exclusive lock access is granted
//
// CurrentPosition maintains the file position after the last Read,
// Write, or Seek by the client. This field is needed only to
// support relative Seeks. Since clients that use relative seeks only
// need 32-bits of file position, this field is maintained as a ULONG.
//
ULONG CurrentPosition;
//
// Type of this share. Accessed in the fsd.
//
SHARE_TYPE ShareType;
//
// The connection pointer is copied from the LFCB so that we can
// find the connection at DPC level (the LFCB is paged, as is the
// pointer to the LFCB in PagedRfcb).
//
PCONNECTION Connection;
//
// The LFCB is used to find the file handle, file object, etc.
//
PLFCB Lfcb;
//
// MpxGlommingAllowed is set when the underlying file system
// supports MDL write.
//
BOOLEAN MpxGlommingAllowed;
//
// The following two booleans describe the read mode, and blocking
// mode of a named pipe.
//
BOOLEAN BlockingModePipe; // TRUE = Blocking, FALSE = Nonblocking
BOOLEAN ByteModePipe; // TRUE = Byte mode, FALSE = Message mode
//
// Indicates whether this file has been written to.
//
BOOLEAN WrittenTo;
/* end of spin lock cache line */
//
// RawWriteSerializationList holds works items that have been queued
// pending completion of a raw write. When the raw write count is
// decremented to 0, this list is flushed by restarting all queued
// work items.
//
LIST_ENTRY RawWriteSerializationList;
//
// fid << 16. Used for key computations.
//
ULONG ShiftedFid;
//
// RawWriteCount counts the number of active raw writes. This is
// used to prevent the file handle from being closed while raw
// writes are in progress. If Raw writes are in progress when the
// close happens, we defer the cleanup until the rawwritecount goes
// to zero.
//
ULONG RawWriteCount;
//
// SavedError retains the error code when a raw read or a raw write
// in writebehind mode gets an error. The next access to the file
// will receive an error indication.
//
NTSTATUS SavedError;
//
// NumberOfLocks is the count of locks currently on the file.
// It is here to support the File APis and RFCB cacheing -- you can't
// cache an RFCB if it has locks in it.
//
LONG NumberOfLocks;
//
// Fid is the file ID assigned to the file and returned to the
// client. Pid is the process ID given by the client when the file
// was opened. Tid is a copy of the parent tree connect's Tid
// field. Uid is used to ensure that the client using a file handle
// is the same one that opened the file.
//
USHORT Fid; USHORT Pid; USHORT Tid; USHORT Uid;
//
// WriteMpx is a WRITE_MPX_CONTEXT structure. It retains context
// about multiplexed write operations. This structure is not used
// on connectionless sessions.
//
WRITE_MPX_CONTEXT WriteMpx;
//
// FileMode tracks whether writethrough is enabled for this file
// object.
ULONG FileMode;
//
// MFCB points to the Master File Control Block for this file.
//
PMFCB Mfcb;
//
// Oplock information. The oplock IRP currently in progress, etc.
// The list entry for queueing the RFCB for oplock break processing
// is located in the block header.
//
PIRP Irp; BOOLEAN OnOplockBreaksInProgressList;
//
// The oplock level to change to, if there is an oplock break
// in progress. Otherwise it is always NO_OPLOCK_BREAK_IN_PROGRESS.
//
UCHAR NewOplockLevel;
//
// This boolean indicates whether or an oplock granted open response
// need to be sent for this RFCB. If it is FALSE, and an oplock break
// request needs to be sent, the request must be deferred until after
// sending the open response.
//
// Access to these fields is synchronized using the MFCB lock.
//
BOOLEAN OpenResponseSent; BOOLEAN DeferredOplockBreak;
//
// Pointer to the paged portion of the rfcb
//
PPAGED_RFCB PagedRfcb;
//
// CachedOpen is set if the RFCB has been cached after being
// closed by the client.
//
LIST_ENTRY CachedOpenListEntry; BOOLEAN CachedOpen;
//
// See if this rfcb can be cached.
//
BOOLEAN IsCacheable;
//
// See if the file was accessed in the last scavenger update period.
// (This is used to update the session last access time).
//
BOOLEAN IsActive;
//
// Is it ok for us to do MPX writes to this RFCB?
//
BOOLEAN MpxWritesOk;
//
// This event is used when the server needs to request an oplock II
// when the initial oplock request fails.
//
PKEVENT RetryOplockRequest;
//
// All RFCBs in the server are stored in a global list to support
// NetFileEnum. This field contains the LIST_ENTRY for the RFCB in
// the global list and a resume handle to support resuming
// enumerations.
//
ORDERED_LIST_ENTRY GlobalRfcbListEntry;
//
// GrantedAccess is the access allowed through this open. This
// GrantedAccess may allow less access than that given in the parent
// LFCB for compatibility mode opens.
//
ACCESS_MASK GrantedAccess;
//
// ShareAccess is the file sharing access specified when the file
// was opened.
//
ULONG ShareAccess;
//
// Current oplock state.
//
OPLOCK_STATE OplockState;
//
// Is it ok for us to do MPX reads to this RFCB?
//
BOOLEAN MpxReadsOk; #ifdef SRVCATCH
CHAR SrvCatch; #endif
#ifdef SRVDBG_RFCBHIST
UCHAR HistoryIndex; ULONG History[256]; #endif
} RFCB, *PRFCB;
#ifdef SRVDBG_RFCBHIST
VOID UpdateRfcbHistory( PRFCB Rfcb, ULONG Event ); #else
#define UpdateRfcbHistory(_rfcb,_event)
#endif
//
// Each incoming (request) and outgoing (response) buffer is represented
// by a BUFFER structure. This descriptor describes the size of the
// buffer, its address, and a full and partial MDL that may be used
// to describe the buffer.
//
// *** The descriptor contains a pointer to the real buffer, which is
// normally allocated out of nonpaged pool. The descriptor itself
// may be allocated out of the FSP heap, although receive buffer
// descriptors are allocated from nonpaged pool, so the FSD
// read/write code can access them.
//
typedef struct _BUFFER { PVOID Buffer; CLONG BufferLength; // Length allocated to buffer
PMDL Mdl; // MDL describing entire buffer
PMDL PartialMdl; // Partial MDL for read/write/etc.
CLONG DataLength; // Length of data currently in buffer
ULONG Reserved; // Pad to quadword
} BUFFER, *PBUFFER;
#define MIN_SEND_SIZE 512
#define MAX_PARTIAL_BUFFER_SIZE 65535
//
// For each search request that is started (Find First or core Search),
// a search block is allocated. This is used to hold enough information
// that the search may be quickly restarted or rewound.
//
// Ths InUse field is protected by Connection->Lock--this lock must be
// held when accessing this field of the search block.
//
typedef struct _SEARCH { BLOCK_HEADER BlockHeader;
HANDLE DirectoryHandle;
ULONG LastFileIndexReturned; UNICODE_STRING SearchName; UNICODE_STRING LastFileNameReturned;
LARGE_INTEGER LastUseTime; LIST_ENTRY LastUseListEntry; LIST_ENTRY HashTableEntry;
PSESSION Session; PTREE_CONNECT TreeConnect; ULONG SearchStorageType;
struct _DIRECTORY_CACHE *DirectoryCache; USHORT NumberOfCachedFiles;
USHORT SearchAttributes; SHORT CoreSequence; SHORT TableIndex; USHORT HashTableIndex;
USHORT Pid; USHORT Flags2;
BOOLEAN Wildcards; BOOLEAN InUse; BOOLEAN DownlevelTimewarp;
// WCHAR SearchNameData[SearchName.MaximumLength/2];
} SEARCH, *PSEARCH;
//
// Each pending transaction request (Transaction, Transaction2, and
// Ioctl) has a transaction block. It records information that is
// needed to stage input and output data across multiple SMBs.
//
// *******************************************************************
// * *
// * DO NOT CHANGE THIS STRUCTURE WITHOUT CHANGING THE CORRESPONDING *
// * STRUCTURE IN net\inc\xstypes.h! *
// * *
// *******************************************************************
//
typedef struct _TRANSACTION {
//
// *** NOTE: The reference count field in the transaction block
// header is not used! Instead, the reference count is
// in the NonpagedHeader structure.
//
BLOCK_HEADER BlockHeader;
PNONPAGED_HEADER NonpagedHeader;
//
// The connection, session, and tree connect pointers are referenced
// pointers if and only if Inserted is TRUE. Otherwise, they are
// simply copies of the work context block's pointers.
//
PCONNECTION Connection; PSESSION Session; PTREE_CONNECT TreeConnect;
LIST_ENTRY ConnectionListEntry;
UNICODE_STRING TransactionName; // not used if Transaction2
ULONG StartTime; ULONG Timeout; CLONG cMaxBufferSize; // if needed we stash this here
//
// The following pointers point into either the trailing portion
// of the transaction block or the last received SMB.
//
// *** ALL information in buffers pointed to by these parameters
// should ALWAYS be in little-endian format. Always use the
// macros defined in srvmacro.h (SmbGetAlignedUshort, etc.) to
// read from or write into these buffers.
//
PSMB_USHORT InSetup; PSMB_USHORT OutSetup; PCHAR InParameters; PCHAR OutParameters; PCHAR InData; PCHAR OutData;
//
// *** Data in all the remaining fields of the transaction block are
// in native format, so no special macros should be used, except
// when copying data to/from the actual SMB.
//
CLONG SetupCount; // amount received (all in first buffer)
CLONG MaxSetupCount; // max that can be sent back
CLONG ParameterCount; // amount received or sent
CLONG TotalParameterCount; // amount expected
CLONG MaxParameterCount; // max that can be sent back
CLONG DataCount; // amount received or sent
CLONG TotalDataCount; // amount expected
CLONG MaxDataCount; // max that can be sent back
USHORT Category; // Ioctl function category
USHORT Function; // Nt Transaction or ioctl function code
//
// The SMB data and paramters may or may not be copied to the
// transaction buffer. If they are not copied, they are read
// and/or written directly into an SMB buffer.
//
// Setup words are never copied.
//
BOOLEAN InputBufferCopied; // if FALSE input buffer is in SMB
BOOLEAN OutputBufferCopied; // if FALSE output buffer is in SMB
BOOLEAN OutDataAllocated; // if TRUE OutData buffer has been separately allocated
USHORT Flags;
USHORT Tid; USHORT Pid; USHORT Uid; USHORT OtherInfo;
HANDLE FileHandle; // Used only for CallNamedPipe processing
PFILE_OBJECT FileObject; // Used only for CallNamedPipe processing
//
// The following fields are used while the response is being sent.
//
CLONG ParameterDisplacement; CLONG DataDisplacement;
//
// PipeRequest is set for named pipe transactions. RemoteApiRequest
// is set for remote API requests.
//
BOOLEAN PipeRequest; BOOLEAN RemoteApiRequest;
//
// The following boolean is TRUE if the transaction has been inserted
// on the connection's transaction list. It will be FALSE when the
// transaction can be handled using a single SMB exchange.
//
BOOLEAN Inserted;
//
// This boolean is TRUE if the transaction is in the state where
// it is waiting for a transaction secondary request to come in
// to acknowledge the receipt of the previous piece of a multipiece
// transaction response.
//
BOOLEAN MultipieceIpxSend;
//
// This boolean is TRUE if all of the transaction data has been received
// and the transaction has been scheduled for execution.
//
BOOLEAN Executing;
//
// The main part of the transaction block is trailed by transaction
// name data and possibly setup words and parameter and data bytes.
//
} TRANSACTION, *PTRANSACTION;
//
// Each pending blocking open request has a BLOCKING_OPEN block. This
// block contains all the info needed to make the call into the file
// system.
typedef struct _BLOCKING_OPEN { BLOCK_HEADER BlockHeader;
PMFCB Mfcb;
PIO_STATUS_BLOCK IoStatusBlock;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING RelativeName;
PVOID EaBuffer; CLONG EaLength;
LARGE_INTEGER AllocationSize; ULONG DesiredAccess; ULONG FileAttributes; ULONG ShareAccess; ULONG CreateDisposition; ULONG CreateOptions;
BOOLEAN CaseInsensitive;
} BLOCKING_OPEN, *PBLOCKING_OPEN;
//
// SRV_TIMER is used for timed operations. The server maintains a pool
// of these structures.
//
typedef struct _SRV_TIMER { SLIST_ENTRY Next; KEVENT Event; KTIMER Timer; KDPC Dpc; } SRV_TIMER, *PSRV_TIMER;
typedef struct _IPX_CLIENT_ADDRESS { TA_IPX_ADDRESS IpxAddress; TDI_CONNECTION_INFORMATION Descriptor; IPX_DATAGRAM_OPTIONS DatagramOptions; } IPX_CLIENT_ADDRESS, *PIPX_CLIENT_ADDRESS;
//
// The state for an I/O request is maintained in a Work Context Block.
// Various fields in the block are filled in or not depending upon the
// request. When a worker thread removes a work item from the FSP work
// queue, it uses the context block, and items pointed to by the
// context block, to determine what to do.
//
// *** Not all of the back pointers have to be here, because a tree
// connect points to a session, which points to a connection, which
// points to an endpoint, etc. However, depending on the operation
// and the state of the operation, we may have a connection pointer
// but no session pointer, etc. So we maintain all of the
// pointers.
//
// *** Any changes to the first 2 elements of this structure must be
// made in concert with the SPECIAL_WORK_ITEM structure in srvtypes.h
//
typedef struct _WORK_CONTEXT {
//
// The list entry in the block header is used to queue the WC for to
// the nonblocking or blocking worker thread work queue. The
// nonblocking work queue also contains RFCBs.
//
// *** Note that this is an unnamed field, so that its elements can
// can be referenced directly. The field names defined in
// QUEUEABLE_BLOCK_HEADER cannot be used elsewhere in this
// block.
//
// Timestamp (in the block header) is used to calculate the total
// time this work context block was on the work queue.
//
// When the work context block is not in use, Timestamp is used to
// record the time at which the block was inserted on the free list.
// This is used to determine when dynamically-allocated work context
// blocks have been idle long enough justify their deletion.
//
// FspRestartRoutine (in the block header) is the routine that is to
// be called by worker thread when the work item is dequeued from
// the work queue.
//
QUEUEABLE_BLOCK_HEADER ; // must be first element
//
// This is the WORK_QUEUE to queue on if we're doing nonblocking work
// It will always point to a valid WORK_QUEUE, even if we're doing
// blocking work.
//
PWORK_QUEUE CurrentWorkQueue;
//
// The free list this should be returned to when work is done
//
PSLIST_HEADER FreeList;
//
// FsdRestartRoutine is the routine that is to be called by the
// FSD's I/O completion routine. This routine can do more
// processing or queue the work item to the FSP. In this case, when
// a worker thread removes the item from the work queue, it calls
// FspRestartRoutine.
//
PRESTART_ROUTINE FsdRestartRoutine;
//
// Linkage field for the in-progress work item list.
//
LIST_ENTRY InProgressListEntry;
//
// Pointers to various structures that might be used.
// These pointers are all referenced pointers. It is
// the responsibility of the SMB processing routines to
// dereference and clear these pointers when they are no
// longer needed.
//
PRFCB Rfcb; PSHARE Share; PSESSION Session; PTREE_CONNECT TreeConnect; PSECURITY_CONTEXT SecurityContext;
//
// These are gathered in one place to facilitate quick zeroing
// of their values when the work context is finished
//
struct _WorkContextZeroBeforeReuse { //
// unreferenced pointer to the endpoint structure for
// this work context. Filled in by SrvRestartReceive and
// available to all SMB processing routines.
//
// Endpoint must be the first element in this structure. See
// INITIALIZE_WORK_CONTEXT in srvmacro.h if changed.
//
PENDPOINT Endpoint; // not a referenced pointer
//
// referenced pointer to the connection structure for this
// this work context. Filled in by SrvRestartReceive and
// available to all SMB processing routines.
//
PCONNECTION Connection; // a reference pointer
//
// The number of times this SMB has been queued to a worker thread
// for processing.
//
ULONG ProcessingCount;
//
// This is a random collection of flags that are needed to steer
// the WorkItem
//
struct {
//
// Can the processing of the current SMB block?
//
ULONG BlockingOperation : 1;
//
// UsingExtraSmbBuffer is TRUE if this work context uses the an extra SMB
// buffer.
//
ULONG UsingExtraSmbBuffer : 1;
//
// Did this Work Item cause a successful oplock open to occur?
//
ULONG OplockOpen : 1;
//
// If we got an ACCESS_DENIED error when opening a file, was it because
// of share ACL checking?
ULONG ShareAclFailure : 1;
//
// Should the WorkContext be queued to the head of the list?
//
ULONG QueueToHead : 1;
//
// Even if security signatures are enabled, do not generate a signature for
// this response.
//
ULONG NoResponseSmbSecuritySignature : 1;
//
// The indicated message exceeds the SMB buffer size. This is allowed
// only for specific SMB(s)
//
ULONG LargeIndication: 1;
#if DBG_STUCK
//
// Do not include this operation in the StuckOperation catching logic
// which is in the scavenger
//
ULONG IsNotStuck : 1; #endif
};
// For SnapShot usage
LARGE_INTEGER SnapShotTime;
};
//
// Pointers to allocated buffers. RequestBuffer is the buffer into
// which the SMB is read. ResponseBuffer is the buffer into which
// the response is written.
//
// *** Currently, ResponseBuffer is always the same as
// RequestBuffer. We have separate pointers in order to reduce
// dependence on this being the case.
//
PBUFFER RequestBuffer; PBUFFER ResponseBuffer;
//
// SMB processing pointers. These are pointers into the request
// buffer. They are maintained in the work context block in support
// of SMB processors that do asynchronous I/O.
//
// Separate request and response parameter pointers are maintained
// to make AndX processing simpler and more efficient. RequestHeader
// is normally the same as ResponseHeader -- both are normally the
// same as RequestBuffer.Buffer. SMB processing code must not depend
// on this -- it must not assume the the request and response buffers
// are the same, nor can it assume that they are different. Special
// rules around AndX SMBs do allow them to assume that the response
// to one command will not overwrite the next request.
//
PSMB_HEADER RequestHeader; PVOID RequestParameters; PSMB_HEADER ResponseHeader; PVOID ResponseParameters;
//
// Pointer to the IRP associated with this work item.
//
PIRP Irp;
//
// StartTime stores the time at which processing of the current
// request began so that the turnaround time may be calculated.
//
ULONG StartTime;
//
// The PartOfInitialAllocation boolean indicates whether this work
// item is part of the block of work items allocated at server
// startup (see blkwork.c\SrvAllocateInitialWorkItems). Such work
// items cannot be deleted during server operation. A work item
// that is dynamically allocated in response to server load does not
// have this bit set, and is a candidate for deletion when the
// server's load decreases.
//
ULONG PartOfInitialAllocation;
//
// The following field contadins the command code of the next
// command to be processed in an SMB. The SMB processing
// initializer and chained (AndX) SMB command processors load this
// field prior to calling or returning to SrvProcessSmb.
//
UCHAR NextCommand;
//
// ClientAddress is used when receiving or sending over IPX.
//
PIPX_CLIENT_ADDRESS ClientAddress;
//
// Spin lock protecting reference count.
//
KSPIN_LOCK SpinLock;
//
// The security signature index for the request
//
ULONG SmbSecuritySignatureIndex;
//
// The security signature index for the response
//
ULONG ResponseSmbSecuritySignatureIndex;
//
// The following union is used to hold request-specific state while
// a response is being sent or while waiting for more data.
//
union {
//
// RemainingEchoCount is used when processing the Echo SMB.
//
USHORT RemainingEchoCount;
//
// Structure used for lock processing. This structure is
// currently used when processing the Lock, LockingAndX, and the
// LockAndRead SMBs.
//
struct {
//
// LockRange is used when processing the LockingAndX SMB. It is
// really either a PLOCKING_ANDX_RANGE, or a PNTLOCKING_ANDX_RANGE
// not just a PVOID.
//
PVOID LockRange;
//
// Timer is a timer and DPC used to timeout lock requests.
//
PSRV_TIMER Timer;
} Lock;
//
// Transaction is used when processing the Transaction[2] SMBs.
// Or when processing a write and X SMB.
//
PTRANSACTION Transaction;
//
// MdlIo is used when processing the ReadRaw or WriteRaw
// SMBs when "MDL read" or "MDL write" is used. It
// retains the status of the response send while the MDL is
// returned to the file system.
//
struct { IO_STATUS_BLOCK IoStatus; ULONG IrpFlags; } MdlIo;
//
// LastWriteTime is used when processing any Read or Write SMB
// that uses RestartChainedClose as a restart routine. This
// field contains the new last write time to set for the file.
//
ULONG LastWriteTime;
//
// CurrentTableIndex is used when processing the Flush SMB. It
// retains the current index into the connection's file table
// when an asynchronous flush is in progress.
//
LONG CurrentTableIndex;
//
// ReadRaw is used when processing the Read Block Raw SMB.
// Offset is the file offset of the read. SavedResponseBuffer
// points to the original SMB response buffer descriptor, which
// is temporarily replaced by a descriptor for the raw read
// buffer. MdlRead indicates whether an MDL read was used,
// rather than a Copy read.
//
struct {
union {
//
// Used for non named pipe reads
//
LARGE_INTEGER Offset; ULONG Length;
//
// Used only for named pipe reads
//
PFILE_PIPE_PEEK_BUFFER PipePeekBuffer;
} ReadRawOtherInfo;
PBUFFER SavedResponseBuffer;
BOOLEAN MdlRead;
} ReadRaw;
//
// WriteRaw is used when processing the Write Block Raw SMB.
// FinalResponseBuffer points to the buffer allocated to contain
// the final response SMB, if writethrough mode was specified.
// Offset is the file offset of the write. ImmediateLength is
// the amount of write data that was sent with the request SMB.
// Pid is the PID of the writer, used to form the lock key on
// the write. FileObject is a pointer to the file object copied
// from the LFCB. (Pid is not used when MDL write is used;
// FileObject is not used when copy write is used.)
//
struct { struct _WORK_CONTEXT *RawWorkContext; } WriteRawPhase1;
struct { LARGE_INTEGER Offset; ULONG Length; PVOID FinalResponseBuffer; CLONG ImmediateLength; PMDL FirstMdl; //PFILE_OBJECT FileObject;
USHORT Pid; BOOLEAN MdlWrite; BOOLEAN ImmediateWriteDone; } WriteRaw;
//
// ReadAndX is the structure used when handling the ReadAndX
// SMB.
//
struct { LARGE_INTEGER ReadOffset; ULONG ReadLength; PCHAR ReadAddress; union { struct { PFILE_PIPE_PEEK_BUFFER PipePeekBuffer; ULONG LastWriteTimeInSeconds; // used if Close is chained
}; struct { // used for ReadLength > negotiated size
PBYTE Buffer; // allocated paged pool, if copy read
PMDL SavedMdl; PMDL CacheMdl; USHORT PadCount; BOOLEAN MdlRead; }; }; } ReadAndX;
#define READX_BUFFER_OFFSET (sizeof(SMB_HEADER) + FIELD_OFFSET(RESP_READ_ANDX, Buffer) )
//
// WriteAndX is the structure used when handling the flavor of WriteAndX that
// exceeds the negotiated buffer size
//
struct { ULONG CurrentWriteLength; // amount of data that was written this time
LARGE_INTEGER Offset; // file offset for this piece of the write
ULONG RemainingWriteLength; // amount of data remaining to be read from xport
ULONG Key; // lock key for the operation
PCHAR WriteAddress; // address in buffer for the data
ULONG BufferLength; // Maximum buffer length in this WorkContext
NTSTATUS FinalStatus; // Final status of the operation
PMDL MdlAddress; // File MDL if MdlWrite == TRUE
BOOLEAN InitialComplete; // TRUE if we have written first part to the file
} WriteAndX;
//
// ReadMpx is the structure used when handling the ReadMpx SMB, unless
// we have a SmartCard accelerating our reads. In this case,
// SmartCardRead is used.
//
struct { ULONG Offset; USHORT FragmentSize; USHORT RemainingLength; ULONG ReadLength; BOOLEAN MdlRead; UCHAR Unused; USHORT CurrentMdlOffset; // logically part of MDL read struct below
union { struct { PVOID MpxBuffer; PMDL MpxBufferMdl; PCHAR NextFragmentAddress; } ; struct { PMDL FirstMdl; PMDL CurrentMdl; } ; } ; } ReadMpx;
//
// SmartCardRead is used to handle direct host read requests if we have
// a Smart Card accelerating the particular request.
//
struct { PDEVICE_OBJECT DeviceObject; PFAST_IO_MDL_READ_COMPLETE MdlReadComplete; } SmartCardRead;
//
// WriteMpx is the structure used when handling the WriteMpx SMB.
//
struct { ULONG Offset; USHORT WriteLength; USHORT Mid; BOOLEAN FirstPacketOfGlom; PVOID Buffer; ULONG ReceiveDatagramFlags; PVOID TransportContext; PMDL DataMdl; } WriteMpx;
struct { LARGE_INTEGER CacheOffset; ULONG WriteLength; PMDL CacheMdl; } WriteMpxMdlWriteComplete;
//
// FastTransactNamedPipe is used when handling a small named pipe
// transaction.
//
struct { PSMB_USHORT OutSetup; PCHAR OutParam; PCHAR OutData; } FastTransactNamedPipe;
} Parameters;
// !!! check whether the compiler leaves a dword gap here!
//
// The following union holds state information about SMBs in progress
// waiting for an oplock break. It is kept separate from the Parameters
// union, since information from both is needed to process some SMBs.
//
union {
//
// Open is the structure used when handling the Open,
// OpenAndX, Open2, Create, or CreateTemporary SMB.
//
struct { PRFCB Rfcb; PFILE_FULL_EA_INFORMATION NtFullEa; ULONG EaErrorOffset;
//
// The Irp used to open the file is the same Irp used to handle
// the oplock processing. This can cause us to lose the original
// iosb->Information. Save it here.
//
ULONG_PTR IosbInformation;
//
// If TRUE, the file was opened only in order to get a handle
// so that we can wait for an oplock to break. This handle will
// be immediately closed, and the open will be retried with the
// user requested access.
//
BOOLEAN TemporaryOpen; } Open;
//
// FileInformation is the structure used when handling the
// QueryInformation, SetInformation, QueryPathInformation,
// or SetPathInformation SMB.
//
struct { HANDLE FileHandle; } FileInformation;
//
// LockLength is used to contain the length of a byte range
// lock since the IRP stack location has no room to hold it.
LARGE_INTEGER LockLength;
} Parameters2;
//
// This field is used when the current operation is blocked waiting
// for an oplock break to occur.
//
struct _WAIT_FOR_OPLOCK_BREAK *WaitForOplockBreak;
union { //
// where we keep the actual client address data.
//
IPX_CLIENT_ADDRESS ClientAddressData;
//
// For a VC-based client, this is the amount of available data if
// LargeIndication is set (above)
//
ULONG BytesAvailable; };
struct { LARGE_INTEGER G_StartTime; ULONG ElapseKCPU; ULONG ElapseUCPU; ULONG ClientAddr; PFILE_OBJECT FileObject; };
ULONG KCPUStart; ULONG UCPUStart; UCHAR PreviousSMB; UCHAR bAlreadyTrace; USHORT FileNameSize; WCHAR strFileName[1024];
#if DBG_STUCK
//
// Time at which this work context was allocated for this current
// unit of work. This time is examined by debugging code in the
// scavenger to help find operations which are taking too long
// to complete.
//
LARGE_INTEGER OpStartTime; #endif
} WORK_CONTEXT, *PWORK_CONTEXT;
//
// Structure used to maintain information about a thread waiting for
// an oplock break.
//
typedef struct _WAIT_FOR_OPLOCK_BREAK { BLOCK_HEADER BlockHeader; LIST_ENTRY ListEntry; LARGE_INTEGER TimeoutTime; PIRP Irp; WAIT_STATE WaitState; } WAIT_FOR_OPLOCK_BREAK, *PWAIT_FOR_OPLOCK_BREAK;
//
// Block manager routines
//
//
// Buffer routines
//
VOID SrvAllocateBuffer ( OUT PBUFFER *Buffer, IN CLONG BufferLength );
VOID SrvFreeBuffer ( IN PBUFFER Buffer );
//
// Connection routines
//
VOID SrvAllocateConnection ( OUT PCONNECTION *Connection );
VOID SrvCloseConnection ( IN PCONNECTION Connection, IN BOOLEAN RemoteDisconnect );
VOID SrvCloseConnectionsFromClient( IN PCONNECTION Connection, IN BOOLEAN OnlyIfNoSessions );
VOID SrvCloseFreeConnection ( IN PCONNECTION Connection );
VOID SrvDereferenceConnection ( IN PCONNECTION Connection );
VOID SrvFreeConnection ( IN PCONNECTION Connection );
#if DBG
NTSTATUS SrvQueryConnections ( OUT PVOID Buffer, IN ULONG BufferLength, OUT PULONG BytesWritten ); #endif
//
// Endpoint routines
//
VOID SrvAllocateEndpoint ( OUT PENDPOINT *Endpoint, IN PUNICODE_STRING NetworkName, IN PUNICODE_STRING TransportName, IN PANSI_STRING TransportAddress, IN PUNICODE_STRING DomainName );
BOOLEAN SRVFASTCALL SrvCheckAndReferenceEndpoint ( IN PENDPOINT Endpoint );
VOID SrvCloseEndpoint ( IN PENDPOINT Endpoint );
VOID SRVFASTCALL SrvDereferenceEndpoint ( IN PENDPOINT Endpoint );
VOID SrvFreeEndpoint ( IN PENDPOINT Endpoint );
VOID SrvReferenceEndpoint ( IN PENDPOINT Endpoint );
BOOLEAN SrvFindNamedEndpoint ( IN PUNICODE_STRING ServerName, IN PBOOLEAN RemapPipeNames OPTIONAL );
VOID EmptyFreeConnectionList ( IN PENDPOINT Endpoint );
PCONNECTION WalkConnectionTable ( IN PENDPOINT Endpoint, IN PUSHORT Index );
//
// Local File Control Block routines
//
VOID SrvAllocateLfcb ( OUT PLFCB *Lfcb, IN PWORK_CONTEXT WorkContext );
VOID SrvCloseLfcb ( IN PLFCB Lfcb );
VOID SrvDereferenceLfcb ( IN PLFCB Lfcb );
VOID SrvFreeLfcb ( IN PLFCB Lfcb, IN PWORK_QUEUE queue );
VOID SrvReferenceLfcb ( IN PLFCB Lfcb );
//
// Master File Control Block routines
//
PMFCB SrvCreateMfcb( IN PUNICODE_STRING FileName, IN PWORK_CONTEXT WorkContext, IN ULONG HashValue );
PMFCB SrvFindMfcb( IN PUNICODE_STRING FileName, IN BOOLEAN CaseInsensitive, OUT PSRV_LOCK *Lock, OUT PULONG HashValue, IN PWORK_CONTEXT WorkContext );
VOID SrvDereferenceMfcb ( IN PMFCB Mfcb );
VOID SrvFreeMfcb ( IN PMFCB Mfcb );
VOID SrvUnlinkLfcbFromMfcb ( IN PLFCB Lfcb );
//
// Remote File Control Block routines
//
VOID SRVFASTCALL SrvAllocateRfcb ( OUT PRFCB *Rfcb, IN PWORK_CONTEXT WorkContext );
BOOLEAN SRVFASTCALL SrvCheckAndReferenceRfcb ( IN PRFCB Rfcb );
VOID SRVFASTCALL SrvCloseRfcb ( IN PRFCB Rfcb );
VOID SrvCloseRfcbsOnLfcb ( PLFCB Lfcb );
VOID SrvCloseRfcbsOnSessionOrPid ( IN PSESSION Session, IN PUSHORT Pid OPTIONAL );
VOID SrvCloseRfcbsOnTree ( PTREE_CONNECT TreeConnect );
VOID SrvCompleteRfcbClose ( IN PRFCB Rfcb );
VOID SRVFASTCALL SrvDereferenceRfcb ( IN PRFCB Rfcb );
VOID SRVFASTCALL SrvFreeRfcb ( IN PRFCB Rfcb, IN PWORK_QUEUE queue );
VOID SRVFASTCALL SrvReferenceRfcb ( IN PRFCB Rfcb );
BOOLEAN SrvFindCachedRfcb ( IN PWORK_CONTEXT WorkContext, IN PMFCB Mfcb, IN ACCESS_MASK DesiredAccess, IN ULONG ShareAccess, IN ULONG CreateDisposition, IN ULONG CreateOptions, IN OPLOCK_TYPE RequestedOplockType, OUT PNTSTATUS Status );
VOID SrvCloseCachedRfcb ( IN PRFCB Rfcb, IN KIRQL OldIrql );
VOID SrvCloseCachedRfcbsOnConnection ( IN PCONNECTION Connection );
VOID SrvCloseCachedRfcbsOnLfcb ( IN PLFCB Lfcb );
ULONG SrvCountCachedRfcbsForTid( PCONNECTION connection, USHORT Tid );
ULONG SrvCountCachedRfcbsForUid( PCONNECTION connection, USHORT Uid );
//
// Search Block routines
//
typedef BOOLEAN (*PSEARCH_FILTER_ROUTINE) ( IN PSEARCH Search, IN PVOID FunctionParameter1, IN PVOID FunctionParameter2 );
VOID SrvAllocateSearch ( OUT PSEARCH *Search, IN PUNICODE_STRING SearchName, IN BOOLEAN IsCoreSearch );
VOID SrvCloseSearch ( IN PSEARCH Search );
VOID SrvCloseSearches ( IN PCONNECTION Connection, IN PSEARCH_FILTER_ROUTINE SearchFilterRoutine, IN PVOID FunctionParameter1, IN PVOID FunctionParameter2 );
VOID SrvDereferenceSearch ( IN PSEARCH Search );
VOID SrvFreeSearch ( IN PSEARCH Search );
VOID SrvReferenceSearch ( IN PSEARCH Search );
BOOLEAN SrvSearchOnDelete( IN PSEARCH Search, IN PUNICODE_STRING DirectoryName, IN PTREE_CONNECT TreeConnect );
BOOLEAN SrvSearchOnPid( IN PSEARCH Search, IN USHORT Pid, IN PVOID Dummy );
BOOLEAN SrvSearchOnSession( IN PSEARCH Search, IN PSESSION Session, IN PVOID Dummy );
BOOLEAN SrvSearchOnTreeConnect( IN PSEARCH Search, IN PTREE_CONNECT TreeConnect, IN PVOID Dummy );
VOID SrvForceTimeoutSearches( IN PCONNECTION Connection );
ULONG SrvTimeoutSearches( IN PLARGE_INTEGER SearchCutoffTime OPTIONAL, IN PCONNECTION Connection, IN BOOLEAN OnlyTimeoutOneBlock );
VOID RemoveDuplicateCoreSearches( IN PPAGED_CONNECTION PagedConnection );
VOID SrvAddToSearchHashTable( IN PPAGED_CONNECTION PagedConnection, IN PSEARCH Search );
//
// Cached directory routines
//
BOOLEAN SrvIsDirectoryCached ( IN PWORK_CONTEXT WorkContext, IN PUNICODE_STRING DirectoryName );
VOID SrvCacheDirectoryName ( IN PWORK_CONTEXT WorkContext, IN PUNICODE_STRING DirectoryName );
VOID SrvRemoveCachedDirectoryName ( IN PWORK_CONTEXT WorkContext, IN PUNICODE_STRING DirectoryName );
VOID SrvCloseCachedDirectoryEntries ( IN PCONNECTION Connection );
//
// Security Context routines
//
PSECURITY_CONTEXT SrvAllocateSecurityContext();
VOID SrvSetSecurityContext( PSECURITY_CONTEXT Context, PCtxtHandle handle );
VOID SrvReferenceSecurityContext( PSECURITY_CONTEXT Context );
VOID SrvDereferenceSecurityContext( PSECURITY_CONTEXT Context );
VOID SrvReplaceSessionSecurityContext( PSESSION Session, PSECURITY_CONTEXT Context, PWORK_CONTEXT WorkContext );
//
// Session routines
//
VOID SrvAllocateSession ( OUT PSESSION *Session, IN PUNICODE_STRING UserName, IN PUNICODE_STRING Domain );
BOOLEAN SRVFASTCALL SrvCheckAndReferenceSession ( IN PSESSION Session );
VOID SrvCloseSession ( IN PSESSION Session );
VOID SrvCloseSessionsOnConnection ( IN PCONNECTION Connection, IN PUNICODE_STRING UserName OPTIONAL );
VOID SRVFASTCALL SrvDereferenceSession ( IN PSESSION Session );
VOID SrvFreeSession ( IN PSESSION Session );
//
// Smb Security Signature Routines
//
BOOLEAN SRVFASTCALL SrvCheckSmbSecuritySignature( IN PWORK_CONTEXT WorkContext );
VOID SRVFASTCALL SrvAddSmbSecuritySignature( IN OUT PWORK_CONTEXT WorkContext, IN PMDL Mdl, IN ULONG SendLength );
VOID SRVFASTCALL SrvInitializeSmbSecuritySignature( IN OUT PCONNECTION Connection, IN PUCHAR SessionKey, IN PUCHAR ChallengeResponse, IN ULONG ChallengeResponseLength );
VOID SrvHashUserSessionKey( PCHAR SessionKey );
//
// Share routines
//
VOID SrvAllocateShare ( OUT PSHARE *Share, IN PUNICODE_STRING ShareName, IN PUNICODE_STRING NtPathName, IN PUNICODE_STRING DosPathName, IN PUNICODE_STRING Remark, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSECURITY_DESCRIPTOR FileSecurityDescriptor OPTIONAL, IN SHARE_TYPE ShareType );
VOID SrvCloseShare ( IN PSHARE Share );
VOID SrvDereferenceShare ( IN PSHARE Share );
VOID SrvDereferenceShareForTreeConnect ( PSHARE Share );
VOID SrvFreeShare ( IN PSHARE Share );
VOID SrvReferenceShare ( IN PSHARE Share );
NTSTATUS SrvReferenceShareForTreeConnect ( PSHARE Share );
//
// Table routines
//
VOID SrvAllocateTable ( IN PTABLE_HEADER TableHeader, IN ULONG NumberOfEntries, IN BOOLEAN Nonpaged );
#define SrvFreeTable( _table ) { \
if ( (_table)->Nonpaged ) { \ DEALLOCATE_NONPAGED_POOL( (_table)->Table ); \ } else { \ FREE_HEAP( (_table)->Table ); \ } \ DEBUG (_table)->Table = NULL; \ DEBUG (_table)->TableSize = -1; \ DEBUG (_table)->FirstFreeEntry = -1; \ DEBUG (_table)->LastFreeEntry = -1; \ }
BOOLEAN SrvGrowTable ( IN PTABLE_HEADER TableHeader, IN ULONG NumberOfNewEntries, IN ULONG MaxNumberOfEntries, OUT NTSTATUS* pStatus );
VOID SrvRemoveEntryTable ( IN PTABLE_HEADER TableHeader, IN USHORT Index );
//
// Transaction routines
//
VOID SrvAllocateTransaction ( OUT PTRANSACTION *Transaction, OUT PVOID *TrailingBytes, IN PCONNECTION Connection, IN CLONG TrailingByteCount, IN PVOID TransactionName, IN PVOID EndOfSourceBuffer OPTIONAL, IN BOOLEAN SourceIsUnicode, IN BOOLEAN RemoteApiRequest );
VOID SrvCloseTransaction ( IN PTRANSACTION Transaction );
VOID SrvCloseTransactionsOnSession ( PSESSION Session );
VOID SrvCloseTransactionsOnTree ( PTREE_CONNECT TreeConnect );
VOID SrvDereferenceTransaction ( IN PTRANSACTION Transaction );
VOID SrvFreeTransaction ( IN PTRANSACTION Transaction );
PTRANSACTION SrvFindTransaction ( IN PCONNECTION Connection, IN PSMB_HEADER Header, IN USHORT Fid OPTIONAL );
BOOLEAN SrvInsertTransaction ( IN PTRANSACTION Transaction );
//
// Tree connect routines
//
VOID SrvAllocateTreeConnect ( OUT PTREE_CONNECT *TreeConnect, IN PUNICODE_STRING ServerName OPTIONAL );
BOOLEAN SRVFASTCALL SrvCheckAndReferenceTreeConnect ( IN PTREE_CONNECT TreeConnect );
VOID SrvCloseTreeConnect ( IN PTREE_CONNECT TreeConnect );
VOID SRVFASTCALL SrvDereferenceTreeConnect ( IN PTREE_CONNECT TreeConnect );
VOID SrvFreeTreeConnect ( IN PTREE_CONNECT TreeConnect );
VOID SrvDisconnectTreeConnectsFromSession ( PCONNECTION connection, PSESSION Session );
VOID SrvCloseTreeConnectsOnShare ( IN PSHARE Share );
//
// Work item routines (includes work contexts, buffers, MDLs, IRPs, etc)
//
NTSTATUS SrvAllocateInitialWorkItems ( VOID );
NTSTATUS SrvAllocateNormalWorkItem ( OUT PWORK_CONTEXT *WorkContext, IN PWORK_QUEUE queue );
VOID SrvAllocateRawModeWorkItem ( OUT PWORK_CONTEXT *WorkContext, IN PWORK_QUEUE queue );
PWORK_CONTEXT SrvGetRawModeWorkItem ( VOID );
VOID SrvRequeueRawModeWorkItem ( IN PWORK_CONTEXT WorkContext );
VOID SRVFASTCALL SrvDereferenceWorkItem ( IN PWORK_CONTEXT WorkContext );
VOID SrvFsdDereferenceWorkItem ( IN PWORK_CONTEXT WorkContext );
NTSTATUS SrvAllocateExtraSmbBuffer ( IN OUT PWORK_CONTEXT WorkContext );
VOID SrvAllocateWaitForOplockBreak ( OUT PWAIT_FOR_OPLOCK_BREAK *WaitForOplockBreak );
VOID SrvDereferenceWaitForOplockBreak ( IN PWAIT_FOR_OPLOCK_BREAK WaitForOplockBreak );
VOID SrvFreeWaitForOplockBreak ( IN PWAIT_FOR_OPLOCK_BREAK WaitForOplockBreak );
VOID SrvOplockWaitTimeout( IN PWAIT_FOR_OPLOCK_BREAK WaitForOplockBreak );
NTSTATUS SrvCheckOplockWaitState( IN PWAIT_FOR_OPLOCK_BREAK WaitForOplockBreak );
NTSTATUS SrvWaitForOplockBreak ( IN PWORK_CONTEXT WorkContext, IN HANDLE FileHandle );
NTSTATUS SrvStartWaitForOplockBreak ( IN PWORK_CONTEXT WorkContext, IN PRESTART_ROUTINE RestartRoutine, IN HANDLE Handle OPTIONAL, IN PFILE_OBJECT FileObject OPTIONAL );
VOID SrvSendDelayedOplockBreak ( IN PCONNECTION Connection );
VOID SrvFreeInitialWorkItems ( VOID );
VOID SrvFreeNormalWorkItem ( IN PWORK_CONTEXT WorkContext );
VOID SrvFreeRawModeWorkItem ( IN PWORK_CONTEXT WorkContext );
//
// Timer routines
//
PSRV_TIMER SrvAllocateTimer ( VOID );
VOID SrvCancelTimer ( IN PSRV_TIMER Timer );
#define SrvDeleteTimer(_timer) DEALLOCATE_NONPAGED_POOL(_timer)
#define SrvFreeTimer(_timer) \
ExInterlockedPushEntrySList(&SrvTimerList, &(_timer)->Next, &GLOBAL_SPIN_LOCK(Timer))
VOID SrvSetTimer ( IN PSRV_TIMER Timer, IN PLARGE_INTEGER Timeout, IN PKDEFERRED_ROUTINE TimeoutHandler, IN PVOID Context );
#if SRVDBG2
VOID SrvInitializeReferenceHistory ( IN PBLOCK_HEADER Block, IN LONG InitialReferenceCount );
VOID SrvUpdateReferenceHistory ( IN PBLOCK_HEADER Block, IN PVOID Caller, IN PVOID CallersCaller, IN BOOLEAN IsDereference );
VOID SrvTerminateReferenceHistory ( IN PBLOCK_HEADER Block );
#define INITIALIZE_REFERENCE_HISTORY(block) \
SrvInitializeReferenceHistory( \ &(block)->BlockHeader, \ ((PBLOCK_HEADER)(block))->ReferenceCount \ )
#define UPDATE_REFERENCE_HISTORY(block,isdereference) \
{ \ PVOID caller, callerscaller; \ RtlGetCallersAddress( &caller, &callerscaller ); \ SrvUpdateReferenceHistory( \ &(block)->BlockHeader, \ caller, \ callerscaller, \ isdereference \ ); \ }
#define TERMINATE_REFERENCE_HISTORY(block) \
SrvTerminateReferenceHistory( &(block)->BlockHeader )
#else
#define INITIALIZE_REFERENCE_HISTORY(block)
#define UPDATE_REFERENCE_HISTORY(block,isdereference)
#define TERMINATE_REFERENCE_HISTORY(block)
#endif // if SRVDBG2
#endif // ndef _SRVBLOCK
|