diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index cf2f622a77e..a7043c223d1 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -399,9 +399,9 @@ @ stdcall EnumCalendarInfoW(ptr long long long) @ stdcall EnumDateFormatsA(ptr long long) @ stdcall EnumDateFormatsExA(ptr long long) -@ stdcall EnumDateFormatsExEx(ptr wstr long long) -@ stdcall EnumDateFormatsExW(ptr long long) -@ stdcall EnumDateFormatsW(ptr long long) +@ stdcall -import EnumDateFormatsExEx(ptr wstr long long) +@ stdcall -import EnumDateFormatsExW(ptr long long) +@ stdcall -import EnumDateFormatsW(ptr long long) @ stdcall EnumLanguageGroupLocalesA(ptr long long ptr) @ stdcall -import EnumLanguageGroupLocalesW(ptr long long ptr) @ stdcall EnumResourceLanguagesA(long str str ptr long) diff --git a/dlls/kernel32/lcformat.c b/dlls/kernel32/lcformat.c index b1dd32de137..6a6a5174c07 100644 --- a/dlls/kernel32/lcformat.c +++ b/dlls/kernel32/lcformat.c @@ -1780,179 +1780,6 @@ enum enum_callback_type { CALLBACK_ENUMPROCEXEX }; -struct enumdateformats_context { - enum enum_callback_type type; /* callback kind */ - union { - DATEFMT_ENUMPROCW callback; /* user callback pointer */ - DATEFMT_ENUMPROCEXW callbackex; - DATEFMT_ENUMPROCEXEX callbackexex; - } u; - LCID lcid; /* locale of interest */ - DWORD flags; - LPARAM lParam; - BOOL unicode; /* A vs W callback type, only for regular and Ex callbacks */ -}; - -/****************************************************************************** - * NLS_EnumDateFormats - * Enumerates date formats for a specified locale. - * - * PARAMS - * ctxt [I] enumeration context, see 'struct enumdateformats_context' - * - * RETURNS - * Success: TRUE. - * Failure: FALSE. Use GetLastError() to determine the cause. - */ -static BOOL NLS_EnumDateFormats(const struct enumdateformats_context *ctxt) -{ - WCHAR bufW[256]; - char bufA[256]; - LCTYPE lctype; - CALID cal_id; - INT ret; - - if (!ctxt->u.callback) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - if (!GetLocaleInfoW(ctxt->lcid, LOCALE_ICALENDARTYPE|LOCALE_RETURN_NUMBER, (LPWSTR)&cal_id, sizeof(cal_id)/sizeof(WCHAR))) - return FALSE; - - switch (ctxt->flags & ~LOCALE_USE_CP_ACP) - { - case 0: - case DATE_SHORTDATE: - lctype = LOCALE_SSHORTDATE; - break; - case DATE_LONGDATE: - lctype = LOCALE_SLONGDATE; - break; - case DATE_YEARMONTH: - lctype = LOCALE_SYEARMONTH; - break; - default: - FIXME("Unknown date format (0x%08x)\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(ctxt->unicode ? bufW : (WCHAR*)bufA, cal_id); - break; - case CALLBACK_ENUMPROCEXEX: - ctxt->u.callbackexex(bufW, cal_id, ctxt->lParam); - break; - default: - ; - } - } - - return TRUE; -} - -/************************************************************************** - * EnumDateFormatsExA (KERNEL32.@) - * - * FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle - * LOCALE_NOUSEROVERRIDE here as well? - */ -BOOL WINAPI EnumDateFormatsExA(DATEFMT_ENUMPROCEXA proc, LCID lcid, DWORD flags) -{ - struct enumdateformats_context ctxt; - - ctxt.type = CALLBACK_ENUMPROCEX; - ctxt.u.callbackex = (DATEFMT_ENUMPROCEXW)proc; - ctxt.lcid = lcid; - ctxt.flags = flags; - ctxt.unicode = FALSE; - - return NLS_EnumDateFormats(&ctxt); -} - -/************************************************************************** - * EnumDateFormatsExW (KERNEL32.@) - */ -BOOL WINAPI EnumDateFormatsExW(DATEFMT_ENUMPROCEXW proc, LCID lcid, DWORD flags) -{ - struct enumdateformats_context ctxt; - - ctxt.type = CALLBACK_ENUMPROCEX; - ctxt.u.callbackex = proc; - ctxt.lcid = lcid; - ctxt.flags = flags; - ctxt.unicode = TRUE; - - return NLS_EnumDateFormats(&ctxt); -} - -/************************************************************************** - * EnumDateFormatsA (KERNEL32.@) - * - * FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle - * LOCALE_NOUSEROVERRIDE here as well? - */ -BOOL WINAPI EnumDateFormatsA(DATEFMT_ENUMPROCA proc, LCID lcid, DWORD flags) -{ - struct enumdateformats_context ctxt; - - ctxt.type = CALLBACK_ENUMPROC; - ctxt.u.callback = (DATEFMT_ENUMPROCW)proc; - ctxt.lcid = lcid; - ctxt.flags = flags; - ctxt.unicode = FALSE; - - return NLS_EnumDateFormats(&ctxt); -} - -/************************************************************************** - * EnumDateFormatsW (KERNEL32.@) - */ -BOOL WINAPI EnumDateFormatsW(DATEFMT_ENUMPROCW proc, LCID lcid, DWORD flags) -{ - struct enumdateformats_context ctxt; - - ctxt.type = CALLBACK_ENUMPROC; - ctxt.u.callback = proc; - ctxt.lcid = lcid; - ctxt.flags = flags; - ctxt.unicode = TRUE; - - return NLS_EnumDateFormats(&ctxt); -} - -/************************************************************************** - * EnumDateFormatsExEx (KERNEL32.@) - */ -BOOL WINAPI EnumDateFormatsExEx(DATEFMT_ENUMPROCEXEX proc, const WCHAR *locale, DWORD flags, LPARAM lParam) -{ - struct enumdateformats_context ctxt; - - ctxt.type = CALLBACK_ENUMPROCEXEX; - ctxt.u.callbackexex = proc; - ctxt.lcid = LocaleNameToLCID(locale, 0); - ctxt.flags = flags; - ctxt.lParam = lParam; - ctxt.unicode = TRUE; - - return NLS_EnumDateFormats(&ctxt); -} - struct enumtimeformats_context { enum enum_callback_type type; /* callback kind */ union { diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c index 0f91728e841..f3468949f7c 100644 --- a/dlls/kernel32/locale.c +++ b/dlls/kernel32/locale.c @@ -59,6 +59,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(nls); #define WC_FLAGSMASK (WC_DISCARDNS|WC_SEPCHARS|WC_DEFAULTCHAR|WC_ERR_INVALID_CHARS|\ WC_COMPOSITECHECK|WC_NO_BEST_FIT_CHARS) +extern BOOL WINAPI Internal_EnumDateFormats( DATEFMT_ENUMPROCW proc, LCID lcid, DWORD flags, BOOL unicode, + BOOL ex, BOOL exex, LPARAM lparam ); extern BOOL WINAPI Internal_EnumLanguageGroupLocales( LANGGROUPLOCALE_ENUMPROCW proc, LGRPID id, DWORD flags, LONG_PTR param, BOOL unicode ); extern BOOL WINAPI Internal_EnumSystemCodePages( CODEPAGE_ENUMPROCW proc, DWORD flags, BOOL unicode ); @@ -3624,6 +3626,28 @@ BOOL WINAPI EnumLanguageGroupLocalesA( LANGGROUPLOCALE_ENUMPROCA proc, LGRPID id return Internal_EnumLanguageGroupLocales( (LANGGROUPLOCALE_ENUMPROCW)proc, id, flags, param, FALSE ); } +/************************************************************************** + * EnumDateFormatsExA (KERNEL32.@) + * + * FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle + * LOCALE_NOUSEROVERRIDE here as well? + */ +BOOL WINAPI EnumDateFormatsExA(DATEFMT_ENUMPROCEXA proc, LCID lcid, DWORD flags) +{ + return Internal_EnumDateFormats( (DATEFMT_ENUMPROCW)proc, lcid, flags, FALSE, TRUE, FALSE, 0 ); +} + +/************************************************************************** + * EnumDateFormatsA (KERNEL32.@) + * + * FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle + * LOCALE_NOUSEROVERRIDE here as well? + */ +BOOL WINAPI EnumDateFormatsA(DATEFMT_ENUMPROCA proc, LCID lcid, DWORD flags) +{ + return Internal_EnumDateFormats( (DATEFMT_ENUMPROCW)proc, lcid, flags, FALSE, FALSE, FALSE, 0 ); +} + /****************************************************************************** * InvalidateNLSCache (KERNEL32.@) * diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index 7c5ae99a790..1cea884e9bb 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -293,9 +293,9 @@ @ stdcall EnumCalendarInfoExEx(ptr wstr long wstr long long) kernel32.EnumCalendarInfoExEx @ stdcall EnumCalendarInfoExW(ptr long long long) kernel32.EnumCalendarInfoExW @ stdcall EnumCalendarInfoW(ptr long long long) kernel32.EnumCalendarInfoW -@ stdcall EnumDateFormatsExEx(ptr wstr long long) kernel32.EnumDateFormatsExEx -@ stdcall EnumDateFormatsExW(ptr long long) kernel32.EnumDateFormatsExW -@ stdcall EnumDateFormatsW(ptr long long) kernel32.EnumDateFormatsW +@ stdcall EnumDateFormatsExEx(ptr wstr long long) +@ stdcall EnumDateFormatsExW(ptr long long) +@ stdcall EnumDateFormatsW(ptr long long) # @ stub EnumDeviceDrivers @ stdcall EnumDynamicTimeZoneInformation(long ptr) @ stdcall EnumLanguageGroupLocalesW(ptr long long ptr) @@ -825,7 +825,7 @@ @ stdcall InterlockedPushListSListEx(ptr ptr ptr long) ntdll.RtlInterlockedPushListSListEx @ stub InternalLcidToName @ stub Internal_EnumCalendarInfo -@ stub Internal_EnumDateFormats +@ stdcall Internal_EnumDateFormats(ptr long long long long long long) @ stdcall Internal_EnumLanguageGroupLocales(ptr long long ptr long) @ stdcall Internal_EnumSystemCodePages(ptr long long) @ stdcall Internal_EnumSystemLanguageGroups(ptr long ptr long) diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c index 204137bf809..2e1e76c4d7a 100644 --- a/dlls/kernelbase/locale.c +++ b/dlls/kernelbase/locale.c @@ -53,6 +53,60 @@ static const WCHAR locales_key[] = static const WCHAR altsort_key[] = {'A','l','t','e','r','n','a','t','e',' ','S','o','r','t','s',0}; +/************************************************************************** + * Internal_EnumDateFormats (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH Internal_EnumDateFormats( DATEFMT_ENUMPROCW proc, LCID lcid, DWORD flags, + BOOL unicode, BOOL ex, BOOL exex, LPARAM lparam ) +{ + WCHAR buffer[256]; + LCTYPE lctype; + CALID cal_id; + INT ret; + + if (!proc) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + if (!GetLocaleInfoW( lcid, LOCALE_ICALENDARTYPE|LOCALE_RETURN_NUMBER, + (LPWSTR)&cal_id, sizeof(cal_id)/sizeof(WCHAR) )) + return FALSE; + + switch (flags & ~LOCALE_USE_CP_ACP) + { + case 0: + case DATE_SHORTDATE: + lctype = LOCALE_SSHORTDATE; + break; + case DATE_LONGDATE: + lctype = LOCALE_SLONGDATE; + break; + case DATE_YEARMONTH: + lctype = LOCALE_SYEARMONTH; + break; + default: + FIXME( "unknown date format 0x%08x\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 (exex) ((DATEFMT_ENUMPROCEXEX)proc)( buffer, cal_id, lparam ); + else if (ex) ((DATEFMT_ENUMPROCEXW)proc)( buffer, cal_id ); + else proc( buffer ); + } + return TRUE; +} + + /****************************************************************************** * Internal_EnumLanguageGroupLocales (kernelbase.@) */ @@ -255,6 +309,35 @@ INT WINAPI DECLSPEC_HOTPATCH CompareStringOrdinal( const WCHAR *str1, INT len1, } +/************************************************************************** + * EnumDateFormatsW (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH EnumDateFormatsW( DATEFMT_ENUMPROCW proc, LCID lcid, DWORD flags ) +{ + return Internal_EnumDateFormats( proc, lcid, flags, TRUE, FALSE, FALSE, 0 ); +} + + +/************************************************************************** + * EnumDateFormatsExW (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH EnumDateFormatsExW( DATEFMT_ENUMPROCEXW proc, LCID lcid, DWORD flags ) +{ + return Internal_EnumDateFormats( (DATEFMT_ENUMPROCW)proc, lcid, flags, TRUE, TRUE, FALSE, 0 ); +} + + +/************************************************************************** + * EnumDateFormatsExEx (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH EnumDateFormatsExEx( DATEFMT_ENUMPROCEXEX proc, const WCHAR *locale, + DWORD flags, LPARAM lparam ) +{ + LCID lcid = LocaleNameToLCID( locale, 0 ); + return Internal_EnumDateFormats( (DATEFMT_ENUMPROCW)proc, lcid, flags, TRUE, TRUE, TRUE, lparam ); +} + + /****************************************************************************** * EnumLanguageGroupLocalesW (kernelbase.@) */