ReactOS 0.4.15-dev-6663-gd1e9fe1
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
1969 lcid = ConvertDefaultLocale(lang);
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 CodePageInfo->DefaultChar[0] = 0x3f;
2058 CodePageInfo->DefaultChar[1] = 0;
2059 CodePageInfo->LeadByte[0] = CodePageInfo->LeadByte[1] = 0;
2060 CodePageInfo->MaxCharSize = (CodePage == CP_UTF7) ? 5 : 4;
2061 return TRUE;
2062 }
2063
2064 DPRINT1("Invalid CP!: %lx\n", CodePage);
2066 return FALSE;
2067 }
2068
2069 if (CodePageEntry->CodePageTable.DefaultChar & 0xff00)
2070 {
2071 CodePageInfo->DefaultChar[0] = (CodePageEntry->CodePageTable.DefaultChar & 0xff00) >> 8;
2072 CodePageInfo->DefaultChar[1] = CodePageEntry->CodePageTable.DefaultChar & 0x00ff;
2073 }
2074 else
2075 {
2076 CodePageInfo->DefaultChar[0] = CodePageEntry->CodePageTable.DefaultChar & 0xff;
2077 CodePageInfo->DefaultChar[1] = 0;
2078 }
2079
2080 if ((CodePageInfo->MaxCharSize = CodePageEntry->CodePageTable.MaximumCharacterSize) == 2)
2081 memcpy(CodePageInfo->LeadByte, CodePageEntry->CodePageTable.LeadByte, sizeof(CodePageInfo->LeadByte));
2082 else
2083 CodePageInfo->LeadByte[0] = CodePageInfo->LeadByte[1] = 0;
2084
2085 return TRUE;
2086}
2087
2088/*
2089 * @implemented
2090 */
2091BOOL
2092WINAPI
2094 DWORD dwFlags,
2095 LPCPINFOEXW lpCPInfoEx)
2096{
2097 if (!GetCPInfo(CodePage, (LPCPINFO)lpCPInfoEx))
2098 return FALSE;
2099
2100 switch(CodePage)
2101 {
2102 case CP_UTF7:
2103 {
2104 lpCPInfoEx->CodePage = CP_UTF7;
2105 lpCPInfoEx->UnicodeDefaultChar = 0x3f;
2106 return GetLocalisedText(lpCPInfoEx->CodePage,
2107 lpCPInfoEx->CodePageName,
2108 ARRAYSIZE(lpCPInfoEx->CodePageName),
2109 GetThreadLocale()) != 0;
2110 }
2111 break;
2112
2113 case CP_UTF8:
2114 {
2115 lpCPInfoEx->CodePage = CP_UTF8;
2116 lpCPInfoEx->UnicodeDefaultChar = 0x3f;
2117 return GetLocalisedText(lpCPInfoEx->CodePage,
2118 lpCPInfoEx->CodePageName,
2119 ARRAYSIZE(lpCPInfoEx->CodePageName),
2120 GetThreadLocale()) != 0;
2121 }
2122
2123 default:
2124 {
2125 PCODEPAGE_ENTRY CodePageEntry;
2126
2127 CodePageEntry = IntGetCodePageEntry(CodePage);
2128 if (CodePageEntry == NULL)
2129 {
2130 DPRINT1("Could not get CodePage Entry! CodePageEntry = NULL\n");
2132 return FALSE;
2133 }
2134
2135 lpCPInfoEx->CodePage = CodePageEntry->CodePageTable.CodePage;
2136 lpCPInfoEx->UnicodeDefaultChar = CodePageEntry->CodePageTable.UniDefaultChar;
2137 return GetLocalisedText(lpCPInfoEx->CodePage,
2138 lpCPInfoEx->CodePageName,
2139 ARRAYSIZE(lpCPInfoEx->CodePageName),
2140 GetThreadLocale()) != 0;
2141 }
2142 break;
2143 }
2144}
2145
2146
2147/*
2148 * @implemented
2149 */
2150BOOL
2151WINAPI
2153 DWORD dwFlags,
2154 LPCPINFOEXA lpCPInfoEx)
2155{
2156 CPINFOEXW CPInfo;
2157
2158 if (!GetCPInfoExW(CodePage, dwFlags, &CPInfo))
2159 return FALSE;
2160
2161 /* the layout is the same except for CodePageName */
2162 memcpy(lpCPInfoEx, &CPInfo, sizeof(CPINFOEXA));
2163
2165 0,
2166 CPInfo.CodePageName,
2167 -1,
2168 lpCPInfoEx->CodePageName,
2169 sizeof(lpCPInfoEx->CodePageName),
2170 NULL,
2171 NULL);
2172 return TRUE;
2173}
2174
2214INT
2215WINAPI
2217 DWORD Flags,
2218 LPCWSTR WideCharString,
2219 INT WideCharCount,
2221 INT MultiByteCount,
2222 LPCSTR DefaultChar,
2223 LPBOOL UsedDefaultChar)
2224{
2225 /* Check the parameters. */
2226 if (WideCharString == NULL ||
2227 WideCharCount == 0 ||
2228 (MultiByteString == NULL && MultiByteCount > 0) ||
2229 (PVOID)WideCharString == (PVOID)MultiByteString ||
2230 MultiByteCount < 0)
2231 {
2233 return 0;
2234 }
2235
2236 /* Determine the input string length. */
2237 if (WideCharCount < 0)
2238 {
2239 WideCharCount = lstrlenW(WideCharString) + 1;
2240 }
2241
2242 switch (CodePage)
2243 {
2244 case CP_UTF8:
2245 if (DefaultChar != NULL || UsedDefaultChar != NULL)
2246 {
2248 return 0;
2249 }
2250 return IntWideCharToMultiByteUTF8(CodePage,
2251 Flags,
2252 WideCharString,
2253 WideCharCount,
2255 MultiByteCount,
2256 DefaultChar,
2257 UsedDefaultChar);
2258
2259 case CP_UTF7:
2260 if (DefaultChar != NULL || UsedDefaultChar != NULL)
2261 {
2263 return 0;
2264 }
2265 if (Flags)
2266 {
2268 return 0;
2269 }
2270 return WideCharToUtf7(WideCharString, WideCharCount,
2271 MultiByteString, MultiByteCount);
2272
2273 case CP_SYMBOL:
2274 if ((DefaultChar!=NULL) || (UsedDefaultChar!=NULL))
2275 {
2277 return 0;
2278 }
2280 WideCharString,
2281 WideCharCount,
2283 MultiByteCount);
2284
2285 default:
2286 return IntWideCharToMultiByteCP(CodePage,
2287 Flags,
2288 WideCharString,
2289 WideCharCount,
2291 MultiByteCount,
2292 DefaultChar,
2293 UsedDefaultChar);
2294 }
2295}
2296
2305UINT
2306WINAPI
2308{
2310}
2311
2320UINT
2321WINAPI
2323{
2325}
2326
2335BOOL
2336WINAPI
2337IsDBCSLeadByteEx(UINT CodePage, BYTE TestByte)
2338{
2339 PCODEPAGE_ENTRY CodePageEntry;
2340
2341 CodePageEntry = IntGetCodePageEntry(CodePage);
2342 if (CodePageEntry != NULL)
2343 return IntIsLeadByte(&CodePageEntry->CodePageTable, TestByte);
2344
2346 return FALSE;
2347}
2348
2357BOOL
2358WINAPI
2360{
2361 return IntIsLeadByte(&AnsiCodePage.CodePageTable, TestByte);
2362}
2363
2392WINAPI
2397{
2400 PSID WorldSid;
2401 PACL Dacl;
2403
2405 {
2406 DPRINT1("Security descriptor size too small\n");
2408 }
2409
2410 /* Create the World SID */
2412 1,
2414 0, 0, 0, 0, 0, 0, 0,
2415 &WorldSid);
2416 if (!NT_SUCCESS(Status))
2417 {
2418 DPRINT1("Failed to create World SID (Status 0x%08x)\n", Status);
2419 return Status;
2420 }
2421
2422 /* Initialize the security descriptor */
2425 if (!NT_SUCCESS(Status))
2426 {
2427 DPRINT1("Failed to create security descriptor (Status 0x%08x)\n", Status);
2428 goto Quit;
2429 }
2430
2431 /* The DACL follows the security descriptor, and includes the World SID */
2434
2435 /* Create the DACL */
2437 if (!NT_SUCCESS(Status))
2438 {
2439 DPRINT1("Failed to create DACL (Status 0x%08x)\n", Status);
2440 goto Quit;
2441 }
2442
2443 /* Add an allowed access ACE to the World SID */
2445 if (!NT_SUCCESS(Status))
2446 {
2447 DPRINT1("Failed to add allowed access ACE for World SID (Status 0x%08x)\n", Status);
2448 goto Quit;
2449 }
2450
2451 /* Set the DACL to the descriptor */
2453 if (!NT_SUCCESS(Status))
2454 {
2455 DPRINT1("Failed to set DACL into descriptor (Status 0x%08x)\n", Status);
2456 goto Quit;
2457 }
2458
2459Quit:
2461 return Status;
2462}
2463
2464/*
2465 * @unimplemented
2466 */
2468{
2469 STUB;
2470 return 0;
2471}
2472
2473/*
2474 * @unimplemented
2475 */
2477{
2478 STUB;
2479}
2480
2481/*
2482 * @unimplemented
2483 */
2485{
2486 STUB;
2487 return 0;
2488}
2489
2490/*
2491 * @unimplemented
2492 */
2493BOOL
2494WINAPI
2495ValidateLCType(int a1, unsigned int a2, int a3, int a4)
2496{
2497 STUB;
2498 return FALSE;
2499}
2500
2501/*
2502 * @unimplemented
2503 */
2504BOOL
2505WINAPI
2507{
2508 STUB;
2509 return TRUE;
2510}
2511
2512/*
2513 * @unimplemented
2514 */
2515VOID
2516WINAPI
2518{
2519 STUB;
2520 lpUnknown = NULL;
2521}
2522
2523/*
2524 * @unimplemented
2525 */
2526VOID
2527WINAPI
2529{
2530 STUB;
2531 lpUnknown = NULL;
2532}
2533
2534/*
2535 * @unimplemented
2536 */
2537BOOL
2538WINAPI
2540{
2541 STUB;
2542 return TRUE;
2543}
2544
2545/*
2546 * @unimplemented
2547 */
2548ULONG
2549WINAPI
2551{
2552 STUB;
2553 return 0;
2554}
2555
2556/*
2557 * @unimplemented
2558 */
2559BOOL
2560WINAPI
2563 IN LPNLSVERSIONINFO lpVersionInformation,
2564 IN LPCWSTR lpString,
2565 IN INT cchStr)
2566{
2567 STUB;
2568 return TRUE;
2569}
2570
2571/*
2572 * @unimplemented
2573 */
2574BOOL
2575WINAPI
2577 IN LCID Locale,
2578 IN OUT LPNLSVERSIONINFO lpVersionInformation)
2579{
2580 STUB;
2581 return TRUE;
2582}
2583
2584/*
2585 * @unimplemented
2586 */
2587BOOL
2588WINAPI
2590 IN LPCWSTR lpLocaleName,
2591 IN OUT LPNLSVERSIONINFOEX lpVersionInformation)
2592{
2593 STUB;
2594 return TRUE;
2595}
2596
2597/* 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:3441
NTSTATUS NTAPI NtOpenSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: section.c:3569
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:32
#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
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:2576
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:2561
VOID WINAPI NlsConvertIntegerToString(ULONG Value, ULONG Base, ULONG strsize, LPWSTR str, ULONG strsize2)
Definition: nls.c:2476
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:2337
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:2495
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:2589
static CODEPAGE_ENTRY AnsiCodePage
Definition: nls.c:46
ULONG WINAPI NlsGetCacheUpdateCount(VOID)
Definition: nls.c:2550
static const unsigned long UTF8LBound[]
Definition: nls.c:41
UINT WINAPI SetCPGlobal(UINT CodePage)
Definition: nls.c:2484
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:2393
BOOL WINAPI IsValidUILanguage(LANGID langid)
Definition: nls.c:2467
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:2528
BOOL WINAPI ValidateLocale(IN ULONG LocaleId)
Definition: nls.c:2539
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:2506
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:2152
BOOL WINAPI GetCPInfoExW(UINT CodePage, DWORD dwFlags, LPCPINFOEXW lpCPInfoEx)
Definition: nls.c:2093
VOID WINAPI GetDefaultSortkeySize(LPVOID lpUnknown)
Definition: nls.c:2517
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:2359
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
static SID_IDENTIFIER_AUTHORITY WorldAuthority
Definition: security.c:14
unsigned char
Definition: typeof.h:29
#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:1305
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
GLuint index
Definition: glext.h:6031
GLenum GLenum dst
Definition: glext.h:6340
GLfloat GLfloat p
Definition: glext.h:8902
GLintptr offset
Definition: glext.h:5920
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 NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
#define NtCurrentTeb
#define STUB
Definition: kernel32.h:27
LCID WINAPI GetThreadLocale(void)
Definition: lang.c:1459
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: lang.c:1108
LCID WINAPI ConvertDefaultLocale(LCID lcid)
Definition: lang.c:1512
#define REG_SZ
Definition: layer.c:22
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
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
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
LANGID langid
Definition: msctf.idl:605
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:1593
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:4317
_In_ BOOLEAN DaclPresent
Definition: rtlfuncs.h:1635
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2439
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:1594
_In_ BOOLEAN _In_opt_ PACL _In_opt_ BOOLEAN DaclDefaulted
Definition: rtlfuncs.h:1638
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
#define L(x)
Definition: ntvdm.h:50
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
VOID NTAPI RtlInitCodePageTable(IN PUSHORT TableBase, OUT PCPTABLEINFO CodePageTable)
Definition: nls.c:155
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define DPRINT
Definition: sndvol32.h:71
base of all file and directory entries
Definition: entries.h:83
Definition: kernel32.h:63
UINT CodePage
Definition: kernel32.h:65
LIST_ENTRY Entry
Definition: kernel32.h:64
HANDLE SectionHandle
Definition: kernel32.h:66
CPTABLEINFO CodePageTable
Definition: kernel32.h:68
PBYTE SectionMapping
Definition: kernel32.h:67
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:583
BYTE DefaultChar[MAX_DEFAULTCHAR]
Definition: winnls.h:582
UINT MaxCharSize
Definition: winnls.h:581
CHAR CodePageName[MAX_PATH]
Definition: winnls.h:591
WCHAR UnicodeDefaultChar
Definition: winnls.h:597
WCHAR CodePageName[MAX_PATH]
Definition: winnls.h:599
UINT CodePage
Definition: winnls.h:598
_In_ SIZE_T DescriptorSize
Definition: nls.c:40
WORD LANGID
Definition: typedefs.h:81
#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
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
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
BOOL * LPBOOL
Definition: windef.h:162
#define WINAPI
Definition: msvc.h:6
#define ERROR_NO_UNICODE_TRANSLATION
Definition: winerror.h:649
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583
#define CP_THREAD_ACP
Definition: winnls.h:233
#define CP_OEMCP
Definition: winnls.h:231
UINT WINAPI GetACP(void)
Definition: nls.c:2307
#define CP_SYMBOL
Definition: winnls.h:234
#define CP_UTF7
Definition: winnls.h:235
#define CP_MACCP
Definition: winnls.h:232
#define LOCALE_IDEFAULTANSICODEPAGE
Definition: winnls.h:38
UINT WINAPI GetOEMCP(void)
Definition: nls.c:2322
#define LOCALE_IDEFAULTMACCODEPAGE
Definition: winnls.h:39
NLS_FUNCTION
Definition: winnls.h:550
#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:1527
#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