windows-nt/Source/XPSP1/NT/base/fs/mup/rpselect.h
2020-09-26 16:20:57 +08:00

163 lines
7.1 KiB
C

//+----------------------------------------------------------------------------
//
// Copyright (C) 1992, Microsoft Corporation
//
// File: rpselect.h
//
// Contents: Function & Data Structure prototypes for replica selection.
//
// Classes:
//
// Functions: ReplFindFirstProvider - find first appropriate provider and
// initialize the select context.
// ReplFindNextProvider - get next provider from the list of
// providers based on an initialized select context.
// ReplSetActiveService - a courtesy routine to tell replica
// selection that a particular service "worked". Will
// cause this service to be the first one to be tried
// on subsequent calls to FindFirst.
// ReplIsRecoverableError - see if error code is something worth
// trying a replica for.
//
// Data Structures:
// REPL_SELECT_CONTEXT
//
// History: 02 Sep 92 MilanS created.
//
//-----------------------------------------------------------------------------
#ifndef _RPSELECT_
#define _RPSELECT_
//
// This structure is supposed to be opaque to the user of this module.
// It should only be used to create select contexts to be passed to
// FindFirstProvider and FindNextProvider.
//
typedef struct _REPL_SELECT_CONTEXT {
unsigned short Flags;
ULONG iFirstSvcIndex; // index of first svc
ULONG iSvcIndex; // index of the last svc
// returned to caller.
} REPL_SELECT_CONTEXT, *PREPL_SELECT_CONTEXT;
//
// Define flags for SelectContext structures.
//
#define REPL_UNINITIALIZED 0x0001
#define REPL_SVC_IS_LOCAL 0x0002
#define REPL_SVC_IS_REMOTE 0x0004
#define REPL_PRINCIPAL_SPECD 0x0008
#define REPL_NO_MORE_ENTRIES 0x0010
NTSTATUS
ReplFindFirstProvider(
IN PDFS_PKT_ENTRY pPktEntry, // for which a svc is needed
IN GUID *pidPrincipal, // look for this service
IN PUNICODE_STRING pustrPrincipal, // or look for this service
OUT PDFS_SERVICE *ppService, // return selected service
OUT PREPL_SELECT_CONTEXT pSelectContext, // Context to be initialized.
OUT BOOLEAN *pLastEntry // Last entry
);
NTSTATUS
ReplFindNextProvider(
IN PDFS_PKT_ENTRY pPktEntry, // for which another svc is
OUT PDFS_SERVICE *ppService, // needed.
IN OUT PREPL_SELECT_CONTEXT pSelectContext, // Context to use
OUT BOOLEAN *pLastEntry // Last entry
);
PPROVIDER_DEF
ReplLookupProvider(ULONG ProviderId);
//+----------------------------------------------------------------------------
//
// Function: ReplSetActiveService
//
// Synopsis: Sets the ActiveService pointer of a PKT Entry. This is an
// Optimization. People who later look for a service for this
// PKT Entry will be asked to look at the ActiveService first.
//
// Arguments: [pPktEntry] Pointer to PKT Entry.
// [SelectContext] Initialized Select Context returned by
// FindFirst or FindNext.
//
// Returns: Nothing
//
// Notes: For now, this is a #define. Later, when we support multi-
// threaded operation, we can change it to a function that tests
// whether the Pkt Entry has changed under it etc.
//
//-----------------------------------------------------------------------------
#define ReplSetActiveService(p,s) \
{ \
if ((s).Flags & REPL_SVC_IS_REMOTE ) { \
(p)->ActiveService = &(p)->Info.ServiceList[(s).iSvcIndex]; \
if ((p)->ActiveService->pMachEntry != NULL) { \
InterlockedIncrement( \
&(p)->ActiveService->pMachEntry->ConnectionCount); \
} \
} \
}
//+----------------------------------------------------------------------------
//
// Function: ReplIsRecoverableError
//
// Synopsis: True if the argument is an NTSTATUS error code for which it
// makes sense to try a replica if one is available.
//
// Arguments: [x] - The NTSTATUS error code to be tested.
//
// Returns: True / False
//
// Notes: For now, this is simply #defined to be a relatively big OR
// statement that tests for a bunch of specific error codes. If we
// need to test for more error codes, it might be worth organizing
// them into a hash table, which can then quickly be tested.
//
// My initial estimates are that a hash table with either a modulo
// or multiplication hash function will become cheaper at around
// 7-8 error codes, assuming clock cycle estimates of x86. A tree
// type organization becomes effective after 10 error codes. The
// problem with the latter is generating at compile time a
// static, balanced tree.
//
//-----------------------------------------------------------------------------
#define ReplIsRecoverableError(x) ( (x) == STATUS_IO_TIMEOUT || \
(x) == STATUS_REMOTE_NOT_LISTENING || \
(x) == STATUS_VIRTUAL_CIRCUIT_CLOSED || \
(x) == STATUS_BAD_NETWORK_PATH || \
(x) == STATUS_NETWORK_BUSY || \
(x) == STATUS_INVALID_NETWORK_RESPONSE || \
(x) == STATUS_UNEXPECTED_NETWORK_ERROR || \
(x) == STATUS_NETWORK_NAME_DELETED || \
(x) == STATUS_BAD_NETWORK_NAME || \
(x) == STATUS_REQUEST_NOT_ACCEPTED || \
(x) == STATUS_DISK_OPERATION_FAILED || \
(x) == STATUS_DEVICE_OFF_LINE || \
(x) == STATUS_NETWORK_UNREACHABLE || \
(x) == STATUS_INSUFFICIENT_RESOURCES || \
(x) == STATUS_SHARING_PAUSED || \
(x) == STATUS_DFS_UNAVAILABLE || \
(x) == STATUS_NO_SUCH_DEVICE || \
(x) == STATUS_NETLOGON_NOT_STARTED || \
(x) == STATUS_UNMAPPABLE_CHARACTER || \
(x) == STATUS_CONNECTION_DISCONNECTED || \
(x) == STATUS_USER_SESSION_DELETED || \
(x) == STATUS_NO_SUCH_LOGON_SESSION \
)
#endif