Files
appsandbox/tools/vad/adapter.cpp

448 lines
12 KiB
C++

#pragma warning (disable : 4127)
//
// All the GUIDs for all the miniports end up in this object.
//
#define PUT_GUIDS_HERE
#include "driverdefs.h"
#include "renderendpoints.h"
typedef void (*fnPcDriverUnload) (PDRIVER_OBJECT);
fnPcDriverUnload gPCDriverUnloadRoutine = NULL;
extern "C" DRIVER_UNLOAD DriverUnload;
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
DRIVER_ADD_DEVICE AddDevice;
NTSTATUS
StartDevice
(
_In_ PDEVICE_OBJECT,
_In_ PIRP,
_In_ PRESOURCELIST
);
_Dispatch_type_(IRP_MJ_PNP)
DRIVER_DISPATCH PnpHandler;
//-----------------------------------------------------------------------------
// Globals
//-----------------------------------------------------------------------------
DWORD g_DoNotCreateDataFiles = 1;
UNICODE_STRING g_RegistryPath;
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
#pragma code_seg("PAGE")
void ReleaseRegistryStringBuffer()
{
PAGED_CODE();
if (g_RegistryPath.Buffer != NULL)
{
ExFreePool(g_RegistryPath.Buffer);
g_RegistryPath.Buffer = NULL;
g_RegistryPath.Length = 0;
g_RegistryPath.MaximumLength = 0;
}
}
//=============================================================================
#pragma code_seg("PAGE")
extern "C"
void DriverUnload
(
_In_ PDRIVER_OBJECT DriverObject
)
{
PAGED_CODE();
DPF(D_TERSE, ("[DriverUnload]"));
ReleaseRegistryStringBuffer();
if (DriverObject == NULL)
{
goto Done;
}
if (gPCDriverUnloadRoutine != NULL)
{
gPCDriverUnloadRoutine(DriverObject);
}
if (WdfGetDriver() != NULL)
{
WdfDriverMiniportUnload(WdfGetDriver());
}
Done:
return;
}
//=============================================================================
#pragma code_seg("INIT")
__drv_requiresIRQL(PASSIVE_LEVEL)
NTSTATUS
CopyRegistrySettingsPath(
_In_ PUNICODE_STRING RegistryPath
)
{
RtlInitUnicodeString(&g_RegistryPath, NULL);
g_RegistryPath.MaximumLength = RegistryPath->Length + sizeof(WCHAR);
g_RegistryPath.Buffer = (PWCH)ExAllocatePool2(POOL_FLAG_PAGED, g_RegistryPath.MaximumLength, VAD_ADAPTER_POOLTAG);
if (g_RegistryPath.Buffer == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlAppendUnicodeToString(&g_RegistryPath, RegistryPath->Buffer);
return STATUS_SUCCESS;
}
//=============================================================================
#pragma code_seg("INIT")
__drv_requiresIRQL(PASSIVE_LEVEL)
NTSTATUS
GetRegistrySettings(
_In_ PUNICODE_STRING RegistryPath
)
{
NTSTATUS ntStatus;
PDRIVER_OBJECT DriverObject;
HANDLE DriverKey;
RTL_QUERY_REGISTRY_TABLE paramTable[] = {
// QueryRoutine Flags Name EntryContext DefaultType DefaultData DefaultLength
{ NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"DoNotCreateDataFiles", &g_DoNotCreateDataFiles, (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_DWORD, &g_DoNotCreateDataFiles, sizeof(ULONG)},
{ NULL, 0, NULL, NULL, 0, NULL, 0}
};
DPF(D_TERSE, ("[GetRegistrySettings]"));
PAGED_CODE();
UNREFERENCED_PARAMETER(RegistryPath);
DriverObject = WdfDriverWdmGetDriverObject(WdfGetDriver());
DriverKey = NULL;
ntStatus = IoOpenDriverRegistryKey(DriverObject,
DriverRegKeyParameters,
KEY_READ,
0,
&DriverKey);
if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
}
ntStatus = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
(PCWSTR) DriverKey,
&paramTable[0],
NULL,
NULL);
if (!NT_SUCCESS(ntStatus))
{
DPF(D_VERBOSE, ("RtlQueryRegistryValues failed, using default values, 0x%x", ntStatus));
}
DPF(D_VERBOSE, ("DoNotCreateDataFiles: %u", g_DoNotCreateDataFiles));
if (DriverKey)
{
ZwClose(DriverKey);
}
return STATUS_SUCCESS;
}
//=============================================================================
#pragma code_seg("INIT")
extern "C" DRIVER_INITIALIZE DriverEntry;
extern "C" NTSTATUS
DriverEntry
(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPathName
)
{
NTSTATUS ntStatus;
WDF_DRIVER_CONFIG config;
DPF(D_TERSE, ("[DriverEntry]"));
ntStatus = CopyRegistrySettingsPath(RegistryPathName);
IF_FAILED_ACTION_JUMP(
ntStatus,
DPF(D_ERROR, ("Registry path copy error 0x%x", ntStatus)),
Done);
WDF_DRIVER_CONFIG_INIT(&config, WDF_NO_EVENT_CALLBACK);
config.DriverInitFlags |= WdfDriverInitNoDispatchOverride;
config.DriverPoolTag = VAD_ADAPTER_POOLTAG;
ntStatus = WdfDriverCreate(DriverObject,
RegistryPathName,
WDF_NO_OBJECT_ATTRIBUTES,
&config,
WDF_NO_HANDLE);
IF_FAILED_ACTION_JUMP(
ntStatus,
DPF(D_ERROR, ("WdfDriverCreate failed, 0x%x", ntStatus)),
Done);
ntStatus = GetRegistrySettings(RegistryPathName);
IF_FAILED_ACTION_JUMP(
ntStatus,
DPF(D_ERROR, ("Registry Configuration error 0x%x", ntStatus)),
Done);
ntStatus = PcInitializeAdapterDriver(DriverObject,
RegistryPathName,
(PDRIVER_ADD_DEVICE)AddDevice);
IF_FAILED_ACTION_JUMP(
ntStatus,
DPF(D_ERROR, ("PcInitializeAdapterDriver failed, 0x%x", ntStatus)),
Done);
DriverObject->MajorFunction[IRP_MJ_PNP] = PnpHandler;
gPCDriverUnloadRoutine = DriverObject->DriverUnload;
DriverObject->DriverUnload = DriverUnload;
ntStatus = STATUS_SUCCESS;
Done:
if (!NT_SUCCESS(ntStatus))
{
if (WdfGetDriver() != NULL)
{
WdfDriverMiniportUnload(WdfGetDriver());
}
ReleaseRegistryStringBuffer();
}
return ntStatus;
}
//=============================================================================
#pragma code_seg()
#pragma warning(disable:28152)
#pragma code_seg("PAGE")
NTSTATUS AddDevice
(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PDEVICE_OBJECT PhysicalDeviceObject
)
{
PAGED_CODE();
NTSTATUS ntStatus;
ULONG maxObjects;
DPF(D_TERSE, ("[AddDevice]"));
maxObjects = g_MaxMiniports;
ntStatus =
PcAddAdapterDevice
(
DriverObject,
PhysicalDeviceObject,
PCPFNSTARTDEVICE(StartDevice),
maxObjects,
0
);
return ntStatus;
}
//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
InstallEndpointRenderFilters(
_In_ PDEVICE_OBJECT _pDeviceObject,
_In_ PIRP _pIrp,
_In_ PADAPTERCOMMON _pAdapterCommon,
_In_ PENDPOINT_MINIPAIR _pAeMiniports
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PUNKNOWN unknownTopology = NULL;
PUNKNOWN unknownWave = NULL;
PPORTCLSETWHELPER pPortClsEtwHelper = NULL;
PAGED_CODE();
UNREFERENCED_PARAMETER(_pDeviceObject);
ntStatus = _pAdapterCommon->InstallEndpointFilters(
_pIrp,
_pAeMiniports,
NULL,
&unknownTopology,
&unknownWave,
NULL, NULL);
if (unknownWave)
{
ntStatus = unknownWave->QueryInterface(IID_IPortClsEtwHelper, (PVOID *)&pPortClsEtwHelper);
if (NT_SUCCESS(ntStatus))
{
_pAdapterCommon->SetEtwHelper(pPortClsEtwHelper);
ASSERT(pPortClsEtwHelper != NULL);
pPortClsEtwHelper->Release();
}
}
SAFE_RELEASE(unknownTopology);
SAFE_RELEASE(unknownWave);
return ntStatus;
}
//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
InstallAllRenderFilters(
_In_ PDEVICE_OBJECT _pDeviceObject,
_In_ PIRP _pIrp,
_In_ PADAPTERCOMMON _pAdapterCommon
)
{
NTSTATUS ntStatus;
PENDPOINT_MINIPAIR* ppAeMiniports = g_RenderEndpoints;
PAGED_CODE();
for (ULONG i = 0; i < g_cRenderEndpoints; ++i, ++ppAeMiniports)
{
ntStatus = InstallEndpointRenderFilters(_pDeviceObject, _pIrp, _pAdapterCommon, *ppAeMiniports);
IF_FAILED_JUMP(ntStatus, Exit);
}
ntStatus = STATUS_SUCCESS;
Exit:
return ntStatus;
}
//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
StartDevice
(
_In_ PDEVICE_OBJECT DeviceObject,
_In_ PIRP Irp,
_In_ PRESOURCELIST ResourceList
)
{
UNREFERENCED_PARAMETER(ResourceList);
PAGED_CODE();
ASSERT(DeviceObject);
ASSERT(Irp);
ASSERT(ResourceList);
NTSTATUS ntStatus = STATUS_SUCCESS;
PADAPTERCOMMON pAdapterCommon = NULL;
PUNKNOWN pUnknownCommon = NULL;
PortClassDeviceContext* pExtension = static_cast<PortClassDeviceContext*>(DeviceObject->DeviceExtension);
DPF_ENTER(("[StartDevice]"));
ntStatus = NewAdapterCommon(
&pUnknownCommon,
IID_IAdapterCommon,
NULL,
POOL_FLAG_NON_PAGED
);
IF_FAILED_JUMP(ntStatus, Exit);
ntStatus = pUnknownCommon->QueryInterface(IID_IAdapterCommon, (PVOID *) &pAdapterCommon);
IF_FAILED_JUMP(ntStatus, Exit);
ntStatus = pAdapterCommon->Init(DeviceObject);
IF_FAILED_JUMP(ntStatus, Exit);
ntStatus = PcRegisterAdapterPowerManagement(PUNKNOWN(pAdapterCommon), DeviceObject);
IF_FAILED_JUMP(ntStatus, Exit);
ntStatus = InstallAllRenderFilters(DeviceObject, Irp, pAdapterCommon);
IF_FAILED_JUMP(ntStatus, Exit);
Exit:
if (pAdapterCommon)
{
ASSERT(pExtension != NULL);
pExtension->m_pCommon = pAdapterCommon;
}
SAFE_RELEASE(pUnknownCommon);
return ntStatus;
}
//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
PnpHandler
(
_In_ DEVICE_OBJECT *_DeviceObject,
_Inout_ IRP *_Irp
)
{
NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
IO_STACK_LOCATION *stack;
PortClassDeviceContext *ext;
#pragma warning(suppress: 28118)
PAGED_CODE();
ASSERT(_DeviceObject);
ASSERT(_Irp);
stack = IoGetCurrentIrpStackLocation(_Irp);
switch (stack->MinorFunction)
{
case IRP_MN_REMOVE_DEVICE:
case IRP_MN_SURPRISE_REMOVAL:
case IRP_MN_STOP_DEVICE:
ext = static_cast<PortClassDeviceContext*>(_DeviceObject->DeviceExtension);
if (ext->m_pCommon != NULL)
{
ext->m_pCommon->Cleanup();
ext->m_pCommon->Release();
ext->m_pCommon = NULL;
}
break;
default:
break;
}
ntStatus = PcDispatchIrp(_DeviceObject, _Irp);
return ntStatus;
}
#pragma code_seg()