ReactOS 0.4.16-dev-2206-gc56950d
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 WCHAR 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
562 if (TrailLength)
563 {
564 WideCharCount++;
565 StringIsValid = FALSE;
566 }
567
568 if (Flags == MB_ERR_INVALID_CHARS && !StringIsValid)
569 {
571 return 0;
572 }
573
574 return WideCharCount;
575 }
576
577 /* convert */
578 MbsEnd = MultiByteString + MultiByteCount;
579 for (Count = 0; Count < WideCharCount && MultiByteString < MbsEnd; Count++)
580 {
581 Char = *MultiByteString++;
582 if (Char < 0x80)
583 {
584 *WideCharString++ = Char;
585 TrailLength = 0;
586 continue;
587 }
588 if ((Char & 0xC0) == 0x80)
589 {
590 *WideCharString++ = InvalidChar;
591 TrailLength = 0;
592 StringIsValid = FALSE;
593 continue;
594 }
595
596 TrailLength = UTF8Length[Char - 0x80];
597 if (TrailLength == 0)
598 {
599 *WideCharString++ = InvalidChar;
600 StringIsValid = FALSE;
601 continue;
602 }
603
604 CharIsValid = TRUE;
605 MbsPtrSave = MultiByteString;
606 WideChar = Char & UTF8Mask[TrailLength];
607
608 while (TrailLength && MultiByteString < MbsEnd)
609 {
610 if ((*MultiByteString & 0xC0) != 0x80)
611 {
612 CharIsValid = StringIsValid = FALSE;
613 break;
614 }
615
616 WideChar = (WideChar << 6) | (*MultiByteString++ & 0x7f);
617 TrailLength--;
618 }
619
620 if (CharIsValid && UTF8LBound[UTF8Length[Char - 0x80]] <= WideChar)
621 {
622 *WideCharString++ = WideChar;
623 }
624 else
625 {
626 *WideCharString++ = InvalidChar;
627 MultiByteString = MbsPtrSave;
628 StringIsValid = FALSE;
629 }
630 }
631
632 if (TrailLength && Count < WideCharCount && MultiByteString < MbsEnd)
633 {
634 *WideCharString = InvalidChar;
635 WideCharCount++;
636 }
637
638 if (MultiByteString < MbsEnd)
639 {
641 return 0;
642 }
643
644 if (Flags == MB_ERR_INVALID_CHARS && (!StringIsValid || TrailLength))
645 {
647 return 0;
648 }
649
650 return Count;
651}
652
663static
664INT
665WINAPI
667 DWORD Flags,
669 INT MultiByteCount,
670 LPWSTR WideCharString,
671 INT WideCharCount)
672{
673 PCODEPAGE_ENTRY CodePageEntry;
675 PUSHORT MultiByteTable;
676 LPCSTR TempString;
677 INT TempLength;
678 USHORT WideChar;
679
680 /* Get code page table. */
681 CodePageEntry = IntGetCodePageEntry(CodePage);
682 if (CodePageEntry == NULL)
683 {
685 return 0;
686 }
687
688 CodePageTable = &CodePageEntry->CodePageTable;
689
690 /* If MB_USEGLYPHCHARS flag present and glyph table present */
692 {
693 /* Use glyph table */
694 MultiByteTable = CodePageTable->MultiByteTable + 256 + 1;
695 }
696 else
697 {
698 MultiByteTable = CodePageTable->MultiByteTable;
699 }
700
701 /* Different handling for DBCS code pages. */
703 {
704 UCHAR Char;
705 USHORT DBCSOffset;
706 LPCSTR MbsEnd = MultiByteString + MultiByteCount;
707 INT Count;
708
710 {
711 TempString = MultiByteString;
712
713 while (TempString < MbsEnd)
714 {
715 DBCSOffset = CodePageTable->DBCSOffsets[(UCHAR)*TempString];
716
717 if (DBCSOffset)
718 {
719 /* If lead byte is presented, but behind it there is no symbol */
720 if (((TempString + 1) == MbsEnd) || (*(TempString + 1) == 0))
721 {
723 return 0;
724 }
725
726 WideChar = CodePageTable->DBCSOffsets[DBCSOffset + *(TempString + 1)];
727
728 if (WideChar == CodePageTable->UniDefaultChar &&
729 MAKEWORD(*(TempString + 1), *TempString) != CodePageTable->TransUniDefaultChar)
730 {
732 return 0;
733 }
734
735 TempString++;
736 }
737 else
738 {
739 WideChar = MultiByteTable[(UCHAR)*TempString];
740
741 if ((WideChar == CodePageTable->UniDefaultChar &&
742 *TempString != CodePageTable->TransUniDefaultChar) ||
743 /* "Private Use" characters */
744 (WideChar >= 0xE000 && WideChar <= 0xF8FF))
745 {
747 return 0;
748 }
749 }
750
751 TempString++;
752 }
753 }
754
755 /* Does caller query for output buffer size? */
756 if (WideCharCount == 0)
757 {
758 for (; MultiByteString < MbsEnd; WideCharCount++)
759 {
760 Char = *MultiByteString++;
761
762 DBCSOffset = CodePageTable->DBCSOffsets[Char];
763
764 if (!DBCSOffset)
765 continue;
766
767 if (MultiByteString < MbsEnd)
769 }
770
771 return WideCharCount;
772 }
773
774 for (Count = 0; Count < WideCharCount && MultiByteString < MbsEnd; Count++)
775 {
776 Char = *MultiByteString++;
777
778 DBCSOffset = CodePageTable->DBCSOffsets[Char];
779
780 if (!DBCSOffset)
781 {
782 *WideCharString++ = MultiByteTable[Char];
783 continue;
784 }
785
786 if (MultiByteString == MbsEnd || *MultiByteString == 0)
787 {
788 *WideCharString++ = CodePageTable->UniDefaultChar;
789 }
790 else
791 {
792 *WideCharString++ = CodePageTable->DBCSOffsets[DBCSOffset + (UCHAR)*MultiByteString++];
793 }
794 }
795
796 if (MultiByteString < MbsEnd)
797 {
799 return 0;
800 }
801
802 return Count;
803 }
804 else /* SBCS code page */
805 {
806 /* Check for invalid characters. */
808 {
809 for (TempString = MultiByteString, TempLength = MultiByteCount;
810 TempLength > 0;
811 TempString++, TempLength--)
812 {
813 WideChar = MultiByteTable[(UCHAR)*TempString];
814
815 if ((WideChar == CodePageTable->UniDefaultChar &&
816 *TempString != CodePageTable->TransUniDefaultChar) ||
817 /* "Private Use" characters */
818 (WideChar >= 0xE000 && WideChar <= 0xF8FF))
819 {
821 return 0;
822 }
823 }
824 }
825
826 /* Does caller query for output buffer size? */
827 if (WideCharCount == 0)
828 return MultiByteCount;
829
830 /* Fill the WideCharString buffer with what will fit: Verified on WinXP */
831 for (TempLength = (WideCharCount < MultiByteCount) ? WideCharCount : MultiByteCount;
832 TempLength > 0;
833 MultiByteString++, TempLength--)
834 {
835 *WideCharString++ = MultiByteTable[(UCHAR)*MultiByteString];
836 }
837
838 /* Adjust buffer size. Wine trick ;-) */
839 if (WideCharCount < MultiByteCount)
840 {
841 MultiByteCount = WideCharCount;
843 return 0;
844 }
845 return MultiByteCount;
846 }
847}
848
857static
858INT
859WINAPI
862 INT MultiByteCount,
863 LPWSTR WideCharString,
864 INT WideCharCount)
865{
866 LONG Count;
867 UCHAR Char;
868 INT WideCharMaxLen;
869
870
871 if (Flags != 0)
872 {
874 return 0;
875 }
876
877 if (WideCharCount == 0)
878 {
879 return MultiByteCount;
880 }
881
882 WideCharMaxLen = WideCharCount > MultiByteCount ? MultiByteCount : WideCharCount;
883
884 for (Count = 0; Count < WideCharMaxLen; Count++)
885 {
886 Char = MultiByteString[Count];
887 if ( Char < 0x20 )
888 {
889 WideCharString[Count] = Char;
890 }
891 else
892 {
893 WideCharString[Count] = Char + 0xf000;
894 }
895 }
896 if (MultiByteCount > WideCharMaxLen)
897 {
899 return 0;
900 }
901
902 return WideCharMaxLen;
903}
904
913static INT
914WINAPI
916 LPCWSTR WideCharString,
917 INT WideCharCount,
919 INT MultiByteCount)
920{
921 LONG Count;
922 INT MaxLen;
923 WCHAR Char;
924
925 if (Flags!=0)
926 {
928 return 0;
929 }
930
931
932 if (MultiByteCount == 0)
933 {
934 return WideCharCount;
935 }
936
937 MaxLen = MultiByteCount > WideCharCount ? WideCharCount : MultiByteCount;
938 for (Count = 0; Count < MaxLen; Count++)
939 {
940 Char = WideCharString[Count];
941 if (Char < 0x20)
942 {
943 MultiByteString[Count] = (CHAR)Char;
944 }
945 else
946 {
947 if ((Char >= 0xf020) && (Char < 0xf100))
948 {
949 MultiByteString[Count] = Char - 0xf000;
950 }
951 else
952 {
954 return 0;
955 }
956 }
957 }
958
959 if (WideCharCount > MaxLen)
960 {
962 return 0;
963 }
964 return MaxLen;
965}
966
975static INT
976WINAPI
978 DWORD Flags,
979 LPCWSTR WideCharString,
980 INT WideCharCount,
982 INT MultiByteCount,
983 LPCSTR DefaultChar,
984 LPBOOL UsedDefaultChar)
985{
986 INT TempLength;
987 DWORD Char;
988
989 if (Flags)
990 {
992 return 0;
993 }
994
995 /* Does caller query for output buffer size? */
996 if (MultiByteCount == 0)
997 {
998 for (TempLength = 0; WideCharCount;
999 WideCharCount--, WideCharString++)
1000 {
1001 TempLength++;
1002 if (*WideCharString >= 0x80)
1003 {
1004 TempLength++;
1005 if (*WideCharString >= 0x800)
1006 {
1007 TempLength++;
1008 if (*WideCharString >= 0xd800 && *WideCharString < 0xdc00 &&
1009 WideCharCount >= 1 &&
1010 WideCharString[1] >= 0xdc00 && WideCharString[1] <= 0xe000)
1011 {
1012 WideCharCount--;
1013 WideCharString++;
1014 TempLength++;
1015 }
1016 }
1017 }
1018 }
1019 return TempLength;
1020 }
1021
1022 for (TempLength = MultiByteCount; WideCharCount; WideCharCount--, WideCharString++)
1023 {
1024 Char = *WideCharString;
1025 if (Char < 0x80)
1026 {
1027 if (!TempLength)
1028 {
1030 break;
1031 }
1032 TempLength--;
1033 *MultiByteString++ = (CHAR)Char;
1034 continue;
1035 }
1036
1037 if (Char < 0x800) /* 0x80-0x7ff: 2 bytes */
1038 {
1039 if (TempLength < 2)
1040 {
1042 break;
1043 }
1044 MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
1045 MultiByteString[0] = 0xc0 | Char;
1046 MultiByteString += 2;
1047 TempLength -= 2;
1048 continue;
1049 }
1050
1051 /* surrogate pair 0x10000-0x10ffff: 4 bytes */
1052 if (Char >= 0xd800 && Char < 0xdc00 &&
1053 WideCharCount >= 1 &&
1054 WideCharString[1] >= 0xdc00 && WideCharString[1] < 0xe000)
1055 {
1056 WideCharCount--;
1057 WideCharString++;
1058
1059 if (TempLength < 4)
1060 {
1062 break;
1063 }
1064
1065 Char = (Char - 0xd800) << 10;
1066 Char |= *WideCharString - 0xdc00;
1067 ASSERT(Char <= 0xfffff);
1068 Char += 0x10000;
1069 ASSERT(Char <= 0x10ffff);
1070
1071 MultiByteString[3] = 0x80 | (Char & 0x3f); Char >>= 6;
1072 MultiByteString[2] = 0x80 | (Char & 0x3f); Char >>= 6;
1073 MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
1074 MultiByteString[0] = 0xf0 | Char;
1075 MultiByteString += 4;
1076 TempLength -= 4;
1077 continue;
1078 }
1079
1080 /* 0x800-0xffff: 3 bytes */
1081 if (TempLength < 3)
1082 {
1084 break;
1085 }
1086 MultiByteString[2] = 0x80 | (Char & 0x3f); Char >>= 6;
1087 MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
1088 MultiByteString[0] = 0xe0 | Char;
1089 MultiByteString += 3;
1090 TempLength -= 3;
1091 }
1092
1093 return MultiByteCount - TempLength;
1094}
1095
1103static
1104inline
1105BOOL
1107{
1108 /* If the WC_NO_BEST_FIT_CHARS flag has been specified, the characters need to match exactly. */
1110 return (CodePageTable->MultiByteTable[ch] == wch);
1111
1112 /* By default, all characters except TransDefaultChar apply as a valid mapping
1113 for ch (so also "nearest" characters) */
1115 return TRUE;
1116
1117 /* The only possible left valid mapping is the default character itself */
1118 return (wch == CodePageTable->TransUniDefaultChar);
1119}
1120
1128static inline BOOL
1130{
1131 /* If ch is the default character, but the wch is not, it can't be a valid mapping */
1133 return FALSE;
1134
1135 /* If the WC_NO_BEST_FIT_CHARS flag has been specified, the characters need to match exactly. */
1137 {
1138 if(ch & 0xff00)
1139 {
1140 USHORT uOffset = CodePageTable->DBCSOffsets[ch >> 8];
1141 /* if (!uOffset) return (CodePageTable->MultiByteTable[ch] == wch); */
1142 return (CodePageTable->DBCSOffsets[uOffset + (ch & 0xff)] == wch);
1143 }
1144
1145 return (CodePageTable->MultiByteTable[ch] == wch);
1146 }
1147
1148 /* If we're still here, we have a valid mapping */
1149 return TRUE;
1150}
1151
1160static
1161INT
1162WINAPI
1164 DWORD Flags,
1165 LPCWSTR WideCharString,
1166 INT WideCharCount,
1168 INT MultiByteCount,
1169 LPCSTR DefaultChar,
1170 LPBOOL UsedDefaultChar)
1171{
1172 PCODEPAGE_ENTRY CodePageEntry;
1174 INT TempLength;
1175
1176 /* Get code page table. */
1177 CodePageEntry = IntGetCodePageEntry(CodePage);
1178 if (CodePageEntry == NULL)
1179 {
1181 return 0;
1182 }
1183
1184 CodePageTable = &CodePageEntry->CodePageTable;
1185
1186
1187 /* Different handling for DBCS code pages. */
1189 {
1190 /* If Flags, DefaultChar or UsedDefaultChar were given, we have to do some more work */
1191 if (Flags || DefaultChar || UsedDefaultChar)
1192 {
1193 BOOL TempUsedDefaultChar;
1194 USHORT DefChar;
1195
1196 /* If UsedDefaultChar is not set, set it to a temporary value, so we don't have
1197 to check on every character */
1198 if (!UsedDefaultChar)
1199 UsedDefaultChar = &TempUsedDefaultChar;
1200
1201 *UsedDefaultChar = FALSE;
1202
1203 /* Use the CodePage's TransDefaultChar if none was given. Don't modify the DefaultChar pointer here. */
1204 if (DefaultChar)
1205 DefChar = DefaultChar[1] ? ((DefaultChar[0] << 8) | DefaultChar[1]) : DefaultChar[0];
1206 else
1208
1209 /* Does caller query for output buffer size? */
1210 if (!MultiByteCount)
1211 {
1212 for (TempLength = 0; WideCharCount; WideCharCount--, WideCharString++, TempLength++)
1213 {
1214 USHORT uChar;
1215
1216 if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1217 {
1218 /* FIXME: Handle WC_COMPOSITECHECK */
1219 DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1220 }
1221
1222 uChar = ((PUSHORT) CodePageTable->WideCharTable)[*WideCharString];
1223
1224 /* Verify if the mapping is valid for handling DefaultChar and UsedDefaultChar */
1225 if (!IntIsValidDBCSMapping(CodePageTable, Flags, *WideCharString, uChar))
1226 {
1227 uChar = DefChar;
1228 *UsedDefaultChar = TRUE;
1229 }
1230
1231 /* Increment TempLength again if this is a double-byte character */
1232 if (uChar & 0xff00)
1233 TempLength++;
1234 }
1235
1236 return TempLength;
1237 }
1238
1239 /* Convert the WideCharString to the MultiByteString and verify if the mapping is valid */
1240 for (TempLength = MultiByteCount;
1241 WideCharCount && TempLength;
1242 TempLength--, WideCharString++, WideCharCount--)
1243 {
1244 USHORT uChar;
1245
1246 if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1247 {
1248 /* FIXME: Handle WC_COMPOSITECHECK */
1249 DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1250 }
1251
1252 uChar = ((PUSHORT)CodePageTable->WideCharTable)[*WideCharString];
1253
1254 /* Verify if the mapping is valid for handling DefaultChar and UsedDefaultChar */
1255 if (!IntIsValidDBCSMapping(CodePageTable, Flags, *WideCharString, uChar))
1256 {
1257 uChar = DefChar;
1258 *UsedDefaultChar = TRUE;
1259 }
1260
1261 /* Handle double-byte characters */
1262 if (uChar & 0xff00)
1263 {
1264 /* Don't output a partial character */
1265 if (TempLength == 1)
1266 break;
1267
1268 TempLength--;
1269 *MultiByteString++ = uChar >> 8;
1270 }
1271
1272 *MultiByteString++ = (char)uChar;
1273 }
1274
1275 /* WideCharCount should be 0 if all characters were converted */
1276 if (WideCharCount)
1277 {
1279 return 0;
1280 }
1281
1282 return MultiByteCount - TempLength;
1283 }
1284
1285 /* Does caller query for output buffer size? */
1286 if (!MultiByteCount)
1287 {
1288 for (TempLength = 0; WideCharCount; WideCharCount--, WideCharString++, TempLength++)
1289 {
1290 /* Increment TempLength again if this is a double-byte character */
1291 if (((PWCHAR)CodePageTable->WideCharTable)[*WideCharString] & 0xff00)
1292 TempLength++;
1293 }
1294
1295 return TempLength;
1296 }
1297
1298 /* Convert the WideCharString to the MultiByteString */
1299 for (TempLength = MultiByteCount;
1300 WideCharCount && TempLength;
1301 TempLength--, WideCharString++, WideCharCount--)
1302 {
1303 USHORT uChar = ((PUSHORT) CodePageTable->WideCharTable)[*WideCharString];
1304
1305 /* Is this a double-byte character? */
1306 if (uChar & 0xff00)
1307 {
1308 /* Don't output a partial character */
1309 if (TempLength == 1)
1310 break;
1311
1312 TempLength--;
1313 *MultiByteString++ = uChar >> 8;
1314 }
1315
1316 *MultiByteString++ = (char)uChar;
1317 }
1318
1319 /* WideCharCount should be 0 if all characters were converted */
1320 if (WideCharCount)
1321 {
1323 return 0;
1324 }
1325
1326 return MultiByteCount - TempLength;
1327 }
1328 else /* SBCS code page */
1329 {
1330 INT nReturn;
1331
1332 /* If Flags, DefaultChar or UsedDefaultChar were given, we have to do some more work */
1333 if (Flags || DefaultChar || UsedDefaultChar)
1334 {
1335 BOOL TempUsedDefaultChar;
1336 CHAR DefChar;
1337
1338 /* If UsedDefaultChar is not set, set it to a temporary value, so we don't have
1339 to check on every character */
1340 if (!UsedDefaultChar)
1341 UsedDefaultChar = &TempUsedDefaultChar;
1342
1343 *UsedDefaultChar = FALSE;
1344
1345 /* Does caller query for output buffer size? */
1346 if (!MultiByteCount)
1347 {
1348 /* Loop through the whole WideCharString and check if we can get a valid mapping for each character */
1349 for (TempLength = 0; WideCharCount; TempLength++, WideCharString++, WideCharCount--)
1350 {
1351 if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1352 {
1353 /* FIXME: Handle WC_COMPOSITECHECK */
1354 DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1355 }
1356
1357 if (!*UsedDefaultChar)
1358 *UsedDefaultChar = !IntIsValidSBCSMapping(CodePageTable,
1359 Flags,
1360 *WideCharString,
1361 ((PCHAR)CodePageTable->WideCharTable)[*WideCharString]);
1362 }
1363
1364 return TempLength;
1365 }
1366
1367 /* Use the CodePage's TransDefaultChar if none was given. Don't modify the DefaultChar pointer here. */
1368 if (DefaultChar)
1369 DefChar = *DefaultChar;
1370 else
1372
1373 /* Convert the WideCharString to the MultiByteString and verify if the mapping is valid */
1374 for (TempLength = MultiByteCount;
1375 WideCharCount && TempLength;
1376 MultiByteString++, TempLength--, WideCharString++, WideCharCount--)
1377 {
1378 if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1379 {
1380 /* FIXME: Handle WC_COMPOSITECHECK */
1381 DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1382 }
1383
1384 *MultiByteString = ((PCHAR)CodePageTable->WideCharTable)[*WideCharString];
1385
1386 if (!IntIsValidSBCSMapping(CodePageTable, Flags, *WideCharString, *MultiByteString))
1387 {
1388 *MultiByteString = DefChar;
1389 *UsedDefaultChar = TRUE;
1390 }
1391 }
1392
1393 /* WideCharCount should be 0 if all characters were converted */
1394 if (WideCharCount)
1395 {
1397 return 0;
1398 }
1399
1400 return MultiByteCount - TempLength;
1401 }
1402
1403 /* Does caller query for output buffer size? */
1404 if (!MultiByteCount)
1405 return WideCharCount;
1406
1407 /* Is the buffer large enough? */
1408 if (MultiByteCount < WideCharCount)
1409 {
1410 /* Convert the string up to MultiByteCount and return 0 */
1411 WideCharCount = MultiByteCount;
1413 nReturn = 0;
1414 }
1415 else
1416 {
1417 /* Otherwise WideCharCount will be the number of converted characters */
1418 nReturn = WideCharCount;
1419 }
1420
1421 /* Convert the WideCharString to the MultiByteString */
1422 for (TempLength = WideCharCount; --TempLength >= 0; WideCharString++, MultiByteString++)
1423 {
1424 *MultiByteString = ((PCHAR)CodePageTable->WideCharTable)[*WideCharString];
1425 }
1426
1427 return nReturn;
1428 }
1429}
1430
1438static BOOL
1439WINAPI
1441{
1442 UINT i;
1443
1444 if (TableInfo->MaximumCharacterSize == 2)
1445 {
1446 for (i = 0; i < MAXIMUM_LEADBYTES && TableInfo->LeadByte[i]; i += 2)
1447 {
1448 if (Byte >= TableInfo->LeadByte[i] && Byte <= TableInfo->LeadByte[i+1])
1449 return TRUE;
1450 }
1451 }
1452
1453 return FALSE;
1454}
1455
1456/* PUBLIC FUNCTIONS ***********************************************************/
1457
1485BOOL
1486WINAPI
1488 UINT Base,
1489 ULONG Unknown,
1490 LPSTR BaseName,
1491 LPSTR Result,
1492 ULONG ResultSize)
1493{
1494 CHAR Integer[11];
1495
1496 if (!NT_SUCCESS(RtlIntegerToChar(CodePage, Base, sizeof(Integer), Integer)))
1497 return FALSE;
1498
1499 /*
1500 * If the name including the terminating NULL character doesn't
1501 * fit in the output buffer then fail.
1502 */
1503 if (strlen(Integer) + strlen(BaseName) >= ResultSize)
1504 return FALSE;
1505
1506 lstrcpyA(Result, BaseName);
1507 lstrcatA(Result, Integer);
1508
1509 return TRUE;
1510}
1511
1530BOOL
1531WINAPI
1533{
1534 WCHAR ValueNameBuffer[11];
1540 DWORD KvpiSize;
1541 BOOL bRetValue;
1542
1543 bRetValue = FALSE;
1544
1545 /* Convert the codepage number to string. */
1546 ValueName.Buffer = ValueNameBuffer;
1547 ValueName.MaximumLength = sizeof(ValueNameBuffer);
1548
1549 if (!NT_SUCCESS(RtlIntegerToUnicodeString(CodePage, 10, &ValueName)))
1550 return bRetValue;
1551
1552 /* Open the registry key containing file name mappings. */
1553 RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System\\"
1554 L"CurrentControlSet\\Control\\Nls\\CodePage");
1556 NULL, NULL);
1558 if (!NT_SUCCESS(Status))
1559 {
1560 return bRetValue;
1561 }
1562
1563 /* Allocate buffer that will be used to query the value data. */
1564 KvpiSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + (MAX_PATH * sizeof(WCHAR));
1565 Kvpi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, KvpiSize);
1566 if (Kvpi == NULL)
1567 {
1569 return bRetValue;
1570 }
1571
1572 /* Query the file name for our code page. */
1574 Kvpi, KvpiSize, &KvpiSize);
1575
1577
1578 /* Check if we succeded and the value is non-empty string. */
1579 if (NT_SUCCESS(Status) && Kvpi->Type == REG_SZ &&
1580 Kvpi->DataLength > sizeof(WCHAR))
1581 {
1582 bRetValue = TRUE;
1583 if (FileName != NULL)
1584 {
1585 lstrcpynW(FileName, (WCHAR*)Kvpi->Data,
1586 min(Kvpi->DataLength / sizeof(WCHAR), FileNameSize));
1587 }
1588 }
1589
1590 /* free temporary buffer */
1591 HeapFree(GetProcessHeap(),0,Kvpi);
1592 return bRetValue;
1593}
1594
1606BOOL
1607WINAPI
1609{
1610 if (CodePage == 0) return FALSE;
1611 if (CodePage == CP_UTF8 || CodePage == CP_UTF7)
1612 return TRUE;
1613 if (IntGetLoadedCodePageEntry(CodePage))
1614 return TRUE;
1615 return GetCPFileNameFromRegistry(CodePage, NULL, 0);
1616}
1617
1618static inline BOOL utf7_write_w(WCHAR *dst, int dstlen, int *index, WCHAR character)
1619{
1620 if (dstlen > 0)
1621 {
1622 if (*index >= dstlen)
1623 return FALSE;
1624
1625 dst[*index] = character;
1626 }
1627
1628 (*index)++;
1629
1630 return TRUE;
1631}
1632
1633static INT Utf7ToWideChar(const char *src, int srclen, WCHAR *dst, int dstlen)
1634{
1635 static const signed char base64_decoding_table[] =
1636 {
1637 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00-0x0F */
1638 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10-0x1F */
1639 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20-0x2F */
1640 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30-0x3F */
1641 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40-0x4F */
1642 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50-0x5F */
1643 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60-0x6F */
1644 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 /* 0x70-0x7F */
1645 };
1646
1647 const char *source_end = src + srclen;
1648 int dest_index = 0;
1649
1650 DWORD byte_pair = 0;
1651 short offset = 0;
1652
1653 while (src < source_end)
1654 {
1655 if (*src == '+')
1656 {
1657 src++;
1658 if (src >= source_end)
1659 break;
1660
1661 if (*src == '-')
1662 {
1663 /* just a plus sign escaped as +- */
1664 if (!utf7_write_w(dst, dstlen, &dest_index, '+'))
1665 {
1667 return 0;
1668 }
1669 src++;
1670 continue;
1671 }
1672
1673 do
1674 {
1675 signed char sextet = *src;
1676 if (sextet == '-')
1677 {
1678 /* skip over the dash and end base64 decoding
1679 * the current, unfinished byte pair is discarded */
1680 src++;
1681 offset = 0;
1682 break;
1683 }
1684 if (sextet < 0)
1685 {
1686 /* the next character of src is < 0 and therefore not part of a base64 sequence
1687 * the current, unfinished byte pair is NOT discarded in this case
1688 * this is probably a bug in Windows */
1689 break;
1690 }
1691
1692 sextet = base64_decoding_table[sextet];
1693 if (sextet == -1)
1694 {
1695 /* -1 means that the next character of src is not part of a base64 sequence
1696 * in other words, all sextets in this base64 sequence have been processed
1697 * the current, unfinished byte pair is discarded */
1698 offset = 0;
1699 break;
1700 }
1701
1702 byte_pair = (byte_pair << 6) | sextet;
1703 offset += 6;
1704
1705 if (offset >= 16)
1706 {
1707 /* this byte pair is done */
1708 if (!utf7_write_w(dst, dstlen, &dest_index, (byte_pair >> (offset - 16)) & 0xFFFF))
1709 {
1711 return 0;
1712 }
1713 offset -= 16;
1714 }
1715
1716 src++;
1717 }
1718 while (src < source_end);
1719 }
1720 else
1721 {
1722 /* we have to convert to unsigned char in case *src < 0 */
1723 if (!utf7_write_w(dst, dstlen, &dest_index, (unsigned char)*src))
1724 {
1726 return 0;
1727 }
1728 src++;
1729 }
1730 }
1731
1732 return dest_index;
1733}
1734
1765INT
1766WINAPI
1768 DWORD Flags,
1770 INT MultiByteCount,
1771 LPWSTR WideCharString,
1772 INT WideCharCount)
1773{
1774 /* Check the parameters. */
1775 if (MultiByteString == NULL ||
1776 MultiByteCount == 0 || WideCharCount < 0 ||
1777 (WideCharCount && (WideCharString == NULL ||
1778 (PVOID)MultiByteString == (PVOID)WideCharString)))
1779 {
1781 return 0;
1782 }
1783
1784 /* Determine the input string length. */
1785 if (MultiByteCount < 0)
1786 {
1787 MultiByteCount = lstrlenA(MultiByteString) + 1;
1788 }
1789
1790 switch (CodePage)
1791 {
1792 case CP_UTF8:
1795 MultiByteCount,
1796 WideCharString,
1797 WideCharCount);
1798
1799 case CP_UTF7:
1800 if (Flags)
1801 {
1803 return 0;
1804 }
1805 return Utf7ToWideChar(MultiByteString, MultiByteCount,
1806 WideCharString, WideCharCount);
1807
1808 case CP_SYMBOL:
1811 MultiByteCount,
1812 WideCharString,
1813 WideCharCount);
1814 default:
1815 return IntMultiByteToWideCharCP(CodePage,
1816 Flags,
1818 MultiByteCount,
1819 WideCharString,
1820 WideCharCount);
1821 }
1822}
1823
1824static inline BOOL utf7_can_directly_encode(WCHAR codepoint)
1825{
1826 static const BOOL directly_encodable_table[] =
1827 {
1828 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, /* 0x00 - 0x0F */
1829 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1F */
1830 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* 0x20 - 0x2F */
1831 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x30 - 0x3F */
1832 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4F */
1833 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x50 - 0x5F */
1834 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6F */
1835 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* 0x70 - 0x7A */
1836 };
1837
1838 return codepoint <= 0x7A ? directly_encodable_table[codepoint] : FALSE;
1839}
1840
1841static inline BOOL utf7_write_c(char *dst, int dstlen, int *index, char character)
1842{
1843 if (dstlen > 0)
1844 {
1845 if (*index >= dstlen)
1846 return FALSE;
1847
1848 dst[*index] = character;
1849 }
1850
1851 (*index)++;
1852
1853 return TRUE;
1854}
1855
1856static INT WideCharToUtf7(const WCHAR *src, int srclen, char *dst, int dstlen)
1857{
1858 static const char base64_encoding_table[] =
1859 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1860
1861 const WCHAR *source_end = src + srclen;
1862 int dest_index = 0;
1863
1864 while (src < source_end)
1865 {
1866 if (*src == '+')
1867 {
1868 if (!utf7_write_c(dst, dstlen, &dest_index, '+'))
1869 {
1871 return 0;
1872 }
1873 if (!utf7_write_c(dst, dstlen, &dest_index, '-'))
1874 {
1876 return 0;
1877 }
1878 src++;
1879 }
1880 else if (utf7_can_directly_encode(*src))
1881 {
1882 if (!utf7_write_c(dst, dstlen, &dest_index, *src))
1883 {
1885 return 0;
1886 }
1887 src++;
1888 }
1889 else
1890 {
1891 unsigned int offset = 0;
1892 DWORD byte_pair = 0;
1893
1894 if (!utf7_write_c(dst, dstlen, &dest_index, '+'))
1895 {
1897 return 0;
1898 }
1899
1900 while (src < source_end && !utf7_can_directly_encode(*src))
1901 {
1902 byte_pair = (byte_pair << 16) | *src;
1903 offset += 16;
1904 while (offset >= 6)
1905 {
1906 if (!utf7_write_c(dst, dstlen, &dest_index, base64_encoding_table[(byte_pair >> (offset - 6)) & 0x3F]))
1907 {
1909 return 0;
1910 }
1911 offset -= 6;
1912 }
1913 src++;
1914 }
1915
1916 if (offset)
1917 {
1918 /* Windows won't create a padded base64 character if there's no room for the - sign
1919 * as well ; this is probably a bug in Windows */
1920 if (dstlen > 0 && dest_index + 1 >= dstlen)
1921 {
1923 return 0;
1924 }
1925
1926 byte_pair <<= (6 - offset);
1927 if (!utf7_write_c(dst, dstlen, &dest_index, base64_encoding_table[byte_pair & 0x3F]))
1928 {
1930 return 0;
1931 }
1932 }
1933
1934 /* Windows always explicitly terminates the base64 sequence
1935 even though RFC 2152 (page 3, rule 2) does not require this */
1936 if (!utf7_write_c(dst, dstlen, &dest_index, '-'))
1937 {
1939 return 0;
1940 }
1941 }
1942 }
1943
1944 return dest_index;
1945}
1946
1947/*
1948 * A function similar to LoadStringW, but adapted for usage by GetCPInfoExW
1949 * and GetGeoInfoW. It uses the current user localization, otherwise falls back
1950 * to English (US). Contrary to LoadStringW which always saves the loaded string
1951 * into the user-given buffer, truncating the string if needed, this function
1952 * returns instead an ERROR_INSUFFICIENT_BUFFER error code if the user buffer
1953 * is not large enough.
1954 */
1955UINT
1957 IN UINT uID,
1959 IN UINT cchDest,
1960 IN LANGID lang)
1961{
1962 HRSRC hrsrc;
1963 HGLOBAL hmem;
1964 LCID lcid;
1965 LANGID langId;
1966 const WCHAR *p;
1967 UINT i;
1968
1969 /* See HACK in winnls/lang/xx-XX.rc files */
1970 if (uID == 37)
1971 uID = uID * 100;
1972
1974
1975 langId = LANGIDFROMLCID(lcid);
1976
1977 if (PRIMARYLANGID(langId) == LANG_NEUTRAL)
1979
1982 MAKEINTRESOURCEW((uID >> 4) + 1),
1983 langId);
1984
1985 /* English fallback */
1986 if (!hrsrc)
1987 {
1990 MAKEINTRESOURCEW((uID >> 4) + 1),
1992 }
1993
1994 if (!hrsrc)
1995 goto NotFound;
1996
1997 hmem = LoadResource(hCurrentModule, hrsrc);
1998 if (!hmem)
1999 goto NotFound;
2000
2001 p = LockResource(hmem);
2002
2003 for (i = 0; i < (uID & 0x0F); i++)
2004 p += *p + 1;
2005
2006 /* Needed for GetGeoInfo(): return the needed string size including the NULL terminator */
2007 if (cchDest == 0)
2008 return *p + 1;
2009 /* Needed for GetGeoInfo(): bail out if the user buffer is not large enough */
2010 if (*p + 1 > cchDest)
2011 {
2013 return 0;
2014 }
2015
2016 i = *p;
2017 if (i > 0)
2018 {
2019 memcpy(lpszDest, p + 1, i * sizeof(WCHAR));
2020 lpszDest[i] = L'\0';
2021 return i;
2022 }
2023#if 0
2024 else
2025 {
2026 if (cchDest >= 1)
2027 lpszDest[0] = L'\0';
2028 /* Fall-back */
2029 }
2030#endif
2031
2032NotFound:
2033 DPRINT1("Resource not found: uID = %lu\n", uID);
2035 return 0;
2036}
2037
2038/*
2039 * @implemented
2040 */
2041BOOL
2042WINAPI
2044 LPCPINFO CodePageInfo)
2045{
2046 PCODEPAGE_ENTRY CodePageEntry;
2047
2048 if (!CodePageInfo)
2049 {
2051 return FALSE;
2052 }
2053
2054 CodePageEntry = IntGetCodePageEntry(CodePage);
2055 if (CodePageEntry == NULL)
2056 {
2057 switch(CodePage)
2058 {
2059 case CP_UTF7:
2060 case CP_UTF8:
2061 RtlZeroMemory(CodePageInfo, sizeof(*CodePageInfo));
2062 CodePageInfo->DefaultChar[0] = 0x3f;
2063 CodePageInfo->DefaultChar[1] = 0;
2064 CodePageInfo->LeadByte[0] = CodePageInfo->LeadByte[1] = 0;
2065 CodePageInfo->MaxCharSize = (CodePage == CP_UTF7) ? 5 : 4;
2066 return TRUE;
2067 }
2068
2069 DPRINT1("Invalid CP!: %lx\n", CodePage);
2071 return FALSE;
2072 }
2073
2074 RtlZeroMemory(CodePageInfo, sizeof(*CodePageInfo));
2075 if (CodePageEntry->CodePageTable.DefaultChar & 0xff00)
2076 {
2077 CodePageInfo->DefaultChar[0] = (CodePageEntry->CodePageTable.DefaultChar & 0xff00) >> 8;
2078 CodePageInfo->DefaultChar[1] = CodePageEntry->CodePageTable.DefaultChar & 0x00ff;
2079 }
2080 else
2081 {
2082 CodePageInfo->DefaultChar[0] = CodePageEntry->CodePageTable.DefaultChar & 0xff;
2083 CodePageInfo->DefaultChar[1] = 0;
2084 }
2085
2086 if ((CodePageInfo->MaxCharSize = CodePageEntry->CodePageTable.MaximumCharacterSize) == 2)
2087 memcpy(CodePageInfo->LeadByte, CodePageEntry->CodePageTable.LeadByte, sizeof(CodePageInfo->LeadByte));
2088 else
2089 CodePageInfo->LeadByte[0] = CodePageInfo->LeadByte[1] = 0;
2090
2091 return TRUE;
2092}
2093
2094/*
2095 * @implemented
2096 */
2097BOOL
2098WINAPI
2100 DWORD dwFlags,
2101 LPCPINFOEXW lpCPInfoEx)
2102{
2103 if (!GetCPInfo(CodePage, (LPCPINFO)lpCPInfoEx))
2104 return FALSE;
2105
2106 switch(CodePage)
2107 {
2108 case CP_UTF7:
2109 {
2110 lpCPInfoEx->CodePage = CP_UTF7;
2111 lpCPInfoEx->UnicodeDefaultChar = 0x3f;
2112 return GetLocalisedText(lpCPInfoEx->CodePage,
2113 lpCPInfoEx->CodePageName,
2114 ARRAYSIZE(lpCPInfoEx->CodePageName),
2115 GetThreadLocale()) != 0;
2116 }
2117 break;
2118
2119 case CP_UTF8:
2120 {
2121 lpCPInfoEx->CodePage = CP_UTF8;
2122 lpCPInfoEx->UnicodeDefaultChar = 0x3f;
2123 return GetLocalisedText(lpCPInfoEx->CodePage,
2124 lpCPInfoEx->CodePageName,
2125 ARRAYSIZE(lpCPInfoEx->CodePageName),
2126 GetThreadLocale()) != 0;
2127 }
2128
2129 default:
2130 {
2131 PCODEPAGE_ENTRY CodePageEntry;
2132
2133 CodePageEntry = IntGetCodePageEntry(CodePage);
2134 if (CodePageEntry == NULL)
2135 {
2136 DPRINT1("Could not get CodePage Entry! CodePageEntry = NULL\n");
2138 return FALSE;
2139 }
2140
2141 lpCPInfoEx->CodePage = CodePageEntry->CodePageTable.CodePage;
2142 lpCPInfoEx->UnicodeDefaultChar = CodePageEntry->CodePageTable.UniDefaultChar;
2143 return GetLocalisedText(lpCPInfoEx->CodePage,
2144 lpCPInfoEx->CodePageName,
2145 ARRAYSIZE(lpCPInfoEx->CodePageName),
2146 GetThreadLocale()) != 0;
2147 }
2148 break;
2149 }
2150}
2151
2152
2153/*
2154 * @implemented
2155 */
2156BOOL
2157WINAPI
2159 DWORD dwFlags,
2160 LPCPINFOEXA lpCPInfoEx)
2161{
2162 CPINFOEXW CPInfo;
2163
2164 if (!GetCPInfoExW(CodePage, dwFlags, &CPInfo))
2165 return FALSE;
2166
2167 /* the layout is the same except for CodePageName */
2168 memcpy(lpCPInfoEx, &CPInfo, sizeof(CPINFOEXA));
2169
2171 0,
2172 CPInfo.CodePageName,
2173 -1,
2174 lpCPInfoEx->CodePageName,
2175 sizeof(lpCPInfoEx->CodePageName),
2176 NULL,
2177 NULL);
2178 return TRUE;
2179}
2180
2220INT
2221WINAPI
2223 DWORD Flags,
2224 LPCWSTR WideCharString,
2225 INT WideCharCount,
2227 INT MultiByteCount,
2228 LPCSTR DefaultChar,
2229 LPBOOL UsedDefaultChar)
2230{
2231 /* Check the parameters. */
2232 if (WideCharString == NULL ||
2233 WideCharCount == 0 ||
2234 (MultiByteString == NULL && MultiByteCount > 0) ||
2235 (PVOID)WideCharString == (PVOID)MultiByteString ||
2236 MultiByteCount < 0)
2237 {
2239 return 0;
2240 }
2241
2242 /* Determine the input string length. */
2243 if (WideCharCount < 0)
2244 {
2245 WideCharCount = lstrlenW(WideCharString) + 1;
2246 }
2247
2248 switch (CodePage)
2249 {
2250 case CP_UTF8:
2251 if (DefaultChar != NULL || UsedDefaultChar != NULL)
2252 {
2254 return 0;
2255 }
2256 return IntWideCharToMultiByteUTF8(CodePage,
2257 Flags,
2258 WideCharString,
2259 WideCharCount,
2261 MultiByteCount,
2262 DefaultChar,
2263 UsedDefaultChar);
2264
2265 case CP_UTF7:
2266 if (DefaultChar != NULL || UsedDefaultChar != NULL)
2267 {
2269 return 0;
2270 }
2271 if (Flags)
2272 {
2274 return 0;
2275 }
2276 return WideCharToUtf7(WideCharString, WideCharCount,
2277 MultiByteString, MultiByteCount);
2278
2279 case CP_SYMBOL:
2280 if ((DefaultChar!=NULL) || (UsedDefaultChar!=NULL))
2281 {
2283 return 0;
2284 }
2286 WideCharString,
2287 WideCharCount,
2289 MultiByteCount);
2290
2291 default:
2292 return IntWideCharToMultiByteCP(CodePage,
2293 Flags,
2294 WideCharString,
2295 WideCharCount,
2297 MultiByteCount,
2298 DefaultChar,
2299 UsedDefaultChar);
2300 }
2301}
2302
2311UINT
2312WINAPI
2314{
2316}
2317
2326UINT
2327WINAPI
2329{
2331}
2332
2341BOOL
2342WINAPI
2343IsDBCSLeadByteEx(UINT CodePage, BYTE TestByte)
2344{
2345 PCODEPAGE_ENTRY CodePageEntry;
2346
2347 CodePageEntry = IntGetCodePageEntry(CodePage);
2348 if (CodePageEntry != NULL)
2349 return IntIsLeadByte(&CodePageEntry->CodePageTable, TestByte);
2350
2352 return FALSE;
2353}
2354
2363BOOL
2364WINAPI
2366{
2367 return IntIsLeadByte(&AnsiCodePage.CodePageTable, TestByte);
2368}
2369
2398WINAPI
2403{
2406 PSID WorldSid;
2407 PACL Dacl;
2409
2411 {
2412 DPRINT1("Security descriptor size too small\n");
2414 }
2415
2416 /* Create the World SID */
2418 1,
2420 0, 0, 0, 0, 0, 0, 0,
2421 &WorldSid);
2422 if (!NT_SUCCESS(Status))
2423 {
2424 DPRINT1("Failed to create World SID (Status 0x%08x)\n", Status);
2425 return Status;
2426 }
2427
2428 /* Initialize the security descriptor */
2431 if (!NT_SUCCESS(Status))
2432 {
2433 DPRINT1("Failed to create security descriptor (Status 0x%08x)\n", Status);
2434 goto Quit;
2435 }
2436
2437 /* The DACL follows the security descriptor, and includes the World SID */
2440
2441 /* Create the DACL */
2443 if (!NT_SUCCESS(Status))
2444 {
2445 DPRINT1("Failed to create DACL (Status 0x%08x)\n", Status);
2446 goto Quit;
2447 }
2448
2449 /* Add an allowed access ACE to the World SID */
2451 if (!NT_SUCCESS(Status))
2452 {
2453 DPRINT1("Failed to add allowed access ACE for World SID (Status 0x%08x)\n", Status);
2454 goto Quit;
2455 }
2456
2457 /* Set the DACL to the descriptor */
2459 if (!NT_SUCCESS(Status))
2460 {
2461 DPRINT1("Failed to set DACL into descriptor (Status 0x%08x)\n", Status);
2462 goto Quit;
2463 }
2464
2465Quit:
2467 return Status;
2468}
2469
2470/*
2471 * @unimplemented
2472 */
2474{
2475 STUB;
2476 return 0;
2477}
2478
2479/*
2480 * @unimplemented
2481 */
2483{
2484 STUB;
2485}
2486
2487/*
2488 * @unimplemented
2489 */
2491{
2492 STUB;
2493 return 0;
2494}
2495
2496/*
2497 * @unimplemented
2498 */
2499BOOL
2500WINAPI
2501ValidateLCType(int a1, unsigned int a2, int a3, int a4)
2502{
2503 STUB;
2504 return FALSE;
2505}
2506
2507/*
2508 * @unimplemented
2509 */
2510BOOL
2511WINAPI
2513{
2514 STUB;
2515 return TRUE;
2516}
2517
2518/*
2519 * @unimplemented
2520 */
2521VOID
2522WINAPI
2524{
2525 STUB;
2526 lpUnknown = NULL;
2527}
2528
2529/*
2530 * @unimplemented
2531 */
2532VOID
2533WINAPI
2535{
2536 STUB;
2537 lpUnknown = NULL;
2538}
2539
2540/*
2541 * @unimplemented
2542 */
2543BOOL
2544WINAPI
2546{
2547 STUB;
2548 return TRUE;
2549}
2550
2551/*
2552 * @unimplemented
2553 */
2554ULONG
2555WINAPI
2557{
2558 STUB;
2559 return 0;
2560}
2561
2562/*
2563 * @unimplemented
2564 */
2565BOOL
2566WINAPI
2570 IN LPCWSTR lpString,
2571 IN INT cchStr)
2572{
2573 STUB;
2574 return TRUE;
2575}
2576
2577/*
2578 * @unimplemented
2579 */
2580BOOL
2581WINAPI
2583 IN LCID Locale,
2585{
2586 STUB;
2587 return TRUE;
2588}
2589
2590/*
2591 * @unimplemented
2592 */
2593BOOL
2594WINAPI
2596 IN LPCWSTR lpLocaleName,
2598{
2599 STUB;
2600 return TRUE;
2601}
2602
2603/* 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:3076
NTSTATUS NTAPI NtOpenSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: section.c:3204
unsigned char BOOLEAN
WCHAR lpszDest[260]
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:2313
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:1163
BOOL WINAPI GetNLSVersion(IN NLS_FUNCTION Function, IN LCID Locale, IN OUT LPNLSVERSIONINFO lpVersionInformation)
Definition: nls.c:2582
static BOOL IntIsValidSBCSMapping(PCPTABLEINFO CodePageTable, DWORD Flags, WCHAR wch, UCHAR ch)
Definition: nls.c:1106
static const char UTF8Length[128]
Definition: nls.c:25
static BOOL utf7_can_directly_encode(WCHAR codepoint)
Definition: nls.c:1824
BOOL WINAPI GetCPInfo(UINT CodePage, LPCPINFO CodePageInfo)
Definition: nls.c:2043
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:2567
VOID WINAPI NlsConvertIntegerToString(ULONG Value, ULONG Base, ULONG strsize, LPWSTR str, ULONG strsize2)
Definition: nls.c:2482
static INT WideCharToUtf7(const WCHAR *src, int srclen, char *dst, int dstlen)
Definition: nls.c:1856
BOOL WINAPI IsDBCSLeadByteEx(UINT CodePage, BYTE TestByte)
Definition: nls.c:2343
static BOOL utf7_write_c(char *dst, int dstlen, int *index, char character)
Definition: nls.c:1841
BOOL WINAPI ValidateLCType(int a1, unsigned int a2, int a3, int a4)
Definition: nls.c:2501
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:1956
BOOL WINAPI IsValidCodePage(UINT CodePage)
Definition: nls.c:1608
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:2595
static CODEPAGE_ENTRY AnsiCodePage
Definition: nls.c:46
ULONG WINAPI NlsGetCacheUpdateCount(VOID)
Definition: nls.c:2556
static const unsigned long UTF8LBound[]
Definition: nls.c:41
UINT WINAPI SetCPGlobal(UINT CodePage)
Definition: nls.c:2490
static BOOL utf7_write_w(WCHAR *dst, int dstlen, int *index, WCHAR character)
Definition: nls.c:1618
BOOL WINAPI GetNlsSectionName(UINT CodePage, UINT Base, ULONG Unknown, LPSTR BaseName, LPSTR Result, ULONG ResultSize)
Definition: nls.c:1487
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:2399
BOOL WINAPI IsValidUILanguage(LANGID langid)
Definition: nls.c:2473
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:977
static RTL_CRITICAL_SECTION CodePageListLock
Definition: nls.c:48
VOID WINAPI GetLinguistLangSize(LPVOID lpUnknown)
Definition: nls.c:2534
BOOL WINAPI ValidateLocale(IN ULONG LocaleId)
Definition: nls.c:2545
static INT Utf7ToWideChar(const char *src, int srclen, WCHAR *dst, int dstlen)
Definition: nls.c:1633
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:1129
BOOL WINAPI GetCPFileNameFromRegistry(UINT CodePage, LPWSTR FileName, ULONG FileNameSize)
Definition: nls.c:1532
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:2512
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:1440
BOOL WINAPI GetCPInfoExA(UINT CodePage, DWORD dwFlags, LPCPINFOEXA lpCPInfoEx)
Definition: nls.c:2158
BOOL WINAPI GetCPInfoExW(UINT CodePage, DWORD dwFlags, LPCPINFOEXW lpCPInfoEx)
Definition: nls.c:2099
VOID WINAPI GetDefaultSortkeySize(LPVOID lpUnknown)
Definition: nls.c:2523
static INT WINAPI IntWideCharToMultiByteSYMBOL(DWORD Flags, LPCWSTR WideCharString, INT WideCharCount, LPSTR MultiByteString, INT MultiByteCount)
Definition: nls.c:915
static INT WINAPI IntMultiByteToWideCharCP(UINT CodePage, DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:666
BOOL WINAPI IsDBCSLeadByte(BYTE TestByte)
Definition: nls.c:2365
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:860
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:25
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 OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_PERMANENT
Definition: winternl.h:226
NTSYSAPI void WINAPI RtlInitCodePageTable(USHORT *, CPTABLEINFO *)
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
#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
#define for
Definition: utility.h:88
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:106
#define min(a, b)
Definition: monoChain.cc:55
struct _SECURITY_DESCRIPTOR SECURITY_DESCRIPTOR
struct _ACL * PACL
Definition: security.c:105
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
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
_In_ INT cchDest
Definition: shlwapi.h:1151
_In_ UINT uID
Definition: shlwapi.h:156
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
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define DPRINT
Definition: sndvol32.h:73
base of all file and directory entries
Definition: entries.h:83
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
#define MAKEWORD(a, b)
Definition: typedefs.h:248
ULONG_PTR SIZE_T
Definition: typedefs.h:80
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
#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
const char * LPCSTR
Definition: xmlstorage.h:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char * LPSTR
Definition: xmlstorage.h:182
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193