[NTOSKRNL]

Implement PoQueueShutdownWorkItem, PoRequestShutdownEvent, PoRequestShutdownWait, PopProcessShutDownLists. One step closer to ... proper shutdown.

svn path=/trunk/; revision=61041
This commit is contained in:
Timo Kreuzer 2013-11-18 17:47:37 +00:00
parent d9d963a62f
commit c5b45ab5bc
3 changed files with 207 additions and 34 deletions

View file

@ -240,7 +240,7 @@ typedef struct _POWER_CHANNEL_SUMMARY
ULONG D0Count; ULONG D0Count;
LIST_ENTRY NotifyList; LIST_ENTRY NotifyList;
} POWER_CHANNEL_SUMMARY, *PPOWER_CHANNEL_SUMMARY; } POWER_CHANNEL_SUMMARY, *PPOWER_CHANNEL_SUMMARY;
typedef struct _DEVICE_OBJECT_POWER_EXTENSION typedef struct _DEVICE_OBJECT_POWER_EXTENSION
{ {
ULONG IdleCount; ULONG IdleCount;
@ -255,6 +255,12 @@ typedef struct _DEVICE_OBJECT_POWER_EXTENSION
LIST_ENTRY Volume; LIST_ENTRY Volume;
} DEVICE_OBJECT_POWER_EXTENSION, *PDEVICE_OBJECT_POWER_EXTENSION; } 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 // Initialization routines
// //
@ -270,6 +276,12 @@ PoInitializePrcb(
IN PKPRCB Prcb IN PKPRCB Prcb
); );
VOID
NTAPI
PopInitShutdownList(
VOID
);
// //
// I/O Routines // I/O Routines
// //

View file

@ -18,16 +18,137 @@
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/
ULONG PopShutdownPowerOffPolicy; ULONG PopShutdownPowerOffPolicy;
KEVENT PopShutdownEvent;
PPOP_SHUTDOWN_WAIT_ENTRY PopShutdownThreadList;
LIST_ENTRY PopShutdownQueue;
KGUARDED_MUTEX PopShutdownListMutex;
BOOLEAN PopShutdownListAvailable;
/* PRIVATE FUNCTIONS *********************************************************/ /* 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 VOID
NTAPI NTAPI
PopShutdownHandler(VOID) PopShutdownHandler(VOID)
{ {
PUCHAR Logo1, Logo2; PUCHAR Logo1, Logo2;
ULONG i; ULONG i;
/* Stop all interrupts */ /* Stop all interrupts */
KeRaiseIrqlToDpcLevel(); KeRaiseIrqlToDpcLevel();
_disable(); _disable();
@ -72,7 +193,7 @@ PopShutdownSystem(IN POWER_ACTION SystemAction)
/* Unload symbols */ /* Unload symbols */
DPRINT1("It's the final countdown...%lx\n", SystemAction); DPRINT1("It's the final countdown...%lx\n", SystemAction);
DbgUnLoadImageSymbols(NULL, (PVOID)-1, 0); DbgUnLoadImageSymbols(NULL, (PVOID)-1, 0);
/* Run the thread on the boot processor */ /* Run the thread on the boot processor */
KeSetSystemAffinityThread(1); KeSetSystemAffinityThread(1);
@ -101,7 +222,7 @@ PopShutdownSystem(IN POWER_ACTION SystemAction)
/* Call shutdown handler */ /* Call shutdown handler */
//PopInvokeSystemStateHandler(PowerStateShutdownOff, NULL); //PopInvokeSystemStateHandler(PowerStateShutdownOff, NULL);
/* ReactOS Hack */ /* ReactOS Hack */
PopSetSystemPowerState(PowerSystemShutdown, SystemAction); PopSetSystemPowerState(PowerSystemShutdown, SystemAction);
PopShutdownHandler(); PopShutdownHandler();
@ -124,6 +245,9 @@ PopGracefulShutdown(IN PVOID Context)
{ {
PEPROCESS Process = NULL; PEPROCESS Process = NULL;
/* Process the registered waits and work items */
PopProcessShutDownLists();
/* Loop every process */ /* Loop every process */
Process = PsGetNextProcess(Process); Process = PsGetNextProcess(Process);
while (Process) while (Process)
@ -144,13 +268,13 @@ PopGracefulShutdown(IN PVOID Context)
HalEndOfBoot(); HalEndOfBoot();
/* In this step, the I/O manager does first-chance shutdown notification */ /* 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); IoShutdownSystem(0);
/* In this step, all workers are killed and hives are flushed */ /* In this step, all workers are killed and hives are flushed */
DPRINT1("Configuration Manager shutting down\n"); DPRINT1("Configuration Manager shutting down\n");
CmShutdownSystem(); CmShutdownSystem();
/* Note that modified pages should be written here (MiShutdownSystem) */ /* Note that modified pages should be written here (MiShutdownSystem) */
#ifdef NEWCC #ifdef NEWCC
/* Flush all user files before we start shutting down IO */ /* Flush all user files before we start shutting down IO */
@ -159,7 +283,7 @@ PopGracefulShutdown(IN PVOID Context)
#endif #endif
/* In this step, the I/O manager does last-chance shutdown notification */ /* 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); IoShutdownSystem(1);
CcWaitForCurrentLazyWriterActivity(); CcWaitForCurrentLazyWriterActivity();
@ -168,7 +292,7 @@ PopGracefulShutdown(IN PVOID Context)
/* In this step, the HAL disables any wake timers */ /* In this step, the HAL disables any wake timers */
DPRINT1("Disabling wake timers\n"); DPRINT1("Disabling wake timers\n");
HalSetWakeEnable(FALSE); HalSetWakeEnable(FALSE);
/* And finally the power request is sent */ /* And finally the power request is sent */
DPRINT1("Taking the system down\n"); DPRINT1("Taking the system down\n");
PopShutdownSystem(PopAction.Action); PopShutdownSystem(PopAction.Action);
@ -185,7 +309,7 @@ PopReadShutdownPolicy(VOID)
ULONG Length; ULONG Length;
UCHAR Buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)]; UCHAR Buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)];
PKEY_VALUE_PARTIAL_INFORMATION Info = (PVOID)Buffer; PKEY_VALUE_PARTIAL_INFORMATION Info = (PVOID)Buffer;
/* Setup object attributes */ /* Setup object attributes */
RtlInitUnicodeString(&KeyString, RtlInitUnicodeString(&KeyString,
L"\\Registry\\Machine\\Software\\Policies\\Microsoft\\Windows NT"); L"\\Registry\\Machine\\Software\\Policies\\Microsoft\\Windows NT");
@ -220,3 +344,60 @@ PopReadShutdownPolicy(VOID)
/* PUBLIC FUNCTIONS **********************************************************/ /* 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;
}

View file

@ -344,6 +344,10 @@ PoInitSystem(IN ULONG BootPhase)
/* Initialize support for dope */ /* Initialize support for dope */
KeInitializeSpinLock(&PopDopeGlobalLock); KeInitializeSpinLock(&PopDopeGlobalLock);
/* Initialize support for shutdown waits and work-items */
PopInitShutdownList();
return TRUE; return TRUE;
} }
@ -445,17 +449,6 @@ PoShutdownBugCheck(IN BOOLEAN LogError,
BugCheckParameter4); BugCheckParameter4);
} }
/*
* @unimplemented
*/
NTSTATUS
NTAPI
PoRequestShutdownEvent(OUT PVOID *Event)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/* /*
* @unimplemented * @unimplemented
*/ */
@ -637,19 +630,6 @@ PoUnregisterSystemState(IN PVOID StateHandle)
UNIMPLEMENTED; UNIMPLEMENTED;
} }
/*
* @unimplemented
*/
NTSTATUS
NTAPI
PoQueueShutdownWorkItem(IN PWORK_QUEUE_ITEM WorkItem)
{
PAGED_CODE();
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/* /*
* @unimplemented * @unimplemented
*/ */