BOOLEAN ServiceTreeFilterCallback( _In_ PPH_TREENEW_NODE Node, _In_opt_ PVOID Context ) { PPH_SERVICE_NODE serviceNode = (PPH_SERVICE_NODE)Node; if (PhIsNullOrEmptyString(SearchboxText)) return TRUE; if (WordMatchStringZ(PhGetServiceTypeString(serviceNode->ServiceItem->Type))) return TRUE; if (WordMatchStringZ(PhGetServiceStateString(serviceNode->ServiceItem->State))) return TRUE; if (WordMatchStringZ(PhGetServiceStartTypeString(serviceNode->ServiceItem->StartType))) return TRUE; if (WordMatchStringZ(PhGetServiceErrorControlString(serviceNode->ServiceItem->ErrorControl))) return TRUE; if (serviceNode->ServiceItem->Name) { if (WordMatchStringRef(&serviceNode->ServiceItem->Name->sr)) return TRUE; } if (serviceNode->ServiceItem->DisplayName) { if (WordMatchStringRef(&serviceNode->ServiceItem->DisplayName->sr)) return TRUE; } if (serviceNode->ServiceItem->ProcessIdString[0] != 0) { if (WordMatchStringZ(serviceNode->ServiceItem->ProcessIdString)) return TRUE; } return FALSE; }
INT_PTR CALLBACK PhpServiceGeneralDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam; PSERVICE_PROPERTIES_CONTEXT context = (PSERVICE_PROPERTIES_CONTEXT)propSheetPage->lParam; PPH_SERVICE_ITEM serviceItem = context->ServiceItem; SC_HANDLE serviceHandle; ULONG startType; ULONG errorControl; // HACK PhCenterWindow(GetParent(hwndDlg), GetParent(GetParent(hwndDlg))); SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)context); PhAddComboBoxStrings(GetDlgItem(hwndDlg, IDC_TYPE), PhServiceTypeStrings, sizeof(PhServiceTypeStrings) / sizeof(WCHAR *)); PhAddComboBoxStrings(GetDlgItem(hwndDlg, IDC_STARTTYPE), PhServiceStartTypeStrings, sizeof(PhServiceStartTypeStrings) / sizeof(WCHAR *)); PhAddComboBoxStrings(GetDlgItem(hwndDlg, IDC_ERRORCONTROL), PhServiceErrorControlStrings, sizeof(PhServiceErrorControlStrings) / sizeof(WCHAR *)); SetDlgItemText(hwndDlg, IDC_DESCRIPTION, serviceItem->DisplayName->Buffer); PhSelectComboBoxString(GetDlgItem(hwndDlg, IDC_TYPE), PhGetServiceTypeString(serviceItem->Type), FALSE); startType = serviceItem->StartType; errorControl = serviceItem->ErrorControl; serviceHandle = PhOpenService(serviceItem->Name->Buffer, SERVICE_QUERY_CONFIG); if (serviceHandle) { LPQUERY_SERVICE_CONFIG config; PPH_STRING description; BOOLEAN delayedStart; if (config = PhGetServiceConfig(serviceHandle)) { SetDlgItemText(hwndDlg, IDC_GROUP, config->lpLoadOrderGroup); SetDlgItemText(hwndDlg, IDC_BINARYPATH, config->lpBinaryPathName); SetDlgItemText(hwndDlg, IDC_USERACCOUNT, config->lpServiceStartName); if (startType != config->dwStartType || errorControl != config->dwErrorControl) { startType = config->dwStartType; errorControl = config->dwErrorControl; PhMarkNeedsConfigUpdateServiceItem(serviceItem); } PhFree(config); } if (description = PhGetServiceDescription(serviceHandle)) { SetDlgItemText(hwndDlg, IDC_DESCRIPTION, description->Buffer); PhDereferenceObject(description); } if ( WindowsVersion >= WINDOWS_VISTA && PhGetServiceDelayedAutoStart(serviceHandle, &delayedStart) ) { context->OldDelayedStart = delayedStart; if (delayedStart) Button_SetCheck(GetDlgItem(hwndDlg, IDC_DELAYEDSTART), BST_CHECKED); } CloseServiceHandle(serviceHandle); } PhSelectComboBoxString(GetDlgItem(hwndDlg, IDC_STARTTYPE), PhGetServiceStartTypeString(startType), FALSE); PhSelectComboBoxString(GetDlgItem(hwndDlg, IDC_ERRORCONTROL), PhGetServiceErrorControlString(errorControl), FALSE); SetDlgItemText(hwndDlg, IDC_PASSWORD, L"password"); Button_SetCheck(GetDlgItem(hwndDlg, IDC_PASSWORDCHECK), BST_UNCHECKED); SetDlgItemText(hwndDlg, IDC_SERVICEDLL, L"N/A"); { HANDLE keyHandle; PPH_STRING keyName; keyName = PhConcatStrings( 3, L"System\\CurrentControlSet\\Services\\", serviceItem->Name->Buffer, L"\\Parameters" ); if (NT_SUCCESS(PhOpenKey( &keyHandle, KEY_READ, PH_KEY_LOCAL_MACHINE, &keyName->sr, 0 ))) { PPH_STRING serviceDllString; if (serviceDllString = PhQueryRegistryString(keyHandle, L"ServiceDll")) { PPH_STRING expandedString; if (expandedString = PhExpandEnvironmentStrings(&serviceDllString->sr)) { SetDlgItemText(hwndDlg, IDC_SERVICEDLL, expandedString->Buffer); PhDereferenceObject(expandedString); } PhDereferenceObject(serviceDllString); } NtClose(keyHandle); } PhDereferenceObject(keyName); } PhpRefreshControls(hwndDlg); context->Ready = TRUE; } break; case WM_DESTROY: { RemoveProp(hwndDlg, PhMakeContextAtom()); } break; case WM_COMMAND: { PSERVICE_PROPERTIES_CONTEXT context = (PSERVICE_PROPERTIES_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom()); switch (LOWORD(wParam)) { case IDCANCEL: { // Workaround for property sheet + multiline edit: http://support.microsoft.com/kb/130765 SendMessage(GetParent(hwndDlg), uMsg, wParam, lParam); } break; case IDC_PASSWORD: { if (HIWORD(wParam) == EN_CHANGE) { Button_SetCheck(GetDlgItem(hwndDlg, IDC_PASSWORDCHECK), BST_CHECKED); } } break; case IDC_DELAYEDSTART: { context->Dirty = TRUE; } break; case IDC_BROWSE: { static PH_FILETYPE_FILTER filters[] = { { L"Executable files (*.exe;*.sys)", L"*.exe;*.sys" }, { L"All files (*.*)", L"*.*" } }; PVOID fileDialog; PPH_STRING fileName; fileDialog = PhCreateOpenFileDialog(); PhSetFileDialogFilter(fileDialog, filters, sizeof(filters) / sizeof(PH_FILETYPE_FILTER)); fileName = PhGetFileName(PHA_GET_DLGITEM_TEXT(hwndDlg, IDC_BINARYPATH)); PhSetFileDialogFileName(fileDialog, fileName->Buffer); PhDereferenceObject(fileName); if (PhShowFileDialog(hwndDlg, fileDialog)) { fileName = PhGetFileDialogFileName(fileDialog); SetDlgItemText(hwndDlg, IDC_BINARYPATH, fileName->Buffer); PhDereferenceObject(fileName); } PhFreeFileDialog(fileDialog); } break; } switch (HIWORD(wParam)) { case EN_CHANGE: case CBN_SELCHANGE: { PhpRefreshControls(hwndDlg); if (context->Ready) context->Dirty = TRUE; } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case PSN_QUERYINITIALFOCUS: { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)GetDlgItem(hwndDlg, IDC_STARTTYPE)); } return TRUE; case PSN_KILLACTIVE: { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); } return TRUE; case PSN_APPLY: { NTSTATUS status; PSERVICE_PROPERTIES_CONTEXT context = (PSERVICE_PROPERTIES_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom()); PPH_SERVICE_ITEM serviceItem = context->ServiceItem; SC_HANDLE serviceHandle; PPH_STRING newServiceTypeString; PPH_STRING newServiceStartTypeString; PPH_STRING newServiceErrorControlString; ULONG newServiceType; ULONG newServiceStartType; ULONG newServiceErrorControl; PPH_STRING newServiceGroup; PPH_STRING newServiceBinaryPath; PPH_STRING newServiceUserAccount; PPH_STRING newServicePassword; SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); if (!context->Dirty) { return TRUE; } newServiceTypeString = PHA_DEREFERENCE(PhGetWindowText(GetDlgItem(hwndDlg, IDC_TYPE))); newServiceStartTypeString = PHA_DEREFERENCE(PhGetWindowText(GetDlgItem(hwndDlg, IDC_STARTTYPE))); newServiceErrorControlString = PHA_DEREFERENCE(PhGetWindowText(GetDlgItem(hwndDlg, IDC_ERRORCONTROL))); newServiceType = PhGetServiceTypeInteger(newServiceTypeString->Buffer); newServiceStartType = PhGetServiceStartTypeInteger(newServiceStartTypeString->Buffer); newServiceErrorControl = PhGetServiceErrorControlInteger(newServiceErrorControlString->Buffer); newServiceGroup = PHA_DEREFERENCE(PhGetWindowText(GetDlgItem(hwndDlg, IDC_GROUP))); newServiceBinaryPath = PHA_DEREFERENCE(PhGetWindowText(GetDlgItem(hwndDlg, IDC_BINARYPATH))); newServiceUserAccount = PHA_DEREFERENCE(PhGetWindowText(GetDlgItem(hwndDlg, IDC_USERACCOUNT))); if (Button_GetCheck(GetDlgItem(hwndDlg, IDC_PASSWORDCHECK)) == BST_CHECKED) { newServicePassword = PhGetWindowText(GetDlgItem(hwndDlg, IDC_PASSWORD)); } else { newServicePassword = NULL; } if (newServiceType == SERVICE_KERNEL_DRIVER && newServiceUserAccount->Length == 0) { newServiceUserAccount = NULL; } serviceHandle = PhOpenService(serviceItem->Name->Buffer, SERVICE_CHANGE_CONFIG); if (serviceHandle) { if (ChangeServiceConfig( serviceHandle, newServiceType, newServiceStartType, newServiceErrorControl, newServiceBinaryPath->Buffer, newServiceGroup->Buffer, NULL, NULL, PhGetString(newServiceUserAccount), PhGetString(newServicePassword), NULL )) { if (WindowsVersion >= WINDOWS_VISTA) { BOOLEAN newDelayedStart; newDelayedStart = Button_GetCheck(GetDlgItem(hwndDlg, IDC_DELAYEDSTART)) == BST_CHECKED; if (newDelayedStart != context->OldDelayedStart) { PhSetServiceDelayedAutoStart(serviceHandle, newDelayedStart); } } PhMarkNeedsConfigUpdateServiceItem(serviceItem); CloseServiceHandle(serviceHandle); } else { CloseServiceHandle(serviceHandle); goto ErrorCase; } } else { if (GetLastError() == ERROR_ACCESS_DENIED && !PhElevated) { // Elevate using phsvc. if (PhUiConnectToPhSvc(hwndDlg, FALSE)) { if (NT_SUCCESS(status = PhSvcCallChangeServiceConfig( serviceItem->Name->Buffer, newServiceType, newServiceStartType, newServiceErrorControl, newServiceBinaryPath->Buffer, newServiceGroup->Buffer, NULL, NULL, PhGetString(newServiceUserAccount), PhGetString(newServicePassword), NULL ))) { if (WindowsVersion >= WINDOWS_VISTA) { BOOLEAN newDelayedStart; newDelayedStart = Button_GetCheck(GetDlgItem(hwndDlg, IDC_DELAYEDSTART)) == BST_CHECKED; if (newDelayedStart != context->OldDelayedStart) { SERVICE_DELAYED_AUTO_START_INFO info; info.fDelayedAutostart = newDelayedStart; PhSvcCallChangeServiceConfig2( serviceItem->Name->Buffer, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, &info ); } } PhMarkNeedsConfigUpdateServiceItem(serviceItem); } PhUiDisconnectFromPhSvc(); if (!NT_SUCCESS(status)) { SetLastError(PhNtStatusToDosError(status)); goto ErrorCase; } } else { // User cancelled elevation. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID); } } else { goto ErrorCase; } } goto Cleanup; ErrorCase: if (PhShowMessage( hwndDlg, MB_ICONERROR | MB_RETRYCANCEL, L"Unable to change service configuration: %s", ((PPH_STRING)PHA_DEREFERENCE(PhGetWin32Message(GetLastError())))->Buffer ) == IDRETRY) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID); } Cleanup: if (newServicePassword) { RtlSecureZeroMemory(newServicePassword->Buffer, newServicePassword->Length); PhDereferenceObject(newServicePassword); } } return TRUE; } } break; } return FALSE; }
BOOLEAN ServiceTreeFilterCallback( _In_ PPH_TREENEW_NODE Node, _In_opt_ PVOID Context ) { PPH_SERVICE_NODE serviceNode = (PPH_SERVICE_NODE)Node; PPH_STRING serviceFileName = NULL; PPH_STRING serviceBinaryPath = NULL; if (PhIsNullOrEmptyString(SearchboxText)) return TRUE; if (WordMatchStringZ(PhGetServiceTypeString(serviceNode->ServiceItem->Type))) return TRUE; if (WordMatchStringZ(PhGetServiceStateString(serviceNode->ServiceItem->State))) return TRUE; if (WordMatchStringZ(PhGetServiceStartTypeString(serviceNode->ServiceItem->StartType))) return TRUE; if (WordMatchStringZ(PhGetServiceErrorControlString(serviceNode->ServiceItem->ErrorControl))) return TRUE; if (!PhIsNullOrEmptyString(serviceNode->ServiceItem->Name)) { if (WordMatchStringRef(&serviceNode->ServiceItem->Name->sr)) return TRUE; } if (!PhIsNullOrEmptyString(serviceNode->ServiceItem->DisplayName)) { if (WordMatchStringRef(&serviceNode->ServiceItem->DisplayName->sr)) return TRUE; } if (serviceNode->ServiceItem->ProcessId) { PPH_PROCESS_NODE processNode; if (WordMatchStringZ(serviceNode->ServiceItem->ProcessIdString)) return TRUE; // Search the process node if (processNode = PhFindProcessNode(serviceNode->ServiceItem->ProcessId)) { if (ProcessTreeFilterCallback(&processNode->Node, NULL)) return TRUE; } } if (!PhIsNullOrEmptyString(serviceNode->ServiceItem->VerifySignerName)) { if (WordMatchStringRef(&serviceNode->ServiceItem->VerifySignerName->sr)) return TRUE; } if (serviceNode->ServiceItem->VerifyResult != VrUnknown) { switch (serviceNode->ServiceItem->VerifyResult) { case VrNoSignature: if (WordMatchStringZ(L"NoSignature")) return TRUE; break; case VrTrusted: if (WordMatchStringZ(L"Trusted")) return TRUE; break; case VrExpired: if (WordMatchStringZ(L"Expired")) return TRUE; break; case VrRevoked: if (WordMatchStringZ(L"Revoked")) return TRUE; break; case VrDistrust: if (WordMatchStringZ(L"Distrust")) return TRUE; break; case VrSecuritySettings: if (WordMatchStringZ(L"SecuritySettings")) return TRUE; break; case VrBadSignature: if (WordMatchStringZ(L"BadSignature")) return TRUE; break; default: if (WordMatchStringZ(L"Unknown")) return TRUE; break; } } if (NT_SUCCESS(QueryServiceFileName( &serviceNode->ServiceItem->Name->sr, &serviceFileName, &serviceBinaryPath ))) { BOOLEAN matched = FALSE; if (serviceFileName) { if (WordMatchStringRef(&serviceFileName->sr)) { matched = TRUE; } PhDereferenceObject(serviceFileName); } if (serviceBinaryPath) { if (WordMatchStringRef(&serviceBinaryPath->sr)) { matched = TRUE; } PhDereferenceObject(serviceBinaryPath); } if (matched) return TRUE; } return FALSE; }
BOOLEAN ServiceTreeFilterCallback( _In_ PPH_TREENEW_NODE Node, _In_opt_ PVOID Context ) { PPH_SERVICE_NODE serviceNode = (PPH_SERVICE_NODE)Node; PPH_STRING serviceFileName = NULL; PPH_STRING serviceBinaryPath = NULL; if (PhIsNullOrEmptyString(SearchboxText)) return TRUE; if (WordMatchStringZ(PhGetServiceTypeString(serviceNode->ServiceItem->Type))) return TRUE; if (WordMatchStringZ(PhGetServiceStateString(serviceNode->ServiceItem->State))) return TRUE; if (WordMatchStringZ(PhGetServiceStartTypeString(serviceNode->ServiceItem->StartType))) return TRUE; if (WordMatchStringZ(PhGetServiceErrorControlString(serviceNode->ServiceItem->ErrorControl))) return TRUE; if (!PhIsNullOrEmptyString(serviceNode->ServiceItem->Name)) { if (WordMatchStringRef(&serviceNode->ServiceItem->Name->sr)) return TRUE; } if (!PhIsNullOrEmptyString(serviceNode->ServiceItem->DisplayName)) { if (WordMatchStringRef(&serviceNode->ServiceItem->DisplayName->sr)) return TRUE; } if (serviceNode->ServiceItem->ProcessId) { PPH_PROCESS_NODE processNode; WCHAR processIdString[PH_INT32_STR_LEN_1]; PhPrintUInt32(processIdString, HandleToUlong(serviceNode->ServiceItem->ProcessId)); if (WordMatchStringZ(processIdString)) return TRUE; // Search the process node if (processNode = PhFindProcessNode(serviceNode->ServiceItem->ProcessId)) { if (ProcessTreeFilterCallback(&processNode->Node, NULL)) return TRUE; } } if (NT_SUCCESS(QueryServiceFileName( &serviceNode->ServiceItem->Name->sr, &serviceFileName, &serviceBinaryPath ))) { BOOLEAN matched = FALSE; if (serviceFileName) { if (WordMatchStringRef(&serviceFileName->sr)) { matched = TRUE; } PhDereferenceObject(serviceFileName); } if (serviceBinaryPath) { if (WordMatchStringRef(&serviceBinaryPath->sr)) { matched = TRUE; } PhDereferenceObject(serviceBinaryPath); } if (matched) return TRUE; } return FALSE; }