https://git.reactos.org/?p=reactos.git;a=commitdiff;h=53b304e6a9e528787ff10…
commit 53b304e6a9e528787ff10a6c7abe1b3f0da9f8aa
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Wed Sep 11 14:49:21 2024 +0300
Commit: Timo Kreuzer <timo.kreuzer(a)reactos.org>
CommitDate: Sun Sep 15 12:09:09 2024 +0300
[SDK] Add unaligned.h header for safely accessing unaligned variables
This supersedes RtlStoreUshort/RtlRetrieveUshort etc, which have a horrible interface
and are inherently unsafe.
---
sdk/include/reactos/unaligned.h | 147 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 147 insertions(+)
diff --git a/sdk/include/reactos/unaligned.h b/sdk/include/reactos/unaligned.h
new file mode 100644
index 00000000000..4f7f12a9ef8
--- /dev/null
+++ b/sdk/include/reactos/unaligned.h
@@ -0,0 +1,147 @@
+/*
+ * PROJECT: ReactOS SDK
+ * LICENSE: MIT (
https://spdx.org/licenses/MIT)
+ * PURPOSE: Unaligened access helper functions
+ * COPYRIGHT: Copyright 2024 Timo Kreuzer <timo.kreuzer(a)reactos.org>
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(_M_IX86) || defined(_M_AMD64)
+#define _UNALIGNED_ACCESS_ALLOWED 1
+#else // defined(_M_IX86) || defined(_M_AMD64)
+#define _UNALIGNED_ACCESS_ALLOWED 0
+#endif // defined(_M_IX86) || defined(_M_AMD64)
+
+#if _UNALIGNED_ACCESS_ALLOWED
+
+__forceinline
+unsigned short
+ReadUnalignedU16(const unsigned short* p)
+{
+ return *p;
+}
+
+__forceinline
+unsigned long
+ReadUnalignedU32(const unsigned long* p)
+{
+ return *p;
+}
+
+__forceinline
+unsigned long long
+ReadUnalignedU64(const unsigned long long* p)
+{
+ return *p;
+}
+
+__forceinline
+void
+WriteUnalignedU16(unsigned short* p, unsigned short val)
+{
+ *p = val;
+}
+
+__forceinline
+void
+WriteUnalignedU32(unsigned long* p, unsigned long val)
+{
+ *p = val;
+}
+
+__forceinline
+void
+WriteUnalignedU64(unsigned long long* p, unsigned long long val)
+{
+ *p = val;
+}
+
+#else // !UNALIGNED_ACCESS_ALLOWED
+
+__forceinline
+unsigned short
+ReadUnalignedU16(const unsigned short* p)
+{
+ unsigned char* p1 = (unsigned char*)p;
+ return (unsigned short)(p1[0] | (p1[1] << 8));
+}
+
+__forceinline
+unsigned long
+ReadUnalignedU32(const unsigned long* p)
+{
+ unsigned char* p1 = (unsigned char*)p;
+ return (((unsigned long)p1[0] << 0) |
+ ((unsigned long)p1[1] << 8) |
+ ((unsigned long)p1[2] << 16) |
+ ((unsigned long)p1[3] << 24));
+}
+
+__forceinline
+unsigned long long
+ReadUnalignedU64(const unsigned long long* p)
+{
+ unsigned char* p1 = (unsigned char*)p;
+ return (((unsigned long long)p1[0] << 0) |
+ ((unsigned long long)p1[1] << 8) |
+ ((unsigned long long)p1[2] << 16) |
+ ((unsigned long long)p1[3] << 24) |
+ ((unsigned long long)p1[4] << 32) |
+ ((unsigned long long)p1[5] << 40) |
+ ((unsigned long long)p1[6] << 48) |
+ ((unsigned long long)p1[7] << 56));
+}
+
+__forceinline
+void
+WriteUnalignedU16(unsigned short* p, unsigned short val)
+{
+ unsigned char* p1 = (unsigned char*)p;
+ p1[0] = (unsigned char)(val >> 0);
+ p1[1] = (unsigned char)(val >> 8);
+}
+
+__forceinline
+void
+WriteUnalignedU32(unsigned long* p, unsigned long val)
+{
+ unsigned char* p1 = (unsigned char*)p;
+ p1[0] = (unsigned char)(val >> 0);
+ p1[1] = (unsigned char)(val >> 8);
+ p1[2] = (unsigned char)(val >> 16);
+ p1[3] = (unsigned char)(val >> 24);
+}
+
+__forceinline
+void
+WriteUnalignedU64(unsigned long long* p, unsigned long long val)
+{
+ unsigned char* p1 = (unsigned char*)p;
+ p1[0] = (unsigned char)(val >> 0);
+ p1[1] = (unsigned char)(val >> 8);
+ p1[2] = (unsigned char)(val >> 16);
+ p1[3] = (unsigned char)(val >> 24);
+ p1[4] = (unsigned char)(val >> 32);
+ p1[5] = (unsigned char)(val >> 40);
+ p1[6] = (unsigned char)(val >> 48);
+ p1[7] = (unsigned char)(val >> 56);
+}
+
+#endif // !UNALIGNED_ACCESS_ALLOWED
+
+#ifdef _WIN64
+#define ReadUnalignedUlongPtr ReadUnalignedU64
+#define WriteUnalignedUlongPtr WriteUnalignedU64
+#else // _WIN64
+#define ReadUnalignedUlongPtr ReadUnalignedU32
+#define WriteUnalignedUlongPtr WriteUnalignedU32
+#endif // _WIN64
+
+#ifdef __cplusplus
+} // extern "C"
+#endif