mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 02:25:17 +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 *****************************************************************/
|
/* 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
|
NTSTATUS STDCALL
|
||||||
NtSetSystemPowerState(IN POWER_ACTION SystemAction,
|
NtSetSystemPowerState(IN POWER_ACTION SystemAction,
|
||||||
IN SYSTEM_POWER_STATE MinSystemState,
|
IN SYSTEM_POWER_STATE MinSystemState,
|
||||||
|
@ -31,6 +121,10 @@ NtSetSystemPowerState(IN POWER_ACTION SystemAction,
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
NtShutdownSystem(IN SHUTDOWN_ACTION Action)
|
NtShutdownSystem(IN SHUTDOWN_ACTION Action)
|
||||||
{
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
HANDLE ThreadHandle;
|
||||||
|
PETHREAD ShutdownThread;
|
||||||
|
|
||||||
static PCH FamousLastWords[] =
|
static PCH FamousLastWords[] =
|
||||||
{
|
{
|
||||||
"So long, and thanks for all the fish\n",
|
"So long, and thanks for all the fish\n",
|
||||||
|
@ -84,42 +178,41 @@ NtShutdownSystem(IN SHUTDOWN_ACTION Action)
|
||||||
ZwQuerySystemTime(&Now);
|
ZwQuerySystemTime(&Now);
|
||||||
Now.u.LowPart = Now.u.LowPart >> 8; /* Seems to give a somewhat better "random" number */
|
Now.u.LowPart = Now.u.LowPart >> 8; /* Seems to give a somewhat better "random" number */
|
||||||
|
|
||||||
IoShutdownRegisteredDevices();
|
|
||||||
CmShutdownRegistry();
|
|
||||||
IoShutdownRegisteredFileSystems();
|
|
||||||
|
|
||||||
PiShutdownProcessManager();
|
|
||||||
MiShutdownMemoryManager();
|
|
||||||
|
|
||||||
if (Action == ShutdownNoReboot)
|
if (Action == ShutdownNoReboot)
|
||||||
{
|
{
|
||||||
HalReleaseDisplayOwnership();
|
HalReleaseDisplayOwnership();
|
||||||
HalDisplayString("\nYou can switch off your computer now\n\n");
|
HalDisplayString("\nYou can switch off your computer now\n\n");
|
||||||
HalDisplayString(FamousLastWords[Now.u.LowPart % (sizeof(FamousLastWords) / sizeof(PCH))]);
|
HalDisplayString(FamousLastWords[Now.u.LowPart % (sizeof(FamousLastWords) / sizeof(PCH))]);
|
||||||
#if 0
|
}
|
||||||
/* Switch off */
|
Status = PsCreateSystemThread(&ThreadHandle,
|
||||||
HalReturnToFirmware (FIRMWARE_OFF);
|
THREAD_ALL_ACCESS,
|
||||||
#else
|
NULL,
|
||||||
PopSetSystemPowerState(PowerSystemShutdown);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
while (TRUE)
|
KeSetPriorityThread(&ShutdownThread->Tcb, LOW_REALTIME_PRIORITY + 1);
|
||||||
{
|
ObDereferenceObject(ShutdownThread);
|
||||||
Ke386DisableInterrupts();
|
|
||||||
Ke386HaltProcessor();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (Action == ShutdownReboot)
|
|
||||||
{
|
|
||||||
HalReturnToFirmware (FIRMWARE_REBOOT);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HalReturnToFirmware (FIRMWARE_HALT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue