Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Переделал 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]

По-моему, незачем корректно закрывать хендлы, если все равно следом выполняется перезагрузка.


Наверх

Титульная страница Поиск, карта сайта Написать письмо