(Слеплено из различных примеров, собранных в инете.)
Есть buffer, заполненный функцией GetTokenInformation();
Заполнен, вроде, правильно: buffer.PrivilegesCount = 17, есть какие-то атрибуты. Дальше:
buffer:=nil;
length:=0;
OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, token)
b:=GetTokenInformation(token, TokenPrivileges, buffer, length, length);
while (not b) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) do
begin
ReallocMem(buffer, length);
b:=GetTokenInformation(token, InformationClass, buffer, length, length);
end;
for i:=0 to buffer.PrivilegeCount-1 do
begin
if not LookupPrivilegeName( nil, buffer.Privileges[i].Luid, ucPrivilegeName, PrivilegeName) then
raise Exception.Create(SysErrorMessage(GetLastError));
// Здесь выскакивает рантайм ошибка if not LookupPrivilegeDisplayName( nil, ucPrivilegeName,
ucDisplayName, dwDisplayName, dwLangId ) then
raise Exception.Create(SysErrorMessage(GetLastError));
Тут идет вывод названий привелегий (там, в TMemo.Lines.Add() например)
.....................................
end;
Код вылетает на функции LookupPrivilegeName с ошибкой A specified privilege does not exist. То-есть, неверный buffer.Privileges[i].Luid??? Если ошибка да, то скажите как правильно пользоваться функцией GetTokenInformation()?
Паскалем уже давно не занимаюсь, поэтому какие-то мелочи в вашем коде мог просмотреть.
Обратите внимание, что размер выходного буфера для LookupPrivilegeName и LookupPrivilegeDisplayName (ucPrivilegeName в вашем коде) нужно инициализировать перед каждым вызовом этих функций, так как они модифицируют переданное им значение. В вашем коде этого не видно.
Ситуация такая — переделал я немного Ваш код под С++ билдер — супер, все работает.
Попробовал сделать так, как Вы сказали в дельфи:
PrivilegeNameSize: array[0..255] of char;
PrivilegeNameSize:=sizeof(ucPrivilegeName);
if not LookupPrivilegeName( nil, buffer.Privileges[i].Luid, PChar(@ucPrivilegeName), PrivilegeNameSize) then
begin
raise Exception.Create(SysErrorMessage(GetLastError));
end;
Получаю "Specified privilege does not exist". Очевидно, проблемы с приведением типов для дельфовской версии винапи. Может кто-нибуть подскажет, где можно нормальную доку увидеть по использованию винапи в дельфи?
Здравствуйте, bigdaddy, Вы писали:
B>Ситуация такая — переделал я немного Ваш код под С++ билдер — супер, все работает.
B>Попробовал сделать так, как Вы сказали в дельфи:
B>
B>PrivilegeNameSize: array[0..255] of char;
B> PrivilegeNameSize:=sizeof(ucPrivilegeName);
B> if not LookupPrivilegeName( nil, buffer.Privileges[i].Luid, PChar(@ucPrivilegeName), PrivilegeNameSize) then
B> begin
B> raise Exception.Create(SysErrorMessage(GetLastError));
B> end;
B>
B>Получаю "Specified privilege does not exist". Очевидно, проблемы с приведением типов для дельфовской версии винапи. Может кто-нибуть подскажет, где можно нормальную доку увидеть по использованию винапи в дельфи?
Здравствуйте, Alex Fedotov, Вы писали:
AF>Ну а как LookupPrivilegeName объявлена в Delphi?
Сорри, неправильно свой код привел:
ucPrivilegeName:array[0..255] of char;
PrivilegeNameSize:cardinal;
PrivilegeNameSize:=sizeof(ucPrivilegeName);
if not LookupPrivilegeName( nil, buffer.Privileges[i].Luid, PChar(@ucPrivilegeName), PrivilegeNameSize) then
begin
raise Exception.Create(SysErrorMessage(GetLastError));
end;
А функция объявлена так: LookupPrivilegeName(lpSystem Pchar; LUID Int64; var lpName Pchar; var cbName Cardinal);
пробовал и так:
ucPrivilegeName: Pchar;
PrivilegeNameSize: cardinal;
PrivilegeNameSize:=0; //sizeof(PChar) - как-то не очень имеет смысл, по-моему... Хотя тоже пробовал :-)if not LookupPrivilegeName( nil, buffer.Privileges[i].Luid, ucPrivilegeName, PrivilegeNameSize) then
begin
raise Exception.Create(SysErrorMessage(GetLastError));
end;
Все время та же лабуда — "указанная привилегия не существует". Я нутром чуваствую, что проблема в типах, но как подобрать??? Хрен его знает...
Обратите внимание, что второй параметр является указателем на LUID, а не непосредственным значением LUID. Это, кстати, объясняет, почему выдается ошибка о том, что привилегия не существует.
С другой стороны, третий параметр является указателем на строку, что эквивалентно просто Pchar (не var Pchar) в Delphi. Поэтому правильным объявлением функции в Delphi будет
LookupPrivilegeName(lpSystem:Pchar; var LUID:Int64; lpName:Pchar; var cbName:Cardinal);
Да, Вы правы, опять я неверно написал:
LookupPrivilegeName(lpSystem Pchar; var LUID Int64; lpName Pchar; var cbName Cardinal);
Огромное спасибо, более-менее разобрался, немного заработало. Проблема еще была и в том, что функция возвращает только те привелегии, которые установлены (я так понял) — оказалось, их всего четыре, всего GetTokenInformation возвращал информацию о 17 привелегиях. А на тех, которые не установлены, LookupPrivilegeName возвращал ошибку, при чем ошибку о несуществующей привелегии. Я просто убал exception.
А Ваш пример под С — показывает все привелегии. Я сравнил оба варианта — насколько мне позволяет знание обоих языков программирования — вроде те же способы вызова функций, за исключением обработки ошибок (почему я их убрал, я написал выше).
Теперь вопрос в том, как увидеть ВСЕ привелегии, а не только те, что разрешены?