/* 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
ExpInitNls(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
}
/* Create SystemRoot Link */
+ Status = ExpCreateSystemRootLink(KeLoaderBlock);
+ if (!NT_SUCCESS(Status))
+ {
+ KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 0, 0, 0);
+ }
/* Create NLS section */
ExpInitNls(KeLoaderBlock);
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
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++)
+ 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)
{
-#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.
- */
+ /* 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;
+ }
- swprintf(DeviceNameBuffer,
- L"\\Device\\CdRom%lu\\reactos\\system32\\ntoskrnl.exe",
- i);
- RtlInitUnicodeString(&DeviceName,
- DeviceNameBuffer);
+ /* Build the name */
+ sprintf(p, "cdrom(%lu)", DeviceNumber);
- 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);
- }
+ /* Adjust original command line */
+ q = strchr(p, ')');
+ if (q)
+ {
+ q++;
+ strcpy(AnsiBuffer, q);
+ sprintf(p, "cdrom(%lu)", DeviceNumber);
+ strcat(p, AnsiBuffer);
+ }
}
-
- DPRINT("Could not find ntoskrnl.exe\n");
- *DeviceNumber = (ULONG)-1;
-
- return(STATUS_UNSUCCESSFUL);
}
-
-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))
+ 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))
{
- CPRINT("IoCreateSymbolicLink() failed (Status %x)\n",
- Status);
-
- return(Status);
+ /* We failed, free the string */
+ RtlFreeUnicodeString(&TargetName);
+ return FALSE;
}
- /* 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))
+ /* Query the current \\SystemRoot */
+ ArcName.Buffer = ArcNameBuffer;
+ ArcName.Length = 0;
+ ArcName.MaximumLength = sizeof(ArcNameBuffer);
+ Status = NtQuerySymbolicLinkObject(LinkHandle, &ArcName, NULL);
+ if (!NT_SUCCESS(Status))
{
- CPRINT("ZwOpenFile() failed to open '\\SystemRoot' (Status %x)\n",
- Status);
- return(Status);
+ /* We failed, free the string */
+ RtlFreeUnicodeString(&TargetName);
+ return FALSE;
}
- ZwClose(Handle);
-
- return(STATUS_SUCCESS);
+ /* 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 */