Author: Jonas Bilinkevicius
How would I reboot the system and restart my program?
Answer:
Solve 1:
This will reboot, shutdown, etc. It's a wrapper function for the ExitWindowsEx API:
function ExitWin(ExitType: Integer): Boolean;
{ExitType can be any of these values:
EWX_FORCE, EWX_LOGOFF, EWX_POWEROFF, EWX_REBOOT, EWX_SHUTDOWN}
1
2 function GetShutdownPrivilege: Boolean;
3 var
4 hToken: THandle;
5 tkp: TTokenPrivileges;
6 retlength: DWORD;
7 Newt: TTokenPrivileges;
8 begin
9 Result := False;
10 hToken := GetCurrentProcess();
11 if OpenProcessToken(hToken, TOKEN_ADJUST_PRIVILEGES + TOKEN_QUERY, hToken) then
12 begin
13 {Get the LUID for shutdown privilege}
14 if LookupPrivilegeValue(nil, 'SeShutdownPrivilege', tkp.Privileges[0].Luid)
15 then
16 begin
17 tkp.PrivilegeCount := 1; {One privilege to set}
18 tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
19 {Get shutdown privilege for this process}
20 Result := AdjustTokenPrivileges(hToken, FALSE, tkp,
21 sizeof(TTokenPrivileges),
22 Newt, retlength)
23 end;
24 end;
25 end;
26
27 begin
28 if Win32Platform = VER_PLATFORM_WIN32_NT then
29 GetShutdownPrivilege;
30 if ExitWindowsEx(ExitType, 0) then
31 begin
32 Result := True;
33 end
34 else
35 begin
36 Result := False;
37 end;
38 end;
Solve 2:
39
40 procedure QuitWindows(uFlags: UINT; forced: boolean);
41 {uFlages can be: EWX_LOGOFF, EWX_REBOOT or EWX_SHUTDOWN}
42 var
43 hProcess: THandle;
44 hToken: THandle;
45 tpAct, tpPrev: TTokenPrivileges;
46 wDummy: DWORD;
47 begin
48 hProcess := GetCurrentProcess;
49 OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken);
50 LookupPrivilegeValue(nil, 'SeShutdownPrivilege', tpAct.Privileges[0].Luid);
51 tpPrev := tpAct;
52 tpAct.PrivilegeCount := 1;
53 tpAct.Privileges[0].Attributes := 2;
54 AdjustTokenPrivileges(hToken, false, tpAct, SizeOf(tpPrev), tpPrev, wDummy);
55 if forced then
56 uFLags := uFlags or EWX_FORCE;
57 ExitWindowsEx(uFlags, 0);
58 end;
Solve 3:
59
60 function GetShutdownPrivilege: Boolean;
61 const
62 SHN: PChar = 'SeShutdownPrivilege';
63 EMP: PChar = '';
64 var
65 hToken: THandle;
66 tkp, p: TTokenPrivileges;
67 RetLen: DWORD;
68 Err: DWord;
69 begin
70 {Get a token for this process.}
71 if not OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or
72 TOKEN_QUERY, hToken) then
73 begin
74 Result := False; // 'Error: OpenProcessToken:' + IntToStr(GetLastError)
75 Exit;
76 end;
77 {Get the LUID for the shutdown privilege.}
78 if not LookupPrivilegeValue(EMP, SHN, tkp.Privileges[0].Luid) then
79 begin
80 Result := False; // 'Error: LookupPrivilegeValue:' + IntToStr(GetLastError)
81 Exit;
82 end;
83 tkp.PrivilegeCount := 1; {One privilege to set}
84 tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
85 {Get the shutdown privilege for this process}
86 AdjustTokenPrivileges(hToken, False, tkp, SizeOf(TTokenPrivileges), p, RetLen);
87 {Cannot test the return value of AdjustTokenPrivileges}
88 Err := GetLastError;
89 if Err <> ERROR_SUCCESS then
90 begin
91 { Err = 1300: 'You do not have the right to shut the system down'
92 else
93 'Error: AdjustTokenPrivileges: ' + IntToStr(Err); }
94 Result := False;
95 Exit;
96 end;
97 {Current user have privileges to shutdown the system}
98 Result := True;
99 end;
100
101 //Usage:
102
103 function MyExit(Param1, Param2: LongWord): Boolean;
104 if Win32Platform = VER_PLATFORM_WIN32_NT then
105 GetShutdownPrivilege;
106 Result := ExitWindowsEx(Param1, Param2)
107 end;
Solve 4:
A quite common question I see often in discussion groups is how to shutdown/reboot
Windows NT. The problem is that the usual API for the task, ExitWindowsEx, doesn't
work right away with Windows NT. It's necessary to "ask for permission" before
calling ExitWindows NT. This means that a process must have the SE_SHUTDOWN_NAME
privilege for rebooting, powering off, or shutting the system, forced or not (using
the EWX_FORCE flag).
For those who have taken a look at the Win32 Development Guide, a help file that
comes with Delphi, there's a topic that explains how to shut down Windows NT, but
that code is in C++. I've translated the code to Delphi, creating a function called
ExitWindowsNT.
Calling ExitWindowsNT is just like calling ExitWindowsEx with only the uFlags
paramter. The uFlags parameter specifies the type of shutdown. More about this is
explained in the topic "ExitWindowsEx" in the Win32 SDK.
All that said, let's go the function itself:
108
109 procedure ExitWindowsNT(uFlags: integer);
110 var
111 hToken: THANDLE;
112 tkp, tkDumb: TTokenPrivileges;
113 DumbInt: integer;
114 begin
115 FillChar(tkp, sizeof(tkp), 0);
116 // Get a token for this process
117 if not (OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES
118 or TOKEN_QUERY, hToken)) then
119 raise Exception.create('OpenProcessToken failed with code '
120 + inttostr(GetLastError));
121
122 // Get the LUID for the Shutdown privilege
123 LookupPrivilegeValue(nil, pchar('SeShutdownPrivilege'),
124 tkp.Privileges[0].Luid);
125
126 tkp.PrivilegeCount := 1; // one privilege to set
127 tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
128
129 // Get the shutdown provolege for this process
130 AdjustTokenPrivileges(hToken, false, tkp, sizeof(tkDumb), tkDumb, DumbInt);
131
132 // Cannot test the return value of AdjustTokenPrivileges
133 if GetLastError <> ERROR_SUCCESS then
134 raise Exception.create('AdjustTokenPrivileges failed with code '
135 + inttostr(GetLastError));
136
137 // shut down the system and for all applications to close
138 if not ExitWindowsEx(uFlags, 0) then
139 raise Exception.create('ExitWindowsEx failed with code '
140 + inttostr(GetLastError));
141 end;
A few examples on using the function above are:
ExitWindowsNT(EWX_SHUTDOWN or EWX_FORCE); ---- This will shutdown Windows NT
without making questions. All opened applications will be closed and any unsaved
data will be lost.
ExitWindowsNT(EWX_REBOOT); ---- This will reboot the system. Applications will be
sent the WM_QUERYENDSESSION message so they can stop the process.
For other possible combinations of EWX_FORCE, EWX_REBOOT, EWX_POWEROFF, EWX_LOGOFF,
EWX_SHUTDOWN, please refer to the Win32 Development Guide.
Solve 5:
Shut-down system under Win XP:
142
143 function DoExitWindows(RebootParam: Longword): boolean;
144 var
145 TTokenHd: THandle;
146 TTokenPvg: TTokenPrivileges;
147 cbtpPrevious: DWORD;
148 rTTokenPvg: TTokenPrivileges;
149 pcbtpPreviousRequired: DWORD;
150 tpResult: boolean;
151 const
152 cSE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
153 begin
154 if (Win32Platform = VER_PLATFORM_WIN32_NT) then
155 begin
156 tpResult := OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES
157 or TOKEN_QUERY, TTokenHd);
158 if tpResult then
159 begin
160 tpResult := LookupPrivilegeValue(nil, cSE_SHUTDOWN_NAME,
161 TTokenPvg.Privileges[0].Luid);
162 TTokenPvg.PrivilegeCount := 1;
163 TTokenPvg.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
164 cbtpPrevious := SizeOf(rTTokenPvg);
165 pcbtpPreviousRequired := 0;
166 if tpResult then
167 Windows.AdjustTokenPrivileges(TTokenHd, false, TTokenPvg, cbtpPrevious,
168 rTTokenPvg, pcbtpPreviousRequired);
169 end;
170 end;
171 Result := ExitWindowsEx(RebootParam, 0);
172 end;
Used like this:
DoExitWindows(EWX_SHUTDOWN or EWX_FORCE);
|