windows-nt/Source/XPSP1/NT/net/netbeui/kdext/traverse.c
2020-09-26 16:20:57 +08:00

418 lines
10 KiB
C

#include "precomp.h"
#pragma hdrstop
MEMBER_VARIABLE_INFO _MemberInfo;
#define STATE_FILENAME "tcpipext.state"
STRUCTURE_TABLE StructureTable[] =
{
{ NULL }
};
BOOL NextListEntry( ULONG Current, PULONG Next );
BOOL PrevListEntry( ULONG Current, PULONG Prev );
VOID NextElement( PMEMBER_VARIABLE_INFO pMemberInfo );
VOID PrevElement( PMEMBER_VARIABLE_INFO pMemberInfo );
VOID DumpListItem( PMEMBER_VARIABLE_INFO pMemberInfo );
BOOL
LocateMemberVariable
(
PCHAR pchStructName,
PCHAR pchMemberName,
PVOID pvStructure,
PMEMBER_VARIABLE_INFO pMemberInfo
)
{
BOOL bMatch;
int index;
PMEMBER_TABLE pMemberTable;
CHAR pchCurrent[ MAX_LIST_VARIABLE_NAME_LENGTH + 1 ];
CHAR _pchStructName[ MAX_LIST_VARIABLE_NAME_LENGTH + 1 ];
CHAR _pchMemberName[ MAX_LIST_VARIABLE_NAME_LENGTH + 1 ];
dprintf( "LocateMemberVariable( \"%s\", \"%s\", 0x%08X )\n", pchStructName, pchMemberName, pMemberInfo );
strcpy( _pchStructName, pchStructName );
strcpy( _pchMemberName, pchMemberName );
_strupr( _pchStructName );
_strupr( _pchMemberName );
pMemberInfo->StructureIndex = 0;
pMemberInfo->MemberIndex = 0;
bMatch = FALSE;
for ( index = 0; StructureTable[ index ].pchStructName != NULL; index ++ )
{
strcpy( pchCurrent, StructureTable[ index ].pchStructName );
_strupr( pchCurrent );
if ( strstr( pchCurrent, _pchStructName ))
{
if ( bMatch )
{
dprintf( "The specified structure name is ambiguous.\n" );
return( FALSE );
}
pMemberInfo->StructureIndex = index;
bMatch = TRUE;
}
}
if ( !bMatch )
{
dprintf( "No matching structure name was found.\n" );
return( FALSE );
}
pMemberTable = StructureTable[ pMemberInfo->StructureIndex ].pMemberTable;
bMatch = FALSE;
for ( index = 0; pMemberTable[ index ].pchMemberName != NULL; index ++ )
{
strcpy( pchCurrent, pMemberTable[ index ].pchMemberName );
_strupr( pchCurrent );
if ( strstr( pchCurrent, _pchMemberName ))
{
if ( bMatch )
{
dprintf( "The variable specified is ambiguous.\n" );
return( FALSE );
}
pMemberInfo->MemberIndex = index;
bMatch = TRUE;
}
}
if ( !bMatch )
{
dprintf( "No matching member name was found in the %s structure.\n", pchStructName );
return( FALSE );
}
pMemberInfo->prHeadContainingObject = ( ULONG )pvStructure;
pMemberInfo->prHeadLinkage = (( ULONG )pvStructure ) + pMemberTable[ pMemberInfo->MemberIndex ].cbOffsetToHead;
pMemberInfo->prCurrentLinkage = pMemberInfo->prHeadLinkage;
pMemberInfo->cCurrentElement = 0;
return( TRUE );
}
BOOL WriteMemberInfo( PMEMBER_VARIABLE_INFO pMemberInfo )
{
HANDLE hStateFile;
DWORD dwWritten;
hStateFile = CreateFile( STATE_FILENAME,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL );
if ( hStateFile == INVALID_HANDLE_VALUE )
{
dprintf( "Can't create state file\n" );
return( FALSE );
}
if ( !WriteFile( hStateFile,
pMemberInfo,
sizeof( MEMBER_VARIABLE_INFO ),
&dwWritten,
NULL ) || ( dwWritten != sizeof( MEMBER_VARIABLE_INFO )))
{
dprintf( "Can't write to state file\n" );
CloseHandle( hStateFile );
return( FALSE );
}
CloseHandle( hStateFile );
return( TRUE );
}
BOOL ReadMemberInfo( PMEMBER_VARIABLE_INFO pMemberInfo )
{
HANDLE hStateFile;
DWORD dwRead;
hStateFile = CreateFile( STATE_FILENAME,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
if ( hStateFile == INVALID_HANDLE_VALUE )
{
dprintf( "Can't open state file\n" );
return( FALSE );
}
if ( !ReadFile( hStateFile,
pMemberInfo,
sizeof( MEMBER_VARIABLE_INFO ),
&dwRead,
NULL ) || ( dwRead != sizeof( MEMBER_VARIABLE_INFO )))
{
dprintf( "Can't read from state file\n" );
CloseHandle( hStateFile );
return( FALSE );
}
CloseHandle( hStateFile );
return( TRUE );
}
DECLARE_API( next )
{
MEMBER_VARIABLE_INFO MemberInfo;
if ( !ReadMemberInfo( &MemberInfo ) )
{
return;
}
NextElement( &MemberInfo );
DumpListItem( &MemberInfo );
WriteMemberInfo( &MemberInfo );
}
DECLARE_API( prev )
{
MEMBER_VARIABLE_INFO MemberInfo;
if ( !ReadMemberInfo( &MemberInfo ) )
{
return;
}
PrevElement( &MemberInfo );
DumpListItem( &MemberInfo );
WriteMemberInfo( &MemberInfo );
}
VOID DumpListItem( PMEMBER_VARIABLE_INFO pMemberInfo )
{
PBYTE pbObject;
PMEMBER_TABLE pMemberTable;
dprintf( "Focus is on: %s.%s, element # %d\n",
StructureTable[ pMemberInfo->StructureIndex ].pchStructName,
StructureTable[ pMemberInfo->StructureIndex ].pMemberTable[ pMemberInfo->MemberIndex ].pchMemberName,
pMemberInfo->cCurrentElement );
pMemberTable = &StructureTable[ pMemberInfo->StructureIndex ].pMemberTable[ pMemberInfo->MemberIndex ];
if ( pMemberInfo->prCurrentLinkage == pMemberInfo->prHeadLinkage )
{
//
// Rather than dumping the head list item, dump all the items on the list,
// in summary form.
//
do
{
NextElement( pMemberInfo );
if ( pMemberInfo->prCurrentLinkage != pMemberInfo->prHeadLinkage )
{
pbObject = (( PBYTE )pMemberInfo->prCurrentLinkage )
- pMemberTable->cbOffsetToLink;
pMemberTable->DumpStructure( ( ULONG )pbObject, VERBOSITY_ONE_LINER );
dprintf( "\n" );
}
} while ( pMemberInfo->prCurrentLinkage != pMemberInfo->prHeadLinkage );
}
else
{
pbObject = (( PBYTE )pMemberInfo->prCurrentLinkage )
- pMemberTable->cbOffsetToLink;
pMemberTable->DumpStructure( ( ULONG )pbObject, VERBOSITY_NORMAL );
}
}
VOID NextElement( PMEMBER_VARIABLE_INFO pMemberInfo )
{
ULONG NextLinkage;
PMEMBER_TABLE pMember;
pMember = &StructureTable[ pMemberInfo->StructureIndex ].pMemberTable[ pMemberInfo->MemberIndex ];
if ( !pMember->Next( pMemberInfo->prCurrentLinkage, &NextLinkage ))
{
dprintf( "Command failed.\n" );
return;
}
pMemberInfo->prCurrentLinkage = NextLinkage;
pMemberInfo->cCurrentElement++;
if ( pMemberInfo->prCurrentLinkage == pMemberInfo->prHeadLinkage )
{
pMemberInfo->cCurrentElement = 0;
}
}
BOOL NextListEntry( ULONG Current, PULONG Next )
{
ULONG result;
ULONG prNextEntry;
LIST_ENTRY Entry;
LIST_ENTRY NextEntry;
if ( !ReadMemory( Current,
&Entry,
sizeof( Entry ),
&result ))
{
dprintf( "Couldn't read current list entry at 0x%08X.\n", Current );
return( FALSE );
}
prNextEntry = ( ULONG )Entry.Flink;
if ( !ReadMemory( prNextEntry,
&NextEntry,
sizeof( NextEntry ),
&result ))
{
dprintf( "Couldn't read next list entry at 0x%08X.\n", prNextEntry );
return( FALSE );
}
if ( ( ULONG )NextEntry.Blink != Current )
{
dprintf( "Next entry's Blink doesn't match current entry's address.\n" );
dprintf( "The list might be corrupt, or you may be using traversal state saved before the list changed.\n" );
return( FALSE );
}
*Next = prNextEntry;
return( TRUE );
}
VOID PrevElement( PMEMBER_VARIABLE_INFO pMemberInfo )
{
ULONG PrevLinkage;
PMEMBER_TABLE pMember;
pMember = &StructureTable[ pMemberInfo->StructureIndex ].pMemberTable[ pMemberInfo->MemberIndex ];
if ( !pMember->Prev( pMemberInfo->prCurrentLinkage, &PrevLinkage ))
{
dprintf( "Command failed.\n" );
return;
}
pMemberInfo->prCurrentLinkage = PrevLinkage;
pMemberInfo->cCurrentElement++;
if ( pMemberInfo->prCurrentLinkage == pMemberInfo->prHeadLinkage )
{
pMemberInfo->cCurrentElement = 0;
}
}
BOOL PrevListEntry( ULONG Current, PULONG Prev )
{
ULONG result;
ULONG prPrevEntry;
LIST_ENTRY Entry;
LIST_ENTRY PrevEntry;
if ( !ReadMemory( Current,
&Entry,
sizeof( Entry ),
&result ))
{
dprintf( "Couldn't read current list entry at 0x%08X.\n", Current );
return( FALSE );
}
prPrevEntry = ( ULONG )Entry.Blink;
if ( !ReadMemory( prPrevEntry,
&PrevEntry,
sizeof( PrevEntry ),
&result ))
{
dprintf( "Couldn't read previous list entry at 0x%08X.\n", prPrevEntry );
return( FALSE );
}
if ( ( ULONG )PrevEntry.Blink != Current )
{
dprintf( "Previous entry's Blink doesn't match current entry's address.\n" );
dprintf( "The list might be corrupt, or you may be using traversal state saved before the list changed.\n" );
return( FALSE );
}
*Prev = prPrevEntry;
return( TRUE );
}
BOOL ReadArgsForTraverse( const char *args, char *VarName )
{
PCHAR pchListVar;
int index;
BOOL bRetval = FALSE;
pchListVar = strstr( args, "-l" );
if ( pchListVar )
{
pchListVar += 2;
while ( *pchListVar == ' ' )
{
pchListVar ++;
}
if ( *pchListVar == '\0' )
{
dprintf( "NOT IMPLEMENTED: usage on -l\n" );
return( bRetval );
}
for ( index = 0; index < MAX_LIST_VARIABLE_NAME_LENGTH; index ++ )
{
VarName[ index ] = *pchListVar;
if ( *pchListVar == ' ' || *pchListVar == '\0' )
{
VarName[ index ] = '\0';
break;
}
VarName[ index + 1 ] = '\0';
pchListVar ++;
}
bRetval = TRUE;
}
return( bRetval );
}