]> glassweightruler.freedombox.rocks Git - Ventoy.git/commitdiff
Optimization for Ventoy2Disk.exe
authorlongpanda <admin@ventoy.net>
Thu, 21 Oct 2021 11:14:44 +0000 (19:14 +0800)
committerlongpanda <admin@ventoy.net>
Thu, 21 Oct 2021 11:14:44 +0000 (19:14 +0800)
INSTALL/Ventoy2Disk.exe
Ventoy2Disk/Ventoy2Disk/DiskService.h
Ventoy2Disk/Ventoy2Disk/DiskService_vds.c
Ventoy2Disk/Ventoy2Disk/PhyDrive.c
Ventoy2Disk/Ventoy2Disk/WinDialog.c
Ventoy2Disk/Ventoy2Disk/process.c

index 66d871e08c66a8b66dc9c7e1cc2ffb8e1249b0a5..63cb2bca4ab543f75597d65b5c8e88560246741b 100644 (file)
Binary files a/INSTALL/Ventoy2Disk.exe and b/INSTALL/Ventoy2Disk.exe differ
index a8b68af725086f9ac39df420388223d43fd80f62..95b8bbc48126150369cf1ffbfc0b1bb58a708e42 100644 (file)
@@ -41,7 +41,7 @@ BOOL VDS_ChangeVtoyEFIAttr(int DriveIndex, UINT64 Attr);
 BOOL VDS_CreateVtoyEFIPart(int DriveIndex, UINT64 Offset);\r
 BOOL VDS_ChangeVtoyEFI2ESP(int DriveIndex, UINT64 Offset);\r
 BOOL VDS_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset);\r
 BOOL VDS_CreateVtoyEFIPart(int DriveIndex, UINT64 Offset);\r
 BOOL VDS_ChangeVtoyEFI2ESP(int DriveIndex, UINT64 Offset);\r
 BOOL VDS_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset);\r
-\r
+BOOL VDS_FormatVtoyEFIPart(int DriveIndex, UINT64 Offset);\r
 \r
 //diskpart.exe\r
 BOOL DSPT_CleanDisk(int DriveIndex);\r
 \r
 //diskpart.exe\r
 BOOL DSPT_CleanDisk(int DriveIndex);\r
index 7fd3f111f7575c65ef342f3450b6ca168f0aef2e..69f099673c18e0053bae211ff869d28b7da5f8c9 100644 (file)
 #include "DiskService.h"\r
 \r
 \r
 #include "DiskService.h"\r
 \r
 \r
+\r
+// Count on Microsoft to add a new API while not bothering updating the existing error facilities,\r
+// so that the new error messages have to be handled manually. Now, since I don't have all day:\r
+// 1. Copy text from https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-vds/5102cc53-3143-4268-ba4c-6ea39e999ab4\r
+// 2. awk '{l[NR%7]=$0} {if (NR%7==0) printf "\tcase %s:\t// %s\n\t\treturn \"%s\";\n", l[1], l[3], l[6]}' vds.txt\r
+// 3. Filter out the crap we don't need.\r
+static const char *GetVdsError(DWORD error_code)\r
+{\r
+       switch (error_code) {\r
+       case 0x80042400:        // VDS_E_NOT_SUPPORTED\r
+               return "The operation is not supported by the object.";\r
+       case 0x80042401:        // VDS_E_INITIALIZED_FAILED\r
+               return "VDS or the provider failed to initialize.";\r
+       case 0x80042402:        // VDS_E_INITIALIZE_NOT_CALLED\r
+               return "VDS did not call the hardware provider's initialization method.";\r
+       case 0x80042403:        // VDS_E_ALREADY_REGISTERED\r
+               return "The provider is already registered.";\r
+       case 0x80042404:        // VDS_E_ANOTHER_CALL_IN_PROGRESS\r
+               return "A concurrent second call is made on an object before the first call is completed.";\r
+       case 0x80042405:        // VDS_E_OBJECT_NOT_FOUND\r
+               return "The specified object was not found.";\r
+       case 0x80042406:        // VDS_E_INVALID_SPACE\r
+               return "The specified space is neither free nor valid.";\r
+       case 0x80042407:        // VDS_E_PARTITION_LIMIT_REACHED\r
+               return "No more partitions can be created on the specified disk.";\r
+       case 0x80042408:        // VDS_E_PARTITION_NOT_EMPTY\r
+               return "The extended partition is not empty.";\r
+       case 0x80042409:        // VDS_E_OPERATION_PENDING\r
+               return "The operation is still in progress.";\r
+       case 0x8004240A:        // VDS_E_OPERATION_DENIED\r
+               return "The operation is not permitted on the specified disk, partition, or volume.";\r
+       case 0x8004240B:        // VDS_E_OBJECT_DELETED\r
+               return "The object no longer exists.";\r
+       case 0x8004240C:        // VDS_E_CANCEL_TOO_LATE\r
+               return "The operation can no longer be canceled.";\r
+       case 0x8004240D:        // VDS_E_OPERATION_CANCELED\r
+               return "The operation has already been canceled.";\r
+       case 0x8004240E:        // VDS_E_CANNOT_EXTEND\r
+               return "The file system does not support extending this volume.";\r
+       case 0x8004240F:        // VDS_E_NOT_ENOUGH_SPACE\r
+               return "There is not enough space to complete the operation.";\r
+       case 0x80042410:        // VDS_E_NOT_ENOUGH_DRIVE\r
+               return "There are not enough free disk drives in the subsystem to complete the operation.";\r
+       case 0x80042411:        // VDS_E_BAD_COOKIE\r
+               return "The cookie was not found.";\r
+       case 0x80042412:        // VDS_E_NO_MEDIA\r
+               return "There is no removable media in the drive.";\r
+       case 0x80042413:        // VDS_E_DEVICE_IN_USE\r
+               return "The device is currently in use.";\r
+       case 0x80042414:        // VDS_E_DISK_NOT_EMPTY\r
+               return "The disk contains partitions or volumes.";\r
+       case 0x80042415:        // VDS_E_INVALID_OPERATION\r
+               return "The specified operation is not valid.";\r
+       case 0x80042416:        // VDS_E_PATH_NOT_FOUND\r
+               return "The specified path was not found.";\r
+       case 0x80042417:        // VDS_E_DISK_NOT_INITIALIZED\r
+               return "The specified disk has not been initialized.";\r
+       case 0x80042418:        // VDS_E_NOT_AN_UNALLOCATED_DISK\r
+               return "The specified disk is not an unallocated disk.";\r
+       case 0x80042419:        // VDS_E_UNRECOVERABLE_ERROR\r
+               return "An unrecoverable error occurred. The service MUST shut down.";\r
+       case 0x0004241A:        // VDS_S_DISK_PARTIALLY_CLEANED\r
+               return "The clean operation was not a full clean or was canceled before it could be completed.";\r
+       case 0x8004241B:        // VDS_E_DMADMIN_SERVICE_CONNECTION_FAILED\r
+               return "The provider failed to connect to the LDMA service.";\r
+       case 0x8004241C:        // VDS_E_PROVIDER_INITIALIZATION_FAILED\r
+               return "The provider failed to initialize.";\r
+       case 0x8004241D:        // VDS_E_OBJECT_EXISTS\r
+               return "The object already exists.";\r
+       case 0x8004241E:        // VDS_E_NO_DISKS_FOUND\r
+               return "No disks were found on the target machine.";\r
+       case 0x8004241F:        // VDS_E_PROVIDER_CACHE_CORRUPT\r
+               return "The cache for a provider is corrupt.";\r
+       case 0x80042420:        // VDS_E_DMADMIN_METHOD_CALL_FAILED\r
+               return "A method call to the LDMA service failed.";\r
+       case 0x00042421:        // VDS_S_PROVIDER_ERROR_LOADING_CACHE\r
+               return "The provider encountered errors while loading the cache.";\r
+       case 0x80042422:        // VDS_E_PROVIDER_VOL_DEVICE_NAME_NOT_FOUND\r
+               return "The device form of the volume pathname could not be retrieved.";\r
+       case 0x80042423:        // VDS_E_PROVIDER_VOL_OPEN\r
+               return "Failed to open the volume device";\r
+       case 0x80042424:        // VDS_E_DMADMIN_CORRUPT_NOTIFICATION\r
+               return "A corrupt notification was sent from the LDMA service.";\r
+       case 0x80042425:        // VDS_E_INCOMPATIBLE_FILE_SYSTEM\r
+               return "The file system is incompatible with the specified operation.";\r
+       case 0x80042426:        // VDS_E_INCOMPATIBLE_MEDIA\r
+               return "The media is incompatible with the specified operation.";\r
+       case 0x80042427:        // VDS_E_ACCESS_DENIED\r
+               return "Access is denied. A VDS operation MUST run elevated.";\r
+       case 0x80042428:        // VDS_E_MEDIA_WRITE_PROTECTED\r
+               return "The media is write-protected.";\r
+       case 0x80042429:        // VDS_E_BAD_LABEL\r
+               return "The volume label is not valid.";\r
+       case 0x8004242A:        // VDS_E_CANT_QUICK_FORMAT\r
+               return "The volume cannot be quick-formatted.";\r
+       case 0x8004242B:        // VDS_E_IO_ERROR\r
+               return "An I/O error occurred during the operation.";\r
+       case 0x8004242C:        // VDS_E_VOLUME_TOO_SMALL\r
+               return "The volume size is too small.";\r
+       case 0x8004242D:        // VDS_E_VOLUME_TOO_BIG\r
+               return "The volume size is too large.";\r
+       case 0x8004242E:        // VDS_E_CLUSTER_SIZE_TOO_SMALL\r
+               return "The cluster size is too small.";\r
+       case 0x8004242F:        // VDS_E_CLUSTER_SIZE_TOO_BIG\r
+               return "The cluster size is too large.";\r
+       case 0x80042430:        // VDS_E_CLUSTER_COUNT_BEYOND_32BITS\r
+               return "The number of clusters is too large to be represented as a 32-bit integer.";\r
+       case 0x80042431:        // VDS_E_OBJECT_STATUS_FAILED\r
+               return "The component that the object represents has failed.";\r
+       case 0x80042432:        // VDS_E_VOLUME_INCOMPLETE\r
+               return "The volume is incomplete.";\r
+       case 0x80042433:        // VDS_E_EXTENT_SIZE_LESS_THAN_MIN\r
+               return "The specified extent size is too small.";\r
+       case 0x00042434:        // VDS_S_UPDATE_BOOTFILE_FAILED\r
+               return "The operation was successful, but VDS failed to update the boot options.";\r
+       case 0x00042436:        // VDS_S_BOOT_PARTITION_NUMBER_CHANGE\r
+       case 0x80042436:        // VDS_E_BOOT_PARTITION_NUMBER_CHANGE\r
+               return "The boot partition's partition number will change as a result of the operation.";\r
+       case 0x80042437:        // VDS_E_NO_FREE_SPACE\r
+               return "The specified disk does not have enough free space to complete the operation.";\r
+       case 0x80042438:        // VDS_E_ACTIVE_PARTITION\r
+               return "An active partition was detected on the selected disk.";\r
+       case 0x80042439:        // VDS_E_PARTITION_OF_UNKNOWN_TYPE\r
+               return "The partition information cannot be read.";\r
+       case 0x8004243A:        // VDS_E_LEGACY_VOLUME_FORMAT\r
+               return "A partition with an unknown type was detected on the specified disk.";\r
+       case 0x8004243C:        // VDS_E_MIGRATE_OPEN_VOLUME\r
+               return "A volume on the specified disk could not be opened.";\r
+       case 0x8004243D:        // VDS_E_VOLUME_NOT_ONLINE\r
+               return "The volume is not online.";\r
+       case 0x8004243E:        // VDS_E_VOLUME_NOT_HEALTHY\r
+               return "The volume is failing or has failed.";\r
+       case 0x8004243F:        // VDS_E_VOLUME_SPANS_DISKS\r
+               return "The volume spans multiple disks.";\r
+       case 0x80042440:        // VDS_E_REQUIRES_CONTIGUOUS_DISK_SPACE\r
+               return "The volume does not consist of a single disk extent.";\r
+       case 0x80042441:        // VDS_E_BAD_PROVIDER_DATA\r
+               return "A provider returned bad data.";\r
+       case 0x80042442:        // VDS_E_PROVIDER_FAILURE\r
+               return "A provider failed to complete an operation.";\r
+       case 0x00042443:        // VDS_S_VOLUME_COMPRESS_FAILED\r
+               return "The file system was formatted successfully but could not be compressed.";\r
+       case 0x80042444:        // VDS_E_PACK_OFFLINE\r
+               return "The pack is offline.";\r
+       case 0x80042445:        // VDS_E_VOLUME_NOT_A_MIRROR\r
+               return "The volume is not a mirror.";\r
+       case 0x80042446:        // VDS_E_NO_EXTENTS_FOR_VOLUME\r
+               return "No extents were found for the volume.";\r
+       case 0x80042447:        // VDS_E_DISK_NOT_LOADED_TO_CACHE\r
+               return "The migrated disk failed to load to the cache.";\r
+       case 0x80042448:        // VDS_E_INTERNAL_ERROR\r
+               return "VDS encountered an internal error.";\r
+       case 0x8004244A:        // VDS_E_PROVIDER_TYPE_NOT_SUPPORTED\r
+               return "The method call is not supported for the specified provider type.";\r
+       case 0x8004244B:        // VDS_E_DISK_NOT_ONLINE\r
+               return "One or more of the specified disks are not online.";\r
+       case 0x8004244C:        // VDS_E_DISK_IN_USE_BY_VOLUME\r
+               return "One or more extents of the disk are already being used by the volume.";\r
+       case 0x0004244D:        // VDS_S_IN_PROGRESS\r
+               return "The asynchronous operation is in progress.";\r
+       case 0x8004244E:        // VDS_E_ASYNC_OBJECT_FAILURE\r
+               return "Failure initializing the asynchronous object.";\r
+       case 0x8004244F:        // VDS_E_VOLUME_NOT_MOUNTED\r
+               return "The volume is not mounted.";\r
+       case 0x80042450:        // VDS_E_PACK_NOT_FOUND\r
+               return "The pack was not found.";\r
+       case 0x80042453:        // VDS_E_OBJECT_OUT_OF_SYNC\r
+               return "The reference to the object might be stale.";\r
+       case 0x80042454:        // VDS_E_MISSING_DISK\r
+               return "The specified disk could not be found.";\r
+       case 0x80042455:        // VDS_E_DISK_PNP_REG_CORRUPT\r
+               return "The provider's list of PnP registered disks has become corrupted.";\r
+       case 0x80042457:        // VDS_E_NO_DRIVELETTER_FLAG\r
+               return "The provider does not support the VDS_VF_NO DRIVELETTER volume flag.";\r
+       case 0x80042459:        // VDS_E_REVERT_ON_CLOSE_SET\r
+               return "Some volume flags are already set.";\r
+       case 0x0004245B:        // VDS_S_UNABLE_TO_GET_GPT_ATTRIBUTES\r
+               return "Unable to retrieve the GPT attributes for this volume.";\r
+       case 0x8004245C:        // VDS_E_VOLUME_TEMPORARILY_DISMOUNTED\r
+               return "The volume is already dismounted temporarily.";\r
+       case 0x8004245D:        // VDS_E_VOLUME_PERMANENTLY_DISMOUNTED\r
+               return "The volume is already permanently dismounted.";\r
+       case 0x8004245E:        // VDS_E_VOLUME_HAS_PATH\r
+               return "The volume cannot be dismounted permanently because it still has an access path.";\r
+       case 0x8004245F:        // VDS_E_TIMEOUT\r
+               return "The operation timed out.";\r
+       case 0x80042461:        // VDS_E_LDM_TIMEOUT\r
+               return "The operation timed out in the LDMA service. Retry the operation.";\r
+       case 0x80042462:        // VDS_E_REVERT_ON_CLOSE_MISMATCH\r
+               return "The flags to be cleared do not match the flags that were set previously.";\r
+       case 0x80042463:        // VDS_E_RETRY\r
+               return "The operation failed. Retry the operation.";\r
+       case 0x80042464:        // VDS_E_ONLINE_PACK_EXISTS\r
+               return "The operation failed, because an online pack object already exists.";\r
+       case 0x80042468:        // VDS_E_MAX_USABLE_MBR\r
+               return "Only the first 2TB are usable on large MBR disks.";\r
+       case 0x80042500:        // VDS_E_NO_SOFTWARE_PROVIDERS_LOADED\r
+               return "There are no software providers loaded.";\r
+       case 0x80042501:        // VDS_E_DISK_NOT_MISSING\r
+               return "The disk is not missing.";\r
+       case 0x80042502:        // VDS_E_NO_VOLUME_LAYOUT\r
+               return "The volume's layout could not be retrieved.";\r
+       case 0x80042503:        // VDS_E_CORRUPT_VOLUME_INFO\r
+               return "The volume's driver information is corrupted.";\r
+       case 0x80042504:        // VDS_E_INVALID_ENUMERATOR\r
+               return "The enumerator is corrupted";\r
+       case 0x80042505:        // VDS_E_DRIVER_INTERNAL_ERROR\r
+               return "An internal error occurred in the volume management driver.";\r
+       case 0x80042507:        // VDS_E_VOLUME_INVALID_NAME\r
+               return "The volume name is not valid.";\r
+       case 0x00042508:        // VDS_S_DISK_IS_MISSING\r
+               return "The disk is missing and not all information could be returned.";\r
+       case 0x80042509:        // VDS_E_CORRUPT_PARTITION_INFO\r
+               return "The disk's partition information is corrupted.";\r
+       case 0x0004250A:        // VDS_S_NONCONFORMANT_PARTITION_INFO\r
+               return "The disk's partition information does not conform to what is expected on a dynamic disk.";\r
+       case 0x8004250B:        // VDS_E_CORRUPT_EXTENT_INFO\r
+               return "The disk's extent information is corrupted.";\r
+       case 0x0004250E:        // VDS_S_SYSTEM_PARTITION\r
+               return "Warning: There was a failure while checking for the system partition.";\r
+       case 0x8004250F:        // VDS_E_BAD_PNP_MESSAGE\r
+               return "The PNP service sent a corrupted notification to the provider.";\r
+       case 0x80042510:        // VDS_E_NO_PNP_DISK_ARRIVE\r
+       case 0x80042511:        // VDS_E_NO_PNP_VOLUME_ARRIVE\r
+               return "No disk/volume arrival notification was received.";\r
+       case 0x80042512:        // VDS_E_NO_PNP_DISK_REMOVE\r
+       case 0x80042513:        // VDS_E_NO_PNP_VOLUME_REMOVE\r
+               return "No disk/volume removal notification was received.";\r
+       case 0x80042514:        // VDS_E_PROVIDER_EXITING\r
+               return "The provider is exiting.";\r
+       case 0x00042517:        // VDS_S_NO_NOTIFICATION\r
+               return "No volume arrival notification was received.";\r
+       case 0x80042519:        // VDS_E_INVALID_DISK\r
+               return "The specified disk is not valid.";\r
+       case 0x8004251A:        // VDS_E_INVALID_PACK\r
+               return "The specified disk pack is not valid.";\r
+       case 0x8004251B:        // VDS_E_VOLUME_ON_DISK\r
+               return "This operation is not allowed on disks with volumes.";\r
+       case 0x8004251C:        // VDS_E_DRIVER_INVALID_PARAM\r
+               return "The driver returned an invalid parameter error.";\r
+       case 0x8004253D:        // VDS_E_DRIVER_OBJECT_NOT_FOUND\r
+               return "The object was not found in the driver cache.";\r
+       case 0x8004253E:        // VDS_E_PARTITION_NOT_CYLINDER_ALIGNED\r
+               return "The disk layout contains partitions which are not cylinder aligned.";\r
+       case 0x8004253F:        // VDS_E_DISK_LAYOUT_PARTITIONS_TOO_SMALL\r
+               return "The disk layout contains partitions which are less than the minimum required size.";\r
+       case 0x80042540:        // VDS_E_DISK_IO_FAILING\r
+               return "The I/O to the disk is failing.";\r
+       case 0x80042543:        // VDS_E_GPT_ATTRIBUTES_INVALID\r
+               return "Invalid GPT attributes were specified.";\r
+       case 0x8004254D:        // VDS_E_UNEXPECTED_DISK_LAYOUT_CHANGE\r
+               return "An unexpected layout change occurred external to the volume manager.";\r
+       case 0x8004254E:        // VDS_E_INVALID_VOLUME_LENGTH\r
+               return "The volume length is invalid.";\r
+       case 0x8004254F:        // VDS_E_VOLUME_LENGTH_NOT_SECTOR_SIZE_MULTIPLE\r
+               return "The volume length is not a multiple of the sector size.";\r
+       case 0x80042550:        // VDS_E_VOLUME_NOT_RETAINED\r
+               return "The volume does not have a retained partition association.";\r
+       case 0x80042551:        // VDS_E_VOLUME_RETAINED\r
+               return "The volume already has a retained partition association.";\r
+       case 0x80042553:        // VDS_E_ALIGN_BEYOND_FIRST_CYLINDER\r
+               return "The specified alignment is beyond the first cylinder.";\r
+       case 0x80042554:        // VDS_E_ALIGN_NOT_SECTOR_SIZE_MULTIPLE\r
+               return "The specified alignment is not a multiple of the sector size.";\r
+       case 0x80042555:        // VDS_E_ALIGN_NOT_ZERO\r
+               return "The specified partition type cannot be created with a non-zero alignment.";\r
+       case 0x80042556:        // VDS_E_CACHE_CORRUPT\r
+               return "The service's cache has become corrupt.";\r
+       case 0x80042557:        // VDS_E_CANNOT_CLEAR_VOLUME_FLAG\r
+               return "The specified volume flag cannot be cleared.";\r
+       case 0x80042558:        // VDS_E_DISK_BEING_CLEANED\r
+               return "The operation is not allowed on a disk that is in the process of being cleaned.";\r
+       case 0x8004255A:        // VDS_E_DISK_REMOVEABLE\r
+               return "The operation is not supported on removable media.";\r
+       case 0x8004255B:        // VDS_E_DISK_REMOVEABLE_NOT_EMPTY\r
+               return "The operation is not supported on a non-empty removable disk.";\r
+       case 0x8004255C:        // VDS_E_DRIVE_LETTER_NOT_FREE\r
+               return "The specified drive letter is not free to be assigned.";\r
+       case 0x8004255E:        // VDS_E_INVALID_DRIVE_LETTER\r
+               return "The specified drive letter is not valid.";\r
+       case 0x8004255F:        // VDS_E_INVALID_DRIVE_LETTER_COUNT\r
+               return "The specified number of drive letters to retrieve is not valid.";\r
+       case 0x80042560:        // VDS_E_INVALID_FS_FLAG\r
+               return "The specified file system flag is not valid.";\r
+       case 0x80042561:        // VDS_E_INVALID_FS_TYPE\r
+               return "The specified file system is not valid.";\r
+       case 0x80042562:        // VDS_E_INVALID_OBJECT_TYPE\r
+               return "The specified object type is not valid.";\r
+       case 0x80042563:        // VDS_E_INVALID_PARTITION_LAYOUT\r
+               return "The specified partition layout is invalid.";\r
+       case 0x80042564:        // VDS_E_INVALID_PARTITION_STYLE\r
+               return "VDS only supports MBR or GPT partition style disks.";\r
+       case 0x80042565:        // VDS_E_INVALID_PARTITION_TYPE\r
+               return "The specified partition type is not valid for this operation.";\r
+       case 0x80042566:        // VDS_E_INVALID_PROVIDER_CLSID\r
+       case 0x80042567:        // VDS_E_INVALID_PROVIDER_ID\r
+       case 0x8004256A:        // VDS_E_INVALID_PROVIDER_VERSION_GUID\r
+               return "A NULL GUID was passed to the provider.";\r
+       case 0x80042568:        // VDS_E_INVALID_PROVIDER_NAME\r
+               return "The specified provider name is invalid.";\r
+       case 0x80042569:        // VDS_E_INVALID_PROVIDER_TYPE\r
+               return "The specified provider type is invalid.";\r
+       case 0x8004256B:        // VDS_E_INVALID_PROVIDER_VERSION_STRING\r
+               return "The specified provider version string is invalid.";\r
+       case 0x8004256C:        // VDS_E_INVALID_QUERY_PROVIDER_FLAG\r
+               return "The specified query provider flag is invalid.";\r
+       case 0x8004256D:        // VDS_E_INVALID_SERVICE_FLAG\r
+               return "The specified service flag is invalid.";\r
+       case 0x8004256E:        // VDS_E_INVALID_VOLUME_FLAG\r
+               return "The specified volume flag is invalid.";\r
+       case 0x8004256F:        // VDS_E_PARTITION_NOT_OEM\r
+               return "The operation is only supported on an OEM, ESP, or unknown partition.";\r
+       case 0x80042570:        // VDS_E_PARTITION_PROTECTED\r
+               return "Cannot delete a protected partition without the force protected parameter set.";\r
+       case 0x80042571:        // VDS_E_PARTITION_STYLE_MISMATCH\r
+               return "The specified partition style is not the same as the disk's partition style.";\r
+       case 0x80042572:        // VDS_E_PROVIDER_INTERNAL_ERROR\r
+               return "An internal error has occurred in the provider.";\r
+       case 0x80042575:        // VDS_E_UNRECOVERABLE_PROVIDER_ERROR\r
+               return "An unrecoverable error occurred in the provider.";\r
+       case 0x80042576:        // VDS_E_VOLUME_HIDDEN\r
+               return "Cannot assign a mount point to a hidden volume.";\r
+       case 0x00042577:        // VDS_S_DISMOUNT_FAILED\r
+       case 0x00042578:        // VDS_S_REMOUNT_FAILED\r
+               return "Failed to dismount/remount the volume after setting the volume flags.";\r
+       case 0x80042579:        // VDS_E_FLAG_ALREADY_SET\r
+               return "Cannot set the specified flag as revert-on-close because it is already set.";\r
+       case 0x8004257B:        // VDS_E_DISTINCT_VOLUME\r
+               return "The input volume id cannot be the id of the volume that is the target of the operation.";\r
+       case 0x00042583:        // VDS_S_FS_LOCK\r
+               return "Failed to obtain a file system lock.";\r
+       case 0x80042584:        // VDS_E_READONLY\r
+               return "The volume is read only.";\r
+       case 0x80042585:        // VDS_E_INVALID_VOLUME_TYPE\r
+               return "The volume type is invalid for this operation.";\r
+       case 0x80042588:        // VDS_E_VOLUME_MIRRORED\r
+               return "This operation is not supported on a mirrored volume.";\r
+       case 0x80042589:        // VDS_E_VOLUME_SIMPLE_SPANNED\r
+               return "The operation is only supported on simple or spanned volumes.";\r
+       case 0x8004258C:        // VDS_E_PARTITION_MSR\r
+       case 0x8004258D:        // VDS_E_PARTITION_LDM\r
+               return "The operation is not supported on this type of partitions.";\r
+       case 0x0004258E:        // VDS_S_WINPE_BOOTENTRY\r
+               return "The boot entries cannot be updated automatically on WinPE.";\r
+       case 0x8004258F:        // VDS_E_ALIGN_NOT_A_POWER_OF_TWO\r
+               return "The alignment is not a power of two.";\r
+       case 0x80042590:        // VDS_E_ALIGN_IS_ZERO\r
+               return "The alignment is zero.";\r
+       case 0x80042593:        // VDS_E_FS_NOT_DETERMINED\r
+               return "The default file system could not be determined.";\r
+       case 0x80042595:        // VDS_E_DISK_NOT_OFFLINE\r
+               return "This disk is already online.";\r
+       case 0x80042596:        // VDS_E_FAILED_TO_ONLINE_DISK\r
+               return "The online operation failed.";\r
+       case 0x80042597:        // VDS_E_FAILED_TO_OFFLINE_DISK\r
+               return "The offline operation failed.";\r
+       case 0x80042598:        // VDS_E_BAD_REVISION_NUMBER\r
+               return "The operation could not be completed because the specified revision number is not supported.";\r
+       case 0x00042700:        // VDS_S_NAME_TRUNCATED\r
+               return "The name was set successfully but had to be truncated.";\r
+       case 0x80042701:        // VDS_E_NAME_NOT_UNIQUE\r
+               return "The specified name is not unique.";\r
+       case 0x8004270F:        // VDS_E_NO_DISK_PATHNAME\r
+               return "The disk's path could not be retrieved. Some operations on the disk might fail.";\r
+       case 0x80042711:        // VDS_E_NO_VOLUME_PATHNAME\r
+               return "The path could not be retrieved for one or more volumes.";\r
+       case 0x80042712:        // VDS_E_PROVIDER_CACHE_OUTOFSYNC\r
+               return "The provider's cache is not in sync with the driver cache.";\r
+       case 0x80042713:        // VDS_E_NO_IMPORT_TARGET\r
+               return "No import target was set for the subsystem.";\r
+       case 0x00042714:        // VDS_S_ALREADY_EXISTS\r
+               return "The object already exists.";\r
+       case 0x00042715:        // VDS_S_PROPERTIES_INCOMPLETE\r
+               return "Some, but not all, of the properties were successfully retrieved.";\r
+       case 0x80042803:        // VDS_E_UNABLE_TO_FIND_BOOT_DISK\r
+               return "Volume disk extent information could not be retrieved for the boot volume.";\r
+       case 0x80042807:        // VDS_E_BOOT_DISK\r
+               return "Disk attributes cannot be changed on the boot disk.";\r
+       case 0x00042808:        // VDS_S_DISK_MOUNT_FAILED\r
+       case 0x00042809:        // VDS_S_DISK_DISMOUNT_FAILED\r
+               return "One or more of the volumes on the disk could not be mounted/dismounted.";\r
+       case 0x8004280A:        // VDS_E_DISK_IS_OFFLINE\r
+       case 0x8004280B:        // VDS_E_DISK_IS_READ_ONLY\r
+               return "The operation cannot be performed on a disk that is offline or read-only.";\r
+       case 0x8004280C:        // VDS_E_PAGEFILE_DISK\r
+       case 0x8004280D:        // VDS_E_HIBERNATION_FILE_DISK\r
+       case 0x8004280E:        // VDS_E_CRASHDUMP_DISK\r
+               return "The operation cannot be performed on a disk that contains a pagefile, hibernation or crashdump volume.";\r
+       case 0x8004280F:        // VDS_E_UNABLE_TO_FIND_SYSTEM_DISK\r
+               return "A system error occurred while retrieving the system disk information.";\r
+       case 0x80042810:        // VDS_E_INCORRECT_SYSTEM_VOLUME_EXTENT_INFO\r
+               return "Multiple disk extents reported for the system volume - system error.";\r
+       case 0x80042811:        // VDS_E_SYSTEM_DISK\r
+               return "Disk attributes cannot be changed on the current system disk or BIOS disk 0.";\r
+       case 0x80042823:        // VDS_E_SECTOR_SIZE_ERROR\r
+               return "The sector size MUST be non-zero, a power of 2, and less than the maximum sector size.";\r
+       case 0x80042907:        // VDS_E_SUBSYSTEM_ID_IS_NULL\r
+               return "The provider returned a NULL subsystem identification string.";\r
+       case 0x8004290C:        // VDS_E_REBOOT_REQUIRED\r
+               return "A reboot is required before any further operations are initiated.";\r
+       case 0x8004290D:        // VDS_E_VOLUME_GUID_PATHNAME_NOT_ALLOWED\r
+               return "Volume GUID pathnames are not valid input to this method.";\r
+       case 0x8004290E:        // VDS_E_BOOT_PAGEFILE_DRIVE_LETTER\r
+               return "Assigning or removing drive letters on the current boot or pagefile volume is not allowed.";\r
+       case 0x8004290F:        // VDS_E_DELETE_WITH_CRITICAL\r
+               return "Delete is not allowed on a critical volume.";\r
+       case 0x80042910:        // VDS_E_CLEAN_WITH_DATA\r
+       case 0x80042911:        // VDS_E_CLEAN_WITH_OEM\r
+               return "The FORCE parameter MUST be set to TRUE in order to clean a disk that contains a data or OEM volume.";\r
+       case 0x80042912:        // VDS_E_CLEAN_WITH_CRITICAL\r
+               return "Clean is not allowed on a critical disk.";\r
+       case 0x80042913:        // VDS_E_FORMAT_CRITICAL\r
+               return "Format is not allowed on a critical volume.";\r
+       case 0x80042914:        // VDS_E_NTFS_FORMAT_NOT_SUPPORTED\r
+       case 0x80042915:        // VDS_E_FAT32_FORMAT_NOT_SUPPORTED\r
+       case 0x80042916:        // VDS_E_FAT_FORMAT_NOT_SUPPORTED\r
+               return "The requested file system format is not supported on this volume.";\r
+       case 0x80042917:        // VDS_E_FORMAT_NOT_SUPPORTED\r
+               return "The volume is not formattable.";\r
+       case 0x80042918:        // VDS_E_COMPRESSION_NOT_SUPPORTED\r
+               return "The specified file system does not support compression.";\r
+       default:\r
+               return NULL;\r
+       }\r
+}\r
+\r
+static const char* GetVimError(DWORD error_code)\r
+{\r
+       switch (error_code) {\r
+       case 0xC1420127:\r
+               return "The specified image in the specified wim is already mounted for read and write access.";\r
+       default:\r
+               return NULL;\r
+       }\r
+}\r
+\r
+#define sfree(p) do {if (p != NULL) {free((void*)(p)); p = NULL;}} while(0)\r
+#define wconvert(p)     wchar_t* w ## p = utf8_to_wchar(p)\r
+#define walloc(p, size) wchar_t* w ## p = (p == NULL)?NULL:(wchar_t*)calloc(size, sizeof(wchar_t))\r
+#define wfree(p) sfree(w ## p)\r
+#define wchar_to_utf8_no_alloc(wsrc, dest, dest_size) \\r
+       WideCharToMultiByte(CP_UTF8, 0, wsrc, -1, dest, dest_size, NULL, NULL)\r
+\r
+static __inline DWORD FormatMessageU(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId,\r
+       DWORD dwLanguageId, char* lpBuffer, DWORD nSize, va_list *Arguments)\r
+{\r
+       DWORD ret = 0, err = ERROR_INVALID_DATA;\r
+       // coverity[returned_null]\r
+       walloc(lpBuffer, nSize);\r
+       ret = FormatMessageW(dwFlags, lpSource, dwMessageId, dwLanguageId, wlpBuffer, nSize, Arguments);\r
+       err = GetLastError();\r
+       if ((ret != 0) && ((ret = wchar_to_utf8_no_alloc(wlpBuffer, lpBuffer, nSize)) == 0)) {\r
+               err = GetLastError();\r
+               ret = 0;\r
+       }\r
+       wfree(lpBuffer);\r
+       SetLastError(err);\r
+       return ret;\r
+}\r
+\r
+\r
+// Convert a windows error to human readable string\r
+const char *WindowsErrorString(DWORD error_code)\r
+{\r
+       static char err_string[256] = { 0 };\r
+\r
+       DWORD size, presize;\r
+       DWORD format_error;\r
+\r
+       // Check for VDS error codes\r
+       if ((HRESULT_FACILITY(error_code) == FACILITY_ITF) && (GetVdsError(error_code) != NULL)) {\r
+               sprintf_s(err_string, sizeof(err_string), "[0x%08lX] %s", error_code, GetVdsError(error_code));\r
+               return err_string;\r
+       }\r
+       if ((HRESULT_FACILITY(error_code) == 322) && (GetVimError(error_code) != NULL)) {\r
+               sprintf_s(err_string, sizeof(err_string), "[0x%08lX] %s", error_code, GetVimError(error_code));\r
+               return err_string;\r
+       }\r
+       sprintf_s(err_string, sizeof(err_string), "[0x%08lX] ", error_code);\r
+       presize = (DWORD)strlen(err_string);\r
+\r
+       size = FormatMessageU(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,\r
+               HRESULT_CODE(error_code), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),\r
+               &err_string[presize], sizeof(err_string)-(DWORD)strlen(err_string), NULL);\r
+       if (size == 0) {\r
+               format_error = GetLastError();\r
+               if ((format_error) && (format_error != ERROR_MR_MID_NOT_FOUND) && (format_error != ERROR_MUI_FILE_NOT_LOADED))\r
+                       sprintf_s(err_string, sizeof(err_string), "Windows error code 0x%08lX (FormatMessage error code 0x%08lX)",\r
+                       error_code, format_error);\r
+               else\r
+                       sprintf_s(err_string, sizeof(err_string), "Windows error code 0x%08lX", error_code);\r
+       }\r
+       else {\r
+               // Microsoft may suffix CRLF to error messages, which we need to remove...              \r
+               size += presize - 2;\r
+               // Cannot underflow if the above assert passed since our first char is neither of the following\r
+               while ((err_string[size] == 0x0D) || (err_string[size] == 0x0A) || (err_string[size] == 0x20))\r
+                       err_string[size--] = 0;\r
+       }\r
+\r
+       return err_string;\r
+}\r
+\r
+\r
+\r
 #define INTF_ADVANCEDDISK  1\r
 #define INTF_ADVANCEDDISK2  2\r
 #define INTF_CREATEPARTITIONEX  3\r
 #define INTF_ADVANCEDDISK  1\r
 #define INTF_ADVANCEDDISK2  2\r
 #define INTF_CREATEPARTITIONEX  3\r
+#define INTF_PARTITIONMF 4\r
 \r
 /* \r
  * Some code and functions in the file are copied from rufus.\r
 \r
 /* \r
  * Some code and functions in the file are copied from rufus.\r
 \r
 #define IVdsCreatePartitionEx_CreatePartitionEx(This, ullOffset, ullSize, ulAlign, para, ppAsync) (This)->lpVtbl->CreatePartitionEx(This, ullOffset, ullSize, ulAlign, para, ppAsync)\r
 #define IVdsCreatePartitionEx_Release(This) (This)->lpVtbl->Release(This)\r
 \r
 #define IVdsCreatePartitionEx_CreatePartitionEx(This, ullOffset, ullSize, ulAlign, para, ppAsync) (This)->lpVtbl->CreatePartitionEx(This, ullOffset, ullSize, ulAlign, para, ppAsync)\r
 #define IVdsCreatePartitionEx_Release(This) (This)->lpVtbl->Release(This)\r
+\r
+#define IVdsPartitionMF_FormatPartitionEx(This, ullOffset, pwszFileSystemTypeName, usFileSystemRevision, ulDesiredUnitAllocationSize, pwszLabel, bForce, bQuickFormat, bEnableCompression, ppAsync) \\r
+       (This)->lpVtbl->FormatPartitionEx(This, ullOffset, pwszFileSystemTypeName, usFileSystemRevision, ulDesiredUnitAllocationSize, pwszLabel, bForce, bQuickFormat, bEnableCompression, ppAsync)\r
+#define IVdsPartitionMF_Release(This) (This)->lpVtbl->Release(This)\r
+\r
 #define IEnumVdsObject_Next(This, celt, ppObjectArray, pcFetched) (This)->lpVtbl->Next(This, celt, ppObjectArray, pcFetched)\r
 #define IVdsPack_QueryVolumes(This, ppEnum) (This)->lpVtbl->QueryVolumes(This, ppEnum)\r
 #define IVdsVolume_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)\r
 #define IEnumVdsObject_Next(This, celt, ppObjectArray, pcFetched) (This)->lpVtbl->Next(This, celt, ppObjectArray, pcFetched)\r
 #define IVdsPack_QueryVolumes(This, ppEnum) (This)->lpVtbl->QueryVolumes(This, ppEnum)\r
 #define IVdsVolume_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)\r
@@ -222,6 +733,7 @@ STATIC BOOL VDS_DiskCommProc(int intf, int DriveIndex, VDS_Callback_PF callback,
                 IVdsAdvancedDisk *pAdvancedDisk;\r
                                IVdsAdvancedDisk2 *pAdvancedDisk2;\r
                                IVdsCreatePartitionEx *pCreatePartitionEx;\r
                 IVdsAdvancedDisk *pAdvancedDisk;\r
                                IVdsAdvancedDisk2 *pAdvancedDisk2;\r
                                IVdsCreatePartitionEx *pCreatePartitionEx;\r
+                               IVdsDiskPartitionMF *pPartitionMP;\r
 \r
                 // Get the disk interface.\r
                 hr = IUnknown_QueryInterface(pDiskUnk, &IID_IVdsDisk, (void **)&pDisk);\r
 \r
                 // Get the disk interface.\r
                 hr = IUnknown_QueryInterface(pDiskUnk, &IID_IVdsDisk, (void **)&pDisk);\r
@@ -300,6 +812,24 @@ STATIC BOOL VDS_DiskCommProc(int intf, int DriveIndex, VDS_Callback_PF callback,
                                        }\r
                                        IVdsCreatePartitionEx_Release(pCreatePartitionEx);\r
                                }\r
                                        }\r
                                        IVdsCreatePartitionEx_Release(pCreatePartitionEx);\r
                                }\r
+                               else if (intf == INTF_PARTITIONMF)\r
+                               {\r
+                                       // Instantiate the DiskPartitionMF interface for our disk.\r
+                                       hr = IVdsDisk_QueryInterface(pDisk, &IID_IVdsDiskPartitionMF, (void **)&pPartitionMP);\r
+                                       IVdsDisk_Release(pDisk);\r
+                                       if (hr != S_OK)\r
+                                       {\r
+                                               VDS_SET_ERROR(hr);\r
+                                               Log("Could not access VDS PartitionMF interface: %u", LASTERR);\r
+                                               goto out;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               Log("Callback %d process for disk <%S>", intf, diskprop.pwszName);\r
+                                               r = callback(pPartitionMP, &diskprop, data);\r
+                                       }\r
+                                       IVdsPartitionMF_Release(pPartitionMP);\r
+                               }\r
 \r
                 goto out;\r
             }\r
 \r
                 goto out;\r
             }\r
@@ -524,7 +1054,7 @@ STATIC BOOL VDS_CallBack_ChangeEFIType(void *pInterface, VDS_DISK_PROP *pDiskPro
        }\r
        else\r
        {\r
        }\r
        else\r
        {\r
-               Log("Failed to change partition type 0x%lx", hr);\r
+               Log("Failed to change partition type 0x%lx(%s)", hr, WindowsErrorString(hr));\r
        }\r
 \r
        return r;\r
        }\r
 \r
        return r;\r
@@ -604,7 +1134,7 @@ STATIC BOOL VDS_CallBack_CreateVtoyEFI(void *pInterface, VDS_DISK_PROP *pDiskPro
     if (hr != S_OK)\r
     {\r
         VDS_SET_ERROR(hr);\r
     if (hr != S_OK)\r
     {\r
         VDS_SET_ERROR(hr);\r
-        Log("Could not create partition, err:0x%lx", LASTERR);\r
+               Log("Could not create partition, err:0x%lx(%s)", LASTERR, WindowsErrorString(hr));\r
         return FALSE;\r
     }\r
 \r
         return FALSE;\r
     }\r
 \r
@@ -632,3 +1162,62 @@ BOOL VDS_CreateVtoyEFIPart(int DriveIndex, UINT64 Offset)
     return ret; \r
 }\r
 \r
     return ret; \r
 }\r
 \r
+\r
+STATIC BOOL VDS_CallBack_FormatVtoyEFI(void *pInterface, VDS_DISK_PROP *pDiskProp, UINT64 data)\r
+{\r
+       HRESULT hr, hr2;\r
+       ULONG completed;\r
+       IVdsAsync* pAsync;      \r
+       IVdsDiskPartitionMF *pPartitionMF = (IVdsDiskPartitionMF *)pInterface;\r
+       VDS_PARA *VdsPara = (VDS_PARA *)(ULONG)data;\r
+\r
+       (void)pDiskProp;\r
+       \r
+       hr = IVdsPartitionMF_FormatPartitionEx(pPartitionMF, VdsPara->Offset, L"FAT", 0x0100, 0, VdsPara->Name, TRUE, TRUE, FALSE, &pAsync);\r
+       while (SUCCEEDED(hr))\r
+       {\r
+               hr = IVdsAsync_QueryStatus(pAsync, &hr2, &completed);\r
+               if (SUCCEEDED(hr))\r
+               {\r
+                       hr = hr2;\r
+                       if (hr == S_OK)\r
+                       {\r
+                               Log("Disk format partition QueryStatus OK, %lu%%", completed);\r
+                               break;\r
+                       }\r
+                       else if (hr == VDS_E_OPERATION_PENDING)\r
+                       {\r
+                               Log("Disk format finish: %lu%%", completed);\r
+                               hr = S_OK;\r
+                       }\r
+                       else\r
+                       {\r
+                               Log("QueryStatus invalid status:0x%lx", hr);\r
+                       }\r
+               }\r
+               Sleep(1000);\r
+       }\r
+\r
+       if (hr != S_OK)\r
+       {\r
+               VDS_SET_ERROR(hr);\r
+               Log("Could not format partition, err:0x%lx (%s)", LASTERR, WindowsErrorString(hr));\r
+               return FALSE;\r
+       }\r
+\r
+       return TRUE;\r
+}\r
+\r
+// Not supported for removable disk\r
+BOOL VDS_FormatVtoyEFIPart(int DriveIndex, UINT64 Offset)\r
+{\r
+       VDS_PARA Para;\r
+\r
+       memset(&Para, 0, sizeof(Para));\r
+       Para.Offset = Offset;\r
+       memcpy(Para.Name, L"VTOYEFI", 7 * 2);\r
+\r
+       BOOL ret = VDS_DiskCommProc(INTF_PARTITIONMF, DriveIndex, VDS_CallBack_FormatVtoyEFI, (ULONG)&Para);\r
+       Log("VDS_FormatVtoyEFIPart %d ret:%d", DriveIndex, ret);\r
+       return ret;\r
+}
\ No newline at end of file
index 570f28eac03dae330382f20c16b90914dfd995df..2fb5273debadbcad16ab71d27127871d05468fa6 100644 (file)
@@ -20,6 +20,7 @@
  */\r
  \r
 #include <Windows.h>\r
  */\r
  \r
 #include <Windows.h>\r
+#include <time.h>\r
 #include <winternl.h>\r
 #include <commctrl.h>\r
 #include <initguid.h>\r
 #include <winternl.h>\r
 #include <commctrl.h>\r
 #include <initguid.h>\r
@@ -1827,6 +1828,103 @@ End:
     return rc;\r
 }\r
 \r
     return rc;\r
 }\r
 \r
+static BOOL BackupDataBeforeCleanDisk(int PhyDrive, UINT64 DiskSize, BYTE **pBackup)\r
+{\r
+       DWORD dwSize;\r
+       DWORD dwStatus;\r
+       BOOL Return = FALSE;\r
+       BOOL ret = FALSE;\r
+       BYTE *backup = NULL;\r
+       HANDLE hDrive = INVALID_HANDLE_VALUE;\r
+       LARGE_INTEGER liCurPosition;\r
+       LARGE_INTEGER liNewPosition;\r
+\r
+       Log("BackupDataBeforeCleanDisk %d", PhyDrive);\r
+\r
+       backup = malloc(SIZE_1MB * 3);\r
+       if (!backup)\r
+       {\r
+               goto out;\r
+       }\r
+\r
+       hDrive = GetPhysicalHandle(PhyDrive, FALSE, FALSE, FALSE);\r
+       if (hDrive == INVALID_HANDLE_VALUE)\r
+       {\r
+               goto out;\r
+       }\r
+\r
+       //read first 1MB\r
+       dwStatus = SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);\r
+       if (dwStatus != 0)\r
+       {\r
+               goto out;\r
+       }\r
+       \r
+       dwSize = 0;\r
+       ret = ReadFile(hDrive, backup, SIZE_1MB, &dwSize, NULL);\r
+       if ((!ret) || (dwSize != SIZE_1MB))\r
+       {\r
+               Log("Failed to read %d %u 0x%x", ret, dwSize, LASTERR);\r
+               goto out;\r
+       }\r
+       \r
+       liCurPosition.QuadPart = DiskSize - (SIZE_1MB * 2);\r
+       liNewPosition.QuadPart = 0;\r
+       if (0 == SetFilePointerEx(hDrive, liCurPosition, &liNewPosition, FILE_BEGIN) ||\r
+               liNewPosition.QuadPart != liCurPosition.QuadPart)\r
+       {\r
+               goto out;\r
+       }\r
+\r
+       dwSize = 0;\r
+       ret = ReadFile(hDrive, backup + SIZE_1MB, 2 * SIZE_1MB, &dwSize, NULL);\r
+       if ((!ret) || (dwSize != 2 * SIZE_1MB))\r
+       {\r
+               Log("Failed to read %d %u 0x%x", ret, dwSize, LASTERR);\r
+               goto out;\r
+       }\r
+\r
+       *pBackup = backup;\r
+       backup = NULL; //For don't free later\r
+       Return = TRUE;\r
+\r
+out:\r
+       CHECK_CLOSE_HANDLE(hDrive);\r
+       if (backup)\r
+               free(backup);\r
+\r
+       return Return;\r
+}\r
+\r
+\r
+static BOOL WriteBackupDataToDisk(HANDLE hDrive, UINT64 Offset, BYTE *Data, DWORD Length)\r
+{\r
+       DWORD dwSize = 0;\r
+       BOOL ret = FALSE;\r
+       LARGE_INTEGER liCurPosition;\r
+       LARGE_INTEGER liNewPosition;\r
+\r
+       Log("WriteBackupDataToDisk %llu %p %u", Offset, Data, Length);\r
+\r
+       liCurPosition.QuadPart = Offset;\r
+       liNewPosition.QuadPart = 0;\r
+       if (0 == SetFilePointerEx(hDrive, liCurPosition, &liNewPosition, FILE_BEGIN) ||\r
+               liNewPosition.QuadPart != liCurPosition.QuadPart)\r
+       {\r
+               return FALSE;\r
+       }\r
+\r
+       ret = WriteFile(hDrive, Data, Length, &dwSize, NULL);\r
+       if ((!ret) || dwSize != Length)\r
+       {\r
+               Log("Failed to write %d %u %u", ret, dwSize, LASTERR);\r
+               return FALSE;\r
+       }\r
+\r
+       Log("WriteBackupDataToDisk %llu %p %u success", Offset, Data, Length);\r
+       return TRUE;\r
+}\r
+\r
 \r
 int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId)\r
 {\r
 \r
 int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId)\r
 {\r
@@ -1835,6 +1933,8 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId)
        int MaxRetry = 3;\r
        BOOL ForceMBR = FALSE;\r
        BOOL Esp2Basic = FALSE;\r
        int MaxRetry = 3;\r
        BOOL ForceMBR = FALSE;\r
        BOOL Esp2Basic = FALSE;\r
+       BOOL ChangeAttr = FALSE;\r
+       BOOL CleanDisk = FALSE;\r
        HANDLE hVolume;\r
        HANDLE hDrive;\r
        DWORD Status;\r
        HANDLE hVolume;\r
        HANDLE hDrive;\r
        DWORD Status;\r
@@ -1846,6 +1946,7 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId)
        UINT64 ReservedMB = 0;\r
        MBR_HEAD BootImg;\r
        MBR_HEAD MBR;\r
        UINT64 ReservedMB = 0;\r
        MBR_HEAD BootImg;\r
        MBR_HEAD MBR;\r
+       BYTE *pBackup = NULL;\r
        VTOY_GPT_INFO *pGptInfo = NULL;\r
        UINT8 ReservedData[4096];\r
 \r
        VTOY_GPT_INFO *pGptInfo = NULL;\r
        UINT8 ReservedData[4096];\r
 \r
@@ -1935,20 +2036,43 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId)
        if (pPhyDrive->PartStyle == 1)\r
        {\r
                Log("TryId=%d EFI GPT partition type is 0x%llx", TryId, pPhyDrive->Part2GPTAttr);\r
        if (pPhyDrive->PartStyle == 1)\r
        {\r
                Log("TryId=%d EFI GPT partition type is 0x%llx", TryId, pPhyDrive->Part2GPTAttr);\r
+               PROGRESS_BAR_SET_POS(PT_DEL_ALL_PART);\r
 \r
 \r
-               if ((TryId == 1 && (pPhyDrive->Part2GPTAttr >> 56) == 0xC0) || TryId == 2)\r
+               if (TryId == 1)\r
                {\r
                {\r
-                       PROGRESS_BAR_SET_POS(PT_DEL_ALL_PART);\r
                        Log("Change GPT partition type to ESP");\r
                        Log("Change GPT partition type to ESP");\r
-\r
                        if (VDS_ChangeVtoyEFI2ESP(pPhyDrive->PhyDrive, StartSector * 512))\r
                        {\r
                                Esp2Basic = TRUE;\r
                                Sleep(1000);\r
                        }\r
                }\r
                        if (VDS_ChangeVtoyEFI2ESP(pPhyDrive->PhyDrive, StartSector * 512))\r
                        {\r
                                Esp2Basic = TRUE;\r
                                Sleep(1000);\r
                        }\r
                }\r
+               else if (TryId == 2)\r
+               {\r
+                       Log("Change GPT partition attribute");\r
+                       if (VDS_ChangeVtoyEFIAttr(pPhyDrive->PhyDrive, 0x8000000000000001))\r
+                       {\r
+                               ChangeAttr = TRUE;\r
+                               Sleep(1000);\r
+                       }\r
+               }\r
+               else if (TryId == 3)\r
+               {\r
+                       Log("Clean disk GPT partition table");\r
+                       if (BackupDataBeforeCleanDisk(pPhyDrive->PhyDrive, pPhyDrive->SizeInBytes, &pBackup))\r
+                       {\r
+                               Log("Success to backup data before clean");\r
+                               CleanDisk = TRUE;\r
+                               VDS_CleanDisk(pPhyDrive->PhyDrive);\r
+                               Sleep(1000);\r
+                       }\r
+                       else\r
+                       {\r
+                               Log("Failed to backup data before clean");\r
+                       }\r
+               }\r
        }\r
        }\r
-\r
+       \r
     PROGRESS_BAR_SET_POS(PT_LOCK_FOR_WRITE);\r
 \r
     Log("Lock disk for update ............................ ");\r
     PROGRESS_BAR_SET_POS(PT_LOCK_FOR_WRITE);\r
 \r
     Log("Lock disk for update ............................ ");\r
@@ -1966,7 +2090,12 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId)
     hVolume = INVALID_HANDLE_VALUE;\r
 \r
        //If we change VTOYEFI to ESP, it can not have s volume name, so don't try to get it.\r
     hVolume = INVALID_HANDLE_VALUE;\r
 \r
        //If we change VTOYEFI to ESP, it can not have s volume name, so don't try to get it.\r
-       if (Esp2Basic)\r
+       if (CleanDisk)\r
+       {\r
+               WriteBackupDataToDisk(hDrive, pPhyDrive->SizeInBytes - (2 * SIZE_1MB), pBackup + SIZE_1MB, 2 * SIZE_1MB);\r
+               Status = ERROR_NOT_FOUND;\r
+       }\r
+       else if (Esp2Basic)\r
        {\r
                Status = ERROR_NOT_FOUND;\r
        }\r
        {\r
                Status = ERROR_NOT_FOUND;\r
        }\r
@@ -2131,6 +2260,13 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId)
         }\r
     }\r
 \r
         }\r
     }\r
 \r
+       if (CleanDisk)\r
+       {\r
+               WriteBackupDataToDisk(hDrive, 4 * 512, pBackup + 4 * 512, SIZE_1MB - 4 * 512);\r
+               WriteBackupDataToDisk(hDrive, 0, pBackup, 4 * 512);\r
+               free(pBackup);\r
+       }\r
+\r
     //Refresh Drive Layout\r
     DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL);\r
 \r
     //Refresh Drive Layout\r
     DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL);\r
 \r
@@ -2153,6 +2289,20 @@ End:
                VDS_ChangeVtoyEFI2Basic(pPhyDrive->PhyDrive, StartSector * 512);\r
     }\r
 \r
                VDS_ChangeVtoyEFI2Basic(pPhyDrive->PhyDrive, StartSector * 512);\r
     }\r
 \r
+       if (ChangeAttr || ((pPhyDrive->Part2GPTAttr >> 56) != 0xC0))\r
+       {\r
+               Log("Change EFI partition attr %u <0x%llx> to <0x%llx>", ChangeAttr, pPhyDrive->Part2GPTAttr, 0xC000000000000001ULL);\r
+               if (VDS_ChangeVtoyEFIAttr(pPhyDrive->PhyDrive, 0xC000000000000001ULL))\r
+               {\r
+                       Log("Change EFI partition attr success");\r
+                       pPhyDrive->Part2GPTAttr = 0xC000000000000001ULL;\r
+               }\r
+               else\r
+               {\r
+                       Log("Change EFI partition attr failed");\r
+               }\r
+       }\r
+\r
     if (pGptInfo)\r
     {\r
         free(pGptInfo);\r
     if (pGptInfo)\r
     {\r
         free(pGptInfo);\r
index a2c41acdd1804812247eedd5afecd1128cd2923e..0e5852c889efb0127202e28c4de63c2f56bcc3dc 100644 (file)
Binary files a/Ventoy2Disk/Ventoy2Disk/WinDialog.c and b/Ventoy2Disk/Ventoy2Disk/WinDialog.c differ
index 2f5d970912d88578409b4800af9332fcfec47f37..39a5485d95eb9831630fa535909b51c6d5eae96d 100644 (file)
@@ -25,6 +25,7 @@
 
 
 #include <Windows.h>
 
 
 #include <Windows.h>
+#include <time.h>
 #include <winternl.h>
 #include <commctrl.h>
 #include <initguid.h>
 #include <winternl.h>
 #include <commctrl.h>
 #include <initguid.h>
@@ -471,6 +472,7 @@ int FindProcessOccupyDisk(HANDLE hDrive, PHY_DRIVE_INFO *pPhyDrive)
     char cmdline[MAX_PATH] = { 0 };
     wchar_t wexe_path[MAX_PATH], *wcmdline;
     int cur_pid;
     char cmdline[MAX_PATH] = { 0 };
     wchar_t wexe_path[MAX_PATH], *wcmdline;
     int cur_pid;
+       time_t starttime, curtime;
 
 
     Log("FindProcessOccupyDisk for PhyDrive %d", pPhyDrive->PhyDrive);
 
 
     Log("FindProcessOccupyDisk for PhyDrive %d", pPhyDrive->PhyDrive);
@@ -506,11 +508,28 @@ int FindProcessOccupyDisk(HANDLE hDrive, PHY_DRIVE_INFO *pPhyDrive)
 
        Log("handles->NumberOfHandles = %lu", (ULONG)handles->NumberOfHandles);
 
 
        Log("handles->NumberOfHandles = %lu", (ULONG)handles->NumberOfHandles);
 
+       if (handles->NumberOfHandles > 10000)
+       {
+               goto out;
+       }
+
+       starttime = time(NULL);
+
        for (i = 0; i < handles->NumberOfHandles; i++) {
         ULONG attempts = 8;
         PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handleInfo =
             (i < handles->NumberOfHandles) ? &handles->Handles[i] : NULL;
 
        for (i = 0; i < handles->NumberOfHandles; i++) {
         ULONG attempts = 8;
         PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handleInfo =
             (i < handles->NumberOfHandles) ? &handles->Handles[i] : NULL;
 
+               //limit the search time
+               if ((i % 100) == 0)
+               {
+                       curtime = time(NULL);
+                       if (curtime - starttime > 10)
+                       {
+                               break;
+                       }
+               }
+
         if ((dupHandle != NULL) && (processHandle != NtCurrentProcess())) {
             pfNtClose(dupHandle);
             dupHandle = NULL;
         if ((dupHandle != NULL) && (processHandle != NtCurrentProcess())) {
             pfNtClose(dupHandle);
             dupHandle = NULL;
@@ -665,8 +684,12 @@ out:
     else
         Log("NOTE: Could not identify the process(es) or service(s) accessing %S", _wHandleName);
 
     else
         Log("NOTE: Could not identify the process(es) or service(s) accessing %S", _wHandleName);
 
-    PhFree(buffer);
-    PhFree(handles);
+       if (buffer)
+               PhFree(buffer);
+
+       if (handles)
+               PhFree(handles);
+
     PhDestroyHeap();
 
     return 0;
     PhDestroyHeap();
 
     return 0;