ntdll: Make NtGetNlsSectionPtr() into a proper Nt syscall.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
892780a5d2
commit
54c31d5332
|
@ -4131,7 +4131,7 @@ static void test_GetCPInfo(void)
|
|||
status = pNtGetNlsSectionPtr( i, 9999, NULL, &ptr, &size );
|
||||
switch (i)
|
||||
{
|
||||
case 9: /* unknown */
|
||||
case 9: /* sortkeys */
|
||||
case 13: /* unknown */
|
||||
ok( status == STATUS_INVALID_PARAMETER_1 || status == STATUS_INVALID_PARAMETER_3, /* vista */
|
||||
"%u: failed %x\n", i, status );
|
||||
|
@ -4160,9 +4160,9 @@ static void test_GetCPInfo(void)
|
|||
status = pNtGetNlsSectionPtr( 10, 0, NULL, &ptr2, &size );
|
||||
ok( ptr != ptr2, "got same pointer\n" );
|
||||
ret = UnmapViewOfFile( ptr );
|
||||
todo_wine ok( ret, "UnmapViewOfFile failed err %u\n", GetLastError() );
|
||||
ok( ret, "UnmapViewOfFile failed err %u\n", GetLastError() );
|
||||
ret = UnmapViewOfFile( ptr2 );
|
||||
todo_wine ok( ret, "UnmapViewOfFile failed err %u\n", GetLastError() );
|
||||
ok( ret, "UnmapViewOfFile failed err %u\n", GetLastError() );
|
||||
}
|
||||
|
||||
/* codepage tables */
|
||||
|
@ -4182,7 +4182,7 @@ static void test_GetCPInfo(void)
|
|||
ok( !table.DBCSCodePage, "wrong dbcs %u\n", table.DBCSCodePage );
|
||||
}
|
||||
ret = UnmapViewOfFile( ptr );
|
||||
todo_wine ok( ret, "UnmapViewOfFile failed err %u\n", GetLastError() );
|
||||
ok( ret, "UnmapViewOfFile failed err %u\n", GetLastError() );
|
||||
|
||||
status = pNtGetNlsSectionPtr( 11, 936, NULL, &ptr, &size );
|
||||
ok( !status, "failed %x\n", status );
|
||||
|
@ -4220,7 +4220,7 @@ static void test_GetCPInfo(void)
|
|||
}
|
||||
}
|
||||
ret = UnmapViewOfFile( ptr );
|
||||
todo_wine ok( ret, "UnmapViewOfFile failed err %u\n", GetLastError() );
|
||||
ok( ret, "UnmapViewOfFile failed err %u\n", GetLastError() );
|
||||
|
||||
/* normalization tables */
|
||||
|
||||
|
@ -4238,7 +4238,7 @@ static void test_GetCPInfo(void)
|
|||
if (status) break;
|
||||
ok( size > 0x8000 && size <= 0x30000 , "wrong size %lx\n", size );
|
||||
ret = UnmapViewOfFile( ptr );
|
||||
todo_wine ok( ret, "UnmapViewOfFile failed err %u\n", GetLastError() );
|
||||
ok( ret, "UnmapViewOfFile failed err %u\n", GetLastError() );
|
||||
break;
|
||||
default:
|
||||
ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "%u: failed %x\n", i, status );
|
||||
|
|
|
@ -228,13 +228,13 @@ static NTSTATUS load_norm_table( ULONG form, const struct norm_table **info )
|
|||
}
|
||||
|
||||
if (InterlockedCompareExchangePointer( (void **)&norm_tables[form], data, NULL ))
|
||||
RtlFreeHeap( GetProcessHeap(), 0, data );
|
||||
NtUnmapViewOfSection( GetCurrentProcess(), data );
|
||||
}
|
||||
*info = norm_tables[form];
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
invalid:
|
||||
RtlFreeHeap( GetProcessHeap(), 0, data );
|
||||
NtUnmapViewOfSection( GetCurrentProcess(), data );
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
@ -534,156 +534,6 @@ static unsigned int compose_string( const struct norm_table *info, WCHAR *str, u
|
|||
}
|
||||
|
||||
|
||||
static NTSTATUS open_nls_data_file( ULONG type, ULONG id, HANDLE *file )
|
||||
{
|
||||
static const WCHAR pathfmtW[] = {'\\','?','?','\\','%','s','%','s',0};
|
||||
static const WCHAR keyfmtW[] =
|
||||
{'\\','R','e','g','i','s','t','r','y','\\','M','a','c','h','i','n','e','\\','S','y','s','t','e','m','\\',
|
||||
'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
|
||||
'C','o','n','t','r','o','l','\\','N','l','s','\\','%','s',0};
|
||||
static const WCHAR sortdirW[] = {'C',':','\\','w','i','n','d','o','w','s','\\',
|
||||
'g','l','o','b','a','l','i','z','a','t','i','o','n','\\',
|
||||
's','o','r','t','i','n','g','\\',0};
|
||||
static const WCHAR cpW[] = {'C','o','d','e','p','a','g','e',0};
|
||||
static const WCHAR normW[] = {'N','o','r','m','a','l','i','z','a','t','i','o','n',0};
|
||||
static const WCHAR langW[] = {'L','a','n','g','u','a','g','e',0};
|
||||
static const WCHAR cpfmtW[] = {'%','u',0};
|
||||
static const WCHAR normfmtW[] = {'%','x',0};
|
||||
static const WCHAR langfmtW[] = {'%','0','4','x',0};
|
||||
static const WCHAR winedatadirW[] = {'W','I','N','E','D','A','T','A','D','I','R',0};
|
||||
static const WCHAR winebuilddirW[] = {'W','I','N','E','B','U','I','L','D','D','I','R',0};
|
||||
static const WCHAR dataprefixW[] = {'\\','n','l','s','\\',0};
|
||||
static const WCHAR cpdefaultW[] = {'c','_','%','0','3','d','.','n','l','s',0};
|
||||
static const WCHAR intlW[] = {'l','_','i','n','t','l','.','n','l','s',0};
|
||||
static const WCHAR normnfcW[] = {'n','o','r','m','n','f','c','.','n','l','s',0};
|
||||
static const WCHAR normnfdW[] = {'n','o','r','m','n','f','d','.','n','l','s',0};
|
||||
static const WCHAR normnfkcW[] = {'n','o','r','m','n','f','k','c','.','n','l','s',0};
|
||||
static const WCHAR normnfkdW[] = {'n','o','r','m','n','f','k','d','.','n','l','s',0};
|
||||
static const WCHAR normidnaW[] = {'n','o','r','m','i','d','n','a','.','n','l','s',0};
|
||||
static const WCHAR sortkeysW[] = {'s','o','r','t','d','e','f','a','u','l','t','.','n','l','s',0};
|
||||
|
||||
DWORD size;
|
||||
HANDLE handle;
|
||||
NTSTATUS status = STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
IO_STATUS_BLOCK io;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING nameW, valueW;
|
||||
WCHAR buffer[MAX_PATH], value[10];
|
||||
const WCHAR *name = NULL, *dir = system_dir;
|
||||
KEY_VALUE_PARTIAL_INFORMATION *info;
|
||||
|
||||
/* get filename from registry */
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case NLS_SECTION_SORTKEYS:
|
||||
if (id) return STATUS_INVALID_PARAMETER_1;
|
||||
buffer[0] = 0;
|
||||
break;
|
||||
case NLS_SECTION_CASEMAP:
|
||||
if (id) return STATUS_UNSUCCESSFUL;
|
||||
swprintf( buffer, ARRAY_SIZE(buffer), keyfmtW, langW );
|
||||
swprintf( value, ARRAY_SIZE(value), langfmtW, LANGIDFROMLCID(system_lcid) );
|
||||
break;
|
||||
case NLS_SECTION_CODEPAGE:
|
||||
swprintf( buffer, ARRAY_SIZE(buffer), keyfmtW, cpW );
|
||||
swprintf( value, ARRAY_SIZE(value), cpfmtW, id );
|
||||
break;
|
||||
case NLS_SECTION_NORMALIZE:
|
||||
swprintf( buffer, ARRAY_SIZE(buffer), keyfmtW, normW );
|
||||
swprintf( value, ARRAY_SIZE(value), normfmtW, id );
|
||||
break;
|
||||
default:
|
||||
return STATUS_INVALID_PARAMETER_1;
|
||||
}
|
||||
|
||||
if (buffer[0])
|
||||
{
|
||||
RtlInitUnicodeString( &nameW, buffer );
|
||||
RtlInitUnicodeString( &valueW, value );
|
||||
InitializeObjectAttributes( &attr, &nameW, 0, 0, NULL );
|
||||
if (!(status = NtOpenKey( &handle, KEY_READ, &attr )))
|
||||
{
|
||||
info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer;
|
||||
size = sizeof(buffer) - sizeof(WCHAR);
|
||||
if (!(status = NtQueryValueKey( handle, &valueW, KeyValuePartialInformation, info, size, &size )))
|
||||
{
|
||||
((WCHAR *)info->Data)[info->DataLength / sizeof(WCHAR)] = 0;
|
||||
name = (WCHAR *)info->Data;
|
||||
}
|
||||
NtClose( handle );
|
||||
}
|
||||
}
|
||||
|
||||
if (!name || !*name) /* otherwise some hardcoded defaults */
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case NLS_SECTION_SORTKEYS:
|
||||
name = sortkeysW;
|
||||
dir = sortdirW;
|
||||
break;
|
||||
case NLS_SECTION_CASEMAP:
|
||||
name = intlW;
|
||||
break;
|
||||
case NLS_SECTION_CODEPAGE:
|
||||
swprintf( buffer, ARRAY_SIZE(buffer), cpdefaultW, id );
|
||||
name = buffer;
|
||||
break;
|
||||
case NLS_SECTION_NORMALIZE:
|
||||
switch (id)
|
||||
{
|
||||
case NormalizationC: name = normnfcW; break;
|
||||
case NormalizationD: name = normnfdW; break;
|
||||
case NormalizationKC: name = normnfkcW; break;
|
||||
case NormalizationKD: name = normnfkdW; break;
|
||||
case 13: name = normidnaW; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!name) return status;
|
||||
}
|
||||
|
||||
/* try to open file in system dir */
|
||||
|
||||
valueW.MaximumLength = (wcslen(name) + wcslen(dir) + 5) * sizeof(WCHAR);
|
||||
if (!(valueW.Buffer = RtlAllocateHeap( GetProcessHeap(), 0, valueW.MaximumLength )))
|
||||
return STATUS_NO_MEMORY;
|
||||
valueW.Length = swprintf( valueW.Buffer, valueW.MaximumLength/sizeof(WCHAR),
|
||||
pathfmtW, dir, name ) * sizeof(WCHAR);
|
||||
InitializeObjectAttributes( &attr, &valueW, 0, 0, NULL );
|
||||
status = NtOpenFile( file, GENERIC_READ, &attr, &io, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT );
|
||||
if (!status) TRACE( "found %s\n", debugstr_w( valueW.Buffer ));
|
||||
RtlFreeUnicodeString( &valueW );
|
||||
if (status != STATUS_OBJECT_NAME_NOT_FOUND && status != STATUS_OBJECT_PATH_NOT_FOUND) return status;
|
||||
|
||||
/* not found, try in build or data dir */
|
||||
|
||||
RtlInitUnicodeString( &nameW, winebuilddirW );
|
||||
valueW.MaximumLength = 0;
|
||||
if (RtlQueryEnvironmentVariable_U( NULL, &nameW, &valueW ) != STATUS_BUFFER_TOO_SMALL)
|
||||
{
|
||||
RtlInitUnicodeString( &nameW, winedatadirW );
|
||||
if (RtlQueryEnvironmentVariable_U( NULL, &nameW, &valueW ) != STATUS_BUFFER_TOO_SMALL)
|
||||
return status;
|
||||
}
|
||||
valueW.MaximumLength = valueW.Length + sizeof(dataprefixW) + wcslen(name) * sizeof(WCHAR);
|
||||
if (!(valueW.Buffer = RtlAllocateHeap( GetProcessHeap(), 0, valueW.MaximumLength )))
|
||||
return STATUS_NO_MEMORY;
|
||||
if (!RtlQueryEnvironmentVariable_U( NULL, &nameW, &valueW ))
|
||||
{
|
||||
wcscat( valueW.Buffer, dataprefixW );
|
||||
wcscat( valueW.Buffer, name );
|
||||
valueW.Length = wcslen(valueW.Buffer) * sizeof(WCHAR);
|
||||
InitializeObjectAttributes( &attr, &valueW, 0, 0, NULL );
|
||||
status = NtOpenFile( file, GENERIC_READ, &attr, &io, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT );
|
||||
if (!status) TRACE( "found %s\n", debugstr_w( valueW.Buffer ));
|
||||
}
|
||||
RtlFreeUnicodeString( &valueW );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
void init_unix_codepage(void)
|
||||
{
|
||||
USHORT *data = unix_funcs->get_unix_codepage_data();
|
||||
|
@ -925,36 +775,6 @@ NTSTATUS WINAPI RtlSetThreadPreferredUILanguages( DWORD flags, PCZZWSTR buffer,
|
|||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* NtGetNlsSectionPtr (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtGetNlsSectionPtr( ULONG type, ULONG id, void *unknown, void **ptr, SIZE_T *size )
|
||||
{
|
||||
FILE_END_OF_FILE_INFORMATION info;
|
||||
IO_STATUS_BLOCK io;
|
||||
HANDLE file;
|
||||
NTSTATUS status;
|
||||
|
||||
if ((status = open_nls_data_file( type, id, &file ))) return status;
|
||||
|
||||
if ((status = NtQueryInformationFile( file, &io, &info, sizeof(info), FileEndOfFileInformation )))
|
||||
goto done;
|
||||
/* FIXME: return a heap block instead of a file mapping for now */
|
||||
if (!(*ptr = RtlAllocateHeap( GetProcessHeap(), 0, info.EndOfFile.QuadPart )))
|
||||
{
|
||||
status = STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
status = NtReadFile( file, 0, NULL, NULL, &io, *ptr, info.EndOfFile.QuadPart, NULL, NULL );
|
||||
if (!status && io.Information != info.EndOfFile.QuadPart) status = STATUS_INVALID_FILE_FOR_SECTION;
|
||||
if (!status) *size = io.Information;
|
||||
else RtlFreeHeap( GetProcessHeap(), 0, *ptr );
|
||||
done:
|
||||
NtClose( file );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* RtlInitCodePageTable (NTDLL.@)
|
||||
*/
|
||||
|
|
|
@ -222,7 +222,7 @@
|
|||
@ stdcall -norelay -syscall NtGetContextThread(long ptr)
|
||||
@ stdcall -syscall NtGetCurrentProcessorNumber()
|
||||
# @ stub NtGetDevicePowerState
|
||||
@ stdcall NtGetNlsSectionPtr(long long long ptr ptr)
|
||||
@ stdcall -syscall NtGetNlsSectionPtr(long long long ptr ptr)
|
||||
@ stub NtGetPlugPlayEvent
|
||||
@ stdcall NtGetTickCount()
|
||||
@ stdcall -syscall NtGetWriteWatch(long long ptr long ptr ptr ptr)
|
||||
|
@ -1226,7 +1226,7 @@
|
|||
@ stdcall -private -norelay -syscall ZwGetContextThread(long ptr) NtGetContextThread
|
||||
@ stdcall -private -syscall ZwGetCurrentProcessorNumber() NtGetCurrentProcessorNumber
|
||||
# @ stub ZwGetDevicePowerState
|
||||
@ stdcall -private ZwGetNlsSectionPtr(long long long ptr ptr) NtGetNlsSectionPtr
|
||||
@ stdcall -private -syscall ZwGetNlsSectionPtr(long long long ptr ptr) NtGetNlsSectionPtr
|
||||
@ stub ZwGetPlugPlayEvent
|
||||
@ stdcall -private ZwGetTickCount() NtGetTickCount
|
||||
@ stdcall -private -syscall ZwGetWriteWatch(long long ptr long ptr ptr ptr) NtGetWriteWatch
|
||||
|
|
|
@ -84,16 +84,49 @@ static struct
|
|||
void *wctable;
|
||||
} unix_cp;
|
||||
|
||||
static void *read_nls_file( const char *name )
|
||||
enum nls_section_type
|
||||
{
|
||||
NLS_SECTION_SORTKEYS = 9,
|
||||
NLS_SECTION_CASEMAP = 10,
|
||||
NLS_SECTION_CODEPAGE = 11,
|
||||
NLS_SECTION_NORMALIZE = 12
|
||||
};
|
||||
|
||||
static char *get_nls_file_path( ULONG type, ULONG id )
|
||||
{
|
||||
const char *dir = build_dir ? build_dir : data_dir;
|
||||
const char *name = NULL;
|
||||
char *path, tmp[16];
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case NLS_SECTION_SORTKEYS: name = "sortdefault"; break;
|
||||
case NLS_SECTION_CASEMAP: name = "l_intl"; break;
|
||||
case NLS_SECTION_CODEPAGE: name = tmp; sprintf( tmp, "c_%03u", id ); break;
|
||||
case NLS_SECTION_NORMALIZE:
|
||||
switch (id)
|
||||
{
|
||||
case NormalizationC: name = "normnfc"; break;
|
||||
case NormalizationD: name = "normnfd"; break;
|
||||
case NormalizationKC: name = "normnfkc"; break;
|
||||
case NormalizationKD: name = "normnfkd"; break;
|
||||
case 13: name = "normidna"; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!name) return NULL;
|
||||
if (!(path = malloc( strlen(dir) + strlen(name) + 10 ))) return NULL;
|
||||
sprintf( path, "%s/nls/%s.nls", dir, name );
|
||||
return path;
|
||||
}
|
||||
|
||||
static void *read_nls_file( ULONG type, ULONG id )
|
||||
{
|
||||
char *path = get_nls_file_path( type, id );
|
||||
struct stat st;
|
||||
char *path;
|
||||
void *data, *ret = NULL;
|
||||
int fd;
|
||||
|
||||
if (!(path = malloc( strlen(dir) + 22 ))) return NULL;
|
||||
sprintf( path, "%s/nls/%s.nls", dir, name );
|
||||
if ((fd = open( path, O_RDONLY )) != -1)
|
||||
{
|
||||
fstat( fd, &st );
|
||||
|
@ -109,11 +142,73 @@ static void *read_nls_file( const char *name )
|
|||
}
|
||||
close( fd );
|
||||
}
|
||||
else ERR( "failed to load %s\n", path );
|
||||
else ERR( "failed to load %u/%u\n", type, id );
|
||||
free( path );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static NTSTATUS open_nls_data_file( ULONG type, ULONG id, HANDLE *file )
|
||||
{
|
||||
static const WCHAR systemdirW[] = {'\\','?','?','\\','C',':','\\','w','i','n','d','o','w','s','\\',
|
||||
's','y','s','t','e','m','3','2','\\',0};
|
||||
static const WCHAR sortdirW[] = {'\\','?','?','\\','C',':','\\','w','i','n','d','o','w','s','\\',
|
||||
'g','l','o','b','a','l','i','z','a','t','i','o','n','\\',
|
||||
's','o','r','t','i','n','g','\\',0};
|
||||
|
||||
NTSTATUS status = STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
IO_STATUS_BLOCK io;
|
||||
OBJECT_ATTRIBUTES attr = { sizeof(attr) };
|
||||
UNICODE_STRING valueW;
|
||||
WCHAR buffer[ARRAY_SIZE(sortdirW) + 16];
|
||||
char *p, *path = get_nls_file_path( type, id );
|
||||
|
||||
if (!path) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
status = open_unix_file( file, path, GENERIC_READ, &attr, 0, FILE_SHARE_READ,
|
||||
FILE_OPEN, FILE_SYNCHRONOUS_IO_ALERT, NULL, 0 );
|
||||
if (status == STATUS_NO_SUCH_FILE)
|
||||
{
|
||||
/* try to open file in system dir */
|
||||
ntdll_wcscpy( buffer, type == NLS_SECTION_SORTKEYS ? sortdirW : systemdirW );
|
||||
p = strrchr( path, '/' ) + 1;
|
||||
ascii_to_unicode( buffer + ntdll_wcslen(buffer), p, strlen(p) + 1 );
|
||||
valueW.Buffer = buffer;
|
||||
valueW.Length = ntdll_wcslen( buffer ) * sizeof(WCHAR);
|
||||
valueW.MaximumLength = sizeof( buffer );
|
||||
InitializeObjectAttributes( &attr, &valueW, 0, 0, NULL );
|
||||
status = NtOpenFile( file, GENERIC_READ, &attr, &io, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT );
|
||||
}
|
||||
free( path );
|
||||
return status;
|
||||
}
|
||||
|
||||
static NTSTATUS get_nls_section_name( ULONG type, ULONG id, WCHAR name[32] )
|
||||
{
|
||||
char buffer[32];
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case NLS_SECTION_SORTKEYS:
|
||||
if (id) return STATUS_INVALID_PARAMETER_1;
|
||||
strcpy( buffer, "\\NLS\\NlsSectionSORTDEFAULT" );
|
||||
break;
|
||||
case NLS_SECTION_CASEMAP:
|
||||
if (id) return STATUS_UNSUCCESSFUL;
|
||||
strcpy( buffer, "\\NLS\\NlsSectionLANG_INTL" );
|
||||
break;
|
||||
case NLS_SECTION_CODEPAGE:
|
||||
sprintf( buffer, "\\NLS\\NlsSectionCP%03u", id);
|
||||
break;
|
||||
case NLS_SECTION_NORMALIZE:
|
||||
sprintf( buffer, "\\NLS\\NlsSectionNORM%08x", id);
|
||||
break;
|
||||
default:
|
||||
return STATUS_INVALID_PARAMETER_1;
|
||||
}
|
||||
ascii_to_unicode( name, buffer, strlen(buffer) + 1 );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int get_utf16( const WCHAR *src, unsigned int srclen, unsigned int *ch )
|
||||
{
|
||||
|
@ -167,7 +262,7 @@ static struct norm_table *nfc_table;
|
|||
|
||||
static void init_unix_codepage(void)
|
||||
{
|
||||
nfc_table = read_nls_file( "normnfc" );
|
||||
nfc_table = read_nls_file( NLS_SECTION_NORMALIZE, NormalizationC );
|
||||
}
|
||||
|
||||
static void put_utf16( WCHAR *dst, unsigned int ch )
|
||||
|
@ -398,11 +493,8 @@ static void init_unix_codepage(void)
|
|||
{
|
||||
if (charset_names[pos].cp != CP_UTF8)
|
||||
{
|
||||
char name[16];
|
||||
void *data;
|
||||
|
||||
sprintf( name, "c_%03u", charset_names[pos].cp );
|
||||
if ((data = read_nls_file( name ))) init_unix_cptable( data );
|
||||
void *data = read_nls_file( NLS_SECTION_CODEPAGE, charset_names[pos].cp );
|
||||
if (data) init_unix_cptable( data );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -958,7 +1050,7 @@ void init_environment( int argc, char *argv[], char *envp[] )
|
|||
init_unix_codepage();
|
||||
init_locale();
|
||||
|
||||
if ((case_table = read_nls_file( "l_intl" )))
|
||||
if ((case_table = read_nls_file( NLS_SECTION_CASEMAP, 0 )))
|
||||
{
|
||||
uctable = case_table + 2;
|
||||
lctable = case_table + case_table[1] + 2;
|
||||
|
@ -1283,6 +1375,43 @@ void CDECL get_locales( WCHAR *sys, WCHAR *user )
|
|||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* NtGetNlsSectionPtr (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtGetNlsSectionPtr( ULONG type, ULONG id, void *unknown, void **ptr, SIZE_T *size )
|
||||
{
|
||||
UNICODE_STRING nameW;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
WCHAR name[32];
|
||||
HANDLE handle, file;
|
||||
NTSTATUS status;
|
||||
|
||||
if ((status = get_nls_section_name( type, id, name ))) return status;
|
||||
|
||||
nameW.Buffer = name;
|
||||
nameW.Length = ntdll_wcslen(name) * sizeof(WCHAR);
|
||||
nameW.MaximumLength = sizeof(name);
|
||||
InitializeObjectAttributes( &attr, &nameW, 0, 0, NULL );
|
||||
if ((status = NtOpenSection( &handle, SECTION_MAP_READ, &attr )))
|
||||
{
|
||||
if ((status = open_nls_data_file( type, id, &file ))) return status;
|
||||
attr.Attributes = OBJ_OPENIF | OBJ_PERMANENT;
|
||||
status = NtCreateSection( &handle, SECTION_MAP_READ, &attr, NULL, PAGE_READONLY, SEC_COMMIT, file );
|
||||
NtClose( file );
|
||||
if (status == STATUS_OBJECT_NAME_EXISTS) status = STATUS_SUCCESS;
|
||||
}
|
||||
if (!status)
|
||||
{
|
||||
*ptr = NULL;
|
||||
*size = 0;
|
||||
status = NtMapViewOfSection( handle, GetCurrentProcess(), ptr, 0, 0, NULL, size,
|
||||
ViewShare, 0, PAGE_READONLY );
|
||||
}
|
||||
NtClose( handle );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* NtQueryDefaultLocale (NTDLL.@)
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue