- Read more information from the registry about the disks detected by the bios.
authorHartmut Birr <osexpert@googlemail.com>
Mon, 19 Sep 2005 20:01:29 +0000 (20:01 +0000)
committerHartmut Birr <osexpert@googlemail.com>
Mon, 19 Sep 2005 20:01:29 +0000 (20:01 +0000)
- 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
reactos/subsys/system/usetup/partlist.c
reactos/subsys/system/usetup/partlist.h

index 4a2e020..2de45c9 100644 (file)
@@ -174,6 +174,116 @@ typedef struct _KEY_BASIC_INFORMATION
     WCHAR Name[1];\r
 } KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION;\r
 \r
+#else\r
+\r
+typedef struct _REG_DELETE_KEY_INFORMATION\r
+{\r
+    PVOID Object;\r
+} REG_DELETE_KEY_INFORMATION, *PREG_DELETE_KEY_INFORMATION;\r
+\r
+typedef struct _REG_SET_VALUE_KEY_INFORMATION\r
+{\r
+    PVOID Object;\r
+    PUNICODE_STRING ValueName;\r
+    ULONG TitleIndex;\r
+    ULONG Type;\r
+    PVOID Data;\r
+    ULONG DataSize;\r
+} REG_SET_VALUE_KEY_INFORMATION, *PREG_SET_VALUE_KEY_INFORMATION;\r
+\r
+typedef struct _REG_DELETE_VALUE_KEY_INFORMATION \r
+{\r
+    PVOID Object;\r
+    PUNICODE_STRING ValueName;\r
+} REG_DELETE_VALUE_KEY_INFORMATION, *PREG_DELETE_VALUE_KEY_INFORMATION;\r
+\r
+typedef struct _REG_SET_INFORMATION_KEY_INFORMATION\r
+{\r
+    PVOID Object;\r
+    KEY_SET_INFORMATION_CLASS KeySetInformationClass;\r
+    PVOID KeySetInformation;\r
+    ULONG KeySetInformationLength;\r
+} REG_SET_INFORMATION_KEY_INFORMATION, *PREG_SET_INFORMATION_KEY_INFORMATION;\r
+\r
+typedef struct _REG_ENUMERATE_KEY_INFORMATION\r
+{\r
+    PVOID Object;\r
+    ULONG Index;\r
+    KEY_INFORMATION_CLASS KeyInformationClass;\r
+    PVOID KeyInformation;\r
+    ULONG Length;\r
+    PULONG ResultLength;\r
+} REG_ENUMERATE_KEY_INFORMATION, *PREG_ENUMERATE_KEY_INFORMATION;\r
+\r
+typedef struct _REG_ENUMERATE_VALUE_KEY_INFORMATION \r
+{\r
+    PVOID Object;\r
+    ULONG Index;\r
+    KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass;\r
+    PVOID KeyValueInformation;\r
+    ULONG Length;\r
+    PULONG ResultLength;\r
+} REG_ENUMERATE_VALUE_KEY_INFORMATION, *PREG_ENUMERATE_VALUE_KEY_INFORMATION;\r
+\r
+typedef struct _REG_QUERY_KEY_INFORMATION\r
+{\r
+    PVOID Object;\r
+    KEY_INFORMATION_CLASS KeyInformationClass;\r
+    PVOID KeyInformation;\r
+    ULONG Length;\r
+    PULONG ResultLength;\r
+} REG_QUERY_KEY_INFORMATION, *PREG_QUERY_KEY_INFORMATION;\r
+\r
+typedef struct _REG_QUERY_VALUE_KEY_INFORMATION \r
+{\r
+    PVOID Object;\r
+    PUNICODE_STRING ValueName;\r
+    KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass;\r
+    PVOID KeyValueInformation;\r
+    ULONG Length;\r
+    PULONG ResultLength;\r
+} REG_QUERY_VALUE_KEY_INFORMATION, *PREG_QUERY_VALUE_KEY_INFORMATION;\r
+\r
+typedef struct _REG_QUERY_MULTIPLE_VALUE_KEY_INFORMATION\r
+{\r
+    PVOID Object;\r
+    PKEY_VALUE_ENTRY ValueEntries;\r
+    ULONG EntryCount;\r
+    PVOID ValueBuffer;\r
+    PULONG BufferLength;\r
+    PULONG RequiredBufferLength;\r
+} REG_QUERY_MULTIPLE_VALUE_KEY_INFORMATION, *PREG_QUERY_MULTIPLE_VALUE_KEY_INFORMATION;\r
+\r
+typedef struct _REG_PRE_CREATE_KEY_INFORMATION \r
+{\r
+    PUNICODE_STRING CompleteName;\r
+} REG_PRE_CREATE_KEY_INFORMATION, *PREG_PRE_CREATE_KEY_INFORMATION;\r
+\r
+typedef struct _REG_POST_CREATE_KEY_INFORMATION \r
+{\r
+    PUNICODE_STRING CompleteName;\r
+    PVOID Object;\r
+    NTSTATUS Status;\r
+} REG_POST_CREATE_KEY_INFORMATION, *PREG_POST_CREATE_KEY_INFORMATION;\r
+\r
+typedef struct _REG_PRE_OPEN_KEY_INFORMATION \r
+{\r
+    PUNICODE_STRING  CompleteName;\r
+} REG_PRE_OPEN_KEY_INFORMATION, *PREG_PRE_OPEN_KEY_INFORMATION;\r
+\r
+typedef struct _REG_POST_OPEN_KEY_INFORMATION \r
+{\r
+    PUNICODE_STRING CompleteName;\r
+    PVOID Object;\r
+    NTSTATUS Status;\r
+} REG_POST_OPEN_KEY_INFORMATION, *PREG_POST_OPEN_KEY_INFORMATION;\r
+\r
+typedef struct _REG_POST_OPERATION_INFORMATION \r
+{\r
+    PVOID Object;\r
+    NTSTATUS Status;\r
+} REG_POST_OPERATION_INFORMATION,*PREG_POST_OPERATION_INFORMATION;\r
+\r
 #endif\r
 \r
 typedef struct _PLUGPLAY_EVENT_BLOCK\r
@@ -275,5 +385,151 @@ typedef struct _PLUGPLAY_BUS_INSTANCE
     WCHAR BusName[MAX_BUS_NAME];\r
 } PLUGPLAY_BUS_INSTANCE, *PPLUGPLAY_BUS_INSTANCE;\r
 \r
+#ifdef NTOS_MODE_USER\r
+\r
+#include <pshpack1.h>\r
+typedef struct _CM_PARTIAL_RESOURCE_DESCRIPTOR {\r
+  UCHAR Type;\r
+  UCHAR ShareDisposition;\r
+  USHORT Flags;\r
+  union {\r
+    struct {\r
+      PHYSICAL_ADDRESS Start;\r
+      ULONG Length;\r
+    } Generic;\r
+    struct {\r
+      PHYSICAL_ADDRESS Start;\r
+      ULONG Length;\r
+    } Port;\r
+    struct {\r
+      ULONG Level;\r
+      ULONG Vector;\r
+      ULONG Affinity;\r
+    } Interrupt;\r
+    struct {\r
+      PHYSICAL_ADDRESS Start;\r
+      ULONG Length;\r
+    } Memory;\r
+    struct {\r
+      ULONG Channel;\r
+      ULONG Port;\r
+      ULONG Reserved1;\r
+    } Dma;\r
+    struct {\r
+      ULONG Data[3];\r
+    } DevicePrivate;\r
+    struct {\r
+      ULONG Start;\r
+      ULONG Length;\r
+      ULONG Reserved;\r
+    } BusNumber;\r
+    struct {\r
+      ULONG DataSize;\r
+      ULONG Reserved1;\r
+      ULONG Reserved2;\r
+    } DeviceSpecificData;\r
+  } u;\r
+} CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR;\r
+\r
+/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Type */\r
+\r
+#define CmResourceTypeNull                0\r
+#define CmResourceTypePort                1\r
+#define CmResourceTypeInterrupt           2\r
+#define CmResourceTypeMemory              3\r
+#define CmResourceTypeDma                 4\r
+#define CmResourceTypeDeviceSpecific      5\r
+#define CmResourceTypeBusNumber           6\r
+#define CmResourceTypeMaximum             7\r
+#define CmResourceTypeNonArbitrated     128\r
+#define CmResourceTypeConfigData        128\r
+#define CmResourceTypeDevicePrivate     129\r
+#define CmResourceTypePcCardConfig      130\r
+#define CmResourceTypeMfCardConfig      131\r
+\r
+/* CM_PARTIAL_RESOURCE_DESCRIPTOR.ShareDisposition */\r
+\r
+typedef enum _CM_SHARE_DISPOSITION {\r
+  CmResourceShareUndetermined,\r
+  CmResourceShareDeviceExclusive,\r
+  CmResourceShareDriverExclusive,\r
+  CmResourceShareShared\r
+} CM_SHARE_DISPOSITION;\r
+\r
+/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Flags if Type = CmResourceTypePort */\r
+\r
+#define CM_RESOURCE_PORT_MEMORY           0x0000\r
+#define CM_RESOURCE_PORT_IO               0x0001\r
+#define CM_RESOURCE_PORT_10_BIT_DECODE    0x0004\r
+#define CM_RESOURCE_PORT_12_BIT_DECODE    0x0008\r
+#define CM_RESOURCE_PORT_16_BIT_DECODE    0x0010\r
+#define CM_RESOURCE_PORT_POSITIVE_DECODE  0x0020\r
+#define CM_RESOURCE_PORT_PASSIVE_DECODE   0x0040\r
+#define CM_RESOURCE_PORT_WINDOW_DECODE    0x0080\r
+\r
+/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Flags if Type = CmResourceTypeInterrupt */\r
+\r
+#define CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE 0x0000\r
+#define CM_RESOURCE_INTERRUPT_LATCHED         0x0001\r
+\r
+/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Flags if Type = CmResourceTypeMemory */\r
+\r
+#define CM_RESOURCE_MEMORY_READ_WRITE     0x0000\r
+#define CM_RESOURCE_MEMORY_READ_ONLY      0x0001\r
+#define CM_RESOURCE_MEMORY_WRITE_ONLY     0x0002\r
+#define CM_RESOURCE_MEMORY_PREFETCHABLE   0x0004\r
+#define CM_RESOURCE_MEMORY_COMBINEDWRITE  0x0008\r
+#define CM_RESOURCE_MEMORY_24             0x0010\r
+#define CM_RESOURCE_MEMORY_CACHEABLE      0x0020\r
+\r
+/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Flags if Type = CmResourceTypeDma */\r
+\r
+#define CM_RESOURCE_DMA_8                 0x0000\r
+#define CM_RESOURCE_DMA_16                0x0001\r
+#define CM_RESOURCE_DMA_32                0x0002\r
+#define CM_RESOURCE_DMA_8_AND_16          0x0004\r
+#define CM_RESOURCE_DMA_BUS_MASTER        0x0008\r
+#define CM_RESOURCE_DMA_TYPE_A            0x0010\r
+#define CM_RESOURCE_DMA_TYPE_B            0x0020\r
+#define CM_RESOURCE_DMA_TYPE_F            0x0040\r
+\r
+typedef struct _CM_PARTIAL_RESOURCE_LIST {\r
+  USHORT  Version;\r
+  USHORT  Revision;\r
+  ULONG  Count;\r
+  CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1];\r
+} CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST;\r
+\r
+typedef struct _CM_FULL_RESOURCE_DESCRIPTOR {\r
+  INTERFACE_TYPE  InterfaceType;\r
+  ULONG  BusNumber;\r
+  CM_PARTIAL_RESOURCE_LIST  PartialResourceList;\r
+} CM_FULL_RESOURCE_DESCRIPTOR, *PCM_FULL_RESOURCE_DESCRIPTOR;\r
+\r
+typedef struct _CM_RESOURCE_LIST {\r
+  ULONG  Count;\r
+  CM_FULL_RESOURCE_DESCRIPTOR  List[1];\r
+} CM_RESOURCE_LIST, *PCM_RESOURCE_LIST;\r
+\r
+typedef struct _CM_INT13_DRIVE_PARAMETER {\r
+  USHORT  DriveSelect;\r
+  ULONG  MaxCylinders;\r
+  USHORT  SectorsPerTrack;\r
+  USHORT  MaxHeads;\r
+  USHORT  NumberDrives;\r
+} CM_INT13_DRIVE_PARAMETER, *PCM_INT13_DRIVE_PARAMETER;\r
+\r
+typedef struct _CM_DISK_GEOMETRY_DEVICE_DATA\r
+{\r
+  ULONG BytesPerSector;\r
+  ULONG NumberOfCylinders;\r
+  ULONG SectorsPerTrack;\r
+  ULONG NumberOfHeads;\r
+} CM_DISK_GEOMETRY_DEVICE_DATA, *PCM_DISK_GEOMETRY_DEVICE_DATA;\r
+\r
+#include <poppack.h>\r
+\r
+#endif\r
+\r
 #endif\r
 \r
index 3de2448..cff9710 100644 (file)
@@ -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;
            }
        }
 
index 42f9ef5..3f79c8d 100644 (file)
@@ -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;