1 /* gcc -mwindows -mno-cygwin -o halt.exe halt.c
2 NAME
3 	halt - stopping the system
4 
5 SYNOPSIS
6 	halt [-pq]
7 
8 DESCRIPTION
9 	The halt utility logs off the current user, flushes the file system
10 	buffers to disk, stops all processes (non-responsive processes are
11 	only forced to stop in Windows 2000), and shuts the system down.
12 
13 	The options are as follows
14 
15 	-p	Attempt to powerdown the system.  If the powerdown fails, or
16 		the system does not support software powerdown, the system
17 		will halt.
18 
19 	-q	Do not give processes a chance to shut down before halting or
20 		restarting.  This option should not normally be used.
21 
22 AUTHOR
23 	Ben Collver <collver@softhome.net>
24  */
25 
26 #include <windows.h>
27 
28 #ifndef EWX_FORCEIFHUNG
29 #define EWX_FORCEIFHUNG 0x00000010
30 #endif
31 
WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)32 int WINAPI WinMain(
33 	HINSTANCE hInstance,
34 	HINSTANCE hPrevInstance,
35 	LPSTR lpCmdLine,
36 	int nCmdShow)
37 {
38 	TOKEN_PRIVILEGES privileges = {1, {{{0, 0}, SE_PRIVILEGE_ENABLED}}};
39 	HANDLE my_token;
40 	UINT my_flags;
41 
42 	my_flags = EWX_SHUTDOWN | EWX_FORCEIFHUNG;
43 
44 	if (strstr(lpCmdLine, "q") != NULL) {
45 		my_flags |= EWX_FORCE;
46 	}
47 
48 	if (strstr(lpCmdLine, "p") != NULL) {
49 		my_flags |= EWX_POWEROFF;
50 	}
51 
52 	if (!LookupPrivilegeValue(
53 		NULL,
54 		SE_SHUTDOWN_NAME,
55 		&privileges.Privileges[0].Luid))
56 	{
57 		exit(1);
58 	}
59 
60 	if (!OpenProcessToken(
61 		GetCurrentProcess(),
62 		TOKEN_ADJUST_PRIVILEGES,
63 		&my_token))
64 	{
65 		exit(2);
66 	}
67 
68 	if (!AdjustTokenPrivileges(
69 		my_token,
70 		FALSE,
71 		&privileges,
72 		sizeof(TOKEN_PRIVILEGES),
73 		NULL,
74 		NULL))
75 	{
76 		exit(3);
77 	}
78 
79 	CloseHandle(my_token);
80 	if (!ExitWindowsEx(my_flags, 0)) {
81 		exit(4);
82 	}
83 	exit(0);
84 }
85