Skip to content

Commit

Permalink
Add KfRaiseIrql and some Etw APIs (#73)
Browse files Browse the repository at this point in the history
* Clean up unused function
* Add KfRaiseIrql. The DDK just defines KeRaiseIrql as inline wrapper around KfRaiseIrql
so we need to expose KfRaiseIrql when linking.  Addresses part of #69.
* Add stubs for ETW apis. Addresses part of #70

Signed-off-by: Dave Thaler <[email protected]>
  • Loading branch information
dthaler authored Aug 2, 2023
1 parent 6ee22db commit 5a54517
Show file tree
Hide file tree
Showing 14 changed files with 180 additions and 11 deletions.
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

0 comments on commit 5a54517

Please sign in to comment.