diff --git a/INSTALL/Ventoy2Disk.exe b/INSTALL/Ventoy2Disk.exe index 92a77d70..59f86dc8 100644 Binary files a/INSTALL/Ventoy2Disk.exe and b/INSTALL/Ventoy2Disk.exe differ diff --git a/INSTALL/Ventoy2Disk_ARM.exe b/INSTALL/Ventoy2Disk_ARM.exe index d1398f64..24865c6f 100644 Binary files a/INSTALL/Ventoy2Disk_ARM.exe and b/INSTALL/Ventoy2Disk_ARM.exe differ diff --git a/INSTALL/Ventoy2Disk_ARM64.exe b/INSTALL/Ventoy2Disk_ARM64.exe index 18a02ae7..ff2a384c 100644 Binary files a/INSTALL/Ventoy2Disk_ARM64.exe and b/INSTALL/Ventoy2Disk_ARM64.exe differ diff --git a/INSTALL/Ventoy2Disk_X64.exe b/INSTALL/Ventoy2Disk_X64.exe index c6cf57cc..e1be78a6 100644 Binary files a/INSTALL/Ventoy2Disk_X64.exe and b/INSTALL/Ventoy2Disk_X64.exe differ diff --git a/INSTALL/grub/localboot.cfg b/INSTALL/grub/localboot.cfg index c1106af7..9366b68c 100644 --- a/INSTALL/grub/localboot.cfg +++ b/INSTALL/grub/localboot.cfg @@ -76,6 +76,11 @@ else terminal_output console chainloader /EFI/Microsoft/Boot/bootmgfw.efi boot + elif [ -f ($vtoydev,$partid)/efi/Microsoft/Boot/bootmgfw.efi ]; then + set root=($vtoydev,$partid) + terminal_output console + chainloader /efi/Microsoft/Boot/bootmgfw.efi + boot fi else break @@ -87,6 +92,10 @@ else terminal_output console chainloader /EFI/Microsoft/Boot/bootmgfw.efi boot + elif search -n -s -f /efi/Microsoft/Boot/bootmgfw.efi; then + terminal_output console + chainloader /efi/Microsoft/Boot/bootmgfw.efi + boot else echo "Windows NOT found ..." fi diff --git a/Ventoy2Disk/Ventoy2Disk/DiskService.c b/Ventoy2Disk/Ventoy2Disk/DiskService.c new file mode 100644 index 00000000..4272d6fe --- /dev/null +++ b/Ventoy2Disk/Ventoy2Disk/DiskService.c @@ -0,0 +1,111 @@ +/****************************************************************************** +* DiskService.c +* +* Copyright (c) 2021, longpanda +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 3 of the +* License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, see . +* +*/ + +#include +#include +#include +#include +#include +#include "Ventoy2Disk.h" +#include "DiskService.h" + +BOOL DISK_CleanDisk(int DriveIndex) +{ + BOOL ret; + + ret = VDS_CleanDisk(DriveIndex); + if (!ret) + { + ret = PSHELL_CleanDisk(DriveIndex); + } + + return ret; +} + + +BOOL DISK_DeleteVtoyEFIPartition(int DriveIndex, UINT64 EfiPartOffset) +{ + BOOL ret; + + ret = VDS_DeleteVtoyEFIPartition(DriveIndex, EfiPartOffset); + if (!ret) + { + ret = PSHELL_DeleteVtoyEFIPartition(DriveIndex, EfiPartOffset); + } + + return ret; +} + +BOOL DISK_ChangeVtoyEFI2ESP(int DriveIndex, UINT64 Offset) +{ + BOOL ret; + + ret = VDS_ChangeVtoyEFI2ESP(DriveIndex, Offset); + if (!ret) + { + ret = PSHELL_ChangeVtoyEFI2ESP(DriveIndex, Offset); + } + + return ret; +} + + +BOOL DISK_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset) +{ + BOOL ret; + + ret = VDS_ChangeVtoyEFI2Basic(DriveIndex, Offset); + if (!ret) + { + ret = PSHELL_ChangeVtoyEFI2Basic(DriveIndex, Offset); + } + + return ret; +} + +BOOL DISK_ChangeVtoyEFIAttr(int DriveIndex, UINT64 Offset, UINT64 Attr) +{ + BOOL ret; + + ret = VDS_ChangeVtoyEFIAttr(DriveIndex, Offset, Attr); + + return ret; +} + +BOOL DISK_ShrinkVolume(int DriveIndex, const char* VolumeGuid, CHAR DriveLetter, UINT64 OldBytes, UINT64 ReduceBytes) +{ + BOOL ret; + + ret = VDS_ShrinkVolume(DriveIndex, VolumeGuid, DriveLetter, OldBytes, ReduceBytes); + if (!ret) + { + if (LASTERR == VDS_E_SHRINK_DIRTY_VOLUME) + { + Log("VDS shrink return dirty, no need to run powershell."); + } + else + { + ret = PSHELL_ShrinkVolume(DriveIndex, VolumeGuid, DriveLetter, OldBytes, ReduceBytes); + } + } + + return ret; +} + diff --git a/Ventoy2Disk/Ventoy2Disk/DiskService.h b/Ventoy2Disk/Ventoy2Disk/DiskService.h index 3ccbc999..78d6ec17 100644 --- a/Ventoy2Disk/Ventoy2Disk/DiskService.h +++ b/Ventoy2Disk/Ventoy2Disk/DiskService.h @@ -29,24 +29,39 @@ typedef struct VDS_PARA WCHAR Name[36]; ULONG NameLen; ULONGLONG Offset; + CHAR DriveLetter; }VDS_PARA; +//DISK API +BOOL DISK_CleanDisk(int DriveIndex); +BOOL DISK_DeleteVtoyEFIPartition(int DriveIndex, UINT64 EfiPartOffset); +BOOL DISK_ChangeVtoyEFIAttr(int DriveIndex, UINT64 Offset, UINT64 Attr); +BOOL DISK_ChangeVtoyEFI2ESP(int DriveIndex, UINT64 Offset); +BOOL DISK_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset); +BOOL DISK_ShrinkVolume(int DriveIndex, const char* VolumeGuid, CHAR DriveLetter, UINT64 OldBytes, UINT64 ReduceBytes); + + //VDS com -int VDS_Init(void); BOOL VDS_CleanDisk(int DriveIndex); BOOL VDS_DeleteAllPartitions(int DriveIndex); -BOOL VDS_DeleteVtoyEFIPartition(int DriveIndex); -BOOL VDS_ChangeVtoyEFIAttr(int DriveIndex, UINT64 Attr); -BOOL VDS_CreateVtoyEFIPart(int DriveIndex, UINT64 Offset); +BOOL VDS_DeleteVtoyEFIPartition(int DriveIndex, UINT64 EfiPartOffset); +BOOL VDS_ChangeVtoyEFIAttr(int DriveIndex, UINT64 Offset, UINT64 Attr); BOOL VDS_ChangeVtoyEFI2ESP(int DriveIndex, UINT64 Offset); BOOL VDS_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset); -BOOL VDS_FormatVtoyEFIPart(int DriveIndex, UINT64 Offset); -BOOL VDS_ShrinkVolume(const char* VolumeGuid, UINT64 ReduceBytes); +BOOL VDS_ShrinkVolume(int DriveIndex, const char* VolumeGuid, CHAR DriveLetter, UINT64 OldBytes, UINT64 ReduceBytes); +BOOL VDS_IsLastAvaliable(void); + //diskpart.exe BOOL DSPT_CleanDisk(int DriveIndex); +//powershell.exe +BOOL PSHELL_CleanDisk(int DriveIndex); +BOOL PSHELL_DeleteVtoyEFIPartition(int DriveIndex, UINT64 EfiPartOffset); +BOOL PSHELL_ChangeVtoyEFI2ESP(int DriveIndex, UINT64 Offset); +BOOL PSHELL_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset); +BOOL PSHELL_ShrinkVolume(int DriveIndex, const char* VolumeGuid, CHAR DriveLetter, UINT64 OldBytes, UINT64 ReduceBytes); // // Internel define diff --git a/Ventoy2Disk/Ventoy2Disk/DiskService_diskpart.c b/Ventoy2Disk/Ventoy2Disk/DiskService_diskpart.c index e7c1dafb..ca1aa815 100644 --- a/Ventoy2Disk/Ventoy2Disk/DiskService_diskpart.c +++ b/Ventoy2Disk/Ventoy2Disk/DiskService_diskpart.c @@ -64,6 +64,9 @@ STATIC BOOL DSPT_CommProc(const char *Cmd) WaitForSingleObject(Pi.hProcess, INFINITE); Log("Process finished..."); + CHECK_CLOSE_HANDLE(Pi.hProcess); + CHECK_CLOSE_HANDLE(Pi.hThread); + DeleteFileA(CmdFile); return TRUE; } diff --git a/Ventoy2Disk/Ventoy2Disk/DiskService_vds.c b/Ventoy2Disk/Ventoy2Disk/DiskService_vds.c index c53cc44a..f930559e 100644 --- a/Ventoy2Disk/Ventoy2Disk/DiskService_vds.c +++ b/Ventoy2Disk/Ventoy2Disk/DiskService_vds.c @@ -390,6 +390,10 @@ static const char *GetVdsError(DWORD error_code) return "The offline operation failed."; case 0x80042598: // VDS_E_BAD_REVISION_NUMBER return "The operation could not be completed because the specified revision number is not supported."; + case 0x80042599: // VDS_E_SHRINK_USER_CANCELLED + return "The shrink operation was cancelled by the user."; + case 0x8004259a: // VDS_E_SHRINK_DIRTY_VOLUME + return "The volume you have selected to shrink may be corrupted. Use Chkdsk to fix the corruption problem, and then try again."; case 0x00042700: // VDS_S_NAME_TRUNCATED return "The name was set successfully but had to be truncated."; case 0x80042701: // VDS_E_NAME_NOT_UNIQUE @@ -601,6 +605,13 @@ const char *WindowsErrorString(DWORD error_code) typedef BOOL(*VDS_Callback_PF)(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data); +static BOOL g_vds_available = TRUE; + +BOOL VDS_IsLastAvaliable(void) +{ + return g_vds_available; +} + STATIC IVdsService * VDS_InitService(void) { HRESULT hr; @@ -627,6 +638,7 @@ STATIC IVdsService * VDS_InitService(void) { VDS_SET_ERROR(hr); Log("Could not load VDS Service: 0x%x", LASTERR); + g_vds_available = FALSE; return NULL; } @@ -640,6 +652,7 @@ STATIC IVdsService * VDS_InitService(void) } Log("VDS init OK, service %p", pService); + g_vds_available = TRUE; return pService; } @@ -1061,16 +1074,16 @@ STATIC BOOL VDS_CallBack_DeletePartition(void *pInterface, VDS_DISK_PROP *pDiskP HRESULT hr; VDS_PARTITION_PROP* prop_array = NULL; LONG i, prop_array_size; - ULONG PartNumber = (ULONG)data; + UINT64 PartOffset = data; IVdsAdvancedDisk *pAdvancedDisk = (IVdsAdvancedDisk *)pInterface; - if (PartNumber == 0) + if (PartOffset == 0) { Log("Deleting ALL partitions from disk '%S':", pDiskProp->pwszName); } else { - Log("Deleting partition(%ld) from disk '%S':", PartNumber, pDiskProp->pwszName); + Log("Deleting partition(offset=%llu) from disk '%S':", PartOffset, pDiskProp->pwszName); } // Query the partition data, so we can get the start offset, which we need for deletion @@ -1080,7 +1093,7 @@ STATIC BOOL VDS_CallBack_DeletePartition(void *pInterface, VDS_DISK_PROP *pDiskP r = TRUE; for (i = 0; i < prop_array_size; i++) { - if (PartNumber == 0 || PartNumber == prop_array[i].ulPartitionNumber) + if (PartOffset == 0 || PartOffset == prop_array[i].ullOffset) { Log("* Partition %d (offset: %lld, size: %llu) delete it.", prop_array[i].ulPartitionNumber, prop_array[i].ullOffset, (ULONGLONG)prop_array[i].ullSize); @@ -1127,9 +1140,9 @@ BOOL VDS_DeleteAllPartitions(int DriveIndex) return ret; } -BOOL VDS_DeleteVtoyEFIPartition(int DriveIndex) +BOOL VDS_DeleteVtoyEFIPartition(int DriveIndex, UINT64 EfiPartOffset) { - BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK, DriveIndex, VDS_CallBack_DeletePartition, 2); + BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK, DriveIndex, VDS_CallBack_DeletePartition, EfiPartOffset); Log("VDS_DeleteVtoyEFIPartition %d ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL"); return ret; } @@ -1138,6 +1151,7 @@ STATIC BOOL VDS_CallBack_ChangeEFIAttr(void *pInterface, VDS_DISK_PROP *pDiskPro { BOOL r = FALSE; HRESULT hr; + VDS_PARA *VdsPara = (VDS_PARA *)data; VDS_PARTITION_PROP* prop_array = NULL; LONG i, prop_array_size; CHANGE_ATTRIBUTES_PARAMETERS AttrPara; @@ -1151,12 +1165,13 @@ STATIC BOOL VDS_CallBack_ChangeEFIAttr(void *pInterface, VDS_DISK_PROP *pDiskPro { if (prop_array[i].ullSize == VENTOY_EFI_PART_SIZE && prop_array[i].PartitionStyle == VDS_PST_GPT && - memcmp(prop_array[i].Gpt.name, L"VTOYEFI", 7 * 2) == 0) + memcmp(prop_array[i].Gpt.name, L"VTOYEFI", 7 * 2) == 0 && + VdsPara->Offset == prop_array[i].ullOffset) { - Log("* Partition %d (offset: %lld, size: %llu, Attr:0x%llx)", prop_array[i].ulPartitionNumber, + Log("** Partition %d (offset: %lld, size: %llu, Attr:0x%llx)", prop_array[i].ulPartitionNumber, prop_array[i].ullOffset, (ULONGLONG)prop_array[i].ullSize, prop_array[i].Gpt.attributes); - if (prop_array[i].Gpt.attributes == data) + if (prop_array[i].Gpt.attributes == VdsPara->Attr) { Log("Attribute match, No need to change."); r = TRUE; @@ -1164,7 +1179,7 @@ STATIC BOOL VDS_CallBack_ChangeEFIAttr(void *pInterface, VDS_DISK_PROP *pDiskPro else { AttrPara.style = VDS_PST_GPT; - AttrPara.GptPartInfo.attributes = data; + AttrPara.GptPartInfo.attributes = VdsPara->Attr; hr = IVdsAdvancedDisk_ChangeAttributes(pAdvancedDisk, prop_array[i].ullOffset, &AttrPara); if (hr == S_OK) { @@ -1191,10 +1206,15 @@ STATIC BOOL VDS_CallBack_ChangeEFIAttr(void *pInterface, VDS_DISK_PROP *pDiskPro return r; } -BOOL VDS_ChangeVtoyEFIAttr(int DriveIndex, UINT64 Attr) +BOOL VDS_ChangeVtoyEFIAttr(int DriveIndex, UINT64 Offset, UINT64 Attr) { - BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK, DriveIndex, VDS_CallBack_ChangeEFIAttr, Attr); - Log("VDS_ChangeVtoyEFIAttr %d ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL"); + VDS_PARA Para; + + Para.Attr = Attr; + Para.Offset = Offset; + + BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK, DriveIndex, VDS_CallBack_ChangeEFIAttr, (UINT64)&Para); + Log("VDS_ChangeVtoyEFIAttr %d (offset:%llu) ret:%d (%s)", DriveIndex, Offset, ret, ret ? "SUCCESS" : "FAIL"); return ret; } @@ -1238,6 +1258,7 @@ BOOL VDS_ChangeVtoyEFI2ESP(int DriveIndex, UINT64 Offset) return ret; } + BOOL VDS_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset) { VDS_PARA Para; @@ -1251,153 +1272,69 @@ BOOL VDS_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset) return ret; } - -STATIC BOOL VDS_CallBack_CreateVtoyEFI(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data) +STATIC BOOL CHKDSK_Volume(CHAR LogicalDrive) { - HRESULT hr, hr2; - ULONG completed; - IVdsAsync* pAsync; - CREATE_PARTITION_PARAMETERS para; - IVdsCreatePartitionEx *pCreatePartitionEx = (IVdsCreatePartitionEx *)pInterface; - VDS_PARA *VdsPara = (VDS_PARA *)data; + CHAR CmdBuf[1024]; + STARTUPINFOA Si; + PROCESS_INFORMATION Pi; - (void)pDiskProp; - - memset(¶, 0, sizeof(para)); - para.style = VDS_PST_GPT; - memcpy(&(para.GptPartInfo.partitionType), &VdsPara->Type, sizeof(GUID)); - memcpy(&(para.GptPartInfo.partitionId), &VdsPara->Id, sizeof(GUID)); - para.GptPartInfo.attributes = VdsPara->Attr; - memcpy(para.GptPartInfo.name, VdsPara->Name, sizeof(WCHAR)* VdsPara->NameLen); - - hr = IVdsCreatePartitionEx_CreatePartitionEx(pCreatePartitionEx, VdsPara->Offset, VENTOY_EFI_PART_SIZE, 512, ¶, &pAsync); - while (SUCCEEDED(hr)) - { - hr = IVdsAsync_QueryStatus(pAsync, &hr2, &completed); - if (SUCCEEDED(hr)) - { - hr = hr2; - if (hr == S_OK) - { - Log("Disk create partition QueryStatus OK, %lu%%", completed); - break; - } - else if (hr == VDS_E_OPERATION_PENDING) - { - Log("Disk partition finish: %lu%%", completed); - hr = S_OK; - } - else - { - Log("QueryStatus invalid status:0x%lx", hr); - } - } - Sleep(1000); - } - - if (hr != S_OK) - { - VDS_SET_ERROR(hr); - Log("Could not create partition, err:0x%lx(%s)", LASTERR, WindowsErrorString(hr)); - return FALSE; - } - - return TRUE; -} - -BOOL VDS_CreateVtoyEFIPart(int DriveIndex, UINT64 Offset) -{ - VDS_PARA Para; - GUID WindowsDataPartType = { 0xebd0a0a2, 0xb9e5, 0x4433, { 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7 } }; - GUID EspPartType = { 0xc12a7328, 0xf81f, 0x11d2, { 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } }; - - Log("VDS_CreateVtoyEFIPart %u Offset:%llu Sector:%llu", DriveIndex, Offset, Offset / 512); - - memset(&Para, 0, sizeof(Para)); - Para.Attr = 0x8000000000000000ULL; - Para.Offset = Offset; - memcpy(Para.Name, L"VTOYEFI", 7 * 2); - Para.NameLen = 7; - memcpy(&(Para.Type), &EspPartType, sizeof(GUID)); - CoCreateGuid(&(Para.Id)); - - BOOL ret = VDS_DiskCommProc(INTF_CREATEPARTITIONEX, DriveIndex, VDS_CallBack_CreateVtoyEFI, (UINT64)&Para); - Log("VDS_CreateVtoyEFIPart %d ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL"); - return ret; -} - - -STATIC BOOL VDS_CallBack_FormatVtoyEFI(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data) -{ - HRESULT hr, hr2; - ULONG completed; - IVdsAsync* pAsync; - IVdsDiskPartitionMF *pPartitionMF = (IVdsDiskPartitionMF *)pInterface; - VDS_PARA *VdsPara = (VDS_PARA *)data; - - (void)pDiskProp; - - hr = IVdsPartitionMF_FormatPartitionEx(pPartitionMF, VdsPara->Offset, L"FAT", 0x0100, 0, VdsPara->Name, TRUE, TRUE, FALSE, &pAsync); - while (SUCCEEDED(hr)) + if ((!IsFileExist("C:\\Windows\\System32\\chkdsk.exe")) || (LogicalDrive == 0)) { - hr = IVdsAsync_QueryStatus(pAsync, &hr2, &completed); - if (SUCCEEDED(hr)) - { - hr = hr2; - if (hr == S_OK) - { - Log("Disk format partition QueryStatus OK, %lu%%", completed); - break; - } - else if (hr == VDS_E_OPERATION_PENDING) - { - Log("Disk format finish: %lu%%", completed); - hr = S_OK; - } - else - { - Log("QueryStatus invalid status:0x%lx", hr); - } - } - Sleep(1000); - } - - if (hr != S_OK) - { - VDS_SET_ERROR(hr); - Log("Could not format partition, err:0x%lx (%s)", LASTERR, WindowsErrorString(hr)); return FALSE; } + GetStartupInfoA(&Si); + Si.dwFlags |= STARTF_USESHOWWINDOW; + Si.wShowWindow = SW_HIDE; + + sprintf_s(CmdBuf, sizeof(CmdBuf), "C:\\Windows\\System32\\chkdsk.exe %C: /f", LogicalDrive); + + Log("CreateProcess <%s>", CmdBuf); + CreateProcessA(NULL, CmdBuf, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi); + + Log("Wair process ..."); + WaitForSingleObject(Pi.hProcess, INFINITE); + Log("Process finished..."); + + CHECK_CLOSE_HANDLE(Pi.hProcess); + CHECK_CLOSE_HANDLE(Pi.hThread); + return TRUE; } -// Not supported for removable disk -BOOL VDS_FormatVtoyEFIPart(int DriveIndex, UINT64 Offset) -{ - VDS_PARA Para; - - memset(&Para, 0, sizeof(Para)); - Para.Offset = Offset; - memcpy(Para.Name, L"VTOYEFI", 7 * 2); - - BOOL ret = VDS_DiskCommProc(INTF_PARTITIONMF, DriveIndex, VDS_CallBack_FormatVtoyEFI, (UINT64)&Para); - Log("VDS_FormatVtoyEFIPart %d ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL"); - return ret; -} STATIC BOOL VDS_CallBack_ShrinkVolume(void* pInterface, VDS_DISK_PROP* pDiskProp, UINT64 data) { + int i; HRESULT hr, hr2; IVdsVolume* pVolume = (IVdsVolume*)pInterface; ULONG completed; IVdsAsync* pAsync; + VDS_PARA *VdsPara = (VDS_PARA *)data; (void)pDiskProp; - Log("VDS_CallBack_ShrinkVolume (%llu) ...", (ULONGLONG)data); + Log("VDS_CallBack_ShrinkVolume (%C:) (%llu) ...", VdsPara->DriveLetter, (ULONGLONG)VdsPara->Offset); - hr = IVdsVolume_Shrink(pVolume, (ULONGLONG)data, &pAsync); + hr = IVdsVolume_Shrink(pVolume, (ULONGLONG)VdsPara->Offset, &pAsync); + if (hr == VDS_E_SHRINK_DIRTY_VOLUME) + { + Log("Volume %C: is dirty, run chkdsk and retry.", VdsPara->DriveLetter); + CHKDSK_Volume(VdsPara->DriveLetter); + + hr = IVdsVolume_Shrink(pVolume, (ULONGLONG)VdsPara->Offset, &pAsync); + if (hr == VDS_E_SHRINK_DIRTY_VOLUME) + { + Log("################################################################"); + Log("################################################################"); + for (i = 0; i < 20; i++) + { + Log("###### Volume dirty, Please run \"chkdsk /f %C:\" and retry. ######", VdsPara->Name[0]); + } + Log("################################################################"); + Log("################################################################"); + } + } while (SUCCEEDED(hr)) { @@ -1427,18 +1364,24 @@ STATIC BOOL VDS_CallBack_ShrinkVolume(void* pInterface, VDS_DISK_PROP* pDiskProp { VDS_SET_ERROR(hr); Log("Could not ShrinkVolume, 0x%x err:0x%lx (%s)", hr, LASTERR, WindowsErrorString(hr)); + + VDS_SET_ERROR(hr); return FALSE; } return TRUE; } -BOOL VDS_ShrinkVolume(const char* VolumeGuid, UINT64 ReduceBytes) +BOOL VDS_ShrinkVolume(int DriveIndex, const char* VolumeGuid, CHAR DriveLetter, UINT64 OldBytes, UINT64 ReduceBytes) { int i; BOOL ret = FALSE; WCHAR wGuid[128] = { 0 }; const char *guid = NULL; + VDS_PARA Para; + + (VOID)DriveIndex; + (VOID)OldBytes; guid = strstr(VolumeGuid, "{"); if (!guid) @@ -1451,7 +1394,10 @@ BOOL VDS_ShrinkVolume(const char* VolumeGuid, UINT64 ReduceBytes) wGuid[i] = guid[i]; } - ret = VDS_VolumeCommProc(INTF_VOLUME, wGuid, VDS_CallBack_ShrinkVolume, ReduceBytes); - Log("VDS_ShrinkVolume ret:%d (%s)", ret, ret ? "SUCCESS" : "FAIL"); + Para.Offset = ReduceBytes; + Para.DriveLetter = DriveLetter; + + ret = VDS_VolumeCommProc(INTF_VOLUME, wGuid, VDS_CallBack_ShrinkVolume, (UINT64)&Para); + Log("VDS_ShrinkVolume %C: ret:%d (%s)", DriveLetter, ret, ret ? "SUCCESS" : "FAIL"); return ret; } \ No newline at end of file diff --git a/Ventoy2Disk/Ventoy2Disk/DiskService_wmsa.c b/Ventoy2Disk/Ventoy2Disk/DiskService_wmsa.c index c5af4ccc..d99e5ac1 100644 --- a/Ventoy2Disk/Ventoy2Disk/DiskService_wmsa.c +++ b/Ventoy2Disk/Ventoy2Disk/DiskService_wmsa.c @@ -23,5 +23,235 @@ #include #include #include +#include #include "Ventoy2Disk.h" #include "DiskService.h" + +STATIC BOOL IsPowershellExist(void) +{ + BOOL ret; + + if (!IsWindows8OrGreater()) + { + Log("This is before Windows8 powershell disk not supported."); + return FALSE; + } + + ret = IsFileExist("C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe"); + if (!ret) + { + Log("powershell.exe not exist"); + } + + return ret; +} + +int PSHELL_GetPartitionNumber(int PhyDrive, UINT64 Offset) +{ + int partnum = -1; + DWORD i = 0; + DWORD BufLen = 0; + DWORD dwBytes = 0; + BOOL bRet; + HANDLE hDrive; + LONGLONG PartStart; + DRIVE_LAYOUT_INFORMATION_EX *pDriveLayout = NULL; + + Log("PSHELL_GetPartitionNumber PhyDrive:%d Offset:%llu", PhyDrive, Offset); + + hDrive = GetPhysicalHandle(PhyDrive, FALSE, FALSE, FALSE); + if (hDrive == INVALID_HANDLE_VALUE) + { + return -1; + } + + BufLen = (DWORD)(sizeof(PARTITION_INFORMATION_EX)* 256); + + pDriveLayout = malloc(BufLen); + if (!pDriveLayout) + { + goto out; + } + memset(pDriveLayout, 0, BufLen); + + bRet = DeviceIoControl(hDrive, + IOCTL_DISK_GET_DRIVE_LAYOUT_EX, NULL, + 0, + pDriveLayout, + BufLen, + &dwBytes, + NULL); + if (!bRet) + { + Log("Failed to ioctrl get drive layout ex %u", LASTERR); + goto out; + } + + Log("PhyDrive:%d PartitionStyle=%s PartitionCount=%u", PhyDrive, + (pDriveLayout->PartitionStyle == PARTITION_STYLE_MBR) ? "MBR" : "GPT", pDriveLayout->PartitionCount); + + for (i = 0; i < pDriveLayout->PartitionCount; i++) + { + PartStart = pDriveLayout->PartitionEntry[i].StartingOffset.QuadPart; + if (PartStart == (LONGLONG)Offset) + { + Log("[*] [%d] PartitionNumber=%u Offset=%lld Length=%lld ", + i, + pDriveLayout->PartitionEntry[i].PartitionNumber, + pDriveLayout->PartitionEntry[i].StartingOffset.QuadPart, + pDriveLayout->PartitionEntry[i].PartitionLength.QuadPart + ); + partnum = (int)pDriveLayout->PartitionEntry[i].PartitionNumber; + } + else + { + Log("[ ] [%d] PartitionNumber=%u Offset=%lld Length=%lld ", + i, + pDriveLayout->PartitionEntry[i].PartitionNumber, + pDriveLayout->PartitionEntry[i].StartingOffset.QuadPart, + pDriveLayout->PartitionEntry[i].PartitionLength.QuadPart + ); + } + } + +out: + + CHECK_CLOSE_HANDLE(hDrive); + CHECK_FREE(pDriveLayout); + + return partnum; +} + + +STATIC BOOL PSHELL_CommProc(const char *Cmd) +{ + CHAR CmdBuf[4096]; + STARTUPINFOA Si; + PROCESS_INFORMATION Pi; + + if (!IsPowershellExist()) + { + return FALSE; + } + + GetStartupInfoA(&Si); + Si.dwFlags |= STARTF_USESHOWWINDOW; + Si.wShowWindow = SW_HIDE; + + sprintf_s(CmdBuf, sizeof(CmdBuf), "C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe -Command \"&{ %s }\"", Cmd); + + Log("CreateProcess <%s>", CmdBuf); + CreateProcessA(NULL, CmdBuf, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi); + + Log("Wair process ..."); + WaitForSingleObject(Pi.hProcess, INFINITE); + Log("Process finished..."); + + CHECK_CLOSE_HANDLE(Pi.hProcess); + CHECK_CLOSE_HANDLE(Pi.hThread); + + return TRUE; +} + + +BOOL PSHELL_CleanDisk(int DriveIndex) +{ + BOOL ret; + CHAR CmdBuf[512]; + + sprintf_s(CmdBuf, sizeof(CmdBuf), "Clear-Disk -Number %d -RemoveData -RemoveOEM -Confirm:$false", DriveIndex); + ret = PSHELL_CommProc(CmdBuf); + Log("CleanDiskByPowershell<%d> ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL"); + + return ret; +} + + +BOOL PSHELL_DeleteVtoyEFIPartition(int DriveIndex, UINT64 EfiPartOffset) +{ + int Part; + BOOL ret; + CHAR CmdBuf[512]; + + Part = PSHELL_GetPartitionNumber(DriveIndex, EfiPartOffset); + if (Part < 0) + { + ret = FALSE; + } + else + { + sprintf_s(CmdBuf, sizeof(CmdBuf), "Remove-Partition -DiskNumber %d -PartitionNumber %d -Confirm:$false", DriveIndex, Part); + ret = PSHELL_CommProc(CmdBuf); + } + + Log("PSHELL_DeleteVtoyEFIPartition<%d> ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL"); + return ret; +} + + +BOOL PSHELL_ChangeVtoyEFI2ESP(int DriveIndex, UINT64 Offset) +{ + int Part; + BOOL ret; + CHAR CmdBuf[512]; + + Part = PSHELL_GetPartitionNumber(DriveIndex, Offset); + if (Part < 0) + { + ret = FALSE; + } + else + { + sprintf_s(CmdBuf, sizeof(CmdBuf), "Set-Partition -DiskNumber %d -PartitionNumber %d -gpttype '{C12A7328-F81F-11D2-BA4B-00A0C93EC93B}' -Confirm:$false", DriveIndex, Part); + ret = PSHELL_CommProc(CmdBuf); + } + + Log("PSHELL_ChangeVtoyEFI2ESP<%d> ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL"); + return ret; +} + + +BOOL PSHELL_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset) +{ + int Part; + BOOL ret; + CHAR CmdBuf[512]; + + Part = PSHELL_GetPartitionNumber(DriveIndex, Offset); + if (Part < 0) + { + ret = FALSE; + } + else + { + sprintf_s(CmdBuf, sizeof(CmdBuf), "Set-Partition -DiskNumber %d -PartitionNumber %d -gpttype '{ebd0a0a2-b9e5-4433-87c0-68b6b72699c7}' -Confirm:$false", DriveIndex, Part); + ret = PSHELL_CommProc(CmdBuf); + } + + Log("PSHELL_ChangeVtoyEFI2Basic<%d> ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL"); + return ret; +} + +BOOL PSHELL_ShrinkVolume(int DriveIndex, const char* VolumeGuid, CHAR DriveLetter, UINT64 OldBytes, UINT64 ReduceBytes) +{ + int Part; + BOOL ret; + CHAR CmdBuf[512]; + + (void)VolumeGuid; + + Part = PSHELL_GetPartitionNumber(DriveIndex, SIZE_1MB); + if (Part < 0) + { + ret = FALSE; + } + else + { + sprintf_s(CmdBuf, sizeof(CmdBuf), "Resize-Partition -DiskNumber %d -PartitionNumber %d -Size %llu -Confirm:$false", + DriveIndex, Part, OldBytes - ReduceBytes); + ret = PSHELL_CommProc(CmdBuf); + } + + Log("PSHELL_ShrinkVolume<%d> %C: ret:%d (%s)", DriveIndex, DriveLetter, ret, ret ? "SUCCESS" : "FAIL"); + return ret; +} diff --git a/Ventoy2Disk/Ventoy2Disk/PhyDrive.c b/Ventoy2Disk/Ventoy2Disk/PhyDrive.c index 182a718e..b079eb18 100644 --- a/Ventoy2Disk/Ventoy2Disk/PhyDrive.c +++ b/Ventoy2Disk/Ventoy2Disk/PhyDrive.c @@ -1127,9 +1127,17 @@ static int FormatPart1exFAT(UINT64 DiskSizeBytes) Log("Formatting Part1 exFAT ..."); + disk_io_reset_write_error(); + Ret = f_mkfs(TEXT("0:"), &Option, 0, 8 * 1024 * 1024); if (FR_OK == Ret) { + if (disk_io_is_write_error()) + { + Log("Formatting Part1 exFAT failed, write error."); + return 1; + } + Log("Formatting Part1 exFAT success"); return 0; } @@ -1851,7 +1859,18 @@ End: } else { + PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN); + FindProcessOccupyDisk(hDrive, pPhyDrive); + + if (!VDS_IsLastAvaliable()) + { + Log("###### [Error:] Virtual Disk Service (VDS) Unavailable ######"); + Log("###### [Error:] Virtual Disk Service (VDS) Unavailable ######"); + Log("###### [Error:] Virtual Disk Service (VDS) Unavailable ######"); + Log("###### [Error:] Virtual Disk Service (VDS) Unavailable ######"); + Log("###### [Error:] Virtual Disk Service (VDS) Unavailable ######"); + } } if (pGptInfo) @@ -1917,7 +1936,7 @@ int PartitionResizeForVentoy(PHY_DRIVE_INFO *pPhyDrive) if (pPhyDrive->ResizeNoShrink == FALSE) { Log("Need to shrink the volume"); - if (VDS_ShrinkVolume(pPhyDrive->ResizeVolumeGuid, RecudeBytes)) + if (DISK_ShrinkVolume(pPhyDrive->PhyDrive, pPhyDrive->ResizeVolumeGuid, pPhyDrive->Part1DriveLetter, pPhyDrive->ResizeOldPart1Size, RecudeBytes)) { Log("Shrink volume success, now check again"); @@ -2011,6 +2030,7 @@ int PartitionResizeForVentoy(PHY_DRIVE_INFO *pPhyDrive) memcpy(pMBR->PartTbl + (j + 1), pMBR->PartTbl + j, sizeof(PART_TABLE)); } + memset(pMBR->PartTbl + 1, 0, sizeof(PART_TABLE)); VentoyFillMBRLocation(pPhyDrive->SizeInBytes, (UINT32)pPhyDrive->ResizePart2StartSector, VENTOY_EFI_PART_SIZE / 512, pMBR->PartTbl + 1); pMBR->PartTbl[0].Active = 0x80; // bootable pMBR->PartTbl[1].Active = 0x00; @@ -2048,6 +2068,7 @@ int PartitionResizeForVentoy(PHY_DRIVE_INFO *pPhyDrive) pMBR->BootCode[92] = 0x22; // to fix windows issue + memset(pGPT->PartTbl + 1, 0, sizeof(VTOY_GPT_PART_TBL)); memcpy(&(pGPT->PartTbl[1].PartType), &WindowsDataPartType, sizeof(GUID)); CoCreateGuid(&(pGPT->PartTbl[1].PartGuid)); @@ -2058,6 +2079,7 @@ int PartitionResizeForVentoy(PHY_DRIVE_INFO *pPhyDrive) //Update CRC pGPT->Head.PartTblCrc = VentoyCrc32(pGPT->PartTbl, sizeof(pGPT->PartTbl)); + pGPT->Head.Crc = 0; pGPT->Head.Crc = VentoyCrc32(&(pGPT->Head), pGPT->Head.Length); Log("pGPT->Head.EfiStartLBA=%llu", (ULONGLONG)pGPT->Head.EfiStartLBA); @@ -2320,6 +2342,7 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId) BOOL Esp2Basic = FALSE; BOOL ChangeAttr = FALSE; BOOL CleanDisk = FALSE; + BOOL DelEFI = FALSE; BOOL bWriteBack = TRUE; HANDLE hVolume; HANDLE hDrive; @@ -2335,6 +2358,7 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId) MBR_HEAD MBR; BYTE *pBackup = NULL; VTOY_GPT_INFO *pGptInfo = NULL; + VTOY_GPT_INFO *pGptBkup = NULL; UINT8 ReservedData[4096]; Log("#####################################################"); @@ -2356,17 +2380,19 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId) if (pPhyDrive->PartStyle) { - pGptInfo = malloc(sizeof(VTOY_GPT_INFO)); + pGptInfo = malloc(2 * sizeof(VTOY_GPT_INFO)); if (!pGptInfo) { return 1; } - memset(pGptInfo, 0, sizeof(VTOY_GPT_INFO)); + memset(pGptInfo, 0, 2 * sizeof(VTOY_GPT_INFO)); + pGptBkup = pGptInfo + 1; // Read GPT Info SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); ReadFile(hDrive, pGptInfo, sizeof(VTOY_GPT_INFO), &dwSize, NULL); + memcpy(pGptBkup, pGptInfo, sizeof(VTOY_GPT_INFO)); //MBR will be used to compare with local boot image memcpy(&MBR, &pGptInfo->MBR, sizeof(MBR_HEAD)); @@ -2430,7 +2456,7 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId) if (TryId == 1) { Log("Change GPT partition type to ESP"); - if (VDS_ChangeVtoyEFI2ESP(pPhyDrive->PhyDrive, StartSector * 512)) + if (DISK_ChangeVtoyEFI2ESP(pPhyDrive->PhyDrive, StartSector * 512ULL)) { Esp2Basic = TRUE; Sleep(3000); @@ -2439,13 +2465,18 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId) else if (TryId == 2) { Log("Change GPT partition attribute"); - if (VDS_ChangeVtoyEFIAttr(pPhyDrive->PhyDrive, 0x8000000000000001)) + if (DISK_ChangeVtoyEFIAttr(pPhyDrive->PhyDrive, StartSector * 512ULL, 0x8000000000000001)) { ChangeAttr = TRUE; Sleep(2000); } } else if (TryId == 3) + { + DISK_DeleteVtoyEFIPartition(pPhyDrive->PhyDrive, StartSector * 512ULL); + DelEFI = TRUE; + } + else if (TryId == 4) { Log("Clean disk GPT partition table"); if (BackupDataBeforeCleanDisk(pPhyDrive->PhyDrive, pPhyDrive->SizeInBytes, &pBackup)) @@ -2457,11 +2488,7 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId) Log("Success to backup data before clean"); CleanDisk = TRUE; - if (!VDS_CleanDisk(pPhyDrive->PhyDrive)) - { - Sleep(3000); - DSPT_CleanDisk(pPhyDrive->PhyDrive); - } + DISK_CleanDisk(pPhyDrive->PhyDrive); Sleep(3000); } else @@ -2504,6 +2531,10 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId) Status = ERROR_NOT_FOUND; } + else if (DelEFI) + { + Status = ERROR_NOT_FOUND; + } else if (Esp2Basic) { Status = ERROR_NOT_FOUND; @@ -2595,7 +2626,7 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId) CHECK_CLOSE_HANDLE(hDrive); Log("Now delete partition 2..."); - VDS_DeleteVtoyEFIPartition(pPhyDrive->PhyDrive); + DISK_DeleteVtoyEFIPartition(pPhyDrive->PhyDrive, StartSector * 512ULL); hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, TRUE, FALSE); if (hDrive == INVALID_HANDLE_VALUE) @@ -2707,6 +2738,37 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId) Sleep(1000); } + else if (DelEFI) + { + VTOY_GPT_HDR BackupHdr; + + VentoyFillBackupGptHead(pGptBkup, &BackupHdr); + if (!WriteBackupDataToDisk(hDrive, 512 * pGptBkup->Head.EfiBackupLBA, (BYTE*)(&BackupHdr), 512)) + { + bWriteBack = FALSE; + } + + if (!WriteBackupDataToDisk(hDrive, 512 * (pGptBkup->Head.EfiBackupLBA - 32), (BYTE*)(pGptBkup->PartTbl), 32 * 512)) + { + bWriteBack = FALSE; + } + + if (!WriteBackupDataToDisk(hDrive, 512, (BYTE*)pGptBkup + 512, 33 * 512)) + { + bWriteBack = FALSE; + } + + if (bWriteBack) + { + Log("Write backup partition table success"); + } + else + { + Log("Write backup partition table failed"); + } + + Sleep(1000); + } //Refresh Drive Layout DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL); @@ -2726,6 +2788,7 @@ End: } else { + PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN); FindProcessOccupyDisk(hDrive, pPhyDrive); } @@ -2734,7 +2797,7 @@ End: if (Esp2Basic) { Log("Recover GPT partition type to basic"); - VDS_ChangeVtoyEFI2Basic(pPhyDrive->PhyDrive, StartSector * 512); + DISK_ChangeVtoyEFI2Basic(pPhyDrive->PhyDrive, StartSector * 512); } if (pPhyDrive->PartStyle == 1) @@ -2742,7 +2805,7 @@ End: if (ChangeAttr || ((pPhyDrive->Part2GPTAttr >> 56) != 0xC0)) { Log("Change EFI partition attr %u <0x%llx> to <0x%llx>", ChangeAttr, pPhyDrive->Part2GPTAttr, 0xC000000000000001ULL); - if (VDS_ChangeVtoyEFIAttr(pPhyDrive->PhyDrive, 0xC000000000000001ULL)) + if (DISK_ChangeVtoyEFIAttr(pPhyDrive->PhyDrive, StartSector * 512ULL, 0xC000000000000001ULL)) { Log("Change EFI partition attr success"); pPhyDrive->Part2GPTAttr = 0xC000000000000001ULL; diff --git a/Ventoy2Disk/Ventoy2Disk/Utility.c b/Ventoy2Disk/Ventoy2Disk/Utility.c index d2d31887..f217bfed 100644 --- a/Ventoy2Disk/Ventoy2Disk/Utility.c +++ b/Ventoy2Disk/Ventoy2Disk/Utility.c @@ -73,6 +73,17 @@ void Log(const char *Fmt, ...) } +const char* GUID2String(void *guid, char *buf, int len) +{ + GUID* pGUID = (GUID*)guid; + sprintf_s(buf, len, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + pGUID->Data1, pGUID->Data2, pGUID->Data3, + pGUID->Data4[0], pGUID->Data4[1], + pGUID->Data4[2], pGUID->Data4[3], pGUID->Data4[4], pGUID->Data4[5], pGUID->Data4[6], pGUID->Data4[7] + ); + return buf; +} + BOOL IsPathExist(BOOL Dir, const char *Fmt, ...) { va_list Arg; @@ -231,6 +242,7 @@ BOOL IsWow64(void) typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS)(HANDLE, PBOOL); LPFN_ISWOW64PROCESS fnIsWow64Process; BOOL bIsWow64 = FALSE; + CHAR Wow64Dir[MAX_PATH]; fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandleA("kernel32"), "IsWow64Process"); if (NULL != fnIsWow64Process) @@ -238,6 +250,15 @@ BOOL IsWow64(void) fnIsWow64Process(GetCurrentProcess(), &bIsWow64); } + if (!bIsWow64) + { + if (GetSystemWow64DirectoryA(Wow64Dir, sizeof(Wow64Dir))) + { + Log("GetSystemWow64DirectoryA=<%s>", Wow64Dir); + bIsWow64 = TRUE; + } + } + return bIsWow64; } diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c index 2f7d2334..4c6f6096 100644 --- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c +++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c @@ -81,6 +81,8 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UIN UINT32 PartStartSector; UINT32 PartSectorCount; CHAR PhyDrivePath[128]; + CHAR GUIDStr[128]; + GUID ZeroGuid = { 0 }; VTOY_GPT_INFO *pGpt = NULL; safe_sprintf(PhyDrivePath, "\\\\.\\PhysicalDrive%d", PhyDrive); @@ -108,20 +110,7 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UIN return FALSE; } - for (i = 0; i < 4; i++) - { - Log("=========== Disk%d Partition Table %d ============", PhyDrive, i + 1); - Log("PartTbl.Active = 0x%x", MBR.PartTbl[i].Active); - Log("PartTbl.FsFlag = 0x%x", MBR.PartTbl[i].FsFlag); - Log("PartTbl.StartSectorId = %u", MBR.PartTbl[i].StartSectorId); - Log("PartTbl.SectorCount = %u", MBR.PartTbl[i].SectorCount); - Log("PartTbl.StartHead = %u", MBR.PartTbl[i].StartHead); - Log("PartTbl.StartSector = %u", MBR.PartTbl[i].StartSector); - Log("PartTbl.StartCylinder = %u", MBR.PartTbl[i].StartCylinder); - Log("PartTbl.EndHead = %u", MBR.PartTbl[i].EndHead); - Log("PartTbl.EndSector = %u", MBR.PartTbl[i].EndSector); - Log("PartTbl.EndCylinder = %u", MBR.PartTbl[i].EndCylinder); - } + if (MBR.PartTbl[0].FsFlag == 0xEE) { @@ -147,6 +136,23 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UIN return FALSE; } + for (i = 0; i < 128; i++) + { + if (memcmp(&(pGpt->PartTbl[i].PartGuid), &ZeroGuid, sizeof(GUID)) == 0) + { + continue; + } + + Log("=========== Disk%d GPT Partition %d ============", PhyDrive, i + 1); + + Log("PartTbl.PartType = %s", GUID2String(&pGpt->PartTbl[i].PartType, GUIDStr, sizeof(GUIDStr))); + Log("PartTbl.PartGuid = %s", GUID2String(&pGpt->PartTbl[i].PartGuid, GUIDStr, sizeof(GUIDStr))); + Log("PartTbl.StartLBA = %llu", (ULONGLONG)pGpt->PartTbl[i].StartLBA); + Log("PartTbl.LastLBA = %llu", (ULONGLONG)pGpt->PartTbl[i].LastLBA); + Log("PartTbl.Attribute = 0x%llx", pGpt->PartTbl[i].Attr); + Log("PartTbl.Name = %S", pGpt->PartTbl[i].Name); + } + if (memcmp(pGpt->PartTbl[1].Name, L"VTOYEFI", 7 * 2)) { if (pGpt->PartTbl[1].Name[0]) @@ -187,6 +193,21 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UIN { CHECK_CLOSE_HANDLE(hDrive); + for (i = 0; i < 4; i++) + { + Log("=========== Disk%d MBR Partition %d ============", PhyDrive, i + 1); + Log("PartTbl.Active = 0x%x", MBR.PartTbl[i].Active); + Log("PartTbl.FsFlag = 0x%x", MBR.PartTbl[i].FsFlag); + Log("PartTbl.StartSectorId = %u", MBR.PartTbl[i].StartSectorId); + Log("PartTbl.SectorCount = %u", MBR.PartTbl[i].SectorCount); + Log("PartTbl.StartHead = %u", MBR.PartTbl[i].StartHead); + Log("PartTbl.StartSector = %u", MBR.PartTbl[i].StartSector); + Log("PartTbl.StartCylinder = %u", MBR.PartTbl[i].StartCylinder); + Log("PartTbl.EndHead = %u", MBR.PartTbl[i].EndHead); + Log("PartTbl.EndSector = %u", MBR.PartTbl[i].EndSector); + Log("PartTbl.EndCylinder = %u", MBR.PartTbl[i].EndCylinder); + } + if (MBR.PartTbl[0].StartSectorId != 2048) { Log("Part1 not match %u", MBR.PartTbl[0].StartSectorId); diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h index fedcd0ba..daf8c3c4 100644 --- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h +++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h @@ -167,6 +167,8 @@ typedef struct PHY_DRIVE_INFO UINT64 Part2GPTAttr; BOOL ResizeNoShrink; + UINT64 ResizeOldPart1Size; + CHAR Part1DriveLetter; CHAR ResizeVolumeGuid[64]; CHAR FsName[64]; UINT64 ResizePart2StartSector; @@ -319,6 +321,9 @@ void disk_io_reset_imghook(int *psegnum, UINT64 *pDataOffset); HANDLE GetPhysicalHandle(int Drive, BOOLEAN bLockDrive, BOOLEAN bWriteAccess, BOOLEAN bWriteShare); void InitComboxCtrl(HWND hWnd, int PhyDrive); +int disk_io_is_write_error(void); +void disk_io_reset_write_error(void); +const char* GUID2String(void* guid, char* buf, int len); #define VTSI_SUPPORT 1 diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj index ee03fa5e..45bb839e 100644 --- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj +++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj @@ -335,6 +335,7 @@ + diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters index 2be3bb28..410ec23f 100644 --- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters +++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters @@ -90,6 +90,9 @@ 源文件 + + 源文件 + diff --git a/Ventoy2Disk/Ventoy2Disk/WinDialog.c b/Ventoy2Disk/Ventoy2Disk/WinDialog.c index 9cebd76c..86277baa 100644 Binary files a/Ventoy2Disk/Ventoy2Disk/WinDialog.c and b/Ventoy2Disk/Ventoy2Disk/WinDialog.c differ diff --git a/Ventoy2Disk/Ventoy2Disk/ff14/source/diskio.c b/Ventoy2Disk/Ventoy2Disk/ff14/source/diskio.c index 2a8c5b38..d45df97d 100644 --- a/Ventoy2Disk/Ventoy2Disk/ff14/source/diskio.c +++ b/Ventoy2Disk/Ventoy2Disk/ff14/source/diskio.c @@ -30,6 +30,20 @@ VTSI_SEGMENT *g_VentoySegment = NULL; int g_VentoyMaxSeg = 0; int g_VentoyCurSeg = -1; UINT64 g_VentoyDataOffset = 0; +int g_write_error = 0; +int g_error_print_cnt = 0; + +void disk_io_reset_write_error(void) +{ + g_write_error = 0; + g_error_print_cnt = 0; +} + + +int disk_io_is_write_error(void) +{ + return g_write_error; +} void disk_io_set_param(HANDLE Handle, UINT64 SectorCount) { @@ -248,9 +262,15 @@ DRESULT disk_write ( bRet = WriteFile(g_hPhyDrive, buff, count * 512, &dwSize, NULL); - if (dwSize != count * 512) + if ((!bRet) || (dwSize != count * 512)) { - Log("WriteFile error bRet:%u WriteSize:%u dwSize:%u ErrCode:%u", bRet, count * 512, dwSize, GetLastError()); + g_write_error = 1; + g_error_print_cnt++; + + if (g_error_print_cnt <= 10) + { + Log("WriteFile error bRet:%u WriteSize:%u dwSize:%u ErrCode:%u", bRet, count * 512, dwSize, GetLastError()); + } } return RES_OK;