Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

420 lines
12 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows NT **/
  3. /** Copyright(c) Microsoft Corp., 1992 **/
  4. /**********************************************************************/
  5. /*
  6. usrcache.hxx
  7. This file contains the class declarations for the abstract
  8. USER_LBI_CACHE class. This class implements a cache of LBIs
  9. used when dealing with very large user databases. This class's
  10. primary purpose is to be the "backing store" for a LAZY_LISTBOX.
  11. As such, its interface is very similar to the BLT_LISTBOX
  12. interface.
  13. FILE HISTORY:
  14. KeithMo 15-Dec-1992 Created.
  15. */
  16. #ifndef _USRCACHE_HXX_
  17. #define _USRCACHE_HXX_
  18. #include "base.hxx"
  19. #include "slist.hxx"
  20. DLL_CLASS ADMIN_AUTHORITY;
  21. //
  22. // These manifests are the default parameters for the
  23. // USER_LBI_CACHE constructor.
  24. //
  25. #define ULC_INITIAL_GROWTH_DEFAULT 0
  26. #define ULC_REQUEST_COUNT_DEFAULT 0
  27. #define ULC_REMOTE_USERS_DEFAULT FALSE
  28. //
  29. // This is the "growth delta" applied to the cache whenever
  30. // the structure array needs to be resized as a result of
  31. // adding items to the cache.
  32. //
  33. // NOTE: This MUST be a power of two!
  34. //
  35. #define ULC_CACHE_GROWTH_DELTA 32
  36. // Error codes returned by the AddItem method.
  37. //
  38. #define ULC_ERR (-1)
  39. //
  40. // An array of these simple structures is used as the
  41. // actual cache. The following relationships are always
  42. // in effect for pddu and plbi:
  43. //
  44. // +-------+-------+------------------------------+
  45. // | | | |
  46. // | pddu | plbi | cache entry |
  47. // | | | |
  48. // +-------+-------+------------------------------+
  49. // | | | |
  50. // | NULL | NULL | unused or unavailable |
  51. // | | | |
  52. // | NULL | !NULL | LBI created with AddItem |
  53. // | | | |
  54. // | !NULL | NULL | needs LBI (no QueryItem yet) |
  55. // | | | |
  56. // | !NULL | !NULL | LBI created during QueryItem |
  57. // | | | |
  58. // +-------+-------+------------------------------+
  59. //
  60. // The array elements actually consist of ULC_ENTRY_BASE structures
  61. // plus _cbExtraBytes of extra space.
  62. //
  63. typedef struct _ULC_ENTRY
  64. {
  65. DOMAIN_DISPLAY_USER * pddu;
  66. LBI * plbi;
  67. BYTE bExtraBytes;
  68. } ULC_ENTRY;
  69. typedef struct _ULC_ENTRY_BASE
  70. {
  71. DOMAIN_DISPLAY_USER * pddu;
  72. LBI * plbi;
  73. } ULC_ENTRY_BASE;
  74. //
  75. // This is the "type" of the compare method required by qsort().
  76. //
  77. typedef int (__cdecl * PQSORT_COMPARE)( const void * p0, const void * p1 );
  78. /*************************************************************************
  79. NAME: ULC_API_BUFFER
  80. SYNOPSIS: ULC_API_BUFFER is used to keep track of the buffers
  81. allocated by the the SamQueryDisplayInformation
  82. API. An SLIST of these nodes is maintained by
  83. USER_LBI_CACHE.
  84. INTERFACE: ULC_API_BUFFER - Class constructor.
  85. ~ULC_API_BUFFER - Class destructor.
  86. QueryItemCount - Returns the number of items
  87. stored in the buffer associated
  88. with this node.
  89. QueryBufferPtr - Returns the buffer pointer
  90. associated with this node.
  91. HISTORY:
  92. KeithMo 15-Dec-1992 Created.
  93. **************************************************************************/
  94. DLL_CLASS ULC_API_BUFFER
  95. {
  96. private:
  97. //
  98. // Pointer to the actual buffer.
  99. //
  100. DOMAIN_DISPLAY_USER * _pddu;
  101. //
  102. // The number of items in this buffer.
  103. //
  104. ULONG _cItems;
  105. public:
  106. //
  107. // Usual constructor/destructor goodies.
  108. //
  109. ULC_API_BUFFER( DOMAIN_DISPLAY_USER * pddu,
  110. ULONG cItems );
  111. ~ULC_API_BUFFER( VOID );
  112. //
  113. // Public accessors.
  114. //
  115. ULONG QueryCount( VOID ) const
  116. { return _cItems; }
  117. DOMAIN_DISPLAY_USER * QueryBuffer( VOID ) const
  118. { return _pddu; }
  119. }; // class ULC_API_BUFFER
  120. DECL_SLIST_OF( ULC_API_BUFFER, DLL_BASED );
  121. /*************************************************************************
  122. NAME: USER_LBI_CACHE
  123. SYNOPSIS: This abstract class implements the guts of an LBI
  124. cache used to manipulate very large user databases.
  125. INTERFACE: USER_LBI_CACHE - Class constructor.
  126. ~USER_LBI_CACHE - Class destructor.
  127. ReadUsers - Read user accounts from a server
  128. into the cache. pfQuitEnum
  129. optionally points to a location
  130. where another thread may request
  131. that enumeration stop.
  132. AddItem - Add an item to the cache
  133. RemoveItem - Remove an item from the cache
  134. w/o deleting the corresponding
  135. LBI. Strangely, this may call
  136. through to CreateLBI to create
  137. a new LBI.
  138. QueryItem - Query a cache item. This may
  139. call through to the CreateLBI
  140. virtual to create a new LBI.
  141. Therefore, it may fail.
  142. QueryCount - Returns the number of entries
  143. in the cache.
  144. IsItemAvailable - Returns TRUE if the given item
  145. is available in the cache. Note
  146. that this does *not* mean that
  147. an associated LBI has been
  148. created, only that the necessary
  149. data is available.
  150. Sort - Sort the cache items. Note that
  151. an initial sort is performed at
  152. object construction.
  153. PARENT: BASE
  154. HISTORY:
  155. KeithMo 15-Dec-1992 Created.
  156. **************************************************************************/
  157. DLL_CLASS USER_LBI_CACHE : public BASE
  158. {
  159. private:
  160. //
  161. // Our cache.
  162. //
  163. VOID * _pCache;
  164. //
  165. // A list of buffers as returned by SamQueryDisplayInformation.
  166. //
  167. SLIST_OF( ULC_API_BUFFER ) _slBuffers;
  168. //
  169. // The number of "slots" in the cache. These slots
  170. // are not necessarily in use. See _cEntries;
  171. //
  172. INT _cSlots;
  173. //
  174. // The number of entries in the cache. Note that the
  175. // cache may "grow" (the array will be resized) as new
  176. // entries are added. _cEntries is always <= _cSlots.
  177. //
  178. INT _cEntries;
  179. //
  180. // Number of extra bytes at the end of each ULC_ENTRY. Note that
  181. // this is rounded up from the construction parameter to the
  182. // next multiple of sizeof(DWORD).
  183. //
  184. INT _cbExtraBytes;
  185. //
  186. // This worker method is responsible for "lazy LBI" creation.
  187. // It is invoked by QueryItem & RemoveItem to ensure that a
  188. // particular cache entry contains a valid LBI.
  189. //
  190. LBI * W_GetLBI( INT i );
  191. //
  192. // This worker method is responsible for growing the
  193. // cache array as needed.
  194. //
  195. BOOL W_GrowCache( INT cTotalCacheEntries );
  196. protected:
  197. //
  198. // This callback is invoked during QueryItem() cache misses.
  199. //
  200. virtual LBI * CreateLBI( const DOMAIN_DISPLAY_USER * pddu ) = 0;
  201. //
  202. // These callbacks are invoked during the binary search
  203. // invoked while processing AddItem.
  204. //
  205. virtual INT Compare( const LBI * plbi,
  206. const DOMAIN_DISPLAY_USER * pddu ) const = 0;
  207. virtual INT Compare( const LBI * plbi0,
  208. const LBI * plbi1 ) const = 0;
  209. //
  210. // This virtual callback returns the appropriate compare
  211. // method to be used by qsort() while sorting the cache entries.
  212. // The default compare method is USER_LBI_CACHE::CompareLogonNames().
  213. //
  214. virtual PQSORT_COMPARE QueryCompareMethod( VOID ) const;
  215. //
  216. // These virtual callbacks are invoked to lock & unlock
  217. // the cache. These may be redefined by a subclass to
  218. // provide multithread safety. The default implementation
  219. // is a NOP for each callback.
  220. //
  221. virtual VOID LockCache( VOID );
  222. virtual VOID UnlockCache( VOID );
  223. //
  224. // This static method will do a case insensitive compare
  225. // of two UNICODE_STRINGs. Might be useful for derived
  226. // subclasses.
  227. //
  228. static int CmpUniStrs( const UNICODE_STRING * punicode0,
  229. const UNICODE_STRING * punicode1 );
  230. //
  231. // This is the default compare routine to be used by
  232. // qsort() while sorting the cache entries.
  233. //
  234. static int __cdecl CompareLogonNames( const void * p0,
  235. const void * p1 );
  236. inline INT QueryULCEntrySize( VOID )
  237. { return sizeof(ULC_ENTRY_BASE) + _cbExtraBytes; }
  238. inline ULC_ENTRY * QueryULCEntryPtr( INT i )
  239. {
  240. ASSERT( i >= 0 && i < _cSlots && _pCache != NULL );
  241. return (ULC_ENTRY *) ( ((BYTE *)_pCache) + ( i * QueryULCEntrySize() ) );
  242. }
  243. public:
  244. //
  245. // Usual constructor/destructor goodies.
  246. //
  247. // Note that padminauth must be NULL for downlevel machines.
  248. //
  249. USER_LBI_CACHE( INT cbExtraBytes = 0 );
  250. virtual ~USER_LBI_CACHE( VOID );
  251. //
  252. // Read the API data & initialize the cache. New items are appended
  253. // to the end of the cache, and are not in sorted order.
  254. //
  255. APIERR ReadUsers( ADMIN_AUTHORITY * padminauth,
  256. UINT nInitialGrowthSpace = ULC_INITIAL_GROWTH_DEFAULT,
  257. UINT cUsersPerRequest = ULC_REQUEST_COUNT_DEFAULT,
  258. BOOL fIncludeRemoteUsers = ULC_REMOTE_USERS_DEFAULT,
  259. BOOL * pfQuitEnum = NULL );
  260. //
  261. // Add a new LBI to the cache. Will return the index of
  262. // the newly added item if successful, ULC_ERR otherwise.
  263. //
  264. virtual INT AddItem( LBI * plbi );
  265. //
  266. // Remove the item at index i from the cache, but don't
  267. // delete the LBI. Will return a pointer to the LBI if
  268. // successful, NULL otherwise.
  269. //
  270. virtual LBI * RemoveItem( INT i );
  271. //
  272. // Query the item at index i in the cache. Will return
  273. // a pointer to the LBI if successful, NULL otherwise.
  274. //
  275. virtual LBI * QueryItem( INT i );
  276. //
  277. // Determines if the necessary data for a given item is
  278. // available.
  279. //
  280. virtual BOOL IsItemAvailable( INT i );
  281. //
  282. // Returns the number of entries in the cache.
  283. //
  284. INT QueryCount( VOID ) const
  285. { return _cEntries; }
  286. //
  287. // Sort the cache entries.
  288. //
  289. VOID Sort( VOID );
  290. //
  291. // Perform a binary search on the cache, finding the
  292. // appropriate index for the new LBI (or a potential LBI for the
  293. // provided DOMAIN_DISPLAY_USER).
  294. //
  295. INT BinarySearch( LBI * plbiNew );
  296. INT BinarySearch( DOMAIN_DISPLAY_USER * pddu );
  297. }; // class USER_LBI_CACHE
  298. #endif // _USRCACHE_HXX_