Author: ion
Date: Mon Apr 9 17:00:38 2007
New Revision: 26294
URL:
http://svn.reactos.org/svn/reactos?rev=26294&view=rev
Log:
- Call IRP_MN_START_DEVICE in a critical region, since NT drivers depend on this
implementation detail (on NT, an ERESOURCE+CriticalRegion is always held when parsing a
new device node, so all related IRP_MNs are actually received under a critical region. For
now, I only made IRP_MN_START_DEVICE behave as such. i8042prt from the DDK depends on this
behavior.
- Cleaned up Fast Mutex Implementation.
- Disabled a hard-coded bugcheck and instead disabled soem code.
Modified:
trunk/reactos/ntoskrnl/ex/fmutex.c
trunk/reactos/ntoskrnl/io/iomgr/error.c
trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
Modified: trunk/reactos/ntoskrnl/ex/fmutex.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/fmutex.c?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/ex/fmutex.c (original)
+++ trunk/reactos/ntoskrnl/ex/fmutex.c Mon Apr 9 17:00:38 2007
@@ -9,37 +9,32 @@
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
-#include <internal/debug.h>
-
-VOID
-FASTCALL
-KiAcquireFastMutex(IN PFAST_MUTEX FastMutex);
-
-/* FUNCTIONS *****************************************************************/
-
-/*
- * @implemented
- */
-VOID
-FASTCALL
-ExEnterCriticalRegionAndAcquireFastMutexUnsafe(PFAST_MUTEX FastMutex)
+#define NDEBUG
+#include <debug.h>
+
+VOID
+FASTCALL
+KiAcquireFastMutex(
+ IN PFAST_MUTEX FastMutex
+);
+
+/* PRIVATE FUNCTIONS *********************************************************/
+
+VOID
+FORCEINLINE
+ExiAcquireFastMutexUnsafe(IN PFAST_MUTEX FastMutex)
{
PKTHREAD Thread = KeGetCurrentThread();
- /* Enter the Critical Region */
- KeEnterCriticalRegion();
-
+ DPRINT("Sanity print: %d %d %p\n",
+ KeGetCurrentIrql(), Thread->CombinedApcDisable, Thread->Teb);
+
+ /* Sanity check */
ASSERT((KeGetCurrentIrql() == APC_LEVEL) ||
- (Thread == NULL) ||
(Thread->CombinedApcDisable != 0) ||
(Thread->Teb == NULL) ||
(Thread->Teb >= (PTEB)MM_SYSTEM_RANGE_START));
-
- ASSERT((KeGetCurrentIrql() == APC_LEVEL) ||
- (Thread == NULL) ||
- (Thread->CombinedApcDisable != 0));
-
- ASSERT((Thread == NULL) || (FastMutex->Owner != Thread));
+ ASSERT(FastMutex->Owner != Thread);
/* Decrease the count */
if (InterlockedDecrement(&FastMutex->Count))
@@ -52,130 +47,16 @@
FastMutex->Owner = Thread;
}
-/*
- * @implemented
- */
-VOID
-FASTCALL
-ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(PFAST_MUTEX FastMutex)
-{
-
+VOID
+FORCEINLINE
+ExiReleaseFastMutexUnsafe(IN OUT PFAST_MUTEX FastMutex)
+{
ASSERT((KeGetCurrentIrql() == APC_LEVEL) ||
- (KeGetCurrentThread() == NULL) ||
- (KeGetCurrentThread()->CombinedApcDisable != 0) ||
- (KeGetCurrentThread()->Teb == NULL) ||
- (KeGetCurrentThread()->Teb >= (PTEB)MM_SYSTEM_RANGE_START));
-
-
- ASSERT((KeGetCurrentIrql() == APC_LEVEL) ||
- (KeGetCurrentThread() == NULL) ||
- (KeGetCurrentThread()->CombinedApcDisable != 0));
- ASSERT(FastMutex->Owner == KeGetCurrentThread());
-
- /* Erase the owner */
- FastMutex->Owner = NULL;
-
- /* Increase the count */
- if (InterlockedIncrement(&FastMutex->Count) <= 0)
- {
- /* Someone was waiting for it, signal the waiter */
- KeSetEventBoostPriority(&FastMutex->Gate, IO_NO_INCREMENT);
- }
-
- /* Leave the critical region */
- KeLeaveCriticalRegion();
-}
-
-/*
- * @implemented
- */
-VOID
-FASTCALL
-ExAcquireFastMutex(PFAST_MUTEX FastMutex)
-{
- KIRQL OldIrql;
- ASSERT_IRQL_LESS_OR_EQUAL(APC_LEVEL);
-
- /* Raise IRQL to APC */
- OldIrql = KfRaiseIrql(APC_LEVEL);
-
- /* Decrease the count */
- if (InterlockedDecrement(&FastMutex->Count))
- {
- /* Someone is still holding it, use slow path */
- KiAcquireFastMutex(FastMutex);
- }
-
- /* Set the owner and IRQL */
- FastMutex->Owner = KeGetCurrentThread();
- FastMutex->OldIrql = OldIrql;
-}
-
-/*
- * @implemented
- */
-VOID
-FASTCALL
-ExReleaseFastMutex (PFAST_MUTEX FastMutex)
-{
- KIRQL OldIrql;
- ASSERT_IRQL(APC_LEVEL);
-
- /* Erase the owner */
- FastMutex->Owner = NULL;
- OldIrql = FastMutex->OldIrql;
-
- /* Increase the count */
- if (InterlockedIncrement(&FastMutex->Count) <= 0)
- {
- /* Someone was waiting for it, signal the waiter */
- KeSetEventBoostPriority(&FastMutex->Gate, IO_NO_INCREMENT);
- }
-
- /* Lower IRQL back */
- KfLowerIrql(OldIrql);
-}
-
-/*
- * @implemented
- */
-VOID
-FASTCALL
-ExAcquireFastMutexUnsafe(PFAST_MUTEX FastMutex)
-{
- PKTHREAD Thread = KeGetCurrentThread();
- ASSERT((KeGetCurrentIrql() == APC_LEVEL) ||
- (Thread == NULL) ||
- (Thread->CombinedApcDisable != 0) ||
- (Thread->Teb == NULL) ||
- (Thread->Teb >= (PTEB)MM_SYSTEM_RANGE_START));
- ASSERT((Thread == NULL) || (FastMutex->Owner != Thread));
-
- /* Decrease the count */
- if (InterlockedDecrement(&FastMutex->Count))
- {
- /* Someone is still holding it, use slow path */
- KiAcquireFastMutex(FastMutex);
- }
-
- /* Set the owner */
- FastMutex->Owner = Thread;
-}
-
-/*
- * @implemented
- */
-VOID
-FASTCALL
-ExReleaseFastMutexUnsafe(PFAST_MUTEX FastMutex)
-{
- ASSERT((KeGetCurrentIrql() == APC_LEVEL) ||
- (KeGetCurrentThread() == NULL) ||
(KeGetCurrentThread()->CombinedApcDisable != 0) ||
(KeGetCurrentThread()->Teb == NULL) ||
(KeGetCurrentThread()->Teb >= (PTEB)MM_SYSTEM_RANGE_START));
ASSERT(FastMutex->Owner == KeGetCurrentThread());
-
+
/* Erase the owner */
FastMutex->Owner = NULL;
@@ -183,8 +64,110 @@
if (InterlockedIncrement(&FastMutex->Count) <= 0)
{
/* Someone was waiting for it, signal the waiter */
+ KeSetEventBoostPriority(&FastMutex->Gate, NULL);
+ }
+}
+
+/* PUBLIC FUNCTIONS **********************************************************/
+
+/*
+ * @implemented
+ */
+VOID
+FASTCALL
+ExEnterCriticalRegionAndAcquireFastMutexUnsafe(IN OUT PFAST_MUTEX FastMutex)
+{
+ /* Enter the Critical Region */
+ KeEnterCriticalRegion();
+
+ /* Acquire the mutex unsafely */
+ ExiAcquireFastMutexUnsafe(FastMutex);
+}
+
+/*
+ * @implemented
+ */
+VOID
+FASTCALL
+ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(IN OUT PFAST_MUTEX FastMutex)
+{
+ /* Release the mutex unsafely */
+ ExiReleaseFastMutexUnsafe(FastMutex);
+
+ /* Leave the critical region */
+ KeLeaveCriticalRegion();
+}
+
+/*
+ * @implemented
+ */
+VOID
+FASTCALL
+ExAcquireFastMutex(IN OUT PFAST_MUTEX FastMutex)
+{
+ KIRQL OldIrql;
+ ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
+
+ /* Raise IRQL to APC */
+ OldIrql = KfRaiseIrql(APC_LEVEL);
+
+ /* Decrease the count */
+ if (InterlockedDecrement(&FastMutex->Count) != 0)
+ {
+ /* Someone is still holding it, use slow path */
+ KiAcquireFastMutex(FastMutex);
+ }
+
+ /* Set the owner and IRQL */
+ FastMutex->Owner = KeGetCurrentThread();
+ FastMutex->OldIrql = OldIrql;
+}
+
+/*
+ * @implemented
+ */
+VOID
+FASTCALL
+ExReleaseFastMutex(IN OUT PFAST_MUTEX FastMutex)
+{
+ KIRQL OldIrql;
+ ASSERT_IRQL(APC_LEVEL);
+
+ /* Erase the owner */
+ FastMutex->Owner = NULL;
+ OldIrql = FastMutex->OldIrql;
+
+ /* Increase the count */
+ if (InterlockedIncrement(&FastMutex->Count) <= 0)
+ {
+ /* Someone was waiting for it, signal the waiter */
KeSetEventBoostPriority(&FastMutex->Gate, IO_NO_INCREMENT);
}
+
+ /* Lower IRQL back */
+ KfLowerIrql(OldIrql);
+}
+
+/*
+ * @implemented
+ */
+VOID
+FASTCALL
+ExAcquireFastMutexUnsafe(IN OUT PFAST_MUTEX FastMutex)
+{
+ /* Acquire the mutex unsafely */
+ ExiAcquireFastMutexUnsafe(FastMutex);
+}
+
+/*
+ * @implemented
+ */
+VOID
+FASTCALL
+ExReleaseFastMutexUnsafe(IN OUT PFAST_MUTEX FastMutex)
+{
+ /* Release the mutex unsafely */
+ ExiReleaseFastMutexUnsafe(FastMutex);
}
/*
@@ -192,10 +175,10 @@
*/
BOOLEAN
FASTCALL
-ExTryToAcquireFastMutex(PFAST_MUTEX FastMutex)
+ExTryToAcquireFastMutex(IN OUT PFAST_MUTEX FastMutex)
{
KIRQL OldIrql;
- ASSERT_IRQL_LESS_OR_EQUAL(APC_LEVEL);
+ ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
/* Raise to APC_LEVEL */
OldIrql = KfRaiseIrql(APC_LEVEL);
Modified: trunk/reactos/ntoskrnl/io/iomgr/error.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/error.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/error.c (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/error.c Mon Apr 9 17:00:38 2007
@@ -572,7 +572,6 @@
KIRQL Irql;
/* Get the main header */
- KEBUGCHECK(0);
LogEntry = (PERROR_LOG_ENTRY)((ULONG_PTR)ElEntry -
sizeof(ERROR_LOG_ENTRY));
@@ -586,12 +585,14 @@
/* Check if the worker is runnign */
if (!IopLogWorkerRunning)
{
+#if 0
/* It's not, initialize it and queue it */
ExInitializeWorkItem(&IopErrorLogWorkItem,
IopLogWorker,
&IopErrorLogWorkItem);
ExQueueWorkItem(&IopErrorLogWorkItem, DelayedWorkQueue);
IopLogWorkerRunning = TRUE;
+#endif
}
/* Release the lock and return */
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c Mon Apr 9 17:00:38 2007
@@ -141,11 +141,20 @@
Stack.Parameters.StartDevice.AllocatedResources = DeviceNode->ResourceList;
Stack.Parameters.StartDevice.AllocatedResourcesTranslated =
DeviceNode->ResourceListTranslated;
+ /*
+ * Windows NT Drivers receive IRP_MN_START_DEVICE in a critical region and
+ * actually _depend_ on this!. This is because NT will lock the Device Node
+ * with an ERESOURCE, which of course requires APCs to be disabled.
+ */
+ KeEnterCriticalRegion();
+
Status = IopInitiatePnpIrp(
Fdo,
&IoStatusBlock,
IRP_MN_START_DEVICE,
&Stack);
+
+ KeLeaveCriticalRegion();
if (!NT_SUCCESS(Status))
{