166 lines
4.6 KiB
C++
166 lines
4.6 KiB
C++
|
|
||
|
#include <wil/result.h>
|
||
|
#include <wil/nt_result_macros.h>
|
||
|
|
||
|
#include "common.h"
|
||
|
|
||
|
#define STATUS_OBJECT_PATH_NOT_FOUND ((NTSTATUS)0xC000003AL)
|
||
|
#define STATUS_INTERNAL_ERROR ((NTSTATUS)0xC00000E5L)
|
||
|
#define STATUS_INVALID_CONNECTION ((NTSTATUS)0xC0000140L)
|
||
|
#define E_LOAD_NAMESERVICE_FAILED ((HRESULT)0x80000140L)
|
||
|
|
||
|
TEST_CASE("NtResultTests::NtReturn", "[result]")
|
||
|
{
|
||
|
auto status = []()
|
||
|
{
|
||
|
NT_RETURN_NTSTATUS(STATUS_INVALID_CONNECTION);
|
||
|
}();
|
||
|
REQUIRE(status == STATUS_INVALID_CONNECTION);
|
||
|
|
||
|
status = []()
|
||
|
{
|
||
|
NT_RETURN_NTSTATUS_MSG(STATUS_INVALID_CONNECTION, "Test NT_RETURN_NTSTATUS_MSG");
|
||
|
}();
|
||
|
REQUIRE(status == STATUS_INVALID_CONNECTION);
|
||
|
|
||
|
status = []()
|
||
|
{
|
||
|
NT_RETURN_NTSTATUS_MSG(STATUS_INVALID_CONNECTION, "Test NT_RETURN_NTSTATUS_MSG %s", L"with parameter");
|
||
|
}();
|
||
|
REQUIRE(status == STATUS_INVALID_CONNECTION);
|
||
|
|
||
|
status = []()
|
||
|
{
|
||
|
NT_RETURN_IF_NTSTATUS_FAILED(STATUS_INVALID_CONNECTION);
|
||
|
return STATUS_SUCCESS;
|
||
|
}();
|
||
|
REQUIRE(status == STATUS_INVALID_CONNECTION);
|
||
|
|
||
|
status = []()
|
||
|
{
|
||
|
NT_RETURN_IF_NTSTATUS_FAILED_MSG(STATUS_INVALID_CONNECTION, "Test NT_RETURN_NTSTATUS_MSG %s", L"with parameter");
|
||
|
return STATUS_SUCCESS;
|
||
|
}();
|
||
|
REQUIRE(status == STATUS_INVALID_CONNECTION);
|
||
|
|
||
|
status = []()
|
||
|
{
|
||
|
NT_RETURN_IF_NTSTATUS_FAILED(STATUS_SUCCESS);
|
||
|
return STATUS_INVALID_CONNECTION;
|
||
|
}();
|
||
|
REQUIRE(status == STATUS_INVALID_CONNECTION);
|
||
|
}
|
||
|
|
||
|
#ifdef WIL_ENABLE_EXCEPTIONS
|
||
|
TEST_CASE("NtResultTests::NtThrowCatch", "[result]")
|
||
|
{
|
||
|
// Throw NTSTATUS with immediate conversion to HRESULT. HRESULT would appear in the logs.
|
||
|
auto hr = []()
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
THROW_NTSTATUS(STATUS_INVALID_CONNECTION);
|
||
|
}
|
||
|
CATCH_RETURN();
|
||
|
}();
|
||
|
// THROW_NTSTATUS converts NTSTATUS to HRESULT through WIN32 error code.
|
||
|
REQUIRE(hr == wil::details::NtStatusToHr(STATUS_INVALID_CONNECTION));
|
||
|
|
||
|
// Verify that conversion NTSTATUS -> HRESULT -> NTSTATUS is not 1:1.
|
||
|
auto status = []()
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
THROW_HR(wil::details::NtStatusToHr(STATUS_INVALID_CONNECTION));
|
||
|
}
|
||
|
NT_CATCH_RETURN();
|
||
|
}();
|
||
|
if (wil::details::g_pfnRtlNtStatusToDosErrorNoTeb)
|
||
|
{
|
||
|
REQUIRE(status != STATUS_INVALID_CONNECTION);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
REQUIRE(status == STATUS_INVALID_CONNECTION);
|
||
|
}
|
||
|
|
||
|
// Throw HRESULT with conversion to NTSTATUS on a best effort. NTSTATUS would appear in the logs.
|
||
|
status = []()
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
THROW_HR(__HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND));
|
||
|
}
|
||
|
NT_CATCH_RETURN();
|
||
|
}();
|
||
|
REQUIRE(status == STATUS_OBJECT_PATH_NOT_FOUND);
|
||
|
|
||
|
// Throw HRESULT with conversion to NTSTATUS on a best effort that maps to generic error. NTSTATUS would appear in the logs.
|
||
|
status = []()
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
THROW_HR(E_LOAD_NAMESERVICE_FAILED);
|
||
|
}
|
||
|
NT_CATCH_RETURN();
|
||
|
}();
|
||
|
REQUIRE(status == STATUS_INTERNAL_ERROR);
|
||
|
|
||
|
// Throw NTSTATUS without conversion. NTSTATUS would appear in the logs.
|
||
|
status = []()
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
THROW_NTSTATUS(STATUS_INVALID_CONNECTION);
|
||
|
}
|
||
|
NT_CATCH_RETURN();
|
||
|
}();
|
||
|
REQUIRE(status == STATUS_INVALID_CONNECTION);
|
||
|
|
||
|
status = []()
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
THROW_NTSTATUS_MSG(STATUS_INVALID_CONNECTION, "Throw STATUS_INVALID_CONNECTION as NTSTATUS");
|
||
|
}
|
||
|
NT_CATCH_RETURN();
|
||
|
}();
|
||
|
REQUIRE(status == STATUS_INVALID_CONNECTION);
|
||
|
|
||
|
status = []()
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
THROW_NTSTATUS_MSG(STATUS_INVALID_CONNECTION, "Throw STATUS_INVALID_CONNECTION as NTSTATUS with custom catch");
|
||
|
}
|
||
|
catch (...)
|
||
|
{
|
||
|
LOG_CAUGHT_EXCEPTION();
|
||
|
|
||
|
return wil::StatusFromCaughtException();
|
||
|
}
|
||
|
}();
|
||
|
REQUIRE(status == STATUS_INVALID_CONNECTION);
|
||
|
|
||
|
hr = []()
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
THROW_NTSTATUS_MSG(STATUS_INVALID_CONNECTION, "Throw STATUS_INVALID_CONNECTION as NTSTATUS");
|
||
|
}
|
||
|
CATCH_RETURN();
|
||
|
}();
|
||
|
REQUIRE(hr == wil::details::NtStatusToHr(STATUS_INVALID_CONNECTION));
|
||
|
|
||
|
status = []()
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
THROW_NTSTATUS_MSG(STATUS_INVALID_CONNECTION, "Throw STATUS_INVALID_CONNECTION as NTSTATUS");
|
||
|
}
|
||
|
NT_CATCH_RETURN_MSG("Catching STATUS_INVALID_CONNECTION thrown by NT_THROW_NTSTATUS_MSG");
|
||
|
}();
|
||
|
REQUIRE(status == STATUS_INVALID_CONNECTION);
|
||
|
}
|
||
|
#endif
|