/**********************************************************************/ /** 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_