Skip to content

Commit 6f8e259

Browse files
author
Andrey
committed
Fix partition creation when Windows uses EFI as system partition
- Fix ProcessService logic to allow creating ISOBOOT when only system EFI exists - Improve mount_partitions.cmd timing and error handling for automatic execution - Update PartitionCreator to conditionally create only missing partitions - Add better synchronization and diagnostics in WinPE partition mounting
1 parent 8c0d614 commit 6f8e259

4 files changed

Lines changed: 93 additions & 48 deletions

File tree

src/config/StartnetConfigurator.cpp

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ bool StartnetConfigurator::createMinimalStartnet(const std::string &mountDir, st
5555
")\r\n"
5656
"\r\n"
5757
"rem Wait for filesystem initialization and partition stabilization\r\n"
58-
"ping 127.0.0.1 -n 4 > nul\r\n"
58+
"ping 127.0.0.1 -n 8 > nul\r\n"
5959
"\r\n"
6060
"rem Start wpeinit in background and continue\r\n"
6161
"start /min wpeinit\r\n"
@@ -90,31 +90,54 @@ bool StartnetConfigurator::createMinimalStartnet(const std::string &mountDir, st
9090
"echo [1/4] Rescanning disks...\r\n"
9191
"echo rescan > X:\\rescan2.txt\r\n"
9292
"diskpart /s X:\\rescan2.txt\r\n"
93+
"if errorlevel 1 (\r\n"
94+
" echo WARNING: Disk rescan failed\r\n"
95+
")\r\n"
9396
"del X:\\rescan2.txt 2>nul\r\n"
9497
"\r\n"
9598
"rem Mount all partitions with verbose output\r\n"
9699
"echo [2/4] Mounting all partitions on disk 0...\r\n"
100+
"echo list partition > X:\\list_part.txt\r\n"
101+
"diskpart /s X:\\list_part.txt > X:\\part_list.txt 2>&1\r\n"
97102
"for /L %%p in (1,1,6) do (\r\n"
98103
" echo Mounting partition %%p...\r\n"
99104
" echo select disk 0 > X:\\mount%%p.txt\r\n"
100105
" echo select partition %%p >> X:\\mount%%p.txt\r\n"
101106
" echo assign >> X:\\mount%%p.txt\r\n"
102-
" diskpart /s X:\\mount%%p.txt > nul 2>&1\r\n"
107+
" diskpart /s X:\\mount%%p.txt > X:\\mount_out%%p.txt 2>&1\r\n"
108+
" findstr /C:\"DiskPart successfully assigned\" X:\\mount_out%%p.txt > nul 2>&1\r\n"
109+
" if errorlevel 1 (\r\n"
110+
" findstr /C:\"No drive letter or mount point\" X:\\mount_out%%p.txt > nul 2>&1\r\n"
111+
" if errorlevel 1 (\r\n"
112+
" echo WARNING: Failed to mount partition %%p (may not exist or already mounted)\r\n"
113+
" ) else (\r\n"
114+
" echo SUCCESS: Partition %%p already has a drive letter\r\n"
115+
" )\r\n"
116+
" ) else (\r\n"
117+
" echo SUCCESS: Partition %%p mounted\r\n"
118+
" )\r\n"
103119
" del X:\\mount%%p.txt 2>nul\r\n"
120+
" del X:\\mount_out%%p.txt 2>nul\r\n"
104121
")\r\n"
122+
"del X:\\list_part.txt 2>nul\r\n"
123+
"del X:\\part_list.txt 2>nul\r\n"
105124
"\r\n"
106125
"rem Wait for partitions to stabilize\r\n"
107126
"echo [3/4] Waiting for partitions to stabilize...\r\n"
108-
"ping 127.0.0.1 -n 3 > nul\r\n"
127+
"ping 127.0.0.1 -n 5 > nul\r\n"
109128
"\r\n"
110129
"rem List all available drives for debugging\r\n"
111130
"echo [4/4] Searching for Windows installation files...\r\n"
112-
"echo Available drives:\r\n"
131+
"echo Available drives after mounting:\r\n"
113132
"for %%d in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (\r\n"
114133
" if exist %%d:\\ echo %%d:\r\n"
115134
")\r\n"
116135
"echo.\r\n"
117136
"\r\n"
137+
"rem Additional wait for critical partitions to be ready\r\n"
138+
"echo Waiting for critical partitions to be fully accessible...\r\n"
139+
"ping 127.0.0.1 -n 3 > nul\r\n"
140+
"\r\n"
118141
"rem Find partition with install.esd/wim and setup.exe (exclude only X: WinPE)\r\n"
119142
"set INSTALL_DRIVE=\r\n"
120143
"for %%d in (C D E F G H I J K L M N O P Q R S T U V W Y Z) do (\r\n"

src/models/PartitionCreator.cpp

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
PartitionCreator::PartitionCreator(EventManager *eventManager) : eventManager(eventManager) {}
1212

13-
bool PartitionCreator::performDiskpartOperations(const std::string &format) {
13+
bool PartitionCreator::performDiskpartOperations(const std::string &format, bool createIsoBoot, bool createEfi) {
1414
std::string logDir = Utils::getExeDirectory() + "logs";
1515
CreateDirectoryA(logDir.c_str(), NULL);
1616
if (eventManager)
@@ -42,13 +42,17 @@ bool PartitionCreator::performDiskpartOperations(const std::string &format) {
4242
scriptFile << "select disk 0\n";
4343
scriptFile << "select volume C\n";
4444
scriptFile << "shrink desired=12000 minimum=12000\n";
45-
scriptFile << "create partition primary size=10000\n";
46-
scriptFile << "format fs=" << fsFormat << " quick label=\"" << VOLUME_LABEL << "\"\n";
47-
scriptFile << "create partition efi size=" << REQUIRED_EFI_SIZE_MB << "\n";
48-
// Set GPT attributes: Hidden (0x8000000000000000) + Required (0x1) = 0x8000000000000001
49-
// This prevents Windows Setup from automatically detecting and using this partition
50-
scriptFile << "gpt attributes=0x8000000000000001\n";
51-
scriptFile << "format fs=fat32 quick label=\"" << EFI_VOLUME_LABEL << "\"\n";
45+
if (createIsoBoot) {
46+
scriptFile << "create partition primary size=10000\n";
47+
scriptFile << "format fs=" << fsFormat << " quick label=\"" << VOLUME_LABEL << "\"\n";
48+
}
49+
if (createEfi) {
50+
scriptFile << "create partition efi size=" << REQUIRED_EFI_SIZE_MB << "\n";
51+
// Set GPT attributes: Hidden (0x8000000000000000) + Required (0x1) = 0x8000000000000001
52+
// This prevents Windows Setup from automatically detecting and using this partition
53+
scriptFile << "gpt attributes=0x8000000000000001\n";
54+
scriptFile << "format fs=fat32 quick label=\"" << EFI_VOLUME_LABEL << "\"\n";
55+
}
5256
scriptFile << "exit\n";
5357
scriptFile.close();
5458

@@ -136,11 +140,15 @@ bool PartitionCreator::performDiskpartOperations(const std::string &format) {
136140
logFile << "select disk 0\n";
137141
logFile << "select volume C\n";
138142
logFile << "shrink desired=12000 minimum=12000\n";
139-
logFile << "create partition primary size=10000\n";
140-
logFile << "format fs=" << fsFormat << " quick label=\"" << VOLUME_LABEL << "\"\n";
141-
logFile << "create partition efi size=" << REQUIRED_EFI_SIZE_MB << "\n";
142-
logFile << "gpt attributes=0x8000000000000001\n";
143-
logFile << "format fs=fat32 quick label=\"" << EFI_VOLUME_LABEL << "\"\n";
143+
if (createIsoBoot) {
144+
logFile << "create partition primary size=10000\n";
145+
logFile << "format fs=" << fsFormat << " quick label=\"" << VOLUME_LABEL << "\"\n";
146+
}
147+
if (createEfi) {
148+
logFile << "create partition efi size=" << REQUIRED_EFI_SIZE_MB << "\n";
149+
logFile << "gpt attributes=0x8000000000000001\n";
150+
logFile << "format fs=fat32 quick label=\"" << EFI_VOLUME_LABEL << "\"\n";
151+
}
144152
logFile << "exit\n";
145153
logFile << "\nExit code: " << exitCode << "\n";
146154
logFile << "\nDiskpart output:\n" << Utils::ansi_to_utf8(output) << "\n";

src/models/PartitionCreator.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class PartitionCreator {
1010
explicit PartitionCreator(EventManager *eventManager);
1111
~PartitionCreator() = default;
1212

13-
bool performDiskpartOperations(const std::string &format);
13+
bool performDiskpartOperations(const std::string &format, bool createIsoBoot = true, bool createEfi = true);
1414
bool verifyPartitionsCreated();
1515

1616
private:

src/services/partitionmanager.cpp

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -303,46 +303,60 @@ bool PartitionManager::createPartition(const std::string &format, bool skipInteg
303303
LocalizedOrUtf8("log.partition.usingExistingPartitions", "Using existing partitions.\r\n"));
304304
} else {
305305
// Only one partition exists - this is an inconsistent state
306-
// CRITICAL: Check if Windows is using the EFI partition before attempting to delete it
307306
bool windowsUsingEfi = volumeDetector->isWindowsUsingEfiPartition();
308307

309-
if (windowsUsingEfi) {
310-
if (eventManager) {
311-
eventManager->notifyLogUpdate("\r\n");
312-
eventManager->notifyLogUpdate("========================================\r\n");
313-
eventManager->notifyLogUpdate(LocalizedOrUtf8("log.partition.criticalError", "CRITICAL ERROR:\r\n"));
314-
eventManager->notifyLogUpdate(
315-
LocalizedOrUtf8("log.partition.windowsUsingEfiSystem",
316-
"Windows is using the ISOEFI partition as its system EFI partition.\r\n"));
317-
eventManager->notifyLogUpdate(
318-
LocalizedOrUtf8("log.partition.cannotDeleteBreakBoot",
319-
"Cannot delete or recreate this partition - it would break Windows boot.\r\n"));
308+
if (partitionExists() && !efiPartitionExists()) {
309+
// Only ISOBOOT exists, no EFI - recreate both
310+
if (eventManager)
320311
eventManager->notifyLogUpdate(
321-
LocalizedOrUtf8("log.partition.manualRecovery",
322-
"Please manually recover space and ensure both partitions exist.\r\n"));
323-
eventManager->notifyLogUpdate("========================================\r\n");
324-
eventManager->notifyLogUpdate("\r\n");
325-
}
326-
return false;
327-
}
312+
LocalizedOrUtf8("log.partition.onlyIsoBootExists",
313+
"Only ISOBOOT partition exists. Recreating both partitions...\r\n"));
328314

329-
if (eventManager)
330-
eventManager->notifyLogUpdate(
331-
LocalizedOrUtf8("log.partition.inconsistentState",
332-
"Inconsistent state: Only one partition exists. Recreating both...\r\n"));
315+
if (!spaceManager->recoverSpace()) {
316+
if (eventManager)
317+
eventManager->notifyLogUpdate(
318+
LocalizedOrUtf8("log.partition.errorRecoveringSpace", "Error: Space recovery failed.\r\n"));
319+
return false;
320+
}
321+
needsToCreatePartitions = true;
322+
} else if (!partitionExists() && efiPartitionExists()) {
323+
// Only EFI exists
324+
if (windowsUsingEfi) {
325+
// Windows is using the EFI partition - reuse it and create ISOBOOT
326+
if (eventManager) {
327+
eventManager->notifyLogUpdate(
328+
LocalizedOrUtf8("log.partition.onlyEfiExistsWindowsUsing",
329+
"Only EFI partition exists and Windows is using it as system EFI.\r\n"));
330+
eventManager->notifyLogUpdate(
331+
LocalizedOrUtf8("log.partition.reuseEfiCreateIsoBoot",
332+
"EFI partition will be reused. Creating ISOBOOT partition...\r\n"));
333+
}
334+
// Don't run space recovery since we want to keep the EFI partition
335+
// Just create the ISOBOOT partition
336+
needsToCreatePartitions = true;
337+
} else {
338+
// Windows is not using EFI - safe to recreate both
339+
if (eventManager)
340+
eventManager->notifyLogUpdate(
341+
LocalizedOrUtf8("log.partition.onlyEfiExistsRecreating",
342+
"Only EFI partition exists (not used by Windows). Recreating both...\r\n"));
333343

334-
if (!spaceManager->recoverSpace()) {
335-
if (eventManager)
336-
eventManager->notifyLogUpdate(
337-
LocalizedOrUtf8("log.partition.errorRecoveringSpace", "Error: Space recovery failed.\r\n"));
338-
return false;
344+
if (!spaceManager->recoverSpace()) {
345+
if (eventManager)
346+
eventManager->notifyLogUpdate(
347+
LocalizedOrUtf8("log.partition.errorRecoveringSpace", "Error: Space recovery failed.\r\n"));
348+
return false;
349+
}
350+
needsToCreatePartitions = true;
351+
}
339352
}
340-
needsToCreatePartitions = true;
341353
}
342354

343355
// Step 4: Create partitions using diskpart (only if needed)
344356
if (needsToCreatePartitions) {
345-
if (!partitionCreator->performDiskpartOperations(format)) {
357+
bool createIsoBoot = !partitionExists(); // Create ISOBOOT if it doesn't exist
358+
bool createEfi = !efiPartitionExists(); // Create EFI if it doesn't exist
359+
if (!partitionCreator->performDiskpartOperations(format, createIsoBoot, createEfi)) {
346360
return false;
347361
}
348362

0 commit comments

Comments
 (0)