1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxQueryInterface.cpp 8 9 Abstract: 10 11 This module implements the device interface object. 12 13 Author: 14 15 16 17 Environment: 18 19 Kernel mode only 20 21 Revision History: 22 23 --*/ 24 25 #include "fxsupportpch.hpp" 26 27 extern "C" { 28 // #include "FxQueryInterface.tmh" 29 } 30 31 FxQueryInterface::FxQueryInterface( 32 __in FxDevice* Device, 33 __in PWDF_QUERY_INTERFACE_CONFIG Config 34 ) : 35 m_Device(Device), 36 m_Interface(NULL) 37 { 38 m_Entry.Next = NULL; 39 40 m_EmbeddedInterface = FALSE; 41 42 if (Config != NULL) { 43 m_SendQueryToParentStack = Config->SendQueryToParentStack; 44 m_ImportInterface = Config->ImportInterface; 45 m_ProcessRequest.m_Method = Config->EvtDeviceProcessQueryInterfaceRequest; 46 RtlCopyMemory(&m_InterfaceType, Config->InterfaceType, sizeof(GUID)); 47 } 48 } 49 50 FxQueryInterface::~FxQueryInterface() 51 { 52 // 53 // Should not in any list 54 // 55 ASSERT(m_Entry.Next == NULL); 56 57 if (m_Interface != NULL && m_EmbeddedInterface == FALSE) { 58 FxPoolFree(m_Interface); 59 } 60 } 61 62 VOID 63 FxQueryInterface::_FormatIrp( 64 __in PIRP Irp, 65 __in const GUID* InterfaceGuid, 66 __out PINTERFACE Interface, 67 __in USHORT InterfaceSize, 68 __in USHORT InterfaceVersion, 69 __in_opt PVOID InterfaceSpecificData 70 ) 71 { 72 PIO_STACK_LOCATION stack; 73 74 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; 75 76 stack = IoGetNextIrpStackLocation(Irp); 77 78 stack->MajorFunction = IRP_MJ_PNP; 79 stack->MinorFunction = IRP_MN_QUERY_INTERFACE; 80 81 stack->Parameters.QueryInterface.Interface = Interface; 82 stack->Parameters.QueryInterface.InterfaceSpecificData = InterfaceSpecificData; 83 stack->Parameters.QueryInterface.Size = InterfaceSize; 84 stack->Parameters.QueryInterface.Version = InterfaceVersion; 85 stack->Parameters.QueryInterface.InterfaceType = InterfaceGuid; 86 } 87 88 _Must_inspect_result_ 89 NTSTATUS 90 FxQueryInterface::_QueryForInterface( 91 __in PDEVICE_OBJECT TopOfStack, 92 __in const GUID* InterfaceType, 93 __out PINTERFACE Interface, 94 __in USHORT Size, 95 __in USHORT Version, 96 __in_opt PVOID InterfaceSpecificData 97 ) 98 /*++ 99 100 Routine Description: 101 Send an IRP_MJPNP/IRP_MN_QUERY_INTERFACE irp to a device object and its 102 attached stack. 103 104 Arguments: 105 TargetDevice - device to send the query to. 106 107 InterfaceType - The type of interface to query for 108 109 Interface - The interface to fill out 110 111 Size - Size of Interface in bytes 112 113 Version - Version of the interface to be queried 114 115 InterfaceSpecificData - Addtional interface data to be queried 116 117 118 Return Value: 119 NTSTATUS as indicated by the handler of the QI with in the device stack, 120 STATUS_NOT_SUPPORTED if the QI is not handled. 121 122 --*/ 123 { 124 PIRP pIrp; 125 NTSTATUS status; 126 127 pIrp = IoAllocateIrp(TopOfStack->StackSize, FALSE); 128 129 if (pIrp != NULL) { 130 FxAutoIrp irp(pIrp); 131 132 _FormatIrp( 133 pIrp, 134 InterfaceType, 135 Interface, 136 Size, 137 Version, 138 InterfaceSpecificData 139 ); 140 141 status = irp.SendIrpSynchronously(TopOfStack); 142 } 143 else { 144 status = STATUS_INSUFFICIENT_RESOURCES; 145 } 146 147 return status; 148 } 149 150 VOID 151 FxQueryInterface::SetEmbedded( 152 __in PWDF_QUERY_INTERFACE_CONFIG Config, 153 __in PINTERFACE Interface 154 ) 155 /*++ 156 157 Routine Description: 158 Marks the structure as embedded and sets the configuration. This is used 159 for FxQueryInterface structs which are embedded in other structures because 160 at contruction time the Config is not available yet. 161 162 By marking as embedded, FxPkgPnp will not free the structure when it deletes 163 the query interface chain. 164 165 Arguments: 166 Config - how the interface behaves 167 168 Interface - the interface that is exported 169 170 Return Value: 171 None 172 173 --*/ 174 { 175 m_EmbeddedInterface = TRUE; 176 m_Interface = Interface; 177 178 m_SendQueryToParentStack = Config->SendQueryToParentStack; 179 m_ImportInterface = Config->ImportInterface; 180 m_ProcessRequest.m_Method = Config->EvtDeviceProcessQueryInterfaceRequest; 181 RtlCopyMemory(&m_InterfaceType, Config->InterfaceType, sizeof(GUID)); 182 } 183