From 047952c5a154c6b335106b6047d09ef470ae4139 Mon Sep 17 00:00:00 2001 From: Hartmut Birr Date: Mon, 19 Sep 2005 20:01:29 +0000 Subject: [PATCH] - Read more information from the registry about the disks detected by the bios. - Fixed the detection of disks with a signature of zero (in AddDiskToList). - Update always the partition table if the modified flag is set. - Create an unique disk signature. - Declared some registry query structures in cmtype.h. svn path=/trunk/; revision=17935 --- reactos/include/ndk/cmtypes.h | 256 ++++++++++++++ reactos/subsys/system/usetup/partlist.c | 451 ++++++++++++++++-------- reactos/subsys/system/usetup/partlist.h | 3 + 3 files changed, 570 insertions(+), 140 deletions(-) diff --git a/reactos/include/ndk/cmtypes.h b/reactos/include/ndk/cmtypes.h index 4a2e020f2be..2de45c9bea4 100644 --- a/reactos/include/ndk/cmtypes.h +++ b/reactos/include/ndk/cmtypes.h @@ -174,6 +174,116 @@ typedef struct _KEY_BASIC_INFORMATION WCHAR Name[1]; } KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION; +#else + +typedef struct _REG_DELETE_KEY_INFORMATION +{ + PVOID Object; +} REG_DELETE_KEY_INFORMATION, *PREG_DELETE_KEY_INFORMATION; + +typedef struct _REG_SET_VALUE_KEY_INFORMATION +{ + PVOID Object; + PUNICODE_STRING ValueName; + ULONG TitleIndex; + ULONG Type; + PVOID Data; + ULONG DataSize; +} REG_SET_VALUE_KEY_INFORMATION, *PREG_SET_VALUE_KEY_INFORMATION; + +typedef struct _REG_DELETE_VALUE_KEY_INFORMATION +{ + PVOID Object; + PUNICODE_STRING ValueName; +} REG_DELETE_VALUE_KEY_INFORMATION, *PREG_DELETE_VALUE_KEY_INFORMATION; + +typedef struct _REG_SET_INFORMATION_KEY_INFORMATION +{ + PVOID Object; + KEY_SET_INFORMATION_CLASS KeySetInformationClass; + PVOID KeySetInformation; + ULONG KeySetInformationLength; +} REG_SET_INFORMATION_KEY_INFORMATION, *PREG_SET_INFORMATION_KEY_INFORMATION; + +typedef struct _REG_ENUMERATE_KEY_INFORMATION +{ + PVOID Object; + ULONG Index; + KEY_INFORMATION_CLASS KeyInformationClass; + PVOID KeyInformation; + ULONG Length; + PULONG ResultLength; +} REG_ENUMERATE_KEY_INFORMATION, *PREG_ENUMERATE_KEY_INFORMATION; + +typedef struct _REG_ENUMERATE_VALUE_KEY_INFORMATION +{ + PVOID Object; + ULONG Index; + KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass; + PVOID KeyValueInformation; + ULONG Length; + PULONG ResultLength; +} REG_ENUMERATE_VALUE_KEY_INFORMATION, *PREG_ENUMERATE_VALUE_KEY_INFORMATION; + +typedef struct _REG_QUERY_KEY_INFORMATION +{ + PVOID Object; + KEY_INFORMATION_CLASS KeyInformationClass; + PVOID KeyInformation; + ULONG Length; + PULONG ResultLength; +} REG_QUERY_KEY_INFORMATION, *PREG_QUERY_KEY_INFORMATION; + +typedef struct _REG_QUERY_VALUE_KEY_INFORMATION +{ + PVOID Object; + PUNICODE_STRING ValueName; + KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass; + PVOID KeyValueInformation; + ULONG Length; + PULONG ResultLength; +} REG_QUERY_VALUE_KEY_INFORMATION, *PREG_QUERY_VALUE_KEY_INFORMATION; + +typedef struct _REG_QUERY_MULTIPLE_VALUE_KEY_INFORMATION +{ + PVOID Object; + PKEY_VALUE_ENTRY ValueEntries; + ULONG EntryCount; + PVOID ValueBuffer; + PULONG BufferLength; + PULONG RequiredBufferLength; +} REG_QUERY_MULTIPLE_VALUE_KEY_INFORMATION, *PREG_QUERY_MULTIPLE_VALUE_KEY_INFORMATION; + +typedef struct _REG_PRE_CREATE_KEY_INFORMATION +{ + PUNICODE_STRING CompleteName; +} REG_PRE_CREATE_KEY_INFORMATION, *PREG_PRE_CREATE_KEY_INFORMATION; + +typedef struct _REG_POST_CREATE_KEY_INFORMATION +{ + PUNICODE_STRING CompleteName; + PVOID Object; + NTSTATUS Status; +} REG_POST_CREATE_KEY_INFORMATION, *PREG_POST_CREATE_KEY_INFORMATION; + +typedef struct _REG_PRE_OPEN_KEY_INFORMATION +{ + PUNICODE_STRING CompleteName; +} REG_PRE_OPEN_KEY_INFORMATION, *PREG_PRE_OPEN_KEY_INFORMATION; + +typedef struct _REG_POST_OPEN_KEY_INFORMATION +{ + PUNICODE_STRING CompleteName; + PVOID Object; + NTSTATUS Status; +} REG_POST_OPEN_KEY_INFORMATION, *PREG_POST_OPEN_KEY_INFORMATION; + +typedef struct _REG_POST_OPERATION_INFORMATION +{ + PVOID Object; + NTSTATUS Status; +} REG_POST_OPERATION_INFORMATION,*PREG_POST_OPERATION_INFORMATION; + #endif typedef struct _PLUGPLAY_EVENT_BLOCK @@ -275,5 +385,151 @@ typedef struct _PLUGPLAY_BUS_INSTANCE WCHAR BusName[MAX_BUS_NAME]; } PLUGPLAY_BUS_INSTANCE, *PPLUGPLAY_BUS_INSTANCE; +#ifdef NTOS_MODE_USER + +#include +typedef struct _CM_PARTIAL_RESOURCE_DESCRIPTOR { + UCHAR Type; + UCHAR ShareDisposition; + USHORT Flags; + union { + struct { + PHYSICAL_ADDRESS Start; + ULONG Length; + } Generic; + struct { + PHYSICAL_ADDRESS Start; + ULONG Length; + } Port; + struct { + ULONG Level; + ULONG Vector; + ULONG Affinity; + } Interrupt; + struct { + PHYSICAL_ADDRESS Start; + ULONG Length; + } Memory; + struct { + ULONG Channel; + ULONG Port; + ULONG Reserved1; + } Dma; + struct { + ULONG Data[3]; + } DevicePrivate; + struct { + ULONG Start; + ULONG Length; + ULONG Reserved; + } BusNumber; + struct { + ULONG DataSize; + ULONG Reserved1; + ULONG Reserved2; + } DeviceSpecificData; + } u; +} CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR; + +/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Type */ + +#define CmResourceTypeNull 0 +#define CmResourceTypePort 1 +#define CmResourceTypeInterrupt 2 +#define CmResourceTypeMemory 3 +#define CmResourceTypeDma 4 +#define CmResourceTypeDeviceSpecific 5 +#define CmResourceTypeBusNumber 6 +#define CmResourceTypeMaximum 7 +#define CmResourceTypeNonArbitrated 128 +#define CmResourceTypeConfigData 128 +#define CmResourceTypeDevicePrivate 129 +#define CmResourceTypePcCardConfig 130 +#define CmResourceTypeMfCardConfig 131 + +/* CM_PARTIAL_RESOURCE_DESCRIPTOR.ShareDisposition */ + +typedef enum _CM_SHARE_DISPOSITION { + CmResourceShareUndetermined, + CmResourceShareDeviceExclusive, + CmResourceShareDriverExclusive, + CmResourceShareShared +} CM_SHARE_DISPOSITION; + +/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Flags if Type = CmResourceTypePort */ + +#define CM_RESOURCE_PORT_MEMORY 0x0000 +#define CM_RESOURCE_PORT_IO 0x0001 +#define CM_RESOURCE_PORT_10_BIT_DECODE 0x0004 +#define CM_RESOURCE_PORT_12_BIT_DECODE 0x0008 +#define CM_RESOURCE_PORT_16_BIT_DECODE 0x0010 +#define CM_RESOURCE_PORT_POSITIVE_DECODE 0x0020 +#define CM_RESOURCE_PORT_PASSIVE_DECODE 0x0040 +#define CM_RESOURCE_PORT_WINDOW_DECODE 0x0080 + +/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Flags if Type = CmResourceTypeInterrupt */ + +#define CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE 0x0000 +#define CM_RESOURCE_INTERRUPT_LATCHED 0x0001 + +/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Flags if Type = CmResourceTypeMemory */ + +#define CM_RESOURCE_MEMORY_READ_WRITE 0x0000 +#define CM_RESOURCE_MEMORY_READ_ONLY 0x0001 +#define CM_RESOURCE_MEMORY_WRITE_ONLY 0x0002 +#define CM_RESOURCE_MEMORY_PREFETCHABLE 0x0004 +#define CM_RESOURCE_MEMORY_COMBINEDWRITE 0x0008 +#define CM_RESOURCE_MEMORY_24 0x0010 +#define CM_RESOURCE_MEMORY_CACHEABLE 0x0020 + +/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Flags if Type = CmResourceTypeDma */ + +#define CM_RESOURCE_DMA_8 0x0000 +#define CM_RESOURCE_DMA_16 0x0001 +#define CM_RESOURCE_DMA_32 0x0002 +#define CM_RESOURCE_DMA_8_AND_16 0x0004 +#define CM_RESOURCE_DMA_BUS_MASTER 0x0008 +#define CM_RESOURCE_DMA_TYPE_A 0x0010 +#define CM_RESOURCE_DMA_TYPE_B 0x0020 +#define CM_RESOURCE_DMA_TYPE_F 0x0040 + +typedef struct _CM_PARTIAL_RESOURCE_LIST { + USHORT Version; + USHORT Revision; + ULONG Count; + CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]; +} CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST; + +typedef struct _CM_FULL_RESOURCE_DESCRIPTOR { + INTERFACE_TYPE InterfaceType; + ULONG BusNumber; + CM_PARTIAL_RESOURCE_LIST PartialResourceList; +} CM_FULL_RESOURCE_DESCRIPTOR, *PCM_FULL_RESOURCE_DESCRIPTOR; + +typedef struct _CM_RESOURCE_LIST { + ULONG Count; + CM_FULL_RESOURCE_DESCRIPTOR List[1]; +} CM_RESOURCE_LIST, *PCM_RESOURCE_LIST; + +typedef struct _CM_INT13_DRIVE_PARAMETER { + USHORT DriveSelect; + ULONG MaxCylinders; + USHORT SectorsPerTrack; + USHORT MaxHeads; + USHORT NumberDrives; +} CM_INT13_DRIVE_PARAMETER, *PCM_INT13_DRIVE_PARAMETER; + +typedef struct _CM_DISK_GEOMETRY_DEVICE_DATA +{ + ULONG BytesPerSector; + ULONG NumberOfCylinders; + ULONG SectorsPerTrack; + ULONG NumberOfHeads; +} CM_DISK_GEOMETRY_DEVICE_DATA, *PCM_DISK_GEOMETRY_DEVICE_DATA; + +#include + +#endif + #endif diff --git a/reactos/subsys/system/usetup/partlist.c b/reactos/subsys/system/usetup/partlist.c index 3de244885b0..cff9710b683 100644 --- a/reactos/subsys/system/usetup/partlist.c +++ b/reactos/subsys/system/usetup/partlist.c @@ -424,28 +424,19 @@ ScanForUnpartitionedDiskSpace (PDISKENTRY DiskEntry) NTSTATUS STDCALL -DiskQueryRoutine(PWSTR ValueName, - ULONG ValueType, - PVOID ValueData, - ULONG ValueLength, - PVOID Context, - PVOID EntryContext) +DiskIdentifierQueryRoutine(PWSTR ValueName, + ULONG ValueType, + PVOID ValueData, + ULONG ValueLength, + PVOID Context, + PVOID EntryContext) { - PLIST_ENTRY ListHead = (PLIST_ENTRY)Context; - PULONG GlobalDiskCount = (PULONG)EntryContext; - PBIOSDISKENTRY BiosDiskEntry; + PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context; UNICODE_STRING NameU; if (ValueType == REG_SZ && - ValueLength == 20 * sizeof(WCHAR)) + 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); @@ -453,30 +444,110 @@ DiskQueryRoutine(PWSTR ValueName, NameU.Buffer = (PWCHAR)ValueData + 9; RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature); - InsertTailList(ListHead, &BiosDiskEntry->ListEntry); + return STATUS_SUCCESS; } + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +STDCALL +DiskConfigurationDataQueryRoutine(PWSTR ValueName, + ULONG ValueType, + PVOID ValueData, + ULONG ValueLength, + PVOID Context, + PVOID EntryContext) +{ + PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context; + PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor; + PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry; - return STATUS_SUCCESS; + if (ValueType == REG_FULL_RESOURCE_DESCRIPTOR && + ValueLength == sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + sizeof(CM_DISK_GEOMETRY_DEVICE_DATA)) + { + FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData; + /* FIXME: + * Is this 'paranoia' check correct ? + */ + if (FullResourceDescriptor->InterfaceType != InterfaceTypeUndefined || + FullResourceDescriptor->BusNumber != 0 || + FullResourceDescriptor->PartialResourceList.Count != 1 || + FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Type != CmResourceTypeDeviceSpecific || + FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize != sizeof(CM_DISK_GEOMETRY_DEVICE_DATA)) + { + return STATUS_UNSUCCESSFUL; + } + DiskGeometry = (PCM_DISK_GEOMETRY_DEVICE_DATA)(FullResourceDescriptor + 1); + BiosDiskEntry->DiskGeometry = *DiskGeometry; + + return STATUS_SUCCESS; + } + return STATUS_UNSUCCESSFUL; } +NTSTATUS +STDCALL +SystemConfigurationDataQueryRoutine(PWSTR ValueName, + ULONG ValueType, + PVOID ValueData, + ULONG ValueLength, + PVOID Context, + PVOID EntryContext) +{ + PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor; + PCM_INT13_DRIVE_PARAMETER* Int13Drives = (PCM_INT13_DRIVE_PARAMETER*)Context; + + if (ValueType == REG_FULL_RESOURCE_DESCRIPTOR && + ValueLength >= sizeof (CM_FULL_RESOURCE_DESCRIPTOR) && + (ValueLength - sizeof(CM_FULL_RESOURCE_DESCRIPTOR)) % sizeof(CM_INT13_DRIVE_PARAMETER) == 0) + { + FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData; + if (FullResourceDescriptor->InterfaceType != InterfaceTypeUndefined || + FullResourceDescriptor->BusNumber != -1 || + FullResourceDescriptor->PartialResourceList.Count != 1 || + FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Type != CmResourceTypeDeviceSpecific) + { + return STATUS_UNSUCCESSFUL; + } + *Int13Drives = RtlAllocateHeap(ProcessHeap, 0, ValueLength - sizeof (CM_FULL_RESOURCE_DESCRIPTOR)); + if (*Int13Drives == NULL) + { + return STATUS_NO_MEMORY; + } + memcpy(*Int13Drives, FullResourceDescriptor + 1, ValueLength - sizeof (CM_FULL_RESOURCE_DESCRIPTOR)); + return STATUS_SUCCESS; + } + return STATUS_UNSUCCESSFUL; + +} #define ROOT_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter" STATIC VOID EnumerateBiosDiskEntries(PPARTLIST PartList) { - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; + RTL_QUERY_REGISTRY_TABLE QueryTable[3]; WCHAR Name[100]; ULONG AdapterCount; - ULONG ControllerCount; ULONG DiskCount; NTSTATUS Status; - ULONG GlobalDiskCount=0; + PCM_INT13_DRIVE_PARAMETER Int13Drives; + PBIOSDISKENTRY BiosDiskEntry; - memset(QueryTable, 0, sizeof(QueryTable)); - QueryTable[0].Name = L"Identifier"; - QueryTable[0].QueryRoutine = DiskQueryRoutine; - QueryTable[0].EntryContext = (PVOID)&GlobalDiskCount; + + QueryTable[1].Name = L"Configuration Data"; + QueryTable[1].QueryRoutine = SystemConfigurationDataQueryRoutine; + Int13Drives = NULL; + Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, + L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System", + &QueryTable[1], + (PVOID)&Int13Drives, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status); + return; + } AdapterCount = 0; while (1) @@ -484,7 +555,7 @@ EnumerateBiosDiskEntries(PPARTLIST PartList) swprintf(Name, L"%s\\%lu", ROOT_NAME, AdapterCount); Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, Name, - &QueryTable[1], + &QueryTable[2], NULL, NULL); if (!NT_SUCCESS(Status)) @@ -495,54 +566,93 @@ EnumerateBiosDiskEntries(PPARTLIST PartList) swprintf(Name, L"%s\\%lu\\DiskController", ROOT_NAME, AdapterCount); Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, Name, - &QueryTable[1], + &QueryTable[2], NULL, NULL); if (NT_SUCCESS(Status)) { - ControllerCount = 0; while (1) { - swprintf(Name, L"%s\\%lu\\DiskController\\%lu", ROOT_NAME, AdapterCount, ControllerCount); + swprintf(Name, L"%s\\%lu\\DiskController\\0", ROOT_NAME, AdapterCount); Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, Name, - &QueryTable[1], + &QueryTable[2], NULL, NULL); if (!NT_SUCCESS(Status)) { - break; + RtlFreeHeap(ProcessHeap, 0, Int13Drives); + return; } - swprintf(Name, L"%s\\%lu\\DiskController\\%lu\\DiskPeripheral", ROOT_NAME, AdapterCount, ControllerCount); + swprintf(Name, L"%s\\%lu\\DiskController\\0\\DiskPeripheral", ROOT_NAME, AdapterCount); Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, Name, - &QueryTable[1], + &QueryTable[2], NULL, NULL); if (NT_SUCCESS(Status)) { + QueryTable[0].Name = L"Identifier"; + QueryTable[0].QueryRoutine = DiskIdentifierQueryRoutine; + QueryTable[1].Name = L"Configuration Data"; + QueryTable[1].QueryRoutine = DiskConfigurationDataQueryRoutine; DiskCount = 0; while (1) { - swprintf(Name, L"%s\\%lu\\DiskController\\%lu\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount, ControllerCount, DiskCount); + BiosDiskEntry = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, sizeof(BIOSDISKENTRY)); + if (BiosDiskEntry == NULL) + { + break; + } + swprintf(Name, L"%s\\%lu\\DiskController\\0\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount, DiskCount); Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, Name, QueryTable, - (PVOID)&PartList->BiosDiskListHead, + (PVOID)BiosDiskEntry, NULL); if (!NT_SUCCESS(Status)) { + RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry); break; } + BiosDiskEntry->DiskNumber = DiskCount; + BiosDiskEntry->Recognized = FALSE; + + if (DiskCount < Int13Drives[0].NumberDrives) + { + BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount]; + } + else + { + DPRINT1("Didn't find int13 drive datas for disk %u\n", DiskCount); + } + + + InsertTailList(&PartList->BiosDiskListHead, &BiosDiskEntry->ListEntry); + + DPRINT("DiskNumber: %d\n", BiosDiskEntry->DiskNumber); + DPRINT("Signature: %08x\n", BiosDiskEntry->Signature); + DPRINT("Checksum: %08x\n", BiosDiskEntry->Checksum); + DPRINT("BytesPerSector: %d\n", BiosDiskEntry->DiskGeometry.BytesPerSector); + DPRINT("NumberOfCylinders: %d\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders); + DPRINT("NumberOfHeads: %d\n", BiosDiskEntry->DiskGeometry.NumberOfHeads); + DPRINT("DriveSelect: %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect); + DPRINT("MaxCylinders: %d\n", BiosDiskEntry->Int13DiskData.MaxCylinders); + DPRINT("SectorsPerTrack: %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack); + DPRINT("MaxHeads: %d\n", BiosDiskEntry->Int13DiskData.MaxHeads); + DPRINT("NumberDrives: %d\n", BiosDiskEntry->Int13DiskData.NumberDrives); + DiskCount++; } } - ControllerCount++; + RtlFreeHeap(ProcessHeap, 0, Int13Drives); + return; } } AdapterCount++; } + RtlFreeHeap(ProcessHeap, 0, Int13Drives); } static VOID @@ -656,19 +766,32 @@ AddDiskToList (HANDLE FileHandle, DiskEntry->Checksum = Checksum; DiskEntry->Signature = Signature; + if (Signature == 0) + { + /* If we have no signature, set the disk to dirty. WritePartitionsToDisk creates a new signature */ + DiskEntry->Modified = TRUE; + } DiskEntry->BiosFound = FALSE; ListEntry = List->BiosDiskListHead.Flink; while(ListEntry != &List->BiosDiskListHead) { BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry); + /* FIXME: + * Compare the size from bios and the reported size from driver. + * If we have more than one disk with a zero or with the same signatur + * we must create new signatures and reboot. After the reboot, + * it is possible to identify the disks. + */ if (BiosDiskEntry->Signature == Signature && - BiosDiskEntry->Checksum == Checksum) + BiosDiskEntry->Checksum == Checksum && + !BiosDiskEntry->Recognized) { if (!DiskEntry->BiosFound) { DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber; DiskEntry->BiosFound = TRUE; + BiosDiskEntry->Recognized = TRUE; } else { @@ -2162,7 +2285,8 @@ WritePartitionsToDisk (PPARTLIST List) WCHAR DstPath[MAX_PATH]; UNICODE_STRING Name; HANDLE FileHandle; - PDISKENTRY DiskEntry; + PDISKENTRY DiskEntry1; + PDISKENTRY DiskEntry2; PPARTENTRY PartEntry; PLIST_ENTRY Entry1; PLIST_ENTRY Entry2; @@ -2179,16 +2303,16 @@ WritePartitionsToDisk (PPARTLIST List) Entry1 = List->DiskListHead.Flink; while (Entry1 != &List->DiskListHead) { - DiskEntry = CONTAINING_RECORD (Entry1, - DISKENTRY, - ListEntry); + DiskEntry1 = CONTAINING_RECORD (Entry1, + DISKENTRY, + ListEntry); - if (DiskEntry->Modified == TRUE) + if (DiskEntry1->Modified == TRUE) { /* Count partitioned entries */ PartitionCount = 0; - Entry2 = DiskEntry->PartListHead.Flink; - while (Entry2 != &DiskEntry->PartListHead) + Entry2 = DiskEntry1->PartListHead.Flink; + while (Entry2 != &DiskEntry1->PartListHead) { PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, @@ -2200,50 +2324,44 @@ WritePartitionsToDisk (PPARTLIST List) Entry2 = Entry2->Flink; } - - if (PartitionCount > 0) - { + if (PartitionCount == 0) + { + DriveLayoutSize = sizeof (DRIVE_LAYOUT_INFORMATION) + + ((4 - 1) * sizeof (PARTITION_INFORMATION)); + } + else + { DriveLayoutSize = sizeof (DRIVE_LAYOUT_INFORMATION) + ((PartitionCount - 1) * sizeof (PARTITION_INFORMATION)); - DriveLayout = (PDRIVE_LAYOUT_INFORMATION)RtlAllocateHeap (ProcessHeap, - 0, - DriveLayoutSize); - if (DriveLayout == NULL) - { - DPRINT1 ("RtlAllocateHeap() failed\n"); - return FALSE; - } + } + DriveLayout = (PDRIVE_LAYOUT_INFORMATION)RtlAllocateHeap (ProcessHeap, + 0, + DriveLayoutSize); + if (DriveLayout == NULL) + { + DPRINT1 ("RtlAllocateHeap() failed\n"); + return FALSE; + } - RtlZeroMemory (DriveLayout, - DriveLayoutSize); + RtlZeroMemory (DriveLayout, + DriveLayoutSize); - DriveLayout->PartitionCount = PartitionCount; - if (DiskEntry->Signature == 0) + if (PartitionCount == 0) + { + /* delete all partitions in the mbr */ + DriveLayout->PartitionCount = 4; + for (Index = 0; Index < 4; Index++) { - 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->PartitionEntry[Index].RewritePartition = TRUE; } - - DriveLayout->Signature = DiskEntry->Signature; + } + else + { + DriveLayout->PartitionCount = PartitionCount; Index = 0; - Entry2 = DiskEntry->PartListHead.Flink; - while (Entry2 != &DiskEntry->PartListHead) + Entry2 = DiskEntry1->PartListHead.Flink; + while (Entry2 != &DiskEntry1->PartListHead) { PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, @@ -2258,74 +2376,127 @@ WritePartitionsToDisk (PPARTLIST List) Entry2 = Entry2->Flink; } + } + if (DiskEntry1->Signature == 0) + { + LARGE_INTEGER SystemTime; + TIME_FIELDS TimeFields; + PUCHAR Buffer; + Buffer = (PUCHAR)&DiskEntry1->Signature; - swprintf (DstPath, - L"\\Device\\Harddisk%d\\Partition0", - DiskEntry->DiskNumber); - RtlInitUnicodeString (&Name, - DstPath); - InitializeObjectAttributes (&ObjectAttributes, - &Name, - 0, - NULL, - NULL); - - Status = NtOpenFile (&FileHandle, - FILE_ALL_ACCESS, - &ObjectAttributes, - &Iosb, - 0, - FILE_SYNCHRONOUS_IO_NONALERT); - if (!NT_SUCCESS (Status)) - { - DPRINT1 ("NtOpenFile() failed (Status %lx)\n", Status); - return FALSE; - } + while (1) + { + NtQuerySystemTime (&SystemTime); + RtlTimeToTimeFields (&SystemTime, &TimeFields); + + 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); + + if (DiskEntry1->Signature == 0) + { + continue; + } + + /* check if the signature already exist */ + /* FIXME: + * Check also signatures from disks, which are + * not visible (bootable) by the bios. + */ + Entry2 = List->DiskListHead.Flink; + while (Entry2 != &List->DiskListHead) + { + DiskEntry2 = CONTAINING_RECORD(Entry2, DISKENTRY, ListEntry); + if (DiskEntry1 != DiskEntry2 && + DiskEntry1->Signature == DiskEntry2->Signature) + { + break; + } + Entry2 = Entry2->Flink; + } + if (Entry2 == &List->DiskListHead) + { + break; + } + } + + /* set one partition entry to dirty, this will update the signature */ + DriveLayout->PartitionEntry[0].RewritePartition = TRUE; + + } + + DriveLayout->Signature = DiskEntry1->Signature; - Status = NtDeviceIoControlFile (FileHandle, - NULL, - NULL, - NULL, - &Iosb, - IOCTL_DISK_SET_DRIVE_LAYOUT, - DriveLayout, - DriveLayoutSize, - NULL, - 0); - if (!NT_SUCCESS (Status)) - { - DPRINT1 ("NtDeviceIoControlFile() failed (Status %lx)\n", Status); - NtClose (FileHandle); - return FALSE; - } - RtlFreeHeap (ProcessHeap, - 0, - DriveLayout); + swprintf (DstPath, + L"\\Device\\Harddisk%d\\Partition0", + DiskEntry1->DiskNumber); + RtlInitUnicodeString (&Name, + DstPath); + InitializeObjectAttributes (&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtOpenFile (&FileHandle, + FILE_ALL_ACCESS, + &ObjectAttributes, + &Iosb, + 0, + FILE_SYNCHRONOUS_IO_NONALERT); + + if (!NT_SUCCESS (Status)) + { + DPRINT1 ("NtOpenFile() failed (Status %lx)\n", Status); + return FALSE; + } + Status = NtDeviceIoControlFile (FileHandle, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_DISK_SET_DRIVE_LAYOUT, + DriveLayout, + DriveLayoutSize, + NULL, + 0); + if (!NT_SUCCESS (Status)) + { + DPRINT1 ("NtDeviceIoControlFile() failed (Status %lx)\n", Status); NtClose (FileHandle); + return FALSE; + } - /* Install MBR code if the disk is new */ - if (DiskEntry->NewDisk == TRUE) - { - wcscpy (SrcPath, SourceRootPath.Buffer); - wcscat (SrcPath, L"\\loader\\dosmbr.bin"); + RtlFreeHeap (ProcessHeap, + 0, + DriveLayout); - DPRINT1 ("Install MBR bootcode: %S ==> %S\n", - SrcPath, DstPath); + NtClose (FileHandle); - /* Install MBR bootcode */ - Status = InstallMbrBootCodeToDisk (SrcPath, - DstPath); - if (!NT_SUCCESS (Status)) - { - DPRINT1 ("InstallMbrBootCodeToDisk() failed (Status %lx)\n", - Status); - return FALSE; - } + /* Install MBR code if the disk is new */ + if (DiskEntry1->NewDisk == TRUE && + DiskEntry1->BiosDiskNumber == 0) + { + wcscpy (SrcPath, SourceRootPath.Buffer); + wcscat (SrcPath, L"\\loader\\dosmbr.bin"); - DiskEntry->NewDisk = FALSE; - } + DPRINT ("Install MBR bootcode: %S ==> %S\n", + SrcPath, DstPath); + + /* Install MBR bootcode */ + Status = InstallMbrBootCodeToDisk (SrcPath, + DstPath); + if (!NT_SUCCESS (Status)) + { + DPRINT1 ("InstallMbrBootCodeToDisk() failed (Status %lx)\n", + Status); + return FALSE; + } + + DiskEntry1->NewDisk = FALSE; } } diff --git a/reactos/subsys/system/usetup/partlist.h b/reactos/subsys/system/usetup/partlist.h index 42f9ef586a7..3f79c8d4d02 100644 --- a/reactos/subsys/system/usetup/partlist.h +++ b/reactos/subsys/system/usetup/partlist.h @@ -74,6 +74,9 @@ typedef struct _BIOSDISKENTRY ULONG DiskNumber; ULONG Signature; ULONG Checksum; + BOOLEAN Recognized; + CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry; + CM_INT13_DRIVE_PARAMETER Int13DiskData; } BIOSDISKENTRY, *PBIOSDISKENTRY; -- 2.17.1