534 lines
18 KiB
C++
534 lines
18 KiB
C++
/*****************************************************************/
|
|
/** 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_
|