@@ -1493,23 +1493,20 @@ LayoutSettingsPage(PINPUT_RECORD Ir)
14931493
14941494
14951495static BOOLEAN
1496- IsPartitionLargeEnough (
1497- _In_ PPARTENTRY PartEntry )
1496+ IsMediumLargeEnough (
1497+ _In_ ULONGLONG SizeInBytes )
14981498{
14991499 /* Retrieve the maximum size in MB (rounded up) */
1500- ULONGLONG PartSize = RoundingDivide (GetPartEntrySizeInBytes ( PartEntry ) , MB );
1500+ ULONGLONG SizeInMB = RoundingDivide (SizeInBytes , MB );
15011501
1502- if (PartSize < USetupData .RequiredPartitionDiskSpace )
1502+ /* Check the medium size */
1503+ if (SizeInMB < USetupData .RequiredPartitionDiskSpace )
15031504 {
1504- /* Partition is too small so ask for another one */
1505- DPRINT1 ("Partition is too small (size: %I64u MB), required disk space is %lu MB\n" ,
1506- PartSize , USetupData .RequiredPartitionDiskSpace );
1505+ DPRINT1 ("Partition/Volume is too small (size: %I64u MB), required space is %lu MB\n" ,
1506+ SizeInMB , USetupData .RequiredPartitionDiskSpace );
15071507 return FALSE;
15081508 }
1509- else
1510- {
1511- return TRUE;
1512- }
1509+ return TRUE;
15131510}
15141511
15151512
@@ -1535,6 +1532,7 @@ SelectPartitionPage(PINPUT_RECORD Ir)
15351532{
15361533 PARTLIST_UI ListUi ;
15371534 ULONG Error ;
1535+ ULONGLONG MaxTargetSize ;
15381536
15391537 if (PartitionList == NULL )
15401538 {
@@ -1555,7 +1553,9 @@ SelectPartitionPage(PINPUT_RECORD Ir)
15551553 {
15561554 ASSERT (CurrentInstallation );
15571555
1558- /* Determine the selected installation disk & partition */
1556+ /* Determine the selected installation disk & partition.
1557+ * It must exist and be valid, since this is the partition
1558+ * where the existing installation already resides. */
15591559 InstallPartition = SelectPartition (PartitionList ,
15601560 CurrentInstallation -> DiskNumber ,
15611561 CurrentInstallation -> PartitionNumber );
@@ -1564,6 +1564,8 @@ SelectPartitionPage(PINPUT_RECORD Ir)
15641564 DPRINT1 ("RepairUpdateFlag == TRUE, SelectPartition() returned FALSE, assert!\n" );
15651565 ASSERT (FALSE);
15661566 }
1567+ ASSERT (InstallPartition -> IsPartitioned );
1568+ ASSERT (InstallPartition -> Volume );
15671569
15681570 return START_PARTITION_OPERATIONS_PAGE ;
15691571 }
@@ -1577,59 +1579,46 @@ SelectPartitionPage(PINPUT_RECORD Ir)
15771579 yScreen - 3 );
15781580 DrawPartitionList (& ListUi );
15791581
1580- if (IsUnattendedSetup )
1582+ if (IsUnattendedSetup ) do
15811583 {
1584+ /* If DestinationDiskNumber or DestinationPartitionNumber are invalid
1585+ * (see below), don't select the partition and show the list instead */
1586+ if (USetupData .DestinationDiskNumber == -1 ||
1587+ USetupData .DestinationPartitionNumber == -1 )
1588+ {
1589+ break ;
1590+ }
1591+
15821592 /* Determine the selected installation disk & partition */
1583- InstallPartition = SelectPartition (PartitionList ,
1593+ CurrentPartition = SelectPartition (PartitionList ,
15841594 USetupData .DestinationDiskNumber ,
15851595 USetupData .DestinationPartitionNumber );
1586- if (!InstallPartition )
1587- {
1588- CurrentPartition = ListUi .CurrentPartition ;
1589-
1590- if (USetupData .AutoPartition )
1591- {
1592- ASSERT (CurrentPartition != NULL );
1593- ASSERT (!IsContainerPartition (CurrentPartition -> PartitionType ));
1594-
1595- /* Automatically create the partition on the whole empty space;
1596- * it will be formatted later with default parameters */
1597- CreatePartition (PartitionList ,
1598- CurrentPartition ,
1599- 0ULL ,
1600- 0 );
1601- if (CurrentPartition -> Volume )
1602- CurrentPartition -> Volume -> New |= VOLUME_NEW_AUTOCREATE ;
1603-
1604- // FIXME?? Aren't we going to enter an infinite loop, if this test fails??
1605- if (!IsPartitionLargeEnough (CurrentPartition ))
1606- {
1607- MUIDisplayError (ERROR_INSUFFICIENT_PARTITION_SIZE , Ir , POPUP_WAIT_ANY_KEY ,
1608- USetupData .RequiredPartitionDiskSpace );
1609- return SELECT_PARTITION_PAGE ; /* let the user select another partition */
1610- }
16111596
1612- InstallPartition = CurrentPartition ;
1613- return START_PARTITION_OPERATIONS_PAGE ;
1614- }
1615- }
1616- else
1597+ /* Now reset DestinationDiskNumber and DestinationPartitionNumber
1598+ * to *invalid* values, so that if the corresponding partition is
1599+ * determined to be invalid by the code below or in CreateInstallPartition,
1600+ * we don't reselect it when SelectPartitionPage() is called again */
1601+ USetupData .DestinationDiskNumber = -1 ;
1602+ USetupData .DestinationPartitionNumber = -1 ;
1603+
1604+ // FIXME: Here and in the AutoPartition case below, the CurrentPartition
1605+ // may actually be unsuitable (MBR-extended, non-simple volume...).
1606+ // More checks need to be made here!
1607+ //
1608+ // NOTE: We don't check for CurrentPartition->Volume in case
1609+ // the partition doesn't contain a recognized volume/none exists.
1610+ // We also don't check whether IsPartitioned is TRUE, because if
1611+ // the partition is still empty space, we'll try to partition it.
1612+ if (CurrentPartition && !IsContainerPartition (CurrentPartition -> PartitionType ))
1613+ goto CreateInstallPartition ;
1614+
1615+ if (USetupData .AutoPartition )
16171616 {
1618- ASSERT (!IsContainerPartition (InstallPartition -> PartitionType ));
1619-
1620- DrawPartitionList (& ListUi ); // FIXME: Doesn't make much sense...
1621-
1622- // FIXME?? Aren't we going to enter an infinite loop, if this test fails??
1623- if (!IsPartitionLargeEnough (InstallPartition ))
1624- {
1625- MUIDisplayError (ERROR_INSUFFICIENT_PARTITION_SIZE , Ir , POPUP_WAIT_ANY_KEY ,
1626- USetupData .RequiredPartitionDiskSpace );
1627- return SELECT_PARTITION_PAGE ; /* let the user select another partition */
1628- }
1629-
1630- return START_PARTITION_OPERATIONS_PAGE ;
1617+ CurrentPartition = ListUi .CurrentPartition ;
1618+ // TODO: Do more checks, and loop until we find a valid partition.
1619+ goto CreateInstallPartition ;
16311620 }
1632- }
1621+ } while ( 0 );
16331622
16341623 while (TRUE)
16351624 {
@@ -1638,7 +1627,7 @@ SelectPartitionPage(PINPUT_RECORD Ir)
16381627 CurrentPartition = ListUi .CurrentPartition ;
16391628
16401629 /* Update status text */
1641- if (CurrentPartition == NULL )
1630+ if (! CurrentPartition )
16421631 {
16431632 // FIXME: If we get a NULL current partition, this means that
16441633 // the current disk is of unrecognized type. So we should display
@@ -1679,7 +1668,7 @@ SelectPartitionPage(PINPUT_RECORD Ir)
16791668 PartitionList = NULL ;
16801669 return QUIT_PAGE ;
16811670 }
1682- break ;
1671+ return SELECT_PARTITION_PAGE ;
16831672 }
16841673 else if ((Ir -> Event .KeyEvent .uChar .AsciiChar == 0x00 ) &&
16851674 (Ir -> Event .KeyEvent .wVirtualKeyCode == VK_DOWN )) /* DOWN */
@@ -1693,10 +1682,11 @@ SelectPartitionPage(PINPUT_RECORD Ir)
16931682 }
16941683 else if (Ir -> Event .KeyEvent .wVirtualKeyCode == VK_RETURN ) /* ENTER */
16951684 {
1696- ASSERT (CurrentPartition != NULL );
1685+ ASSERT (CurrentPartition );
16971686
1687+ /* Don't select an extended partition for OS installation */
16981688 if (IsContainerPartition (CurrentPartition -> PartitionType ))
1699- continue ; // return SELECT_PARTITION_PAGE;
1689+ continue ;
17001690
17011691 /*
17021692 * Check whether the user wants to install ReactOS on a disk that
@@ -1715,38 +1705,11 @@ SelectPartitionPage(PINPUT_RECORD Ir)
17151705 // return SELECT_PARTITION_PAGE;
17161706 }
17171707
1718- if (!CurrentPartition -> IsPartitioned )
1719- {
1720- Error = PartitionCreationChecks (CurrentPartition );
1721- if (Error != NOT_AN_ERROR )
1722- {
1723- MUIDisplayError (Error , Ir , POPUP_WAIT_ANY_KEY );
1724- return SELECT_PARTITION_PAGE ;
1725- }
1726-
1727- /* Automatically create the partition on the whole empty space;
1728- * it will be formatted later with default parameters */
1729- CreatePartition (PartitionList ,
1730- CurrentPartition ,
1731- 0ULL ,
1732- 0 );
1733- if (CurrentPartition -> Volume )
1734- CurrentPartition -> Volume -> New |= VOLUME_NEW_AUTOCREATE ;
1735- }
1736-
1737- if (!IsPartitionLargeEnough (CurrentPartition ))
1738- {
1739- MUIDisplayError (ERROR_INSUFFICIENT_PARTITION_SIZE , Ir , POPUP_WAIT_ANY_KEY ,
1740- USetupData .RequiredPartitionDiskSpace );
1741- return SELECT_PARTITION_PAGE ; /* let the user select another partition */
1742- }
1743-
1744- InstallPartition = CurrentPartition ;
1745- return START_PARTITION_OPERATIONS_PAGE ;
1708+ goto CreateInstallPartition ;
17461709 }
17471710 else if (Ir -> Event .KeyEvent .wVirtualKeyCode == 'C' ) /* C */
17481711 {
1749- ASSERT (CurrentPartition != NULL );
1712+ ASSERT (CurrentPartition );
17501713
17511714 Error = PartitionCreationChecks (CurrentPartition );
17521715 if (Error != NOT_AN_ERROR )
@@ -1760,24 +1723,25 @@ SelectPartitionPage(PINPUT_RECORD Ir)
17601723 }
17611724 else if (Ir -> Event .KeyEvent .wVirtualKeyCode == 'E' ) /* E */
17621725 {
1763- ASSERT (CurrentPartition != NULL );
1726+ ASSERT (CurrentPartition );
17641727
1765- if (CurrentPartition -> LogicalPartition == FALSE)
1766- {
1767- Error = ExtendedPartitionCreationChecks (CurrentPartition );
1768- if (Error != NOT_AN_ERROR )
1769- {
1770- MUIDisplayError (Error , Ir , POPUP_WAIT_ANY_KEY );
1771- return SELECT_PARTITION_PAGE ;
1772- }
1728+ /* Don't create an extended partition within a logical partition */
1729+ if (CurrentPartition -> LogicalPartition )
1730+ continue ;
17731731
1774- PartCreateType = PartTypeExtended ;
1775- return CREATE_PARTITION_PAGE ;
1732+ Error = ExtendedPartitionCreationChecks (CurrentPartition );
1733+ if (Error != NOT_AN_ERROR )
1734+ {
1735+ MUIDisplayError (Error , Ir , POPUP_WAIT_ANY_KEY );
1736+ return SELECT_PARTITION_PAGE ;
17761737 }
1738+
1739+ PartCreateType = PartTypeExtended ;
1740+ return CREATE_PARTITION_PAGE ;
17771741 }
17781742 else if (Ir -> Event .KeyEvent .wVirtualKeyCode == 'D' ) /* D */
17791743 {
1780- ASSERT (CurrentPartition != NULL );
1744+ ASSERT (CurrentPartition );
17811745
17821746 /* Ignore deletion in case this is not a partitioned entry */
17831747 if (!CurrentPartition -> IsPartitioned )
@@ -1818,7 +1782,42 @@ SelectPartitionPage(PINPUT_RECORD Ir)
18181782 }
18191783 }
18201784
1821- return SELECT_PARTITION_PAGE ;
1785+ CreateInstallPartition :
1786+ ASSERT (CurrentPartition );
1787+ ASSERT (!IsContainerPartition (CurrentPartition -> PartitionType ));
1788+
1789+ /* Create the partition if the selected region is empty */
1790+ if (!CurrentPartition -> IsPartitioned )
1791+ {
1792+ Error = PartitionCreationChecks (CurrentPartition );
1793+ if (Error != NOT_AN_ERROR )
1794+ {
1795+ MUIDisplayError (Error , Ir , POPUP_WAIT_ANY_KEY );
1796+ return SELECT_PARTITION_PAGE ;
1797+ }
1798+
1799+ /* Automatically create the partition on the whole empty space;
1800+ * it will be formatted later with default parameters */
1801+ CreatePartition (PartitionList ,
1802+ CurrentPartition ,
1803+ 0ULL ,
1804+ 0 );
1805+ ASSERT (CurrentPartition -> IsPartitioned );
1806+ if (CurrentPartition -> Volume )
1807+ CurrentPartition -> Volume -> New |= VOLUME_NEW_AUTOCREATE ;
1808+ }
1809+
1810+ /* Verify the target medium size */
1811+ MaxTargetSize = GetPartEntrySizeInBytes (CurrentPartition );
1812+ if (!IsMediumLargeEnough (MaxTargetSize ))
1813+ {
1814+ MUIDisplayError (ERROR_INSUFFICIENT_PARTITION_SIZE , Ir , POPUP_WAIT_ANY_KEY ,
1815+ USetupData .RequiredPartitionDiskSpace );
1816+ return SELECT_PARTITION_PAGE ; /* Let the user select another partition */
1817+ }
1818+
1819+ InstallPartition = CurrentPartition ;
1820+ return START_PARTITION_OPERATIONS_PAGE ;
18221821}
18231822
18241823
0 commit comments