0

Below code is working fine as 32bit application.(Compiled on gcc 4.6.3), I ported same code to 64bit application,it doesn't give the correct output.

#include <iostream>
#include <stdint.h>
using namespace std;
typedef unsigned long DWORD;
typedef unsigned long long int  uint64;
typedef long long LONGLONG;
typedef struct _SND_FILETIME
{
    DWORD dwLowDateTime;
    DWORD dwHighDateTime;
} SND_FILETIME, *SND_PFILETIME, *SND_LPFILETIME;

void FileTimeToUnixTime(const SND_FILETIME *pft, time_t *t)
{
#if BYTE_ORDER == LITTLE_ENDIAN
        LONGLONG ll = (LONGLONG)pft->dwHighDateTime;
        ll <<= 32;
        ll |= (LONGLONG)pft->dwLowDateTime;
#else
        LONGLONG ll = (LONGLONG)pft->dwLowDateTime;
        ll <<= 32;
        ll |= (LONGLONG)pft->dwHighDateTime;
#endif
        ll -= 116444736000000000LL;
        ll /= 10000000;
        *t = (time_t)ll;
        struct tm *info = localtime(t);
       cout << "Time" << asctime(info) << std::endl;
}
int main()
{
    uint64 time64 = 132385716359962190;
    SND_FILETIME* ptr = (SND_FILETIME*)&time64;
    cout <<"HighPart = " << ptr->dwHighDateTime <<endl;
    cout <<"lowPart = " << ptr->dwLowDateTime <<endl;
    time_t t;
    FileTimeToUnixTime(ptr,&t);
    return 0;
}

Output I'm getting for 32bit application:

HighPart = 30823451 lowPart = 2365103694 TimeTue Jul 7 10:30:35 2020

for 64bit application : HighPart = 140730490267024 lowPart = 132385716359962190 TimeTue Aug 11 02:12:08 23514

If I change the input to something like,

uint64 time64 = 132385716359962190;
    SND_FILETIME filetime;
    filetime.dwHighDateTime = 0;
    filetime.dwLowDateTime = 132385716359962190;
    SND_FILETIME* ptr=&filetime;
   
    cout <<"HighPart = " << ptr->dwHighDateTime <<endl;
    cout <<"lowPart = " << ptr->dwLowDateTime <<endl;
    time_t t;
    FileTimeToUnixTime(ptr,&t);

64bit application works. but I don't want to do this, as I'll have to change all code. Is there any way to get this work without changing code.

Please help!!!

Thanks,

nandkumar
  • 3
  • 2
  • 2
    That `SND_FILETIME* ptr = (SND_FILETIME*)&time64;` is undefined behaviour. You cannot reinterpret one type as another (unless either type is some `char` or `std::byte` type, with more restrictions if the destination is a class type). So there's no point advising how you might _seem to_ fix that wrong design. You should instead parse/copy the bits manually out of the int. (If you want to keep writing UB, you should at least check whether `DWORD` is the same size, but please don't keep UB.) – underscore_d Jul 08 '20 at 11:45
  • 3
    Since your code clearly depends on precise integer sizes I recommend that you dispense with `long` and use the size you mean in all places, i.e. `uint64_t`, `uint32_t`, `int64_t` and `int32_t`. You are including `stdint.h`, so use it. Incidentally your code worked for me using VC++ in both 32 bit and 64 bit versions. So it should be easy enough to fix. – john Jul 08 '20 at 11:46
  • 1
    Unrelated to your problem, but any symbol starting with an underscore and followed by an upper-case letter (like e.g. `_SND_FILETIME`) is reserved in *all* scopes. See e.g. [this](https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) for more details. – Some programmer dude Jul 08 '20 at 11:49
  • Yes, you caught me :) , also actual application is huge and due to time crunch I need to do this faster. – nandkumar Jul 08 '20 at 12:11
  • 1
    Code is full of macro stuff, did not use any types defined in STL (uint_xx) and uses types in naming conventions, asumtions on memory layout ... much to rework! – Klaus Jul 08 '20 at 12:56
  • By the way, why are you using Windows API and SDK naming conventions and types? Is it a port of a Windows application? – Some programmer dude Jul 08 '20 at 13:22
  • 1) Read this: https://www.viva64.com/en/l/full/ 2) Use Viva64 rules: https://www.viva64.com/en/w/#64CPP – AndreyKarpov Jul 09 '20 at 08:37

1 Answers1

0

Change the typedef of DWORD to:

typedef unsigned int DWORD;

Also, update uint64 to uint64_t which belongs to the stdint.h header.

Paul Roub
  • 36,322
  • 27
  • 84
  • 93