- 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.
Modified: trunk/reactos/include/ndk/cmtypes.h
Modified: trunk/reactos/subsys/system/usetup/partlist.c
Modified: trunk/reactos/subsys/system/usetup/partlist.h

Modified: trunk/reactos/include/ndk/cmtypes.h
--- trunk/reactos/include/ndk/cmtypes.h	2005-09-19 15:16:00 UTC (rev 17934)
+++ trunk/reactos/include/ndk/cmtypes.h	2005-09-19 20:01:29 UTC (rev 17935)
@@ -174,6 +174,116 @@
     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 @@
     WCHAR BusName[MAX_BUS_NAME];
 } PLUGPLAY_BUS_INSTANCE, *PPLUGPLAY_BUS_INSTANCE;
 
+#ifdef NTOS_MODE_USER
+
+#include <pshpack1.h>
+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 <poppack.h>
+
 #endif
 
+#endif
+

Modified: trunk/reactos/subsys/system/usetup/partlist.c
--- trunk/reactos/subsys/system/usetup/partlist.c	2005-09-19 15:16:00 UTC (rev 17934)
+++ trunk/reactos/subsys/system/usetup/partlist.c	2005-09-19 20:01:29 UTC (rev 17935)
@@ -424,28 +424,19 @@
 
 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,38 +444,118 @@
       NameU.Buffer = (PWCHAR)ValueData + 9;
       RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature);
 
-      InsertTailList(ListHead, &BiosDiskEntry->ListEntry);
+      return STATUS_SUCCESS;
     }
+    return STATUS_UNSUCCESSFUL;
+}
 
-    return STATUS_SUCCESS;
+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;
+
+  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)
     {
       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 @@
       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 @@
 
   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 @@
   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 @@
   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 @@
 
 	      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 @@
 
 		  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);
+              while (1)
+                {
+                  NtQuerySystemTime (&SystemTime);
+                  RtlTimeToTimeFields (&SystemTime, &TimeFields);
 
-	      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;
-		}
+                  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);
 
-	      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;
-		}
+                  if (DiskEntry1->Signature == 0)
+                    {
+                      continue;
+                    }
 
-	      RtlFreeHeap (ProcessHeap,
-			   0,
-			   DriveLayout);
+                  /* 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;
+
+
+	  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;
 	    }
 	}
 

Modified: trunk/reactos/subsys/system/usetup/partlist.h
--- trunk/reactos/subsys/system/usetup/partlist.h	2005-09-19 15:16:00 UTC (rev 17934)
+++ trunk/reactos/subsys/system/usetup/partlist.h	2005-09-19 20:01:29 UTC (rev 17935)
@@ -74,6 +74,9 @@
   ULONG DiskNumber;
   ULONG Signature;
   ULONG Checksum;
+  BOOLEAN Recognized;
+  CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
+  CM_INT13_DRIVE_PARAMETER Int13DiskData;
 } BIOSDISKENTRY, *PBIOSDISKENTRY;