Module: wine Branch: master Commit: 1b127e24dc89a7b7f728004811016d1b7c4a2028 URL: https://source.winehq.org/git/wine.git/?a=commit;h=1b127e24dc89a7b7f72800481...
Author: Alexandre Julliard julliard@winehq.org Date: Wed May 4 08:52:08 2022 +0200
kernelbase: Reimplement GetTimeFormatW/Ex() using get_locale_info().
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/kernel32/kernel32.spec | 4 +- dlls/kernel32/lcformat.c | 47 ------------ dlls/kernelbase/kernelbase.spec | 4 +- dlls/kernelbase/locale.c | 153 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 157 insertions(+), 51 deletions(-)
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index 7067dff6b25..ebe5559d615 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -870,8 +870,8 @@ @ stdcall GetTickCount() @ stdcall -ret64 GetTickCount64() @ stdcall GetTimeFormatA(long long ptr str ptr long) -@ stdcall GetTimeFormatEx(wstr long ptr wstr ptr long) -@ stdcall GetTimeFormatW(long long ptr wstr ptr long) +@ stdcall -import GetTimeFormatEx(wstr long ptr wstr ptr long) +@ stdcall -import GetTimeFormatW(long long ptr wstr ptr long) @ stdcall -import GetTimeZoneInformation(ptr) @ stdcall -import GetTimeZoneInformationForYear(long ptr ptr) # @ stub GetUILanguageInfo diff --git a/dlls/kernel32/lcformat.c b/dlls/kernel32/lcformat.c index dbe960abec4..21d14328449 100644 --- a/dlls/kernel32/lcformat.c +++ b/dlls/kernel32/lcformat.c @@ -830,50 +830,3 @@ INT WINAPI GetTimeFormatA(LCID lcid, DWORD dwFlags, const SYSTEMTIME* lpTime, return NLS_GetDateTimeFormatA(lcid, dwFlags|TIME_TIMEVARSONLY, lpTime, lpFormat, lpTimeStr, cchOut); } - -/****************************************************************************** - * GetTimeFormatEx [KERNEL32.@] - * - * Format a date for a given locale. - * - * PARAMS - * localename [I] Locale to format for - * flags [I] LOCALE_ and TIME_ flags from "winnls.h" - * time [I] Time to format - * format [I] Formatting overrides - * outbuf [O] Destination for formatted string - * bufsize [I] Size of outbuf, or 0 to calculate the resulting size - * - * See GetTimeFormatA for notes. - * - * RETURNS - * Success: The number of characters written to outbuf, or that would have - * have been written if bufsize is 0. - * Failure: 0. Use GetLastError() to determine the cause. - */ -INT WINAPI GetTimeFormatEx(LPCWSTR localename, DWORD flags, - const SYSTEMTIME* time, LPCWSTR format, - LPWSTR outbuf, INT bufsize) -{ - TRACE("(%s,0x%08lx,%p,%s,%p,%d)\n", debugstr_w(localename), flags, time, - debugstr_w(format), outbuf, bufsize); - - return NLS_GetDateTimeFormatW(LocaleNameToLCID(localename, 0), - flags | TIME_TIMEVARSONLY, time, format, - outbuf, bufsize); -} - -/****************************************************************************** - * GetTimeFormatW [KERNEL32.@] - * - * See GetTimeFormatA. - */ -INT WINAPI GetTimeFormatW(LCID lcid, DWORD dwFlags, const SYSTEMTIME* lpTime, - LPCWSTR lpFormat, LPWSTR lpTimeStr, INT cchOut) -{ - TRACE("(0x%04lx,0x%08lx,%p,%s,%p,%d)\n",lcid, dwFlags, lpTime, - debugstr_w(lpFormat), lpTimeStr, cchOut); - - return NLS_GetDateTimeFormatW(lcid, dwFlags|TIME_TIMEVARSONLY, lpTime, - lpFormat, lpTimeStr, cchOut); -} diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index 103054ed636..06744a79b1f 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -756,8 +756,8 @@ @ stdcall GetTickCount() @ stdcall -ret64 GetTickCount64() @ stdcall GetTimeFormatA(long long ptr str ptr long) kernel32.GetTimeFormatA -@ stdcall GetTimeFormatEx(wstr long ptr wstr ptr long) kernel32.GetTimeFormatEx -@ stdcall GetTimeFormatW(long long ptr wstr ptr long) kernel32.GetTimeFormatW +@ stdcall GetTimeFormatEx(wstr long ptr wstr ptr long) +@ stdcall GetTimeFormatW(long long ptr wstr ptr long) @ stdcall GetTimeZoneInformation(ptr) @ stdcall GetTimeZoneInformationForYear(long ptr ptr) @ stdcall GetTokenInformation(long long ptr long ptr) diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c index 2f9fd8eaf4a..01ccd3cc6b6 100644 --- a/dlls/kernelbase/locale.c +++ b/dlls/kernelbase/locale.c @@ -6966,6 +6966,120 @@ static int get_date_format( const NLS_LOCALE_DATA *locale, DWORD flags, const SY }
+static int get_time_format( const NLS_LOCALE_DATA *locale, DWORD flags, const SYSTEMTIME *systime, + const WCHAR *format, WCHAR *buffer, int len ) +{ + DWORD override = flags & LOCALE_NOUSEROVERRIDE; + WCHAR *p, *last, fmt[80], output[256]; + SYSTEMTIME time; + int i, ret, val, count; + BOOL skip = FALSE; + + if (!format) + { + get_locale_info( locale, 0, LOCALE_STIMEFORMAT | override, fmt, ARRAY_SIZE(fmt) ); + format = fmt; + } + else if (override) + { + SetLastError( ERROR_INVALID_FLAGS ); + return 0; + } + + if (systime) + { + time = *systime; + if (time.wMilliseconds > 999 || time.wSecond > 59 || time.wMinute > 59 || time.wHour > 23) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return 0; + } + } + else GetLocalTime( &time ); + + for (p = last = output; *format; format += count) + { + count = get_pattern_len( format, L"Hhmst" ); + + switch (*format) + { + case ''': + for (i = 1; i < count; i++) + { + if (format[i] == ''') i++; + if (!skip && i < count) *p++ = format[i]; + } + continue; + + case 'H': + val = time.wHour; + break; + + case 'h': + val = time.wHour; + if (!(flags & TIME_FORCE24HOURFORMAT)) + { + val %= 12; + if (!val) val = 12; + } + break; + + case 'm': + if (flags & TIME_NOMINUTESORSECONDS) + { + p = last; + skip = TRUE; + continue; + } + val = time.wMinute; + break; + + case 's': + if (flags & (TIME_NOMINUTESORSECONDS | TIME_NOSECONDS)) + { + p = last; + skip = TRUE; + continue; + } + val = time.wSecond; + break; + + case 't': + if (flags & TIME_NOTIMEMARKER) + { + p = last; + skip = TRUE; + continue; + } + val = time.wHour < 12 ? LOCALE_S1159 : LOCALE_S2359; + ret = get_locale_info( locale, 0, val | override, p, output + ARRAY_SIZE(output) - p ); + p += (count > 1) ? ret - 1 : 1; + skip = FALSE; + continue; + + default: + if (!skip || *format == ' ') *p++ = *format; + continue; + } + + p += swprintf( p, output + ARRAY_SIZE(output) - p, L"%.*u", min( 2, count ), val ); + last = p; + skip = FALSE; + } + *p++ = 0; + ret = p - output; + + if (!len) return ret; + lstrcpynW( buffer, output, len ); + if (ret > len) + { + SetLastError( ERROR_INSUFFICIENT_BUFFER ); + return 0; + } + return ret; +} + + /************************************************************************** * GetNumberFormatW (kernelbase.@) */ @@ -7081,3 +7195,42 @@ int WINAPI GetDateFormatEx( const WCHAR *name, DWORD flags, const SYSTEMTIME *sy TRACE( "(%s,%lx,%p,%s,%p,%d)\n", debugstr_w(name), flags, systime, debugstr_w(format), buffer, len ); return get_date_format( locale, flags, systime, format, buffer, len ); } + + +/*********************************************************************** + * GetTimeFormatW (kernelbase.@) + */ +int WINAPI GetTimeFormatW( LCID lcid, DWORD flags, const SYSTEMTIME *systime, + const WCHAR *format, WCHAR *buffer, int len ) +{ + const NLS_LOCALE_DATA *locale = NlsValidateLocale( &lcid, 0 ); + + if (len < 0 || (len && !buffer) || !locale) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return 0; + } + + TRACE( "(%04lx,%lx,%p,%s,%p,%d)\n", lcid, flags, systime, debugstr_w(format), buffer, len ); + return get_time_format( locale, flags, systime, format, buffer, len ); +} + + +/*********************************************************************** + * GetTimeFormatEx (kernelbase.@) + */ +int WINAPI GetTimeFormatEx( const WCHAR *name, DWORD flags, const SYSTEMTIME *systime, + const WCHAR *format, WCHAR *buffer, int len ) +{ + LCID lcid; + const NLS_LOCALE_DATA *locale = get_locale_by_name( name, &lcid ); + + if (len < 0 || (len && !buffer) || !locale) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return 0; + } + + TRACE( "(%s,%lx,%p,%s,%p,%d)\n", debugstr_w(name), flags, systime, debugstr_w(format), buffer, len ); + return get_time_format( locale, flags, systime, format, buffer, len ); +}