mirror of
https://github.com/reactos/reactos.git
synced 2024-06-30 09:50:07 +00:00
[NTOSKRNL]
Implement PoQueueShutdownWorkItem, PoRequestShutdownEvent, PoRequestShutdownWait, PopProcessShutDownLists. One step closer to ... proper shutdown. svn path=/trunk/; revision=61041
This commit is contained in:
parent
d9d963a62f
commit
c5b45ab5bc
|
@ -240,7 +240,7 @@ typedef struct _POWER_CHANNEL_SUMMARY
|
|||
ULONG D0Count;
|
||||
LIST_ENTRY NotifyList;
|
||||
} POWER_CHANNEL_SUMMARY, *PPOWER_CHANNEL_SUMMARY;
|
||||
|
||||
|
||||
typedef struct _DEVICE_OBJECT_POWER_EXTENSION
|
||||
{
|
||||
ULONG IdleCount;
|
||||
|
@ -255,6 +255,12 @@ typedef struct _DEVICE_OBJECT_POWER_EXTENSION
|
|||
LIST_ENTRY Volume;
|
||||
} DEVICE_OBJECT_POWER_EXTENSION, *PDEVICE_OBJECT_POWER_EXTENSION;
|
||||
|
||||
typedef struct _POP_SHUTDOWN_WAIT_ENTRY
|
||||
{
|
||||
struct _POP_SHUTDOWN_WAIT_ENTRY *NextEntry;
|
||||
PETHREAD Thread;
|
||||
} POP_SHUTDOWN_WAIT_ENTRY, *PPOP_SHUTDOWN_WAIT_ENTRY;
|
||||
|
||||
//
|
||||
// Initialization routines
|
||||
//
|
||||
|
@ -270,6 +276,12 @@ PoInitializePrcb(
|
|||
IN PKPRCB Prcb
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PopInitShutdownList(
|
||||
VOID
|
||||
);
|
||||
|
||||
//
|
||||
// I/O Routines
|
||||
//
|
||||
|
|
|
@ -18,16 +18,137 @@
|
|||
/* GLOBALS *******************************************************************/
|
||||
|
||||
ULONG PopShutdownPowerOffPolicy;
|
||||
KEVENT PopShutdownEvent;
|
||||
PPOP_SHUTDOWN_WAIT_ENTRY PopShutdownThreadList;
|
||||
LIST_ENTRY PopShutdownQueue;
|
||||
KGUARDED_MUTEX PopShutdownListMutex;
|
||||
BOOLEAN PopShutdownListAvailable;
|
||||
|
||||
|
||||
/* PRIVATE FUNCTIONS *********************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PopInitShutdownList(VOID)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
/* Initialize the global shutdown event */
|
||||
KeInitializeEvent(&PopShutdownEvent, NotificationEvent, FALSE);
|
||||
|
||||
/* Initialize the shutdown lists */
|
||||
PopShutdownThreadList = NULL;
|
||||
InitializeListHead(&PopShutdownQueue);
|
||||
|
||||
/* Initialize the shutdown list lock */
|
||||
KeInitializeGuardedMutex(&PopShutdownListMutex);
|
||||
|
||||
/* The list is available now */
|
||||
PopShutdownListAvailable = TRUE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PoRequestShutdownWait(
|
||||
_In_ PETHREAD Thread)
|
||||
{
|
||||
PPOP_SHUTDOWN_WAIT_ENTRY ShutDownWaitEntry;
|
||||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Allocate a new shutdown wait entry */
|
||||
ShutDownWaitEntry = ExAllocatePoolWithTag(PagedPool, 8u, 'LSoP');
|
||||
if (ShutDownWaitEntry == NULL)
|
||||
{
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* Reference the thread and save it in the wait entry */
|
||||
ObReferenceObject(Thread);
|
||||
ShutDownWaitEntry->Thread = Thread;
|
||||
|
||||
/* Acquire the shutdown list lock */
|
||||
KeAcquireGuardedMutex(&PopShutdownListMutex);
|
||||
|
||||
/* Check if the list is still available */
|
||||
if (PopShutdownListAvailable)
|
||||
{
|
||||
/* Insert the item in the list */
|
||||
ShutDownWaitEntry->NextEntry = PopShutdownThreadList;
|
||||
PopShutdownThreadList = ShutDownWaitEntry;
|
||||
|
||||
/* We are successful */
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We cannot proceed, cleanup and return failure */
|
||||
ObDereferenceObject(Thread);
|
||||
ExFreePoolWithTag(ShutDownWaitEntry, 0);
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* Release the list lock */
|
||||
KeReleaseGuardedMutex(&PopShutdownListMutex);
|
||||
|
||||
/* Return the status */
|
||||
return Status;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PopProcessShutDownLists(VOID)
|
||||
{
|
||||
PPOP_SHUTDOWN_WAIT_ENTRY ShutDownWaitEntry;
|
||||
PWORK_QUEUE_ITEM WorkItem;
|
||||
PLIST_ENTRY ListEntry;
|
||||
|
||||
/* First signal the shutdown event */
|
||||
KeSetEvent(&PopShutdownEvent, IO_NO_INCREMENT, FALSE);
|
||||
|
||||
/* Acquire the shutdown list lock */
|
||||
KeAcquireGuardedMutex(&PopShutdownListMutex);
|
||||
|
||||
/* Block any further attempts to register a shutdown event */
|
||||
PopShutdownListAvailable = FALSE;
|
||||
|
||||
/* Release the list lock, since we are exclusively using the lists now */
|
||||
KeReleaseGuardedMutex(&PopShutdownListMutex);
|
||||
|
||||
/* Process the shutdown queue */
|
||||
while (!IsListEmpty(&PopShutdownQueue))
|
||||
{
|
||||
/* Get the head entry */
|
||||
ListEntry = RemoveHeadList(&PopShutdownQueue);
|
||||
WorkItem = CONTAINING_RECORD(ListEntry, WORK_QUEUE_ITEM, List);
|
||||
|
||||
/* Call the shutdown worker routine */
|
||||
WorkItem->WorkerRoutine(WorkItem->Parameter);
|
||||
}
|
||||
|
||||
/* Now process the shutdown thread list */
|
||||
while (PopShutdownThreadList != NULL)
|
||||
{
|
||||
/* Get the top entry and remove it from the list */
|
||||
ShutDownWaitEntry = PopShutdownThreadList;
|
||||
PopShutdownThreadList = PopShutdownThreadList->NextEntry;
|
||||
|
||||
/* Wait for the thread to finish and dereference it */
|
||||
KeWaitForSingleObject(ShutDownWaitEntry->Thread, 0, 0, 0, 0);
|
||||
ObfDereferenceObject(ShutDownWaitEntry->Thread);
|
||||
|
||||
/* Finally free the entry */
|
||||
ExFreePoolWithTag(ShutDownWaitEntry, 0);
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PopShutdownHandler(VOID)
|
||||
{
|
||||
PUCHAR Logo1, Logo2;
|
||||
ULONG i;
|
||||
|
||||
|
||||
/* Stop all interrupts */
|
||||
KeRaiseIrqlToDpcLevel();
|
||||
_disable();
|
||||
|
@ -72,7 +193,7 @@ PopShutdownSystem(IN POWER_ACTION SystemAction)
|
|||
/* Unload symbols */
|
||||
DPRINT1("It's the final countdown...%lx\n", SystemAction);
|
||||
DbgUnLoadImageSymbols(NULL, (PVOID)-1, 0);
|
||||
|
||||
|
||||
/* Run the thread on the boot processor */
|
||||
KeSetSystemAffinityThread(1);
|
||||
|
||||
|
@ -101,7 +222,7 @@ PopShutdownSystem(IN POWER_ACTION SystemAction)
|
|||
|
||||
/* Call shutdown handler */
|
||||
//PopInvokeSystemStateHandler(PowerStateShutdownOff, NULL);
|
||||
|
||||
|
||||
/* ReactOS Hack */
|
||||
PopSetSystemPowerState(PowerSystemShutdown, SystemAction);
|
||||
PopShutdownHandler();
|
||||
|
@ -124,6 +245,9 @@ PopGracefulShutdown(IN PVOID Context)
|
|||
{
|
||||
PEPROCESS Process = NULL;
|
||||
|
||||
/* Process the registered waits and work items */
|
||||
PopProcessShutDownLists();
|
||||
|
||||
/* Loop every process */
|
||||
Process = PsGetNextProcess(Process);
|
||||
while (Process)
|
||||
|
@ -144,13 +268,13 @@ PopGracefulShutdown(IN PVOID Context)
|
|||
HalEndOfBoot();
|
||||
|
||||
/* In this step, the I/O manager does first-chance shutdown notification */
|
||||
DPRINT1("I/O manager shutting down in phase 0\n");
|
||||
DPRINT1("I/O manager shutting down in phase 0\n");
|
||||
IoShutdownSystem(0);
|
||||
|
||||
|
||||
/* In this step, all workers are killed and hives are flushed */
|
||||
DPRINT1("Configuration Manager shutting down\n");
|
||||
CmShutdownSystem();
|
||||
|
||||
|
||||
/* Note that modified pages should be written here (MiShutdownSystem) */
|
||||
#ifdef NEWCC
|
||||
/* Flush all user files before we start shutting down IO */
|
||||
|
@ -159,7 +283,7 @@ PopGracefulShutdown(IN PVOID Context)
|
|||
#endif
|
||||
|
||||
/* In this step, the I/O manager does last-chance shutdown notification */
|
||||
DPRINT1("I/O manager shutting down in phase 1\n");
|
||||
DPRINT1("I/O manager shutting down in phase 1\n");
|
||||
IoShutdownSystem(1);
|
||||
CcWaitForCurrentLazyWriterActivity();
|
||||
|
||||
|
@ -168,7 +292,7 @@ PopGracefulShutdown(IN PVOID Context)
|
|||
/* In this step, the HAL disables any wake timers */
|
||||
DPRINT1("Disabling wake timers\n");
|
||||
HalSetWakeEnable(FALSE);
|
||||
|
||||
|
||||
/* And finally the power request is sent */
|
||||
DPRINT1("Taking the system down\n");
|
||||
PopShutdownSystem(PopAction.Action);
|
||||
|
@ -185,7 +309,7 @@ PopReadShutdownPolicy(VOID)
|
|||
ULONG Length;
|
||||
UCHAR Buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)];
|
||||
PKEY_VALUE_PARTIAL_INFORMATION Info = (PVOID)Buffer;
|
||||
|
||||
|
||||
/* Setup object attributes */
|
||||
RtlInitUnicodeString(&KeyString,
|
||||
L"\\Registry\\Machine\\Software\\Policies\\Microsoft\\Windows NT");
|
||||
|
@ -220,3 +344,60 @@ PopReadShutdownPolicy(VOID)
|
|||
|
||||
/* PUBLIC FUNCTIONS **********************************************************/
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PoQueueShutdownWorkItem(
|
||||
_In_ PWORK_QUEUE_ITEM WorkItem)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Acquire the shutdown list lock */
|
||||
KeAcquireGuardedMutex(&PopShutdownListMutex);
|
||||
|
||||
/* Check if the list is (already/still) available */
|
||||
if (PopShutdownListAvailable)
|
||||
{
|
||||
/* Insert the item into the list */
|
||||
InsertTailList(&PopShutdownQueue, &WorkItem->List);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We are already in shutdown */
|
||||
Status = STATUS_SYSTEM_SHUTDOWN;
|
||||
}
|
||||
|
||||
/* Release the list lock */
|
||||
KeReleaseGuardedMutex(&PopShutdownListMutex);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PoRequestShutdownEvent(OUT PVOID *Event)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Initialize to NULL */
|
||||
if (Event) *Event = NULL;
|
||||
|
||||
/* Request a shutdown wait */
|
||||
Status = PoRequestShutdownWait(PsGetCurrentThread());
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Return the global shutdown event */
|
||||
if (Event) *Event = &PopShutdownEvent;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -344,6 +344,10 @@ PoInitSystem(IN ULONG BootPhase)
|
|||
|
||||
/* Initialize support for dope */
|
||||
KeInitializeSpinLock(&PopDopeGlobalLock);
|
||||
|
||||
/* Initialize support for shutdown waits and work-items */
|
||||
PopInitShutdownList();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -445,17 +449,6 @@ PoShutdownBugCheck(IN BOOLEAN LogError,
|
|||
BugCheckParameter4);
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PoRequestShutdownEvent(OUT PVOID *Event)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
|
@ -637,19 +630,6 @@ PoUnregisterSystemState(IN PVOID StateHandle)
|
|||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PoQueueShutdownWorkItem(IN PWORK_QUEUE_ITEM WorkItem)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue