Mandatory callback function that draws contenst of table cells. See Tables for the detailed description.
typedef int DRAWFUNC(wchar_t *s,uchar *mask,int *select,struct t_table *pt,t_sorthdr *ps,int column,void *cache);
Parameters:
s
(Out)
Pointer to the UNICODE string, at least TEXTLEN wide characters long,
that receives contents of the string to be drawn in the cell. This
buffer is not initialized. Null character at the end of the string is not required
mask
(Out)
Pointer to the byte array, at least TEXTLEN bytes long, that receives
individual drawing attributes of the corresponding characters in s
as a combinations of flags DRAW_xxx with numerical values not exceeding
0xFF. This buffer is not initialized. To use mask, set flag DRAW_MASK in *select
select
(Out)
Pointer to drawing attributes that apply to the string as a whole as a
combination of flags DRAW_xxx. On input, pointed variable is zeroed
pt
(In) Pointer to the table descriptor, a structure of type t_table
ps
(In,out) For standard tables, pointer to the displayed element of sorted data. For tables of type TABLE_USERDEF and TABLE_SIMPLE, pointer to the structure t_drawheader that tells drawing function which line is currently painted. Dedicated parts of t_drawheader may be used as a cache of fixed size
column
(In) Either zero-based index of the column to which the processed cell belongs (column>=0), or one of the constants DF_xxx indicating requests to prepare for drawing. See Tables for details
cache
(In,out) Pointer to the cache. Its size was determined by the drawing function during the first call with column=DF_CACHESIZE.
OllyDbg preserves contents of the cache during the whole drawing sequence and
guarantees that there is no interference with other tables, even if
they use the same drawing function. Note that cache may be NULL if requested cache size is 0
Return values:
If column is DF_CACHESIZE, this function must return the requested size of the data cache. If column is DF_FILLCACHE, DF_FREECACHE or DF_NEWROW, it must return 0. In all other cases, it must return the length of the displayed string s in wide characters (and, if mask is used, the length of the mask in bytes)
Example:
This
is the slightly modified drawing function of the INT3 Breakpoints window:
typedef struct { // Structure of internal draw cache
t_disasm da; // Disassembled command
ulong length; // Length of command (0: invalid)
} t_bpointcache;
int Bpointdraw(wchar *s,uchar *mask,int *select,t_table *pt,t_drawheader *ph,int column,void *cache) {
int n,mode;
ulong length;
uchar cmd[MAXCMDSIZE];
t_bpoint *pbrk;
t_bpointcache *pc;
t_module *pmod;
pbrk=(t_bpoint *)ph;
pc=(t_bpointcache *)cache;
n=0;
switch (column) {
case DF_CACHESIZE: // Request for draw cache size
return sizeof(t_bpointcache);
case DF_FILLCACHE: // Request to fill draw cache
break;
case DF_FREECACHE: // Request to free cached resources
break;
case DF_NEWROW: // Request to start new row in window
length=Readmemory(cmd,pbrk->addr,sizeof(cmd),MM_SILENT|MM_PARTIAL);
if (length>0)
length=Disasm(cmd,length,pbrk->addr,Finddecode(pbrk->addr,NULL),
&(pc->da),DA_TEXT|DA_OPCOMM|DA_MEMORY,NULL,NULL);
pc->length=length;
break;
case 0: // Address of INT3 breakpoint
n=Simpleaddress(s,pbrk->addr,mask,select);
break;
case 1: // Module name
pmod=Findmodule(pbrk->addr);
if (pmod==NULL) break;
n=StrcopyW(s,TEXTLEN,pmod->modname);
break;
case 2: // Breakpoint status
if (pbrk->type & BP_MANUAL) {
if (pbrk->type & BP_DISABLED)
n=StrcopyW(s,TEXTLEN,T(L"Disabled"));
else if (pbrk->type & BP_COND)
n=StrcopyW(s,TEXTLEN,T(L"Cond"));
else
n=StrcopyW(s,TEXTLEN,T(L"Active"));
; }
else if (pbrk->type & BP_ONESHOT)
n=StrcopyW(s,TEXTLEN,T(L"One-shot"));
else if (pbrk->type & BP_TEMP)
n=StrcopyW(s,TEXTLEN,T(L"Temporary"));
else if (pbrk->type & BP_TRACE)
n=StrcopyW(s,TEXTLEN,T(L"Trace"));
break;
case 3: // Disassembly
if (pc->length>0)
n=StrcopyW(s,TEXTLEN,pc->da.result);
break;
case 4: // Comment
n=Commentaddress(pbrk->addr,COMM_ALL,s,TEXTLEN);
if (n==0) n=StrcopyW(s,TEXTLEN,pc->da.comment);
*select|=DRAW_VARWIDTH;
break;
default: break;
};
return n;
};
typedef struct { // Structure of internal draw cache
t_disasm da; // Disassembled command
ulong length; // Length of command (0: invalid)
} t_bpointcache;
int Bpointdraw(wchar *s,uchar *mask,int *select,t_table *pt,t_drawheader *ph,int column,void *cache) {
int n,mode;
ulong length;
uchar cmd[MAXCMDSIZE];
t_bpoint *pbrk;
t_bpointcache *pc;
t_module *pmod;
pbrk=(t_bpoint *)ph;
pc=(t_bpointcache *)cache;
n=0;
switch (column) {
case DF_CACHESIZE: // Request for draw cache size
return sizeof(t_bpointcache);
case DF_FILLCACHE: // Request to fill draw cache
break;
case DF_FREECACHE: // Request to free cached resources
break;
case DF_NEWROW: // Request to start new row in window
length=Readmemory(cmd,pbrk->addr,sizeof(cmd),MM_SILENT|MM_PARTIAL);
if (length>0)
length=Disasm(cmd,length,pbrk->addr,Finddecode(pbrk->addr,NULL),
&(pc->da),DA_TEXT|DA_OPCOMM|DA_MEMORY,NULL,NULL);
pc->length=length;
break;
case 0: // Address of INT3 breakpoint
n=Simpleaddress(s,pbrk->addr,mask,select);
break;
case 1: // Module name
pmod=Findmodule(pbrk->addr);
if (pmod==NULL) break;
n=StrcopyW(s,TEXTLEN,pmod->modname);
break;
case 2: // Breakpoint status
if (pbrk->type & BP_MANUAL) {
if (pbrk->type & BP_DISABLED)
n=StrcopyW(s,TEXTLEN,T(L"Disabled"));
else if (pbrk->type & BP_COND)
n=StrcopyW(s,TEXTLEN,T(L"Cond"));
else
n=StrcopyW(s,TEXTLEN,T(L"Active"));
; }
else if (pbrk->type & BP_ONESHOT)
n=StrcopyW(s,TEXTLEN,T(L"One-shot"));
else if (pbrk->type & BP_TEMP)
n=StrcopyW(s,TEXTLEN,T(L"Temporary"));
else if (pbrk->type & BP_TRACE)
n=StrcopyW(s,TEXTLEN,T(L"Trace"));
break;
case 3: // Disassembly
if (pc->length>0)
n=StrcopyW(s,TEXTLEN,pc->da.result);
break;
case 4: // Comment
n=Commentaddress(pbrk->addr,COMM_ALL,s,TEXTLEN);
if (n==0) n=StrcopyW(s,TEXTLEN,pc->da.comment);
*select|=DRAW_VARWIDTH;
break;
default: break;
};
return n;
};
See also: