mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +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;
|
||||
FinalFreeSpace.QuadPart = FreeSpace.QuadPart * SizeInfo.BytesPerSector;
|
||||
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.SectorsPerAllocationUnit,
|
||||
SizeInfo.BytesPerSector);
|
||||
|
@ -592,7 +592,13 @@ SmpCreatePagingFileOnFixedDrive(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor,
|
|||
if (Descriptor->ActualMinSize.QuadPart < MinimumSize->QuadPart)
|
||||
{
|
||||
/* 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",
|
||||
Descriptor->ActualMinSize.QuadPart,
|
||||
Descriptor->ActualMaxSize.QuadPart,
|
||||
|
|
|
@ -1755,13 +1755,31 @@ SSI_DEF(SystemSetTimeSlipEvent)
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmSessionCreate(OUT PULONG SessionId);
|
||||
|
||||
/* Class 47 - Create a new session (TSE) */
|
||||
SSI_DEF(SystemCreateSession)
|
||||
{
|
||||
/* FIXME */
|
||||
DPRINT1("NtSetSystemInformation - SystemCreateSession not implemented\n");
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
ULONG SessionId;
|
||||
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
|
||||
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
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MiInitializeSessionIds(
|
||||
VOID
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
MiInitializeMemoryEvents(
|
||||
|
|
|
@ -1340,6 +1340,144 @@ MmCleanProcessAddressSpace(IN PEPROCESS Process)
|
|||
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 ***************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
|
|
|
@ -437,6 +437,9 @@ MmInitSystem(IN ULONG Phase,
|
|||
PageFrameNumber);
|
||||
*MmSharedUserDataPte = TempPte;
|
||||
|
||||
/* Setup session IDs */
|
||||
MiInitializeSessionIds();
|
||||
|
||||
/* Setup the memory threshold events */
|
||||
if (!MiInitializeMemoryEvents()) return FALSE;
|
||||
|
||||
|
|
Loading…
Reference in a new issue