/*++ Copyright (c) 1989 Microsoft Corporation Module Name: prefix.h Abstract: This module defines the data structures that enable the RDBSS to use the prefix package to catalog its server and netroot names. For the moment, file/directory names use the same stuff. Author: Revision History: --*/ #ifndef _RXPREFIX_ #define _RXPREFIX_ // this stuff is implemented in prefix.c /* The current implementation uses a table that has as components: 1) a prefix table 2) a queue 3) a version 4) a lock You use the lock in the normal way: shared to lookup; eclusive to change. the version changes eith each change. The reason that we have the queue is that the prefix table package allows caller to be enumerating at a time..... the Q/version approach allows multiple guys at a time. The Q could be used as a faster lookup for filenames but the prefix table is definitely the right thing for netroots. */ typedef struct _RX_CONNECTION_ID { union { ULONG SessionID; LUID Luid; }; } RX_CONNECTION_ID, *PRX_CONNECTION_ID; ULONG RxTableComputeHashValue ( IN PUNICODE_STRING Name ); PVOID RxPrefixTableLookupName ( IN PRX_PREFIX_TABLE ThisTable, IN PUNICODE_STRING CanonicalName, OUT PUNICODE_STRING RemainingName, IN PRX_CONNECTION_ID ConnectionId ); PRX_PREFIX_ENTRY RxPrefixTableInsertName ( IN OUT PRX_PREFIX_TABLE ThisTable, IN OUT PRX_PREFIX_ENTRY ThisEntry, IN PVOID Container, IN PULONG ContainerRefCount, IN USHORT CaseInsensitiveLength, IN PRX_CONNECTION_ID ConnectionId ); VOID RxRemovePrefixTableEntry ( IN OUT PRX_PREFIX_TABLE ThisTable, IN OUT PRX_PREFIX_ENTRY Entry ); VOID RxDereferenceEntryContainer ( IN OUT PRX_PREFIX_ENTRY Entry, IN PRX_PREFIX_TABLE PrefixTable ); BOOLEAN RxIsNameTableEmpty ( IN PRX_PREFIX_TABLE ThisTable ); VOID RxInitializePrefixTable ( IN OUT PRX_PREFIX_TABLE ThisTable, IN ULONG TableSize OPTIONAL, IN BOOLEAN CaseInsensitiveMatch ); VOID RxFinalizePrefixTable ( IN OUT PRX_PREFIX_TABLE ThisTable ); // // Rx form of a table entry. // typedef struct _RX_PREFIX_ENTRY { // // Normal Header for Refcounted Structure // NODE_TYPE_CODE NodeTypeCode; NODE_BYTE_SIZE NodeByteSize; // // the initial part of the name that is always case insensitive // USHORT CaseInsensitiveLength; USHORT Spare1; ULONG SavedHashValue; LIST_ENTRY HashLinks; // // queue of the set members // LIST_ENTRY MemberQLinks; // // Name of the entry // UNICODE_STRING Prefix; // // Pointer to the reference count of the container // PULONG ContainerRefCount; // // don't know the parent type...nor do all callers! // thus, i need this backptr. // PVOID ContainingRecord; // // some space that alternate table routines can use // PVOID Context; // // Used for controlled multiplexing // RX_CONNECTION_ID ConnectionId; } RX_PREFIX_ENTRY, *PRX_PREFIX_ENTRY; // // Rx form of name table. wraps in a lock and a queue. Originally, this implementation used the prefix tables // in Rtl which don't allow an empty string entry. so, we special case this. // #define RX_PREFIX_TABLE_DEFAULT_LENGTH 32 typedef PVOID (*PRX_TABLE_LOOKUPNAME) ( IN PRX_PREFIX_TABLE ThisTable, IN PUNICODE_STRING CanonicalName, OUT PUNICODE_STRING RemainingName ); typedef PRX_PREFIX_ENTRY (*PRX_TABLE_INSERTENTRY) ( IN OUT PRX_PREFIX_TABLE ThisTable, IN OUT PRX_PREFIX_ENTRY ThisEntry ); typedef VOID (*PRX_TABLE_REMOVEENTRY) ( IN OUT PRX_PREFIX_TABLE ThisTable, IN OUT PRX_PREFIX_ENTRY Entry ); typedef struct _RX_PREFIX_TABLE { // // Normal Header // NODE_TYPE_CODE NodeTypeCode; NODE_BYTE_SIZE NodeByteSize; // // version stamp changes on each insertion/removal // ULONG Version; // // queue of the inserted names // LIST_ENTRY MemberQueue; // // Resource used to control table access // ERESOURCE TableLock; // // PrefixEntry for the Null string // PRX_PREFIX_ENTRY TableEntryForNull; BOOLEAN CaseInsensitiveMatch; // // we may act differently for this....esp for debug! // BOOLEAN IsNetNameTable; ULONG TableSize; #if DBG ULONG Lookups; ULONG FailedLookups; ULONG Considers; ULONG Compares; #endif LIST_ENTRY HashBuckets[RX_PREFIX_TABLE_DEFAULT_LENGTH]; } RX_PREFIX_TABLE, *PRX_PREFIX_TABLE; #if 0 #define RxAcquirePrefixTableLockShared(PrefixTable,Wait) \ RxpAcquirePrefixTableLockShared((PrefixTable),(Wait),TRUE, __FILE__,__LINE__ ) #define RxAcquirePrefixTableLockExclusive(PrefixTable,Wait) \ RxpAcquirePrefixTableLockExclusive((PrefixTable),(Wait),TRUE, __FILE__,__LINE__ ) #define RxReleasePrefixTableLock(PrefixTable) \ RxpReleasePrefixTableLock((PrefixTable),TRUE, __FILE__,__LINE__ ) extern BOOLEAN RxpAcquirePrefixTableLockShared ( PRX_PREFIX_TABLE pTable, BOOLEAN Wait, BOOLEAN ProcessBufferingStateChangeRequests, PSZ FileName, ULONG LineNumber ); extern BOOLEAN RxpAcquirePrefixTableLockExclusive ( PRX_PREFIX_TABLE pTable, BOOLEAN Wait, BOOLEAN ProcessBufferingStateChangeRequests, PSZ FileName, ULONG LineNumber ); extern VOID RxpReleasePrefixTableLock ( PRX_PREFIX_TABLE pTable, BOOLEAN ProcessBufferingStateChangeRequests, PSZ FileName, ULONG LineNumber ); #else #define RxAcquirePrefixTableLockShared(TABLE,WAIT) ExAcquireResourceSharedLite( &(TABLE)->TableLock, (WAIT) ) #define RxAcquirePrefixTableLockExclusive(TABLE,WAIT) ExAcquireResourceExclusiveLite( &(TABLE)->TableLock, (WAIT) ) #define RxReleasePrefixTableLock(TABLE) ExReleaseResourceLite( &(TABLE)->TableLock ) #endif extern VOID RxExclusivePrefixTableLockToShared ( PRX_PREFIX_TABLE Table ); #define RxIsPrefixTableLockExclusive(TABLE) ExIsResourceAcquiredExclusiveLite(&(TABLE)->TableLock) #define RxIsPrefixTableLockAcquired(TABLE) ( ExIsResourceAcquiredSharedLite(&(TABLE)->TableLock) || \ ExIsResourceAcquiredExclusiveLite(&(TABLE)->TableLock) ) #endif // _RXPREFIX_