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.

533 lines
18 KiB

  1. /*****************************************************************/
  2. /** Microsoft LAN Manager **/
  3. /** Copyright(c) Microsoft Corp., 1991 **/
  4. /*****************************************************************/
  5. /*
  6. * History:
  7. * RustanL 03-Jan-1991 Wrote initial implementation in shell\util
  8. * RustanL 10-Jan-1991 Added iterators, simplified usage and
  9. * the adding of subclasses. Moved into
  10. * LMOBJ.
  11. * ChuckC 24-Mar-1991 Added VAlidateName()
  12. * gregj 23-May-1991 Added LOCATION support
  13. * rustanl 18-Jul-1991 Added ( const LOCATION & ) constructor
  14. * rustanl 19-Jul-1991 Inherit from BASE; Removed ValidateName
  15. * rustanl 20-Aug-1991 Changed QuerySize to QueryCount
  16. * rustanl 21-Aug-1991 Introduced the ENUM_CALLER class
  17. * KeithMo 07-Oct-1991 Win32 Conversion.
  18. * KeithMo 23-Oct-1991 Added forward references.
  19. *
  20. */
  21. /*
  22. * LM_ENUM system overview
  23. * -----------------------
  24. *
  25. * The LM_ENUM system consists of the LM_ENUM, LOC_LM_ENUM, LM_ENUM_ITER, and
  26. * ENUM_OBJ_BASE hierarchies.
  27. *
  28. * The LM_ENUM hierarchy offers a simple interface for calling the LAN Man
  29. * enumeration APIs.
  30. *
  31. * The LM_ENUM_ITER hierarchy work in conjunction with the LM_ENUM hierarchy
  32. * to return pointers to the different objects.
  33. *
  34. * LM_ENUM_ITER actually returns a pointer to a class derived from
  35. * ENUM_OBJ_BASE. Client applications then invoke QueryXxx() methods
  36. * from this returned object.
  37. *
  38. *
  39. * To subclass LM_ENUM or LOC_LM_ENUM, replace the constructor, destructor
  40. * (optionally) and CallAPI methods.
  41. *
  42. * To subclass LM_ENUM_ITER, use the DECLARE_LM_ENUM_ITER macro in the
  43. * header file, and DEFINE_LM_ENUM_ITER macro in your source file.
  44. *
  45. * To subclass ENUM_OBJ_BASE, replace the QueryBufferPtr() method with
  46. * one that casts the buffer pointer to a proper LanMan structure
  47. * pointer. Also, provide QueryXxx() methods which parallel the
  48. * corresponding LMOBJ object.
  49. *
  50. * See the other lmoe*.?xx files for code examples.
  51. *
  52. *
  53. * Here follows an example of the use a LM_ENUM subclass, say SERVER1_ENUM,
  54. * and its iterator.
  55. *
  56. * extern "C"
  57. * {
  58. * #include <server.h>
  59. * }
  60. * #include <lmoesrv.hxx>
  61. *
  62. * APIERR f( const TCHAR * pszServer )
  63. * {
  64. * SERVER1_ENUM se1( pszServer );
  65. *
  66. * APIERR err = se1.GetInfo();
  67. * if ( err != NERR_Success )
  68. * {
  69. * return err;
  70. * }
  71. *
  72. * SERVER1_ENUM_ITER sei1( se1 );
  73. * const SERVER1_ENUM_OBJ * psi1;
  74. *
  75. * while ( ( psi1 = sei1()) != NULL )
  76. * {
  77. * printf( "%s\t%s\n", psi1->QueryName(), psi1->QueryComment() );
  78. * }
  79. *
  80. * return NERR_Success;
  81. *
  82. * } // f
  83. *
  84. *
  85. */
  86. #ifndef _LMOENUM_HXX_
  87. #define _LMOENUM_HXX_
  88. #include "uibuffer.hxx"
  89. #include "lmoloc.hxx"
  90. //
  91. // Forward references.
  92. //
  93. DLL_CLASS ENUM_CALLER;
  94. DLL_CLASS LM_ENUM_ITER;
  95. DLL_CLASS LM_ENUM;
  96. DLL_CLASS ENUM_OBJ_BASE;
  97. /*************************************************************************
  98. NAME: ENUM_CALLER
  99. SYNOPSIS: Does the work of calling an enumeration API
  100. INTERFACE: ENUM_CALLER() - constructor (guaranteed to succeed;
  101. see source for more details)
  102. QueryCount() - returns the number of enumerated
  103. items
  104. W_GetInfo() - Does the work of calling the
  105. enumeration API until the buffer
  106. is large enough. (The purpose of
  107. this class.)
  108. CallAPI() - Virtual method which calls the
  109. enumeration API, using the given
  110. parameters.
  111. EC_QueryBufferPtr() - virtual returning a pointer to a
  112. buffer to be used for the API
  113. call
  114. EC_SetBufferPtr() - virtual which sets the buffer
  115. pointer.
  116. PARENT:
  117. NOTES: This class is inherited from by LM_ENUM and ENUM_CALLER_LM_OBJ,
  118. both of which need the behavior of W_GetInfo. This way
  119. the two classes can share code.
  120. The virtual buffer methods all have the EC_ (for ENUM_CALLER)
  121. prefix so as to not conflict with those of the NEW_LM_OBJ
  122. class.
  123. CODEWORK. CallAPI could be renamed I_CallAPI
  124. CODEWORK. QueryCount should return a UINT
  125. HISTORY:
  126. rustanl 21-Aug-1991 Created from LM_ENUM
  127. KeithMo 07-Oct-1991 Changed all USHORT to UINT.
  128. **************************************************************************/
  129. DLL_CLASS ENUM_CALLER
  130. {
  131. private:
  132. UINT _cEntriesRead;
  133. virtual BYTE * EC_QueryBufferPtr() const = 0;
  134. virtual APIERR EC_SetBufferPtr( BYTE * pBuffer ) = 0;
  135. protected:
  136. APIERR W_GetInfo();
  137. virtual APIERR CallAPI( BYTE ** ppBuffer,
  138. UINT * pcEntriesRead ) = 0;
  139. // This method should be used with caution: the calling
  140. // subclass is responsible for updating the buffer if this
  141. // method is called.
  142. VOID SetCount( UINT c )
  143. { _cEntriesRead = c; }
  144. public:
  145. ENUM_CALLER();
  146. UINT QueryCount( VOID ) const
  147. { return _cEntriesRead; }
  148. }; // class ENUM_CALLER
  149. /*************************************************************************
  150. NAME: LM_ENUM
  151. SYNOPSIS: Abstract base for designing enumeration classes.
  152. INTERFACE: LM_ENUM - Class constructor.
  153. ~LM_ENUM - Class destructor.
  154. QueryServer - Query server name.
  155. QueryInfoLevel - Query infomation level.
  156. GetInfo - get information.
  157. PARENT: BASE
  158. ENUM_CALLER
  159. USES: LOCATION
  160. BUFFER
  161. HISTORY:
  162. RustanL 03-Jan-1991 Wrote initial implementation in shell\util
  163. RustanL 10-Jan-1991 Added iterators, simplified usage and
  164. the adding of subclasses. Moved into
  165. LMOBJ.
  166. gregj 23-May-1991 Added LOCATION support.
  167. rustanl 18-Jul-1991 Added ( const LOCATION & ) constructor
  168. rustanl 21-Aug-1991 Inherit from ENUM_CALLER
  169. KeithMo 07-Oct-1991 Changed all USHORT to UINT, fixed
  170. comment block.
  171. Thomaspa 21-Feb-1992 Moved LOCATION support to LOC_LM_ENUM
  172. **************************************************************************/
  173. DLL_CLASS LM_ENUM : public BASE, public ENUM_CALLER
  174. {
  175. friend class LM_ENUM_ITER;
  176. private:
  177. UINT _uLevel;
  178. BYTE * _pBuffer;
  179. UINT _cIterRef;
  180. // This method calls the LAN Man API. The server name and info level
  181. // can be retrieved through the QueryServer and QueryInfoLevel methods.
  182. virtual APIERR CallAPI( BYTE ** ppBuffer,
  183. UINT * pcEntriesRead ) = 0;
  184. // This following two methods are private, and are intended to be
  185. // called by the LM_ENUM_ITER friend class.
  186. //
  187. // Register an iterator "binding" to this enumerator.
  188. //
  189. VOID _RegisterIter( VOID );
  190. VOID RegisterIter( VOID )
  191. #ifdef DEBUG
  192. { _RegisterIter() ; }
  193. #else
  194. {}
  195. #endif
  196. //
  197. // Deregister an iterator "unbinding" from this enumerator.
  198. //
  199. VOID _DeregisterIter( VOID );
  200. VOID DeregisterIter( VOID )
  201. #ifdef DEBUG
  202. { _DeregisterIter() ; }
  203. #else
  204. {}
  205. #endif
  206. // Replacements for virtuals in ENUM_CALLER class
  207. virtual BYTE * EC_QueryBufferPtr() const;
  208. virtual APIERR EC_SetBufferPtr( BYTE * pBuffer );
  209. protected:
  210. LM_ENUM( UINT uLevel );
  211. // Returns pointer to buffer, or NULL on error or if there are no entires.
  212. BYTE * QueryPtr( VOID ) const
  213. { return _pBuffer; }
  214. public:
  215. ~LM_ENUM();
  216. UINT QueryInfoLevel( VOID ) const
  217. { return _uLevel; }
  218. APIERR GetInfo( VOID );
  219. }; // class LM_ENUM
  220. /*************************************************************************
  221. NAME: LOC_LM_ENUM
  222. SYNOPSIS: LM_ENUM with LOCATION object
  223. INTERFACE: LOC_LM_ENUM - Class constructor.
  224. ~LOC_LM_ENUM - Class destructor.
  225. QueryServer - Query server name.
  226. PARENT: LM_ENUM
  227. USES: LOCATION
  228. HISTORY:
  229. thomaspa 21-Feb-1992 Split off from LM_ENUM
  230. **************************************************************************/
  231. DLL_CLASS LOC_LM_ENUM : public LM_ENUM
  232. {
  233. private:
  234. LOCATION _loc;
  235. virtual APIERR CallAPI( BYTE ** ppBuffer,
  236. UINT * pcEntriesRead ) = 0;
  237. protected:
  238. LOC_LM_ENUM( const TCHAR * pszServer, UINT uLevel );
  239. LOC_LM_ENUM( LOCATION_TYPE locType, UINT uLevel );
  240. LOC_LM_ENUM( const LOCATION & loc, UINT uLevel );
  241. public:
  242. ~LOC_LM_ENUM();
  243. const TCHAR * QueryServer( VOID ) const;
  244. }; // class LOC_LM_ENUM
  245. /*************************************************************************
  246. NAME: LM_ENUM_ITER
  247. SYNOPSIS: Abstract base for designing iterator classes which
  248. interface with classes derived from the LM_ENUM
  249. enumerator class.
  250. INTERFACE: LM_ENUM_ITER - Class constructor, takes a
  251. reference to an LM_ENUM.
  252. ~LM_ENUM_ITER - Class destructor.
  253. QueryBasePtr - Returns a pointer to the
  254. LM_ENUM's enumeration buffer.
  255. QueryCount - Returns the number of items
  256. in the LM_ENUM's enumeration
  257. buffer.
  258. USES: LM_ENUM
  259. HISTORY:
  260. RustanL 03-Jan-1991 Wrote initial implementation in shell\util
  261. RustanL 10-Jan-1991 Added iterators, simplified usage and
  262. the adding of subclasses. Moved into
  263. LMOBJ.
  264. KeithMo 07-Oct-1991 Changed all USHORT to UINT, fixed
  265. comment block.
  266. **************************************************************************/
  267. DLL_CLASS LM_ENUM_ITER
  268. {
  269. private:
  270. UINT _cItems;
  271. LM_ENUM * _plmenum;
  272. protected:
  273. LM_ENUM_ITER( LM_ENUM & lmenum );
  274. ~LM_ENUM_ITER();
  275. BYTE * QueryBasePtr() const
  276. { return _plmenum->QueryPtr(); }
  277. UINT QueryCount( VOID ) const
  278. { return _cItems; }
  279. }; // class LM_ENUM_ITER
  280. /*************************************************************************
  281. NAME: ENUM_OBJ_BASE
  282. SYNOPSIS: Abstract class from which classes returned by LM_ENUM_ITER
  283. are derived from.
  284. INTERFACE: ENUM_OBJ_BASE - Class constructor.
  285. ~ENUM_OBJ_BASE - Class destructor.
  286. SetBufferPtr - Sets this object's buffer pointer.
  287. QueryBufferPtr - Returns this object's buffer
  288. pointer.
  289. PARENT: BASE
  290. HISTORY:
  291. KeithMo 07-Oct-1991 Created.
  292. **************************************************************************/
  293. DLL_CLASS ENUM_OBJ_BASE : public BASE
  294. {
  295. //
  296. // We declare the LM_ENUM_ITER class to be a friend so that it
  297. // (and classes derived from it) can invoke the Query/SetBufferPtr()
  298. // methods.
  299. //
  300. friend class LM_ENUM_ITER;
  301. private:
  302. //
  303. // This is the pointer to this object's buffer. Note that this
  304. // class does not do any actual buffer manipulation. This class
  305. // is designed to receive its buffer from an LM_ENUM_ITER object
  306. // via the SetBufferPtr() method.
  307. //
  308. const BYTE * _pBuffer;
  309. protected:
  310. //
  311. // The constructor/destructor pair are protected, since ENUM_OBJ_BASE
  312. // will never be directly instantiated.
  313. //
  314. ENUM_OBJ_BASE( VOID )
  315. { SetBufferPtr( NULL ); }
  316. ~ENUM_OBJ_BASE( VOID )
  317. { SetBufferPtr( NULL ); }
  318. //
  319. // Query/Set the buffer pointer.
  320. //
  321. const BYTE * QueryBufferPtr( VOID ) const
  322. { return _pBuffer; }
  323. VOID SetBufferPtr( const BYTE * pBuffer )
  324. { _pBuffer = pBuffer; }
  325. }; // class ENUM_OBJ_BASE
  326. /*
  327. * define convenient macros for creating iterators,
  328. * for example:
  329. * DECLARE_LM_ENUM_ITER_OF( SERVER1, struct server_info_1 );
  330. * DEFINE_LM_ENUM_ITER_OF( SERVER1, struct server_info_1 );
  331. * first arg is LMOBJ class, second is a class which the
  332. * iterator returns pointers to.
  333. *
  334. * Backup returns TRUE if successful, FALSE otherwise. Backs up one in the
  335. * iteration (i.e., is the inverse of operator()).
  336. */
  337. #define DECLARE_LM_ENUM_ITER_OF( enum_name, type ) \
  338. \
  339. class enum_name##_ENUM_ITER : public LM_ENUM_ITER \
  340. { \
  341. private: \
  342. enum_name##_ENUM_OBJ _enumobj; \
  343. type * _p; \
  344. UINT _i; \
  345. \
  346. public: \
  347. enum_name##_ENUM_ITER( enum_name##_ENUM & e ); \
  348. \
  349. const enum_name##_ENUM_OBJ * operator()( VOID ); \
  350. BOOL Backup( VOID ); \
  351. \
  352. }; /* class enum_name##_ENUM_ITER */
  353. #define DEFINE_LM_ENUM_ITER_OF( enum_name, type ) \
  354. \
  355. enum_name##_ENUM_ITER::enum_name##_ENUM_ITER( enum_name##_ENUM & e ) \
  356. : LM_ENUM_ITER( e ), \
  357. _enumobj(), \
  358. _p( (type *)QueryBasePtr() ), \
  359. _i( 0 ) \
  360. { \
  361. ; \
  362. \
  363. } /* enum_name##_ENUM_ITER::enum_name##_ENUM_ITER */ \
  364. \
  365. \
  366. const enum_name##_ENUM_OBJ * enum_name##_ENUM_ITER::operator()( VOID ) \
  367. { \
  368. if ( _i < QueryCount()) \
  369. { \
  370. _i++; \
  371. _enumobj.SetBufferPtr( _p++ ); \
  372. return &_enumobj; \
  373. } \
  374. \
  375. return NULL; \
  376. \
  377. } /* enum_name##_ENUM_ITER::operator() */ \
  378. \
  379. BOOL enum_name##_ENUM_ITER::Backup( VOID ) \
  380. { \
  381. BOOL fRet = FALSE ; \
  382. if ( _i > 0 ) \
  383. { \
  384. _i--; \
  385. _enumobj.SetBufferPtr( _p-- ); \
  386. fRet = TRUE ; \
  387. } \
  388. \
  389. return fRet ; \
  390. \
  391. } /* enum_name##_ENUM_ITER::Backup() */
  392. #define DECLARE_ENUM_BUFFER_METHODS( type ) \
  393. const type * QueryBufferPtr( VOID ) const \
  394. { return (const type *)ENUM_OBJ_BASE :: QueryBufferPtr(); } \
  395. \
  396. VOID SetBufferPtr( const type * pBuffer ) \
  397. { ENUM_OBJ_BASE :: SetBufferPtr( (const BYTE *)pBuffer ); }
  398. #define DECLARE_ENUM_ACCESSOR( name, type, field ) \
  399. type name( VOID ) const \
  400. { return (type)(QueryBufferPtr()->field); }
  401. #endif // _LMOENUM_HXX_