Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add KfRaiseIrql and some Etw APIs #73

Merged
merged 4 commits into from
Aug 2, 2023
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
47 changes: 47 additions & 0 deletions inc/usersim/etw.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (c) Microsoft Corporation
// SPDX-License-Identifier: MIT
#pragma once
#include "usersim/ke.h"

#ifdef __cplusplus
extern "C"
{
#endif

typedef _IRQL_requires_max_(PASSIVE_LEVEL) _IRQL_requires_same_ VOID NTAPI ETWENABLECALLBACK(
_In_ LPCGUID SourceId,
_In_ ULONG ControlCode,
_In_ UCHAR Level,
_In_ ULONGLONG MatchAnyKeyword,
_In_ ULONGLONG MatchAllKeyword,
_In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData,
_Inout_opt_ PVOID CallbackContext);

typedef ETWENABLECALLBACK* PETWENABLECALLBACK;

_IRQL_requires_max_(PASSIVE_LEVEL) USERSIM_API NTSTATUS EtwRegister(
_In_ LPCGUID provider_id,
_In_opt_ PETWENABLECALLBACK enable_callback,
_In_opt_ PVOID callback_context,
_Out_ PREGHANDLE reg_handle);

_IRQL_requires_max_(PASSIVE_LEVEL) USERSIM_API NTSTATUS EtwUnregister(_In_ REGHANDLE reg_handle);

_IRQL_requires_max_(HIGH_LEVEL) USERSIM_API NTSTATUS EtwWriteTransfer(
REGHANDLE reg_handle,
_In_ EVENT_DESCRIPTOR const* descriptor,
_In_opt_ LPCGUID activity_id,
_In_opt_ LPCGUID related_activity_id,
_In_range_(2, 128) UINT32 data_size,
_Inout_cap_(cData) EVENT_DATA_DESCRIPTOR* data);

USERSIM_API NTSTATUS
EtwSetInformation(
REGHANDLE reg_handle,
EVENT_INFO_CLASS information_class,
_In_opt_ PVOID information,
UINT16 const information_size);

#ifdef __cplusplus
}
#endif
7 changes: 6 additions & 1 deletion inc/usersim/ke.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@

#pragma once
#include "..\src\platform.h"
#include <string>

#if defined(__cplusplus)
#include <string>

extern "C"
{
#endif
Expand Down Expand Up @@ -67,6 +68,10 @@ extern "C"
VOID
KeRaiseIrql(_In_ KIRQL new_irql, _Out_ PKIRQL old_irql);

USERSIM_API
_IRQL_requires_max_(HIGH_LEVEL) _IRQL_raises_(new_irql) _IRQL_saves_ KIRQL
KfRaiseIrql(_In_ KIRQL new_irql);

USERSIM_API
KIRQL
KeRaiseIrqlToDpcLevel();
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

add_library(usersim SHARED
dllmain.cpp
etw.cpp
ex.cpp
fault_injection.cpp
fault_injection.h
Expand Down
67 changes: 67 additions & 0 deletions src/etw.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright (c) Microsoft Corporation
// SPDX-License-Identifier: MIT

#include "platform.h"
#include "usersim/etw.h"

typedef struct
{
GUID provider_id;
PETWENABLECALLBACK enable_callback;
PVOID callback_context;
} usersim_etw_provider_t;

_IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS EtwRegister(
_In_ LPCGUID provider_id,
_In_opt_ PETWENABLECALLBACK enable_callback,
_In_opt_ PVOID callback_context,
_Out_ PREGHANDLE reg_handle)
{
usersim_etw_provider_t* provider = (usersim_etw_provider_t*)usersim_allocate(sizeof(*provider));
if (provider == nullptr) {
return STATUS_NO_MEMORY;
}
provider->provider_id = *provider_id;
provider->enable_callback = enable_callback;
provider->callback_context = callback_context;
*reg_handle = (uintptr_t)provider;
return STATUS_SUCCESS;
}

_IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS EtwUnregister(_In_ REGHANDLE reg_handle)
{
usersim_free((void*)(uintptr_t)reg_handle);
return STATUS_SUCCESS;
}

NTSTATUS
EtwWriteTransfer(
REGHANDLE reg_handle,
_In_ EVENT_DESCRIPTOR const* desc,
_In_opt_ LPCGUID activity_id,
_In_opt_ LPCGUID related_activity_id,
_In_range_(2, 128) UINT32 data_size,
_Inout_cap_(cData) EVENT_DATA_DESCRIPTOR* data)
{
usersim_etw_provider_t* provider = (usersim_etw_provider_t*)reg_handle;

// TODO(#70): implement similar to usersim_trace_logging_write().
UNREFERENCED_PARAMETER(provider);
UNREFERENCED_PARAMETER(desc);
UNREFERENCED_PARAMETER(activity_id);
UNREFERENCED_PARAMETER(related_activity_id);
UNREFERENCED_PARAMETER(data_size);
UNREFERENCED_PARAMETER(data);
return STATUS_SUCCESS;
}

NTSTATUS
EtwSetInformation(
REGHANDLE reg_handle, EVENT_INFO_CLASS information_class, _In_opt_ PVOID information, UINT16 const information_size)
{
UNREFERENCED_PARAMETER(reg_handle);
UNREFERENCED_PARAMETER(information_class);
UNREFERENCED_PARAMETER(information);
UNREFERENCED_PARAMETER(information_size);
return STATUS_SUCCESS;
}
12 changes: 10 additions & 2 deletions src/ke.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,18 @@ KeGetCurrentIrql() { return _usersim_current_irql; }
VOID
KeRaiseIrql(_In_ KIRQL new_irql, _Out_ PKIRQL old_irql)
{
*old_irql = KeGetCurrentIrql();
*old_irql = KfRaiseIrql(new_irql);
}

KIRQL
KfRaiseIrql(_In_ KIRQL new_irql)
{
KIRQL old_irql = KeGetCurrentIrql();
_usersim_current_irql = new_irql;
BOOL result = SetThreadPriority(GetCurrentThread(), new_irql);
ASSERT(result);

if (new_irql >= DISPATCH_LEVEL && *old_irql < DISPATCH_LEVEL) {
if (new_irql >= DISPATCH_LEVEL && old_irql < DISPATCH_LEVEL) {
PROCESSOR_NUMBER processor;
uint32_t processor_index = KeGetCurrentProcessorNumberEx(&processor);

Expand All @@ -85,6 +91,8 @@ KeRaiseIrql(_In_ KIRQL new_irql, _Out_ PKIRQL old_irql)

_usersim_dispatch_locks[processor_index].lock();
}

return old_irql;
}

KIRQL
Expand Down
2 changes: 1 addition & 1 deletion src/platform_user.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1156,4 +1156,4 @@ usersim_trace_logging_write(_In_ const TraceLoggingHProvider hProvider, _In_z_ c
va_end(valist);

printf("}\n");
}
}
2 changes: 2 additions & 0 deletions src/usersim.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="etw.cpp" />
<ClCompile Include="ex.cpp" />
<ClCompile Include="fault_injection.cpp" />
<ClCompile Include="fwp_um.cpp" />
Expand All @@ -214,6 +215,7 @@
<ItemGroup>
<ClInclude Include="..\inc\TraceLoggingProvider.h" />
<ClInclude Include="..\inc\usersim\common.h" />
<ClInclude Include="..\inc\usersim\etw.h" />
<ClInclude Include="..\inc\usersim\ex.h" />
<ClInclude Include="..\inc\usersim\fwp_test.h" />
<ClInclude Include="..\inc\usersim\wdf.h" />
Expand Down
6 changes: 6 additions & 0 deletions src/usersim.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="etw.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="fwp_um.h">
Expand Down Expand Up @@ -134,6 +137,9 @@
<ClInclude Include="..\inc\usersim\wdf.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\inc\usersim\etw.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="Source.def">
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ FetchContent_Declare(
FetchContent_MakeAvailable(Catch2)

add_executable(usersim_tests
etw_test.cpp
ex_test.cpp
ke_test.cpp
mm_test.cpp
Expand Down
17 changes: 17 additions & 0 deletions tests/etw_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// 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/etw.h"

TEST_CASE("EtwRegister", "[etw]")
{
GUID guid = {};
REGHANDLE reg_handle;
REQUIRE(EtwRegister(&guid, nullptr, nullptr, &reg_handle) == STATUS_SUCCESS);
REQUIRE(EtwUnregister(reg_handle) == STATUS_SUCCESS);
}
17 changes: 17 additions & 0 deletions tests/ke_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,23 @@ TEST_CASE("irql", "[ke]")
REQUIRE(KeGetCurrentIrql() == PASSIVE_LEVEL);
}

TEST_CASE("KfRaiseIrql", "[ke]")
{
REQUIRE(KeGetCurrentIrql() == PASSIVE_LEVEL);

KIRQL old_irql;
old_irql = KfRaiseIrql(DISPATCH_LEVEL);
REQUIRE(old_irql == PASSIVE_LEVEL);
REQUIRE(KeGetCurrentIrql() == DISPATCH_LEVEL);

old_irql = KfRaiseIrql(DISPATCH_LEVEL);
REQUIRE(old_irql == DISPATCH_LEVEL);
REQUIRE(KeGetCurrentIrql() == DISPATCH_LEVEL);

KeLowerIrql(PASSIVE_LEVEL);
REQUIRE(KeGetCurrentIrql() == PASSIVE_LEVEL);
}

TEST_CASE("spin lock", "[ke]")
{
KSPIN_LOCK lock;
Expand Down
8 changes: 1 addition & 7 deletions tests/mm_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,6 @@ TEST_CASE("IoAllocateMdl", "[mm]")
ExFreePoolWithTag(buffer, tag);
}

int
test_probe_for_read_exception_filter(ULONG code, _In_ struct _EXCEPTION_POINTERS *ep)
{
return EXCEPTION_EXECUTE_HANDLER;
}

ULONG
test_probe_for_read(_In_ const volatile void* address, SIZE_T length, ULONG alignment)
{
Expand Down Expand Up @@ -116,4 +110,4 @@ TEST_CASE("ProbeForWrite", "[mm]")

// Verify a write past end of memory results in STATUS_ACCESS_VIOLATION.
REQUIRE(test_probe_for_write(&x, 65536, 8) == STATUS_ACCESS_VIOLATION);
}
}
1 change: 1 addition & 0 deletions tests/tests.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="etw_test.cpp" />
<ClCompile Include="ex_test.cpp" />
<ClCompile Include="ke_test.cpp" />
<ClCompile Include="mm_test.cpp" />
Expand Down
3 changes: 3 additions & 0 deletions tests/tests.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
<ClCompile Include="se_test.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="etw_test.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
Expand Down