#define DR_MASK(x) (1 << (x))
#define DR_REG_MASK 0x4F
-#define IMAGE_FILE_MACHINE_ARCHITECTURE IMAGE_FILE_MACHINE_I386
-
//
// INT3 is 1 byte long
//
#define KiGetLinkedTrapFrame(x) \
(PKTRAP_FRAME)((x)->Edx)
-
+
#define KeGetContextReturnRegister(Context) \
((Context)->Eax)
#define KTE_SKIP_PM_BIT (((KTRAP_EXIT_SKIP_BITS) { { .SkipPreviousMode = TRUE } }).Bits)
#define KTE_SKIP_SEG_BIT (((KTRAP_EXIT_SKIP_BITS) { { .SkipSegments = TRUE } }).Bits)
#define KTE_SKIP_VOL_BIT (((KTRAP_EXIT_SKIP_BITS) { { .SkipVolatiles = TRUE } }).Bits)
-
+
typedef union _KTRAP_EXIT_SKIP_BITS
{
struct
FX_SAVE_AREA NpxArea;
KV86_FRAME V86Frame;
} KV8086_STACK_FRAME, *PKV8086_STACK_FRAME;
-
+
//
// Registers an interrupt handler with an IDT vector
//
VOID
KeRegisterInterruptHandler(IN ULONG Vector,
IN PVOID Handler)
-{
+{
UCHAR Entry;
ULONG_PTR Address;
PKIPCR Pcr = (PKIPCR)KeGetPcr();
VdmDispatchBop(
IN PKTRAP_FRAME TrapFrame
);
-
+
BOOLEAN
FASTCALL
KiVdmOpcodePrefix(
IN ULONG StackBytes)
{
NTSTATUS Result;
-
+
/*
* This sequence does a RtlCopyMemory(Stack - StackBytes, Arguments, StackBytes)
* and then calls the function associated with the system call.
FORCEINLINE
KiConvertToGuiThread(VOID)
{
- NTSTATUS Result;
+ NTSTATUS Result;
PVOID StackFrame;
/*
"subl %1, %%esp\n"
"pushl %2\n"
"jmp _KiSystemStartupBootStack@0\n"
- :
+ :
: "c"(InitialStack),
"i"(NPX_FRAME_LENGTH + KTRAP_FRAME_ALIGN + KTRAP_FRAME_LENGTH),
"i"(CR0_EM | CR0_TS | CR0_MP)
/* Disable interrupts and end the interrupt */
_disable();
HalEndSystemInterrupt(Irql, TrapFrame);
-
+
/* Exit the interrupt */
KiEoiHelper(TrapFrame);
}
#define PTE_COUNT PTE_PER_PAGE
#endif
-#ifdef _M_IX86
-#define IMAGE_FILE_MACHINE_NATIVE IMAGE_FILE_MACHINE_I386
-#elif _M_ARM
-#define IMAGE_FILE_MACHINE_NATIVE IMAGE_FILE_MACHINE_ARM
-#elif _M_AMD64
-#define IMAGE_FILE_MACHINE_NATIVE IMAGE_FILE_MACHINE_AMD64
-#else
-#error Define these please!
-#endif
-
//
// Protection Bits part of the internal memory manager Protection Mask
// Taken from http://www.reactos.org/wiki/Techwiki:Memory_management_in_the_Windows_XP_kernel
// and public assertions.
//
#define MM_ZERO_ACCESS 0
-#define MM_READONLY 1
-#define MM_EXECUTE 2
-#define MM_EXECUTE_READ 3
+#define MM_READONLY 1
+#define MM_EXECUTE 2
+#define MM_EXECUTE_READ 3
#define MM_READWRITE 4
-#define MM_WRITECOPY 5
-#define MM_EXECUTE_READWRITE 6
-#define MM_EXECUTE_WRITECOPY 7
-#define MM_NOCACHE 8
-#define MM_DECOMMIT 0x10
+#define MM_WRITECOPY 5
+#define MM_EXECUTE_READWRITE 6
+#define MM_EXECUTE_WRITECOPY 7
+#define MM_NOCACHE 8
+#define MM_DECOMMIT 0x10
#define MM_NOACCESS (MM_DECOMMIT | MM_NOCACHE)
#define MM_INVALID_PROTECTION 0xFFFFFFFF
//
// For example, in the logical attributes, we want to express read-only as a flag
// but on x86, it is writability that must be set. On the other hand, on x86, just
-// like in the kernel, it is disabling the caches that requires a special flag,
+// like in the kernel, it is disabling the caches that requires a special flag,
// while on certain architectures such as ARM, it is enabling the cache which
// requires a flag.
//
//
#define MI_IS_SESSION_IMAGE_ADDRESS(Address) \
(((Address) >= MiSessionImageStart) && ((Address) < MiSessionImageEnd))
-
+
#define MI_IS_SESSION_ADDRESS(Address) \
(((Address) >= MmSessionBase) && ((Address) < MiSessionSpaceEnd))
-
+
#define MI_IS_SESSION_PTE(Pte) \
((((PMMPTE)Pte) >= MiSessionBasePte) && (((PMMPTE)Pte) < MiSessionLastPte))
#define MI_IS_PAGE_TABLE_OR_HYPER_ADDRESS(Address) \
(((PVOID)(Address) >= (PVOID)PTE_BASE) && ((PVOID)(Address) <= (PVOID)MmHyperSpaceEnd))
-
+
//
// Corresponds to MMPTE_SOFTWARE.Protection
//
MiDetermineUserGlobalPteMask(IN PVOID PointerPte)
{
MMPTE TempPte;
-
+
/* Start fresh */
TempPte.u.Long = 0;
-
+
/* Make it valid and accessed */
TempPte.u.Hard.Valid = TRUE;
MI_MAKE_ACCESSED_PAGE(&TempPte);
-
+
/* Is this for user-mode? */
if ((PointerPte <= (PVOID)MiHighestUserPte) ||
((PointerPte >= (PVOID)MiAddressToPde(NULL)) &&
/* Set the owner bit */
MI_MAKE_OWNER_PAGE(&TempPte);
}
-
+
/* FIXME: We should also set the global bit */
-
+
/* Return the protection */
return TempPte.u.Long;
}
ASSERT(MappingPte > MiHighestUserPte);
ASSERT(!MI_IS_SESSION_PTE(MappingPte));
ASSERT((MappingPte < (PMMPTE)PDE_BASE) || (MappingPte > (PMMPTE)PDE_TOP));
-
+
/* Start fresh */
*NewPte = ValidKernelPte;
-
+
/* Set the protection and page */
NewPte->u.Hard.PageFrameNumber = PageFrameNumber;
NewPte->u.Long |= MmProtectToPteMask[ProtectionMask];
{
/* Only valid for kernel, non-session PTEs */
ASSERT(MappingPte <= MiHighestUserPte);
-
+
/* Start fresh */
*NewPte = ValidKernelPte;
-
+
/* Set the protection and page */
NewPte->u.Hard.Owner = TRUE;
NewPte->u.Hard.PageFrameNumber = PageFrameNumber;
/* Mark this as a prototype */
NewPte->u.Long = 0;
NewPte->u.Proto.Prototype = 1;
-
+
/*
* Prototype PTEs are only valid in paged pool by design, this little trick
* lets us only use 28 bits for the adress of the PTE
MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
{
PMMPDE PointerPde;
-
+
/* Large pages are never paged out, always physically resident */
PointerPde = MiAddressToPde(Address);
return ((PointerPde->u.Hard.LargePage) && (PointerPde->u.Hard.Valid));
ASSERT(MI_WS_OWNER(Process));
/* This can't be checked because Vm is used by MAREAs) */
//ASSERT(Process->Vm.Flags.AcquiredUnsafe == 0);
-
+
/* The thread doesn't own it anymore */
ASSERT(Thread->OwnsProcessWorkingSetExclusive == TRUE);
Thread->OwnsProcessWorkingSetExclusive = FALSE;
-
+
/* FIXME: Actually release it (we can't because Vm is used by MAREAs) */
/* Unblock APCs */
{
/* Block APCs */
KeEnterGuardedRegion();
-
+
/* Working set should be in global memory */
ASSERT(MI_IS_SESSION_ADDRESS((PVOID)WorkingSet) == FALSE);
-
+
/* Thread shouldn't already be owning something */
ASSERT(!MM_ANY_WS_LOCK_HELD(Thread));
-
+
/* FIXME: Actually lock it (we can't because Vm is used by MAREAs) */
-
+
/* Which working set is this? */
if (WorkingSet == &MmSystemCacheWs)
{
{
/* Working set should be in global memory */
ASSERT(MI_IS_SESSION_ADDRESS((PVOID)WorkingSet) == FALSE);
-
+
/* Which working set is this? */
if (WorkingSet == &MmSystemCacheWs)
{
(Thread->OwnsProcessWorkingSetShared));
Thread->OwnsProcessWorkingSetExclusive = FALSE;
}
-
+
/* FIXME: Actually release it (we can't because Vm is used by MAREAs) */
/* Unblock APCs */
MiInitializeMemoryEvents(
VOID
);
-
+
PFN_NUMBER
NTAPI
MxGetNextPage(
IN PLOADER_PARAMETER_BLOCK LoaderBlock,
IN PBOOLEAN IncludeType
);
-
+
PFN_NUMBER
NTAPI
MiPagesInLoaderBlock(
IN PLOADER_PARAMETER_BLOCK LoaderBlock,
IN PBOOLEAN IncludeType
);
-
+
VOID
FASTCALL
MiSyncARM3WithROS(
IN PVOID AddressStart,
IN PVOID AddressEnd
);
-
+
NTSTATUS
NTAPI
MmArmAccessFault(
IN ULONG Flags,
OUT PPFN_NUMBER ValidPages
);
-
+
PLDR_DATA_TABLE_ENTRY
NTAPI
MiLookupDataTableEntry(
IN PMMVAD Vad,
IN ULONG_PTR Vpn
);
-
+
//
// MiRemoveZeroPage will use inline code to zero out the page manually if only
// free pages are available. In some scenarios, we don't/can't run that piece of