diff --git a/qxldod/QxlDod.cpp b/qxldod/QxlDod.cpp
index f01600d..b482360 100755
--- a/qxldod/QxlDod.cpp
+++ b/qxldod/QxlDod.cpp
@@ -1,6 +1,7 @@
#include "driver.h"
#include "qxldod.h"
#include "qxl_windows.h"
+#include "compat.h"
#pragma code_seg("PAGE")
@@ -1960,17 +1961,18 @@ MapFrameBuffer(
return STATUS_INVALID_PARAMETER;
}
- *VirtualAddress = MmMapIoSpace(PhysicalAddress,
- Length,
- MmWriteCombined);
+ *VirtualAddress = MapIoSpace(PhysicalAddress,
+ Length,
+ MmWriteCombined,
+ PAGE_WRITECOMBINE | PAGE_READWRITE);
if (*VirtualAddress == NULL)
{
// The underlying call to MmMapIoSpace failed. This may be because, MmWriteCombined
// isn't supported, so try again with MmNonCached
-
- *VirtualAddress = MmMapIoSpace(PhysicalAddress,
- Length,
- MmNonCached);
+ *VirtualAddress = MapIoSpace(PhysicalAddress,
+ Length,
+ MmNonCached,
+ PAGE_NOCACHE | PAGE_READWRITE);
if (*VirtualAddress == NULL)
{
DbgPrint(TRACE_LEVEL_ERROR, ("MmMapIoSpace returned a NULL buffer when trying to allocate %lu bytes", Length));
diff --git a/qxldod/compat.cpp b/qxldod/compat.cpp
new file mode 100644
index 0000000..88f9619
--- /dev/null
+++ b/qxldod/compat.cpp
@@ -0,0 +1,62 @@
+#include "driver.h"
+#include "compat.h"
+
+static MapIoSpaceFunc DetectMapIoSpace;
+MapIoSpaceFunc *MapIoSpace = DetectMapIoSpace;
+
+typedef NTKERNELAPI PVOID MmMapIoSpaceExFunc(
+ _In_ PHYSICAL_ADDRESS PhysicalAddress,
+ _In_ SIZE_T NumberOfBytes,
+ _In_ ULONG Protect
+);
+static MmMapIoSpaceExFunc *pMmMapIoSpaceEx;
+
+// all functions in this module are paged
+#pragma code_seg("PAGE")
+
+// we call MmMapIoSpace only if MmMapIoSpaceEx is not present
+// so disable the warning
+#pragma warning(push)
+#pragma warning(disable:30029)
+static PVOID OldMapIoSpace(
+ _In_ PHYSICAL_ADDRESS PhysicalAddress,
+ _In_ SIZE_T NumberOfBytes,
+ _In_ MEMORY_CACHING_TYPE CacheType,
+ _In_ ULONG Protect
+)
+{
+ PAGED_CODE();
+ return MmMapIoSpace(PhysicalAddress, NumberOfBytes, CacheType);
+}
+#pragma warning(pop)
+
+static PVOID NewMapIoSpace(
+ _In_ PHYSICAL_ADDRESS PhysicalAddress,
+ _In_ SIZE_T NumberOfBytes,
+ _In_ MEMORY_CACHING_TYPE CacheType,
+ _In_ ULONG Protect
+)
+{
+ PAGED_CODE();
+ return pMmMapIoSpaceEx(PhysicalAddress, NumberOfBytes, Protect);
+}
+
+static PVOID DetectMapIoSpace(
+ _In_ PHYSICAL_ADDRESS PhysicalAddress,
+ _In_ SIZE_T NumberOfBytes,
+ _In_ MEMORY_CACHING_TYPE CacheType,
+ _In_ ULONG Protect
+)
+{
+ PAGED_CODE();
+ UNICODE_STRING name;
+ RtlInitUnicodeString(&name, L"MmMapIoSpaceEx");
+
+ pMmMapIoSpaceEx = (MmMapIoSpaceExFunc*)MmGetSystemRoutineAddress(&name);
+ if (pMmMapIoSpaceEx) {
+ MapIoSpace = NewMapIoSpace;
+ } else {
+ MapIoSpace = OldMapIoSpace;
+ }
+ return MapIoSpace(PhysicalAddress, NumberOfBytes, CacheType, Protect);
+}
diff --git a/qxldod/compat.h b/qxldod/compat.h
new file mode 100644
index 0000000..3f20b81
--- /dev/null
+++ b/qxldod/compat.h
@@ -0,0 +1,10 @@
+#pragma once
+#include "BaseObject.h"
+
+typedef PVOID MapIoSpaceFunc(
+ _In_ PHYSICAL_ADDRESS PhysicalAddress,
+ _In_ SIZE_T NumberOfBytes,
+ _In_ MEMORY_CACHING_TYPE CacheType,
+ _In_ ULONG Protect
+);
+extern MapIoSpaceFunc *MapIoSpace;
diff --git a/qxldod/qxldod.vcxproj b/qxldod/qxldod.vcxproj
index 37d2b38..2c10158 100755
--- a/qxldod/qxldod.vcxproj
+++ b/qxldod/qxldod.vcxproj
@@ -272,12 +272,14 @@
+
+
diff --git a/qxldod/qxldod.vcxproj.filters b/qxldod/qxldod.vcxproj.filters
index bb9daa9..1e86aa6 100755
--- a/qxldod/qxldod.vcxproj.filters
+++ b/qxldod/qxldod.vcxproj.filters
@@ -25,6 +25,9 @@
Header Files
+
+ Header Files
+
Header Files
@@ -36,6 +39,9 @@
Source Files
+
+ Source Files
+
Source Files