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; +} +