mirror of
https://github.com/reactos/reactos.git
synced 2025-05-08 19:27:00 +00:00
- Multiple PEB/TEB creation fixes:
- Set up PEB and TEB under SEH to handle possible paging errors (which are legitimate). - Also touch the image under SEH to handle image paging errors (also legitimate). - Should avoid kernel panics in cases where the executable is damaged, invalid, or impossible to page in. - Initialize more PEB fields. - Add new INITIAL_PEB structure to support fork() in the future. Also fixes the fact we don't create a PEB for the system process anymore. - Create PEB while attached to the process. - Handle UP-only images, and set correct affinity mask in the PEB. - Set session ID instead of session structure (currently zero). - Set correct TIB version in the TEB. Due to a historical oddity, the NT TIB identifies itself as '0x1e00', which is 30 shifted 8 bits. 30 is the version identifier of OS/2 3.0, the original 32-bit target of the Windows NT effort. - Handle initial TEB correctly for fork(). - Move AWE APIs to procsup.c instea of section.c since they are unrelated. - Move the rewritten PEB/TEB functions to ARM3's procsup.c. svn path=/trunk/; revision=43476
This commit is contained in:
parent
0387f3045a
commit
1ea8fff57a
8 changed files with 552 additions and 325 deletions
|
@ -586,24 +586,54 @@ typedef struct _PEB_FREE_BLOCK
|
|||
ULONG Size;
|
||||
} PEB_FREE_BLOCK, *PPEB_FREE_BLOCK;
|
||||
|
||||
//
|
||||
// Initial PEB
|
||||
//
|
||||
typedef struct _INITIAL_PEB
|
||||
{
|
||||
BOOLEAN InheritedAddressSpace;
|
||||
BOOLEAN ReadImageFileExecOptions;
|
||||
BOOLEAN BeingDebugged;
|
||||
union
|
||||
{
|
||||
BOOLEAN BitField;
|
||||
#if (NTDDI_VERSION >= NTDDI_WS03)
|
||||
struct
|
||||
{
|
||||
BOOLEAN ImageUsesLargePages:1;
|
||||
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
|
||||
BOOLEAN IsProtectedProcess:1;
|
||||
BOOLEAN IsLegacyProcess:1;
|
||||
BOOLEAN SpareBits:5;
|
||||
#else
|
||||
BOOLEAN SpareBits:7;
|
||||
#endif
|
||||
};
|
||||
#else
|
||||
BOOLEAN SpareBool;
|
||||
#endif
|
||||
};
|
||||
HANDLE Mutant;
|
||||
} INITIAL_PEB, *PINITIAL_PEB;
|
||||
|
||||
//
|
||||
// Process Environment Block (PEB)
|
||||
//
|
||||
typedef struct _PEB
|
||||
{
|
||||
UCHAR InheritedAddressSpace;
|
||||
UCHAR ReadImageFileExecOptions;
|
||||
UCHAR BeingDebugged;
|
||||
BOOLEAN InheritedAddressSpace;
|
||||
BOOLEAN ReadImageFileExecOptions;
|
||||
BOOLEAN BeingDebugged;
|
||||
#if (NTDDI_VERSION >= NTDDI_WS03)
|
||||
struct
|
||||
{
|
||||
UCHAR ImageUsesLargePages:1;
|
||||
BOOLEAN ImageUsesLargePages:1;
|
||||
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
|
||||
UCHAR IsProtectedProcess:1;
|
||||
UCHAR IsLegacyProcess:1;
|
||||
UCHAR SpareBits:5;
|
||||
BOOLEAN IsProtectedProcess:1;
|
||||
BOOLEAN IsLegacyProcess:1;
|
||||
BOOLEAN SpareBits:5;
|
||||
#else
|
||||
UCHAR SpareBits:7;
|
||||
BOOLEAN SpareBits:7;
|
||||
#endif
|
||||
};
|
||||
#else
|
||||
|
|
|
@ -776,14 +776,19 @@ MmInitializeProcessAddressSpace(
|
|||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmCreatePeb(struct _EPROCESS *Process);
|
||||
MmCreatePeb(
|
||||
IN PEPROCESS Process,
|
||||
IN PINITIAL_PEB InitialPeb,
|
||||
OUT PPEB *BasePeb
|
||||
);
|
||||
|
||||
PTEB
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmCreateTeb(
|
||||
struct _EPROCESS *Process,
|
||||
PCLIENT_ID ClientId,
|
||||
PINITIAL_TEB InitialTeb
|
||||
IN PEPROCESS Process,
|
||||
IN PCLIENT_ID ClientId,
|
||||
IN PINITIAL_TEB InitialTeb,
|
||||
OUT PTEB* BaseTeb
|
||||
);
|
||||
|
||||
VOID
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
#define MI_PAGED_POOL_START (PVOID)0xE1000000
|
||||
#define MI_NONPAGED_POOL_END (PVOID)0xFFBE0000
|
||||
|
||||
#define MM_HIGHEST_VAD_ADDRESS \
|
||||
(PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE))
|
||||
|
||||
|
||||
//
|
||||
// FIXFIX: These should go in ex.h after the pool merge
|
||||
//
|
||||
|
|
|
@ -16,6 +16,13 @@
|
|||
#define MODULE_INVOLVED_IN_ARM3
|
||||
#include "../ARM3/miarm.h"
|
||||
|
||||
extern MM_SYSTEMSIZE MmSystemSize;
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
MiCreatePebOrTeb(PEPROCESS Process,
|
||||
PVOID BaseAddress);
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
VOID
|
||||
|
@ -278,4 +285,454 @@ MmGrowKernelStack(IN PVOID StackPointer)
|
|||
return MmGrowKernelStackEx(StackPointer, KERNEL_LARGE_STACK_COMMIT);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmSetMemoryPriorityProcess(IN PEPROCESS Process,
|
||||
IN UCHAR MemoryPriority)
|
||||
{
|
||||
UCHAR OldPriority;
|
||||
|
||||
//
|
||||
// Check if we have less then 16MB of Physical Memory
|
||||
//
|
||||
if ((MmSystemSize == MmSmallSystem) &&
|
||||
(MmStats.NrTotalPages < ((15 * 1024 * 1024) / PAGE_SIZE)))
|
||||
{
|
||||
//
|
||||
// Always use background priority
|
||||
//
|
||||
MemoryPriority = MEMORY_PRIORITY_BACKGROUND;
|
||||
}
|
||||
|
||||
//
|
||||
// Save the old priority and update it
|
||||
//
|
||||
OldPriority = (UCHAR)Process->Vm.Flags.MemoryPriority;
|
||||
Process->Vm.Flags.MemoryPriority = MemoryPriority;
|
||||
|
||||
//
|
||||
// Return the old priority
|
||||
//
|
||||
return OldPriority;
|
||||
}
|
||||
|
||||
LCID
|
||||
NTAPI
|
||||
MmGetSessionLocaleId(VOID)
|
||||
{
|
||||
PEPROCESS Process;
|
||||
PAGED_CODE();
|
||||
|
||||
//
|
||||
// Get the current process
|
||||
//
|
||||
Process = PsGetCurrentProcess();
|
||||
|
||||
//
|
||||
// Check if it's the Session Leader
|
||||
//
|
||||
if (Process->Vm.Flags.SessionLeader)
|
||||
{
|
||||
//
|
||||
// Make sure it has a valid Session
|
||||
//
|
||||
if (Process->Session)
|
||||
{
|
||||
//
|
||||
// Get the Locale ID
|
||||
//
|
||||
#if ROS_HAS_SESSIONS
|
||||
return ((PMM_SESSION_SPACE)Process->Session)->LocaleId;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Not a session leader, return the default
|
||||
//
|
||||
return PsDefaultThreadLocaleId;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmCreatePeb(IN PEPROCESS Process,
|
||||
IN PINITIAL_PEB InitialPeb,
|
||||
OUT PPEB *BasePeb)
|
||||
{
|
||||
PPEB Peb = NULL;
|
||||
LARGE_INTEGER SectionOffset;
|
||||
SIZE_T ViewSize = 0;
|
||||
PVOID TableBase = NULL;
|
||||
PIMAGE_NT_HEADERS NtHeaders;
|
||||
PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigData;
|
||||
NTSTATUS Status;
|
||||
USHORT Characteristics;
|
||||
KAFFINITY ProcessAffinityMask = 0;
|
||||
SectionOffset.QuadPart = (ULONGLONG)0;
|
||||
*BasePeb = NULL;
|
||||
|
||||
//
|
||||
// Attach to Process
|
||||
//
|
||||
KeAttachProcess(&Process->Pcb);
|
||||
|
||||
//
|
||||
// Allocate the PEB
|
||||
//
|
||||
Peb = MiCreatePebOrTeb(Process,
|
||||
(PVOID)((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1));
|
||||
ASSERT(Peb == (PVOID)0x7FFDF000);
|
||||
|
||||
//
|
||||
// Map NLS Tables
|
||||
//
|
||||
Status = MmMapViewOfSection(ExpNlsSectionPointer,
|
||||
(PEPROCESS)Process,
|
||||
&TableBase,
|
||||
0,
|
||||
0,
|
||||
&SectionOffset,
|
||||
&ViewSize,
|
||||
ViewShare,
|
||||
MEM_TOP_DOWN,
|
||||
PAGE_READONLY);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
//
|
||||
// Use SEH in case we can't load the PEB
|
||||
//
|
||||
_SEH2_TRY
|
||||
{
|
||||
//
|
||||
// Initialize the PEB
|
||||
//
|
||||
RtlZeroMemory(Peb, sizeof(PEB));
|
||||
|
||||
//
|
||||
// Set up data
|
||||
//
|
||||
Peb->ImageBaseAddress = Process->SectionBaseAddress;
|
||||
Peb->InheritedAddressSpace = InitialPeb->InheritedAddressSpace;
|
||||
Peb->Mutant = InitialPeb->Mutant;
|
||||
Peb->ImageUsesLargePages = InitialPeb->ImageUsesLargePages;
|
||||
|
||||
//
|
||||
// NLS
|
||||
//
|
||||
Peb->AnsiCodePageData = (PCHAR)TableBase + ExpAnsiCodePageDataOffset;
|
||||
Peb->OemCodePageData = (PCHAR)TableBase + ExpOemCodePageDataOffset;
|
||||
Peb->UnicodeCaseTableData = (PCHAR)TableBase + ExpUnicodeCaseTableDataOffset;
|
||||
|
||||
//
|
||||
// Default Version Data (could get changed below)
|
||||
//
|
||||
Peb->OSMajorVersion = NtMajorVersion;
|
||||
Peb->OSMinorVersion = NtMinorVersion;
|
||||
Peb->OSBuildNumber = (USHORT)(NtBuildNumber & 0x3FFF);
|
||||
Peb->OSPlatformId = 2; /* VER_PLATFORM_WIN32_NT */
|
||||
Peb->OSCSDVersion = (USHORT)CmNtCSDVersion;
|
||||
|
||||
//
|
||||
// Heap and Debug Data
|
||||
//
|
||||
Peb->NumberOfProcessors = KeNumberProcessors;
|
||||
Peb->BeingDebugged = (BOOLEAN)(Process->DebugPort != NULL ? TRUE : FALSE);
|
||||
Peb->NtGlobalFlag = NtGlobalFlag;
|
||||
/*Peb->HeapSegmentReserve = MmHeapSegmentReserve;
|
||||
Peb->HeapSegmentCommit = MmHeapSegmentCommit;
|
||||
Peb->HeapDeCommitTotalFreeThreshold = MmHeapDeCommitTotalFreeThreshold;
|
||||
Peb->HeapDeCommitFreeBlockThreshold = MmHeapDeCommitFreeBlockThreshold;
|
||||
Peb->CriticalSectionTimeout = MmCriticalSectionTimeout;
|
||||
Peb->MinimumStackCommit = MmMinimumStackCommitInBytes;
|
||||
*/
|
||||
Peb->MaximumNumberOfHeaps = (PAGE_SIZE - sizeof(PEB)) / sizeof(PVOID);
|
||||
Peb->ProcessHeaps = (PVOID*)(Peb + 1);
|
||||
|
||||
//
|
||||
// Session ID
|
||||
//
|
||||
if (Process->Session) Peb->SessionId = 0; // MmGetSessionId(Process);
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
//
|
||||
// Fail
|
||||
//
|
||||
KeDetachProcess();
|
||||
_SEH2_YIELD(return _SEH2_GetExceptionCode());
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
//
|
||||
// Use SEH in case we can't load the image
|
||||
//
|
||||
_SEH2_TRY
|
||||
{
|
||||
//
|
||||
// Get NT Headers
|
||||
//
|
||||
NtHeaders = RtlImageNtHeader(Peb->ImageBaseAddress);
|
||||
Characteristics = NtHeaders->FileHeader.Characteristics;
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
//
|
||||
// Fail
|
||||
//
|
||||
KeDetachProcess();
|
||||
_SEH2_YIELD(return STATUS_INVALID_IMAGE_PROTECT);
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
//
|
||||
// Parse the headers
|
||||
//
|
||||
if (NtHeaders)
|
||||
{
|
||||
//
|
||||
// Use SEH in case we can't load the headers
|
||||
//
|
||||
_SEH2_TRY
|
||||
{
|
||||
//
|
||||
// Get the Image Config Data too
|
||||
//
|
||||
ImageConfigData = RtlImageDirectoryEntryToData(Peb->ImageBaseAddress,
|
||||
TRUE,
|
||||
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG,
|
||||
&ViewSize);
|
||||
if (ImageConfigData)
|
||||
{
|
||||
//
|
||||
// Probe it
|
||||
//
|
||||
ProbeForRead(ImageConfigData,
|
||||
sizeof(IMAGE_LOAD_CONFIG_DIRECTORY),
|
||||
sizeof(ULONG));
|
||||
}
|
||||
|
||||
//
|
||||
// Write subsystem data
|
||||
//
|
||||
Peb->ImageSubSystem = NtHeaders->OptionalHeader.Subsystem;
|
||||
Peb->ImageSubSystemMajorVersion = NtHeaders->OptionalHeader.MajorSubsystemVersion;
|
||||
Peb->ImageSubSystemMinorVersion = NtHeaders->OptionalHeader.MinorSubsystemVersion;
|
||||
|
||||
//
|
||||
// Check for version data
|
||||
//
|
||||
if (NtHeaders->OptionalHeader.Win32VersionValue)
|
||||
{
|
||||
//
|
||||
// Extract values and write them
|
||||
//
|
||||
Peb->OSMajorVersion = NtHeaders->OptionalHeader.Win32VersionValue & 0xFF;
|
||||
Peb->OSMinorVersion = (NtHeaders->OptionalHeader.Win32VersionValue >> 8) & 0xFF;
|
||||
Peb->OSBuildNumber = (NtHeaders->OptionalHeader.Win32VersionValue >> 16) & 0x3FFF;
|
||||
Peb->OSPlatformId = (NtHeaders->OptionalHeader.Win32VersionValue >> 30) ^ 2;
|
||||
}
|
||||
|
||||
//
|
||||
// Process the image config data overrides if specfied
|
||||
//
|
||||
if (ImageConfigData != NULL)
|
||||
{
|
||||
//
|
||||
// Process CSD version override
|
||||
//
|
||||
if (ImageConfigData->CSDVersion)
|
||||
{
|
||||
//
|
||||
// Set new data
|
||||
//
|
||||
Peb->OSCSDVersion = ImageConfigData->CSDVersion;
|
||||
}
|
||||
|
||||
//
|
||||
// Process affinity mask ovverride
|
||||
//
|
||||
if (ImageConfigData->ProcessAffinityMask)
|
||||
{
|
||||
//
|
||||
// Set new data
|
||||
//
|
||||
ProcessAffinityMask = ImageConfigData->ProcessAffinityMask;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check if this is a UP image
|
||||
if (Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY)
|
||||
{
|
||||
//
|
||||
// Force it to use CPU 0
|
||||
//
|
||||
Peb->ImageProcessAffinityMask = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Whatever was configured
|
||||
//
|
||||
Peb->ImageProcessAffinityMask = ProcessAffinityMask;
|
||||
}
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
//
|
||||
// Fail
|
||||
//
|
||||
KeDetachProcess();
|
||||
_SEH2_YIELD(return STATUS_INVALID_IMAGE_PROTECT);
|
||||
}
|
||||
_SEH2_END;
|
||||
}
|
||||
|
||||
//
|
||||
// Detach from the Process
|
||||
//
|
||||
KeDetachProcess();
|
||||
*BasePeb = Peb;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmCreateTeb(IN PEPROCESS Process,
|
||||
IN PCLIENT_ID ClientId,
|
||||
IN PINITIAL_TEB InitialTeb,
|
||||
OUT PTEB *BaseTeb)
|
||||
{
|
||||
PTEB Teb;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
*BaseTeb = NULL;
|
||||
|
||||
//
|
||||
// Attach to Target
|
||||
//
|
||||
KeAttachProcess(&Process->Pcb);
|
||||
|
||||
//
|
||||
// Allocate the TEB
|
||||
//
|
||||
Teb = MiCreatePebOrTeb(Process,
|
||||
(PVOID)((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1));
|
||||
if (!Teb) return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
//
|
||||
// Use SEH in case we can't load the TEB
|
||||
//
|
||||
_SEH2_TRY
|
||||
{
|
||||
//
|
||||
// Initialize the PEB
|
||||
//
|
||||
RtlZeroMemory(Teb, sizeof(TEB));
|
||||
|
||||
//
|
||||
// Set TIB Data
|
||||
//
|
||||
Teb->Tib.ExceptionList = EXCEPTION_CHAIN_END;
|
||||
Teb->Tib.Self = (PNT_TIB)Teb;
|
||||
|
||||
//
|
||||
// Identify this as an OS/2 V3.0 ("Cruiser") TIB
|
||||
//
|
||||
Teb->Tib.Version = 30 << 8;
|
||||
|
||||
//
|
||||
// Set TEB Data
|
||||
//
|
||||
Teb->ClientId = *ClientId;
|
||||
Teb->RealClientId = *ClientId;
|
||||
Teb->ProcessEnvironmentBlock = Process->Peb;
|
||||
Teb->CurrentLocale = PsDefaultThreadLocaleId;
|
||||
|
||||
//
|
||||
// Check if we have a grandparent TEB
|
||||
//
|
||||
if ((InitialTeb->PreviousStackBase == NULL) &&
|
||||
(InitialTeb->PreviousStackLimit == NULL))
|
||||
{
|
||||
//
|
||||
// Use grandparent TEB values
|
||||
//
|
||||
Teb->Tib.StackBase = InitialTeb->PreviousStackBase;
|
||||
Teb->Tib.StackLimit = InitialTeb->PreviousStackLimit;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Use initial TEB values
|
||||
//
|
||||
Teb->Tib.StackBase = InitialTeb->StackBase;
|
||||
Teb->Tib.StackLimit = InitialTeb->StackLimit;
|
||||
Teb->DeallocationStack = InitialTeb->AllocatedStackBase;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the static unicode string
|
||||
//
|
||||
Teb->StaticUnicodeString.MaximumLength = sizeof(Teb->StaticUnicodeBuffer);
|
||||
Teb->StaticUnicodeString.Buffer = Teb->StaticUnicodeBuffer;
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
//
|
||||
// Get error code
|
||||
//
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
//
|
||||
// Return
|
||||
//
|
||||
KeDetachProcess();
|
||||
*BaseTeb = Teb;
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* SYSTEM CALLS ***************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtAllocateUserPhysicalPages(IN HANDLE ProcessHandle,
|
||||
IN OUT PULONG_PTR NumberOfPages,
|
||||
IN OUT PULONG_PTR UserPfnArray)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtMapUserPhysicalPages(IN PVOID VirtualAddresses,
|
||||
IN ULONG_PTR NumberOfPages,
|
||||
IN OUT PULONG_PTR UserPfnArray)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtMapUserPhysicalPagesScatter(IN PVOID *VirtualAddresses,
|
||||
IN ULONG_PTR NumberOfPages,
|
||||
IN OUT PULONG_PTR UserPfnArray)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtFreeUserPhysicalPages(IN HANDLE ProcessHandle,
|
||||
IN OUT PULONG_PTR NumberOfPages,
|
||||
IN OUT PULONG_PTR UserPfnArray)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -13,67 +13,8 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
extern ULONG NtMajorVersion;
|
||||
extern ULONG NtMinorVersion;
|
||||
extern ULONG CmNtCSDVersion;
|
||||
extern ULONG NtBuildNumber;
|
||||
extern MM_SYSTEMSIZE MmSystemSize;
|
||||
|
||||
#define MM_HIGHEST_VAD_ADDRESS \
|
||||
(PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE))
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmSetMemoryPriorityProcess(IN PEPROCESS Process,
|
||||
IN UCHAR MemoryPriority)
|
||||
{
|
||||
UCHAR OldPriority;
|
||||
|
||||
/* Check if we have less then 16MB of Physical Memory */
|
||||
if ((MmSystemSize == MmSmallSystem) &&
|
||||
(MmStats.NrTotalPages < ((15 * 1024 * 1024) / PAGE_SIZE)))
|
||||
{
|
||||
/* Always use background priority */
|
||||
MemoryPriority = 0;
|
||||
}
|
||||
|
||||
/* Save the old priority and update it */
|
||||
OldPriority = (UCHAR)Process->Vm.Flags.MemoryPriority;
|
||||
Process->Vm.Flags.MemoryPriority = MemoryPriority;
|
||||
|
||||
/* Return the old priority */
|
||||
return OldPriority;
|
||||
}
|
||||
|
||||
LCID
|
||||
NTAPI
|
||||
MmGetSessionLocaleId(VOID)
|
||||
{
|
||||
PEPROCESS Process;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Get the current process */
|
||||
Process = PsGetCurrentProcess();
|
||||
|
||||
/* Check if it's the Session Leader */
|
||||
if (Process->Vm.Flags.SessionLeader)
|
||||
{
|
||||
/* Make sure it has a valid Session */
|
||||
if (Process->Session)
|
||||
{
|
||||
/* Get the Locale ID */
|
||||
#if ROS_HAS_SESSIONS
|
||||
return ((PMM_SESSION_SPACE)Process->Session)->LocaleId;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Not a session leader, return the default */
|
||||
return PsDefaultThreadLocaleId;
|
||||
}
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
MiCreatePebOrTeb(PEPROCESS Process,
|
||||
|
@ -148,211 +89,6 @@ MmDeleteTeb(PEPROCESS Process,
|
|||
MmUnlockAddressSpace(ProcessAddressSpace);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmCreatePeb(PEPROCESS Process)
|
||||
{
|
||||
PPEB Peb = NULL;
|
||||
LARGE_INTEGER SectionOffset;
|
||||
SIZE_T ViewSize = 0;
|
||||
PVOID TableBase = NULL;
|
||||
PIMAGE_NT_HEADERS NtHeaders;
|
||||
PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigData;
|
||||
NTSTATUS Status;
|
||||
KAFFINITY ProcessAffinityMask = 0;
|
||||
SectionOffset.QuadPart = (ULONGLONG)0;
|
||||
DPRINT("MmCreatePeb\n");
|
||||
|
||||
/* Allocate the PEB */
|
||||
Peb = MiCreatePebOrTeb(Process,
|
||||
(PVOID)((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1));
|
||||
ASSERT(Peb == (PVOID)0x7FFDF000);
|
||||
|
||||
/* Map NLS Tables */
|
||||
DPRINT("Mapping NLS\n");
|
||||
Status = MmMapViewOfSection(ExpNlsSectionPointer,
|
||||
(PEPROCESS)Process,
|
||||
&TableBase,
|
||||
0,
|
||||
0,
|
||||
&SectionOffset,
|
||||
&ViewSize,
|
||||
ViewShare,
|
||||
MEM_TOP_DOWN,
|
||||
PAGE_READONLY);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("MmMapViewOfSection() failed (Status %lx)\n", Status);
|
||||
return(Status);
|
||||
}
|
||||
DPRINT("TableBase %p ViewSize %lx\n", TableBase, ViewSize);
|
||||
|
||||
/* Attach to Process */
|
||||
KeAttachProcess(&Process->Pcb);
|
||||
|
||||
/* Initialize the PEB */
|
||||
DPRINT("Allocated: %x\n", Peb);
|
||||
RtlZeroMemory(Peb, sizeof(PEB));
|
||||
|
||||
/* Set up data */
|
||||
DPRINT("Setting up PEB\n");
|
||||
Peb->ImageBaseAddress = Process->SectionBaseAddress;
|
||||
Peb->InheritedAddressSpace = 0;
|
||||
Peb->Mutant = NULL;
|
||||
|
||||
/* NLS */
|
||||
Peb->AnsiCodePageData = (PCHAR)TableBase + ExpAnsiCodePageDataOffset;
|
||||
Peb->OemCodePageData = (PCHAR)TableBase + ExpOemCodePageDataOffset;
|
||||
Peb->UnicodeCaseTableData = (PCHAR)TableBase + ExpUnicodeCaseTableDataOffset;
|
||||
|
||||
/* Default Version Data (could get changed below) */
|
||||
Peb->OSMajorVersion = NtMajorVersion;
|
||||
Peb->OSMinorVersion = NtMinorVersion;
|
||||
Peb->OSBuildNumber = (USHORT)(NtBuildNumber & 0x3FFF);
|
||||
Peb->OSPlatformId = 2; /* VER_PLATFORM_WIN32_NT */
|
||||
Peb->OSCSDVersion = (USHORT)CmNtCSDVersion;
|
||||
|
||||
/* Heap and Debug Data */
|
||||
Peb->NumberOfProcessors = KeNumberProcessors;
|
||||
Peb->BeingDebugged = (BOOLEAN)(Process->DebugPort != NULL ? TRUE : FALSE);
|
||||
Peb->NtGlobalFlag = NtGlobalFlag;
|
||||
/*Peb->HeapSegmentReserve = MmHeapSegmentReserve;
|
||||
Peb->HeapSegmentCommit = MmHeapSegmentCommit;
|
||||
Peb->HeapDeCommitTotalFreeThreshold = MmHeapDeCommitTotalFreeThreshold;
|
||||
Peb->HeapDeCommitFreeBlockThreshold = MmHeapDeCommitFreeBlockThreshold;*/
|
||||
Peb->NumberOfHeaps = 0;
|
||||
Peb->MaximumNumberOfHeaps = (PAGE_SIZE - sizeof(PEB)) / sizeof(PVOID);
|
||||
Peb->ProcessHeaps = (PVOID*)(Peb + 1);
|
||||
|
||||
/* Image Data */
|
||||
if ((NtHeaders = RtlImageNtHeader(Peb->ImageBaseAddress)))
|
||||
{
|
||||
/* Write subsystem data */
|
||||
Peb->ImageSubSystem = NtHeaders->OptionalHeader.Subsystem;
|
||||
Peb->ImageSubSystemMajorVersion = NtHeaders->OptionalHeader.MajorSubsystemVersion;
|
||||
Peb->ImageSubSystemMinorVersion = NtHeaders->OptionalHeader.MinorSubsystemVersion;
|
||||
|
||||
/* Write Version Data */
|
||||
if (NtHeaders->OptionalHeader.Win32VersionValue)
|
||||
{
|
||||
Peb->OSMajorVersion = NtHeaders->OptionalHeader.Win32VersionValue & 0xFF;
|
||||
Peb->OSMinorVersion = (NtHeaders->OptionalHeader.Win32VersionValue >> 8) & 0xFF;
|
||||
Peb->OSBuildNumber = (NtHeaders->OptionalHeader.Win32VersionValue >> 16) & 0x3FFF;
|
||||
|
||||
/* Set the Platform ID */
|
||||
Peb->OSPlatformId = (NtHeaders->OptionalHeader.Win32VersionValue >> 30) ^ 2;
|
||||
}
|
||||
|
||||
/* Check if the image is not safe for SMP */
|
||||
if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY)
|
||||
{
|
||||
/* FIXME: Choose one randomly */
|
||||
Peb->ImageProcessAffinityMask = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use affinity from Image Header */
|
||||
Peb->ImageProcessAffinityMask = ProcessAffinityMask;
|
||||
}
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* Get the Image Config Data too */
|
||||
ImageConfigData = RtlImageDirectoryEntryToData(Peb->ImageBaseAddress,
|
||||
TRUE,
|
||||
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG,
|
||||
&ViewSize);
|
||||
|
||||
ProbeForRead(ImageConfigData,
|
||||
sizeof(IMAGE_LOAD_CONFIG_DIRECTORY),
|
||||
sizeof(ULONG));
|
||||
|
||||
/* Process the image config data overrides if specfied. */
|
||||
if (ImageConfigData != NULL)
|
||||
{
|
||||
if (ImageConfigData->CSDVersion)
|
||||
{
|
||||
Peb->OSCSDVersion = ImageConfigData->CSDVersion;
|
||||
}
|
||||
if (ImageConfigData->ProcessAffinityMask)
|
||||
{
|
||||
ProcessAffinityMask = ImageConfigData->ProcessAffinityMask;
|
||||
}
|
||||
}
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END;
|
||||
}
|
||||
|
||||
/* Misc data */
|
||||
Peb->SessionId = Process->Session;
|
||||
Process->Peb = Peb;
|
||||
|
||||
/* Detach from the Process */
|
||||
KeDetachProcess();
|
||||
|
||||
DPRINT("MmCreatePeb: Peb created at %p\n", Peb);
|
||||
return Status;
|
||||
}
|
||||
|
||||
PTEB
|
||||
NTAPI
|
||||
MmCreateTeb(PEPROCESS Process,
|
||||
PCLIENT_ID ClientId,
|
||||
PINITIAL_TEB InitialTeb)
|
||||
{
|
||||
PTEB Teb;
|
||||
BOOLEAN Attached = FALSE;
|
||||
|
||||
/* Attach to the process */
|
||||
DPRINT("MmCreateTeb\n");
|
||||
if (Process != PsGetCurrentProcess())
|
||||
{
|
||||
/* Attach to Target */
|
||||
KeAttachProcess(&Process->Pcb);
|
||||
Attached = TRUE;
|
||||
}
|
||||
|
||||
/* Allocate the TEB */
|
||||
Teb = MiCreatePebOrTeb(Process,
|
||||
(PVOID)((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1));
|
||||
|
||||
/* Initialize the PEB */
|
||||
RtlZeroMemory(Teb, sizeof(TEB));
|
||||
|
||||
/* Set TIB Data */
|
||||
Teb->Tib.ExceptionList = (PVOID)0xFFFFFFFF;
|
||||
Teb->Tib.Version = 1;
|
||||
Teb->Tib.Self = (PNT_TIB)Teb;
|
||||
|
||||
/* Set TEB Data */
|
||||
Teb->ClientId = *ClientId;
|
||||
Teb->RealClientId = *ClientId;
|
||||
Teb->ProcessEnvironmentBlock = Process->Peb;
|
||||
Teb->CurrentLocale = PsDefaultThreadLocaleId;
|
||||
|
||||
/* Store stack information from InitialTeb */
|
||||
if(InitialTeb != NULL)
|
||||
{
|
||||
Teb->Tib.StackBase = InitialTeb->StackBase;
|
||||
Teb->Tib.StackLimit = InitialTeb->StackLimit;
|
||||
Teb->DeallocationStack = InitialTeb->AllocatedStackBase;
|
||||
}
|
||||
|
||||
/* Initialize the static unicode string */
|
||||
Teb->StaticUnicodeString.Length = 0;
|
||||
Teb->StaticUnicodeString.MaximumLength = sizeof(Teb->StaticUnicodeBuffer);
|
||||
Teb->StaticUnicodeString.Buffer = Teb->StaticUnicodeBuffer;
|
||||
|
||||
/* Return TEB Address */
|
||||
DPRINT("Allocated: %x\n", Teb);
|
||||
if (Attached) KeDetachProcess();
|
||||
return Teb;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmInitializeHandBuiltProcess2(IN PEPROCESS Process)
|
||||
|
|
|
@ -5070,46 +5070,6 @@ MmCreateSection (OUT PVOID * Section,
|
|||
AllocationAttributes));
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtAllocateUserPhysicalPages(IN HANDLE ProcessHandle,
|
||||
IN OUT PULONG_PTR NumberOfPages,
|
||||
IN OUT PULONG_PTR UserPfnArray)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtMapUserPhysicalPages(IN PVOID VirtualAddresses,
|
||||
IN ULONG_PTR NumberOfPages,
|
||||
IN OUT PULONG_PTR UserPfnArray)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtMapUserPhysicalPagesScatter(IN PVOID *VirtualAddresses,
|
||||
IN ULONG_PTR NumberOfPages,
|
||||
IN OUT PULONG_PTR UserPfnArray)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtFreeUserPhysicalPages(IN HANDLE ProcessHandle,
|
||||
IN OUT PULONG_PTR NumberOfPages,
|
||||
IN OUT PULONG_PTR UserPfnArray)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtAreMappedFilesTheSame(IN PVOID File1MappedAsAnImage,
|
||||
|
|
|
@ -379,6 +379,8 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
|
|||
BOOLEAN Result, SdAllocated;
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor;
|
||||
SECURITY_SUBJECT_CONTEXT SubjectContext;
|
||||
BOOLEAN NeedsPeb = FALSE;
|
||||
INITIAL_PEB InitialPeb;
|
||||
PAGED_CODE();
|
||||
PSTRACE(PS_PROCESS_DEBUG,
|
||||
"ProcessHandle: %p Parent: %p\n", ProcessHandle, ParentProcess);
|
||||
|
@ -635,17 +637,27 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
|
|||
SeAuditProcessCreationInfo.
|
||||
ImageFileName);
|
||||
if (!NT_SUCCESS(Status)) goto CleanupWithRef;
|
||||
|
||||
//
|
||||
// We need a PEB
|
||||
//
|
||||
NeedsPeb = TRUE;
|
||||
}
|
||||
else if (Parent)
|
||||
{
|
||||
/* Check if this is a child of the system process */
|
||||
if (Parent != PsInitialSystemProcess)
|
||||
{
|
||||
//
|
||||
// We need a PEB
|
||||
//
|
||||
NeedsPeb = TRUE;
|
||||
|
||||
/* This is a clone! */
|
||||
ASSERTMSG("No support for cloning yet\n", FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
/* This is the initial system process */
|
||||
Flags &= ~PS_LARGE_PAGES;
|
||||
Status = MmInitializeProcessAddressSpace(Process,
|
||||
|
@ -702,11 +714,34 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
|
|||
}
|
||||
|
||||
/* Create PEB only for User-Mode Processes */
|
||||
if (Parent)
|
||||
if ((Parent) && (NeedsPeb))
|
||||
{
|
||||
/* Create it */
|
||||
Status = MmCreatePeb(Process);
|
||||
if (!NT_SUCCESS(Status)) goto CleanupWithRef;
|
||||
//
|
||||
// Set up the initial PEB
|
||||
//
|
||||
RtlZeroMemory(&InitialPeb, sizeof(INITIAL_PEB));
|
||||
InitialPeb.Mutant = (HANDLE)-1;
|
||||
InitialPeb.ImageUsesLargePages = 0; // FIXME: Not yet supported
|
||||
|
||||
//
|
||||
// Create it only if we have an image section
|
||||
//
|
||||
if (SectionHandle)
|
||||
{
|
||||
//
|
||||
// Create it
|
||||
//
|
||||
Status = MmCreatePeb(Process, &InitialPeb, &Process->Peb);
|
||||
if (!NT_SUCCESS(Status)) goto CleanupWithRef;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// We have to clone it
|
||||
//
|
||||
ASSERTMSG("No support for cloning yet\n", FALSE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* The process can now be activated */
|
||||
|
|
|
@ -310,13 +310,13 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
|
|||
if (ThreadContext)
|
||||
{
|
||||
/* User-mode Thread, create Teb */
|
||||
TebBase = MmCreateTeb(Process, &Thread->Cid, InitialTeb);
|
||||
if (!TebBase)
|
||||
Status = MmCreateTeb(Process, &Thread->Cid, InitialTeb, &TebBase);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Failed to create the TEB. Release rundown and dereference */
|
||||
ExReleaseRundownProtection(&Process->RundownProtect);
|
||||
ObDereferenceObject(Thread);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set the Start Addresses */
|
||||
|
|
Loading…
Reference in a new issue