|
23 | 23 | #include <fluent-bit/flb_utils.h> |
24 | 24 | #include <fluent-bit/flb_pack.h> |
25 | 25 | #include <fluent-bit/flb_input_plugin.h> |
| 26 | +#include <stdlib.h> |
26 | 27 | #include <msgpack.h> |
27 | 28 | #include <sddl.h> |
28 | 29 | #include <locale.h> |
@@ -265,39 +266,84 @@ static int pack_systemtime(struct winevtlog_config *ctx, SYSTEMTIME *st) |
265 | 266 |
|
266 | 267 | static int pack_filetime(struct winevtlog_config *ctx, ULONGLONG filetime) |
267 | 268 | { |
268 | | - LARGE_INTEGER timestamp; |
| 269 | + FILETIME ft; |
| 270 | + SYSTEMTIME st_utc; |
| 271 | + SYSTEMTIME st_local; |
| 272 | + DYNAMIC_TIME_ZONE_INFORMATION dtzi; |
269 | 273 | CHAR buf[64]; |
270 | | - size_t len = 0; |
271 | | - FILETIME ft, ft_local; |
272 | | - SYSTEMTIME st; |
| 274 | + size_t len; |
| 275 | + LONG bias_minutes; |
| 276 | + int offset_hours; |
| 277 | + int offset_minutes; |
| 278 | + char offset_sign; |
273 | 279 | _locale_t locale; |
| 280 | + DWORD tz_id; |
274 | 281 |
|
275 | 282 | _tzset(); |
276 | 283 |
|
277 | 284 | locale = _get_current_locale(); |
278 | 285 | if (locale == NULL) { |
279 | 286 | return -1; |
280 | 287 | } |
281 | | - timestamp.QuadPart = filetime; |
282 | | - ft.dwHighDateTime = timestamp.HighPart; |
283 | | - ft.dwLowDateTime = timestamp.LowPart; |
284 | | - FileTimeToLocalFileTime(&ft, &ft_local); |
285 | | - if (FileTimeToSystemTime(&ft_local, &st)) { |
286 | | - struct tm tm = {st.wSecond, st.wMinute, st.wHour, st.wDay, st.wMonth-1, st.wYear-1900, st.wDayOfWeek, 0, -1}; |
287 | | - len = _strftime_l(buf, 64, FORMAT_ISO8601, &tm, locale); |
288 | | - if (len == 0) { |
289 | | - flb_errno(); |
290 | | - _free_locale(locale); |
291 | | - return -1; |
292 | | - } |
| 288 | + |
| 289 | + ft.dwHighDateTime = (DWORD)(filetime >> 32); |
| 290 | + ft.dwLowDateTime = (DWORD)(filetime & 0xFFFFFFFF); |
| 291 | + |
| 292 | + if (!FileTimeToSystemTime(&ft, &st_utc)) { |
| 293 | + _free_locale(locale); |
| 294 | + return -1; |
| 295 | + } |
| 296 | + |
| 297 | + tz_id = GetDynamicTimeZoneInformation(&dtzi); |
| 298 | + |
| 299 | + if (!SystemTimeToTzSpecificLocalTimeEx(&dtzi, &st_utc, &st_local)) { |
293 | 300 | _free_locale(locale); |
| 301 | + return -1; |
| 302 | + } |
294 | 303 |
|
295 | | - flb_log_event_encoder_append_body_string(ctx->log_encoder, buf, len); |
| 304 | + /* Determine bias (minutes) */ |
| 305 | + bias_minutes = dtzi.Bias; |
| 306 | + |
| 307 | + if (tz_id == TIME_ZONE_ID_DAYLIGHT) { |
| 308 | + bias_minutes += dtzi.DaylightBias; |
| 309 | + } |
| 310 | + else if (tz_id == TIME_ZONE_ID_STANDARD) { |
| 311 | + bias_minutes += dtzi.StandardBias; |
| 312 | + } |
| 313 | + |
| 314 | + /* Windows bias: minutes to add to local to get UTC |
| 315 | + ISO8601 offset: inverse sign */ |
| 316 | + if (bias_minutes > 0) { |
| 317 | + offset_sign = '-'; |
296 | 318 | } |
297 | 319 | else { |
| 320 | + offset_sign = '+'; |
| 321 | + bias_minutes = -bias_minutes; |
| 322 | + } |
| 323 | + |
| 324 | + offset_hours = bias_minutes / 60; |
| 325 | + offset_minutes = bias_minutes % 60; |
| 326 | + |
| 327 | + len = _snprintf_s(buf, sizeof(buf), _TRUNCATE, |
| 328 | + "%04d-%02d-%02d %02d:%02d:%02d %c%02d%02d", |
| 329 | + st_local.wYear, |
| 330 | + st_local.wMonth, |
| 331 | + st_local.wDay, |
| 332 | + st_local.wHour, |
| 333 | + st_local.wMinute, |
| 334 | + st_local.wSecond, |
| 335 | + offset_sign, |
| 336 | + offset_hours, |
| 337 | + offset_minutes); |
| 338 | + |
| 339 | + if (len <= 0) { |
| 340 | + _free_locale(locale); |
298 | 341 | return -1; |
299 | 342 | } |
300 | 343 |
|
| 344 | + _free_locale(locale); |
| 345 | + |
| 346 | + flb_log_event_encoder_append_body_string(ctx->log_encoder, buf, len); |
301 | 347 | return 0; |
302 | 348 | } |
303 | 349 |
|
|
0 commit comments