123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421 |
- #include "wl_base_help_plugin.h"
- // This must be included before many other Windows headers.
- #include <windows.h>
- #include <tlhelp32.h>
- #include <WinInet.h>
- #include <Ras.h>
- #include <RasError.h>
- #include <vector>
- #include <iostream>
- #include "raserror.h"
- #pragma comment(lib, "wininet")
- #pragma comment(lib, "Rasapi32")
- #pragma comment(lib, "rasapi32.lib")
- #include <string>
- // For getPlatformVersion; remove unless needed for your plugin implementation.
- #include <VersionHelpers.h>
- #include <flutter/method_channel.h>
- #include <flutter/plugin_registrar_windows.h>
- #include <flutter/standard_method_codec.h>
- #include <memory>
- #include <sstream>
- typedef LONG NTSTATUS, * PNTSTATUS;
- #define STATUS_SUCCESS (0x00000000)
- typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
- void startProxy(const int port)
- {
- INTERNET_PER_CONN_OPTION_LIST list;
- DWORD dwBufSize = sizeof(list);
- list.dwSize = sizeof(list);
- list.pszConnection = nullptr;
- auto url = "127.0.0.1:" + std::to_string(port);
- auto wUrl = std::wstring(url.begin(), url.end());
- auto fullAddr = new WCHAR[url.length() + 1];
- wcscpy_s(fullAddr, url.length() + 1, wUrl.c_str());
- list.dwOptionCount = 2;
- list.pOptions = new INTERNET_PER_CONN_OPTION[2];
- if (!list.pOptions)
- {
- return;
- }
- list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS;
- list.pOptions[0].Value.dwValue = PROXY_TYPE_DIRECT | PROXY_TYPE_PROXY;
- list.pOptions[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
- list.pOptions[1].Value.pszValue = fullAddr;
- InternetSetOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize);
- RASENTRYNAME entry;
- entry.dwSize = sizeof(entry);
- std::vector<RASENTRYNAME> entries;
- DWORD size = sizeof(entry), count;
- LPRASENTRYNAME entryAddr = &entry;
- auto ret = RasEnumEntries(nullptr, nullptr, entryAddr, &size, &count);
- if (ret == ERROR_BUFFER_TOO_SMALL)
- {
- entries.resize(count);
- entries[0].dwSize = sizeof(RASENTRYNAME);
- entryAddr = entries.data();
- ret = RasEnumEntries(nullptr, nullptr, entryAddr, &size, &count);
- }
- if (ret != ERROR_SUCCESS)
- {
- return;
- }
- for (DWORD i = 0; i < count; i++)
- {
- list.pszConnection = entryAddr[i].szEntryName;
- InternetSetOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize);
- }
- delete[] list.pOptions;
- InternetSetOption(nullptr, INTERNET_OPTION_SETTINGS_CHANGED, nullptr, 0);
- InternetSetOption(nullptr, INTERNET_OPTION_REFRESH, nullptr, 0);
- }
- void stopProxy()
- {
- INTERNET_PER_CONN_OPTION_LIST list;
- DWORD dwBufSize = sizeof(list);
- list.dwSize = sizeof(list);
- list.pszConnection = nullptr;
- list.dwOptionCount = 1;
- list.pOptions = new INTERNET_PER_CONN_OPTION[1];
- if (nullptr == list.pOptions)
- {
- return;
- }
- list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS;
- list.pOptions[0].Value.dwValue = PROXY_TYPE_DIRECT;
- InternetSetOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize);
- RASENTRYNAME entry;
- entry.dwSize = sizeof(entry);
- std::vector<RASENTRYNAME> entries;
- DWORD size = sizeof(entry), count;
- LPRASENTRYNAME entryAddr = &entry;
- auto ret = RasEnumEntries(nullptr, nullptr, entryAddr, &size, &count);
- if (ret == ERROR_BUFFER_TOO_SMALL)
- {
- entries.resize(count);
- entries[0].dwSize = sizeof(RASENTRYNAME);
- entryAddr = entries.data();
- ret = RasEnumEntries(nullptr, nullptr, entryAddr, &size, &count);
- }
- if (ret != ERROR_SUCCESS)
- {
- return;
- }
- for (DWORD i = 0; i < count; i++)
- {
- list.pszConnection = entryAddr[i].szEntryName;
- InternetSetOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize);
- }
- delete[] list.pOptions;
- InternetSetOption(nullptr, INTERNET_OPTION_SETTINGS_CHANGED, nullptr, 0);
- InternetSetOption(nullptr, INTERNET_OPTION_REFRESH, nullptr, 0);
- }
- // 检测代理是否启用的函数
- bool isProxyEnabled() {
- INTERNET_PER_CONN_OPTION_LIST list;
- DWORD dwBufSize = sizeof(list);
- list.dwSize = sizeof(list);
- list.pszConnection = nullptr;
- list.dwOptionCount = 1;
- list.pOptions = new INTERNET_PER_CONN_OPTION[1];
- list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS;
- bool proxyEnabled = false;
- if (InternetQueryOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &dwBufSize)) {
- proxyEnabled = (list.pOptions[0].Value.dwValue & PROXY_TYPE_PROXY) != 0;
- }
- delete[] list.pOptions;
- return proxyEnabled;
- }
- RTL_OSVERSIONINFOW GetRealOSVersion() {
- HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll");
- if (hMod) {
- RtlGetVersionPtr fnRtlGetVersion = (RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion");
- if (fnRtlGetVersion != nullptr) {
- RTL_OSVERSIONINFOW rovi = { 0 };
- rovi.dwOSVersionInfoSize = sizeof(rovi);
- if (STATUS_SUCCESS == fnRtlGetVersion(&rovi)) {
- return rovi;
- }
- }
- }
- RTL_OSVERSIONINFOW rovi = { 0 };
- return rovi;
- }
- bool IsWindows11OrGreater() {
- RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
- return (rovi.dwMajorVersion > 10) ||
- (rovi.dwMajorVersion == 10 && rovi.dwBuildNumber >= 22000);
- }
- void ShowConsole() {
- HWND consoleWindow = GetConsoleWindow();
- if (consoleWindow != NULL) {
- ShowWindow(consoleWindow, SW_SHOW);
- }
- }
- void HideConsole() {
- HWND consoleWindow = GetConsoleWindow();
- if (consoleWindow != NULL) {
- ShowWindow(consoleWindow, SW_HIDE);
- }
- }
- bool IsProcessRunning(const std::wstring& processName) {
- bool isRunning = false;
- HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if (hSnapshot != INVALID_HANDLE_VALUE) {
- PROCESSENTRY32 pe32;
- pe32.dwSize = sizeof(PROCESSENTRY32);
- if (Process32First(hSnapshot, &pe32)) {
- do {
- if (processName == pe32.szExeFile) {
- isRunning = true;
- break;
- }
- } while (Process32Next(hSnapshot, &pe32));
- }
- CloseHandle(hSnapshot);
- }
- return isRunning;
- }
- void KillProcess(const std::wstring& processName) {
- HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if (hSnapshot != INVALID_HANDLE_VALUE) {
- PROCESSENTRY32 pe32;
- pe32.dwSize = sizeof(PROCESSENTRY32);
- if (Process32First(hSnapshot, &pe32)) {
- do {
- if (processName == pe32.szExeFile) {
- HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pe32.th32ProcessID);
- if (hProcess != NULL) {
- TerminateProcess(hProcess, 0);
- CloseHandle(hProcess);
- break;
- }
- }
- } while (Process32Next(hSnapshot, &pe32));
- }
- CloseHandle(hSnapshot);
- }
- }
- bool isDialUpEnabled() {
- DWORD dwCb = 0;
- DWORD dwRet = ERROR_SUCCESS;
- DWORD dwConnections = 0;
- LPRASCONN lpRasConn = NULL;
- // 第一次调用 RasEnumConnections 来获取所需的缓冲区大小
- dwRet = RasEnumConnections(lpRasConn, &dwCb, &dwConnections);
- if (dwRet == ERROR_BUFFER_TOO_SMALL) {
- // 分配内存来保存 RAS 连接信息
- lpRasConn = (LPRASCONN)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwCb);
- if (lpRasConn == NULL) {
- wprintf(L"HeapAlloc failed!\n");
- return false;
- }
- // 初始化结构体大小
- lpRasConn[0].dwSize = sizeof(RASCONN);
- // 再次调用 RasEnumConnections 以填充连接信息
- dwRet = RasEnumConnections(lpRasConn, &dwCb, &dwConnections);
- // 检查是否成功,并且有连接
- if (ERROR_SUCCESS == dwRet && dwConnections > 0) {
- // 遍历连接,检查是否有 PPP 或 PPPoE 类型的拨号连接
- for (DWORD i = 0; i < dwConnections; i++) {
- if (wcscmp(lpRasConn[i].szDeviceType, L"RASDT_PPP") == 0 ||
- wcscmp(lpRasConn[i].szDeviceType, L"RASDT_PPPoE") == 0) {
- // 释放内存后返回 true,表示有拨号连接
- HeapFree(GetProcessHeap(), 0, lpRasConn);
- return true;
- }
- }
- }
- // 释放内存
- HeapFree(GetProcessHeap(), 0, lpRasConn);
- }
- // 没有找到符合条件的拨号连接,返回 false
- return false;
- }
- namespace wl_base_help {
- // static
- void WlBaseHelpPlugin::RegisterWithRegistrar(
- flutter::PluginRegistrarWindows *registrar) {
- auto channel =
- std::make_unique<flutter::MethodChannel<flutter::EncodableValue>>(
- registrar->messenger(), "wl_base_help",
- &flutter::StandardMethodCodec::GetInstance());
- auto plugin = std::make_unique<WlBaseHelpPlugin>(registrar);
- channel->SetMethodCallHandler(
- [plugin_pointer = plugin.get()](const auto &call, auto result) {
- plugin_pointer->HandleMethodCall(call, std::move(result));
- });
- registrar->AddPlugin(std::move(plugin));
- }
- WlBaseHelpPlugin::WlBaseHelpPlugin(flutter::PluginRegistrarWindows* registrar) : registrar(registrar) {}
- WlBaseHelpPlugin::~WlBaseHelpPlugin() {}
- void WlBaseHelpPlugin::HandleMethodCall(
- const flutter::MethodCall<flutter::EncodableValue>& method_call,
- std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
- if (method_call.method_name().compare("isDialUpEnabled") == 0) {
- bool dialUpEnabled = isDialUpEnabled();
- result->Success(flutter::EncodableValue(dialUpEnabled));
- } else if (method_call.method_name().compare("startProxy") == 0) {
- const auto* arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
- int port = std::get<int>(arguments->at(flutter::EncodableValue("port")));
- startProxy(port);
- result->Success();
- } else if (method_call.method_name().compare("stopProxy") == 0) {
- stopProxy();
- result->Success();
- } else if (method_call.method_name().compare("isProxyEnabled") == 0) {
- bool enabled = isProxyEnabled();
- result->Success(flutter::EncodableValue(enabled));
- } else if (method_call.method_name().compare("isProcessRunning") == 0) {
- const auto* arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
- auto processName = std::get<std::string>(arguments->find(flutter::EncodableValue("processName"))->second);
- bool isRunning = IsProcessRunning(std::wstring(processName.begin(), processName.end()));
- result->Success(flutter::EncodableValue(isRunning));
- }
- else if (method_call.method_name().compare("killProcess") == 0) {
- const auto* arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
- auto processName = std::get<std::string>(arguments->find(flutter::EncodableValue("processName"))->second);
- KillProcess(std::wstring(processName.begin(), processName.end()));
- result->Success();
- }
- else if (method_call.method_name().compare("showConsole") == 0) {
- ShowConsole();
- result->Success();
- }
- else if (method_call.method_name().compare("hideConsole") == 0) {
- HideConsole();
- result->Success();
- }else if (method_call.method_name().compare("runAsAdministrator") == 0) {
- HWND hwnd = GetMainWindow();
- // 调用您的提权逻辑,传递 hwnd
- TryRunAsAdmin(hwnd, result);
- //result->Success(flutter::EncodableValue(true));
- }
- else if (method_call.method_name().compare("isRunningAsAdmin") == 0) {
- bool isAdmin = IsRunningAsAdmin();
- result->Success(flutter::EncodableValue(isAdmin));
- }
- else if (method_call.method_name().compare("getPlatformVersion") == 0) {
- std::ostringstream version_stream;
- version_stream << "Windows ";
- if (IsWindows11OrGreater()) {
- version_stream << "11+";
- }else if (IsWindows10OrGreater()) {
- version_stream << "10+";
- } else if (IsWindows8OrGreater()) {
- version_stream << "8";
- } else if (IsWindows7OrGreater()) {
- version_stream << "7";
- }
- result->Success(flutter::EncodableValue(version_stream.str()));
- } else {
- result->NotImplemented();
- }
- }
- HWND WlBaseHelpPlugin::GetMainWindow() {
- if (registrar)
- {
- windowHwnd = registrar->GetView()->GetNativeWindow();
- }
- return ::GetAncestor(windowHwnd, GA_ROOT);
- }
- bool WlBaseHelpPlugin::IsRunningAsAdmin() {
- BOOL isAdmin = FALSE;
- PSID adminGroup = NULL;
- SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;
- if (AllocateAndInitializeSid(&ntAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
- DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
- &adminGroup)) {
- if (!CheckTokenMembership(NULL, adminGroup, &isAdmin)) {
- isAdmin = FALSE;
- }
- FreeSid(adminGroup);
- }
- return isAdmin != FALSE;
- }
- void WlBaseHelpPlugin::TryRunAsAdmin(HWND hwnd,
- std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>>& result){
- wchar_t szPath[MAX_PATH];
- if (GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath))) {
- std::wstring params = L"--runas-admin";
- SHELLEXECUTEINFO sei = { sizeof(sei) };
- sei.lpVerb = L"runas";
- sei.lpFile = szPath;
- sei.lpParameters = params.c_str();
- sei.hwnd = hwnd;
- sei.nShow = SW_NORMAL;
- if (!ShellExecuteEx(&sei)) {
- DWORD dwError = GetLastError();
- if (dwError == ERROR_CANCELLED) {
- // 用户拒绝了 UAC 提示
- result->Error("UAC_CANCELLED", "User cancelled the UAC prompt.");
- } else {
- // 发生其他错误
- std::ostringstream errMsg;
- errMsg << "Failed to execute with error code: " << dwError;
- result->Error("EXECUTION_FAILED", errMsg.str());
- }
- } else {
- result->Success();
- ExitProcess(0); // 退出当前进程
- }
- } else {
- result->Error("GET_MODULE_FAILED", "Failed to get module file name.");
- }
- }
- } // namespace wl_base_help
|