/*++ 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 }