Skip to content

Commit

Permalink
Sync with the OS & fix some issues (#258)
Browse files Browse the repository at this point in the history
* Sync with OS commit 7304518c5f69f8c5d9d05ed36cc79c7cb0396b5e

* Build fixes

* Unreachable code warnings

* Fixes to get kernel code building again

* Revert "Revert result macros to be noexcept again (#246)"

This reverts commit d84d4e6.
  • Loading branch information
dunhor authored Sep 14, 2022
1 parent 856f0a2 commit 5f4caba
Show file tree
Hide file tree
Showing 5 changed files with 295 additions and 116 deletions.
10 changes: 5 additions & 5 deletions include/wil/com.h
Original file line number Diff line number Diff line change
Expand Up @@ -1294,7 +1294,7 @@ namespace wil
auto raw = com_raw_ptr(wistd::forward<T>(ptrSource));
auto hr = details::query_policy_t<decltype(raw)>::query(raw, ptrResult);
__analysis_assume(SUCCEEDED(hr) || (*ptrResult == nullptr));
RETURN_HR(hr);
return hr;
}

#ifdef WIL_ENABLE_EXCEPTIONS
Expand Down Expand Up @@ -1336,7 +1336,7 @@ namespace wil
auto raw = com_raw_ptr(wistd::forward<T>(ptrSource));
auto hr = details::query_policy_t<decltype(raw)>::query(raw, riid, ptrResult);
__analysis_assume(SUCCEEDED(hr) || (*ptrResult == nullptr));
RETURN_HR(hr);
return hr;
}
//! @}

Expand Down Expand Up @@ -1726,7 +1726,7 @@ namespace wil
auto raw = com_raw_ptr(wistd::forward<T>(ptrSource));
auto hr = ::RoGetAgileReference(options, __uuidof(raw), raw, ptrResult);
__analysis_assume(SUCCEEDED(hr) || (*ptrResult == nullptr));
RETURN_HR(hr);
return hr;
}

#ifdef WIL_ENABLE_EXCEPTIONS
Expand Down Expand Up @@ -1841,7 +1841,7 @@ namespace wil
auto raw = com_raw_ptr(wistd::forward<T>(ptrSource));
auto hr = details::GetWeakReference(raw, ptrResult);
__analysis_assume(SUCCEEDED(hr) || (*ptrResult == nullptr));
RETURN_HR(hr);
return hr;
}

#ifdef WIL_ENABLE_EXCEPTIONS
Expand Down Expand Up @@ -2076,7 +2076,7 @@ namespace wil
{
return std::tuple<HRESULT, decltype(result)>{E_NOINTERFACE, {}};
}
return std::tuple<HRESULT, decltype(result)>{S_OK, result};
return std::tuple<HRESULT, decltype(result)>{error, result};
}

template <typename... Results>
Expand Down
25 changes: 22 additions & 3 deletions include/wil/filesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,9 +339,28 @@ namespace wil
{
if (deleteHandle != INVALID_HANDLE_VALUE)
{
FILE_DISPOSITION_INFO fileInfo{};
fileInfo.DeleteFile = TRUE;
RETURN_IF_WIN32_BOOL_FALSE(SetFileInformationByHandle(deleteHandle, FileDispositionInfo, &fileInfo, sizeof(fileInfo)));
#if (NTDDI_VERSION >= NTDDI_WIN10_RS1)
// DeleteFile and RemoveDirectory use POSIX delete, falling back to non-POSIX on most errors. Do the same here.
FILE_DISPOSITION_INFO_EX fileInfoEx{};
fileInfoEx.Flags = FILE_DISPOSITION_FLAG_DELETE | FILE_DISPOSITION_FLAG_POSIX_SEMANTICS;
if (!SetFileInformationByHandle(deleteHandle, FileDispositionInfoEx, &fileInfoEx, sizeof(fileInfoEx)))
{
auto const err = ::GetLastError();
// The real error we're looking for is STATUS_CANNOT_DELETE, but that's mapped to ERROR_ACCESS_DENIED.
if (err != ERROR_ACCESS_DENIED)
{
#endif
FILE_DISPOSITION_INFO fileInfo{};
fileInfo.DeleteFile = TRUE;
RETURN_IF_WIN32_BOOL_FALSE(SetFileInformationByHandle(deleteHandle, FileDispositionInfo, &fileInfo, sizeof(fileInfo)));
#if (NTDDI_VERSION >= NTDDI_WIN10_RS1)
}
else
{
RETURN_WIN32(err);
}
}
#endif
}
else
{
Expand Down
72 changes: 72 additions & 0 deletions include/wil/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,78 @@ namespace Microsoft

namespace wil
{
//! This type copies the current value of GetLastError at construction and resets the last error
//! to that value when it is destroyed.
//!
//! This is useful in library code that runs during a value's destructor. If the library code could
//! inadvertantly change the value of GetLastError (by calling a Win32 API or similar), it should
//! instantiate a value of this type before calling the library function in order to preserve the
//! GetLastError value the user would expect.
//!
//! This construct exists to hide kernel mode/user mode differences in wil library code.
//!
//! Example usage:
//!
//! if (!CreateFile(...))
//! {
//! auto lastError = wil::last_error_context();
//! WriteFile(g_hlog, logdata);
//! }
//!
class last_error_context
{
#ifndef WIL_KERNEL_MODE
bool m_dismissed = false;
DWORD m_error = 0;
public:
last_error_context() WI_NOEXCEPT : last_error_context(::GetLastError())
{
}

explicit last_error_context(DWORD error) WI_NOEXCEPT :
m_error(error)
{
}

last_error_context(last_error_context&& other) WI_NOEXCEPT
{
operator=(wistd::move(other));
}

last_error_context& operator=(last_error_context&& other) WI_NOEXCEPT
{
m_dismissed = wistd::exchange(other.m_dismissed, true);
m_error = other.m_error;

return *this;
}

~last_error_context() WI_NOEXCEPT
{
if (!m_dismissed)
{
::SetLastError(m_error);
}
}

//! last_error_context doesn't own a concrete resource, so therefore
//! it just disarms its destructor and returns void.
void release() WI_NOEXCEPT
{
WI_ASSERT(!m_dismissed);
m_dismissed = true;
}

auto value() const WI_NOEXCEPT
{
return m_error;
}
#else
public:
void release() WI_NOEXCEPT { }
#endif // WIL_KERNEL_MODE
};

/// @cond
namespace details
{
Expand Down
Loading

0 comments on commit 5f4caba

Please sign in to comment.