ReactOS  0.4.13-dev-479-gec9c8fd
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  * Katayama Hirofumi MZ
11  * UPDATE HISTORY:
12  * Created 24/08/2004
13  */
14 
15 /* INCLUDES *******************************************************************/
16 
17 #include <k32.h>
18 
19 #define NDEBUG
20 #include <debug.h>
21 
22 /* GLOBAL VARIABLES ***********************************************************/
23 
24 /* Sequence length based on the first character. */
25 static const char UTF8Length[128] =
26 {
27  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8F */
28  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9F */
29  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0 - 0xAF */
30  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0 - 0xBF */
31  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xC0 - 0xCF */
32  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xD0 - 0xDF */
33  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xE0 - 0xEF */
34  3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 0, 0 /* 0xF0 - 0xFF */
35 };
36 
37 /* First byte mask depending on UTF-8 sequence length. */
38 static const unsigned char UTF8Mask[6] = {0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
39 
40 /* UTF-8 length to lower bound */
41 static const unsigned long UTF8LBound[] =
42  {0, 0x80, 0x800, 0x10000, 0x200000, 0x2000000, 0xFFFFFFFF};
43 
44 /* FIXME: Change to HASH table or linear array. */
49 
50 /* FORWARD DECLARATIONS *******************************************************/
51 
54  LPSTR BaseName, LPSTR Result, ULONG ResultSize);
55 
57 GetCPFileNameFromRegistry(UINT CodePage, LPWSTR FileName, ULONG FileNameSize);
58 
59 /* PRIVATE FUNCTIONS **********************************************************/
60 
67 BOOL
70 {
73  HANDLE Handle;
74 
77 
78  /*
79  * FIXME: Eventually this should be done only for the NLS Server
80  * process, but since we don't have anything like that (yet?) we
81  * always try to create the "\Nls" directory here.
82  */
83  RtlInitUnicodeString(&DirName, L"\\Nls");
84 
86  &DirName,
88  NULL,
89  NULL);
90 
92  {
93  NtClose(Handle);
94  }
95 
96  /* Setup ANSI code page. */
98  AnsiCodePage.SectionMapping = NtCurrentTeb()->ProcessEnvironmentBlock->AnsiCodePageData;
99 
103 
105 
106  /* Setup OEM code page. */
108  OemCodePage.SectionMapping = NtCurrentTeb()->ProcessEnvironmentBlock->OemCodePageData;
109 
114 
115  return TRUE;
116 }
117 
124 VOID
125 FASTCALL
127 {
128  PCODEPAGE_ENTRY Current;
129 
130  /* Delete the code page list. */
131  while (!IsListEmpty(&CodePageListHead))
132  {
134  if (Current->SectionHandle != NULL)
135  {
137  NtClose(Current->SectionHandle);
138  }
140  }
142 }
143 
159 FASTCALL
161 {
162  LIST_ENTRY *CurrentEntry;
163  PCODEPAGE_ENTRY Current;
164 
166  for (CurrentEntry = CodePageListHead.Flink;
167  CurrentEntry != &CodePageListHead;
168  CurrentEntry = CurrentEntry->Flink)
169  {
170  Current = CONTAINING_RECORD(CurrentEntry, CODEPAGE_ENTRY, Entry);
171  if (Current->CodePage == CodePage)
172  {
174  return Current;
175  }
176  }
178 
179  return NULL;
180 }
181 
195 FASTCALL
197 {
198  CHAR SectionName[40];
200  HANDLE SectionHandle = INVALID_HANDLE_VALUE, FileHandle;
201  PBYTE SectionMapping;
203  ANSI_STRING AnsiName;
205  WCHAR FileName[MAX_PATH + 1];
206  UINT FileNamePos;
207  PCODEPAGE_ENTRY CodePageEntry;
208  if (CodePage == CP_ACP)
209  {
210  return &AnsiCodePage;
211  }
212  else if (CodePage == CP_OEMCP)
213  {
214  return &OemCodePage;
215  }
216  else if (CodePage == CP_THREAD_ACP)
217  {
219  LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
220  (WCHAR *)&CodePage,
221  sizeof(CodePage) / sizeof(WCHAR)))
222  {
223  /* Last error is set by GetLocaleInfoW. */
224  return NULL;
225  }
226  if (CodePage == 0)
227  return &AnsiCodePage;
228  }
229  else if (CodePage == CP_MACCP)
230  {
232  LOCALE_IDEFAULTMACCODEPAGE | LOCALE_RETURN_NUMBER,
233  (WCHAR *)&CodePage,
234  sizeof(CodePage) / sizeof(WCHAR)))
235  {
236  /* Last error is set by GetLocaleInfoW. */
237  return NULL;
238  }
239  }
240 
241  /* Try searching for loaded page first. */
242  CodePageEntry = IntGetLoadedCodePageEntry(CodePage);
243  if (CodePageEntry != NULL)
244  {
245  return CodePageEntry;
246  }
247 
248  /*
249  * Yes, we really want to lock here. Otherwise it can happen that
250  * two parallel requests will try to get the entry for the same
251  * code page and we would load it twice.
252  */
254 
255  /* Generate the section name. */
256  if (!GetNlsSectionName(CodePage,
257  10,
258  0,
259  "\\Nls\\NlsSectionCP",
260  SectionName,
261  sizeof(SectionName)))
262  {
264  return NULL;
265  }
266 
267  RtlInitAnsiString(&AnsiName, SectionName);
269 
271 
272  /* Try to open the section first */
274 
275  /* If the section doesn't exist, try to create it. */
276  if (Status == STATUS_UNSUCCESSFUL ||
279  {
280  FileNamePos = GetSystemDirectoryW(FileName, MAX_PATH);
281  if (GetCPFileNameFromRegistry(CodePage,
282  FileName + FileNamePos + 1,
283  MAX_PATH - FileNamePos - 1))
284  {
285  FileName[FileNamePos] = L'\\';
286  FileName[MAX_PATH] = 0;
290  NULL,
292  0,
293  NULL);
294 
295  Status = NtCreateSection(&SectionHandle,
298  NULL,
300  SEC_COMMIT,
301  FileHandle);
302 
303  /* HACK: Check if another process was faster
304  * and already created this section. See bug 3626 for details */
306  {
307  /* Close the file then */
309 
310  /* And open the section */
311  Status = NtOpenSection(&SectionHandle,
314  }
315  }
316  }
318 
319  if (!NT_SUCCESS(Status))
320  {
322  return NULL;
323  }
324 
325  SectionMapping = MapViewOfFile(SectionHandle, FILE_MAP_READ, 0, 0, 0);
326  if (SectionMapping == NULL)
327  {
328  NtClose(SectionHandle);
330  return NULL;
331  }
332 
333  CodePageEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(CODEPAGE_ENTRY));
334  if (CodePageEntry == NULL)
335  {
336  NtClose(SectionHandle);
338  return NULL;
339  }
340 
341  CodePageEntry->CodePage = CodePage;
342  CodePageEntry->SectionHandle = SectionHandle;
343  CodePageEntry->SectionMapping = SectionMapping;
344 
345  RtlInitCodePageTable((PUSHORT)SectionMapping, &CodePageEntry->CodePageTable);
346 
347  /* Insert the new entry to list and unlock. Uff. */
348  InsertTailList(&CodePageListHead, &CodePageEntry->Entry);
350 
351  return CodePageEntry;
352 }
353 
362 static
363 INT
364 WINAPI
367  INT MultiByteCount,
368  LPWSTR WideCharString,
369  INT WideCharCount)
370 {
371  LPCSTR MbsEnd, MbsPtrSave;
372  UCHAR Char, TrailLength;
373  WCHAR WideChar;
374  LONG Count;
375  BOOL CharIsValid, StringIsValid = TRUE;
376  const WCHAR InvalidChar = 0xFFFD;
377 
378  if (Flags != 0 && Flags != MB_ERR_INVALID_CHARS)
379  {
381  return 0;
382  }
383 
384  /* Does caller query for output buffer size? */
385  if (WideCharCount == 0)
386  {
387  /* validate and count the wide characters */
388  MbsEnd = MultiByteString + MultiByteCount;
389  for (; MultiByteString < MbsEnd; WideCharCount++)
390  {
391  Char = *MultiByteString++;
392  if (Char < 0xC0)
393  {
394  TrailLength = 0;
395  continue;
396  }
397  if (Char >= 0xF8 || (Char & 0xC0) == 0x80)
398  {
399  TrailLength = 0;
400  StringIsValid = FALSE;
401  continue;
402  }
403 
404  CharIsValid = TRUE;
405  MbsPtrSave = MultiByteString;
406  TrailLength = UTF8Length[Char - 0x80];
407  WideChar = Char & UTF8Mask[TrailLength];
408 
409  while (TrailLength && MultiByteString < MbsEnd)
410  {
411  if ((*MultiByteString & 0xC0) != 0x80)
412  {
413  CharIsValid = StringIsValid = FALSE;
414  break;
415  }
416 
417  WideChar = (WideChar << 6) | (*MultiByteString++ & 0x7f);
418  TrailLength--;
419  }
420 
421  if (!CharIsValid || WideChar < UTF8LBound[UTF8Length[Char - 0x80]])
422  {
423  MultiByteString = MbsPtrSave;
424  }
425  }
426 
427  if (TrailLength)
428  {
429  WideCharCount++;
430  }
431 
432  if (Flags == MB_ERR_INVALID_CHARS && (!StringIsValid || TrailLength))
433  {
435  return 0;
436  }
437 
438  return WideCharCount;
439  }
440 
441  /* convert */
442  MbsEnd = MultiByteString + MultiByteCount;
443  for (Count = 0; Count < WideCharCount && MultiByteString < MbsEnd; Count++)
444  {
445  Char = *MultiByteString++;
446  if (Char < 0x80)
447  {
448  *WideCharString++ = Char;
449  TrailLength = 0;
450  continue;
451  }
452  if (Char >= 0xF8 || Char == 0x80 || (Char & 0xC0) == 0x80)
453  {
454  *WideCharString++ = InvalidChar;
455  TrailLength = 0;
456  continue;
457  }
458 
459  CharIsValid = TRUE;
460  MbsPtrSave = MultiByteString;
461  TrailLength = UTF8Length[Char - 0x80];
462  WideChar = Char & UTF8Mask[TrailLength];
463 
464  while (TrailLength && MultiByteString < MbsEnd)
465  {
466  if ((*MultiByteString & 0xC0) != 0x80)
467  {
468  CharIsValid = StringIsValid = FALSE;
469  break;
470  }
471 
472  WideChar = (WideChar << 6) | (*MultiByteString++ & 0x7f);
473  TrailLength--;
474  }
475 
476  if (CharIsValid && UTF8LBound[UTF8Length[Char - 0x80]] <= WideChar)
477  {
478  *WideCharString++ = WideChar;
479  }
480  else
481  {
482  *WideCharString++ = InvalidChar;
483  MultiByteString = MbsPtrSave;
484  }
485  }
486 
487  if (TrailLength && Count < WideCharCount && MultiByteString < MbsEnd)
488  {
489  *WideCharString = InvalidChar;
490  WideCharCount++;
491  }
492 
493  if (MultiByteString < MbsEnd)
494  {
496  return 0;
497  }
498 
499  if (Flags == MB_ERR_INVALID_CHARS && (!StringIsValid || TrailLength))
500  {
502  return 0;
503  }
504 
505  return Count;
506 }
507 
518 static
519 INT
520 WINAPI
522  DWORD Flags,
524  INT MultiByteCount,
525  LPWSTR WideCharString,
526  INT WideCharCount)
527 {
528  PCODEPAGE_ENTRY CodePageEntry;
530  PUSHORT MultiByteTable;
531  LPCSTR TempString;
532  INT TempLength;
533  USHORT WideChar;
534 
535  /* Get code page table. */
536  CodePageEntry = IntGetCodePageEntry(CodePage);
537  if (CodePageEntry == NULL)
538  {
540  return 0;
541  }
542 
543  CodePageTable = &CodePageEntry->CodePageTable;
544 
545  /* If MB_USEGLYPHCHARS flag present and glyph table present */
547  {
548  /* Use glyph table */
549  MultiByteTable = CodePageTable->MultiByteTable + 256 + 1;
550  }
551  else
552  {
553  MultiByteTable = CodePageTable->MultiByteTable;
554  }
555 
556  /* Different handling for DBCS code pages. */
558  {
559  UCHAR Char;
560  USHORT DBCSOffset;
561  LPCSTR MbsEnd = MultiByteString + MultiByteCount;
562  INT Count;
563 
565  {
566  TempString = MultiByteString;
567 
568  while (TempString < MbsEnd)
569  {
570  DBCSOffset = CodePageTable->DBCSOffsets[(UCHAR)*TempString];
571 
572  if (DBCSOffset)
573  {
574  /* If lead byte is presented, but behind it there is no symbol */
575  if (((TempString + 1) == MbsEnd) || (*(TempString + 1) == 0))
576  {
578  return 0;
579  }
580 
581  WideChar = CodePageTable->DBCSOffsets[DBCSOffset + *(TempString + 1)];
582 
583  if (WideChar == CodePageTable->UniDefaultChar &&
584  MAKEWORD(*(TempString + 1), *TempString) != CodePageTable->TransUniDefaultChar)
585  {
587  return 0;
588  }
589 
590  TempString++;
591  }
592  else
593  {
594  WideChar = MultiByteTable[(UCHAR)*TempString];
595 
596  if ((WideChar == CodePageTable->UniDefaultChar &&
597  *TempString != CodePageTable->TransUniDefaultChar) ||
598  /* "Private Use" characters */
599  (WideChar >= 0xE000 && WideChar <= 0xF8FF))
600  {
602  return 0;
603  }
604  }
605 
606  TempString++;
607  }
608  }
609 
610  /* Does caller query for output buffer size? */
611  if (WideCharCount == 0)
612  {
613  for (; MultiByteString < MbsEnd; WideCharCount++)
614  {
615  Char = *MultiByteString++;
616 
617  DBCSOffset = CodePageTable->DBCSOffsets[Char];
618 
619  if (!DBCSOffset)
620  continue;
621 
622  if (MultiByteString < MbsEnd)
623  MultiByteString++;
624  }
625 
626  return WideCharCount;
627  }
628 
629  for (Count = 0; Count < WideCharCount && MultiByteString < MbsEnd; Count++)
630  {
631  Char = *MultiByteString++;
632 
633  DBCSOffset = CodePageTable->DBCSOffsets[Char];
634 
635  if (!DBCSOffset)
636  {
637  *WideCharString++ = MultiByteTable[Char];
638  continue;
639  }
640 
641  if (MultiByteString == MbsEnd)
642  {
643  *WideCharString++ = MultiByteTable[Char];
644  }
645  else if (*MultiByteString == 0)
646  {
647  *WideCharString++ = UNICODE_NULL;
648  MultiByteString++;
649  }
650  else
651  {
652  *WideCharString++ = CodePageTable->DBCSOffsets[DBCSOffset + (UCHAR)*MultiByteString++];
653  }
654  }
655 
656  if (MultiByteString < MbsEnd)
657  {
659  return 0;
660  }
661 
662  return Count;
663  }
664  else /* SBCS code page */
665  {
666  /* Check for invalid characters. */
668  {
669  for (TempString = MultiByteString, TempLength = MultiByteCount;
670  TempLength > 0;
671  TempString++, TempLength--)
672  {
673  WideChar = MultiByteTable[(UCHAR)*TempString];
674 
675  if ((WideChar == CodePageTable->UniDefaultChar &&
676  *TempString != CodePageTable->TransUniDefaultChar) ||
677  /* "Private Use" characters */
678  (WideChar >= 0xE000 && WideChar <= 0xF8FF))
679  {
681  return 0;
682  }
683  }
684  }
685 
686  /* Does caller query for output buffer size? */
687  if (WideCharCount == 0)
688  return MultiByteCount;
689 
690  /* Fill the WideCharString buffer with what will fit: Verified on WinXP */
691  for (TempLength = (WideCharCount < MultiByteCount) ? WideCharCount : MultiByteCount;
692  TempLength > 0;
693  MultiByteString++, TempLength--)
694  {
695  *WideCharString++ = MultiByteTable[(UCHAR)*MultiByteString];
696  }
697 
698  /* Adjust buffer size. Wine trick ;-) */
699  if (WideCharCount < MultiByteCount)
700  {
701  MultiByteCount = WideCharCount;
703  return 0;
704  }
705  return MultiByteCount;
706  }
707 }
708 
717 static
718 INT
719 WINAPI
722  INT MultiByteCount,
723  LPWSTR WideCharString,
724  INT WideCharCount)
725 {
726  LONG Count;
727  UCHAR Char;
728  INT WideCharMaxLen;
729 
730 
731  if (Flags != 0)
732  {
734  return 0;
735  }
736 
737  if (WideCharCount == 0)
738  {
739  return MultiByteCount;
740  }
741 
742  WideCharMaxLen = WideCharCount > MultiByteCount ? MultiByteCount : WideCharCount;
743 
744  for (Count = 0; Count < WideCharMaxLen; Count++)
745  {
747  if ( Char < 0x20 )
748  {
749  WideCharString[Count] = Char;
750  }
751  else
752  {
753  WideCharString[Count] = Char + 0xf000;
754  }
755  }
756  if (MultiByteCount > WideCharMaxLen)
757  {
759  return 0;
760  }
761 
762  return WideCharMaxLen;
763 }
764 
773 static INT
774 WINAPI
776  LPCWSTR WideCharString,
777  INT WideCharCount,
779  INT MultiByteCount)
780 {
781  LONG Count;
782  INT MaxLen;
783  WCHAR Char;
784 
785  if (Flags!=0)
786  {
788  return 0;
789  }
790 
791 
792  if (MultiByteCount == 0)
793  {
794  return WideCharCount;
795  }
796 
797  MaxLen = MultiByteCount > WideCharCount ? WideCharCount : MultiByteCount;
798  for (Count = 0; Count < MaxLen; Count++)
799  {
800  Char = WideCharString[Count];
801  if (Char < 0x20)
802  {
804  }
805  else
806  {
807  if ((Char >= 0xf020) && (Char < 0xf100))
808  {
809  MultiByteString[Count] = Char - 0xf000;
810  }
811  else
812  {
814  return 0;
815  }
816  }
817  }
818 
819  if (WideCharCount > MaxLen)
820  {
822  return 0;
823  }
824  return MaxLen;
825 }
826 
835 static INT
836 WINAPI
838  DWORD Flags,
839  LPCWSTR WideCharString,
840  INT WideCharCount,
842  INT MultiByteCount,
843  LPCSTR DefaultChar,
844  LPBOOL UsedDefaultChar)
845 {
846  INT TempLength;
847  DWORD Char;
848 
849  if (Flags)
850  {
852  return 0;
853  }
854 
855  /* Does caller query for output buffer size? */
856  if (MultiByteCount == 0)
857  {
858  for (TempLength = 0; WideCharCount;
859  WideCharCount--, WideCharString++)
860  {
861  TempLength++;
862  if (*WideCharString >= 0x80)
863  {
864  TempLength++;
865  if (*WideCharString >= 0x800)
866  {
867  TempLength++;
868  if (*WideCharString >= 0xd800 && *WideCharString < 0xdc00 &&
869  WideCharCount >= 1 &&
870  WideCharString[1] >= 0xdc00 && WideCharString[1] <= 0xe000)
871  {
872  WideCharCount--;
873  WideCharString++;
874  TempLength++;
875  }
876  }
877  }
878  }
879  return TempLength;
880  }
881 
882  for (TempLength = MultiByteCount; WideCharCount; WideCharCount--, WideCharString++)
883  {
884  Char = *WideCharString;
885  if (Char < 0x80)
886  {
887  if (!TempLength)
888  {
890  break;
891  }
892  TempLength--;
893  *MultiByteString++ = (CHAR)Char;
894  continue;
895  }
896 
897  if (Char < 0x800) /* 0x80-0x7ff: 2 bytes */
898  {
899  if (TempLength < 2)
900  {
902  break;
903  }
904  MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
905  MultiByteString[0] = 0xc0 | Char;
906  MultiByteString += 2;
907  TempLength -= 2;
908  continue;
909  }
910 
911  /* surrogate pair 0x10000-0x10ffff: 4 bytes */
912  if (Char >= 0xd800 && Char < 0xdc00 &&
913  WideCharCount >= 1 &&
914  WideCharString[1] >= 0xdc00 && WideCharString[1] < 0xe000)
915  {
916  WideCharCount--;
917  WideCharString++;
918 
919  if (TempLength < 4)
920  {
922  break;
923  }
924 
925  Char = (Char - 0xd800) << 10;
926  Char |= *WideCharString - 0xdc00;
927  ASSERT(Char <= 0xfffff);
928  Char += 0x10000;
929  ASSERT(Char <= 0x10ffff);
930 
931  MultiByteString[3] = 0x80 | (Char & 0x3f); Char >>= 6;
932  MultiByteString[2] = 0x80 | (Char & 0x3f); Char >>= 6;
933  MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
934  MultiByteString[0] = 0xf0 | Char;
935  MultiByteString += 4;
936  TempLength -= 4;
937  continue;
938  }
939 
940  /* 0x800-0xffff: 3 bytes */
941  if (TempLength < 3)
942  {
944  break;
945  }
946  MultiByteString[2] = 0x80 | (Char & 0x3f); Char >>= 6;
947  MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
948  MultiByteString[0] = 0xe0 | Char;
949  MultiByteString += 3;
950  TempLength -= 3;
951  }
952 
953  return MultiByteCount - TempLength;
954 }
955 
963 static
964 inline
965 BOOL
967 {
968  /* If the WC_NO_BEST_FIT_CHARS flag has been specified, the characters need to match exactly. */
970  return (CodePageTable->MultiByteTable[ch] == wch);
971 
972  /* By default, all characters except TransDefaultChar apply as a valid mapping
973  for ch (so also "nearest" characters) */
974  if (ch != CodePageTable->TransDefaultChar)
975  return TRUE;
976 
977  /* The only possible left valid mapping is the default character itself */
978  return (wch == CodePageTable->TransUniDefaultChar);
979 }
980 
988 static inline BOOL
990 {
991  /* If ch is the default character, but the wch is not, it can't be a valid mapping */
993  return FALSE;
994 
995  /* If the WC_NO_BEST_FIT_CHARS flag has been specified, the characters need to match exactly. */
997  {
998  if(ch & 0xff00)
999  {
1000  USHORT uOffset = CodePageTable->DBCSOffsets[ch >> 8];
1001  /* if (!uOffset) return (CodePageTable->MultiByteTable[ch] == wch); */
1002  return (CodePageTable->DBCSOffsets[uOffset + (ch & 0xff)] == wch);
1003  }
1004 
1005  return (CodePageTable->MultiByteTable[ch] == wch);
1006  }
1007 
1008  /* If we're still here, we have a valid mapping */
1009  return TRUE;
1010 }
1011 
1020 static
1021 INT
1022 WINAPI
1024  DWORD Flags,
1025  LPCWSTR WideCharString,
1026  INT WideCharCount,
1028  INT MultiByteCount,
1029  LPCSTR DefaultChar,
1030  LPBOOL UsedDefaultChar)
1031 {
1032  PCODEPAGE_ENTRY CodePageEntry;
1034  INT TempLength;
1035 
1036  /* Get code page table. */
1037  CodePageEntry = IntGetCodePageEntry(CodePage);
1038  if (CodePageEntry == NULL)
1039  {
1041  return 0;
1042  }
1043 
1044  CodePageTable = &CodePageEntry->CodePageTable;
1045 
1046 
1047  /* Different handling for DBCS code pages. */
1049  {
1050  /* If Flags, DefaultChar or UsedDefaultChar were given, we have to do some more work */
1051  if (Flags || DefaultChar || UsedDefaultChar)
1052  {
1053  BOOL TempUsedDefaultChar;
1054  USHORT DefChar;
1055 
1056  /* If UsedDefaultChar is not set, set it to a temporary value, so we don't have
1057  to check on every character */
1058  if (!UsedDefaultChar)
1059  UsedDefaultChar = &TempUsedDefaultChar;
1060 
1061  *UsedDefaultChar = FALSE;
1062 
1063  /* Use the CodePage's TransDefaultChar if none was given. Don't modify the DefaultChar pointer here. */
1064  if (DefaultChar)
1065  DefChar = DefaultChar[1] ? ((DefaultChar[0] << 8) | DefaultChar[1]) : DefaultChar[0];
1066  else
1067  DefChar = CodePageTable->TransDefaultChar;
1068 
1069  /* Does caller query for output buffer size? */
1070  if (!MultiByteCount)
1071  {
1072  for (TempLength = 0; WideCharCount; WideCharCount--, WideCharString++, TempLength++)
1073  {
1074  USHORT uChar;
1075 
1076  if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1077  {
1078  /* FIXME: Handle WC_COMPOSITECHECK */
1079  DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1080  }
1081 
1082  uChar = ((PUSHORT) CodePageTable->WideCharTable)[*WideCharString];
1083 
1084  /* Verify if the mapping is valid for handling DefaultChar and UsedDefaultChar */
1085  if (!IntIsValidDBCSMapping(CodePageTable, Flags, *WideCharString, uChar))
1086  {
1087  uChar = DefChar;
1088  *UsedDefaultChar = TRUE;
1089  }
1090 
1091  /* Increment TempLength again if this is a double-byte character */
1092  if (uChar & 0xff00)
1093  TempLength++;
1094  }
1095 
1096  return TempLength;
1097  }
1098 
1099  /* Convert the WideCharString to the MultiByteString and verify if the mapping is valid */
1100  for (TempLength = MultiByteCount;
1101  WideCharCount && TempLength;
1102  TempLength--, WideCharString++, WideCharCount--)
1103  {
1104  USHORT uChar;
1105 
1106  if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1107  {
1108  /* FIXME: Handle WC_COMPOSITECHECK */
1109  DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1110  }
1111 
1112  uChar = ((PUSHORT)CodePageTable->WideCharTable)[*WideCharString];
1113 
1114  /* Verify if the mapping is valid for handling DefaultChar and UsedDefaultChar */
1115  if (!IntIsValidDBCSMapping(CodePageTable, Flags, *WideCharString, uChar))
1116  {
1117  uChar = DefChar;
1118  *UsedDefaultChar = TRUE;
1119  }
1120 
1121  /* Handle double-byte characters */
1122  if (uChar & 0xff00)
1123  {
1124  /* Don't output a partial character */
1125  if (TempLength == 1)
1126  break;
1127 
1128  TempLength--;
1129  *MultiByteString++ = uChar >> 8;
1130  }
1131 
1132  *MultiByteString++ = (char)uChar;
1133  }
1134 
1135  /* WideCharCount should be 0 if all characters were converted */
1136  if (WideCharCount)
1137  {
1139  return 0;
1140  }
1141 
1142  return MultiByteCount - TempLength;
1143  }
1144 
1145  /* Does caller query for output buffer size? */
1146  if (!MultiByteCount)
1147  {
1148  for (TempLength = 0; WideCharCount; WideCharCount--, WideCharString++, TempLength++)
1149  {
1150  /* Increment TempLength again if this is a double-byte character */
1151  if (((PWCHAR)CodePageTable->WideCharTable)[*WideCharString] & 0xff00)
1152  TempLength++;
1153  }
1154 
1155  return TempLength;
1156  }
1157 
1158  /* Convert the WideCharString to the MultiByteString */
1159  for (TempLength = MultiByteCount;
1160  WideCharCount && TempLength;
1161  TempLength--, WideCharString++, WideCharCount--)
1162  {
1163  USHORT uChar = ((PUSHORT) CodePageTable->WideCharTable)[*WideCharString];
1164 
1165  /* Is this a double-byte character? */
1166  if (uChar & 0xff00)
1167  {
1168  /* Don't output a partial character */
1169  if (TempLength == 1)
1170  break;
1171 
1172  TempLength--;
1173  *MultiByteString++ = uChar >> 8;
1174  }
1175 
1176  *MultiByteString++ = (char)uChar;
1177  }
1178 
1179  /* WideCharCount should be 0 if all characters were converted */
1180  if (WideCharCount)
1181  {
1183  return 0;
1184  }
1185 
1186  return MultiByteCount - TempLength;
1187  }
1188  else /* SBCS code page */
1189  {
1190  INT nReturn;
1191 
1192  /* If Flags, DefaultChar or UsedDefaultChar were given, we have to do some more work */
1193  if (Flags || DefaultChar || UsedDefaultChar)
1194  {
1195  BOOL TempUsedDefaultChar;
1196  CHAR DefChar;
1197 
1198  /* If UsedDefaultChar is not set, set it to a temporary value, so we don't have
1199  to check on every character */
1200  if (!UsedDefaultChar)
1201  UsedDefaultChar = &TempUsedDefaultChar;
1202 
1203  *UsedDefaultChar = FALSE;
1204 
1205  /* Does caller query for output buffer size? */
1206  if (!MultiByteCount)
1207  {
1208  /* Loop through the whole WideCharString and check if we can get a valid mapping for each character */
1209  for (TempLength = 0; WideCharCount; TempLength++, WideCharString++, WideCharCount--)
1210  {
1211  if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1212  {
1213  /* FIXME: Handle WC_COMPOSITECHECK */
1214  DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1215  }
1216 
1217  if (!*UsedDefaultChar)
1218  *UsedDefaultChar = !IntIsValidSBCSMapping(CodePageTable,
1219  Flags,
1220  *WideCharString,
1221  ((PCHAR)CodePageTable->WideCharTable)[*WideCharString]);
1222  }
1223 
1224  return TempLength;
1225  }
1226 
1227  /* Use the CodePage's TransDefaultChar if none was given. Don't modify the DefaultChar pointer here. */
1228  if (DefaultChar)
1229  DefChar = *DefaultChar;
1230  else
1231  DefChar = (CHAR)CodePageTable->TransDefaultChar;
1232 
1233  /* Convert the WideCharString to the MultiByteString and verify if the mapping is valid */
1234  for (TempLength = MultiByteCount;
1235  WideCharCount && TempLength;
1236  MultiByteString++, TempLength--, WideCharString++, WideCharCount--)
1237  {
1238  if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1239  {
1240  /* FIXME: Handle WC_COMPOSITECHECK */
1241  DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1242  }
1243 
1244  *MultiByteString = ((PCHAR)CodePageTable->WideCharTable)[*WideCharString];
1245 
1246  if (!IntIsValidSBCSMapping(CodePageTable, Flags, *WideCharString, *MultiByteString))
1247  {
1248  *MultiByteString = DefChar;
1249  *UsedDefaultChar = TRUE;
1250  }
1251  }
1252 
1253  /* WideCharCount should be 0 if all characters were converted */
1254  if (WideCharCount)
1255  {
1257  return 0;
1258  }
1259 
1260  return MultiByteCount - TempLength;
1261  }
1262 
1263  /* Does caller query for output buffer size? */
1264  if (!MultiByteCount)
1265  return WideCharCount;
1266 
1267  /* Is the buffer large enough? */
1268  if (MultiByteCount < WideCharCount)
1269  {
1270  /* Convert the string up to MultiByteCount and return 0 */
1271  WideCharCount = MultiByteCount;
1273  nReturn = 0;
1274  }
1275  else
1276  {
1277  /* Otherwise WideCharCount will be the number of converted characters */
1278  nReturn = WideCharCount;
1279  }
1280 
1281  /* Convert the WideCharString to the MultiByteString */
1282  for (TempLength = WideCharCount; --TempLength >= 0; WideCharString++, MultiByteString++)
1283  {
1284  *MultiByteString = ((PCHAR)CodePageTable->WideCharTable)[*WideCharString];
1285  }
1286 
1287  return nReturn;
1288  }
1289 }
1290 
1298 static BOOL
1299 WINAPI
1301 {
1302  UINT i;
1303 
1304  if (TableInfo->MaximumCharacterSize == 2)
1305  {
1306  for (i = 0; i < MAXIMUM_LEADBYTES && TableInfo->LeadByte[i]; i += 2)
1307  {
1308  if (Byte >= TableInfo->LeadByte[i] && Byte <= TableInfo->LeadByte[i+1])
1309  return TRUE;
1310  }
1311  }
1312 
1313  return FALSE;
1314 }
1315 
1316 /* PUBLIC FUNCTIONS ***********************************************************/
1317 
1345 BOOL
1346 WINAPI
1348  UINT Base,
1349  ULONG Unknown,
1350  LPSTR BaseName,
1351  LPSTR Result,
1352  ULONG ResultSize)
1353 {
1354  CHAR Integer[11];
1355 
1356  if (!NT_SUCCESS(RtlIntegerToChar(CodePage, Base, sizeof(Integer), Integer)))
1357  return FALSE;
1358 
1359  /*
1360  * If the name including the terminating NULL character doesn't
1361  * fit in the output buffer then fail.
1362  */
1363  if (strlen(Integer) + strlen(BaseName) >= ResultSize)
1364  return FALSE;
1365 
1366  lstrcpyA(Result, BaseName);
1367  lstrcatA(Result, Integer);
1368 
1369  return TRUE;
1370 }
1371 
1390 BOOL
1391 WINAPI
1393 {
1394  WCHAR ValueNameBuffer[11];
1397  NTSTATUS Status;
1398  HANDLE KeyHandle;
1400  DWORD KvpiSize;
1401  BOOL bRetValue;
1402 
1403  bRetValue = FALSE;
1404 
1405  /* Convert the codepage number to string. */
1406  ValueName.Buffer = ValueNameBuffer;
1407  ValueName.MaximumLength = sizeof(ValueNameBuffer);
1408 
1409  if (!NT_SUCCESS(RtlIntegerToUnicodeString(CodePage, 10, &ValueName)))
1410  return bRetValue;
1411 
1412  /* Open the registry key containing file name mappings. */
1413  RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System\\"
1414  L"CurrentControlSet\\Control\\Nls\\CodePage");
1416  NULL, NULL);
1418  if (!NT_SUCCESS(Status))
1419  {
1420  return bRetValue;
1421  }
1422 
1423  /* Allocate buffer that will be used to query the value data. */
1424  KvpiSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + (MAX_PATH * sizeof(WCHAR));
1425  Kvpi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, KvpiSize);
1426  if (Kvpi == NULL)
1427  {
1428  NtClose(KeyHandle);
1429  return bRetValue;
1430  }
1431 
1432  /* Query the file name for our code page. */
1434  Kvpi, KvpiSize, &KvpiSize);
1435 
1436  NtClose(KeyHandle);
1437 
1438  /* Check if we succeded and the value is non-empty string. */
1439  if (NT_SUCCESS(Status) && Kvpi->Type == REG_SZ &&
1440  Kvpi->DataLength > sizeof(WCHAR))
1441  {
1442  bRetValue = TRUE;
1443  if (FileName != NULL)
1444  {
1445  lstrcpynW(FileName, (WCHAR*)Kvpi->Data,
1446  min(Kvpi->DataLength / sizeof(WCHAR), FileNameSize));
1447  }
1448  }
1449 
1450  /* free temporary buffer */
1451  HeapFree(GetProcessHeap(),0,Kvpi);
1452  return bRetValue;
1453 }
1454 
1466 BOOL
1467 WINAPI
1469 {
1470  if (CodePage == 0) return FALSE;
1471  if (CodePage == CP_UTF8 || CodePage == CP_UTF7)
1472  return TRUE;
1473  if (IntGetLoadedCodePageEntry(CodePage))
1474  return TRUE;
1475  return GetCPFileNameFromRegistry(CodePage, NULL, 0);
1476 }
1477 
1478 static inline BOOL utf7_write_w(WCHAR *dst, int dstlen, int *index, WCHAR character)
1479 {
1480  if (dstlen > 0)
1481  {
1482  if (*index >= dstlen)
1483  return FALSE;
1484 
1485  dst[*index] = character;
1486  }
1487 
1488  (*index)++;
1489 
1490  return TRUE;
1491 }
1492 
1493 static INT Utf7ToWideChar(const char *src, int srclen, WCHAR *dst, int dstlen)
1494 {
1495  static const signed char base64_decoding_table[] =
1496  {
1497  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00-0x0F */
1498  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10-0x1F */
1499  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20-0x2F */
1500  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30-0x3F */
1501  -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40-0x4F */
1502  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50-0x5F */
1503  -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60-0x6F */
1504  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 /* 0x70-0x7F */
1505  };
1506 
1507  const char *source_end = src + srclen;
1508  int dest_index = 0;
1509 
1510  DWORD byte_pair = 0;
1511  short offset = 0;
1512 
1513  while (src < source_end)
1514  {
1515  if (*src == '+')
1516  {
1517  src++;
1518  if (src >= source_end)
1519  break;
1520 
1521  if (*src == '-')
1522  {
1523  /* just a plus sign escaped as +- */
1524  if (!utf7_write_w(dst, dstlen, &dest_index, '+'))
1525  {
1527  return 0;
1528  }
1529  src++;
1530  continue;
1531  }
1532 
1533  do
1534  {
1535  signed char sextet = *src;
1536  if (sextet == '-')
1537  {
1538  /* skip over the dash and end base64 decoding
1539  * the current, unfinished byte pair is discarded */
1540  src++;
1541  offset = 0;
1542  break;
1543  }
1544  if (sextet < 0)
1545  {
1546  /* the next character of src is < 0 and therefore not part of a base64 sequence
1547  * the current, unfinished byte pair is NOT discarded in this case
1548  * this is probably a bug in Windows */
1549  break;
1550  }
1551 
1552  sextet = base64_decoding_table[sextet];
1553  if (sextet == -1)
1554  {
1555  /* -1 means that the next character of src is not part of a base64 sequence
1556  * in other words, all sextets in this base64 sequence have been processed
1557  * the current, unfinished byte pair is discarded */
1558  offset = 0;
1559  break;
1560  }
1561 
1562  byte_pair = (byte_pair << 6) | sextet;
1563  offset += 6;
1564 
1565  if (offset >= 16)
1566  {
1567  /* this byte pair is done */
1568  if (!utf7_write_w(dst, dstlen, &dest_index, (byte_pair >> (offset - 16)) & 0xFFFF))
1569  {
1571  return 0;
1572  }
1573  offset -= 16;
1574  }
1575 
1576  src++;
1577  }
1578  while (src < source_end);
1579  }
1580  else
1581  {
1582  /* we have to convert to unsigned char in case *src < 0 */
1583  if (!utf7_write_w(dst, dstlen, &dest_index, (unsigned char)*src))
1584  {
1586  return 0;
1587  }
1588  src++;
1589  }
1590  }
1591 
1592  return dest_index;
1593 }
1594 
1626 INT
1627 WINAPI
1629  DWORD Flags,
1631  INT MultiByteCount,
1632  LPWSTR WideCharString,
1633  INT WideCharCount)
1634 {
1635  /* Check the parameters. */
1636  if (MultiByteString == NULL ||
1637  MultiByteCount == 0 || WideCharCount < 0 ||
1638  (WideCharCount && (WideCharString == NULL ||
1639  (PVOID)MultiByteString == (PVOID)WideCharString)))
1640  {
1642  return 0;
1643  }
1644 
1645  /* Determine the input string length. */
1646  if (MultiByteCount < 0)
1647  {
1648  MultiByteCount = lstrlenA(MultiByteString) + 1;
1649  }
1650 
1651  switch (CodePage)
1652  {
1653  case CP_UTF8:
1656  MultiByteCount,
1657  WideCharString,
1658  WideCharCount);
1659 
1660  case CP_UTF7:
1661  if (Flags)
1662  {
1664  return 0;
1665  }
1666  return Utf7ToWideChar(MultiByteString, MultiByteCount,
1667  WideCharString, WideCharCount);
1668 
1669  case CP_SYMBOL:
1672  MultiByteCount,
1673  WideCharString,
1674  WideCharCount);
1675  default:
1676  return IntMultiByteToWideCharCP(CodePage,
1677  Flags,
1679  MultiByteCount,
1680  WideCharString,
1681  WideCharCount);
1682  }
1683 }
1684 
1685 static inline BOOL utf7_can_directly_encode(WCHAR codepoint)
1686 {
1687  static const BOOL directly_encodable_table[] =
1688  {
1689  1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, /* 0x00 - 0x0F */
1690  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1F */
1691  1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* 0x20 - 0x2F */
1692  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x30 - 0x3F */
1693  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4F */
1694  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x50 - 0x5F */
1695  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6F */
1696  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* 0x70 - 0x7A */
1697  };
1698 
1699  return codepoint <= 0x7A ? directly_encodable_table[codepoint] : FALSE;
1700 }
1701 
1702 static inline BOOL utf7_write_c(char *dst, int dstlen, int *index, char character)
1703 {
1704  if (dstlen > 0)
1705  {
1706  if (*index >= dstlen)
1707  return FALSE;
1708 
1709  dst[*index] = character;
1710  }
1711 
1712  (*index)++;
1713 
1714  return TRUE;
1715 }
1716 
1717 static INT WideCharToUtf7(const WCHAR *src, int srclen, char *dst, int dstlen)
1718 {
1719  static const char base64_encoding_table[] =
1720  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1721 
1722  const WCHAR *source_end = src + srclen;
1723  int dest_index = 0;
1724 
1725  while (src < source_end)
1726  {
1727  if (*src == '+')
1728  {
1729  if (!utf7_write_c(dst, dstlen, &dest_index, '+'))
1730  {
1732  return 0;
1733  }
1734  if (!utf7_write_c(dst, dstlen, &dest_index, '-'))
1735  {
1737  return 0;
1738  }
1739  src++;
1740  }
1741  else if (utf7_can_directly_encode(*src))
1742  {
1743  if (!utf7_write_c(dst, dstlen, &dest_index, *src))
1744  {
1746  return 0;
1747  }
1748  src++;
1749  }
1750  else
1751  {
1752  unsigned int offset = 0;
1753  DWORD byte_pair = 0;
1754 
1755  if (!utf7_write_c(dst, dstlen, &dest_index, '+'))
1756  {
1758  return 0;
1759  }
1760 
1761  while (src < source_end && !utf7_can_directly_encode(*src))
1762  {
1763  byte_pair = (byte_pair << 16) | *src;
1764  offset += 16;
1765  while (offset >= 6)
1766  {
1767  if (!utf7_write_c(dst, dstlen, &dest_index, base64_encoding_table[(byte_pair >> (offset - 6)) & 0x3F]))
1768  {
1770  return 0;
1771  }
1772  offset -= 6;
1773  }
1774  src++;
1775  }
1776 
1777  if (offset)
1778  {
1779  /* Windows won't create a padded base64 character if there's no room for the - sign
1780  * as well ; this is probably a bug in Windows */
1781  if (dstlen > 0 && dest_index + 1 >= dstlen)
1782  {
1784  return 0;
1785  }
1786 
1787  byte_pair <<= (6 - offset);
1788  if (!utf7_write_c(dst, dstlen, &dest_index, base64_encoding_table[byte_pair & 0x3F]))
1789  {
1791  return 0;
1792  }
1793  }
1794 
1795  /* Windows always explicitly terminates the base64 sequence
1796  even though RFC 2152 (page 3, rule 2) does not require this */
1797  if (!utf7_write_c(dst, dstlen, &dest_index, '-'))
1798  {
1800  return 0;
1801  }
1802  }
1803  }
1804 
1805  return dest_index;
1806 }
1807 
1808 /*
1809  * A function similar to LoadStringW, but adapted for usage by GetCPInfoExW
1810  * and GetGeoInfoW. It uses the current user localization, otherwise falls back
1811  * to English (US). Contrary to LoadStringW which always saves the loaded string
1812  * into the user-given buffer, truncating the string if needed, this function
1813  * returns instead an ERROR_INSUFFICIENT_BUFFER error code if the user buffer
1814  * is not large enough.
1815  */
1816 UINT
1818  IN UINT uID,
1819  IN LPWSTR lpszDest,
1820  IN UINT cchDest)
1821 {
1822  HRSRC hrsrc;
1823  HGLOBAL hmem;
1824  LCID lcid;
1825  LANGID langId;
1826  const WCHAR *p;
1827  UINT i;
1828 
1829  /* See HACK in winnls/lang/xx-XX.rc files */
1830  if (uID == 37)
1831  uID = uID * 100;
1832 
1835 
1836  langId = LANGIDFROMLCID(lcid);
1837 
1838  if (PRIMARYLANGID(langId) == LANG_NEUTRAL)
1840 
1842  (LPWSTR)RT_STRING,
1843  MAKEINTRESOURCEW((uID >> 4) + 1),
1844  langId);
1845 
1846  /* English fallback */
1847  if (!hrsrc)
1848  {
1850  (LPWSTR)RT_STRING,
1851  MAKEINTRESOURCEW((uID >> 4) + 1),
1853  }
1854 
1855  if (!hrsrc)
1856  goto NotFound;
1857 
1858  hmem = LoadResource(hCurrentModule, hrsrc);
1859  if (!hmem)
1860  goto NotFound;
1861 
1862  p = LockResource(hmem);
1863 
1864  for (i = 0; i < (uID & 0x0F); i++)
1865  p += *p + 1;
1866 
1867  /* Needed for GetGeoInfo(): return the needed string size including the NULL terminator */
1868  if (cchDest == 0)
1869  return *p + 1;
1870  /* Needed for GetGeoInfo(): bail out if the user buffer is not large enough */
1871  if (*p + 1 > cchDest)
1872  {
1874  return 0;
1875  }
1876 
1877  i = *p;
1878  if (i > 0)
1879  {
1880  memcpy(lpszDest, p + 1, i * sizeof(WCHAR));
1881  lpszDest[i] = L'\0';
1882  return i;
1883  }
1884 #if 0
1885  else
1886  {
1887  if (cchDest >= 1)
1888  lpszDest[0] = L'\0';
1889  /* Fall-back */
1890  }
1891 #endif
1892 
1893 NotFound:
1894  DPRINT1("Resource not found: uID = %lu\n", uID);
1896  return 0;
1897 }
1898 
1899 /*
1900  * @implemented
1901  */
1902 BOOL
1903 WINAPI
1904 GetCPInfo(UINT CodePage,
1905  LPCPINFO CodePageInfo)
1906 {
1907  PCODEPAGE_ENTRY CodePageEntry;
1908 
1909  if (!CodePageInfo)
1910  {
1912  return FALSE;
1913  }
1914 
1915  CodePageEntry = IntGetCodePageEntry(CodePage);
1916  if (CodePageEntry == NULL)
1917  {
1918  switch(CodePage)
1919  {
1920  case CP_UTF7:
1921  case CP_UTF8:
1922  CodePageInfo->DefaultChar[0] = 0x3f;
1923  CodePageInfo->DefaultChar[1] = 0;
1924  CodePageInfo->LeadByte[0] = CodePageInfo->LeadByte[1] = 0;
1925  CodePageInfo->MaxCharSize = (CodePage == CP_UTF7) ? 5 : 4;
1926  return TRUE;
1927  }
1928 
1929  DPRINT1("Invalid CP!: %lx\n", CodePage);
1931  return FALSE;
1932  }
1933 
1934  if (CodePageEntry->CodePageTable.DefaultChar & 0xff00)
1935  {
1936  CodePageInfo->DefaultChar[0] = (CodePageEntry->CodePageTable.DefaultChar & 0xff00) >> 8;
1937  CodePageInfo->DefaultChar[1] = CodePageEntry->CodePageTable.DefaultChar & 0x00ff;
1938  }
1939  else
1940  {
1941  CodePageInfo->DefaultChar[0] = CodePageEntry->CodePageTable.DefaultChar & 0xff;
1942  CodePageInfo->DefaultChar[1] = 0;
1943  }
1944 
1945  if ((CodePageInfo->MaxCharSize = CodePageEntry->CodePageTable.MaximumCharacterSize) == 2)
1946  memcpy(CodePageInfo->LeadByte, CodePageEntry->CodePageTable.LeadByte, sizeof(CodePageInfo->LeadByte));
1947  else
1948  CodePageInfo->LeadByte[0] = CodePageInfo->LeadByte[1] = 0;
1949 
1950  return TRUE;
1951 }
1952 
1953 /*
1954  * @implemented
1955  */
1956 BOOL
1957 WINAPI
1959  DWORD dwFlags,
1960  LPCPINFOEXW lpCPInfoEx)
1961 {
1962  if (!GetCPInfo(CodePage, (LPCPINFO)lpCPInfoEx))
1963  return FALSE;
1964 
1965  switch(CodePage)
1966  {
1967  case CP_UTF7:
1968  {
1969  lpCPInfoEx->CodePage = CP_UTF7;
1970  lpCPInfoEx->UnicodeDefaultChar = 0x3f;
1971  return GetLocalisedText(lpCPInfoEx->CodePage,
1972  lpCPInfoEx->CodePageName,
1973  ARRAYSIZE(lpCPInfoEx->CodePageName)) != 0;
1974  }
1975  break;
1976 
1977  case CP_UTF8:
1978  {
1979  lpCPInfoEx->CodePage = CP_UTF8;
1980  lpCPInfoEx->UnicodeDefaultChar = 0x3f;
1981  return GetLocalisedText(lpCPInfoEx->CodePage,
1982  lpCPInfoEx->CodePageName,
1983  ARRAYSIZE(lpCPInfoEx->CodePageName)) != 0;
1984  }
1985 
1986  default:
1987  {
1988  PCODEPAGE_ENTRY CodePageEntry;
1989 
1990  CodePageEntry = IntGetCodePageEntry(CodePage);
1991  if (CodePageEntry == NULL)
1992  {
1993  DPRINT1("Could not get CodePage Entry! CodePageEntry = NULL\n");
1995  return FALSE;
1996  }
1997 
1998  lpCPInfoEx->CodePage = CodePageEntry->CodePageTable.CodePage;
1999  lpCPInfoEx->UnicodeDefaultChar = CodePageEntry->CodePageTable.UniDefaultChar;
2000  return GetLocalisedText(lpCPInfoEx->CodePage,
2001  lpCPInfoEx->CodePageName,
2002  ARRAYSIZE(lpCPInfoEx->CodePageName)) != 0;
2003  }
2004  break;
2005  }
2006 }
2007 
2008 
2009 /*
2010  * @implemented
2011  */
2012 BOOL
2013 WINAPI
2015  DWORD dwFlags,
2016  LPCPINFOEXA lpCPInfoEx)
2017 {
2018  CPINFOEXW CPInfo;
2019 
2020  if (!GetCPInfoExW(CodePage, dwFlags, &CPInfo))
2021  return FALSE;
2022 
2023  /* the layout is the same except for CodePageName */
2024  memcpy(lpCPInfoEx, &CPInfo, sizeof(CPINFOEXA));
2025 
2027  0,
2028  CPInfo.CodePageName,
2029  -1,
2030  lpCPInfoEx->CodePageName,
2031  sizeof(lpCPInfoEx->CodePageName),
2032  NULL,
2033  NULL);
2034  return TRUE;
2035 }
2036 
2076 INT
2077 WINAPI
2079  DWORD Flags,
2080  LPCWSTR WideCharString,
2081  INT WideCharCount,
2083  INT MultiByteCount,
2084  LPCSTR DefaultChar,
2085  LPBOOL UsedDefaultChar)
2086 {
2087  /* Check the parameters. */
2088  if (WideCharString == NULL ||
2089  WideCharCount == 0 ||
2090  (MultiByteString == NULL && MultiByteCount > 0) ||
2091  (PVOID)WideCharString == (PVOID)MultiByteString ||
2092  MultiByteCount < 0)
2093  {
2095  return 0;
2096  }
2097 
2098  /* Determine the input string length. */
2099  if (WideCharCount < 0)
2100  {
2101  WideCharCount = lstrlenW(WideCharString) + 1;
2102  }
2103 
2104  switch (CodePage)
2105  {
2106  case CP_UTF8:
2107  if (DefaultChar != NULL || UsedDefaultChar != NULL)
2108  {
2110  return 0;
2111  }
2112  return IntWideCharToMultiByteUTF8(CodePage,
2113  Flags,
2114  WideCharString,
2115  WideCharCount,
2117  MultiByteCount,
2118  DefaultChar,
2119  UsedDefaultChar);
2120 
2121  case CP_UTF7:
2122  if (DefaultChar != NULL || UsedDefaultChar != NULL)
2123  {
2125  return 0;
2126  }
2127  if (Flags)
2128  {
2130  return 0;
2131  }
2132  return WideCharToUtf7(WideCharString, WideCharCount,
2133  MultiByteString, MultiByteCount);
2134 
2135  case CP_SYMBOL:
2136  if ((DefaultChar!=NULL) || (UsedDefaultChar!=NULL))
2137  {
2139  return 0;
2140  }
2142  WideCharString,
2143  WideCharCount,
2145  MultiByteCount);
2146 
2147  default:
2148  return IntWideCharToMultiByteCP(CodePage,
2149  Flags,
2150  WideCharString,
2151  WideCharCount,
2153  MultiByteCount,
2154  DefaultChar,
2155  UsedDefaultChar);
2156  }
2157 }
2158 
2167 UINT
2168 WINAPI
2170 {
2172 }
2173 
2182 UINT
2183 WINAPI
2185 {
2187 }
2188 
2197 BOOL
2198 WINAPI
2199 IsDBCSLeadByteEx(UINT CodePage, BYTE TestByte)
2200 {
2201  PCODEPAGE_ENTRY CodePageEntry;
2202 
2203  CodePageEntry = IntGetCodePageEntry(CodePage);
2204  if (CodePageEntry != NULL)
2205  return IntIsLeadByte(&CodePageEntry->CodePageTable, TestByte);
2206 
2208  return FALSE;
2209 }
2210 
2219 BOOL
2220 WINAPI
2222 {
2223  return IntIsLeadByte(&AnsiCodePage.CodePageTable, TestByte);
2224 }
2225 
2226 /*
2227  * @unimplemented
2228  */
2230 {
2231  STUB;
2232  return 0;
2233 }
2234 
2235 /*
2236  * @unimplemented
2237  */
2239 {
2240  STUB;
2241  return 0;
2242 }
2243 
2244 /*
2245  * @unimplemented
2246  */
2248 {
2249  STUB;
2250 }
2251 
2252 /*
2253  * @unimplemented
2254  */
2256 {
2257  STUB;
2258  return 0;
2259 }
2260 
2261 /*
2262  * @unimplemented
2263  */
2264 BOOL
2265 WINAPI
2266 ValidateLCType(int a1, unsigned int a2, int a3, int a4)
2267 {
2268  STUB;
2269  return FALSE;
2270 }
2271 
2272 /*
2273  * @unimplemented
2274  */
2275 BOOL
2276 WINAPI
2278 {
2279  STUB;
2280  return TRUE;
2281 }
2282 
2283 /*
2284  * @unimplemented
2285  */
2286 VOID
2287 WINAPI
2289 {
2290  STUB;
2291  lpUnknown = NULL;
2292 }
2293 
2294 /*
2295  * @unimplemented
2296  */
2297 VOID
2298 WINAPI
2300 {
2301  STUB;
2302  lpUnknown = NULL;
2303 }
2304 
2305 /*
2306  * @unimplemented
2307  */
2308 BOOL
2309 WINAPI
2311 {
2312  STUB;
2313  return TRUE;
2314 }
2315 
2316 /*
2317  * @unimplemented
2318  */
2319 ULONG
2320 WINAPI
2322 {
2323  STUB;
2324  return 0;
2325 }
2326 
2327 /*
2328  * @unimplemented
2329  */
2330 BOOL
2331 WINAPI
2333  IN DWORD dwFlags,
2334  IN LPNLSVERSIONINFO lpVersionInformation,
2335  IN LPCWSTR lpString,
2336  IN INT cchStr)
2337 {
2338  STUB;
2339  return TRUE;
2340 }
2341 
2342 /*
2343  * @unimplemented
2344  */
2345 BOOL
2346 WINAPI
2348  IN LCID Locale,
2349  IN OUT LPNLSVERSIONINFO lpVersionInformation)
2350 {
2351  STUB;
2352  return TRUE;
2353 }
2354 
2355 /*
2356  * @unimplemented
2357  */
2358 BOOL
2359 WINAPI
2361  IN LPCWSTR lpLocaleName,
2362  IN OUT LPNLSVERSIONINFOEX lpVersionInformation)
2363 {
2364  STUB;
2365  return TRUE;
2366 }
2367 
2368 /* 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:365
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:4711
BOOL WINAPI IsValidUILanguage(LANGID langid)
Definition: nls.c:2238
#define IN
Definition: typedefs.h:38
BOOL WINAPI GetCPInfo(UINT CodePage, LPCPINFO CodePageInfo)
Definition: nls.c:1904
#define LOCALE_IDEFAULTANSICODEPAGE
Definition: winnls.h:38
static CODEPAGE_ENTRY AnsiCodePage
Definition: nls.c:46
static INT Utf7ToWideChar(const char *src, int srclen, WCHAR *dst, int dstlen)
Definition: nls.c:1493
#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:1717
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
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
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:775
_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
static LIST_ENTRY CodePageListHead
Definition: nls.c:45
static const char UTF8Length[128]
Definition: nls.c:25
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:2310
#define CP_ACP
Definition: compat.h:99
BOOL WINAPI ValidateLCType(int a1, unsigned int a2, int a3, int a4)
Definition: nls.c:2266
char CHAR
Definition: xmlstorage.h:175
VOID WINAPI GetLinguistLangSize(LPVOID lpUnknown)
Definition: nls.c:2299
BOOL WINAPI IsNLSDefinedString(IN NLS_FUNCTION Function, IN DWORD dwFlags, IN LPNLSVERSIONINFO lpVersionInformation, IN LPCWSTR lpString, IN INT cchStr)
Definition: nls.c:2332
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:2360
static const unsigned long UTF8LBound[]
Definition: nls.c:41
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:2078
DWORD LCID
Definition: nls.h:13
WORD LANGID
Definition: typedefs.h:79
LCID WINAPI GetUserDefaultLCID(void)
Definition: lang.c:768
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:160
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:837
#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:1098
static INT WINAPI IntMultiByteToWideCharSYMBOL(DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:720
BOOL WINAPI NlsResetProcessLocale(VOID)
Definition: nls.c:2277
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
HANDLE FileHandle
Definition: stats.c:38
BOOL WINAPI IsDBCSLeadByteEx(UINT CodePage, BYTE TestByte)
Definition: nls.c:2199
_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:1702
VOID WINAPI GetDefaultSortkeySize(LPVOID lpUnknown)
Definition: nls.c:2288
#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:1502
unsigned int BOOL
Definition: ntddk_ex.h:94
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:966
smooth NULL
Definition: ftsmooth.c:416
unsigned char
Definition: typeof.h:29
_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:2221
UINT WINAPI GetACP(VOID)
Definition: nls.c:2169
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:2321
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:2247
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)
static INT WINAPI IntMultiByteToWideCharCP(UINT CodePage, DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:521
#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:2229
__wchar_t WCHAR
Definition: xmlstorage.h:180
LIST_ENTRY Entry
Definition: kernel32.h:64
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
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:2347
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
PCODEPAGE_ENTRY FASTCALL IntGetCodePageEntry(UINT CodePage)
Definition: nls.c:196
#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:1300
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: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:47
static BOOL IntIsValidDBCSMapping(PCPTABLEINFO CodePageTable, DWORD Flags, WCHAR wch, USHORT ch)
Definition: nls.c:989
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:1023
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:48
#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:1392
INT WINAPI MultiByteToWideChar(UINT CodePage, DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:1628
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:1347
UINT GetLocalisedText(IN UINT uID, IN LPWSTR lpszDest, IN UINT cchDest)
Definition: nls.c:1817
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:773
BOOL WINAPI IsValidCodePage(UINT CodePage)
Definition: nls.c:1468
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:2014
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
unsigned int UINT
Definition: ndis.h:50
#define PAGE_READONLY
Definition: compat.h:127
static const unsigned char UTF8Mask[6]
Definition: nls.c:38
#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:1958
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:1478
static BOOL utf7_can_directly_encode(WCHAR codepoint)
Definition: nls.c:1685
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:126
#define UnmapViewOfFile
Definition: compat.h:403
#define CHAR(Char)
BOOL FASTCALL NlsInit(VOID)
Definition: nls.c:69
BYTE * PBYTE
Definition: pedump.c:66
UINT WINAPI SetCPGlobal(UINT CodePage)
Definition: nls.c:2255
#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:1449
#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:2184
#define REG_SZ
Definition: layer.c:22