Avoid rare deadlock inside SHCreateDirectoyExW.

Replace call to SHCreateDirectoyExW on the win32 platform with multiple
calls to CreateDirectoryW to avoid deadlock within CoUninitialize which
is called from SHCreateDirectoyExW. MSDN states that calling
CoInitialize during DllMain is prohibited. SHCreateDirectoyExW
internally calls CoInitialize, thus calling SHCreateDirectoyExW inside
the DllMain is prohibited as well.
This commit is contained in:
Benjamin Thaut authored and Baldur Karlsson committed 2018-08-27 16:53:54 +02:00
1 parent adb3bb8cc6
commit ccdd7acd0b
1 file changed
+30 -1
+30 -1
View File
@@ -240,7 +240,36 @@ void CreateParentDirectory(const string &filename)
if(wfn[i] == L'/')
wfn[i] = L'\\';
SHCreateDirectoryExW(NULL, wfn.c_str(), NULL);
// Remove trailing \\s
size_t trailingSeperatorPos = wfn.find_last_of(L'\\');
while(trailingSeperatorPos == wfn.length() - 1)
{
wfn.erase(trailingSeperatorPos);
trailingSeperatorPos = wfn.find_last_of(L'\\');
}
// Find all directories we need to create
std::vector<wstring> directoriesToCreate;
while(!wfn.empty())
{
DWORD fileAttributes = GetFileAttributesW(wfn.c_str());
if(fileAttributes != INVALID_FILE_ATTRIBUTES)
break;
directoriesToCreate.push_back(wfn);
size_t seperatorPos = wfn.find_last_of(L'\\');
if(seperatorPos == string::npos)
break;
else
wfn = wfn.substr(0, seperatorPos);
}
// Create the directories in reverse order
for(ptrdiff_t i = directoriesToCreate.size() - 1; i >= 0; i--)
{
CreateDirectoryW(directoriesToCreate[i].c_str(), NULL);
}
}
string GetReplayAppFilename()