_Must_inspect_result_ BOOLEAN FxpIsAddressKnownToWdf( __in PVOID Address, __in PFX_DRIVER_GLOBALS FxDriverGlobals ) /*++ Routine Description: This routine will check the address to determine if it falls within the image of a WDF component (Library, Client driver or Class Extension). This is accomplished by traversing the WdfLdrGlobals.LoadedModuleList and comparing each image start/end address with Address. Arguments: PVOID Address - The address to be checked, and it need not be currently paged in. In other words, it is NOT used in this routine as an address, but more as a simple scaler into a 4GB (x86) array. NOTE - Do not attempt to validatate Address, say via MmIsAddressValid(Address). Address's memory could be paged out, but Address is still valid. PFX_DRIVER_GLOBALS FxDriverGlobals - Driver's globals. Return Value: TRUE indicates something was found, either library, client or both. FALSE indicates either not found or invalid parameters. --*/ { if (NULL == Address || NULL == FxDriverGlobals) { return FALSE; } if (Address >= FxDriverGlobals->ImageAddress && Address < WDF_PTR_ADD_OFFSET(FxDriverGlobals->ImageAddress, FxDriverGlobals->ImageSize)) { return TRUE; } return FALSE; }
_Must_inspect_result_ NTSTATUS FxpGetImageBase( __in PDRIVER_OBJECT DriverObject, __out PVOID* ImageBase, __out PULONG ImageSize ) { NTSTATUS status = STATUS_UNSUCCESSFUL; ULONG modulesSize = 0; AUX_MODULE_EXTENDED_INFO* modules = NULL; AUX_MODULE_EXTENDED_INFO* module; PVOID addressInImage = NULL; ULONG numberOfModules; ULONG i; // // Basic validation. // if (NULL == DriverObject || NULL == ImageBase || NULL == ImageSize) { status = STATUS_INVALID_PARAMETER; goto exit; } // // Get the address of a well known entry in the Image. // addressInImage = (PVOID) DriverObject->DriverStart; ASSERT(addressInImage != NULL); // // Initialize the AUX Kernel Library. // status = AuxKlibInitialize(); if (!NT_SUCCESS(status)) { goto exit; } // // Get size of area needed for loaded modules. // status = AuxKlibQueryModuleInformation(&modulesSize, sizeof(AUX_MODULE_EXTENDED_INFO), NULL); if (!NT_SUCCESS(status) || (0 == modulesSize)) { goto exit; } numberOfModules = modulesSize / sizeof(AUX_MODULE_EXTENDED_INFO); // // Allocate returned-sized memory for the modules area. // modules = (AUX_MODULE_EXTENDED_INFO*) ExAllocatePoolWithTag(PagedPool, modulesSize, '30LW'); if (NULL == modules) { status = STATUS_INSUFFICIENT_RESOURCES; goto exit; } // // Request the modules array be filled with module information. // status = AuxKlibQueryModuleInformation(&modulesSize, sizeof(AUX_MODULE_EXTENDED_INFO), modules); if (!NT_SUCCESS(status)) { goto exit; } // // Traverse list, searching for the well known address in Image for which the // module's Image Base Address is in its range. // module = modules; for (i=0; i < numberOfModules; i++) { if (addressInImage >= module->BasicInfo.ImageBase && addressInImage < WDF_PTR_ADD_OFFSET(module->BasicInfo.ImageBase, module->ImageSize)) { *ImageBase = module->BasicInfo.ImageBase; *ImageSize = module->ImageSize; status = STATUS_SUCCESS; goto exit; } module++; } status = STATUS_NOT_FOUND; exit: if (modules != NULL) { ExFreePool(modules); modules = NULL; } return status; }
_Must_inspect_result_ NTSTATUS FxPkgPdo::Initialize( __in PWDFDEVICE_INIT DeviceInit ) /*++ Routine Description: Do initialization that might fail here. Arguemnts: DeviceInit - the structure the driver passed in with initialization data Returns: NTSTATUS --*/ { NTSTATUS status; size_t cbLength, cbStrLength; PWSTR pCur; PdoInit* pPdo; status = FxPkgPnp::Initialize(DeviceInit); if (!NT_SUCCESS(status)) { return status; } cbLength = 0; // // Compute the total number of bytes required for all strings and then // make one allocation and remember pointers w/in the string so we can // retrieve them individually later. // pPdo = &DeviceInit->Pdo; cbLength += FxCalculateTotalStringSize(&pPdo->HardwareIDs); cbLength += FxCalculateTotalStringSize(&pPdo->CompatibleIDs); if (pPdo->DeviceID != NULL) { cbLength += pPdo->DeviceID->ByteLength(TRUE); } if (pPdo->InstanceID != NULL) { cbLength += pPdo->InstanceID->ByteLength(TRUE); } if (pPdo->ContainerID != NULL) { cbLength += pPdo->ContainerID->ByteLength(TRUE); } m_IDsAllocation = (PWSTR) FxPoolAllocate(GetDriverGlobals(), PagedPool, cbLength); if (m_IDsAllocation == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; DoTraceLevelMessage( GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP, "DeviceInit %p could not allocate string for device IDs " "(length %I64d), %!STATUS!", DeviceInit, cbLength, status); return status; } pCur = m_IDsAllocation; m_HardwareIDs = pCur; pCur = FxCopyMultiSz(m_HardwareIDs, &pPdo->HardwareIDs); m_CompatibleIDs = pCur; pCur = FxCopyMultiSz(m_CompatibleIDs, &pPdo->CompatibleIDs); if (pPdo->DeviceID != NULL) { m_DeviceID = pCur; // // Copy the bytes and then null terminate the buffer // cbStrLength = pPdo->DeviceID->ByteLength(FALSE); RtlCopyMemory(m_DeviceID, pPdo->DeviceID->Buffer(), cbStrLength); m_DeviceID[cbStrLength / sizeof(WCHAR)] = UNICODE_NULL; pCur = (PWSTR) WDF_PTR_ADD_OFFSET(m_DeviceID, cbStrLength + sizeof(UNICODE_NULL)); } if (pPdo->InstanceID != NULL) { m_InstanceID = pCur; // // Copy the bytes and then null terminate the buffer // cbStrLength = pPdo->InstanceID->ByteLength(FALSE); RtlCopyMemory(m_InstanceID, pPdo->InstanceID->Buffer(), cbStrLength); m_InstanceID[cbStrLength / sizeof(WCHAR)] = UNICODE_NULL; pCur = (PWSTR) WDF_PTR_ADD_OFFSET(m_InstanceID, cbStrLength + sizeof(UNICODE_NULL)); } if (pPdo->ContainerID != NULL) { m_ContainerID = pCur; // // Copy the bytes and then null terminate the buffer // cbStrLength = pPdo->ContainerID->ByteLength(FALSE); RtlCopyMemory(m_ContainerID, pPdo->ContainerID->Buffer(), cbStrLength); m_ContainerID[cbStrLength / sizeof(WCHAR)] = UNICODE_NULL; } m_Static = pPdo->Static; if (m_Static) { // // Statically enumerated children do not support reenumeration requests // from the stack on top of them. // // // The only way we can have static children is if an FDO enumerates them. // Mx::MxAssert(m_Device->m_ParentDevice->IsFdo()); m_OwningChildList = m_Device->m_ParentDevice->GetFdoPkg()->m_StaticDeviceList; m_OwningChildList->ADDREF(this); } else { m_Description = pPdo->DescriptionEntry; m_OwningChildList = m_Description->GetParentList(); m_OwningChildList->ADDREF(this); } return STATUS_SUCCESS; }