Extract WindowsESD.pf separately

This commit is contained in:
paravis committed 2026-11-08 23:17:21 +03:00
1 parent a69409e526
commit 3c807fbcf2
6 files changed
+129 -46

No files matched your search

+81 -37
View File
@@ -6,7 +6,6 @@
#include <cctype>
#include <cstdlib>
#include <cwchar>
#include <filesystem>
#include <string>
#include <vector>
@@ -214,6 +213,12 @@ void App::Apply()
return;
}
if (esdPfAvailable && !IsWimFile(esdPfPath)) {
ShowMessage(MB_ICONERROR | MB_OK, L"WindowsESD.pf повреждён",
L"Файл WindowsESD.pf не является WIM-архивом:\r\n" + esdPfPath);
return;
}
std::wstring message =
Format(L"Накопитель (%.1f ГБ)\r\n\r\n",
static_cast<double>(sizeBytes) / 1073741824.0);
@@ -224,9 +229,14 @@ void App::Apply()
static_cast<double>(p3) / 1024.0);
message += L"Затем на разделы будут распакованы файлы из архива Data.pf\r\n";
message += L"(1 -> PARAVIS, 2 -> VTOYEFI, 3 -> DATA).\r\n\r\n";
if (noEsd) {
message += L"Файлы *.esd из папки WindowsESD копироваться не будут\r\n";
message += L"(остальные файлы папки будут скопированы).\r\n\r\n";
if (esdPfAvailable) {
if (noEsd) {
message += L"WindowsESD.pf распаковываться не будет.\r\n\r\n";
} else {
message += L"После Data.pf будет распакован WindowsESD.pf.\r\n\r\n";
}
} else {
message += L"WindowsESD.pf не найден - Windows ESD не будет распакован.\r\n\r\n";
}
message += L"ВНИМАНИЕ! ВСЕ ДАННЫЕ НА ЭТОМ ДИСКЕ БУДУТ УНИЧТОЖЕНЫ.\r\n";
message += L"Продолжить?";
@@ -341,6 +351,30 @@ void App::Apply()
DebugLog(L"ApplyImages result=%d applied=%d cancel=%d", result, applied, cancel ? 1 : 0);
if (result == 1) {
if (!noEsd && esdPfAvailable) {
int esdResult = ApplyWindowsEsd(disk);
if (esdResult == 3) {
SetWork(L"Отменено");
HideProgress();
BusySet(false);
HideProgress();
ShowMessage(MB_ICONINFORMATION | MB_OK, L"Отменено",
L"Операция отменена пользователем.\r\n\r\n"
L"Диск размечен, Windows ESD не распакован.");
return;
}
if (esdResult == 2) {
SetWork(L"Ошибка Windows ESD");
HideProgress();
ShowMessage(MB_ICONERROR | MB_OK, L"Ошибка Windows ESD",
L"Не удалось распаковать WindowsESD.pf.\r\n\r\n"
L"Проверьте, что файл не повреждён.");
BusySet(false);
HideProgress();
return;
}
}
std::wstring first = GetPartitionLetter(disk, 0);
DebugLog(L"partition0=%s", first.c_str());
@@ -456,39 +490,6 @@ int App::ApplyImages(int disk, const std::wstring& wim)
return 2;
}
if (i == 2 && noEsd) {
std::wstring esdDir = dir + L"WindowsESD";
std::error_code ec;
if (std::filesystem::exists(esdDir, ec)) {
std::filesystem::recursive_directory_iterator it(
esdDir, std::filesystem::directory_options::skip_permission_denied, ec);
const std::filesystem::recursive_directory_iterator end;
while (it != end) {
if (ec) {
DebugLog(L"skip ESD: scan stopped ec=%d", ec.value());
break;
}
const std::filesystem::directory_entry& entry = *it;
std::error_code fileEc;
if (entry.is_regular_file(fileEc)) {
std::wstring ext = entry.path().extension().wstring();
std::transform(ext.begin(), ext.end(), ext.begin(),
[](wchar_t c) {
return static_cast<wchar_t>(towlower(c));
});
if (ext == L".esd") {
std::error_code removeEc;
std::filesystem::remove(entry.path(), removeEc);
DebugLog(L"skip ESD: %s removed=%d ec=%d",
entry.path().c_str(),
removeEc ? 0 : 1, removeEc.value());
}
}
it.increment(ec);
}
}
}
++applied;
if (cancel) {
@@ -499,6 +500,49 @@ int App::ApplyImages(int disk, const std::wstring& wim)
return 1;
}
int App::ApplyWindowsEsd(int disk)
{
std::wstring dir;
for (int attempt = 0; attempt < 15; ++attempt) {
dir = GetPartitionLetter(disk, 2);
if (!dir.empty()) {
break;
}
SleepPump(1000);
}
if (dir.empty()) {
ShowMessage(MB_ICONERROR | MB_OK, L"Ошибка",
L"Не удалось определить букву раздела DATA.");
return 2;
}
if (cancel) {
return 3;
}
if (!IsWimFile(esdPfPath)) {
ShowMessage(MB_ICONERROR | MB_OK, L"WindowsESD.pf повреждён",
L"Файл WindowsESD.pf не является WIM-архивом:\r\n" + esdPfPath);
return 2;
}
std::wstring caption = L"Распаковка Windows ESD";
DebugLog(L"ApplyWindowsEsd %s -> %s", esdPfPath.c_str(), dir.c_str());
phase = 2;
ShowProgress(0);
SetWork(caption);
bool ok = DismApply(esdPfPath, 1, dir, caption);
phase = 0;
if (!ok) {
if (cancel) {
return 3;
}
return 2;
}
return 1;
}
bool App::DismApply(const std::wstring& wim, int index, const std::wstring& dir,
const std::wstring& caption)
{