]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - Ventoy2Disk/Ventoy2Disk/DiskService_vds.c
Add timeout option for auto_install/persistence plugin (#1161)
[Ventoy.git] / Ventoy2Disk / Ventoy2Disk / DiskService_vds.c
1 /******************************************************************************
2 * DiskService_vds.c
3 *
4 * Copyright (c) 2021, longpanda <admin@ventoy.net>
5 * Copyright (c) 2011-2020, Pete Batard <pete@akeo.ie>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 3 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22 #include <Windows.h>
23 #include <winternl.h>
24 #include <commctrl.h>
25 #include <initguid.h>
26 #include <vds.h>
27 #include "Ventoy2Disk.h"
28 #include "DiskService.h"
29
30
31 #define INTF_ADVANCEDDISK 1
32 #define INTF_ADVANCEDDISK2 2
33 #define INTF_CREATEPARTITIONEX 3
34
35 /*
36 * Some code and functions in the file are copied from rufus.
37 * https://github.com/pbatard/rufus
38 */
39 #define VDS_SET_ERROR SetLastError
40 #define IVdsServiceLoader_LoadService(This, pwszMachineName, ppService) (This)->lpVtbl->LoadService(This, pwszMachineName, ppService)
41 #define IVdsServiceLoader_Release(This) (This)->lpVtbl->Release(This)
42 #define IVdsService_QueryProviders(This, masks, ppEnum) (This)->lpVtbl->QueryProviders(This, masks, ppEnum)
43 #define IVdsService_WaitForServiceReady(This) ((This)->lpVtbl->WaitForServiceReady(This))
44 #define IVdsService_CleanupObsoleteMountPoints(This) ((This)->lpVtbl->CleanupObsoleteMountPoints(This))
45 #define IVdsService_Refresh(This) ((This)->lpVtbl->Refresh(This))
46 #define IVdsService_Reenumerate(This) ((This)->lpVtbl->Reenumerate(This))
47 #define IVdsSwProvider_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
48 #define IVdsProvider_Release(This) (This)->lpVtbl->Release(This)
49 #define IVdsSwProvider_QueryPacks(This, ppEnum) (This)->lpVtbl->QueryPacks(This, ppEnum)
50 #define IVdsSwProvider_Release(This) (This)->lpVtbl->Release(This)
51 #define IVdsPack_QueryDisks(This, ppEnum) (This)->lpVtbl->QueryDisks(This, ppEnum)
52 #define IVdsDisk_GetProperties(This, pDiskProperties) (This)->lpVtbl->GetProperties(This, pDiskProperties)
53 #define IVdsDisk_Release(This) (This)->lpVtbl->Release(This)
54 #define IVdsDisk_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
55 #define IVdsAdvancedDisk_QueryPartitions(This, ppPartitionPropArray, plNumberOfPartitions) (This)->lpVtbl->QueryPartitions(This, ppPartitionPropArray, plNumberOfPartitions)
56 #define IVdsAdvancedDisk_DeletePartition(This, ullOffset, bForce, bForceProtected) (This)->lpVtbl->DeletePartition(This, ullOffset, bForce, bForceProtected)
57 #define IVdsAdvancedDisk_ChangeAttributes(This, ullOffset, para) (This)->lpVtbl->ChangeAttributes(This, ullOffset, para)
58 #define IVdsAdvancedDisk_CreatePartition(This, ullOffset, ullSize, para, ppAsync) (This)->lpVtbl->CreatePartition(This, ullOffset, ullSize, para, ppAsync)
59 #define IVdsAdvancedDisk_Clean(This, bForce, bForceOEM, bFullClean, ppAsync) (This)->lpVtbl->Clean(This, bForce, bForceOEM, bFullClean, ppAsync)
60 #define IVdsAdvancedDisk_Release(This) (This)->lpVtbl->Release(This)
61
62 #define IVdsAdvancedDisk2_ChangePartitionType(This, ullOffset, bForce, para) (This)->lpVtbl->ChangePartitionType(This, ullOffset, bForce, para)
63 #define IVdsAdvancedDisk2_Release(This) (This)->lpVtbl->Release(This)
64
65 #define IVdsCreatePartitionEx_CreatePartitionEx(This, ullOffset, ullSize, ulAlign, para, ppAsync) (This)->lpVtbl->CreatePartitionEx(This, ullOffset, ullSize, ulAlign, para, ppAsync)
66 #define IVdsCreatePartitionEx_Release(This) (This)->lpVtbl->Release(This)
67 #define IEnumVdsObject_Next(This, celt, ppObjectArray, pcFetched) (This)->lpVtbl->Next(This, celt, ppObjectArray, pcFetched)
68 #define IVdsPack_QueryVolumes(This, ppEnum) (This)->lpVtbl->QueryVolumes(This, ppEnum)
69 #define IVdsVolume_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
70 #define IVdsVolume_Release(This) (This)->lpVtbl->Release(This)
71 #define IVdsVolumeMF3_QueryVolumeGuidPathnames(This, pwszPathArray, pulNumberOfPaths) (This)->lpVtbl->QueryVolumeGuidPathnames(This,pwszPathArray,pulNumberOfPaths)
72 #define IVdsVolumeMF3_FormatEx2(This, pwszFileSystemTypeName, usFileSystemRevision, ulDesiredUnitAllocationSize, pwszLabel, Options, ppAsync) (This)->lpVtbl->FormatEx2(This, pwszFileSystemTypeName, usFileSystemRevision, ulDesiredUnitAllocationSize, pwszLabel, Options, ppAsync)
73 #define IVdsVolumeMF3_Release(This) (This)->lpVtbl->Release(This)
74 #define IVdsVolume_GetProperties(This, pVolumeProperties) (This)->lpVtbl->GetProperties(This,pVolumeProperties)
75 #define IVdsAsync_Cancel(This) (This)->lpVtbl->Cancel(This)
76 #define IVdsAsync_QueryStatus(This,pHrResult,pulPercentCompleted) (This)->lpVtbl->QueryStatus(This,pHrResult,pulPercentCompleted)
77 #define IVdsAsync_Wait(This,pHrResult,pAsyncOut) (This)->lpVtbl->Wait(This,pHrResult,pAsyncOut)
78 #define IVdsAsync_Release(This) (This)->lpVtbl->Release(This)
79
80 #define IUnknown_QueryInterface(This, a, b) (This)->lpVtbl->QueryInterface(This,a,b)
81 #define IUnknown_Release(This) (This)->lpVtbl->Release(This)
82
83 typedef BOOL(*VDS_Callback_PF)(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data);
84
85 STATIC IVdsService * VDS_InitService(void)
86 {
87 HRESULT hr;
88 IVdsServiceLoader *pLoader;
89 IVdsService *pService;
90
91 // Initialize COM
92 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
93 CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL);
94
95 // Create a VDS Loader Instance
96 hr = CoCreateInstance(&CLSID_VdsLoader, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, &IID_IVdsServiceLoader, (void **)&pLoader);
97 if (hr != S_OK)
98 {
99 VDS_SET_ERROR(hr);
100 Log("Could not create VDS Loader Instance: %u", LASTERR);
101 return NULL;
102 }
103
104 // Load the VDS Service
105 hr = IVdsServiceLoader_LoadService(pLoader, L"", &pService);
106 IVdsServiceLoader_Release(pLoader);
107 if (hr != S_OK)
108 {
109 VDS_SET_ERROR(hr);
110 Log("Could not load VDS Service: %u", LASTERR);
111 return NULL;
112 }
113
114 // Wait for the Service to become ready if needed
115 hr = IVdsService_WaitForServiceReady(pService);
116 if (hr != S_OK)
117 {
118 VDS_SET_ERROR(hr);
119 Log("VDS Service is not ready: %u", LASTERR);
120 return NULL;
121 }
122
123 Log("VDS init OK, service %p", pService);
124 return pService;
125 }
126
127
128 STATIC BOOL VDS_DiskCommProc(int intf, int DriveIndex, VDS_Callback_PF callback, UINT64 data)
129 {
130 BOOL r = FALSE;
131 HRESULT hr;
132 ULONG ulFetched;
133 IUnknown *pUnk = NULL;
134 IEnumVdsObject *pEnum = NULL;
135 IVdsService *pService = NULL;
136 wchar_t wPhysicalName[48];
137
138 swprintf_s(wPhysicalName, ARRAYSIZE(wPhysicalName), L"\\\\?\\PhysicalDrive%d", DriveIndex);
139
140 pService = VDS_InitService();
141 if (!pService)
142 {
143 Log("Could not query VDS Service");
144 goto out;
145 }
146
147 // Query the VDS Service Providers
148 hr = IVdsService_QueryProviders(pService, VDS_QUERY_SOFTWARE_PROVIDERS, &pEnum);
149 if (hr != S_OK)
150 {
151 VDS_SET_ERROR(hr);
152 Log("Could not query VDS Service Providers: 0x%lx %u", hr, LASTERR);
153 goto out;
154 }
155
156 while (IEnumVdsObject_Next(pEnum, 1, &pUnk, &ulFetched) == S_OK)
157 {
158 IVdsProvider *pProvider;
159 IVdsSwProvider *pSwProvider;
160 IEnumVdsObject *pEnumPack;
161 IUnknown *pPackUnk;
162
163 // Get VDS Provider
164 hr = IUnknown_QueryInterface(pUnk, &IID_IVdsProvider, (void **)&pProvider);
165 IUnknown_Release(pUnk);
166 if (hr != S_OK)
167 {
168 VDS_SET_ERROR(hr);
169 Log("Could not get VDS Provider: %u", LASTERR);
170 goto out;
171 }
172
173 // Get VDS Software Provider
174 hr = IVdsSwProvider_QueryInterface(pProvider, &IID_IVdsSwProvider, (void **)&pSwProvider);
175 IVdsProvider_Release(pProvider);
176 if (hr != S_OK)
177 {
178 VDS_SET_ERROR(hr);
179 Log("Could not get VDS Software Provider: %u", LASTERR);
180 goto out;
181 }
182
183 // Get VDS Software Provider Packs
184 hr = IVdsSwProvider_QueryPacks(pSwProvider, &pEnumPack);
185 IVdsSwProvider_Release(pSwProvider);
186 if (hr != S_OK)
187 {
188 VDS_SET_ERROR(hr);
189 Log("Could not get VDS Software Provider Packs: %u", LASTERR);
190 goto out;
191 }
192
193 // Enumerate Provider Packs
194 while (IEnumVdsObject_Next(pEnumPack, 1, &pPackUnk, &ulFetched) == S_OK)
195 {
196 IVdsPack *pPack;
197 IEnumVdsObject *pEnumDisk;
198 IUnknown *pDiskUnk;
199
200 hr = IUnknown_QueryInterface(pPackUnk, &IID_IVdsPack, (void **)&pPack);
201 IUnknown_Release(pPackUnk);
202 if (hr != S_OK)
203 {
204 VDS_SET_ERROR(hr);
205 Log("Could not query VDS Software Provider Pack: %u", LASTERR);
206 goto out;
207 }
208
209 // Use the pack interface to access the disks
210 hr = IVdsPack_QueryDisks(pPack, &pEnumDisk);
211 if (hr != S_OK) {
212 VDS_SET_ERROR(hr);
213 Log("Could not query VDS disks: %u", LASTERR);
214 goto out;
215 }
216
217 // List disks
218 while (IEnumVdsObject_Next(pEnumDisk, 1, &pDiskUnk, &ulFetched) == S_OK)
219 {
220 VDS_DISK_PROP diskprop;
221 IVdsDisk *pDisk;
222 IVdsAdvancedDisk *pAdvancedDisk;
223 IVdsAdvancedDisk2 *pAdvancedDisk2;
224 IVdsCreatePartitionEx *pCreatePartitionEx;
225
226 // Get the disk interface.
227 hr = IUnknown_QueryInterface(pDiskUnk, &IID_IVdsDisk, (void **)&pDisk);
228 if (hr != S_OK) {
229 VDS_SET_ERROR(hr);
230 Log("Could not query VDS Disk Interface: %u", LASTERR);
231 goto out;
232 }
233
234 // Get the disk properties
235 hr = IVdsDisk_GetProperties(pDisk, &diskprop);
236 if (hr != S_OK) {
237 VDS_SET_ERROR(hr);
238 Log("Could not query VDS Disk Properties: %u", LASTERR);
239 goto out;
240 }
241
242 // Isolate the disk we want
243 if (_wcsicmp(wPhysicalName, diskprop.pwszName) != 0)
244 {
245 IVdsDisk_Release(pDisk);
246 continue;
247 }
248
249 if (intf == INTF_ADVANCEDDISK)
250 {
251 // Instantiate the AdvanceDisk interface for our disk.
252 hr = IVdsDisk_QueryInterface(pDisk, &IID_IVdsAdvancedDisk, (void **)&pAdvancedDisk);
253 IVdsDisk_Release(pDisk);
254 if (hr != S_OK)
255 {
256 VDS_SET_ERROR(hr);
257 Log("Could not access VDS Advanced Disk interface: %u", LASTERR);
258 goto out;
259 }
260 else
261 {
262 Log("Callback %d process for disk <%S>", intf, diskprop.pwszName);
263 r = callback(pAdvancedDisk, &diskprop, data);
264 }
265 IVdsAdvancedDisk_Release(pAdvancedDisk);
266 }
267 else if (intf == INTF_ADVANCEDDISK2)
268 {
269 // Instantiate the AdvanceDisk interface for our disk.
270 hr = IVdsDisk_QueryInterface(pDisk, &IID_IVdsAdvancedDisk2, (void **)&pAdvancedDisk2);
271 IVdsDisk_Release(pDisk);
272 if (hr != S_OK)
273 {
274 VDS_SET_ERROR(hr);
275 Log("Could not access VDS Advanced Disk2 interface: %u", LASTERR);
276 goto out;
277 }
278 else
279 {
280 Log("Callback %d process for disk2 <%S>", intf, diskprop.pwszName);
281 r = callback(pAdvancedDisk2, &diskprop, data);
282 }
283 IVdsAdvancedDisk2_Release(pAdvancedDisk2);
284 }
285 else if (intf == INTF_CREATEPARTITIONEX)
286 {
287 // Instantiate the CreatePartitionEx interface for our disk.
288 hr = IVdsDisk_QueryInterface(pDisk, &IID_IVdsCreatePartitionEx, (void **)&pCreatePartitionEx);
289 IVdsDisk_Release(pDisk);
290 if (hr != S_OK)
291 {
292 VDS_SET_ERROR(hr);
293 Log("Could not access VDS CreatePartitionEx interface: %u", LASTERR);
294 goto out;
295 }
296 else
297 {
298 Log("Callback %d process for disk <%S>", intf, diskprop.pwszName);
299 r = callback(pCreatePartitionEx, &diskprop, data);
300 }
301 IVdsCreatePartitionEx_Release(pCreatePartitionEx);
302 }
303
304 goto out;
305 }
306 }
307 }
308
309 out:
310 return r;
311 }
312
313 STATIC BOOL VDS_CallBack_CleanDisk(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data)
314 {
315 HRESULT hr, hr2;
316 ULONG completed;
317 IVdsAsync* pAsync;
318 IVdsAdvancedDisk *pAdvancedDisk = (IVdsAdvancedDisk *)pInterface;
319
320 (void)pDiskProp;
321 (void)data;
322
323 hr = IVdsAdvancedDisk_Clean(pAdvancedDisk, TRUE, TRUE, FALSE, &pAsync);
324 while (SUCCEEDED(hr))
325 {
326 hr = IVdsAsync_QueryStatus(pAsync, &hr2, &completed);
327 if (SUCCEEDED(hr))
328 {
329 hr = hr2;
330 if (hr == S_OK)
331 {
332 Log("Disk clean QueryStatus OK");
333 break;
334 }
335 else if (hr == VDS_E_OPERATION_PENDING)
336 {
337 hr = S_OK;
338 }
339 else
340 {
341 Log("QueryStatus invalid status:%u", hr);
342 }
343 }
344 Sleep(500);
345 }
346
347 if (hr != S_OK)
348 {
349 VDS_SET_ERROR(hr);
350 Log("Could not clean disk 0x%lx err:%u", hr, LASTERR);
351 return FALSE;
352 }
353
354 return TRUE;
355 }
356
357 BOOL VDS_CleanDisk(int DriveIndex)
358 {
359 BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK, DriveIndex, VDS_CallBack_CleanDisk, 0);
360 Log("VDS_CleanDisk %d ret:%d", DriveIndex, ret);
361 return ret;
362 }
363
364 STATIC BOOL VDS_CallBack_DeletePartition(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data)
365 {
366 BOOL r = FALSE;
367 HRESULT hr;
368 VDS_PARTITION_PROP* prop_array = NULL;
369 LONG i, prop_array_size;
370 ULONG PartNumber = (ULONG)data;
371 IVdsAdvancedDisk *pAdvancedDisk = (IVdsAdvancedDisk *)pInterface;
372
373 if (PartNumber == 0)
374 {
375 Log("Deleting ALL partitions from disk '%S':", pDiskProp->pwszName);
376 }
377 else
378 {
379 Log("Deleting partition(%ld) from disk '%S':", PartNumber, pDiskProp->pwszName);
380 }
381
382 // Query the partition data, so we can get the start offset, which we need for deletion
383 hr = IVdsAdvancedDisk_QueryPartitions(pAdvancedDisk, &prop_array, &prop_array_size);
384 if (hr == S_OK)
385 {
386 for (i = 0; i < prop_array_size; i++)
387 {
388 if (PartNumber == 0 || PartNumber == prop_array[i].ulPartitionNumber)
389 {
390 Log("* Partition %d (offset: %lld, size: %llu) delete it.",
391 prop_array[i].ulPartitionNumber, prop_array[i].ullOffset, (ULONGLONG)prop_array[i].ullSize);
392 }
393 else
394 {
395 Log(" Partition %d (offset: %lld, size: %llu) skip it.",
396 prop_array[i].ulPartitionNumber, prop_array[i].ullOffset, (ULONGLONG)prop_array[i].ullSize);
397 continue;
398 }
399
400 hr = IVdsAdvancedDisk_DeletePartition(pAdvancedDisk, prop_array[i].ullOffset, TRUE, TRUE);
401 if (hr != S_OK)
402 {
403 r = FALSE;
404 VDS_SET_ERROR(hr);
405 Log("Could not delete partitions: %u", LASTERR);
406 }
407 else
408 {
409 Log("Delete this partitions success");
410 }
411 }
412 r = TRUE;
413 }
414 else
415 {
416 Log("No partition to delete on disk '%S'", pDiskProp->pwszName);
417 r = TRUE;
418 }
419 CoTaskMemFree(prop_array);
420
421 return r;
422 }
423
424 BOOL VDS_DeleteAllPartitions(int DriveIndex)
425 {
426 BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK, DriveIndex, VDS_CallBack_DeletePartition, 0);
427 Log("VDS_DeleteAllPartitions %d ret:%d", DriveIndex, ret);
428 return ret;
429 }
430
431 BOOL VDS_DeleteVtoyEFIPartition(int DriveIndex)
432 {
433 BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK, DriveIndex, VDS_CallBack_DeletePartition, 2);
434 Log("VDS_DeleteVtoyEFIPartition %d ret:%d", DriveIndex, ret);
435 return ret;
436 }
437
438 STATIC BOOL VDS_CallBack_ChangeEFIAttr(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data)
439 {
440 BOOL r = FALSE;
441 HRESULT hr;
442 VDS_PARTITION_PROP* prop_array = NULL;
443 LONG i, prop_array_size;
444 CHANGE_ATTRIBUTES_PARAMETERS AttrPara;
445 IVdsAdvancedDisk *pAdvancedDisk = (IVdsAdvancedDisk *)pInterface;
446
447 // Query the partition data, so we can get the start offset, which we need for deletion
448 hr = IVdsAdvancedDisk_QueryPartitions(pAdvancedDisk, &prop_array, &prop_array_size);
449 if (hr == S_OK)
450 {
451 for (i = 0; i < prop_array_size; i++)
452 {
453 if (prop_array[i].ullSize == VENTOY_EFI_PART_SIZE &&
454 prop_array[i].PartitionStyle == VDS_PST_GPT &&
455 memcmp(prop_array[i].Gpt.name, L"VTOYEFI", 7 * 2) == 0)
456 {
457 Log("* Partition %d (offset: %lld, size: %llu, Attr:0x%llx)", prop_array[i].ulPartitionNumber,
458 prop_array[i].ullOffset, (ULONGLONG)prop_array[i].ullSize, prop_array[i].Gpt.attributes);
459
460 if (prop_array[i].Gpt.attributes == data)
461 {
462 Log("Attribute match, No need to change.");
463 r = TRUE;
464 }
465 else
466 {
467 AttrPara.style = VDS_PST_GPT;
468 AttrPara.GptPartInfo.attributes = data;
469 hr = IVdsAdvancedDisk_ChangeAttributes(pAdvancedDisk, prop_array[i].ullOffset, &AttrPara);
470 if (hr == S_OK)
471 {
472 r = TRUE;
473 Log("Change this partitions attribute success");
474 }
475 else
476 {
477 r = FALSE;
478 VDS_SET_ERROR(hr);
479 Log("Could not change partitions attr: %u", LASTERR);
480 }
481 }
482 break;
483 }
484 }
485 }
486 else
487 {
488 Log("No partition found on disk '%S'", pDiskProp->pwszName);
489 }
490 CoTaskMemFree(prop_array);
491
492 return r;
493 }
494
495 BOOL VDS_ChangeVtoyEFIAttr(int DriveIndex, UINT64 Attr)
496 {
497 BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK, DriveIndex, VDS_CallBack_ChangeEFIAttr, Attr);
498 Log("VDS_ChangeVtoyEFIAttr %d ret:%d", DriveIndex, ret);
499 return ret;
500 }
501
502
503
504 STATIC BOOL VDS_CallBack_ChangeEFIType(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data)
505 {
506 BOOL r = FALSE;
507 HRESULT hr;
508 IVdsAdvancedDisk2 *pAdvancedDisk2 = (IVdsAdvancedDisk2 *)pInterface;
509 VDS_PARA *VdsPara = (VDS_PARA *)(ULONG)data;
510 CHANGE_PARTITION_TYPE_PARAMETERS para;
511
512 para.style = VDS_PST_GPT;
513 memcpy(&(para.GptPartInfo.partitionType), &VdsPara->Type, sizeof(GUID));
514
515 hr = IVdsAdvancedDisk2_ChangePartitionType(pAdvancedDisk2, VdsPara->Offset, TRUE, &para);
516 if (hr == S_OK)
517 {
518 r = TRUE;
519 }
520 else
521 {
522 Log("Failed to change partition type 0x%lx", hr);
523 }
524
525 return r;
526 }
527
528
529 BOOL VDS_ChangeVtoyEFI2ESP(int DriveIndex, UINT64 Offset)
530 {
531 VDS_PARA Para;
532 GUID EspPartType = { 0xc12a7328, 0xf81f, 0x11d2, { 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } };
533
534 memcpy(&(Para.Type), &EspPartType, sizeof(GUID));
535 Para.Offset = Offset;
536
537 BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK2, DriveIndex, VDS_CallBack_ChangeEFIType, (ULONG)&Para);
538 Log("VDS_ChangeVtoyEFI2ESP %d ret:%d", DriveIndex, ret);
539 return ret;
540 }
541
542 BOOL VDS_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset)
543 {
544 VDS_PARA Para;
545 GUID WindowsDataPartType = { 0xebd0a0a2, 0xb9e5, 0x4433, { 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7 } };
546
547 memcpy(&(Para.Type), &WindowsDataPartType, sizeof(GUID));
548 Para.Offset = Offset;
549
550 BOOL ret = VDS_DiskCommProc(INTF_ADVANCEDDISK2, DriveIndex, VDS_CallBack_ChangeEFIType, (ULONG)&Para);
551 Log("VDS_ChangeVtoyEFI2ESP %d ret:%d", DriveIndex, ret);
552 return ret;
553 }
554
555
556 STATIC BOOL VDS_CallBack_CreateVtoyEFI(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data)
557 {
558 HRESULT hr, hr2;
559 ULONG completed;
560 IVdsAsync* pAsync;
561 CREATE_PARTITION_PARAMETERS para;
562 IVdsCreatePartitionEx *pCreatePartitionEx = (IVdsCreatePartitionEx *)pInterface;
563 VDS_PARA *VdsPara = (VDS_PARA *)(ULONG)data;
564
565 (void)pDiskProp;
566
567 memset(&para, 0, sizeof(para));
568 para.style = VDS_PST_GPT;
569 memcpy(&(para.GptPartInfo.partitionType), &VdsPara->Type, sizeof(GUID));
570 memcpy(&(para.GptPartInfo.partitionId), &VdsPara->Id, sizeof(GUID));
571 para.GptPartInfo.attributes = VdsPara->Attr;
572 memcpy(para.GptPartInfo.name, VdsPara->Name, sizeof(WCHAR)* VdsPara->NameLen);
573
574 hr = IVdsCreatePartitionEx_CreatePartitionEx(pCreatePartitionEx, VdsPara->Offset, VENTOY_EFI_PART_SIZE, 512, &para, &pAsync);
575 while (SUCCEEDED(hr))
576 {
577 hr = IVdsAsync_QueryStatus(pAsync, &hr2, &completed);
578 if (SUCCEEDED(hr))
579 {
580 hr = hr2;
581 if (hr == S_OK)
582 {
583 Log("Disk create partition QueryStatus OK, %lu%%", completed);
584 break;
585 }
586 else if (hr == VDS_E_OPERATION_PENDING)
587 {
588 Log("Disk partition finish: %lu%%", completed);
589 hr = S_OK;
590 }
591 else
592 {
593 Log("QueryStatus invalid status:0x%lx", hr);
594 }
595 }
596 Sleep(1000);
597 }
598
599 if (hr != S_OK)
600 {
601 VDS_SET_ERROR(hr);
602 Log("Could not create partition, err:0x%lx", LASTERR);
603 return FALSE;
604 }
605
606 return TRUE;
607 }
608
609 BOOL VDS_CreateVtoyEFIPart(int DriveIndex, UINT64 Offset)
610 {
611 VDS_PARA Para;
612 GUID WindowsDataPartType = { 0xebd0a0a2, 0xb9e5, 0x4433, { 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7 } };
613 GUID EspPartType = { 0xc12a7328, 0xf81f, 0x11d2, { 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } };
614
615 Log("VDS_CreateVtoyEFIPart %u Offset:%llu Sector:%llu", DriveIndex, Offset, Offset / 512);
616
617 memset(&Para, 0, sizeof(Para));
618 Para.Attr = 0x8000000000000000ULL;
619 Para.Offset = Offset;
620 memcpy(Para.Name, L"VTOYEFI", 7 * 2);
621 Para.NameLen = 7;
622 memcpy(&(Para.Type), &EspPartType, sizeof(GUID));
623 CoCreateGuid(&(Para.Id));
624
625 BOOL ret = VDS_DiskCommProc(INTF_CREATEPARTITIONEX, DriveIndex, VDS_CallBack_CreateVtoyEFI, (ULONG)&Para);
626 Log("VDS_CreateVtoyEFIPart %d ret:%d", DriveIndex, ret);
627 return ret;
628 }
629