mirror of
https://gitea.tendokyu.moe/moegrid/sega-mount.git
synced 2026-09-22 22:37:57 +03:00
158 lines
5.1 KiB
C++
158 lines
5.1 KiB
C++
// 单元测试:挂载/卸载/链接/取消链接 OPT 容器
|
|
// 需要管理员权限运行(驱动安装+挂载都需要)
|
|
//
|
|
// 用法:
|
|
// test_mount_opt mount <opt_path> <tag> 挂载容器,验证设备可访问
|
|
// test_mount_opt unmount <tag> 卸载容器,验证设备已消失
|
|
// test_mount_opt link <tag> <link_dir> 为已挂载的卷创建目录链接(Junction)
|
|
// test_mount_opt unlink <link_dir> 移除目录链接(Junction)
|
|
//
|
|
// 示例:
|
|
// test_mount_opt mount "C:\Users\aiyah\Desktop\SDGA_A011_20260716114938_0.opt" OPT_TEST
|
|
// test_mount_opt link OPT_TEST "C:\mnt\opt_test"
|
|
// test_mount_opt unlink "C:\mnt\opt_test"
|
|
// test_mount_opt unmount OPT_TEST
|
|
#define LOG_MODULE "TEST"
|
|
#include "fscrypt.h"
|
|
#include "driver_service.h"
|
|
#include "utils/strings.h"
|
|
#include "utils/log.h"
|
|
#include <windows.h>
|
|
#include <cstdio>
|
|
#include <string>
|
|
#include <format>
|
|
|
|
static void print_usage() {
|
|
puts("Usage:");
|
|
puts(" test_mount_opt mount <opt_path> <tag> Mount container");
|
|
puts(" test_mount_opt unmount <tag> Unmount container");
|
|
puts(" test_mount_opt link <tag> <link_dir> Link device to directory");
|
|
puts(" test_mount_opt unlink <link_dir> Remove directory link");
|
|
}
|
|
|
|
// 确保驱动服务运行
|
|
static bool ensure_driver() {
|
|
std::string svc_err;
|
|
if (!driver::ensure_running(&svc_err)) {
|
|
LOG_ERROR("driver::ensure_running failed: {}", svc_err);
|
|
LOG_ERROR("Hint: run this program as Administrator");
|
|
return false;
|
|
}
|
|
LOG_INFO("Driver service ready");
|
|
return true;
|
|
}
|
|
|
|
// 验证设备 \\.\FscryptDisk_<tag> 是否可访问
|
|
static bool check_device(const std::wstring &tag, bool should_exist) {
|
|
std::wstring device_path = std::format(L"\\\\.\\FscryptDisk_{}", tag);
|
|
HANDLE hCheck = CreateFileW(device_path.c_str(), 0,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
nullptr, OPEN_EXISTING, 0, nullptr);
|
|
bool exists = (hCheck != INVALID_HANDLE_VALUE);
|
|
if (exists) CloseHandle(hCheck);
|
|
|
|
if (should_exist && !exists) {
|
|
LOG_ERROR("Device {} not accessible: {}", utils::wstr_to_str(device_path), GetLastError());
|
|
return false;
|
|
}
|
|
if (!should_exist && exists) {
|
|
LOG_ERROR("Device {} still exists after unmount!", utils::wstr_to_str(device_path));
|
|
return false;
|
|
}
|
|
if (should_exist) {
|
|
LOG_INFO("Device {} accessible", utils::wstr_to_str(device_path));
|
|
} else {
|
|
LOG_INFO("Device {} removed", utils::wstr_to_str(device_path));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// ---- 子命令实现 ----
|
|
|
|
static int cmd_mount(int argc, char *argv[]) {
|
|
if (argc < 4) { print_usage(); return 1; }
|
|
std::wstring opt_path = utils::to_wstring(argv[2]);
|
|
std::wstring tag = utils::to_wstring(argv[3]);
|
|
|
|
if (!ensure_driver()) return 1;
|
|
|
|
LOG_INFO("Mounting '{}' as tag '{}' ...", utils::wstr_to_str(opt_path), utils::wstr_to_str(tag));
|
|
auto result = fscrypt::mount_container(opt_path, tag);
|
|
if (!result.success) {
|
|
LOG_ERROR("Mount failed: {}", result.error);
|
|
return 1;
|
|
}
|
|
LOG_INFO("Mount succeeded");
|
|
|
|
if (!check_device(tag, true)) return 1;
|
|
|
|
LOG_INFO("=== MOUNT OK ===");
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_unmount(int argc, char *argv[]) {
|
|
if (argc < 3) { print_usage(); return 1; }
|
|
std::wstring tag = utils::to_wstring(argv[2]);
|
|
|
|
if (!ensure_driver()) return 1;
|
|
|
|
LOG_INFO("Unmounting tag '{}' ...", utils::wstr_to_str(tag));
|
|
if (!fscrypt::unmount_container(tag)) {
|
|
LOG_ERROR("Unmount failed");
|
|
return 1;
|
|
}
|
|
LOG_INFO("Unmount succeeded");
|
|
|
|
if (!check_device(tag, false)) return 1;
|
|
|
|
LOG_INFO("=== UNMOUNT OK ===");
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_link(int argc, char *argv[]) {
|
|
if (argc < 4) { print_usage(); return 1; }
|
|
std::wstring tag = utils::to_wstring(argv[2]);
|
|
std::wstring link_dir = utils::to_wstring(argv[3]);
|
|
|
|
LOG_INFO("Linking tag '{}' -> '{}' ...", utils::wstr_to_str(tag), utils::wstr_to_str(link_dir));
|
|
if (!fscrypt::link_container(tag, link_dir)) {
|
|
LOG_ERROR("Link failed");
|
|
return 1;
|
|
}
|
|
LOG_INFO("=== LINK OK ===");
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_unlink(int argc, char *argv[]) {
|
|
if (argc < 3) { print_usage(); return 1; }
|
|
std::wstring link_dir = utils::to_wstring(argv[2]);
|
|
|
|
LOG_INFO("Unlinking '{}' ...", utils::wstr_to_str(link_dir));
|
|
if (!fscrypt::unlink_container(link_dir)) {
|
|
LOG_ERROR("Unlink failed");
|
|
return 1;
|
|
}
|
|
LOG_INFO("=== UNLINK OK ===");
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
SetConsoleOutputCP(CP_UTF8);
|
|
SetConsoleCP(CP_UTF8);
|
|
|
|
if (argc < 2) {
|
|
print_usage();
|
|
return 1;
|
|
}
|
|
|
|
std::string cmd = argv[1];
|
|
if (cmd == "mount") return cmd_mount(argc, argv);
|
|
if (cmd == "unmount") return cmd_unmount(argc, argv);
|
|
if (cmd == "link") return cmd_link(argc, argv);
|
|
if (cmd == "unlink") return cmd_unlink(argc, argv);
|
|
|
|
LOG_ERROR("Unknown command: {}", cmd);
|
|
print_usage();
|
|
return 1;
|
|
}
|