mirror of
https://github.com/espressif/openthread.git
synced 2026-07-05 03:40:26 +00:00
1d999ccea3
* Add Windows Tunnel Mode Miniport Driver (ottmp)
274 lines
8.6 KiB
C++
274 lines
8.6 KiB
C++
/*
|
|
* Copyright (c) 2016, The OpenThread Authors.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. Neither the name of the copyright holder nor the
|
|
* names of its contributors may be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* This module has code to deal with loading and unloading of the driver
|
|
*/
|
|
|
|
#include "pch.hpp"
|
|
#include "driver.tmh"
|
|
|
|
#ifdef OTTMP_LEGACY
|
|
static GLOBALS GlobalData = { 0 };
|
|
#endif
|
|
|
|
INITCODE
|
|
extern "C"
|
|
NTSTATUS
|
|
DriverEntry (
|
|
_In_ PDRIVER_OBJECT DriverObject,
|
|
_In_ PUNICODE_STRING RegistryPath
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
DriverEntry initializes the driver and is the first routine called by the
|
|
system after the driver is loaded. DriverEntry specifies the other entry
|
|
points in the function driver, such as EvtDevice and DriverUnload.
|
|
|
|
Parameters Description:
|
|
|
|
DriverObject - represents the instance of the function driver that is loaded
|
|
into memory. DriverEntry must initialize members of DriverObject before it
|
|
returns to the caller. DriverObject is allocated by the system before the
|
|
driver is loaded, and it is released by the system after the system unloads
|
|
the function driver from memory.
|
|
|
|
RegistryPath - represents the driver specific path in the Registry.
|
|
The function driver can use the path to store driver related data between
|
|
reboots. The path does not store hardware instance specific data.
|
|
|
|
Return Value:
|
|
|
|
A success status as determined by NT_SUCCESS macro, if successful.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS status;
|
|
WDF_DRIVER_CONFIG config;
|
|
#ifdef OTTMP_LEGACY
|
|
NDIS_STATUS ndisStatus = NDIS_STATUS_FAILURE;
|
|
NDIS_MINIPORT_DRIVER_CHARACTERISTICS MPChar = { 0 };
|
|
NET_BUFFER_LIST_POOL_PARAMETERS NblParams = { 0 };
|
|
NET_BUFFER_POOL_PARAMETERS NbParams = { 0 };
|
|
#endif
|
|
|
|
WPP_INIT_TRACING(DriverObject, RegistryPath);
|
|
|
|
LogFuncEntry(DRIVER_DEFAULT);
|
|
|
|
//
|
|
// Create the WdfDriver Object
|
|
//
|
|
WDF_DRIVER_CONFIG_INIT(&config, WDF_NO_EVENT_CALLBACK);
|
|
|
|
#ifdef OTTMP_LEGACY
|
|
//
|
|
// Set WdfDriverInitNoDispatchOverride flag to tell the framework
|
|
// not to provide dispatch routines for the driver. In other words,
|
|
// the framework must not intercept IRPs that the I/O manager has
|
|
// directed to the driver. In this case, it will be handled by NDIS
|
|
// port driver.
|
|
//
|
|
config.DriverInitFlags |= WdfDriverInitNoDispatchOverride;
|
|
#else
|
|
config.EvtDriverDeviceAdd = EvtDriverDeviceAdd;
|
|
config.EvtDriverUnload = EvtDriverUnload;
|
|
#endif
|
|
|
|
status = WdfDriverCreate(DriverObject,
|
|
RegistryPath,
|
|
WDF_NO_OBJECT_ATTRIBUTES,
|
|
&config,
|
|
#ifdef OTTMP_LEGACY
|
|
&GlobalData.WdfDriver
|
|
#else
|
|
NULL
|
|
#endif
|
|
);
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
LogError(DRIVER_DEFAULT, "WdfDriverCreate failed, %!STATUS!", status);
|
|
goto error;
|
|
}
|
|
|
|
#ifdef OTTMP_LEGACY
|
|
MPChar.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS;
|
|
MPChar.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2;
|
|
MPChar.Header.Size = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2;
|
|
|
|
// Version Suff
|
|
MPChar.MajorNdisVersion = NDIS_MINIPORT_MAJOR_VERSION;
|
|
MPChar.MinorNdisVersion = NDIS_MINIPORT_MINOR_VERSION;
|
|
MPChar.MajorDriverVersion = NIC_VENDOR_DRIVER_VERSION_MAJOR;
|
|
MPChar.MinorDriverVersion = NIC_VENDOR_DRIVER_VERSION_MINOR;
|
|
|
|
MPChar.InitializeHandlerEx = MPInitializeEx;
|
|
MPChar.HaltHandlerEx = MPHaltEx;
|
|
MPChar.UnloadHandler = MPDriverUnload;
|
|
MPChar.PauseHandler = MPPause;
|
|
MPChar.RestartHandler = MPRestart;
|
|
MPChar.OidRequestHandler = MPOidRequest;
|
|
MPChar.SendNetBufferListsHandler = MPSendNetBufferLists;
|
|
MPChar.ReturnNetBufferListsHandler = MPReturnNetBufferLists;
|
|
MPChar.CancelSendHandler = MPCancelSend;
|
|
MPChar.DevicePnPEventNotifyHandler = MPDevicePnpEventNotify;
|
|
MPChar.ShutdownHandlerEx = MPShutdownEx;
|
|
MPChar.CancelOidRequestHandler = MPCancelOidRequest;
|
|
|
|
ndisStatus = NdisMRegisterMiniportDriver(DriverObject,
|
|
RegistryPath,
|
|
&GlobalData,
|
|
&MPChar,
|
|
&GlobalData.hDriver);
|
|
if (ndisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
LogError(DRIVER_DEFAULT, "NdisMRegisterMiniportDriver failed %!NDIS_STATUS!", ndisStatus);
|
|
status = STATUS_UNSUCCESSFUL;
|
|
goto error;
|
|
}
|
|
|
|
NblParams.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
|
|
NblParams.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
|
|
NblParams.Header.Size = NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
|
|
NblParams.PoolTag = NIC_TAG_RECV_NBL;
|
|
GlobalData.hNblPool = NdisAllocateNetBufferListPool(GlobalData.hDriver, &NblParams);
|
|
if (GlobalData.hNblPool == 0)
|
|
{
|
|
LogError(DRIVER_DEFAULT, "NdisAllocateNetBufferListPool failed");
|
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
|
goto error;
|
|
}
|
|
|
|
NbParams.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
|
|
NbParams.Header.Revision = NET_BUFFER_POOL_PARAMETERS_REVISION_1;
|
|
NbParams.Header.Size = NDIS_SIZEOF_NET_BUFFER_POOL_PARAMETERS_REVISION_1;
|
|
NbParams.PoolTag = NIC_TAG_RECV_NBL;
|
|
NbParams.DataSize = MAX_SPINEL_COMMAND_LENGTH;
|
|
GlobalData.hNbPool = NdisAllocateNetBufferPool(GlobalData.hDriver, &NbParams);
|
|
if (GlobalData.hNbPool == 0)
|
|
{
|
|
LogError(DRIVER_DEFAULT, "NdisAllocateNetBufferListPool failed");
|
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
|
goto error;
|
|
}
|
|
#endif
|
|
|
|
error:
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
#ifdef OTTMP_LEGACY
|
|
MPDriverUnload(DriverObject);
|
|
#else
|
|
WPP_CLEANUP(DriverObject);
|
|
#endif
|
|
}
|
|
|
|
LogFuncExitNT(DRIVER_DEFAULT, status);
|
|
return status;
|
|
}
|
|
|
|
#ifdef OTTMP_LEGACY
|
|
|
|
PAGED
|
|
_Use_decl_annotations_
|
|
VOID
|
|
MPDriverUnload(
|
|
_In_ PDRIVER_OBJECT DriverObject
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
|
|
MPDriverUnload will clean up the WPP resources that was allocated
|
|
for this driver.
|
|
|
|
Arguments:
|
|
|
|
DriverObject - Handle to a framework driver object created in DriverEntry
|
|
|
|
--*/
|
|
{
|
|
LogFuncEntry(DRIVER_DEFAULT);
|
|
|
|
PAGED_CODE();
|
|
|
|
if (GlobalData.WdfDriver)
|
|
{
|
|
NT_ASSERT(GlobalData.WdfDriver == WdfGetDriver());
|
|
WdfDriverMiniportUnload(GlobalData.WdfDriver);
|
|
GlobalData.WdfDriver = nullptr;
|
|
}
|
|
|
|
if (GlobalData.hNblPool)
|
|
{
|
|
NdisFreeNetBufferListPool(GlobalData.hNblPool);
|
|
GlobalData.hNblPool = nullptr;
|
|
}
|
|
|
|
if (GlobalData.hDriver)
|
|
{
|
|
NdisMDeregisterMiniportDriver(GlobalData.hDriver);
|
|
GlobalData.hDriver = nullptr;
|
|
}
|
|
|
|
LogFuncExit(DRIVER_DEFAULT);
|
|
|
|
#pragma warning(suppress: 25024) // Dangerous cast
|
|
WPP_CLEANUP(DriverObject);
|
|
}
|
|
|
|
#else
|
|
|
|
PAGED
|
|
VOID
|
|
EvtDriverUnload(
|
|
WDFDRIVER Driver
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
|
|
EvtDriverUnload will clean up the WPP resources that was allocated
|
|
for this driver.
|
|
|
|
Arguments:
|
|
|
|
Driver - Handle to a framework driver object created in DriverEntry
|
|
|
|
--*/
|
|
{
|
|
LogFuncEntry(DRIVER_DEFAULT);
|
|
|
|
PAGED_CODE();
|
|
|
|
LogFuncExit(DRIVER_DEFAULT);
|
|
WPP_CLEANUP(WdfDriverWdmGetDriverObject(Driver));
|
|
}
|
|
|
|
#endif
|