1 /******************************************************************************
4 * Copyright (c) 2021, longpanda <admin@ventoy.net>
5 * Copyright (c) 2011-2020, Pete Batard <pete@akeo.ie>
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.
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.
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/>.
27 #include "Ventoy2Disk.h"
28 #include "DiskService.h"
31 #define INTF_ADVANCEDDISK 1
32 #define INTF_ADVANCEDDISK2 2
33 #define INTF_CREATEPARTITIONEX 3
36 * Some code and functions in the file are copied from rufus.
37 * https://github.com/pbatard/rufus
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)
62 #define IVdsAdvancedDisk2_ChangePartitionType(This, ullOffset, bForce, para) (This)->lpVtbl->ChangePartitionType(This, ullOffset, bForce, para)
63 #define IVdsAdvancedDisk2_Release(This) (This)->lpVtbl->Release(This)
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)
80 #define IUnknown_QueryInterface(This, a, b) (This)->lpVtbl->QueryInterface(This,a,b)
81 #define IUnknown_Release(This) (This)->lpVtbl->Release(This)
83 typedef BOOL(*VDS_Callback_PF
)(void *pInterface
, VDS_DISK_PROP
*pDiskProp
, UINT64 data
);
85 STATIC IVdsService
* VDS_InitService(void)
88 IVdsServiceLoader
*pLoader
;
89 IVdsService
*pService
;
92 CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
93 CoInitializeSecurity(NULL
, -1, NULL
, NULL
, RPC_C_AUTHN_LEVEL_CONNECT
, RPC_C_IMP_LEVEL_IMPERSONATE
, NULL
, 0, NULL
);
95 // Create a VDS Loader Instance
96 hr
= CoCreateInstance(&CLSID_VdsLoader
, NULL
, CLSCTX_LOCAL_SERVER
| CLSCTX_REMOTE_SERVER
, &IID_IVdsServiceLoader
, (void **)&pLoader
);
100 Log("Could not create VDS Loader Instance: %u", LASTERR
);
104 // Load the VDS Service
105 hr
= IVdsServiceLoader_LoadService(pLoader
, L
"", &pService
);
106 IVdsServiceLoader_Release(pLoader
);
110 Log("Could not load VDS Service: %u", LASTERR
);
114 // Wait for the Service to become ready if needed
115 hr
= IVdsService_WaitForServiceReady(pService
);
119 Log("VDS Service is not ready: %u", LASTERR
);
123 Log("VDS init OK, service %p", pService
);
128 STATIC BOOL
VDS_DiskCommProc(int intf
, int DriveIndex
, VDS_Callback_PF callback
, UINT64 data
)
133 IUnknown
*pUnk
= NULL
;
134 IEnumVdsObject
*pEnum
= NULL
;
135 IVdsService
*pService
= NULL
;
136 wchar_t wPhysicalName
[48];
138 swprintf_s(wPhysicalName
, ARRAYSIZE(wPhysicalName
), L
"\\\\?\\PhysicalDrive%d", DriveIndex
);
140 pService
= VDS_InitService();
143 Log("Could not query VDS Service");
147 // Query the VDS Service Providers
148 hr
= IVdsService_QueryProviders(pService
, VDS_QUERY_SOFTWARE_PROVIDERS
, &pEnum
);
152 Log("Could not query VDS Service Providers: 0x%lx %u", hr
, LASTERR
);
156 while (IEnumVdsObject_Next(pEnum
, 1, &pUnk
, &ulFetched
) == S_OK
)
158 IVdsProvider
*pProvider
;
159 IVdsSwProvider
*pSwProvider
;
160 IEnumVdsObject
*pEnumPack
;
164 hr
= IUnknown_QueryInterface(pUnk
, &IID_IVdsProvider
, (void **)&pProvider
);
165 IUnknown_Release(pUnk
);
169 Log("Could not get VDS Provider: %u", LASTERR
);
173 // Get VDS Software Provider
174 hr
= IVdsSwProvider_QueryInterface(pProvider
, &IID_IVdsSwProvider
, (void **)&pSwProvider
);
175 IVdsProvider_Release(pProvider
);
179 Log("Could not get VDS Software Provider: %u", LASTERR
);
183 // Get VDS Software Provider Packs
184 hr
= IVdsSwProvider_QueryPacks(pSwProvider
, &pEnumPack
);
185 IVdsSwProvider_Release(pSwProvider
);
189 Log("Could not get VDS Software Provider Packs: %u", LASTERR
);
193 // Enumerate Provider Packs
194 while (IEnumVdsObject_Next(pEnumPack
, 1, &pPackUnk
, &ulFetched
) == S_OK
)
197 IEnumVdsObject
*pEnumDisk
;
200 hr
= IUnknown_QueryInterface(pPackUnk
, &IID_IVdsPack
, (void **)&pPack
);
201 IUnknown_Release(pPackUnk
);
205 Log("Could not query VDS Software Provider Pack: %u", LASTERR
);
209 // Use the pack interface to access the disks
210 hr
= IVdsPack_QueryDisks(pPack
, &pEnumDisk
);
213 Log("Could not query VDS disks: %u", LASTERR
);
218 while (IEnumVdsObject_Next(pEnumDisk
, 1, &pDiskUnk
, &ulFetched
) == S_OK
)
220 VDS_DISK_PROP diskprop
;
222 IVdsAdvancedDisk
*pAdvancedDisk
;
223 IVdsAdvancedDisk2
*pAdvancedDisk2
;
224 IVdsCreatePartitionEx
*pCreatePartitionEx
;
226 // Get the disk interface.
227 hr
= IUnknown_QueryInterface(pDiskUnk
, &IID_IVdsDisk
, (void **)&pDisk
);
230 Log("Could not query VDS Disk Interface: %u", LASTERR
);
234 // Get the disk properties
235 hr
= IVdsDisk_GetProperties(pDisk
, &diskprop
);
238 Log("Could not query VDS Disk Properties: %u", LASTERR
);
242 // Isolate the disk we want
243 if (_wcsicmp(wPhysicalName
, diskprop
.pwszName
) != 0)
245 IVdsDisk_Release(pDisk
);
249 if (intf
== INTF_ADVANCEDDISK
)
251 // Instantiate the AdvanceDisk interface for our disk.
252 hr
= IVdsDisk_QueryInterface(pDisk
, &IID_IVdsAdvancedDisk
, (void **)&pAdvancedDisk
);
253 IVdsDisk_Release(pDisk
);
257 Log("Could not access VDS Advanced Disk interface: %u", LASTERR
);
262 Log("Callback %d process for disk <%S>", intf
, diskprop
.pwszName
);
263 r
= callback(pAdvancedDisk
, &diskprop
, data
);
265 IVdsAdvancedDisk_Release(pAdvancedDisk
);
267 else if (intf
== INTF_ADVANCEDDISK2
)
269 // Instantiate the AdvanceDisk interface for our disk.
270 hr
= IVdsDisk_QueryInterface(pDisk
, &IID_IVdsAdvancedDisk2
, (void **)&pAdvancedDisk2
);
271 IVdsDisk_Release(pDisk
);
275 Log("Could not access VDS Advanced Disk2 interface: %u", LASTERR
);
280 Log("Callback %d process for disk2 <%S>", intf
, diskprop
.pwszName
);
281 r
= callback(pAdvancedDisk2
, &diskprop
, data
);
283 IVdsAdvancedDisk2_Release(pAdvancedDisk2
);
285 else if (intf
== INTF_CREATEPARTITIONEX
)
287 // Instantiate the CreatePartitionEx interface for our disk.
288 hr
= IVdsDisk_QueryInterface(pDisk
, &IID_IVdsCreatePartitionEx
, (void **)&pCreatePartitionEx
);
289 IVdsDisk_Release(pDisk
);
293 Log("Could not access VDS CreatePartitionEx interface: %u", LASTERR
);
298 Log("Callback %d process for disk <%S>", intf
, diskprop
.pwszName
);
299 r
= callback(pCreatePartitionEx
, &diskprop
, data
);
301 IVdsCreatePartitionEx_Release(pCreatePartitionEx
);
313 STATIC BOOL
VDS_CallBack_CleanDisk(void *pInterface
, VDS_DISK_PROP
*pDiskProp
, UINT64 data
)
318 IVdsAdvancedDisk
*pAdvancedDisk
= (IVdsAdvancedDisk
*)pInterface
;
323 hr
= IVdsAdvancedDisk_Clean(pAdvancedDisk
, TRUE
, TRUE
, FALSE
, &pAsync
);
324 while (SUCCEEDED(hr
))
326 hr
= IVdsAsync_QueryStatus(pAsync
, &hr2
, &completed
);
332 Log("Disk clean QueryStatus OK");
335 else if (hr
== VDS_E_OPERATION_PENDING
)
341 Log("QueryStatus invalid status:%u", hr
);
350 Log("Could not clean disk 0x%lx err:%u", hr
, LASTERR
);
357 BOOL
VDS_CleanDisk(int DriveIndex
)
359 BOOL ret
= VDS_DiskCommProc(INTF_ADVANCEDDISK
, DriveIndex
, VDS_CallBack_CleanDisk
, 0);
360 Log("VDS_CleanDisk %d ret:%d", DriveIndex
, ret
);
364 STATIC BOOL
VDS_CallBack_DeletePartition(void *pInterface
, VDS_DISK_PROP
*pDiskProp
, UINT64 data
)
368 VDS_PARTITION_PROP
* prop_array
= NULL
;
369 LONG i
, prop_array_size
;
370 ULONG PartNumber
= (ULONG
)data
;
371 IVdsAdvancedDisk
*pAdvancedDisk
= (IVdsAdvancedDisk
*)pInterface
;
375 Log("Deleting ALL partitions from disk '%S':", pDiskProp
->pwszName
);
379 Log("Deleting partition(%ld) from disk '%S':", PartNumber
, pDiskProp
->pwszName
);
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
);
386 for (i
= 0; i
< prop_array_size
; i
++)
388 if (PartNumber
== 0 || PartNumber
== prop_array
[i
].ulPartitionNumber
)
390 Log("* Partition %d (offset: %lld, size: %llu) delete it.",
391 prop_array
[i
].ulPartitionNumber
, prop_array
[i
].ullOffset
, (ULONGLONG
)prop_array
[i
].ullSize
);
395 Log(" Partition %d (offset: %lld, size: %llu) skip it.",
396 prop_array
[i
].ulPartitionNumber
, prop_array
[i
].ullOffset
, (ULONGLONG
)prop_array
[i
].ullSize
);
400 hr
= IVdsAdvancedDisk_DeletePartition(pAdvancedDisk
, prop_array
[i
].ullOffset
, TRUE
, TRUE
);
405 Log("Could not delete partitions: %u", LASTERR
);
409 Log("Delete this partitions success");
416 Log("No partition to delete on disk '%S'", pDiskProp
->pwszName
);
419 CoTaskMemFree(prop_array
);
424 BOOL
VDS_DeleteAllPartitions(int DriveIndex
)
426 BOOL ret
= VDS_DiskCommProc(INTF_ADVANCEDDISK
, DriveIndex
, VDS_CallBack_DeletePartition
, 0);
427 Log("VDS_DeleteAllPartitions %d ret:%d", DriveIndex
, ret
);
431 BOOL
VDS_DeleteVtoyEFIPartition(int DriveIndex
)
433 BOOL ret
= VDS_DiskCommProc(INTF_ADVANCEDDISK
, DriveIndex
, VDS_CallBack_DeletePartition
, 2);
434 Log("VDS_DeleteVtoyEFIPartition %d ret:%d", DriveIndex
, ret
);
438 STATIC BOOL
VDS_CallBack_ChangeEFIAttr(void *pInterface
, VDS_DISK_PROP
*pDiskProp
, UINT64 data
)
442 VDS_PARTITION_PROP
* prop_array
= NULL
;
443 LONG i
, prop_array_size
;
444 CHANGE_ATTRIBUTES_PARAMETERS AttrPara
;
445 IVdsAdvancedDisk
*pAdvancedDisk
= (IVdsAdvancedDisk
*)pInterface
;
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
);
451 for (i
= 0; i
< prop_array_size
; i
++)
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)
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
);
460 if (prop_array
[i
].Gpt
.attributes
== data
)
462 Log("Attribute match, No need to change.");
467 AttrPara
.style
= VDS_PST_GPT
;
468 AttrPara
.GptPartInfo
.attributes
= data
;
469 hr
= IVdsAdvancedDisk_ChangeAttributes(pAdvancedDisk
, prop_array
[i
].ullOffset
, &AttrPara
);
473 Log("Change this partitions attribute success");
479 Log("Could not change partitions attr: %u", LASTERR
);
488 Log("No partition found on disk '%S'", pDiskProp
->pwszName
);
490 CoTaskMemFree(prop_array
);
495 BOOL
VDS_ChangeVtoyEFIAttr(int DriveIndex
, UINT64 Attr
)
497 BOOL ret
= VDS_DiskCommProc(INTF_ADVANCEDDISK
, DriveIndex
, VDS_CallBack_ChangeEFIAttr
, Attr
);
498 Log("VDS_ChangeVtoyEFIAttr %d ret:%d", DriveIndex
, ret
);
504 STATIC BOOL
VDS_CallBack_ChangeEFIType(void *pInterface
, VDS_DISK_PROP
*pDiskProp
, UINT64 data
)
508 IVdsAdvancedDisk2
*pAdvancedDisk2
= (IVdsAdvancedDisk2
*)pInterface
;
509 VDS_PARA
*VdsPara
= (VDS_PARA
*)(ULONG
)data
;
510 CHANGE_PARTITION_TYPE_PARAMETERS para
;
512 para
.style
= VDS_PST_GPT
;
513 memcpy(&(para
.GptPartInfo
.partitionType
), &VdsPara
->Type
, sizeof(GUID
));
515 hr
= IVdsAdvancedDisk2_ChangePartitionType(pAdvancedDisk2
, VdsPara
->Offset
, TRUE
, ¶
);
522 Log("Failed to change partition type 0x%lx", hr
);
529 BOOL
VDS_ChangeVtoyEFI2ESP(int DriveIndex
, UINT64 Offset
)
532 GUID EspPartType
= { 0xc12a7328, 0xf81f, 0x11d2, { 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } };
534 memcpy(&(Para
.Type
), &EspPartType
, sizeof(GUID
));
535 Para
.Offset
= Offset
;
537 BOOL ret
= VDS_DiskCommProc(INTF_ADVANCEDDISK2
, DriveIndex
, VDS_CallBack_ChangeEFIType
, (ULONG
)&Para
);
538 Log("VDS_ChangeVtoyEFI2ESP %d ret:%d", DriveIndex
, ret
);
542 BOOL
VDS_ChangeVtoyEFI2Basic(int DriveIndex
, UINT64 Offset
)
545 GUID WindowsDataPartType
= { 0xebd0a0a2, 0xb9e5, 0x4433, { 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7 } };
547 memcpy(&(Para
.Type
), &WindowsDataPartType
, sizeof(GUID
));
548 Para
.Offset
= Offset
;
550 BOOL ret
= VDS_DiskCommProc(INTF_ADVANCEDDISK2
, DriveIndex
, VDS_CallBack_ChangeEFIType
, (ULONG
)&Para
);
551 Log("VDS_ChangeVtoyEFI2ESP %d ret:%d", DriveIndex
, ret
);
556 STATIC BOOL
VDS_CallBack_CreateVtoyEFI(void *pInterface
, VDS_DISK_PROP
*pDiskProp
, UINT64 data
)
561 CREATE_PARTITION_PARAMETERS para
;
562 IVdsCreatePartitionEx
*pCreatePartitionEx
= (IVdsCreatePartitionEx
*)pInterface
;
563 VDS_PARA
*VdsPara
= (VDS_PARA
*)(ULONG
)data
;
567 memset(¶
, 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
);
574 hr
= IVdsCreatePartitionEx_CreatePartitionEx(pCreatePartitionEx
, VdsPara
->Offset
, VENTOY_EFI_PART_SIZE
, 512, ¶
, &pAsync
);
575 while (SUCCEEDED(hr
))
577 hr
= IVdsAsync_QueryStatus(pAsync
, &hr2
, &completed
);
583 Log("Disk create partition QueryStatus OK, %lu%%", completed
);
586 else if (hr
== VDS_E_OPERATION_PENDING
)
588 Log("Disk partition finish: %lu%%", completed
);
593 Log("QueryStatus invalid status:0x%lx", hr
);
602 Log("Could not create partition, err:0x%lx", LASTERR
);
609 BOOL
VDS_CreateVtoyEFIPart(int DriveIndex
, UINT64 Offset
)
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 } };
615 Log("VDS_CreateVtoyEFIPart %u Offset:%llu Sector:%llu", DriveIndex
, Offset
, Offset
/ 512);
617 memset(&Para
, 0, sizeof(Para
));
618 Para
.Attr
= 0x8000000000000000ULL
;
619 Para
.Offset
= Offset
;
620 memcpy(Para
.Name
, L
"VTOYEFI", 7 * 2);
622 memcpy(&(Para
.Type
), &EspPartType
, sizeof(GUID
));
623 CoCreateGuid(&(Para
.Id
));
625 BOOL ret
= VDS_DiskCommProc(INTF_CREATEPARTITIONEX
, DriveIndex
, VDS_CallBack_CreateVtoyEFI
, (ULONG
)&Para
);
626 Log("VDS_CreateVtoyEFIPart %d ret:%d", DriveIndex
, ret
);