VOID PhpUpdateServiceItemConfig( _In_ SC_HANDLE ScManagerHandle, _In_ PPH_SERVICE_ITEM ServiceItem ) { SC_HANDLE serviceHandle; serviceHandle = OpenService(ScManagerHandle, ServiceItem->Name->Buffer, SERVICE_QUERY_CONFIG); if (serviceHandle) { LPQUERY_SERVICE_CONFIG config; SERVICE_DELAYED_AUTO_START_INFO delayedAutoStartInfo; ULONG returnLength; PSERVICE_TRIGGER_INFO triggerInfo; config = PhGetServiceConfig(serviceHandle); if (config) { ServiceItem->StartType = config->dwStartType; ServiceItem->ErrorControl = config->dwErrorControl; PhFree(config); } if (QueryServiceConfig2( serviceHandle, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, (BYTE *)&delayedAutoStartInfo, sizeof(SERVICE_DELAYED_AUTO_START_INFO), &returnLength )) { ServiceItem->DelayedStart = delayedAutoStartInfo.fDelayedAutostart; } else { ServiceItem->DelayedStart = FALSE; } if (triggerInfo = PhQueryServiceVariableSize(serviceHandle, SERVICE_CONFIG_TRIGGER_INFO)) { ServiceItem->HasTriggers = triggerInfo->cTriggers != 0; PhFree(triggerInfo); } else { ServiceItem->HasTriggers = FALSE; } CloseServiceHandle(serviceHandle); } }
PPH_STRING PhGetServiceDescription( _In_ SC_HANDLE ServiceHandle ) { PPH_STRING description = NULL; LPSERVICE_DESCRIPTION serviceDescription; serviceDescription = PhQueryServiceVariableSize(ServiceHandle, SERVICE_CONFIG_DESCRIPTION); if (serviceDescription) { if (serviceDescription->lpDescription) description = PhCreateString(serviceDescription->lpDescription); PhFree(serviceDescription); return description; } else { return NULL; } }
NTSTATUS EspLoadOtherInfo( _In_ HWND hwndDlg, _In_ PSERVICE_OTHER_CONTEXT Context ) { NTSTATUS status = STATUS_SUCCESS; SC_HANDLE serviceHandle; ULONG returnLength; SERVICE_PRESHUTDOWN_INFO preshutdownInfo; LPSERVICE_REQUIRED_PRIVILEGES_INFO requiredPrivilegesInfo; SERVICE_SID_INFO sidInfo; SERVICE_LAUNCH_PROTECTED_INFO launchProtectedInfo; if (!(serviceHandle = PhOpenService(Context->ServiceItem->Name->Buffer, SERVICE_QUERY_CONFIG))) return NTSTATUS_FROM_WIN32(GetLastError()); // Preshutdown timeout if (QueryServiceConfig2(serviceHandle, SERVICE_CONFIG_PRESHUTDOWN_INFO, (PBYTE)&preshutdownInfo, sizeof(SERVICE_PRESHUTDOWN_INFO), &returnLength )) { SetDlgItemInt(hwndDlg, IDC_PRESHUTDOWNTIMEOUT, preshutdownInfo.dwPreshutdownTimeout, FALSE); Context->PreshutdownTimeoutValid = TRUE; } // Required privileges if (requiredPrivilegesInfo = PhQueryServiceVariableSize(serviceHandle, SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO)) { PWSTR privilege; ULONG privilegeLength; INT lvItemIndex; PH_STRINGREF privilegeSr; PPH_STRING privilegeString; PPH_STRING displayName; privilege = requiredPrivilegesInfo->pmszRequiredPrivileges; if (privilege) { while (TRUE) { privilegeLength = (ULONG)PhCountStringZ(privilege); if (privilegeLength == 0) break; privilegeString = PhCreateStringEx(privilege, privilegeLength * sizeof(WCHAR)); PhAddItemList(Context->PrivilegeList, privilegeString); lvItemIndex = PhAddListViewItem(Context->PrivilegesLv, MAXINT, privilege, privilegeString); privilegeSr.Buffer = privilege; privilegeSr.Length = privilegeLength * sizeof(WCHAR); if (PhLookupPrivilegeDisplayName(&privilegeSr, &displayName)) { PhSetListViewSubItem(Context->PrivilegesLv, lvItemIndex, 1, displayName->Buffer); PhDereferenceObject(displayName); } privilege += privilegeLength + 1; } } ExtendedListView_SortItems(Context->PrivilegesLv); PhFree(requiredPrivilegesInfo); Context->RequiredPrivilegesValid = TRUE; } // SID type if (QueryServiceConfig2(serviceHandle, SERVICE_CONFIG_SERVICE_SID_INFO, (PBYTE)&sidInfo, sizeof(SERVICE_SID_INFO), &returnLength )) { PhSelectComboBoxString(GetDlgItem(hwndDlg, IDC_SIDTYPE), EspGetServiceSidTypeString(sidInfo.dwServiceSidType), FALSE); Context->SidTypeValid = TRUE; } // Launch protected if (QueryServiceConfig2(serviceHandle, SERVICE_CONFIG_LAUNCH_PROTECTED, (PBYTE)&launchProtectedInfo, sizeof(SERVICE_LAUNCH_PROTECTED_INFO), &returnLength )) { PhSelectComboBoxString(GetDlgItem(hwndDlg, IDC_PROTECTION), EspGetServiceLaunchProtectedString(launchProtectedInfo.dwLaunchProtected), FALSE); Context->LaunchProtectedValid = TRUE; Context->OriginalLaunchProtected = launchProtectedInfo.dwLaunchProtected; } CloseServiceHandle(serviceHandle); return status; }
NTSTATUS EspLoadRecoveryInfo( _In_ HWND hwndDlg, _In_ PSERVICE_RECOVERY_CONTEXT Context ) { NTSTATUS status = STATUS_SUCCESS; SC_HANDLE serviceHandle; LPSERVICE_FAILURE_ACTIONS failureActions; SERVICE_FAILURE_ACTIONS_FLAG failureActionsFlag; SC_ACTION_TYPE lastType; ULONG returnLength; ULONG i; if (!(serviceHandle = PhOpenService(Context->ServiceItem->Name->Buffer, SERVICE_QUERY_CONFIG))) return NTSTATUS_FROM_WIN32(GetLastError()); if (!(failureActions = PhQueryServiceVariableSize(serviceHandle, SERVICE_CONFIG_FAILURE_ACTIONS))) { CloseServiceHandle(serviceHandle); return NTSTATUS_FROM_WIN32(GetLastError()); } // Failure action types Context->NumberOfActions = failureActions->cActions; if (failureActions->cActions != 0 && failureActions->cActions != 3) status = STATUS_SOME_NOT_MAPPED; // If failure actions are not defined for a particular fail count, the // last failure action is used. Here we duplicate this behaviour when there // are fewer than 3 failure actions. lastType = SC_ACTION_NONE; ServiceActionToComboBox(GetDlgItem(hwndDlg, IDC_FIRSTFAILURE), failureActions->cActions >= 1 ? (lastType = failureActions->lpsaActions[0].Type) : lastType); ServiceActionToComboBox(GetDlgItem(hwndDlg, IDC_SECONDFAILURE), failureActions->cActions >= 2 ? (lastType = failureActions->lpsaActions[1].Type) : lastType); ServiceActionToComboBox(GetDlgItem(hwndDlg, IDC_SUBSEQUENTFAILURES), failureActions->cActions >= 3 ? (lastType = failureActions->lpsaActions[2].Type) : lastType); // Reset fail count after SetDlgItemInt(hwndDlg, IDC_RESETFAILCOUNT, failureActions->dwResetPeriod / (60 * 60 * 24), FALSE); // s to days // Restart service after SetDlgItemText(hwndDlg, IDC_RESTARTSERVICEAFTER, L"1"); for (i = 0; i < failureActions->cActions; i++) { if (failureActions->lpsaActions[i].Type == SC_ACTION_RESTART) { if (failureActions->lpsaActions[i].Delay != 0) { SetDlgItemInt(hwndDlg, IDC_RESTARTSERVICEAFTER, failureActions->lpsaActions[i].Delay / (1000 * 60), FALSE); // ms to min } break; } } // Enable actions for stops with errors // This is Vista and above only. if (WindowsVersion >= WINDOWS_VISTA && QueryServiceConfig2( serviceHandle, SERVICE_CONFIG_FAILURE_ACTIONS_FLAG, (BYTE *)&failureActionsFlag, sizeof(SERVICE_FAILURE_ACTIONS_FLAG), &returnLength )) { Button_SetCheck(GetDlgItem(hwndDlg, IDC_ENABLEFORERRORSTOPS), failureActionsFlag.fFailureActionsOnNonCrashFailures ? BST_CHECKED : BST_UNCHECKED); Context->EnableFlagCheckBox = TRUE; } else { Context->EnableFlagCheckBox = FALSE; } // Restart computer options Context->RebootAfter = 1 * 1000 * 60; for (i = 0; i < failureActions->cActions; i++) { if (failureActions->lpsaActions[i].Type == SC_ACTION_REBOOT) { if (failureActions->lpsaActions[i].Delay != 0) Context->RebootAfter = failureActions->lpsaActions[i].Delay; break; } } if (failureActions->lpRebootMsg && failureActions->lpRebootMsg[0] != 0) PhMoveReference(&Context->RebootMessage, PhCreateString(failureActions->lpRebootMsg)); else PhClearReference(&Context->RebootMessage); // Run program SetDlgItemText(hwndDlg, IDC_RUNPROGRAM, failureActions->lpCommand); PhFree(failureActions); CloseServiceHandle(serviceHandle); return status; }