ReactOS  0.4.12-dev-914-g71f84a3
lcformat.c
Go to the documentation of this file.
1 /*
2  * Locale-dependent format handling
3  *
4  * Copyright 1995 Martin von Loewis
5  * Copyright 1998 David Lee Lambert
6  * Copyright 2000 Julio César Gázquez
7  * Copyright 2003 Jon Griffiths
8  * Copyright 2005 Dmitry Timoshkov
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #ifdef __REACTOS__
26 
27 #include <k32.h>
28 
29 #define NDEBUG
30 #include <debug.h>
32 
33 #define CRITICAL_SECTION RTL_CRITICAL_SECTION
34 #define CRITICAL_SECTION_DEBUG RTL_CRITICAL_SECTION_DEBUG
35 #define CALINFO_MAX_YEAR 2029
36 
37 #else /* __REACTOS__ */
38 
39 #include "config.h"
40 #include "wine/port.h"
41 
42 #include <string.h>
43 #include <stdarg.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 
47 #include "windef.h"
48 #include "winbase.h"
49 #include "wine/unicode.h"
50 #include "wine/debug.h"
51 #include "winternl.h"
52 
53 #include "kernel_private.h"
54 
56 
57 #endif /* __REACTOS__ */
58 
59 #define DATE_DATEVARSONLY 0x0100 /* only date stuff: yMdg */
60 #define TIME_TIMEVARSONLY 0x0200 /* only time stuff: hHmst */
61 
62 /* Since calculating the formatting data for each locale is time-consuming,
63  * we get the format data for each locale only once and cache it in memory.
64  * We cache both the system default and user overridden data, after converting
65  * them into the formats that the functions here expect. Since these functions
66  * will typically be called with only a small number of the total locales
67  * installed, the memory overhead is minimal while the speedup is significant.
68  *
69  * Our cache takes the form of a singly linked list, whose node is below:
70  */
71 #define NLS_NUM_CACHED_STRINGS 57
72 
73 typedef struct _NLS_FORMAT_NODE
74 {
75  LCID lcid; /* Locale Id */
76  DWORD dwFlags; /* 0 or LOCALE_NOUSEROVERRIDE */
77  DWORD dwCodePage; /* Default code page (if LOCALE_USE_ANSI_CP not given) */
78  NUMBERFMTW fmt; /* Default format for numbers */
79  CURRENCYFMTW cyfmt; /* Default format for currencies */
80  LPWSTR lppszStrings[NLS_NUM_CACHED_STRINGS]; /* Default formats,day/month names */
81  WCHAR szShortAM[2]; /* Short 'AM' marker */
82  WCHAR szShortPM[2]; /* Short 'PM' marker */
85 
86 /* Macros to get particular data strings from a format node */
87 #define GetNegative(fmt) fmt->lppszStrings[0]
88 #define GetLongDate(fmt) fmt->lppszStrings[1]
89 #define GetShortDate(fmt) fmt->lppszStrings[2]
90 #define GetTime(fmt) fmt->lppszStrings[3]
91 #define GetAM(fmt) fmt->lppszStrings[54]
92 #define GetPM(fmt) fmt->lppszStrings[55]
93 #define GetYearMonth(fmt) fmt->lppszStrings[56]
94 
95 #define GetLongDay(fmt,day) fmt->lppszStrings[4 + day]
96 #define GetShortDay(fmt,day) fmt->lppszStrings[11 + day]
97 #define GetLongMonth(fmt,mth) fmt->lppszStrings[18 + mth]
98 #define GetGenitiveMonth(fmt,mth) fmt->lppszStrings[30 + mth]
99 #define GetShortMonth(fmt,mth) fmt->lppszStrings[42 + mth]
100 
101 /* Write access to the cache is protected by this critical section */
104 {
105  0, 0, &NLS_FormatsCS,
108 #ifdef __REACTOS__
109  0, 0, 0
110 #else
111  0, 0, { (DWORD_PTR)(__FILE__ ": NLS_Formats") }
112 #endif
113 };
114 static CRITICAL_SECTION NLS_FormatsCS = { &NLS_FormatsCS_debug, -1, 0, 0, 0, 0 };
115 
116 /**************************************************************************
117  * NLS_GetLocaleNumber <internal>
118  *
119  * Get a numeric locale format value.
120  */
122 {
123  WCHAR szBuff[80];
124  DWORD dwVal = 0;
125 
126  szBuff[0] = '\0';
127  GetLocaleInfoW(lcid, dwFlags, szBuff, ARRAY_SIZE(szBuff));
128 
129  if (szBuff[0] && szBuff[1] == ';' && szBuff[2] != '0')
130  dwVal = (szBuff[0] - '0') * 10 + (szBuff[2] - '0');
131  else
132  {
133  const WCHAR* iter = szBuff;
134  dwVal = 0;
135  while(*iter >= '0' && *iter <= '9')
136  dwVal = dwVal * 10 + (*iter++ - '0');
137  }
138  return dwVal;
139 }
140 
141 /**************************************************************************
142  * NLS_GetLocaleString <internal>
143  *
144  * Get a string locale format value.
145  */
147 {
148  WCHAR szBuff[80], *str;
149  DWORD dwLen;
150 
151  szBuff[0] = '\0';
152  GetLocaleInfoW(lcid, dwFlags, szBuff, ARRAY_SIZE(szBuff));
153  dwLen = strlenW(szBuff) + 1;
154  str = HeapAlloc(GetProcessHeap(), 0, dwLen * sizeof(WCHAR));
155  if (str)
156  memcpy(str, szBuff, dwLen * sizeof(WCHAR));
157  return str;
158 }
159 
160 #define GET_LOCALE_NUMBER(num, type) num = NLS_GetLocaleNumber(lcid, type|dwFlags); \
161  TRACE( #type ": %d (%08x)\n", (DWORD)num, (DWORD)num)
162 
163 #define GET_LOCALE_STRING(str, type) str = NLS_GetLocaleString(lcid, type|dwFlags); \
164  TRACE( #type ": %s\n", debugstr_w(str))
165 
166 /**************************************************************************
167  * NLS_GetFormats <internal>
168  *
169  * Calculate (and cache) the number formats for a locale.
170  */
172 {
173  /* GetLocaleInfo() identifiers for cached formatting strings */
174  static const LCTYPE NLS_LocaleIndices[] = {
204  LOCALE_SYEARMONTH
205  };
206  static NLS_FORMAT_NODE *NLS_CachedFormats = NULL;
207  NLS_FORMAT_NODE *node = NLS_CachedFormats;
208 
210 
211  TRACE("(0x%04x,0x%08x)\n", lcid, dwFlags);
212 
213  /* See if we have already cached the locales number format */
214  while (node && (node->lcid != lcid || node->dwFlags != dwFlags) && node->next)
215  node = node->next;
216 
217  if (!node || node->lcid != lcid || node->dwFlags != dwFlags)
218  {
219  NLS_FORMAT_NODE *new_node;
220  DWORD i;
221 
222  TRACE("Creating new cache entry\n");
223 
224  if (!(new_node = HeapAlloc(GetProcessHeap(), 0, sizeof(NLS_FORMAT_NODE))))
225  return NULL;
226 
228 
229  /* Number Format */
230  new_node->lcid = lcid;
231  new_node->dwFlags = dwFlags;
232  new_node->next = NULL;
233 
237 
239  if (new_node->fmt.Grouping > 9 && new_node->fmt.Grouping != 32)
240  {
241  WARN("LOCALE_SGROUPING (%d) unhandled, please report!\n",
242  new_node->fmt.Grouping);
243  new_node->fmt.Grouping = 0;
244  }
245 
248 
249  /* Currency Format */
250  new_node->cyfmt.NumDigits = new_node->fmt.NumDigits;
251  new_node->cyfmt.LeadingZero = new_node->fmt.LeadingZero;
252 
254 
255  if (new_node->cyfmt.Grouping > 9)
256  {
257  WARN("LOCALE_SMONGROUPING (%d) unhandled, please report!\n",
258  new_node->cyfmt.Grouping);
259  new_node->cyfmt.Grouping = 0;
260  }
261 
263  if (new_node->cyfmt.NegativeOrder > 15)
264  {
265  WARN("LOCALE_INEGCURR (%d) unhandled, please report!\n",
266  new_node->cyfmt.NegativeOrder);
267  new_node->cyfmt.NegativeOrder = 0;
268  }
270  if (new_node->cyfmt.PositiveOrder > 3)
271  {
272  WARN("LOCALE_IPOSCURR (%d) unhandled,please report!\n",
273  new_node->cyfmt.PositiveOrder);
274  new_node->cyfmt.PositiveOrder = 0;
275  }
279 
280  /* Date/Time Format info, negative character, etc */
281  for (i = 0; i < ARRAY_SIZE(NLS_LocaleIndices); i++)
282  {
283  GET_LOCALE_STRING(new_node->lppszStrings[i], NLS_LocaleIndices[i]);
284  }
285  /* Save some memory if month genitive name is the same or not present */
286  for (i = 0; i < 12; i++)
287  {
288  if (strcmpW(GetLongMonth(new_node, i), GetGenitiveMonth(new_node, i)) == 0)
289  {
290  HeapFree(GetProcessHeap(), 0, GetGenitiveMonth(new_node, i));
291  GetGenitiveMonth(new_node, i) = NULL;
292  }
293  }
294 
295  new_node->szShortAM[0] = GetAM(new_node)[0]; new_node->szShortAM[1] = '\0';
296  new_node->szShortPM[0] = GetPM(new_node)[0]; new_node->szShortPM[1] = '\0';
297 
298  /* Now add the computed format to the cache */
300 
301  /* Search again: We may have raced to add the node */
302  node = NLS_CachedFormats;
303  while (node && (node->lcid != lcid || node->dwFlags != dwFlags) && node->next)
304  node = node->next;
305 
306  if (!node)
307  {
308  node = NLS_CachedFormats = new_node; /* Empty list */
309  new_node = NULL;
310  }
311  else if (node->lcid != lcid || node->dwFlags != dwFlags)
312  {
313  node->next = new_node; /* Not in the list, add to end */
314  node = new_node;
315  new_node = NULL;
316  }
317 
319 
320  if (new_node)
321  {
322  /* We raced and lost: The node was already added by another thread.
323  * node points to the currently cached node, so free new_node.
324  */
325  for (i = 0; i < ARRAY_SIZE(NLS_LocaleIndices); i++)
326  HeapFree(GetProcessHeap(), 0, new_node->lppszStrings[i]);
327  HeapFree(GetProcessHeap(), 0, new_node->fmt.lpDecimalSep);
328  HeapFree(GetProcessHeap(), 0, new_node->fmt.lpThousandSep);
329  HeapFree(GetProcessHeap(), 0, new_node->cyfmt.lpDecimalSep);
330  HeapFree(GetProcessHeap(), 0, new_node->cyfmt.lpThousandSep);
332  HeapFree(GetProcessHeap(), 0, new_node);
333  }
334  }
335  return node;
336 }
337 
338 /**************************************************************************
339  * NLS_IsUnicodeOnlyLcid <internal>
340  *
341  * Determine if a locale is Unicode only, and thus invalid in ASCII calls.
342  */
344 {
346 
347  switch (PRIMARYLANGID(lcid))
348  {
349  case LANG_ARMENIAN:
350  case LANG_DIVEHI:
351  case LANG_GEORGIAN:
352  case LANG_GUJARATI:
353  case LANG_HINDI:
354  case LANG_KANNADA:
355  case LANG_KONKANI:
356  case LANG_MARATHI:
357  case LANG_PUNJABI:
358  case LANG_SANSKRIT:
359  TRACE("lcid 0x%08x: langid 0x%4x is Unicode Only\n", lcid, PRIMARYLANGID(lcid));
360  return TRUE;
361  default:
362  return FALSE;
363  }
364 }
365 
366 /*
367  * Formatting of dates, times, numbers and currencies.
368  */
369 
370 #define IsLiteralMarker(p) (p == '\'')
371 #define IsDateFmtChar(p) (p == 'd'||p == 'M'||p == 'y'||p == 'g')
372 #define IsTimeFmtChar(p) (p == 'H'||p == 'h'||p == 'm'||p == 's'||p == 't')
373 
374 /* Only the following flags can be given if a date/time format is specified */
375 #define DATE_FORMAT_FLAGS (DATE_DATEVARSONLY)
376 #define TIME_FORMAT_FLAGS (TIME_TIMEVARSONLY|TIME_FORCE24HOURFORMAT| \
377  TIME_NOMINUTESORSECONDS|TIME_NOSECONDS| \
378  TIME_NOTIMEMARKER)
379 
380 /******************************************************************************
381  * NLS_GetDateTimeFormatW <internal>
382  *
383  * Performs the formatting for GetDateFormatW/GetTimeFormatW.
384  *
385  * FIXME
386  * DATE_USE_ALT_CALENDAR - Requires GetCalendarInfo to work first.
387  * DATE_LTRREADING/DATE_RTLREADING - Not yet implemented.
388  */
390  const SYSTEMTIME* lpTime, LPCWSTR lpFormat,
391  LPWSTR lpStr, INT cchOut)
392 {
393  const NLS_FORMAT_NODE *node;
394  SYSTEMTIME st;
395  INT cchWritten = 0;
396  INT lastFormatPos = 0;
397  BOOL bSkipping = FALSE; /* Skipping text around marker? */
398  BOOL d_dd_formatted = FALSE; /* previous formatted part was for d or dd */
399 
400  /* Verify our arguments */
401  if ((cchOut && !lpStr) || !(node = NLS_GetFormats(lcid, dwFlags)))
402  goto invalid_parameter;
403 
405  {
406  if (lpFormat &&
409  {
410  goto invalid_flags;
411  }
412 
414  {
415  if ((dwFlags & (DATE_LTRREADING|DATE_RTLREADING)) == (DATE_LTRREADING|DATE_RTLREADING))
416  goto invalid_flags;
417  else if (dwFlags & (DATE_LTRREADING|DATE_RTLREADING))
418  FIXME("Unsupported flags: DATE_LTRREADING/DATE_RTLREADING\n");
419 
420  switch (dwFlags & (DATE_SHORTDATE|DATE_LONGDATE|DATE_YEARMONTH))
421  {
422  case 0:
423  break;
424  case DATE_SHORTDATE:
425  case DATE_LONGDATE:
426  case DATE_YEARMONTH:
427  if (lpFormat)
428  goto invalid_flags;
429  break;
430  default:
431  goto invalid_flags;
432  }
433  }
434  }
435 
436  if (!lpFormat)
437  {
438  /* Use the appropriate default format */
440  {
441  if (dwFlags & DATE_YEARMONTH)
443  else if (dwFlags & DATE_LONGDATE)
445  else
447  }
448  else
449  lpFormat = GetTime(node);
450  }
451 
452  if (!lpTime)
453  {
454  GetLocalTime(&st); /* Default to current time */
455  lpTime = &st;
456  }
457  else
458  {
460  {
461  FILETIME ftTmp;
462 
463  /* Verify the date and correct the D.O.W. if needed */
464  memset(&st, 0, sizeof(st));
465  st.wYear = lpTime->wYear;
466  st.wMonth = lpTime->wMonth;
467  st.wDay = lpTime->wDay;
468 
469  if (st.wDay > 31 || st.wMonth > 12 || !SystemTimeToFileTime(&st, &ftTmp))
470  goto invalid_parameter;
471 
472  FileTimeToSystemTime(&ftTmp, &st);
473  lpTime = &st;
474  }
475 
477  {
478  /* Verify the time */
479  if (lpTime->wHour > 24 || lpTime->wMinute > 59 || lpTime->wSecond > 59)
480  goto invalid_parameter;
481  }
482  }
483 
484  /* Format the output */
485  while (*lpFormat)
486  {
488  {
489  /* Start of a literal string */
490  lpFormat++;
491 
492  /* Loop until the end of the literal marker or end of the string */
493  while (*lpFormat)
494  {
496  {
497  lpFormat++;
498  if (!IsLiteralMarker(*lpFormat))
499  break; /* Terminating literal marker */
500  }
501 
502  if (!cchOut)
503  cchWritten++; /* Count size only */
504  else if (cchWritten >= cchOut)
505  goto overrun;
506  else if (!bSkipping)
507  {
508  lpStr[cchWritten] = *lpFormat;
509  cchWritten++;
510  }
511  lpFormat++;
512  }
513  }
514  else if ((dwFlags & DATE_DATEVARSONLY && IsDateFmtChar(*lpFormat)) ||
516  {
517  WCHAR buff[32], fmtChar;
518  LPCWSTR szAdd = NULL;
519  DWORD dwVal = 0;
520  int count = 0, dwLen;
521 
522  bSkipping = FALSE;
523 
524  fmtChar = *lpFormat;
525  while (*lpFormat == fmtChar)
526  {
527  count++;
528  lpFormat++;
529  }
530  buff[0] = '\0';
531 
532  if (fmtChar != 'M') d_dd_formatted = FALSE;
533  switch(fmtChar)
534  {
535  case 'd':
536  if (count >= 4)
537  szAdd = GetLongDay(node, (lpTime->wDayOfWeek + 6) % 7);
538  else if (count == 3)
539  szAdd = GetShortDay(node, (lpTime->wDayOfWeek + 6) % 7);
540  else
541  {
542  dwVal = lpTime->wDay;
543  szAdd = buff;
544  d_dd_formatted = TRUE;
545  }
546  break;
547 
548  case 'M':
549  if (count >= 4)
550  {
551  LPCWSTR genitive = GetGenitiveMonth(node, lpTime->wMonth - 1);
552  if (genitive)
553  {
554  if (d_dd_formatted)
555  {
556  szAdd = genitive;
557  break;
558  }
559  else
560  {
562  /* Look forward now, if next format pattern is for day genitive
563  name should be used */
564  while (*format)
565  {
566  /* Skip parts within markers */
567  if (IsLiteralMarker(*format))
568  {
569  ++format;
570  while (*format)
571  {
572  if (IsLiteralMarker(*format))
573  {
574  ++format;
575  if (!IsLiteralMarker(*format)) break;
576  }
577  }
578  }
579  if (*format != ' ') break;
580  ++format;
581  }
582  /* Only numeric day form matters */
583  if (*format == 'd')
584  {
585  INT dcount = 1;
586  while (*++format == 'd') dcount++;
587  if (dcount < 3)
588  {
589  szAdd = genitive;
590  break;
591  }
592  }
593  }
594  }
595  szAdd = GetLongMonth(node, lpTime->wMonth - 1);
596  }
597  else if (count == 3)
598  szAdd = GetShortMonth(node, lpTime->wMonth - 1);
599  else
600  {
601  dwVal = lpTime->wMonth;
602  szAdd = buff;
603  }
604  break;
605 
606  case 'y':
607  if (count >= 4)
608  {
609  count = 4;
610  dwVal = lpTime->wYear;
611  }
612  else
613  {
614  count = count > 2 ? 2 : count;
615  dwVal = lpTime->wYear % 100;
616  }
617  szAdd = buff;
618  break;
619 
620  case 'g':
621  if (count == 2)
622  {
623  /* FIXME: Our GetCalendarInfo() does not yet support CAL_SERASTRING.
624  * When it is fixed, this string should be cached in 'node'.
625  */
626  FIXME("Should be using GetCalendarInfo(CAL_SERASTRING), defaulting to 'AD'\n");
627  buff[0] = 'A'; buff[1] = 'D'; buff[2] = '\0';
628  }
629  else
630  {
631  buff[0] = 'g'; buff[1] = '\0'; /* Add a literal 'g' */
632  }
633  szAdd = buff;
634  break;
635 
636  case 'h':
638  {
639  count = count > 2 ? 2 : count;
640  dwVal = lpTime->wHour == 0 ? 12 : (lpTime->wHour - 1) % 12 + 1;
641  szAdd = buff;
642  break;
643  }
644  /* .. fall through if we are forced to output in 24 hour format */
645 
646  case 'H':
647  count = count > 2 ? 2 : count;
648  dwVal = lpTime->wHour;
649  szAdd = buff;
650  break;
651 
652  case 'm':
654  {
655  cchWritten = lastFormatPos; /* Skip */
656  bSkipping = TRUE;
657  }
658  else
659  {
660  count = count > 2 ? 2 : count;
661  dwVal = lpTime->wMinute;
662  szAdd = buff;
663  }
664  break;
665 
666  case 's':
668  {
669  cchWritten = lastFormatPos; /* Skip */
670  bSkipping = TRUE;
671  }
672  else
673  {
674  count = count > 2 ? 2 : count;
675  dwVal = lpTime->wSecond;
676  szAdd = buff;
677  }
678  break;
679 
680  case 't':
682  {
683  cchWritten = lastFormatPos; /* Skip */
684  bSkipping = TRUE;
685  }
686  else
687  {
688  if (count == 1)
689  szAdd = lpTime->wHour < 12 ? node->szShortAM : node->szShortPM;
690  else
691  szAdd = lpTime->wHour < 12 ? GetAM(node) : GetPM(node);
692  }
693  break;
694  }
695 
696  if (szAdd == buff && buff[0] == '\0')
697  {
698  static const WCHAR fmtW[] = {'%','.','*','d',0};
699  /* We have a numeric value to add */
700  snprintfW(buff, ARRAY_SIZE(buff), fmtW, count, dwVal);
701  }
702 
703  dwLen = szAdd ? strlenW(szAdd) : 0;
704 
705  if (cchOut && dwLen)
706  {
707  if (cchWritten + dwLen < cchOut)
708  memcpy(lpStr + cchWritten, szAdd, dwLen * sizeof(WCHAR));
709  else
710  {
711  memcpy(lpStr + cchWritten, szAdd, (cchOut - cchWritten) * sizeof(WCHAR));
712  goto overrun;
713  }
714  }
715  cchWritten += dwLen;
716  lastFormatPos = cchWritten; /* Save position of last output format text */
717  }
718  else
719  {
720  /* Literal character */
721  if (!cchOut)
722  cchWritten++; /* Count size only */
723  else if (cchWritten >= cchOut)
724  goto overrun;
725  else if (!bSkipping || *lpFormat == ' ')
726  {
727  lpStr[cchWritten] = *lpFormat;
728  cchWritten++;
729  }
730  lpFormat++;
731  }
732  }
733 
734  /* Final string terminator and sanity check */
735  if (cchOut)
736  {
737  if (cchWritten >= cchOut)
738  goto overrun;
739  else
740  lpStr[cchWritten] = '\0';
741  }
742  cchWritten++; /* Include terminating NUL */
743 
744  TRACE("returning length=%d, output=%s\n", cchWritten, debugstr_w(lpStr));
745  return cchWritten;
746 
747 overrun:
748  TRACE("returning 0, (ERROR_INSUFFICIENT_BUFFER)\n");
750  return 0;
751 
752 invalid_parameter:
754  return 0;
755 
756 invalid_flags:
758  return 0;
759 }
760 
761 /******************************************************************************
762  * NLS_GetDateTimeFormatA <internal>
763  *
764  * ASCII wrapper for GetDateFormatA/GetTimeFormatA.
765  */
767  const SYSTEMTIME* lpTime,
768  LPCSTR lpFormat, LPSTR lpStr, INT cchOut)
769 {
770  DWORD cp = CP_ACP;
771  WCHAR szFormat[128], szOut[128];
772  INT iRet;
773 
774  TRACE("(0x%04x,0x%08x,%p,%s,%p,%d)\n", lcid, dwFlags, lpTime,
775  debugstr_a(lpFormat), lpStr, cchOut);
776 
778  {
780  return 0;
781  }
782 
783  if (!(dwFlags & LOCALE_USE_CP_ACP))
784  {
786  if (!node)
787  {
789  return 0;
790  }
791 
792  cp = node->dwCodePage;
793  }
794 
795  if (lpFormat)
796  MultiByteToWideChar(cp, 0, lpFormat, -1, szFormat, ARRAY_SIZE(szFormat));
797 
798  if (cchOut > (int) ARRAY_SIZE(szOut))
799  cchOut = ARRAY_SIZE(szOut);
800 
801  szOut[0] = '\0';
802 
803  iRet = NLS_GetDateTimeFormatW(lcid, dwFlags, lpTime, lpFormat ? szFormat : NULL,
804  lpStr ? szOut : NULL, cchOut);
805 
806  if (lpStr)
807  {
808  if (szOut[0])
809  WideCharToMultiByte(cp, 0, szOut, iRet ? -1 : cchOut, lpStr, cchOut, 0, 0);
810  else if (cchOut && iRet)
811  *lpStr = '\0';
812  }
813  return iRet;
814 }
815 
816 /******************************************************************************
817  * GetDateFormatA [KERNEL32.@]
818  *
819  * Format a date for a given locale.
820  *
821  * PARAMS
822  * lcid [I] Locale to format for
823  * dwFlags [I] LOCALE_ and DATE_ flags from "winnls.h"
824  * lpTime [I] Date to format
825  * lpFormat [I] Format string, or NULL to use the system defaults
826  * lpDateStr [O] Destination for formatted string
827  * cchOut [I] Size of lpDateStr, or 0 to calculate the resulting size
828  *
829  * NOTES
830  * - If lpFormat is NULL, lpDateStr will be formatted according to the format
831  * details returned by GetLocaleInfoA() and modified by dwFlags.
832  * - lpFormat is a string of characters and formatting tokens. Any characters
833  * in the string are copied verbatim to lpDateStr, with tokens being replaced
834  * by the date values they represent.
835  * - The following tokens have special meanings in a date format string:
836  *| Token Meaning
837  *| ----- -------
838  *| d Single digit day of the month (no leading 0)
839  *| dd Double digit day of the month
840  *| ddd Short name for the day of the week
841  *| dddd Long name for the day of the week
842  *| M Single digit month of the year (no leading 0)
843  *| MM Double digit month of the year
844  *| MMM Short name for the month of the year
845  *| MMMM Long name for the month of the year
846  *| y Double digit year number (no leading 0)
847  *| yy Double digit year number
848  *| yyyy Four digit year number
849  *| gg Era string, for example 'AD'.
850  * - To output any literal character that could be misidentified as a token,
851  * enclose it in single quotes.
852  * - The Ascii version of this function fails if lcid is Unicode only.
853  *
854  * RETURNS
855  * Success: The number of character written to lpDateStr, or that would
856  * have been written, if cchOut is 0.
857  * Failure: 0. Use GetLastError() to determine the cause.
858  */
860  LPCSTR lpFormat, LPSTR lpDateStr, INT cchOut)
861 {
862  TRACE("(0x%04x,0x%08x,%p,%s,%p,%d)\n",lcid, dwFlags, lpTime,
863  debugstr_a(lpFormat), lpDateStr, cchOut);
864 
866  lpFormat, lpDateStr, cchOut);
867 }
868 
869 #if _WIN32_WINNT >= 0x600
870 /******************************************************************************
871  * GetDateFormatEx [KERNEL32.@]
872  *
873  * Format a date for a given locale.
874  *
875  * PARAMS
876  * localename [I] Locale to format for
877  * flags [I] LOCALE_ and DATE_ flags from "winnls.h"
878  * date [I] Date to format
879  * format [I] Format string, or NULL to use the locale defaults
880  * outbuf [O] Destination for formatted string
881  * bufsize [I] Size of outbuf, or 0 to calculate the resulting size
882  * calendar [I] Reserved, must be NULL
883  *
884  * See GetDateFormatA for notes.
885  *
886  * RETURNS
887  * Success: The number of characters written to outbuf, or that would have
888  * been written if bufsize is 0.
889  * Failure: 0. Use GetLastError() to determine the cause.
890  */
892  const SYSTEMTIME* date, LPCWSTR format,
893  LPWSTR outbuf, INT bufsize, LPCWSTR calendar)
894 {
895  TRACE("(%s,0x%08x,%p,%s,%p,%d,%s)\n", debugstr_w(localename), flags,
896  date, debugstr_w(format), outbuf, bufsize, debugstr_w(calendar));
897 
898  /* Parameter is currently reserved and Windows errors if set */
899  if (calendar != NULL)
900  {
902  return 0;
903  }
904 
905  return NLS_GetDateTimeFormatW(LocaleNameToLCID(localename, 0),
907  outbuf, bufsize);
908 }
909 #endif /* _WIN32_WINNT >= 0x600 */
910 
911 /******************************************************************************
912  * GetDateFormatW [KERNEL32.@]
913  *
914  * See GetDateFormatA.
915  */
917  LPCWSTR lpFormat, LPWSTR lpDateStr, INT cchOut)
918 {
919  TRACE("(0x%04x,0x%08x,%p,%s,%p,%d)\n", lcid, dwFlags, lpTime,
920  debugstr_w(lpFormat), lpDateStr, cchOut);
921 
923  lpFormat, lpDateStr, cchOut);
924 }
925 
926 /******************************************************************************
927  * GetTimeFormatA [KERNEL32.@]
928  *
929  * Format a time for a given locale.
930  *
931  * PARAMS
932  * lcid [I] Locale to format for
933  * dwFlags [I] LOCALE_ and TIME_ flags from "winnls.h"
934  * lpTime [I] Time to format
935  * lpFormat [I] Formatting overrides
936  * lpTimeStr [O] Destination for formatted string
937  * cchOut [I] Size of lpTimeStr, or 0 to calculate the resulting size
938  *
939  * NOTES
940  * - If lpFormat is NULL, lpszValue will be formatted according to the format
941  * details returned by GetLocaleInfoA() and modified by dwFlags.
942  * - lpFormat is a string of characters and formatting tokens. Any characters
943  * in the string are copied verbatim to lpTimeStr, with tokens being replaced
944  * by the time values they represent.
945  * - The following tokens have special meanings in a time format string:
946  *| Token Meaning
947  *| ----- -------
948  *| h Hours with no leading zero (12-hour clock)
949  *| hh Hours with full two digits (12-hour clock)
950  *| H Hours with no leading zero (24-hour clock)
951  *| HH Hours with full two digits (24-hour clock)
952  *| m Minutes with no leading zero
953  *| mm Minutes with full two digits
954  *| s Seconds with no leading zero
955  *| ss Seconds with full two digits
956  *| t Short time marker (e.g. "A" or "P")
957  *| tt Long time marker (e.g. "AM", "PM")
958  * - To output any literal character that could be misidentified as a token,
959  * enclose it in single quotes.
960  * - The Ascii version of this function fails if lcid is Unicode only.
961  *
962  * RETURNS
963  * Success: The number of character written to lpTimeStr, or that would
964  * have been written, if cchOut is 0.
965  * Failure: 0. Use GetLastError() to determine the cause.
966  */
968  LPCSTR lpFormat, LPSTR lpTimeStr, INT cchOut)
969 {
970  TRACE("(0x%04x,0x%08x,%p,%s,%p,%d)\n",lcid, dwFlags, lpTime,
971  debugstr_a(lpFormat), lpTimeStr, cchOut);
972 
974  lpFormat, lpTimeStr, cchOut);
975 }
976 
977 #if _WIN32_WINNT >= 0x600
978 /******************************************************************************
979  * GetTimeFormatEx [KERNEL32.@]
980  *
981  * Format a date for a given locale.
982  *
983  * PARAMS
984  * localename [I] Locale to format for
985  * flags [I] LOCALE_ and TIME_ flags from "winnls.h"
986  * time [I] Time to format
987  * format [I] Formatting overrides
988  * outbuf [O] Destination for formatted string
989  * bufsize [I] Size of outbuf, or 0 to calculate the resulting size
990  *
991  * See GetTimeFormatA for notes.
992  *
993  * RETURNS
994  * Success: The number of characters written to outbuf, or that would have
995  * have been written if bufsize is 0.
996  * Failure: 0. Use GetLastError() to determine the cause.
997  */
999  const SYSTEMTIME* time, LPCWSTR format,
1001 {
1002  TRACE("(%s,0x%08x,%p,%s,%p,%d)\n", debugstr_w(localename), flags, time,
1004 
1005  return NLS_GetDateTimeFormatW(LocaleNameToLCID(localename, 0),
1007  outbuf, bufsize);
1008 }
1009 #endif /* _WIN32_WINNT >= 0x600 */
1010 
1011 /******************************************************************************
1012  * GetTimeFormatW [KERNEL32.@]
1013  *
1014  * See GetTimeFormatA.
1015  */
1017  LPCWSTR lpFormat, LPWSTR lpTimeStr, INT cchOut)
1018 {
1019  TRACE("(0x%04x,0x%08x,%p,%s,%p,%d)\n",lcid, dwFlags, lpTime,
1020  debugstr_w(lpFormat), lpTimeStr, cchOut);
1021 
1023  lpFormat, lpTimeStr, cchOut);
1024 }
1025 
1026 /**************************************************************************
1027  * GetNumberFormatA (KERNEL32.@)
1028  *
1029  * Format a number string for a given locale.
1030  *
1031  * PARAMS
1032  * lcid [I] Locale to format for
1033  * dwFlags [I] LOCALE_ flags from "winnls.h"
1034  * lpszValue [I] String to format
1035  * lpFormat [I] Formatting overrides
1036  * lpNumberStr [O] Destination for formatted string
1037  * cchOut [I] Size of lpNumberStr, or 0 to calculate the resulting size
1038  *
1039  * NOTES
1040  * - lpszValue can contain only '0' - '9', '-' and '.'.
1041  * - If lpFormat is non-NULL, dwFlags must be 0. In this case lpszValue will
1042  * be formatted according to the format details returned by GetLocaleInfoA().
1043  * - This function rounds the number string if the number of decimals exceeds the
1044  * locales normal number of decimal places.
1045  * - If cchOut is 0, this function does not write to lpNumberStr.
1046  * - The Ascii version of this function fails if lcid is Unicode only.
1047  *
1048  * RETURNS
1049  * Success: The number of character written to lpNumberStr, or that would
1050  * have been written, if cchOut is 0.
1051  * Failure: 0. Use GetLastError() to determine the cause.
1052  */
1054  LPCSTR lpszValue, const NUMBERFMTA *lpFormat,
1055  LPSTR lpNumberStr, int cchOut)
1056 {
1057  DWORD cp = CP_ACP;
1058  WCHAR szDec[8], szGrp[8], szIn[128], szOut[128];
1059  NUMBERFMTW fmt;
1060  const NUMBERFMTW *pfmt = NULL;
1061  INT iRet;
1062 
1063  TRACE("(0x%04x,0x%08x,%s,%p,%p,%d)\n", lcid, dwFlags, debugstr_a(lpszValue),
1064  lpFormat, lpNumberStr, cchOut);
1065 
1067  {
1069  return 0;
1070  }
1071 
1072  if (!(dwFlags & LOCALE_USE_CP_ACP))
1073  {
1075  if (!node)
1076  {
1078  return 0;
1079  }
1080 
1081  cp = node->dwCodePage;
1082  }
1083 
1084  if (lpFormat)
1085  {
1086  memcpy(&fmt, lpFormat, sizeof(fmt));
1087  pfmt = &fmt;
1088  if (lpFormat->lpDecimalSep)
1089  {
1090  MultiByteToWideChar(cp, 0, lpFormat->lpDecimalSep, -1, szDec, ARRAY_SIZE(szDec));
1091  fmt.lpDecimalSep = szDec;
1092  }
1093  if (lpFormat->lpThousandSep)
1094  {
1095  MultiByteToWideChar(cp, 0, lpFormat->lpThousandSep, -1, szGrp, ARRAY_SIZE(szGrp));
1096  fmt.lpThousandSep = szGrp;
1097  }
1098  }
1099 
1100  if (lpszValue)
1101  MultiByteToWideChar(cp, 0, lpszValue, -1, szIn, ARRAY_SIZE(szIn));
1102 
1103  if (cchOut > (int) ARRAY_SIZE(szOut))
1104  cchOut = ARRAY_SIZE(szOut);
1105 
1106  szOut[0] = '\0';
1107 
1108  iRet = GetNumberFormatW(lcid, dwFlags, lpszValue ? szIn : NULL, pfmt,
1109  lpNumberStr ? szOut : NULL, cchOut);
1110 
1111  if (szOut[0] && lpNumberStr)
1112  WideCharToMultiByte(cp, 0, szOut, -1, lpNumberStr, cchOut, 0, 0);
1113  return iRet;
1114 }
1115 
1116 /* Number parsing state flags */
1117 #define NF_ISNEGATIVE 0x1 /* '-' found */
1118 #define NF_ISREAL 0x2 /* '.' found */
1119 #define NF_DIGITS 0x4 /* '0'-'9' found */
1120 #define NF_DIGITS_OUT 0x8 /* Digits before the '.' found */
1121 #define NF_ROUND 0x10 /* Number needs to be rounded */
1122 
1123 /* Formatting options for Numbers */
1124 #define NLS_NEG_PARENS 0 /* "(1.1)" */
1125 #define NLS_NEG_LEFT 1 /* "-1.1" */
1126 #define NLS_NEG_LEFT_SPACE 2 /* "- 1.1" */
1127 #define NLS_NEG_RIGHT 3 /* "1.1-" */
1128 #define NLS_NEG_RIGHT_SPACE 4 /* "1.1 -" */
1129 
1130 /**************************************************************************
1131  * GetNumberFormatW (KERNEL32.@)
1132  *
1133  * See GetNumberFormatA.
1134  */
1136  LPCWSTR lpszValue, const NUMBERFMTW *lpFormat,
1137  LPWSTR lpNumberStr, int cchOut)
1138 {
1139  WCHAR szBuff[128], *szOut = szBuff + ARRAY_SIZE(szBuff) - 1;
1140  WCHAR szNegBuff[8];
1141  const WCHAR *lpszNeg = NULL, *lpszNegStart, *szSrc;
1142  DWORD dwState = 0, dwDecimals = 0, dwGroupCount = 0, dwCurrentGroupCount = 0;
1143  INT iRet;
1144 
1145  TRACE("(0x%04x,0x%08x,%s,%p,%p,%d)\n", lcid, dwFlags, debugstr_w(lpszValue),
1146  lpFormat, lpNumberStr, cchOut);
1147 
1148  if (!lpszValue || cchOut < 0 || (cchOut > 0 && !lpNumberStr) ||
1149  !IsValidLocale(lcid, 0) ||
1150  (lpFormat && (dwFlags || !lpFormat->lpDecimalSep || !lpFormat->lpThousandSep)))
1151  {
1152  goto error;
1153  }
1154 
1155  if (!lpFormat)
1156  {
1158 
1159  if (!node)
1160  goto error;
1161  lpFormat = &node->fmt;
1162  lpszNegStart = lpszNeg = GetNegative(node);
1163  }
1164  else
1165  {
1167  szNegBuff, ARRAY_SIZE(szNegBuff));
1168  lpszNegStart = lpszNeg = szNegBuff;
1169  }
1170  lpszNeg = lpszNeg + strlenW(lpszNeg) - 1;
1171 
1173 
1174  /* Format the number backwards into a temporary buffer */
1175 
1176  szSrc = lpszValue;
1177  *szOut-- = '\0';
1178 
1179  /* Check the number for validity */
1180  while (*szSrc)
1181  {
1182  if (*szSrc >= '0' && *szSrc <= '9')
1183  {
1184  dwState |= NF_DIGITS;
1185  if (dwState & NF_ISREAL)
1186  dwDecimals++;
1187  }
1188  else if (*szSrc == '-')
1189  {
1190  if (dwState)
1191  goto error; /* '-' not first character */
1192  dwState |= NF_ISNEGATIVE;
1193  }
1194  else if (*szSrc == '.')
1195  {
1196  if (dwState & NF_ISREAL)
1197  goto error; /* More than one '.' */
1198  dwState |= NF_ISREAL;
1199  }
1200  else
1201  goto error; /* Invalid char */
1202  szSrc++;
1203  }
1204  szSrc--; /* Point to last character */
1205 
1206  if (!(dwState & NF_DIGITS))
1207  goto error; /* No digits */
1208 
1209  /* Add any trailing negative sign */
1210  if (dwState & NF_ISNEGATIVE)
1211  {
1212  switch (lpFormat->NegativeOrder)
1213  {
1214  case NLS_NEG_PARENS:
1215  *szOut-- = ')';
1216  break;
1217  case NLS_NEG_RIGHT:
1218  case NLS_NEG_RIGHT_SPACE:
1219  while (lpszNeg >= lpszNegStart)
1220  *szOut-- = *lpszNeg--;
1221  if (lpFormat->NegativeOrder == NLS_NEG_RIGHT_SPACE)
1222  *szOut-- = ' ';
1223  break;
1224  }
1225  }
1226 
1227  /* Copy all digits up to the decimal point */
1228  if (!lpFormat->NumDigits)
1229  {
1230  if (dwState & NF_ISREAL)
1231  {
1232  while (*szSrc != '.') /* Don't write any decimals or a separator */
1233  {
1234  if (*szSrc >= '5' || (*szSrc == '4' && (dwState & NF_ROUND)))
1235  dwState |= NF_ROUND;
1236  else
1237  dwState &= ~NF_ROUND;
1238  szSrc--;
1239  }
1240  szSrc--;
1241  }
1242  }
1243  else
1244  {
1245  LPWSTR lpszDec = lpFormat->lpDecimalSep + strlenW(lpFormat->lpDecimalSep) - 1;
1246 
1247  if (dwDecimals <= lpFormat->NumDigits)
1248  {
1249  dwDecimals = lpFormat->NumDigits - dwDecimals;
1250  while (dwDecimals--)
1251  *szOut-- = '0'; /* Pad to correct number of dp */
1252  }
1253  else
1254  {
1255  dwDecimals -= lpFormat->NumDigits;
1256  /* Skip excess decimals, and determine if we have to round the number */
1257  while (dwDecimals--)
1258  {
1259  if (*szSrc >= '5' || (*szSrc == '4' && (dwState & NF_ROUND)))
1260  dwState |= NF_ROUND;
1261  else
1262  dwState &= ~NF_ROUND;
1263  szSrc--;
1264  }
1265  }
1266 
1267  if (dwState & NF_ISREAL)
1268  {
1269  while (*szSrc != '.')
1270  {
1271  if (dwState & NF_ROUND)
1272  {
1273  if (*szSrc == '9')
1274  *szOut-- = '0'; /* continue rounding */
1275  else
1276  {
1277  dwState &= ~NF_ROUND;
1278  *szOut-- = (*szSrc)+1;
1279  }
1280  szSrc--;
1281  }
1282  else
1283  *szOut-- = *szSrc--; /* Write existing decimals */
1284  }
1285  szSrc--; /* Skip '.' */
1286  }
1287 
1288  while (lpszDec >= lpFormat->lpDecimalSep)
1289  *szOut-- = *lpszDec--; /* Write decimal separator */
1290  }
1291 
1292  dwGroupCount = lpFormat->Grouping == 32 ? 3 : lpFormat->Grouping;
1293 
1294  /* Write the remaining whole number digits, including grouping chars */
1295  while (szSrc >= lpszValue && *szSrc >= '0' && *szSrc <= '9')
1296  {
1297  if (dwState & NF_ROUND)
1298  {
1299  if (*szSrc == '9')
1300  *szOut-- = '0'; /* continue rounding */
1301  else
1302  {
1303  dwState &= ~NF_ROUND;
1304  *szOut-- = (*szSrc)+1;
1305  }
1306  szSrc--;
1307  }
1308  else
1309  *szOut-- = *szSrc--;
1310 
1311  dwState |= NF_DIGITS_OUT;
1312  dwCurrentGroupCount++;
1313  if (szSrc >= lpszValue && dwCurrentGroupCount == dwGroupCount && *szSrc != '-')
1314  {
1315  LPWSTR lpszGrp = lpFormat->lpThousandSep + strlenW(lpFormat->lpThousandSep) - 1;
1316 
1317  while (lpszGrp >= lpFormat->lpThousandSep)
1318  *szOut-- = *lpszGrp--; /* Write grouping char */
1319 
1320  dwCurrentGroupCount = 0;
1321  if (lpFormat->Grouping == 32)
1322  dwGroupCount = 2; /* Indic grouping: 3 then 2 */
1323  }
1324  }
1325  if (dwState & NF_ROUND)
1326  {
1327  *szOut-- = '1'; /* e.g. .6 > 1.0 */
1328  }
1329  else if (!(dwState & NF_DIGITS_OUT) && lpFormat->LeadingZero)
1330  *szOut-- = '0'; /* Add leading 0 if we have no digits before the decimal point */
1331 
1332  /* Add any leading negative sign */
1333  if (dwState & NF_ISNEGATIVE)
1334  {
1335  switch (lpFormat->NegativeOrder)
1336  {
1337  case NLS_NEG_PARENS:
1338  *szOut-- = '(';
1339  break;
1340  case NLS_NEG_LEFT_SPACE:
1341  *szOut-- = ' ';
1342  /* Fall through */
1343  case NLS_NEG_LEFT:
1344  while (lpszNeg >= lpszNegStart)
1345  *szOut-- = *lpszNeg--;
1346  break;
1347  }
1348  }
1349  szOut++;
1350 
1351  iRet = strlenW(szOut) + 1;
1352  if (cchOut)
1353  {
1354  if (iRet <= cchOut)
1355  memcpy(lpNumberStr, szOut, iRet * sizeof(WCHAR));
1356  else
1357  {
1358  memcpy(lpNumberStr, szOut, cchOut * sizeof(WCHAR));
1359  lpNumberStr[cchOut - 1] = '\0';
1361  iRet = 0;
1362  }
1363  }
1364  return iRet;
1365 
1366 error:
1368  return 0;
1369 }
1370 
1371 #if _WIN32_WINNT >= 0x600
1372 /**************************************************************************
1373  * GetNumberFormatEx (KERNEL32.@)
1374  */
1375 INT WINAPI GetNumberFormatEx(LPCWSTR name, DWORD flags,
1376  LPCWSTR value, const NUMBERFMTW *format,
1377  LPWSTR number, int numout)
1378 {
1379  LCID lcid;
1380 
1381  TRACE("(%s,0x%08x,%s,%p,%p,%d)\n", debugstr_w(name), flags,
1382  debugstr_w(value), format, number, numout);
1383 
1384  lcid = LocaleNameToLCID(name, 0);
1385  if (!lcid)
1386  return 0;
1387 
1388  return GetNumberFormatW(lcid, flags, value, format, number, numout);
1389 }
1390 #endif /* _WIN32_WINNT >= 0x600 */
1391 
1392 /**************************************************************************
1393  * GetCurrencyFormatA (KERNEL32.@)
1394  *
1395  * Format a currency string for a given locale.
1396  *
1397  * PARAMS
1398  * lcid [I] Locale to format for
1399  * dwFlags [I] LOCALE_ flags from "winnls.h"
1400  * lpszValue [I] String to format
1401  * lpFormat [I] Formatting overrides
1402  * lpCurrencyStr [O] Destination for formatted string
1403  * cchOut [I] Size of lpCurrencyStr, or 0 to calculate the resulting size
1404  *
1405  * NOTES
1406  * - lpszValue can contain only '0' - '9', '-' and '.'.
1407  * - If lpFormat is non-NULL, dwFlags must be 0. In this case lpszValue will
1408  * be formatted according to the format details returned by GetLocaleInfoA().
1409  * - This function rounds the currency if the number of decimals exceeds the
1410  * locales number of currency decimal places.
1411  * - If cchOut is 0, this function does not write to lpCurrencyStr.
1412  * - The Ascii version of this function fails if lcid is Unicode only.
1413  *
1414  * RETURNS
1415  * Success: The number of character written to lpNumberStr, or that would
1416  * have been written, if cchOut is 0.
1417  * Failure: 0. Use GetLastError() to determine the cause.
1418  */
1420  LPCSTR lpszValue, const CURRENCYFMTA *lpFormat,
1421  LPSTR lpCurrencyStr, int cchOut)
1422 {
1423  DWORD cp = CP_ACP;
1424  WCHAR szDec[8], szGrp[8], szCy[8], szIn[128], szOut[128];
1425  CURRENCYFMTW fmt;
1426  const CURRENCYFMTW *pfmt = NULL;
1427  INT iRet;
1428 
1429  TRACE("(0x%04x,0x%08x,%s,%p,%p,%d)\n", lcid, dwFlags, debugstr_a(lpszValue),
1430  lpFormat, lpCurrencyStr, cchOut);
1431 
1433  {
1435  return 0;
1436  }
1437 
1438  if (!(dwFlags & LOCALE_USE_CP_ACP))
1439  {
1441  if (!node)
1442  {
1444  return 0;
1445  }
1446 
1447  cp = node->dwCodePage;
1448  }
1449 
1450  if (lpFormat)
1451  {
1452  memcpy(&fmt, lpFormat, sizeof(fmt));
1453  pfmt = &fmt;
1454  if (lpFormat->lpDecimalSep)
1455  {
1456  MultiByteToWideChar(cp, 0, lpFormat->lpDecimalSep, -1, szDec, ARRAY_SIZE(szDec));
1457  fmt.lpDecimalSep = szDec;
1458  }
1459  if (lpFormat->lpThousandSep)
1460  {
1461  MultiByteToWideChar(cp, 0, lpFormat->lpThousandSep, -1, szGrp, ARRAY_SIZE(szGrp));
1462  fmt.lpThousandSep = szGrp;
1463  }
1464  if (lpFormat->lpCurrencySymbol)
1465  {
1466  MultiByteToWideChar(cp, 0, lpFormat->lpCurrencySymbol, -1, szCy, ARRAY_SIZE(szCy));
1467  fmt.lpCurrencySymbol = szCy;
1468  }
1469  }
1470 
1471  if (lpszValue)
1472  MultiByteToWideChar(cp, 0, lpszValue, -1, szIn, ARRAY_SIZE(szIn));
1473 
1474  if (cchOut > (int) ARRAY_SIZE(szOut))
1475  cchOut = ARRAY_SIZE(szOut);
1476 
1477  szOut[0] = '\0';
1478 
1479  iRet = GetCurrencyFormatW(lcid, dwFlags, lpszValue ? szIn : NULL, pfmt,
1480  lpCurrencyStr ? szOut : NULL, cchOut);
1481 
1482  if (szOut[0] && lpCurrencyStr)
1483  WideCharToMultiByte(cp, 0, szOut, -1, lpCurrencyStr, cchOut, 0, 0);
1484  return iRet;
1485 }
1486 
1487 /* Formatting states for Currencies. We use flags to avoid code duplication. */
1488 #define CF_PARENS 0x1 /* Parentheses */
1489 #define CF_MINUS_LEFT 0x2 /* '-' to the left */
1490 #define CF_MINUS_RIGHT 0x4 /* '-' to the right */
1491 #define CF_MINUS_BEFORE 0x8 /* '-' before '$' */
1492 #define CF_CY_LEFT 0x10 /* '$' to the left */
1493 #define CF_CY_RIGHT 0x20 /* '$' to the right */
1494 #define CF_CY_SPACE 0x40 /* ' ' by '$' */
1495 
1496 /**************************************************************************
1497  * GetCurrencyFormatW (KERNEL32.@)
1498  *
1499  * See GetCurrencyFormatA.
1500  */
1502  LPCWSTR lpszValue, const CURRENCYFMTW *lpFormat,
1503  LPWSTR lpCurrencyStr, int cchOut)
1504 {
1505  static const BYTE NLS_NegCyFormats[16] =
1506  {
1507  CF_PARENS|CF_CY_LEFT, /* ($1.1) */
1509  CF_MINUS_LEFT|CF_CY_LEFT, /* $-1.1 */
1510  CF_MINUS_RIGHT|CF_CY_LEFT, /* $1.1- */
1511  CF_PARENS|CF_CY_RIGHT, /* (1.1$) */
1512  CF_MINUS_LEFT|CF_CY_RIGHT, /* -1.1$ */
1514  CF_MINUS_RIGHT|CF_CY_RIGHT, /* 1.1$- */
1515  CF_MINUS_LEFT|CF_CY_RIGHT|CF_CY_SPACE, /* -1.1 $ */
1517  CF_MINUS_RIGHT|CF_CY_RIGHT|CF_CY_SPACE, /* 1.1 $- */
1518  CF_MINUS_RIGHT|CF_CY_LEFT|CF_CY_SPACE, /* $ 1.1- */
1519  CF_MINUS_LEFT|CF_CY_LEFT|CF_CY_SPACE, /* $ -1.1 */
1521  CF_PARENS|CF_CY_LEFT|CF_CY_SPACE, /* ($ 1.1) */
1522  CF_PARENS|CF_CY_RIGHT|CF_CY_SPACE, /* (1.1 $) */
1523  };
1524  static const BYTE NLS_PosCyFormats[4] =
1525  {
1526  CF_CY_LEFT, /* $1.1 */
1527  CF_CY_RIGHT, /* 1.1$ */
1528  CF_CY_LEFT|CF_CY_SPACE, /* $ 1.1 */
1529  CF_CY_RIGHT|CF_CY_SPACE, /* 1.1 $ */
1530  };
1531  WCHAR szBuff[128], *szOut = szBuff + ARRAY_SIZE(szBuff) - 1;
1532  WCHAR szNegBuff[8];
1533  const WCHAR *lpszNeg = NULL, *lpszNegStart, *szSrc, *lpszCy, *lpszCyStart;
1534  DWORD dwState = 0, dwDecimals = 0, dwGroupCount = 0, dwCurrentGroupCount = 0, dwFmt;
1535  INT iRet;
1536 
1537  TRACE("(0x%04x,0x%08x,%s,%p,%p,%d)\n", lcid, dwFlags, debugstr_w(lpszValue),
1538  lpFormat, lpCurrencyStr, cchOut);
1539 
1540  if (!lpszValue || cchOut < 0 || (cchOut > 0 && !lpCurrencyStr) ||
1541  !IsValidLocale(lcid, 0) ||
1542  (lpFormat && (dwFlags || !lpFormat->lpDecimalSep || !lpFormat->lpThousandSep ||
1543  !lpFormat->lpCurrencySymbol || lpFormat->NegativeOrder > 15 ||
1544  lpFormat->PositiveOrder > 3)))
1545  {
1546  goto error;
1547  }
1548 
1549  if (!lpFormat)
1550  {
1552 
1553  if (!node)
1554  goto error;
1555 
1556  lpFormat = &node->cyfmt;
1557  lpszNegStart = lpszNeg = GetNegative(node);
1558  }
1559  else
1560  {
1562  szNegBuff, ARRAY_SIZE(szNegBuff));
1563  lpszNegStart = lpszNeg = szNegBuff;
1564  }
1566 
1567  lpszNeg = lpszNeg + strlenW(lpszNeg) - 1;
1568  lpszCyStart = lpFormat->lpCurrencySymbol;
1569  lpszCy = lpszCyStart + strlenW(lpszCyStart) - 1;
1570 
1571  /* Format the currency backwards into a temporary buffer */
1572 
1573  szSrc = lpszValue;
1574  *szOut-- = '\0';
1575 
1576  /* Check the number for validity */
1577  while (*szSrc)
1578  {
1579  if (*szSrc >= '0' && *szSrc <= '9')
1580  {
1581  dwState |= NF_DIGITS;
1582  if (dwState & NF_ISREAL)
1583  dwDecimals++;
1584  }
1585  else if (*szSrc == '-')
1586  {
1587  if (dwState)
1588  goto error; /* '-' not first character */
1589  dwState |= NF_ISNEGATIVE;
1590  }
1591  else if (*szSrc == '.')
1592  {
1593  if (dwState & NF_ISREAL)
1594  goto error; /* More than one '.' */
1595  dwState |= NF_ISREAL;
1596  }
1597  else
1598  goto error; /* Invalid char */
1599  szSrc++;
1600  }
1601  szSrc--; /* Point to last character */
1602 
1603  if (!(dwState & NF_DIGITS))
1604  goto error; /* No digits */
1605 
1606  if (dwState & NF_ISNEGATIVE)
1607  dwFmt = NLS_NegCyFormats[lpFormat->NegativeOrder];
1608  else
1609  dwFmt = NLS_PosCyFormats[lpFormat->PositiveOrder];
1610 
1611  /* Add any trailing negative or currency signs */
1612  if (dwFmt & CF_PARENS)
1613  *szOut-- = ')';
1614 
1615  while (dwFmt & (CF_MINUS_RIGHT|CF_CY_RIGHT))
1616  {
1617  switch (dwFmt & (CF_MINUS_RIGHT|CF_MINUS_BEFORE|CF_CY_RIGHT))
1618  {
1619  case CF_MINUS_RIGHT:
1621  while (lpszNeg >= lpszNegStart)
1622  *szOut-- = *lpszNeg--;
1623  dwFmt &= ~CF_MINUS_RIGHT;
1624  break;
1625 
1626  case CF_CY_RIGHT:
1629  while (lpszCy >= lpszCyStart)
1630  *szOut-- = *lpszCy--;
1631  if (dwFmt & CF_CY_SPACE)
1632  *szOut-- = ' ';
1633  dwFmt &= ~(CF_CY_RIGHT|CF_MINUS_BEFORE);
1634  break;
1635  }
1636  }
1637 
1638  /* Copy all digits up to the decimal point */
1639  if (!lpFormat->NumDigits)
1640  {
1641  if (dwState & NF_ISREAL)
1642  {
1643  while (*szSrc != '.') /* Don't write any decimals or a separator */
1644  {
1645  if (*szSrc >= '5' || (*szSrc == '4' && (dwState & NF_ROUND)))
1646  dwState |= NF_ROUND;
1647  else
1648  dwState &= ~NF_ROUND;
1649  szSrc--;
1650  }
1651  szSrc--;
1652  }
1653  }
1654  else
1655  {
1656  LPWSTR lpszDec = lpFormat->lpDecimalSep + strlenW(lpFormat->lpDecimalSep) - 1;
1657 
1658  if (dwDecimals <= lpFormat->NumDigits)
1659  {
1660  dwDecimals = lpFormat->NumDigits - dwDecimals;
1661  while (dwDecimals--)
1662  *szOut-- = '0'; /* Pad to correct number of dp */
1663  }
1664  else
1665  {
1666  dwDecimals -= lpFormat->NumDigits;
1667  /* Skip excess decimals, and determine if we have to round the number */
1668  while (dwDecimals--)
1669  {
1670  if (*szSrc >= '5' || (*szSrc == '4' && (dwState & NF_ROUND)))
1671  dwState |= NF_ROUND;
1672  else
1673  dwState &= ~NF_ROUND;
1674  szSrc--;
1675  }
1676  }
1677 
1678  if (dwState & NF_ISREAL)
1679  {
1680  while (*szSrc != '.')
1681  {
1682  if (dwState & NF_ROUND)
1683  {
1684  if (*szSrc == '9')
1685  *szOut-- = '0'; /* continue rounding */
1686  else
1687  {
1688  dwState &= ~NF_ROUND;
1689  *szOut-- = (*szSrc)+1;
1690  }
1691  szSrc--;
1692  }
1693  else
1694  *szOut-- = *szSrc--; /* Write existing decimals */
1695  }
1696  szSrc--; /* Skip '.' */
1697  }
1698  while (lpszDec >= lpFormat->lpDecimalSep)
1699  *szOut-- = *lpszDec--; /* Write decimal separator */
1700  }
1701 
1702  dwGroupCount = lpFormat->Grouping;
1703 
1704  /* Write the remaining whole number digits, including grouping chars */
1705  while (szSrc >= lpszValue && *szSrc >= '0' && *szSrc <= '9')
1706  {
1707  if (dwState & NF_ROUND)
1708  {
1709  if (*szSrc == '9')
1710  *szOut-- = '0'; /* continue rounding */
1711  else
1712  {
1713  dwState &= ~NF_ROUND;
1714  *szOut-- = (*szSrc)+1;
1715  }
1716  szSrc--;
1717  }
1718  else
1719  *szOut-- = *szSrc--;
1720 
1721  dwState |= NF_DIGITS_OUT;
1722  dwCurrentGroupCount++;
1723  if (szSrc >= lpszValue && dwCurrentGroupCount == dwGroupCount && *szSrc != '-')
1724  {
1725  LPWSTR lpszGrp = lpFormat->lpThousandSep + strlenW(lpFormat->lpThousandSep) - 1;
1726 
1727  while (lpszGrp >= lpFormat->lpThousandSep)
1728  *szOut-- = *lpszGrp--; /* Write grouping char */
1729 
1730  dwCurrentGroupCount = 0;
1731  }
1732  }
1733  if (dwState & NF_ROUND)
1734  *szOut-- = '1'; /* e.g. .6 > 1.0 */
1735  else if (!(dwState & NF_DIGITS_OUT) && lpFormat->LeadingZero)
1736  *szOut-- = '0'; /* Add leading 0 if we have no digits before the decimal point */
1737 
1738  /* Add any leading negative or currency sign */
1739  while (dwFmt & (CF_MINUS_LEFT|CF_CY_LEFT))
1740  {
1741  switch (dwFmt & (CF_MINUS_LEFT|CF_MINUS_BEFORE|CF_CY_LEFT))
1742  {
1743  case CF_MINUS_LEFT:
1745  while (lpszNeg >= lpszNegStart)
1746  *szOut-- = *lpszNeg--;
1747  dwFmt &= ~CF_MINUS_LEFT;
1748  break;
1749 
1750  case CF_CY_LEFT:
1753  if (dwFmt & CF_CY_SPACE)
1754  *szOut-- = ' ';
1755  while (lpszCy >= lpszCyStart)
1756  *szOut-- = *lpszCy--;
1757  dwFmt &= ~(CF_CY_LEFT|CF_MINUS_BEFORE);
1758  break;
1759  }
1760  }
1761  if (dwFmt & CF_PARENS)
1762  *szOut-- = '(';
1763  szOut++;
1764 
1765  iRet = strlenW(szOut) + 1;
1766  if (cchOut)
1767  {
1768  if (iRet <= cchOut)
1769  memcpy(lpCurrencyStr, szOut, iRet * sizeof(WCHAR));
1770  else
1771  {
1772  memcpy(lpCurrencyStr, szOut, cchOut * sizeof(WCHAR));
1773  lpCurrencyStr[cchOut - 1] = '\0';
1775  iRet = 0;
1776  }
1777  }
1778  return iRet;
1779 
1780 error:
1782  return 0;
1783 }
1784 
1785 #if _WIN32_WINNT >= 0x600
1786 /***********************************************************************
1787  * GetCurrencyFormatEx (KERNEL32.@)
1788  */
1789 int WINAPI GetCurrencyFormatEx(LPCWSTR localename, DWORD flags, LPCWSTR value,
1790  const CURRENCYFMTW *format, LPWSTR str, int len)
1791 {
1792  TRACE("(%s,0x%08x,%s,%p,%p,%d)\n", debugstr_w(localename), flags,
1793  debugstr_w(value), format, str, len);
1794 
1795  return GetCurrencyFormatW( LocaleNameToLCID(localename, 0), flags, value, format, str, len);
1796 }
1797 #endif
1798 
1799 
1800 /* FIXME: Everything below here needs to move somewhere else along with the
1801  * other EnumXXX functions, when a method for storing resources for
1802  * alternate calendars is determined.
1803  */
1804 
1809 };
1810 
1812  enum enum_callback_type type; /* callback kind */
1813  union {
1814  DATEFMT_ENUMPROCW callback; /* user callback pointer */
1817  } u;
1818  LCID lcid; /* locale of interest */
1821  BOOL unicode; /* A vs W callback type, only for regular and Ex callbacks */
1822 };
1823 
1824 /******************************************************************************
1825  * NLS_EnumDateFormats <internal>
1826  * Enumerates date formats for a specified locale.
1827  *
1828  * PARAMS
1829  * ctxt [I] enumeration context, see 'struct enumdateformats_context'
1830  *
1831  * RETURNS
1832  * Success: TRUE.
1833  * Failure: FALSE. Use GetLastError() to determine the cause.
1834  */
1836 {
1837  WCHAR bufW[256];
1838  char bufA[256];
1839  LCTYPE lctype;
1840  CALID cal_id;
1841  INT ret;
1842 
1843  if (!ctxt->u.callback)
1844  {
1846  return FALSE;
1847  }
1848 
1849  if (!GetLocaleInfoW(ctxt->lcid, LOCALE_ICALENDARTYPE|LOCALE_RETURN_NUMBER, (LPWSTR)&cal_id, sizeof(cal_id)/sizeof(WCHAR)))
1850  return FALSE;
1851 
1852  switch (ctxt->flags & ~LOCALE_USE_CP_ACP)
1853  {
1854  case 0:
1855  case DATE_SHORTDATE:
1856  lctype = LOCALE_SSHORTDATE;
1857  break;
1858  case DATE_LONGDATE:
1859  lctype = LOCALE_SLONGDATE;
1860  break;
1861  case DATE_YEARMONTH:
1862  lctype = LOCALE_SYEARMONTH;
1863  break;
1864  default:
1865  FIXME("Unknown date format (0x%08x)\n", ctxt->flags);
1867  return FALSE;
1868  }
1869 
1870  lctype |= ctxt->flags & LOCALE_USE_CP_ACP;
1871  if (ctxt->unicode)
1872  ret = GetLocaleInfoW(ctxt->lcid, lctype, bufW, ARRAY_SIZE(bufW));
1873  else
1874  ret = GetLocaleInfoA(ctxt->lcid, lctype, bufA, ARRAY_SIZE(bufA));
1875 
1876  if (ret)
1877  {
1878  switch (ctxt->type)
1879  {
1880  case CALLBACK_ENUMPROC:
1881  ctxt->u.callback(ctxt->unicode ? bufW : (WCHAR*)bufA);
1882  break;
1883  case CALLBACK_ENUMPROCEX:
1884  ctxt->u.callbackex(ctxt->unicode ? bufW : (WCHAR*)bufA, cal_id);
1885  break;
1886  case CALLBACK_ENUMPROCEXEX:
1887  ctxt->u.callbackexex(bufW, cal_id, ctxt->lParam);
1888  break;
1889  default:
1890  ;
1891  }
1892  }
1893 
1894  return TRUE;
1895 }
1896 
1897 /**************************************************************************
1898  * EnumDateFormatsExA (KERNEL32.@)
1899  *
1900  * FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle
1901  * LOCALE_NOUSEROVERRIDE here as well?
1902  */
1904 {
1905  struct enumdateformats_context ctxt;
1906 
1907  ctxt.type = CALLBACK_ENUMPROCEX;
1909  ctxt.lcid = lcid;
1910  ctxt.flags = flags;
1911  ctxt.unicode = FALSE;
1912 
1913  return NLS_EnumDateFormats(&ctxt);
1914 }
1915 
1916 /**************************************************************************
1917  * EnumDateFormatsExW (KERNEL32.@)
1918  */
1920 {
1921  struct enumdateformats_context ctxt;
1922 
1923  ctxt.type = CALLBACK_ENUMPROCEX;
1924  ctxt.u.callbackex = proc;
1925  ctxt.lcid = lcid;
1926  ctxt.flags = flags;
1927  ctxt.unicode = TRUE;
1928 
1929  return NLS_EnumDateFormats(&ctxt);
1930 }
1931 
1932 /**************************************************************************
1933  * EnumDateFormatsA (KERNEL32.@)
1934  *
1935  * FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle
1936  * LOCALE_NOUSEROVERRIDE here as well?
1937  */
1939 {
1940  struct enumdateformats_context ctxt;
1941 
1942  ctxt.type = CALLBACK_ENUMPROC;
1943  ctxt.u.callback = (DATEFMT_ENUMPROCW)proc;
1944  ctxt.lcid = lcid;
1945  ctxt.flags = flags;
1946  ctxt.unicode = FALSE;
1947 
1948  return NLS_EnumDateFormats(&ctxt);
1949 }
1950 
1951 /**************************************************************************
1952  * EnumDateFormatsW (KERNEL32.@)
1953  */
1955 {
1956  struct enumdateformats_context ctxt;
1957 
1958  ctxt.type = CALLBACK_ENUMPROC;
1959  ctxt.u.callback = proc;
1960  ctxt.lcid = lcid;
1961  ctxt.flags = flags;
1962  ctxt.unicode = TRUE;
1963 
1964  return NLS_EnumDateFormats(&ctxt);
1965 }
1966 
1967 #if _WIN32_WINNT >= 0x600
1968 /**************************************************************************
1969  * EnumDateFormatsExEx (KERNEL32.@)
1970  */
1971 BOOL WINAPI EnumDateFormatsExEx(DATEFMT_ENUMPROCEXEX proc, const WCHAR *locale, DWORD flags, LPARAM lParam)
1972 {
1973  struct enumdateformats_context ctxt;
1974 
1975  ctxt.type = CALLBACK_ENUMPROCEXEX;
1976  ctxt.u.callbackexex = proc;
1977  ctxt.lcid = LocaleNameToLCID(locale, 0);
1978  ctxt.flags = flags;
1979  ctxt.lParam = lParam;
1980  ctxt.unicode = TRUE;
1981 
1982  return NLS_EnumDateFormats(&ctxt);
1983 }
1984 #endif /* _WIN32_WINNT >= 0x600 */
1985 
1987  enum enum_callback_type type; /* callback kind */
1988  union {
1989  TIMEFMT_ENUMPROCW callback; /* user callback pointer */
1991  } u;
1992  LCID lcid; /* locale of interest */
1995  BOOL unicode; /* A vs W callback type, only for regular and Ex callbacks */
1996 };
1997 
1999 {
2000  WCHAR bufW[256];
2001  char bufA[256];
2002  LCTYPE lctype;
2003  INT ret;
2004 
2005  if (!ctxt->u.callback)
2006  {
2008  return FALSE;
2009  }
2010 
2011  switch (ctxt->flags & ~LOCALE_USE_CP_ACP)
2012  {
2013  case 0:
2014  lctype = LOCALE_STIMEFORMAT;
2015  break;
2016  case TIME_NOSECONDS:
2017  lctype = LOCALE_SSHORTTIME;
2018  break;
2019  default:
2020  FIXME("Unknown time format (%d)\n", ctxt->flags);
2022  return FALSE;
2023  }
2024 
2025  lctype |= ctxt->flags & LOCALE_USE_CP_ACP;
2026  if (ctxt->unicode)
2027  ret = GetLocaleInfoW(ctxt->lcid, lctype, bufW, ARRAY_SIZE(bufW));
2028  else
2029  ret = GetLocaleInfoA(ctxt->lcid, lctype, bufA, ARRAY_SIZE(bufA));
2030 
2031  if (ret)
2032  {
2033  switch (ctxt->type)
2034  {
2035  case CALLBACK_ENUMPROC:
2036  ctxt->u.callback(ctxt->unicode ? bufW : (WCHAR*)bufA);
2037  break;
2038  case CALLBACK_ENUMPROCEX:
2039  ctxt->u.callbackex(bufW, ctxt->lParam);
2040  break;
2041  default:
2042  ;
2043  }
2044  }
2045 
2046  return TRUE;
2047 }
2048 
2049 /**************************************************************************
2050  * EnumTimeFormatsA (KERNEL32.@)
2051  *
2052  * FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle
2053  * LOCALE_NOUSEROVERRIDE here as well?
2054  */
2056 {
2057  struct enumtimeformats_context ctxt;
2058 
2059  /* EnumTimeFormatsA doesn't support flags, EnumTimeFormatsW does. */
2060  if (flags & ~LOCALE_USE_CP_ACP)
2061  {
2063  return FALSE;
2064  }
2065 
2066  ctxt.type = CALLBACK_ENUMPROC;
2067  ctxt.u.callback = (TIMEFMT_ENUMPROCW)proc;
2068  ctxt.lcid = lcid;
2069  ctxt.flags = flags;
2070  ctxt.unicode = FALSE;
2071 
2072  return NLS_EnumTimeFormats(&ctxt);
2073 }
2074 
2075 /**************************************************************************
2076  * EnumTimeFormatsW (KERNEL32.@)
2077  */
2079 {
2080  struct enumtimeformats_context ctxt;
2081 
2082  ctxt.type = CALLBACK_ENUMPROC;
2083  ctxt.u.callback = proc;
2084  ctxt.lcid = lcid;
2085  ctxt.flags = flags;
2086  ctxt.unicode = TRUE;
2087 
2088  return NLS_EnumTimeFormats(&ctxt);
2089 }
2090 
2091 #if _WIN32_WINNT >= 0x600
2092 /**************************************************************************
2093  * EnumTimeFormatsEx (KERNEL32.@)
2094  */
2095 BOOL WINAPI EnumTimeFormatsEx(TIMEFMT_ENUMPROCEX proc, const WCHAR *locale, DWORD flags, LPARAM lParam)
2096 {
2097  struct enumtimeformats_context ctxt;
2098 
2099  ctxt.type = CALLBACK_ENUMPROCEX;
2100  ctxt.u.callbackex = proc;
2101  ctxt.lcid = LocaleNameToLCID(locale, 0);
2102  ctxt.flags = flags;
2103  ctxt.lParam = lParam;
2104  ctxt.unicode = TRUE;
2105 
2106  return NLS_EnumTimeFormats(&ctxt);
2107 }
2108 #endif /* _WIN32_WINNT >= 0x600 */
2109 
2111  enum enum_callback_type type; /* callback kind */
2112  union {
2113  CALINFO_ENUMPROCW callback; /* user callback pointer */
2116  } u;
2117  LCID lcid; /* locale of interest */
2118  CALID calendar; /* specific calendar or ENUM_ALL_CALENDARS */
2119  CALTYPE caltype; /* calendar information type */
2120  LPARAM lParam; /* user input parameter passed to callback, for ExEx case only */
2121  BOOL unicode; /* A vs W callback type, only for regular and Ex callbacks */
2122 };
2123 
2124 /******************************************************************************
2125  * NLS_EnumCalendarInfo <internal>
2126  * Enumerates calendar information for a specified locale.
2127  *
2128  * PARAMS
2129  * ctxt [I] enumeration context, see 'struct enumcalendar_context'
2130  *
2131  * RETURNS
2132  * Success: TRUE.
2133  * Failure: FALSE. Use GetLastError() to determine the cause.
2134  *
2135  * NOTES
2136  * When the ANSI version of this function is used with a Unicode-only LCID,
2137  * the call can succeed because the system uses the system code page.
2138  * However, characters that are undefined in the system code page appear
2139  * in the string as a question mark (?).
2140  *
2141  * TODO
2142  * The above note should be respected by GetCalendarInfoA.
2143  */
2145 {
2146  WCHAR *buf, *opt = NULL, *iter = NULL;
2147  CALID calendar = ctxt->calendar;
2148  BOOL ret = FALSE;
2149  int bufSz = 200; /* the size of the buffer */
2150 
2151  if (ctxt->u.callback == NULL)
2152  {
2154  return FALSE;
2155  }
2156 
2157  buf = HeapAlloc(GetProcessHeap(), 0, bufSz);
2158  if (buf == NULL)
2159  {
2161  return FALSE;
2162  }
2163 
2164  if (calendar == ENUM_ALL_CALENDARS)
2165  {
2166  int optSz = GetLocaleInfoW(ctxt->lcid, LOCALE_IOPTIONALCALENDAR, NULL, 0);
2167  if (optSz > 1)
2168  {
2169  opt = HeapAlloc(GetProcessHeap(), 0, optSz * sizeof(WCHAR));
2170  if (opt == NULL)
2171  {
2173  goto cleanup;
2174  }
2175  if (GetLocaleInfoW(ctxt->lcid, LOCALE_IOPTIONALCALENDAR, opt, optSz))
2176  iter = opt;
2177  }
2178  calendar = NLS_GetLocaleNumber(ctxt->lcid, LOCALE_ICALENDARTYPE);
2179  }
2180 
2181  while (TRUE) /* loop through calendars */
2182  {
2183  do /* loop until there's no error */
2184  {
2185  if (ctxt->caltype & CAL_RETURN_NUMBER)
2186  ret = GetCalendarInfoW(ctxt->lcid, calendar, ctxt->caltype, NULL, bufSz / sizeof(WCHAR), (LPDWORD)buf);
2187  else if (ctxt->unicode)
2188  ret = GetCalendarInfoW(ctxt->lcid, calendar, ctxt->caltype, buf, bufSz / sizeof(WCHAR), NULL);
2189  else ret = GetCalendarInfoA(ctxt->lcid, calendar, ctxt->caltype, (CHAR*)buf, bufSz / sizeof(CHAR), NULL);
2190 
2191  if (!ret)
2192  {
2194  { /* so resize it */
2195  int newSz;
2196  if (ctxt->unicode)
2197  newSz = GetCalendarInfoW(ctxt->lcid, calendar, ctxt->caltype, NULL, 0, NULL) * sizeof(WCHAR);
2198  else newSz = GetCalendarInfoA(ctxt->lcid, calendar, ctxt->caltype, NULL, 0, NULL) * sizeof(CHAR);
2199  if (bufSz >= newSz)
2200  {
2201  ERR("Buffer resizing disorder: was %d, requested %d.\n", bufSz, newSz);
2202  goto cleanup;
2203  }
2204  bufSz = newSz;
2205  WARN("Buffer too small; resizing to %d bytes.\n", bufSz);
2206  buf = HeapReAlloc(GetProcessHeap(), 0, buf, bufSz);
2207  if (buf == NULL)
2208  goto cleanup;
2209  } else goto cleanup;
2210  }
2211  } while (!ret);
2212 
2213  /* Here we are. We pass the buffer to the correct version of
2214  * the callback. Because it's not the same number of params,
2215  * we must check for Ex, but we don't care about Unicode
2216  * because the buffer is already in the correct format.
2217  */
2218  switch (ctxt->type)
2219  {
2220  case CALLBACK_ENUMPROC:
2221  ret = ctxt->u.callback(buf);
2222  break;
2223  case CALLBACK_ENUMPROCEX:
2224  ret = ctxt->u.callbackex(buf, calendar);
2225  break;
2226  case CALLBACK_ENUMPROCEXEX:
2227  ret = ctxt->u.callbackexex(buf, calendar, NULL, ctxt->lParam);
2228  break;
2229  default:
2230  ;
2231  }
2232 
2233  if (!ret) { /* the callback told to stop */
2234  ret = TRUE;
2235  break;
2236  }
2237 
2238  if ((iter == NULL) || (*iter == 0)) /* no more calendars */
2239  break;
2240 
2241  calendar = 0;
2242  while ((*iter >= '0') && (*iter <= '9'))
2243  calendar = calendar * 10 + *iter++ - '0';
2244 
2245  if (*iter++ != 0)
2246  {
2248  ret = FALSE;
2249  break;
2250  }
2251  }
2252 
2253 cleanup:
2254  HeapFree(GetProcessHeap(), 0, opt);
2255  HeapFree(GetProcessHeap(), 0, buf);
2256  return ret;
2257 }
2258 
2259 /******************************************************************************
2260  * EnumCalendarInfoA [KERNEL32.@]
2261  */
2263  CALID calendar,CALTYPE caltype )
2264 {
2265  struct enumcalendar_context ctxt;
2266 
2267  TRACE("(%p,0x%08x,0x%08x,0x%08x)\n", calinfoproc, locale, calendar, caltype);
2268 
2269  ctxt.type = CALLBACK_ENUMPROC;
2270  ctxt.u.callback = (CALINFO_ENUMPROCW)calinfoproc;
2271  ctxt.lcid = locale;
2272  ctxt.calendar = calendar;
2273  ctxt.caltype = caltype;
2274  ctxt.lParam = 0;
2275  ctxt.unicode = FALSE;
2276  return NLS_EnumCalendarInfo(&ctxt);
2277 }
2278 
2279 /******************************************************************************
2280  * EnumCalendarInfoW [KERNEL32.@]
2281  */
2284 {
2285  struct enumcalendar_context ctxt;
2286 
2287  TRACE("(%p,0x%08x,0x%08x,0x%08x)\n", calinfoproc, locale, calendar, caltype);
2288 
2289  ctxt.type = CALLBACK_ENUMPROC;
2290  ctxt.u.callback = calinfoproc;
2291  ctxt.lcid = locale;
2292  ctxt.calendar = calendar;
2293  ctxt.caltype = caltype;
2294  ctxt.lParam = 0;
2295  ctxt.unicode = TRUE;
2296  return NLS_EnumCalendarInfo(&ctxt);
2297 }
2298 
2299 /******************************************************************************
2300  * EnumCalendarInfoExA [KERNEL32.@]
2301  */
2304 {
2305  struct enumcalendar_context ctxt;
2306 
2307  TRACE("(%p,0x%08x,0x%08x,0x%08x)\n", calinfoproc, locale, calendar, caltype);
2308 
2309  ctxt.type = CALLBACK_ENUMPROCEX;
2310  ctxt.u.callbackex = (CALINFO_ENUMPROCEXW)calinfoproc;
2311  ctxt.lcid = locale;
2312  ctxt.calendar = calendar;
2313  ctxt.caltype = caltype;
2314  ctxt.lParam = 0;
2315  ctxt.unicode = FALSE;
2316  return NLS_EnumCalendarInfo(&ctxt);
2317 }
2318 
2319 /******************************************************************************
2320  * EnumCalendarInfoExW [KERNEL32.@]
2321  */
2324 {
2325  struct enumcalendar_context ctxt;
2326 
2327  TRACE("(%p,0x%08x,0x%08x,0x%08x)\n", calinfoproc, locale, calendar, caltype);
2328 
2329  ctxt.type = CALLBACK_ENUMPROCEX;
2330  ctxt.u.callbackex = calinfoproc;
2331  ctxt.lcid = locale;
2332  ctxt.calendar = calendar;
2333  ctxt.caltype = caltype;
2334  ctxt.lParam = 0;
2335  ctxt.unicode = TRUE;
2336  return NLS_EnumCalendarInfo(&ctxt);
2337 }
2338 
2339 #if _WIN32_WINNT >= 0x600
2340 /******************************************************************************
2341  * EnumCalendarInfoExEx [KERNEL32.@]
2342  */
2343 BOOL WINAPI EnumCalendarInfoExEx( CALINFO_ENUMPROCEXEX calinfoproc, LPCWSTR locale, CALID calendar,
2345 {
2346  struct enumcalendar_context ctxt;
2347 
2348  TRACE("(%p,%s,0x%08x,%p,0x%08x,0x%ld)\n", calinfoproc, debugstr_w(locale), calendar, reserved, caltype, lParam);
2349 
2350  ctxt.type = CALLBACK_ENUMPROCEXEX;
2351  ctxt.u.callbackexex = calinfoproc;
2352  ctxt.lcid = LocaleNameToLCID(locale, 0);
2353  ctxt.calendar = calendar;
2354  ctxt.caltype = caltype;
2355  ctxt.lParam = lParam;
2356  ctxt.unicode = TRUE;
2357  return NLS_EnumCalendarInfo(&ctxt);
2358 }
2359 #endif /* _WIN32_WINNT >= 0x600 */
2360 
2361 /*********************************************************************
2362  * GetCalendarInfoA (KERNEL32.@)
2363  *
2364  */
2366  LPSTR lpCalData, int cchData, LPDWORD lpValue)
2367 {
2368  int ret, cchDataW = cchData;
2369  LPWSTR lpCalDataW = NULL;
2370 
2372  {
2374  return 0;
2375  }
2376 
2377  if (!cchData && !(CalType & CAL_RETURN_NUMBER))
2378  cchDataW = GetCalendarInfoW(lcid, Calendar, CalType, NULL, 0, NULL);
2379  if (!(lpCalDataW = HeapAlloc(GetProcessHeap(), 0, cchDataW*sizeof(WCHAR))))
2380  return 0;
2381 
2382  ret = GetCalendarInfoW(lcid, Calendar, CalType, lpCalDataW, cchDataW, lpValue);
2383  if(ret && lpCalDataW && lpCalData)
2384  ret = WideCharToMultiByte(CP_ACP, 0, lpCalDataW, -1, lpCalData, cchData, NULL, NULL);
2385  else if (CalType & CAL_RETURN_NUMBER)
2386  ret *= sizeof(WCHAR);
2387  HeapFree(GetProcessHeap(), 0, lpCalDataW);
2388 
2389  return ret;
2390 }
2391 
2392 /*********************************************************************
2393  * GetCalendarInfoW (KERNEL32.@)
2394  *
2395  */
2396 int WINAPI GetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType,
2397  LPWSTR lpCalData, int cchData, LPDWORD lpValue)
2398 {
2399  static const LCTYPE caltype_lctype_map[] = {
2400  0, /* not used */
2401  0, /* CAL_ICALINTVALUE */
2402  0, /* CAL_SCALNAME */
2403  0, /* CAL_IYEAROFFSETRANGE */
2404  0, /* CAL_SERASTRING */
2447  LOCALE_SYEARMONTH,
2448  0, /* CAL_ITWODIGITYEARMAX */
2449 #if (WINVER >= 0x0600) /* ReactOS */
2450  LOCALE_SSHORTESTDAYNAME1,
2451  LOCALE_SSHORTESTDAYNAME2,
2452  LOCALE_SSHORTESTDAYNAME3,
2453  LOCALE_SSHORTESTDAYNAME4,
2454  LOCALE_SSHORTESTDAYNAME5,
2455  LOCALE_SSHORTESTDAYNAME6,
2456  LOCALE_SSHORTESTDAYNAME7,
2457 #endif
2459  0, /* CAL_SABBREVERASTRING */
2460  };
2461  DWORD localeflags = 0;
2462  CALTYPE calinfo;
2463 
2464  if (CalType & CAL_NOUSEROVERRIDE)
2465  FIXME("flag CAL_NOUSEROVERRIDE used, not fully implemented\n");
2466  if (CalType & CAL_USE_CP_ACP)
2467  FIXME("flag CAL_USE_CP_ACP used, not fully implemented\n");
2468 
2469  if (CalType & CAL_RETURN_NUMBER) {
2470  if (!lpValue)
2471  {
2473  return 0;
2474  }
2475  if (lpCalData != NULL)
2476  WARN("lpCalData not NULL (%p) when it should!\n", lpCalData);
2477  if (cchData != 0)
2478  WARN("cchData not 0 (%d) when it should!\n", cchData);
2479  } else {
2480  if (lpValue != NULL)
2481  WARN("lpValue not NULL (%p) when it should!\n", lpValue);
2482  }
2483 
2484  /* FIXME: No verification is made yet wrt Locale
2485  * for the CALTYPES not requiring GetLocaleInfoA */
2486 
2487  calinfo = CalType & 0xffff;
2488 
2489 #ifdef __REACTOS__
2490  if (CalType & LOCALE_RETURN_GENITIVE_NAMES)
2491 #else
2492  if (CalType & CAL_RETURN_GENITIVE_NAMES)
2493 #endif
2494  localeflags |= LOCALE_RETURN_GENITIVE_NAMES;
2495 
2496  switch (calinfo) {
2497  case CAL_ICALINTVALUE:
2498  if (CalType & CAL_RETURN_NUMBER)
2499  return GetLocaleInfoW(Locale, LOCALE_RETURN_NUMBER | LOCALE_ICALENDARTYPE,
2500  (LPWSTR)lpValue, 2);
2501  return GetLocaleInfoW(Locale, LOCALE_ICALENDARTYPE, lpCalData, cchData);
2502  case CAL_SCALNAME:
2503  FIXME("Unimplemented caltype %d\n", calinfo);
2504  if (lpCalData) *lpCalData = 0;
2505  return 1;
2506  case CAL_IYEAROFFSETRANGE:
2507  FIXME("Unimplemented caltype %d\n", calinfo);
2508  return 0;
2509  case CAL_SERASTRING:
2510  FIXME("Unimplemented caltype %d\n", calinfo);
2511  return 0;
2512  case CAL_SSHORTDATE:
2513  case CAL_SLONGDATE:
2514  case CAL_SDAYNAME1:
2515  case CAL_SDAYNAME2:
2516  case CAL_SDAYNAME3:
2517  case CAL_SDAYNAME4:
2518  case CAL_SDAYNAME5:
2519  case CAL_SDAYNAME6:
2520  case CAL_SDAYNAME7:
2521  case CAL_SABBREVDAYNAME1:
2522  case CAL_SABBREVDAYNAME2:
2523  case CAL_SABBREVDAYNAME3:
2524  case CAL_SABBREVDAYNAME4:
2525  case CAL_SABBREVDAYNAME5:
2526  case CAL_SABBREVDAYNAME6:
2527  case CAL_SABBREVDAYNAME7:
2528  case CAL_SMONTHNAME1:
2529  case CAL_SMONTHNAME2:
2530  case CAL_SMONTHNAME3:
2531  case CAL_SMONTHNAME4:
2532  case CAL_SMONTHNAME5:
2533  case CAL_SMONTHNAME6:
2534  case CAL_SMONTHNAME7:
2535  case CAL_SMONTHNAME8:
2536  case CAL_SMONTHNAME9:
2537  case CAL_SMONTHNAME10:
2538  case CAL_SMONTHNAME11:
2539  case CAL_SMONTHNAME12:
2540  case CAL_SMONTHNAME13:
2541  case CAL_SABBREVMONTHNAME1:
2542  case CAL_SABBREVMONTHNAME2:
2543  case CAL_SABBREVMONTHNAME3:
2544  case CAL_SABBREVMONTHNAME4:
2545  case CAL_SABBREVMONTHNAME5:
2546  case CAL_SABBREVMONTHNAME6:
2547  case CAL_SABBREVMONTHNAME7:
2548  case CAL_SABBREVMONTHNAME8:
2549  case CAL_SABBREVMONTHNAME9:
2554  case CAL_SYEARMONTH:
2555  return GetLocaleInfoW(Locale, caltype_lctype_map[calinfo] | localeflags, lpCalData, cchData);
2556  case CAL_ITWODIGITYEARMAX:
2557  if (CalType & CAL_RETURN_NUMBER)
2558  {
2559  *lpValue = CALINFO_MAX_YEAR;
2560  return sizeof(DWORD) / sizeof(WCHAR);
2561  }
2562  else
2563  {
2564  static const WCHAR fmtW[] = {'%','u',0};
2565  WCHAR buffer[10];
2566  int ret = snprintfW( buffer, 10, fmtW, CALINFO_MAX_YEAR ) + 1;
2567  if (!lpCalData) return ret;
2568  if (ret <= cchData)
2569  {
2570  strcpyW( lpCalData, buffer );
2571  return ret;
2572  }
2574  return 0;
2575  }
2576  break;
2577  default:
2578  FIXME("Unknown caltype %d\n", calinfo);
2580  return 0;
2581  }
2582  return 0;
2583 }
2584 
2585 #if _WIN32_WINNT >= 0x600
2586 /*********************************************************************
2587  * GetCalendarInfoEx (KERNEL32.@)
2588  */
2589 int WINAPI GetCalendarInfoEx(LPCWSTR locale, CALID calendar, LPCWSTR lpReserved, CALTYPE caltype,
2590  LPWSTR data, int len, DWORD *value)
2591 {
2592  static int once;
2593 
2594  LCID lcid = LocaleNameToLCID(locale, 0);
2595  if (!once++)
2596  FIXME("(%s, %d, %p, 0x%08x, %p, %d, %p): semi-stub\n", debugstr_w(locale), calendar, lpReserved, caltype,
2597  data, len, value);
2599 }
2600 #endif
2601 
2602 /*********************************************************************
2603  * SetCalendarInfoA (KERNEL32.@)
2604  *
2605  */
2606 int WINAPI SetCalendarInfoA(LCID Locale, CALID Calendar, CALTYPE CalType, LPCSTR lpCalData)
2607 {
2608  FIXME("(%08x,%08x,%08x,%s): stub\n",
2609  Locale, Calendar, CalType, debugstr_a(lpCalData));
2610  return 0;
2611 }
2612 
2613 /*********************************************************************
2614  * SetCalendarInfoW (KERNEL32.@)
2615  *
2616  *
2617  */
2618 int WINAPI SetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType, LPCWSTR lpCalData)
2619 {
2620  FIXME("(%08x,%08x,%08x,%s): stub\n",
2621  Locale, Calendar, CalType, debugstr_w(lpCalData));
2622  return 0;
2623 }
BOOL(CALLBACK * CALINFO_ENUMPROCA)(LPSTR)
Definition: winnls.h:524
LPWSTR lpThousandSep
Definition: winnls.h:643
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define LOCALE_SGROUPING
Definition: winnls.h:44
#define GetShortDate(fmt)
Definition: lcformat.c:89
#define CAL_SDAYNAME6
Definition: winnls.h:405
#define CAL_SCALNAME
Definition: winnls.h:395
#define LOCALE_IDEFAULTANSICODEPAGE
Definition: winnls.h:38
BOOL WINAPI EnumCalendarInfoExA(CALINFO_ENUMPROCEXA calinfoproc, LCID locale, CALID calendar, CALTYPE caltype)
Definition: lcformat.c:2302
BOOL WINAPI EnumCalendarInfoExW(CALINFO_ENUMPROCEXW calinfoproc, LCID locale, CALID calendar, CALTYPE caltype)
Definition: lcformat.c:2322
#define LOCALE_SABBREVMONTHNAME12
Definition: winnls.h:115
BOOL WINAPI EnumDateFormatsA(DATEFMT_ENUMPROCA proc, LCID lcid, DWORD flags)
Definition: lcformat.c:1938
#define GetNegative(fmt)
Definition: lcformat.c:87
#define CAL_SABBREVMONTHNAME12
Definition: winnls.h:438
#define TRUE
Definition: types.h:120
#define snprintfW
Definition: unicode.h:60
BOOL WINAPI EnumTimeFormatsW(TIMEFMT_ENUMPROCW proc, LCID lcid, DWORD flags)
Definition: lcformat.c:2078
CURRENCYFMTW cyfmt
Definition: lcformat.c:79
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
#define LOCALE_SABBREVDAYNAME2
Definition: winnls.h:85
#define LOCALE_SABBREVMONTHNAME1
Definition: winnls.h:104
BOOL WINAPI EnumDateFormatsExW(DATEFMT_ENUMPROCEXW proc, LCID lcid, DWORD flags)
Definition: lcformat.c:1919
#define DWORD_PTR
Definition: treelist.c:76
#define NF_ROUND
Definition: lcformat.c:1121
#define LOCALE_SMONTHNAME5
Definition: winnls.h:95
int WINAPI SetCalendarInfoA(LCID Locale, CALID Calendar, CALTYPE CalType, LPCSTR lpCalData)
Definition: lcformat.c:2606
#define WideCharToMultiByte
Definition: compat.h:101
LPWSTR lpDecimalSep
Definition: winnls.h:642
#define error(str)
Definition: mkdosfs.c:1605
UINT PositiveOrder
Definition: winnls.h:615
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define NLS_NEG_RIGHT_SPACE
Definition: lcformat.c:1128
UINT Grouping
Definition: winnls.h:611
#define LOCALE_SABBREVMONTHNAME6
Definition: winnls.h:109
WORD wMonth
Definition: winbase.h:871
#define LOCALE_SMONTHNAME2
Definition: winnls.h:92
UINT NegativeOrder
Definition: winnls.h:614
BOOL WINAPI EnumTimeFormatsA(TIMEFMT_ENUMPROCA proc, LCID lcid, DWORD flags)
Definition: lcformat.c:2055
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
CALINFO_ENUMPROCEXEX callbackexex
Definition: lcformat.c:2115
INT WINAPI GetDateFormatA(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCSTR lpFormat, LPSTR lpDateStr, INT cchOut)
Definition: lcformat.c:859
#define LOCALE_SABBREVDAYNAME4
Definition: winnls.h:87
#define LANG_HINDI
Definition: nls.h:68
UINT LeadingZero
Definition: winnls.h:610
#define CP_ACP
Definition: compat.h:99
INT WINAPI GetLocaleInfoA(LCID lcid, LCTYPE lctype, LPSTR buffer, INT len)
Definition: lang.c:1015
#define LOCALE_SABBREVDAYNAME7
Definition: winnls.h:90
#define LOCALE_SABBREVDAYNAME1
Definition: winnls.h:84
GLuint GLuint GLsizei count
Definition: gl.h:1545
WORD wDayOfWeek
Definition: winbase.h:872
#define DATE_SHORTDATE
Definition: winnls.h:193
INT WINAPI GetCurrencyFormatW(LCID lcid, DWORD dwFlags, LPCWSTR lpszValue, const CURRENCYFMTW *lpFormat, LPWSTR lpCurrencyStr, int cchOut)
Definition: lcformat.c:1501
BOOL WINAPI EnumDateFormatsExA(DATEFMT_ENUMPROCEXA proc, LCID lcid, DWORD flags)
Definition: lcformat.c:1903
char CHAR
Definition: xmlstorage.h:175
#define WARN(fmt,...)
Definition: debug.h:111
#define CAL_SMONTHNAME1
Definition: winnls.h:414
BOOL(CALLBACK * DATEFMT_ENUMPROCEXA)(LPSTR, CALID)
Definition: winnls.h:541
#define LOCALE_SMONTHNAME13
Definition: winnls.h:103
#define LOCALE_SDAYNAME2
Definition: winnls.h:78
#define LANG_DIVEHI
Definition: nls.h:50
#define TIME_TIMEVARSONLY
Definition: lcformat.c:60
const char * fmt
Definition: wsprintf.c:30
#define LOCALE_SMONTHNAME6
Definition: winnls.h:96
#define LOCALE_ICALENDARTYPE
Definition: winnls.h:73
#define LOCALE_ILZERO
Definition: winnls.h:46
void * next
Definition: dlist.c:360
UINT Grouping
Definition: winnls.h:641
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define GetGenitiveMonth(fmt, mth)
Definition: lcformat.c:98
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define CF_CY_RIGHT
Definition: lcformat.c:1493
#define LOCALE_SABBREVMONTHNAME7
Definition: winnls.h:110
GLuint buffer
Definition: glext.h:5915
int WINAPI GetDateFormatEx(LPCWSTR, DWORD, const SYSTEMTIME *, LPCWSTR, LPWSTR, int, LPCWSTR)
#define GetAM(fmt)
Definition: lcformat.c:91
#define IsLiteralMarker(p)
Definition: lcformat.c:370
DWORD LCID
Definition: nls.h:13
#define DATE_DATEVARSONLY
Definition: lcformat.c:59
static HANDLE proc()
Definition: pdb.c:32
#define CF_MINUS_BEFORE
Definition: lcformat.c:1491
LPWSTR lpThousandSep
Definition: winnls.h:613
__u16 time
Definition: mkdosfs.c:366
#define CAL_SERASTRING
Definition: winnls.h:397
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
char * LPSTR
Definition: xmlstorage.h:182
#define LOCALE_SABBREVMONTHNAME3
Definition: winnls.h:106
#define DWORD
Definition: nt_native.h:44
int32_t INT
Definition: typedefs.h:56
#define CAL_SMONTHNAME4
Definition: winnls.h:417
#define LOCALE_SMONTHNAME8
Definition: winnls.h:98
#define CAL_SDAYNAME3
Definition: winnls.h:402
#define LOCALE_RETURN_GENITIVE_NAMES
Definition: winnls.h:24
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#define CAL_SABBREVMONTHNAME7
Definition: winnls.h:433
#define LOCALE_SABBREVMONTHNAME8
Definition: winnls.h:111
#define LOCALE_SCURRENCY
Definition: winnls.h:49
UINT NegativeOrder
Definition: winnls.h:644
int WINAPI GetTimeFormatEx(LPCWSTR, DWORD, const SYSTEMTIME *, LPCWSTR, LPWSTR, int)
#define CF_MINUS_LEFT
Definition: lcformat.c:1489
#define LOCALE_INEGNUMBER
Definition: winnls.h:47
#define LOCALE_SDAYNAME5
Definition: winnls.h:81
#define CAL_SABBREVDAYNAME2
Definition: winnls.h:408
static const NLS_FORMAT_NODE * NLS_GetFormats(LCID lcid, DWORD dwFlags)
Definition: lcformat.c:171
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: lang.c:1095
enum enum_callback_type type
Definition: lcformat.c:1812
struct node node
#define LOCALE_SDAYNAME1
Definition: winnls.h:77
#define LOCALE_SABBREVDAYNAME3
Definition: winnls.h:86
INT WINAPI GetTimeFormatA(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCSTR lpFormat, LPSTR lpTimeStr, INT cchOut)
Definition: lcformat.c:967
#define CAL_SDAYNAME7
Definition: winnls.h:406
WORD wYear
Definition: winbase.h:870
union enumcalendar_context::@441 u
#define LOCALE_SABBREVMONTHNAME5
Definition: winnls.h:108
DWORD LCTYPE
Definition: winnls.h:514
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define LOCALE_SMONTHNAME1
Definition: winnls.h:91
#define LOCALE_STHOUSAND
Definition: winnls.h:43
#define LOCALE_NOUSEROVERRIDE
Definition: winnls.h:19
DATEFMT_ENUMPROCEXW callbackex
Definition: lcformat.c:1815
union enumtimeformats_context::@440 u
LCID WINAPI ConvertDefaultLocale(LCID lcid)
Definition: lang.c:1499
#define CAL_SABBREVDAYNAME3
Definition: winnls.h:409
Definition: _locale.h:75
#define CAL_SABBREVMONTHNAME10
Definition: winnls.h:436
unsigned int BOOL
Definition: ntddk_ex.h:94
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define CAL_SABBREVMONTHNAME4
Definition: winnls.h:430
#define NLS_NEG_LEFT_SPACE
Definition: lcformat.c:1126
#define LOCALE_SABBREVMONTHNAME10
Definition: winnls.h:113
static size_t double number
Definition: printf.c:64
#define LOCALE_SABBREVDAYNAME6
Definition: winnls.h:89
BOOL WINAPI EnumCalendarInfoW(CALINFO_ENUMPROCW calinfoproc, LCID locale, CALID calendar, CALTYPE caltype)
Definition: lcformat.c:2282
#define debugstr_w
Definition: kernel32.h:32
#define GetPM(fmt)
Definition: lcformat.c:92
UINT NumDigits
Definition: winnls.h:639
#define LOCALE_SLONGDATE
Definition: winnls.h:61
#define FIXME(fmt,...)
Definition: debug.h:110
static BOOL NLS_EnumDateFormats(const struct enumdateformats_context *ctxt)
Definition: lcformat.c:1835
int WINAPI GetCalendarInfoA(LCID lcid, CALID Calendar, CALTYPE CalType, LPSTR lpCalData, int cchData, LPDWORD lpValue)
Definition: lcformat.c:2365
CALINFO_ENUMPROCW callback
Definition: lcformat.c:2113
#define CAL_SSHORTDATE
Definition: winnls.h:398
r reserved
Definition: btrfs.c:2655
#define CAL_SABBREVMONTHNAME3
Definition: winnls.h:429
static CRITICAL_SECTION_DEBUG NLS_FormatsCS_debug
Definition: lcformat.c:103
#define GET_LOCALE_NUMBER(num, type)
Definition: lcformat.c:160
BOOL(CALLBACK * DATEFMT_ENUMPROCEXW)(LPWSTR, CALID)
Definition: winnls.h:542
#define CAL_SMONTHNAME13
Definition: winnls.h:426
#define CF_MINUS_RIGHT
Definition: lcformat.c:1490
const WCHAR * str
WORD wMinute
Definition: winbase.h:875
#define DEBUG_CHANNEL(args)
Definition: rdesktop.h:159
#define nls
Definition: kernel32.h:13
#define LOCALE_INEGCURR
Definition: winnls.h:57
#define LANG_KONKANI
Definition: nls.h:83
#define LOCALE_SABBREVMONTHNAME4
Definition: winnls.h:107
smooth NULL
Definition: ftsmooth.c:416
enum enum_callback_type type
Definition: lcformat.c:2111
static INT NLS_GetDateTimeFormatW(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCWSTR lpFormat, LPWSTR lpStr, INT cchOut)
Definition: lcformat.c:389
LONG_PTR LPARAM
Definition: windef.h:208
#define LOCALE_SMONTHNAME4
Definition: winnls.h:94
#define LOCALE_SABBREVMONTHNAME13
Definition: winnls.h:116
#define LOCALE_SDECIMAL
Definition: winnls.h:42
VOID WINAPI GetLocalTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:276
const char * LPCSTR
Definition: xmlstorage.h:183
#define GetLongDate(fmt)
Definition: lcformat.c:88
struct _NLS_FORMAT_NODE * next
Definition: lcformat.c:83
BOOL(CALLBACK * CALINFO_ENUMPROCW)(LPWSTR)
Definition: winnls.h:525
#define IsTimeFmtChar(p)
Definition: lcformat.c:372
#define GetLongMonth(fmt, mth)
Definition: lcformat.c:97
WCHAR szShortAM[2]
Definition: lcformat.c:81
#define CAL_SABBREVDAYNAME1
Definition: winnls.h:407
#define NLS_NEG_RIGHT
Definition: lcformat.c:1127
#define NLS_NUM_CACHED_STRINGS
Definition: lcformat.c:71
BOOL(CALLBACK * DATEFMT_ENUMPROCEXEX)(LPWSTR, CALID, LPARAM)
Definition: winnls.h:522
INT WINAPI GetCurrencyFormatA(LCID lcid, DWORD dwFlags, LPCSTR lpszValue, const CURRENCYFMTA *lpFormat, LPSTR lpCurrencyStr, int cchOut)
Definition: lcformat.c:1419
#define LOCALE_SDAYNAME4
Definition: winnls.h:80
#define CAL_SMONTHNAME7
Definition: winnls.h:420
#define LOCALE_SSHORTTIME
Definition: winnls.h:160
#define LOCALE_ICURRENCY
Definition: winnls.h:56
#define LOCALE_SMONDECIMALSEP
Definition: winnls.h:51
#define GetShortDay(fmt, day)
Definition: lcformat.c:96
#define LOCALE_SMONTHNAME11
Definition: winnls.h:101
BOOL WINAPI EnumCalendarInfoA(CALINFO_ENUMPROCA calinfoproc, LCID locale, CALID calendar, CALTYPE caltype)
Definition: lcformat.c:2262
BOOL WINAPI EnumDateFormatsW(DATEFMT_ENUMPROCW proc, LCID lcid, DWORD flags)
Definition: lcformat.c:1954
#define ENUM_ALL_CALENDARS
Definition: winnls.h:192
#define TRACE(s)
Definition: solgame.cpp:4
BOOL WINAPI FileTimeToSystemTime(IN CONST FILETIME *lpFileTime, OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:178
#define GetProcessHeap()
Definition: compat.h:395
#define LOCALE_SDAYNAME3
Definition: winnls.h:79
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define NF_ISREAL
Definition: lcformat.c:1118
#define LOCALE_SMONTHOUSANDSEP
Definition: winnls.h:52
#define LOCALE_SMONTHNAME10
Definition: winnls.h:100
__wchar_t WCHAR
Definition: xmlstorage.h:180
int WINAPI SetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType, LPCWSTR lpCalData)
Definition: lcformat.c:2618
#define CAL_ICALINTVALUE
Definition: winnls.h:394
#define CAL_SDAYNAME2
Definition: winnls.h:401
BOOL(CALLBACK * TIMEFMT_ENUMPROCA)(LPSTR)
Definition: winnls.h:543
#define debugstr_a
Definition: kernel32.h:31
#define GetLongDay(fmt, day)
Definition: lcformat.c:95
#define LANG_SANSKRIT
Definition: nls.h:115
BOOL NLS_IsUnicodeOnlyLcid(LCID lcid)
Definition: lcformat.c:343
#define LOCALE_SABBREVMONTHNAME2
Definition: winnls.h:105
#define WINAPI
Definition: msvc.h:8
#define CAL_SMONTHNAME6
Definition: winnls.h:419
#define TIME_NOMINUTESORSECONDS
Definition: winnls.h:274
#define CAL_SLONGDATE
Definition: winnls.h:399
unsigned long DWORD
Definition: ntddk_ex.h:95
DATEFMT_ENUMPROCW callback
Definition: lcformat.c:1814
#define SetLastError(x)
Definition: compat.h:409
#define CAL_IYEAROFFSETRANGE
Definition: winnls.h:396
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
DWORD CALTYPE
Definition: winnls.h:515
#define LOCALE_SDAYNAME7
Definition: winnls.h:83
GLbitfield flags
Definition: glext.h:7161
DWORD CALID
Definition: winnls.h:516
WORD wSecond
Definition: winbase.h:876
#define LOCALE_S1159
Definition: winnls.h:71
static DWORD NLS_GetLocaleNumber(LCID lcid, DWORD dwFlags)
Definition: lcformat.c:121
BOOL(CALLBACK * CALINFO_ENUMPROCEXW)(LPWSTR, CALID)
Definition: winnls.h:527
#define DATE_FORMAT_FLAGS
Definition: lcformat.c:375
TIMEFMT_ENUMPROCEX callbackex
Definition: lcformat.c:1990
#define CF_CY_LEFT
Definition: lcformat.c:1492
BOOL WINAPI IsValidLocale(LCID lcid, DWORD flags)
Definition: lang.c:1545
int ret
LPWSTR lpDecimalSep
Definition: winnls.h:612
#define CAL_SMONTHNAME12
Definition: winnls.h:425
#define CAL_SMONTHNAME11
Definition: winnls.h:424
#define LOCALE_SMONTHNAME3
Definition: winnls.h:93
#define LOCALE_SDAYNAME6
Definition: winnls.h:82
#define LOCALE_SNEGATIVESIGN
Definition: winnls.h:118
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define LOCALE_SSHORTDATE
Definition: winnls.h:60
#define LANG_KANNADA
Definition: nls.h:77
#define CAL_SABBREVDAYNAME4
Definition: winnls.h:410
static BOOL NLS_EnumTimeFormats(struct enumtimeformats_context *ctxt)
Definition: lcformat.c:1998
#define CAL_SABBREVMONTHNAME1
Definition: winnls.h:427
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
#define GetYearMonth(fmt)
Definition: lcformat.c:93
LPCWSTR lpFormat
Definition: trayclock.cpp:32
#define CAL_SABBREVMONTHNAME13
Definition: winnls.h:439
#define LOCALE_IDIGITS
Definition: winnls.h:45
#define NF_ISNEGATIVE
Definition: lcformat.c:1117
LIST_ENTRY ProcessLocksList
Definition: winbase.h:848
enum_callback_type
Definition: lcformat.c:1805
#define GET_LOCALE_STRING(str, type)
Definition: lcformat.c:163
#define CAL_SMONTHNAME5
Definition: winnls.h:418
#define LOCALE_USE_CP_ACP
Definition: winnls.h:20
#define NLS_NEG_LEFT
Definition: lcformat.c:1125
struct _NLS_FORMAT_NODE NLS_FORMAT_NODE
INT WINAPI GetDateFormatW(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCWSTR lpFormat, LPWSTR lpDateStr, INT cchOut)
Definition: lcformat.c:916
NUMBERFMTW fmt
Definition: lcformat.c:78
static BOOL NLS_EnumCalendarInfo(const struct enumcalendar_context *ctxt)
Definition: lcformat.c:2144
#define LANG_MARATHI
Definition: nls.h:98
BOOL(CALLBACK * CALINFO_ENUMPROCEXA)(LPSTR, CALID)
Definition: winnls.h:526
BOOL(CALLBACK * CALINFO_ENUMPROCEXEX)(LPWSTR, CALID, LPWSTR, LPARAM)
Definition: winnls.h:521
LPWSTR lpCurrencySymbol
Definition: winnls.h:616
#define CAL_SMONTHNAME2
Definition: winnls.h:415
#define ERR(fmt,...)
Definition: debug.h:109
WINE_DEFAULT_DEBUG_CHANNEL(nls)
#define CAL_SABBREVMONTHNAME11
Definition: winnls.h:437
WORD wDay
Definition: winbase.h:873
#define CAL_SMONTHNAME10
Definition: winnls.h:423
static const wchar_t void * locale
Definition: printf.c:73
#define LOCALE_SABBREVMONTHNAME9
Definition: winnls.h:112
static INT NLS_GetDateTimeFormatA(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCSTR lpFormat, LPSTR lpStr, INT cchOut)
Definition: lcformat.c:766
BOOL WINAPI SystemTimeToFileTime(IN CONST SYSTEMTIME *lpSystemTime, OUT LPFILETIME lpFileTime)
Definition: time.c:148
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
#define TIME_FORCE24HOURFORMAT
Definition: winnls.h:277
#define NLS_NEG_PARENS
Definition: lcformat.c:1124
#define LOCALE_SABBREVMONTHNAME11
Definition: winnls.h:114
BOOL(CALLBACK * TIMEFMT_ENUMPROCEX)(LPWSTR, LPARAM)
Definition: winnls.h:523
#define LANG_PUNJABI
Definition: nls.h:109
#define CAL_SABBREVMONTHNAME6
Definition: winnls.h:432
BOOL(CALLBACK * TIMEFMT_ENUMPROCW)(LPWSTR)
Definition: winnls.h:544
#define LOCALE_SABBREVDAYNAME5
Definition: winnls.h:88
#define IsDateFmtChar(p)
Definition: lcformat.c:371
#define ARRAY_SIZE(a)
Definition: main.h:24
__u16 date
Definition: mkdosfs.c:366
#define HeapReAlloc
Definition: compat.h:393
#define DATE_LONGDATE
Definition: winnls.h:194
WORD wHour
Definition: winbase.h:874
INT WINAPI GetNumberFormatA(LCID lcid, DWORD dwFlags, LPCSTR lpszValue, const NUMBERFMTA *lpFormat, LPSTR lpNumberStr, int cchOut)
Definition: lcformat.c:1053
DATEFMT_ENUMPROCEXEX callbackexex
Definition: lcformat.c:1816
#define LOCALE_SMONTHNAME9
Definition: winnls.h:99
#define CAL_SDAYNAME1
Definition: winnls.h:400
WCHAR szShortPM[2]
Definition: lcformat.c:82
#define GetShortMonth(fmt, mth)
Definition: lcformat.c:99
union enumdateformats_context::@439 u
#define LOCALE_SMONTHNAME12
Definition: winnls.h:102
#define MultiByteToWideChar
Definition: compat.h:100
#define CAL_SABBREVDAYNAME6
Definition: winnls.h:412
CALINFO_ENUMPROCEXW callbackex
Definition: lcformat.c:2114
UINT NumDigits
Definition: winnls.h:609
POINT cp
Definition: magnifier.c:60
Definition: name.c:36
DWORD dwCodePage
Definition: lcformat.c:77
WINE_UNICODE_INLINE int strcmpW(const WCHAR *str1, const WCHAR *str2)
Definition: unicode.h:229
#define LOCALE_SMONTHDAY
Definition: winnls.h:159
#define CF_CY_SPACE
Definition: lcformat.c:1494
static WCHAR * NLS_GetLocaleString(LCID lcid, DWORD dwFlags)
Definition: lcformat.c:146
uint32_t * LPDWORD
Definition: typedefs.h:57
#define LOCALE_SMONTHNAME7
Definition: winnls.h:97
#define GetTime(fmt)
Definition: lcformat.c:90
#define CAL_SABBREVMONTHNAME5
Definition: winnls.h:431
UINT LeadingZero
Definition: winnls.h:640
#define CAL_SMONTHNAME3
Definition: winnls.h:416
#define LANG_ARMENIAN
Definition: nls.h:30
char * cleanup(char *str)
Definition: wpickclick.c:99
#define CAL_SMONTHNAME8
Definition: winnls.h:421
#define TIME_NOSECONDS
Definition: winnls.h:275
static CRITICAL_SECTION NLS_FormatsCS
Definition: lcformat.c:102
#define CAL_SABBREVDAYNAME5
Definition: winnls.h:411
INT WINAPI GetNumberFormatW(LCID lcid, DWORD dwFlags, LPCWSTR lpszValue, const NUMBERFMTW *lpFormat, LPWSTR lpNumberStr, int cchOut)
Definition: lcformat.c:1135
#define NF_DIGITS
Definition: lcformat.c:1119
TIMEFMT_ENUMPROCW callback
Definition: lcformat.c:1989
#define LANG_GEORGIAN
Definition: nls.h:61
WCHAR * LPWSTR
Definition: xmlstorage.h:184
BOOL(CALLBACK * DATEFMT_ENUMPROCW)(LPWSTR)
Definition: winnls.h:540
#define NF_DIGITS_OUT
Definition: lcformat.c:1120
#define CAL_SABBREVMONTHNAME9
Definition: winnls.h:435
#define CAL_SABBREVDAYNAME7
Definition: winnls.h:413
INT WINAPI GetTimeFormatW(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCWSTR lpFormat, LPWSTR lpTimeStr, INT cchOut)
Definition: lcformat.c:1016
#define memset(x, y, z)
Definition: compat.h:39
BOOL(CALLBACK * DATEFMT_ENUMPROCA)(LPSTR)
Definition: winnls.h:539
#define CAL_SABBREVMONTHNAME2
Definition: winnls.h:428
#define CAL_SDAYNAME5
Definition: winnls.h:404
#define CHAR(Char)
#define LOCALE_IOPTIONALCALENDAR
Definition: winnls.h:74
LPWSTR lppszStrings[NLS_NUM_CACHED_STRINGS]
Definition: lcformat.c:80
#define LOCALE_S2359
Definition: winnls.h:72
#define LOCALE_STIMEFORMAT
Definition: winnls.h:62
LPARAM lParam
Definition: combotst.c:139
static unsigned char buff[32768]
Definition: fatten.c:17
Definition: dsound.c:943
#define HeapFree(x, y, z)
Definition: compat.h:394
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583
#define CF_PARENS
Definition: lcformat.c:1488
#define CAL_SMONTHNAME9
Definition: winnls.h:422
#define LANG_GUJARATI
Definition: nls.h:65
#define CAL_SABBREVMONTHNAME8
Definition: winnls.h:434
#define CAL_SDAYNAME4
Definition: winnls.h:403
#define TIME_NOTIMEMARKER
Definition: winnls.h:276
int WINAPI GetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType, LPWSTR lpCalData, int cchData, LPDWORD lpValue)
Definition: lcformat.c:2396
#define ERROR_BADDB
Definition: winerror.h:588
enum enum_callback_type type
Definition: lcformat.c:1987
Definition: dlist.c:348
#define PRIMARYLANGID(l)
Definition: nls.h:16
uchar outbuf[M_BLOCK_OUT]
Definition: unzcrash.c:41
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define TIME_FORMAT_FLAGS
Definition: lcformat.c:376