mirror of
https://github.com/jamesstringer90/appsandbox.git
synced 2026-10-22 02:52:49 -05:00
448 lines
12 KiB
C++
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,
|
|
¶mTable[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()
|