diff --git a/src/drive.c b/src/drive.c index ceca853d..471f727f 100644 --- a/src/drive.c +++ b/src/drive.c @@ -1,7 +1,7 @@ /* * Rufus: The Reliable USB Formatting Utility * Drive access function calls - * Copyright © 2011-2020 Pete Batard + * Copyright © 2011-2021 Pete Batard * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -649,6 +649,7 @@ static BOOL GetVdsDiskInterface(DWORD DriveIndex, const IID* InterfaceIID, void* } // Check if we are on the target disk + // uprintf("GetVdsDiskInterface: Seeking %S found %S", wPhysicalName, prop.pwszName); hr = (HRESULT)_wcsicmp(wPhysicalName, prop.pwszName); CoTaskMemFree(prop.pwszName); if (hr != S_OK) { @@ -676,6 +677,71 @@ out: return (hr == S_OK); } +/* + * Invoke IVdsService::Refresh() and/or IVdsService::Reenumerate() to force a + * rescan of the VDS disks. This can become necessary after writing an image + * such as Ubuntu 20.10, as Windows may "lose" the active disk otherwise... + */ +BOOL VdsRescan(DWORD dwRescanType, DWORD dwSleepTime, BOOL bSilent) +{ + BOOL ret = TRUE; + HRESULT hr = S_FALSE; + IVdsServiceLoader* pLoader; + IVdsService* pService; + + IGNORE_RETVAL(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)); + IGNORE_RETVAL(CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, + RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL)); + + hr = CoCreateInstance(&CLSID_VdsLoader, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, + &IID_IVdsServiceLoader, (void**)&pLoader); + if (hr != S_OK) { + suprintf("Could not create VDS Loader Instance: %s", VdsErrorString(hr)); + return FALSE; + } + + hr = IVdsServiceLoader_LoadService(pLoader, L"", &pService); + IVdsServiceLoader_Release(pLoader); + if (hr != S_OK) { + suprintf("Could not load VDS Service: %s", VdsErrorString(hr)); + return FALSE; + } + + hr = IVdsService_WaitForServiceReady(pService); + if (hr != S_OK) { + suprintf("VDS Service is not ready: %s", VdsErrorString(hr)); + return FALSE; + } + + // https://docs.microsoft.com/en-us/windows/win32/api/vds/nf-vds-ivdsservice-refresh + // This method synchronizes the disk layout to the layout known to the disk driver. + // It does not force the driver to read the layout from the disk. + // Additionally, this method refreshes the view of all objects in the VDS cache. + if (dwRescanType & VDS_RESCAN_REFRESH) { + hr = IVdsService_Refresh(pService); + if (hr != S_OK) { + suprintf("VDS Refresh failed: %s", VdsErrorString(hr)); + ret = FALSE; + } + } + + // https://docs.microsoft.com/en-us/windows/win32/api/vds/nf-vds-ivdsservice-reenumerate + // This method returns immediately after a bus rescan request is issued. + // The operation might be incomplete when the method returns. + if (dwRescanType & VDS_RESCAN_REENUMERATE) { + hr = IVdsService_Reenumerate(pService); + if (hr != S_OK) { + suprintf("VDS Re-enumeration failed: %s", VdsErrorString(hr)); + ret = FALSE; + } + } + + if (dwSleepTime != 0) + Sleep(dwSleepTime); + + return ret; +} + /* * Delete one partition at offset PartitionOffset, or all partitions if the offset is 0. */ @@ -689,8 +755,13 @@ BOOL DeletePartition(DWORD DriveIndex, ULONGLONG PartitionOffset, BOOL bSilent) if (!GetVdsDiskInterface(DriveIndex, &IID_IVdsAdvancedDisk, (void**)&pAdvancedDisk, bSilent)) return FALSE; if (pAdvancedDisk == NULL) { - suprintf("No partition to delete on disk"); - return TRUE; + suprintf("Looks like Windows has \"lost\" our disk - Forcing a VDS rescan..."); + VdsRescan(VDS_RESCAN_REFRESH | VDS_RESCAN_REENUMERATE, 1000, bSilent); + if (!GetVdsDiskInterface(DriveIndex, &IID_IVdsAdvancedDisk, (void**)&pAdvancedDisk, bSilent) || + (pAdvancedDisk == NULL)) { + suprintf("Could not locate disk - Aborting."); + return FALSE; + } } // Query the partition data, so we can get the start offset, which we need for deletion diff --git a/src/drive.h b/src/drive.h index 44df0298..461fc097 100644 --- a/src/drive.h +++ b/src/drive.h @@ -1,7 +1,7 @@ /* * Rufus: The Reliable USB Formatting Utility * Drive access function calls - * Copyright © 2011-2020 Pete Batard + * Copyright © 2011-2021 Pete Batard * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -54,6 +54,9 @@ #define FILE_FLOPPY_DISKETTE 0x00000004 +#define VDS_RESCAN_REFRESH 0x00000001 +#define VDS_RESCAN_REENUMERATE 0x00000002 + #define VDS_SET_ERROR(hr) do { if (hr != S_OK) { SetLastError(hr); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_GEN_FAILURE; } } while(0) #if !defined(__MINGW32__) @@ -373,6 +376,7 @@ BOOL GetAutoMount(BOOL* enabled); char* GetPhysicalName(DWORD DriveIndex); BOOL DeletePartition(DWORD DriveIndex, ULONGLONG PartitionOffset, BOOL bSilent); BOOL ListVdsVolumes(BOOL bSilent); +BOOL VdsRescan(DWORD dwRescanType, DWORD dwSleepTime, BOOL bSilent); HANDLE GetPhysicalHandle(DWORD DriveIndex, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare); char* GetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent); char* AltGetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrailingBackslash, BOOL bSilent); diff --git a/src/ext2fs/symlink.c b/src/ext2fs/symlink.c index a66fb7ec..6b0a7397 100644 --- a/src/ext2fs/symlink.c +++ b/src/ext2fs/symlink.c @@ -104,7 +104,9 @@ errcode_t ext2fs_symlink(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t ino, inode.i_mode = LINUX_S_IFLNK | 0777; inode.i_uid = inode.i_gid = 0; inode.i_links_count = 1; - ext2fs_inode_size_set(fs, &inode, target_len); + retval = ext2fs_inode_size_set(fs, &inode, target_len); + if (retval) + goto cleanup; /* The time fields are set by ext2fs_write_new_inode() */ inlinelink = !fastlink && ext2fs_has_feature_inline_data(fs->super); diff --git a/src/format.c b/src/format.c index 27ded0d3..d9344957 100644 --- a/src/format.c +++ b/src/format.c @@ -1,7 +1,7 @@ /* * Rufus: The Reliable USB Formatting Utility * Formatting function calls - * Copyright © 2011-2020 Pete Batard + * Copyright © 2011-2021 Pete Batard * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -2181,6 +2181,7 @@ DWORD WINAPI FormatThread(void* param) } out: + VdsRescan(VDS_RESCAN_REFRESH, 0, TRUE); safe_free(volume_name); safe_free(buffer); safe_closehandle(hSourceImage); diff --git a/src/rufus.rc b/src/rufus.rc index 8aa67275..1a4dd45f 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -35,7 +35,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 232, 326 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 3.14.1733" +CAPTION "Rufus 3.14.1734" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -397,8 +397,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,14,1733,0 - PRODUCTVERSION 3,14,1733,0 + FILEVERSION 3,14,1734,0 + PRODUCTVERSION 3,14,1734,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -416,13 +416,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "3.14.1733" + VALUE "FileVersion", "3.14.1734" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2021 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "rufus-3.14.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "3.14.1733" + VALUE "ProductVersion", "3.14.1734" END END BLOCK "VarFileInfo"