ReactOS 0.4.16-dev-1531-gd958a24
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;
301 ANSI_STRING AnsiName;
304 UINT FileNamePos;
305 PCODEPAGE_ENTRY CodePageEntry;
306
307 if (CodePage == CP_ACP)
308 {
309 return &AnsiCodePage;
310 }
311 else if (CodePage == CP_OEMCP)
312 {
313 return &OemCodePage;
314 }
315 else if (CodePage == CP_THREAD_ACP)
316 {
318 LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
319 (WCHAR *)&CodePage,
320 sizeof(CodePage) / sizeof(WCHAR)))
321 {
322 /* Last error is set by GetLocaleInfoW. */
323 return NULL;
324 }
325 if (CodePage == 0)
326 return &AnsiCodePage;
327 }
328 else if (CodePage == CP_MACCP)
329 {
331 LOCALE_IDEFAULTMACCODEPAGE | LOCALE_RETURN_NUMBER,
332 (WCHAR *)&CodePage,
333 sizeof(CodePage) / sizeof(WCHAR)))
334 {
335 /* Last error is set by GetLocaleInfoW. */
336 return NULL;
337 }
338 }
339
340 /* Try searching for loaded page first. */
341 CodePageEntry = IntGetLoadedCodePageEntry(CodePage);
342 if (CodePageEntry != NULL)
343 {
344 return CodePageEntry;
345 }
346
347 /*
348 * Yes, we really want to lock here. Otherwise it can happen that
349 * two parallel requests will try to get the entry for the same
350 * code page and we would load it twice.
351 */
353
354 /* Generate the section name. */
355 if (!GetNlsSectionName(CodePage,
356 10,
357 0,
358 "\\Nls\\NlsSectionCP",
359 SectionName,
360 sizeof(SectionName)))
361 {
363 return NULL;
364 }
365
366 RtlInitAnsiString(&AnsiName, SectionName);
368
369 /*
370 * FIXME: IntGetCodePageEntry should not create any security
371 * descriptor here but instead this responsibility should be
372 * assigned to Base Server API (aka basesrv.dll). That is,
373 * kernel32 must instruct basesrv.dll on creating NLS section
374 * names that do not exist through API message communication.
375 * However since we do not do that, let the kernel32 do the job
376 * by assigning security to NLS section names for the time being...
377 */
379 sizeof(SecurityDescriptor),
381 if (!NT_SUCCESS(Status))
382 {
383 DPRINT1("CreateNlsSecurityDescriptor FAILED! (Status 0x%08x)\n", Status);
385 return NULL;
386 }
387
391 NULL,
393
394 /* Try to open the section first */
395 Status = NtOpenSection(&SectionHandle,
398
399 /* If the section doesn't exist, try to create it. */
403 {
404 FileNamePos = GetSystemDirectoryW(FileName, MAX_PATH);
405 if (GetCPFileNameFromRegistry(CodePage,
406 FileName + FileNamePos + 1,
407 MAX_PATH - FileNamePos - 1))
408 {
409 FileName[FileNamePos] = L'\\';
410 FileName[MAX_PATH] = 0;
414 NULL,
416 0,
417 NULL);
418
419 Status = NtCreateSection(&SectionHandle,
422 NULL,
425 FileHandle);
426
427 /* HACK: Check if another process was faster
428 * and already created this section. See bug 3626 for details */
430 {
431 /* Close the file then */
433
434 /* And open the section */
435 Status = NtOpenSection(&SectionHandle,
438 }
439 }
440 }
442
443 if (!NT_SUCCESS(Status))
444 {
446 return NULL;
447 }
448
449 SectionMapping = MapViewOfFile(SectionHandle, FILE_MAP_READ, 0, 0, 0);
450 if (SectionMapping == NULL)
451 {
452 NtClose(SectionHandle);
454 return NULL;
455 }
456
457 CodePageEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(CODEPAGE_ENTRY));
458 if (CodePageEntry == NULL)
459 {
460 NtClose(SectionHandle);
462 return NULL;
463 }
464
465 CodePageEntry->CodePage = CodePage;
466 CodePageEntry->SectionHandle = SectionHandle;
467 CodePageEntry->SectionMapping = SectionMapping;
468
469 RtlInitCodePageTable((PUSHORT)SectionMapping, &CodePageEntry->CodePageTable);
470
471 /* Insert the new entry to list and unlock. Uff. */
472 InsertTailList(&CodePageListHead, &CodePageEntry->Entry);
474
475 return CodePageEntry;
476}
477
487static
488INT
489WINAPI
492 INT MultiByteCount,
493 LPWSTR WideCharString,
494 INT WideCharCount)
495{
496 LPCSTR MbsEnd, MbsPtrSave;
497 UCHAR Char, TrailLength;
498 WCHAR WideChar;
499 LONG Count;
500 BOOL CharIsValid, StringIsValid = TRUE;
501 const WCHAR InvalidChar = 0xFFFD;
502
503 if (Flags != 0 && Flags != MB_ERR_INVALID_CHARS)
504 {
506 return 0;
507 }
508
509 /* Does caller query for output buffer size? */
510 if (WideCharCount == 0)
511 {
512 /* validate and count the wide characters */
513 MbsEnd = MultiByteString + MultiByteCount;
514 for (; MultiByteString < MbsEnd; WideCharCount++)
515 {
516 Char = *MultiByteString++;
517 if (Char < 0x80)
518 {
519 TrailLength = 0;
520 continue;
521 }
522 if ((Char & 0xC0) == 0x80)
523 {
524 TrailLength = 0;
525 StringIsValid = FALSE;
526 continue;
527 }
528
529 TrailLength = UTF8Length[Char - 0x80];
530 if (TrailLength == 0)
531 {
532 StringIsValid = FALSE;
533 continue;
534 }
535
536 CharIsValid = TRUE;
537 MbsPtrSave = MultiByteString;
538 WideChar = Char & UTF8Mask[TrailLength];
539
540 while (TrailLength && MultiByteString < MbsEnd)
541 {
542 if ((*MultiByteString & 0xC0) != 0x80)
543 {
544 CharIsValid = StringIsValid = FALSE;
545 break;
546 }
547
548 WideChar = (WideChar << 6) | (*MultiByteString++ & 0x7f);
549 TrailLength--;
550 }
551
552 if (!CharIsValid || WideChar < UTF8LBound[UTF8Length[Char - 0x80]])
553 {
554 MultiByteString = MbsPtrSave;
555 }
556 }
557
558 if (TrailLength)
559 {
560 WideCharCount++;
561 StringIsValid = FALSE;
562 }
563
564 if (Flags == MB_ERR_INVALID_CHARS && !StringIsValid)
565 {
567 return 0;
568 }
569
570 return WideCharCount;
571 }
572
573 /* convert */
574 MbsEnd = MultiByteString + MultiByteCount;
575 for (Count = 0; Count < WideCharCount && MultiByteString < MbsEnd; Count++)
576 {
577 Char = *MultiByteString++;
578 if (Char < 0x80)
579 {
580 *WideCharString++ = Char;
581 TrailLength = 0;
582 continue;
583 }
584 if ((Char & 0xC0) == 0x80)
585 {
586 *WideCharString++ = InvalidChar;
587 TrailLength = 0;
588 StringIsValid = FALSE;
589 continue;
590 }
591
592 TrailLength = UTF8Length[Char - 0x80];
593 if (TrailLength == 0)
594 {
595 *WideCharString++ = InvalidChar;
596 StringIsValid = FALSE;
597 continue;
598 }
599
600 CharIsValid = TRUE;
601 MbsPtrSave = MultiByteString;
602 WideChar = Char & UTF8Mask[TrailLength];
603
604 while (TrailLength && MultiByteString < MbsEnd)
605 {
606 if ((*MultiByteString & 0xC0) != 0x80)
607 {
608 CharIsValid = StringIsValid = FALSE;
609 break;
610 }
611
612 WideChar = (WideChar << 6) | (*MultiByteString++ & 0x7f);
613 TrailLength--;
614 }
615
616 if (CharIsValid && UTF8LBound[UTF8Length[Char - 0x80]] <= WideChar)
617 {
618 *WideCharString++ = WideChar;
619 }
620 else
621 {
622 *WideCharString++ = InvalidChar;
623 MultiByteString = MbsPtrSave;
624 StringIsValid = FALSE;
625 }
626 }
627
628 if (TrailLength && Count < WideCharCount && MultiByteString < MbsEnd)
629 {
630 *WideCharString = InvalidChar;
631 WideCharCount++;
632 }
633
634 if (MultiByteString < MbsEnd)
635 {
637 return 0;
638 }
639
640 if (Flags == MB_ERR_INVALID_CHARS && (!StringIsValid || TrailLength))
641 {
643 return 0;
644 }
645
646 return Count;
647}
648
659static
660INT
661WINAPI
663 DWORD Flags,
665 INT MultiByteCount,
666 LPWSTR WideCharString,
667 INT WideCharCount)
668{
669 PCODEPAGE_ENTRY CodePageEntry;
671 PUSHORT MultiByteTable;
672 LPCSTR TempString;
673 INT TempLength;
674 USHORT WideChar;
675
676 /* Get code page table. */
677 CodePageEntry = IntGetCodePageEntry(CodePage);
678 if (CodePageEntry == NULL)
679 {
681 return 0;
682 }
683
684 CodePageTable = &CodePageEntry->CodePageTable;
685
686 /* If MB_USEGLYPHCHARS flag present and glyph table present */
688 {
689 /* Use glyph table */
690 MultiByteTable = CodePageTable->MultiByteTable + 256 + 1;
691 }
692 else
693 {
694 MultiByteTable = CodePageTable->MultiByteTable;
695 }
696
697 /* Different handling for DBCS code pages. */
699 {
700 UCHAR Char;
701 USHORT DBCSOffset;
702 LPCSTR MbsEnd = MultiByteString + MultiByteCount;
703 INT Count;
704
706 {
707 TempString = MultiByteString;
708
709 while (TempString < MbsEnd)
710 {
711 DBCSOffset = CodePageTable->DBCSOffsets[(UCHAR)*TempString];
712
713 if (DBCSOffset)
714 {
715 /* If lead byte is presented, but behind it there is no symbol */
716 if (((TempString + 1) == MbsEnd) || (*(TempString + 1) == 0))
717 {
719 return 0;
720 }
721
722 WideChar = CodePageTable->DBCSOffsets[DBCSOffset + *(TempString + 1)];
723
724 if (WideChar == CodePageTable->UniDefaultChar &&
725 MAKEWORD(*(TempString + 1), *TempString) != CodePageTable->TransUniDefaultChar)
726 {
728 return 0;
729 }
730
731 TempString++;
732 }
733 else
734 {
735 WideChar = MultiByteTable[(UCHAR)*TempString];
736
737 if ((WideChar == CodePageTable->UniDefaultChar &&
738 *TempString != CodePageTable->TransUniDefaultChar) ||
739 /* "Private Use" characters */
740 (WideChar >= 0xE000 && WideChar <= 0xF8FF))
741 {
743 return 0;
744 }
745 }
746
747 TempString++;
748 }
749 }
750
751 /* Does caller query for output buffer size? */
752 if (WideCharCount == 0)
753 {
754 for (; MultiByteString < MbsEnd; WideCharCount++)
755 {
756 Char = *MultiByteString++;
757
758 DBCSOffset = CodePageTable->DBCSOffsets[Char];
759
760 if (!DBCSOffset)
761 continue;
762
763 if (MultiByteString < MbsEnd)
765 }
766
767 return WideCharCount;
768 }
769
770 for (Count = 0; Count < WideCharCount && MultiByteString < MbsEnd; Count++)
771 {
772 Char = *MultiByteString++;
773
774 DBCSOffset = CodePageTable->DBCSOffsets[Char];
775
776 if (!DBCSOffset)
777 {
778 *WideCharString++ = MultiByteTable[Char];
779 continue;
780 }
781
782 if (MultiByteString == MbsEnd || *MultiByteString == 0)
783 {
784 *WideCharString++ = CodePageTable->UniDefaultChar;
785 }
786 else
787 {
788 *WideCharString++ = CodePageTable->DBCSOffsets[DBCSOffset + (UCHAR)*MultiByteString++];
789 }
790 }
791
792 if (MultiByteString < MbsEnd)
793 {
795 return 0;
796 }
797
798 return Count;
799 }
800 else /* SBCS code page */
801 {
802 /* Check for invalid characters. */
804 {
805 for (TempString = MultiByteString, TempLength = MultiByteCount;
806 TempLength > 0;
807 TempString++, TempLength--)
808 {
809 WideChar = MultiByteTable[(UCHAR)*TempString];
810
811 if ((WideChar == CodePageTable->UniDefaultChar &&
812 *TempString != CodePageTable->TransUniDefaultChar) ||
813 /* "Private Use" characters */
814 (WideChar >= 0xE000 && WideChar <= 0xF8FF))
815 {
817 return 0;
818 }
819 }
820 }
821
822 /* Does caller query for output buffer size? */
823 if (WideCharCount == 0)
824 return MultiByteCount;
825
826 /* Fill the WideCharString buffer with what will fit: Verified on WinXP */
827 for (TempLength = (WideCharCount < MultiByteCount) ? WideCharCount : MultiByteCount;
828 TempLength > 0;
829 MultiByteString++, TempLength--)
830 {
831 *WideCharString++ = MultiByteTable[(UCHAR)*MultiByteString];
832 }
833
834 /* Adjust buffer size. Wine trick ;-) */
835 if (WideCharCount < MultiByteCount)
836 {
837 MultiByteCount = WideCharCount;
839 return 0;
840 }
841 return MultiByteCount;
842 }
843}
844
853static
854INT
855WINAPI
858 INT MultiByteCount,
859 LPWSTR WideCharString,
860 INT WideCharCount)
861{
862 LONG Count;
863 UCHAR Char;
864 INT WideCharMaxLen;
865
866
867 if (Flags != 0)
868 {
870 return 0;
871 }
872
873 if (WideCharCount == 0)
874 {
875 return MultiByteCount;
876 }
877
878 WideCharMaxLen = WideCharCount > MultiByteCount ? MultiByteCount : WideCharCount;
879
880 for (Count = 0; Count < WideCharMaxLen; Count++)
881 {
882 Char = MultiByteString[Count];
883 if ( Char < 0x20 )
884 {
885 WideCharString[Count] = Char;
886 }
887 else
888 {
889 WideCharString[Count] = Char + 0xf000;
890 }
891 }
892 if (MultiByteCount > WideCharMaxLen)
893 {
895 return 0;
896 }
897
898 return WideCharMaxLen;
899}
900
909static INT
910WINAPI
912 LPCWSTR WideCharString,
913 INT WideCharCount,
915 INT MultiByteCount)
916{
917 LONG Count;
918 INT MaxLen;
919 WCHAR Char;
920
921 if (Flags!=0)
922 {
924 return 0;
925 }
926
927
928 if (MultiByteCount == 0)
929 {
930 return WideCharCount;
931 }
932
933 MaxLen = MultiByteCount > WideCharCount ? WideCharCount : MultiByteCount;
934 for (Count = 0; Count < MaxLen; Count++)
935 {
936 Char = WideCharString[Count];
937 if (Char < 0x20)
938 {
939 MultiByteString[Count] = (CHAR)Char;
940 }
941 else
942 {
943 if ((Char >= 0xf020) && (Char < 0xf100))
944 {
945 MultiByteString[Count] = Char - 0xf000;
946 }
947 else
948 {
950 return 0;
951 }
952 }
953 }
954
955 if (WideCharCount > MaxLen)
956 {
958 return 0;
959 }
960 return MaxLen;
961}
962
971static INT
972WINAPI
974 DWORD Flags,
975 LPCWSTR WideCharString,
976 INT WideCharCount,
978 INT MultiByteCount,
979 LPCSTR DefaultChar,
980 LPBOOL UsedDefaultChar)
981{
982 INT TempLength;
983 DWORD Char;
984
985 if (Flags)
986 {
988 return 0;
989 }
990
991 /* Does caller query for output buffer size? */
992 if (MultiByteCount == 0)
993 {
994 for (TempLength = 0; WideCharCount;
995 WideCharCount--, WideCharString++)
996 {
997 TempLength++;
998 if (*WideCharString >= 0x80)
999 {
1000 TempLength++;
1001 if (*WideCharString >= 0x800)
1002 {
1003 TempLength++;
1004 if (*WideCharString >= 0xd800 && *WideCharString < 0xdc00 &&
1005 WideCharCount >= 1 &&
1006 WideCharString[1] >= 0xdc00 && WideCharString[1] <= 0xe000)
1007 {
1008 WideCharCount--;
1009 WideCharString++;
1010 TempLength++;
1011 }
1012 }
1013 }
1014 }
1015 return TempLength;
1016 }
1017
1018 for (TempLength = MultiByteCount; WideCharCount; WideCharCount--, WideCharString++)
1019 {
1020 Char = *WideCharString;
1021 if (Char < 0x80)
1022 {
1023 if (!TempLength)
1024 {
1026 break;
1027 }
1028 TempLength--;
1029 *MultiByteString++ = (CHAR)Char;
1030 continue;
1031 }
1032
1033 if (Char < 0x800) /* 0x80-0x7ff: 2 bytes */
1034 {
1035 if (TempLength < 2)
1036 {
1038 break;
1039 }
1040 MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
1041 MultiByteString[0] = 0xc0 | Char;
1042 MultiByteString += 2;
1043 TempLength -= 2;
1044 continue;
1045 }
1046
1047 /* surrogate pair 0x10000-0x10ffff: 4 bytes */
1048 if (Char >= 0xd800 && Char < 0xdc00 &&
1049 WideCharCount >= 1 &&
1050 WideCharString[1] >= 0xdc00 && WideCharString[1] < 0xe000)
1051 {
1052 WideCharCount--;
1053 WideCharString++;
1054
1055 if (TempLength < 4)
1056 {
1058 break;
1059 }
1060
1061 Char = (Char - 0xd800) << 10;
1062 Char |= *WideCharString - 0xdc00;
1063 ASSERT(Char <= 0xfffff);
1064 Char += 0x10000;
1065 ASSERT(Char <= 0x10ffff);
1066
1067 MultiByteString[3] = 0x80 | (Char & 0x3f); Char >>= 6;
1068 MultiByteString[2] = 0x80 | (Char & 0x3f); Char >>= 6;
1069 MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
1070 MultiByteString[0] = 0xf0 | Char;
1071 MultiByteString += 4;
1072 TempLength -= 4;
1073 continue;
1074 }
1075
1076 /* 0x800-0xffff: 3 bytes */
1077 if (TempLength < 3)
1078 {
1080 break;
1081 }
1082 MultiByteString[2] = 0x80 | (Char & 0x3f); Char >>= 6;
1083 MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
1084 MultiByteString[0] = 0xe0 | Char;
1085 MultiByteString += 3;
1086 TempLength -= 3;
1087 }
1088
1089 return MultiByteCount - TempLength;
1090}
1091
1099static
1100inline
1101BOOL
1103{
1104 /* If the WC_NO_BEST_FIT_CHARS flag has been specified, the characters need to match exactly. */
1106 return (CodePageTable->MultiByteTable[ch] == wch);
1107
1108 /* By default, all characters except TransDefaultChar apply as a valid mapping
1109 for ch (so also "nearest" characters) */
1111 return TRUE;
1112
1113 /* The only possible left valid mapping is the default character itself */
1114 return (wch == CodePageTable->TransUniDefaultChar);
1115}
1116
1124static inline BOOL
1126{
1127 /* If ch is the default character, but the wch is not, it can't be a valid mapping */
1129 return FALSE;
1130
1131 /* If the WC_NO_BEST_FIT_CHARS flag has been specified, the characters need to match exactly. */
1133 {
1134 if(ch & 0xff00)
1135 {
1136 USHORT uOffset = CodePageTable->DBCSOffsets[ch >> 8];
1137 /* if (!uOffset) return (CodePageTable->MultiByteTable[ch] == wch); */
1138 return (CodePageTable->DBCSOffsets[uOffset + (ch & 0xff)] == wch);
1139 }
1140
1141 return (CodePageTable->MultiByteTable[ch] == wch);
1142 }
1143
1144 /* If we're still here, we have a valid mapping */
1145 return TRUE;
1146}
1147
1156static
1157INT
1158WINAPI
1160 DWORD Flags,
1161 LPCWSTR WideCharString,
1162 INT WideCharCount,
1164 INT MultiByteCount,
1165 LPCSTR DefaultChar,
1166 LPBOOL UsedDefaultChar)
1167{
1168 PCODEPAGE_ENTRY CodePageEntry;
1170 INT TempLength;
1171
1172 /* Get code page table. */
1173 CodePageEntry = IntGetCodePageEntry(CodePage);
1174 if (CodePageEntry == NULL)
1175 {
1177 return 0;
1178 }
1179
1180 CodePageTable = &CodePageEntry->CodePageTable;
1181
1182
1183 /* Different handling for DBCS code pages. */
1185 {
1186 /* If Flags, DefaultChar or UsedDefaultChar were given, we have to do some more work */
1187 if (Flags || DefaultChar || UsedDefaultChar)
1188 {
1189 BOOL TempUsedDefaultChar;
1190 USHORT DefChar;
1191
1192 /* If UsedDefaultChar is not set, set it to a temporary value, so we don't have
1193 to check on every character */
1194 if (!UsedDefaultChar)
1195 UsedDefaultChar = &TempUsedDefaultChar;
1196
1197 *UsedDefaultChar = FALSE;
1198
1199 /* Use the CodePage's TransDefaultChar if none was given. Don't modify the DefaultChar pointer here. */
1200 if (DefaultChar)
1201 DefChar = DefaultChar[1] ? ((DefaultChar[0] << 8) | DefaultChar[1]) : DefaultChar[0];
1202 else
1204
1205 /* Does caller query for output buffer size? */
1206 if (!MultiByteCount)
1207 {
1208 for (TempLength = 0; WideCharCount; WideCharCount--, WideCharString++, TempLength++)
1209 {
1210 USHORT uChar;
1211
1212 if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1213 {
1214 /* FIXME: Handle WC_COMPOSITECHECK */
1215 DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1216 }
1217
1218 uChar = ((PUSHORT) CodePageTable->WideCharTable)[*WideCharString];
1219
1220 /* Verify if the mapping is valid for handling DefaultChar and UsedDefaultChar */
1221 if (!IntIsValidDBCSMapping(CodePageTable, Flags, *WideCharString, uChar))
1222 {
1223 uChar = DefChar;
1224 *UsedDefaultChar = TRUE;
1225 }
1226
1227 /* Increment TempLength again if this is a double-byte character */
1228 if (uChar & 0xff00)
1229 TempLength++;
1230 }
1231
1232 return TempLength;
1233 }
1234
1235 /* Convert the WideCharString to the MultiByteString and verify if the mapping is valid */
1236 for (TempLength = MultiByteCount;
1237 WideCharCount && TempLength;
1238 TempLength--, WideCharString++, WideCharCount--)
1239 {
1240 USHORT uChar;
1241
1242 if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1243 {
1244 /* FIXME: Handle WC_COMPOSITECHECK */
1245 DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1246 }
1247
1248 uChar = ((PUSHORT)CodePageTable->WideCharTable)[*WideCharString];
1249
1250 /* Verify if the mapping is valid for handling DefaultChar and UsedDefaultChar */
1251 if (!IntIsValidDBCSMapping(CodePageTable, Flags, *WideCharString, uChar))
1252 {
1253 uChar = DefChar;
1254 *UsedDefaultChar = TRUE;
1255 }
1256
1257 /* Handle double-byte characters */
1258 if (uChar & 0xff00)
1259 {
1260 /* Don't output a partial character */
1261 if (TempLength == 1)
1262 break;
1263
1264 TempLength--;
1265 *MultiByteString++ = uChar >> 8;
1266 }
1267
1268 *MultiByteString++ = (char)uChar;
1269 }
1270
1271 /* WideCharCount should be 0 if all characters were converted */
1272 if (WideCharCount)
1273 {
1275 return 0;
1276 }
1277
1278 return MultiByteCount - TempLength;
1279 }
1280
1281 /* Does caller query for output buffer size? */
1282 if (!MultiByteCount)
1283 {
1284 for (TempLength = 0; WideCharCount; WideCharCount--, WideCharString++, TempLength++)
1285 {
1286 /* Increment TempLength again if this is a double-byte character */
1287 if (((PWCHAR)CodePageTable->WideCharTable)[*WideCharString] & 0xff00)
1288 TempLength++;
1289 }
1290
1291 return TempLength;
1292 }
1293
1294 /* Convert the WideCharString to the MultiByteString */
1295 for (TempLength = MultiByteCount;
1296 WideCharCount && TempLength;
1297 TempLength--, WideCharString++, WideCharCount--)
1298 {
1299 USHORT uChar = ((PUSHORT) CodePageTable->WideCharTable)[*WideCharString];
1300
1301 /* Is this a double-byte character? */
1302 if (uChar & 0xff00)
1303 {
1304 /* Don't output a partial character */
1305 if (TempLength == 1)
1306 break;
1307
1308 TempLength--;
1309 *MultiByteString++ = uChar >> 8;
1310 }
1311
1312 *MultiByteString++ = (char)uChar;
1313 }
1314
1315 /* WideCharCount should be 0 if all characters were converted */
1316 if (WideCharCount)
1317 {
1319 return 0;
1320 }
1321
1322 return MultiByteCount - TempLength;
1323 }
1324 else /* SBCS code page */
1325 {
1326 INT nReturn;
1327
1328 /* If Flags, DefaultChar or UsedDefaultChar were given, we have to do some more work */
1329 if (Flags || DefaultChar || UsedDefaultChar)
1330 {
1331 BOOL TempUsedDefaultChar;
1332 CHAR DefChar;
1333
1334 /* If UsedDefaultChar is not set, set it to a temporary value, so we don't have
1335 to check on every character */
1336 if (!UsedDefaultChar)
1337 UsedDefaultChar = &TempUsedDefaultChar;
1338
1339 *UsedDefaultChar = FALSE;
1340
1341 /* Does caller query for output buffer size? */
1342 if (!MultiByteCount)
1343 {
1344 /* Loop through the whole WideCharString and check if we can get a valid mapping for each character */
1345 for (TempLength = 0; WideCharCount; TempLength++, WideCharString++, WideCharCount--)
1346 {
1347 if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1348 {
1349 /* FIXME: Handle WC_COMPOSITECHECK */
1350 DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1351 }
1352
1353 if (!*UsedDefaultChar)
1354 *UsedDefaultChar = !IntIsValidSBCSMapping(CodePageTable,
1355 Flags,
1356 *WideCharString,
1357 ((PCHAR)CodePageTable->WideCharTable)[*WideCharString]);
1358 }
1359
1360 return TempLength;
1361 }
1362
1363 /* Use the CodePage's TransDefaultChar if none was given. Don't modify the DefaultChar pointer here. */
1364 if (DefaultChar)
1365 DefChar = *DefaultChar;
1366 else
1368
1369 /* Convert the WideCharString to the MultiByteString and verify if the mapping is valid */
1370 for (TempLength = MultiByteCount;
1371 WideCharCount && TempLength;
1372 MultiByteString++, TempLength--, WideCharString++, WideCharCount--)
1373 {
1374 if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1375 {
1376 /* FIXME: Handle WC_COMPOSITECHECK */
1377 DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1378 }
1379
1380 *MultiByteString = ((PCHAR)CodePageTable->WideCharTable)[*WideCharString];
1381
1382 if (!IntIsValidSBCSMapping(CodePageTable, Flags, *WideCharString, *MultiByteString))
1383 {
1384 *MultiByteString = DefChar;
1385 *UsedDefaultChar = TRUE;
1386 }
1387 }
1388
1389 /* WideCharCount should be 0 if all characters were converted */
1390 if (WideCharCount)
1391 {
1393 return 0;
1394 }
1395
1396 return MultiByteCount - TempLength;
1397 }
1398
1399 /* Does caller query for output buffer size? */
1400 if (!MultiByteCount)
1401 return WideCharCount;
1402
1403 /* Is the buffer large enough? */
1404 if (MultiByteCount < WideCharCount)
1405 {
1406 /* Convert the string up to MultiByteCount and return 0 */
1407 WideCharCount = MultiByteCount;
1409 nReturn = 0;
1410 }
1411 else
1412 {
1413 /* Otherwise WideCharCount will be the number of converted characters */
1414 nReturn = WideCharCount;
1415 }
1416
1417 /* Convert the WideCharString to the MultiByteString */
1418 for (TempLength = WideCharCount; --TempLength >= 0; WideCharString++, MultiByteString++)
1419 {
1420 *MultiByteString = ((PCHAR)CodePageTable->WideCharTable)[*WideCharString];
1421 }
1422
1423 return nReturn;
1424 }
1425}
1426
1434static BOOL
1435WINAPI
1437{
1438 UINT i;
1439
1440 if (TableInfo->MaximumCharacterSize == 2)
1441 {
1442 for (i = 0; i < MAXIMUM_LEADBYTES && TableInfo->LeadByte[i]; i += 2)
1443 {
1444 if (Byte >= TableInfo->LeadByte[i] && Byte <= TableInfo->LeadByte[i+1])
1445 return TRUE;
1446 }
1447 }
1448
1449 return FALSE;
1450}
1451
1452/* PUBLIC FUNCTIONS ***********************************************************/
1453
1481BOOL
1482WINAPI
1484 UINT Base,
1485 ULONG Unknown,
1486 LPSTR BaseName,
1487 LPSTR Result,
1488 ULONG ResultSize)
1489{
1490 CHAR Integer[11];
1491
1492 if (!NT_SUCCESS(RtlIntegerToChar(CodePage, Base, sizeof(Integer), Integer)))
1493 return FALSE;
1494
1495 /*
1496 * If the name including the terminating NULL character doesn't
1497 * fit in the output buffer then fail.
1498 */
1499 if (strlen(Integer) + strlen(BaseName) >= ResultSize)
1500 return FALSE;
1501
1502 lstrcpyA(Result, BaseName);
1503 lstrcatA(Result, Integer);
1504
1505 return TRUE;
1506}
1507
1526BOOL
1527WINAPI
1529{
1530 WCHAR ValueNameBuffer[11];
1536 DWORD KvpiSize;
1537 BOOL bRetValue;
1538
1539 bRetValue = FALSE;
1540
1541 /* Convert the codepage number to string. */
1542 ValueName.Buffer = ValueNameBuffer;
1543 ValueName.MaximumLength = sizeof(ValueNameBuffer);
1544
1545 if (!NT_SUCCESS(RtlIntegerToUnicodeString(CodePage, 10, &ValueName)))
1546 return bRetValue;
1547
1548 /* Open the registry key containing file name mappings. */
1549 RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System\\"
1550 L"CurrentControlSet\\Control\\Nls\\CodePage");
1552 NULL, NULL);
1554 if (!NT_SUCCESS(Status))
1555 {
1556 return bRetValue;
1557 }
1558
1559 /* Allocate buffer that will be used to query the value data. */
1560 KvpiSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + (MAX_PATH * sizeof(WCHAR));
1561 Kvpi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, KvpiSize);
1562 if (Kvpi == NULL)
1563 {
1565 return bRetValue;
1566 }
1567
1568 /* Query the file name for our code page. */
1570 Kvpi, KvpiSize, &KvpiSize);
1571
1573
1574 /* Check if we succeded and the value is non-empty string. */
1575 if (NT_SUCCESS(Status) && Kvpi->Type == REG_SZ &&
1576 Kvpi->DataLength > sizeof(WCHAR))
1577 {
1578 bRetValue = TRUE;
1579 if (FileName != NULL)
1580 {
1581 lstrcpynW(FileName, (WCHAR*)Kvpi->Data,
1582 min(Kvpi->DataLength / sizeof(WCHAR), FileNameSize));
1583 }
1584 }
1585
1586 /* free temporary buffer */
1587 HeapFree(GetProcessHeap(),0,Kvpi);
1588 return bRetValue;
1589}
1590
1602BOOL
1603WINAPI
1605{
1606 if (CodePage == 0) return FALSE;
1607 if (CodePage == CP_UTF8 || CodePage == CP_UTF7)
1608 return TRUE;
1609 if (IntGetLoadedCodePageEntry(CodePage))
1610 return TRUE;
1611 return GetCPFileNameFromRegistry(CodePage, NULL, 0);
1612}
1613
1614static inline BOOL utf7_write_w(WCHAR *dst, int dstlen, int *index, WCHAR character)
1615{
1616 if (dstlen > 0)
1617 {
1618 if (*index >= dstlen)
1619 return FALSE;
1620
1621 dst[*index] = character;
1622 }
1623
1624 (*index)++;
1625
1626 return TRUE;
1627}
1628
1629static INT Utf7ToWideChar(const char *src, int srclen, WCHAR *dst, int dstlen)
1630{
1631 static const signed char base64_decoding_table[] =
1632 {
1633 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00-0x0F */
1634 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10-0x1F */
1635 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20-0x2F */
1636 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30-0x3F */
1637 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40-0x4F */
1638 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50-0x5F */
1639 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60-0x6F */
1640 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 /* 0x70-0x7F */
1641 };
1642
1643 const char *source_end = src + srclen;
1644 int dest_index = 0;
1645
1646 DWORD byte_pair = 0;
1647 short offset = 0;
1648
1649 while (src < source_end)
1650 {
1651 if (*src == '+')
1652 {
1653 src++;
1654 if (src >= source_end)
1655 break;
1656
1657 if (*src == '-')
1658 {
1659 /* just a plus sign escaped as +- */
1660 if (!utf7_write_w(dst, dstlen, &dest_index, '+'))
1661 {
1663 return 0;
1664 }
1665 src++;
1666 continue;
1667 }
1668
1669 do
1670 {
1671 signed char sextet = *src;
1672 if (sextet == '-')
1673 {
1674 /* skip over the dash and end base64 decoding
1675 * the current, unfinished byte pair is discarded */
1676 src++;
1677 offset = 0;
1678 break;
1679 }
1680 if (sextet < 0)
1681 {
1682 /* the next character of src is < 0 and therefore not part of a base64 sequence
1683 * the current, unfinished byte pair is NOT discarded in this case
1684 * this is probably a bug in Windows */
1685 break;
1686 }
1687
1688 sextet = base64_decoding_table[sextet];
1689 if (sextet == -1)
1690 {
1691 /* -1 means that the next character of src is not part of a base64 sequence
1692 * in other words, all sextets in this base64 sequence have been processed
1693 * the current, unfinished byte pair is discarded */
1694 offset = 0;
1695 break;
1696 }
1697
1698 byte_pair = (byte_pair << 6) | sextet;
1699 offset += 6;
1700
1701 if (offset >= 16)
1702 {
1703 /* this byte pair is done */
1704 if (!utf7_write_w(dst, dstlen, &dest_index, (byte_pair >> (offset - 16)) & 0xFFFF))
1705 {
1707 return 0;
1708 }
1709 offset -= 16;
1710 }
1711
1712 src++;
1713 }
1714 while (src < source_end);
1715 }
1716 else
1717 {
1718 /* we have to convert to unsigned char in case *src < 0 */
1719 if (!utf7_write_w(dst, dstlen, &dest_index, (unsigned char)*src))
1720 {
1722 return 0;
1723 }
1724 src++;
1725 }
1726 }
1727
1728 return dest_index;
1729}
1730
1761INT
1762WINAPI
1764 DWORD Flags,
1766 INT MultiByteCount,
1767 LPWSTR WideCharString,
1768 INT WideCharCount)
1769{
1770 /* Check the parameters. */
1771 if (MultiByteString == NULL ||
1772 MultiByteCount == 0 || WideCharCount < 0 ||
1773 (WideCharCount && (WideCharString == NULL ||
1774 (PVOID)MultiByteString == (PVOID)WideCharString)))
1775 {
1777 return 0;
1778 }
1779
1780 /* Determine the input string length. */
1781 if (MultiByteCount < 0)
1782 {
1783 MultiByteCount = lstrlenA(MultiByteString) + 1;
1784 }
1785
1786 switch (CodePage)
1787 {
1788 case CP_UTF8:
1791 MultiByteCount,
1792 WideCharString,
1793 WideCharCount);
1794
1795 case CP_UTF7:
1796 if (Flags)
1797 {
1799 return 0;
1800 }
1801 return Utf7ToWideChar(MultiByteString, MultiByteCount,
1802 WideCharString, WideCharCount);
1803
1804 case CP_SYMBOL:
1807 MultiByteCount,
1808 WideCharString,
1809 WideCharCount);
1810 default:
1811 return IntMultiByteToWideCharCP(CodePage,
1812 Flags,
1814 MultiByteCount,
1815 WideCharString,
1816 WideCharCount);
1817 }
1818}
1819
1820static inline BOOL utf7_can_directly_encode(WCHAR codepoint)
1821{
1822 static const BOOL directly_encodable_table[] =
1823 {
1824 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, /* 0x00 - 0x0F */
1825 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1F */
1826 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* 0x20 - 0x2F */
1827 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x30 - 0x3F */
1828 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4F */
1829 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x50 - 0x5F */
1830 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6F */
1831 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* 0x70 - 0x7A */
1832 };
1833
1834 return codepoint <= 0x7A ? directly_encodable_table[codepoint] : FALSE;
1835}
1836
1837static inline BOOL utf7_write_c(char *dst, int dstlen, int *index, char character)
1838{
1839 if (dstlen > 0)
1840 {
1841 if (*index >= dstlen)
1842 return FALSE;
1843
1844 dst[*index] = character;
1845 }
1846
1847 (*index)++;
1848
1849 return TRUE;
1850}
1851
1852static INT WideCharToUtf7(const WCHAR *src, int srclen, char *dst, int dstlen)
1853{
1854 static const char base64_encoding_table[] =
1855 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1856
1857 const WCHAR *source_end = src + srclen;
1858 int dest_index = 0;
1859
1860 while (src < source_end)
1861 {
1862 if (*src == '+')
1863 {
1864 if (!utf7_write_c(dst, dstlen, &dest_index, '+'))
1865 {
1867 return 0;
1868 }
1869 if (!utf7_write_c(dst, dstlen, &dest_index, '-'))
1870 {
1872 return 0;
1873 }
1874 src++;
1875 }
1876 else if (utf7_can_directly_encode(*src))
1877 {
1878 if (!utf7_write_c(dst, dstlen, &dest_index, *src))
1879 {
1881 return 0;
1882 }
1883 src++;
1884 }
1885 else
1886 {
1887 unsigned int offset = 0;
1888 DWORD byte_pair = 0;
1889
1890 if (!utf7_write_c(dst, dstlen, &dest_index, '+'))
1891 {
1893 return 0;
1894 }
1895
1896 while (src < source_end && !utf7_can_directly_encode(*src))
1897 {
1898 byte_pair = (byte_pair << 16) | *src;
1899 offset += 16;
1900 while (offset >= 6)
1901 {
1902 if (!utf7_write_c(dst, dstlen, &dest_index, base64_encoding_table[(byte_pair >> (offset - 6)) & 0x3F]))
1903 {
1905 return 0;
1906 }
1907 offset -= 6;
1908 }
1909 src++;
1910 }
1911
1912 if (offset)
1913 {
1914 /* Windows won't create a padded base64 character if there's no room for the - sign
1915 * as well ; this is probably a bug in Windows */
1916 if (dstlen > 0 && dest_index + 1 >= dstlen)
1917 {
1919 return 0;
1920 }
1921
1922 byte_pair <<= (6 - offset);
1923 if (!utf7_write_c(dst, dstlen, &dest_index, base64_encoding_table[byte_pair & 0x3F]))
1924 {
1926 return 0;
1927 }
1928 }
1929
1930 /* Windows always explicitly terminates the base64 sequence
1931 even though RFC 2152 (page 3, rule 2) does not require this */
1932 if (!utf7_write_c(dst, dstlen, &dest_index, '-'))
1933 {
1935 return 0;
1936 }
1937 }
1938 }
1939
1940 return dest_index;
1941}
1942
1943/*
1944 * A function similar to LoadStringW, but adapted for usage by GetCPInfoExW
1945 * and GetGeoInfoW. It uses the current user localization, otherwise falls back
1946 * to English (US). Contrary to LoadStringW which always saves the loaded string
1947 * into the user-given buffer, truncating the string if needed, this function
1948 * returns instead an ERROR_INSUFFICIENT_BUFFER error code if the user buffer
1949 * is not large enough.
1950 */
1951UINT
1953 IN UINT uID,
1955 IN UINT cchDest,
1956 IN LANGID lang)
1957{
1958 HRSRC hrsrc;
1959 HGLOBAL hmem;
1960 LCID lcid;
1961 LANGID langId;
1962 const WCHAR *p;
1963 UINT i;
1964
1965 /* See HACK in winnls/lang/xx-XX.rc files */
1966 if (uID == 37)
1967 uID = uID * 100;
1968
1970
1971 langId = LANGIDFROMLCID(lcid);
1972
1973 if (PRIMARYLANGID(langId) == LANG_NEUTRAL)
1975
1978 MAKEINTRESOURCEW((uID >> 4) + 1),
1979 langId);
1980
1981 /* English fallback */
1982 if (!hrsrc)
1983 {
1986 MAKEINTRESOURCEW((uID >> 4) + 1),
1988 }
1989
1990 if (!hrsrc)
1991 goto NotFound;
1992
1993 hmem = LoadResource(hCurrentModule, hrsrc);
1994 if (!hmem)
1995 goto NotFound;
1996
1997 p = LockResource(hmem);
1998
1999 for (i = 0; i < (uID & 0x0F); i++)
2000 p += *p + 1;
2001
2002 /* Needed for GetGeoInfo(): return the needed string size including the NULL terminator */
2003 if (cchDest == 0)
2004 return *p + 1;
2005 /* Needed for GetGeoInfo(): bail out if the user buffer is not large enough */
2006 if (*p + 1 > cchDest)
2007 {
2009 return 0;
2010 }
2011
2012 i = *p;
2013 if (i > 0)
2014 {
2015 memcpy(lpszDest, p + 1, i * sizeof(WCHAR));
2016 lpszDest[i] = L'\0';
2017 return i;
2018 }
2019#if 0
2020 else
2021 {
2022 if (cchDest >= 1)
2023 lpszDest[0] = L'\0';
2024 /* Fall-back */
2025 }
2026#endif
2027
2028NotFound:
2029 DPRINT1("Resource not found: uID = %lu\n", uID);
2031 return 0;
2032}
2033
2034/*
2035 * @implemented
2036 */
2037BOOL
2038WINAPI
2040 LPCPINFO CodePageInfo)
2041{
2042 PCODEPAGE_ENTRY CodePageEntry;
2043
2044 if (!CodePageInfo)
2045 {
2047 return FALSE;
2048 }
2049
2050 CodePageEntry = IntGetCodePageEntry(CodePage);
2051 if (CodePageEntry == NULL)
2052 {
2053 switch(CodePage)
2054 {
2055 case CP_UTF7:
2056 case CP_UTF8:
2057 RtlZeroMemory(CodePageInfo, sizeof(*CodePageInfo));
2058 CodePageInfo->DefaultChar[0] = 0x3f;
2059 CodePageInfo->DefaultChar[1] = 0;
2060 CodePageInfo->LeadByte[0] = CodePageInfo->LeadByte[1] = 0;
2061 CodePageInfo->MaxCharSize = (CodePage == CP_UTF7) ? 5 : 4;
2062 return TRUE;
2063 }
2064
2065 DPRINT1("Invalid CP!: %lx\n", CodePage);
2067 return FALSE;
2068 }
2069
2070 RtlZeroMemory(CodePageInfo, sizeof(*CodePageInfo));
2071 if (CodePageEntry->CodePageTable.DefaultChar & 0xff00)
2072 {
2073 CodePageInfo->DefaultChar[0] = (CodePageEntry->CodePageTable.DefaultChar & 0xff00) >> 8;
2074 CodePageInfo->DefaultChar[1] = CodePageEntry->CodePageTable.DefaultChar & 0x00ff;
2075 }
2076 else
2077 {
2078 CodePageInfo->DefaultChar[0] = CodePageEntry->CodePageTable.DefaultChar & 0xff;
2079 CodePageInfo->DefaultChar[1] = 0;
2080 }
2081
2082 if ((CodePageInfo->MaxCharSize = CodePageEntry->CodePageTable.MaximumCharacterSize) == 2)
2083 memcpy(CodePageInfo->LeadByte, CodePageEntry->CodePageTable.LeadByte, sizeof(CodePageInfo->LeadByte));
2084 else
2085 CodePageInfo->LeadByte[0] = CodePageInfo->LeadByte[1] = 0;
2086
2087 return TRUE;
2088}
2089
2090/*
2091 * @implemented
2092 */
2093BOOL
2094WINAPI
2096 DWORD dwFlags,
2097 LPCPINFOEXW lpCPInfoEx)
2098{
2099 if (!GetCPInfo(CodePage, (LPCPINFO)lpCPInfoEx))
2100 return FALSE;
2101
2102 switch(CodePage)
2103 {
2104 case CP_UTF7:
2105 {
2106 lpCPInfoEx->CodePage = CP_UTF7;
2107 lpCPInfoEx->UnicodeDefaultChar = 0x3f;
2108 return GetLocalisedText(lpCPInfoEx->CodePage,
2109 lpCPInfoEx->CodePageName,
2110 ARRAYSIZE(lpCPInfoEx->CodePageName),
2111 GetThreadLocale()) != 0;
2112 }
2113 break;
2114
2115 case CP_UTF8:
2116 {
2117 lpCPInfoEx->CodePage = CP_UTF8;
2118 lpCPInfoEx->UnicodeDefaultChar = 0x3f;
2119 return GetLocalisedText(lpCPInfoEx->CodePage,
2120 lpCPInfoEx->CodePageName,
2121 ARRAYSIZE(lpCPInfoEx->CodePageName),
2122 GetThreadLocale()) != 0;
2123 }
2124
2125 default:
2126 {
2127 PCODEPAGE_ENTRY CodePageEntry;
2128
2129 CodePageEntry = IntGetCodePageEntry(CodePage);
2130 if (CodePageEntry == NULL)
2131 {
2132 DPRINT1("Could not get CodePage Entry! CodePageEntry = NULL\n");
2134 return FALSE;
2135 }
2136
2137 lpCPInfoEx->CodePage = CodePageEntry->CodePageTable.CodePage;
2138 lpCPInfoEx->UnicodeDefaultChar = CodePageEntry->CodePageTable.UniDefaultChar;
2139 return GetLocalisedText(lpCPInfoEx->CodePage,
2140 lpCPInfoEx->CodePageName,
2141 ARRAYSIZE(lpCPInfoEx->CodePageName),
2142 GetThreadLocale()) != 0;
2143 }
2144 break;
2145 }
2146}
2147
2148
2149/*
2150 * @implemented
2151 */
2152BOOL
2153WINAPI
2155 DWORD dwFlags,
2156 LPCPINFOEXA lpCPInfoEx)
2157{
2158 CPINFOEXW CPInfo;
2159
2160 if (!GetCPInfoExW(CodePage, dwFlags, &CPInfo))
2161 return FALSE;
2162
2163 /* the layout is the same except for CodePageName */
2164 memcpy(lpCPInfoEx, &CPInfo, sizeof(CPINFOEXA));
2165
2167 0,
2168 CPInfo.CodePageName,
2169 -1,
2170 lpCPInfoEx->CodePageName,
2171 sizeof(lpCPInfoEx->CodePageName),
2172 NULL,
2173 NULL);
2174 return TRUE;
2175}
2176
2216INT
2217WINAPI
2219 DWORD Flags,
2220 LPCWSTR WideCharString,
2221 INT WideCharCount,
2223 INT MultiByteCount,
2224 LPCSTR DefaultChar,
2225 LPBOOL UsedDefaultChar)
2226{
2227 /* Check the parameters. */
2228 if (WideCharString == NULL ||
2229 WideCharCount == 0 ||
2230 (MultiByteString == NULL && MultiByteCount > 0) ||
2231 (PVOID)WideCharString == (PVOID)MultiByteString ||
2232 MultiByteCount < 0)
2233 {
2235 return 0;
2236 }
2237
2238 /* Determine the input string length. */
2239 if (WideCharCount < 0)
2240 {
2241 WideCharCount = lstrlenW(WideCharString) + 1;
2242 }
2243
2244 switch (CodePage)
2245 {
2246 case CP_UTF8:
2247 if (DefaultChar != NULL || UsedDefaultChar != NULL)
2248 {
2250 return 0;
2251 }
2252 return IntWideCharToMultiByteUTF8(CodePage,
2253 Flags,
2254 WideCharString,
2255 WideCharCount,
2257 MultiByteCount,
2258 DefaultChar,
2259 UsedDefaultChar);
2260
2261 case CP_UTF7:
2262 if (DefaultChar != NULL || UsedDefaultChar != NULL)
2263 {
2265 return 0;
2266 }
2267 if (Flags)
2268 {
2270 return 0;
2271 }
2272 return WideCharToUtf7(WideCharString, WideCharCount,
2273 MultiByteString, MultiByteCount);
2274
2275 case CP_SYMBOL:
2276 if ((DefaultChar!=NULL) || (UsedDefaultChar!=NULL))
2277 {
2279 return 0;
2280 }
2282 WideCharString,
2283 WideCharCount,
2285 MultiByteCount);
2286
2287 default:
2288 return IntWideCharToMultiByteCP(CodePage,
2289 Flags,
2290 WideCharString,
2291 WideCharCount,
2293 MultiByteCount,
2294 DefaultChar,
2295 UsedDefaultChar);
2296 }
2297}
2298
2307UINT
2308WINAPI
2310{
2312}
2313
2322UINT
2323WINAPI
2325{
2327}
2328
2337BOOL
2338WINAPI
2339IsDBCSLeadByteEx(UINT CodePage, BYTE TestByte)
2340{
2341 PCODEPAGE_ENTRY CodePageEntry;
2342
2343 CodePageEntry = IntGetCodePageEntry(CodePage);
2344 if (CodePageEntry != NULL)
2345 return IntIsLeadByte(&CodePageEntry->CodePageTable, TestByte);
2346
2348 return FALSE;
2349}
2350
2359BOOL
2360WINAPI
2362{
2363 return IntIsLeadByte(&AnsiCodePage.CodePageTable, TestByte);
2364}
2365
2394WINAPI
2399{
2402 PSID WorldSid;
2403 PACL Dacl;
2405
2407 {
2408 DPRINT1("Security descriptor size too small\n");
2410 }
2411
2412 /* Create the World SID */
2414 1,
2416 0, 0, 0, 0, 0, 0, 0,
2417 &WorldSid);
2418 if (!NT_SUCCESS(Status))
2419 {
2420 DPRINT1("Failed to create World SID (Status 0x%08x)\n", Status);
2421 return Status;
2422 }
2423
2424 /* Initialize the security descriptor */
2427 if (!NT_SUCCESS(Status))
2428 {
2429 DPRINT1("Failed to create security descriptor (Status 0x%08x)\n", Status);
2430 goto Quit;
2431 }
2432
2433 /* The DACL follows the security descriptor, and includes the World SID */
2436
2437 /* Create the DACL */
2439 if (!NT_SUCCESS(Status))
2440 {
2441 DPRINT1("Failed to create DACL (Status 0x%08x)\n", Status);
2442 goto Quit;
2443 }
2444
2445 /* Add an allowed access ACE to the World SID */
2447 if (!NT_SUCCESS(Status))
2448 {
2449 DPRINT1("Failed to add allowed access ACE for World SID (Status 0x%08x)\n", Status);
2450 goto Quit;
2451 }
2452
2453 /* Set the DACL to the descriptor */
2455 if (!NT_SUCCESS(Status))
2456 {
2457 DPRINT1("Failed to set DACL into descriptor (Status 0x%08x)\n", Status);
2458 goto Quit;
2459 }
2460
2461Quit:
2463 return Status;
2464}
2465
2466/*
2467 * @unimplemented
2468 */
2470{
2471 STUB;
2472 return 0;
2473}
2474
2475/*
2476 * @unimplemented
2477 */
2479{
2480 STUB;
2481}
2482
2483/*
2484 * @unimplemented
2485 */
2487{
2488 STUB;
2489 return 0;
2490}
2491
2492/*
2493 * @unimplemented
2494 */
2495BOOL
2496WINAPI
2497ValidateLCType(int a1, unsigned int a2, int a3, int a4)
2498{
2499 STUB;
2500 return FALSE;
2501}
2502
2503/*
2504 * @unimplemented
2505 */
2506BOOL
2507WINAPI
2509{
2510 STUB;
2511 return TRUE;
2512}
2513
2514/*
2515 * @unimplemented
2516 */
2517VOID
2518WINAPI
2520{
2521 STUB;
2522 lpUnknown = NULL;
2523}
2524
2525/*
2526 * @unimplemented
2527 */
2528VOID
2529WINAPI
2531{
2532 STUB;
2533 lpUnknown = NULL;
2534}
2535
2536/*
2537 * @unimplemented
2538 */
2539BOOL
2540WINAPI
2542{
2543 STUB;
2544 return TRUE;
2545}
2546
2547/*
2548 * @unimplemented
2549 */
2550ULONG
2551WINAPI
2553{
2554 STUB;
2555 return 0;
2556}
2557
2558/*
2559 * @unimplemented
2560 */
2561BOOL
2562WINAPI
2566 IN LPCWSTR lpString,
2567 IN INT cchStr)
2568{
2569 STUB;
2570 return TRUE;
2571}
2572
2573/*
2574 * @unimplemented
2575 */
2576BOOL
2577WINAPI
2579 IN LCID Locale,
2581{
2582 STUB;
2583 return TRUE;
2584}
2585
2586/*
2587 * @unimplemented
2588 */
2589BOOL
2590WINAPI
2592 IN LPCWSTR lpLocaleName,
2594{
2595 STUB;
2596 return TRUE;
2597}
2598
2599/* 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]
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
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
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:1159
BOOL WINAPI GetNLSVersion(IN NLS_FUNCTION Function, IN LCID Locale, IN OUT LPNLSVERSIONINFO lpVersionInformation)
Definition: nls.c:2578
static BOOL IntIsValidSBCSMapping(PCPTABLEINFO CodePageTable, DWORD Flags, WCHAR wch, UCHAR ch)
Definition: nls.c:1102
static const char UTF8Length[128]
Definition: nls.c:25
static BOOL utf7_can_directly_encode(WCHAR codepoint)
Definition: nls.c:1820
BOOL WINAPI GetCPInfo(UINT CodePage, LPCPINFO CodePageInfo)
Definition: nls.c:2039
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:2563
VOID WINAPI NlsConvertIntegerToString(ULONG Value, ULONG Base, ULONG strsize, LPWSTR str, ULONG strsize2)
Definition: nls.c:2478
static INT WideCharToUtf7(const WCHAR *src, int srclen, char *dst, int dstlen)
Definition: nls.c:1852
BOOL WINAPI IsDBCSLeadByteEx(UINT CodePage, BYTE TestByte)
Definition: nls.c:2339
static BOOL utf7_write_c(char *dst, int dstlen, int *index, char character)
Definition: nls.c:1837
BOOL WINAPI ValidateLCType(int a1, unsigned int a2, int a3, int a4)
Definition: nls.c:2497
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:1952
BOOL WINAPI IsValidCodePage(UINT CodePage)
Definition: nls.c:1604
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:2591
static CODEPAGE_ENTRY AnsiCodePage
Definition: nls.c:46
ULONG WINAPI NlsGetCacheUpdateCount(VOID)
Definition: nls.c:2552
static const unsigned long UTF8LBound[]
Definition: nls.c:41
UINT WINAPI SetCPGlobal(UINT CodePage)
Definition: nls.c:2486
static BOOL utf7_write_w(WCHAR *dst, int dstlen, int *index, WCHAR character)
Definition: nls.c:1614
BOOL WINAPI GetNlsSectionName(UINT CodePage, UINT Base, ULONG Unknown, LPSTR BaseName, LPSTR Result, ULONG ResultSize)
Definition: nls.c:1483
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:2395
BOOL WINAPI IsValidUILanguage(LANGID langid)
Definition: nls.c:2469
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:973
static RTL_CRITICAL_SECTION CodePageListLock
Definition: nls.c:48
VOID WINAPI GetLinguistLangSize(LPVOID lpUnknown)
Definition: nls.c:2530
BOOL WINAPI ValidateLocale(IN ULONG LocaleId)
Definition: nls.c:2541
static INT Utf7ToWideChar(const char *src, int srclen, WCHAR *dst, int dstlen)
Definition: nls.c:1629
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:1125
BOOL WINAPI GetCPFileNameFromRegistry(UINT CodePage, LPWSTR FileName, ULONG FileNameSize)
Definition: nls.c:1528
static INT WINAPI IntMultiByteToWideCharUTF8(DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:490
BOOL WINAPI NlsResetProcessLocale(VOID)
Definition: nls.c:2508
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:1436
BOOL WINAPI GetCPInfoExA(UINT CodePage, DWORD dwFlags, LPCPINFOEXA lpCPInfoEx)
Definition: nls.c:2154
BOOL WINAPI GetCPInfoExW(UINT CodePage, DWORD dwFlags, LPCPINFOEXW lpCPInfoEx)
Definition: nls.c:2095
VOID WINAPI GetDefaultSortkeySize(LPVOID lpUnknown)
Definition: nls.c:2519
static INT WINAPI IntWideCharToMultiByteSYMBOL(DWORD Flags, LPCWSTR WideCharString, INT WideCharCount, LPSTR MultiByteString, INT MultiByteCount)
Definition: nls.c:911
static INT WINAPI IntMultiByteToWideCharCP(UINT CodePage, DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:662
BOOL WINAPI IsDBCSLeadByte(BYTE TestByte)
Definition: nls.c:2361
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:856
LCID lcid
Definition: locale.c:5656
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
#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
LPCWSTR LPCWSTR LPCWSTR DWORD dwFlags
Definition: env.c:37
static const struct update_accum a1
Definition: msg.c:578
static const struct update_accum a2
Definition: msg.c:586
static const struct update_accum a3
Definition: msg.c:600
static const struct update_accum a4
Definition: msg.c:2285
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:1617
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:4311
_In_ BOOLEAN DaclPresent
Definition: rtlfuncs.h:1659
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2478
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:1618
_In_ BOOLEAN _In_opt_ PACL _In_opt_ BOOLEAN DaclDefaulted
Definition: rtlfuncs.h:1662
#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:1256
@ KeyValuePartialInformation
Definition: nt_native.h:1182
#define KEY_READ
Definition: nt_native.h:1023
#define DIRECTORY_TRAVERSE
Definition: nt_native.h:1255
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:1259
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
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:603
BYTE DefaultChar[MAX_DEFAULTCHAR]
Definition: winnls.h:602
UINT MaxCharSize
Definition: winnls.h:601
CHAR CodePageName[MAX_PATH]
Definition: winnls.h:611
WCHAR UnicodeDefaultChar
Definition: winnls.h:617
WCHAR CodePageName[MAX_PATH]
Definition: winnls.h:619
UINT CodePage
Definition: winnls.h:618
_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:2699
_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
BOOL * LPBOOL
Definition: windef.h:162
#define WINAPI
Definition: msvc.h:6
#define ERROR_NO_UNICODE_TRANSLATION
Definition: winerror.h:974
#define ERROR_INVALID_FLAGS
Definition: winerror.h:908
#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:1198
#define CP_UTF7
Definition: winnls.h:253
#define CP_MACCP
Definition: winnls.h:250
_In_ DWORD _In_ int _In_ int cchDest
Definition: winnls.h:1197
#define LOCALE_IDEFAULTANSICODEPAGE
Definition: winnls.h:45
#define LOCALE_IDEFAULTMACCODEPAGE
Definition: winnls.h:46
NLS_FUNCTION
Definition: winnls.h:570
#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
char * LPSTR
Definition: xmlstorage.h:182
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193