ReactOS 0.4.16-dev-1946-g52006dd
wdfldr.c File Reference
#include "wdfloader.h"
Include dependency graph for wdfldr.c:

Go to the source code of this file.

Functions

 DEFINE_GUID (GUID_WDF_LOADER_INTERFACE_DIAGNOSTIC, 0x55905BA4, 0x1DD2, 0x45D3, 0xAB, 0xEA, 0xF7, 0xA8, 0x70, 0x11, 0xD6, 0x9F)
 
 DEFINE_GUID (GUID_WDF_LOADER_INTERFACE_CLASS_BIND, 0xFA4838CB, 0x1D08, 0x41E1, 0x8B, 0xA8, 0x71, 0x9C, 0xF8, 0x44, 0xEA, 0x74)
 
VOID NTAPI WdfLdrUnload (_In_ PDRIVER_OBJECT DriverObject)
 
NTSTATUS NTAPI DriverEntry (_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
 
NTSTATUS NTAPI WdfLdrDiagnosticsValueByNameAsULONG (_In_ PUNICODE_STRING ValueName, _Out_ PULONG Value)
 Retrieves an ULONG value from KMDF diagnostics registry key.
 
NTSTATUS NTAPI DllInitialize (_In_ PUNICODE_STRING RegistryPath)
 
VOID NTAPI DllUnload (VOID)
 
NTSTATUS NTAPI WdfLdrQueryInterface (_In_ PWDF_INTERFACE_HEADER LoaderInterface)
 
NTSTATUS NTAPI WdfRegisterLibrary (_In_ PWDF_LIBRARY_INFO LibraryInfo, _In_ PUNICODE_STRING ServicePath, _In_ PCUNICODE_STRING LibraryDeviceName)
 Register wdf01000 library.
 
NTSTATUS NTAPI WdfVersionBind (_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING ServicePath, _Inout_ PWDF_BIND_INFO BindInfo, _Out_ PWDF_COMPONENT_GLOBALS *ComponentGlobals)
 Bind client driver with framework.
 
NTSTATUS NTAPI WdfVersionUnbind (_In_ PUNICODE_STRING RegistryPath, _In_ PWDF_BIND_INFO BindInfo, _In_ PWDF_COMPONENT_GLOBALS ComponentGlobals)
 Unbind client driver from framework.
 
NTSTATUS NTAPI ReferenceVersion (_In_ PWDF_BIND_INFO Info, _Out_ PLIBRARY_MODULE *Module)
 Reference a WDF library version.
 
NTSTATUS NTAPI DereferenceVersion (_In_ PWDF_BIND_INFO Info, _In_opt_ PWDF_COMPONENT_GLOBALS Globals)
 Dereference a WDF library version.
 
NTSTATUS NTAPI WdfRegisterClassLibrary (_In_ PWDF_CLASS_LIBRARY_INFO ClassLibInfo, _In_ PUNICODE_STRING SourceString, _In_ PUNICODE_STRING ObjectName)
 Register class extension library (e.g., UCX)
 
NTSTATUS NTAPI WdfVersionBindClass (_In_ PWDF_BIND_INFO BindInfo, _Inout_ PWDF_COMPONENT_GLOBALS *ClientGlobals, _In_ PWDF_CLASS_BIND_INFO ClassBindInfo)
 
VOID NTAPI WdfVersionUnbindClass (_In_ PWDF_BIND_INFO BindInfo, _In_ PWDF_COMPONENT_GLOBALS Globals, _In_ PWDF_CLASS_BIND_INFO ClassBindInfo)
 

Variables

BOOLEAN gAlreadyInitialized = FALSE
 
BOOLEAN gAlreadyUnloaded = FALSE
 
WDFLDR_DIAGS WdfLdrDiags = { 0 }
 
WDF_LDR_GLOBALS WdfLdrGlobals
 

Function Documentation

◆ DEFINE_GUID() [1/2]

DEFINE_GUID ( GUID_WDF_LOADER_INTERFACE_CLASS_BIND  ,
0xFA4838CB  ,
0x1D08  ,
0x41E1  ,
0x8B  ,
0xA8  ,
0x71  ,
0x9C  ,
0xF8  ,
0x44  ,
0xEA  ,
0x74   
)

◆ DEFINE_GUID() [2/2]

DEFINE_GUID ( GUID_WDF_LOADER_INTERFACE_DIAGNOSTIC  ,
0x55905BA4  ,
0x1DD2  ,
0x45D3  ,
0xAB  ,
0xEA  ,
0xF7  ,
0xA8  ,
0x70  ,
0x11  ,
0xD6  ,
0x9F   
)

◆ DereferenceVersion()

NTSTATUS NTAPI DereferenceVersion ( _In_ PWDF_BIND_INFO  Info,
_In_opt_ PWDF_COMPONENT_GLOBALS  Globals 
)

Dereference a WDF library version.

Parameters
InfoBinding information
GlobalsComponent globals to clean up
Returns
NTSTATUS Success or failure status

Definition at line 630 of file wdfldr.c.

633{
635 NTSTATUS unregisterStatus = STATUS_SUCCESS;
636 PLIBRARY_MODULE pLibModule;
637
639
640 if (!Info || !Info->Module)
641 {
642 DPRINT_ERROR(("Invalid Info or Module is NULL\n"));
644 }
645
646 pLibModule = Info->Module;
647
648 // Unregister the client if we have globals
649 if (Globals && pLibModule->LibraryInfo &&
651 {
652 unregisterStatus = pLibModule->LibraryInfo->LibraryUnregisterClient(Info, Globals);
653 if (!NT_SUCCESS(unregisterStatus))
654 {
655 DPRINT_ERROR(("LibraryUnregisterClient failed with status 0x%x\n", unregisterStatus));
657 {
658 DPRINT_VERBOSE(("LibraryUnregisterClient failed\n"));
659 }
660 }
661 }
662
663 // Unlink the client
664 if (!LibraryUnlinkClient(pLibModule, Info))
665 {
666 DPRINT_ERROR(("LibraryUnlinkClient failed\n"));
668 {
669 DPRINT_VERBOSE(("LibraryUnlinkClient failed\n"));
670 }
671 }
672
673 // Release the reference
674 LibraryReleaseReference(pLibModule);
675
676 // Clear the module reference
677 Info->Module = NULL;
678
680 return NT_SUCCESS(unregisterStatus) ? status : unregisterStatus;
681}
LONG NTSTATUS
Definition: precomp.h:26
CLIPBOARD_GLOBALS Globals
Definition: clipbrd.c:13
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
VOID NTAPI LibraryReleaseReference(_In_ PLIBRARY_MODULE LibModule)
Release a reference to a library module.
Definition: library.c:280
BOOLEAN LibraryUnlinkClient(_In_ PLIBRARY_MODULE LibModule, _In_ PWDF_BIND_INFO BindInfo)
Definition: library.c:475
#define STATUS_SUCCESS
Definition: shellext.h:65
PWDF_LIBRARY_INFO LibraryInfo
Definition: wdfloader.h:119
UINT32 DiagFlags
Definition: wdfloader.h:91
PFNLIBRARYUNREGISTERCLIENT LibraryUnregisterClient
Definition: fxldr.h:144
Definition: ps.c:97
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
WDFLDR_DIAGS WdfLdrDiags
Definition: wdfldr.c:27
#define DIAGFLAG_ENABLED
Definition: wdfloader.h:79
#define DPRINT_TRACE_ENTRY()
Definition: wdfloader.h:47
#define DPRINT_TRACE_EXIT()
Definition: wdfloader.h:54
#define DPRINT_ERROR(_x_)
Definition: wdfloader.h:39
#define DPRINT_VERBOSE(_x_)
Definition: wdfloader.h:31

◆ DllInitialize()

NTSTATUS NTAPI DllInitialize ( _In_ PUNICODE_STRING  RegistryPath)

Definition at line 105 of file wdfldr.c.

107{
109 UNICODE_STRING dbgPrintOn = RTL_CONSTANT_STRING(L"DbgPrintOn");
110 UNICODE_STRING verboseLogging = RTL_CONSTANT_STRING(L"VerboseLogging");
111 UNICODE_STRING traceEntry = RTL_CONSTANT_STRING(L"TraceEntry");
112 ULONG diagValue = 0;
113
115
117 {
118 return STATUS_SUCCESS;
119 }
120
124
127 if (!NT_SUCCESS(status))
128 {
129 DPRINT_ERROR(("ExInitializeResourceLite failed with Status 0x%x\n", status));
130 return status;
131 }
132
133#if 0
134 /* Force debugging everything */
138#endif
139 status = WdfLdrDiagnosticsValueByNameAsULONG(&dbgPrintOn, &diagValue);
140 if (NT_SUCCESS(status) && diagValue != 0)
141 {
143 }
144
145 status = WdfLdrDiagnosticsValueByNameAsULONG(&verboseLogging, &diagValue);
146 if (NT_SUCCESS(status) && diagValue != 0)
147 {
149 }
150
151 status = WdfLdrDiagnosticsValueByNameAsULONG(&traceEntry, &diagValue);
152 if (NT_SUCCESS(status) && diagValue != 0)
153 {
155 }
156
158 if (NT_SUCCESS(status))
159 {
161 DPRINT(("Initialized WdfLdr - OS Version %d.%d.%d\n",
165 }
166 else
167 {
168 DPRINT_ERROR(("AuxKlibInitialize failed with Status 0x%x\n", status));
171 return status;
172 }
173
174
175 DPRINT(("WDF Loader initialization completed successfully\n"));
176 return STATUS_SUCCESS;
177}
NTSTATUS NTAPI AuxKlibInitialize(VOID)
Definition: aux_klib.c:26
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
NTSTATUS NTAPI RtlGetVersion(IN OUT PRTL_OSVERSIONINFOW lpVersionInformation)
Definition: version.c:182
#define L(x)
Definition: resources.c:13
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define ExDeleteResourceLite(res)
Definition: env_spec_w32.h:647
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
#define DPRINT
Definition: sndvol32.h:73
ULONG dwMajorVersion
Definition: rtltypes.h:270
ULONG dwMinorVersion
Definition: rtltypes.h:271
ULONG dwBuildNumber
Definition: rtltypes.h:272
ERESOURCE LoadedModulesListLock
Definition: wdfloader.h:72
LIST_ENTRY LoadedModulesList
Definition: wdfloader.h:73
OSVERSIONINFOEXW OsVersion
Definition: wdfloader.h:71
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
BOOLEAN gAlreadyInitialized
Definition: wdfldr.c:21
NTSTATUS NTAPI WdfLdrDiagnosticsValueByNameAsULONG(_In_ PUNICODE_STRING ValueName, _Out_ PULONG Value)
Retrieves an ULONG value from KMDF diagnostics registry key.
Definition: wdfldr.c:54
WDF_LDR_GLOBALS WdfLdrGlobals
Definition: wdfldr.c:28
#define DIAGFLAG_LOG_WARNINGS
Definition: wdfloader.h:84
#define DIAGFLAG_TRACE_FUNCTION_ENTRY
Definition: wdfloader.h:81
#define DIAGFLAG_TRACE_FUNCTION_EXIT
Definition: wdfloader.h:82
#define DIAGFLAG_VERBOSE_LOGGING
Definition: wdfloader.h:80
#define DIAGFLAG_LOG_ERRORS
Definition: wdfloader.h:83

Referenced by DriverEntry().

◆ DllUnload()

VOID NTAPI DllUnload ( VOID  )

Definition at line 182 of file wdfldr.c.

183{
185 {
186 return;
187 }
188
191
192 //
193 // Unload all loaded libraries - CRITICAL: proper cleanup sequence
194 //
196 {
199
200 DPRINT(("Unloading module %p (%wZ)\n", module, &module->ServicePath));
201
202 InitializeListHead(&module->LibraryListEntry);
204
205 if (module->LibraryInfo)
206 {
208 }
209 else
210 {
213 }
214 }
215
218}
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
uint32_t entry
Definition: isohybrid.c:63
VOID LibraryClose(_Inout_ PLIBRARY_MODULE LibModule)
Dereferences KMDF library's device object.
Definition: library.c:195
VOID LibraryFree(_In_ PLIBRARY_MODULE LibModule)
Definition: library.c:13
PLIST_ENTRY LibraryUnloadClasses(_In_ PLIBRARY_MODULE LibModule)
Definition: class.c:636
Definition: typedefs.h:120
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
VOID LibraryUnload()
BOOLEAN gAlreadyUnloaded
Definition: wdfldr.c:22

◆ DriverEntry()

NTSTATUS NTAPI DriverEntry ( _In_ PDRIVER_OBJECT  DriverObject,
_In_ PUNICODE_STRING  RegistryPath 
)

Definition at line 41 of file wdfldr.c.

44{
45 DriverObject->DriverUnload = WdfLdrUnload;
47}
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
NTSTATUS NTAPI DllInitialize(_In_ PUNICODE_STRING RegistryPath)
Definition: wdfldr.c:105
VOID NTAPI WdfLdrUnload(_In_ PDRIVER_OBJECT DriverObject)
Definition: wdfldr.c:33

◆ ReferenceVersion()

NTSTATUS NTAPI ReferenceVersion ( _In_ PWDF_BIND_INFO  Info,
_Out_ PLIBRARY_MODULE Module 
)

Reference a WDF library version.

Parameters
InfoBinding information containing version details
ModulePointer to receive the library module
Returns
NTSTATUS Success or failure status

Definition at line 576 of file wdfldr.c.

579{
581 UNICODE_STRING libraryServicePath = { 0 };
582
584
585 if (!Info || !Module)
586 {
587 DPRINT_ERROR(("Invalid parameters: Info=%p, Module=%p\n", Info, Module));
589 }
590
591 *Module = NULL;
592 /* Multiple ways to find the correct library - once again UCX stresses this extensively */
593 status = GetVersionServicePath(Info, &libraryServicePath);
594 if (!NT_SUCCESS(status))
595 {
596 DPRINT_ERROR(("GetVersionServicePath failed with status 0x%x\n", status));
597 goto Exit;
598 }
599
600 status = LibraryFindOrLoad(&libraryServicePath, Module);
601 if (NT_SUCCESS(status))
602 {
603 Info->Module = *Module;
604 DPRINT_VERBOSE(("Referenced version for library %wZ\n", &libraryServicePath));
605 }
606 else
607 {
608 DPRINT_ERROR(("LibraryFindOrLoad failed with status 0x%x\n", status));
609 }
610
611Exit:
612 if (libraryServicePath.Buffer)
613 {
614 RtlFreeUnicodeString(&libraryServicePath);
615 }
616
618 return status;
619}
NTSTATUS LibraryFindOrLoad(_In_ PCUNICODE_STRING ServicePath, _Out_ PLIBRARY_MODULE *LibModule)
Definition: library.c:206
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSTATUS GetVersionServicePath(_In_ PWDF_BIND_INFO BindInfo, _Out_ PUNICODE_STRING ServicePath)
Get service path from bind info and registry.
Definition: registry.c:141
static void Exit(void)
Definition: sock.c:1330

Referenced by WdfVersionBind().

◆ WdfLdrDiagnosticsValueByNameAsULONG()

NTSTATUS NTAPI WdfLdrDiagnosticsValueByNameAsULONG ( _In_ PUNICODE_STRING  ValueName,
_Out_ PULONG  Value 
)

Retrieves an ULONG value from KMDF diagnostics registry key.

Definition at line 54 of file wdfldr.c.

57{
60
61 if (ValueName == NULL || Value == NULL)
62 {
63 __DBGPRINT(("ERROR: Invalid Input Parameter\n"));
65 }
66
67 *Value = 0; // for compatibility
68
70 {
71 __DBGPRINT(("Not at PASSIVE_LEVEL\n"));
73 }
74
75 // open framework diagnostics key
76 OBJECT_ATTRIBUTES attributes;
77 static UNICODE_STRING diagPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Wdf\\Kmdf\\Diagnostics");
78
80 &diagPath,
82 NULL,
83 NULL);
84
85 status = ZwOpenKey(&keyHandle, KEY_QUERY_VALUE, &attributes);
86
87 if (NT_SUCCESS(status))
88 {
90
91 __DBGPRINT(("Status %x, value 0x%x\n", status, *Value));
92
94 }
95 else
96 {
97 __DBGPRINT(("ERROR: ZwOpenKey failed with Status 0x%x\n", status));
98 }
99
100 return status;
101}
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
WDFKEY keyHandle
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define KEY_QUERY_VALUE
Definition: nt_native.h:1019
NTSTATUS FxLdrQueryUlong(_In_ HANDLE KeyHandle, _In_ PUNICODE_STRING ValueName, _Out_ PULONG Value)
Definition: registry.c:231
#define __DBGPRINT(_x_)
Definition: wdfloader.h:62
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

Referenced by DllInitialize(), DriverEntry(), and WdfLdrQueryInterface().

◆ WdfLdrQueryInterface()

NTSTATUS NTAPI WdfLdrQueryInterface ( _In_ PWDF_INTERFACE_HEADER  LoaderInterface)

Definition at line 222 of file wdfldr.c.

224{
226
227 if (LoaderInterface == NULL)
228 {
229 DPRINT_ERROR(("LoaderInterface is NULL\n"));
231 }
232
233 if (LoaderInterface->InterfaceType == NULL)
234 {
235 DPRINT_ERROR(("InterfaceType is NULL\n"));
237 }
238
239 if (IsEqualGUID(LoaderInterface->InterfaceType, &GUID_WDF_LOADER_INTERFACE_STANDARD))
240 {
241 if (LoaderInterface->InterfaceSize < sizeof(WDF_LOADER_INTERFACE))
242 {
243 DPRINT_ERROR(("Interface size too small: %u, expected: %u\n",
244 LoaderInterface->InterfaceSize, sizeof(WDF_LOADER_INTERFACE)));
246 }
247
248 PWDF_LOADER_INTERFACE lInterface = (PWDF_LOADER_INTERFACE)LoaderInterface;
249
251 lInterface->VersionBind = WdfVersionBind;
252 lInterface->VersionUnbind = WdfVersionUnbind;
254
255 DPRINT_VERBOSE(("Provided standard WDF loader interface\n"));
256 return STATUS_SUCCESS;
257 }
258 else if (IsEqualGUID(LoaderInterface->InterfaceType, &GUID_WDF_LOADER_INTERFACE_DIAGNOSTIC))
259 {
260 if (LoaderInterface->InterfaceSize < sizeof(WDF_LOADER_INTERFACE_DIAGNOSTIC))
261 {
262 DPRINT_ERROR(("Diagnostic interface size too small: %u, expected: %u\n",
263 LoaderInterface->InterfaceSize, sizeof(WDF_LOADER_INTERFACE_DIAGNOSTIC)));
265 }
266
268 (PWDF_LOADER_INTERFACE_DIAGNOSTIC)LoaderInterface;
269
271
272 DPRINT_VERBOSE(("Provided diagnostic interface\n"));
273 return STATUS_SUCCESS;
274 }
275 else if (IsEqualGUID(LoaderInterface->InterfaceType, &GUID_WDF_LOADER_INTERFACE_CLASS_BIND))
276 {
277 if (LoaderInterface->InterfaceSize < sizeof(WDF_LOADER_INTERFACE_CLASS_BIND))
278 {
279 DPRINT_ERROR(("Class bind interface size too small: %u, expected: %u\n",
280 LoaderInterface->InterfaceSize, sizeof(WDF_LOADER_INTERFACE_CLASS_BIND)));
281
283 }
284
286 (PWDF_LOADER_INTERFACE_CLASS_BIND)LoaderInterface;
287
288 lInterface->ClassBind = WdfVersionBindClass;
290
291 DPRINT_VERBOSE(("Provided class bind interface\n"));
292 return STATUS_SUCCESS;
293 }
294
295 DPRINT_ERROR(("Unknown interface type requested\n"));
297 return STATUS_NOINTERFACE;
298}
struct _WDF_LOADER_INTERFACE * PWDF_LOADER_INTERFACE
#define STATUS_NOINTERFACE
Definition: ntstatus.h:937
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
PWDF_CLASS_UNBIND ClassUnbind
Definition: wdfloader.h:152
PWDF_LDR_DIAGNOSTICS_VALUE_BY_NAME_AS_ULONG DiagnosticsValueByNameAsULONG
Definition: wdfloader.h:146
PWDF_REGISTER_LIBRARY RegisterLibrary
Definition: fxldr.h:154
PWDF_VERSION_UNBIND VersionUnbind
Definition: fxldr.h:156
PWDF_LDR_DIAGNOSTICS_VALUE_BY_NAME_AS_ULONG DiagnosticsValueByNameAsULONG
Definition: fxldr.h:157
PWDF_VERSION_BIND VersionBind
Definition: fxldr.h:155
NTSTATUS NTAPI WdfVersionBind(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING ServicePath, _Inout_ PWDF_BIND_INFO BindInfo, _Out_ PWDF_COMPONENT_GLOBALS *ComponentGlobals)
Bind client driver with framework.
Definition: wdfldr.c:411
VOID NTAPI WdfVersionUnbindClass(_In_ PWDF_BIND_INFO BindInfo, _In_ PWDF_COMPONENT_GLOBALS Globals, _In_ PWDF_CLASS_BIND_INFO ClassBindInfo)
Definition: wdfldr.c:850
NTSTATUS NTAPI WdfRegisterLibrary(_In_ PWDF_LIBRARY_INFO LibraryInfo, _In_ PUNICODE_STRING ServicePath, _In_ PCUNICODE_STRING LibraryDeviceName)
Register wdf01000 library.
Definition: wdfldr.c:311
NTSTATUS NTAPI WdfVersionBindClass(_In_ PWDF_BIND_INFO BindInfo, _Inout_ PWDF_COMPONENT_GLOBALS *ClientGlobals, _In_ PWDF_CLASS_BIND_INFO ClassBindInfo)
Definition: wdfldr.c:794
NTSTATUS NTAPI WdfVersionUnbind(_In_ PUNICODE_STRING RegistryPath, _In_ PWDF_BIND_INFO BindInfo, _In_ PWDF_COMPONENT_GLOBALS ComponentGlobals)
Unbind client driver from framework.
Definition: wdfldr.c:519
struct _WDF_LOADER_INTERFACE_CLASS_BIND * PWDF_LOADER_INTERFACE_CLASS_BIND
struct _WDF_LOADER_INTERFACE_DIAGNOSTIC * PWDF_LOADER_INTERFACE_DIAGNOSTIC

◆ WdfLdrUnload()

VOID NTAPI WdfLdrUnload ( _In_ PDRIVER_OBJECT  DriverObject)

Definition at line 33 of file wdfldr.c.

35{
36 DllUnload();
37}
ULONG NTAPI DllUnload()
Definition: dll.cpp:28

Referenced by DriverEntry().

◆ WdfRegisterClassLibrary()

NTSTATUS NTAPI WdfRegisterClassLibrary ( _In_ PWDF_CLASS_LIBRARY_INFO  ClassLibInfo,
_In_ PUNICODE_STRING  SourceString,
_In_ PUNICODE_STRING  ObjectName 
)

Register class extension library (e.g., UCX)

See also
http://redplait.blogspot.com/2013/03/ucxfunctionsidc.html
Parameters
ClassLibInfoClass library information
SourceStringService name of the class library
ObjectNameDevice object name
Returns
STATUS_SUCCESS on success, error code otherwise

Definition at line 696 of file wdfldr.c.

700{
702 PCLASS_MODULE pClassModule;
703 PFN_CLASS_LIBRARY_INIT fnClassLibInit;
704 PLIBRARY_MODULE libModule;
705
706 PAGED_CODE();
707
710
711 // First, try to find an existing class module
712 pClassModule = FindClassByServiceNameLocked(SourceString, &libModule);
713
714 if (pClassModule)
715 {
716 /* Another behavior you can observe by running UCX */
717 pClassModule->ClassLibraryInfo = ClassLibInfo;
718 }
719 else
720 {
722 if (!NT_SUCCESS(status))
723 {
725 {
726 DPRINT_VERBOSE(("No library found for class module %wZ, status 0x%x\n",
728 }
729
730 /*
731 * This ensures class modules are always searchable through library class lists
732 * The behavior here can be observed from UCX
733 */
735 {
737 libModule = CONTAINING_RECORD(entry, LIBRARY_MODULE, LibraryListEntry);
738 DPRINT(("Using default WDF library %wZ for class module %wZ\n",
739 &libModule->ServicePath, SourceString));
740 }
741 else
742 {
743 libModule = NULL;
744 }
745 }
746
747 pClassModule = ClassCreate(ClassLibInfo, libModule, SourceString);
748 if (pClassModule)
749 {
750 if (libModule)
751 LibraryAddToClassListLocked(libModule, pClassModule);
752 ClassAddReference(pClassModule);
753 }
754 }
756
757 if (!pClassModule)
758 {
760 }
761
762 __DBGPRINT(("Class Library (%p)\n", pClassModule));
763
764 status = ClassOpen(pClassModule, ObjectName);
765
766 if (!NT_SUCCESS(status))
767 {
768 __DBGPRINT(("ERROR: ClassOpen(%wZ) failed, status 0x%x\n", ObjectName, status));
769 ClassRemoveFromLibraryList(pClassModule);
770 return status;
771 }
772
773 fnClassLibInit = pClassModule->ClassLibraryInfo->ClassLibraryInitialize;
774 if (fnClassLibInit)
775 {
776 status = fnClassLibInit();
777 if (!NT_SUCCESS(status))
778 {
779 __DBGPRINT(("ERROR: WdfRegisterClassLibrary: ClassLibraryInitialize failed, status 0x%x\n", status));
780 pClassModule->ClassLibraryInfo = NULL;
781 ClassClose(pClassModule);
782 }
783 }
784
785 /* Classes always stay loaded after registration - (UCX, NDIS) */
786 return status;
787}
#define PAGED_CODE()
static DRIVER_DISPATCH ClassClose
Definition: kbdclass.c:19
static DRIVER_DISPATCH ClassCreate
Definition: kbdclass.c:18
_Out_ _Inout_ POEM_STRING _In_ PCUNICODE_STRING SourceString
Definition: rtlfuncs.h:1957
VOID ClassRemoveFromLibraryList(_In_ PCLASS_MODULE ClassModule)
Definition: class.c:692
PCLASS_MODULE FindClassByServiceNameLocked(_In_ PUNICODE_STRING ServicePath, _Out_ PLIBRARY_MODULE *LibModule)
Definition: class.c:585
PLIST_ENTRY LibraryAddToClassListLocked(_In_ PLIBRARY_MODULE LibModule, _In_ PCLASS_MODULE ClassModule)
Definition: class.c:673
NTSTATUS ClassOpen(_Inout_ PCLASS_MODULE ClassModule, _In_ PUNICODE_STRING ObjectName)
Definition: class.c:29
VOID NTAPI ClassAddReference(_In_ PCLASS_MODULE ClassModule)
Definition: class.c:761
VOID FxLdrAcquireLoadedModuleLock(VOID)
Definition: common.c:13
VOID FxLdrReleaseLoadedModuleLock(VOID)
Definition: common.c:20
PWDF_CLASS_LIBRARY_INFO ClassLibraryInfo
Definition: wdfloader.h:173
UNICODE_STRING ServicePath
Definition: wdfloader.h:113
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
PFN_CLASS_LIBRARY_INIT ClassLibraryInitialize
Definition: wdfldr.h:110
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS(NTAPI * PFN_CLASS_LIBRARY_INIT)(VOID)
Definition: wdfldr.h:34
NTSTATUS NTAPI FindModuleByClientService(_In_ PUNICODE_STRING RegistryPath, _Out_ PLIBRARY_MODULE *Library)
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:64

◆ WdfRegisterLibrary()

NTSTATUS NTAPI WdfRegisterLibrary ( _In_ PWDF_LIBRARY_INFO  LibraryInfo,
_In_ PUNICODE_STRING  ServicePath,
_In_ PCUNICODE_STRING  LibraryDeviceName 
)

Register wdf01000 library.

Parameters
LibraryInfoInformation about the library being registered
ServicePathService path in registry
LibraryDeviceNameKMDF device name
Returns
STATUS_SUCCESS on success, error code otherwise

Definition at line 311 of file wdfldr.c.

315{
317 PLIBRARY_MODULE pLibModule;
318
319 PAGED_CODE();
320
323
324 if (pLibModule != NULL)
325 {
326 // This happens when a driver which uses KMDF library is loaded before the library itself.
327 // In such case, LibraryCreate(NULL, ...) was called in from WdfVersionBind
328
329 ASSERT(pLibModule->ImplicitlyLoaded == TRUE);
330 ASSERT(pLibModule->LibraryInfo == NULL);
331
332 pLibModule->Version = LibraryInfo->Version;
333 pLibModule->LibraryInfo = LibraryInfo;
334
335 status = GetImageInfo(&pLibModule->ImageName,
336 &pLibModule->ImageAddress,
337 &pLibModule->ImageSize);
338 if (!NT_SUCCESS(status))
339 {
340 __DBGPRINT(("ERROR: GetImageInfo(%wZ) failed with status 0x%x\n",
341 pLibModule->ImageName, status));
342 }
343 }
344 else
345 {
346 status = LibraryCreate(LibraryInfo, ServicePath, &pLibModule);
347 }
348
349 // Reference the library while we're working on it
350 if (pLibModule)
351 {
353 }
354
356
357 if (!pLibModule)
358 {
359 __DBGPRINT(("WdfRegisterLibrary: LibraryCreate(%wZ) failed, status %X\n",
361 return status;
362 }
363
364 __DBGPRINT(("Registering library(%p) %wZ\n", pLibModule, &pLibModule->ImageName));
365
366 // WdfRegisterLibrary is called from the library itself so we're sure it is loaded
367 // Now reference the library's device object
368 status = LibraryOpen(pLibModule, LibraryDeviceName);
369 if (!NT_SUCCESS(status))
370 {
371 __DBGPRINT(("ERROR: LibraryOpen(%wZ) failed with status %x\n", LibraryDeviceName, status));
372 goto Failure;
373 }
374
375 // Now call the custom library callback
376 status = pLibModule->LibraryInfo->LibraryCommission();
377 if (!NT_SUCCESS(status))
378 {
379 __DBGPRINT(("ERROR: WdfRegisterLibrary: LibraryCommission failed status 0x%X\n", status));
380 goto Failure;
381 }
382
383 // The work is finished
384 LibraryDereference(pLibModule);
385 return status;
386
387Failure:
388 // Dereference two times - the library should be cleaned up then
389 // Setting LibraryInfo to NULL so ZwUnloadDriver is not called
390 pLibModule->LibraryInfo = NULL;
391 LibraryDereference(pLibModule);
392
393 // If the library was created in WdfVersionBind, it will be dereferenced there
394 if (pLibModule->ImplicitlyLoaded)
395 LibraryDereference(pLibModule);
396 return status;
397}
#define InterlockedIncrement
Definition: armddk.h:53
NTSTATUS LibraryOpen(_Inout_ PLIBRARY_MODULE LibModule, _In_ PCUNICODE_STRING ObjectName)
Opens KMDF library's driver object by its name and fills some library structure data.
Definition: library.c:167
VOID LibraryDereference(_In_ PLIBRARY_MODULE LibModule)
Definition: library.c:300
_In_ PCUNICODE_STRING ServicePath
Definition: library.c:55
#define ASSERT(a)
Definition: mode.c:44
NTSTATUS GetImageInfo(_In_ PCUNICODE_STRING ImageName, _Out_ PVOID *ImageBase, _Out_ PULONG ImageSize)
Definition: common.c:182
PVOID ImageAddress
Definition: wdfloader.h:115
LONG LibraryRefCount
Definition: wdfloader.h:108
BOOLEAN ImplicitlyLoaded
Definition: wdfloader.h:112
UNICODE_STRING ImageName
Definition: wdfloader.h:114
WDF_VERSION Version
Definition: wdfloader.h:122
PFNLIBRARYCOMMISSION LibraryCommission
Definition: fxldr.h:141
NTSTATUS LibraryCreate(_In_opt_ PWDF_LIBRARY_INFO LibraryInfo, _In_ PCUNICODE_STRING ServicePath, _Out_ PLIBRARY_MODULE *OutLibraryModule)
PLIBRARY_MODULE FindLibraryByServicePathLocked(_In_ PCUNICODE_STRING ServicePath)

Referenced by DriverEntry(), and WdfLdrQueryInterface().

◆ WdfVersionBind()

NTSTATUS NTAPI WdfVersionBind ( _In_ PDRIVER_OBJECT  DriverObject,
_In_ PUNICODE_STRING  ServicePath,
_Inout_ PWDF_BIND_INFO  BindInfo,
_Out_ PWDF_COMPONENT_GLOBALS ComponentGlobals 
)

Bind client driver with framework.

Parameters
DriverObjectDriver object
ServicePathRegistry service path
BindInfoClient driver bind information
ComponentGlobalsClient driver global settings
Returns
STATUS_SUCCESS on success, error code otherwise

Definition at line 411 of file wdfldr.c.

416{
418 PLIBRARY_MODULE pLibModule = NULL;
419 PCLIENT_MODULE clientModule = NULL;
420 UNICODE_STRING libraryServicePath = { 0 };
421 CLIENT_INFO clientInfo;
423
425 PAGED_CODE();
426
428
429 if (ComponentGlobals == NULL || BindInfo == NULL || BindInfo->FuncTable == NULL)
430 {
431 DPRINT_ERROR(("Invalid parameters: ComponentGlobals=%p, BindInfo=%p\n",
432 ComponentGlobals, BindInfo));
434 goto Exit;
435 }
436
437 *ComponentGlobals = NULL;
438
439 status = ReferenceVersion(BindInfo, &pLibModule);
440 if (!NT_SUCCESS(status))
441 {
442 DPRINT_ERROR(("ReferenceVersion failed with status 0x%x\n", status));
443 goto Exit;
444 }
445
446 DPRINT_VERBOSE(("Referenced library version for %wZ\n", &pLibModule->ServicePath));
447
448
449 clientInfo.Size = sizeof(CLIENT_INFO);
450 clientInfo.RegistryPath = ServicePath;
451
452 status = LibraryLinkInClient(pLibModule, ServicePath, BindInfo, &clientInfo, &clientModule);
453 if (!NT_SUCCESS(status))
454 {
455 DPRINT_ERROR(("LibraryLinkInClient failed with status 0x%x\n", status));
456 LibraryDereference(pLibModule);
457 goto Exit;
458 }
459
460 /* Dereference the library as LibraryLinkInClient has its own reference */
461 LibraryDereference(pLibModule);
462
463 BindInfo->Module = pLibModule;
464
465 if (!pLibModule->LibraryInfo)
466 {
467 DPRINT_ERROR(("Library not properly initialized - LibraryInfo is NULL\n"));
469 goto Cleanup;
470 }
471
472 if (!pLibModule->LibraryInfo->LibraryRegisterClient)
473 {
474 DPRINT_ERROR(("Library missing LibraryRegisterClient function pointer\n"));
476 goto Cleanup;
477 }
478
479 DPRINT_VERBOSE(("Calling LibraryRegisterClient at %p for library %wZ\n",
480 pLibModule->LibraryInfo->LibraryRegisterClient, &pLibModule->ServicePath));
481
482 status = pLibModule->LibraryInfo->LibraryRegisterClient(BindInfo, ComponentGlobals, &context);
483 if (NT_SUCCESS(status))
484 {
485 clientModule->Globals = *ComponentGlobals;
486 clientModule->Context = context; // Pointer to FX_DRIVER_GLOBALS
487
488 DPRINT(("Successfully bound client %wZ to library %wZ\n",
489 ServicePath, &libraryServicePath));
490 goto Exit;
491 }
492
493 DPRINT_ERROR(("LibraryRegisterClient failed with status 0x%x\n", status));
494
495Cleanup:
496 WdfVersionUnbind(ServicePath, BindInfo, *ComponentGlobals);
497
498Exit:
499 if (libraryServicePath.Buffer)
500 {
501 RtlFreeUnicodeString(&libraryServicePath);
502 }
503
505 return status;
506}
static const WCHAR Cleanup[]
Definition: register.c:80
struct _CLIENT_INFO CLIENT_INFO
NTSTATUS LibraryLinkInClient(_In_ PLIBRARY_MODULE LibModule, _In_ PUNICODE_STRING ServicePath, _In_ PWDF_BIND_INFO BindInfo, _In_ PVOID Context, _Out_ PCLIENT_MODULE *OutClientModule)
Create client module and add it to library client list.
Definition: library.c:404
PUNICODE_STRING RegistryPath
Definition: fxldr.h:186
ULONG Size
Definition: fxldr.h:181
PLIBRARY_MODULE Module
Definition: fxldr.h:136
PFNLIBRARYREGISTERCLIENT LibraryRegisterClient
Definition: fxldr.h:143
Definition: http.c:7252
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
WDF_BIND_INFO BindInfo
NTSTATUS NTAPI ReferenceVersion(_In_ PWDF_BIND_INFO Info, _Out_ PLIBRARY_MODULE *Module)
Reference a WDF library version.
Definition: wdfldr.c:576

Referenced by FxDriverEntry(), and WdfLdrQueryInterface().

◆ WdfVersionBindClass()

NTSTATUS NTAPI WdfVersionBindClass ( _In_ PWDF_BIND_INFO  BindInfo,
_Inout_ PWDF_COMPONENT_GLOBALS ClientGlobals,
_In_ PWDF_CLASS_BIND_INFO  ClassBindInfo 
)

Definition at line 794 of file wdfldr.c.

798{
799 PCLASS_CLIENT_MODULE pClassClientModule = NULL;
801 PCLASS_MODULE pClassModule = NULL;
802
804
805 pClassClientModule = ClassClientCreate();
806 if (pClassClientModule == NULL)
807 {
808 DPRINT_ERROR(("Could not create class client struct\n"));
810 }
811
812 status = ReferenceClassVersion(ClassBindInfo, BindInfo, &pClassModule);
813 if (!NT_SUCCESS(status))
814 {
815 ExFreePoolWithTag(pClassClientModule, WDFLDR_TAG);
816 return status;
817 }
818
819 status = ClassLinkInClient(pClassModule, ClassBindInfo, BindInfo, pClassClientModule);
820 if (!NT_SUCCESS(status))
821 {
822 DPRINT_ERROR(("ClassLinkInClient failed 0x%x\n", status));
823 }
824 else
825 {
826 // Success - clear pClassClientModule so we don't free it
827 pClassClientModule = NULL;
828 status = pClassModule->ClassLibraryInfo->ClassLibraryBindClient(ClassBindInfo, ClientGlobals);
829 if (NT_SUCCESS(status))
830 {
832 return status;
833 }
834
835 DPRINT_ERROR(("ClassLibraryBindClient failed, status 0x%x\n", status));
836 }
837
838 if (pClassModule != NULL)
839 DereferenceClassVersion(ClassBindInfo, BindInfo, *ClientGlobals);
840 if (pClassClientModule != NULL)
841 ExFreePoolWithTag(pClassClientModule, WDFLDR_TAG);
842
844 return status;
845}
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
PCLASS_CLIENT_MODULE ClassClientCreate()
Definition: class.c:137
NTSTATUS ReferenceClassVersion(_In_ PWDF_CLASS_BIND_INFO ClassBindInfo, _In_ PWDF_BIND_INFO BindInfo, _Out_ PCLASS_MODULE *ClassModule)
Definition: class.c:423
VOID DereferenceClassVersion(_In_ PWDF_CLASS_BIND_INFO ClassBindInfo, _In_ PWDF_BIND_INFO BindInfo, _In_ PWDF_COMPONENT_GLOBALS Globals)
Definition: class.c:790
NTSTATUS ClassLinkInClient(_In_ PCLASS_MODULE ClassModule, _In_ PWDF_CLASS_BIND_INFO ClassBindInfo, _In_ PWDF_BIND_INFO BindInfo, _Out_ PCLASS_CLIENT_MODULE ClassClientModule)
Definition: class.c:170
PFN_CLASS_LIBRARY_BIND_CLIENT ClassLibraryBindClient
Definition: wdfldr.h:112
#define WDFLDR_TAG
Definition: wdfloader.h:17

Referenced by WdfLdrQueryInterface().

◆ WdfVersionUnbind()

NTSTATUS NTAPI WdfVersionUnbind ( _In_ PUNICODE_STRING  RegistryPath,
_In_ PWDF_BIND_INFO  BindInfo,
_In_ PWDF_COMPONENT_GLOBALS  ComponentGlobals 
)

Unbind client driver from framework.

Parameters
RegistryPathRegistry path
BindInfoClient driver bind information
ComponentGlobalsClient driver global settings
Returns
STATUS_SUCCESS on success, error code otherwise

Definition at line 519 of file wdfldr.c.

523{
524 PLIBRARY_MODULE pLibModule;
526 NTSTATUS unregisterStatus = STATUS_SUCCESS;
527
528 PAGED_CODE();
530
531 if (!BindInfo || !BindInfo->Module)
532 {
533 DPRINT_ERROR(("Invalid BindInfo or Module is NULL\n"));
535 goto Exit;
536 }
537
538 pLibModule = BindInfo->Module;
539
540 /* Reference the module while working on it and unregister if globals are valid. */
541 LibraryReference(pLibModule);
542 if (ComponentGlobals != NULL && pLibModule->LibraryInfo &&
544 {
545 unregisterStatus = pLibModule->LibraryInfo->LibraryUnregisterClient(BindInfo, ComponentGlobals);
546 if (!NT_SUCCESS(unregisterStatus))
547 {
548 DPRINT_ERROR(("LibraryUnregisterClient failed with status 0x%x\n", unregisterStatus));
549 }
550 }
551
552 if (!LibraryUnlinkClient(pLibModule, BindInfo))
553 {
554 DPRINT_ERROR(("LibraryUnlinkClient failed for BindInfo %p\n", BindInfo));
555 }
556
557 LibraryDereference(pLibModule);
559
560 DPRINT_VERBOSE(("Successfully unbound client %wZ\n", RegistryPath));
561
562Exit:
564 return NT_SUCCESS(unregisterStatus) ? status : unregisterStatus;
565}
VOID LibraryReference(_In_ PLIBRARY_MODULE LibModule)
Definition: library.c:267

Referenced by FxDriverUnloadCommon(), WdfLdrQueryInterface(), and WdfVersionBind().

◆ WdfVersionUnbindClass()

VOID NTAPI WdfVersionUnbindClass ( _In_ PWDF_BIND_INFO  BindInfo,
_In_ PWDF_COMPONENT_GLOBALS  Globals,
_In_ PWDF_CLASS_BIND_INFO  ClassBindInfo 
)

Definition at line 850 of file wdfldr.c.

854{
856}

Referenced by WdfLdrQueryInterface().

Variable Documentation

◆ gAlreadyInitialized

BOOLEAN gAlreadyInitialized = FALSE

Definition at line 21 of file wdfldr.c.

Referenced by DllInitialize().

◆ gAlreadyUnloaded

BOOLEAN gAlreadyUnloaded = FALSE

Definition at line 22 of file wdfldr.c.

Referenced by DllUnload().

◆ WdfLdrDiags

WDFLDR_DIAGS WdfLdrDiags = { 0 }

Definition at line 27 of file wdfldr.c.

Referenced by DereferenceVersion(), DllInitialize(), and WdfRegisterClassLibrary().

◆ WdfLdrGlobals