Source code of Windows XP (NT5)
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.

333 lines
7.6 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. process.c
  5. Abstract:
  6. WinDbg Extension Api
  7. Author:
  8. John Richardson (v-johnjr) 05-Nov-1998
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. BOOL
  16. DumpSession(
  17. IN char * pad,
  18. IN ULONG64 RealProcessBase,
  19. IN ULONG Flags,
  20. IN PCHAR ImageFileName
  21. );
  22. DECLARE_API( session )
  23. /*++
  24. Routine Description:
  25. Dumps the active sessions list.
  26. Arguments:
  27. None.
  28. Return Value:
  29. None.
  30. --*/
  31. {
  32. ULONG64 ProcessToDump;
  33. ULONG SessionToDump;
  34. ULONG Flags;
  35. ULONG Result;
  36. ULONG64 Next;
  37. ULONG64 ProcessHead;
  38. ULONG64 Process;
  39. ULONG64 Thread;
  40. PCHAR ImageFileName;
  41. STRING string1, string2;
  42. CHAR Buf[256];
  43. CHAR Buf2[256];
  44. ULONG ActiveProcessLinksOffset;
  45. // Dump all processes
  46. ProcessToDump = 0;
  47. SessionToDump = 0xFFFFFFFF;
  48. Flags = 0xFFFFFFFF;
  49. RtlZeroMemory(Buf, 256);
  50. if (!sscanf(args,"%lx %lx %s",&SessionToDump, &Flags, Buf)) {
  51. Flags = 0xFFFFFFFF;
  52. SessionToDump = 0xFFFFFFFF;
  53. }
  54. if (Flags == 0xFFFFFFFF) {
  55. Flags = 3;
  56. }
  57. // We use csrss.exe to represent sessions by default
  58. if (Buf[0] != '\0') {
  59. ImageFileName = Buf;
  60. } else {
  61. ImageFileName = "csrss.exe";
  62. }
  63. dprintf("*** !session obsolete, Use !process");
  64. if (SessionToDump == -1) {
  65. dprintf(" 0 0 %s\n", ImageFileName);
  66. } else {
  67. dprintf(" /s %lx 0 0 %s\n", SessionToDump, ImageFileName);
  68. }
  69. dprintf("**** NT ACTIVE SESSION DUMP ****\n");
  70. ProcessHead = GetNtDebuggerData( PsActiveProcessHead );
  71. if (!ProcessHead) {
  72. dprintf("Unable to get value of PsActiveProcessHead\n");
  73. return E_INVALIDARG;
  74. }
  75. if (GetFieldValue( ProcessHead, "nt!_LIST_ENTRY", "Flink", Next)) {
  76. dprintf("Unable to get value of PsActiveProcessHead\n");
  77. return E_INVALIDARG;
  78. }
  79. if (Next == 0) {
  80. dprintf("PsActiveProcessHead is NULL!\n");
  81. return E_INVALIDARG;
  82. }
  83. if (GetFieldOffset("nt!_EPROCESS", "ActiveProcessLinks", &ActiveProcessLinksOffset)) {
  84. dprintf("Cannot find nt!_EPROCESS type.\n");
  85. return E_INVALIDARG;
  86. }
  87. //dprintf("Offset %#x\n", ActiveProcessLinksOffset);
  88. while(Next != ProcessHead) {
  89. ULONG SessionId;
  90. if (Next != 0) {
  91. Process = (Next - ActiveProcessLinksOffset);
  92. }
  93. else {
  94. Process = ProcessToDump;
  95. }
  96. if (GetFieldValue( Process, "nt!_EPROCESS", "ImageFileName", Buf2)) {
  97. dprintf("Unable to read nt!_EPROCESS at %p\n",Process);
  98. return E_INVALIDARG;
  99. }
  100. if (Buf2[0] == '\0' ) {
  101. strcpy((PCHAR)Buf2,"System Process");
  102. }
  103. RtlInitString(&string1, ImageFileName);
  104. RtlInitString(&string2, (PCSZ) Buf2);
  105. GetFieldValue( Process, "nt!_EPROCESS", "SessionId" ,SessionId);
  106. if ( ((SessionToDump == (ULONG) -1) || (SessionToDump == SessionId))
  107. &&
  108. RtlCompareString(&string1, &string2, TRUE) == 0) {
  109. if (DumpSession ("", Process, Flags, ImageFileName) && (Flags & 6)) {
  110. EXPRLastDump = Process;
  111. dprintf("\n");
  112. }
  113. if (ProcessToDump != 0) {
  114. return E_INVALIDARG;
  115. }
  116. }
  117. GetFieldValue( Process, "nt!_EPROCESS", "ActiveProcessLinks.Flink", Next);
  118. if (Next == 0) {
  119. return E_INVALIDARG;
  120. }
  121. if (CheckControlC()) {
  122. return E_INVALIDARG;
  123. }
  124. }
  125. return S_OK;
  126. }
  127. DECLARE_API( dss )
  128. /*++
  129. Routine Description:
  130. Dumps the session space structure
  131. Arguments:
  132. None.
  133. Return Value:
  134. None.
  135. --*/
  136. {
  137. ULONG Result;
  138. ULONG64 MmSessionSpace;
  139. ULONG64 MmSessionSpacePtr = 0;
  140. ULONG64 Wsle;
  141. MmSessionSpacePtr = GetExpression(args);
  142. if( MmSessionSpacePtr == 0 ) {
  143. MmSessionSpacePtr = GetExpression("nt!MmSessionSpace");
  144. if( !MmSessionSpacePtr ) {
  145. dprintf("Unable to get address of MmSessionSpace\n");
  146. return E_INVALIDARG;
  147. }
  148. if (!ReadPointer( MmSessionSpacePtr, &MmSessionSpace)) {
  149. dprintf("Unable to get value of MmSessionSpace\n");
  150. return E_INVALIDARG;
  151. }
  152. } else {
  153. MmSessionSpace = MmSessionSpacePtr;
  154. }
  155. dprintf("MM_SESSION_SPACE at 0x%p\n",
  156. MmSessionSpace
  157. );
  158. if (GetFieldValue(MmSessionSpace, "MM_SESSION_SPACE", "Wsle", Wsle)) {
  159. dprintf("Unable to get value of MM_SESSION_SPACE at 0x%p\n",MmSessionSpace);
  160. return E_INVALIDARG;
  161. }
  162. GetFieldOffset("MM_SESSION_SPACE", "PageTables", &Result);
  163. dprintf("&PageTables %p\n",
  164. MmSessionSpace + Result
  165. );
  166. GetFieldOffset("MM_SESSION_SPACE", "PagedPoolInfo", &Result);
  167. dprintf("&MM_PAGED_POOL_INFO %x\n",
  168. MmSessionSpace + Result
  169. );
  170. GetFieldOffset("MM_SESSION_SPACE", "Vm", &Result);
  171. dprintf("&MMSUPPORT %p\n",
  172. MmSessionSpace + Result
  173. );
  174. GetFieldOffset("MM_SESSION_SPACE", "Wsle", &Result);
  175. dprintf("&PMMWSLE %p\n",
  176. MmSessionSpace + Result
  177. );
  178. GetFieldOffset("MM_SESSION_SPACE", "Session", &Result);
  179. dprintf("&MMSESSION %p\n",
  180. MmSessionSpace + Result
  181. );
  182. GetFieldOffset("MM_SESSION_SPACE", "WorkingSetLockOwner", &Result);
  183. dprintf("&WorkingSetLockOwner %p\n",
  184. MmSessionSpace + Result
  185. );
  186. GetFieldOffset("MM_SESSION_SPACE", "PagedPool", &Result);
  187. dprintf("&POOL_DESCRIPTOR %p\n",
  188. MmSessionSpace + Result
  189. );
  190. return S_OK;
  191. }
  192. BOOL
  193. DumpSession(
  194. IN char * pad,
  195. IN ULONG64 RealProcessBase,
  196. IN ULONG Flags,
  197. IN PCHAR ImageFileName
  198. )
  199. {
  200. ULONG NumberOfHandles;
  201. ULONG Result;
  202. LARGE_INTEGER RunTime;
  203. ULONG KeTimeIncrement;
  204. ULONG TimeIncrement;
  205. STRING string1, string2;
  206. ULONG Type, SessionId,StackCount;
  207. ULONG64 ObjectTable,UniqueProcessId, Peb,DirBase;
  208. #define ProcFld(F, V) GetFieldValue(RealProcessBase, "EPROCESS", #F, V)
  209. #define ProcFld2(F) GetFieldValue(RealProcessBase, "EPROCESS", #F, F)
  210. if (ProcFld(Pcb.Header.Type, Type)) {
  211. dprintf("Unable to read EPROCESS at %p\n", RealProcessBase);
  212. return FALSE;
  213. }
  214. if (Type != (ULONG) ProcessObject) {
  215. dprintf("TYPE mismatch for process object at %p\n",RealProcessBase);
  216. return FALSE;
  217. }
  218. ProcFld2(ObjectTable); ProcFld2(UniqueProcessId); ProcFld2(Peb);
  219. ProcFld2(SessionId); ProcFld(Pcb.StackCount, StackCount);
  220. ProcFld(Pcb.DirectoryTableBase[0], DirBase);
  221. NumberOfHandles = 0;
  222. if (ObjectTable) {
  223. GetFieldValue(ObjectTable,
  224. "HANDLE_TABLE",
  225. "HandleCount",
  226. NumberOfHandles);
  227. }
  228. dprintf("%sPROCESS %08p Cid: %04I64lx Peb: %08p SessionId: %08u\n",
  229. pad,
  230. RealProcessBase,
  231. UniqueProcessId,
  232. Peb,
  233. SessionId
  234. );
  235. // If Pcb.StackCount is 0, PD is not resident!
  236. if( StackCount == 0 ) {
  237. dprintf("%s DirBase: NotResident ObjectTable: %08p TableSize: %3u.\n",
  238. pad,
  239. ObjectTable,
  240. NumberOfHandles
  241. );
  242. }
  243. else {
  244. dprintf("%s DirBase: %08p ObjectTable: %08p TableSize: %3u.\n",
  245. pad,
  246. DirBase,
  247. ObjectTable,
  248. NumberOfHandles
  249. );
  250. }
  251. dprintf("%s Image: %s\n",pad,ImageFileName);
  252. #undef ProcFld
  253. #undef ProcFld2
  254. return TRUE;
  255. }