225 lines
6.2 KiB
C
225 lines
6.2 KiB
C
|
/*++
|
||
|
|
||
|
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_
|