#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'};
wchar16_t user32_base_name[] = {'u','s','e','r','3','2','.','d','l','l'};
/* 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;
}