1. 删除宏UNICODE和_UNICODE

2. 修复app.exe和worker析构顺序不对导致的卡死
3. 修改CMakeLists.txt的install部分
This commit is contained in:
Zhennan Tu
2023-06-02 23:49:33 +08:00
parent d873b08d7b
commit ecf0c6da65
9 changed files with 105 additions and 112 deletions

View File

@@ -31,7 +31,7 @@ endif()
set(CMAKE_CXX_STANDARD 17)
if(LT_WINDOWS)
add_compile_definitions(UNICODE _UNICODE WIN32 _WIN32 NOMINMAX WIN32_LEAN_AND_MEAN)# NOGDI)
add_compile_definitions(WIN32 _WIN32 NOMINMAX WIN32_LEAN_AND_MEAN)# NOGDI)
add_compile_options(/wd4819 /utf-8)
#add_compile_options(/W4 /WX)
else()

View File

@@ -53,7 +53,10 @@ App::App() {
}
App::~App() {
//
if (ioloop_) {
ioloop_->stop();
}
thread_.reset();
}
bool App::init() {

View File

@@ -134,6 +134,22 @@ target_link_libraries(${PROJECT_NAME}
install(TARGETS ${PROJECT_NAME})
install(CODE [[
file(GET_RUNTIME_DEPENDENCIES
RESOLVED_DEPENDENCIES_VAR RESOLVED_DEPS
UNRESOLVED_DEPENDENCIES_VAR UNRESOLVED_DEPS
EXECUTABLES $<TARGET_FILE:lanthing>
DIRECTORIES ${CMAKE_SOURCE_DIR}
PRE_INCLUDE_REGEXES ${CMAKE_SOURCE_DIR}
POST_INCLUDE_REGEXES ${CMAKE_SOURCE_DIR}
PRE_EXCLUDE_REGEXES "system32"
POST_EXCLUDE_REGEXES "system32"
)
foreach(DEP_LIB ${RESOLVED_DEPS})
file(INSTALL ${DEP_LIB} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
endforeach()
]])
deploy_dlls(${PROJECT_NAME})
# 设置VS调试路径

View File

@@ -1,15 +1,13 @@
#include "worker_process.h"
#include <Windows.h>
#include <g3log/g3log.hpp>
#include <ltproto/peer2peer/stop_working.pb.h>
#include <ltlib/system.h>
#include <ltlib/strings.h>
#include <ltlib/system.h>
#include <ltproto/peer2peer/stop_working.pb.h>
namespace
{
namespace {
std::string to_string(std::vector<rtc::VideoCodecType> codecs)
{
std::string to_string(std::vector<rtc::VideoCodecType> codecs) {
std::string str;
for (size_t i = 0; i < codecs.size(); i++) {
switch (codecs[i]) {
@@ -32,38 +30,30 @@ std::string to_string(std::vector<rtc::VideoCodecType> codecs)
} // namespace
namespace lt
{
namespace lt {
namespace svc
{
namespace svc {
std::unique_ptr<WorkerProcess> WorkerProcess::create(const Params& params)
{
std::unique_ptr<WorkerProcess> process { new WorkerProcess(params) };
std::unique_ptr<WorkerProcess> WorkerProcess::create(const Params& params) {
std::unique_ptr<WorkerProcess> process{new WorkerProcess(params)};
process->start();
return process;
}
WorkerProcess::WorkerProcess(const Params& params)
: on_stoped_ { params.on_stoped }
, path_ { params.path }
, pipe_name_ { params.pipe_name }
, client_width_ { params.client_width }
, client_height_ { params.client_height }
, client_refresh_rate_ { params.client_refresh_rate }
, client_codecs_ { params.client_codecs }
, run_as_win_service_ { ltlib::is_run_as_service() }
{
}
: on_stoped_{params.on_stoped}
, path_{params.path}
, pipe_name_{params.pipe_name}
, client_width_{params.client_width}
, client_height_{params.client_height}
, client_refresh_rate_{params.client_refresh_rate}
, client_codecs_{params.client_codecs}
, run_as_win_service_{ltlib::is_run_as_service()} {}
WorkerProcess::~WorkerProcess()
{
}
WorkerProcess::~WorkerProcess() {}
void WorkerProcess::start()
{
std::lock_guard lk { mutex_ };
void WorkerProcess::start() {
std::lock_guard lk{mutex_};
if (thread_ != nullptr) {
LOG(WARNING) << "Host process already launched";
return;
@@ -72,20 +62,21 @@ void WorkerProcess::start()
std::promise<void> promise;
auto future = promise.get_future();
thread_ = ltlib::BlockingThread::create(
"worker_process", [this, &promise](const std::function<void()>& i_am_alive, void*) {
"worker_process",
[this, &promise](const std::function<void()>& i_am_alive, void*) {
main_loop(promise, i_am_alive);
},
nullptr);
future.get();
}
void WorkerProcess::main_loop(std::promise<void>& promise, const std::function<void()>& i_am_alive)
{
void WorkerProcess::main_loop(std::promise<void>& promise,
const std::function<void()>& i_am_alive) {
while (!stoped_) {
i_am_alive();
if (!launch_worker_process()) {
LOG(WARNING) << "Launch worker process failed";
std::this_thread::sleep_for(std::chrono::milliseconds { 100 });
std::this_thread::sleep_for(std::chrono::milliseconds{100});
continue;
}
promise.set_value();
@@ -93,16 +84,11 @@ void WorkerProcess::main_loop(std::promise<void>& promise, const std::function<v
}
}
bool WorkerProcess::launch_worker_process()
{
bool WorkerProcess::launch_worker_process() {
std::stringstream ss;
ss << path_
<< " -type worker "
<< " -name " << pipe_name_
<< " -width " << client_width_
<< " -height " << client_height_
<< " -freq " << client_refresh_rate_
<< " -codecs " << ::to_string(client_codecs_);
ss << path_ << " -type worker "
<< " -name " << pipe_name_ << " -width " << client_width_ << " -height " << client_height_
<< " -freq " << client_refresh_rate_ << " -codecs " << ::to_string(client_codecs_);
std::wstring cmd = ltlib::utf8_to_utf16(ss.str());
if (process_handle_) {
CloseHandle(process_handle_);
@@ -123,7 +109,8 @@ bool WorkerProcess::launch_worker_process()
LOG(WARNING) << "OpenProcessToken fail: " << GetLastError();
return ret;
}
if (!DuplicateTokenEx(token, MAXIMUM_ALLOWED, 0, SecurityImpersonation, TokenPrimary, &user_token)) {
if (!DuplicateTokenEx(token, MAXIMUM_ALLOWED, 0, SecurityImpersonation, TokenPrimary,
&user_token)) {
LOG(WARNING) << "DuplicateTokenEx fail: " << GetLastError();
return ret;
}
@@ -133,25 +120,27 @@ bool WorkerProcess::launch_worker_process()
LOG(WARNING) << "WTSGetActiveConsoleSessionId fail" << GetLastError();
return ret;
}
if (!SetTokenInformation(user_token, (TOKEN_INFORMATION_CLASS)TokenSessionId, &curr_session_id, sizeof(curr_session_id))) {
if (!SetTokenInformation(user_token, (TOKEN_INFORMATION_CLASS)TokenSessionId,
&curr_session_id, sizeof(curr_session_id))) {
LOG(WARNING) << "SetTokenInformation fail: " << GetLastError();
return ret;
}
DWORD ui_access = 1;
if (!SetTokenInformation(user_token, (TOKEN_INFORMATION_CLASS)TokenUIAccess, &ui_access, sizeof(ui_access))) {
if (!SetTokenInformation(user_token, (TOKEN_INFORMATION_CLASS)TokenUIAccess, &ui_access,
sizeof(ui_access))) {
LOG(WARNING) << "SetTokenInformation fail: " << GetLastError();
return ret;
}
}
PROCESS_INFORMATION pi = { 0 };
SECURITY_ATTRIBUTES sa = { 0 };
PROCESS_INFORMATION pi = {0};
SECURITY_ATTRIBUTES sa = {0};
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
STARTUPINFO si = { 0 };
STARTUPINFOW si = {0};
si.dwFlags = STARTF_USESHOWWINDOW;
si.cb = sizeof(STARTUPINFO);
si.wShowWindow = SW_SHOW;
ret = CreateProcessAsUserW(user_token, NULL, const_cast<LPTSTR>(cmd.c_str()),
&sa, &sa, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
ret = CreateProcessAsUserW(user_token, NULL, const_cast<LPWSTR>(cmd.c_str()), &sa, &sa, FALSE,
NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
CloseHandle(token);
CloseHandle(user_token);
if (!ret) {
@@ -164,8 +153,7 @@ bool WorkerProcess::launch_worker_process()
return ret;
}
void WorkerProcess::wait_for_worker_process(const std::function<void()>& i_am_alive)
{
void WorkerProcess::wait_for_worker_process(const std::function<void()>& i_am_alive) {
int32_t count_seconds = 0;
while (!stoped_) {
i_am_alive();

View File

@@ -1,27 +1,27 @@
#include <Windows.h>
#include <set>
#include <g3log/g3log.hpp>
#include "display_setting.h"
namespace lt
{
#include <g3log/g3log.hpp>
#include <set>
namespace worker
{
namespace lt {
DisplaySetting DisplaySettingNegotiator::negotiate(DisplaySetting client_display_setting)
{
DEVMODE current_mode {};
current_mode.dmSize = sizeof(DEVMODE);
namespace worker {
DisplaySetting DisplaySettingNegotiator::negotiate(DisplaySetting client_display_setting) {
DEVMODEW current_mode{};
current_mode.dmSize = sizeof(DEVMODEW);
if (EnumDisplaySettingsW(nullptr, ENUM_CURRENT_SETTINGS, &current_mode) == 0) {
LOG(WARNING) << "Enumerate current display settings failed";
return {};
}
// 比较{width, height, refresh_rate ± 1}
std::set<DisplaySetting, decltype(&DisplaySetting::compare_full_loose)> available_settings { &DisplaySetting::compare_full_loose };
DEVMODE mode {};
mode.dmSize = sizeof(DEVMODE);
std::set<DisplaySetting, decltype(&DisplaySetting::compare_full_loose)> available_settings{
&DisplaySetting::compare_full_loose};
DEVMODEW mode{};
mode.dmSize = sizeof(DEVMODEW);
DWORD mode_num = 0;
while (EnumDisplaySettingsW(nullptr, mode_num, &mode) != 0) {
mode_num += 1;
@@ -34,7 +34,9 @@ DisplaySetting DisplaySettingNegotiator::negotiate(DisplaySetting client_display
}
// 比较{width, height}
std::set<DisplaySetting, decltype(&DisplaySetting::compare_width_height)> avaiable_settings2 { available_settings.begin(), available_settings.end(), &DisplaySetting::compare_width_height };
std::set<DisplaySetting, decltype(&DisplaySetting::compare_width_height)> avaiable_settings2{
available_settings.begin(), available_settings.end(),
&DisplaySetting::compare_width_height};
auto iter2 = avaiable_settings2.find(client_display_setting);
if (iter2 != avaiable_settings2.end()) {
DisplaySetting result = *iter2;
@@ -53,12 +55,12 @@ DisplaySetting DisplaySettingNegotiator::negotiate(DisplaySetting client_display
}
}
// 找不到直接返回host当前的DisplaySetting
DisplaySetting result(current_mode.dmPelsWidth, current_mode.dmPelsHeight, current_mode.dmDisplayFrequency);
DisplaySetting result(current_mode.dmPelsWidth, current_mode.dmPelsHeight,
current_mode.dmDisplayFrequency);
return result;
}
bool DisplaySetting::compare_full_strict(const DisplaySetting& lhs, const DisplaySetting& rhs)
{
bool DisplaySetting::compare_full_strict(const DisplaySetting& lhs, const DisplaySetting& rhs) {
if (lhs.width != rhs.width) {
return lhs.width < rhs.width;
}
@@ -68,8 +70,7 @@ bool DisplaySetting::compare_full_strict(const DisplaySetting& lhs, const Displa
return lhs.refrash_rate < rhs.refrash_rate;
}
bool DisplaySetting::compare_full_loose(const DisplaySetting& lhs, const DisplaySetting& rhs)
{
bool DisplaySetting::compare_full_loose(const DisplaySetting& lhs, const DisplaySetting& rhs) {
if (lhs.width != rhs.width) {
return lhs.width < rhs.width;
}
@@ -82,8 +83,7 @@ bool DisplaySetting::compare_full_loose(const DisplaySetting& lhs, const Display
return (rhs.refrash_rate > lhs.refrash_rate) && (rhs.refrash_rate - lhs.refrash_rate > 2);
}
bool DisplaySetting::compare_width_height(const DisplaySetting& lhs, const DisplaySetting& rhs)
{
bool DisplaySetting::compare_width_height(const DisplaySetting& lhs, const DisplaySetting& rhs) {
if (lhs.width != rhs.width) {
return lhs.width < rhs.width;
}

View File

@@ -125,7 +125,10 @@ Worker::Worker(const Params& params)
, last_time_received_from_service_{ltlib::steady_now_ms()} {}
Worker::~Worker() {
//
if (ioloop_) {
ioloop_->stop();
}
thread_.reset();
}
void Worker::wait() {

View File

@@ -1,4 +1,4 @@
//#include <process.h>
// #include <process.h>
#include <Windows.h>
#include <TlHelp32.h>
#include <Shlobj.h>
@@ -11,7 +11,7 @@
namespace
{
BOOL GetTokenByName(HANDLE& hToken, const LPTSTR lpName)
BOOL GetTokenByName(HANDLE& hToken, const LPWSTR lpName)
{
if (!lpName)
return FALSE;
@@ -26,7 +26,7 @@ BOOL GetTokenByName(HANDLE& hToken, const LPTSTR lpName)
pe32.dwSize = sizeof(PROCESSENTRY32W);
if (Process32First(hProcessSnap, &pe32)) {
if (Process32FirstW(hProcessSnap, &pe32)) {
do {
if (!wcscmp(wcsupr(pe32.szExeFile), wcsupr(lpName))) {
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);
@@ -50,33 +50,18 @@ bool execute_as_user(const std::function<bool(HANDLE)>& func)
HANDLE hToken = NULL;
bool res = false;
do {
//可能有些电脑在刚开机一直会失败
if (!GetTokenByName(hToken, (const LPTSTR) L"EXPLORER.EXE")) {
if (!GetTokenByName(hToken, (const LPWSTR)L"EXPLORER.EXE")) {
return false;
}
////可能进程还没起来
//for (int i = 0; i < 1; i++)
//{
// if (!GetTokenByName(hToken, (const LPTSTR)_T("EXPLORER.EXE")))
// {
// std::this_thread::sleep_for(std::chrono::seconds(1));
// continue;
// }
// break;
//}
if (!hToken) {
break;
}
// 模拟登录用户的安全上下文
if (FALSE == ImpersonateLoggedOnUser(hToken)) {
break;
}
res = func(hToken);
// 到这里已经模拟完了,别忘记返回原来的安全上下文
if (FALSE == RevertToSelf()) {
break;
}
@@ -88,7 +73,7 @@ bool execute_as_user(const std::function<bool(HANDLE)>& func)
return res;
}
} // 匿名空间
} // namespace
namespace ltlib
{
@@ -142,7 +127,7 @@ bool get_program_path(std::wstring& path)
return false;
}
template<>
template <>
std::string get_program_path<char>()
{
std::string path;
@@ -178,7 +163,7 @@ uint32_t get_session_id_by_pid(uint32_t pid)
{
DWORD sid = 0;
if (FALSE == ProcessIdToSessionId(pid, &sid)) {
//TODO error handling
// TODO error handling
return 0;
}
return sid;
@@ -191,7 +176,7 @@ uint32_t get_parent_pid(uint32_t curr_pid)
return 0;
}
PROCESSENTRY32 pe32;
PROCESSENTRY32W pe32;
pe32.dwSize = sizeof(pe32);
pe32.dwFlags = sizeof(pe32);
BOOL hProcess = Process32FirstW(PHANDLE, &pe32);
@@ -225,18 +210,18 @@ std::string get_appdata_path(bool is_service)
if (hr != S_OK) {
return false;
}
if (!pidl || !SHGetPathFromIDList(pidl, szDocument)) {
if (!pidl || !SHGetPathFromIDListW(pidl, szDocument)) {
return false;
}
CoTaskMemFree(pidl);
GetShortPathName(szDocument, m_lpszDefaultDir, _MAX_PATH);
appdata_path = utf16_to_utf8(std::wstring(m_lpszDefaultDir));
GetShortPathNameW(szDocument, m_lpszDefaultDir, _MAX_PATH);
appdata_path = utf16_to_utf8(std::wstring(m_lpszDefaultDir));
return true;
};
if (is_service) {
if (!execute_as_user(get_path)) {
//log_print(kError, _T("get_path fail"));
// log_print(kError, _T("get_path fail"));
return "";
}
return appdata_path;
@@ -306,13 +291,13 @@ bool set_thread_desktop()
break;
}
TCHAR cur_thread_desktop_name[1024] = { 0 };
TCHAR cur_input_desktop_name[1024] = { 0 };
WCHAR cur_thread_desktop_name[1024] = { 0 };
WCHAR cur_input_desktop_name[1024] = { 0 };
DWORD needLength = 0;
if (!GetUserObjectInformation(thread_desktop, UOI_NAME, cur_thread_desktop_name, sizeof(cur_thread_desktop_name), &needLength)) {
if (!GetUserObjectInformationW(thread_desktop, UOI_NAME, cur_thread_desktop_name, sizeof(cur_thread_desktop_name), &needLength)) {
break;
}
if (!GetUserObjectInformation(input_desktop, UOI_NAME, cur_input_desktop_name, sizeof(cur_input_desktop_name), &needLength)) {
if (!GetUserObjectInformationW(input_desktop, UOI_NAME, cur_input_desktop_name, sizeof(cur_input_desktop_name), &needLength)) {
break;
}

View File

@@ -18,7 +18,7 @@ bool get_service_status(SC_HANDLE service_handle, SERVICE_STATUS_PROCESS& servic
return false;
}
} // 匿名空间
} // namespace
namespace ltlib
{
@@ -34,7 +34,7 @@ ServiceApp::~ServiceApp()
void ServiceApp::run()
{
SERVICE_TABLE_ENTRY dispatch_table[] = {
SERVICE_TABLE_ENTRYW dispatch_table[] = {
{ NULL, (LPSERVICE_MAIN_FUNCTIONW)service_main },
{ NULL, NULL }
};
@@ -60,7 +60,6 @@ bool ServiceApp::report_status(uint32_t current_state, uint32_t win32_exit_code,
return SetServiceStatus(g_status_handle, &g_status) == TRUE;
}
void __stdcall ServiceApp::service_main()
{
std::wstring service_name;
@@ -74,7 +73,6 @@ void __stdcall ServiceApp::service_main()
report_status(SERVICE_STOPPED, NO_ERROR, 0);
}
void __stdcall ServiceApp::service_control_handler(unsigned long ctrl_code)
{
switch (ctrl_code) {