windows-nt/Source/XPSP1/NT/admin/netui/common/h/usrcache.hxx
2020-09-26 16:20:57 +08:00

421 lines
12 KiB
C++

/**********************************************************************/
/** Microsoft Windows NT **/
/** Copyright(c) Microsoft Corp., 1992 **/
/**********************************************************************/
/*
usrcache.hxx
This file contains the class declarations for the abstract
USER_LBI_CACHE class. This class implements a cache of LBIs
used when dealing with very large user databases. This class's
primary purpose is to be the "backing store" for a LAZY_LISTBOX.
As such, its interface is very similar to the BLT_LISTBOX
interface.
FILE HISTORY:
KeithMo 15-Dec-1992 Created.
*/
#ifndef _USRCACHE_HXX_
#define _USRCACHE_HXX_
#include "base.hxx"
#include "slist.hxx"
DLL_CLASS ADMIN_AUTHORITY;
//
// These manifests are the default parameters for the
// USER_LBI_CACHE constructor.
//
#define ULC_INITIAL_GROWTH_DEFAULT 0
#define ULC_REQUEST_COUNT_DEFAULT 0
#define ULC_REMOTE_USERS_DEFAULT FALSE
//
// This is the "growth delta" applied to the cache whenever
// the structure array needs to be resized as a result of
// adding items to the cache.
//
// NOTE: This MUST be a power of two!
//
#define ULC_CACHE_GROWTH_DELTA 32
// Error codes returned by the AddItem method.
//
#define ULC_ERR (-1)
//
// An array of these simple structures is used as the
// actual cache. The following relationships are always
// in effect for pddu and plbi:
//
// +-------+-------+------------------------------+
// | | | |
// | pddu | plbi | cache entry |
// | | | |
// +-------+-------+------------------------------+
// | | | |
// | NULL | NULL | unused or unavailable |
// | | | |
// | NULL | !NULL | LBI created with AddItem |
// | | | |
// | !NULL | NULL | needs LBI (no QueryItem yet) |
// | | | |
// | !NULL | !NULL | LBI created during QueryItem |
// | | | |
// +-------+-------+------------------------------+
//
// The array elements actually consist of ULC_ENTRY_BASE structures
// plus _cbExtraBytes of extra space.
//
typedef struct _ULC_ENTRY
{
DOMAIN_DISPLAY_USER * pddu;
LBI * plbi;
BYTE bExtraBytes;
} ULC_ENTRY;
typedef struct _ULC_ENTRY_BASE
{
DOMAIN_DISPLAY_USER * pddu;
LBI * plbi;
} ULC_ENTRY_BASE;
//
// This is the "type" of the compare method required by qsort().
//
typedef int (__cdecl * PQSORT_COMPARE)( const void * p0, const void * p1 );
/*************************************************************************
NAME: ULC_API_BUFFER
SYNOPSIS: ULC_API_BUFFER is used to keep track of the buffers
allocated by the the SamQueryDisplayInformation
API. An SLIST of these nodes is maintained by
USER_LBI_CACHE.
INTERFACE: ULC_API_BUFFER - Class constructor.
~ULC_API_BUFFER - Class destructor.
QueryItemCount - Returns the number of items
stored in the buffer associated
with this node.
QueryBufferPtr - Returns the buffer pointer
associated with this node.
HISTORY:
KeithMo 15-Dec-1992 Created.
**************************************************************************/
DLL_CLASS ULC_API_BUFFER
{
private:
//
// Pointer to the actual buffer.
//
DOMAIN_DISPLAY_USER * _pddu;
//
// The number of items in this buffer.
//
ULONG _cItems;
public:
//
// Usual constructor/destructor goodies.
//
ULC_API_BUFFER( DOMAIN_DISPLAY_USER * pddu,
ULONG cItems );
~ULC_API_BUFFER( VOID );
//
// Public accessors.
//
ULONG QueryCount( VOID ) const
{ return _cItems; }
DOMAIN_DISPLAY_USER * QueryBuffer( VOID ) const
{ return _pddu; }
}; // class ULC_API_BUFFER
DECL_SLIST_OF( ULC_API_BUFFER, DLL_BASED );
/*************************************************************************
NAME: USER_LBI_CACHE
SYNOPSIS: This abstract class implements the guts of an LBI
cache used to manipulate very large user databases.
INTERFACE: USER_LBI_CACHE - Class constructor.
~USER_LBI_CACHE - Class destructor.
ReadUsers - Read user accounts from a server
into the cache. pfQuitEnum
optionally points to a location
where another thread may request
that enumeration stop.
AddItem - Add an item to the cache
RemoveItem - Remove an item from the cache
w/o deleting the corresponding
LBI. Strangely, this may call
through to CreateLBI to create
a new LBI.
QueryItem - Query a cache item. This may
call through to the CreateLBI
virtual to create a new LBI.
Therefore, it may fail.
QueryCount - Returns the number of entries
in the cache.
IsItemAvailable - Returns TRUE if the given item
is available in the cache. Note
that this does *not* mean that
an associated LBI has been
created, only that the necessary
data is available.
Sort - Sort the cache items. Note that
an initial sort is performed at
object construction.
PARENT: BASE
HISTORY:
KeithMo 15-Dec-1992 Created.
**************************************************************************/
DLL_CLASS USER_LBI_CACHE : public BASE
{
private:
//
// Our cache.
//
VOID * _pCache;
//
// A list of buffers as returned by SamQueryDisplayInformation.
//
SLIST_OF( ULC_API_BUFFER ) _slBuffers;
//
// The number of "slots" in the cache. These slots
// are not necessarily in use. See _cEntries;
//
INT _cSlots;
//
// The number of entries in the cache. Note that the
// cache may "grow" (the array will be resized) as new
// entries are added. _cEntries is always <= _cSlots.
//
INT _cEntries;
//
// Number of extra bytes at the end of each ULC_ENTRY. Note that
// this is rounded up from the construction parameter to the
// next multiple of sizeof(DWORD).
//
INT _cbExtraBytes;
//
// This worker method is responsible for "lazy LBI" creation.
// It is invoked by QueryItem & RemoveItem to ensure that a
// particular cache entry contains a valid LBI.
//
LBI * W_GetLBI( INT i );
//
// This worker method is responsible for growing the
// cache array as needed.
//
BOOL W_GrowCache( INT cTotalCacheEntries );
protected:
//
// This callback is invoked during QueryItem() cache misses.
//
virtual LBI * CreateLBI( const DOMAIN_DISPLAY_USER * pddu ) = 0;
//
// These callbacks are invoked during the binary search
// invoked while processing AddItem.
//
virtual INT Compare( const LBI * plbi,
const DOMAIN_DISPLAY_USER * pddu ) const = 0;
virtual INT Compare( const LBI * plbi0,
const LBI * plbi1 ) const = 0;
//
// This virtual callback returns the appropriate compare
// method to be used by qsort() while sorting the cache entries.
// The default compare method is USER_LBI_CACHE::CompareLogonNames().
//
virtual PQSORT_COMPARE QueryCompareMethod( VOID ) const;
//
// These virtual callbacks are invoked to lock & unlock
// the cache. These may be redefined by a subclass to
// provide multithread safety. The default implementation
// is a NOP for each callback.
//
virtual VOID LockCache( VOID );
virtual VOID UnlockCache( VOID );
//
// This static method will do a case insensitive compare
// of two UNICODE_STRINGs. Might be useful for derived
// subclasses.
//
static int CmpUniStrs( const UNICODE_STRING * punicode0,
const UNICODE_STRING * punicode1 );
//
// This is the default compare routine to be used by
// qsort() while sorting the cache entries.
//
static int __cdecl CompareLogonNames( const void * p0,
const void * p1 );
inline INT QueryULCEntrySize( VOID )
{ return sizeof(ULC_ENTRY_BASE) + _cbExtraBytes; }
inline ULC_ENTRY * QueryULCEntryPtr( INT i )
{
ASSERT( i >= 0 && i < _cSlots && _pCache != NULL );
return (ULC_ENTRY *) ( ((BYTE *)_pCache) + ( i * QueryULCEntrySize() ) );
}
public:
//
// Usual constructor/destructor goodies.
//
// Note that padminauth must be NULL for downlevel machines.
//
USER_LBI_CACHE( INT cbExtraBytes = 0 );
virtual ~USER_LBI_CACHE( VOID );
//
// Read the API data & initialize the cache. New items are appended
// to the end of the cache, and are not in sorted order.
//
APIERR ReadUsers( ADMIN_AUTHORITY * padminauth,
UINT nInitialGrowthSpace = ULC_INITIAL_GROWTH_DEFAULT,
UINT cUsersPerRequest = ULC_REQUEST_COUNT_DEFAULT,
BOOL fIncludeRemoteUsers = ULC_REMOTE_USERS_DEFAULT,
BOOL * pfQuitEnum = NULL );
//
// Add a new LBI to the cache. Will return the index of
// the newly added item if successful, ULC_ERR otherwise.
//
virtual INT AddItem( LBI * plbi );
//
// Remove the item at index i from the cache, but don't
// delete the LBI. Will return a pointer to the LBI if
// successful, NULL otherwise.
//
virtual LBI * RemoveItem( INT i );
//
// Query the item at index i in the cache. Will return
// a pointer to the LBI if successful, NULL otherwise.
//
virtual LBI * QueryItem( INT i );
//
// Determines if the necessary data for a given item is
// available.
//
virtual BOOL IsItemAvailable( INT i );
//
// Returns the number of entries in the cache.
//
INT QueryCount( VOID ) const
{ return _cEntries; }
//
// Sort the cache entries.
//
VOID Sort( VOID );
//
// Perform a binary search on the cache, finding the
// appropriate index for the new LBI (or a potential LBI for the
// provided DOMAIN_DISPLAY_USER).
//
INT BinarySearch( LBI * plbiNew );
INT BinarySearch( DOMAIN_DISPLAY_USER * pddu );
}; // class USER_LBI_CACHE
#endif // _USRCACHE_HXX_