Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1128 lines
26 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1990 - 1999
//
// File: util.hxx
//
//--------------------------------------------------------------------------
/* --------------------------------------------------------------------
Internal Header File for RPC Runtime Library
-------------------------------------------------------------------- */
#ifndef __UTIL_HXX__
#define __UTIL_HXX__
#ifndef __SYSINC_H__
#error Needs sysinc.h
#endif
START_C_EXTERN
#ifndef ARGUMENT_PRESENT
#define ARGUMENT_PRESENT(Argument) (Argument != 0)
#endif // ARGUMENT_PRESENT
#ifdef NULL
#undef NULL
#endif
#define NULL (0)
#define Nil 0
#ifdef TRUE
#undef TRUE
#endif
#ifdef FALSE
#undef FALSE
#endif
#define _NOT_COVERED_ (0)
#define FALSE (0)
#define TRUE (1)
//
// Expose the external logging hook on all builds.
//
#define RPC_ENABLE_WMI_TRACE
#define RPC_ERROR_LOGGING
#ifdef DBG
//#define RPC_ENABLE_TEST_HOOKS
#ifndef RPC_LOGGING
#define RPC_LOGGING
#endif
#endif
unsigned long
SomeLongValue (
);
unsigned short
SomeShortValue (
);
unsigned short
AnotherShortValue (
);
unsigned char
SomeCharacterValue (
);
extern int
RpcpCheckHeap (
void
);
int
IsMgmtIfUuid(
UUID PAPI * Uuid
);
END_C_EXTERN
void
PerformGarbageCollection (
void
);
BOOL
GarbageCollectionNeeded (
IN BOOL fOneTimeCleanup,
IN unsigned long GarbageCollectInterval
);
RPC_STATUS CreateGarbageCollectionThread (
void
);
RPC_STATUS
EnableIdleConnectionCleanup (
void
);
RPC_STATUS
EnableIdleLrpcSContextsCleanup (
void
);
void
GetMaxRpcSizeAndThreadPoolParameters (
void
);
#ifdef RPC_DELAYED_INITIALIZATION
extern int RpcHasBeenInitialized;
extern RPC_STATUS
PerformRpcInitialization (
void
);
#define InitializeIfNecessary() \
if ( RpcHasBeenInitialized == 0 ) \
{ \
RPC_STATUS RpcStatus; \
\
RpcStatus = PerformRpcInitialization(); \
if ( RpcStatus != RPC_S_OK ) \
return(RpcStatus); \
}
#define AssertRpcInitialized() ASSERT( RpcHasBeenInitialized != 0 )
#else /* RPC_DELAYED_INITIALIZATION */
#define InitializeIfNecessary()
#define AssertRpcInitialized()
#define PerformRpcInitialization()
#endif /* RPC_DELAYED_INITIALIZATION */
RPC_CHAR *
DuplicateString (
IN const RPC_CHAR PAPI * String
);
PSID
DuplicateSID (
IN const PSID Sid
);
// trick the compiler into statically initializing SID with two SubAuthorities
typedef struct _RPC_SID2 {
UCHAR Revision;
UCHAR SubAuthorityCount;
SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
ULONG SubAuthority[2];
} RPC_SID2;
extern const SID LocalSystem;
extern const SID LocalService;
extern const SID NetworkService;
extern const RPC_SID2 Admin1;
RPC_STATUS
RpcpLookupAccountName (
IN RPC_CHAR *ServerPrincipalName,
IN OUT BOOL *fCache,
OUT PSID *Sid
);
RPC_STATUS
RpcpLookupAccountNameDirect (
IN RPC_CHAR *ServerPrincipalName,
OUT PSID *Sid
);
RPC_STATUS
RpcpLookupAccountSid (
IN PSID Sid,
OUT RPC_CHAR **ServerPrincipalName
);
#ifdef UNICODE
extern RPC_STATUS
AnsiToUnicodeString (
IN unsigned char * String,
OUT UNICODE_STRING * UnicodeString
);
extern unsigned char *
UnicodeToAnsiString (
IN RPC_CHAR * WideCharString,
OUT RPC_STATUS * RpcStatus
);
#endif // UNICODE
void
DestroyContextHandlesForGuard (
IN PVOID Context,
IN BOOL RundownContextHandle,
IN void *CtxGuard
);
// forward definition
class ContextCollection;
RPC_STATUS
NDRSContextInitializeCollection (
IN ContextCollection **ContextCollectionPlaceholder
);
#if DBG
void
RpcpInterfaceForCallDoesNotUseStrict (
IN RPC_BINDING_HANDLE BindingHandle
);
#endif
inline unsigned short
RpcpByteSwapShort (unsigned short Value)
{
return (RtlUshortByteSwap(Value));
}
inline unsigned long
RpcpByteSwapLong (unsigned long Value)
{
return (RtlUlongByteSwap(Value));
}
typedef union tagFastCopyLUIDAccess
{
LUID Luid;
__int64 FastAccess;
} FastCopyLUIDAccess;
inline void FastCopyLUIDAligned (LUID *TargetLUID, const LUID *SourceLUID)
{
FastCopyLUIDAccess *EffectiveSourceLUID = (FastCopyLUIDAccess *)SourceLUID;
FastCopyLUIDAccess *EffectiveTargetLUID = (FastCopyLUIDAccess *)TargetLUID;
#if defined(_WIN64)
ASSERT((((ULONG_PTR)EffectiveSourceLUID) % 8) == 0);
ASSERT((((ULONG_PTR)EffectiveTargetLUID) % 8) == 0);
#endif
EffectiveTargetLUID->FastAccess = EffectiveSourceLUID->FastAccess;
}
inline void FastCopyLUID (LUID *TargetLUID, LUID *SourceLUID)
{
FastCopyLUIDAccess *EffectiveSourceLUID = (FastCopyLUIDAccess *)SourceLUID;
FastCopyLUIDAccess *EffectiveTargetLUID = (FastCopyLUIDAccess *)TargetLUID;
#if !defined(_WIN64)
FastCopyLUIDAligned(TargetLUID, SourceLUID);
#else
TargetLUID->HighPart = SourceLUID->HighPart;
TargetLUID->LowPart = SourceLUID->LowPart;
#endif
}
// returns non-zero if equal
inline BOOL FastCompareLUIDAligned (const LUID *TargetLUID, const LUID *SourceLUID)
{
FastCopyLUIDAccess *EffectiveSourceLUID = (FastCopyLUIDAccess *)SourceLUID;
FastCopyLUIDAccess *EffectiveTargetLUID = (FastCopyLUIDAccess *)TargetLUID;
#if defined(_WIN64)
ASSERT((((ULONG_PTR)EffectiveSourceLUID) % 8) == 0);
ASSERT((((ULONG_PTR)EffectiveTargetLUID) % 8) == 0);
#endif
return (EffectiveTargetLUID->FastAccess == EffectiveSourceLUID->FastAccess);
}
inline BOOL FastCompareLUID (LUID *TargetLUID, LUID *SourceLUID)
{
FastCopyLUIDAccess *EffectiveSourceLUID = (FastCopyLUIDAccess *)SourceLUID;
FastCopyLUIDAccess *EffectiveTargetLUID = (FastCopyLUIDAccess *)TargetLUID;
#if !defined(_WIN64)
return FastCompareLUIDAligned(TargetLUID, SourceLUID);
#else
return ((TargetLUID->HighPart == SourceLUID->HighPart)
&& (TargetLUID->LowPart == SourceLUID->LowPart));
#endif
}
// zeroes out everything b/n the two fields, including the first field,
// but excluding the second
#define RPCP_ZERO_OUT_STRUCT_RANGE(Type, Instance, Field1, Field2) \
RpcpMemorySet(((char *)(Instance)) + FIELD_OFFSET(Type, Field1), 0, FIELD_OFFSET(Type, Field2) - FIELD_OFFSET(Type, Field1))
// zeroes out everything from a field to the end including the field
#define RPCP_ZERO_OUT_STRUCT_TAIL(Type, Instance, Field) \
RpcpMemorySet(((char *)(Instance)) + FIELD_OFFSET(Type, Field), 0, sizeof(Type) - FIELD_OFFSET(Type, Field))
PUNICODE_STRING
FastGetImageBaseNameUnicodeString (
void
);
const RPC_CHAR *
FastGetImageBaseName (
void
);
//
// System features - constant after InitializeIfNecessary.
//
// Just contants on non-NT systems
//
extern DWORD gPageSize;
extern DWORD gThreadTimeout;
extern UINT gNumberOfProcessors;
extern DWORD gMaxRpcSize;
extern DWORD gProrateStart;
extern DWORD gProrateMax;
extern DWORD gProrateFactor;
extern BOOL gfServerPlatform;
extern ULONGLONG gPhysicalMemorySize; // in megabytes
extern DWORD gProcessStartTime;
// The local machine's name.
extern RPC_CHAR *gLocalComputerName;
// The length of the name in TCHAR's including the terminating NULL.
extern DWORD gLocalComputerNameLength;
//
// RPC Verifier settings
//
extern BOOL gfAppVerifierEnabled;
extern BOOL gfRPCVerifierEnabled;
// Corruption patterns:
// ZeroOut - memory is zeroed-out
// Negate - 0xff pattern is written
// BitFlip - a random bit is flipped
// IncDec - a byte is incremented or decremented
// Randomize - a random byte is written
// One of the above patterns is used at random
enum tCorruptionPattern {ZeroOut, Negate, BitFlip, IncDec, Randomize, AllPatterns=100};
// When choosing a random corruption pattern to apply, we will pick one from this range.
#define MIN_CORRUPTION_PATTERN_ID (0)
#define MAX_CORRUPTION_PATTERN_ID (4)
// Corruption can be of a fixed or random size.
enum tCorruptionSizeType {FixedSize, RandomSize};
// Corruption may be spacially localized or randomized.
// When it is localized, a sub-sequence of the buffer will be corrupted.
// When it is randomized, random elements of the buffer will be corrupted.
enum tCorruptionDistributionType {LocalizedDistribution, RandomizedDistribution};
//
// All of the RPC verifier settings are contained in a single
// structure. We will allocate and initialize it iff
// the RPC verifier is enabled.
//
typedef struct _tRpcVerifierSettings
{
// Fault injecting ImpersonateClient calls
BOOL fFaultInjectImpersonateClient;
// Proabilities are integers 1-10000. 10000 is p=1.
unsigned int ProbFaultInjectImpersonateClient;
// Delay in seconds before the start of fault injection.
unsigned int DelayFaultInjectImpersonateClient;
// Corruption injecting the data
BOOL fCorruptionInjectServerReceives;
BOOL fCorruptionInjectClientReceives;
// Proabilities of corruption are integers 1-10000. 10000 is p=1.
unsigned int ProbRpcHeaderCorruption;
unsigned int ProbDataCorruption;
unsigned int ProbSecureDataCorruption;
tCorruptionPattern CorruptionPattern;
tCorruptionSizeType CorruptionSizeType;
// For Fixed size - set the size of the corruption in bytes
// For Random size - set the maximum size of the corruption.
// Actual size may be between 1 and gCorruptionSize
unsigned int CorruptionSize;
tCorruptionDistributionType CorruptionDistributionType;
unsigned int ProbBufferTruncation;
unsigned int MaxBufferTruncationSize;
// Fault injecting transport failures.
BOOL fFaultInjectTransports;
unsigned int ProbFaultInjectTransports;
// Injecting pauses into calls to external APIs
BOOL fPauseInjectExternalAPIs;
unsigned int ProbPauseInjectExternalAPIs;
unsigned int PauseInjectExternalAPIsMaxWait;
// Initialized to True if the process is running under a high-priv account.
// This is used to detect if privileges are being leaked.
BOOL IsHighPrivilege;
// Optionally supressing app verifier breaks on bad RPC practictices.
BOOL fSupressAppVerifierBreaks;
// Causes RPC to switch to the allocation off a read-only paged heap.
// Each allocation off the heap is guarded by a read-only page. This
// catches AV's but still allows NDR to walk of the end of buffers a little.
BOOL fReadonlyPagedHeap;
} tRpcVerifierSettings;
extern tRpcVerifierSettings *pRpcVerifierSettings;
//
// Macros for some common conditions and states.
//
extern BOOL gfRpcVerifierCorruptionExpected;
#define gfRpcVerifierCorruptionInjectClientReceives \
( \
gfRPCVerifierEnabled && \
pRpcVerifierSettings->fCorruptionInjectClientReceives \
)
#define gfRpcVerifierCorruptionInjectServerReceives \
( \
gfRPCVerifierEnabled && \
pRpcVerifierSettings->fCorruptionInjectServerReceives \
)
#define gfRpcVerifierSupressAppVerifierBreaks (pRpcVerifierSettings->fSupressAppVerifierBreaks)
#define gfRPCVerifierEnabledWithBreaks (gfRPCVerifierEnabled && !gfRpcVerifierSupressAppVerifierBreaks)
// When defined, this macro builds a private with corruption injection for lrpc.
//#define RPC_LRPC_CORRUPTION
//
// RPC Verifier utility functions
//
// Generates a boolean with P(True)=Prob/10000.
inline BOOL
RndBool(
unsigned int Prob
);
// The buffer types passed to the corruption injection routine.
enum tBufferType {ServerReceive, ClientReceive};
// Injects corruption into a buffer
extern void
CorruptionInject(
tBufferType BufferType,
unsigned int *pBufferLength,
void **pBuffer
);
extern void
PrintCurrentStackTrace(
unsigned int FramesToSkip,
unsigned int Size
);
extern void
PrintUUID(
GUID *guid
);
#define RPC_VERIFIER_PRINT_OFFENDING_STACK(FramesToSkip, FramesToPrint) \
DbgPrint("RPC: Offending Stack:\n"); \
PrintCurrentStackTrace(FramesToSkip, FramesToPrint); \
DbgPrint("RPC: To determine the symbolic stack, do an \"ln\" on the above addresses in the context of the faulting process.\n\n")
//
// Macros used to print app verifier warnings.
//
#define RPC_VERIFIER_UNSECURE_IF_REMOTELY_ACCESSIBLE (0x10)
#define RPC_VERIFIER_DISABLING_SELECTIVE_BINDING (0x20)
#define RPC_VERIFIER_WEAK_SECURITY_FOR_REMOTE_CALL (0x30)
#define RPC_VERIFIER_UNSAFE_PROTOCOL (0x40)
#define RPC_VERIFIER_UNSAFE_FEATURE (0x50)
#define RPC_VERIFIER_NO_LOCAL_MUTUAL_AUTHENTICATION (0x60)
#define RPC_VERIFIER_REGISTERING_NONROBUST_IF (0x70)
#define RPC_VERIFIER_ARGUMENTS_IGNORED (0x80)
#define RPC_VERIFIER_PRIVILEGE_LEAK (0x90)
#define RPC_VERIFIER_WARNING_MSG(Msg, WarningType) \
VERIFIER_STOP(APPLICATION_VERIFIER_RPC_ERROR | APPLICATION_VERIFIER_NO_BREAK, \
Msg, WarningType, "RpcWarningType", 0, NULL, 0, NULL, 0, NULL); \
//
// RPC Verifier debuging macros
//
// Macro used to assert when corruption injection is not enabled.
// This allows us to run with corruption injection on checked builds without
// triggering the asserts that catch corruption.
#if DBG
#define CORRUPTION_ASSERT(cond) \
if (!gfRpcVerifierCorruptionExpected) \
{ \
ASSERT(cond); \
}
#else // DBG
#define CORRUPTION_ASSERT(cond) ((void) 0)
#endif // DBG
// Set when building a private with verifier
// debugging spew.
//#define VERIFIER_DBG
#ifdef VERIFIER_DBG
#define VERIFIER_DBG_PRINT_0(s) DbgPrint(s)
#define VERIFIER_DBG_PRINT_1(s, x1) DbgPrint(s, x1)
#define VERIFIER_DBG_PRINT_2(s, x1, x2) DbgPrint(s, x1, x2)
#define VERIFIER_DBG_PRINT_3(s, x1, x2, x3) DbgPrint(s, x1, x2, x3)
#else
#define VERIFIER_DBG_PRINT_0(x) ((void) 0)
#define VERIFIER_DBG_PRINT_1(s, x1) ((void) 0)
#define VERIFIER_DBG_PRINT_2(s, x1, x2) ((void) 0)
#define VERIFIER_DBG_PRINT_3(s, x1, x2, x3) ((void) 0)
#endif
//
// Per-interface security check exemptions.
//
// The flags for various security checks that may be disabled for an interface:
// Registering an interface that is remotely acessible without a security callback
// and without RPC_IF_ALLOW_SECURE_ONLY flag.
#define ALLOW_UNSECURE_REMOTE_ACCESS 0x00000001
// An interface may be called remotely by without RPC_C_AUTHN_LEVEL_PKT_PRIVACY
#define ALLOW_UNENCRYPTED_REMOTE_ACCESS 0x00000002
// An interface may be called remotely by without mutual authentication.
#define ALLOW_NO_MUTUAL_AUTH_REMOTE_ACCESS 0x00000004
#define ALLOW_EVERYTHING 0xffffffff
// Determines whether a security check is disabled for a given interface.
extern BOOL
IsInterfaceExempt (
IN GUID *IfUuid,
IN DWORD CheckFlag
);
//
// Detecting unsafe protseqs.
//
// Determines whether a given protseq is unsafe.
extern BOOL
IsProtseqUnsafe (
IN RPC_CHAR *ProtocolSequence
);
//
// Paged BCache settings
//
enum BCacheMode {
BCacheModeCached, // Allocations go through the cache.
BCacheModeDirect // Allocations go directly to the heap.
};
// set to one of the constants above
extern BCacheMode gBCacheMode;
// if non-zero, we may be in lsa. This is maybe, because
// conclusive check is too expensive, and the only
// way we use this flag is to avoid some optimizations
// that can result in deadlock in lsa.
extern BOOL fMaybeLsa;
//
// Security support functions
//
extern RPC_STATUS
IsCurrentUserAdmin(
void
);
//
// constants for LogEvent(),
//
#define SU_HANDLE 'h'
#define SU_CCONN 'n'
#define SU_SCONN 'N'
#define SU_CASSOC 'a'
#define SU_SASSOC 'A'
#define SU_CCALL 'c'
#define SU_SCALL 'C'
#define SU_PACKET 'p'
#define SU_CENDPOINT 'e'
#define SU_ENGINE 'E'
#define SU_ASSOC '.'
#define SU_MUTEX 'm'
#define SU_STABLE 'T'
#define SU_ADDRESS 'D'
#define SU_HEAP 'H'
#define SU_BCACHE 'b'
#define SU_REFOBJ 'r'
#define SU_THREAD 't'
#define SU_TRANS_CONN 'o'
#define SU_EVENT 'v'
#define SU_EXCEPT 'x'
#define SU_CTXHANDLE 'l'
#define SU_EEINFO 'I'
#define SU_GC 'G'
#define SU_IF 'i'
#define SU_SECCRED 'S'
#define SU_HTTPv2 '2'
#define SU_CORRUPT 'O'
#define EV_CREATE 'C'
#define EV_DELETE 'D'
#define EV_START 'c'
#define EV_STOP 'd'
#define EV_INC '+'
#define EV_DEC '-'
#define EV_PROC 'p'
#define EV_ACK 'a'
#define EV_CALLBACK 'L'
#define EV_NOTIFY 'N'
#define EV_APC 'A'
#define EV_STATUS 'S'
#define EV_DISASSOC 'x'
#define EV_STATE '='
#define EV_POP 'P'
#define EV_PUSH 'Q'
#define EV_PKT_IN 'k'
#define EV_PKT_OUT 'K'
#define EV_BUFFER_IN 'b'
#define EV_BUFFER_OUT 'B'
#define EV_BUFFER_FAIL 'X'
#define EV_ABORT 'R'
#define EV_SET 's'
// for debugging. A packet can be dropped or delayed.
//
#define EV_DROP '*'
#define EV_DELAY '#'
#define EV_PRUNE 'p'
// SU_SCONN: a call is being transferred to another connection during auto-reconnect.
//
#define EV_TRANSFER 'T'
// SU_CASSOC: the dynamic endpoint has been resolved into a real endpoint
//
#define EV_RESOLVED 'r'
// SU_ENGINE: window size and selective-ack bits from a FACK or NOCALL
//
#define EV_WINDOW 'w'
// SU_SCALL: the call was removed from the connection's active list
#define EV_REMOVED 'm'
// SU_SCALL: Cleanup() was called with refcount > 0
#define EV_CLEANUP ','
#define EV_BHCOPY 'O'
#define EV_ALLOCATE 't'
#define EV_OPER 'o'
//
//
#define EV_SEC_INIT1 'i'
#define EV_SEC_INIT3 'I'
#define EV_SEC_ACCEPT1 'j'
#define EV_SEC_ACCEPT3 'J'
#define IN_CHANNEL_STATE (UlongToPtr(0))
#define OUT_CHANNEL_STATE (UlongToPtr(1))
#define MAX_RPC_EVENT 4096
#define STACKTRACE_DEPTH 4
// The RPC event log and the size of the RPC event log.
// When the RPC verifier is enabled we will re-allocate the log and extend its size.
extern struct RPC_EVENT *RpcEvents;
extern long EventArrayLength;
struct RPC_EVENT
{
DWORD Thread;
DWORD Time;
unsigned char Subject;
unsigned char Verb;
void * SubjectPointer;
void * ObjectPointer;
ULONG_PTR Data;
void * EventStackTrace[STACKTRACE_DEPTH];
};
extern void
TrulyLogEvent(
IN unsigned char Subject,
IN unsigned char Verb,
IN void * SubjectPointer,
IN void * ObjectPointer = 0,
IN ULONG_PTR Data = 0,
IN BOOL fCaptureStackTrace = 0,
IN int AdditionalFramesToSkip = 0
);
#ifdef RPC_LOGGING
extern BOOL fEnableLog;
inline void
LogEvent(
IN unsigned char Subject,
IN unsigned char Verb,
IN void * SubjectPointer,
IN void * ObjectPointer = 0,
IN ULONG_PTR Data = 0,
IN BOOL fCaptureStackTrace = 0,
IN int AdditionalFramesToSkip = 0
)
{
if (fEnableLog)
{
TrulyLogEvent( Subject,
Verb,
SubjectPointer,
ObjectPointer,
Data,
fCaptureStackTrace,
AdditionalFramesToSkip
);
}
}
#else
inline void
LogEvent(
IN unsigned char Subject,
IN unsigned char Verb,
IN void * SubjectPointer,
IN void * ObjectPointer = 0,
IN ULONG_PTR Data = 0,
IN BOOL fCaptureStackTrace = 0,
IN int AdditionalFramesToSkip = 0
)
{
#if DBG
TrulyLogEvent(Subject, Verb, SubjectPointer, ObjectPointer, Data, fCaptureStackTrace,
AdditionalFramesToSkip);
#endif
}
#endif
//
// LogError will produce an event even on normal retail builds.
//
#ifdef RPC_ERROR_LOGGING
inline void
LogError(
IN unsigned char Subject,
IN unsigned char Verb,
IN void * SubjectPointer,
IN void * ObjectPointer = 0,
IN ULONG_PTR Data = 0,
IN BOOL fCaptureStackTrace = 0,
IN int AdditionalFramesToSkip = 0
)
{
TrulyLogEvent( Subject,
Verb,
SubjectPointer,
ObjectPointer,
Data,
fCaptureStackTrace,
AdditionalFramesToSkip
);
}
#else
inline void
LogError(
IN unsigned char Subject,
IN unsigned char Verb,
IN void * SubjectPointer,
IN void * ObjectPointer = 0,
IN ULONG_PTR Data = 0,
IN BOOL fCaptureStackTrace = 0,
IN int AdditionalFramesToSkip = 0
)
{
#if DBG
TrulyLogEvent(Subject, Verb, SubjectPointer, ObjectPointer, Data, fCaptureStackTrace,
AdditionalFramesToSkip);
#endif
}
#endif
#ifdef STATS
extern DWORD g_dwStat1;
extern DWORD g_dwStat2;
extern DWORD g_dwStat3;
extern DWORD g_dwStat4;
inline void GetStats(DWORD *pdwStat1, DWORD *pdwStat2, DWORD *pdwStat3, DWORD *pdwStat4)
{
*pdwStat1 = g_dwStat1;
*pdwStat2 = g_dwStat2;
*pdwStat3 = g_dwStat3;
*pdwStat4 = g_dwStat4;
}
inline void SetStat1(DWORD dwStat)
{
g_dwStat1 = dwStat;
}
inline void SetStat2(DWORD dwStat)
{
g_dwStat2 = dwStat;
}
inline void SetStat3(DWORD dwStat)
{
g_dwStat3 = dwStat;
}
inline void SetStat4(DWORD dwStat)
{
g_dwStat4 = dwStat;
}
inline void IncStat1(void)
{
InterlockedIncrement((long *) &g_dwStat1);
}
inline void DecStat1(void)
{
InterlockedDecrement((long *) &g_dwStat1);
}
inline void Stat1Add(long val)
{
InterlockedExchangeAdd((long *) &g_dwStat1, val);
}
inline void Stat1Sub(long val)
{
InterlockedExchangeAdd((long *) &g_dwStat1, -val);
}
inline void IncStat2(void)
{
InterlockedIncrement((long *) &g_dwStat2);
}
inline void DecStat2(void)
{
InterlockedDecrement((long *) &g_dwStat2);
}
inline void Stat2Add(long val)
{
InterlockedExchangeAdd((long *) &g_dwStat2, val);
}
inline void Stat2Sub(long val)
{
InterlockedExchangeAdd((long *) &g_dwStat2, -val);
}
inline void IncStat3(void)
{
InterlockedIncrement((long *) &g_dwStat3);
}
inline void DecStat3(void)
{
InterlockedDecrement((long *) &g_dwStat3);
}
inline void Stat3Add(long val)
{
InterlockedExchangeAdd((long *) &g_dwStat3, val);
}
inline void Stat3Sub(long val)
{
InterlockedExchangeAdd((long *) &g_dwStat3, -val);
}
inline void IncStat4(void)
{
InterlockedIncrement((long *) &g_dwStat4);
}
inline void DecStat4(void)
{
InterlockedDecrement((long *) &g_dwStat4);
}
inline void Stat4Add(long val)
{
InterlockedExchangeAdd((long *) &g_dwStat4, val);
}
inline void Stat4Sub(long val)
{
InterlockedExchangeAdd((long *) &g_dwStat4, -val);
}
#else
inline void GetStats(DWORD *pdwStat1, DWORD *pdwStat2, DWORD *pdwStat3, DWORD *pdwStat4)
{
}
inline void SetStat1(DWORD dwStat)
{
}
inline void SetStat2(DWORD dwStat)
{
}
inline void SetStat3(DWORD dwStat)
{
}
inline void SetStat4(DWORD dwStat)
{
}
inline void IncStat1(void)
{
}
inline void DecStat1(void)
{
}
inline void Stat1Add(long val)
{
}
inline void Stat1Sub(long val)
{
}
inline void IncStat2(void)
{
}
inline void DecStat2(void)
{
}
inline void Stat2Add(long val)
{
}
inline void Stat2Sub(long val)
{
}
inline void IncStat3(void)
{
}
inline void DecStat3(void)
{
}
inline void Stat3Add(long val)
{
}
inline void Stat3Sub(long val)
{
}
inline void IncStat4(void)
{
}
inline void DecStat4(void)
{
}
inline void Stat4Add(long val)
{
}
inline void Stat4Sub(long val)
{
}
#endif
//
// test hook data. The stuff that would logically live in UTIL.CXX is actually in DGCLNT.CXX
// due to trouble linking the BVT programs.
//
typedef unsigned long RPC_TEST_HOOK_ID;
typedef void (RPC_TEST_HOOK_FN_RAW)( RPC_TEST_HOOK_ID id, PVOID subject, PVOID object );
typedef RPC_TEST_HOOK_FN_RAW * RPC_TEST_HOOK_FN;
RPCRTAPI
DWORD
RPC_ENTRY
I_RpcSetTestHook(
RPC_TEST_HOOK_ID id,
RPC_TEST_HOOK_FN fn
);
void
ForceCallTestHook(
RPC_TEST_HOOK_ID id,
PVOID subject,
PVOID object
);
//
// ranges for the major field:
//
// common: 001-099
// dg: 100-199
// co: 200-299
// lrpc: 300-399
// transports: 400-499
// reserved: 500-32767
//
#define MAKE_TEST_HOOK_ID( major, minor ) ( ((major) << 16) | (minor) )
#define TH_RPC_BASE 1
#define TH_DG_BASE 100
#define TH_CO_BASE 200
#define TH_LRPC_BASE 300
#define TH_TRANS_BASE 400
//
// protocol-independent hook IDs.
//
// member functions of SECURITY_CONTEXT and SECURITY_CREDENTIALS
//
#define TH_SECURITY_PROVIDER (TH_RPC_BASE+1)
//
// Each of these hooks is passed the security context and a pStatus pointer.
// If the hook makes *pStatus nonzero, that becomes the return code from the
// member function.
//
#define TH_SECURITY_FN_SIGN MAKE_TEST_HOOK_ID( TH_SECURITY_PROVIDER, 1)
#define TH_SECURITY_FN_VERIFY MAKE_TEST_HOOK_ID( TH_SECURITY_PROVIDER, 2)
#define TH_SECURITY_FN_ACCEPT1 MAKE_TEST_HOOK_ID( TH_SECURITY_PROVIDER, 3)
#define TH_SECURITY_FN_ACCEPT3 MAKE_TEST_HOOK_ID( TH_SECURITY_PROVIDER, 4)
#define TH_SECURITY_FN_INIT1 MAKE_TEST_HOOK_ID( TH_SECURITY_PROVIDER, 5)
#define TH_SECURITY_FN_INIT3 MAKE_TEST_HOOK_ID( TH_SECURITY_PROVIDER, 6)
#define TH_RPC_SECURITY_SERVER_CONTEXT_CREATED MAKE_TEST_HOOK_ID( TH_SECURITY_PROVIDER, 7)
#define TH_RPC_SECURITY_CLIENT_CONTEXT_CREATED MAKE_TEST_HOOK_ID( TH_SECURITY_PROVIDER, 8)
// subject = pointer to RPC event structure
// object = 0
//
#define TH_RPC_LOG_EVENT MAKE_TEST_HOOK_ID(TH_RPC_BASE+2, 1)
inline void
CallTestHook(
RPC_TEST_HOOK_ID id,
PVOID subject = 0,
PVOID object = 0
)
{
#ifdef RPC_ENABLE_TEST_HOOKS
ForceCallTestHook( id, subject, object );
#endif
}
#ifdef RPC_ENABLE_TEST_HOOKS
RPC_TEST_HOOK_FN
GetTestHook(
RPC_TEST_HOOK_ID id
);
#endif
#endif /* __UTIL_HXX__ */