@ RbMm верно.
Ниже приведен пример использования winapi в C ++.
#include <windows.h>
#include <sddl.h>
#pragma comment(lib, "Advapi32")
int main()
{
SC_HANDLE sHdl = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
if (sHdl == NULL)
printf("OpenSCManager error: %d\n", GetLastError());
SC_HANDLE serviceHdl = OpenService(sHdl, L"MyTestDirectXService", READ_CONTROL | WRITE_OWNER | WRITE_DAC);
if (sHdl == NULL)
printf("OpenService error: %d\n", GetLastError());
char buf[1024];
DWORD retLen = 0;
// ### Query
if(!QueryServiceObjectSecurity(serviceHdl, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, buf, sizeof(buf), &retLen))
printf("QueryServiceObjectSecurity error: %d\n", GetLastError());
LPWSTR strBuf = NULL;
unsigned long strLen = 0;
if (!ConvertSecurityDescriptorToStringSecurityDescriptor(buf, SDDL_REVISION_1, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, &strBuf, &strLen))
printf("ConvertSecurityDescriptorToStringSecurityDescriptor error: %d\n", GetLastError());
wprintf(strBuf);
// ### Set
PSECURITY_DESCRIPTOR sDescriptor = {0};
if(!ConvertStringSecurityDescriptorToSecurityDescriptor(L"O:BAD:(A;;GA;;;SY)(A;;GRGX;;;IU)", SDDL_REVISION_1, &sDescriptor, NULL))
printf("ConvertStringSecurityDescriptorToSecurityDescriptor error: %d\n", GetLastError());
if (!SetServiceObjectSecurity(serviceHdl, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, sDescriptor))
printf("SetServiceObjectSecurity error: %d\n", GetLastError());
// ### Check
if (!QueryServiceObjectSecurity(serviceHdl, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, buf, sizeof(buf), &retLen))
printf("QueryServiceObjectSecurity error: %d\n", GetLastError());
strBuf = NULL;
strLen = 0;
if (!ConvertSecurityDescriptorToStringSecurityDescriptor(buf, SDDL_REVISION_1, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, &strBuf, &strLen))
printf("ConvertSecurityDescriptorToStringSecurityDescriptor error: %d\n", GetLastError());
wprintf(strBuf);
getchar();
}
После запуска вышеуказанного кода опция запуска отключается следующим образом:
ОБНОВЛЕНИЕ: Благодаря « [SetServiceObjectSecurity
доступно для использования в операционных системах, указанных в разделе« Требования ». быть изменен или недоступен в последующих версиях. Вместо этого используйте функцию SetNamedSecurityInfo
.] "Ниже приведен пример использования SetNamedSecurityInfo
API.
// ### Set
PSECURITY_DESCRIPTOR sDescriptor = { 0 };
if (!ConvertStringSecurityDescriptorToSecurityDescriptor(L"O:BAD:(A;;GA;;;SY)(A;;GRGX;;;IU)", SDDL_REVISION_1, &sDescriptor, NULL))
printf("ConvertStringSecurityDescriptorToSecurityDescriptor error: %d\n", GetLastError());
char daclBuf[100];
char ownerBuf[100];
char abBuf[100];
DWORD abLen = sizeof(abBuf);
DWORD dLen = sizeof(daclBuf);
DWORD oLen = sizeof(ownerBuf);
DWORD sLen = 0;
DWORD gLen = 0;
// Only owner and DACL security information valid in String security descriptor so here set DACL and Primary Group buffer to NULL.
BOOL returnVal = MakeAbsoluteSD(sDescriptor, abBuf, &abLen, (PACL)daclBuf, &dLen, NULL, &sLen, ownerBuf, &oLen, NULL, &gLen);
if ((!returnVal) && (ERROR_INSUFFICIENT_BUFFER) == GetLastError())
printf("One or more of the buffers is too small.\n");
WCHAR serviceName[] = L"MySecondService";
DWORD result = SetNamedSecurityInfo(serviceName, SE_SERVICE, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, ownerBuf, NULL, (ACL*)daclBuf, NULL);
if(ERROR_SUCCESS != result)
printf("ConvertStringSecurityDescriptorToSecurityDescriptor error: %d\n", result);