-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/arcname.c
- * PURPOSE: Creates ARC names for boot devices
- *
- * PROGRAMMERS: Eric Kohl (ekohl@rz-online.de)
- */
-
-/* INCLUDES *****************************************************************/
+/*
+* PROJECT: ReactOS Kernel
+* LICENSE: GPL - See COPYING in the top level directory
+* FILE: ntoskrnl/io/iomgr/arcname.c
+* PURPOSE: ARC Path Initialization Functions
+* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+* Eric Kohl
+*/
+
+/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
UNICODE_STRING IoArcHalDeviceName, IoArcBootDeviceName;
PCHAR IoLoaderArcBootDeviceName;
+extern PROS_LOADER_PARAMETER_BLOCK KeRosLoaderBlock;
-/* FUNCTIONS ****************************************************************/
+/* FUNCTIONS *****************************************************************/
BOOLEAN
INIT_FUNCTION
{
ULONG DeviceNumber = -1;
OBJECT_ATTRIBUTES ObjectAttributes;
+ ANSI_STRING InstallName;
UNICODE_STRING DeviceName;
- WCHAR Buffer[MAX_PATH];
- CHAR AnsiBuffer[MAX_PATH];
+ CHAR Buffer[128], RosSysPath[16];
FILE_BASIC_INFORMATION FileInfo;
NTSTATUS Status;
PCHAR p, q;
+ PCONFIGURATION_INFORMATION ConfigInfo = IoGetConfigurationInformation();
+ extern BOOLEAN InitIsWinPEMode, ExpInTextModeSetup;
+
+ /* Change this if you want ROS to boot properly from another directory */
+ sprintf(RosSysPath, "%s", "reactos");
/* Only ARC Name left - Build full ARC Name */
p = strstr(KeLoaderBlock->ArcBootDeviceName, "cdrom");
if (p)
{
+ /* Build installer name */
+ sprintf(Buffer, "\\Device\\CdRom%lu\\%s\\ntoskrnl.exe", i, RosSysPath);
+ RtlInitAnsiString(&InstallName, Buffer);
+ Status = RtlAnsiStringToUnicodeString(&DeviceName, &InstallName, TRUE);
+ if (!NT_SUCCESS(Status)) return FALSE;
+
/* 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;
+ /* Free the string */
+ RtlFreeUnicodeString(&DeviceName);
- /* Build the name */
- sprintf(p, "cdrom(%lu)", DeviceNumber);
+ /* Check if we found the file */
+ if (NT_SUCCESS(Status))
+ {
+ /* We did, save the device number */
+ DeviceNumber = i;
+ }
+ else
+ {
+ /* Build live CD kernel name */
+ sprintf(Buffer,
+ "\\Device\\CdRom%lu\\%s\\system32\\ntoskrnl.exe",
+ i, RosSysPath);
+ RtlInitAnsiString(&InstallName, Buffer);
+ Status = RtlAnsiStringToUnicodeString(&DeviceName,
+ &InstallName,
+ TRUE);
+ if (!NT_SUCCESS(Status)) return FALSE;
+
+ /* Try to find it */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &DeviceName,
+ 0,
+ NULL,
+ NULL);
+ Status = ZwQueryAttributesFile(&ObjectAttributes, &FileInfo);
+ if (NT_SUCCESS(Status)) DeviceNumber = i;
+
+ /* Free the string */
+ RtlFreeUnicodeString(&DeviceName);
+ }
- /* Adjust original command line */
- q = strchr(p, ')');
- if (q)
+ if (!InitIsWinPEMode)
{
- q++;
- strcpy(AnsiBuffer, q);
+ /* Build the name */
sprintf(p, "cdrom(%lu)", DeviceNumber);
- strcat(p, AnsiBuffer);
+
+ /* Adjust original command line */
+ q = strchr(p, ')');
+ if (q)
+ {
+ q++;
+ strcpy(Buffer, q);
+ sprintf(p, "cdrom(%lu)", DeviceNumber);
+ strcat(p, Buffer);
+ }
}
}
+ /* OK, how many disks are there? */
+ DeviceNumber += ConfigInfo->DiskCount;
+
/* Return whether this is the CD or not */
- if (DeviceNumber != 1) return TRUE;
+ if ((InitIsWinPEMode) || (ExpInTextModeSetup))
+ {
+ return TRUE;
+ }
+
+ /* Failed */
return FALSE;
}
{
ULONG j, Checksum;
ANSI_STRING TempString;
- CHAR Buffer[256];
+ CHAR Buffer[128];
UNICODE_STRING DeviceName;
NTSTATUS Status;
PDEVICE_OBJECT DeviceObject;
PIRP Irp;
IO_STATUS_BLOCK StatusBlock;
LARGE_INTEGER PartitionOffset;
- PPARTITION_SECTOR PartitionBuffer;
+ PULONG PartitionBuffer;
/* Build the name */
sprintf(Buffer, "\\Device\\Harddisk%lu\\Partition0", i);
/* Get the device pointer */
Status = IoGetDeviceObjectPointer(&DeviceName,
- FILE_READ_DATA,
+ FILE_READ_ATTRIBUTES,
&FileObject,
&DeviceObject);
*DiskDeviceObject = DeviceObject;
PartitionBuffer = ExAllocatePoolWithTag(NonPagedPool,
DiskGeometry.BytesPerSector,
TAG_IO);
- if (!PartitionBuffer) return FALSE;
+ if (!PartitionBuffer)
+ {
+ /* Try again */
+ ExFreePoolWithTag(DriveLayout, TAG_FILE_SYSTEM);
+ return FALSE;
+ }
/* Build an IRP to read the partition sector */
KeInitializeEvent(&Event, NotificationEvent, FALSE);
&PartitionOffset,
&Event,
&StatusBlock);
+ if (!Irp)
+ {
+ /* Try again */
+ ExFreePoolWithTag(PartitionBuffer, TAG_IO);
+ ExFreePoolWithTag(DriveLayout, TAG_FILE_SYSTEM);
+ return FALSE;
+ }
/* Call the driver and check if we have to wait */
Status = IoCallDriver(DeviceObject, Irp);
if (!NT_SUCCESS(Status))
{
/* Try again */
- ExFreePool(PartitionBuffer);
- ExFreePool(DriveLayout);
+ ExFreePoolWithTag(PartitionBuffer, TAG_IO);
+ ExFreePoolWithTag(DriveLayout, TAG_FILE_SYSTEM);
return FALSE;
}
/* Calculate the MBR checksum */
Checksum = 0;
- for (j = 0; j < 128; j++)
- {
- Checksum += ((PULONG)PartitionBuffer)[j];
- }
+ for (j = 0; j < 128; j++) Checksum += PartitionBuffer[j];
/* Save the signature and checksum */
*CheckSum = ~Checksum + 1;
*PartitionCount = DriveLayout->PartitionCount;
/* Free the buffer */
- ExFreePool(PartitionBuffer);
- ExFreePool(DriveLayout);
+ ExFreePoolWithTag(PartitionBuffer, TAG_IO);
+ ExFreePoolWithTag(DriveLayout, TAG_FILE_SYSTEM);
return TRUE;
}
BOOLEAN
INIT_FUNCTION
NTAPI
-IopAssignArcNamesToCdrom(IN PULONG Buffer,
+IopAssignArcNamesToCdrom(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+ IN PULONG Buffer,
IN ULONG DiskNumber)
{
- CHAR ArcBuffer[256];
- ANSI_STRING TempString, ArcNameString;
+ CHAR ArcBuffer[128];
+ ANSI_STRING TempString;
UNICODE_STRING DeviceName, ArcName;
NTSTATUS Status;
LARGE_INTEGER PartitionOffset;
ULONG i, CheckSum = 0;
PDEVICE_OBJECT DeviceObject;
PFILE_OBJECT FileObject;
+ PARC_DISK_INFORMATION ArcDiskInfo = LoaderBlock->ArcDiskInformation;
+ PLIST_ENTRY NextEntry;
+ PARC_DISK_SIGNATURE ArcDiskEntry;
+ BOOLEAN IsBootCdRom = FALSE;
/* Build the device name */
sprintf(ArcBuffer, "\\Device\\CdRom%lu", DiskNumber);
/* Now calculate the checksum */
for (i = 0; i < 2048 / sizeof(ULONG); i++) CheckSum += Buffer[i];
+ if (KeRosLoaderBlock) goto freeldrhack;
+
+ /* Search if this device is the actual boot CD */
+ for (NextEntry = ArcDiskInfo->DiskSignatureListHead.Flink;
+ NextEntry != &ArcDiskInfo->DiskSignatureListHead;
+ NextEntry = NextEntry->Flink)
+ {
+ /* Get the current ARC disk signature entry */
+ ArcDiskEntry = CONTAINING_RECORD(NextEntry,
+ ARC_DISK_SIGNATURE,
+ ListEntry);
+ /* And check if checksums and arc names match */
+ if (CheckSum == ArcDiskEntry->CheckSum &&
+ strcmp(KeLoaderBlock->ArcBootDeviceName, ArcDiskEntry->ArcName) == 0)
+ {
+ IsBootCdRom = TRUE;
+ break;
+ }
+ }
+ goto checkbootcd;
+
+freeldrhack:
/*
* FIXME: In normal conditions, NTLDR/FreeLdr sends the *proper* CDROM
* ARC Path name, and what happens here is a comparision of both checksums
* The signature code stays however, because eventually FreeLDR will work
* like NTLDR, and, conversly, we do want to be able to be booted by NTLDR.
*/
- if (IopApplyRosCdromArcHack(DiskNumber))
+ IsBootCdRom = IopApplyRosCdromArcHack(DiskNumber);
+
+checkbootcd:
+ if (IsBootCdRom)
{
/* This is the boot CD-ROM, build the ARC name */
sprintf(ArcBuffer, "\\ArcName\\%s", KeLoaderBlock->ArcBootDeviceName);
/* Convert it to Unicode */
- RtlInitAnsiString(&ArcNameString, ArcBuffer);
- Status = RtlAnsiStringToUnicodeString(&ArcName, &ArcNameString, TRUE);
+ RtlInitAnsiString(&TempString, ArcBuffer);
+ Status = RtlAnsiStringToUnicodeString(&ArcName, &TempString, TRUE);
if (!NT_SUCCESS(Status)) return FALSE;
/* Create the symbolic link and free the strings */
NTSTATUS
INIT_FUNCTION
-IoCreateArcNames(VOID)
+NTAPI
+IopCreateArcNames(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
- PLOADER_PARAMETER_BLOCK LoaderBlock = KeLoaderBlock;
PCONFIGURATION_INFORMATION ConfigInfo = IoGetConfigurationInformation();
PARC_DISK_INFORMATION ArcDiskInfo = LoaderBlock->ArcDiskInformation;
- CHAR ArcBuffer[256], Buffer[256];
- ANSI_STRING ArcBootString, ArcSystemString, ArcString, TempString, BootString;
+ CHAR Buffer[128];
+ ANSI_STRING ArcBootString, ArcSystemString, ArcString;
UNICODE_STRING ArcName, BootPath, DeviceName;
BOOLEAN SingleDisk;
ULONG i, j, Length;
(&ArcDiskInfo->DiskSignatureListHead);
/* Create the global HAL partition name */
- sprintf(ArcBuffer, "\\ArcName\\%s", LoaderBlock->ArcHalDeviceName);
- RtlInitAnsiString(&ArcString, ArcBuffer);
+ sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcHalDeviceName);
+ RtlInitAnsiString(&ArcString, Buffer);
RtlAnsiStringToUnicodeString(&IoArcHalDeviceName, &ArcString, TRUE);
/* Create the global system partition name */
- sprintf(ArcBuffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName);
- RtlInitAnsiString(&ArcString, ArcBuffer);
+ sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName);
+ RtlInitAnsiString(&ArcString, Buffer);
RtlAnsiStringToUnicodeString(&IoArcBootDeviceName, &ArcString, TRUE);
/* Allocate memory for the string */
if (IoLoaderArcBootDeviceName)
{
/* Copy the name */
- RtlMoveMemory(IoLoaderArcBootDeviceName,
+ RtlCopyMemory(IoLoaderArcBootDeviceName,
LoaderBlock->ArcBootDeviceName,
Length);
}
sprintf(Buffer, "\\Device\\Harddisk%lu\\Partition0", i);
/* Convert it to Unicode */
- RtlInitAnsiString(&TempString, Buffer);
- Status = RtlAnsiStringToUnicodeString(&DeviceName, &TempString, TRUE);
+ RtlInitAnsiString(&ArcString, Buffer);
+ Status = RtlAnsiStringToUnicodeString(&DeviceName,
+ &ArcString,
+ TRUE);
if (!NT_SUCCESS(Status)) continue;
/* Build the ARC Device Name */
- sprintf(ArcBuffer, "\\ArcName\\%s", ArcDiskEntry->ArcName);
+ sprintf(Buffer, "\\ArcName\\%s", ArcDiskEntry->ArcName);
/* Convert it to Unicode */
- RtlInitAnsiString(&ArcString, ArcBuffer);
- Status = RtlAnsiStringToUnicodeString(&ArcName, &ArcString, TRUE);
+ RtlInitAnsiString(&ArcString, Buffer);
+ Status = RtlAnsiStringToUnicodeString(&ArcName,
+ &ArcString,
+ TRUE);
if (!NT_SUCCESS(Status)) continue;
/* Create the symbolic link and free the strings */
for (j = 0; j < PartitionCount; j++)
{
/* Build the partition device name */
- sprintf(Buffer, "\\Device\\Harddisk%lu\\Partition%lu", i, j + 1);
+ sprintf(Buffer,
+ "\\Device\\Harddisk%lu\\Partition%lu",
+ i,
+ j + 1);
/* Convert it to Unicode */
- RtlInitAnsiString(&TempString, Buffer);
- Status = RtlAnsiStringToUnicodeString(&DeviceName, &TempString, TRUE);
+ RtlInitAnsiString(&ArcString, Buffer);
+ Status = RtlAnsiStringToUnicodeString(&DeviceName,
+ &ArcString,
+ TRUE);
if (!NT_SUCCESS(Status)) continue;
/* Build the partial ARC name for this partition */
- sprintf(ArcBuffer, "%spartition(%lu)", ArcDiskEntry->ArcName, j + 1);
- RtlInitAnsiString(&ArcString, ArcBuffer);
+ sprintf(Buffer,
+ "%spartition(%lu)",
+ ArcDiskEntry->ArcName,
+ j + 1);
+ RtlInitAnsiString(&ArcString, Buffer);
/* Check if this is the boot device */
if (RtlEqualString(&ArcString, &ArcBootString, TRUE))
if (RtlEqualString(&ArcString, &ArcSystemString, TRUE))
{
/* It is, create a Unicode string for it */
- RtlInitAnsiString(&BootString, LoaderBlock->NtHalPathName);
- Status = RtlAnsiStringToUnicodeString(&BootPath, &BootString, TRUE);
+ RtlInitAnsiString(&ArcString,
+ LoaderBlock->NtHalPathName);
+ Status = RtlAnsiStringToUnicodeString(&BootPath,
+ &ArcString,
+ TRUE);
if (NT_SUCCESS(Status))
{
/* FIXME: Save in registry */
}
/* Build the full ARC name */
- sprintf(Buffer, "\\ArcName\\%spartition(%lu)", ArcDiskEntry->ArcName, j + 1);
+ sprintf(Buffer,
+ "\\ArcName\\%spartition(%lu)",
+ ArcDiskEntry->ArcName,
+ j + 1);
/* Convert it to Unicode */
RtlInitAnsiString(&ArcString, Buffer);
- Status = RtlAnsiStringToUnicodeString(&ArcName, &ArcString, TRUE);
+ Status = RtlAnsiStringToUnicodeString(&ArcName,
+ &ArcString,
+ TRUE);
if (!NT_SUCCESS(Status)) continue;
/* Create the symbolic link and free the strings */
for (i = 0; i < ConfigInfo->CdRomCount; i++)
{
/* Give it an ARC name */
- if (IopAssignArcNamesToCdrom(PartitionBuffer, i)) break;
+ if (IopAssignArcNamesToCdrom(LoaderBlock, PartitionBuffer, i)) break;
}
/* Free the buffer */
- ExFreePool(PartitionBuffer);
+ ExFreePoolWithTag(PartitionBuffer, TAG_IO);
}
/* Return success */