Aktualizacja: 2025-10-21 08:39:47
This commit is contained in:
5
kvc.sln
5
kvc.sln
@@ -11,6 +11,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kvc_pass", "kvc\kvc_pass.vc
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KvcXor", "kvc\KvcXor.vcxproj", "{A905154D-F1EC-4821-9717-9F6D35F69F3F}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KvcXor", "kvc\KvcXor.vcxproj", "{A905154D-F1EC-4821-9717-9F6D35F69F3F}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "implementer", "kvc\implementer.vcxproj", "{376BAFB6-0DB9-4BFF-903A-779B4CE72CBC}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Release|x64 = Release|x64
|
Release|x64 = Release|x64
|
||||||
@@ -24,11 +26,14 @@ Global
|
|||||||
{12345678-1234-1234-1234-123456789ABC}.Release|x64.Build.0 = Release|x64
|
{12345678-1234-1234-1234-123456789ABC}.Release|x64.Build.0 = Release|x64
|
||||||
{A905154D-F1EC-4821-9717-9F6D35F69F3F}.Release|x64.ActiveCfg = Release|x64
|
{A905154D-F1EC-4821-9717-9F6D35F69F3F}.Release|x64.ActiveCfg = Release|x64
|
||||||
{A905154D-F1EC-4821-9717-9F6D35F69F3F}.Release|x64.Build.0 = Release|x64
|
{A905154D-F1EC-4821-9717-9F6D35F69F3F}.Release|x64.Build.0 = Release|x64
|
||||||
|
{376BAFB6-0DB9-4BFF-903A-779B4CE72CBC}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{376BAFB6-0DB9-4BFF-903A-779B4CE72CBC}.Release|x64.Build.0 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {75429447-576C-4E36-9CDC-F4B668D9FBF5}
|
||||||
SolutionGuid = {6314F007-4E69-4DEE-8AB4-D38008D70307}
|
SolutionGuid = {6314F007-4E69-4DEE-8AB4-D38008D70307}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
757
kvc/implementer.cpp
Normal file
757
kvc/implementer.cpp
Normal file
@@ -0,0 +1,757 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
|
#include <array>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <span>
|
||||||
|
#include <ranges>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <optional>
|
||||||
|
#include <variant>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <map>
|
||||||
|
#include <sstream>
|
||||||
|
#include <format>
|
||||||
|
#include <expected>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define NOMINMAX
|
||||||
|
#include <windows.h>
|
||||||
|
#include <fci.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <io.h>
|
||||||
|
#pragma comment(lib, "cabinet.lib")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
namespace rng = std::ranges;
|
||||||
|
|
||||||
|
// XOR key (same as PowerShell version)
|
||||||
|
constexpr std::array<uint8_t, 7> XOR_KEY = { 0xA0, 0xE2, 0x80, 0x8B, 0xE2, 0x80, 0x8C };
|
||||||
|
|
||||||
|
// Default file paths
|
||||||
|
constexpr std::string_view DEFAULT_CONFIG = "kvc.ini";
|
||||||
|
constexpr std::string_view TEMP_EVTX = "kvc.evtx";
|
||||||
|
constexpr std::string_view TEMP_CAB = "kvc.cab";
|
||||||
|
|
||||||
|
// Console colors
|
||||||
|
enum class Color : int {
|
||||||
|
Default = 7,
|
||||||
|
Green = 10,
|
||||||
|
Red = 12,
|
||||||
|
Yellow = 14,
|
||||||
|
Cyan = 11
|
||||||
|
};
|
||||||
|
|
||||||
|
void set_color(Color color) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), static_cast<int>(color));
|
||||||
|
#else
|
||||||
|
switch (color) {
|
||||||
|
case Color::Green: std::cout << "\033[32m"; break;
|
||||||
|
case Color::Red: std::cout << "\033[31m"; break;
|
||||||
|
case Color::Yellow: std::cout << "\033[33m"; break;
|
||||||
|
case Color::Cyan: std::cout << "\033[36m"; break;
|
||||||
|
case Color::Default: std::cout << "\033[0m"; break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_color() {
|
||||||
|
set_color(Color::Default);
|
||||||
|
}
|
||||||
|
|
||||||
|
// RAII color guard
|
||||||
|
class ColorGuard {
|
||||||
|
public:
|
||||||
|
explicit ColorGuard(Color new_color) {
|
||||||
|
set_color(new_color);
|
||||||
|
}
|
||||||
|
~ColorGuard() {
|
||||||
|
reset_color();
|
||||||
|
}
|
||||||
|
ColorGuard(const ColorGuard&) = delete;
|
||||||
|
ColorGuard& operator=(const ColorGuard&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Modern Result type using std::expected (C++23)
|
||||||
|
template<typename T>
|
||||||
|
using Result = std::expected<T, std::string>;
|
||||||
|
|
||||||
|
// Specialization for void
|
||||||
|
using ResultVoid = std::expected<void, std::string>;
|
||||||
|
|
||||||
|
// Configuration structure
|
||||||
|
struct Config {
|
||||||
|
std::string driver_file;
|
||||||
|
std::string dll_file;
|
||||||
|
std::string icon_file;
|
||||||
|
std::string output_file;
|
||||||
|
};
|
||||||
|
|
||||||
|
// WinAPI file operations
|
||||||
|
class WinFile {
|
||||||
|
HANDLE handle{ INVALID_HANDLE_VALUE };
|
||||||
|
|
||||||
|
public:
|
||||||
|
WinFile() = default;
|
||||||
|
|
||||||
|
WinFile(const std::string& filename, DWORD desiredAccess, DWORD creationDisposition) {
|
||||||
|
std::wstring wide_name;
|
||||||
|
int size = MultiByteToWideChar(CP_UTF8, 0, filename.c_str(), -1, nullptr, 0);
|
||||||
|
if (size > 0) {
|
||||||
|
wide_name.resize(size);
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, filename.c_str(), -1, wide_name.data(), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
handle = CreateFileW(
|
||||||
|
wide_name.c_str(),
|
||||||
|
desiredAccess,
|
||||||
|
FILE_SHARE_READ,
|
||||||
|
nullptr,
|
||||||
|
creationDisposition,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
~WinFile() {
|
||||||
|
if (is_valid()) {
|
||||||
|
CloseHandle(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_valid() const { return handle != INVALID_HANDLE_VALUE; }
|
||||||
|
HANDLE get() const { return handle; }
|
||||||
|
|
||||||
|
WinFile(const WinFile&) = delete;
|
||||||
|
WinFile& operator=(const WinFile&) = delete;
|
||||||
|
|
||||||
|
WinFile(WinFile&& other) noexcept : handle(other.handle) {
|
||||||
|
other.handle = INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
WinFile& operator=(WinFile&& other) noexcept {
|
||||||
|
if (this != &other) {
|
||||||
|
if (is_valid()) {
|
||||||
|
CloseHandle(handle);
|
||||||
|
}
|
||||||
|
handle = other.handle;
|
||||||
|
other.handle = INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check if file exists using WinAPI
|
||||||
|
bool file_exists_winapi(const std::string& filename) {
|
||||||
|
std::wstring wide_filename;
|
||||||
|
int size = MultiByteToWideChar(CP_UTF8, 0, filename.c_str(), -1, nullptr, 0);
|
||||||
|
if (size > 0) {
|
||||||
|
wide_filename.resize(size);
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, filename.c_str(), -1, wide_filename.data(), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD attrs = GetFileAttributesW(wide_filename.c_str());
|
||||||
|
return (attrs != INVALID_FILE_ATTRIBUTES && !(attrs & FILE_ATTRIBUTE_DIRECTORY));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get file size using WinAPI
|
||||||
|
Result<size_t> get_file_size_winapi(const std::string& filename) {
|
||||||
|
std::wstring wide_filename;
|
||||||
|
int size = MultiByteToWideChar(CP_UTF8, 0, filename.c_str(), -1, nullptr, 0);
|
||||||
|
if (size > 0) {
|
||||||
|
wide_filename.resize(size);
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, filename.c_str(), -1, wide_filename.data(), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
WIN32_FILE_ATTRIBUTE_DATA fileInfo;
|
||||||
|
if (!GetFileAttributesExW(wide_filename.c_str(), GetFileExInfoStandard, &fileInfo)) {
|
||||||
|
return std::unexpected("Cannot get file size: " + filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (static_cast<uint64_t>(fileInfo.nFileSizeHigh) << 32) | fileInfo.nFileSizeLow;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper functions
|
||||||
|
std::string format_size_kb(size_t bytes) {
|
||||||
|
return std::format("{:.2f} KB", bytes / 1024.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string trim(std::string_view str) {
|
||||||
|
const auto start = str.find_first_not_of(" \t\r\n");
|
||||||
|
if (start == std::string_view::npos) return "";
|
||||||
|
const auto end = str.find_last_not_of(" \t\r\n");
|
||||||
|
return std::string(str.substr(start, end - start + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read entire file into vector using WinAPI
|
||||||
|
Result<std::vector<uint8_t>> read_file_winapi(const std::string& filename) {
|
||||||
|
WinFile file(filename, GENERIC_READ, OPEN_EXISTING);
|
||||||
|
if (!file.is_valid()) {
|
||||||
|
return std::unexpected("Cannot open file: " + filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto size_result = get_file_size_winapi(filename);
|
||||||
|
if (!size_result) {
|
||||||
|
return std::unexpected(size_result.error());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> data(size_result.value());
|
||||||
|
DWORD bytesRead = 0;
|
||||||
|
|
||||||
|
if (!ReadFile(file.get(), data.data(), static_cast<DWORD>(data.size()), &bytesRead, nullptr)) {
|
||||||
|
return std::unexpected("Error reading file: " + filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytesRead != data.size()) {
|
||||||
|
return std::unexpected("Incomplete read of file: " + filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write data to file using WinAPI
|
||||||
|
ResultVoid write_file_winapi(const std::string& filename, std::span<const uint8_t> data) {
|
||||||
|
WinFile file(filename, GENERIC_WRITE, CREATE_ALWAYS);
|
||||||
|
if (!file.is_valid()) {
|
||||||
|
return std::unexpected("Cannot create file: " + filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD bytesWritten = 0;
|
||||||
|
if (!WriteFile(file.get(), data.data(), static_cast<DWORD>(data.size()), &bytesWritten, nullptr)) {
|
||||||
|
return std::unexpected("Error writing to file: " + filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytesWritten != data.size()) {
|
||||||
|
return std::unexpected("Incomplete write to file: " + filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// XOR operation
|
||||||
|
void xor_data(std::span<uint8_t> data, std::span<const uint8_t> key) noexcept {
|
||||||
|
for (size_t i = 0; i < data.size(); ++i) {
|
||||||
|
data[i] ^= key[i % key.size()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read INI configuration
|
||||||
|
Result<Config> read_config(const std::string& config_path) {
|
||||||
|
auto file_result = read_file_winapi(config_path);
|
||||||
|
if (!file_result) {
|
||||||
|
return std::unexpected(file_result.error());
|
||||||
|
}
|
||||||
|
|
||||||
|
Config config;
|
||||||
|
std::string content(file_result->begin(), file_result->end());
|
||||||
|
std::istringstream stream(content);
|
||||||
|
std::string line;
|
||||||
|
std::string current_section;
|
||||||
|
|
||||||
|
while (std::getline(stream, line)) {
|
||||||
|
line = trim(line);
|
||||||
|
|
||||||
|
if (line.empty() || line[0] == '#' || line[0] == ';') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Section header
|
||||||
|
if (line.starts_with('[') && line.ends_with(']')) {
|
||||||
|
current_section = line.substr(1, line.length() - 2);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Key=Value pair
|
||||||
|
size_t pos = line.find('=');
|
||||||
|
if (pos != std::string::npos) {
|
||||||
|
std::string key = trim(line.substr(0, pos));
|
||||||
|
std::string value = trim(line.substr(pos + 1));
|
||||||
|
|
||||||
|
if (key == "DriverFile") {
|
||||||
|
config.driver_file = value;
|
||||||
|
} else if (key == "DllFile") {
|
||||||
|
config.dll_file = value;
|
||||||
|
} else if (key == "IconFile") {
|
||||||
|
config.icon_file = value;
|
||||||
|
} else if (key == "OutputFile") {
|
||||||
|
config.output_file = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate config
|
||||||
|
if (config.driver_file.empty() || config.dll_file.empty() ||
|
||||||
|
config.icon_file.empty() || config.output_file.empty()) {
|
||||||
|
return std::unexpected("Incomplete configuration in INI file");
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Cabinet API callback structures
|
||||||
|
struct CabContext {
|
||||||
|
std::string input_file;
|
||||||
|
std::string output_file;
|
||||||
|
UINT temp_file_counter = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// FCI callbacks
|
||||||
|
FNFCIALLOC(fci_alloc) {
|
||||||
|
return malloc(cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
FNFCIFREE(fci_free) {
|
||||||
|
free(memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
FNFCIOPEN(fci_open) {
|
||||||
|
int flags = 0;
|
||||||
|
|
||||||
|
if (oflag & _O_RDWR) flags = GENERIC_READ | GENERIC_WRITE;
|
||||||
|
else if (oflag & _O_WRONLY) flags = GENERIC_WRITE;
|
||||||
|
else flags = GENERIC_READ;
|
||||||
|
|
||||||
|
DWORD creation = OPEN_EXISTING;
|
||||||
|
if (oflag & _O_CREAT) {
|
||||||
|
creation = CREATE_ALWAYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE handle = CreateFileA(
|
||||||
|
pszFile,
|
||||||
|
flags,
|
||||||
|
FILE_SHARE_READ,
|
||||||
|
nullptr,
|
||||||
|
creation,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
|
||||||
|
return (INT_PTR)handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
FNFCIREAD(fci_read) {
|
||||||
|
DWORD bytesRead = 0;
|
||||||
|
if (!ReadFile((HANDLE)hf, memory, cb, &bytesRead, nullptr)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return bytesRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
FNFCIWRITE(fci_write) {
|
||||||
|
DWORD bytesWritten = 0;
|
||||||
|
if (!WriteFile((HANDLE)hf, memory, cb, &bytesWritten, nullptr)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return bytesWritten;
|
||||||
|
}
|
||||||
|
|
||||||
|
FNFCICLOSE(fci_close) {
|
||||||
|
CloseHandle((HANDLE)hf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FNFCISEEK(fci_seek) {
|
||||||
|
return SetFilePointer((HANDLE)hf, dist, nullptr, seektype);
|
||||||
|
}
|
||||||
|
|
||||||
|
FNFCIDELETE(fci_delete) {
|
||||||
|
DeleteFileA(pszFile);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FNFCIGETTEMPFILE(fci_get_temp_file) {
|
||||||
|
CabContext* ctx = static_cast<CabContext*>(pv);
|
||||||
|
snprintf(pszTempName, cbTempName, "temp_cab_%u.tmp", ctx->temp_file_counter++);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
FNFCIGETNEXTCABINET(fci_get_next_cabinet) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
FNFCIFILEPLACED(fci_file_placed) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FNFCISTATUS(fci_status) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FNFCIGETOPENINFO(fci_get_open_info) {
|
||||||
|
WIN32_FIND_DATAA findData;
|
||||||
|
HANDLE findHandle = FindFirstFileA(pszName, &findData);
|
||||||
|
|
||||||
|
if (findHandle == INVALID_HANDLE_VALUE) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
FindClose(findHandle);
|
||||||
|
|
||||||
|
FILETIME ftLocal;
|
||||||
|
FileTimeToLocalFileTime(&findData.ftLastWriteTime, &ftLocal);
|
||||||
|
FileTimeToDosDateTime(&ftLocal, pdate, ptime);
|
||||||
|
|
||||||
|
*pattribs = findData.dwFileAttributes &
|
||||||
|
(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN |
|
||||||
|
FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE);
|
||||||
|
|
||||||
|
HANDLE handle = CreateFileA(
|
||||||
|
pszName,
|
||||||
|
GENERIC_READ,
|
||||||
|
FILE_SHARE_READ,
|
||||||
|
nullptr,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
|
||||||
|
if (handle == INVALID_HANDLE_VALUE) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (INT_PTR)handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create CAB file
|
||||||
|
ResultVoid create_cab_file(const std::string& input_file, const std::string& output_file) {
|
||||||
|
CabContext context;
|
||||||
|
context.input_file = input_file;
|
||||||
|
context.output_file = output_file;
|
||||||
|
|
||||||
|
ERF erf = {};
|
||||||
|
CCAB ccab = {};
|
||||||
|
|
||||||
|
// Setup cabinet parameters
|
||||||
|
ccab.cb = 0x7FFFFFFF; // Max cabinet size
|
||||||
|
ccab.cbFolderThresh = 0x7FFFFFFF;
|
||||||
|
ccab.cbReserveCFHeader = 0;
|
||||||
|
ccab.cbReserveCFFolder = 0;
|
||||||
|
ccab.cbReserveCFData = 0;
|
||||||
|
ccab.iCab = 1;
|
||||||
|
ccab.iDisk = 0;
|
||||||
|
ccab.setID = 0;
|
||||||
|
strncpy_s(ccab.szCab, output_file.c_str(), _TRUNCATE);
|
||||||
|
strcpy_s(ccab.szCabPath, "");
|
||||||
|
|
||||||
|
// Create FCI context
|
||||||
|
HFCI hfci = FCICreate(
|
||||||
|
&erf,
|
||||||
|
fci_file_placed,
|
||||||
|
fci_alloc,
|
||||||
|
fci_free,
|
||||||
|
fci_open,
|
||||||
|
fci_read,
|
||||||
|
fci_write,
|
||||||
|
fci_close,
|
||||||
|
fci_seek,
|
||||||
|
fci_delete,
|
||||||
|
fci_get_temp_file,
|
||||||
|
&ccab,
|
||||||
|
&context
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!hfci) {
|
||||||
|
return std::unexpected("Failed to create FCI context");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add file to cabinet with LZX compression
|
||||||
|
BOOL result = FCIAddFile(
|
||||||
|
hfci,
|
||||||
|
const_cast<char*>(input_file.c_str()),
|
||||||
|
const_cast<char*>(fs::path(input_file).filename().string().c_str()),
|
||||||
|
FALSE,
|
||||||
|
fci_get_next_cabinet,
|
||||||
|
fci_status,
|
||||||
|
fci_get_open_info,
|
||||||
|
tcompTYPE_LZX | tcompLZX_WINDOW_HI
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
FCIDestroy(hfci);
|
||||||
|
return std::unexpected("Failed to add file to cabinet");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush and close cabinet
|
||||||
|
result = FCIFlushCabinet(hfci, FALSE, fci_get_next_cabinet, fci_status);
|
||||||
|
FCIDestroy(hfci);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return std::unexpected("Failed to flush cabinet");
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Delete file using WinAPI
|
||||||
|
bool delete_file_winapi(const std::string& filename) {
|
||||||
|
std::wstring wide_filename;
|
||||||
|
int size = MultiByteToWideChar(CP_UTF8, 0, filename.c_str(), -1, nullptr, 0);
|
||||||
|
if (size > 0) {
|
||||||
|
wide_filename.resize(size);
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, filename.c_str(), -1, wide_filename.data(), size);
|
||||||
|
}
|
||||||
|
return DeleteFileW(wide_filename.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main packaging function
|
||||||
|
ResultVoid package_files(const Config& config) {
|
||||||
|
std::cout << "\n";
|
||||||
|
{
|
||||||
|
ColorGuard cyan(Color::Cyan);
|
||||||
|
std::cout << "=== FILE PACKAGING SCRIPT ===\n";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
ColorGuard green(Color::Green);
|
||||||
|
std::cout << "Starting packaging process...\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 0: Display configuration
|
||||||
|
std::cout << "\n";
|
||||||
|
{
|
||||||
|
ColorGuard yellow(Color::Yellow);
|
||||||
|
std::cout << "Step 0: Configuration loaded\n";
|
||||||
|
}
|
||||||
|
std::cout << " - Driver: " << config.driver_file << "\n";
|
||||||
|
std::cout << " - DLL: " << config.dll_file << "\n";
|
||||||
|
std::cout << " - Icon: " << config.icon_file << "\n";
|
||||||
|
std::cout << " - Output: " << config.output_file << "\n";
|
||||||
|
|
||||||
|
// Step 1: Verify input files using WinAPI
|
||||||
|
std::cout << "\n";
|
||||||
|
{
|
||||||
|
ColorGuard yellow(Color::Yellow);
|
||||||
|
std::cout << "Step 1: Verifying input files...\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> required_files = {
|
||||||
|
config.driver_file,
|
||||||
|
config.dll_file,
|
||||||
|
config.icon_file
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto& file : required_files) {
|
||||||
|
if (!file_exists_winapi(file)) {
|
||||||
|
ColorGuard red(Color::Red);
|
||||||
|
std::cout << " X File not found: " << file << "\n";
|
||||||
|
|
||||||
|
// Debug info
|
||||||
|
std::cout << " Debug bytes: ";
|
||||||
|
for (char c : file) {
|
||||||
|
printf("%02X ", (unsigned char)c);
|
||||||
|
}
|
||||||
|
std::cout << "\n";
|
||||||
|
|
||||||
|
return std::unexpected("ABORTING: Required file missing: " + file);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto size_result = get_file_size_winapi(file);
|
||||||
|
if (!size_result) {
|
||||||
|
ColorGuard red(Color::Red);
|
||||||
|
std::cout << " X Cannot get size for: " << file << " - " << size_result.error() << "\n";
|
||||||
|
return std::unexpected(size_result.error());
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorGuard green(Color::Green);
|
||||||
|
std::cout << " + Found: " << file << " (" << format_size_kb(size_result.value()) << ")\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2: Concatenate PE files
|
||||||
|
std::cout << "\n";
|
||||||
|
{
|
||||||
|
ColorGuard yellow(Color::Yellow);
|
||||||
|
std::cout << "Step 2: Concatenating PE files...\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto driver_result = read_file_winapi(config.driver_file);
|
||||||
|
if (!driver_result) {
|
||||||
|
ColorGuard red(Color::Red);
|
||||||
|
std::cout << " X Failed to read driver file: " << driver_result.error() << "\n";
|
||||||
|
return std::unexpected(driver_result.error());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dll_result = read_file_winapi(config.dll_file);
|
||||||
|
if (!dll_result) {
|
||||||
|
ColorGuard red(Color::Red);
|
||||||
|
std::cout << " X Failed to read DLL file: " << dll_result.error() << "\n";
|
||||||
|
return std::unexpected(dll_result.error());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> concatenated_data;
|
||||||
|
concatenated_data.reserve(driver_result->size() + dll_result->size());
|
||||||
|
concatenated_data.insert(concatenated_data.end(), driver_result->begin(), driver_result->end());
|
||||||
|
concatenated_data.insert(concatenated_data.end(), dll_result->begin(), dll_result->end());
|
||||||
|
|
||||||
|
auto write_result = write_file_winapi(std::string(TEMP_EVTX), concatenated_data);
|
||||||
|
if (!write_result) {
|
||||||
|
ColorGuard red(Color::Red);
|
||||||
|
std::cout << " X Failed to create concatenated file: " << write_result.error() << "\n";
|
||||||
|
return std::unexpected(write_result.error());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
ColorGuard green(Color::Green);
|
||||||
|
std::cout << " + Created: " << TEMP_EVTX << " ("
|
||||||
|
<< format_size_kb(concatenated_data.size()) << ")\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3: Compress with CAB
|
||||||
|
std::cout << "\n";
|
||||||
|
{
|
||||||
|
ColorGuard yellow(Color::Yellow);
|
||||||
|
std::cout << "Step 3: Compressing with CAB...\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
auto cab_result = create_cab_file(std::string(TEMP_EVTX), std::string(TEMP_CAB));
|
||||||
|
if (!cab_result) {
|
||||||
|
ColorGuard red(Color::Red);
|
||||||
|
std::cout << " X CAB compression failed: " << cab_result.error() << "\n";
|
||||||
|
return std::unexpected(cab_result.error());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cab_size_result = get_file_size_winapi(std::string(TEMP_CAB));
|
||||||
|
if (!cab_size_result) {
|
||||||
|
ColorGuard red(Color::Red);
|
||||||
|
std::cout << " X Cannot get CAB file size: " << cab_size_result.error() << "\n";
|
||||||
|
return std::unexpected(cab_size_result.error());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
ColorGuard green(Color::Green);
|
||||||
|
std::cout << " + Created: " << TEMP_CAB << " (" << format_size_kb(cab_size_result.value()) << ")\n";
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
ColorGuard red(Color::Red);
|
||||||
|
std::cout << " X CAB compression is only supported on Windows\n";
|
||||||
|
return std::unexpected("CAB compression requires Windows Cabinet API");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Step 4: XOR encrypt the CAB file
|
||||||
|
std::cout << "\n";
|
||||||
|
{
|
||||||
|
ColorGuard yellow(Color::Yellow);
|
||||||
|
std::cout << "Step 4: XOR encrypting CAB file...\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cab_data_result = read_file_winapi(std::string(TEMP_CAB));
|
||||||
|
if (!cab_data_result) {
|
||||||
|
ColorGuard red(Color::Red);
|
||||||
|
std::cout << " X Failed to read CAB file: " << cab_data_result.error() << "\n";
|
||||||
|
return std::unexpected(cab_data_result.error());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> encrypted_cab = std::move(cab_data_result.value());
|
||||||
|
xor_data(encrypted_cab, XOR_KEY);
|
||||||
|
|
||||||
|
{
|
||||||
|
ColorGuard green(Color::Green);
|
||||||
|
std::cout << " + CAB file encrypted (" << encrypted_cab.size() << " bytes)\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 5: Create final package with icon
|
||||||
|
std::cout << "\n";
|
||||||
|
{
|
||||||
|
ColorGuard yellow(Color::Yellow);
|
||||||
|
std::cout << "Step 5: Creating final package with icon...\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto icon_result = read_file_winapi(config.icon_file);
|
||||||
|
if (!icon_result) {
|
||||||
|
ColorGuard red(Color::Red);
|
||||||
|
std::cout << " X Failed to read icon file: " << icon_result.error() << "\n";
|
||||||
|
return std::unexpected(icon_result.error());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> final_package;
|
||||||
|
final_package.reserve(icon_result->size() + encrypted_cab.size());
|
||||||
|
final_package.insert(final_package.end(), icon_result->begin(), icon_result->end());
|
||||||
|
final_package.insert(final_package.end(), encrypted_cab.begin(), encrypted_cab.end());
|
||||||
|
|
||||||
|
auto final_write_result = write_file_winapi(config.output_file, final_package);
|
||||||
|
if (!final_write_result) {
|
||||||
|
ColorGuard red(Color::Red);
|
||||||
|
std::cout << " X Failed to create final package: " << final_write_result.error() << "\n";
|
||||||
|
return std::unexpected(final_write_result.error());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
ColorGuard green(Color::Green);
|
||||||
|
std::cout << " + Final package created: " << config.output_file
|
||||||
|
<< " (" << format_size_kb(final_package.size()) << ")\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 6: Cleanup temporary files
|
||||||
|
std::cout << "\n";
|
||||||
|
{
|
||||||
|
ColorGuard yellow(Color::Yellow);
|
||||||
|
std::cout << "Step 6: Cleaning up temporary files...\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string_view> temp_files = { TEMP_EVTX, TEMP_CAB };
|
||||||
|
for (const auto& temp_file : temp_files) {
|
||||||
|
if (file_exists_winapi(std::string(temp_file))) {
|
||||||
|
if (delete_file_winapi(std::string(temp_file))) {
|
||||||
|
ColorGuard green(Color::Green);
|
||||||
|
std::cout << " + Removed: " << temp_file << "\n";
|
||||||
|
} else {
|
||||||
|
ColorGuard yellow(Color::Yellow);
|
||||||
|
std::cout << " ! Warning: Could not remove " << temp_file << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final summary
|
||||||
|
std::cout << "\n";
|
||||||
|
{
|
||||||
|
ColorGuard cyan(Color::Cyan);
|
||||||
|
std::cout << "=== PACKAGING COMPLETED SUCCESSFULLY ===\n";
|
||||||
|
}
|
||||||
|
std::cout << "Output file: " << config.output_file << "\n";
|
||||||
|
std::cout << "Total size: " << format_size_kb(final_package.size()) << "\n";
|
||||||
|
std::cout << "Structure: [" << icon_result->size() << "-byte icon] + [XOR-encrypted CAB]\n";
|
||||||
|
std::cout << "Breakdown:\n";
|
||||||
|
std::cout << " - Icon: " << icon_result->size() << " bytes\n";
|
||||||
|
std::cout << " - Encrypted CAB: " << encrypted_cab.size() << " bytes\n";
|
||||||
|
{
|
||||||
|
ColorGuard green(Color::Green);
|
||||||
|
std::cout << "\nThe file is ready for embedding as a resource!\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
// Set console to UTF-8 mode
|
||||||
|
SetConsoleOutputCP(CP_UTF8);
|
||||||
|
SetConsoleCP(CP_UTF8);
|
||||||
|
|
||||||
|
std::string config_file = std::string(DEFAULT_CONFIG);
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
config_file = argv[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Reading configuration from: " << config_file << "\n";
|
||||||
|
|
||||||
|
auto config_result = read_config(config_file);
|
||||||
|
if (!config_result) {
|
||||||
|
ColorGuard red(Color::Red);
|
||||||
|
std::cerr << "Error: " << config_result.error() << "\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto result = package_files(config_result.value());
|
||||||
|
if (!result) {
|
||||||
|
ColorGuard red(Color::Red);
|
||||||
|
std::cerr << "\nError: " << result.error() << "\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
22
kvc/implementer.filters
Normal file
22
kvc/implementer.filters
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="implementer.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
77
kvc/implementer.rc
Normal file
77
kvc/implementer.rc
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
// Microsoft Visual C++ generated resource script.
|
||||||
|
// implementer.exe Resource File - Microsoft Corporation branding
|
||||||
|
//
|
||||||
|
#include "resource.h"
|
||||||
|
|
||||||
|
#define APSTUDIO_READONLY_SYMBOLS
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Generated from the TEXTINCLUDE 2 resource.
|
||||||
|
//
|
||||||
|
#include "winres.h"
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
#undef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// English (United States) resources
|
||||||
|
|
||||||
|
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||||
|
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Icon
|
||||||
|
//
|
||||||
|
|
||||||
|
IDI_ICON1 ICON "ICON\\kvc.ico"
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Version Information - Microsoft Corporation branding
|
||||||
|
//
|
||||||
|
|
||||||
|
VS_VERSION_INFO VERSIONINFO
|
||||||
|
FILEVERSION 10,0,26200,8460
|
||||||
|
PRODUCTVERSION 10,0,26200,8460
|
||||||
|
FILEFLAGSMASK 0x3fL
|
||||||
|
#ifdef _DEBUG
|
||||||
|
FILEFLAGS 0x1L
|
||||||
|
#else
|
||||||
|
FILEFLAGS 0x0L
|
||||||
|
#endif
|
||||||
|
FILEOS 0x40004L
|
||||||
|
FILETYPE 0x1L // VFT_APP - Application file type
|
||||||
|
FILESUBTYPE 0x0L
|
||||||
|
BEGIN
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
BEGIN
|
||||||
|
BLOCK "040904b0"
|
||||||
|
BEGIN
|
||||||
|
VALUE "CompanyName", "Microsoft Corporation"
|
||||||
|
VALUE "FileDescription", "Windows System Utility"
|
||||||
|
VALUE "FileVersion", "10.0.26200.8460"
|
||||||
|
VALUE "InternalName", "implementer.exe"
|
||||||
|
VALUE "LegalCopyright", "© Microsoft Corporation. All rights reserved."
|
||||||
|
VALUE "OriginalFilename", "implementer.exe"
|
||||||
|
VALUE "ProductName", "Microsoft® Windows® Operating System"
|
||||||
|
VALUE "ProductVersion", "10.0.26200.8460"
|
||||||
|
END
|
||||||
|
END
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Translation", 0x409, 1200
|
||||||
|
END
|
||||||
|
END
|
||||||
|
|
||||||
|
#endif // English (United States) resources
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef APSTUDIO_INVOKED
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Generated from the TEXTINCLUDE 3 resource.
|
||||||
|
//
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // not APSTUDIO_INVOKED
|
||||||
84
kvc/implementer.vcxproj
Normal file
84
kvc/implementer.vcxproj
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>17.0</VCProjectVersion>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<ProjectGuid>{376BAFB6-0DB9-4BFF-903A-779B4CE72CBC}</ProjectGuid>
|
||||||
|
<RootNamespace>implementer</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings" />
|
||||||
|
<ImportGroup Label="Shared" />
|
||||||
|
<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" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)bin\x64\Release\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)obj\$(ProjectName)\$(Configuration)\$(Platform)\</IntDir>
|
||||||
|
<TargetName>implementer</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>powershell -Command "& {$f='$(OutDir)$(TargetName)$(TargetExt)'; (Get-Item $f).CreationTime='2026-01-01 00:00:00'; (Get-Item $f).LastWriteTime='2026-01-01 00:00:00'}"</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="implementer.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="resource.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="implementer.rc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Image Include="ICON\kvc.ico" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets" />
|
||||||
|
</Project>
|
||||||
4
kvc/implementer.vcxproj.user
Normal file
4
kvc/implementer.vcxproj.user
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup />
|
||||||
|
</Project>
|
||||||
Reference in New Issue
Block a user