|
|
/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
proc.c
Abstract:
Code for dumping information about processes using the NT API rather than the win32 API.
Environment:
User mode only
Revision History:
03-26-96 : Created
--*/
//
// this module may be compiled at warning level 4 with the following
// warnings disabled:
//
#pragma warning(disable:4200) // array[0]
#pragma warning(disable:4201) // nameless struct/unions
#pragma warning(disable:4214) // bit fields other than int
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define PROCESS_BUFFER_INCREMENT (16 * 4096)
PSYSTEM_PROCESS_INFORMATION ProcessInfo = NULL; DWORD ProcessInfoLength;
VOID GetAllProcessInfo( VOID ) { PSYSTEM_PROCESS_INFORMATION buffer; DWORD bufferSize = 1 * PROCESS_BUFFER_INCREMENT;
NTSTATUS status;
assert(ProcessInfo == NULL);
do { buffer = LocalAlloc(LMEM_FIXED, bufferSize);
if(buffer == NULL) { return; }
status = NtQuerySystemInformation(SystemProcessInformation, buffer, bufferSize, &ProcessInfoLength);
if(status == STATUS_INFO_LENGTH_MISMATCH) {
LocalFree(buffer); bufferSize += PROCESS_BUFFER_INCREMENT; continue; }
} while(status == STATUS_INFO_LENGTH_MISMATCH);
if(NT_SUCCESS(status)) { ProcessInfo = buffer; } return; }
VOID PrintProcessInfo( DWORD_PTR ProcessId ) { PSYSTEM_PROCESS_INFORMATION info;
if(ProcessInfo == NULL) { return; }
info = ProcessInfo;
do {
if(ProcessId == (DWORD_PTR) info->UniqueProcessId) {
printf(": %.*S", (info->ImageName.Length / 2), info->ImageName.Buffer);
break; }
info = (PSYSTEM_PROCESS_INFORMATION) (((ULONG_PTR) info) + info->NextEntryOffset); } while((ULONG_PTR) info <= (ULONG_PTR) ProcessInfo + ProcessInfoLength);
return; }
#if 0
DWORD QueryDirectory( IN PSTRING DirectoryName ) { NTSTATUS Status; HANDLE DirectoryHandle, LinkHandle; ULONG Context = 0; ULONG i, ReturnedLength; UNICODE_STRING LinkTarget;
POBJECT_DIRECTORY_INFORMATION DirInfo; POBJECT_NAME_INFORMATION NameInfo; OBJECT_ATTRIBUTES Attributes; UNICODE_STRING UnicodeString;
//
// Perform initial setup
//
RtlZeroMemory( Buffer, BUFFERSIZE );
//
// Open the directory for list directory access
//
Status = RtlAnsiStringToUnicodeString( &UnicodeString, DirectoryName, TRUE );
ASSERT(NT_SUCCESS(Status));
InitializeObjectAttributes(&Attributes, &UnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL);
Status = NtOpenDirectoryObject(&DirectoryHandle, DIRECTORY_QUERY, &Attributes);
if(!NT_SUCCESS(Status)) { if (Status == STATUS_OBJECT_TYPE_MISMATCH) { printf("%Z is not a valid Object Directory Object name\n", DirectoryName ); } else { printf("Error %#08lx opening %Z\n", Status, DirectoryName); }
return; }
//
// Query the entire directory in one sweep
//
NumberOfDirEntries = 0; for (Status = NtQueryDirectoryObject( DirectoryHandle, &Buffer, BUFFERSIZE, FALSE, FALSE, &Context, &ReturnedLength ); NT_SUCCESS( Status ); Status = NtQueryDirectoryObject( DirectoryHandle, &Buffer, BUFFERSIZE, FALSE, FALSE, &Context, &ReturnedLength ) ) {
//
// Check the status of the operation.
//
if (!NT_SUCCESS( Status )) { if (Status != STATUS_NO_MORE_FILES) { Error( Status, Status ); } break; }
//
// For every record in the buffer type out the directory information
//
//
// Point to the first record in the buffer, we are guaranteed to have
// one otherwise Status would have been No More Files
//
DirInfo = (POBJECT_DIRECTORY_INFORMATION) &Buffer[0];
while (TRUE) {
//
// Check if there is another record. If there isn't, then get out
// of the loop now
//
if (DirInfo->Name.Length == 0) { break; }
//
// Print out information about the file
//
if (NumberOfDirEntries >= MAX_DIR_ENTRIES) { printf( "OBJDIR: Too many directory entries.\n" ); exit( 1 ); }
DirEntries[ NumberOfDirEntries ].Name = RtlAllocateHeap( RtlProcessHeap(), HEAP_ZERO_MEMORY, DirInfo->Name.Length + sizeof( UNICODE_NULL ) ); DirEntries[ NumberOfDirEntries ].Type = RtlAllocateHeap( RtlProcessHeap(), HEAP_ZERO_MEMORY, DirInfo->TypeName.Length + sizeof( UNICODE_NULL ) ); memmove( DirEntries[ NumberOfDirEntries ].Name, DirInfo->Name.Buffer, DirInfo->Name.Length ); memmove( DirEntries[ NumberOfDirEntries ].Type, DirInfo->TypeName.Buffer, DirInfo->TypeName.Length );
NumberOfDirEntries++;
//
// There is another record so advance DirInfo to the next entry
//
DirInfo = (POBJECT_DIRECTORY_INFORMATION) (((PUCHAR) DirInfo) + sizeof( OBJECT_DIRECTORY_INFORMATION ) );
}
RtlZeroMemory( Buffer, BUFFERSIZE );
}
qsort( DirEntries, NumberOfDirEntries, sizeof( DIR_ENTRY ), CompareDirEntry ); for (i=0; i<NumberOfDirEntries; i++) { printf( "%-32ws ", DirEntries[ i ].Name); if (CompoundLineOutput) { printf("\n "); } printf( "%ws", DirEntries[ i ].Type );
if (!wcscmp( DirEntries[ i ].Type, L"SymbolicLink" )) { RtlInitUnicodeString( &UnicodeString, DirEntries[ i ].Name ); InitializeObjectAttributes( &Attributes, &UnicodeString, OBJ_CASE_INSENSITIVE, DirectoryHandle, NULL ); Status = NtOpenSymbolicLinkObject( &LinkHandle, SYMBOLIC_LINK_QUERY, &Attributes ); if (NT_SUCCESS( Status )) { LinkTarget.Buffer = LinkTargetBuffer; LinkTarget.Length = 0; LinkTarget.MaximumLength = sizeof( LinkTargetBuffer ); Status = NtQuerySymbolicLinkObject( LinkHandle, &LinkTarget, NULL ); NtClose( LinkHandle ); }
if (!NT_SUCCESS( Status )) { printf( " - unable to query link target (Status == %09X)\n", Status ); } else { printf( " - %wZ\n", &LinkTarget ); } } else { printf( "\n" ); } }
//
// Output final messages
//
if (NumberOfDirEntries == 0) { printf( "no entries\n" ); } else if (NumberOfDirEntries == 1) { printf( "\n1 entry\n" ); } else { printf( "\n%ld entries\n", NumberOfDirEntries ); }
//
// Now close the directory object
//
(VOID) NtClose( DirectoryHandle );
//
// And return to our caller
//
return;
} #endif
|