1. Fix some bugs when do update after non-destructive installation.

2. Call chkdsk to fix the volume before shrink.
This commit is contained in:
longpanda 2021-11-13 19:52:42 +08:00
parent b0568922d2
commit 0891e34d47
18 changed files with 626 additions and 178 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -76,6 +76,11 @@ else
terminal_output console terminal_output console
chainloader /EFI/Microsoft/Boot/bootmgfw.efi chainloader /EFI/Microsoft/Boot/bootmgfw.efi
boot 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 fi
else else
break break
@ -87,6 +92,10 @@ else
terminal_output console terminal_output console
chainloader /EFI/Microsoft/Boot/bootmgfw.efi chainloader /EFI/Microsoft/Boot/bootmgfw.efi
boot boot
elif search -n -s -f /efi/Microsoft/Boot/bootmgfw.efi; then
terminal_output console
chainloader /efi/Microsoft/Boot/bootmgfw.efi
boot
else else
echo "Windows NOT found ..." echo "Windows NOT found ..."
fi fi

View file

@ -0,0 +1,111 @@
/******************************************************************************
* DiskService.c
*
* Copyright (c) 2021, longpanda <admin@ventoy.net>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include <Windows.h>
#include <winternl.h>
#include <commctrl.h>
#include <initguid.h>
#include <vds.h>
#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;
}

View file

@ -29,24 +29,39 @@ typedef struct VDS_PARA
WCHAR Name[36]; WCHAR Name[36];
ULONG NameLen; ULONG NameLen;
ULONGLONG Offset; ULONGLONG Offset;
CHAR DriveLetter;
}VDS_PARA; }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 //VDS com
int VDS_Init(void);
BOOL VDS_CleanDisk(int DriveIndex); BOOL VDS_CleanDisk(int DriveIndex);
BOOL VDS_DeleteAllPartitions(int DriveIndex); BOOL VDS_DeleteAllPartitions(int DriveIndex);
BOOL VDS_DeleteVtoyEFIPartition(int DriveIndex); BOOL VDS_DeleteVtoyEFIPartition(int DriveIndex, UINT64 EfiPartOffset);
BOOL VDS_ChangeVtoyEFIAttr(int DriveIndex, UINT64 Attr); BOOL VDS_ChangeVtoyEFIAttr(int DriveIndex, UINT64 Offset, UINT64 Attr);
BOOL VDS_CreateVtoyEFIPart(int DriveIndex, UINT64 Offset);
BOOL VDS_ChangeVtoyEFI2ESP(int DriveIndex, UINT64 Offset); BOOL VDS_ChangeVtoyEFI2ESP(int DriveIndex, UINT64 Offset);
BOOL VDS_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset); BOOL VDS_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset);
BOOL VDS_FormatVtoyEFIPart(int DriveIndex, UINT64 Offset); BOOL VDS_ShrinkVolume(int DriveIndex, const char* VolumeGuid, CHAR DriveLetter, UINT64 OldBytes, UINT64 ReduceBytes);
BOOL VDS_ShrinkVolume(const char* VolumeGuid, UINT64 ReduceBytes); BOOL VDS_IsLastAvaliable(void);
//diskpart.exe //diskpart.exe
BOOL DSPT_CleanDisk(int DriveIndex); 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 // Internel define

View file

@ -64,6 +64,9 @@ STATIC BOOL DSPT_CommProc(const char *Cmd)
WaitForSingleObject(Pi.hProcess, INFINITE); WaitForSingleObject(Pi.hProcess, INFINITE);
Log("Process finished..."); Log("Process finished...");
CHECK_CLOSE_HANDLE(Pi.hProcess);
CHECK_CLOSE_HANDLE(Pi.hThread);
DeleteFileA(CmdFile); DeleteFileA(CmdFile);
return TRUE; return TRUE;
} }

View file

@ -390,6 +390,10 @@ static const char *GetVdsError(DWORD error_code)
return "The offline operation failed."; return "The offline operation failed.";
case 0x80042598: // VDS_E_BAD_REVISION_NUMBER case 0x80042598: // VDS_E_BAD_REVISION_NUMBER
return "The operation could not be completed because the specified revision number is not supported."; 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 case 0x00042700: // VDS_S_NAME_TRUNCATED
return "The name was set successfully but had to be truncated."; return "The name was set successfully but had to be truncated.";
case 0x80042701: // VDS_E_NAME_NOT_UNIQUE 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); 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) STATIC IVdsService * VDS_InitService(void)
{ {
HRESULT hr; HRESULT hr;
@ -627,6 +638,7 @@ STATIC IVdsService * VDS_InitService(void)
{ {
VDS_SET_ERROR(hr); VDS_SET_ERROR(hr);
Log("Could not load VDS Service: 0x%x", LASTERR); Log("Could not load VDS Service: 0x%x", LASTERR);
g_vds_available = FALSE;
return NULL; return NULL;
} }
@ -640,6 +652,7 @@ STATIC IVdsService * VDS_InitService(void)
} }
Log("VDS init OK, service %p", pService); Log("VDS init OK, service %p", pService);
g_vds_available = TRUE;
return pService; return pService;
} }
@ -1061,16 +1074,16 @@ STATIC BOOL VDS_CallBack_DeletePartition(void *pInterface, VDS_DISK_PROP *pDiskP
HRESULT hr; HRESULT hr;
VDS_PARTITION_PROP* prop_array = NULL; VDS_PARTITION_PROP* prop_array = NULL;
LONG i, prop_array_size; LONG i, prop_array_size;
ULONG PartNumber = (ULONG)data; UINT64 PartOffset = data;
IVdsAdvancedDisk *pAdvancedDisk = (IVdsAdvancedDisk *)pInterface; IVdsAdvancedDisk *pAdvancedDisk = (IVdsAdvancedDisk *)pInterface;
if (PartNumber == 0) if (PartOffset == 0)
{ {
Log("Deleting ALL partitions from disk '%S':", pDiskProp->pwszName); Log("Deleting ALL partitions from disk '%S':", pDiskProp->pwszName);
} }
else 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 // 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; r = TRUE;
for (i = 0; i < prop_array_size; i++) 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.", Log("* Partition %d (offset: %lld, size: %llu) delete it.",
prop_array[i].ulPartitionNumber, prop_array[i].ullOffset, (ULONGLONG)prop_array[i].ullSize); prop_array[i].ulPartitionNumber, prop_array[i].ullOffset, (ULONGLONG)prop_array[i].ullSize);
@ -1127,9 +1140,9 @@ BOOL VDS_DeleteAllPartitions(int DriveIndex)
return ret; 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"); Log("VDS_DeleteVtoyEFIPartition %d ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL");
return ret; return ret;
} }
@ -1138,6 +1151,7 @@ STATIC BOOL VDS_CallBack_ChangeEFIAttr(void *pInterface, VDS_DISK_PROP *pDiskPro
{ {
BOOL r = FALSE; BOOL r = FALSE;
HRESULT hr; HRESULT hr;
VDS_PARA *VdsPara = (VDS_PARA *)data;
VDS_PARTITION_PROP* prop_array = NULL; VDS_PARTITION_PROP* prop_array = NULL;
LONG i, prop_array_size; LONG i, prop_array_size;
CHANGE_ATTRIBUTES_PARAMETERS AttrPara; 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 && if (prop_array[i].ullSize == VENTOY_EFI_PART_SIZE &&
prop_array[i].PartitionStyle == VDS_PST_GPT && 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); 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."); Log("Attribute match, No need to change.");
r = TRUE; r = TRUE;
@ -1164,7 +1179,7 @@ STATIC BOOL VDS_CallBack_ChangeEFIAttr(void *pInterface, VDS_DISK_PROP *pDiskPro
else else
{ {
AttrPara.style = VDS_PST_GPT; AttrPara.style = VDS_PST_GPT;
AttrPara.GptPartInfo.attributes = data; AttrPara.GptPartInfo.attributes = VdsPara->Attr;
hr = IVdsAdvancedDisk_ChangeAttributes(pAdvancedDisk, prop_array[i].ullOffset, &AttrPara); hr = IVdsAdvancedDisk_ChangeAttributes(pAdvancedDisk, prop_array[i].ullOffset, &AttrPara);
if (hr == S_OK) if (hr == S_OK)
{ {
@ -1191,10 +1206,15 @@ STATIC BOOL VDS_CallBack_ChangeEFIAttr(void *pInterface, VDS_DISK_PROP *pDiskPro
return r; 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); VDS_PARA Para;
Log("VDS_ChangeVtoyEFIAttr %d ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL");
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; return ret;
} }
@ -1238,6 +1258,7 @@ BOOL VDS_ChangeVtoyEFI2ESP(int DriveIndex, UINT64 Offset)
return ret; return ret;
} }
BOOL VDS_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset) BOOL VDS_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset)
{ {
VDS_PARA Para; VDS_PARA Para;
@ -1251,153 +1272,69 @@ BOOL VDS_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset)
return ret; return ret;
} }
STATIC BOOL CHKDSK_Volume(CHAR LogicalDrive)
STATIC BOOL VDS_CallBack_CreateVtoyEFI(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data)
{ {
HRESULT hr, hr2; CHAR CmdBuf[1024];
ULONG completed; STARTUPINFOA Si;
IVdsAsync* pAsync; PROCESS_INFORMATION Pi;
CREATE_PARTITION_PARAMETERS para;
IVdsCreatePartitionEx *pCreatePartitionEx = (IVdsCreatePartitionEx *)pInterface;
VDS_PARA *VdsPara = (VDS_PARA *)data;
(void)pDiskProp; if ((!IsFileExist("C:\\Windows\\System32\\chkdsk.exe")) || (LogicalDrive == 0))
memset(&para, 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, &para, &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))
{ {
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; 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; 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) STATIC BOOL VDS_CallBack_ShrinkVolume(void* pInterface, VDS_DISK_PROP* pDiskProp, UINT64 data)
{ {
int i;
HRESULT hr, hr2; HRESULT hr, hr2;
IVdsVolume* pVolume = (IVdsVolume*)pInterface; IVdsVolume* pVolume = (IVdsVolume*)pInterface;
ULONG completed; ULONG completed;
IVdsAsync* pAsync; IVdsAsync* pAsync;
VDS_PARA *VdsPara = (VDS_PARA *)data;
(void)pDiskProp; (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)) while (SUCCEEDED(hr))
{ {
@ -1427,18 +1364,24 @@ STATIC BOOL VDS_CallBack_ShrinkVolume(void* pInterface, VDS_DISK_PROP* pDiskProp
{ {
VDS_SET_ERROR(hr); VDS_SET_ERROR(hr);
Log("Could not ShrinkVolume, 0x%x err:0x%lx (%s)", hr, LASTERR, WindowsErrorString(hr)); Log("Could not ShrinkVolume, 0x%x err:0x%lx (%s)", hr, LASTERR, WindowsErrorString(hr));
VDS_SET_ERROR(hr);
return FALSE; return FALSE;
} }
return TRUE; 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; int i;
BOOL ret = FALSE; BOOL ret = FALSE;
WCHAR wGuid[128] = { 0 }; WCHAR wGuid[128] = { 0 };
const char *guid = NULL; const char *guid = NULL;
VDS_PARA Para;
(VOID)DriveIndex;
(VOID)OldBytes;
guid = strstr(VolumeGuid, "{"); guid = strstr(VolumeGuid, "{");
if (!guid) if (!guid)
@ -1451,7 +1394,10 @@ BOOL VDS_ShrinkVolume(const char* VolumeGuid, UINT64 ReduceBytes)
wGuid[i] = guid[i]; wGuid[i] = guid[i];
} }
ret = VDS_VolumeCommProc(INTF_VOLUME, wGuid, VDS_CallBack_ShrinkVolume, ReduceBytes); Para.Offset = ReduceBytes;
Log("VDS_ShrinkVolume ret:%d (%s)", ret, ret ? "SUCCESS" : "FAIL"); 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; return ret;
} }

View file

@ -23,5 +23,235 @@
#include <commctrl.h> #include <commctrl.h>
#include <initguid.h> #include <initguid.h>
#include <vds.h> #include <vds.h>
#include <VersionHelpers.h>
#include "Ventoy2Disk.h" #include "Ventoy2Disk.h"
#include "DiskService.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;
}

View file

@ -1127,9 +1127,17 @@ static int FormatPart1exFAT(UINT64 DiskSizeBytes)
Log("Formatting Part1 exFAT ..."); Log("Formatting Part1 exFAT ...");
disk_io_reset_write_error();
Ret = f_mkfs(TEXT("0:"), &Option, 0, 8 * 1024 * 1024); Ret = f_mkfs(TEXT("0:"), &Option, 0, 8 * 1024 * 1024);
if (FR_OK == Ret) if (FR_OK == Ret)
{ {
if (disk_io_is_write_error())
{
Log("Formatting Part1 exFAT failed, write error.");
return 1;
}
Log("Formatting Part1 exFAT success"); Log("Formatting Part1 exFAT success");
return 0; return 0;
} }
@ -1851,7 +1859,18 @@ End:
} }
else else
{ {
PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN);
FindProcessOccupyDisk(hDrive, pPhyDrive); 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) if (pGptInfo)
@ -1917,7 +1936,7 @@ int PartitionResizeForVentoy(PHY_DRIVE_INFO *pPhyDrive)
if (pPhyDrive->ResizeNoShrink == FALSE) if (pPhyDrive->ResizeNoShrink == FALSE)
{ {
Log("Need to shrink the volume"); 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"); 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)); 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); VentoyFillMBRLocation(pPhyDrive->SizeInBytes, (UINT32)pPhyDrive->ResizePart2StartSector, VENTOY_EFI_PART_SIZE / 512, pMBR->PartTbl + 1);
pMBR->PartTbl[0].Active = 0x80; // bootable pMBR->PartTbl[0].Active = 0x80; // bootable
pMBR->PartTbl[1].Active = 0x00; pMBR->PartTbl[1].Active = 0x00;
@ -2048,6 +2068,7 @@ int PartitionResizeForVentoy(PHY_DRIVE_INFO *pPhyDrive)
pMBR->BootCode[92] = 0x22; pMBR->BootCode[92] = 0x22;
// to fix windows issue // to fix windows issue
memset(pGPT->PartTbl + 1, 0, sizeof(VTOY_GPT_PART_TBL));
memcpy(&(pGPT->PartTbl[1].PartType), &WindowsDataPartType, sizeof(GUID)); memcpy(&(pGPT->PartTbl[1].PartType), &WindowsDataPartType, sizeof(GUID));
CoCreateGuid(&(pGPT->PartTbl[1].PartGuid)); CoCreateGuid(&(pGPT->PartTbl[1].PartGuid));
@ -2058,6 +2079,7 @@ int PartitionResizeForVentoy(PHY_DRIVE_INFO *pPhyDrive)
//Update CRC //Update CRC
pGPT->Head.PartTblCrc = VentoyCrc32(pGPT->PartTbl, sizeof(pGPT->PartTbl)); pGPT->Head.PartTblCrc = VentoyCrc32(pGPT->PartTbl, sizeof(pGPT->PartTbl));
pGPT->Head.Crc = 0;
pGPT->Head.Crc = VentoyCrc32(&(pGPT->Head), pGPT->Head.Length); pGPT->Head.Crc = VentoyCrc32(&(pGPT->Head), pGPT->Head.Length);
Log("pGPT->Head.EfiStartLBA=%llu", (ULONGLONG)pGPT->Head.EfiStartLBA); 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 Esp2Basic = FALSE;
BOOL ChangeAttr = FALSE; BOOL ChangeAttr = FALSE;
BOOL CleanDisk = FALSE; BOOL CleanDisk = FALSE;
BOOL DelEFI = FALSE;
BOOL bWriteBack = TRUE; BOOL bWriteBack = TRUE;
HANDLE hVolume; HANDLE hVolume;
HANDLE hDrive; HANDLE hDrive;
@ -2335,6 +2358,7 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId)
MBR_HEAD MBR; MBR_HEAD MBR;
BYTE *pBackup = NULL; BYTE *pBackup = NULL;
VTOY_GPT_INFO *pGptInfo = NULL; VTOY_GPT_INFO *pGptInfo = NULL;
VTOY_GPT_INFO *pGptBkup = NULL;
UINT8 ReservedData[4096]; UINT8 ReservedData[4096];
Log("#####################################################"); Log("#####################################################");
@ -2356,17 +2380,19 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId)
if (pPhyDrive->PartStyle) if (pPhyDrive->PartStyle)
{ {
pGptInfo = malloc(sizeof(VTOY_GPT_INFO)); pGptInfo = malloc(2 * sizeof(VTOY_GPT_INFO));
if (!pGptInfo) if (!pGptInfo)
{ {
return 1; return 1;
} }
memset(pGptInfo, 0, sizeof(VTOY_GPT_INFO)); memset(pGptInfo, 0, 2 * sizeof(VTOY_GPT_INFO));
pGptBkup = pGptInfo + 1;
// Read GPT Info // Read GPT Info
SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
ReadFile(hDrive, pGptInfo, sizeof(VTOY_GPT_INFO), &dwSize, NULL); 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 //MBR will be used to compare with local boot image
memcpy(&MBR, &pGptInfo->MBR, sizeof(MBR_HEAD)); memcpy(&MBR, &pGptInfo->MBR, sizeof(MBR_HEAD));
@ -2430,7 +2456,7 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId)
if (TryId == 1) if (TryId == 1)
{ {
Log("Change GPT partition type to ESP"); Log("Change GPT partition type to ESP");
if (VDS_ChangeVtoyEFI2ESP(pPhyDrive->PhyDrive, StartSector * 512)) if (DISK_ChangeVtoyEFI2ESP(pPhyDrive->PhyDrive, StartSector * 512ULL))
{ {
Esp2Basic = TRUE; Esp2Basic = TRUE;
Sleep(3000); Sleep(3000);
@ -2439,13 +2465,18 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId)
else if (TryId == 2) else if (TryId == 2)
{ {
Log("Change GPT partition attribute"); Log("Change GPT partition attribute");
if (VDS_ChangeVtoyEFIAttr(pPhyDrive->PhyDrive, 0x8000000000000001)) if (DISK_ChangeVtoyEFIAttr(pPhyDrive->PhyDrive, StartSector * 512ULL, 0x8000000000000001))
{ {
ChangeAttr = TRUE; ChangeAttr = TRUE;
Sleep(2000); Sleep(2000);
} }
} }
else if (TryId == 3) else if (TryId == 3)
{
DISK_DeleteVtoyEFIPartition(pPhyDrive->PhyDrive, StartSector * 512ULL);
DelEFI = TRUE;
}
else if (TryId == 4)
{ {
Log("Clean disk GPT partition table"); Log("Clean disk GPT partition table");
if (BackupDataBeforeCleanDisk(pPhyDrive->PhyDrive, pPhyDrive->SizeInBytes, &pBackup)) 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"); Log("Success to backup data before clean");
CleanDisk = TRUE; CleanDisk = TRUE;
if (!VDS_CleanDisk(pPhyDrive->PhyDrive)) DISK_CleanDisk(pPhyDrive->PhyDrive);
{
Sleep(3000);
DSPT_CleanDisk(pPhyDrive->PhyDrive);
}
Sleep(3000); Sleep(3000);
} }
else else
@ -2504,6 +2531,10 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId)
Status = ERROR_NOT_FOUND; Status = ERROR_NOT_FOUND;
} }
else if (DelEFI)
{
Status = ERROR_NOT_FOUND;
}
else if (Esp2Basic) else if (Esp2Basic)
{ {
Status = ERROR_NOT_FOUND; Status = ERROR_NOT_FOUND;
@ -2595,7 +2626,7 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId)
CHECK_CLOSE_HANDLE(hDrive); CHECK_CLOSE_HANDLE(hDrive);
Log("Now delete partition 2..."); Log("Now delete partition 2...");
VDS_DeleteVtoyEFIPartition(pPhyDrive->PhyDrive); DISK_DeleteVtoyEFIPartition(pPhyDrive->PhyDrive, StartSector * 512ULL);
hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, TRUE, FALSE); hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, TRUE, FALSE);
if (hDrive == INVALID_HANDLE_VALUE) if (hDrive == INVALID_HANDLE_VALUE)
@ -2707,6 +2738,37 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId)
Sleep(1000); 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 //Refresh Drive Layout
DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL); DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL);
@ -2726,6 +2788,7 @@ End:
} }
else else
{ {
PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN);
FindProcessOccupyDisk(hDrive, pPhyDrive); FindProcessOccupyDisk(hDrive, pPhyDrive);
} }
@ -2734,7 +2797,7 @@ End:
if (Esp2Basic) if (Esp2Basic)
{ {
Log("Recover GPT partition type to basic"); Log("Recover GPT partition type to basic");
VDS_ChangeVtoyEFI2Basic(pPhyDrive->PhyDrive, StartSector * 512); DISK_ChangeVtoyEFI2Basic(pPhyDrive->PhyDrive, StartSector * 512);
} }
if (pPhyDrive->PartStyle == 1) if (pPhyDrive->PartStyle == 1)
@ -2742,7 +2805,7 @@ End:
if (ChangeAttr || ((pPhyDrive->Part2GPTAttr >> 56) != 0xC0)) if (ChangeAttr || ((pPhyDrive->Part2GPTAttr >> 56) != 0xC0))
{ {
Log("Change EFI partition attr %u <0x%llx> to <0x%llx>", ChangeAttr, pPhyDrive->Part2GPTAttr, 0xC000000000000001ULL); 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"); Log("Change EFI partition attr success");
pPhyDrive->Part2GPTAttr = 0xC000000000000001ULL; pPhyDrive->Part2GPTAttr = 0xC000000000000001ULL;

View file

@ -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, ...) BOOL IsPathExist(BOOL Dir, const char *Fmt, ...)
{ {
va_list Arg; va_list Arg;
@ -231,6 +242,7 @@ BOOL IsWow64(void)
typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS)(HANDLE, PBOOL); typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS)(HANDLE, PBOOL);
LPFN_ISWOW64PROCESS fnIsWow64Process; LPFN_ISWOW64PROCESS fnIsWow64Process;
BOOL bIsWow64 = FALSE; BOOL bIsWow64 = FALSE;
CHAR Wow64Dir[MAX_PATH];
fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandleA("kernel32"), "IsWow64Process"); fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandleA("kernel32"), "IsWow64Process");
if (NULL != fnIsWow64Process) if (NULL != fnIsWow64Process)
@ -238,6 +250,15 @@ BOOL IsWow64(void)
fnIsWow64Process(GetCurrentProcess(), &bIsWow64); fnIsWow64Process(GetCurrentProcess(), &bIsWow64);
} }
if (!bIsWow64)
{
if (GetSystemWow64DirectoryA(Wow64Dir, sizeof(Wow64Dir)))
{
Log("GetSystemWow64DirectoryA=<%s>", Wow64Dir);
bIsWow64 = TRUE;
}
}
return bIsWow64; return bIsWow64;
} }

View file

@ -81,6 +81,8 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UIN
UINT32 PartStartSector; UINT32 PartStartSector;
UINT32 PartSectorCount; UINT32 PartSectorCount;
CHAR PhyDrivePath[128]; CHAR PhyDrivePath[128];
CHAR GUIDStr[128];
GUID ZeroGuid = { 0 };
VTOY_GPT_INFO *pGpt = NULL; VTOY_GPT_INFO *pGpt = NULL;
safe_sprintf(PhyDrivePath, "\\\\.\\PhysicalDrive%d", PhyDrive); safe_sprintf(PhyDrivePath, "\\\\.\\PhysicalDrive%d", PhyDrive);
@ -108,20 +110,7 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UIN
return FALSE; 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) if (MBR.PartTbl[0].FsFlag == 0xEE)
{ {
@ -147,6 +136,23 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UIN
return FALSE; 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 (memcmp(pGpt->PartTbl[1].Name, L"VTOYEFI", 7 * 2))
{ {
if (pGpt->PartTbl[1].Name[0]) 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); 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) if (MBR.PartTbl[0].StartSectorId != 2048)
{ {
Log("Part1 not match %u", MBR.PartTbl[0].StartSectorId); Log("Part1 not match %u", MBR.PartTbl[0].StartSectorId);

View file

@ -167,6 +167,8 @@ typedef struct PHY_DRIVE_INFO
UINT64 Part2GPTAttr; UINT64 Part2GPTAttr;
BOOL ResizeNoShrink; BOOL ResizeNoShrink;
UINT64 ResizeOldPart1Size;
CHAR Part1DriveLetter;
CHAR ResizeVolumeGuid[64]; CHAR ResizeVolumeGuid[64];
CHAR FsName[64]; CHAR FsName[64];
UINT64 ResizePart2StartSector; 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); HANDLE GetPhysicalHandle(int Drive, BOOLEAN bLockDrive, BOOLEAN bWriteAccess, BOOLEAN bWriteShare);
void InitComboxCtrl(HWND hWnd, int PhyDrive); 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 #define VTSI_SUPPORT 1

View file

@ -335,6 +335,7 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="crc32.c" /> <ClCompile Include="crc32.c" />
<ClCompile Include="DiskService.c" />
<ClCompile Include="DiskService_diskpart.c" /> <ClCompile Include="DiskService_diskpart.c" />
<ClCompile Include="DiskService_vds.c" /> <ClCompile Include="DiskService_vds.c" />
<ClCompile Include="DiskService_wmsa.c" /> <ClCompile Include="DiskService_wmsa.c" />

View file

@ -90,6 +90,9 @@
<ClCompile Include="DiskService_wmsa.c"> <ClCompile Include="DiskService_wmsa.c">
<Filter>源文件</Filter> <Filter>源文件</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="DiskService.c">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Ventoy2Disk.h"> <ClInclude Include="Ventoy2Disk.h">

Binary file not shown.

View file

@ -30,6 +30,20 @@ VTSI_SEGMENT *g_VentoySegment = NULL;
int g_VentoyMaxSeg = 0; int g_VentoyMaxSeg = 0;
int g_VentoyCurSeg = -1; int g_VentoyCurSeg = -1;
UINT64 g_VentoyDataOffset = 0; 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) 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); 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; return RES_OK;