- 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.
Modified: trunk/reactos/subsys/system/usetup/partlist.c
Modified: trunk/reactos/subsys/system/usetup/partlist.h
Modified: trunk/reactos/subsys/system/usetup/registry.c
Modified: trunk/reactos/subsys/system/usetup/usetup.c
_____
Modified: trunk/reactos/subsys/system/usetup/partlist.c
--- trunk/reactos/subsys/system/usetup/partlist.c 2005-09-15
16:52:23 UTC (rev 17863)
+++ trunk/reactos/subsys/system/usetup/partlist.c 2005-09-15
17:19:31 UTC (rev 17864)
@@ -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(a)users.sourceforge.net)
+ * Hartmut Birr
*/
#include <usetup.h>
@@ -421,7 +422,129 @@
}
}
+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\\MultifunctionAdapt
er"
+
+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,
ULONG DiskNumber,
@@ -433,6 +556,15 @@
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 @@
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 @@
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 @@
GetDriverName (DiskEntry);
- InsertTailList (&List->DiskListHead,
- &DiskEntry->ListEntry);
+ InsertAscendingList(&List->DiskListHead, DISKENTRY, ListEntry,
DiskEntry, BiosDiskNumber);
LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap
(ProcessHeap,
0,
@@ -587,7 +792,10 @@
List->CurrentPartition = NULL;
InitializeListHead (&List->DiskListHead);
+ InitializeListHead (&List->BiosDiskListHead);
+ EnumerateBiosDiskEntries(List);
+
Status = NtQuerySystemInformation (SystemDeviceInformation,
&Sdi,
sizeof(SYSTEM_DEVICE_INFORMATION),
@@ -667,6 +875,7 @@
DestroyPartitionList (PPARTLIST List)
{
PDISKENTRY DiskEntry;
+ PBIOSDISKENTRY BiosDiskEntry;
PPARTENTRY PartEntry;
PLIST_ENTRY Entry;
@@ -694,6 +903,15 @@
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 @@
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 @@
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 */
_____
Modified: trunk/reactos/subsys/system/usetup/partlist.h
--- trunk/reactos/subsys/system/usetup/partlist.h 2005-09-15
16:52:23 UTC (rev 17863)
+++ trunk/reactos/subsys/system/usetup/partlist.h 2005-09-15
17:19:31 UTC (rev 17864)
@@ -68,6 +68,15 @@
} 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 @@
ULONGLONG CylinderSize;
ULONGLONG TrackSize;
+ BOOLEAN BiosFound;
+ ULONG BiosDiskNumber;
+ ULONG Signature;
+ ULONG Checksum;
+
ULONG DiskNumber;
USHORT Port;
USHORT Bus;
@@ -118,11 +132,47 @@
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,
SHORT Top,
_____
Modified: trunk/reactos/subsys/system/usetup/registry.c
--- trunk/reactos/subsys/system/usetup/registry.c 2005-09-15
16:52:23 UTC (rev 17863)
+++ trunk/reactos/subsys/system/usetup/registry.c 2005-09-15
17:19:31 UTC (rev 17864)
@@ -45,7 +45,16 @@
#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
****************************************************************/
static BOOLEAN
@@ -640,4 +649,61 @@
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 */
_____
Modified: trunk/reactos/subsys/system/usetup/usetup.c
--- trunk/reactos/subsys/system/usetup/usetup.c 2005-09-15 16:52:23 UTC
(rev 17863)
+++ trunk/reactos/subsys/system/usetup/usetup.c 2005-09-15 17:19:31 UTC
(rev 17864)
@@ -2545,7 +2545,7 @@
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 @@
}
}
+ /* Update the mounted devices list */
+ SetMountedDeviceValues(PartitionList);
+
SetStatusText(" Done...");
return BOOT_LOADER_PAGE;