1 /* $Id: shutdown.c,v 1.6 2002/09/07 15:12:53 chorns Exp $
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 *****************************************************************/
17 #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
;