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

Pavel Labath via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 6 00:23:01 PST 2024


================
@@ -1387,12 +1387,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;
+  HRESULT HR =
+      CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
+  if (SUCCEEDED(HR)) {
+    IFileOperation *FileOp = NULL;
+    HR = CoCreateInstance(CLSID_FileOperation, NULL, CLSCTX_ALL,
+                          IID_PPV_ARGS(&FileOp));
+    if (SUCCEEDED(HR)) {
+      HR = FileOp->SetOperationFlags(FOF_NO_UI | FOFX_NOCOPYHOOKS);
+      if (SUCCEEDED(HR)) {
+        PIDLIST_ABSOLUTE PIDL = ILCreateFromPathW(Path16.data());
+        IShellItem *ShItem = NULL;
+        HR = SHCreateItemFromIDList(PIDL, IID_PPV_ARGS(&ShItem));
+        if (SUCCEEDED(HR)) {
+          HR = FileOp->DeleteItem(ShItem, NULL);
+          if (SUCCEEDED(HR)) {
+            HR = FileOp->PerformOperations();
----------------
labath wrote:

It may be compact but it goes directly against the coding standards. And you don't need to add releases before every early returns -- that's what make_scope_exit is for. I don't know if it's possible to use some COM apis for that or not, but something like this should be equivalent to your code, but have a nesting level of one.

```
HRESULT deleteDirectoriesImpl(...) {
  if (HRESULT HR =
      CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); !SUCCEEDED(HR))
    return HR;
  auto Uninitialize = make_scope_exit([]{CoUninitialize();});
  IFileOperation *FileOp = NULL;
  if (HRESULT HR = CoCreateInstance(CLSID_FileOperation, NULL, CLSCTX_ALL,
                          IID_PPV_ARGS(&FileOp)); !SUCCEEDED(HR))
    return HR;
  auto ReleaseFile = make_scope_exit([]{FileOp->Release();});
  ...
```

https://github.com/llvm/llvm-project/pull/118677


More information about the llvm-commits mailing list