*/\r
\r
#include <Windows.h>\r
+#include <time.h>\r
#include <winternl.h>\r
#include <commctrl.h>\r
#include <initguid.h>\r
-#include <vds.h>\r
#include "resource.h"\r
#include "Language.h"\r
#include "Ventoy2Disk.h"\r
#include "fat_filelib.h"\r
#include "ff.h"\r
+#include "DiskService.h"\r
\r
-/* \r
- * Some code and functions in the file are copied from rufus.\r
- * https://github.com/pbatard/rufus\r
- */\r
-#define VDS_SET_ERROR SetLastError\r
-#define IVdsServiceLoader_LoadService(This, pwszMachineName, ppService) (This)->lpVtbl->LoadService(This, pwszMachineName, ppService)\r
-#define IVdsServiceLoader_Release(This) (This)->lpVtbl->Release(This)\r
-#define IVdsService_QueryProviders(This, masks, ppEnum) (This)->lpVtbl->QueryProviders(This, masks, ppEnum)\r
-#define IVdsService_WaitForServiceReady(This) ((This)->lpVtbl->WaitForServiceReady(This))\r
-#define IVdsService_CleanupObsoleteMountPoints(This) ((This)->lpVtbl->CleanupObsoleteMountPoints(This))\r
-#define IVdsService_Refresh(This) ((This)->lpVtbl->Refresh(This))\r
-#define IVdsService_Reenumerate(This) ((This)->lpVtbl->Reenumerate(This)) \r
-#define IVdsSwProvider_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)\r
-#define IVdsProvider_Release(This) (This)->lpVtbl->Release(This)\r
-#define IVdsSwProvider_QueryPacks(This, ppEnum) (This)->lpVtbl->QueryPacks(This, ppEnum)\r
-#define IVdsSwProvider_Release(This) (This)->lpVtbl->Release(This)\r
-#define IVdsPack_QueryDisks(This, ppEnum) (This)->lpVtbl->QueryDisks(This, ppEnum)\r
-#define IVdsDisk_GetProperties(This, pDiskProperties) (This)->lpVtbl->GetProperties(This, pDiskProperties)\r
-#define IVdsDisk_Release(This) (This)->lpVtbl->Release(This)\r
-#define IVdsDisk_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)\r
-#define IVdsAdvancedDisk_QueryPartitions(This, ppPartitionPropArray, plNumberOfPartitions) (This)->lpVtbl->QueryPartitions(This, ppPartitionPropArray, plNumberOfPartitions)\r
-#define IVdsAdvancedDisk_DeletePartition(This, ullOffset, bForce, bForceProtected) (This)->lpVtbl->DeletePartition(This, ullOffset, bForce, bForceProtected)\r
-#define IVdsAdvancedDisk_Clean(This, bForce, bForceOEM, bFullClean, ppAsync) (This)->lpVtbl->Clean(This, bForce, bForceOEM, bFullClean, ppAsync)\r
-#define IVdsAdvancedDisk_Release(This) (This)->lpVtbl->Release(This)\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 IVdsVolume_Release(This) (This)->lpVtbl->Release(This)\r
-#define IVdsVolumeMF3_QueryVolumeGuidPathnames(This, pwszPathArray, pulNumberOfPaths) (This)->lpVtbl->QueryVolumeGuidPathnames(This,pwszPathArray,pulNumberOfPaths)\r
-#define IVdsVolumeMF3_FormatEx2(This, pwszFileSystemTypeName, usFileSystemRevision, ulDesiredUnitAllocationSize, pwszLabel, Options, ppAsync) (This)->lpVtbl->FormatEx2(This, pwszFileSystemTypeName, usFileSystemRevision, ulDesiredUnitAllocationSize, pwszLabel, Options, ppAsync)\r
-#define IVdsVolumeMF3_Release(This) (This)->lpVtbl->Release(This)\r
-#define IVdsVolume_GetProperties(This, pVolumeProperties) (This)->lpVtbl->GetProperties(This,pVolumeProperties)\r
-#define IVdsAsync_Cancel(This) (This)->lpVtbl->Cancel(This)\r
-#define IVdsAsync_QueryStatus(This,pHrResult,pulPercentCompleted) (This)->lpVtbl->QueryStatus(This,pHrResult,pulPercentCompleted)\r
-#define IVdsAsync_Wait(This,pHrResult,pAsyncOut) (This)->lpVtbl->Wait(This,pHrResult,pAsyncOut)\r
-#define IVdsAsync_Release(This) (This)->lpVtbl->Release(This)\r
-\r
-#define IUnknown_QueryInterface(This, a, b) (This)->lpVtbl->QueryInterface(This,a,b)\r
-#define IUnknown_Release(This) (This)->lpVtbl->Release(This)\r
-\r
-/*\r
-* Delete all the partitions from a disk, using VDS\r
-* Mostly copied from https://social.msdn.microsoft.com/Forums/vstudio/en-US/b90482ae-4e44-4b08-8731-81915030b32a/createpartition-using-vds-interface-throw-error-enointerface-dcom?forum=vcgeneral\r
-*/\r
-BOOL DeletePartitions(DWORD DriveIndex, BOOL OnlyPart2)\r
-{\r
- BOOL r = FALSE;\r
- HRESULT hr;\r
- ULONG ulFetched;\r
- wchar_t wPhysicalName[48];\r
- IVdsServiceLoader *pLoader;\r
- IVdsService *pService;\r
- IEnumVdsObject *pEnum;\r
- IUnknown *pUnk;\r
-\r
- swprintf_s(wPhysicalName, ARRAYSIZE(wPhysicalName), L"\\\\?\\PhysicalDrive%lu", DriveIndex);\r
-\r
- // Initialize COM\r
- CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);\r
- CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT,\r
- RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL);\r
-\r
- // Create a VDS Loader Instance\r
- hr = CoCreateInstance(&CLSID_VdsLoader, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,\r
- &IID_IVdsServiceLoader, (void **)&pLoader);\r
- if (hr != S_OK) {\r
- VDS_SET_ERROR(hr);\r
- Log("Could not create VDS Loader Instance: %u", LASTERR);\r
- goto out;\r
- }\r
-\r
- // Load the VDS Service\r
- hr = IVdsServiceLoader_LoadService(pLoader, L"", &pService);\r
- IVdsServiceLoader_Release(pLoader);\r
- if (hr != S_OK) {\r
- VDS_SET_ERROR(hr);\r
- Log("Could not load VDS Service: %u", LASTERR);\r
- goto out;\r
- }\r
-\r
- // Wait for the Service to become ready if needed\r
- hr = IVdsService_WaitForServiceReady(pService);\r
- if (hr != S_OK) {\r
- VDS_SET_ERROR(hr);\r
- Log("VDS Service is not ready: %u", LASTERR);\r
- goto out;\r
- }\r
-\r
- // Query the VDS Service Providers\r
- hr = IVdsService_QueryProviders(pService, VDS_QUERY_SOFTWARE_PROVIDERS, &pEnum);\r
- if (hr != S_OK) {\r
- VDS_SET_ERROR(hr);\r
- Log("Could not query VDS Service Providers: %u", LASTERR);\r
- goto out;\r
- }\r
-\r
- while (IEnumVdsObject_Next(pEnum, 1, &pUnk, &ulFetched) == S_OK) {\r
- IVdsProvider *pProvider;\r
- IVdsSwProvider *pSwProvider;\r
- IEnumVdsObject *pEnumPack;\r
- IUnknown *pPackUnk;\r
-\r
- // Get VDS Provider\r
- hr = IUnknown_QueryInterface(pUnk, &IID_IVdsProvider, (void **)&pProvider);\r
- IUnknown_Release(pUnk);\r
- if (hr != S_OK) {\r
- VDS_SET_ERROR(hr);\r
- Log("Could not get VDS Provider: %u", LASTERR);\r
- goto out;\r
- }\r
-\r
- // Get VDS Software Provider\r
- hr = IVdsSwProvider_QueryInterface(pProvider, &IID_IVdsSwProvider, (void **)&pSwProvider);\r
- IVdsProvider_Release(pProvider);\r
- if (hr != S_OK) {\r
- VDS_SET_ERROR(hr);\r
- Log("Could not get VDS Software Provider: %u", LASTERR);\r
- goto out;\r
- }\r
-\r
- // Get VDS Software Provider Packs\r
- hr = IVdsSwProvider_QueryPacks(pSwProvider, &pEnumPack);\r
- IVdsSwProvider_Release(pSwProvider);\r
- if (hr != S_OK) {\r
- VDS_SET_ERROR(hr);\r
- Log("Could not get VDS Software Provider Packs: %u", LASTERR);\r
- goto out;\r
- }\r
-\r
- // Enumerate Provider Packs\r
- while (IEnumVdsObject_Next(pEnumPack, 1, &pPackUnk, &ulFetched) == S_OK) {\r
- IVdsPack *pPack;\r
- IEnumVdsObject *pEnumDisk;\r
- IUnknown *pDiskUnk;\r
-\r
- hr = IUnknown_QueryInterface(pPackUnk, &IID_IVdsPack, (void **)&pPack);\r
- IUnknown_Release(pPackUnk);\r
- if (hr != S_OK) {\r
- VDS_SET_ERROR(hr);\r
- Log("Could not query VDS Software Provider Pack: %u", LASTERR);\r
- goto out;\r
- }\r
-\r
- // Use the pack interface to access the disks\r
- hr = IVdsPack_QueryDisks(pPack, &pEnumDisk);\r
- if (hr != S_OK) {\r
- VDS_SET_ERROR(hr);\r
- Log("Could not query VDS disks: %u", LASTERR);\r
- goto out;\r
- }\r
-\r
- // List disks\r
- while (IEnumVdsObject_Next(pEnumDisk, 1, &pDiskUnk, &ulFetched) == S_OK) {\r
- VDS_DISK_PROP diskprop;\r
- VDS_PARTITION_PROP* prop_array;\r
- LONG i, prop_array_size;\r
- IVdsDisk *pDisk;\r
- IVdsAdvancedDisk *pAdvancedDisk;\r
-\r
- // Get the disk interface.\r
- hr = IUnknown_QueryInterface(pDiskUnk, &IID_IVdsDisk, (void **)&pDisk);\r
- if (hr != S_OK) {\r
- VDS_SET_ERROR(hr);\r
- Log("Could not query VDS Disk Interface: %u", LASTERR);\r
- goto out;\r
- }\r
-\r
- // Get the disk properties\r
- hr = IVdsDisk_GetProperties(pDisk, &diskprop);\r
- if (hr != S_OK) {\r
- VDS_SET_ERROR(hr);\r
- Log("Could not query VDS Disk Properties: %u", LASTERR);\r
- goto out;\r
- }\r
-\r
- // Isolate the disk we want\r
- if (_wcsicmp(wPhysicalName, diskprop.pwszName) != 0) {\r
- IVdsDisk_Release(pDisk);\r
- continue;\r
- }\r
+static int g_backup_bin_index = 0;\r
\r
- // Instantiate the AdvanceDisk interface for our disk.\r
- hr = IVdsDisk_QueryInterface(pDisk, &IID_IVdsAdvancedDisk, (void **)&pAdvancedDisk);\r
- IVdsDisk_Release(pDisk);\r
- if (hr != S_OK) {\r
- VDS_SET_ERROR(hr);\r
- Log("Could not access VDS Advanced Disk interface: %u", LASTERR);\r
- goto out;\r
- }\r
\r
- // Query the partition data, so we can get the start offset, which we need for deletion\r
- hr = IVdsAdvancedDisk_QueryPartitions(pAdvancedDisk, &prop_array, &prop_array_size);\r
- if (hr == S_OK) {\r
- Log("Deleting ALL partition(s) from disk '%S':", diskprop.pwszName);\r
- // Now go through each partition\r
- for (i = 0; i < prop_array_size; i++) {\r
- \r
- Log("* Partition %d (offset: %lld, size: %llu)", prop_array[i].ulPartitionNumber,\r
- prop_array[i].ullOffset, (ULONGLONG)prop_array[i].ullSize);\r
-\r
- if (OnlyPart2 && prop_array[i].ullOffset == 2048*512)\r
- {\r
- Log("Skip this partition...");\r
- continue;\r
- }\r
+static BOOL WriteDataToPhyDisk(HANDLE hDrive, UINT64 Offset, VOID *buffer, DWORD len)\r
+{\r
+ BOOL bRet;\r
+ DWORD dwSize = 0;\r
+ LARGE_INTEGER liCurPosition;\r
+ LARGE_INTEGER liNewPosition;\r
\r
+ liCurPosition.QuadPart = (LONGLONG)Offset;\r
+ liNewPosition.QuadPart = 0;\r
+ if (0 == SetFilePointerEx(hDrive, liCurPosition, &liNewPosition, FILE_BEGIN) ||\r
+ liNewPosition.QuadPart != liCurPosition.QuadPart)\r
+ {\r
+ Log("SetFilePointerEx Failed %u", LASTERR);\r
+ return FALSE;\r
+ }\r
\r
- hr = IVdsAdvancedDisk_DeletePartition(pAdvancedDisk, prop_array[i].ullOffset, TRUE, TRUE);\r
- if (hr != S_OK) {\r
- r = FALSE;\r
- VDS_SET_ERROR(hr);\r
- Log("Could not delete partitions: %u", LASTERR);\r
- }\r
- }\r
- r = TRUE;\r
- }\r
- else {\r
- Log("No partition to delete on disk '%S'", diskprop.pwszName);\r
- r = TRUE;\r
- }\r
- CoTaskMemFree(prop_array);\r
-\r
-#if 0\r
- // Issue a Clean while we're at it\r
- HRESULT hr2 = E_FAIL;\r
- ULONG completed;\r
- IVdsAsync* pAsync;\r
- hr = IVdsAdvancedDisk_Clean(pAdvancedDisk, TRUE, FALSE, FALSE, &pAsync);\r
- while (SUCCEEDED(hr)) {\r
- if (IS_ERROR(FormatStatus)) {\r
- IVdsAsync_Cancel(pAsync);\r
- break;\r
- }\r
- hr = IVdsAsync_QueryStatus(pAsync, &hr2, &completed);\r
- if (SUCCEEDED(hr)) {\r
- hr = hr2;\r
- if (hr == S_OK)\r
- break;\r
- if (hr == VDS_E_OPERATION_PENDING)\r
- hr = S_OK;\r
- }\r
- Sleep(500);\r
- }\r
- if (hr != S_OK) {\r
- VDS_SET_ERROR(hr);\r
- Log("Could not clean disk: %s", LASTERR);\r
- }\r
-#endif\r
- IVdsAdvancedDisk_Release(pAdvancedDisk);\r
- goto out;\r
- }\r
- }\r
- }\r
+ bRet = WriteFile(hDrive, buffer, len, &dwSize, NULL);\r
+ if (bRet == FALSE || dwSize != len)\r
+ {\r
+ Log("Write file error %u %u", dwSize, LASTERR);\r
+ return FALSE;\r
+ }\r
\r
-out:\r
- return r;\r
+ return TRUE;\r
}\r
\r
\r
return Status;\r
}\r
\r
-static int GetLettersBelongPhyDrive(int PhyDrive, char *DriveLetters, size_t Length)\r
+int GetLettersBelongPhyDrive(int PhyDrive, char *DriveLetters, size_t Length)\r
{\r
int n = 0;\r
DWORD DataSize = 0;\r
\r
for (Pos = StringBuf; *Pos; Pos += strlen(Pos) + 1)\r
{\r
- if (n < (int)Length && PhyDrive == GetPhyDriveByLogicalDrive(Pos[0]))\r
+ if (n < (int)Length && PhyDrive == GetPhyDriveByLogicalDrive(Pos[0], NULL))\r
{\r
Log("%C: is belong to phydrive%d", Pos[0], PhyDrive);\r
DriveLetters[n++] = Pos[0];\r
return 0;\r
}\r
\r
-static HANDLE GetPhysicalHandle(int Drive, BOOLEAN bLockDrive, BOOLEAN bWriteAccess, BOOLEAN bWriteShare)\r
+HANDLE GetPhysicalHandle(int Drive, BOOLEAN bLockDrive, BOOLEAN bWriteAccess, BOOLEAN bWriteShare)\r
{\r
int i;\r
DWORD dwSize;\r
return hDrive;\r
}\r
\r
-int GetPhyDriveByLogicalDrive(int DriveLetter)\r
+int GetPhyDriveByLogicalDrive(int DriveLetter, UINT64 *Offset)\r
{\r
- BOOL Ret;\r
- DWORD dwSize;\r
- HANDLE Handle;\r
+ BOOL Ret = FALSE;\r
+ DWORD dwSize = 0;\r
+ HANDLE Handle = INVALID_HANDLE_VALUE;\r
VOLUME_DISK_EXTENTS DiskExtents;\r
CHAR PhyPath[128];\r
\r
return -1;\r
}\r
\r
+ memset(&DiskExtents, 0, sizeof(DiskExtents));\r
Ret = DeviceIoControl(Handle,\r
IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,\r
NULL,\r
}\r
CHECK_CLOSE_HANDLE(Handle);\r
\r
- Log("LogicalDrive:%s PhyDrive:%d Offset:%llu ExtentLength:%llu",\r
+ Log("LogicalDrive:%s PhyDrive:%d Num:%d Offset:%llu ExtentLength:%llu",\r
PhyPath,\r
DiskExtents.Extents[0].DiskNumber,\r
+ DiskExtents.NumberOfDiskExtents,\r
DiskExtents.Extents[0].StartingOffset.QuadPart,\r
DiskExtents.Extents[0].ExtentLength.QuadPart\r
);\r
\r
+ if (Offset)\r
+ {\r
+ *Offset = (UINT64)(DiskExtents.Extents[0].StartingOffset.QuadPart);\r
+ }\r
+\r
return (int)DiskExtents.Extents[0].DiskNumber;\r
}\r
\r
STORAGE_PROPERTY_QUERY Query;\r
STORAGE_DESCRIPTOR_HEADER DevDescHeader;\r
STORAGE_DEVICE_DESCRIPTOR *pDevDesc;\r
+ STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR diskAlignment;\r
int PhyDriveId[VENTOY_MAX_PHY_DRIVE];\r
\r
Count = GetPhysicalDriveCount();\r
{\r
if (dwBytes & 0x01)\r
{\r
- id = GetPhyDriveByLogicalDrive(Letter);\r
+ id = GetPhyDriveByLogicalDrive(Letter, NULL);\r
Log("%C --> %d", Letter, id);\r
if (id >= 0)\r
{\r
continue;\r
}\r
\r
+\r
+\r
+ memset(&Query, 0, sizeof(STORAGE_PROPERTY_QUERY));\r
+ Query.PropertyId = StorageAccessAlignmentProperty;\r
+ Query.QueryType = PropertyStandardQuery;\r
+ memset(&diskAlignment, 0, sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR));\r
+\r
+ bRet = DeviceIoControl(Handle,\r
+ IOCTL_STORAGE_QUERY_PROPERTY,\r
+ &Query,\r
+ sizeof(STORAGE_PROPERTY_QUERY),\r
+ &diskAlignment,\r
+ sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR),\r
+ &dwBytes,\r
+ NULL);\r
+ if (!bRet)\r
+ {\r
+ Log("DeviceIoControl3 error:%u dwBytes:%u", LASTERR, dwBytes); \r
+ }\r
+\r
CurDrive->PhyDrive = i;\r
CurDrive->SizeInBytes = LengthInfo.Length.QuadPart;\r
CurDrive->DeviceType = pDevDesc->DeviceType;\r
CurDrive->RemovableMedia = pDevDesc->RemovableMedia;\r
CurDrive->BusType = pDevDesc->BusType;\r
\r
+ CurDrive->BytesPerLogicalSector = diskAlignment.BytesPerLogicalSector;\r
+ CurDrive->BytesPerPhysicalSector = diskAlignment.BytesPerPhysicalSector;\r
+\r
if (pDevDesc->VendorIdOffset)\r
{\r
safe_strcpy(CurDrive->VendorId, (char *)pDevDesc + pDevDesc->VendorIdOffset);\r
\r
for (i = 0, CurDrive = pDriveList; i < (int)DriveCount; i++, CurDrive++)\r
{\r
- Log("PhyDrv:%d BusType:%-4s Removable:%u Size:%dGB(%llu) Name:%s %s",\r
+ Log("PhyDrv:%d BusType:%-4s Removable:%u Size:%dGB(%llu) Sector:%u/%u Name:%s %s",\r
CurDrive->PhyDrive, GetBusTypeString(CurDrive->BusType), CurDrive->RemovableMedia,\r
GetHumanReadableGBSize(CurDrive->SizeInBytes), CurDrive->SizeInBytes,\r
+ CurDrive->BytesPerLogicalSector, CurDrive->BytesPerPhysicalSector,\r
CurDrive->VendorId, CurDrive->ProductId);\r
}\r
\r
fl_fclose(file);\r
\r
Log("Now delete all efi files ...");\r
- fl_remove("/EFI/BOOT/BOOTX64.EFI");\r
- fl_remove("/EFI/BOOT/grubx64.efi");\r
+ fl_remove("/EFI/BOOT/BOOTX64.EFI"); \r
+ fl_remove("/EFI/BOOT/grubx64.efi"); \r
fl_remove("/EFI/BOOT/grubx64_real.efi");\r
fl_remove("/EFI/BOOT/MokManager.efi");\r
+ fl_remove("/EFI/BOOT/mmx64.efi");\r
fl_remove("/ENROLL_THIS_KEY_IN_MOKMANAGER.cer");\r
+ fl_remove("/EFI/BOOT/grub.efi");\r
\r
file = fl_fopen("/EFI/BOOT/BOOTX64.EFI", "wb");\r
Log("Open bootx64 efi file %p ", file);\r
int len = 0;\r
int writelen = 0;\r
int partwrite = 0;\r
+ int Pos = PT_WRITE_VENTOY_START;\r
DWORD dwSize = 0;\r
BOOL bRet;\r
unsigned char *data = NULL;\r
LARGE_INTEGER liCurrentPosition;\r
LARGE_INTEGER liNewPosition;\r
+ BYTE *CheckBuf = NULL;\r
+\r
+ Log("FormatPart2Fat %llu...", (ULONGLONG)StartSectorId);\r
\r
- Log("FormatPart2Fat %llu...", StartSectorId);\r
+ CheckBuf = malloc(SIZE_1MB);\r
+ if (!CheckBuf)\r
+ {\r
+ Log("Failed to malloc check buf");\r
+ return 1;\r
+ }\r
\r
rc = ReadWholeFileToBuf(VENTOY_FILE_DISK_IMG, 0, (void **)&data, &len);\r
if (rc)\r
{\r
Log("Failed to read img file %p %u", data, len);\r
+ free(CheckBuf);\r
return 1;\r
}\r
\r
liCurrentPosition.QuadPart = StartSectorId * 512;\r
- SetFilePointerEx(hDrive, liCurrentPosition, &liNewPosition, FILE_BEGIN);\r
-\r
- Log("Set file pointer: %llu New pointer:%llu", liCurrentPosition.QuadPart, liNewPosition.QuadPart);\r
+ SetFilePointerEx(hDrive, liCurrentPosition, &liNewPosition, FILE_BEGIN);\r
\r
memset(g_part_img_buf, 0, sizeof(g_part_img_buf));\r
\r
goto End;\r
}\r
\r
- PROGRESS_BAR_SET_POS(PT_WRITE_VENTOY_START + i); \r
+ PROGRESS_BAR_SET_POS(Pos);\r
+ if (i % 2 == 0)\r
+ {\r
+ Pos++;\r
+ }\r
+ }\r
+\r
+ //Read and check the data\r
+ liCurrentPosition.QuadPart = StartSectorId * 512;\r
+ SetFilePointerEx(hDrive, liCurrentPosition, &liNewPosition, FILE_BEGIN);\r
+\r
+ for (i = 0; i < VENTOY_EFI_PART_SIZE / SIZE_1MB; i++)\r
+ {\r
+ bRet = ReadFile(hDrive, CheckBuf, SIZE_1MB, &dwSize, NULL);\r
+ Log("Read part data bRet:%u dwSize:%u code:%u", bRet, dwSize, LASTERR);\r
+\r
+ if (!bRet || memcmp(CheckBuf, g_part_img_buf[0] + i * SIZE_1MB, SIZE_1MB))\r
+ {\r
+ Log("### [Check Fail] The data write and read does not match");\r
+ rc = 1;\r
+ goto End;\r
+ }\r
+\r
+ PROGRESS_BAR_SET_POS(Pos);\r
+ if (i % 2 == 0)\r
+ {\r
+ Pos++;\r
+ }\r
}\r
}\r
else\r
\r
VentoyProcSecureBoot(g_SecureBoot);\r
\r
- for (int i = 0; i < VENTOY_EFI_PART_SIZE / SIZE_1MB; i++)\r
+ for (i = 0; i < VENTOY_EFI_PART_SIZE / SIZE_1MB; i++)\r
{\r
dwSize = 0;\r
bRet = WriteFile(hDrive, g_part_img_buf[i], SIZE_1MB, &dwSize, NULL);\r
rc = 1;\r
goto End;\r
}\r
+ \r
+ PROGRESS_BAR_SET_POS(Pos);\r
+ if (i % 2 == 0)\r
+ {\r
+ Pos++;\r
+ }\r
+ }\r
+\r
+ //Read and check the data\r
+ liCurrentPosition.QuadPart = StartSectorId * 512;\r
+ SetFilePointerEx(hDrive, liCurrentPosition, &liNewPosition, FILE_BEGIN);\r
+\r
+ for (i = 0; i < VENTOY_EFI_PART_SIZE / SIZE_1MB; i++)\r
+ {\r
+ bRet = ReadFile(hDrive, CheckBuf, SIZE_1MB, &dwSize, NULL);\r
+ Log("Read part data bRet:%u dwSize:%u code:%u", bRet, dwSize, LASTERR);\r
+\r
+ if (!bRet || memcmp(CheckBuf, g_part_img_buf[i], SIZE_1MB))\r
+ {\r
+ Log("### [Check Fail] The data write and read does not match");\r
+ rc = 1;\r
+ goto End;\r
+ }\r
\r
- PROGRESS_BAR_SET_POS(PT_WRITE_VENTOY_START + i);\r
+ PROGRESS_BAR_SET_POS(Pos);\r
+ if (i % 2 == 0)\r
+ {\r
+ Pos++;\r
+ }\r
}\r
}\r
else\r
End:\r
\r
if (data) free(data);\r
+ if (CheckBuf)free(CheckBuf);\r
\r
if (partwrite)\r
{\r
}\r
\r
\r
+static int FormatPart1LargeFAT32(UINT64 DiskSizeBytes, int CluserSize)\r
+{\r
+ MKFS_PARM Option;\r
+ FRESULT Ret;\r
+ FATFS FS;\r
+\r
+ Option.fmt = FM_FAT32;\r
+ Option.n_fat = 1;\r
+ Option.align = 8;\r
+ Option.n_root = 1;\r
+\r
+ if (CluserSize == 0)\r
+ {\r
+ // < 32GB select 32KB as cluster size\r
+ // > 32GB select 128KB as cluster size\r
+ if (DiskSizeBytes / 1024 / 1024 / 1024 <= 32)\r
+ {\r
+ Option.au_size = 32768;\r
+ }\r
+ else\r
+ {\r
+ Option.au_size = 131072;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ Option.au_size = CluserSize;\r
+ }\r
+\r
+ Log("Formatting Part1 large FAT32 ClusterSize:%u(%uKB) ...", CluserSize, CluserSize / 1024);\r
+\r
+ disk_io_reset_write_error();\r
+\r
+ Ret = f_mkfs(TEXT("0:"), &Option, 0, 8 * 1024 * 1024);\r
+ if (FR_OK == Ret)\r
+ {\r
+ if (disk_io_is_write_error())\r
+ {\r
+ Log("Formatting Part1 large FAT32 failed, write error.");\r
+ return 1;\r
+ }\r
+\r
+ Log("Formatting Part1 large FAT32 success, now set label");\r
+ \r
+ Ret = f_mount(&FS, TEXT("0:"), 1);\r
+ if (FR_OK == Ret)\r
+ {\r
+ Log("f_mount SUCCESS");\r
+ Ret = f_setlabel(TEXT("0:Ventoy"));\r
+ if (FR_OK == Ret)\r
+ {\r
+ Log("f_setlabel SUCCESS");\r
+ Ret = f_unmount(TEXT("0:"));\r
+ Log("f_unmount %d %s", Ret, (FR_OK == Ret) ? "SUCCESS" : "FAILED");\r
+ }\r
+ else\r
+ {\r
+ Log("f_setlabel failed %d", Ret);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ Log("f_mount failed %d", Ret);\r
+ }\r
+\r
+ return 0;\r
+ }\r
+ else\r
+ {\r
+ Log("Formatting Part1 large FAT32 failed");\r
+ return 1;\r
+ }\r
+}\r
\r
static int FormatPart1exFAT(UINT64 DiskSizeBytes)\r
{\r
MKFS_PARM Option;\r
FRESULT Ret;\r
- FATFS fs;\r
\r
Option.fmt = FM_EXFAT;\r
Option.n_fat = 1;\r
\r
Log("Formatting Part1 exFAT ...");\r
\r
- Ret = f_mkfs(TEXT("0:"), &Option, 0, 8 * 1024 * 1024);\r
+ disk_io_reset_write_error();\r
\r
+ Ret = f_mkfs(TEXT("0:"), &Option, 0, 8 * 1024 * 1024);\r
if (FR_OK == Ret)\r
{\r
- Log("Formatting Part1 exFAT success");\r
-\r
- Ret = f_mount(&fs, TEXT("0:"), 1);\r
- Log("mount part %d", Ret);\r
-\r
- if (FR_OK == Ret)\r
- {\r
- Ret = f_setlabel(TEXT("Ventoy"));\r
- Log("f_setlabel %d", Ret);\r
+ if (disk_io_is_write_error())\r
+ {\r
+ Log("Formatting Part1 exFAT failed, write error.");\r
+ return 1;\r
+ }\r
\r
- Ret = f_mount(0, TEXT("0:"), 1);\r
- Log("umount part %d", Ret);\r
- return 0;\r
- }\r
- else\r
- {\r
- Log("mount exfat failed %d", Ret);\r
- return 1;\r
- }\r
+ Log("Formatting Part1 exFAT success");\r
+ return 0;\r
}\r
else\r
{\r
}\r
}\r
\r
+static int ZeroPart1FileSystem(HANDLE hDrive, UINT64 Part2StartSector)\r
+{\r
+ int i;\r
+ DWORD dwSize = 0;\r
+ LARGE_INTEGER liCurPos;\r
+ LARGE_INTEGER liNewPos;\r
+ CHAR TmpBuffer[1024] = { 0 };\r
+\r
+ liCurPos.QuadPart = VENTOY_PART1_START_SECTOR * 512;\r
+ liNewPos.QuadPart = 0;\r
+ if (0 == SetFilePointerEx(hDrive, liCurPos, &liNewPos, FILE_BEGIN) ||\r
+ liNewPos.QuadPart != liCurPos.QuadPart)\r
+ {\r
+ Log("SetFilePointerEx Failed %u %llu %llu", LASTERR, (ULONGLONG)liCurPos.QuadPart, (ULONGLONG)liNewPos.QuadPart);\r
+ return 1;\r
+ }\r
+\r
+ for (i = 0; i < 1024; i++)\r
+ {\r
+ WriteFile(hDrive, TmpBuffer, 1024, &dwSize, NULL);\r
+ }\r
+\r
+ liCurPos.QuadPart = (Part2StartSector * 512) - (1024 * 1024);\r
+ liNewPos.QuadPart = 0;\r
+ if (0 == SetFilePointerEx(hDrive, liCurPos, &liNewPos, FILE_BEGIN) ||\r
+ liNewPos.QuadPart != liCurPos.QuadPart)\r
+ {\r
+ Log("SetFilePointerEx Failed %u %llu %llu", LASTERR, (ULONGLONG)liCurPos.QuadPart, (ULONGLONG)liNewPos.QuadPart);\r
+ return 1;\r
+ }\r
+\r
+ for (i = 0; i < 1024; i++)\r
+ {\r
+ WriteFile(hDrive, TmpBuffer, 1024, &dwSize, NULL);\r
+ }\r
\r
+ Log("Zero Part1 SUCCESS");\r
+ return 0;\r
+}\r
\r
int ClearVentoyFromPhyDrive(HWND hWnd, PHY_DRIVE_INFO *pPhyDrive, char *pDrvLetter)\r
{\r
\r
PROGRESS_BAR_SET_POS(PT_DEL_ALL_PART);\r
\r
- if (!DeletePartitions(pPhyDrive->PhyDrive, FALSE))\r
+ if (!VDS_DeleteAllPartitions(pPhyDrive->PhyDrive))\r
{\r
Log("Notice: Could not delete partitions: %u", GetLastError());\r
}\r
End:\r
\r
PROGRESS_BAR_SET_POS(PT_MOUNT_VOLUME);\r
+ PROGRESS_BAR_SET_POS(PT_REFORMAT_FINISH);\r
\r
if (pTmpBuf)\r
{\r
return rc;\r
}\r
\r
-int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle)\r
+int InstallVentoy2FileImage(PHY_DRIVE_INFO *pPhyDrive, int PartStyle)\r
{\r
int i;\r
- int rc = 0;\r
- int state = 0;\r
- HANDLE hDrive;\r
- DWORD dwSize;\r
- BOOL bRet;\r
- CHAR MountDrive;\r
- CHAR DriveName[] = "?:\\";\r
- CHAR DriveLetters[MAX_PATH] = { 0 };\r
- MBR_HEAD MBR;\r
- VTOY_GPT_INFO *pGptInfo = NULL;\r
+ int rc = 1;\r
+ int Len = 0;\r
+ int dataLen = 0;\r
+ UINT size = 0;\r
+ UINT segnum = 0;\r
+ UINT32 chksum = 0;\r
+ UINT64 data_offset = 0;\r
+ UINT64 Part2StartSector = 0;\r
UINT64 Part1StartSector = 0;\r
UINT64 Part1SectorCount = 0;\r
- UINT64 Part2StartSector = 0;\r
-\r
+ UINT8 *pData = NULL; \r
+ UINT8 *pBkGptPartTbl = NULL;\r
+ BYTE *ImgBuf = NULL;\r
+ MBR_HEAD *pMBR = NULL;\r
+ VTSI_FOOTER *pImgFooter = NULL;\r
+ VTSI_SEGMENT *pSegment = NULL;\r
+ VTOY_GPT_INFO *pGptInfo = NULL;\r
+ VTOY_GPT_HDR *pBkGptHdr = NULL;\r
+ FILE *fp = NULL;\r
\r
- Log("InstallVentoy2PhyDrive %s PhyDrive%d <<%s %s %dGB>>",\r
+ Log("InstallVentoy2FileImage %s PhyDrive%d <<%s %s %dGB>>",\r
PartStyle ? "GPT" : "MBR", pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId,\r
GetHumanReadableGBSize(pPhyDrive->SizeInBytes));\r
\r
- if (PartStyle)\r
+ PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN);\r
+\r
+ size = SIZE_1MB + VENTOY_EFI_PART_SIZE + 33 * 512 + VTSI_IMG_MAX_SEG * sizeof(VTSI_SEGMENT) + sizeof(VTSI_FOOTER);\r
+\r
+ pData = (UINT8 *)malloc(size);\r
+ if (!pData)\r
{\r
- pGptInfo = malloc(sizeof(VTOY_GPT_INFO));\r
- memset(pGptInfo, 0, sizeof(VTOY_GPT_INFO));\r
+ Log("malloc image buffer failed %d.", size);\r
+ goto End;\r
}\r
\r
- PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN);\r
+ pImgFooter = (VTSI_FOOTER *)(pData + size - sizeof(VTSI_FOOTER));\r
+ pSegment = (VTSI_SEGMENT *)((UINT8 *)pImgFooter - VTSI_IMG_MAX_SEG * sizeof(VTSI_SEGMENT));\r
+ memset(pImgFooter, 0, sizeof(VTSI_FOOTER));\r
+ memset(pSegment, 0, VTSI_IMG_MAX_SEG * sizeof(VTSI_SEGMENT));\r
+\r
+ PROGRESS_BAR_SET_POS(PT_WRITE_VENTOY_START);\r
+\r
+ Log("Writing Boot Image ............................. ");\r
+ if (ReadWholeFileToBuf(VENTOY_FILE_STG1_IMG, 0, (void **)&ImgBuf, &Len))\r
+ {\r
+ Log("Failed to read stage1 img");\r
+ goto End;\r
+ }\r
+\r
+ unxz(ImgBuf, Len, NULL, NULL, pData, &dataLen, unxz_error);\r
+ SAFE_FREE(ImgBuf);\r
+\r
+ Log("decompress %s len:%d", VENTOY_FILE_STG1_IMG, dataLen);\r
\r
if (PartStyle)\r
{\r
+ pData[500] = 35;//update blocklist\r
+ memmove(pData + 34 * 512, pData, SIZE_1MB - 512 * 34);\r
+ memset(pData, 0, 34 * 512);\r
+\r
+ pGptInfo = (VTOY_GPT_INFO *)pData;\r
+ memset(pGptInfo, 0, sizeof(VTOY_GPT_INFO));\r
VentoyFillGpt(pPhyDrive->SizeInBytes, pGptInfo);\r
+\r
+ pBkGptPartTbl = pData + SIZE_1MB + VENTOY_EFI_PART_SIZE;\r
+ memset(pBkGptPartTbl, 0, 33 * 512);\r
+\r
+ memcpy(pBkGptPartTbl, pGptInfo->PartTbl, 32 * 512);\r
+ pBkGptHdr = (VTOY_GPT_HDR *)(pBkGptPartTbl + 32 * 512);\r
+ VentoyFillBackupGptHead(pGptInfo, pBkGptHdr);\r
+\r
Part1StartSector = pGptInfo->PartTbl[0].StartLBA;\r
Part1SectorCount = pGptInfo->PartTbl[0].LastLBA - Part1StartSector + 1;\r
Part2StartSector = pGptInfo->PartTbl[1].StartLBA;\r
+\r
+ Log("Write GPT Info OK ...");\r
}\r
else\r
{\r
- VentoyFillMBR(pPhyDrive->SizeInBytes, &MBR, PartStyle);\r
- Part1StartSector = MBR.PartTbl[0].StartSectorId;\r
- Part1SectorCount = MBR.PartTbl[0].SectorCount;\r
- Part2StartSector = MBR.PartTbl[1].StartSectorId;\r
- }\r
+ memmove(pData + 512, pData, SIZE_1MB - 512);\r
+ memset(pData, 0, 512);\r
\r
- Log("Lock disk for clean ............................. ");\r
+ pMBR = (MBR_HEAD *)pData;\r
+ VentoyFillMBR(pPhyDrive->SizeInBytes, pMBR, PartStyle, 0x07);\r
+ Part1StartSector = pMBR->PartTbl[0].StartSectorId;\r
+ Part1SectorCount = pMBR->PartTbl[0].SectorCount;\r
+ Part2StartSector = pMBR->PartTbl[1].StartSectorId;\r
\r
- hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, FALSE, FALSE);\r
- if (hDrive == INVALID_HANDLE_VALUE)\r
- {\r
- Log("Failed to open physical disk");\r
- free(pGptInfo);\r
- return 1;\r
+ Log("Write MBR OK ...");\r
}\r
\r
- GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters));\r
+ Log("Writing EFI part Image ............................. ");\r
+ rc = ReadWholeFileToBuf(VENTOY_FILE_DISK_IMG, 0, (void **)&ImgBuf, &Len);\r
+ if (rc)\r
+ {\r
+ Log("Failed to read img file %p %u", ImgBuf, Len);\r
+ goto End;\r
+ }\r
\r
- if (DriveLetters[0] == 0)\r
+ PROGRESS_BAR_SET_POS(PT_WRITE_VENTOY_START + 28);\r
+ memset(g_part_img_buf, 0, sizeof(g_part_img_buf));\r
+ unxz(ImgBuf, Len, NULL, NULL, pData + SIZE_1MB, &dataLen, unxz_error);\r
+ if (dataLen == Len)\r
{\r
- Log("No drive letter was assigned...");\r
- DriveName[0] = GetFirstUnusedDriveLetter();\r
- Log("GetFirstUnusedDriveLetter %C: ...", DriveName[0]);\r
+ Log("decompress finished success");\r
+ g_part_img_buf[0] = pData + SIZE_1MB;\r
+\r
+ VentoyProcSecureBoot(g_SecureBoot);\r
}\r
else\r
{\r
- // Unmount all mounted volumes that belong to this drive\r
- // Do it in reverse so that we always end on the first volume letter\r
- for (i = (int)strlen(DriveLetters); i > 0; i--)\r
- {\r
- DriveName[0] = DriveLetters[i - 1];\r
- bRet = DeleteVolumeMountPointA(DriveName);\r
- Log("Delete mountpoint %s ret:%u code:%u", DriveName, bRet, GetLastError());\r
- }\r
+ Log("decompress finished failed");\r
+ goto End;\r
}\r
\r
- MountDrive = DriveName[0];\r
- Log("Will use '%C:' as volume mountpoint", DriveName[0]);\r
-\r
- // It kind of blows, but we have to relinquish access to the physical drive\r
- // for VDS to be able to delete the partitions that reside on it...\r
- DeviceIoControl(hDrive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);\r
- CHECK_CLOSE_HANDLE(hDrive);\r
-\r
- PROGRESS_BAR_SET_POS(PT_DEL_ALL_PART);\r
-\r
- if (!DeletePartitions(pPhyDrive->PhyDrive, FALSE))\r
+ fopen_s(&fp, "VentoySparseImg.vtsi", "wb+");\r
+ if (!fp)\r
{\r
- Log("Notice: Could not delete partitions: %u", GetLastError());\r
+ Log("Failed to create Ventoy img file");\r
+ goto End;\r
}\r
\r
- Log("Deleting all partitions ......................... OK");\r
+ Log("Writing stage1 data ............................. ");\r
\r
- PROGRESS_BAR_SET_POS(PT_LOCK_FOR_WRITE);\r
+ fwrite(pData, 1, SIZE_1MB, fp);\r
\r
- Log("Lock disk for write ............................. ");\r
+ pSegment[0].disk_start_sector = 0;\r
+ pSegment[0].sector_num = SIZE_1MB / 512;\r
+ pSegment[0].data_offset = data_offset;\r
+ data_offset += pSegment[0].sector_num * 512;\r
+\r
+ disk_io_set_param(INVALID_HANDLE_VALUE, Part1StartSector + Part1SectorCount);// include the 2048 sector gap\r
+ disk_io_set_imghook(fp, pSegment + 1, VTSI_IMG_MAX_SEG - 1, data_offset);\r
+\r
+ Log("Formatting part1 exFAT ...");\r
+ if (0 != FormatPart1exFAT(pPhyDrive->SizeInBytes))\r
+ {\r
+ Log("FormatPart1exFAT failed.");\r
+ disk_io_reset_imghook(&segnum, &data_offset);\r
+ goto End;\r
+ }\r
+\r
+ disk_io_reset_imghook(&segnum, &data_offset);\r
+ segnum++;\r
+\r
+ Log("current segment number:%d dataoff:%ld", segnum, (long)data_offset);\r
+\r
+ //write data\r
+ Log("Writing part2 data ............................. ");\r
+ fwrite(pData + SIZE_1MB, 1, VENTOY_EFI_PART_SIZE, fp);\r
+ pSegment[segnum].disk_start_sector = Part2StartSector;\r
+ pSegment[segnum].sector_num = VENTOY_EFI_PART_SIZE / 512;\r
+ pSegment[segnum].data_offset = data_offset;\r
+ data_offset += pSegment[segnum].sector_num * 512;\r
+ segnum++;\r
+\r
+ if (PartStyle)\r
+ {\r
+ Log("Writing backup gpt table ............................. ");\r
+ fwrite(pBkGptPartTbl, 1, 33 * 512, fp);\r
+ pSegment[segnum].disk_start_sector = pPhyDrive->SizeInBytes / 512 - 33;\r
+ pSegment[segnum].sector_num = 33;\r
+ pSegment[segnum].data_offset = data_offset;\r
+ data_offset += pSegment[segnum].sector_num * 512;\r
+ segnum++;\r
+ }\r
+\r
+ Log("Writing segment metadata ............................. ");\r
+\r
+ for (i = 0; i < (int)segnum; i++)\r
+ {\r
+ Log("SEG[%d]: PhySector:%llu SectorNum:%llu DataOffset:%llu(sector:%llu)", i, pSegment[i].disk_start_sector, pSegment[i].sector_num,\r
+ pSegment[i].data_offset, pSegment[i].data_offset / 512);\r
+ }\r
+\r
+ dataLen = segnum * sizeof(VTSI_SEGMENT);\r
+ fwrite(pSegment, 1, dataLen, fp);\r
+\r
+ if (dataLen % 512)\r
+ {\r
+ //pData + SIZE_1MB - 8192 is a temp data buffer with zero\r
+ fwrite(pData + SIZE_1MB - 8192, 1, 512 - (dataLen % 512), fp);\r
+ }\r
+\r
+ //Fill footer\r
+ pImgFooter->magic = VTSI_IMG_MAGIC;\r
+ pImgFooter->version = 1;\r
+ pImgFooter->disk_size = pPhyDrive->SizeInBytes;\r
+ memcpy(&pImgFooter->disk_signature, pPhyDrive->MBR.BootCode + 0x1b8, 4);\r
+ pImgFooter->segment_num = segnum;\r
+ pImgFooter->segment_offset = data_offset;\r
+\r
+ for (i = 0, chksum = 0; i < (int)(segnum * sizeof(VTSI_SEGMENT)); i++)\r
+ {\r
+ chksum += *((UINT8 *)pSegment + i);\r
+ }\r
+ pImgFooter->segment_chksum = ~chksum;\r
+\r
+ for (i = 0, chksum = 0; i < sizeof(VTSI_FOOTER); i++)\r
+ {\r
+ chksum += *((UINT8 *)pImgFooter + i);\r
+ }\r
+ pImgFooter->foot_chksum = ~chksum;\r
+\r
+ Log("Writing footer segnum(%u) segoffset(%llu) ......................", segnum, data_offset);\r
+ Log("disk_size=%llu disk_signature=%lx segment_offset=%llu", pImgFooter->disk_size, pImgFooter->disk_signature, pImgFooter->segment_offset);\r
+\r
+ fwrite(pImgFooter, 1, sizeof(VTSI_FOOTER), fp);\r
+ fclose(fp);\r
+\r
+ Log("Writing Ventoy image file finished, the file size should be %llu .", data_offset + 512 + ((dataLen + 511) / 512 * 512));\r
+\r
+ rc = 0;\r
+\r
+End:\r
+\r
+ PROGRESS_BAR_SET_POS(PT_MOUNT_VOLUME);\r
+ PROGRESS_BAR_SET_POS(PT_REFORMAT_FINISH);\r
+\r
+ Log("retcode:%d\n", rc);\r
+\r
+ SAFE_FREE(pData);\r
+ SAFE_FREE(ImgBuf);\r
+ \r
+ return rc;\r
+}\r
+\r
+\r
+int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle, int TryId)\r
+{\r
+ int i;\r
+ int rc = 0;\r
+ int state = 0;\r
+ BOOL ReformatOK;\r
+ HANDLE hDrive;\r
+ DWORD dwSize;\r
+ BOOL bRet;\r
+ CHAR MountDrive;\r
+ CHAR DriveName[] = "?:\\";\r
+ CHAR DriveLetters[MAX_PATH] = { 0 };\r
+ MBR_HEAD MBR;\r
+ VTOY_GPT_INFO *pGptInfo = NULL;\r
+ UINT64 Part1StartSector = 0;\r
+ UINT64 Part1SectorCount = 0;\r
+ UINT64 Part2StartSector = 0;\r
+ BOOL LargeFAT32 = FALSE;\r
+ BOOL DefaultExFAT = FALSE;\r
+ UINT8 FsFlag = 0x07;\r
+\r
+ Log("#####################################################");\r
+ Log("InstallVentoy2PhyDrive try%d %s PhyDrive%d <<%s %s %dGB>>", TryId,\r
+ PartStyle ? "GPT" : "MBR", pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId,\r
+ GetHumanReadableGBSize(pPhyDrive->SizeInBytes));\r
+ Log("#####################################################");\r
+\r
+ if (PartStyle)\r
+ {\r
+ pGptInfo = malloc(sizeof(VTOY_GPT_INFO));\r
+ memset(pGptInfo, 0, sizeof(VTOY_GPT_INFO));\r
+ }\r
+\r
+ PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN);\r
+\r
+ if (PartStyle)\r
+ {\r
+ VentoyFillGpt(pPhyDrive->SizeInBytes, pGptInfo);\r
+ Part1StartSector = pGptInfo->PartTbl[0].StartLBA;\r
+ Part1SectorCount = pGptInfo->PartTbl[0].LastLBA - Part1StartSector + 1;\r
+ Part2StartSector = pGptInfo->PartTbl[1].StartLBA;\r
+ }\r
+ else\r
+ {\r
+ if (GetVentoyFsType() == VTOY_FS_FAT32)\r
+ {\r
+ FsFlag = 0x0C;\r
+ }\r
+\r
+ VentoyFillMBR(pPhyDrive->SizeInBytes, &MBR, PartStyle, FsFlag);\r
+ Part1StartSector = MBR.PartTbl[0].StartSectorId;\r
+ Part1SectorCount = MBR.PartTbl[0].SectorCount;\r
+ Part2StartSector = MBR.PartTbl[1].StartSectorId;\r
+ }\r
+\r
+ Log("Lock disk for clean ............................. ");\r
+\r
+ hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, FALSE, FALSE);\r
+ if (hDrive == INVALID_HANDLE_VALUE)\r
+ {\r
+ Log("Failed to open physical disk");\r
+ free(pGptInfo);\r
+ return 1;\r
+ }\r
+\r
+ GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters));\r
+\r
+ if (DriveLetters[0] == 0)\r
+ {\r
+ Log("No drive letter was assigned...");\r
+ DriveName[0] = GetFirstUnusedDriveLetter();\r
+ Log("GetFirstUnusedDriveLetter %C: ...", DriveName[0]);\r
+ }\r
+ else\r
+ {\r
+ // Unmount all mounted volumes that belong to this drive\r
+ // Do it in reverse so that we always end on the first volume letter\r
+ for (i = (int)strlen(DriveLetters); i > 0; i--)\r
+ {\r
+ DriveName[0] = DriveLetters[i - 1];\r
+ bRet = DeleteVolumeMountPointA(DriveName);\r
+ Log("Delete mountpoint %s ret:%u code:%u", DriveName, bRet, GetLastError());\r
+ }\r
+ }\r
+\r
+ MountDrive = DriveName[0];\r
+ Log("Will use '%C:' as volume mountpoint", DriveName[0]);\r
+\r
+ // It kind of blows, but we have to relinquish access to the physical drive\r
+ // for VDS to be able to delete the partitions that reside on it...\r
+ DeviceIoControl(hDrive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);\r
+ CHECK_CLOSE_HANDLE(hDrive);\r
+\r
+ PROGRESS_BAR_SET_POS(PT_DEL_ALL_PART);\r
+\r
+ if (!VDS_DeleteAllPartitions(pPhyDrive->PhyDrive))\r
+ {\r
+ Log("Notice: Could not delete partitions: 0x%x, but we continue.", GetLastError());\r
+ }\r
+\r
+ Log("Deleting all partitions ......................... OK");\r
+\r
+ PROGRESS_BAR_SET_POS(PT_LOCK_FOR_WRITE);\r
+\r
+ Log("Lock disk for write ............................. ");\r
hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, TRUE, FALSE);\r
if (hDrive == INVALID_HANDLE_VALUE)\r
{\r
Sleep(1000 * 5);\r
}\r
\r
- Log("Formatting part1 exFAT ...");\r
- if (0 != FormatPart1exFAT(pPhyDrive->SizeInBytes))\r
+ if (GetVentoyFsType() == VTOY_FS_FAT32 && (Part1SectorCount * 512 >= FAT32_MAX_LIMIT))\r
{\r
- Log("FormatPart1exFAT failed.");\r
- rc = 1;\r
- goto End;\r
+ Log("Formatting part1 large FAT32 ...");\r
+ LargeFAT32 = TRUE;\r
+ if (0 != FormatPart1LargeFAT32(pPhyDrive->SizeInBytes, GetClusterSize()))\r
+ {\r
+ Log("FormatPart1LargeFAT32 failed.");\r
+ rc = 1;\r
+ goto End;\r
+ }\r
+ }\r
+ else if (GetVentoyFsType() == VTOY_FS_EXFAT && GetClusterSize() == 0)\r
+ {\r
+ Log("Formatting part1 exFAT ...");\r
+ DefaultExFAT = TRUE;\r
+ if (0 != FormatPart1exFAT(pPhyDrive->SizeInBytes))\r
+ {\r
+ Log("FormatPart1exFAT failed.");\r
+ rc = 1;\r
+ goto End;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ Log("Zero part1 file system ...");\r
+ if (0 != ZeroPart1FileSystem(hDrive, Part2StartSector))\r
+ {\r
+ Log("ZeroPart1FileSystem failed.");\r
+ rc = 1;\r
+ goto End;\r
+ }\r
}\r
-\r
- \r
\r
PROGRESS_BAR_SET_POS(PT_FORMAT_PART2);\r
Log("Writing part2 FAT img ...");\r
}\r
\r
PROGRESS_BAR_SET_POS(PT_WRITE_STG1_IMG);\r
- Log("Writting Boot Image ............................. ");\r
+ Log("Writing Boot Image ............................. ");\r
if (WriteGrubStage1ToPhyDrive(hDrive, PartStyle) != 0)\r
{\r
Log("WriteGrubStage1ToPhyDrive failed.");\r
}\r
\r
PROGRESS_BAR_SET_POS(PT_WRITE_PART_TABLE);\r
- Log("Writting Partition Table ........................ ");\r
+ Log("Writing Partition Table ........................ ");\r
SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);\r
\r
if (PartStyle)\r
memcpy(&(pPhyDrive->MBR), &MBR, 512);\r
}\r
\r
- //Refresh Drive Layout\r
- DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL);\r
+ //Refresh Drive Layout\r
+ DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL);\r
+\r
+End:\r
+\r
+ PROGRESS_BAR_SET_POS(PT_MOUNT_VOLUME);\r
+\r
+ if (rc == 0)\r
+ {\r
+ Log("Mounting Ventoy Partition ....................... ");\r
+ Sleep(1000);\r
+\r
+ state = 0;\r
+ memset(DriveLetters, 0, sizeof(DriveLetters));\r
+ GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters));\r
+ Log("Logical drive letter after write ventoy: <%s>", DriveLetters);\r
+\r
+ for (i = 0; i < sizeof(DriveLetters) && DriveLetters[i]; i++)\r
+ {\r
+ DriveName[0] = DriveLetters[i];\r
+ if (IsVentoyLogicalDrive(DriveName[0]))\r
+ {\r
+ Log("%s is ventoy part2, delete mountpoint", DriveName);\r
+ DeleteVolumeMountPointA(DriveName);\r
+ }\r
+ else\r
+ {\r
+ Log("%s is ventoy part1, already mounted", DriveName);\r
+ MountDrive = DriveName[0];\r
+ state = 1;\r
+ }\r
+ }\r
+\r
+ if (state != 1)\r
+ {\r
+ Log("need to mount ventoy part1...");\r
+ \r
+ if (0 == GetVentoyVolumeName(pPhyDrive->PhyDrive, Part1StartSector, DriveLetters, sizeof(DriveLetters), FALSE))\r
+ {\r
+ DriveName[0] = MountDrive;\r
+ bRet = SetVolumeMountPointA(DriveName, DriveLetters);\r
+ Log("SetVolumeMountPoint <%s> <%s> bRet:%u code:%u", DriveName, DriveLetters, bRet, GetLastError());\r
+\r
+ if (bRet)\r
+ {\r
+ state = 1;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ Log("Failed to find ventoy volume");\r
+ }\r
+ }\r
+\r
+ // close handle, or it will deny reformat\r
+ Log("Close handle ...");\r
+ CHECK_CLOSE_HANDLE(hDrive);\r
+\r
+ ReformatOK = TRUE;\r
+\r
+ if (state)\r
+ {\r
+ if (LargeFAT32)\r
+ {\r
+ Log("No need to reformat for large FAT32");\r
+ pPhyDrive->VentoyFsClusterSize = GetVolumeClusterSize(MountDrive);\r
+ }\r
+ else if (DefaultExFAT)\r
+ {\r
+ Log("No need to reformat for default exfat");\r
+ pPhyDrive->VentoyFsClusterSize = GetVolumeClusterSize(MountDrive);\r
+ }\r
+ else\r
+ {\r
+ bRet = DISK_FormatVolume(MountDrive, GetVentoyFsType(), Part1SectorCount * 512);\r
+ for (i = 0; bRet == FALSE && i < 2; i++)\r
+ {\r
+ Log("Wait and retry reformat ...");\r
+ Sleep(1000);\r
+ bRet = DISK_FormatVolume(MountDrive, GetVentoyFsType(), Part1SectorCount * 512);\r
+ }\r
+\r
+ if (bRet)\r
+ {\r
+ Log("Reformat %C:\\ to %s SUCCESS", MountDrive, GetVentoyFsName());\r
+ pPhyDrive->VentoyFsClusterSize = GetVolumeClusterSize(MountDrive);\r
+\r
+ if ((GetVentoyFsType() != VTOY_FS_UDF) && (pPhyDrive->VentoyFsClusterSize < 2048))\r
+ {\r
+ for (i = 0; i < 10; i++)\r
+ {\r
+ Log("### Invalid cluster size %d ###", pPhyDrive->VentoyFsClusterSize);\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ ReformatOK = FALSE;\r
+ Log("Reformat %C:\\ to %s FAILED", MountDrive, GetVentoyFsName());\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ Log("Can not reformat %s to %s", DriveName, GetVentoyFsName());\r
+ }\r
+\r
+ if (!ReformatOK)\r
+ {\r
+ Log("Format to exfat with built-in algorithm");\r
+\r
+ hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, TRUE, FALSE);\r
+ if (hDrive == INVALID_HANDLE_VALUE)\r
+ {\r
+ Log("Failed to GetPhysicalHandle for write.");\r
+ }\r
+ else\r
+ {\r
+ if (0 != FormatPart1exFAT(pPhyDrive->SizeInBytes))\r
+ {\r
+ Log("FormatPart1exFAT SUCCESS.");\r
+ }\r
+ else\r
+ {\r
+ Log("FormatPart1exFAT FAILED.");\r
+ }\r
+\r
+ CHECK_CLOSE_HANDLE(hDrive);\r
+ }\r
+ }\r
+\r
+ Log("OK\n");\r
+ }\r
+ else\r
+ {\r
+ PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN);\r
+\r
+ FindProcessOccupyDisk(hDrive, pPhyDrive);\r
+\r
+ if (!VDS_IsLastAvaliable())\r
+ {\r
+ Log("###### [Error:] Virtual Disk Service (VDS) Unavailable ######");\r
+ Log("###### [Error:] Virtual Disk Service (VDS) Unavailable ######");\r
+ Log("###### [Error:] Virtual Disk Service (VDS) Unavailable ######");\r
+ Log("###### [Error:] Virtual Disk Service (VDS) Unavailable ######");\r
+ Log("###### [Error:] Virtual Disk Service (VDS) Unavailable ######");\r
+ }\r
+\r
+ CHECK_CLOSE_HANDLE(hDrive);\r
+ }\r
+\r
+ if (pGptInfo)\r
+ {\r
+ free(pGptInfo);\r
+ }\r
+ \r
+ return rc;\r
+}\r
+\r
+\r
+int PartitionResizeForVentoy(PHY_DRIVE_INFO *pPhyDrive)\r
+{\r
+ int i, j;\r
+ int rc = 1;\r
+ int PhyDrive;\r
+ int PartStyle;\r
+ UINT64 RecudeBytes;\r
+ GUID Guid;\r
+ MBR_HEAD MBR;\r
+ VTOY_GPT_INFO *pGPT;\r
+ MBR_HEAD *pMBR;\r
+ DWORD dwSize = 0;\r
+ VTOY_GPT_HDR BackupHead;\r
+ HANDLE hDrive = INVALID_HANDLE_VALUE;\r
+ GUID ZeroGuid = { 0 };\r
+ static GUID WindowsDataPartType = { 0xebd0a0a2, 0xb9e5, 0x4433, { 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7 } };\r
+ static GUID EspPartType = { 0xc12a7328, 0xf81f, 0x11d2, { 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } };\r
+ static GUID BiosGrubPartType = { 0x21686148, 0x6449, 0x6e6f, { 0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49 } };\r
+\r
+ Log("#####################################################");\r
+ Log("PartitionResizeForVentoy PhyDrive%d <<%s %s %dGB>>",\r
+ pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId,\r
+ GetHumanReadableGBSize(pPhyDrive->SizeInBytes));\r
+ Log("#####################################################");\r
+\r
+ pGPT = &(pPhyDrive->Gpt);\r
+ pMBR = &(pPhyDrive->Gpt.MBR);\r
+ Log("Disksize:%llu Part2Start:%llu", pPhyDrive->SizeInBytes, pPhyDrive->ResizePart2StartSector * 512);\r
+\r
+ if (pMBR->PartTbl[0].FsFlag == 0xEE && memcmp(pGPT->Head.Signature, "EFI PART", 8) == 0)\r
+ {\r
+ PartStyle = 1;\r
+ }\r
+ else\r
+ {\r
+ PartStyle = 0;\r
+ }\r
+\r
+ PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN);\r
+\r
+ RecudeBytes = VENTOY_EFI_PART_SIZE;\r
+\r
+ if (pPhyDrive->ResizeNoShrink == FALSE)\r
+ {\r
+ Log("Need to shrink the volume");\r
+ if (DISK_ShrinkVolume(pPhyDrive->PhyDrive, pPhyDrive->ResizeVolumeGuid, pPhyDrive->Part1DriveLetter, pPhyDrive->ResizeOldPart1Size, RecudeBytes))\r
+ {\r
+ Log("Shrink volume success, now check again");\r
+\r
+ hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, TRUE, FALSE);\r
+ if (hDrive == INVALID_HANDLE_VALUE)\r
+ {\r
+ Log("Failed to GetPhysicalHandle for update.");\r
+ goto End;\r
+ }\r
+\r
+ //Refresh Drive Layout\r
+ DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL);\r
+\r
+ CHECK_CLOSE_HANDLE(hDrive);\r
+\r
+\r
+ if (PartResizePreCheck(NULL) && pPhyDrive->ResizeNoShrink)\r
+ {\r
+ Log("Recheck after Shrink volume success");\r
+ Log("After shrink Disksize:%llu Part2Start:%llu", pPhyDrive->SizeInBytes, pPhyDrive->ResizePart2StartSector * 512);\r
+ }\r
+ else\r
+ {\r
+ Log("Recheck after Shrink volume failed %u", pPhyDrive->ResizeNoShrink);\r
+ goto End;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ Log("Shrink volume failed");\r
+ goto End;\r
+ }\r
+ }\r
+\r
+\r
+ //Now try write data\r
+ hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, TRUE, FALSE);\r
+ if (hDrive == INVALID_HANDLE_VALUE)\r
+ {\r
+ Log("Failed to GetPhysicalHandle for update.");\r
+ goto End;\r
+ }\r
+\r
+\r
+ //Write partition 2 data\r
+ PROGRESS_BAR_SET_POS(PT_FORMAT_PART2);\r
+ if (0 != FormatPart2Fat(hDrive, pPhyDrive->ResizePart2StartSector))\r
+ {\r
+ Log("FormatPart2Fat failed.");\r
+ goto End;\r
+ }\r
+\r
+ //Write grub stage2 gap\r
+ PROGRESS_BAR_SET_POS(PT_WRITE_STG1_IMG);\r
+ Log("Writing Boot Image ............................. ");\r
+ if (WriteGrubStage1ToPhyDrive(hDrive, PartStyle) != 0)\r
+ {\r
+ Log("WriteGrubStage1ToPhyDrive failed.");\r
+ goto End;\r
+ }\r
+\r
+\r
+ //Write partition table\r
+ PROGRESS_BAR_SET_POS(PT_WRITE_PART_TABLE);\r
+ Log("Writing partition table ............................. ");\r
+\r
+ VentoyGetLocalBootImg(&MBR);\r
+ CoCreateGuid(&Guid);\r
+ memcpy(MBR.BootCode + 0x180, &Guid, 16);\r
+ memcpy(pMBR->BootCode, MBR.BootCode, 440);\r
+\r
+ if (PartStyle == 0)\r
+ {\r
+ for (i = 1; i < 4; i++)\r
+ {\r
+ if (pMBR->PartTbl[i].SectorCount == 0)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (i >= 4)\r
+ {\r
+ Log("Can not find MBR free partition table");\r
+ goto End;\r
+ }\r
+\r
+ for (j = i - 1; j > 0; j--)\r
+ {\r
+ Log("Move MBR partition table %d --> %d", j + 1, j + 2);\r
+ memcpy(pMBR->PartTbl + (j + 1), pMBR->PartTbl + j, sizeof(PART_TABLE));\r
+ }\r
+\r
+ memset(pMBR->PartTbl + 1, 0, sizeof(PART_TABLE));\r
+ VentoyFillMBRLocation(pPhyDrive->SizeInBytes, (UINT32)pPhyDrive->ResizePart2StartSector, VENTOY_EFI_PART_SIZE / 512, pMBR->PartTbl + 1);\r
+ pMBR->PartTbl[0].Active = 0x80; // bootable\r
+ pMBR->PartTbl[1].Active = 0x00;\r
+ pMBR->PartTbl[1].FsFlag = 0xEF; // EFI System Partition\r
+\r
+ if (!WriteDataToPhyDisk(hDrive, 0, pMBR, 512))\r
+ {\r
+ Log("Legacy BIOS write MBR failed");\r
+ goto End;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ for (i = 1; i < 128; i++)\r
+ {\r
+ if (memcmp(&(pGPT->PartTbl[i].PartGuid), &ZeroGuid, sizeof(GUID)) == 0)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (i >= 128)\r
+ {\r
+ Log("Can not find GPT free partition table");\r
+ goto End;\r
+ }\r
+\r
+ for (j = i - 1; j > 0; j--)\r
+ {\r
+ Log("Move GPT partition table %d --> %d", j + 1, j + 2);\r
+ memcpy(pGPT->PartTbl + (j + 1), pGPT->PartTbl + j, sizeof(VTOY_GPT_PART_TBL));\r
+ }\r
+\r
+\r
+ pMBR->BootCode[92] = 0x22;\r
+\r
+ // to fix windows issue\r
+ memset(pGPT->PartTbl + 1, 0, sizeof(VTOY_GPT_PART_TBL));\r
+ memcpy(&(pGPT->PartTbl[1].PartType), &WindowsDataPartType, sizeof(GUID));\r
+ CoCreateGuid(&(pGPT->PartTbl[1].PartGuid));\r
+\r
+ pGPT->PartTbl[1].StartLBA = pGPT->PartTbl[0].LastLBA + 1;\r
+ pGPT->PartTbl[1].LastLBA = pGPT->PartTbl[1].StartLBA + VENTOY_EFI_PART_SIZE / 512 - 1;\r
+ pGPT->PartTbl[1].Attr = 0xC000000000000001ULL;\r
+ memcpy(pGPT->PartTbl[1].Name, L"VTOYEFI", 7 * 2);\r
+\r
+ //Update CRC\r
+ pGPT->Head.PartTblCrc = VentoyCrc32(pGPT->PartTbl, sizeof(pGPT->PartTbl));\r
+ pGPT->Head.Crc = 0;\r
+ pGPT->Head.Crc = VentoyCrc32(&(pGPT->Head), pGPT->Head.Length);\r
+\r
+ Log("pGPT->Head.EfiStartLBA=%llu", (ULONGLONG)pGPT->Head.EfiStartLBA);\r
+ Log("pGPT->Head.EfiBackupLBA=%llu", (ULONGLONG)pGPT->Head.EfiBackupLBA);\r
+\r
+ VentoyFillBackupGptHead(pGPT, &BackupHead);\r
+ if (!WriteDataToPhyDisk(hDrive, pGPT->Head.EfiBackupLBA * 512, &BackupHead, 512))\r
+ {\r
+ Log("UEFI write backup head failed");\r
+ goto End;\r
+ }\r
+\r
+ if (!WriteDataToPhyDisk(hDrive, (pGPT->Head.EfiBackupLBA - 32) * 512, pGPT->PartTbl, 512 * 32))\r
+ {\r
+ Log("UEFI write backup partition table failed");\r
+ goto End;\r
+ }\r
+\r
+ if (!WriteDataToPhyDisk(hDrive, 0, pGPT, 512 * 34))\r
+ {\r
+ Log("UEFI write MBR & Main partition table failed");\r
+ goto End;\r
+ }\r
+ }\r
+\r
+\r
+\r
+ //Refresh Drive Layout\r
+ DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL);\r
+ \r
+ //We must close handle here, because it will block the refresh bellow\r
+ CHECK_CLOSE_HANDLE(hDrive);\r
+\r
+ Sleep(2000);\r
+\r
+ if (g_CLI_Mode)\r
+ {\r
+ Log("### Ventoy non-destructive CLI installation successfully finished.");\r
+ }\r
+ else\r
+ {\r
+ //Refresh disk list\r
+ PhyDrive = pPhyDrive->PhyDrive;\r
+\r
+ Log("#### Now Refresh PhyDrive ####");\r
+ Ventoy2DiskDestroy();\r
+ Ventoy2DiskInit();\r
+\r
+ pPhyDrive = GetPhyDriveInfoByPhyDrive(PhyDrive);\r
+ if (pPhyDrive)\r
+ {\r
+ if (pPhyDrive->VentoyVersion[0] == 0)\r
+ {\r
+ Log("After process the Ventoy version is still invalid");\r
+ goto End;\r
+ }\r
+\r
+ Log("### Ventoy non-destructive installation successfully finished <%s>", pPhyDrive->VentoyVersion);\r
+ }\r
+ else\r
+ {\r
+ Log("### Ventoy non-destructive installation successfully finished <not found>");\r
+ }\r
+\r
+ InitComboxCtrl(g_DialogHwnd, PhyDrive);\r
+ }\r
+\r
+ rc = 0;\r
+\r
+End:\r
+ CHECK_CLOSE_HANDLE(hDrive);\r
+ return rc;\r
+}\r
+\r
+\r
+static BOOL DiskCheckWriteAccess(HANDLE hDrive)\r
+{\r
+ DWORD dwSize;\r
+ BOOL ret = FALSE;\r
+ BOOL bRet = FALSE;\r
+ BYTE Buffer[512];\r
+ LARGE_INTEGER liCurPosition;\r
+ LARGE_INTEGER liNewPosition;\r
+\r
+ liCurPosition.QuadPart = 2039 * 512;\r
+ liNewPosition.QuadPart = 0;\r
+ if (0 == SetFilePointerEx(hDrive, liCurPosition, &liNewPosition, FILE_BEGIN) ||\r
+ liNewPosition.QuadPart != liCurPosition.QuadPart)\r
+ {\r
+ Log("SetFilePointer1 Failed %u", LASTERR);\r
+ goto out;\r
+ }\r
+\r
+\r
+ dwSize = 0;\r
+ ret = ReadFile(hDrive, Buffer, 512, &dwSize, NULL);\r
+ if ((!ret) || (dwSize != 512))\r
+ {\r
+ Log("Failed to read %d %u 0x%x", ret, dwSize, LASTERR);\r
+ goto out;\r
+ }\r
+\r
+\r
+ liCurPosition.QuadPart = 2039 * 512;\r
+ liNewPosition.QuadPart = 0;\r
+ if (0 == SetFilePointerEx(hDrive, liCurPosition, &liNewPosition, FILE_BEGIN) ||\r
+ liNewPosition.QuadPart != liCurPosition.QuadPart)\r
+ {\r
+ Log("SetFilePointer2 Failed %u", LASTERR);\r
+ goto out;\r
+ }\r
+\r
+ dwSize = 0;\r
+ ret = WriteFile(hDrive, Buffer, 512, &dwSize, NULL);\r
+ if ((!ret) || dwSize != 512)\r
+ {\r
+ Log("Failed to write %d %u %u", ret, dwSize, LASTERR);\r
+ goto out;\r
+ }\r
+\r
+ bRet = TRUE;\r
+\r
+out:\r
+ \r
+ return bRet;\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
+ UINT64 offset;\r
+ HANDLE hDrive = INVALID_HANDLE_VALUE;\r
+ LARGE_INTEGER liCurPosition;\r
+ LARGE_INTEGER liNewPosition;\r
+ VTOY_GPT_INFO *pGPT = NULL;\r
+\r
+ Log("BackupDataBeforeCleanDisk %d", PhyDrive);\r
+\r
+ // step1: check write access\r
+ hDrive = GetPhysicalHandle(PhyDrive, TRUE, TRUE, FALSE);\r
+ if (hDrive == INVALID_HANDLE_VALUE)\r
+ {\r
+ Log("Failed to GetPhysicalHandle for write.");\r
+ goto out;\r
+ }\r
+\r
+ if (DiskCheckWriteAccess(hDrive))\r
+ {\r
+ Log("DiskCheckWriteAccess success");\r
+ CHECK_CLOSE_HANDLE(hDrive);\r
+ }\r
+ else\r
+ {\r
+ Log("DiskCheckWriteAccess failed");\r
+ goto out;\r
+ }\r
+\r
+ //step2 backup 4MB data\r
+ backup = malloc(SIZE_1MB * 4);\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 2MB\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_2MB, &dwSize, NULL);\r
+ if ((!ret) || (dwSize != SIZE_2MB))\r
+ {\r
+ Log("Failed to read %d %u 0x%x", ret, dwSize, LASTERR);\r
+ goto out;\r
+ }\r
+ \r
+ pGPT = (VTOY_GPT_INFO *)backup;\r
+ offset = pGPT->Head.EfiBackupLBA * 512;\r
+ if (offset >= (DiskSize - SIZE_2MB) && offset < DiskSize)\r
+ {\r
+ Log("EFI partition table check success"); \r
+ }\r
+ else\r
+ {\r
+ Log("Backup EFI LBA not in last 2MB range: %llu", pGPT->Head.EfiBackupLBA);\r
+ goto out;\r
+ }\r
+\r
+ //read last 2MB\r
+ liCurPosition.QuadPart = DiskSize - SIZE_2MB;\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_2MB, SIZE_2MB, &dwSize, NULL);\r
+ if ((!ret) || (dwSize != SIZE_2MB))\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
-End:\r
+out:\r
+ CHECK_CLOSE_HANDLE(hDrive);\r
+ if (backup)\r
+ free(backup);\r
\r
- PROGRESS_BAR_SET_POS(PT_MOUNT_VOLUME);\r
+ return Return;\r
+}\r
\r
- if (rc == 0)\r
- {\r
- Log("Mounting Ventoy Partition ....................... ");\r
- Sleep(1000);\r
\r
- state = 0;\r
- memset(DriveLetters, 0, sizeof(DriveLetters));\r
- GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters));\r
- Log("Logical drive letter after write ventoy: <%s>", DriveLetters);\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
- for (i = 0; i < sizeof(DriveLetters) && DriveLetters[i]; i++)\r
- {\r
- DriveName[0] = DriveLetters[i];\r
- if (IsVentoyLogicalDrive(DriveName[0]))\r
- {\r
- Log("%s is ventoy part2, delete mountpoint", DriveName);\r
- DeleteVolumeMountPointA(DriveName);\r
- }\r
- else\r
- {\r
- Log("%s is ventoy part1, already mounted", DriveName);\r
- state = 1;\r
- }\r
- }\r
+ Log("WriteBackupDataToDisk %llu %p %u", Offset, Data, Length);\r
\r
- if (state != 1)\r
- {\r
- Log("need to mount ventoy part1...");\r
- \r
- if (0 == GetVentoyVolumeName(pPhyDrive->PhyDrive, Part1StartSector, DriveLetters, sizeof(DriveLetters), FALSE))\r
- {\r
- DriveName[0] = MountDrive;\r
- bRet = SetVolumeMountPointA(DriveName, DriveLetters);\r
- Log("SetVolumeMountPoint <%s> <%s> bRet:%u code:%u", DriveName, DriveLetters, bRet, GetLastError());\r
- }\r
- else\r
- {\r
- Log("Failed to find ventoy volume");\r
- }\r
- }\r
- Log("OK\n");\r
- }\r
- else\r
- {\r
- FindProcessOccupyDisk(hDrive, pPhyDrive);\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
- if (pGptInfo)\r
- {\r
- free(pGptInfo);\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
- CHECK_CLOSE_HANDLE(hDrive);\r
- return rc;\r
+ Log("WriteBackupDataToDisk %llu %p %u success", Offset, Data, Length);\r
+ return TRUE;\r
}\r
\r
-int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)\r
+\r
+int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId)\r
{\r
- int i;\r
- int rc = 0;\r
- BOOL ForceMBR = FALSE;\r
- HANDLE hVolume;\r
- HANDLE hDrive;\r
- DWORD Status;\r
- DWORD dwSize;\r
- BOOL bRet;\r
- CHAR DriveName[] = "?:\\";\r
- CHAR DriveLetters[MAX_PATH] = { 0 };\r
- UINT64 StartSector;\r
+ int i;\r
+ int rc = 0;\r
+ int MaxRetry = 4;\r
+ BOOL ForceMBR = FALSE;\r
+ BOOL Esp2Basic = FALSE;\r
+ BOOL ChangeAttr = FALSE;\r
+ BOOL CleanDisk = FALSE;\r
+ BOOL DelEFI = FALSE;\r
+ BOOL bWriteBack = TRUE;\r
+ HANDLE hVolume;\r
+ HANDLE hDrive;\r
+ DWORD Status;\r
+ DWORD dwSize;\r
+ BOOL bRet;\r
+ CHAR DriveName[] = "?:\\";\r
+ CHAR DriveLetters[MAX_PATH] = { 0 };\r
+ CHAR BackBinFile[MAX_PATH];\r
+ UINT64 StartSector;\r
UINT64 ReservedMB = 0;\r
- MBR_HEAD BootImg;\r
- MBR_HEAD MBR;\r
- VTOY_GPT_INFO *pGptInfo = NULL;\r
- UINT8 ReservedData[4096];\r
+ MBR_HEAD BootImg;\r
+ MBR_HEAD MBR;\r
+ BYTE *pBackup = NULL;\r
+ VTOY_GPT_INFO *pGptInfo = NULL;\r
+ VTOY_GPT_INFO *pGptBkup = NULL;\r
+ UINT8 ReservedData[4096];\r
\r
- Log("UpdateVentoy2PhyDrive %s PhyDrive%d <<%s %s %dGB>>",\r
- pPhyDrive->PartStyle ? "GPT" : "MBR", pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId,\r
- GetHumanReadableGBSize(pPhyDrive->SizeInBytes));\r
+ Log("#####################################################");\r
+ Log("UpdateVentoy2PhyDrive try%d %s PhyDrive%d <<%s %s %dGB>>", TryId,\r
+ pPhyDrive->PartStyle ? "GPT" : "MBR", pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId,\r
+ GetHumanReadableGBSize(pPhyDrive->SizeInBytes));\r
+ Log("#####################################################");\r
\r
- PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN);\r
+ PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN);\r
\r
- Log("Lock disk for umount ............................ ");\r
+ Log("Lock disk for umount ............................ ");\r
\r
- hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, FALSE, FALSE);\r
- if (hDrive == INVALID_HANDLE_VALUE)\r
- {\r
- Log("Failed to open physical disk");\r
- return 1;\r
- }\r
+ hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, FALSE, FALSE);\r
+ if (hDrive == INVALID_HANDLE_VALUE)\r
+ {\r
+ Log("Failed to open physical disk");\r
+ return 1;\r
+ }\r
\r
- if (pPhyDrive->PartStyle)\r
- {\r
- pGptInfo = malloc(sizeof(VTOY_GPT_INFO));\r
- if (!pGptInfo)\r
- {\r
- return 1;\r
- }\r
+ if (pPhyDrive->PartStyle)\r
+ {\r
+ pGptInfo = malloc(2 * sizeof(VTOY_GPT_INFO));\r
+ if (!pGptInfo)\r
+ {\r
+ return 1;\r
+ }\r
\r
- memset(pGptInfo, 0, sizeof(VTOY_GPT_INFO));\r
+ memset(pGptInfo, 0, 2 * sizeof(VTOY_GPT_INFO));\r
+ pGptBkup = pGptInfo + 1;\r
\r
- // Read GPT Info\r
- SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);\r
- ReadFile(hDrive, pGptInfo, sizeof(VTOY_GPT_INFO), &dwSize, NULL);\r
+ // Read GPT Info\r
+ SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);\r
+ ReadFile(hDrive, pGptInfo, sizeof(VTOY_GPT_INFO), &dwSize, NULL);\r
+ memcpy(pGptBkup, pGptInfo, sizeof(VTOY_GPT_INFO));\r
\r
- //MBR will be used to compare with local boot image\r
- memcpy(&MBR, &pGptInfo->MBR, sizeof(MBR_HEAD));\r
+ //MBR will be used to compare with local boot image\r
+ memcpy(&MBR, &pGptInfo->MBR, sizeof(MBR_HEAD));\r
\r
- StartSector = pGptInfo->PartTbl[1].StartLBA;\r
- Log("GPT StartSector in PartTbl:%llu", (ULONGLONG)StartSector);\r
+ StartSector = pGptInfo->PartTbl[1].StartLBA;\r
+ Log("GPT StartSector in PartTbl:%llu", (ULONGLONG)StartSector);\r
\r
- ReservedMB = (pPhyDrive->SizeInBytes / 512 - (StartSector + VENTOY_EFI_PART_SIZE / 512) - 33) / 2048;\r
- Log("GPT Reserved Disk Space:%llu MB", (ULONGLONG)ReservedMB);\r
- }\r
- else\r
- {\r
- // Read MBR\r
- SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);\r
- ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL);\r
+ ReservedMB = (pPhyDrive->SizeInBytes / 512 - (StartSector + VENTOY_EFI_PART_SIZE / 512) - 33) / 2048;\r
+ Log("GPT Reserved Disk Space:%llu MB", (ULONGLONG)ReservedMB);\r
+ }\r
+ else\r
+ {\r
+ // Read MBR\r
+ SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);\r
+ ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL);\r
\r
- StartSector = MBR.PartTbl[1].StartSectorId;\r
- Log("MBR StartSector in PartTbl:%llu", (ULONGLONG)StartSector);\r
+ StartSector = MBR.PartTbl[1].StartSectorId;\r
+ Log("MBR StartSector in PartTbl:%llu", (ULONGLONG)StartSector);\r
\r
- ReservedMB = (pPhyDrive->SizeInBytes / 512 - (StartSector + VENTOY_EFI_PART_SIZE / 512)) / 2048;\r
- Log("MBR Reserved Disk Space:%llu MB", (ULONGLONG)ReservedMB);\r
- }\r
+ ReservedMB = (pPhyDrive->SizeInBytes / 512 - (StartSector + VENTOY_EFI_PART_SIZE / 512)) / 2048;\r
+ Log("MBR Reserved Disk Space:%llu MB", (ULONGLONG)ReservedMB);\r
+ }\r
\r
- //Read Reserved Data\r
- SetFilePointer(hDrive, 512 * 2040, NULL, FILE_BEGIN);\r
- ReadFile(hDrive, ReservedData, sizeof(ReservedData), &dwSize, NULL);\r
+ //Read Reserved Data\r
+ SetFilePointer(hDrive, 512 * 2040, NULL, FILE_BEGIN);\r
+ ReadFile(hDrive, ReservedData, sizeof(ReservedData), &dwSize, NULL);\r
\r
- GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters));\r
+ GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters));\r
\r
- if (DriveLetters[0] == 0)\r
- {\r
- Log("No drive letter was assigned...");\r
- }\r
- else\r
- {\r
- // Unmount all mounted volumes that belong to this drive\r
- // Do it in reverse so that we always end on the first volume letter\r
- for (i = (int)strlen(DriveLetters); i > 0; i--)\r
- {\r
- DriveName[0] = DriveLetters[i - 1];\r
- if (IsVentoyLogicalDrive(DriveName[0]))\r
- {\r
- Log("%s is ventoy logical drive", DriveName);\r
- bRet = DeleteVolumeMountPointA(DriveName);\r
- Log("Delete mountpoint %s ret:%u code:%u", DriveName, bRet, LASTERR);\r
- break;\r
- }\r
- }\r
- }\r
+ if (DriveLetters[0] == 0)\r
+ {\r
+ Log("No drive letter was assigned...");\r
+ }\r
+ else\r
+ {\r
+ // Unmount all mounted volumes that belong to this drive\r
+ // Do it in reverse so that we always end on the first volume letter\r
+ for (i = (int)strlen(DriveLetters); i > 0; i--)\r
+ {\r
+ DriveName[0] = DriveLetters[i - 1];\r
+ if (IsVentoyLogicalDrive(DriveName[0]))\r
+ {\r
+ Log("%s is ventoy logical drive", DriveName);\r
+ bRet = DeleteVolumeMountPointA(DriveName);\r
+ Log("Delete mountpoint %s ret:%u code:%u", DriveName, bRet, LASTERR);\r
+ break;\r
+ }\r
+ }\r
+ }\r
\r
- // It kind of blows, but we have to relinquish access to the physical drive\r
- // for VDS to be able to delete the partitions that reside on it...\r
- DeviceIoControl(hDrive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);\r
- CHECK_CLOSE_HANDLE(hDrive);\r
+ // It kind of blows, but we have to relinquish access to the physical drive\r
+ // for VDS to be able to delete the partitions that reside on it...\r
+ DeviceIoControl(hDrive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);\r
+ CHECK_CLOSE_HANDLE(hDrive);\r
+\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
+ if (TryId == 1)\r
+ {\r
+ Log("Change GPT partition type to ESP");\r
+ if (DISK_ChangeVtoyEFI2ESP(pPhyDrive->PhyDrive, StartSector * 512ULL))\r
+ {\r
+ Esp2Basic = TRUE;\r
+ Sleep(3000);\r
+ }\r
+ }\r
+ else if (TryId == 2)\r
+ {\r
+ Log("Change GPT partition attribute");\r
+ if (DISK_ChangeVtoyEFIAttr(pPhyDrive->PhyDrive, StartSector * 512ULL, 0x8000000000000001))\r
+ {\r
+ ChangeAttr = TRUE;\r
+ Sleep(2000);\r
+ }\r
+ }\r
+ else if (TryId == 3)\r
+ {\r
+ DISK_DeleteVtoyEFIPartition(pPhyDrive->PhyDrive, StartSector * 512ULL);\r
+ DelEFI = TRUE;\r
+ }\r
+ else if (TryId == 4)\r
+ {\r
+ Log("Clean disk GPT partition table");\r
+ if (BackupDataBeforeCleanDisk(pPhyDrive->PhyDrive, pPhyDrive->SizeInBytes, &pBackup))\r
+ {\r
+ sprintf_s(BackBinFile, sizeof(BackBinFile), ".\\ventoy\\phydrive%d_%u_%d.bin",\r
+ pPhyDrive->PhyDrive, GetCurrentProcessId(), g_backup_bin_index++);\r
+ SaveBufToFile(BackBinFile, pBackup, 4 * SIZE_1MB);\r
+ Log("Save backup data to %s", BackBinFile);\r
+\r
+ Log("Success to backup data before clean");\r
+ CleanDisk = TRUE;\r
+ DISK_CleanDisk(pPhyDrive->PhyDrive);\r
+ Sleep(3000);\r
+ }\r
+ else\r
+ {\r
+ Log("Failed to backup data before clean");\r
+ }\r
+ }\r
+ }\r
+ \r
PROGRESS_BAR_SET_POS(PT_LOCK_FOR_WRITE);\r
\r
Log("Lock disk for update ............................ ");\r
\r
Log("Lock volume for update .......................... ");\r
hVolume = INVALID_HANDLE_VALUE;\r
- Status = GetVentoyVolumeName(pPhyDrive->PhyDrive, StartSector, DriveLetters, sizeof(DriveLetters), TRUE);\r
+\r
+ //If we change VTOYEFI to ESP, it can not have s volume name, so don't try to get it.\r
+ if (CleanDisk)\r
+ {\r
+ //writeback the last 2MB\r
+ if (!WriteBackupDataToDisk(hDrive, pPhyDrive->SizeInBytes - SIZE_2MB, pBackup + SIZE_2MB, SIZE_2MB))\r
+ {\r
+ bWriteBack = FALSE;\r
+ }\r
+\r
+ //write the first 2MB except parttable\r
+ if (!WriteBackupDataToDisk(hDrive, 34 * 512, pBackup + 34 * 512, SIZE_2MB - 34 * 512))\r
+ {\r
+ bWriteBack = FALSE;\r
+ }\r
+\r
+ Status = ERROR_NOT_FOUND;\r
+ }\r
+ else if (DelEFI)\r
+ {\r
+ Status = ERROR_NOT_FOUND;\r
+ }\r
+ else if (Esp2Basic)\r
+ {\r
+ Status = ERROR_NOT_FOUND;\r
+ }\r
+ else\r
+ {\r
+ for (i = 0; i < MaxRetry; i++)\r
+ {\r
+ Status = GetVentoyVolumeName(pPhyDrive->PhyDrive, StartSector, DriveLetters, sizeof(DriveLetters), TRUE);\r
+ if (ERROR_SUCCESS == Status)\r
+ {\r
+ break;\r
+ }\r
+ else\r
+ {\r
+ Log("==== Volume not found, wait and retry %d... ====", i);\r
+ Sleep(2);\r
+ }\r
+ }\r
+ }\r
+ \r
if (ERROR_SUCCESS == Status)\r
{\r
Log("Now lock and dismount volume <%s>", DriveLetters);\r
- hVolume = CreateFileA(DriveLetters,\r
- GENERIC_READ | GENERIC_WRITE,\r
- FILE_SHARE_READ,\r
- NULL,\r
- OPEN_EXISTING,\r
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,\r
- NULL);\r
+\r
+ for (i = 0; i < MaxRetry; i++)\r
+ {\r
+ hVolume = CreateFileA(DriveLetters,\r
+ GENERIC_READ | GENERIC_WRITE,\r
+ FILE_SHARE_READ,\r
+ NULL,\r
+ OPEN_EXISTING,\r
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,\r
+ NULL);\r
+\r
+ if (hVolume == INVALID_HANDLE_VALUE)\r
+ {\r
+ Log("Failed to create file volume, errcode:%u, wait and retry ...", LASTERR);\r
+ Sleep(2000);\r
+ }\r
+ else\r
+ {\r
+ break;\r
+ }\r
+ }\r
\r
if (hVolume == INVALID_HANDLE_VALUE)\r
{\r
Log("Failed to create file volume, errcode:%u", LASTERR);\r
- rc = 1;\r
- goto End;\r
}\r
+ else\r
+ {\r
+ bRet = DeviceIoControl(hVolume, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);\r
+ Log("FSCTL_LOCK_VOLUME bRet:%u code:%u", bRet, LASTERR);\r
\r
- bRet = DeviceIoControl(hVolume, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);\r
- Log("FSCTL_LOCK_VOLUME bRet:%u code:%u", bRet, LASTERR);\r
-\r
- bRet = DeviceIoControl(hVolume, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);\r
- Log("FSCTL_DISMOUNT_VOLUME bRet:%u code:%u", bRet, LASTERR);\r
+ bRet = DeviceIoControl(hVolume, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);\r
+ Log("FSCTL_DISMOUNT_VOLUME bRet:%u code:%u", bRet, LASTERR);\r
+ }\r
}\r
else if (ERROR_NOT_FOUND == Status)\r
{\r
goto End;\r
}\r
\r
+ bRet = TryWritePart2(hDrive, StartSector);\r
+ if (FALSE == bRet && Esp2Basic)\r
+ {\r
+ Log("TryWritePart2 agagin ...");\r
+ Sleep(3000);\r
+ bRet = TryWritePart2(hDrive, StartSector);\r
+ }\r
\r
- if (!TryWritePart2(hDrive, StartSector))\r
+ if (!bRet)\r
{\r
if (pPhyDrive->PartStyle == 0)\r
{\r
- ForceMBR = TRUE;\r
- Log("Try write failed, now delete partition 2...");\r
+ if (DiskCheckWriteAccess(hDrive))\r
+ {\r
+ Log("MBR DiskCheckWriteAccess success");\r
\r
- CHECK_CLOSE_HANDLE(hDrive);\r
+ ForceMBR = TRUE;\r
\r
- Log("Now delete partition 2...");\r
- DeletePartitions(pPhyDrive->PhyDrive, TRUE);\r
+ Log("Try write failed, now delete partition 2 for MBR...");\r
+ CHECK_CLOSE_HANDLE(hDrive);\r
\r
- hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, TRUE, FALSE);\r
- if (hDrive == INVALID_HANDLE_VALUE)\r
+ Log("Now delete partition 2...");\r
+ DISK_DeleteVtoyEFIPartition(pPhyDrive->PhyDrive, StartSector * 512ULL);\r
+\r
+ hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, TRUE, FALSE);\r
+ if (hDrive == INVALID_HANDLE_VALUE)\r
+ {\r
+ Log("Failed to GetPhysicalHandle for write.");\r
+ rc = 1;\r
+ goto End;\r
+ }\r
+ }\r
+ else\r
{\r
- Log("Failed to GetPhysicalHandle for write.");\r
- rc = 1;\r
- goto End;\r
+ Log("MBR DiskCheckWriteAccess failed");\r
}\r
}\r
+ else\r
+ {\r
+ Log("TryWritePart2 failed ....");\r
+ rc = 1;\r
+ goto End;\r
+ }\r
}\r
\r
PROGRESS_BAR_SET_POS(PT_FORMAT_PART2);\r
}\r
}\r
\r
+ if (CleanDisk)\r
+ {\r
+ if (!WriteBackupDataToDisk(hDrive, 0, pBackup, 34 * 512))\r
+ {\r
+ bWriteBack = FALSE;\r
+ }\r
+\r
+ free(pBackup);\r
+\r
+ if (bWriteBack)\r
+ {\r
+ Log("Write backup data success, now delete %s", BackBinFile);\r
+ DeleteFileA(BackBinFile);\r
+ }\r
+ else\r
+ {\r
+ Log("Write backup data failed");\r
+ }\r
+\r
+ Sleep(1000);\r
+ }\r
+ else if (DelEFI)\r
+ {\r
+ VTOY_GPT_HDR BackupHdr;\r
+\r
+ VentoyFillBackupGptHead(pGptBkup, &BackupHdr);\r
+ if (!WriteBackupDataToDisk(hDrive, 512 * pGptBkup->Head.EfiBackupLBA, (BYTE*)(&BackupHdr), 512))\r
+ {\r
+ bWriteBack = FALSE;\r
+ }\r
+\r
+ if (!WriteBackupDataToDisk(hDrive, 512 * (pGptBkup->Head.EfiBackupLBA - 32), (BYTE*)(pGptBkup->PartTbl), 32 * 512))\r
+ {\r
+ bWriteBack = FALSE;\r
+ }\r
+\r
+ if (!WriteBackupDataToDisk(hDrive, 512, (BYTE*)pGptBkup + 512, 33 * 512))\r
+ {\r
+ bWriteBack = FALSE;\r
+ }\r
+\r
+ if (bWriteBack)\r
+ {\r
+ Log("Write backup partition table success");\r
+ }\r
+ else\r
+ {\r
+ Log("Write backup partition table failed");\r
+ }\r
+\r
+ Sleep(1000);\r
+ }\r
+\r
//Refresh Drive Layout\r
DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL);\r
\r
End:\r
\r
+ if (hVolume != INVALID_HANDLE_VALUE)\r
+ {\r
+ bRet = DeviceIoControl(hVolume, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);\r
+ Log("FSCTL_UNLOCK_VOLUME bRet:%u code:%u", bRet, LASTERR);\r
+ CHECK_CLOSE_HANDLE(hVolume);\r
+ }\r
+\r
if (rc == 0)\r
{\r
Log("OK");\r
}\r
else\r
{\r
+ PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN);\r
FindProcessOccupyDisk(hDrive, pPhyDrive);\r
}\r
\r
CHECK_CLOSE_HANDLE(hDrive);\r
\r
+ if (Esp2Basic)\r
+ {\r
+ Log("Recover GPT partition type to basic");\r
+ DISK_ChangeVtoyEFI2Basic(pPhyDrive->PhyDrive, StartSector * 512);\r
+ }\r
+\r
+ if (pPhyDrive->PartStyle == 1)\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 (DISK_ChangeVtoyEFIAttr(pPhyDrive->PhyDrive, StartSector * 512ULL, 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
+\r
if (pGptInfo)\r
{\r
free(pGptInfo);\r