diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index a7043c223d1..3f6943a29d5 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -426,8 +426,8 @@ @ stdcall -import EnumSystemLocalesEx(ptr long long ptr) @ stdcall -import EnumSystemLocalesW(ptr long) @ stdcall EnumTimeFormatsA(ptr long long) -@ stdcall EnumTimeFormatsEx(ptr wstr long long) -@ stdcall EnumTimeFormatsW(ptr long long) +@ stdcall -import EnumTimeFormatsEx(ptr wstr long long) +@ stdcall -import EnumTimeFormatsW(ptr long long) @ stdcall EnumUILanguagesA(ptr long long) @ stdcall -import EnumUILanguagesW(ptr long long) # @ stub EnumerateLocalComputerNamesA diff --git a/dlls/kernel32/lcformat.c b/dlls/kernel32/lcformat.c index 6a6a5174c07..28e305a8ee5 100644 --- a/dlls/kernel32/lcformat.c +++ b/dlls/kernel32/lcformat.c @@ -1780,128 +1780,6 @@ enum enum_callback_type { CALLBACK_ENUMPROCEXEX }; -struct enumtimeformats_context { - enum enum_callback_type type; /* callback kind */ - union { - TIMEFMT_ENUMPROCW callback; /* user callback pointer */ - TIMEFMT_ENUMPROCEX callbackex; - } u; - LCID lcid; /* locale of interest */ - DWORD flags; - LPARAM lParam; - BOOL unicode; /* A vs W callback type, only for regular and Ex callbacks */ -}; - -static BOOL NLS_EnumTimeFormats(struct enumtimeformats_context *ctxt) -{ - WCHAR bufW[256]; - char bufA[256]; - LCTYPE lctype; - INT ret; - - if (!ctxt->u.callback) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - switch (ctxt->flags & ~LOCALE_USE_CP_ACP) - { - case 0: - lctype = LOCALE_STIMEFORMAT; - break; - case TIME_NOSECONDS: - lctype = LOCALE_SSHORTTIME; - break; - default: - FIXME("Unknown time format (%d)\n", ctxt->flags); - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - lctype |= ctxt->flags & LOCALE_USE_CP_ACP; - if (ctxt->unicode) - ret = GetLocaleInfoW(ctxt->lcid, lctype, bufW, ARRAY_SIZE(bufW)); - else - ret = GetLocaleInfoA(ctxt->lcid, lctype, bufA, ARRAY_SIZE(bufA)); - - if (ret) - { - switch (ctxt->type) - { - case CALLBACK_ENUMPROC: - ctxt->u.callback(ctxt->unicode ? bufW : (WCHAR*)bufA); - break; - case CALLBACK_ENUMPROCEX: - ctxt->u.callbackex(bufW, ctxt->lParam); - break; - default: - ; - } - } - - return TRUE; -} - -/************************************************************************** - * EnumTimeFormatsA (KERNEL32.@) - * - * FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle - * LOCALE_NOUSEROVERRIDE here as well? - */ -BOOL WINAPI EnumTimeFormatsA(TIMEFMT_ENUMPROCA proc, LCID lcid, DWORD flags) -{ - struct enumtimeformats_context ctxt; - - /* EnumTimeFormatsA doesn't support flags, EnumTimeFormatsW does. */ - if (flags & ~LOCALE_USE_CP_ACP) - { - SetLastError(ERROR_INVALID_FLAGS); - return FALSE; - } - - ctxt.type = CALLBACK_ENUMPROC; - ctxt.u.callback = (TIMEFMT_ENUMPROCW)proc; - ctxt.lcid = lcid; - ctxt.flags = flags; - ctxt.unicode = FALSE; - - return NLS_EnumTimeFormats(&ctxt); -} - -/************************************************************************** - * EnumTimeFormatsW (KERNEL32.@) - */ -BOOL WINAPI EnumTimeFormatsW(TIMEFMT_ENUMPROCW proc, LCID lcid, DWORD flags) -{ - struct enumtimeformats_context ctxt; - - ctxt.type = CALLBACK_ENUMPROC; - ctxt.u.callback = proc; - ctxt.lcid = lcid; - ctxt.flags = flags; - ctxt.unicode = TRUE; - - return NLS_EnumTimeFormats(&ctxt); -} - -/************************************************************************** - * EnumTimeFormatsEx (KERNEL32.@) - */ -BOOL WINAPI EnumTimeFormatsEx(TIMEFMT_ENUMPROCEX proc, const WCHAR *locale, DWORD flags, LPARAM lParam) -{ - struct enumtimeformats_context ctxt; - - ctxt.type = CALLBACK_ENUMPROCEX; - ctxt.u.callbackex = proc; - ctxt.lcid = LocaleNameToLCID(locale, 0); - ctxt.flags = flags; - ctxt.lParam = lParam; - ctxt.unicode = TRUE; - - return NLS_EnumTimeFormats(&ctxt); -} - struct enumcalendar_context { enum enum_callback_type type; /* callback kind */ union { diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c index f3468949f7c..d7f32cbfdac 100644 --- a/dlls/kernel32/locale.c +++ b/dlls/kernel32/locale.c @@ -66,6 +66,8 @@ extern BOOL WINAPI Internal_EnumLanguageGroupLocales( LANGGROUPLOCALE_ENUMPROCW extern BOOL WINAPI Internal_EnumSystemCodePages( CODEPAGE_ENUMPROCW proc, DWORD flags, BOOL unicode ); extern BOOL WINAPI Internal_EnumSystemLanguageGroups( LANGUAGEGROUP_ENUMPROCW proc, DWORD flags, LONG_PTR param, BOOL unicode ); +extern BOOL WINAPI Internal_EnumTimeFormats( TIMEFMT_ENUMPROCW proc, LCID lcid, DWORD flags, + BOOL unicode, BOOL ex, LPARAM lparam ); extern BOOL WINAPI Internal_EnumUILanguages( UILANGUAGE_ENUMPROCW proc, DWORD flags, LONG_PTR param, BOOL unicode ); @@ -3648,6 +3650,23 @@ BOOL WINAPI EnumDateFormatsA(DATEFMT_ENUMPROCA proc, LCID lcid, DWORD flags) return Internal_EnumDateFormats( (DATEFMT_ENUMPROCW)proc, lcid, flags, FALSE, FALSE, FALSE, 0 ); } +/************************************************************************** + * EnumTimeFormatsA (KERNEL32.@) + * + * FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle + * LOCALE_NOUSEROVERRIDE here as well? + */ +BOOL WINAPI EnumTimeFormatsA( TIMEFMT_ENUMPROCA proc, LCID lcid, DWORD flags ) +{ + /* EnumTimeFormatsA doesn't support flags, EnumTimeFormatsW does. */ + if (flags & ~LOCALE_USE_CP_ACP) + { + SetLastError(ERROR_INVALID_FLAGS); + return FALSE; + } + return Internal_EnumTimeFormats( (TIMEFMT_ENUMPROCW)proc, lcid, flags, FALSE, FALSE, 0 ); +} + /****************************************************************************** * InvalidateNLSCache (KERNEL32.@) * diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index 1cea884e9bb..546a52c7ef6 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -318,8 +318,8 @@ @ stdcall EnumSystemLocalesA(ptr long) @ stdcall EnumSystemLocalesEx(ptr long long ptr) @ stdcall EnumSystemLocalesW(ptr long) -@ stdcall EnumTimeFormatsEx(ptr wstr long long) kernel32.EnumTimeFormatsEx -@ stdcall EnumTimeFormatsW(ptr long long) kernel32.EnumTimeFormatsW +@ stdcall EnumTimeFormatsEx(ptr wstr long long) +@ stdcall EnumTimeFormatsW(ptr long long) @ stdcall EnumUILanguagesW(ptr long long) # @ stub EnumerateStateAtomValues # @ stub EnumerateStateContainerItems @@ -830,7 +830,7 @@ @ stdcall Internal_EnumSystemCodePages(ptr long long) @ stdcall Internal_EnumSystemLanguageGroups(ptr long ptr long) @ stub Internal_EnumSystemLocales -@ stub Internal_EnumTimeFormats +@ stdcall Internal_EnumTimeFormats(ptr long long long long long) @ stdcall Internal_EnumUILanguages(ptr long long long) # @ stub InternetTimeFromSystemTimeA # @ stub InternetTimeFromSystemTimeW diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c index 2e1e76c4d7a..473e6e2391e 100644 --- a/dlls/kernelbase/locale.c +++ b/dlls/kernelbase/locale.c @@ -244,6 +244,50 @@ BOOL WINAPI DECLSPEC_HOTPATCH Internal_EnumSystemLanguageGroups( LANGUAGEGROUP_E } +/************************************************************************** + * Internal_EnumTimeFormats (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH Internal_EnumTimeFormats( TIMEFMT_ENUMPROCW proc, LCID lcid, DWORD flags, + BOOL unicode, BOOL ex, LPARAM lparam ) +{ + WCHAR buffer[256]; + LCTYPE lctype; + INT ret; + + if (!proc) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + switch (flags & ~LOCALE_USE_CP_ACP) + { + case 0: + lctype = LOCALE_STIMEFORMAT; + break; + case TIME_NOSECONDS: + lctype = LOCALE_SSHORTTIME; + break; + default: + FIXME( "Unknown time format %x\n", flags ); + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + lctype |= flags & LOCALE_USE_CP_ACP; + if (unicode) + ret = GetLocaleInfoW( lcid, lctype, buffer, ARRAY_SIZE(buffer) ); + else + ret = GetLocaleInfoA( lcid, lctype, (char *)buffer, sizeof(buffer) ); + + if (ret) + { + if (ex) ((TIMEFMT_ENUMPROCEX)proc)( buffer, lparam ); + else proc( buffer ); + } + return TRUE; +} + + /****************************************************************************** * Internal_EnumUILanguages (kernelbase.@) */ @@ -475,6 +519,26 @@ BOOL WINAPI DECLSPEC_HOTPATCH EnumSystemLocalesEx( LOCALE_ENUMPROCEX proc, DWORD } +/************************************************************************** + * EnumTimeFormatsW (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH EnumTimeFormatsW( TIMEFMT_ENUMPROCW proc, LCID lcid, DWORD flags ) +{ + return Internal_EnumTimeFormats( proc, lcid, flags, TRUE, FALSE, 0 ); +} + + +/************************************************************************** + * EnumTimeFormatsEx (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH EnumTimeFormatsEx( TIMEFMT_ENUMPROCEX proc, const WCHAR *locale, + DWORD flags, LPARAM lparam ) +{ + LCID lcid = LocaleNameToLCID( locale, 0 ); + return Internal_EnumTimeFormats( (TIMEFMT_ENUMPROCW)proc, lcid, flags, TRUE, TRUE, lparam ); +} + + /****************************************************************************** * FindStringOrdinal (kernelbase.@) */