Author: tkreuzer
Date: Thu Feb 9 12:04:31 2012
New Revision: 55513
URL: http://svn.reactos.org/svn/reactos?rev=55513&view=rev
Log:
[NTOSKRNL]
Use MiNonPagedSystemSize when creating the system NP memory area instead of making assumptions about the memory layout
Finally the amd64 port boots into usermode and usetup is partly working, formats the harddisk but freezes, when copying files.
Modified:
trunk/reactos/ntoskrnl/mm/mminit.c
Modified: trunk/reactos/ntoskrnl/mm/mminit.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/mminit.c?rev=5…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] Thu Feb 9 12:04:31 2012
@@ -126,8 +126,7 @@
Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC,
&BaseAddress,
- (ULONG_PTR)MmNonPagedPoolEnd -
- (ULONG_PTR)MmNonPagedSystemStart,
+ MiNonPagedSystemSize,
PAGE_READWRITE,
&MArea,
TRUE,
Author: ion
Date: Thu Feb 9 02:21:56 2012
New Revision: 55509
URL: http://svn.reactos.org/svn/reactos?rev=55509&view=rev
Log:
[SMSS2]: Implement SmpCallCsrCreateProcess and SmpLoadSubsystem. We now load CSRSS and everything works 100%! Winlogon is now launched by SMSS2 and no regressions have been found.
[SMSS]: Turn off all code other than setting up the pagefile.
There's a lot of debug prints, as soon as things seem stable after a few days, SMSS will be gone and SMSS2 will take over and DPRINT1s will mostly be gone.
Modified:
trunk/reactos/base/system/smss/init.c
trunk/reactos/base/system/smss2/smsubsys.c
Modified: trunk/reactos/base/system/smss/init.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss/init.c?re…
==============================================================================
--- trunk/reactos/base/system/smss/init.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/smss/init.c [iso-8859-1] Thu Feb 9 02:21:56 2012
@@ -24,8 +24,8 @@
} InitRoutine [] = {
{TRUE, SmCreateHeap, "create private heap, aborting"},
// {TRUE, SmCreateObjectDirectories, "create object directories"},
- {TRUE, SmCreateApiPort, "create \\SmApiPort"},
- {TRUE, SmCreateEnvironment, "create the system environment"},
+// {TRUE, SmCreateApiPort, "create \\SmApiPort"},
+// {TRUE, SmCreateEnvironment, "create the system environment"},
// {TRUE, SmSetEnvironmentVariables, "set system environment variables"},
// {TRUE, SmInitDosDevices, "create dos device links"},
// {TRUE, SmRunBootApplications, "run boot applications"},
@@ -34,8 +34,8 @@
// {FALSE, SmLoadKnownDlls, "preload system DLLs"},
{TRUE, SmCreatePagingFiles, "create paging files"},
// {TRUE, SmInitializeRegistry, "initialize the registry"},
- {TRUE, SmInitializeClientManagement, "initialize client management"},
- {TRUE, SmLoadSubsystems, "load subsystems"}
+// {TRUE, SmInitializeClientManagement, "initialize client management"},
+// {TRUE, SmLoadSubsystems, "load subsystems"}
};
NTSTATUS
Modified: trunk/reactos/base/system/smss2/smsubsys.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/smsubsys…
==============================================================================
--- trunk/reactos/base/system/smss2/smsubsys.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/smss2/smsubsys.c [iso-8859-1] Thu Feb 9 02:21:56 2012
@@ -23,6 +23,24 @@
/* FUNCTIONS ******************************************************************/
+NTSTATUS
+NTAPI
+SmpCallCsrCreateProcess(IN PSB_API_MSG SbApiMsg,
+ IN USHORT MessageLength,
+ IN HANDLE PortHandle)
+{
+ NTSTATUS Status;
+
+ /* Initialize the header and send the message to CSRSS */
+ SbApiMsg->h.u2.ZeroInit = 0;
+ SbApiMsg->h.u1.s1.DataLength = MessageLength + 8;
+ SbApiMsg->h.u1.s1.TotalLength = sizeof(SB_API_MSG);
+ SbApiMsg->ApiNumber = SbpCreateProcess;
+ Status = NtRequestWaitReplyPort(PortHandle, &SbApiMsg->h, &SbApiMsg->h);
+ if (NT_SUCCESS(Status)) Status = SbApiMsg->ReturnValue;
+ return Status;
+}
+
VOID
NTAPI
SmpDereferenceSubsystem(IN PSMP_SUBSYSTEM SubSystem)
@@ -60,7 +78,7 @@
{
/* Check if this one matches the client ID and is still valid */
Subsystem = CONTAINING_RECORD(NextEntry, SMP_SUBSYSTEM, Entry);
- if ((*(PULONGLONG)&Subsystem->ClientId == *(PULONGLONG)&ClientId) &&
+ if ((*(PULONGLONG)&Subsystem->ClientId == *(PULONGLONG)ClientId) &&
!(Subsystem->Terminating))
{
/* Add a reference and return it */
@@ -123,8 +141,378 @@
OUT PHANDLE ProcessId,
IN ULONG Flags)
{
- DPRINT1("Should start subsystem %wZ for Session: %lx\n", FileName, MuSessionId);
- return STATUS_SUCCESS;
+ PSMP_SUBSYSTEM Subsystem, NewSubsystem, KnownSubsystem = NULL;
+ HANDLE SubSysProcessId;
+ NTSTATUS Status = STATUS_SUCCESS;
+ SB_API_MSG SbApiMsg, SbApiMsg2;
+ RTL_USER_PROCESS_INFORMATION ProcessInformation;
+ LARGE_INTEGER Timeout;
+ PVOID State;
+ PSB_CREATE_PROCESS_MSG CreateProcess = &SbApiMsg.CreateProcess;
+ PSB_CREATE_SESSION_MSG CreateSession = &SbApiMsg.CreateSession;
+ DPRINT1("Loading subsystem: %wZ\n", FileName);
+
+ /* Make sure this is a found subsystem */
+ if (Flags & SMP_INVALID_PATH)
+ {
+ DPRINT1("SMSS: Unable to find subsystem - %wZ\n", FileName);
+ return STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ /* Don't use a session if the flag is set */
+ if (Flags & 0x80) MuSessionId = 0;
+
+ /* Lock the subsystems while we do a look up */
+ RtlEnterCriticalSection(&SmpKnownSubSysLock);
+ while (TRUE)
+ {
+ /* Check if we found a subsystem not yet fully iniitalized */
+ Subsystem = SmpLocateKnownSubSysByType(MuSessionId, -1);
+ if (!Subsystem) break;
+ RtlLeaveCriticalSection(&SmpKnownSubSysLock);
+
+ /* Wait on it to initialize */
+ NtWaitForSingleObject(Subsystem->Event, FALSE, NULL);
+
+ /* Dereference it and try the next one */
+ RtlEnterCriticalSection(&SmpKnownSubSysLock);
+ SmpDereferenceSubsystem(Subsystem);
+ }
+
+ /* Check if this is a POSIX subsystem */
+ if (Flags & SMP_POSIX_FLAG)
+ {
+ /* Do we already have it? */
+ Subsystem = SmpLocateKnownSubSysByType(MuSessionId, IMAGE_SUBSYSTEM_POSIX_CUI);
+ }
+ else if (Flags & SMP_OS2_FLAG)
+ {
+ /* This is an OS/2 subsystem, do we we already have it? */
+ Subsystem = SmpLocateKnownSubSysByType(MuSessionId, IMAGE_SUBSYSTEM_OS2_CUI);
+ }
+
+ /* Check if we already have one of the optional subsystems for the session */
+ if (Subsystem)
+ {
+ /* Dereference and return, no work to do */
+ SmpDereferenceSubsystem(Subsystem);
+ RtlLeaveCriticalSection(&SmpKnownSubSysLock);
+ return STATUS_SUCCESS;
+ }
+
+ /* Allocate a new subsystem! */
+ NewSubsystem = RtlAllocateHeap(SmpHeap, SmBaseTag, sizeof(SMP_SUBSYSTEM));
+ DPRINT1("new subsystem created: %p\n", NewSubsystem);
+ if (!NewSubsystem)
+ {
+ RtlLeaveCriticalSection(&SmpKnownSubSysLock);
+ return STATUS_NO_MEMORY;
+ }
+
+ /* Initialize its header and reference count */
+ NewSubsystem->ReferenceCount = 1;
+ NewSubsystem->MuSessionId = MuSessionId;
+ NewSubsystem->ImageType = -1;
+
+ /* Clear out all the other data for now */
+ NewSubsystem->Terminating = FALSE;
+ NewSubsystem->ProcessHandle = NULL;
+ NewSubsystem->Event = NULL;
+ NewSubsystem->PortHandle = NULL;
+ NewSubsystem->SbApiPort = NULL;
+
+ /* Create the event we'll be wating on for initialization */
+ Status = NtCreateEvent(&NewSubsystem->Event,
+ EVENT_ALL_ACCESS,
+ NULL,
+ NotificationEvent,
+ FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ /* This failed, bail out */
+ RtlFreeHeap(SmpHeap, 0, NewSubsystem);
+ RtlLeaveCriticalSection(&SmpKnownSubSysLock);
+ return STATUS_NO_MEMORY;
+ }
+
+ /* Insert the subsystem and release the lock. It can now be found */
+ InsertTailList(&SmpKnownSubSysHead, &NewSubsystem->Entry);
+ RtlLeaveCriticalSection(&SmpKnownSubSysLock);
+
+ /* The OS/2 and POSIX subsystems are actually Windows applications! */
+ if (Flags & (SMP_POSIX_FLAG | SMP_OS2_FLAG))
+ {
+ /* Locate the Windows subsystem for this session */
+ KnownSubsystem = SmpLocateKnownSubSysByType(MuSessionId,
+ IMAGE_SUBSYSTEM_WINDOWS_GUI);
+ if (!KnownSubsystem)
+ {
+ DPRINT1("SMSS: SmpLoadSubSystem - SmpLocateKnownSubSysByType Failed\n");
+ goto Quickie2;
+ }
+
+ /* Fill out all the process details and call CSRSS to launch it */
+ CreateProcess->In.ImageName = FileName;
+ CreateProcess->In.CurrentDirectory = Directory;
+ CreateProcess->In.CommandLine = CommandLine;
+ CreateProcess->In.DllPath = SmpDefaultLibPath.Length ?
+ &SmpDefaultLibPath : NULL;
+ CreateProcess->In.Flags = Flags | SMP_DEFERRED_FLAG;
+ CreateProcess->In.DebugFlags = SmpDebug;
+ Status = SmpCallCsrCreateProcess(&SbApiMsg,
+ sizeof(*CreateProcess),
+ KnownSubsystem->SbApiPort);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Handle failures */
+ DPRINT1("SMSS: SmpLoadSubSystem - SmpCallCsrCreateProcess Failed with Status %lx\n",
+ Status);
+ goto Quickie2;
+ }
+
+ /* Save the process information we'll need for the create session */
+ ProcessInformation.ProcessHandle = CreateProcess->Out.ProcessHandle;
+ ProcessInformation.ThreadHandle = CreateProcess->Out.ThreadHandle;
+ ProcessInformation.ClientId = CreateProcess->Out.ClientId;
+ ProcessInformation.ImageInformation.SubSystemType = CreateProcess->Out.SubsystemType;
+ }
+ else
+ {
+ /* This must be CSRSS itself, so just launch it and that's it */
+ DPRINT1("Executing CSRSS\n");
+ Status = SmpExecuteImage(FileName,
+ Directory,
+ CommandLine,
+ MuSessionId,
+ Flags | SMP_DEFERRED_FLAG,
+ &ProcessInformation);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Handle failures */
+ DPRINT1("SMSS: SmpLoadSubSystem - SmpExecuteImage Failed with Status %lx\n",
+ Status);
+ goto Quickie2;
+ }
+ }
+
+ /* Fill out the handle and client ID in the subsystem structure now */
+ NewSubsystem->ProcessHandle = ProcessInformation.ProcessHandle;
+ NewSubsystem->ClientId = ProcessInformation.ClientId;
+
+ /* Check if we launched a native image or a subsystem-backed image */
+ if (ProcessInformation.ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_NATIVE)
+ {
+ /* This must be CSRSS itself, since it's a native subsystem image */
+ SubSysProcessId = ProcessInformation.ClientId.UniqueProcess;
+ if ((ProcessId) && !(*ProcessId)) *ProcessId = SubSysProcessId;
+
+ /* Was this the initial CSRSS on Session 0? */
+ if (!MuSessionId)
+ {
+ /* Then save it in the global variables */
+ SmpWindowsSubSysProcessId = SubSysProcessId;
+ SmpWindowsSubSysProcess = ProcessInformation.ProcessHandle;
+ }
+ ASSERT(NT_SUCCESS(Status));
+ DPRINT1("CSRSS is up and running: %lx %lx\n", SmpWindowsSubSysProcessId, SmpWindowsSubSysProcess);
+ }
+ else
+ {
+ /* This is the POSIX or OS/2 subsystem process, copy its information */
+ RtlCopyMemory(&CreateSession->ProcessInfo,
+ &ProcessInformation,
+ sizeof(&CreateSession->ProcessInfo));
+
+ /* Not sure these field mean what I think they do -- but clear them */
+ *(PULONGLONG)&CreateSession->ClientId = 0;
+ CreateSession->MuSessionId = 0;
+
+ /* This should find CSRSS because they are POSIX or OS/2 subsystems */
+ Subsystem = SmpLocateKnownSubSysByType(MuSessionId,
+ ProcessInformation.ImageInformation.SubSystemType);
+ if (!Subsystem)
+ {
+ /* Odd failure -- but handle it anyway */
+ Status = STATUS_NO_SUCH_PACKAGE;
+ DPRINT1("SMSS: SmpLoadSubSystem - SmpLocateKnownSubSysByType Failed with Status %lx for sessionid %ld\n",
+ Status,
+ MuSessionId);
+ goto Quickie;
+ }
+
+ /* Duplicate the parent process handle for the subsystem to have */
+ Status = NtDuplicateObject(NtCurrentProcess(),
+ ProcessInformation.ProcessHandle,
+ Subsystem->ProcessHandle,
+ &CreateSession->ProcessInfo.ProcessHandle,
+ PROCESS_ALL_ACCESS,
+ 0,
+ 0);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Fail since this is critical */
+ DPRINT1("SMSS: SmpLoadSubSystem - NtDuplicateObject Failed with Status %lx for sessionid %ld\n",
+ Status,
+ MuSessionId);
+ goto Quickie;
+ }
+
+ /* Duplicate the initial thread handle for the subsystem to have */
+ Status = NtDuplicateObject(NtCurrentProcess(),
+ ProcessInformation.ThreadHandle,
+ Subsystem->ProcessHandle,
+ &CreateSession->ProcessInfo.ThreadHandle,
+ THREAD_ALL_ACCESS,
+ 0,
+ 0);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Fail since this is critical */
+ DPRINT1("SMSS: SmpLoadSubSystem - NtDuplicateObject Failed with Status %lx for sessionid %ld\n",
+ Status,
+ MuSessionId);
+ goto Quickie;
+ }
+
+ /* Allocate an internal Session ID for this subsystem */
+ MuSessionId = SmpAllocateSessionId(Subsystem, 0);
+ CreateSession->SessionId = MuSessionId;
+
+ /* Send the create session message to the subsystem */
+ SbApiMsg2.ReturnValue = STATUS_SUCCESS;
+ SbApiMsg2.h.u2.ZeroInit = 0;
+ SbApiMsg2.h.u1.s1.DataLength = sizeof(SB_CREATE_SESSION_MSG) + 8;
+ SbApiMsg2.h.u1.s1.TotalLength = sizeof(SB_API_MSG);
+ Status = NtRequestWaitReplyPort(Subsystem->SbApiPort,
+ &SbApiMsg2.h,
+ &SbApiMsg2.h);
+ if (NT_SUCCESS(Status)) Status = SbApiMsg2.ReturnValue;
+ if (!NT_SUCCESS(Status))
+ {
+ /* Delete the session and handle failure if the LPC call failed */
+ SmpDeleteSession(CreateSession->SessionId);
+ DPRINT1("SMSS: SmpLoadSubSystem - NtRequestWaitReplyPort Failed with Status %lx for sessionid %ld\n",
+ Status,
+ CreateSession->SessionId);
+ goto Quickie;
+ }
+ }
+
+ /* Okay, everything looks good to go, initialize this subsystem now! */
+ DPRINT1("Resuming the subsystem!\n");
+ Status = NtResumeThread(ProcessInformation.ThreadHandle, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ /* That didn't work -- back out of everything */
+ DPRINT1("SMSS: SmpLoadSubSystem - NtResumeThread failed Status %lx\n", Status);
+ goto Quickie;
+ }
+
+ /* Check if this was the subsystem for a different session */
+ if (MuSessionId)
+ {
+ /* Wait up to 60 seconds for it to initialize */
+ Timeout.QuadPart = -600000000;
+ Status = NtWaitForSingleObject(NewSubsystem->Event, FALSE, &Timeout);
+
+ /* Timeout is done -- does this session still exist? */
+ if (!SmpCheckDuplicateMuSessionId(MuSessionId))
+ {
+ /* Nope, it died. Cleanup should've ocurred in a different path. */
+ DPRINT1("SMSS: SmpLoadSubSystem - session deleted\n");
+ return STATUS_DELETE_PENDING;
+ }
+
+ /* Check if we timed our or there was another error with the wait */
+ if (Status != STATUS_WAIT_0)
+ {
+ /* Something is wrong with the subsystem, so back out of everything */
+ DPRINT1("SMSS: SmpLoadSubSystem - Timeout waiting for subsystem connect with Status %lx for sessionid %ld\n",
+ Status,
+ MuSessionId);
+ goto Quickie;
+ }
+ }
+ else
+ {
+ /* This a session 0 subsystem, just wait for it to initialize */
+ DPRINT1("Waiting on the subsystem to initialize...\n");
+ NtWaitForSingleObject(NewSubsystem->Event, FALSE, NULL);
+ DPRINT1("Subsystem is ready!!!\n");
+ }
+
+ /* Subsystem is created, resumed, and initialized. Close handles and exit */
+ NtClose(ProcessInformation.ThreadHandle);
+ Status = STATUS_SUCCESS;
+ DPRINT1("Returning success\n");
+ goto Quickie2;
+
+Quickie:
+ /* This is the failure path. First check if we need to detach from session */
+ if ((AttachedSessionId == -1) || (Flags & (SMP_POSIX_FLAG | SMP_OS2_FLAG)))
+ {
+ /* We were not attached, or did not launch subsystems that required it */
+ DPRINT1("SMSS: Did not detach from Session Space: SessionId=%x Flags=%x Status=%x\n",
+ AttachedSessionId,
+ Flags | SMP_DEFERRED_FLAG,
+ Status);
+ }
+ else
+ {
+ /* Get the privilege we need for detachment */
+ Status = SmpAcquirePrivilege(SE_LOAD_DRIVER_PRIVILEGE, &State);
+ if (!NT_SUCCESS(Status))
+ {
+ /* We can't detach without it */
+ DPRINT1("SMSS: Did not detach from Session Space: SessionId=%x Flags=%x Status=%x\n",
+ AttachedSessionId,
+ Flags | SMP_DEFERRED_FLAG,
+ Status);
+ }
+ else
+ {
+ /* Now detach from the session */
+ Status = NtSetSystemInformation(SystemSessionDetach,
+ &AttachedSessionId,
+ sizeof(AttachedSessionId));
+ if (!NT_SUCCESS(Status))
+ {
+ /* Failed to detach. Note the DPRINT1 has a typo in Windows */
+ DPRINT1("SMSS: SmpStartCsr, Couldn't Detach from Session Space. Status=%x\n", Status);
+ ASSERT(NT_SUCCESS(Status));
+ }
+ else
+ {
+ /* Detachment worked, reset our attached session ID */
+ AttachedSessionId = -1;
+ }
+
+ /* And release the privilege we acquired */
+ SmpReleasePrivilege(State);
+ }
+ }
+
+ /* Since this is the failure path, terminate the subsystem process */
+ NtTerminateProcess(ProcessInformation.ProcessHandle, Status);
+ NtClose(ProcessInformation.ThreadHandle);
+
+Quickie2:
+ /* This is the cleanup path -- first dereference our subsystems */
+ RtlEnterCriticalSection(&SmpKnownSubSysLock);
+ if (Subsystem) SmpDereferenceSubsystem(Subsystem);
+ if (KnownSubsystem) SmpDereferenceSubsystem(KnownSubsystem);
+
+ /* In the failure case, destroy the new subsystem we just created */
+ if (!NT_SUCCESS(Status))
+ {
+ RemoveEntryList(&NewSubsystem->Entry);
+ NtSetEvent(NewSubsystem->Event, 0);
+ if (NewSubsystem) SmpDereferenceSubsystem(NewSubsystem);
+ }
+
+ /* Finally, we're all done! */
+ RtlLeaveCriticalSection(&SmpKnownSubSysLock);
+ return Status;
}
NTSTATUS