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

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1990 - 1999
  6. //
  7. // File: util.hxx
  8. //
  9. //--------------------------------------------------------------------------
  10. /* --------------------------------------------------------------------
  11. Internal Header File for RPC Runtime Library
  12. -------------------------------------------------------------------- */
  13. #ifndef __UTIL_HXX__
  14. #define __UTIL_HXX__
  15. #ifndef __SYSINC_H__
  16. #error Needs sysinc.h
  17. #endif
  18. START_C_EXTERN
  19. #ifndef ARGUMENT_PRESENT
  20. #define ARGUMENT_PRESENT(Argument) (Argument != 0)
  21. #endif // ARGUMENT_PRESENT
  22. #ifdef NULL
  23. #undef NULL
  24. #endif
  25. #define NULL (0)
  26. #define Nil 0
  27. #ifdef TRUE
  28. #undef TRUE
  29. #endif
  30. #ifdef FALSE
  31. #undef FALSE
  32. #endif
  33. #define _NOT_COVERED_ (0)
  34. #define FALSE (0)
  35. #define TRUE (1)
  36. //
  37. // Expose the external logging hook on all builds.
  38. //
  39. #define RPC_ENABLE_WMI_TRACE
  40. #define RPC_ERROR_LOGGING
  41. #ifdef DBG
  42. //#define RPC_ENABLE_TEST_HOOKS
  43. #ifndef RPC_LOGGING
  44. #define RPC_LOGGING
  45. #endif
  46. #endif
  47. unsigned long
  48. SomeLongValue (
  49. );
  50. unsigned short
  51. SomeShortValue (
  52. );
  53. unsigned short
  54. AnotherShortValue (
  55. );
  56. unsigned char
  57. SomeCharacterValue (
  58. );
  59. extern int
  60. RpcpCheckHeap (
  61. void
  62. );
  63. int
  64. IsMgmtIfUuid(
  65. UUID PAPI * Uuid
  66. );
  67. END_C_EXTERN
  68. void
  69. PerformGarbageCollection (
  70. void
  71. );
  72. BOOL
  73. GarbageCollectionNeeded (
  74. IN BOOL fOneTimeCleanup,
  75. IN unsigned long GarbageCollectInterval
  76. );
  77. RPC_STATUS CreateGarbageCollectionThread (
  78. void
  79. );
  80. RPC_STATUS
  81. EnableIdleConnectionCleanup (
  82. void
  83. );
  84. RPC_STATUS
  85. EnableIdleLrpcSContextsCleanup (
  86. void
  87. );
  88. void
  89. GetMaxRpcSizeAndThreadPoolParameters (
  90. void
  91. );
  92. #ifdef RPC_DELAYED_INITIALIZATION
  93. extern int RpcHasBeenInitialized;
  94. extern RPC_STATUS
  95. PerformRpcInitialization (
  96. void
  97. );
  98. #define InitializeIfNecessary() \
  99. if ( RpcHasBeenInitialized == 0 ) \
  100. { \
  101. RPC_STATUS RpcStatus; \
  102. \
  103. RpcStatus = PerformRpcInitialization(); \
  104. if ( RpcStatus != RPC_S_OK ) \
  105. return(RpcStatus); \
  106. }
  107. #define AssertRpcInitialized() ASSERT( RpcHasBeenInitialized != 0 )
  108. #else /* RPC_DELAYED_INITIALIZATION */
  109. #define InitializeIfNecessary()
  110. #define AssertRpcInitialized()
  111. #define PerformRpcInitialization()
  112. #endif /* RPC_DELAYED_INITIALIZATION */
  113. RPC_CHAR *
  114. DuplicateString (
  115. IN const RPC_CHAR PAPI * String
  116. );
  117. PSID
  118. DuplicateSID (
  119. IN const PSID Sid
  120. );
  121. // trick the compiler into statically initializing SID with two SubAuthorities
  122. typedef struct _RPC_SID2 {
  123. UCHAR Revision;
  124. UCHAR SubAuthorityCount;
  125. SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
  126. ULONG SubAuthority[2];
  127. } RPC_SID2;
  128. extern const SID LocalSystem;
  129. extern const SID LocalService;
  130. extern const SID NetworkService;
  131. extern const RPC_SID2 Admin1;
  132. RPC_STATUS
  133. RpcpLookupAccountName (
  134. IN RPC_CHAR *ServerPrincipalName,
  135. IN OUT BOOL *fCache,
  136. OUT PSID *Sid
  137. );
  138. RPC_STATUS
  139. RpcpLookupAccountNameDirect (
  140. IN RPC_CHAR *ServerPrincipalName,
  141. OUT PSID *Sid
  142. );
  143. RPC_STATUS
  144. RpcpLookupAccountSid (
  145. IN PSID Sid,
  146. OUT RPC_CHAR **ServerPrincipalName
  147. );
  148. #ifdef UNICODE
  149. extern RPC_STATUS
  150. AnsiToUnicodeString (
  151. IN unsigned char * String,
  152. OUT UNICODE_STRING * UnicodeString
  153. );
  154. extern unsigned char *
  155. UnicodeToAnsiString (
  156. IN RPC_CHAR * WideCharString,
  157. OUT RPC_STATUS * RpcStatus
  158. );
  159. #endif // UNICODE
  160. void
  161. DestroyContextHandlesForGuard (
  162. IN PVOID Context,
  163. IN BOOL RundownContextHandle,
  164. IN void *CtxGuard
  165. );
  166. // forward definition
  167. class ContextCollection;
  168. RPC_STATUS
  169. NDRSContextInitializeCollection (
  170. IN ContextCollection **ContextCollectionPlaceholder
  171. );
  172. #if DBG
  173. void
  174. RpcpInterfaceForCallDoesNotUseStrict (
  175. IN RPC_BINDING_HANDLE BindingHandle
  176. );
  177. #endif
  178. inline unsigned short
  179. RpcpByteSwapShort (unsigned short Value)
  180. {
  181. return (RtlUshortByteSwap(Value));
  182. }
  183. inline unsigned long
  184. RpcpByteSwapLong (unsigned long Value)
  185. {
  186. return (RtlUlongByteSwap(Value));
  187. }
  188. typedef union tagFastCopyLUIDAccess
  189. {
  190. LUID Luid;
  191. __int64 FastAccess;
  192. } FastCopyLUIDAccess;
  193. inline void FastCopyLUIDAligned (LUID *TargetLUID, const LUID *SourceLUID)
  194. {
  195. FastCopyLUIDAccess *EffectiveSourceLUID = (FastCopyLUIDAccess *)SourceLUID;
  196. FastCopyLUIDAccess *EffectiveTargetLUID = (FastCopyLUIDAccess *)TargetLUID;
  197. #if defined(_WIN64)
  198. ASSERT((((ULONG_PTR)EffectiveSourceLUID) % 8) == 0);
  199. ASSERT((((ULONG_PTR)EffectiveTargetLUID) % 8) == 0);
  200. #endif
  201. EffectiveTargetLUID->FastAccess = EffectiveSourceLUID->FastAccess;
  202. }
  203. inline void FastCopyLUID (LUID *TargetLUID, LUID *SourceLUID)
  204. {
  205. FastCopyLUIDAccess *EffectiveSourceLUID = (FastCopyLUIDAccess *)SourceLUID;
  206. FastCopyLUIDAccess *EffectiveTargetLUID = (FastCopyLUIDAccess *)TargetLUID;
  207. #if !defined(_WIN64)
  208. FastCopyLUIDAligned(TargetLUID, SourceLUID);
  209. #else
  210. TargetLUID->HighPart = SourceLUID->HighPart;
  211. TargetLUID->LowPart = SourceLUID->LowPart;
  212. #endif
  213. }
  214. // returns non-zero if equal
  215. inline BOOL FastCompareLUIDAligned (const LUID *TargetLUID, const LUID *SourceLUID)
  216. {
  217. FastCopyLUIDAccess *EffectiveSourceLUID = (FastCopyLUIDAccess *)SourceLUID;
  218. FastCopyLUIDAccess *EffectiveTargetLUID = (FastCopyLUIDAccess *)TargetLUID;
  219. #if defined(_WIN64)
  220. ASSERT((((ULONG_PTR)EffectiveSourceLUID) % 8) == 0);
  221. ASSERT((((ULONG_PTR)EffectiveTargetLUID) % 8) == 0);
  222. #endif
  223. return (EffectiveTargetLUID->FastAccess == EffectiveSourceLUID->FastAccess);
  224. }
  225. inline BOOL FastCompareLUID (LUID *TargetLUID, LUID *SourceLUID)
  226. {
  227. FastCopyLUIDAccess *EffectiveSourceLUID = (FastCopyLUIDAccess *)SourceLUID;
  228. FastCopyLUIDAccess *EffectiveTargetLUID = (FastCopyLUIDAccess *)TargetLUID;
  229. #if !defined(_WIN64)
  230. return FastCompareLUIDAligned(TargetLUID, SourceLUID);
  231. #else
  232. return ((TargetLUID->HighPart == SourceLUID->HighPart)
  233. && (TargetLUID->LowPart == SourceLUID->LowPart));
  234. #endif
  235. }
  236. // zeroes out everything b/n the two fields, including the first field,
  237. // but excluding the second
  238. #define RPCP_ZERO_OUT_STRUCT_RANGE(Type, Instance, Field1, Field2) \
  239. RpcpMemorySet(((char *)(Instance)) + FIELD_OFFSET(Type, Field1), 0, FIELD_OFFSET(Type, Field2) - FIELD_OFFSET(Type, Field1))
  240. // zeroes out everything from a field to the end including the field
  241. #define RPCP_ZERO_OUT_STRUCT_TAIL(Type, Instance, Field) \
  242. RpcpMemorySet(((char *)(Instance)) + FIELD_OFFSET(Type, Field), 0, sizeof(Type) - FIELD_OFFSET(Type, Field))
  243. PUNICODE_STRING
  244. FastGetImageBaseNameUnicodeString (
  245. void
  246. );
  247. const RPC_CHAR *
  248. FastGetImageBaseName (
  249. void
  250. );
  251. //
  252. // System features - constant after InitializeIfNecessary.
  253. //
  254. // Just contants on non-NT systems
  255. //
  256. extern DWORD gPageSize;
  257. extern DWORD gThreadTimeout;
  258. extern UINT gNumberOfProcessors;
  259. extern DWORD gMaxRpcSize;
  260. extern DWORD gProrateStart;
  261. extern DWORD gProrateMax;
  262. extern DWORD gProrateFactor;
  263. extern BOOL gfServerPlatform;
  264. extern ULONGLONG gPhysicalMemorySize; // in megabytes
  265. extern DWORD gProcessStartTime;
  266. // The local machine's name.
  267. extern RPC_CHAR *gLocalComputerName;
  268. // The length of the name in TCHAR's including the terminating NULL.
  269. extern DWORD gLocalComputerNameLength;
  270. //
  271. // RPC Verifier settings
  272. //
  273. extern BOOL gfAppVerifierEnabled;
  274. extern BOOL gfRPCVerifierEnabled;
  275. // Corruption patterns:
  276. // ZeroOut - memory is zeroed-out
  277. // Negate - 0xff pattern is written
  278. // BitFlip - a random bit is flipped
  279. // IncDec - a byte is incremented or decremented
  280. // Randomize - a random byte is written
  281. // One of the above patterns is used at random
  282. enum tCorruptionPattern {ZeroOut, Negate, BitFlip, IncDec, Randomize, AllPatterns=100};
  283. // When choosing a random corruption pattern to apply, we will pick one from this range.
  284. #define MIN_CORRUPTION_PATTERN_ID (0)
  285. #define MAX_CORRUPTION_PATTERN_ID (4)
  286. // Corruption can be of a fixed or random size.
  287. enum tCorruptionSizeType {FixedSize, RandomSize};
  288. // Corruption may be spacially localized or randomized.
  289. // When it is localized, a sub-sequence of the buffer will be corrupted.
  290. // When it is randomized, random elements of the buffer will be corrupted.
  291. enum tCorruptionDistributionType {LocalizedDistribution, RandomizedDistribution};
  292. //
  293. // All of the RPC verifier settings are contained in a single
  294. // structure. We will allocate and initialize it iff
  295. // the RPC verifier is enabled.
  296. //
  297. typedef struct _tRpcVerifierSettings
  298. {
  299. // Fault injecting ImpersonateClient calls
  300. BOOL fFaultInjectImpersonateClient;
  301. // Proabilities are integers 1-10000. 10000 is p=1.
  302. unsigned int ProbFaultInjectImpersonateClient;
  303. // Delay in seconds before the start of fault injection.
  304. unsigned int DelayFaultInjectImpersonateClient;
  305. // Corruption injecting the data
  306. BOOL fCorruptionInjectServerReceives;
  307. BOOL fCorruptionInjectClientReceives;
  308. // Proabilities of corruption are integers 1-10000. 10000 is p=1.
  309. unsigned int ProbRpcHeaderCorruption;
  310. unsigned int ProbDataCorruption;
  311. unsigned int ProbSecureDataCorruption;
  312. tCorruptionPattern CorruptionPattern;
  313. tCorruptionSizeType CorruptionSizeType;
  314. // For Fixed size - set the size of the corruption in bytes
  315. // For Random size - set the maximum size of the corruption.
  316. // Actual size may be between 1 and gCorruptionSize
  317. unsigned int CorruptionSize;
  318. tCorruptionDistributionType CorruptionDistributionType;
  319. unsigned int ProbBufferTruncation;
  320. unsigned int MaxBufferTruncationSize;
  321. // Fault injecting transport failures.
  322. BOOL fFaultInjectTransports;
  323. unsigned int ProbFaultInjectTransports;
  324. // Injecting pauses into calls to external APIs
  325. BOOL fPauseInjectExternalAPIs;
  326. unsigned int ProbPauseInjectExternalAPIs;
  327. unsigned int PauseInjectExternalAPIsMaxWait;
  328. // Initialized to True if the process is running under a high-priv account.
  329. // This is used to detect if privileges are being leaked.
  330. BOOL IsHighPrivilege;
  331. // Optionally supressing app verifier breaks on bad RPC practictices.
  332. BOOL fSupressAppVerifierBreaks;
  333. // Causes RPC to switch to the allocation off a read-only paged heap.
  334. // Each allocation off the heap is guarded by a read-only page. This
  335. // catches AV's but still allows NDR to walk of the end of buffers a little.
  336. BOOL fReadonlyPagedHeap;
  337. } tRpcVerifierSettings;
  338. extern tRpcVerifierSettings *pRpcVerifierSettings;
  339. //
  340. // Macros for some common conditions and states.
  341. //
  342. extern BOOL gfRpcVerifierCorruptionExpected;
  343. #define gfRpcVerifierCorruptionInjectClientReceives \
  344. ( \
  345. gfRPCVerifierEnabled && \
  346. pRpcVerifierSettings->fCorruptionInjectClientReceives \
  347. )
  348. #define gfRpcVerifierCorruptionInjectServerReceives \
  349. ( \
  350. gfRPCVerifierEnabled && \
  351. pRpcVerifierSettings->fCorruptionInjectServerReceives \
  352. )
  353. #define gfRpcVerifierSupressAppVerifierBreaks (pRpcVerifierSettings->fSupressAppVerifierBreaks)
  354. #define gfRPCVerifierEnabledWithBreaks (gfRPCVerifierEnabled && !gfRpcVerifierSupressAppVerifierBreaks)
  355. // When defined, this macro builds a private with corruption injection for lrpc.
  356. //#define RPC_LRPC_CORRUPTION
  357. //
  358. // RPC Verifier utility functions
  359. //
  360. // Generates a boolean with P(True)=Prob/10000.
  361. inline BOOL
  362. RndBool(
  363. unsigned int Prob
  364. );
  365. // The buffer types passed to the corruption injection routine.
  366. enum tBufferType {ServerReceive, ClientReceive};
  367. // Injects corruption into a buffer
  368. extern void
  369. CorruptionInject(
  370. tBufferType BufferType,
  371. unsigned int *pBufferLength,
  372. void **pBuffer
  373. );
  374. extern void
  375. PrintCurrentStackTrace(
  376. unsigned int FramesToSkip,
  377. unsigned int Size
  378. );
  379. extern void
  380. PrintUUID(
  381. GUID *guid
  382. );
  383. #define RPC_VERIFIER_PRINT_OFFENDING_STACK(FramesToSkip, FramesToPrint) \
  384. DbgPrint("RPC: Offending Stack:\n"); \
  385. PrintCurrentStackTrace(FramesToSkip, FramesToPrint); \
  386. DbgPrint("RPC: To determine the symbolic stack, do an \"ln\" on the above addresses in the context of the faulting process.\n\n")
  387. //
  388. // Macros used to print app verifier warnings.
  389. //
  390. #define RPC_VERIFIER_UNSECURE_IF_REMOTELY_ACCESSIBLE (0x10)
  391. #define RPC_VERIFIER_DISABLING_SELECTIVE_BINDING (0x20)
  392. #define RPC_VERIFIER_WEAK_SECURITY_FOR_REMOTE_CALL (0x30)
  393. #define RPC_VERIFIER_UNSAFE_PROTOCOL (0x40)
  394. #define RPC_VERIFIER_UNSAFE_FEATURE (0x50)
  395. #define RPC_VERIFIER_NO_LOCAL_MUTUAL_AUTHENTICATION (0x60)
  396. #define RPC_VERIFIER_REGISTERING_NONROBUST_IF (0x70)
  397. #define RPC_VERIFIER_ARGUMENTS_IGNORED (0x80)
  398. #define RPC_VERIFIER_PRIVILEGE_LEAK (0x90)
  399. #define RPC_VERIFIER_WARNING_MSG(Msg, WarningType) \
  400. VERIFIER_STOP(APPLICATION_VERIFIER_RPC_ERROR | APPLICATION_VERIFIER_NO_BREAK, \
  401. Msg, WarningType, "RpcWarningType", 0, NULL, 0, NULL, 0, NULL); \
  402. //
  403. // RPC Verifier debuging macros
  404. //
  405. // Macro used to assert when corruption injection is not enabled.
  406. // This allows us to run with corruption injection on checked builds without
  407. // triggering the asserts that catch corruption.
  408. #if DBG
  409. #define CORRUPTION_ASSERT(cond) \
  410. if (!gfRpcVerifierCorruptionExpected) \
  411. { \
  412. ASSERT(cond); \
  413. }
  414. #else // DBG
  415. #define CORRUPTION_ASSERT(cond) ((void) 0)
  416. #endif // DBG
  417. // Set when building a private with verifier
  418. // debugging spew.
  419. //#define VERIFIER_DBG
  420. #ifdef VERIFIER_DBG
  421. #define VERIFIER_DBG_PRINT_0(s) DbgPrint(s)
  422. #define VERIFIER_DBG_PRINT_1(s, x1) DbgPrint(s, x1)
  423. #define VERIFIER_DBG_PRINT_2(s, x1, x2) DbgPrint(s, x1, x2)
  424. #define VERIFIER_DBG_PRINT_3(s, x1, x2, x3) DbgPrint(s, x1, x2, x3)
  425. #else
  426. #define VERIFIER_DBG_PRINT_0(x) ((void) 0)
  427. #define VERIFIER_DBG_PRINT_1(s, x1) ((void) 0)
  428. #define VERIFIER_DBG_PRINT_2(s, x1, x2) ((void) 0)
  429. #define VERIFIER_DBG_PRINT_3(s, x1, x2, x3) ((void) 0)
  430. #endif
  431. //
  432. // Per-interface security check exemptions.
  433. //
  434. // The flags for various security checks that may be disabled for an interface:
  435. // Registering an interface that is remotely acessible without a security callback
  436. // and without RPC_IF_ALLOW_SECURE_ONLY flag.
  437. #define ALLOW_UNSECURE_REMOTE_ACCESS 0x00000001
  438. // An interface may be called remotely by without RPC_C_AUTHN_LEVEL_PKT_PRIVACY
  439. #define ALLOW_UNENCRYPTED_REMOTE_ACCESS 0x00000002
  440. // An interface may be called remotely by without mutual authentication.
  441. #define ALLOW_NO_MUTUAL_AUTH_REMOTE_ACCESS 0x00000004
  442. #define ALLOW_EVERYTHING 0xffffffff
  443. // Determines whether a security check is disabled for a given interface.
  444. extern BOOL
  445. IsInterfaceExempt (
  446. IN GUID *IfUuid,
  447. IN DWORD CheckFlag
  448. );
  449. //
  450. // Detecting unsafe protseqs.
  451. //
  452. // Determines whether a given protseq is unsafe.
  453. extern BOOL
  454. IsProtseqUnsafe (
  455. IN RPC_CHAR *ProtocolSequence
  456. );
  457. //
  458. // Paged BCache settings
  459. //
  460. enum BCacheMode {
  461. BCacheModeCached, // Allocations go through the cache.
  462. BCacheModeDirect // Allocations go directly to the heap.
  463. };
  464. // set to one of the constants above
  465. extern BCacheMode gBCacheMode;
  466. // if non-zero, we may be in lsa. This is maybe, because
  467. // conclusive check is too expensive, and the only
  468. // way we use this flag is to avoid some optimizations
  469. // that can result in deadlock in lsa.
  470. extern BOOL fMaybeLsa;
  471. //
  472. // Security support functions
  473. //
  474. extern RPC_STATUS
  475. IsCurrentUserAdmin(
  476. void
  477. );
  478. //
  479. // constants for LogEvent(),
  480. //
  481. #define SU_HANDLE 'h'
  482. #define SU_CCONN 'n'
  483. #define SU_SCONN 'N'
  484. #define SU_CASSOC 'a'
  485. #define SU_SASSOC 'A'
  486. #define SU_CCALL 'c'
  487. #define SU_SCALL 'C'
  488. #define SU_PACKET 'p'
  489. #define SU_CENDPOINT 'e'
  490. #define SU_ENGINE 'E'
  491. #define SU_ASSOC '.'
  492. #define SU_MUTEX 'm'
  493. #define SU_STABLE 'T'
  494. #define SU_ADDRESS 'D'
  495. #define SU_HEAP 'H'
  496. #define SU_BCACHE 'b'
  497. #define SU_REFOBJ 'r'
  498. #define SU_THREAD 't'
  499. #define SU_TRANS_CONN 'o'
  500. #define SU_EVENT 'v'
  501. #define SU_EXCEPT 'x'
  502. #define SU_CTXHANDLE 'l'
  503. #define SU_EEINFO 'I'
  504. #define SU_GC 'G'
  505. #define SU_IF 'i'
  506. #define SU_SECCRED 'S'
  507. #define SU_HTTPv2 '2'
  508. #define SU_CORRUPT 'O'
  509. #define EV_CREATE 'C'
  510. #define EV_DELETE 'D'
  511. #define EV_START 'c'
  512. #define EV_STOP 'd'
  513. #define EV_INC '+'
  514. #define EV_DEC '-'
  515. #define EV_PROC 'p'
  516. #define EV_ACK 'a'
  517. #define EV_CALLBACK 'L'
  518. #define EV_NOTIFY 'N'
  519. #define EV_APC 'A'
  520. #define EV_STATUS 'S'
  521. #define EV_DISASSOC 'x'
  522. #define EV_STATE '='
  523. #define EV_POP 'P'
  524. #define EV_PUSH 'Q'
  525. #define EV_PKT_IN 'k'
  526. #define EV_PKT_OUT 'K'
  527. #define EV_BUFFER_IN 'b'
  528. #define EV_BUFFER_OUT 'B'
  529. #define EV_BUFFER_FAIL 'X'
  530. #define EV_ABORT 'R'
  531. #define EV_SET 's'
  532. // for debugging. A packet can be dropped or delayed.
  533. //
  534. #define EV_DROP '*'
  535. #define EV_DELAY '#'
  536. #define EV_PRUNE 'p'
  537. // SU_SCONN: a call is being transferred to another connection during auto-reconnect.
  538. //
  539. #define EV_TRANSFER 'T'
  540. // SU_CASSOC: the dynamic endpoint has been resolved into a real endpoint
  541. //
  542. #define EV_RESOLVED 'r'
  543. // SU_ENGINE: window size and selective-ack bits from a FACK or NOCALL
  544. //
  545. #define EV_WINDOW 'w'
  546. // SU_SCALL: the call was removed from the connection's active list
  547. #define EV_REMOVED 'm'
  548. // SU_SCALL: Cleanup() was called with refcount > 0
  549. #define EV_CLEANUP ','
  550. #define EV_BHCOPY 'O'
  551. #define EV_ALLOCATE 't'
  552. #define EV_OPER 'o'
  553. //
  554. //
  555. #define EV_SEC_INIT1 'i'
  556. #define EV_SEC_INIT3 'I'
  557. #define EV_SEC_ACCEPT1 'j'
  558. #define EV_SEC_ACCEPT3 'J'
  559. #define IN_CHANNEL_STATE (UlongToPtr(0))
  560. #define OUT_CHANNEL_STATE (UlongToPtr(1))
  561. #define MAX_RPC_EVENT 4096
  562. #define STACKTRACE_DEPTH 4
  563. // The RPC event log and the size of the RPC event log.
  564. // When the RPC verifier is enabled we will re-allocate the log and extend its size.
  565. extern struct RPC_EVENT *RpcEvents;
  566. extern long EventArrayLength;
  567. struct RPC_EVENT
  568. {
  569. DWORD Thread;
  570. DWORD Time;
  571. unsigned char Subject;
  572. unsigned char Verb;
  573. void * SubjectPointer;
  574. void * ObjectPointer;
  575. ULONG_PTR Data;
  576. void * EventStackTrace[STACKTRACE_DEPTH];
  577. };
  578. extern void
  579. TrulyLogEvent(
  580. IN unsigned char Subject,
  581. IN unsigned char Verb,
  582. IN void * SubjectPointer,
  583. IN void * ObjectPointer = 0,
  584. IN ULONG_PTR Data = 0,
  585. IN BOOL fCaptureStackTrace = 0,
  586. IN int AdditionalFramesToSkip = 0
  587. );
  588. #ifdef RPC_LOGGING
  589. extern BOOL fEnableLog;
  590. inline void
  591. LogEvent(
  592. IN unsigned char Subject,
  593. IN unsigned char Verb,
  594. IN void * SubjectPointer,
  595. IN void * ObjectPointer = 0,
  596. IN ULONG_PTR Data = 0,
  597. IN BOOL fCaptureStackTrace = 0,
  598. IN int AdditionalFramesToSkip = 0
  599. )
  600. {
  601. if (fEnableLog)
  602. {
  603. TrulyLogEvent( Subject,
  604. Verb,
  605. SubjectPointer,
  606. ObjectPointer,
  607. Data,
  608. fCaptureStackTrace,
  609. AdditionalFramesToSkip
  610. );
  611. }
  612. }
  613. #else
  614. inline void
  615. LogEvent(
  616. IN unsigned char Subject,
  617. IN unsigned char Verb,
  618. IN void * SubjectPointer,
  619. IN void * ObjectPointer = 0,
  620. IN ULONG_PTR Data = 0,
  621. IN BOOL fCaptureStackTrace = 0,
  622. IN int AdditionalFramesToSkip = 0
  623. )
  624. {
  625. #if DBG
  626. TrulyLogEvent(Subject, Verb, SubjectPointer, ObjectPointer, Data, fCaptureStackTrace,
  627. AdditionalFramesToSkip);
  628. #endif
  629. }
  630. #endif
  631. //
  632. // LogError will produce an event even on normal retail builds.
  633. //
  634. #ifdef RPC_ERROR_LOGGING
  635. inline void
  636. LogError(
  637. IN unsigned char Subject,
  638. IN unsigned char Verb,
  639. IN void * SubjectPointer,
  640. IN void * ObjectPointer = 0,
  641. IN ULONG_PTR Data = 0,
  642. IN BOOL fCaptureStackTrace = 0,
  643. IN int AdditionalFramesToSkip = 0
  644. )
  645. {
  646. TrulyLogEvent( Subject,
  647. Verb,
  648. SubjectPointer,
  649. ObjectPointer,
  650. Data,
  651. fCaptureStackTrace,
  652. AdditionalFramesToSkip
  653. );
  654. }
  655. #else
  656. inline void
  657. LogError(
  658. IN unsigned char Subject,
  659. IN unsigned char Verb,
  660. IN void * SubjectPointer,
  661. IN void * ObjectPointer = 0,
  662. IN ULONG_PTR Data = 0,
  663. IN BOOL fCaptureStackTrace = 0,
  664. IN int AdditionalFramesToSkip = 0
  665. )
  666. {
  667. #if DBG
  668. TrulyLogEvent(Subject, Verb, SubjectPointer, ObjectPointer, Data, fCaptureStackTrace,
  669. AdditionalFramesToSkip);
  670. #endif
  671. }
  672. #endif
  673. #ifdef STATS
  674. extern DWORD g_dwStat1;
  675. extern DWORD g_dwStat2;
  676. extern DWORD g_dwStat3;
  677. extern DWORD g_dwStat4;
  678. inline void GetStats(DWORD *pdwStat1, DWORD *pdwStat2, DWORD *pdwStat3, DWORD *pdwStat4)
  679. {
  680. *pdwStat1 = g_dwStat1;
  681. *pdwStat2 = g_dwStat2;
  682. *pdwStat3 = g_dwStat3;
  683. *pdwStat4 = g_dwStat4;
  684. }
  685. inline void SetStat1(DWORD dwStat)
  686. {
  687. g_dwStat1 = dwStat;
  688. }
  689. inline void SetStat2(DWORD dwStat)
  690. {
  691. g_dwStat2 = dwStat;
  692. }
  693. inline void SetStat3(DWORD dwStat)
  694. {
  695. g_dwStat3 = dwStat;
  696. }
  697. inline void SetStat4(DWORD dwStat)
  698. {
  699. g_dwStat4 = dwStat;
  700. }
  701. inline void IncStat1(void)
  702. {
  703. InterlockedIncrement((long *) &g_dwStat1);
  704. }
  705. inline void DecStat1(void)
  706. {
  707. InterlockedDecrement((long *) &g_dwStat1);
  708. }
  709. inline void Stat1Add(long val)
  710. {
  711. InterlockedExchangeAdd((long *) &g_dwStat1, val);
  712. }
  713. inline void Stat1Sub(long val)
  714. {
  715. InterlockedExchangeAdd((long *) &g_dwStat1, -val);
  716. }
  717. inline void IncStat2(void)
  718. {
  719. InterlockedIncrement((long *) &g_dwStat2);
  720. }
  721. inline void DecStat2(void)
  722. {
  723. InterlockedDecrement((long *) &g_dwStat2);
  724. }
  725. inline void Stat2Add(long val)
  726. {
  727. InterlockedExchangeAdd((long *) &g_dwStat2, val);
  728. }
  729. inline void Stat2Sub(long val)
  730. {
  731. InterlockedExchangeAdd((long *) &g_dwStat2, -val);
  732. }
  733. inline void IncStat3(void)
  734. {
  735. InterlockedIncrement((long *) &g_dwStat3);
  736. }
  737. inline void DecStat3(void)
  738. {
  739. InterlockedDecrement((long *) &g_dwStat3);
  740. }
  741. inline void Stat3Add(long val)
  742. {
  743. InterlockedExchangeAdd((long *) &g_dwStat3, val);
  744. }
  745. inline void Stat3Sub(long val)
  746. {
  747. InterlockedExchangeAdd((long *) &g_dwStat3, -val);
  748. }
  749. inline void IncStat4(void)
  750. {
  751. InterlockedIncrement((long *) &g_dwStat4);
  752. }
  753. inline void DecStat4(void)
  754. {
  755. InterlockedDecrement((long *) &g_dwStat4);
  756. }
  757. inline void Stat4Add(long val)
  758. {
  759. InterlockedExchangeAdd((long *) &g_dwStat4, val);
  760. }
  761. inline void Stat4Sub(long val)
  762. {
  763. InterlockedExchangeAdd((long *) &g_dwStat4, -val);
  764. }
  765. #else
  766. inline void GetStats(DWORD *pdwStat1, DWORD *pdwStat2, DWORD *pdwStat3, DWORD *pdwStat4)
  767. {
  768. }
  769. inline void SetStat1(DWORD dwStat)
  770. {
  771. }
  772. inline void SetStat2(DWORD dwStat)
  773. {
  774. }
  775. inline void SetStat3(DWORD dwStat)
  776. {
  777. }
  778. inline void SetStat4(DWORD dwStat)
  779. {
  780. }
  781. inline void IncStat1(void)
  782. {
  783. }
  784. inline void DecStat1(void)
  785. {
  786. }
  787. inline void Stat1Add(long val)
  788. {
  789. }
  790. inline void Stat1Sub(long val)
  791. {
  792. }
  793. inline void IncStat2(void)
  794. {
  795. }
  796. inline void DecStat2(void)
  797. {
  798. }
  799. inline void Stat2Add(long val)
  800. {
  801. }
  802. inline void Stat2Sub(long val)
  803. {
  804. }
  805. inline void IncStat3(void)
  806. {
  807. }
  808. inline void DecStat3(void)
  809. {
  810. }
  811. inline void Stat3Add(long val)
  812. {
  813. }
  814. inline void Stat3Sub(long val)
  815. {
  816. }
  817. inline void IncStat4(void)
  818. {
  819. }
  820. inline void DecStat4(void)
  821. {
  822. }
  823. inline void Stat4Add(long val)
  824. {
  825. }
  826. inline void Stat4Sub(long val)
  827. {
  828. }
  829. #endif
  830. //
  831. // test hook data. The stuff that would logically live in UTIL.CXX is actually in DGCLNT.CXX
  832. // due to trouble linking the BVT programs.
  833. //
  834. typedef unsigned long RPC_TEST_HOOK_ID;
  835. typedef void (RPC_TEST_HOOK_FN_RAW)( RPC_TEST_HOOK_ID id, PVOID subject, PVOID object );
  836. typedef RPC_TEST_HOOK_FN_RAW * RPC_TEST_HOOK_FN;
  837. RPCRTAPI
  838. DWORD
  839. RPC_ENTRY
  840. I_RpcSetTestHook(
  841. RPC_TEST_HOOK_ID id,
  842. RPC_TEST_HOOK_FN fn
  843. );
  844. void
  845. ForceCallTestHook(
  846. RPC_TEST_HOOK_ID id,
  847. PVOID subject,
  848. PVOID object
  849. );
  850. //
  851. // ranges for the major field:
  852. //
  853. // common: 001-099
  854. // dg: 100-199
  855. // co: 200-299
  856. // lrpc: 300-399
  857. // transports: 400-499
  858. // reserved: 500-32767
  859. //
  860. #define MAKE_TEST_HOOK_ID( major, minor ) ( ((major) << 16) | (minor) )
  861. #define TH_RPC_BASE 1
  862. #define TH_DG_BASE 100
  863. #define TH_CO_BASE 200
  864. #define TH_LRPC_BASE 300
  865. #define TH_TRANS_BASE 400
  866. //
  867. // protocol-independent hook IDs.
  868. //
  869. // member functions of SECURITY_CONTEXT and SECURITY_CREDENTIALS
  870. //
  871. #define TH_SECURITY_PROVIDER (TH_RPC_BASE+1)
  872. //
  873. // Each of these hooks is passed the security context and a pStatus pointer.
  874. // If the hook makes *pStatus nonzero, that becomes the return code from the
  875. // member function.
  876. //
  877. #define TH_SECURITY_FN_SIGN MAKE_TEST_HOOK_ID( TH_SECURITY_PROVIDER, 1)
  878. #define TH_SECURITY_FN_VERIFY MAKE_TEST_HOOK_ID( TH_SECURITY_PROVIDER, 2)
  879. #define TH_SECURITY_FN_ACCEPT1 MAKE_TEST_HOOK_ID( TH_SECURITY_PROVIDER, 3)
  880. #define TH_SECURITY_FN_ACCEPT3 MAKE_TEST_HOOK_ID( TH_SECURITY_PROVIDER, 4)
  881. #define TH_SECURITY_FN_INIT1 MAKE_TEST_HOOK_ID( TH_SECURITY_PROVIDER, 5)
  882. #define TH_SECURITY_FN_INIT3 MAKE_TEST_HOOK_ID( TH_SECURITY_PROVIDER, 6)
  883. #define TH_RPC_SECURITY_SERVER_CONTEXT_CREATED MAKE_TEST_HOOK_ID( TH_SECURITY_PROVIDER, 7)
  884. #define TH_RPC_SECURITY_CLIENT_CONTEXT_CREATED MAKE_TEST_HOOK_ID( TH_SECURITY_PROVIDER, 8)
  885. // subject = pointer to RPC event structure
  886. // object = 0
  887. //
  888. #define TH_RPC_LOG_EVENT MAKE_TEST_HOOK_ID(TH_RPC_BASE+2, 1)
  889. inline void
  890. CallTestHook(
  891. RPC_TEST_HOOK_ID id,
  892. PVOID subject = 0,
  893. PVOID object = 0
  894. )
  895. {
  896. #ifdef RPC_ENABLE_TEST_HOOKS
  897. ForceCallTestHook( id, subject, object );
  898. #endif
  899. }
  900. #ifdef RPC_ENABLE_TEST_HOOKS
  901. RPC_TEST_HOOK_FN
  902. GetTestHook(
  903. RPC_TEST_HOOK_ID id
  904. );
  905. #endif
  906. #endif /* __UTIL_HXX__ */