mirror of
https://github.com/reactos/reactos.git
synced 2025-01-06 06:20:13 +00:00
- Part 2 of ARC boot changes: Major modifications done to the existing code, as well as re-formatting and cleanup. Floppy ARC names are not created anymore (they don't exist), and CD-ROM ARC name is only created 1) when there is a boot CD and 2) only for the boot CD. This mimics NT functionality.
- Optimize some code paths, mostly by not querying the whole GET_DRIVE_GEOMETRY IRP twice and reducing some buffer usage. Also re-factor some code better into smaller functions. - Document and work around currently FreeLDR incompatibility (lack of ARC_DISK_INFORMATION) data in LoaderBlock. svn path=/trunk/; revision=24451
This commit is contained in:
parent
b234cb305e
commit
7a1b73cf84
3 changed files with 490 additions and 429 deletions
|
@ -73,6 +73,19 @@ typedef struct _BOOT_DRIVER_LIST_ENTRY
|
||||||
struct _LDR_DATA_TABLE_ENTRY *DataTableEntry;
|
struct _LDR_DATA_TABLE_ENTRY *DataTableEntry;
|
||||||
} BOOT_DRIVER_LIST_ENTRY, *PBOOT_DRIVER_LIST_ENTRY;
|
} BOOT_DRIVER_LIST_ENTRY, *PBOOT_DRIVER_LIST_ENTRY;
|
||||||
|
|
||||||
|
typedef struct _ARC_DISK_SIGNATURE
|
||||||
|
{
|
||||||
|
LIST_ENTRY ListEntry;
|
||||||
|
ULONG Signature;
|
||||||
|
PCHAR ArcName;
|
||||||
|
ULONG CheckSum;
|
||||||
|
BOOLEAN ValidPartitionTable;
|
||||||
|
BOOLEAN xInt13;
|
||||||
|
BOOLEAN IsGpt;
|
||||||
|
BOOLEAN Reserved;
|
||||||
|
CHAR GptSignature[16];
|
||||||
|
} ARC_DISK_SIGNATURE, *PARC_DISK_SIGNATURE;
|
||||||
|
|
||||||
typedef struct _CONFIGURATION_COMPONENT
|
typedef struct _CONFIGURATION_COMPONENT
|
||||||
{
|
{
|
||||||
CONFIGURATION_CLASS Class;
|
CONFIGURATION_CLASS Class;
|
||||||
|
|
|
@ -423,6 +423,7 @@ typedef struct _DISKENTRY
|
||||||
ULONG Signature;
|
ULONG Signature;
|
||||||
ULONG Checksum;
|
ULONG Checksum;
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
ULONG PartitionCount;
|
||||||
} DISKENTRY, *PDISKENTRY;
|
} DISKENTRY, *PDISKENTRY;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -15,34 +15,6 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
static NTSTATUS
|
|
||||||
STDCALL INIT_FUNCTION
|
|
||||||
DiskQueryRoutine(PWSTR ValueName,
|
|
||||||
ULONG ValueType,
|
|
||||||
PVOID ValueData,
|
|
||||||
ULONG ValueLength,
|
|
||||||
PVOID Context,
|
|
||||||
PVOID EntryContext);
|
|
||||||
|
|
||||||
static VOID INIT_FUNCTION
|
|
||||||
IopEnumerateBiosDisks(PLIST_ENTRY ListHead);
|
|
||||||
|
|
||||||
static VOID INIT_FUNCTION
|
|
||||||
IopEnumerateDisks(PLIST_ENTRY ListHead);
|
|
||||||
|
|
||||||
static NTSTATUS INIT_FUNCTION
|
|
||||||
IopAssignArcNamesToDisk(PDEVICE_OBJECT DeviceObject, ULONG RDisk, ULONG DiskNumber);
|
|
||||||
|
|
||||||
#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, IoCreateSystemRootLink)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* MACROS *******************************************************************/
|
/* MACROS *******************************************************************/
|
||||||
|
|
||||||
#define FS_VOLUME_BUFFER_SIZE (MAX_PATH + sizeof(FILE_FS_VOLUME_INFORMATION))
|
#define FS_VOLUME_BUFFER_SIZE (MAX_PATH + sizeof(FILE_FS_VOLUME_INFORMATION))
|
||||||
|
@ -174,420 +146,47 @@ IopEnumerateBiosDisks(PLIST_ENTRY ListHead)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID INIT_FUNCTION
|
BOOLEAN
|
||||||
IopEnumerateDisks(PLIST_ENTRY ListHead)
|
|
||||||
{
|
|
||||||
ULONG i, k;
|
|
||||||
PDISKENTRY DiskEntry;
|
|
||||||
DISK_GEOMETRY DiskGeometry;
|
|
||||||
KEVENT Event;
|
|
||||||
PIRP Irp;
|
|
||||||
IO_STATUS_BLOCK StatusBlock;
|
|
||||||
LARGE_INTEGER PartitionOffset;
|
|
||||||
PULONG Buffer;
|
|
||||||
WCHAR DeviceNameBuffer[80];
|
|
||||||
UNICODE_STRING DeviceName;
|
|
||||||
NTSTATUS Status;
|
|
||||||
PDEVICE_OBJECT DeviceObject;
|
|
||||||
PFILE_OBJECT FileObject;
|
|
||||||
BOOLEAN IsRemovableMedia;
|
|
||||||
PPARTITION_SECTOR PartitionBuffer = NULL;
|
|
||||||
ULONG PartitionBufferSize = 0;
|
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < IoGetConfigurationInformation()->DiskCount; i++)
|
|
||||||
{
|
|
||||||
|
|
||||||
swprintf(DeviceNameBuffer,
|
|
||||||
L"\\Device\\Harddisk%lu\\Partition0",
|
|
||||||
i);
|
|
||||||
RtlInitUnicodeString(&DeviceName,
|
|
||||||
DeviceNameBuffer);
|
|
||||||
|
|
||||||
|
|
||||||
Status = IoGetDeviceObjectPointer(&DeviceName,
|
|
||||||
FILE_READ_DATA,
|
|
||||||
&FileObject,
|
|
||||||
&DeviceObject);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
IsRemovableMedia = DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA ? TRUE : FALSE;
|
|
||||||
ObDereferenceObject(FileObject);
|
|
||||||
if (IsRemovableMedia)
|
|
||||||
{
|
|
||||||
ObDereferenceObject(DeviceObject);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
DiskEntry = ExAllocatePool(PagedPool, sizeof(DISKENTRY));
|
|
||||||
if (DiskEntry == NULL)
|
|
||||||
{
|
|
||||||
KEBUGCHECK(0);
|
|
||||||
}
|
|
||||||
DiskEntry->DiskNumber = i;
|
|
||||||
DiskEntry->DeviceObject = DeviceObject;
|
|
||||||
|
|
||||||
/* determine the sector size */
|
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
|
||||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_GEOMETRY,
|
|
||||||
DeviceObject,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
&DiskGeometry,
|
|
||||||
sizeof(DISK_GEOMETRY),
|
|
||||||
FALSE,
|
|
||||||
&Event,
|
|
||||||
&StatusBlock);
|
|
||||||
if (Irp == NULL)
|
|
||||||
{
|
|
||||||
KEBUGCHECK(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = IoCallDriver(DeviceObject, Irp);
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event,
|
|
||||||
Executive,
|
|
||||||
KernelMode,
|
|
||||||
FALSE,
|
|
||||||
NULL);
|
|
||||||
Status = StatusBlock.Status;
|
|
||||||
}
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
KEBUGCHECK(0);
|
|
||||||
}
|
|
||||||
if (PartitionBuffer != NULL && PartitionBufferSize < DiskGeometry.BytesPerSector)
|
|
||||||
{
|
|
||||||
ExFreePool(PartitionBuffer);
|
|
||||||
PartitionBuffer = NULL;
|
|
||||||
}
|
|
||||||
if (PartitionBuffer == NULL)
|
|
||||||
{
|
|
||||||
PartitionBufferSize = max(DiskGeometry.BytesPerSector, PAGE_SIZE);
|
|
||||||
PartitionBuffer = ExAllocatePool(PagedPool, PartitionBufferSize);
|
|
||||||
if (PartitionBuffer == NULL)
|
|
||||||
{
|
|
||||||
KEBUGCHECK(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read the partition sector */
|
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
|
||||||
PartitionOffset.QuadPart = 0;
|
|
||||||
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
|
|
||||||
DeviceObject,
|
|
||||||
PartitionBuffer,
|
|
||||||
DiskGeometry.BytesPerSector,
|
|
||||||
&PartitionOffset,
|
|
||||||
&Event,
|
|
||||||
&StatusBlock);
|
|
||||||
Status = IoCallDriver(DeviceObject, Irp);
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event,
|
|
||||||
Executive,
|
|
||||||
KernelMode,
|
|
||||||
FALSE,
|
|
||||||
NULL);
|
|
||||||
Status = StatusBlock.Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
KEBUGCHECK(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate the MBR checksum */
|
|
||||||
DiskEntry->Checksum = 0;
|
|
||||||
Buffer = (PULONG)PartitionBuffer;
|
|
||||||
for (k = 0; k < 128; k++)
|
|
||||||
{
|
|
||||||
DiskEntry->Checksum += Buffer[k];
|
|
||||||
}
|
|
||||||
DiskEntry->Checksum = ~DiskEntry->Checksum + 1;
|
|
||||||
DiskEntry->Signature = PartitionBuffer->Signature;
|
|
||||||
|
|
||||||
InsertTailList(ListHead, &DiskEntry->ListEntry);
|
|
||||||
}
|
|
||||||
if (PartitionBuffer)
|
|
||||||
{
|
|
||||||
ExFreePool(PartitionBuffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static NTSTATUS INIT_FUNCTION
|
|
||||||
IopAssignArcNamesToDisk(PDEVICE_OBJECT DeviceObject, ULONG RDisk, ULONG DiskNumber)
|
|
||||||
{
|
|
||||||
WCHAR DeviceNameBuffer[80];
|
|
||||||
WCHAR ArcNameBuffer[80];
|
|
||||||
UNICODE_STRING DeviceName;
|
|
||||||
UNICODE_STRING ArcName;
|
|
||||||
PDRIVE_LAYOUT_INFORMATION LayoutInfo = NULL;
|
|
||||||
NTSTATUS Status;
|
|
||||||
ULONG i;
|
|
||||||
KEVENT Event;
|
|
||||||
PIRP Irp;
|
|
||||||
IO_STATUS_BLOCK StatusBlock;
|
|
||||||
ULONG PartitionNumber;
|
|
||||||
|
|
||||||
swprintf(DeviceNameBuffer,
|
|
||||||
L"\\Device\\Harddisk%lu\\Partition0",
|
|
||||||
DiskNumber);
|
|
||||||
RtlInitUnicodeString(&DeviceName,
|
|
||||||
DeviceNameBuffer);
|
|
||||||
|
|
||||||
swprintf(ArcNameBuffer,
|
|
||||||
L"\\ArcName\\multi(0)disk(0)rdisk(%lu)",
|
|
||||||
RDisk);
|
|
||||||
RtlInitUnicodeString(&ArcName,
|
|
||||||
ArcNameBuffer);
|
|
||||||
|
|
||||||
DPRINT("%wZ ==> %wZ\n", &ArcName, &DeviceName);
|
|
||||||
|
|
||||||
Status = IoAssignArcName(&ArcName, &DeviceName);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("IoAssignArcName failed, status=%lx\n", Status);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
LayoutInfo = ExAllocatePool(PagedPool, 2 * PAGE_SIZE);
|
|
||||||
if (LayoutInfo == NULL)
|
|
||||||
{
|
|
||||||
return STATUS_NO_MEMORY;
|
|
||||||
}
|
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
|
||||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_LAYOUT,
|
|
||||||
DeviceObject,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
LayoutInfo,
|
|
||||||
2 * PAGE_SIZE,
|
|
||||||
FALSE,
|
|
||||||
&Event,
|
|
||||||
&StatusBlock);
|
|
||||||
if (Irp == NULL)
|
|
||||||
{
|
|
||||||
ExFreePool(LayoutInfo);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = IoCallDriver(DeviceObject, Irp);
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event,
|
|
||||||
Executive,
|
|
||||||
KernelMode,
|
|
||||||
FALSE,
|
|
||||||
NULL);
|
|
||||||
Status = StatusBlock.Status;
|
|
||||||
}
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
ExFreePool(LayoutInfo);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("Number of partitions: %u\n", LayoutInfo->PartitionCount);
|
|
||||||
|
|
||||||
PartitionNumber = 1;
|
|
||||||
for (i = 0; i < LayoutInfo->PartitionCount; i++)
|
|
||||||
{
|
|
||||||
if (!IsContainerPartition(LayoutInfo->PartitionEntry[i].PartitionType) &&
|
|
||||||
LayoutInfo->PartitionEntry[i].PartitionType != PARTITION_ENTRY_UNUSED)
|
|
||||||
{
|
|
||||||
|
|
||||||
swprintf(DeviceNameBuffer,
|
|
||||||
L"\\Device\\Harddisk%lu\\Partition%lu",
|
|
||||||
DiskNumber,
|
|
||||||
PartitionNumber);
|
|
||||||
RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
|
|
||||||
|
|
||||||
swprintf(ArcNameBuffer,
|
|
||||||
L"\\ArcName\\multi(0)disk(0)rdisk(%lu)partition(%lu)",
|
|
||||||
RDisk,
|
|
||||||
PartitionNumber);
|
|
||||||
RtlInitUnicodeString(&ArcName, ArcNameBuffer);
|
|
||||||
|
|
||||||
DPRINT("%wZ ==> %wZ\n", &ArcName, &DeviceName);
|
|
||||||
|
|
||||||
Status = IoAssignArcName(&ArcName, &DeviceName);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("IoAssignArcName failed, status=%lx\n", Status);
|
|
||||||
ExFreePool(LayoutInfo);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
PartitionNumber++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ExFreePool(LayoutInfo);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS INIT_FUNCTION
|
|
||||||
IoCreateArcNames(VOID)
|
|
||||||
{
|
|
||||||
PCONFIGURATION_INFORMATION ConfigInfo;
|
|
||||||
WCHAR DeviceNameBuffer[80];
|
|
||||||
WCHAR ArcNameBuffer[80];
|
|
||||||
UNICODE_STRING DeviceName;
|
|
||||||
UNICODE_STRING ArcName;
|
|
||||||
ULONG i, RDiskNumber;
|
|
||||||
NTSTATUS Status;
|
|
||||||
LIST_ENTRY BiosDiskListHead;
|
|
||||||
LIST_ENTRY DiskListHead;
|
|
||||||
PLIST_ENTRY Entry;
|
|
||||||
PDISKENTRY BiosDiskEntry;
|
|
||||||
PDISKENTRY DiskEntry;
|
|
||||||
|
|
||||||
DPRINT("IoCreateArcNames() called\n");
|
|
||||||
|
|
||||||
ConfigInfo = IoGetConfigurationInformation();
|
|
||||||
|
|
||||||
/* create ARC names for floppy drives */
|
|
||||||
DPRINT("Floppy drives: %lu\n", ConfigInfo->FloppyCount);
|
|
||||||
for (i = 0; i < ConfigInfo->FloppyCount; i++)
|
|
||||||
{
|
|
||||||
swprintf(DeviceNameBuffer,
|
|
||||||
L"\\Device\\Floppy%lu",
|
|
||||||
i);
|
|
||||||
RtlInitUnicodeString(&DeviceName,
|
|
||||||
DeviceNameBuffer);
|
|
||||||
|
|
||||||
swprintf(ArcNameBuffer,
|
|
||||||
L"\\ArcName\\multi(0)disk(0)fdisk(%lu)",
|
|
||||||
i);
|
|
||||||
RtlInitUnicodeString(&ArcName,
|
|
||||||
ArcNameBuffer);
|
|
||||||
DPRINT("%wZ ==> %wZ\n",
|
|
||||||
&ArcName,
|
|
||||||
&DeviceName);
|
|
||||||
|
|
||||||
Status = IoAssignArcName(&ArcName,
|
|
||||||
&DeviceName);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* create ARC names for hard disk drives */
|
|
||||||
InitializeListHead(&BiosDiskListHead);
|
|
||||||
InitializeListHead(&DiskListHead);
|
|
||||||
IopEnumerateBiosDisks(&BiosDiskListHead);
|
|
||||||
IopEnumerateDisks(&DiskListHead);
|
|
||||||
|
|
||||||
RDiskNumber = 0;
|
|
||||||
while (!IsListEmpty(&BiosDiskListHead))
|
|
||||||
{
|
|
||||||
Entry = RemoveHeadList(&BiosDiskListHead);
|
|
||||||
BiosDiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
|
|
||||||
Entry = DiskListHead.Flink;
|
|
||||||
while (Entry != &DiskListHead)
|
|
||||||
{
|
|
||||||
DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
|
|
||||||
if (DiskEntry->Checksum == BiosDiskEntry->Checksum &&
|
|
||||||
DiskEntry->Signature == BiosDiskEntry->Signature)
|
|
||||||
{
|
|
||||||
|
|
||||||
Status = IopAssignArcNamesToDisk(DiskEntry->DeviceObject, RDiskNumber, DiskEntry->DiskNumber);
|
|
||||||
|
|
||||||
RemoveEntryList(&DiskEntry->ListEntry);
|
|
||||||
ExFreePool(DiskEntry);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Entry = Entry->Flink;
|
|
||||||
}
|
|
||||||
RDiskNumber++;
|
|
||||||
ExFreePool(BiosDiskEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!IsListEmpty(&DiskListHead))
|
|
||||||
{
|
|
||||||
Entry = RemoveHeadList(&DiskListHead);
|
|
||||||
DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
|
|
||||||
ExFreePool(DiskEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* create ARC names for cdrom drives */
|
|
||||||
DPRINT("CD-ROM drives: %lu\n", ConfigInfo->CdRomCount);
|
|
||||||
for (i = 0; i < ConfigInfo->CdRomCount; i++)
|
|
||||||
{
|
|
||||||
swprintf(DeviceNameBuffer,
|
|
||||||
L"\\Device\\CdRom%lu",
|
|
||||||
i);
|
|
||||||
RtlInitUnicodeString(&DeviceName,
|
|
||||||
DeviceNameBuffer);
|
|
||||||
|
|
||||||
swprintf(ArcNameBuffer,
|
|
||||||
L"\\ArcName\\multi(0)disk(0)cdrom(%lu)",
|
|
||||||
i);
|
|
||||||
RtlInitUnicodeString(&ArcName,
|
|
||||||
ArcNameBuffer);
|
|
||||||
DPRINT("%wZ ==> %wZ\n",
|
|
||||||
&ArcName,
|
|
||||||
&DeviceName);
|
|
||||||
|
|
||||||
Status = IoAssignArcName(&ArcName,
|
|
||||||
&DeviceName);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("IoCreateArcNames() done\n");
|
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
INIT_FUNCTION
|
INIT_FUNCTION
|
||||||
NTAPI
|
NTAPI
|
||||||
IopApplyRosCdromArcHack(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
IopApplyRosCdromArcHack(IN ULONG i)
|
||||||
{
|
{
|
||||||
ULONG DeviceNumber = -1;
|
ULONG DeviceNumber = -1;
|
||||||
PCONFIGURATION_INFORMATION ConfigInfo;
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
UNICODE_STRING DeviceName;
|
UNICODE_STRING DeviceName;
|
||||||
WCHAR Buffer[MAX_PATH];
|
WCHAR Buffer[MAX_PATH];
|
||||||
CHAR AnsiBuffer[MAX_PATH];
|
CHAR AnsiBuffer[MAX_PATH];
|
||||||
ULONG i;
|
|
||||||
FILE_BASIC_INFORMATION FileInfo;
|
FILE_BASIC_INFORMATION FileInfo;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PCHAR p, q;
|
PCHAR p, q;
|
||||||
|
|
||||||
/* Only ARC Name left - Build full ARC Name */
|
/* Only ARC Name left - Build full ARC Name */
|
||||||
p = strstr(LoaderBlock->ArcBootDeviceName, "cdrom");
|
p = strstr(KeLoaderBlock->ArcBootDeviceName, "cdrom");
|
||||||
if (p)
|
if (p)
|
||||||
{
|
{
|
||||||
/* Get configuration information */
|
/* Try to find the installer */
|
||||||
ConfigInfo = IoGetConfigurationInformation();
|
swprintf(Buffer, L"\\Device\\CdRom%lu\\reactos\\ntoskrnl.exe", i);
|
||||||
for (i = 0; i < ConfigInfo->CdRomCount; i++)
|
RtlInitUnicodeString(&DeviceName, Buffer);
|
||||||
{
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
/* Try to find the installer */
|
&DeviceName,
|
||||||
swprintf(Buffer, L"\\Device\\CdRom%lu\\reactos\\ntoskrnl.exe", i);
|
0,
|
||||||
RtlInitUnicodeString(&DeviceName, Buffer);
|
NULL,
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
NULL);
|
||||||
&DeviceName,
|
Status = ZwQueryAttributesFile(&ObjectAttributes, &FileInfo);
|
||||||
0,
|
if (NT_SUCCESS(Status)) DeviceNumber = i;
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
Status = ZwQueryAttributesFile(&ObjectAttributes, &FileInfo);
|
|
||||||
if (NT_SUCCESS(Status)) DeviceNumber = i;
|
|
||||||
|
|
||||||
/* Try to find live CD boot */
|
/* Try to find live CD boot */
|
||||||
swprintf(Buffer,
|
swprintf(Buffer,
|
||||||
L"\\Device\\CdRom%lu\\reactos\\system32\\ntoskrnl.exe",
|
L"\\Device\\CdRom%lu\\reactos\\system32\\ntoskrnl.exe",
|
||||||
i);
|
i);
|
||||||
RtlInitUnicodeString(&DeviceName, Buffer);
|
RtlInitUnicodeString(&DeviceName, Buffer);
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
&DeviceName,
|
&DeviceName,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
Status = ZwQueryAttributesFile(&ObjectAttributes, &FileInfo);
|
Status = ZwQueryAttributesFile(&ObjectAttributes, &FileInfo);
|
||||||
if (NT_SUCCESS(Status)) DeviceNumber = i;
|
if (NT_SUCCESS(Status)) DeviceNumber = i;
|
||||||
}
|
|
||||||
|
|
||||||
/* Build the name */
|
/* Build the name */
|
||||||
sprintf(p, "cdrom(%lu)", DeviceNumber);
|
sprintf(p, "cdrom(%lu)", DeviceNumber);
|
||||||
|
@ -602,6 +201,457 @@ IopApplyRosCdromArcHack(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||||
strcat(p, AnsiBuffer);
|
strcat(p, AnsiBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return whether this is the CD or not */
|
||||||
|
if (DeviceNumber != 1) return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
INIT_FUNCTION
|
||||||
|
NTAPI
|
||||||
|
IopEnumerateDisks(IN PLIST_ENTRY ListHead)
|
||||||
|
{
|
||||||
|
ULONG i, j;
|
||||||
|
ANSI_STRING TempString;
|
||||||
|
CHAR Buffer[256];
|
||||||
|
UNICODE_STRING DeviceName;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
PFILE_OBJECT FileObject;
|
||||||
|
DISK_GEOMETRY DiskGeometry;
|
||||||
|
PDRIVE_LAYOUT_INFORMATION DriveLayout;
|
||||||
|
KEVENT Event;
|
||||||
|
PIRP Irp;
|
||||||
|
IO_STATUS_BLOCK StatusBlock;
|
||||||
|
LARGE_INTEGER PartitionOffset;
|
||||||
|
PPARTITION_SECTOR PartitionBuffer;
|
||||||
|
PDISKENTRY DiskEntry;
|
||||||
|
|
||||||
|
/* Loop every detected disk */
|
||||||
|
for (i = 0; i < IoGetConfigurationInformation()->DiskCount; i++)
|
||||||
|
{
|
||||||
|
/* Build the name */
|
||||||
|
sprintf(Buffer, "\\Device\\Harddisk%lu\\Partition0", i);
|
||||||
|
|
||||||
|
/* Convert it to Unicode */
|
||||||
|
RtlInitAnsiString(&TempString, Buffer);
|
||||||
|
Status = RtlAnsiStringToUnicodeString(&DeviceName, &TempString, TRUE);
|
||||||
|
if (!NT_SUCCESS(Status)) continue;
|
||||||
|
|
||||||
|
/* Get the device pointer */
|
||||||
|
Status = IoGetDeviceObjectPointer(&DeviceName,
|
||||||
|
FILE_READ_DATA,
|
||||||
|
&FileObject,
|
||||||
|
&DeviceObject);
|
||||||
|
|
||||||
|
/* Free the string */
|
||||||
|
RtlFreeUnicodeString(&DeviceName);
|
||||||
|
|
||||||
|
/* Move on if we failed */
|
||||||
|
if (!NT_SUCCESS(Status)) continue;
|
||||||
|
|
||||||
|
/* Allocate the ROS disk Entry */
|
||||||
|
DiskEntry = ExAllocatePoolWithTag(PagedPool, sizeof(DISKENTRY), TAG_IO);
|
||||||
|
DiskEntry->DiskNumber = i;
|
||||||
|
DiskEntry->DeviceObject = DeviceObject;
|
||||||
|
|
||||||
|
/* Build an IRP to determine the sector size */
|
||||||
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_GEOMETRY,
|
||||||
|
DeviceObject,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
&DiskGeometry,
|
||||||
|
sizeof(DISK_GEOMETRY),
|
||||||
|
FALSE,
|
||||||
|
&Event,
|
||||||
|
&StatusBlock);
|
||||||
|
if (!Irp)
|
||||||
|
{
|
||||||
|
/* Try again */
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call the driver and check if we have to wait on it */
|
||||||
|
Status = IoCallDriver(DeviceObject, Irp);
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
/* Wait on the driver */
|
||||||
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
Status = StatusBlock.Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we failed */
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Try again */
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the partition table */
|
||||||
|
Status = IoReadPartitionTable(DeviceObject,
|
||||||
|
DiskGeometry.BytesPerSector,
|
||||||
|
TRUE,
|
||||||
|
&DriveLayout);
|
||||||
|
|
||||||
|
/* Dereference the file object */
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
if (!NT_SUCCESS(Status)) continue;
|
||||||
|
|
||||||
|
/* Set the offset to 0 */
|
||||||
|
PartitionOffset.QuadPart = 0;
|
||||||
|
|
||||||
|
/* Allocate a buffer for the partition */
|
||||||
|
PartitionBuffer = ExAllocatePoolWithTag(NonPagedPool,
|
||||||
|
DiskGeometry.BytesPerSector,
|
||||||
|
TAG_IO);
|
||||||
|
if (!PartitionBuffer) continue;
|
||||||
|
|
||||||
|
/* Build an IRP to read the partition sector */
|
||||||
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
|
||||||
|
DeviceObject,
|
||||||
|
PartitionBuffer,
|
||||||
|
DiskGeometry.BytesPerSector,
|
||||||
|
&PartitionOffset,
|
||||||
|
&Event,
|
||||||
|
&StatusBlock);
|
||||||
|
|
||||||
|
/* Call the driver and check if we have to wait */
|
||||||
|
Status = IoCallDriver(DeviceObject, Irp);
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
/* Wait for completion */
|
||||||
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
Status = StatusBlock.Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we failed */
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Try again */
|
||||||
|
ExFreePool(PartitionBuffer);
|
||||||
|
ExFreePool(DriveLayout);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the MBR checksum */
|
||||||
|
DiskEntry->Checksum = 0;
|
||||||
|
for (j = 0; j < 128; j++)
|
||||||
|
{
|
||||||
|
DiskEntry->Checksum += ((PULONG)PartitionBuffer)[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save the signature and checksum */
|
||||||
|
DiskEntry->Checksum = ~DiskEntry->Checksum + 1;
|
||||||
|
DiskEntry->Signature = DriveLayout->Signature;
|
||||||
|
DiskEntry->PartitionCount = DriveLayout->PartitionCount;
|
||||||
|
|
||||||
|
/* Insert it into the list */
|
||||||
|
InsertTailList(ListHead, &DiskEntry->ListEntry);
|
||||||
|
|
||||||
|
/* Free the buffer */
|
||||||
|
ExFreePool(PartitionBuffer);
|
||||||
|
ExFreePool(DriveLayout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
INIT_FUNCTION
|
||||||
|
NTAPI
|
||||||
|
IopAssignArcNamesToDisk(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN ULONG RDisk,
|
||||||
|
IN ULONG DiskNumber,
|
||||||
|
IN ULONG PartitionCount,
|
||||||
|
IN PBOOLEAN FoundHdBoot)
|
||||||
|
{
|
||||||
|
CHAR Buffer[256];
|
||||||
|
CHAR ArcBuffer[256];
|
||||||
|
ANSI_STRING TempString, ArcNameString, BootString;
|
||||||
|
ANSI_STRING ArcBootString, ArcSystemString;
|
||||||
|
UNICODE_STRING DeviceName, ArcName, BootPath;
|
||||||
|
ULONG i;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* HACK: Build the ARC name that FreeLDR should've given us */
|
||||||
|
CHAR BootArcName[256]; // should come from FREELDR
|
||||||
|
sprintf(BootArcName, "multi(0)disk(0)rdisk(%lu)", RDisk);
|
||||||
|
|
||||||
|
/* Set default */
|
||||||
|
*FoundHdBoot = FALSE;
|
||||||
|
|
||||||
|
/* Build the boot strings */
|
||||||
|
RtlInitAnsiString(&ArcBootString, KeLoaderBlock->ArcBootDeviceName);
|
||||||
|
RtlInitAnsiString(&ArcSystemString, KeLoaderBlock->ArcHalDeviceName);
|
||||||
|
|
||||||
|
/* Build the NT Device Name */
|
||||||
|
sprintf(Buffer, "\\Device\\Harddisk%lu\\Partition0", DiskNumber);
|
||||||
|
|
||||||
|
/* Convert it to unicode */
|
||||||
|
RtlInitAnsiString(&TempString, Buffer);
|
||||||
|
Status = RtlAnsiStringToUnicodeString(&DeviceName, &TempString, TRUE);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
/* Build the ARC Device Name */
|
||||||
|
sprintf(ArcBuffer, "\\ArcName\\%s", BootArcName);
|
||||||
|
|
||||||
|
/* Convert it to Unicode */
|
||||||
|
RtlInitAnsiString(&ArcNameString, ArcBuffer);
|
||||||
|
Status = RtlAnsiStringToUnicodeString(&ArcName, &ArcNameString, TRUE);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
/* Create the symbolic link and free the strings */
|
||||||
|
IoAssignArcName(&ArcName, &DeviceName);
|
||||||
|
RtlFreeUnicodeString(&ArcName);
|
||||||
|
RtlFreeUnicodeString(&DeviceName);
|
||||||
|
|
||||||
|
/* Loop all the partitions */
|
||||||
|
for (i = 0; i < PartitionCount; i++)
|
||||||
|
{
|
||||||
|
/* Build the partition device name */
|
||||||
|
sprintf(Buffer, "\\Device\\Harddisk%lu\\Partition%lu", DiskNumber, i+1);
|
||||||
|
|
||||||
|
/* Convert it to Unicode */
|
||||||
|
RtlInitAnsiString(&TempString, Buffer);
|
||||||
|
Status = RtlAnsiStringToUnicodeString(&DeviceName, &TempString, TRUE);
|
||||||
|
if (!NT_SUCCESS(Status)) continue;
|
||||||
|
|
||||||
|
/* Build the partial ARC name for this partition */
|
||||||
|
sprintf(ArcBuffer, "%spartition(%lu)", BootArcName, i + 1);
|
||||||
|
RtlInitAnsiString(&ArcNameString, ArcBuffer);
|
||||||
|
|
||||||
|
/* Check if this is the boot device */
|
||||||
|
if (RtlEqualString(&ArcNameString, &ArcBootString, TRUE))
|
||||||
|
{
|
||||||
|
/* Remember that we found a Hard Disk Boot Device */
|
||||||
|
*FoundHdBoot = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if it's the system boot partition */
|
||||||
|
if (RtlEqualString(&ArcNameString, &ArcSystemString, TRUE))
|
||||||
|
{
|
||||||
|
/* It is, create a Unicode string for it */
|
||||||
|
RtlInitAnsiString(&BootString, KeLoaderBlock->NtHalPathName);
|
||||||
|
Status = RtlAnsiStringToUnicodeString(&BootPath, &BootString, TRUE);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* FIXME: Save in registry */
|
||||||
|
|
||||||
|
/* Free the string now */
|
||||||
|
RtlFreeUnicodeString(&BootPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build the full ARC name */
|
||||||
|
sprintf(Buffer, "\\ArcName\\%spartition(%lu)", BootArcName, i + 1);
|
||||||
|
|
||||||
|
/* Convert it to Unicode */
|
||||||
|
RtlInitAnsiString(&ArcNameString, Buffer);
|
||||||
|
Status = RtlAnsiStringToUnicodeString(&ArcName, &ArcNameString, TRUE);
|
||||||
|
if (!NT_SUCCESS(Status)) continue;
|
||||||
|
|
||||||
|
/* Create the symbolic link and free the strings */
|
||||||
|
IoAssignArcName(&ArcName, &DeviceName);
|
||||||
|
RtlFreeUnicodeString(&ArcName);
|
||||||
|
RtlFreeUnicodeString(&DeviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
INIT_FUNCTION
|
||||||
|
NTAPI
|
||||||
|
IopAssignArcNamesToCdrom(IN PULONG Buffer,
|
||||||
|
IN ULONG DiskNumber)
|
||||||
|
{
|
||||||
|
CHAR ArcBuffer[256];
|
||||||
|
ANSI_STRING TempString, ArcNameString;
|
||||||
|
UNICODE_STRING DeviceName, ArcName;
|
||||||
|
NTSTATUS Status;
|
||||||
|
LARGE_INTEGER PartitionOffset;
|
||||||
|
KEVENT Event;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
PIRP Irp;
|
||||||
|
ULONG i, CheckSum = 0;
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
PFILE_OBJECT FileObject;
|
||||||
|
|
||||||
|
/* Build the device name */
|
||||||
|
sprintf(ArcBuffer, "\\Device\\CdRom%lu", DiskNumber);
|
||||||
|
|
||||||
|
/* Convert it to Unicode */
|
||||||
|
RtlInitAnsiString(&TempString, ArcBuffer);
|
||||||
|
Status = RtlAnsiStringToUnicodeString(&DeviceName, &TempString, TRUE);
|
||||||
|
if (!NT_SUCCESS(Status)) return FALSE;
|
||||||
|
|
||||||
|
/* Get the device for it */
|
||||||
|
Status = IoGetDeviceObjectPointer(&DeviceName,
|
||||||
|
FILE_READ_ATTRIBUTES,
|
||||||
|
&FileObject,
|
||||||
|
&DeviceObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Free the string and fail */
|
||||||
|
RtlFreeUnicodeString(&DeviceName);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup the event */
|
||||||
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
|
/* Set the offset and build the read IRP */
|
||||||
|
PartitionOffset.QuadPart = 0x8000;
|
||||||
|
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
|
||||||
|
DeviceObject,
|
||||||
|
Buffer,
|
||||||
|
2048,
|
||||||
|
&PartitionOffset,
|
||||||
|
&Event,
|
||||||
|
&IoStatusBlock);
|
||||||
|
if (!Irp)
|
||||||
|
{
|
||||||
|
/* Free the string and fail */
|
||||||
|
RtlFreeUnicodeString(&DeviceName);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call the driver and check if we have to wait on it */
|
||||||
|
Status = IoCallDriver(DeviceObject, Irp);
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
/* Wait for completion */
|
||||||
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
Status = IoStatusBlock.Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dereference the file object */
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
if (!NT_SUCCESS(Status)) return FALSE;
|
||||||
|
|
||||||
|
/* Now calculate the checksum */
|
||||||
|
for (i = 0; i < 2048 / sizeof(ULONG); i++) CheckSum += Buffer[i];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: In normal conditions, NTLDR/FreeLdr sends the *proper* CDROM
|
||||||
|
* ARC Path name, and what happens here is a comparision of both checksums
|
||||||
|
* in order to see if this is the actual boot CD.
|
||||||
|
*
|
||||||
|
* In ReactOS this doesn't currently happen, instead we have a hack on top
|
||||||
|
* of this file which scans the CD for the ntoskrnl.exe file, then modifies
|
||||||
|
* the LoaderBlock's ARC Path with the right CDROM path. Consequently, we
|
||||||
|
* get the same state as if NTLDR had properly booted us, except that we do
|
||||||
|
* not actually need to check the signature, since the hack already did the
|
||||||
|
* check for ntoskrnl.exe, which is just as good.
|
||||||
|
*
|
||||||
|
* 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))
|
||||||
|
{
|
||||||
|
/* 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);
|
||||||
|
if (!NT_SUCCESS(Status)) return FALSE;
|
||||||
|
|
||||||
|
/* Create the symbolic link and free the strings */
|
||||||
|
IoAssignArcName(&ArcName, &DeviceName);
|
||||||
|
RtlFreeUnicodeString(&ArcName);
|
||||||
|
RtlFreeUnicodeString(&DeviceName);
|
||||||
|
|
||||||
|
/* Let caller know that we've found the boot CD */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No boot CD found */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS INIT_FUNCTION
|
||||||
|
IoCreateArcNames(VOID)
|
||||||
|
{
|
||||||
|
PCONFIGURATION_INFORMATION ConfigInfo;
|
||||||
|
ULONG i, RDiskNumber;
|
||||||
|
NTSTATUS Status;
|
||||||
|
LIST_ENTRY BiosDiskListHead;
|
||||||
|
LIST_ENTRY DiskListHead;
|
||||||
|
PLIST_ENTRY Entry;
|
||||||
|
PDISKENTRY BiosDiskEntry;
|
||||||
|
PDISKENTRY DiskEntry;
|
||||||
|
BOOLEAN FoundBoot;
|
||||||
|
PULONG Buffer;
|
||||||
|
|
||||||
|
ConfigInfo = IoGetConfigurationInformation();
|
||||||
|
|
||||||
|
/* create ARC names for hard disk drives */
|
||||||
|
InitializeListHead(&BiosDiskListHead);
|
||||||
|
InitializeListHead(&DiskListHead);
|
||||||
|
IopEnumerateBiosDisks(&BiosDiskListHead);
|
||||||
|
IopEnumerateDisks(&DiskListHead);
|
||||||
|
|
||||||
|
RDiskNumber = 0;
|
||||||
|
while (!IsListEmpty(&BiosDiskListHead))
|
||||||
|
{
|
||||||
|
Entry = RemoveHeadList(&BiosDiskListHead);
|
||||||
|
BiosDiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
|
||||||
|
Entry = DiskListHead.Flink;
|
||||||
|
while (Entry != &DiskListHead)
|
||||||
|
{
|
||||||
|
DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
|
||||||
|
if (DiskEntry->Checksum == BiosDiskEntry->Checksum &&
|
||||||
|
DiskEntry->Signature == BiosDiskEntry->Signature)
|
||||||
|
{
|
||||||
|
|
||||||
|
Status = IopAssignArcNamesToDisk(DiskEntry->DeviceObject,
|
||||||
|
RDiskNumber,
|
||||||
|
DiskEntry->DiskNumber,
|
||||||
|
DiskEntry->PartitionCount,
|
||||||
|
&FoundBoot);
|
||||||
|
|
||||||
|
RemoveEntryList(&DiskEntry->ListEntry);
|
||||||
|
ExFreePool(DiskEntry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Entry = Entry->Flink;
|
||||||
|
}
|
||||||
|
RDiskNumber++;
|
||||||
|
ExFreePool(BiosDiskEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!IsListEmpty(&DiskListHead))
|
||||||
|
{
|
||||||
|
Entry = RemoveHeadList(&DiskListHead);
|
||||||
|
DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
|
||||||
|
ExFreePool(DiskEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we didn't find the boot disk */
|
||||||
|
if (!FoundBoot)
|
||||||
|
{
|
||||||
|
/* Allocate a buffer for the CD-ROM MBR */
|
||||||
|
Buffer = ExAllocatePoolWithTag(NonPagedPool, 2048, TAG_IO);
|
||||||
|
if (!Buffer) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
/* Loop every CD-ROM */
|
||||||
|
for (i = 0; i < ConfigInfo->CdRomCount; i++)
|
||||||
|
{
|
||||||
|
/* Give it an ARC name */
|
||||||
|
if (IopAssignArcNamesToCdrom(Buffer, i)) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the buffer */
|
||||||
|
ExFreePool(Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -617,9 +667,6 @@ IopReassignSystemRoot(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||||
UNICODE_STRING LinkName, TargetName, ArcName;
|
UNICODE_STRING LinkName, TargetName, ArcName;
|
||||||
HANDLE LinkHandle;
|
HANDLE LinkHandle;
|
||||||
|
|
||||||
/* Check if this is a CD-ROM boot */
|
|
||||||
IopApplyRosCdromArcHack(LoaderBlock);
|
|
||||||
|
|
||||||
/* Create the Unicode name for the current ARC boot device */
|
/* Create the Unicode name for the current ARC boot device */
|
||||||
sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName);
|
sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName);
|
||||||
RtlInitAnsiString(&TargetString, Buffer);
|
RtlInitAnsiString(&TargetString, Buffer);
|
||||||
|
|
Loading…
Reference in a new issue