static VOID NTAPI TreeNewMessageCallback( _In_opt_ PVOID Parameter, _In_opt_ PVOID Context ) { PPH_PLUGIN_TREENEW_MESSAGE message = Parameter; switch (message->Message) { case TreeNewGetCellText: { if (message->TreeNewHandle == NetworkTreeNewHandle) { PPH_TREENEW_GET_CELL_TEXT getCellText = message->Parameter1; PPH_NETWORK_NODE networkNode = (PPH_NETWORK_NODE)getCellText->Node; PNETWORK_DNSCACHE_EXTENSION extension = PhPluginGetObjectExtension(PluginInstance, networkNode->NetworkItem, EmNetworkItemType); UpdateNetworkItem(message->SubId, networkNode->NetworkItem, extension); switch (message->SubId) { case NETWORK_COLUMN_ID_DNSCACHE_ROOT_QUERY: { if (extension->DnsCacheValid) getCellText->Text = PhGetStringRef(extension->DnsCacheQueryRoot); } break; } } } break; } }
VOID ThreadTreeNewMessage( _In_ PVOID Parameter ) { PPH_PLUGIN_TREENEW_MESSAGE message = Parameter; PTHREAD_TREE_CONTEXT context = message->Context; if (message->Message == TreeNewGetCellText) { PPH_TREENEW_GET_CELL_TEXT getCellText = message->Parameter1; PPH_THREAD_NODE threadNode = (PPH_THREAD_NODE)getCellText->Node; PDN_THREAD_ITEM dnThread; dnThread = PhPluginGetObjectExtension(PluginInstance, threadNode->ThreadItem, EmThreadItemType); switch (message->SubId) { case DNTHTNC_APPDOMAIN: UpdateThreadClrData(context, dnThread); getCellText->Text = PhGetStringRef(dnThread->AppDomainText); break; } } }
BOOLEAN NTAPI DotNetAsmTreeNewCallback( _In_ HWND hwnd, _In_ PH_TREENEW_MESSAGE Message, _In_opt_ PVOID Parameter1, _In_opt_ PVOID Parameter2, _In_opt_ PVOID Context ) { PASMPAGE_CONTEXT context; PDNA_NODE node; context = Context; switch (Message) { case TreeNewGetChildren: { PPH_TREENEW_GET_CHILDREN getChildren = Parameter1; node = (PDNA_NODE)getChildren->Node; if (!node) { getChildren->Children = (PPH_TREENEW_NODE *)context->NodeRootList->Items; getChildren->NumberOfChildren = context->NodeRootList->Count; } else { if (node->Type == DNA_TYPE_APPDOMAIN || node == context->ClrV2Node) { // Sort the assemblies. qsort(node->Children->Items, node->Children->Count, sizeof(PVOID), AssemblyNodeNameCompareFunction); } getChildren->Children = (PPH_TREENEW_NODE *)node->Children->Items; getChildren->NumberOfChildren = node->Children->Count; } } return TRUE; case TreeNewIsLeaf: { PPH_TREENEW_IS_LEAF isLeaf = Parameter1; node = (PDNA_NODE)isLeaf->Node; isLeaf->IsLeaf = node->Children->Count == 0; } return TRUE; case TreeNewGetCellText: { PPH_TREENEW_GET_CELL_TEXT getCellText = Parameter1; node = (PDNA_NODE)getCellText->Node; switch (getCellText->Id) { case DNATNC_STRUCTURE: getCellText->Text = node->StructureText; break; case DNATNC_ID: getCellText->Text = PhGetStringRef(node->IdText); break; case DNATNC_FLAGS: getCellText->Text = PhGetStringRef(node->FlagsText); break; case DNATNC_PATH: getCellText->Text = PhGetStringRef(node->PathText); break; case DNATNC_NATIVEPATH: getCellText->Text = PhGetStringRef(node->NativePathText); break; default: return FALSE; } getCellText->Flags = TN_CACHE; } return TRUE; case TreeNewGetCellTooltip: { PPH_TREENEW_GET_CELL_TOOLTIP getCellTooltip = Parameter1; node = (PDNA_NODE)getCellTooltip->Node; if (getCellTooltip->Column->Id != 0 || node->Type != DNA_TYPE_ASSEMBLY) return FALSE; if (!PhIsNullOrEmptyString(node->u.Assembly.FullyQualifiedAssemblyName)) { getCellTooltip->Text = node->u.Assembly.FullyQualifiedAssemblyName->sr; getCellTooltip->Unfolding = FALSE; } else { return FALSE; } } return TRUE; case TreeNewKeyDown: { PPH_TREENEW_KEY_EVENT keyEvent = Parameter1; switch (keyEvent->VirtualKey) { case 'C': if (GetKeyState(VK_CONTROL) < 0) SendMessage(context->WindowHandle, WM_COMMAND, ID_COPY, 0); break; } } return TRUE; case TreeNewContextMenu: { PPH_TREENEW_MOUSE_EVENT mouseEvent = Parameter1; DotNetAsmShowContextMenu(context, mouseEvent->Location); } return TRUE; } return FALSE; }
VOID NTAPI TreeNewMessageCallback( _In_opt_ PVOID Parameter, _In_opt_ PVOID Context ) { PPH_PLUGIN_TREENEW_MESSAGE message = Parameter; switch (message->Message) { case TreeNewGetCellText: { PPH_TREENEW_GET_CELL_TEXT getCellText = message->Parameter1; switch (message->SubId) { case COLUMN_ID_VIUSTOTAL_PROCESS: { PPH_PROCESS_NODE processNode = (PPH_PROCESS_NODE)getCellText->Node; PPROCESS_EXTENSION extension = PhPluginGetObjectExtension(PluginInstance, processNode->ProcessItem, EmProcessItemType); getCellText->Text = PhGetStringRef(extension->VirusTotalResult); } break; case COLUMN_ID_VIUSTOTAL_MODULE: { PPH_MODULE_NODE moduleNode = (PPH_MODULE_NODE)getCellText->Node; PPROCESS_EXTENSION extension = PhPluginGetObjectExtension(PluginInstance, moduleNode->ModuleItem, EmModuleItemType); getCellText->Text = PhGetStringRef(extension->VirusTotalResult); } break; case COLUMN_ID_VIUSTOTAL_SERVICE: { PPH_SERVICE_NODE serviceNode = (PPH_SERVICE_NODE)getCellText->Node; PPROCESS_EXTENSION extension = PhPluginGetObjectExtension(PluginInstance, serviceNode->ServiceItem, EmServiceItemType); getCellText->Text = PhGetStringRef(extension->VirusTotalResult); } break; } } break; case TreeNewCustomDraw: { PPH_TREENEW_CUSTOM_DRAW customDraw = message->Parameter1; PPROCESS_EXTENSION extension = NULL; PH_STRINGREF text; if (!VirusTotalScanningEnabled) { static PH_STRINGREF disabledText = PH_STRINGREF_INIT(L"Scanning disabled"); DrawText( customDraw->Dc, disabledText.Buffer, (ULONG)disabledText.Length / 2, &customDraw->CellRect, DT_CENTER | DT_VCENTER | DT_END_ELLIPSIS | DT_SINGLELINE ); return; } switch (message->SubId) { case COLUMN_ID_VIUSTOTAL_PROCESS: { PPH_PROCESS_NODE processNode = (PPH_PROCESS_NODE)customDraw->Node; extension = PhPluginGetObjectExtension(PluginInstance, processNode->ProcessItem, EmProcessItemType); } break; case COLUMN_ID_VIUSTOTAL_MODULE: { PPH_MODULE_NODE moduleNode = (PPH_MODULE_NODE)customDraw->Node; extension = PhPluginGetObjectExtension(PluginInstance, moduleNode->ModuleItem, EmModuleItemType); } break; case COLUMN_ID_VIUSTOTAL_SERVICE: { PPH_SERVICE_NODE serviceNode = (PPH_SERVICE_NODE)customDraw->Node; extension = PhPluginGetObjectExtension(PluginInstance, serviceNode->ServiceItem, EmServiceItemType); } break; } if (!extension) break; //if (extension->Positives > 0) // SetTextColor(customDraw->Dc, RGB(0xff, 0x0, 0x0)); text = PhGetStringRef(extension->VirusTotalResult); DrawText( customDraw->Dc, text.Buffer, (ULONG)text.Length / sizeof(WCHAR), &customDraw->CellRect, DT_CENTER | DT_VCENTER | DT_END_ELLIPSIS | DT_SINGLELINE ); } break; } }
INT_PTR CALLBACK EtwDiskNetworkPageDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { LPPROPSHEETPAGE propSheetPage; PPH_PROCESS_PROPPAGECONTEXT propPageContext; PPH_PROCESS_ITEM processItem; PET_DISKNET_CONTEXT context; if (PhPropPageDlgProcHeader(hwndDlg, uMsg, lParam, &propSheetPage, &propPageContext, &processItem)) { context = propPageContext->Context; } else { return FALSE; } switch (uMsg) { case WM_INITDIALOG: { ULONG sampleCount; // We have already set the group boxes to have WS_EX_TRANSPARENT to fix // the drawing issue that arises when using WS_CLIPCHILDREN. However // in removing the flicker from the graphs the group boxes will now flicker. // It's a good tradeoff since no one stares at the group boxes. PhSetWindowStyle(hwndDlg, WS_CLIPCHILDREN, WS_CLIPCHILDREN); sampleCount = PhGetIntegerSetting(L"SampleCount"); context = PhAllocateZero(sizeof(ET_DISKNET_CONTEXT)); context->WindowHandle = hwndDlg; context->Block = EtGetProcessBlock(processItem); context->Enabled = TRUE; context->DiskGroupBox = GetDlgItem(hwndDlg, IDC_GROUPDISK); context->NetworkGroupBox = GetDlgItem(hwndDlg, IDC_GROUPNETWORK); propPageContext->Context = context; PhInitializeLayoutManager(&context->LayoutManager, hwndDlg); PhInitializeGraphState(&context->DiskGraphState); PhInitializeGraphState(&context->NetworkGraphState); PhInitializeCircularBuffer_ULONG64(&context->DiskReadHistory, sampleCount); PhInitializeCircularBuffer_ULONG64(&context->DiskWriteHistory, sampleCount); PhInitializeCircularBuffer_ULONG64(&context->NetworkSendHistory, sampleCount); PhInitializeCircularBuffer_ULONG64(&context->NetworkReceiveHistory, sampleCount); EtwDiskNetworkCreateGraphs(context); EtwDiskNetworkCreatePanel(context); EtwDiskNetworkUpdateInfo(context); EtwDiskNetworkUpdatePanel(context); PhRegisterCallback( PhGetGeneralCallback(GeneralCallbackProcessProviderUpdatedEvent), EtwDiskNetworkUpdateHandler, context, &context->ProcessesUpdatedRegistration ); PhInitializeWindowTheme(hwndDlg, !!PhGetIntegerSetting(L"EnableThemeSupport")); } break; case WM_DESTROY: { PhDeleteLayoutManager(&context->LayoutManager); PhDeleteGraphState(&context->DiskGraphState); PhDeleteGraphState(&context->NetworkGraphState); PhDeleteCircularBuffer_ULONG64(&context->DiskReadHistory); PhDeleteCircularBuffer_ULONG64(&context->DiskWriteHistory); PhDeleteCircularBuffer_ULONG64(&context->NetworkSendHistory); PhDeleteCircularBuffer_ULONG64(&context->NetworkReceiveHistory); if (context->DiskGraphHandle) DestroyWindow(context->DiskGraphHandle); if (context->NetworkGraphHandle) DestroyWindow(context->NetworkGraphHandle); if (context->PanelHandle) DestroyWindow(context->PanelHandle); PhUnregisterCallback(PhGetGeneralCallback(GeneralCallbackProcessProviderUpdatedEvent), &context->ProcessesUpdatedRegistration); PhFree(context); } break; case WM_SHOWWINDOW: { if (PhBeginPropPageLayout(hwndDlg, propPageContext)) PhEndPropPageLayout(hwndDlg, propPageContext); } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case PSN_SETACTIVE: context->Enabled = TRUE; break; case PSN_KILLACTIVE: context->Enabled = FALSE; break; case GCN_GETDRAWINFO: { PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)header; PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo; if (header->hwndFrom == context->DiskGraphHandle) { if (PhGetIntegerSetting(L"GraphShowText")) { HDC hdc; PhMoveReference(&context->DiskGraphState.Text, PhFormatString( L"R: %s, W: %s", PhaFormatSize(context->CurrentDiskRead, ULONG_MAX)->Buffer, PhaFormatSize(context->CurrentDiskWrite, ULONG_MAX)->Buffer )); hdc = Graph_GetBufferedContext(context->DiskGraphHandle); SelectObject(hdc, PhApplicationFont); PhSetGraphText(hdc, drawInfo, &context->DiskGraphState.Text->sr, &NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT); } else { drawInfo->Text.Buffer = NULL; } drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y | PH_GRAPH_LABEL_MAX_Y | PH_GRAPH_USE_LINE_2; PhSiSetColorsGraphDrawInfo(drawInfo, PhGetIntegerSetting(L"ColorIoReadOther"), PhGetIntegerSetting(L"ColorIoWrite")); PhGraphStateGetDrawInfo(&context->DiskGraphState, getDrawInfo, context->DiskReadHistory.Count); if (!context->DiskGraphState.Valid) { FLOAT max = 0; for (ULONG i = 0; i < drawInfo->LineDataCount; i++) { FLOAT data1; FLOAT data2; context->DiskGraphState.Data1[i] = data1 = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->DiskReadHistory, i); context->DiskGraphState.Data2[i] = data2 = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->DiskWriteHistory, i); if (max < data1 + data2) max = data1 + data2; } // Minimum scaling of 1 MB. //if (max < 1024 * 1024) // max = 1024 * 1024; if (max != 0) { // Scale the data. PhDivideSinglesBySingle( context->DiskGraphState.Data1, max, drawInfo->LineDataCount ); PhDivideSinglesBySingle( context->DiskGraphState.Data2, max, drawInfo->LineDataCount ); } drawInfo->LabelYFunction = PhSiSizeLabelYFunction; drawInfo->LabelYFunctionParameter = max; context->DiskGraphState.Valid = TRUE; } } else if (header->hwndFrom == context->NetworkGraphHandle) { if (PhGetIntegerSetting(L"GraphShowText")) { HDC hdc; PhMoveReference(&context->NetworkGraphState.Text, PhFormatString( L"R: %s, S: %s", PhaFormatSize(context->CurrentNetworkReceive, ULONG_MAX)->Buffer, PhaFormatSize(context->CurrentNetworkSend, ULONG_MAX)->Buffer )); hdc = Graph_GetBufferedContext(context->NetworkGraphHandle); SelectObject(hdc, PhApplicationFont); PhSetGraphText(hdc, drawInfo, &context->NetworkGraphState.Text->sr, &NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT); } else { drawInfo->Text.Buffer = NULL; } drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y | PH_GRAPH_LABEL_MAX_Y | PH_GRAPH_USE_LINE_2; PhSiSetColorsGraphDrawInfo(drawInfo, PhGetIntegerSetting(L"ColorIoReadOther"), PhGetIntegerSetting(L"ColorIoWrite")); PhGraphStateGetDrawInfo(&context->NetworkGraphState, getDrawInfo, context->NetworkSendHistory.Count); if (!context->NetworkGraphState.Valid) { FLOAT max = 0; for (ULONG i = 0; i < drawInfo->LineDataCount; i++) { FLOAT data1; FLOAT data2; context->NetworkGraphState.Data1[i] = data1 = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->NetworkReceiveHistory, i); context->NetworkGraphState.Data2[i] = data2 = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->NetworkSendHistory, i); if (max < data1 + data2) max = data1 + data2; } // Minimum scaling of 1 MB. //if (max < 1024 * 1024) // max = 1024 * 1024; if (max != 0) { // Scale the data. PhDivideSinglesBySingle( context->NetworkGraphState.Data1, max, drawInfo->LineDataCount ); PhDivideSinglesBySingle( context->NetworkGraphState.Data2, max, drawInfo->LineDataCount ); } drawInfo->LabelYFunction = PhSiSizeLabelYFunction; drawInfo->LabelYFunctionParameter = max; context->NetworkGraphState.Valid = TRUE; } } } break; case GCN_GETTOOLTIPTEXT: { PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)lParam; if (getTooltipText->Index < getTooltipText->TotalCount) { if (header->hwndFrom == context->DiskGraphHandle) { if (context->DiskGraphState.TooltipIndex != getTooltipText->Index) { ULONG64 diskRead = PhGetItemCircularBuffer_ULONG64( &context->DiskReadHistory, getTooltipText->Index ); ULONG64 diskWrite = PhGetItemCircularBuffer_ULONG64( &context->DiskWriteHistory, getTooltipText->Index ); PhMoveReference(&context->DiskGraphState.TooltipText, PhFormatString( L"R: %s\nW: %s\n%s", PhaFormatSize(diskRead, ULONG_MAX)->Buffer, PhaFormatSize(diskWrite, ULONG_MAX)->Buffer, ((PPH_STRING)PH_AUTO(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer )); } getTooltipText->Text = PhGetStringRef(context->DiskGraphState.TooltipText); } else if (header->hwndFrom == context->NetworkGraphHandle) { if (context->NetworkGraphState.TooltipIndex != getTooltipText->Index) { ULONG64 networkSend = PhGetItemCircularBuffer_ULONG64( &context->NetworkSendHistory, getTooltipText->Index ); ULONG64 networkReceive = PhGetItemCircularBuffer_ULONG64( &context->NetworkReceiveHistory, getTooltipText->Index ); PhMoveReference(&context->NetworkGraphState.TooltipText, PhFormatString( L"S: %s\nR: %s\n%s", PhaFormatSize(networkSend, ULONG_MAX)->Buffer, PhaFormatSize(networkReceive, ULONG_MAX)->Buffer, ((PPH_STRING)PH_AUTO(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer )); } getTooltipText->Text = PhGetStringRef(context->NetworkGraphState.TooltipText); } } } break; } } break; case ET_WM_UPDATE: { if (context->Enabled) { EtwDiskNetworkUpdateInfo(context); EtwDiskNetworkUpdateGraphs(context); EtwDiskNetworkUpdatePanel(context); } } break; case WM_SIZE: { EtwDiskNetworkLayoutGraphs(context); } break; } return FALSE; }