Skip to content

Commit

Permalink
Merge branch 'winsiderss:master' into ObjManagerPlus
Browse files Browse the repository at this point in the history
  • Loading branch information
DartVanya authored Oct 6, 2024
2 parents df35cfa + 90012bf commit 6e9fd02
Show file tree
Hide file tree
Showing 30 changed files with 516 additions and 403 deletions.
4 changes: 2 additions & 2 deletions SystemInformer/delayhook.c
Original file line number Diff line number Diff line change
Expand Up @@ -647,8 +647,8 @@ LRESULT CALLBACK PhEditWindowHookProcedure(

if (GetFocus() == WindowHandle)
{
//SetDCBrushColor(hdc, GetSysColor(COLOR_HOTLIGHT)); // PhThemeWindowHighlightColor
FrameRect(hdc, &windowRect, (HBRUSH)(COLOR_HOTLIGHT + 1));
SetDCBrushColor(hdc, GetSysColor(COLOR_HOTLIGHT)); // PhThemeWindowHighlightColor
FrameRect(hdc, &windowRect, PhGetStockBrush(DC_BRUSH));
}
else
{
Expand Down
25 changes: 5 additions & 20 deletions SystemInformer/include/informer.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,40 +12,29 @@
#ifndef PH_KSIMSG_H
#define PH_KSIMSG_H

typedef struct _PH_INFORMER_REPLY_CONTEXT
typedef struct _PH_INFORMER_CONTEXT
{
PKPH_MESSAGE Message;
ULONG_PTR ReplyToken;
BOOLEAN Handled;
} PH_INFORMER_REPLY_CONTEXT, *PPH_INFORMER_REPLY_CONTEXT;

/**
* Callback registration for informer messages, these messages are dispatched
* asynchronously from the primary message threads, meaning they can not be
* replied to. This is the preferred method of registering for message since
* it gets out of the way of the system.
*
* Receives PKPH_MESSAGE as the callback parameter, this is an object that can
* be referenced.
*/
extern PH_CALLBACK PhInformerCallback;
} PH_INFORMER_CONTEXT, *PPH_INFORMER_CONTEXT;

/**
* Callback registration for informer messages that can be replied to. Any
* processing done by these callbacks **must** be brief as it is blocking
* informer message handling on the system.
*
* Receives PPH_INFORMER_REPLY_CONTEXT as the callback parameter. The callback
* Receives PPH_INFORMER_CONTEXT as the callback parameter. The callback
* may use PhInformerReply to reply to a message. After a successful call to
* PhInformerReply the context is updated with Handled set to TRUE. Callbacks
* later in the chain will still be called, but the message should not be
* replied to. Callbacks should generally check if the message has already
* been handled prior to doing work.
*/
extern PH_CALLBACK PhInformerReplyCallback;
extern PH_CALLBACK PhInformerCallback;

NTSTATUS PhInformerReply(
_Inout_ PPH_INFORMER_REPLY_CONTEXT Context,
_Inout_ PPH_INFORMER_CONTEXT Context,
_In_ PKPH_MESSAGE ReplyMessage
);

Expand All @@ -58,8 +47,4 @@ VOID PhInformerInitialize(
VOID
);

VOID PhInformerStop(
VOID
);

#endif
1 change: 1 addition & 0 deletions SystemInformer/include/phplug.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ typedef enum _PH_GENERAL_CALLBACK
GeneralCallbackProcessStatsNotifyEvent,
GeneralCallbackSettingsUpdated,
GeneralCallbackDangerousProcess,
GeneralCallbackUpdateAutomatically,

GeneralCallbackMaximum
} PH_GENERAL_CALLBACK, *PPH_GENERAL_CALLBACK;
Expand Down
2 changes: 2 additions & 0 deletions SystemInformer/include/procprpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ typedef struct _PH_MODULES_CONTEXT
PH_CALLBACK_REGISTRATION ModifiedEventRegistration;
PH_CALLBACK_REGISTRATION RemovedEventRegistration;
PH_CALLBACK_REGISTRATION UpdatedEventRegistration;
PH_CALLBACK_REGISTRATION ChangedEventRegistration;

HWND WindowHandle;
// end_phapppub
Expand Down Expand Up @@ -274,6 +275,7 @@ typedef struct _PH_HANDLES_CONTEXT
PH_CALLBACK_REGISTRATION ModifiedEventRegistration;
PH_CALLBACK_REGISTRATION RemovedEventRegistration;
PH_CALLBACK_REGISTRATION UpdatedEventRegistration;
PH_CALLBACK_REGISTRATION ChangedEventRegistration;

HWND WindowHandle;
// end_phapppub
Expand Down
202 changes: 4 additions & 198 deletions SystemInformer/informer.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,158 +13,12 @@

#include <informer.h>

#define KSI_MESSAGE_DRAIN_LIMIT 256
#define KSI_MESSAGE_DRAIN_TIMEOUT 5000000 // 500ms

typedef struct _KSI_MESSAGE_QUEUE_ENTRY
{
SLIST_ENTRY Entry;
PKPH_MESSAGE Message;
} KSI_MESSAGE_QUEUE_ENTRY, *PKSI_MESSAGE_QUEUE_ENTRY;

static PPH_OBJECT_TYPE KsiMessageObjectType = NULL;
static HANDLE KsiMessageWorkerThreadHandle = NULL;
static PH_RUNDOWN_PROTECT KsiMessageRundown;
static HANDLE KsiMessageQueueEvent = NULL;
static SLIST_HEADER KsiMessageQueueHeader;
static PH_FREE_LIST KsiMessageQueueFreeList;
static PPH_LIST KsiMessageOrderingList = NULL;
static LARGE_INTEGER KsiMessageLastDrain = { 0 };

PH_CALLBACK_DECLARE(PhInformerCallback);
PH_CALLBACK_DECLARE(PhInformerReplyCallback);

static int __cdecl PhpInformerMessageSort(
_In_ void* Context,
_In_ const void *elem1,
_In_ const void *elem2
)
{
PKSI_MESSAGE_QUEUE_ENTRY entry1 = *(PKSI_MESSAGE_QUEUE_ENTRY*)elem1;
PKSI_MESSAGE_QUEUE_ENTRY entry2 = *(PKSI_MESSAGE_QUEUE_ENTRY*)elem2;

return int64cmp(entry1->Message->Header.TimeStamp.QuadPart, entry2->Message->Header.TimeStamp.QuadPart);
}

BOOLEAN PhpInformerDrainShouldDispatch(
VOID
)
{
BOOLEAN result;
LARGE_INTEGER systemTime;
LARGE_INTEGER elapsed;

PhQuerySystemTime(&systemTime);

if (KsiMessageOrderingList->Count >= KSI_MESSAGE_DRAIN_LIMIT)
{
result = TRUE;
goto CleanupExit;
}

elapsed.QuadPart = systemTime.QuadPart - KsiMessageLastDrain.QuadPart;
if (elapsed.QuadPart >= KSI_MESSAGE_DRAIN_TIMEOUT)
{
result = TRUE;
goto CleanupExit;
}

result = FALSE;

CleanupExit:

if (result)
KsiMessageLastDrain = systemTime;

return result;
}

BOOLEAN PhpInformerDrain(
_In_ BOOLEAN Force
)
{
PSLIST_ENTRY entry;
PKSI_MESSAGE_QUEUE_ENTRY queueEntry;

entry = InterlockedFlushSList(&KsiMessageQueueHeader);

if (!entry)
{
if (Force)
goto ForceDrain;

return TRUE;
}

while (entry)
{
queueEntry = CONTAINING_RECORD(entry, KSI_MESSAGE_QUEUE_ENTRY, Entry);
PhAddItemList(KsiMessageOrderingList, queueEntry);
entry = entry->Next;
}

if (!Force && !PhpInformerDrainShouldDispatch())
return FALSE;

ForceDrain:

qsort_s(
KsiMessageOrderingList->Items,
KsiMessageOrderingList->Count,
sizeof(PVOID),
PhpInformerMessageSort,
NULL
);

for (ULONG i = 0; i < KsiMessageOrderingList->Count; i++)
{
queueEntry = KsiMessageOrderingList->Items[i];

PhInvokeCallback(&PhInformerCallback, queueEntry->Message);
PhDereferenceObject(queueEntry->Message);
PhFreeToFreeList(&KsiMessageQueueFreeList, queueEntry);
}

PhClearList(KsiMessageOrderingList);

return FALSE;
}

NTSTATUS NTAPI PhpInformerMessageWorker(
_In_ PVOID Context
)
{
BOOLEAN exit = FALSE;

PhSetThreadName(NtCurrentThread(), L"InformerMessageWorker");

for (NOTHING; !exit; NtWaitForSingleObject(KsiMessageQueueEvent, FALSE, NULL))
{
for (BOOLEAN drained = FALSE; !drained; NOTHING)
{
if (!PhAcquireRundownProtection(&KsiMessageRundown))
{
exit = TRUE;
break;
}

if (PhpInformerDrain(FALSE))
{
drained = TRUE;
NtResetEvent(KsiMessageQueueEvent, NULL);
}

PhReleaseRundownProtection(&KsiMessageRundown);
}

PhpInformerDrain(TRUE);
}

return STATUS_SUCCESS;
}

NTSTATUS PhInformerReply(
_Inout_ PPH_INFORMER_REPLY_CONTEXT Context,
_Inout_ PPH_INFORMER_CONTEXT Context,
_In_ PKPH_MESSAGE ReplyMessage
)
{
Expand All @@ -185,10 +39,7 @@ BOOLEAN PhInformerDispatch(
)
{
PKPH_MESSAGE message;
PH_INFORMER_REPLY_CONTEXT context;

if (!PhAcquireRundownProtection(&KsiMessageRundown))
return FALSE;
PH_INFORMER_CONTEXT context;

message = PhCreateObject(Message->Header.Size, KsiMessageObjectType);
memcpy(message, Message, Message->Header.Size);
Expand All @@ -197,23 +48,9 @@ BOOLEAN PhInformerDispatch(
context.ReplyToken = ReplyToken;
context.Handled = FALSE;

PhInvokeCallback(&PhInformerReplyCallback, &context);

if (KsiMessageWorkerThreadHandle)
{
PKSI_MESSAGE_QUEUE_ENTRY entry;
PhInvokeCallback(&PhInformerCallback, &context);

entry = PhAllocateFromFreeList(&KsiMessageQueueFreeList);
entry->Message = message;
if (!InterlockedPushEntrySList(&KsiMessageQueueHeader, &entry->Entry))
NtSetEvent(KsiMessageQueueEvent, NULL);
}
else
{
PhDereferenceObject(message);
}

PhReleaseRundownProtection(&KsiMessageRundown);
PhDereferenceObject(message);

return context.Handled;
}
Expand All @@ -222,36 +59,5 @@ VOID PhInformerInitialize(
VOID
)
{
OBJECT_ATTRIBUTES objectAttributes;
PhInitializeRundownProtection(&KsiMessageRundown);
KsiMessageObjectType = PhCreateObjectType(L"KsiMessage", 0, NULL);
KsiMessageOrderingList = PhCreateList(KSI_MESSAGE_DRAIN_LIMIT);
PhInitializeFreeList(&KsiMessageQueueFreeList, sizeof(KSI_MESSAGE_QUEUE_ENTRY), KSI_MESSAGE_DRAIN_LIMIT);
InitializeSListHead(&KsiMessageQueueHeader);
InitializeObjectAttributes(&objectAttributes, NULL, OBJ_EXCLUSIVE, NULL, NULL);
if (NT_SUCCESS(NtCreateEvent(&KsiMessageQueueEvent, EVENT_ALL_ACCESS, &objectAttributes, NotificationEvent, FALSE)))
{
KsiMessageWorkerThreadHandle = PhCreateThread(0, PhpInformerMessageWorker, NULL);
}
}

VOID PhInformerStop(
VOID
)
{
PhWaitForRundownProtection(&KsiMessageRundown);
if (KsiMessageQueueEvent)
{
NtSetEvent(KsiMessageQueueEvent, NULL);
if (KsiMessageWorkerThreadHandle)
{
NtWaitForSingleObject(KsiMessageWorkerThreadHandle, FALSE, NULL);
NtClose(KsiMessageWorkerThreadHandle);
KsiMessageWorkerThreadHandle = NULL;
}
NtClose(KsiMessageQueueEvent);
KsiMessageQueueEvent = NULL;
}
PhDeleteFreeList(&KsiMessageQueueFreeList);
PhDereferenceObject(KsiMessageOrderingList);
}
1 change: 0 additions & 1 deletion SystemInformer/ksisup.c
Original file line number Diff line number Diff line change
Expand Up @@ -1245,7 +1245,6 @@ NTSTATUS PhCleanupKsi(
}

KphCommsStop();
PhInformerStop();
#ifdef DEBUG
KsiDebugLogFinalize();
#endif
Expand Down
8 changes: 7 additions & 1 deletion SystemInformer/mainwnd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1124,6 +1124,9 @@ VOID PhMwpOnCommand(
case ID_UPDATEINTERVAL_VERYSLOW:
interval = 10000;
break;
default:
interval = 1000;
break;
}

PH_SET_INTEGER_CACHED_SETTING(UpdateInterval, interval);
Expand All @@ -1133,7 +1136,10 @@ VOID PhMwpOnCommand(
case ID_VIEW_UPDATEAUTOMATICALLY:
{
PhMwpUpdateAutomatically = !PhMwpUpdateAutomatically;
PhMwpNotifyAllPages(MainTabPageUpdateAutomaticallyChanged, (PVOID)PhMwpUpdateAutomatically, NULL);

PhMwpNotifyAllPages(MainTabPageUpdateAutomaticallyChanged, UlongToPtr(PhMwpUpdateAutomatically), NULL);

PhInvokeCallback(PhGetGeneralCallback(GeneralCallbackUpdateAutomatically), UlongToPtr(PhMwpUpdateAutomatically));
}
break;
case ID_TOOLS_THREADSTACKS:
Expand Down
Loading

0 comments on commit 6e9fd02

Please sign in to comment.