Alexandre Julliard : ntdll: Implement NtInitializeNlsFiles().

Alexandre Julliard julliard at winehq.org
Mon Mar 21 17:20:25 CDT 2022


Module: wine
Branch: master
Commit: 5ed078dc14c7c40815c3f65a8718207d861d0320
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=5ed078dc14c7c40815c3f65a8718207d861d0320

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Mar 21 11:51:13 2022 +0100

ntdll: Implement NtInitializeNlsFiles().

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/ntdll.spec    |  2 ++
 dlls/ntdll/unix/env.c    | 63 +++++++++++++++++++++++++++++++++++-------------
 dlls/ntdll/unix/loader.c |  3 ++-
 include/winternl.h       |  1 +
 4 files changed, 51 insertions(+), 18 deletions(-)

diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index d514bca5e11..6d134770596 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -235,6 +235,7 @@
 @ stdcall -syscall NtImpersonateAnonymousToken(long)
 # @ stub NtImpersonateClientOfPort
 # @ stub NtImpersonateThread
+@ stdcall -syscall NtInitializeNlsFiles(ptr ptr ptr)
 # @ stub NtInitializeRegistry
 @ stdcall -syscall NtInitiatePowerAction (long long long long)
 @ stdcall -syscall NtIsProcessInJob(long long)
@@ -1257,6 +1258,7 @@
 @ stdcall -private -syscall ZwImpersonateAnonymousToken(long) NtImpersonateAnonymousToken
 # @ stub ZwImpersonateClientOfPort
 # @ stub ZwImpersonateThread
+@ stdcall -private -syscall ZwInitializeNlsFiles(ptr ptr ptr) NtInitializeNlsFiles
 # @ stub ZwInitializeRegistry
 @ stdcall -private -syscall ZwInitiatePowerAction(long long long long) NtInitiatePowerAction
 @ stdcall -private -syscall ZwIsProcessInJob(long long) NtIsProcessInJob
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c
index 227bcdbfa0f..2302ee46e86 100644
--- a/dlls/ntdll/unix/env.c
+++ b/dlls/ntdll/unix/env.c
@@ -153,22 +153,15 @@ static void *read_nls_file( ULONG type, ULONG id )
     return ret;
 }
 
-static NTSTATUS open_nls_data_file( ULONG type, ULONG id, HANDLE *file )
+static NTSTATUS open_nls_data_file( const char *path, const WCHAR *sysdir, HANDLE *file )
 {
-    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;
     OBJECT_ATTRIBUTES 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;
+    WCHAR buffer[64];
+    char *p, *ntpath;
 
-    /* try to open file in system dir */
-    wcscpy( buffer, type == NLS_SECTION_SORTKEYS ? sortdirW : system_dir );
+    wcscpy( buffer, system_dir );
     p = strrchr( path, '/' ) + 1;
     ascii_to_unicode( buffer + wcslen(buffer), p, strlen(p) + 1 );
     init_unicode_string( &valueW, buffer );
@@ -176,13 +169,12 @@ static NTSTATUS open_nls_data_file( ULONG type, ULONG id, HANDLE *file )
 
     status = open_unix_file( file, path, GENERIC_READ, &attr, 0, FILE_SHARE_READ,
                              FILE_OPEN, FILE_SYNCHRONOUS_IO_ALERT, NULL, 0 );
-    free( path );
     if (status != STATUS_NO_SUCH_FILE) return status;
 
-    if ((status = nt_to_unix_file_name( &attr, &path, FILE_OPEN ))) return status;
-    status = open_unix_file( file, path, GENERIC_READ, &attr, 0, FILE_SHARE_READ,
+    if ((status = nt_to_unix_file_name( &attr, &ntpath, FILE_OPEN ))) return status;
+    status = open_unix_file( file, ntpath, GENERIC_READ, &attr, 0, FILE_SHARE_READ,
                              FILE_OPEN, FILE_SYNCHRONOUS_IO_ALERT, NULL, 0 );
-    free( path );
+    free( ntpath );
     return status;
 }
 
@@ -2438,6 +2430,9 @@ void *create_startup_info( const UNICODE_STRING *nt_image, const RTL_USER_PROCES
  */
 NTSTATUS WINAPI NtGetNlsSectionPtr( ULONG type, ULONG id, void *unknown, void **ptr, SIZE_T *size )
 {
+    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};
     UNICODE_STRING nameW;
     OBJECT_ATTRIBUTES attr;
     WCHAR name[32];
@@ -2450,7 +2445,12 @@ NTSTATUS WINAPI NtGetNlsSectionPtr( ULONG type, ULONG id, void *unknown, void **
     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;
+        char *path = get_nls_file_path( type, id );
+
+        if (!path) return STATUS_OBJECT_NAME_NOT_FOUND;
+        status = open_nls_data_file( path, type == NLS_SECTION_SORTKEYS ? sortdirW : system_dir, &file );
+        free( path );
+        if (status) return status;
         attr.Attributes = OBJ_OPENIF | OBJ_PERMANENT;
         status = NtCreateSection( &handle, SECTION_MAP_READ, &attr, NULL, PAGE_READONLY, SEC_COMMIT, file );
         NtClose( file );
@@ -2461,8 +2461,37 @@ NTSTATUS WINAPI NtGetNlsSectionPtr( ULONG type, ULONG id, void *unknown, void **
         status = map_section( handle, ptr, size, PAGE_READONLY );
         NtClose( handle );
     }
+    return status;
+}
+
+
+/**************************************************************************
+ *      NtInitializeNlsFiles  (NTDLL.@)
+ */
+NTSTATUS WINAPI NtInitializeNlsFiles( void **ptr, LCID *lcid, LARGE_INTEGER *size )
+{
+    const char *dir = build_dir ? build_dir : data_dir;
+    char *path;
+    HANDLE handle, file;
+    SIZE_T mapsize;
+    NTSTATUS status;
+
+    if (!(path = malloc( strlen(dir) + sizeof("/nls/locale.nls") ))) return STATUS_NO_MEMORY;
+    strcpy( path, dir );
+    strcat( path, "/nls/locale.nls" );
+    status = open_nls_data_file( path, system_dir, &file );
+    free( path );
+    if (!status)
+    {
+        status = NtCreateSection( &handle, SECTION_MAP_READ, NULL, NULL, PAGE_READONLY, SEC_COMMIT, file );
+        NtClose( file );
+    }
+    if (!status)
+    {
+        status = map_section( handle, ptr, &mapsize, PAGE_READONLY );
+        NtClose( handle );
     }
-    NtClose( handle );
+    *lcid = system_lcid;
     return status;
 }
 
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
index 97fb624d6d2..d1c42ddc0f3 100644
--- a/dlls/ntdll/unix/loader.c
+++ b/dlls/ntdll/unix/loader.c
@@ -196,7 +196,8 @@ static void * const syscalls[] =
     NtGetNlsSectionPtr,
     NtGetWriteWatch,
     NtImpersonateAnonymousToken,
-    NtInitiatePowerAction ,
+    NtInitializeNlsFiles,
+    NtInitiatePowerAction,
     NtIsProcessInJob,
     NtListenPort,
     NtLoadDriver,
diff --git a/include/winternl.h b/include/winternl.h
index 4c49f5eae47..68c174d6086 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -3995,6 +3995,7 @@ NTSYSAPI NTSTATUS  WINAPI NtGetWriteWatch(HANDLE,ULONG,PVOID,SIZE_T,PVOID*,ULONG
 NTSYSAPI NTSTATUS  WINAPI NtImpersonateAnonymousToken(HANDLE);
 NTSYSAPI NTSTATUS  WINAPI NtImpersonateClientOfPort(HANDLE,PPORT_MESSAGE);
 NTSYSAPI NTSTATUS  WINAPI NtImpersonateThread(HANDLE,HANDLE,PSECURITY_QUALITY_OF_SERVICE);
+NTSYSAPI NTSTATUS  WINAPI NtInitializeNlsFiles(void**,LCID*,LARGE_INTEGER*);
 NTSYSAPI NTSTATUS  WINAPI NtInitializeRegistry(BOOLEAN);
 NTSYSAPI NTSTATUS  WINAPI NtInitiatePowerAction(POWER_ACTION,SYSTEM_POWER_STATE,ULONG,BOOLEAN);
 NTSYSAPI NTSTATUS  WINAPI NtIsProcessInJob(HANDLE,HANDLE);




More information about the wine-cvs mailing list