Search code examples
cvisual-studiowinapi64-bit

64bit windows api programming type casting problem


(Sorry for my bad English). I have 2 questions about 64bit c programming.

My code worked good but today I get error (no compiler or code analysis). And its randomly. For instance sometimes the code works sometimes it doesn't. When I open executable inside WinDbg my code always gets error. I think its 64bit type casting problem.

Code Sample:

DWORD hash_string_len = 0;
hash_string_len = (DWORD)strlen(hash_string); //hash_string is 32 character hash (A998B0FE08AB295072965B5A4B0C835E)
if (hash_string_len != (DWORD)(MD5_DIGEST_LENGTH * 2)) //MD5_DIGEST_LENGTH (#define MD5_DIGEST_LENGTH 16)
{
   debug_this(); //printf("%d\n",__LINE__)
   HeapFree(GetProcessHeap(), 0, ENGINE_HASHLIST_MD5_ENTRY);
   return FALSE;
}

Without WinDbg code don't print error (by debug_this()) but inside WinDbg code print Line number (reason is hash_string_len != 32) but I know hash_string_len = 32 so I think its 64 bit truncation problem. Can anybody help me?

My Second question is:

Can it give me error in 64bit programming?

DWORD a = 0;

some_func(&a);


some_func(PDWORD pA)
{
 *pA = 1;
}

Because I use a lot codes like this inside my project. Like that.

LZMA Lib

SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);

I call this function like that.

DWORD destLen = 0;
PBYTE dest = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(SIZE_T)1024);
LzmaDec_DecodeToBuf(...,dest,&destLen,...)

So I really have function problem in 64bit programming. Thanks for reading


Solution

  • Assuming SizeT is SIZE_T:

    I call this function like that.

    DWORD destLen = 0;
    PBYTE dest = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(SIZE_T)1024);
    LzmaDec_DecodeToBuf(...,dest,&destLen,...)
    

    Passing the address of DWORD (32bit wide on 32-bit-windows as well as on 64-bit-windows) to where the address of a SIZE_T (64bit wide on 64-bit-windows and 32bit wide on 32-bit-windows) is expected is bad.

    Cast the DWORD to SIZE_T before taking its address like this:

    LzmaDec_DecodeToBuf(..., dest, &((SIZE_T) destLen), ...)
    

    Introduce a temporay variable of SIZE_T and pass its address:

    {
      SIZE_T s = destLen; /* The initialisation is only necessary if
                             LzmaDec_DecodeToBuf() expects a value. */
      LzmaDec_DecodeToBuf(..., dest, &s, ...);
      if (((SIZE_T) UINT_MAX) < s) {
        /* handle overflow of destLen! */
      }
      destLen = s;
    }
    

    More on issue migrating code from 32bit to 64bit using VC on Windows are here: https://learn.microsoft.com/en-us/cpp/build/common-visual-cpp-64-bit-migration-issues?view=vs-2019