I check the Irp->RequestorMode flag in my IRP_MJ_READ dispatch routine. If this flag is UserMode, Irp->UserBuffer pointer is valid only in this thread context.
I guess here in dispatch routine is the right place where I can call my function to obtain process name. I use this function:
NTSTATUS GetCurrentProcessImageName( PUNICODE_STRING ProcessImageName )
{
NTSTATUS Status;
ULONG ReturnedLength;
PVOID pBuffer;
PROCESS_BASIC_INFORMATION* pBasicInfo;
PPEB pPeb;
UNICODE_STRING UnicodeString;
if ( NULL == ZwQueryInformationProcess )
{
UNICODE_STRING RoutineName;
RtlInitUnicodeString( &RoutineName, L"ZwQueryInformationProcess" );
ZwQueryInformationProcess = ( QUERY_INFO_PROCESS )MmGetSystemRoutineAddress( &RoutineName );
if ( NULL == ZwQueryInformationProcess )
{
DbgPrint( “Cannot resolve ZwQueryInformationProcess\n” );
return STATUS_UNSUCCESSFUL;
}
}
pBuffer = ExAllocatePoolWithTag( NonPagedPool, sizeof( PROCESS_BASIC_INFORMATION ), ‘cuL’ );
if ( NULL == pBuffer ) return STATUS_INSUFFICIENT_RESOURCES;
ReturnedLength = 0;
Status = ZwQueryInformationProcess(
NtCurrentProcess(),
ProcessBasicInformation,
pBuffer,
sizeof( PROCESS_BASIC_INFORMATION ),
&ReturnedLength );
if ( STATUS_SUCCESS != Status )
{
DbgPrint( “ZwQueryInformationProcess failed\n” );
ExFreePoolWithTag( pBuffer, ‘cuL’ );
return STATUS_UNSUCCESSFUL;
}
pBasicInfo = ( PROCESS_BASIC_INFORMATION* )pBuffer;
pPeb = pBasicInfo->PebBaseAddress;
if ( NULL == pPeb )
{
if ( pBasicInfo->UniqueProcessId == 4 ) RtlInitUnicodeString( &UnicodeString, L"System" );
else RtlInitUnicodeString( &UnicodeString, L"" );
RtlCopyUnicodeString( ProcessImageName, &UnicodeString );
}
else
{
RtlCopyUnicodeString( ProcessImageName, &pPeb->ProcessParameters->ImagePathName );
}
ExFreePoolWithTag( pBuffer, ‘cuL’ );
return STATUS_SUCCESS;
}
Here are some structures from Winternl.h
typedef struct _PEB_LDR_DATA
{
UCHAR Reserved1[8];
PVOID Reserved2[3];
LIST_ENTRY InMemoryOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
typedef struct _RTL_USER_PROCESS_PARAMETERS
{
UCHAR Reserved1[16];
PVOID Reserved2[10];
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
typedef struct _PEB
{
UCHAR Reserved1[2];
UCHAR BeingDebugged;
UCHAR Reserved2[1];
PVOID Reserved3[2];
PPEB_LDR_DATA Ldr;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
// …
} PEB, *PPEB;
typedef NTSTATUS ( *QUERY_INFO_PROCESS ) (
__in HANDLE ProcessHandle,
__in PROCESSINFOCLASS ProcessInformationClass,
__out_bcount(ProcessInformationLength) PVOID ProcessInformation,
__in ULONG ProcessInformationLength,
__out_opt PULONG ReturnLength
);