diff --git a/2.x/trunk/ProcessHacker/basesup.c b/2.x/trunk/ProcessHacker/basesup.c
index 9b48b6420..9f4e95502 100644
--- a/2.x/trunk/ProcessHacker/basesup.c
+++ b/2.x/trunk/ProcessHacker/basesup.c
@@ -183,6 +183,7 @@ BOOLEAN PhInitializeBase()
sizeof(PHP_BASE_THREAD_CONTEXT),
16
);
+
#ifdef DEBUG
PhDbgThreadDbgTlsIndex = TlsAlloc();
InitializeListHead(&PhDbgThreadListHead);
diff --git a/2.x/trunk/ProcessHacker/dbgcon.c b/2.x/trunk/ProcessHacker/dbgcon.c
index 8fb95fd42..c6d733f96 100644
--- a/2.x/trunk/ProcessHacker/dbgcon.c
+++ b/2.x/trunk/ProcessHacker/dbgcon.c
@@ -57,13 +57,14 @@ static BOOLEAN NTAPI PhpLoadCurrentProcessSymbolsCallback(
}
static VOID PhpPrintObjectInfo(
- __in PPH_OBJECT_HEADER ObjectHeader
+ __in PPH_OBJECT_HEADER ObjectHeader,
+ __in LONG RefToSubtract
)
{
wprintf(L"%Ix", PhObjectHeaderToObject(ObjectHeader));
wprintf(L"\t% 20s", ObjectHeader->Type->Name);
- wprintf(L"\t%d", ObjectHeader->RefCount - 1);
+ wprintf(L"\t%d", ObjectHeader->RefCount - RefToSubtract);
if (!ObjectHeader->Type)
{
@@ -110,15 +111,15 @@ static VOID PhpDumpObjectInfo(
if (ObjectHeader->Type == PhObjectTypeObject)
{
- wprintf(L"%.32s\n", ((PPH_OBJECT_TYPE)PhObjectHeaderToObject(ObjectHeader))->Name);
+ wprintf(L"%s\n", ((PPH_OBJECT_TYPE)PhObjectHeaderToObject(ObjectHeader))->Name);
}
else if (ObjectHeader->Type == PhStringType)
{
- wprintf(L"%.32s\n", ((PPH_STRING)PhObjectHeaderToObject(ObjectHeader))->Buffer);
+ wprintf(L"%s\n", ((PPH_STRING)PhObjectHeaderToObject(ObjectHeader))->Buffer);
}
else if (ObjectHeader->Type == PhAnsiStringType)
{
- wprintf(L"%.32S\n", ((PPH_ANSI_STRING)PhObjectHeaderToObject(ObjectHeader))->Buffer);
+ wprintf(L"%S\n", ((PPH_ANSI_STRING)PhObjectHeaderToObject(ObjectHeader))->Buffer);
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
@@ -220,6 +221,7 @@ NTSTATUS PhpDebugConsoleThreadStart(
L"dumpobj\n"
L"dumpautopool\n"
L"threads\n"
+ L"provthreads\n"
);
}
else if (WSTR_IEQUAL(command, L"objects"))
@@ -265,7 +267,7 @@ NTSTATUS PhpDebugConsoleThreadStart(
(typeFilter && wcsstr(typeName, typeFilter))
)
{
- PhpPrintObjectInfo(objectHeader);
+ PhpPrintObjectInfo(objectHeader, 1);
}
currentEntry = currentEntry->Flink;
@@ -414,7 +416,7 @@ NTSTATUS PhpDebugConsoleThreadStart(
{
PPH_OBJECT_HEADER objectHeader = newObjects->Items[i];
- PhpPrintObjectInfo(objectHeader);
+ PhpPrintObjectInfo(objectHeader, 1);
PhDereferenceObject(PhObjectHeaderToObject(objectHeader));
}
@@ -464,7 +466,7 @@ NTSTATUS PhpDebugConsoleThreadStart(
for (i = 0; i < NewObjectList->Count; i++)
{
- PhpPrintObjectInfo(PhObjectToObjectHeader(NewObjectList->Items[i]));
+ PhpPrintObjectInfo(PhObjectToObjectHeader(NewObjectList->Items[i]), 1);
}
PhReleaseMutex(&NewObjectListLock);
@@ -507,12 +509,12 @@ NTSTATUS PhpDebugConsoleThreadStart(
wprintf(L"Static objects:\n");
for (i = 0; i < autoPool->StaticCount; i++)
- PhpPrintObjectInfo(PhObjectToObjectHeader(autoPool->StaticObjects[i]));
+ PhpPrintObjectInfo(PhObjectToObjectHeader(autoPool->StaticObjects[i]), 0);
wprintf(L"Dynamic objects:\n");
for (i = 0; i < autoPool->DynamicCount; i++)
- PhpPrintObjectInfo(PhObjectToObjectHeader(autoPool->DynamicObjects[i]));
+ PhpPrintObjectInfo(PhObjectToObjectHeader(autoPool->DynamicObjects[i]), 0);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
@@ -549,6 +551,71 @@ NTSTATUS PhpDebugConsoleThreadStart(
PhReleaseFastLockShared(&PhDbgThreadListLock);
#else
wprintf(commandDebugOnly);
+#endif
+ }
+ else if (WSTR_IEQUAL(command, L"provthreads"))
+ {
+#ifdef DEBUG
+ PLIST_ENTRY currentEntry;
+
+ PhAcquireFastLockShared(&PhDbgProviderListLock);
+
+ currentEntry = PhDbgProviderListHead.Flink;
+
+ while (currentEntry != &PhDbgProviderListHead)
+ {
+ PPH_PROVIDER_THREAD providerThread;
+ THREAD_BASIC_INFORMATION basicInfo;
+ PLIST_ENTRY providerEntry;
+
+ providerThread = CONTAINING_RECORD(currentEntry, PH_PROVIDER_THREAD, DbgListEntry);
+
+ if (providerThread->ThreadHandle)
+ {
+ PhGetThreadBasicInformation(providerThread->ThreadHandle, &basicInfo);
+ wprintf(L"Thread %u\n", (ULONG)basicInfo.ClientId.UniqueThread);
+ }
+ else
+ {
+ wprintf(L"Thread not running\n");
+ }
+
+ PhAcquireMutex(&providerThread->Mutex);
+
+ providerEntry = providerThread->ListHead.Flink;
+
+ while (providerEntry != &providerThread->ListHead)
+ {
+ PPH_PROVIDER_REGISTRATION registration;
+
+ registration = CONTAINING_RECORD(providerEntry, PH_PROVIDER_REGISTRATION, ListEntry);
+
+ wprintf(L"\tProvider registration at %Ix\n", registration);
+ wprintf(L"\t\tEnabled: %s\n", registration->Enabled ? L"Yes" : L"No");
+ wprintf(L"\t\tFunction: %s\n",
+ ((PPH_STRING)PHA_DEREFERENCE(PhGetSymbolFromAddress(
+ symbolProvider, (ULONG64)registration->Function, NULL, NULL, NULL, NULL
+ )))->Buffer);
+
+ if (registration->Object)
+ {
+ wprintf(L"\t\tObject:\n");
+ PhpPrintObjectInfo(PhObjectToObjectHeader(registration->Object), 0);
+ }
+
+ providerEntry = providerEntry->Flink;
+ }
+
+ PhReleaseMutex(&providerThread->Mutex);
+
+ wprintf(L"\n");
+
+ currentEntry = currentEntry->Flink;
+ }
+
+ PhReleaseFastLockShared(&PhDbgProviderListLock);
+#else
+ wprintf(commandDebugOnly);
#endif
}
else
diff --git a/2.x/trunk/ProcessHacker/include/fastlock.h b/2.x/trunk/ProcessHacker/include/fastlock.h
index 638f92bb0..ee723747f 100644
--- a/2.x/trunk/ProcessHacker/include/fastlock.h
+++ b/2.x/trunk/ProcessHacker/include/fastlock.h
@@ -12,6 +12,8 @@ typedef struct _PH_FAST_LOCK
HANDLE SharedWakeEvent;
} PH_FAST_LOCK, *PPH_FAST_LOCK;
+#define PH_FAST_LOCK_INIT { 0, NULL, NULL }
+
VOID PhFastLockInitialization();
VOID PhInitializeFastLock(
diff --git a/2.x/trunk/ProcessHacker/include/ph.h b/2.x/trunk/ProcessHacker/include/ph.h
index 3589784bb..a1e403fcf 100644
--- a/2.x/trunk/ProcessHacker/include/ph.h
+++ b/2.x/trunk/ProcessHacker/include/ph.h
@@ -690,6 +690,11 @@ VERIFY_RESULT PhVerifyFile(
// provider
+#ifndef PROVIDER_PRIVATE
+extern LIST_ENTRY PhDbgProviderListHead;
+extern PH_FAST_LOCK PhDbgProviderListLock;
+#endif
+
typedef enum _PH_PROVIDER_THREAD_STATE
{
ProviderThreadRunning,
@@ -713,6 +718,9 @@ typedef struct _PH_PROVIDER_REGISTRATION
typedef struct _PH_PROVIDER_THREAD
{
+#ifdef DEBUG
+ LIST_ENTRY DbgListEntry;
+#endif
HANDLE ThreadHandle;
HANDLE TimerHandle;
ULONG Interval;
diff --git a/2.x/trunk/ProcessHacker/main.c b/2.x/trunk/ProcessHacker/main.c
index b4175479c..c96af8e6c 100644
--- a/2.x/trunk/ProcessHacker/main.c
+++ b/2.x/trunk/ProcessHacker/main.c
@@ -135,6 +135,11 @@ INT WINAPI WinMain(
TlsSetValue(PhDbgThreadDbgTlsIndex, &dbg);
#endif
+#ifdef DEBUG
+ InitializeListHead(&PhDbgProviderListHead);
+ PhInitializeFastLock(&PhDbgProviderListLock);
+#endif
+
PhInitializeAutoPool(&BaseAutoPool);
PhGuiSupportInitialization();
diff --git a/2.x/trunk/ProcessHacker/provider.c b/2.x/trunk/ProcessHacker/provider.c
index 81315fef3..3f6507004 100644
--- a/2.x/trunk/ProcessHacker/provider.c
+++ b/2.x/trunk/ProcessHacker/provider.c
@@ -20,8 +20,14 @@
* along with Process Hacker. If not, see .
*/
+#define PROVIDER_PRIVATE
#include
+#ifdef DEBUG
+LIST_ENTRY PhDbgProviderListHead;
+PH_FAST_LOCK PhDbgProviderListLock;
+#endif
+
VOID PhInitializeProviderThread(
__out PPH_PROVIDER_THREAD ProviderThread,
__in ULONG Interval
@@ -35,6 +41,12 @@ VOID PhInitializeProviderThread(
PhInitializeMutex(&ProviderThread->Mutex);
InitializeListHead(&ProviderThread->ListHead);
ProviderThread->BoostCount = 0;
+
+#ifdef DEBUG
+ PhAcquireFastLockExclusive(&PhDbgProviderListLock);
+ InsertTailList(&PhDbgProviderListHead, &ProviderThread->DbgListEntry);
+ PhReleaseFastLockExclusive(&PhDbgProviderListLock);
+#endif
}
VOID PhDeleteProviderThread(
@@ -42,6 +54,12 @@ VOID PhDeleteProviderThread(
)
{
PhDeleteMutex(&ProviderThread->Mutex);
+
+#ifdef DEBUG
+ PhAcquireFastLockExclusive(&PhDbgProviderListLock);
+ RemoveEntryList(&ProviderThread->DbgListEntry);
+ PhReleaseFastLockExclusive(&PhDbgProviderListLock);
+#endif
}
NTSTATUS NTAPI PhpProviderThreadStart(
diff --git a/2.x/trunk/ProcessHacker/treelist.c b/2.x/trunk/ProcessHacker/treelist.c
index d40e1c7f4..a19720d80 100644
--- a/2.x/trunk/ProcessHacker/treelist.c
+++ b/2.x/trunk/ProcessHacker/treelist.c
@@ -115,6 +115,33 @@ LRESULT CALLBACK PhpTreeListWndProc(
clientRect.right - clientRect.left, 20, SWP_NOACTIVATE | SWP_NOZORDER);
}
break;
+ case WM_ERASEBKGND:
+ return TRUE;
+ case WM_PAINT:
+ {
+ HDC hdc;
+ PAINTSTRUCT paintStruct;
+ RECT clientRect;
+ RECT rect;
+
+ hdc = BeginPaint(hwnd, &paintStruct);
+
+ GetClientRect(hwnd, &clientRect);
+
+ SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW));
+ Rectangle(hdc, clientRect.left, clientRect.top, clientRect.right, clientRect.bottom);
+
+ SelectObject(hdc, GetSysColorBrush(COLOR_WINDOWTEXT));
+ rect.left = 0;
+ rect.top = 0;
+ rect.right = 200;
+ rect.bottom = 100;
+
+ DrawText(hdc, L"Test", -1, &rect, DT_LEFT | DT_NOCLIP);
+
+ EndPaint(hwnd, &paintStruct);
+ }
+ break;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);