NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { NTSTATUS status = STATUS_SUCCESS; WDF_DRIVER_CONFIG config; WDF_OBJECT_ATTRIBUTES attributes; WDFDRIVER Driver; PDRIVER_CONTEXT Context; #if (NTDDI_VERSION > NTDDI_WIN7) ExInitializeDriverRuntime(DrvRtPoolNxOptIn); #endif WPP_INIT_TRACING(DriverObject, RegistryPath); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "Virtio-Serial driver started...built on %s %s\n", __DATE__, __TIME__); WDF_DRIVER_CONFIG_INIT(&config,VIOSerialEvtDeviceAdd); config.DriverPoolTag = VIOSERIAL_DRIVER_MEMORY_TAG; WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DRIVER_CONTEXT); attributes.EvtCleanupCallback = VIOSerialEvtDriverContextCleanup; status = WdfDriverCreate(DriverObject, RegistryPath, &attributes, &config, &Driver); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT, "WdfDriverCreate failed - 0x%x\n", status); WPP_CLEANUP(DriverObject); return status; } Context = GetDriverContext(Driver); // create a lookaside list used for allocating WRITE_BUFFER_ENTRY // structures by all devices status = WdfLookasideListCreate(WDF_NO_OBJECT_ATTRIBUTES, sizeof(WRITE_BUFFER_ENTRY), NonPagedPool, WDF_NO_OBJECT_ATTRIBUTES, VIOSERIAL_DRIVER_MEMORY_TAG, &Context->WriteBufferLookaside); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT, "WdfLookasideListCreate failed - 0x%x\n", status); return status; } TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- %s\n", __FUNCTION__); return status; }
VOID VIOSerialPortWrite(IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t Length) { NTSTATUS status; PVOID InBuf; PVOID buffer; PVIOSERIAL_PORT Port; PWRITE_BUFFER_ENTRY entry; WDFDEVICE Device; PDRIVER_CONTEXT Context; WDFMEMORY EntryHandle; TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "--> %s Request: %p Length: %d\n", __FUNCTION__, Request, Length); PAGED_CODE(); Device = WdfIoQueueGetDevice(Queue); Port = RawPdoSerialPortGetData(Device)->port; if (Port->Removed) { TraceEvents(TRACE_LEVEL_WARNING, DBG_WRITE, "Write request on a removed port %d\n", Port->PortId); WdfRequestComplete(Request, STATUS_OBJECT_NO_LONGER_EXISTS); return; } status = WdfRequestRetrieveInputBuffer(Request, Length, &InBuf, NULL); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "Failed to retrieve input buffer: %x\n", status); WdfRequestComplete(Request, status); return; } if (VIOSerialWillWriteBlock(Port)) { WdfRequestComplete(Request, STATUS_CANT_WAIT); return; } buffer = ExAllocatePoolWithTag(NonPagedPool, Length, VIOSERIAL_DRIVER_MEMORY_TAG); if (buffer == NULL) { TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "Failed to allocate.\n"); WdfRequestComplete(Request, STATUS_INSUFFICIENT_RESOURCES); return; } Context = GetDriverContext(WdfDeviceGetDriver(Device)); status = WdfMemoryCreateFromLookaside(Context->WriteBufferLookaside, &EntryHandle); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "Failed to allocate write buffer entry: %x.\n", status); ExFreePoolWithTag(buffer, VIOSERIAL_DRIVER_MEMORY_TAG); WdfRequestComplete(Request, STATUS_INSUFFICIENT_RESOURCES); return; } status = WdfRequestMarkCancelableEx(Request, VIOSerialPortWriteRequestCancel); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "Failed to mark request as cancelable: %x\n", status); ExFreePoolWithTag(buffer, VIOSERIAL_DRIVER_MEMORY_TAG); WdfObjectDelete(EntryHandle); WdfRequestComplete(Request, status); return; } RtlCopyMemory(buffer, InBuf, Length); WdfRequestSetInformation(Request, (ULONG_PTR)Length); entry = (PWRITE_BUFFER_ENTRY)WdfMemoryGetBuffer(EntryHandle, NULL); entry->EntryHandle = EntryHandle; entry->Buffer = buffer; entry->Request = Request; if (VIOSerialSendBuffers(Port, entry, Length) <= 0) { TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "Failed to send user's buffer.\n"); ExFreePoolWithTag(buffer, VIOSERIAL_DRIVER_MEMORY_TAG); WdfObjectDelete(EntryHandle); if (WdfRequestUnmarkCancelable(Request) != STATUS_CANCELLED) { WdfRequestComplete(Request, Port->Removed ? STATUS_INVALID_DEVICE_STATE : STATUS_INSUFFICIENT_RESOURCES); } } TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,"<-- %s\n", __FUNCTION__); }
NTSTATUS DrvClass::PnpAdd_sta(IN WDFDRIVER Driver, IN PWDFDEVICE_INIT DeviceInit) { PDRIVER_CONTEXT pContext = GetDriverContext(Driver); DrvClass* pThis = (DrvClass*)pContext->par1; return pThis->PnpAdd(DeviceInit); }
DrvClass* DrvClass::GetDrvClassFromDriver(WDFDRIVER Driver) { PDRIVER_CONTEXT pContext = GetDriverContext(Driver); return (DrvClass*)pContext->par1; }
string IDataSource::GetApplicationName(void) const { return GetDriverContext()->GetApplicationName(); }
void IDataSource::SetApplicationName(const string& app_name) { GetDriverContext()->SetApplicationName(app_name); }