mirror of https://github.com/ventoy/Ventoy.git
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:
parent
b0568922d2
commit
0891e34d47
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -23,5 +23,235 @@
|
|||
#include <commctrl.h>
|
||||
#include <initguid.h>
|
||||
#include <vds.h>
|
||||
#include <VersionHelpers.h>
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -335,6 +335,7 @@
|
|||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="crc32.c" />
|
||||
<ClCompile Include="DiskService.c" />
|
||||
<ClCompile Include="DiskService_diskpart.c" />
|
||||
<ClCompile Include="DiskService_vds.c" />
|
||||
<ClCompile Include="DiskService_wmsa.c" />
|
||||
|
|
|
@ -90,6 +90,9 @@
|
|||
<ClCompile Include="DiskService_wmsa.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DiskService.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Ventoy2Disk.h">
|
||||
|
|
Binary file not shown.
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue