Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions inc/usersim/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,26 @@
#else
#define USERSIM_API __declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C"
{
#endif

/**
* @brief Suspend fault injection within usersim.dll.
*
* Calls may be nested and must be balanced by calls to usersim_fault_injection_resume().
*/
USERSIM_API void
usersim_fault_injection_suspend();

/**
* @brief Resume fault injection within usersim.dll after a matching suspension.
*/
USERSIM_API void
usersim_fault_injection_resume();

#ifdef __cplusplus
}
#endif
3 changes: 3 additions & 0 deletions src/Source.def
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,6 @@ EXPORTS
NmrRegisterProvider
NmrWaitForClientDeregisterComplete
NmrWaitForProviderDeregisterComplete

usersim_fault_injection_resume
usersim_fault_injection_suspend
13 changes: 13 additions & 0 deletions src/platform_user.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "cxplat.h"
#include "cxplat_fault_injection.h"
#include "tracelog.h"
#include "usersim/common.h"
#include "usersim/ex.h"
#include "usersim/ke.h"
#include "usersim/mm.h"
Expand Down Expand Up @@ -45,6 +46,18 @@ static bool _cxplat_initialized = false;
// Used to compute the current CPU index.
static std::vector<uint32_t> _usersim_platform_group_to_index_map;

void
usersim_fault_injection_suspend()
{
cxplat_fault_injection_suspend();
}

void
usersim_fault_injection_resume()
{
cxplat_fault_injection_resume();
}

_Must_inspect_result_ usersim_result_t
usersim_platform_initiate()
{
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ FetchContent_MakeAvailable(Catch2)
add_executable(usersim_tests
etw_test.cpp
ex_test.cpp
fault_injection_test.cpp
ke_test.cpp
mm_test.cpp
nmr_test.cpp
Expand Down
44 changes: 44 additions & 0 deletions tests/fault_injection_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) Microsoft Corporation
// SPDX-License-Identifier: MIT

#if !defined(CMAKE_NUGET)
#include <catch2/catch_all.hpp>
#else
#include <catch2/catch.hpp>
#endif

#include "usersim/common.h"
#include "usersim/ex.h"

#include <cstdlib>

static bool
_is_fault_injection_enabled()
{
char value[32] = {};
size_t required_size = 0;
getenv_s(&required_size, value, sizeof(value), "CXPLAT_FAULT_INJECTION_SIMULATION");
return required_size > 0 && std::strtoull(value, nullptr, 10) > 0;
}

TEST_CASE("usersim fault injection suspension", "[fault_injection]")
{
auto call_fault_injected_usersim_api = []() {
UUID uuid = {};
return ExUuidCreate(&uuid);
};

usersim_fault_injection_suspend();
usersim_fault_injection_suspend();
NTSTATUS nested_suspension_status = call_fault_injected_usersim_api();

usersim_fault_injection_resume();
NTSTATUS single_suspension_status = call_fault_injected_usersim_api();

usersim_fault_injection_resume();
NTSTATUS resumed_status = call_fault_injected_usersim_api();

REQUIRE(nested_suspension_status == STATUS_SUCCESS);
REQUIRE(single_suspension_status == STATUS_SUCCESS);
REQUIRE(resumed_status == (_is_fault_injection_enabled() ? STATUS_NOT_SUPPORTED : STATUS_SUCCESS));
}
1 change: 1 addition & 0 deletions tests/tests.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
<ItemGroup>
<ClCompile Include="etw_test.cpp" />
<ClCompile Include="ex_test.cpp" />
<ClCompile Include="fault_injection_test.cpp" />
<ClCompile Include="io_test.cpp" />
<ClCompile Include="ke_test.cpp" />
<ClCompile Include="mm_test.cpp" />
Expand Down