|
|
/*****************************************************************/ /** 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 <server.h> * } * #include <lmoesrv.hxx> * * 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_
|