Skip to content

Commit

Permalink
Add experimental support for Non-destructive Installation in Windows.
Browse files Browse the repository at this point in the history
  • Loading branch information
ventoy committed Nov 10, 2021
1 parent b67f738 commit 563214e
Show file tree
Hide file tree
Showing 14 changed files with 844 additions and 12 deletions.
Binary file modified INSTALL/Ventoy2Disk.exe
Binary file not shown.
Binary file modified INSTALL/Ventoy2Disk_ARM.exe
Binary file not shown.
Binary file modified INSTALL/Ventoy2Disk_ARM64.exe
Binary file not shown.
Binary file modified INSTALL/Ventoy2Disk_X64.exe
Binary file not shown.
250 changes: 248 additions & 2 deletions LANGUAGES/languages.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion LinuxGUI/build_qt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@ if [ "$1" = "VENTOY_I386_QT_BUILD" ]; then
exit 0
fi


if [ ! -f /opt/CentOS8/LinuxGUI/build.sh ]; then
mount --bind /home/share/Ventoy/LinuxGUI /opt/CentOS8/LinuxGUI
fi

chroot /opt/CentOS8 sh /buildqt.sh
force_copy ./Ventoy2Disk.qt5_32 ../INSTALL/tool/i386/Ventoy2Disk.qt5
Expand Down
1 change: 1 addition & 0 deletions Ventoy2Disk/Ventoy2Disk/DiskService.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ BOOL VDS_CreateVtoyEFIPart(int DriveIndex, UINT64 Offset);
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);

//diskpart.exe
BOOL DSPT_CleanDisk(int DriveIndex);
Expand Down
235 changes: 234 additions & 1 deletion Ventoy2Disk/Ventoy2Disk/DiskService_vds.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
// 3. Filter out the crap we don't need.
static const char *GetVdsError(DWORD error_code)
{
static char code[32];

sprintf_s(code, sizeof(code), "[0x%08x]", error_code);

switch (error_code) {
case 0x80042400: // VDS_E_NOT_SUPPORTED
return "The operation is not supported by the object.";
Expand Down Expand Up @@ -450,7 +454,7 @@ static const char *GetVdsError(DWORD error_code)
case 0x80042918: // VDS_E_COMPRESSION_NOT_SUPPORTED
return "The specified file system does not support compression.";
default:
return NULL;
return code;
}
}

Expand Down Expand Up @@ -537,6 +541,8 @@ const char *WindowsErrorString(DWORD error_code)
#define INTF_ADVANCEDDISK2 2
#define INTF_CREATEPARTITIONEX 3
#define INTF_PARTITIONMF 4
#define INTF_VOLUME 5
#define INTF_VOLUME_MF3 6

/*
* Some code and functions in the file are copied from rufus.
Expand Down Expand Up @@ -588,6 +594,8 @@ const char *WindowsErrorString(DWORD error_code)
#define IVdsAsync_Wait(This,pHrResult,pAsyncOut) (This)->lpVtbl->Wait(This,pHrResult,pAsyncOut)
#define IVdsAsync_Release(This) (This)->lpVtbl->Release(This)

#define IVdsVolume_Shrink(This, ullNumberOfBytesToRemove, ppAsync) (This)->lpVtbl->Shrink(This, ullNumberOfBytesToRemove, ppAsync)

#define IUnknown_QueryInterface(This, a, b) (This)->lpVtbl->QueryInterface(This,a,b)
#define IUnknown_Release(This) (This)->lpVtbl->Release(This)

Expand Down Expand Up @@ -635,6 +643,162 @@ STATIC IVdsService * VDS_InitService(void)
return pService;
}

STATIC BOOL VDS_VolumeCommProc(int intf, const WCHAR* wVolumeGuid, VDS_Callback_PF callback, UINT64 data)
{
int Pos = 0;
BOOL Find = FALSE;
BOOL r = FALSE;
HRESULT hr;
ULONG ulFetched;
IUnknown* pUnk = NULL;
IEnumVdsObject* pEnum = NULL;
IVdsService* pService = NULL;

pService = VDS_InitService();
if (!pService)
{
Log("Could not query VDS Service");
goto out;
}

// Query the VDS Service Providers
hr = IVdsService_QueryProviders(pService, VDS_QUERY_SOFTWARE_PROVIDERS, &pEnum);
if (hr != S_OK)
{
VDS_SET_ERROR(hr);
Log("Could not query VDS Service Providers: 0x%lx %u", hr, LASTERR);
goto out;
}

while (IEnumVdsObject_Next(pEnum, 1, &pUnk, &ulFetched) == S_OK)
{
IVdsProvider* pProvider;
IVdsSwProvider* pSwProvider;
IEnumVdsObject* pEnumPack;
IUnknown* pPackUnk;

// Get VDS Provider
hr = IUnknown_QueryInterface(pUnk, &IID_IVdsProvider, (void**)&pProvider);
IUnknown_Release(pUnk);
if (hr != S_OK)
{
VDS_SET_ERROR(hr);
Log("Could not get VDS Provider: %u", LASTERR);
goto out;
}

// Get VDS Software Provider
hr = IVdsSwProvider_QueryInterface(pProvider, &IID_IVdsSwProvider, (void**)&pSwProvider);
IVdsProvider_Release(pProvider);
if (hr != S_OK)
{
VDS_SET_ERROR(hr);
Log("Could not get VDS Software Provider: %u", LASTERR);
goto out;
}

// Get VDS Software Provider Packs
hr = IVdsSwProvider_QueryPacks(pSwProvider, &pEnumPack);
IVdsSwProvider_Release(pSwProvider);
if (hr != S_OK)
{
VDS_SET_ERROR(hr);
Log("Could not get VDS Software Provider Packs: %u", LASTERR);
goto out;
}

// Enumerate Provider Packs
while (IEnumVdsObject_Next(pEnumPack, 1, &pPackUnk, &ulFetched) == S_OK)
{
IVdsPack* pPack;
IEnumVdsObject* pEnumVolume;
IUnknown* pVolumeUnk;

hr = IUnknown_QueryInterface(pPackUnk, &IID_IVdsPack, (void**)&pPack);
IUnknown_Release(pPackUnk);
if (hr != S_OK)
{
VDS_SET_ERROR(hr);
Log("Could not query VDS Software Provider Pack: %u", LASTERR);
goto out;
}

// Use the pack interface to access the volume
hr = IVdsPack_QueryVolumes(pPack, &pEnumVolume);;
if (hr != S_OK) {
VDS_SET_ERROR(hr);
Log("Could not query VDS volume: %u", LASTERR);
goto out;
}

// List disks
while (IEnumVdsObject_Next(pEnumVolume, 1, &pVolumeUnk, &ulFetched) == S_OK)
{
IVdsVolume* pVolume;
IVdsVolumeMF3* pVolumeMF3;
LPWSTR* wszPathArray;
ULONG ulNumberOfPaths;

// Get the disk interface.
hr = IUnknown_QueryInterface(pVolumeUnk, &IID_IVdsVolumeMF3, (void**)&pVolumeMF3);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
Log("Could not query VDS Volume Interface: %u", LASTERR);
goto out;
}

// Get the volume properties
hr = IVdsVolumeMF3_QueryVolumeGuidPathnames(pVolumeMF3, &wszPathArray, &ulNumberOfPaths);
if ((hr != S_OK) && (hr != VDS_S_PROPERTIES_INCOMPLETE))
{
Log("Could not query VDS VolumeMF3 GUID PathNames: %s", GetVdsError(hr));
IVdsVolume_Release(pVolumeMF3);
IUnknown_Release(pVolumeUnk);
continue;
}

Log("Get Volume %d %lu <%S>", intf, ulNumberOfPaths, wszPathArray[0]);

if ((ulNumberOfPaths >= 1) && wcsstr(wszPathArray[0], wVolumeGuid))
{
Find = TRUE;
Log("Call back for this Volume %d <%S>", intf, wVolumeGuid);

if (INTF_VOLUME_MF3 == intf)
{
r = callback(pVolumeMF3, NULL, data);
}
else if (INTF_VOLUME == intf)
{
// Get the disk interface.
hr = IUnknown_QueryInterface(pVolumeUnk, &IID_IVdsVolume, (void**)&pVolume);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
Log("Could not query VDS Volume Interface: %u", LASTERR);
}
else {
r = callback(pVolume, NULL, data);
IVdsVolume_Release(pVolume);
}
}
}

CoTaskMemFree(wszPathArray);
IVdsVolume_Release(pVolumeMF3);
IUnknown_Release(pVolumeUnk);

if (Find)
{
goto out;
}
}
}
}

out:
return r;
}


STATIC BOOL VDS_DiskCommProc(int intf, int DriveIndex, VDS_Callback_PF callback, UINT64 data)
{
Expand Down Expand Up @@ -1222,3 +1386,72 @@ BOOL VDS_FormatVtoyEFIPart(int DriveIndex, UINT64 Offset)
return ret;
}

STATIC BOOL VDS_CallBack_ShrinkVolume(void* pInterface, VDS_DISK_PROP* pDiskProp, UINT64 data)
{
HRESULT hr, hr2;
IVdsVolume* pVolume = (IVdsVolume*)pInterface;
ULONG completed;
IVdsAsync* pAsync;

(void)pDiskProp;

Log("VDS_CallBack_ShrinkVolume (%llu) ...", (ULONGLONG)data);

hr = IVdsVolume_Shrink(pVolume, (ULONGLONG)data, &pAsync);

while (SUCCEEDED(hr))
{
hr = IVdsAsync_QueryStatus(pAsync, &hr2, &completed);
if (SUCCEEDED(hr))
{
hr = hr2;
if (hr == S_OK)
{
Log("ShrinkVolume QueryStatus OK, %lu%%", completed);
break;
}
else if (hr == VDS_E_OPERATION_PENDING)
{
Log("ShrinkVolume: %lu%%", completed);
hr = S_OK;
}
else
{
Log("ShrinkVolume invalid status:0x%lx", hr);
}
}
Sleep(1000);
}

if (hr != S_OK)
{
VDS_SET_ERROR(hr);
Log("Could not ShrinkVolume, 0x%x err:0x%lx (%s)", hr, LASTERR, WindowsErrorString(hr));
return FALSE;
}

return TRUE;
}

BOOL VDS_ShrinkVolume(const char* VolumeGuid, UINT64 ReduceBytes)
{
int i;
BOOL ret = FALSE;
WCHAR wGuid[128] = { 0 };
const char *guid = NULL;

guid = strstr(VolumeGuid, "{");
if (!guid)
{
return FALSE;
}

for (i = 0; i < 128 && guid[i]; i++)
{
wGuid[i] = guid[i];
}

ret = VDS_VolumeCommProc(INTF_VOLUME, wGuid, VDS_CallBack_ShrinkVolume, ReduceBytes);
Log("VDS_ShrinkVolume ret:%d (%s)", ret, ret ? "SUCCESS" : "FAIL");
return ret;
}
8 changes: 8 additions & 0 deletions Ventoy2Disk/Ventoy2Disk/Language.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ typedef enum STR_ID
STR_VTSI_CREATE_SUCCESS, //41
STR_VTSI_CREATE_FAILED, //42

STR_MENU_PART_RESIZE,//43
STR_PART_RESIZE_TIP,//44
STR_PART_RESIZE_SUCCESS,//45
STR_PART_RESIZE_FAILED,//46
STR_PART_RESIZE_UNSUPPORTED,//47

STR_ID_MAX
}STR_ID;

Expand All @@ -90,6 +96,7 @@ extern BOOL g_SecureBoot;
#define VTOY_MENU_PART_GPT 0xA005
#define VTOY_MENU_ALL_DEV 0xA006
#define VTOY_MENU_VTSI 0xA007
#define VTOY_MENU_PART_RESIZE 0xA008


typedef enum OPT_SUBMENU
Expand All @@ -100,6 +107,7 @@ typedef enum OPT_SUBMENU
OPT_SUBMENU_CLEAR,
OPT_SUBMENU_ALL_DEV,
OPT_SUBMENU_VTSI,
OPT_SUBMENU_PART_RESIZE,

OPT_SUBMENU_MAX
}OPT_SUBMENU;
Expand Down
Loading

0 comments on commit 563214e

Please sign in to comment.