ReactOS  0.4.12-dev-712-ge6be187
nls.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS system libraries
4  * FILE: dll/win32/kernel32/winnls/string/nls.c
5  * PURPOSE: National Language Support
6  * PROGRAMMER: Filip Navara
7  * Hartmut Birr
8  * Gunnar Andre Dalsnes
9  * Thomas Weidenmueller
10  * UPDATE HISTORY:
11  * Created 24/08/2004
12  */
13 
14 /* INCLUDES *******************************************************************/
15 
16 #include <k32.h>
17 
18 #define NDEBUG
19 #include <debug.h>
20 
21 /* GLOBAL VARIABLES ***********************************************************/
22 
23 /* Sequence length based on the first character. */
24 static const char UTF8Length[128] =
25 {
26  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8F */
27  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9F */
28  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0 - 0xAF */
29  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0 - 0xBF */
30  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xC0 - 0xCF */
31  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xD0 - 0xDF */
32  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xE0 - 0xEF */
33  3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 0, 0 /* 0xF0 - 0xFF */
34 };
35 
36 /* First byte mask depending on UTF-8 sequence length. */
37 static const unsigned char UTF8Mask[6] = {0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
38 
39 /* FIXME: Change to HASH table or linear array. */
44 
45 /* FORWARD DECLARATIONS *******************************************************/
46 
49  LPSTR BaseName, LPSTR Result, ULONG ResultSize);
50 
52 GetCPFileNameFromRegistry(UINT CodePage, LPWSTR FileName, ULONG FileNameSize);
53 
54 /* PRIVATE FUNCTIONS **********************************************************/
55 
62 BOOL
65 {
68  HANDLE Handle;
69 
72 
73  /*
74  * FIXME: Eventually this should be done only for the NLS Server
75  * process, but since we don't have anything like that (yet?) we
76  * always try to create the "\Nls" directory here.
77  */
78  RtlInitUnicodeString(&DirName, L"\\Nls");
79 
81  &DirName,
83  NULL,
84  NULL);
85 
87  {
88  NtClose(Handle);
89  }
90 
91  /* Setup ANSI code page. */
93  AnsiCodePage.SectionMapping = NtCurrentTeb()->ProcessEnvironmentBlock->AnsiCodePageData;
94 
98 
100 
101  /* Setup OEM code page. */
103  OemCodePage.SectionMapping = NtCurrentTeb()->ProcessEnvironmentBlock->OemCodePageData;
104 
109 
110  return TRUE;
111 }
112 
119 VOID
120 FASTCALL
122 {
123  PCODEPAGE_ENTRY Current;
124 
125  /* Delete the code page list. */
126  while (!IsListEmpty(&CodePageListHead))
127  {
129  if (Current->SectionHandle != NULL)
130  {
132  NtClose(Current->SectionHandle);
133  }
135  }
137 }
138 
154 FASTCALL
156 {
157  LIST_ENTRY *CurrentEntry;
158  PCODEPAGE_ENTRY Current;
159 
161  for (CurrentEntry = CodePageListHead.Flink;
162  CurrentEntry != &CodePageListHead;
163  CurrentEntry = CurrentEntry->Flink)
164  {
165  Current = CONTAINING_RECORD(CurrentEntry, CODEPAGE_ENTRY, Entry);
166  if (Current->CodePage == CodePage)
167  {
169  return Current;
170  }
171  }
173 
174  return NULL;
175 }
176 
190 FASTCALL
192 {
193  CHAR SectionName[40];
195  HANDLE SectionHandle = INVALID_HANDLE_VALUE, FileHandle;
196  PBYTE SectionMapping;
198  ANSI_STRING AnsiName;
200  WCHAR FileName[MAX_PATH + 1];
201  UINT FileNamePos;
202  PCODEPAGE_ENTRY CodePageEntry;
203  if (CodePage == CP_ACP)
204  {
205  return &AnsiCodePage;
206  }
207  else if (CodePage == CP_OEMCP)
208  {
209  return &OemCodePage;
210  }
211  else if (CodePage == CP_THREAD_ACP)
212  {
214  LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
215  (WCHAR *)&CodePage,
216  sizeof(CodePage) / sizeof(WCHAR)))
217  {
218  /* Last error is set by GetLocaleInfoW. */
219  return NULL;
220  }
221  if (CodePage == 0)
222  return &AnsiCodePage;
223  }
224  else if (CodePage == CP_MACCP)
225  {
227  LOCALE_IDEFAULTMACCODEPAGE | LOCALE_RETURN_NUMBER,
228  (WCHAR *)&CodePage,
229  sizeof(CodePage) / sizeof(WCHAR)))
230  {
231  /* Last error is set by GetLocaleInfoW. */
232  return NULL;
233  }
234  }
235 
236  /* Try searching for loaded page first. */
237  CodePageEntry = IntGetLoadedCodePageEntry(CodePage);
238  if (CodePageEntry != NULL)
239  {
240  return CodePageEntry;
241  }
242 
243  /*
244  * Yes, we really want to lock here. Otherwise it can happen that
245  * two parallel requests will try to get the entry for the same
246  * code page and we would load it twice.
247  */
249 
250  /* Generate the section name. */
251  if (!GetNlsSectionName(CodePage,
252  10,
253  0,
254  "\\Nls\\NlsSectionCP",
255  SectionName,
256  sizeof(SectionName)))
257  {
259  return NULL;
260  }
261 
262  RtlInitAnsiString(&AnsiName, SectionName);
264 
266 
267  /* Try to open the section first */
269 
270  /* If the section doesn't exist, try to create it. */
271  if (Status == STATUS_UNSUCCESSFUL ||
274  {
275  FileNamePos = GetSystemDirectoryW(FileName, MAX_PATH);
276  if (GetCPFileNameFromRegistry(CodePage,
277  FileName + FileNamePos + 1,
278  MAX_PATH - FileNamePos - 1))
279  {
280  FileName[FileNamePos] = L'\\';
281  FileName[MAX_PATH] = 0;
285  NULL,
287  0,
288  NULL);
289 
290  Status = NtCreateSection(&SectionHandle,
293  NULL,
295  SEC_COMMIT,
296  FileHandle);
297 
298  /* HACK: Check if another process was faster
299  * and already created this section. See bug 3626 for details */
301  {
302  /* Close the file then */
304 
305  /* And open the section */
306  Status = NtOpenSection(&SectionHandle,
309  }
310  }
311  }
313 
314  if (!NT_SUCCESS(Status))
315  {
317  return NULL;
318  }
319 
320  SectionMapping = MapViewOfFile(SectionHandle, FILE_MAP_READ, 0, 0, 0);
321  if (SectionMapping == NULL)
322  {
323  NtClose(SectionHandle);
325  return NULL;
326  }
327 
328  CodePageEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(CODEPAGE_ENTRY));
329  if (CodePageEntry == NULL)
330  {
331  NtClose(SectionHandle);
333  return NULL;
334  }
335 
336  CodePageEntry->CodePage = CodePage;
337  CodePageEntry->SectionHandle = SectionHandle;
338  CodePageEntry->SectionMapping = SectionMapping;
339 
340  RtlInitCodePageTable((PUSHORT)SectionMapping, &CodePageEntry->CodePageTable);
341 
342  /* Insert the new entry to list and unlock. Uff. */
343  InsertTailList(&CodePageListHead, &CodePageEntry->Entry);
345 
346  return CodePageEntry;
347 }
348 
358 static
359 INT
360 WINAPI
363  INT MultiByteCount,
364  LPWSTR WideCharString,
365  INT WideCharCount)
366 {
367  LPCSTR MbsEnd;
368  UCHAR Char, Length;
369  WCHAR WideChar;
370  LONG Count;
371 
372  if (Flags != 0 && Flags != MB_ERR_INVALID_CHARS)
373  {
375  return 0;
376  }
377 
378  /* Does caller query for output buffer size? */
379  if (WideCharCount == 0)
380  {
381  MbsEnd = MultiByteString + MultiByteCount;
382  for (; MultiByteString < MbsEnd; WideCharCount++)
383  {
384  Char = *MultiByteString++;
385  if (Char < 0xC0)
386  continue;
387  MultiByteString += UTF8Length[Char - 0x80];
388  }
389  return WideCharCount;
390  }
391 
392  MbsEnd = MultiByteString + MultiByteCount;
393  for (Count = 0; Count < WideCharCount && MultiByteString < MbsEnd; Count++)
394  {
395  Char = *MultiByteString++;
396  if (Char < 0x80)
397  {
398  *WideCharString++ = Char;
399  continue;
400  }
401  Length = UTF8Length[Char - 0x80];
402  WideChar = Char & UTF8Mask[Length];
403  while (Length && MultiByteString < MbsEnd)
404  {
405  WideChar = (WideChar << 6) | (*MultiByteString++ & 0x7f);
406  Length--;
407  }
408  *WideCharString++ = WideChar;
409  }
410 
411  if (MultiByteString < MbsEnd)
413 
414  return Count;
415 }
416 
427 static
428 INT
429 WINAPI
431  DWORD Flags,
433  INT MultiByteCount,
434  LPWSTR WideCharString,
435  INT WideCharCount)
436 {
437  PCODEPAGE_ENTRY CodePageEntry;
439  PUSHORT MultiByteTable;
440  LPCSTR TempString;
441  INT TempLength;
442  USHORT WideChar;
443 
444  /* Get code page table. */
445  CodePageEntry = IntGetCodePageEntry(CodePage);
446  if (CodePageEntry == NULL)
447  {
449  return 0;
450  }
451 
452  CodePageTable = &CodePageEntry->CodePageTable;
453 
454  /* If MB_USEGLYPHCHARS flag present and glyph table present */
456  {
457  /* Use glyph table */
458  MultiByteTable = CodePageTable->MultiByteTable + 256 + 1;
459  }
460  else
461  {
462  MultiByteTable = CodePageTable->MultiByteTable;
463  }
464 
465  /* Different handling for DBCS code pages. */
467  {
468  UCHAR Char;
469  USHORT DBCSOffset;
470  LPCSTR MbsEnd = MultiByteString + MultiByteCount;
471  INT Count;
472 
474  {
475  TempString = MultiByteString;
476 
477  while (TempString < MbsEnd)
478  {
479  DBCSOffset = CodePageTable->DBCSOffsets[(UCHAR)*TempString];
480 
481  if (DBCSOffset)
482  {
483  /* If lead byte is presented, but behind it there is no symbol */
484  if (((TempString + 1) == MbsEnd) || (*(TempString + 1) == 0))
485  {
487  return 0;
488  }
489 
490  WideChar = CodePageTable->DBCSOffsets[DBCSOffset + *(TempString + 1)];
491 
492  if (WideChar == CodePageTable->UniDefaultChar &&
493  MAKEWORD(*(TempString + 1), *TempString) != CodePageTable->TransUniDefaultChar)
494  {
496  return 0;
497  }
498 
499  TempString++;
500  }
501  else
502  {
503  WideChar = MultiByteTable[(UCHAR)*TempString];
504 
505  if ((WideChar == CodePageTable->UniDefaultChar &&
506  *TempString != CodePageTable->TransUniDefaultChar) ||
507  /* "Private Use" characters */
508  (WideChar >= 0xE000 && WideChar <= 0xF8FF))
509  {
511  return 0;
512  }
513  }
514 
515  TempString++;
516  }
517  }
518 
519  /* Does caller query for output buffer size? */
520  if (WideCharCount == 0)
521  {
522  for (; MultiByteString < MbsEnd; WideCharCount++)
523  {
524  Char = *MultiByteString++;
525 
526  DBCSOffset = CodePageTable->DBCSOffsets[Char];
527 
528  if (!DBCSOffset)
529  continue;
530 
531  if (MultiByteString < MbsEnd)
532  MultiByteString++;
533  }
534 
535  return WideCharCount;
536  }
537 
538  for (Count = 0; Count < WideCharCount && MultiByteString < MbsEnd; Count++)
539  {
540  Char = *MultiByteString++;
541 
542  DBCSOffset = CodePageTable->DBCSOffsets[Char];
543 
544  if (!DBCSOffset)
545  {
546  *WideCharString++ = MultiByteTable[Char];
547  continue;
548  }
549 
550  if (MultiByteString == MbsEnd)
551  {
552  *WideCharString++ = UNICODE_NULL;
553  }
554  else if (*MultiByteString == 0)
555  {
556  *WideCharString++ = UNICODE_NULL;
557  MultiByteString++;
558  }
559  else
560  {
561  *WideCharString++ = CodePageTable->DBCSOffsets[DBCSOffset + (UCHAR)*MultiByteString++];
562  }
563  }
564 
565  if (MultiByteString < MbsEnd)
566  {
568  return 0;
569  }
570 
571  return Count;
572  }
573  else /* SBCS code page */
574  {
575  /* Check for invalid characters. */
577  {
578  for (TempString = MultiByteString, TempLength = MultiByteCount;
579  TempLength > 0;
580  TempString++, TempLength--)
581  {
582  WideChar = MultiByteTable[(UCHAR)*TempString];
583 
584  if ((WideChar == CodePageTable->UniDefaultChar &&
585  *TempString != CodePageTable->TransUniDefaultChar) ||
586  /* "Private Use" characters */
587  (WideChar >= 0xE000 && WideChar <= 0xF8FF))
588  {
590  return 0;
591  }
592  }
593  }
594 
595  /* Does caller query for output buffer size? */
596  if (WideCharCount == 0)
597  return MultiByteCount;
598 
599  /* Fill the WideCharString buffer with what will fit: Verified on WinXP */
600  for (TempLength = (WideCharCount < MultiByteCount) ? WideCharCount : MultiByteCount;
601  TempLength > 0;
602  MultiByteString++, TempLength--)
603  {
604  *WideCharString++ = MultiByteTable[(UCHAR)*MultiByteString];
605  }
606 
607  /* Adjust buffer size. Wine trick ;-) */
608  if (WideCharCount < MultiByteCount)
609  {
610  MultiByteCount = WideCharCount;
612  return 0;
613  }
614  return MultiByteCount;
615  }
616 }
617 
626 static
627 INT
628 WINAPI
631  INT MultiByteCount,
632  LPWSTR WideCharString,
633  INT WideCharCount)
634 {
635  LONG Count;
636  UCHAR Char;
637  INT WideCharMaxLen;
638 
639 
640  if (Flags != 0)
641  {
643  return 0;
644  }
645 
646  if (WideCharCount == 0)
647  {
648  return MultiByteCount;
649  }
650 
651  WideCharMaxLen = WideCharCount > MultiByteCount ? MultiByteCount : WideCharCount;
652 
653  for (Count = 0; Count < WideCharMaxLen; Count++)
654  {
656  if ( Char < 0x20 )
657  {
658  WideCharString[Count] = Char;
659  }
660  else
661  {
662  WideCharString[Count] = Char + 0xf000;
663  }
664  }
665  if (MultiByteCount > WideCharMaxLen)
666  {
668  return 0;
669  }
670 
671  return WideCharMaxLen;
672 }
673 
682 static INT
683 WINAPI
685  LPCWSTR WideCharString,
686  INT WideCharCount,
688  INT MultiByteCount)
689 {
690  LONG Count;
691  INT MaxLen;
692  WCHAR Char;
693 
694  if (Flags!=0)
695  {
697  return 0;
698  }
699 
700 
701  if (MultiByteCount == 0)
702  {
703  return WideCharCount;
704  }
705 
706  MaxLen = MultiByteCount > WideCharCount ? WideCharCount : MultiByteCount;
707  for (Count = 0; Count < MaxLen; Count++)
708  {
709  Char = WideCharString[Count];
710  if (Char < 0x20)
711  {
713  }
714  else
715  {
716  if ((Char >= 0xf020) && (Char < 0xf100))
717  {
718  MultiByteString[Count] = Char - 0xf000;
719  }
720  else
721  {
723  return 0;
724  }
725  }
726  }
727 
728  if (WideCharCount > MaxLen)
729  {
731  return 0;
732  }
733  return MaxLen;
734 }
735 
744 static INT
745 WINAPI
747  DWORD Flags,
748  LPCWSTR WideCharString,
749  INT WideCharCount,
751  INT MultiByteCount,
752  LPCSTR DefaultChar,
753  LPBOOL UsedDefaultChar)
754 {
755  INT TempLength;
756  DWORD Char;
757 
758  if (Flags)
759  {
761  return 0;
762  }
763 
764  /* Does caller query for output buffer size? */
765  if (MultiByteCount == 0)
766  {
767  for (TempLength = 0; WideCharCount;
768  WideCharCount--, WideCharString++)
769  {
770  TempLength++;
771  if (*WideCharString >= 0x80)
772  {
773  TempLength++;
774  if (*WideCharString >= 0x800)
775  {
776  TempLength++;
777  if (*WideCharString >= 0xd800 && *WideCharString < 0xdc00 &&
778  WideCharCount >= 1 &&
779  WideCharString[1] >= 0xdc00 && WideCharString[1] <= 0xe000)
780  {
781  WideCharCount--;
782  WideCharString++;
783  TempLength++;
784  }
785  }
786  }
787  }
788  return TempLength;
789  }
790 
791  for (TempLength = MultiByteCount; WideCharCount; WideCharCount--, WideCharString++)
792  {
793  Char = *WideCharString;
794  if (Char < 0x80)
795  {
796  if (!TempLength)
797  {
799  break;
800  }
801  TempLength--;
802  *MultiByteString++ = (CHAR)Char;
803  continue;
804  }
805 
806  if (Char < 0x800) /* 0x80-0x7ff: 2 bytes */
807  {
808  if (TempLength < 2)
809  {
811  break;
812  }
813  MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
814  MultiByteString[0] = 0xc0 | Char;
815  MultiByteString += 2;
816  TempLength -= 2;
817  continue;
818  }
819 
820  /* surrogate pair 0x10000-0x10ffff: 4 bytes */
821  if (Char >= 0xd800 && Char < 0xdc00 &&
822  WideCharCount >= 1 &&
823  WideCharString[1] >= 0xdc00 && WideCharString[1] < 0xe000)
824  {
825  WideCharCount--;
826  WideCharString++;
827 
828  if (TempLength < 4)
829  {
831  break;
832  }
833 
834  Char = (Char - 0xd800) << 10;
835  Char |= *WideCharString - 0xdc00;
836  ASSERT(Char <= 0xfffff);
837  Char += 0x10000;
838  ASSERT(Char <= 0x10ffff);
839 
840  MultiByteString[3] = 0x80 | (Char & 0x3f); Char >>= 6;
841  MultiByteString[2] = 0x80 | (Char & 0x3f); Char >>= 6;
842  MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
843  MultiByteString[0] = 0xf0 | Char;
844  MultiByteString += 4;
845  TempLength -= 4;
846  continue;
847  }
848 
849  /* 0x800-0xffff: 3 bytes */
850  if (TempLength < 3)
851  {
853  break;
854  }
855  MultiByteString[2] = 0x80 | (Char & 0x3f); Char >>= 6;
856  MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
857  MultiByteString[0] = 0xe0 | Char;
858  MultiByteString += 3;
859  TempLength -= 3;
860  }
861 
862  return MultiByteCount - TempLength;
863 }
864 
872 static
873 inline
874 BOOL
876 {
877  /* If the WC_NO_BEST_FIT_CHARS flag has been specified, the characters need to match exactly. */
879  return (CodePageTable->MultiByteTable[ch] == wch);
880 
881  /* By default, all characters except TransDefaultChar apply as a valid mapping
882  for ch (so also "nearest" characters) */
883  if (ch != CodePageTable->TransDefaultChar)
884  return TRUE;
885 
886  /* The only possible left valid mapping is the default character itself */
887  return (wch == CodePageTable->TransUniDefaultChar);
888 }
889 
897 static inline BOOL
899 {
900  /* If ch is the default character, but the wch is not, it can't be a valid mapping */
902  return FALSE;
903 
904  /* If the WC_NO_BEST_FIT_CHARS flag has been specified, the characters need to match exactly. */
906  {
907  if(ch & 0xff00)
908  {
909  USHORT uOffset = CodePageTable->DBCSOffsets[ch >> 8];
910  /* if (!uOffset) return (CodePageTable->MultiByteTable[ch] == wch); */
911  return (CodePageTable->DBCSOffsets[uOffset + (ch & 0xff)] == wch);
912  }
913 
914  return (CodePageTable->MultiByteTable[ch] == wch);
915  }
916 
917  /* If we're still here, we have a valid mapping */
918  return TRUE;
919 }
920 
929 static
930 INT
931 WINAPI
933  DWORD Flags,
934  LPCWSTR WideCharString,
935  INT WideCharCount,
937  INT MultiByteCount,
938  LPCSTR DefaultChar,
939  LPBOOL UsedDefaultChar)
940 {
941  PCODEPAGE_ENTRY CodePageEntry;
943  INT TempLength;
944 
945  /* Get code page table. */
946  CodePageEntry = IntGetCodePageEntry(CodePage);
947  if (CodePageEntry == NULL)
948  {
950  return 0;
951  }
952 
953  CodePageTable = &CodePageEntry->CodePageTable;
954 
955 
956  /* Different handling for DBCS code pages. */
958  {
959  /* If Flags, DefaultChar or UsedDefaultChar were given, we have to do some more work */
960  if (Flags || DefaultChar || UsedDefaultChar)
961  {
962  BOOL TempUsedDefaultChar;
963  USHORT DefChar;
964 
965  /* If UsedDefaultChar is not set, set it to a temporary value, so we don't have
966  to check on every character */
967  if (!UsedDefaultChar)
968  UsedDefaultChar = &TempUsedDefaultChar;
969 
970  *UsedDefaultChar = FALSE;
971 
972  /* Use the CodePage's TransDefaultChar if none was given. Don't modify the DefaultChar pointer here. */
973  if (DefaultChar)
974  DefChar = DefaultChar[1] ? ((DefaultChar[0] << 8) | DefaultChar[1]) : DefaultChar[0];
975  else
976  DefChar = CodePageTable->TransDefaultChar;
977 
978  /* Does caller query for output buffer size? */
979  if (!MultiByteCount)
980  {
981  for (TempLength = 0; WideCharCount; WideCharCount--, WideCharString++, TempLength++)
982  {
983  USHORT uChar;
984 
985  if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
986  {
987  /* FIXME: Handle WC_COMPOSITECHECK */
988  DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
989  }
990 
991  uChar = ((PUSHORT) CodePageTable->WideCharTable)[*WideCharString];
992 
993  /* Verify if the mapping is valid for handling DefaultChar and UsedDefaultChar */
994  if (!IntIsValidDBCSMapping(CodePageTable, Flags, *WideCharString, uChar))
995  {
996  uChar = DefChar;
997  *UsedDefaultChar = TRUE;
998  }
999 
1000  /* Increment TempLength again if this is a double-byte character */
1001  if (uChar & 0xff00)
1002  TempLength++;
1003  }
1004 
1005  return TempLength;
1006  }
1007 
1008  /* Convert the WideCharString to the MultiByteString and verify if the mapping is valid */
1009  for (TempLength = MultiByteCount;
1010  WideCharCount && TempLength;
1011  TempLength--, WideCharString++, WideCharCount--)
1012  {
1013  USHORT uChar;
1014 
1015  if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1016  {
1017  /* FIXME: Handle WC_COMPOSITECHECK */
1018  DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1019  }
1020 
1021  uChar = ((PUSHORT)CodePageTable->WideCharTable)[*WideCharString];
1022 
1023  /* Verify if the mapping is valid for handling DefaultChar and UsedDefaultChar */
1024  if (!IntIsValidDBCSMapping(CodePageTable, Flags, *WideCharString, uChar))
1025  {
1026  uChar = DefChar;
1027  *UsedDefaultChar = TRUE;
1028  }
1029 
1030  /* Handle double-byte characters */
1031  if (uChar & 0xff00)
1032  {
1033  /* Don't output a partial character */
1034  if (TempLength == 1)
1035  break;
1036 
1037  TempLength--;
1038  *MultiByteString++ = uChar >> 8;
1039  }
1040 
1041  *MultiByteString++ = (char)uChar;
1042  }
1043 
1044  /* WideCharCount should be 0 if all characters were converted */
1045  if (WideCharCount)
1046  {
1048  return 0;
1049  }
1050 
1051  return MultiByteCount - TempLength;
1052  }
1053 
1054  /* Does caller query for output buffer size? */
1055  if (!MultiByteCount)
1056  {
1057  for (TempLength = 0; WideCharCount; WideCharCount--, WideCharString++, TempLength++)
1058  {
1059  /* Increment TempLength again if this is a double-byte character */
1060  if (((PWCHAR)CodePageTable->WideCharTable)[*WideCharString] & 0xff00)
1061  TempLength++;
1062  }
1063 
1064  return TempLength;
1065  }
1066 
1067  /* Convert the WideCharString to the MultiByteString */
1068  for (TempLength = MultiByteCount;
1069  WideCharCount && TempLength;
1070  TempLength--, WideCharString++, WideCharCount--)
1071  {
1072  USHORT uChar = ((PUSHORT) CodePageTable->WideCharTable)[*WideCharString];
1073 
1074  /* Is this a double-byte character? */
1075  if (uChar & 0xff00)
1076  {
1077  /* Don't output a partial character */
1078  if (TempLength == 1)
1079  break;
1080 
1081  TempLength--;
1082  *MultiByteString++ = uChar >> 8;
1083  }
1084 
1085  *MultiByteString++ = (char)uChar;
1086  }
1087 
1088  /* WideCharCount should be 0 if all characters were converted */
1089  if (WideCharCount)
1090  {
1092  return 0;
1093  }
1094 
1095  return MultiByteCount - TempLength;
1096  }
1097  else /* SBCS code page */
1098  {
1099  INT nReturn;
1100 
1101  /* If Flags, DefaultChar or UsedDefaultChar were given, we have to do some more work */
1102  if (Flags || DefaultChar || UsedDefaultChar)
1103  {
1104  BOOL TempUsedDefaultChar;
1105  CHAR DefChar;
1106 
1107  /* If UsedDefaultChar is not set, set it to a temporary value, so we don't have
1108  to check on every character */
1109  if (!UsedDefaultChar)
1110  UsedDefaultChar = &TempUsedDefaultChar;
1111 
1112  *UsedDefaultChar = FALSE;
1113 
1114  /* Does caller query for output buffer size? */
1115  if (!MultiByteCount)
1116  {
1117  /* Loop through the whole WideCharString and check if we can get a valid mapping for each character */
1118  for (TempLength = 0; WideCharCount; TempLength++, WideCharString++, WideCharCount--)
1119  {
1120  if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1121  {
1122  /* FIXME: Handle WC_COMPOSITECHECK */
1123  DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1124  }
1125 
1126  if (!*UsedDefaultChar)
1127  *UsedDefaultChar = !IntIsValidSBCSMapping(CodePageTable,
1128  Flags,
1129  *WideCharString,
1130  ((PCHAR)CodePageTable->WideCharTable)[*WideCharString]);
1131  }
1132 
1133  return TempLength;
1134  }
1135 
1136  /* Use the CodePage's TransDefaultChar if none was given. Don't modify the DefaultChar pointer here. */
1137  if (DefaultChar)
1138  DefChar = *DefaultChar;
1139  else
1140  DefChar = (CHAR)CodePageTable->TransDefaultChar;
1141 
1142  /* Convert the WideCharString to the MultiByteString and verify if the mapping is valid */
1143  for (TempLength = MultiByteCount;
1144  WideCharCount && TempLength;
1145  MultiByteString++, TempLength--, WideCharString++, WideCharCount--)
1146  {
1147  if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1148  {
1149  /* FIXME: Handle WC_COMPOSITECHECK */
1150  DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1151  }
1152 
1153  *MultiByteString = ((PCHAR)CodePageTable->WideCharTable)[*WideCharString];
1154 
1155  if (!IntIsValidSBCSMapping(CodePageTable, Flags, *WideCharString, *MultiByteString))
1156  {
1157  *MultiByteString = DefChar;
1158  *UsedDefaultChar = TRUE;
1159  }
1160  }
1161 
1162  /* WideCharCount should be 0 if all characters were converted */
1163  if (WideCharCount)
1164  {
1166  return 0;
1167  }
1168 
1169  return MultiByteCount - TempLength;
1170  }
1171 
1172  /* Does caller query for output buffer size? */
1173  if (!MultiByteCount)
1174  return WideCharCount;
1175 
1176  /* Is the buffer large enough? */
1177  if (MultiByteCount < WideCharCount)
1178  {
1179  /* Convert the string up to MultiByteCount and return 0 */
1180  WideCharCount = MultiByteCount;
1182  nReturn = 0;
1183  }
1184  else
1185  {
1186  /* Otherwise WideCharCount will be the number of converted characters */
1187  nReturn = WideCharCount;
1188  }
1189 
1190  /* Convert the WideCharString to the MultiByteString */
1191  for (TempLength = WideCharCount; --TempLength >= 0; WideCharString++, MultiByteString++)
1192  {
1193  *MultiByteString = ((PCHAR)CodePageTable->WideCharTable)[*WideCharString];
1194  }
1195 
1196  return nReturn;
1197  }
1198 }
1199 
1207 static BOOL
1208 WINAPI
1210 {
1211  UINT i;
1212 
1213  if (TableInfo->MaximumCharacterSize == 2)
1214  {
1215  for (i = 0; i < MAXIMUM_LEADBYTES && TableInfo->LeadByte[i]; i += 2)
1216  {
1217  if (Byte >= TableInfo->LeadByte[i] && Byte <= TableInfo->LeadByte[i+1])
1218  return TRUE;
1219  }
1220  }
1221 
1222  return FALSE;
1223 }
1224 
1225 /* PUBLIC FUNCTIONS ***********************************************************/
1226 
1254 BOOL
1255 WINAPI
1257  UINT Base,
1258  ULONG Unknown,
1259  LPSTR BaseName,
1260  LPSTR Result,
1261  ULONG ResultSize)
1262 {
1263  CHAR Integer[11];
1264 
1265  if (!NT_SUCCESS(RtlIntegerToChar(CodePage, Base, sizeof(Integer), Integer)))
1266  return FALSE;
1267 
1268  /*
1269  * If the name including the terminating NULL character doesn't
1270  * fit in the output buffer then fail.
1271  */
1272  if (strlen(Integer) + strlen(BaseName) >= ResultSize)
1273  return FALSE;
1274 
1275  lstrcpyA(Result, BaseName);
1276  lstrcatA(Result, Integer);
1277 
1278  return TRUE;
1279 }
1280 
1299 BOOL
1300 WINAPI
1302 {
1303  WCHAR ValueNameBuffer[11];
1306  NTSTATUS Status;
1307  HANDLE KeyHandle;
1309  DWORD KvpiSize;
1310  BOOL bRetValue;
1311 
1312  bRetValue = FALSE;
1313 
1314  /* Convert the codepage number to string. */
1315  ValueName.Buffer = ValueNameBuffer;
1316  ValueName.MaximumLength = sizeof(ValueNameBuffer);
1317 
1318  if (!NT_SUCCESS(RtlIntegerToUnicodeString(CodePage, 10, &ValueName)))
1319  return bRetValue;
1320 
1321  /* Open the registry key containing file name mappings. */
1322  RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System\\"
1323  L"CurrentControlSet\\Control\\Nls\\CodePage");
1325  NULL, NULL);
1327  if (!NT_SUCCESS(Status))
1328  {
1329  return bRetValue;
1330  }
1331 
1332  /* Allocate buffer that will be used to query the value data. */
1333  KvpiSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + (MAX_PATH * sizeof(WCHAR));
1334  Kvpi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, KvpiSize);
1335  if (Kvpi == NULL)
1336  {
1337  NtClose(KeyHandle);
1338  return bRetValue;
1339  }
1340 
1341  /* Query the file name for our code page. */
1343  Kvpi, KvpiSize, &KvpiSize);
1344 
1345  NtClose(KeyHandle);
1346 
1347  /* Check if we succeded and the value is non-empty string. */
1348  if (NT_SUCCESS(Status) && Kvpi->Type == REG_SZ &&
1349  Kvpi->DataLength > sizeof(WCHAR))
1350  {
1351  bRetValue = TRUE;
1352  if (FileName != NULL)
1353  {
1354  lstrcpynW(FileName, (WCHAR*)Kvpi->Data,
1355  min(Kvpi->DataLength / sizeof(WCHAR), FileNameSize));
1356  }
1357  }
1358 
1359  /* free temporary buffer */
1360  HeapFree(GetProcessHeap(),0,Kvpi);
1361  return bRetValue;
1362 }
1363 
1375 BOOL
1376 WINAPI
1378 {
1379  if (CodePage == 0) return FALSE;
1380  if (CodePage == CP_UTF8 || CodePage == CP_UTF7)
1381  return TRUE;
1382  if (IntGetLoadedCodePageEntry(CodePage))
1383  return TRUE;
1384  return GetCPFileNameFromRegistry(CodePage, NULL, 0);
1385 }
1386 
1387 static inline BOOL utf7_write_w(WCHAR *dst, int dstlen, int *index, WCHAR character)
1388 {
1389  if (dstlen > 0)
1390  {
1391  if (*index >= dstlen)
1392  return FALSE;
1393 
1394  dst[*index] = character;
1395  }
1396 
1397  (*index)++;
1398 
1399  return TRUE;
1400 }
1401 
1402 static INT Utf7ToWideChar(const char *src, int srclen, WCHAR *dst, int dstlen)
1403 {
1404  static const signed char base64_decoding_table[] =
1405  {
1406  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00-0x0F */
1407  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10-0x1F */
1408  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20-0x2F */
1409  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30-0x3F */
1410  -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40-0x4F */
1411  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50-0x5F */
1412  -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60-0x6F */
1413  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 /* 0x70-0x7F */
1414  };
1415 
1416  const char *source_end = src + srclen;
1417  int dest_index = 0;
1418 
1419  DWORD byte_pair = 0;
1420  short offset = 0;
1421 
1422  while (src < source_end)
1423  {
1424  if (*src == '+')
1425  {
1426  src++;
1427  if (src >= source_end)
1428  break;
1429 
1430  if (*src == '-')
1431  {
1432  /* just a plus sign escaped as +- */
1433  if (!utf7_write_w(dst, dstlen, &dest_index, '+'))
1434  {
1436  return 0;
1437  }
1438  src++;
1439  continue;
1440  }
1441 
1442  do
1443  {
1444  signed char sextet = *src;
1445  if (sextet == '-')
1446  {
1447  /* skip over the dash and end base64 decoding
1448  * the current, unfinished byte pair is discarded */
1449  src++;
1450  offset = 0;
1451  break;
1452  }
1453  if (sextet < 0)
1454  {
1455  /* the next character of src is < 0 and therefore not part of a base64 sequence
1456  * the current, unfinished byte pair is NOT discarded in this case
1457  * this is probably a bug in Windows */
1458  break;
1459  }
1460 
1461  sextet = base64_decoding_table[sextet];
1462  if (sextet == -1)
1463  {
1464  /* -1 means that the next character of src is not part of a base64 sequence
1465  * in other words, all sextets in this base64 sequence have been processed
1466  * the current, unfinished byte pair is discarded */
1467  offset = 0;
1468  break;
1469  }
1470 
1471  byte_pair = (byte_pair << 6) | sextet;
1472  offset += 6;
1473 
1474  if (offset >= 16)
1475  {
1476  /* this byte pair is done */
1477  if (!utf7_write_w(dst, dstlen, &dest_index, (byte_pair >> (offset - 16)) & 0xFFFF))
1478  {
1480  return 0;
1481  }
1482  offset -= 16;
1483  }
1484 
1485  src++;
1486  }
1487  while (src < source_end);
1488  }
1489  else
1490  {
1491  /* we have to convert to unsigned char in case *src < 0 */
1492  if (!utf7_write_w(dst, dstlen, &dest_index, (unsigned char)*src))
1493  {
1495  return 0;
1496  }
1497  src++;
1498  }
1499  }
1500 
1501  return dest_index;
1502 }
1503 
1535 INT
1536 WINAPI
1538  DWORD Flags,
1540  INT MultiByteCount,
1541  LPWSTR WideCharString,
1542  INT WideCharCount)
1543 {
1544  /* Check the parameters. */
1545  if (MultiByteString == NULL ||
1546  MultiByteCount == 0 || WideCharCount < 0 ||
1547  (WideCharCount && (WideCharString == NULL ||
1548  (PVOID)MultiByteString == (PVOID)WideCharString)))
1549  {
1551  return 0;
1552  }
1553 
1554  /* Determine the input string length. */
1555  if (MultiByteCount < 0)
1556  {
1557  MultiByteCount = lstrlenA(MultiByteString) + 1;
1558  }
1559 
1560  switch (CodePage)
1561  {
1562  case CP_UTF8:
1565  MultiByteCount,
1566  WideCharString,
1567  WideCharCount);
1568 
1569  case CP_UTF7:
1570  if (Flags)
1571  {
1573  return 0;
1574  }
1575  return Utf7ToWideChar(MultiByteString, MultiByteCount,
1576  WideCharString, WideCharCount);
1577 
1578  case CP_SYMBOL:
1581  MultiByteCount,
1582  WideCharString,
1583  WideCharCount);
1584  default:
1585  return IntMultiByteToWideCharCP(CodePage,
1586  Flags,
1588  MultiByteCount,
1589  WideCharString,
1590  WideCharCount);
1591  }
1592 }
1593 
1594 static inline BOOL utf7_can_directly_encode(WCHAR codepoint)
1595 {
1596  static const BOOL directly_encodable_table[] =
1597  {
1598  1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, /* 0x00 - 0x0F */
1599  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1F */
1600  1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* 0x20 - 0x2F */
1601  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x30 - 0x3F */
1602  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4F */
1603  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x50 - 0x5F */
1604  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6F */
1605  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* 0x70 - 0x7A */
1606  };
1607 
1608  return codepoint <= 0x7A ? directly_encodable_table[codepoint] : FALSE;
1609 }
1610 
1611 static inline BOOL utf7_write_c(char *dst, int dstlen, int *index, char character)
1612 {
1613  if (dstlen > 0)
1614  {
1615  if (*index >= dstlen)
1616  return FALSE;
1617 
1618  dst[*index] = character;
1619  }
1620 
1621  (*index)++;
1622 
1623  return TRUE;
1624 }
1625 
1626 static INT WideCharToUtf7(const WCHAR *src, int srclen, char *dst, int dstlen)
1627 {
1628  static const char base64_encoding_table[] =
1629  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1630 
1631  const WCHAR *source_end = src + srclen;
1632  int dest_index = 0;
1633 
1634  while (src < source_end)
1635  {
1636  if (*src == '+')
1637  {
1638  if (!utf7_write_c(dst, dstlen, &dest_index, '+'))
1639  {
1641  return 0;
1642  }
1643  if (!utf7_write_c(dst, dstlen, &dest_index, '-'))
1644  {
1646  return 0;
1647  }
1648  src++;
1649  }
1650  else if (utf7_can_directly_encode(*src))
1651  {
1652  if (!utf7_write_c(dst, dstlen, &dest_index, *src))
1653  {
1655  return 0;
1656  }
1657  src++;
1658  }
1659  else
1660  {
1661  unsigned int offset = 0;
1662  DWORD byte_pair = 0;
1663 
1664  if (!utf7_write_c(dst, dstlen, &dest_index, '+'))
1665  {
1667  return 0;
1668  }
1669 
1670  while (src < source_end && !utf7_can_directly_encode(*src))
1671  {
1672  byte_pair = (byte_pair << 16) | *src;
1673  offset += 16;
1674  while (offset >= 6)
1675  {
1676  if (!utf7_write_c(dst, dstlen, &dest_index, base64_encoding_table[(byte_pair >> (offset - 6)) & 0x3F]))
1677  {
1679  return 0;
1680  }
1681  offset -= 6;
1682  }
1683  src++;
1684  }
1685 
1686  if (offset)
1687  {
1688  /* Windows won't create a padded base64 character if there's no room for the - sign
1689  * as well ; this is probably a bug in Windows */
1690  if (dstlen > 0 && dest_index + 1 >= dstlen)
1691  {
1693  return 0;
1694  }
1695 
1696  byte_pair <<= (6 - offset);
1697  if (!utf7_write_c(dst, dstlen, &dest_index, base64_encoding_table[byte_pair & 0x3F]))
1698  {
1700  return 0;
1701  }
1702  }
1703 
1704  /* Windows always explicitly terminates the base64 sequence
1705  even though RFC 2152 (page 3, rule 2) does not require this */
1706  if (!utf7_write_c(dst, dstlen, &dest_index, '-'))
1707  {
1709  return 0;
1710  }
1711  }
1712  }
1713 
1714  return dest_index;
1715 }
1716 
1717 /*
1718  * A function similar to LoadStringW, but adapted for usage by GetCPInfoExW
1719  * and GetGeoInfoW. It uses the current user localization, otherwise falls back
1720  * to English (US). Contrary to LoadStringW which always saves the loaded string
1721  * into the user-given buffer, truncating the string if needed, this function
1722  * returns instead an ERROR_INSUFFICIENT_BUFFER error code if the user buffer
1723  * is not large enough.
1724  */
1725 UINT
1727  IN UINT uID,
1728  IN LPWSTR lpszDest,
1729  IN UINT cchDest)
1730 {
1731  HRSRC hrsrc;
1732  HGLOBAL hmem;
1733  LCID lcid;
1734  LANGID langId;
1735  const WCHAR *p;
1736  UINT i;
1737 
1738  /* See HACK in winnls/lang/xx-XX.rc files */
1739  if (uID == 37)
1740  uID = uID * 100;
1741 
1744 
1745  langId = LANGIDFROMLCID(lcid);
1746 
1747  if (PRIMARYLANGID(langId) == LANG_NEUTRAL)
1749 
1751  (LPWSTR)RT_STRING,
1752  MAKEINTRESOURCEW((uID >> 4) + 1),
1753  langId);
1754 
1755  /* English fallback */
1756  if (!hrsrc)
1757  {
1759  (LPWSTR)RT_STRING,
1760  MAKEINTRESOURCEW((uID >> 4) + 1),
1762  }
1763 
1764  if (!hrsrc)
1765  goto NotFound;
1766 
1767  hmem = LoadResource(hCurrentModule, hrsrc);
1768  if (!hmem)
1769  goto NotFound;
1770 
1771  p = LockResource(hmem);
1772 
1773  for (i = 0; i < (uID & 0x0F); i++)
1774  p += *p + 1;
1775 
1776  /* Needed for GetGeoInfo(): return the needed string size including the NULL terminator */
1777  if (cchDest == 0)
1778  return *p + 1;
1779  /* Needed for GetGeoInfo(): bail out if the user buffer is not large enough */
1780  if (*p + 1 > cchDest)
1781  {
1783  return 0;
1784  }
1785 
1786  i = *p;
1787  if (i > 0)
1788  {
1789  memcpy(lpszDest, p + 1, i * sizeof(WCHAR));
1790  lpszDest[i] = L'\0';
1791  return i;
1792  }
1793 #if 0
1794  else
1795  {
1796  if (cchDest >= 1)
1797  lpszDest[0] = L'\0';
1798  /* Fall-back */
1799  }
1800 #endif
1801 
1802 NotFound:
1803  DPRINT1("Resource not found: uID = %lu\n", uID);
1805  return 0;
1806 }
1807 
1808 /*
1809  * @implemented
1810  */
1811 BOOL
1812 WINAPI
1813 GetCPInfo(UINT CodePage,
1814  LPCPINFO CodePageInfo)
1815 {
1816  PCODEPAGE_ENTRY CodePageEntry;
1817 
1818  if (!CodePageInfo)
1819  {
1821  return FALSE;
1822  }
1823 
1824  CodePageEntry = IntGetCodePageEntry(CodePage);
1825  if (CodePageEntry == NULL)
1826  {
1827  switch(CodePage)
1828  {
1829  case CP_UTF7:
1830  case CP_UTF8:
1831  CodePageInfo->DefaultChar[0] = 0x3f;
1832  CodePageInfo->DefaultChar[1] = 0;
1833  CodePageInfo->LeadByte[0] = CodePageInfo->LeadByte[1] = 0;
1834  CodePageInfo->MaxCharSize = (CodePage == CP_UTF7) ? 5 : 4;
1835  return TRUE;
1836  }
1837 
1838  DPRINT1("Invalid CP!: %lx\n", CodePage);
1840  return FALSE;
1841  }
1842 
1843  if (CodePageEntry->CodePageTable.DefaultChar & 0xff00)
1844  {
1845  CodePageInfo->DefaultChar[0] = (CodePageEntry->CodePageTable.DefaultChar & 0xff00) >> 8;
1846  CodePageInfo->DefaultChar[1] = CodePageEntry->CodePageTable.DefaultChar & 0x00ff;
1847  }
1848  else
1849  {
1850  CodePageInfo->DefaultChar[0] = CodePageEntry->CodePageTable.DefaultChar & 0xff;
1851  CodePageInfo->DefaultChar[1] = 0;
1852  }
1853 
1854  if ((CodePageInfo->MaxCharSize = CodePageEntry->CodePageTable.MaximumCharacterSize) == 2)
1855  memcpy(CodePageInfo->LeadByte, CodePageEntry->CodePageTable.LeadByte, sizeof(CodePageInfo->LeadByte));
1856  else
1857  CodePageInfo->LeadByte[0] = CodePageInfo->LeadByte[1] = 0;
1858 
1859  return TRUE;
1860 }
1861 
1862 /*
1863  * @implemented
1864  */
1865 BOOL
1866 WINAPI
1868  DWORD dwFlags,
1869  LPCPINFOEXW lpCPInfoEx)
1870 {
1871  if (!GetCPInfo(CodePage, (LPCPINFO)lpCPInfoEx))
1872  return FALSE;
1873 
1874  switch(CodePage)
1875  {
1876  case CP_UTF7:
1877  {
1878  lpCPInfoEx->CodePage = CP_UTF7;
1879  lpCPInfoEx->UnicodeDefaultChar = 0x3f;
1880  return GetLocalisedText(lpCPInfoEx->CodePage,
1881  lpCPInfoEx->CodePageName,
1882  ARRAYSIZE(lpCPInfoEx->CodePageName)) != 0;
1883  }
1884  break;
1885 
1886  case CP_UTF8:
1887  {
1888  lpCPInfoEx->CodePage = CP_UTF8;
1889  lpCPInfoEx->UnicodeDefaultChar = 0x3f;
1890  return GetLocalisedText(lpCPInfoEx->CodePage,
1891  lpCPInfoEx->CodePageName,
1892  ARRAYSIZE(lpCPInfoEx->CodePageName)) != 0;
1893  }
1894 
1895  default:
1896  {
1897  PCODEPAGE_ENTRY CodePageEntry;
1898 
1899  CodePageEntry = IntGetCodePageEntry(CodePage);
1900  if (CodePageEntry == NULL)
1901  {
1902  DPRINT1("Could not get CodePage Entry! CodePageEntry = NULL\n");
1904  return FALSE;
1905  }
1906 
1907  lpCPInfoEx->CodePage = CodePageEntry->CodePageTable.CodePage;
1908  lpCPInfoEx->UnicodeDefaultChar = CodePageEntry->CodePageTable.UniDefaultChar;
1909  return GetLocalisedText(lpCPInfoEx->CodePage,
1910  lpCPInfoEx->CodePageName,
1911  ARRAYSIZE(lpCPInfoEx->CodePageName)) != 0;
1912  }
1913  break;
1914  }
1915 }
1916 
1917 
1918 /*
1919  * @implemented
1920  */
1921 BOOL
1922 WINAPI
1924  DWORD dwFlags,
1925  LPCPINFOEXA lpCPInfoEx)
1926 {
1927  CPINFOEXW CPInfo;
1928 
1929  if (!GetCPInfoExW(CodePage, dwFlags, &CPInfo))
1930  return FALSE;
1931 
1932  /* the layout is the same except for CodePageName */
1933  memcpy(lpCPInfoEx, &CPInfo, sizeof(CPINFOEXA));
1934 
1936  0,
1937  CPInfo.CodePageName,
1938  -1,
1939  lpCPInfoEx->CodePageName,
1940  sizeof(lpCPInfoEx->CodePageName),
1941  NULL,
1942  NULL);
1943  return TRUE;
1944 }
1945 
1985 INT
1986 WINAPI
1988  DWORD Flags,
1989  LPCWSTR WideCharString,
1990  INT WideCharCount,
1992  INT MultiByteCount,
1993  LPCSTR DefaultChar,
1994  LPBOOL UsedDefaultChar)
1995 {
1996  /* Check the parameters. */
1997  if (WideCharString == NULL ||
1998  WideCharCount == 0 ||
1999  (MultiByteString == NULL && MultiByteCount > 0) ||
2000  (PVOID)WideCharString == (PVOID)MultiByteString ||
2001  MultiByteCount < 0)
2002  {
2004  return 0;
2005  }
2006 
2007  /* Determine the input string length. */
2008  if (WideCharCount < 0)
2009  {
2010  WideCharCount = lstrlenW(WideCharString) + 1;
2011  }
2012 
2013  switch (CodePage)
2014  {
2015  case CP_UTF8:
2016  if (DefaultChar != NULL || UsedDefaultChar != NULL)
2017  {
2019  return 0;
2020  }
2021  return IntWideCharToMultiByteUTF8(CodePage,
2022  Flags,
2023  WideCharString,
2024  WideCharCount,
2026  MultiByteCount,
2027  DefaultChar,
2028  UsedDefaultChar);
2029 
2030  case CP_UTF7:
2031  if (DefaultChar != NULL || UsedDefaultChar != NULL)
2032  {
2034  return 0;
2035  }
2036  if (Flags)
2037  {
2039  return 0;
2040  }
2041  return WideCharToUtf7(WideCharString, WideCharCount,
2042  MultiByteString, MultiByteCount);
2043 
2044  case CP_SYMBOL:
2045  if ((DefaultChar!=NULL) || (UsedDefaultChar!=NULL))
2046  {
2048  return 0;
2049  }
2051  WideCharString,
2052  WideCharCount,
2054  MultiByteCount);
2055 
2056  default:
2057  return IntWideCharToMultiByteCP(CodePage,
2058  Flags,
2059  WideCharString,
2060  WideCharCount,
2062  MultiByteCount,
2063  DefaultChar,
2064  UsedDefaultChar);
2065  }
2066 }
2067 
2076 UINT
2077 WINAPI
2079 {
2081 }
2082 
2091 UINT
2092 WINAPI
2094 {
2096 }
2097 
2106 BOOL
2107 WINAPI
2108 IsDBCSLeadByteEx(UINT CodePage, BYTE TestByte)
2109 {
2110  PCODEPAGE_ENTRY CodePageEntry;
2111 
2112  CodePageEntry = IntGetCodePageEntry(CodePage);
2113  if (CodePageEntry != NULL)
2114  return IntIsLeadByte(&CodePageEntry->CodePageTable, TestByte);
2115 
2117  return FALSE;
2118 }
2119 
2128 BOOL
2129 WINAPI
2131 {
2132  return IntIsLeadByte(&AnsiCodePage.CodePageTable, TestByte);
2133 }
2134 
2135 /*
2136  * @unimplemented
2137  */
2139 {
2140  STUB;
2141  return 0;
2142 }
2143 
2144 /*
2145  * @unimplemented
2146  */
2148 {
2149  STUB;
2150  return 0;
2151 }
2152 
2153 /*
2154  * @unimplemented
2155  */
2157 {
2158  STUB;
2159 }
2160 
2161 /*
2162  * @unimplemented
2163  */
2165 {
2166  STUB;
2167  return 0;
2168 }
2169 
2170 /*
2171  * @unimplemented
2172  */
2173 BOOL
2174 WINAPI
2175 ValidateLCType(int a1, unsigned int a2, int a3, int a4)
2176 {
2177  STUB;
2178  return FALSE;
2179 }
2180 
2181 /*
2182  * @unimplemented
2183  */
2184 BOOL
2185 WINAPI
2187 {
2188  STUB;
2189  return TRUE;
2190 }
2191 
2192 /*
2193  * @unimplemented
2194  */
2195 VOID
2196 WINAPI
2198 {
2199  STUB;
2200  lpUnknown = NULL;
2201 }
2202 
2203 /*
2204  * @unimplemented
2205  */
2206 VOID
2207 WINAPI
2209 {
2210  STUB;
2211  lpUnknown = NULL;
2212 }
2213 
2214 /*
2215  * @unimplemented
2216  */
2217 BOOL
2218 WINAPI
2220 {
2221  STUB;
2222  return TRUE;
2223 }
2224 
2225 /*
2226  * @unimplemented
2227  */
2228 ULONG
2229 WINAPI
2231 {
2232  STUB;
2233  return 0;
2234 }
2235 
2236 /*
2237  * @unimplemented
2238  */
2239 BOOL
2240 WINAPI
2242  IN DWORD dwFlags,
2243  IN LPNLSVERSIONINFO lpVersionInformation,
2244  IN LPCWSTR lpString,
2245  IN INT cchStr)
2246 {
2247  STUB;
2248  return TRUE;
2249 }
2250 
2251 /*
2252  * @unimplemented
2253  */
2254 BOOL
2255 WINAPI
2257  IN LCID Locale,
2258  IN OUT LPNLSVERSIONINFO lpVersionInformation)
2259 {
2260  STUB;
2261  return TRUE;
2262 }
2263 
2264 /*
2265  * @unimplemented
2266  */
2267 BOOL
2268 WINAPI
2270  IN LPCWSTR lpLocaleName,
2271  IN OUT LPNLSVERSIONINFOEX lpVersionInformation)
2272 {
2273  STUB;
2274  return TRUE;
2275 }
2276 
2277 /* EOF */
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2327
signed char * PCHAR
Definition: retypes.h:7
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define FILE_GENERIC_READ
Definition: nt_native.h:653
static INT WINAPI IntMultiByteToWideCharUTF8(DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:361
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4693
BOOL WINAPI IsValidUILanguage(LANGID langid)
Definition: nls.c:2147
#define IN
Definition: typedefs.h:38
BOOL WINAPI GetCPInfo(UINT CodePage, LPCPINFO CodePageInfo)
Definition: nls.c:1813
#define LOCALE_IDEFAULTANSICODEPAGE
Definition: winnls.h:38
static CODEPAGE_ENTRY AnsiCodePage
Definition: nls.c:41
static INT Utf7ToWideChar(const char *src, int srclen, WCHAR *dst, int dstlen)
Definition: nls.c:1402
#define TRUE
Definition: types.h:120
static const struct update_accum a3
Definition: msg.c:600
#define MB_ERR_INVALID_CHARS
Definition: unicode.h:41
USHORT UniDefaultChar
Definition: precomp.h:35
static INT WideCharToUtf7(const WCHAR *src, int srclen, char *dst, int dstlen)
Definition: nls.c:1626
PUSHORT DBCSOffsets
Definition: precomp.h:43
#define MapViewOfFile
Definition: compat.h:402
NTSTATUS NTAPI NtCreateSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize OPTIONAL, IN ULONG SectionPageProtection OPTIONAL, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL)
Definition: section.c:3371
#define MB_USEGLYPHCHARS
Definition: unicode.h:42
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4693
USHORT MaximumLength
Definition: env_spec_w32.h:370
PUSHORT MultiByteTable
Definition: precomp.h:40
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define CP_UTF7
Definition: winnls.h:232
#define MAKEWORD(a, b)
Definition: typedefs.h:247
unsigned char Byte
Definition: zconf.h:391
#define KEY_READ
Definition: nt_native.h:1023
static INT WINAPI IntWideCharToMultiByteSYMBOL(DWORD Flags, LPCWSTR WideCharString, INT WideCharCount, LPSTR MultiByteString, INT MultiByteCount)
Definition: nls.c:684
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
static LIST_ENTRY CodePageListHead
Definition: nls.c:40
static const char UTF8Length[128]
Definition: nls.c:24
NLS_FUNCTION
Definition: winnls.h:547
WCHAR CodePageName[MAX_PATH]
Definition: winnls.h:596
#define LANG_NEUTRAL
Definition: nls.h:22
BOOL WINAPI ValidateLocale(IN ULONG LocaleId)
Definition: nls.c:2219
#define CP_ACP
Definition: compat.h:99
BOOL WINAPI ValidateLCType(int a1, unsigned int a2, int a3, int a4)
Definition: nls.c:2175
char CHAR
Definition: xmlstorage.h:175
VOID WINAPI GetLinguistLangSize(LPVOID lpUnknown)
Definition: nls.c:2208
BOOL WINAPI IsNLSDefinedString(IN NLS_FUNCTION Function, IN DWORD dwFlags, IN LPNLSVERSIONINFO lpVersionInformation, IN LPCWSTR lpString, IN INT cchStr)
Definition: nls.c:2241
LONG NTSTATUS
Definition: precomp.h:26
IN PDCB IN POEM_STRING IN PUNICODE_STRING UnicodeName
Definition: fatprocs.h:1294
GLintptr offset
Definition: glext.h:5920
#define LOCALE_IDEFAULTMACCODEPAGE
Definition: winnls.h:39
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2327
BOOL WINAPI GetNLSVersionEx(IN NLS_FUNCTION function, IN LPCWSTR lpLocaleName, IN OUT LPNLSVERSIONINFOEX lpVersionInformation)
Definition: nls.c:2269
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
#define OBJ_PERMANENT
Definition: winternl.h:226
static const struct update_accum a4
Definition: msg.c:2285
UINT MaxCharSize
Definition: winnls.h:578
INT WINAPI WideCharToMultiByte(UINT CodePage, DWORD Flags, LPCWSTR WideCharString, INT WideCharCount, LPSTR MultiByteString, INT MultiByteCount, LPCSTR DefaultChar, LPBOOL UsedDefaultChar)
Definition: nls.c:1987
DWORD LCID
Definition: nls.h:13
WORD LANGID
Definition: typedefs.h:79
LCID WINAPI GetUserDefaultLCID(void)
Definition: lang.c:765
uint16_t * PWCHAR
Definition: typedefs.h:54
#define InsertTailList(ListHead, Entry)
NTSYSAPI NTSTATUS NTAPI RtlIntegerToChar(_In_ ULONG Value, _In_ ULONG Base, _In_ ULONG Length, _Out_ PCHAR String)
char * LPSTR
Definition: xmlstorage.h:182
PCODEPAGE_ENTRY FASTCALL IntGetLoadedCodePageEntry(UINT CodePage)
Definition: nls.c:155
LANGID langid
Definition: msctf.idl:605
#define lstrlenW
Definition: compat.h:407
#define FASTCALL
Definition: nt_native.h:50
#define CP_SYMBOL
Definition: winnls.h:231
int32_t INT
Definition: typedefs.h:56
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
static INT WINAPI IntWideCharToMultiByteUTF8(UINT CodePage, DWORD Flags, LPCWSTR WideCharString, INT WideCharCount, LPSTR MultiByteString, INT MultiByteCount, LPCSTR DefaultChar, LPBOOL UsedDefaultChar)
Definition: nls.c:746
#define FILE_SHARE_READ
Definition: compat.h:125
#define SUBLANG_ENGLISH_US
Definition: nls.h:222
#define lstrcpynW
Definition: compat.h:397
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: lang.c:1095
static INT WINAPI IntMultiByteToWideCharSYMBOL(DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:629
BOOL WINAPI NlsResetProcessLocale(VOID)
Definition: nls.c:2186
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
HANDLE FileHandle
Definition: stats.c:38
BOOL WINAPI IsDBCSLeadByteEx(UINT CodePage, BYTE TestByte)
Definition: nls.c:2108
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
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
static BOOL utf7_write_c(char *dst, int dstlen, int *index, char character)
Definition: nls.c:1611
VOID WINAPI GetDefaultSortkeySize(LPVOID lpUnknown)
Definition: nls.c:2197
#define SEC_COMMIT
Definition: mmtypes.h:99
#define CP_UTF8
Definition: nls.h:20
#define UNICODE_NULL
static LPOVERLAPPED_COMPLETION_ROUTINE Function
Definition: sync.c:684
LCID WINAPI ConvertDefaultLocale(LCID lcid)
Definition: lang.c:1499
long LONG
Definition: pedump.c:60
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
PVOID WideCharTable
Definition: precomp.h:41
UINT CodePage
Definition: kernel32.h:65
char Char
Definition: bzip2.c:161
NTSTATUS NTAPI NtOpenSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: section.c:3499
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
const WCHAR * str
static BOOL IntIsValidSBCSMapping(PCPTABLEINFO CodePageTable, DWORD Flags, WCHAR wch, UCHAR ch)
Definition: nls.c:875
smooth NULL
Definition: ftsmooth.c:416
unsigned char
Definition: typeof.h:27
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
BOOL WINAPI IsDBCSLeadByte(BYTE TestByte)
Definition: nls.c:2130
UINT WINAPI GetACP(VOID)
Definition: nls.c:2078
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
WCHAR lpszDest[260]
void DPRINT(...)
Definition: polytest.cpp:61
#define FILE_MAP_READ
Definition: compat.h:427
USHORT TransDefaultChar
Definition: precomp.h:36
GLuint index
Definition: glext.h:6031
const char * LPCSTR
Definition: xmlstorage.h:183
#define OPEN_EXISTING
Definition: compat.h:426
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
HMODULE hCurrentModule
Definition: dllmain.c:25
#define PCHAR
Definition: match.c:90
ULONG WINAPI NlsGetCacheUpdateCount(VOID)
Definition: nls.c:2230
UCHAR LeadByte[MAXIMUM_LEADBYTES]
Definition: precomp.h:39
USHORT DBCSCodePage
Definition: precomp.h:38
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
_In_ HANDLE Handle
Definition: extypes.h:390
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
VOID WINAPI NlsConvertIntegerToString(ULONG Value, ULONG Base, ULONG strsize, LPWSTR str, ULONG strsize2)
Definition: nls.c:2156
NTSYSAPI NTSTATUS NTAPI RtlIntegerToUnicodeString(ULONG Value, ULONG Base, PUNICODE_STRING String)
NTSYSAPI NTSTATUS NTAPI NtQueryValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, IN PULONG ResultLength)
unsigned int BOOL
Definition: ntddk_ex.h:94
static INT WINAPI IntMultiByteToWideCharCP(UINT CodePage, DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:430
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
NTSTATUS WINAPI CreateNlsSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, ULONG Size, ULONG AccessMask)
Definition: nls.c:2138
LIST_ENTRY Entry
Definition: kernel32.h:64
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
USHORT TransUniDefaultChar
Definition: precomp.h:37
static const struct update_accum a2
Definition: msg.c:586
BYTE LeadByte[MAX_LEADBYTES]
Definition: winnls.h:580
USHORT MaximumCharacterSize
Definition: precomp.h:33
static DWORD LPDWORD LPCSTR DWORD srclen
Definition: directory.c:51
BOOL WINAPI GetNLSVersion(IN NLS_FUNCTION Function, IN LCID Locale, IN OUT LPNLSVERSIONINFO lpVersionInformation)
Definition: nls.c:2256
#define MAX_PATH
Definition: compat.h:26
PCODEPAGE_ENTRY FASTCALL IntGetCodePageEntry(UINT CodePage)
Definition: nls.c:191
unsigned int UINT
Definition: ndis.h:50
#define LOCALE_SYSTEM_DEFAULT
_In_ ACCESS_MASK AccessMask
Definition: exfuncs.h:186
#define for
Definition: utility.h:88
unsigned long DWORD
Definition: ntddk_ex.h:95
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
static BOOL WINAPI IntIsLeadByte(PCPTABLEINFO TableInfo, BYTE Byte)
Definition: nls.c:1209
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define SetLastError(x)
Definition: compat.h:409
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define WC_NO_BEST_FIT_CHARS
Definition: unicode.h:46
#define LANG_ENGLISH
Definition: nls.h:52
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
USHORT CodePage
Definition: precomp.h:32
#define ERROR_NO_UNICODE_TRANSLATION
Definition: winerror.h:649
static CODEPAGE_ENTRY OemCodePage
Definition: nls.c:42
static BOOL IntIsValidDBCSMapping(PCPTABLEINFO CodePageTable, DWORD Flags, WCHAR wch, USHORT ch)
Definition: nls.c:898
unsigned char UCHAR
Definition: xmlstorage.h:181
static INT WINAPI IntWideCharToMultiByteCP(UINT CodePage, DWORD Flags, LPCWSTR WideCharString, INT WideCharCount, LPSTR MultiByteString, INT MultiByteCount, LPCSTR DefaultChar, LPBOOL UsedDefaultChar)
Definition: nls.c:932
HRSRC WINAPI FindResourceExW(HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD lang)
Definition: res.c:164
CHAR CodePageName[MAX_PATH]
Definition: winnls.h:588
static RTL_CRITICAL_SECTION CodePageListLock
Definition: nls.c:43
#define index(s, c)
Definition: various.h:29
static const WCHAR L[]
Definition: oid.c:1250
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define SECTION_MAP_READ
Definition: compat.h:128
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define LANGIDFROMLCID(l)
Definition: nls.h:18
unsigned char BYTE
Definition: mem.h:68
#define MAXIMUM_LEADBYTES
Definition: precomp.h:16
VOID NTAPI RtlInitCodePageTable(IN PUSHORT TableBase, OUT PCPTABLEINFO CodePageTable)
Definition: nls.c:155
#define RT_STRING
Definition: pedump.c:368
USHORT DefaultChar
Definition: precomp.h:34
Definition: typedefs.h:117
GLenum src
Definition: glext.h:6340
BOOL WINAPI GetCPFileNameFromRegistry(UINT CodePage, LPWSTR FileName, ULONG FileNameSize)
Definition: nls.c:1301
INT WINAPI MultiByteToWideChar(UINT CodePage, DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:1537
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
BOOL WINAPI GetNlsSectionName(UINT CodePage, UINT Base, ULONG Unknown, LPSTR BaseName, LPSTR Result, ULONG ResultSize)
Definition: nls.c:1256
#define WINAPI
Definition: msvc.h:20
UINT GetLocalisedText(IN UINT uID, IN LPWSTR lpszDest, IN UINT cchDest)
Definition: nls.c:1726
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:731
BOOL WINAPI IsValidCodePage(UINT CodePage)
Definition: nls.c:1377
BOOL * LPBOOL
Definition: windef.h:162
static DWORD dstlen
Definition: directory.c:51
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
Definition: kernel32.h:62
#define WC_COMPOSITECHECK
Definition: unicode.h:43
#define STUB
Definition: kernel32.h:27
unsigned short USHORT
Definition: pedump.c:61
BOOL WINAPI GetCPInfoExA(UINT CodePage, DWORD dwFlags, LPCPINFOEXA lpCPInfoEx)
Definition: nls.c:1923
BYTE DefaultChar[MAX_DEFAULTCHAR]
Definition: winnls.h:579
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1259
GLenum GLenum dst
Definition: glext.h:6340
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2312
#define min(a, b)
Definition: monoChain.cc:55
#define PAGE_READONLY
Definition: compat.h:127
static const unsigned char UTF8Mask[6]
Definition: nls.c:37
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
PBYTE SectionMapping
Definition: kernel32.h:67
*BytesInMultiByteString PCHAR MultiByteString
Definition: rtlfuncs.h:1528
#define DPRINT1
Definition: precomp.h:8
#define CreateFileW
Definition: compat.h:400
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
#define MAKELANGID(p, s)
Definition: nls.h:15
BOOL WINAPI GetCPInfoExW(UINT CodePage, DWORD dwFlags, LPCPINFOEXW lpCPInfoEx)
Definition: nls.c:1867
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
_In_ PFCB _In_ PCD_NAME DirName
Definition: cdprocs.h:741
_Out_ PCPTABLEINFO CodePageTable
Definition: rtlfuncs.h:4097
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
static BOOL utf7_write_w(WCHAR *dst, int dstlen, int *index, WCHAR character)
Definition: nls.c:1387
static BOOL utf7_can_directly_encode(WCHAR codepoint)
Definition: nls.c:1594
static const struct update_accum a1
Definition: msg.c:578
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
HANDLE SectionHandle
Definition: kernel32.h:66
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
NTSYSAPI NTSTATUS NTAPI RtlDeleteCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define CP_THREAD_ACP
Definition: winnls.h:230
VOID FASTCALL NlsUninit(VOID)
Definition: nls.c:121
#define UnmapViewOfFile
Definition: compat.h:403
#define CHAR(Char)
BOOL FASTCALL NlsInit(VOID)
Definition: nls.c:64
BYTE * PBYTE
Definition: pedump.c:66
UINT WINAPI SetCPGlobal(UINT CodePage)
Definition: nls.c:2164
#define CP_OEMCP
Definition: winnls.h:228
#define HeapFree(x, y, z)
Definition: compat.h:394
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583
unsigned short * PUSHORT
Definition: retypes.h:2
base of all file and directory entries
Definition: entries.h:82
CPTABLEINFO CodePageTable
Definition: kernel32.h:68
LCID WINAPI GetThreadLocale(void)
Definition: lang.c:1446
#define CP_MACCP
Definition: winnls.h:229
#define PRIMARYLANGID(l)
Definition: nls.h:16
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
UINT WINAPI GetOEMCP(VOID)
Definition: nls.c:2093
#define REG_SZ
Definition: layer.c:22