summaryrefslogtreecommitdiffhomepage
path: root/src/internal/gdi/gdi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/internal/gdi/gdi.c')
-rw-r--r--src/internal/gdi/gdi.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/src/internal/gdi/gdi.c b/src/internal/gdi/gdi.c
new file mode 100644
index 0000000..3edf1a2
--- /dev/null
+++ b/src/internal/gdi/gdi.c
@@ -0,0 +1,132 @@
+#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;
+}