/*
* PROJECT: ReactOS Windows-Compatible Session Manager
* LICENSE: BSD 2-Clause License
- * FILE: base/system/smss/smss.c
+ * FILE: base/system/smss/sminit.c
* PURPOSE: Main SMSS Code
* PROGRAMMERS: Alex Ionescu
*/
PISECURITY_DESCRIPTOR SmpKnownDllsSecurityDescriptor, SmpApiPortSecurityDescriptor;
ULONG SmpAllowProtectedRenames, SmpProtectionMode = 1;
-BOOLEAN MiniNTBoot;
+BOOLEAN MiniNTBoot = FALSE;
#define SMSS_CHECKPOINT(x, y) \
{ \
/* A new entry -- allocate it */
RegEntry = RtlAllocateHeap(RtlGetProcessHeap(),
SmBaseTag,
- NameString.MaximumLength +
- sizeof(SMP_REGISTRY_VALUE));
+ sizeof(SMP_REGISTRY_VALUE) +
+ NameString.MaximumLength);
if (!RegEntry) return STATUS_NO_MEMORY;
/* Initialize the list and set all values to NULL */
}
/* Move to the next requested object */
- while (*SourceString++);
+ SourceString += wcslen(SourceString) + 1;
}
/* All done */
IN PVOID EntryContext)
{
NTSTATUS Status;
- static PWCHAR Canary;
+ static PWCHAR Canary = NULL;
/* Check if this is the second call */
if (Canary)
{
/* Save the data into the list */
- DPRINT1("Renamed file: %S-%S\n", Canary, ValueData);
+ DPRINT("Renamed file: '%S' - '%S'\n", Canary, ValueData);
Status = SmpSaveRegistryValue(EntryContext, Canary, ValueData, FALSE);
- Canary = 0;
+ Canary = NULL;
}
else
{
if (!(NT_SUCCESS(Status)) || (ValueType == REG_SZ)) return Status;
/* Otherwise, move to the next DLL name */
- while (*DllName++);
+ DllName += wcslen(DllName) + 1;
}
}
}
/* Move to the next name */
- while (*SubsystemName++);
+ SubsystemName += wcslen(SubsystemName) + 1;
}
}
{
SmpConfigureAllowProtectedRenames,
- 0, //RTL_QUERY_REGISTRY_DELETE,
+ RTL_QUERY_REGISTRY_DELETE,
L"AllowProtectedRenames",
NULL,
REG_DWORD,
{
SmpConfigureFileRenames,
- 0, //RTL_QUERY_REGISTRY_DELETE,
+ RTL_QUERY_REGISTRY_DELETE,
L"PendingFileRenameOperations",
&SmpFileRenameList,
REG_NONE,
{
SmpConfigureFileRenames,
- 0, //RTL_QUERY_REGISTRY_DELETE,
+ RTL_QUERY_REGISTRY_DELETE,
L"PendingFileRenameOperations2",
&SmpFileRenameList,
REG_NONE,
NextEntry = SmpKnownDllsList.Flink;
while (NextEntry != &SmpKnownDllsList)
{
- /* Get the entry and skip it if it's in the exluded list */
+ /* Get the entry and move on */
RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
+ NextEntry = NextEntry->Flink;
+
DPRINT("Processing known DLL: %wZ-%wZ\n", &RegEntry->Name, &RegEntry->Value);
+
+ /* Skip the entry if it's in the excluded list */
if ((SmpFindRegistryValue(&SmpExcludeKnownDllsList,
RegEntry->Name.Buffer)) ||
(SmpFindRegistryValue(&SmpExcludeKnownDllsList,
OBJ_CASE_INSENSITIVE,
DirFileHandle,
NULL);
- Status = NtOpenFile(&FileHandle,
- SYNCHRONIZE | FILE_EXECUTE,
- &ObjectAttributes,
- &IoStatusBlock,
- FILE_SHARE_READ | FILE_SHARE_DELETE,
- FILE_NON_DIRECTORY_FILE |
- FILE_SYNCHRONOUS_IO_NONALERT);
- if (!NT_SUCCESS(Status)) break;
+ Status1 = NtOpenFile(&FileHandle,
+ SYNCHRONIZE | FILE_EXECUTE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ | FILE_SHARE_DELETE,
+ FILE_NON_DIRECTORY_FILE |
+ FILE_SYNCHRONOUS_IO_NONALERT);
+ /* If we failed, skip it */
+ if (!NT_SUCCESS(Status1)) continue;
/* Checksum it */
Status = LdrVerifyImageMatchesChecksum((HANDLE)((ULONG_PTR)FileHandle | 1),
ErrorParameters[2] = (ULONG)&RegEntry->Value;
SmpTerminate(ErrorParameters, 5, RTL_NUMBER_OF(ErrorParameters));
}
- else
- if (!(ImageCharacteristics & IMAGE_FILE_DLL))
+ else if (!(ImageCharacteristics & IMAGE_FILE_DLL))
{
/* An invalid known DLL entry will also kill SMSS */
RtlInitUnicodeString(&ErrorResponse,
/* Close the file since we can move on to the next one */
Status1 = NtClose(FileHandle);
ASSERT(NT_SUCCESS(Status1));
-
- /* Go to the next entry */
- NextEntry = NextEntry->Flink;
}
Quickie:
UNICODE_STRING ValueName, DestinationString;
HANDLE KeyHandle, KeyHandle2;
ULONG ResultLength;
- PWCHAR ArchName;
+ PWCHAR ValueData;
WCHAR ValueBuffer[512], ValueBuffer2[512];
PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = (PVOID)ValueBuffer;
PKEY_VALUE_PARTIAL_INFORMATION PartialInfo2 = (PVOID)ValueBuffer2;
/* First let's write the OS variable */
RtlInitUnicodeString(&ValueName, L"OS");
- DPRINT("Setting %wZ to %S\n", &ValueName, L"Windows_NT");
+ ValueData = L"Windows_NT";
+ DPRINT("Setting %wZ to %S\n", &ValueName, ValueData);
Status = NtSetValueKey(KeyHandle,
&ValueName,
0,
REG_SZ,
- L"Windows_NT",
- wcslen(L"Windows_NT") * sizeof(WCHAR) + sizeof(UNICODE_NULL));
+ ValueData,
+ (wcslen(ValueData) + 1) * sizeof(WCHAR));
if (!NT_SUCCESS(Status))
{
DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
{
/* Pick the correct string that matches the architecture */
case PROCESSOR_ARCHITECTURE_INTEL:
- ArchName = L"x86";
+ ValueData = L"x86";
break;
case PROCESSOR_ARCHITECTURE_AMD64:
- ArchName = L"AMD64";
+ ValueData = L"AMD64";
break;
case PROCESSOR_ARCHITECTURE_IA64:
- ArchName = L"IA64";
+ ValueData = L"IA64";
break;
default:
- ArchName = L"Unknown";
+ ValueData = L"Unknown";
break;
}
/* Set it */
- DPRINT("Setting %wZ to %S\n", &ValueName, ArchName);
+ DPRINT("Setting %wZ to %S\n", &ValueName, ValueData);
Status = NtSetValueKey(KeyHandle,
&ValueName,
0,
REG_SZ,
- ArchName,
- wcslen(ArchName) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
+ ValueData,
+ (wcslen(ValueData) + 1) * sizeof(WCHAR));
if (!NT_SUCCESS(Status))
{
DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
0,
REG_SZ,
ValueBuffer,
- wcslen(ValueBuffer) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
+ (wcslen(ValueBuffer) + 1) * sizeof(WCHAR));
if (!NT_SUCCESS(Status))
{
DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
0,
REG_SZ,
PartialInfo->Data,
- wcslen((PWCHAR)PartialInfo->Data) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
+ (wcslen((PWCHAR)PartialInfo->Data) + 1) * sizeof(WCHAR));
if (!NT_SUCCESS(Status))
{
DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
0,
REG_SZ,
ValueBuffer,
- wcslen(ValueBuffer) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
+ (wcslen(ValueBuffer) + 1) * sizeof(WCHAR));
if (!NT_SUCCESS(Status))
{
DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
0,
REG_SZ,
ValueBuffer,
- wcslen(ValueBuffer) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
+ (wcslen(ValueBuffer) + 1) * sizeof(WCHAR));
if (!NT_SUCCESS(Status))
{
DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
0,
REG_SZ,
ValueBuffer,
- wcslen(ValueBuffer) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
+ (wcslen(ValueBuffer) + 1) * sizeof(WCHAR));
if (!NT_SUCCESS(Status))
{
DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, FALSE, &OldState);
if (NT_SUCCESS(Status)) HavePrivilege = TRUE;
+ // FIXME: Handle SFC-protected file renames!
+ if (SmpAllowProtectedRenames)
+ DPRINT1("SMSS: FIXME: Handle SFC-protected file renames!\n");
+
/* Process pending files to rename */
Head = &SmpFileRenameList;
while (!IsListEmpty(Head))
/* Get this entry */
NextEntry = RemoveHeadList(Head);
RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
- DPRINT1("Processing PFRO: %wZ/%wZ\n", &RegEntry->Value, &RegEntry->Name);
+ DPRINT("Processing PFRO: '%wZ' / '%wZ'\n", &RegEntry->Value, &RegEntry->Name);
/* Skip past the '@' marker */
if (!(RegEntry->Value.Length) && (*RegEntry->Name.Buffer == L'@'))
InformationClass);
/* Check if we seem to have failed because the file was readonly */
- if ((NT_SUCCESS(Status) &&
+ if (!NT_SUCCESS(Status) &&
(InformationClass == FileRenameInformation) &&
(Status == STATUS_OBJECT_NAME_COLLISION) &&
- (Buffer->ReplaceIfExists)))
+ Buffer->ReplaceIfExists)
{
/* Open the file for write attribute access this time... */
- DPRINT1("\nSMSS: %wZ => %wZ failed - Status == %x, Possible readonly target\n",
+ DPRINT("\nSMSS: '%wZ' => '%wZ' failed - Status == %x, Possible readonly target\n",
&RegEntry->Name,
&RegEntry->Value,
STATUS_OBJECT_NAME_COLLISION);
else
{
/* Now remove the read-only attribute from the file */
- DPRINT1(" SMSS: Open Existing Success\n");
+ DPRINT(" SMSS: Open Existing Success\n");
RtlZeroMemory(&BasicInfo, sizeof(BasicInfo));
BasicInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
Status = NtSetInformationFile(FileHandle,
else
{
/* Now that the file is no longer read-only, delete! */
- DPRINT1(" SMSS: Set To NORMAL OK\n");
+ DPRINT(" SMSS: Set To NORMAL OK\n");
Status = NtSetInformationFile(OtherFileHandle,
&IoStatusBlock,
Buffer,
else
{
/* Everything ok */
- DPRINT1(" SMSS: Re-Rename Worked OK\n");
+ DPRINT(" SMSS: Re-Rename Worked OK\n");
}
}
}
if (!NT_SUCCESS(Status))
{
/* We totally failed */
- DPRINT1("SMSS: %wZ => %wZ failed - Status == %x\n",
+ DPRINT1("SMSS: '%wZ' => '%wZ' failed - Status == %x\n",
&RegEntry->Name, &RegEntry->Value, Status);
}
else if (RegEntry->Value.Length)
{
/* We succeed with a rename */
- DPRINT1("SMSS: %wZ (renamed to) %wZ\n", &RegEntry->Name, &RegEntry->Value);
+ DPRINT("SMSS: '%wZ' (renamed to) '%wZ'\n", &RegEntry->Name, &RegEntry->Value);
}
else
{
- /* We suceeded with a delete */
- DPRINT1("SMSS: %wZ (deleted)\n", &RegEntry->Name);
+ /* We succeeded with a delete */
+ DPRINT("SMSS: '%wZ' (deleted)\n", &RegEntry->Name);
}
/* Now free this entry and keep going */
}
/* Print out if this is the case */
- if (MiniNTBoot) DPRINT1("SMSS: !!! MiniNT Boot !!!\n");
+ if (MiniNTBoot) DPRINT("SMSS: !!! MiniNT Boot !!!\n");
/* Open the environment key to see if we are booted in safe mode */
RtlInitUnicodeString(&DestinationString,
return Status;
}
- /* Loop every page file */
- Head = &SmpPagingFileList;
- while (!IsListEmpty(Head))
+ /* Create the needed page files */
+ if (!MiniNTBoot)
{
- /* Remove each one from the list */
- NextEntry = RemoveHeadList(Head);
+ /* 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);
+ /* 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);
- }
+ /* 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();
+ /* 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(CM_BOOT_FLAG_SMSS);
return Status;
}
- /* And finally load all the subsytems for our first session! */
+ /* And finally load all the subsystems for our first session! */
Status = SmpLoadSubSystemsForMuSession(&MuSessionId,
&SmpWindowsSubSysProcessId,
InitialCommand);