3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/shutdown.c
6 * PURPOSE: Implements shutdown notification
7 * PROGRAMMER: David Welch (welch@mcmail.com)
12 /* INCLUDES *****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <internal/pool.h>
18 #include <internal/debug.h>
20 /* LOCAL DATA ***************************************************************/
22 typedef struct _SHUTDOWN_ENTRY
24 LIST_ENTRY ShutdownList;
25 PDEVICE_OBJECT DeviceObject;
26 } SHUTDOWN_ENTRY, *PSHUTDOWN_ENTRY;
28 static LIST_ENTRY ShutdownListHead;
29 static KSPIN_LOCK ShutdownListLock;
31 #define TAG_SHUTDOWN_ENTRY TAG('S', 'H', 'U', 'T')
33 /* FUNCTIONS *****************************************************************/
35 VOID IoInitShutdownNotification (VOID)
37 InitializeListHead(&ShutdownListHead);
38 KeInitializeSpinLock(&ShutdownListLock);
41 VOID IoShutdownRegisteredDevices(VOID)
43 PSHUTDOWN_ENTRY ShutdownEntry;
45 IO_STATUS_BLOCK StatusBlock;
50 Entry = ShutdownListHead.Flink;
51 while (Entry != &ShutdownListHead)
53 ShutdownEntry = CONTAINING_RECORD(Entry, SHUTDOWN_ENTRY, ShutdownList);
55 KeInitializeEvent (&Event,
59 Irp = IoBuildSynchronousFsdRequest (IRP_MJ_SHUTDOWN,
60 ShutdownEntry->DeviceObject,
67 Status = IoCallDriver (ShutdownEntry->DeviceObject,
69 if (Status == STATUS_PENDING)
71 KeWaitForSingleObject (&Event,
85 NTSTATUS STDCALL IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
87 PSHUTDOWN_ENTRY Entry;
89 Entry = ExAllocatePoolWithTag(NonPagedPool, sizeof(SHUTDOWN_ENTRY),
92 return STATUS_INSUFFICIENT_RESOURCES;
94 Entry->DeviceObject = DeviceObject;
96 ExInterlockedInsertHeadList(&ShutdownListHead,
100 DeviceObject->Flags |= DO_SHUTDOWN_REGISTERED;
102 return STATUS_SUCCESS;
108 VOID STDCALL IoUnregisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
110 PSHUTDOWN_ENTRY ShutdownEntry;
114 Entry = ShutdownListHead.Flink;
115 while (Entry != &ShutdownListHead)
117 ShutdownEntry = CONTAINING_RECORD(Entry, SHUTDOWN_ENTRY, ShutdownList);
118 if (ShutdownEntry->DeviceObject == DeviceObject)
120 DeviceObject->Flags &= ~DO_SHUTDOWN_REGISTERED;
122 KeAcquireSpinLock(&ShutdownListLock,&oldlvl);
123 RemoveEntryList(Entry);
124 KeReleaseSpinLock(&ShutdownListLock,oldlvl);
130 Entry = Entry->Flink;