Win32/File.cpp: Fix fs::file constraints to avoid crashes
This commit is contained in:
+34
-4
@@ -117,6 +117,7 @@ static fs::error to_error(DWORD e)
|
|||||||
case ERROR_NEGATIVE_SEEK: return fs::error::inval;
|
case ERROR_NEGATIVE_SEEK: return fs::error::inval;
|
||||||
case ERROR_DIRECTORY: return fs::error::inval;
|
case ERROR_DIRECTORY: return fs::error::inval;
|
||||||
case ERROR_INVALID_NAME: return fs::error::inval;
|
case ERROR_INVALID_NAME: return fs::error::inval;
|
||||||
|
case ERROR_INVALID_FUNCTION: return fs::error::inval;
|
||||||
case ERROR_SHARING_VIOLATION: return fs::error::acces;
|
case ERROR_SHARING_VIOLATION: return fs::error::acces;
|
||||||
case ERROR_DIR_NOT_EMPTY: return fs::error::notempty;
|
case ERROR_DIR_NOT_EMPTY: return fs::error::notempty;
|
||||||
case ERROR_NOT_READY: return fs::error::noent;
|
case ERROR_NOT_READY: return fs::error::noent;
|
||||||
@@ -584,7 +585,7 @@ namespace fs
|
|||||||
if (!GetFileInformationByHandleEx(m_handle, FileIdInfo, &info, sizeof(info)))
|
if (!GetFileInformationByHandleEx(m_handle, FileIdInfo, &info, sizeof(info)))
|
||||||
{
|
{
|
||||||
// Try GetFileInformationByHandle as a fallback
|
// Try GetFileInformationByHandle as a fallback
|
||||||
BY_HANDLE_FILE_INFORMATION info2;
|
BY_HANDLE_FILE_INFORMATION info2{};
|
||||||
ensure(GetFileInformationByHandle(m_handle, &info2));
|
ensure(GetFileInformationByHandle(m_handle, &info2));
|
||||||
|
|
||||||
info = {};
|
info = {};
|
||||||
@@ -1658,11 +1659,40 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
|||||||
|
|
||||||
// Check if the handle is actually valid.
|
// Check if the handle is actually valid.
|
||||||
// This can fail on empty mounted drives (e.g. with ERROR_NOT_READY or ERROR_INVALID_FUNCTION).
|
// This can fail on empty mounted drives (e.g. with ERROR_NOT_READY or ERROR_INVALID_FUNCTION).
|
||||||
BY_HANDLE_FILE_INFORMATION info;
|
BY_HANDLE_FILE_INFORMATION info{};
|
||||||
if (!GetFileInformationByHandle(handle, &info))
|
if (!GetFileInformationByHandle(handle, &info))
|
||||||
{
|
{
|
||||||
|
const DWORD last_error = GetLastError();
|
||||||
CloseHandle(handle);
|
CloseHandle(handle);
|
||||||
g_tls_error = to_error(GetLastError());
|
|
||||||
|
if (last_error == ERROR_INVALID_FUNCTION)
|
||||||
|
{
|
||||||
|
g_tls_error = fs::error::isdir;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_tls_error = to_error(last_error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
|
{
|
||||||
|
CloseHandle(handle);
|
||||||
|
g_tls_error = fs::error::isdir;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)
|
||||||
|
{
|
||||||
|
CloseHandle(handle);
|
||||||
|
g_tls_error = fs::error::acces;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mode & fs::write) && (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
|
||||||
|
{
|
||||||
|
CloseHandle(handle);
|
||||||
|
g_tls_error = fs::error::readonly;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2605,7 +2635,7 @@ bool fs::pending_file::commit(bool overwrite)
|
|||||||
while (file_handle != INVALID_HANDLE_VALUE)
|
while (file_handle != INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
// Get file ID (used to check for hardlinks)
|
// Get file ID (used to check for hardlinks)
|
||||||
BY_HANDLE_FILE_INFORMATION file_info;
|
BY_HANDLE_FILE_INFORMATION file_info{};
|
||||||
|
|
||||||
if (!GetFileInformationByHandle(file_handle, &file_info) || file_info.nNumberOfLinks == 1)
|
if (!GetFileInformationByHandle(file_handle, &file_info) || file_info.nNumberOfLinks == 1)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user