8 #include "Ventoy2Disk.h"
9 #include "DiskService.h"
10 #include "VentoyJson.h"
12 extern void CLISetReserveSpace(int MB
);
14 typedef struct CLI_CFG
22 BOOL g_CLI_Mode
= FALSE
;
24 static int g_CLI_PhyDrive
;
26 static int CLI_GetPhyDriveInfo(int PhyDrive
, PHY_DRIVE_INFO
* pInfo
)
30 HANDLE Handle
= INVALID_HANDLE_VALUE
;
31 CHAR PhyDrivePath
[128];
32 GET_LENGTH_INFORMATION LengthInfo
;
33 STORAGE_PROPERTY_QUERY Query
;
34 STORAGE_DESCRIPTOR_HEADER DevDescHeader
;
35 STORAGE_DEVICE_DESCRIPTOR
* pDevDesc
;
37 safe_sprintf(PhyDrivePath
, "\\\\.\\PhysicalDrive%d", PhyDrive
);
38 Handle
= CreateFileA(PhyDrivePath
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, NULL
);
39 Log("Create file Handle:%p %s status:%u", Handle
, PhyDrivePath
, LASTERR
);
41 if (Handle
== INVALID_HANDLE_VALUE
)
46 bRet
= DeviceIoControl(Handle
,
47 IOCTL_DISK_GET_LENGTH_INFO
, NULL
,
55 Log("DeviceIoControl IOCTL_DISK_GET_LENGTH_INFO failed error:%u", LASTERR
);
59 Log("PHYSICALDRIVE%d size %llu bytes", PhyDrive
, (ULONGLONG
)LengthInfo
.Length
.QuadPart
);
61 Query
.PropertyId
= StorageDeviceProperty
;
62 Query
.QueryType
= PropertyStandardQuery
;
64 bRet
= DeviceIoControl(Handle
,
65 IOCTL_STORAGE_QUERY_PROPERTY
,
69 sizeof(STORAGE_DESCRIPTOR_HEADER
),
74 Log("DeviceIoControl1 error:%u dwBytes:%u", LASTERR
, dwBytes
);
78 if (DevDescHeader
.Size
< sizeof(STORAGE_DEVICE_DESCRIPTOR
))
80 Log("Invalid DevDescHeader.Size:%u", DevDescHeader
.Size
);
84 pDevDesc
= (STORAGE_DEVICE_DESCRIPTOR
*)malloc(DevDescHeader
.Size
);
87 Log("failed to malloc error:%u len:%u", LASTERR
, DevDescHeader
.Size
);
91 bRet
= DeviceIoControl(Handle
,
92 IOCTL_STORAGE_QUERY_PROPERTY
,
101 Log("DeviceIoControl2 error:%u dwBytes:%u", LASTERR
, dwBytes
);
106 pInfo
->PhyDrive
= PhyDrive
;
107 pInfo
->SizeInBytes
= LengthInfo
.Length
.QuadPart
;
108 pInfo
->DeviceType
= pDevDesc
->DeviceType
;
109 pInfo
->RemovableMedia
= pDevDesc
->RemovableMedia
;
110 pInfo
->BusType
= pDevDesc
->BusType
;
112 if (pDevDesc
->VendorIdOffset
)
114 safe_strcpy(pInfo
->VendorId
, (char*)pDevDesc
+ pDevDesc
->VendorIdOffset
);
115 TrimString(pInfo
->VendorId
);
118 if (pDevDesc
->ProductIdOffset
)
120 safe_strcpy(pInfo
->ProductId
, (char*)pDevDesc
+ pDevDesc
->ProductIdOffset
);
121 TrimString(pInfo
->ProductId
);
124 if (pDevDesc
->ProductRevisionOffset
)
126 safe_strcpy(pInfo
->ProductRev
, (char*)pDevDesc
+ pDevDesc
->ProductRevisionOffset
);
127 TrimString(pInfo
->ProductRev
);
130 if (pDevDesc
->SerialNumberOffset
)
132 safe_strcpy(pInfo
->SerialNumber
, (char*)pDevDesc
+ pDevDesc
->SerialNumberOffset
);
133 TrimString(pInfo
->SerialNumber
);
138 CHECK_CLOSE_HANDLE(Handle
);
143 static int CLI_CheckParam(int argc
, char** argv
, PHY_DRIVE_INFO
* pDrvInfo
, CLI_CFG
*pCfg
)
151 BOOL USBCheck
= TRUE
;
153 UINT64 Part2GPTAttr
= 0;
154 UINT64 Part2StartSector
= 0;
156 for (i
= 0; i
< argc
; i
++)
159 if (_stricmp(opt
, "/I") == 0)
163 else if (_stricmp(opt
, "/U") == 0)
167 else if (_stricmp(opt
, "/GPT") == 0)
171 else if (_stricmp(opt
, "/NoSB") == 0)
173 g_SecureBoot
= FALSE
;
175 else if (_stricmp(opt
, "/NoUSBCheck") == 0)
179 else if (_strnicmp(opt
, "/Drive:", 7) == 0)
181 Log("Get PhyDrive by logical drive %C:", opt
[7]);
182 PhyDrive
= GetPhyDriveByLogicalDrive(opt
[7], NULL
);
184 else if (_strnicmp(opt
, "/PhyDrive:", 10) == 0)
186 PhyDrive
= (int)strtol(opt
+ 10, NULL
, 10);
188 else if (_strnicmp(opt
, "/R:", 3) == 0)
190 ReserveMB
= (int)strtol(opt
+ 3, NULL
, 10);
194 if (op
< 0 || PhyDrive
< 0)
196 Log("[ERROR] Invalid parameters %d %d", op
, PhyDrive
);
200 Log("Ventoy CLI %s PhyDrive:%d %s SecureBoot:%d ReserveSpace:%dMB USBCheck:%u",
201 op
== 0 ? "install" : "update",
202 PhyDrive
, PartStyle
? "GPT" : "MBR",
203 g_SecureBoot
, ReserveMB
, USBCheck
206 if (CLI_GetPhyDriveInfo(PhyDrive
, pDrvInfo
))
208 Log("[ERROR] Failed to get phydrive%d info", PhyDrive
);
212 Log("PhyDrive:%d BusType:%-4s Removable:%u Size:%dGB(%llu) Name:%s %s",
213 pDrvInfo
->PhyDrive
, GetBusTypeString(pDrvInfo
->BusType
), pDrvInfo
->RemovableMedia
,
214 GetHumanReadableGBSize(pDrvInfo
->SizeInBytes
), pDrvInfo
->SizeInBytes
,
215 pDrvInfo
->VendorId
, pDrvInfo
->ProductId
);
217 if (IsVentoyPhyDrive(PhyDrive
, pDrvInfo
->SizeInBytes
, &MBR
, &Part2StartSector
, &Part2GPTAttr
))
219 memcpy(&(pDrvInfo
->MBR
), &MBR
, sizeof(MBR
));
220 pDrvInfo
->PartStyle
= (MBR
.PartTbl
[0].FsFlag
== 0xEE) ? 1 : 0;
221 pDrvInfo
->Part2GPTAttr
= Part2GPTAttr
;
222 GetVentoyVerInPhyDrive(pDrvInfo
, Part2StartSector
, pDrvInfo
->VentoyVersion
, sizeof(pDrvInfo
->VentoyVersion
), &(pDrvInfo
->SecureBootSupport
));
223 Log("PhyDrive %d is Ventoy Disk ver:%s SecureBoot:%u", pDrvInfo
->PhyDrive
, pDrvInfo
->VentoyVersion
, pDrvInfo
->SecureBootSupport
);
225 GetVentoyFsNameInPhyDrive(pDrvInfo
);
227 if (pDrvInfo
->VentoyVersion
[0] == 0)
229 pDrvInfo
->VentoyVersion
[0] = '?';
230 Log("Unknown Ventoy Version");
235 pCfg
->PartStyle
= PartStyle
;
236 pCfg
->ReserveMB
= ReserveMB
;
237 pCfg
->USBCheck
= USBCheck
;
242 static int Ventoy_CLI_Install(PHY_DRIVE_INFO
* pDrvInfo
, CLI_CFG
*pCfg
)
247 Log("Ventoy_CLI_Install start ...");
249 if (pCfg
->ReserveMB
> 0)
251 CLISetReserveSpace(pCfg
->ReserveMB
);
254 rc
= InstallVentoy2PhyDrive(pDrvInfo
, pCfg
->PartStyle
, TryId
++);
257 Log("This time install failed, clean disk by disk, wait 3s and retry...");
258 DISK_CleanDisk(pDrvInfo
->PhyDrive
);
262 Log("Now retry to install...");
263 rc
= InstallVentoy2PhyDrive(pDrvInfo
, pCfg
->PartStyle
, TryId
++);
267 Log("This time install failed, clean disk by diskpart, wait 5s and retry...");
268 DSPT_CleanDisk(pDrvInfo
->PhyDrive
);
272 Log("Now retry to install...");
273 rc
= InstallVentoy2PhyDrive(pDrvInfo
, pCfg
->PartStyle
, TryId
++);
277 Log("Ventoy_CLI_Install [%s]", rc
== 0 ? "SUCCESS" : "FAILED");
282 static int Ventoy_CLI_Update(PHY_DRIVE_INFO
* pDrvInfo
, CLI_CFG
* pCfg
)
287 Log("Ventoy_CLI_Update start ...");
289 rc
= UpdateVentoy2PhyDrive(pDrvInfo
, TryId
++);
292 Log("This time update failed, now wait and retry...");
296 Log("Now retry to update...");
297 rc
= UpdateVentoy2PhyDrive(pDrvInfo
, TryId
++);
302 Log("Now retry to update...");
303 rc
= UpdateVentoy2PhyDrive(pDrvInfo
, TryId
++);
306 //Try4 is dangerous ...
308 Log("Now retry to update...");
309 rc
= UpdateVentoy2PhyDrive(pDrvInfo
, TryId
++);
314 Log("Ventoy_CLI_Update [%s]", rc
== 0 ? "SUCCESS" : "FAILED");
319 void CLI_UpdatePercent(int Pos
)
325 Len
= (int)sprintf_s(szBuf
, sizeof(szBuf
), "%d", Pos
* 100 / PT_FINISH
);
326 fopen_s(&File
, VENTOY_CLI_PERCENT
, "w+");
329 fwrite(szBuf
, 1, Len
, File
);
330 fwrite("\n", 1, 1, File
);
335 static void CLI_WriteDoneFile(int ret
)
339 fopen_s(&File
, VENTOY_CLI_DONE
, "w+");
344 fwrite("0\n", 1, 2, File
);
348 fwrite("1\n", 1, 2, File
);
355 * Ventoy2Disk.exe VTOYCLI { /I | /U } { /Drive:F: | /PhyDrive:1 } /GPT /NoSB /R:4096 /NoUSBCheck
358 int VentoyCLIMain(int argc
, char** argv
)
361 PHY_DRIVE_INFO
* pDrvInfo
= NULL
;
364 DeleteFileA(VENTOY_CLI_PERCENT
);
365 DeleteFileA(VENTOY_CLI_DONE
);
367 pDrvInfo
= (PHY_DRIVE_INFO
*)malloc(sizeof(PHY_DRIVE_INFO
));
372 memset(pDrvInfo
, 0, sizeof(PHY_DRIVE_INFO
));
374 if (CLI_CheckParam(argc
, argv
, pDrvInfo
, &CliCfg
))
379 //Check USB type for install
380 if (CliCfg
.op
== 0 && CliCfg
.USBCheck
)
382 if (pDrvInfo
->BusType
!= BusTypeUsb
)
384 Log("[ERROR] PhyDrive %d is NOT USB type", pDrvInfo
->PhyDrive
);
391 ret
= Ventoy_CLI_Install(pDrvInfo
, &CliCfg
);
395 if (pDrvInfo
->VentoyVersion
[0] == 0)
397 Log("[ERROR] No Ventoy information detected in PhyDrive %d, so can not do update", pDrvInfo
->PhyDrive
);
401 ret
= Ventoy_CLI_Update(pDrvInfo
, &CliCfg
);
405 CHECK_FREE(pDrvInfo
);
407 CLI_UpdatePercent(PT_FINISH
);
408 CLI_WriteDoneFile(ret
);