PPH_STRING PhEscapeStringForDelimiter( __in PPH_STRING String, __in WCHAR Delimiter ) { PH_STRING_BUILDER stringBuilder; SIZE_T length; SIZE_T i; WCHAR temp[2]; length = String->Length / 2; PhInitializeStringBuilder(&stringBuilder, String->Length / 2 * 3); temp[0] = '\\'; for (i = 0; i < length; i++) { if (String->Buffer[i] == '\\' || String->Buffer[i] == Delimiter) { temp[1] = String->Buffer[i]; PhAppendStringBuilderEx(&stringBuilder, temp, 4); } else { PhAppendCharStringBuilder(&stringBuilder, String->Buffer[i]); } } return PhFinalStringBuilderString(&stringBuilder); }
VOID PhpEscapeStringForCsv( __inout PPH_STRING_BUILDER StringBuilder, __in PPH_STRING String ) { SIZE_T i; SIZE_T length; PWCHAR runStart; ULONG runLength; length = String->Length / sizeof(WCHAR); runStart = NULL; for (i = 0; i < length; i++) { switch (String->Buffer[i]) { case '\"': if (runStart) { PhAppendStringBuilderEx(StringBuilder, runStart, runLength * sizeof(WCHAR)); runStart = NULL; } PhAppendStringBuilder2(StringBuilder, L"\"\""); break; default: if (runStart) { runLength++; } else { runStart = &String->Buffer[i]; runLength = 1; } break; } } if (runStart) PhAppendStringBuilderEx(StringBuilder, runStart, runLength * sizeof(WCHAR)); }
PPH_STRING SaveFilterList( _Inout_ PPH_LIST FilterList ) { PH_STRING_BUILDER stringBuilder; SIZE_T i; SIZE_T j; WCHAR temp[2]; PhInitializeStringBuilder(&stringBuilder, 100); temp[0] = '\\'; for (i = 0; i < FilterList->Count; i++) { PFILTER_ENTRY entry = FilterList->Items[i]; SIZE_T length; // Write the entry type. temp[1] = entry->Type == FilterInclude ? 'i' : 'e'; PhAppendStringBuilderEx(&stringBuilder, temp, 4); // Write the filter string. length = entry->Filter->Length / 2; for (j = 0; j < length; j++) { if (entry->Filter->Buffer[j] == '\\') // escape backslashes { temp[1] = entry->Filter->Buffer[j]; PhAppendStringBuilderEx(&stringBuilder, temp, 4); } else { PhAppendCharStringBuilder(&stringBuilder, entry->Filter->Buffer[j]); } } } return PhFinalStringBuilderString(&stringBuilder); }
PPH_STRING PhGetTreeNewText( __in HWND TreeNewHandle, __reserved ULONG Reserved ) { PH_STRING_BUILDER stringBuilder; PULONG displayToId; ULONG rows; ULONG columns; ULONG i; ULONG j; PhMapDisplayIndexTreeNew(TreeNewHandle, &displayToId, NULL, &columns); rows = TreeNew_GetFlatNodeCount(TreeNewHandle); PhInitializeStringBuilder(&stringBuilder, 0x100); for (i = 0; i < rows; i++) { PH_TREENEW_GET_CELL_TEXT getCellText; getCellText.Node = TreeNew_GetFlatNode(TreeNewHandle, i); assert(getCellText.Node); if (!getCellText.Node->Selected) continue; for (j = 0; j < columns; j++) { getCellText.Id = displayToId[j]; PhInitializeEmptyStringRef(&getCellText.Text); TreeNew_GetCellText(TreeNewHandle, &getCellText); PhAppendStringBuilderEx(&stringBuilder, getCellText.Text.Buffer, getCellText.Text.Length); PhAppendStringBuilder2(&stringBuilder, L", "); } // Remove the trailing comma and space. if (stringBuilder.String->Length != 0) PhRemoveStringBuilder(&stringBuilder, stringBuilder.String->Length / 2 - 2, 2); PhAppendStringBuilder2(&stringBuilder, L"\r\n"); } PhFree(displayToId); return PhFinalStringBuilderString(&stringBuilder); }
static PPH_STRING SaveCounterList( _Inout_ PPH_LIST FilterList ) { PH_STRING_BUILDER stringBuilder; WCHAR temp[2]; PhInitializeStringBuilder(&stringBuilder, 100); temp[0] = '\\'; for (SIZE_T i = 0; i < FilterList->Count; i++) { PPH_PERFMON_ENTRY entry = (PPH_PERFMON_ENTRY)FilterList->Items[i]; SIZE_T length = entry->Name->Length / 2; for (SIZE_T ii = 0; ii < length; ii++) { if (entry->Name->Buffer[ii] == '\\') // escape backslashes { temp[1] = entry->Name->Buffer[ii]; PhAppendStringBuilderEx(&stringBuilder, temp, 4); } else { PhAppendCharStringBuilder(&stringBuilder, entry->Name->Buffer[ii]); } } PhAppendCharStringBuilder(&stringBuilder, ','); } if (stringBuilder.String->Length != 0) PhRemoveStringBuilder(&stringBuilder, stringBuilder.String->Length / 2 - 1, 1); return PhFinalStringBuilderString(&stringBuilder); }
VOID PhpAppendStringWithLineBreaks( _Inout_ PPH_STRING_BUILDER StringBuilder, _In_ PPH_STRINGREF String, _In_ ULONG CharactersPerLine, _In_opt_ PPH_STRINGREF IndentAfterFirstLine ) { PH_STRINGREF line; SIZE_T bytesPerLine; BOOLEAN afterFirstLine; SIZE_T bytesToAppend; line = *String; bytesPerLine = CharactersPerLine * sizeof(WCHAR); afterFirstLine = FALSE; while (line.Length != 0) { bytesToAppend = line.Length; if (bytesToAppend > bytesPerLine) bytesToAppend = bytesPerLine; if (afterFirstLine) { PhAppendCharStringBuilder(StringBuilder, '\n'); if (IndentAfterFirstLine) PhAppendStringBuilder(StringBuilder, IndentAfterFirstLine); } PhAppendStringBuilderEx(StringBuilder, line.Buffer, bytesToAppend); afterFirstLine = TRUE; PhSkipStringRef(&line, bytesToAppend); } }
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; }