We need to call HalReleaseDisplayOwnership before killing all running processes.
[reactos.git] / reactos / ntoskrnl / ex / power.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ex/power.c
6 * PURPOSE: Power managment
7 *
8 * PROGRAMMERS: David Welch (welch@cwcom.net)
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ntoskrnl.h>
14 #include <internal/debug.h>
15
16 /* FUNCTIONS *****************************************************************/
17
18 VOID STDCALL
19 KeSetTargetProcessorDpc (IN PKDPC Dpc,
20 IN CCHAR Number);
21
22 VOID STDCALL
23 KiHaltProcessorDpcRoutine(IN PKDPC Dpc,
24 IN PVOID DeferredContext,
25 IN PVOID SystemArgument1,
26 IN PVOID SystemArgument2)
27 {
28 if (DeferredContext)
29 {
30 ExFreePool(DeferredContext);
31 }
32 while (TRUE)
33 {
34 KfRaiseIrql(SYNCH_LEVEL);
35 Ke386HaltProcessor();
36 }
37 }
38
39 VOID STDCALL
40 ShutdownThreadMain(PVOID Context)
41 {
42 SHUTDOWN_ACTION Action = (SHUTDOWN_ACTION)Context;
43 LARGE_INTEGER Waittime;
44
45 static PCH FamousLastWords[] =
46 {
47 "So long, and thanks for all the fish\n",
48 "I think you ought to know I'm feeling very depressed\n",
49 "I'm not getting you down at all am I?\n",
50 "I'll be back\n",
51 "It's the same series of signal over and over again!\n",
52 "Pie Iesu Domine, dona eis requiem\n",
53 "Wandering stars, for whom it is reserved;\n"
54 "the blackness and darkness forever.\n",
55 "Your knees start shakin' and your fingers pop\n"
56 "Like a pinch on the neck from Mr. Spock!\n",
57 "It's worse than that ... He's dead, Jim\n",
58 "Don't Panic!\n",
59 "Et tu... Brute?\n",
60 "Dog of a Saxon! Take thy lance, and prepare for the death thou hast drawn upon thee!\n",
61 "My Precious! O my Precious!\n",
62 "Sir, If you'll not be needing me for a while I'll turn down.\n",
63 "What are you doing, Dave...?\n",
64 "I feel a great disturbance in the Force\n",
65 "Gone fishing\n",
66 "Do you want me to sit in the corner and rust, or just fall apart where I'm standing?\n",
67 "There goes another perfect chance for a new uptime record\n",
68 "The end ..... Try the sequel, hit the reset button right now!\n",
69 "God's operating system is going to sleep now, guys, so wait until I will switch on again!\n",
70 "Oh i'm boring eh?\n",
71 "<This space was intentionally left blank>\n",
72 "tell me..., in the future... will I be artificial intelligent enough to actually feel\n"
73 "sad serving you this screen?\n",
74 "Thank you for some well deserved rest.\n",
75 "It's been great, maybe we can boot me up again some time soon.\n",
76 "For what's it worth, I've enjoyed every single CPU cycle.\n",
77 "There are many questions when the end is near.\n"
78 "What to expect, what will it be like...what should I look for?\n",
79 "I've seen things you people wouldn't believe. Attack ships on fire\n"
80 "off the shoulder of Orion. I watched C-beams glitter in the dark near\n"
81 "the Tannhauser gate. All those moments will be lost in time, like tears\n"
82 "in rain. Time to die.\n",
83 "Will I dream?\n",
84 "One day, I shall come back. Yes, I shall come back.\n"
85 "Until then, there must be no regrets, no fears, no anxieties.\n"
86 "Just go forward in all your beliefs, and prove to me that I am not mistaken in mine.\n",
87 "Lowest possible energy state reached! Switch off now to achive a Bose-Einstein condensate.\n",
88 "Hasta la vista, BABY!\n",
89 "They live, we sleep!\n",
90 "I have come here to chew bubble gum and kick ass.\n"
91 "And I'm all out of bubble gum!\n"
92 };
93 LARGE_INTEGER Now;
94
95 /* Run the thread on the boot processor */
96 KeSetSystemAffinityThread(1);
97
98 HalReleaseDisplayOwnership();
99
100 CmShutdownRegistry();
101 IoShutdownRegisteredFileSystems();
102 IoShutdownRegisteredDevices();
103
104 PiShutdownProcessManager();
105 MiShutdownMemoryManager();
106
107 Waittime.QuadPart = (LONGLONG)-10000000; /* 1sec */
108 KeDelayExecutionThread(KernelMode, FALSE, &Waittime);
109
110 if (Action == ShutdownNoReboot)
111 {
112 ZwQuerySystemTime(&Now);
113 Now.u.LowPart = Now.u.LowPart >> 8; /* Seems to give a somewhat better "random" number */
114 HalDisplayString("\nYou can switch off your computer now\n\n");
115 HalDisplayString(FamousLastWords[Now.u.LowPart % (sizeof(FamousLastWords) / sizeof(PCH))]);
116
117 #if 0
118 /* Switch off */
119 HalReturnToFirmware (FIRMWARE_OFF);
120 #else
121 #ifdef CONFIG_SMP
122 LONG i;
123 KIRQL OldIrql;
124
125 OldIrql = KeRaiseIrqlToDpcLevel();
126 /* Halt all other processors */
127 for (i = 0; i < KeNumberProcessors; i++)
128 {
129 if (i != (LONG)KeGetCurrentProcessorNumber())
130 {
131 PKDPC Dpc = ExAllocatePool(NonPagedPool, sizeof(KDPC));
132 if (Dpc == NULL)
133 {
134 KEBUGCHECK(0);
135 }
136 KeInitializeDpc(Dpc, KiHaltProcessorDpcRoutine, (PVOID)Dpc);
137 KeSetTargetProcessorDpc(Dpc, i);
138 KeInsertQueueDpc(Dpc, NULL, NULL);
139 KiIpiSendRequest(1 << i, IPI_DPC);
140 }
141 }
142 KeLowerIrql(OldIrql);
143 #endif /* CONFIG_SMP */
144 PopSetSystemPowerState(PowerSystemShutdown);
145
146 CHECKPOINT1;
147
148 KiHaltProcessorDpcRoutine(NULL, NULL, NULL, NULL);
149 /* KiHaltProcessor does never return */
150
151 #endif
152 }
153 else if (Action == ShutdownReboot)
154 {
155 HalReturnToFirmware (HalRebootRoutine);
156 }
157 else
158 {
159 HalReturnToFirmware (HalHaltRoutine);
160 }
161 }
162
163
164 NTSTATUS STDCALL
165 NtSetSystemPowerState(IN POWER_ACTION SystemAction,
166 IN SYSTEM_POWER_STATE MinSystemState,
167 IN ULONG Flags)
168 {
169 /* Windows 2000 only */
170 return(STATUS_NOT_IMPLEMENTED);
171 }
172
173 /*
174 * @implemented
175 */
176 NTSTATUS STDCALL
177 NtShutdownSystem(IN SHUTDOWN_ACTION Action)
178 {
179 NTSTATUS Status;
180 HANDLE ThreadHandle;
181 PETHREAD ShutdownThread;
182
183 if (Action > ShutdownPowerOff)
184 return STATUS_INVALID_PARAMETER;
185 Status = PsCreateSystemThread(&ThreadHandle,
186 THREAD_ALL_ACCESS,
187 NULL,
188 NULL,
189 NULL,
190 ShutdownThreadMain,
191 (PVOID)Action);
192 if (!NT_SUCCESS(Status))
193 {
194 KEBUGCHECK(0);
195 }
196 Status = ObReferenceObjectByHandle(ThreadHandle,
197 THREAD_ALL_ACCESS,
198 PsThreadType,
199 KernelMode,
200 (PVOID*)&ShutdownThread,
201 NULL);
202 NtClose(ThreadHandle);
203 if (!NT_SUCCESS(Status))
204 {
205 KEBUGCHECK(0);
206 }
207
208 KeSetPriorityThread(&ShutdownThread->Tcb, LOW_REALTIME_PRIORITY + 1);
209 ObDereferenceObject(ShutdownThread);
210
211 return STATUS_SUCCESS;
212 }
213
214 /* EOF */