508 lines
15 KiB
C
508 lines
15 KiB
C
/*++
|
|
|
|
Copyright (c) 1998-2000, Microsoft Corporation All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
csrlocal.c
|
|
|
|
Abstract:
|
|
|
|
This module implements functions that are used by the functions in locale.c
|
|
to communicate with csrss.
|
|
|
|
Author:
|
|
|
|
Michael Zoran (mzoran) 21-Jun-1998
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
|
|
//
|
|
// Include Files.
|
|
//
|
|
|
|
#include "nls.h"
|
|
#include "ntwow64n.h"
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CsrBasepNlsSetUserInfo
|
|
//
|
|
// Parameters:
|
|
// LCType The type of locale information to be set.
|
|
// pData The buffer which contains the information to be set.
|
|
// This is usually an Unicode string.
|
|
// DataLength The length of pData in BYTE.
|
|
//
|
|
// Return:
|
|
// STATUS_SUCCESS if the locale information is set correctly.
|
|
// Otherwise, a proper NTSTATUS error code is returned.
|
|
//
|
|
// Note:
|
|
// When kernel32.dll is complied for the WOW64 layer, we will call
|
|
// a thunk function NtWow64CsrBasepNlsSetUserInfo(), and it will
|
|
// in turn call the corresponding 64-bit version of this function.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
NTSTATUS CsrBasepNlsSetUserInfo(
|
|
IN LCTYPE LCType,
|
|
IN LPWSTR pData,
|
|
IN ULONG DataLength)
|
|
{
|
|
|
|
#if defined(BUILD_WOW6432)
|
|
|
|
return (NtWow64CsrBasepNlsSetUserInfo( LCType,
|
|
pData,
|
|
DataLength ));
|
|
|
|
#else
|
|
|
|
BASE_API_MSG m;
|
|
PBASE_NLS_SET_USER_INFO_MSG a = &m.u.NlsSetUserInfo;
|
|
PCSR_CAPTURE_HEADER CaptureBuffer = NULL;
|
|
|
|
//
|
|
// Get the capture buffer for the strings.
|
|
//
|
|
CaptureBuffer = CsrAllocateCaptureBuffer( 1, DataLength );
|
|
|
|
if (CaptureBuffer == NULL)
|
|
{
|
|
return (STATUS_NO_MEMORY);
|
|
}
|
|
|
|
if (CsrAllocateMessagePointer(CaptureBuffer, DataLength, (PVOID *)&(a->pData)) == 0)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
RtlCopyMemory (a->pData, pData, DataLength);
|
|
|
|
//
|
|
// Save the pointer to the cache string.
|
|
//
|
|
a->LCType = LCType;
|
|
|
|
//
|
|
// Save the length of the data in the msg structure.
|
|
//
|
|
a->DataLength = DataLength;
|
|
|
|
//
|
|
// Call the server to set the registry value.
|
|
//
|
|
CsrClientCallServer( (PCSR_API_MSG)&m,
|
|
CaptureBuffer,
|
|
CSR_MAKE_API_NUMBER( BASESRV_SERVERDLL_INDEX,
|
|
BasepNlsSetUserInfo ),
|
|
sizeof(*a) );
|
|
|
|
exit:
|
|
//
|
|
// Free the capture buffer.
|
|
//
|
|
if (CaptureBuffer != NULL)
|
|
{
|
|
CsrFreeCaptureBuffer(CaptureBuffer);
|
|
}
|
|
|
|
return (m.ReturnValue);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CsrBasepNlsGetUserInfo
|
|
//
|
|
// This function uses LPC to call into server side (csrss.exe) to retrieve
|
|
// the locale setting from the registry cache.
|
|
//
|
|
// Parameters
|
|
// Locale The locale to be retrived. Note that this could be different from
|
|
// the current user locale stored in the registry cache.
|
|
// If that's the case, this function will return FALSE.
|
|
// CacheOffset The offset in BYTE for the field in the NLS_USER_INFO cache to retrieve.
|
|
// FIELD_OFFSET(NLS_USER_INFO, fieldName) should be used to get the offset.
|
|
// pData The pointer which points to the target buffer
|
|
// DataLength The size of the target buffer in BYTE (the NULL terminator is included in the count)
|
|
//
|
|
// BIGNOTE BIGNOTE
|
|
// This function follows the convention of CsrBasepNlsSetUserInfo to use
|
|
// DataLength in BYTE.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
NTSTATUS CsrBasepNlsGetUserInfo(
|
|
IN LCID Locale,
|
|
IN SIZE_T CacheOffset,
|
|
IN LPWSTR pData,
|
|
IN ULONG DataLength)
|
|
{
|
|
|
|
#if defined(BUILD_WOW6432)
|
|
|
|
return (NtWow64CsrBasepNlsGetUserInfo( Locale, CacheOffset,
|
|
pData,
|
|
DataLength ));
|
|
|
|
#else
|
|
|
|
BASE_API_MSG m;
|
|
PBASE_NLS_GET_USER_INFO_MSG a = &m.u.NlsGetUserInfo;
|
|
PCSR_CAPTURE_HEADER CaptureBuffer = NULL;
|
|
NTSTATUS rc;
|
|
|
|
// Check the following:
|
|
// 1. Make sure that the CacheOffset can not be greater than the offset of the last field. The assumption here is that
|
|
// UserLocaleId the FIRST field after any field that contains strings.
|
|
// 2. Make sure that CacheOffset is always aligned in WCHAR and is aligned with the beginning of each field.
|
|
// 3. DataLength can not be greater than the maximum length in BYTE.
|
|
// 4. The pointer to the data is not NULL.
|
|
//
|
|
// There is a duplicated check in BaseSrvNlsGetUserInfo().
|
|
|
|
if ((CacheOffset > FIELD_OFFSET(NLS_USER_INFO, UserLocaleId) - sizeof(WCHAR) * MAX_REG_VAL_SIZE) ||
|
|
((CacheOffset % (sizeof(WCHAR) * MAX_REG_VAL_SIZE)) != 0) ||
|
|
(DataLength > MAX_REG_VAL_SIZE * sizeof(WCHAR)) ||
|
|
(pData == NULL))
|
|
{
|
|
return (STATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
//
|
|
// Get the capture buffer for the strings.
|
|
//
|
|
CaptureBuffer = CsrAllocateCaptureBuffer( 1, DataLength );
|
|
|
|
if (CaptureBuffer == NULL)
|
|
{
|
|
return (STATUS_NO_MEMORY);
|
|
}
|
|
|
|
CsrCaptureMessageBuffer( CaptureBuffer,
|
|
NULL,
|
|
DataLength,
|
|
(PVOID *)&a->pData );
|
|
|
|
a->Locale = Locale;
|
|
a->CacheOffset = CacheOffset;
|
|
|
|
//
|
|
// Save the length of the data in the msg structure.
|
|
//
|
|
a->DataLength = DataLength;
|
|
|
|
//
|
|
// Call the server to set the registry value.
|
|
//
|
|
rc = CsrClientCallServer( (PCSR_API_MSG)&m,
|
|
CaptureBuffer,
|
|
CSR_MAKE_API_NUMBER( BASESRV_SERVERDLL_INDEX,
|
|
BasepNlsGetUserInfo ),
|
|
sizeof(*a) );
|
|
|
|
if (NT_SUCCESS(rc))
|
|
{
|
|
// NOTE: DataLength is in BYTE.
|
|
wcsncpy(pData, a->pData, DataLength/sizeof(WCHAR));
|
|
}
|
|
//
|
|
// Free the capture buffer.
|
|
//
|
|
if (CaptureBuffer != NULL)
|
|
{
|
|
CsrFreeCaptureBuffer(CaptureBuffer);
|
|
}
|
|
|
|
return (rc);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CsrBasepNlsSetMultipleUserInfo
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
NTSTATUS CsrBasepNlsSetMultipleUserInfo(
|
|
IN DWORD dwFlags,
|
|
IN int cchData,
|
|
IN LPCWSTR pPicture,
|
|
IN LPCWSTR pSeparator,
|
|
IN LPCWSTR pOrder,
|
|
IN LPCWSTR pTLZero,
|
|
IN LPCWSTR pTimeMarkPosn)
|
|
{
|
|
|
|
#if defined(BUILD_WOW6432)
|
|
|
|
return (NtWow64CsrBasepNlsSetMultipleUserInfo( dwFlags,
|
|
cchData,
|
|
pPicture,
|
|
pSeparator,
|
|
pOrder,
|
|
pTLZero,
|
|
pTimeMarkPosn ));
|
|
|
|
#else
|
|
|
|
ULONG CaptureLength; // length of capture buffer
|
|
ULONG Length; // temp storage for length of string
|
|
|
|
BASE_API_MSG m;
|
|
PBASE_NLS_SET_MULTIPLE_USER_INFO_MSG a = &m.u.NlsSetMultipleUserInfo;
|
|
PCSR_CAPTURE_HEADER CaptureBuffer = NULL;
|
|
|
|
//
|
|
// Initialize the msg structure to NULL.
|
|
//
|
|
RtlZeroMemory(a, sizeof(BASE_NLS_SET_MULTIPLE_USER_INFO_MSG));
|
|
|
|
//
|
|
// Save the flags and the length of the data in the msg structure.
|
|
//
|
|
a->Flags = dwFlags;
|
|
a->DataLength = cchData * sizeof(WCHAR);
|
|
|
|
//
|
|
// Save the appropriate strings in the msg structure.
|
|
//
|
|
switch (dwFlags)
|
|
{
|
|
case ( LOCALE_STIMEFORMAT ) :
|
|
{
|
|
//
|
|
// Get the length of the capture buffer.
|
|
//
|
|
Length = wcslen(pSeparator) + 1;
|
|
CaptureLength = (cchData + Length + 2 + 2 + 2) * sizeof(WCHAR);
|
|
|
|
//
|
|
// Get the capture buffer for the strings.
|
|
//
|
|
CaptureBuffer = CsrAllocateCaptureBuffer( 5,
|
|
CaptureLength );
|
|
if (CaptureBuffer != NULL)
|
|
{
|
|
CsrCaptureMessageBuffer( CaptureBuffer,
|
|
(PCHAR)pPicture,
|
|
cchData * sizeof(WCHAR),
|
|
(PVOID *)&a->pPicture );
|
|
|
|
CsrCaptureMessageBuffer( CaptureBuffer,
|
|
(PCHAR)pSeparator,
|
|
Length * sizeof(WCHAR),
|
|
(PVOID *)&a->pSeparator );
|
|
|
|
CsrCaptureMessageBuffer( CaptureBuffer,
|
|
(PCHAR)pOrder,
|
|
2 * sizeof(WCHAR),
|
|
(PVOID *)&a->pOrder );
|
|
|
|
CsrCaptureMessageBuffer( CaptureBuffer,
|
|
(PCHAR)pTLZero,
|
|
2 * sizeof(WCHAR),
|
|
(PVOID *)&a->pTLZero );
|
|
|
|
CsrCaptureMessageBuffer( CaptureBuffer,
|
|
(PCHAR)pTimeMarkPosn,
|
|
2 * sizeof(WCHAR),
|
|
(PVOID *)&a->pTimeMarkPosn );
|
|
}
|
|
break;
|
|
}
|
|
case ( LOCALE_STIME ) :
|
|
{
|
|
//
|
|
// Get the length of the capture buffer.
|
|
//
|
|
Length = wcslen(pPicture) + 1;
|
|
CaptureLength = (Length + cchData) * sizeof(WCHAR);
|
|
|
|
//
|
|
// Get the capture buffer for the strings.
|
|
//
|
|
CaptureBuffer = CsrAllocateCaptureBuffer( 2,
|
|
CaptureLength );
|
|
if (CaptureBuffer != NULL)
|
|
{
|
|
CsrCaptureMessageBuffer( CaptureBuffer,
|
|
(PCHAR)pPicture,
|
|
Length * sizeof(WCHAR),
|
|
(PVOID *)&a->pPicture );
|
|
|
|
CsrCaptureMessageBuffer( CaptureBuffer,
|
|
(PCHAR)pSeparator,
|
|
cchData * sizeof(WCHAR),
|
|
(PVOID *)&a->pSeparator );
|
|
}
|
|
break;
|
|
}
|
|
case ( LOCALE_ITIME ) :
|
|
{
|
|
//
|
|
// Get the length of the capture buffer.
|
|
//
|
|
Length = wcslen(pPicture) + 1;
|
|
CaptureLength = (Length + cchData) * sizeof(WCHAR);
|
|
|
|
//
|
|
// Get the capture buffer for the strings.
|
|
//
|
|
CaptureBuffer = CsrAllocateCaptureBuffer( 2,
|
|
CaptureLength );
|
|
if (CaptureBuffer != NULL)
|
|
{
|
|
CsrCaptureMessageBuffer( CaptureBuffer,
|
|
(PCHAR)pPicture,
|
|
Length * sizeof(WCHAR),
|
|
(PVOID *)&a->pPicture );
|
|
|
|
CsrCaptureMessageBuffer( CaptureBuffer,
|
|
(PCHAR)pOrder,
|
|
cchData * sizeof(WCHAR),
|
|
(PVOID *)&a->pOrder );
|
|
}
|
|
break;
|
|
}
|
|
case ( LOCALE_SSHORTDATE ) :
|
|
{
|
|
//
|
|
// Get the length of the capture buffer.
|
|
//
|
|
Length = wcslen(pSeparator) + 1;
|
|
CaptureLength = (cchData + Length + 2) * sizeof(WCHAR);
|
|
|
|
//
|
|
// Get the capture buffer for the strings.
|
|
//
|
|
CaptureBuffer = CsrAllocateCaptureBuffer( 3,
|
|
CaptureLength );
|
|
if (CaptureBuffer != NULL)
|
|
{
|
|
CsrCaptureMessageBuffer( CaptureBuffer,
|
|
(PCHAR)pPicture,
|
|
cchData * sizeof(WCHAR),
|
|
(PVOID *)&a->pPicture );
|
|
|
|
CsrCaptureMessageBuffer( CaptureBuffer,
|
|
(PCHAR)pSeparator,
|
|
Length * sizeof(WCHAR),
|
|
(PVOID *)&a->pSeparator );
|
|
|
|
CsrCaptureMessageBuffer( CaptureBuffer,
|
|
(PCHAR)pOrder,
|
|
2 * sizeof(WCHAR),
|
|
(PVOID *)&a->pOrder );
|
|
}
|
|
break;
|
|
}
|
|
case ( LOCALE_SDATE ) :
|
|
{
|
|
//
|
|
// Get the length of the capture buffer.
|
|
//
|
|
Length = wcslen(pPicture) + 1;
|
|
CaptureLength = (Length + cchData) * sizeof(WCHAR);
|
|
|
|
//
|
|
// Get the capture buffer for the strings.
|
|
//
|
|
CaptureBuffer = CsrAllocateCaptureBuffer( 2,
|
|
CaptureLength );
|
|
if (CaptureBuffer != NULL)
|
|
{
|
|
CsrCaptureMessageBuffer( CaptureBuffer,
|
|
(PCHAR)pPicture,
|
|
Length * sizeof(WCHAR),
|
|
(PVOID *)&a->pPicture );
|
|
|
|
CsrCaptureMessageBuffer( CaptureBuffer,
|
|
(PCHAR)pSeparator,
|
|
cchData * sizeof(WCHAR),
|
|
(PVOID *)&a->pSeparator );
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Make sure the CaptureBuffer was created and filled in.
|
|
//
|
|
if (CaptureBuffer == NULL)
|
|
{
|
|
return (STATUS_NO_MEMORY);
|
|
}
|
|
|
|
//
|
|
// Call the server to set the registry values.
|
|
//
|
|
CsrClientCallServer( (PCSR_API_MSG)&m,
|
|
CaptureBuffer,
|
|
CSR_MAKE_API_NUMBER( BASESRV_SERVERDLL_INDEX,
|
|
BasepNlsSetMultipleUserInfo ),
|
|
sizeof(*a) );
|
|
|
|
//
|
|
// Free the capture buffer.
|
|
//
|
|
if (CaptureBuffer != NULL)
|
|
{
|
|
CsrFreeCaptureBuffer(CaptureBuffer);
|
|
}
|
|
|
|
return (m.ReturnValue);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CsrBasepNlsUpdateCacheCount
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
NTSTATUS CsrBasepNlsUpdateCacheCount()
|
|
{
|
|
|
|
#if defined(BUILD_WOW6432)
|
|
|
|
return (NtWow64CsrBasepNlsUpdateCacheCount());
|
|
|
|
#else
|
|
|
|
BASE_API_MSG m;
|
|
PBASE_NLS_UPDATE_CACHE_COUNT_MSG a = &m.u.NlsCacheUpdateCount;
|
|
|
|
a->Reserved = 0L;
|
|
|
|
CsrClientCallServer( (PCSR_API_MSG)&m,
|
|
NULL,
|
|
CSR_MAKE_API_NUMBER( BASESRV_SERVERDLL_INDEX,
|
|
BasepNlsUpdateCacheCount ),
|
|
sizeof(*a) );
|
|
|
|
return (m.ReturnValue);
|
|
|
|
#endif
|
|
|
|
}
|