You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
480 lines
16 KiB
480 lines
16 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
smbcedb.h
|
|
|
|
Abstract:
|
|
|
|
This module defines all functions, along with implementations for inline functions
|
|
related to accessing the SMB connection engine
|
|
|
|
Revision History:
|
|
|
|
Balan Sethu Raman [SethuR] 6-March-1995
|
|
|
|
Notes:
|
|
|
|
The various data structures created by the mini rdr (Server Entries, Session Entries
|
|
and Net Root Entries) are used in asynchronous operations. Hence a reference count
|
|
mechanism is used to keep track of the creation/use/destruction of these data structures.
|
|
|
|
The usage patterns for these data structures falls into one of two cases
|
|
|
|
1) A prior reference exists and access is required
|
|
|
|
2) A new reference need be created.
|
|
|
|
These two scenarios are dealt with by two sets of access routines
|
|
SmbCeGetAssociatedServerEntry,
|
|
SmbCeGetAssociatedNetRootEntry
|
|
and
|
|
SmbCeReferenceAssociatedServerEntry,
|
|
SmbCeReferenceAssociatedNetRootEntry.
|
|
|
|
The first set of routines include the necessary asserts in a debug build to ensure that a
|
|
reference does exist.
|
|
|
|
The dereferencing mechanism is provided by the following routines
|
|
SmbCeDereferenceServerEntry,
|
|
SmbCeDereferenceSessionEntry,
|
|
SmbCeDereferenceNetRootEntry.
|
|
|
|
The dereferencing routines also ensure that the data structures are deleted if the reference
|
|
count is zero.
|
|
|
|
The construction of the various SMB mini redirector structures ( Server,Session and Net root entries )
|
|
follow a two phase protocol since network traffic is involved. The first set of routines
|
|
initiate the construction while the second set of routines complete the construction.
|
|
|
|
These routines are
|
|
SmbCeInitializeServerEntry,
|
|
SmbCeCompleteServerEntryInitialization,
|
|
SmbCeInitializeSessionEntry,
|
|
SmbCeCompleteSessionEntryInitialization,
|
|
SmbCeInitializeNetRootEntry,
|
|
and SmbCeCompleteNetRootEntryInitialization.
|
|
|
|
Each of the SMB mini redirector data structures embodies a state diagram that consist of
|
|
the following states
|
|
|
|
SMBCEDB_ACTIVE, // the instance is in use
|
|
SMBCEDB_INVALID, // the instance has been invalidated/disconnected.
|
|
SMBCEDB_MARKED_FOR_DELETION, // the instance has been marked for deletion.
|
|
SMBCEDB_RECYCLE, // the instance is available for recycling
|
|
SMBCEDB_START_CONSTRUCTION, // Initiate construction.
|
|
SMBCEDB_CONSTRUCTION_IN_PROGRESS, // the instance construction is in progress
|
|
SMBCEDB_DESTRUCTION_IN_PROGRESS // the instance destruction is in progress
|
|
|
|
A SMB MRX data structure instance begins its life in SMBCEDB_START_CONSTRUCTION state.
|
|
When the construction is initiated the state transitions to SMBCEDB_CONSTRUCTION_IN_PROGRESS.
|
|
|
|
On completion of the construction the state is either transitioned to SMBCEDB_ACTIVE if the
|
|
construction was successful. If the construction was not successful the state transitions to
|
|
SMBCEDB_MARKED_FOR_DELETION if scavenging is to be done or SMBCEDB_DESTRUCTION_IN_PROGRESS
|
|
if the tear down has been initiated.
|
|
|
|
An instance in the SMBCEDB_ACTIVE state transitions to SMBCEDB_INVALID when the transport/remote server
|
|
information associated with it has been invalidated due to disconnects etc. This state is a
|
|
cue for a reconnect attempt to be initiated.
|
|
|
|
The SMBCEDB_RECYCLE state is not in use currently.
|
|
|
|
All the state transitions are accomplished by the following set of routines which ensure that
|
|
the appropriate concurrency control action is taken.
|
|
|
|
SmbCeUpdateServerEntryState,
|
|
SmbCeUpdateSessionEntryState,
|
|
and SmbCeUpdateNetRootEntryState.
|
|
|
|
Since the Server,Session and NetRoot entries are often referenced together the following
|
|
two routines provide a batching mechanism to minimize the concurrency control overhead.
|
|
|
|
SmbCeReferenceAssociatedEntries,
|
|
SmbCeDereferenceEntries
|
|
|
|
In addition this file also contains helper functions to access certain fields of
|
|
MRX_SRV_CALL,MRX_NET_ROOT and MRX_V_NET_ROOT which are intrepreted differently by the SMB
|
|
mini redirector.
|
|
|
|
--*/
|
|
|
|
#ifndef _SMBCEDB_H_
|
|
#define _SMBCEDB_H_
|
|
#include <smbcedbp.h> // To accomodate inline routines.
|
|
|
|
//
|
|
// All the routines below return the referenced object if successful. It is the caller's
|
|
// responsibility to dereference them subsequently.
|
|
//
|
|
|
|
PSMBCEDB_SERVER_ENTRY
|
|
SmbCeFindServerEntry(
|
|
PUNICODE_STRING pServerName,
|
|
SMBCEDB_SERVER_TYPE ServerType,
|
|
PRX_CONNECTION_ID RxConnectionId);
|
|
|
|
extern NTSTATUS
|
|
SmbCeFindOrConstructServerEntry(
|
|
PUNICODE_STRING pServerName,
|
|
SMBCEDB_SERVER_TYPE ServerType,
|
|
PSMBCEDB_SERVER_ENTRY *pServerEntryPtr,
|
|
PBOOLEAN pNewServerEntry,
|
|
PRX_CONNECTION_ID RxConnectionId);
|
|
|
|
extern NTSTATUS
|
|
SmbCeInitializeServerEntry(
|
|
IN PMRX_SRV_CALL pSrvCall,
|
|
IN OUT PMRX_SRVCALL_CALLBACK_CONTEXT pCallbackContext,
|
|
IN BOOLEAN DeferNetworkInitialization);
|
|
|
|
extern NTSTATUS
|
|
SmbCeFindOrConstructSessionEntry(
|
|
IN PMRX_V_NET_ROOT pVirtualNetRoot,
|
|
OUT PSMBCEDB_SESSION_ENTRY *pSessionEntryPtr);
|
|
|
|
extern NTSTATUS
|
|
SmbCeFindOrConstructNetRootEntry(
|
|
IN PMRX_NET_ROOT pNetRoot,
|
|
OUT PSMBCEDB_NET_ROOT_ENTRY *pNetRootEntryPtr);
|
|
|
|
extern NTSTATUS
|
|
SmbCeFindOrConstructVNetRootContext(
|
|
IN OUT PMRX_V_NET_ROOT pVNetRoot,
|
|
IN BOOLEAN fDeferNetworkInitialization,
|
|
IN BOOLEAN fCscAgentOpen);
|
|
|
|
//
|
|
// The finalization routines are invoked in the context of a worker thread to finalize
|
|
// the construction of an entry as well as resume other entries waiting for it.
|
|
//
|
|
|
|
extern VOID
|
|
SmbCeCompleteServerEntryInitialization(
|
|
PSMBCEDB_SERVER_ENTRY pServerEntry,
|
|
NTSTATUS Status);
|
|
|
|
extern VOID
|
|
SmbCeCompleteSessionEntryInitialization(
|
|
PVOID pSessionEntry,
|
|
NTSTATUS Status,
|
|
BOOLEAN SecuritySignatureReturned);
|
|
|
|
extern VOID
|
|
SmbCeCompleteVNetRootContextInitialization(
|
|
PVOID pVNetRootContextEntry);
|
|
|
|
extern VOID
|
|
SmbReferenceRecord(
|
|
PREFERENCE_RECORD pReferenceRecord,
|
|
PVOID FileName,
|
|
ULONG FileLine);
|
|
|
|
//
|
|
// Routines for referencing/dereferencing SMB Mini redirector information associated with
|
|
// the wrapper data structures.
|
|
//
|
|
|
|
INLINE PSMBCEDB_SERVER_ENTRY
|
|
SmbCeGetAssociatedServerEntry(
|
|
PMRX_SRV_CALL pSrvCall)
|
|
{
|
|
ASSERT(pSrvCall->Context != NULL);
|
|
return (PSMBCEDB_SERVER_ENTRY)(pSrvCall->Context);
|
|
}
|
|
|
|
INLINE PSMBCE_V_NET_ROOT_CONTEXT
|
|
SmbCeGetAssociatedVNetRootContext(
|
|
PMRX_V_NET_ROOT pVNetRoot)
|
|
{
|
|
ASSERT(pVNetRoot != NULL);
|
|
return (PSMBCE_V_NET_ROOT_CONTEXT)(pVNetRoot->Context);
|
|
}
|
|
|
|
INLINE PSMBCEDB_NET_ROOT_ENTRY
|
|
SmbCeGetAssociatedNetRootEntry(
|
|
PMRX_NET_ROOT pNetRoot)
|
|
{
|
|
ASSERT(pNetRoot->Context != NULL);
|
|
return (PSMBCEDB_NET_ROOT_ENTRY)(pNetRoot->Context);
|
|
}
|
|
|
|
//
|
|
// All the macros for referencing and dereferencing begin with a prefix SmbCep...
|
|
// The p stands for a private version which is used for implementing reference tracking.
|
|
// By selectively turning on the desired flag it is possible to track every instance
|
|
// of a given type as the reference count is modified.
|
|
//
|
|
|
|
#define MRXSMB_REF_TRACE_SERVER_ENTRY (0x00000001)
|
|
#define MRXSMB_REF_TRACE_NETROOT_ENTRY (0x00000002)
|
|
#define MRXSMB_REF_TRACE_SESSION_ENTRY (0x00000004)
|
|
#define MRXSMB_REF_TRACE_VNETROOT_CONTEXT (0x00000008)
|
|
|
|
#define MRXSMB_LOG_REF_TRACKING (0x80000000)
|
|
#define MRXSMB_PRINT_REF_TRACKING (0x40000000)
|
|
|
|
extern ULONG MRxSmbReferenceTracingValue;
|
|
|
|
VOID
|
|
MRxSmbTrackRefCount(
|
|
PVOID pInstance,
|
|
PCHAR FileName,
|
|
ULONG Line);
|
|
|
|
VOID
|
|
MRxSmbTrackDerefCount(
|
|
PVOID pInstance,
|
|
PCHAR FileName,
|
|
ULONG Line);
|
|
|
|
#define MRXSMB_REF_TRACING_ON(TraceMask) (TraceMask & MRxSmbReferenceTracingValue)
|
|
//#define MRXSMB_PRINT_REF_COUNT(TYPE,Count) \
|
|
// if (MRXSMB_REF_TRACING_ON( MRXSMB_REF_TRACE_ ## TYPE )) { \
|
|
// DbgPrint("%ld\n",Count); \
|
|
// }
|
|
|
|
INLINE VOID
|
|
SmbCepReferenceServerEntry(
|
|
PSMBCEDB_SERVER_ENTRY pServerEntry)
|
|
{
|
|
ASSERT(pServerEntry->Header.ObjectType == SMBCEDB_OT_SERVER);
|
|
InterlockedIncrement(&pServerEntry->Header.SwizzleCount);
|
|
}
|
|
|
|
INLINE VOID
|
|
SmbCepReferenceSessionEntry(
|
|
PSMBCEDB_SESSION_ENTRY pSessionEntry)
|
|
{
|
|
ASSERT(pSessionEntry->Header.ObjectType == SMBCEDB_OT_SESSION);
|
|
InterlockedIncrement(&(pSessionEntry->Header.SwizzleCount));
|
|
}
|
|
|
|
INLINE VOID
|
|
SmbCepReferenceNetRootEntry(
|
|
PSMBCEDB_NET_ROOT_ENTRY pNetRootEntry,
|
|
PVOID FileName,
|
|
ULONG FileLine)
|
|
{
|
|
ASSERT(pNetRootEntry->Header.ObjectType == SMBCEDB_OT_NETROOT);
|
|
InterlockedIncrement(&(pNetRootEntry->Header.SwizzleCount));
|
|
}
|
|
|
|
INLINE VOID
|
|
SmbCepReferenceVNetRootContext(
|
|
PSMBCE_V_NET_ROOT_CONTEXT pVNetRootContext)
|
|
{
|
|
ASSERT(pVNetRootContext->Header.ObjectType == SMBCEDB_OT_VNETROOTCONTEXT);
|
|
InterlockedIncrement(&(pVNetRootContext->Header.SwizzleCount));
|
|
}
|
|
|
|
INLINE PSMBCEDB_SERVER_ENTRY
|
|
SmbCeReferenceAssociatedServerEntry(
|
|
PMRX_SRV_CALL pSrvCall)
|
|
{
|
|
PSMBCEDB_SERVER_ENTRY pServerEntry;
|
|
|
|
if ((pServerEntry = pSrvCall->Context) != NULL) {
|
|
ASSERT(pServerEntry->Header.SwizzleCount > 0);
|
|
MRxSmbTrackRefCount(pServerEntry,__FILE__,__LINE__);
|
|
SmbCepReferenceServerEntry(pServerEntry);
|
|
}
|
|
|
|
return pServerEntry;
|
|
}
|
|
|
|
|
|
INLINE PSMBCEDB_NET_ROOT_ENTRY
|
|
SmbCeReferenceAssociatedNetRootEntry(
|
|
PMRX_NET_ROOT pNetRoot)
|
|
{
|
|
PSMBCEDB_NET_ROOT_ENTRY pNetRootEntry;
|
|
|
|
if ((pNetRootEntry = pNetRoot->Context) != NULL) {
|
|
ASSERT(pNetRootEntry->Header.SwizzleCount > 0);
|
|
MRxSmbTrackRefCount(pNetRootEntry,__FILE__,__LINE__);
|
|
SmbCepReferenceNetRootEntry(pNetRootEntry,__FILE__,__LINE__);
|
|
}
|
|
|
|
return pNetRootEntry;
|
|
}
|
|
|
|
extern VOID
|
|
SmbCepDereferenceServerEntry(
|
|
PSMBCEDB_SERVER_ENTRY pServerEntry);
|
|
|
|
extern VOID
|
|
SmbCepDereferenceSessionEntry(
|
|
PSMBCEDB_SESSION_ENTRY pSessionEntry);
|
|
|
|
extern VOID
|
|
SmbCepDereferenceNetRootEntry(
|
|
PSMBCEDB_NET_ROOT_ENTRY pNetRootEntry,
|
|
PVOID FileName,
|
|
ULONG FileLine);
|
|
|
|
extern VOID
|
|
SmbCepDereferenceVNetRootContext(
|
|
PSMBCE_V_NET_ROOT_CONTEXT pVNetRootContext);
|
|
|
|
#define SmbCeReferenceServerEntry(pServerEntry) \
|
|
MRxSmbTrackRefCount(pServerEntry,__FILE__,__LINE__); \
|
|
SmbReferenceRecord(&pServerEntry->ReferenceRecord[0],__FILE__,__LINE__); \
|
|
SmbCepReferenceServerEntry(pServerEntry)
|
|
|
|
#define SmbCeReferenceNetRootEntry(pNetRootEntry) \
|
|
MRxSmbTrackRefCount(pNetRootEntry,__FILE__,__LINE__); \
|
|
SmbCepReferenceNetRootEntry(pNetRootEntry,__FILE__,__LINE__)
|
|
|
|
#define SmbCeReferenceVNetRootContext(pVNetRootContext) \
|
|
MRxSmbTrackRefCount(pVNetRootContext,__FILE__,__LINE__); \
|
|
SmbReferenceRecord(&pVNetRootContext->ReferenceRecord[0],__FILE__,__LINE__); \
|
|
SmbCepReferenceVNetRootContext(pVNetRootContext)
|
|
|
|
#define SmbCeReferenceSessionEntry(pSessionEntry) \
|
|
MRxSmbTrackRefCount(pSessionEntry,__FILE__,__LINE__); \
|
|
SmbCepReferenceSessionEntry(pSessionEntry)
|
|
|
|
#define SmbCeDereferenceServerEntry(pServerEntry) \
|
|
MRxSmbTrackDerefCount(pServerEntry,__FILE__,__LINE__); \
|
|
SmbReferenceRecord(&pServerEntry->ReferenceRecord[0],__FILE__,__LINE__); \
|
|
SmbCepDereferenceServerEntry(pServerEntry)
|
|
|
|
#define SmbCeDereferenceNetRootEntry(pNetRootEntry) \
|
|
MRxSmbTrackDerefCount(pNetRootEntry,__FILE__,__LINE__); \
|
|
SmbCepDereferenceNetRootEntry(pNetRootEntry,__FILE__,__LINE__)
|
|
|
|
#define SmbCeDereferenceSessionEntry(pSessionEntry) \
|
|
MRxSmbTrackDerefCount(pSessionEntry,__FILE__,__LINE__); \
|
|
SmbCepDereferenceSessionEntry(pSessionEntry)
|
|
|
|
#define SmbCeDereferenceVNetRootContext(pVNetRootContext) \
|
|
MRxSmbTrackDerefCount(pVNetRootContext,__FILE__,__LINE__); \
|
|
SmbReferenceRecord(&pVNetRootContext->ReferenceRecord[0],__FILE__,__LINE__); \
|
|
SmbCepDereferenceVNetRootContext(pVNetRootContext)
|
|
|
|
INLINE VOID
|
|
SmbCeDereferenceEntries(
|
|
PSMBCEDB_SERVER_ENTRY pServerEntry,
|
|
PSMBCEDB_SESSION_ENTRY pSessionEntry,
|
|
PSMBCEDB_NET_ROOT_ENTRY pNetRootEntry)
|
|
{
|
|
SmbCeDereferenceNetRootEntry(pNetRootEntry);
|
|
SmbCeDereferenceSessionEntry(pSessionEntry);
|
|
SmbCeDereferenceServerEntry(pServerEntry);
|
|
}
|
|
|
|
//
|
|
// Routines for updating the state of SMB MRX data structures
|
|
//
|
|
|
|
#define SmbCeUpdateServerEntryState(pServerEntry,NEWSTATE) \
|
|
InterlockedExchange(&pServerEntry->Header.State,(NEWSTATE))
|
|
|
|
#define SmbCeUpdateSessionEntryState(pSessionEntry,NEWSTATE) \
|
|
InterlockedExchange(&pSessionEntry->Header.State,(NEWSTATE))
|
|
|
|
#define SmbCeUpdateNetRootEntryState(pNetRootEntry,NEWSTATE) \
|
|
InterlockedExchange(&pNetRootEntry->Header.State,(NEWSTATE))
|
|
|
|
#define SmbCeUpdateVNetRootContextState(pVNetRootContext,NEWSTATE) \
|
|
InterlockedExchange(&pVNetRootContext->Header.State,(NEWSTATE))
|
|
|
|
INLINE BOOLEAN
|
|
SmbCeIsServerInDisconnectedMode(
|
|
PSMBCEDB_SERVER_ENTRY pServerEntry)
|
|
{
|
|
return ((pServerEntry->Server.CscState == ServerCscDisconnected) ||
|
|
(pServerEntry->Server.CscState == ServerCscTransitioningToShadowing));
|
|
}
|
|
|
|
INLINE BOOLEAN
|
|
SmbCeIsServerSetupForDisconnectedOperation(
|
|
PSMBCEDB_SERVER_ENTRY pServerEntry)
|
|
{
|
|
return (pServerEntry->pTransport == NULL);
|
|
}
|
|
|
|
//
|
|
// The RDBSS wrapper stores all the server names with a backslash prepended to
|
|
// them. This helps synthesize UNC names easily. In order to manipulate the
|
|
// Server name in the SMB protocol the \ needs to be stripped off.
|
|
|
|
INLINE VOID
|
|
SmbCeGetServerName(
|
|
PMRX_SRV_CALL pSrvCall,
|
|
PUNICODE_STRING pServerName)
|
|
{
|
|
ASSERT(pSrvCall->pSrvCallName != NULL);
|
|
pServerName->Buffer = pSrvCall->pSrvCallName->Buffer + 1;
|
|
pServerName->Length = pSrvCall->pSrvCallName->Length - sizeof(WCHAR);
|
|
pServerName->MaximumLength = pSrvCall->pSrvCallName->MaximumLength - sizeof(WCHAR);
|
|
}
|
|
|
|
INLINE VOID
|
|
SmbCeGetNetRootName(
|
|
PMRX_NET_ROOT pNetRoot,
|
|
PUNICODE_STRING pNetRootName)
|
|
{
|
|
ASSERT(pNetRoot->pNetRootName != NULL);
|
|
*pNetRootName = *pNetRoot->pNetRootName;
|
|
}
|
|
|
|
extern NTSTATUS
|
|
SmbCeDestroyAssociatedVNetRootContext(
|
|
PMRX_V_NET_ROOT pVNetRoot);
|
|
|
|
extern VOID
|
|
SmbCeTearDownVNetRootContext(
|
|
PSMBCE_V_NET_ROOT_CONTEXT pVNetRootContext);
|
|
|
|
extern NTSTATUS
|
|
SmbCeGetUserNameAndDomainName(
|
|
PSMBCEDB_SESSION_ENTRY pSessionEntry,
|
|
PUNICODE_STRING pUserName,
|
|
PUNICODE_STRING pUserDomainName);
|
|
|
|
extern BOOLEAN
|
|
SmbCeAreServerEntriesAliased(
|
|
PSMBCEDB_SERVER_ENTRY pServernEntry1,
|
|
PSMBCEDB_SERVER_ENTRY pServerEntry2);
|
|
|
|
extern VOID
|
|
SmbCeUnblockSerializedSessionSetupRequests(
|
|
PSMBCEDB_SESSION_ENTRY pSessionEntry);
|
|
|
|
extern NTSTATUS
|
|
SmbCeUpdateSrvCall(
|
|
IN PSMBCEDB_SERVER_ENTRY pServerEntry);
|
|
|
|
extern NTSTATUS
|
|
SmbCeUpdateNetRoot(
|
|
PSMBCEDB_NET_ROOT_ENTRY pNetRootEntry,
|
|
PMRX_NET_ROOT pNetRoot);
|
|
|
|
extern NTSTATUS
|
|
SmbCeScavengeRelatedContexts(
|
|
IN PSMBCEDB_SERVER_ENTRY pServerEntry);
|
|
|
|
extern VOID
|
|
SmbCeResumeOutstandingRequests(
|
|
IN OUT PSMBCEDB_REQUESTS pRequests,
|
|
IN NTSTATUS Status);
|
|
|
|
|
|
// given \\server\share, this routine returns a refcounted serverentry
|
|
NTSTATUS
|
|
FindServerEntryFromCompleteUNCPath(
|
|
USHORT *lpuServerShareName,
|
|
PSMBCEDB_SERVER_ENTRY *ppServerEntry);
|
|
|
|
// given \\server\share, this routine returns a refcounted netroot entry
|
|
NTSTATUS
|
|
FindNetRootEntryFromCompleteUNCPath(
|
|
USHORT *lpuServerShareName,
|
|
PSMBCEDB_NET_ROOT_ENTRY *ppNetRootEntry);
|
|
|
|
#endif // _SMBCEDB_H_
|
|
|