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.

417 lines
10 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. MEMBER_VARIABLE_INFO _MemberInfo;
  4. #define STATE_FILENAME "tcpipext.state"
  5. STRUCTURE_TABLE StructureTable[] =
  6. {
  7. { NULL }
  8. };
  9. BOOL NextListEntry( ULONG Current, PULONG Next );
  10. BOOL PrevListEntry( ULONG Current, PULONG Prev );
  11. VOID NextElement( PMEMBER_VARIABLE_INFO pMemberInfo );
  12. VOID PrevElement( PMEMBER_VARIABLE_INFO pMemberInfo );
  13. VOID DumpListItem( PMEMBER_VARIABLE_INFO pMemberInfo );
  14. BOOL
  15. LocateMemberVariable
  16. (
  17. PCHAR pchStructName,
  18. PCHAR pchMemberName,
  19. PVOID pvStructure,
  20. PMEMBER_VARIABLE_INFO pMemberInfo
  21. )
  22. {
  23. BOOL bMatch;
  24. int index;
  25. PMEMBER_TABLE pMemberTable;
  26. CHAR pchCurrent[ MAX_LIST_VARIABLE_NAME_LENGTH + 1 ];
  27. CHAR _pchStructName[ MAX_LIST_VARIABLE_NAME_LENGTH + 1 ];
  28. CHAR _pchMemberName[ MAX_LIST_VARIABLE_NAME_LENGTH + 1 ];
  29. dprintf( "LocateMemberVariable( \"%s\", \"%s\", 0x%08X )\n", pchStructName, pchMemberName, pMemberInfo );
  30. strcpy( _pchStructName, pchStructName );
  31. strcpy( _pchMemberName, pchMemberName );
  32. _strupr( _pchStructName );
  33. _strupr( _pchMemberName );
  34. pMemberInfo->StructureIndex = 0;
  35. pMemberInfo->MemberIndex = 0;
  36. bMatch = FALSE;
  37. for ( index = 0; StructureTable[ index ].pchStructName != NULL; index ++ )
  38. {
  39. strcpy( pchCurrent, StructureTable[ index ].pchStructName );
  40. _strupr( pchCurrent );
  41. if ( strstr( pchCurrent, _pchStructName ))
  42. {
  43. if ( bMatch )
  44. {
  45. dprintf( "The specified structure name is ambiguous.\n" );
  46. return( FALSE );
  47. }
  48. pMemberInfo->StructureIndex = index;
  49. bMatch = TRUE;
  50. }
  51. }
  52. if ( !bMatch )
  53. {
  54. dprintf( "No matching structure name was found.\n" );
  55. return( FALSE );
  56. }
  57. pMemberTable = StructureTable[ pMemberInfo->StructureIndex ].pMemberTable;
  58. bMatch = FALSE;
  59. for ( index = 0; pMemberTable[ index ].pchMemberName != NULL; index ++ )
  60. {
  61. strcpy( pchCurrent, pMemberTable[ index ].pchMemberName );
  62. _strupr( pchCurrent );
  63. if ( strstr( pchCurrent, _pchMemberName ))
  64. {
  65. if ( bMatch )
  66. {
  67. dprintf( "The variable specified is ambiguous.\n" );
  68. return( FALSE );
  69. }
  70. pMemberInfo->MemberIndex = index;
  71. bMatch = TRUE;
  72. }
  73. }
  74. if ( !bMatch )
  75. {
  76. dprintf( "No matching member name was found in the %s structure.\n", pchStructName );
  77. return( FALSE );
  78. }
  79. pMemberInfo->prHeadContainingObject = ( ULONG )pvStructure;
  80. pMemberInfo->prHeadLinkage = (( ULONG )pvStructure ) + pMemberTable[ pMemberInfo->MemberIndex ].cbOffsetToHead;
  81. pMemberInfo->prCurrentLinkage = pMemberInfo->prHeadLinkage;
  82. pMemberInfo->cCurrentElement = 0;
  83. return( TRUE );
  84. }
  85. BOOL WriteMemberInfo( PMEMBER_VARIABLE_INFO pMemberInfo )
  86. {
  87. HANDLE hStateFile;
  88. DWORD dwWritten;
  89. hStateFile = CreateFile( STATE_FILENAME,
  90. GENERIC_WRITE,
  91. 0,
  92. NULL,
  93. CREATE_ALWAYS,
  94. FILE_ATTRIBUTE_NORMAL,
  95. NULL );
  96. if ( hStateFile == INVALID_HANDLE_VALUE )
  97. {
  98. dprintf( "Can't create state file\n" );
  99. return( FALSE );
  100. }
  101. if ( !WriteFile( hStateFile,
  102. pMemberInfo,
  103. sizeof( MEMBER_VARIABLE_INFO ),
  104. &dwWritten,
  105. NULL ) || ( dwWritten != sizeof( MEMBER_VARIABLE_INFO )))
  106. {
  107. dprintf( "Can't write to state file\n" );
  108. CloseHandle( hStateFile );
  109. return( FALSE );
  110. }
  111. CloseHandle( hStateFile );
  112. return( TRUE );
  113. }
  114. BOOL ReadMemberInfo( PMEMBER_VARIABLE_INFO pMemberInfo )
  115. {
  116. HANDLE hStateFile;
  117. DWORD dwRead;
  118. hStateFile = CreateFile( STATE_FILENAME,
  119. GENERIC_READ,
  120. 0,
  121. NULL,
  122. OPEN_EXISTING,
  123. FILE_ATTRIBUTE_NORMAL,
  124. NULL );
  125. if ( hStateFile == INVALID_HANDLE_VALUE )
  126. {
  127. dprintf( "Can't open state file\n" );
  128. return( FALSE );
  129. }
  130. if ( !ReadFile( hStateFile,
  131. pMemberInfo,
  132. sizeof( MEMBER_VARIABLE_INFO ),
  133. &dwRead,
  134. NULL ) || ( dwRead != sizeof( MEMBER_VARIABLE_INFO )))
  135. {
  136. dprintf( "Can't read from state file\n" );
  137. CloseHandle( hStateFile );
  138. return( FALSE );
  139. }
  140. CloseHandle( hStateFile );
  141. return( TRUE );
  142. }
  143. DECLARE_API( next )
  144. {
  145. MEMBER_VARIABLE_INFO MemberInfo;
  146. if ( !ReadMemberInfo( &MemberInfo ) )
  147. {
  148. return;
  149. }
  150. NextElement( &MemberInfo );
  151. DumpListItem( &MemberInfo );
  152. WriteMemberInfo( &MemberInfo );
  153. }
  154. DECLARE_API( prev )
  155. {
  156. MEMBER_VARIABLE_INFO MemberInfo;
  157. if ( !ReadMemberInfo( &MemberInfo ) )
  158. {
  159. return;
  160. }
  161. PrevElement( &MemberInfo );
  162. DumpListItem( &MemberInfo );
  163. WriteMemberInfo( &MemberInfo );
  164. }
  165. VOID DumpListItem( PMEMBER_VARIABLE_INFO pMemberInfo )
  166. {
  167. PBYTE pbObject;
  168. PMEMBER_TABLE pMemberTable;
  169. dprintf( "Focus is on: %s.%s, element # %d\n",
  170. StructureTable[ pMemberInfo->StructureIndex ].pchStructName,
  171. StructureTable[ pMemberInfo->StructureIndex ].pMemberTable[ pMemberInfo->MemberIndex ].pchMemberName,
  172. pMemberInfo->cCurrentElement );
  173. pMemberTable = &StructureTable[ pMemberInfo->StructureIndex ].pMemberTable[ pMemberInfo->MemberIndex ];
  174. if ( pMemberInfo->prCurrentLinkage == pMemberInfo->prHeadLinkage )
  175. {
  176. //
  177. // Rather than dumping the head list item, dump all the items on the list,
  178. // in summary form.
  179. //
  180. do
  181. {
  182. NextElement( pMemberInfo );
  183. if ( pMemberInfo->prCurrentLinkage != pMemberInfo->prHeadLinkage )
  184. {
  185. pbObject = (( PBYTE )pMemberInfo->prCurrentLinkage )
  186. - pMemberTable->cbOffsetToLink;
  187. pMemberTable->DumpStructure( ( ULONG )pbObject, VERBOSITY_ONE_LINER );
  188. dprintf( "\n" );
  189. }
  190. } while ( pMemberInfo->prCurrentLinkage != pMemberInfo->prHeadLinkage );
  191. }
  192. else
  193. {
  194. pbObject = (( PBYTE )pMemberInfo->prCurrentLinkage )
  195. - pMemberTable->cbOffsetToLink;
  196. pMemberTable->DumpStructure( ( ULONG )pbObject, VERBOSITY_NORMAL );
  197. }
  198. }
  199. VOID NextElement( PMEMBER_VARIABLE_INFO pMemberInfo )
  200. {
  201. ULONG NextLinkage;
  202. PMEMBER_TABLE pMember;
  203. pMember = &StructureTable[ pMemberInfo->StructureIndex ].pMemberTable[ pMemberInfo->MemberIndex ];
  204. if ( !pMember->Next( pMemberInfo->prCurrentLinkage, &NextLinkage ))
  205. {
  206. dprintf( "Command failed.\n" );
  207. return;
  208. }
  209. pMemberInfo->prCurrentLinkage = NextLinkage;
  210. pMemberInfo->cCurrentElement++;
  211. if ( pMemberInfo->prCurrentLinkage == pMemberInfo->prHeadLinkage )
  212. {
  213. pMemberInfo->cCurrentElement = 0;
  214. }
  215. }
  216. BOOL NextListEntry( ULONG Current, PULONG Next )
  217. {
  218. ULONG result;
  219. ULONG prNextEntry;
  220. LIST_ENTRY Entry;
  221. LIST_ENTRY NextEntry;
  222. if ( !ReadMemory( Current,
  223. &Entry,
  224. sizeof( Entry ),
  225. &result ))
  226. {
  227. dprintf( "Couldn't read current list entry at 0x%08X.\n", Current );
  228. return( FALSE );
  229. }
  230. prNextEntry = ( ULONG )Entry.Flink;
  231. if ( !ReadMemory( prNextEntry,
  232. &NextEntry,
  233. sizeof( NextEntry ),
  234. &result ))
  235. {
  236. dprintf( "Couldn't read next list entry at 0x%08X.\n", prNextEntry );
  237. return( FALSE );
  238. }
  239. if ( ( ULONG )NextEntry.Blink != Current )
  240. {
  241. dprintf( "Next entry's Blink doesn't match current entry's address.\n" );
  242. dprintf( "The list might be corrupt, or you may be using traversal state saved before the list changed.\n" );
  243. return( FALSE );
  244. }
  245. *Next = prNextEntry;
  246. return( TRUE );
  247. }
  248. VOID PrevElement( PMEMBER_VARIABLE_INFO pMemberInfo )
  249. {
  250. ULONG PrevLinkage;
  251. PMEMBER_TABLE pMember;
  252. pMember = &StructureTable[ pMemberInfo->StructureIndex ].pMemberTable[ pMemberInfo->MemberIndex ];
  253. if ( !pMember->Prev( pMemberInfo->prCurrentLinkage, &PrevLinkage ))
  254. {
  255. dprintf( "Command failed.\n" );
  256. return;
  257. }
  258. pMemberInfo->prCurrentLinkage = PrevLinkage;
  259. pMemberInfo->cCurrentElement++;
  260. if ( pMemberInfo->prCurrentLinkage == pMemberInfo->prHeadLinkage )
  261. {
  262. pMemberInfo->cCurrentElement = 0;
  263. }
  264. }
  265. BOOL PrevListEntry( ULONG Current, PULONG Prev )
  266. {
  267. ULONG result;
  268. ULONG prPrevEntry;
  269. LIST_ENTRY Entry;
  270. LIST_ENTRY PrevEntry;
  271. if ( !ReadMemory( Current,
  272. &Entry,
  273. sizeof( Entry ),
  274. &result ))
  275. {
  276. dprintf( "Couldn't read current list entry at 0x%08X.\n", Current );
  277. return( FALSE );
  278. }
  279. prPrevEntry = ( ULONG )Entry.Blink;
  280. if ( !ReadMemory( prPrevEntry,
  281. &PrevEntry,
  282. sizeof( PrevEntry ),
  283. &result ))
  284. {
  285. dprintf( "Couldn't read previous list entry at 0x%08X.\n", prPrevEntry );
  286. return( FALSE );
  287. }
  288. if ( ( ULONG )PrevEntry.Blink != Current )
  289. {
  290. dprintf( "Previous entry's Blink doesn't match current entry's address.\n" );
  291. dprintf( "The list might be corrupt, or you may be using traversal state saved before the list changed.\n" );
  292. return( FALSE );
  293. }
  294. *Prev = prPrevEntry;
  295. return( TRUE );
  296. }
  297. BOOL ReadArgsForTraverse( const char *args, char *VarName )
  298. {
  299. PCHAR pchListVar;
  300. int index;
  301. BOOL bRetval = FALSE;
  302. pchListVar = strstr( args, "-l" );
  303. if ( pchListVar )
  304. {
  305. pchListVar += 2;
  306. while ( *pchListVar == ' ' )
  307. {
  308. pchListVar ++;
  309. }
  310. if ( *pchListVar == '\0' )
  311. {
  312. dprintf( "NOT IMPLEMENTED: usage on -l\n" );
  313. return( bRetval );
  314. }
  315. for ( index = 0; index < MAX_LIST_VARIABLE_NAME_LENGTH; index ++ )
  316. {
  317. VarName[ index ] = *pchListVar;
  318. if ( *pchListVar == ' ' || *pchListVar == '\0' )
  319. {
  320. VarName[ index ] = '\0';
  321. break;
  322. }
  323. VarName[ index + 1 ] = '\0';
  324. pchListVar ++;
  325. }
  326. bRetval = TRUE;
  327. }
  328. return( bRetval );
  329. }