Blob Blame History Raw
#include <psxtypes/psxtypes.h>
#include <pemagine/pemagine.h>
#include <ntapi/ntapi.h>
#include <gdi/gdi.h>

#ifndef GDI_ADDRESS_SPACE_OCD
#define GDI_ADDRESS_SPACE_OCD 0
#endif

int32_t __fastcall gdi_vtbl_init(gdi_vtbl * gdi)
{
	int32_t			status;
	void *			hgdi32;
	void *			huser32;

	ntapi_vtbl *		ntapi;
	struct dalist_ex	ldr_module_list;
	struct dalist_node *	node;

	uintptr_t		block[0x80];
	wchar16_t		gdi32_base_name[]  = {'g','d','i','3','2','.','d','l','l',0};
	wchar16_t		user32_base_name[] = {'u','s','e','r','3','2','.','d','l','l',0};

	/* init */
	if ((status = ntapi_init(&ntapi)))
		return status;

	ntapi->tt_aligned_block_memset(
		block,0,sizeof(block));

	/* module list */
	if ((status = dalist_init_ex(
			&ldr_module_list,
			0,0,0,
			DALIST_MEMFN_CUSTOM)))
		return status;

	if ((status = dalist_deposit_memory_block(
			&ldr_module_list,
			block,sizeof(block))))
		return status;

	if ((status = ntapi->ldr_create_state_snapshot(
			&ldr_module_list)))
		return status;

	/* load gdi32 (explicit), user32 (implicit) */
	hgdi32  = 0;
	huser32 = 0;

	if ((status = ntapi->ldr_load_system_dll(
			0,
			gdi32_base_name,
			sizeof(gdi32_base_name),
			0,&hgdi32)))
		return status;

	hgdi32  = pe_get_module_handle(gdi32_base_name);
	huser32 = pe_get_module_handle(user32_base_name);

	if (!hgdi32 || !huser32)
		return NT_STATUS_INTERNAL_ERROR;

	/* address space ocd */
	if ((status = dalist_get_node_by_key(
			&ldr_module_list,
			(struct dalist_node_ex **)&node,
			(uintptr_t)hgdi32,
			DALIST_NODE_TYPE_EXISTING | DALIST_NODE_TYPE_NEW,
			0)))
		return status;

	if ((status = dalist_get_node_by_key(
			&ldr_module_list,
			(struct dalist_node_ex **)&node,
			(uintptr_t)huser32,
			DALIST_NODE_TYPE_EXISTING | DALIST_NODE_TYPE_NEW,
			0)))
		return status;

	if (GDI_ADDRESS_SPACE_OCD)
		if ((status = ntapi->ldr_revert_state_to_snapshot(&ldr_module_list)))
			return status;

	/* gdi vtbl */
	gdi->get_system_metrics = (gdi_get_system_metrics *)pe_get_procedure_address(
		huser32,
		"GetSystemMetrics");

	gdi->is_iconic = (gdi_is_iconic *)pe_get_procedure_address(
		huser32,
		"IsIconic");

	gdi->is_zoomed = (gdi_is_zoomed *)pe_get_procedure_address(
		huser32,
		"IsZoomed");

	gdi->peek_message = (gdi_peek_message *)pe_get_procedure_address(
		huser32,
		"PeekMessageW");

	gdi->move_window = (gdi_move_window *)pe_get_procedure_address(
		huser32,
		"MoveWindow");

	gdi->set_window_pos = (gdi_set_window_pos *)pe_get_procedure_address(
		huser32,
		"SetWindowPos");

	gdi->get_window_rect = (gdi_get_window_rect *)pe_get_procedure_address(
		huser32,
		"GetWindowRect");

	gdi->get_client_rect = (gdi_get_client_rect *)pe_get_procedure_address(
		huser32,
		"GetClientRect");

	gdi->get_desktop_window = (gdi_get_desktop_window *)pe_get_procedure_address(
		huser32,
		"GetDesktopWindow");

	if (sizeof(size_t) == 8)
		gdi->set_window_long_ptr = (gdi_set_window_long_ptr *)pe_get_procedure_address(
			huser32,
			"SetWindowLongPtrW");
	else
		gdi->set_window_long_ptr = (gdi_set_window_long_ptr *)pe_get_procedure_address(
			huser32,
			"SetWindowLongW");

	return NT_STATUS_SUCCESS;
}