USBDK/UsbDk/Driver.cpp
Dmitry Fleytman fccb982f58 FilterDevice: Protect filter objects from deletion while in use
This patch makes filter object reference counting objects and
ensures reference is help to filter objects while they are in use.

Signed-off-by: Dmitry Fleytman <dfleytma@redhat.com>
2015-11-24 12:32:33 +02:00

151 lines
3.7 KiB
C++

/**********************************************************************
* Copyright (c) 2013-2014 Red Hat, Inc.
*
* Developed by Daynix Computing LTD.
*
* Authors:
* Dmitry Fleytman <dmitry@daynix.com>
* Pavel Gurvich <pavel@daynix.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**********************************************************************/
#include "stdafx.h"
#include "driver.h"
#include "ControlDevice.h"
#include "FilterDevice.h"
#include "driver.tmh"
#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, DriverEntry)
#endif
NTSTATUS
DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
{
WDF_DRIVER_CONFIG config;
NTSTATUS status;
WDF_OBJECT_ATTRIBUTES attributes;
//
// Initialize WPP Tracing
//
WPP_INIT_TRACING( DriverObject, RegistryPath );
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
//
// Register a cleanup callback so that we can call WPP_CLEANUP when
// the framework driver object is deleted during driver unload.
//
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
attributes.EvtCleanupCallback = UsbDkEvtDriverContextCleanup;
WDF_DRIVER_CONFIG_INIT(&config,
UsbDkEvtDeviceAdd);
config.EvtDriverUnload = DriverUnload;
CDriverParamsRegistryPath::CreateFrom(RegistryPath);
WDFDRIVER Driver;
status = WdfDriverCreate(DriverObject,
RegistryPath,
&attributes,
&config,
&Driver);
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "WdfDriverCreate failed %!STATUS!", status);
WPP_CLEANUP(DriverObject);
return status;
}
if (!CUsbDkControlDevice::Allocate())
{
return STATUS_INSUFFICIENT_RESOURCES;
}
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit");
return STATUS_SUCCESS;
}
VOID
DriverUnload(IN WDFDRIVER Driver)
{
UNREFERENCED_PARAMETER(Driver);
PAGED_CODE();
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
CUsbDkControlDevice::Deallocate();
CDriverParamsRegistryPath::Destroy();
return;
}
NTSTATUS
UsbDkEvtDeviceAdd(
_In_ WDFDRIVER Driver,
_Inout_ PWDFDEVICE_INIT DeviceInit
)
{
PAGED_CODE();
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
auto FilterDevice = new CUsbDkFilterDevice();
if (FilterDevice == nullptr)
{
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "%!FUNC! Failed to allocate filter device");
return STATUS_INSUFFICIENT_RESOURCES;
}
auto status = FilterDevice->Create(DeviceInit);
if (!NT_SUCCESS(status))
{
FilterDevice->Release();
return status;
}
status = FilterDevice->AttachToStack(Driver);
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit %!STATUS!", status);
return status;
}
VOID
UsbDkEvtDriverContextCleanup(
_In_ WDFOBJECT DriverObject
)
{
UNREFERENCED_PARAMETER(DriverObject);
PAGED_CODE ();
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
//
// Stop WPP Tracing
//
WPP_CLEANUP( WdfGetDriver() );
}