From 5426a647c3f86885e4b9d8679d4a4c108933b5ee Mon Sep 17 00:00:00 2001 From: Alex Bozhko Date: Thu, 11 Jun 2026 16:13:41 -0700 Subject: Netvadapter: virtual NIC sample for KMDF and UMDF --- .../netvadapter/drivercode/memorymanagement.cpp | 89 ++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 network/netadaptercx/netvadapter/drivercode/memorymanagement.cpp (limited to 'network/netadaptercx/netvadapter/drivercode/memorymanagement.cpp') diff --git a/network/netadaptercx/netvadapter/drivercode/memorymanagement.cpp b/network/netadaptercx/netvadapter/drivercode/memorymanagement.cpp new file mode 100644 index 00000000..29a2006a --- /dev/null +++ b/network/netadaptercx/netvadapter/drivercode/memorymanagement.cpp @@ -0,0 +1,89 @@ +// Copyright (c) Microsoft Corporation. All rights reserved +// +// Global operator new / delete for the driver. +// +// The shared netvadapterlibrary routes its allocations through the global +// operator new (see memory.cpp in the library, which provides the nothrow +// variant that forwards to operator new(size_t)). The client driver is +// responsible for providing the backing implementation. We use WDF managed +// memory so that the same implementation works for both KMDF and UMDF, the +// same approach used by the WIFICX sample. + +#include "pch.hpp" + +#define NETV_POOL_TAG 'vteN' + +struct NETV_MEMORY_HEADER +{ + size_t HeaderSize; + WDFMEMORY WdfMemoryHandle; +}; + +static void* AllocateBuffer(size_t Size) +{ + const size_t totalSize = Size + sizeof(NETV_MEMORY_HEADER); + + WDF_OBJECT_ATTRIBUTES attributes; + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + + WDFMEMORY wdfMemory = WDF_NO_HANDLE; + void* buffer = nullptr; + + if (!NT_SUCCESS(WdfMemoryCreate(&attributes, NonPagedPoolNx, NETV_POOL_TAG, totalSize, &wdfMemory, &buffer))) + { + return nullptr; + } + + RtlZeroMemory(buffer, totalSize); + + auto header = static_cast(buffer); + header->HeaderSize = sizeof(NETV_MEMORY_HEADER); + header->WdfMemoryHandle = wdfMemory; + + return reinterpret_cast(reinterpret_cast(buffer) + sizeof(NETV_MEMORY_HEADER)); +} + +static void FreeBuffer(void* Buffer) +{ + if (Buffer == nullptr) + { + return; + } + + auto header = reinterpret_cast( + reinterpret_cast(Buffer) - sizeof(NETV_MEMORY_HEADER)); + + NT_ASSERT(header->HeaderSize == sizeof(NETV_MEMORY_HEADER)); + + WdfObjectDelete(header->WdfMemoryHandle); +} + +void* __cdecl operator new(size_t Size) +{ + return AllocateBuffer(Size); +} + +void* __cdecl operator new[](size_t Size) +{ + return AllocateBuffer(Size); +} + +void __cdecl operator delete(void* Buffer) noexcept +{ + FreeBuffer(Buffer); +} + +void __cdecl operator delete[](void* Buffer) noexcept +{ + FreeBuffer(Buffer); +} + +void __cdecl operator delete(void* Buffer, size_t) noexcept +{ + FreeBuffer(Buffer); +} + +void __cdecl operator delete[](void* Buffer, size_t) noexcept +{ + FreeBuffer(Buffer); +} -- cgit v1.3.1