164 строки
5.1 KiB
C
164 строки
5.1 KiB
C
// Copyright (c) Microsoft Corporation
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#define NO_CRT
|
|
#include "bpf2c.h"
|
|
|
|
#include <guiddef.h>
|
|
#include <wdm.h>
|
|
#include <wsk.h>
|
|
|
|
DRIVER_INITIALIZE DriverEntry;
|
|
DRIVER_UNLOAD DriverUnload;
|
|
RTL_QUERY_REGISTRY_ROUTINE static _bpf2c_query_registry_routine;
|
|
|
|
#define metadata_table ___METADATA_TABLE___##_metadata_table
|
|
|
|
static GUID _bpf2c_npi_id = {/* c847aac8-a6f2-4b53-aea3-f4a94b9a80cb */
|
|
0xc847aac8,
|
|
0xa6f2,
|
|
0x4b53,
|
|
{0xae, 0xa3, 0xf4, 0xa9, 0x4b, 0x9a, 0x80, 0xcb}};
|
|
static NPI_MODULEID _bpf2c_module_id = {sizeof(_bpf2c_module_id), MIT_GUID, {0}};
|
|
static HANDLE _bpf2c_nmr_client_handle;
|
|
static HANDLE _bpf2c_nmr_provider_handle;
|
|
extern metadata_table_t metadata_table;
|
|
|
|
static NTSTATUS
|
|
_bpf2c_npi_client_attach_provider(
|
|
_In_ HANDLE nmr_binding_handle,
|
|
_In_ void* client_context,
|
|
_In_ const NPI_REGISTRATION_INSTANCE* provider_registration_instance);
|
|
|
|
static NTSTATUS
|
|
_bpf2c_npi_client_detach_provider(_In_ void* client_binding_context);
|
|
|
|
static const NPI_CLIENT_CHARACTERISTICS _bpf2c_npi_client_characteristics = {
|
|
0, // Version
|
|
sizeof(NPI_CLIENT_CHARACTERISTICS), // Length
|
|
_bpf2c_npi_client_attach_provider,
|
|
_bpf2c_npi_client_detach_provider,
|
|
NULL,
|
|
{0, // Version
|
|
sizeof(NPI_REGISTRATION_INSTANCE), // Length
|
|
&_bpf2c_npi_id,
|
|
&_bpf2c_module_id,
|
|
0,
|
|
&metadata_table}};
|
|
|
|
static NTSTATUS
|
|
_bpf2c_query_npi_module_id(
|
|
_In_ const wchar_t* value_name,
|
|
unsigned long value_type,
|
|
_In_ const void* value_data,
|
|
unsigned long value_length,
|
|
_Inout_ void* context,
|
|
_Inout_ void* entry_context)
|
|
{
|
|
UNREFERENCED_PARAMETER(value_name);
|
|
UNREFERENCED_PARAMETER(context);
|
|
UNREFERENCED_PARAMETER(entry_context);
|
|
|
|
if (value_type != REG_BINARY) {
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
if (value_length != sizeof(_bpf2c_module_id.Guid)) {
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
memcpy(&_bpf2c_module_id.Guid, value_data, value_length);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
NTSTATUS
|
|
DriverEntry(_In_ DRIVER_OBJECT* driver_object, _In_ UNICODE_STRING* registry_path)
|
|
{
|
|
NTSTATUS status;
|
|
RTL_QUERY_REGISTRY_TABLE query_table[] = {
|
|
{
|
|
NULL, // Query routine
|
|
RTL_QUERY_REGISTRY_SUBKEY, // Flags
|
|
L"Parameters", // Name
|
|
NULL, // Entry context
|
|
REG_NONE, // Default type
|
|
NULL, // Default data
|
|
0, // Default length
|
|
},
|
|
{
|
|
_bpf2c_query_npi_module_id, // Query routine
|
|
RTL_QUERY_REGISTRY_REQUIRED, // Flags
|
|
L"NpiModuleId", // Name
|
|
NULL, // Entry context
|
|
REG_NONE, // Default type
|
|
NULL, // Default data
|
|
0, // Default length
|
|
},
|
|
{0}};
|
|
|
|
status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, registry_path->Buffer, query_table, NULL, NULL);
|
|
if (!NT_SUCCESS(status)) {
|
|
goto Exit;
|
|
}
|
|
|
|
status = NmrRegisterClient(&_bpf2c_npi_client_characteristics, NULL, &_bpf2c_nmr_client_handle);
|
|
|
|
Exit:
|
|
if (NT_SUCCESS(status)) {
|
|
driver_object->DriverUnload = DriverUnload;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
void
|
|
DriverUnload(_In_ DRIVER_OBJECT* driver_object)
|
|
{
|
|
NTSTATUS status = NmrDeregisterClient(_bpf2c_nmr_client_handle);
|
|
if (status == STATUS_PENDING) {
|
|
NmrWaitForClientDeregisterComplete(_bpf2c_nmr_client_handle);
|
|
}
|
|
UNREFERENCED_PARAMETER(driver_object);
|
|
}
|
|
|
|
static NTSTATUS
|
|
_bpf2c_npi_client_attach_provider(
|
|
_In_ HANDLE nmr_binding_handle,
|
|
_In_ void* client_context,
|
|
_In_ const NPI_REGISTRATION_INSTANCE* provider_registration_instance)
|
|
{
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
void* provider_binding_context = NULL;
|
|
void* provider_dispatch_table = NULL;
|
|
|
|
UNREFERENCED_PARAMETER(client_context);
|
|
UNREFERENCED_PARAMETER(provider_registration_instance);
|
|
|
|
if (_bpf2c_nmr_provider_handle != NULL) {
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
#pragma warning(push)
|
|
#pragma warning( \
|
|
disable : 6387) // Param 3 does not adhere to the specification for the function 'NmrClientAttachProvider'
|
|
// As per MSDN, client dispatch can be NULL, but SAL does not allow it.
|
|
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/netioddk/nf-netioddk-nmrclientattachprovider
|
|
status = NmrClientAttachProvider(
|
|
nmr_binding_handle, client_context, NULL, &provider_binding_context, &provider_dispatch_table);
|
|
if (status != STATUS_SUCCESS) {
|
|
goto Done;
|
|
}
|
|
#pragma warning(pop)
|
|
_bpf2c_nmr_provider_handle = nmr_binding_handle;
|
|
|
|
Done:
|
|
return status;
|
|
}
|
|
|
|
static NTSTATUS
|
|
_bpf2c_npi_client_detach_provider(_In_ void* client_binding_context)
|
|
{
|
|
_bpf2c_nmr_provider_handle = NULL;
|
|
UNREFERENCED_PARAMETER(client_binding_context);
|
|
return STATUS_SUCCESS;
|
|
}
|