|
|
/*++
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:
Joe Linn (JoeLinn) 8-8-94
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);
#if 0
#define RX_PREFIXTABLELOCK_ARGS ,__FILE__,__LINE__
#define RX_PREFIXTABLELOCK_PARAMS ,PSZ FileName,ULONG LineNumber
#else
#define RX_PREFIXTABLELOCK_ARGS
#define RX_PREFIXTABLELOCK_PARAMS
#endif
#define RxAcquirePrefixTableLockShared(pPrefixTable,Wait) \
RxpAcquirePrefixTableLockShared((pPrefixTable),(Wait),TRUE RX_PREFIXTABLELOCK_ARGS)
#define RxAcquirePrefixTableLockExclusive(pPrefixTable,Wait) \
RxpAcquirePrefixTableLockExclusive((pPrefixTable),(Wait),TRUE RX_PREFIXTABLELOCK_ARGS)
#define RxReleasePrefixTableLock(pPrefixTable) \
RxpReleasePrefixTableLock((pPrefixTable),TRUE RX_PREFIXTABLELOCK_ARGS)
extern BOOLEAN RxpAcquirePrefixTableLockShared( PRX_PREFIX_TABLE pTable, BOOLEAN Wait, BOOLEAN ProcessBufferingStateChangeRequests RX_PREFIXTABLELOCK_PARAMS);
extern BOOLEAN RxpAcquirePrefixTableLockExclusive( PRX_PREFIX_TABLE pTable, BOOLEAN Wait, BOOLEAN ProcessBufferingStateChangeRequests RX_PREFIXTABLELOCK_PARAMS);
extern VOID RxExclusivePrefixTableLockToShared(PRX_PREFIX_TABLE pTable);
extern VOID RxpReleasePrefixTableLock( PRX_PREFIX_TABLE pTable, BOOLEAN ProcessBufferingStateChangeRequests RX_PREFIXTABLELOCK_PARAMS);
#define RxIsPrefixTableLockExclusive(PTABLE) ExIsResourceAcquiredExclusiveLite(&(PTABLE)->TableLock)
#define RxIsPrefixTableLockAcquired(PTABLE) ( ExIsResourceAcquiredSharedLite(&(PTABLE)->TableLock) || \
ExIsResourceAcquiredExclusiveLite(&(PTABLE)->TableLock) )
VOID RxInitializePrefixTable( IN OUT PRX_PREFIX_TABLE ThisTable, IN ULONG TableSize OPTIONAL, //0=>use default
IN BOOLEAN CaseInsensitiveMatch );
VOID RxFinalizePrefixTable( IN OUT PRX_PREFIX_TABLE ThisTable );
//
// Rx form of a table entry.
typedef struct _RX_PREFIX_ENTRY {
NODE_TYPE_CODE NodeTypeCode; // Normal Header for Refcounted Structure
NODE_BYTE_SIZE NodeByteSize;
USHORT CaseInsensitiveLength; //the initial part of the name that is always case insensitive
USHORT Spare1;
//UNICODE_PREFIX_TABLE_ENTRY TableEntry; // Actual table linkage
ULONG SavedHashValue; LIST_ENTRY HashLinks;
LIST_ENTRY MemberQLinks; // queue of the set members
UNICODE_STRING Prefix; // Name of the entry
PULONG ContainerRefCount; // Pointer to the reference count of the container
PVOID ContainingRecord; // don't know the parent type...nor do all callers!
// thus, i need this backptr.
PVOID Context; // some space that alternate table routines can use
RX_CONNECTION_ID ConnectionId; // Used for controlled multiplexing
} 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 {
NODE_TYPE_CODE NodeTypeCode; // Normal Header
NODE_BYTE_SIZE NodeByteSize;
ULONG Version; // version stamp changes on each insertion/removal
LIST_ENTRY MemberQueue; // queue of the inserted names
ERESOURCE TableLock; // Resource used to control table access
PRX_PREFIX_ENTRY TableEntryForNull; // PrefixEntry for the Null string
BOOLEAN CaseInsensitiveMatch; BOOLEAN IsNetNameTable; //we may act differently for this....esp for debug!
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;
#endif // _RXPREFIX_
|