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.

474 lines
11 KiB

  1. /*++
  2. Copyright (c) 1992-2000 Microsoft Corporation
  3. Module Name:
  4. util.c
  5. Abstract:
  6. WinDbg Extension Api
  7. Environment:
  8. User Mode.
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. ULONG
  14. GetBitFieldOffset (
  15. IN LPSTR Type,
  16. IN LPSTR Field,
  17. OUT PULONG pOffset,
  18. OUT PULONG pSize
  19. )
  20. {
  21. FIELD_INFO flds = {
  22. Field, "", 0,
  23. DBG_DUMP_FIELD_FULL_NAME | DBG_DUMP_FIELD_RETURN_ADDRESS | DBG_DUMP_FIELD_SIZE_IN_BITS,
  24. 0, NULL};
  25. SYM_DUMP_PARAM Sym = {
  26. sizeof (SYM_DUMP_PARAM), Type, DBG_DUMP_NO_PRINT, 0,
  27. NULL, NULL, NULL, 1, &flds
  28. };
  29. ULONG Err, i=0;
  30. LPSTR dot, last=Field;
  31. Sym.nFields = 1;
  32. Err = Ioctl( IG_DUMP_SYMBOL_INFO, &Sym, Sym.size );
  33. *pOffset = (ULONG) (flds.address - Sym.addr);
  34. *pSize = flds.size;
  35. return Err;
  36. }
  37. ULONG
  38. GetUlongFromAddress (
  39. ULONG64 Location
  40. )
  41. {
  42. ULONG Value;
  43. ULONG result;
  44. if ((!ReadMemory(Location,&Value,sizeof(ULONG),&result)) ||
  45. (result < sizeof(ULONG))) {
  46. dprintf("unable to read from %08x\n",Location);
  47. return 0;
  48. }
  49. return Value;
  50. }
  51. ULONG64
  52. GetPointerFromAddress (
  53. ULONG64 Location
  54. )
  55. {
  56. ULONG64 Value;
  57. ULONG result;
  58. if (!ReadPointer(Location,&Value)) {
  59. dprintf("unable to read from %08p\n",Location);
  60. return 0;
  61. }
  62. return Value;
  63. }
  64. ULONG
  65. GetUlongValue (
  66. PCHAR String
  67. )
  68. {
  69. ULONG64 Location;
  70. ULONG Value;
  71. ULONG result;
  72. Location = GetExpression( String );
  73. if (!Location) {
  74. dprintf("unable to get %s\n",String);
  75. return 0;
  76. }
  77. return GetUlongFromAddress( Location );
  78. }
  79. ULONG64
  80. GetPointerValue (
  81. PCHAR String
  82. )
  83. {
  84. ULONG64 Location, Val=0;
  85. Location = GetExpression( String );
  86. if (!Location) {
  87. dprintf("unable to get %s\n",String);
  88. return 0;
  89. }
  90. ReadPointer(Location, &Val);
  91. return Val;
  92. }
  93. #if 0
  94. VOID
  95. DumpImageName(
  96. IN ULONG64 Process
  97. )
  98. {
  99. ULONG64 ImageFileName;
  100. STRING String;
  101. ULONG Result;
  102. IN WCHAR Buf[512];
  103. if ( !GetFieldValue(Process, "EPROCESS", "ImageFileName.Buffer", ImageFileName ) ){
  104. wcscpy(Buf,L"*** image name unavailable ***");
  105. if ( ReadMemory( ImageFileName,
  106. &String,
  107. sizeof(STRING),
  108. &Result) ) {
  109. if ( ReadMemory( (DWORD)String.Buffer,
  110. &Buf[0],
  111. String.Length,
  112. &Result) ) {
  113. Buf[String.Length/sizeof(WCHAR)] = UNICODE_NULL;
  114. }
  115. }
  116. } else {
  117. wcscpy(Buf,L"System Process");
  118. }
  119. dprintf("%ws",Buf);
  120. }
  121. #endif
  122. BOOLEAN
  123. DbgRtlIsRightChild(
  124. ULONG64 pLinks,
  125. ULONG64 Parent
  126. )
  127. {
  128. ULONG64 RightChild;
  129. if (Parent == pLinks) {
  130. return FALSE;
  131. }
  132. if (GetFieldValue(Parent, "RTL_SPLAY_LINKS", "RightChild", RightChild)) {
  133. return FALSE;
  134. }
  135. if (RightChild == pLinks) {
  136. return TRUE;
  137. }
  138. return FALSE;
  139. }
  140. BOOLEAN
  141. DbgRtlIsLeftChild(
  142. ULONG64 pLinks,
  143. ULONG64 Parent
  144. )
  145. {
  146. ULONG64 LeftChild;
  147. if (Parent == pLinks) {
  148. return FALSE;
  149. }
  150. if (GetFieldValue(Parent, "RTL_SPLAY_LINKS", "LeftChild", LeftChild)) {
  151. return FALSE;
  152. }
  153. if (LeftChild == pLinks) {
  154. return TRUE;
  155. }
  156. return FALSE;
  157. }
  158. ULONG
  159. DumpSplayTree(
  160. IN ULONG64 pSplayLinks,
  161. IN PDUMP_SPLAY_NODE_FN DumpNodeFn
  162. )
  163. /*++
  164. Purpose:
  165. Perform an in-order iteration across a splay tree, calling a
  166. user supplied function with a pointer to each RTL_SPLAY_LINKS
  167. structure encountered in the tree, and the level in the tree
  168. at which it was encountered (zero based).
  169. Arguments:
  170. pSplayLinks - pointer to root of a splay tree
  171. DumpNodeFn - user supplied dumping function
  172. Returns:
  173. Count of nodes encountered in the tree.
  174. Notes:
  175. Errors reading memory do not terminate the iteration if more
  176. work is possible.
  177. Consumes the Control-C flag to terminate possible loops in
  178. corrupt structures.
  179. --*/
  180. {
  181. ULONG Level = 0;
  182. ULONG NodeCount = 0;
  183. if (pSplayLinks) {
  184. ULONG64 LeftChild, RightChild, Parent, Current;
  185. //
  186. // Retrieve the root links, find the leftmost node in the tree
  187. //
  188. if (GetFieldValue(Current = pSplayLinks,
  189. "RTL_SPLAY_LINKS",
  190. "LeftChild",
  191. LeftChild)) {
  192. return NodeCount;
  193. }
  194. while (LeftChild != 0) {
  195. if ( CheckControlC() ) {
  196. return NodeCount;
  197. }
  198. if (GetFieldValue(Current = LeftChild,
  199. "RTL_SPLAY_LINKS",
  200. "LeftChild",
  201. LeftChild)) {
  202. //
  203. // We can try to continue from this
  204. //
  205. break;
  206. }
  207. Level++;
  208. }
  209. while (TRUE) {
  210. if ( CheckControlC() ) {
  211. return NodeCount;
  212. }
  213. NodeCount++;
  214. pSplayLinks = Current;
  215. (*DumpNodeFn)(pSplayLinks, Level);
  216. /*
  217. first check to see if there is a right subtree to the input link
  218. if there is then the real successor is the left most node in
  219. the right subtree. That is find and return P in the following diagram
  220. Links
  221. \
  222. .
  223. .
  224. .
  225. /
  226. P
  227. \
  228. */
  229. GetFieldValue(Current, "RTL_SPLAY_LINKS", "RightChild", RightChild);
  230. if (RightChild != 0) {
  231. if (GetFieldValue(Current = RightChild,
  232. "RTL_SPLAY_LINKS",
  233. "RightChild",
  234. RightChild)) {
  235. //
  236. // We've failed to step through to a successor, so
  237. // there is no more to do
  238. //
  239. return NodeCount;
  240. }
  241. Level++;
  242. GetFieldValue(Current,"RTL_SPLAY_LINKS","LeftChild",LeftChild);
  243. while (LeftChild != 0) {
  244. if ( CheckControlC() ) {
  245. return NodeCount;
  246. }
  247. if (GetFieldValue(Current = LeftChild,
  248. "RTL_SPLAY_LINKS",
  249. "LeftChild",
  250. LeftChild)) {
  251. //
  252. // We can continue from this
  253. //
  254. break;
  255. }
  256. Level++;
  257. }
  258. } else {
  259. /*
  260. we do not have a right child so check to see if have a parent and if
  261. so find the first ancestor that we are a left decendent of. That
  262. is find and return P in the following diagram
  263. P
  264. /
  265. .
  266. .
  267. .
  268. Links
  269. */
  270. //
  271. // If the IsLeft or IsRight functions fail to read through a parent
  272. // pointer, then we will quickly exit through the break below
  273. //
  274. GetFieldValue(Current, "RTL_SPLAY_LINKS", "Parent", Parent);
  275. while (DbgRtlIsRightChild(Current, Parent)) {
  276. if ( CheckControlC() ) {
  277. return NodeCount;
  278. }
  279. Level--;
  280. pSplayLinks = (Current = Parent);
  281. }
  282. GetFieldValue(Current, "RTL_SPLAY_LINKS", "Parent", Parent);
  283. if (!DbgRtlIsLeftChild(Current, Parent)) {
  284. //
  285. // we do not have a real successor so we break out
  286. //
  287. break;
  288. } else {
  289. Level--;
  290. pSplayLinks = (Current = Parent);
  291. }
  292. }
  293. }
  294. }
  295. return NodeCount;
  296. }
  297. VOID
  298. DumpUnicode64(
  299. UNICODE_STRING64 u
  300. )
  301. {
  302. UNICODE_STRING v;
  303. DWORD BytesRead;
  304. // dprintf("L %x, M %x, B %p ", u.Length, u.MaximumLength, u.Buffer);
  305. if ((u.Length <= u.MaximumLength) &&
  306. (u.Buffer) &&
  307. (u.Length > 0)) {
  308. v.Buffer = LocalAlloc(LPTR, u.MaximumLength+2);
  309. if (v.Buffer != NULL) {
  310. v.MaximumLength = u.MaximumLength;
  311. v.Length = u.Length;
  312. if (ReadMemory(u.Buffer,
  313. v.Buffer,
  314. u.Length,
  315. (PULONG) &u.Buffer) &&
  316. (v.Buffer[0] != 0)) {
  317. v.Buffer[v.Length/sizeof(WCHAR)] = 0;
  318. dprintf("%ws", v.Buffer);
  319. } else {
  320. dprintf("< Name not readable >");
  321. }
  322. LocalFree(v.Buffer);
  323. return;
  324. }
  325. }
  326. dprintf("< Name not readable >");
  327. }
  328. BOOLEAN
  329. IsHexNumber(
  330. const char *szExpression
  331. )
  332. {
  333. if (!szExpression[0]) {
  334. return FALSE ;
  335. }
  336. for(;*szExpression; szExpression++) {
  337. if ((*szExpression)< '0') { return FALSE ; }
  338. else if ((*szExpression)> 'f') { return FALSE ; }
  339. else if ((*szExpression)>='a') { continue ; }
  340. else if ((*szExpression)> 'F') { return FALSE ; }
  341. else if ((*szExpression)<='9') { continue ; }
  342. else if ((*szExpression)>='A') { continue ; }
  343. else { return FALSE ; }
  344. }
  345. return TRUE ;
  346. }
  347. BOOLEAN
  348. IsDecNumber(
  349. const char *szExpression
  350. )
  351. {
  352. if (!szExpression[0]) {
  353. return FALSE ;
  354. }
  355. while(*szExpression) {
  356. if ((*szExpression)<'0') { return FALSE ; }
  357. else if ((*szExpression)>'9') { return FALSE ; }
  358. szExpression ++ ;
  359. }
  360. return TRUE ;
  361. }