mirror of
https://github.com/mirror/processhacker
synced 2026-06-08 16:03:24 +00:00
added error message formatting
git-svn-id: svn://svn.code.sf.net/p/processhacker/code@2567 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
@@ -61,8 +61,10 @@ EXT _NtWriteFile NtWriteFile EQNULL;
|
||||
EXT _NtWriteVirtualMemory NtWriteVirtualMemory EQNULL;
|
||||
EXT _RtlCreateQueryDebugBuffer RtlCreateQueryDebugBuffer EQNULL;
|
||||
EXT _RtlDestroyQueryDebugBuffer RtlDestroyQueryDebugBuffer EQNULL;
|
||||
EXT _RtlFindMessage RtlFindMessage EQNULL;
|
||||
EXT _RtlMultiByteToUnicodeN RtlMultiByteToUnicodeN EQNULL;
|
||||
EXT _RtlMultiByteToUnicodeSize RtlMultiByteToUnicodeSize EQNULL;
|
||||
EXT _RtlNtStatusToDosError RtlNtStatusToDosError EQNULL;
|
||||
EXT _RtlQueryProcessDebugInformation RtlQueryProcessDebugInformation EQNULL;
|
||||
EXT _RtlUnicodeToMultiByteN RtlUnicodeToMultiByteN EQNULL;
|
||||
EXT _RtlUnicodeToMultiByteSize RtlUnicodeToMultiByteSize EQNULL;
|
||||
|
||||
@@ -329,4 +329,20 @@ typedef NTSTATUS (NTAPI *_RtlQueryProcessDebugInformation)(
|
||||
#define RTL_QUERY_PROCESS_MODULES32 0x00000040
|
||||
#define RTL_QUERY_PROCESS_NONINVASIVE 0x80000000
|
||||
|
||||
// Messages
|
||||
|
||||
typedef NTSTATUS (NTAPI *_RtlFindMessage)(
|
||||
__in PVOID DllHandle,
|
||||
__in ULONG MessageTableId,
|
||||
__in ULONG MessageLanguageId,
|
||||
__in ULONG MessageId,
|
||||
__out PMESSAGE_RESOURCE_ENTRY *MessageEntry
|
||||
);
|
||||
|
||||
// Errors
|
||||
|
||||
typedef ULONG (NTAPI *_RtlNtStatusToDosError)(
|
||||
__in NTSTATUS Status
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -49,6 +49,16 @@ NTSTATUS PhOpenProcessToken(
|
||||
__in HANDLE ProcessHandle
|
||||
);
|
||||
|
||||
NTSTATUS PhTerminateProcess(
|
||||
__in HANDLE ProcessHandle,
|
||||
__in NTSTATUS ExitStatus
|
||||
);
|
||||
|
||||
NTSTATUS PhTerminateThread(
|
||||
__in HANDLE ThreadHandle,
|
||||
__in NTSTATUS ExitStatus
|
||||
);
|
||||
|
||||
NTSTATUS PhReadVirtualMemory(
|
||||
__in HANDLE ProcessHandle,
|
||||
__in PVOID BaseAddress,
|
||||
@@ -683,6 +693,21 @@ VOID PhThreadProviderUpdate(
|
||||
|
||||
// support
|
||||
|
||||
PPH_STRING PhGetMessage(
|
||||
__in HANDLE DllHandle,
|
||||
__in ULONG MessageTableId,
|
||||
__in ULONG MessageLanguageId,
|
||||
__in ULONG MessageId
|
||||
);
|
||||
|
||||
PPH_STRING PhGetNtMessage(
|
||||
__in NTSTATUS Status
|
||||
);
|
||||
|
||||
PPH_STRING PhGetWin32Message(
|
||||
__in ULONG Result
|
||||
);
|
||||
|
||||
#define PH_MAX_MESSAGE_SIZE 400
|
||||
|
||||
INT PhShowMessage(
|
||||
@@ -701,6 +726,13 @@ INT PhShowMessage_V(
|
||||
|
||||
#define PhShowError(hWnd, Format, ...) PhShowMessage(hWnd, MB_OK | MB_ICONERROR, Format, __VA_ARGS__)
|
||||
|
||||
VOID PhShowStatus(
|
||||
__in HWND hWnd,
|
||||
__in_opt PWSTR Message,
|
||||
__in NTSTATUS Status,
|
||||
__in_opt ULONG Win32Result
|
||||
);
|
||||
|
||||
PVOID PhGetFileVersionInfo(
|
||||
__in PWSTR FileName
|
||||
);
|
||||
|
||||
@@ -25,7 +25,7 @@ typedef BOOL (WINAPI *_SymFromAddr)(
|
||||
__in HANDLE hProcess,
|
||||
__in DWORD64 Address,
|
||||
__out_opt PDWORD64 Displacement,
|
||||
__inout PSYMBOL_INFO Symbol
|
||||
__inout PSYMBOL_INFOW Symbol
|
||||
);
|
||||
|
||||
typedef DWORD64 (WINAPI *_SymLoadModule64)(
|
||||
|
||||
@@ -83,8 +83,10 @@ BOOLEAN PhInitializeImports()
|
||||
InitProcReq("ntdll.dll", NtWriteVirtualMemory);
|
||||
InitProcReq("ntdll.dll", RtlCreateQueryDebugBuffer);
|
||||
InitProcReq("ntdll.dll", RtlDestroyQueryDebugBuffer);
|
||||
InitProcReq("ntdll.dll", RtlFindMessage);
|
||||
InitProcReq("ntdll.dll", RtlMultiByteToUnicodeN);
|
||||
InitProcReq("ntdll.dll", RtlMultiByteToUnicodeSize);
|
||||
InitProcReq("ntdll.dll", RtlNtStatusToDosError);
|
||||
InitProcReq("ntdll.dll", RtlQueryProcessDebugInformation);
|
||||
InitProcReq("ntdll.dll", RtlUnicodeToMultiByteN);
|
||||
InitProcReq("ntdll.dll", RtlUnicodeToMultiByteSize);
|
||||
|
||||
@@ -114,6 +114,50 @@ NTSTATUS PhOpenProcessToken(
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS PhTerminateProcess(
|
||||
__in HANDLE ProcessHandle,
|
||||
__in NTSTATUS ExitStatus
|
||||
)
|
||||
{
|
||||
if (PhKphHandle)
|
||||
{
|
||||
return KphTerminateProcess(
|
||||
PhKphHandle,
|
||||
ProcessHandle,
|
||||
ExitStatus
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NtTerminateProcess(
|
||||
ProcessHandle,
|
||||
ExitStatus
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS PhTerminateThread(
|
||||
__in HANDLE ThreadHandle,
|
||||
__in NTSTATUS ExitStatus
|
||||
)
|
||||
{
|
||||
if (PhKphHandle)
|
||||
{
|
||||
return KphTerminateThread(
|
||||
PhKphHandle,
|
||||
ThreadHandle,
|
||||
ExitStatus
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NtTerminateThread(
|
||||
ThreadHandle,
|
||||
ExitStatus
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS PhReadVirtualMemory(
|
||||
__in HANDLE ProcessHandle,
|
||||
__in PVOID BaseAddress,
|
||||
|
||||
@@ -334,7 +334,31 @@ INT_PTR CALLBACK PhpProcessGeneralDlgProc(
|
||||
processItem->ProcessName->Buffer
|
||||
) == IDYES)
|
||||
{
|
||||
|
||||
NTSTATUS status;
|
||||
HANDLE processHandle;
|
||||
|
||||
if (NT_SUCCESS(status = PhOpenProcess(
|
||||
&processHandle,
|
||||
PROCESS_TERMINATE,
|
||||
processItem->ProcessId
|
||||
)))
|
||||
{
|
||||
status = PhTerminateProcess(
|
||||
processHandle,
|
||||
STATUS_SUCCESS
|
||||
);
|
||||
CloseHandle(processHandle);
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
PhShowStatus(
|
||||
hwndDlg,
|
||||
L"Unable to terminate the process",
|
||||
status,
|
||||
0
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -23,6 +23,105 @@
|
||||
#include <phgui.h>
|
||||
#include <wchar.h>
|
||||
|
||||
PPH_STRING PhGetMessage(
|
||||
__in HANDLE DllHandle,
|
||||
__in ULONG MessageTableId,
|
||||
__in ULONG MessageLanguageId,
|
||||
__in ULONG MessageId
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
PMESSAGE_RESOURCE_ENTRY messageEntry;
|
||||
|
||||
status = RtlFindMessage(
|
||||
DllHandle,
|
||||
MessageTableId,
|
||||
MessageLanguageId,
|
||||
MessageId,
|
||||
&messageEntry
|
||||
);
|
||||
|
||||
// Try using the system LANGID.
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
status = RtlFindMessage(
|
||||
DllHandle,
|
||||
MessageTableId,
|
||||
GetSystemDefaultLangID(),
|
||||
MessageId,
|
||||
&messageEntry
|
||||
);
|
||||
}
|
||||
|
||||
// Try using U.S. English.
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
status = RtlFindMessage(
|
||||
DllHandle,
|
||||
MessageTableId,
|
||||
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
|
||||
MessageId,
|
||||
&messageEntry
|
||||
);
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
return NULL;
|
||||
|
||||
if (messageEntry->Flags & MESSAGE_RESOURCE_UNICODE)
|
||||
{
|
||||
return PhCreateStringEx((PWSTR)messageEntry->Text, messageEntry->Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
return PhCreateStringFromAnsiEx((PSTR)messageEntry->Text, messageEntry->Length);
|
||||
}
|
||||
}
|
||||
|
||||
PPH_STRING PhGetNtMessage(
|
||||
__in NTSTATUS Status
|
||||
)
|
||||
{
|
||||
PPH_STRING message;
|
||||
|
||||
message = PhGetMessage(GetModuleHandle(L"ntdll.dll"), 0xb, GetUserDefaultLangID(), (ULONG)Status);
|
||||
|
||||
if (!message)
|
||||
return NULL;
|
||||
if (message->Length == 0)
|
||||
return message;
|
||||
|
||||
// Fix those messages which are formatted like:
|
||||
// {Asdf}\r\nAsdf asdf asdf...
|
||||
if (message->Buffer[0] == '{')
|
||||
{
|
||||
ULONG indexOfNewLine = PhStringIndexOfChar(message, 0, '\n');
|
||||
|
||||
if (indexOfNewLine != -1)
|
||||
{
|
||||
PPH_STRING newMessage;
|
||||
|
||||
newMessage = PhSubstring(
|
||||
message,
|
||||
indexOfNewLine + 1,
|
||||
message->Length / 2 - indexOfNewLine - 1
|
||||
);
|
||||
PhDereferenceObject(message);
|
||||
|
||||
message = newMessage;
|
||||
}
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
PPH_STRING PhGetWin32Message(
|
||||
__in ULONG Result
|
||||
)
|
||||
{
|
||||
return PhGetMessage(GetModuleHandle(L"kernel32.dll"), 0xb, GetUserDefaultLangID(), Result);
|
||||
}
|
||||
|
||||
INT PhShowMessage(
|
||||
__in HWND hWnd,
|
||||
__in ULONG Type,
|
||||
@@ -55,6 +154,61 @@ INT PhShowMessage_V(
|
||||
return MessageBox(hWnd, message, PH_APP_NAME, Type);
|
||||
}
|
||||
|
||||
VOID PhShowStatus(
|
||||
__in HWND hWnd,
|
||||
__in_opt PWSTR Message,
|
||||
__in NTSTATUS Status,
|
||||
__in_opt ULONG Win32Result
|
||||
)
|
||||
{
|
||||
PPH_STRING statusMessage;
|
||||
|
||||
if (!Win32Result)
|
||||
{
|
||||
// In some cases we want the simple Win32 messages.
|
||||
if (
|
||||
Status != STATUS_ACCESS_DENIED &&
|
||||
Status != STATUS_ACCESS_VIOLATION
|
||||
)
|
||||
{
|
||||
statusMessage = PhGetNtMessage(Status);
|
||||
}
|
||||
else
|
||||
{
|
||||
statusMessage = PhGetWin32Message(RtlNtStatusToDosError(Status));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
statusMessage = PhGetWin32Message(Win32Result);
|
||||
}
|
||||
|
||||
if (!statusMessage)
|
||||
{
|
||||
if (Message)
|
||||
{
|
||||
PhShowError(hWnd, L"%s.", Message);
|
||||
}
|
||||
else
|
||||
{
|
||||
PhShowError(hWnd, L"Unable to perform the operation.");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (Message)
|
||||
{
|
||||
PhShowError(hWnd, L"%s: %s", Message, statusMessage->Buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
PhShowError(hWnd, L"%s", statusMessage->Buffer);
|
||||
}
|
||||
|
||||
PhDereferenceObject(statusMessage);
|
||||
}
|
||||
|
||||
PVOID PhGetFileVersionInfo(
|
||||
__in PWSTR FileName
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user