Я использую Hyper V на Windows 8 и хотел бы иметь возможность общаться с виртуальным последовательным портом через именованный канал. Я даю каналу имя на выбор, и он хорошо работает с последовательным портом виртуальной ОС (в моем случае — XP), но только под пользователем Admin из-за настроек PipeSecurity.
Теперь я хотел бы иметь возможность предоставить полный контроль для всех в именованном канале, созданном Hyper-V. Программно или, может быть, с некоторыми настройками Hyper V. Мне нужно иметь возможность общаться с виртуальной ОС как обычный пользователь.
Я знаю, как установить определенную защиту для именованного канала, который я создаю сам, используя NamedPipeServerStream вместе с объектом PipeSecurity. Я в основном использую C #, но вижу, что есть C ++ API: например, SetSecurityInfo. Но это требует ручку к существующей трубе.
В псевдокоде я хотел бы сделать что-то вроде:
SetSecurityInfo («mypipe», новый PipeAccessRule («Everyone», PipeAccessRights.FullControl, AccessControlType.Allow));
Кто-нибудь знает, как это сделать? (C ++ или предпочтительно C #)
Мне удалось получить работающее решение C ++. Идея Гарри встроить этот код в службу может потребоваться для именованных каналов, которые не являются постоянными в системе.
HANDLE hPipe = CreateFile(L"\\\\.\\pipe\\mypipe", GENERIC_WRITE | WRITE_DAC, 0, NULL, OPEN_EXISTING, NULL, NULL);
if (hPipe != INVALID_HANDLE_VALUE)
{
PACL pOldDACL = NULL;
if(GetSecurityInfo(hPipe, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDACL, NULL, NULL) == ERROR_SUCCESS)
{
TRUSTEE trustee[1];
trustee[0].TrusteeForm = TRUSTEE_IS_NAME;
trustee[0].TrusteeType = TRUSTEE_IS_GROUP;
trustee[0].ptstrName = _T("Everyone");
trustee[0].MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
trustee[0].pMultipleTrustee = NULL;
EXPLICIT_ACCESS explicit_access_list[1];
ZeroMemory(&explicit_access_list[0], sizeof(EXPLICIT_ACCESS));
explicit_access_list[0].grfAccessMode = GRANT_ACCESS;
explicit_access_list[0].grfAccessPermissions = GENERIC_ALL;
explicit_access_list[0].grfInheritance = NO_INHERITANCE;
explicit_access_list[0].Trustee = trustee[0];
PACL pNewDACL = NULL;
if(SetEntriesInAcl(1, explicit_access_list, pOldDACL, &pNewDACL) == ERROR_SUCCESS)
{
if(SetSecurityInfo(hPipe, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDACL, NULL) != ERROR_SUCCESS)
{
//Error handling
DWORD dw = GetLastError();
}
LocalFree(pNewDACL);
}
else
{
//Error handling
GetLastError();
}
LocalFree(pOldDACL);
}
else
{
//Error
GetLastError();
}
}
else
{
//Error handling
DWORD dw = GetLastError();
}
CloseHandle(hPipe);
Я нашел это на MSDN. Выглядит достаточно просто, чтобы следовать:
http://msdn.microsoft.com/en-gb/library/windows/desktop/aa365600(v=vs.85).aspx
Чтение статьи, если вы устанавливаете SetSecurityInfo на PSID вашей группы пользователей, тогда это должно быть выполнимо.