NtResultTests.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. #include <wil/result.h>
  2. #include <wil/nt_result_macros.h>
  3. #include "common.h"
  4. #define STATUS_OBJECT_PATH_NOT_FOUND ((NTSTATUS)0xC000003AL)
  5. #define STATUS_INTERNAL_ERROR ((NTSTATUS)0xC00000E5L)
  6. #define STATUS_INVALID_CONNECTION ((NTSTATUS)0xC0000140L)
  7. #define E_LOAD_NAMESERVICE_FAILED ((HRESULT)0x80000140L)
  8. TEST_CASE("NtResultTests::NtReturn", "[result]")
  9. {
  10. auto status = []()
  11. {
  12. NT_RETURN_NTSTATUS(STATUS_INVALID_CONNECTION);
  13. }();
  14. REQUIRE(status == STATUS_INVALID_CONNECTION);
  15. status = []()
  16. {
  17. NT_RETURN_NTSTATUS_MSG(STATUS_INVALID_CONNECTION, "Test NT_RETURN_NTSTATUS_MSG");
  18. }();
  19. REQUIRE(status == STATUS_INVALID_CONNECTION);
  20. status = []()
  21. {
  22. NT_RETURN_NTSTATUS_MSG(STATUS_INVALID_CONNECTION, "Test NT_RETURN_NTSTATUS_MSG %s", L"with parameter");
  23. }();
  24. REQUIRE(status == STATUS_INVALID_CONNECTION);
  25. status = []()
  26. {
  27. NT_RETURN_IF_NTSTATUS_FAILED(STATUS_INVALID_CONNECTION);
  28. return STATUS_SUCCESS;
  29. }();
  30. REQUIRE(status == STATUS_INVALID_CONNECTION);
  31. status = []()
  32. {
  33. NT_RETURN_IF_NTSTATUS_FAILED_MSG(STATUS_INVALID_CONNECTION, "Test NT_RETURN_NTSTATUS_MSG %s", L"with parameter");
  34. return STATUS_SUCCESS;
  35. }();
  36. REQUIRE(status == STATUS_INVALID_CONNECTION);
  37. status = []()
  38. {
  39. NT_RETURN_IF_NTSTATUS_FAILED(STATUS_SUCCESS);
  40. return STATUS_INVALID_CONNECTION;
  41. }();
  42. REQUIRE(status == STATUS_INVALID_CONNECTION);
  43. }
  44. #ifdef WIL_ENABLE_EXCEPTIONS
  45. TEST_CASE("NtResultTests::NtThrowCatch", "[result]")
  46. {
  47. // Throw NTSTATUS with immediate conversion to HRESULT. HRESULT would appear in the logs.
  48. auto hr = []()
  49. {
  50. try
  51. {
  52. THROW_NTSTATUS(STATUS_INVALID_CONNECTION);
  53. }
  54. CATCH_RETURN();
  55. }();
  56. // THROW_NTSTATUS converts NTSTATUS to HRESULT through WIN32 error code.
  57. REQUIRE(hr == wil::details::NtStatusToHr(STATUS_INVALID_CONNECTION));
  58. // Verify that conversion NTSTATUS -> HRESULT -> NTSTATUS is not 1:1.
  59. auto status = []()
  60. {
  61. try
  62. {
  63. THROW_HR(wil::details::NtStatusToHr(STATUS_INVALID_CONNECTION));
  64. }
  65. NT_CATCH_RETURN();
  66. }();
  67. if (wil::details::g_pfnRtlNtStatusToDosErrorNoTeb)
  68. {
  69. REQUIRE(status != STATUS_INVALID_CONNECTION);
  70. }
  71. else
  72. {
  73. REQUIRE(status == STATUS_INVALID_CONNECTION);
  74. }
  75. // Throw HRESULT with conversion to NTSTATUS on a best effort. NTSTATUS would appear in the logs.
  76. status = []()
  77. {
  78. try
  79. {
  80. THROW_HR(__HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND));
  81. }
  82. NT_CATCH_RETURN();
  83. }();
  84. REQUIRE(status == STATUS_OBJECT_PATH_NOT_FOUND);
  85. // Throw HRESULT with conversion to NTSTATUS on a best effort that maps to generic error. NTSTATUS would appear in the logs.
  86. status = []()
  87. {
  88. try
  89. {
  90. THROW_HR(E_LOAD_NAMESERVICE_FAILED);
  91. }
  92. NT_CATCH_RETURN();
  93. }();
  94. REQUIRE(status == STATUS_INTERNAL_ERROR);
  95. // Throw NTSTATUS without conversion. NTSTATUS would appear in the logs.
  96. status = []()
  97. {
  98. try
  99. {
  100. THROW_NTSTATUS(STATUS_INVALID_CONNECTION);
  101. }
  102. NT_CATCH_RETURN();
  103. }();
  104. REQUIRE(status == STATUS_INVALID_CONNECTION);
  105. status = []()
  106. {
  107. try
  108. {
  109. THROW_NTSTATUS_MSG(STATUS_INVALID_CONNECTION, "Throw STATUS_INVALID_CONNECTION as NTSTATUS");
  110. }
  111. NT_CATCH_RETURN();
  112. }();
  113. REQUIRE(status == STATUS_INVALID_CONNECTION);
  114. status = []()
  115. {
  116. try
  117. {
  118. THROW_NTSTATUS_MSG(STATUS_INVALID_CONNECTION, "Throw STATUS_INVALID_CONNECTION as NTSTATUS with custom catch");
  119. }
  120. catch (...)
  121. {
  122. LOG_CAUGHT_EXCEPTION();
  123. return wil::StatusFromCaughtException();
  124. }
  125. }();
  126. REQUIRE(status == STATUS_INVALID_CONNECTION);
  127. hr = []()
  128. {
  129. try
  130. {
  131. THROW_NTSTATUS_MSG(STATUS_INVALID_CONNECTION, "Throw STATUS_INVALID_CONNECTION as NTSTATUS");
  132. }
  133. CATCH_RETURN();
  134. }();
  135. REQUIRE(hr == wil::details::NtStatusToHr(STATUS_INVALID_CONNECTION));
  136. status = []()
  137. {
  138. try
  139. {
  140. THROW_NTSTATUS_MSG(STATUS_INVALID_CONNECTION, "Throw STATUS_INVALID_CONNECTION as NTSTATUS");
  141. }
  142. NT_CATCH_RETURN_MSG("Catching STATUS_INVALID_CONNECTION thrown by NT_THROW_NTSTATUS_MSG");
  143. }();
  144. REQUIRE(status == STATUS_INVALID_CONNECTION);
  145. }
  146. #endif