~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/ntdll/resource.c

Version: ~ [ wine-1.5.30 ] ~ [ wine-1.5.29 ] ~ [ wine-1.5.28 ] ~ [ wine-1.5.27 ] ~ [ wine-1.5.26 ] ~ [ wine-1.5.25 ] ~ [ wine-1.5.24 ] ~ [ wine-1.5.23 ] ~ [ wine-1.5.22 ] ~ [ wine-1.5.21 ] ~ [ wine-1.5.20 ] ~ [ wine-1.5.19 ] ~ [ wine-1.5.18 ] ~ [ wine-1.5.17 ] ~ [ wine-1.5.16 ] ~ [ wine-1.5.15 ] ~ [ wine-1.5.14 ] ~ [ wine-1.5.13 ] ~ [ wine-1.5.12 ] ~ [ wine-1.5.11 ] ~ [ wine-1.5.10 ] ~ [ wine-1.5.9 ] ~ [ wine-1.5.8 ] ~ [ wine-1.5.7 ] ~ [ wine-1.4.1 ] ~ [ wine-1.5.6 ] ~ [ wine-1.5.5 ] ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * PE file resources
  3  *
  4  * Copyright 1995 Thomas Sandford
  5  * Copyright 1996 Martin von Loewis
  6  * Copyright 2003 Alexandre Julliard
  7  *
  8  * Based on the Win16 resource handling code in loader/resource.c
  9  * Copyright 1993 Robert J. Amstadt
 10  * Copyright 1995 Alexandre Julliard
 11  * Copyright 1997 Marcus Meissner
 12  *
 13  * This library is free software; you can redistribute it and/or
 14  * modify it under the terms of the GNU Lesser General Public
 15  * License as published by the Free Software Foundation; either
 16  * version 2.1 of the License, or (at your option) any later version.
 17  *
 18  * This library is distributed in the hope that it will be useful,
 19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 21  * Lesser General Public License for more details.
 22  *
 23  * You should have received a copy of the GNU Lesser General Public
 24  * License along with this library; if not, write to the Free Software
 25  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 26  */
 27 
 28 #include "config.h"
 29 #include "wine/port.h"
 30 
 31 #include <stdarg.h>
 32 #include <stdlib.h>
 33 #include <sys/types.h>
 34 
 35 #define NONAMELESSUNION
 36 #define NONAMELESSSTRUCT
 37 #include "ntstatus.h"
 38 #define WIN32_NO_STATUS
 39 #include "windef.h"
 40 #include "winbase.h"
 41 #include "winnt.h"
 42 #include "winternl.h"
 43 #include "wine/exception.h"
 44 #include "wine/unicode.h"
 45 #include "wine/debug.h"
 46 
 47 WINE_DEFAULT_DEBUG_CHANNEL(resource);
 48 
 49 static LCID user_lcid, system_lcid;
 50 static LANGID user_ui_language, system_ui_language;
 51 
 52 #define IS_INTRESOURCE(x)       (((ULONG_PTR)(x) >> 16) == 0)
 53 
 54 /**********************************************************************
 55  *  is_data_file_module
 56  *
 57  * Check if a module handle is for a LOAD_LIBRARY_AS_DATAFILE module.
 58  */
 59 static inline int is_data_file_module( HMODULE hmod )
 60 {
 61     return (ULONG_PTR)hmod & 1;
 62 }
 63 
 64 
 65 /**********************************************************************
 66  *  push_language
 67  *
 68  * push a language in the list of languages to try
 69  */
 70 static inline int push_language( WORD *list, int pos, WORD lang )
 71 {
 72     int i;
 73     for (i = 0; i < pos; i++) if (list[i] == lang) return pos;
 74     list[pos++] = lang;
 75     return pos;
 76 }
 77 
 78 
 79 /**********************************************************************
 80  *  find_first_entry
 81  *
 82  * Find the first suitable entry in a resource directory
 83  */
 84 static const IMAGE_RESOURCE_DIRECTORY *find_first_entry( const IMAGE_RESOURCE_DIRECTORY *dir,
 85                                                          const void *root, int want_dir )
 86 {
 87     const IMAGE_RESOURCE_DIRECTORY_ENTRY *entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1);
 88     int pos;
 89 
 90     for (pos = 0; pos < dir->NumberOfNamedEntries + dir->NumberOfIdEntries; pos++)
 91     {
 92         if (!entry[pos].u2.s3.DataIsDirectory == !want_dir)
 93             return (const IMAGE_RESOURCE_DIRECTORY *)((const char *)root + entry[pos].u2.s3.OffsetToDirectory);
 94     }
 95     return NULL;
 96 }
 97 
 98 
 99 /**********************************************************************
100  *  find_entry_by_id
101  *
102  * Find an entry by id in a resource directory
103  */
104 static const IMAGE_RESOURCE_DIRECTORY *find_entry_by_id( const IMAGE_RESOURCE_DIRECTORY *dir,
105                                                          WORD id, const void *root, int want_dir )
106 {
107     const IMAGE_RESOURCE_DIRECTORY_ENTRY *entry;
108     int min, max, pos;
109 
110     entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1);
111     min = dir->NumberOfNamedEntries;
112     max = min + dir->NumberOfIdEntries - 1;
113     while (min <= max)
114     {
115         pos = (min + max) / 2;
116         if (entry[pos].u1.s2.Id == id)
117         {
118             if (!entry[pos].u2.s3.DataIsDirectory == !want_dir)
119             {
120                 TRACE("root %p dir %p id %04x ret %p\n",
121                       root, dir, id, (const char*)root + entry[pos].u2.s3.OffsetToDirectory);
122                 return (const IMAGE_RESOURCE_DIRECTORY *)((const char *)root + entry[pos].u2.s3.OffsetToDirectory);
123             }
124             break;
125         }
126         if (entry[pos].u1.s2.Id > id) max = pos - 1;
127         else min = pos + 1;
128     }
129     TRACE("root %p dir %p id %04x not found\n", root, dir, id );
130     return NULL;
131 }
132 
133 
134 /**********************************************************************
135  *  find_entry_by_name
136  *
137  * Find an entry by name in a resource directory
138  */
139 static const IMAGE_RESOURCE_DIRECTORY *find_entry_by_name( const IMAGE_RESOURCE_DIRECTORY *dir,
140                                                            LPCWSTR name, const void *root,
141                                                            int want_dir )
142 {
143     const IMAGE_RESOURCE_DIRECTORY_ENTRY *entry;
144     const IMAGE_RESOURCE_DIR_STRING_U *str;
145     int min, max, res, pos, namelen;
146 
147     if (IS_INTRESOURCE(name)) return find_entry_by_id( dir, LOWORD(name), root, want_dir );
148     entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1);
149     namelen = strlenW(name);
150     min = 0;
151     max = dir->NumberOfNamedEntries - 1;
152     while (min <= max)
153     {
154         pos = (min + max) / 2;
155         str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const char *)root + entry[pos].u1.s1.NameOffset);
156         res = strncmpW( name, str->NameString, str->Length );
157         if (!res && namelen == str->Length)
158         {
159             if (!entry[pos].u2.s3.DataIsDirectory == !want_dir)
160             {
161                 TRACE("root %p dir %p name %s ret %p\n",
162                       root, dir, debugstr_w(name), (const char*)root + entry[pos].u2.s3.OffsetToDirectory);
163                 return (const IMAGE_RESOURCE_DIRECTORY *)((const char *)root + entry[pos].u2.s3.OffsetToDirectory);
164             }
165             break;
166         }
167         if (res < 0) max = pos - 1;
168         else min = pos + 1;
169     }
170     TRACE("root %p dir %p name %s not found\n", root, dir, debugstr_w(name) );
171     return NULL;
172 }
173 
174 
175 /**********************************************************************
176  *  find_entry
177  *
178  * Find a resource entry
179  */
180 static NTSTATUS find_entry( HMODULE hmod, const LDR_RESOURCE_INFO *info,
181                             ULONG level, const void **ret, int want_dir )
182 {
183     ULONG size;
184     const void *root;
185     const IMAGE_RESOURCE_DIRECTORY *resdirptr;
186     WORD list[9];  /* list of languages to try */
187     int i, pos = 0;
188 
189     root = RtlImageDirectoryEntryToData( hmod, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &size );
190     if (!root) return STATUS_RESOURCE_DATA_NOT_FOUND;
191     if (size < sizeof(*resdirptr)) return STATUS_RESOURCE_DATA_NOT_FOUND;
192     resdirptr = root;
193 
194     if (!level--) goto done;
195     if (!(*ret = find_entry_by_name( resdirptr, (LPCWSTR)info->Type, root, want_dir || level )))
196         return STATUS_RESOURCE_TYPE_NOT_FOUND;
197     if (!level--) return STATUS_SUCCESS;
198 
199     resdirptr = *ret;
200     if (!(*ret = find_entry_by_name( resdirptr, (LPCWSTR)info->Name, root, want_dir || level )))
201         return STATUS_RESOURCE_NAME_NOT_FOUND;
202     if (!level--) return STATUS_SUCCESS;
203     if (level) return STATUS_INVALID_PARAMETER;  /* level > 3 */
204 
205     /* 1. specified language */
206     pos = push_language( list, pos, info->Language );
207 
208     /* 2. specified language with neutral sublanguage */
209     pos = push_language( list, pos, MAKELANGID( PRIMARYLANGID(info->Language), SUBLANG_NEUTRAL ) );
210 
211     /* 3. neutral language with neutral sublanguage */
212     pos = push_language( list, pos, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ) );
213 
214     /* if no explicitly specified language, try some defaults */
215     if (PRIMARYLANGID(info->Language) == LANG_NEUTRAL)
216     {
217         /* user defaults, unless SYS_DEFAULT sublanguage specified  */
218         if (SUBLANGID(info->Language) != SUBLANG_SYS_DEFAULT)
219         {
220             /* 4. current thread locale language */
221             pos = push_language( list, pos, LANGIDFROMLCID(NtCurrentTeb()->CurrentLocale) );
222 
223             /* 5. user locale language */
224             pos = push_language( list, pos, LANGIDFROMLCID(user_lcid) );
225 
226             /* 6. user locale language with neutral sublanguage  */
227             pos = push_language( list, pos, MAKELANGID( PRIMARYLANGID(user_lcid), SUBLANG_NEUTRAL ) );
228         }
229 
230         /* now system defaults */
231 
232         /* 7. system locale language */
233         pos = push_language( list, pos, LANGIDFROMLCID( system_lcid ) );
234 
235         /* 8. system locale language with neutral sublanguage */
236         pos = push_language( list, pos, MAKELANGID( PRIMARYLANGID(system_lcid), SUBLANG_NEUTRAL ) );
237 
238         /* 9. English */
239         pos = push_language( list, pos, MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT ) );
240     }
241 
242     resdirptr = *ret;
243     for (i = 0; i < pos; i++)
244         if ((*ret = find_entry_by_id( resdirptr, list[i], root, want_dir ))) return STATUS_SUCCESS;
245 
246     /* if no explicitly specified language, return the first entry */
247     if (PRIMARYLANGID(info->Language) == LANG_NEUTRAL)
248     {
249         if ((*ret = find_first_entry( resdirptr, root, want_dir ))) return STATUS_SUCCESS;
250     }
251     return STATUS_RESOURCE_LANG_NOT_FOUND;
252 
253 done:
254     *ret = resdirptr;
255     return STATUS_SUCCESS;
256 }
257 
258 
259 /**********************************************************************
260  *      LdrFindResourceDirectory_U  (NTDLL.@)
261  */
262 NTSTATUS WINAPI LdrFindResourceDirectory_U( HMODULE hmod, const LDR_RESOURCE_INFO *info,
263                                             ULONG level, const IMAGE_RESOURCE_DIRECTORY **dir )
264 {
265     const void *res;
266     NTSTATUS status;
267 
268     __TRY
269     {
270         if (info) TRACE( "module %p type %s name %s lang %04x level %d\n",
271                      hmod, debugstr_w((LPCWSTR)info->Type),
272                      level > 1 ? debugstr_w((LPCWSTR)info->Name) : "",
273                      level > 2 ? info->Language : 0, level );
274 
275         status = find_entry( hmod, info, level, &res, TRUE );
276         if (status == STATUS_SUCCESS) *dir = res;
277     }
278     __EXCEPT_PAGE_FAULT
279     {
280         return GetExceptionCode();
281     }
282     __ENDTRY;
283     return status;
284 }
285 
286 
287 /**********************************************************************
288  *      LdrFindResource_U  (NTDLL.@)
289  */
290 NTSTATUS WINAPI LdrFindResource_U( HMODULE hmod, const LDR_RESOURCE_INFO *info,
291                                    ULONG level, const IMAGE_RESOURCE_DATA_ENTRY **entry )
292 {
293     const void *res;
294     NTSTATUS status;
295 
296     __TRY
297     {
298         if (info) TRACE( "module %p type %s name %s lang %04x level %d\n",
299                      hmod, debugstr_w((LPCWSTR)info->Type),
300                      level > 1 ? debugstr_w((LPCWSTR)info->Name) : "",
301                      level > 2 ? info->Language : 0, level );
302 
303         status = find_entry( hmod, info, level, &res, FALSE );
304         if (status == STATUS_SUCCESS) *entry = res;
305     }
306     __EXCEPT_PAGE_FAULT
307     {
308         return GetExceptionCode();
309     }
310     __ENDTRY;
311     return status;
312 }
313 
314 
315 /* don't penalize other platforms stuff needed on i386 for compatibility */
316 #ifdef __i386__
317 NTSTATUS WINAPI access_resource( HMODULE hmod, const IMAGE_RESOURCE_DATA_ENTRY *entry,
318                                  void **ptr, ULONG *size )
319 #else
320 static inline NTSTATUS access_resource( HMODULE hmod, const IMAGE_RESOURCE_DATA_ENTRY *entry,
321                                         void **ptr, ULONG *size )
322 #endif
323 {
324     NTSTATUS status;
325 
326     __TRY
327     {
328         ULONG dirsize;
329 
330         if (!RtlImageDirectoryEntryToData( hmod, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &dirsize ))
331             status = STATUS_RESOURCE_DATA_NOT_FOUND;
332         else
333         {
334             if (ptr)
335             {
336                 if (is_data_file_module(hmod))
337                 {
338                     HMODULE mod = (HMODULE)((ULONG_PTR)hmod & ~1);
339                     *ptr = RtlImageRvaToVa( RtlImageNtHeader(mod), mod, entry->OffsetToData, NULL );
340                 }
341                 else *ptr = (char *)hmod + entry->OffsetToData;
342             }
343             if (size) *size = entry->Size;
344             status = STATUS_SUCCESS;
345         }
346     }
347     __EXCEPT_PAGE_FAULT
348     {
349         return GetExceptionCode();
350     }
351     __ENDTRY;
352     return status;
353 }
354 
355 /**********************************************************************
356  *      LdrAccessResource  (NTDLL.@)
357  *
358  * NOTE
359  * On x86, Shrinker, an executable compressor, depends on the
360  * "call access_resource" instruction being there.
361  */
362 #ifdef __i386__
363 __ASM_STDCALL_FUNC( LdrAccessResource, 16,
364     "pushl %ebp\n\t"
365     "movl %esp, %ebp\n\t"
366     "subl $4,%esp\n\t"
367     "pushl 24(%ebp)\n\t"
368     "pushl 20(%ebp)\n\t"
369     "pushl 16(%ebp)\n\t"
370     "pushl 12(%ebp)\n\t"
371     "pushl 8(%ebp)\n\t"
372     "call " __ASM_NAME("access_resource") "\n\t"
373     "leave\n\t"
374     "ret $16"
375 )
376 #else
377 NTSTATUS WINAPI LdrAccessResource( HMODULE hmod, const IMAGE_RESOURCE_DATA_ENTRY *entry,
378                                    void **ptr, ULONG *size )
379 {
380     return access_resource( hmod, entry, ptr, size );
381 }
382 #endif
383 
384 /**********************************************************************
385  *      RtlFindMessage  (NTDLL.@)
386  */
387 NTSTATUS WINAPI RtlFindMessage( HMODULE hmod, ULONG type, ULONG lang,
388                                 ULONG msg_id, const MESSAGE_RESOURCE_ENTRY **ret )
389 {
390     const MESSAGE_RESOURCE_DATA *data;
391     const MESSAGE_RESOURCE_BLOCK *block;
392     const IMAGE_RESOURCE_DATA_ENTRY *rsrc;
393     LDR_RESOURCE_INFO info;
394     NTSTATUS status;
395     void *ptr;
396     unsigned int i;
397 
398     info.Type     = type;
399     info.Name     = 1;
400     info.Language = lang;
401 
402     if ((status = LdrFindResource_U( hmod, &info, 3, &rsrc )) != STATUS_SUCCESS)
403         return status;
404     if ((status = LdrAccessResource( hmod, rsrc, &ptr, NULL )) != STATUS_SUCCESS)
405         return status;
406 
407     data = ptr;
408     block = data->Blocks;
409     for (i = 0; i < data->NumberOfBlocks; i++, block++)
410     {
411         if (msg_id >= block->LowId && msg_id <= block->HighId)
412         {
413             const MESSAGE_RESOURCE_ENTRY *entry;
414 
415             entry = (const MESSAGE_RESOURCE_ENTRY *)((const char *)data + block->OffsetToEntries);
416             for (i = msg_id - block->LowId; i > 0; i--)
417                 entry = (const MESSAGE_RESOURCE_ENTRY *)((const char *)entry + entry->Length);
418             *ret = entry;
419             return STATUS_SUCCESS;
420         }
421     }
422     return STATUS_MESSAGE_NOT_FOUND;
423 }
424 
425 /**********************************************************************
426  *      RtlFormatMessage  (NTDLL.@)
427  *
428  * Formats a message (similar to sprintf).
429  *
430  * PARAMS
431  *   Message          [I] Message to format.
432  *   MaxWidth         [I] Maximum width in characters of each output line.
433  *   IgnoreInserts    [I] Whether to copy the message without processing inserts.
434  *   Ansi             [I] Whether Arguments may have ANSI strings.
435  *   ArgumentsIsArray [I] Whether Arguments is actually an array rather than a va_list *.
436  *   Buffer           [O] Buffer to store processed message in.
437  *   BufferSize       [I] Size of Buffer (in bytes?).
438  *
439  * RETURNS
440  *      NTSTATUS code.
441  */
442 NTSTATUS WINAPI RtlFormatMessage( LPWSTR Message, UCHAR MaxWidth,
443                                   BOOLEAN IgnoreInserts, BOOLEAN Ansi,
444                                   BOOLEAN ArgumentIsArray, __ms_va_list * Arguments,
445                                   LPWSTR Buffer, ULONG BufferSize )
446 {
447     FIXME("(%s, %u, %s, %s, %s, %p, %p, %d)\n", debugstr_w(Message),
448         MaxWidth, IgnoreInserts ? "TRUE" : "FALSE", Ansi ? "TRUE" : "FALSE",
449         ArgumentIsArray ? "TRUE" : "FALSE", Arguments, Buffer, BufferSize);
450     return STATUS_SUCCESS;
451 }
452 
453 
454 /**********************************************************************
455  *      NtQueryDefaultLocale  (NTDLL.@)
456  */
457 NTSTATUS WINAPI NtQueryDefaultLocale( BOOLEAN user, LCID *lcid )
458 {
459     *lcid = user ? user_lcid : system_lcid;
460     return STATUS_SUCCESS;
461 }
462 
463 
464 /**********************************************************************
465  *      NtSetDefaultLocale  (NTDLL.@)
466  */
467 NTSTATUS WINAPI NtSetDefaultLocale( BOOLEAN user, LCID lcid )
468 {
469     if (user) user_lcid = lcid;
470     else
471     {
472         system_lcid = lcid;
473         system_ui_language = LANGIDFROMLCID(lcid); /* there is no separate call to set it */
474     }
475     return STATUS_SUCCESS;
476 }
477 
478 
479 /**********************************************************************
480  *      NtQueryDefaultUILanguage  (NTDLL.@)
481  */
482 NTSTATUS WINAPI NtQueryDefaultUILanguage( LANGID *lang )
483 {
484     *lang = user_ui_language;
485     return STATUS_SUCCESS;
486 }
487 
488 
489 /**********************************************************************
490  *      NtSetDefaultUILanguage  (NTDLL.@)
491  */
492 NTSTATUS WINAPI NtSetDefaultUILanguage( LANGID lang )
493 {
494     user_ui_language = lang;
495     return STATUS_SUCCESS;
496 }
497 
498 
499 /**********************************************************************
500  *      NtQueryInstallUILanguage  (NTDLL.@)
501  */
502 NTSTATUS WINAPI NtQueryInstallUILanguage( LANGID *lang )
503 {
504     *lang = system_ui_language;
505     return STATUS_SUCCESS;
506 }
507 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.