Skip to content

Commit 925471e

Browse files
authored
[llvm][Support][Windows] Avoid crash calling remove_directories() (llvm#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 llvm#118032 for more details. Based on [this article](https://devblogs.microsoft.com/oldnewthing/20120330-00/?p=7963).
1 parent 077cc3d commit 925471e

File tree

1 file changed

+28
-8
lines changed

1 file changed

+28
-8
lines changed

llvm/lib/Support/Windows/Path.inc

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
// These two headers must be included last, and make sure shlobj is required
2626
// after Windows.h to make sure it picks up our definition of _WIN32_WINNT
2727
#include "llvm/Support/Windows/WindowsSupport.h"
28+
#include <atlbase.h>
2829
#include <shellapi.h>
2930
#include <shlobj.h>
3031

@@ -1387,14 +1388,33 @@ std::error_code remove_directories(const Twine &path, bool IgnoreErrors) {
13871388
Path16.push_back(0);
13881389
Path16.push_back(0);
13891390

1390-
SHFILEOPSTRUCTW shfos = {};
1391-
shfos.wFunc = FO_DELETE;
1392-
shfos.pFrom = Path16.data();
1393-
shfos.fFlags = FOF_NO_UI;
1394-
1395-
int result = ::SHFileOperationW(&shfos);
1396-
if (result != 0 && !IgnoreErrors)
1397-
return mapWindowsError(result);
1391+
HRESULT HR;
1392+
do {
1393+
HR =
1394+
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
1395+
if (FAILED(HR))
1396+
break;
1397+
auto Uninitialize = make_scope_exit([] { CoUninitialize(); });
1398+
CComPtr<IFileOperation> FileOp;
1399+
HR = FileOp.CoCreateInstance(CLSID_FileOperation);
1400+
if (FAILED(HR))
1401+
break;
1402+
HR = FileOp->SetOperationFlags(FOF_NO_UI | FOFX_NOCOPYHOOKS);
1403+
if (FAILED(HR))
1404+
break;
1405+
PIDLIST_ABSOLUTE PIDL = ILCreateFromPathW(Path16.data());
1406+
auto FreePIDL = make_scope_exit([&PIDL] { ILFree(PIDL); });
1407+
CComPtr<IShellItem> ShItem;
1408+
HR = SHCreateItemFromIDList(PIDL, IID_PPV_ARGS(&ShItem));
1409+
if (FAILED(HR))
1410+
break;
1411+
HR = FileOp->DeleteItem(ShItem, NULL);
1412+
if (FAILED(HR))
1413+
break;
1414+
HR = FileOp->PerformOperations();
1415+
} while (false);
1416+
if (FAILED(HR) && !IgnoreErrors)
1417+
return mapWindowsError(HRESULT_CODE(HR));
13981418
return std::error_code();
13991419
}
14001420

0 commit comments

Comments
 (0)