diff options
author | Guy Harris <guy@alum.mit.edu> | 2015-04-20 13:41:07 -0700 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2015-04-20 20:41:58 +0000 |
commit | b1bd95c440528f0d5049fb2daf4eb711120f9f01 (patch) | |
tree | 39931ace6a2656f8eb796b4641f28e09f025ed5b /wsutil | |
parent | b3299011126b56e154f7e0f473e6aaaccbac8387 (diff) | |
download | wireshark-b1bd95c440528f0d5049fb2daf4eb711120f9f01.tar.gz |
Have a common routine to convert FILETIME to nstime_t.
We had several copies of that code; put it into a filetime_to_nstime()
routine in wsutil, and call that common routine instead.
Change-Id: I1eb5579c36c129ff8d23f9212285ab3f63be0f43
Reviewed-on: https://code.wireshark.org/review/8142
Reviewed-by: Guy Harris <guy@alum.mit.edu>
(cherry picked from commit 94dc9cd113f5263a55ee86855a4642991f87a351)
Reviewed-on: https://code.wireshark.org/review/8143
Diffstat (limited to 'wsutil')
-rw-r--r-- | wsutil/nstime.c | 76 | ||||
-rw-r--r-- | wsutil/nstime.h | 4 |
2 files changed, 80 insertions, 0 deletions
diff --git a/wsutil/nstime.c b/wsutil/nstime.c index 439f31a783..ff6626abc1 100644 --- a/wsutil/nstime.c +++ b/wsutil/nstime.c @@ -187,6 +187,82 @@ double nstime_to_sec(const nstime_t *nstime) } /* + * Number of seconds between the UN*X epoch (January 1, 1970, 00:00:00 GMT) + * and the Windows NT epoch (January 1, 1601 in the proleptic Gregorian + * calendar, 00:00:00 "GMT") + * + * This is + * + * 369*365.25*24*60*60-(3*24*60*60+6*60*60) + * + * 1970-1601 is 369; 365.25 is the average length of a year in days, + * including leap years. + * + * 3 days are subtracted because 1700, 1800, and 1900 were not leap + * years, as, while they're all evenly divisible by 4, they're also + * evently divisible by 100, but not evently divisible by 400, so + * we need to compensate for using the average length of a year in + * days, which assumes a leap year every 4 years, *including* every + * 100 years. + * + * I'm not sure what the extra 6 hours are that are being subtracted. + */ +#define TIME_FIXUP_CONSTANT G_GUINT64_CONSTANT(11644473600) + +#ifndef TIME_T_MIN +#define TIME_T_MIN ((time_t) ((time_t)0 < (time_t) -1 ? (time_t) 0 \ + : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))) +#endif +#ifndef TIME_T_MAX +#define TIME_T_MAX ((time_t) (~ (time_t) 0 - TIME_T_MIN)) +#endif + +/* + * function: filetime_to_nstime + * converts a Windows FILETIME value to an nstime_t + * returns TRUE if the conversion succeeds, FALSE if it doesn't + * (for example, with a 32-bit time_t, the time overflows or + * underflows time_t) + */ +gboolean +filetime_to_nstime(nstime_t *nstime, guint64 filetime) +{ + /* + * This code is based on the Samba code: + * + * Unix SMB/Netbios implementation. + * Version 1.9. + * time handling functions + * Copyright (C) Andrew Tridgell 1992-1998 + */ + gint64 secs; + int nsecs; + /* The next two lines are a fix needed for the + broken SCO compiler. JRA. */ + time_t l_time_min = TIME_T_MIN; + time_t l_time_max = TIME_T_MAX; + + /* Split into seconds and nanoseconds. */ + secs = filetime / 10000000; + nsecs = (int)((filetime % 10000000)*100); + + /* Now adjust the seconds. */ + secs -= TIME_FIXUP_CONSTANT; + + if (!(l_time_min <= secs && secs <= l_time_max)) { + /* The result won't fit in a time_t */ + return FALSE; + } + + /* + * Get the time as seconds and nanoseconds. + */ + nstime->secs = (time_t) secs; + nstime->nsecs = nsecs; + return TRUE; +} + +/* * Editor modelines * * Local Variables: diff --git a/wsutil/nstime.h b/wsutil/nstime.h index a74457c8b6..c72daa19c6 100644 --- a/wsutil/nstime.h +++ b/wsutil/nstime.h @@ -102,6 +102,10 @@ WS_DLL_PUBLIC double nstime_to_msec(const nstime_t *nstime); /** converts nstime to double, time base is seconds */ WS_DLL_PUBLIC double nstime_to_sec(const nstime_t *nstime); +/** converts Windows FILETIME to nstime, returns TRUE on success, + FALSE on failure */ +WS_DLL_PUBLIC gboolean filetime_to_nstime(nstime_t *nstime, guint64 filetime); + #ifdef __cplusplus } #endif /* __cplusplus */ |