ReactOS  0.4.15-dev-3733-g974a0f0
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 
363 static
364 INT
365 WINAPI
368  INT MultiByteCount,
369  LPWSTR WideCharString,
370  INT WideCharCount)
371 {
372  LPCSTR MbsEnd, MbsPtrSave;
373  UCHAR Char, TrailLength;
374  WCHAR WideChar;
375  LONG Count;
376  BOOL CharIsValid, StringIsValid = TRUE;
377  const WCHAR InvalidChar = 0xFFFD;
378 
379  if (Flags != 0 && Flags != MB_ERR_INVALID_CHARS)
380  {
382  return 0;
383  }
384 
385  /* Does caller query for output buffer size? */
386  if (WideCharCount == 0)
387  {
388  /* validate and count the wide characters */
389  MbsEnd = MultiByteString + MultiByteCount;
390  for (; MultiByteString < MbsEnd; WideCharCount++)
391  {
392  Char = *MultiByteString++;
393  if (Char < 0x80)
394  {
395  TrailLength = 0;
396  continue;
397  }
398  if ((Char & 0xC0) == 0x80)
399  {
400  TrailLength = 0;
401  StringIsValid = FALSE;
402  continue;
403  }
404 
405  TrailLength = UTF8Length[Char - 0x80];
406  if (TrailLength == 0)
407  {
408  StringIsValid = FALSE;
409  continue;
410  }
411 
412  CharIsValid = TRUE;
413  MbsPtrSave = MultiByteString;
414  WideChar = Char & UTF8Mask[TrailLength];
415 
416  while (TrailLength && MultiByteString < MbsEnd)
417  {
418  if ((*MultiByteString & 0xC0) != 0x80)
419  {
420  CharIsValid = StringIsValid = FALSE;
421  break;
422  }
423 
424  WideChar = (WideChar << 6) | (*MultiByteString++ & 0x7f);
425  TrailLength--;
426  }
427 
428  if (!CharIsValid || WideChar < UTF8LBound[UTF8Length[Char - 0x80]])
429  {
430  MultiByteString = MbsPtrSave;
431  }
432  }
433 
434  if (TrailLength)
435  {
436  WideCharCount++;
437  StringIsValid = FALSE;
438  }
439 
440  if (Flags == MB_ERR_INVALID_CHARS && !StringIsValid)
441  {
443  return 0;
444  }
445 
446  return WideCharCount;
447  }
448 
449  /* convert */
450  MbsEnd = MultiByteString + MultiByteCount;
451  for (Count = 0; Count < WideCharCount && MultiByteString < MbsEnd; Count++)
452  {
453  Char = *MultiByteString++;
454  if (Char < 0x80)
455  {
456  *WideCharString++ = Char;
457  TrailLength = 0;
458  continue;
459  }
460  if ((Char & 0xC0) == 0x80)
461  {
462  *WideCharString++ = InvalidChar;
463  TrailLength = 0;
464  StringIsValid = FALSE;
465  continue;
466  }
467 
468  TrailLength = UTF8Length[Char - 0x80];
469  if (TrailLength == 0)
470  {
471  *WideCharString++ = InvalidChar;
472  StringIsValid = FALSE;
473  continue;
474  }
475 
476  CharIsValid = TRUE;
477  MbsPtrSave = MultiByteString;
478  WideChar = Char & UTF8Mask[TrailLength];
479 
480  while (TrailLength && MultiByteString < MbsEnd)
481  {
482  if ((*MultiByteString & 0xC0) != 0x80)
483  {
484  CharIsValid = StringIsValid = FALSE;
485  break;
486  }
487 
488  WideChar = (WideChar << 6) | (*MultiByteString++ & 0x7f);
489  TrailLength--;
490  }
491 
492  if (CharIsValid && UTF8LBound[UTF8Length[Char - 0x80]] <= WideChar)
493  {
494  *WideCharString++ = WideChar;
495  }
496  else
497  {
498  *WideCharString++ = InvalidChar;
499  MultiByteString = MbsPtrSave;
500  StringIsValid = FALSE;
501  }
502  }
503 
504  if (TrailLength && Count < WideCharCount && MultiByteString < MbsEnd)
505  {
506  *WideCharString = InvalidChar;
507  WideCharCount++;
508  }
509 
510  if (MultiByteString < MbsEnd)
511  {
513  return 0;
514  }
515 
516  if (Flags == MB_ERR_INVALID_CHARS && (!StringIsValid || TrailLength))
517  {
519  return 0;
520  }
521 
522  return Count;
523 }
524 
535 static
536 INT
537 WINAPI
539  DWORD Flags,
541  INT MultiByteCount,
542  LPWSTR WideCharString,
543  INT WideCharCount)
544 {
545  PCODEPAGE_ENTRY CodePageEntry;
547  PUSHORT MultiByteTable;
548  LPCSTR TempString;
549  INT TempLength;
550  USHORT WideChar;
551 
552  /* Get code page table. */
553  CodePageEntry = IntGetCodePageEntry(CodePage);
554  if (CodePageEntry == NULL)
555  {
557  return 0;
558  }
559 
560  CodePageTable = &CodePageEntry->CodePageTable;
561 
562  /* If MB_USEGLYPHCHARS flag present and glyph table present */
564  {
565  /* Use glyph table */
566  MultiByteTable = CodePageTable->MultiByteTable + 256 + 1;
567  }
568  else
569  {
570  MultiByteTable = CodePageTable->MultiByteTable;
571  }
572 
573  /* Different handling for DBCS code pages. */
575  {
576  UCHAR Char;
577  USHORT DBCSOffset;
578  LPCSTR MbsEnd = MultiByteString + MultiByteCount;
579  INT Count;
580 
582  {
583  TempString = MultiByteString;
584 
585  while (TempString < MbsEnd)
586  {
587  DBCSOffset = CodePageTable->DBCSOffsets[(UCHAR)*TempString];
588 
589  if (DBCSOffset)
590  {
591  /* If lead byte is presented, but behind it there is no symbol */
592  if (((TempString + 1) == MbsEnd) || (*(TempString + 1) == 0))
593  {
595  return 0;
596  }
597 
598  WideChar = CodePageTable->DBCSOffsets[DBCSOffset + *(TempString + 1)];
599 
600  if (WideChar == CodePageTable->UniDefaultChar &&
601  MAKEWORD(*(TempString + 1), *TempString) != CodePageTable->TransUniDefaultChar)
602  {
604  return 0;
605  }
606 
607  TempString++;
608  }
609  else
610  {
611  WideChar = MultiByteTable[(UCHAR)*TempString];
612 
613  if ((WideChar == CodePageTable->UniDefaultChar &&
614  *TempString != CodePageTable->TransUniDefaultChar) ||
615  /* "Private Use" characters */
616  (WideChar >= 0xE000 && WideChar <= 0xF8FF))
617  {
619  return 0;
620  }
621  }
622 
623  TempString++;
624  }
625  }
626 
627  /* Does caller query for output buffer size? */
628  if (WideCharCount == 0)
629  {
630  for (; MultiByteString < MbsEnd; WideCharCount++)
631  {
632  Char = *MultiByteString++;
633 
634  DBCSOffset = CodePageTable->DBCSOffsets[Char];
635 
636  if (!DBCSOffset)
637  continue;
638 
639  if (MultiByteString < MbsEnd)
640  MultiByteString++;
641  }
642 
643  return WideCharCount;
644  }
645 
646  for (Count = 0; Count < WideCharCount && MultiByteString < MbsEnd; Count++)
647  {
648  Char = *MultiByteString++;
649 
650  DBCSOffset = CodePageTable->DBCSOffsets[Char];
651 
652  if (!DBCSOffset)
653  {
654  *WideCharString++ = MultiByteTable[Char];
655  continue;
656  }
657 
658  if (MultiByteString == MbsEnd || *MultiByteString == 0)
659  {
660  *WideCharString++ = CodePageTable->UniDefaultChar;
661  }
662  else
663  {
664  *WideCharString++ = CodePageTable->DBCSOffsets[DBCSOffset + (UCHAR)*MultiByteString++];
665  }
666  }
667 
668  if (MultiByteString < MbsEnd)
669  {
671  return 0;
672  }
673 
674  return Count;
675  }
676  else /* SBCS code page */
677  {
678  /* Check for invalid characters. */
680  {
681  for (TempString = MultiByteString, TempLength = MultiByteCount;
682  TempLength > 0;
683  TempString++, TempLength--)
684  {
685  WideChar = MultiByteTable[(UCHAR)*TempString];
686 
687  if ((WideChar == CodePageTable->UniDefaultChar &&
688  *TempString != CodePageTable->TransUniDefaultChar) ||
689  /* "Private Use" characters */
690  (WideChar >= 0xE000 && WideChar <= 0xF8FF))
691  {
693  return 0;
694  }
695  }
696  }
697 
698  /* Does caller query for output buffer size? */
699  if (WideCharCount == 0)
700  return MultiByteCount;
701 
702  /* Fill the WideCharString buffer with what will fit: Verified on WinXP */
703  for (TempLength = (WideCharCount < MultiByteCount) ? WideCharCount : MultiByteCount;
704  TempLength > 0;
705  MultiByteString++, TempLength--)
706  {
707  *WideCharString++ = MultiByteTable[(UCHAR)*MultiByteString];
708  }
709 
710  /* Adjust buffer size. Wine trick ;-) */
711  if (WideCharCount < MultiByteCount)
712  {
713  MultiByteCount = WideCharCount;
715  return 0;
716  }
717  return MultiByteCount;
718  }
719 }
720 
729 static
730 INT
731 WINAPI
734  INT MultiByteCount,
735  LPWSTR WideCharString,
736  INT WideCharCount)
737 {
738  LONG Count;
739  UCHAR Char;
740  INT WideCharMaxLen;
741 
742 
743  if (Flags != 0)
744  {
746  return 0;
747  }
748 
749  if (WideCharCount == 0)
750  {
751  return MultiByteCount;
752  }
753 
754  WideCharMaxLen = WideCharCount > MultiByteCount ? MultiByteCount : WideCharCount;
755 
756  for (Count = 0; Count < WideCharMaxLen; Count++)
757  {
758  Char = MultiByteString[Count];
759  if ( Char < 0x20 )
760  {
761  WideCharString[Count] = Char;
762  }
763  else
764  {
765  WideCharString[Count] = Char + 0xf000;
766  }
767  }
768  if (MultiByteCount > WideCharMaxLen)
769  {
771  return 0;
772  }
773 
774  return WideCharMaxLen;
775 }
776 
785 static INT
786 WINAPI
788  LPCWSTR WideCharString,
789  INT WideCharCount,
791  INT MultiByteCount)
792 {
793  LONG Count;
794  INT MaxLen;
795  WCHAR Char;
796 
797  if (Flags!=0)
798  {
800  return 0;
801  }
802 
803 
804  if (MultiByteCount == 0)
805  {
806  return WideCharCount;
807  }
808 
809  MaxLen = MultiByteCount > WideCharCount ? WideCharCount : MultiByteCount;
810  for (Count = 0; Count < MaxLen; Count++)
811  {
812  Char = WideCharString[Count];
813  if (Char < 0x20)
814  {
815  MultiByteString[Count] = (CHAR)Char;
816  }
817  else
818  {
819  if ((Char >= 0xf020) && (Char < 0xf100))
820  {
821  MultiByteString[Count] = Char - 0xf000;
822  }
823  else
824  {
826  return 0;
827  }
828  }
829  }
830 
831  if (WideCharCount > MaxLen)
832  {
834  return 0;
835  }
836  return MaxLen;
837 }
838 
847 static INT
848 WINAPI
850  DWORD Flags,
851  LPCWSTR WideCharString,
852  INT WideCharCount,
854  INT MultiByteCount,
855  LPCSTR DefaultChar,
856  LPBOOL UsedDefaultChar)
857 {
858  INT TempLength;
859  DWORD Char;
860 
861  if (Flags)
862  {
864  return 0;
865  }
866 
867  /* Does caller query for output buffer size? */
868  if (MultiByteCount == 0)
869  {
870  for (TempLength = 0; WideCharCount;
871  WideCharCount--, WideCharString++)
872  {
873  TempLength++;
874  if (*WideCharString >= 0x80)
875  {
876  TempLength++;
877  if (*WideCharString >= 0x800)
878  {
879  TempLength++;
880  if (*WideCharString >= 0xd800 && *WideCharString < 0xdc00 &&
881  WideCharCount >= 1 &&
882  WideCharString[1] >= 0xdc00 && WideCharString[1] <= 0xe000)
883  {
884  WideCharCount--;
885  WideCharString++;
886  TempLength++;
887  }
888  }
889  }
890  }
891  return TempLength;
892  }
893 
894  for (TempLength = MultiByteCount; WideCharCount; WideCharCount--, WideCharString++)
895  {
896  Char = *WideCharString;
897  if (Char < 0x80)
898  {
899  if (!TempLength)
900  {
902  break;
903  }
904  TempLength--;
905  *MultiByteString++ = (CHAR)Char;
906  continue;
907  }
908 
909  if (Char < 0x800) /* 0x80-0x7ff: 2 bytes */
910  {
911  if (TempLength < 2)
912  {
914  break;
915  }
916  MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
917  MultiByteString[0] = 0xc0 | Char;
918  MultiByteString += 2;
919  TempLength -= 2;
920  continue;
921  }
922 
923  /* surrogate pair 0x10000-0x10ffff: 4 bytes */
924  if (Char >= 0xd800 && Char < 0xdc00 &&
925  WideCharCount >= 1 &&
926  WideCharString[1] >= 0xdc00 && WideCharString[1] < 0xe000)
927  {
928  WideCharCount--;
929  WideCharString++;
930 
931  if (TempLength < 4)
932  {
934  break;
935  }
936 
937  Char = (Char - 0xd800) << 10;
938  Char |= *WideCharString - 0xdc00;
939  ASSERT(Char <= 0xfffff);
940  Char += 0x10000;
941  ASSERT(Char <= 0x10ffff);
942 
943  MultiByteString[3] = 0x80 | (Char & 0x3f); Char >>= 6;
944  MultiByteString[2] = 0x80 | (Char & 0x3f); Char >>= 6;
945  MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
946  MultiByteString[0] = 0xf0 | Char;
947  MultiByteString += 4;
948  TempLength -= 4;
949  continue;
950  }
951 
952  /* 0x800-0xffff: 3 bytes */
953  if (TempLength < 3)
954  {
956  break;
957  }
958  MultiByteString[2] = 0x80 | (Char & 0x3f); Char >>= 6;
959  MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
960  MultiByteString[0] = 0xe0 | Char;
961  MultiByteString += 3;
962  TempLength -= 3;
963  }
964 
965  return MultiByteCount - TempLength;
966 }
967 
975 static
976 inline
977 BOOL
979 {
980  /* If the WC_NO_BEST_FIT_CHARS flag has been specified, the characters need to match exactly. */
982  return (CodePageTable->MultiByteTable[ch] == wch);
983 
984  /* By default, all characters except TransDefaultChar apply as a valid mapping
985  for ch (so also "nearest" characters) */
986  if (ch != CodePageTable->TransDefaultChar)
987  return TRUE;
988 
989  /* The only possible left valid mapping is the default character itself */
990  return (wch == CodePageTable->TransUniDefaultChar);
991 }
992 
1000 static inline BOOL
1002 {
1003  /* If ch is the default character, but the wch is not, it can't be a valid mapping */
1005  return FALSE;
1006 
1007  /* If the WC_NO_BEST_FIT_CHARS flag has been specified, the characters need to match exactly. */
1009  {
1010  if(ch & 0xff00)
1011  {
1012  USHORT uOffset = CodePageTable->DBCSOffsets[ch >> 8];
1013  /* if (!uOffset) return (CodePageTable->MultiByteTable[ch] == wch); */
1014  return (CodePageTable->DBCSOffsets[uOffset + (ch & 0xff)] == wch);
1015  }
1016 
1017  return (CodePageTable->MultiByteTable[ch] == wch);
1018  }
1019 
1020  /* If we're still here, we have a valid mapping */
1021  return TRUE;
1022 }
1023 
1032 static
1033 INT
1034 WINAPI
1036  DWORD Flags,
1037  LPCWSTR WideCharString,
1038  INT WideCharCount,
1040  INT MultiByteCount,
1041  LPCSTR DefaultChar,
1042  LPBOOL UsedDefaultChar)
1043 {
1044  PCODEPAGE_ENTRY CodePageEntry;
1046  INT TempLength;
1047 
1048  /* Get code page table. */
1049  CodePageEntry = IntGetCodePageEntry(CodePage);
1050  if (CodePageEntry == NULL)
1051  {
1053  return 0;
1054  }
1055 
1056  CodePageTable = &CodePageEntry->CodePageTable;
1057 
1058 
1059  /* Different handling for DBCS code pages. */
1061  {
1062  /* If Flags, DefaultChar or UsedDefaultChar were given, we have to do some more work */
1063  if (Flags || DefaultChar || UsedDefaultChar)
1064  {
1065  BOOL TempUsedDefaultChar;
1066  USHORT DefChar;
1067 
1068  /* If UsedDefaultChar is not set, set it to a temporary value, so we don't have
1069  to check on every character */
1070  if (!UsedDefaultChar)
1071  UsedDefaultChar = &TempUsedDefaultChar;
1072 
1073  *UsedDefaultChar = FALSE;
1074 
1075  /* Use the CodePage's TransDefaultChar if none was given. Don't modify the DefaultChar pointer here. */
1076  if (DefaultChar)
1077  DefChar = DefaultChar[1] ? ((DefaultChar[0] << 8) | DefaultChar[1]) : DefaultChar[0];
1078  else
1079  DefChar = CodePageTable->TransDefaultChar;
1080 
1081  /* Does caller query for output buffer size? */
1082  if (!MultiByteCount)
1083  {
1084  for (TempLength = 0; WideCharCount; WideCharCount--, WideCharString++, TempLength++)
1085  {
1086  USHORT uChar;
1087 
1088  if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1089  {
1090  /* FIXME: Handle WC_COMPOSITECHECK */
1091  DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1092  }
1093 
1094  uChar = ((PUSHORT) CodePageTable->WideCharTable)[*WideCharString];
1095 
1096  /* Verify if the mapping is valid for handling DefaultChar and UsedDefaultChar */
1097  if (!IntIsValidDBCSMapping(CodePageTable, Flags, *WideCharString, uChar))
1098  {
1099  uChar = DefChar;
1100  *UsedDefaultChar = TRUE;
1101  }
1102 
1103  /* Increment TempLength again if this is a double-byte character */
1104  if (uChar & 0xff00)
1105  TempLength++;
1106  }
1107 
1108  return TempLength;
1109  }
1110 
1111  /* Convert the WideCharString to the MultiByteString and verify if the mapping is valid */
1112  for (TempLength = MultiByteCount;
1113  WideCharCount && TempLength;
1114  TempLength--, WideCharString++, WideCharCount--)
1115  {
1116  USHORT uChar;
1117 
1118  if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1119  {
1120  /* FIXME: Handle WC_COMPOSITECHECK */
1121  DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1122  }
1123 
1124  uChar = ((PUSHORT)CodePageTable->WideCharTable)[*WideCharString];
1125 
1126  /* Verify if the mapping is valid for handling DefaultChar and UsedDefaultChar */
1127  if (!IntIsValidDBCSMapping(CodePageTable, Flags, *WideCharString, uChar))
1128  {
1129  uChar = DefChar;
1130  *UsedDefaultChar = TRUE;
1131  }
1132 
1133  /* Handle double-byte characters */
1134  if (uChar & 0xff00)
1135  {
1136  /* Don't output a partial character */
1137  if (TempLength == 1)
1138  break;
1139 
1140  TempLength--;
1141  *MultiByteString++ = uChar >> 8;
1142  }
1143 
1144  *MultiByteString++ = (char)uChar;
1145  }
1146 
1147  /* WideCharCount should be 0 if all characters were converted */
1148  if (WideCharCount)
1149  {
1151  return 0;
1152  }
1153 
1154  return MultiByteCount - TempLength;
1155  }
1156 
1157  /* Does caller query for output buffer size? */
1158  if (!MultiByteCount)
1159  {
1160  for (TempLength = 0; WideCharCount; WideCharCount--, WideCharString++, TempLength++)
1161  {
1162  /* Increment TempLength again if this is a double-byte character */
1163  if (((PWCHAR)CodePageTable->WideCharTable)[*WideCharString] & 0xff00)
1164  TempLength++;
1165  }
1166 
1167  return TempLength;
1168  }
1169 
1170  /* Convert the WideCharString to the MultiByteString */
1171  for (TempLength = MultiByteCount;
1172  WideCharCount && TempLength;
1173  TempLength--, WideCharString++, WideCharCount--)
1174  {
1175  USHORT uChar = ((PUSHORT) CodePageTable->WideCharTable)[*WideCharString];
1176 
1177  /* Is this a double-byte character? */
1178  if (uChar & 0xff00)
1179  {
1180  /* Don't output a partial character */
1181  if (TempLength == 1)
1182  break;
1183 
1184  TempLength--;
1185  *MultiByteString++ = uChar >> 8;
1186  }
1187 
1188  *MultiByteString++ = (char)uChar;
1189  }
1190 
1191  /* WideCharCount should be 0 if all characters were converted */
1192  if (WideCharCount)
1193  {
1195  return 0;
1196  }
1197 
1198  return MultiByteCount - TempLength;
1199  }
1200  else /* SBCS code page */
1201  {
1202  INT nReturn;
1203 
1204  /* If Flags, DefaultChar or UsedDefaultChar were given, we have to do some more work */
1205  if (Flags || DefaultChar || UsedDefaultChar)
1206  {
1207  BOOL TempUsedDefaultChar;
1208  CHAR DefChar;
1209 
1210  /* If UsedDefaultChar is not set, set it to a temporary value, so we don't have
1211  to check on every character */
1212  if (!UsedDefaultChar)
1213  UsedDefaultChar = &TempUsedDefaultChar;
1214 
1215  *UsedDefaultChar = FALSE;
1216 
1217  /* Does caller query for output buffer size? */
1218  if (!MultiByteCount)
1219  {
1220  /* Loop through the whole WideCharString and check if we can get a valid mapping for each character */
1221  for (TempLength = 0; WideCharCount; TempLength++, WideCharString++, WideCharCount--)
1222  {
1223  if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1224  {
1225  /* FIXME: Handle WC_COMPOSITECHECK */
1226  DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1227  }
1228 
1229  if (!*UsedDefaultChar)
1230  *UsedDefaultChar = !IntIsValidSBCSMapping(CodePageTable,
1231  Flags,
1232  *WideCharString,
1233  ((PCHAR)CodePageTable->WideCharTable)[*WideCharString]);
1234  }
1235 
1236  return TempLength;
1237  }
1238 
1239  /* Use the CodePage's TransDefaultChar if none was given. Don't modify the DefaultChar pointer here. */
1240  if (DefaultChar)
1241  DefChar = *DefaultChar;
1242  else
1243  DefChar = (CHAR)CodePageTable->TransDefaultChar;
1244 
1245  /* Convert the WideCharString to the MultiByteString and verify if the mapping is valid */
1246  for (TempLength = MultiByteCount;
1247  WideCharCount && TempLength;
1248  MultiByteString++, TempLength--, WideCharString++, WideCharCount--)
1249  {
1250  if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1251  {
1252  /* FIXME: Handle WC_COMPOSITECHECK */
1253  DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1254  }
1255 
1256  *MultiByteString = ((PCHAR)CodePageTable->WideCharTable)[*WideCharString];
1257 
1258  if (!IntIsValidSBCSMapping(CodePageTable, Flags, *WideCharString, *MultiByteString))
1259  {
1260  *MultiByteString = DefChar;
1261  *UsedDefaultChar = TRUE;
1262  }
1263  }
1264 
1265  /* WideCharCount should be 0 if all characters were converted */
1266  if (WideCharCount)
1267  {
1269  return 0;
1270  }
1271 
1272  return MultiByteCount - TempLength;
1273  }
1274 
1275  /* Does caller query for output buffer size? */
1276  if (!MultiByteCount)
1277  return WideCharCount;
1278 
1279  /* Is the buffer large enough? */
1280  if (MultiByteCount < WideCharCount)
1281  {
1282  /* Convert the string up to MultiByteCount and return 0 */
1283  WideCharCount = MultiByteCount;
1285  nReturn = 0;
1286  }
1287  else
1288  {
1289  /* Otherwise WideCharCount will be the number of converted characters */
1290  nReturn = WideCharCount;
1291  }
1292 
1293  /* Convert the WideCharString to the MultiByteString */
1294  for (TempLength = WideCharCount; --TempLength >= 0; WideCharString++, MultiByteString++)
1295  {
1296  *MultiByteString = ((PCHAR)CodePageTable->WideCharTable)[*WideCharString];
1297  }
1298 
1299  return nReturn;
1300  }
1301 }
1302 
1310 static BOOL
1311 WINAPI
1313 {
1314  UINT i;
1315 
1316  if (TableInfo->MaximumCharacterSize == 2)
1317  {
1318  for (i = 0; i < MAXIMUM_LEADBYTES && TableInfo->LeadByte[i]; i += 2)
1319  {
1320  if (Byte >= TableInfo->LeadByte[i] && Byte <= TableInfo->LeadByte[i+1])
1321  return TRUE;
1322  }
1323  }
1324 
1325  return FALSE;
1326 }
1327 
1328 /* PUBLIC FUNCTIONS ***********************************************************/
1329 
1357 BOOL
1358 WINAPI
1360  UINT Base,
1361  ULONG Unknown,
1362  LPSTR BaseName,
1363  LPSTR Result,
1364  ULONG ResultSize)
1365 {
1366  CHAR Integer[11];
1367 
1368  if (!NT_SUCCESS(RtlIntegerToChar(CodePage, Base, sizeof(Integer), Integer)))
1369  return FALSE;
1370 
1371  /*
1372  * If the name including the terminating NULL character doesn't
1373  * fit in the output buffer then fail.
1374  */
1375  if (strlen(Integer) + strlen(BaseName) >= ResultSize)
1376  return FALSE;
1377 
1378  lstrcpyA(Result, BaseName);
1379  lstrcatA(Result, Integer);
1380 
1381  return TRUE;
1382 }
1383 
1402 BOOL
1403 WINAPI
1405 {
1406  WCHAR ValueNameBuffer[11];
1409  NTSTATUS Status;
1410  HANDLE KeyHandle;
1412  DWORD KvpiSize;
1413  BOOL bRetValue;
1414 
1415  bRetValue = FALSE;
1416 
1417  /* Convert the codepage number to string. */
1418  ValueName.Buffer = ValueNameBuffer;
1419  ValueName.MaximumLength = sizeof(ValueNameBuffer);
1420 
1421  if (!NT_SUCCESS(RtlIntegerToUnicodeString(CodePage, 10, &ValueName)))
1422  return bRetValue;
1423 
1424  /* Open the registry key containing file name mappings. */
1425  RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System\\"
1426  L"CurrentControlSet\\Control\\Nls\\CodePage");
1428  NULL, NULL);
1430  if (!NT_SUCCESS(Status))
1431  {
1432  return bRetValue;
1433  }
1434 
1435  /* Allocate buffer that will be used to query the value data. */
1436  KvpiSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + (MAX_PATH * sizeof(WCHAR));
1437  Kvpi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, KvpiSize);
1438  if (Kvpi == NULL)
1439  {
1440  NtClose(KeyHandle);
1441  return bRetValue;
1442  }
1443 
1444  /* Query the file name for our code page. */
1446  Kvpi, KvpiSize, &KvpiSize);
1447 
1448  NtClose(KeyHandle);
1449 
1450  /* Check if we succeded and the value is non-empty string. */
1451  if (NT_SUCCESS(Status) && Kvpi->Type == REG_SZ &&
1452  Kvpi->DataLength > sizeof(WCHAR))
1453  {
1454  bRetValue = TRUE;
1455  if (FileName != NULL)
1456  {
1457  lstrcpynW(FileName, (WCHAR*)Kvpi->Data,
1458  min(Kvpi->DataLength / sizeof(WCHAR), FileNameSize));
1459  }
1460  }
1461 
1462  /* free temporary buffer */
1463  HeapFree(GetProcessHeap(),0,Kvpi);
1464  return bRetValue;
1465 }
1466 
1478 BOOL
1479 WINAPI
1481 {
1482  if (CodePage == 0) return FALSE;
1483  if (CodePage == CP_UTF8 || CodePage == CP_UTF7)
1484  return TRUE;
1485  if (IntGetLoadedCodePageEntry(CodePage))
1486  return TRUE;
1487  return GetCPFileNameFromRegistry(CodePage, NULL, 0);
1488 }
1489 
1490 static inline BOOL utf7_write_w(WCHAR *dst, int dstlen, int *index, WCHAR character)
1491 {
1492  if (dstlen > 0)
1493  {
1494  if (*index >= dstlen)
1495  return FALSE;
1496 
1497  dst[*index] = character;
1498  }
1499 
1500  (*index)++;
1501 
1502  return TRUE;
1503 }
1504 
1505 static INT Utf7ToWideChar(const char *src, int srclen, WCHAR *dst, int dstlen)
1506 {
1507  static const signed char base64_decoding_table[] =
1508  {
1509  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00-0x0F */
1510  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10-0x1F */
1511  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20-0x2F */
1512  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30-0x3F */
1513  -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40-0x4F */
1514  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50-0x5F */
1515  -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60-0x6F */
1516  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 /* 0x70-0x7F */
1517  };
1518 
1519  const char *source_end = src + srclen;
1520  int dest_index = 0;
1521 
1522  DWORD byte_pair = 0;
1523  short offset = 0;
1524 
1525  while (src < source_end)
1526  {
1527  if (*src == '+')
1528  {
1529  src++;
1530  if (src >= source_end)
1531  break;
1532 
1533  if (*src == '-')
1534  {
1535  /* just a plus sign escaped as +- */
1536  if (!utf7_write_w(dst, dstlen, &dest_index, '+'))
1537  {
1539  return 0;
1540  }
1541  src++;
1542  continue;
1543  }
1544 
1545  do
1546  {
1547  signed char sextet = *src;
1548  if (sextet == '-')
1549  {
1550  /* skip over the dash and end base64 decoding
1551  * the current, unfinished byte pair is discarded */
1552  src++;
1553  offset = 0;
1554  break;
1555  }
1556  if (sextet < 0)
1557  {
1558  /* the next character of src is < 0 and therefore not part of a base64 sequence
1559  * the current, unfinished byte pair is NOT discarded in this case
1560  * this is probably a bug in Windows */
1561  break;
1562  }
1563 
1564  sextet = base64_decoding_table[sextet];
1565  if (sextet == -1)
1566  {
1567  /* -1 means that the next character of src is not part of a base64 sequence
1568  * in other words, all sextets in this base64 sequence have been processed
1569  * the current, unfinished byte pair is discarded */
1570  offset = 0;
1571  break;
1572  }
1573 
1574  byte_pair = (byte_pair << 6) | sextet;
1575  offset += 6;
1576 
1577  if (offset >= 16)
1578  {
1579  /* this byte pair is done */
1580  if (!utf7_write_w(dst, dstlen, &dest_index, (byte_pair >> (offset - 16)) & 0xFFFF))
1581  {
1583  return 0;
1584  }
1585  offset -= 16;
1586  }
1587 
1588  src++;
1589  }
1590  while (src < source_end);
1591  }
1592  else
1593  {
1594  /* we have to convert to unsigned char in case *src < 0 */
1595  if (!utf7_write_w(dst, dstlen, &dest_index, (unsigned char)*src))
1596  {
1598  return 0;
1599  }
1600  src++;
1601  }
1602  }
1603 
1604  return dest_index;
1605 }
1606 
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  IN LANGID lang)
1833 {
1834  HRSRC hrsrc;
1835  HGLOBAL hmem;
1836  LCID lcid;
1837  LANGID langId;
1838  const WCHAR *p;
1839  UINT i;
1840 
1841  /* See HACK in winnls/lang/xx-XX.rc files */
1842  if (uID == 37)
1843  uID = uID * 100;
1844 
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),
1985  GetThreadLocale()) != 0;
1986  }
1987  break;
1988 
1989  case CP_UTF8:
1990  {
1991  lpCPInfoEx->CodePage = CP_UTF8;
1992  lpCPInfoEx->UnicodeDefaultChar = 0x3f;
1993  return GetLocalisedText(lpCPInfoEx->CodePage,
1994  lpCPInfoEx->CodePageName,
1995  ARRAYSIZE(lpCPInfoEx->CodePageName),
1996  GetThreadLocale()) != 0;
1997  }
1998 
1999  default:
2000  {
2001  PCODEPAGE_ENTRY CodePageEntry;
2002 
2003  CodePageEntry = IntGetCodePageEntry(CodePage);
2004  if (CodePageEntry == NULL)
2005  {
2006  DPRINT1("Could not get CodePage Entry! CodePageEntry = NULL\n");
2008  return FALSE;
2009  }
2010 
2011  lpCPInfoEx->CodePage = CodePageEntry->CodePageTable.CodePage;
2012  lpCPInfoEx->UnicodeDefaultChar = CodePageEntry->CodePageTable.UniDefaultChar;
2013  return GetLocalisedText(lpCPInfoEx->CodePage,
2014  lpCPInfoEx->CodePageName,
2015  ARRAYSIZE(lpCPInfoEx->CodePageName),
2016  GetThreadLocale()) != 0;
2017  }
2018  break;
2019  }
2020 }
2021 
2022 
2023 /*
2024  * @implemented
2025  */
2026 BOOL
2027 WINAPI
2029  DWORD dwFlags,
2030  LPCPINFOEXA lpCPInfoEx)
2031 {
2032  CPINFOEXW CPInfo;
2033 
2034  if (!GetCPInfoExW(CodePage, dwFlags, &CPInfo))
2035  return FALSE;
2036 
2037  /* the layout is the same except for CodePageName */
2038  memcpy(lpCPInfoEx, &CPInfo, sizeof(CPINFOEXA));
2039 
2041  0,
2042  CPInfo.CodePageName,
2043  -1,
2044  lpCPInfoEx->CodePageName,
2045  sizeof(lpCPInfoEx->CodePageName),
2046  NULL,
2047  NULL);
2048  return TRUE;
2049 }
2050 
2090 INT
2091 WINAPI
2093  DWORD Flags,
2094  LPCWSTR WideCharString,
2095  INT WideCharCount,
2097  INT MultiByteCount,
2098  LPCSTR DefaultChar,
2099  LPBOOL UsedDefaultChar)
2100 {
2101  /* Check the parameters. */
2102  if (WideCharString == NULL ||
2103  WideCharCount == 0 ||
2104  (MultiByteString == NULL && MultiByteCount > 0) ||
2105  (PVOID)WideCharString == (PVOID)MultiByteString ||
2106  MultiByteCount < 0)
2107  {
2109  return 0;
2110  }
2111 
2112  /* Determine the input string length. */
2113  if (WideCharCount < 0)
2114  {
2115  WideCharCount = lstrlenW(WideCharString) + 1;
2116  }
2117 
2118  switch (CodePage)
2119  {
2120  case CP_UTF8:
2121  if (DefaultChar != NULL || UsedDefaultChar != NULL)
2122  {
2124  return 0;
2125  }
2126  return IntWideCharToMultiByteUTF8(CodePage,
2127  Flags,
2128  WideCharString,
2129  WideCharCount,
2131  MultiByteCount,
2132  DefaultChar,
2133  UsedDefaultChar);
2134 
2135  case CP_UTF7:
2136  if (DefaultChar != NULL || UsedDefaultChar != NULL)
2137  {
2139  return 0;
2140  }
2141  if (Flags)
2142  {
2144  return 0;
2145  }
2146  return WideCharToUtf7(WideCharString, WideCharCount,
2147  MultiByteString, MultiByteCount);
2148 
2149  case CP_SYMBOL:
2150  if ((DefaultChar!=NULL) || (UsedDefaultChar!=NULL))
2151  {
2153  return 0;
2154  }
2156  WideCharString,
2157  WideCharCount,
2159  MultiByteCount);
2160 
2161  default:
2162  return IntWideCharToMultiByteCP(CodePage,
2163  Flags,
2164  WideCharString,
2165  WideCharCount,
2167  MultiByteCount,
2168  DefaultChar,
2169  UsedDefaultChar);
2170  }
2171 }
2172 
2181 UINT
2182 WINAPI
2184 {
2186 }
2187 
2196 UINT
2197 WINAPI
2199 {
2201 }
2202 
2211 BOOL
2212 WINAPI
2213 IsDBCSLeadByteEx(UINT CodePage, BYTE TestByte)
2214 {
2215  PCODEPAGE_ENTRY CodePageEntry;
2216 
2217  CodePageEntry = IntGetCodePageEntry(CodePage);
2218  if (CodePageEntry != NULL)
2219  return IntIsLeadByte(&CodePageEntry->CodePageTable, TestByte);
2220 
2222  return FALSE;
2223 }
2224 
2233 BOOL
2234 WINAPI
2236 {
2237  return IntIsLeadByte(&AnsiCodePage.CodePageTable, TestByte);
2238 }
2239 
2240 /*
2241  * @unimplemented
2242  */
2244 {
2245  STUB;
2246  return 0;
2247 }
2248 
2249 /*
2250  * @unimplemented
2251  */
2253 {
2254  STUB;
2255  return 0;
2256 }
2257 
2258 /*
2259  * @unimplemented
2260  */
2262 {
2263  STUB;
2264 }
2265 
2266 /*
2267  * @unimplemented
2268  */
2270 {
2271  STUB;
2272  return 0;
2273 }
2274 
2275 /*
2276  * @unimplemented
2277  */
2278 BOOL
2279 WINAPI
2280 ValidateLCType(int a1, unsigned int a2, int a3, int a4)
2281 {
2282  STUB;
2283  return FALSE;
2284 }
2285 
2286 /*
2287  * @unimplemented
2288  */
2289 BOOL
2290 WINAPI
2292 {
2293  STUB;
2294  return TRUE;
2295 }
2296 
2297 /*
2298  * @unimplemented
2299  */
2300 VOID
2301 WINAPI
2303 {
2304  STUB;
2305  lpUnknown = NULL;
2306 }
2307 
2308 /*
2309  * @unimplemented
2310  */
2311 VOID
2312 WINAPI
2314 {
2315  STUB;
2316  lpUnknown = NULL;
2317 }
2318 
2319 /*
2320  * @unimplemented
2321  */
2322 BOOL
2323 WINAPI
2325 {
2326  STUB;
2327  return TRUE;
2328 }
2329 
2330 /*
2331  * @unimplemented
2332  */
2333 ULONG
2334 WINAPI
2336 {
2337  STUB;
2338  return 0;
2339 }
2340 
2341 /*
2342  * @unimplemented
2343  */
2344 BOOL
2345 WINAPI
2347  IN DWORD dwFlags,
2348  IN LPNLSVERSIONINFO lpVersionInformation,
2349  IN LPCWSTR lpString,
2350  IN INT cchStr)
2351 {
2352  STUB;
2353  return TRUE;
2354 }
2355 
2356 /*
2357  * @unimplemented
2358  */
2359 BOOL
2360 WINAPI
2362  IN LCID Locale,
2363  IN OUT LPNLSVERSIONINFO lpVersionInformation)
2364 {
2365  STUB;
2366  return TRUE;
2367 }
2368 
2369 /*
2370  * @unimplemented
2371  */
2372 BOOL
2373 WINAPI
2375  IN LPCWSTR lpLocaleName,
2376  IN OUT LPNLSVERSIONINFOEX lpVersionInformation)
2377 {
2378  STUB;
2379  return TRUE;
2380 }
2381 
2382 /* EOF */
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
signed char * PCHAR
Definition: retypes.h:7
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#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:366
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
BOOL WINAPI IsValidUILanguage(LANGID langid)
Definition: nls.c:2252
#define IN
Definition: typedefs.h:39
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:1505
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
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1154
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:604
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:3433
#define MB_USEGLYPHCHARS
Definition: unicode.h:42
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
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
PUSHORT MultiByteTable
Definition: precomp.h:40
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define CP_UTF7
Definition: winnls.h:235
#define MAKEWORD(a, b)
Definition: typedefs.h:248
#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:787
#define TRUE
Definition: types.h:120
_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:550
WCHAR CodePageName[MAX_PATH]
Definition: winnls.h:599
#define LANG_NEUTRAL
Definition: nls.h:22
BOOL WINAPI ValidateLocale(IN ULONG LocaleId)
Definition: nls.c:2324
#define CP_ACP
Definition: compat.h:109
BOOL WINAPI ValidateLCType(int a1, unsigned int a2, int a3, int a4)
Definition: nls.c:2280
char CHAR
Definition: xmlstorage.h:175
VOID WINAPI GetLinguistLangSize(LPVOID lpUnknown)
Definition: nls.c:2313
BOOL WINAPI IsNLSDefinedString(IN NLS_FUNCTION Function, IN DWORD dwFlags, IN LPNLSVERSIONINFO lpVersionInformation, IN LPCWSTR lpString, IN INT cchStr)
Definition: nls.c:2346
LONG NTSTATUS
Definition: precomp.h:26
IN PDCB IN POEM_STRING IN PUNICODE_STRING UnicodeName
Definition: fatprocs.h:1303
#define LOCALE_IDEFAULTMACCODEPAGE
Definition: winnls.h:39
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2386
BOOL WINAPI GetNLSVersionEx(IN NLS_FUNCTION function, IN LPCWSTR lpLocaleName, IN OUT LPNLSVERSIONINFOEX lpVersionInformation)
Definition: nls.c:2374
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:590
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
static const struct update_accum a4
Definition: msg.c:2285
UINT MaxCharSize
Definition: winnls.h:581
INT WINAPI WideCharToMultiByte(UINT CodePage, DWORD Flags, LPCWSTR WideCharString, INT WideCharCount, LPSTR MultiByteString, INT MultiByteCount, LPCSTR DefaultChar, LPBOOL UsedDefaultChar)
Definition: nls.c:2092
DWORD LCID
Definition: nls.h:13
WORD LANGID
Definition: typedefs.h:81
uint16_t * PWCHAR
Definition: typedefs.h:56
#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:609
#define FASTCALL
Definition: nt_native.h:50
#define CP_SYMBOL
Definition: winnls.h:234
int32_t INT
Definition: typedefs.h:58
_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:849
#define FILE_SHARE_READ
Definition: compat.h:136
#define SUBLANG_ENGLISH_US
Definition: nls.h:222
#define lstrcpynW
Definition: compat.h:597
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: lang.c:1102
static INT WINAPI IntMultiByteToWideCharSYMBOL(DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:732
BOOL WINAPI NlsResetProcessLocale(VOID)
Definition: nls.c:2291
HANDLE FileHandle
Definition: stats.c:38
BOOL WINAPI IsDBCSLeadByteEx(UINT CodePage, BYTE TestByte)
Definition: nls.c:2213
static BOOL utf7_write_c(char *dst, int dstlen, int *index, char character)
Definition: nls.c:1713
#define L(x)
Definition: ntvdm.h:50
VOID WINAPI GetDefaultSortkeySize(LPVOID lpUnknown)
Definition: nls.c:2302
#define SEC_COMMIT
Definition: mmtypes.h:99
#define CP_UTF8
Definition: nls.h:20
#define FALSE
Definition: types.h:117
LCID WINAPI ConvertDefaultLocale(LCID lcid)
Definition: lang.c:1506
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:3561
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:978
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:2235
UINT WINAPI GetACP(VOID)
Definition: nls.c:2183
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
WCHAR lpszDest[260]
#define FILE_MAP_READ
Definition: compat.h:635
USHORT TransDefaultChar
Definition: precomp.h:36
GLuint index
Definition: glext.h:6031
const char * LPCSTR
Definition: xmlstorage.h:183
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2697
#define OPEN_EXISTING
Definition: compat.h:634
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:2335
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
static const WCHAR lang[]
Definition: wbemdisp.c:287
Status
Definition: gdiplustypes.h:24
UCHAR LeadByte[MAXIMUM_LEADBYTES]
Definition: precomp.h:39
USHORT DBCSCodePage
Definition: precomp.h:38
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
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:2261
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)
int Count
Definition: noreturn.cpp:7
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
static INT WINAPI IntMultiByteToWideCharCP(UINT CodePage, DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:538
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
NTSTATUS WINAPI CreateNlsSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, ULONG Size, ULONG AccessMask)
Definition: nls.c:2243
#define ASSERT(a)
Definition: mode.c:44
__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:583
GLintptr offset
Definition: glext.h:5920
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:2361
#define MAX_PATH
Definition: compat.h:34
#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:1312
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define SetLastError(x)
Definition: compat.h:611
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3401
#define WC_NO_BEST_FIT_CHARS
Definition: unicode.h:46
#define LANG_ENGLISH
Definition: nls.h:52
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
USHORT CodePage
Definition: precomp.h:32
#define ERROR_NO_UNICODE_TRANSLATION
Definition: winerror.h:649
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING _In_ PCUNICODE_STRING _In_ LCID LocaleId
Definition: wdfpdo.h:430
static CODEPAGE_ENTRY OemCodePage
Definition: nls.c:47
static BOOL IntIsValidDBCSMapping(PCPTABLEINFO CodePageTable, DWORD Flags, WCHAR wch, USHORT ch)
Definition: nls.c:1001
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:240
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:1035
HRSRC WINAPI FindResourceExW(HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD lang)
Definition: res.c:164
CHAR CodePageName[MAX_PATH]
Definition: winnls.h:591
static RTL_CRITICAL_SECTION CodePageListLock
Definition: nls.c:48
#define index(s, c)
Definition: various.h:29
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define SECTION_MAP_READ
Definition: compat.h:139
#define OBJ_PERMANENT
Definition: winternl.h:226
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define LANGIDFROMLCID(l)
Definition: nls.h:18
#define MAXIMUM_LEADBYTES
Definition: precomp.h:16
VOID NTAPI RtlInitCodePageTable(IN PUSHORT TableBase, OUT PCPTABLEINFO CodePageTable)
Definition: nls.c:155
#define RT_STRING
Definition: pedump.c:368
USHORT DefaultChar
Definition: precomp.h:34
Definition: typedefs.h:119
GLenum src
Definition: glext.h:6340
BOOL WINAPI GetCPFileNameFromRegistry(UINT CodePage, LPWSTR FileName, ULONG FileNameSize)
Definition: nls.c:1404
INT WINAPI MultiByteToWideChar(UINT CodePage, DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:1639
BOOL WINAPI GetNlsSectionName(UINT CodePage, UINT Base, ULONG Unknown, LPSTR BaseName, LPSTR Result, ULONG ResultSize)
Definition: nls.c:1359
unsigned char BYTE
Definition: xxhash.c:193
NTSTATUS NTAPI NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:765
BOOL WINAPI IsValidCodePage(UINT CodePage)
Definition: nls.c:1480
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
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define 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:2028
BYTE DefaultChar[MAX_DEFAULTCHAR]
Definition: winnls.h:582
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 NULL
Definition: types.h:112
#define PAGE_READONLY
Definition: compat.h:138
static const unsigned char UTF8Mask[6]
Definition: nls.c:38
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
PBYTE SectionMapping
Definition: kernel32.h:67
*BytesInMultiByteString PCHAR MultiByteString
Definition: rtlfuncs.h:1527
#define DPRINT1
Definition: precomp.h:8
#define CreateFileW
Definition: compat.h:600
unsigned char Byte
Definition: zlib.h:37
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
_In_ HANDLE Handle
Definition: extypes.h:390
#define OUT
Definition: typedefs.h:40
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:736
_Out_ PCPTABLEINFO CodePageTable
Definition: rtlfuncs.h:4264
#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:1490
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
UINT GetLocalisedText(IN UINT uID, IN LPWSTR lpszDest, IN UINT cchDest, IN LANGID lang)
Definition: nls.c:1828
HANDLE SectionHandle
Definition: kernel32.h:66
GLfloat GLfloat p
Definition: glext.h:8902
#define DPRINT
Definition: sndvol32.h:71
WCHAR * LPWSTR
Definition: xmlstorage.h:184
NTSYSAPI NTSTATUS NTAPI RtlDeleteCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define CP_THREAD_ACP
Definition: winnls.h:233
VOID FASTCALL NlsUninit(VOID)
Definition: nls.c:126
#define UnmapViewOfFile
Definition: compat.h:605
#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:2269
#define CP_OEMCP
Definition: winnls.h:231
#define HeapFree(x, y, z)
Definition: compat.h:594
#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:1453
#define CP_MACCP
Definition: winnls.h:232
#define PRIMARYLANGID(l)
Definition: nls.h:16
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
UINT WINAPI GetOEMCP(VOID)
Definition: nls.c:2198
#define REG_SZ
Definition: layer.c:22