mirror of
https://github.com/Nezumi-2711/winrar-keygen.git
synced 2026-09-22 13:48:33 +00:00
🐧 Cross-platform build support
This commit is contained in:
@@ -0,0 +1,129 @@
|
|||||||
|
name: Build All Platforms
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# --- Windows builds (MSBuild + vcpkg) ---
|
||||||
|
windows:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- platform: x64
|
||||||
|
artifact: winrar-keygen-x64
|
||||||
|
- platform: Win32
|
||||||
|
artifact: winrar-keygen-x86
|
||||||
|
- platform: ARM64
|
||||||
|
artifact: winrar-keygen-arm64
|
||||||
|
name: Windows ${{ matrix.platform }}
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v6.0.2
|
||||||
|
|
||||||
|
- name: Setup vcpkg
|
||||||
|
uses: lukka/run-vcpkg@v11
|
||||||
|
with:
|
||||||
|
vcpkgGitCommitId: 'a34c873a9717a888f58dc05268dea15592c2f0ff'
|
||||||
|
|
||||||
|
- name: Setup MSBuild
|
||||||
|
uses: microsoft/setup-msbuild@v2
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
msbuild winrar-keygen.sln /p:Configuration=Release /p:Platform=${{ matrix.platform }} /p:VcpkgEnableManifest=true
|
||||||
|
|
||||||
|
- name: Prepare artifact
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
$src = "bin/${{ matrix.platform }}-Release/winrar-keygen.exe"
|
||||||
|
Copy-Item $src "${{ matrix.artifact }}.exe"
|
||||||
|
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@v6.0.0
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.artifact }}
|
||||||
|
path: ${{ matrix.artifact }}.exe
|
||||||
|
|
||||||
|
# --- Linux x64 build (CMake) ---
|
||||||
|
linux-x64:
|
||||||
|
name: Linux x64
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v6.0.2
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y libgmp-dev
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -DCMAKE_BUILD_TYPE=Release
|
||||||
|
cmake --build . --config Release
|
||||||
|
|
||||||
|
- name: Prepare artifact
|
||||||
|
run: |
|
||||||
|
cp build/winrar-keygen winrar-keygen-linux-x64
|
||||||
|
chmod +x winrar-keygen-linux-x64
|
||||||
|
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@v6.0.0
|
||||||
|
with:
|
||||||
|
name: winrar-keygen-linux-x64
|
||||||
|
path: winrar-keygen-linux-x64
|
||||||
|
|
||||||
|
# --- Linux ARM64 build (native runner) ---
|
||||||
|
linux-arm64:
|
||||||
|
name: Linux ARM64
|
||||||
|
runs-on: ubuntu-24.04-arm
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v6.0.2
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y libgmp-dev
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -DCMAKE_BUILD_TYPE=Release
|
||||||
|
cmake --build . --config Release
|
||||||
|
|
||||||
|
- name: Prepare artifact
|
||||||
|
run: |
|
||||||
|
cp build/winrar-keygen winrar-keygen-linux-arm64
|
||||||
|
chmod +x winrar-keygen-linux-arm64
|
||||||
|
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@v6.0.0
|
||||||
|
with:
|
||||||
|
name: winrar-keygen-linux-arm64
|
||||||
|
path: winrar-keygen-linux-arm64
|
||||||
|
|
||||||
|
# --- macOS ARM64 build (CMake) ---
|
||||||
|
macos:
|
||||||
|
name: macOS ARM64
|
||||||
|
runs-on: macos-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v6.0.2
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: brew install gmp
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -DCMAKE_BUILD_TYPE=Release
|
||||||
|
cmake --build . --config Release
|
||||||
|
|
||||||
|
- name: Prepare artifact
|
||||||
|
run: |
|
||||||
|
cp build/winrar-keygen winrar-keygen-macos-arm64
|
||||||
|
chmod +x winrar-keygen-macos-arm64
|
||||||
|
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@v6.0.0
|
||||||
|
with:
|
||||||
|
name: winrar-keygen-macos-arm64
|
||||||
|
path: winrar-keygen-macos-arm64
|
||||||
+19
-2
@@ -1,7 +1,24 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable: 4146 4244 4267)
|
||||||
|
#endif
|
||||||
#include <gmp.h>
|
#include <gmp.h>
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// MPIR (used by vcpkg x86/x64) provides mpz_*_sx/mpz_*_ux for intmax_t.
|
||||||
|
// Standard GMP (used by ARM64 and Linux/macOS) does not; fall back to long variants.
|
||||||
|
#ifndef __MPIR_VERSION
|
||||||
|
#define mpz_init_set_sx(z, v) mpz_init_set_si((z), static_cast<long>(v))
|
||||||
|
#define mpz_init_set_ux(z, v) mpz_init_set_ui((z), static_cast<unsigned long>(v))
|
||||||
|
#define mpz_set_sx(z, v) mpz_set_si((z), static_cast<long>(v))
|
||||||
|
#define mpz_set_ux(z, v) mpz_set_ui((z), static_cast<unsigned long>(v))
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
@@ -300,11 +317,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TestBit(size_t i) const noexcept {
|
bool TestBit(size_t i) const noexcept {
|
||||||
return mpz_tstbit(_Value, i) != 0;
|
return mpz_tstbit(_Value, static_cast<mp_bitcnt_t>(i)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetBit(size_t i) noexcept {
|
void SetBit(size_t i) noexcept {
|
||||||
mpz_setbit(_Value, i);
|
mpz_setbit(_Value, static_cast<mp_bitcnt_t>(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ToString(size_t Base, bool LowerCase) const {
|
std::string ToString(size_t Base, bool LowerCase) const {
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
project(winrar-keygen LANGUAGES CXX)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
# Version
|
||||||
|
set(APP_VERSION "4.1.0.0")
|
||||||
|
|
||||||
|
add_executable(winrar-keygen
|
||||||
|
_tmain.cpp
|
||||||
|
BigInteger.hpp
|
||||||
|
EllipticCurveGF2m.hpp
|
||||||
|
GaloisField.hpp
|
||||||
|
Hasher.hpp
|
||||||
|
HasherCrc32Traits.hpp
|
||||||
|
HasherSha1Traits.hpp
|
||||||
|
WinRarConfig.hpp
|
||||||
|
WinRarKeygen.hpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_definitions(winrar-keygen PRIVATE
|
||||||
|
APP_VERSION="${APP_VERSION}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Find GMP
|
||||||
|
find_path(GMP_INCLUDE_DIR gmp.h REQUIRED)
|
||||||
|
target_include_directories(winrar-keygen PRIVATE ${GMP_INCLUDE_DIR})
|
||||||
|
|
||||||
|
# macOS Universal Binary support
|
||||||
|
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
|
||||||
|
message(STATUS "Building macOS Universal Binary: ${CMAKE_OSX_ARCHITECTURES}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Static linking on Linux for portable binaries
|
||||||
|
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||||
|
find_library(GMP_STATIC_LIBRARY libgmp.a)
|
||||||
|
if(GMP_STATIC_LIBRARY)
|
||||||
|
target_link_libraries(winrar-keygen PRIVATE ${GMP_STATIC_LIBRARY})
|
||||||
|
target_link_options(winrar-keygen PRIVATE -static-libgcc -static-libstdc++)
|
||||||
|
message(STATUS "Using static GMP: ${GMP_STATIC_LIBRARY}")
|
||||||
|
else()
|
||||||
|
find_library(GMP_LIBRARY gmp REQUIRED)
|
||||||
|
target_link_libraries(winrar-keygen PRIVATE ${GMP_LIBRARY})
|
||||||
|
message(STATUS "Using dynamic GMP: ${GMP_LIBRARY}")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
find_library(GMP_LIBRARY gmp REQUIRED)
|
||||||
|
target_link_libraries(winrar-keygen PRIVATE ${GMP_LIBRARY})
|
||||||
|
endif()
|
||||||
+135
-1
@@ -149,5 +149,139 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
#else
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
struct HasherSha1Traits {
|
||||||
|
public:
|
||||||
|
static constexpr size_t BlockSize = 512 / 8;
|
||||||
|
static constexpr size_t DigestSize = 160 / 8;
|
||||||
|
|
||||||
|
struct DigestType {
|
||||||
|
uint8_t Bytes[DigestSize];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ContextType {
|
||||||
|
uint32_t State[5];
|
||||||
|
uint64_t Count;
|
||||||
|
uint8_t Buffer[64];
|
||||||
|
|
||||||
|
ContextType() noexcept : State{}, Count(0), Buffer{} {}
|
||||||
|
ContextType(const ContextType&) noexcept = default;
|
||||||
|
ContextType& operator=(const ContextType&) noexcept = default;
|
||||||
|
ContextType(ContextType&& Other) noexcept = default;
|
||||||
|
ContextType& operator=(ContextType&& Other) noexcept = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
static inline uint32_t RotateLeft(uint32_t x, int n) noexcept {
|
||||||
|
return (x << n) | (x >> (32 - n));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ProcessBlock(uint32_t state[5], const uint8_t block[64]) noexcept {
|
||||||
|
uint32_t w[80];
|
||||||
|
for (int i = 0; i < 16; ++i) {
|
||||||
|
w[i] = (static_cast<uint32_t>(block[i * 4]) << 24) |
|
||||||
|
(static_cast<uint32_t>(block[i * 4 + 1]) << 16) |
|
||||||
|
(static_cast<uint32_t>(block[i * 4 + 2]) << 8) |
|
||||||
|
(static_cast<uint32_t>(block[i * 4 + 3]));
|
||||||
|
}
|
||||||
|
for (int i = 16; i < 80; ++i) {
|
||||||
|
w[i] = RotateLeft(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
|
||||||
|
for (int i = 0; i < 80; ++i) {
|
||||||
|
uint32_t f, k;
|
||||||
|
if (i < 20) { f = (b & c) | (~b & d); k = 0x5A827999; }
|
||||||
|
else if (i < 40) { f = b ^ c ^ d; k = 0x6ED9EBA1; }
|
||||||
|
else if (i < 60) { f = (b & c) | (b & d) | (c & d); k = 0x8F1BBCDC; }
|
||||||
|
else { f = b ^ c ^ d; k = 0xCA62C1D6; }
|
||||||
|
uint32_t temp = RotateLeft(a, 5) + f + e + k + w[i];
|
||||||
|
e = d; d = c; c = RotateLeft(b, 30); b = a; a = temp;
|
||||||
|
}
|
||||||
|
state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static inline ContextType ContextCreate() {
|
||||||
|
ContextType Ctx;
|
||||||
|
Ctx.State[0] = 0x67452301;
|
||||||
|
Ctx.State[1] = 0xEFCDAB89;
|
||||||
|
Ctx.State[2] = 0x98BADCFE;
|
||||||
|
Ctx.State[3] = 0x10325476;
|
||||||
|
Ctx.State[4] = 0xC3D2E1F0;
|
||||||
|
Ctx.Count = 0;
|
||||||
|
return Ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline ContextType ContextCreate(const void* lpBuffer, size_t cbBuffer) {
|
||||||
|
ContextType Ctx = ContextCreate();
|
||||||
|
ContextUpdate(Ctx, lpBuffer, cbBuffer);
|
||||||
|
return Ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline ContextType ContextCopy(const ContextType& Ctx) {
|
||||||
|
return Ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ContextUpdate(ContextType& Ctx, const void* lpBuffer, size_t cbBuffer) {
|
||||||
|
auto data = reinterpret_cast<const uint8_t*>(lpBuffer);
|
||||||
|
size_t bufferOffset = static_cast<size_t>(Ctx.Count % 64);
|
||||||
|
Ctx.Count += cbBuffer;
|
||||||
|
|
||||||
|
if (bufferOffset > 0) {
|
||||||
|
size_t toCopy = 64 - bufferOffset;
|
||||||
|
if (toCopy > cbBuffer) toCopy = cbBuffer;
|
||||||
|
std::memcpy(Ctx.Buffer + bufferOffset, data, toCopy);
|
||||||
|
data += toCopy;
|
||||||
|
cbBuffer -= toCopy;
|
||||||
|
bufferOffset += toCopy;
|
||||||
|
if (bufferOffset == 64) {
|
||||||
|
ProcessBlock(Ctx.State, Ctx.Buffer);
|
||||||
|
bufferOffset = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (cbBuffer >= 64) {
|
||||||
|
ProcessBlock(Ctx.State, data);
|
||||||
|
data += 64;
|
||||||
|
cbBuffer -= 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cbBuffer > 0) {
|
||||||
|
std::memcpy(Ctx.Buffer, data, cbBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ContextEvaluate(const ContextType& Ctx, DigestType& Digest) {
|
||||||
|
ContextType tmp = Ctx;
|
||||||
|
uint64_t totalBits = tmp.Count * 8;
|
||||||
|
uint8_t pad = 0x80;
|
||||||
|
ContextUpdate(tmp, &pad, 1);
|
||||||
|
uint8_t zero = 0;
|
||||||
|
while (tmp.Count % 64 != 56) {
|
||||||
|
ContextUpdate(tmp, &zero, 1);
|
||||||
|
}
|
||||||
|
uint8_t lenBytes[8];
|
||||||
|
for (int i = 7; i >= 0; --i) {
|
||||||
|
lenBytes[i] = static_cast<uint8_t>(totalBits);
|
||||||
|
totalBits >>= 8;
|
||||||
|
}
|
||||||
|
ContextUpdate(tmp, lenBytes, 8);
|
||||||
|
for (int i = 0; i < 5; ++i) {
|
||||||
|
Digest.Bytes[i * 4] = static_cast<uint8_t>(tmp.State[i] >> 24);
|
||||||
|
Digest.Bytes[i * 4 + 1] = static_cast<uint8_t>(tmp.State[i] >> 16);
|
||||||
|
Digest.Bytes[i * 4 + 2] = static_cast<uint8_t>(tmp.State[i] >> 8);
|
||||||
|
Digest.Bytes[i * 4 + 3] = static_cast<uint8_t>(tmp.State[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ContextDestroy(ContextType& Ctx) noexcept {
|
||||||
|
std::memset(&Ctx, 0, sizeof(Ctx));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
+9
-3
@@ -9,6 +9,12 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define BSWAP32(x) _byteswap_ulong(x)
|
||||||
|
#else
|
||||||
|
#define BSWAP32(x) __builtin_bswap32(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename __ConfigType>
|
template<typename __ConfigType>
|
||||||
class WinRarKeygen {
|
class WinRarKeygen {
|
||||||
public:
|
public:
|
||||||
@@ -40,7 +46,7 @@ private:
|
|||||||
Sha1Digest = Sha1.Evaluate();
|
Sha1Digest = Sha1.Evaluate();
|
||||||
|
|
||||||
for (unsigned i = 0; i < 5; ++i) {
|
for (unsigned i = 0; i < 5; ++i) {
|
||||||
Generator[i + 1] = _byteswap_ulong(reinterpret_cast<uint32_t*>(Sha1Digest.Bytes)[i]);
|
Generator[i + 1] = BSWAP32(reinterpret_cast<uint32_t*>(Sha1Digest.Bytes)[i]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Generator[1] = 0xeb3eb781;
|
Generator[1] = 0xeb3eb781;
|
||||||
@@ -59,7 +65,7 @@ private:
|
|||||||
Sha1Digest = Sha1.Evaluate();
|
Sha1Digest = Sha1.Evaluate();
|
||||||
|
|
||||||
RawPrivateKey[i] = static_cast<uint16_t>(
|
RawPrivateKey[i] = static_cast<uint16_t>(
|
||||||
_byteswap_ulong(reinterpret_cast<uint32_t*>(Sha1Digest.Bytes)[0])
|
BSWAP32(reinterpret_cast<uint32_t*>(Sha1Digest.Bytes)[0])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,7 +118,7 @@ private:
|
|||||||
HasherSha1Traits::DigestType Sha1Digest = Sha1.Evaluate();
|
HasherSha1Traits::DigestType Sha1Digest = Sha1.Evaluate();
|
||||||
|
|
||||||
for (size_t i = 0; i < 5; ++i) {
|
for (size_t i = 0; i < 5; ++i) {
|
||||||
RawHash[i] = _byteswap_ulong(reinterpret_cast<uint32_t*>(Sha1Digest.Bytes)[i]);
|
RawHash[i] = BSWAP32(reinterpret_cast<uint32_t*>(Sha1Digest.Bytes)[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SHA1("") with all-zeroed initial value
|
// SHA1("") with all-zeroed initial value
|
||||||
|
|||||||
+470
-7
@@ -1,17 +1,35 @@
|
|||||||
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <winhttp.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
#else
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <codecvt>
|
|
||||||
#include "WinRarConfig.hpp"
|
#include "WinRarConfig.hpp"
|
||||||
#include "WinRarKeygen.hpp"
|
#include "WinRarKeygen.hpp"
|
||||||
#include <system_error>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
#pragma comment(lib, "Version.lib")
|
#pragma comment(lib, "Version.lib")
|
||||||
|
#pragma comment(lib, "winhttp.lib")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef APP_VERSION
|
||||||
|
#define APP_VERSION "4.1.0.0"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
std::string WideToUtf8(const std::wstring& wstr) {
|
std::string WideToUtf8(const std::wstring& wstr) {
|
||||||
if (wstr.empty()) return {};
|
if (wstr.empty()) return {};
|
||||||
int size = WideCharToMultiByte(CP_UTF8, 0, wstr.data(), (int)wstr.size(), nullptr, 0, nullptr, nullptr);
|
int size = WideCharToMultiByte(CP_UTF8, 0, wstr.data(), (int)wstr.size(), nullptr, 0, nullptr, nullptr);
|
||||||
@@ -43,20 +61,30 @@ std::string WideToAnsi(const std::wstring& wstr) {
|
|||||||
&result[0], size, nullptr, nullptr);
|
&result[0], size, nullptr, nullptr);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
enum class Encoding { ASCII, ANSI, UTF8 };
|
enum class Encoding { ASCII, ANSI, UTF8 };
|
||||||
|
|
||||||
struct Options {
|
struct Options {
|
||||||
|
#ifdef _WIN32
|
||||||
std::wstring username;
|
std::wstring username;
|
||||||
std::wstring license;
|
std::wstring license;
|
||||||
Encoding encoding = Encoding::UTF8;
|
Encoding encoding = Encoding::UTF8;
|
||||||
std::wstring outputFile = L"rarreg.key";
|
std::wstring outputFile = L"rarreg.key";
|
||||||
|
#else
|
||||||
|
std::string username;
|
||||||
|
std::string license;
|
||||||
|
Encoding encoding = Encoding::UTF8;
|
||||||
|
std::string outputFile = "rarreg.key";
|
||||||
|
#endif
|
||||||
bool textOnly = false;
|
bool textOnly = false;
|
||||||
bool activate = false;
|
bool activate = false;
|
||||||
bool showVersion = false;
|
bool showVersion = false;
|
||||||
bool showHelp = false;
|
bool showHelp = false;
|
||||||
|
bool checkUpdate = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
bool ParseArguments(int argc, wchar_t* argv[], Options& opts) {
|
bool ParseArguments(int argc, wchar_t* argv[], Options& opts) {
|
||||||
std::vector<std::wstring> positional;
|
std::vector<std::wstring> positional;
|
||||||
for (int i = 1; i < argc; ++i) {
|
for (int i = 1; i < argc; ++i) {
|
||||||
@@ -73,6 +101,9 @@ bool ParseArguments(int argc, wchar_t* argv[], Options& opts) {
|
|||||||
if (arg == L"-a" || arg == L"--activate") {
|
if (arg == L"-a" || arg == L"--activate") {
|
||||||
opts.activate = true; continue;
|
opts.activate = true; continue;
|
||||||
}
|
}
|
||||||
|
if (arg == L"-u" || arg == L"--update") {
|
||||||
|
opts.checkUpdate = true; return true;
|
||||||
|
}
|
||||||
if (arg == L"-e" || arg == L"--encoding") {
|
if (arg == L"-e" || arg == L"--encoding") {
|
||||||
if (++i >= argc) {
|
if (++i >= argc) {
|
||||||
std::wcerr << L"Error: Missing value for " << arg << L"\n";
|
std::wcerr << L"Error: Missing value for " << arg << L"\n";
|
||||||
@@ -114,7 +145,70 @@ bool ParseArguments(int argc, wchar_t* argv[], Options& opts) {
|
|||||||
<< positional.size() << L"\n";
|
<< positional.size() << L"\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
bool ParseArguments(int argc, char* argv[], Options& opts) {
|
||||||
|
std::vector<std::string> positional;
|
||||||
|
for (int i = 1; i < argc; ++i) {
|
||||||
|
std::string arg = argv[i];
|
||||||
|
if (arg == "-v" || arg == "--version" || strcasecmp(arg.c_str(), "ver") == 0) {
|
||||||
|
opts.showVersion = true; return true;
|
||||||
|
}
|
||||||
|
if (arg == "-h" || arg == "--help" || strcasecmp(arg.c_str(), "help") == 0) {
|
||||||
|
opts.showHelp = true; return true;
|
||||||
|
}
|
||||||
|
if (arg == "-t" || arg == "--text") {
|
||||||
|
opts.textOnly = true; continue;
|
||||||
|
}
|
||||||
|
if (arg == "-a" || arg == "--activate") {
|
||||||
|
opts.activate = true; continue;
|
||||||
|
}
|
||||||
|
if (arg == "-u" || arg == "--update") {
|
||||||
|
opts.checkUpdate = true; return true;
|
||||||
|
}
|
||||||
|
if (arg == "-e" || arg == "--encoding") {
|
||||||
|
if (++i >= argc) {
|
||||||
|
std::cerr << "Error: Missing value for " << arg << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::string val = argv[i];
|
||||||
|
if (strcasecmp(val.c_str(), "ascii") == 0) opts.encoding = Encoding::ASCII;
|
||||||
|
else if (strcasecmp(val.c_str(), "ansi") == 0) opts.encoding = Encoding::ANSI;
|
||||||
|
else if (strcasecmp(val.c_str(), "utf8") == 0 || strcasecmp(val.c_str(), "utf-8") == 0)
|
||||||
|
opts.encoding = Encoding::UTF8;
|
||||||
|
else {
|
||||||
|
std::cerr << "Error: Unknown encoding '" << val << "'. Use: ascii, ansi, utf8\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (arg == "-o" || arg == "--output") {
|
||||||
|
if (++i >= argc) {
|
||||||
|
std::cerr << "Error: Missing value for " << arg << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
opts.outputFile = argv[i]; continue;
|
||||||
|
}
|
||||||
|
if (!arg.empty() && arg[0] == '-') {
|
||||||
|
std::cerr << "Error: Unknown option '" << arg << "'\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
positional.push_back(arg);
|
||||||
|
}
|
||||||
|
if (positional.size() == 2) {
|
||||||
|
opts.username = positional[0];
|
||||||
|
opts.license = positional[1];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (positional.empty()) {
|
||||||
|
opts.showHelp = true; return true;
|
||||||
|
}
|
||||||
|
std::cerr << "Error: Expected 2 arguments (Username, LicenseName), got "
|
||||||
|
<< positional.size() << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
void ShowHelp(const std::wstring& version) {
|
void ShowHelp(const std::wstring& version) {
|
||||||
std::wcout << L"WinRAR Keygen v" << version << L"\n\n";
|
std::wcout << L"WinRAR Keygen v" << version << L"\n\n";
|
||||||
std::wcout << L"Usage:\n";
|
std::wcout << L"Usage:\n";
|
||||||
@@ -126,17 +220,43 @@ void ShowHelp(const std::wstring& version) {
|
|||||||
std::wcout << L" -o, --output <file> Output file (default: rarreg.key)\n";
|
std::wcout << L" -o, --output <file> Output file (default: rarreg.key)\n";
|
||||||
std::wcout << L" -a, --activate Write to %APPDATA%\\WinRAR\\rarreg.key\n";
|
std::wcout << L" -a, --activate Write to %APPDATA%\\WinRAR\\rarreg.key\n";
|
||||||
std::wcout << L" -t, --text Print to console only, don't write file\n";
|
std::wcout << L" -t, --text Print to console only, don't write file\n";
|
||||||
|
std::wcout << L" -u, --update Check for updates on GitHub\n";
|
||||||
std::wcout << L" -v, --version Show version\n";
|
std::wcout << L" -v, --version Show version\n";
|
||||||
std::wcout << L" -h, --help Show this help\n\n";
|
std::wcout << L" -h, --help Show this help\n\n";
|
||||||
std::wcout << L"Examples:\n";
|
std::wcout << L"Examples:\n";
|
||||||
std::wcout << L" winrar-keygen.exe \"Github\" \"Single PC usage license\"\n";
|
std::wcout << L" winrar-keygen.exe \"Github\" \"Single PC usage license\"\n";
|
||||||
std::wcout << L" winrar-keygen.exe \"Github\" \"Single PC usage license\" -e ansi\n";
|
std::wcout << L" winrar-keygen.exe \"Github\" \"Single PC usage license\" -e ascii\n";
|
||||||
std::wcout << L" winrar-keygen.exe \"YourName\" \"Single PC usage license\" -e utf8\n";
|
std::wcout << L" winrar-keygen.exe \"Github\" \"Single PC usage license\" -a\n";
|
||||||
std::wcout << L" winrar-keygen.exe \"Github\" \"Single PC usage license\" -o \"D:\\keys\\rarreg.key\"\n";
|
|
||||||
std::wcout << L" winrar-keygen.exe \"Github\" \"Single PC usage license\" --activate\n";
|
|
||||||
std::wcout << L" winrar-keygen.exe \"Github\" \"Single PC usage license\" -t\n";
|
std::wcout << L" winrar-keygen.exe \"Github\" \"Single PC usage license\" -t\n";
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
void ShowHelp(const std::string& version) {
|
||||||
|
std::cout << "WinRAR Keygen v" << version << "\n\n";
|
||||||
|
std::cout << "Usage:\n";
|
||||||
|
std::cout << " winrar-keygen <Username> <LicenseName> [options]\n";
|
||||||
|
std::cout << " winrar-keygen -v | --version\n";
|
||||||
|
std::cout << " winrar-keygen -h | --help\n\n";
|
||||||
|
std::cout << "Options:\n";
|
||||||
|
std::cout << " -e, --encoding <enc> utf8 (default), ascii\n";
|
||||||
|
std::cout << " -o, --output <file> Output file (default: rarreg.key)\n";
|
||||||
|
#ifdef __APPLE__
|
||||||
|
std::cout << " -a, --activate Write to ~/Library/Application Support/com.rarlab.WinRAR/rarreg.key\n";
|
||||||
|
#else
|
||||||
|
std::cout << " -a, --activate Write to ~/.rarkey\n";
|
||||||
|
#endif
|
||||||
|
std::cout << " -t, --text Print to console only, don't write file\n";
|
||||||
|
std::cout << " -u, --update Check for updates on GitHub\n";
|
||||||
|
std::cout << " -v, --version Show version\n";
|
||||||
|
std::cout << " -h, --help Show this help\n\n";
|
||||||
|
std::cout << "Examples:\n";
|
||||||
|
std::cout << " winrar-keygen \"Github\" \"Single PC usage license\"\n";
|
||||||
|
std::cout << " winrar-keygen \"Github\" \"Single PC usage license\" -e ascii\n";
|
||||||
|
std::cout << " winrar-keygen \"Github\" \"Single PC usage license\" -a\n";
|
||||||
|
std::cout << " winrar-keygen \"Github\" \"Single PC usage license\" -t\n";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
std::wstring GetExecutableVersion() {
|
std::wstring GetExecutableVersion() {
|
||||||
wchar_t exePath[MAX_PATH] = {};
|
wchar_t exePath[MAX_PATH] = {};
|
||||||
DWORD pathLen = GetModuleFileNameW(nullptr, exePath, MAX_PATH);
|
DWORD pathLen = GetModuleFileNameW(nullptr, exePath, MAX_PATH);
|
||||||
@@ -169,7 +289,13 @@ std::wstring GetExecutableVersion() {
|
|||||||
std::to_wstring(HIWORD(fixedInfo->dwFileVersionLS)) + L"." +
|
std::to_wstring(HIWORD(fixedInfo->dwFileVersionLS)) + L"." +
|
||||||
std::to_wstring(LOWORD(fixedInfo->dwFileVersionLS));
|
std::to_wstring(LOWORD(fixedInfo->dwFileVersionLS));
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
std::string GetAppVersion() {
|
||||||
|
return APP_VERSION;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
void PrintRegisterInfo(const WinRarKeygen<WinRarConfig>::RegisterInfo& Info,
|
void PrintRegisterInfo(const WinRarKeygen<WinRarConfig>::RegisterInfo& Info,
|
||||||
const std::wstring& wUser, const std::wstring& wLicense) {
|
const std::wstring& wUser, const std::wstring& wLicense) {
|
||||||
std::wstring uid = Utf8ToWide(Info.UID);
|
std::wstring uid = Utf8ToWide(Info.UID);
|
||||||
@@ -184,6 +310,19 @@ void PrintRegisterInfo(const WinRarKeygen<WinRarConfig>::RegisterInfo& Info,
|
|||||||
std::wcout << data.substr(i, 54) << L"\n";
|
std::wcout << data.substr(i, 54) << L"\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
void PrintRegisterInfo(const WinRarKeygen<WinRarConfig>::RegisterInfo& Info,
|
||||||
|
const std::string& user, const std::string& license) {
|
||||||
|
std::cout << "RAR registration data\n";
|
||||||
|
std::cout << user << "\n";
|
||||||
|
std::cout << license << "\n";
|
||||||
|
std::cout << "UID=" << Info.UID << "\n";
|
||||||
|
|
||||||
|
for (size_t i = 0; i < Info.HexData.length(); i += 54) {
|
||||||
|
std::cout << Info.HexData.substr(i, 54) << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
std::string BuildRegFileContent(const WinRarKeygen<WinRarConfig>::RegisterInfo& Info) {
|
std::string BuildRegFileContent(const WinRarKeygen<WinRarConfig>::RegisterInfo& Info) {
|
||||||
std::string s;
|
std::string s;
|
||||||
@@ -197,6 +336,7 @@ std::string BuildRegFileContent(const WinRarKeygen<WinRarConfig>::RegisterInfo&
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
bool WriteRegFile(const std::wstring& filePath, const std::string& content) {
|
bool WriteRegFile(const std::wstring& filePath, const std::string& content) {
|
||||||
FILE* fp = nullptr;
|
FILE* fp = nullptr;
|
||||||
if (_wfopen_s(&fp, filePath.c_str(), L"wb") != 0 || !fp)
|
if (_wfopen_s(&fp, filePath.c_str(), L"wb") != 0 || !fp)
|
||||||
@@ -205,7 +345,17 @@ bool WriteRegFile(const std::wstring& filePath, const std::string& content) {
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
return written == content.size();
|
return written == content.size();
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
bool WriteRegFile(const std::string& filePath, const std::string& content) {
|
||||||
|
FILE* fp = fopen(filePath.c_str(), "wb");
|
||||||
|
if (!fp) return false;
|
||||||
|
size_t written = fwrite(content.data(), 1, content.size(), fp);
|
||||||
|
fclose(fp);
|
||||||
|
return written == content.size();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
bool IsConsoleHandle(HANDLE handle) {
|
bool IsConsoleHandle(HANDLE handle) {
|
||||||
if (handle == nullptr || handle == INVALID_HANDLE_VALUE) {
|
if (handle == nullptr || handle == INVALID_HANDLE_VALUE) {
|
||||||
return false;
|
return false;
|
||||||
@@ -238,7 +388,187 @@ void ConfigureConsoleOutput() {
|
|||||||
std::wcerr << L"Failed to set stderr _O_U8TEXT\n";
|
std::wcerr << L"Failed to set stderr _O_U8TEXT\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct Version {
|
||||||
|
int major = 0, minor = 0, patch = 0;
|
||||||
|
bool valid = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Version ParseVersion(const std::string& verStr) {
|
||||||
|
Version v;
|
||||||
|
std::string s = verStr;
|
||||||
|
if (!s.empty() && (s[0] == 'v' || s[0] == 'V')) s = s.substr(1);
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
int count = sscanf_s(s.c_str(), "%d.%d.%d", &v.major, &v.minor, &v.patch);
|
||||||
|
#else
|
||||||
|
int count = sscanf(s.c_str(), "%d.%d.%d", &v.major, &v.minor, &v.patch);
|
||||||
|
#endif
|
||||||
|
v.valid = (count >= 2);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsNewer(const Version& remote, const Version& local) {
|
||||||
|
if (remote.major != local.major) return remote.major > local.major;
|
||||||
|
if (remote.minor != local.minor) return remote.minor > local.minor;
|
||||||
|
return remote.patch > local.patch;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ExtractTagFromJson(const std::string& responseBody) {
|
||||||
|
std::string tagKey = "\"tag_name\"";
|
||||||
|
size_t pos = responseBody.find(tagKey);
|
||||||
|
if (pos == std::string::npos) return "";
|
||||||
|
pos = responseBody.find('\"', pos + tagKey.length());
|
||||||
|
if (pos == std::string::npos) return "";
|
||||||
|
size_t end = responseBody.find('\"', pos + 1);
|
||||||
|
if (end == std::string::npos) return "";
|
||||||
|
return responseBody.substr(pos + 1, end - pos - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CompareAndPrintUpdate(const std::string& currentVersion, const std::string& remoteTag) {
|
||||||
|
Version local = ParseVersion(currentVersion);
|
||||||
|
Version remote = ParseVersion(remoteTag);
|
||||||
|
|
||||||
|
if (!remote.valid) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
std::wcerr << L"Error: Could not parse remote version '" << Utf8ToWide(remoteTag) << L"'.\n";
|
||||||
|
#else
|
||||||
|
std::cerr << "Error: Could not parse remote version '" << remoteTag << "'.\n";
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsNewer(remote, local)) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
std::wcout << L"\n New version available: " << Utf8ToWide(remoteTag)
|
||||||
|
<< L" (current: v" << Utf8ToWide(currentVersion) << L")\n";
|
||||||
|
std::wcout << L" Download: https://github.com/bitcookies/winrar-keygen/releases/latest\n\n";
|
||||||
|
#else
|
||||||
|
std::cout << "\n New version available: " << remoteTag
|
||||||
|
<< " (current: v" << currentVersion << ")\n";
|
||||||
|
std::cout << " Download: https://github.com/bitcookies/winrar-keygen/releases/latest\n\n";
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
#ifdef _WIN32
|
||||||
|
std::wcout << L"Already up to date. (v" << Utf8ToWide(currentVersion) << L")\n";
|
||||||
|
#else
|
||||||
|
std::cout << "Already up to date. (v" << currentVersion << ")\n";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
int CheckForUpdate(const std::string& currentVersion) {
|
||||||
|
std::wcout << L"Checking for updates...\n";
|
||||||
|
|
||||||
|
HINTERNET hSession = WinHttpOpen(L"winrar-keygen-updater",
|
||||||
|
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
|
||||||
|
if (!hSession) {
|
||||||
|
std::wcerr << L"Error: Failed to initialize WinHTTP.\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
HINTERNET hConnect = WinHttpConnect(hSession, L"api.github.com",
|
||||||
|
INTERNET_DEFAULT_HTTPS_PORT, 0);
|
||||||
|
if (!hConnect) {
|
||||||
|
std::wcerr << L"Error: Failed to connect to api.github.com.\n";
|
||||||
|
WinHttpCloseHandle(hSession);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"GET",
|
||||||
|
L"/repos/bitcookies/winrar-keygen/releases/latest",
|
||||||
|
nullptr, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
|
||||||
|
if (!hRequest) {
|
||||||
|
std::wcerr << L"Error: Failed to create HTTP request.\n";
|
||||||
|
WinHttpCloseHandle(hConnect);
|
||||||
|
WinHttpCloseHandle(hSession);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL bResult = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0,
|
||||||
|
WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
|
||||||
|
if (!bResult) {
|
||||||
|
std::wcerr << L"Error: Failed to send HTTP request. Check your network connection.\n";
|
||||||
|
WinHttpCloseHandle(hRequest);
|
||||||
|
WinHttpCloseHandle(hConnect);
|
||||||
|
WinHttpCloseHandle(hSession);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bResult = WinHttpReceiveResponse(hRequest, nullptr);
|
||||||
|
if (!bResult) {
|
||||||
|
std::wcerr << L"Error: No response from GitHub API.\n";
|
||||||
|
WinHttpCloseHandle(hRequest);
|
||||||
|
WinHttpCloseHandle(hConnect);
|
||||||
|
WinHttpCloseHandle(hSession);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string responseBody;
|
||||||
|
DWORD dwSize = 0;
|
||||||
|
DWORD dwDownloaded = 0;
|
||||||
|
do {
|
||||||
|
dwSize = 0;
|
||||||
|
WinHttpQueryDataAvailable(hRequest, &dwSize);
|
||||||
|
if (dwSize == 0) break;
|
||||||
|
std::vector<char> buffer(dwSize);
|
||||||
|
WinHttpReadData(hRequest, buffer.data(), dwSize, &dwDownloaded);
|
||||||
|
responseBody.append(buffer.data(), dwDownloaded);
|
||||||
|
} while (dwSize > 0);
|
||||||
|
|
||||||
|
WinHttpCloseHandle(hRequest);
|
||||||
|
WinHttpCloseHandle(hConnect);
|
||||||
|
WinHttpCloseHandle(hSession);
|
||||||
|
|
||||||
|
if (responseBody.empty()) {
|
||||||
|
std::wcerr << L"Error: Empty response from GitHub API.\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string remoteTag = ExtractTagFromJson(responseBody);
|
||||||
|
if (remoteTag.empty()) {
|
||||||
|
std::wcerr << L"Error: Could not find version info in GitHub response.\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CompareAndPrintUpdate(currentVersion, remoteTag);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int CheckForUpdate(const std::string& currentVersion) {
|
||||||
|
std::cout << "Checking for updates...\n";
|
||||||
|
|
||||||
|
FILE* pipe = popen("curl -s https://api.github.com/repos/bitcookies/winrar-keygen/releases/latest 2>/dev/null", "r");
|
||||||
|
if (!pipe) {
|
||||||
|
std::cerr << "Error: Failed to run curl. Make sure curl is installed.\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string responseBody;
|
||||||
|
char buf[4096];
|
||||||
|
while (fgets(buf, sizeof(buf), pipe)) {
|
||||||
|
responseBody += buf;
|
||||||
|
}
|
||||||
|
int status = pclose(pipe);
|
||||||
|
|
||||||
|
if (status != 0 || responseBody.empty()) {
|
||||||
|
std::cerr << "Error: Failed to fetch update info. Check your network connection.\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string remoteTag = ExtractTagFromJson(responseBody);
|
||||||
|
if (remoteTag.empty()) {
|
||||||
|
std::cerr << "Error: Could not find version info in GitHub response.\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CompareAndPrintUpdate(currentVersion, remoteTag);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
int wmain(int argc, wchar_t* argv[]) {
|
int wmain(int argc, wchar_t* argv[]) {
|
||||||
ConfigureConsoleOutput();
|
ConfigureConsoleOutput();
|
||||||
|
|
||||||
@@ -248,6 +578,7 @@ int wmain(int argc, wchar_t* argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::wstring version = GetExecutableVersion();
|
std::wstring version = GetExecutableVersion();
|
||||||
|
std::string versionUtf8 = WideToUtf8(version);
|
||||||
|
|
||||||
if (opts.showVersion) {
|
if (opts.showVersion) {
|
||||||
std::wcout << L"winrar-keygen v" << version << L"\n";
|
std::wcout << L"winrar-keygen v" << version << L"\n";
|
||||||
@@ -257,6 +588,9 @@ int wmain(int argc, wchar_t* argv[]) {
|
|||||||
ShowHelp(version);
|
ShowHelp(version);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (opts.checkUpdate) {
|
||||||
|
return CheckForUpdate(versionUtf8);
|
||||||
|
}
|
||||||
|
|
||||||
if (opts.activate && opts.outputFile != L"rarreg.key") {
|
if (opts.activate && opts.outputFile != L"rarreg.key") {
|
||||||
std::wcerr << L"Error: --activate and -o cannot be used together.\n";
|
std::wcerr << L"Error: --activate and -o cannot be used together.\n";
|
||||||
@@ -271,7 +605,7 @@ int wmain(int argc, wchar_t* argv[]) {
|
|||||||
wchar_t appdata[MAX_PATH] = {};
|
wchar_t appdata[MAX_PATH] = {};
|
||||||
DWORD len = ExpandEnvironmentStringsW(L"%APPDATA%\\WinRAR", appdata, MAX_PATH);
|
DWORD len = ExpandEnvironmentStringsW(L"%APPDATA%\\WinRAR", appdata, MAX_PATH);
|
||||||
if (len == 0 || len > MAX_PATH) {
|
if (len == 0 || len > MAX_PATH) {
|
||||||
std::wcerr << L"Error: Failed to resolve %%APPDATA%% path.\n";
|
std::wcerr << L"Error: Failed to resolve %APPDATA% path.\n";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
CreateDirectoryW(appdata, nullptr);
|
CreateDirectoryW(appdata, nullptr);
|
||||||
@@ -355,3 +689,132 @@ int wmain(int argc, wchar_t* argv[]) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
Options opts;
|
||||||
|
if (!ParseArguments(argc, argv, opts)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string version = GetAppVersion();
|
||||||
|
|
||||||
|
if (opts.showVersion) {
|
||||||
|
std::cout << "winrar-keygen v" << version << "\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (opts.showHelp) {
|
||||||
|
ShowHelp(version);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (opts.checkUpdate) {
|
||||||
|
return CheckForUpdate(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts.activate && opts.outputFile != "rarreg.key") {
|
||||||
|
std::cerr << "Error: --activate and -o cannot be used together.\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (opts.activate && opts.textOnly) {
|
||||||
|
std::cerr << "Error: --activate and -t cannot be used together.\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts.activate) {
|
||||||
|
#ifdef __APPLE__
|
||||||
|
const char* home = getenv("HOME");
|
||||||
|
if (!home) {
|
||||||
|
std::cerr << "Error: Failed to resolve $HOME path.\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
std::string activateDir = std::string(home) + "/Library/Application Support/com.rarlab.WinRAR";
|
||||||
|
mkdir(activateDir.c_str(), 0755);
|
||||||
|
opts.outputFile = activateDir + "/rarreg.key";
|
||||||
|
#else
|
||||||
|
const char* home = getenv("HOME");
|
||||||
|
if (!home) {
|
||||||
|
std::cerr << "Error: Failed to resolve $HOME path.\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
opts.outputFile = std::string(home) + "/.rarkey";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (opts.username.empty() || opts.license.empty()) {
|
||||||
|
std::cerr << "Error: Username and License Name must not be empty.\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (opts.username.length() > 200 || opts.license.length() > 200) {
|
||||||
|
std::cerr << "Error: Username and License Name must not exceed 200 characters.\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string displayUser = opts.username;
|
||||||
|
std::string displayLicense = opts.license;
|
||||||
|
std::string user, license;
|
||||||
|
|
||||||
|
switch (opts.encoding) {
|
||||||
|
case Encoding::UTF8: {
|
||||||
|
auto hasNonAscii = [](const std::string& s) {
|
||||||
|
for (unsigned char c : s)
|
||||||
|
if (c > 127) return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
if (hasNonAscii(displayUser) &&
|
||||||
|
(displayUser.length() < 5 || displayUser.substr(0, 5) != "utf8:"))
|
||||||
|
displayUser = "utf8:" + displayUser;
|
||||||
|
if (hasNonAscii(displayLicense) &&
|
||||||
|
(displayLicense.length() < 5 || displayLicense.substr(0, 5) != "utf8:"))
|
||||||
|
displayLicense = "utf8:" + displayLicense;
|
||||||
|
user = displayUser;
|
||||||
|
license = displayLicense;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Encoding::ANSI:
|
||||||
|
std::cerr << "Warning: ANSI encoding is not supported on this platform. Using UTF-8.\n";
|
||||||
|
user = displayUser;
|
||||||
|
license = displayLicense;
|
||||||
|
break;
|
||||||
|
case Encoding::ASCII:
|
||||||
|
default:
|
||||||
|
user = displayUser;
|
||||||
|
license = displayLicense;
|
||||||
|
for (unsigned char c : user)
|
||||||
|
if (c > 127)
|
||||||
|
throw std::runtime_error(
|
||||||
|
"Username contains non-ASCII characters. Use '-e utf8'.");
|
||||||
|
for (unsigned char c : license)
|
||||||
|
if (c > 127)
|
||||||
|
throw std::runtime_error(
|
||||||
|
"License name contains non-ASCII characters. Use '-e utf8'.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Info = WinRarKeygen<WinRarConfig>::GenerateRegisterInfo(user.c_str(), license.c_str());
|
||||||
|
|
||||||
|
if (opts.textOnly) {
|
||||||
|
PrintRegisterInfo(Info, displayUser, displayLicense);
|
||||||
|
} else {
|
||||||
|
std::string content = BuildRegFileContent(Info);
|
||||||
|
if (!WriteRegFile(opts.outputFile, content)) {
|
||||||
|
std::cerr << "Error: Failed to write file: " << opts.outputFile << "\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* encName = (opts.encoding == Encoding::UTF8) ? "UTF-8" :
|
||||||
|
(opts.encoding == Encoding::ANSI) ? "ANSI" : "ASCII";
|
||||||
|
|
||||||
|
std::cout << "\n";
|
||||||
|
PrintRegisterInfo(Info, displayUser, displayLicense);
|
||||||
|
std::cout << "\nDone! " << opts.outputFile << " has been generated. ("
|
||||||
|
<< encName << ")\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::exception& e) {
|
||||||
|
std::cerr << "Error: " << e.what() << "\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"name": "winrar-keygen",
|
||||||
|
"version": "4.1.0.0",
|
||||||
|
"dependencies": [
|
||||||
|
"gmp"
|
||||||
|
]
|
||||||
|
}
|
||||||
+4
-4
@@ -51,8 +51,8 @@ END
|
|||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 4,0,1,0
|
FILEVERSION 4,1,0,0
|
||||||
PRODUCTVERSION 4,0,1,0
|
PRODUCTVERSION 4,1,0,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
@@ -69,12 +69,12 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "WinRAR Keygen"
|
VALUE "CompanyName", "WinRAR Keygen"
|
||||||
VALUE "FileDescription", "WinRAR Key Generation Tool"
|
VALUE "FileDescription", "WinRAR Key Generation Tool"
|
||||||
VALUE "FileVersion", "4.0.1.0"
|
VALUE "FileVersion", "4.1.0.0"
|
||||||
VALUE "InternalName", "winrar-keygen.exe"
|
VALUE "InternalName", "winrar-keygen.exe"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2021 Bitcookies"
|
VALUE "LegalCopyright", "Copyright (C) 2021 Bitcookies"
|
||||||
VALUE "OriginalFilename", "winrar-keygen.exe"
|
VALUE "OriginalFilename", "winrar-keygen.exe"
|
||||||
VALUE "ProductName", "WinRAR Keygen"
|
VALUE "ProductName", "WinRAR Keygen"
|
||||||
VALUE "ProductVersion", "4.0.1.0"
|
VALUE "ProductVersion", "4.1.0.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|||||||
+8
-2
@@ -1,14 +1,16 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 16
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 16.0.29009.5
|
VisualStudioVersion = 17.14.37111.16
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winrar-keygen", "winrar-keygen.vcxproj", "{2443AA55-9534-4451-9BCC-48AC0982A0CC}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winrar-keygen", "winrar-keygen.vcxproj", "{2443AA55-9534-4451-9BCC-48AC0982A0CC}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|ARM64 = Debug|ARM64
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
Debug|x86 = Debug|x86
|
Debug|x86 = Debug|x86
|
||||||
|
Release|ARM64 = Release|ARM64
|
||||||
Release|x64 = Release|x64
|
Release|x64 = Release|x64
|
||||||
Release|x86 = Release|x86
|
Release|x86 = Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
@@ -21,6 +23,10 @@ Global
|
|||||||
{2443AA55-9534-4451-9BCC-48AC0982A0CC}.Release|x64.Build.0 = Release|x64
|
{2443AA55-9534-4451-9BCC-48AC0982A0CC}.Release|x64.Build.0 = Release|x64
|
||||||
{2443AA55-9534-4451-9BCC-48AC0982A0CC}.Release|x86.ActiveCfg = Release|Win32
|
{2443AA55-9534-4451-9BCC-48AC0982A0CC}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{2443AA55-9534-4451-9BCC-48AC0982A0CC}.Release|x86.Build.0 = Release|Win32
|
{2443AA55-9534-4451-9BCC-48AC0982A0CC}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{2443AA55-9534-4451-9BCC-48AC0982A0CC}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{2443AA55-9534-4451-9BCC-48AC0982A0CC}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
|
{2443AA55-9534-4451-9BCC-48AC0982A0CC}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{2443AA55-9534-4451-9BCC-48AC0982A0CC}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -17,6 +17,14 @@
|
|||||||
<Configuration>Release</Configuration>
|
<Configuration>Release</Configuration>
|
||||||
<Platform>x64</Platform>
|
<Platform>x64</Platform>
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|ARM64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|ARM64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
<VCProjectVersion>16.0</VCProjectVersion>
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
@@ -26,6 +34,7 @@
|
|||||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
<VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet>
|
<VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet>
|
||||||
<VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet>
|
<VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet>
|
||||||
|
<VcpkgTriplet Condition="'$(Platform)'=='ARM64'">arm64-windows-static</VcpkgTriplet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
@@ -58,6 +67,21 @@
|
|||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
<SpectreMitigation>false</SpectreMitigation>
|
<SpectreMitigation>false</SpectreMitigation>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<SpectreMitigation>false</SpectreMitigation>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<SpectreMitigation>false</SpectreMitigation>
|
||||||
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
<ImportGroup Label="ExtensionSettings">
|
<ImportGroup Label="ExtensionSettings">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
@@ -75,6 +99,12 @@
|
|||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
@@ -96,6 +126,16 @@
|
|||||||
<OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir>
|
<OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir>
|
||||||
<IntDir>$(SolutionDir)obj\$(Platform)-$(Configuration)\</IntDir>
|
<IntDir>$(SolutionDir)obj\$(Platform)-$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)obj\$(Platform)-$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)obj\$(Platform)-$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
@@ -157,6 +197,43 @@
|
|||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
|
|||||||
Reference in New Issue
Block a user