Skip to content

Commit

Permalink
feat: 实现 UI 功能 (1/2)
Browse files Browse the repository at this point in the history
  • Loading branch information
Blinue committed Apr 27, 2024
1 parent 585c99b commit 7795222
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 9 deletions.
3 changes: 2 additions & 1 deletion src/Magpie.App/HomePage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@
<local:SettingsCard.HeaderIcon>
<FontIcon Glyph="&#xEBFC;" />
</local:SettingsCard.HeaderIcon>
<ToggleSwitch x:Uid="ToggleSwitch" />
<ToggleSwitch x:Uid="ToggleSwitch"
IsOn="{x:Bind ViewModel.IsTouchSupportEnabled, Mode=TwoWay}" />
</local:SettingsCard>
<local:SettingsCard x:Uid="Home_Advanced_InlineParams">
<local:SettingsCard.HeaderIcon>
Expand Down
52 changes: 52 additions & 0 deletions src/Magpie.App/HomeViewModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "StrUtils.h"
#include "UpdateService.h"
#include "CommonSharedConstants.h"
#include "Logger.h"

namespace winrt::Magpie::App::implementation {

Expand Down Expand Up @@ -185,6 +186,57 @@ void HomeViewModel::RemindMeLater() {
ShowUpdateCard(false);
}

bool HomeViewModel::IsTouchSupportEnabled() const noexcept {
wil::unique_cotaskmem_string system32Dir;
HRESULT hr = SHGetKnownFolderPath(
FOLDERID_System, KF_FLAG_DEFAULT, NULL, system32Dir.put());
if (FAILED(hr)) {
Logger::Get().ComError("SHGetKnownFolderPath 失败", hr);
return false;
}

std::wstring path = StrUtils::Concat(system32Dir.get(),
L"\\Magpie\\", CommonSharedConstants::TOUCH_HELPER_EXE_NAME);
if (!Win32Utils::FileExists(path.c_str())) {
return false;
}

path += L".ver";

std::vector<uint8_t> version;
if (!Win32Utils::ReadFile(path.c_str(), version) || version.size() != 4) {
Logger::Get().Error("读取版本号失败");
return false;
}

return *(uint32_t*)version.data() == CommonSharedConstants::TOUCH_HELPER_VERSION;
}

void HomeViewModel::IsTouchSupportEnabled(bool value) {
if (IsTouchSupportEnabled() == value) {
return;
}

SHELLEXECUTEINFO execInfo{
.cbSize = sizeof(execInfo),
.fMask = SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS,
.lpVerb = L"runas",
.lpFile = Win32Utils::GetExePath().c_str(),
.lpParameters = value ? L" -r" : L" -ur"
};

if (ShellExecuteEx(&execInfo)) {
wil::unique_process_handle hProcess(execInfo.hProcess);
if (hProcess) {
wil::handle_wait(hProcess.get());
}
} else {
Logger::Get().Win32Error("ShellExecuteEx 失败");
}

RaisePropertyChanged(L"IsTouchSupportEnabled");
}

bool HomeViewModel::IsAllowScalingMaximized() const noexcept {
return AppSettings::Get().IsAllowScalingMaximized();
}
Expand Down
3 changes: 3 additions & 0 deletions src/Magpie.App/HomeViewModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ struct HomeViewModel : HomeViewModelT<HomeViewModel>, wil::notify_property_chang

void RemindMeLater();

bool IsTouchSupportEnabled() const noexcept;
void IsTouchSupportEnabled(bool value);

bool IsAllowScalingMaximized() const noexcept;
void IsAllowScalingMaximized(bool value);

Expand Down
1 change: 1 addition & 0 deletions src/Magpie.App/HomeViewModel.idl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ namespace Magpie.App {
void ActivateRestore();
void ClearRestore();

Boolean IsTouchSupportEnabled;
Boolean IsAllowScalingMaximized;
Boolean IsInlineParams;
Boolean IsSimulateExclusiveFullscreen;
Expand Down
54 changes: 48 additions & 6 deletions src/Magpie/UIAccessHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@

namespace Magpie {

// 证书的 SHA1 哈希值,也是“指纹”
static constexpr std::array<uint8_t, 20> CERT_FINGERPRINT{
0xad, 0x5a, 0x50, 0x3d, 0xda, 0xec, 0x08, 0x5b, 0xf4, 0x48,
0xd8, 0x63, 0xcf, 0x90, 0x3a, 0xb4, 0x72, 0x0e, 0x0b, 0x12
};

static std::vector<uint8_t> GetCertificateDataFromPE(const wchar_t* fileName) noexcept {
wil::unique_hfile hFile(CreateFile(
fileName, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL));
Expand Down Expand Up @@ -40,12 +46,6 @@ using unique_cert_context =
wil::unique_any<PCCERT_CONTEXT, decltype(&CertFreeCertificateContext), CertFreeCertificateContext>;

static bool InstallCertificateFromPE(const wchar_t* exePath) noexcept {
// 证书的 SHA1 哈希值,也是“指纹”
static constexpr std::array<uint8_t, 20> CERT_FINGERPRINT{
0xad, 0x5a, 0x50, 0x3d, 0xda, 0xec, 0x08, 0x5b, 0xf4, 0x48,
0xd8, 0x63, 0xcf, 0x90, 0x3a, 0xb4, 0x72, 0x0e, 0x0b, 0x12
};

// 打开本地计算机的根证书存储区
unique_cert_store hRootCertStore(CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL,
CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG, L"ROOT"));
Expand Down Expand Up @@ -182,4 +182,46 @@ bool UIAccessHelper::MakeExeUIAccess(const wchar_t* exePath, uint32_t version) n
return true;
}

bool UIAccessHelper::ClearUIAccess() noexcept {
if (!Win32Utils::IsProcessElevated()) {
Logger::Get().Error("没有管理员权限");
return false;
}

// 删除 system32\Magpie 文件夹

wil::unique_cotaskmem_string system32Dir;
HRESULT hr = SHGetKnownFolderPath(
FOLDERID_System, KF_FLAG_DEFAULT, NULL, system32Dir.put());
if (FAILED(hr)) {
Logger::Get().ComError("SHGetKnownFolderPath 失败", hr);
return false;
}

wil::RemoveDirectoryRecursiveNoThrow(
StrUtils::Concat(system32Dir.get(), L"\\Magpie").c_str());

// 删除证书

// 打开本地计算机的根证书存储区
unique_cert_store hRootCertStore(CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL,
CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG, L"ROOT"));
if (!hRootCertStore) {
Logger::Get().Win32Error("CertOpenStore 失败");
return false;
}

const CRYPT_DATA_BLOB blob{
.cbData = (DWORD)CERT_FINGERPRINT.size(),
.pbData = (BYTE*)CERT_FINGERPRINT.data()
};
unique_cert_context context(CertFindCertificateInStore(
hRootCertStore.get(), PKCS_7_ASN_ENCODING, 0, CERT_FIND_SHA1_HASH, &blob, nullptr));
if (context) {
CertDeleteCertificateFromStore(context.get());
}

return true;
}

}
1 change: 1 addition & 0 deletions src/Magpie/UIAccessHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace Magpie {

struct UIAccessHelper {
static bool MakeExeUIAccess(const wchar_t* exePath, uint32_t version) noexcept;
static bool ClearUIAccess() noexcept;
};

}
3 changes: 3 additions & 0 deletions src/Magpie/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ int APIENTRY wWinMain(
CommonSharedConstants::TOUCH_HELPER_EXE_NAME,
CommonSharedConstants::TOUCH_HELPER_VERSION
) ? 0 : 1;
} else if (lpCmdLine == L"-ur"sv) {
// TouchHelper 正在运行?
return Magpie::UIAccessHelper::ClearUIAccess() ? 0 : 1;
}

auto& app = Magpie::XamlApp::Get();
Expand Down
2 changes: 1 addition & 1 deletion src/Shared/Win32Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ bool Win32Utils::GetWindowFrameRect(HWND hWnd, RECT& rect) noexcept {
return true;
}

bool Win32Utils::ReadFile(const wchar_t* fileName, std::vector<BYTE>& result) noexcept {
bool Win32Utils::ReadFile(const wchar_t* fileName, std::vector<uint8_t>& result) noexcept {
Logger::Get().Info(StrUtils::Concat("读取文件: ", StrUtils::UTF16ToUTF8(fileName)));

CREATEFILE2_EXTENDED_PARAMETERS extendedParams{
Expand Down
2 changes: 1 addition & 1 deletion src/Shared/Win32Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct Win32Utils {

static bool GetWindowFrameRect(HWND hWnd, RECT& rect) noexcept;

static bool ReadFile(const wchar_t* fileName, std::vector<BYTE>& result) noexcept;
static bool ReadFile(const wchar_t* fileName, std::vector<uint8_t>& result) noexcept;

static bool ReadTextFile(const wchar_t* fileName, std::string& result) noexcept;

Expand Down

0 comments on commit 7795222

Please sign in to comment.