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.

263 lines
5.5 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. Tunnel.c
  5. Abstract:
  6. WinDbg Extension Api
  7. Author:
  8. Dan Lovinger 2-Apr-96
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. //
  16. // printf is really expensive to iteratively call to do the indenting,
  17. // so we just build up some avaliable spaces to mangle as required
  18. //
  19. #define MIN(a,b) ((a) > (b) ? (b) : (a))
  20. #define MAXINDENT 128
  21. #define INDENTSTEP 2
  22. #define MakeSpace(I) Space[MIN((I)*INDENTSTEP, MAXINDENT)] = '\0'
  23. #define RestoreSpace(I) Space[MIN((I)*INDENTSTEP, MAXINDENT)] = ' '
  24. CHAR Space[MAXINDENT*INDENTSTEP + 1];
  25. //#define SplitLI(LI) (LI).HighPart, (LI).LowPart
  26. #define SplitLL(LL) (ULONG)((LL) >> 32), (ULONG)((LL) & 0xffffffff)
  27. VOID
  28. DumpTunnelNode (
  29. ULONG64 Node,
  30. ULONG Indent
  31. )
  32. {
  33. WCHAR ShortNameStr[8+1+3] = {0};
  34. WCHAR LongNameStr[64] = {0};
  35. ULONG Flags;
  36. UNICODE_STRING ShortName, LongName;
  37. if (GetFieldValue(Node, "TUNNEL_NODE", "Flags", Flags)) {
  38. return;
  39. }
  40. InitTypeRead(Node, TUNNEL_NODE);
  41. ShortName.Length = (USHORT) ReadField(ShortName.Length);
  42. if (ShortName.Length >= sizeof(ShortNameStr))
  43. {
  44. ShortName.Length = sizeof(ShortNameStr) - sizeof(WCHAR);
  45. }
  46. LongName.Length = (USHORT) ReadField(LongName.Length);
  47. if (LongName.Length >= sizeof(LongNameStr))
  48. {
  49. LongName.Length = sizeof(LongNameStr) - sizeof(WCHAR);
  50. }
  51. //
  52. // Grab the strings from the debugee
  53. //
  54. if (!ReadMemory(ReadField(ShortName.Buffer),
  55. ShortNameStr,
  56. ShortName.Length,
  57. NULL)) {
  58. return;
  59. }
  60. if (!ReadMemory(ReadField(LongName.Buffer),
  61. LongNameStr,
  62. LongName.Length,
  63. NULL)) {
  64. return;
  65. }
  66. //
  67. // Modify the node in-place so we can use normal printing
  68. //
  69. LongName.Buffer = LongNameStr;
  70. ShortName.Buffer = ShortNameStr;
  71. MakeSpace(Indent);
  72. dprintf("%sNode @ %08x Cr %08x%08x DK %08x%08x [",
  73. Space,
  74. Node,
  75. SplitLL(ReadField(CreateTime)),
  76. SplitLL(ReadField(DirKey)));
  77. //
  78. // Must be kept in sync with flag usage in fsrtl\tunnel.c
  79. //
  80. if (Flags & 0x1)
  81. dprintf("NLA");
  82. else
  83. dprintf("LA");
  84. if (Flags & 0x2)
  85. dprintf(" KYS");
  86. else
  87. dprintf(" KYL");
  88. dprintf("]\n");
  89. dprintf("%sP %08p R %08p L %08p Sfn/Lfn \"%wZ\"/\"%wZ\"\n",
  90. Space,
  91. ReadField(CacheLinks.Parent),
  92. ReadField(CacheLinks.RightChild),
  93. ReadField(CacheLinks.LeftChild),
  94. &ShortName,
  95. &LongName );
  96. dprintf("%sF %08p B %08p\n",
  97. Space,
  98. ReadField(ListLinks.Flink),
  99. ReadField(ListLinks.Blink));
  100. RestoreSpace(Indent);
  101. }
  102. VOID DumpTunnelNodeWrapper (
  103. ULONG64 pCacheLinks,
  104. ULONG Indent
  105. )
  106. {
  107. // TUNNEL_NODE Node, *pNode;
  108. static ULONG Off=0;
  109. if (!Off) {
  110. GetFieldOffset("TUNNEL_NODE", "CacheLinks", &Off);
  111. }
  112. DumpTunnelNode(pCacheLinks - Off, Indent);
  113. }
  114. VOID
  115. DumpTunnel (
  116. ULONG64 pTunnel
  117. )
  118. {
  119. ULONG64 pLink, pHead, NodeFlink=0, TimerQueueFlink, pNode;
  120. ULONG Indent = 0, EntryCount = 0, NumEntries, Offset, ListOffset;
  121. ULONG64 Cache;
  122. if (GetFieldValue(pTunnel, "TUNNEL", "NumEntries", NumEntries)) {
  123. dprintf("Can't read TUNNEL at %p\n", pTunnel);
  124. return;
  125. }
  126. GetFieldValue(pTunnel, "TUNNEL", "Cache", Cache);
  127. GetFieldValue(pTunnel, "TUNNEL", "TimerQueue.Flink", TimerQueueFlink);
  128. pLink = TimerQueueFlink;
  129. GetFieldOffset("TUNNEL", "TimerQueue", &Offset);
  130. dprintf("Tunnel @ %08x\n"
  131. "NumEntries = %ld\n\n"
  132. "Splay Tree @ %08x\n",
  133. pTunnel,
  134. NumEntries,
  135. Cache);
  136. EntryCount = DumpSplayTree(Cache, DumpTunnelNodeWrapper);
  137. if (EntryCount != NumEntries) {
  138. dprintf("Tree count mismatch (%d not expected %d)\n", EntryCount, NumEntries);
  139. }
  140. GetFieldOffset("TUNNEL_NODE", "ListLinks", &ListOffset);
  141. for (EntryCount = 0,
  142. pHead = pTunnel + Offset,
  143. pLink = TimerQueueFlink;
  144. pLink != pHead;
  145. pLink = NodeFlink,
  146. EntryCount++) {
  147. pNode = pLink - ListOffset;
  148. if (pLink == TimerQueueFlink) {
  149. dprintf("\nTimer Queue @ %08x\n", pHead);
  150. }
  151. if (GetFieldValue(pNode, "TUNNEL_NODE",
  152. "ListLinks.Flink", NodeFlink)) {
  153. dprintf("Can't read TUNNEL_NODE at %p\n", pNode);
  154. return;
  155. }
  156. DumpTunnelNode(pNode, 0);
  157. if ( CheckControlC() ) {
  158. return;
  159. }
  160. }
  161. if (EntryCount != NumEntries) {
  162. dprintf("Timer count mismatch (%d not expected %d)\n", EntryCount, NumEntries);
  163. }
  164. }
  165. DECLARE_API( tunnel )
  166. /*++
  167. Routine Description:
  168. Dump tunnel caches
  169. Arguments:
  170. arg - <Address>
  171. Return Value:
  172. None
  173. --*/
  174. {
  175. ULONG64 Tunnel = 0;
  176. RtlFillMemory(Space, sizeof(Space), ' ');
  177. Tunnel = GetExpression(args);
  178. if (Tunnel == 0) {
  179. //
  180. // No args
  181. //
  182. return E_INVALIDARG;
  183. }
  184. DumpTunnel(Tunnel);
  185. return S_OK;
  186. }