-
Пытаюсь получить список групп (для начала юзера от которого запущен процесс), по идее должно работать - function SidToName(Sid: PSID): string;
var
Name: array[0..128] of Char;
NameSize: DWORD;
Domain: array[0..64] of Char;
DomainSize: DWORD;
peUse: SID_NAME_USE;
begin
Win32Check(IsValidSid(Sid));
NameSize :=128;
DomainSize:=64;
if LookupAccountSid(nil, Sid, @Name[0], NameSize, @Domain[0], DomainSize, peUse)
then result:= Domain + '\' + Name + ' - ' + IntToStr(peUse);
end;
procedure SidGroupList(List: TStrings);
var
hToken: THandle;
pTGroups: PTokenGroups;
i, Size: integer;
RetLength: DWORD;
Sid: PSid;
begin
Win32Check(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, hToken));
try
pTGroups:= nil;
GetTokenInformation(hToken, TokenGroups, pTGroups, 0, RetLength);
GetMem(pTGroups, RetLength);
try
Win32Check(GetTokenInformation(hToken, TokenGroups, pTGroups, RetLength, RetLength));
for i:= 0 to pTGroups.GroupCount - 1 do begin
Size:= GetLengthSid(pTGroups.Groups[i].Sid);
GetMem(Sid, Size);
CopyMemory(Sid, pTGroups.Groups[i].Sid, Size);
List.AddObject(SidToName(Sid), Sid);
end;
finally
FreeMem(pTGroups);
end;
finally
CloseHandle(hToken);
end;
end; даже что то выдает... но, почему то всегда одно и тоже. Для проверки создал свою группу "Test", добавляю себя в члены этой группы... (в lusrmgr.msc видит) но моя функция, группу игнорирует. Вопрос, почему? Ну и продолжение, как получить полный список доступных, независимо от пользователя. В гугле что то все вертится вокруг проверки является ли текущий админом...
-
Блин! Первый вопрос отпал, все работает, просто в системе 2 одноименных юзера (различаются по сиду), доменный и локальный, а lusrmgr.msc показывает их как одного, вот и путаница. Если запустить от имени и выбрать чисто локального, то моя группа у него есть.
По общему списку еще актуален.
-
> как получить полный список доступных
групп? NetGroupEnum что-ли?
-
Кстати, приемлем (а то и лучше) другой вариант... Если в свойствах учетки на панели "Членство в группах" нажать "Добавить" то открывается выбор от системы, так вот если есть возможность использовать этот системный выбор, это бы меня более чем устроило. (нужно сделать выбор группы в программе, а средства значения не имеют) Опять, вопрос как? Если вообще возможно.
-
> NetGroupEnum что-ли? А это тоже самое?
-
> это тоже самое?
ну наверно да.
-
Нда, похоже я искал не там... потому и не находил. Спасибо.
-
В общем итог procedure GroupList(List: TStrings);
type
GROUP_INFO = record
lgrpi_name : LPWSTR;
lgrpi_comment: LPWSTR;
end;
TGroups = array of GROUP_INFO;
var
pGroups: Pointer;
Res, i : integer;
cbRead, cbTotal: integer;
DName: WideString;
begin
NetLocalGroupEnum(nil, 1, pGroups, DWORD(-1), DWORD(cbRead), DWORD(cbTotal), nil);
for i:=0 to cbRead - 1 do
with TGroups(pGroups)[i] do
List.Add('\' + WideCharToString(lgrpi_name));
NetApiBufferFree(pGroups);
DName:= DomainName;
NetGroupEnum(PWideChar(DName), 1, pGroups, DWORD(-1), DWORD(cbRead), DWORD(cbTotal), nil);
for i:= 0 to cbRead - 1 do
with TGroups(pGroups)[i] do
List.Add(DomainName + '\' + WideCharToString(lgrpi_name));
NetApiBufferFree(pGroups);
end; Действительно все сходится... т.е. тут нету сида, но если его получить по имени группы (+локальное(/пустое) или доменное имя) то они сходятся один в один с тем что получал ранее для текущего процесса.
|