[WDF] Add Windows Driver Framework files
[reactos.git] / sdk / lib / drivers / wdf / shared / object / km / globalskm.cpp
diff --git a/sdk/lib/drivers/wdf/shared/object/km/globalskm.cpp b/sdk/lib/drivers/wdf/shared/object/km/globalskm.cpp
new file mode 100644 (file)
index 0000000..41de43d
--- /dev/null
@@ -0,0 +1,254 @@
+//
+//    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
+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,
+                                &parametersPath,
+                                &hWdf.m_Key,
+                                KEY_READ
+                                );
+    if (!NT_SUCCESS(status)) {
+        return FALSE;
+    }
+
+    status = FxRegKey::_QueryULong(hWdf.m_Key,
+                                   &wdfMajorValue,
+                                   &registeredMajor);
+
+    if (!NT_SUCCESS(status) || registeredMajor != WdfBindInfo->Version.Major) {
+        return FALSE;
+    }
+
+    status = FxRegKey::_QueryULong(hWdf.m_Key,
+                                   &wdfMinorValue,
+                                   &registeredMinor);
+
+    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,
+                               &parametersPart,
+                               &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());
+}