/*****************************************************************/ /** Microsoft LAN Manager **/ /** Copyright(c) Microsoft Corp., 1991 **/ /*****************************************************************/ /* * History: * RustanL 03-Jan-1991 Wrote initial implementation in shell\util * RustanL 10-Jan-1991 Added iterators, simplified usage and * the adding of subclasses. Moved into * LMOBJ. * ChuckC 24-Mar-1991 Added VAlidateName() * gregj 23-May-1991 Added LOCATION support * rustanl 18-Jul-1991 Added ( const LOCATION & ) constructor * rustanl 19-Jul-1991 Inherit from BASE; Removed ValidateName * rustanl 20-Aug-1991 Changed QuerySize to QueryCount * rustanl 21-Aug-1991 Introduced the ENUM_CALLER class * KeithMo 07-Oct-1991 Win32 Conversion. * KeithMo 23-Oct-1991 Added forward references. * */ /* * LM_ENUM system overview * ----------------------- * * The LM_ENUM system consists of the LM_ENUM, LOC_LM_ENUM, LM_ENUM_ITER, and * ENUM_OBJ_BASE hierarchies. * * The LM_ENUM hierarchy offers a simple interface for calling the LAN Man * enumeration APIs. * * The LM_ENUM_ITER hierarchy work in conjunction with the LM_ENUM hierarchy * to return pointers to the different objects. * * LM_ENUM_ITER actually returns a pointer to a class derived from * ENUM_OBJ_BASE. Client applications then invoke QueryXxx() methods * from this returned object. * * * To subclass LM_ENUM or LOC_LM_ENUM, replace the constructor, destructor * (optionally) and CallAPI methods. * * To subclass LM_ENUM_ITER, use the DECLARE_LM_ENUM_ITER macro in the * header file, and DEFINE_LM_ENUM_ITER macro in your source file. * * To subclass ENUM_OBJ_BASE, replace the QueryBufferPtr() method with * one that casts the buffer pointer to a proper LanMan structure * pointer. Also, provide QueryXxx() methods which parallel the * corresponding LMOBJ object. * * See the other lmoe*.?xx files for code examples. * * * Here follows an example of the use a LM_ENUM subclass, say SERVER1_ENUM, * and its iterator. * * extern "C" * { * #include * } * #include * * APIERR f( const TCHAR * pszServer ) * { * SERVER1_ENUM se1( pszServer ); * * APIERR err = se1.GetInfo(); * if ( err != NERR_Success ) * { * return err; * } * * SERVER1_ENUM_ITER sei1( se1 ); * const SERVER1_ENUM_OBJ * psi1; * * while ( ( psi1 = sei1()) != NULL ) * { * printf( "%s\t%s\n", psi1->QueryName(), psi1->QueryComment() ); * } * * return NERR_Success; * * } // f * * */ #ifndef _LMOENUM_HXX_ #define _LMOENUM_HXX_ #include "uibuffer.hxx" #include "lmoloc.hxx" // // Forward references. // DLL_CLASS ENUM_CALLER; DLL_CLASS LM_ENUM_ITER; DLL_CLASS LM_ENUM; DLL_CLASS ENUM_OBJ_BASE; /************************************************************************* NAME: ENUM_CALLER SYNOPSIS: Does the work of calling an enumeration API INTERFACE: ENUM_CALLER() - constructor (guaranteed to succeed; see source for more details) QueryCount() - returns the number of enumerated items W_GetInfo() - Does the work of calling the enumeration API until the buffer is large enough. (The purpose of this class.) CallAPI() - Virtual method which calls the enumeration API, using the given parameters. EC_QueryBufferPtr() - virtual returning a pointer to a buffer to be used for the API call EC_SetBufferPtr() - virtual which sets the buffer pointer. PARENT: NOTES: This class is inherited from by LM_ENUM and ENUM_CALLER_LM_OBJ, both of which need the behavior of W_GetInfo. This way the two classes can share code. The virtual buffer methods all have the EC_ (for ENUM_CALLER) prefix so as to not conflict with those of the NEW_LM_OBJ class. CODEWORK. CallAPI could be renamed I_CallAPI CODEWORK. QueryCount should return a UINT HISTORY: rustanl 21-Aug-1991 Created from LM_ENUM KeithMo 07-Oct-1991 Changed all USHORT to UINT. **************************************************************************/ DLL_CLASS ENUM_CALLER { private: UINT _cEntriesRead; virtual BYTE * EC_QueryBufferPtr() const = 0; virtual APIERR EC_SetBufferPtr( BYTE * pBuffer ) = 0; protected: APIERR W_GetInfo(); virtual APIERR CallAPI( BYTE ** ppBuffer, UINT * pcEntriesRead ) = 0; // This method should be used with caution: the calling // subclass is responsible for updating the buffer if this // method is called. VOID SetCount( UINT c ) { _cEntriesRead = c; } public: ENUM_CALLER(); UINT QueryCount( VOID ) const { return _cEntriesRead; } }; // class ENUM_CALLER /************************************************************************* NAME: LM_ENUM SYNOPSIS: Abstract base for designing enumeration classes. INTERFACE: LM_ENUM - Class constructor. ~LM_ENUM - Class destructor. QueryServer - Query server name. QueryInfoLevel - Query infomation level. GetInfo - get information. PARENT: BASE ENUM_CALLER USES: LOCATION BUFFER HISTORY: RustanL 03-Jan-1991 Wrote initial implementation in shell\util RustanL 10-Jan-1991 Added iterators, simplified usage and the adding of subclasses. Moved into LMOBJ. gregj 23-May-1991 Added LOCATION support. rustanl 18-Jul-1991 Added ( const LOCATION & ) constructor rustanl 21-Aug-1991 Inherit from ENUM_CALLER KeithMo 07-Oct-1991 Changed all USHORT to UINT, fixed comment block. Thomaspa 21-Feb-1992 Moved LOCATION support to LOC_LM_ENUM **************************************************************************/ DLL_CLASS LM_ENUM : public BASE, public ENUM_CALLER { friend class LM_ENUM_ITER; private: UINT _uLevel; BYTE * _pBuffer; UINT _cIterRef; // This method calls the LAN Man API. The server name and info level // can be retrieved through the QueryServer and QueryInfoLevel methods. virtual APIERR CallAPI( BYTE ** ppBuffer, UINT * pcEntriesRead ) = 0; // This following two methods are private, and are intended to be // called by the LM_ENUM_ITER friend class. // // Register an iterator "binding" to this enumerator. // VOID _RegisterIter( VOID ); VOID RegisterIter( VOID ) #ifdef DEBUG { _RegisterIter() ; } #else {} #endif // // Deregister an iterator "unbinding" from this enumerator. // VOID _DeregisterIter( VOID ); VOID DeregisterIter( VOID ) #ifdef DEBUG { _DeregisterIter() ; } #else {} #endif // Replacements for virtuals in ENUM_CALLER class virtual BYTE * EC_QueryBufferPtr() const; virtual APIERR EC_SetBufferPtr( BYTE * pBuffer ); protected: LM_ENUM( UINT uLevel ); // Returns pointer to buffer, or NULL on error or if there are no entires. BYTE * QueryPtr( VOID ) const { return _pBuffer; } public: ~LM_ENUM(); UINT QueryInfoLevel( VOID ) const { return _uLevel; } APIERR GetInfo( VOID ); }; // class LM_ENUM /************************************************************************* NAME: LOC_LM_ENUM SYNOPSIS: LM_ENUM with LOCATION object INTERFACE: LOC_LM_ENUM - Class constructor. ~LOC_LM_ENUM - Class destructor. QueryServer - Query server name. PARENT: LM_ENUM USES: LOCATION HISTORY: thomaspa 21-Feb-1992 Split off from LM_ENUM **************************************************************************/ DLL_CLASS LOC_LM_ENUM : public LM_ENUM { private: LOCATION _loc; virtual APIERR CallAPI( BYTE ** ppBuffer, UINT * pcEntriesRead ) = 0; protected: LOC_LM_ENUM( const TCHAR * pszServer, UINT uLevel ); LOC_LM_ENUM( LOCATION_TYPE locType, UINT uLevel ); LOC_LM_ENUM( const LOCATION & loc, UINT uLevel ); public: ~LOC_LM_ENUM(); const TCHAR * QueryServer( VOID ) const; }; // class LOC_LM_ENUM /************************************************************************* NAME: LM_ENUM_ITER SYNOPSIS: Abstract base for designing iterator classes which interface with classes derived from the LM_ENUM enumerator class. INTERFACE: LM_ENUM_ITER - Class constructor, takes a reference to an LM_ENUM. ~LM_ENUM_ITER - Class destructor. QueryBasePtr - Returns a pointer to the LM_ENUM's enumeration buffer. QueryCount - Returns the number of items in the LM_ENUM's enumeration buffer. USES: LM_ENUM HISTORY: RustanL 03-Jan-1991 Wrote initial implementation in shell\util RustanL 10-Jan-1991 Added iterators, simplified usage and the adding of subclasses. Moved into LMOBJ. KeithMo 07-Oct-1991 Changed all USHORT to UINT, fixed comment block. **************************************************************************/ DLL_CLASS LM_ENUM_ITER { private: UINT _cItems; LM_ENUM * _plmenum; protected: LM_ENUM_ITER( LM_ENUM & lmenum ); ~LM_ENUM_ITER(); BYTE * QueryBasePtr() const { return _plmenum->QueryPtr(); } UINT QueryCount( VOID ) const { return _cItems; } }; // class LM_ENUM_ITER /************************************************************************* NAME: ENUM_OBJ_BASE SYNOPSIS: Abstract class from which classes returned by LM_ENUM_ITER are derived from. INTERFACE: ENUM_OBJ_BASE - Class constructor. ~ENUM_OBJ_BASE - Class destructor. SetBufferPtr - Sets this object's buffer pointer. QueryBufferPtr - Returns this object's buffer pointer. PARENT: BASE HISTORY: KeithMo 07-Oct-1991 Created. **************************************************************************/ DLL_CLASS ENUM_OBJ_BASE : public BASE { // // We declare the LM_ENUM_ITER class to be a friend so that it // (and classes derived from it) can invoke the Query/SetBufferPtr() // methods. // friend class LM_ENUM_ITER; private: // // This is the pointer to this object's buffer. Note that this // class does not do any actual buffer manipulation. This class // is designed to receive its buffer from an LM_ENUM_ITER object // via the SetBufferPtr() method. // const BYTE * _pBuffer; protected: // // The constructor/destructor pair are protected, since ENUM_OBJ_BASE // will never be directly instantiated. // ENUM_OBJ_BASE( VOID ) { SetBufferPtr( NULL ); } ~ENUM_OBJ_BASE( VOID ) { SetBufferPtr( NULL ); } // // Query/Set the buffer pointer. // const BYTE * QueryBufferPtr( VOID ) const { return _pBuffer; } VOID SetBufferPtr( const BYTE * pBuffer ) { _pBuffer = pBuffer; } }; // class ENUM_OBJ_BASE /* * define convenient macros for creating iterators, * for example: * DECLARE_LM_ENUM_ITER_OF( SERVER1, struct server_info_1 ); * DEFINE_LM_ENUM_ITER_OF( SERVER1, struct server_info_1 ); * first arg is LMOBJ class, second is a class which the * iterator returns pointers to. * * Backup returns TRUE if successful, FALSE otherwise. Backs up one in the * iteration (i.e., is the inverse of operator()). */ #define DECLARE_LM_ENUM_ITER_OF( enum_name, type ) \ \ class enum_name##_ENUM_ITER : public LM_ENUM_ITER \ { \ private: \ enum_name##_ENUM_OBJ _enumobj; \ type * _p; \ UINT _i; \ \ public: \ enum_name##_ENUM_ITER( enum_name##_ENUM & e ); \ \ const enum_name##_ENUM_OBJ * operator()( VOID ); \ BOOL Backup( VOID ); \ \ }; /* class enum_name##_ENUM_ITER */ #define DEFINE_LM_ENUM_ITER_OF( enum_name, type ) \ \ enum_name##_ENUM_ITER::enum_name##_ENUM_ITER( enum_name##_ENUM & e ) \ : LM_ENUM_ITER( e ), \ _enumobj(), \ _p( (type *)QueryBasePtr() ), \ _i( 0 ) \ { \ ; \ \ } /* enum_name##_ENUM_ITER::enum_name##_ENUM_ITER */ \ \ \ const enum_name##_ENUM_OBJ * enum_name##_ENUM_ITER::operator()( VOID ) \ { \ if ( _i < QueryCount()) \ { \ _i++; \ _enumobj.SetBufferPtr( _p++ ); \ return &_enumobj; \ } \ \ return NULL; \ \ } /* enum_name##_ENUM_ITER::operator() */ \ \ BOOL enum_name##_ENUM_ITER::Backup( VOID ) \ { \ BOOL fRet = FALSE ; \ if ( _i > 0 ) \ { \ _i--; \ _enumobj.SetBufferPtr( _p-- ); \ fRet = TRUE ; \ } \ \ return fRet ; \ \ } /* enum_name##_ENUM_ITER::Backup() */ #define DECLARE_ENUM_BUFFER_METHODS( type ) \ const type * QueryBufferPtr( VOID ) const \ { return (const type *)ENUM_OBJ_BASE :: QueryBufferPtr(); } \ \ VOID SetBufferPtr( const type * pBuffer ) \ { ENUM_OBJ_BASE :: SetBufferPtr( (const BYTE *)pBuffer ); } #define DECLARE_ENUM_ACCESSOR( name, type, field ) \ type name( VOID ) const \ { return (type)(QueryBufferPtr()->field); } #endif // _LMOENUM_HXX_