Содержание материала

 

Code:

function MyExitWindows(RebootParam: Longword): Boolean;

var

TTokenHd: THandle;

TTokenPvg: TTokenPrivileges;

cbtpPrevious: DWORD;

rTTokenPvg: TTokenPrivileges;

pcbtpPreviousRequired: DWORD;

tpResult: Boolean;

const

SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';

begin

if Win32Platform = VER_PLATFORM_WIN32_NT then

begin

   tpResult := OpenProcessToken(GetCurrentProcess(),

     TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,

     TTokenHd);

   if tpResult then

   begin

     tpResult := LookupPrivilegeValue(nil,

                                      SE_SHUTDOWN_NAME,

                                      TTokenPvg.Privileges[0].Luid);

     TTokenPvg.PrivilegeCount := 1;

     TTokenPvg.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;

     cbtpPrevious := SizeOf(rTTokenPvg);

     pcbtpPreviousRequired := 0;

     if tpResult then

       Windows.AdjustTokenPrivileges(TTokenHd,

                                     False,

                                     TTokenPvg,

                                     cbtpPrevious,

                                     rTTokenPvg,

                                     pcbtpPreviousRequired);

   end;

end;

Result := ExitWindowsEx(RebootParam, 0);

end;

 

// Example to shutdown Windows:

 

procedure TForm1.Button1Click(Sender: TObject);

begin

MyExitWindows(EWX_POWEROFF or EWX_FORCE);

end;

 

// Example to reboot Windows:

 

procedure TForm1.Button1Click(Sender: TObject);

begin

MyExitWindows(EWX_REBOOT or EWX_FORCE);

end;

 


  

Code:

program Shutdown;

{$APPTYPE CONSOLE}

 

uses

SysUtils,

Windows;

 

// Shutdown Program

// (c) NeuralAbyss Software

//

 

var

logoff: Boolean = False;

reboot: Boolean = False;

warn: Boolean = False;

downQuick: Boolean = False;

cancelShutdown: Boolean = False;

powerOff: Boolean = False;

timeDelay: Integer = 0;

 

function HasParam(Opt: Char): Boolean;

var

x: Integer;

begin

Result := False;

for x := 1 to ParamCount do

   if (ParamStr(x) = '-' + opt) or (ParamStr(x) = '/' + opt) then Result := True;

end;

 

function GetErrorstring: string;

var

lz: Cardinal;

err: array[0..512] of Char;

begin

lz := GetLastError;

FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nil, lz, 0, @err, 512, nil);

Result := string(err);

end;

 

procedure DoShutdown;

var

rl, flgs: Cardinal;

hToken: Cardinal;

tkp: TOKEN_PRIVILEGES;

begin

flgs := 0;

if downQuick then flgs := flgs or EWX_FORCE;

if not reboot then flgs := flgs or EWX_SHUTDOWN;

if reboot then flgs := flgs or EWX_REBOOT;

if poweroff and (not reboot) then flgs := flgs or EWX_POWEROFF;

if logoff then flgs := (flgs and (not (EWX_REBOOT or EWX_SHUTDOWN or EWX_POWEROFF))) or

     EWX_LOGOFF;

if Win32Platform = VER_PLATFORM_WIN32_NT then

begin

   if not OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,

     hToken) then

     Writeln('Cannot open process token. [' + GetErrorstring + ']')

   else

   begin

     if LookupPrivilegeValue(nil, 'SeShutdownPrivilege', tkp.Privileges[0].Luid) then

     begin

       tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;

       tkp.PrivilegeCount           := 1;

       AdjustTokenPrivileges(hToken, False, tkp, 0, nil, rl);

       if GetLastError <> ERROR_SUCCESS then

         Writeln('Error adjusting process privileges.');

     end

     else

       Writeln('Cannot find privilege value. [' + GetErrorstring + ']');

   end;

   {   if CancelShutdown then

         if AbortSystemShutdown(nil) = False then

           Writeln(\'Cannot abort. [\' + GetErrorstring + \']\')

         else

          Writeln(\'Cancelled.\')

      else

      begin

        if InitiateSystemShutdown(nil, nil, timeDelay, downQuick, Reboot) = False then

           Writeln(\'Cannot go down. [\' + GetErrorstring + \']\')

        else

           Writeln(\'Shutting down!\');

      end;

   }

end;

//     else begin

ExitWindowsEx(flgs, 0);

//     end;

end;

 

begin

Writeln('Shutdown v0.3 for Win32 (similar to the Linux version)');

Writeln('(c) 2000 NeuralAbyss Software. All Rights Reserved.');

if HasParam('?') or (ParamCount = 0) then

begin

   Writeln('Usage:    shutdown [-akrhfnc] [-t secs]');

   Writeln('                  -k:      do not really shutdown, only warn.');

   Writeln('                  -r:      reboot after shutdown.');

   Writeln('                  -h:      halt after shutdown.');

   Writeln('                  -p:      power off after shutdown');

   Writeln('                  -l:      log off only');

   Writeln('                  -n:      kill apps that do not want to die.');

   Writeln('                  -c:      cancel a running shutdown.');

end

else

begin

   if HasParam('k') then warn := True;

   if HasParam('r') then reboot := True;

   if HasParam('h') and reboot then

   begin

     Writeln('Error: Cannot specify -r and -h parameters together!');

     Exit;

   end;

   if HasParam('h') then reboot := False;

   if HasParam('n') then downQuick := True;

   if HasParam('c') then cancelShutdown := True;

   if HasParam('p') then powerOff := True;

   if HasParam('l') then logoff := True;

   DoShutdown;

end;

end.

 


 Для выполнения перезагрузки/выключения предназначены функции ExitWindows/ExitWindowsEx

 

ExitWindows:

 

Описание:

Function ExitWindows(Reserved: DWord; ReturnCode: Word): Bool;

Иницииpует стандаpтную пpоцедуpу завеpшения pаботы с Windows. Все пpикладные задачи должны подтвеpдить завеpшение pаботы Windows. Вызывает функцию 4CH пpеpывания 21H DOS.

 

Паpаметpы:

Reserved: Установлен в нуль.

ReturnCode: Значение, пеpедаваемое в DOS (в pегистpе AL).

 

Возвpащаемое значение:

Нуль, если одна или несколько задач отказываются завеpшить pаботу.

 

Примеры использования:

ExitWindows(EWX_LOGOFF,0); - завершение сеанса

ExitWindows(EWX_SHUTDOWN,0); - выключение компьютера

ExitWindows(EWX_REBOOT,0); - перезагрузка

Флаги EWX_FORCE, EWX_POWEROFF и  EWX_FORCEIFHUNG могут комбинироваться к нужному действию.

 

ExitWindowsEx:

Функция ExitWindowsEx() представляет собой расширенный вариант ExitWindows().

 

Описание:

BOOL ExitWindowsEx( UINT uFlags, DWORD dwReserved, );

Функция ExitWindowsEx перезагружает(restart) или выключает систему (shutdown), а также может завершить сессию для текущего пользователя(log off).

 

Параметры:

uFlags -- флаг завершения работы, может принимать следущие значения:

  EWX_LOGOFF завершает сессию текущего пользователя.

  EWX_POWEROFF выключает питание компьютера(компьютер должен поддерживать данную функцию).

  EWX_REBOOT перезагружает систему.

  EWX_SHUTDOWN завершает работу комьпьютера до того места, где он может быть безопасно выключен: сброшенны все файловые буферы на диск, завершает работу всех процессов.

dwReserved --Зарезирвированно для последующих нужд, параметр игнорируется.

 

Возвращаемое значение:

Не ноль если всё прошло успешно

 

Пример использования:

ExitWindowsEx(EWX_SHUTDOWN,0);

Остальные примеры смотри в описании первой функции.

 


Вышеописанные примеры действительны только для w9x/Me.

Дело в том, что, чтобы выполнить функциию в NT ОС, нужно получить права на выполнение этой функции. Сделать это можно через AdjustTokenPriviligies.

С помощью нижеприведённой функции можно получить любую привелегию, в т.ч. и привеленгию SeShutdownPrivilege, которая нужна для разрешения функции ExitWindows(Ex)

 

Code:

Function SetPrivilege(aPrivilegeName: String; aEnabled: Boolean ): Boolean;

Var TPPrev,

     TP: TTokenPrivileges;

     Token: THandle;

     dwRetLen: DWord;

Begin

Result:=False;

OpenProcessToken(GetCurrentProcess,TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, @Token );

TP.PrivilegeCount:=1;

IF LookupPrivilegeValue(nil,PChar(aPrivilegeName),TP.Privileges[0].LUID )) then

Begin

  IF aEnabled then TP.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED

             else TP.Privileges[0].Attributes:=0;

  dwRetLen:= 0;

  Result:=AdjustTokenPrivileges(Token,False,TP,SizeOf(TPPrev),TPPrev,dwRetLen);

End;

CloseHandle(Token);

End;

  

Пример использования для среды NT:

 

SetPrivilege('SeShutdownPrivilege',True);

ExitWindowsEx(EWX_SHUTDOWN,0);

 

Добавить комментарий

Не использовать не нормативную лексику.

Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.

ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!


Защитный код
Обновить