ReactOS  0.4.11-dev-195-gef016bf
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 
70  InitializeListHead(&CodePageListHead);
71  RtlInitializeCriticalSection(&CodePageListLock);
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 
80  InitializeObjectAttributes(&ObjectAttributes,
81  &DirName,
83  NULL,
84  NULL);
85 
86  if (NT_SUCCESS(NtCreateDirectoryObject(&Handle, DIRECTORY_ALL_ACCESS, &ObjectAttributes)))
87  {
88  NtClose(Handle);
89  }
90 
91  /* Setup ANSI code page. */
92  AnsiCodePage.SectionHandle = NULL;
93  AnsiCodePage.SectionMapping = NtCurrentTeb()->ProcessEnvironmentBlock->AnsiCodePageData;
94 
96  &AnsiCodePage.CodePageTable);
97  AnsiCodePage.CodePage = AnsiCodePage.CodePageTable.CodePage;
98 
99  InsertTailList(&CodePageListHead, &AnsiCodePage.Entry);
100 
101  /* Setup OEM code page. */
102  OemCodePage.SectionHandle = NULL;
103  OemCodePage.SectionMapping = NtCurrentTeb()->ProcessEnvironmentBlock->OemCodePageData;
104 
106  &OemCodePage.CodePageTable);
107  OemCodePage.CodePage = OemCodePage.CodePageTable.CodePage;
108  InsertTailList(&CodePageListHead, &OemCodePage.Entry);
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  {
128  Current = CONTAINING_RECORD(CodePageListHead.Flink, CODEPAGE_ENTRY, Entry);
129  if (Current->SectionHandle != NULL)
130  {
132  NtClose(Current->SectionHandle);
133  }
134  RemoveHeadList(&CodePageListHead);
135  }
136  RtlDeleteCriticalSection(&CodePageListLock);
137 }
138 
154 FASTCALL
156 {
157  LIST_ENTRY *CurrentEntry;
158  PCODEPAGE_ENTRY Current;
159 
160  RtlEnterCriticalSection(&CodePageListLock);
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  {
168  RtlLeaveCriticalSection(&CodePageListLock);
169  return Current;
170  }
171  }
172  RtlLeaveCriticalSection(&CodePageListLock);
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  */
248  RtlEnterCriticalSection(&CodePageListLock);
249 
250  /* Generate the section name. */
251  if (!GetNlsSectionName(CodePage,
252  10,
253  0,
254  "\\Nls\\NlsSectionCP",
255  SectionName,
256  sizeof(SectionName)))
257  {
258  RtlLeaveCriticalSection(&CodePageListLock);
259  return NULL;
260  }
261 
262  RtlInitAnsiString(&AnsiName, SectionName);
263  RtlAnsiStringToUnicodeString(&UnicodeName, &AnsiName, TRUE);
264 
265  InitializeObjectAttributes(&ObjectAttributes, &UnicodeName, 0, NULL, NULL);
266 
267  /* Try to open the section first */
268  Status = NtOpenSection(&SectionHandle, SECTION_MAP_READ, &ObjectAttributes);
269 
270  /* If the section doesn't exist, try to create it. */
271  if (Status == STATUS_UNSUCCESSFUL ||
272  Status == STATUS_OBJECT_NAME_NOT_FOUND ||
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;
282  FileHandle = CreateFileW(FileName,
285  NULL,
287  0,
288  NULL);
289 
290  Status = NtCreateSection(&SectionHandle,
292  &ObjectAttributes,
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 */
300  if (Status == STATUS_OBJECT_NAME_COLLISION)
301  {
302  /* Close the file then */
303  NtClose(FileHandle);
304 
305  /* And open the section */
306  Status = NtOpenSection(&SectionHandle,
308  &ObjectAttributes);
309  }
310  }
311  }
312  RtlFreeUnicodeString(&UnicodeName);
313 
314  if (!NT_SUCCESS(Status))
315  {
316  RtlLeaveCriticalSection(&CodePageListLock);
317  return NULL;
318  }
319 
320  SectionMapping = MapViewOfFile(SectionHandle, FILE_MAP_READ, 0, 0, 0);
321  if (SectionMapping == NULL)
322  {
323  NtClose(SectionHandle);
324  RtlLeaveCriticalSection(&CodePageListLock);
325  return NULL;
326  }
327 
328  CodePageEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(CODEPAGE_ENTRY));
329  if (CodePageEntry == NULL)
330  {
331  NtClose(SectionHandle);
332  RtlLeaveCriticalSection(&CodePageListLock);
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);
344  RtlLeaveCriticalSection(&CodePageListLock);
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 */
455  if ((Flags & MB_USEGLYPHCHARS) && CodePageTable->MultiByteTable[256])
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. */
466  if (CodePageTable->DBCSCodePage)
467  {
468  UCHAR Char;
469  USHORT DBCSOffset;
470  LPCSTR MbsEnd = MultiByteString + MultiByteCount;
471  INT Count;
472 
473  if (Flags & MB_ERR_INVALID_CHARS)
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. */
576  if (Flags & MB_ERR_INVALID_CHARS)
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  {
655  Char = MultiByteString[Count];
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  {
712  MultiByteString[Count] = (CHAR)Char;
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. */
878  if (Flags & WC_NO_BEST_FIT_CHARS)
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 */
901  if (ch == CodePageTable->TransDefaultChar && wch != CodePageTable->TransUniDefaultChar)
902  return FALSE;
903 
904  /* If the WC_NO_BEST_FIT_CHARS flag has been specified, the characters need to match exactly. */
905  if (Flags & WC_NO_BEST_FIT_CHARS)
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. */
957  if (CodePageTable->DBCSCodePage)
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");
1324  InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE,
1325  NULL, NULL);
1326  Status = NtOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
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. */
1342  Status = NtQueryValueKey(KeyHandle, &ValueName, KeyValuePartialInformation,
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:
1563  return IntMultiByteToWideCharUTF8(Flags,
1564  MultiByteString,
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:
1579  return IntMultiByteToWideCharSYMBOL(Flags,
1580  MultiByteString,
1581  MultiByteCount,
1582  WideCharString,
1583  WideCharCount);
1584  default:
1585  return IntMultiByteToWideCharCP(CodePage,
1586  Flags,
1587  MultiByteString,
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 
1742  lcid = GetUserDefaultLCID();
1743  lcid = ConvertDefaultLocale(lcid);
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,
2025  MultiByteString,
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  }
2050  return IntWideCharToMultiByteSYMBOL(Flags,
2051  WideCharString,
2052  WideCharCount,
2053  MultiByteString,
2054  MultiByteCount);
2055 
2056  default:
2057  return IntWideCharToMultiByteCP(CodePage,
2058  Flags,
2059  WideCharString,
2060  WideCharCount,
2061  MultiByteString,
2062  MultiByteCount,
2063  DefaultChar,
2064  UsedDefaultChar);
2065  }
2066 }
2067 
2076 UINT
2077 WINAPI
2079 {
2080  return AnsiCodePage.CodePageTable.CodePage;
2081 }
2082 
2091 UINT
2092 WINAPI
2094 {
2095  return OemCodePage.CodePageTable.CodePage;
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 /* EOF */
DWORD *typedef PVOID
Definition: winlogon.h:61
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
signed char * PCHAR
Definition: retypes.h:7
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define FILE_GENERIC_READ
Definition: nt_native.h:653
HANDLE HGLOBAL
Definition: windef.h:243
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:3372
#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:223
#define MAKEWORD(a, b)
Definition: typedefs.h:247
unsigned char Byte
Definition: zconf.h:391
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#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:538
WCHAR CodePageName[MAX_PATH]
Definition: winnls.h:587
#define LANG_NEUTRAL
Definition: nls.h:22
BOOL WINAPI ValidateLocale(IN ULONG LocaleId)
Definition: nls.c:2219
#define CP_ACP
Definition: compat.h:99
IN OUT PIRP IN ULONG IN WMIENABLEDISABLECONTROL Function
Definition: wmilib.h:37
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
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
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:569
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:523
_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
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:222
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
DWORD DWORD
Definition: winlogon.h:84
#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:807
static INT WINAPI IntMultiByteToWideCharSYMBOL(DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:629
GLuint const GLubyte GLvoid * src
Definition: s_context.h:57
BOOL WINAPI NlsResetProcessLocale(VOID)
Definition: nls.c:2186
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
BOOL WINAPI IsDBCSLeadByteEx(UINT CodePage, BYTE TestByte)
Definition: nls.c:2108
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
GLenum GLclampf GLint i
Definition: glfuncs.h:14
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 FALSE
Definition: types.h:117
#define UNICODE_NULL
LCID WINAPI ConvertDefaultLocale(LCID lcid)
Definition: lang.c:1176
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:63
char Char
Definition: bzip2.c:161
NTSTATUS NTAPI NtOpenSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: section.c:3500
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
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
UINTN Size
Definition: acefiex.h:555
#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
LONG NTSTATUS
Definition: precomp.h:26
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:62
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:571
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
#define LOCALE_SYSTEM_DEFAULT
_In_ ACCESS_MASK AccessMask
Definition: exfuncs.h:186
unsigned short * PUSHORT
Definition: retypes.h:2
#define for
Definition: utility.h:88
#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
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3393
#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
#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:579
static RTL_CRITICAL_SECTION CodePageListLock
Definition: nls.c:43
#define index(s, c)
Definition: various.h:29
static const WCHAR L[]
Definition: oid.c:1087
VOID UINTN Length
Definition: acefiex.h:744
_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
#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
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
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
UINTN UINT8 Value
Definition: acefiex.h:751
unsigned char BYTE
Definition: ntddk_ex.h:96
UINT GetLocalisedText(IN UINT uID, IN LPWSTR lpszDest, IN UINT cchDest)
Definition: nls.c:1726
Status
Definition: gdiplustypes.h:24
static HANDLE FileHandle
Definition: cabinet.c:48
NTSTATUS NTAPI NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:731
DWORD *typedef HANDLE
Definition: winlogon.h:61
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:60
#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:570
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
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2312
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define PAGE_READONLY
Definition: compat.h:127
static const unsigned char UTF8Mask[6]
Definition: nls.c:37
GLuint const GLubyte GLvoid const GLvoid * dst
Definition: s_context.h:57
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
PBYTE SectionMapping
Definition: kernel32.h:65
*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:120
#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:64
GLfloat GLfloat p
Definition: glext.h:8902
NTSYSAPI NTSTATUS NTAPI RtlDeleteCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define CP_THREAD_ACP
Definition: winnls.h:221
VOID FASTCALL NlsUninit(VOID)
Definition: nls.c:121
#define UnmapViewOfFile
Definition: compat.h:403
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#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:219
#define HeapFree(x, y, z)
Definition: compat.h:394
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583
base of all file and directory entries
Definition: entries.h:82
CPTABLEINFO CodePageTable
Definition: kernel32.h:66
LCID WINAPI GetThreadLocale(void)
Definition: lang.c:1123
#define CP_MACCP
Definition: winnls.h:220
#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