From 12f8a6d6a61c8407f204fcfd513e8a63537df226 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 6 Feb 2012 09:06:38 +0000 Subject: [PATCH] [SMSS2]: Implement SmpProcessFileRenames and actually create the paging file now. All initialization work is now done by SMSS2. [SMSS]: Neuter away most of the code and only keep SMSS around for managing the API port. Next step is to make the SMSS2 API port go into use. svn path=/trunk/; revision=55453 --- reactos/base/system/smss/init.c | 14 +- reactos/base/system/smss2/pagefile.c | 4 +- reactos/base/system/smss2/sminit.c | 206 ++++++++++++++++++++++++++- 3 files changed, 213 insertions(+), 11 deletions(-) diff --git a/reactos/base/system/smss/init.c b/reactos/base/system/smss/init.c index 1ad50e33989..54678f4ffc1 100644 --- a/reactos/base/system/smss/init.c +++ b/reactos/base/system/smss/init.c @@ -23,16 +23,16 @@ struct { PCHAR ErrorMessage; } InitRoutine [] = { {TRUE, SmCreateHeap, "create private heap, aborting"}, - {TRUE, SmCreateObjectDirectories, "create object directories"}, +// {TRUE, SmCreateObjectDirectories, "create object directories"}, {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"}, - {TRUE, SmProcessFileRenameList, "process the file rename list"}, +// {TRUE, SmSetEnvironmentVariables, "set system environment variables"}, +// {TRUE, SmInitDosDevices, "create dos device links"}, +// {TRUE, SmRunBootApplications, "run boot applications"}, +// {TRUE, SmProcessFileRenameList, "process the file rename list"}, {FALSE, SmUpdateEnvironment, "update environment variables"}, - {FALSE, SmLoadKnownDlls, "preload system DLLs"}, - {TRUE, SmCreatePagingFiles, "create paging files"}, +// {FALSE, SmLoadKnownDlls, "preload system DLLs"}, +// {TRUE, SmCreatePagingFiles, "create paging files"}, // {TRUE, SmInitializeRegistry, "initialize the registry"}, {TRUE, SmInitializeClientManagement, "initialize client management"}, {TRUE, SmLoadSubsystems, "load subsystems"} diff --git a/reactos/base/system/smss2/pagefile.c b/reactos/base/system/smss2/pagefile.c index f257963641a..035f437d858 100644 --- a/reactos/base/system/smss2/pagefile.c +++ b/reactos/base/system/smss2/pagefile.c @@ -451,11 +451,9 @@ SmpCreatePagingFile(IN PUNICODE_STRING Name, IN ULONG Priority) { NTSTATUS Status; - DPRINT1("Should request pagefile: %wZ with size %I64x and %I64x\n", Name, MinSize->QuadPart, MaxSize->QuadPart); /* Tell the kernel to create the pagefile */ - Status = STATUS_SUCCESS; - //Status = NtCreatePagingFile(Name, MinSize, MaxSize, Priority); + Status = NtCreatePagingFile(Name, MinSize, MaxSize, Priority); if (NT_SUCCESS(Status)) { DPRINT1("SMSS:PFILE: NtCreatePagingFile (%wZ, %I64X, %I64X) succeeded. \n", diff --git a/reactos/base/system/smss2/sminit.c b/reactos/base/system/smss2/sminit.c index 625de6a58be..c07bfc936a2 100644 --- a/reactos/base/system/smss2/sminit.c +++ b/reactos/base/system/smss2/sminit.c @@ -1827,7 +1827,211 @@ NTSTATUS NTAPI SmpProcessFileRenames(VOID) { - return STATUS_SUCCESS; + BOOLEAN OldState, HavePrivilege; + NTSTATUS Status; + HANDLE FileHandle, OtherFileHandle; + FILE_INFORMATION_CLASS InformationClass; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING FileString; + FILE_BASIC_INFORMATION BasicInfo; + FILE_DISPOSITION_INFORMATION DeleteInformation; + PFILE_RENAME_INFORMATION Buffer; + PLIST_ENTRY Head, NextEntry; + PSMP_REGISTRY_VALUE RegEntry; + PWCHAR FileName; + ULONG ValueLength, Length; + + /* Give us access to restore any files we want */ + Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, FALSE, &OldState); + if (NT_SUCCESS(Status)) HavePrivilege = TRUE; + + /* 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); + + /* Skip past the '@' marker */ + if (!(RegEntry->Value.Length) && (*RegEntry->Name.Buffer == L'@')) + { + RegEntry->Name.Length -= sizeof(UNICODE_NULL); + RegEntry->Name.Buffer++; + } + + /* Open the file for delete access */ + InitializeObjectAttributes(&ObjectAttributes, + &RegEntry->Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenFile(&OtherFileHandle, + DELETE | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(Status)) goto Quickie; + + /* Check if it's a rename or just a delete */ + ValueLength = RegEntry->Value.Length; + if (!ValueLength) + { + /* Just a delete, set up the class, length and buffer */ + InformationClass = FileDispositionInformation; + Length = sizeof(DeleteInformation); + Buffer = (PFILE_RENAME_INFORMATION)&DeleteInformation; + + /* Set the delete disposition */ + DeleteInformation.DeleteFile = TRUE; + } + else + { + /* This is a rename, setup the class and length */ + InformationClass = FileRenameInformation; + Length = ValueLength + sizeof(FILE_RENAME_INFORMATION); + + /* Skip past the special markers */ + FileName = RegEntry->Value.Buffer; + if ((*FileName == L'!') || (*FileName == L'@')) + { + FileName++; + Length -= sizeof(UNICODE_NULL); + } + + /* Now allocate the buffer for the rename information */ + Buffer = RtlAllocateHeap(RtlGetProcessHeap(), SmBaseTag, Length); + if (Buffer) + { + /* Setup the buffer to point to the filename, and copy it */ + Buffer->RootDirectory = NULL; + Buffer->FileNameLength = Length - sizeof(FILE_RENAME_INFORMATION); + Buffer->ReplaceIfExists = FileName != RegEntry->Value.Buffer; + RtlCopyMemory(Buffer->FileName, FileName, Buffer->FileNameLength); + } + else + { + /* Fail */ + Status = STATUS_NO_MEMORY; + } + } + + /* Check if everything is okay till here */ + if (NT_SUCCESS(Status)) + { + /* Now either rename or delete the file as requested */ + Status = NtSetInformationFile(OtherFileHandle, + &IoStatusBlock, + Buffer, + Length, + InformationClass); + + /* Check if we seem to have failed because the file was readonly */ + if ((NT_SUCCESS(Status) && + (InformationClass == FileRenameInformation) && + (Status == STATUS_OBJECT_NAME_COLLISION) && + (Buffer->ReplaceIfExists))) + { + /* Open the file for write attribute access this time... */ + DPRINT1("\nSMSS: %wZ => %wZ failed - Status == %x, Possible readonly target\n", + &RegEntry->Name, + &RegEntry->Value, + STATUS_OBJECT_NAME_COLLISION); + FileString.Length = RegEntry->Value.Length - sizeof(WCHAR); + FileString.MaximumLength = RegEntry->Value.MaximumLength - sizeof(WCHAR); + FileString.Buffer = FileName; + InitializeObjectAttributes(&ObjectAttributes, + &FileString, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenFile(&FileHandle, + FILE_WRITE_ATTRIBUTES | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(Status)) + { + /* That didn't work, so bail out */ + DPRINT1(" SMSS: Open Existing file Failed - Status == %x\n", + Status); + } + else + { + /* Now remove the read-only attribute from the file */ + DPRINT1(" SMSS: Open Existing Success\n"); + RtlZeroMemory(&BasicInfo, sizeof(BasicInfo)); + BasicInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL; + Status = NtSetInformationFile(FileHandle, + &IoStatusBlock, + &BasicInfo, + sizeof(BasicInfo), + FileBasicInformation); + NtClose(FileHandle); + if (!NT_SUCCESS(Status)) + { + /* That didn't work, bail out */ + DPRINT1(" SMSS: Set To NORMAL Failed - Status == %x\n", + Status); + } + else + { + /* Now that the file is no longer read-only, delete! */ + DPRINT1(" SMSS: Set To NORMAL OK\n"); + Status = NtSetInformationFile(OtherFileHandle, + &IoStatusBlock, + Buffer, + Length, + FileRenameInformation); + if (!NT_SUCCESS(Status)) + { + /* That failed too! */ + DPRINT1(" SMSS: Re-Rename Failed - Status == %x\n", + Status); + } + else + { + /* Everything ok */ + DPRINT1(" SMSS: Re-Rename Worked OK\n"); + } + } + } + } + } + + /* Close the file handle and check the operation result */ + NtClose(OtherFileHandle); +Quickie: + if (!NT_SUCCESS(Status)) + { + /* We totally failed */ + 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); + } + else + { + /* We suceeded with a delete */ + DPRINT1("SMSS: %wZ (deleted)\n", &RegEntry->Name); + } + + /* Now free this entry and keep going */ + if (RegEntry->AnsiValue) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->AnsiValue); + if (RegEntry->Value.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->Value.Buffer); + RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry); + } + + /* Put back the restore privilege if we had requested it, and return */ + if (HavePrivilege) RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, FALSE, FALSE, &OldState); + return Status; } NTSTATUS