From ddeb8354e491e7e66caa8b7844efc9a457c2d866 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 30 Jan 2012 05:32:34 +0000 Subject: [PATCH] [SMSS2]: Initialize a bunch more internal stuff, and start parsing the registry for settings. Right now just ProtectionMode and AllowProtectedRenames are parsed. Stub functions needed for the rest of initialization. Create the \Sessions directory. Hack to work under setup. Loop BootExecute and PageFile entries. Create SMSS environment. Detect MiniNT mode (PE/LiveCD). Delete SAFEBOOT_OPTION if found. svn path=/trunk/; revision=55317 --- reactos/base/system/smss2/pagefile.c | 26 +++ reactos/base/system/smss2/sminit.c | 328 ++++++++++++++++++++++++++- reactos/base/system/smss2/smsessn.c | 1 + reactos/base/system/smss2/smss.c | 13 +- reactos/base/system/smss2/smss.h | 46 +++- reactos/base/system/smss2/smsubsys.c | 12 +- 6 files changed, 418 insertions(+), 8 deletions(-) diff --git a/reactos/base/system/smss2/pagefile.c b/reactos/base/system/smss2/pagefile.c index 8678afa43b2..52a88672c58 100644 --- a/reactos/base/system/smss2/pagefile.c +++ b/reactos/base/system/smss2/pagefile.c @@ -14,4 +14,30 @@ /* GLOBALS ********************************************************************/ +LIST_ENTRY SmpPagingFileDescriptorList, SmpVolumeDescriptorList; + /* FUNCTIONS ******************************************************************/ + +VOID +NTAPI +SmpPagingFileInitialize(VOID) +{ + /* Initialize the two lists */ + InitializeListHead(&SmpPagingFileDescriptorList); + InitializeListHead(&SmpVolumeDescriptorList); +} + +NTSTATUS +NTAPI +SmpCreatePagingFileDescriptor(IN PUNICODE_STRING PageFileToken) +{ + DPRINT1("New pagefile data: %wZ\n", PageFileToken); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +SmpCreatePagingFiles(VOID) +{ + return STATUS_SUCCESS; +} diff --git a/reactos/base/system/smss2/sminit.c b/reactos/base/system/smss2/sminit.c index 06b35bf8891..23a45ca8c95 100644 --- a/reactos/base/system/smss2/sminit.c +++ b/reactos/base/system/smss2/sminit.c @@ -14,19 +14,37 @@ /* GLOBALS ********************************************************************/ +typedef struct _SMP_REGISTRY_VALUE +{ + LIST_ENTRY Entry; + UNICODE_STRING Name; + UNICODE_STRING Value; + PCHAR AnsiValue; +} SMP_REGISTRY_VALUE, *PSMP_REGISTRY_VALUE; + UNICODE_STRING SmpSubsystemName, PosixName, Os2Name; -LIST_ENTRY NativeProcessList; +UNICODE_STRING SmpDebugKeyword, SmpASyncKeyword, SmpAutoChkKeyword; +LIST_ENTRY SmpBootExecuteList, SmpSetupExecuteList, SmpPagingFileList; +LIST_ENTRY SmpDosDevicesList, SmpFileRenameList, SmpKnownDllsList; +LIST_ENTRY SmpExcludeKnownDllsList, SmpSubSystemList, SmpSubSystemsToLoad; +LIST_ENTRY SmpSubSystemsToDefer, SmpExecuteList, NativeProcessList; + ULONG SmBaseTag; -PVOID SmpHeap; HANDLE SmpDebugPort; +PVOID SmpHeap; +PWCHAR SmpDefaultEnvironment; + ULONG SmpInitProgressByLine; NTSTATUS SmpInitReturnStatus; PVOID SmpInitLastCall; + SECURITY_DESCRIPTOR SmpPrimarySDBody, SmpLiberalSDBody, SmpKnownDllsSDBody; SECURITY_DESCRIPTOR SmpApiPortSDBody; PSECURITY_DESCRIPTOR SmpPrimarySecurityDescriptor, SmpLiberalSecurityDescriptor; PSECURITY_DESCRIPTOR SmpKnownDllsSecurityDescriptor, SmpApiPortSecurityDescriptor; -ULONG SmpProtectionMode = 1; + +ULONG SmpAllowProtectedRenames, SmpProtectionMode = 1; +BOOLEAN MiniNTBoot; #define SMSS_CHECKPOINT(x, y) \ { \ @@ -35,6 +53,84 @@ ULONG SmpProtectionMode = 1; SmpInitLastCall = (x); \ } +/* REGISTRY CONFIGURATION *****************************************************/ + +NTSTATUS +NTAPI +SmpConfigureProtectionMode(IN PWSTR ValueName, + IN ULONG ValueType, + IN PVOID ValueData, + IN ULONG ValueLength, + IN PVOID Context, + IN PVOID EntryContext) +{ + /* Make sure the value is valid */ + if (ValueLength == sizeof(ULONG)) + { + /* Read it */ + SmpProtectionMode = *(PULONG)ValueData; + } + else + { + /* Default is to protect stuff */ + SmpProtectionMode = 1; + } + + /* Recreate the security descriptors to take into account security mode */ + SmpCreateSecurityDescriptors(FALSE); + DPRINT1("SmpProtectionMode: %d\n", SmpProtectionMode); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +SmpConfigureAllowProtectedRenames(IN PWSTR ValueName, + IN ULONG ValueType, + IN PVOID ValueData, + IN ULONG ValueLength, + IN PVOID Context, + IN PVOID EntryContext) +{ + /* Make sure the value is valid */ + if (ValueLength == sizeof(ULONG)) + { + /* Read it */ + SmpAllowProtectedRenames = *(PULONG)ValueData; + } + else + { + /* Default is to not allow protected renames */ + SmpAllowProtectedRenames = 0; + } + + DPRINT1("SmpAllowProtectedRenames: %d\n", SmpAllowProtectedRenames); + return STATUS_SUCCESS; +} + +RTL_QUERY_REGISTRY_TABLE +SmpRegistryConfigurationTable[] = +{ + { + SmpConfigureProtectionMode, + 0, + L"ProtectionMode", + NULL, + REG_DWORD, + NULL, + 0 + }, + { + SmpConfigureAllowProtectedRenames, + RTL_QUERY_REGISTRY_DELETE, + L"AllowProtectedRenames", + NULL, + REG_DWORD, + NULL, + 0 + }, + {0}, +}; + /* FUNCTIONS ******************************************************************/ NTSTATUS @@ -343,11 +439,233 @@ Quickie: NTSTATUS NTAPI -SmpLoadDataFromRegistry(OUT PUNICODE_STRING InitialCommand) +SmpInitializeDosDevices(VOID) { return STATUS_SUCCESS; } +NTSTATUS +NTAPI +SmpInitializeKnownDlls(VOID) +{ + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +SmpCreateDynamicEnvironmentVariables(VOID) +{ + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +SmpProcessFileRenames(VOID) +{ + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +SmpLoadDataFromRegistry(OUT PUNICODE_STRING InitialCommand) +{ + NTSTATUS Status; + PLIST_ENTRY Head, NextEntry; + PSMP_REGISTRY_VALUE RegEntry; + PVOID OriginalEnvironment; + ULONG MuSessionId = 0; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE KeyHandle; + UNICODE_STRING DestinationString; + + /* Initialize the keywords we'll be looking for */ + RtlInitUnicodeString(&SmpDebugKeyword, L"debug"); + RtlInitUnicodeString(&SmpASyncKeyword, L"async"); + RtlInitUnicodeString(&SmpAutoChkKeyword, L"autocheck"); + + /* Initialize all the registry-associated list heads */ + InitializeListHead(&SmpBootExecuteList); + InitializeListHead(&SmpSetupExecuteList); + InitializeListHead(&SmpPagingFileList); + InitializeListHead(&SmpDosDevicesList); + InitializeListHead(&SmpFileRenameList); + InitializeListHead(&SmpKnownDllsList); + InitializeListHead(&SmpExcludeKnownDllsList); + InitializeListHead(&SmpSubSystemList); + InitializeListHead(&SmpSubSystemsToLoad); + InitializeListHead(&SmpSubSystemsToDefer); + InitializeListHead(&SmpExecuteList); + SmpPagingFileInitialize(); + + /* Initialize the SMSS environment */ + Status = RtlCreateEnvironment(TRUE, &SmpDefaultEnvironment); + if (!NT_SUCCESS(Status)) + { + /* Fail if there was a problem */ + DPRINT1("SMSS: Unable to allocate default environment - Status == %X\n", + Status); + SMSS_CHECKPOINT(RtlCreateEnvironment, Status); + return Status; + } + + /* Check if we were booted in PE mode (LiveCD should have this) */ + RtlInitUnicodeString(&DestinationString, + L"\\Registry\\Machine\\System\\CurrentControlSet\\" + "Control\\MiniNT"); + InitializeObjectAttributes(&ObjectAttributes, + &DestinationString, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes); + if (NT_SUCCESS(Status)) + { + /* If the key exists, we were */ + NtClose(KeyHandle); + MiniNTBoot = TRUE; + } + + /* Print out if this is the case */ + if (MiniNTBoot) DPRINT1("SMSS: !!! MiniNT Boot !!!\n"); + + /* Open the environment key to see if we are booted in safe mode */ + RtlInitUnicodeString(&DestinationString, + L"\\Registry\\Machine\\System\\CurrentControlSet\\" + "Control\\Session Manager\\Environment"); + InitializeObjectAttributes(&ObjectAttributes, + &DestinationString, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes); + if (NT_SUCCESS(Status)) + { + /* Delete the value if we found it */ + RtlInitUnicodeString(&DestinationString, L"SAFEBOOT_OPTION"); + NtDeleteValueKey(KeyHandle, &DestinationString); + NtClose(KeyHandle); + } + + /* Switch environments, then query the registry for all needed settings */ + OriginalEnvironment = NtCurrentPeb()->ProcessParameters->Environment; + NtCurrentPeb()->ProcessParameters->Environment = SmpDefaultEnvironment; + Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL, + L"Session Manager", + SmpRegistryConfigurationTable, + NULL, + NULL); + SmpDefaultEnvironment = NtCurrentPeb()->ProcessParameters->Environment; + NtCurrentPeb()->ProcessParameters->Environment = OriginalEnvironment; + if (!NT_SUCCESS(Status)) + { + /* We failed somewhere in registry initialization, which is bad... */ + DPRINT1("SMSS: RtlQueryRegistryValues failed - Status == %lx\n", Status); + SMSS_CHECKPOINT(RtlQueryRegistryValues, Status); + return Status; + } + + /* Now we can start acting on the registry settings. First to DOS devices */ + Status = SmpInitializeDosDevices(); + if (!NT_SUCCESS(Status)) + { + /* Failed */ + DPRINT1("SMSS: Unable to initialize DosDevices configuration - Status == %lx\n", + Status); + SMSS_CHECKPOINT(SmpInitializeDosDevices, Status); + return Status; + } + + /* Next create the session directory... */ + RtlInitUnicodeString(&DestinationString, L"\\Sessions"); + InitializeObjectAttributes(&ObjectAttributes, + &DestinationString, + OBJ_CASE_INSENSITIVE | OBJ_OPENIF | OBJ_PERMANENT, + NULL, + SmpPrimarySecurityDescriptor); + Status = NtCreateDirectoryObject(&SmpSessionsObjectDirectory, + DIRECTORY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + /* Fail */ + DPRINT1("SMSS: Unable to create %wZ object directory - Status == %lx\n", + &DestinationString, Status); + SMSS_CHECKPOINT(NtCreateDirectoryObject, Status); + return Status; + } + + /* Next loop all the boot execute binaries */ + Head = &SmpBootExecuteList; + while (!IsListEmpty(Head)) + { + /* Remove each one from the list */ + NextEntry = RemoveHeadList(Head); + + /* Execute it */ + RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry); + SmpExecuteCommand(&RegEntry->Name, 0, NULL, 0); + + /* And free it */ + if (RegEntry->AnsiValue) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->AnsiValue); + if (RegEntry->Value.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->Value.Buffer); + RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry); + } + + /* Now do any pending file rename operations... */ + if (!MiniNTBoot) SmpProcessFileRenames(); + + /* And initialize known DLLs... */ + Status = SmpInitializeKnownDlls(); + if (!NT_SUCCESS(Status)) + { + /* Fail if that didn't work */ + DPRINT1("SMSS: Unable to initialize KnownDll configuration - Status == %lx\n", + Status); + SMSS_CHECKPOINT(SmpInitializeKnownDlls, Status); + return Status; + } + + /* Loop every page file */ + Head = &SmpPagingFileList; + while (!IsListEmpty(Head)) + { + /* Remove each one from the list */ + NextEntry = RemoveHeadList(Head); + + /* Create the descriptor for it */ + RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry); + SmpCreatePagingFileDescriptor(&RegEntry->Name); + + /* And free it */ + if (RegEntry->AnsiValue) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->AnsiValue); + if (RegEntry->Value.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->Value.Buffer); + RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry); + } + + /* Now create all the paging files for the descriptors that we have */ + SmpCreatePagingFiles(); + + /* Tell Cm it's now safe to fully enable write access to the registry */ + // NtInitializeRegistry(FALSE); Later... + + /* Create all the system-based environment variables for later inheriting */ + Status = SmpCreateDynamicEnvironmentVariables(); + if (!NT_SUCCESS(Status)) + { + /* Handle failure */ + SMSS_CHECKPOINT(SmpCreateDynamicEnvironmentVariables, Status); + return Status; + } + + /* And finally load all the subsytems for our first session! */ + Status = SmpLoadSubSystemsForMuSession(&MuSessionId, + &SmpWindowsSubSysProcessId, + InitialCommand); + ASSERT(MuSessionId == 0); + if (!NT_SUCCESS(Status)) SMSS_CHECKPOINT(SmpLoadSubSystemsForMuSession, Status); + return Status; +} + NTSTATUS NTAPI SmpInit(IN PUNICODE_STRING InitialCommand, @@ -386,7 +704,7 @@ SmpInit(IN PUNICODE_STRING InitialCommand, SmpNextSessionId = 1; SmpNextSessionIdScanMode = 0; SmpDbgSsLoaded = FALSE; - + /* Create the initial security descriptors */ Status = SmpCreateSecurityDescriptors(TRUE); if (!NT_SUCCESS(Status)) diff --git a/reactos/base/system/smss2/smsessn.c b/reactos/base/system/smss2/smsessn.c index 5f511f8f041..2b9cd9bad45 100644 --- a/reactos/base/system/smss2/smsessn.c +++ b/reactos/base/system/smss2/smsessn.c @@ -19,5 +19,6 @@ LIST_ENTRY SmpSessionListHead; ULONG SmpNextSessionId; ULONG SmpNextSessionIdScanMode; BOOLEAN SmpDbgSsLoaded; +HANDLE SmpSessionsObjectDirectory; /* FUNCTIONS ******************************************************************/ diff --git a/reactos/base/system/smss2/smss.c b/reactos/base/system/smss2/smss.c index 2be1f0c40c6..8ccb9b12ef3 100644 --- a/reactos/base/system/smss2/smss.c +++ b/reactos/base/system/smss2/smss.c @@ -33,6 +33,17 @@ BOOLEAN SmpDebug; /* FUNCTIONS ******************************************************************/ +NTSTATUS +NTAPI +SmpExecuteCommand(IN PUNICODE_STRING CommandLine, + IN ULONG MuSessionId, + OUT PULONG ProcessId, + IN ULONG Flags) +{ + DPRINT1("Should run: %wZ for session %d\n", CommandLine, MuSessionId); + return STATUS_SUCCESS; +} + NTSTATUS NTAPI ExpLoadInitialProcess(IN PINIT_BUFFER InitBuffer, @@ -389,7 +400,7 @@ _main(IN INT argc, DPRINT1("SMSS: SmpInit return failure - Status == %x\n"); RtlInitUnicodeString(&DbgString, L"Session Manager Initialization"); Parameters[1] = Status; - _SEH2_LEAVE; + //_SEH2_LEAVE; Hack so that setup can work. will go away later } /* Get the global flags */ diff --git a/reactos/base/system/smss2/smss.h b/reactos/base/system/smss2/smss.h index a700103d960..430fe748c0e 100644 --- a/reactos/base/system/smss2/smss.h +++ b/reactos/base/system/smss2/smss.h @@ -40,9 +40,17 @@ extern ULONG SmpNextSessionId; extern ULONG SmpNextSessionIdScanMode; extern BOOLEAN SmpDbgSsLoaded; extern HANDLE SmpWindowsSubSysProcess; - +extern HANDLE SmpSessionsObjectDirectory; +extern HANDLE SmpWindowsSubSysProcessId; + /* FUNCTIONS ******************************************************************/ +NTSTATUS +NTAPI +SmpCreateSecurityDescriptors( + IN BOOLEAN InitialCall +); + NTSTATUS NTAPI SmpInit( @@ -68,3 +76,39 @@ NTAPI SmpApiLoop( IN PVOID Parameter ); + +NTSTATUS +NTAPI +SmpExecuteCommand( + IN PUNICODE_STRING CommandLine, + IN ULONG MuSessionId, + OUT PULONG ProcessId, + IN ULONG Flags +); + +NTSTATUS +NTAPI +SmpLoadSubSystemsForMuSession( + IN PULONG MuSessionId, + OUT PHANDLE ProcessId, + IN PUNICODE_STRING InitialCommand +); + +VOID +NTAPI +SmpPagingFileInitialize( + VOID +); + +NTSTATUS +NTAPI +SmpCreatePagingFileDescriptor( + IN PUNICODE_STRING PageFileToken +); + +NTSTATUS +NTAPI +SmpCreatePagingFiles( + VOID +); + diff --git a/reactos/base/system/smss2/smsubsys.c b/reactos/base/system/smss2/smsubsys.c index dd0eabb5577..ab5ae67ade2 100644 --- a/reactos/base/system/smss2/smsubsys.c +++ b/reactos/base/system/smss2/smsubsys.c @@ -17,7 +17,17 @@ RTL_CRITICAL_SECTION SmpKnownSubSysLock; LIST_ENTRY SmpKnownSubSysHead; HANDLE SmpWindowsSubSysProcess; +HANDLE SmpWindowsSubSysProcessId; /* FUNCTIONS ******************************************************************/ -/* EOF */ +NTSTATUS +NTAPI +SmpLoadSubSystemsForMuSession(IN PULONG MuSessionId, + OUT PHANDLE ProcessId, + IN PUNICODE_STRING InitialCommand) +{ + DPRINT1("Should start subsystems for Session: %lx\n", *MuSessionId); + return STATUS_SUCCESS; +} +