1 /******************************************************************************
4 * Copyright (c) 2021, longpanda <admin@ventoy.net>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 3 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
26 #include <VersionHelpers.h>
27 #include "Ventoy2Disk.h"
28 #include "DiskService.h"
30 STATIC BOOL
IsPowershellExist(void)
34 ret
= IsFileExist("%s\\system32\\WindowsPowerShell\\v1.0\\powershell.exe", DISK_GetWindowsDir());
37 Log("powershell.exe not exist");
43 int PSHELL_GetPartitionNumber(int PhyDrive
, UINT64 Offset
)
52 DRIVE_LAYOUT_INFORMATION_EX
*pDriveLayout
= NULL
;
54 Log("PSHELL_GetPartitionNumber PhyDrive:%d Offset:%llu", PhyDrive
, Offset
);
56 hDrive
= GetPhysicalHandle(PhyDrive
, FALSE
, FALSE
, FALSE
);
57 if (hDrive
== INVALID_HANDLE_VALUE
)
62 BufLen
= (DWORD
)(sizeof(PARTITION_INFORMATION_EX
)* 256);
64 pDriveLayout
= malloc(BufLen
);
69 memset(pDriveLayout
, 0, BufLen
);
71 bRet
= DeviceIoControl(hDrive
,
72 IOCTL_DISK_GET_DRIVE_LAYOUT_EX
, NULL
,
80 Log("Failed to ioctrl get drive layout ex %u", LASTERR
);
84 Log("PhyDrive:%d PartitionStyle=%s PartitionCount=%u", PhyDrive
,
85 (pDriveLayout
->PartitionStyle
== PARTITION_STYLE_MBR
) ? "MBR" : "GPT", pDriveLayout
->PartitionCount
);
87 for (i
= 0; i
< pDriveLayout
->PartitionCount
; i
++)
89 PartStart
= pDriveLayout
->PartitionEntry
[i
].StartingOffset
.QuadPart
;
90 if (PartStart
== (LONGLONG
)Offset
)
92 Log("[*] [%d] PartitionNumber=%u Offset=%lld Length=%lld ",
94 pDriveLayout
->PartitionEntry
[i
].PartitionNumber
,
95 pDriveLayout
->PartitionEntry
[i
].StartingOffset
.QuadPart
,
96 pDriveLayout
->PartitionEntry
[i
].PartitionLength
.QuadPart
98 partnum
= (int)pDriveLayout
->PartitionEntry
[i
].PartitionNumber
;
102 Log("[ ] [%d] PartitionNumber=%u Offset=%lld Length=%lld ",
104 pDriveLayout
->PartitionEntry
[i
].PartitionNumber
,
105 pDriveLayout
->PartitionEntry
[i
].StartingOffset
.QuadPart
,
106 pDriveLayout
->PartitionEntry
[i
].PartitionLength
.QuadPart
113 CHECK_CLOSE_HANDLE(hDrive
);
114 CHECK_FREE(pDriveLayout
);
120 STATIC BOOL
PSHELL_CommProc(const char *Cmd
)
124 PROCESS_INFORMATION Pi
;
126 if (!IsPowershellExist())
131 GetStartupInfoA(&Si
);
132 Si
.dwFlags
|= STARTF_USESHOWWINDOW
;
133 Si
.wShowWindow
= SW_HIDE
;
135 sprintf_s(CmdBuf
, sizeof(CmdBuf
), "C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe -Command \"&{ %s }\"", Cmd
);
137 Log("CreateProcess <%s>", CmdBuf
);
138 CreateProcessA(NULL
, CmdBuf
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &Si
, &Pi
);
140 Log("Wair process ...");
141 WaitForSingleObject(Pi
.hProcess
, INFINITE
);
142 Log("Process finished...");
144 CHECK_CLOSE_HANDLE(Pi
.hProcess
);
145 CHECK_CLOSE_HANDLE(Pi
.hThread
);
151 BOOL
PSHELL_CleanDisk(int DriveIndex
)
156 sprintf_s(CmdBuf
, sizeof(CmdBuf
), "Clear-Disk -Number %d -RemoveData -RemoveOEM -Confirm:$false", DriveIndex
);
157 ret
= PSHELL_CommProc(CmdBuf
);
158 Log("CleanDiskByPowershell<%d> ret:%d (%s)", DriveIndex
, ret
, ret
? "SUCCESS" : "FAIL");
164 BOOL
PSHELL_DeleteVtoyEFIPartition(int DriveIndex
, UINT64 EfiPartOffset
)
170 Part
= PSHELL_GetPartitionNumber(DriveIndex
, EfiPartOffset
);
177 sprintf_s(CmdBuf
, sizeof(CmdBuf
), "Remove-Partition -DiskNumber %d -PartitionNumber %d -Confirm:$false", DriveIndex
, Part
);
178 ret
= PSHELL_CommProc(CmdBuf
);
181 Log("PSHELL_DeleteVtoyEFIPartition<%d> ret:%d (%s)", DriveIndex
, ret
, ret
? "SUCCESS" : "FAIL");
186 BOOL
PSHELL_ChangeVtoyEFI2ESP(int DriveIndex
, UINT64 Offset
)
192 Part
= PSHELL_GetPartitionNumber(DriveIndex
, Offset
);
199 sprintf_s(CmdBuf
, sizeof(CmdBuf
), "Set-Partition -DiskNumber %d -PartitionNumber %d -gpttype '{C12A7328-F81F-11D2-BA4B-00A0C93EC93B}' -Confirm:$false", DriveIndex
, Part
);
200 ret
= PSHELL_CommProc(CmdBuf
);
203 Log("PSHELL_ChangeVtoyEFI2ESP<%d> ret:%d (%s)", DriveIndex
, ret
, ret
? "SUCCESS" : "FAIL");
208 BOOL
PSHELL_ChangeVtoyEFI2Basic(int DriveIndex
, UINT64 Offset
)
214 Part
= PSHELL_GetPartitionNumber(DriveIndex
, Offset
);
221 sprintf_s(CmdBuf
, sizeof(CmdBuf
), "Set-Partition -DiskNumber %d -PartitionNumber %d -gpttype '{ebd0a0a2-b9e5-4433-87c0-68b6b72699c7}' -Confirm:$false", DriveIndex
, Part
);
222 ret
= PSHELL_CommProc(CmdBuf
);
225 Log("PSHELL_ChangeVtoyEFI2Basic<%d> ret:%d (%s)", DriveIndex
, ret
, ret
? "SUCCESS" : "FAIL");
229 BOOL
PSHELL_ShrinkVolume(int DriveIndex
, const char* VolumeGuid
, CHAR DriveLetter
, UINT64 OldBytes
, UINT64 ReduceBytes
)
237 Part
= PSHELL_GetPartitionNumber(DriveIndex
, SIZE_1MB
);
244 sprintf_s(CmdBuf
, sizeof(CmdBuf
), "Resize-Partition -DiskNumber %d -PartitionNumber %d -Size %llu -Confirm:$false",
245 DriveIndex
, Part
, OldBytes
- ReduceBytes
);
246 ret
= PSHELL_CommProc(CmdBuf
);
249 Log("PSHELL_ShrinkVolume<%d> %C: ret:%d (%s)", DriveIndex
, DriveLetter
, ret
, ret
? "SUCCESS" : "FAIL");
253 BOOL
PSHELL_FormatVolume(char DriveLetter
, int fs
, DWORD ClusterSize
)
256 const char* fsname
= NULL
;
260 fsname
= GetVentoyFsFmtNameByTypeA(fs
);
264 sprintf_s(CmdBuf
, sizeof(CmdBuf
),
265 "format-volume -DriveLetter %C -FileSystem %s -AllocationUnitSize %u -Force -NewFileSystemLabel Ventoy",
266 DriveLetter
, fsname
, ClusterSize
);
270 sprintf_s(CmdBuf
, sizeof(CmdBuf
),
271 "format-volume -DriveLetter %C -FileSystem %s -Force -NewFileSystemLabel Ventoy",
272 DriveLetter
, fsname
);
275 ret
= PSHELL_CommProc(CmdBuf
);
276 Log("PSHELL_FormatVolume %C: ret:%d (%s)", DriveLetter
, ret
, ret
? "SUCCESS" : "FAIL");
283 sprintf_s(CmdBuf
, sizeof(CmdBuf
), "%C:\\", DriveLetter
);
284 GetVolumeInformationA(CmdBuf
, NULL
, 0, NULL
, NULL
, NULL
, FsName
, sizeof(FsName
));
285 VentoyStringToUpper(FsName
);
287 Log("New fs name after run PSHELL:<%s>", FsName
);
289 if (strcmp(FsName
, fsname
) == 0)
291 Log("PSHELL_FormatVolume <%C:> SUCCESS", DriveLetter
);
296 Log("PSHELL_FormatVolume <%C:> FAILED", DriveLetter
);