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.

447 lines
12 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. afds.c
  5. Abstract:
  6. Implements afds command
  7. Author:
  8. Vadim Eydelman, March 2000
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "afdkdp.h"
  14. #pragma hdrstop
  15. #define AFDKD_TOKEN "@$."
  16. #define AFDKD_TOKSZ (sizeof (AFDKD_TOKEN)-1)
  17. ULONG
  18. ListCallback (
  19. PFIELD_INFO pField,
  20. PVOID UserContext
  21. );
  22. //
  23. // Public functions.
  24. //
  25. ULONG LinkOffset;
  26. DECLARE_API( afds )
  27. /*++
  28. Routine Description:
  29. Dumps afd endpoints
  30. Arguments:
  31. None.
  32. Return Value:
  33. None.
  34. --*/
  35. {
  36. ULONG64 address;
  37. CHAR expr[MAX_ADDRESS_EXPRESSION];
  38. PCHAR argp;
  39. INT i;
  40. ULONG result;
  41. gClient = pClient;
  42. argp = ProcessOptions ((PCHAR)args);
  43. if (argp==NULL)
  44. return E_INVALIDARG;
  45. if ((Options & (AFDKD_LINK_FIELD|AFDKD_LIST_TYPE)) !=
  46. (AFDKD_LINK_FIELD|AFDKD_LIST_TYPE)) {
  47. dprintf ("\nafds: Missing link or list type specification");
  48. dprintf ("\nUsage:\nafds -l link -t type [options] address\n");
  49. return E_INVALIDARG;
  50. }
  51. if (sscanf( argp, "%s%n", expr, &i )!=1) {
  52. dprintf ("\nafds: Missing address specification");
  53. dprintf ("\nUsage:\nafds -l link -t type [options] address\n");
  54. return E_INVALIDARG;
  55. }
  56. argp += i;
  57. address = GetExpression (expr);
  58. if (Options & AFDKD_LINK_SELF) {
  59. result = GetFieldOffset (ListedType, LinkField, &LinkOffset);
  60. if (result!=0) {
  61. dprintf ("\nafds: Cannot get offset of %s in %s, err: %ld\n",
  62. LinkField, ListedType, result);
  63. return E_INVALIDARG;
  64. }
  65. }
  66. ListType (
  67. (Options & AFDKD_LINK_SELF)
  68. ? "LIST_ENTRY"
  69. : ListedType, // Type
  70. address, // Address
  71. (Options & AFDKD_LINK_AOF)
  72. ? 1
  73. : 0, // ListByFieldAddress
  74. (Options & AFDKD_LINK_SELF)
  75. ? "Flink"
  76. : LinkField, // NextPointer
  77. ListedType, // Context
  78. ListCallback);
  79. dprintf ("\n");
  80. return S_OK;
  81. }
  82. ULONG
  83. ListCallback (
  84. PFIELD_INFO pField,
  85. PVOID UserContext
  86. )
  87. {
  88. ULONG64 address;
  89. address = pField->address;
  90. if (Options & AFDKD_LINK_SELF) {
  91. address -= LinkOffset;
  92. }
  93. if (!(Options & AFDKD_CONDITIONAL) ||
  94. CheckConditional (address, UserContext)) {
  95. dprintf ("\n%s @ %p", UserContext, address);
  96. ProcessFieldOutput (address, UserContext);
  97. }
  98. else {
  99. dprintf (".");
  100. }
  101. return 0;
  102. }
  103. /*
  104. {
  105. ULONG64
  106. GetExpressionFromType (
  107. ULONG64 Address,
  108. PCHAR Type,
  109. PCHAR Expression
  110. )
  111. CHAR expr[MAX_CONDITIONAL_EXPRESSION];
  112. PCHAR argp = Expression, pe = expr, pestop=pe+sizeof(expr)-1;
  113. ULONG result;
  114. ULONG64 value;
  115. PCHAR type = Type;
  116. ULONG64 address = Address;
  117. while (*argp) {
  118. if (*argp=='@' && strncmp (argp, AFDKD_TOKEN, AFDKD_TOKSZ)==0) {
  119. PCHAR end = pe;
  120. argp+= AFDKD_TOKSZ;
  121. while (isalnum (*argp) ||
  122. *argp=='[' ||
  123. *argp==']' ||
  124. *argp=='_' ||
  125. *argp=='.' ||
  126. *argp=='-') {
  127. if (*argp=='-') {
  128. if (*(argp+1)=='>') {
  129. if (*(argp+2)=='(') {
  130. *end = 0;
  131. result = GetFieldValue (address, type, pe, value);
  132. if (result!=0) {
  133. dprintf ("\nCheckConditional: Can't get %s.%s at %p (err:%d)\n", type, pe, address, result);
  134. return FALSE;
  135. }
  136. if (value==0)
  137. return FALSE;
  138. argp += 3;
  139. type = argp;
  140. while (*argp && *argp!=')') {
  141. argp += 1;
  142. }
  143. *argp++ = 0;
  144. address = value;
  145. end = pe;
  146. continue;
  147. }
  148. if (end>=pestop)
  149. break;
  150. *end++ = *argp++;
  151. }
  152. else
  153. break;
  154. }
  155. if (end>=pestop)
  156. break;
  157. *end++ = *argp++;
  158. }
  159. *end = 0;
  160. result = GetFieldValue (address, type, pe, value);
  161. if (result!=0) {
  162. dprintf ("\nCheckConditional: Can't get %s.%s at %p (err:%d)\n", type, pe, address, result);
  163. return FALSE;
  164. }
  165. pe += _snprintf (pe, pestop-pe, "0x%I64X", value);
  166. address = Address;
  167. type = Type;
  168. }
  169. else {
  170. if (pe>=pestop)
  171. break;
  172. *pe++ = *argp++;
  173. }
  174. }
  175. *pe = 0;
  176. return GetExpression (expr);
  177. }
  178. */
  179. BOOLEAN
  180. CheckConditional (
  181. ULONG64 Address,
  182. PCHAR Type
  183. )
  184. {
  185. DEBUG_VALUE val;
  186. if (GetExpressionFromType (Address, Type, Conditional, DEBUG_VALUE_INT64, &val)==S_OK)
  187. return val.I64!=0;
  188. else
  189. return FALSE;
  190. }
  191. VOID
  192. ProcessFieldOutput (
  193. ULONG64 Address,
  194. PCHAR Type
  195. )
  196. {
  197. ULONG result;
  198. FldParam.addr = Address;
  199. FldParam.sName = Type;
  200. if (Options & AFDKD_NO_DISPLAY) {
  201. FldParam.Options |= DBG_DUMP_COMPACT_OUT;
  202. }
  203. dprintf ("\n");
  204. if (FldParam.nFields>0 ||
  205. (FldParam.nFields==0 && CppFieldEnd==0)) {
  206. result = Ioctl (IG_DUMP_SYMBOL_INFO, &FldParam, FldParam.size );
  207. if (result!=0) {
  208. dprintf ("\nProcessFieldOutput: IG_DUMP_SYMBOL_INFO failed, err: %ld\n", result);
  209. }
  210. }
  211. if (CppFieldEnd>FldParam.nFields) {
  212. ULONG i;
  213. for (i=FldParam.nFields; i<CppFieldEnd; i++) {
  214. DEBUG_VALUE val;
  215. if (GetExpressionFromType (Address, Type, FldParam.Fields[i].fName,
  216. DEBUG_VALUE_INVALID,
  217. &val)==S_OK) {
  218. dprintf (" %s = 0x%I64x(%d)\n",
  219. &FldParam.Fields[i].fName[AFDKD_CPP_PREFSZ],
  220. val.I64,
  221. val.Type
  222. );
  223. }
  224. /*
  225. SYM_DUMP_PARAM fldParam;
  226. CHAR fieldStr[MAX_FIELD_CHARS], *p;
  227. FIELD_INFO field = FldParam.Fields[i];
  228. ULONG64 value;
  229. ULONG skip = 0;
  230. fldParam = FldParam;
  231. fldParam.nFields = 1;
  232. fldParam.Fields = &field;
  233. //fldParam.Options |= DBG_DUMP_NO_PRINT;
  234. strncpy (fieldStr, field.fName, sizeof (fieldStr));
  235. field.fName = p = fieldStr;
  236. field.fOptions |= DBG_DUMP_FIELD_COPY_FIELD_DATA;
  237. field.fieldCallBack = &value;
  238. while ((p=strstr (p, "->("))!=NULL) {
  239. *p = 0;
  240. result = Ioctl (IG_DUMP_SYMBOL_INFO, &fldParam, fldParam.size );
  241. if (result!=0) {
  242. dprintf ("\nProcessFieldOutput: GetFieldValue (%p,%s,%s) failed, err: %ld\n",
  243. fldParam.addr,
  244. fldParam.sName,
  245. field.fName,
  246. result);
  247. goto DoneField;
  248. }
  249. fldParam.addr = value;
  250. p += sizeof ("->(")-1;
  251. fldParam.sName = p;
  252. p = strchr (p, ')');
  253. if (p==NULL) {
  254. dprintf ("\nProcessFieldOutput: missing ')' in %s\n", fldParam.sName);
  255. goto DoneField;
  256. }
  257. *p++ = 0;
  258. skip += 3;
  259. dprintf ("%*.80s%s : %I64x->(%s)\n", skip, " ",
  260. field.fName,
  261. DISP_PTR(value),
  262. fldParam.sName);
  263. field.fName = p;
  264. if (value==0) {
  265. goto DoneField;
  266. }
  267. }
  268. //fldParam.Options &= (~DBG_DUMP_NO_PRINT);
  269. field.fOptions &= ~(DBG_DUMP_FIELD_COPY_FIELD_DATA);
  270. field.fieldCallBack = NULL;
  271. result = Ioctl (IG_DUMP_SYMBOL_INFO, &fldParam, fldParam.size );
  272. if (result!=0) {
  273. dprintf ("\nProcessFieldOutput: IG_DUMP_SYMBOL_INFO %p %s %s failed, err: %ld\n",
  274. fldParam.addr,
  275. fldParam.sName,
  276. field.fName,
  277. result);
  278. break;
  279. }
  280. DoneField:
  281. ;
  282. */
  283. }
  284. }
  285. }
  286. DECLARE_API( filefind )
  287. /*++
  288. Routine Description:
  289. Searches non-paged pool for FILE_OBJECT given its FsContext field.
  290. Arguments:
  291. None.
  292. Return Value:
  293. None.
  294. --*/
  295. {
  296. ULONG64 FsContext;
  297. ULONG64 PoolStart, PoolEnd, PoolPage;
  298. ULONG64 PoolExpansionStart, PoolExpansionEnd;
  299. ULONG result;
  300. ULONG64 val;
  301. BOOLEAN twoPools;
  302. gClient = pClient;
  303. if (!CheckKmGlobals ()) {
  304. return E_INVALIDARG;
  305. }
  306. FsContext = GetExpression (args);
  307. if (FsContext==0 || FsContext<UserProbeAddress) {
  308. return E_INVALIDARG;
  309. }
  310. if ( (result = ReadPtr (DebuggerData.MmNonPagedPoolStart, &PoolStart))!=0 ||
  311. (result = ReadPtr (DebuggerData.MmNonPagedPoolEnd, &PoolEnd))!=0 ) {
  312. dprintf ("\nfilefind - Cannot get non-paged pool limits, err: %ld\n",
  313. result);
  314. return E_INVALIDARG;
  315. }
  316. if (PoolStart + DebuggerData.MmMaximumNonPagedPoolInBytes!=PoolEnd) {
  317. if ( (result = GetFieldValue (0,
  318. "NT!MmSizeOfNonPagedPoolInBytes",
  319. NULL,
  320. val))!=0 ||
  321. (result = GetFieldValue (0,
  322. "NT!MmNonPagedPoolExpansionStart",
  323. NULL,
  324. PoolExpansionStart))!=0 ) {
  325. dprintf ("\nfilefind - Cannot get non-paged pool expansion limits, err: %ld\n",
  326. result);
  327. return E_INVALIDARG;
  328. }
  329. PoolExpansionEnd = PoolEnd;
  330. PoolEnd = PoolStart + val;
  331. twoPools = TRUE;
  332. }
  333. else {
  334. twoPools = FALSE;
  335. }
  336. PoolPage = PoolStart;
  337. dprintf ("Searching non-paged pool %p - %p...\n", PoolStart, PoolEnd);
  338. while (PoolPage<PoolEnd) {
  339. SEARCHMEMORY Search;
  340. if (CheckControlC ()) {
  341. break;
  342. }
  343. Search.SearchAddress = PoolPage;
  344. Search.SearchLength = PoolEnd-PoolPage;
  345. Search.Pattern = &FsContext;
  346. Search.PatternLength = IsPtr64 () ? sizeof (ULONG64) : sizeof (ULONG);
  347. Search.FoundAddress = 0;
  348. if (Ioctl (IG_SEARCH_MEMORY, &Search, sizeof (Search)) &&
  349. Search.FoundAddress!=0) {
  350. ULONG64 fileAddr;
  351. fileAddr = Search.FoundAddress-FsContextOffset;
  352. result = (ULONG)InitTypeRead (fileAddr, NT!_FILE_OBJECT);
  353. if (result==0 && (CSHORT)ReadField (Type)==IO_TYPE_FILE) {
  354. dprintf ("File object at %p\n", fileAddr);
  355. }
  356. else {
  357. dprintf (" pool search match at %p\n", Search.FoundAddress);
  358. }
  359. PoolPage = Search.FoundAddress +
  360. (IsPtr64() ? sizeof (ULONG64) : sizeof (ULONG));
  361. }
  362. else {
  363. if (!twoPools || PoolEnd==PoolExpansionEnd) {
  364. break;
  365. }
  366. else {
  367. dprintf ("Searching expansion non-paged pool %p - %p...\n",
  368. PoolExpansionStart, PoolExpansionEnd);
  369. PoolEnd = PoolExpansionEnd;
  370. PoolPage = PoolExpansionStart;
  371. }
  372. }
  373. }
  374. return S_OK;
  375. }