server: Create the NLS section object for the l_intl.nls file.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-11-27 16:41:07 +01:00
parent 48c11f1e80
commit 8fa03e494a
7 changed files with 64 additions and 16 deletions

View File

@ -249,14 +249,12 @@ static void create_session( unsigned int id )
static const WCHAR dir_bnolinksW[] = {'B','N','O','L','I','N','K','S'};
static const WCHAR dir_bnoW[] = {'B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s'};
static const WCHAR dir_dosdevicesW[] = {'D','o','s','D','e','v','i','c','e','s'};
static const WCHAR dir_nlsW[] = {'N','L','S'};
static const WCHAR dir_windowsW[] = {'W','i','n','d','o','w','s'};
static const WCHAR dir_winstationsW[] = {'W','i','n','d','o','w','S','t','a','t','i','o','n','s'};
static const struct unicode_str dir_sessions_str = {dir_sessionsW, sizeof(dir_sessionsW)};
static const struct unicode_str dir_bnolinks_str = {dir_bnolinksW, sizeof(dir_bnolinksW)};
static const struct unicode_str dir_bno_str = {dir_bnoW, sizeof(dir_bnoW)};
static const struct unicode_str dir_dosdevices_str = {dir_dosdevicesW, sizeof(dir_dosdevicesW)};
static const struct unicode_str dir_nls_str = {dir_nlsW, sizeof(dir_nlsW)};
static const struct unicode_str dir_windows_str = {dir_windowsW, sizeof(dir_windowsW)};
static const struct unicode_str dir_winstations_str = {dir_winstationsW, sizeof(dir_winstationsW)};
@ -280,7 +278,6 @@ static void create_session( unsigned int id )
dir_bno_global = create_directory( &root_directory->obj, &dir_bno_str, OBJ_PERMANENT, HASH_SIZE, NULL );
dir_sessions = create_directory( &root_directory->obj, &dir_sessions_str, OBJ_PERMANENT, HASH_SIZE, NULL );
dir_bnolinks = create_directory( &dir_sessions->obj, &dir_bnolinks_str, OBJ_PERMANENT, HASH_SIZE, NULL );
release_object( create_directory( &root_directory->obj, &dir_nls_str, OBJ_PERMANENT, HASH_SIZE, NULL ));
release_object( dir_bno_global );
release_object( dir_bnolinks );
release_object( dir_sessions );
@ -326,7 +323,7 @@ static void create_session( unsigned int id )
free( id_strW );
}
void init_directories(void)
void init_directories( struct fd *intl_fd )
{
/* Directories */
static const WCHAR dir_globalW[] = {'?','?'};
@ -334,11 +331,13 @@ void init_directories(void)
static const WCHAR dir_deviceW[] = {'D','e','v','i','c','e'};
static const WCHAR dir_objtypeW[] = {'O','b','j','e','c','t','T','y','p','e','s'};
static const WCHAR dir_kernelW[] = {'K','e','r','n','e','l','O','b','j','e','c','t','s'};
static const WCHAR dir_nlsW[] = {'N','L','S'};
static const struct unicode_str dir_global_str = {dir_globalW, sizeof(dir_globalW)};
static const struct unicode_str dir_driver_str = {dir_driverW, sizeof(dir_driverW)};
static const struct unicode_str dir_device_str = {dir_deviceW, sizeof(dir_deviceW)};
static const struct unicode_str dir_objtype_str = {dir_objtypeW, sizeof(dir_objtypeW)};
static const struct unicode_str dir_kernel_str = {dir_kernelW, sizeof(dir_kernelW)};
static const struct unicode_str dir_nls_str = {dir_nlsW, sizeof(dir_nlsW)};
/* symlinks */
static const WCHAR link_dosdevW[] = {'D','o','s','D','e','v','i','c','e','s'};
@ -399,10 +398,12 @@ void init_directories(void)
static const struct unicode_str keyed_event_crit_sect_str = {keyed_event_crit_sectW, sizeof(keyed_event_crit_sectW)};
/* mappings */
static const WCHAR intlW[] = {'N','l','s','S','e','c','t','i','o','n','L','A','N','G','_','I','N','T','L'};
static const WCHAR user_dataW[] = {'_','_','w','i','n','e','_','u','s','e','r','_','s','h','a','r','e','d','_','d','a','t','a'};
static const struct unicode_str intl_str = {intlW, sizeof(intlW)};
static const struct unicode_str user_data_str = {user_dataW, sizeof(user_dataW)};
struct directory *dir_driver, *dir_device, *dir_global, *dir_kernel;
struct directory *dir_driver, *dir_device, *dir_global, *dir_kernel, *dir_nls;
struct object *named_pipe_device, *mailslot_device, *null_device;
unsigned int i;
@ -412,6 +413,7 @@ void init_directories(void)
dir_objtype = create_directory( &root_directory->obj, &dir_objtype_str, OBJ_PERMANENT, HASH_SIZE, NULL );
dir_kernel = create_directory( &root_directory->obj, &dir_kernel_str, OBJ_PERMANENT, HASH_SIZE, NULL );
dir_global = create_directory( &root_directory->obj, &dir_global_str, OBJ_PERMANENT, HASH_SIZE, NULL );
dir_nls = create_directory( &root_directory->obj, &dir_nls_str, OBJ_PERMANENT, HASH_SIZE, NULL );
/* devices */
named_pipe_device = create_named_pipe_device( &dir_device->obj, &named_pipe_str, OBJ_PERMANENT, NULL );
@ -439,7 +441,8 @@ void init_directories(void)
release_object( create_event( &dir_kernel->obj, &kernel_events[i], OBJ_PERMANENT, 1, 0, NULL ));
release_object( create_keyed_event( &dir_kernel->obj, &keyed_event_crit_sect_str, OBJ_PERMANENT, NULL ));
/* user data mapping */
/* mappings */
release_object( create_fd_mapping( &dir_nls->obj, &intl_str, intl_fd, OBJ_PERMANENT, NULL ));
release_object( create_user_data_mapping( &dir_kernel->obj, &user_data_str, OBJ_PERMANENT, NULL ));
release_object( named_pipe_device );
@ -450,6 +453,7 @@ void init_directories(void)
release_object( dir_device );
release_object( dir_objtype );
release_object( dir_kernel );
release_object( dir_nls );
release_object( dir_global );
}

View File

@ -171,6 +171,8 @@ extern struct file *get_mapping_file( struct process *process, client_ptr_t base
extern const pe_image_info_t *get_mapping_image_info( struct process *process, client_ptr_t base );
extern void free_mapped_views( struct process *process );
extern int get_page_size(void);
extern struct mapping *create_fd_mapping( struct object *root, const struct unicode_str *name, struct fd *fd,
unsigned int attr, const struct security_descriptor *sd );
extern struct object *create_user_data_mapping( struct object *root, const struct unicode_str *name,
unsigned int attr, const struct security_descriptor *sd );

View File

@ -144,8 +144,7 @@ int main( int argc, char *argv[] )
if (debug_level) fprintf( stderr, "wineserver: starting (pid=%ld)\n", (long) getpid() );
set_current_time();
init_signals();
load_intl_file();
init_directories();
init_directories( load_intl_file() );
init_registry();
main_loop();
return 0;

View File

@ -883,6 +883,41 @@ static struct mapping *create_mapping( struct object *root, const struct unicode
return NULL;
}
/* create a read-only file mapping for the specified fd */
struct mapping *create_fd_mapping( struct object *root, const struct unicode_str *name,
struct fd *fd, unsigned int attr, const struct security_descriptor *sd )
{
struct mapping *mapping;
int unix_fd;
struct stat st;
if (!(mapping = create_named_object( root, &mapping_ops, name, attr, sd ))) return NULL;
if (get_error() == STATUS_OBJECT_NAME_EXISTS) return mapping; /* Nothing else to do */
mapping->shared = NULL;
mapping->committed = NULL;
mapping->flags = SEC_FILE;
mapping->fd = (struct fd *)grab_object( fd );
set_fd_user( mapping->fd, &mapping_fd_ops, NULL );
if ((unix_fd = get_unix_fd( mapping->fd )) == -1) goto error;
if (fstat( unix_fd, &st ) == -1)
{
file_set_error();
goto error;
}
if (!(mapping->size = st.st_size))
{
set_error( STATUS_MAPPED_FILE_SIZE_ZERO );
goto error;
}
return mapping;
error:
release_object( mapping );
return NULL;
}
static struct mapping *get_mapping_obj( struct process *process, obj_handle_t handle, unsigned int access )
{
return (struct mapping *)get_handle_obj( process, handle, access, &mapping_ops );

View File

@ -244,7 +244,7 @@ extern struct object *get_root_directory(void);
extern struct object *get_directory_obj( struct process *process, obj_handle_t handle );
extern struct object_type *get_object_type( const struct unicode_str *name );
extern int directory_link_name( struct object *obj, struct object_name *name, struct object *parent );
extern void init_directories(void);
extern void init_directories( struct fd *intl_fd );
/* symbolic link functions */

View File

@ -23,9 +23,13 @@
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "windef.h"
#include "winternl.h"
#include "request.h"
#include "unicode.h"
#include "file.h"
/* number of following bytes in sequence based on first byte value (for bytes above 0x7f) */
static const char utf8_length[128] =
@ -257,13 +261,15 @@ static char *get_nls_dir(void)
}
/* load the case mapping table */
void load_intl_file(void)
struct fd *load_intl_file(void)
{
static const char *nls_dirs[] = { NULL, NLSDIR, "/usr/local/share/wine/nls", "/usr/share/wine/nls" };
unsigned int i, offset, size;
unsigned short data;
char *path;
int unix_fd = -1;
struct fd *fd = NULL;
int unix_fd;
mode_t mode = 0600;
nls_dirs[0] = get_nls_dir();
for (i = 0; i < ARRAY_SIZE( nls_dirs ); i++)
@ -272,10 +278,13 @@ void load_intl_file(void)
if (!(path = malloc( strlen(nls_dirs[i]) + sizeof("/l_intl.nls" )))) continue;
strcpy( path, nls_dirs[i] );
strcat( path, "/l_intl.nls" );
if ((unix_fd = open( path, O_RDONLY )) != -1) break;
if ((fd = open_fd( NULL, path, O_RDONLY, &mode, FILE_READ_DATA,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ))) break;
free( path );
}
if (unix_fd == -1) fatal_error( "failed to load l_intl.nls\n" );
if (!fd) fatal_error( "failed to load l_intl.nls\n" );
unix_fd = get_unix_fd( fd );
/* read initial offset */
if (pread( unix_fd, &data, sizeof(data), 0 ) != sizeof(data) || !data) goto failed;
offset = data;
@ -289,9 +298,8 @@ void load_intl_file(void)
/* read lowercase table */
if (!(casemap = malloc( size * 2 ))) goto failed;
if (pread( unix_fd, casemap, size * 2, offset * 2 ) != size * 2) goto failed;
close( unix_fd );
free( path );
return;
return fd;
failed:
fatal_error( "invalid format for casemap table %s\n", path );

View File

@ -31,6 +31,6 @@ extern unsigned int hash_strW( const WCHAR *str, data_size_t len, unsigned int h
extern WCHAR *ascii_to_unicode_str( const char *str, struct unicode_str *ret );
extern int parse_strW( WCHAR *buffer, data_size_t *len, const char *src, char endchar );
extern int dump_strW( const WCHAR *str, data_size_t len, FILE *f, const char escape[2] );
extern void load_intl_file(void);
extern struct fd *load_intl_file(void);
#endif /* __WINE_SERVER_UNICODE_H */