ReactOS 0.4.17-dev-243-g1369312
nls.c File Reference
#include <k32.h>
#include <debug.h>
Include dependency graph for nls.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

static NTSTATUS CreateNlsDirectorySecurity (_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ SIZE_T DescriptorSize)
 Creates a security descriptor for the NLS object directory.
 
GetNlsSectionName

Construct a name of NLS section.

Parameters
CodePageCode page number.
BaseInteger base used for converting to string. Usually set to 10.
UnknownAs the name suggests the meaning of this parameter is unknown. The native version of Kernel32 passes it as the third parameter to NlsConvertIntegerToString function, which is used for the actual conversion of the code page number.
BaseNameBase name of the section. (ex. "\\Nls\\NlsSectionCP")
ResultBuffer that will hold the constructed name.
ResultSizeSize of the buffer for the result.
Returns
TRUE if the buffer was large enough and was filled with the requested information, FALSE otherwise.

@implemented

BOOL WINAPI GetNlsSectionName (UINT CodePage, UINT Base, ULONG Unknown, LPSTR BaseName, LPSTR Result, ULONG ResultSize)
 
GetCPFileNameFromRegistry

Get file name of code page definition file.

Parameters
CodePageCode page number to get file name of.
FileNameBuffer that is filled with file name of successful return. Can be set to NULL.
FileNameSizeSize of the buffer to hold file name in WCHARs.
Returns
TRUE if the file name was retrieved, FALSE otherwise.

@implemented

BOOL WINAPI GetCPFileNameFromRegistry (UINT CodePage, LPWSTR FileName, ULONG FileNameSize)
 
IsDBCSLeadByteEx

Determine if passed byte is lead byte in current ANSI code page.

@implemented

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 SID) read access to the sections.
 
BOOL WINAPI IsDBCSLeadByteEx (UINT CodePage, BYTE TestByte)
 
BOOL WINAPI IsDBCSLeadByte (BYTE TestByte)
 
BOOL WINAPI IsValidUILanguage (LANGID langid)
 
VOID WINAPI NlsConvertIntegerToString (ULONG Value, ULONG Base, ULONG strsize, LPWSTR str, ULONG strsize2)
 
UINT WINAPI SetCPGlobal (UINT CodePage)
 
BOOL WINAPI ValidateLCType (int a1, unsigned int a2, int a3, int a4)
 
BOOL WINAPI NlsResetProcessLocale (VOID)
 
VOID WINAPI GetDefaultSortkeySize (LPVOID lpUnknown)
 
VOID WINAPI GetLinguistLangSize (LPVOID lpUnknown)
 
BOOL WINAPI ValidateLocale (IN ULONG LocaleId)
 
ULONG WINAPI NlsGetCacheUpdateCount (VOID)
 
BOOL WINAPI IsNLSDefinedString (IN NLS_FUNCTION Function, IN DWORD dwFlags, IN LPNLSVERSIONINFO lpVersionInformation, IN LPCWSTR lpString, IN INT cchStr)
 
BOOL WINAPI GetNLSVersion (IN NLS_FUNCTION Function, IN LCID Locale, IN OUT LPNLSVERSIONINFO lpVersionInformation)
 
BOOL WINAPI GetNLSVersionEx (IN NLS_FUNCTION function, IN LPCWSTR lpLocaleName, IN OUT LPNLSVERSIONINFOEX lpVersionInformation)
 
NlsInit

Internal NLS related stuff initialization.

BOOL FASTCALL NlsInit (VOID)
 
NlsUninit

Internal NLS related stuff uninitialization.

VOID FASTCALL NlsUninit (VOID)
 
IntGetLoadedCodePageEntry

Internal function to get structure containing a code page information of code page that is already loaded.

Parameters
CodePageNumber of the code page. Special values like CP_OEMCP, CP_ACP or CP_UTF8 aren't allowed.
Returns
Code page entry or NULL if the specified code page hasn't been loaded yet.
PCODEPAGE_ENTRY FASTCALL IntGetLoadedCodePageEntry (UINT CodePage)
 
IntGetCodePageEntry

Internal function to get structure containing a code page information.

Parameters
CodePageNumber of the code page. Special values like CP_OEMCP, CP_ACP or CP_THREAD_ACP are allowed, but CP_UTF[7/8] isn't.
Returns
Code page entry.
PCODEPAGE_ENTRY FASTCALL IntGetCodePageEntry (UINT CodePage)
 
IntMultiByteToWideCharUTF8

Internal version of MultiByteToWideChar for UTF8.

Note
We use Win10's behaviour due to security reason.
See also
MultiByteToWideChar
static INT WINAPI IntMultiByteToWideCharUTF8 (DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
 
IntMultiByteToWideCharCP

Internal version of MultiByteToWideChar for code page tables.

See also
MultiByteToWideChar
Todo:
Handle MB_PRECOMPOSED, MB_COMPOSITE, MB_USEGLYPHCHARS and DBCS codepages.
static INT WINAPI IntMultiByteToWideCharCP (UINT CodePage, DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
 
IntMultiByteToWideCharSYMBOL

Internal version of MultiByteToWideChar for SYMBOL.

See also
MultiByteToWideChar
static INT WINAPI IntMultiByteToWideCharSYMBOL (DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
 
IntWideCharToMultiByteSYMBOL

Internal version of WideCharToMultiByte for SYMBOL.

See also
WideCharToMultiByte
static INT WINAPI IntWideCharToMultiByteSYMBOL (DWORD Flags, LPCWSTR WideCharString, INT WideCharCount, LPSTR MultiByteString, INT MultiByteCount)
 
IntWideCharToMultiByteUTF8

Internal version of WideCharToMultiByte for UTF8.

See also
WideCharToMultiByte
static INT WINAPI IntWideCharToMultiByteUTF8 (UINT CodePage, DWORD Flags, LPCWSTR WideCharString, INT WideCharCount, LPSTR MultiByteString, INT MultiByteCount, LPCSTR DefaultChar, LPBOOL UsedDefaultChar)
 
IsValidSBCSMapping

Checks if ch (single-byte character) is a valid mapping for wch

See also
IntWideCharToMultiByteCP
static BOOL IntIsValidSBCSMapping (PCPTABLEINFO CodePageTable, DWORD Flags, WCHAR wch, UCHAR ch)
 
IsValidDBCSMapping

Checks if ch (double-byte character) is a valid mapping for wch

See also
IntWideCharToMultiByteCP
static BOOL IntIsValidDBCSMapping (PCPTABLEINFO CodePageTable, DWORD Flags, WCHAR wch, USHORT ch)
 
IntWideCharToMultiByteCP

Internal version of WideCharToMultiByte for code page tables.

See also
WideCharToMultiByte
Todo:
Handle WC_COMPOSITECHECK
static INT WINAPI IntWideCharToMultiByteCP (UINT CodePage, DWORD Flags, LPCWSTR WideCharString, INT WideCharCount, LPSTR MultiByteString, INT MultiByteCount, LPCSTR DefaultChar, LPBOOL UsedDefaultChar)
 
IntIsLeadByte

Internal function to detect if byte is lead byte in specific character table.

static BOOL WINAPI IntIsLeadByte (PCPTABLEINFO TableInfo, BYTE Byte)
 
IsValidCodePage

Detect if specified code page is valid and present in the system.

Parameters
CodePageCode page number to query.
Returns
TRUE if code page is present.
BOOL WINAPI IsValidCodePage (UINT CodePage)
 
static BOOL utf7_write_w (WCHAR *dst, int dstlen, int *index, WCHAR character)
 
static INT Utf7ToWideChar (const char *src, int srclen, WCHAR *dst, int dstlen)
 
MultiByteToWideChar

Convert a multi-byte string to wide-charater equivalent.

Parameters
CodePageCode page to be used to perform the conversion. It can be also one of the special values (CP_ACP for ANSI code page, CP_MACCP for Macintosh code page, CP_OEMCP for OEM code page, CP_THREAD_ACP for thread active code page, CP_UTF7 or CP_UTF8).
FlagsAdditional conversion flags (MB_PRECOMPOSED, MB_COMPOSITE, MB_ERR_INVALID_CHARS, MB_USEGLYPHCHARS).
MultiByteStringInput buffer.
MultiByteCountSize of MultiByteString, or -1 if MultiByteString is NULL terminated.
WideCharStringOutput buffer.
WideCharCountSize in WCHARs of WideCharString, or 0 if the caller just wants to know how large WideCharString should be for a successful conversion.
Returns
Zero on error, otherwise the number of WCHARs written in the WideCharString buffer.

@implemented

INT WINAPI MultiByteToWideChar (UINT CodePage, DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
 
static BOOL utf7_can_directly_encode (WCHAR codepoint)
 
static BOOL utf7_write_c (char *dst, int dstlen, int *index, char character)
 
static INT WideCharToUtf7 (const WCHAR *src, int srclen, char *dst, int dstlen)
 
UINT GetLocalisedText (IN UINT uID, IN LPWSTR lpszDest, IN UINT cchDest, IN LANGID lang)
 
BOOL WINAPI GetCPInfo (UINT CodePage, LPCPINFO CodePageInfo)
 
BOOL WINAPI GetCPInfoExW (UINT CodePage, DWORD dwFlags, LPCPINFOEXW lpCPInfoEx)
 
BOOL WINAPI GetCPInfoExA (UINT CodePage, DWORD dwFlags, LPCPINFOEXA lpCPInfoEx)
 
WideCharToMultiByte

Convert a wide-charater string to closest multi-byte equivalent.

Parameters
CodePageCode page to be used to perform the conversion. It can be also one of the special values (CP_ACP for ANSI code page, CP_MACCP for Macintosh code page, CP_OEMCP for OEM code page, CP_THREAD_ACP for thread active code page, CP_UTF7 or CP_UTF8).
FlagsAdditional conversion flags (WC_NO_BEST_FIT_CHARS, WC_COMPOSITECHECK, WC_DISCARDNS, WC_SEPCHARS, WC_DEFAULTCHAR).
WideCharStringPoints to the wide-character string to be converted.
WideCharCountSize in WCHARs of WideCharStr, or 0 if the caller just wants to know how large WideCharString should be for a successful conversion.
MultiByteStringPoints to the buffer to receive the translated string.
MultiByteCountSpecifies the size in bytes of the buffer pointed to by the MultiByteString parameter. If this value is zero, the function returns the number of bytes required for the buffer.
DefaultCharPoints to the character used if a wide character cannot be represented in the specified code page. If this parameter is NULL, a system default value is used.
UsedDefaultCharPoints to a flag that indicates whether a default character was used. This parameter can be NULL.
Returns
Zero on error, otherwise the number of bytes written in the MultiByteString buffer. Or the number of bytes needed for the MultiByteString buffer if MultiByteCount is zero.

@implemented

INT WINAPI WideCharToMultiByte (UINT CodePage, DWORD Flags, LPCWSTR WideCharString, INT WideCharCount, LPSTR MultiByteString, INT MultiByteCount, LPCSTR DefaultChar, LPBOOL UsedDefaultChar)
 
GetACP

Get active ANSI code page number.

@implemented

UINT WINAPI GetACP (VOID)
 
GetOEMCP

Get active OEM code page number.

@implemented

UINT WINAPI GetOEMCP (VOID)
 

Variables

static const char UTF8Length [128]
 
static const unsigned char UTF8Mask [6] = {0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01}
 
static const unsigned long UTF8LBound []
 
static LIST_ENTRY CodePageListHead
 
static CODEPAGE_ENTRY AnsiCodePage
 
static CODEPAGE_ENTRY OemCodePage
 
static RTL_CRITICAL_SECTION CodePageListLock
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 19 of file nls.c.

Function Documentation

◆ CreateNlsDirectorySecurity()

static NTSTATUS CreateNlsDirectorySecurity ( _Out_ PSECURITY_DESCRIPTOR  SecurityDescriptor,
_In_ SIZE_T  DescriptorSize 
)
static

Creates a security descriptor for the NLS object directory.

Parameters
[out]SecurityDescriptor
[in]DescriptorSizeSame parameters as for CreateNlsSecurityDescriptor().
Remarks
Everyone (World SID) is given read access to the NLS directory, whereas Admins are given full access.

Definition at line 81 of file nls.c.

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}
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
static SID_IDENTIFIER_AUTHORITY NtAuthority
Definition: security.c:40
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
NTSTATUS WINAPI CreateNlsSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ SIZE_T DescriptorSize, _In_ ULONG AccessMask)
Creates a security descriptor for each NLS section. Typically used by BASESRV to give Everyone (World...
Definition: nls.c:2424
Status
Definition: gdiplustypes.h:24
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1625
_In_ BOOLEAN DaclPresent
Definition: rtlfuncs.h:1667
NTSYSAPI PVOID NTAPI RtlFreeSid(_In_ _Post_invalid_ PSID Sid)
NTSYSAPI NTSTATUS NTAPI RtlGetDaclSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Out_ PBOOLEAN DaclPresent, _Out_ PACL *Dacl, _Out_ PBOOLEAN DaclDefaulted)
_In_ BOOLEAN _In_opt_ PACL _In_opt_ BOOLEAN DaclDefaulted
Definition: rtlfuncs.h:1670
#define DIRECTORY_CREATE_OBJECT
Definition: nt_native.h:1259
#define DIRECTORY_TRAVERSE
Definition: nt_native.h:1258
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1262
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
_In_ SIZE_T DescriptorSize
Definition: nls.c:40
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
_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
#define SECURITY_BUILTIN_DOMAIN_RID
Definition: setypes.h:581
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:554
#define ACL_REVISION
Definition: setypes.h:39
#define DOMAIN_ALIAS_RID_ADMINS
Definition: setypes.h:652

Referenced by NlsInit().

◆ CreateNlsSecurityDescriptor()

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 SID) read access to the sections.

Parameters
[out]SecurityDescriptorA pointer to a correctly sized user-allocated buffer, that receives a security descriptor containing one ACL with one World SID. Its size should be at least equal to NLS_SECTION_SECURITY_DESCRIPTOR_SIZE.
[in]DescriptorSizeSize (in bytes) of the user-provided SecurityDescriptor buffer.
[in]AccessMaskAn access mask that grants Everyone an access specific to that mask.
Returns
STATUS_SUCCESS is returned if the function has successfully created a security descriptor for a NLS section name. Otherwise a NTSTATUS failure code is returned.
Remarks
This implementation has to be made compatible with NT <= 5.2 in order to inter-operate with BASESRV. In particular, the security descriptor is a user-provided buffer correctly sized. The caller is responsible to submit the exact size of the descriptor.

Definition at line 2424 of file nls.c.

2428{
2431 PSID WorldSid;
2432 PACL Dacl;
2434
2436 {
2437 DPRINT1("Security descriptor size too small\n");
2439 }
2440
2441 /* Create the World SID */
2443 1,
2445 0, 0, 0, 0, 0, 0, 0,
2446 &WorldSid);
2447 if (!NT_SUCCESS(Status))
2448 {
2449 DPRINT1("Failed to create World SID (Status 0x%08x)\n", Status);
2450 return Status;
2451 }
2452
2453 /* Initialize the security descriptor */
2456 if (!NT_SUCCESS(Status))
2457 {
2458 DPRINT1("Failed to create security descriptor (Status 0x%08x)\n", Status);
2459 goto Quit;
2460 }
2461
2462 /* The DACL follows the security descriptor, and includes the World SID */
2465
2466 /* Create the DACL */
2468 if (!NT_SUCCESS(Status))
2469 {
2470 DPRINT1("Failed to create DACL (Status 0x%08x)\n", Status);
2471 goto Quit;
2472 }
2473
2474 /* Add an allowed access ACE to the World SID */
2476 if (!NT_SUCCESS(Status))
2477 {
2478 DPRINT1("Failed to add allowed access ACE for World SID (Status 0x%08x)\n", Status);
2479 goto Quit;
2480 }
2481
2482 /* Set the DACL to the descriptor */
2484 if (!NT_SUCCESS(Status))
2485 {
2486 DPRINT1("Failed to set DACL into descriptor (Status 0x%08x)\n", Status);
2487 goto Quit;
2488 }
2489
2490Quit:
2492 return Status;
2493}
PSID WorldSid
Definition: globals.c:15
#define NLS_SECTION_SECURITY_DESCRIPTOR_SIZE
Definition: base.h:31
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static SID_IDENTIFIER_AUTHORITY WorldAuthority
Definition: security.c:14
struct _SECURITY_DESCRIPTOR SECURITY_DESCRIPTOR
struct _ACL * PACL
_In_ ACCESS_MASK AccessMask
Definition: exfuncs.h:186
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG DaclSize
Definition: rtlfuncs.h:1626
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
#define SECURITY_WORLD_SID_AUTHORITY
Definition: setypes.h:527
#define SECURITY_WORLD_RID
Definition: setypes.h:541
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58

Referenced by CreateNlsDirectorySecurity(), and IntGetCodePageEntry().

◆ GetACP()

UINT WINAPI GetACP ( VOID  )

Definition at line 2338 of file nls.c.

2339{
2341}
static CODEPAGE_ENTRY AnsiCodePage
Definition: nls.c:46
CPTABLEINFO CodePageTable
Definition: kernel32.h:65
USHORT CodePage
Definition: precomp.h:32

◆ GetCPFileNameFromRegistry()

BOOL WINAPI GetCPFileNameFromRegistry ( UINT  CodePage,
LPWSTR  FileName,
ULONG  FileNameSize 
)

Definition at line 1557 of file nls.c.

1558{
1559 WCHAR ValueNameBuffer[11];
1565 DWORD KvpiSize;
1566 BOOL bRetValue;
1567
1568 bRetValue = FALSE;
1569
1570 /* Convert the codepage number to string. */
1571 ValueName.Buffer = ValueNameBuffer;
1572 ValueName.MaximumLength = sizeof(ValueNameBuffer);
1573
1574 if (!NT_SUCCESS(RtlIntegerToUnicodeString(CodePage, 10, &ValueName)))
1575 return bRetValue;
1576
1577 /* Open the registry key containing file name mappings. */
1578 RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System\\"
1579 L"CurrentControlSet\\Control\\Nls\\CodePage");
1581 NULL, NULL);
1583 if (!NT_SUCCESS(Status))
1584 {
1585 return bRetValue;
1586 }
1587
1588 /* Allocate buffer that will be used to query the value data. */
1589 KvpiSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + (MAX_PATH * sizeof(WCHAR));
1590 Kvpi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, KvpiSize);
1591 if (Kvpi == NULL)
1592 {
1594 return bRetValue;
1595 }
1596
1597 /* Query the file name for our code page. */
1599 Kvpi, KvpiSize, &KvpiSize);
1600
1602
1603 /* Check if we succeded and the value is non-empty string. */
1604 if (NT_SUCCESS(Status) && Kvpi->Type == REG_SZ &&
1605 Kvpi->DataLength > sizeof(WCHAR))
1606 {
1607 bRetValue = TRUE;
1608 if (FileName != NULL)
1609 {
1610 lstrcpynW(FileName, (WCHAR*)Kvpi->Data,
1611 min(Kvpi->DataLength / sizeof(WCHAR), FileNameSize));
1612 }
1613 }
1614
1615 /* free temporary buffer */
1616 HeapFree(GetProcessHeap(),0,Kvpi);
1617 return bRetValue;
1618}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define lstrcpynW
Definition: compat.h:738
#define L(x)
Definition: resources.c:13
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define REG_SZ
Definition: layer.c:22
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
#define min(a, b)
Definition: monoChain.cc:55
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
@ KeyValuePartialInformation
Definition: nt_native.h:1185
#define KEY_READ
Definition: nt_native.h:1026
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
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
short WCHAR
Definition: pedump.c:58
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2705
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243

Referenced by IntGetCodePageEntry(), and IsValidCodePage().

◆ GetCPInfo()

BOOL WINAPI GetCPInfo ( UINT  CodePage,
LPCPINFO  CodePageInfo 
)

Definition at line 2068 of file nls.c.

2070{
2071 PCODEPAGE_ENTRY CodePageEntry;
2072
2073 if (!CodePageInfo)
2074 {
2076 return FALSE;
2077 }
2078
2079 CodePageEntry = IntGetCodePageEntry(CodePage);
2080 if (CodePageEntry == NULL)
2081 {
2082 switch(CodePage)
2083 {
2084 case CP_UTF7:
2085 case CP_UTF8:
2086 RtlZeroMemory(CodePageInfo, sizeof(*CodePageInfo));
2087 CodePageInfo->DefaultChar[0] = 0x3f;
2088 CodePageInfo->DefaultChar[1] = 0;
2089 CodePageInfo->LeadByte[0] = CodePageInfo->LeadByte[1] = 0;
2090 CodePageInfo->MaxCharSize = (CodePage == CP_UTF7) ? 5 : 4;
2091 return TRUE;
2092 }
2093
2094 DPRINT1("Invalid CP!: %lx\n", CodePage);
2096 return FALSE;
2097 }
2098
2099 RtlZeroMemory(CodePageInfo, sizeof(*CodePageInfo));
2100 if (CodePageEntry->CodePageTable.DefaultChar & 0xff00)
2101 {
2102 CodePageInfo->DefaultChar[0] = (CodePageEntry->CodePageTable.DefaultChar & 0xff00) >> 8;
2103 CodePageInfo->DefaultChar[1] = CodePageEntry->CodePageTable.DefaultChar & 0x00ff;
2104 }
2105 else
2106 {
2107 CodePageInfo->DefaultChar[0] = CodePageEntry->CodePageTable.DefaultChar & 0xff;
2108 CodePageInfo->DefaultChar[1] = 0;
2109 }
2110
2111 if ((CodePageInfo->MaxCharSize = CodePageEntry->CodePageTable.MaximumCharacterSize) == 2)
2112 memcpy(CodePageInfo->LeadByte, CodePageEntry->CodePageTable.LeadByte, sizeof(CodePageInfo->LeadByte));
2113 else
2114 CodePageInfo->LeadByte[0] = CodePageInfo->LeadByte[1] = 0;
2115
2116 return TRUE;
2117}
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
PCODEPAGE_ENTRY FASTCALL IntGetCodePageEntry(UINT CodePage)
Definition: nls.c:293
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define CP_UTF8
Definition: nls.h:20
Definition: kernel32.h:60
USHORT DefaultChar
Definition: precomp.h:34
UCHAR LeadByte[MAXIMUM_LEADBYTES]
Definition: precomp.h:39
USHORT MaximumCharacterSize
Definition: precomp.h:33
BYTE LeadByte[MAX_LEADBYTES]
Definition: winnls.h:652
BYTE DefaultChar[MAX_DEFAULTCHAR]
Definition: winnls.h:651
UINT MaxCharSize
Definition: winnls.h:650
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define CP_UTF7
Definition: winnls.h:253

Referenced by GetCPInfoExW().

◆ GetCPInfoExA()

BOOL WINAPI GetCPInfoExA ( UINT  CodePage,
DWORD  dwFlags,
LPCPINFOEXA  lpCPInfoEx 
)

Definition at line 2183 of file nls.c.

2186{
2187 CPINFOEXW CPInfo;
2188
2189 if (!GetCPInfoExW(CodePage, dwFlags, &CPInfo))
2190 return FALSE;
2191
2192 /* the layout is the same except for CodePageName */
2193 memcpy(lpCPInfoEx, &CPInfo, sizeof(CPINFOEXA));
2194
2196 0,
2197 CPInfo.CodePageName,
2198 -1,
2199 lpCPInfoEx->CodePageName,
2200 sizeof(lpCPInfoEx->CodePageName),
2201 NULL,
2202 NULL);
2203 return TRUE;
2204}
#define CP_ACP
Definition: compat.h:109
#define WideCharToMultiByte
Definition: compat.h:111
BOOL WINAPI GetCPInfoExW(UINT CodePage, DWORD dwFlags, LPCPINFOEXW lpCPInfoEx)
Definition: nls.c:2124
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
CHAR CodePageName[MAX_PATH]
Definition: winnls.h:660
WCHAR CodePageName[MAX_PATH]
Definition: winnls.h:668

◆ GetCPInfoExW()

BOOL WINAPI GetCPInfoExW ( UINT  CodePage,
DWORD  dwFlags,
LPCPINFOEXW  lpCPInfoEx 
)

Definition at line 2124 of file nls.c.

2127{
2128 if (!GetCPInfo(CodePage, (LPCPINFO)lpCPInfoEx))
2129 return FALSE;
2130
2131 switch(CodePage)
2132 {
2133 case CP_UTF7:
2134 {
2135 lpCPInfoEx->CodePage = CP_UTF7;
2136 lpCPInfoEx->UnicodeDefaultChar = 0x3f;
2137 return GetLocalisedText(lpCPInfoEx->CodePage,
2138 lpCPInfoEx->CodePageName,
2139 ARRAYSIZE(lpCPInfoEx->CodePageName),
2140 GetThreadLocale()) != 0;
2141 }
2142 break;
2143
2144 case CP_UTF8:
2145 {
2146 lpCPInfoEx->CodePage = CP_UTF8;
2147 lpCPInfoEx->UnicodeDefaultChar = 0x3f;
2148 return GetLocalisedText(lpCPInfoEx->CodePage,
2149 lpCPInfoEx->CodePageName,
2150 ARRAYSIZE(lpCPInfoEx->CodePageName),
2151 GetThreadLocale()) != 0;
2152 }
2153
2154 default:
2155 {
2156 PCODEPAGE_ENTRY CodePageEntry;
2157
2158 CodePageEntry = IntGetCodePageEntry(CodePage);
2159 if (CodePageEntry == NULL)
2160 {
2161 DPRINT1("Could not get CodePage Entry! CodePageEntry = NULL\n");
2163 return FALSE;
2164 }
2165
2166 lpCPInfoEx->CodePage = CodePageEntry->CodePageTable.CodePage;
2167 lpCPInfoEx->UnicodeDefaultChar = CodePageEntry->CodePageTable.UniDefaultChar;
2168 return GetLocalisedText(lpCPInfoEx->CodePage,
2169 lpCPInfoEx->CodePageName,
2170 ARRAYSIZE(lpCPInfoEx->CodePageName),
2171 GetThreadLocale()) != 0;
2172 }
2173 break;
2174 }
2175}
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
LCID WINAPI GetThreadLocale(void)
Definition: locale.c:2803
BOOL WINAPI GetCPInfo(UINT CodePage, LPCPINFO CodePageInfo)
Definition: nls.c:2068
UINT GetLocalisedText(IN UINT uID, IN LPWSTR lpszDest, IN UINT cchDest, IN LANGID lang)
Definition: nls.c:1981
USHORT UniDefaultChar
Definition: precomp.h:35

Referenced by GetCPInfoExA().

◆ GetDefaultSortkeySize()

VOID WINAPI GetDefaultSortkeySize ( LPVOID  lpUnknown)

Definition at line 2548 of file nls.c.

2549{
2550 STUB;
2551 lpUnknown = NULL;
2552}
#define STUB
Definition: kernel32.h:27

◆ GetLinguistLangSize()

VOID WINAPI GetLinguistLangSize ( LPVOID  lpUnknown)

Definition at line 2559 of file nls.c.

2560{
2561 STUB;
2562 lpUnknown = NULL;
2563}

◆ GetLocalisedText()

UINT GetLocalisedText ( IN UINT  uID,
IN LPWSTR  lpszDest,
IN UINT  cchDest,
IN LANGID  lang 
)

Definition at line 1981 of file nls.c.

1986{
1987 HRSRC hrsrc;
1988 HGLOBAL hmem;
1989 LCID lcid;
1990 LANGID langId;
1991 const WCHAR *p;
1992 UINT i;
1993
1994 /* See HACK in winnls/lang/xx-XX.rc files */
1995 if (uID == 37)
1996 uID = uID * 100;
1997
1999
2000 langId = LANGIDFROMLCID(lcid);
2001
2002 if (PRIMARYLANGID(langId) == LANG_NEUTRAL)
2004
2007 MAKEINTRESOURCEW((uID >> 4) + 1),
2008 langId);
2009
2010 /* English fallback */
2011 if (!hrsrc)
2012 {
2015 MAKEINTRESOURCEW((uID >> 4) + 1),
2017 }
2018
2019 if (!hrsrc)
2020 goto NotFound;
2021
2022 hmem = LoadResource(hCurrentModule, hrsrc);
2023 if (!hmem)
2024 goto NotFound;
2025
2026 p = LockResource(hmem);
2027
2028 for (i = 0; i < (uID & 0x0F); i++)
2029 p += *p + 1;
2030
2031 /* Needed for GetGeoInfo(): return the needed string size including the NULL terminator */
2032 if (cchDest == 0)
2033 return *p + 1;
2034 /* Needed for GetGeoInfo(): bail out if the user buffer is not large enough */
2035 if (*p + 1 > cchDest)
2036 {
2038 return 0;
2039 }
2040
2041 i = *p;
2042 if (i > 0)
2043 {
2044 memcpy(lpszDest, p + 1, i * sizeof(WCHAR));
2045 lpszDest[i] = L'\0';
2046 return i;
2047 }
2048#if 0
2049 else
2050 {
2051 if (cchDest >= 1)
2052 lpszDest[0] = L'\0';
2053 /* Fall-back */
2054 }
2055#endif
2056
2057NotFound:
2058 DPRINT1("Resource not found: uID = %lu\n", uID);
2060 return 0;
2061}
WCHAR lpszDest[260]
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
HMODULE hCurrentModule
Definition: dllmain.c:25
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
HRSRC WINAPI FindResourceExW(HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD lang)
Definition: res.c:164
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
LCID WINAPI ConvertDefaultLocale(LCID lcid)
Definition: locale.c:2879
LCID lcid
Definition: locale.c:5656
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
USHORT LANGID
Definition: mui.h:9
unsigned int UINT
Definition: ndis.h:50
#define RT_STRING
Definition: pedump.c:368
_In_ INT cchDest
Definition: shlwapi.h:1151
_In_ UINT uID
Definition: shlwapi.h:156
#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 PRIMARYLANGID(l)
Definition: nls.h:16
#define SUBLANG_ENGLISH_US
Definition: nls.h:222
uint16_t * LPWSTR
Definition: typedefs.h:56
static const WCHAR lang[]
Definition: wbemdisp.c:287
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582

Referenced by GetCPInfoExW().

◆ GetNlsSectionName()

BOOL WINAPI GetNlsSectionName ( UINT  CodePage,
UINT  Base,
ULONG  Unknown,
LPSTR  BaseName,
LPSTR  Result,
ULONG  ResultSize 
)

Definition at line 1512 of file nls.c.

1518{
1519 CHAR Integer[11];
1520
1521 if (!NT_SUCCESS(RtlIntegerToChar(CodePage, Base, sizeof(Integer), Integer)))
1522 return FALSE;
1523
1524 /*
1525 * If the name including the terminating NULL character doesn't
1526 * fit in the output buffer then fail.
1527 */
1528 if (strlen(Integer) + strlen(BaseName) >= ResultSize)
1529 return FALSE;
1530
1531 lstrcpyA(Result, BaseName);
1532 lstrcatA(Result, Integer);
1533
1534 return TRUE;
1535}
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2486
NTSYSAPI NTSTATUS NTAPI RtlIntegerToChar(_In_ ULONG Value, _In_ ULONG Base, _In_ ULONG Length, _Out_ PCHAR String)
char CHAR
Definition: pedump.c:57
_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

Referenced by IntGetCodePageEntry().

◆ GetNLSVersion()

BOOL WINAPI GetNLSVersion ( IN NLS_FUNCTION  Function,
IN LCID  Locale,
IN OUT LPNLSVERSIONINFO  lpVersionInformation 
)

Definition at line 2607 of file nls.c.

2610{
2611 STUB;
2612 return TRUE;
2613}

◆ GetNLSVersionEx()

BOOL WINAPI GetNLSVersionEx ( IN NLS_FUNCTION  function,
IN LPCWSTR  lpLocaleName,
IN OUT LPNLSVERSIONINFOEX  lpVersionInformation 
)

Definition at line 2620 of file nls.c.

2623{
2624 STUB;
2625 return TRUE;
2626}

◆ GetOEMCP()

UINT WINAPI GetOEMCP ( VOID  )

Definition at line 2353 of file nls.c.

2354{
2356}
static CODEPAGE_ENTRY OemCodePage
Definition: nls.c:47

◆ IntGetCodePageEntry()

PCODEPAGE_ENTRY FASTCALL IntGetCodePageEntry ( UINT  CodePage)

Definition at line 293 of file nls.c.

294{
296 CHAR SectionName[40];
297 HANDLE SectionHandle = INVALID_HANDLE_VALUE, FileHandle;
298 PBYTE SectionMapping;
300 union
301 {
302 SECURITY_DESCRIPTOR AlignedSd;
305 ANSI_STRING AnsiName;
308 UINT FileNamePos;
309 PCODEPAGE_ENTRY CodePageEntry;
310
311 if (CodePage == CP_ACP)
312 {
313 return &AnsiCodePage;
314 }
315 else if (CodePage == CP_OEMCP)
316 {
317 return &OemCodePage;
318 }
319 else if (CodePage == CP_THREAD_ACP)
320 {
322 LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
323 (WCHAR *)&CodePage,
324 sizeof(CodePage) / sizeof(WCHAR)))
325 {
326 /* Last error is set by GetLocaleInfoW. */
327 return NULL;
328 }
329 if (CodePage == 0)
330 return &AnsiCodePage;
331 }
332 else if (CodePage == CP_MACCP)
333 {
335 LOCALE_IDEFAULTMACCODEPAGE | LOCALE_RETURN_NUMBER,
336 (WCHAR *)&CodePage,
337 sizeof(CodePage) / sizeof(WCHAR)))
338 {
339 /* Last error is set by GetLocaleInfoW. */
340 return NULL;
341 }
342 }
343
344 /* Try searching for loaded page first. */
345 CodePageEntry = IntGetLoadedCodePageEntry(CodePage);
346 if (CodePageEntry != NULL)
347 {
348 return CodePageEntry;
349 }
350
351 /*
352 * Yes, we really want to lock here. Otherwise it can happen that
353 * two parallel requests will try to get the entry for the same
354 * code page and we would load it twice.
355 */
357
358 /* Generate the section name. */
359 if (!GetNlsSectionName(CodePage,
360 10,
361 0,
362 "\\Nls\\NlsSectionCP",
363 SectionName,
364 sizeof(SectionName)))
365 {
367 return NULL;
368 }
369
370 RtlInitAnsiString(&AnsiName, SectionName);
372
373 /*
374 * FIXME: IntGetCodePageEntry should not create any security
375 * descriptor here but instead this responsibility should be
376 * assigned to Base Server API (aka basesrv.dll). That is,
377 * kernel32 must instruct basesrv.dll on creating NLS section
378 * names that do not exist through API message communication.
379 * However since we do not do that, let the kernel32 do the job
380 * by assigning security to NLS section names for the time being...
381 */
383 sizeof(SecurityDescriptor),
385 if (!NT_SUCCESS(Status))
386 {
387 DPRINT1("CreateNlsSecurityDescriptor FAILED! (Status 0x%08x)\n", Status);
389 return NULL;
390 }
391
395 NULL,
397
398 /* Try to open the section first */
399 Status = NtOpenSection(&SectionHandle,
402
403 /* If the section doesn't exist, try to create it. */
407 {
408 FileNamePos = GetSystemDirectoryW(FileName, MAX_PATH);
409 if (GetCPFileNameFromRegistry(CodePage,
410 FileName + FileNamePos + 1,
411 MAX_PATH - FileNamePos - 1))
412 {
413 FileName[FileNamePos] = L'\\';
414 FileName[MAX_PATH] = 0;
418 NULL,
420 0,
421 NULL);
422
423 Status = NtCreateSection(&SectionHandle,
426 NULL,
429 FileHandle);
430
431 /* HACK: Check if another process was faster
432 * and already created this section. See bug 3626 for details */
434 {
435 /* Close the file then */
437
438 /* And open the section */
439 Status = NtOpenSection(&SectionHandle,
442 }
443 }
444 }
446
447 if (!NT_SUCCESS(Status))
448 {
450 return NULL;
451 }
452
453 SectionMapping = MapViewOfFile(SectionHandle, FILE_MAP_READ, 0, 0, 0);
454 if (SectionMapping == NULL)
455 {
456 NtClose(SectionHandle);
458 return NULL;
459 }
460
461 CodePageEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(CODEPAGE_ENTRY));
462 if (CodePageEntry == NULL)
463 {
464 NtClose(SectionHandle);
466 return NULL;
467 }
468
469 CodePageEntry->CodePage = CodePage;
470 CodePageEntry->SectionHandle = SectionHandle;
471 CodePageEntry->SectionMapping = SectionMapping;
472
473 RtlInitCodePageTable((PUSHORT)SectionMapping, &CodePageEntry->CodePageTable);
474
475 /* Insert the new entry to list and unlock. Uff. */
476 InsertTailList(&CodePageListHead, &CodePageEntry->Entry);
478
479 return CodePageEntry;
480}
NTSTATUS NTAPI NtCreateSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize OPTIONAL, IN ULONG SectionPageProtection OPTIONAL, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL)
Definition: section.c:3083
NTSTATUS NTAPI NtOpenSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: section.c:3211
Definition: bufpool.h:45
#define PAGE_READONLY
Definition: compat.h:138
#define SECTION_MAP_READ
Definition: compat.h:139
#define OPEN_EXISTING
Definition: compat.h:775
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CreateFileW
Definition: compat.h:741
#define FILE_MAP_READ
Definition: compat.h:776
#define MapViewOfFile
Definition: compat.h:745
#define FILE_SHARE_READ
Definition: compat.h:136
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2232
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: locale.c:1675
PCODEPAGE_ENTRY FASTCALL IntGetLoadedCodePageEntry(UINT CodePage)
Definition: nls.c:257
BOOL WINAPI GetNlsSectionName(UINT CodePage, UINT Base, ULONG Unknown, LPSTR BaseName, LPSTR Result, ULONG ResultSize)
Definition: nls.c:1512
static RTL_CRITICAL_SECTION CodePageListLock
Definition: nls.c:48
BOOL WINAPI GetCPFileNameFromRegistry(UINT CodePage, LPWSTR FileName, ULONG FileNameSize)
Definition: nls.c:1557
static LIST_ENTRY CodePageListHead
Definition: nls.c:45
#define InsertTailList(ListHead, Entry)
IN PDCB IN POEM_STRING IN PUNICODE_STRING UnicodeName
Definition: fatprocs.h:1306
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
#define SEC_COMMIT
Definition: mmtypes.h:100
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define FILE_GENERIC_READ
Definition: nt_native.h:653
#define LOCALE_SYSTEM_DEFAULT
BYTE * PBYTE
Definition: pedump.c:66
UINT CodePage
Definition: kernel32.h:62
LIST_ENTRY Entry
Definition: kernel32.h:61
HANDLE SectionHandle
Definition: kernel32.h:63
PBYTE SectionMapping
Definition: kernel32.h:64
unsigned char UCHAR
Definition: typedefs.h:53
uint16_t * PUSHORT
Definition: typedefs.h:56
#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
NTSYSAPI void WINAPI RtlInitCodePageTable(USHORT *, CPTABLEINFO *)
#define CP_THREAD_ACP
Definition: winnls.h:251
#define CP_OEMCP
Definition: winnls.h:249
#define CP_MACCP
Definition: winnls.h:250
#define LOCALE_IDEFAULTANSICODEPAGE
Definition: winnls.h:45
#define LOCALE_IDEFAULTMACCODEPAGE
Definition: winnls.h:46

Referenced by GetCPInfo(), GetCPInfoExW(), IntMultiByteToWideCharCP(), IntWideCharToMultiByteCP(), and IsDBCSLeadByteEx().

◆ IntGetLoadedCodePageEntry()

PCODEPAGE_ENTRY FASTCALL IntGetLoadedCodePageEntry ( UINT  CodePage)

Definition at line 257 of file nls.c.

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}
Entry
Definition: section.c:5216
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by IntGetCodePageEntry(), and IsValidCodePage().

◆ IntIsLeadByte()

static BOOL WINAPI IntIsLeadByte ( PCPTABLEINFO  TableInfo,
BYTE  Byte 
)
static

Definition at line 1465 of file nls.c.

1466{
1467 UINT i;
1468
1469 if (TableInfo->MaximumCharacterSize == 2)
1470 {
1471 for (i = 0; i < MAXIMUM_LEADBYTES && TableInfo->LeadByte[i]; i += 2)
1472 {
1473 if (Byte >= TableInfo->LeadByte[i] && Byte <= TableInfo->LeadByte[i+1])
1474 return TRUE;
1475 }
1476 }
1477
1478 return FALSE;
1479}
unsigned char Byte
Definition: zlib.h:37
#define MAXIMUM_LEADBYTES
Definition: precomp.h:16

Referenced by IsDBCSLeadByte(), and IsDBCSLeadByteEx().

◆ IntIsValidDBCSMapping()

static BOOL IntIsValidDBCSMapping ( PCPTABLEINFO  CodePageTable,
DWORD  Flags,
WCHAR  wch,
USHORT  ch 
)
inlinestatic

Definition at line 1154 of file nls.c.

1155{
1156 /* If ch is the default character, but the wch is not, it can't be a valid mapping */
1158 return FALSE;
1159
1160 /* If the WC_NO_BEST_FIT_CHARS flag has been specified, the characters need to match exactly. */
1162 {
1163 if(ch & 0xff00)
1164 {
1165 USHORT uOffset = CodePageTable->DBCSOffsets[ch >> 8];
1166 /* if (!uOffset) return (CodePageTable->MultiByteTable[ch] == wch); */
1167 return (CodePageTable->DBCSOffsets[uOffset + (ch & 0xff)] == wch);
1168 }
1169
1170 return (CodePageTable->MultiByteTable[ch] == wch);
1171 }
1172
1173 /* If we're still here, we have a valid mapping */
1174 return TRUE;
1175}
unsigned char ch[4][2]
Definition: console.c:118
#define WC_NO_BEST_FIT_CHARS
Definition: unicode.h:46
_Out_ PCPTABLEINFO CodePageTable
Definition: rtlfuncs.h:4319
unsigned short USHORT
Definition: pedump.c:61
USHORT TransDefaultChar
Definition: precomp.h:36
PUSHORT MultiByteTable
Definition: precomp.h:40
PUSHORT DBCSOffsets
Definition: precomp.h:43
USHORT TransUniDefaultChar
Definition: precomp.h:37
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by IntWideCharToMultiByteCP().

◆ IntIsValidSBCSMapping()

static BOOL IntIsValidSBCSMapping ( PCPTABLEINFO  CodePageTable,
DWORD  Flags,
WCHAR  wch,
UCHAR  ch 
)
inlinestatic

Definition at line 1131 of file nls.c.

1132{
1133 /* If the WC_NO_BEST_FIT_CHARS flag has been specified, the characters need to match exactly. */
1135 return (CodePageTable->MultiByteTable[ch] == wch);
1136
1137 /* By default, all characters except TransDefaultChar apply as a valid mapping
1138 for ch (so also "nearest" characters) */
1140 return TRUE;
1141
1142 /* The only possible left valid mapping is the default character itself */
1143 return (wch == CodePageTable->TransUniDefaultChar);
1144}

Referenced by IntWideCharToMultiByteCP().

◆ IntMultiByteToWideCharCP()

static INT WINAPI IntMultiByteToWideCharCP ( UINT  CodePage,
DWORD  Flags,
LPCSTR  MultiByteString,
INT  MultiByteCount,
LPWSTR  WideCharString,
INT  WideCharCount 
)
static

Definition at line 691 of file nls.c.

697{
698 PCODEPAGE_ENTRY CodePageEntry;
700 PUSHORT MultiByteTable;
701 LPCSTR TempString;
702 INT TempLength;
703 USHORT WideChar;
704
705 /* Get code page table. */
706 CodePageEntry = IntGetCodePageEntry(CodePage);
707 if (CodePageEntry == NULL)
708 {
710 return 0;
711 }
712
713 CodePageTable = &CodePageEntry->CodePageTable;
714
715 /* If MB_USEGLYPHCHARS flag present and glyph table present */
717 {
718 /* Use glyph table */
719 MultiByteTable = CodePageTable->MultiByteTable + 256 + 1;
720 }
721 else
722 {
723 MultiByteTable = CodePageTable->MultiByteTable;
724 }
725
726 /* Different handling for DBCS code pages. */
728 {
729 UCHAR Char;
730 USHORT DBCSOffset;
731 LPCSTR MbsEnd = MultiByteString + MultiByteCount;
732 INT Count;
733
735 {
736 TempString = MultiByteString;
737
738 while (TempString < MbsEnd)
739 {
740 DBCSOffset = CodePageTable->DBCSOffsets[(UCHAR)*TempString];
741
742 if (DBCSOffset)
743 {
744 /* If lead byte is presented, but behind it there is no symbol */
745 if (((TempString + 1) == MbsEnd) || (*(TempString + 1) == 0))
746 {
748 return 0;
749 }
750
751 WideChar = CodePageTable->DBCSOffsets[DBCSOffset + *(TempString + 1)];
752
753 if (WideChar == CodePageTable->UniDefaultChar &&
754 MAKEWORD(*(TempString + 1), *TempString) != CodePageTable->TransUniDefaultChar)
755 {
757 return 0;
758 }
759
760 TempString++;
761 }
762 else
763 {
764 WideChar = MultiByteTable[(UCHAR)*TempString];
765
766 if ((WideChar == CodePageTable->UniDefaultChar &&
767 *TempString != CodePageTable->TransUniDefaultChar) ||
768 /* "Private Use" characters */
769 (WideChar >= 0xE000 && WideChar <= 0xF8FF))
770 {
772 return 0;
773 }
774 }
775
776 TempString++;
777 }
778 }
779
780 /* Does caller query for output buffer size? */
781 if (WideCharCount == 0)
782 {
783 for (; MultiByteString < MbsEnd; WideCharCount++)
784 {
785 Char = *MultiByteString++;
786
787 DBCSOffset = CodePageTable->DBCSOffsets[Char];
788
789 if (!DBCSOffset)
790 continue;
791
792 if (MultiByteString < MbsEnd)
794 }
795
796 return WideCharCount;
797 }
798
799 for (Count = 0; Count < WideCharCount && MultiByteString < MbsEnd; Count++)
800 {
801 Char = *MultiByteString++;
802
803 DBCSOffset = CodePageTable->DBCSOffsets[Char];
804
805 if (!DBCSOffset)
806 {
807 *WideCharString++ = MultiByteTable[Char];
808 continue;
809 }
810
811 if (MultiByteString == MbsEnd || *MultiByteString == 0)
812 {
813 *WideCharString++ = CodePageTable->UniDefaultChar;
814 }
815 else
816 {
817 *WideCharString++ = CodePageTable->DBCSOffsets[DBCSOffset + (UCHAR)*MultiByteString++];
818 }
819 }
820
821 if (MultiByteString < MbsEnd)
822 {
824 return 0;
825 }
826
827 return Count;
828 }
829 else /* SBCS code page */
830 {
831 /* Check for invalid characters. */
833 {
834 for (TempString = MultiByteString, TempLength = MultiByteCount;
835 TempLength > 0;
836 TempString++, TempLength--)
837 {
838 WideChar = MultiByteTable[(UCHAR)*TempString];
839
840 if ((WideChar == CodePageTable->UniDefaultChar &&
841 *TempString != CodePageTable->TransUniDefaultChar) ||
842 /* "Private Use" characters */
843 (WideChar >= 0xE000 && WideChar <= 0xF8FF))
844 {
846 return 0;
847 }
848 }
849 }
850
851 /* Does caller query for output buffer size? */
852 if (WideCharCount == 0)
853 return MultiByteCount;
854
855 /* Fill the WideCharString buffer with what will fit: Verified on WinXP */
856 for (TempLength = (WideCharCount < MultiByteCount) ? WideCharCount : MultiByteCount;
857 TempLength > 0;
858 MultiByteString++, TempLength--)
859 {
860 *WideCharString++ = MultiByteTable[(UCHAR)*MultiByteString];
861 }
862
863 /* Adjust buffer size. Wine trick ;-) */
864 if (WideCharCount < MultiByteCount)
865 {
866 MultiByteCount = WideCharCount;
868 return 0;
869 }
870 return MultiByteCount;
871 }
872}
#define MB_USEGLYPHCHARS
Definition: unicode.h:42
#define MB_ERR_INVALID_CHARS
Definition: unicode.h:41
int Count
Definition: noreturn.cpp:7
USHORT DBCSCodePage
Definition: precomp.h:38
const char * LPCSTR
Definition: typedefs.h:52
#define MAKEWORD(a, b)
Definition: typedefs.h:248
int32_t INT
Definition: typedefs.h:58
#define ERROR_NO_UNICODE_TRANSLATION
Definition: winerror.h:973
*BytesInMultiByteString PCHAR MultiByteString
Definition: rtlfuncs.h:1544

Referenced by MultiByteToWideChar().

◆ IntMultiByteToWideCharSYMBOL()

static INT WINAPI IntMultiByteToWideCharSYMBOL ( DWORD  Flags,
LPCSTR  MultiByteString,
INT  MultiByteCount,
LPWSTR  WideCharString,
INT  WideCharCount 
)
static

Definition at line 885 of file nls.c.

890{
891 LONG Count;
892 UCHAR Char;
893 INT WideCharMaxLen;
894
895
896 if (Flags != 0)
897 {
899 return 0;
900 }
901
902 if (WideCharCount == 0)
903 {
904 return MultiByteCount;
905 }
906
907 WideCharMaxLen = WideCharCount > MultiByteCount ? MultiByteCount : WideCharCount;
908
909 for (Count = 0; Count < WideCharMaxLen; Count++)
910 {
911 Char = MultiByteString[Count];
912 if ( Char < 0x20 )
913 {
914 WideCharString[Count] = Char;
915 }
916 else
917 {
918 WideCharString[Count] = Char + 0xf000;
919 }
920 }
921 if (MultiByteCount > WideCharMaxLen)
922 {
924 return 0;
925 }
926
927 return WideCharMaxLen;
928}
long LONG
Definition: pedump.c:60
#define ERROR_INVALID_FLAGS
Definition: winerror.h:907

Referenced by MultiByteToWideChar().

◆ IntMultiByteToWideCharUTF8()

static INT WINAPI IntMultiByteToWideCharUTF8 ( DWORD  Flags,
LPCSTR  MultiByteString,
INT  MultiByteCount,
LPWSTR  WideCharString,
INT  WideCharCount 
)
static

Definition at line 494 of file nls.c.

499{
500 LPCSTR MbsEnd, MbsPtrSave;
501 UCHAR Char, TrailLength;
502 UINT WideChar;
503 LONG Count;
504 BOOL CharIsValid, StringIsValid = TRUE;
505 const WCHAR InvalidChar = 0xFFFD;
506
507 if (Flags != 0 && Flags != MB_ERR_INVALID_CHARS)
508 {
510 return 0;
511 }
512
513 /* Does caller query for output buffer size? */
514 if (WideCharCount == 0)
515 {
516 /* validate and count the wide characters */
517 MbsEnd = MultiByteString + MultiByteCount;
518 for (; MultiByteString < MbsEnd; WideCharCount++)
519 {
520 Char = *MultiByteString++;
521 if (Char < 0x80)
522 {
523 TrailLength = 0;
524 continue;
525 }
526 if ((Char & 0xC0) == 0x80)
527 {
528 TrailLength = 0;
529 StringIsValid = FALSE;
530 continue;
531 }
532
533 TrailLength = UTF8Length[Char - 0x80];
534 if (TrailLength == 0)
535 {
536 StringIsValid = FALSE;
537 continue;
538 }
539
540 CharIsValid = TRUE;
541 MbsPtrSave = MultiByteString;
542 WideChar = Char & UTF8Mask[TrailLength];
543
544 while (TrailLength && MultiByteString < MbsEnd)
545 {
546 if ((*MultiByteString & 0xC0) != 0x80)
547 {
548 CharIsValid = StringIsValid = FALSE;
549 break;
550 }
551
552 WideChar = (WideChar << 6) | (*MultiByteString++ & 0x7f);
553 TrailLength--;
554 }
555
556 if (!CharIsValid || WideChar < UTF8LBound[UTF8Length[Char - 0x80]])
557 {
558 MultiByteString = MbsPtrSave;
559 }
560
561 if (WideChar > 0xFFFF)
562 {
563 /* UTF-16 surrogate pair */
564 WideCharCount++;
565 }
566 }
567
568 if (TrailLength)
569 {
570 WideCharCount++;
571 StringIsValid = FALSE;
572 }
573
574 if (Flags == MB_ERR_INVALID_CHARS && !StringIsValid)
575 {
577 return 0;
578 }
579
580 return WideCharCount;
581 }
582
583 /* convert */
584 MbsEnd = MultiByteString + MultiByteCount;
585 for (Count = 0; Count < WideCharCount && MultiByteString < MbsEnd; Count++)
586 {
587 Char = *MultiByteString++;
588 if (Char < 0x80)
589 {
590 *WideCharString++ = Char;
591 TrailLength = 0;
592 continue;
593 }
594 if ((Char & 0xC0) == 0x80)
595 {
596 *WideCharString++ = InvalidChar;
597 TrailLength = 0;
598 StringIsValid = FALSE;
599 continue;
600 }
601
602 TrailLength = UTF8Length[Char - 0x80];
603 if (TrailLength == 0)
604 {
605 *WideCharString++ = InvalidChar;
606 StringIsValid = FALSE;
607 continue;
608 }
609
610 CharIsValid = TRUE;
611 MbsPtrSave = MultiByteString;
612 WideChar = Char & UTF8Mask[TrailLength];
613
614 while (TrailLength && MultiByteString < MbsEnd)
615 {
616 if ((*MultiByteString & 0xC0) != 0x80)
617 {
618 CharIsValid = StringIsValid = FALSE;
619 break;
620 }
621
622 WideChar = (WideChar << 6) | (*MultiByteString++ & 0x7f);
623 TrailLength--;
624 }
625
626 if (CharIsValid && UTF8LBound[UTF8Length[Char - 0x80]] <= WideChar)
627 {
628 /* Check for UTF-16 surrogate pair */
629 if (WideChar > 0xFFFF)
630 {
631 WideChar -= 0x10000;
632 *WideCharString++ = 0xD800 | (WideChar >> 10);
633 Count++;
634
635 /* Check if we have space for the second surrogate */
636 if (Count >= WideCharCount)
637 {
639 return 0;
640 }
641
642 *WideCharString++ = 0xDC00 | (WideChar & 0x3FF);
643 }
644 else
645 {
646 *WideCharString++ = WideChar;
647 }
648 }
649 else
650 {
651 *WideCharString++ = InvalidChar;
652 MultiByteString = MbsPtrSave;
653 StringIsValid = FALSE;
654 }
655 }
656
657 if (TrailLength && Count < WideCharCount && MultiByteString < MbsEnd)
658 {
659 *WideCharString = InvalidChar;
660 WideCharCount++;
661 }
662
663 if (MultiByteString < MbsEnd)
664 {
666 return 0;
667 }
668
669 if (Flags == MB_ERR_INVALID_CHARS && (!StringIsValid || TrailLength))
670 {
672 return 0;
673 }
674
675 return Count;
676}
static const char UTF8Length[128]
Definition: nls.c:25
static const unsigned long UTF8LBound[]
Definition: nls.c:41
static const unsigned char UTF8Mask[6]
Definition: nls.c:38

Referenced by MultiByteToWideChar().

◆ IntWideCharToMultiByteCP()

static INT WINAPI IntWideCharToMultiByteCP ( UINT  CodePage,
DWORD  Flags,
LPCWSTR  WideCharString,
INT  WideCharCount,
LPSTR  MultiByteString,
INT  MultiByteCount,
LPCSTR  DefaultChar,
LPBOOL  UsedDefaultChar 
)
static

Definition at line 1188 of file nls.c.

1196{
1197 PCODEPAGE_ENTRY CodePageEntry;
1199 INT TempLength;
1200
1201 /* Get code page table. */
1202 CodePageEntry = IntGetCodePageEntry(CodePage);
1203 if (CodePageEntry == NULL)
1204 {
1206 return 0;
1207 }
1208
1209 CodePageTable = &CodePageEntry->CodePageTable;
1210
1211
1212 /* Different handling for DBCS code pages. */
1214 {
1215 /* If Flags, DefaultChar or UsedDefaultChar were given, we have to do some more work */
1216 if (Flags || DefaultChar || UsedDefaultChar)
1217 {
1218 BOOL TempUsedDefaultChar;
1219 USHORT DefChar;
1220
1221 /* If UsedDefaultChar is not set, set it to a temporary value, so we don't have
1222 to check on every character */
1223 if (!UsedDefaultChar)
1224 UsedDefaultChar = &TempUsedDefaultChar;
1225
1226 *UsedDefaultChar = FALSE;
1227
1228 /* Use the CodePage's TransDefaultChar if none was given. Don't modify the DefaultChar pointer here. */
1229 if (DefaultChar)
1230 DefChar = DefaultChar[1] ? ((DefaultChar[0] << 8) | DefaultChar[1]) : DefaultChar[0];
1231 else
1233
1234 /* Does caller query for output buffer size? */
1235 if (!MultiByteCount)
1236 {
1237 for (TempLength = 0; WideCharCount; WideCharCount--, WideCharString++, TempLength++)
1238 {
1239 USHORT uChar;
1240
1241 if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1242 {
1243 /* FIXME: Handle WC_COMPOSITECHECK */
1244 DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1245 }
1246
1247 uChar = ((PUSHORT) CodePageTable->WideCharTable)[*WideCharString];
1248
1249 /* Verify if the mapping is valid for handling DefaultChar and UsedDefaultChar */
1250 if (!IntIsValidDBCSMapping(CodePageTable, Flags, *WideCharString, uChar))
1251 {
1252 uChar = DefChar;
1253 *UsedDefaultChar = TRUE;
1254 }
1255
1256 /* Increment TempLength again if this is a double-byte character */
1257 if (uChar & 0xff00)
1258 TempLength++;
1259 }
1260
1261 return TempLength;
1262 }
1263
1264 /* Convert the WideCharString to the MultiByteString and verify if the mapping is valid */
1265 for (TempLength = MultiByteCount;
1266 WideCharCount && TempLength;
1267 TempLength--, WideCharString++, WideCharCount--)
1268 {
1269 USHORT uChar;
1270
1271 if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1272 {
1273 /* FIXME: Handle WC_COMPOSITECHECK */
1274 DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1275 }
1276
1277 uChar = ((PUSHORT)CodePageTable->WideCharTable)[*WideCharString];
1278
1279 /* Verify if the mapping is valid for handling DefaultChar and UsedDefaultChar */
1280 if (!IntIsValidDBCSMapping(CodePageTable, Flags, *WideCharString, uChar))
1281 {
1282 uChar = DefChar;
1283 *UsedDefaultChar = TRUE;
1284 }
1285
1286 /* Handle double-byte characters */
1287 if (uChar & 0xff00)
1288 {
1289 /* Don't output a partial character */
1290 if (TempLength == 1)
1291 break;
1292
1293 TempLength--;
1294 *MultiByteString++ = uChar >> 8;
1295 }
1296
1297 *MultiByteString++ = (char)uChar;
1298 }
1299
1300 /* WideCharCount should be 0 if all characters were converted */
1301 if (WideCharCount)
1302 {
1304 return 0;
1305 }
1306
1307 return MultiByteCount - TempLength;
1308 }
1309
1310 /* Does caller query for output buffer size? */
1311 if (!MultiByteCount)
1312 {
1313 for (TempLength = 0; WideCharCount; WideCharCount--, WideCharString++, TempLength++)
1314 {
1315 /* Increment TempLength again if this is a double-byte character */
1316 if (((PWCHAR)CodePageTable->WideCharTable)[*WideCharString] & 0xff00)
1317 TempLength++;
1318 }
1319
1320 return TempLength;
1321 }
1322
1323 /* Convert the WideCharString to the MultiByteString */
1324 for (TempLength = MultiByteCount;
1325 WideCharCount && TempLength;
1326 TempLength--, WideCharString++, WideCharCount--)
1327 {
1328 USHORT uChar = ((PUSHORT) CodePageTable->WideCharTable)[*WideCharString];
1329
1330 /* Is this a double-byte character? */
1331 if (uChar & 0xff00)
1332 {
1333 /* Don't output a partial character */
1334 if (TempLength == 1)
1335 break;
1336
1337 TempLength--;
1338 *MultiByteString++ = uChar >> 8;
1339 }
1340
1341 *MultiByteString++ = (char)uChar;
1342 }
1343
1344 /* WideCharCount should be 0 if all characters were converted */
1345 if (WideCharCount)
1346 {
1348 return 0;
1349 }
1350
1351 return MultiByteCount - TempLength;
1352 }
1353 else /* SBCS code page */
1354 {
1355 INT nReturn;
1356
1357 /* If Flags, DefaultChar or UsedDefaultChar were given, we have to do some more work */
1358 if (Flags || DefaultChar || UsedDefaultChar)
1359 {
1360 BOOL TempUsedDefaultChar;
1361 CHAR DefChar;
1362
1363 /* If UsedDefaultChar is not set, set it to a temporary value, so we don't have
1364 to check on every character */
1365 if (!UsedDefaultChar)
1366 UsedDefaultChar = &TempUsedDefaultChar;
1367
1368 *UsedDefaultChar = FALSE;
1369
1370 /* Does caller query for output buffer size? */
1371 if (!MultiByteCount)
1372 {
1373 /* Loop through the whole WideCharString and check if we can get a valid mapping for each character */
1374 for (TempLength = 0; WideCharCount; TempLength++, WideCharString++, WideCharCount--)
1375 {
1376 if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1377 {
1378 /* FIXME: Handle WC_COMPOSITECHECK */
1379 DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1380 }
1381
1382 if (!*UsedDefaultChar)
1383 *UsedDefaultChar = !IntIsValidSBCSMapping(CodePageTable,
1384 Flags,
1385 *WideCharString,
1386 ((PCHAR)CodePageTable->WideCharTable)[*WideCharString]);
1387 }
1388
1389 return TempLength;
1390 }
1391
1392 /* Use the CodePage's TransDefaultChar if none was given. Don't modify the DefaultChar pointer here. */
1393 if (DefaultChar)
1394 DefChar = *DefaultChar;
1395 else
1397
1398 /* Convert the WideCharString to the MultiByteString and verify if the mapping is valid */
1399 for (TempLength = MultiByteCount;
1400 WideCharCount && TempLength;
1401 MultiByteString++, TempLength--, WideCharString++, WideCharCount--)
1402 {
1403 if ((Flags & WC_COMPOSITECHECK) && WideCharCount > 1)
1404 {
1405 /* FIXME: Handle WC_COMPOSITECHECK */
1406 DPRINT("WC_COMPOSITECHECK flag UNIMPLEMENTED\n");
1407 }
1408
1409 *MultiByteString = ((PCHAR)CodePageTable->WideCharTable)[*WideCharString];
1410
1411 if (!IntIsValidSBCSMapping(CodePageTable, Flags, *WideCharString, *MultiByteString))
1412 {
1413 *MultiByteString = DefChar;
1414 *UsedDefaultChar = TRUE;
1415 }
1416 }
1417
1418 /* WideCharCount should be 0 if all characters were converted */
1419 if (WideCharCount)
1420 {
1422 return 0;
1423 }
1424
1425 return MultiByteCount - TempLength;
1426 }
1427
1428 /* Does caller query for output buffer size? */
1429 if (!MultiByteCount)
1430 return WideCharCount;
1431
1432 /* Is the buffer large enough? */
1433 if (MultiByteCount < WideCharCount)
1434 {
1435 /* Convert the string up to MultiByteCount and return 0 */
1436 WideCharCount = MultiByteCount;
1438 nReturn = 0;
1439 }
1440 else
1441 {
1442 /* Otherwise WideCharCount will be the number of converted characters */
1443 nReturn = WideCharCount;
1444 }
1445
1446 /* Convert the WideCharString to the MultiByteString */
1447 for (TempLength = WideCharCount; --TempLength >= 0; WideCharString++, MultiByteString++)
1448 {
1449 *MultiByteString = ((PCHAR)CodePageTable->WideCharTable)[*WideCharString];
1450 }
1451
1452 return nReturn;
1453 }
1454}
#define CHAR(Char)
static BOOL IntIsValidSBCSMapping(PCPTABLEINFO CodePageTable, DWORD Flags, WCHAR wch, UCHAR ch)
Definition: nls.c:1131
static BOOL IntIsValidDBCSMapping(PCPTABLEINFO CodePageTable, DWORD Flags, WCHAR wch, USHORT ch)
Definition: nls.c:1154
unsigned char
Definition: typeof.h:29
#define WC_COMPOSITECHECK
Definition: unicode.h:43
#define PCHAR
Definition: match.c:90
for(i=0;i< sizeof(testsuite)/sizeof(testsuite[0]);++i) ok(call_test(testsuite[i].func)
#define DPRINT
Definition: sndvol32.h:73
PVOID WideCharTable
Definition: precomp.h:41
uint16_t * PWCHAR
Definition: typedefs.h:56
char * PCHAR
Definition: typedefs.h:51

Referenced by WideCharToMultiByte().

◆ IntWideCharToMultiByteSYMBOL()

static INT WINAPI IntWideCharToMultiByteSYMBOL ( DWORD  Flags,
LPCWSTR  WideCharString,
INT  WideCharCount,
LPSTR  MultiByteString,
INT  MultiByteCount 
)
static

Definition at line 940 of file nls.c.

945{
946 LONG Count;
947 INT MaxLen;
948 WCHAR Char;
949
950 if (Flags!=0)
951 {
953 return 0;
954 }
955
956
957 if (MultiByteCount == 0)
958 {
959 return WideCharCount;
960 }
961
962 MaxLen = MultiByteCount > WideCharCount ? WideCharCount : MultiByteCount;
963 for (Count = 0; Count < MaxLen; Count++)
964 {
965 Char = WideCharString[Count];
966 if (Char < 0x20)
967 {
968 MultiByteString[Count] = (CHAR)Char;
969 }
970 else
971 {
972 if ((Char >= 0xf020) && (Char < 0xf100))
973 {
974 MultiByteString[Count] = Char - 0xf000;
975 }
976 else
977 {
979 return 0;
980 }
981 }
982 }
983
984 if (WideCharCount > MaxLen)
985 {
987 return 0;
988 }
989 return MaxLen;
990}

Referenced by WideCharToMultiByte().

◆ IntWideCharToMultiByteUTF8()

static INT WINAPI IntWideCharToMultiByteUTF8 ( UINT  CodePage,
DWORD  Flags,
LPCWSTR  WideCharString,
INT  WideCharCount,
LPSTR  MultiByteString,
INT  MultiByteCount,
LPCSTR  DefaultChar,
LPBOOL  UsedDefaultChar 
)
static

Definition at line 1002 of file nls.c.

1010{
1011 INT TempLength;
1012 DWORD Char;
1013
1014 if (Flags)
1015 {
1017 return 0;
1018 }
1019
1020 /* Does caller query for output buffer size? */
1021 if (MultiByteCount == 0)
1022 {
1023 for (TempLength = 0; WideCharCount;
1024 WideCharCount--, WideCharString++)
1025 {
1026 TempLength++;
1027 if (*WideCharString >= 0x80)
1028 {
1029 TempLength++;
1030 if (*WideCharString >= 0x800)
1031 {
1032 TempLength++;
1033 if (*WideCharString >= 0xd800 && *WideCharString < 0xdc00 &&
1034 WideCharCount >= 1 &&
1035 WideCharString[1] >= 0xdc00 && WideCharString[1] <= 0xe000)
1036 {
1037 WideCharCount--;
1038 WideCharString++;
1039 TempLength++;
1040 }
1041 }
1042 }
1043 }
1044 return TempLength;
1045 }
1046
1047 for (TempLength = MultiByteCount; WideCharCount; WideCharCount--, WideCharString++)
1048 {
1049 Char = *WideCharString;
1050 if (Char < 0x80)
1051 {
1052 if (!TempLength)
1053 {
1055 break;
1056 }
1057 TempLength--;
1058 *MultiByteString++ = (CHAR)Char;
1059 continue;
1060 }
1061
1062 if (Char < 0x800) /* 0x80-0x7ff: 2 bytes */
1063 {
1064 if (TempLength < 2)
1065 {
1067 break;
1068 }
1069 MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
1070 MultiByteString[0] = 0xc0 | Char;
1071 MultiByteString += 2;
1072 TempLength -= 2;
1073 continue;
1074 }
1075
1076 /* surrogate pair 0x10000-0x10ffff: 4 bytes */
1077 if (Char >= 0xd800 && Char < 0xdc00 &&
1078 WideCharCount >= 1 &&
1079 WideCharString[1] >= 0xdc00 && WideCharString[1] < 0xe000)
1080 {
1081 WideCharCount--;
1082 WideCharString++;
1083
1084 if (TempLength < 4)
1085 {
1087 break;
1088 }
1089
1090 Char = (Char - 0xd800) << 10;
1091 Char |= *WideCharString - 0xdc00;
1092 ASSERT(Char <= 0xfffff);
1093 Char += 0x10000;
1094 ASSERT(Char <= 0x10ffff);
1095
1096 MultiByteString[3] = 0x80 | (Char & 0x3f); Char >>= 6;
1097 MultiByteString[2] = 0x80 | (Char & 0x3f); Char >>= 6;
1098 MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
1099 MultiByteString[0] = 0xf0 | Char;
1100 MultiByteString += 4;
1101 TempLength -= 4;
1102 continue;
1103 }
1104
1105 /* 0x800-0xffff: 3 bytes */
1106 if (TempLength < 3)
1107 {
1109 break;
1110 }
1111 MultiByteString[2] = 0x80 | (Char & 0x3f); Char >>= 6;
1112 MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
1113 MultiByteString[0] = 0xe0 | Char;
1114 MultiByteString += 3;
1115 TempLength -= 3;
1116 }
1117
1118 return MultiByteCount - TempLength;
1119}
#define ASSERT(a)
Definition: mode.c:44

Referenced by WideCharToMultiByte().

◆ IsDBCSLeadByte()

BOOL WINAPI IsDBCSLeadByte ( BYTE  TestByte)

Definition at line 2390 of file nls.c.

2391{
2392 return IntIsLeadByte(&AnsiCodePage.CodePageTable, TestByte);
2393}
static BOOL WINAPI IntIsLeadByte(PCPTABLEINFO TableInfo, BYTE Byte)
Definition: nls.c:1465

◆ IsDBCSLeadByteEx()

BOOL WINAPI IsDBCSLeadByteEx ( UINT  CodePage,
BYTE  TestByte 
)

Definition at line 2368 of file nls.c.

2369{
2370 PCODEPAGE_ENTRY CodePageEntry;
2371
2372 CodePageEntry = IntGetCodePageEntry(CodePage);
2373 if (CodePageEntry != NULL)
2374 return IntIsLeadByte(&CodePageEntry->CodePageTable, TestByte);
2375
2377 return FALSE;
2378}

◆ IsNLSDefinedString()

BOOL WINAPI IsNLSDefinedString ( IN NLS_FUNCTION  Function,
IN DWORD  dwFlags,
IN LPNLSVERSIONINFO  lpVersionInformation,
IN LPCWSTR  lpString,
IN INT  cchStr 
)

Definition at line 2592 of file nls.c.

2597{
2598 STUB;
2599 return TRUE;
2600}

◆ IsValidCodePage()

BOOL WINAPI IsValidCodePage ( UINT  CodePage)

Definition at line 1633 of file nls.c.

1634{
1635 if (CodePage == 0) return FALSE;
1636 if (CodePage == CP_UTF8 || CodePage == CP_UTF7)
1637 return TRUE;
1638 if (IntGetLoadedCodePageEntry(CodePage))
1639 return TRUE;
1640 return GetCPFileNameFromRegistry(CodePage, NULL, 0);
1641}

◆ IsValidUILanguage()

BOOL WINAPI IsValidUILanguage ( LANGID  langid)

Definition at line 2498 of file nls.c.

2499{
2500 STUB;
2501 return 0;
2502}

◆ MultiByteToWideChar()

INT WINAPI MultiByteToWideChar ( UINT  CodePage,
DWORD  Flags,
LPCSTR  MultiByteString,
INT  MultiByteCount,
LPWSTR  WideCharString,
INT  WideCharCount 
)

Definition at line 1792 of file nls.c.

1798{
1799 /* Check the parameters. */
1800 if (MultiByteString == NULL ||
1801 MultiByteCount == 0 || WideCharCount < 0 ||
1802 (WideCharCount && (WideCharString == NULL ||
1803 (PVOID)MultiByteString == (PVOID)WideCharString)))
1804 {
1806 return 0;
1807 }
1808
1809 /* Determine the input string length. */
1810 if (MultiByteCount < 0)
1811 {
1812 MultiByteCount = lstrlenA(MultiByteString) + 1;
1813 }
1814
1815 switch (CodePage)
1816 {
1817 case CP_UTF8:
1820 MultiByteCount,
1821 WideCharString,
1822 WideCharCount);
1823
1824 case CP_UTF7:
1825 if (Flags)
1826 {
1828 return 0;
1829 }
1830 return Utf7ToWideChar(MultiByteString, MultiByteCount,
1831 WideCharString, WideCharCount);
1832
1833 case CP_SYMBOL:
1836 MultiByteCount,
1837 WideCharString,
1838 WideCharCount);
1839 default:
1840 return IntMultiByteToWideCharCP(CodePage,
1841 Flags,
1843 MultiByteCount,
1844 WideCharString,
1845 WideCharCount);
1846 }
1847}
static INT Utf7ToWideChar(const char *src, int srclen, WCHAR *dst, int dstlen)
Definition: nls.c:1658
static INT WINAPI IntMultiByteToWideCharUTF8(DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:494
static INT WINAPI IntMultiByteToWideCharCP(UINT CodePage, DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:691
static INT WINAPI IntMultiByteToWideCharSYMBOL(DWORD Flags, LPCSTR MultiByteString, INT MultiByteCount, LPWSTR WideCharString, INT WideCharCount)
Definition: nls.c:885
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define CP_SYMBOL
Definition: winnls.h:252

◆ NlsConvertIntegerToString()

VOID WINAPI NlsConvertIntegerToString ( ULONG  Value,
ULONG  Base,
ULONG  strsize,
LPWSTR  str,
ULONG  strsize2 
)

Definition at line 2507 of file nls.c.

2508{
2509 STUB;
2510}

◆ NlsGetCacheUpdateCount()

ULONG WINAPI NlsGetCacheUpdateCount ( VOID  )

Definition at line 2581 of file nls.c.

2582{
2583 STUB;
2584 return 0;
2585}

◆ NlsInit()

BOOL FASTCALL NlsInit ( VOID  )

Definition at line 151 of file nls.c.

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}
#define NLS_SIZEOF_ACE_AND_SIDS(n)
Definition: base.h:26
_In_ PFCB _In_ PCD_NAME DirName
Definition: cdprocs.h:737
static NTSTATUS CreateNlsDirectorySecurity(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ SIZE_T DescriptorSize)
Creates a security descriptor for the NLS object directory.
Definition: nls.c:81
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
ULONG Handle
Definition: gdb_input.c:15
#define NtCurrentTeb
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSTATUS NTAPI NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:765
#define OBJ_PERMANENT
Definition: winternl.h:226

Referenced by DllMain().

◆ NlsResetProcessLocale()

BOOL WINAPI NlsResetProcessLocale ( VOID  )

Definition at line 2537 of file nls.c.

2538{
2539 STUB;
2540 return TRUE;
2541}

◆ NlsUninit()

VOID FASTCALL NlsUninit ( VOID  )

Definition at line 223 of file nls.c.

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}
#define UnmapViewOfFile
Definition: compat.h:746
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
NTSYSAPI NTSTATUS NTAPI RtlDeleteCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)

Referenced by DllMain().

◆ SetCPGlobal()

UINT WINAPI SetCPGlobal ( UINT  CodePage)

Definition at line 2515 of file nls.c.

2516{
2517 STUB;
2518 return 0;
2519}

◆ utf7_can_directly_encode()

static BOOL utf7_can_directly_encode ( WCHAR  codepoint)
inlinestatic

Definition at line 1849 of file nls.c.

1850{
1851 static const BOOL directly_encodable_table[] =
1852 {
1853 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, /* 0x00 - 0x0F */
1854 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1F */
1855 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* 0x20 - 0x2F */
1856 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x30 - 0x3F */
1857 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4F */
1858 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x50 - 0x5F */
1859 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6F */
1860 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* 0x70 - 0x7A */
1861 };
1862
1863 return codepoint <= 0x7A ? directly_encodable_table[codepoint] : FALSE;
1864}

Referenced by WideCharToUtf7().

◆ utf7_write_c()

static BOOL utf7_write_c ( char dst,
int  dstlen,
int index,
char  character 
)
inlinestatic

Definition at line 1866 of file nls.c.

1867{
1868 if (dstlen > 0)
1869 {
1870 if (*index >= dstlen)
1871 return FALSE;
1872
1873 dst[*index] = character;
1874 }
1875
1876 (*index)++;
1877
1878 return TRUE;
1879}
#define index(s, c)
Definition: various.h:29
GLuint index
Definition: glext.h:6031
GLenum GLenum dst
Definition: glext.h:6340
static DWORD dstlen
Definition: directory.c:51

Referenced by WideCharToUtf7().

◆ utf7_write_w()

static BOOL utf7_write_w ( WCHAR dst,
int  dstlen,
int index,
WCHAR  character 
)
inlinestatic

Definition at line 1643 of file nls.c.

1644{
1645 if (dstlen > 0)
1646 {
1647 if (*index >= dstlen)
1648 return FALSE;
1649
1650 dst[*index] = character;
1651 }
1652
1653 (*index)++;
1654
1655 return TRUE;
1656}

Referenced by Utf7ToWideChar().

◆ Utf7ToWideChar()

static INT Utf7ToWideChar ( const char src,
int  srclen,
WCHAR dst,
int  dstlen 
)
static

Definition at line 1658 of file nls.c.

1659{
1660 static const signed char base64_decoding_table[] =
1661 {
1662 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00-0x0F */
1663 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10-0x1F */
1664 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20-0x2F */
1665 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30-0x3F */
1666 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40-0x4F */
1667 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50-0x5F */
1668 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60-0x6F */
1669 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 /* 0x70-0x7F */
1670 };
1671
1672 const char *source_end = src + srclen;
1673 int dest_index = 0;
1674
1675 DWORD byte_pair = 0;
1676 short offset = 0;
1677
1678 while (src < source_end)
1679 {
1680 if (*src == '+')
1681 {
1682 src++;
1683 if (src >= source_end)
1684 break;
1685
1686 if (*src == '-')
1687 {
1688 /* just a plus sign escaped as +- */
1689 if (!utf7_write_w(dst, dstlen, &dest_index, '+'))
1690 {
1692 return 0;
1693 }
1694 src++;
1695 continue;
1696 }
1697
1698 do
1699 {
1700 signed char sextet = *src;
1701 if (sextet == '-')
1702 {
1703 /* skip over the dash and end base64 decoding
1704 * the current, unfinished byte pair is discarded */
1705 src++;
1706 offset = 0;
1707 break;
1708 }
1709 if (sextet < 0)
1710 {
1711 /* the next character of src is < 0 and therefore not part of a base64 sequence
1712 * the current, unfinished byte pair is NOT discarded in this case
1713 * this is probably a bug in Windows */
1714 break;
1715 }
1716
1717 sextet = base64_decoding_table[sextet];
1718 if (sextet == -1)
1719 {
1720 /* -1 means that the next character of src is not part of a base64 sequence
1721 * in other words, all sextets in this base64 sequence have been processed
1722 * the current, unfinished byte pair is discarded */
1723 offset = 0;
1724 break;
1725 }
1726
1727 byte_pair = (byte_pair << 6) | sextet;
1728 offset += 6;
1729
1730 if (offset >= 16)
1731 {
1732 /* this byte pair is done */
1733 if (!utf7_write_w(dst, dstlen, &dest_index, (byte_pair >> (offset - 16)) & 0xFFFF))
1734 {
1736 return 0;
1737 }
1738 offset -= 16;
1739 }
1740
1741 src++;
1742 }
1743 while (src < source_end);
1744 }
1745 else
1746 {
1747 /* we have to convert to unsigned char in case *src < 0 */
1748 if (!utf7_write_w(dst, dstlen, &dest_index, (unsigned char)*src))
1749 {
1751 return 0;
1752 }
1753 src++;
1754 }
1755 }
1756
1757 return dest_index;
1758}
static BOOL utf7_write_w(WCHAR *dst, int dstlen, int *index, WCHAR character)
Definition: nls.c:1643
GLenum src
Definition: glext.h:6340
GLintptr offset
Definition: glext.h:5920
static DWORD LPDWORD LPCSTR DWORD srclen
Definition: directory.c:52

Referenced by MultiByteToWideChar().

◆ ValidateLCType()

BOOL WINAPI ValidateLCType ( int  a1,
unsigned int  a2,
int  a3,
int  a4 
)

Definition at line 2526 of file nls.c.

2527{
2528 STUB;
2529 return FALSE;
2530}

◆ ValidateLocale()

BOOL WINAPI ValidateLocale ( IN ULONG  LocaleId)

Definition at line 2570 of file nls.c.

2571{
2572 STUB;
2573 return TRUE;
2574}

◆ WideCharToMultiByte()

INT WINAPI WideCharToMultiByte ( UINT  CodePage,
DWORD  Flags,
LPCWSTR  WideCharString,
INT  WideCharCount,
LPSTR  MultiByteString,
INT  MultiByteCount,
LPCSTR  DefaultChar,
LPBOOL  UsedDefaultChar 
)

Definition at line 2247 of file nls.c.

2255{
2256 /* Check the parameters. */
2257 if (WideCharString == NULL ||
2258 WideCharCount == 0 ||
2259 (MultiByteString == NULL && MultiByteCount > 0) ||
2260 (PVOID)WideCharString == (PVOID)MultiByteString ||
2261 MultiByteCount < 0)
2262 {
2264 return 0;
2265 }
2266
2267 /* Determine the input string length. */
2268 if (WideCharCount < 0)
2269 {
2270 WideCharCount = lstrlenW(WideCharString) + 1;
2271 }
2272
2273 switch (CodePage)
2274 {
2275 case CP_UTF8:
2276 if (DefaultChar != NULL || UsedDefaultChar != NULL)
2277 {
2279 return 0;
2280 }
2281 return IntWideCharToMultiByteUTF8(CodePage,
2282 Flags,
2283 WideCharString,
2284 WideCharCount,
2286 MultiByteCount,
2287 DefaultChar,
2288 UsedDefaultChar);
2289
2290 case CP_UTF7:
2291 if (DefaultChar != NULL || UsedDefaultChar != NULL)
2292 {
2294 return 0;
2295 }
2296 if (Flags)
2297 {
2299 return 0;
2300 }
2301 return WideCharToUtf7(WideCharString, WideCharCount,
2302 MultiByteString, MultiByteCount);
2303
2304 case CP_SYMBOL:
2305 if ((DefaultChar!=NULL) || (UsedDefaultChar!=NULL))
2306 {
2308 return 0;
2309 }
2311 WideCharString,
2312 WideCharCount,
2314 MultiByteCount);
2315
2316 default:
2317 return IntWideCharToMultiByteCP(CodePage,
2318 Flags,
2319 WideCharString,
2320 WideCharCount,
2322 MultiByteCount,
2323 DefaultChar,
2324 UsedDefaultChar);
2325 }
2326}
#define lstrlenW
Definition: compat.h:750
static INT WINAPI IntWideCharToMultiByteCP(UINT CodePage, DWORD Flags, LPCWSTR WideCharString, INT WideCharCount, LPSTR MultiByteString, INT MultiByteCount, LPCSTR DefaultChar, LPBOOL UsedDefaultChar)
Definition: nls.c:1188
static INT WideCharToUtf7(const WCHAR *src, int srclen, char *dst, int dstlen)
Definition: nls.c:1881
static INT WINAPI IntWideCharToMultiByteUTF8(UINT CodePage, DWORD Flags, LPCWSTR WideCharString, INT WideCharCount, LPSTR MultiByteString, INT MultiByteCount, LPCSTR DefaultChar, LPBOOL UsedDefaultChar)
Definition: nls.c:1002
static INT WINAPI IntWideCharToMultiByteSYMBOL(DWORD Flags, LPCWSTR WideCharString, INT WideCharCount, LPSTR MultiByteString, INT MultiByteCount)
Definition: nls.c:940

◆ WideCharToUtf7()

static INT WideCharToUtf7 ( const WCHAR src,
int  srclen,
char dst,
int  dstlen 
)
static

Definition at line 1881 of file nls.c.

1882{
1883 static const char base64_encoding_table[] =
1884 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1885
1886 const WCHAR *source_end = src + srclen;
1887 int dest_index = 0;
1888
1889 while (src < source_end)
1890 {
1891 if (*src == '+')
1892 {
1893 if (!utf7_write_c(dst, dstlen, &dest_index, '+'))
1894 {
1896 return 0;
1897 }
1898 if (!utf7_write_c(dst, dstlen, &dest_index, '-'))
1899 {
1901 return 0;
1902 }
1903 src++;
1904 }
1905 else if (utf7_can_directly_encode(*src))
1906 {
1907 if (!utf7_write_c(dst, dstlen, &dest_index, *src))
1908 {
1910 return 0;
1911 }
1912 src++;
1913 }
1914 else
1915 {
1916 unsigned int offset = 0;
1917 DWORD byte_pair = 0;
1918
1919 if (!utf7_write_c(dst, dstlen, &dest_index, '+'))
1920 {
1922 return 0;
1923 }
1924
1925 while (src < source_end && !utf7_can_directly_encode(*src))
1926 {
1927 byte_pair = (byte_pair << 16) | *src;
1928 offset += 16;
1929 while (offset >= 6)
1930 {
1931 if (!utf7_write_c(dst, dstlen, &dest_index, base64_encoding_table[(byte_pair >> (offset - 6)) & 0x3F]))
1932 {
1934 return 0;
1935 }
1936 offset -= 6;
1937 }
1938 src++;
1939 }
1940
1941 if (offset)
1942 {
1943 /* Windows won't create a padded base64 character if there's no room for the - sign
1944 * as well ; this is probably a bug in Windows */
1945 if (dstlen > 0 && dest_index + 1 >= dstlen)
1946 {
1948 return 0;
1949 }
1950
1951 byte_pair <<= (6 - offset);
1952 if (!utf7_write_c(dst, dstlen, &dest_index, base64_encoding_table[byte_pair & 0x3F]))
1953 {
1955 return 0;
1956 }
1957 }
1958
1959 /* Windows always explicitly terminates the base64 sequence
1960 even though RFC 2152 (page 3, rule 2) does not require this */
1961 if (!utf7_write_c(dst, dstlen, &dest_index, '-'))
1962 {
1964 return 0;
1965 }
1966 }
1967 }
1968
1969 return dest_index;
1970}
static BOOL utf7_can_directly_encode(WCHAR codepoint)
Definition: nls.c:1849
static BOOL utf7_write_c(char *dst, int dstlen, int *index, char character)
Definition: nls.c:1866

Referenced by WideCharToMultiByte().

Variable Documentation

◆ AnsiCodePage

CODEPAGE_ENTRY AnsiCodePage
static

◆ CodePageListHead

LIST_ENTRY CodePageListHead
static

Definition at line 45 of file nls.c.

Referenced by IntGetCodePageEntry(), IntGetLoadedCodePageEntry(), NlsInit(), and NlsUninit().

◆ CodePageListLock

RTL_CRITICAL_SECTION CodePageListLock
static

Definition at line 48 of file nls.c.

Referenced by IntGetCodePageEntry(), IntGetLoadedCodePageEntry(), NlsInit(), and NlsUninit().

◆ OemCodePage

◆ UTF8LBound

const unsigned long UTF8LBound[]
static
Initial value:
=
{0, 0x80, 0x800, 0x10000, 0x200000, 0x2000000, 0xFFFFFFFF}

Definition at line 41 of file nls.c.

Referenced by IntMultiByteToWideCharUTF8().

◆ UTF8Length

const char UTF8Length[128]
static
Initial value:
=
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0
}

Definition at line 25 of file nls.c.

Referenced by IntMultiByteToWideCharUTF8().

◆ UTF8Mask

const unsigned char UTF8Mask[6] = {0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01}
static

Definition at line 38 of file nls.c.

Referenced by IntMultiByteToWideCharUTF8().