#include "../tdkpin_object_windows.h" #include #include static uint8_t g_dgroup[0x10000]; static uint8_t g_code[0x10000]; static uint8_t g_object[0x100]; static BOOL16 g_is_window; static Win16FarPtr g_window_proc; static Win16FarPtr g_property_object; static unsigned g_set_count; static unsigned g_remove_count; static uint16_t g_property_offsets[2]; static uint16_t g_property_values[2]; static unsigned g_set_window_long_calls; static Win16FarPtr g_installed_proc; static Win16FarPtr g_called_proc; static HWND16 g_called_window; static UINT16 g_called_message; static WPARAM16 g_called_wparam; static LPARAM16 g_called_lparam; Win16FarPtr g_object_windows_creating_object; LRESULT16 SetWindowLong16(HWND16 window, INT16 index, int32_t value) { assert(window == 0x77 && index == -4); g_set_window_long_calls++; g_installed_proc = (Win16FarPtr)(uint32_t)value; return 0; } LRESULT16 win16_call_window_proc( Win16FarPtr procedure, HWND16 window, UINT16 message, WPARAM16 wparam, LPARAM16 lparam) { g_called_proc = procedure; g_called_window = window; g_called_message = message; g_called_wparam = wparam; g_called_lparam = lparam; return (LRESULT16)0x12345678u; } BOOL16 SetProp16(HWND16 window, Win16FarPtr name, Win16Handle value) { assert(window == 0x77); assert(g_set_count < 2); g_property_offsets[g_set_count] = win16_far_offset(name); g_property_values[g_set_count] = value; g_set_count++; return 1; } Win16Handle RemoveProp16(HWND16 window, Win16FarPtr name) { assert(window == 0x77); assert(g_remove_count < 2); g_property_offsets[g_remove_count++] = win16_far_offset(name); return 0; } Win16Handle GetProp16(HWND16 window, Win16FarPtr name) { assert(window == 0x77); return win16_far_offset(name) == 0x067a ? win16_far_selector(g_property_object) : win16_far_offset(g_property_object); } BOOL16 IsWindow16(HWND16 window) { assert(window == 0x77); return g_is_window; } int32_t GetWindowLong16(HWND16 window, INT16 index) { assert(window == 0x77 && index == -4); return (int32_t)g_window_proc; } static void reset_state(void) { memset(g_dgroup, 0, sizeof(g_dgroup)); memset(g_code, 0, sizeof(g_code)); win16_reset_segment_bindings(); win16_bind_segment(0x5000, g_dgroup, sizeof(g_dgroup), true); win16_bind_segment(0x6000, g_code, sizeof(g_code), true); win16_bind_segment(0x7000, g_object, sizeof(g_object), true); win16_set_dgroup_selector(0x5000); g_is_window = 1; g_set_count = 0; g_remove_count = 0; g_set_window_long_calls = 0; } static void test_bootstrap_transition(void) { reset_state(); Win16FarPtr object = win16_make_far_pointer(0x7000, 0x0010); Win16FarPtr bound_proc = win16_make_far_pointer(0x6000, 0x0300); g_object_windows_creating_object = object; win16_write_u16(object, 0x12, win16_far_offset(bound_proc)); win16_write_u16(object, 0x14, win16_far_selector(bound_proc)); LRESULT16 result = object_window_bootstrap_proc( 0x77, 0x0123, 0x4567, (LPARAM16)0x89abcdefu); assert(result == (LRESULT16)0x12345678u); assert(g_set_window_long_calls == 1 && g_installed_proc == bound_proc); assert(g_set_count == 2); assert(g_property_values[0] == win16_far_selector(object)); assert(g_property_values[1] == win16_far_offset(object)); assert(g_called_proc == bound_proc && g_called_window == 0x77); assert(g_called_message == 0x0123 && g_called_wparam == 0x4567); assert(g_called_lparam == (LPARAM16)0x89abcdefu); } static void test_property_binding(void) { reset_state(); Win16FarPtr object = win16_make_far_pointer(0x3456, 0x789a); object_windows_bind_window(0x77, object); assert(g_set_count == 2); assert(g_property_offsets[0] == 0x067a && g_property_values[0] == 0x3456); assert(g_property_offsets[1] == 0x067e && g_property_values[1] == 0x789a); object_windows_unbind_window(0x77); assert(g_remove_count == 2); assert(g_property_offsets[0] == 0x067a && g_property_offsets[1] == 0x067e); } static void test_generated_thunk_lookup(void) { reset_state(); g_window_proc = win16_make_far_pointer(0x6000, 0x0100); Win16FarPtr object = win16_make_far_pointer(0x3456, 0x789a); g_code[2] = 0x5b; g_code[3] = 0x2e; g_code[0x0100] = 0xe8; g_code[0x0101] = 0xff; g_code[0x0102] = 0xfe; g_code[0x0103] = (uint8_t)object; g_code[0x0104] = (uint8_t)(object >> 8); g_code[0x0105] = (uint8_t)(object >> 16); g_code[0x0106] = (uint8_t)(object >> 24); assert(object_windows_object_from_window(0x77) == object); } static void test_property_fallback_and_invalid_window(void) { reset_state(); g_window_proc = win16_make_far_pointer(0x6000, 0x0200); g_property_object = win16_make_far_pointer(0x1111, 0x2222); assert(object_windows_object_from_window(0x77) == g_property_object); g_is_window = 0; assert(object_windows_object_from_window(0x77) == 0); } int main(void) { test_property_binding(); test_generated_thunk_lookup(); test_property_fallback_and_invalid_window(); test_bootstrap_transition(); return 0; }