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.

517 lines
18 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. CellDef.hxx
  5. Abstract:
  6. The header file which contains the common definitions for the
  7. cell debugging facilities.
  8. Author:
  9. Kamen Moutafov (kamenm) Dec 99 - Feb 2000
  10. Revision History:
  11. Data Structures:
  12. The cells are kept in the so called cell heap. The cell heap can allocate,
  13. free and relocate cells. Here's the relation b/n them:
  14. /////////////////
  15. // CellHeap //
  16. /////////////////
  17. |
  18. | 1
  19. | :
  20. | N
  21. V
  22. ================= 1:N \\\\\\\\\\\\\\\\
  23. == CellSection ==-------->\\ Cells \\
  24. ================= \\\\\\\\\\\\\\\\
  25. There is only one cell heap per process. Each cell section is a DACL protected,
  26. read-only from outside the process shared memory section. It starts with one
  27. committed page, and will commit more, if necessary. Pages are never decommitted
  28. from a section. We keep one cached section. If a whole section becomes unused,
  29. we make it the cached section. If the number of free cells in a section drops
  30. below a threshold, we free the cached section. Each section has a small header
  31. with information maintained by the cell heap manager.
  32. The allocator is tuned to pick up new cells from the first avaialble sections,
  33. which should preserve good locality and minimize long term memory pressure.
  34. The cell is 32 bytes big in both 32 and 64 bit versions. The fixed length
  35. simplifies and speeds up the operations of the allocator. All cells must start
  36. with the same Type byte in the same position - this is how code outside the
  37. process knows what cell is what.
  38. DebugCellID: There is the important concept of a debug cell id. A debug cell id
  39. is a unique identified of a cell, which is valid across processes. Thus, if you
  40. reference once cell from another, you should use the debug cell id, instead of
  41. the pointer.
  42. --*/
  43. #if _MSC_VER > 1000
  44. #pragma once
  45. #endif // _MSC_VER > 1000
  46. #ifndef __CELLDEF_H__
  47. #define __CELLDEF_H__
  48. #ifndef __DBGCOMN_HXX__
  49. #include <DbgComn.h>
  50. #endif
  51. #ifndef __DbgIdl_h__
  52. #include <DbgIdl.h>
  53. #endif
  54. #define _NOT_COVERED_ (0)
  55. // forwards
  56. class CellSection;
  57. typedef int CellTag;
  58. // temporary cells can be dctInvalid when the caller gets them and
  59. // starts initializing them
  60. const int dctFirstEntry = dctInvalid;
  61. const int dctLastEntry = dctUsedGeneric;
  62. typedef enum tagCallStatus
  63. {
  64. csAllocated,
  65. csActive,
  66. csDispatched
  67. } CallStatus;
  68. const int CallStatusFirst = csAllocated;
  69. const int CallStatusLast = csDispatched;
  70. #define DBGCELL_CACHED_CALL 0x00000001
  71. #define DBGCELL_ASYNC_CALL 0x00000002
  72. #define DBGCELL_PIPE_CALL 0x00000004
  73. #define DBGCELL_LRPC_CALL 0x00000008
  74. #define DBGCELL_VALID_CALL_FLAGS 0x00000015
  75. typedef struct tagDebugCallInfo
  76. {
  77. union
  78. {
  79. struct
  80. {
  81. BYTE Type;
  82. // chosen from the CallStatus enum
  83. BYTE Status;
  84. USHORT ProcNum;
  85. };
  86. DWORD TypeHeader;
  87. };
  88. DWORD InterfaceUUIDStart;
  89. DebugCellID ServicingTID;
  90. // 1 - cached if set
  91. // 2 - async if set
  92. // 3 - pipe if set
  93. // 4 - set if this is an LRPC call - otherwise its OSF
  94. // the others are not used
  95. DWORD CallFlags;
  96. DWORD CallID;
  97. DWORD LastUpdateTime;
  98. union
  99. {
  100. // valid for OSF only
  101. DebugCellID Connection;
  102. // valid for LRPC only
  103. union
  104. {
  105. struct
  106. {
  107. USHORT PID;
  108. USHORT TID;
  109. };
  110. // used for fast zeroing out of PID/TID pair
  111. DWORD FastInit;
  112. };
  113. };
  114. DWORD Reserved;
  115. } DebugCallInfo;
  116. #define DBGCELL_AUTH_SVC_NTLM 16
  117. #define DBGCELL_AUTH_SVC_KERB 32
  118. #define DBGCELL_AUTH_SVC_OTHER 48
  119. const int ConnectionAuthLevelMask = 14;
  120. const int ConnectionAuthLevelShift = 1;
  121. const int ConnectionAuthServiceMask = 48;
  122. const int ConnectionAuthServiceShift = 4;
  123. typedef struct tagDebugConnectionInfo
  124. {
  125. union
  126. {
  127. struct
  128. {
  129. BYTE Type;
  130. // 1 - exclusive if set
  131. // 2,3,4 - auth level
  132. // 5,6 - auth service encoded as follows:
  133. // 0 - none
  134. // 1 - NTLM
  135. // 2 - Kerberos/Snego
  136. // 3 - other
  137. // 7,8 - reserved
  138. BYTE Flags;
  139. USHORT LastTransmitFragmentSize;
  140. };
  141. DWORD TypeHeader;
  142. };
  143. DebugCellID Endpoint;
  144. // switch for union type is made based on the
  145. // protseq type in the endpoint
  146. HANDLE ConnectionID[2];
  147. DWORD LastSendTime;
  148. DWORD LastReceiveTime;
  149. #ifndef _WIN64
  150. DWORD Reserved[2];
  151. #endif
  152. } DebugConnectionInfo;
  153. typedef enum tagDebugThreadStatus
  154. {
  155. dtsProcessing,
  156. dtsDispatched,
  157. dtsAllocated,
  158. dtsIdle
  159. } DebugThreadStatus;
  160. typedef struct tagDebugThreadInfo
  161. {
  162. union
  163. {
  164. struct
  165. {
  166. BYTE Type;
  167. BYTE Reserved;
  168. // picked from the DebugThreadStatus enum
  169. USHORT Status;
  170. };
  171. DWORD TypeHeader;
  172. };
  173. DWORD LastUpdateTime;
  174. DebugCellID Endpoint;
  175. // something else?
  176. USHORT TID;
  177. // if LRPC thread, the address it is listening on. If remote
  178. // worker thread, 0
  179. USHORT Reserved2;
  180. DWORD Reserved3[4];
  181. } DebugThreadInfo;
  182. typedef enum tagDebugEndpointStatus
  183. {
  184. desAllocated,
  185. desActive,
  186. desInactive
  187. } DebugEndpointStatus;
  188. const int DebugEndpointNameLength = 28;
  189. typedef struct tagDebugEndpointInfo
  190. {
  191. union
  192. {
  193. struct
  194. {
  195. BYTE Type;
  196. BYTE ProtseqType;
  197. // chosen from the DebugEndpointStatus enum
  198. BYTE Status;
  199. BYTE Reserved;
  200. };
  201. DWORD TypeHeader;
  202. };
  203. // this string is *not* NULL terminated - use with care
  204. char EndpointName[DebugEndpointNameLength];
  205. } DebugEndpointInfo;
  206. const int ClientCallEndpointLength = 12;
  207. typedef struct tagDebugClientCallInfo
  208. {
  209. union
  210. {
  211. struct
  212. {
  213. BYTE Type;
  214. BYTE Reserved;
  215. USHORT ProcNum;
  216. };
  217. DWORD TypeHeader;
  218. };
  219. DebugCellID ServicingThread;
  220. DWORD IfStart;
  221. DWORD CallID;
  222. DebugCellID CallTargetID;
  223. // Note - this string is not zero terminated
  224. char Endpoint[ClientCallEndpointLength];
  225. } DebugClientCallInfo;
  226. const int TargetServerNameLength = 24;
  227. typedef struct tagDebugCallTargetInfo
  228. {
  229. union
  230. {
  231. struct
  232. {
  233. BYTE Type;
  234. BYTE Reserved;
  235. USHORT ProtocolSequence;
  236. };
  237. DWORD TypeHeader;
  238. };
  239. DWORD LastUpdateTime;
  240. // Note - this string is not zero terminated
  241. char TargetServer[TargetServerNameLength];
  242. } DebugCallTargetInfo;
  243. typedef struct tagDebugFreeCell
  244. {
  245. union
  246. {
  247. struct
  248. {
  249. BYTE Type;
  250. BYTE Reserved;
  251. USHORT Reserved2;
  252. };
  253. DWORD TypeHeader;
  254. };
  255. #ifdef _WIN64
  256. DWORD Reserved3[1];
  257. #endif
  258. CellSection *pOwnerSection;
  259. LIST_ENTRY FreeCellsChain;
  260. #ifndef _WIN64
  261. DWORD Reserved3[4];
  262. #endif
  263. } DebugFreeCell;
  264. typedef struct tagDebugCellGeneric
  265. {
  266. union
  267. {
  268. struct
  269. {
  270. BYTE Type;
  271. BYTE ProtseqType;
  272. USHORT Reserved;
  273. };
  274. DWORD TypeHeader;
  275. };
  276. } DebugCellGeneric;
  277. typedef struct tagDebugCellUnion
  278. {
  279. union
  280. {
  281. DebugCallInfo callInfo;
  282. DebugThreadInfo threadInfo;
  283. DebugEndpointInfo endpointInfo;
  284. DebugClientCallInfo clientCallInfo;
  285. DebugConnectionInfo connectionInfo;
  286. DebugCallTargetInfo callTargetInfo;
  287. DebugFreeCell freeCell;
  288. DebugCellGeneric genericCell;
  289. };
  290. } DebugCellUnion;
  291. // forward
  292. class CellHeap;
  293. // 32 bytes for 32 bit systems, 64 bytes for 64 bit systems
  294. class CellSection
  295. {
  296. public:
  297. friend CellHeap;
  298. friend void RPC_ENTRY I_RpcDoCellUnitTest(IN OUT void *p);
  299. void CompleteSectionInitialization(void);
  300. void PrepareSectionForCleanup(void);
  301. void CellAllocated(void);
  302. void CellFreed(void);
  303. static CellSection *AllocateCellSection(OUT RPC_STATUS *Status,
  304. IN BOOL fFirstSection, IN SECURITY_DESCRIPTOR *pSecDescriptor, IN CellHeap *pCellHeap);
  305. #if DBG
  306. void AssertValid(CellHeap *pCellHeap);
  307. #endif
  308. private:
  309. // ownership of hNewFileMapping passes to the CellSection
  310. CellSection(IN OUT RPC_STATUS *Status, IN OUT HANDLE hNewFileMapping, IN CellHeap *pCellHeap,
  311. IN DWORD *pRandomNumbers);
  312. void Free(void);
  313. // always must be called within the CellHeap mutex
  314. RPC_STATUS ExtendSection(IN CellHeap *pCellHeap);
  315. void InitializeNewPage(PVOID NewPage);
  316. USHORT Signature; // set during section creation
  317. public:
  318. USHORT LastCommittedPage; // the index of the last committed page
  319. // pages never get decommitted - only a whole
  320. // section can get freed. Therefore this
  321. // number only grows. It's protected by the
  322. // CellHeapMutex and is 1 based
  323. short SectionID; // the key for this section in the section
  324. // dictionary.
  325. private:
  326. USHORT NumberOfUsedCells; // the number of cells used in the section
  327. // protected by the CellHeap lock
  328. public:
  329. DWORD NextSectionId[2]; // two DWORDs that uniquely identify the next
  330. // section name. On the cached section, they
  331. // identify this section's name
  332. private:
  333. DebugFreeCell *pFirstFreeCell; // first free cell from this section
  334. // protected by the CellHeap lock
  335. HANDLE hFileMapping; // the handle of the section
  336. LIST_ENTRY SectionListEntry;// placeholder to chain the sections
  337. #if defined(_WIN64)
  338. DWORD Reserved[4];
  339. #endif
  340. };
  341. // all of these functions are in the debug library
  342. // enumeration handles
  343. typedef void * ServerEnumerationHandle;
  344. typedef void * CellEnumerationHandle;
  345. typedef void * RPCSystemWideCellEnumerationHandle;
  346. typedef void * CallInfoEnumerationHandle;
  347. typedef void * EndpointInfoEnumerationHandle;
  348. typedef void * ThreadInfoEnumerationHandle;
  349. typedef void * ClientCallInfoEnumerationHandle;
  350. #define RPCDBG_NO_PROCNUM_SPECIFIED (~(USHORT)0)
  351. // section manipulation functions
  352. void GenerateSectionName(OUT RPC_CHAR *Buffer, IN int BufferLength,
  353. IN DWORD ProcessID, IN DWORD *pSectionNumbers OPTIONAL);
  354. RPC_STATUS OpenDbgSection(OUT HANDLE *pHandle, OUT PVOID *pSection,
  355. IN DWORD ProcessID, IN DWORD *pSectionNumbers OPTIONAL);
  356. void CloseDbgSection(IN HANDLE SecHandle, IN PVOID SecPointer);
  357. // server manipulation functions
  358. RPC_STATUS StartServerEnumeration(OUT ServerEnumerationHandle *pHandle);
  359. RPC_STATUS OpenNextRPCServer(IN ServerEnumerationHandle Handle, OUT CellEnumerationHandle *pHandle);
  360. void ResetServerEnumeration(IN ServerEnumerationHandle Handle);
  361. void FinishServerEnumeration(IN OUT ServerEnumerationHandle *pHandle);
  362. DWORD GetCurrentServerPID(IN ServerEnumerationHandle Handle);
  363. // utility functions
  364. DWORD GetPageSize(void);
  365. RPC_STATUS InitializeDbgLib(void);
  366. // cell enumeration functions
  367. // enumerating a particular server
  368. RPC_STATUS OpenRPCServerDebugInfo(IN DWORD ProcessID, OUT CellEnumerationHandle *pHandle);
  369. DebugCellUnion *GetNextDebugCellInfo(IN CellEnumerationHandle Handle, OUT DebugCellID *CellID);
  370. void ResetRPCServerDebugInfo(IN CellEnumerationHandle Handle);
  371. void CloseRPCServerDebugInfo(IN OUT CellEnumerationHandle *pHandle);
  372. // enumerating all servers
  373. RPC_STATUS OpenRPCSystemWideCellEnumeration(OUT RPCSystemWideCellEnumerationHandle *pHandle);
  374. RPC_STATUS GetNextRPCSystemWideCell(IN RPCSystemWideCellEnumerationHandle handle, OUT DebugCellUnion **NextCell,
  375. OUT DebugCellID *CellID, OUT DWORD *ServerPID OPTIONAL);
  376. DebugCellUnion *GetRPCSystemWideCellFromCellID(IN RPCSystemWideCellEnumerationHandle handle,
  377. IN DebugCellID CellID);
  378. void FinishRPCSystemWideCellEnumeration(IN OUT RPCSystemWideCellEnumerationHandle *pHandle);
  379. RPC_STATUS ResetRPCSystemWideCellEnumeration(IN RPCSystemWideCellEnumerationHandle handle);
  380. // enumerating calls
  381. RPC_STATUS OpenRPCDebugCallInfoEnumeration(IN DWORD CallID OPTIONAL, IN DWORD IfStart OPTIONAL,
  382. IN int ProcNum OPTIONAL,
  383. IN DWORD ProcessID OPTIONAL,
  384. OUT CallInfoEnumerationHandle *pHandle);
  385. RPC_STATUS GetNextRPCDebugCallInfo(IN CallInfoEnumerationHandle handle, OUT DebugCallInfo **NextCall,
  386. OUT DebugCellID *CellID, OUT DWORD *ServerPID);
  387. void FinishRPCDebugCallInfoEnumeration(IN OUT CallInfoEnumerationHandle *pHandle);
  388. RPC_STATUS ResetRPCDebugCallInfoEnumeration(IN CallInfoEnumerationHandle handle);
  389. // enumerating endpoints
  390. RPC_STATUS OpenRPCDebugEndpointInfoEnumeration(IN char *Endpoint OPTIONAL,
  391. OUT EndpointInfoEnumerationHandle *pHandle);
  392. RPC_STATUS GetNextRPCDebugEndpointInfo(IN CallInfoEnumerationHandle handle, OUT DebugEndpointInfo **NextEndpoint,
  393. OUT DebugCellID *CellID, OUT DWORD *ServerPID);
  394. void FinishRPCDebugEndpointInfoEnumeration(IN OUT EndpointInfoEnumerationHandle *pHandle);
  395. RPC_STATUS ResetRPCDebugEndpointInfoEnumeration(IN EndpointInfoEnumerationHandle handle);
  396. // enumerating threads
  397. RPC_STATUS OpenRPCDebugThreadInfoEnumeration(IN DWORD ProcessID,
  398. IN DWORD ThreadID OPTIONAL,
  399. OUT ThreadInfoEnumerationHandle *pHandle);
  400. RPC_STATUS GetNextRPCDebugThreadInfo(IN ThreadInfoEnumerationHandle handle, OUT DebugThreadInfo **NextThread,
  401. OUT DebugCellID *CellID, OUT DWORD *ServerPID);
  402. void FinishRPCDebugThreadInfoEnumeration(IN OUT ThreadInfoEnumerationHandle *pHandle);
  403. RPC_STATUS ResetRPCDebugThreadInfoEnumeration(IN ThreadInfoEnumerationHandle handle);
  404. // enumerating client calls
  405. RPC_STATUS OpenRPCDebugClientCallInfoEnumeration(IN DWORD CallID OPTIONAL, IN DWORD IfStart OPTIONAL,
  406. IN int ProcNum OPTIONAL,
  407. IN DWORD ProcessID OPTIONAL,
  408. OUT ClientCallInfoEnumerationHandle *pHandle);
  409. RPC_STATUS GetNextRPCDebugClientCallInfo(IN ClientCallInfoEnumerationHandle handle,
  410. OUT DebugClientCallInfo **NextCall,
  411. OUT DebugCallTargetInfo **NextCallTarget,
  412. OUT DebugCellID *CellID, OUT DWORD *ServerPID);
  413. void FinishRPCDebugClientCallInfoEnumeration(IN OUT ClientCallInfoEnumerationHandle *pHandle);
  414. RPC_STATUS ResetRPCDebugClientCallInfoEnumeration(IN CallInfoEnumerationHandle handle);
  415. // retrieving a cell by the cell id
  416. DebugCellUnion *GetCellByDebugCellID(IN CellEnumerationHandle CellEnumHandle, IN DebugCellID CellID);
  417. RPC_STATUS GetCellByDebugCellID(IN DWORD ProcessID, IN DebugCellID CellID, DebugCellUnion *Container);
  418. // print function prototype
  419. typedef VOID (__cdecl *PRPCDEBUG_OUTPUT_ROUTINE)(PCSTR lpFormat, ...);
  420. // format and print functions
  421. void PrintCallInfoHeader(PRPCDEBUG_OUTPUT_ROUTINE PrintRoutine);
  422. void PrintCallInfoBody(IN DWORD ProcessID, IN DebugCellID CellID,
  423. IN DebugCallInfo *CallInfo, PRPCDEBUG_OUTPUT_ROUTINE PrintRoutine);
  424. void GetAndPrintCallInfo(IN DWORD CallID OPTIONAL, IN DWORD IfStart OPTIONAL,
  425. IN int ProcNum OPTIONAL, IN DWORD ProcessID OPTIONAL,
  426. PRPCDEBUG_OUTPUT_ROUTINE PrintRoutine);
  427. void PrintDbgCellInfo(IN DebugCellUnion *Container, IN DebugCellUnion *EndpointContainer OPTIONAL,
  428. PRPCDEBUG_OUTPUT_ROUTINE PrintRoutine);
  429. void GetAndPrintDbgCellInfo(DWORD ProcessID, DebugCellID CellID,
  430. PRPCDEBUG_OUTPUT_ROUTINE PrintRoutine);
  431. void PrintEndpointInfoHeader(PRPCDEBUG_OUTPUT_ROUTINE PrintRoutine);
  432. void PrintEndpointInfoBody(IN DWORD ProcessID, IN DebugCellID CellID,
  433. IN DebugEndpointInfo *EndpointInfo, PRPCDEBUG_OUTPUT_ROUTINE PrintRoutine);
  434. void GetAndPrintEndpointInfo(IN char *Endpoint OPTIONAL,
  435. PRPCDEBUG_OUTPUT_ROUTINE PrintRoutine);
  436. void PrintThreadInfoHeader(PRPCDEBUG_OUTPUT_ROUTINE PrintRoutine);
  437. void PrintThreadInfoBody(IN DWORD ProcessID, IN DebugCellID CellID,
  438. IN DebugThreadInfo *ThreadInfo, PRPCDEBUG_OUTPUT_ROUTINE PrintRoutine);
  439. void GetAndPrintThreadInfo(DWORD ProcessID, DWORD ThreadID OPTIONAL,
  440. PRPCDEBUG_OUTPUT_ROUTINE PrintRoutine);
  441. void PrintClientCallInfoHeader(PRPCDEBUG_OUTPUT_ROUTINE PrintRoutine);
  442. void PrintClientCallInfoBody(IN DWORD ProcessID, IN DebugCellID CellID,
  443. IN DebugClientCallInfo *ClientCallInfo,
  444. IN DebugCallTargetInfo *CallTargetInfo,
  445. PRPCDEBUG_OUTPUT_ROUTINE PrintRoutine);
  446. void GetAndPrintClientCallInfo(IN DWORD CallID OPTIONAL, IN DWORD IfStart OPTIONAL,
  447. IN int ProcNum OPTIONAL, IN DWORD ProcessID OPTIONAL,
  448. PRPCDEBUG_OUTPUT_ROUTINE PrintRoutine);
  449. #define RPC_S_DBG_NOT_AN_RPC_SERVER 1
  450. #define RPC_S_DBG_ENUMERATION_DONE 2
  451. #endif __CELLDEF_H__