ReactOS 0.4.17-dev-243-g1369312
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. */
25static 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. */
38static const unsigned char UTF8Mask[6] = {0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
39
40/* UTF-8 length to lower bound */
41static 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
57GetCPFileNameFromRegistry(UINT CodePage, LPWSTR FileName, ULONG FileNameSize);
58
65
66/* PRIVATE FUNCTIONS **********************************************************/
67
80static NTSTATUS
84{
87 PSID AdminsSid;
88 PACL Dacl;
90
91 /* Give everyone basic directory access */
95 if (!NT_SUCCESS(Status))
96 {
97 DPRINT1("Failed to create basic NLS SD (Status 0x%08x)\n", Status);
98 return Status;
99 }
100
101 /* Create the Admins SID */
102 // NOTE: Win <= 2k3 uses SYSTEM instead (SECURITY_LOCAL_SYSTEM_RID with one SubAuthority)
104 2,
107 0, 0, 0, 0, 0, 0,
108 &AdminsSid);
109 if (!NT_SUCCESS(Status))
110 {
111 DPRINT1("Failed to create Admins SID (Status 0x%08x)\n", Status);
112 goto Quit;
113 }
114
115 /* Retrieve the DACL from the descriptor */
118 &Dacl,
120 if (!NT_SUCCESS(Status) || !DaclPresent || !Dacl)
121 {
122 DPRINT1("Failed to get DACL from descriptor (Status 0x%08x)\n", Status);
123 goto Quit;
124 }
125
126 /* Add an allowed access ACE to the Admins SID with full access.
127 * The function verifies the DACL is large enough to accommodate it. */
131 AdminsSid);
132 if (!NT_SUCCESS(Status))
133 {
134 DPRINT1("Failed to add allowed access ACE for Admins SID (Status 0x%08x)\n", Status);
135 goto Quit;
136 }
137
138Quit:
139 RtlFreeSid(AdminsSid);
140 return Status;
141}
142
149BOOL
152{
159
162
163 /*
164 * FIXME: Eventually this should be done only for the NLS Server
165 * process, but since we don't have anything like that (yet?) we
166 * always try to create the "\NLS" directory here.
167 */
169
170 /* Create a security descriptor for the NLS directory */
172 sizeof(SecurityDescriptor));
173 if (!NT_SUCCESS(Status))
174 {
175 DPRINT1("Failed to create NLS directory security (Status 0x%08x)\n", Status);
176 return FALSE;
177 }
178
180 &DirName,
182 NULL,
184
188 if (NT_SUCCESS(Status))
189 {
191 }
192
193 /* Setup ANSI code page. */
195 AnsiCodePage.SectionMapping = NtCurrentTeb()->ProcessEnvironmentBlock->AnsiCodePageData;
196
200
202
203 /* Setup OEM code page. */
205 OemCodePage.SectionMapping = NtCurrentTeb()->ProcessEnvironmentBlock->OemCodePageData;
206
211
212 return TRUE;
213}
214
221VOID
224{
225 PCODEPAGE_ENTRY Current;
226
227 /* Delete the code page list. */
229 {
231 if (Current->SectionHandle != NULL)
232 {
234 NtClose(Current->SectionHandle);
235 }
237 }
239}
240
258{
259 LIST_ENTRY *CurrentEntry;
260 PCODEPAGE_ENTRY Current;
261
263 for (CurrentEntry = CodePageListHead.Flink;
264 CurrentEntry != &CodePageListHead;
265 CurrentEntry = CurrentEntry->Flink)
266 {
267 Current = CONTAINING_RECORD(CurrentEntry, CODEPAGE_ENTRY, Entry);
268 if (Current->CodePage == CodePage)
269 {
271 return Current;
272 }
273 }
275
276 return NULL;
277}
278
294{
296 CHAR SectionName[40];
297 HANDLE SectionHandle = INVALID_HANDLE_VALUE, FileHandle;
298 PBYTE SectionMapping;
300 union
301 {
302 SECURITY_DESCRIPTOR AlignedSd;
305 ANSI_STRING AnsiName;
308 UINT FileNamePos;
309 PCODEPAGE_ENTRY CodePageEntry;
310
311 if (CodePage == CP_ACP)
312 {
313 return &AnsiCodePage;
314 }
315 else if (CodePage == CP_OEMCP)
316 {
317 return &OemCodePage;
318 }
319 else if (CodePage == CP_THREAD_ACP)
320 {
322 LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
323 (WCHAR *)&CodePage,
324 sizeof(CodePage) / sizeof(WCHAR)))
325 {
326 /* Last error is set by GetLocaleInfoW. */
327 return NULL;
328 }
329 if (CodePage == 0)
330 return &AnsiCodePage;
331 }
332 else if (CodePage == CP_MACCP)
333 {
335 LOCALE_IDEFAULTMACCODEPAGE | LOCALE_RETURN_NUMBER,
336 (WCHAR *)&CodePage,
337 sizeof(CodePage) / sizeof(WCHAR)))
338 {
339 /* Last error is set by GetLocaleInfoW. */
340 return NULL;
341 }
342 }
343
344 /* Try searching for loaded page first. */
345 CodePageEntry = IntGetLoadedCodePageEntry(CodePage);
346 if (CodePageEntry != NULL)
347 {
348 return CodePageEntry;
349 }
350
351 /*
352 * Yes, we really want to lock here. Otherwise it can happen that
353 * two parallel requests will try to get the entry for the same
354 * code page and we would load it twice.
355 */
357
358 /* Generate the section name. */
359 if (!GetNlsSectionName(CodePage,
360 10,
361 0,
362 "\\Nls\\NlsSectionCP",
363 SectionName,
364 sizeof(SectionName)))
365 {
367 return NULL;
368 }
369
370 RtlInitAnsiString(&AnsiName, SectionName);
372
373 /*
374 * FIXME: IntGetCodePageEntry should not create any security
375 * descriptor here but instead this responsibility should be
376 * assigned to Base Server API (aka basesrv.dll). That is,
377 * kernel32 must instruct basesrv.dll on creating NLS section
378 * names that do not exist through API message communication.
379 * However since we do not do that, let the kernel32 do the job
380 * by assigning security to NLS section names for the time being...
381 */
383 sizeof(SecurityDescriptor),
385 if (!NT_SUCCESS(Status))
386 {
387 DPRINT1("CreateNlsSecurityDescriptor FAILED! (Status 0x%08x)\n", Status);
389 return NULL;
390 }
391
395 NULL,
397
398 /* Try to open the section first */
399 Status = NtOpenSection(&SectionHandle,
402
403 /* If the section doesn't exist, try to create it. */
407 {
408 FileNamePos = GetSystemDirectoryW(FileName, MAX_PATH);
409 if (GetCPFileNameFromRegistry(CodePage,
410 FileName + FileNamePos + 1,
411 MAX_PATH - FileNamePos - 1))
412 {
413 FileName[FileNamePos] = L'\\';
414 FileName[MAX_PATH] = 0;
418 NULL,
420 0,
421 NULL);
422
423 Status = NtCreateSection(&SectionHandle,
426 NULL,
429 FileHandle);
430
431 /* HACK: Check if another process was faster
432 * and already created this section. See bug 3626 for details */
434 {
435 /* Close the file then */
437
438 /* And open the section */
439 Status = NtOpenSection(&SectionHandle,
442 }
443 }
444 }
446
447 if (!NT_SUCCESS(Status))
448 {
450 return NULL;
451 }
452
453 SectionMapping = MapViewOfFile(SectionHandle, FILE_MAP_READ, 0, 0, 0);
454 if (SectionMapping == NULL)
455 {
456 NtClose(SectionHandle);
458 return NULL;
459 }
460
461 CodePageEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(CODEPAGE_ENTRY));
462 if (CodePageEntry == NULL)
463 {
464 NtClose(SectionHandle);
466 return NULL;
467 }
468
469 CodePageEntry->CodePage = CodePage;
470 CodePageEntry->SectionHandle = SectionHandle;
471 CodePageEntry->SectionMapping = SectionMapping;
472
473 RtlInitCodePageTable((PUSHORT)SectionMapping, &CodePageEntry->CodePageTable);
474
475 /* Insert the new entry to list and unlock. Uff. */
476 InsertTailList(&CodePageListHead, &CodePageEntry->Entry);
478
479 return CodePageEntry;
480}
481
491static
492INT
493WINAPI
496 INT MultiByteCount,
497 LPWSTR WideCharString,
498 INT WideCharCount)
499{
500 LPCSTR MbsEnd, MbsPtrSave;
501 UCHAR Char, TrailLength;
502 UINT WideChar;
503 LONG Count;
504 BOOL CharIsValid, StringIsValid = TRUE;
505 const WCHAR InvalidChar = 0xFFFD;
506
507 if (Flags != 0 && Flags != MB_ERR_INVALID_CHARS)
508 {
510 return 0;
511 }
512
513 /* Does caller query for output buffer size? */
514 if (WideCharCount == 0)
515 {
516 /* validate and count the wide characters */
517 MbsEnd = MultiByteString + MultiByteCount;
518 for (; MultiByteString < MbsEnd; WideCharCount++)
519 {
520 Char = *MultiByteString++;
521 if (Char < 0x80)
522 {
523 TrailLength = 0;
524 continue;
525 }
526 if ((Char & 0xC0) == 0x80)
527 {
528 TrailLength = 0;
529 StringIsValid = FALSE;
530 continue;
531 }
532
533 TrailLength = UTF8Length[Char - 0x80];
534 if (TrailLength == 0)
535 {
536 StringIsValid = FALSE;
537 continue;
538 }
539
540 CharIsValid = TRUE;
541 MbsPtrSave = MultiByteString;
542 WideChar = Char & UTF8Mask[TrailLength];
543
544 while (TrailLength && MultiByteString < MbsEnd)
545 {
546 if ((*MultiByteString & 0xC0) != 0x80)
547 {
548 CharIsValid = StringIsValid = FALSE;
549 break;
550 }
551
552 WideChar = (WideChar << 6) | (*MultiByteString++ & 0x7f);
553 TrailLength--;
554 }
555
556 if (!CharIsValid || WideChar < UTF8LBound[UTF8Length[Char - 0x80]])
557 {
558 MultiByteString = MbsPtrSave;
559 }
560
561 if (WideChar > 0xFFFF)
562 {
563 /* UTF-16 surrogate pair */
564 WideCharCount++;
565 }
566 }
567
568 if (TrailLength)
569 {
570 WideCharCount++;
571 StringIsValid = FALSE;
572 }
573
574 if (Flags == MB_ERR_INVALID_CHARS && !StringIsValid)
575 {
577 return 0;
578 }
579
580 return WideCharCount;
581 }
582
583 /* convert */
584 MbsEnd = MultiByteString + MultiByteCount;
585 for (Count = 0; Count < WideCharCount && MultiByteString < MbsEnd; Count++)
586 {
587 Char = *MultiByteString++;
588 if (Char < 0x80)
589 {
590 *WideCharString++ = Char;
591 TrailLength = 0;
592 continue;
593 }
594 if ((Char & 0xC0) == 0x80)
595 {
596 *WideCharString++ = InvalidChar;
597 TrailLength = 0;
598 StringIsValid = FALSE;
599 continue;
600 }
601
602 TrailLength = UTF8Length[Char - 0x80];
603 if (TrailLength == 0)
604 {
605 *WideCharString++ = InvalidChar;
606 StringIsValid = FALSE;
607 continue;
608 }
609
610 CharIsValid = TRUE;
611 MbsPtrSave = MultiByteString;
612 WideChar = Char & UTF8Mask[TrailLength];
613
614 while (TrailLength && MultiByteString < MbsEnd)
615 {
616 if ((*MultiByteString & 0xC0) != 0x80)
617 {
618 CharIsValid = StringIsValid = FALSE;
619 break;
620 }
621
622 WideChar = (WideChar << 6) | (*MultiByteString++ & 0x7f);
623 TrailLength--;
624 }
625
626 if (CharIsValid && UTF8LBound[UTF8Length[Char - 0x80]] <= WideChar)
627 {
628 /* Check for UTF-16 surrogate pair */
629 if (WideChar > 0xFFFF)
630 {
631 WideChar -= 0x10000;
632 *WideCharString++ = 0xD800 | (WideChar >> 10);
633 Count++;
634
635 /* Check if we have space for the second surrogate */
636 if (Count >= WideCharCount)
637 {
639 return 0;
640 }
641
642 *WideCharString++ = 0xDC00 | (WideChar & 0x3FF);
643 }
644 else
645 {
646 *WideCharString++ = WideChar;
647 }
648 }
649 else
650 {
651 *WideCharString++ = InvalidChar;
652 MultiByteString = MbsPtrSave;
653 StringIsValid = FALSE;
654 }
655 }
656
657 if (TrailLength && Count < WideCharCount && MultiByteString < MbsEnd)
658 {
659 *WideCharString = InvalidChar;
660 WideCharCount++;
661 }
662
663 if (MultiByteString < MbsEnd)
664 {
666 return 0;
667 }
668
669 if (Flags == MB_ERR_INVALID_CHARS && (!StringIsValid || TrailLength))
670 {
672 return 0;
673 }
674
675 return Count;
676}
677
688static
689INT
690WINAPI
692 DWORD Flags,
694 INT MultiByteCount,
695 LPWSTR WideCharString,
696 INT WideCharCount)
697{
698 PCODEPAGE_ENTRY CodePageEntry;
700 PUSHORT MultiByteTable;
701 LPCSTR TempString;
702 INT TempLength;
703 USHORT WideChar;
704
705 /* Get code page table. */
706 CodePageEntry = IntGetCodePageEntry(CodePage);
707 if (CodePageEntry == NULL)
708 {
710 return 0;
711 }
712
713 CodePageTable = &CodePageEntry->CodePageTable;
714
715 /* If MB_USEGLYPHCHARS flag present and glyph table present */
717 {
718 /* Use glyph table */
719 MultiByteTable = CodePageTable->MultiByteTable + 256 + 1;
720 }
721 else
722 {
723 MultiByteTable = CodePageTable->MultiByteTable;
724 }
725
726 /* Different handling for DBCS code pages. */
728 {
729 UCHAR Char;
730 USHORT DBCSOffset;
731 LPCSTR MbsEnd = MultiByteString + MultiByteCount;
732 INT Count;
733
735 {
736 TempString = MultiByteString;
737
738 while (TempString < MbsEnd)
739 {
740 DBCSOffset = CodePageTable->DBCSOffsets[(UCHAR)*TempString];
741
742 if (DBCSOffset)
743 {
744 /* If lead byte is presented, but behind it there is no symbol */
745 if (((TempString + 1) == MbsEnd) || (*(TempString + 1) == 0))
746 {
748 return 0;
749 }
750
751 WideChar = CodePageTable->DBCSOffsets[DBCSOffset + *(TempString + 1)];
752
753 if (WideChar == CodePageTable->UniDefaultChar &&
754 MAKEWORD(*(TempString + 1), *TempString) != CodePageTable->TransUniDefaultChar)
755 {
757 return 0;
758 }
759
760 TempString++;
761 }
762 else
763 {
764 WideChar = MultiByteTable[(UCHAR)*TempString];
765
766 if ((WideChar == CodePageTable->UniDefaultChar &&
767 *TempString != CodePageTable->TransUniDefaultChar) ||
768 /* "Private Use" characters */
769 (WideChar >= 0xE000 && WideChar <= 0xF8FF))
770 {
772 return 0;
773 }
774 }
775
776 TempString++;
777 }
778 }
779
780 /* Does caller query for output buffer size? */
781 if (WideCharCount == 0)
782 {
783 for (; MultiByteString < MbsEnd; WideCharCount++)
784 {
785 Char = *MultiByteString++;
786
787 DBCSOffset = CodePageTable->DBCSOffsets[Char];
788
789 if (!DBCSOffset)
790 continue;
791
792 if (MultiByteString < MbsEnd)
794 }
795
796 return WideCharCount;
797 }
798
799 for (Count = 0; Count < WideCharCount && MultiByteString < MbsEnd; Count++)
800 {
801 Char = *MultiByteString++;
802
803 DBCSOffset = CodePageTable->DBCSOffsets[Char];
804
805 if (!DBCSOffset)
806 {
807 *WideCharString++ = MultiByteTable[Char];
808 continue;
809 }
810
811 if (MultiByteString == MbsEnd || *MultiByteString == 0)
812 {
813 *WideCharString++ = CodePageTable->UniDefaultChar;
814 }
815 else
816 {
817 *WideCharString++ = CodePageTable->DBCSOffsets[DBCSOffset + (UCHAR)*MultiByteString++];
818 }
819 }
820
821 if (MultiByteString < MbsEnd)
822 {
824 return 0;
825 }
826
827 return Count;
828 }
829 else /* SBCS code page */
830 {
831 /* Check for invalid characters. */
833 {
834 for (TempString = MultiByteString, TempLength = MultiByteCount;
835 TempLength > 0;
836 TempString++, TempLength--)
837 {
838 WideChar = MultiByteTable[(UCHAR)*TempString];
839
840 if ((WideChar == CodePageTable->UniDefaultChar &&
841 *TempString != CodePageTable->TransUniDefaultChar) ||
842 /* "Private Use" characters */
843 (WideChar >= 0xE000 && WideChar <= 0xF8FF))
844 {
846 return 0;
847 }
848 }
849 }
850
851 /* Does caller query for output buffer size? */
852 if (WideCharCount == 0)
853 return MultiByteCount;
854
855 /* Fill the WideCharString buffer with what will fit: Verified on WinXP */
856 for (TempLength = (WideCharCount < MultiByteCount) ? WideCharCount : MultiByteCount;
857 TempLength > 0;
858 MultiByteString++, TempLength--)
859 {
860 *WideCharString++ = MultiByteTable[(UCHAR)*MultiByteString];
861 }
862
863 /* Adjust buffer size. Wine trick ;-) */
864 if (WideCharCount < MultiByteCount)
865 {
866 MultiByteCount = WideCharCount;
868 return 0;
869 }
870 return MultiByteCount;
871 }
872}
873
882static
883INT
884WINAPI
887 INT MultiByteCount,
888 LPWSTR WideCharString,
889 INT WideCharCount)
890{
891 LONG Count;
892 UCHAR Char;
893 INT WideCharMaxLen;
894
895
896 if (Flags != 0)
897 {
899 return 0;
900 }
901
902 if (WideCharCount == 0)
903 {
904 return MultiByteCount;
905 }
906
907 WideCharMaxLen = WideCharCount > MultiByteCount ? MultiByteCount : WideCharCount;
908
909 for (Count = 0; Count < WideCharMaxLen; Count++)
910 {
911 Char = MultiByteString[Count];
912 if ( Char < 0x20 )
913 {
914 WideCharString[Count] = Char;
915 }
916 else
917 {
918 WideCharString[Count] = Char + 0xf000;
919 }
920 }
921 if (MultiByteCount > WideCharMaxLen)
922 {
924 return 0;
925 }
926
927 return WideCharMaxLen;
928}
929
938static INT
939WINAPI
941 LPCWSTR WideCharString,
942 INT WideCharCount,
944 INT MultiByteCount)
945{
946 LONG Count;
947 INT MaxLen;
948 WCHAR Char;
949
950 if (Flags!=0)
951 {
953 return 0;
954 }
955
956
957 if (MultiByteCount == 0)
958 {
959 return WideCharCount;
960 }
961
962 MaxLen = MultiByteCount > WideCharCount ? WideCharCount : MultiByteCount;
963 for (Count = 0; Count < MaxLen; Count++)
964 {
965 Char = WideCharString[Count];
966 if (Char < 0x20)
967 {
968 MultiByteString[Count] = (CHAR)Char;
969 }
970 else
971 {
972 if ((Char >= 0xf020) && (Char < 0xf100))
973 {
974 MultiByteString[Count] = Char - 0xf000;
975 }
976 else
977 {
979 return 0;
980 }
981 }
982 }
983
984 if (WideCharCount > MaxLen)
985 {
987 return 0;
988 }
989 return MaxLen;
990}
991
1000static INT
1001WINAPI
1003 DWORD Flags,
1004 LPCWSTR WideCharString,
1005 INT WideCharCount,
1007 INT MultiByteCount,
1008 LPCSTR DefaultChar,
1009 LPBOOL UsedDefaultChar)
1010{
1011 INT TempLength;
1012 DWORD Char;
1013
1014 if (Flags)
1015 {
1017 return 0;
1018 }
1019
1020 /* Does caller query for output buffer size? */
1021 if (MultiByteCount == 0)
1022 {
1023 for (TempLength = 0; WideCharCount;
1024 WideCharCount--, WideCharString++)
1025 {
1026 TempLength++;
1027 if (*WideCharString >= 0x80)
1028 {
1029 TempLength++;
1030 if (*WideCharString >= 0x800)
1031 {
1032 TempLength++;
1033 if (*WideCharString >= 0xd800 && *WideCharString < 0xdc00 &&
1034 WideCharCount >= 1 &&
1035 WideCharString[1] >= 0xdc00 && WideCharString[1] <= 0xe000)
1036 {
1037 WideCharCount--;
1038 WideCharString++;
1039 TempLength++;
1040 }
1041 }
1042 }
1043 }
1044 return TempLength;
1045 }
1046
1047 for (TempLength = MultiByteCount; WideCharCount; WideCharCount--, WideCharString++)
1048 {
1049 Char = *WideCharString;
1050 if (Char < 0x80)
1051 {
1052 if (!TempLength)
1053 {
1055 break;
1056 }
1057 TempLength--;
1058 *MultiByteString++ = (CHAR)Char;
1059 continue;
1060 }
1061
1062 if (Char < 0x800) /* 0x80-0x7ff: 2 bytes */
1063 {
1064 if (TempLength < 2)
1065 {
1067 break;
1068 }
1069 MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
1070 MultiByteString[0] = 0xc0 | Char;
1071 MultiByteString += 2;
1072 TempLength -= 2;
1073 continue;
1074 }
1075
1076 /* surrogate pair 0x10000-0x10ffff: 4 bytes */
1077 if (Char >= 0xd800 && Char < 0xdc00 &&
1078 WideCharCount >= 1 &&
1079 WideCharString[1] >= 0xdc00 && WideCharString[1] < 0xe000)
1080 {
1081 WideCharCount--;
1082 WideCharString++;
1083
1084 if (TempLength < 4)
1085 {
1087 break;
1088 }
1089
1090 Char = (Char - 0xd800) << 10;
1091 Char |= *WideCharString - 0xdc00;
1092 ASSERT(Char <= 0xfffff);
1093 Char += 0x10000;
1094 ASSERT(Char <= 0x10ffff);
1095
1096 MultiByteString[3] = 0x80 | (Char & 0x3f); Char >>= 6;
1097 MultiByteString[2] = 0x80 | (Char & 0x3f); Char >>= 6;
1098 MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
1099 MultiByteString[0] = 0xf0 | Char;
1100 MultiByteString += 4;
1101 TempLength -= 4;
1102 continue;
1103 }
1104
1105 /* 0x800-0xffff: 3 bytes */
1106 if (TempLength < 3)
1107 {
1109 break;
1110 }
1111 MultiByteString[2] = 0x80 | (Char & 0x3f); Char >>= 6;
1112 MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
1113 MultiByteString[0] = 0xe0 | Char;
1114 MultiByteString += 3;
1115 TempLength -= 3;
1116 }
1117
1118 return MultiByteCount - TempLength;
1119}
1120
1128static
1129inline
1130BOOL
1132{
1133 /* If the WC_NO_BEST_FIT_CHARS flag has been specified, the characters need to match exactly. */
1135 return (CodePageTable->MultiByteTable[ch] == wch);
1136
1137 /* By default, all characters except TransDefaultChar apply as a valid mapping
1138 for ch (so also "nearest" characters) */
1140 return TRUE;
1141
1142 /* The only possible left valid mapping is the default character itself */
1143 return (wch == CodePageTable->TransUniDefaultChar);
1144}
1145
1153static inline BOOL
1155{
1156 /* If ch is the default character, but the wch is not, it can't be a valid mapping */
1158 return FALSE;
1159
1160 /* If the WC_NO_BEST_FIT_CHARS flag has been specified, the characters need to match exactly. */
1162 {
1163 if(ch & 0xff00)
1164 {
1165 USHORT uOffset = CodePageTable->DBCSOffsets[ch >> 8];
1166 /* if (!uOffset) return (CodePageTable->MultiByteTable[ch] == wch); */
1167 return (CodePageTable->DBCSOffsets[uOffset + (ch & 0xff)] == wch);
1168 }
1169
1170 return (CodePageTable->MultiByteTable[ch] == wch);
1171 }
1172
1173 /* If we're still here, we have a valid mapping */
1174 return TRUE;
1175}
1176
1185static
1186INT
1187WINAPI
1189 DWORD Flags,
1190 LPCWSTR WideCharString,
1191 INT WideCharCount,
1193 INT MultiByteCount,
1194 LPCSTR DefaultChar,
1195 LPBOOL UsedDefaultChar)
1196{
1197 PCODEPAGE_ENTRY CodePageEntry;
1199 INT TempLength;
1200
1201 /* Get code page table. */
1202 CodePageEntry = IntGetCodePageEntry(CodePage);
1203 if (CodePageEntry == NULL)
1204 {
1206 return 0;
1207 }
1208
1209 CodePageTable = &CodePageEntry->CodePageTable;
1210
1211
1212 /* Different handling for DBCS code pages. */
1214 {
1215 /* If Flags, DefaultChar or UsedDefaultChar were given, we have to do some more work */
1216 if (Flags || DefaultChar || UsedDefaultChar)
1217 {
1218 BOOL TempUsedDefaultChar;
1219 USHORT DefChar;
1220
1221 /* If UsedDefaultChar is not set, set it to a temporary value, so we don't have
1222 to check on every character */
1223 if (!UsedDefaultChar)
1224 UsedDefaultChar = &TempUsedDefaultChar;
1225
1226 *UsedDefaultChar = FALSE;
1227
1228 /* Use the CodePage's TransDefaultChar if none was given. Don't modify the DefaultChar pointer here. */
1229 if (DefaultChar)
1230 DefChar = DefaultChar[1] ? ((DefaultChar[0] << 8) | DefaultChar[1]) : DefaultChar[0];
1231 else
1233
1234 /* Does caller query for output buffer size? */
1235 if (!MultiByteCount)
1236 {
1237 for (TempLength = 0; WideCharCount; WideCharCount--, WideCharString++, TempLength++)
1238 {
1239 USHORT uChar;
1240
1241 if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1242 {
1243 /* FIXME: Handle WC_COMPOSITECHECK */
1244 DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1245 }
1246
1247 uChar = ((PUSHORT) CodePageTable->WideCharTable)[*WideCharString];
1248
1249 /* Verify if the mapping is valid for handling DefaultChar and UsedDefaultChar */
1250 if (!IntIsValidDBCSMapping(CodePageTable, Flags, *WideCharString, uChar))
1251 {
1252 uChar = DefChar;
1253 *UsedDefaultChar = TRUE;
1254 }
1255
1256 /* Increment TempLength again if this is a double-byte character */
1257 if (uChar & 0xff00)
1258 TempLength++;
1259 }
1260
1261 return TempLength;
1262 }
1263
1264 /* Convert the WideCharString to the MultiByteString and verify if the mapping is valid */
1265 for (TempLength = MultiByteCount;
1266 WideCharCount && TempLength;
1267 TempLength--, WideCharString++, WideCharCount--)
1268 {
1269 USHORT uChar;
1270
1271 if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1272 {
1273 /* FIXME: Handle WC_COMPOSITECHECK */
1274 DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1275 }
1276
1277 uChar = ((PUSHORT)CodePageTable->WideCharTable)[*WideCharString];
1278
1279 /* Verify if the mapping is valid for handling DefaultChar and UsedDefaultChar */
1280 if (!IntIsValidDBCSMapping(CodePageTable, Flags, *WideCharString, uChar))
1281 {
1282 uChar = DefChar;
1283 *UsedDefaultChar = TRUE;
1284 }
1285
1286 /* Handle double-byte characters */
1287 if (uChar & 0xff00)
1288 {
1289 /* Don't output a partial character */
1290 if (TempLength == 1)
1291 break;
1292
1293 TempLength--;
1294 *MultiByteString++ = uChar >> 8;
1295 }
1296
1297 *MultiByteString++ = (char)uChar;
1298 }
1299
1300 /* WideCharCount should be 0 if all characters were converted */
1301 if (WideCharCount)
1302 {
1304 return 0;
1305 }
1306
1307 return MultiByteCount - TempLength;
1308 }
1309
1310 /* Does caller query for output buffer size? */
1311 if (!MultiByteCount)
1312 {
1313 for (TempLength = 0; WideCharCount; WideCharCount--, WideCharString++, TempLength++)
1314 {
1315 /* Increment TempLength again if this is a double-byte character */
1316 if (((PWCHAR)CodePageTable->WideCharTable)[*WideCharString] & 0xff00)
1317 TempLength++;
1318 }
1319
1320 return TempLength;
1321 }
1322
1323 /* Convert the WideCharString to the MultiByteString */
1324 for (TempLength = MultiByteCount;
1325 WideCharCount && TempLength;
1326 TempLength--, WideCharString++, WideCharCount--)
1327 {
1328 USHORT uChar = ((PUSHORT) CodePageTable->WideCharTable)[*WideCharString];
1329
1330 /* Is this a double-byte character? */
1331 if (uChar & 0xff00)
1332 {
1333 /* Don't output a partial character */
1334 if (TempLength == 1)
1335 break;
1336
1337 TempLength--;
1338 *MultiByteString++ = uChar >> 8;
1339 }
1340
1341 *MultiByteString++ = (char)uChar;
1342 }
1343
1344 /* WideCharCount should be 0 if all characters were converted */
1345 if (WideCharCount)
1346 {
1348 return 0;
1349 }
1350
1351 return MultiByteCount - TempLength;
1352 }
1353 else /* SBCS code page */
1354 {
1355 INT nReturn;
1356
1357 /* If Flags, DefaultChar or UsedDefaultChar were given, we have to do some more work */
1358 if (Flags || DefaultChar || UsedDefaultChar)
1359 {
1360 BOOL TempUsedDefaultChar;
1361 CHAR DefChar;
1362
1363 /* If UsedDefaultChar is not set, set it to a temporary value, so we don't have
1364 to check on every character */
1365 if (!UsedDefaultChar)
1366 UsedDefaultChar = &TempUsedDefaultChar;
1367
1368 *UsedDefaultChar = FALSE;
1369
1370 /* Does caller query for output buffer size? */
1371 if (!MultiByteCount)
1372 {
1373 /* Loop through the whole WideCharString and check if we can get a valid mapping for each character */
1374 for (TempLength = 0; WideCharCount; TempLength++, WideCharString++, WideCharCount--)
1375 {
1376 if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1377 {
1378 /* FIXME: Handle WC_COMPOSITECHECK */
1379 DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1380 }
1381
1382 if (!*UsedDefaultChar)
1383 *UsedDefaultChar = !IntIsValidSBCSMapping(CodePageTable,
1384 Flags,
1385 *WideCharString,
1386 ((PCHAR)CodePageTable->WideCharTable)[*WideCharString]);
1387 }
1388
1389 return TempLength;
1390 }
1391
1392 /* Use the CodePage's TransDefaultChar if none was given. Don't modify the DefaultChar pointer here. */
1393 if (DefaultChar)
1394 DefChar = *DefaultChar;
1395 else
1397
1398 /* Convert the WideCharString to the MultiByteString and verify if the mapping is valid */
1399 for (TempLength = MultiByteCount;
1400 WideCharCount && TempLength;
1401 MultiByteString++, TempLength--, WideCharString++, WideCharCount--)
1402 {
1403 if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1404 {
1405 /* FIXME: Handle WC_COMPOSITECHECK */
1406 DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1407 }
1408
1409 *MultiByteString = ((PCHAR)CodePageTable->WideCharTable)[*WideCharString];
1410
1411 if (!IntIsValidSBCSMapping(CodePageTable, Flags, *WideCharString, *MultiByteString))
1412 {
1413 *MultiByteString = DefChar;
1414 *UsedDefaultChar = TRUE;
1415 }
1416 }
1417
1418 /* WideCharCount should be 0 if all characters were converted */
1419 if (WideCharCount)
1420 {
1422 return 0;
1423 }
1424
1425 return MultiByteCount - TempLength;
1426 }
1427
1428 /* Does caller query for output buffer size? */
1429 if (!MultiByteCount)
1430 return WideCharCount;
1431
1432 /* Is the buffer large enough? */
1433 if (MultiByteCount < WideCharCount)
1434 {
1435 /* Convert the string up to MultiByteCount and return 0 */
1436 WideCharCount = MultiByteCount;
1438 nReturn = 0;
1439 }
1440 else
1441 {
1442 /* Otherwise WideCharCount will be the number of converted characters */
1443 nReturn = WideCharCount;
1444 }
1445
1446 /* Convert the WideCharString to the MultiByteString */
1447 for (TempLength = WideCharCount; --TempLength >= 0; WideCharString++, MultiByteString++)
1448 {
1449 *MultiByteString = ((PCHAR)CodePageTable->WideCharTable)[*WideCharString];
1450 }
1451
1452 return nReturn;
1453 }
1454}
1455
1463static BOOL
1464WINAPI
1466{
1467 UINT i;
1468
1469 if (TableInfo->MaximumCharacterSize == 2)
1470 {
1471 for (i = 0; i < MAXIMUM_LEADBYTES && TableInfo->LeadByte[i]; i += 2)
1472 {
1473 if (Byte >= TableInfo->LeadByte[i] && Byte <= TableInfo->LeadByte[i+1])
1474 return TRUE;
1475 }
1476 }
1477
1478 return FALSE;
1479}
1480
1481/* PUBLIC FUNCTIONS ***********************************************************/
1482
1510BOOL
1511WINAPI
1513 UINT Base,
1514 ULONG Unknown,
1515 LPSTR BaseName,
1516 LPSTR Result,
1517 ULONG ResultSize)
1518{
1519 CHAR Integer[11];
1520
1521 if (!NT_SUCCESS(RtlIntegerToChar(CodePage, Base, sizeof(Integer), Integer)))
1522 return FALSE;
1523
1524 /*
1525 * If the name including the terminating NULL character doesn't
1526 * fit in the output buffer then fail.
1527 */
1528 if (strlen(Integer) + strlen(BaseName) >= ResultSize)
1529 return FALSE;
1530
1531 lstrcpyA(Result, BaseName);
1532 lstrcatA(Result, Integer);
1533
1534 return TRUE;
1535}
1536
1555BOOL
1556WINAPI
1558{
1559 WCHAR ValueNameBuffer[11];
1565 DWORD KvpiSize;
1566 BOOL bRetValue;
1567
1568 bRetValue = FALSE;
1569
1570 /* Convert the codepage number to string. */
1571 ValueName.Buffer = ValueNameBuffer;
1572 ValueName.MaximumLength = sizeof(ValueNameBuffer);
1573
1574 if (!NT_SUCCESS(RtlIntegerToUnicodeString(CodePage, 10, &ValueName)))
1575 return bRetValue;
1576
1577 /* Open the registry key containing file name mappings. */
1578 RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System\\"
1579 L"CurrentControlSet\\Control\\Nls\\CodePage");
1581 NULL, NULL);
1583 if (!NT_SUCCESS(Status))
1584 {
1585 return bRetValue;
1586 }
1587
1588 /* Allocate buffer that will be used to query the value data. */
1589 KvpiSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + (MAX_PATH * sizeof(WCHAR));
1590 Kvpi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, KvpiSize);
1591 if (Kvpi == NULL)
1592 {
1594 return bRetValue;
1595 }
1596
1597 /* Query the file name for our code page. */
1599 Kvpi, KvpiSize, &KvpiSize);
1600
1602
1603 /* Check if we succeded and the value is non-empty string. */
1604 if (NT_SUCCESS(Status) && Kvpi->Type == REG_SZ &&
1605 Kvpi->DataLength > sizeof(WCHAR))
1606 {
1607 bRetValue = TRUE;
1608 if (FileName != NULL)
1609 {
1610 lstrcpynW(FileName, (WCHAR*)Kvpi->Data,
1611 min(Kvpi->DataLength / sizeof(WCHAR), FileNameSize));
1612 }
1613 }
1614
1615 /* free temporary buffer */
1616 HeapFree(GetProcessHeap(),0,Kvpi);
1617 return bRetValue;
1618}
1619
1631BOOL
1632WINAPI
1634{
1635 if (CodePage == 0) return FALSE;
1636 if (CodePage == CP_UTF8 || CodePage == CP_UTF7)
1637 return TRUE;
1638 if (IntGetLoadedCodePageEntry(CodePage))
1639 return TRUE;
1640 return GetCPFileNameFromRegistry(CodePage, NULL, 0);
1641}
1642
1643static inline BOOL utf7_write_w(WCHAR *dst, int dstlen, int *index, WCHAR character)
1644{
1645 if (dstlen > 0)
1646 {
1647 if (*index >= dstlen)
1648 return FALSE;
1649
1650 dst[*index] = character;
1651 }
1652
1653 (*index)++;
1654
1655 return TRUE;
1656}
1657
1658static INT Utf7ToWideChar(const char *src, int srclen, WCHAR *dst, int dstlen)
1659{
1660 static const signed char base64_decoding_table[] =
1661 {
1662 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00-0x0F */
1663 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10-0x1F */
1664 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20-0x2F */
1665 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30-0x3F */
1666 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40-0x4F */
1667 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50-0x5F */
1668 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60-0x6F */
1669 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 /* 0x70-0x7F */
1670 };
1671
1672 const char *source_end = src + srclen;
1673 int dest_index = 0;
1674
1675 DWORD byte_pair = 0;
1676 short offset = 0;
1677
1678 while (src < source_end)
1679 {
1680 if (*src == '+')
1681 {
1682 src++;
1683 if (src >= source_end)
1684 break;
1685
1686 if (*src == '-')
1687 {
1688 /* just a plus sign escaped as +- */
1689 if (!utf7_write_w(dst, dstlen, &dest_index, '+'))
1690 {
1692 return 0;
1693 }
1694 src++;
1695 continue;
1696 }
1697
1698 do
1699 {
1700 signed char sextet = *src;
1701 if (sextet == '-')
1702 {
1703 /* skip over the dash and end base64 decoding
1704 * the current, unfinished byte pair is discarded */
1705 src++;
1706 offset = 0;
1707 break;
1708 }
1709 if (sextet < 0)
1710 {
1711 /* the next character of src is < 0 and therefore not part of a base64 sequence
1712 * the current, unfinished byte pair is NOT discarded in this case
1713 * this is probably a bug in Windows */
1714 break;
1715 }
1716
1717 sextet = base64_decoding_table[sextet];
1718 if (sextet == -1)
1719 {
1720 /* -1 means that the next character of src is not part of a base64 sequence
1721 * in other words, all sextets in this base64 sequence have been processed
1722 * the current, unfinished byte pair is discarded */
1723 offset = 0;
1724 break;
1725 }
1726
1727 byte_pair = (byte_pair << 6) | sextet;
1728 offset += 6;
1729
1730 if (offset >= 16)
1731 {
1732 /* this byte pair is done */
1733 if (!utf7_write_w(dst, dstlen, &dest_index, (byte_pair >> (offset - 16)) & 0xFFFF))
1734 {
1736 return 0;
1737 }
1738 offset -= 16;
1739 }
1740
1741 src++;
1742 }
1743 while (src < source_end);
1744 }
1745 else
1746 {
1747 /* we have to convert to unsigned char in case *src < 0 */
1748 if (!utf7_write_w(dst, dstlen, &dest_index, (unsigned char)*src))
1749 {
1751 return 0;
1752 }
1753 src++;
1754 }
1755 }
1756
1757 return dest_index;
1758}
1759
1790INT
1791WINAPI
1793 DWORD Flags,
1795 INT MultiByteCount,
1796 LPWSTR WideCharString,
1797 INT WideCharCount)
1798{
1799 /* Check the parameters. */
1800 if (MultiByteString == NULL ||
1801 MultiByteCount == 0 || WideCharCount < 0 ||
1802 (WideCharCount && (WideCharString == NULL ||
1803 (PVOID)MultiByteString == (PVOID)WideCharString)))
1804 {
1806 return 0;
1807 }
1808
1809 /* Determine the input string length. */
1810 if (MultiByteCount < 0)
1811 {
1812 MultiByteCount = lstrlenA(MultiByteString) + 1;
1813 }
1814
1815 switch (CodePage)
1816 {
1817 case CP_UTF8:
1820 MultiByteCount,
1821 WideCharString,
1822 WideCharCount);
1823
1824 case CP_UTF7:
1825 if (Flags)
1826 {
1828 return 0;
1829 }
1830 return Utf7ToWideChar(MultiByteString, MultiByteCount,
1831 WideCharString, WideCharCount);
1832
1833 case CP_SYMBOL:
1836 MultiByteCount,
1837 WideCharString,
1838 WideCharCount);
1839 default:
1840 return IntMultiByteToWideCharCP(CodePage,
1841 Flags,
1843 MultiByteCount,
1844 WideCharString,
1845 WideCharCount);
1846 }
1847}
1848
1849static inline BOOL utf7_can_directly_encode(WCHAR codepoint)
1850{
1851 static const BOOL directly_encodable_table[] =
1852 {
1853 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, /* 0x00 - 0x0F */
1854 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1F */
1855 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* 0x20 - 0x2F */
1856 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x30 - 0x3F */
1857 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4F */
1858 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x50 - 0x5F */
1859 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6F */
1860 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* 0x70 - 0x7A */
1861 };
1862
1863 return codepoint <= 0x7A ? directly_encodable_table[codepoint] : FALSE;
1864}
1865
1866static inline BOOL utf7_write_c(char *dst, int dstlen, int *index, char character)
1867{
1868 if (dstlen > 0)
1869 {
1870 if (*index >= dstlen)
1871 return FALSE;
1872
1873 dst[*index] = character;
1874 }
1875
1876 (*index)++;
1877
1878 return TRUE;
1879}
1880
1881static INT WideCharToUtf7(const WCHAR *src, int srclen, char *dst, int dstlen)
1882{
1883 static const char base64_encoding_table[] =
1884 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1885
1886 const WCHAR *source_end = src + srclen;
1887 int dest_index = 0;
1888
1889 while (src < source_end)
1890 {
1891 if (*src == '+')
1892 {
1893 if (!utf7_write_c(dst, dstlen, &dest_index, '+'))
1894 {
1896 return 0;
1897 }
1898 if (!utf7_write_c(dst, dstlen, &dest_index, '-'))
1899 {
1901 return 0;
1902 }
1903 src++;
1904 }
1905 else if (utf7_can_directly_encode(*src))
1906 {
1907 if (!utf7_write_c(dst, dstlen, &dest_index, *src))
1908 {
1910 return 0;
1911 }
1912 src++;
1913 }
1914 else
1915 {
1916 unsigned int offset = 0;
1917 DWORD byte_pair = 0;
1918
1919 if (!utf7_write_c(dst, dstlen, &dest_index, '+'))
1920 {
1922 return 0;
1923 }
1924
1925 while (src < source_end && !utf7_can_directly_encode(*src))
1926 {
1927 byte_pair = (byte_pair << 16) | *src;
1928 offset += 16;
1929 while (offset >= 6)
1930 {
1931 if (!utf7_write_c(dst, dstlen, &dest_index, base64_encoding_table[(byte_pair >> (offset - 6)) & 0x3F]))
1932 {
1934 return 0;
1935 }
1936 offset -= 6;
1937 }
1938 src++;
1939 }
1940
1941 if (offset)
1942 {
1943 /* Windows won't create a padded base64 character if there's no room for the - sign
1944 * as well ; this is probably a bug in Windows */
1945 if (dstlen > 0 && dest_index + 1 >= dstlen)
1946 {
1948 return 0;
1949 }
1950
1951 byte_pair <<= (6 - offset);
1952 if (!utf7_write_c(dst, dstlen, &dest_index, base64_encoding_table[byte_pair & 0x3F]))
1953 {
1955 return 0;
1956 }
1957 }
1958
1959 /* Windows always explicitly terminates the base64 sequence
1960 even though RFC 2152 (page 3, rule 2) does not require this */
1961 if (!utf7_write_c(dst, dstlen, &dest_index, '-'))
1962 {
1964 return 0;
1965 }
1966 }
1967 }
1968
1969 return dest_index;
1970}
1971
1972/*
1973 * A function similar to LoadStringW, but adapted for usage by GetCPInfoExW
1974 * and GetGeoInfoW. It uses the current user localization, otherwise falls back
1975 * to English (US). Contrary to LoadStringW which always saves the loaded string
1976 * into the user-given buffer, truncating the string if needed, this function
1977 * returns instead an ERROR_INSUFFICIENT_BUFFER error code if the user buffer
1978 * is not large enough.
1979 */
1980UINT
1982 IN UINT uID,
1984 IN UINT cchDest,
1985 IN LANGID lang)
1986{
1987 HRSRC hrsrc;
1988 HGLOBAL hmem;
1989 LCID lcid;
1990 LANGID langId;
1991 const WCHAR *p;
1992 UINT i;
1993
1994 /* See HACK in winnls/lang/xx-XX.rc files */
1995 if (uID == 37)
1996 uID = uID * 100;
1997
1999
2000 langId = LANGIDFROMLCID(lcid);
2001
2002 if (PRIMARYLANGID(langId) == LANG_NEUTRAL)
2004
2007 MAKEINTRESOURCEW((uID >> 4) + 1),
2008 langId);
2009
2010 /* English fallback */
2011 if (!hrsrc)
2012 {
2015 MAKEINTRESOURCEW((uID >> 4) + 1),
2017 }
2018
2019 if (!hrsrc)
2020 goto NotFound;
2021
2022 hmem = LoadResource(hCurrentModule, hrsrc);
2023 if (!hmem)
2024 goto NotFound;
2025
2026 p = LockResource(hmem);
2027
2028 for (i = 0; i < (uID & 0x0F); i++)
2029 p += *p + 1;
2030
2031 /* Needed for GetGeoInfo(): return the needed string size including the NULL terminator */
2032 if (cchDest == 0)
2033 return *p + 1;
2034 /* Needed for GetGeoInfo(): bail out if the user buffer is not large enough */
2035 if (*p + 1 > cchDest)
2036 {
2038 return 0;
2039 }
2040
2041 i = *p;
2042 if (i > 0)
2043 {
2044 memcpy(lpszDest, p + 1, i * sizeof(WCHAR));
2045 lpszDest[i] = L'\0';
2046 return i;
2047 }
2048#if 0
2049 else
2050 {
2051 if (cchDest >= 1)
2052 lpszDest[0] = L'\0';
2053 /* Fall-back */
2054 }
2055#endif
2056
2057NotFound:
2058 DPRINT1("Resource not found: uID = %lu\n", uID);
2060 return 0;
2061}
2062
2063/*
2064 * @implemented
2065 */
2066BOOL
2067WINAPI
2069 LPCPINFO CodePageInfo)
2070{
2071 PCODEPAGE_ENTRY CodePageEntry;
2072
2073 if (!CodePageInfo)
2074 {
2076 return FALSE;
2077 }
2078
2079 CodePageEntry = IntGetCodePageEntry(CodePage);
2080 if (CodePageEntry == NULL)
2081 {
2082 switch(CodePage)
2083 {
2084 case CP_UTF7:
2085 case CP_UTF8:
2086 RtlZeroMemory(CodePageInfo, sizeof(*CodePageInfo));
2087 CodePageInfo->DefaultChar[0] = 0x3f;
2088 CodePageInfo->DefaultChar[1] = 0;
2089 CodePageInfo->LeadByte[0] = CodePageInfo->LeadByte[1] = 0;
2090 CodePageInfo->MaxCharSize = (CodePage == CP_UTF7) ? 5 : 4;
2091 return TRUE;
2092 }
2093
2094 DPRINT1("Invalid CP!: %lx\n", CodePage);
2096 return FALSE;
2097 }
2098
2099 RtlZeroMemory(CodePageInfo, sizeof(*CodePageInfo));
2100 if (CodePageEntry->CodePageTable.DefaultChar & 0xff00)
2101 {
2102 CodePageInfo->DefaultChar[0] = (CodePageEntry->CodePageTable.DefaultChar & 0xff00) >> 8;
2103 CodePageInfo->DefaultChar[1] = CodePageEntry->CodePageTable.DefaultChar & 0x00ff;
2104 }
2105 else
2106 {
2107 CodePageInfo->DefaultChar[0] = CodePageEntry->CodePageTable.DefaultChar & 0xff;
2108 CodePageInfo->DefaultChar[1] = 0;
2109 }
2110
2111 if ((CodePageInfo->MaxCharSize = CodePageEntry->CodePageTable.MaximumCharacterSize) == 2)
2112 memcpy(CodePageInfo->LeadByte, CodePageEntry->CodePageTable.LeadByte, sizeof(CodePageInfo->LeadByte));
2113 else
2114 CodePageInfo->LeadByte[0] = CodePageInfo->LeadByte[1] = 0;
2115
2116 return TRUE;
2117}
2118
2119/*
2120 * @implemented
2121 */
2122BOOL
2123WINAPI
2125 DWORD dwFlags,
2126 LPCPINFOEXW lpCPInfoEx)
2127{
2128 if (!GetCPInfo(CodePage, (LPCPINFO)lpCPInfoEx))
2129 return FALSE;
2130
2131 switch(CodePage)
2132 {
2133 case CP_UTF7:
2134 {
2135 lpCPInfoEx->CodePage = CP_UTF7;
2136 lpCPInfoEx->UnicodeDefaultChar = 0x3f;
2137 return GetLocalisedText(lpCPInfoEx->CodePage,
2138 lpCPInfoEx->CodePageName,
2139 ARRAYSIZE(lpCPInfoEx->CodePageName),
2140 GetThreadLocale()) != 0;
2141 }
2142 break;
2143
2144 case CP_UTF8:
2145 {
2146 lpCPInfoEx->CodePage = CP_UTF8;
2147 lpCPInfoEx->UnicodeDefaultChar = 0x3f;
2148 return GetLocalisedText(lpCPInfoEx->CodePage,
2149 lpCPInfoEx->CodePageName,
2150 ARRAYSIZE(lpCPInfoEx->CodePageName),
2151 GetThreadLocale()) != 0;
2152 }
2153
2154 default:
2155 {
2156 PCODEPAGE_ENTRY CodePageEntry;
2157
2158 CodePageEntry = IntGetCodePageEntry(CodePage);
2159 if (CodePageEntry == NULL)
2160 {
2161 DPRINT1("Could not get CodePage Entry! CodePageEntry = NULL\n");
2163 return FALSE;
2164 }
2165
2166 lpCPInfoEx->CodePage = CodePageEntry->CodePageTable.CodePage;
2167 lpCPInfoEx->UnicodeDefaultChar = CodePageEntry->CodePageTable.UniDefaultChar;
2168 return GetLocalisedText(lpCPInfoEx->CodePage,
2169 lpCPInfoEx->CodePageName,
2170 ARRAYSIZE(lpCPInfoEx->CodePageName),
2171 GetThreadLocale()) != 0;
2172 }
2173 break;
2174 }
2175}
2176
2177
2178/*
2179 * @implemented
2180 */
2181BOOL
2182WINAPI
2184 DWORD dwFlags,
2185 LPCPINFOEXA lpCPInfoEx)
2186{
2187 CPINFOEXW CPInfo;
2188
2189 if (!GetCPInfoExW(CodePage, dwFlags, &CPInfo))
2190 return FALSE;
2191
2192 /* the layout is the same except for CodePageName */
2193 memcpy(lpCPInfoEx, &CPInfo, sizeof(CPINFOEXA));
2194
2196 0,
2197 CPInfo.CodePageName,
2198 -1,
2199 lpCPInfoEx->CodePageName,
2200 sizeof(lpCPInfoEx->CodePageName),
2201 NULL,
2202 NULL);
2203 return TRUE;
2204}
2205
2245INT
2246WINAPI
2248 DWORD Flags,
2249 LPCWSTR WideCharString,
2250 INT WideCharCount,
2252 INT MultiByteCount,
2253 LPCSTR DefaultChar,
2254 LPBOOL UsedDefaultChar)
2255{
2256 /* Check the parameters. */
2257 if (WideCharString == NULL ||
2258 WideCharCount == 0 ||
2259 (MultiByteString == NULL && MultiByteCount > 0) ||
2260 (PVOID)WideCharString == (PVOID)MultiByteString ||
2261 MultiByteCount < 0)
2262 {
2264 return 0;
2265 }
2266
2267 /* Determine the input string length. */
2268 if (WideCharCount < 0)
2269 {
2270 WideCharCount = lstrlenW(WideCharString) + 1;
2271 }
2272
2273 switch (CodePage)
2274 {
2275 case CP_UTF8:
2276 if (DefaultChar != NULL || UsedDefaultChar != NULL)
2277 {
2279 return 0;
2280 }
2281 return IntWideCharToMultiByteUTF8(CodePage,
2282 Flags,
2283 WideCharString,
2284 WideCharCount,
2286 MultiByteCount,
2287 DefaultChar,
2288 UsedDefaultChar);
2289
2290 case CP_UTF7:
2291 if (DefaultChar != NULL || UsedDefaultChar != NULL)
2292 {
2294 return 0;
2295 }
2296 if (Flags)
2297 {
2299 return 0;
2300 }
2301 return WideCharToUtf7(WideCharString, WideCharCount,
2302 MultiByteString, MultiByteCount);
2303
2304 case CP_SYMBOL:
2305 if ((DefaultChar!=NULL) || (UsedDefaultChar!=NULL))
2306 {
2308 return 0;
2309 }
2311 WideCharString,
2312 WideCharCount,
2314 MultiByteCount);
2315
2316 default:
2317 return IntWideCharToMultiByteCP(CodePage,
2318 Flags,
2319 WideCharString,
2320 WideCharCount,
2322 MultiByteCount,
2323 DefaultChar,
2324 UsedDefaultChar);
2325 }
2326}
2327
2336UINT
2337WINAPI
2339{
2341}
2342
2351UINT
2352WINAPI
2354{
2356}
2357
2366BOOL
2367WINAPI
2368IsDBCSLeadByteEx(UINT CodePage, BYTE TestByte)
2369{
2370 PCODEPAGE_ENTRY CodePageEntry;
2371
2372 CodePageEntry = IntGetCodePageEntry(CodePage);
2373 if (CodePageEntry != NULL)
2374 return IntIsLeadByte(&CodePageEntry->CodePageTable, TestByte);
2375
2377 return FALSE;
2378}
2379
2388BOOL
2389WINAPI
2391{
2392 return IntIsLeadByte(&AnsiCodePage.CodePageTable, TestByte);
2393}
2394
2423WINAPI
2428{
2431 PSID WorldSid;
2432 PACL Dacl;
2434
2436 {
2437 DPRINT1("Security descriptor size too small\n");
2439 }
2440
2441 /* Create the World SID */
2443 1,
2445 0, 0, 0, 0, 0, 0, 0,
2446 &WorldSid);
2447 if (!NT_SUCCESS(Status))
2448 {
2449 DPRINT1("Failed to create World SID (Status 0x%08x)\n", Status);
2450 return Status;
2451 }
2452
2453 /* Initialize the security descriptor */
2456 if (!NT_SUCCESS(Status))
2457 {
2458 DPRINT1("Failed to create security descriptor (Status 0x%08x)\n", Status);
2459 goto Quit;
2460 }
2461
2462 /* The DACL follows the security descriptor, and includes the World SID */
2465
2466 /* Create the DACL */
2468 if (!NT_SUCCESS(Status))
2469 {
2470 DPRINT1("Failed to create DACL (Status 0x%08x)\n", Status);
2471 goto Quit;
2472 }
2473
2474 /* Add an allowed access ACE to the World SID */
2476 if (!NT_SUCCESS(Status))
2477 {
2478 DPRINT1("Failed to add allowed access ACE for World SID (Status 0x%08x)\n", Status);
2479 goto Quit;
2480 }
2481
2482 /* Set the DACL to the descriptor */
2484 if (!NT_SUCCESS(Status))
2485 {
2486 DPRINT1("Failed to set DACL into descriptor (Status 0x%08x)\n", Status);
2487 goto Quit;
2488 }
2489
2490Quit:
2492 return Status;
2493}
2494
2495/*
2496 * @unimplemented
2497 */
2499{
2500 STUB;
2501 return 0;
2502}
2503
2504/*
2505 * @unimplemented
2506 */
2508{
2509 STUB;
2510}
2511
2512/*
2513 * @unimplemented
2514 */
2516{
2517 STUB;
2518 return 0;
2519}
2520
2521/*
2522 * @unimplemented
2523 */
2524BOOL
2525WINAPI
2526ValidateLCType(int a1, unsigned int a2, int a3, int a4)
2527{
2528 STUB;
2529 return FALSE;
2530}
2531
2532/*
2533 * @unimplemented
2534 */
2535BOOL
2536WINAPI
2538{
2539 STUB;
2540 return TRUE;
2541}
2542
2543/*
2544 * @unimplemented
2545 */
2546VOID
2547WINAPI
2549{
2550 STUB;
2551 lpUnknown = NULL;
2552}
2553
2554/*
2555 * @unimplemented
2556 */
2557VOID
2558WINAPI
2560{
2561 STUB;
2562 lpUnknown = NULL;
2563}
2564
2565/*
2566 * @unimplemented
2567 */
2568BOOL
2569WINAPI
2571{
2572 STUB;
2573 return TRUE;
2574}
2575
2576/*
2577 * @unimplemented
2578 */
2579ULONG
2580WINAPI
2582{
2583 STUB;
2584 return 0;
2585}
2586
2587/*
2588 * @unimplemented
2589 */
2590BOOL
2591WINAPI
2595 IN LPCWSTR lpString,
2596 IN INT cchStr)
2597{
2598 STUB;
2599 return TRUE;
2600}
2601
2602/*
2603 * @unimplemented
2604 */
2605BOOL
2606WINAPI
2608 IN LCID Locale,
2610{
2611 STUB;
2612 return TRUE;
2613}
2614
2615/*
2616 * @unimplemented
2617 */
2618BOOL
2619WINAPI
2621 IN LPCWSTR lpLocaleName,
2623{
2624 STUB;
2625 return TRUE;
2626}
2627
2628/* EOF */
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:3083
NTSTATUS NTAPI NtOpenSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: section.c:3211
WCHAR lpszDest[260]
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
#define index(s, c)
Definition: various.h:29
#define DPRINT1
Definition: precomp.h:8
PSID WorldSid
Definition: globals.c:15
#define CHAR(Char)
static SID_IDENTIFIER_AUTHORITY NtAuthority
Definition: security.c:40
#define NLS_SIZEOF_ACE_AND_SIDS(n)
Definition: base.h:26
#define NLS_SECTION_SECURITY_DESCRIPTOR_SIZE
Definition: base.h:31
_In_ PFCB _In_ PCD_NAME DirName
Definition: cdprocs.h:737
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define PAGE_READONLY
Definition: compat.h:138
#define SECTION_MAP_READ
Definition: compat.h:139
#define UnmapViewOfFile
Definition: compat.h:746
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CreateFileW
Definition: compat.h:741
#define FILE_MAP_READ
Definition: compat.h:776
#define WideCharToMultiByte
Definition: compat.h:111
#define MapViewOfFile
Definition: compat.h:745
#define MultiByteToWideChar
Definition: compat.h:110
#define FILE_SHARE_READ
Definition: compat.h:136
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
unsigned char Byte
Definition: zlib.h:37
HMODULE hCurrentModule
Definition: dllmain.c:25
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2232
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
HRSRC WINAPI FindResourceExW(HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD lang)
Definition: res.c:164
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
LCID WINAPI GetThreadLocale(void)
Definition: locale.c:2803
UINT WINAPI GetACP(void)
Definition: locale.c:2023
UINT WINAPI GetOEMCP(void)
Definition: locale.c:2062
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: locale.c:1675
LCID WINAPI ConvertDefaultLocale(LCID lcid)
Definition: locale.c:2879
static INT WINAPI IntWideCharToMultiByteCP(UINT CodePage, DWORD Flags, LPCWSTR WideCharString, INT WideCharCount, LPSTR MultiByteString, INT MultiByteCount, LPCSTR DefaultChar, LPBOOL UsedDefaultChar)
Definition: nls.c:1188
BOOL WINAPI GetNLSVersion(IN NLS_FUNCTION Function, IN LCID Locale, IN OUT LPNLSVERSIONINFO lpVersionInformation)
Definition: nls.c:2607
static BOOL IntIsValidSBCSMapping(PCPTABLEINFO CodePageTable, DWORD Flags, WCHAR wch, UCHAR ch)
Definition: nls.c:1131
static const char UTF8Length[128]
Definition: nls.c:25
static BOOL utf7_can_directly_encode(WCHAR codepoint)
Definition: nls.c:1849
BOOL WINAPI GetCPInfo(UINT CodePage, LPCPINFO CodePageInfo)
Definition: nls.c:2068
VOID FASTCALL NlsUninit(VOID)
Definition: nls.c:223
BOOL WINAPI IsNLSDefinedString(IN NLS_FUNCTION Function, IN DWORD dwFlags, IN LPNLSVERSIONINFO lpVersionInformation, IN LPCWSTR lpString, IN INT cchStr)
Definition: nls.c:2592
VOID WINAPI NlsConvertIntegerToString(ULONG Value, ULONG Base, ULONG strsize, LPWSTR str, ULONG strsize2)
Definition: nls.c:2507
static INT WideCharToUtf7(const WCHAR *src, int srclen, char *dst, int dstlen)
Definition: nls.c:1881
BOOL WINAPI IsDBCSLeadByteEx(UINT CodePage, BYTE TestByte)
Definition: nls.c:2368
static BOOL utf7_write_c(char *dst, int dstlen, int *index, char character)
Definition: nls.c:1866
BOOL WINAPI ValidateLCType(int a1, unsigned int a2, int a3, int a4)
Definition: nls.c:2526
PCODEPAGE_ENTRY FASTCALL IntGetCodePageEntry(UINT CodePage)
Definition: nls.c:293
UINT GetLocalisedText(IN UINT uID, IN LPWSTR lpszDest, IN UINT cchDest, IN LANGID lang)
Definition: nls.c:1981
BOOL WINAPI IsValidCodePage(UINT CodePage)
Definition: nls.c:1633
PCODEPAGE_ENTRY FASTCALL IntGetLoadedCodePageEntry(UINT CodePage)
Definition: nls.c:257
BOOL WINAPI GetNLSVersionEx(IN NLS_FUNCTION function, IN LPCWSTR lpLocaleName, IN OUT LPNLSVERSIONINFOEX lpVersionInformation)
Definition: nls.c:2620
static CODEPAGE_ENTRY AnsiCodePage
Definition: nls.c:46
ULONG WINAPI NlsGetCacheUpdateCount(VOID)
Definition: nls.c:2581
static const unsigned long UTF8LBound[]
Definition: nls.c:41
UINT WINAPI SetCPGlobal(UINT CodePage)
Definition: nls.c:2515
static BOOL utf7_write_w(WCHAR *dst, int dstlen, int *index, WCHAR character)
Definition: nls.c:1643
BOOL WINAPI GetNlsSectionName(UINT CodePage, UINT Base, ULONG Unknown, LPSTR BaseName, LPSTR Result, ULONG ResultSize)
Definition: nls.c:1512
NTSTATUS WINAPI CreateNlsSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ SIZE_T DescriptorSize, _In_ ULONG AccessMask)
Creates a security descriptor for each NLS section. Typically used by BASESRV to give Everyone (World...
Definition: nls.c:2424
BOOL WINAPI IsValidUILanguage(LANGID langid)
Definition: nls.c:2498
BOOL FASTCALL NlsInit(VOID)
Definition: nls.c:151
static INT WINAPI IntWideCharToMultiByteUTF8(UINT CodePage, DWORD Flags, LPCWSTR WideCharString, INT WideCharCount, LPSTR MultiByteString, INT MultiByteCount, LPCSTR DefaultChar, LPBOOL UsedDefaultChar)
Definition: nls.c:1002
static RTL_CRITICAL_SECTION CodePageListLock
Definition: nls.c:48
VOID WINAPI GetLinguistLangSize(LPVOID lpUnknown)
Definition: nls.c:2559
BOOL WINAPI ValidateLocale(IN ULONG LocaleId)
Definition: nls.c:2570
static INT Utf7ToWideChar(const char *src, int srclen, WCHAR *dst, int dstlen)
Definition: nls.c:1658
static NTSTATUS CreateNlsDirectorySecurity(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ SIZE_T DescriptorSize)
Creates a security descriptor for the NLS object directory.
Definition: nls.c:81
static BOOL IntIsValidDBCSMapping(PCPTABLEINFO CodePageTable, DWORD Flags, WCHAR wch, USHORT ch)
Definition: nls.c:1154
BOOL WINAPI GetCPFileNameFromRegistry(UINT CodePage, LPWSTR FileName, ULONG FileNameSize)
Definition: nls.c:1557
static INT WINAPI IntMultiByteToWideCharUTF8(DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:494
BOOL WINAPI NlsResetProcessLocale(VOID)
Definition: nls.c:2537
static CODEPAGE_ENTRY OemCodePage
Definition: nls.c:47
static LIST_ENTRY CodePageListHead
Definition: nls.c:45
static BOOL WINAPI IntIsLeadByte(PCPTABLEINFO TableInfo, BYTE Byte)
Definition: nls.c:1465
BOOL WINAPI GetCPInfoExA(UINT CodePage, DWORD dwFlags, LPCPINFOEXA lpCPInfoEx)
Definition: nls.c:2183
BOOL WINAPI GetCPInfoExW(UINT CodePage, DWORD dwFlags, LPCPINFOEXW lpCPInfoEx)
Definition: nls.c:2124
VOID WINAPI GetDefaultSortkeySize(LPVOID lpUnknown)
Definition: nls.c:2548
static INT WINAPI IntWideCharToMultiByteSYMBOL(DWORD Flags, LPCWSTR WideCharString, INT WideCharCount, LPSTR MultiByteString, INT MultiByteCount)
Definition: nls.c:940
static INT WINAPI IntMultiByteToWideCharCP(UINT CodePage, DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:691
BOOL WINAPI IsDBCSLeadByte(BYTE TestByte)
Definition: nls.c:2390
static const unsigned char UTF8Mask[6]
Definition: nls.c:38
static INT WINAPI IntMultiByteToWideCharSYMBOL(DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:885
LCID lcid
Definition: locale.c:5656
unsigned char ch[4][2]
Definition: console.c:118
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
static SID_IDENTIFIER_AUTHORITY WorldAuthority
Definition: security.c:14
unsigned char
Definition: typeof.h:29
#define L(x)
Definition: resources.c:13
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
IN PDCB IN POEM_STRING IN PUNICODE_STRING UnicodeName
Definition: fatprocs.h:1306
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:24
GLenum src
Definition: glext.h:6340
GLintptr offset
Definition: glext.h:5920
GLuint index
Definition: glext.h:6031
GLenum GLenum dst
Definition: glext.h:6340
GLfloat GLfloat p
Definition: glext.h:8902
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 MB_USEGLYPHCHARS
Definition: unicode.h:42
#define MB_ERR_INVALID_CHARS
Definition: unicode.h:41
#define WC_NO_BEST_FIT_CHARS
Definition: unicode.h:46
@ Unknown
Definition: i8042prt.h:114
#define NtCurrentTeb
#define STUB
Definition: kernel32.h:27
#define REG_SZ
Definition: layer.c:22
USHORT LANGID
Definition: mui.h:9
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
BOOL * LPBOOL
Definition: minwindef.h:138
#define PCHAR
Definition: match.c:90
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ASSERT(a)
Definition: mode.c:44
#define MAXIMUM_LEADBYTES
Definition: precomp.h:16
static const struct update_accum a1
Definition: msg.c:534
static const struct update_accum a2
Definition: msg.c:542
static const struct update_accum a3
Definition: msg.c:556
static const struct update_accum a4
Definition: msg.c:2188
static DWORD LPDWORD LPCSTR DWORD srclen
Definition: directory.c:52
static DWORD dstlen
Definition: directory.c:51
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
#define min(a, b)
Definition: monoChain.cc:55
struct _SECURITY_DESCRIPTOR SECURITY_DESCRIPTOR
struct _ACL * PACL
LANGID langid
Definition: msctf.idl:626
unsigned int UINT
Definition: ndis.h:50
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
_In_ ACCESS_MASK AccessMask
Definition: exfuncs.h:186
#define SEC_COMMIT
Definition: mmtypes.h:100
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1625
NTSYSAPI NTSTATUS NTAPI RtlDeleteCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
_Out_ PCPTABLEINFO CodePageTable
Definition: rtlfuncs.h:4319
_In_ BOOLEAN DaclPresent
Definition: rtlfuncs.h:1667
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2486
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI PVOID NTAPI RtlFreeSid(_In_ _Post_invalid_ PSID Sid)
NTSYSAPI NTSTATUS NTAPI RtlIntegerToChar(_In_ ULONG Value, _In_ ULONG Base, _In_ ULONG Length, _Out_ PCHAR String)
NTSYSAPI NTSTATUS NTAPI RtlGetDaclSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Out_ PBOOLEAN DaclPresent, _Out_ PACL *Dacl, _Out_ PBOOLEAN DaclDefaulted)
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG DaclSize
Definition: rtlfuncs.h:1626
_In_ BOOLEAN _In_opt_ PACL _In_opt_ BOOLEAN DaclDefaulted
Definition: rtlfuncs.h:1670
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
int Count
Definition: noreturn.cpp:7
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
#define DIRECTORY_CREATE_OBJECT
Definition: nt_native.h:1259
@ KeyValuePartialInformation
Definition: nt_native.h:1185
#define KEY_READ
Definition: nt_native.h:1026
#define DIRECTORY_TRAVERSE
Definition: nt_native.h:1258
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define FASTCALL
Definition: nt_native.h:50
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)
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
NTSYSAPI NTSTATUS NTAPI RtlIntegerToUnicodeString(ULONG Value, ULONG Base, PUNICODE_STRING String)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1262
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define FILE_GENERIC_READ
Definition: nt_native.h:653
#define LOCALE_SYSTEM_DEFAULT
NTSYSAPI NTSTATUS NTAPI RtlAllocateAndInitializeSid(IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, IN UCHAR SubAuthorityCount, IN ULONG SubAuthority0, IN ULONG SubAuthority1, IN ULONG SubAuthority2, IN ULONG SubAuthority3, IN ULONG SubAuthority4, IN ULONG SubAuthority5, IN ULONG SubAuthority6, IN ULONG SubAuthority7, OUT PSID *Sid)
Definition: sid.c:290
NTSTATUS NTAPI NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:765
#define RT_STRING
Definition: pedump.c:368
BYTE * PBYTE
Definition: pedump.c:66
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
char CHAR
Definition: pedump.c:57
_In_ INT cchDest
Definition: shlwapi.h:1151
_In_ UINT uID
Definition: shlwapi.h:156
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_PERMANENT
Definition: winternl.h:226
for(i=0;i< sizeof(testsuite)/sizeof(testsuite[0]);++i) ok(call_test(testsuite[i].func)
const WCHAR * str
#define LANG_NEUTRAL
Definition: nls.h:22
#define MAKELANGID(p, s)
Definition: nls.h:15
#define LANG_ENGLISH
Definition: nls.h:52
#define LANGIDFROMLCID(l)
Definition: nls.h:18
DWORD LCID
Definition: nls.h:13
#define CP_UTF8
Definition: nls.h:20
#define PRIMARYLANGID(l)
Definition: nls.h:16
#define SUBLANG_ENGLISH_US
Definition: nls.h:222
Entry
Definition: section.c:5216
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define DPRINT
Definition: sndvol32.h:73
Definition: kernel32.h:60
UINT CodePage
Definition: kernel32.h:62
LIST_ENTRY Entry
Definition: kernel32.h:61
HANDLE SectionHandle
Definition: kernel32.h:63
CPTABLEINFO CodePageTable
Definition: kernel32.h:65
PBYTE SectionMapping
Definition: kernel32.h:64
USHORT DefaultChar
Definition: precomp.h:34
USHORT DBCSCodePage
Definition: precomp.h:38
USHORT TransDefaultChar
Definition: precomp.h:36
PUSHORT MultiByteTable
Definition: precomp.h:40
UCHAR LeadByte[MAXIMUM_LEADBYTES]
Definition: precomp.h:39
USHORT CodePage
Definition: precomp.h:32
PUSHORT DBCSOffsets
Definition: precomp.h:43
USHORT UniDefaultChar
Definition: precomp.h:35
USHORT MaximumCharacterSize
Definition: precomp.h:33
PVOID WideCharTable
Definition: precomp.h:41
USHORT TransUniDefaultChar
Definition: precomp.h:37
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
BYTE LeadByte[MAX_LEADBYTES]
Definition: winnls.h:652
BYTE DefaultChar[MAX_DEFAULTCHAR]
Definition: winnls.h:651
UINT MaxCharSize
Definition: winnls.h:650
CHAR CodePageName[MAX_PATH]
Definition: winnls.h:660
WCHAR UnicodeDefaultChar
Definition: winnls.h:666
WCHAR CodePageName[MAX_PATH]
Definition: winnls.h:668
UINT CodePage
Definition: winnls.h:667
_In_ SIZE_T DescriptorSize
Definition: nls.c:40
const char * LPCSTR
Definition: typedefs.h:52
const uint16_t * LPCWSTR
Definition: typedefs.h:57
unsigned char UCHAR
Definition: typedefs.h:53
#define MAKEWORD(a, b)
Definition: typedefs.h:248
uint16_t * LPWSTR
Definition: typedefs.h:56
ULONG_PTR SIZE_T
Definition: typedefs.h:80
char * LPSTR
Definition: typedefs.h:51
int32_t INT
Definition: typedefs.h:58
uint16_t * PUSHORT
Definition: typedefs.h:56
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
static const WCHAR lang[]
Definition: wbemdisp.c:287
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2705
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING _In_ PCUNICODE_STRING _In_ LCID LocaleId
Definition: wdfpdo.h:437
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
#define WINAPI
Definition: msvc.h:6
NTSYSAPI void WINAPI RtlInitCodePageTable(USHORT *, CPTABLEINFO *)
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
#define ERROR_NO_UNICODE_TRANSLATION
Definition: winerror.h:973
#define ERROR_INVALID_FLAGS
Definition: winerror.h:907
#define CP_THREAD_ACP
Definition: winnls.h:251
#define CP_OEMCP
Definition: winnls.h:249
#define CP_SYMBOL
Definition: winnls.h:252
_In_ DWORD _In_ int _In_ int _In_opt_ LPNLSVERSIONINFO lpVersionInformation
Definition: winnls.h:1267
#define CP_UTF7
Definition: winnls.h:253
#define CP_MACCP
Definition: winnls.h:250
#define LOCALE_IDEFAULTANSICODEPAGE
Definition: winnls.h:45
#define LOCALE_IDEFAULTMACCODEPAGE
Definition: winnls.h:46
NLS_FUNCTION
Definition: winnls.h:614
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
_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:191
_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:409
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
*BytesInMultiByteString PCHAR MultiByteString
Definition: rtlfuncs.h:1544
#define SECURITY_BUILTIN_DOMAIN_RID
Definition: setypes.h:581
#define SECURITY_WORLD_SID_AUTHORITY
Definition: setypes.h:527
#define SECURITY_WORLD_RID
Definition: setypes.h:541
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:554
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define ACL_REVISION
Definition: setypes.h:39
#define DOMAIN_ALIAS_RID_ADMINS
Definition: setypes.h:652
unsigned char BYTE
Definition: xxhash.c:193