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);
43 VOID IoShutdownRegisteredDevices(VOID)
45 PSHUTDOWN_ENTRY ShutdownEntry;
47 IO_STATUS_BLOCK StatusBlock;
52 Entry = ShutdownListHead.Flink;
53 while (Entry != &ShutdownListHead)
55 ShutdownEntry = CONTAINING_RECORD(Entry, SHUTDOWN_ENTRY, ShutdownList);
57 KeInitializeEvent (&Event,
61 Irp = IoBuildSynchronousFsdRequest (IRP_MJ_SHUTDOWN,
62 ShutdownEntry->DeviceObject,
69 Status = IoCallDriver (ShutdownEntry->DeviceObject,
71 if (Status == STATUS_PENDING)
73 KeWaitForSingleObject (&Event,
84 #endif /* LIBCAPTIVE */
86 NTSTATUS STDCALL IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
88 PSHUTDOWN_ENTRY Entry;
90 Entry = ExAllocatePoolWithTag(NonPagedPool, sizeof(SHUTDOWN_ENTRY),
93 return STATUS_INSUFFICIENT_RESOURCES;
95 Entry->DeviceObject = DeviceObject;
97 ExInterlockedInsertHeadList(&ShutdownListHead,
101 DeviceObject->Flags |= DO_SHUTDOWN_REGISTERED;
103 return STATUS_SUCCESS;
106 VOID STDCALL IoUnregisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
108 PSHUTDOWN_ENTRY ShutdownEntry;
112 Entry = ShutdownListHead.Flink;
113 while (Entry != &ShutdownListHead)
115 ShutdownEntry = CONTAINING_RECORD(Entry, SHUTDOWN_ENTRY, ShutdownList);
116 if (ShutdownEntry->DeviceObject == DeviceObject)
118 DeviceObject->Flags &= ~DO_SHUTDOWN_REGISTERED;
120 KeAcquireSpinLock(&ShutdownListLock,&oldlvl);
121 RemoveEntryList(Entry);
122 KeReleaseSpinLock(&ShutdownListLock,oldlvl);
128 Entry = Entry->Flink;