Author: ion
Date: Sat Jul 1 22:26:22 2006
New Revision: 22743
URL:
http://svn.reactos.org/svn/reactos?rev=22743&view=rev
Log:
- Implement IoRegisterLastchanceShutdownNotification based on
IoRegisterShutdownNotification
- Modify IoUnregisterShudownNotification to loop both lists now.
- Used the lock in IoShutdownREgisteredDevices when looping the list, and changed it to
send IRP_MJ_SHUTDOWN to the attached DO. Also fixed a memory leak where the shutdown entry
wasn't being freed, and optimized the function only to initialize the event once (And
simply clear it each time).
- Moved IoSynchronousInvalidateDeviceRelations to PnP
Modified:
trunk/reactos/ntoskrnl/include/internal/io.h
trunk/reactos/ntoskrnl/io/device.c
trunk/reactos/ntoskrnl/io/pnpmgr.c
Modified: trunk/reactos/ntoskrnl/include/internal/io.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/io.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/io.h Sat Jul 1 22:26:22 2006
@@ -594,6 +594,7 @@
);
VOID
+NTAPI
IoShutdownRegisteredDevices(
VOID
);
Modified: trunk/reactos/ntoskrnl/io/device.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/device.c?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/io/device.c (original)
+++ trunk/reactos/ntoskrnl/io/device.c Sat Jul 1 22:26:22 2006
@@ -16,52 +16,69 @@
/* GLOBALS ********************************************************************/
-static ULONG IopDeviceObjectNumber = 0;
+ULONG IopDeviceObjectNumber = 0;
typedef struct _SHUTDOWN_ENTRY
{
- LIST_ENTRY ShutdownList;
- PDEVICE_OBJECT DeviceObject;
+ LIST_ENTRY ShutdownList;
+ PDEVICE_OBJECT DeviceObject;
} SHUTDOWN_ENTRY, *PSHUTDOWN_ENTRY;
-LIST_ENTRY ShutdownListHead;
+LIST_ENTRY ShutdownListHead, LastChanceShutdownListHead;
KSPIN_LOCK ShutdownListLock;
/* PRIVATE FUNCTIONS **********************************************************/
VOID
+NTAPI
IoShutdownRegisteredDevices(VOID)
{
- PSHUTDOWN_ENTRY ShutdownEntry;
- IO_STATUS_BLOCK StatusBlock;
- PIRP Irp;
- KEVENT Event;
- NTSTATUS Status;
-
- LIST_FOR_EACH(ShutdownEntry, &ShutdownListHead, SHUTDOWN_ENTRY, ShutdownList)
- {
- KeInitializeEvent (&Event,
- NotificationEvent,
- FALSE);
-
- Irp = IoBuildSynchronousFsdRequest (IRP_MJ_SHUTDOWN,
- ShutdownEntry->DeviceObject,
- NULL,
- 0,
- NULL,
- &Event,
- &StatusBlock);
-
- Status = IoCallDriver (ShutdownEntry->DeviceObject,
- Irp);
- if (Status == STATUS_PENDING)
- {
- KeWaitForSingleObject (&Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- }
+ PLIST_ENTRY ListEntry;
+ PDEVICE_OBJECT DeviceObject;
+ PSHUTDOWN_ENTRY ShutdownEntry;
+ IO_STATUS_BLOCK StatusBlock;
+ PIRP Irp;
+ KEVENT Event;
+ NTSTATUS Status;
+
+ /* Initialize an event to wait on */
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ /* Get the first entry and start looping */
+ ListEntry = ExInterlockedRemoveHeadList(&ShutdownListHead,
+ &ShutdownListLock);
+ while (ListEntry)
+ {
+ /* Get the shutdown entry */
+ ShutdownEntry = CONTAINING_RECORD(ListEntry,
+ SHUTDOWN_ENTRY,
+ ShutdownList);
+
+ /* Get the attached device */
+ DeviceObject = IoGetAttachedDevice(ShutdownEntry->DeviceObject);
+
+ /* Build the shutdown IRP and call the driver */
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN,
+ DeviceObject,
+ NULL,
+ 0,
+ NULL,
+ &Event,
+ &StatusBlock);
+ Status = IoCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ /* Wait on the driver */
+ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+ }
+
+ /* Free the shutdown entry and reset the event */
+ ExFreePool(ShutdownEntry);
+ KeClearEvent(&Event);
+
+ /* Go to the next entry */
+ ListEntry = ExInterlockedRemoveHeadList(&ShutdownListHead,
+ &ShutdownListLock);
}
}
@@ -1097,39 +1114,123 @@
}
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS
-STDCALL
+NTAPI
IoRegisterLastChanceShutdownNotification(IN PDEVICE_OBJECT DeviceObject)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PSHUTDOWN_ENTRY Entry;
+
+ /* Allocate the shutdown entry */
+ Entry = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(SHUTDOWN_ENTRY),
+ TAG_SHUTDOWN_ENTRY);
+ if (!Entry) return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* Set the DO */
+ Entry->DeviceObject = DeviceObject;
+
+ /* Insert it into the list */
+ ExInterlockedInsertHeadList(&LastChanceShutdownListHead,
+ &Entry->ShutdownList,
+ &ShutdownListLock);
+
+ /* Set the shutdown registered flag */
+ DeviceObject->Flags |= DO_SHUTDOWN_REGISTERED;
+ return STATUS_SUCCESS;
}
/*
* @implemented
*/
NTSTATUS
-STDCALL
+NTAPI
IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
{
- PSHUTDOWN_ENTRY Entry;
-
- Entry = ExAllocatePoolWithTag(NonPagedPool, sizeof(SHUTDOWN_ENTRY),
- TAG_SHUTDOWN_ENTRY);
- if (Entry == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- Entry->DeviceObject = DeviceObject;
-
- ExInterlockedInsertHeadList(&ShutdownListHead,
- &Entry->ShutdownList,
- &ShutdownListLock);
-
- DeviceObject->Flags |= DO_SHUTDOWN_REGISTERED;
-
- return STATUS_SUCCESS;
+ PSHUTDOWN_ENTRY Entry;
+
+ /* Allocate the shutdown entry */
+ Entry = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(SHUTDOWN_ENTRY),
+ TAG_SHUTDOWN_ENTRY);
+ if (!Entry) return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* Set the DO */
+ Entry->DeviceObject = DeviceObject;
+
+ /* Insert it into the list */
+ ExInterlockedInsertHeadList(&ShutdownListHead,
+ &Entry->ShutdownList,
+ &ShutdownListLock);
+
+ /* Set the shutdown registered flag */
+ DeviceObject->Flags |= DO_SHUTDOWN_REGISTERED;
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+IoUnregisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
+{
+ PSHUTDOWN_ENTRY ShutdownEntry;
+ PLIST_ENTRY NextEntry;
+ KIRQL OldIrql;
+
+ /* Acquire the shutdown lock and loop the shutdown list */
+ KeAcquireSpinLock(&ShutdownListLock, &OldIrql);
+ NextEntry = ShutdownListHead.Flink;
+ while (NextEntry != &ShutdownListHead)
+ {
+ /* Get the entry */
+ ShutdownEntry = CONTAINING_RECORD(NextEntry,
+ SHUTDOWN_ENTRY,
+ ShutdownList);
+
+ /* Get if the DO matches */
+ if (ShutdownEntry->DeviceObject == DeviceObject)
+ {
+ /* Remove it from the list */
+ RemoveEntryList(NextEntry);
+ NextEntry = NextEntry->Blink;
+
+ /* Free the entry */
+ ExFreePool(ShutdownEntry);
+ }
+
+ /* Go to the next entry */
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* Now loop the last chance list */
+ NextEntry = LastChanceShutdownListHead.Flink;
+ while (NextEntry != &LastChanceShutdownListHead)
+ {
+ /* Get the entry */
+ ShutdownEntry = CONTAINING_RECORD(NextEntry,
+ SHUTDOWN_ENTRY,
+ ShutdownList);
+
+ /* Get if the DO matches */
+ if (ShutdownEntry->DeviceObject == DeviceObject)
+ {
+ /* Remove it from the list */
+ RemoveEntryList(NextEntry);
+ NextEntry = NextEntry->Blink;
+
+ /* Free the entry */
+ ExFreePool(ShutdownEntry);
+ }
+
+ /* Go to the next entry */
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* Now remove the flag */
+ DeviceObject->Flags &= ~DO_SHUTDOWN_REGISTERED;
}
/*
@@ -1277,46 +1378,6 @@
{
IoReleaseCancelSpinLock(oldirql);
}
-
-}
-
-/*
- * @unimplemented
- */
-VOID
-STDCALL
-IoSynchronousInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject,
- IN DEVICE_RELATION_TYPE Type)
-{
- UNIMPLEMENTED;
-}
-
-/*
- * @implemented
- */
-VOID
-STDCALL
-IoUnregisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
-{
- PSHUTDOWN_ENTRY ShutdownEntry, tmp;
- KIRQL oldlvl;
-
- LIST_FOR_EACH_SAFE(ShutdownEntry, tmp, &ShutdownListHead, SHUTDOWN_ENTRY,
ShutdownList)
- {
-
- if (ShutdownEntry->DeviceObject == DeviceObject)
- {
- DeviceObject->Flags &= ~DO_SHUTDOWN_REGISTERED;
-
- KeAcquireSpinLock(&ShutdownListLock,&oldlvl);
- RemoveEntryList(&ShutdownEntry->ShutdownList);
- KeReleaseSpinLock(&ShutdownListLock,oldlvl);
-
- ExFreePool(ShutdownEntry);
- return;
- }
-
- }
}
/* EOF */
Modified: trunk/reactos/ntoskrnl/io/pnpmgr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr.c?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr.c (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr.c Sat Jul 1 22:26:22 2006
@@ -79,6 +79,17 @@
IN DEVICE_RELATION_TYPE Type)
{
IopInvalidateDeviceRelations(IopGetDeviceNode(DeviceObject), Type);
+}
+
+/*
+ * @unimplemented
+ */
+VOID
+STDCALL
+IoSynchronousInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject,
+ IN DEVICE_RELATION_TYPE Type)
+{
+ UNIMPLEMENTED;
}
/*