From 875c4fa3447b9a5c5c3ae6b13988c5397fd9c078 Mon Sep 17 00:00:00 2001 From: SaiXU Date: Fri, 30 Jan 2026 11:36:39 +0800 Subject: [PATCH] support ARM64 on windows --- CMakeSettings.json | 66 ++++++++++++++++++++++++ src/CMakeLists.txt | 57 ++++++++++++++++----- src/Cedar/CMakeLists.txt | 32 ++++++++---- src/Mayaqua/Encrypt.c | 10 ++-- src/Neo6/NDIS6.c | 3 +- src/Neo6/NDIS6.h | 48 +++++++++++------- src/Neo6/Neo6.vcxproj | 107 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 279 insertions(+), 44 deletions(-) create mode 100644 src/Neo6/Neo6.vcxproj diff --git a/CMakeSettings.json b/CMakeSettings.json index 4817c860..3e854af1 100644 --- a/CMakeSettings.json +++ b/CMakeSettings.json @@ -136,6 +136,72 @@ "type": "STRING" } ] + }, + { + "name": "arm64-on-x64", + "description": "Cross compile Windows ARM64 on x64", + "generator": "Ninja", + "configurationType": "RelWithDebInfo", + "inheritEnvironments": ["msvc_arm64_x64"], + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "variables": [ + { + "name": "BUILD_NUMBER", + "value": "${env.BuildNumber}", + "type": "STRING" + }, + { + "name": "CMAKE_SYSTEM_NAME", + "value": "Windows", + "type": "STRING" + }, + { + "name": "CMAKE_SYSTEM_PROCESSOR", + "value": "arm64", + "type": "STRING" + }, + { + "name": "CMAKE_C_COMPILER", + "value": "${env.VCINSTALLDIR}Tools/Llvm/bin/clang-cl.exe", + "type": "FILEPATH" + }, + { + "name": "CMAKE_CXX_COMPILER", + "value": "${env.VCINSTALLDIR}Tools/Llvm/bin/clang-cl.exe", + "type": "FILEPATH" + }, + { + "name": "CMAKE_C_COMPILER_TARGET", + "value": "arm64-windows-msvc", + "type": "STRING" + }, + { + "name": "CMAKE_CXX_COMPILER_TARGET", + "value": "arm64-windows-msvc", + "type": "STRING" + }, + { + "name": "CMAKE_EXE_LINKER_FLAGS", + "value": "/machine:ARM64", + "type": "STRING" + }, + { + "name": "VCPKG_TARGET_TRIPLET", + "value": "arm64-windows-static", + "type": "STRING" + }, + { + "name": "CMAKE_STATIC_LINKER_FLAGS", + "value": "/machine:ARM64", + "type": "STRING" + }, + { + "name": "CMAKE_SHARED_LINKER_FLAGS", + "value": "/machine:ARM64", + "type": "STRING" + } + ] } ] } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8f9f9843..5a6f6b9f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -if(UNIX) +if(UNIX) # Creates wrapper scripts and installs them in the user's binaries directory, which is usually "/usr/local/bin". # This is required because symlinks use the folder they are in as working directory. # @@ -59,6 +59,12 @@ add_definitions(-D_REENTRANT -DREENTRANT -D_THREAD_SAFE -D_THREADSAFE -DTHREAD_S include_directories(.) if(WIN32) + if(IS_CROSS_COMPILATION MATCHES "arm64-on-x64") + set(CMAKE_SYSTEM_PROCESSOR "arm64") + else() + message("Setting QSPECTRE") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Qspectre") + endif() add_definitions(-DWIN32 -D_WINDOWS -DOS_WIN32 -D_CRT_SECURE_NO_WARNINGS) # @@ -69,9 +75,6 @@ if(WIN32) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /guard:cf") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /guard:cf /DYNAMICBASE") - message("Setting QSPECTRE") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Qspectre") - message("Setting CETCOMPAT") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /CETCOMPAT") @@ -164,15 +167,45 @@ add_custom_target(hamcore-archive-build ALL DEPENDS "${BUILD_DIRECTORY}/hamcore.se2" ) +if(IS_CROSS_COMPILATION MATCHES "arm64-on-x64") + file(TO_CMAKE_PATH "${TOP_DIRECTORY}" TOP_DIRECTORY_NORM) + set(X64_HAMCORE_BUILDER + "${TOP_DIRECTORY_NORM}/out/build/x64-native/src/hamcorebuilder/hamcorebuilder.exe" + ) + if(EXISTS "${X64_HAMCORE_BUILDER}") + message(STATUS "file exist (from TOP_DIRECTORY)") + endif() -add_custom_command( - COMMENT "Building hamcore.se2 archive file..." - COMMAND hamcorebuilder "hamcore.se2" "${TOP_DIRECTORY}/src/bin/hamcore" - DEPENDS hamcorebuilder "${TOP_DIRECTORY}/src/bin/hamcore/" - OUTPUT "${BUILD_DIRECTORY}/hamcore.se2" - WORKING_DIRECTORY "${BUILD_DIRECTORY}" - VERBATIM -) + # support cross compile, when you compile ARM64 version on X64 Platform + if(EXISTS "${X64_HAMCORE_BUILDER}") + message("X64_HAMCORE_BUILDER found: ${X64_HAMCORE_BUILDER}") + elseif(EXISTS("${TOP_DIRECTORY}/out/build/x64-native/src/hamcorebuilder/hamcorebuilder.exe")) + set(X64_HAMCORE_BUILDER "${TOP_DIRECTORY}/out/build/x64-native/src/hamcorebuilder/hamcorebuilder.exe") + else() + message("${TOP_DIRECTORY}/out/build/x64-native/src/hamcorebuilder/hamcorebuilder.exe") + message(FATAL_ERROR "X64_HAMCORE_BUILDER not found: ${X64_HAMCORE_BUILDER}, pls build x64-native version first") + endif() + message(STATUS "X64_HAMCORE_BUILDER = ${X64_HAMCORE_BUILDER}") + + add_custom_command( + COMMENT "Building hamcore.se2 archive file..." + COMMAND ${X64_HAMCORE_BUILDER} "hamcore.se2" "${TOP_DIRECTORY}/src/bin/hamcore" + DEPENDS ${X64_HAMCORE_BUILDER} "${TOP_DIRECTORY}/src/bin/hamcore/" + OUTPUT "${BUILD_DIRECTORY}/hamcore.se2" + WORKING_DIRECTORY "${BUILD_DIRECTORY}" + VERBATIM + ) + +else() + add_custom_command( + COMMENT "Building hamcore.se2 archive file..." + COMMAND hamcorebuilder "hamcore.se2" "${TOP_DIRECTORY}/src/bin/hamcore" + DEPENDS hamcorebuilder "${TOP_DIRECTORY}/src/bin/hamcore/" + OUTPUT "${BUILD_DIRECTORY}/hamcore.se2" + WORKING_DIRECTORY "${BUILD_DIRECTORY}" + VERBATIM + ) +endif() if(WIN32) # PenCore diff --git a/src/Cedar/CMakeLists.txt b/src/Cedar/CMakeLists.txt index 7818d790..3e8a75e1 100644 --- a/src/Cedar/CMakeLists.txt +++ b/src/Cedar/CMakeLists.txt @@ -12,6 +12,15 @@ else() add_library(cedar SHARED ${SOURCES_CEDAR} ${SOURCES_CEDAR_CPP} ${HEADERS_CEDAR}) endif() +if(MSVC) + target_compile_options(cedar PRIVATE /EHsc) +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + if(CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC") + target_compile_options(cedar PRIVATE /EHsc) + else() + target_compile_options(cedar PRIVATE -fexceptions) + endif() +endif() set_target_properties(cedar PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${BUILD_DIRECTORY}" @@ -22,19 +31,22 @@ set_target_properties(cedar target_link_libraries(cedar PUBLIC mayaqua) cmake_host_system_information(RESULT HAS_SSE2 QUERY HAS_SSE2) - -set(BLAKE2_SRC_PATH $,${TOP_DIRECTORY}/3rdparty/BLAKE2/sse,${TOP_DIRECTORY}/3rdparty/BLAKE2/ref>) -set(BLAKE2_SRC $,${BLAKE2_SRC_PATH}/blake2s.c,${BLAKE2_SRC_PATH}/blake2s-ref.c>) - +if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64|arm64v8|ARM64") + message(STATUS "Target architecture is ARM64") + set(BLAKE2_SRC_PATH "${TOP_DIRECTORY}/3rdparty/BLAKE2/neon") + set(BLAKE2_SRC "${BLAKE2_SRC_PATH}/blake2s-neon.c") +else() + set(BLAKE2_SRC_PATH $,${TOP_DIRECTORY}/3rdparty/BLAKE2/sse,${TOP_DIRECTORY}/3rdparty/BLAKE2/ref>) + set(BLAKE2_SRC $,${BLAKE2_SRC_PATH}/blake2s.c,${BLAKE2_SRC_PATH}/blake2s-ref.c>) + if(HAS_SSE2) + # If SSE2 is enabled, a build failure occurs with MSVC because it doesn't define "__SSE2__". + # The fix consists in defining "HAVE_SSE2" manually, effectively overriding the check. + set_property(SOURCE ${BLAKE2_SRC} PROPERTY COMPILE_DEFINITIONS "HAVE_SSE2") + endif() +endif() target_include_directories(cedar PUBLIC ${BLAKE2_SRC_PATH}) target_sources(cedar PRIVATE ${BLAKE2_SRC}) -if(HAS_SSE2) - # If SSE2 is enabled, a build failure occurs with MSVC because it doesn't define "__SSE2__". - # The fix consists in defining "HAVE_SSE2" manually, effectively overriding the check. - set_property(SOURCE ${BLAKE2_SRC} PROPERTY COMPILE_DEFINITIONS "HAVE_SSE2") -endif() - if(VCPKG_TARGET_TRIPLET) find_package(unofficial-sodium CONFIG REQUIRED) target_link_libraries(cedar PUBLIC unofficial-sodium::sodium) diff --git a/src/Mayaqua/Encrypt.c b/src/Mayaqua/Encrypt.c index f473b01d..e9b8b745 100644 --- a/src/Mayaqua/Encrypt.c +++ b/src/Mayaqua/Encrypt.c @@ -4462,9 +4462,13 @@ bool IsAesNiSupported() // Unfortunately OpenSSL doesn't provide a function to do it #ifdef _MSC_VER - int regs[4]; // EAX, EBX, ECX, EDX - __cpuid(regs, 1); - supported = (regs[2] >> 25) & 1; + #if defined(_M_X64) || defined(_M_IX86) + int regs[4]; // EAX, EBX, ECX, EDX + __cpuid(regs, 1); + supported = (regs[2] >> 25) & 1; + #elif defined(_M_ARM64) + return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE); + #endif #else // _MSC_VER #if defined(CPU_FEATURES_ARCH_X86) const X86Features features = GetX86Info().features; diff --git a/src/Neo6/NDIS6.c b/src/Neo6/NDIS6.c index 9532f9fe..4df8d023 100644 --- a/src/Neo6/NDIS6.c +++ b/src/Neo6/NDIS6.c @@ -5,7 +5,8 @@ // NDIS6.c // Windows NDIS 6.2 Routine -#include +//#include +#include "GlobalConst.h" #define NEO_DEVICE_DRIVER diff --git a/src/Neo6/NDIS6.h b/src/Neo6/NDIS6.h index 2c33bb5f..54a43d92 100644 --- a/src/Neo6/NDIS6.h +++ b/src/Neo6/NDIS6.h @@ -9,25 +9,37 @@ #define NDIS5_H // Win32 DDK related -#ifndef CPU_64 -#define _X86_ -#else // CPU_64 -#ifndef NEO_IA64 -#define _AMD64_ -#define AMD64 -#else // NEO_IA64 -#define _IA64_ -#define IA64 -#endif // NEO_IA64 -#endif // CPU_64 +#ifndef CPU_64 +#define _X86_ +#else // CPU_64 +#ifdef CPU_ARM64 +//#define _ARM64_ +//#define ARM64 +#elif defined(NEO_IA64) +#define _IA64_ +#define IA64 +#else +#define _AMD64_ +#define AMD64 +#endif +#endif // CPU_64 #define NDIS_MINIPORT_DRIVER -// NDIS 6.2 -#define NDIS620_MINIPORT -#define NDIS_SUPPORT_NDIS61 1 -#define NDIS_SUPPORT_NDIS620 1 -#define NEO_NDIS_MAJOR_VERSION 6 -#define NEO_NDIS_MINOR_VERSION 20 -#define NDIS_WDM 1 +#ifdef CPU_ARM64 + #define NDIS640_MINIPORT + #define NDIS_MINIPORT_MINIMUM_MAJOR_VERSION 6 + #define NDIS_MINIPORT_MINIMUM_MINOR_VERSION 40 + #define NEO_NDIS_MAJOR_VERSION 6 + #define NEO_NDIS_MINOR_VERSION 40 +#else + // NDIS 6.2 + #define NDIS620_MINIPORT + #define NDIS_SUPPORT_NDIS61 1 + #define NDIS_SUPPORT_NDIS620 1 + #define NEO_NDIS_MAJOR_VERSION 6 + #define NEO_NDIS_MINOR_VERSION 20 + #define NDIS_WDM 1 +#endif + #include #include diff --git a/src/Neo6/Neo6.vcxproj b/src/Neo6/Neo6.vcxproj new file mode 100644 index 00000000..0238edca --- /dev/null +++ b/src/Neo6/Neo6.vcxproj @@ -0,0 +1,107 @@ + + + + + Release + ARM64 + + + + 17.0 + {F7679B65-2FEC-469A-8BAC-B07BF4439422} + Neo6 + Win32Proj + + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + Neo6_arm64_unsigned + .sys + + + + + + + + + + + + + + + + <_ProjectFileVersion>17.0.36310.24 + + + $(Platform)_$(Configuration)\ + true + false + false + + + + + MaxSpeed + Default + false + Neither + false + $(ProjectDir)\..\;$(SolutionDir);%(AdditionalIncludeDirectories) + ARM64;_ARM64_;CPU_64;WIN32;CPU_ARM64;NDEBUG;_WINDOWS;_USRDLL;NEO_EXPORTS;VPN_SPEED;%(PreprocessorDefinitions) + false + + + MultiThreaded + 8Bytes + false + false + + + Level3 + ProgramDatabase + + CompileAsC + 4996;%(DisableSpecificWarnings) + + + + false + + + $(OutDir)Neo6_arm64_unsigned.sys + %(AdditionalLibraryDirectories) + ntoskrnl.lib;wdm.lib;hal.lib;;ucrt.lib;ndis.lib;wdmsec.lib;ntdll.lib;Kernel32.lib;fwpkclnt.lib;libcntpr.lib;%(AdditionalDependencies) + + MachineARM64 + + + + + + + + + + + + + + + + + + + \ No newline at end of file