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