windows-nt/Source/XPSP1/NT/base/tools/ntsdexts/secexts.c
2020-09-26 16:20:57 +08:00

980 lines
29 KiB
C

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
Abstract:
This function contains the default ntsd debugger extensions
Author:
Revision History:
--*/
char * AccessMask[] = { "Delete", "ReadControl", "WriteDac", "WriteOwner",
"Synch", "", "", "",
"Sacl", "MaxAllowed", "", "",
"GenericAll", "GenericExec", "GenericWrite", "GenericRead"};
char * TokenRights[] = {"AssignPrimary", "Duplicate", "Impersonate", "Query",
"QuerySource", "AdjustPriv", "AdjustGroup", "AdjustDef"};
char * KeyRights[] = { "QueryValue", "SetValue", "CreateSubKey", "EnumSubKey",
"Notify", "CreateLink", "", "" };
char * EventRights[] = {"QueryState", "ModifyState" };
char * MutantRights[]={ "QueryState" };
char * SemaphoreRights[] = { "QueryState", "ModifyState" };
char * TimerRights[] = {"QueryState", "ModifyState" };
char * ProfileRights[]={"Control"};
char * ProcessRights[]={"Terminate", "CreateThread", "", "VMOp",
"VMRead", "VMWrite", "DupHandle", "CreateProcess",
"SetQuota", "SetInfo", "QueryInfo", "SetPort" };
char * ThreadRights[] ={"Terminate", "Suspend", "Alert", "GetContext",
"SetContext", "SetInfo", "QueryInfo", "SetToken",
"Impersonate", "DirectImpersonate" };
char * SectionRights[]={"Query", "MapWrite", "MapRead", "MapExecute",
"Extend"};
char * FileRights[] = { "Read/List", "Write/Add", "Append/SubDir/CreatePipe", "ReadEA",
"WriteEA", "Execute/Traverse", "DelChild", "ReadAttr",
"WriteAttr"};
char * PortRights[] = { "Connect" };
char * DirRights[] = { "Query", "Traverse", "Create", "CreateSubdir" };
char * SymLinkRights[]={"Query" };
char * WinstaRights[]={ "EnumDesktops", "ReadAttr", "Clipboard", "CreateDesktop",
"WriteAttr", "GlobalAtom", "ExitWindows", "",
"Enumerate", "ReadScreen" };
char * DesktopRights[]={"ReadObjects", "CreateWindow", "CreateMenu", "HookControl",
"JournalRecord", "JournalPlayback", "Enumerate", "WriteObjects",
"SwitchDesktop" };
char * CompletionRights[] = { "Query", "Modify" };
char * ChannelRights[] = { "ReadMessage", "WriteMessage", "Query", "SetInfo" };
char * JobRights[] = { "AssignProcess", "SetAttr", "Query", "Terminate", "SetSecAttr" };
TCHAR * PrivNames[] = {
TEXT("Invalid"),
TEXT("Invalid"),
SE_CREATE_TOKEN_NAME,
SE_ASSIGNPRIMARYTOKEN_NAME,
SE_LOCK_MEMORY_NAME,
SE_MACHINE_ACCOUNT_NAME,
SE_TCB_NAME,
SE_SECURITY_NAME,
SE_TAKE_OWNERSHIP_NAME,
SE_LOAD_DRIVER_NAME,
SE_SYSTEM_PROFILE_NAME,
SE_PROF_SINGLE_PROCESS_NAME,
SE_INC_BASE_PRIORITY_NAME,
SE_CREATE_PAGEFILE_NAME,
SE_CREATE_PERMANENT_NAME,
SE_BACKUP_NAME,
SE_RESTORE_NAME,
SE_SHUTDOWN_NAME,
SE_DEBUG_NAME,
SE_AUDIT_NAME,
SE_SYSTEM_ENVIRONMENT_NAME,
SE_CHANGE_NOTIFY_NAME,
SE_REMOTE_SHUTDOWN_NAME,
SE_UNDOCK_NAME,
SE_SYNC_AGENT_NAME,
SE_ENABLE_DELEGATION_NAME
};
///////////////////////////////
char * TokenImpLevels[] = { "Anonymous", "Identification", "Impersonation", "Delegation" };
#define GetTokenImpersonationLevel( x ) \
( x <= SecurityDelegation ? TokenImpLevels[ x ] : "Invalid" )
#define GHI_TYPE 0x00000001
#define GHI_BASIC 0x00000002
#define GHI_NAME 0x00000004
#define GHI_SPECIFIC 0x00000008
#define GHI_VERBOSE 0x00000010
#define GHI_NOLOOKUP 0x00000020
#define GHI_SILENT 0x00000100
#define TYPE_NONE 0
#define TYPE_EVENT 1
#define TYPE_SECTION 2
#define TYPE_FILE 3
#define TYPE_PORT 4
#define TYPE_DIRECTORY 5
#define TYPE_LINK 6
#define TYPE_MUTANT 7
#define TYPE_WINSTA 8
#define TYPE_SEM 9
#define TYPE_KEY 10
#define TYPE_TOKEN 11
#define TYPE_PROCESS 12
#define TYPE_THREAD 13
#define TYPE_DESKTOP 14
#define TYPE_COMPLETE 15
#define TYPE_CHANNEL 16
#define TYPE_TIMER 17
#define TYPE_JOB 18
#define TYPE_WPORT 19
#define TYPE_MAX 20
LPWSTR pszTypeNames[TYPE_MAX] = { L"None", L"Event", L"Section", L"File",
L"Port", L"Directory", L"SymbolicLink",
L"Mutant", L"WindowStation", L"Semaphore",
L"Key", L"Token", L"Process", L"Thread",
L"Desktop", L"IoCompletion", L"Channel",
L"Timer", L"Job", L"WaitablePort" };
LPSTR pszTypeNamesA[TYPE_MAX] = { "None", "Event", "Section", "File",
"Port", "Directory", "SymbolicLink",
"Mutant", "WindowStation", "Semaphore",
"Key", "Token", "Process", "Thread",
"Desktop", "IoCompletion", "Channe",
"Timer", "Job", "WaitablePort" };
typedef VOID
( * TYPEINFOFN)(HANDLE hObject, DWORD Flags);
VOID EventInfo(HANDLE, ULONG);
VOID MutantInfo(HANDLE, ULONG);
VOID SemaphoreInfo(HANDLE, ULONG);
VOID TimerInfo(HANDLE, ULONG);
VOID SectionInfo(HANDLE, ULONG);
VOID KeyInfo(HANDLE, ULONG);
VOID ProcessInfo(HANDLE, ULONG);
VOID ThreadInfo(HANDLE, ULONG);
VOID TokenInfo(HANDLE, ULONG);
VOID IoCompleteInfo(HANDLE, ULONG);
VOID JobInfo( HANDLE, ULONG );
typedef struct _TYPEINFO {
PWSTR pszName;
char * * AccessRights;
DWORD NumberRights;
TYPEINFOFN Func;
} TYPEINFO, * PTYPEINFO;
TYPEINFO TypeNames[TYPE_MAX] = {
{ L"None", NULL, 0, 0 },
{ L"Event", EventRights, 2, EventInfo },
{ L"Section", SectionRights, 5, SectionInfo },
{ L"File", FileRights, 9, 0 },
{ L"Port", PortRights, 1, 0 },
{ L"Directory", DirRights, 4, 0 },
{ L"SymbolicLink", SymLinkRights, 1, 0 },
{ L"Mutant", MutantRights, 2, MutantInfo },
{ L"WindowStation", WinstaRights, 10, 0 },
{ L"Semaphore", SemaphoreRights, 2, SemaphoreInfo },
{ L"Key", KeyRights, 6, KeyInfo },
{ L"Token", TokenRights, 8, TokenInfo },
{ L"Process", ProcessRights, 12, ProcessInfo },
{ L"Thread", ThreadRights, 10, ThreadInfo },
{ L"Desktop", DesktopRights, 10, 0 },
{ L"IoCompletion", CompletionRights, 2, IoCompleteInfo },
{ L"Channel", ChannelRights, 4, 0},
{ L"Timer", TimerRights, 2, TimerInfo },
{ L"Job", JobRights, 5, JobInfo },
{ L"WaitablePort", PortRights, 1, 0 }
};
void DisplayFlags( DWORD Flags,
DWORD FlagLimit,
char *flagset[],
UCHAR * buffer)
{
char * offset;
DWORD mask, test, i;
DWORD scratch;
if (!Flags) {
strcpy((CHAR *)buffer, "None");
return;
}
mask = 0;
offset = (CHAR *) buffer;
test = 1;
for (i = 0 ; i < FlagLimit ; i++ ) {
if (Flags & test) {
scratch = sprintf(offset, "%s", flagset[i]);
offset += scratch;
mask |= test;
if (Flags & (~mask)) {
*offset++ = ',';
}
}
test <<= 1;
}
}
VOID
EventInfo(
HANDLE hEvent,
DWORD Flags)
{
EVENT_BASIC_INFORMATION Info;
NTSTATUS Status;
Status = NtQueryEvent( hEvent,
EventBasicInformation,
&Info,
sizeof( Info ),
NULL );
if (NT_SUCCESS( Status ) )
{
dprintf(" Event Type %s\n", Info.EventType == SynchronizationEvent ?
"Auto Reset" : "Manual Reset" );
dprintf(" Event is %s\n", Info.EventState ? "Set" : "Waiting" );
}
}
VOID
SemaphoreInfo(
HANDLE hSem,
DWORD Flags)
{
SEMAPHORE_BASIC_INFORMATION Info;
NTSTATUS Status;
Status = NtQuerySemaphore( hSem,
SemaphoreBasicInformation,
&Info,
sizeof( Info ),
NULL );
if (NT_SUCCESS( Status ) )
{
dprintf(" Semaphore Count %d\n", Info.CurrentCount );
dprintf(" Semaphore Limit %d\n", Info.MaximumCount );
}
}
VOID
MutantInfo(
HANDLE hMutant,
DWORD Flags)
{
MUTANT_BASIC_INFORMATION Info;
NTSTATUS Status;
Status = NtQueryMutant( hMutant,
MutantBasicInformation,
&Info,
sizeof( Info ),
NULL );
if (NT_SUCCESS( Status ) )
{
dprintf(" Mutex is %s\n", Info.CurrentCount ? "Free" : "Owned" );
if ( Info.AbandonedState )
{
dprintf(" Mutex is abandoned\n");
}
}
}
VOID
TimerInfo(
HANDLE hTimer,
DWORD Flags)
{
TIMER_BASIC_INFORMATION Info;
NTSTATUS Status;
Status = NtQueryTimer( hTimer,
TimerBasicInformation,
&Info,
sizeof( Info ),
NULL );
if (NT_SUCCESS( Status ) )
{
dprintf(" Timer is %s\n", Info.TimerState ? "signalled" : "waiting" );
dprintf(" Remaining time %d\n", (DWORD) Info.RemainingTime.QuadPart );
}
}
VOID
SectionInfo(
HANDLE hSection,
DWORD Flags)
{
SECTION_BASIC_INFORMATION Info;
NTSTATUS Status;
Status = NtQuerySection( hSection,
SectionBasicInformation,
&Info,
sizeof( Info ),
NULL );
if ( NT_SUCCESS( Status ) )
{
dprintf(" Section base address %#x\n", Info.BaseAddress );
dprintf(" Section attributes %#x\n", Info.AllocationAttributes );
dprintf(" Section max size %#x\n", (DWORD) Info.MaximumSize.QuadPart );
}
}
VOID
KeyInfo(
HANDLE hKey,
DWORD Flags)
{
PKEY_BASIC_INFORMATION pInfo;
NTSTATUS Status;
SYSTEMTIME st;
FILETIME lft;
ULONG Length;
pInfo = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, 1024);
if ( pInfo )
{
Status = NtQueryKey( hKey,
KeyBasicInformation,
pInfo,
1024,
&Length );
if ( NT_SUCCESS( Status ) )
{
FileTimeToLocalFileTime( (FILETIME *) &pInfo->LastWriteTime,
& lft );
FileTimeToSystemTime( &lft, &st );
dprintf(" Key last write time: %02d:%02d:%02d. %d/%d/%d\n",
st.wHour, st.wMinute, st.wSecond, st.wMonth,
st.wDay, st.wYear );
dprintf(" Key name %ws\n", pInfo->Name );
}
LocalFree( pInfo );
}
}
VOID
ProcessInfo(
HANDLE hProcess,
DWORD Flags)
{
PROCESS_BASIC_INFORMATION Info;
NTSTATUS Status;
Status = NtQueryInformationProcess( hProcess,
ProcessBasicInformation,
&Info,
sizeof( Info ),
NULL );
if ( NT_SUCCESS( Status ) )
{
dprintf(" Process Id %d\n", Info.UniqueProcessId );
dprintf(" Parent Process %d\n", Info.InheritedFromUniqueProcessId );
dprintf(" Base Priority %d\n", Info.BasePriority );
}
}
VOID
ThreadInfo(
HANDLE hThread,
DWORD Flags)
{
THREAD_BASIC_INFORMATION Info;
NTSTATUS Status;
PVOID StartAddr ;
CHAR Buffer[ 128 ];
DWORD_PTR Offset ;
Status = NtQueryInformationThread( hThread,
ThreadBasicInformation,
&Info,
sizeof( Info ),
NULL );
if ( NT_SUCCESS( Status ) )
{
dprintf(" Thread Id %d.%d\n", Info.ClientId.UniqueProcess, Info.ClientId.UniqueThread );
dprintf(" Priority %d\n", Info.Priority );
dprintf(" Base Priority %d\n", Info.BasePriority );
}
Status = NtQueryInformationThread( hThread,
ThreadQuerySetWin32StartAddress,
&StartAddr,
sizeof( PVOID ),
NULL );
if ( NT_SUCCESS( Status ) )
{
Buffer[0] = '\0';
GetSymbol( StartAddr, Buffer, &Offset );
dprintf(" Start Address %x %s\n",
StartAddr, Buffer[0] ? Buffer : "" );
}
}
VOID
IoCompleteInfo(
HANDLE hIoCompletionPort,
DWORD Flags)
{
IO_COMPLETION_BASIC_INFORMATION Info;
NTSTATUS Status;
Status = NtQueryIoCompletion( hIoCompletionPort,
IoCompletionBasicInformation,
&Info,
sizeof( Info ),
NULL );
if ( NT_SUCCESS( Status ) )
{
dprintf(" Depth %d\n", Info.Depth );
}
}
VOID
TokenInfo(
HANDLE hToken,
DWORD Flags)
{
TOKEN_STATISTICS Stats;
UCHAR Buffer[ 1024 ];
PTOKEN_USER pUser;
PTOKEN_GROUPS pGroups;
PTOKEN_PRIVILEGES pPrivs ;
ULONG Size;
NTSTATUS Status;
UNICODE_STRING s;
WCHAR Name[ 64 ];
WCHAR Domain[ 64 ];
DWORD NameSize;
DWORD DomainSize;
SID_NAME_USE Use;
BOOL FoundName;
ULONG Index;
Status = NtQueryInformationToken( hToken,
TokenStatistics,
&Stats,
sizeof(Stats),
&Size );
if ( NT_SUCCESS( Status ) )
{
dprintf(" Auth Id %#x : %#x\n", Stats.AuthenticationId.HighPart, Stats.AuthenticationId.LowPart );
dprintf(" Type %s\n", Stats.TokenType == TokenPrimary ? "Primary" : "Impersonation" );
dprintf(" Imp Level %s\n", GetTokenImpersonationLevel( Stats.ImpersonationLevel ) );
if ( Flags & GHI_VERBOSE )
{
dprintf(" Token Id %#x : %#x \n", Stats.TokenId.HighPart, Stats.TokenId.LowPart );
dprintf(" Mod Id %#x : %#x \n", Stats.ModifiedId.HighPart, Stats.ModifiedId.LowPart );
dprintf(" Dyn Chg %#x\n", Stats.DynamicCharged );
dprintf(" Dyn Avail %#x\n", Stats.DynamicAvailable );
dprintf(" Groups %d\n", Stats.GroupCount );
dprintf(" Privs %d\n", Stats.PrivilegeCount );
pUser = (PTOKEN_USER) Buffer;
Status = NtQueryInformationToken( hToken,
TokenUser,
Buffer,
sizeof(Buffer),
&Size );
if (NT_SUCCESS( Status ) )
{
FoundName = FALSE ;
if ( !(Flags & GHI_NOLOOKUP) )
{
NameSize = 64 ;
DomainSize = 64 ;
if ( LookupAccountSidW( NULL,
pUser->User.Sid,
Name,
&NameSize,
Domain,
&DomainSize,
&Use ) )
{
dprintf(" User %ws\\%ws\n", Domain, Name );
FoundName = TRUE;
}
}
if ( (Flags & GHI_NOLOOKUP) || (!FoundName) )
{
RtlConvertSidToUnicodeString( &s, pUser->User.Sid, TRUE );
dprintf(" User %ws\n", s.Buffer );
RtlFreeUnicodeString( &s );
}
}
pGroups = (PTOKEN_GROUPS) Buffer;
Status = NtQueryInformationToken( hToken,
TokenGroups,
Buffer,
sizeof(Buffer),
&Size );
if ( NT_SUCCESS( Status ) )
{
dprintf(" Groups %d\n", pGroups->GroupCount );
for ( Index = 0 ; Index < pGroups->GroupCount ; Index++ )
{
FoundName = FALSE ;
if ( !(Flags & GHI_NOLOOKUP) )
{
NameSize = 64 ;
DomainSize = 64 ;
if ( LookupAccountSidW( NULL,
pGroups->Groups[Index].Sid,
Name,
&NameSize,
Domain,
&DomainSize,
&Use ) )
{
dprintf(" %ws\\%ws\n", Domain, Name );
FoundName = TRUE;
}
}
if ( ( Flags & GHI_NOLOOKUP ) || ( !FoundName ) )
{
RtlConvertSidToUnicodeString( &s,
pGroups->Groups[Index].Sid,
TRUE );
dprintf(" %ws\n", s.Buffer );
RtlFreeUnicodeString( &s );
}
}
}
pPrivs = (PTOKEN_PRIVILEGES) Buffer ;
Status = NtQueryInformationToken( hToken,
TokenPrivileges,
Buffer,
sizeof(Buffer),
&Size );
if ( NT_SUCCESS( Status ) )
{
dprintf(" Privileges %d\n", pPrivs->PrivilegeCount );
for ( Index = 0 ; Index < pPrivs->PrivilegeCount ; Index++ )
{
dprintf(" %s (%s%s)\n",
PrivNames[ pPrivs->Privileges[ Index ].Luid.LowPart ],
pPrivs->Privileges[ Index ].Attributes & SE_PRIVILEGE_ENABLED ? " Enabled " : " ",
pPrivs->Privileges[ Index ].Attributes & SE_PRIVILEGE_ENABLED_BY_DEFAULT ? "Default " : ""
);
}
}
}
}
}
VOID
JobInfo(
HANDLE Job,
ULONG Flags
)
{
JOBOBJECT_BASIC_ACCOUNTING_INFORMATION BasicInfo ;
UCHAR Buffer[ 128 * sizeof( ULONG_PTR ) ];
PJOBOBJECT_BASIC_PROCESS_ID_LIST ProcList ;
NTSTATUS Status ;
ULONG Size ;
TIME_FIELDS Time ;
//
// Delay load this API since it does not exist on NT 4
//
typedef NTSTATUS (NTAPI* PNTQUERYJOB)(HANDLE, JOBOBJECTINFOCLASS, PVOID, LONG, PULONG);
HMODULE hNtdll;
PNTQUERYJOB pNtQueryJob;
hNtdll = GetModuleHandle( "ntdll.dll" );
if (!hNtdll) {
dprintf("Unable to get module handle for ntdll.dll\n");
return;
}
pNtQueryJob =
(PNTQUERYJOB)GetProcAddress( hNtdll, "NtQueryInformationJobObject" );
if (pNtQueryJob == NULL) {
dprintf("Unable to get address of NtQueryInformationJobObject\n");
return;
}
Status = pNtQueryJob(
Job,
JobObjectBasicAccountingInformation,
&BasicInfo,
sizeof( BasicInfo ),
&Size );
if ( NT_SUCCESS( Status ) )
{
RtlTimeToElapsedTimeFields( &BasicInfo.TotalUserTime, &Time );
dprintf( " TotalUserTime \t%3ld:%02ld:%02ld.%04ld\n",
Time.Hour,
Time.Minute,
Time.Second,
Time.Milliseconds );
RtlTimeToElapsedTimeFields( &BasicInfo.TotalKernelTime, &Time );
dprintf( " TotalKernelTime \t%3ld:%02ld:%02ld.%04ld\n",
Time.Hour,
Time.Minute,
Time.Second,
Time.Milliseconds );
dprintf( " TotalProcesses \t%x\n",
BasicInfo.TotalProcesses );
dprintf( " ActiveProcesses \t%x\n",
BasicInfo.ActiveProcesses );
dprintf( " TotalPageFaultCount\t%x\n",
BasicInfo.TotalPageFaultCount );
if ( BasicInfo.ActiveProcesses )
{
ProcList = (PJOBOBJECT_BASIC_PROCESS_ID_LIST) Buffer ;
Status = pNtQueryJob(
Job,
JobObjectBasicProcessIdList,
ProcList,
sizeof( Buffer ),
&Size );
if ( NT_SUCCESS( Status ) )
{
ULONG i ;
dprintf( " Processes:\n" );
for (i = 0 ; i < ProcList->NumberOfProcessIdsInList ; i++ )
{
dprintf( " %x\n", ProcList->ProcessIdList[ i ] );
}
}
}
}
}
DWORD
GetObjectTypeIndex(
LPCSTR pszTypeName )
{
WCHAR TypeName[ MAX_PATH ];
DWORD i;
mbstowcs( TypeName, pszTypeName, strlen( pszTypeName ) + 1 );
for ( i = 1 ; i < TYPE_MAX ; i++ )
{
if (_wcsicmp( TypeNames[i].pszName, TypeName ) == 0 )
{
return( i );
}
}
return( (DWORD) -1 );
}
DWORD
GetHandleInfoDirect(
HANDLE hProcess,
HANDLE hThere,
DWORD Flags,
DWORD * Type)
{
HANDLE hHere;
NTSTATUS Status;
POBJECT_TYPE_INFORMATION pTypeInfo;
POBJECT_NAME_INFORMATION pNameInfo;
POBJECT_BASIC_INFORMATION pBasicInfo;
UCHAR Buffer[1024];
DWORD SuccessCount = 0;
DWORD i;
UCHAR szBuf[256];
if (!DuplicateHandle( hProcess, hThere,
GetCurrentProcess(), &hHere,
0, FALSE,
DUPLICATE_SAME_ACCESS) )
{
if ( (Flags & GHI_SILENT) == 0)
{
dprintf("Could not duplicate handle %x, error %d\n",
hThere, GetLastError() );
}
return( 0 );
}
pTypeInfo = (POBJECT_TYPE_INFORMATION) Buffer;
pNameInfo = (POBJECT_NAME_INFORMATION) Buffer;
pBasicInfo = (POBJECT_BASIC_INFORMATION) Buffer;
if ( (Flags & GHI_SILENT) == 0)
{
dprintf("Handle %x\n", hThere );
}
if (Flags & GHI_TYPE)
{
ZeroMemory( Buffer, 1024 );
Status = NtQueryObject( hHere, ObjectTypeInformation, pTypeInfo, 1024, NULL );
if (NT_SUCCESS(Status))
{
if ((Flags & GHI_SILENT) == 0)
{
dprintf(" Type \t%ws\n", pTypeInfo->TypeName.Buffer );
}
for (i = 1; i < TYPE_MAX ; i++ )
{
if (wcscmp(pTypeInfo->TypeName.Buffer, TypeNames[i].pszName) == 0)
{
*Type = i;
break;
}
}
if (i == TYPE_MAX)
{
*Type = 0;
}
SuccessCount++;
}
}
if (Flags & GHI_BASIC)
{
ZeroMemory( Buffer, 1024 );
Status = NtQueryObject(hHere, ObjectBasicInformation, pBasicInfo,
sizeof( OBJECT_BASIC_INFORMATION), NULL);
if (NT_SUCCESS(Status))
{
dprintf(" Attributes \t%#x\n", pBasicInfo->Attributes );
dprintf(" GrantedAccess\t%#x:\n", pBasicInfo->GrantedAccess );
DisplayFlags( pBasicInfo->GrantedAccess >> 16,
16,
AccessMask,
szBuf);
dprintf(" %s\n", szBuf);
DisplayFlags( pBasicInfo->GrantedAccess & 0xFFFF,
TypeNames[ *Type ].NumberRights,
TypeNames[ *Type ].AccessRights,
szBuf);
dprintf(" %s\n", szBuf);
dprintf(" HandleCount \t%d\n", pBasicInfo->HandleCount );
dprintf(" PointerCount \t%d\n", pBasicInfo->PointerCount );
SuccessCount++;
}
else
{
if ( Status != STATUS_INVALID_HANDLE )
{
dprintf("unable to query object information\n");
}
}
}
if ( (Flags & GHI_NAME) &&
(*Type != TYPE_FILE ) )
{
ZeroMemory( Buffer, 1024 );
Status = NtQueryObject( hHere, ObjectNameInformation, pNameInfo, 1024, NULL );
if (NT_SUCCESS(Status))
{
dprintf(" Name \t%ws\n", pNameInfo->Name.Buffer ?
pNameInfo->Name.Buffer : L"<none>" );
SuccessCount++;
}
else
{
if ( Status != STATUS_INVALID_HANDLE )
{
dprintf("unable to query object information\n");
}
}
}
if ( Flags & GHI_SPECIFIC )
{
if ( TypeNames[ *Type ].Func )
{
dprintf(" Object Specific Information\n");
TypeNames[ *Type ].Func( hHere, Flags );
}
}
NtClose( hHere );
return( SuccessCount );
}
DWORD
GetHandleInfoInterface(
HANDLE hThere,
DWORD Flags,
DWORD * Type)
{
ULONG64 IfHandle = (ULONG_PTR)hThere;
HRESULT Status;
DWORD SuccessCount = 0;
DWORD i;
UCHAR Buffer[1024];
UCHAR szBuf[256];
if ( (Flags & GHI_SILENT) == 0)
{
dprintf("Handle %I64x\n", IfHandle );
}
if (Flags & GHI_TYPE)
{
if (g_ExtData2->lpVtbl->
ReadHandleData(g_ExtData2, IfHandle,
DEBUG_HANDLE_DATA_TYPE_TYPE_NAME,
Buffer, sizeof(Buffer), NULL) == S_OK)
{
if ((Flags & GHI_SILENT) == 0)
{
dprintf(" Type \t%s\n", Buffer);
}
for (i = 1; i < TYPE_MAX ; i++ )
{
if (strcmp((LPSTR)Buffer, pszTypeNamesA[i]) == 0)
{
*Type = i;
break;
}
}
if (i == TYPE_MAX)
{
*Type = 0;
}
SuccessCount++;
}
}
if (Flags & GHI_BASIC)
{
DEBUG_HANDLE_DATA_BASIC Basic;
if (g_ExtData2->lpVtbl->
ReadHandleData(g_ExtData2, IfHandle,
DEBUG_HANDLE_DATA_TYPE_BASIC,
&Basic, sizeof(Basic), NULL) == S_OK)
{
dprintf(" Attributes \t%#x\n", Basic.Attributes );
dprintf(" GrantedAccess\t%#x:\n", Basic.GrantedAccess );
DisplayFlags( Basic.GrantedAccess >> 16,
16,
AccessMask,
szBuf);
dprintf(" %s\n", szBuf);
DisplayFlags( Basic.GrantedAccess & 0xFFFF,
TypeNames[ *Type ].NumberRights,
TypeNames[ *Type ].AccessRights,
szBuf);
dprintf(" %s\n", szBuf);
dprintf(" HandleCount \t%d\n", Basic.HandleCount );
dprintf(" PointerCount \t%d\n", Basic.PointerCount );
SuccessCount++;
}
else
{
dprintf("unable to query object information\n");
}
}
if ( (Flags & GHI_NAME) &&
(*Type != TYPE_FILE ) )
{
if (g_ExtData2->lpVtbl->
ReadHandleData(g_ExtData2, IfHandle,
DEBUG_HANDLE_DATA_TYPE_OBJECT_NAME,
Buffer, sizeof(Buffer), NULL) == S_OK)
{
dprintf(" Name \t%s\n",
Buffer[0] ? Buffer : "<none>" );
SuccessCount++;
}
else
{
dprintf("unable to query object information\n");
}
}
if ( Flags & GHI_SPECIFIC )
{
dprintf(" No object specific information available\n");
}
return( SuccessCount );
}
DWORD
GetHandleInfo(
BOOL Direct,
HANDLE hProcess,
HANDLE hThere,
DWORD Flags,
DWORD * Type)
{
if (Direct) {
return GetHandleInfoDirect(hProcess, hThere, Flags, Type);
} else {
return GetHandleInfoInterface(hThere, Flags, Type);
}
}