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,
82 NTSTATUS STDCALL IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
84 PSHUTDOWN_ENTRY Entry;
86 Entry = ExAllocatePoolWithTag(NonPagedPool, sizeof(SHUTDOWN_ENTRY),
89 return STATUS_INSUFFICIENT_RESOURCES;
91 Entry->DeviceObject = DeviceObject;
93 ExInterlockedInsertHeadList(&ShutdownListHead,
97 DeviceObject->Flags |= DO_SHUTDOWN_REGISTERED;
99 return STATUS_SUCCESS;
102 VOID STDCALL IoUnregisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
104 PSHUTDOWN_ENTRY ShutdownEntry;
108 Entry = ShutdownListHead.Flink;
109 while (Entry != &ShutdownListHead)
111 ShutdownEntry = CONTAINING_RECORD(Entry, SHUTDOWN_ENTRY, ShutdownList);
112 if (ShutdownEntry->DeviceObject == DeviceObject)
114 DeviceObject->Flags &= ~DO_SHUTDOWN_REGISTERED;
116 KeAcquireSpinLock(&ShutdownListLock,&oldlvl);
117 RemoveEntryList(Entry);
118 KeReleaseSpinLock(&ShutdownListLock,oldlvl);
124 Entry = Entry->Flink;