ReactOS  0.4.14-dev-608-gd495a4f
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  0, 0, 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, 0, 0, 0, 0, 0, 0, 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 < 0x80)
393  {
394  TrailLength = 0;
395  continue;
396  }
397  if ((Char & 0xC0) == 0x80)
398  {
399  TrailLength = 0;
400  StringIsValid = FALSE;
401  continue;
402  }
403 
404  TrailLength = UTF8Length[Char - 0x80];
405  if (TrailLength == 0)
406  {
407  StringIsValid = FALSE;
408  continue;
409  }
410 
411  CharIsValid = TRUE;
412  MbsPtrSave = MultiByteString;
413  WideChar = Char & UTF8Mask[TrailLength];
414 
415  while (TrailLength && MultiByteString < MbsEnd)
416  {
417  if ((*MultiByteString & 0xC0) != 0x80)
418  {
419  CharIsValid = StringIsValid = FALSE;
420  break;
421  }
422 
423  WideChar = (WideChar << 6) | (*MultiByteString++ & 0x7f);
424  TrailLength--;
425  }
426 
427  if (!CharIsValid || WideChar < UTF8LBound[UTF8Length[Char - 0x80]])
428  {
429  MultiByteString = MbsPtrSave;
430  }
431  }
432 
433  if (TrailLength)
434  {
435  WideCharCount++;
436  StringIsValid = FALSE;
437  }
438 
439  if (Flags == MB_ERR_INVALID_CHARS && !StringIsValid)
440  {
442  return 0;
443  }
444 
445  return WideCharCount;
446  }
447 
448  /* convert */
449  MbsEnd = MultiByteString + MultiByteCount;
450  for (Count = 0; Count < WideCharCount && MultiByteString < MbsEnd; Count++)
451  {
452  Char = *MultiByteString++;
453  if (Char < 0x80)
454  {
455  *WideCharString++ = Char;
456  TrailLength = 0;
457  continue;
458  }
459  if ((Char & 0xC0) == 0x80)
460  {
461  *WideCharString++ = InvalidChar;
462  TrailLength = 0;
463  StringIsValid = FALSE;
464  continue;
465  }
466 
467  TrailLength = UTF8Length[Char - 0x80];
468  if (TrailLength == 0)
469  {
470  *WideCharString++ = InvalidChar;
471  StringIsValid = FALSE;
472  continue;
473  }
474 
475  CharIsValid = TRUE;
476  MbsPtrSave = MultiByteString;
477  WideChar = Char & UTF8Mask[TrailLength];
478 
479  while (TrailLength && MultiByteString < MbsEnd)
480  {
481  if ((*MultiByteString & 0xC0) != 0x80)
482  {
483  CharIsValid = StringIsValid = FALSE;
484  break;
485  }
486 
487  WideChar = (WideChar << 6) | (*MultiByteString++ & 0x7f);
488  TrailLength--;
489  }
490 
491  if (CharIsValid && UTF8LBound[UTF8Length[Char - 0x80]] <= WideChar)
492  {
493  *WideCharString++ = WideChar;
494  }
495  else
496  {
497  *WideCharString++ = InvalidChar;
498  MultiByteString = MbsPtrSave;
499  StringIsValid = FALSE;
500  }
501  }
502 
503  if (TrailLength && Count < WideCharCount && MultiByteString < MbsEnd)
504  {
505  *WideCharString = InvalidChar;
506  WideCharCount++;
507  }
508 
509  if (MultiByteString < MbsEnd)
510  {
512  return 0;
513  }
514 
515  if (Flags == MB_ERR_INVALID_CHARS && (!StringIsValid || TrailLength))
516  {
518  return 0;
519  }
520 
521  return Count;
522 }
523 
534 static
535 INT
536 WINAPI
538  DWORD Flags,
540  INT MultiByteCount,
541  LPWSTR WideCharString,
542  INT WideCharCount)
543 {
544  PCODEPAGE_ENTRY CodePageEntry;
546  PUSHORT MultiByteTable;
547  LPCSTR TempString;
548  INT TempLength;
549  USHORT WideChar;
550 
551  /* Get code page table. */
552  CodePageEntry = IntGetCodePageEntry(CodePage);
553  if (CodePageEntry == NULL)
554  {
556  return 0;
557  }
558 
559  CodePageTable = &CodePageEntry->CodePageTable;
560 
561  /* If MB_USEGLYPHCHARS flag present and glyph table present */
563  {
564  /* Use glyph table */
565  MultiByteTable = CodePageTable->MultiByteTable + 256 + 1;
566  }
567  else
568  {
569  MultiByteTable = CodePageTable->MultiByteTable;
570  }
571 
572  /* Different handling for DBCS code pages. */
574  {
575  UCHAR Char;
576  USHORT DBCSOffset;
577  LPCSTR MbsEnd = MultiByteString + MultiByteCount;
578  INT Count;
579 
581  {
582  TempString = MultiByteString;
583 
584  while (TempString < MbsEnd)
585  {
586  DBCSOffset = CodePageTable->DBCSOffsets[(UCHAR)*TempString];
587 
588  if (DBCSOffset)
589  {
590  /* If lead byte is presented, but behind it there is no symbol */
591  if (((TempString + 1) == MbsEnd) || (*(TempString + 1) == 0))
592  {
594  return 0;
595  }
596 
597  WideChar = CodePageTable->DBCSOffsets[DBCSOffset + *(TempString + 1)];
598 
599  if (WideChar == CodePageTable->UniDefaultChar &&
600  MAKEWORD(*(TempString + 1), *TempString) != CodePageTable->TransUniDefaultChar)
601  {
603  return 0;
604  }
605 
606  TempString++;
607  }
608  else
609  {
610  WideChar = MultiByteTable[(UCHAR)*TempString];
611 
612  if ((WideChar == CodePageTable->UniDefaultChar &&
613  *TempString != CodePageTable->TransUniDefaultChar) ||
614  /* "Private Use" characters */
615  (WideChar >= 0xE000 && WideChar <= 0xF8FF))
616  {
618  return 0;
619  }
620  }
621 
622  TempString++;
623  }
624  }
625 
626  /* Does caller query for output buffer size? */
627  if (WideCharCount == 0)
628  {
629  for (; MultiByteString < MbsEnd; WideCharCount++)
630  {
631  Char = *MultiByteString++;
632 
633  DBCSOffset = CodePageTable->DBCSOffsets[Char];
634 
635  if (!DBCSOffset)
636  continue;
637 
638  if (MultiByteString < MbsEnd)
639  MultiByteString++;
640  }
641 
642  return WideCharCount;
643  }
644 
645  for (Count = 0; Count < WideCharCount && MultiByteString < MbsEnd; Count++)
646  {
647  Char = *MultiByteString++;
648 
649  DBCSOffset = CodePageTable->DBCSOffsets[Char];
650 
651  if (!DBCSOffset)
652  {
653  *WideCharString++ = MultiByteTable[Char];
654  continue;
655  }
656 
657  if (MultiByteString == MbsEnd || *MultiByteString == 0)
658  {
659  *WideCharString++ = CodePageTable->UniDefaultChar;
660  }
661  else
662  {
663  *WideCharString++ = CodePageTable->DBCSOffsets[DBCSOffset + (UCHAR)*MultiByteString++];
664  }
665  }
666 
667  if (MultiByteString < MbsEnd)
668  {
670  return 0;
671  }
672 
673  return Count;
674  }
675  else /* SBCS code page */
676  {
677  /* Check for invalid characters. */
679  {
680  for (TempString = MultiByteString, TempLength = MultiByteCount;
681  TempLength > 0;
682  TempString++, TempLength--)
683  {
684  WideChar = MultiByteTable[(UCHAR)*TempString];
685 
686  if ((WideChar == CodePageTable->UniDefaultChar &&
687  *TempString != CodePageTable->TransUniDefaultChar) ||
688  /* "Private Use" characters */
689  (WideChar >= 0xE000 && WideChar <= 0xF8FF))
690  {
692  return 0;
693  }
694  }
695  }
696 
697  /* Does caller query for output buffer size? */
698  if (WideCharCount == 0)
699  return MultiByteCount;
700 
701  /* Fill the WideCharString buffer with what will fit: Verified on WinXP */
702  for (TempLength = (WideCharCount < MultiByteCount) ? WideCharCount : MultiByteCount;
703  TempLength > 0;
704  MultiByteString++, TempLength--)
705  {
706  *WideCharString++ = MultiByteTable[(UCHAR)*MultiByteString];
707  }
708 
709  /* Adjust buffer size. Wine trick ;-) */
710  if (WideCharCount < MultiByteCount)
711  {
712  MultiByteCount = WideCharCount;
714  return 0;
715  }
716  return MultiByteCount;
717  }
718 }
719 
728 static
729 INT
730 WINAPI
733  INT MultiByteCount,
734  LPWSTR WideCharString,
735  INT WideCharCount)
736 {
737  LONG Count;
738  UCHAR Char;
739  INT WideCharMaxLen;
740 
741 
742  if (Flags != 0)
743  {
745  return 0;
746  }
747 
748  if (WideCharCount == 0)
749  {
750  return MultiByteCount;
751  }
752 
753  WideCharMaxLen = WideCharCount > MultiByteCount ? MultiByteCount : WideCharCount;
754 
755  for (Count = 0; Count < WideCharMaxLen; Count++)
756  {
757  Char = MultiByteString[Count];
758  if ( Char < 0x20 )
759  {
760  WideCharString[Count] = Char;
761  }
762  else
763  {
764  WideCharString[Count] = Char + 0xf000;
765  }
766  }
767  if (MultiByteCount > WideCharMaxLen)
768  {
770  return 0;
771  }
772 
773  return WideCharMaxLen;
774 }
775 
784 static INT
785 WINAPI
787  LPCWSTR WideCharString,
788  INT WideCharCount,
790  INT MultiByteCount)
791 {
792  LONG Count;
793  INT MaxLen;
794  WCHAR Char;
795 
796  if (Flags!=0)
797  {
799  return 0;
800  }
801 
802 
803  if (MultiByteCount == 0)
804  {
805  return WideCharCount;
806  }
807 
808  MaxLen = MultiByteCount > WideCharCount ? WideCharCount : MultiByteCount;
809  for (Count = 0; Count < MaxLen; Count++)
810  {
811  Char = WideCharString[Count];
812  if (Char < 0x20)
813  {
814  MultiByteString[Count] = (CHAR)Char;
815  }
816  else
817  {
818  if ((Char >= 0xf020) && (Char < 0xf100))
819  {
820  MultiByteString[Count] = Char - 0xf000;
821  }
822  else
823  {
825  return 0;
826  }
827  }
828  }
829 
830  if (WideCharCount > MaxLen)
831  {
833  return 0;
834  }
835  return MaxLen;
836 }
837 
846 static INT
847 WINAPI
849  DWORD Flags,
850  LPCWSTR WideCharString,
851  INT WideCharCount,
853  INT MultiByteCount,
854  LPCSTR DefaultChar,
855  LPBOOL UsedDefaultChar)
856 {
857  INT TempLength;
858  DWORD Char;
859 
860  if (Flags)
861  {
863  return 0;
864  }
865 
866  /* Does caller query for output buffer size? */
867  if (MultiByteCount == 0)
868  {
869  for (TempLength = 0; WideCharCount;
870  WideCharCount--, WideCharString++)
871  {
872  TempLength++;
873  if (*WideCharString >= 0x80)
874  {
875  TempLength++;
876  if (*WideCharString >= 0x800)
877  {
878  TempLength++;
879  if (*WideCharString >= 0xd800 && *WideCharString < 0xdc00 &&
880  WideCharCount >= 1 &&
881  WideCharString[1] >= 0xdc00 && WideCharString[1] <= 0xe000)
882  {
883  WideCharCount--;
884  WideCharString++;
885  TempLength++;
886  }
887  }
888  }
889  }
890  return TempLength;
891  }
892 
893  for (TempLength = MultiByteCount; WideCharCount; WideCharCount--, WideCharString++)
894  {
895  Char = *WideCharString;
896  if (Char < 0x80)
897  {
898  if (!TempLength)
899  {
901  break;
902  }
903  TempLength--;
904  *MultiByteString++ = (CHAR)Char;
905  continue;
906  }
907 
908  if (Char < 0x800) /* 0x80-0x7ff: 2 bytes */
909  {
910  if (TempLength < 2)
911  {
913  break;
914  }
915  MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
916  MultiByteString[0] = 0xc0 | Char;
917  MultiByteString += 2;
918  TempLength -= 2;
919  continue;
920  }
921 
922  /* surrogate pair 0x10000-0x10ffff: 4 bytes */
923  if (Char >= 0xd800 && Char < 0xdc00 &&
924  WideCharCount >= 1 &&
925  WideCharString[1] >= 0xdc00 && WideCharString[1] < 0xe000)
926  {
927  WideCharCount--;
928  WideCharString++;
929 
930  if (TempLength < 4)
931  {
933  break;
934  }
935 
936  Char = (Char - 0xd800) << 10;
937  Char |= *WideCharString - 0xdc00;
938  ASSERT(Char <= 0xfffff);
939  Char += 0x10000;
940  ASSERT(Char <= 0x10ffff);
941 
942  MultiByteString[3] = 0x80 | (Char & 0x3f); Char >>= 6;
943  MultiByteString[2] = 0x80 | (Char & 0x3f); Char >>= 6;
944  MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
945  MultiByteString[0] = 0xf0 | Char;
946  MultiByteString += 4;
947  TempLength -= 4;
948  continue;
949  }
950 
951  /* 0x800-0xffff: 3 bytes */
952  if (TempLength < 3)
953  {
955  break;
956  }
957  MultiByteString[2] = 0x80 | (Char & 0x3f); Char >>= 6;
958  MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
959  MultiByteString[0] = 0xe0 | Char;
960  MultiByteString += 3;
961  TempLength -= 3;
962  }
963 
964  return MultiByteCount - TempLength;
965 }
966 
974 static
975 inline
976 BOOL
978 {
979  /* If the WC_NO_BEST_FIT_CHARS flag has been specified, the characters need to match exactly. */
981  return (CodePageTable->MultiByteTable[ch] == wch);
982 
983  /* By default, all characters except TransDefaultChar apply as a valid mapping
984  for ch (so also "nearest" characters) */
985  if (ch != CodePageTable->TransDefaultChar)
986  return TRUE;
987 
988  /* The only possible left valid mapping is the default character itself */
989  return (wch == CodePageTable->TransUniDefaultChar);
990 }
991 
999 static inline BOOL
1001 {
1002  /* If ch is the default character, but the wch is not, it can't be a valid mapping */
1004  return FALSE;
1005 
1006  /* If the WC_NO_BEST_FIT_CHARS flag has been specified, the characters need to match exactly. */
1008  {
1009  if(ch & 0xff00)
1010  {
1011  USHORT uOffset = CodePageTable->DBCSOffsets[ch >> 8];
1012  /* if (!uOffset) return (CodePageTable->MultiByteTable[ch] == wch); */
1013  return (CodePageTable->DBCSOffsets[uOffset + (ch & 0xff)] == wch);
1014  }
1015 
1016  return (CodePageTable->MultiByteTable[ch] == wch);
1017  }
1018 
1019  /* If we're still here, we have a valid mapping */
1020  return TRUE;
1021 }
1022 
1031 static
1032 INT
1033 WINAPI
1035  DWORD Flags,
1036  LPCWSTR WideCharString,
1037  INT WideCharCount,
1039  INT MultiByteCount,
1040  LPCSTR DefaultChar,
1041  LPBOOL UsedDefaultChar)
1042 {
1043  PCODEPAGE_ENTRY CodePageEntry;
1045  INT TempLength;
1046 
1047  /* Get code page table. */
1048  CodePageEntry = IntGetCodePageEntry(CodePage);
1049  if (CodePageEntry == NULL)
1050  {
1052  return 0;
1053  }
1054 
1055  CodePageTable = &CodePageEntry->CodePageTable;
1056 
1057 
1058  /* Different handling for DBCS code pages. */
1060  {
1061  /* If Flags, DefaultChar or UsedDefaultChar were given, we have to do some more work */
1062  if (Flags || DefaultChar || UsedDefaultChar)
1063  {
1064  BOOL TempUsedDefaultChar;
1065  USHORT DefChar;
1066 
1067  /* If UsedDefaultChar is not set, set it to a temporary value, so we don't have
1068  to check on every character */
1069  if (!UsedDefaultChar)
1070  UsedDefaultChar = &TempUsedDefaultChar;
1071 
1072  *UsedDefaultChar = FALSE;
1073 
1074  /* Use the CodePage's TransDefaultChar if none was given. Don't modify the DefaultChar pointer here. */
1075  if (DefaultChar)
1076  DefChar = DefaultChar[1] ? ((DefaultChar[0] << 8) | DefaultChar[1]) : DefaultChar[0];
1077  else
1078  DefChar = CodePageTable->TransDefaultChar;
1079 
1080  /* Does caller query for output buffer size? */
1081  if (!MultiByteCount)
1082  {
1083  for (TempLength = 0; WideCharCount; WideCharCount--, WideCharString++, TempLength++)
1084  {
1085  USHORT uChar;
1086 
1087  if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1088  {
1089  /* FIXME: Handle WC_COMPOSITECHECK */
1090  DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1091  }
1092 
1093  uChar = ((PUSHORT) CodePageTable->WideCharTable)[*WideCharString];
1094 
1095  /* Verify if the mapping is valid for handling DefaultChar and UsedDefaultChar */
1096  if (!IntIsValidDBCSMapping(CodePageTable, Flags, *WideCharString, uChar))
1097  {
1098  uChar = DefChar;
1099  *UsedDefaultChar = TRUE;
1100  }
1101 
1102  /* Increment TempLength again if this is a double-byte character */
1103  if (uChar & 0xff00)
1104  TempLength++;
1105  }
1106 
1107  return TempLength;
1108  }
1109 
1110  /* Convert the WideCharString to the MultiByteString and verify if the mapping is valid */
1111  for (TempLength = MultiByteCount;
1112  WideCharCount && TempLength;
1113  TempLength--, WideCharString++, WideCharCount--)
1114  {
1115  USHORT uChar;
1116 
1117  if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1118  {
1119  /* FIXME: Handle WC_COMPOSITECHECK */
1120  DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1121  }
1122 
1123  uChar = ((PUSHORT)CodePageTable->WideCharTable)[*WideCharString];
1124 
1125  /* Verify if the mapping is valid for handling DefaultChar and UsedDefaultChar */
1126  if (!IntIsValidDBCSMapping(CodePageTable, Flags, *WideCharString, uChar))
1127  {
1128  uChar = DefChar;
1129  *UsedDefaultChar = TRUE;
1130  }
1131 
1132  /* Handle double-byte characters */
1133  if (uChar & 0xff00)
1134  {
1135  /* Don't output a partial character */
1136  if (TempLength == 1)
1137  break;
1138 
1139  TempLength--;
1140  *MultiByteString++ = uChar >> 8;
1141  }
1142 
1143  *MultiByteString++ = (char)uChar;
1144  }
1145 
1146  /* WideCharCount should be 0 if all characters were converted */
1147  if (WideCharCount)
1148  {
1150  return 0;
1151  }
1152 
1153  return MultiByteCount - TempLength;
1154  }
1155 
1156  /* Does caller query for output buffer size? */
1157  if (!MultiByteCount)
1158  {
1159  for (TempLength = 0; WideCharCount; WideCharCount--, WideCharString++, TempLength++)
1160  {
1161  /* Increment TempLength again if this is a double-byte character */
1162  if (((PWCHAR)CodePageTable->WideCharTable)[*WideCharString] & 0xff00)
1163  TempLength++;
1164  }
1165 
1166  return TempLength;
1167  }
1168 
1169  /* Convert the WideCharString to the MultiByteString */
1170  for (TempLength = MultiByteCount;
1171  WideCharCount && TempLength;
1172  TempLength--, WideCharString++, WideCharCount--)
1173  {
1174  USHORT uChar = ((PUSHORT) CodePageTable->WideCharTable)[*WideCharString];
1175 
1176  /* Is this a double-byte character? */
1177  if (uChar & 0xff00)
1178  {
1179  /* Don't output a partial character */
1180  if (TempLength == 1)
1181  break;
1182 
1183  TempLength--;
1184  *MultiByteString++ = uChar >> 8;
1185  }
1186 
1187  *MultiByteString++ = (char)uChar;
1188  }
1189 
1190  /* WideCharCount should be 0 if all characters were converted */
1191  if (WideCharCount)
1192  {
1194  return 0;
1195  }
1196 
1197  return MultiByteCount - TempLength;
1198  }
1199  else /* SBCS code page */
1200  {
1201  INT nReturn;
1202 
1203  /* If Flags, DefaultChar or UsedDefaultChar were given, we have to do some more work */
1204  if (Flags || DefaultChar || UsedDefaultChar)
1205  {
1206  BOOL TempUsedDefaultChar;
1207  CHAR DefChar;
1208 
1209  /* If UsedDefaultChar is not set, set it to a temporary value, so we don't have
1210  to check on every character */
1211  if (!UsedDefaultChar)
1212  UsedDefaultChar = &TempUsedDefaultChar;
1213 
1214  *UsedDefaultChar = FALSE;
1215 
1216  /* Does caller query for output buffer size? */
1217  if (!MultiByteCount)
1218  {
1219  /* Loop through the whole WideCharString and check if we can get a valid mapping for each character */
1220  for (TempLength = 0; WideCharCount; TempLength++, WideCharString++, WideCharCount--)
1221  {
1222  if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1223  {
1224  /* FIXME: Handle WC_COMPOSITECHECK */
1225  DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1226  }
1227 
1228  if (!*UsedDefaultChar)
1229  *UsedDefaultChar = !IntIsValidSBCSMapping(CodePageTable,
1230  Flags,
1231  *WideCharString,
1232  ((PCHAR)CodePageTable->WideCharTable)[*WideCharString]);
1233  }
1234 
1235  return TempLength;
1236  }
1237 
1238  /* Use the CodePage's TransDefaultChar if none was given. Don't modify the DefaultChar pointer here. */
1239  if (DefaultChar)
1240  DefChar = *DefaultChar;
1241  else
1242  DefChar = (CHAR)CodePageTable->TransDefaultChar;
1243 
1244  /* Convert the WideCharString to the MultiByteString and verify if the mapping is valid */
1245  for (TempLength = MultiByteCount;
1246  WideCharCount && TempLength;
1247  MultiByteString++, TempLength--, WideCharString++, WideCharCount--)
1248  {
1249  if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1250  {
1251  /* FIXME: Handle WC_COMPOSITECHECK */
1252  DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1253  }
1254 
1255  *MultiByteString = ((PCHAR)CodePageTable->WideCharTable)[*WideCharString];
1256 
1257  if (!IntIsValidSBCSMapping(CodePageTable, Flags, *WideCharString, *MultiByteString))
1258  {
1259  *MultiByteString = DefChar;
1260  *UsedDefaultChar = TRUE;
1261  }
1262  }
1263 
1264  /* WideCharCount should be 0 if all characters were converted */
1265  if (WideCharCount)
1266  {
1268  return 0;
1269  }
1270 
1271  return MultiByteCount - TempLength;
1272  }
1273 
1274  /* Does caller query for output buffer size? */
1275  if (!MultiByteCount)
1276  return WideCharCount;
1277 
1278  /* Is the buffer large enough? */
1279  if (MultiByteCount < WideCharCount)
1280  {
1281  /* Convert the string up to MultiByteCount and return 0 */
1282  WideCharCount = MultiByteCount;
1284  nReturn = 0;
1285  }
1286  else
1287  {
1288  /* Otherwise WideCharCount will be the number of converted characters */
1289  nReturn = WideCharCount;
1290  }
1291 
1292  /* Convert the WideCharString to the MultiByteString */
1293  for (TempLength = WideCharCount; --TempLength >= 0; WideCharString++, MultiByteString++)
1294  {
1295  *MultiByteString = ((PCHAR)CodePageTable->WideCharTable)[*WideCharString];
1296  }
1297 
1298  return nReturn;
1299  }
1300 }
1301 
1309 static BOOL
1310 WINAPI
1312 {
1313  UINT i;
1314 
1315  if (TableInfo->MaximumCharacterSize == 2)
1316  {
1317  for (i = 0; i < MAXIMUM_LEADBYTES && TableInfo->LeadByte[i]; i += 2)
1318  {
1319  if (Byte >= TableInfo->LeadByte[i] && Byte <= TableInfo->LeadByte[i+1])
1320  return TRUE;
1321  }
1322  }
1323 
1324  return FALSE;
1325 }
1326 
1327 /* PUBLIC FUNCTIONS ***********************************************************/
1328 
1356 BOOL
1357 WINAPI
1359  UINT Base,
1360  ULONG Unknown,
1361  LPSTR BaseName,
1362  LPSTR Result,
1363  ULONG ResultSize)
1364 {
1365  CHAR Integer[11];
1366 
1367  if (!NT_SUCCESS(RtlIntegerToChar(CodePage, Base, sizeof(Integer), Integer)))
1368  return FALSE;
1369 
1370  /*
1371  * If the name including the terminating NULL character doesn't
1372  * fit in the output buffer then fail.
1373  */
1374  if (strlen(Integer) + strlen(BaseName) >= ResultSize)
1375  return FALSE;
1376 
1377  lstrcpyA(Result, BaseName);
1378  lstrcatA(Result, Integer);
1379 
1380  return TRUE;
1381 }
1382 
1401 BOOL
1402 WINAPI
1404 {
1405  WCHAR ValueNameBuffer[11];
1408  NTSTATUS Status;
1409  HANDLE KeyHandle;
1411  DWORD KvpiSize;
1412  BOOL bRetValue;
1413 
1414  bRetValue = FALSE;
1415 
1416  /* Convert the codepage number to string. */
1417  ValueName.Buffer = ValueNameBuffer;
1418  ValueName.MaximumLength = sizeof(ValueNameBuffer);
1419 
1420  if (!NT_SUCCESS(RtlIntegerToUnicodeString(CodePage, 10, &ValueName)))
1421  return bRetValue;
1422 
1423  /* Open the registry key containing file name mappings. */
1424  RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System\\"
1425  L"CurrentControlSet\\Control\\Nls\\CodePage");
1427  NULL, NULL);
1429  if (!NT_SUCCESS(Status))
1430  {
1431  return bRetValue;
1432  }
1433 
1434  /* Allocate buffer that will be used to query the value data. */
1435  KvpiSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + (MAX_PATH * sizeof(WCHAR));
1436  Kvpi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, KvpiSize);
1437  if (Kvpi == NULL)
1438  {
1439  NtClose(KeyHandle);
1440  return bRetValue;
1441  }
1442 
1443  /* Query the file name for our code page. */
1445  Kvpi, KvpiSize, &KvpiSize);
1446 
1447  NtClose(KeyHandle);
1448 
1449  /* Check if we succeded and the value is non-empty string. */
1450  if (NT_SUCCESS(Status) && Kvpi->Type == REG_SZ &&
1451  Kvpi->DataLength > sizeof(WCHAR))
1452  {
1453  bRetValue = TRUE;
1454  if (FileName != NULL)
1455  {
1456  lstrcpynW(FileName, (WCHAR*)Kvpi->Data,
1457  min(Kvpi->DataLength / sizeof(WCHAR), FileNameSize));
1458  }
1459  }
1460 
1461  /* free temporary buffer */
1462  HeapFree(GetProcessHeap(),0,Kvpi);
1463  return bRetValue;
1464 }
1465 
1477 BOOL
1478 WINAPI
1480 {
1481  if (CodePage == 0) return FALSE;
1482  if (CodePage == CP_UTF8 || CodePage == CP_UTF7)
1483  return TRUE;
1484  if (IntGetLoadedCodePageEntry(CodePage))
1485  return TRUE;
1486  return GetCPFileNameFromRegistry(CodePage, NULL, 0);
1487 }
1488 
1489 static inline BOOL utf7_write_w(WCHAR *dst, int dstlen, int *index, WCHAR character)
1490 {
1491  if (dstlen > 0)
1492  {
1493  if (*index >= dstlen)
1494  return FALSE;
1495 
1496  dst[*index] = character;
1497  }
1498 
1499  (*index)++;
1500 
1501  return TRUE;
1502 }
1503 
1504 static INT Utf7ToWideChar(const char *src, int srclen, WCHAR *dst, int dstlen)
1505 {
1506  static const signed char base64_decoding_table[] =
1507  {
1508  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00-0x0F */
1509  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10-0x1F */
1510  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20-0x2F */
1511  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30-0x3F */
1512  -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40-0x4F */
1513  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50-0x5F */
1514  -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60-0x6F */
1515  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 /* 0x70-0x7F */
1516  };
1517 
1518  const char *source_end = src + srclen;
1519  int dest_index = 0;
1520 
1521  DWORD byte_pair = 0;
1522  short offset = 0;
1523 
1524  while (src < source_end)
1525  {
1526  if (*src == '+')
1527  {
1528  src++;
1529  if (src >= source_end)
1530  break;
1531 
1532  if (*src == '-')
1533  {
1534  /* just a plus sign escaped as +- */
1535  if (!utf7_write_w(dst, dstlen, &dest_index, '+'))
1536  {
1538  return 0;
1539  }
1540  src++;
1541  continue;
1542  }
1543 
1544  do
1545  {
1546  signed char sextet = *src;
1547  if (sextet == '-')
1548  {
1549  /* skip over the dash and end base64 decoding
1550  * the current, unfinished byte pair is discarded */
1551  src++;
1552  offset = 0;
1553  break;
1554  }
1555  if (sextet < 0)
1556  {
1557  /* the next character of src is < 0 and therefore not part of a base64 sequence
1558  * the current, unfinished byte pair is NOT discarded in this case
1559  * this is probably a bug in Windows */
1560  break;
1561  }
1562 
1563  sextet = base64_decoding_table[sextet];
1564  if (sextet == -1)
1565  {
1566  /* -1 means that the next character of src is not part of a base64 sequence
1567  * in other words, all sextets in this base64 sequence have been processed
1568  * the current, unfinished byte pair is discarded */
1569  offset = 0;
1570  break;
1571  }
1572 
1573  byte_pair = (byte_pair << 6) | sextet;
1574  offset += 6;
1575 
1576  if (offset >= 16)
1577  {
1578  /* this byte pair is done */
1579  if (!utf7_write_w(dst, dstlen, &dest_index, (byte_pair >> (offset - 16)) & 0xFFFF))
1580  {
1582  return 0;
1583  }
1584  offset -= 16;
1585  }
1586 
1587  src++;
1588  }
1589  while (src < source_end);
1590  }
1591  else
1592  {
1593  /* we have to convert to unsigned char in case *src < 0 */
1594  if (!utf7_write_w(dst, dstlen, &dest_index, (unsigned char)*src))
1595  {
1597  return 0;
1598  }
1599  src++;
1600  }
1601  }
1602 
1603  return dest_index;
1604 }
1605 
1637 INT
1638 WINAPI
1640  DWORD Flags,
1642  INT MultiByteCount,
1643  LPWSTR WideCharString,
1644  INT WideCharCount)
1645 {
1646  /* Check the parameters. */
1647  if (MultiByteString == NULL ||
1648  MultiByteCount == 0 || WideCharCount < 0 ||
1649  (WideCharCount && (WideCharString == NULL ||
1650  (PVOID)MultiByteString == (PVOID)WideCharString)))
1651  {
1653  return 0;
1654  }
1655 
1656  /* Determine the input string length. */
1657  if (MultiByteCount < 0)
1658  {
1659  MultiByteCount = lstrlenA(MultiByteString) + 1;
1660  }
1661 
1662  switch (CodePage)
1663  {
1664  case CP_UTF8:
1667  MultiByteCount,
1668  WideCharString,
1669  WideCharCount);
1670 
1671  case CP_UTF7:
1672  if (Flags)
1673  {
1675  return 0;
1676  }
1677  return Utf7ToWideChar(MultiByteString, MultiByteCount,
1678  WideCharString, WideCharCount);
1679 
1680  case CP_SYMBOL:
1683  MultiByteCount,
1684  WideCharString,
1685  WideCharCount);
1686  default:
1687  return IntMultiByteToWideCharCP(CodePage,
1688  Flags,
1690  MultiByteCount,
1691  WideCharString,
1692  WideCharCount);
1693  }
1694 }
1695 
1696 static inline BOOL utf7_can_directly_encode(WCHAR codepoint)
1697 {
1698  static const BOOL directly_encodable_table[] =
1699  {
1700  1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, /* 0x00 - 0x0F */
1701  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1F */
1702  1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* 0x20 - 0x2F */
1703  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x30 - 0x3F */
1704  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4F */
1705  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x50 - 0x5F */
1706  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6F */
1707  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* 0x70 - 0x7A */
1708  };
1709 
1710  return codepoint <= 0x7A ? directly_encodable_table[codepoint] : FALSE;
1711 }
1712 
1713 static inline BOOL utf7_write_c(char *dst, int dstlen, int *index, char character)
1714 {
1715  if (dstlen > 0)
1716  {
1717  if (*index >= dstlen)
1718  return FALSE;
1719 
1720  dst[*index] = character;
1721  }
1722 
1723  (*index)++;
1724 
1725  return TRUE;
1726 }
1727 
1728 static INT WideCharToUtf7(const WCHAR *src, int srclen, char *dst, int dstlen)
1729 {
1730  static const char base64_encoding_table[] =
1731  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1732 
1733  const WCHAR *source_end = src + srclen;
1734  int dest_index = 0;
1735 
1736  while (src < source_end)
1737  {
1738  if (*src == '+')
1739  {
1740  if (!utf7_write_c(dst, dstlen, &dest_index, '+'))
1741  {
1743  return 0;
1744  }
1745  if (!utf7_write_c(dst, dstlen, &dest_index, '-'))
1746  {
1748  return 0;
1749  }
1750  src++;
1751  }
1752  else if (utf7_can_directly_encode(*src))
1753  {
1754  if (!utf7_write_c(dst, dstlen, &dest_index, *src))
1755  {
1757  return 0;
1758  }
1759  src++;
1760  }
1761  else
1762  {
1763  unsigned int offset = 0;
1764  DWORD byte_pair = 0;
1765 
1766  if (!utf7_write_c(dst, dstlen, &dest_index, '+'))
1767  {
1769  return 0;
1770  }
1771 
1772  while (src < source_end && !utf7_can_directly_encode(*src))
1773  {
1774  byte_pair = (byte_pair << 16) | *src;
1775  offset += 16;
1776  while (offset >= 6)
1777  {
1778  if (!utf7_write_c(dst, dstlen, &dest_index, base64_encoding_table[(byte_pair >> (offset - 6)) & 0x3F]))
1779  {
1781  return 0;
1782  }
1783  offset -= 6;
1784  }
1785  src++;
1786  }
1787 
1788  if (offset)
1789  {
1790  /* Windows won't create a padded base64 character if there's no room for the - sign
1791  * as well ; this is probably a bug in Windows */
1792  if (dstlen > 0 && dest_index + 1 >= dstlen)
1793  {
1795  return 0;
1796  }
1797 
1798  byte_pair <<= (6 - offset);
1799  if (!utf7_write_c(dst, dstlen, &dest_index, base64_encoding_table[byte_pair & 0x3F]))
1800  {
1802  return 0;
1803  }
1804  }
1805 
1806  /* Windows always explicitly terminates the base64 sequence
1807  even though RFC 2152 (page 3, rule 2) does not require this */
1808  if (!utf7_write_c(dst, dstlen, &dest_index, '-'))
1809  {
1811  return 0;
1812  }
1813  }
1814  }
1815 
1816  return dest_index;
1817 }
1818 
1819 /*
1820  * A function similar to LoadStringW, but adapted for usage by GetCPInfoExW
1821  * and GetGeoInfoW. It uses the current user localization, otherwise falls back
1822  * to English (US). Contrary to LoadStringW which always saves the loaded string
1823  * into the user-given buffer, truncating the string if needed, this function
1824  * returns instead an ERROR_INSUFFICIENT_BUFFER error code if the user buffer
1825  * is not large enough.
1826  */
1827 UINT
1829  IN UINT uID,
1830  IN LPWSTR lpszDest,
1831  IN UINT cchDest)
1832 {
1833  HRSRC hrsrc;
1834  HGLOBAL hmem;
1835  LCID lcid;
1836  LANGID langId;
1837  const WCHAR *p;
1838  UINT i;
1839 
1840  /* See HACK in winnls/lang/xx-XX.rc files */
1841  if (uID == 37)
1842  uID = uID * 100;
1843 
1846 
1847  langId = LANGIDFROMLCID(lcid);
1848 
1849  if (PRIMARYLANGID(langId) == LANG_NEUTRAL)
1851 
1853  (LPWSTR)RT_STRING,
1854  MAKEINTRESOURCEW((uID >> 4) + 1),
1855  langId);
1856 
1857  /* English fallback */
1858  if (!hrsrc)
1859  {
1861  (LPWSTR)RT_STRING,
1862  MAKEINTRESOURCEW((uID >> 4) + 1),
1864  }
1865 
1866  if (!hrsrc)
1867  goto NotFound;
1868 
1869  hmem = LoadResource(hCurrentModule, hrsrc);
1870  if (!hmem)
1871  goto NotFound;
1872 
1873  p = LockResource(hmem);
1874 
1875  for (i = 0; i < (uID & 0x0F); i++)
1876  p += *p + 1;
1877 
1878  /* Needed for GetGeoInfo(): return the needed string size including the NULL terminator */
1879  if (cchDest == 0)
1880  return *p + 1;
1881  /* Needed for GetGeoInfo(): bail out if the user buffer is not large enough */
1882  if (*p + 1 > cchDest)
1883  {
1885  return 0;
1886  }
1887 
1888  i = *p;
1889  if (i > 0)
1890  {
1891  memcpy(lpszDest, p + 1, i * sizeof(WCHAR));
1892  lpszDest[i] = L'\0';
1893  return i;
1894  }
1895 #if 0
1896  else
1897  {
1898  if (cchDest >= 1)
1899  lpszDest[0] = L'\0';
1900  /* Fall-back */
1901  }
1902 #endif
1903 
1904 NotFound:
1905  DPRINT1("Resource not found: uID = %lu\n", uID);
1907  return 0;
1908 }
1909 
1910 /*
1911  * @implemented
1912  */
1913 BOOL
1914 WINAPI
1915 GetCPInfo(UINT CodePage,
1916  LPCPINFO CodePageInfo)
1917 {
1918  PCODEPAGE_ENTRY CodePageEntry;
1919 
1920  if (!CodePageInfo)
1921  {
1923  return FALSE;
1924  }
1925 
1926  CodePageEntry = IntGetCodePageEntry(CodePage);
1927  if (CodePageEntry == NULL)
1928  {
1929  switch(CodePage)
1930  {
1931  case CP_UTF7:
1932  case CP_UTF8:
1933  CodePageInfo->DefaultChar[0] = 0x3f;
1934  CodePageInfo->DefaultChar[1] = 0;
1935  CodePageInfo->LeadByte[0] = CodePageInfo->LeadByte[1] = 0;
1936  CodePageInfo->MaxCharSize = (CodePage == CP_UTF7) ? 5 : 4;
1937  return TRUE;
1938  }
1939 
1940  DPRINT1("Invalid CP!: %lx\n", CodePage);
1942  return FALSE;
1943  }
1944 
1945  if (CodePageEntry->CodePageTable.DefaultChar & 0xff00)
1946  {
1947  CodePageInfo->DefaultChar[0] = (CodePageEntry->CodePageTable.DefaultChar & 0xff00) >> 8;
1948  CodePageInfo->DefaultChar[1] = CodePageEntry->CodePageTable.DefaultChar & 0x00ff;
1949  }
1950  else
1951  {
1952  CodePageInfo->DefaultChar[0] = CodePageEntry->CodePageTable.DefaultChar & 0xff;
1953  CodePageInfo->DefaultChar[1] = 0;
1954  }
1955 
1956  if ((CodePageInfo->MaxCharSize = CodePageEntry->CodePageTable.MaximumCharacterSize) == 2)
1957  memcpy(CodePageInfo->LeadByte, CodePageEntry->CodePageTable.LeadByte, sizeof(CodePageInfo->LeadByte));
1958  else
1959  CodePageInfo->LeadByte[0] = CodePageInfo->LeadByte[1] = 0;
1960 
1961  return TRUE;
1962 }
1963 
1964 /*
1965  * @implemented
1966  */
1967 BOOL
1968 WINAPI
1970  DWORD dwFlags,
1971  LPCPINFOEXW lpCPInfoEx)
1972 {
1973  if (!GetCPInfo(CodePage, (LPCPINFO)lpCPInfoEx))
1974  return FALSE;
1975 
1976  switch(CodePage)
1977  {
1978  case CP_UTF7:
1979  {
1980  lpCPInfoEx->CodePage = CP_UTF7;
1981  lpCPInfoEx->UnicodeDefaultChar = 0x3f;
1982  return GetLocalisedText(lpCPInfoEx->CodePage,
1983  lpCPInfoEx->CodePageName,
1984  ARRAYSIZE(lpCPInfoEx->CodePageName)) != 0;
1985  }
1986  break;
1987 
1988  case CP_UTF8:
1989  {
1990  lpCPInfoEx->CodePage = CP_UTF8;
1991  lpCPInfoEx->UnicodeDefaultChar = 0x3f;
1992  return GetLocalisedText(lpCPInfoEx->CodePage,
1993  lpCPInfoEx->CodePageName,
1994  ARRAYSIZE(lpCPInfoEx->CodePageName)) != 0;
1995  }
1996 
1997  default:
1998  {
1999  PCODEPAGE_ENTRY CodePageEntry;
2000 
2001  CodePageEntry = IntGetCodePageEntry(CodePage);
2002  if (CodePageEntry == NULL)
2003  {
2004  DPRINT1("Could not get CodePage Entry! CodePageEntry = NULL\n");
2006  return FALSE;
2007  }
2008 
2009  lpCPInfoEx->CodePage = CodePageEntry->CodePageTable.CodePage;
2010  lpCPInfoEx->UnicodeDefaultChar = CodePageEntry->CodePageTable.UniDefaultChar;
2011  return GetLocalisedText(lpCPInfoEx->CodePage,
2012  lpCPInfoEx->CodePageName,
2013  ARRAYSIZE(lpCPInfoEx->CodePageName)) != 0;
2014  }
2015  break;
2016  }
2017 }
2018 
2019 
2020 /*
2021  * @implemented
2022  */
2023 BOOL
2024 WINAPI
2026  DWORD dwFlags,
2027  LPCPINFOEXA lpCPInfoEx)
2028 {
2029  CPINFOEXW CPInfo;
2030 
2031  if (!GetCPInfoExW(CodePage, dwFlags, &CPInfo))
2032  return FALSE;
2033 
2034  /* the layout is the same except for CodePageName */
2035  memcpy(lpCPInfoEx, &CPInfo, sizeof(CPINFOEXA));
2036 
2038  0,
2039  CPInfo.CodePageName,
2040  -1,
2041  lpCPInfoEx->CodePageName,
2042  sizeof(lpCPInfoEx->CodePageName),
2043  NULL,
2044  NULL);
2045  return TRUE;
2046 }
2047 
2087 INT
2088 WINAPI
2090  DWORD Flags,
2091  LPCWSTR WideCharString,
2092  INT WideCharCount,
2094  INT MultiByteCount,
2095  LPCSTR DefaultChar,
2096  LPBOOL UsedDefaultChar)
2097 {
2098  /* Check the parameters. */
2099  if (WideCharString == NULL ||
2100  WideCharCount == 0 ||
2101  (MultiByteString == NULL && MultiByteCount > 0) ||
2102  (PVOID)WideCharString == (PVOID)MultiByteString ||
2103  MultiByteCount < 0)
2104  {
2106  return 0;
2107  }
2108 
2109  /* Determine the input string length. */
2110  if (WideCharCount < 0)
2111  {
2112  WideCharCount = lstrlenW(WideCharString) + 1;
2113  }
2114 
2115  switch (CodePage)
2116  {
2117  case CP_UTF8:
2118  if (DefaultChar != NULL || UsedDefaultChar != NULL)
2119  {
2121  return 0;
2122  }
2123  return IntWideCharToMultiByteUTF8(CodePage,
2124  Flags,
2125  WideCharString,
2126  WideCharCount,
2128  MultiByteCount,
2129  DefaultChar,
2130  UsedDefaultChar);
2131 
2132  case CP_UTF7:
2133  if (DefaultChar != NULL || UsedDefaultChar != NULL)
2134  {
2136  return 0;
2137  }
2138  if (Flags)
2139  {
2141  return 0;
2142  }
2143  return WideCharToUtf7(WideCharString, WideCharCount,
2144  MultiByteString, MultiByteCount);
2145 
2146  case CP_SYMBOL:
2147  if ((DefaultChar!=NULL) || (UsedDefaultChar!=NULL))
2148  {
2150  return 0;
2151  }
2153  WideCharString,
2154  WideCharCount,
2156  MultiByteCount);
2157 
2158  default:
2159  return IntWideCharToMultiByteCP(CodePage,
2160  Flags,
2161  WideCharString,
2162  WideCharCount,
2164  MultiByteCount,
2165  DefaultChar,
2166  UsedDefaultChar);
2167  }
2168 }
2169 
2178 UINT
2179 WINAPI
2181 {
2183 }
2184 
2193 UINT
2194 WINAPI
2196 {
2198 }
2199 
2208 BOOL
2209 WINAPI
2210 IsDBCSLeadByteEx(UINT CodePage, BYTE TestByte)
2211 {
2212  PCODEPAGE_ENTRY CodePageEntry;
2213 
2214  CodePageEntry = IntGetCodePageEntry(CodePage);
2215  if (CodePageEntry != NULL)
2216  return IntIsLeadByte(&CodePageEntry->CodePageTable, TestByte);
2217 
2219  return FALSE;
2220 }
2221 
2230 BOOL
2231 WINAPI
2233 {
2234  return IntIsLeadByte(&AnsiCodePage.CodePageTable, TestByte);
2235 }
2236 
2237 /*
2238  * @unimplemented
2239  */
2241 {
2242  STUB;
2243  return 0;
2244 }
2245 
2246 /*
2247  * @unimplemented
2248  */
2250 {
2251  STUB;
2252  return 0;
2253 }
2254 
2255 /*
2256  * @unimplemented
2257  */
2259 {
2260  STUB;
2261 }
2262 
2263 /*
2264  * @unimplemented
2265  */
2267 {
2268  STUB;
2269  return 0;
2270 }
2271 
2272 /*
2273  * @unimplemented
2274  */
2275 BOOL
2276 WINAPI
2277 ValidateLCType(int a1, unsigned int a2, int a3, int a4)
2278 {
2279  STUB;
2280  return FALSE;
2281 }
2282 
2283 /*
2284  * @unimplemented
2285  */
2286 BOOL
2287 WINAPI
2289 {
2290  STUB;
2291  return TRUE;
2292 }
2293 
2294 /*
2295  * @unimplemented
2296  */
2297 VOID
2298 WINAPI
2300 {
2301  STUB;
2302  lpUnknown = NULL;
2303 }
2304 
2305 /*
2306  * @unimplemented
2307  */
2308 VOID
2309 WINAPI
2311 {
2312  STUB;
2313  lpUnknown = NULL;
2314 }
2315 
2316 /*
2317  * @unimplemented
2318  */
2319 BOOL
2320 WINAPI
2322 {
2323  STUB;
2324  return TRUE;
2325 }
2326 
2327 /*
2328  * @unimplemented
2329  */
2330 ULONG
2331 WINAPI
2333 {
2334  STUB;
2335  return 0;
2336 }
2337 
2338 /*
2339  * @unimplemented
2340  */
2341 BOOL
2342 WINAPI
2344  IN DWORD dwFlags,
2345  IN LPNLSVERSIONINFO lpVersionInformation,
2346  IN LPCWSTR lpString,
2347  IN INT cchStr)
2348 {
2349  STUB;
2350  return TRUE;
2351 }
2352 
2353 /*
2354  * @unimplemented
2355  */
2356 BOOL
2357 WINAPI
2359  IN LCID Locale,
2360  IN OUT LPNLSVERSIONINFO lpVersionInformation)
2361 {
2362  STUB;
2363  return TRUE;
2364 }
2365 
2366 /*
2367  * @unimplemented
2368  */
2369 BOOL
2370 WINAPI
2372  IN LPCWSTR lpLocaleName,
2373  IN OUT LPNLSVERSIONINFOEX lpVersionInformation)
2374 {
2375  STUB;
2376  return TRUE;
2377 }
2378 
2379 /* EOF */
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
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:2249
#define IN
Definition: typedefs.h:38
BOOL WINAPI GetCPInfo(UINT CodePage, LPCPINFO CodePageInfo)
Definition: nls.c:1915
#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:1504
#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:1728
PUSHORT DBCSOffsets
Definition: precomp.h:43
#define MapViewOfFile
Definition: compat.h:410
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:3373
#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:786
_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:2321
#define CP_ACP
Definition: compat.h:99
BOOL WINAPI ValidateLCType(int a1, unsigned int a2, int a3, int a4)
Definition: nls.c:2277
char CHAR
Definition: xmlstorage.h:175
VOID WINAPI GetLinguistLangSize(LPVOID lpUnknown)
Definition: nls.c:2310
BOOL WINAPI IsNLSDefinedString(IN NLS_FUNCTION Function, IN DWORD dwFlags, IN LPNLSVERSIONINFO lpVersionInformation, IN LPCWSTR lpString, IN INT cchStr)
Definition: nls.c:2343
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:2343
BOOL WINAPI GetNLSVersionEx(IN NLS_FUNCTION function, IN LPCWSTR lpLocaleName, IN OUT LPNLSVERSIONINFOEX lpVersionInformation)
Definition: nls.c:2371
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:399
_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:2089
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:415
#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:848
#define FILE_SHARE_READ
Definition: compat.h:125
#define SUBLANG_ENGLISH_US
Definition: nls.h:222
#define lstrcpynW
Definition: compat.h:405
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:731
BOOL WINAPI NlsResetProcessLocale(VOID)
Definition: nls.c:2288
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
HANDLE FileHandle
Definition: stats.c:38
BOOL WINAPI IsDBCSLeadByteEx(UINT CodePage, BYTE TestByte)
Definition: nls.c:2210
_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:1713
VOID WINAPI GetDefaultSortkeySize(LPVOID lpUnknown)
Definition: nls.c:2299
#define SEC_COMMIT
Definition: mmtypes.h:99
#define CP_UTF8
Definition: nls.h:20
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
NTSTATUS NTAPI NtOpenSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: section.c:3501
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:977
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:2232
UINT WINAPI GetACP(VOID)
Definition: nls.c:2180
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:435
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:434
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:2332
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:2258
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:537
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
NTSTATUS WINAPI CreateNlsSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, ULONG Size, ULONG AccessMask)
Definition: nls.c:2240
__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:2358
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:6
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:1311
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define SetLastError(x)
Definition: compat.h:417
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:1000
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:1034
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:1403
INT WINAPI MultiByteToWideChar(UINT CodePage, DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:1639
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:1358
UINT GetLocalisedText(IN UINT uID, IN LPWSTR lpszDest, IN UINT cchDest)
Definition: nls.c:1828
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:1479
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:2025
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:408
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:1969
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:4113
#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:1489
static BOOL utf7_can_directly_encode(WCHAR codepoint)
Definition: nls.c:1696
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:411
#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:2266
#define CP_OEMCP
Definition: winnls.h:228
#define HeapFree(x, y, z)
Definition: compat.h:402
#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:2195
#define REG_SZ
Definition: layer.c:22