Modified: trunk/reactos/ntoskrnl/ex/list.c
Modified: trunk/reactos/ntoskrnl/include/internal/mm.h
Modified: trunk/reactos/ntoskrnl/mm/i386/memsafe.s
Modified: trunk/reactos/ntoskrnl/mm/i386/pfault.c
--- trunk/reactos/ntoskrnl/ex/list.c 2005-02-21 21:40:31 UTC (rev 13708)
+++ trunk/reactos/ntoskrnl/ex/list.c 2005-02-22 01:07:41 UTC (rev 13709)
@@ -16,8 +16,6 @@
#define NDEBUG
#include <internal/debug.h>
-static KSPIN_LOCK ExpGlobalListLock = { 0, };
-
/* FUNCTIONS *************************************************************/
/*
@@ -446,8 +444,31 @@
FASTCALL
InterlockedPopEntrySList(IN PSLIST_HEADER ListHead)
{
- return (PSLIST_ENTRY) ExInterlockedPopEntrySList(ListHead,
- &ExpGlobalListLock);
+ SLIST_HEADER newslh, oldslh;
+ PSLIST_ENTRY le;
+
+ do
+ {
+ oldslh = *ListHead;
+ le = oldslh.Next.Next;
+ if(le == NULL)
+ {
+ /* nothing to do */
+ return NULL;
+ }
+ newslh.Sequence = oldslh.Sequence + 1;
+ newslh.Depth = oldslh.Depth - 1;
+ newslh.Next.Next = MmSafeReadPtr(&le->Next);
+ if(newslh.Next.Next == NULL)
+ {
+ /* try again */
+ continue;
+ }
+ } while(ExfInterlockedCompareExchange64(&ListHead->Alignment,
+ &newslh.Alignment,
+ &oldslh.Alignment) != oldslh.Alignment);
+
+ return le;
}
@@ -457,11 +478,23 @@
PSLIST_ENTRY
FASTCALL
InterlockedPushEntrySList(IN PSLIST_HEADER ListHead,
- IN PSLIST_ENTRY ListEntry)
+ IN PSLIST_ENTRY ListEntry)
{
- return (PSLIST_ENTRY) ExInterlockedPushEntrySList(ListHead,
- ListEntry,
- &ExpGlobalListLock);
+ SLIST_HEADER newslh, oldslh;
+
+ newslh.Next.Next = ListEntry;
+
+ do
+ {
+ oldslh = *ListHead;
+ newslh.Depth = oldslh.Depth + 1;
+ newslh.Sequence = oldslh.Sequence + 1;
+ ListEntry->Next = oldslh.Next.Next;
+ } while(ExfInterlockedCompareExchange64(&ListHead->Alignment,
+ &newslh.Alignment,
+ &oldslh.Alignment) != oldslh.Alignment);
+
+ return oldslh.Next.Next;
}
/* EOF */
--- trunk/reactos/ntoskrnl/include/internal/mm.h 2005-02-21 21:40:31 UTC (rev 13708)
+++ trunk/reactos/ntoskrnl/include/internal/mm.h 2005-02-22 01:07:41 UTC (rev 13709)
@@ -563,6 +563,8 @@
NTSTATUS MmSafeCopyToUser(PVOID Dest, const VOID *Src, ULONG Count);
+PVOID FASTCALL MmSafeReadPtr(PVOID Source);
+
/* pageop.c ******************************************************************/
VOID
--- trunk/reactos/ntoskrnl/mm/i386/memsafe.s 2005-02-21 21:40:31 UTC (rev 13708)
+++ trunk/reactos/ntoskrnl/mm/i386/memsafe.s 2005-02-22 01:07:41 UTC (rev 13709)
@@ -4,6 +4,9 @@
.globl _MmSafeCopyToUser
.globl _MmSafeCopyToUserUnsafeStart
.globl _MmSafeCopyToUserRestart
+.globl @MmSafeReadPtr@4
+.globl _MmSafeReadPtrStart
+.globl _MmSafeReadPtrEnd
/*
* NTSTATUS MmSafeCopyFromUser(PVOID Dest, PVOID Src,
@@ -83,3 +86,16 @@
popl %ebp
ret
+/*****************************************************************************/
+
+ /*
+ * PVOID FASTCALL MmSafeReadPtr(PVOID Source)
+ */
+@MmSafeReadPtr@4:
+_MmSafeReadPtrStart:
+ /*
+ * If we incur a pagefault, eax will be set NULL
+ */
+ movl (%ecx),%eax
+_MmSafeReadPtrEnd:
+ ret
--- trunk/reactos/ntoskrnl/mm/i386/pfault.c 2005-02-21 21:40:31 UTC (rev 13708)
+++ trunk/reactos/ntoskrnl/mm/i386/pfault.c 2005-02-22 01:07:41 UTC (rev 13709)
@@ -20,6 +20,8 @@
extern VOID MmSafeCopyFromUserRestart(VOID);
extern VOID MmSafeCopyToUserUnsafeStart(VOID);
extern VOID MmSafeCopyToUserRestart(VOID);
+extern VOID MmSafeReadPtrStart(VOID);
+extern VOID MmSafeReadPtrEnd(VOID);
extern ULONG MmGlobalKernelPageDirectory[1024];
@@ -90,5 +92,14 @@
(*Eax) = STATUS_ACCESS_VIOLATION;
return(STATUS_SUCCESS);
}
+ if (!NT_SUCCESS(Status) && (Mode == KernelMode) &&
+ ((*Eip) >= (ULONG_PTR)MmSafeReadPtrStart) &&
+ ((*Eip) <= (ULONG_PTR)MmSafeReadPtrEnd))
+ {
+ (*Eip) = (ULONG_PTR)MmSafeReadPtrEnd;
+ (*Eax) = 0;
+ return(STATUS_SUCCESS);
+ }
+
return(Status);
}