mirror of https://github.com/ventoy/Ventoy
parent
3938fbb351
commit
be78728342
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,411 @@
|
||||
#include <Windows.h>
|
||||
#include <Shlobj.h>
|
||||
#include <tlhelp32.h>
|
||||
#include <Psapi.h>
|
||||
#include <commctrl.h>
|
||||
#include "resource.h"
|
||||
#include "Language.h"
|
||||
#include "Ventoy2Disk.h"
|
||||
#include "DiskService.h"
|
||||
#include "VentoyJson.h"
|
||||
|
||||
extern void CLISetReserveSpace(int MB);
|
||||
|
||||
typedef struct CLI_CFG
|
||||
{
|
||||
int op;
|
||||
int PartStyle;
|
||||
int ReserveMB;
|
||||
BOOL USBCheck;
|
||||
}CLI_CFG;
|
||||
|
||||
BOOL g_CLI_Mode = FALSE;
|
||||
static int g_CLI_OP;
|
||||
static int g_CLI_PhyDrive;
|
||||
|
||||
static int CLI_GetPhyDriveInfo(int PhyDrive, PHY_DRIVE_INFO* pInfo)
|
||||
{
|
||||
BOOL bRet;
|
||||
DWORD dwBytes;
|
||||
HANDLE Handle = INVALID_HANDLE_VALUE;
|
||||
CHAR PhyDrivePath[128];
|
||||
GET_LENGTH_INFORMATION LengthInfo;
|
||||
STORAGE_PROPERTY_QUERY Query;
|
||||
STORAGE_DESCRIPTOR_HEADER DevDescHeader;
|
||||
STORAGE_DEVICE_DESCRIPTOR* pDevDesc;
|
||||
|
||||
safe_sprintf(PhyDrivePath, "\\\\.\\PhysicalDrive%d", PhyDrive);
|
||||
Handle = CreateFileA(PhyDrivePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
Log("Create file Handle:%p %s status:%u", Handle, PhyDrivePath, LASTERR);
|
||||
|
||||
if (Handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
bRet = DeviceIoControl(Handle,
|
||||
IOCTL_DISK_GET_LENGTH_INFO, NULL,
|
||||
0,
|
||||
&LengthInfo,
|
||||
sizeof(LengthInfo),
|
||||
&dwBytes,
|
||||
NULL);
|
||||
if (!bRet)
|
||||
{
|
||||
Log("DeviceIoControl IOCTL_DISK_GET_LENGTH_INFO failed error:%u", LASTERR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Log("PHYSICALDRIVE%d size %llu bytes", PhyDrive, (ULONGLONG)LengthInfo.Length.QuadPart);
|
||||
|
||||
Query.PropertyId = StorageDeviceProperty;
|
||||
Query.QueryType = PropertyStandardQuery;
|
||||
|
||||
bRet = DeviceIoControl(Handle,
|
||||
IOCTL_STORAGE_QUERY_PROPERTY,
|
||||
&Query,
|
||||
sizeof(Query),
|
||||
&DevDescHeader,
|
||||
sizeof(STORAGE_DESCRIPTOR_HEADER),
|
||||
&dwBytes,
|
||||
NULL);
|
||||
if (!bRet)
|
||||
{
|
||||
Log("DeviceIoControl1 error:%u dwBytes:%u", LASTERR, dwBytes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (DevDescHeader.Size < sizeof(STORAGE_DEVICE_DESCRIPTOR))
|
||||
{
|
||||
Log("Invalid DevDescHeader.Size:%u", DevDescHeader.Size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
pDevDesc = (STORAGE_DEVICE_DESCRIPTOR*)malloc(DevDescHeader.Size);
|
||||
if (!pDevDesc)
|
||||
{
|
||||
Log("failed to malloc error:%u len:%u", LASTERR, DevDescHeader.Size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
bRet = DeviceIoControl(Handle,
|
||||
IOCTL_STORAGE_QUERY_PROPERTY,
|
||||
&Query,
|
||||
sizeof(Query),
|
||||
pDevDesc,
|
||||
DevDescHeader.Size,
|
||||
&dwBytes,
|
||||
NULL);
|
||||
if (!bRet)
|
||||
{
|
||||
Log("DeviceIoControl2 error:%u dwBytes:%u", LASTERR, dwBytes);
|
||||
free(pDevDesc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
pInfo->PhyDrive = PhyDrive;
|
||||
pInfo->SizeInBytes = LengthInfo.Length.QuadPart;
|
||||
pInfo->DeviceType = pDevDesc->DeviceType;
|
||||
pInfo->RemovableMedia = pDevDesc->RemovableMedia;
|
||||
pInfo->BusType = pDevDesc->BusType;
|
||||
|
||||
if (pDevDesc->VendorIdOffset)
|
||||
{
|
||||
safe_strcpy(pInfo->VendorId, (char*)pDevDesc + pDevDesc->VendorIdOffset);
|
||||
TrimString(pInfo->VendorId);
|
||||
}
|
||||
|
||||
if (pDevDesc->ProductIdOffset)
|
||||
{
|
||||
safe_strcpy(pInfo->ProductId, (char*)pDevDesc + pDevDesc->ProductIdOffset);
|
||||
TrimString(pInfo->ProductId);
|
||||
}
|
||||
|
||||
if (pDevDesc->ProductRevisionOffset)
|
||||
{
|
||||
safe_strcpy(pInfo->ProductRev, (char*)pDevDesc + pDevDesc->ProductRevisionOffset);
|
||||
TrimString(pInfo->ProductRev);
|
||||
}
|
||||
|
||||
if (pDevDesc->SerialNumberOffset)
|
||||
{
|
||||
safe_strcpy(pInfo->SerialNumber, (char*)pDevDesc + pDevDesc->SerialNumberOffset);
|
||||
TrimString(pInfo->SerialNumber);
|
||||
}
|
||||
|
||||
free(pDevDesc);
|
||||
|
||||
CHECK_CLOSE_HANDLE(Handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CLI_CheckParam(int argc, char** argv, PHY_DRIVE_INFO* pDrvInfo, CLI_CFG *pCfg)
|
||||
{
|
||||
int i;
|
||||
int op = -1;
|
||||
char* opt = NULL;
|
||||
int PhyDrive = -1;
|
||||
int PartStyle = 0;
|
||||
int ReserveMB = 0;
|
||||
BOOL USBCheck = TRUE;
|
||||
MBR_HEAD MBR;
|
||||
UINT64 Part2GPTAttr = 0;
|
||||
UINT64 Part2StartSector = 0;
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
opt = argv[i];
|
||||
if (_stricmp(opt, "/I") == 0)
|
||||
{
|
||||
op = 0;
|
||||
}
|
||||
else if (_stricmp(opt, "/U") == 0)
|
||||
{
|
||||
op = 1;
|
||||
}
|
||||
else if (_stricmp(opt, "/GPT") == 0)
|
||||
{
|
||||
PartStyle = 1;
|
||||
}
|
||||
else if (_stricmp(opt, "/NoSB") == 0)
|
||||
{
|
||||
g_SecureBoot = FALSE;
|
||||
}
|
||||
else if (_stricmp(opt, "/NoUSBCheck") == 0)
|
||||
{
|
||||
USBCheck = FALSE;
|
||||
}
|
||||
else if (_strnicmp(opt, "/Drive:", 7) == 0)
|
||||
{
|
||||
Log("Get PhyDrive by logical drive %C:", opt[7]);
|
||||
PhyDrive = GetPhyDriveByLogicalDrive(opt[7], NULL);
|
||||
}
|
||||
else if (_strnicmp(opt, "/PhyDrive:", 10) == 0)
|
||||
{
|
||||
PhyDrive = (int)strtol(opt + 10, NULL, 10);
|
||||
}
|
||||
else if (_strnicmp(opt, "/R:", 3) == 0)
|
||||
{
|
||||
ReserveMB = (int)strtol(opt + 3, NULL, 10);
|
||||
}
|
||||
}
|
||||
|
||||
if (op < 0 || PhyDrive < 0)
|
||||
{
|
||||
Log("[ERROR] Invalid parameters %d %d", op, PhyDrive);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Log("Ventoy CLI %s PhyDrive:%d %s SecureBoot:%d ReserveSpace:%dMB USBCheck:%u",
|
||||
op == 0 ? "install" : "update",
|
||||
PhyDrive, PartStyle ? "GPT" : "MBR",
|
||||
g_SecureBoot, ReserveMB, USBCheck
|
||||
);
|
||||
|
||||
if (CLI_GetPhyDriveInfo(PhyDrive, pDrvInfo))
|
||||
{
|
||||
Log("[ERROR] Failed to get phydrive%d info", PhyDrive);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Log("PhyDrive:%d BusType:%-4s Removable:%u Size:%dGB(%llu) Name:%s %s",
|
||||
pDrvInfo->PhyDrive, GetBusTypeString(pDrvInfo->BusType), pDrvInfo->RemovableMedia,
|
||||
GetHumanReadableGBSize(pDrvInfo->SizeInBytes), pDrvInfo->SizeInBytes,
|
||||
pDrvInfo->VendorId, pDrvInfo->ProductId);
|
||||
|
||||
if (IsVentoyPhyDrive(PhyDrive, pDrvInfo->SizeInBytes, &MBR, &Part2StartSector, &Part2GPTAttr))
|
||||
{
|
||||
memcpy(&(pDrvInfo->MBR), &MBR, sizeof(MBR));
|
||||
pDrvInfo->PartStyle = (MBR.PartTbl[0].FsFlag == 0xEE) ? 1 : 0;
|
||||
pDrvInfo->Part2GPTAttr = Part2GPTAttr;
|
||||
GetVentoyVerInPhyDrive(pDrvInfo, Part2StartSector, pDrvInfo->VentoyVersion, sizeof(pDrvInfo->VentoyVersion), &(pDrvInfo->SecureBootSupport));
|
||||
Log("PhyDrive %d is Ventoy Disk ver:%s SecureBoot:%u", pDrvInfo->PhyDrive, pDrvInfo->VentoyVersion, pDrvInfo->SecureBootSupport);
|
||||
|
||||
GetVentoyFsNameInPhyDrive(pDrvInfo);
|
||||
|
||||
if (pDrvInfo->VentoyVersion[0] == 0)
|
||||
{
|
||||
pDrvInfo->VentoyVersion[0] = '?';
|
||||
Log("Unknown Ventoy Version");
|
||||
}
|
||||
}
|
||||
|
||||
pCfg->op = op;
|
||||
pCfg->PartStyle = PartStyle;
|
||||
pCfg->ReserveMB = ReserveMB;
|
||||
pCfg->USBCheck = USBCheck;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Ventoy_CLI_Install(PHY_DRIVE_INFO* pDrvInfo, CLI_CFG *pCfg)
|
||||
{
|
||||
int rc;
|
||||
int TryId = 1;
|
||||
|
||||
Log("Ventoy_CLI_Install start ...");
|
||||
|
||||
if (pCfg->ReserveMB > 0)
|
||||
{
|
||||
CLISetReserveSpace(pCfg->ReserveMB);
|
||||
}
|
||||
|
||||
rc = InstallVentoy2PhyDrive(pDrvInfo, pCfg->PartStyle, TryId++);
|
||||
if (rc)
|
||||
{
|
||||
Log("This time install failed, clean disk by disk, wait 3s and retry...");
|
||||
DISK_CleanDisk(pDrvInfo->PhyDrive);
|
||||
|
||||
Sleep(3000);
|
||||
|
||||
Log("Now retry to install...");
|
||||
rc = InstallVentoy2PhyDrive(pDrvInfo, pCfg->PartStyle, TryId++);
|
||||
|
||||
if (rc)
|
||||
{
|
||||
Log("This time install failed, clean disk by diskpart, wait 5s and retry...");
|
||||
DSPT_CleanDisk(pDrvInfo->PhyDrive);
|
||||
|
||||
Sleep(5000);
|
||||
|
||||
Log("Now retry to install...");
|
||||
rc = InstallVentoy2PhyDrive(pDrvInfo, pCfg->PartStyle, TryId++);
|
||||
}
|
||||
}
|
||||
|
||||
Log("Ventoy_CLI_Install [%s]", rc == 0 ? "SUCCESS" : "FAILED");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int Ventoy_CLI_Update(PHY_DRIVE_INFO* pDrvInfo, CLI_CFG* pCfg)
|
||||
{
|
||||
int rc;
|
||||
int TryId = 1;
|
||||
|
||||
Log("Ventoy_CLI_Update start ...");
|
||||
|
||||
rc = UpdateVentoy2PhyDrive(pDrvInfo, TryId++);
|
||||
if (rc)
|
||||
{
|
||||
Log("This time update failed, now wait and retry...");
|
||||
Sleep(4000);
|
||||
|
||||
//Try2
|
||||
Log("Now retry to update...");
|
||||
rc = UpdateVentoy2PhyDrive(pDrvInfo, TryId++);
|
||||
if (rc)
|
||||
{
|
||||
//Try3
|
||||
Sleep(1000);
|
||||
Log("Now retry to update...");
|
||||
rc = UpdateVentoy2PhyDrive(pDrvInfo, TryId++);
|
||||
if (rc)
|
||||
{
|
||||
//Try4 is dangerous ...
|
||||
Sleep(3000);
|
||||
Log("Now retry to update...");
|
||||
rc = UpdateVentoy2PhyDrive(pDrvInfo, TryId++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Log("Ventoy_CLI_Update [%s]", rc == 0 ? "SUCCESS" : "FAILED");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void CLI_UpdatePercent(int Pos)
|
||||
{
|
||||
int Len;
|
||||
FILE* File = NULL;
|
||||
CHAR szBuf[128];
|
||||
|
||||
Len = (int)sprintf_s(szBuf, sizeof(szBuf), "%d", Pos * 100 / PT_FINISH);
|
||||
fopen_s(&File, VENTOY_CLI_PERCENT, "w+");
|
||||
if (File)
|
||||
{
|
||||
fwrite(szBuf, 1, Len, File);
|
||||
fwrite("\n", 1, 1, File);
|
||||
fclose(File);
|
||||
}
|
||||
}
|
||||
|
||||
static void CLI_WriteDoneFile(int ret)
|
||||
{
|
||||
FILE* File = NULL;
|
||||
|
||||
fopen_s(&File, VENTOY_CLI_DONE, "w+");
|
||||
if (File)
|
||||
{
|
||||
if (ret == 0)
|
||||
{
|
||||
fwrite("0\n", 1, 2, File);
|
||||
}
|
||||
else
|
||||
{
|
||||
fwrite("1\n", 1, 2, File);
|
||||
}
|
||||
fclose(File);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Ventoy2Disk.exe VTOYCLI { /I | /U } { /Drive:F: | /PhyDrive:1 } /GPT /NoSB /R:4096 /NoUSBCheck
|
||||
*
|
||||
*/
|
||||
int VentoyCLIMain(int argc, char** argv)
|
||||
{
|
||||
int ret = 1;
|
||||
PHY_DRIVE_INFO* pDrvInfo = NULL;
|
||||
CLI_CFG CliCfg;
|
||||
|
||||
DeleteFileA(VENTOY_CLI_PERCENT);
|
||||
DeleteFileA(VENTOY_CLI_DONE);
|
||||
|
||||
pDrvInfo = (PHY_DRIVE_INFO*)malloc(sizeof(PHY_DRIVE_INFO));
|
||||
if (!pDrvInfo)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
memset(pDrvInfo, 0, sizeof(PHY_DRIVE_INFO));
|
||||
|
||||
if (CLI_CheckParam(argc, argv, pDrvInfo, &CliCfg))
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
//Check USB type for install
|
||||
if (CliCfg.op == 0 && CliCfg.USBCheck)
|
||||
{
|
||||
if (pDrvInfo->BusType != BusTypeUsb)
|
||||
{
|
||||
Log("[ERROR] PhyDrive %d is NOT USB type", pDrvInfo->PhyDrive);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (CliCfg.op == 0)
|
||||
{
|
||||
ret = Ventoy_CLI_Install(pDrvInfo, &CliCfg);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pDrvInfo->VentoyVersion[0] == 0)
|
||||
{
|
||||
Log("[ERROR] No Ventoy information detected in PhyDrive %d, so can not do update", pDrvInfo->PhyDrive);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = Ventoy_CLI_Update(pDrvInfo, &CliCfg);
|
||||
}
|
||||
|
||||
end:
|
||||
CHECK_FREE(pDrvInfo);
|
||||
|
||||
CLI_UpdatePercent(PT_FINISH);
|
||||
CLI_WriteDoneFile(ret);
|
||||
|
||||
return ret;
|
||||
}
|
Loading…
Reference in New Issue