![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Переделал WindowsShutdown из KOL [Delphi]
Ruzzz © (2010-02-22 05:12:00)Переделал WindowsShutdown из KOL.pas
// if fail Result = 0
function EnablePrivilege(const Machine, PrivilegesName: KOLString;
var PreviousState: TTokenPrivileges): THandle;
var
Ftkp: TTokenPrivileges;
dwRetLen :DWORD;
begin
if not OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES
or TOKEN_QUERY, Result) then
begin
Result := 0;
Exit;
end;
if not LookupPrivilegeValue(PKOLChar(Machine), PKOLChar(PrivilegesName),
Ftkp.Privileges[0].Luid) then
begin
CloseHandle(Result);
Result := 0;
Exit;
end;
Ftkp.PrivilegeCount := 1;
Ftkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
// TODO: Корректно обрабатывать PreviousState, dwRetLen
if (not AdjustTokenPrivileges(Result, FALSE, Ftkp, sizeof(Ftkp),
PreviousState, dwRetLen)) or (GetLastError() = ERROR_NOT_ALL_ASSIGNED) then
begin
CloseHandle(Result);
Result := 0;
Exit;
end;
end;
procedure RestorePrivilege(hToken: THandle; Previous: TTokenPrivileges);
var
dummy: Cardinal;
begin
AdjustTokenPrivileges(hToken, FALSE, Previous, sizeOf(Previous), nil, dummy);
CloseHandle(hToken);
end;
function WindowsShutdown(const Machine: KOLString; Force, Reboot: Boolean): Boolean;
var
hToken: THandle;
tkp_prev: TTokenPrivileges;
Flags: Integer;
PrName: KOLString;
begin
Result := False;
if Integer( GetVersion ) < 0 then // Windows95/98/Me
begin
if Machine <> '' then Exit;
Flags := EWX_SHUTDOWN;
if Reboot then
Flags := Flags or EWX_REBOOT;
if Force then
Flags := Flags or EWX_FORCE;
Result := ExitWindowsEx( Flags, 0 );
Exit;
end;
if Machine = '' then
PrName := 'SeShutdownPrivilege'
else
PrName := 'SeRemoteShutdownPrivilege';
hToken := EnablePrivilege(Machine, PrName, tkp_prev);
if hToken = 0 then Exit;
Result := InitiateSystemShutdown(PKOLChar(Machine), nil, 0, Force, Reboot);
if not Result then RestorePrivilege(hToken, tkp_prev);
// Иначе восстанавливать нет смысла
end;
В оригинале не закрывается hToken, не критично но все же :) Плюс лишний tkp_prev:=tkp; и зачем получать сразу обе привилегии 'SeShutdownPrivilege' и 'SeRemoteShutdownPrivilege'? Плюс код включения привелегий может еще кому-то пригодиться. Например вот:
function Suspend(Hibernate, Force: Boolean): Boolean;
var
hToken: THandle;
tkp_prev: TTokenPrivileges;
begin
Result := False;
if Integer( GetVersion ) < 0 then Exit; // Windows95/98/Me
hToken := EnablePrivilege('', 'SeShutdownPrivilege', tkp_prev);
if hToken = 0 then Exit;
Result := SetSystemPowerState(not Hibernate, Force); // or SetSuspendState
RestorePrivilege(hToken, tkp_prev);
end;
Если ошибок нет, предлагаю заменить и добавить.
Ruzzz (2010-02-23 22:11:00) [1]miek, в коде видно, что хендл закрывается лишь в случае ошибки, конечно же, врядли незакрытие сделает проблемы, но все же.
Основная идея это EnablePrivilege и RestorePrivilege которые могут пригодиться. Ну и исправления:
«лишний tkp_prev:=tkp; и зачем получать сразу обе привилегии 'SeShutdownPrivilege' и 'SeRemoteShutdownPrivilege'»
miek (2010-02-23 13:27:00) [2]По-моему, незачем корректно закрывать хендлы, если все равно следом выполняется перезагрузка.