Author: ion Date: Sun Oct 8 11:53:37 2006 New Revision: 24440
URL: http://svn.reactos.org/svn/reactos?rev=24440&view=rev Log: - Part 1 of ARC boot cleanups/changes: Create a valid \SystemRoot symbolic link as the system is booting, which points to the ARC name, then, once drivers have loaded, re-assign it to the proper NT Device name. Added proper security descriptors and flags to symbolic links, as well as proper bugchecks when required. - Kept and cleaned up the ROS hack for CD-ROM boot.
Modified: trunk/reactos/ntoskrnl/ex/init.c trunk/reactos/ntoskrnl/include/internal/io.h trunk/reactos/ntoskrnl/io/iomgr/arcname.c trunk/reactos/ntoskrnl/io/iomgr/iomgr.c
Modified: trunk/reactos/ntoskrnl/ex/init.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/init.c?rev=2444... ============================================================================== --- trunk/reactos/ntoskrnl/ex/init.c (original) +++ trunk/reactos/ntoskrnl/ex/init.c Sun Oct 8 11:53:37 2006 @@ -48,6 +48,113 @@ PVOID ExpNlsSectionPointer;
/* FUNCTIONS ****************************************************************/ + +NTSTATUS +NTAPI +ExpCreateSystemRootLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + UNICODE_STRING LinkName; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE LinkHandle; + NTSTATUS Status; + ANSI_STRING AnsiName; + CHAR Buffer[256]; + ANSI_STRING TargetString; + UNICODE_STRING TargetName; + + /* Initialize the ArcName tree */ + RtlInitUnicodeString(&LinkName, L"\ArcName"); + InitializeObjectAttributes(&ObjectAttributes, + &LinkName, + OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, + NULL, + SePublicDefaultSd); + + /* Create it */ + Status = NtCreateDirectoryObject(&LinkHandle, + DIRECTORY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 1, 0, 0); + } + + /* Close the LinkHandle */ + NtClose(LinkHandle); + + /* Initialize the Device tree */ + RtlInitUnicodeString(&LinkName, L"\Device"); + InitializeObjectAttributes(&ObjectAttributes, + &LinkName, + OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, + NULL, + SePublicDefaultSd); + + /* Create it */ + Status = NtCreateDirectoryObject(&LinkHandle, + DIRECTORY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 2, 0, 0); + } + + /* Close the LinkHandle */ + ObCloseHandle(LinkHandle, KernelMode); + + /* Create the system root symlink name */ + RtlInitAnsiString(&AnsiName, "\SystemRoot"); + Status = RtlAnsiStringToUnicodeString(&LinkName, &AnsiName, TRUE); + if (!NT_SUCCESS(Status)) + { + KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 3, 0, 0); + } + + /* Initialize the attributes for the link */ + InitializeObjectAttributes(&ObjectAttributes, + &LinkName, + OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, + NULL, + SePublicDefaultSd); + + /* Build the ARC name */ + sprintf(Buffer, + "\ArcName\%s%s", + LoaderBlock->ArcBootDeviceName, + LoaderBlock->NtBootPathName); + Buffer[strlen(Buffer) - 1] = ANSI_NULL; + + /* Convert it to Unicode */ + RtlInitString(&TargetString, Buffer); + Status = RtlAnsiStringToUnicodeString(&TargetName, + &TargetString, + TRUE); + if (!NT_SUCCESS(Status)) + { + /* We failed, bugcheck */ + KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 4, 0, 0); + } + + /* Create it */ + Status = NtCreateSymbolicLinkObject(&LinkHandle, + SYMBOLIC_LINK_ALL_ACCESS, + &ObjectAttributes, + &TargetName); + + /* Free the strings */ + RtlFreeUnicodeString(&LinkName); + RtlFreeUnicodeString(&TargetName); + + /* Check if creating the link failed */ + if (!NT_SUCCESS(Status)) + { + KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 5, 0, 0); + } + + /* Close the handle and return success */ + ObCloseHandle(LinkHandle, KernelMode); + return STATUS_SUCCESS; +}
VOID NTAPI @@ -934,6 +1041,11 @@ }
/* Create SystemRoot Link */ + Status = ExpCreateSystemRootLink(KeLoaderBlock); + if (!NT_SUCCESS(Status)) + { + KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 0, 0, 0); + }
/* Create NLS section */ ExpInitNls(KeLoaderBlock);
Modified: trunk/reactos/ntoskrnl/include/internal/io.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/i... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/io.h (original) +++ trunk/reactos/ntoskrnl/include/internal/io.h Sun Oct 8 11:53:37 2006 @@ -567,8 +567,10 @@ );
NTSTATUS -IoCreateSystemRootLink( - IN PLOADER_PARAMETER_BLOCK LoaderBlock +NTAPI +IopReassignSystemRoot( + IN PLOADER_PARAMETER_BLOCK LoaderBlock, + OUT PANSI_STRING NtBootPath );
//
Modified: trunk/reactos/ntoskrnl/io/iomgr/arcname.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/arcname.c... ============================================================================== --- trunk/reactos/ntoskrnl/io/iomgr/arcname.c (original) +++ trunk/reactos/ntoskrnl/io/iomgr/arcname.c Sun Oct 8 11:53:37 2006 @@ -33,16 +33,12 @@ static NTSTATUS INIT_FUNCTION IopAssignArcNamesToDisk(PDEVICE_OBJECT DeviceObject, ULONG RDisk, ULONG DiskNumber);
-static NTSTATUS INIT_FUNCTION -IopCheckCdromDevices(PULONG DeviceNumber); - #if defined (ALLOC_PRAGMA) #pragma alloc_text(INIT, DiskQueryRoutine) #pragma alloc_text(INIT, IopEnumerateBiosDisks) #pragma alloc_text(INIT, IopEnumerateDisks) #pragma alloc_text(INIT, IopAssignArcNamesToDisk) #pragma alloc_text(INIT, IoCreateArcNames) -#pragma alloc_text(INIT, IopCheckCdromDevices) #pragma alloc_text(INIT, IoCreateSystemRootLink) #endif
@@ -544,288 +540,179 @@ return(STATUS_SUCCESS); }
- -static NTSTATUS INIT_FUNCTION -IopCheckCdromDevices(PULONG DeviceNumber) +VOID +INIT_FUNCTION +NTAPI +IopApplyRosCdromArcHack(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { - PCONFIGURATION_INFORMATION ConfigInfo; - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING DeviceName; - WCHAR DeviceNameBuffer[MAX_PATH]; - HANDLE Handle; - ULONG i; - NTSTATUS Status; - IO_STATUS_BLOCK IoStatusBlock; -#if 0 - PFILE_FS_VOLUME_INFORMATION FileFsVolume; - USHORT Buffer[FS_VOLUME_BUFFER_SIZE]; - - FileFsVolume = (PFILE_FS_VOLUME_INFORMATION)Buffer; -#endif - - ConfigInfo = IoGetConfigurationInformation(); - for (i = 0; i < ConfigInfo->CdRomCount; i++) - { -#if 0 - swprintf(DeviceNameBuffer, - L"\Device\CdRom%lu\", - i); - RtlInitUnicodeString(&DeviceName, - DeviceNameBuffer); - - InitializeObjectAttributes(&ObjectAttributes, - &DeviceName, - 0, - NULL, - NULL); - - Status = ZwOpenFile(&Handle, - FILE_ALL_ACCESS, - &ObjectAttributes, - &IoStatusBlock, - 0, - 0); - DPRINT("ZwOpenFile() DeviceNumber %lu Status %lx\n", i, Status); - if (NT_SUCCESS(Status)) - { - Status = ZwQueryVolumeInformationFile(Handle, - &IoStatusBlock, - FileFsVolume, - FS_VOLUME_BUFFER_SIZE, - FileFsVolumeInformation); - DPRINT("ZwQueryVolumeInformationFile() Status %lx\n", Status); - if (NT_SUCCESS(Status)) - { - DPRINT("VolumeLabel: '%S'\n", FileFsVolume->VolumeLabel); - if (_wcsicmp(FileFsVolume->VolumeLabel, L"REACTOS") == 0) - { - ZwClose(Handle); - *DeviceNumber = i; - return(STATUS_SUCCESS); - } - } - ZwClose(Handle); - } -#endif - - /* - * Check for 'reactos/ntoskrnl.exe' first... - */ - - swprintf(DeviceNameBuffer, - L"\Device\CdRom%lu\reactos\ntoskrnl.exe", - i); - RtlInitUnicodeString(&DeviceName, - DeviceNameBuffer); - - InitializeObjectAttributes(&ObjectAttributes, - &DeviceName, - 0, - NULL, - NULL); - - Status = ZwOpenFile(&Handle, - FILE_ALL_ACCESS, - &ObjectAttributes, - &IoStatusBlock, - 0, - 0); - DPRINT("ZwOpenFile() DeviceNumber %lu Status %lx\n", i, Status); - if (NT_SUCCESS(Status)) - { - DPRINT("Found ntoskrnl.exe on Cdrom%lu\n", i); - ZwClose(Handle); - *DeviceNumber = i; - return(STATUS_SUCCESS); - } - - /* - * ...and for 'reactos/system32/ntoskrnl.exe' also. - */ - - swprintf(DeviceNameBuffer, - L"\Device\CdRom%lu\reactos\system32\ntoskrnl.exe", - i); - RtlInitUnicodeString(&DeviceName, - DeviceNameBuffer); - - InitializeObjectAttributes(&ObjectAttributes, - &DeviceName, - 0, - NULL, - NULL); - - Status = ZwOpenFile(&Handle, - FILE_ALL_ACCESS, - &ObjectAttributes, - &IoStatusBlock, - 0, - 0); - DPRINT("ZwOpenFile() DeviceNumber %lu Status %lx\n", i, Status); - if (NT_SUCCESS(Status)) - { - DPRINT("Found ntoskrnl.exe on Cdrom%lu\n", i); - ZwClose(Handle); - *DeviceNumber = i; - return(STATUS_SUCCESS); - } - } - - DPRINT("Could not find ntoskrnl.exe\n"); - *DeviceNumber = (ULONG)-1; - - return(STATUS_UNSUCCESSFUL); + ULONG DeviceNumber = -1; + PCONFIGURATION_INFORMATION ConfigInfo; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING DeviceName; + WCHAR Buffer[MAX_PATH]; + CHAR AnsiBuffer[MAX_PATH]; + ULONG i; + FILE_BASIC_INFORMATION FileInfo; + NTSTATUS Status; + PCHAR p, q; + + /* Only ARC Name left - Build full ARC Name */ + p = strstr(LoaderBlock->ArcBootDeviceName, "cdrom"); + if (p) + { + /* Get configuration information */ + ConfigInfo = IoGetConfigurationInformation(); + for (i = 0; i < ConfigInfo->CdRomCount; i++) + { + /* Try to find the installer */ + swprintf(Buffer, L"\Device\CdRom%lu\reactos\ntoskrnl.exe", i); + RtlInitUnicodeString(&DeviceName, Buffer); + InitializeObjectAttributes(&ObjectAttributes, + &DeviceName, + 0, + NULL, + NULL); + Status = ZwQueryAttributesFile(&ObjectAttributes, &FileInfo); + if (NT_SUCCESS(Status)) DeviceNumber = i; + + /* Try to find live CD boot */ + swprintf(Buffer, + L"\Device\CdRom%lu\reactos\system32\ntoskrnl.exe", + i); + RtlInitUnicodeString(&DeviceName, Buffer); + InitializeObjectAttributes(&ObjectAttributes, + &DeviceName, + 0, + NULL, + NULL); + Status = ZwQueryAttributesFile(&ObjectAttributes, &FileInfo); + if (NT_SUCCESS(Status)) DeviceNumber = i; + } + + /* Build the name */ + sprintf(p, "cdrom(%lu)", DeviceNumber); + + /* Adjust original command line */ + q = strchr(p, ')'); + if (q) + { + q++; + strcpy(AnsiBuffer, q); + sprintf(p, "cdrom(%lu)", DeviceNumber); + strcat(p, AnsiBuffer); + } + } }
- -NTSTATUS INIT_FUNCTION -IoCreateSystemRootLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock) +NTSTATUS +NTAPI +IopReassignSystemRoot(IN PLOADER_PARAMETER_BLOCK LoaderBlock, + OUT PANSI_STRING NtBootPath) { - OBJECT_ATTRIBUTES ObjectAttributes; - IO_STATUS_BLOCK IoStatusBlock; - UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\SystemRoot"); - UNICODE_STRING DeviceName; - UNICODE_STRING ArcName; - UNICODE_STRING BootPath; - PCHAR ParamBuffer; - PWCHAR ArcNameBuffer; - PCHAR p; - NTSTATUS Status; - ULONG Length; - HANDLE Handle; - - RtlCreateUnicodeStringFromAsciiz(&BootPath, LoaderBlock->NtBootPathName); - - /* Remove the trailing backslash */ - BootPath.Length -= sizeof(WCHAR); - BootPath.MaximumLength -= sizeof(WCHAR); - - /* Only ARC Name left - Build full ARC Name */ - ParamBuffer = LoaderBlock->ArcBootDeviceName; - - p = strstr(ParamBuffer, "cdrom"); - if (p != NULL) - { - ULONG DeviceNumber; - - DPRINT("Booting from CD-ROM!\n"); - Status = IopCheckCdromDevices(&DeviceNumber); - if (!NT_SUCCESS(Status)) - { - CPRINT("Failed to find setup disk!\n"); - return(Status); - } - - sprintf(p, "cdrom(%lu)", DeviceNumber); - - DPRINT("New ARC name: %s\n", ParamBuffer); - - /* Adjust original command line */ - p = strstr(LoaderBlock->ArcBootDeviceName, "cdrom"); - if (p != NULL); - { - char temp[256]; - char *q; - - q = strchr(p, ')'); - if (q != NULL) - { - - q++; - strcpy(temp, q); - sprintf(p, "cdrom(%lu)", DeviceNumber); - strcat(p, temp); - } - } - } - - /* Only arc name left - build full arc name */ - ArcNameBuffer = ExAllocatePool(PagedPool, 256 * sizeof(WCHAR)); - swprintf(ArcNameBuffer, - L"\ArcName\%S", ParamBuffer); - RtlInitUnicodeString(&ArcName, ArcNameBuffer); - - /* allocate device name string */ - DeviceName.Length = 0; - DeviceName.MaximumLength = 256 * sizeof(WCHAR); - DeviceName.Buffer = ExAllocatePool(PagedPool, 256 * sizeof(WCHAR)); - - InitializeObjectAttributes(&ObjectAttributes, - &ArcName, - OBJ_OPENLINK, - NULL, - NULL); - - Status = ZwOpenSymbolicLinkObject(&Handle, - SYMBOLIC_LINK_ALL_ACCESS, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - RtlFreeUnicodeString(&BootPath); - ExFreePool(DeviceName.Buffer); - CPRINT("ZwOpenSymbolicLinkObject() '%wZ' failed (Status %x)\n", - &ArcName, - Status); - ExFreePool(ArcName.Buffer); - - return(Status); - } - ExFreePool(ArcName.Buffer); - - Status = ZwQuerySymbolicLinkObject(Handle, - &DeviceName, - &Length); - ZwClose (Handle); - if (!NT_SUCCESS(Status)) - { - RtlFreeUnicodeString(&BootPath); - ExFreePool(DeviceName.Buffer); - CPRINT("ZwQuerySymbolicObject() failed (Status %x)\n", - Status); - - return(Status); - } - - RtlAppendUnicodeStringToString(&DeviceName, - &BootPath); - - RtlFreeUnicodeString(&BootPath); - - /* create the '\SystemRoot' link */ - Status = IoCreateSymbolicLink(&LinkName, - &DeviceName); - ExFreePool(DeviceName.Buffer); - if (!NT_SUCCESS(Status)) - { - CPRINT("IoCreateSymbolicLink() failed (Status %x)\n", - Status); - - return(Status); - } - - /* Check whether '\SystemRoot'(LinkName) can be opened */ - InitializeObjectAttributes(&ObjectAttributes, - &LinkName, - 0, - NULL, - NULL); - - Status = ZwOpenFile(&Handle, - FILE_ALL_ACCESS, - &ObjectAttributes, - &IoStatusBlock, - 0, - 0); - if (!NT_SUCCESS(Status)) - { - CPRINT("ZwOpenFile() failed to open '\SystemRoot' (Status %x)\n", - Status); - return(Status); - } - - ZwClose(Handle); - - return(STATUS_SUCCESS); + OBJECT_ATTRIBUTES ObjectAttributes; + NTSTATUS Status; + CHAR Buffer[256], AnsiBuffer[256]; + WCHAR ArcNameBuffer[64]; + ANSI_STRING TargetString, ArcString, TempString; + UNICODE_STRING LinkName, TargetName, ArcName; + HANDLE LinkHandle; + + /* Check if this is a CD-ROM boot */ + IopApplyRosCdromArcHack(LoaderBlock); + + /* Create the Unicode name for the current ARC boot device */ + sprintf(Buffer, "\ArcName\%s", LoaderBlock->ArcBootDeviceName); + RtlInitAnsiString(&TargetString, Buffer); + Status = RtlAnsiStringToUnicodeString(&TargetName, &TargetString, TRUE); + if (!NT_SUCCESS(Status)) return FALSE; + + /* Initialize the attributes and open the link */ + InitializeObjectAttributes(&ObjectAttributes, + &TargetName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenSymbolicLinkObject(&LinkHandle, + SYMBOLIC_LINK_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + /* We failed, free the string */ + RtlFreeUnicodeString(&TargetName); + return FALSE; + } + + /* Query the current \SystemRoot */ + ArcName.Buffer = ArcNameBuffer; + ArcName.Length = 0; + ArcName.MaximumLength = sizeof(ArcNameBuffer); + Status = NtQuerySymbolicLinkObject(LinkHandle, &ArcName, NULL); + if (!NT_SUCCESS(Status)) + { + /* We failed, free the string */ + RtlFreeUnicodeString(&TargetName); + return FALSE; + } + + /* Convert it to Ansi */ + ArcString.Buffer = AnsiBuffer; + ArcString.Length = 0; + ArcString.MaximumLength = sizeof(AnsiBuffer); + Status = RtlUnicodeStringToAnsiString(&ArcString, &ArcName, FALSE); + AnsiBuffer[ArcString.Length] = ANSI_NULL; + + /* Close the link handle and free the name */ + ObCloseHandle(LinkHandle, KernelMode); + RtlFreeUnicodeString(&TargetName); + + /* Setup the system root name again */ + RtlInitAnsiString(&TempString, "\SystemRoot"); + Status = RtlAnsiStringToUnicodeString(&LinkName, &TempString, TRUE); + if (!NT_SUCCESS(Status)) return FALSE; + + /* Open the symbolic link for it */ + InitializeObjectAttributes(&ObjectAttributes, + &LinkName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenSymbolicLinkObject(&LinkHandle, + SYMBOLIC_LINK_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) return FALSE; + + /* Destroy it */ + NtMakeTemporaryObject(LinkHandle); + ObCloseHandle(LinkHandle, KernelMode); + + /* Now create the new name for it */ + sprintf(Buffer, "%s%s", ArcString.Buffer, LoaderBlock->NtBootPathName); + + /* Copy it into the passed parameter and null-terminate it */ + RtlCopyString(NtBootPath, &ArcString); + Buffer[strlen(Buffer) - 1] = ANSI_NULL; + + /* Setup the Unicode-name for the new symbolic link value */ + RtlInitAnsiString(&TargetString, Buffer); + InitializeObjectAttributes(&ObjectAttributes, + &LinkName, + OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, + NULL, + NULL); + Status = RtlAnsiStringToUnicodeString(&ArcName, &TargetString, TRUE); + if (!NT_SUCCESS(Status)) return FALSE; + + /* Create it */ + Status = NtCreateSymbolicLinkObject(&LinkHandle, + SYMBOLIC_LINK_ALL_ACCESS, + &ObjectAttributes, + &ArcName); + + /* Free all the strings and close the handle and return success */ + RtlFreeUnicodeString(&ArcName); + RtlFreeUnicodeString(&LinkName); + ObCloseHandle(LinkHandle, KernelMode); + return TRUE; }
/* EOF */
Modified: trunk/reactos/ntoskrnl/io/iomgr/iomgr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/iomgr.c?r... ============================================================================== --- trunk/reactos/ntoskrnl/io/iomgr/iomgr.c (original) +++ trunk/reactos/ntoskrnl/io/iomgr/iomgr.c Sun Oct 8 11:53:37 2006 @@ -477,13 +477,14 @@ IoInit3(VOID) { NTSTATUS Status; + ANSI_STRING NtBootPath;
/* Create ARC names for boot devices */ IoCreateArcNames();
/* Create the SystemRoot symbolic link */ DPRINT("CommandLine: %s\n", KeLoaderBlock->LoadOptions); - Status = IoCreateSystemRootLink(KeLoaderBlock); + Status = IopReassignSystemRoot(KeLoaderBlock, &NtBootPath); if (!NT_SUCCESS(Status)) { CPRINT("IoCreateSystemRootLink FAILED: (0x%x) - ", Status); KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE); @@ -500,13 +501,15 @@
/* Load system start drivers */ IopInitializeSystemDrivers(); + + /* Destroy the group driver list */ IoDestroyDriverList();
/* Reinitialize drivers that requested it */ IopReinitializeDrivers();
- /* Stop boot logging */ - IopStopBootLog(); + /* Convert SystemRoot from ARC to NT path */ + if (!IopReassignSystemRoot(KeLoaderBlock, &NtBootPath)) KEBUGCHECK(0);
/* Assign drive letters */ IoAssignDriveLetters(KeLoaderBlock,