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 *****************************************************************/
16 #include <internal/debug.h>
18 /* LOCAL DATA ***************************************************************/
20 typedef struct _SHUTDOWN_ENTRY
22 LIST_ENTRY ShutdownList
;
23 PDEVICE_OBJECT DeviceObject
;
24 } SHUTDOWN_ENTRY
, *PSHUTDOWN_ENTRY
;
26 static LIST_ENTRY ShutdownListHead
;
27 static KSPIN_LOCK ShutdownListLock
;
29 #define TAG_SHUTDOWN_ENTRY TAG('S', 'H', 'U', 'T')
31 /* FUNCTIONS *****************************************************************/
34 IoInitShutdownNotification (VOID
)
36 InitializeListHead(&ShutdownListHead
);
37 KeInitializeSpinLock(&ShutdownListLock
);
40 VOID
IoShutdownRegisteredDevices(VOID
)
42 PSHUTDOWN_ENTRY ShutdownEntry
;
44 IO_STATUS_BLOCK StatusBlock
;
49 Entry
= ShutdownListHead
.Flink
;
50 while (Entry
!= &ShutdownListHead
)
52 ShutdownEntry
= CONTAINING_RECORD(Entry
, SHUTDOWN_ENTRY
, ShutdownList
);
54 KeInitializeEvent (&Event
,
58 Irp
= IoBuildSynchronousFsdRequest (IRP_MJ_SHUTDOWN
,
59 ShutdownEntry
->DeviceObject
,
66 Status
= IoCallDriver (ShutdownEntry
->DeviceObject
,
68 if (Status
== STATUS_PENDING
)
70 KeWaitForSingleObject (&Event
,
84 NTSTATUS STDCALL
IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject
)
86 PSHUTDOWN_ENTRY Entry
;
88 Entry
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(SHUTDOWN_ENTRY
),
91 return STATUS_INSUFFICIENT_RESOURCES
;
93 Entry
->DeviceObject
= DeviceObject
;
95 ExInterlockedInsertHeadList(&ShutdownListHead
,
99 DeviceObject
->Flags
|= DO_SHUTDOWN_REGISTERED
;
101 return STATUS_SUCCESS
;
107 VOID STDCALL
IoUnregisterShutdownNotification(PDEVICE_OBJECT DeviceObject
)
109 PSHUTDOWN_ENTRY ShutdownEntry
;
113 Entry
= ShutdownListHead
.Flink
;
114 while (Entry
!= &ShutdownListHead
)
116 ShutdownEntry
= CONTAINING_RECORD(Entry
, SHUTDOWN_ENTRY
, ShutdownList
);
117 if (ShutdownEntry
->DeviceObject
== DeviceObject
)
119 DeviceObject
->Flags
&= ~DO_SHUTDOWN_REGISTERED
;
121 KeAcquireSpinLock(&ShutdownListLock
,&oldlvl
);
122 RemoveEntryList(Entry
);
123 KeReleaseSpinLock(&ShutdownListLock
,oldlvl
);
129 Entry
= Entry
->Flink
;