Skip to content

Commit

Permalink
Add Wdf* APIs required by ebpf-for-windows (#76)
Browse files Browse the repository at this point in the history
* Add Wdf* APIs required by ebpf-for-windows
* Add cache-aligned allocations (fixes #31)
* Add some WDF tests
* Also make more kernel functions callable from C code

Signed-off-by: Dave Thaler <[email protected]>
  • Loading branch information
dthaler authored Aug 7, 2023
1 parent 7ce8f1a commit 8e6fdef
Show file tree
Hide file tree
Showing 19 changed files with 825 additions and 270 deletions.
93 changes: 93 additions & 0 deletions inc/usersim/ex.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,77 @@ extern "C"
USERSIM_API void
ExRaiseDatatypeMisalignment();

/**
* @brief Allocate memory.
* @param[in] pool_type Pool type to use.
* @param[in] size Size of memory to allocate.
* @param[in] tag Pool tag to use.
* @param[in] initialize False to return "uninitialized" memory.
* @returns Pointer to memory block allocated, or null on failure.
*/
__drv_allocatesMem(Mem) _Must_inspect_result_ _Ret_writes_maybenull_(size) void* usersim_allocate_with_tag(
_In_ __drv_strictTypeMatch(__drv_typeExpr) POOL_TYPE pool_type, size_t size, uint32_t tag, bool initialize);

/**
* @brief Allocate memory.
* @param[in] size Size of memory to allocate.
* @returns Pointer to memory block allocated, or null on failure.
*/
__drv_allocatesMem(Mem) _Must_inspect_result_ _Ret_writes_maybenull_(size) void* usersim_allocate(size_t size);

/**
* @brief Reallocate memory.
* @param[in] memory Allocation to be reallocated.
* @param[in] old_size Old size of memory to reallocate.
* @param[in] new_size New size of memory to reallocate.
* @returns Pointer to memory block allocated, or null on failure.
*/
__drv_allocatesMem(Mem) _Must_inspect_result_ _Ret_writes_maybenull_(new_size) void* usersim_reallocate(
_In_ _Post_invalid_ void* memory, size_t old_size, size_t new_size);

/**
* @brief Reallocate memory with tag.
* @param[in] memory Allocation to be reallocated.
* @param[in] old_size Old size of memory to reallocate.
* @param[in] new_size New size of memory to reallocate.
* @param[in] tag Pool tag to use.
* @returns Pointer to memory block allocated, or null on failure.
*/
__drv_allocatesMem(Mem) _Must_inspect_result_ _Ret_writes_maybenull_(new_size) void* usersim_reallocate_with_tag(
_In_ _Post_invalid_ void* memory, size_t old_size, size_t new_size, uint32_t tag);

/**
* @brief Free memory.
* @param[in] memory Allocation to be freed.
*/
void
usersim_free(_Frees_ptr_opt_ void* memory);

/**
* @brief Allocate memory that has a starting address that is cache aligned.
* @param[in] size Size of memory to allocate
* @returns Pointer to memory block allocated, or null on failure.
*/
USERSIM_API
__drv_allocatesMem(Mem) _Must_inspect_result_
_Ret_writes_maybenull_(size) void* usersim_allocate_cache_aligned(size_t size);

/**
* @brief Allocate memory that has a starting address that is cache aligned with tag.
* @param[in] size Size of memory to allocate
* @param[in] tag Pool tag to use.
* @returns Pointer to memory block allocated, or null on failure.
*/
__drv_allocatesMem(Mem) _Must_inspect_result_
_Ret_writes_maybenull_(size) void* usersim_allocate_cache_aligned_with_tag(size_t size, uint32_t tag);

/**
* @brief Free memory that has a starting address that is cache aligned.
* @param[in] memory Allocation to be freed.
*/
void
usersim_free_cache_aligned(_Frees_ptr_opt_ void* memory);

#if defined(__cplusplus)
}

Expand All @@ -207,4 +278,26 @@ ExRaiseAccessViolationCPP();
USERSIM_API void
ExRaiseDatatypeMisalignmentCPP();

void usersim_initialize_ex(bool leak_detector);
void usersim_clean_up_ex();

#ifdef __cplusplus
#include <memory>
namespace usersim_helper {

struct _usersim_free_functor
{
void
operator()(void* memory)
{
usersim_free(memory);
}
};

typedef std::unique_ptr<void, _usersim_free_functor> usersim_memory_ptr;

} // namespace usersim_helper

#endif

#endif
11 changes: 10 additions & 1 deletion inc/usersim/fwp_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
#include <stdint.h>
#include <ws2def.h>

#if defined(__cplusplus)
extern "C"
{
#endif

typedef struct _fwp_classify_parameters
{
ADDRESS_FAMILY family;
Expand Down Expand Up @@ -51,4 +56,8 @@ usersim_fwp_sock_ops_v6(_In_ fwp_classify_parameters_t* parameters);

USERSIM_API void
usersim_fwp_set_sublayer_guids(
_In_ const GUID& default_sublayer, _In_ const GUID& connect_v4_sublayer, _In_ const GUID& connect_v6_sublayer);
_In_ const GUID& default_sublayer, _In_ const GUID& connect_v4_sublayer, _In_ const GUID& connect_v6_sublayer);

#if defined(__cplusplus)
}
#endif
10 changes: 8 additions & 2 deletions inc/usersim/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ extern "C"

typedef struct _DEVICE_OBJECT DEVICE_OBJECT;

typedef struct _DRIVER_OBJECT DRIVER_OBJECT;
typedef struct _DRIVER_OBJECT DRIVER_OBJECT, *PDRIVER_OBJECT;

typedef struct _IO_WORKITEM IO_WORKITEM, *PIO_WORKITEM;

Expand Down Expand Up @@ -68,7 +68,13 @@ extern "C"
IoGetFileObjectGenericMapping();

USERSIM_API
_IRQL_requires_max_(DISPATCH_LEVEL) NTKERNELAPI PEPROCESS IoGetCurrentProcess(VOID);
_IRQL_requires_max_(DISPATCH_LEVEL) PEPROCESS IoGetCurrentProcess(VOID);

typedef struct _IRP* PIRP;

USERSIM_API
_IRQL_requires_max_(DISPATCH_LEVEL) VOID
IofCompleteRequest(_In_ PIRP irp, _In_ CCHAR priority_boost);

#if defined(__cplusplus)
}
Expand Down
10 changes: 6 additions & 4 deletions inc/usersim/rtl.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,16 @@ extern "C"
_Out_ PSTRING destination_string,
_In_opt_ __drv_aliasesMem PCSTR source_string);

_IRQL_requires_max_(DISPATCH_LEVEL) _At_(DestinationString->Buffer, _Post_equal_to_(SourceString))
_At_(DestinationString->Length, _Post_equal_to_(_String_length_(SourceString) * sizeof(WCHAR)))
_At_(DestinationString->MaximumLength, _Post_equal_to_((_String_length_(SourceString) + 1) * sizeof(WCHAR)))
_IRQL_requires_max_(DISPATCH_LEVEL) _At_(destination_string->Buffer, _Post_equal_to_(source_string))
_At_(destination_string->Length, _Post_equal_to_(_String_length_(source_string) * sizeof(WCHAR)))
_At_(destination_string->MaximumLength, _Post_equal_to_((_String_length_(source_string) + 1) * sizeof(WCHAR)))
USERSIM_API VOID NTAPI
RtlInitUnicodeString(
_Out_ PCUNICODE_STRING destination_string,
_Out_ PUNICODE_STRING destination_string,
_In_opt_z_ __drv_aliasesMem PCWSTR source_string);

typedef struct _object_attributes OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;

// Include Rtl* implementations from ntdll.lib.
#pragma comment(lib, "ntdll.lib")

Expand Down
123 changes: 115 additions & 8 deletions inc/usersim/wdf.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// implemented in usersim.dll, and can be used by unit tests.
#pragma once
#include "usersim/common.h"
#include "usersim/io.h" // For IRP
#include "usersim/rtl.h" // For UNICODE_STRING

#if defined(__cplusplus)
Expand All @@ -13,18 +14,17 @@ extern "C"
#endif

typedef HANDLE WDFDEVICE;
typedef struct _wdfdriver WDFDRIVER;
typedef HANDLE WDFDRIVER;

typedef struct _WDF_OBJECT_ATTRIBUTES WDF_OBJECT_ATTRIBUTES, *PWDF_OBJECT_ATTRIBUTES;
typedef struct _WDF_OBJECT_ATTRIBUTES
{
int SynchronizationScope;
} WDF_OBJECT_ATTRIBUTES, *PWDF_OBJECT_ATTRIBUTES;
typedef struct _WDFDEVICE_INIT WDFDEVICE_INIT, *PWDFDEVICE_INIT;

#define WDF_NO_OBJECT_ATTRIBUTES 0
#define WDF_NO_HANDLE 0

typedef struct _wdfdriver WDFDRIVER;

typedef struct _driver_object DRIVER_OBJECT, *PDRIVER_OBJECT;

typedef NTSTATUS(DRIVER_INITIALIZE)(_In_ PDRIVER_OBJECT driver_object, _In_ PUNICODE_STRING registry_path);

typedef struct _WDFDEVICE_INIT WDFDEVICE_INIT, *PWDFDEVICE_INIT;
Expand All @@ -44,10 +44,10 @@ extern "C"
ULONG DriverPoolTag;
} WDF_DRIVER_CONFIG, *PWDF_DRIVER_CONFIG;

typedef struct _wdfdriver
struct _DRIVER_OBJECT
{
WDF_DRIVER_CONFIG config;
} WDFDRIVER;
};

#define WDF_DRIVER_GLOBALS_NAME_LEN (32)

Expand Down Expand Up @@ -78,6 +78,113 @@ extern "C"
void
WDF_DRIVER_CONFIG_INIT(_Out_ PWDF_DRIVER_CONFIG config, _In_opt_ PFN_WDF_DRIVER_DEVICE_ADD evt_driver_device_add);

typedef NTSTATUS(WdfDriverCreate_t)(
_In_ WDF_DRIVER_GLOBALS* driver_globals,
_In_ PDRIVER_OBJECT driver_object,
_In_ PCUNICODE_STRING registry_path,
_In_opt_ PWDF_OBJECT_ATTRIBUTES driver_attributes,
_In_ PWDF_DRIVER_CONFIG driver_config,
_Out_opt_ WDFDRIVER* driver);

typedef NTSTATUS(WdfDeviceCreate_t)(
_In_ WDF_DRIVER_GLOBALS* driver_globals,
_Inout_ PWDFDEVICE_INIT* device_init,
_In_opt_ PWDF_OBJECT_ATTRIBUTES device_attributes,
_Out_ WDFDEVICE* device);

typedef _IRQL_requires_max_(DISPATCH_LEVEL)
VOID(WdfDeviceInitFree_t)(_In_ PWDF_DRIVER_GLOBALS driver_globals, _In_ PWDFDEVICE_INIT device_init);

typedef _Must_inspect_result_ _IRQL_requires_max_(PASSIVE_LEVEL) PWDFDEVICE_INIT(WdfControlDeviceInitAllocate_t)(
_In_ PWDF_DRIVER_GLOBALS driver_globals,
_In_ WDFDRIVER driver,
_In_ CONST UNICODE_STRING* sddl_string);

typedef _IRQL_requires_max_(DISPATCH_LEVEL) VOID(WdfDeviceInitSetDeviceType_t)(
_In_ PWDF_DRIVER_GLOBALS driver_globals,
_In_ PWDFDEVICE_INIT device_init,
DEVICE_TYPE device_type);

#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080
#define FILE_DEVICE_SECURE_OPEN 0x00000100

typedef _IRQL_requires_max_(DISPATCH_LEVEL) VOID(WdfDeviceInitSetCharacteristics_t)(
_In_ PWDF_DRIVER_GLOBALS driver_globals,
_In_ PWDFDEVICE_INIT device_init,
ULONG device_characteristics,
BOOLEAN or_in_values);

typedef _Must_inspect_result_ _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS (WdfDeviceInitAssignName_t)(
_In_ PWDF_DRIVER_GLOBALS driver_globals,
_In_ PWDFDEVICE_INIT device_init,
_In_opt_ PCUNICODE_STRING device_name);

typedef struct _WDF_FILEOBJECT_CONFIG
{
int unused;
} WDF_FILEOBJECT_CONFIG, *PWDF_FILEOBJECT_CONFIG;

typedef _IRQL_requires_max_(DISPATCH_LEVEL) VOID (WdfDeviceInitSetFileObjectConfig_t)(
_In_ PWDF_DRIVER_GLOBALS driver_globals,
_In_ PWDFDEVICE_INIT device_init,
_In_ PWDF_FILEOBJECT_CONFIG file_object_config,
_In_opt_ PWDF_OBJECT_ATTRIBUTES file_object_attributes);


typedef NTSTATUS(FN_WDFDEVICE_WDM_IRP_PREPROCESS)(_In_ WDFDEVICE device, _Inout_ IRP* irp);
typedef FN_WDFDEVICE_WDM_IRP_PREPROCESS* PFN_WDFDEVICE_WDM_IRP_PREPROCESS;

#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a

typedef _Must_inspect_result_ _IRQL_requires_max_(DISPATCH_LEVEL) NTSTATUS (WdfDeviceInitAssignWdmIrpPreprocessCallback_t)(
_In_ PWDF_DRIVER_GLOBALS driver_globals,
_In_ PWDFDEVICE_INIT device_init,
_In_ PFN_WDFDEVICE_WDM_IRP_PREPROCESS evt_device_wdm_irp_preprocess,
UCHAR major_function,
_When_(num_minor_functions > 0, _In_reads_bytes_(num_minor_functions))
_When_(num_minor_functions == 0, _In_opt_) PUCHAR minor_functions,
ULONG num_minor_functions);

typedef _Must_inspect_result_ _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS (WdfDeviceCreateSymbolicLink_t)(
_In_ PWDF_DRIVER_GLOBALS driver_globals,
_In_ WDFDEVICE device,
_In_ PCUNICODE_STRING symbolic_link_name);

typedef struct _WDF_IO_QUEUE_CONFIG
{
int unused;
} WDF_IO_QUEUE_CONFIG, *PWDF_IO_QUEUE_CONFIG;
typedef HANDLE WDFQUEUE;

typedef _Must_inspect_result_ _IRQL_requires_max_(DISPATCH_LEVEL) NTSTATUS (WdfIoQueueCreate_t)(
_In_ PWDF_DRIVER_GLOBALS driver_globals,
_In_ WDFDEVICE device,
_In_ PWDF_IO_QUEUE_CONFIG config,
_In_opt_ PWDF_OBJECT_ATTRIBUTES queue_attributes,
_Out_opt_ WDFQUEUE* queue);

typedef HANDLE WDFOBJECT;

typedef _IRQL_requires_max_(DISPATCH_LEVEL)
VOID(WdfObjectDelete_t)(_In_ PWDF_DRIVER_GLOBALS driver_globals, _In_ WDFOBJECT object);

typedef enum _WDFFUNCENUM
{
WdfControlDeviceInitAllocateTableIndex = 25,
WdfDeviceInitFreeTableIndex = 54,
WdfDeviceInitSetDeviceTypeTableIndex = 66,
WdfDeviceInitAssignNameTableIndex = 67,
WdfDeviceInitSetCharacteristicsTableIndex = 70,
WdfDeviceInitSetFileObjectConfigTableIndex = 71,
WdfDeviceInitAssignWdmIrpPreprocessCallbackTableIndex = 73,
WdfDeviceCreateTableIndex = 75,
WdfDeviceCreateSymbolicLinkTableIndex = 80,
WdfDriverCreateTableIndex = 116,
WdfIoQueueCreateTableIndex = 152,
WdfObjectDeleteTableIndex = 208,
WdfFunctionTableNumEntries = 444,
} WDFFUNCENUM;

void
usersim_initialize_wdf();

Expand Down
1 change: 1 addition & 0 deletions src/etw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

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

typedef struct
{
Expand Down
Loading

0 comments on commit 8e6fdef

Please sign in to comment.