clang-format: Apply formatting

Code submissions have continually suffered from formatting
inconsistencies that constantly have to be addressed.  Using
clang-format simplifies this by making code formatting more consistent,
and allows automation of the code formatting so that maintainers can
focus more on the code itself instead of code formatting.
This commit is contained in:
jp9000
2019-06-22 22:13:45 -07:00
parent 53615ee10f
commit f53df7da64
567 changed files with 34068 additions and 32903 deletions

View File

@@ -13,7 +13,8 @@ bool is_app(HANDLE process)
if (OpenProcessToken(process, TOKEN_QUERY, &token)) {
BOOL success = GetTokenInformation(token, TokenIsAppContainer,
&ret, sizeof(ret), &size_ret);
&ret, sizeof(ret),
&size_ret);
if (!success) {
DWORD error = GetLastError();
int test = 0;
@@ -33,12 +34,12 @@ wchar_t *get_app_sid(HANDLE process)
if (OpenProcessToken(process, TOKEN_QUERY, &token)) {
DWORD info_len = GetSidLengthRequired(12) +
sizeof(TOKEN_APPCONTAINER_INFORMATION);
sizeof(TOKEN_APPCONTAINER_INFORMATION);
PTOKEN_APPCONTAINER_INFORMATION info = malloc(info_len);
success = GetTokenInformation(token, TokenAppContainerSid,
info, info_len, &size_ret);
success = GetTokenInformation(token, TokenAppContainerSid, info,
info_len, &size_ret);
if (success)
ConvertSidToStringSidW(info->TokenAppContainer, &ret);

View File

@@ -47,7 +47,7 @@ static inline void apply_mask(uint8_t *color, uint8_t *mask, long num_pixels)
}
static inline uint8_t *copy_from_color(ICONINFO *ii, uint32_t *width,
uint32_t *height)
uint32_t *height)
{
BITMAP bmp_color;
BITMAP bmp_mask;
@@ -80,7 +80,7 @@ static inline uint8_t *copy_from_color(ICONINFO *ii, uint32_t *width,
}
static inline uint8_t *copy_from_mask(ICONINFO *ii, uint32_t *width,
uint32_t *height)
uint32_t *height)
{
uint8_t *output;
uint8_t *mask;
@@ -107,8 +107,8 @@ static inline uint8_t *copy_from_mask(ICONINFO *ii, uint32_t *width,
if (!alpha) {
output[i * 4 + 3] = color;
} else {
*(uint32_t*)&output[i * 4] = !!color ?
0xFFFFFFFF : 0xFF000000;
*(uint32_t *)&output[i * 4] = !!color ? 0xFFFFFFFF
: 0xFF000000;
}
}
@@ -119,8 +119,8 @@ static inline uint8_t *copy_from_mask(ICONINFO *ii, uint32_t *width,
return output;
}
static inline uint8_t *cursor_capture_icon_bitmap(ICONINFO *ii,
uint32_t *width, uint32_t *height)
static inline uint8_t *cursor_capture_icon_bitmap(ICONINFO *ii, uint32_t *width,
uint32_t *height)
{
uint8_t *output;
@@ -131,8 +131,8 @@ static inline uint8_t *cursor_capture_icon_bitmap(ICONINFO *ii,
return output;
}
static gs_texture_t *get_cached_texture(struct cursor_data *data,
uint32_t cx, uint32_t cy)
static gs_texture_t *get_cached_texture(struct cursor_data *data, uint32_t cx,
uint32_t cy)
{
struct cached_cursor cc;
@@ -210,7 +210,7 @@ void cursor_capture(struct cursor_data *data)
}
void cursor_draw(struct cursor_data *data, long x_offset, long y_offset,
float x_scale, float y_scale, long width, long height)
float x_scale, float y_scale, long width, long height)
{
long x = data->cursor_pos.x + x_offset;
long y = data->cursor_pos.y + y_offset;

View File

@@ -9,20 +9,20 @@ struct cached_cursor {
};
struct cursor_data {
gs_texture_t *texture;
HCURSOR current_cursor;
POINT cursor_pos;
long x_hotspot;
long y_hotspot;
bool visible;
gs_texture_t *texture;
HCURSOR current_cursor;
POINT cursor_pos;
long x_hotspot;
long y_hotspot;
bool visible;
uint32_t last_cx;
uint32_t last_cy;
uint32_t last_cx;
uint32_t last_cy;
DARRAY(struct cached_cursor) cached_textures;
DARRAY(struct cached_cursor) cached_textures;
};
extern void cursor_capture(struct cursor_data *data);
extern void cursor_draw(struct cursor_data *data, long x_offset, long y_offset,
float x_scale, float y_scale, long width, long height);
float x_scale, float y_scale, long width, long height);
extern void cursor_data_free(struct cursor_data *data);

View File

@@ -6,12 +6,12 @@
static inline void init_textures(struct dc_capture *capture)
{
if (capture->compatibility)
capture->texture = gs_texture_create(
capture->width, capture->height,
GS_BGRA, 1, NULL, GS_DYNAMIC);
capture->texture = gs_texture_create(capture->width,
capture->height, GS_BGRA,
1, NULL, GS_DYNAMIC);
else
capture->texture = gs_texture_create_gdi(
capture->width, capture->height);
capture->texture =
gs_texture_create_gdi(capture->width, capture->height);
if (!capture->texture) {
blog(LOG_WARNING, "[dc_capture_init] Failed to "
@@ -22,16 +22,15 @@ static inline void init_textures(struct dc_capture *capture)
capture->valid = true;
}
void dc_capture_init(struct dc_capture *capture, int x, int y,
uint32_t width, uint32_t height, bool cursor,
bool compatibility)
void dc_capture_init(struct dc_capture *capture, int x, int y, uint32_t width,
uint32_t height, bool cursor, bool compatibility)
{
memset(capture, 0, sizeof(struct dc_capture));
capture->x = x;
capture->y = y;
capture->width = width;
capture->height = height;
capture->x = x;
capture->y = y;
capture->width = width;
capture->height = height;
capture->capture_cursor = cursor;
obs_enter_graphics();
@@ -51,16 +50,16 @@ void dc_capture_init(struct dc_capture *capture, int x, int y,
if (compatibility) {
BITMAPINFO bi = {0};
BITMAPINFOHEADER *bih = &bi.bmiHeader;
bih->biSize = sizeof(BITMAPINFOHEADER);
bih->biSize = sizeof(BITMAPINFOHEADER);
bih->biBitCount = 32;
bih->biWidth = width;
bih->biHeight = height;
bih->biPlanes = 1;
bih->biWidth = width;
bih->biHeight = height;
bih->biPlanes = 1;
capture->hdc = CreateCompatibleDC(NULL);
capture->bmp = CreateDIBSection(capture->hdc, &bi,
DIB_RGB_COLORS, (void**)&capture->bits,
NULL, 0);
capture->bmp =
CreateDIBSection(capture->hdc, &bi, DIB_RGB_COLORS,
(void **)&capture->bits, NULL, 0);
capture->old_bmp = SelectObject(capture->hdc, capture->bmp);
}
}
@@ -82,10 +81,10 @@ void dc_capture_free(struct dc_capture *capture)
static void draw_cursor(struct dc_capture *capture, HDC hdc, HWND window)
{
HICON icon;
ICONINFO ii;
HICON icon;
ICONINFO ii;
CURSORINFO *ci = &capture->ci;
POINT win_pos = {capture->x, capture->y};
POINT win_pos = {capture->x, capture->y};
if (!(capture->ci.flags & CURSOR_SHOWING))
return;
@@ -103,8 +102,7 @@ static void draw_cursor(struct dc_capture *capture, HDC hdc, HWND window)
pos.x = ci->ptScreenPos.x - (int)ii.xHotspot - win_pos.x;
pos.y = ci->ptScreenPos.y - (int)ii.yHotspot - win_pos.y;
DrawIconEx(hdc, pos.x, pos.y, icon, 0, 0, 0, NULL,
DI_NORMAL);
DrawIconEx(hdc, pos.x, pos.y, icon, 0, 0, 0, NULL, DI_NORMAL);
DeleteObject(ii.hbmColor);
DeleteObject(ii.hbmMask);
@@ -127,8 +125,8 @@ static inline HDC dc_capture_get_dc(struct dc_capture *capture)
static inline void dc_capture_release_dc(struct dc_capture *capture)
{
if (capture->compatibility) {
gs_texture_set_image(capture->texture,
capture->bits, capture->width*4, false);
gs_texture_set_image(capture->texture, capture->bits,
capture->width * 4, false);
} else {
gs_texture_release_dc(capture->texture);
}
@@ -148,14 +146,14 @@ void dc_capture_capture(struct dc_capture *capture, HWND window)
hdc = dc_capture_get_dc(capture);
if (!hdc) {
blog(LOG_WARNING, "[capture_screen] Failed to get "
"texture DC");
"texture DC");
return;
}
hdc_target = GetDC(window);
BitBlt(hdc, 0, 0, capture->width, capture->height,
hdc_target, capture->x, capture->y, SRCCOPY);
BitBlt(hdc, 0, 0, capture->width, capture->height, hdc_target,
capture->x, capture->y, SRCCOPY);
ReleaseDC(NULL, hdc_target);
@@ -169,10 +167,10 @@ void dc_capture_capture(struct dc_capture *capture, HWND window)
static void draw_texture(struct dc_capture *capture, gs_effect_t *effect)
{
gs_texture_t *texture = capture->texture;
gs_technique_t *tech = gs_effect_get_technique(effect, "Draw");
gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image");
size_t passes;
gs_texture_t *texture = capture->texture;
gs_technique_t *tech = gs_effect_get_technique(effect, "Draw");
gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image");
size_t passes;
gs_effect_set_texture(image, texture);

View File

@@ -7,27 +7,27 @@
struct dc_capture {
gs_texture_t *texture;
bool texture_written;
int x, y;
uint32_t width;
uint32_t height;
bool texture_written;
int x, y;
uint32_t width;
uint32_t height;
bool compatibility;
HDC hdc;
HBITMAP bmp, old_bmp;
BYTE *bits;
bool compatibility;
HDC hdc;
HBITMAP bmp, old_bmp;
BYTE *bits;
bool capture_cursor;
bool cursor_captured;
bool cursor_hidden;
CURSORINFO ci;
bool capture_cursor;
bool cursor_captured;
bool cursor_hidden;
CURSORINFO ci;
bool valid;
bool valid;
};
extern void dc_capture_init(struct dc_capture *capture, int x, int y,
uint32_t width, uint32_t height, bool cursor,
bool compatibility);
uint32_t width, uint32_t height, bool cursor,
bool compatibility);
extern void dc_capture_free(struct dc_capture *capture);
extern void dc_capture_capture(struct dc_capture *capture, HWND window);

View File

@@ -5,13 +5,15 @@
#include "cursor-capture.h"
#define do_log(level, format, ...) \
#define do_log(level, format, ...) \
blog(level, "[duplicator-monitor-capture: '%s'] " format, \
obs_source_get_name(capture->source), ##__VA_ARGS__)
obs_source_get_name(capture->source), ##__VA_ARGS__)
#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__)
#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__)
#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__)
#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__)
#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__)
#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__)
/* clang-format off */
#define TEXT_MONITOR_CAPTURE obs_module_text("MonitorCapture")
#define TEXT_CAPTURE_CURSOR obs_module_text("CaptureCursor")
@@ -19,30 +21,32 @@
#define TEXT_MONITOR obs_module_text("Monitor")
#define TEXT_PRIMARY_MONITOR obs_module_text("PrimaryMonitor")
/* clang-format on */
#define RESET_INTERVAL_SEC 3.0f
struct duplicator_capture {
obs_source_t *source;
int monitor;
bool capture_cursor;
bool showing;
obs_source_t *source;
int monitor;
bool capture_cursor;
bool showing;
long x;
long y;
int rot;
uint32_t width;
uint32_t height;
gs_duplicator_t *duplicator;
float reset_timeout;
struct cursor_data cursor_data;
long x;
long y;
int rot;
uint32_t width;
uint32_t height;
gs_duplicator_t *duplicator;
float reset_timeout;
struct cursor_data cursor_data;
};
/* ------------------------------------------------------------------------- */
static inline void update_settings(struct duplicator_capture *capture,
obs_data_t *settings)
obs_data_t *settings)
{
capture->monitor = (int)obs_data_get_int(settings, "monitor");
capture->monitor = (int)obs_data_get_int(settings, "monitor");
capture->capture_cursor = obs_data_get_bool(settings, "capture_cursor");
obs_enter_graphics();
@@ -94,7 +98,7 @@ static void duplicator_capture_update(void *data, obs_data_t *settings)
}
static void *duplicator_capture_create(obs_data_t *settings,
obs_source_t *source)
obs_source_t *source)
{
struct duplicator_capture *capture;
@@ -148,7 +152,7 @@ static void duplicator_capture_tick(void *data, float seconds)
}
return;
/* always try to load the capture immediately when the source is first
/* always try to load the capture immediately when the source is first
* shown */
} else if (!capture->showing) {
capture->reset_timeout = RESET_INTERVAL_SEC;
@@ -201,10 +205,9 @@ static uint32_t duplicator_capture_height(void *data)
static void draw_cursor(struct duplicator_capture *capture)
{
cursor_draw(&capture->cursor_data, -capture->x, -capture->y,
1.0f, 1.0f,
capture->rot % 180 == 0 ? capture->width : capture->height,
capture->rot % 180 == 0 ? capture->height : capture->width);
cursor_draw(&capture->cursor_data, -capture->x, -capture->y, 1.0f, 1.0f,
capture->rot % 180 == 0 ? capture->width : capture->height,
capture->rot % 180 == 0 ? capture->height : capture->width);
}
static void duplicator_capture_render(void *data, gs_effect_t *effect)
@@ -270,12 +273,11 @@ static bool get_monitor_props(obs_property_t *monitor_list, int monitor_idx)
if (!gs_get_duplicator_monitor_info(monitor_idx, &info))
return false;
dstr_catf(&monitor_desc, "%s %d: %ldx%ld @ %ld,%ld",
TEXT_MONITOR, monitor_idx + 1,
info.cx, info.cy, info.x, info.y);
dstr_catf(&monitor_desc, "%s %d: %ldx%ld @ %ld,%ld", TEXT_MONITOR,
monitor_idx + 1, info.cx, info.cy, info.x, info.y);
obs_property_list_add_int(monitor_list, monitor_desc.array,
monitor_idx);
monitor_idx);
dstr_free(&monitor_desc);
@@ -290,15 +292,16 @@ static obs_properties_t *duplicator_capture_properties(void *unused)
obs_properties_t *props = obs_properties_create();
obs_property_t *monitors = obs_properties_add_list(props,
"monitor", TEXT_MONITOR,
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_t *monitors = obs_properties_add_list(
props, "monitor", TEXT_MONITOR, OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_properties_add_bool(props, "capture_cursor", TEXT_CAPTURE_CURSOR);
obs_enter_graphics();
while (get_monitor_props(monitors, monitor_idx++));
while (get_monitor_props(monitors, monitor_idx++))
;
obs_leave_graphics();
@@ -306,18 +309,18 @@ static obs_properties_t *duplicator_capture_properties(void *unused)
}
struct obs_source_info duplicator_capture_info = {
.id = "monitor_capture",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW |
OBS_SOURCE_DO_NOT_DUPLICATE,
.get_name = duplicator_capture_getname,
.create = duplicator_capture_create,
.destroy = duplicator_capture_destroy,
.video_render = duplicator_capture_render,
.video_tick = duplicator_capture_tick,
.update = duplicator_capture_update,
.get_width = duplicator_capture_width,
.get_height = duplicator_capture_height,
.get_defaults = duplicator_capture_defaults,
.get_properties = duplicator_capture_properties
.id = "monitor_capture",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW |
OBS_SOURCE_DO_NOT_DUPLICATE,
.get_name = duplicator_capture_getname,
.create = duplicator_capture_create,
.destroy = duplicator_capture_destroy,
.video_render = duplicator_capture_render,
.video_tick = duplicator_capture_tick,
.update = duplicator_capture_update,
.get_width = duplicator_capture_width,
.get_height = duplicator_capture_height,
.get_defaults = duplicator_capture_defaults,
.get_properties = duplicator_capture_properties,
};

View File

@@ -2,11 +2,11 @@
#include <stdlib.h>
#include "funchook.h"
#define JMP_64_SIZE 14
#define JMP_32_SIZE 5
#define JMP_64_SIZE 14
#define JMP_32_SIZE 5
#define X86_NOP 0x90
#define X86_JMP_NEG_5 0xF9EB
#define X86_NOP 0x90
#define X86_JMP_NEG_5 0xF9EB
static inline void fix_permissions(void *addr, size_t size)
{
@@ -14,8 +14,8 @@ static inline void fix_permissions(void *addr, size_t size)
VirtualProtect(addr, size, PAGE_EXECUTE_READWRITE, &protect_val);
}
void hook_init(struct func_hook *hook,
void *func_addr, void *hook_addr, const char *name)
void hook_init(struct func_hook *hook, void *func_addr, void *hook_addr,
const char *name)
{
memset(hook, 0, sizeof(*hook));
@@ -23,7 +23,7 @@ void hook_init(struct func_hook *hook,
hook->hook_addr = (uintptr_t)hook_addr;
hook->name = name;
fix_permissions((void*)(hook->func_addr - JMP_32_SIZE),
fix_permissions((void *)(hook->func_addr - JMP_32_SIZE),
JMP_64_SIZE + JMP_32_SIZE);
memcpy(hook->unhook_data, func_addr, JMP_64_SIZE);
@@ -39,30 +39,30 @@ static const uint8_t longjmp64[6] = {0xFF, 0x25, 0x00, 0x00, 0x00, 0x00};
static inline void rehook64(struct func_hook *hook)
{
uint8_t data[JMP_64_SIZE];
uintptr_t *ptr_loc = (uintptr_t*)((uint8_t*)data + sizeof(longjmp64));
uintptr_t *ptr_loc = (uintptr_t *)((uint8_t *)data + sizeof(longjmp64));
fix_permissions((void*)hook->func_addr, JMP_64_SIZE);
fix_permissions((void *)hook->func_addr, JMP_64_SIZE);
memcpy(data, (void*)hook->func_addr, JMP_64_SIZE);
memcpy(data, (void *)hook->func_addr, JMP_64_SIZE);
memcpy(data, longjmp64, sizeof(longjmp64));
*ptr_loc = hook->hook_addr;
hook->call_addr = (void*)hook->func_addr;
hook->call_addr = (void *)hook->func_addr;
hook->type = HOOKTYPE_FORWARD_OVERWRITE;
hook->hooked = true;
memcpy((void*)hook->func_addr, data, JMP_64_SIZE);
memcpy((void *)hook->func_addr, data, JMP_64_SIZE);
}
static inline void hook_reverse_new(struct func_hook *hook, uint8_t *p)
{
hook->call_addr = (void*)(hook->func_addr + 2);
hook->call_addr = (void *)(hook->func_addr + 2);
hook->type = HOOKTYPE_REVERSE_CHAIN;
hook->hooked = true;
p[0] = 0xE9;
*((uint32_t*)&p[1]) = (uint32_t)(hook->hook_addr - hook->func_addr);
*((uint16_t*)&p[5]) = X86_JMP_NEG_5;
*((uint32_t *)&p[1]) = (uint32_t)(hook->hook_addr - hook->func_addr);
*((uint16_t *)&p[5]) = X86_JMP_NEG_5;
}
static inline void hook_reverse_chain(struct func_hook *hook, uint8_t *p)
@@ -70,49 +70,49 @@ static inline void hook_reverse_chain(struct func_hook *hook, uint8_t *p)
if (hook->type != HOOKTYPE_FORWARD_OVERWRITE)
return;
hook->call_addr = (void*)(hook->func_addr + *((int32_t*)&p[1]));
hook->call_addr = (void *)(hook->func_addr + *((int32_t *)&p[1]));
hook->type = HOOKTYPE_REVERSE_CHAIN;
hook->hooked = true;
*((uint32_t*)&p[1]) = (uint32_t)(hook->hook_addr - hook->func_addr);
*((uint32_t *)&p[1]) = (uint32_t)(hook->hook_addr - hook->func_addr);
}
static inline void hook_forward_chain(struct func_hook *hook, uint8_t *p,
intptr_t offset)
intptr_t offset)
{
int32_t cur_offset = *(int32_t*)&p[6];
int32_t cur_offset = *(int32_t *)&p[6];
if (hook->type != HOOKTYPE_FORWARD_OVERWRITE)
return;
hook->call_addr = (void*)(hook->func_addr + JMP_32_SIZE + cur_offset);
hook->call_addr = (void *)(hook->func_addr + JMP_32_SIZE + cur_offset);
hook->type = HOOKTYPE_FORWARD_CHAIN;
hook->hooked = true;
*((int32_t*)&p[6]) = (int32_t)offset;
*((int32_t *)&p[6]) = (int32_t)offset;
}
static inline void hook_forward_overwrite(struct func_hook *hook,
intptr_t offset)
intptr_t offset)
{
uint8_t *ptr = (uint8_t*)hook->func_addr;
uint8_t *ptr = (uint8_t *)hook->func_addr;
hook->call_addr = (void*)hook->func_addr;
hook->call_addr = (void *)hook->func_addr;
hook->type = HOOKTYPE_FORWARD_OVERWRITE;
hook->hooked = true;
*(ptr++) = 0xE9;
*((int32_t*)ptr) = (int32_t)offset;
*((int32_t *)ptr) = (int32_t)offset;
}
static inline void rehook32(struct func_hook *hook, bool force, intptr_t offset)
{
fix_permissions((void*)(hook->func_addr - JMP_32_SIZE),
fix_permissions((void *)(hook->func_addr - JMP_32_SIZE),
JMP_32_SIZE * 2);
if (force || !hook->started) {
uint8_t *p = (uint8_t*)hook->func_addr - JMP_32_SIZE;
size_t nop_count = 0;
uint8_t *p = (uint8_t *)hook->func_addr - JMP_32_SIZE;
size_t nop_count = 0;
/* check for reverse chain hook availability */
for (size_t i = 0; i < JMP_32_SIZE; i++) {
@@ -123,7 +123,8 @@ static inline void rehook32(struct func_hook *hook, bool force, intptr_t offset)
if (nop_count == JMP_32_SIZE && p[5] == 0x8B && p[6] == 0xFF) {
hook_reverse_new(hook, p);
} else if (p[0] == 0xE9 && *(uint16_t*)&p[5] == X86_JMP_NEG_5) {
} else if (p[0] == 0xE9 &&
*(uint16_t *)&p[5] == X86_JMP_NEG_5) {
hook_reverse_chain(hook, p);
} else if (p[5] == 0xE9) {
@@ -157,7 +158,8 @@ static void setup_64bit_bounce(struct func_hook *hook, intptr_t *offset)
int i;
success = VirtualQueryEx(GetCurrentProcess(),
(const void*)hook->func_addr, &mbi, sizeof(mbi));
(const void *)hook->func_addr, &mbi,
sizeof(mbi));
if (!success)
return;
@@ -167,19 +169,20 @@ static void setup_64bit_bounce(struct func_hook *hook, intptr_t *offset)
address = (uintptr_t)mbi.AllocationBase - pagesize;
for (i = 0; i < 256; i++, address -= pagesize) {
hook->bounce_addr = VirtualAlloc((LPVOID)address, pagesize,
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if (hook->bounce_addr)
break;
}
if (!hook->bounce_addr) {
address = (uintptr_t)mbi.AllocationBase + mbi.RegionSize +
pagesize;
pagesize;
for (i = 0; i < 256; i++, address += pagesize) {
hook->bounce_addr = VirtualAlloc((LPVOID)address,
pagesize, MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
hook->bounce_addr =
VirtualAlloc((LPVOID)address, pagesize,
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if (hook->bounce_addr)
break;
}
@@ -194,14 +197,14 @@ static void setup_64bit_bounce(struct func_hook *hook, intptr_t *offset)
newdiff = (uintptr_t)hook->bounce_addr - hook->func_addr + 5;
if (newdiff <= 0x7ffffff0) {
uint8_t *addr = (uint8_t*)hook->bounce_addr;
uint8_t *addr = (uint8_t *)hook->bounce_addr;
FillMemory(hook->bounce_addr, pagesize, 0xCC);
*(addr++) = 0xFF;
*(addr++) = 0x25;
*((uint32_t*)addr) = 0;
*((uint64_t*)(addr + 4)) = hook->hook_addr;
*((uint32_t *)addr) = 0;
*((uint64_t *)(addr + 4)) = hook->hook_addr;
hook->hook_addr = (uint64_t)hook->bounce_addr;
*offset = hook->hook_addr - hook->func_addr - JMP_32_SIZE;
@@ -230,7 +233,7 @@ void do_hook(struct func_hook *hook, bool force)
size = patch_size(hook);
}
memcpy((void*)addr, hook->rehook_data, size);
memcpy((void *)addr, hook->rehook_data, size);
hook->hooked = true;
return;
}
@@ -272,11 +275,11 @@ void unhook(struct func_hook *hook)
addr = hook->func_addr;
}
fix_permissions((void*)addr, size);
memcpy(hook->rehook_data, (void*)addr, size);
fix_permissions((void *)addr, size);
memcpy(hook->rehook_data, (void *)addr, size);
if (hook->type == HOOKTYPE_FORWARD_OVERWRITE)
memcpy((void*)hook->func_addr, hook->unhook_data, size);
memcpy((void *)hook->func_addr, hook->unhook_data, size);
hook->hooked = false;
}

View File

@@ -18,23 +18,23 @@ enum hook_type {
};
struct func_hook {
void *call_addr;
void *call_addr;
uintptr_t func_addr; /* function being hooked to */
uintptr_t hook_addr; /* hook function itself */
void *bounce_addr;
const char *name;
enum hook_type type;
bool is_64bit_jump;
bool hooked;
bool started;
bool attempted_bounce;
uint8_t unhook_data[14];
uint8_t rehook_data[14];
uintptr_t func_addr; /* function being hooked to */
uintptr_t hook_addr; /* hook function itself */
void *bounce_addr;
const char *name;
enum hook_type type;
bool is_64bit_jump;
bool hooked;
bool started;
bool attempted_bounce;
uint8_t unhook_data[14];
uint8_t rehook_data[14];
};
extern void hook_init(struct func_hook *hook,
void *func_addr, void *hook_addr, const char *name);
extern void hook_init(struct func_hook *hook, void *func_addr, void *hook_addr,
const char *name);
extern void hook_start(struct func_hook *hook);
extern void do_hook(struct func_hook *hook, bool force);
extern void unhook(struct func_hook *hook);

File diff suppressed because it is too large Load Diff

View File

@@ -6,20 +6,20 @@
typedef IDirect3D8 *(WINAPI *d3d8create_t)(UINT);
struct d3d8_info {
HMODULE module;
HWND hwnd;
IDirect3D8 *d3d8;
HMODULE module;
HWND hwnd;
IDirect3D8 *d3d8;
IDirect3DDevice8 *device;
};
static inline bool d3d8_init(d3d8_info &info)
{
d3d8create_t create;
HRESULT hr;
HRESULT hr;
info.hwnd = CreateWindowExA(0, DUMMY_WNDCLASS, "d3d8 get-addr window",
WS_POPUP, 0, 0, 1, 1, nullptr, nullptr,
GetModuleHandleA(nullptr), nullptr);
WS_POPUP, 0, 0, 1, 1, nullptr, nullptr,
GetModuleHandleA(nullptr), nullptr);
if (!info.hwnd) {
return false;
}
@@ -40,17 +40,18 @@ static inline bool d3d8_init(d3d8_info &info)
}
D3DPRESENT_PARAMETERS pp = {};
pp.Windowed = true;
pp.SwapEffect = D3DSWAPEFFECT_FLIP;
pp.BackBufferFormat = D3DFMT_A8R8G8B8;
pp.BackBufferWidth = 2;
pp.BackBufferHeight = 2;
pp.BackBufferCount = 1;
pp.hDeviceWindow = info.hwnd;
pp.Windowed = true;
pp.SwapEffect = D3DSWAPEFFECT_FLIP;
pp.BackBufferFormat = D3DFMT_A8R8G8B8;
pp.BackBufferWidth = 2;
pp.BackBufferHeight = 2;
pp.BackBufferCount = 1;
pp.hDeviceWindow = info.hwnd;
hr = info.d3d8->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
info.hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &pp,
&info.device);
info.hwnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING, &pp,
&info.device);
if (FAILED(hr)) {
return false;
}
@@ -70,8 +71,8 @@ static inline void d3d8_free(d3d8_info &info)
void get_d3d8_offsets(struct d3d8_offsets *offsets)
{
d3d8_info info = {};
bool success = d3d8_init(info);
d3d8_info info = {};
bool success = d3d8_init(info);
if (success) {
offsets->present = vtable_offset(info.module, info.device, 15);

View File

@@ -3,24 +3,24 @@
#include <d3d9.h>
#include "get-graphics-offsets.h"
typedef HRESULT (WINAPI *d3d9createex_t)(UINT, IDirect3D9Ex**);
typedef HRESULT(WINAPI *d3d9createex_t)(UINT, IDirect3D9Ex **);
struct d3d9_info {
HMODULE module;
HWND hwnd;
IDirect3D9Ex *d3d9ex;
IDirect3DDevice9Ex *device;
IDirect3DSwapChain9 *swap;
HMODULE module;
HWND hwnd;
IDirect3D9Ex *d3d9ex;
IDirect3DDevice9Ex *device;
IDirect3DSwapChain9 *swap;
};
static inline bool d3d9_init(d3d9_info &info)
{
d3d9createex_t create;
HRESULT hr;
HRESULT hr;
info.hwnd = CreateWindowExA(0, DUMMY_WNDCLASS, "d3d9 get-offset window",
WS_POPUP, 0, 0, 1, 1, nullptr, nullptr,
GetModuleHandleA(nullptr), nullptr);
WS_POPUP, 0, 0, 1, 1, nullptr, nullptr,
GetModuleHandleA(nullptr), nullptr);
if (!info.hwnd) {
return false;
}
@@ -31,7 +31,7 @@ static inline bool d3d9_init(d3d9_info &info)
}
create = (d3d9createex_t)GetProcAddress(info.module,
"Direct3DCreate9Ex");
"Direct3DCreate9Ex");
if (!create) {
return false;
}
@@ -42,19 +42,19 @@ static inline bool d3d9_init(d3d9_info &info)
}
D3DPRESENT_PARAMETERS pp = {};
pp.Windowed = true;
pp.SwapEffect = D3DSWAPEFFECT_FLIP;
pp.BackBufferFormat = D3DFMT_A8R8G8B8;
pp.BackBufferWidth = 2;
pp.BackBufferHeight = 2;
pp.BackBufferCount = 1;
pp.hDeviceWindow = info.hwnd;
pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
pp.Windowed = true;
pp.SwapEffect = D3DSWAPEFFECT_FLIP;
pp.BackBufferFormat = D3DFMT_A8R8G8B8;
pp.BackBufferWidth = 2;
pp.BackBufferHeight = 2;
pp.BackBufferCount = 1;
pp.hDeviceWindow = info.hwnd;
pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
hr = info.d3d9ex->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
info.hwnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING |
D3DCREATE_NOWINDOWCHANGES, &pp, nullptr, &info.device);
hr = info.d3d9ex->CreateDeviceEx(
D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, info.hwnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_NOWINDOWCHANGES,
&pp, nullptr, &info.device);
if (FAILED(hr)) {
return false;
}
@@ -84,24 +84,12 @@ static inline void d3d9_free(d3d9_info &info)
#define MAX_CMP_SIZE 22
static const uint8_t mask[][MAX_CMP_SIZE] = {
{
0xF8, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0x00,
0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00
},
{
0xF8, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
0xFF, 0x00,
0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00
},
{
0xF8, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
0xFF, 0x00,
0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00
},
{0xF8, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0x00, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00},
{0xF8, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x00,
0x00, 0x00, 0xFF, 0x00, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00},
{0xF8, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x00,
0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00},
};
static const uint8_t mask_cmp[][MAX_CMP_SIZE] = {
@@ -112,12 +100,8 @@ static const uint8_t mask_cmp[][MAX_CMP_SIZE] = {
* 75 12 jnz short loc_7FF7AA90530
* 41 B8 F9 19 00 00 mov r8d, 19F9h
*/
{
0x48, 0x8B, 0x80, 0x00, 0x00, 0x00, 0x00,
0x44, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00,
0x75, 0x00,
0x40, 0xB8, 0x00, 0x00, 0x00, 0x00
},
{0x48, 0x8B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x44, 0x39, 0x00, 0x00,
0x00, 0x00, 0x00, 0x75, 0x00, 0x40, 0xB8, 0x00, 0x00, 0x00, 0x00},
/*
* Windows ???+
* 49 8B 87 78 41 00 00 mov rax, [r15+4178h]
@@ -125,12 +109,8 @@ static const uint8_t mask_cmp[][MAX_CMP_SIZE] = {
* 75 12 jnz short loc_1800AEC9C
* 41 B9 C3 1A 00 00 mov r9d, 1AC3h
*/
{
0x48, 0x8B, 0x80, 0x00, 0x00, 0x00, 0x00,
0x39, 0x80, 0x00, 0x00, 0x00, 0x00,
0x75, 0x00,
0x40, 0xB8, 0x00, 0x00, 0x00, 0x00
},
{0x48, 0x8B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x39, 0x80, 0x00, 0x00,
0x00, 0x00, 0x75, 0x00, 0x40, 0xB8, 0x00, 0x00, 0x00, 0x00},
/*
* Windows 10 April 2018
* 49 8B 87 58 40 00 00 mov rax, [r15+4058h]
@@ -140,13 +120,8 @@ static const uint8_t mask_cmp[][MAX_CMP_SIZE] = {
*
* Note: different instructions, last byte skipped due to MAX_CMP_SIZE
*/
{
0x48, 0x8B, 0x80, 0x00, 0x00, 0x00, 0x00,
0x39, 0x80, 0x00, 0x00, 0x00, 0x00,
0x75, 0x00,
0x48, 0x8D, 0x00, 0x00, 0x00, 0x00
}
};
{0x48, 0x8B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x39, 0x80, 0x00, 0x00,
0x00, 0x00, 0x75, 0x00, 0x48, 0x8D, 0x00, 0x00, 0x00, 0x00}};
// Offset into the code for the numbers we're interested in
static const uint32_t code_offsets[][2] = {
@@ -159,24 +134,12 @@ static const uint32_t code_offsets[][2] = {
#define MAX_CMP_SIZE 20
static const uint8_t mask[][MAX_CMP_SIZE] = {
{
0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
0xFF, 0x00,
0xFF, 0x00, 0x00, 0x00, 0x00
},
{
0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF,
0xFF, 0x00,
0xFF, 0x00, 0x00, 0x00, 0x00
},
{
0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF,
0xFF, 0x00,
0xFF, 0x00, 0x00, 0x00, 0x00
},
{0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00},
{0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00},
{0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00},
};
static const uint8_t mask_cmp[][MAX_CMP_SIZE] = {
@@ -187,12 +150,8 @@ static const uint8_t mask_cmp[][MAX_CMP_SIZE] = {
* 75 14 jnz short loc_754CD9E1
* 68 F9 19 00 00 push 19F9h
*/
{
0x8B, 0x80, 0x00, 0x00, 0x00, 0x00,
0x39, 0x80, 0x00, 0x00, 0x00, 0x00,
0x75, 0x00,
0x68, 0x00, 0x00, 0x00, 0x00
},
{0x8B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x39, 0x80, 0x00, 0x00, 0x00, 0x00,
0x75, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00},
/* Windows 10 Creator's Update+
* 8B 86 F8 2B 00 00 mov eax, [esi+2BF8h]
@@ -200,12 +159,8 @@ static const uint8_t mask_cmp[][MAX_CMP_SIZE] = {
* 75 0F jnz short loc_100D793C
* 68 C3 1A 00 00 push 1AC3h
*/
{
0x8B, 0x80, 0x00, 0x00, 0x00, 0x00,
0x83, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x75, 0x00,
0x68, 0x00, 0x00, 0x00, 0x00
},
{0x8B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x83, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x75, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00},
/*
* Windows 10 April 2018 Update
@@ -214,13 +169,8 @@ static const uint8_t mask_cmp[][MAX_CMP_SIZE] = {
* 75 0F jnz short loc_100D9A9C
* BA 08 71 01 10 mov edx, offset errMsg
*/
{
0x8B, 0x80, 0x00, 0x00, 0x00, 0x00,
0x83, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x75, 0x00,
0xBA, 0x00, 0x00, 0x00, 0x00
}
};
{0x8B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x83, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x75, 0x00, 0xBA, 0x00, 0x00, 0x00, 0x00}};
// Offset into the code for the numbers we're interested in
static const uint32_t code_offsets[][2] = {
@@ -233,7 +183,7 @@ static const uint32_t code_offsets[][2] = {
#define MAX_FUNC_SCAN_BYTES 200
static inline bool pattern_matches(uint8_t *byte, uint32_t *offset1,
uint32_t *offset2)
uint32_t *offset2)
{
for (size_t j = 0; j < sizeof(mask) / sizeof(mask[0]); j++) {
for (size_t i = 0; i < MAX_CMP_SIZE; i++) {
@@ -245,7 +195,7 @@ static inline bool pattern_matches(uint8_t *byte, uint32_t *offset1,
*offset2 = code_offsets[j][1];
return true;
next_signature:;
next_signature:;
}
return false;
@@ -253,23 +203,23 @@ next_signature:;
void get_d3d9_offsets(struct d3d9_offsets *offsets)
{
d3d9_info info = {};
bool success = d3d9_init(info);
d3d9_info info = {};
bool success = d3d9_init(info);
if (success) {
uint8_t **vt = *(uint8_t***)info.device;
uint8_t **vt = *(uint8_t ***)info.device;
uint8_t *crr = vt[125];
offsets->present = vtable_offset(info.module, info.device, 17);
offsets->present_ex = vtable_offset(info.module, info.device,
121);
offsets->present_swap = vtable_offset(info.module, info.swap,
3);
offsets->present_ex =
vtable_offset(info.module, info.device, 121);
offsets->present_swap =
vtable_offset(info.module, info.swap, 3);
uint32_t offset1, offset2;
for (size_t i = 0; i < MAX_FUNC_SCAN_BYTES; i++) {
if (pattern_matches(&crr[i], &offset1, &offset2)) {
#define get_offset(x) *(uint32_t*)&crr[i + x]
#define get_offset(x) *(uint32_t *)&crr[i + x]
uint32_t off1 = get_offset(offset1);
uint32_t off2 = get_offset(offset2);
@@ -278,23 +228,23 @@ void get_d3d9_offsets(struct d3d9_offsets *offsets)
if (off1 > 0xFFFF || off2 > 0xFFFF)
break;
/* check to make sure offsets actually point
/* check to make sure offsets actually point
* toward expected data */
#ifdef _MSC_VER
__try {
uint8_t *ptr = (uint8_t*)(info.device);
uint8_t *ptr = (uint8_t *)(info.device);
uint8_t *d3d9_ptr =
*(uint8_t**)(ptr + off1);
if (d3d9_ptr != (uint8_t*)info.d3d9ex)
*(uint8_t **)(ptr + off1);
if (d3d9_ptr != (uint8_t *)info.d3d9ex)
break;
BOOL &is_d3d9ex =
*(BOOL*)(d3d9_ptr + off2);
*(BOOL *)(d3d9_ptr + off2);
if (is_d3d9ex != TRUE)
break;
} __except(EXCEPTION_EXECUTE_HANDLER) {
} __except (EXCEPTION_EXECUTE_HANDLER) {
break;
}
#endif

View File

@@ -4,33 +4,38 @@
#include <dxgi1_2.h>
#include "get-graphics-offsets.h"
typedef HRESULT (WINAPI *d3d10create_t)(IDXGIAdapter*, D3D10_DRIVER_TYPE,
HMODULE, UINT, UINT, DXGI_SWAP_CHAIN_DESC*,
IDXGISwapChain**, IUnknown**);
typedef HRESULT (WINAPI *create_fac_t)(IID *id, void**);
typedef HRESULT(WINAPI *d3d10create_t)(IDXGIAdapter *, D3D10_DRIVER_TYPE,
HMODULE, UINT, UINT,
DXGI_SWAP_CHAIN_DESC *,
IDXGISwapChain **, IUnknown **);
typedef HRESULT(WINAPI *create_fac_t)(IID *id, void **);
struct dxgi_info {
HMODULE module;
HWND hwnd;
HMODULE module;
HWND hwnd;
IDXGISwapChain *swap;
};
static const IID dxgiFactory2 =
{0x50c83a1c, 0xe072, 0x4c48, {0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0}};
static const IID dxgiFactory2 = {0x50c83a1c,
0xe072,
0x4c48,
{0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6,
0xd0}};
static inline bool dxgi_init(dxgi_info &info)
{
HMODULE d3d10_module;
HMODULE d3d10_module;
d3d10create_t create;
create_fac_t create_factory;
create_fac_t create_factory;
IDXGIFactory1 *factory;
IDXGIAdapter1 *adapter;
IUnknown *device;
HRESULT hr;
IUnknown *device;
HRESULT hr;
info.hwnd = CreateWindowExA(0, DUMMY_WNDCLASS, "d3d10 get-offset window",
WS_POPUP, 0, 0, 2, 2, nullptr, nullptr,
GetModuleHandleA(nullptr), nullptr);
info.hwnd = CreateWindowExA(0, DUMMY_WNDCLASS,
"d3d10 get-offset window", WS_POPUP, 0, 0,
2, 2, nullptr, nullptr,
GetModuleHandleA(nullptr), nullptr);
if (!info.hwnd) {
return false;
}
@@ -40,8 +45,8 @@ static inline bool dxgi_init(dxgi_info &info)
return false;
}
create_factory = (create_fac_t)GetProcAddress(info.module,
"CreateDXGIFactory1");
create_factory =
(create_fac_t)GetProcAddress(info.module, "CreateDXGIFactory1");
d3d10_module = LoadLibraryA("d3d10.dll");
if (!d3d10_module) {
@@ -49,16 +54,15 @@ static inline bool dxgi_init(dxgi_info &info)
}
create = (d3d10create_t)GetProcAddress(d3d10_module,
"D3D10CreateDeviceAndSwapChain");
"D3D10CreateDeviceAndSwapChain");
if (!create) {
return false;
}
IID factory_iid = IsWindows8OrGreater()
? dxgiFactory2
: __uuidof(IDXGIFactory1);
IID factory_iid = IsWindows8OrGreater() ? dxgiFactory2
: __uuidof(IDXGIFactory1);
hr = create_factory(&factory_iid, (void**)&factory);
hr = create_factory(&factory_iid, (void **)&factory);
if (FAILED(hr)) {
return false;
}
@@ -70,17 +74,17 @@ static inline bool dxgi_init(dxgi_info &info)
}
DXGI_SWAP_CHAIN_DESC desc = {};
desc.BufferCount = 2;
desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.BufferDesc.Width = 2;
desc.BufferDesc.Height = 2;
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
desc.OutputWindow = info.hwnd;
desc.SampleDesc.Count = 1;
desc.Windowed = true;
desc.BufferCount = 2;
desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.BufferDesc.Width = 2;
desc.BufferDesc.Height = 2;
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
desc.OutputWindow = info.hwnd;
desc.SampleDesc.Count = 1;
desc.Windowed = true;
hr = create(adapter, D3D10_DRIVER_TYPE_HARDWARE, nullptr, 0,
D3D10_SDK_VERSION, &desc, &info.swap, &device);
D3D10_SDK_VERSION, &desc, &info.swap, &device);
adapter->Release();
if (FAILED(hr)) {
return false;
@@ -100,17 +104,17 @@ static inline void dxgi_free(dxgi_info &info)
void get_dxgi_offsets(struct dxgi_offsets *offsets)
{
dxgi_info info = {};
bool success = dxgi_init(info);
HRESULT hr;
dxgi_info info = {};
bool success = dxgi_init(info);
HRESULT hr;
if (success) {
offsets->present = vtable_offset(info.module, info.swap, 8);
offsets->resize = vtable_offset(info.module, info.swap, 13);
offsets->resize = vtable_offset(info.module, info.swap, 13);
IDXGISwapChain1 *swap1;
hr = info.swap->QueryInterface(__uuidof(IDXGISwapChain1),
(void**)&swap1);
(void **)&swap1);
if (SUCCEEDED(hr)) {
offsets->present1 =
vtable_offset(info.module, swap1, 22);

View File

@@ -9,10 +9,10 @@ int main(int argc, char *argv[])
struct d3d9_offsets d3d9 = {0};
struct dxgi_offsets dxgi = {0};
WNDCLASSA wc = {0};
wc.style = CS_OWNDC;
wc.hInstance = GetModuleHandleA(NULL);
wc.lpfnWndProc = (WNDPROC)DefWindowProcA;
WNDCLASSA wc = {0};
wc.style = CS_OWNDC;
wc.hInstance = GetModuleHandleA(NULL);
wc.lpfnWndProc = (WNDPROC)DefWindowProcA;
wc.lpszClassName = DUMMY_WNDCLASS;
SetErrorMode(SEM_FAILCRITICALERRORS);
@@ -27,17 +27,17 @@ int main(int argc, char *argv[])
get_dxgi_offsets(&dxgi);
printf("[d3d8]\n");
printf("present=0x%"PRIx32"\n", d3d8.present);
printf("present=0x%" PRIx32 "\n", d3d8.present);
printf("[d3d9]\n");
printf("present=0x%"PRIx32"\n", d3d9.present);
printf("present_ex=0x%"PRIx32"\n", d3d9.present_ex);
printf("present_swap=0x%"PRIx32"\n", d3d9.present_swap);
printf("d3d9_clsoff=0x%"PRIx32"\n", d3d9.d3d9_clsoff);
printf("is_d3d9ex_clsoff=0x%"PRIx32"\n", d3d9.is_d3d9ex_clsoff);
printf("present=0x%" PRIx32 "\n", d3d9.present);
printf("present_ex=0x%" PRIx32 "\n", d3d9.present_ex);
printf("present_swap=0x%" PRIx32 "\n", d3d9.present_swap);
printf("d3d9_clsoff=0x%" PRIx32 "\n", d3d9.d3d9_clsoff);
printf("is_d3d9ex_clsoff=0x%" PRIx32 "\n", d3d9.is_d3d9ex_clsoff);
printf("[dxgi]\n");
printf("present=0x%"PRIx32"\n", dxgi.present);
printf("present1=0x%"PRIx32"\n", dxgi.present1);
printf("resize=0x%"PRIx32"\n", dxgi.resize);
printf("present=0x%" PRIx32 "\n", dxgi.present);
printf("present1=0x%" PRIx32 "\n", dxgi.present1);
printf("resize=0x%" PRIx32 "\n", dxgi.resize);
(void)argc;
(void)argv;

View File

@@ -15,9 +15,9 @@ extern "C" {
#endif
static inline uint32_t vtable_offset(HMODULE module, void *cls,
unsigned int offset)
unsigned int offset)
{
uintptr_t *vtable = *(uintptr_t**)cls;
uintptr_t *vtable = *(uintptr_t **)cls;
return (uint32_t)(vtable[offset] - (uintptr_t)module);
}

View File

@@ -8,22 +8,22 @@
#include "hook-helpers.h"
#define EVENT_CAPTURE_RESTART L"CaptureHook_Restart"
#define EVENT_CAPTURE_STOP L"CaptureHook_Stop"
#define EVENT_CAPTURE_STOP L"CaptureHook_Stop"
#define EVENT_HOOK_READY L"CaptureHook_HookReady"
#define EVENT_HOOK_EXIT L"CaptureHook_Exit"
#define EVENT_HOOK_READY L"CaptureHook_HookReady"
#define EVENT_HOOK_EXIT L"CaptureHook_Exit"
#define EVENT_HOOK_INIT L"CaptureHook_Initialize"
#define EVENT_HOOK_INIT L"CaptureHook_Initialize"
#define WINDOW_HOOK_KEEPALIVE L"CaptureHook_KeepAlive"
#define MUTEX_TEXTURE1 L"CaptureHook_TextureMutex1"
#define MUTEX_TEXTURE2 L"CaptureHook_TextureMutex2"
#define MUTEX_TEXTURE1 L"CaptureHook_TextureMutex1"
#define MUTEX_TEXTURE2 L"CaptureHook_TextureMutex2"
#define SHMEM_HOOK_INFO L"CaptureHook_HookInfo"
#define SHMEM_TEXTURE L"CaptureHook_Texture"
#define SHMEM_HOOK_INFO L"CaptureHook_HookInfo"
#define SHMEM_TEXTURE L"CaptureHook_Texture"
#define PIPE_NAME "CaptureHook_Pipe"
#define PIPE_NAME "CaptureHook_Pipe"
#pragma pack(push, 8)
@@ -69,7 +69,7 @@ struct shtex_data {
enum capture_type {
CAPTURE_TYPE_MEMORY,
CAPTURE_TYPE_TEXTURE
CAPTURE_TYPE_TEXTURE,
};
struct graphics_offsets {
@@ -81,26 +81,26 @@ struct graphics_offsets {
struct hook_info {
/* capture info */
enum capture_type type;
uint32_t window;
uint32_t format;
uint32_t cx;
uint32_t cy;
uint32_t base_cx;
uint32_t base_cy;
uint32_t pitch;
uint32_t map_id;
uint32_t map_size;
bool flip;
enum capture_type type;
uint32_t window;
uint32_t format;
uint32_t cx;
uint32_t cy;
uint32_t base_cx;
uint32_t base_cy;
uint32_t pitch;
uint32_t map_id;
uint32_t map_size;
bool flip;
/* additional options */
uint64_t frame_interval;
bool use_scale;
bool force_shmem;
bool capture_overlay;
uint64_t frame_interval;
bool use_scale;
bool force_shmem;
bool capture_overlay;
/* hook addresses */
struct graphics_offsets offsets;
struct graphics_offsets offsets;
};
#pragma pack(pop)
@@ -112,6 +112,6 @@ static inline HANDLE create_hook_info(DWORD id)
wchar_t new_name[64];
_snwprintf(new_name, 64, L"%s%lu", SHMEM_HOOK_INFO, id);
return CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
0, sizeof(struct hook_info), new_name);
return CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,
sizeof(struct hook_info), new_name);
}

View File

@@ -6,49 +6,49 @@
#include "../funchook.h"
struct d3d10_data {
ID3D10Device *device; /* do not release */
uint32_t base_cx;
uint32_t base_cy;
uint32_t cx;
uint32_t cy;
DXGI_FORMAT format;
bool using_shtex;
bool using_scale;
bool multisampled;
ID3D10Device *device; /* do not release */
uint32_t base_cx;
uint32_t base_cy;
uint32_t cx;
uint32_t cy;
DXGI_FORMAT format;
bool using_shtex;
bool using_scale;
bool multisampled;
ID3D10Texture2D *scale_tex;
ID3D10ShaderResourceView *scale_resource;
ID3D10Texture2D *scale_tex;
ID3D10ShaderResourceView *scale_resource;
ID3D10VertexShader *vertex_shader;
ID3D10InputLayout *vertex_layout;
ID3D10PixelShader *pixel_shader;
ID3D10VertexShader *vertex_shader;
ID3D10InputLayout *vertex_layout;
ID3D10PixelShader *pixel_shader;
ID3D10SamplerState *sampler_state;
ID3D10BlendState *blend_state;
ID3D10DepthStencilState *zstencil_state;
ID3D10RasterizerState *raster_state;
ID3D10SamplerState *sampler_state;
ID3D10BlendState *blend_state;
ID3D10DepthStencilState *zstencil_state;
ID3D10RasterizerState *raster_state;
ID3D10Buffer *vertex_buffer;
ID3D10Buffer *vertex_buffer;
union {
/* shared texture */
struct {
struct shtex_data *shtex_info;
ID3D10Texture2D *texture;
struct shtex_data *shtex_info;
ID3D10Texture2D *texture;
ID3D10RenderTargetView *render_target;
HANDLE handle;
HANDLE handle;
};
/* shared memory */
struct {
struct shmem_data *shmem_info;
ID3D10Texture2D *copy_surfaces[NUM_BUFFERS];
ID3D10Texture2D *textures[NUM_BUFFERS];
struct shmem_data *shmem_info;
ID3D10Texture2D *copy_surfaces[NUM_BUFFERS];
ID3D10Texture2D *textures[NUM_BUFFERS];
ID3D10RenderTargetView *render_targets[NUM_BUFFERS];
bool texture_ready[NUM_BUFFERS];
bool texture_mapped[NUM_BUFFERS];
uint32_t pitch;
int cur_tex;
int copy_wait;
bool texture_ready[NUM_BUFFERS];
bool texture_mapped[NUM_BUFFERS];
uint32_t pitch;
int cur_tex;
int copy_wait;
};
};
};
@@ -108,31 +108,30 @@ static bool create_d3d10_stage_surface(ID3D10Texture2D **tex)
{
HRESULT hr;
D3D10_TEXTURE2D_DESC desc = {};
desc.Width = data.cx;
desc.Height = data.cy;
desc.Format = data.format;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.SampleDesc.Count = 1;
desc.Usage = D3D10_USAGE_STAGING;
desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
D3D10_TEXTURE2D_DESC desc = {};
desc.Width = data.cx;
desc.Height = data.cy;
desc.Format = data.format;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.SampleDesc.Count = 1;
desc.Usage = D3D10_USAGE_STAGING;
desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
hr = data.device->CreateTexture2D(&desc, nullptr, tex);
if (FAILED(hr)) {
hlog_hr("create_d3d10_stage_surface: failed to create texture",
hr);
hr);
return false;
}
return true;
}
static bool create_d3d10_tex(uint32_t cx, uint32_t cy,
ID3D10Texture2D **tex,
ID3D10ShaderResourceView **resource,
ID3D10RenderTargetView **render_target,
HANDLE *handle)
static bool create_d3d10_tex(uint32_t cx, uint32_t cy, ID3D10Texture2D **tex,
ID3D10ShaderResourceView **resource,
ID3D10RenderTargetView **render_target,
HANDLE *handle)
{
UINT flags = 0;
UINT misc_flags = 0;
@@ -145,16 +144,16 @@ static bool create_d3d10_tex(uint32_t cx, uint32_t cy,
if (!!handle)
misc_flags |= D3D10_RESOURCE_MISC_SHARED;
D3D10_TEXTURE2D_DESC desc = {};
desc.Width = cx;
desc.Height = cy;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = data.format;
desc.BindFlags = flags;
desc.SampleDesc.Count = 1;
desc.Usage = D3D10_USAGE_DEFAULT;
desc.MiscFlags = misc_flags;
D3D10_TEXTURE2D_DESC desc = {};
desc.Width = cx;
desc.Height = cy;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = data.format;
desc.BindFlags = flags;
desc.SampleDesc.Count = 1;
desc.Usage = D3D10_USAGE_DEFAULT;
desc.MiscFlags = misc_flags;
hr = data.device->CreateTexture2D(&desc, nullptr, tex);
if (FAILED(hr)) {
@@ -169,20 +168,22 @@ static bool create_d3d10_tex(uint32_t cx, uint32_t cy,
res_desc.Texture2D.MipLevels = 1;
hr = data.device->CreateShaderResourceView(*tex, &res_desc,
resource);
resource);
if (FAILED(hr)) {
hlog_hr("create_d3d10_tex: failed to create resource "
"view", hr);
"view",
hr);
return false;
}
}
if (!!render_target) {
hr = data.device->CreateRenderTargetView(*tex, nullptr,
render_target);
render_target);
if (FAILED(hr)) {
hlog_hr("create_d3d10_tex: failed to create render "
"target view", hr);
"target view",
hr);
return false;
}
}
@@ -190,10 +191,11 @@ static bool create_d3d10_tex(uint32_t cx, uint32_t cy,
if (!!handle) {
IDXGIResource *dxgi_res;
hr = (*tex)->QueryInterface(__uuidof(IDXGIResource),
(void**)&dxgi_res);
(void **)&dxgi_res);
if (FAILED(hr)) {
hlog_hr("create_d3d10_tex: failed to query "
"IDXGIResource interface from texture", hr);
"IDXGIResource interface from texture",
hr);
return false;
}
@@ -201,7 +203,7 @@ static bool create_d3d10_tex(uint32_t cx, uint32_t cy,
dxgi_res->Release();
if (FAILED(hr)) {
hlog_hr("create_d3d10_tex: failed to get shared handle",
hr);
hr);
return false;
}
}
@@ -246,10 +248,10 @@ static inline bool d3d10_init_vertex_shader(void)
vs_data = get_d3d1x_vertex_shader(&size);
hr = data.device->CreateVertexShader(vs_data, size,
&data.vertex_shader);
&data.vertex_shader);
if (FAILED(hr)) {
hlog_hr("d3d10_init_vertex_shader: failed to create shader",
hr);
hr);
return false;
}
@@ -270,10 +272,10 @@ static inline bool d3d10_init_vertex_shader(void)
desc[1].InstanceDataStepRate = 0;
hr = data.device->CreateInputLayout(desc, 2, vs_data, size,
&data.vertex_layout);
&data.vertex_layout);
if (FAILED(hr)) {
hlog_hr("d3d10_init_vertex_shader: failed to create layout",
hr);
hr);
return false;
}
@@ -301,16 +303,17 @@ static inline bool d3d10_init_sampler_state(void)
{
HRESULT hr;
D3D10_SAMPLER_DESC desc = {};
desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR;
desc.AddressU = D3D10_TEXTURE_ADDRESS_CLAMP;
desc.AddressV = D3D10_TEXTURE_ADDRESS_CLAMP;
desc.AddressW = D3D10_TEXTURE_ADDRESS_CLAMP;
D3D10_SAMPLER_DESC desc = {};
desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR;
desc.AddressU = D3D10_TEXTURE_ADDRESS_CLAMP;
desc.AddressV = D3D10_TEXTURE_ADDRESS_CLAMP;
desc.AddressW = D3D10_TEXTURE_ADDRESS_CLAMP;
hr = data.device->CreateSamplerState(&desc, &data.sampler_state);
if (FAILED(hr)) {
hlog_hr("d3d10_init_sampler_state: failed to create sampler "
"state", hr);
"state",
hr);
return false;
}
@@ -328,7 +331,7 @@ static inline bool d3d10_init_blend_state(void)
hr = data.device->CreateBlendState(&desc, &data.blend_state);
if (FAILED(hr)) {
hlog_hr("d3d10_init_blend_state: failed to create blend state",
hr);
hr);
return false;
}
@@ -343,7 +346,8 @@ static inline bool d3d10_init_zstencil_state(void)
hr = data.device->CreateDepthStencilState(&desc, &data.zstencil_state);
if (FAILED(hr)) {
hlog_hr("d3d10_init_zstencil_state: failed to create "
"zstencil state", hr);
"zstencil state",
hr);
return false;
}
@@ -361,7 +365,8 @@ static inline bool d3d10_init_raster_state(void)
hr = data.device->CreateRasterizerState(&desc, &data.raster_state);
if (FAILED(hr)) {
hlog_hr("d3d10_init_raster_state: failed to create raster "
"state", hr);
"state",
hr);
return false;
}
@@ -374,26 +379,26 @@ static inline bool d3d10_init_vertex_buffer(void)
{
HRESULT hr;
const vertex verts[NUM_VERTS] = {
{{-1.0f, 1.0f, 0.0f, 1.0f}, {0.0f, 0.0f}},
{{-1.0f, 1.0f, 0.0f, 1.0f}, {0.0f, 0.0f}},
{{-1.0f, -1.0f, 0.0f, 1.0f}, {0.0f, 1.0f}},
{{ 1.0f, 1.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
{{ 1.0f, -1.0f, 0.0f, 1.0f}, {1.0f, 1.0f}}
};
{{1.0f, 1.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
{{1.0f, -1.0f, 0.0f, 1.0f}, {1.0f, 1.0f}}};
D3D10_BUFFER_DESC desc;
desc.ByteWidth = sizeof(vertex) * NUM_VERTS;
desc.Usage = D3D10_USAGE_DEFAULT;
desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
desc.ByteWidth = sizeof(vertex) * NUM_VERTS;
desc.Usage = D3D10_USAGE_DEFAULT;
desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA srd = {};
srd.pSysMem = (const void*)verts;
D3D10_SUBRESOURCE_DATA srd = {};
srd.pSysMem = (const void *)verts;
hr = data.device->CreateBuffer(&desc, &srd, &data.vertex_buffer);
if (FAILED(hr)) {
hlog_hr("d3d10_init_vertex_buffer: failed to create vertex "
"buffer", hr);
"buffer",
hr);
return false;
}
@@ -404,9 +409,8 @@ static bool d3d10_init_scaling(void)
{
bool success;
success = create_d3d10_tex(data.base_cx, data.base_cy,
&data.scale_tex, &data.scale_resource, nullptr,
nullptr);
success = create_d3d10_tex(data.base_cx, data.base_cy, &data.scale_tex,
&data.scale_resource, nullptr, nullptr);
if (!success) {
hlog("d3d10_init_scaling: failed to create scale texture");
return false;
@@ -454,7 +458,8 @@ static bool d3d10_shmem_init_buffers(size_t idx)
hr = data.copy_surfaces[idx]->Map(0, D3D10_MAP_READ, 0, &map);
if (FAILED(hr)) {
hlog_hr("d3d10_shmem_init_buffers: failed to get "
"pitch", hr);
"pitch",
hr);
return false;
}
@@ -463,7 +468,7 @@ static bool d3d10_shmem_init_buffers(size_t idx)
}
success = create_d3d10_tex(data.cx, data.cy, &data.textures[idx],
nullptr, &data.render_targets[idx], nullptr);
nullptr, &data.render_targets[idx], nullptr);
if (!success) {
hlog("d3d10_shmem_init_buffers: failed to create texture");
return false;
@@ -481,9 +486,9 @@ static bool d3d10_shmem_init(HWND window)
return false;
}
}
if (!capture_init_shmem(&data.shmem_info, window,
data.base_cx, data.base_cy, data.cx, data.cy,
data.pitch, data.format, false)) {
if (!capture_init_shmem(&data.shmem_info, window, data.base_cx,
data.base_cy, data.cx, data.cy, data.pitch,
data.format, false)) {
return false;
}
@@ -499,7 +504,7 @@ static bool d3d10_shtex_init(HWND window)
data.using_shtex = true;
success = create_d3d10_tex(data.cx, data.cy, &data.texture, &resource,
&data.render_target, &data.handle);
&data.render_target, &data.handle);
if (resource)
resource->Release();
@@ -507,9 +512,9 @@ static bool d3d10_shtex_init(HWND window)
hlog("d3d10_shtex_init: failed to create texture");
return false;
}
if (!capture_init_shtex(&data.shtex_info, window,
data.base_cx, data.base_cy, data.cx, data.cy,
data.format, false, (uintptr_t)data.handle)) {
if (!capture_init_shtex(&data.shtex_info, window, data.base_cx,
data.base_cy, data.cx, data.cy, data.format,
false, (uintptr_t)data.handle)) {
return false;
}
@@ -525,7 +530,7 @@ static void d3d10_init(IDXGISwapChain *swap)
data.using_scale = global_hook_info->use_scale;
hr = swap->GetDevice(__uuidof(ID3D10Device), (void**)&data.device);
hr = swap->GetDevice(__uuidof(ID3D10Device), (void **)&data.device);
if (FAILED(hr)) {
hlog_hr("d3d10_init: failed to get device from swap", hr);
return;
@@ -553,32 +558,32 @@ static void d3d10_init(IDXGISwapChain *swap)
d3d10_free();
}
#define MAX_RENDER_TARGETS D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT
#define MAX_SO_TARGETS 4
#define MAX_RENDER_TARGETS D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT
#define MAX_SO_TARGETS 4
struct d3d10_state {
ID3D10GeometryShader *geom_shader;
ID3D10InputLayout *vertex_layout;
D3D10_PRIMITIVE_TOPOLOGY topology;
ID3D10Buffer *vertex_buffer;
UINT vb_stride;
UINT vb_offset;
ID3D10BlendState *blend_state;
float blend_factor[4];
UINT sample_mask;
ID3D10DepthStencilState *zstencil_state;
UINT zstencil_ref;
ID3D10RenderTargetView *render_targets[MAX_RENDER_TARGETS];
ID3D10DepthStencilView *zstencil_view;
ID3D10SamplerState *sampler_state;
ID3D10PixelShader *pixel_shader;
ID3D10ShaderResourceView *resource;
ID3D10RasterizerState *raster_state;
UINT num_viewports;
D3D10_VIEWPORT *viewports;
ID3D10Buffer *stream_output_targets[MAX_SO_TARGETS];
UINT so_offsets[MAX_SO_TARGETS];
ID3D10VertexShader *vertex_shader;
ID3D10GeometryShader *geom_shader;
ID3D10InputLayout *vertex_layout;
D3D10_PRIMITIVE_TOPOLOGY topology;
ID3D10Buffer *vertex_buffer;
UINT vb_stride;
UINT vb_offset;
ID3D10BlendState *blend_state;
float blend_factor[4];
UINT sample_mask;
ID3D10DepthStencilState *zstencil_state;
UINT zstencil_ref;
ID3D10RenderTargetView *render_targets[MAX_RENDER_TARGETS];
ID3D10DepthStencilView *zstencil_view;
ID3D10SamplerState *sampler_state;
ID3D10PixelShader *pixel_shader;
ID3D10ShaderResourceView *resource;
ID3D10RasterizerState *raster_state;
UINT num_viewports;
D3D10_VIEWPORT *viewports;
ID3D10Buffer *stream_output_targets[MAX_SO_TARGETS];
UINT so_offsets[MAX_SO_TARGETS];
ID3D10VertexShader *vertex_shader;
};
static inline void d3d10_save_state(struct d3d10_state *state)
@@ -587,32 +592,34 @@ static inline void d3d10_save_state(struct d3d10_state *state)
data.device->IAGetInputLayout(&state->vertex_layout);
data.device->IAGetPrimitiveTopology(&state->topology);
data.device->IAGetVertexBuffers(0, 1, &state->vertex_buffer,
&state->vb_stride, &state->vb_offset);
&state->vb_stride, &state->vb_offset);
data.device->OMGetBlendState(&state->blend_state, state->blend_factor,
&state->sample_mask);
&state->sample_mask);
data.device->OMGetDepthStencilState(&state->zstencil_state,
&state->zstencil_ref);
&state->zstencil_ref);
data.device->OMGetRenderTargets(MAX_RENDER_TARGETS,
state->render_targets, &state->zstencil_view);
state->render_targets,
&state->zstencil_view);
data.device->PSGetSamplers(0, 1, &state->sampler_state);
data.device->PSGetShader(&state->pixel_shader);
data.device->PSGetShaderResources(0, 1, &state->resource);
data.device->RSGetState(&state->raster_state);
data.device->RSGetViewports(&state->num_viewports, nullptr);
if (state->num_viewports) {
state->viewports = (D3D10_VIEWPORT*)malloc(
sizeof(D3D10_VIEWPORT) * state->num_viewports);
state->viewports = (D3D10_VIEWPORT *)malloc(
sizeof(D3D10_VIEWPORT) * state->num_viewports);
data.device->RSGetViewports(&state->num_viewports,
state->viewports);
state->viewports);
}
data.device->SOGetTargets(MAX_SO_TARGETS, state->stream_output_targets,
state->so_offsets);
state->so_offsets);
data.device->VSGetShader(&state->vertex_shader);
}
static inline void safe_release(IUnknown *p)
{
if (p) p->Release();
if (p)
p->Release();
}
static inline void d3d10_restore_state(struct d3d10_state *state)
@@ -621,20 +628,21 @@ static inline void d3d10_restore_state(struct d3d10_state *state)
data.device->IASetInputLayout(state->vertex_layout);
data.device->IASetPrimitiveTopology(state->topology);
data.device->IASetVertexBuffers(0, 1, &state->vertex_buffer,
&state->vb_stride, &state->vb_offset);
&state->vb_stride, &state->vb_offset);
data.device->OMSetBlendState(state->blend_state, state->blend_factor,
state->sample_mask);
state->sample_mask);
data.device->OMSetDepthStencilState(state->zstencil_state,
state->zstencil_ref);
state->zstencil_ref);
data.device->OMSetRenderTargets(MAX_RENDER_TARGETS,
state->render_targets, state->zstencil_view);
state->render_targets,
state->zstencil_view);
data.device->PSSetSamplers(0, 1, &state->sampler_state);
data.device->PSSetShader(state->pixel_shader);
data.device->PSSetShaderResources(0, 1, &state->resource);
data.device->RSSetState(state->raster_state);
data.device->RSSetViewports(state->num_viewports, state->viewports);
data.device->SOSetTargets(MAX_SO_TARGETS, state->stream_output_targets,
state->so_offsets);
state->so_offsets);
data.device->VSSetShader(state->vertex_shader);
safe_release(state->geom_shader);
safe_release(state->vertex_layout);
@@ -656,7 +664,7 @@ static inline void d3d10_restore_state(struct d3d10_state *state)
}
static inline void d3d10_setup_pipeline(ID3D10RenderTargetView *target,
ID3D10ShaderResourceView *resource)
ID3D10ShaderResourceView *resource)
{
D3D10_VIEWPORT viewport = {0};
const float factor[4] = {1.0f, 1.0f, 1.0f, 1.0f};
@@ -671,9 +679,9 @@ static inline void d3d10_setup_pipeline(ID3D10RenderTargetView *target,
data.device->GSSetShader(nullptr);
data.device->IASetInputLayout(data.vertex_layout);
data.device->IASetPrimitiveTopology(
D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
data.device->IASetVertexBuffers(0, 1, &data.vertex_buffer, &stride,
&zero);
&zero);
data.device->OMSetBlendState(data.blend_state, factor, 0xFFFFFFFF);
data.device->OMSetDepthStencilState(data.zstencil_state, 0);
data.device->OMSetRenderTargets(1, &target, nullptr);
@@ -682,12 +690,12 @@ static inline void d3d10_setup_pipeline(ID3D10RenderTargetView *target,
data.device->PSSetShaderResources(0, 1, &resource);
data.device->RSSetState(data.raster_state);
data.device->RSSetViewports(1, &viewport);
data.device->SOSetTargets(1, (ID3D10Buffer**)&emptyptr, &zero);
data.device->SOSetTargets(1, (ID3D10Buffer **)&emptyptr, &zero);
data.device->VSSetShader(data.vertex_shader);
}
static inline void d3d10_scale_texture(ID3D10RenderTargetView *target,
ID3D10ShaderResourceView *resource)
ID3D10ShaderResourceView *resource)
{
struct d3d10_state old_state = {};
@@ -725,8 +733,8 @@ static inline void d3d10_shmem_queue_copy()
if (data.texture_ready[i]) {
data.texture_ready[i] = false;
hr = data.copy_surfaces[i]->Map(0, D3D10_MAP_READ,
0, &map);
hr = data.copy_surfaces[i]->Map(0, D3D10_MAP_READ, 0,
&map);
if (SUCCEEDED(hr)) {
data.texture_mapped[i] = true;
shmem_copy_data(i, map.pData);
@@ -742,12 +750,12 @@ static inline void d3d10_shmem_capture(ID3D10Resource *backbuffer)
d3d10_shmem_queue_copy();
next_tex = (data.cur_tex == NUM_BUFFERS - 1) ? 0 : data.cur_tex + 1;
next_tex = (data.cur_tex == NUM_BUFFERS - 1) ? 0 : data.cur_tex + 1;
if (data.using_scale) {
d3d10_copy_texture(data.scale_tex, backbuffer);
d3d10_scale_texture(data.render_targets[data.cur_tex],
data.scale_resource);
data.scale_resource);
} else {
d3d10_copy_texture(data.textures[data.cur_tex], backbuffer);
}
@@ -773,8 +781,8 @@ static inline void d3d10_shmem_capture(ID3D10Resource *backbuffer)
void d3d10_capture(void *swap_ptr, void *backbuffer_ptr, bool)
{
IDXGIResource *dxgi_backbuffer = (IDXGIResource*)backbuffer_ptr;
IDXGISwapChain *swap = (IDXGISwapChain*)swap_ptr;
IDXGIResource *dxgi_backbuffer = (IDXGIResource *)backbuffer_ptr;
IDXGISwapChain *swap = (IDXGISwapChain *)swap_ptr;
HRESULT hr;
if (capture_should_stop()) {
@@ -787,10 +795,11 @@ void d3d10_capture(void *swap_ptr, void *backbuffer_ptr, bool)
ID3D10Resource *backbuffer;
hr = dxgi_backbuffer->QueryInterface(__uuidof(ID3D10Resource),
(void**)&backbuffer);
(void **)&backbuffer);
if (FAILED(hr)) {
hlog_hr("d3d10_shtex_capture: failed to get "
"backbuffer", hr);
"backbuffer",
hr);
return;
}

View File

@@ -6,50 +6,50 @@
#include "../funchook.h"
struct d3d11_data {
ID3D11Device *device; /* do not release */
ID3D11DeviceContext *context; /* do not release */
uint32_t base_cx;
uint32_t base_cy;
uint32_t cx;
uint32_t cy;
DXGI_FORMAT format;
bool using_shtex;
bool using_scale;
bool multisampled;
ID3D11Device *device; /* do not release */
ID3D11DeviceContext *context; /* do not release */
uint32_t base_cx;
uint32_t base_cy;
uint32_t cx;
uint32_t cy;
DXGI_FORMAT format;
bool using_shtex;
bool using_scale;
bool multisampled;
ID3D11Texture2D *scale_tex;
ID3D11ShaderResourceView *scale_resource;
ID3D11Texture2D *scale_tex;
ID3D11ShaderResourceView *scale_resource;
ID3D11VertexShader *vertex_shader;
ID3D11InputLayout *vertex_layout;
ID3D11PixelShader *pixel_shader;
ID3D11VertexShader *vertex_shader;
ID3D11InputLayout *vertex_layout;
ID3D11PixelShader *pixel_shader;
ID3D11SamplerState *sampler_state;
ID3D11BlendState *blend_state;
ID3D11DepthStencilState *zstencil_state;
ID3D11RasterizerState *raster_state;
ID3D11SamplerState *sampler_state;
ID3D11BlendState *blend_state;
ID3D11DepthStencilState *zstencil_state;
ID3D11RasterizerState *raster_state;
ID3D11Buffer *vertex_buffer;
ID3D11Buffer *vertex_buffer;
union {
/* shared texture */
struct {
struct shtex_data *shtex_info;
ID3D11Texture2D *texture;
struct shtex_data *shtex_info;
ID3D11Texture2D *texture;
ID3D11RenderTargetView *render_target;
HANDLE handle;
HANDLE handle;
};
/* shared memory */
struct {
ID3D11Texture2D *copy_surfaces[NUM_BUFFERS];
ID3D11Texture2D *textures[NUM_BUFFERS];
ID3D11Texture2D *copy_surfaces[NUM_BUFFERS];
ID3D11Texture2D *textures[NUM_BUFFERS];
ID3D11RenderTargetView *render_targets[NUM_BUFFERS];
bool texture_ready[NUM_BUFFERS];
bool texture_mapped[NUM_BUFFERS];
uint32_t pitch;
struct shmem_data *shmem_info;
int cur_tex;
int copy_wait;
bool texture_ready[NUM_BUFFERS];
bool texture_mapped[NUM_BUFFERS];
uint32_t pitch;
struct shmem_data *shmem_info;
int cur_tex;
int copy_wait;
};
};
};
@@ -91,8 +91,7 @@ void d3d11_free(void)
if (data.copy_surfaces[i]) {
if (data.texture_mapped[i])
data.context->Unmap(
data.copy_surfaces[i],
0);
data.copy_surfaces[i], 0);
data.copy_surfaces[i]->Release();
}
if (data.textures[i])
@@ -111,31 +110,30 @@ static bool create_d3d11_stage_surface(ID3D11Texture2D **tex)
{
HRESULT hr;
D3D11_TEXTURE2D_DESC desc = {};
desc.Width = data.cx;
desc.Height = data.cy;
desc.Format = data.format;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_STAGING;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
D3D11_TEXTURE2D_DESC desc = {};
desc.Width = data.cx;
desc.Height = data.cy;
desc.Format = data.format;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_STAGING;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
hr = data.device->CreateTexture2D(&desc, nullptr, tex);
if (FAILED(hr)) {
hlog_hr("create_d3d11_stage_surface: failed to create texture",
hr);
hr);
return false;
}
return true;
}
static bool create_d3d11_tex(uint32_t cx, uint32_t cy,
ID3D11Texture2D **tex,
ID3D11ShaderResourceView **resource,
ID3D11RenderTargetView **render_target,
HANDLE *handle)
static bool create_d3d11_tex(uint32_t cx, uint32_t cy, ID3D11Texture2D **tex,
ID3D11ShaderResourceView **resource,
ID3D11RenderTargetView **render_target,
HANDLE *handle)
{
UINT flags = 0;
UINT misc_flags = 0;
@@ -148,16 +146,16 @@ static bool create_d3d11_tex(uint32_t cx, uint32_t cy,
if (!!handle)
misc_flags |= D3D11_RESOURCE_MISC_SHARED;
D3D11_TEXTURE2D_DESC desc = {};
desc.Width = cx;
desc.Height = cy;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = data.format;
desc.BindFlags = flags;
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.MiscFlags = misc_flags;
D3D11_TEXTURE2D_DESC desc = {};
desc.Width = cx;
desc.Height = cy;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = data.format;
desc.BindFlags = flags;
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.MiscFlags = misc_flags;
hr = data.device->CreateTexture2D(&desc, nullptr, tex);
if (FAILED(hr)) {
@@ -172,20 +170,22 @@ static bool create_d3d11_tex(uint32_t cx, uint32_t cy,
res_desc.Texture2D.MipLevels = 1;
hr = data.device->CreateShaderResourceView(*tex, &res_desc,
resource);
resource);
if (FAILED(hr)) {
hlog_hr("create_d3d11_tex: failed to create resource "
"view", hr);
"view",
hr);
return false;
}
}
if (!!render_target) {
hr = data.device->CreateRenderTargetView(*tex, nullptr,
render_target);
render_target);
if (FAILED(hr)) {
hlog_hr("create_d3d11_tex: failed to create render "
"target view", hr);
"target view",
hr);
return false;
}
}
@@ -193,10 +193,11 @@ static bool create_d3d11_tex(uint32_t cx, uint32_t cy,
if (!!handle) {
IDXGIResource *dxgi_res;
hr = (*tex)->QueryInterface(__uuidof(IDXGIResource),
(void**)&dxgi_res);
(void **)&dxgi_res);
if (FAILED(hr)) {
hlog_hr("create_d3d11_tex: failed to query "
"IDXGIResource interface from texture", hr);
"IDXGIResource interface from texture",
hr);
return false;
}
@@ -204,7 +205,7 @@ static bool create_d3d11_tex(uint32_t cx, uint32_t cy,
dxgi_res->Release();
if (FAILED(hr)) {
hlog_hr("create_d3d11_tex: failed to get shared handle",
hr);
hr);
return false;
}
}
@@ -249,10 +250,10 @@ static inline bool d3d11_init_vertex_shader(void)
vs_data = get_d3d1x_vertex_shader(&size);
hr = data.device->CreateVertexShader(vs_data, size, nullptr,
&data.vertex_shader);
&data.vertex_shader);
if (FAILED(hr)) {
hlog_hr("d3d11_init_vertex_shader: failed to create shader",
hr);
hr);
return false;
}
@@ -273,10 +274,10 @@ static inline bool d3d11_init_vertex_shader(void)
desc[1].InstanceDataStepRate = 0;
hr = data.device->CreateInputLayout(desc, 2, vs_data, size,
&data.vertex_layout);
&data.vertex_layout);
if (FAILED(hr)) {
hlog_hr("d3d11_init_vertex_shader: failed to create layout",
hr);
hr);
return false;
}
@@ -292,7 +293,7 @@ static inline bool d3d11_init_pixel_shader(void)
ps_data = get_d3d1x_pixel_shader(&size);
hr = data.device->CreatePixelShader(ps_data, size, nullptr,
&data.pixel_shader);
&data.pixel_shader);
if (FAILED(hr)) {
hlog_hr("d3d11_init_pixel_shader: failed to create shader", hr);
return false;
@@ -305,16 +306,17 @@ static inline bool d3d11_init_sampler_state(void)
{
HRESULT hr;
D3D11_SAMPLER_DESC desc = {};
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
D3D11_SAMPLER_DESC desc = {};
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
hr = data.device->CreateSamplerState(&desc, &data.sampler_state);
if (FAILED(hr)) {
hlog_hr("d3d11_init_sampler_state: failed to create sampler "
"state", hr);
"state",
hr);
return false;
}
@@ -333,7 +335,7 @@ static inline bool d3d11_init_blend_state(void)
hr = data.device->CreateBlendState(&desc, &data.blend_state);
if (FAILED(hr)) {
hlog_hr("d3d11_init_blend_state: failed to create blend state",
hr);
hr);
return false;
}
@@ -348,7 +350,8 @@ static inline bool d3d11_init_zstencil_state(void)
hr = data.device->CreateDepthStencilState(&desc, &data.zstencil_state);
if (FAILED(hr)) {
hlog_hr("d3d11_init_zstencil_state: failed to create "
"zstencil state", hr);
"zstencil state",
hr);
return false;
}
@@ -366,7 +369,8 @@ static inline bool d3d11_init_raster_state(void)
hr = data.device->CreateRasterizerState(&desc, &data.raster_state);
if (FAILED(hr)) {
hlog_hr("d3d11_init_raster_state: failed to create raster "
"state", hr);
"state",
hr);
return false;
}
@@ -379,26 +383,26 @@ static inline bool d3d11_init_vertex_buffer(void)
{
HRESULT hr;
const vertex verts[NUM_VERTS] = {
{{-1.0f, 1.0f, 0.0f, 1.0f}, {0.0f, 0.0f}},
{{-1.0f, 1.0f, 0.0f, 1.0f}, {0.0f, 0.0f}},
{{-1.0f, -1.0f, 0.0f, 1.0f}, {0.0f, 1.0f}},
{{ 1.0f, 1.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
{{ 1.0f, -1.0f, 0.0f, 1.0f}, {1.0f, 1.0f}}
};
{{1.0f, 1.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
{{1.0f, -1.0f, 0.0f, 1.0f}, {1.0f, 1.0f}}};
D3D11_BUFFER_DESC desc;
desc.ByteWidth = sizeof(vertex) * NUM_VERTS;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
desc.ByteWidth = sizeof(vertex) * NUM_VERTS;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA srd = {};
srd.pSysMem = (const void*)verts;
D3D11_SUBRESOURCE_DATA srd = {};
srd.pSysMem = (const void *)verts;
hr = data.device->CreateBuffer(&desc, &srd, &data.vertex_buffer);
if (FAILED(hr)) {
hlog_hr("d3d11_init_vertex_buffer: failed to create vertex "
"buffer", hr);
"buffer",
hr);
return false;
}
@@ -409,9 +413,8 @@ static bool d3d11_init_scaling(void)
{
bool success;
success = create_d3d11_tex(data.base_cx, data.base_cy,
&data.scale_tex, &data.scale_resource, nullptr,
nullptr);
success = create_d3d11_tex(data.base_cx, data.base_cy, &data.scale_tex,
&data.scale_resource, nullptr, nullptr);
if (!success) {
hlog("d3d11_init_scaling: failed to create scale texture");
return false;
@@ -457,10 +460,11 @@ static bool d3d11_shmem_init_buffers(size_t idx)
HRESULT hr;
hr = data.context->Map(data.copy_surfaces[idx], 0,
D3D11_MAP_READ, 0, &map);
D3D11_MAP_READ, 0, &map);
if (FAILED(hr)) {
hlog_hr("d3d11_shmem_init_buffers: failed to get "
"pitch", hr);
"pitch",
hr);
return false;
}
@@ -469,7 +473,7 @@ static bool d3d11_shmem_init_buffers(size_t idx)
}
success = create_d3d11_tex(data.cx, data.cy, &data.textures[idx],
nullptr, &data.render_targets[idx], nullptr);
nullptr, &data.render_targets[idx], nullptr);
if (!success) {
hlog("d3d11_shmem_init_buffers: failed to create texture");
return false;
@@ -487,9 +491,9 @@ static bool d3d11_shmem_init(HWND window)
return false;
}
}
if (!capture_init_shmem(&data.shmem_info, window,
data.base_cx, data.base_cy, data.cx, data.cy,
data.pitch, data.format, false)) {
if (!capture_init_shmem(&data.shmem_info, window, data.base_cx,
data.base_cy, data.cx, data.cy, data.pitch,
data.format, false)) {
return false;
}
@@ -505,7 +509,7 @@ static bool d3d11_shtex_init(HWND window)
data.using_shtex = true;
success = create_d3d11_tex(data.cx, data.cy, &data.texture, &resource,
&data.render_target, &data.handle);
&data.render_target, &data.handle);
if (resource)
resource->Release();
@@ -513,9 +517,9 @@ static bool d3d11_shtex_init(HWND window)
hlog("d3d11_shtex_init: failed to create texture");
return false;
}
if (!capture_init_shtex(&data.shtex_info, window,
data.base_cx, data.base_cy, data.cx, data.cy,
data.format, false, (uintptr_t)data.handle)) {
if (!capture_init_shtex(&data.shtex_info, window, data.base_cx,
data.base_cy, data.cx, data.cy, data.format,
false, (uintptr_t)data.handle)) {
return false;
}
@@ -531,7 +535,7 @@ static void d3d11_init(IDXGISwapChain *swap)
data.using_scale = global_hook_info->use_scale;
hr = swap->GetDevice(__uuidof(ID3D11Device), (void**)&data.device);
hr = swap->GetDevice(__uuidof(ID3D11Device), (void **)&data.device);
if (FAILED(hr)) {
hlog_hr("d3d11_init: failed to get device from swap", hr);
return;
@@ -561,38 +565,38 @@ static void d3d11_init(IDXGISwapChain *swap)
d3d11_free();
}
#define MAX_RENDER_TARGETS D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT
#define MAX_SO_TARGETS 4
#define MAX_CLASS_INSTS 256
#define MAX_RENDER_TARGETS D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT
#define MAX_SO_TARGETS 4
#define MAX_CLASS_INSTS 256
struct d3d11_state {
ID3D11GeometryShader *geom_shader;
ID3D11InputLayout *vertex_layout;
D3D11_PRIMITIVE_TOPOLOGY topology;
ID3D11Buffer *vertex_buffer;
UINT vb_stride;
UINT vb_offset;
ID3D11BlendState *blend_state;
float blend_factor[4];
UINT sample_mask;
ID3D11DepthStencilState *zstencil_state;
UINT zstencil_ref;
ID3D11RenderTargetView *render_targets[MAX_RENDER_TARGETS];
ID3D11DepthStencilView *zstencil_view;
ID3D11SamplerState *sampler_state;
ID3D11PixelShader *pixel_shader;
ID3D11ShaderResourceView *resource;
ID3D11RasterizerState *raster_state;
UINT num_viewports;
D3D11_VIEWPORT *viewports;
ID3D11Buffer *stream_output_targets[MAX_SO_TARGETS];
ID3D11VertexShader *vertex_shader;
ID3D11ClassInstance *gs_class_instances[MAX_CLASS_INSTS];
ID3D11ClassInstance *ps_class_instances[MAX_CLASS_INSTS];
ID3D11ClassInstance *vs_class_instances[MAX_CLASS_INSTS];
UINT gs_class_inst_count;
UINT ps_class_inst_count;
UINT vs_class_inst_count;
ID3D11GeometryShader *geom_shader;
ID3D11InputLayout *vertex_layout;
D3D11_PRIMITIVE_TOPOLOGY topology;
ID3D11Buffer *vertex_buffer;
UINT vb_stride;
UINT vb_offset;
ID3D11BlendState *blend_state;
float blend_factor[4];
UINT sample_mask;
ID3D11DepthStencilState *zstencil_state;
UINT zstencil_ref;
ID3D11RenderTargetView *render_targets[MAX_RENDER_TARGETS];
ID3D11DepthStencilView *zstencil_view;
ID3D11SamplerState *sampler_state;
ID3D11PixelShader *pixel_shader;
ID3D11ShaderResourceView *resource;
ID3D11RasterizerState *raster_state;
UINT num_viewports;
D3D11_VIEWPORT *viewports;
ID3D11Buffer *stream_output_targets[MAX_SO_TARGETS];
ID3D11VertexShader *vertex_shader;
ID3D11ClassInstance *gs_class_instances[MAX_CLASS_INSTS];
ID3D11ClassInstance *ps_class_instances[MAX_CLASS_INSTS];
ID3D11ClassInstance *vs_class_instances[MAX_CLASS_INSTS];
UINT gs_class_inst_count;
UINT ps_class_inst_count;
UINT vs_class_inst_count;
};
static inline void d3d11_save_state(struct d3d11_state *state)
@@ -602,76 +606,77 @@ static inline void d3d11_save_state(struct d3d11_state *state)
state->vs_class_inst_count = MAX_CLASS_INSTS;
data.context->GSGetShader(&state->geom_shader,
state->gs_class_instances,
&state->gs_class_inst_count);
state->gs_class_instances,
&state->gs_class_inst_count);
data.context->IAGetInputLayout(&state->vertex_layout);
data.context->IAGetPrimitiveTopology(&state->topology);
data.context->IAGetVertexBuffers(0, 1, &state->vertex_buffer,
&state->vb_stride, &state->vb_offset);
&state->vb_stride, &state->vb_offset);
data.context->OMGetBlendState(&state->blend_state, state->blend_factor,
&state->sample_mask);
&state->sample_mask);
data.context->OMGetDepthStencilState(&state->zstencil_state,
&state->zstencil_ref);
&state->zstencil_ref);
data.context->OMGetRenderTargets(MAX_RENDER_TARGETS,
state->render_targets, &state->zstencil_view);
state->render_targets,
&state->zstencil_view);
data.context->PSGetSamplers(0, 1, &state->sampler_state);
data.context->PSGetShader(&state->pixel_shader,
state->ps_class_instances,
&state->ps_class_inst_count);
state->ps_class_instances,
&state->ps_class_inst_count);
data.context->PSGetShaderResources(0, 1, &state->resource);
data.context->RSGetState(&state->raster_state);
data.context->RSGetViewports(&state->num_viewports, nullptr);
if (state->num_viewports) {
state->viewports = (D3D11_VIEWPORT*)malloc(
sizeof(D3D11_VIEWPORT) * state->num_viewports);
state->viewports = (D3D11_VIEWPORT *)malloc(
sizeof(D3D11_VIEWPORT) * state->num_viewports);
data.context->RSGetViewports(&state->num_viewports,
state->viewports);
state->viewports);
}
data.context->SOGetTargets(MAX_SO_TARGETS,
state->stream_output_targets);
state->stream_output_targets);
data.context->VSGetShader(&state->vertex_shader,
state->vs_class_instances,
&state->vs_class_inst_count);
state->vs_class_instances,
&state->vs_class_inst_count);
}
static inline void safe_release(IUnknown *p)
{
if (p) p->Release();
if (p)
p->Release();
}
#define SO_APPEND ((UINT)-1)
static inline void d3d11_restore_state(struct d3d11_state *state)
{
UINT so_offsets[MAX_SO_TARGETS] =
{SO_APPEND, SO_APPEND, SO_APPEND, SO_APPEND};
UINT so_offsets[MAX_SO_TARGETS] = {SO_APPEND, SO_APPEND, SO_APPEND,
SO_APPEND};
data.context->GSSetShader(state->geom_shader,
state->gs_class_instances,
state->gs_class_inst_count);
data.context->GSSetShader(state->geom_shader, state->gs_class_instances,
state->gs_class_inst_count);
data.context->IASetInputLayout(state->vertex_layout);
data.context->IASetPrimitiveTopology(state->topology);
data.context->IASetVertexBuffers(0, 1, &state->vertex_buffer,
&state->vb_stride, &state->vb_offset);
&state->vb_stride, &state->vb_offset);
data.context->OMSetBlendState(state->blend_state, state->blend_factor,
state->sample_mask);
state->sample_mask);
data.context->OMSetDepthStencilState(state->zstencil_state,
state->zstencil_ref);
state->zstencil_ref);
data.context->OMSetRenderTargets(MAX_RENDER_TARGETS,
state->render_targets,
state->zstencil_view);
state->render_targets,
state->zstencil_view);
data.context->PSSetSamplers(0, 1, &state->sampler_state);
data.context->PSSetShader(state->pixel_shader,
state->ps_class_instances,
state->ps_class_inst_count);
state->ps_class_instances,
state->ps_class_inst_count);
data.context->PSSetShaderResources(0, 1, &state->resource);
data.context->RSSetState(state->raster_state);
data.context->RSSetViewports(state->num_viewports, state->viewports);
data.context->SOSetTargets(MAX_SO_TARGETS,
state->stream_output_targets, so_offsets);
data.context->SOSetTargets(MAX_SO_TARGETS, state->stream_output_targets,
so_offsets);
data.context->VSSetShader(state->vertex_shader,
state->vs_class_instances,
state->vs_class_inst_count);
state->vs_class_instances,
state->vs_class_inst_count);
safe_release(state->geom_shader);
safe_release(state->vertex_layout);
safe_release(state->vertex_buffer);
@@ -698,7 +703,7 @@ static inline void d3d11_restore_state(struct d3d11_state *state)
}
static inline void d3d11_setup_pipeline(ID3D11RenderTargetView *target,
ID3D11ShaderResourceView *resource)
ID3D11ShaderResourceView *resource)
{
const float factor[4] = {1.0f, 1.0f, 1.0f, 1.0f};
D3D11_VIEWPORT viewport = {0};
@@ -713,9 +718,9 @@ static inline void d3d11_setup_pipeline(ID3D11RenderTargetView *target,
data.context->GSSetShader(nullptr, nullptr, 0);
data.context->IASetInputLayout(data.vertex_layout);
data.context->IASetPrimitiveTopology(
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
data.context->IASetVertexBuffers(0, 1, &data.vertex_buffer, &stride,
&zero);
&zero);
data.context->OMSetBlendState(data.blend_state, factor, 0xFFFFFFFF);
data.context->OMSetDepthStencilState(data.zstencil_state, 0);
data.context->OMSetRenderTargets(1, &target, nullptr);
@@ -724,12 +729,12 @@ static inline void d3d11_setup_pipeline(ID3D11RenderTargetView *target,
data.context->PSSetShaderResources(0, 1, &resource);
data.context->RSSetState(data.raster_state);
data.context->RSSetViewports(1, &viewport);
data.context->SOSetTargets(1, (ID3D11Buffer**)&emptyptr, &zero);
data.context->SOSetTargets(1, (ID3D11Buffer **)&emptyptr, &zero);
data.context->VSSetShader(data.vertex_shader, nullptr, 0);
}
static inline void d3d11_scale_texture(ID3D11RenderTargetView *target,
ID3D11ShaderResourceView *resource)
ID3D11ShaderResourceView *resource)
{
static struct d3d11_state old_state = {0};
@@ -768,7 +773,7 @@ static inline void d3d11_shmem_queue_copy()
data.texture_ready[i] = false;
hr = data.context->Map(data.copy_surfaces[i], 0,
D3D11_MAP_READ, 0, &map);
D3D11_MAP_READ, 0, &map);
if (SUCCEEDED(hr)) {
data.texture_mapped[i] = true;
shmem_copy_data(i, map.pData);
@@ -784,12 +789,12 @@ static inline void d3d11_shmem_capture(ID3D11Resource *backbuffer)
d3d11_shmem_queue_copy();
next_tex = (data.cur_tex == NUM_BUFFERS - 1) ? 0 : data.cur_tex + 1;
next_tex = (data.cur_tex == NUM_BUFFERS - 1) ? 0 : data.cur_tex + 1;
if (data.using_scale) {
d3d11_copy_texture(data.scale_tex, backbuffer);
d3d11_scale_texture(data.render_targets[data.cur_tex],
data.scale_resource);
data.scale_resource);
} else {
d3d11_copy_texture(data.textures[data.cur_tex], backbuffer);
}
@@ -815,8 +820,8 @@ static inline void d3d11_shmem_capture(ID3D11Resource *backbuffer)
void d3d11_capture(void *swap_ptr, void *backbuffer_ptr, bool)
{
IDXGIResource *dxgi_backbuffer = (IDXGIResource*)backbuffer_ptr;
IDXGISwapChain *swap = (IDXGISwapChain*)swap_ptr;
IDXGIResource *dxgi_backbuffer = (IDXGIResource *)backbuffer_ptr;
IDXGISwapChain *swap = (IDXGISwapChain *)swap_ptr;
HRESULT hr;
if (capture_should_stop()) {
@@ -829,10 +834,11 @@ void d3d11_capture(void *swap_ptr, void *backbuffer_ptr, bool)
ID3D11Resource *backbuffer;
hr = dxgi_backbuffer->QueryInterface(__uuidof(ID3D11Resource),
(void**)&backbuffer);
(void **)&backbuffer);
if (FAILED(hr)) {
hlog_hr("d3d11_shtex_capture: failed to get "
"backbuffer", hr);
"backbuffer",
hr);
return;
}

View File

@@ -13,29 +13,29 @@
#define MAX_BACKBUFFERS 8
struct d3d12_data {
ID3D12Device *device; /* do not release */
uint32_t base_cx;
uint32_t base_cy;
uint32_t cx;
uint32_t cy;
DXGI_FORMAT format;
bool using_shtex;
bool using_scale;
bool multisampled;
bool dxgi_1_4;
ID3D12Device *device; /* do not release */
uint32_t base_cx;
uint32_t base_cy;
uint32_t cx;
uint32_t cy;
DXGI_FORMAT format;
bool using_shtex;
bool using_scale;
bool multisampled;
bool dxgi_1_4;
ID3D11Device *device11;
ID3D11DeviceContext *context11;
ID3D11On12Device *device11on12;
ID3D11Device *device11;
ID3D11DeviceContext *context11;
ID3D11On12Device *device11on12;
union {
struct {
struct shtex_data *shtex_info;
ID3D11Resource *backbuffer11[MAX_BACKBUFFERS];
UINT backbuffer_count;
UINT cur_backbuffer;
ID3D11Texture2D *copy_tex;
HANDLE handle;
struct shtex_data *shtex_info;
ID3D11Resource *backbuffer11[MAX_BACKBUFFERS];
UINT backbuffer_count;
UINT cur_backbuffer;
ID3D11Texture2D *copy_tex;
HANDLE handle;
};
};
};
@@ -81,15 +81,14 @@ static bool create_d3d12_tex(bb_info &bb)
for (UINT i = 0; i < bb.count; i++) {
hr = data.device11on12->CreateWrappedResource(
bb.backbuffer[i],
&rf11,
D3D12_RESOURCE_STATE_COPY_SOURCE,
D3D12_RESOURCE_STATE_PRESENT,
__uuidof(ID3D11Resource),
(void**)&data.backbuffer11[i]);
bb.backbuffer[i], &rf11,
D3D12_RESOURCE_STATE_COPY_SOURCE,
D3D12_RESOURCE_STATE_PRESENT, __uuidof(ID3D11Resource),
(void **)&data.backbuffer11[i]);
if (FAILED(hr)) {
hlog_hr("create_d3d12_tex: failed to create "
"backbuffer11", hr);
"backbuffer11",
hr);
return false;
}
}
@@ -107,21 +106,22 @@ static bool create_d3d12_tex(bb_info &bb)
hr = data.device11->CreateTexture2D(&desc11, nullptr, &data.copy_tex);
if (FAILED(hr)) {
hlog_hr("create_d3d12_tex: creation of d3d11 copy tex failed",
hr);
hr);
return false;
}
for (UINT i = 0; i < bb.count; i++) {
data.device11on12->ReleaseWrappedResources(
&data.backbuffer11[i], 1);
&data.backbuffer11[i], 1);
}
IDXGIResource *dxgi_res;
hr = data.copy_tex->QueryInterface(__uuidof(IDXGIResource),
(void**)&dxgi_res);
(void **)&dxgi_res);
if (FAILED(hr)) {
hlog_hr("create_d3d12_tex: failed to query "
"IDXGIResource interface from texture", hr);
"IDXGIResource interface from texture",
hr);
return false;
}
@@ -137,8 +137,7 @@ static bool create_d3d12_tex(bb_info &bb)
typedef PFN_D3D11ON12_CREATE_DEVICE create_11_on_12_t;
const static D3D_FEATURE_LEVEL feature_levels[] =
{
const static D3D_FEATURE_LEVEL feature_levels[] = {
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
@@ -166,11 +165,11 @@ static bool d3d12_init_11on12(void)
}
if (!initialized_func && !create_11_on_12) {
create_11_on_12 = (create_11_on_12_t)GetProcAddress(d3d11,
"D3D11On12CreateDevice");
create_11_on_12 = (create_11_on_12_t)GetProcAddress(
d3d11, "D3D11On12CreateDevice");
if (!create_11_on_12) {
hlog("d3d12_init_11on12: Failed to get "
"D3D11On12CreateDevice address");
"D3D11On12CreateDevice address");
}
initialized_func = true;
@@ -180,16 +179,15 @@ static bool d3d12_init_11on12(void)
return false;
}
hr = create_11_on_12(data.device, 0, nullptr, 0,
nullptr, 0, 0,
&data.device11, &data.context11, nullptr);
hr = create_11_on_12(data.device, 0, nullptr, 0, nullptr, 0, 0,
&data.device11, &data.context11, nullptr);
if (FAILED(hr)) {
hlog_hr("d3d12_init_11on12: failed to create 11 device", hr);
return false;
}
data.device11->QueryInterface(__uuidof(ID3D11On12Device),
(void**)&data.device11on12);
(void **)&data.device11on12);
if (FAILED(hr)) {
hlog_hr("d3d12_init_11on12: failed to query 11on12 device", hr);
return false;
@@ -206,9 +204,9 @@ static bool d3d12_shtex_init(HWND window, bb_info &bb)
if (!create_d3d12_tex(bb)) {
return false;
}
if (!capture_init_shtex(&data.shtex_info, window,
data.base_cx, data.base_cy, data.cx, data.cy,
data.format, false, (uintptr_t)data.handle)) {
if (!capture_init_shtex(&data.shtex_info, window, data.base_cx,
data.base_cy, data.cx, data.cy, data.format,
false, (uintptr_t)data.handle)) {
return false;
}
@@ -217,7 +215,7 @@ static bool d3d12_shtex_init(HWND window, bb_info &bb)
}
static inline bool d3d12_init_format(IDXGISwapChain *swap, HWND &window,
bb_info &bb)
bb_info &bb)
{
DXGI_SWAP_CHAIN_DESC desc;
IDXGISwapChain3 *swap3;
@@ -235,7 +233,7 @@ static inline bool d3d12_init_format(IDXGISwapChain *swap, HWND &window,
data.base_cx = desc.BufferDesc.Width;
data.base_cy = desc.BufferDesc.Height;
hr = swap->QueryInterface(__uuidof(IDXGISwapChain3), (void**)&swap3);
hr = swap->QueryInterface(__uuidof(IDXGISwapChain3), (void **)&swap3);
if (SUCCEEDED(hr)) {
data.dxgi_1_4 = true;
hlog("We're DXGI1.4 boys!");
@@ -243,24 +241,25 @@ static inline bool d3d12_init_format(IDXGISwapChain *swap, HWND &window,
}
hlog("Buffer count: %d, swap effect: %d", (int)desc.BufferCount,
(int)desc.SwapEffect);
(int)desc.SwapEffect);
bb.count = desc.SwapEffect == DXGI_SWAP_EFFECT_DISCARD
? 1 : desc.BufferCount;
? 1
: desc.BufferCount;
if (bb.count == 1)
data.dxgi_1_4 = false;
if (bb.count > MAX_BACKBUFFERS) {
hlog("Somehow it's using more than the max backbuffers. "
"Not sure why anyone would do that.");
"Not sure why anyone would do that.");
bb.count = 1;
data.dxgi_1_4 = false;
}
for (UINT i = 0; i < bb.count; i++) {
hr = swap->GetBuffer(i, __uuidof(ID3D12Resource),
(void**)&bb.backbuffer[i]);
(void **)&bb.backbuffer[i]);
if (SUCCEEDED(hr)) {
bb.backbuffer[i]->Release();
} else {
@@ -287,7 +286,7 @@ static void d3d12_init(IDXGISwapChain *swap)
data.using_scale = global_hook_info->use_scale;
hr = swap->GetDevice(__uuidof(ID3D12Device), (void**)&data.device);
hr = swap->GetDevice(__uuidof(ID3D12Device), (void **)&data.device);
if (FAILED(hr)) {
hlog_hr("d3d12_init: failed to get device from swap", hr);
return;
@@ -304,7 +303,7 @@ static void d3d12_init(IDXGISwapChain *swap)
if (success) {
if (global_hook_info->force_shmem) {
hlog("d3d12_init: shared memory capture currently "
"unsupported; ignoring");
"unsupported; ignoring");
}
success = d3d12_shtex_init(window, bb);
@@ -324,14 +323,14 @@ static inline void d3d12_copy_texture(ID3D11Resource *dst, ID3D11Resource *src)
}
static inline void d3d12_shtex_capture(IDXGISwapChain *swap,
bool capture_overlay)
bool capture_overlay)
{
bool dxgi_1_4 = data.dxgi_1_4;
UINT cur_idx;
if (dxgi_1_4) {
IDXGISwapChain3 *swap3 =
reinterpret_cast<IDXGISwapChain3*>(swap);
reinterpret_cast<IDXGISwapChain3 *>(swap);
cur_idx = swap3->GetCurrentBackBufferIndex();
if (!capture_overlay) {
if (++cur_idx >= data.backbuffer_count)
@@ -354,9 +353,9 @@ static inline void d3d12_shtex_capture(IDXGISwapChain *swap,
}
}
void d3d12_capture(void *swap_ptr, void*, bool capture_overlay)
void d3d12_capture(void *swap_ptr, void *, bool capture_overlay)
{
IDXGISwapChain *swap = (IDXGISwapChain*)swap_ptr;
IDXGISwapChain *swap = (IDXGISwapChain *)swap_ptr;
if (capture_should_stop()) {
d3d12_free();

View File

@@ -1,7 +1,6 @@
#pragma once
static const char vertex_shader_string[] =
"struct VertData \
static const char vertex_shader_string[] = "struct VertData \
{ \
float4 pos : SV_Position; \
float2 texCoord : TexCoord0; \
@@ -14,8 +13,7 @@ VertData main(VertData input) \
return output; \
}";
static const char pixel_shader_string[] =
"uniform Texture2D diffuseTexture; \
static const char pixel_shader_string[] = "uniform Texture2D diffuseTexture; \
SamplerState textureSampler \
{ \
AddressU = Clamp; \

View File

@@ -4,28 +4,29 @@
#include "graphics-hook.h"
#include "../funchook.h"
typedef HRESULT(STDMETHODCALLTYPE *reset_t)(IDirect3DDevice8*,
D3DPRESENT_PARAMETERS*);
typedef HRESULT(STDMETHODCALLTYPE *present_t)(IDirect3DDevice8*,
CONST RECT*, CONST RECT*, HWND, CONST RGNDATA*);
typedef HRESULT(STDMETHODCALLTYPE *reset_t)(IDirect3DDevice8 *,
D3DPRESENT_PARAMETERS *);
typedef HRESULT(STDMETHODCALLTYPE *present_t)(IDirect3DDevice8 *, CONST RECT *,
CONST RECT *, HWND,
CONST RGNDATA *);
static struct func_hook present;
static struct func_hook reset;
struct d3d8_data {
HMODULE d3d8;
uint32_t cx;
uint32_t cy;
D3DFORMAT d3d8_format;
DXGI_FORMAT dxgi_format;
HMODULE d3d8;
uint32_t cx;
uint32_t cy;
D3DFORMAT d3d8_format;
DXGI_FORMAT dxgi_format;
struct shmem_data *shmem_info;
HWND window;
uint32_t pitch;
IDirect3DSurface8 *copy_surfaces[NUM_BUFFERS];
bool surface_locked[NUM_BUFFERS];
int cur_surface;
int copy_wait;
struct shmem_data *shmem_info;
HWND window;
uint32_t pitch;
IDirect3DSurface8 *copy_surfaces[NUM_BUFFERS];
bool surface_locked[NUM_BUFFERS];
int cur_surface;
int copy_wait;
};
static d3d8_data data = {};
@@ -34,10 +35,14 @@ static DXGI_FORMAT d3d8_to_dxgi_format(D3DFORMAT format)
{
switch ((unsigned long)format) {
case D3DFMT_X1R5G5B5:
case D3DFMT_A1R5G5B5: return DXGI_FORMAT_B5G5R5A1_UNORM;
case D3DFMT_R5G6B5: return DXGI_FORMAT_B5G6R5_UNORM;
case D3DFMT_A8R8G8B8: return DXGI_FORMAT_B8G8R8A8_UNORM;
case D3DFMT_X8R8G8B8: return DXGI_FORMAT_B8G8R8X8_UNORM;
case D3DFMT_A1R5G5B5:
return DXGI_FORMAT_B5G5R5A1_UNORM;
case D3DFMT_R5G6B5:
return DXGI_FORMAT_B5G6R5_UNORM;
case D3DFMT_A8R8G8B8:
return DXGI_FORMAT_B8G8R8A8_UNORM;
case D3DFMT_X8R8G8B8:
return DXGI_FORMAT_B8G8R8X8_UNORM;
}
return DXGI_FORMAT_UNKNOWN;
@@ -64,7 +69,8 @@ static bool d3d8_get_window_handle(IDirect3DDevice8 *device)
hr = device->GetCreationParameters(&parameters);
if (FAILED(hr)) {
hlog_hr("d3d8_get_window_handle: Failed to get "
"device creation parameters", hr);
"device creation parameters",
hr);
return false;
}
@@ -90,7 +96,8 @@ static bool d3d8_init_format_backbuffer(IDirect3DDevice8 *device)
backbuffer->Release();
if (FAILED(hr)) {
hlog_hr("d3d8_init_format_backbuffer: Failed to get "
"backbuffer descriptor", hr);
"backbuffer descriptor",
hr);
return false;
}
@@ -106,8 +113,8 @@ static bool d3d8_shmem_init_buffer(IDirect3DDevice8 *device, int idx)
{
HRESULT hr;
hr = device->CreateImageSurface(data.cx, data.cy,
data.d3d8_format, &data.copy_surfaces[idx]);
hr = device->CreateImageSurface(data.cx, data.cy, data.d3d8_format,
&data.copy_surfaces[idx]);
if (FAILED(hr)) {
hlog_hr("d3d8_shmem_init_buffer: Failed to create surface", hr);
return false;
@@ -116,9 +123,10 @@ static bool d3d8_shmem_init_buffer(IDirect3DDevice8 *device, int idx)
if (idx == 0) {
D3DLOCKED_RECT rect;
hr = data.copy_surfaces[0]->LockRect(&rect, nullptr,
D3DLOCK_READONLY);
D3DLOCK_READONLY);
if (FAILED(hr)) {
hlog_hr("d3d8_shmem_init_buffer: Failed to lock buffer", hr);
hlog_hr("d3d8_shmem_init_buffer: Failed to lock buffer",
hr);
return false;
}
@@ -190,7 +198,7 @@ static void d3d8_shmem_capture_copy(int idx)
}
static void d3d8_shmem_capture(IDirect3DDevice8 *device,
IDirect3DSurface8 *backbuffer)
IDirect3DSurface8 *backbuffer)
{
int cur_surface;
int next_surface;
@@ -221,7 +229,7 @@ static void d3d8_shmem_capture(IDirect3DDevice8 *device,
}
static void d3d8_capture(IDirect3DDevice8 *device,
IDirect3DSurface8 *backbuffer)
IDirect3DSurface8 *backbuffer)
{
if (capture_should_stop()) {
d3d8_free();
@@ -234,9 +242,8 @@ static void d3d8_capture(IDirect3DDevice8 *device,
}
}
static HRESULT STDMETHODCALLTYPE hook_reset(IDirect3DDevice8 *device,
D3DPRESENT_PARAMETERS *parameters)
D3DPRESENT_PARAMETERS *parameters)
{
HRESULT hr;
@@ -255,18 +262,20 @@ static bool hooked_reset = false;
static void setup_reset_hooks(IDirect3DDevice8 *device)
{
uintptr_t *vtable = *(uintptr_t**)device;
uintptr_t *vtable = *(uintptr_t **)device;
hook_init(&reset, (void*)vtable[14], (void*)hook_reset,
"IDirect3DDevice8::Reset");
hook_init(&reset, (void *)vtable[14], (void *)hook_reset,
"IDirect3DDevice8::Reset");
rehook(&reset);
hooked_reset = true;
}
static HRESULT STDMETHODCALLTYPE hook_present(IDirect3DDevice8 *device,
CONST RECT *src_rect, CONST RECT *dst_rect,
HWND override_window, CONST RGNDATA *dirty_region)
CONST RECT *src_rect,
CONST RECT *dst_rect,
HWND override_window,
CONST RGNDATA *dirty_region)
{
IDirect3DSurface8 *backbuffer;
HRESULT hr;
@@ -291,7 +300,7 @@ static HRESULT STDMETHODCALLTYPE hook_present(IDirect3DDevice8 *device,
typedef IDirect3D8 *(WINAPI *d3d8create_t)(UINT);
static bool manually_get_d3d8_present_addr(HMODULE d3d8_module,
void **present_addr)
void **present_addr)
{
d3d8create_t create;
D3DPRESENT_PARAMETERS pp;
@@ -315,22 +324,23 @@ static bool manually_get_d3d8_present_addr(HMODULE d3d8_module,
}
memset(&pp, 0, sizeof(pp));
pp.Windowed = true;
pp.SwapEffect = D3DSWAPEFFECT_FLIP;
pp.BackBufferFormat = D3DFMT_A8R8G8B8;
pp.BackBufferWidth = 2;
pp.BackBufferHeight = 2;
pp.BackBufferCount = 1;
pp.hDeviceWindow = dummy_window;
pp.Windowed = true;
pp.SwapEffect = D3DSWAPEFFECT_FLIP;
pp.BackBufferFormat = D3DFMT_A8R8G8B8;
pp.BackBufferWidth = 2;
pp.BackBufferHeight = 2;
pp.BackBufferCount = 1;
pp.hDeviceWindow = dummy_window;
hr = d3d8->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
dummy_window, D3DCREATE_HARDWARE_VERTEXPROCESSING, &pp,
&device);
dummy_window,
D3DCREATE_HARDWARE_VERTEXPROCESSING, &pp,
&device);
d3d8->Release();
if (SUCCEEDED(hr)) {
uintptr_t *vtable = *(uintptr_t**)device;
*present_addr = (void*)vtable[15];
uintptr_t *vtable = *(uintptr_t **)device;
*present_addr = (void *)vtable[15];
device->Release();
} else {
@@ -354,15 +364,15 @@ bool hook_d3d8(void)
d3d8_size = module_size(d3d8_module);
if (global_hook_info->offsets.d3d8.present < d3d8_size) {
present_addr = get_offset_addr(d3d8_module,
global_hook_info->offsets.d3d8.present);
present_addr = get_offset_addr(
d3d8_module, global_hook_info->offsets.d3d8.present);
} else {
if (!dummy_window) {
return false;
}
if (!manually_get_d3d8_present_addr(d3d8_module,
&present_addr)) {
&present_addr)) {
hlog("Failed to get D3D8 value");
return true;
}
@@ -373,8 +383,8 @@ bool hook_d3d8(void)
return true;
}
hook_init(&present, present_addr, (void*)hook_present,
"IDirect3DDevice8::Present");
hook_init(&present, present_addr, (void *)hook_present,
"IDirect3DDevice8::Present");
rehook(&present);

View File

@@ -6,18 +6,23 @@
#include "../funchook.h"
#include "d3d9-patches.hpp"
typedef HRESULT (STDMETHODCALLTYPE *present_t)(IDirect3DDevice9*,
CONST RECT*, CONST RECT*, HWND, CONST RGNDATA*);
typedef HRESULT (STDMETHODCALLTYPE *present_ex_t)(IDirect3DDevice9*,
CONST RECT*, CONST RECT*, HWND, CONST RGNDATA*, DWORD);
typedef HRESULT (STDMETHODCALLTYPE *present_swap_t)(IDirect3DSwapChain9*,
CONST RECT*, CONST RECT*, HWND, CONST RGNDATA*, DWORD);
typedef HRESULT (STDMETHODCALLTYPE *reset_t)(IDirect3DDevice9*,
D3DPRESENT_PARAMETERS*);
typedef HRESULT (STDMETHODCALLTYPE *reset_ex_t)(IDirect3DDevice9*,
D3DPRESENT_PARAMETERS*, D3DDISPLAYMODEEX*);
typedef HRESULT(STDMETHODCALLTYPE *present_t)(IDirect3DDevice9 *, CONST RECT *,
CONST RECT *, HWND,
CONST RGNDATA *);
typedef HRESULT(STDMETHODCALLTYPE *present_ex_t)(IDirect3DDevice9 *,
CONST RECT *, CONST RECT *,
HWND, CONST RGNDATA *, DWORD);
typedef HRESULT(STDMETHODCALLTYPE *present_swap_t)(IDirect3DSwapChain9 *,
CONST RECT *, CONST RECT *,
HWND, CONST RGNDATA *,
DWORD);
typedef HRESULT(STDMETHODCALLTYPE *reset_t)(IDirect3DDevice9 *,
D3DPRESENT_PARAMETERS *);
typedef HRESULT(STDMETHODCALLTYPE *reset_ex_t)(IDirect3DDevice9 *,
D3DPRESENT_PARAMETERS *,
D3DDISPLAYMODEEX *);
typedef HRESULT (WINAPI *createfactory1_t)(REFIID, void **);
typedef HRESULT(WINAPI *createfactory1_t)(REFIID, void **);
static struct func_hook present;
static struct func_hook present_ex;
@@ -26,34 +31,34 @@ static struct func_hook reset;
static struct func_hook reset_ex;
struct d3d9_data {
HMODULE d3d9;
IDirect3DDevice9 *device; /* do not release */
uint32_t cx;
uint32_t cy;
D3DFORMAT d3d9_format;
DXGI_FORMAT dxgi_format;
bool using_shtex;
bool using_scale;
HMODULE d3d9;
IDirect3DDevice9 *device; /* do not release */
uint32_t cx;
uint32_t cy;
D3DFORMAT d3d9_format;
DXGI_FORMAT dxgi_format;
bool using_shtex;
bool using_scale;
/* shared texture */
IDirect3DSurface9 *d3d9_copytex;
ID3D11Device *d3d11_device;
ID3D11DeviceContext *d3d11_context;
ID3D11Resource *d3d11_tex;
struct shtex_data *shtex_info;
HANDLE handle;
int patch;
IDirect3DSurface9 *d3d9_copytex;
ID3D11Device *d3d11_device;
ID3D11DeviceContext *d3d11_context;
ID3D11Resource *d3d11_tex;
struct shtex_data *shtex_info;
HANDLE handle;
int patch;
/* shared memory */
IDirect3DSurface9 *copy_surfaces[NUM_BUFFERS];
IDirect3DSurface9 *render_targets[NUM_BUFFERS];
IDirect3DQuery9 *queries[NUM_BUFFERS];
struct shmem_data *shmem_info;
bool texture_mapped[NUM_BUFFERS];
volatile bool issued_queries[NUM_BUFFERS];
uint32_t pitch;
int cur_tex;
int copy_wait;
IDirect3DSurface9 *copy_surfaces[NUM_BUFFERS];
IDirect3DSurface9 *render_targets[NUM_BUFFERS];
IDirect3DQuery9 *queries[NUM_BUFFERS];
struct shmem_data *shmem_info;
bool texture_mapped[NUM_BUFFERS];
volatile bool issued_queries[NUM_BUFFERS];
uint32_t pitch;
int cur_tex;
int copy_wait;
};
static struct d3d9_data data = {};
@@ -93,16 +98,18 @@ static void d3d9_free()
static DXGI_FORMAT d3d9_to_dxgi_format(D3DFORMAT format)
{
switch ((unsigned long)format) {
case D3DFMT_A2B10G10R10: return DXGI_FORMAT_R10G10B10A2_UNORM;
case D3DFMT_A8R8G8B8: return DXGI_FORMAT_B8G8R8A8_UNORM;
case D3DFMT_X8R8G8B8: return DXGI_FORMAT_B8G8R8X8_UNORM;
case D3DFMT_A2B10G10R10:
return DXGI_FORMAT_R10G10B10A2_UNORM;
case D3DFMT_A8R8G8B8:
return DXGI_FORMAT_B8G8R8A8_UNORM;
case D3DFMT_X8R8G8B8:
return DXGI_FORMAT_B8G8R8X8_UNORM;
}
return DXGI_FORMAT_UNKNOWN;
}
const static D3D_FEATURE_LEVEL feature_levels[] =
{
const static D3D_FEATURE_LEVEL feature_levels[] = {
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
@@ -132,21 +139,21 @@ static inline bool shex_init_d3d11()
return false;
}
create_factory = (createfactory1_t)GetProcAddress(dxgi,
"CreateDXGIFactory1");
create_factory =
(createfactory1_t)GetProcAddress(dxgi, "CreateDXGIFactory1");
if (!create_factory) {
hlog("d3d9_init: Failed to get CreateDXGIFactory1 address");
return false;
}
create_device = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(d3d11,
"D3D11CreateDevice");
create_device = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(
d3d11, "D3D11CreateDevice");
if (!create_device) {
hlog("d3d9_init: Failed to get D3D11CreateDevice address");
return false;
}
hr = create_factory(__uuidof(IDXGIFactory1), (void**)&factory);
hr = create_factory(__uuidof(IDXGIFactory1), (void **)&factory);
if (FAILED(hr)) {
hlog_hr("d3d9_init: Failed to create factory object", hr);
return false;
@@ -160,11 +167,11 @@ static inline bool shex_init_d3d11()
return false;
}
hr = create_device(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr,
0, feature_levels,
sizeof(feature_levels) / sizeof(D3D_FEATURE_LEVEL),
D3D11_SDK_VERSION, &data.d3d11_device, &level_used,
&data.d3d11_context);
hr = create_device(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, 0,
feature_levels,
sizeof(feature_levels) / sizeof(D3D_FEATURE_LEVEL),
D3D11_SDK_VERSION, &data.d3d11_device, &level_used,
&data.d3d11_context);
adapter->Release();
if (FAILED(hr)) {
@@ -181,30 +188,29 @@ static inline bool d3d9_shtex_init_shtex()
HRESULT hr;
D3D11_TEXTURE2D_DESC desc = {};
desc.Width = data.cx;
desc.Height = data.cy;
desc.Format = data.dxgi_format;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
desc.BindFlags = D3D11_BIND_RENDER_TARGET |
D3D11_BIND_SHADER_RESOURCE;
desc.Width = data.cx;
desc.Height = data.cy;
desc.Format = data.dxgi_format;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
hr = data.d3d11_device->CreateTexture2D(&desc, nullptr,
(ID3D11Texture2D**)&data.d3d11_tex);
hr = data.d3d11_device->CreateTexture2D(
&desc, nullptr, (ID3D11Texture2D **)&data.d3d11_tex);
if (FAILED(hr)) {
hlog_hr("d3d9_shtex_init_shtex: Failed to create D3D11 texture",
hr);
hr);
return false;
}
hr = data.d3d11_tex->QueryInterface(__uuidof(IDXGIResource),
(void**)&res);
(void **)&res);
if (FAILED(hr)) {
hlog_hr("d3d9_shtex_init_shtex: Failed to query IDXGIResource",
hr);
hr);
return false;
}
@@ -213,7 +219,7 @@ static inline bool d3d9_shtex_init_shtex()
if (FAILED(hr)) {
hlog_hr("d3d9_shtex_init_shtex: Failed to get shared handle",
hr);
hr);
return false;
}
@@ -233,10 +239,10 @@ static inline bool d3d9_shtex_init_copytex()
HRESULT hr;
if (offsets.d3d9_clsoff && offsets.is_d3d9ex_clsoff) {
uint8_t *device_ptr = (uint8_t*)(data.device);
uint8_t *device_ptr = (uint8_t *)(data.device);
uint8_t *d3d9_ptr =
*(uint8_t**)(device_ptr + offsets.d3d9_clsoff);
p_is_d3d9 = (BOOL*)(d3d9_ptr + offsets.is_d3d9ex_clsoff);
*(uint8_t **)(device_ptr + offsets.d3d9_clsoff);
p_is_d3d9 = (BOOL *)(d3d9_ptr + offsets.is_d3d9ex_clsoff);
} else {
patch_addr = get_d3d9_patch_addr(data.d3d9, data.patch);
}
@@ -248,14 +254,14 @@ static inline bool d3d9_shtex_init_copytex()
} else if (patch_addr) {
patch_size = patch[data.patch].size;
VirtualProtect(patch_addr, patch_size, PAGE_EXECUTE_READWRITE,
&protect_val);
&protect_val);
memcpy(saved_data, patch_addr, patch_size);
memcpy(patch_addr, patch[data.patch].data, patch_size);
}
hr = data.device->CreateTexture(data.cx, data.cy, 1,
D3DUSAGE_RENDERTARGET, data.d3d9_format,
D3DPOOL_DEFAULT, &tex, &data.handle);
D3DUSAGE_RENDERTARGET, data.d3d9_format,
D3DPOOL_DEFAULT, &tex, &data.handle);
if (p_is_d3d9) {
*p_is_d3d9 = was_d3d9ex;
@@ -263,12 +269,12 @@ static inline bool d3d9_shtex_init_copytex()
} else if (patch_addr && patch_size) {
memcpy(patch_addr, saved_data, patch_size);
VirtualProtect(patch_addr, patch_size, protect_val,
&protect_val);
&protect_val);
}
if (FAILED(hr)) {
hlog_hr("d3d9_shtex_init_copytex: Failed to create shared texture",
hr);
hr);
return false;
}
@@ -276,7 +282,8 @@ static inline bool d3d9_shtex_init_copytex()
tex->Release();
if (FAILED(hr)) {
hlog_hr("d3d9_shtex_init_copytex: Failed to get surface level", hr);
hlog_hr("d3d9_shtex_init_copytex: Failed to get surface level",
hr);
return false;
}
@@ -296,8 +303,8 @@ static bool d3d9_shtex_init(uint32_t cx, uint32_t cy, HWND window)
if (!d3d9_shtex_init_copytex()) {
return false;
}
if (!capture_init_shtex(&data.shtex_info, window, cx, cy,
data.cx, data.cy, data.dxgi_format, false,
if (!capture_init_shtex(&data.shtex_info, window, cx, cy, data.cx,
data.cy, data.dxgi_format, false,
(uintptr_t)data.handle)) {
return false;
}
@@ -310,40 +317,43 @@ static bool d3d9_shmem_init_buffers(size_t buffer)
{
HRESULT hr;
hr = data.device->CreateOffscreenPlainSurface(data.cx, data.cy,
data.d3d9_format, D3DPOOL_SYSTEMMEM,
&data.copy_surfaces[buffer], nullptr);
hr = data.device->CreateOffscreenPlainSurface(
data.cx, data.cy, data.d3d9_format, D3DPOOL_SYSTEMMEM,
&data.copy_surfaces[buffer], nullptr);
if (FAILED(hr)) {
hlog_hr("d3d9_shmem_init_buffers: Failed to create surface",
hr);
hr);
return false;
}
if (buffer == 0) {
D3DLOCKED_RECT rect;
hr = data.copy_surfaces[buffer]->LockRect(&rect, nullptr,
D3DLOCK_READONLY);
D3DLOCK_READONLY);
if (FAILED(hr)) {
hlog_hr("d3d9_shmem_init_buffers: Failed to lock "
"buffer", hr);
"buffer",
hr);
return false;
}
data.pitch = rect.Pitch;
data.copy_surfaces[buffer]->UnlockRect();
}
}
hr = data.device->CreateRenderTarget(data.cx, data.cy,
data.d3d9_format, D3DMULTISAMPLE_NONE, 0, false,
&data.render_targets[buffer], nullptr);
hr = data.device->CreateRenderTarget(data.cx, data.cy, data.d3d9_format,
D3DMULTISAMPLE_NONE, 0, false,
&data.render_targets[buffer],
nullptr);
if (FAILED(hr)) {
hlog_hr("d3d9_shmem_init_buffers: Failed to create render "
"target", hr);
"target",
hr);
return false;
}
hr = data.device->CreateQuery(D3DQUERYTYPE_EVENT,
&data.queries[buffer]);
&data.queries[buffer]);
if (FAILED(hr)) {
hlog_hr("d3d9_shmem_init_buffers: Failed to create query", hr);
return false;
@@ -361,9 +371,8 @@ static bool d3d9_shmem_init(uint32_t cx, uint32_t cy, HWND window)
return false;
}
}
if (!capture_init_shmem(&data.shmem_info, window, cx, cy,
data.cx, data.cy, data.pitch, data.dxgi_format,
false)) {
if (!capture_init_shmem(&data.shmem_info, window, cx, cy, data.cx,
data.cy, data.pitch, data.dxgi_format, false)) {
return false;
}
@@ -387,7 +396,8 @@ static bool d3d9_get_swap_desc(D3DPRESENT_PARAMETERS &pp)
if (FAILED(hr)) {
hlog_hr("d3d9_get_swap_desc: Failed to get "
"presentation parameters", hr);
"presentation parameters",
hr);
return false;
}
@@ -395,7 +405,7 @@ static bool d3d9_get_swap_desc(D3DPRESENT_PARAMETERS &pp)
}
static bool d3d9_init_format_backbuffer(uint32_t &cx, uint32_t &cy,
HWND &window)
HWND &window)
{
IDirect3DSurface9 *back_buffer = nullptr;
D3DPRESENT_PARAMETERS pp;
@@ -416,7 +426,8 @@ static bool d3d9_init_format_backbuffer(uint32_t &cx, uint32_t &cy,
if (FAILED(hr)) {
hlog_hr("d3d9_init_format_backbuffer: Failed to get "
"backbuffer descriptor", hr);
"backbuffer descriptor",
hr);
return false;
}
@@ -480,7 +491,7 @@ static void d3d9_init(IDirect3DDevice9 *device)
data.device = device;
hr = device->QueryInterface(__uuidof(IDirect3DDevice9Ex),
(void**)&d3d9ex);
(void **)&d3d9ex);
if (SUCCEEDED(hr)) {
d3d9ex->Release();
data.patch = -1;
@@ -508,7 +519,7 @@ static void d3d9_init(IDirect3DDevice9 *device)
}
static inline HRESULT get_backbuffer(IDirect3DDevice9 *device,
IDirect3DSurface9 **surface)
IDirect3DSurface9 **surface)
{
static bool use_backbuffer = false;
static bool checked_exceptions = false;
@@ -521,7 +532,7 @@ static inline HRESULT get_backbuffer(IDirect3DDevice9 *device,
if (use_backbuffer) {
return device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO,
surface);
surface);
} else {
return device->GetRenderTarget(0, surface);
}
@@ -535,7 +546,7 @@ static inline void d3d9_shtex_capture(IDirect3DSurface9 *backbuffer)
filter = data.using_scale ? D3DTEXF_LINEAR : D3DTEXF_NONE;
hr = data.device->StretchRect(backbuffer, nullptr, data.d3d9_copytex,
nullptr, filter);
nullptr, filter);
if (FAILED(hr))
hlog_hr("d3d9_shtex_capture: StretchRect failed", hr);
}
@@ -574,12 +585,12 @@ static inline void d3d9_shmem_capture(IDirect3DSurface9 *backbuffer)
d3d9_shmem_capture_queue_copy();
next_tex = (data.cur_tex == NUM_BUFFERS - 1) ? 0 : data.cur_tex + 1;
next_tex = (data.cur_tex == NUM_BUFFERS - 1) ? 0 : data.cur_tex + 1;
filter = data.using_scale ? D3DTEXF_LINEAR : D3DTEXF_NONE;
copy = data.render_targets[data.cur_tex];
hr = data.device->StretchRect(backbuffer, nullptr, copy, nullptr,
filter);
filter);
if (FAILED(hr)) {
hlog_hr("d3d9_shmem_capture: StretchRect failed", hr);
@@ -601,7 +612,8 @@ static inline void d3d9_shmem_capture(IDirect3DSurface9 *backbuffer)
hr = data.device->GetRenderTargetData(src, dst);
if (FAILED(hr)) {
hlog_hr("d3d9_shmem_capture: GetRenderTargetData "
"failed", hr);
"failed",
hr);
}
data.queries[next_tex]->Issue(D3DISSUE_END);
@@ -612,7 +624,7 @@ static inline void d3d9_shmem_capture(IDirect3DSurface9 *backbuffer)
}
static void d3d9_capture(IDirect3DDevice9 *device,
IDirect3DSurface9 *backbuffer)
IDirect3DSurface9 *backbuffer)
{
if (capture_should_stop()) {
d3d9_free();
@@ -637,7 +649,7 @@ static void d3d9_capture(IDirect3DDevice9 *device,
static int present_recurse = 0;
static inline void present_begin(IDirect3DDevice9 *device,
IDirect3DSurface9 *&backbuffer)
IDirect3DSurface9 *&backbuffer)
{
HRESULT hr;
@@ -645,7 +657,8 @@ static inline void present_begin(IDirect3DDevice9 *device,
hr = get_backbuffer(device, &backbuffer);
if (FAILED(hr)) {
hlog_hr("d3d9_shmem_capture: Failed to get "
"backbuffer", hr);
"backbuffer",
hr);
}
if (!global_hook_info->capture_overlay) {
@@ -657,7 +670,7 @@ static inline void present_begin(IDirect3DDevice9 *device,
}
static inline void present_end(IDirect3DDevice9 *device,
IDirect3DSurface9 *backbuffer)
IDirect3DSurface9 *backbuffer)
{
present_recurse--;
@@ -676,8 +689,10 @@ static bool hooked_reset = false;
static void setup_reset_hooks(IDirect3DDevice9 *device);
static HRESULT STDMETHODCALLTYPE hook_present(IDirect3DDevice9 *device,
CONST RECT *src_rect, CONST RECT *dst_rect,
HWND override_window, CONST RGNDATA *dirty_region)
CONST RECT *src_rect,
CONST RECT *dst_rect,
HWND override_window,
CONST RGNDATA *dirty_region)
{
IDirect3DSurface9 *backbuffer = nullptr;
HRESULT hr;
@@ -697,9 +712,9 @@ static HRESULT STDMETHODCALLTYPE hook_present(IDirect3DDevice9 *device,
return hr;
}
static HRESULT STDMETHODCALLTYPE hook_present_ex(IDirect3DDevice9 *device,
CONST RECT *src_rect, CONST RECT *dst_rect,
HWND override_window, CONST RGNDATA *dirty_region, DWORD flags)
static HRESULT STDMETHODCALLTYPE hook_present_ex(
IDirect3DDevice9 *device, CONST RECT *src_rect, CONST RECT *dst_rect,
HWND override_window, CONST RGNDATA *dirty_region, DWORD flags)
{
IDirect3DSurface9 *backbuffer = nullptr;
HRESULT hr;
@@ -712,7 +727,7 @@ static HRESULT STDMETHODCALLTYPE hook_present_ex(IDirect3DDevice9 *device,
unhook(&present_ex);
present_ex_t call = (present_ex_t)present_ex.call_addr;
hr = call(device, src_rect, dst_rect, override_window, dirty_region,
flags);
flags);
rehook(&present_ex);
present_end(device, backbuffer);
@@ -720,9 +735,9 @@ static HRESULT STDMETHODCALLTYPE hook_present_ex(IDirect3DDevice9 *device,
return hr;
}
static HRESULT STDMETHODCALLTYPE hook_present_swap(IDirect3DSwapChain9 *swap,
CONST RECT *src_rect, CONST RECT *dst_rect,
HWND override_window, CONST RGNDATA *dirty_region, DWORD flags)
static HRESULT STDMETHODCALLTYPE hook_present_swap(
IDirect3DSwapChain9 *swap, CONST RECT *src_rect, CONST RECT *dst_rect,
HWND override_window, CONST RGNDATA *dirty_region, DWORD flags)
{
IDirect3DSurface9 *backbuffer = nullptr;
IDirect3DDevice9 *device = nullptr;
@@ -745,7 +760,7 @@ static HRESULT STDMETHODCALLTYPE hook_present_swap(IDirect3DSwapChain9 *swap,
unhook(&present_swap);
present_swap_t call = (present_swap_t)present_swap.call_addr;
hr = call(swap, src_rect, dst_rect, override_window, dirty_region,
flags);
flags);
rehook(&present_swap);
if (device)
@@ -755,7 +770,7 @@ static HRESULT STDMETHODCALLTYPE hook_present_swap(IDirect3DSwapChain9 *swap,
}
static HRESULT STDMETHODCALLTYPE hook_reset(IDirect3DDevice9 *device,
D3DPRESENT_PARAMETERS *params)
D3DPRESENT_PARAMETERS *params)
{
HRESULT hr;
@@ -771,7 +786,8 @@ static HRESULT STDMETHODCALLTYPE hook_reset(IDirect3DDevice9 *device,
}
static HRESULT STDMETHODCALLTYPE hook_reset_ex(IDirect3DDevice9 *device,
D3DPRESENT_PARAMETERS *params, D3DDISPLAYMODEEX *dmex)
D3DPRESENT_PARAMETERS *params,
D3DDISPLAYMODEEX *dmex)
{
HRESULT hr;
@@ -789,18 +805,18 @@ static HRESULT STDMETHODCALLTYPE hook_reset_ex(IDirect3DDevice9 *device,
static void setup_reset_hooks(IDirect3DDevice9 *device)
{
IDirect3DDevice9Ex *d3d9ex = nullptr;
uintptr_t *vtable = *(uintptr_t**)device;
uintptr_t *vtable = *(uintptr_t **)device;
HRESULT hr;
hook_init(&reset, (void*)vtable[16], (void*)hook_reset,
"IDirect3DDevice9::Reset");
hook_init(&reset, (void *)vtable[16], (void *)hook_reset,
"IDirect3DDevice9::Reset");
rehook(&reset);
hr = device->QueryInterface(__uuidof(IDirect3DDevice9Ex),
(void**)&d3d9ex);
(void **)&d3d9ex);
if (SUCCEEDED(hr)) {
hook_init(&reset_ex, (void*)vtable[132], (void*)hook_reset_ex,
"IDirect3DDevice9Ex::ResetEx");
hook_init(&reset_ex, (void *)vtable[132], (void *)hook_reset_ex,
"IDirect3DDevice9Ex::ResetEx");
rehook(&reset_ex);
d3d9ex->Release();
@@ -809,12 +825,11 @@ static void setup_reset_hooks(IDirect3DDevice9 *device)
hooked_reset = true;
}
typedef HRESULT (WINAPI *d3d9create_ex_t)(UINT, IDirect3D9Ex**);
typedef HRESULT(WINAPI *d3d9create_ex_t)(UINT, IDirect3D9Ex **);
static bool manually_get_d3d9_addrs(HMODULE d3d9_module,
void **present_addr,
void **present_ex_addr,
void **present_swap_addr)
static bool manually_get_d3d9_addrs(HMODULE d3d9_module, void **present_addr,
void **present_ex_addr,
void **present_swap_addr)
{
d3d9create_ex_t create_ex;
D3DPRESENT_PARAMETERS pp;
@@ -826,7 +841,7 @@ static bool manually_get_d3d9_addrs(HMODULE d3d9_module,
hlog("D3D9 values invalid, manually obtaining");
create_ex = (d3d9create_ex_t)GetProcAddress(d3d9_module,
"Direct3DCreate9Ex");
"Direct3DCreate9Ex");
if (!create_ex) {
hlog("Failed to load Direct3DCreate9Ex");
return false;
@@ -837,30 +852,30 @@ static bool manually_get_d3d9_addrs(HMODULE d3d9_module,
}
memset(&pp, 0, sizeof(pp));
pp.Windowed = 1;
pp.SwapEffect = D3DSWAPEFFECT_FLIP;
pp.BackBufferFormat = D3DFMT_A8R8G8B8;
pp.BackBufferCount = 1;
pp.hDeviceWindow = (HWND)dummy_window;
pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
pp.Windowed = 1;
pp.SwapEffect = D3DSWAPEFFECT_FLIP;
pp.BackBufferFormat = D3DFMT_A8R8G8B8;
pp.BackBufferCount = 1;
pp.hDeviceWindow = (HWND)dummy_window;
pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
hr = d3d9ex->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
dummy_window,
D3DCREATE_HARDWARE_VERTEXPROCESSING |
D3DCREATE_NOWINDOWCHANGES, &pp, NULL, &device);
hr = d3d9ex->CreateDeviceEx(
D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, dummy_window,
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_NOWINDOWCHANGES,
&pp, NULL, &device);
d3d9ex->Release();
if (SUCCEEDED(hr)) {
uintptr_t *vtable = *(uintptr_t**)device;
uintptr_t *vtable = *(uintptr_t **)device;
IDirect3DSwapChain9 *swap;
*present_addr = (void*)vtable[17];
*present_ex_addr = (void*)vtable[121];
*present_addr = (void *)vtable[17];
*present_ex_addr = (void *)vtable[121];
hr = device->GetSwapChain(0, &swap);
if (SUCCEEDED(hr)) {
vtable = *(uintptr_t**)swap;
*present_swap_addr = (void*)vtable[3];
vtable = *(uintptr_t **)swap;
*present_swap_addr = (void *)vtable[3];
swap->Release();
}
@@ -888,25 +903,25 @@ bool hook_d3d9(void)
d3d9_size = module_size(d3d9_module);
if (global_hook_info->offsets.d3d9.present < d3d9_size &&
global_hook_info->offsets.d3d9.present_ex < d3d9_size &&
if (global_hook_info->offsets.d3d9.present < d3d9_size &&
global_hook_info->offsets.d3d9.present_ex < d3d9_size &&
global_hook_info->offsets.d3d9.present_swap < d3d9_size) {
present_addr = get_offset_addr(d3d9_module,
global_hook_info->offsets.d3d9.present);
present_ex_addr = get_offset_addr(d3d9_module,
global_hook_info->offsets.d3d9.present_ex);
present_swap_addr = get_offset_addr(d3d9_module,
global_hook_info->offsets.d3d9.present_swap);
present_addr = get_offset_addr(
d3d9_module, global_hook_info->offsets.d3d9.present);
present_ex_addr = get_offset_addr(
d3d9_module, global_hook_info->offsets.d3d9.present_ex);
present_swap_addr = get_offset_addr(
d3d9_module,
global_hook_info->offsets.d3d9.present_swap);
} else {
if (!dummy_window) {
return false;
}
if (!manually_get_d3d9_addrs(d3d9_module,
&present_addr,
&present_ex_addr,
&present_swap_addr)) {
if (!manually_get_d3d9_addrs(d3d9_module, &present_addr,
&present_ex_addr,
&present_swap_addr)) {
hlog("Failed to get D3D9 values");
return true;
}
@@ -919,20 +934,18 @@ bool hook_d3d9(void)
if (present_swap_addr) {
hook_init(&present_swap, present_swap_addr,
(void*)hook_present_swap,
"IDirect3DSwapChain9::Present");
(void *)hook_present_swap,
"IDirect3DSwapChain9::Present");
rehook(&present_swap);
}
if (present_ex_addr) {
hook_init(&present_ex, present_ex_addr,
(void*)hook_present_ex,
"IDirect3DDevice9Ex::PresentEx");
hook_init(&present_ex, present_ex_addr, (void *)hook_present_ex,
"IDirect3DDevice9Ex::PresentEx");
rehook(&present_ex);
}
if (present_addr) {
hook_init(&present, present_addr,
(void*)hook_present,
"IDirect3DDevice9::Present");
hook_init(&present, present_addr, (void *)hook_present,
"IDirect3DDevice9::Present");
rehook(&present);
}

View File

@@ -12,7 +12,7 @@
#define __try
#endif
#ifndef __except
#define __except(x) if (0)
#define __except (x) if (0)
#endif
#endif
#endif
@@ -36,7 +36,7 @@ static inline int safe_memcmp(const void *p1, const void *p2, size_t size)
#ifdef NO_SEH_MINGW
__except1
#else
__except(EXCEPTION_EXECUTE_HANDLER)
__except (EXCEPTION_EXECUTE_HANDLER)
#endif
{
return -1;
@@ -49,7 +49,10 @@ struct patch_info {
const BYTE *data;
};
#define NEW_PATCH(x) {sizeof(x), (x)}
#define NEW_PATCH(x) \
{ \
sizeof(x), (x) \
}
#define MAX_PATCH_SIZE 2
static const BYTE force_jump[] = {0xEB};
@@ -57,125 +60,137 @@ static const BYTE ignore_jump[] = {0x90, 0x90};
#ifdef _WIN64
#define NUM_VERS (16)
#define CMP_SIZE (13)
#define NUM_VERS (16)
#define CMP_SIZE (13)
static const uintptr_t patch_offset[NUM_VERS] = {
0x54FE6, //win7 - 6.1.7600.16385
0x55095, //win7 - 6.1.7601.16562
0x550C5, //win7 - 6.1.7601.17514
0x6E2FC, //win10 - 10.0.14393.0
0x6FE18, //win10 - 10.0.10240.16412
0x70050, //win10 - 10.0.10240.16384
0x703F8, //win10 - 10.0.10162.0
0x7E48C, //win10 - 10.0.10586.494
0x7E49C, //win10 - 10.0.10586.0
0x8BDB5, //win8.1 - 6.3.9431.00000
0x8E635, //win8.1 - 6.3.9600.17415
0x90352, //win8.1 - 6.3.9600.17085
0x9038A, //win8.1 - 6.3.9600.17095
0x93AFA, //win8.1 - 6.3.9600.16384
0x93B8A, //win8.1 - 6.3.9600.16404
0x1841E5 //win8 - 6.2.9200.16384
0x54FE6, //win7 - 6.1.7600.16385
0x55095, //win7 - 6.1.7601.16562
0x550C5, //win7 - 6.1.7601.17514
0x6E2FC, //win10 - 10.0.14393.0
0x6FE18, //win10 - 10.0.10240.16412
0x70050, //win10 - 10.0.10240.16384
0x703F8, //win10 - 10.0.10162.0
0x7E48C, //win10 - 10.0.10586.494
0x7E49C, //win10 - 10.0.10586.0
0x8BDB5, //win8.1 - 6.3.9431.00000
0x8E635, //win8.1 - 6.3.9600.17415
0x90352, //win8.1 - 6.3.9600.17085
0x9038A, //win8.1 - 6.3.9600.17095
0x93AFA, //win8.1 - 6.3.9600.16384
0x93B8A, //win8.1 - 6.3.9600.16404
0x1841E5 //win8 - 6.2.9200.16384
};
static const uint8_t patch_cmp[NUM_VERS][CMP_SIZE] = {
{0x48, 0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0x98, 0x68, 0x50, 0x00, 0x00},
{0x48, 0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0x98, 0x68, 0x50, 0x00, 0x00},
{0x48, 0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0x98, 0x68, 0x50, 0x00, 0x00},
{0x8b, 0x81, 0x18, 0x3e, 0x00, 0x00, 0x44, 0x39, 0x98, 0x90, 0x51, 0x00, 0x00},
{0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0x98, 0x88, 0x51, 0x00, 0x00},
{0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0x98, 0x88, 0x51, 0x00, 0x00},
{0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0x98, 0x88, 0x51, 0x00, 0x00},
{0x8b, 0x81, 0x18, 0x3e, 0x00, 0x00, 0x44, 0x39, 0x98, 0x88, 0x51, 0x00, 0x00},
{0x8b, 0x81, 0x18, 0x3e, 0x00, 0x00, 0x44, 0x39, 0x98, 0x88, 0x51, 0x00, 0x00},
{0x48, 0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0xB0, 0x28, 0x51, 0x00, 0x00},
{0x48, 0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0xA8, 0x28, 0x51, 0x00, 0x00},
{0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0xA0, 0x28, 0x51, 0x00, 0x00},
{0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0xA0, 0x28, 0x51, 0x00, 0x00},
{0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0xA0, 0x28, 0x51, 0x00, 0x00},
{0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0xA0, 0x28, 0x51, 0x00, 0x00},
{0x49, 0x8b, 0x85, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0x88, 0xc8, 0x50, 0x00, 0x00},
{0x48, 0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0x98, 0x68, 0x50, 0x00,
0x00},
{0x48, 0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0x98, 0x68, 0x50, 0x00,
0x00},
{0x48, 0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0x98, 0x68, 0x50, 0x00,
0x00},
{0x8b, 0x81, 0x18, 0x3e, 0x00, 0x00, 0x44, 0x39, 0x98, 0x90, 0x51, 0x00,
0x00},
{0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0x98, 0x88, 0x51, 0x00,
0x00},
{0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0x98, 0x88, 0x51, 0x00,
0x00},
{0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0x98, 0x88, 0x51, 0x00,
0x00},
{0x8b, 0x81, 0x18, 0x3e, 0x00, 0x00, 0x44, 0x39, 0x98, 0x88, 0x51, 0x00,
0x00},
{0x8b, 0x81, 0x18, 0x3e, 0x00, 0x00, 0x44, 0x39, 0x98, 0x88, 0x51, 0x00,
0x00},
{0x48, 0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0xB0, 0x28, 0x51, 0x00,
0x00},
{0x48, 0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0xA8, 0x28, 0x51, 0x00,
0x00},
{0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0xA0, 0x28, 0x51, 0x00,
0x00},
{0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0xA0, 0x28, 0x51, 0x00,
0x00},
{0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0xA0, 0x28, 0x51, 0x00,
0x00},
{0x8b, 0x81, 0xb8, 0x3d, 0x00, 0x00, 0x44, 0x39, 0xA0, 0x28, 0x51, 0x00,
0x00},
{0x49, 0x8b, 0x85, 0xb8, 0x3d, 0x00, 0x00, 0x39, 0x88, 0xc8, 0x50, 0x00,
0x00},
};
static const struct patch_info patch[NUM_VERS] = {
NEW_PATCH(force_jump),
NEW_PATCH(force_jump),
NEW_PATCH(force_jump),
NEW_PATCH(force_jump),
NEW_PATCH(force_jump),
NEW_PATCH(force_jump),
NEW_PATCH(force_jump),
NEW_PATCH(force_jump),
NEW_PATCH(force_jump),
NEW_PATCH(ignore_jump),
NEW_PATCH(ignore_jump),
NEW_PATCH(ignore_jump),
NEW_PATCH(ignore_jump),
NEW_PATCH(ignore_jump),
NEW_PATCH(ignore_jump),
NEW_PATCH(force_jump), NEW_PATCH(force_jump), NEW_PATCH(force_jump),
NEW_PATCH(force_jump), NEW_PATCH(force_jump), NEW_PATCH(force_jump),
NEW_PATCH(force_jump), NEW_PATCH(force_jump), NEW_PATCH(force_jump),
NEW_PATCH(ignore_jump), NEW_PATCH(ignore_jump), NEW_PATCH(ignore_jump),
NEW_PATCH(ignore_jump), NEW_PATCH(ignore_jump), NEW_PATCH(ignore_jump),
NEW_PATCH(ignore_jump),
};
#else
#define NUM_VERS (16)
#define CMP_SIZE (12)
#define NUM_VERS (16)
#define CMP_SIZE (12)
static const uintptr_t patch_offset[NUM_VERS] = {
0x79AA6, //win7 - 6.1.7601.16562
0x79C9E, //win7 - 6.1.7600.16385
0x79D96, //win7 - 6.1.7601.17514
0x7F9BD, //win8.1 - 6.3.9431.00000
0x8A3F4, //win8.1 - 6.3.9600.16404
0x8B15F, //win10 - 10.0.10240.16384
0x8B19F, //win10 - 10.0.10162.0
0x8B83F, //win10 - 10.0.10240.16412
0x8E9F7, //win8.1 - 6.3.9600.17095
0x8F00F, //win8.1 - 6.3.9600.17085
0x8FBB1, //win8.1 - 6.3.9600.16384
0x90264, //win8.1 - 6.3.9600.17415
0x90C3A, //win10 - 10.0.10586.494
0x90C57, //win10 - 10.0.10586.0
0x96673, //win10 - 10.0.14393.0
0x166A08 //win8 - 6.2.9200.16384
0x79AA6, //win7 - 6.1.7601.16562
0x79C9E, //win7 - 6.1.7600.16385
0x79D96, //win7 - 6.1.7601.17514
0x7F9BD, //win8.1 - 6.3.9431.00000
0x8A3F4, //win8.1 - 6.3.9600.16404
0x8B15F, //win10 - 10.0.10240.16384
0x8B19F, //win10 - 10.0.10162.0
0x8B83F, //win10 - 10.0.10240.16412
0x8E9F7, //win8.1 - 6.3.9600.17095
0x8F00F, //win8.1 - 6.3.9600.17085
0x8FBB1, //win8.1 - 6.3.9600.16384
0x90264, //win8.1 - 6.3.9600.17415
0x90C3A, //win10 - 10.0.10586.494
0x90C57, //win10 - 10.0.10586.0
0x96673, //win10 - 10.0.14393.0
0x166A08 //win8 - 6.2.9200.16384
};
static const uint8_t patch_cmp[NUM_VERS][CMP_SIZE] = {
{0x8b, 0x89, 0xe8, 0x29, 0x00, 0x00, 0x39, 0xb9, 0x80, 0x4b, 0x00, 0x00},
{0x8b, 0x89, 0xe8, 0x29, 0x00, 0x00, 0x39, 0xb9, 0x80, 0x4b, 0x00, 0x00},
{0x8b, 0x89, 0xe8, 0x29, 0x00, 0x00, 0x39, 0xb9, 0x80, 0x4b, 0x00, 0x00},
{0x8b, 0x80, 0xe8, 0x29, 0x00, 0x00, 0x39, 0xb0, 0x40, 0x4c, 0x00, 0x00},
{0x80, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0x40, 0x4c, 0x00, 0x00, 0x00},
{0x81, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0xa0, 0x4c, 0x00, 0x00, 0x00},
{0x81, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0xa0, 0x4c, 0x00, 0x00, 0x00},
{0x81, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0xa0, 0x4c, 0x00, 0x00, 0x00},
{0x80, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0x40, 0x4c, 0x00, 0x00, 0x00},
{0x80, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0x40, 0x4c, 0x00, 0x00, 0x00},
{0x80, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0x40, 0x4c, 0x00, 0x00, 0x00},
{0x87, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0x40, 0x4c, 0x00, 0x00, 0x00},
{0x81, 0x18, 0x2a, 0x00, 0x00, 0x83, 0xb8, 0xa0, 0x4c, 0x00, 0x00, 0x00},
{0x81, 0x18, 0x2a, 0x00, 0x00, 0x83, 0xb8, 0xa0, 0x4c, 0x00, 0x00, 0x00},
{0x81, 0x18, 0x2a, 0x00, 0x00, 0x83, 0xb8, 0xa8, 0x4c, 0x00, 0x00, 0x00},
{0x8b, 0x80, 0xe8, 0x29, 0x00, 0x00, 0x39, 0x90, 0xb0, 0x4b, 0x00, 0x00},
{0x8b, 0x89, 0xe8, 0x29, 0x00, 0x00, 0x39, 0xb9, 0x80, 0x4b, 0x00,
0x00},
{0x8b, 0x89, 0xe8, 0x29, 0x00, 0x00, 0x39, 0xb9, 0x80, 0x4b, 0x00,
0x00},
{0x8b, 0x89, 0xe8, 0x29, 0x00, 0x00, 0x39, 0xb9, 0x80, 0x4b, 0x00,
0x00},
{0x8b, 0x80, 0xe8, 0x29, 0x00, 0x00, 0x39, 0xb0, 0x40, 0x4c, 0x00,
0x00},
{0x80, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0x40, 0x4c, 0x00, 0x00,
0x00},
{0x81, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0xa0, 0x4c, 0x00, 0x00,
0x00},
{0x81, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0xa0, 0x4c, 0x00, 0x00,
0x00},
{0x81, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0xa0, 0x4c, 0x00, 0x00,
0x00},
{0x80, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0x40, 0x4c, 0x00, 0x00,
0x00},
{0x80, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0x40, 0x4c, 0x00, 0x00,
0x00},
{0x80, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0x40, 0x4c, 0x00, 0x00,
0x00},
{0x87, 0xe8, 0x29, 0x00, 0x00, 0x83, 0xb8, 0x40, 0x4c, 0x00, 0x00,
0x00},
{0x81, 0x18, 0x2a, 0x00, 0x00, 0x83, 0xb8, 0xa0, 0x4c, 0x00, 0x00,
0x00},
{0x81, 0x18, 0x2a, 0x00, 0x00, 0x83, 0xb8, 0xa0, 0x4c, 0x00, 0x00,
0x00},
{0x81, 0x18, 0x2a, 0x00, 0x00, 0x83, 0xb8, 0xa8, 0x4c, 0x00, 0x00,
0x00},
{0x8b, 0x80, 0xe8, 0x29, 0x00, 0x00, 0x39, 0x90, 0xb0, 0x4b, 0x00,
0x00},
};
static const struct patch_info patch[NUM_VERS] = {
NEW_PATCH(force_jump),
NEW_PATCH(force_jump),
NEW_PATCH(force_jump),
NEW_PATCH(force_jump),
NEW_PATCH(force_jump),
NEW_PATCH(ignore_jump),
NEW_PATCH(ignore_jump),
NEW_PATCH(ignore_jump),
NEW_PATCH(force_jump),
NEW_PATCH(force_jump),
NEW_PATCH(force_jump),
NEW_PATCH(ignore_jump),
NEW_PATCH(ignore_jump),
NEW_PATCH(ignore_jump),
NEW_PATCH(ignore_jump),
NEW_PATCH(force_jump), NEW_PATCH(force_jump), NEW_PATCH(force_jump),
NEW_PATCH(force_jump), NEW_PATCH(force_jump), NEW_PATCH(ignore_jump),
NEW_PATCH(ignore_jump), NEW_PATCH(ignore_jump), NEW_PATCH(force_jump),
NEW_PATCH(force_jump), NEW_PATCH(force_jump), NEW_PATCH(ignore_jump),
NEW_PATCH(ignore_jump), NEW_PATCH(ignore_jump), NEW_PATCH(ignore_jump),
NEW_PATCH(force_jump),
};
@@ -183,10 +198,10 @@ static const struct patch_info patch[NUM_VERS] = {
static inline int get_d3d9_patch(HMODULE d3d9)
{
uint8_t *addr = (uint8_t*)d3d9;
uint8_t *addr = (uint8_t *)d3d9;
for (int i = 0; i < NUM_VERS; i++) {
int ret = safe_memcmp(addr + patch_offset[i], patch_cmp[i],
CMP_SIZE);
CMP_SIZE);
if (ret == 0)
return i;
}
@@ -199,6 +214,6 @@ static inline uint8_t *get_d3d9_patch_addr(HMODULE d3d9, int patch)
if (patch == -1)
return nullptr;
uint8_t *addr = (uint8_t*)d3d9;
uint8_t *addr = (uint8_t *)d3d9;
return addr + patch_offset[patch] + CMP_SIZE;
}

View File

@@ -11,11 +11,12 @@
#include <d3d12.h>
#endif
typedef HRESULT (STDMETHODCALLTYPE *resize_buffers_t)(IDXGISwapChain*, UINT,
UINT, UINT, DXGI_FORMAT, UINT);
typedef HRESULT (STDMETHODCALLTYPE *present_t)(IDXGISwapChain*, UINT, UINT);
typedef HRESULT (STDMETHODCALLTYPE *present1_t)(IDXGISwapChain1*, UINT, UINT,
const DXGI_PRESENT_PARAMETERS *);
typedef HRESULT(STDMETHODCALLTYPE *resize_buffers_t)(IDXGISwapChain *, UINT,
UINT, UINT, DXGI_FORMAT,
UINT);
typedef HRESULT(STDMETHODCALLTYPE *present_t)(IDXGISwapChain *, UINT, UINT);
typedef HRESULT(STDMETHODCALLTYPE *present1_t)(IDXGISwapChain1 *, UINT, UINT,
const DXGI_PRESENT_PARAMETERS *);
static struct func_hook resize_buffers;
static struct func_hook present;
@@ -23,7 +24,7 @@ static struct func_hook present1;
struct dxgi_swap_data {
IDXGISwapChain *swap;
void (*capture)(void*, void*, bool);
void (*capture)(void *, void *, bool);
void (*free)(void);
};
@@ -34,9 +35,9 @@ static bool setup_dxgi(IDXGISwapChain *swap)
IUnknown *device;
HRESULT hr;
hr = swap->GetDevice(__uuidof(ID3D11Device), (void**)&device);
hr = swap->GetDevice(__uuidof(ID3D11Device), (void **)&device);
if (SUCCEEDED(hr)) {
ID3D11Device *d3d11 = reinterpret_cast<ID3D11Device*>(device);
ID3D11Device *d3d11 = reinterpret_cast<ID3D11Device *>(device);
D3D_FEATURE_LEVEL level = d3d11->GetFeatureLevel();
device->Release();
@@ -48,7 +49,7 @@ static bool setup_dxgi(IDXGISwapChain *swap)
}
}
hr = swap->GetDevice(__uuidof(ID3D10Device), (void**)&device);
hr = swap->GetDevice(__uuidof(ID3D10Device), (void **)&device);
if (SUCCEEDED(hr)) {
data.swap = swap;
data.capture = d3d10_capture;
@@ -57,7 +58,7 @@ static bool setup_dxgi(IDXGISwapChain *swap)
return true;
}
hr = swap->GetDevice(__uuidof(ID3D11Device), (void**)&device);
hr = swap->GetDevice(__uuidof(ID3D11Device), (void **)&device);
if (SUCCEEDED(hr)) {
data.swap = swap;
data.capture = d3d11_capture;
@@ -67,7 +68,7 @@ static bool setup_dxgi(IDXGISwapChain *swap)
}
#if COMPILE_D3D12_HOOK
hr = swap->GetDevice(__uuidof(ID3D12Device), (void**)&device);
hr = swap->GetDevice(__uuidof(ID3D12Device), (void **)&device);
if (SUCCEEDED(hr)) {
data.swap = swap;
data.capture = d3d12_capture;
@@ -83,8 +84,10 @@ static bool setup_dxgi(IDXGISwapChain *swap)
static bool resize_buffers_called = false;
static HRESULT STDMETHODCALLTYPE hook_resize_buffers(IDXGISwapChain *swap,
UINT buffer_count, UINT width, UINT height, DXGI_FORMAT format,
UINT flags)
UINT buffer_count,
UINT width, UINT height,
DXGI_FORMAT format,
UINT flags)
{
HRESULT hr;
@@ -110,7 +113,7 @@ static inline IUnknown *get_dxgi_backbuffer(IDXGISwapChain *swap)
IDXGIResource *res = nullptr;
HRESULT hr;
hr = swap->GetBuffer(0, __uuidof(IUnknown), (void**)&res);
hr = swap->GetBuffer(0, __uuidof(IUnknown), (void **)&res);
if (FAILED(hr))
hlog_hr("get_dxgi_backbuffer: GetBuffer failed", hr);
@@ -118,7 +121,7 @@ static inline IUnknown *get_dxgi_backbuffer(IDXGISwapChain *swap)
}
static HRESULT STDMETHODCALLTYPE hook_present(IDXGISwapChain *swap,
UINT sync_interval, UINT flags)
UINT sync_interval, UINT flags)
{
IUnknown *backbuffer = nullptr;
bool capture_overlay = global_hook_info->capture_overlay;
@@ -168,9 +171,9 @@ static HRESULT STDMETHODCALLTYPE hook_present(IDXGISwapChain *swap,
return hr;
}
static HRESULT STDMETHODCALLTYPE hook_present1(IDXGISwapChain1 *swap,
UINT sync_interval, UINT flags,
const DXGI_PRESENT_PARAMETERS *params)
static HRESULT STDMETHODCALLTYPE
hook_present1(IDXGISwapChain1 *swap, UINT sync_interval, UINT flags,
const DXGI_PRESENT_PARAMETERS *params)
{
IUnknown *backbuffer = nullptr;
bool capture_overlay = global_hook_info->capture_overlay;
@@ -227,7 +230,7 @@ static pD3DCompile get_compiler(void)
HMODULE module = LoadLibraryA(d3dcompiler);
if (module) {
compile = (pD3DCompile)GetProcAddress(module,
"D3DCompile");
"D3DCompile");
if (compile) {
break;
}
@@ -267,9 +270,8 @@ bool hook_dxgi(void)
/* ---------------------- */
hr = compile(vertex_shader_string, sizeof(vertex_shader_string),
"vertex_shader_string", nullptr, nullptr, "main",
"vs_4_0", D3D10_SHADER_OPTIMIZATION_LEVEL1, 0, &blob,
nullptr);
"vertex_shader_string", nullptr, nullptr, "main", "vs_4_0",
D3D10_SHADER_OPTIMIZATION_LEVEL1, 0, &blob, nullptr);
if (FAILED(hr)) {
hlog_hr("hook_dxgi: failed to compile vertex shader", hr);
return true;
@@ -277,15 +279,14 @@ bool hook_dxgi(void)
vertex_shader_size = (size_t)blob->GetBufferSize();
memcpy(vertex_shader_data, blob->GetBufferPointer(),
blob->GetBufferSize());
blob->GetBufferSize());
blob->Release();
/* ---------------------- */
hr = compile(pixel_shader_string, sizeof(pixel_shader_string),
"pixel_shader_string", nullptr, nullptr, "main",
"ps_4_0", D3D10_SHADER_OPTIMIZATION_LEVEL1, 0, &blob,
nullptr);
"pixel_shader_string", nullptr, nullptr, "main", "ps_4_0",
D3D10_SHADER_OPTIMIZATION_LEVEL1, 0, &blob, nullptr);
if (FAILED(hr)) {
hlog_hr("hook_dxgi: failed to compile pixel shader", hr);
return true;
@@ -293,26 +294,26 @@ bool hook_dxgi(void)
pixel_shader_size = (size_t)blob->GetBufferSize();
memcpy(pixel_shader_data, blob->GetBufferPointer(),
blob->GetBufferSize());
blob->GetBufferSize());
blob->Release();
/* ---------------------- */
present_addr = get_offset_addr(dxgi_module,
global_hook_info->offsets.dxgi.present);
global_hook_info->offsets.dxgi.present);
resize_addr = get_offset_addr(dxgi_module,
global_hook_info->offsets.dxgi.resize);
global_hook_info->offsets.dxgi.resize);
if (global_hook_info->offsets.dxgi.present1)
present1_addr = get_offset_addr(dxgi_module,
global_hook_info->offsets.dxgi.present1);
present1_addr = get_offset_addr(
dxgi_module, global_hook_info->offsets.dxgi.present1);
hook_init(&present, present_addr, (void*)hook_present,
"IDXGISwapChain::Present");
hook_init(&resize_buffers, resize_addr, (void*)hook_resize_buffers,
"IDXGISwapChain::ResizeBuffers");
hook_init(&present, present_addr, (void *)hook_present,
"IDXGISwapChain::Present");
hook_init(&resize_buffers, resize_addr, (void *)hook_resize_buffers,
"IDXGISwapChain::ResizeBuffers");
if (present1_addr)
hook_init(&present1, present1_addr, (void*)hook_present1,
"IDXGISwapChain1::Present1");
hook_init(&present1, present1_addr, (void *)hook_present1,
"IDXGISwapChain1::Present1");
rehook(&resize_buffers);
rehook(&present);

View File

@@ -3,12 +3,11 @@
static inline DXGI_FORMAT fix_dxgi_format(DXGI_FORMAT format)
{
switch ((unsigned long)format) {
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
return DXGI_FORMAT_B8G8R8A8_UNORM;
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
return DXGI_FORMAT_R8G8B8A8_UNORM;
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
return DXGI_FORMAT_B8G8R8A8_UNORM;
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
return DXGI_FORMAT_R8G8B8A8_UNORM;
}
return format;
}

View File

@@ -15,11 +15,15 @@
#define DUMMY_WINDOW_CLASS_NAME L"graphics_hook_gl_dummy_window"
/* clang-format off */
static const GUID GUID_IDXGIFactory1 =
{0x770aae78, 0xf26f, 0x4dba, {0xa8, 0x29, 0x25, 0x3c, 0x83, 0xd1, 0xb3, 0x87}};
static const GUID GUID_IDXGIResource =
{0x035f3ab4, 0x482e, 0x4e50, {0xb4, 0x1f, 0x8a, 0x7f, 0x8b, 0xd8, 0x96, 0x0b}};
/* clang-format on */
static struct func_hook swap_buffers;
static struct func_hook wgl_swap_layer_buffers;
static struct func_hook wgl_swap_buffers;
@@ -28,40 +32,40 @@ static struct func_hook wgl_delete_context;
static bool darkest_dungeon_fix = false;
struct gl_data {
HDC hdc;
uint32_t base_cx;
uint32_t base_cy;
uint32_t cx;
uint32_t cy;
DXGI_FORMAT format;
GLuint fbo;
bool using_shtex;
bool using_scale;
bool shmem_fallback;
HDC hdc;
uint32_t base_cx;
uint32_t base_cy;
uint32_t cx;
uint32_t cy;
DXGI_FORMAT format;
GLuint fbo;
bool using_shtex;
bool using_scale;
bool shmem_fallback;
union {
/* shared texture */
struct {
struct shtex_data *shtex_info;
ID3D11Device *d3d11_device;
ID3D11DeviceContext *d3d11_context;
ID3D11Texture2D *d3d11_tex;
IDXGISwapChain *dxgi_swap;
HANDLE gl_device;
HANDLE gl_dxobj;
HANDLE handle;
HWND hwnd;
GLuint texture;
struct shtex_data *shtex_info;
ID3D11Device *d3d11_device;
ID3D11DeviceContext *d3d11_context;
ID3D11Texture2D *d3d11_tex;
IDXGISwapChain *dxgi_swap;
HANDLE gl_device;
HANDLE gl_dxobj;
HANDLE handle;
HWND hwnd;
GLuint texture;
};
/* shared memory */
struct {
struct shmem_data *shmem_info;
int cur_tex;
int copy_wait;
GLuint pbos[NUM_BUFFERS];
GLuint textures[NUM_BUFFERS];
bool texture_ready[NUM_BUFFERS];
bool texture_mapped[NUM_BUFFERS];
struct shmem_data *shmem_info;
int cur_tex;
int copy_wait;
GLuint pbos[NUM_BUFFERS];
GLuint textures[NUM_BUFFERS];
bool texture_ready[NUM_BUFFERS];
bool texture_mapped[NUM_BUFFERS];
};
};
};
@@ -88,7 +92,7 @@ static void gl_free(void)
if (data.using_shtex) {
if (data.gl_dxobj)
jimglDXUnregisterObjectNV(data.gl_device,
data.gl_dxobj);
data.gl_dxobj);
if (data.gl_device)
jimglDXCloseDeviceNV(data.gl_device);
if (data.texture)
@@ -108,7 +112,7 @@ static void gl_free(void)
if (data.pbos[i]) {
if (data.texture_mapped[i]) {
glBindBuffer(GL_PIXEL_PACK_BUFFER,
data.pbos[i]);
data.pbos[i]);
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
}
@@ -133,12 +137,12 @@ static void gl_free(void)
static inline void *base_get_proc(const char *name)
{
return (void*)GetProcAddress(gl, name);
return (void *)GetProcAddress(gl, name);
}
static inline void *wgl_get_proc(const char *name)
{
return (void*)jimglGetProcAddress(name);
return (void *)jimglGetProcAddress(name);
}
static inline void *get_proc(const char *name)
@@ -163,27 +167,23 @@ static void init_nv_functions(void)
jimglDXUnlockObjectsNV = get_proc("wglDXUnlockObjectsNV");
nv_capture_available =
!!jimglDXSetResourceShareHandleNV &&
!!jimglDXOpenDeviceNV &&
!!jimglDXCloseDeviceNV &&
!!jimglDXRegisterObjectNV &&
!!jimglDXUnregisterObjectNV &&
!!jimglDXObjectAccessNV &&
!!jimglDXLockObjectsNV &&
!!jimglDXUnlockObjectsNV;
!!jimglDXSetResourceShareHandleNV && !!jimglDXOpenDeviceNV &&
!!jimglDXCloseDeviceNV && !!jimglDXRegisterObjectNV &&
!!jimglDXUnregisterObjectNV && !!jimglDXObjectAccessNV &&
!!jimglDXLockObjectsNV && !!jimglDXUnlockObjectsNV;
if (nv_capture_available)
hlog("Shared-texture OpenGL capture available");
}
#define GET_PROC(cur_func, ptr, func) \
do { \
ptr = get_proc(#func); \
if (!ptr) { \
#define GET_PROC(cur_func, ptr, func) \
do { \
ptr = get_proc(#func); \
if (!ptr) { \
hlog("%s: failed to get function '%s'", #cur_func, \
#func); \
success = false; \
} \
#func); \
success = false; \
} \
} while (false)
static bool init_gl_functions(void)
@@ -199,7 +199,7 @@ static bool init_gl_functions(void)
GET_PROC(init_gl_functions, jimglMakeCurrent, wglMakeCurrent);
GET_PROC(init_gl_functions, jimglGetCurrentDC, wglGetCurrentDC);
GET_PROC(init_gl_functions, jimglGetCurrentContext,
wglGetCurrentContext);
wglGetCurrentContext);
GET_PROC(init_gl_functions, glTexImage2D, glTexImage2D);
GET_PROC(init_gl_functions, glReadBuffer, glReadBuffer);
GET_PROC(init_gl_functions, glGetTexImage, glGetTexImage);
@@ -220,7 +220,7 @@ static bool init_gl_functions(void)
GET_PROC(init_gl_functions, glBindFramebuffer, glBindFramebuffer);
GET_PROC(init_gl_functions, glBlitFramebuffer, glBlitFramebuffer);
GET_PROC(init_gl_functions, glFramebufferTexture2D,
glFramebufferTexture2D);
glFramebufferTexture2D);
init_nv_functions();
return success;
@@ -229,7 +229,7 @@ static bool init_gl_functions(void)
static void get_window_size(HDC hdc, uint32_t *cx, uint32_t *cy)
{
HWND hwnd = WindowFromDC(hdc);
RECT rc = {0};
RECT rc = {0};
if (darkest_dungeon_fix) {
*cx = 1920;
@@ -243,23 +243,22 @@ static void get_window_size(HDC hdc, uint32_t *cx, uint32_t *cy)
static inline bool gl_shtex_init_window(void)
{
data.hwnd = CreateWindowExW(0, DUMMY_WINDOW_CLASS_NAME,
L"Dummy GL window, ignore",
WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
0, 0, 2, 2, NULL, NULL, GetModuleHandle(NULL), NULL);
data.hwnd = CreateWindowExW(
0, DUMMY_WINDOW_CLASS_NAME, L"Dummy GL window, ignore",
WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, 2, 2, NULL,
NULL, GetModuleHandle(NULL), NULL);
if (!data.hwnd) {
hlog("gl_shtex_init_window: failed to create window: %d",
GetLastError());
GetLastError());
return false;
}
return true;
}
typedef HRESULT (WINAPI *create_dxgi_factory1_t)(REFIID, void **);
typedef HRESULT(WINAPI *create_dxgi_factory1_t)(REFIID, void **);
static const D3D_FEATURE_LEVEL feature_levels[] =
{
static const D3D_FEATURE_LEVEL feature_levels[] = {
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
@@ -276,37 +275,38 @@ static inline bool gl_shtex_init_d3d11(void)
HMODULE d3d11 = load_system_library("d3d11.dll");
if (!d3d11) {
hlog("gl_shtex_init_d3d11: failed to load D3D11.dll: %d",
GetLastError());
GetLastError());
return false;
}
HMODULE dxgi = load_system_library("dxgi.dll");
if (!dxgi) {
hlog("gl_shtex_init_d3d11: failed to load DXGI.dll: %d",
GetLastError());
GetLastError());
return false;
}
DXGI_SWAP_CHAIN_DESC desc = {0};
desc.BufferCount = 2;
desc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
desc.BufferDesc.Width = 2;
desc.BufferDesc.Height = 2;
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
desc.SampleDesc.Count = 1;
desc.Windowed = true;
desc.OutputWindow = data.hwnd;
DXGI_SWAP_CHAIN_DESC desc = {0};
desc.BufferCount = 2;
desc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
desc.BufferDesc.Width = 2;
desc.BufferDesc.Height = 2;
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
desc.SampleDesc.Count = 1;
desc.Windowed = true;
desc.OutputWindow = data.hwnd;
create_dxgi_factory1_t create_factory = (void*)GetProcAddress(dxgi,
"CreateDXGIFactory1");
create_dxgi_factory1_t create_factory =
(void *)GetProcAddress(dxgi, "CreateDXGIFactory1");
if (!create_factory) {
hlog("gl_shtex_init_d3d11: failed to load CreateDXGIFactory1 "
"procedure: %d", GetLastError());
"procedure: %d",
GetLastError());
return false;
}
PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN create = (void*)GetProcAddress(
d3d11, "D3D11CreateDeviceAndSwapChain");
PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN create =
(void *)GetProcAddress(d3d11, "D3D11CreateDeviceAndSwapChain");
if (!create) {
hlog("gl_shtex_init_d3d11: failed to load "
"D3D11CreateDeviceAndSwapChain procedure: %d",
@@ -314,13 +314,14 @@ static inline bool gl_shtex_init_d3d11(void)
return false;
}
hr = create_factory(&GUID_IDXGIFactory1, (void**)&factory);
hr = create_factory(&GUID_IDXGIFactory1, (void **)&factory);
if (FAILED(hr)) {
hlog_hr("gl_shtex_init_d3d11: failed to create factory", hr);
return false;
}
hr = IDXGIFactory1_EnumAdapters1(factory, 0, (IDXGIAdapter1**)&adapter);
hr = IDXGIFactory1_EnumAdapters1(factory, 0,
(IDXGIAdapter1 **)&adapter);
IDXGIFactory1_Release(factory);
if (FAILED(hr)) {
@@ -329,9 +330,9 @@ static inline bool gl_shtex_init_d3d11(void)
}
hr = create(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, feature_levels,
sizeof(feature_levels) / sizeof(D3D_FEATURE_LEVEL),
D3D11_SDK_VERSION, &desc, &data.dxgi_swap,
&data.d3d11_device, &level_used, &data.d3d11_context);
sizeof(feature_levels) / sizeof(D3D_FEATURE_LEVEL),
D3D11_SDK_VERSION, &desc, &data.dxgi_swap,
&data.d3d11_device, &level_used, &data.d3d11_context);
IDXGIAdapter_Release(adapter);
if (FAILED(hr)) {
@@ -347,31 +348,30 @@ static inline bool gl_shtex_init_d3d11_tex(void)
IDXGIResource *dxgi_res;
HRESULT hr;
D3D11_TEXTURE2D_DESC desc = {0};
desc.Width = data.cx;
desc.Height = data.cy;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
desc.BindFlags = D3D11_BIND_RENDER_TARGET |
D3D11_BIND_SHADER_RESOURCE;
D3D11_TEXTURE2D_DESC desc = {0};
desc.Width = data.cx;
desc.Height = data.cy;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
hr = ID3D11Device_CreateTexture2D(data.d3d11_device, &desc, NULL,
&data.d3d11_tex);
&data.d3d11_tex);
if (FAILED(hr)) {
hlog_hr("gl_shtex_init_d3d11_tex: failed to create texture",
hr);
hr);
return false;
}
hr = ID3D11Device_QueryInterface(data.d3d11_tex,
&GUID_IDXGIResource, (void**)&dxgi_res);
hr = ID3D11Device_QueryInterface(data.d3d11_tex, &GUID_IDXGIResource,
(void **)&dxgi_res);
if (FAILED(hr)) {
hlog_hr("gl_shtex_init_d3d11_tex: failed to get IDXGIResource",
hr);
hr);
return false;
}
@@ -380,7 +380,7 @@ static inline bool gl_shtex_init_d3d11_tex(void)
if (FAILED(hr)) {
hlog_hr("gl_shtex_init_d3d11_tex: failed to get shared handle",
hr);
hr);
return false;
}
@@ -401,8 +401,8 @@ static inline bool gl_shtex_init_gl_tex(void)
}
data.gl_dxobj = jimglDXRegisterObjectNV(data.gl_device, data.d3d11_tex,
data.texture, GL_TEXTURE_2D,
WGL_ACCESS_WRITE_DISCARD_NV);
data.texture, GL_TEXTURE_2D,
WGL_ACCESS_WRITE_DISCARD_NV);
if (!data.gl_dxobj) {
hlog("gl_shtex_init_gl_tex: failed to register object");
return false;
@@ -434,9 +434,9 @@ static bool gl_shtex_init(HWND window)
if (!gl_init_fbo()) {
return false;
}
if (!capture_init_shtex(&data.shtex_info, window,
data.base_cx, data.base_cy, data.cx, data.cy,
data.format, true, (uintptr_t)data.handle)) {
if (!capture_init_shtex(&data.shtex_info, window, data.base_cx,
data.base_cy, data.cx, data.cy, data.format,
true, (uintptr_t)data.handle)) {
return false;
}
@@ -461,8 +461,8 @@ static inline bool gl_shmem_init_data(size_t idx, size_t size)
return false;
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, data.cx, data.cy,
0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, data.cx, data.cy, 0, GL_BGRA,
GL_UNSIGNED_BYTE, NULL);
if (gl_error("gl_shmem_init_data", "failed to set texture data")) {
return false;
}
@@ -488,7 +488,7 @@ static inline bool gl_shmem_init_buffers(void)
glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &last_pbo);
if (gl_error("gl_shmem_init_buffers",
"failed to save pixel pack buffer")) {
"failed to save pixel pack buffer")) {
return false;
}
@@ -516,9 +516,9 @@ static bool gl_shmem_init(HWND window)
if (!gl_init_fbo()) {
return false;
}
if (!capture_init_shmem(&data.shmem_info, window,
data.base_cx, data.base_cy, data.cx, data.cy,
data.cx * 4, data.format, true)) {
if (!capture_init_shmem(&data.shmem_info, window, data.base_cx,
data.base_cy, data.cx, data.cy, data.cx * 4,
data.format, true)) {
return false;
}
@@ -526,9 +526,9 @@ static bool gl_shmem_init(HWND window)
return true;
}
#define INIT_SUCCESS 0
#define INIT_FAILED -1
#define INIT_SHTEX_FAILED -2
#define INIT_SUCCESS 0
#define INIT_FAILED -1
#define INIT_SHTEX_FAILED -2
static int gl_init(HDC hdc)
{
@@ -550,8 +550,8 @@ static int gl_init(HDC hdc)
data.format = DXGI_FORMAT_B8G8R8A8_UNORM;
data.using_scale = global_hook_info->use_scale;
data.using_shtex = nv_capture_available &&
!global_hook_info->force_shmem &&
!data.shmem_fallback;
!global_hook_info->force_shmem &&
!data.shmem_fallback;
if (data.using_scale) {
data.cx = global_hook_info->cx;
@@ -590,7 +590,7 @@ static void gl_copy_backbuffer(GLuint dst)
}
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, dst, 0);
GL_TEXTURE_2D, dst, 0);
if (gl_error("gl_copy_backbuffer", "failed to set frame buffer")) {
return;
}
@@ -598,17 +598,16 @@ static void gl_copy_backbuffer(GLuint dst)
glReadBuffer(GL_BACK);
/* darkest dungeon fix */
darkest_dungeon_fix =
glGetError() == GL_INVALID_OPERATION &&
_strcmpi(process_name, "Darkest.exe") == 0;
darkest_dungeon_fix = glGetError() == GL_INVALID_OPERATION &&
_strcmpi(process_name, "Darkest.exe") == 0;
glDrawBuffer(GL_COLOR_ATTACHMENT0);
if (gl_error("gl_copy_backbuffer", "failed to set draw buffer")) {
return;
}
glBlitFramebuffer(0, 0, data.base_cx, data.base_cy,
0, 0, data.cx, data.cy, GL_COLOR_BUFFER_BIT, GL_LINEAR);
glBlitFramebuffer(0, 0, data.base_cx, data.base_cy, 0, 0, data.cx,
data.cy, GL_COLOR_BUFFER_BIT, GL_LINEAR);
gl_error("gl_copy_backbuffer", "failed to blit");
}
@@ -649,11 +648,12 @@ static inline void gl_shmem_capture_queue_copy(void)
glBindBuffer(GL_PIXEL_PACK_BUFFER, data.pbos[i]);
if (gl_error("gl_shmem_capture_queue_copy",
"failed to bind pbo")) {
"failed to bind pbo")) {
return;
}
buffer = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
buffer =
glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
if (buffer) {
data.texture_mapped[i] = true;
shmem_copy_data(i, buffer);
@@ -779,7 +779,7 @@ static BOOL WINAPI hook_swap_buffers(HDC hdc)
gl_capture(hdc);
unhook(&swap_buffers);
BOOL (WINAPI *call)(HDC) = swap_buffers.call_addr;
BOOL(WINAPI * call)(HDC) = swap_buffers.call_addr;
ret = call(hdc);
rehook(&swap_buffers);
@@ -797,7 +797,7 @@ static BOOL WINAPI hook_wgl_swap_buffers(HDC hdc)
gl_capture(hdc);
unhook(&wgl_swap_buffers);
BOOL (WINAPI *call)(HDC) = wgl_swap_buffers.call_addr;
BOOL(WINAPI * call)(HDC) = wgl_swap_buffers.call_addr;
ret = call(hdc);
rehook(&wgl_swap_buffers);
@@ -815,7 +815,7 @@ static BOOL WINAPI hook_wgl_swap_layer_buffers(HDC hdc, UINT planes)
gl_capture(hdc);
unhook(&wgl_swap_layer_buffers);
BOOL (WINAPI *call)(HDC, UINT) = wgl_swap_layer_buffers.call_addr;
BOOL(WINAPI * call)(HDC, UINT) = wgl_swap_layer_buffers.call_addr;
ret = call(hdc, planes);
rehook(&wgl_swap_layer_buffers);
@@ -839,7 +839,7 @@ static BOOL WINAPI hook_wgl_delete_context(HGLRC hrc)
}
unhook(&wgl_delete_context);
BOOL (WINAPI *call)(HGLRC) = wgl_delete_context.call_addr;
BOOL(WINAPI * call)(HGLRC) = wgl_delete_context.call_addr;
ret = call(hrc);
rehook(&wgl_delete_context);
@@ -856,7 +856,7 @@ static bool gl_register_window(void)
if (!RegisterClassW(&wc)) {
hlog("gl_register_window: failed to register window class: %d",
GetLastError());
GetLastError());
return false;
}
@@ -878,7 +878,7 @@ bool hook_gl(void)
* the same time, so blacklist it from capturing opengl */
const char *process_name = get_process_name();
if (_strcmpi(process_name, "yo_cm_client.exe") == 0 ||
_strcmpi(process_name, "cm_client.exe") == 0) {
_strcmpi(process_name, "cm_client.exe") == 0) {
hlog("Ignoring opengl for game: %s", process_name);
return true;
}
@@ -894,20 +894,17 @@ bool hook_gl(void)
hook_init(&swap_buffers, SwapBuffers, hook_swap_buffers, "SwapBuffers");
if (wgl_dc_proc) {
hook_init(&wgl_delete_context, wgl_dc_proc,
hook_wgl_delete_context,
"wglDeleteContext");
hook_wgl_delete_context, "wglDeleteContext");
rehook(&wgl_delete_context);
}
if (wgl_slb_proc) {
hook_init(&wgl_swap_layer_buffers, wgl_slb_proc,
hook_wgl_swap_layer_buffers,
"wglSwapLayerBuffers");
hook_wgl_swap_layer_buffers, "wglSwapLayerBuffers");
rehook(&wgl_swap_layer_buffers);
}
if (wgl_sb_proc) {
hook_init(&wgl_swap_buffers, wgl_sb_proc,
hook_wgl_swap_buffers,
"wglSwapBuffers");
hook_init(&wgl_swap_buffers, wgl_sb_proc, hook_wgl_swap_buffers,
"wglSwapBuffers");
rehook(&wgl_swap_buffers);
}

View File

@@ -69,51 +69,57 @@ typedef ptrdiff_t GLsizeiptrARB;
#define GL_COLOR_ATTACHMENT0 0x8CE0
#define GL_COLOR_ATTACHMENT1 0x8CE1
typedef void (WINAPI *GLTEXIMAGE2DPROC)(GLenum target, GLint level,
GLint internal_format, GLsizei width, GLsizei height,
GLint border, GLenum format, GLenum type, const GLvoid *data);
typedef void (WINAPI *GLGETTEXIMAGEPROC)(GLenum target, GLint level,
GLenum format, GLenum type, GLvoid *img);
typedef void (WINAPI *GLREADBUFFERPROC)(GLenum);
typedef void (WINAPI *GLDRAWBUFFERPROC)(GLenum mode);
typedef void (WINAPI *GLGETINTEGERVPROC)(GLenum pname, GLint *params);
typedef GLenum (WINAPI *GLGETERRORPROC)();
typedef BOOL (WINAPI *WGLSWAPLAYERBUFFERSPROC)(HDC, UINT);
typedef BOOL (WINAPI *WGLSWAPBUFFERSPROC)(HDC);
typedef BOOL (WINAPI *WGLDELETECONTEXTPROC)(HGLRC);
typedef PROC (WINAPI *WGLGETPROCADDRESSPROC)(LPCSTR);
typedef BOOL (WINAPI *WGLMAKECURRENTPROC)(HDC, HGLRC);
typedef HDC (WINAPI *WGLGETCURRENTDCPROC)();
typedef HGLRC (WINAPI *WGLGETCURRENTCONTEXTPROC)();
typedef HGLRC (WINAPI *WGLCREATECONTEXTPROC)(HDC);
typedef void (WINAPI *GLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size,
const GLvoid* data, GLenum usage);
typedef void (WINAPI *GLDELETEBUFFERSARBPROC)(GLsizei n, const GLuint* buffers);
typedef void (WINAPI *GLDELETETEXTURESPROC)(GLsizei n, const GLuint* buffers);
typedef void (WINAPI *GLGENBUFFERSARBPROC)(GLsizei n, GLuint* buffers);
typedef void (WINAPI *GLGENTEXTURESPROC)(GLsizei n, GLuint* textures);
typedef GLvoid* (WINAPI *GLMAPBUFFERPROC)(GLenum target, GLenum access);
typedef GLboolean (WINAPI *GLUNMAPBUFFERPROC)(GLenum target);
typedef void (WINAPI *GLBINDBUFFERPROC)(GLenum target, GLuint buffer);
typedef void (WINAPI *GLBINDTEXTUREPROC)(GLenum target, GLuint texture);
typedef void (WINAPI *GLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint* buffers);
typedef void (WINAPI *GLDELETEFRAMEBUFFERSPROC)(GLsizei n,
GLuint *framebuffers);
typedef void (WINAPI *GLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer);
typedef void (WINAPI *GLBLITFRAMEBUFFERPROC)(GLint srcX0, GLint srcY0,
GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0,
GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
typedef void (WINAPI *GLFRAMEBUFFERTEXTURE2DPROC)(GLenum target,
GLenum attachment, GLenum textarget, GLuint texture,
GLint level);
typedef BOOL (WINAPI *WGLSETRESOURCESHAREHANDLENVPROC)(void*, HANDLE);
typedef HANDLE (WINAPI *WGLDXOPENDEVICENVPROC)(void*);
typedef BOOL (WINAPI *WGLDXCLOSEDEVICENVPROC)(HANDLE);
typedef HANDLE (WINAPI *WGLDXREGISTEROBJECTNVPROC)(HANDLE, void *, GLuint, GLenum, GLenum);
typedef BOOL (WINAPI *WGLDXUNREGISTEROBJECTNVPROC)(HANDLE, HANDLE);
typedef BOOL (WINAPI *WGLDXOBJECTACCESSNVPROC)(HANDLE, GLenum);
typedef BOOL (WINAPI *WGLDXLOCKOBJECTSNVPROC)(HANDLE, GLint, HANDLE *);
typedef BOOL (WINAPI *WGLDXUNLOCKOBJECTSNVPROC)(HANDLE, GLint, HANDLE *);
typedef void(WINAPI *GLTEXIMAGE2DPROC)(GLenum target, GLint level,
GLint internal_format, GLsizei width,
GLsizei height, GLint border,
GLenum format, GLenum type,
const GLvoid *data);
typedef void(WINAPI *GLGETTEXIMAGEPROC)(GLenum target, GLint level,
GLenum format, GLenum type,
GLvoid *img);
typedef void(WINAPI *GLREADBUFFERPROC)(GLenum);
typedef void(WINAPI *GLDRAWBUFFERPROC)(GLenum mode);
typedef void(WINAPI *GLGETINTEGERVPROC)(GLenum pname, GLint *params);
typedef GLenum(WINAPI *GLGETERRORPROC)();
typedef BOOL(WINAPI *WGLSWAPLAYERBUFFERSPROC)(HDC, UINT);
typedef BOOL(WINAPI *WGLSWAPBUFFERSPROC)(HDC);
typedef BOOL(WINAPI *WGLDELETECONTEXTPROC)(HGLRC);
typedef PROC(WINAPI *WGLGETPROCADDRESSPROC)(LPCSTR);
typedef BOOL(WINAPI *WGLMAKECURRENTPROC)(HDC, HGLRC);
typedef HDC(WINAPI *WGLGETCURRENTDCPROC)();
typedef HGLRC(WINAPI *WGLGETCURRENTCONTEXTPROC)();
typedef HGLRC(WINAPI *WGLCREATECONTEXTPROC)(HDC);
typedef void(WINAPI *GLBUFFERDATAARBPROC)(GLenum target, GLsizeiptrARB size,
const GLvoid *data, GLenum usage);
typedef void(WINAPI *GLDELETEBUFFERSARBPROC)(GLsizei n, const GLuint *buffers);
typedef void(WINAPI *GLDELETETEXTURESPROC)(GLsizei n, const GLuint *buffers);
typedef void(WINAPI *GLGENBUFFERSARBPROC)(GLsizei n, GLuint *buffers);
typedef void(WINAPI *GLGENTEXTURESPROC)(GLsizei n, GLuint *textures);
typedef GLvoid *(WINAPI *GLMAPBUFFERPROC)(GLenum target, GLenum access);
typedef GLboolean(WINAPI *GLUNMAPBUFFERPROC)(GLenum target);
typedef void(WINAPI *GLBINDBUFFERPROC)(GLenum target, GLuint buffer);
typedef void(WINAPI *GLBINDTEXTUREPROC)(GLenum target, GLuint texture);
typedef void(WINAPI *GLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint *buffers);
typedef void(WINAPI *GLDELETEFRAMEBUFFERSPROC)(GLsizei n, GLuint *framebuffers);
typedef void(WINAPI *GLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer);
typedef void(WINAPI *GLBLITFRAMEBUFFERPROC)(GLint srcX0, GLint srcY0,
GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0,
GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter);
typedef void(WINAPI *GLFRAMEBUFFERTEXTURE2DPROC)(GLenum target,
GLenum attachment,
GLenum textarget,
GLuint texture, GLint level);
typedef BOOL(WINAPI *WGLSETRESOURCESHAREHANDLENVPROC)(void *, HANDLE);
typedef HANDLE(WINAPI *WGLDXOPENDEVICENVPROC)(void *);
typedef BOOL(WINAPI *WGLDXCLOSEDEVICENVPROC)(HANDLE);
typedef HANDLE(WINAPI *WGLDXREGISTEROBJECTNVPROC)(HANDLE, void *, GLuint,
GLenum, GLenum);
typedef BOOL(WINAPI *WGLDXUNREGISTEROBJECTNVPROC)(HANDLE, HANDLE);
typedef BOOL(WINAPI *WGLDXOBJECTACCESSNVPROC)(HANDLE, GLenum);
typedef BOOL(WINAPI *WGLDXLOCKOBJECTSNVPROC)(HANDLE, GLint, HANDLE *);
typedef BOOL(WINAPI *WGLDXUNLOCKOBJECTSNVPROC)(HANDLE, GLint, HANDLE *);
static GLTEXIMAGE2DPROC glTexImage2D = NULL;
static GLGETTEXIMAGEPROC glGetTexImage = NULL;

View File

@@ -13,45 +13,44 @@
#endif
struct thread_data {
CRITICAL_SECTION mutexes[NUM_BUFFERS];
CRITICAL_SECTION data_mutex;
void *volatile cur_data;
uint8_t *shmem_textures[2];
HANDLE copy_thread;
HANDLE copy_event;
HANDLE stop_event;
volatile int cur_tex;
unsigned int pitch;
unsigned int cy;
volatile bool locked_textures[NUM_BUFFERS];
CRITICAL_SECTION mutexes[NUM_BUFFERS];
CRITICAL_SECTION data_mutex;
void *volatile cur_data;
uint8_t *shmem_textures[2];
HANDLE copy_thread;
HANDLE copy_event;
HANDLE stop_event;
volatile int cur_tex;
unsigned int pitch;
unsigned int cy;
volatile bool locked_textures[NUM_BUFFERS];
};
ipc_pipe_client_t pipe = {0};
HANDLE signal_restart = NULL;
HANDLE signal_stop = NULL;
HANDLE signal_ready = NULL;
HANDLE signal_exit = NULL;
static HANDLE signal_init = NULL;
HANDLE tex_mutexes[2] = {NULL, NULL};
static HANDLE filemap_hook_info = NULL;
ipc_pipe_client_t pipe = {0};
HANDLE signal_restart = NULL;
HANDLE signal_stop = NULL;
HANDLE signal_ready = NULL;
HANDLE signal_exit = NULL;
static HANDLE signal_init = NULL;
HANDLE tex_mutexes[2] = {NULL, NULL};
static HANDLE filemap_hook_info = NULL;
static HINSTANCE dll_inst = NULL;
static volatile bool stop_loop = false;
static HANDLE capture_thread = NULL;
char system_path[MAX_PATH] = {0};
char process_name[MAX_PATH] = {0};
wchar_t keepalive_name[64] = {0};
HWND dummy_window = NULL;
static HINSTANCE dll_inst = NULL;
static volatile bool stop_loop = false;
static HANDLE capture_thread = NULL;
char system_path[MAX_PATH] = {0};
char process_name[MAX_PATH] = {0};
wchar_t keepalive_name[64] = {0};
HWND dummy_window = NULL;
static unsigned int shmem_id_counter = 0;
static void *shmem_info = NULL;
static HANDLE shmem_file_handle = 0;
static unsigned int shmem_id_counter = 0;
static void *shmem_info = NULL;
static HANDLE shmem_file_handle = 0;
static struct thread_data thread_data = {0};
volatile bool active = false;
struct hook_info *global_hook_info = NULL;
static struct thread_data thread_data = {0};
volatile bool active = false;
struct hook_info *global_hook_info = NULL;
static inline void wait_for_dll_main_finish(HANDLE thread_handle)
{
@@ -153,7 +152,7 @@ static inline bool init_system_path(void)
static inline void log_current_process(void)
{
DWORD len = GetModuleBaseNameA(GetCurrentProcess(), NULL, process_name,
MAX_PATH);
MAX_PATH);
if (len > 0) {
process_name[len] = 0;
hlog("Hooked to process: %s", process_name);
@@ -167,15 +166,15 @@ static inline bool init_hook_info(void)
filemap_hook_info = create_hook_info(GetCurrentProcessId());
if (!filemap_hook_info) {
hlog("Failed to create hook info file mapping: %lu",
GetLastError());
GetLastError());
return false;
}
global_hook_info = MapViewOfFile(filemap_hook_info, FILE_MAP_ALL_ACCESS,
0, 0, sizeof(struct hook_info));
0, 0, sizeof(struct hook_info));
if (!global_hook_info) {
hlog("Failed to map the hook info file mapping: %lu",
GetLastError());
GetLastError());
return false;
}
@@ -198,12 +197,13 @@ static DWORD WINAPI dummy_window_thread(LPVOID *unused)
if (!RegisterClass(&wc)) {
hlog("Failed to create temp D3D window class: %lu",
GetLastError());
GetLastError());
return 0;
}
dummy_window = CreateWindowExW(0, dummy_window_class, L"Temp Window",
DEF_FLAGS, 0, 0, 1, 1, NULL, NULL, dll_inst, NULL);
DEF_FLAGS, 0, 0, 1, 1, NULL, NULL,
dll_inst, NULL);
if (!dummy_window) {
hlog("Failed to create temp D3D window: %lu", GetLastError());
return 0;
@@ -220,11 +220,11 @@ static DWORD WINAPI dummy_window_thread(LPVOID *unused)
static inline void init_dummy_window_thread(void)
{
HANDLE thread = CreateThread(NULL, 0, dummy_window_thread, NULL, 0,
NULL);
HANDLE thread =
CreateThread(NULL, 0, dummy_window_thread, NULL, 0, NULL);
if (!thread) {
hlog("Failed to create temp D3D window thread: %lu",
GetLastError());
GetLastError());
return;
}
@@ -236,7 +236,7 @@ static inline bool init_hook(HANDLE thread_handle)
wait_for_dll_main_finish(thread_handle);
_snwprintf(keepalive_name, sizeof(keepalive_name) / sizeof(wchar_t),
L"%s%lu", WINDOW_HOOK_KEEPALIVE, GetCurrentProcessId());
L"%s%lu", WINDOW_HOOK_KEEPALIVE, GetCurrentProcessId());
init_pipe();
@@ -283,35 +283,35 @@ static inline bool d3d8_hookable(void)
static inline bool ddraw_hookable(void)
{
return !!global_hook_info->offsets.ddraw.surface_create &&
!!global_hook_info->offsets.ddraw.surface_restore &&
!!global_hook_info->offsets.ddraw.surface_release &&
!!global_hook_info->offsets.ddraw.surface_unlock &&
!!global_hook_info->offsets.ddraw.surface_blt &&
!!global_hook_info->offsets.ddraw.surface_flip &&
!!global_hook_info->offsets.ddraw.surface_set_palette &&
!!global_hook_info->offsets.ddraw.palette_set_entries;
!!global_hook_info->offsets.ddraw.surface_restore &&
!!global_hook_info->offsets.ddraw.surface_release &&
!!global_hook_info->offsets.ddraw.surface_unlock &&
!!global_hook_info->offsets.ddraw.surface_blt &&
!!global_hook_info->offsets.ddraw.surface_flip &&
!!global_hook_info->offsets.ddraw.surface_set_palette &&
!!global_hook_info->offsets.ddraw.palette_set_entries;
}
static inline bool d3d9_hookable(void)
{
return !!global_hook_info->offsets.d3d9.present &&
!!global_hook_info->offsets.d3d9.present_ex &&
!!global_hook_info->offsets.d3d9.present_swap;
!!global_hook_info->offsets.d3d9.present_ex &&
!!global_hook_info->offsets.d3d9.present_swap;
}
static inline bool dxgi_hookable(void)
{
return !!global_hook_info->offsets.dxgi.present &&
!!global_hook_info->offsets.dxgi.resize;
!!global_hook_info->offsets.dxgi.resize;
}
static inline bool attempt_hook(void)
{
//static bool ddraw_hooked = false;
static bool d3d8_hooked = false;
static bool d3d9_hooked = false;
static bool dxgi_hooked = false;
static bool gl_hooked = false;
static bool d3d8_hooked = false;
static bool d3d9_hooked = false;
static bool dxgi_hooked = false;
static bool gl_hooked = false;
if (!d3d9_hooked) {
if (!d3d9_hookable()) {
@@ -342,7 +342,7 @@ static inline bool attempt_hook(void)
if (gl_hooked) {
return true;
}
/*} else {
/*} else {
rehook_gl();*/
}
@@ -381,7 +381,8 @@ static inline void capture_loop(void)
for (size_t n = 0; !stop_loop; n++) {
/* this causes it to check every 4 seconds, but still with
* a small sleep interval in case the thread needs to stop */
if (n % 100 == 0) attempt_hook();
if (n % 100 == 0)
attempt_hook();
Sleep(40);
}
}
@@ -425,10 +426,10 @@ void hlog_hr(const char *text, HRESULT hr)
LPSTR buffer = NULL;
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, hr, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(LPSTR)&buffer, 0, NULL);
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, hr, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(LPSTR)&buffer, 0, NULL);
if (buffer) {
hlog("%s (0x%08lX): %s", text, hr, buffer);
@@ -495,27 +496,28 @@ static inline bool init_shared_info(size_t size)
_snwprintf(name, 64, L"%s%ld", SHMEM_TEXTURE, ++shmem_id_counter);
shmem_file_handle = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
PAGE_READWRITE, 0, (DWORD)size, name);
PAGE_READWRITE, 0, (DWORD)size,
name);
if (!shmem_file_handle) {
hlog("init_shared_info: Failed to create shared memory: %d",
GetLastError());
GetLastError());
return false;
}
shmem_info = MapViewOfFile(shmem_file_handle, FILE_MAP_ALL_ACCESS,
0, 0, size);
shmem_info = MapViewOfFile(shmem_file_handle, FILE_MAP_ALL_ACCESS, 0, 0,
size);
if (!shmem_info) {
hlog("init_shared_info: Failed to map shared memory: %d",
GetLastError());
GetLastError());
return false;
}
return true;
}
bool capture_init_shtex(struct shtex_data **data, HWND window,
uint32_t base_cx, uint32_t base_cy, uint32_t cx, uint32_t cy,
uint32_t format, bool flip, uintptr_t handle)
bool capture_init_shtex(struct shtex_data **data, HWND window, uint32_t base_cx,
uint32_t base_cy, uint32_t cx, uint32_t cy,
uint32_t format, bool flip, uintptr_t handle)
{
if (!init_shared_info(sizeof(struct shtex_data))) {
hlog("capture_init_shtex: Failed to initialize memory");
@@ -538,7 +540,7 @@ bool capture_init_shtex(struct shtex_data **data, HWND window,
if (!SetEvent(signal_ready)) {
hlog("capture_init_shtex: Failed to signal ready: %d",
GetLastError());
GetLastError());
return false;
}
@@ -555,13 +557,13 @@ static DWORD CALLBACK copy_thread(LPVOID unused)
if (!duplicate_handle(&events[0], thread_data.copy_event)) {
hlog_hr("copy_thread: Failed to duplicate copy event: %d",
GetLastError());
GetLastError());
return 0;
}
if (!duplicate_handle(&events[1], thread_data.stop_event)) {
hlog_hr("copy_thread: Failed to duplicate stop event: %d",
GetLastError());
GetLastError());
goto finish;
}
@@ -585,10 +587,10 @@ static DWORD CALLBACK copy_thread(LPVOID unused)
int lock_id = try_lock_shmem_tex(shmem_id);
if (lock_id != -1) {
memcpy(thread_data.shmem_textures[lock_id],
cur_data, pitch * cy);
cur_data, pitch * cy);
unlock_shmem_tex(lock_id);
((struct shmem_data*)shmem_info)->last_tex =
((struct shmem_data *)shmem_info)->last_tex =
lock_id;
shmem_id = lock_id == 0 ? 1 : 0;
@@ -623,7 +625,7 @@ void shmem_copy_data(size_t idx, void *volatile data)
bool shmem_texture_data_lock(int idx)
{
bool locked;
EnterCriticalSection(&thread_data.data_mutex);
locked = thread_data.locked_textures[idx];
LeaveCriticalSection(&thread_data.data_mutex);
@@ -651,20 +653,20 @@ static inline bool init_shmem_thread(uint32_t pitch, uint32_t cy)
thread_data.pitch = pitch;
thread_data.cy = cy;
thread_data.shmem_textures[0] = (uint8_t*)data + data->tex1_offset;
thread_data.shmem_textures[1] = (uint8_t*)data + data->tex2_offset;
thread_data.shmem_textures[0] = (uint8_t *)data + data->tex1_offset;
thread_data.shmem_textures[1] = (uint8_t *)data + data->tex2_offset;
thread_data.copy_event = CreateEvent(NULL, false, false, NULL);
if (!thread_data.copy_event) {
hlog("init_shmem_thread: Failed to create copy event: %d",
GetLastError());
GetLastError());
return false;
}
thread_data.stop_event = CreateEvent(NULL, true, false, NULL);
if (!thread_data.stop_event) {
hlog("init_shmem_thread: Failed to create stop event: %d",
GetLastError());
GetLastError());
return false;
}
@@ -674,28 +676,28 @@ static inline bool init_shmem_thread(uint32_t pitch, uint32_t cy)
InitializeCriticalSection(&thread_data.data_mutex);
thread_data.copy_thread = CreateThread(NULL, 0, copy_thread, NULL, 0,
NULL);
thread_data.copy_thread =
CreateThread(NULL, 0, copy_thread, NULL, 0, NULL);
if (!thread_data.copy_thread) {
hlog("init_shmem_thread: Failed to create thread: %d",
GetLastError());
GetLastError());
return false;
}
return true;
}
#ifndef ALIGN
#define ALIGN(bytes, align) (((bytes) + ((align) - 1)) & ~((align) - 1))
#define ALIGN(bytes, align) (((bytes) + ((align)-1)) & ~((align)-1))
#endif
bool capture_init_shmem(struct shmem_data **data, HWND window,
uint32_t base_cx, uint32_t base_cy, uint32_t cx, uint32_t cy,
uint32_t pitch, uint32_t format, bool flip)
bool capture_init_shmem(struct shmem_data **data, HWND window, uint32_t base_cx,
uint32_t base_cy, uint32_t cx, uint32_t cy,
uint32_t pitch, uint32_t format, bool flip)
{
uint32_t tex_size = cy * pitch;
uint32_t aligned_header = ALIGN(sizeof(struct shmem_data), 32);
uint32_t aligned_tex = ALIGN(tex_size, 32);
uint32_t total_size = aligned_header + aligned_tex * 2 + 32;
uint32_t tex_size = cy * pitch;
uint32_t aligned_header = ALIGN(sizeof(struct shmem_data), 32);
uint32_t aligned_tex = ALIGN(tex_size, 32);
uint32_t total_size = aligned_header + aligned_tex * 2 + 32;
uintptr_t align_pos;
if (!init_shared_info(total_size)) {
@@ -706,7 +708,7 @@ bool capture_init_shmem(struct shmem_data **data, HWND window,
*data = shmem_info;
/* to ensure fast copy rate, align texture data to 256bit addresses */
align_pos = (uintptr_t)shmem_info;
align_pos = (uintptr_t)shmem_info;
align_pos += aligned_header;
align_pos &= ~(32 - 1);
align_pos -= (uintptr_t)shmem_info;
@@ -736,7 +738,7 @@ bool capture_init_shmem(struct shmem_data **data, HWND window,
if (!SetEvent(signal_ready)) {
hlog("capture_init_shmem: Failed to signal ready: %d",
GetLastError());
GetLastError());
return false;
}
@@ -792,9 +794,9 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID unused1)
HANDLE cur_thread;
bool success = DuplicateHandle(GetCurrentProcess(),
GetCurrentThread(),
GetCurrentProcess(), &cur_thread,
SYNCHRONIZE, false, 0);
GetCurrentThread(),
GetCurrentProcess(), &cur_thread,
SYNCHRONIZE, false, 0);
if (!success)
DbgOut("Failed to get current thread handle");
@@ -817,9 +819,9 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID unused1)
GetModuleFileNameW(hinst, name, MAX_PATH);
LoadLibraryW(name);
capture_thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)main_capture_thread,
(LPVOID)cur_thread, 0, 0);
capture_thread = CreateThread(
NULL, 0, (LPTHREAD_START_ROUTINE)main_capture_thread,
(LPVOID)cur_thread, 0, 0);
if (!capture_thread) {
CloseHandle(cur_thread);
return false;
@@ -839,19 +841,18 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID unused1)
return true;
}
__declspec(dllexport) LRESULT CALLBACK dummy_debug_proc(int code,
WPARAM wparam, LPARAM lparam)
__declspec(dllexport) LRESULT CALLBACK
dummy_debug_proc(int code, WPARAM wparam, LPARAM lparam)
{
static bool hooking = true;
MSG *msg = (MSG*)lparam;
MSG *msg = (MSG *)lparam;
if (hooking && msg->message == (WM_USER + 432)) {
HMODULE user32 = GetModuleHandleW(L"USER32");
BOOL (WINAPI *unhook_windows_hook_ex)(HHOOK) = NULL;
BOOL(WINAPI * unhook_windows_hook_ex)(HHOOK) = NULL;
unhook_windows_hook_ex = get_obfuscated_func(user32,
"VojeleY`bdgxvM`hhDz",
0x7F55F80C9EE3A213ULL);
unhook_windows_hook_ex = get_obfuscated_func(
user32, "VojeleY`bdgxvM`hhDz", 0x7F55F80C9EE3A213ULL);
if (unhook_windows_hook_ex)
unhook_windows_hook_ex((HHOOK)msg->lParam);

View File

@@ -4,7 +4,7 @@
#ifdef _MSC_VER
/* conversion from data/function pointer */
#pragma warning(disable: 4152)
#pragma warning(disable : 4152)
#endif
#include "../graphics-hook-info.h"
@@ -59,11 +59,13 @@ extern uint8_t *get_d3d1x_pixel_shader(size_t *size);
extern bool rehook_gl(void);
extern bool capture_init_shtex(struct shtex_data **data, HWND window,
uint32_t base_cx, uint32_t base_cy, uint32_t cx, uint32_t cy,
uint32_t format, bool flip, uintptr_t handle);
uint32_t base_cx, uint32_t base_cy, uint32_t cx,
uint32_t cy, uint32_t format, bool flip,
uintptr_t handle);
extern bool capture_init_shmem(struct shmem_data **data, HWND window,
uint32_t base_cx, uint32_t base_cy, uint32_t cx, uint32_t cy,
uint32_t pitch, uint32_t format, bool flip);
uint32_t base_cx, uint32_t base_cy, uint32_t cx,
uint32_t cy, uint32_t pitch, uint32_t format,
bool flip);
extern void capture_free(void);
extern struct hook_info *global_hook_info;
@@ -80,12 +82,12 @@ struct vertex {
static inline bool duplicate_handle(HANDLE *dst, HANDLE src)
{
return !!DuplicateHandle(GetCurrentProcess(), src, GetCurrentProcess(),
dst, 0, false, DUPLICATE_SAME_ACCESS);
dst, 0, false, DUPLICATE_SAME_ACCESS);
}
static inline void *get_offset_addr(HMODULE module, uint32_t offset)
{
return (void*)((uintptr_t)module + (uintptr_t)offset);
return (void *)((uintptr_t)module + (uintptr_t)offset);
}
/* ------------------------------------------------------------------------- */
@@ -121,7 +123,7 @@ static inline uint32_t module_size(HMODULE module)
{
MODULEINFO info;
bool success = !!GetModuleInformation(GetCurrentProcess(), module,
&info, sizeof(info));
&info, sizeof(info));
return success ? info.SizeOfImage : 0;
}
@@ -160,8 +162,8 @@ static inline bool capture_active(void)
static inline bool frame_ready(uint64_t interval)
{
static uint64_t last_time = 0;
uint64_t elapsed;
uint64_t t;
uint64_t elapsed;
uint64_t t;
if (!interval) {
return true;
@@ -181,7 +183,7 @@ static inline bool frame_ready(uint64_t interval)
static inline bool capture_ready(void)
{
return capture_active() &&
frame_ready(global_hook_info->frame_interval);
frame_ready(global_hook_info->frame_interval);
}
static inline bool capture_stopped(void)

View File

@@ -48,4 +48,3 @@ static inline bool object_signalled(HANDLE event)
return WaitForSingleObject(event, 0) == WAIT_OBJECT_0;
}

View File

@@ -27,37 +27,38 @@ static void load_debug_privilege(void)
tp.Privileges[0].Luid = val;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(token, false, &tp,
sizeof(tp), NULL, NULL);
AdjustTokenPrivileges(token, false, &tp, sizeof(tp), NULL,
NULL);
}
CloseHandle(token);
}
static inline HANDLE open_process(DWORD desired_access, bool inherit_handle,
DWORD process_id)
DWORD process_id)
{
HANDLE (WINAPI *open_process_proc)(DWORD, BOOL, DWORD);
HANDLE(WINAPI * open_process_proc)(DWORD, BOOL, DWORD);
open_process_proc = get_obfuscated_func(GetModuleHandleW(L"KERNEL32"),
"HxjcQrmkb|~", 0xc82efdf78201df87);
"HxjcQrmkb|~",
0xc82efdf78201df87);
return open_process_proc(desired_access, inherit_handle, process_id);
}
static inline int inject_library(HANDLE process, const wchar_t *dll)
{
return inject_library_obf(process, dll,
"E}mo|d[cefubWk~bgk", 0x7c3371986918e8f6,
"Rqbr`T{cnor{Bnlgwz", 0x81bf81adc9456b35,
"]`~wrl`KeghiCt", 0xadc6a7b9acd73c9b,
"Zh}{}agHzfd@{", 0x57135138eb08ff1c,
"DnafGhj}l~sX", 0x350bfacdf81b2018);
return inject_library_obf(process, dll, "E}mo|d[cefubWk~bgk",
0x7c3371986918e8f6, "Rqbr`T{cnor{Bnlgwz",
0x81bf81adc9456b35, "]`~wrl`KeghiCt",
0xadc6a7b9acd73c9b, "Zh}{}agHzfd@{",
0x57135138eb08ff1c, "DnafGhj}l~sX",
0x350bfacdf81b2018);
}
static inline int inject_library_safe(DWORD thread_id, const wchar_t *dll)
{
return inject_library_safe_obf(thread_id, dll,
"[bs^fbkmwuKfmfOvI", 0xEAD293602FCF9778ULL);
return inject_library_safe_obf(thread_id, dll, "[bs^fbkmwuKfmfOvI",
0xEAD293602FCF9778ULL);
}
static inline int inject_library_full(DWORD process_id, const wchar_t *dll)
@@ -87,9 +88,8 @@ static int inject_helper(wchar_t *argv[], const wchar_t *dll)
return INJECT_ERROR_INVALID_PARAMS;
}
return use_safe_inject
? inject_library_safe(id, dll)
: inject_library_full(id, dll);
return use_safe_inject ? inject_library_safe(id, dll)
: inject_library_full(id, dll);
}
#define UNUSED_PARAMETER(x) ((void)(x))
@@ -107,8 +107,7 @@ int main(int argc, char *argv_ansi[])
pCommandLineW = GetCommandLineW();
argv = CommandLineToArgvW(pCommandLineW, &argc);
if (argv && argc == 4) {
DWORD size = GetModuleFileNameW(NULL,
dll_path, MAX_PATH);
DWORD size = GetModuleFileNameW(NULL, dll_path, MAX_PATH);
if (size) {
wchar_t *name_start = wcsrchr(dll_path, '\\');
if (name_start) {

View File

@@ -3,20 +3,21 @@
#include "obfuscate.h"
#include "inject-library.h"
typedef HANDLE (WINAPI *create_remote_thread_t)(HANDLE, LPSECURITY_ATTRIBUTES,
SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD);
typedef BOOL (WINAPI *write_process_memory_t)(HANDLE, LPVOID, LPCVOID, SIZE_T,
SIZE_T*);
typedef LPVOID (WINAPI *virtual_alloc_ex_t)(HANDLE, LPVOID, SIZE_T, DWORD,
DWORD);
typedef BOOL (WINAPI *virtual_free_ex_t)(HANDLE, LPVOID, SIZE_T, DWORD);
typedef HANDLE(WINAPI *create_remote_thread_t)(HANDLE, LPSECURITY_ATTRIBUTES,
SIZE_T, LPTHREAD_START_ROUTINE,
LPVOID, DWORD, LPDWORD);
typedef BOOL(WINAPI *write_process_memory_t)(HANDLE, LPVOID, LPCVOID, SIZE_T,
SIZE_T *);
typedef LPVOID(WINAPI *virtual_alloc_ex_t)(HANDLE, LPVOID, SIZE_T, DWORD,
DWORD);
typedef BOOL(WINAPI *virtual_free_ex_t)(HANDLE, LPVOID, SIZE_T, DWORD);
int inject_library_obf(HANDLE process, const wchar_t *dll,
const char *create_remote_thread_obf, uint64_t obf1,
const char *write_process_memory_obf, uint64_t obf2,
const char *virtual_alloc_ex_obf, uint64_t obf3,
const char *virtual_free_ex_obf, uint64_t obf4,
const char *load_library_w_obf, uint64_t obf5)
const char *create_remote_thread_obf, uint64_t obf1,
const char *write_process_memory_obf, uint64_t obf2,
const char *virtual_alloc_ex_obf, uint64_t obf3,
const char *virtual_free_ex_obf, uint64_t obf4,
const char *load_library_w_obf, uint64_t obf5)
{
int ret = INJECT_ERROR_UNLIKELY_FAIL;
DWORD last_error = 0;
@@ -36,34 +37,34 @@ int inject_library_obf(HANDLE process, const wchar_t *dll,
virtual_free_ex_t virtual_free_ex;
FARPROC load_library_w;
create_remote_thread = get_obfuscated_func(kernel32,
create_remote_thread_obf, obf1);
write_process_memory = get_obfuscated_func(kernel32,
write_process_memory_obf, obf2);
virtual_alloc_ex = get_obfuscated_func(kernel32,
virtual_alloc_ex_obf, obf3);
virtual_free_ex = get_obfuscated_func(kernel32,
virtual_free_ex_obf, obf4);
load_library_w = get_obfuscated_func(kernel32,
load_library_w_obf, obf5);
create_remote_thread =
get_obfuscated_func(kernel32, create_remote_thread_obf, obf1);
write_process_memory =
get_obfuscated_func(kernel32, write_process_memory_obf, obf2);
virtual_alloc_ex =
get_obfuscated_func(kernel32, virtual_alloc_ex_obf, obf3);
virtual_free_ex =
get_obfuscated_func(kernel32, virtual_free_ex_obf, obf4);
load_library_w =
get_obfuscated_func(kernel32, load_library_w_obf, obf5);
/* -------------------------------- */
size = (wcslen(dll) + 1) * sizeof(wchar_t);
mem = virtual_alloc_ex(process, NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
mem = virtual_alloc_ex(process, NULL, size, MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE);
if (!mem) {
goto fail;
}
success = write_process_memory(process, mem, dll,
size, &written_size);
success = write_process_memory(process, mem, dll, size, &written_size);
if (!success) {
goto fail;
}
thread = create_remote_thread(process, NULL, 0,
(LPTHREAD_START_ROUTINE)load_library_w, mem, 0,
&thread_id);
(LPTHREAD_START_ROUTINE)load_library_w,
mem, 0, &thread_id);
if (!thread) {
goto fail;
}
@@ -95,14 +96,14 @@ fail:
/* ------------------------------------------------------------------------- */
typedef HHOOK (WINAPI *set_windows_hook_ex_t)(int, HOOKPROC, HINSTANCE, DWORD);
typedef HHOOK(WINAPI *set_windows_hook_ex_t)(int, HOOKPROC, HINSTANCE, DWORD);
#define RETRY_INTERVAL_MS 500
#define TOTAL_RETRY_TIME_MS 4000
#define RETRY_COUNT (TOTAL_RETRY_TIME_MS / RETRY_INTERVAL_MS)
#define RETRY_INTERVAL_MS 500
#define TOTAL_RETRY_TIME_MS 4000
#define RETRY_COUNT (TOTAL_RETRY_TIME_MS / RETRY_INTERVAL_MS)
int inject_library_safe_obf(DWORD thread_id, const wchar_t *dll,
const char *set_windows_hook_ex_obf, uint64_t obf1)
const char *set_windows_hook_ex_obf, uint64_t obf1)
{
HMODULE user32 = GetModuleHandleW(L"USER32");
set_windows_hook_ex_t set_windows_hook_ex;
@@ -125,8 +126,8 @@ int inject_library_safe_obf(DWORD thread_id, const wchar_t *dll,
return INJECT_ERROR_UNLIKELY_FAIL;
}
set_windows_hook_ex = get_obfuscated_func(user32,
set_windows_hook_ex_obf, obf1);
set_windows_hook_ex =
get_obfuscated_func(user32, set_windows_hook_ex_obf, obf1);
hook = set_windows_hook_ex(WH_GETMESSAGE, proc, lib, thread_id);
if (!hook) {

View File

@@ -1,17 +1,20 @@
#include <windows.h>
#include <stdint.h>
#define INJECT_ERROR_INJECT_FAILED -1
#define INJECT_ERROR_INVALID_PARAMS -2
#define INJECT_ERROR_INJECT_FAILED -1
#define INJECT_ERROR_INVALID_PARAMS -2
#define INJECT_ERROR_OPEN_PROCESS_FAIL -3
#define INJECT_ERROR_UNLIKELY_FAIL -4
#define INJECT_ERROR_UNLIKELY_FAIL -4
extern int inject_library_obf(HANDLE process, const wchar_t *dll,
const char *create_remote_thread_obf, uint64_t obf1,
const char *write_process_memory_obf, uint64_t obf2,
const char *virtual_alloc_ex_obf, uint64_t obf3,
const char *virtual_free_ex_obf, uint64_t obf4,
const char *load_library_w_obf, uint64_t obf5);
const char *create_remote_thread_obf,
uint64_t obf1,
const char *write_process_memory_obf,
uint64_t obf2, const char *virtual_alloc_ex_obf,
uint64_t obf3, const char *virtual_free_ex_obf,
uint64_t obf4, const char *load_library_w_obf,
uint64_t obf5);
extern int inject_library_safe_obf(DWORD thread_id, const wchar_t *dll,
const char *set_windows_hook_ex_obf, uint64_t obf1);
const char *set_windows_hook_ex_obf,
uint64_t obf1);

View File

@@ -12,7 +12,7 @@ extern struct graphics_offsets offsets32;
extern struct graphics_offsets offsets64;
static inline bool load_offsets_from_string(struct graphics_offsets *offsets,
const char *str)
const char *str)
{
config_t *config;
@@ -46,7 +46,7 @@ static inline bool load_offsets_from_string(struct graphics_offsets *offsets,
}
static inline bool load_offsets_from_file(struct graphics_offsets *offsets,
const char *file)
const char *file)
{
char *str = os_quick_read_utf8_file(file);
bool success = false;
@@ -56,15 +56,14 @@ static inline bool load_offsets_from_file(struct graphics_offsets *offsets,
return success;
}
static inline bool config_ver_mismatch(
config_t *ver_config,
const char *section,
struct win_version_info *ver)
static inline bool config_ver_mismatch(config_t *ver_config,
const char *section,
struct win_version_info *ver)
{
struct win_version_info config_ver;
bool mismatch = false;
#define get_sub_ver(subver) \
#define get_sub_ver(subver) \
config_ver.subver = (int)config_get_int(ver_config, section, #subver); \
mismatch |= config_ver.subver != ver->subver;
@@ -79,7 +78,7 @@ static inline bool config_ver_mismatch(
}
static inline void write_config_ver(config_t *ver_config, const char *section,
struct win_version_info *ver)
struct win_version_info *ver)
{
#define set_sub_ver(subver) \
config_set_int(ver_config, section, #subver, ver->subver);
@@ -93,7 +92,7 @@ static inline void write_config_ver(config_t *ver_config, const char *section,
}
static bool get_32bit_system_dll_ver(const wchar_t *system_lib,
struct win_version_info *ver)
struct win_version_info *ver)
{
wchar_t path[MAX_PATH];
UINT ret;
@@ -104,8 +103,10 @@ static bool get_32bit_system_dll_ver(const wchar_t *system_lib,
ret = GetSystemDirectoryW(path, MAX_PATH);
#endif
if (!ret) {
blog(LOG_ERROR, "Failed to get windows 32bit system path: "
"%lu", GetLastError());
blog(LOG_ERROR,
"Failed to get windows 32bit system path: "
"%lu",
GetLastError());
return false;
}
@@ -116,8 +117,8 @@ static bool get_32bit_system_dll_ver(const wchar_t *system_lib,
bool cached_versions_match(void)
{
struct win_version_info d3d8_ver = {0};
struct win_version_info d3d9_ver = {0};
struct win_version_info d3d8_ver = {0};
struct win_version_info d3d9_ver = {0};
struct win_version_info dxgi_ver = {0};
bool ver_mismatch = false;
config_t *config;
@@ -176,12 +177,13 @@ bool load_graphics_offsets(bool is32bit, const char *config_path)
pp = os_process_pipe_create(offset_exe_path, "r");
if (!pp) {
blog(LOG_INFO, "load_graphics_offsets: Failed to start '%s'",
offset_exe.array);
offset_exe.array);
goto error;
}
for (;;) {
size_t len = os_process_pipe_read(pp, (uint8_t*)data, sizeof(data));
size_t len =
os_process_pipe_read(pp, (uint8_t *)data, sizeof(data));
if (!len)
break;
@@ -189,13 +191,15 @@ bool load_graphics_offsets(bool is32bit, const char *config_path)
}
if (dstr_is_empty(&str)) {
blog(LOG_INFO, "load_graphics_offsets: Failed to read "
"from '%s'", offset_exe.array);
blog(LOG_INFO,
"load_graphics_offsets: Failed to read "
"from '%s'",
offset_exe.array);
goto error;
}
// uncomment this if you enable USE_HOOK_ADDRESS_CACHE
/*
/*
dstr_copy(&config_ini, config_path);
dstr_cat(&config_ini, is32bit ? "32.ini" : "64.ini");
@@ -205,7 +209,7 @@ bool load_graphics_offsets(bool is32bit, const char *config_path)
*/
success = load_offsets_from_string(is32bit ? &offsets32 : &offsets64,
str.array);
str.array);
if (!success) {
blog(LOG_INFO, "load_graphics_offsets: Failed to load string");
}
@@ -227,7 +231,7 @@ bool load_cached_graphics_offsets(bool is32bit, const char *config_path)
dstr_copy(&config_ini, config_path);
dstr_cat(&config_ini, is32bit ? "32.ini" : "64.ini");
success = load_offsets_from_file(is32bit ? &offsets32 : &offsets64,
config_ini.array);
config_ini.array);
if (!success)
success = load_graphics_offsets(is32bit, config_path);

View File

@@ -1,27 +1,31 @@
#include <util/dstr.h>
#include "dc-capture.h"
/* clang-format off */
#define TEXT_MONITOR_CAPTURE obs_module_text("MonitorCapture")
#define TEXT_CAPTURE_CURSOR obs_module_text("CaptureCursor")
#define TEXT_COMPATIBILITY obs_module_text("Compatibility")
#define TEXT_MONITOR obs_module_text("Monitor")
#define TEXT_PRIMARY_MONITOR obs_module_text("PrimaryMonitor")
struct monitor_capture {
obs_source_t *source;
/* clang-format on */
int monitor;
bool capture_cursor;
bool compatibility;
struct monitor_capture {
obs_source_t *source;
int monitor;
bool capture_cursor;
bool compatibility;
struct dc_capture data;
};
struct monitor_info {
int cur_id;
int desired_id;
int id;
RECT rect;
int cur_id;
int desired_id;
int id;
RECT rect;
};
/* ------------------------------------------------------------------------- */
@@ -42,13 +46,13 @@ static inline void do_log(int level, const char *msg, ...)
}
static BOOL CALLBACK enum_monitor(HMONITOR handle, HDC hdc, LPRECT rect,
LPARAM param)
LPARAM param)
{
struct monitor_info *monitor = (struct monitor_info *)param;
if (monitor->cur_id == 0 || monitor->desired_id == monitor->cur_id) {
monitor->rect = *rect;
monitor->id = monitor->cur_id;
monitor->id = monitor->cur_id;
}
UNUSED_PARAMETER(hdc);
@@ -57,7 +61,7 @@ static BOOL CALLBACK enum_monitor(HMONITOR handle, HDC hdc, LPRECT rect,
}
static void update_monitor(struct monitor_capture *capture,
obs_data_t *settings)
obs_data_t *settings)
{
struct monitor_info monitor = {0};
uint32_t width, height;
@@ -67,7 +71,7 @@ static void update_monitor(struct monitor_capture *capture,
capture->monitor = monitor.id;
width = monitor.rect.right - monitor.rect.left;
width = monitor.rect.right - monitor.rect.left;
height = monitor.rect.bottom - monitor.rect.top;
dc_capture_init(&capture->data, monitor.rect.left, monitor.rect.top,
@@ -76,11 +80,11 @@ static void update_monitor(struct monitor_capture *capture,
}
static inline void update_settings(struct monitor_capture *capture,
obs_data_t *settings)
obs_data_t *settings)
{
capture->monitor = (int)obs_data_get_int(settings, "monitor");
capture->monitor = (int)obs_data_get_int(settings, "monitor");
capture->capture_cursor = obs_data_get_bool(settings, "capture_cursor");
capture->compatibility = obs_data_get_bool(settings, "compatibility");
capture->compatibility = obs_data_get_bool(settings, "compatibility");
dc_capture_free(&capture->data);
update_monitor(capture, settings);
@@ -148,7 +152,7 @@ static void monitor_capture_render(void *data, gs_effect_t *effect)
{
struct monitor_capture *capture = data;
dc_capture_render(&capture->data,
obs_get_base_effect(OBS_EFFECT_OPAQUE));
obs_get_base_effect(OBS_EFFECT_OPAQUE));
UNUSED_PARAMETER(effect);
}
@@ -166,43 +170,38 @@ static uint32_t monitor_capture_height(void *data)
}
static BOOL CALLBACK enum_monitor_props(HMONITOR handle, HDC hdc, LPRECT rect,
LPARAM param)
LPARAM param)
{
UNUSED_PARAMETER(hdc);
UNUSED_PARAMETER(rect);
obs_property_t *monitor_list = (obs_property_t*)param;
obs_property_t *monitor_list = (obs_property_t *)param;
MONITORINFO mi;
size_t monitor_id = 0;
struct dstr monitor_desc = { 0 };
struct dstr resolution = { 0 };
struct dstr format_string = { 0 };
struct dstr monitor_desc = {0};
struct dstr resolution = {0};
struct dstr format_string = {0};
monitor_id = obs_property_list_item_count(monitor_list);
mi.cbSize = sizeof(mi);
GetMonitorInfo(handle, &mi);
dstr_catf(&resolution,
"%dx%d @ %d,%d",
mi.rcMonitor.right - mi.rcMonitor.left,
mi.rcMonitor.bottom - mi.rcMonitor.top,
mi.rcMonitor.left,
mi.rcMonitor.top);
dstr_catf(&resolution, "%dx%d @ %d,%d",
mi.rcMonitor.right - mi.rcMonitor.left,
mi.rcMonitor.bottom - mi.rcMonitor.top, mi.rcMonitor.left,
mi.rcMonitor.top);
dstr_copy(&format_string, "%s %d: %s");
if (mi.dwFlags == MONITORINFOF_PRIMARY) {
dstr_catf(&format_string, " (%s)", TEXT_PRIMARY_MONITOR);
}
dstr_catf(&monitor_desc,
format_string.array,
TEXT_MONITOR,
monitor_id + 1,
resolution.array);
dstr_catf(&monitor_desc, format_string.array, TEXT_MONITOR,
monitor_id + 1, resolution.array);
obs_property_list_add_int(monitor_list,
monitor_desc.array, (int)monitor_id);
obs_property_list_add_int(monitor_list, monitor_desc.array,
(int)monitor_id);
dstr_free(&monitor_desc);
dstr_free(&resolution);
@@ -217,9 +216,9 @@ static obs_properties_t *monitor_capture_properties(void *unused)
obs_properties_t *props = obs_properties_create();
obs_property_t *monitors = obs_properties_add_list(props,
"monitor", TEXT_MONITOR,
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_t *monitors = obs_properties_add_list(
props, "monitor", TEXT_MONITOR, OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_properties_add_bool(props, "compatibility", TEXT_COMPATIBILITY);
obs_properties_add_bool(props, "capture_cursor", TEXT_CAPTURE_CURSOR);
@@ -230,18 +229,18 @@ static obs_properties_t *monitor_capture_properties(void *unused)
}
struct obs_source_info monitor_capture_info = {
.id = "monitor_capture",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW |
OBS_SOURCE_DO_NOT_DUPLICATE,
.get_name = monitor_capture_getname,
.create = monitor_capture_create,
.destroy = monitor_capture_destroy,
.video_render = monitor_capture_render,
.video_tick = monitor_capture_tick,
.update = monitor_capture_update,
.get_width = monitor_capture_width,
.get_height = monitor_capture_height,
.get_defaults = monitor_capture_defaults,
.get_properties = monitor_capture_properties
.id = "monitor_capture",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW |
OBS_SOURCE_DO_NOT_DUPLICATE,
.get_name = monitor_capture_getname,
.create = monitor_capture_create,
.destroy = monitor_capture_destroy,
.video_render = monitor_capture_render,
.video_tick = monitor_capture_tick,
.update = monitor_capture_update,
.get_width = monitor_capture_width,
.get_height = monitor_capture_height,
.get_defaults = monitor_capture_defaults,
.get_properties = monitor_capture_properties,
};

View File

@@ -6,18 +6,18 @@
#define THREAD_WAIT_REASON_SUSPENDED 5
typedef struct _OBS_SYSTEM_PROCESS_INFORMATION2 {
ULONG NextEntryOffset;
ULONG ThreadCount;
BYTE Reserved1[48];
PVOID Reserved2[3];
HANDLE UniqueProcessId;
PVOID Reserved3;
ULONG HandleCount;
BYTE Reserved4[4];
PVOID Reserved5[11];
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER Reserved6[6];
ULONG NextEntryOffset;
ULONG ThreadCount;
BYTE Reserved1[48];
PVOID Reserved2[3];
HANDLE UniqueProcessId;
PVOID Reserved3;
ULONG HandleCount;
BYTE Reserved4[4];
PVOID Reserved5[11];
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER Reserved6[6];
} OBS_SYSTEM_PROCESS_INFORMATION2;
typedef struct _OBS_SYSTEM_THREAD_INFORMATION {
@@ -40,22 +40,25 @@ typedef struct _OBS_SYSTEM_THREAD_INFORMATION {
#define NT_SUCCESS(status) ((NTSTATUS)(status) >= 0)
#endif
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define init_named_attribs(o, name) \
do { \
(o)->Length = sizeof(*(o)); \
(o)->ObjectName = name; \
(o)->RootDirectory = NULL; \
(o)->Attributes = 0; \
(o)->SecurityDescriptor = NULL; \
#define init_named_attribs(o, name) \
do { \
(o)->Length = sizeof(*(o)); \
(o)->ObjectName = name; \
(o)->RootDirectory = NULL; \
(o)->Attributes = 0; \
(o)->SecurityDescriptor = NULL; \
(o)->SecurityQualityOfService = NULL; \
} while (false)
typedef void (WINAPI *RTLINITUNICODESTRINGFUNC)(PCUNICODE_STRING pstr, const wchar_t *lpstrName);
typedef NTSTATUS (WINAPI *NTOPENFUNC)(PHANDLE phandle, ACCESS_MASK access, POBJECT_ATTRIBUTES objattr);
typedef ULONG (WINAPI *RTLNTSTATUSTODOSERRORFUNC)(NTSTATUS status);
typedef NTSTATUS (WINAPI *NTQUERYSYSTEMINFORMATIONFUNC)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
typedef void(WINAPI *RTLINITUNICODESTRINGFUNC)(PCUNICODE_STRING pstr,
const wchar_t *lpstrName);
typedef NTSTATUS(WINAPI *NTOPENFUNC)(PHANDLE phandle, ACCESS_MASK access,
POBJECT_ATTRIBUTES objattr);
typedef ULONG(WINAPI *RTLNTSTATUSTODOSERRORFUNC)(NTSTATUS status);
typedef NTSTATUS(WINAPI *NTQUERYSYSTEMINFORMATIONFUNC)(SYSTEM_INFORMATION_CLASS,
PVOID, ULONG, PULONG);
static FARPROC get_nt_func(const char *name)
{
@@ -76,7 +79,7 @@ static void nt_set_last_error(NTSTATUS status)
if (!initialized) {
func = (RTLNTSTATUSTODOSERRORFUNC)get_nt_func(
"RtlNtStatusToDosError");
"RtlNtStatusToDosError");
initialized = true;
}
@@ -91,7 +94,7 @@ static void rtl_init_str(UNICODE_STRING *unistr, const wchar_t *str)
if (!initialized) {
func = (RTLINITUNICODESTRINGFUNC)get_nt_func(
"RtlInitUnicodeString");
"RtlInitUnicodeString");
initialized = true;
}
@@ -100,14 +103,14 @@ static void rtl_init_str(UNICODE_STRING *unistr, const wchar_t *str)
}
static NTSTATUS nt_query_information(SYSTEM_INFORMATION_CLASS info_class,
PVOID info, ULONG info_len, PULONG ret_len)
PVOID info, ULONG info_len, PULONG ret_len)
{
static bool initialized = false;
static NTQUERYSYSTEMINFORMATIONFUNC func = NULL;
if (!initialized) {
func = (NTQUERYSYSTEMINFORMATIONFUNC)get_nt_func(
"NtQuerySystemInformation");
"NtQuerySystemInformation");
initialized = true;
}
@@ -124,7 +127,7 @@ static bool thread_is_suspended(DWORD process_id, DWORD thread_id)
for (;;) {
NTSTATUS stat = nt_query_information(SystemProcessInformation,
data, size, &size);
data, size, &size);
if (NT_SUCCESS(stat))
break;
@@ -148,12 +151,12 @@ static bool thread_is_suspended(DWORD process_id, DWORD thread_id)
if (!offset)
goto fail;
spi = (OBS_SYSTEM_PROCESS_INFORMATION2*)((BYTE*)spi + offset);
spi = (OBS_SYSTEM_PROCESS_INFORMATION2 *)((BYTE *)spi + offset);
}
OBS_SYSTEM_THREAD_INFORMATION *sti;
OBS_SYSTEM_THREAD_INFORMATION *info = NULL;
sti = (OBS_SYSTEM_THREAD_INFORMATION*)((BYTE*)spi + sizeof(*spi));
sti = (OBS_SYSTEM_THREAD_INFORMATION *)((BYTE *)spi + sizeof(*spi));
for (ULONG i = 0; i < spi->ThreadCount; i++) {
if (sti[i].UniqueThreadId == (HANDLE)(DWORD_PTR)thread_id) {
@@ -164,7 +167,7 @@ static bool thread_is_suspended(DWORD process_id, DWORD thread_id)
if (info) {
suspended = info->ThreadState == THREAD_STATE_WAITING &&
info->WaitReason == THREAD_WAIT_REASON_SUSPENDED;
info->WaitReason == THREAD_WAIT_REASON_SUSPENDED;
}
fail:
@@ -172,33 +175,33 @@ fail:
return suspended;
}
#define MAKE_NT_OPEN_FUNC(func_name, nt_name, access) \
static HANDLE func_name(const wchar_t *name) \
{ \
static bool initialized = false; \
static NTOPENFUNC open = NULL; \
HANDLE handle; \
NTSTATUS status; \
UNICODE_STRING unistr; \
OBJECT_ATTRIBUTES attr; \
\
if (!initialized) { \
open = (NTOPENFUNC)get_nt_func(#nt_name); \
initialized = true; \
} \
\
if (!open) \
return NULL; \
\
rtl_init_str(&unistr, name); \
init_named_attribs(&attr, &unistr); \
\
status = open(&handle, access, &attr); \
if (NT_SUCCESS(status)) \
return handle; \
nt_set_last_error(status); \
return NULL; \
}
#define MAKE_NT_OPEN_FUNC(func_name, nt_name, access) \
static HANDLE func_name(const wchar_t *name) \
{ \
static bool initialized = false; \
static NTOPENFUNC open = NULL; \
HANDLE handle; \
NTSTATUS status; \
UNICODE_STRING unistr; \
OBJECT_ATTRIBUTES attr; \
\
if (!initialized) { \
open = (NTOPENFUNC)get_nt_func(#nt_name); \
initialized = true; \
} \
\
if (!open) \
return NULL; \
\
rtl_init_str(&unistr, name); \
init_named_attribs(&attr, &unistr); \
\
status = open(&handle, access, &attr); \
if (NT_SUCCESS(status)) \
return handle; \
nt_set_last_error(status); \
return NULL; \
}
MAKE_NT_OPEN_FUNC(nt_open_mutex, NtOpenMutant, SYNCHRONIZE)
MAKE_NT_OPEN_FUNC(nt_open_event, NtOpenEvent, EVENT_MODIFY_STATE | SYNCHRONIZE)

View File

@@ -6,21 +6,20 @@
#include <windows.h>
#include "obfuscate.h"
#define LOWER_HALFBYTE(x) ((x) & 0xF)
#define LOWER_HALFBYTE(x) ((x)&0xF)
#define UPPER_HALFBYTE(x) (((x) >> 4) & 0xF)
static void deobfuscate_str(char *str, uint64_t val)
{
uint8_t *dec_val = (uint8_t*)&val;
uint8_t *dec_val = (uint8_t *)&val;
int i = 0;
while (*str != 0) {
int pos = i / 2;
bool bottom = (i % 2) == 0;
uint8_t *ch = (uint8_t*)str;
uint8_t xor = bottom ?
LOWER_HALFBYTE(dec_val[pos]) :
UPPER_HALFBYTE(dec_val[pos]);
uint8_t *ch = (uint8_t *)str;
uint8_t xor = bottom ? LOWER_HALFBYTE(dec_val[pos])
: UPPER_HALFBYTE(dec_val[pos]);
*ch ^= xor;

View File

@@ -7,7 +7,7 @@ extern "C" {
#endif
/* this is a workaround to A/Vs going crazy whenever certain functions (such as
* OpenProcess) are used */
* OpenProcess) are used */
extern void *get_obfuscated_func(HMODULE module, const char *str, uint64_t val);
#ifdef __cplusplus

View File

@@ -37,8 +37,7 @@ static DWORD WINAPI init_hooks(LPVOID param)
{
char *config_path = param;
if (USE_HOOK_ADDRESS_CACHE &&
cached_versions_match() &&
if (USE_HOOK_ADDRESS_CACHE && cached_versions_match() &&
load_cached_graphics_offsets(IS32BIT, config_path)) {
load_cached_graphics_offsets(!IS32BIT, config_path);
@@ -95,7 +94,8 @@ bool obs_module_load(void)
char *config_path = obs_module_config_path(NULL);
init_hooks_thread = CreateThread(NULL, 0, init_hooks, config_path, 0, NULL);
init_hooks_thread =
CreateThread(NULL, 0, init_hooks, config_path, 0, NULL);
obs_register_source(&game_capture_info);
return true;

View File

@@ -3,6 +3,8 @@
#include "dc-capture.h"
#include "window-helpers.h"
/* clang-format off */
#define TEXT_WINDOW_CAPTURE obs_module_text("WindowCapture")
#define TEXT_WINDOW obs_module_text("WindowCapture.Window")
#define TEXT_MATCH_PRIORITY obs_module_text("WindowCapture.Priority")
@@ -12,31 +14,33 @@
#define TEXT_CAPTURE_CURSOR obs_module_text("CaptureCursor")
#define TEXT_COMPATIBILITY obs_module_text("Compatibility")
/* clang-format on */
struct window_capture {
obs_source_t *source;
obs_source_t *source;
char *title;
char *class;
char *executable;
char *title;
char *class;
char *executable;
enum window_priority priority;
bool cursor;
bool compatibility;
bool use_wildcards; /* TODO */
bool cursor;
bool compatibility;
bool use_wildcards; /* TODO */
struct dc_capture capture;
struct dc_capture capture;
float resize_timer;
float check_window_timer;
float cursor_check_time;
float resize_timer;
float check_window_timer;
float cursor_check_time;
HWND window;
RECT last_rect;
HWND window;
RECT last_rect;
};
static void update_settings(struct window_capture *wc, obs_data_t *s)
{
const char *window = obs_data_get_string(s, "window");
int priority = (int)obs_data_get_int(s, "priority");
const char *window = obs_data_get_string(s, "window");
int priority = (int)obs_data_get_int(s, "priority");
bfree(wc->title);
bfree(wc->class);
@@ -45,15 +49,15 @@ static void update_settings(struct window_capture *wc, obs_data_t *s)
build_window_strings(window, &wc->class, &wc->title, &wc->executable);
if (wc->title != NULL) {
blog(LOG_INFO, "[window-capture: '%s'] update settings:\n"
"\texecutable: %s",
obs_source_get_name(wc->source),
wc->executable);
blog(LOG_INFO,
"[window-capture: '%s'] update settings:\n"
"\texecutable: %s",
obs_source_get_name(wc->source), wc->executable);
blog(LOG_DEBUG, "\tclass: %s", wc->class);
}
wc->priority = (enum window_priority)priority;
wc->cursor = obs_data_get_bool(s, "cursor");
wc->priority = (enum window_priority)priority;
wc->cursor = obs_data_get_bool(s, "cursor");
wc->use_wildcards = obs_data_get_bool(s, "use_wildcards");
wc->compatibility = obs_data_get_bool(s, "compatibility");
}
@@ -127,14 +131,15 @@ static obs_properties_t *wc_properties(void *unused)
obs_property_t *p;
p = obs_properties_add_list(ppts, "window", TEXT_WINDOW,
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_STRING);
fill_window_list(p, EXCLUDE_MINIMIZED, NULL);
p = obs_properties_add_list(ppts, "priority", TEXT_MATCH_PRIORITY,
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_list_add_int(p, TEXT_MATCH_TITLE, WINDOW_PRIORITY_TITLE);
obs_property_list_add_int(p, TEXT_MATCH_CLASS, WINDOW_PRIORITY_CLASS);
obs_property_list_add_int(p, TEXT_MATCH_EXE, WINDOW_PRIORITY_EXE);
obs_property_list_add_int(p, TEXT_MATCH_EXE, WINDOW_PRIORITY_EXE);
obs_properties_add_bool(ppts, "cursor", TEXT_CAPTURE_CURSOR);
@@ -170,7 +175,7 @@ static void wc_tick(void *data, float seconds)
wc->check_window_timer = 0.0f;
wc->window = find_window(EXCLUDE_MINIMIZED, wc->priority,
wc->class, wc->title, wc->executable);
wc->class, wc->title, wc->executable);
if (!wc->window) {
if (wc->capture.valid)
dc_capture_free(&wc->capture);
@@ -188,13 +193,15 @@ static void wc_tick(void *data, float seconds)
DWORD foreground_pid, target_pid;
// Can't just compare the window handle in case of app with child windows
if (!GetWindowThreadProcessId(GetForegroundWindow(), &foreground_pid))
if (!GetWindowThreadProcessId(GetForegroundWindow(),
&foreground_pid))
foreground_pid = 0;
if (!GetWindowThreadProcessId(wc->window, &target_pid))
target_pid = 0;
if (foreground_pid && target_pid && foreground_pid != target_pid)
if (foreground_pid && target_pid &&
foreground_pid != target_pid)
wc->capture.cursor_hidden = true;
else
wc->capture.cursor_hidden = false;
@@ -211,7 +218,7 @@ static void wc_tick(void *data, float seconds)
if (wc->resize_timer >= RESIZE_CHECK_TIME) {
if (rect.bottom != wc->last_rect.bottom ||
rect.right != wc->last_rect.right)
rect.right != wc->last_rect.right)
reset_capture = true;
wc->resize_timer = 0.0f;
@@ -239,17 +246,17 @@ static void wc_render(void *data, gs_effect_t *effect)
}
struct obs_source_info window_capture_info = {
.id = "window_capture",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW,
.get_name = wc_getname,
.create = wc_create,
.destroy = wc_destroy,
.update = wc_update,
.video_render = wc_render,
.video_tick = wc_tick,
.get_width = wc_width,
.get_height = wc_height,
.get_defaults = wc_defaults,
.get_properties = wc_properties
.id = "window_capture",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW,
.get_name = wc_getname,
.create = wc_create,
.destroy = wc_destroy,
.update = wc_update,
.video_render = wc_render,
.video_tick = wc_tick,
.get_width = wc_width,
.get_height = wc_height,
.get_defaults = wc_defaults,
.get_properties = wc_properties,
};

View File

@@ -22,16 +22,14 @@ static inline char *decode_str(const char *src)
return str.array;
}
extern void build_window_strings(const char *str,
char **class,
char **title,
char **exe)
extern void build_window_strings(const char *str, char **class, char **title,
char **exe)
{
char **strlist;
*class = NULL;
*title = NULL;
*exe = NULL;
*exe = NULL;
if (!str) {
return;
@@ -42,7 +40,7 @@ extern void build_window_strings(const char *str,
if (strlist && strlist[0] && strlist[1] && strlist[2]) {
*title = decode_str(strlist[0]);
*class = decode_str(strlist[1]);
*exe = decode_str(strlist[2]);
*exe = decode_str(strlist[2]);
}
strlist_free(strlist);
@@ -57,24 +55,24 @@ static HMODULE kernel32(void)
}
static inline HANDLE open_process(DWORD desired_access, bool inherit_handle,
DWORD process_id)
DWORD process_id)
{
static HANDLE (WINAPI *open_process_proc)(DWORD, BOOL, DWORD) = NULL;
static HANDLE(WINAPI * open_process_proc)(DWORD, BOOL, DWORD) = NULL;
if (!open_process_proc)
open_process_proc = get_obfuscated_func(kernel32(),
"B}caZyah`~q", 0x2D5BEBAF6DDULL);
open_process_proc = get_obfuscated_func(
kernel32(), "B}caZyah`~q", 0x2D5BEBAF6DDULL);
return open_process_proc(desired_access, inherit_handle, process_id);
}
bool get_window_exe(struct dstr *name, HWND window)
{
wchar_t wname[MAX_PATH];
struct dstr temp = {0};
bool success = false;
HANDLE process = NULL;
char *slash;
DWORD id;
wchar_t wname[MAX_PATH];
struct dstr temp = {0};
bool success = false;
HANDLE process = NULL;
char *slash;
DWORD id;
GetWindowThreadProcessId(window, &id);
if (id == GetCurrentProcessId())
@@ -92,7 +90,7 @@ bool get_window_exe(struct dstr *name, HWND window)
if (!slash)
goto fail;
dstr_copy(name, slash+1);
dstr_copy(name, slash + 1);
success = true;
fail:
@@ -113,8 +111,8 @@ void get_window_title(struct dstr *name, HWND hwnd)
if (!len)
return;
temp = malloc(sizeof(wchar_t) * (len+1));
if (GetWindowTextW(hwnd, temp, len+1))
temp = malloc(sizeof(wchar_t) * (len + 1));
if (GetWindowTextW(hwnd, temp, len + 1))
dstr_from_wcs(name, temp);
free(temp);
}
@@ -136,7 +134,7 @@ static const char *internal_microsoft_exes[] = {
"winstore.app",
"searchui",
"lockapp",
NULL
NULL,
};
static bool is_microsoft_internal_window_exe(const char *exe)
@@ -154,11 +152,11 @@ static bool is_microsoft_internal_window_exe(const char *exe)
static void add_window(obs_property_t *p, HWND hwnd, add_window_cb callback)
{
struct dstr class = {0};
struct dstr title = {0};
struct dstr exe = {0};
struct dstr class = {0};
struct dstr title = {0};
struct dstr exe = {0};
struct dstr encoded = {0};
struct dstr desc = {0};
struct dstr desc = {0};
if (!get_window_exe(&exe, hwnd))
return;
@@ -207,14 +205,14 @@ static void add_window(obs_property_t *p, HWND hwnd, add_window_cb callback)
static bool check_window_valid(HWND window, enum window_search_mode mode)
{
DWORD styles, ex_styles;
RECT rect;
RECT rect;
if (!IsWindowVisible(window) ||
(mode == EXCLUDE_MINIMIZED && IsIconic(window)))
return false;
GetClientRect(window, &rect);
styles = (DWORD)GetWindowLongPtr(window, GWL_STYLE);
styles = (DWORD)GetWindowLongPtr(window, GWL_STYLE);
ex_styles = (DWORD)GetWindowLongPtr(window, GWL_EXSTYLE);
if (ex_styles & WS_EX_TOOLWINDOW)
@@ -259,8 +257,8 @@ HWND get_uwp_actual_window(HWND parent)
return NULL;
}
static HWND next_window(HWND window, enum window_search_mode mode,
HWND *parent, bool use_findwindowex)
static HWND next_window(HWND window, enum window_search_mode mode, HWND *parent,
bool use_findwindowex)
{
if (*parent) {
window = *parent;
@@ -270,7 +268,7 @@ static HWND next_window(HWND window, enum window_search_mode mode,
while (true) {
if (use_findwindowex)
window = FindWindowEx(GetDesktopWindow(), window, NULL,
NULL);
NULL);
else
window = GetNextWindow(window, GW_HWNDNEXT);
@@ -290,7 +288,7 @@ static HWND next_window(HWND window, enum window_search_mode mode,
}
static HWND first_window(enum window_search_mode mode, HWND *parent,
bool *use_findwindowex)
bool *use_findwindowex)
{
HWND window = FindWindowEx(GetDesktopWindow(), NULL, NULL, NULL);
@@ -312,7 +310,7 @@ static HWND first_window(enum window_search_mode mode, HWND *parent,
window = GetWindow(GetDesktopWindow(), GW_CHILD);
if (!check_window_valid(window, mode))
window = next_window(window, mode, parent,
*use_findwindowex);
*use_findwindowex);
}
}
@@ -328,7 +326,7 @@ static HWND first_window(enum window_search_mode mode, HWND *parent,
}
void fill_window_list(obs_property_t *p, enum window_search_mode mode,
add_window_cb callback)
add_window_cb callback)
{
HWND parent;
bool use_findwindowex = false;
@@ -341,16 +339,13 @@ void fill_window_list(obs_property_t *p, enum window_search_mode mode,
}
}
static int window_rating(HWND window,
enum window_priority priority,
const char *class,
const char *title,
const char *exe,
bool uwp_window)
static int window_rating(HWND window, enum window_priority priority,
const char *class, const char *title, const char *exe,
bool uwp_window)
{
struct dstr cur_class = {0};
struct dstr cur_title = {0};
struct dstr cur_exe = {0};
struct dstr cur_exe = {0};
int val = 0x7FFFFFFF;
if (!get_window_exe(&cur_exe, window))
@@ -388,27 +383,24 @@ static int window_rating(HWND window,
return val;
}
HWND find_window(enum window_search_mode mode,
enum window_priority priority,
const char *class,
const char *title,
const char *exe)
HWND find_window(enum window_search_mode mode, enum window_priority priority,
const char *class, const char *title, const char *exe)
{
HWND parent;
bool use_findwindowex = false;
HWND window = first_window(mode, &parent, &use_findwindowex);
HWND window = first_window(mode, &parent, &use_findwindowex);
HWND best_window = NULL;
int best_rating = 0x7FFFFFFF;
int best_rating = 0x7FFFFFFF;
if (!class)
return NULL;
bool uwp_window = strcmp(class, "Windows.UI.Core.CoreWindow") == 0;
bool uwp_window = strcmp(class, "Windows.UI.Core.CoreWindow") == 0;
while (window) {
int rating = window_rating(window, priority, class, title, exe,
uwp_window);
uwp_window);
if (rating < best_rating) {
best_rating = rating;
best_window = window;

View File

@@ -10,7 +10,7 @@ enum window_priority {
enum window_search_mode {
INCLUDE_MINIMIZED,
EXCLUDE_MINIMIZED
EXCLUDE_MINIMIZED,
};
extern bool get_window_exe(struct dstr *name, HWND window);
@@ -20,18 +20,14 @@ extern bool is_uwp_window(HWND hwnd);
extern HWND get_uwp_actual_window(HWND parent);
typedef bool (*add_window_cb)(const char *title, const char *class,
const char *exe);
const char *exe);
extern void fill_window_list(obs_property_t *p, enum window_search_mode mode,
add_window_cb callback);
add_window_cb callback);
extern void build_window_strings(const char *str,
char **class,
char **title,
char **exe);
extern void build_window_strings(const char *str, char **class, char **title,
char **exe);
extern HWND find_window(enum window_search_mode mode,
enum window_priority priority,
const char *class,
const char *title,
const char *exe);
enum window_priority priority, const char *class,
const char *title, const char *exe);