Sync with trunk r58033.
[reactos.git] / ntoskrnl / po / poshtdwn.c
1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: ntoskrnl/po/poshtdwn.c
5 * PURPOSE: Power Manager Shutdown Code
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <ntoskrnl.h>
12 #ifdef NEWCC
13 #include "../cache/newcc.h"
14 #endif
15 #define NDEBUG
16 #include <debug.h>
17
18 /* GLOBALS *******************************************************************/
19
20 ULONG PopShutdownPowerOffPolicy;
21
22 /* PRIVATE FUNCTIONS *********************************************************/
23
24 VOID
25 NTAPI
26 PopShutdownHandler(VOID)
27 {
28 PUCHAR Logo1, Logo2;
29 ULONG i;
30
31 /* Stop all interrupts */
32 KeRaiseIrqlToDpcLevel();
33 _disable();
34
35 /* Do we have boot video */
36 if (InbvIsBootDriverInstalled())
37 {
38 /* Yes we do, cleanup for shutdown screen */
39 if (!InbvCheckDisplayOwnership()) InbvAcquireDisplayOwnership();
40 InbvResetDisplay();
41 InbvSolidColorFill(0, 0, 639, 479, 0);
42 InbvEnableDisplayString(TRUE);
43 InbvSetScrollRegion(0, 0, 639, 479);
44
45 /* Display shutdown logo and message */
46 Logo1 = InbvGetResourceAddress(IDB_SHUTDOWN_LOGO);
47 Logo2 = InbvGetResourceAddress(IDB_LOGO);
48 if ((Logo1) && (Logo2))
49 {
50 InbvBitBlt(Logo1, 215, 352);
51 InbvBitBlt(Logo2, 217, 111);
52 }
53 }
54 else
55 {
56 /* Do it in text-mode */
57 for (i = 0; i < 25; i++) InbvDisplayString("\n");
58 InbvDisplayString(" ");
59 InbvDisplayString("The system may be powered off now.\n");
60 }
61
62 /* Hang the system */
63 for (;;) HalHaltSystem();
64 }
65
66 VOID
67 NTAPI
68 PopShutdownSystem(IN POWER_ACTION SystemAction)
69 {
70 /* Note should notify caller of NtPowerInformation(PowerShutdownNotification) */
71
72 /* Unload symbols */
73 DPRINT1("It's the final countdown...%lx\n", SystemAction);
74 DbgUnLoadImageSymbols(NULL, (PVOID)-1, 0);
75
76 /* Run the thread on the boot processor */
77 KeSetSystemAffinityThread(1);
78
79 /* Now check what the caller wants */
80 switch (SystemAction)
81 {
82 /* Reset */
83 case PowerActionShutdownReset:
84
85 /* Try platform driver first, then legacy */
86 //PopInvokeSystemStateHandler(PowerStateShutdownReset, NULL);
87 PopSetSystemPowerState(PowerSystemShutdown, SystemAction);
88 HalReturnToFirmware(HalRebootRoutine);
89 break;
90
91 case PowerActionShutdown:
92
93 /* Check for group policy that says to use "it is now safe" screen */
94 if (PopShutdownPowerOffPolicy)
95 {
96 /* FIXFIX: Switch to legacy shutdown handler */
97 //PopPowerStateHandlers[PowerStateShutdownOff].Handler = PopShutdownHandler;
98 }
99
100 case PowerActionShutdownOff:
101
102 /* Call shutdown handler */
103 //PopInvokeSystemStateHandler(PowerStateShutdownOff, NULL);
104
105 /* ReactOS Hack */
106 PopSetSystemPowerState(PowerSystemShutdown, SystemAction);
107 PopShutdownHandler();
108
109 /* If that didn't work, call the HAL */
110 HalReturnToFirmware(HalPowerDownRoutine);
111 break;
112
113 default:
114 break;
115 }
116
117 /* Anything else should not happen */
118 KeBugCheckEx(INTERNAL_POWER_ERROR, 5, 0, 0, 0);
119 }
120
121 VOID
122 NTAPI
123 PopGracefulShutdown(IN PVOID Context)
124 {
125 PEPROCESS Process = NULL;
126
127 /* Loop every process */
128 Process = PsGetNextProcess(Process);
129 while (Process)
130 {
131 /* Make sure this isn't the idle or initial process */
132 if ((Process != PsInitialSystemProcess) && (Process != PsIdleProcess))
133 {
134 /* Print it */
135 DPRINT1("%15s is still RUNNING (%lx)\n", Process->ImageFileName, Process->UniqueProcessId);
136 }
137
138 /* Get the next process */
139 Process = PsGetNextProcess(Process);
140 }
141
142 /* First, the HAL handles any "end of boot" special functionality */
143 DPRINT1("HAL shutting down\n");
144 HalEndOfBoot();
145
146 /* In this step, the I/O manager does first-chance shutdown notification */
147 DPRINT1("I/O manager shutting down in phase 0\n");
148 IoShutdownSystem(0);
149
150 /* In this step, all workers are killed and hives are flushed */
151 DPRINT1("Configuration Manager shutting down\n");
152 CmShutdownSystem();
153
154 /* Note that modified pages should be written here (MiShutdownSystem) */
155 #ifdef NEWCC
156 /* Flush all user files before we start shutting down IO */
157 /* This is where modified pages are written back by the IO manager */
158 CcShutdownSystem();
159 #endif
160
161 /* In this step, the I/O manager does last-chance shutdown notification */
162 DPRINT1("I/O manager shutting down in phase 1\n");
163 IoShutdownSystem(1);
164 CcWaitForCurrentLazyWriterActivity();
165
166 /* Note that here, we should broadcast the power IRP to devices */
167
168 /* In this step, the HAL disables any wake timers */
169 DPRINT1("Disabling wake timers\n");
170 HalSetWakeEnable(FALSE);
171
172 /* And finally the power request is sent */
173 DPRINT1("Taking the system down\n");
174 PopShutdownSystem(PopAction.Action);
175 }
176
177 VOID
178 NTAPI
179 PopReadShutdownPolicy(VOID)
180 {
181 UNICODE_STRING KeyString;
182 OBJECT_ATTRIBUTES ObjectAttributes;
183 NTSTATUS Status;
184 HANDLE KeyHandle;
185 ULONG Length;
186 UCHAR Buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)];
187 PKEY_VALUE_PARTIAL_INFORMATION Info = (PVOID)Buffer;
188
189 /* Setup object attributes */
190 RtlInitUnicodeString(&KeyString,
191 L"\\Registry\\Machine\\Software\\Policies\\Microsoft\\Windows NT");
192 InitializeObjectAttributes(&ObjectAttributes,
193 &KeyString,
194 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
195 NULL,
196 NULL);
197
198 /* Open the key */
199 Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
200 if (NT_SUCCESS(Status))
201 {
202 /* Open the policy value and query it */
203 RtlInitUnicodeString(&KeyString, L"DontPowerOffAfterShutdown");
204 Status = ZwQueryValueKey(KeyHandle,
205 &KeyString,
206 KeyValuePartialInformation,
207 &Info,
208 sizeof(Info),
209 &Length);
210 if ((NT_SUCCESS(Status)) && (Info->Type == REG_DWORD))
211 {
212 /* Read the policy */
213 PopShutdownPowerOffPolicy = *Info->Data == 1;
214 }
215
216 /* Close the key */
217 ZwClose(KeyHandle);
218 }
219 }
220
221 /* PUBLIC FUNCTIONS **********************************************************/
222