1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7     fxldr.h
8 
9 Abstract:
10     This module contains private interfaces to the WDF loader.  This interface
11     is used by
12     a) the stub code in the client driver
13     b) the framework
14     c) the framework loader
15 --*/
16 #ifndef __FXLDR_H__
17 #define __FXLDR_H__
18 
19 #include <initguid.h>
20 #include <wdfldr.h>
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 #define WDF_COMPONENT_NAME(a) L#a
27 
28 //
29 // Bind info structures are aligned on memory allocation boundaries on 64-bit
30 // platforms, pointer boundaries on 32-bit.  The alignment __declspec didn't
31 // fix this for Itanium builds, so we must accomodate this.
32 //
33 // This "marker type" allows us to declare a leading boundary that will always
34 // have the proper alignment.  It may "waste" 4 to 8 bytes (0-4 to align the
35 // marker, and 4 more because the alignment isn't necessary, making the marker
36 // bigger than needed) on 32-bit, but that's not a large price to pay.
37 //
38 
39 typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _MARKER_TYPE {
40     UCHAR Pad[MEMORY_ALLOCATION_ALIGNMENT];
41 } MARKER_TYPE;
42 
43 typedef struct _LIBRARY_MODULE *PLIBRARY_MODULE;
44 typedef struct _WDF_LIBRARY_INFO *PWDF_LIBRARY_INFO;
45 
46 typedef
47 VOID
48 (*WDFFUNC)(
49     VOID
50     );
51 
52 typedef
53 _Must_inspect_result_
54 NTSTATUS
55 (*PFNLIBRARYCOMMISSION)(
56     VOID
57     );
58 
59 typedef
60 _Must_inspect_result_
61 NTSTATUS
62 (*PFNLIBRARYDECOMMISSION)(
63     VOID
64     );
65 
66 typedef
67 _Must_inspect_result_
68 NTSTATUS
69 (*PFNLIBRARYREGISTERCLIENT)(
70     __in PWDF_BIND_INFO             Info,
71     __deref_out   PWDF_COMPONENT_GLOBALS   * ComponentGlobals,
72     __deref_inout PVOID                    * Context
73     );
74 
75 typedef
76 _Must_inspect_result_
77 NTSTATUS
78 (*PFNLIBRARYUNREGISTERCLIENT)(
79     __in PWDF_BIND_INFO             Info,
80     __in PWDF_COMPONENT_GLOBALS     DriverGlobals
81     );
82 
83 typedef
84 _Must_inspect_result_
85 NTSTATUS
86 (*PWDF_REGISTER_LIBRARY)(
87     __in  PWDF_LIBRARY_INFO   LibraryInfo,
88     __in  PUNICODE_STRING     ServicePath,
89     __in  PCUNICODE_STRING    LibraryDeviceName
90     ) ;
91 
92 typedef
93 _Must_inspect_result_
94 NTSTATUS
95 (*PWDF_VERSION_BIND)(
96     __in  PDRIVER_OBJECT           DriverObject,
97     __in  PUNICODE_STRING          RegistryPath,
98     __in  PWDF_BIND_INFO           Info,
99     __out PWDF_COMPONENT_GLOBALS * Globals
100     ) ;
101 
102 typedef
103 NTSTATUS
104 (*PWDF_VERSION_UNBIND)(
105     __in PUNICODE_STRING         RegistryPath,
106     __in PWDF_BIND_INFO          Info,
107     __in PWDF_COMPONENT_GLOBALS  Globals
108     );
109 
110 #define WDF_LIBRARY_COMMISSION          LibraryCommission
111 #define WDF_LIBRARY_DECOMMISSION        LibraryDecommission
112 #define WDF_LIBRARY_REGISTER_CLIENT     LibraryRegisterClient
113 #define WDF_LIBRARY_UNREGISTER_CLIENT   LibraryUnregisterClient
114 
115 #define WDF_REGISTRY_DBGPRINT_ON   L"DbgPrintOn"
116 
117 
118 //
119 // Version container
120 //
121 typedef struct _WDF_VERSION {
122     WDF_MAJOR_VERSION  Major;
123     WDF_MINOR_VERSION  Minor;
124     WDF_BUILD_NUMBER   Build;
125 } WDF_VERSION;
126 
127 //
128 // WDF bind information structure.
129 //
130 typedef struct _WDF_BIND_INFO {
131     ULONG              Size;
132     PWCHAR             Component;
133     WDF_VERSION        Version;
134     ULONG              FuncCount;
135     __field_bcount(FuncCount*sizeof(WDFFUNC)) WDFFUNC* FuncTable;
136     PLIBRARY_MODULE    Module;     // Mgmt and diagnostic use only
137 } WDF_BIND_INFO, * PWDF_BIND_INFO;
138 
139 typedef struct _WDF_LIBRARY_INFO {
140     ULONG                             Size;
141     PFNLIBRARYCOMMISSION              LibraryCommission;
142     PFNLIBRARYDECOMMISSION            LibraryDecommission;
143     PFNLIBRARYREGISTERCLIENT          LibraryRegisterClient;
144     PFNLIBRARYUNREGISTERCLIENT        LibraryUnregisterClient;
145     WDF_VERSION                       Version;
146 } WDF_LIBRARY_INFO, *PWDF_LIBRARY_INFO;
147 
148 // {49215DFF-F5AC-4901-8588-AB3D540F6021}
149 DEFINE_GUID(GUID_WDF_LOADER_INTERFACE_STANDARD, \
150              0x49215dff, 0xf5ac, 0x4901, 0x85, 0x88, 0xab, 0x3d, 0x54, 0xf, 0x60, 0x21);
151 
152 typedef struct _WDF_LOADER_INTERFACE {
153     WDF_INTERFACE_HEADER        Header;
154     PWDF_REGISTER_LIBRARY       RegisterLibrary;
155     PWDF_VERSION_BIND           VersionBind;
156     PWDF_VERSION_UNBIND         VersionUnbind;
157     PWDF_LDR_DIAGNOSTICS_VALUE_BY_NAME_AS_ULONG DiagnosticsValueByNameAsULONG;
158 } WDF_LOADER_INTERFACE,  *PWDF_LOADER_INTERFACE;
159 
160 VOID
161 __inline
162 WDF_LOADER_INTERFACE_INIT(
163     PWDF_LOADER_INTERFACE Interface
164     )
165 {
166     RtlZeroMemory(Interface, sizeof(WDF_LOADER_INTERFACE));
167     Interface->Header.InterfaceSize = sizeof(WDF_LOADER_INTERFACE);
168     Interface->Header.InterfaceType = &GUID_WDF_LOADER_INTERFACE_STANDARD;
169 }
170 
171 //
172 // Client Driver information structure. This is used by loader when
173 // registering client with library to provide some additional info to
174 // library that is not already present in WDF_BIND_INFO (also passed to library
175 // during client registration)
176 //
177 typedef struct _CLIENT_INFO {
178     //
179     // Size of this structure
180     //
181     ULONG              Size;
182 
183     //
184     // registry service path of client driver
185     //
186     PUNICODE_STRING    RegistryPath;
187 
188 } CLIENT_INFO, *PCLIENT_INFO;
189 
190 //-----------------------------------------------------------------------------
191 // WDFLDR.SYS exported function prototype definitions
192 //-----------------------------------------------------------------------------
193 _Must_inspect_result_
194 NTSTATUS
195 WdfVersionBind(
196     __in    PDRIVER_OBJECT DriverObject,
197     __in    PUNICODE_STRING RegistryPath,
198     __inout PWDF_BIND_INFO BindInfo,
199     __out   PWDF_COMPONENT_GLOBALS* ComponentGlobals
200     );
201 
202 NTSTATUS
203 WdfVersionUnbind(
204     __in PUNICODE_STRING RegistryPath,
205     __in PWDF_BIND_INFO BindInfo,
206     __in PWDF_COMPONENT_GLOBALS ComponentGlobals
207     );
208 
209 _Must_inspect_result_
210 NTSTATUS
211 WdfRegisterLibrary(
212     __in PWDF_LIBRARY_INFO LibraryInfo,
213     __in PUNICODE_STRING ServicePath,
214     __in PCUNICODE_STRING LibraryDeviceName
215     );
216 
217 #ifdef ALLOC_PRAGMA
218 #pragma alloc_text (PAGE, WdfVersionBind)
219 #pragma alloc_text (PAGE, WdfVersionUnbind)
220 #pragma alloc_text (PAGE, WdfRegisterLibrary)
221 // #pragma alloc_text (PAGE, WdfRegisterClassLibrary)
222 #endif
223 
224 #ifdef __cplusplus
225 } // extern "C"
226 #endif
227 
228 //
229 // Event name: WdfCensusEvtLinkClientToCx
230 //
231 // Source:      WdfLdr
232 // Description: Written when a client is binding to a class extension.
233 //              WdfVersionBindClass which is called from the client's stub,
234 //              will load/reference the Cx and add it to the fx library's
235 //              list of clients. The client driver's class extension list is
236 //              also updated at that time, which is when this event is written.
237 //
238 // Frequency: Everytime a client driver binds to a class extension.
239 //
240 //
241 #define WDF_CENSUS_EVT_WRITE_LINK_CLIENT_TO_CX(TraceHandle, CxImageName, ClientImageName)        \
242             TraceLoggingWrite(TraceHandle,                                     \
243                 "WdfCensusEvtLinkClientToCx",                                  \
244                 WDF_TELEMETRY_EVT_KEYWORDS,                                    \
245                 TraceLoggingWideString(CxImageName,       "CxImageName"),      \
246                 TraceLoggingWideString(ClientImageName,   "ClientImageName"  ) \
247                 );
248 
249 #endif // __FXLDR_H__
250