ReactOS  0.4.15-dev-5455-g015cd25
nls.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS system libraries
4  * FILE: dll/win32/kernel32/winnls/string/nls.c
5  * PURPOSE: National Language Support
6  * PROGRAMMER: Filip Navara
7  * Hartmut Birr
8  * Gunnar Andre Dalsnes
9  * Thomas Weidenmueller
10  * Katayama Hirofumi MZ
11  * UPDATE HISTORY:
12  * Created 24/08/2004
13  */
14 
15 /* INCLUDES *******************************************************************/
16 
17 #include <k32.h>
18 
19 #define NDEBUG
20 #include <debug.h>
21 
22 /* GLOBAL VARIABLES ***********************************************************/
23 
24 /* Sequence length based on the first character. */
25 static const char UTF8Length[128] =
26 {
27  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8F */
28  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9F */
29  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0 - 0xAF */
30  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0 - 0xBF */
31  0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xC0 - 0xCF */
32  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xD0 - 0xDF */
33  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xE0 - 0xEF */
34  3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xF0 - 0xFF */
35 };
36 
37 /* First byte mask depending on UTF-8 sequence length. */
38 static const unsigned char UTF8Mask[6] = {0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
39 
40 /* UTF-8 length to lower bound */
41 static const unsigned long UTF8LBound[] =
42  {0, 0x80, 0x800, 0x10000, 0x200000, 0x2000000, 0xFFFFFFFF};
43 
44 /* FIXME: Change to HASH table or linear array. */
49 
50 /* FORWARD DECLARATIONS *******************************************************/
51 
54  LPSTR BaseName, LPSTR Result, ULONG ResultSize);
55 
57 GetCPFileNameFromRegistry(UINT CodePage, LPWSTR FileName, ULONG FileNameSize);
58 
60 WINAPI
65 
66 /* PRIVATE FUNCTIONS **********************************************************/
67 
80 static 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 */
117  &DaclPresent,
118  &Dacl,
119  &DaclDefaulted);
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. */
129  ACL_REVISION,
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 
138 Quit:
139  RtlFreeSid(AdminsSid);
140  return Status;
141 }
142 
149 BOOL
150 FASTCALL
152 {
156  HANDLE Handle;
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  */
168  RtlInitUnicodeString(&DirName, L"\\NLS");
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  {
190  NtClose(Handle);
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 
221 VOID
222 FASTCALL
224 {
225  PCODEPAGE_ENTRY Current;
226 
227  /* Delete the code page list. */
228  while (!IsListEmpty(&CodePageListHead))
229  {
231  if (Current->SectionHandle != NULL)
232  {
234  NtClose(Current->SectionHandle);
235  }
237  }
239 }
240 
256 FASTCALL
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 
292 FASTCALL
294 {
296  CHAR SectionName[40];
297  HANDLE SectionHandle = INVALID_HANDLE_VALUE, FileHandle;
298  PBYTE SectionMapping;
301  ANSI_STRING AnsiName;
303  WCHAR FileName[MAX_PATH + 1];
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 
389  &UnicodeName,
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. */
400  if (Status == STATUS_UNSUCCESSFUL ||
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,
424  SEC_COMMIT,
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 
487 static
488 INT
489 WINAPI
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 
659 static
660 INT
661 WINAPI
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)
764  MultiByteString++;
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 
853 static
854 INT
855 WINAPI
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 
909 static INT
910 WINAPI
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 
971 static INT
972 WINAPI
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 
1099 static
1100 inline
1101 BOOL
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) */
1110  if (ch != CodePageTable->TransDefaultChar)
1111  return TRUE;
1112 
1113  /* The only possible left valid mapping is the default character itself */
1114  return (wch == CodePageTable->TransUniDefaultChar);
1115 }
1116 
1124 static 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 
1156 static
1157 INT
1158 WINAPI
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
1203  DefChar = CodePageTable->TransDefaultChar;
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
1367  DefChar = (CHAR)CodePageTable->TransDefaultChar;
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 
1434 static BOOL
1435 WINAPI
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 
1481 BOOL
1482 WINAPI
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 
1526 BOOL
1527 WINAPI
1529 {
1530  WCHAR ValueNameBuffer[11];
1533  NTSTATUS Status;
1534  HANDLE KeyHandle;
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  {
1564  NtClose(KeyHandle);
1565  return bRetValue;
1566  }
1567 
1568  /* Query the file name for our code page. */
1570  Kvpi, KvpiSize, &KvpiSize);
1571 
1572  NtClose(KeyHandle);
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 
1602 BOOL
1603 WINAPI
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 
1614 static 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 
1629 static 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 
1761 INT
1762 WINAPI
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 
1820 static 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 
1837 static 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 
1852 static 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  */
1951 UINT
1953  IN UINT uID,
1954  IN LPWSTR lpszDest,
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 
1977  (LPWSTR)RT_STRING,
1978  MAKEINTRESOURCEW((uID >> 4) + 1),
1979  langId);
1980 
1981  /* English fallback */
1982  if (!hrsrc)
1983  {
1985  (LPWSTR)RT_STRING,
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 
2028 NotFound:
2029  DPRINT1("Resource not found: uID = %lu\n", uID);
2031  return 0;
2032 }
2033 
2034 /*
2035  * @implemented
2036  */
2037 BOOL
2038 WINAPI
2039 GetCPInfo(UINT CodePage,
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  */
2091 BOOL
2092 WINAPI
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  */
2150 BOOL
2151 WINAPI
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 
2214 INT
2215 WINAPI
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 
2305 UINT
2306 WINAPI
2308 {
2310 }
2311 
2320 UINT
2321 WINAPI
2323 {
2325 }
2326 
2335 BOOL
2336 WINAPI
2337 IsDBCSLeadByteEx(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 
2357 BOOL
2358 WINAPI
2360 {
2361  return IntIsLeadByte(&AnsiCodePage.CodePageTable, TestByte);
2362 }
2363 
2391 NTSTATUS
2392 WINAPI
2397 {
2399  NTSTATUS Status;
2400  PSID WorldSid;
2401  PACL Dacl;
2402  ULONG DaclSize;
2403 
2405  {
2406  DPRINT1("Security descriptor size too small\n");
2407  return STATUS_BUFFER_TOO_SMALL;
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 
2459 Quit:
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  */
2493 BOOL
2494 WINAPI
2495 ValidateLCType(int a1, unsigned int a2, int a3, int a4)
2496 {
2497  STUB;
2498  return FALSE;
2499 }
2500 
2501 /*
2502  * @unimplemented
2503  */
2504 BOOL
2505 WINAPI
2507 {
2508  STUB;
2509  return TRUE;
2510 }
2511 
2512 /*
2513  * @unimplemented
2514  */
2515 VOID
2516 WINAPI
2518 {
2519  STUB;
2520  lpUnknown = NULL;
2521 }
2522 
2523 /*
2524  * @unimplemented
2525  */
2526 VOID
2527 WINAPI
2529 {
2530  STUB;
2531  lpUnknown = NULL;
2532 }
2533 
2534 /*
2535  * @unimplemented
2536  */
2537 BOOL
2538 WINAPI
2540 {
2541  STUB;
2542  return TRUE;
2543 }
2544 
2545 /*
2546  * @unimplemented
2547  */
2548 ULONG
2549 WINAPI
2551 {
2552  STUB;
2553  return 0;
2554 }
2555 
2556 /*
2557  * @unimplemented
2558  */
2559 BOOL
2560 WINAPI
2562  IN DWORD dwFlags,
2563  IN LPNLSVERSIONINFO lpVersionInformation,
2564  IN LPCWSTR lpString,
2565  IN INT cchStr)
2566 {
2567  STUB;
2568  return TRUE;
2569 }
2570 
2571 /*
2572  * @unimplemented
2573  */
2574 BOOL
2575 WINAPI
2577  IN LCID Locale,
2578  IN OUT LPNLSVERSIONINFO lpVersionInformation)
2579 {
2580  STUB;
2581  return TRUE;
2582 }
2583 
2584 /*
2585  * @unimplemented
2586  */
2587 BOOL
2588 WINAPI
2590  IN LPCWSTR lpLocaleName,
2591  IN OUT LPNLSVERSIONINFOEX lpVersionInformation)
2592 {
2593  STUB;
2594  return TRUE;
2595 }
2596 
2597 /* EOF */
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
signed char * PCHAR
Definition: retypes.h:7
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define FILE_GENERIC_READ
Definition: nt_native.h:653
static INT WINAPI IntMultiByteToWideCharUTF8(DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:490
static NTSTATUS CreateNlsDirectorySecurity(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ SIZE_T DescriptorSize)
Creates a security descriptor for the NLS object directory.
Definition: nls.c:81
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
BOOL WINAPI IsValidUILanguage(LANGID langid)
Definition: nls.c:2467
#define IN
Definition: typedefs.h:39
BOOL WINAPI GetCPInfo(UINT CodePage, LPCPINFO CodePageInfo)
Definition: nls.c:2039
#define LOCALE_IDEFAULTANSICODEPAGE
Definition: winnls.h:38
static CODEPAGE_ENTRY AnsiCodePage
Definition: nls.c:46
static INT Utf7ToWideChar(const char *src, int srclen, WCHAR *dst, int dstlen)
Definition: nls.c:1629
static const struct update_accum a3
Definition: msg.c:600
#define MB_ERR_INVALID_CHARS
Definition: unicode.h:41
USHORT UniDefaultChar
Definition: precomp.h:35
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1154
static INT WideCharToUtf7(const WCHAR *src, int srclen, char *dst, int dstlen)
Definition: nls.c:1852
PUSHORT DBCSOffsets
Definition: precomp.h:43
#define MapViewOfFile
Definition: compat.h:745
_In_ BOOLEAN _In_opt_ PACL _In_opt_ BOOLEAN DaclDefaulted
Definition: rtlfuncs.h:1635
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
#define MB_USEGLYPHCHARS
Definition: unicode.h:42
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
#define NLS_SECTION_SECURITY_DESCRIPTOR_SIZE
Definition: base.h:31
#define _Out_
Definition: ms_sal.h:345
PUSHORT MultiByteTable
Definition: precomp.h:40
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define CP_UTF7
Definition: winnls.h:235
#define MAKEWORD(a, b)
Definition: typedefs.h:248
#define KEY_READ
Definition: nt_native.h:1023
static INT WINAPI IntWideCharToMultiByteSYMBOL(DWORD Flags, LPCWSTR WideCharString, INT WideCharCount, LPSTR MultiByteString, INT MultiByteCount)
Definition: nls.c:911
#define TRUE
Definition: types.h:120
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:182
static LIST_ENTRY CodePageListHead
Definition: nls.c:45
static const char UTF8Length[128]
Definition: nls.c:25
#define DIRECTORY_CREATE_OBJECT
Definition: nt_native.h:1256
NLS_FUNCTION
Definition: winnls.h:550
WCHAR CodePageName[MAX_PATH]
Definition: winnls.h:599
#define LANG_NEUTRAL
Definition: nls.h:22
BOOL WINAPI ValidateLocale(IN ULONG LocaleId)
Definition: nls.c:2539
#define CP_ACP
Definition: compat.h:109
NTSYSAPI PVOID NTAPI RtlFreeSid(_In_ _Post_invalid_ PSID Sid)
BOOL WINAPI ValidateLCType(int a1, unsigned int a2, int a3, int a4)
Definition: nls.c:2495
char CHAR
Definition: xmlstorage.h:175
VOID WINAPI GetLinguistLangSize(LPVOID lpUnknown)
Definition: nls.c:2528
BOOL WINAPI IsNLSDefinedString(IN NLS_FUNCTION Function, IN DWORD dwFlags, IN LPNLSVERSIONINFO lpVersionInformation, IN LPCWSTR lpString, IN INT cchStr)
Definition: nls.c:2561
LONG NTSTATUS
Definition: precomp.h:26
static SID_IDENTIFIER_AUTHORITY WorldAuthority
Definition: security.c:14
IN PDCB IN POEM_STRING IN PUNICODE_STRING UnicodeName
Definition: fatprocs.h:1303
#define LOCALE_IDEFAULTMACCODEPAGE
Definition: winnls.h:39
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2427
BOOL WINAPI GetNLSVersionEx(IN NLS_FUNCTION function, IN LPCWSTR lpLocaleName, IN OUT LPNLSVERSIONINFOEX lpVersionInformation)
Definition: nls.c:2589
static const unsigned long UTF8LBound[]
Definition: nls.c:41
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
static const struct update_accum a4
Definition: msg.c:2285
UINT MaxCharSize
Definition: winnls.h:581
INT WINAPI WideCharToMultiByte(UINT CodePage, DWORD Flags, LPCWSTR WideCharString, INT WideCharCount, LPSTR MultiByteString, INT MultiByteCount, LPCSTR DefaultChar, LPBOOL UsedDefaultChar)
Definition: nls.c:2216
DWORD LCID
Definition: nls.h:13
WORD LANGID
Definition: typedefs.h:81
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
uint16_t * PWCHAR
Definition: typedefs.h:56
#define InsertTailList(ListHead, Entry)
NTSYSAPI NTSTATUS NTAPI RtlIntegerToChar(_In_ ULONG Value, _In_ ULONG Base, _In_ ULONG Length, _Out_ PCHAR String)
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
char * LPSTR
Definition: xmlstorage.h:182
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
PCODEPAGE_ENTRY FASTCALL IntGetLoadedCodePageEntry(UINT CodePage)
Definition: nls.c:257
LANGID langid
Definition: msctf.idl:605
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 lstrlenW
Definition: compat.h:750
#define FASTCALL
Definition: nt_native.h:50
#define CP_SYMBOL
Definition: winnls.h:234
int32_t INT
Definition: typedefs.h:58
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
static INT WINAPI IntWideCharToMultiByteUTF8(UINT CodePage, DWORD Flags, LPCWSTR WideCharString, INT WideCharCount, LPSTR MultiByteString, INT MultiByteCount, LPCSTR DefaultChar, LPBOOL UsedDefaultChar)
Definition: nls.c:973
#define FILE_SHARE_READ
Definition: compat.h:136
_In_ BOOLEAN DaclPresent
Definition: rtlfuncs.h:1635
#define SUBLANG_ENGLISH_US
Definition: nls.h:222
NTSYSAPI NTSTATUS NTAPI RtlGetDaclSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Out_ PBOOLEAN DaclPresent, _Out_ PACL *Dacl, _Out_ PBOOLEAN DaclDefaulted)
#define lstrcpynW
Definition: compat.h:738
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: lang.c:1102
static INT WINAPI IntMultiByteToWideCharSYMBOL(DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:856
BOOL WINAPI NlsResetProcessLocale(VOID)
Definition: nls.c:2506
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
#define L(x)
Definition: ntvdm.h:50
VOID WINAPI GetDefaultSortkeySize(LPVOID lpUnknown)
Definition: nls.c:2517
#define SEC_COMMIT
Definition: mmtypes.h:99
#define CP_UTF8
Definition: nls.h:20
#define FALSE
Definition: types.h:117
LCID WINAPI ConvertDefaultLocale(LCID lcid)
Definition: lang.c:1506
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
PVOID WideCharTable
Definition: precomp.h:41
UINT CodePage
Definition: kernel32.h:65
NTSTATUS NTAPI NtOpenSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: section.c:3569
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
const WCHAR * str
unsigned char BOOLEAN
static BOOL IntIsValidSBCSMapping(PCPTABLEINFO CodePageTable, DWORD Flags, WCHAR wch, UCHAR ch)
Definition: nls.c:1102
unsigned char
Definition: typeof.h:29
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define _In_
Definition: ms_sal.h:308
BOOL WINAPI IsDBCSLeadByte(BYTE TestByte)
Definition: nls.c:2359
UINT WINAPI GetACP(VOID)
Definition: nls.c:2307
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
WCHAR lpszDest[260]
#define FILE_MAP_READ
Definition: compat.h:776
USHORT TransDefaultChar
Definition: precomp.h:36
GLuint index
Definition: glext.h:6031
const char * LPCSTR
Definition: xmlstorage.h:183
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2697
#define OPEN_EXISTING
Definition: compat.h:775
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:554
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
HMODULE hCurrentModule
Definition: dllmain.c:25
#define PCHAR
Definition: match.c:90
ULONG WINAPI NlsGetCacheUpdateCount(VOID)
Definition: nls.c:2550
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
struct _ACL * PACL
Definition: security.c:104
#define DIRECTORY_TRAVERSE
Definition: nt_native.h:1255
static const WCHAR lang[]
Definition: wbemdisp.c:287
Status
Definition: gdiplustypes.h:24
UCHAR LeadByte[MAXIMUM_LEADBYTES]
Definition: precomp.h:39
USHORT DBCSCodePage
Definition: precomp.h:38
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
VOID WINAPI NlsConvertIntegerToString(ULONG Value, ULONG Base, ULONG strsize, LPWSTR str, ULONG strsize2)
Definition: nls.c:2476
NTSYSAPI NTSTATUS NTAPI RtlIntegerToUnicodeString(ULONG Value, ULONG Base, PUNICODE_STRING String)
NTSYSAPI NTSTATUS NTAPI NtQueryValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, IN PULONG ResultLength)
int Count
Definition: noreturn.cpp:7
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
static INT WINAPI IntMultiByteToWideCharCP(UINT CodePage, DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:662
#define GetProcessHeap()
Definition: compat.h:736
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define SECURITY_BUILTIN_DOMAIN_RID
Definition: setypes.h:581
#define ASSERT(a)
Definition: mode.c:44
#define NLS_SIZEOF_ACE_AND_SIDS(n)
Definition: base.h:26
__wchar_t WCHAR
Definition: xmlstorage.h:180
LIST_ENTRY Entry
Definition: kernel32.h:64
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
USHORT TransUniDefaultChar
Definition: precomp.h:37
#define SECURITY_WORLD_SID_AUTHORITY
Definition: setypes.h:527
static const struct update_accum a2
Definition: msg.c:586
BYTE LeadByte[MAX_LEADBYTES]
Definition: winnls.h:583
GLintptr offset
Definition: glext.h:5920
USHORT MaximumCharacterSize
Definition: precomp.h:33
static DWORD LPDWORD LPCSTR DWORD srclen
Definition: directory.c:51
BOOL WINAPI GetNLSVersion(IN NLS_FUNCTION Function, IN LCID Locale, IN OUT LPNLSVERSIONINFO lpVersionInformation)
Definition: nls.c:2576
#define MAX_PATH
Definition: compat.h:34
#define WINAPI
Definition: msvc.h:6
PCODEPAGE_ENTRY FASTCALL IntGetCodePageEntry(UINT CodePage)
Definition: nls.c:293
#define LOCALE_SYSTEM_DEFAULT
#define for
Definition: utility.h:88
unsigned long DWORD
Definition: ntddk_ex.h:95
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
static BOOL WINAPI IntIsLeadByte(PCPTABLEINFO TableInfo, BYTE Byte)
Definition: nls.c:1436
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define SetLastError(x)
Definition: compat.h:752
#define SECURITY_WORLD_RID
Definition: setypes.h:541
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define WC_NO_BEST_FIT_CHARS
Definition: unicode.h:46
#define LANG_ENGLISH
Definition: nls.h:52
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
USHORT CodePage
Definition: precomp.h:32
#define ERROR_NO_UNICODE_TRANSLATION
Definition: winerror.h:649
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING _In_ PCUNICODE_STRING _In_ LCID LocaleId
Definition: wdfpdo.h:430
static CODEPAGE_ENTRY OemCodePage
Definition: nls.c:47
static BOOL IntIsValidDBCSMapping(PCPTABLEINFO CodePageTable, DWORD Flags, WCHAR wch, USHORT ch)
Definition: nls.c:1125
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:240
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1593
unsigned char UCHAR
Definition: xmlstorage.h:181
static INT WINAPI IntWideCharToMultiByteCP(UINT CodePage, DWORD Flags, LPCWSTR WideCharString, INT WideCharCount, LPSTR MultiByteString, INT MultiByteCount, LPCSTR DefaultChar, LPBOOL UsedDefaultChar)
Definition: nls.c:1159
HRSRC WINAPI FindResourceExW(HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD lang)
Definition: res.c:164
CHAR CodePageName[MAX_PATH]
Definition: winnls.h:591
static RTL_CRITICAL_SECTION CodePageListLock
Definition: nls.c:48
#define index(s, c)
Definition: various.h:29
static SID_IDENTIFIER_AUTHORITY NtAuthority
Definition: security.c:40
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define SECTION_MAP_READ
Definition: compat.h:139
PSID WorldSid
Definition: globals.c:15
#define OBJ_PERMANENT
Definition: winternl.h:226
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define LANGIDFROMLCID(l)
Definition: nls.h:18
#define MAXIMUM_LEADBYTES
Definition: precomp.h:16
VOID NTAPI RtlInitCodePageTable(IN PUSHORT TableBase, OUT PCPTABLEINFO CodePageTable)
Definition: nls.c:155
#define RT_STRING
Definition: pedump.c:368
USHORT DefaultChar
Definition: precomp.h:34
Definition: typedefs.h:119
GLenum src
Definition: glext.h:6340
BOOL WINAPI GetCPFileNameFromRegistry(UINT CodePage, LPWSTR FileName, ULONG FileNameSize)
Definition: nls.c:1528
INT WINAPI MultiByteToWideChar(UINT CodePage, DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:1763
struct _SECURITY_DESCRIPTOR SECURITY_DESCRIPTOR
BOOL WINAPI GetNlsSectionName(UINT CodePage, UINT Base, ULONG Unknown, LPSTR BaseName, LPSTR Result, ULONG ResultSize)
Definition: nls.c:1483
unsigned char BYTE
Definition: xxhash.c:193
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
ULONG_PTR SIZE_T
Definition: typedefs.h:80
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1230
NTSTATUS NTAPI NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:765
BOOL WINAPI IsValidCodePage(UINT CodePage)
Definition: nls.c:1604
BOOL * LPBOOL
Definition: windef.h:162
static DWORD dstlen
Definition: directory.c:51
_In_ SIZE_T DescriptorSize
Definition: nls.c:40
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
Definition: kernel32.h:62
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define WC_COMPOSITECHECK
Definition: unicode.h:43
#define STUB
Definition: kernel32.h:27
unsigned short USHORT
Definition: pedump.c:61
BOOL WINAPI GetCPInfoExA(UINT CodePage, DWORD dwFlags, LPCPINFOEXA lpCPInfoEx)
Definition: nls.c:2152
BYTE DefaultChar[MAX_DEFAULTCHAR]
Definition: winnls.h:582
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1259
GLenum GLenum dst
Definition: glext.h:6340
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2313
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define PAGE_READONLY
Definition: compat.h:138
static const unsigned char UTF8Mask[6]
Definition: nls.c:38
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
PBYTE SectionMapping
Definition: kernel32.h:67
*BytesInMultiByteString PCHAR MultiByteString
Definition: rtlfuncs.h:1527
#define DPRINT1
Definition: precomp.h:8
#define CreateFileW
Definition: compat.h:741
unsigned char Byte
Definition: zlib.h:37
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG DaclSize
Definition: rtlfuncs.h:1593
#define ACL_REVISION
Definition: setypes.h:39
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
_In_ HANDLE Handle
Definition: extypes.h:390
#define OUT
Definition: typedefs.h:40
unsigned int ULONG
Definition: retypes.h:1
#define MAKELANGID(p, s)
Definition: nls.h:15
BOOL WINAPI GetCPInfoExW(UINT CodePage, DWORD dwFlags, LPCPINFOEXW lpCPInfoEx)
Definition: nls.c:2093
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
_In_ PFCB _In_ PCD_NAME DirName
Definition: cdprocs.h:736
_Out_ PCPTABLEINFO CodePageTable
Definition: rtlfuncs.h:4305
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
static BOOL utf7_write_w(WCHAR *dst, int dstlen, int *index, WCHAR character)
Definition: nls.c:1614
static BOOL utf7_can_directly_encode(WCHAR codepoint)
Definition: nls.c:1820
static const struct update_accum a1
Definition: msg.c:578
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
UINT GetLocalisedText(IN UINT uID, IN LPWSTR lpszDest, IN UINT cchDest, IN LANGID lang)
Definition: nls.c:1952
HANDLE SectionHandle
Definition: kernel32.h:66
GLfloat GLfloat p
Definition: glext.h:8902
#define DPRINT
Definition: sndvol32.h:71
WCHAR * LPWSTR
Definition: xmlstorage.h:184
NTSYSAPI NTSTATUS NTAPI RtlDeleteCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define CP_THREAD_ACP
Definition: winnls.h:233
VOID FASTCALL NlsUninit(VOID)
Definition: nls.c:223
#define UnmapViewOfFile
Definition: compat.h:746
#define CHAR(Char)
BOOL FASTCALL NlsInit(VOID)
Definition: nls.c:151
#define DOMAIN_ALIAS_RID_ADMINS
Definition: setypes.h:652
BYTE * PBYTE
Definition: pedump.c:66
UINT WINAPI SetCPGlobal(UINT CodePage)
Definition: nls.c:2484
#define CP_OEMCP
Definition: winnls.h:231
#define HeapFree(x, y, z)
Definition: compat.h:735
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583
unsigned short * PUSHORT
Definition: retypes.h:2
base of all file and directory entries
Definition: entries.h:82
CPTABLEINFO CodePageTable
Definition: kernel32.h:68
LCID WINAPI GetThreadLocale(void)
Definition: lang.c:1453
#define CP_MACCP
Definition: winnls.h:232
#define PRIMARYLANGID(l)
Definition: nls.h:16
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
UINT WINAPI GetOEMCP(VOID)
Definition: nls.c:2322
#define REG_SZ
Definition: layer.c:22
_In_ SIZE_T _In_ ULONG AccessMask
Definition: nls.c:40