NT4/private/windows/mpr/mprbase.hxx
2020-09-30 17:12:29 +02:00

272 lines
8.5 KiB
C++

/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
mprbase.hxx
Abstract:
Contains class definitions for base classes that implement common code
for Multi-Provider Router operations, namely:
CMprOperation
CRoutedOperation
Author:
Anirudh Sahni (anirudhs) 11-Oct-1995
Environment:
User Mode -Win32
Revision History:
11-Oct-1995 AnirudhS
Created.
--*/
#ifndef _MPRBASE_HXX_
#define _MPRBASE_HXX_
//=======================
// MACROS
//=======================
// Macro used to access PROVIDER class member functions in a generic
// fashion without creating an array of functions
#define PROVIDERFUNC(x) ((FARPROC PROVIDER::*) (&PROVIDER::x))
// Macro for use in declaring subclasses of CRoutedOperation
#define DECLARE_CROUTED \
\
protected: \
\
DWORD ValidateRoutedParameters( \
LPCWSTR * ppProviderName, \
LPCWSTR * ppRemoteName \
); \
\
DWORD TestProvider( \
const PROVIDER *pProvider \
);
// "Debug-only parameter" macro
#if DBG == 1
#define DBGPARM(x) x,
#else
#define DBGPARM(x)
#endif
//=======================
// CONSTANTS
//=======================
// Number of recently used net paths for CPathCache to remember
#define PATH_CACHE_SIZE 4
// Possible algorithms for routing among providers
enum ROUTING_ALGORITHM
{
ROUTE_LAZY,
ROUTE_AGGRESSIVE
};
//+-------------------------------------------------------------------------
//
// Class: CMprOperation
//
// Purpose: An MPR operation is an API in which the MPR needs to be
// initialized, parameters need to be validated, operation-
// specific processing needs to be performed, and the result
// needs to be saved by SetLastError.
//
// CMprOperation::Perform provides this common outline.
// Each MPR API can be implemented by providing a derived class.
// The derived class must fill in the API-specific processing
// by supplying the ValidateParameters and GetResult methods.
//
// Interface: Constructor - API can only construct an instance of a derived
// class, passing it the API parameters.
// Perform - API calls this to make the operation happen.
// ValidateParameters - In this method, the derived class does
// any parameter validation that could cause an exception.
// GetResult - In this method, the derived class does operation-
// specific processing.
//
// History: 11-Oct-95 AnirudhS Created.
//
// Notes:
//
//--------------------------------------------------------------------------
class CMprOperation
{
public:
DWORD Perform();
#if DBG == 1
LPCSTR OpName()
{ return _OpName; }
#endif
protected:
#if DBG == 1
CMprOperation(LPCSTR OpName) :
_OpName(OpName)
{ }
#else
CMprOperation()
{ }
#endif
virtual DWORD ValidateParameters() = 0;
virtual DWORD GetResult() = 0;
#if DBG == 1
private:
LPCSTR _OpName; // API name to print in debug messages
#endif
};
//+-------------------------------------------------------------------------
//
// Class: CRoutedOperation
//
// Purpose: A Routed Operation is an MPR operation which needs to be
// routed to the provider responsible, usually by either
// calling a provider that is named by the API caller, or
// polling all the providers and determining the right one
// based on the errors returned.
// This is a common type of MPR operation, so this subclass of
// CMprOperation, CRoutedOperation, is defined to hold the
// common code. A derived class is required for each routed
// operation.
//
// Parameter validation for a routed operation usually includes
// validating the name of a specific NP that may have been
// passed in by the caller of the WNet API, so CRoutedOperation
// ::ValidateParameters does this.
// CRoutedOperation::GetResult provides the logic for polling
// the providers and picking the best error. This may still be
// overridden if it does not exactly meet a particular
// operation's needs.
//
// Derived classes need to provide the methods
// ValidateRoutedParameters and TestProvider.
//
// Interface:
//
// History: 11-Oct-95 AnirudhS Created.
//
// Notes:
//
//--------------------------------------------------------------------------
class CRoutedOperation : public CMprOperation
{
public:
// The important public method is the Perform method from CMprOperation
// CODEWORK: This should become private once all APIs use CRoutedOperation
static DWORD FindCallOrder(
const UNICODE_STRING *NameInfo,
LPPROVIDER ProviderArray[],
LPDWORD ProviderArrayCount,
DWORD InitClass
);
static void ConstructCache()
{ _PathCache.Construct(); }
static void DestroyCache()
{ _PathCache.Destroy(); }
protected:
CRoutedOperation(
DBGPARM(LPCSTR OpName)
FARPROC PROVIDER::* pProviderFunction = NULL,
ROUTING_ALGORITHM Routing = ROUTE_LAZY
) :
DBGPARM(CMprOperation(OpName))
_pProviderFunction (pProviderFunction),
_AggressiveRouting (Routing == ROUTE_AGGRESSIVE),
_pSpecifiedProvider(NULL),
_LastProvider (NULL)
{ }
//
// Helper functions for child classes
//
PROVIDER * LastProvider() const
{ return _LastProvider; }
//
// Implementations of CMprOperation functions
//
DWORD ValidateParameters();
DWORD GetResult();
//
// Virtual functions that child classes should supply
//
virtual DWORD ValidateRoutedParameters(
LPCWSTR *ppProviderName,
LPCWSTR *ppRemoteName
) = 0;
virtual DWORD TestProvider(
const PROVIDER * pProvider
) = 0;
private:
FARPROC PROVIDER::*
_pProviderFunction; // Required provider function, if any
BOOL _AggressiveRouting; // Whether to continue on "other" errors
PROVIDER * _pSpecifiedProvider; // Provider specified in API parameters
UNICODE_STRING _RemoteName; // Remote name specified in API parameters
PROVIDER * _LastProvider; // On a success return from GetResult,
// is the provider that responded
//
// Cache of providers for the last few net paths accessed through WNet APIs
//
class CPathCache
{
public:
void Construct();
void Destroy();
void AddEntry(const UNICODE_STRING * Path, LPPROVIDER Provider);
LPPROVIDER FindEntry(const UNICODE_STRING * Path);
private:
// The cache is a doubly linked list of UNICODE_STRINGs and LPPROVIDERs.
// The string buffers are allocated on the heap but the the list
// entries are allocated statically.
struct CacheEntry
{
LIST_ENTRY Links;
UNICODE_STRING Path;
LPPROVIDER Provider;
};
CRITICAL_SECTION _Lock;
CacheEntry _RecentPaths[PATH_CACHE_SIZE];
LIST_ENTRY _ListHead;
DWORD _NumFree; // _RecentPaths[0] thru [_NumFree-1] are unused
};
static CPathCache _PathCache;
};
#endif // _MPRBASE_HXX_