Friday, December 22, 2006

Conversion macros\inline functions

sometimes you might need to convert (safely) between different Windows data types.
for example, consider this:

you have a dialog window procedure and you want to handle WM_CTLCOLOREDIT message to change the background color of the edit control.


BOOL CALLBACK DialogProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch(uMsg)
{
case WM_CTLCOLOREDIT:
return (BOOL)(GetStockObject(DKGRAY_BRUSH));
}
}

I followed the instructions from MSDN for WM_CTLCOLOREDIT:
"If a dialog box procedure handles this message, it should cast the desired return value to a BOOL and return the value directly."

the problem is it works but it gives a warning: Compiler Warning (level 1) C4311.
"This warning detects 64-bit portability issues. For example, if code is compiled on a 64-bit platform, the value of a pointer (64 bits) will be truncated if it is assigned to an int (32 bits). This warning is only issued when /Wp64 is used. "

I am using VisualC++ 2003 compiler so it seems /wp64 is put by default.

Now, MS made some inline conversion functions which must be used when converting data types.
this if found in intsafe.h header.

additional information can be found in a blog of a MS security guy:

http://blogs.msdn.com/michael_howard/archive/2006/02/02/523392.aspx

additionally, look at this info:
"Rules for Using Pointers" in MSDN

There are also some other conversion macros in Basetsd.h header made for win64 programming too:
void * Handle64ToHandle( const void * POINTER_64 h )
void * POINTER_64 HandleToHandle64( const void *h )
long HandleToLong( const void *h )
unsigned long HandleToUlong( const void *h )
void * IntToPtr( const int i )
void * LongToHandle( const long h )
void * LongToPtr( const long l )
void * Ptr64ToPtr( const void * POINTER_64 p )
int PtrToInt( const void *p )
long PtrToLong( const void *p )
void * POINTER_64 PtrToPtr64( const void *p )
short PtrToShort( const void *p )
unsigned int PtrToUint( const void *p )
unsigned long PtrToUlong( const void *p )
unsigned short PtrToUshort( const void *p )
void * UIntToPtr( const unsigned int ui )
void * ULongToPtr( const unsigned long ul )

look in MSDN here for more info.

For the above code, the inline conversion function to use is:

case WM_CTLCOLOREDIT:
return HandleToLong(GetStockObject(DKGRAY_BRUSH));
or:


case WM_CTLCOLOREDIT:
return (BOOL)(INT_PTR)(GetStockObject(DKGRAY_BRUSH));

No comments: