/* Caller should check for success and only call if syscall is successful (for !pre) */ static void syscall_check_gdi(bool pre, void *drcontext, drsys_sysnum_t sysnum, cls_syscall_t *pt, dr_mcontext_t *mc) { app_loc_t loc; ASSERT(options.check_gdi, "shouldn't be called"); if (drsys_sysnums_equal(&sysnum, &sysnum_UserGetDC) || drsys_sysnums_equal(&sysnum, &sysnum_UserGetDCEx) || drsys_sysnums_equal(&sysnum, &sysnum_UserGetWindowDC) || drsys_sysnums_equal(&sysnum, &sysnum_UserBeginPaint) || drsys_sysnums_equal(&sysnum, &sysnum_GdiGetDCforBitmap) || drsys_sysnums_equal(&sysnum, &sysnum_GdiDdGetDC)) { if (!pre) { HDC hdc = (HDC) dr_syscall_get_result(drcontext); /* i#1192: NtGdiGetDCforBitmap does not allocate a new DC * that needs to be freed. We leave it enabled as an * "allocation" to have more DC's in our table (presumably * adding in those created before we took over). */ uint flags = 0; if (!drsys_sysnums_equal(&sysnum, &sysnum_GdiGetDCforBitmap)) flags |= GDI_DC_ALLOC_GET; syscall_to_loc(&loc, sysnum, ""); gdicheck_dc_alloc(hdc, flags, sysnum, mc, &loc); if (drsys_sysnums_equal(&sysnum, &sysnum_UserBeginPaint)) { /* we store the hdc for access in EndPaint */ pt->paintDC = hdc; } } } else if (drsys_sysnums_equal(&sysnum, &sysnum_GdiCreateMetafileDC) || drsys_sysnums_equal(&sysnum, &sysnum_GdiCreateCompatibleDC) || drsys_sysnums_equal(&sysnum, &sysnum_GdiOpenDCW)) { if (!pre) { HDC hdc = (HDC) dr_syscall_get_result(drcontext); uint flags = GDI_DC_ALLOC_CREATE; if (drsys_sysnums_equal(&sysnum, &sysnum_GdiCreateCompatibleDC) && syscall_get_param(drcontext, 0) == 0) flags |= GDI_DC_ALLOC_DUP_NULL; syscall_to_loc(&loc, sysnum, ""); gdicheck_dc_alloc(hdc, flags, sysnum, mc, &loc); } } else if (drsys_sysnums_equal(&sysnum, &sysnum_UserReleaseDC) || drsys_sysnums_equal(&sysnum, &sysnum_UserEndPaint)) { if (pre) { HDC hdc; if (drsys_sysnums_equal(&sysnum, &sysnum_UserReleaseDC)) hdc = (HDC)syscall_get_param(drcontext, 0); else { hdc = pt->paintDC; pt->paintDC = NULL; } gdicheck_dc_free(hdc, false/*Get not Create*/, sysnum, mc); } } else if (drsys_sysnums_equal(&sysnum, &sysnum_GdiDeleteObjectApp)) { if (pre) gdicheck_obj_free((HANDLE)syscall_get_param(drcontext, 0), sysnum, mc); } }
static handle_create_info_t * handle_create_info_alloc(int sysnum, app_pc pc, dr_mcontext_t *mc) { handle_create_info_t *hci; hci = global_alloc(sizeof(*hci), HEAPSTAT_CALLSTACK); /* assuming pc will never be NULL */ if (pc == NULL) syscall_to_loc(&hci->loc, sysnum, NULL); else pc_to_loc(&hci->loc, pc); packed_callstack_record(&hci->pcs, mc, &hci->loc); return hci; }