提交 926b9c5f 编写于 作者: J jp9000

win-capture: Open UWP named objects with helper functions

This detects whether the target process is a UWP process, and then uses
the open_app_* functions for mutexes/events/mapping.  Also slightly
refactors named object open functions.
上级 aeb1d7ae
......@@ -12,6 +12,7 @@
#include "graphics-hook-info.h"
#include "window-helpers.h"
#include "cursor-capture.h"
#include "app-helpers.h"
#define do_log(level, format, ...) \
blog(level, "[game-capture: '%s'] " format, \
......@@ -127,6 +128,7 @@ struct game_capture {
bool dwm_capture : 1;
bool initial_config : 1;
bool convert_16bit : 1;
bool is_app : 1;
struct game_capture_config config;
......@@ -144,6 +146,7 @@ struct game_capture {
HANDLE global_hook_info_map;
HANDLE target_process;
HANDLE texture_mutexes[2];
wchar_t *app_sid;
union {
struct {
......@@ -161,6 +164,61 @@ struct game_capture {
struct graphics_offsets offsets32 = {0};
struct graphics_offsets offsets64 = {0};
static inline bool use_anticheat(struct game_capture *gc)
{
return gc->config.anticheat_hook && !gc->is_app;
}
static inline HANDLE open_mutex_plus_id(struct game_capture *gc,
const wchar_t *name, DWORD id)
{
wchar_t new_name[64];
_snwprintf(new_name, 64, L"%s%lu", name, id);
return gc->is_app
? open_app_mutex(gc->app_sid, new_name)
: open_mutex(new_name);
}
static inline HANDLE open_mutex_gc(struct game_capture *gc,
const wchar_t *name)
{
return open_mutex_plus_id(gc, name, gc->process_id);
}
static inline HANDLE open_event_plus_id(struct game_capture *gc,
const wchar_t *name, DWORD id)
{
wchar_t new_name[64];
_snwprintf(new_name, 64, L"%s%lu", name, id);
return gc->is_app
? open_app_event(gc->app_sid, new_name)
: open_event(new_name);
}
static inline HANDLE open_event_gc(struct game_capture *gc,
const wchar_t *name)
{
return open_event_plus_id(gc, name, gc->process_id);
}
static inline HANDLE open_map_plus_id(struct game_capture *gc,
const wchar_t *name, DWORD id)
{
wchar_t new_name[64];
_snwprintf(new_name, 64, L"%s%lu", name, id);
debug("map id: %S", new_name);
return gc->is_app
? open_app_map(gc->app_sid, new_name)
: OpenFileMappingW(GC_MAPPING_FLAGS, false, new_name);
}
static inline HANDLE open_hook_info(struct game_capture *gc)
{
return open_map_plus_id(gc, SHMEM_HOOK_INFO, gc->process_id);
}
static inline enum gs_color_format convert_format(uint32_t format)
{
switch (format) {
......@@ -227,6 +285,11 @@ static void stop_capture(struct game_capture *gc)
close_handle(&gc->keepalive_thread);
}
if (gc->app_sid) {
LocalFree(gc->app_sid);
gc->app_sid = NULL;
}
close_handle(&gc->hook_restart);
close_handle(&gc->hook_stop);
close_handle(&gc->hook_ready);
......@@ -563,6 +626,10 @@ static inline bool open_target_process(struct game_capture *gc)
}
gc->process_is_64bit = is_64bit_process(gc->target_process);
gc->is_app = is_app(gc->target_process);
if (gc->is_app) {
gc->app_sid = get_app_sid(gc->target_process);
}
return true;
}
......@@ -643,10 +710,8 @@ static inline bool init_keepalive(struct game_capture *gc)
static inline bool init_texture_mutexes(struct game_capture *gc)
{
gc->texture_mutexes[0] = open_mutex_plus_id(MUTEX_TEXTURE1,
gc->process_id);
gc->texture_mutexes[1] = open_mutex_plus_id(MUTEX_TEXTURE2,
gc->process_id);
gc->texture_mutexes[0] = open_mutex_gc(gc, MUTEX_TEXTURE1);
gc->texture_mutexes[1] = open_mutex_gc(gc, MUTEX_TEXTURE2);
if (!gc->texture_mutexes[0] || !gc->texture_mutexes[1]) {
warn("failed to open texture mutexes: %lu", GetLastError());
......@@ -659,8 +724,7 @@ static inline bool init_texture_mutexes(struct game_capture *gc)
/* if there's already a hook in the process, then signal and start */
static inline bool attempt_existing_hook(struct game_capture *gc)
{
gc->hook_restart = open_event_plus_id(EVENT_CAPTURE_RESTART,
gc->process_id);
gc->hook_restart = open_event_gc(gc, EVENT_CAPTURE_RESTART);
if (gc->hook_restart) {
debug("existing hook found, signaling process: %s",
gc->config.executable);
......@@ -692,7 +756,7 @@ static inline void reset_frame_interval(struct game_capture *gc)
static inline bool init_hook_info(struct game_capture *gc)
{
gc->global_hook_info_map = open_hook_info(gc->process_id);
gc->global_hook_info_map = open_hook_info(gc);
if (!gc->global_hook_info_map) {
warn("init_hook_info: get_hook_info failed: %lu",
GetLastError());
......@@ -807,7 +871,7 @@ static inline bool create_inject_process(struct game_capture *gc,
wchar_t *command_line_w = malloc(4096 * sizeof(wchar_t));
wchar_t *inject_path_w;
wchar_t *hook_dll_w;
bool anti_cheat = gc->config.anticheat_hook;
bool anti_cheat = use_anticheat(gc);
PROCESS_INFORMATION pi = {0};
STARTUPINFO si = {0};
bool success = false;
......@@ -869,11 +933,11 @@ static inline bool inject_hook(struct game_capture *gc)
matching_architecture = !gc->process_is_64bit;
#endif
if (matching_architecture && !gc->config.anticheat_hook) {
if (matching_architecture && !use_anticheat(gc)) {
info("using direct hook");
success = hook_direct(gc, hook_path);
} else {
info("using helper (%s hook)", gc->config.anticheat_hook ?
info("using helper (%s hook)", use_anticheat(gc) ?
"compatibility" : "direct");
success = create_inject_process(gc, inject_path, hook_dll);
}
......@@ -976,13 +1040,24 @@ static bool init_hook(struct game_capture *gc)
static void setup_window(struct game_capture *gc, HWND window)
{
DWORD process_id = 0;
HANDLE hook_restart;
HANDLE process;
GetWindowThreadProcessId(window, &process_id);
GetWindowThreadProcessId(window, &gc->process_id);
if (gc->process_id) {
process = open_process(PROCESS_QUERY_INFORMATION,
false, gc->process_id);
if (process) {
gc->is_app = is_app(process);
if (gc->is_app) {
gc->app_sid = get_app_sid(process);
}
CloseHandle(process);
}
}
/* do not wait if we're re-hooking a process */
hook_restart = open_event_plus_id(EVENT_CAPTURE_RESTART, process_id);
hook_restart = open_event_gc(gc, EVENT_CAPTURE_RESTART);
if (hook_restart) {
gc->wait_for_target_startup = false;
CloseHandle(hook_restart);
......@@ -1102,8 +1177,7 @@ static void try_hook(struct game_capture *gc)
static inline bool init_events(struct game_capture *gc)
{
if (!gc->hook_restart) {
gc->hook_restart = open_event_plus_id(EVENT_CAPTURE_RESTART,
gc->process_id);
gc->hook_restart = open_event_gc(gc, EVENT_CAPTURE_RESTART);
if (!gc->hook_restart) {
warn("init_events: failed to get hook_restart "
"event: %lu", GetLastError());
......@@ -1112,8 +1186,7 @@ static inline bool init_events(struct game_capture *gc)
}
if (!gc->hook_stop) {
gc->hook_stop = open_event_plus_id(EVENT_CAPTURE_STOP,
gc->process_id);
gc->hook_stop = open_event_gc(gc, EVENT_CAPTURE_STOP);
if (!gc->hook_stop) {
warn("init_events: failed to get hook_stop event: %lu",
GetLastError());
......@@ -1122,8 +1195,7 @@ static inline bool init_events(struct game_capture *gc)
}
if (!gc->hook_init) {
gc->hook_init = open_event_plus_id(EVENT_HOOK_INIT,
gc->process_id);
gc->hook_init = open_event_gc(gc, EVENT_HOOK_INIT);
if (!gc->hook_init) {
warn("init_events: failed to get hook_init event: %lu",
GetLastError());
......@@ -1132,8 +1204,7 @@ static inline bool init_events(struct game_capture *gc)
}
if (!gc->hook_ready) {
gc->hook_ready = open_event_plus_id(EVENT_HOOK_READY,
gc->process_id);
gc->hook_ready = open_event_gc(gc, EVENT_HOOK_READY);
if (!gc->hook_ready) {
warn("init_events: failed to get hook_ready event: %lu",
GetLastError());
......@@ -1142,8 +1213,7 @@ static inline bool init_events(struct game_capture *gc)
}
if (!gc->hook_exit) {
gc->hook_exit = open_event_plus_id(EVENT_HOOK_EXIT,
gc->process_id);
gc->hook_exit = open_event_gc(gc, EVENT_HOOK_EXIT);
if (!gc->hook_exit) {
warn("init_events: failed to get hook_exit event: %lu",
GetLastError());
......@@ -1162,9 +1232,6 @@ enum capture_result {
static inline enum capture_result init_capture_data(struct game_capture *gc)
{
char name[64];
sprintf(name, "%s%u", SHMEM_TEXTURE, gc->global_hook_info->map_id);
gc->cx = gc->global_hook_info->cx;
gc->cy = gc->global_hook_info->cy;
gc->pitch = gc->global_hook_info->pitch;
......@@ -1176,7 +1243,8 @@ static inline enum capture_result init_capture_data(struct game_capture *gc)
CloseHandle(gc->hook_data_map);
gc->hook_data_map = OpenFileMappingA(FILE_MAP_ALL_ACCESS, false, name);
gc->hook_data_map = open_map_plus_id(gc, SHMEM_TEXTURE,
gc->global_hook_info->map_id);
if (!gc->hook_data_map) {
DWORD error = GetLastError();
if (error == 2) {
......@@ -1552,8 +1620,7 @@ static void game_capture_tick(void *data, float seconds)
}
if (gc->active && !gc->hook_ready && gc->process_id) {
gc->hook_ready = open_event_plus_id(EVENT_HOOK_READY,
gc->process_id);
gc->hook_ready = open_event_gc(gc, EVENT_HOOK_READY);
}
if (gc->injector_process && object_signalled(gc->injector_process)) {
......
......@@ -113,11 +113,3 @@ static inline HANDLE create_hook_info(DWORD id)
return CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
0, sizeof(struct hook_info), new_name);
}
static inline HANDLE open_hook_info(DWORD id)
{
wchar_t new_name[64];
_snwprintf(new_name, 64, L"%s%lu", SHMEM_HOOK_INFO, id);
return OpenFileMappingW(GC_MAPPING_FLAGS, false, new_name);
}
......@@ -34,13 +34,6 @@ static inline HANDLE create_event_plus_id(const wchar_t *name, DWORD id)
return create_event(new_name);
}
static inline HANDLE open_event_plus_id(const wchar_t *name, DWORD id)
{
wchar_t new_name[64];
_snwprintf(new_name, 64, L"%s%lu", name, id);
return open_event(new_name);
}
static inline HANDLE create_mutex_plus_id(const wchar_t *name, DWORD id)
{
wchar_t new_name[64];
......@@ -48,13 +41,6 @@ static inline HANDLE create_mutex_plus_id(const wchar_t *name, DWORD id)
return create_mutex(new_name);
}
static inline HANDLE open_mutex_plus_id(const wchar_t *name, DWORD id)
{
wchar_t new_name[64];
_snwprintf(new_name, 64, L"%s%lu", name, id);
return open_mutex(new_name);
}
static inline bool object_signalled(HANDLE event)
{
if (!event)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册