Author: ros-arm-bringup
Date: Fri Oct 16 00:08:26 2009
New Revision: 43507
URL: http://svn.reactos.org/svn/reactos?rev=43507&view=rev
Log:
- Implement ARM3 page fault handling.
- Paged pool PTEs are demand zero PTEs while the memory hasn't been accessed -- this is the only type of fault supported.
- Because paged pool PDEs are also demand-paged, added code to handle demand paging of PDEs as well.
- Also, because paged pool is non-resident, but can be accessed from any process, we need a mechanism to sync up the kernel's page directory with the per-process one, on demand. This is done at startup, but other processes may have paged in paged pool that another process knows nothing about when he faults.
- Similar to the hack ReactOS Mm uses, but done properly.
- This is what that shadow system page directory is finally being used for.
- Assert if we get a user-mode fault, a transition fault, or a soft fault, since these shouldn't happen.
- Disable APCs while dispatching faults, and pseudo-use the working set lock.
- Assert if we get write errors on read-only pages, since we don't use those in ARM3 yet.
- Assert if we have a paged out PTE, this shouldn't happen yet.
- Enable test to see if we can touch a paged pool allocation.
Added:
trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c (with props)
Modified:
trunk/reactos/ntoskrnl/mm/mmfault.c
trunk/reactos/ntoskrnl/mm/mminit.c
trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild
Added: trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pagfault.…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c (added)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] Fri Oct 16 00:08:26 2009
@@ -1,0 +1,391 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
+ * FILE: ntoskrnl/mm/ARM3/pagfault.c
+ * PURPOSE: ARM Memory Manager Page Fault Handling
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+#line 15 "ARM³::PAGFAULT"
+#define MODULE_INVOLVED_IN_ARM3
+#include "../ARM3/miarm.h"
+
+/* GLOBALS ********************************************************************/
+
+/* PRIVATE FUNCTIONS **********************************************************/
+
+NTSTATUS
+FASTCALL
+MiCheckPdeForPagedPool(IN PVOID Address)
+{
+ PMMPTE PointerPde;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ //
+ // Check if this is a fault while trying to access the page table itself
+ //
+ if ((Address >= (PVOID)MiAddressToPte(MmSystemRangeStart)) &&
+ (Address < (PVOID)PTE_TOP))
+ {
+ //
+ // Send a hint to the page fault handler that this is only a valid fault
+ // if we already detected this was access within the page table range
+ //
+ PointerPde = MiAddressToPte(Address);
+ Status = STATUS_WAIT_1;
+ }
+ else if (Address < MmSystemRangeStart)
+ {
+ //
+ // This is totally illegal
+ //
+ return STATUS_ACCESS_VIOLATION;
+ }
+ else
+ {
+ //
+ // Get the PDE for the address
+ //
+ PointerPde = MiAddressToPde(Address);
+ }
+
+ //
+ // Check if it's not valid
+ //
+ if (PointerPde->u.Hard.Valid == 0)
+ {
+ //
+ // Copy it from our double-mapped system page directory
+ //
+ InterlockedExchangePte(PointerPde,
+ MmSystemPagePtes[((ULONG_PTR)PointerPde &
+ (PAGE_SIZE - 1)) /
+ sizeof(MMPTE)].u.Long);
+ }
+
+ //
+ // Return status
+ //
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+MiResolveDemandZeroFault(IN PVOID Address,
+ IN PMMPTE PointerPte,
+ IN PEPROCESS Process,
+ IN KIRQL OldIrql)
+{
+ PFN_NUMBER PageFrameNumber;
+ MMPTE TempPte;
+ DPRINT("ARM3 Demand Zero Page Fault Handler for address: %p in process: %p\n",
+ Address,
+ Process);
+
+ //
+ // Lock the PFN database
+ //
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ ASSERT(PointerPte->u.Hard.Valid == 0);
+
+ //
+ // Get a page
+ //
+ PageFrameNumber = MmAllocPage(MC_PPOOL, 0);
+ DPRINT("New pool page: %lx\n", PageFrameNumber);
+
+ //
+ // Release PFN lock
+ //
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+
+ //
+ // Increment demand zero faults
+ //
+ InterlockedIncrement(&KeGetCurrentPrcb()->MmDemandZeroCount);
+
+ //
+ // Build the PTE
+ //
+ TempPte = HyperTemplatePte;
+ TempPte.u.Hard.PageFrameNumber = PageFrameNumber;
+ *PointerPte = TempPte;
+ ASSERT(PointerPte->u.Hard.Valid == 1);
+
+ //
+ // It's all good now
+ //
+ DPRINT("Paged pool page has now been paged in\n");
+ return STATUS_PAGE_FAULT_DEMAND_ZERO;
+}
+
+NTSTATUS
+NTAPI
+MiDispatchFault(IN BOOLEAN StoreInstruction,
+ IN PVOID Address,
+ IN PMMPTE PointerPte,
+ IN PMMPTE PrototypePte,
+ IN BOOLEAN Recursive,
+ IN PEPROCESS Process,
+ IN PVOID TrapInformation,
+ IN PVOID Vad)
+{
+ MMPTE TempPte;
+ KIRQL OldIrql;
+ NTSTATUS Status;
+ DPRINT("ARM3 Page Fault Dispatcher for address: %p in process: %p\n",
+ Address,
+ Process);
+
+ //
+ // Make sure APCs are off and we're not at dispatch
+ //
+ OldIrql = KeGetCurrentIrql ();
+ ASSERT(OldIrql <= APC_LEVEL);
+ ASSERT(KeAreAllApcsDisabled () == TRUE);
+
+ //
+ // Grab a copy of the PTE
+ //
+ TempPte = *PointerPte;
+
+ //
+ // The PTE must be invalid, but not totally blank
+ //
+ ASSERT(TempPte.u.Hard.Valid == 0);
+ ASSERT(TempPte.u.Long != 0);
+
+ //
+ // No prototype, transition or page file software PTEs in ARM3 yet
+ //
+ ASSERT(TempPte.u.Soft.Prototype == 0);
+ ASSERT(TempPte.u.Soft.Transition == 0);
+ ASSERT(TempPte.u.Soft.PageFileHigh == 0);
+
+ //
+ // If we got this far, the PTE can only be a demand zero PTE, which is what
+ // we want. Go handle it!
+ //
+ Status = MiResolveDemandZeroFault(Address,
+ PointerPte,
+ Process,
+ -1);
+ if (NT_SUCCESS(Status))
+ {
+ //
+ // Make sure we're returning in a sane state and pass the status down
+ //
+ ASSERT(OldIrql == KeGetCurrentIrql ());
+ ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
+ return Status;
+ }
+
+ //
+ // Generate an access fault
+ //
+ return STATUS_ACCESS_VIOLATION;
+}
+
+NTSTATUS
+NTAPI
+MmArmAccessFault(IN BOOLEAN StoreInstruction,
+ IN PVOID Address,
+ IN KPROCESSOR_MODE Mode,
+ IN PVOID TrapInformation)
+{
+ KIRQL OldIrql = KeGetCurrentIrql(), LockIrql;
+ PMMPTE PointerPde, PointerPte;
+ MMPTE TempPte;
+ PETHREAD CurrentThread;
+ NTSTATUS Status;
+ DPRINT("ARM3 FAULT AT: %p\n", Address);
+
+ //
+ // Get the PTE and PDE
+ //
+ PointerPte = MiAddressToPte(Address);
+ PointerPde = MiAddressToPde(Address);
+
+ //
+ // Check for dispatch-level snafu
+ //
+ if (OldIrql > APC_LEVEL)
+ {
+ //
+ // There are some special cases where this is okay, but not in ARM3 yet
+ //
+ DbgPrint("MM:***PAGE FAULT AT IRQL > 1 Va %p, IRQL %lx\n",
+ Address,
+ OldIrql);
+ ASSERT(OldIrql <= APC_LEVEL);
+ }
+
+ //
+ // Check for kernel fault
+ //
+ if (Address >= MmSystemRangeStart)
+ {
+ //
+ // What are you even DOING here?
+ //
+ if (Mode == UserMode) return STATUS_ACCESS_VIOLATION;
+
+ //
+ // Is the PDE valid?
+ //
+ if (!PointerPde->u.Hard.Valid == 0)
+ {
+ //
+ // Debug spew (eww!)
+ //
+ DPRINT("Invalid PDE\n");
+
+ //
+ // Handle mapping in "Special" PDE directoreis
+ //
+ MiCheckPdeForPagedPool(Address);
+
+ //
+ // Now we SHOULD be good
+ //
+ if (PointerPde->u.Hard.Valid == 0)
+ {
+ //
+ // FIXFIX: Do the S-LIST hack
+ //
+
+ //
+ // Kill the system
+ //
+ KeBugCheckEx(PAGE_FAULT_IN_NONPAGED_AREA,
+ (ULONG_PTR)Address,
+ StoreInstruction,
+ (ULONG_PTR)TrapInformation,
+ 2);
+ }
+ }
+
+ //
+ // The PDE is valid, so read the PTE
+ //
+ TempPte = *PointerPte;
+ if (TempPte.u.Hard.Valid == 1)
+ {
+ //
+ // Only two things can go wrong here:
+ // Executing NX page (we couldn't care less)
+ // Writing to a read-only page (the stuff ARM3 works with is write,
+ // so again, moot point).
+ //
+ if (StoreInstruction)
+ {
+ DPRINT1("Should NEVER happen on ARM3!!!\n");
+ return STATUS_ACCESS_VIOLATION;
+ }
+
+ //
+ // Otherwise, the PDE was probably invalid, and all is good now
+ //
+ return STATUS_SUCCESS;
+ }
+
+ //
+ // Check for a fault on the page table or hyperspace itself
+ // FIXME: Use MmHyperSpaceEnd
+ //
+ if ((Address >= (PVOID)PTE_BASE) && (Address <= (PVOID)0xC0800000))
+ {
+ //
+ // This might happen...not sure yet
+ //
+ DPRINT1("FAULT ON PAGE TABLES!\n");
+ return STATUS_ACCESS_VIOLATION;
+ }
+
+ //
+ // Now we must raise to APC_LEVEL and mark the thread as owner
+ // We don't actually implement a working set pushlock, so this is only
+ // for internal consistency (and blocking APCs)
+ //
+ KeRaiseIrql(APC_LEVEL, &LockIrql);
+ CurrentThread = PsGetCurrentThread();
+ KeEnterGuardedRegion();
+ ASSERT((CurrentThread->OwnsSystemWorkingSetExclusive == 0) &&
+ (CurrentThread->OwnsSystemWorkingSetShared == 0));
+ CurrentThread->OwnsSystemWorkingSetExclusive = 1;
+
+ //
+ // Re-read PTE now that the IRQL has been raised
+ //
+ TempPte = *PointerPte;
+ if (TempPte.u.Hard.Valid == 1)
+ {
+ //
+ // Only two things can go wrong here:
+ // Executing NX page (we couldn't care less)
+ // Writing to a read-only page (the stuff ARM3 works with is write,
+ // so again, moot point.
+ //
+ if (StoreInstruction)
+ {
+ DPRINT1("Should NEVER happen on ARM3!!!\n");
+ return STATUS_ACCESS_VIOLATION;
+ }
+
+ //
+ // Otherwise, the PDE was probably invalid, and all is good now
+ //
+ return STATUS_SUCCESS;
+ }
+
+ //
+ // We don't implement prototype PTEs
+ //
+ ASSERT(TempPte.u.Soft.Prototype == 0);
+
+ //
+ // We don't implement transition PTEs
+ //
+ ASSERT(TempPte.u.Soft.Transition == 0);
+
+ //
+ // Now do the real fault handling
+ //
+ Status = MiDispatchFault(StoreInstruction,
+ Address,
+ PointerPte,
+ NULL,
+ FALSE,
+ NULL,
+ TrapInformation,
+ NULL);
+
+ //
+ // Re-enable APCs
+ //
+ ASSERT(KeAreAllApcsDisabled() == TRUE);
+ CurrentThread->OwnsSystemWorkingSetExclusive = 0;
+ KeLeaveGuardedRegion();
+ KeLowerIrql(LockIrql);
+
+ //
+ // We are done!
+ //
+ DPRINT("Fault resolved with status: %lx\n", Status);
+ return Status;
+ }
+
+ //
+ // DIE DIE DIE
+ //
+ DPRINT1("WARNING: USER MODE FAULT IN ARM3???\n");
+ return STATUS_ACCESS_VIOLATION;
+}
+
+/* EOF */
Propchange: trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: trunk/reactos/ntoskrnl/mm/mmfault.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/mmfault.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/mmfault.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/mmfault.c [iso-8859-1] Fri Oct 16 00:08:26 2009
@@ -283,9 +283,7 @@
//
// Hand it off to more competent hands...
//
- UNIMPLEMENTED;
- KeBugCheckEx(MEMORY_AREA_OWNED_BY_ARM3, Mode, (ULONG_PTR)Address, 0, 0);
- //return MmArmAccessFault(StoreInstruction, Address, Mode, TrapInformation);
+ return MmArmAccessFault(StoreInstruction, Address, Mode, TrapInformation);
}
/* Keep same old ReactOS Behaviour */
Modified: trunk/reactos/ntoskrnl/mm/mminit.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/mminit.c?rev=4…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] Fri Oct 16 00:08:26 2009
@@ -403,12 +403,12 @@
// STEP 3: Allocate a page and touch it.
// We should get an ARM3 page fault and it should handle the fault
//
- if (0) // NOT YET IMPLEMENTED
+ if (1)
{
PULONG Test;
Test = MiAllocatePoolPages(PagedPool, PAGE_SIZE);
- DPRINT1("Value: %lx", *Test);
+ ASSERT(*Test == 0);
MiFreePoolPages(Test);
}
Modified: trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl-generic.…
==============================================================================
--- trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] Fri Oct 16 00:08:26 2009
@@ -392,6 +392,7 @@
<file>mdlsup.c</file>
<file>mmsup.c</file>
<file>ncache.c</file>
+ <file>pagfault.c</file>
<file>pool.c</file>
<file>procsup.c</file>
<file>syspte.c</file>
Author: ros-arm-bringup
Date: Thu Oct 15 23:23:24 2009
New Revision: 43503
URL: http://svn.reactos.org/svn/reactos?rev=43503&view=rev
Log:
- Add some simple code to handle paged pool page allocation and freeing in MiAllocatePoolPages and MiFreePoolPages.
- Allocation does not support paged pool expansion yet, so we're limited to the initial 4MB that are initialized on startup.
- This only tests the raw page allocation routines so touching memory will fail as we don't handle paged pool faults yet.
- Nothing excercises this code path other than some simple tests while booting.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/pool.c
trunk/reactos/ntoskrnl/mm/mminit.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pool.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pool.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pool.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pool.c [iso-8859-1] Thu Oct 15 23:23:24 2009
@@ -149,6 +149,83 @@
SizeInPages = BYTES_TO_PAGES(SizeInBytes);
//
+ // Handle paged pool
+ //
+ if (PoolType == PagedPool)
+ {
+ //
+ // Lock the paged pool mutex
+ //
+ KeAcquireGuardedMutex(&MmPagedPoolMutex);
+
+ //
+ // Find some empty allocation space
+ //
+ i = RtlFindClearBitsAndSet(MmPagedPoolInfo.PagedPoolAllocationMap,
+ SizeInPages,
+ MmPagedPoolInfo.PagedPoolHint);
+ if (i == 0xFFFFFFFF)
+ {
+ //
+ // Out of memory!
+ //
+ DPRINT1("OUT OF PAGED POOL!!!\n");
+ KeReleaseGuardedMutex(&MmPagedPoolMutex);
+ return NULL;
+ }
+
+ //
+ // Update the pool hint if the request was just one page
+ //
+ if (SizeInPages == 1) MmPagedPoolInfo.PagedPoolHint = i + 1;
+
+ //
+ // Update the end bitmap so we know the bounds of this allocation when
+ // the time comes to free it
+ //
+ RtlSetBit(MmPagedPoolInfo.EndOfPagedPoolBitmap, i + SizeInPages - 1);
+
+ //
+ // Now we can release the lock (it mainly protects the bitmap)
+ //
+ KeReleaseGuardedMutex(&MmPagedPoolMutex);
+
+ //
+ // Now figure out where this allocation starts
+ //
+ BaseVa = (PVOID)((ULONG_PTR)MmPagedPoolStart + (i << PAGE_SHIFT));
+
+ //
+ // Flush the TLB
+ //
+ KeFlushEntireTb(TRUE, TRUE);
+
+ //
+ // Setup a demand-zero writable PTE
+ //
+ TempPte.u.Long = 0;
+ MI_MAKE_WRITE_PAGE(&TempPte);
+
+ //
+ // Find the first and last PTE, then loop them all
+ //
+ PointerPte = MiAddressToPte(BaseVa);
+ StartPte = PointerPte + SizeInPages;
+ do
+ {
+ //
+ // Write the demand zero PTE and keep going
+ //
+ *PointerPte++ = TempPte;
+ } while (PointerPte < StartPte);
+
+ //
+ // Return the allocation address to the caller
+ //
+ return BaseVa;
+ }
+
+ //
// Allocations of less than 4 pages go into their individual buckets
//
i = SizeInPages - 1;
@@ -346,7 +423,57 @@
PFN_NUMBER FreePages, NumberOfPages;
KIRQL OldIrql;
PMMFREE_POOL_ENTRY FreeEntry, NextEntry, LastEntry;
- ULONG i;
+ ULONG i, End;
+
+ //
+ // Handle paged pool
+ //
+ if ((StartingVa >= MmPagedPoolStart) && (StartingVa <= MmPagedPoolEnd))
+ {
+ //
+ // Calculate the offset from the beginning of paged pool, and convert it
+ // into pages
+ //
+ i = ((ULONG_PTR)StartingVa - (ULONG_PTR)MmPagedPoolStart) >> PAGE_SHIFT;
+ End = i;
+
+ //
+ // Now use the end bitmap to scan until we find a set bit, meaning that
+ // this allocation finishes here
+ //
+ while (!RtlTestBit(MmPagedPoolInfo.EndOfPagedPoolBitmap, End)) End++;
+
+ //
+ // Now calculate the total number of pages this allocation spans
+ //
+ NumberOfPages = End - i + 1;
+
+ //
+ // Acquire the paged pool lock
+ //
+ KeAcquireGuardedMutex(&MmPagedPoolMutex);
+
+ //
+ // Clear the allocation and free bits
+ //
+ RtlClearBit(MmPagedPoolInfo.EndOfPagedPoolBitmap, i);
+ RtlClearBits(MmPagedPoolInfo.PagedPoolAllocationMap, i, NumberOfPages);
+
+ //
+ // Update the hint if we need to
+ //
+ if (i < MmPagedPoolInfo.PagedPoolHint) MmPagedPoolInfo.PagedPoolHint = i;
+
+ //
+ // Release the lock protecting the bitmaps
+ //
+ KeReleaseGuardedMutex(&MmPagedPoolMutex);
+
+ //
+ // And finally return the number of pages freed
+ //
+ return NumberOfPages;
+ }
//
// Get the first PTE and its corresponding PFN entry
Modified: trunk/reactos/ntoskrnl/mm/mminit.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/mminit.c?rev=4…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] Thu Oct 15 23:23:24 2009
@@ -353,6 +353,65 @@
/* Intialize system memory areas */
MiInitSystemMemoryAreas();
+ //
+ // STEP 1: Allocate and free a single page, repeatedly
+ // We should always get the same address back
+ //
+ if (1)
+ {
+ PULONG Test, OldTest;
+ ULONG i;
+
+ OldTest = Test = MiAllocatePoolPages(PagedPool, PAGE_SIZE);
+ ASSERT(Test);
+ for (i = 0; i < 16; i++)
+ {
+ MiFreePoolPages(Test);
+ Test = MiAllocatePoolPages(PagedPool, PAGE_SIZE);
+ ASSERT(OldTest == Test);
+ }
+ MiFreePoolPages(Test);
+ }
+
+ //
+ // STEP 2: Allocate 2048 pages without freeing them
+ // We should run out of space at 1024 pages, since we don't support
+ // expansion yet.
+ //
+ if (1)
+ {
+ PULONG Test[2048];
+ ULONG i;
+
+ for (i = 0; i < 2048; i++)
+ {
+ Test[i] = MiAllocatePoolPages(PagedPool, PAGE_SIZE);
+ if (!Test[i])
+ {
+ ASSERT(i == 1024);
+ break;
+ }
+ }
+
+ //
+ // Cleanup
+ //
+ while (--i) if (Test[i]) MiFreePoolPages(Test[i]);
+ }
+
+ //
+ // STEP 3: Allocate a page and touch it.
+ // We should get an ARM3 page fault and it should handle the fault
+ //
+ if (0) // NOT YET IMPLEMENTED
+ {
+ PULONG Test;
+
+ Test = MiAllocatePoolPages(PagedPool, PAGE_SIZE);
+ DPRINT1("Value: %lx", *Test);
+ MiFreePoolPages(Test);
+ }
+
/* Dump the address space */
MiDbgDumpAddressSpace();
Author: tkreuzer
Date: Thu Oct 15 22:07:47 2009
New Revision: 43501
URL: http://svn.reactos.org/svn/reactos?rev=43501&view=rev
Log:
The SessionId is not the same as the session pointer. Add fixed code for PsGetThreadSessionId, commented out as we don't have support for Sessions anyway.
Modified:
branches/ros-amd64-bringup/reactos/ntoskrnl/ps/thread.c
Modified: branches/ros-amd64-bringup/reactos/ntoskrnl/ps/thread.c
URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/ntosk…
==============================================================================
--- branches/ros-amd64-bringup/reactos/ntoskrnl/ps/thread.c [iso-8859-1] (original)
+++ branches/ros-amd64-bringup/reactos/ntoskrnl/ps/thread.c [iso-8859-1] Thu Oct 15 22:07:47 2009
@@ -736,6 +736,11 @@
PsGetThreadSessionId(IN PETHREAD Thread)
{
return (HANDLE)Thread->ThreadsProcess->Session;
+#if 0
+ // Should probably return a DWORD
+ PMM_SESSION_SPACE Session = Thread->ThreadsProcess->Session;
+ return Session->SessionId;
+#endif
}
/*