[llvm] 925471e - [llvm][Support][Windows] Avoid crash calling remove_directories() (#118677)

via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 11 23:17:57 PST 2024


Author: Dmitry Vasilyev
Date: 2024-12-12T11:17:54+04:00
New Revision: 925471ed903dad871042d7ed0bab89ab6566a564

URL: https://github.com/llvm/llvm-project/commit/925471ed903dad871042d7ed0bab89ab6566a564
DIFF: https://github.com/llvm/llvm-project/commit/925471ed903dad871042d7ed0bab89ab6566a564.diff

LOG: [llvm][Support][Windows] Avoid crash calling remove_directories() (#118677)

We faced an unexpected crash in SHELL32_CallFileCopyHooks() on the buildbot 
[lldb-remote-linux-win](https://lab.llvm.org/staging/#/builders/197/builds/1066).
The host is Windows Server 2022 w/o any 3rd party shell extensions. See #118032 for more details.
Based on [this article](https://devblogs.microsoft.com/oldnewthing/20120330-00/?p=7963).

Added: 
    

Modified: 
    llvm/lib/Support/Windows/Path.inc

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc
index c4bd5e24723517..d4e8261ae4feba 100644
--- a/llvm/lib/Support/Windows/Path.inc
+++ b/llvm/lib/Support/Windows/Path.inc
@@ -25,6 +25,7 @@
 // These two headers must be included last, and make sure shlobj is required
 // after Windows.h to make sure it picks up our definition of _WIN32_WINNT
 #include "llvm/Support/Windows/WindowsSupport.h"
+#include <atlbase.h>
 #include <shellapi.h>
 #include <shlobj.h>
 
@@ -1387,14 +1388,33 @@ std::error_code remove_directories(const Twine &path, bool IgnoreErrors) {
   Path16.push_back(0);
   Path16.push_back(0);
 
-  SHFILEOPSTRUCTW shfos = {};
-  shfos.wFunc = FO_DELETE;
-  shfos.pFrom = Path16.data();
-  shfos.fFlags = FOF_NO_UI;
-
-  int result = ::SHFileOperationW(&shfos);
-  if (result != 0 && !IgnoreErrors)
-    return mapWindowsError(result);
+  HRESULT HR;
+  do {
+    HR =
+        CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
+    if (FAILED(HR))
+      break;
+    auto Uninitialize = make_scope_exit([] { CoUninitialize(); });
+    CComPtr<IFileOperation> FileOp;
+    HR = FileOp.CoCreateInstance(CLSID_FileOperation);
+    if (FAILED(HR))
+      break;
+    HR = FileOp->SetOperationFlags(FOF_NO_UI | FOFX_NOCOPYHOOKS);
+    if (FAILED(HR))
+      break;
+    PIDLIST_ABSOLUTE PIDL = ILCreateFromPathW(Path16.data());
+    auto FreePIDL = make_scope_exit([&PIDL] { ILFree(PIDL); });
+    CComPtr<IShellItem> ShItem;
+    HR = SHCreateItemFromIDList(PIDL, IID_PPV_ARGS(&ShItem));
+    if (FAILED(HR))
+      break;
+    HR = FileOp->DeleteItem(ShItem, NULL);
+    if (FAILED(HR))
+      break;
+    HR = FileOp->PerformOperations();
+  } while (false);
+  if (FAILED(HR) && !IgnoreErrors)
+    return mapWindowsError(HRESULT_CODE(HR));
   return std::error_code();
 }
 


        


More information about the llvm-commits mailing list