mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
- Used a system thread to shutdown various kernel components.
- Halt also the other processors on a smp machine. svn path=/trunk/; revision=12835
This commit is contained in:
parent
6801048d57
commit
3d5ec80a67
1 changed files with 121 additions and 28 deletions
|
@ -16,6 +16,96 @@
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID STDCALL
|
||||
KeSetTargetProcessorDpc (IN PKDPC Dpc,
|
||||
IN CCHAR Number);
|
||||
|
||||
VOID STDCALL
|
||||
KiHaltProcessorDpcRoutine(IN PKDPC Dpc,
|
||||
IN PVOID DeferredContext,
|
||||
IN PVOID SystemArgument1,
|
||||
IN PVOID SystemArgument2)
|
||||
{
|
||||
if (DeferredContext)
|
||||
{
|
||||
ExFreePool(DeferredContext);
|
||||
}
|
||||
while (TRUE)
|
||||
{
|
||||
KfRaiseIrql(SYNCH_LEVEL);
|
||||
Ke386HaltProcessor();
|
||||
}
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
ShutdownThreadMain(PVOID Context)
|
||||
{
|
||||
SHUTDOWN_ACTION Action = (SHUTDOWN_ACTION)Context;
|
||||
LARGE_INTEGER Waittime;
|
||||
|
||||
/* Run the thread on the boot processor */
|
||||
KeSetSystemAffinityThread(1);
|
||||
|
||||
IoShutdownRegisteredDevices();
|
||||
CmShutdownRegistry();
|
||||
IoShutdownRegisteredFileSystems();
|
||||
|
||||
PiShutdownProcessManager();
|
||||
MiShutdownMemoryManager();
|
||||
|
||||
Waittime.QuadPart = (LONGLONG)-10000000; /* 1sec */
|
||||
KeDelayExecutionThread(KernelMode, FALSE, &Waittime);
|
||||
|
||||
if (Action == ShutdownNoReboot)
|
||||
{
|
||||
|
||||
#if 0
|
||||
/* Switch off */
|
||||
HalReturnToFirmware (FIRMWARE_OFF);
|
||||
#else
|
||||
#ifdef CONFIG_SMP
|
||||
ULONG i;
|
||||
KIRQL OldIrql;
|
||||
|
||||
OldIrql = KeRaiseIrqlToDpcLevel();
|
||||
/* Halt all other processors */
|
||||
for (i = 0; i < KeNumberProcessors; i++)
|
||||
{
|
||||
if (i != KeGetCurrentProcessorNumber())
|
||||
{
|
||||
PKDPC Dpc = ExAllocatePool(NonPagedPool, sizeof(KDPC));
|
||||
if (Dpc == NULL)
|
||||
{
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
KeInitializeDpc(Dpc, KiHaltProcessorDpcRoutine, (PVOID)Dpc);
|
||||
KeSetTargetProcessorDpc(Dpc, i);
|
||||
KeInsertQueueDpc(Dpc, NULL, NULL);
|
||||
KiIpiSendRequest(1 << i, IPI_REQUEST_DPC);
|
||||
}
|
||||
}
|
||||
KeLowerIrql(OldIrql);
|
||||
#endif /* CONFIG_SMP */
|
||||
PopSetSystemPowerState(PowerSystemShutdown);
|
||||
|
||||
CHECKPOINT1;
|
||||
|
||||
KiHaltProcessorDpcRoutine(NULL, NULL, NULL, NULL);
|
||||
/* KiHaltProcessor does never return */
|
||||
|
||||
#endif
|
||||
}
|
||||
else if (Action == ShutdownReboot)
|
||||
{
|
||||
HalReturnToFirmware (FIRMWARE_REBOOT);
|
||||
}
|
||||
else
|
||||
{
|
||||
HalReturnToFirmware (FIRMWARE_HALT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
NtSetSystemPowerState(IN POWER_ACTION SystemAction,
|
||||
IN SYSTEM_POWER_STATE MinSystemState,
|
||||
|
@ -31,6 +121,10 @@ NtSetSystemPowerState(IN POWER_ACTION SystemAction,
|
|||
NTSTATUS STDCALL
|
||||
NtShutdownSystem(IN SHUTDOWN_ACTION Action)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE ThreadHandle;
|
||||
PETHREAD ShutdownThread;
|
||||
|
||||
static PCH FamousLastWords[] =
|
||||
{
|
||||
"So long, and thanks for all the fish\n",
|
||||
|
@ -84,42 +178,41 @@ NtShutdownSystem(IN SHUTDOWN_ACTION Action)
|
|||
ZwQuerySystemTime(&Now);
|
||||
Now.u.LowPart = Now.u.LowPart >> 8; /* Seems to give a somewhat better "random" number */
|
||||
|
||||
IoShutdownRegisteredDevices();
|
||||
CmShutdownRegistry();
|
||||
IoShutdownRegisteredFileSystems();
|
||||
|
||||
PiShutdownProcessManager();
|
||||
MiShutdownMemoryManager();
|
||||
|
||||
if (Action == ShutdownNoReboot)
|
||||
{
|
||||
HalReleaseDisplayOwnership();
|
||||
HalDisplayString("\nYou can switch off your computer now\n\n");
|
||||
HalDisplayString(FamousLastWords[Now.u.LowPart % (sizeof(FamousLastWords) / sizeof(PCH))]);
|
||||
#if 0
|
||||
/* Switch off */
|
||||
HalReturnToFirmware (FIRMWARE_OFF);
|
||||
#else
|
||||
PopSetSystemPowerState(PowerSystemShutdown);
|
||||
}
|
||||
Status = PsCreateSystemThread(&ThreadHandle,
|
||||
THREAD_ALL_ACCESS,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ShutdownThreadMain,
|
||||
(PVOID)Action);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
Status = ObReferenceObjectByHandle(ThreadHandle,
|
||||
THREAD_ALL_ACCESS,
|
||||
PsThreadType,
|
||||
KernelMode,
|
||||
(PVOID*)&ShutdownThread,
|
||||
NULL);
|
||||
NtClose(ThreadHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
|
||||
KeSetPriorityThread(&ShutdownThread->Tcb, LOW_REALTIME_PRIORITY + 1);
|
||||
ObDereferenceObject(ShutdownThread);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
Ke386DisableInterrupts();
|
||||
Ke386HaltProcessor();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (Action == ShutdownReboot)
|
||||
{
|
||||
HalReturnToFirmware (FIRMWARE_REBOOT);
|
||||
}
|
||||
else
|
||||
{
|
||||
HalReturnToFirmware (FIRMWARE_HALT);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* EOF */
|
||||
|
||||
|
|
Loading…
Reference in a new issue