[WDF] Add Windows Driver Framework files
[reactos.git] / sdk / lib / drivers / wdf / shared / inc / private / um / fxdeviceum.hpp
diff --git a/sdk/lib/drivers/wdf/shared/inc/private/um/fxdeviceum.hpp b/sdk/lib/drivers/wdf/shared/inc/private/um/fxdeviceum.hpp
new file mode 100644 (file)
index 0000000..88cc1bc
--- /dev/null
@@ -0,0 +1,460 @@
+/*++
+
+Copyright (c) Microsoft Corporation
+
+Module Name:
+
+    FxDeviceUM.hpp
+
+Abstract:
+
+    This is the definition of the FxDevice object UM specific
+
+Author:
+
+
+
+Environment:
+
+    User mode only
+
+Revision History:
+
+--*/
+
+#ifndef _FXDEVICEUM_H_
+#define _FXDEVICEUM_H_
+
+#define WDF_PATH_SEPARATOR              L"\\"
+#define WUDF_SUB_KEY                    L"WUDF"
+#define WUDF_ADDITIONAL_SUB_KEY         L"WDF"
+
+#define FX_DIRECT_HARDWARE_ACCESS           L"DirectHardwareAccess"
+#define FX_DIRECT_HARDWARE_ACCESS_DEFAULT   (WdfRejectDirectHardwareAccess)
+
+#define FX_REGISTER_ACCESS_MODE             L"RegisterAccessMode"
+#define FX_REGISTER_ACCESS_MODE_DEFAULT     (WdfRegisterAccessUsingSystemCall)
+
+#define FX_FILE_OBJECT_POLICY               L"FileObjectPolicy"
+#define FX_FILE_OBJECT_POLICY_DEFAULT       (WdfRejectNullAndUnknownFileObjects)
+
+#define FX_FS_CONTEXT_USE_POLICY            L"FsContextUsePolicy"
+#define FX_FS_CONTEXT_USE_POLICY_DEFAULT    (WdfDefaultFsContextUsePolicy)
+
+#define FX_KERNEL_MODE_CLIENT_POLICY        L"KernelModeClientPolicy"
+#define FX_METHOD_NEITHER_ACTION            L"MethodNeitherAction"
+#define FX_PROCESS_SHARING_ENABLED          L"HostProcessSharingEnabled"
+#define FX_DEVICE_GROUP_ID                  L"DeviceGroupId"
+#define FX_FILE_OBJECT_POLICY               L"FileObjectPolicy"
+
+//
+// READ/WRITE_REGISTER_Xxx macros need compiler and memory barrier. Each
+// platform has a different set of compiler intrinsics to support that.
+// In kernel, x86 READ/WRITE macros are implemented in assembly and use
+// lock prefix to force real access. For amd64, _ReadWriteBarrier
+// (compiler barrier) is used for reads and __faststorefence (CPU barrier) for
+// writes. For ARM, _ReadWriteBarrier (compiler barrier) is used for reads and
+// both _ReadWriteBarrier and __emit(Value) for writes.
+//
+// Because of this variation, UMDF will use the macros directly from wdm.h
+// by autogenerating those macros from wdm.h into a private UMDF header.
+// For x86, there are no macros so either UMDF could directly link to the
+// ntosrtl.lib (that has these macros implemented in assembly), or implement
+// its own macros that use MemoryBarrier() macro from winnt.h.
+//
+// Below is UMDF's implementation for x86. The macros for other platforms are
+// in WudfWdm_private.h.
+//
+#if defined(_X86_)
+
+#define READ_REGISTER_UCHAR(x) \
+    (MemoryBarrier(), *(volatile UCHAR * const)(x))
+
+#define READ_REGISTER_USHORT(x) \
+    (MemoryBarrier(), *(volatile USHORT * const)(x))
+
+#define READ_REGISTER_ULONG(x) \
+    (MemoryBarrier(), *(volatile ULONG * const)(x))
+
+#define READ_REGISTER_ULONG64(x) \
+    (MemoryBarrier(), *(volatile ULONG64 * const)(x))
+
+#define READ_REGISTER_BUFFER_UCHAR(x, y, z) {                           \
+    PUCHAR registerBuffer = x;                                          \
+    PUCHAR readBuffer = y;                                              \
+    ULONG readCount;                                                    \
+    MemoryBarrier();                                                    \
+    for (readCount = z; readCount--; readBuffer++, registerBuffer++) {  \
+        *readBuffer = *(volatile UCHAR * const)(registerBuffer);        \
+    }                                                                   \
+}
+
+#define READ_REGISTER_BUFFER_USHORT(x, y, z) {                          \
+    PUSHORT registerBuffer = x;                                         \
+    PUSHORT readBuffer = y;                                             \
+    ULONG readCount;                                                    \
+    MemoryBarrier();                                                    \
+    for (readCount = z; readCount--; readBuffer++, registerBuffer++) {  \
+        *readBuffer = *(volatile USHORT * const)(registerBuffer);       \
+    }                                                                   \
+}
+
+#define READ_REGISTER_BUFFER_ULONG(x, y, z) {                           \
+    PULONG registerBuffer = x;                                          \
+    PULONG readBuffer = y;                                              \
+    ULONG readCount;                                                    \
+    MemoryBarrier();                                                    \
+    for (readCount = z; readCount--; readBuffer++, registerBuffer++) {  \
+        *readBuffer = *(volatile ULONG * const)(registerBuffer);        \
+    }                                                                   \
+}
+
+#define READ_REGISTER_BUFFER_ULONG64(x, y, z) {                         \
+    PULONG64 registerBuffer = x;                                        \
+    PULONG64 readBuffer = y;                                            \
+    ULONG readCount;                                                    \
+    MemoryBarrier();                                                    \
+    for (readCount = z; readCount--; readBuffer++, registerBuffer++) {  \
+        *readBuffer = *(volatile ULONG64 * const)(registerBuffer);      \
+    }                                                                   \
+}
+
+#define WRITE_REGISTER_UCHAR(x, y) {    \
+    *(volatile UCHAR * const)(x) = y;   \
+    MemoryBarrier();                    \
+}
+
+#define WRITE_REGISTER_USHORT(x, y) {   \
+    *(volatile USHORT * const)(x) = y;  \
+    MemoryBarrier();               \
+}
+
+#define WRITE_REGISTER_ULONG(x, y) {    \
+    *(volatile ULONG * const)(x) = y;   \
+    MemoryBarrier();                    \
+}
+
+#define WRITE_REGISTER_ULONG64(x, y) {  \
+    *(volatile ULONG64 * const)(x) = y; \
+    MemoryBarrier();                    \
+}
+
+#define WRITE_REGISTER_BUFFER_UCHAR(x, y, z) {                            \
+    PUCHAR registerBuffer = x;                                            \
+    PUCHAR writeBuffer = y;                                               \
+    ULONG writeCount;                                                     \
+    for (writeCount = z; writeCount--; writeBuffer++, registerBuffer++) { \
+        *(volatile UCHAR * const)(registerBuffer) = *writeBuffer;         \
+    }                                                                     \
+    MemoryBarrier();                                                      \
+}
+
+#define WRITE_REGISTER_BUFFER_USHORT(x, y, z) {                           \
+    PUSHORT registerBuffer = x;                                           \
+    PUSHORT writeBuffer = y;                                              \
+    ULONG writeCount;                                                     \
+    for (writeCount = z; writeCount--; writeBuffer++, registerBuffer++) { \
+        *(volatile USHORT * const)(registerBuffer) = *writeBuffer;        \
+    }                                                                     \
+    MemoryBarrier();                                                      \
+}
+
+#define WRITE_REGISTER_BUFFER_ULONG(x, y, z) {                            \
+    PULONG registerBuffer = x;                                            \
+    PULONG writeBuffer = y;                                               \
+    ULONG writeCount;                                                     \
+    for (writeCount = z; writeCount--; writeBuffer++, registerBuffer++) { \
+        *(volatile ULONG * const)(registerBuffer) = *writeBuffer;         \
+    }                                                                     \
+    MemoryBarrier();                                                      \
+}
+
+#define WRITE_REGISTER_BUFFER_ULONG64(x, y, z) {                          \
+    PULONG64 registerBuffer = x;                                          \
+    PULONG64 writeBuffer = y;                                             \
+    ULONG writeCount;                                                     \
+    for (writeCount = z; writeCount--; writeBuffer++, registerBuffer++) { \
+        *(volatile ULONG64 * const)(registerBuffer) = *writeBuffer;       \
+    }                                                                     \
+    MemoryBarrier();                                                      \
+}
+
+#endif // _X86_
+
+__inline
+SIZE_T
+FxDevice::ReadRegister(
+    __in WDF_DEVICE_HWACCESS_TARGET_SIZE Size,
+    __in PVOID Register
+    )
+{
+    SIZE_T value = 0;
+
+    //
+    // ETW start event for perf measurement
+    //
+    EventWriteEVENT_UMDF_FX_READ_FROM_HARDWARE_START(
+        WdfDeviceHwAccessTargetTypeRegister, Size, 0);
+
+    switch(Size) {
+    case WdfDeviceHwAccessTargetSizeUchar:
+        value = READ_REGISTER_UCHAR((PUCHAR)Register);
+        break;
+    case WdfDeviceHwAccessTargetSizeUshort:
+        value = READ_REGISTER_USHORT((PUSHORT)Register);
+        break;
+    case WdfDeviceHwAccessTargetSizeUlong:
+        value = READ_REGISTER_ULONG((PULONG)Register);
+        break;
+    case WdfDeviceHwAccessTargetSizeUlong64:
+#if defined(_WIN64)
+        value = READ_REGISTER_ULONG64((PULONG64)Register);
+#else
+        FX_VERIFY(DRIVER(BadArgument, TODO), CHECK("Invalid call to ULONG64 "
+            "hardware access function", FALSE));
+#endif
+        break;
+    default:
+        FX_VERIFY(INTERNAL, TRAPMSG("Unexpected"));
+        break;
+    }
+
+    //
+    // ETW end event for perf measurement
+    //
+    EventWriteEVENT_UMDF_FX_READ_FROM_HARDWARE_END(
+        WdfDeviceHwAccessTargetTypeRegister, Size, 0);
+
+    return value;
+}
+
+__inline
+VOID
+FxDevice::ReadRegisterBuffer(
+    __in WDF_DEVICE_HWACCESS_TARGET_SIZE Size,
+    __in PVOID Register,
+    __out_ecount_full(Count) PVOID Buffer,
+    __in ULONG Count
+    )
+{
+    //
+    // ETW start event for perf measurement
+    //
+    EventWriteEVENT_UMDF_FX_READ_FROM_HARDWARE_START(
+        WdfDeviceHwAccessTargetTypeRegisterBuffer, Size, Count);
+
+    switch(Size) {
+    case WdfDeviceHwAccessTargetSizeUchar:
+        READ_REGISTER_BUFFER_UCHAR(((PUCHAR)Register), (PUCHAR)Buffer, Count );
+        break;
+    case WdfDeviceHwAccessTargetSizeUshort:
+#pragma prefast(suppress:26000, "The Size parameter dictates the buffer size")
+        READ_REGISTER_BUFFER_USHORT(((PUSHORT)Register), (PUSHORT)Buffer, Count );
+        break;
+    case WdfDeviceHwAccessTargetSizeUlong:
+        READ_REGISTER_BUFFER_ULONG(((PULONG)Register), (PULONG)Buffer, Count );
+        break;
+    case WdfDeviceHwAccessTargetSizeUlong64:
+#if defined(_WIN64)
+        READ_REGISTER_BUFFER_ULONG64(((PULONG64)Register), (PULONG64)Buffer, Count );
+#else
+        FX_VERIFY(DRIVER(BadArgument, TODO), CHECK("Invalid call to ULONG64 "
+            "hardware access function", FALSE));
+#endif
+        break;
+    default:
+        FX_VERIFY(INTERNAL, TRAPMSG("Unexpected"));
+        break;
+    }
+
+    //
+    // ETW start event for perf measurement
+    //
+    EventWriteEVENT_UMDF_FX_READ_FROM_HARDWARE_END(
+        WdfDeviceHwAccessTargetTypeRegisterBuffer, Size, Count);
+}
+
+__inline
+VOID
+FxDevice::WriteRegister(
+    __in WDF_DEVICE_HWACCESS_TARGET_SIZE Size,
+    __in PVOID Register,
+    __in SIZE_T Value
+    )
+{
+    //
+    // ETW start event for perf measurement
+    //
+    EventWriteEVENT_UMDF_FX_WRITE_TO_HARDWARE_START(
+        WdfDeviceHwAccessTargetTypeRegister, Size, 0);
+
+    switch(Size) {
+    case WdfDeviceHwAccessTargetSizeUchar:
+        WRITE_REGISTER_UCHAR((PUCHAR)Register, (UCHAR)Value);
+        break;
+    case WdfDeviceHwAccessTargetSizeUshort:
+        WRITE_REGISTER_USHORT((PUSHORT)Register, (USHORT)Value);
+        break;
+    case WdfDeviceHwAccessTargetSizeUlong:
+        WRITE_REGISTER_ULONG((PULONG)Register, (ULONG)Value);
+        break;
+    case WdfDeviceHwAccessTargetSizeUlong64:
+#if defined(_WIN64)
+        WRITE_REGISTER_ULONG64((PULONG64)Register, (ULONG64)Value);
+#else
+        FX_VERIFY(DRIVER(BadArgument, TODO), CHECK("Invalid call to ULONG64 "
+            "hardware access function", FALSE));
+#endif
+        break;
+    default:
+        FX_VERIFY(INTERNAL, TRAPMSG("Unexpected"));
+        break;
+    }
+
+    //
+    // ETW start event for perf measurement
+    //
+    EventWriteEVENT_UMDF_FX_WRITE_TO_HARDWARE_END(
+        WdfDeviceHwAccessTargetTypeRegister, Size, 0);
+}
+
+__inline
+VOID
+FxDevice::WriteRegisterBuffer(
+    __in WDF_DEVICE_HWACCESS_TARGET_SIZE Size,
+    __in PVOID Register,
+    __in_ecount(Count) PVOID Buffer,
+    __in ULONG Count
+    )
+{
+    //
+    // ETW start event for perf measurement
+    //
+    EventWriteEVENT_UMDF_FX_WRITE_TO_HARDWARE_START(
+        WdfDeviceHwAccessTargetTypeRegisterBuffer, Size, Count);
+
+    switch(Size) {
+    case WdfDeviceHwAccessTargetSizeUchar:
+        WRITE_REGISTER_BUFFER_UCHAR(((PUCHAR)Register), (PUCHAR)Buffer, Count);
+        break;
+    case WdfDeviceHwAccessTargetSizeUshort:
+#pragma prefast(suppress:26000, "The Size parameter dictates the buffer size")
+        WRITE_REGISTER_BUFFER_USHORT(((PUSHORT)Register), (PUSHORT)Buffer, Count);
+        break;
+    case WdfDeviceHwAccessTargetSizeUlong:
+        WRITE_REGISTER_BUFFER_ULONG(((PULONG)Register), (PULONG)Buffer, Count);
+        break;
+    case WdfDeviceHwAccessTargetSizeUlong64:
+#if defined(_WIN64)
+        WRITE_REGISTER_BUFFER_ULONG64(((PULONG64)Register), (PULONG64)Buffer, Count);
+#else
+        FX_VERIFY(DRIVER(BadArgument, TODO), CHECK("Invalid call to ULONG64 "
+            "hardware access function", FALSE));
+#endif
+        break;
+    default:
+        FX_VERIFY(INTERNAL, TRAPMSG("Unexpected"));
+        break;
+    }
+
+    //
+    // ETW start event for perf measurement
+    //
+    EventWriteEVENT_UMDF_FX_WRITE_TO_HARDWARE_END(
+        WdfDeviceHwAccessTargetTypeRegisterBuffer, Size, Count);
+}
+
+__inline
+FxWdmDeviceExtension*
+FxDevice::_GetFxWdmExtension(
+    __in MdDeviceObject DeviceObject
+    )
+{
+    return (FxWdmDeviceExtension*)
+        ((static_cast<IWudfDevice2*> (DeviceObject))->GetDeviceExtension());
+}
+
+__inline
+BOOLEAN
+FxDevice::IsRemoveLockEnabledForIo(
+    VOID
+    )
+{
+   return FALSE;
+}
+
+__inline
+MdRemoveLock
+FxDevice::GetRemoveLock(
+    VOID
+    )
+{
+    return &FxDevice::_GetFxWdmExtension(
+        GetDeviceObject())->IoRemoveLock;
+}
+
+__inline
+NTSTATUS
+FxDevice::WmiPkgRegister(
+    VOID
+    )
+{
+    //
+    // WMI doesn't apply for UMDF
+    //
+    DO_NOTHING();
+    return STATUS_SUCCESS;
+}
+
+__inline
+VOID
+FxDevice::WmiPkgDeregister(
+    VOID
+    )
+{
+    //
+    // WMI doesn't apply for UMDF
+    //
+    DO_NOTHING();
+}
+
+__inline
+VOID
+FxDevice::WmiPkgCleanup(
+    VOID
+    )
+{
+    //
+    // WMI doesn't apply for UMDF
+    //
+    DO_NOTHING();
+}
+
+__inline
+IWudfDeviceStack*
+FxDevice::GetDeviceStack(
+    VOID
+    )
+{
+    return m_DevStack;
+}
+
+__inline
+IWudfDeviceStack2 *
+FxDevice::GetDeviceStack2(
+    )
+{
+    IWudfDeviceStack2 *pDeviceStack2;
+    HRESULT hrQI;
+
+    hrQI = m_DevStack->QueryInterface(IID_IWudfDeviceStack2,
+                                      (PVOID*)&pDeviceStack2);
+    FX_VERIFY(INTERNAL, CHECK_QI(hrQI, pDeviceStack2));
+
+    m_DevStack->Release();
+
+    return pDeviceStack2;
+}
+
+#endif //_FXDEVICEUM_H_
+