mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-28 04:13:35 +00:00
[SDK][WDFLDR] Add kmdf loader driver [SDK][WDF] Add kmdf drver init static library [SDK][WDF] Modify kmdf driver for working with wdfldr driver [SDK][CDROM] Cdrom driver dynamically linking with kmdf [SDK][WDF] Add kmdfdriver module type [SDK][WDF][USBDEX][NTOSKRNL_VISTA] Fully enable KMDF [KMDF][WDFLDR][WDF01000] Fix Windows 10 Compatibility WDFLDR and WDF01000 [WDF01000] NO_KERNEL_LIST_ENTRY_CHECKS for wdf01000 3rd party code This PR is an accumulation of three peoples work, with the goal of the trying to get WDF to work like it should. This has been tested in combination with some extra NT6+ ntoskrnl against multiple drivers. --------- Co-authored-by: Max Korostil <[email protected]> Co-authored-by: Victor Perevertkin <[email protected]> Co-authored-by: Adam Słaboń <[email protected]> Co-authored-by: Hermès BÉLUSCA - MAÏTO <[email protected]>
256 lines
6.8 KiB
C++
256 lines
6.8 KiB
C++
//
|
|
// Copyright (C) Microsoft. All rights reserved.
|
|
//
|
|
#include "fxobjectpch.hpp"
|
|
|
|
// Tracing support
|
|
extern "C" {
|
|
#if defined(EVENT_TRACING)
|
|
#include "globalskm.tmh"
|
|
#endif
|
|
|
|
// #include <wdfcxbase.h>
|
|
#include <fxldr.h>
|
|
|
|
|
|
}
|
|
extern "C" {
|
|
|
|
VOID
|
|
FxFreeAllocatedMdlsDebugInfo(
|
|
__in FxDriverGlobalsDebugExtension* DebugExtension
|
|
)
|
|
{
|
|
FxAllocatedMdls* pNext, *pCur;
|
|
|
|
pNext = DebugExtension->AllocatedMdls.Next;
|
|
|
|
//
|
|
// MDL leaks were already checked for in FxPoolDestroy, just free all
|
|
// the tables here.
|
|
//
|
|
while (pNext != NULL) {
|
|
pCur = pNext;
|
|
pNext = pCur->Next;
|
|
|
|
ExFreePool(pCur);
|
|
}
|
|
}
|
|
|
|
KDEFERRED_ROUTINE FxFlushDpc;
|
|
|
|
__drv_functionClass(KDEFERRED_ROUTINE)
|
|
__drv_maxIRQL(DISPATCH_LEVEL)
|
|
__drv_minIRQL(DISPATCH_LEVEL)
|
|
__drv_requiresIRQL(DISPATCH_LEVEL)
|
|
__drv_sameIRQL
|
|
VOID
|
|
NTAPI
|
|
FxFlushDpc (
|
|
__in struct _KDPC *Dpc,
|
|
__in_opt PVOID DeferredContext,
|
|
__in_opt PVOID SystemArgument1,
|
|
__in_opt PVOID SystemArgument2
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This DPC is called on a processor to assist in flushing previous DPC's
|
|
|
|
Arguments:
|
|
|
|
Dpc - Supplies a pointer to DPC object.
|
|
|
|
DeferredContext - Supplies the deferred context (event object address).
|
|
|
|
SystemArgument1 - Supplies the first system context parameter (not used).
|
|
|
|
SystemArgument2 - Supplies the second system context parameter (not used).
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
UNREFERENCED_PARAMETER(Dpc);
|
|
UNREFERENCED_PARAMETER(SystemArgument1);
|
|
UNREFERENCED_PARAMETER(SystemArgument2);
|
|
|
|
//
|
|
// Signal that this routine has been called.
|
|
//
|
|
((FxCREvent*)DeferredContext)->Set();
|
|
}
|
|
|
|
_Must_inspect_result_
|
|
BOOLEAN
|
|
FX_DRIVER_GLOBALS::IsVersionGreaterThanOrEqualTo(
|
|
__in ULONG Major,
|
|
__in ULONG Minor
|
|
)
|
|
{
|
|
if ((WdfBindInfo->Version.Major > Major) ||
|
|
(WdfBindInfo->Version.Major == Major &&
|
|
WdfBindInfo->Version.Minor >= Minor)) {
|
|
return TRUE;
|
|
}
|
|
else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
#define WDF_MAJOR_VERSION_VALUE L"WdfMajorVersion"
|
|
#define WDF_MINOR_VERSION_VALUE L"WdfMinorVersion"
|
|
|
|
_Must_inspect_result_
|
|
BOOLEAN
|
|
FX_DRIVER_GLOBALS::IsCorrectVersionRegistered(
|
|
_In_ PCUNICODE_STRING ServiceKeyName
|
|
)
|
|
{
|
|
FxAutoRegKey hDriver, hWdf;
|
|
DECLARE_CONST_UNICODE_STRING(parametersPath, L"Parameters\\Wdf");
|
|
DECLARE_CONST_UNICODE_STRING(wdfMajorValue, WDF_MAJOR_VERSION_VALUE);
|
|
DECLARE_CONST_UNICODE_STRING(wdfMinorValue, WDF_MINOR_VERSION_VALUE);
|
|
ULONG registeredMajor = 0, registeredMinor = 0;
|
|
NTSTATUS status;
|
|
|
|
status = FxRegKey::_OpenKey(NULL,
|
|
ServiceKeyName,
|
|
&hDriver.m_Key,
|
|
KEY_READ
|
|
);
|
|
if (!NT_SUCCESS(status)) {
|
|
return FALSE;
|
|
}
|
|
|
|
status = FxRegKey::_OpenKey(hDriver.m_Key,
|
|
¶metersPath,
|
|
&hWdf.m_Key,
|
|
KEY_READ
|
|
);
|
|
if (!NT_SUCCESS(status)) {
|
|
return FALSE;
|
|
}
|
|
|
|
status = FxRegKey::_QueryULong(hWdf.m_Key,
|
|
&wdfMajorValue,
|
|
®isteredMajor);
|
|
|
|
if (!NT_SUCCESS(status) || registeredMajor != WdfBindInfo->Version.Major) {
|
|
return FALSE;
|
|
}
|
|
|
|
status = FxRegKey::_QueryULong(hWdf.m_Key,
|
|
&wdfMinorValue,
|
|
®isteredMinor);
|
|
|
|
if (!NT_SUCCESS(status) || registeredMinor != WdfBindInfo->Version.Minor){
|
|
return FALSE;
|
|
}
|
|
else {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
FX_DRIVER_GLOBALS::RegisterClientVersion(
|
|
_In_ PCUNICODE_STRING ServiceKeyName
|
|
)
|
|
{
|
|
FxAutoRegKey hDriver, hParameters, hWdf;
|
|
DECLARE_CONST_UNICODE_STRING(parametersPart, L"Parameters");
|
|
DECLARE_CONST_UNICODE_STRING(wdfPart, L"Wdf");
|
|
//
|
|
// Not defined with the macro because ZwSetValue doesn't use PCUNICODE_STRING
|
|
//
|
|
UNICODE_STRING wdfMajorValue;
|
|
UNICODE_STRING wdfMinorValue;
|
|
NTSTATUS status;
|
|
|
|
RtlInitUnicodeString(&wdfMajorValue, WDF_MAJOR_VERSION_VALUE);
|
|
RtlInitUnicodeString(&wdfMinorValue, WDF_MINOR_VERSION_VALUE);
|
|
|
|
status = FxRegKey::_OpenKey(NULL,
|
|
ServiceKeyName,
|
|
&hDriver.m_Key,
|
|
KEY_WRITE | KEY_READ
|
|
);
|
|
if (!NT_SUCCESS(status)) {
|
|
DoTraceLevelMessage(this, TRACE_LEVEL_VERBOSE, TRACINGDRIVER,
|
|
"Unable to open driver's service key, status %!STATUS!", status);
|
|
return;
|
|
}
|
|
//
|
|
// Key creation, unlike user mode, must happen one level at a time, since
|
|
// create will also open take both steps instead of trying open first
|
|
//
|
|
status = FxRegKey::_Create(hDriver.m_Key,
|
|
¶metersPart,
|
|
&hParameters.m_Key,
|
|
KEY_WRITE | KEY_READ
|
|
);
|
|
if (!NT_SUCCESS(status)) {
|
|
DoTraceLevelMessage(this, TRACE_LEVEL_VERBOSE, TRACINGDRIVER,
|
|
"Unable to write Parameters key, status %!STATUS!", status);
|
|
return;
|
|
}
|
|
|
|
status = FxRegKey::_Create(hParameters.m_Key,
|
|
&wdfPart,
|
|
&hWdf.m_Key,
|
|
KEY_WRITE | KEY_READ
|
|
);
|
|
if (!NT_SUCCESS(status)) {
|
|
DoTraceLevelMessage(this, TRACE_LEVEL_VERBOSE, TRACINGDRIVER,
|
|
"Unable to write Parameters key, status %!STATUS!", status);
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Using ZwSetValueKey here to avoid having to change the implementation
|
|
// in FxRegKey of SetValue to a static / thiscall pair
|
|
//
|
|
status = ZwSetValueKey(hWdf.m_Key,
|
|
&wdfMajorValue,
|
|
0,
|
|
REG_DWORD,
|
|
&WdfBindInfo->Version.Major,
|
|
sizeof(WdfBindInfo->Version.Major)
|
|
);
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
DoTraceLevelMessage(this, TRACE_LEVEL_VERBOSE, TRACINGDRIVER,
|
|
"Failed to record driver major version value, status %!STATUS!", status);
|
|
}
|
|
|
|
status = ZwSetValueKey(hWdf.m_Key,
|
|
&wdfMinorValue,
|
|
0,
|
|
REG_DWORD,
|
|
&WdfBindInfo->Version.Minor,
|
|
sizeof(WdfBindInfo->Version.Minor)
|
|
);
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
DoTraceLevelMessage(this, TRACE_LEVEL_VERBOSE, TRACINGDRIVER,
|
|
"Failed to record driver version value, status %!STATUS!", status);
|
|
}
|
|
}
|
|
|
|
} // extern "C"
|
|
|
|
_Must_inspect_result_
|
|
BOOLEAN
|
|
FX_DRIVER_GLOBALS::IsDebuggerAttached(
|
|
VOID
|
|
)
|
|
{
|
|
return (FALSE == KdRefreshDebuggerNotPresent());
|
|
}
|