28 typedef struct _SERVICE_OTHER_CONTEXT
36 ULONG PreshutdownTimeoutValid : 1;
37 ULONG RequiredPrivilegesValid : 1;
38 ULONG SidTypeValid : 1;
39 ULONG LaunchProtectedValid : 1;
44 ULONG OriginalLaunchProtected;
47 #define SIP(String, Integer) { (String), (PVOID)(Integer) }
51 _In_opt_ SC_HANDLE ServiceHandle,
58 SIP(L
"None", SERVICE_SID_TYPE_NONE),
59 SIP(L
"Restricted", SERVICE_SID_TYPE_RESTRICTED),
60 SIP(L
"Unrestricted", SERVICE_SID_TYPE_UNRESTRICTED)
65 SIP(L
"None", SERVICE_LAUNCH_PROTECTED_NONE),
66 SIP(L
"Full (Windows)", SERVICE_LAUNCH_PROTECTED_WINDOWS),
67 SIP(L
"Light (Windows)", SERVICE_LAUNCH_PROTECTED_WINDOWS_LIGHT),
68 SIP(L
"Light (Antimalware)", SERVICE_LAUNCH_PROTECTED_ANTIMALWARE_LIGHT)
81 EspServiceSidTypePairs,
82 sizeof(EspServiceSidTypePairs),
98 EspServiceSidTypePairs,
99 sizeof(EspServiceSidTypePairs),
109 _In_ ULONG LaunchProtected
115 EspServiceLaunchProtectedPairs,
116 sizeof(EspServiceLaunchProtectedPairs),
126 _In_ PWSTR LaunchProtected
132 EspServiceLaunchProtectedPairs,
133 sizeof(EspServiceLaunchProtectedPairs),
147 NTSTATUS status = STATUS_SUCCESS;
148 SC_HANDLE serviceHandle;
150 SERVICE_PRESHUTDOWN_INFO preshutdownInfo;
151 LPSERVICE_REQUIRED_PRIVILEGES_INFO requiredPrivilegesInfo;
152 SERVICE_SID_INFO sidInfo;
153 SERVICE_LAUNCH_PROTECTED_INFO launchProtectedInfo;
155 if (!(serviceHandle =
PhOpenService(Context->ServiceItem->Name->Buffer, SERVICE_QUERY_CONFIG)))
156 return NTSTATUS_FROM_WIN32(GetLastError());
160 if (QueryServiceConfig2(serviceHandle,
161 SERVICE_CONFIG_PRESHUTDOWN_INFO,
162 (PBYTE)&preshutdownInfo,
163 sizeof(SERVICE_PRESHUTDOWN_INFO),
168 Context->PreshutdownTimeoutValid =
TRUE;
176 ULONG privilegeLength;
182 privilege = requiredPrivilegesInfo->pmszRequiredPrivileges;
190 if (privilegeLength == 0)
193 privilegeString =
PhCreateStringEx(privilege, privilegeLength *
sizeof(WCHAR));
196 lvItemIndex =
PhAddListViewItem(Context->PrivilegesLv, MAXINT, privilege, privilegeString);
197 privilegeSr.
Buffer = privilege;
198 privilegeSr.
Length = privilegeLength *
sizeof(WCHAR);
206 privilege += privilegeLength + 1;
212 PhFree(requiredPrivilegesInfo);
213 Context->RequiredPrivilegesValid =
TRUE;
218 if (QueryServiceConfig2(serviceHandle,
219 SERVICE_CONFIG_SERVICE_SID_INFO,
221 sizeof(SERVICE_SID_INFO),
227 Context->SidTypeValid =
TRUE;
232 if (QueryServiceConfig2(serviceHandle,
233 SERVICE_CONFIG_LAUNCH_PROTECTED,
234 (PBYTE)&launchProtectedInfo,
235 sizeof(SERVICE_LAUNCH_PROTECTED_INFO),
241 Context->LaunchProtectedValid =
TRUE;
242 Context->OriginalLaunchProtected = launchProtectedInfo.dwLaunchProtected;
245 CloseServiceHandle(serviceHandle);
254 PSID serviceSid = NULL;
256 ULONG serviceSidLength = 0;
266 serviceSid = PhAllocate(serviceSidLength);
277 static int __cdecl PrivilegeNameCompareFunction(
278 _In_
const void *elem1,
279 _In_
const void *elem2
282 PWSTR string1 = *(PWSTR *)elem1;
283 PWSTR string2 = *(PWSTR *)elem2;
285 return wcscmp(string1, string2);
297 if (uMsg == WM_INITDIALOG)
302 SetProp(hwndDlg, L
"Context", (HANDLE)context);
308 if (uMsg == WM_DESTROY)
309 RemoveProp(hwndDlg, L
"Context");
320 LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam;
324 context->ServiceItem = serviceItem;
326 context->PrivilegesLv = privilegesLv = GetDlgItem(hwndDlg,
IDC_PRIVILEGES);
335 if (context->ServiceItem->Type == SERVICE_KERNEL_DRIVER || context->ServiceItem->Type == SERVICE_FILE_SYSTEM_DRIVER)
358 PhShowWarning(hwndDlg, L
"Unable to query service information: %s",
362 context->Ready =
TRUE;
367 if (context->PrivilegeList)
378 switch (LOWORD(wParam))
383 LSA_HANDLE policyHandle;
384 LSA_ENUMERATION_HANDLE enumContext;
395 PhShowStatus(hwndDlg, L
"Unable to open LSA policy", status, 0);
411 if (status == STATUS_NO_MORE_ENTRIES)
416 for (i = 0; i < count; i++)
421 LsaFreeMemory(buffer);
424 LsaClose(policyHandle);
426 qsort(choices->
Items, choices->
Count,
sizeof(PWSTR), PrivilegeNameCompareFunction);
431 L
"Select a privilege to add:",
432 (PWSTR *)choices->
Items,
441 BOOLEAN found =
FALSE;
447 for (i = 0; i < context->PrivilegeList->Count; i++)
460 MB_OKCANCEL | MB_ICONERROR,
461 L
"The selected privilege has already been added."
485 context->Dirty =
TRUE;
486 context->RequiredPrivilegesValid =
TRUE;
500 lvItemIndex = ListView_GetNextItem(context->PrivilegesLv, -1, LVNI_SELECTED);
502 if (lvItemIndex != -1 &&
PhGetListViewItemParam(context->PrivilegesLv, lvItemIndex, (PVOID *)&privilegeString))
504 index = PhFindItemList(context->PrivilegeList, privilegeString);
512 context->Dirty =
TRUE;
513 context->RequiredPrivilegesValid =
TRUE;
520 switch (HIWORD(wParam))
527 context->Dirty =
TRUE;
529 switch (LOWORD(wParam))
532 context->PreshutdownTimeoutValid =
TRUE;
535 context->SidTypeValid =
TRUE;
538 context->LaunchProtectedValid =
TRUE;
549 LPNMHDR header = (LPNMHDR)lParam;
551 switch (header->code)
555 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT,
FALSE);
560 SC_HANDLE serviceHandle = NULL;
561 ULONG win32Result = 0;
562 BOOLEAN connectedToPhSvc =
FALSE;
564 ULONG launchProtected;
566 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
571 if (context->LaunchProtectedValid && launchProtected != 0 && launchProtected != context->OriginalLaunchProtected)
575 MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2,
576 L
"Setting service protection will prevent the service from being controlled, modified, or deleted. Do you want to continue?"
579 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID);
586 SERVICE_PRESHUTDOWN_INFO preshutdownInfo;
587 SERVICE_REQUIRED_PRIVILEGES_INFO requiredPrivilegesInfo;
588 SERVICE_SID_INFO sidInfo;
589 SERVICE_LAUNCH_PROTECTED_INFO launchProtectedInfo;
591 if (!(serviceHandle =
PhOpenService(context->ServiceItem->Name->Buffer, SERVICE_CHANGE_CONFIG)))
593 win32Result = GetLastError();
595 if (win32Result == ERROR_ACCESS_DENIED && !
PhElevated)
601 connectedToPhSvc =
TRUE;
606 win32Result = ERROR_CANCELLED;
616 if (context->PreshutdownTimeoutValid)
621 SERVICE_CONFIG_PRESHUTDOWN_INFO, &preshutdownInfo))
623 win32Result = GetLastError();
627 if (context->RequiredPrivilegesValid)
634 for (i = 0; i < context->PrivilegeList->Count; i++)
640 requiredPrivilegesInfo.pmszRequiredPrivileges = sb.
String->
Buffer;
643 SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO, &requiredPrivilegesInfo))
645 win32Result = GetLastError();
651 if (context->SidTypeValid)
659 SERVICE_CONFIG_SERVICE_SID_INFO, &sidInfo))
661 win32Result = GetLastError();
665 if (context->LaunchProtectedValid)
667 launchProtectedInfo.dwLaunchProtected = launchProtected;
670 SERVICE_CONFIG_LAUNCH_PROTECTED, &launchProtectedInfo))
678 if (connectedToPhSvc)
681 CloseServiceHandle(serviceHandle);
683 if (win32Result != 0)
687 MB_ICONERROR | MB_RETRYCANCEL,
688 L
"Unable to change service information: %s",
692 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID);
700 case LVN_ITEMCHANGED:
702 if (header->hwndFrom == context->PrivilegesLv)
704 EnableWindow(GetDlgItem(hwndDlg,
IDC_REMOVE), ListView_GetSelectedCount(context->PrivilegesLv) == 1);
717 _In_ PWSTR ServiceName,
718 _In_opt_ SC_HANDLE ServiceHandle,
719 _In_ ULONG InfoLevel,
725 return !!ChangeServiceConfig2(ServiceHandle, InfoLevel, Info);