mirror of
https://github.com/reactos/reactos.git
synced 2025-03-10 10:14:44 +00:00
460 lines
14 KiB
C++
460 lines
14 KiB
C++
/*++
|
|
|
|
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_
|
|
|