mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +00:00
- Do only allow to install reactos on disks which are visible by the bios.
- Arrange the disks in the same sequence how they was detected by the bios. - Create a registry entry in MountedDevices for each recognized partition. svn path=/trunk/; revision=17864
This commit is contained in:
parent
a9ef5d9d40
commit
9f214815b7
4 changed files with 401 additions and 4 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 2002, 2003 ReactOS Team
|
||||
* Copyright (C) 2002, 2003, 2004, 2005 ReactOS Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -23,6 +23,7 @@
|
|||
* PURPOSE: Partition list functions
|
||||
* PROGRAMMER: Eric Kohl
|
||||
* Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* Hartmut Birr
|
||||
*/
|
||||
|
||||
#include <usetup.h>
|
||||
|
@ -421,6 +422,128 @@ ScanForUnpartitionedDiskSpace (PDISKENTRY DiskEntry)
|
|||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
DiskQueryRoutine(PWSTR ValueName,
|
||||
ULONG ValueType,
|
||||
PVOID ValueData,
|
||||
ULONG ValueLength,
|
||||
PVOID Context,
|
||||
PVOID EntryContext)
|
||||
{
|
||||
PLIST_ENTRY ListHead = (PLIST_ENTRY)Context;
|
||||
PULONG GlobalDiskCount = (PULONG)EntryContext;
|
||||
PBIOSDISKENTRY BiosDiskEntry;
|
||||
UNICODE_STRING NameU;
|
||||
|
||||
if (ValueType == REG_SZ &&
|
||||
ValueLength == 20 * sizeof(WCHAR))
|
||||
{
|
||||
BiosDiskEntry = RtlAllocateHeap(ProcessHeap, 0, sizeof(BIOSDISKENTRY));
|
||||
if (BiosDiskEntry == NULL)
|
||||
{
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
BiosDiskEntry->DiskNumber = (*GlobalDiskCount)++;
|
||||
|
||||
NameU.Buffer = (PWCHAR)ValueData;
|
||||
NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR);
|
||||
RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum);
|
||||
|
||||
NameU.Buffer = (PWCHAR)ValueData + 9;
|
||||
RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature);
|
||||
|
||||
InsertTailList(ListHead, &BiosDiskEntry->ListEntry);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define ROOT_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
|
||||
|
||||
STATIC VOID
|
||||
EnumerateBiosDiskEntries(PPARTLIST PartList)
|
||||
{
|
||||
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
|
||||
WCHAR Name[100];
|
||||
ULONG AdapterCount;
|
||||
ULONG ControllerCount;
|
||||
ULONG DiskCount;
|
||||
NTSTATUS Status;
|
||||
ULONG GlobalDiskCount=0;
|
||||
|
||||
|
||||
memset(QueryTable, 0, sizeof(QueryTable));
|
||||
QueryTable[0].Name = L"Identifier";
|
||||
QueryTable[0].QueryRoutine = DiskQueryRoutine;
|
||||
QueryTable[0].EntryContext = (PVOID)&GlobalDiskCount;
|
||||
|
||||
AdapterCount = 0;
|
||||
while (1)
|
||||
{
|
||||
swprintf(Name, L"%s\\%lu", ROOT_NAME, AdapterCount);
|
||||
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
|
||||
Name,
|
||||
&QueryTable[1],
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
swprintf(Name, L"%s\\%lu\\DiskController", ROOT_NAME, AdapterCount);
|
||||
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
|
||||
Name,
|
||||
&QueryTable[1],
|
||||
NULL,
|
||||
NULL);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
ControllerCount = 0;
|
||||
while (1)
|
||||
{
|
||||
swprintf(Name, L"%s\\%lu\\DiskController\\%lu", ROOT_NAME, AdapterCount, ControllerCount);
|
||||
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
|
||||
Name,
|
||||
&QueryTable[1],
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
swprintf(Name, L"%s\\%lu\\DiskController\\%lu\\DiskPeripheral", ROOT_NAME, AdapterCount, ControllerCount);
|
||||
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
|
||||
Name,
|
||||
&QueryTable[1],
|
||||
NULL,
|
||||
NULL);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
DiskCount = 0;
|
||||
while (1)
|
||||
{
|
||||
swprintf(Name, L"%s\\%lu\\DiskController\\%lu\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount, ControllerCount, DiskCount);
|
||||
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
|
||||
Name,
|
||||
QueryTable,
|
||||
(PVOID)&PartList->BiosDiskListHead,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
break;
|
||||
}
|
||||
DiskCount++;
|
||||
}
|
||||
}
|
||||
ControllerCount++;
|
||||
}
|
||||
}
|
||||
AdapterCount++;
|
||||
}
|
||||
}
|
||||
|
||||
static VOID
|
||||
AddDiskToList (HANDLE FileHandle,
|
||||
|
@ -433,6 +556,15 @@ AddDiskToList (HANDLE FileHandle,
|
|||
PDISKENTRY DiskEntry;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
NTSTATUS Status;
|
||||
PPARTITION_SECTOR Mbr;
|
||||
PULONG Buffer;
|
||||
LARGE_INTEGER FileOffset;
|
||||
WCHAR Identifier[20];
|
||||
ULONG Checksum;
|
||||
ULONG Signature;
|
||||
ULONG i;
|
||||
PLIST_ENTRY ListEntry;
|
||||
PBIOSDISKENTRY BiosDiskEntry;
|
||||
|
||||
Status = NtDeviceIoControlFile (FileHandle,
|
||||
NULL,
|
||||
|
@ -469,6 +601,51 @@ AddDiskToList (HANDLE FileHandle,
|
|||
return;
|
||||
}
|
||||
|
||||
Mbr = RtlAllocateHeap(ProcessHeap,
|
||||
0,
|
||||
DiskGeometry.BytesPerSector);
|
||||
|
||||
if (Mbr == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FileOffset.QuadPart = 0;
|
||||
Status = NtReadFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&Iosb,
|
||||
(PVOID)Mbr,
|
||||
DiskGeometry.BytesPerSector,
|
||||
&FileOffset,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
RtlFreeHeap(ProcessHeap,
|
||||
0,
|
||||
Mbr);
|
||||
DPRINT1("NtReadFile failed, status=%x\n", Status);
|
||||
return;
|
||||
}
|
||||
Signature = Mbr->Signature;
|
||||
|
||||
/* Calculate the MBR checksum */
|
||||
Checksum = 0;
|
||||
Buffer = (PULONG)Mbr;
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
Checksum += Buffer[i];
|
||||
}
|
||||
Checksum = ~Checksum + 1;
|
||||
|
||||
RtlFreeHeap (ProcessHeap,
|
||||
0,
|
||||
Mbr);
|
||||
|
||||
swprintf(Identifier, L"%08x-%08x-A", Checksum, Signature);
|
||||
DPRINT("Identifier: %S\n", Identifier);
|
||||
|
||||
DiskEntry = (PDISKENTRY)RtlAllocateHeap (ProcessHeap,
|
||||
0,
|
||||
sizeof(DISKENTRY));
|
||||
|
@ -477,6 +654,35 @@ AddDiskToList (HANDLE FileHandle,
|
|||
return;
|
||||
}
|
||||
|
||||
DiskEntry->Checksum = Checksum;
|
||||
DiskEntry->Signature = Signature;
|
||||
DiskEntry->BiosFound = FALSE;
|
||||
|
||||
ListEntry = List->BiosDiskListHead.Flink;
|
||||
while(ListEntry != &List->BiosDiskListHead)
|
||||
{
|
||||
BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
|
||||
if (BiosDiskEntry->Signature == Signature &&
|
||||
BiosDiskEntry->Checksum == Checksum)
|
||||
{
|
||||
if (!DiskEntry->BiosFound)
|
||||
{
|
||||
DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber;
|
||||
DiskEntry->BiosFound = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
ListEntry = ListEntry->Flink;
|
||||
}
|
||||
|
||||
if (!DiskEntry->BiosFound)
|
||||
{
|
||||
RtlFreeHeap(ProcessHeap, 0, DiskEntry);
|
||||
return;
|
||||
}
|
||||
|
||||
InitializeListHead (&DiskEntry->PartListHead);
|
||||
|
||||
DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
|
||||
|
@ -509,8 +715,7 @@ AddDiskToList (HANDLE FileHandle,
|
|||
|
||||
GetDriverName (DiskEntry);
|
||||
|
||||
InsertTailList (&List->DiskListHead,
|
||||
&DiskEntry->ListEntry);
|
||||
InsertAscendingList(&List->DiskListHead, DISKENTRY, ListEntry, DiskEntry, BiosDiskNumber);
|
||||
|
||||
LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap (ProcessHeap,
|
||||
0,
|
||||
|
@ -587,6 +792,9 @@ CreatePartitionList (SHORT Left,
|
|||
List->CurrentPartition = NULL;
|
||||
|
||||
InitializeListHead (&List->DiskListHead);
|
||||
InitializeListHead (&List->BiosDiskListHead);
|
||||
|
||||
EnumerateBiosDiskEntries(List);
|
||||
|
||||
Status = NtQuerySystemInformation (SystemDeviceInformation,
|
||||
&Sdi,
|
||||
|
@ -667,6 +875,7 @@ VOID
|
|||
DestroyPartitionList (PPARTLIST List)
|
||||
{
|
||||
PDISKENTRY DiskEntry;
|
||||
PBIOSDISKENTRY BiosDiskEntry;
|
||||
PPARTENTRY PartEntry;
|
||||
PLIST_ENTRY Entry;
|
||||
|
||||
|
@ -694,6 +903,15 @@ DestroyPartitionList (PPARTLIST List)
|
|||
RtlFreeHeap (ProcessHeap, 0, DiskEntry);
|
||||
}
|
||||
|
||||
/* release the bios disk info */
|
||||
while(!IsListEmpty(&List->BiosDiskListHead))
|
||||
{
|
||||
Entry = RemoveHeadList(&List->BiosDiskListHead);
|
||||
BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
|
||||
|
||||
RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
|
||||
}
|
||||
|
||||
/* Release list head */
|
||||
RtlFreeHeap (ProcessHeap, 0, List);
|
||||
}
|
||||
|
@ -2000,7 +2218,29 @@ WritePartitionsToDisk (PPARTLIST List)
|
|||
DriveLayoutSize);
|
||||
|
||||
DriveLayout->PartitionCount = PartitionCount;
|
||||
if (DiskEntry->Signature == 0)
|
||||
{
|
||||
LARGE_INTEGER SystemTime;
|
||||
TIME_FIELDS TimeFields;
|
||||
PUCHAR Buffer;
|
||||
|
||||
NtQuerySystemTime (&SystemTime);
|
||||
RtlTimeToTimeFields (&SystemTime, &TimeFields);
|
||||
|
||||
Buffer = (PUCHAR)&DiskEntry->Signature;
|
||||
Buffer[0] = (UCHAR)(TimeFields.Year & 0xFF) + (UCHAR)(TimeFields.Hour & 0xFF);
|
||||
Buffer[1] = (UCHAR)(TimeFields.Year >> 8) + (UCHAR)(TimeFields.Minute & 0xFF);
|
||||
Buffer[2] = (UCHAR)(TimeFields.Month & 0xFF) + (UCHAR)(TimeFields.Second & 0xFF);
|
||||
Buffer[3] = (UCHAR)(TimeFields.Day & 0xFF) + (UCHAR)(TimeFields.Milliseconds & 0xFF);
|
||||
|
||||
/* FIXME:
|
||||
* check for an existing signature
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
DriveLayout->Signature = DiskEntry->Signature;
|
||||
|
||||
Index = 0;
|
||||
Entry2 = DiskEntry->PartListHead.Flink;
|
||||
while (Entry2 != &DiskEntry->PartListHead)
|
||||
|
@ -2095,4 +2335,42 @@ WritePartitionsToDisk (PPARTLIST List)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL SetMountedDeviceValues(PPARTLIST List)
|
||||
{
|
||||
PLIST_ENTRY Entry1, Entry2;
|
||||
PDISKENTRY DiskEntry;
|
||||
PPARTENTRY PartEntry;
|
||||
|
||||
if (List == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Entry1 = List->DiskListHead.Flink;
|
||||
while (Entry1 != &List->DiskListHead)
|
||||
{
|
||||
DiskEntry = CONTAINING_RECORD (Entry1,
|
||||
DISKENTRY,
|
||||
ListEntry);
|
||||
|
||||
Entry2 = DiskEntry->PartListHead.Flink;
|
||||
while (Entry2 != &DiskEntry->PartListHead)
|
||||
{
|
||||
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
|
||||
if (!PartEntry->Unpartitioned && PartEntry->DriveLetter)
|
||||
{
|
||||
if (!SetMountedDeviceValue(PartEntry->DriveLetter, DiskEntry->Signature, PartEntry->PartInfo[0].StartingOffset))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
Entry2 = Entry2->Flink;
|
||||
}
|
||||
Entry1 = Entry1->Flink;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -68,6 +68,15 @@ typedef struct _PARTENTRY
|
|||
} PARTENTRY, *PPARTENTRY;
|
||||
|
||||
|
||||
typedef struct _BIOSDISKENTRY
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
ULONG DiskNumber;
|
||||
ULONG Signature;
|
||||
ULONG Checksum;
|
||||
} BIOSDISKENTRY, *PBIOSDISKENTRY;
|
||||
|
||||
|
||||
typedef struct _DISKENTRY
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
|
@ -81,6 +90,11 @@ typedef struct _DISKENTRY
|
|||
ULONGLONG CylinderSize;
|
||||
ULONGLONG TrackSize;
|
||||
|
||||
BOOLEAN BiosFound;
|
||||
ULONG BiosDiskNumber;
|
||||
ULONG Signature;
|
||||
ULONG Checksum;
|
||||
|
||||
ULONG DiskNumber;
|
||||
USHORT Port;
|
||||
USHORT Bus;
|
||||
|
@ -118,10 +132,46 @@ typedef struct _PARTLIST
|
|||
PPARTENTRY ActiveBootPartition;
|
||||
|
||||
LIST_ENTRY DiskListHead;
|
||||
LIST_ENTRY BiosDiskListHead;
|
||||
|
||||
} PARTLIST, *PPARTLIST;
|
||||
|
||||
#define PARTITION_TBL_SIZE 4
|
||||
|
||||
#include <pshpack1.h>
|
||||
|
||||
typedef struct _PARTITION
|
||||
{
|
||||
unsigned char BootFlags; /* bootable? 0=no, 128=yes */
|
||||
unsigned char StartingHead; /* beginning head number */
|
||||
unsigned char StartingSector; /* beginning sector number */
|
||||
unsigned char StartingCylinder; /* 10 bit nmbr, with high 2 bits put in begsect */
|
||||
unsigned char PartitionType; /* Operating System type indicator code */
|
||||
unsigned char EndingHead; /* ending head number */
|
||||
unsigned char EndingSector; /* ending sector number */
|
||||
unsigned char EndingCylinder; /* also a 10 bit nmbr, with same high 2 bit trick */
|
||||
unsigned int StartingBlock; /* first sector relative to start of disk */
|
||||
unsigned int SectorCount; /* number of sectors in partition */
|
||||
} PARTITION, *PPARTITION;
|
||||
|
||||
typedef struct _PARTITION_SECTOR
|
||||
{
|
||||
UCHAR BootCode[440]; /* 0x000 */
|
||||
ULONG Signature; /* 0x1B8 */
|
||||
UCHAR Reserved[2]; /* 0x1BC */
|
||||
PARTITION Partition[PARTITION_TBL_SIZE]; /* 0x1BE */
|
||||
USHORT Magic; /* 0x1FE */
|
||||
} PARTITION_SECTOR, *PPARTITION_SECTOR;
|
||||
|
||||
#include <poppack.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
ULONG DiskNumber;
|
||||
ULONG Idendifier;
|
||||
ULONG Signature;
|
||||
} BIOS_DISK, *PBIOS_DISK;
|
||||
|
||||
PPARTLIST
|
||||
CreatePartitionList (SHORT Left,
|
||||
|
|
|
@ -45,6 +45,15 @@
|
|||
#define FLG_ADDREG_TYPE_NONE (0x00020000 | FLG_ADDREG_BINVALUETYPE)
|
||||
#define FLG_ADDREG_TYPE_MASK (0xFFFF0000 | FLG_ADDREG_BINVALUETYPE)
|
||||
|
||||
#include <pshpack1.h>
|
||||
|
||||
typedef struct _REG_DISK_MOUNT_INFO
|
||||
{
|
||||
ULONG Signature;
|
||||
LARGE_INTEGER StartingOffset;
|
||||
} REG_DISK_MOUNT_INFO, *PREG_DISK_MOUNT_INFO;
|
||||
|
||||
#include <poppack.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
|
@ -640,4 +649,61 @@ SetInstallPathValue(PUNICODE_STRING InstallPath)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
SetMountedDeviceValue(CHAR Letter, ULONG Signature, LARGE_INTEGER StartingOffset)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
WCHAR ValueNameBuffer[16];
|
||||
UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\MountedDevices");
|
||||
UNICODE_STRING ValueName;
|
||||
REG_DISK_MOUNT_INFO MountInfo;
|
||||
NTSTATUS Status;
|
||||
HANDLE KeyHandle;
|
||||
|
||||
swprintf(ValueNameBuffer, L"\\DosDevices\\%C:", Letter);
|
||||
RtlInitUnicodeString(&ValueName, ValueNameBuffer);
|
||||
|
||||
InitializeObjectAttributes (&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = NtOpenKey (&KeyHandle,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Status = NtCreateKey(&KeyHandle,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MountInfo.Signature = Signature;
|
||||
MountInfo.StartingOffset = StartingOffset;
|
||||
Status = NtSetValueKey (KeyHandle,
|
||||
&ValueName,
|
||||
0,
|
||||
REG_BINARY,
|
||||
(PVOID)&MountInfo,
|
||||
sizeof(MountInfo));
|
||||
NtClose(KeyHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -2545,7 +2545,7 @@ InstallDirectoryPage1(PWCHAR InstallDir, PDISKENTRY DiskEntry, PPARTENTRY PartEn
|
|||
RtlFreeUnicodeString(&DestinationArcPath);
|
||||
swprintf(PathBuffer,
|
||||
L"multi(0)disk(0)rdisk(%lu)partition(%lu)",
|
||||
DiskEntry->DiskNumber,
|
||||
DiskEntry->BiosDiskNumber,
|
||||
PartEntry->PartInfo[0].PartitionNumber);
|
||||
if (InstallDir[0] != L'\\')
|
||||
wcscat(PathBuffer,
|
||||
|
@ -3241,6 +3241,9 @@ RegistryPage(PINPUT_RECORD Ir)
|
|||
}
|
||||
}
|
||||
|
||||
/* Update the mounted devices list */
|
||||
SetMountedDeviceValues(PartitionList);
|
||||
|
||||
SetStatusText(" Done...");
|
||||
|
||||
return BOOT_LOADER_PAGE;
|
||||
|
|
Loading…
Reference in a new issue