mirror of
https://github.com/reactos/reactos.git
synced 2025-07-23 12:54:02 +00:00
[NTOSKRNL]: Stubplement SystemSessionCreateInformation (it allocates a real Session ID and sets the right EPROCESS flags). Nobody uses this yet (future SMSS2 will).
[SMSS2]: More attempts at fixing KVM. svn path=/trunk/; revision=55464
This commit is contained in:
parent
1fbcc2809f
commit
5fb988c04d
5 changed files with 176 additions and 5 deletions
|
@ -395,7 +395,7 @@ SmpGetVolumeFreeSpace(IN PSMP_VOLUME_DESCRIPTOR Volume)
|
||||||
SizeInfo.SectorsPerAllocationUnit;
|
SizeInfo.SectorsPerAllocationUnit;
|
||||||
FinalFreeSpace.QuadPart = FreeSpace.QuadPart * SizeInfo.BytesPerSector;
|
FinalFreeSpace.QuadPart = FreeSpace.QuadPart * SizeInfo.BytesPerSector;
|
||||||
Volume->FreeSpace = FinalFreeSpace;
|
Volume->FreeSpace = FinalFreeSpace;
|
||||||
DPRINT1("AUs: %I64 Sectors: %lx Bytes Per Sector: %lx\n",
|
DPRINT1("AUs: %I64x Sectors: %lx Bytes Per Sector: %lx\n",
|
||||||
SizeInfo.AvailableAllocationUnits.QuadPart,
|
SizeInfo.AvailableAllocationUnits.QuadPart,
|
||||||
SizeInfo.SectorsPerAllocationUnit,
|
SizeInfo.SectorsPerAllocationUnit,
|
||||||
SizeInfo.BytesPerSector);
|
SizeInfo.BytesPerSector);
|
||||||
|
@ -592,7 +592,13 @@ SmpCreatePagingFileOnFixedDrive(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor,
|
||||||
if (Descriptor->ActualMinSize.QuadPart < MinimumSize->QuadPart)
|
if (Descriptor->ActualMinSize.QuadPart < MinimumSize->QuadPart)
|
||||||
{
|
{
|
||||||
/* Delete the current page file and fail */
|
/* Delete the current page file and fail */
|
||||||
if (ShouldDelete) SmpDeletePagingFile(&Descriptor->Name);
|
if (ShouldDelete)
|
||||||
|
{
|
||||||
|
SmpDeletePagingFile(&Descriptor->Name);
|
||||||
|
|
||||||
|
/* FIXFIX: Windows Vista does this, and it seems like we should too, so try to see if this fixes KVM */
|
||||||
|
Volume->FreeSpace.QuadPart += PageFileSize.QuadPart;
|
||||||
|
}
|
||||||
DPRINT1("SMSS:PFILE: Failing for min %I64X, max %I64X, real min %I64X \n",
|
DPRINT1("SMSS:PFILE: Failing for min %I64X, max %I64X, real min %I64X \n",
|
||||||
Descriptor->ActualMinSize.QuadPart,
|
Descriptor->ActualMinSize.QuadPart,
|
||||||
Descriptor->ActualMaxSize.QuadPart,
|
Descriptor->ActualMaxSize.QuadPart,
|
||||||
|
|
|
@ -1755,13 +1755,31 @@ SSI_DEF(SystemSetTimeSlipEvent)
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MmSessionCreate(OUT PULONG SessionId);
|
||||||
|
|
||||||
/* Class 47 - Create a new session (TSE) */
|
/* Class 47 - Create a new session (TSE) */
|
||||||
SSI_DEF(SystemCreateSession)
|
SSI_DEF(SystemCreateSession)
|
||||||
{
|
{
|
||||||
/* FIXME */
|
ULONG SessionId;
|
||||||
DPRINT1("NtSetSystemInformation - SystemCreateSession not implemented\n");
|
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
if (Size != sizeof(ULONG)) return STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
if (!SeSinglePrivilegeCheck(SeLoadDriverPrivilege, PreviousMode))
|
||||||
|
{
|
||||||
|
return STATUS_PRIVILEGE_NOT_HELD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = MmSessionCreate(&SessionId);
|
||||||
|
if (NT_SUCCESS(Status)) *(PULONG)Buffer = SessionId;
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -983,6 +983,12 @@ MiInitializePfnDatabase(
|
||||||
IN PLOADER_PARAMETER_BLOCK LoaderBlock
|
IN PLOADER_PARAMETER_BLOCK LoaderBlock
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
MiInitializeSessionIds(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
MiInitializeMemoryEvents(
|
MiInitializeMemoryEvents(
|
||||||
|
|
|
@ -1340,6 +1340,144 @@ MmCleanProcessAddressSpace(IN PEPROCESS Process)
|
||||||
MmUnlockAddressSpace(&Process->Vm);
|
MmUnlockAddressSpace(&Process->Vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SESSION CODE TO MOVE TO SESSION.C ******************************************/
|
||||||
|
|
||||||
|
KGUARDED_MUTEX MiSessionIdMutex;
|
||||||
|
PRTL_BITMAP MiSessionIdBitmap;
|
||||||
|
volatile LONG MiSessionLeaderExists;
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
MiInitializeSessionIds(VOID)
|
||||||
|
{
|
||||||
|
/* FIXME: Other stuff should go here */
|
||||||
|
|
||||||
|
/* Initialize the lock */
|
||||||
|
KeInitializeGuardedMutex(&MiSessionIdMutex);
|
||||||
|
|
||||||
|
/* Allocate the bitmap */
|
||||||
|
MiSessionIdBitmap = ExAllocatePoolWithTag(PagedPool,
|
||||||
|
sizeof(RTL_BITMAP) + ((64 + 31) / 32) * 4,
|
||||||
|
' mM');
|
||||||
|
if (MiSessionIdBitmap)
|
||||||
|
{
|
||||||
|
/* Free all the bits */
|
||||||
|
RtlInitializeBitMap(MiSessionIdBitmap, (PVOID)(MiSessionIdBitmap + 1), 64);
|
||||||
|
RtlClearAllBits(MiSessionIdBitmap);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Die if we couldn't allocate the bitmap */
|
||||||
|
KeBugCheckEx(INSTALL_MORE_MEMORY,
|
||||||
|
MmNumberOfPhysicalPages,
|
||||||
|
MmLowestPhysicalPage,
|
||||||
|
MmHighestPhysicalPage,
|
||||||
|
0x200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
MiSessionLeader(IN PEPROCESS Process)
|
||||||
|
{
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
/* Set the flag while under the expansion lock */
|
||||||
|
OldIrql = KeAcquireQueuedSpinLock(LockQueueExpansionLock);
|
||||||
|
Process->Vm.Flags.SessionLeader = TRUE;
|
||||||
|
KeReleaseQueuedSpinLock(LockQueueExpansionLock, OldIrql);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MiSessionCreateInternal(OUT PULONG SessionId)
|
||||||
|
{
|
||||||
|
PEPROCESS Process = PsGetCurrentProcess();
|
||||||
|
ULONG NewFlags, Flags;
|
||||||
|
|
||||||
|
/* Loop so we can set the session-is-creating flag */
|
||||||
|
Flags = Process->Flags;
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
/* Check if it's already set */
|
||||||
|
if (Flags & PSF_SESSION_CREATION_UNDERWAY_BIT)
|
||||||
|
{
|
||||||
|
/* Bail out */
|
||||||
|
DPRINT1("Lost session race\n");
|
||||||
|
return STATUS_ALREADY_COMMITTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now try to set it */
|
||||||
|
NewFlags = InterlockedCompareExchange((PLONG)&Process->Flags,
|
||||||
|
Flags | PSF_SESSION_CREATION_UNDERWAY_BIT,
|
||||||
|
Flags);
|
||||||
|
if (NewFlags == Flags) break;
|
||||||
|
|
||||||
|
/* It changed, try again */
|
||||||
|
Flags = NewFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we should own the flag */
|
||||||
|
ASSERT(Process->Flags & PSF_SESSION_CREATION_UNDERWAY_BIT);
|
||||||
|
|
||||||
|
/* Allocate a new Session ID */
|
||||||
|
KeAcquireGuardedMutex(&MiSessionIdMutex);
|
||||||
|
*SessionId = RtlFindClearBitsAndSet(MiSessionIdBitmap, 1, 0);
|
||||||
|
if (*SessionId == 0xFFFFFFFF)
|
||||||
|
{
|
||||||
|
DPRINT1("Too many sessions created. Expansion not yet supported\n");
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
KeReleaseGuardedMutex(&MiSessionIdMutex);
|
||||||
|
|
||||||
|
/* We're done, clear the flag */
|
||||||
|
ASSERT(Process->Flags & PSF_SESSION_CREATION_UNDERWAY_BIT);
|
||||||
|
PspClearProcessFlag(Process, PSF_SESSION_CREATION_UNDERWAY_BIT);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MmSessionCreate(OUT PULONG SessionId)
|
||||||
|
{
|
||||||
|
PEPROCESS Process = PsGetCurrentProcess();
|
||||||
|
ULONG SessionLeaderExists;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Fail if the process is already in a session */
|
||||||
|
if (Process->Flags & PSF_PROCESS_IN_SESSION_BIT)
|
||||||
|
{
|
||||||
|
DPRINT1("Process already in session\n");
|
||||||
|
return STATUS_ALREADY_COMMITTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if the process is already the session leader */
|
||||||
|
if (!Process->Vm.Flags.SessionLeader)
|
||||||
|
{
|
||||||
|
/* Atomically set it as the leader */
|
||||||
|
SessionLeaderExists = InterlockedCompareExchange(&MiSessionLeaderExists, 1, 0);
|
||||||
|
if (SessionLeaderExists)
|
||||||
|
{
|
||||||
|
DPRINT1("Session leader race\n");
|
||||||
|
return STATUS_INVALID_SYSTEM_SERVICE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do the work required to upgrade him */
|
||||||
|
MiSessionLeader(Process);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Actually create a session */
|
||||||
|
KeEnterCriticalRegion();
|
||||||
|
Status = MiSessionCreateInternal(SessionId);
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
|
/* Set and assert the flags, and return */
|
||||||
|
PspSetProcessFlag(Process, PSF_PROCESS_IN_SESSION_BIT);
|
||||||
|
ASSERT(MiSessionLeaderExists == 1);
|
||||||
|
if (NT_SUCCESS(Status)) DPRINT1("New session created: %lx\n", *SessionId);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* SYSTEM CALLS ***************************************************************/
|
/* SYSTEM CALLS ***************************************************************/
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -437,6 +437,9 @@ MmInitSystem(IN ULONG Phase,
|
||||||
PageFrameNumber);
|
PageFrameNumber);
|
||||||
*MmSharedUserDataPte = TempPte;
|
*MmSharedUserDataPte = TempPte;
|
||||||
|
|
||||||
|
/* Setup session IDs */
|
||||||
|
MiInitializeSessionIds();
|
||||||
|
|
||||||
/* Setup the memory threshold events */
|
/* Setup the memory threshold events */
|
||||||
if (!MiInitializeMemoryEvents()) return FALSE;
|
if (!MiInitializeMemoryEvents()) return FALSE;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue