static INT_PTR CALLBACK NetworkOutputDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PNETWORK_OUTPUT_CONTEXT context; if (uMsg == WM_INITDIALOG) { context = (PNETWORK_OUTPUT_CONTEXT)lParam; SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PNETWORK_OUTPUT_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_DESTROY) { PhSaveWindowPlacementToSetting(SETTING_NAME_TRACERT_WINDOW_POSITION, SETTING_NAME_TRACERT_WINDOW_SIZE, hwndDlg); PhDeleteLayoutManager(&context->LayoutManager); if (context->ProcessHandle) { // Terminate the child process. PhTerminateProcess(context->ProcessHandle, STATUS_SUCCESS); // Close the child process handle. NtClose(context->ProcessHandle); } // Close the pipe handle. if (context->PipeReadHandle) NtClose(context->PipeReadHandle); RemoveProp(hwndDlg, L"Context"); PhFree(context); } } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { PH_RECTANGLE windowRectangle; context->WindowHandle = hwndDlg; context->OutputHandle = GetDlgItem(hwndDlg, IDC_NETOUTPUTEDIT); PhInitializeLayoutManager(&context->LayoutManager, hwndDlg); PhAddLayoutItem(&context->LayoutManager, context->OutputHandle, NULL, PH_ANCHOR_ALL); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_MORE_INFO), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT); windowRectangle.Position = PhGetIntegerPairSetting(SETTING_NAME_TRACERT_WINDOW_POSITION); windowRectangle.Size = PhGetIntegerPairSetting(SETTING_NAME_TRACERT_WINDOW_SIZE); if (MinimumSize.left == -1) { RECT rect; rect.left = 0; rect.top = 0; rect.right = 190; rect.bottom = 120; MapDialogRect(hwndDlg, &rect); MinimumSize = rect; MinimumSize.left = 0; } // Check for first-run default position. if (windowRectangle.Position.X == 0 || windowRectangle.Position.Y == 0) { PhCenterWindow(hwndDlg, GetParent(hwndDlg)); } else { PhLoadWindowPlacementFromSetting(SETTING_NAME_TRACERT_WINDOW_POSITION, SETTING_NAME_TRACERT_WINDOW_SIZE, hwndDlg); } if (context->IpAddress.Type == PH_IPV4_NETWORK_TYPE) { RtlIpv4AddressToString(&context->IpAddress.InAddr, context->IpAddressString); } else { RtlIpv6AddressToString(&context->IpAddress.In6Addr, context->IpAddressString); } switch (context->Action) { case NETWORK_ACTION_TRACEROUTE: { HANDLE dialogThread = INVALID_HANDLE_VALUE; Static_SetText(context->WindowHandle, PhaFormatString(L"Tracing route to %s...", context->IpAddressString)->Buffer ); if (dialogThread = PhCreateThread(0, NetworkTracertThreadStart, (PVOID)context)) NtClose(dialogThread); } break; case NETWORK_ACTION_WHOIS: { HANDLE dialogThread = INVALID_HANDLE_VALUE; Static_SetText(context->WindowHandle, PhaFormatString(L"Whois %s...", context->IpAddressString)->Buffer ); ShowWindow(GetDlgItem(hwndDlg, IDC_MORE_INFO), SW_SHOW); if (dialogThread = PhCreateThread(0, NetworkWhoisThreadStart, (PVOID)context)) NtClose(dialogThread); } break; } } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: PostQuitMessage(0); break; } } break; case WM_SIZE: PhLayoutManagerLayout(&context->LayoutManager); break; case WM_SIZING: PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom); break; case WM_CTLCOLORDLG: case WM_CTLCOLORSTATIC: { HDC hDC = (HDC)wParam; HWND hwndChild = (HWND)lParam; // Check if old graph colors are enabled. if (!PhGetIntegerSetting(L"GraphColorMode")) break; // Set a transparent background for the control backcolor. SetBkMode(hDC, TRANSPARENT); // Check for our edit control and change the color. if (hwndChild == context->OutputHandle) { // Set text color as the Green PH graph text color. SetTextColor(hDC, RGB(124, 252, 0)); // Set a black control backcolor. return (INT_PTR)GetStockBrush(BLACK_BRUSH); } } break; case WM_NOTIFY: { switch (((LPNMHDR)lParam)->code) { case NM_CLICK: case NM_RETURN: { PNMLINK syslink = (PNMLINK)lParam; if (syslink->hdr.idFrom == IDC_MORE_INFO) { PhShellExecute( PhMainWndHandle, PhaConcatStrings2(L"http://wq.apnic.net/apnic-bin/whois.pl?searchtext=", context->IpAddressString)->Buffer, NULL ); } } break; } } break; case NTM_RECEIVEDTRACE: { OEM_STRING inputString; UNICODE_STRING convertedString; PH_STRING_BUILDER receivedString; if (wParam != 0) { inputString.Buffer = (PCHAR)lParam; inputString.Length = (USHORT)wParam; if (NT_SUCCESS(RtlOemStringToUnicodeString(&convertedString, &inputString, TRUE))) { PPH_STRING windowText = NULL; PhInitializeStringBuilder(&receivedString, PAGE_SIZE); // Get the current output text. windowText = PhGetWindowText(context->OutputHandle); // Append the current output text to the New string. if (!PhIsNullOrEmptyString(windowText)) PhAppendStringBuilder(&receivedString, &windowText->sr); PhAppendFormatStringBuilder(&receivedString, L"%s", convertedString.Buffer); // Remove leading newlines. if (receivedString.String->Length >= 2 * 2 && receivedString.String->Buffer[0] == '\r' && receivedString.String->Buffer[1] == '\n') { PhRemoveStringBuilder(&receivedString, 0, 2); } SetWindowText(context->OutputHandle, receivedString.String->Buffer); SendMessage( context->OutputHandle, EM_SETSEL, receivedString.String->Length / 2 - 1, receivedString.String->Length / 2 - 1 ); SendMessage(context->OutputHandle, WM_VSCROLL, SB_BOTTOM, 0); PhDereferenceObject(windowText); PhDeleteStringBuilder(&receivedString); RtlFreeUnicodeString(&convertedString); } } } break; case NTM_RECEIVEDWHOIS: { OEM_STRING inputString; UNICODE_STRING convertedString; PH_STRING_BUILDER receivedString; if (lParam != 0) { inputString.Buffer = (PCHAR)lParam; inputString.Length = (USHORT)wParam; if (NT_SUCCESS(RtlOemStringToUnicodeString(&convertedString, &inputString, TRUE))) { USHORT i; PhInitializeStringBuilder(&receivedString, PAGE_SIZE); // Convert carriage returns. for (i = 0; i < convertedString.Length; i++) { if (convertedString.Buffer[i] == '\n') { PhAppendStringBuilder2(&receivedString, L"\r\n"); } else { PhAppendCharStringBuilder(&receivedString, convertedString.Buffer[i]); } } // Remove leading newlines. if (receivedString.String->Length >= 2 * 2 && receivedString.String->Buffer[0] == '\r' && receivedString.String->Buffer[1] == '\n') { PhRemoveStringBuilder(&receivedString, 0, 2); } SetWindowText(context->OutputHandle, receivedString.String->Buffer); SendMessage( context->OutputHandle, EM_SETSEL, receivedString.String->Length / 2 - 1, receivedString.String->Length / 2 - 1 ); SendMessage(context->OutputHandle, WM_VSCROLL, SB_TOP, 0); PhDeleteStringBuilder(&receivedString); RtlFreeUnicodeString(&convertedString); } PhFree((PVOID)lParam); } } break; case NTM_RECEIVEDFINISH: { PPH_STRING windowText = PhGetWindowText(context->WindowHandle); if (windowText) { Static_SetText( context->WindowHandle, PhaFormatString(L"%s Finished.", windowText->Buffer)->Buffer ); PhDereferenceObject(windowText); } } break; } return FALSE; }
INT_PTR CALLBACK PhpSessionPropertiesDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { ULONG sessionId = (ULONG)lParam; WINSTATIONINFORMATION winStationInfo; BOOLEAN haveWinStationInfo; WINSTATIONCLIENT clientInfo; BOOLEAN haveClientInfo; ULONG returnLength; PWSTR stateString; SetProp(hwndDlg, L"SessionId", UlongToHandle(sessionId)); PhCenterWindow(hwndDlg, GetParent(hwndDlg)); // Query basic session information haveWinStationInfo = WinStationQueryInformationW( NULL, sessionId, WinStationInformation, &winStationInfo, sizeof(WINSTATIONINFORMATION), &returnLength ); // Query client information haveClientInfo = WinStationQueryInformationW( NULL, sessionId, WinStationClient, &clientInfo, sizeof(WINSTATIONCLIENT), &returnLength ); if (haveWinStationInfo) { SetDlgItemText(hwndDlg, IDC_USERNAME, PhaFormatString(L"%s\\%s", winStationInfo.Domain, winStationInfo.UserName)->Buffer); } SetDlgItemInt(hwndDlg, IDC_SESSIONID, sessionId, FALSE); if (haveWinStationInfo) { if (PhFindStringSiKeyValuePairs( PhpConnectStatePairs, sizeof(PhpConnectStatePairs), winStationInfo.ConnectState, &stateString )) { SetDlgItemText(hwndDlg, IDC_STATE, stateString); } } if (haveWinStationInfo && winStationInfo.LogonTime.QuadPart != 0) { SYSTEMTIME systemTime; PPH_STRING time; PhLargeIntegerToLocalSystemTime(&systemTime, &winStationInfo.LogonTime); time = PhFormatDateTime(&systemTime); SetDlgItemText(hwndDlg, IDC_LOGONTIME, time->Buffer); PhDereferenceObject(time); } if (haveWinStationInfo && winStationInfo.ConnectTime.QuadPart != 0) { SYSTEMTIME systemTime; PPH_STRING time; PhLargeIntegerToLocalSystemTime(&systemTime, &winStationInfo.ConnectTime); time = PhFormatDateTime(&systemTime); SetDlgItemText(hwndDlg, IDC_CONNECTTIME, time->Buffer); PhDereferenceObject(time); } if (haveWinStationInfo && winStationInfo.DisconnectTime.QuadPart != 0) { SYSTEMTIME systemTime; PPH_STRING time; PhLargeIntegerToLocalSystemTime(&systemTime, &winStationInfo.DisconnectTime); time = PhFormatDateTime(&systemTime); SetDlgItemText(hwndDlg, IDC_DISCONNECTTIME, time->Buffer); PhDereferenceObject(time); } if (haveWinStationInfo && winStationInfo.LastInputTime.QuadPart != 0) { SYSTEMTIME systemTime; PPH_STRING time; PhLargeIntegerToLocalSystemTime(&systemTime, &winStationInfo.LastInputTime); time = PhFormatDateTime(&systemTime); SetDlgItemText(hwndDlg, IDC_LASTINPUTTIME, time->Buffer); PhDereferenceObject(time); } if (haveClientInfo && clientInfo.ClientName[0] != 0) { WCHAR addressString[65]; SetDlgItemText(hwndDlg, IDC_CLIENTNAME, clientInfo.ClientName); if (clientInfo.ClientAddressFamily == AF_INET6) { struct in6_addr address; ULONG i; PUSHORT in; PUSHORT out; // IPv6 is special - the client address data is a reversed version of // the real address. in = (PUSHORT)clientInfo.ClientAddress; out = (PUSHORT)address.u.Word; for (i = 8; i != 0; i--) { *out = _byteswap_ushort(*in); in++; out++; } RtlIpv6AddressToString(&address, addressString); } else { wcscpy_s(addressString, 65, clientInfo.ClientAddress); } SetDlgItemText(hwndDlg, IDC_CLIENTADDRESS, addressString); SetDlgItemText(hwndDlg, IDC_CLIENTDISPLAY, PhaFormatString(L"%ux%u@%u", clientInfo.HRes, clientInfo.VRes, clientInfo.ColorDepth)->Buffer ); } SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDOK), TRUE); } break; case WM_DESTROY: { RemoveProp(hwndDlg, L"SessionId"); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: EndDialog(hwndDlg, IDOK); break; } } break; } return FALSE; }
INT_PTR CALLBACK NetworkOutputDlgProc( __in HWND hwndDlg, __in UINT uMsg, __in WPARAM wParam, __in LPARAM lParam ) { PNETWORK_OUTPUT_CONTEXT context; if (uMsg == WM_INITDIALOG) { context = (PNETWORK_OUTPUT_CONTEXT)lParam; SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PNETWORK_OUTPUT_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_DESTROY) RemoveProp(hwndDlg, L"Context"); } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { WCHAR addressString[65]; HANDLE pipeWriteHandle; PhCenterWindow(hwndDlg, GetParent(hwndDlg)); context->WindowHandle = hwndDlg; PhInitializeLayoutManager(&context->LayoutManager, hwndDlg); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_TEXT), NULL, PH_ANCHOR_ALL); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT); if (context->Address.Type == PH_IPV4_NETWORK_TYPE) RtlIpv4AddressToString(&context->Address.InAddr, addressString); else RtlIpv6AddressToString(&context->Address.In6Addr, addressString); switch (context->Action) { case NETWORK_ACTION_PING: case NETWORK_ACTION_TRACEROUTE: if (context->Action == NETWORK_ACTION_PING) { SetWindowText(hwndDlg, PhaFormatString(L"Pinging %s...", addressString)->Buffer); } else { SetWindowText(hwndDlg, PhaFormatString(L"Tracing route to %s...", addressString)->Buffer); } // Doing this properly would be too complex, so we'll just // execute ping.exe/traceroute.exe and display its output. if (CreatePipe(&context->PipeReadHandle, &pipeWriteHandle, NULL, 0)) { STARTUPINFO startupInfo = { sizeof(startupInfo) }; PPH_STRING command; OBJECT_HANDLE_FLAG_INFORMATION flagInfo; startupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; startupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); startupInfo.hStdOutput = pipeWriteHandle; startupInfo.hStdError = pipeWriteHandle; startupInfo.wShowWindow = SW_HIDE; if (context->Action == NETWORK_ACTION_PING) { command = PhaFormatString( L"%s\\system32\\ping.exe %s", USER_SHARED_DATA->NtSystemRoot, addressString ); } else { command = PhaFormatString( L"%s\\system32\\tracert.exe %s", USER_SHARED_DATA->NtSystemRoot, addressString ); } // Allow the write handle to be inherited. flagInfo.Inherit = TRUE; flagInfo.ProtectFromClose = FALSE; NtSetInformationObject( pipeWriteHandle, ObjectHandleFlagInformation, &flagInfo, sizeof(OBJECT_HANDLE_FLAG_INFORMATION) ); PhCreateProcessWin32Ex( NULL, command->Buffer, NULL, NULL, &startupInfo, PH_CREATE_PROCESS_INHERIT_HANDLES, NULL, NULL, &context->ProcessHandle, NULL ); // Essential; when the process exits, the last instance of the pipe // will be disconnected and our thread will exit. NtClose(pipeWriteHandle); // Create a thread which will wait for output and display it. context->ThreadHandle = PhCreateThread(0, NetworkWorkerThreadStart, context); } break; } } break; case WM_DESTROY: { PhAcquireQueuedLockExclusive(&context->WindowHandleLock); context->WindowHandle = NULL; PhReleaseQueuedLockExclusive(&context->WindowHandleLock); if (context->ProcessHandle) { NtTerminateProcess(context->ProcessHandle, STATUS_SUCCESS); NtClose(context->ProcessHandle); } } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: EndDialog(hwndDlg, IDOK); break; } } break; case WM_SIZE: PhLayoutManagerLayout(&context->LayoutManager); break; case NTM_DONE: { PPH_STRING windowText = PhGetWindowText(hwndDlg); if (windowText) { SetWindowText(hwndDlg, PhaFormatString(L"%s Finished.", windowText->Buffer)->Buffer); PhDereferenceObject(windowText); } } break; case NTM_RECEIVED: { OEM_STRING inputString; UNICODE_STRING convertedString; if (wParam != 0) { inputString.Buffer = (PCHAR)lParam; inputString.Length = (USHORT)wParam; if (NT_SUCCESS(RtlOemStringToUnicodeString(&convertedString, &inputString, TRUE))) { PhAppendStringBuilderEx(&context->ReceivedString, convertedString.Buffer, convertedString.Length); RtlFreeUnicodeString(&convertedString); // Remove leading newlines. if ( context->ReceivedString.String->Length >= 2 * 2 && context->ReceivedString.String->Buffer[0] == '\r' && context->ReceivedString.String->Buffer[1] == '\n' ) { PhRemoveStringBuilder(&context->ReceivedString, 0, 2); } SetDlgItemText(hwndDlg, IDC_TEXT, context->ReceivedString.String->Buffer); SendMessage( GetDlgItem(hwndDlg, IDC_TEXT), EM_SETSEL, context->ReceivedString.String->Length / 2 - 1, context->ReceivedString.String->Length / 2 - 1 ); SendMessage(GetDlgItem(hwndDlg, IDC_TEXT), WM_VSCROLL, SB_BOTTOM, 0); } } } break; } return FALSE; }
static PDNS_RECORD _SearchRootQuery( _In_ PWCHAR RemoteAddressString, _In_ PDNS_RECORD DnsCacheList ) { PDNS_RECORD p = DnsCacheList; PWCHAR orig = RemoteAddressString; PDNS_RECORD result = NULL; WCHAR ipAddrString[INET6_ADDRSTRLEN] = L""; while (p) { BOOLEAN found = FALSE; if (p->wType == DNS_TYPE_A) { RtlIpv4AddressToString((IN_ADDR*)&p->Data.A.IpAddress, ipAddrString); if (PhEqualStringZ(ipAddrString, orig, TRUE)) { found = TRUE; } } if (p->wType == DNS_TYPE_AAAA) { RtlIpv6AddressToString((IN6_ADDR*)&p->Data.AAAA.Ip6Address, ipAddrString); if (PhEqualStringZ(ipAddrString, orig, TRUE)) { found = TRUE; } } if (p->wType == DNS_TYPE_MX && PhEqualStringZ(orig, p->Data.MX.pNameExchange, TRUE)) { found = TRUE; } if (p->wType == DNS_TYPE_SRV && PhEqualStringZ(orig, p->Data.SRV.pNameTarget, TRUE)) { found = TRUE; } else if (p->wType == DNS_TYPE_CNAME && PhEqualStringZ(p->Data.CNAME.pNameHost, orig, TRUE)) { found = TRUE; } if (found) { PDNS_RECORD tmp = DnsRecordCopy(p); tmp->pNext = result; result = tmp; } p = p->pNext; } if (result) { PDNS_RECORD p = result; PDNS_RECORD finalResult = NULL; while (p) { PDNS_RECORD r = _SearchRootQuery(p->pName, DnsCacheList); if (r) { PDNS_RECORD t = r; while (t->pNext) t = t->pNext; t->pNext = finalResult; finalResult = r; } p = p->pNext; } if (finalResult) { DnsRecordListFree(result, DnsFreeRecordList); return finalResult; } return result; } return NULL; }
VOID EnumDnsCacheTable( _In_ HWND ListViewHandle ) { PDNS_RECORD dnsRecordPtr = TraverseDnsCacheTable(NULL); PDNS_RECORD dnsRecordRootPtr = dnsRecordPtr; while (dnsRecordPtr) { INT itemIndex = MAXINT; ULONG ipAddrStringLength = INET6_ADDRSTRLEN; WCHAR ipAddrString[INET6_ADDRSTRLEN] = L""; itemIndex = PhAddListViewItem( ListViewHandle, MAXINT, PhaFormatString(L"%s", dnsRecordPtr->pName)->Buffer, NULL ); if (dnsRecordPtr->wType == DNS_TYPE_A) { IN_ADDR ipv4Address = { 0 }; ipv4Address.s_addr = dnsRecordPtr->Data.A.IpAddress; RtlIpv4AddressToString(&ipv4Address, ipAddrString); PhSetListViewSubItem(ListViewHandle, itemIndex, 1, PhaFormatString(L"A")->Buffer); PhSetListViewSubItem(ListViewHandle, itemIndex, 2, PhaFormatString(L"%s", ipAddrString)->Buffer); } else if (dnsRecordPtr->wType == DNS_TYPE_AAAA) { IN6_ADDR ipv6Address = { 0 }; memcpy_s( ipv6Address.s6_addr, sizeof(ipv6Address.s6_addr), dnsRecordPtr->Data.AAAA.Ip6Address.IP6Byte, sizeof(dnsRecordPtr->Data.AAAA.Ip6Address.IP6Byte) ); RtlIpv6AddressToString(&ipv6Address, ipAddrString); PhSetListViewSubItem(ListViewHandle, itemIndex, 1, PhaFormatString(L"AAAA")->Buffer); PhSetListViewSubItem(ListViewHandle, itemIndex, 2, PhaFormatString(L"%s", ipAddrString)->Buffer); } else if (dnsRecordPtr->wType == DNS_TYPE_PTR) { PhSetListViewSubItem(ListViewHandle, itemIndex, 1, PhaFormatString(L"PTR")->Buffer); PhSetListViewSubItem(ListViewHandle, itemIndex, 2, PhaFormatString(L"%s", dnsRecordPtr->Data.PTR.pNameHost)->Buffer); } else if (dnsRecordPtr->wType == DNS_TYPE_CNAME) { PhSetListViewSubItem(ListViewHandle, itemIndex, 1, PhaFormatString(L"CNAME")->Buffer); PhSetListViewSubItem(ListViewHandle, itemIndex, 2, PhaFormatString(L"%s", dnsRecordPtr->Data.CNAME.pNameHost)->Buffer); } else if (dnsRecordPtr->wType == DNS_TYPE_SRV) { PhSetListViewSubItem(ListViewHandle, itemIndex, 1, PhaFormatString(L"SRV")->Buffer); PhSetListViewSubItem(ListViewHandle, itemIndex, 2, PhaFormatString(L"%s:%u", dnsRecordPtr->Data.SRV.pNameTarget, dnsRecordPtr->Data.SRV.wPort)->Buffer); } else if (dnsRecordPtr->wType == DNS_TYPE_MX) { PhSetListViewSubItem(ListViewHandle, itemIndex, 1, PhaFormatString(L"MX")->Buffer); PhSetListViewSubItem(ListViewHandle, itemIndex, 2, PhaFormatString(L"%s", dnsRecordPtr->Data.MX.pNameExchange)->Buffer); } else { PhSetListViewSubItem(ListViewHandle, itemIndex, 1, PhaFormatString(L"UNKNOWN")->Buffer); PhSetListViewSubItem(ListViewHandle, itemIndex, 2, L""); } PhSetListViewSubItem(ListViewHandle, itemIndex, 3, PhaFormatString(L"%lu", dnsRecordPtr->dwTtl)->Buffer); dnsRecordPtr = dnsRecordPtr->pNext; } if (dnsRecordRootPtr) { DnsRecordListFree(dnsRecordRootPtr, DnsFreeRecordList); } }
static INT_PTR CALLBACK NetworkPingWndProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PNETWORK_OUTPUT_CONTEXT context = NULL; if (uMsg == WM_INITDIALOG) { context = (PNETWORK_OUTPUT_CONTEXT)lParam; SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PNETWORK_OUTPUT_CONTEXT)GetProp(hwndDlg, L"Context"); } if (context == NULL) return FALSE; switch (uMsg) { case WM_INITDIALOG: { PH_RECTANGLE windowRectangle; PPH_LAYOUT_ITEM panelItem; // 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); context->WindowHandle = hwndDlg; context->ParentHandle = GetParent(hwndDlg); context->StatusHandle = GetDlgItem(hwndDlg, IDC_MAINTEXT); context->MaxPingTimeout = PhGetIntegerSetting(SETTING_NAME_PING_TIMEOUT); windowRectangle.Position = PhGetIntegerPairSetting(SETTING_NAME_PING_WINDOW_POSITION); windowRectangle.Size = PhGetIntegerPairSetting(SETTING_NAME_PING_WINDOW_SIZE); // Create the font handle. context->FontHandle = InitializeFont(context->StatusHandle); // Create the graph control. context->PingGraphHandle = CreateWindow( PH_GRAPH_CLASSNAME, NULL, WS_VISIBLE | WS_CHILD | WS_BORDER, 0, 0, 3, 3, hwndDlg, NULL, NULL, NULL ); Graph_SetTooltip(context->PingGraphHandle, TRUE); // Load the Process Hacker icon. context->IconHandle = (HICON)LoadImage( NtCurrentPeb()->ImageBaseAddress, MAKEINTRESOURCE(PHAPP_IDI_PROCESSHACKER), IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), LR_SHARED ); // Set window icon. if (context->IconHandle) SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)context->IconHandle); // Initialize the WorkQueue with a maximum of 20 threads (fix pinging slow-links with a high interval update). PhInitializeWorkQueue(&context->PingWorkQueue, 0, 20, 5000); PhInitializeGraphState(&context->PingGraphState); PhInitializeLayoutManager(&context->LayoutManager, hwndDlg); PhInitializeCircularBuffer_ULONG(&context->PingHistory, PhGetIntegerSetting(L"SampleCount")); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_ICMP_PANEL), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_ICMP_AVG), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_ICMP_MIN), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_ICMP_MAX), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_PINGS_SENT), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_PINGS_LOST), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_BAD_HASH), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_ANON_ADDR), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT); panelItem = PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_PING_LAYOUT), NULL, PH_ANCHOR_ALL); PhAddLayoutItemEx(&context->LayoutManager, context->PingGraphHandle, NULL, PH_ANCHOR_ALL, panelItem->Margin); // Load window settings. if (windowRectangle.Position.X == 0 || windowRectangle.Position.Y == 0) PhCenterWindow(hwndDlg, GetParent(hwndDlg)); else { PhLoadWindowPlacementFromSetting(SETTING_NAME_PING_WINDOW_POSITION, SETTING_NAME_PING_WINDOW_SIZE, hwndDlg); } // Initialize window layout. PhLayoutManagerLayout(&context->LayoutManager); // Convert IP Address to string format. if (context->IpAddress.Type == PH_IPV4_NETWORK_TYPE) { RtlIpv4AddressToString(&context->IpAddress.InAddr, context->IpAddressString); } else { RtlIpv6AddressToString(&context->IpAddress.In6Addr, context->IpAddressString); } SetWindowText(hwndDlg, PhaFormatString(L"Ping %s", context->IpAddressString)->Buffer); SetWindowText(context->StatusHandle, PhaFormatString(L"Pinging %s with 32 bytes of data:", context->IpAddressString)->Buffer); PhRegisterCallback( PhGetGeneralCallback(GeneralCallbackProcessesUpdated), NetworkPingUpdateHandler, context, &context->ProcessesUpdatedRegistration ); } return TRUE; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: PostQuitMessage(0); break; } } break; case WM_DESTROY: { PhUnregisterCallback( PhGetGeneralCallback(GeneralCallbackProcessesUpdated), &context->ProcessesUpdatedRegistration ); PhSaveWindowPlacementToSetting( SETTING_NAME_PING_WINDOW_POSITION, SETTING_NAME_PING_WINDOW_SIZE, hwndDlg ); if (context->PingGraphHandle) DestroyWindow(context->PingGraphHandle); if (context->IconHandle) DestroyIcon(context->IconHandle); if (context->FontHandle) DeleteObject(context->FontHandle); PhDeleteWorkQueue(&context->PingWorkQueue); PhDeleteGraphState(&context->PingGraphState); PhDeleteLayoutManager(&context->LayoutManager); RemoveProp(hwndDlg, L"Context"); PhFree(context); } break; case WM_SIZE: PhLayoutManagerLayout(&context->LayoutManager); break; case WM_SIZING: PhResizingMinimumSize((PRECT)lParam, wParam, 420, 250); break; case WM_CTLCOLORBTN: case WM_CTLCOLORDLG: case WM_CTLCOLORSTATIC: { HDC hDC = (HDC)wParam; HWND hwndChild = (HWND)lParam; // Check for our static label and change the color. if (GetDlgCtrlID(hwndChild) == IDC_MAINTEXT) { SetTextColor(hDC, RGB(19, 112, 171)); } // Set a transparent background for the control backcolor. SetBkMode(hDC, TRANSPARENT); // set window background color. return (INT_PTR)GetSysColorBrush(COLOR_WINDOW); } break; case WM_PING_UPDATE: { ULONG i = 0; ULONG maxGraphHeight = 0; ULONG pingAvgValue = 0; PhNetworkPingUpdateGraph(context); for (i = 0; i < context->PingHistory.Count; i++) { maxGraphHeight = maxGraphHeight + PhGetItemCircularBuffer_ULONG(&context->PingHistory, i); pingAvgValue = maxGraphHeight / context->PingHistory.Count; } SetDlgItemText(hwndDlg, IDC_ICMP_AVG, PhaFormatString( L"Average: %lums", pingAvgValue)->Buffer); SetDlgItemText(hwndDlg, IDC_ICMP_MIN, PhaFormatString( L"Minimum: %lums", context->PingMinMs)->Buffer); SetDlgItemText(hwndDlg, IDC_ICMP_MAX, PhaFormatString( L"Maximum: %lums", context->PingMaxMs)->Buffer); SetDlgItemText(hwndDlg, IDC_PINGS_SENT, PhaFormatString( L"Pings Sent: %lu", context->PingSentCount)->Buffer); SetDlgItemText(hwndDlg, IDC_PINGS_LOST, PhaFormatString( L"Pings Lost: %lu (%.0f%%)", context->PingLossCount, ((FLOAT)context->PingLossCount / context->PingSentCount * 100) )->Buffer); SetDlgItemText(hwndDlg, IDC_BAD_HASH, PhaFormatString( L"Bad Hashes: %lu", context->HashFailCount)->Buffer); SetDlgItemText(hwndDlg, IDC_ANON_ADDR, PhaFormatString( L"Anon Replies: %lu", context->UnknownAddrCount)->Buffer); } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case GCN_GETDRAWINFO: { PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)header; PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo; PhSiSetColorsGraphDrawInfo(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), PhGetIntegerSetting(L"ColorCpuUser")); if (header->hwndFrom == context->PingGraphHandle) { if (PhGetIntegerSetting(L"GraphShowText")) { HDC hdc = Graph_GetBufferedContext(context->PingGraphHandle); PhMoveReference(&context->PingGraphState.Text, PhFormatString(L"Ping: %lums", context->CurrentPingMs) ); SelectObject(hdc, PhApplicationFont); PhSetGraphText(hdc, drawInfo, &context->PingGraphState.Text->sr, &NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT); } else { drawInfo->Text.Buffer = NULL; } PhGraphStateGetDrawInfo( &context->PingGraphState, getDrawInfo, context->PingHistory.Count ); if (!context->PingGraphState.Valid) { ULONG i; FLOAT max = 0; for (i = 0; i < drawInfo->LineDataCount; i++) { FLOAT data1; context->PingGraphState.Data1[i] = data1 = (FLOAT)PhGetItemCircularBuffer_ULONG(&context->PingHistory, i); if (max < data1) max = data1; } // Minimum scaling of timeout (1000ms default). if (max < (FLOAT)context->MaxPingTimeout) max = (FLOAT)context->MaxPingTimeout; // Scale the data. PhxfDivideSingle2U( context->PingGraphState.Data1, max, drawInfo->LineDataCount ); context->PingGraphState.Valid = TRUE; } } } break; case GCN_GETTOOLTIPTEXT: { PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)lParam; if (getTooltipText->Index < getTooltipText->TotalCount) { if (header->hwndFrom == context->PingGraphHandle) { if (context->PingGraphState.TooltipIndex != getTooltipText->Index) { ULONG pingMs = PhGetItemCircularBuffer_ULONG(&context->PingHistory, getTooltipText->Index); PhMoveReference(&context->PingGraphState.TooltipText, PhFormatString(L"Ping: %lums", pingMs) ); } getTooltipText->Text = context->PingGraphState.TooltipText->sr; } } } break; } } break; } return FALSE; }